diff --git a/app.py b/app.py index e5af1eb..bf95df4 100755 --- a/app.py +++ b/app.py @@ -1,4 +1,4 @@ -from flask import Flask, render_template, send_file, url_for, jsonify, request, session, send_from_directory, abort +from flask import Flask, render_template, send_file, url_for, jsonify, request, session, send_from_directory, make_response, abort import os from PIL import Image, ImageOps import io @@ -286,10 +286,16 @@ def serve_file(subpath): # Try to read the requested variant with cache.read(cache_key) as reader: file_path = reader.name + cached_hit = True except KeyError: + if small: # do not create when thumbnail requested + response = make_response('', 204) + return response + + cached_hit = False # On miss: generate both full-size and small thumb, then cache with Image.open(full_path) as orig: - exif_bytes = orig.info.get('exif') + img = ImageOps.exif_transpose(orig) variants = { orig_key: (1920, 1920), @@ -301,7 +307,7 @@ def serve_file(subpath): if thumb.mode in ("RGBA", "P"): thumb = thumb.convert("RGB") bio = io.BytesIO() - # don’t pass exif_bytes here + thumb.save(bio, format='JPEG', quality=85) bio.seek(0) cache.set(key, bio, read=True) @@ -320,7 +326,7 @@ def serve_file(subpath): response.headers['Content-Disposition'] = 'inline' response.headers['Cache-Control'] = 'public, max-age=86400' - if do_log: + if do_log and not small: a.log_file_access( cache_key, os.path.getsize(file_path), @@ -328,7 +334,7 @@ def serve_file(subpath): ip_address, user_agent, session['device_id'], - True + cached_hit ) return response @@ -336,7 +342,9 @@ def serve_file(subpath): try: with cache.read(subpath) as reader: file_path = reader.name + cached_hit = True except KeyError: + cached_hit = False try: cache.set(subpath, open(full_path, 'rb'), read=True) with cache.read(subpath) as reader: @@ -347,8 +355,7 @@ def serve_file(subpath): # 6) Build response for non-image filesize = os.path.getsize(file_path) - cached_hit = True - + # Figure out download flag and filename ask_download = request.args.get('download') == 'true' filename = os.path.basename(full_path) diff --git a/docker-compose.yml b/docker-compose.yml index 17ab8ff..8dc9c47 100755 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -40,7 +40,7 @@ services: # Production-ready Gunicorn command with eventlet command: > sh -c "pip install -r requirements.txt && - gunicorn --worker-class eventlet -w 1 -b 0.0.0.0:5000 app:app" + gunicorn --worker-class eventlet -w 4 -b 0.0.0.0:5000 app:app" networks: diff --git a/static/app.css b/static/app.css index 8309ec6..9562e5b 100644 --- a/static/app.css +++ b/static/app.css @@ -238,25 +238,54 @@ footer { cursor: auto; } + +/* IMAGE GRID */ + .images-grid { display: grid; - /* make each column exactly 150px wide */ grid-template-columns: repeat(auto-fill, 150px); - /* force every row exactly 150px tall */ grid-auto-rows: 150px; gap: 14px; } .image-item { - /* ensure the thumbnail can’t overflow its cell */ + position: relative; overflow: hidden; + border: 2px solid #ccc; + border-radius: 8px; + background: #f9f9f9; } +/* the filename overlay, centered at bottom */ +.image-item .file-name { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + padding: 4px 0; + text-align: center; + font-size: 12px; + background: rgba(0, 0, 0, 0.6); + color: #fff; + box-sizing: border-box; + transition: opacity 0.3s; + opacity: 1; + pointer-events: none; +} + +/* once loaded, hide the filename overlay */ +.image-item.loaded .file-name { + opacity: 0.5; +} + +/* thumbnail styling unchanged */ .thumbnail { - /* fill the full cell */ width: 100%; height: 100%; - /* crop/scale to cover without stretching */ object-fit: cover; - border-radius: 4px; -} \ No newline at end of file +} + +/* pop when loaded */ +.image-item.loaded .thumbnail { + transform: scale(1.05); +} diff --git a/static/app.js b/static/app.js index 2f6b086..d44dbe7 100644 --- a/static/app.js +++ b/static/app.js @@ -58,9 +58,17 @@ function renderContent(data) { const thumbUrl = `${file.path}?thumbnail=true`; contentHTML += `
`; }); diff --git a/templates/app.html b/templates/app.html index 6084fd9..048a82e 100644 --- a/templates/app.html +++ b/templates/app.html @@ -35,7 +35,7 @@