From fd993b506353c28ff48c62d86c61efb82e7cc4f7 Mon Sep 17 00:00:00 2001
From: Oskar Manhart <52569953+oskardotglobal@users.noreply.github.com>
Date: Sat, 3 Aug 2024 14:25:15 +0200
Subject: [PATCH 1/6] feat: use lazy loading for images
---
cps/templates/image.html | 2 ++
1 file changed, 2 insertions(+)
diff --git a/cps/templates/image.html b/cps/templates/image.html
index 0bdba9a51..f84fa12b2 100644
--- a/cps/templates/image.html
+++ b/cps/templates/image.html
@@ -6,6 +6,7 @@
srcset="{{ srcset }}"
src="{{ url_for('web.get_cover', book_id=book.id, resolution='og', c=book|last_modified) }}"
alt="{{ image_alt }}"
+ loading="lazy"
/>
{%- endmacro %}
@@ -16,5 +17,6 @@
srcset="{{ srcset }}"
src="{{ url_for('web.get_series_cover', series_id=series.id, resolution='og', c='day'|cache_timestamp) }}"
alt="{{ book_title }}"
+ loading="lazy"
/>
{%- endmacro %}
From 26c8e15436ccad567c91214e92404fe6314cd065 Mon Sep 17 00:00:00 2001
From: Oskar Manhart <52569953+oskardotglobal@users.noreply.github.com>
Date: Sat, 3 Aug 2024 14:59:16 +0200
Subject: [PATCH 2/6] feat: resize and convert images to webp using
Flask-Image-Resizer
---
cps/__init__.py | 6 +++++-
cps/templates/image.html | 4 ++--
requirements.txt | 1 +
3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/cps/__init__.py b/cps/__init__.py
index 157dd14e5..f945b97a7 100755
--- a/cps/__init__.py
+++ b/cps/__init__.py
@@ -26,12 +26,13 @@ import os
import mimetypes
from flask import Flask
+from flask_image_resizer import Images
+
from .MyLoginManager import MyLoginManager
from flask_principal import Principal
from . import logger
from .cli import CliParameter
-from .constants import CONFIG_DIR
from .reverseproxy import ReverseProxied
from .server import WebServer
from .dep_check import dependency_check
@@ -124,6 +125,9 @@ def create_app():
config_sql.load_configuration(ub.session, encrypt_key)
config.init_config(ub.session, encrypt_key, cli_param)
+ # Initialize Flask-Images
+ Images(app)
+
if error:
log.error(error)
diff --git a/cps/templates/image.html b/cps/templates/image.html
index f84fa12b2..088e6b99b 100644
--- a/cps/templates/image.html
+++ b/cps/templates/image.html
@@ -4,7 +4,7 @@
{% set srcset = book|get_cover_srcset %}
@@ -15,7 +15,7 @@
{% set srcset = series|get_series_srcset %}
diff --git a/requirements.txt b/requirements.txt
index 460a73578..965d039fa 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -20,3 +20,4 @@ regex>=2022.3.2,<2024.6.25
bleach>=6.0.0,<6.2.0
python-magic>=0.4.27,<0.5.0
flask-httpAuth>=4.4.0,<5.0.0
+Flask-Image-Resizer==3.0.6
From ba383643f50b2672884a465a139207513482ee05 Mon Sep 17 00:00:00 2001
From: Oskar Manhart <52569953+oskardotglobal@users.noreply.github.com>
Date: Sat, 3 Aug 2024 15:49:15 +0200
Subject: [PATCH 3/6] feat: resize images directly at cover endpoint
---
cps/helper.py | 30 ++++++++++++++++++++++--------
cps/templates/image.html | 4 ++--
cps/web.py | 24 ++++++++++++++++++++++++
3 files changed, 48 insertions(+), 10 deletions(-)
diff --git a/cps/helper.py b/cps/helper.py
index 004e1b0e0..37ee7bb2e 100644
--- a/cps/helper.py
+++ b/cps/helper.py
@@ -30,10 +30,12 @@ import requests
import unidecode
from uuid import uuid4
-from flask import send_from_directory, make_response, abort, url_for, Response
+from flask import send_from_directory, make_response, abort, url_for, Response, redirect
from flask_babel import gettext as _
from flask_babel import lazy_gettext as N_
from flask_babel import get_locale
+from flask_image_resizer import resized_img_src
+
from .cw_login import current_user
from sqlalchemy.sql.expression import true, false, and_, or_, text, func
from sqlalchemy.exc import InvalidRequestError, OperationalError
@@ -749,6 +751,8 @@ def get_book_cover_with_uuid(book_uuid, resolution=None):
def get_book_cover_internal(book, resolution=None):
+ """returns an optimized version of the cover, unless using google drive"""
+
if book and book.has_cover:
# Send the book cover thumbnail if it exists in cache
@@ -757,8 +761,13 @@ def get_book_cover_internal(book, resolution=None):
if thumbnail:
cache = fs.FileSystem()
if cache.get_cache_file_exists(thumbnail.filename, CACHE_TYPE_THUMBNAILS):
- return send_from_directory(cache.get_cache_file_dir(thumbnail.filename, CACHE_TYPE_THUMBNAILS),
- thumbnail.filename)
+ return redirect(resized_img_src(
+ os.path.join(
+ cache.get_cache_file_dir(thumbnail.filename, CACHE_TYPE_THUMBNAILS),
+ thumbnail.filename
+ ),
+ format="webp"
+ ))
# Send the book cover from Google Drive if configured
if config.config_use_google_drive:
@@ -777,9 +786,9 @@ def get_book_cover_internal(book, resolution=None):
# Send the book cover from the Calibre directory
else:
- cover_file_path = os.path.join(config.get_book_path(), book.path)
- if os.path.isfile(os.path.join(cover_file_path, "cover.jpg")):
- return send_from_directory(cover_file_path, "cover.jpg")
+ cover_file_path = os.path.join(config.get_book_path(), book.path, "cover.jpg")
+ if os.path.isfile(cover_file_path):
+ return redirect(resized_img_src(cover_file_path, format="webp"))
else:
return get_cover_on_failure()
else:
@@ -820,8 +829,13 @@ def get_series_cover_internal(series_id, resolution=None):
if thumbnail:
cache = fs.FileSystem()
if cache.get_cache_file_exists(thumbnail.filename, CACHE_TYPE_THUMBNAILS):
- return send_from_directory(cache.get_cache_file_dir(thumbnail.filename, CACHE_TYPE_THUMBNAILS),
- thumbnail.filename)
+ return redirect(resized_img_src(
+ os.path.join(
+ cache.get_cache_file_dir(thumbnail.filename, CACHE_TYPE_THUMBNAILS),
+ thumbnail.filename
+ ),
+ format="webp"
+ ))
return get_series_thumbnail_on_failure(series_id, resolution)
diff --git a/cps/templates/image.html b/cps/templates/image.html
index 088e6b99b..f84fa12b2 100644
--- a/cps/templates/image.html
+++ b/cps/templates/image.html
@@ -4,7 +4,7 @@
{% set srcset = book|get_cover_srcset %}
@@ -15,7 +15,7 @@
{% set srcset = series|get_series_srcset %}
diff --git a/cps/web.py b/cps/web.py
index 2519ebd5b..fa15b3fc3 100644
--- a/cps/web.py
+++ b/cps/web.py
@@ -29,6 +29,8 @@ from flask import request, redirect, send_from_directory, make_response, flash,
from flask import session as flask_session
from flask_babel import gettext as _
from flask_babel import get_locale
+from flask_image_resizer import resized_img_src
+
from .cw_login import login_user, logout_user, current_user
from flask_limiter import RateLimitExceeded
from flask_limiter.util import get_remote_address
@@ -1147,6 +1149,17 @@ def category_list():
@web.route("/cover//")
@login_required_if_no_ano
def get_cover(book_id, resolution=None):
+ return redirect(
+ resized_img_src(
+ url_for("web.get_raw_cover", book_id=book_id, resolution=resolution)
+ )
+ )
+
+
+@web.route("/raw_cover/")
+@web.route("/raw_cover//")
+@login_required_if_no_ano
+def get_raw_cover(book_id, resolution=None):
resolutions = {
'og': constants.COVER_THUMBNAIL_ORIGINAL,
'sm': constants.COVER_THUMBNAIL_SMALL,
@@ -1161,6 +1174,17 @@ def get_cover(book_id, resolution=None):
@web.route("/series_cover//")
@login_required_if_no_ano
def get_series_cover(series_id, resolution=None):
+ return redirect(
+ resized_img_src(
+ url_for("web.get_raw_series_cover", series_id=series_id, resolution=resolution)
+ )
+ )
+
+
+@web.route("/raw_series_cover/")
+@web.route("/raw_series_cover//")
+@login_required_if_no_ano
+def get_raw_series_cover(series_id, resolution=None):
resolutions = {
'og': constants.COVER_THUMBNAIL_ORIGINAL,
'sm': constants.COVER_THUMBNAIL_SMALL,
From 26fb9921b20e8515199958e505356b57574ec7d9 Mon Sep 17 00:00:00 2001
From: Oskar Manhart <52569953+oskardotglobal@users.noreply.github.com>
Date: Sat, 3 Aug 2024 15:49:55 +0200
Subject: [PATCH 4/6] fix: typo
---
cps/__init__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cps/__init__.py b/cps/__init__.py
index f945b97a7..e6843fa0c 100644
--- a/cps/__init__.py
+++ b/cps/__init__.py
@@ -125,7 +125,7 @@ def create_app():
config_sql.load_configuration(ub.session, encrypt_key)
config.init_config(ub.session, encrypt_key, cli_param)
- # Initialize Flask-Images
+ # Initialize Flask-Image-Resizer
Images(app)
if error:
From 9955e348a03331ff019b30a06cc3f61cda8e305f Mon Sep 17 00:00:00 2001
From: Oskar Manhart <52569953+oskardotglobal@users.noreply.github.com>
Date: Sat, 3 Aug 2024 16:28:13 +0200
Subject: [PATCH 5/6] Revert "feat: resize images directly at cover endpoint"
This reverts commit ba383643f50b2672884a465a139207513482ee05.
---
cps/helper.py | 30 ++++++++----------------------
cps/templates/image.html | 4 ++--
cps/web.py | 24 ------------------------
3 files changed, 10 insertions(+), 48 deletions(-)
diff --git a/cps/helper.py b/cps/helper.py
index 37ee7bb2e..004e1b0e0 100644
--- a/cps/helper.py
+++ b/cps/helper.py
@@ -30,12 +30,10 @@ import requests
import unidecode
from uuid import uuid4
-from flask import send_from_directory, make_response, abort, url_for, Response, redirect
+from flask import send_from_directory, make_response, abort, url_for, Response
from flask_babel import gettext as _
from flask_babel import lazy_gettext as N_
from flask_babel import get_locale
-from flask_image_resizer import resized_img_src
-
from .cw_login import current_user
from sqlalchemy.sql.expression import true, false, and_, or_, text, func
from sqlalchemy.exc import InvalidRequestError, OperationalError
@@ -751,8 +749,6 @@ def get_book_cover_with_uuid(book_uuid, resolution=None):
def get_book_cover_internal(book, resolution=None):
- """returns an optimized version of the cover, unless using google drive"""
-
if book and book.has_cover:
# Send the book cover thumbnail if it exists in cache
@@ -761,13 +757,8 @@ def get_book_cover_internal(book, resolution=None):
if thumbnail:
cache = fs.FileSystem()
if cache.get_cache_file_exists(thumbnail.filename, CACHE_TYPE_THUMBNAILS):
- return redirect(resized_img_src(
- os.path.join(
- cache.get_cache_file_dir(thumbnail.filename, CACHE_TYPE_THUMBNAILS),
- thumbnail.filename
- ),
- format="webp"
- ))
+ return send_from_directory(cache.get_cache_file_dir(thumbnail.filename, CACHE_TYPE_THUMBNAILS),
+ thumbnail.filename)
# Send the book cover from Google Drive if configured
if config.config_use_google_drive:
@@ -786,9 +777,9 @@ def get_book_cover_internal(book, resolution=None):
# Send the book cover from the Calibre directory
else:
- cover_file_path = os.path.join(config.get_book_path(), book.path, "cover.jpg")
- if os.path.isfile(cover_file_path):
- return redirect(resized_img_src(cover_file_path, format="webp"))
+ cover_file_path = os.path.join(config.get_book_path(), book.path)
+ if os.path.isfile(os.path.join(cover_file_path, "cover.jpg")):
+ return send_from_directory(cover_file_path, "cover.jpg")
else:
return get_cover_on_failure()
else:
@@ -829,13 +820,8 @@ def get_series_cover_internal(series_id, resolution=None):
if thumbnail:
cache = fs.FileSystem()
if cache.get_cache_file_exists(thumbnail.filename, CACHE_TYPE_THUMBNAILS):
- return redirect(resized_img_src(
- os.path.join(
- cache.get_cache_file_dir(thumbnail.filename, CACHE_TYPE_THUMBNAILS),
- thumbnail.filename
- ),
- format="webp"
- ))
+ return send_from_directory(cache.get_cache_file_dir(thumbnail.filename, CACHE_TYPE_THUMBNAILS),
+ thumbnail.filename)
return get_series_thumbnail_on_failure(series_id, resolution)
diff --git a/cps/templates/image.html b/cps/templates/image.html
index f84fa12b2..088e6b99b 100644
--- a/cps/templates/image.html
+++ b/cps/templates/image.html
@@ -4,7 +4,7 @@
{% set srcset = book|get_cover_srcset %}
@@ -15,7 +15,7 @@
{% set srcset = series|get_series_srcset %}
diff --git a/cps/web.py b/cps/web.py
index fa15b3fc3..2519ebd5b 100644
--- a/cps/web.py
+++ b/cps/web.py
@@ -29,8 +29,6 @@ from flask import request, redirect, send_from_directory, make_response, flash,
from flask import session as flask_session
from flask_babel import gettext as _
from flask_babel import get_locale
-from flask_image_resizer import resized_img_src
-
from .cw_login import login_user, logout_user, current_user
from flask_limiter import RateLimitExceeded
from flask_limiter.util import get_remote_address
@@ -1149,17 +1147,6 @@ def category_list():
@web.route("/cover//")
@login_required_if_no_ano
def get_cover(book_id, resolution=None):
- return redirect(
- resized_img_src(
- url_for("web.get_raw_cover", book_id=book_id, resolution=resolution)
- )
- )
-
-
-@web.route("/raw_cover/")
-@web.route("/raw_cover//")
-@login_required_if_no_ano
-def get_raw_cover(book_id, resolution=None):
resolutions = {
'og': constants.COVER_THUMBNAIL_ORIGINAL,
'sm': constants.COVER_THUMBNAIL_SMALL,
@@ -1174,17 +1161,6 @@ def get_raw_cover(book_id, resolution=None):
@web.route("/series_cover//")
@login_required_if_no_ano
def get_series_cover(series_id, resolution=None):
- return redirect(
- resized_img_src(
- url_for("web.get_raw_series_cover", series_id=series_id, resolution=resolution)
- )
- )
-
-
-@web.route("/raw_series_cover/")
-@web.route("/raw_series_cover//")
-@login_required_if_no_ano
-def get_raw_series_cover(series_id, resolution=None):
resolutions = {
'og': constants.COVER_THUMBNAIL_ORIGINAL,
'sm': constants.COVER_THUMBNAIL_SMALL,
From c53a5168874ea44f46abf76a1b227374111d71fa Mon Sep 17 00:00:00 2001
From: Oskar Manhart <52569953+oskardotglobal@users.noreply.github.com>
Date: Mon, 5 Aug 2024 12:02:43 +0200
Subject: [PATCH 6/6] feat: revert all the resizing stuff
---
cps/__init__.py | 5 -----
cps/templates/image.html | 4 ++--
requirements.txt | 1 -
3 files changed, 2 insertions(+), 8 deletions(-)
diff --git a/cps/__init__.py b/cps/__init__.py
index e6843fa0c..d003ed5a8 100644
--- a/cps/__init__.py
+++ b/cps/__init__.py
@@ -26,8 +26,6 @@ import os
import mimetypes
from flask import Flask
-from flask_image_resizer import Images
-
from .MyLoginManager import MyLoginManager
from flask_principal import Principal
@@ -125,9 +123,6 @@ def create_app():
config_sql.load_configuration(ub.session, encrypt_key)
config.init_config(ub.session, encrypt_key, cli_param)
- # Initialize Flask-Image-Resizer
- Images(app)
-
if error:
log.error(error)
diff --git a/cps/templates/image.html b/cps/templates/image.html
index 088e6b99b..f84fa12b2 100644
--- a/cps/templates/image.html
+++ b/cps/templates/image.html
@@ -4,7 +4,7 @@
{% set srcset = book|get_cover_srcset %}
@@ -15,7 +15,7 @@
{% set srcset = series|get_series_srcset %}
diff --git a/requirements.txt b/requirements.txt
index 965d039fa..460a73578 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -20,4 +20,3 @@ regex>=2022.3.2,<2024.6.25
bleach>=6.0.0,<6.2.0
python-magic>=0.4.27,<0.5.0
flask-httpAuth>=4.4.0,<5.0.0
-Flask-Image-Resizer==3.0.6