From 2c1e33429809f250eb5498689f9b9fa549044643 Mon Sep 17 00:00:00 2001 From: Adrien Delhorme Date: Mon, 11 Apr 2022 18:24:52 +0200 Subject: [PATCH] FEAT: add image cropping --- filer/admin/imageadmin.py | 8 +- filer/locale/fr/LC_MESSAGES/django.mo | Bin 18372 -> 17925 bytes filer/locale/fr/LC_MESSAGES/django.po | 416 +++++++++++++----------- filer/migrations/0015_image_cropping.py | 20 ++ filer/models/abstract.py | 5 + filer/templatetags/filer_admin_tags.py | 2 +- filer/utils/cropping.py | 7 + setup.py | 1 + 8 files changed, 273 insertions(+), 186 deletions(-) create mode 100644 filer/migrations/0015_image_cropping.py create mode 100644 filer/utils/cropping.py diff --git a/filer/admin/imageadmin.py b/filer/admin/imageadmin.py index d0062b3fe..619dfa141 100644 --- a/filer/admin/imageadmin.py +++ b/filer/admin/imageadmin.py @@ -2,6 +2,8 @@ from django.utils.translation import gettext as _ from django.utils.translation import gettext_lazy +from image_cropping.admin import ImageCroppingMixin + from ..settings import FILER_IMAGE_MODEL from ..thumbnail_processors import normalize_subject_location from ..utils.compatibility import string_concat @@ -89,7 +91,7 @@ class Media: ) -class ImageAdmin(FileAdmin): +class ImageAdmin(ImageCroppingMixin, FileAdmin): change_form_template = 'admin/filer/image/change_form.html' form = ImageAdminForm @@ -102,6 +104,10 @@ class ImageAdmin(FileAdmin): ImageAdmin.fieldsets = ImageAdmin.build_fieldsets( extra_main_fields=extra_main_fields, extra_fieldsets=( + (_('Cropping'), { + 'fields': ('cropping',), + 'classes': ('collapse',), + }), (_('Subject location'), { 'fields': ('subject_location',), 'classes': ('collapse',), diff --git a/filer/locale/fr/LC_MESSAGES/django.mo b/filer/locale/fr/LC_MESSAGES/django.mo index b3cffbda23081df76176fef7bcf076b37f6b3b3e..886ed104c8052a1b3d63f622f5b6f36f9fc0771e 100644 GIT binary patch delta 4645 zcmYk-3sBWn0>|;gOT+|$ODLd%A)tV~(nM1c3E!fLu8CwqA|WQoruGnSrm2}GdNE&> znpUi(tKD{erD7_k?ylNSw!4|T#puphR-?JQ&D6Bt-~AsO&-mkW&j0=&=k@=4a*f}M ztNh$oA_LbO%0<$Z>}+RDjGr;-p*m_zV}vpH;aW__53nD8j`w0jq%mA#Qm_MNU@#6q zPBHn|9*c1WmZENb6}hk5+@jK*1JN$$M*T3J_8`;)OR*a+K|OFgX5fCj2d`ls-ozNp zi83Y#$6_a(h-p}k+4u^EU<(HEd~=pcAO|j>Zty8;#NVMt63J6Ff>_i@6EO}`u_q44 z*;tM5;3cFlrXkvx5?qHG$PLu}qdFUtg&EkL=bOiG_^a=+$;#E}p zraj?DREL6@9?euLGTSB}HG-+A^QR+yGZmPL&!alH7j@oo+it~F+MnTg^mnth`%;;R z58!g_hexppe?U!n0k4SG`YBAt&8Qn3#|JSY-Wk9+tfpOpv#}LdVs?Ua{fDTx;Vaa0 z-C@j|Dg~H=Ph&6KhU(B6)Ce>U>Uj`qWLc<@=c8tBq&+?vwTWlh;|s8!_7c?hz>l5C zEsYD=J8sj@shHI`njfy>7|iPFO#LDZqrDaNHta#I`2h^Tqo|I2gzDHC)F%6fwaxzi z4QkDAS^b#K5WWAMsOSMPsGj%24w!2#z(CqXwq1;R&~()KHTHKmYSS%6b)XUTHf=(6 zd^_qs@7nfW4C49b5Eb^BX+e$TGHR;YkdLFejX~I+g_mKd%@~C`KMmEP9Mtax_V_4N zhbEw=ycF3^rUBKF*U+uXb}G8T+o&npk9xo(-x9-8e}W;j|88x=B-%Gn18`*+Q;8$-9PUMRY*D5$3voRTMt5kIGlDVrFbArU zbIlR#fZw3Lc>hIx(>u|N2pol4nrWz!mD%G}sHJ%hwO4lHXxxoD?|;}4HC;?H>raJ` zn8`&=;S~O8jaH)8awn=IEvOruLuT3h6;tpR9D*tL^D)9%SdGo7nT%pO*rz5A3vd`} z=9Xb+z5k6=)YE4B!#?Dm<}hkXzeWC;C>DMYjzWESmZ3J~O5}5HHlt>0KZfFY)Y5%{ z8lXO>_dq;qfN406=bJ(*QRuNYqdIg1@5NRO!^@}(zeX)ZP=90C&?XP{epjI$@G@$~ zHrV5DqGsqMY7YeDIy2K1-Fk2$6_(fJVkuUkc4sT*p&w7ve=_-4j`cVU|AnlfN#tbq zlPSVE*nkY$e2rRy9$dTtd*L&<72m*^LCn84+X3cPo95rBsSamrYAp+q{bH6Q%V`ec zB)oz8fDB_;TB;EkhtHxm*Q*$VJ1`cHSpSCMv~S@K49sKxBd9bpOl_(|I2W(sJe)j~ zosFll5_{7t-dM91wYEpmgWpw_m`{=N#e8Jkce+J)-Kaa2dnVQ>5d^?;u+5(6J{z7w5M=XFDMs3)>#+$M`k z3I}Fj0IopYU=?aaO{k9T!)|y2JL8wA8T%1+!{9>a0WJ)r9gCWoc+?)~i@M)<)b(@F zrT2d+6`i;db>VJQ&)-MA-=|PB@+s;;S5O_ijymrq`l0SIgKQ^fh^|%PZS@tslD{Xf zlPWTbjO6*g@)&LR3q%{#L!Ki$$OO`bOd|)$PEtTd6O{zt zU*|s}Rfm%Xa#ZVIL*)aa@)Vins~IyBw~~DF5m`;N0agC!V9sI*d7HdOGKk)qBC>_7 zAj`?!1MCAns z^CV8Ob)>nwitK@O=2U1QRB&$eIa+2hcyUT&Q8t+rjA*G}*i6wPp>Yc5bNn;zy zB8x~OSxDxPWOBr}SSP5d3??s<`$$KkvXX2jyUEkUMOsKYxlWb`L{9OC2(pZb1S`J(HQ~WqL@qm-i)qmI(W|}U-$1gwrpp0aE&#$emt9p{>WM?INn=-Ejc$@D3 REWlgee_^OMsPLHo{{g{E>#hI* delta 5065 zcmYk<33OD|9mnyTgam@D2@oJG!;*xs?+tq*ArvDZ4O$s(@?Q27j{q+cYtzE&UW! zVIxoj_^>t3MHRRfyW>v#{g*h5{@2)o@l6^>#j+y{RryHlf|IZpzKrp>4|Uujtc54A z1)f0__!a8PYBzHVZ-~kCn_)-njYT*Kx8YGtWPDSUWXu$N33Vk`Q71Odjp+$3QCFUe zn$jXvp%s{di%|u>k1B8RO4N!voGeJHW!@Pm|{SI{DIn;6AqAuhtux2+!kE9KiHw@f=4z75_vH+>FbUxtN9vuoJ$ADySND0d-hN zD!e}G!ZJ`-J_?z+ka@;_F%28?h2QzYyo4{(Uxr$w@g1F8m5f?ML#%7?Df)LY7c;1q zvCSfEfZI^_d_TtGVT{3(7^mm|3=LIQjaqE~u-=Irz~V&R^M}@W=20h1LJiOkRd`RV zi<#D3tVMsK?LUhervP>Q9DUFD=2aS6bjwi%tV2Ckn@|I7N1dn=wb%~Y{UT-W{Tx)9w)S^tskbaO!LzRuR2TVroe-2fc2lbScA?weCQ3dU> z?nnK;3N=$_Q3HH|D&%`q0WmBPU0^)w_X(Yte>IZWp%b)1{jeMAsmMl6@$>e3Kk9@b z)bCcI23(6ObSu`z-S+!~sDVF1P5ChlL>Y4t`Db!EGylwzDPf6@z_qBUyoQ>AA8h|8 z)bpF%#hKDRs258PHo+-&e+lZvv=CLuMhxRt)NvVIo%4=HJw4+?GK-=f<~(L;sN=_CZ!AGx<7P8X!z%2BExJ1eo2UD;Fbp>m%5YONz*t@4w(2qEWeiA1cf-6ylpTlu@7a1~S zhH)8n+2Kb`@jTSuf>qcUKSABYzoVw~rrm!Bbr1iCnz__I&U>H->K4pL9lsju;YQ>x zn(fHT(R_xz_59zbp&z7jIlA|msDh@VPEd%tB_)`K8*nHd!z_&EJ{4m&YNmE$DjvY$ zcpWu!?RhQg0=uFL&c=AgH=}8A5oQu+uZiKp`w%7^>+5MAICn!V>P=-3eT-0$ZY<~x8fJ3M?amsqp?!SSx z*#EWD51DUhXlfpyrX-g4uohtw>K?mLC(K1H$~@GSc~J!|KoztU({UB*_$o}mV;GB< zQO8|F6?PMQ==uMSMjAWX<~WbpNQ?}Ky0Sb}VWrp_7h)2=gPOU6s1u&VIQ$fKg;!BC zbRD%8?xW7vV5IZ=E|{oQJDi3NoP_$J4^?>?HpE4!8Ci`Q=q;>`+fm2u!6+O<9^XEq zlmFO`X5s2aiJ?;V=mzUSttKl;%@(d{SU*NDNh7Ps2C|WiB3+28Uq*J5o}^}*Lqqqb zBhllfs!x#>df{t(E%NCs*%`Dwq>}JPGS87JqU{&t6*87ACa1|sQnPXE%(J$m2mMIR z7r2R(5j{3M&XMQUZO5nU{Ey*yq~$y#%W41B_Ooy;e$P=Q+6o=aYHUhol3dc3)F%^3B1s}2k_6J2yh&aq zHQQ#}_!FKd`$-}B z+rNVQ$R9{ByrS{D8CkwyxAC62L6eoA@5=U+&j@%+gWeKT@cCTj-uWI^X}~kv>zPwI zw)vIlI;9@Jt3XF~OkP#D_AGCCxz}G2TOFRO6-gOwwOACCS% D#>idL diff --git a/filer/locale/fr/LC_MESSAGES/django.po b/filer/locale/fr/LC_MESSAGES/django.po index 9890d31d0..6e95d562b 100644 --- a/filer/locale/fr/LC_MESSAGES/django.po +++ b/filer/locale/fr/LC_MESSAGES/django.po @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Translators: # Translators: @@ -14,57 +14,60 @@ msgid "" msgstr "" "Project-Id-Version: django Filer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-04-09 08:57+0200\n" +"POT-Creation-Date: 2022-04-11 18:20+0200\n" "PO-Revision-Date: 2018-04-09 06:58+0000\n" "Last-Translator: yakky \n" -"Language-Team: French (http://www.transifex.com/divio/django-filer/language/fr/)\n" +"Language-Team: French (http://www.transifex.com/divio/django-filer/language/" +"fr/)\n" +"Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: admin/fileadmin.py:48 templates/admin/filer/tools/detail_info.html:166 +#: admin/fileadmin.py:40 msgid "Advanced" msgstr "Avancé" -#: admin/fileadmin.py:156 +#: admin/fileadmin.py:148 msgid "canonical URL" msgstr "URL canonique" -#: admin/folderadmin.py:387 admin/folderadmin.py:554 +#: admin/folderadmin.py:378 admin/folderadmin.py:545 msgid "" "Items must be selected in order to perform actions on them. No items have " "been changed." -msgstr "Des éléments doivent être sélectionnés pour effectuer les actions. Aucun élément n'a été modifié." +msgstr "" +"Des éléments doivent être sélectionnés pour effectuer les actions. Aucun " +"élément n'a été modifié." -#: admin/folderadmin.py:407 +#: admin/folderadmin.py:401 #, python-format msgid "%(total_count)s selected" msgid_plural "All %(total_count)s selected" msgstr[0] "%(total_count)s sélectionné" msgstr[1] "Tous les %(total_count)s sélectionnés" -#: admin/folderadmin.py:431 +#: admin/folderadmin.py:425 #, python-format msgid "Directory listing for %(folder_name)s" msgstr "" -#: admin/folderadmin.py:446 +#: admin/folderadmin.py:440 #, python-format msgid "0 of %(cnt)s selected" msgstr "0 sur %(cnt)s sélectionné" -#: admin/folderadmin.py:584 +#: admin/folderadmin.py:575 msgid "No action selected." msgstr "Pas d'action sélectionnée." -#: admin/folderadmin.py:629 +#: admin/folderadmin.py:627 #, python-format msgid "Successfully moved %(count)d files to clipboard." msgstr "%(count)d fichiers déplacés avec succès vers le presse-papiers." -#: admin/folderadmin.py:635 +#: admin/folderadmin.py:633 msgid "Move selected files to clipboard" msgstr "Déplacer les fichiers sélectionnés vers le presse-papiers" @@ -107,118 +110,125 @@ msgstr "Supprimer les fichiers et/ou dossiers" msgid "Delete selected files and/or folders" msgstr "Supprimer les fichiers et/ou dossiers sélectionnés" -#: admin/folderadmin.py:906 +#: admin/folderadmin.py:903 #, python-format msgid "Folders with names %s already exist at the selected destination" msgstr "Des dossiers nommés %s existent déjà dans la destination sélectionnée" -#: admin/folderadmin.py:910 +#: admin/folderadmin.py:907 #, python-format msgid "" "Successfully moved %(count)d files and/or folders to folder " "'%(destination)s'." -msgstr "%(count)d fichiers et/ou dossiers déplacés avec succès vers le dossier « %(destination)s »." +msgstr "" +"%(count)d fichiers et/ou dossiers déplacés avec succès vers le dossier " +"« %(destination)s »." -#: admin/folderadmin.py:918 admin/folderadmin.py:920 +#: admin/folderadmin.py:915 admin/folderadmin.py:917 msgid "Move files and/or folders" msgstr "Déplacer les fichiers et/ou dossiers" -#: admin/folderadmin.py:935 +#: admin/folderadmin.py:932 msgid "Move selected files and/or folders" msgstr "Déplacer les fichiers et/ou dossiers sélectionnés" -#: admin/folderadmin.py:992 +#: admin/folderadmin.py:989 #, python-format msgid "Successfully renamed %(count)d files." msgstr "%(count)d fichiers renommés avec succès." -#: admin/folderadmin.py:1001 admin/folderadmin.py:1003 -#: admin/folderadmin.py:1018 +#: admin/folderadmin.py:998 admin/folderadmin.py:1000 admin/folderadmin.py:1015 msgid "Rename files" msgstr "Renommer les fichiers" -#: admin/folderadmin.py:1113 +#: admin/folderadmin.py:1110 #, python-format msgid "" "Successfully copied %(count)d files and/or folders to folder " "'%(destination)s'." -msgstr "%(count)d fichiers et/dossiers copiés avec succès dans le dossier « %(destination)s »." +msgstr "" +"%(count)d fichiers et/dossiers copiés avec succès dans le dossier " +"« %(destination)s »." -#: admin/folderadmin.py:1131 admin/folderadmin.py:1133 +#: admin/folderadmin.py:1128 admin/folderadmin.py:1130 msgid "Copy files and/or folders" msgstr "Copier les fichiers et/ou dossiers" -#: admin/folderadmin.py:1150 +#: admin/folderadmin.py:1147 msgid "Copy selected files and/or folders" msgstr "Copier les fichiers et/ou dossiers sélectionnés" -#: admin/folderadmin.py:1255 +#: admin/folderadmin.py:1252 #, python-format msgid "Successfully resized %(count)d images." msgstr "%(count)d images redimensionnées avec succès." -#: admin/folderadmin.py:1262 admin/folderadmin.py:1264 +#: admin/folderadmin.py:1259 admin/folderadmin.py:1261 msgid "Resize images" msgstr "Redimensionner les images" -#: admin/folderadmin.py:1280 +#: admin/folderadmin.py:1277 msgid "Resize selected images" msgstr "Redimensionner les images sélectionnées" -#: admin/forms.py:27 +#: admin/forms.py:24 msgid "Suffix which will be appended to filenames of copied files." msgstr "Suffixe qui sera ajouté au nom des fichiers copiés." -#: admin/forms.py:34 +#: admin/forms.py:31 #, python-format msgid "" "Suffix should be a valid, simple and lowercase filename part, like " "\"%(valid)s\"." -msgstr "Le suffixe doit être une partie de nom de fichier valide, simple et en minuscules, comme « %(valid)s »." +msgstr "" +"Le suffixe doit être une partie de nom de fichier valide, simple et en " +"minuscules, comme « %(valid)s »." -#: admin/forms.py:55 +#: admin/forms.py:52 #, python-format msgid "Unknown rename format value key \"%(key)s\"." msgstr "La clé de formatage « %(key)s » est inconnue." -#: admin/forms.py:57 +#: admin/forms.py:54 #, python-format msgid "Invalid rename format: %(error)s." msgstr "Format de renommage non valide : %(error)s." -#: admin/forms.py:63 models/thumbnailoptionmodels.py:23 +#: admin/forms.py:64 models/thumbnailoptionmodels.py:37 msgid "thumbnail option" msgstr "option de miniature" -#: admin/forms.py:64 models/thumbnailoptionmodels.py:15 +#: admin/forms.py:67 models/thumbnailoptionmodels.py:15 msgid "width" msgstr "largeur" -#: admin/forms.py:65 models/thumbnailoptionmodels.py:16 +#: admin/forms.py:68 models/thumbnailoptionmodels.py:20 msgid "height" msgstr "hauteur" -#: admin/forms.py:66 models/thumbnailoptionmodels.py:17 +#: admin/forms.py:69 models/thumbnailoptionmodels.py:25 msgid "crop" msgstr "rogner" -#: admin/forms.py:67 models/thumbnailoptionmodels.py:18 +#: admin/forms.py:70 models/thumbnailoptionmodels.py:30 msgid "upscale" msgstr "agrandir" -#: admin/forms.py:72 +#: admin/forms.py:75 msgid "Thumbnail option or resize parameters must be choosen." -msgstr "Une option de miniature ou des paramètres de dimensionnement doivent être choisis." +msgstr "" +"Une option de miniature ou des paramètres de dimensionnement doivent être " +"choisis." -#: admin/forms.py:74 +#: admin/forms.py:77 msgid "Resize parameters must be choosen." msgstr "Des paramètres de dimensionnement doivent être choisis." -#: admin/imageadmin.py:20 admin/imageadmin.py:98 +#: admin/imageadmin.py:19 admin/imageadmin.py:110 msgid "Subject location" msgstr "Emplacement du sujet" -#: admin/imageadmin.py:21 +#: admin/imageadmin.py:20 msgid "Location of the main subject of the scene. Format: \"x,y\"." msgstr "Emplacement du sujet principal de la scène. Format : « x,y »." @@ -226,79 +236,83 @@ msgstr "Emplacement du sujet principal de la scène. Format : « x,y »." msgid "Invalid subject location format. " msgstr "Format d'emplacement de sujet invalide." -#: admin/imageadmin.py:64 +#: admin/imageadmin.py:66 msgid "Subject location is outside of the image. " msgstr "L'emplacement du sujet est en dehors de l'image." -#: admin/imageadmin.py:73 +#: admin/imageadmin.py:75 #, python-brace-format msgid "Your input: \"{subject_location}\". " msgstr "Votre entrée : « {subject_location} »." -#: admin/views.py:57 +#: admin/imageadmin.py:106 +msgid "Cropping" +msgstr "Recadrage" + +#: admin/views.py:55 msgid "Folder with this name already exists." msgstr "Il existe déjà un dossier avec ce nom." -#: apps.py:10 templates/admin/filer/breadcrumbs.html:5 +#: apps.py:7 templates/admin/filer/breadcrumbs.html:5 #: templates/admin/filer/folder/change_form.html:7 #: templates/admin/filer/folder/directory_listing.html:47 msgid "Filer" msgstr "Filer" -#: contrib/django_cms/cms_toolbars.py:47 +#: contrib/django_cms/cms_toolbars.py:44 msgid "Media library" msgstr "Bibliotèque multimedia" -#: models/abstract.py:36 +#: models/abstract.py:44 msgid "default alt text" msgstr "texte alternatif par défaut" -#: models/abstract.py:37 +#: models/abstract.py:51 msgid "default caption" msgstr "légende par défaut" -#: models/abstract.py:39 +#: models/abstract.py:58 msgid "subject location" msgstr "emplacement du sujet" -#: models/abstract.py:184 +#: models/abstract.py:77 msgid "image" msgstr "image" -#: models/abstract.py:185 +#: models/abstract.py:78 msgid "images" msgstr "images" -#: models/clipboardmodels.py:17 models/foldermodels.py:270 +#: models/clipboardmodels.py:11 models/foldermodels.py:304 msgid "user" msgstr "utilisateur" -#: models/clipboardmodels.py:19 models/filemodels.py:356 +#: models/clipboardmodels.py:17 models/filemodels.py:148 msgid "files" msgstr "fichiers" -#: models/clipboardmodels.py:37 models/clipboardmodels.py:43 +#: models/clipboardmodels.py:24 models/clipboardmodels.py:50 msgid "clipboard" msgstr "presse-papiers" -#: models/clipboardmodels.py:38 +#: models/clipboardmodels.py:25 msgid "clipboards" msgstr "presse-papiers" -#: models/clipboardmodels.py:42 models/filemodels.py:58 -#: models/filemodels.py:355 +#: models/clipboardmodels.py:44 models/filemodels.py:65 +#: models/filemodels.py:147 msgid "file" msgstr "fichier" -#: models/clipboardmodels.py:47 +#: models/clipboardmodels.py:56 msgid "clipboard item" msgstr "élément du presse-papiers" -#: models/clipboardmodels.py:48 +#: models/clipboardmodels.py:57 msgid "clipboard items" msgstr "éléments du presse-papiers" -#: models/filemodels.py:56 templates/admin/filer/folder/change_form.html:8 +#: models/filemodels.py:57 templates/admin/filer/folder/change_form.html:8 #: templates/admin/filer/folder/directory_listing.html:118 #: templates/admin/filer/folder/new_folder_form.html:4 #: templates/admin/filer/folder/new_folder_form.html:7 @@ -306,159 +320,164 @@ msgstr "éléments du presse-papiers" msgid "folder" msgstr "dossier" -#: models/filemodels.py:59 +#: models/filemodels.py:72 msgid "file size" msgstr "taille du fichier" -#: models/filemodels.py:61 +#: models/filemodels.py:78 msgid "sha1" msgstr "sha1" -#: models/filemodels.py:63 +#: models/filemodels.py:85 msgid "has all mandatory data" msgstr "possède toutes les données nécessaires" -#: models/filemodels.py:65 +#: models/filemodels.py:91 msgid "original filename" msgstr "nom de fichier originel" -#: models/filemodels.py:67 models/foldermodels.py:104 -#: models/thumbnailoptionmodels.py:14 +#: models/filemodels.py:101 models/foldermodels.py:109 +#: models/thumbnailoptionmodels.py:10 msgid "name" msgstr "nom" -#: models/filemodels.py:69 +#: models/filemodels.py:107 msgid "description" msgstr "description" -#: models/filemodels.py:73 models/foldermodels.py:106 +#: models/filemodels.py:116 models/foldermodels.py:115 msgid "owner" msgstr "propriétaire" -#: models/filemodels.py:75 models/foldermodels.py:110 +#: models/filemodels.py:120 models/foldermodels.py:123 msgid "uploaded at" msgstr "téléversé le" -#: models/filemodels.py:76 models/foldermodels.py:113 +#: models/filemodels.py:125 models/foldermodels.py:133 msgid "modified at" msgstr "modifié le" -#: models/filemodels.py:80 +#: models/filemodels.py:131 msgid "Permissions disabled" msgstr "Permissions désactivées" -#: models/filemodels.py:81 +#: models/filemodels.py:132 msgid "" "Disable any permission checking for this file. File will be publicly " "accessible to anyone." -msgstr "Désactiver la vérification des permissions pour ce fichier. Le fichier sera publiquement accessible à tout le monde." +msgstr "" +"Désactiver la vérification des permissions pour ce fichier. Le fichier sera " +"publiquement accessible à tout le monde." -#: models/foldermodels.py:112 +#: models/foldermodels.py:128 msgid "created at" msgstr "créé le" -#: models/foldermodels.py:235 -#: templates/admin/filer/widgets/admin_folder.html:7 +#: models/foldermodels.py:145 templates/admin/filer/widgets/admin_folder.html:7 #: templates/admin/filer/widgets/admin_folder.html:33 msgid "Folder" msgstr "Dossier" -#: models/foldermodels.py:236 +#: models/foldermodels.py:146 msgid "Folders" msgstr "Dossiers" -#: models/foldermodels.py:255 +#: models/foldermodels.py:275 msgid "all items" msgstr "tous les éléments" -#: models/foldermodels.py:256 +#: models/foldermodels.py:276 msgid "this item only" msgstr "cet élément seulement" -#: models/foldermodels.py:257 +#: models/foldermodels.py:277 msgid "this item and all children" msgstr "cet élément et ses enfants" -#: models/foldermodels.py:261 +#: models/foldermodels.py:281 +msgid "inherit" +msgstr "" + +#: models/foldermodels.py:282 msgid "allow" msgstr "autoriser" -#: models/foldermodels.py:262 +#: models/foldermodels.py:283 msgid "deny" msgstr "refuser" -#: models/foldermodels.py:267 +#: models/foldermodels.py:295 msgid "type" msgstr "type" -#: models/foldermodels.py:273 +#: models/foldermodels.py:312 msgid "group" msgstr "groupe" -#: models/foldermodels.py:274 +#: models/foldermodels.py:319 msgid "everybody" msgstr "tous" -#: models/foldermodels.py:276 -msgid "can edit" -msgstr "peut éditer" - -#: models/foldermodels.py:277 +#: models/foldermodels.py:324 msgid "can read" msgstr "peut lire" -#: models/foldermodels.py:278 +#: models/foldermodels.py:332 +msgid "can edit" +msgstr "peut éditer" + +#: models/foldermodels.py:340 msgid "can add children" msgstr "peut ajouter un enfant" -#: models/foldermodels.py:320 +#: models/foldermodels.py:348 msgid "folder permission" msgstr "permission du dossier" -#: models/foldermodels.py:321 +#: models/foldermodels.py:349 msgid "folder permissions" msgstr "permissions du dossier" -#: models/imagemodels.py:21 +#: models/imagemodels.py:18 msgid "date taken" msgstr "date de prise de vue" -#: models/imagemodels.py:23 +#: models/imagemodels.py:25 msgid "author" msgstr "auteur" -#: models/imagemodels.py:24 +#: models/imagemodels.py:32 msgid "must always publish author credit" msgstr "doit toujours publier l'attribution à l'auteur" -#: models/imagemodels.py:25 +#: models/imagemodels.py:37 msgid "must always publish copyright" msgstr "doit toujours publier le droit d'auteur" -#: models/thumbnailoptionmodels.py:15 +#: models/thumbnailoptionmodels.py:16 msgid "width in pixel." msgstr "largeur en pixels." -#: models/thumbnailoptionmodels.py:16 +#: models/thumbnailoptionmodels.py:21 msgid "height in pixel." msgstr "hauteur en pixels." -#: models/thumbnailoptionmodels.py:24 +#: models/thumbnailoptionmodels.py:38 msgid "thumbnail options" msgstr "options de miniature" -#: models/virtualitems.py:50 +#: models/virtualitems.py:46 #: templates/admin/filer/folder/directory_table.html:4 #: templates/admin/filer/folder/directory_table.html:157 #: templates/admin/filer/tools/clipboard/clipboard.html:27 msgid "Unsorted Uploads" msgstr "Téléversements non triés" -#: models/virtualitems.py:65 +#: models/virtualitems.py:61 msgid "files with missing metadata" msgstr "fichiers avec des métadonnées manquantes" -#: models/virtualitems.py:79 templates/admin/filer/breadcrumbs.html:7 +#: models/virtualitems.py:75 templates/admin/filer/breadcrumbs.html:7 #: templates/admin/filer/folder/change_form.html:8 #: templates/admin/filer/folder/directory_listing.html:51 #: templates/admin/filer/folder/directory_listing.html:118 @@ -527,19 +546,26 @@ msgid "" "Deleting the selected files and/or folders would result in deleting related " "objects, but your account doesn't have permission to delete the following " "types of objects:" -msgstr "Supprimer les fichiers et/ou dossiers sélectionnés devrait provoquer la suppression des objets liés, mais votre compte n'a pas les permissions nécessaires pour supprimer les types d'objets suivants :" +msgstr "" +"Supprimer les fichiers et/ou dossiers sélectionnés devrait provoquer la " +"suppression des objets liés, mais votre compte n'a pas les permissions " +"nécessaires pour supprimer les types d'objets suivants :" #: templates/admin/filer/delete_selected_files_confirmation.html:19 msgid "" "Deleting the selected files and/or folders would require deleting the " "following protected related objects:" -msgstr "Supprimer les fichiers et/ou dossiers provoquera la suppression des objets liés protégés suivants :" +msgstr "" +"Supprimer les fichiers et/ou dossiers provoquera la suppression des objets " +"liés protégés suivants :" #: templates/admin/filer/delete_selected_files_confirmation.html:27 msgid "" "Are you sure you want to delete the selected files and/or folders? All of " "the following objects and their related items will be deleted:" -msgstr "Voulez-vous vraiment supprimer les fichiers et/ou dossiers sélectionnés ? Tous les objets suivants et leurs éléments liés seront supprimés :" +msgstr "" +"Voulez-vous vraiment supprimer les fichiers et/ou dossiers sélectionnés ? " +"Tous les objets suivants et leurs éléments liés seront supprimés :" #: templates/admin/filer/delete_selected_files_confirmation.html:46 #: templates/admin/filer/folder/choose_copy_destination.html:77 @@ -551,15 +577,15 @@ msgstr "Non, faites-moi revenir" msgid "Yes, I'm sure" msgstr "Oui, je suis sûr" -#: templates/admin/filer/file/change_form.html:37 +#: templates/admin/filer/file/change_form.html:35 #: templates/admin/filer/folder/change_form.html:21 -#: templates/admin/filer/image/change_form.html:36 +#: templates/admin/filer/image/change_form.html:35 msgid "History" msgstr "Historique" -#: templates/admin/filer/file/change_form.html:39 +#: templates/admin/filer/file/change_form.html:37 #: templates/admin/filer/folder/change_form.html:23 -#: templates/admin/filer/image/change_form.html:38 +#: templates/admin/filer/image/change_form.html:37 msgid "View on site" msgstr "Voir sur le site" @@ -585,9 +611,11 @@ msgstr "Icône du dossier" #: templates/admin/filer/folder/choose_copy_destination.html:36 msgid "" -"Your account doesn't have permissions to copy all of the selected files " -"and/or folders." -msgstr "Votre compte n'a pas les permissions nécessaires pour copier tous les fichiers et/ou dossiers sélectionnés." +"Your account doesn't have permissions to copy all of the selected files and/" +"or folders." +msgstr "" +"Votre compte n'a pas les permissions nécessaires pour copier tous les " +"fichiers et/ou dossiers sélectionnés." #: templates/admin/filer/folder/choose_copy_destination.html:38 #: templates/admin/filer/folder/choose_copy_destination.html:44 @@ -611,7 +639,9 @@ msgstr "Aucun fichier ou dossier n'est disponible à copier." msgid "" "The following files and/or folders will be copied to a destination folder " "(retaining their tree structure):" -msgstr "Les fichiers et/ou dossiers suivants seront copiés vers un dossier de destination (en conservant leur arborescence) :" +msgstr "" +"Les fichiers et/ou dossiers suivants seront copiés vers un dossier de " +"destination (en conservant leur arborescence) :" #: templates/admin/filer/folder/choose_copy_destination.html:67 #: templates/admin/filer/folder/choose_move_destination.html:65 @@ -631,7 +661,9 @@ msgstr "Il est impossible de copier des fichiers dans le même dossier" #: templates/admin/filer/folder/choose_images_resize_options.html:15 msgid "" "Your account doesn't have permissions to resize all of the selected images." -msgstr "Votre compte na pas les permissions nécessaires pour redimensionner toutes les images sélectionnées." +msgstr "" +"Votre compte na pas les permissions nécessaires pour redimensionner toutes " +"les images sélectionnées." #: templates/admin/filer/folder/choose_images_resize_options.html:18 msgid "There are no images available to resize." @@ -643,7 +675,9 @@ msgstr "Les images suivantes seront redimensionnées :" #: templates/admin/filer/folder/choose_images_resize_options.html:33 msgid "Choose an existing thumbnail option or enter resize parameters:" -msgstr "Choisissez une option de miniature existante ou entrez des paramètres de redimensionnement :" +msgstr "" +"Choisissez une option de miniature existante ou entrez des paramètres de " +"redimensionnement :" #: templates/admin/filer/folder/choose_images_resize_options.html:35 msgid "Choose resize parameters:" @@ -653,7 +687,10 @@ msgstr "Choisissez des paramètres de redimensionnement :" msgid "" "Warning: Images will be resized in-place and originals will be lost. Maybe " "first make a copy of them to retain the originals." -msgstr "Avertissement : Les images seront redimensionnées en place et les originales seront perdues. Faites-en éventuellement une copie préalable afin de les conserver." +msgstr "" +"Avertissement : Les images seront redimensionnées en place et les originales " +"seront perdues. Faites-en éventuellement une copie préalable afin de les " +"conserver." #: templates/admin/filer/folder/choose_images_resize_options.html:41 msgid "Resize" @@ -661,9 +698,11 @@ msgstr "Redimensionner" #: templates/admin/filer/folder/choose_move_destination.html:36 msgid "" -"Your account doesn't have permissions to move all of the selected files " -"and/or folders." -msgstr "Votre compte n'a pas les permissions nécessaires pour déplacer tous les fichiers et/ou dossiers sélectionnés." +"Your account doesn't have permissions to move all of the selected files and/" +"or folders." +msgstr "" +"Votre compte n'a pas les permissions nécessaires pour déplacer tous les " +"fichiers et/ou dossiers sélectionnés." #: templates/admin/filer/folder/choose_move_destination.html:48 msgid "There are no files and/or folders available to move." @@ -673,7 +712,9 @@ msgstr "Il n'y a pas de fichiers et/ou dossiers disponibles à déplacer." msgid "" "The following files and/or folders will be moved to a destination folder " "(retaining their tree structure):" -msgstr "Les fichiers et/ou dossiers suivants seront déplacés vers un dossier de destination (en conservant leur arborescence) :" +msgstr "" +"Les fichiers et/ou dossiers suivants seront déplacés vers un dossier de " +"destination (en conservant leur arborescence) :" #: templates/admin/filer/folder/choose_move_destination.html:74 #: templates/admin/filer/folder/choose_move_destination.html:77 @@ -688,7 +729,9 @@ msgstr "Il est impossible de déplacer des fichiers dans le même dossier" #: templates/admin/filer/folder/choose_rename_format.html:15 msgid "" "Your account doesn't have permissions to rename all of the selected files." -msgstr "Votre compte n'a pas les permissions nécessaires pour renommer tous les fichiers sélectionnés." +msgstr "" +"Votre compte n'a pas les permissions nécessaires pour renommer tous les " +"fichiers sélectionnés." #: templates/admin/filer/folder/choose_rename_format.html:18 msgid "There are no files available to rename." @@ -698,7 +741,10 @@ msgstr "Il n'y a pas de fichiers disponibles à renommer." msgid "" "The following files will be renamed (they will stay in their folders and " "keep original filename, only displayed filename will be changed):" -msgstr "Les fichiers suivants seront renommés (ils resteront dans leurs dossiers et conserveront leur nom de fichier d'origine ; seul le nom affiché sera changé) :" +msgstr "" +"Les fichiers suivants seront renommés (ils resteront dans leurs dossiers et " +"conserveront leur nom de fichier d'origine ; seul le nom affiché sera " +"changé) :" #: templates/admin/filer/folder/choose_rename_format.html:59 msgid "Rename" @@ -741,7 +787,6 @@ msgid "Limit the search to current folder" msgstr "Limiter la recherche au dossier actuel" #: templates/admin/filer/folder/directory_listing.html:191 -#: templates/admin/filer/tools/detail_info.html:213 msgid "Delete" msgstr "Supprimer" @@ -770,14 +815,12 @@ msgid "Name" msgstr "Nom" #: templates/admin/filer/folder/directory_table.html:14 -#: templates/admin/filer/tools/detail_info.html:59 -#: templates/admin/filer/tools/detail_info.html:150 +#: templates/admin/filer/tools/detail_info.html:56 msgid "Owner" msgstr "Propriétaire" #: templates/admin/filer/folder/directory_table.html:15 -#: templates/admin/filer/tools/detail_info.html:38 -#: templates/admin/filer/tools/detail_info.html:102 +#: templates/admin/filer/tools/detail_info.html:35 msgid "Size" msgstr "Taille" @@ -844,13 +887,11 @@ msgstr "activé" #: templates/admin/filer/folder/directory_table.html:139 #, python-format -#| msgid "Change '%(item_label)s' details" msgid "Canonical url '%(item_label)s'" msgstr "url canonique '%(item_label)s' " #: templates/admin/filer/folder/directory_table.html:141 #, python-format -#| msgid "Change '%(item_label)s' details" msgid "Download '%(item_label)s'" msgstr "Télécharger '%(item_label)s' " @@ -860,7 +901,8 @@ msgstr "Supprimer le fichier" #: templates/admin/filer/folder/directory_table.html:151 msgid "Drop files here or use the \"Upload Files\" button" -msgstr "Déposez des fichiers ici ou utilisez le bouton « Téléverser des fichiers »" +msgstr "" +"Déposez des fichiers ici ou utilisez le bouton « Téléverser des fichiers »" #: templates/admin/filer/folder/directory_table.html:161 msgid "Drop your file to upload into:" @@ -919,6 +961,14 @@ msgstr[1] "Veuillez corriger les erreurs suivantes." msgid "Save" msgstr "Sauvegarder" +#: templates/admin/filer/templatetags/file_icon.html:9 +msgid "Your browser does not support audio." +msgstr "" + +#: templates/admin/filer/templatetags/file_icon.html:14 +msgid "Your browser does not support video." +msgstr "" + #: templates/admin/filer/tools/clipboard/clipboard.html:9 msgid "Clipboard" msgstr "Presse-papiers" @@ -943,59 +993,38 @@ msgstr "Le presse-papiers est vide" msgid "upload failed" msgstr "transfert échoué" -#: templates/admin/filer/tools/detail_info.html:22 -msgid "Open file" -msgstr "Ouvrir le fichier" +#: templates/admin/filer/tools/detail_info.html:13 +msgid "Download" +msgstr "" -#: templates/admin/filer/tools/detail_info.html:24 -#: templates/admin/filer/tools/detail_info.html:86 -msgid "Full size preview" -msgstr "Afficher en pleine taille" +#: templates/admin/filer/tools/detail_info.html:17 +msgid "Expand" +msgstr "" + +#: templates/admin/filer/tools/detail_info.html:22 +#: templates/admin/filer/widgets/admin_file.html:29 +#: templatetags/filer_admin_tags.py:69 +#, fuzzy +#| msgid "file missing" +msgid "File is missing" +msgstr "fichier manquant" -#: templates/admin/filer/tools/detail_info.html:34 -#: templates/admin/filer/tools/detail_info.html:93 +#: templates/admin/filer/tools/detail_info.html:31 msgid "Type" msgstr "Type" -#: templates/admin/filer/tools/detail_info.html:42 -#: templates/admin/filer/tools/detail_info.html:111 +#: templates/admin/filer/tools/detail_info.html:39 msgid "File-size" msgstr "Taille de fichier" -#: templates/admin/filer/tools/detail_info.html:46 -#: templates/admin/filer/tools/detail_info.html:120 +#: templates/admin/filer/tools/detail_info.html:43 msgid "Modified" msgstr "Modifié" -#: templates/admin/filer/tools/detail_info.html:50 -#: templates/admin/filer/tools/detail_info.html:129 +#: templates/admin/filer/tools/detail_info.html:47 msgid "Created" msgstr "Créé" -#: templates/admin/filer/tools/detail_info.html:158 -msgid "Add Description" -msgstr "Ajouter une description" - -#: templates/admin/filer/tools/detail_info.html:176 -msgid "Author" -msgstr "Auteur" - -#: templates/admin/filer/tools/detail_info.html:183 -msgid "Add Alt-Text" -msgstr "Ajouter un texte alternatif" - -#: templates/admin/filer/tools/detail_info.html:190 -msgid "Add caption" -msgstr "Ajouter une légende" - -#: templates/admin/filer/tools/detail_info.html:197 -msgid "Add Tags" -msgstr "Ajouter des balises" - -#: templates/admin/filer/tools/detail_info.html:204 -msgid "Change File" -msgstr "Changer le fichier" - #: templates/admin/filer/tools/search_form.html:5 msgid "found" msgstr "trouvé :" @@ -1008,31 +1037,26 @@ msgstr "et" msgid "cancel search" msgstr "annuler la recherche" -#: templates/admin/filer/widgets/admin_file.html:8 -#: templates/admin/filer/widgets/admin_file.html:35 +#: templates/admin/filer/widgets/admin_file.html:10 +#: templates/admin/filer/widgets/admin_file.html:37 #: templates/admin/filer/widgets/admin_folder.html:18 msgid "Clear" msgstr "Effacer" -#: templates/admin/filer/widgets/admin_file.html:17 +#: templates/admin/filer/widgets/admin_file.html:19 msgid "or drop your file here" msgstr "ou déposez votre fichier ici" -#: templates/admin/filer/widgets/admin_file.html:26 -#: templates/admin/filer/widgets/admin_file.html:27 -msgid "file missing" -msgstr "fichier manquant" - -#: templates/admin/filer/widgets/admin_file.html:30 +#: templates/admin/filer/widgets/admin_file.html:32 msgid "no file selected" msgstr "pas de fichier sélectionné" -#: templates/admin/filer/widgets/admin_file.html:39 +#: templates/admin/filer/widgets/admin_file.html:41 #: templates/admin/filer/widgets/admin_folder.html:14 msgid "Lookup" msgstr "Recherche" -#: templates/admin/filer/widgets/admin_file.html:40 +#: templates/admin/filer/widgets/admin_file.html:42 msgid "Choose File" msgstr "Sélectionner un fichier" @@ -1045,6 +1069,30 @@ msgstr "aucune sélection" msgid "Add Folder" msgstr "Ajouter un dossier" +#~ msgid "Open file" +#~ msgstr "Ouvrir le fichier" + +#~ msgid "Full size preview" +#~ msgstr "Afficher en pleine taille" + +#~ msgid "Add Description" +#~ msgstr "Ajouter une description" + +#~ msgid "Author" +#~ msgstr "Auteur" + +#~ msgid "Add Alt-Text" +#~ msgstr "Ajouter un texte alternatif" + +#~ msgid "Add caption" +#~ msgstr "Ajouter une légende" + +#~ msgid "Add Tags" +#~ msgstr "Ajouter des balises" + +#~ msgid "Change File" +#~ msgstr "Changer le fichier" + #~ msgid "Subject Location" #~ msgstr "Subject location" diff --git a/filer/migrations/0015_image_cropping.py b/filer/migrations/0015_image_cropping.py new file mode 100644 index 000000000..dd8eade48 --- /dev/null +++ b/filer/migrations/0015_image_cropping.py @@ -0,0 +1,20 @@ +# Generated by Django 2.2.26 on 2022-04-11 13:11 + +from django.db import migrations + +import image_cropping.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('filer', '0014_folder_permission_choices'), + ] + + operations = [ + migrations.AddField( + model_name='image', + name='cropping', + field=image_cropping.fields.ImageRatioField('file', '100x100', adapt_rotation=False, allow_fullsize=True, free_crop=True, help_text=None, hide_image_field=False, size_warning=False, verbose_name='cropping'), + ), + ] diff --git a/filer/models/abstract.py b/filer/models/abstract.py index f07c7fcc1..53e695023 100644 --- a/filer/models/abstract.py +++ b/filer/models/abstract.py @@ -5,6 +5,7 @@ from django.utils.translation import gettext_lazy as _ from easy_thumbnails.VIL import Image as VILImage +from image_cropping import ImageRatioField from .. import settings as filer_settings from ..utils.compatibility import PILImage @@ -60,6 +61,10 @@ class BaseImage(File): default='', ) + cropping = ImageRatioField( + "file", "100x100", free_crop=True, allow_fullsize=True + ) + file_ptr = models.OneToOneField( to='filer.File', parent_link=True, diff --git a/filer/templatetags/filer_admin_tags.py b/filer/templatetags/filer_admin_tags.py index 8342eda70..e9fa92e98 100644 --- a/filer/templatetags/filer_admin_tags.py +++ b/filer/templatetags/filer_admin_tags.py @@ -84,7 +84,7 @@ def file_icon_context(file, detail, width, height): context['sidebar_image_ratio'] = file.width / 210 opts = {'size': (width, height), 'upscale': True} else: - opts = {'size': (width, height), 'crop': True} + opts = {'size': (width, height), 'crop': True, 'box': file.cropping} icon_url = thumbnailer.get_thumbnail(opts).url context['alt_text'] = file.default_alt_text if mime_subtype != 'svg+xml': diff --git a/filer/utils/cropping.py b/filer/utils/cropping.py new file mode 100644 index 000000000..c5ef665ad --- /dev/null +++ b/filer/utils/cropping.py @@ -0,0 +1,7 @@ +from image_cropping.backends.easy_thumbs import EasyThumbnailsBackend +from image_cropping.widgets import ImageCropWidget + + +class FilerBackend(EasyThumbnailsBackend): + WIDGETS = dict(EasyThumbnailsBackend.WIDGETS) + WIDGETS['MultiStorageFileField'] = ImageCropWidget diff --git a/setup.py b/setup.py index c36789f1f..620e49bde 100644 --- a/setup.py +++ b/setup.py @@ -10,6 +10,7 @@ 'django-polymorphic>=2,<3.1', 'easy-thumbnails>=2.8.0', 'Unidecode>=0.04,<1.2', + 'django-image-cropping>=1.7,<2', ]