Move thumbnails to instance directory

This commit is contained in:
augustin64 2024-01-16 21:00:14 +01:00
parent ec3a7d4523
commit 64d06dcfe2
16 changed files with 116 additions and 72 deletions

14
.gitignore vendored
View File

@ -2,15 +2,11 @@
**/__pycache__ **/__pycache__
# config # config
.vscode .vscode/
# data # data
instance instance/
partitioncloud/partitions
partitioncloud/search-partitions
partitioncloud/static/thumbnails
partitioncloud/static/search-thumbnails
partitioncloud/attachments
.venv
backups .venv/
backups/

View File

@ -12,7 +12,7 @@ from flask import Flask, g, redirect, render_template, request, send_file, flash
from werkzeug.security import generate_password_hash from werkzeug.security import generate_password_hash
from .modules.utils import User, Album, get_all_albums 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.auth import admin_required, login_required
from .modules.db import get_db from .modules.db import get_db
@ -66,6 +66,7 @@ app.register_blueprint(admin.bp)
app.register_blueprint(groupe.bp) app.register_blueprint(groupe.bp)
app.register_blueprint(albums.bp) app.register_blueprint(albums.bp)
app.register_blueprint(partition.bp) app.register_blueprint(partition.bp)
app.register_blueprint(thumbnails.bp)
__version__ = get_version() __version__ = get_version()
@ -107,35 +108,6 @@ def add_user():
return render_template("auth/register.html", albums=get_all_albums(), user=current_user) return render_template("auth/register.html", albums=get_all_albums(), user=current_user)
@app.route("/static/search-thumbnails/<uuid>.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 @app.before_request
def before_request(): def before_request():
"""Set cookie max age to 31 days""" """Set cookie max age to 31 days"""

View File

@ -299,13 +299,6 @@ def add_partition(album_uuid):
partition_path 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() db.commit()
album.add_partition(partition_uuid) album.add_partition(partition_uuid)

View File

@ -133,8 +133,8 @@ class Album():
attachment.delete(instance_path) attachment.delete(instance_path)
os.remove(f"{instance_path}/partitions/{partition['uuid']}.pdf") os.remove(f"{instance_path}/partitions/{partition['uuid']}.pdf")
if os.path.exists(f"partitioncloud/static/thumbnails/{partition['uuid']}.jpg"): if os.path.exists(f"{instance_path}/cache/thumbnails/{partition['uuid']}.jpg"):
os.remove(f"partitioncloud/static/thumbnails/{partition['uuid']}.jpg") os.remove(f"{instance_path}/cache/thumbnails/{partition['uuid']}.jpg")
partitions = db.execute( partitions = db.execute(
""" """

View File

@ -43,8 +43,8 @@ class Partition():
db.commit() db.commit()
os.remove(f"{instance_path}/partitions/{self.uuid}.pdf") os.remove(f"{instance_path}/partitions/{self.uuid}.pdf")
if os.path.exists(f"partitioncloud/static/thumbnails/{self.uuid}.jpg"): if os.path.exists(f"{instance_path}/cache/thumbnails/{self.uuid}.jpg"):
os.remove(f"partitioncloud/static/thumbnails/{self.uuid}.jpg") os.remove(f"{instance_path}/cache/thumbnails/{self.uuid}.jpg")
db.execute( db.execute(
""" """

View File

@ -150,14 +150,11 @@ def flush_cache(instance_path):
).fetchall() ).fetchall()
for element in expired_cache: for element in expired_cache:
uuid = element["uuid"] uuid = element["uuid"]
try: if os.path.exists(f"{instance_path}/search-partitions/{uuid}.pdf"):
os.remove(f"{instance_path}/search-partitions/{uuid}.pdf") os.remove(f"{instance_path}/search-partitions/{uuid}.pdf")
except FileNotFoundError:
pass if os.path.exists(f"{instance_path}/cache/search-thumbnails/{uuid}.jpg"):
try: os.remove(f"{instance_path}/cache/search-thumbnails/{uuid}.jpg")
os.remove(f"partitioncloud/static/search-thumbnails/{uuid}.jpg")
except FileNotFoundError:
pass
db.execute( db.execute(
""" """

View File

@ -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/<uuid>.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("/<uuid>.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")
)

View File

@ -11,7 +11,7 @@
<div> <div>
<a href="/partition/{{ partition['uuid'] }}"> <a href="/partition/{{ partition['uuid'] }}">
<div class="partition" id="partition-{{ partition['uuid'] }}"> <div class="partition" id="partition-{{ partition['uuid'] }}">
<img class="partition-thumbnail" src="/static/thumbnails/{{ partition['uuid'] }}.jpg"> <img class="partition-thumbnail" src="/thumbnails/{{ partition['uuid'] }}.jpg">
<div class="partition-description"> <div class="partition-description">
<div class="partition-name">{{ partition["name"] }}</div> <div class="partition-name">{{ partition["name"] }}</div>
<div class="partition-author">{{ partition["author"] }}</div> <div class="partition-author">{{ partition["author"] }}</div>

View File

@ -78,7 +78,7 @@
<div> <div>
<a href="/partition/{{ partition['uuid'] }}"> <a href="/partition/{{ partition['uuid'] }}">
<div class="partition" id="partition-{{ partition['uuid'] }}"> <div class="partition" id="partition-{{ partition['uuid'] }}">
<img class="partition-thumbnail" src="/static/thumbnails/{{ partition['uuid'] }}.jpg"> <img class="partition-thumbnail" src="/thumbnails/{{ partition['uuid'] }}.jpg">
<div class="partition-description"> <div class="partition-description">
<div class="partition-name">{{ partition["name"] }}</div> <div class="partition-name">{{ partition["name"] }}</div>
<div class="partition-author">{{ partition["author"] }}</div> <div class="partition-author">{{ partition["author"] }}</div>

View File

@ -10,7 +10,7 @@
<div class="partition-container"> <div class="partition-container">
<a href="/partition/{{ partition['uuid'] }}"> <a href="/partition/{{ partition['uuid'] }}">
<div class="partition" id="partition-{{ partition['uuid'] }}"> <div class="partition" id="partition-{{ partition['uuid'] }}">
<img class="partition-thumbnail" src="/static/thumbnails/{{ partition['uuid'] }}.jpg"> <img class="partition-thumbnail" src="/thumbnails/{{ partition['uuid'] }}.jpg">
<div class="partition-description"> <div class="partition-description">
<div class="partition-name">{{ partition["name"] }}</div> <div class="partition-name">{{ partition["name"] }}</div>
<div class="partition-author">{{ partition["author"] }}</div> <div class="partition-author">{{ partition["author"] }}</div>
@ -48,7 +48,7 @@
<div class="partition-container"> <div class="partition-container">
<a href="/partition/search/{{ partition['uuid'] }}"> <a href="/partition/search/{{ partition['uuid'] }}">
<div class="partition" id="partition-{{ partition['uuid'] }}"> <div class="partition" id="partition-{{ partition['uuid'] }}">
<img class="partition-thumbnail" src="/static/search-thumbnails/{{ partition['uuid'] }}.jpg"> <img class="partition-thumbnail" src="/thumbnails/search/{{ partition['uuid'] }}.jpg">
<div class="partition-description"> <div class="partition-description">
<div class="partition-name">{{ partition["name"] }}</div> <div class="partition-name">{{ partition["name"] }}</div>
</div> </div>

View File

@ -50,7 +50,7 @@
</tr> </tr>
<tr> <tr>
<td>Fichier</td> <td>Fichier</td>
<td><a href="/partition/{{ partition.uuid }}"><img class="partition-thumbnail" src="/static/thumbnails/{{ partition.uuid }}.jpg"></a></td> <td><a href="/partition/{{ partition.uuid }}"><img class="partition-thumbnail" src="/thumbnails/{{ partition.uuid }}.jpg"></a></td>
</tr> </tr>
<tr> <tr>
<td>Titre</td> <td>Titre</td>

View File

@ -11,7 +11,9 @@
<tbody> <tbody>
<tr> <tr>
<td>Fichier</td> <td>Fichier</td>
<td><a href="/partition/{{ partition.uuid }}"><img class="partition-thumbnail" src="/static/thumbnails/{{ partition.uuid }}.jpg"></a></td> <td><a href="/partition/{{ partition.uuid }}">
<img class="partition-thumbnail" src="/thumbnails/{{ partition.uuid }}.jpg">
</a></td>
</tr> </tr>
{% if partition.source != "unknown" and partition.source != "upload" %} {% if partition.source != "unknown" and partition.source != "upload" %}
<tr> <tr>

5
scripts/hooks/config.py Normal file
View File

@ -0,0 +1,5 @@
"""
Config parameters, shared between files
"""
instance = "instance"

View File

@ -2,10 +2,15 @@ import random
import string import string
import sqlite3 import sqlite3
from . import config
def run_sqlite_command(*args): def run_sqlite_command(*args):
"""Run a command against the database""" """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 = con.cursor()
cur.execute(*args) cur.execute(*args)
con.commit() con.commit()
@ -14,7 +19,10 @@ def run_sqlite_command(*args):
def get_sqlite_data(*args): def get_sqlite_data(*args):
"""Get data from the db""" """Get data from the db"""
con = sqlite3.connect("instance/partitioncloud.sqlite") con = sqlite3.connect(os.path.join(
config.instance,
"partitioncloud.sqlite"
))
cur = con.cursor() cur = con.cursor()
data = cur.execute(*args) data = cur.execute(*args)
new_data = list(data) new_data = list(data)

View File

@ -1,9 +1,11 @@
import os import os
import shutil import shutil
import sqlite3 import sqlite3
from hooks import utils
from colorama import Fore, Style from colorama import Fore, Style
from . import utils
from . import config
""" """
v1.3.* v1.3.*
""" """
@ -159,5 +161,13 @@ def move_instance():
for path in paths: for path in paths:
shutil.move( shutil.move(
os.path.join("partitioncloud", path), os.path.join("partitioncloud", path),
os.path.join("instance", path) 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)

View File

@ -6,7 +6,7 @@ import argparse
from functools import cmp_to_key from functools import cmp_to_key
from colorama import Fore, Style 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): def get_version(v: str) -> (int, int, int):
@ -33,7 +33,8 @@ hooks = [
], ],
), ),
("v1.4.1", [("Install qrcode", v1_hooks.install_qrcode)]), ("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) os.makedirs(dest)
paths = [ paths = [
("instance", os.path.join(dest, "instance")), (config.instance, os.path.join(dest, "instance")),
( (
os.path.join("partitioncloud", "partitions"), os.path.join("partitioncloud", "partitions"),
os.path.join(dest, "partitions"), os.path.join(dest, "partitions"),
@ -155,7 +156,7 @@ def restore(version):
dest = os.path.join("backups", version) dest = os.path.join("backups", version)
print(f"Restoring from {dest}") print(f"Restoring from {dest}")
paths = [ paths = [
("instance", os.path.join(dest, "instance")), (config.instance, os.path.join(dest, "instance")),
( (
os.path.join("partitioncloud", "partitions"), os.path.join("partitioncloud", "partitions"),
os.path.join(dest, "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("-c", "--current", help="current version (vx.y.z)")
parser.add_argument("-t", "--target", help="target 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("-s", "--skip-backup", action="store_true")
parser.add_argument( parser.add_argument(
"-r", "-r",
@ -199,6 +201,7 @@ if __name__ == "__main__":
) )
args = parser.parse_args() args = parser.parse_args()
config.instance = os.path.abspath(args.instance)
if args.restore is None: if args.restore is None:
migrate(args.current, args.target, skip_backup=args.skip_backup) migrate(args.current, args.target, skip_backup=args.skip_backup)