From 64d06dcfe24a34b660fda8b0ccadc74a49a7d4b8 Mon Sep 17 00:00:00 2001 From: augustin64 Date: Tue, 16 Jan 2024 21:00:14 +0100 Subject: [PATCH] Move thumbnails to instance directory --- .gitignore | 14 ++--- partitioncloud/__init__.py | 32 +--------- partitioncloud/modules/albums.py | 7 --- partitioncloud/modules/classes/album.py | 4 +- partitioncloud/modules/classes/partition.py | 4 +- partitioncloud/modules/search.py | 11 ++-- partitioncloud/modules/thumbnails.py | 58 +++++++++++++++++++ .../templates/admin/partitions.html | 2 +- partitioncloud/templates/albums/album.html | 2 +- partitioncloud/templates/albums/search.html | 4 +- .../templates/partition/details.html | 2 +- partitioncloud/templates/partition/edit.html | 4 +- scripts/hooks/config.py | 5 ++ scripts/hooks/utils.py | 12 +++- scripts/hooks/v1.py | 16 ++++- scripts/migration.py | 11 ++-- 16 files changed, 116 insertions(+), 72 deletions(-) create mode 100644 partitioncloud/modules/thumbnails.py create mode 100644 scripts/hooks/config.py diff --git a/.gitignore b/.gitignore index 8026c87..ced5f7e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,15 +2,11 @@ **/__pycache__ # config -.vscode +.vscode/ # data -instance -partitioncloud/partitions -partitioncloud/search-partitions -partitioncloud/static/thumbnails -partitioncloud/static/search-thumbnails -partitioncloud/attachments +instance/ -.venv -backups \ No newline at end of file + +.venv/ +backups/ \ No newline at end of file diff --git a/partitioncloud/__init__.py b/partitioncloud/__init__.py index f61915d..ef08977 100644 --- a/partitioncloud/__init__.py +++ b/partitioncloud/__init__.py @@ -12,7 +12,7 @@ from flask import Flask, g, redirect, render_template, request, send_file, flash from werkzeug.security import generate_password_hash from .modules.utils import User, Album, get_all_albums -from .modules import albums, auth, partition, admin, groupe +from .modules import albums, auth, partition, admin, groupe, thumbnails from .modules.auth import admin_required, login_required from .modules.db import get_db @@ -66,6 +66,7 @@ app.register_blueprint(admin.bp) app.register_blueprint(groupe.bp) app.register_blueprint(albums.bp) app.register_blueprint(partition.bp) +app.register_blueprint(thumbnails.bp) __version__ = get_version() @@ -107,35 +108,6 @@ def add_user(): return render_template("auth/register.html", albums=get_all_albums(), user=current_user) -@app.route("/static/search-thumbnails/.jpg") -@login_required -def search_thumbnail(uuid): - """ - Renvoie l'apercu d'un résultat de recherche - """ - db = get_db() - part = db.execute( - """ - SELECT uuid, url FROM search_results - WHERE uuid = ? - """, - (uuid,) - ).fetchone() - - if part is None: - abort(404) - if not os.path.exists(os.path.join(app.static_folder, "search-thumbnails", f"{uuid}.jpg")): - os.system( - f'/usr/bin/convert -thumbnail\ - "178^>" -background white -alpha \ - remove -crop 178x178+0+0 \ - {app.instance_path}/search-partitions/{uuid}.pdf[0] \ - partitioncloud/static/search-thumbnails/{uuid}.jpg' - ) - - return send_file(os.path.join(app.static_folder, "search-thumbnails", f"{uuid}.jpg")) - - @app.before_request def before_request(): """Set cookie max age to 31 days""" diff --git a/partitioncloud/modules/albums.py b/partitioncloud/modules/albums.py index defa440..ddeaa5e 100644 --- a/partitioncloud/modules/albums.py +++ b/partitioncloud/modules/albums.py @@ -299,13 +299,6 @@ def add_partition(album_uuid): partition_path ) - os.system( - f'/usr/bin/convert -thumbnail\ - "178^>" -background white -alpha \ - remove -crop 178x178+0+0 \ - {partition_path}[0] \ - partitioncloud/static/thumbnails/{partition_uuid}.jpg' - ) db.commit() album.add_partition(partition_uuid) diff --git a/partitioncloud/modules/classes/album.py b/partitioncloud/modules/classes/album.py index 7e048fd..6812701 100644 --- a/partitioncloud/modules/classes/album.py +++ b/partitioncloud/modules/classes/album.py @@ -133,8 +133,8 @@ class Album(): attachment.delete(instance_path) os.remove(f"{instance_path}/partitions/{partition['uuid']}.pdf") - if os.path.exists(f"partitioncloud/static/thumbnails/{partition['uuid']}.jpg"): - os.remove(f"partitioncloud/static/thumbnails/{partition['uuid']}.jpg") + if os.path.exists(f"{instance_path}/cache/thumbnails/{partition['uuid']}.jpg"): + os.remove(f"{instance_path}/cache/thumbnails/{partition['uuid']}.jpg") partitions = db.execute( """ diff --git a/partitioncloud/modules/classes/partition.py b/partitioncloud/modules/classes/partition.py index b8465b2..ce36cf5 100644 --- a/partitioncloud/modules/classes/partition.py +++ b/partitioncloud/modules/classes/partition.py @@ -43,8 +43,8 @@ class Partition(): db.commit() os.remove(f"{instance_path}/partitions/{self.uuid}.pdf") - if os.path.exists(f"partitioncloud/static/thumbnails/{self.uuid}.jpg"): - os.remove(f"partitioncloud/static/thumbnails/{self.uuid}.jpg") + if os.path.exists(f"{instance_path}/cache/thumbnails/{self.uuid}.jpg"): + os.remove(f"{instance_path}/cache/thumbnails/{self.uuid}.jpg") db.execute( """ diff --git a/partitioncloud/modules/search.py b/partitioncloud/modules/search.py index 27c8b22..060e1dd 100644 --- a/partitioncloud/modules/search.py +++ b/partitioncloud/modules/search.py @@ -150,14 +150,11 @@ def flush_cache(instance_path): ).fetchall() for element in expired_cache: uuid = element["uuid"] - try: + if os.path.exists(f"{instance_path}/search-partitions/{uuid}.pdf"): os.remove(f"{instance_path}/search-partitions/{uuid}.pdf") - except FileNotFoundError: - pass - try: - os.remove(f"partitioncloud/static/search-thumbnails/{uuid}.jpg") - except FileNotFoundError: - pass + + if os.path.exists(f"{instance_path}/cache/search-thumbnails/{uuid}.jpg"): + os.remove(f"{instance_path}/cache/search-thumbnails/{uuid}.jpg") db.execute( """ diff --git a/partitioncloud/modules/thumbnails.py b/partitioncloud/modules/thumbnails.py new file mode 100644 index 0000000..54e2a5b --- /dev/null +++ b/partitioncloud/modules/thumbnails.py @@ -0,0 +1,58 @@ +""" +Thumbnails +""" +import os + +from flask import current_app, abort, Blueprint, send_file + +from .db import get_db +from .auth import login_required + +bp = Blueprint("thumbnails", __name__, url_prefix="/thumbnails") + + +def generate_thumbnail(source, dest): + """ + Generates a thumbnail with 'convert' (ImageMagick) + """ + os.system( + f'/usr/bin/convert -thumbnail\ + "178^>" -background white -alpha \ + remove -crop 178x178+0+0 \ + {source}[0] \ + {dest}' + ) + +def serve_thumbnail(partition_file, thumbnail_file): + """ + Generates thumbnail if non-existent + """ + if not os.path.exists(partition_file): + abort(404) + + if not os.path.exists(thumbnail_file): + generate_thumbnail(partition_file, thumbnail_file) + + return send_file(thumbnail_file) + + +@bp.route("/search/.jpg") +@login_required +def search_thumbnail(uuid): + """ + Renvoie l'apercu d'un résultat de recherche + """ + return serve_thumbnail( + os.path.join(current_app.instance_path, "search-partitions", f"{uuid}.pdf"), + os.path.join(current_app.instance_path, "cache", "search-thumbnails", f"{uuid}.jpg") + ) + +@bp.route("/.jpg") +def regular_thumbnail(uuid): + """ + Renvoie l'apercu d'une partition déjà enregistrée + """ + return serve_thumbnail( + os.path.join(current_app.instance_path, "partitions", f"{uuid}.pdf"), + os.path.join(current_app.instance_path, "cache", "thumbnails", f"{uuid}.jpg") + ) \ No newline at end of file diff --git a/partitioncloud/templates/admin/partitions.html b/partitioncloud/templates/admin/partitions.html index c1170d4..7b6ff17 100644 --- a/partitioncloud/templates/admin/partitions.html +++ b/partitioncloud/templates/admin/partitions.html @@ -11,7 +11,7 @@
- +
{{ partition["name"] }}
{{ partition["author"] }}
diff --git a/partitioncloud/templates/albums/album.html b/partitioncloud/templates/albums/album.html index 0b004bc..4ede23c 100644 --- a/partitioncloud/templates/albums/album.html +++ b/partitioncloud/templates/albums/album.html @@ -78,7 +78,7 @@
- +
{{ partition["name"] }}
{{ partition["author"] }}
diff --git a/partitioncloud/templates/albums/search.html b/partitioncloud/templates/albums/search.html index 50f1922..9d5d71f 100644 --- a/partitioncloud/templates/albums/search.html +++ b/partitioncloud/templates/albums/search.html @@ -10,7 +10,7 @@
- +
{{ partition["name"] }}
{{ partition["author"] }}
@@ -48,7 +48,7 @@
- +
{{ partition["name"] }}
diff --git a/partitioncloud/templates/partition/details.html b/partitioncloud/templates/partition/details.html index 8fa6129..ed4d3eb 100644 --- a/partitioncloud/templates/partition/details.html +++ b/partitioncloud/templates/partition/details.html @@ -50,7 +50,7 @@ Fichier -
+ Titre diff --git a/partitioncloud/templates/partition/edit.html b/partitioncloud/templates/partition/edit.html index 29eb568..3eb202d 100644 --- a/partitioncloud/templates/partition/edit.html +++ b/partitioncloud/templates/partition/edit.html @@ -11,7 +11,9 @@ Fichier - + + + {% if partition.source != "unknown" and partition.source != "upload" %} diff --git a/scripts/hooks/config.py b/scripts/hooks/config.py new file mode 100644 index 0000000..28e722c --- /dev/null +++ b/scripts/hooks/config.py @@ -0,0 +1,5 @@ +""" +Config parameters, shared between files +""" + +instance = "instance" \ No newline at end of file diff --git a/scripts/hooks/utils.py b/scripts/hooks/utils.py index d095752..cb1d2a0 100644 --- a/scripts/hooks/utils.py +++ b/scripts/hooks/utils.py @@ -2,10 +2,15 @@ import random import string import sqlite3 +from . import config + def run_sqlite_command(*args): """Run a command against the database""" - con = sqlite3.connect("instance/partitioncloud.sqlite") + con = sqlite3.connect(os.path.join( + config.instance, + "partitioncloud.sqlite" + )) cur = con.cursor() cur.execute(*args) con.commit() @@ -14,7 +19,10 @@ def run_sqlite_command(*args): def get_sqlite_data(*args): """Get data from the db""" - con = sqlite3.connect("instance/partitioncloud.sqlite") + con = sqlite3.connect(os.path.join( + config.instance, + "partitioncloud.sqlite" + )) cur = con.cursor() data = cur.execute(*args) new_data = list(data) diff --git a/scripts/hooks/v1.py b/scripts/hooks/v1.py index b9050f7..176b813 100644 --- a/scripts/hooks/v1.py +++ b/scripts/hooks/v1.py @@ -1,9 +1,11 @@ import os import shutil import sqlite3 -from hooks import utils from colorama import Fore, Style +from . import utils +from . import config + """ v1.3.* """ @@ -159,5 +161,13 @@ def move_instance(): for path in paths: shutil.move( os.path.join("partitioncloud", path), - os.path.join("instance", path) - ) \ No newline at end of file + os.path.join(config.instance, path) + ) + + +def move_thumbnails(): + shutil.rmtree("partitioncloud/static/thumbnails", ignore_errors=True) + shutil.rmtree("partitioncloud/static/search-thumbnails", ignore_errors=True) + + os.makedirs(os.path.join(config.instance, "cache", "thumbnails"), exist_ok=True) + os.makedirs(os.path.join(config.instance, "cache", "search-thumbnails"), exist_ok=True) diff --git a/scripts/migration.py b/scripts/migration.py index 0ac6a94..4434bbb 100644 --- a/scripts/migration.py +++ b/scripts/migration.py @@ -6,7 +6,7 @@ import argparse from functools import cmp_to_key from colorama import Fore, Style -from hooks import v1 as v1_hooks +from hooks import v1 as v1_hooks, config def get_version(v: str) -> (int, int, int): @@ -33,7 +33,8 @@ hooks = [ ], ), ("v1.4.1", [("Install qrcode", v1_hooks.install_qrcode)]), - ("v1.5.0", [("Move to instance directory", v1_hooks.move_instance)]) + ("v1.5.0", [("Move to instance directory", v1_hooks.move_instance)]), + ("v1.5.1", [("Move thumbnails", v1_hooks.move_thumbnails)]) ] @@ -73,7 +74,7 @@ def backup_instance(version, verbose=True): os.makedirs(dest) paths = [ - ("instance", os.path.join(dest, "instance")), + (config.instance, os.path.join(dest, "instance")), ( os.path.join("partitioncloud", "partitions"), os.path.join(dest, "partitions"), @@ -155,7 +156,7 @@ def restore(version): dest = os.path.join("backups", version) print(f"Restoring from {dest}") paths = [ - ("instance", os.path.join(dest, "instance")), + (config.instance, os.path.join(dest, "instance")), ( os.path.join("partitioncloud", "partitions"), os.path.join(dest, "partitions"), @@ -191,6 +192,7 @@ if __name__ == "__main__": parser.add_argument("-c", "--current", help="current version (vx.y.z)") parser.add_argument("-t", "--target", help="target version (vx.y.z)") + parser.add_argument("-i", "--instance", help="instance folder", default="instance") parser.add_argument("-s", "--skip-backup", action="store_true") parser.add_argument( "-r", @@ -199,6 +201,7 @@ if __name__ == "__main__": ) args = parser.parse_args() + config.instance = os.path.abspath(args.instance) if args.restore is None: migrate(args.current, args.target, skip_backup=args.skip_backup)