diff --git a/VERSION b/VERSION index 7ec1d6db..3e3c2f1e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.1.0 +2.1.1 diff --git a/apptax/migrations/versions/2c68a907f74c_increase_t_medias_source_size.py b/apptax/migrations/versions/2c68a907f74c_increase_t_medias_source_size.py new file mode 100644 index 00000000..be0e6f95 --- /dev/null +++ b/apptax/migrations/versions/2c68a907f74c_increase_t_medias_source_size.py @@ -0,0 +1,33 @@ +"""increase t_medias.source size + +Revision ID: 2c68a907f74c +Revises: 3c4762751898 +Create Date: 2024-12-19 10:31:05.778720 + +""" + +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = "2c68a907f74c" +down_revision = "3c4762751898" +branch_labels = None +depends_on = None + + +def upgrade(): + op.alter_column( + "t_medias", "source", type_=sa.Unicode(), existing_nullable=True, schema="taxonomie" + ) + + +def downgrade(): + op.alter_column( + "t_medias", + "source", + type_=sa.VARCHAR(length=25), + existing_nullable=True, + schema="taxonomie", + ) diff --git a/apptax/taxonomie/filemanager.py b/apptax/taxonomie/filemanager.py index a04e7c8a..be12a347 100644 --- a/apptax/taxonomie/filemanager.py +++ b/apptax/taxonomie/filemanager.py @@ -94,10 +94,17 @@ def create_thumb(self, media, size, force=False, regenerate=False): # Get Image try: - img = self._get_image_object(media) + img: Image = self._get_image_object(media) except TaxhubError as e: return None + # If width only was given in the parameter (height <=> size[1] < 0) + if size[1] < 0: + size[1] = img.width / size[0] * img.height + # Same with height + if size[0] < 0: + size[0] = img.height / size[1] * img.width + # Création du thumbnail resizeImg = resize_thumbnail(img, (size[0], size[1], force)) # Sauvegarde de l'image diff --git a/apptax/taxonomie/models.py b/apptax/taxonomie/models.py index d0b244d5..aaffafe4 100644 --- a/apptax/taxonomie/models.py +++ b/apptax/taxonomie/models.py @@ -174,7 +174,11 @@ class Taxref(db.Model): status = db.relationship("VBdcStatus", order_by="VBdcStatus.lb_type_statut") synonymes = db.relationship( - "Taxref", foreign_keys=[cd_ref], primaryjoin="Taxref.cd_ref == Taxref.cd_ref", uselist=True + "Taxref", + foreign_keys=[cd_ref], + primaryjoin="Taxref.cd_ref == Taxref.cd_ref", + uselist=True, + post_update=True, ) parent = db.relationship("Taxref", primaryjoin=foreign(cd_sup) == remote(cd_ref)) attributs = db.relationship("CorTaxonAttribut", back_populates="taxon") diff --git a/apptax/taxonomie/routestmedias.py b/apptax/taxonomie/routestmedias.py index f8ae7bfb..b3bc5a6d 100644 --- a/apptax/taxonomie/routestmedias.py +++ b/apptax/taxonomie/routestmedias.py @@ -3,6 +3,7 @@ from pathlib import Path import os from flask import json, Blueprint, request, current_app, send_file, abort +from werkzeug.exceptions import Forbidden from .models import TMedias, BibTypesMedia @@ -10,6 +11,7 @@ from .filemanager import FILEMANAGER +DEFAULT_THUMBNAIL_SIZE = (300, 400) adresses = Blueprint("t_media", __name__) logger = logging.getLogger() @@ -84,9 +86,22 @@ def getThumbnail_tmedias(id_media): ) params = request.args - size = (300, 400) - if ("h" in params) or ("w" in params): - size = (int(params.get("h", -1)), int(params.get("w", -1))) + + size = DEFAULT_THUMBNAIL_SIZE + + height_params: str = params.get("h", None) + width_params: str = params.get("w", None) + + if (width_params and not width_params.isdigit()) or ( + height_params and not height_params.isdigit() + ): + raise Forbidden("Valeur de la hauteur ou largeur incorrecte: Un entier est attendu") + + if width_params: + size = (int(width_params), size[1]) + + if height_params: + size = (size[0], int(height_params)) force = False if ("force" in params) and (params.get("force") == "true"): diff --git a/apptax/tests/fixtures.py b/apptax/tests/fixtures.py index aec6503f..f7fd46af 100644 --- a/apptax/tests/fixtures.py +++ b/apptax/tests/fixtures.py @@ -34,7 +34,6 @@ def noms_without_listexample(): with db.session.begin_nested(): for cd_nom, cd_ref, nom_francais, comments, attr in bibnom_exemple: nom = Taxref.query.get(cd_nom) - db.session.add(nom) noms.append(nom) return noms diff --git a/apptax/tests/test_media.py b/apptax/tests/test_media.py index 69fb287a..907ff323 100644 --- a/apptax/tests/test_media.py +++ b/apptax/tests/test_media.py @@ -1,8 +1,9 @@ import json import os +from apptax.taxonomie.models import BibTypesMedia, TMedias import pytest -from flask import url_for, current_app +from flask import url_for, current_app, Response from apptax.database import db @@ -39,6 +40,21 @@ def user(): return u +@pytest.fixture +def media(): + test_dir_absolute_path = os.path.dirname(os.path.abspath(__file__)) + with db.session.begin_nested(): + media = TMedias( + titre="test", + chemin=os.path.join(test_dir_absolute_path, "assets", "coccinelle.jpg"), + is_public=True, + types=BibTypesMedia.query.first(), + ) + db.session.add(media) + db.session.commit() + return media + + @pytest.mark.usefixtures("client_class", "temporary_transaction") class TestAPIMedia: @@ -117,8 +133,24 @@ def test_get_tmedias(self): # id_media = json.loads(response.data)["id_media"] # self.get_thumbnail(id_media) - def get_thumbnail(self, id_media): - response = self.client.get( - url_for("t_media.getThumbnail_tmedias", id_media=id_media), + @pytest.mark.parametrize( + "get_params,expected_status_code", + [ + ({}, 200), + (dict(w=100), 200), + (dict(h=100), 200), + (dict(w=100, h=100), 200), + (dict(w=100, h=-1), 403), + (dict(w="a", h="b"), 403), + (dict(h="b"), 403), + ], + ) + def test_get_thumbnail(self, media, get_params, expected_status_code): + id_media = media.id_media + + response: Response = self.client.get( + url_for( + "t_media.getThumbnail_tmedias", id_media=id_media, **get_params, regenerate="true" + ), ) - assert response.status_code == 200 + assert response.status_code == expected_status_code diff --git a/docs/changelog.md b/docs/changelog.md index b4d72d46..f1b42214 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,14 +1,22 @@ # CHANGELOG +2.1.1 (2024-01-14) +------------------ + +**🚀 Nouveautés** + +- La limite du nombre de caractères de la colonne `source` des médias est supprimée (#592, par @jacquesfize & @amandine-sahl) +- Ajout de la possibilité d'indiquer seulement la hauteur ou la largeur de la minitiature souhaitée sur la route `/thumbnail/` (#593, par @jacquesfize) + 2.1.0 (2024-12-06) ------------------ **🚀 Nouveautés** -- Optimisation de la VM `vm_taxref_tree` pour en améliorer les performances et gérer différents cas où des taxons locaux ont été ajoutés à la table `taxref` (#587) -- Ajout d'une route `/tmedias/types/` renvoyant la liste des types de médias (#588) -- Amélioration des performances de la route `/biblistes/` (#584) -- Ajout de la possibilité de filtrer la route `/taxref/` par une liste de cd_nom (#581) +- Optimisation de la VM `vm_taxref_tree` pour en améliorer les performances et gérer différents cas où des taxons locaux ont été ajoutés à la table `taxref` (#587 par @bouttier) +- Ajout d'une route `/tmedias/types/` renvoyant la liste des types de médias (#588 par @amandine-sahl) +- Amélioration des performances de la route `/biblistes/` (#584 par @andriacap) +- Ajout de la possibilité de filtrer la route `/taxref/` par une liste de cd_nom (#581 par @amandine-sahl) 2.0.0 (2024-10-29) ------------------