Implement album and groupe zip download

Disabled by default for users not logged in
This commit is contained in:
augustin64 2024-04-10 18:38:47 +02:00
parent 52894d37ea
commit d1812cdde7
4 changed files with 101 additions and 3 deletions

View File

@ -5,12 +5,12 @@ Albums module
import os import os
import pypdf import pypdf
import shutil import shutil
from uuid import uuid4 from uuid import uuid4
from typing import TypeVar from typing import TypeVar
from flask import (Blueprint, abort, flash, redirect, render_template, from flask import (Blueprint, abort, flash, redirect, render_template,
request, session, current_app) request, session, current_app, send_file, g, url_for)
from werkzeug.utils import secure_filename
from flask_babel import _ from flask_babel import _
from .auth import login_required from .auth import login_required
@ -115,6 +115,30 @@ def qr_code(uuid):
return utils.get_qrcode(f"/albums/{uuid}") return utils.get_qrcode(f"/albums/{uuid}")
@bp.route("/<uuid>/zip")
def zip_download(uuid):
"""
Télécharger un album comme fichier zip
"""
if g.user is None and current_app.config["ZIP_REQUIRE_LOGIN"]:
flash(_("You need to login to access this resource."))
return redirect(url_for("auth.login"))
try:
album = Album(uuid=uuid)
except LookupError:
try:
album = Album(uuid=utils.format_uuid(uuid))
return redirect(f"/albums/{utils.format_uuid(uuid)}")
except LookupError:
return abort(404)
return send_file(
album.to_zip(current_app.instance_path),
download_name=secure_filename(f"{album.name}.zip")
)
@bp.route("/create-album", methods=["POST"]) @bp.route("/create-album", methods=["POST"])
@login_required @login_required
def create_album_req(): def create_album_req():

View File

@ -2,6 +2,10 @@
Classe Album Classe Album
""" """
import os import os
import io
import zipfile
from werkzeug.utils import secure_filename
from ..db import get_db from ..db import get_db
from ..utils import new_uuid from ..utils import new_uuid
@ -165,6 +169,23 @@ class Album():
) )
db.commit() db.commit()
def to_zip(self, instance_path):
data = io.BytesIO()
with zipfile.ZipFile(data, mode="w") as z:
for partition in self.get_partitions():
z.write(os.path.join(
instance_path,
"partitions",
f"{partition['uuid']}.pdf"
), arcname=secure_filename(partition['name']+".pdf")
)
# Spooling back to the beginning of the buffer
data.seek(0)
return data
def create(name: str) -> str: def create(name: str) -> str:
"""Créer un nouvel album""" """Créer un nouvel album"""

View File

@ -1,3 +1,12 @@
"""
Classe Groupe
"""
import io
import os
import zipfile
from werkzeug.utils import secure_filename
from ..db import get_db from ..db import get_db
from .album import Album from .album import Album
@ -116,3 +125,21 @@ class Groupe():
(self.id,) (self.id,)
).fetchall() ).fetchall()
return [i["id"] for i in data] return [i["id"] for i in data]
def to_zip(self, instance_path):
data = io.BytesIO()
with zipfile.ZipFile(data, mode="w") as z:
for album in self.get_albums():
for partition in album.get_partitions():
z.write(os.path.join(
instance_path,
"partitions",
f"{partition['uuid']}.pdf"
), arcname=secure_filename(album.name)+"/"
+secure_filename(partition['name']+".pdf")
)
# Spooling back to the beginning of the buffer
data.seek(0)
return data

View File

@ -3,7 +3,8 @@
Groupe module Groupe module
""" """
from flask import (Blueprint, abort, flash, redirect, render_template, from flask import (Blueprint, abort, flash, redirect, render_template,
request, session, current_app) request, session, current_app, send_file, g, url_for)
from werkzeug.utils import secure_filename
from flask_babel import _ from flask_babel import _
from .auth import login_required from .auth import login_required
@ -261,6 +262,31 @@ def get_album(groupe_uuid, album_uuid):
) )
@bp.route("/<groupe_uuid>/zip")
def zip_download(groupe_uuid):
"""
Télécharger un groupe comme fichier zip
"""
if g.user is None and current_app.config["ZIP_REQUIRE_LOGIN"]:
flash(_("You need to login to access this resource."))
return redirect(url_for("auth.login"))
try:
groupe = Groupe(uuid=groupe_uuid)
except LookupError:
try:
groupe = Groupe(uuid=utils.format_uuid(groupe_uuid))
return redirect(f"/groupe/{utils.format_uuid(groupe_uuid)}/zip")
except LookupError:
return abort(404)
return send_file(
groupe.to_zip(current_app.instance_path),
download_name=secure_filename(f"{groupe.name}.zip")
)
@bp.route("/<groupe_uuid>/<album_uuid>/qr") @bp.route("/<groupe_uuid>/<album_uuid>/qr")
def groupe_qr_code(groupe_uuid, album_uuid): def groupe_qr_code(groupe_uuid, album_uuid):
return utils.get_qrcode(f"/groupe/{groupe_uuid}/{album_uuid}") return utils.get_qrcode(f"/groupe/{groupe_uuid}/{album_uuid}")