diff --git a/photoapp/daemon.py b/photoapp/daemon.py index fb163d4..5106a8f 100644 --- a/photoapp/daemon.py +++ b/photoapp/daemon.py @@ -7,21 +7,19 @@ from collections import defaultdict from urllib.parse import urlparse from datetime import datetime, timedelta from photoapp.thumbtool import ThumbGenerator -from photoapp.types import Photo, PhotoSet, Tag, TagItem, PhotoStatus, User, mime2ext, regular_mimes, video_mimes +from photoapp.types import APPROOT, Photo, PhotoSet, Tag, TagItem, PhotoStatus, User, mime2ext, \ + regular_mimes, video_mimes from photoapp.dbsession import DatabaseSession from photoapp.common import pwhash from photoapp.api import PhotosApi, LibraryManager from photoapp.dbutils import SAEnginePlugin, SATool, db, get_db_engine, date_format from photoapp.utils import auth, require_auth, photoset_auth_filter, slugify, cherryparam, number_format from photoapp.storage import uri_to_storage -from photoapp.webutils import validate_password +from photoapp.webutils import validate_password, serve_thumbnail_placeholder from jinja2 import Environment, FileSystemLoader, select_autoescape from sqlalchemy import desc, func, and_, or_ -APPROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "../")) - - class PhotosWeb(object): """ Http root of the UI webserver @@ -272,14 +270,15 @@ class ThumbnailView(object): t = vtypes.pop() # TODO arbitrary thumb_from = formats[t][0] # TODO arbitrary + if not thumb_from: # no format we know how to make a thumbnail from was found + return serve_thumbnail_placeholder() + thumb_fobj = self.master.thumbtool.make_thumb(thumb_from, thumb_size) if thumb_fobj: return cherrypy.lib.static.serve_fileobj(thumb_fobj, "image/jpeg") - else: - cherrypy.response.headers["Cache-Control"] = "no-store, must-revalidate, max-age=0" - cherrypy.response.headers["Age"] = "0" - return cherrypy.lib.static.serve_file(os.path.join(APPROOT, "assets/img/unknown.svg"), "image/svg+xml") + else: # thumb creation failed or in progress + return serve_thumbnail_placeholder(True) @cherrypy.popargs('item_type', 'uuid') diff --git a/photoapp/types.py b/photoapp/types.py index 72e4faf..b2c8aa7 100644 --- a/photoapp/types.py +++ b/photoapp/types.py @@ -3,11 +3,15 @@ from sqlalchemy.orm import relationship from sqlalchemy.schema import UniqueConstraint from photoapp.dbutils import Base from datetime import datetime +import os import enum as py_enum import uuid import enum +APPROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "../")) + + class fcategory(py_enum.Enum): image = 0 raw = 1 diff --git a/photoapp/webutils.py b/photoapp/webutils.py index 87426eb..a862a16 100644 --- a/photoapp/webutils.py +++ b/photoapp/webutils.py @@ -1,4 +1,6 @@ -from photoapp.types import User +import os +import cherrypy +from photoapp.types import APPROOT, User from photoapp.dbutils import db from photoapp.common import pwhash @@ -7,3 +9,13 @@ def validate_password(realm, username, password): if db.query(User).filter(User.name == username, User.password == pwhash(password)).first(): return True return False + + +def serve_thumbnail_placeholder(temporary=False): + """ + Serve the placeholder for broken/unavailable thumbnails, the image. Setting temporary will add a no-cache header + """ + if temporary: + cherrypy.response.headers["Cache-Control"] = "no-store, must-revalidate, max-age=0" + cherrypy.response.headers["Age"] = "0" + return cherrypy.lib.static.serve_file(os.path.join(APPROOT, "assets/img/unknown.svg"), "image/svg+xml")