From 846688a9a2b1285c257ab898647843f866f60678 Mon Sep 17 00:00:00 2001 From: Aymeric Jakobowski Date: Mon, 18 Sep 2023 16:42:14 +0200 Subject: [PATCH 01/19] Add breadcrumb link for Home --- pod/main/templates/base.html | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/pod/main/templates/base.html b/pod/main/templates/base.html index 7a8cf660b1..0f59dda399 100644 --- a/pod/main/templates/base.html +++ b/pod/main/templates/base.html @@ -82,9 +82,17 @@ From 6197c7668e31a46e5304c093ace804c8dcd32c33 Mon Sep 17 00:00:00 2001 From: Aymeric Jakobowski Date: Mon, 18 Sep 2023 16:57:33 +0200 Subject: [PATCH 02/19] Fix sort direction when less than 2 videos --- .../js/filter-aside-playlist-list-refresh.js | 22 ++++++++++--------- .../templates/playlist/playlists.html | 2 +- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/pod/playlist/static/playlist/js/filter-aside-playlist-list-refresh.js b/pod/playlist/static/playlist/js/filter-aside-playlist-list-refresh.js index 5fdff03a3d..fd31d339cb 100644 --- a/pod/playlist/static/playlist/js/filter-aside-playlist-list-refresh.js +++ b/pod/playlist/static/playlist/js/filter-aside-playlist-list-refresh.js @@ -46,15 +46,17 @@ function refreshPlaylistsSearch() { }); } - -// Add trigger event to manage sort direction. -document - .getElementById('sort_direction_label') - .addEventListener('click', function (e) { - e.preventDefault(); - toggleSortDirection(); +let playlist_list = document.getElementById("playlists_list"); +if (playlist_list.dataset.numberVideos >= 2) { + // Add trigger event to manage sort direction. + document + .getElementById('sort_direction_label') + .addEventListener('click', function (e) { + e.preventDefault(); + toggleSortDirection(); + refreshPlaylistsSearch(); + }); + document.getElementById('sort').addEventListener('change', function (e) { refreshPlaylistsSearch(); }); -document.getElementById('sort').addEventListener('change', function (e) { - refreshPlaylistsSearch(); -}); +} \ No newline at end of file diff --git a/pod/playlist/templates/playlist/playlists.html b/pod/playlist/templates/playlist/playlists.html index 6ccaf14821..a336d6102e 100644 --- a/pod/playlist/templates/playlist/playlists.html +++ b/pod/playlist/templates/playlist/playlists.html @@ -35,7 +35,7 @@

{% trans "No playlists found"%}

-
+
{% for playlist in playlists %}
{% include "playlist/playlist_card.html" %} From 414c0f2cbcfe17839f835010dc56d1a96d41f3ce Mon Sep 17 00:00:00 2001 From: Aymeric Jakobowski Date: Tue, 19 Sep 2023 12:33:44 +0200 Subject: [PATCH 03/19] Fix playlist migration --- pod/playlist/apps.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/pod/playlist/apps.py b/pod/playlist/apps.py index e4d27f9728..8e2576f3c8 100644 --- a/pod/playlist/apps.py +++ b/pod/playlist/apps.py @@ -115,19 +115,21 @@ def create_new_favorites(self): from pod.playlist.models import Playlist, PlaylistContent from django.utils.translation import gettext_lazy as _ from django.contrib.auth.models import User + from pod.playlist.utils import get_favorite_playlist_for_user # Add Favorites playlist for users without favorites existing_users = User.objects.all() users_without_favorites = existing_users.exclude(id__in=FAVORITES_DATA.keys()) for user in users_without_favorites: - Playlist.objects.create( - name=FAVORITE_PLAYLIST_NAME, - description=_("Your favorites videos."), - visibility="private", - autoplay=True, - owner=user, - editable=False, - ) + if not get_favorite_playlist_for_user(user): + Playlist.objects.create( + name=FAVORITE_PLAYLIST_NAME, + description=_("Your favorites videos."), + visibility="private", + autoplay=True, + owner=user, + editable=False, + ) # Converting previous favorites to new system for owner_id, data_lists in FAVORITES_DATA.items(): From 0193738dcea88d49254cefbe0fb1bdbbc3906ca9 Mon Sep 17 00:00:00 2001 From: Aymeric Jakobowski Date: Tue, 19 Sep 2023 12:38:10 +0200 Subject: [PATCH 04/19] Add password encryption for protected videos --- pod/video/apps.py | 9 +++++++++ pod/video/models.py | 3 +++ pod/video/views.py | 7 ++++--- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/pod/video/apps.py b/pod/video/apps.py index 5c7d8814de..8b59f634f7 100644 --- a/pod/video/apps.py +++ b/pod/video/apps.py @@ -57,6 +57,14 @@ def fix_transcript(sender, **kwargs): Video.objects.filter(transcript="1").update(transcript=F("main_lang")) Video.objects.filter(transcript="0").update(transcript="") +def update_video_passwords(sender, **kwargs): + """Encrypt all video passwords.""" + from pod.video.models import Video + from django.contrib.auth.hashers import make_password + for video in Video.objects.all(): + if video.password and not video.password.startswith(('pbkdf2', 'sha256$')): + video.password = make_password(video.password, hasher="pbkdf2_sha256") + video.save() class VideoConfig(AppConfig): name = "pod.video" @@ -68,6 +76,7 @@ def ready(self): post_migrate.connect(set_default_site, sender=self) post_migrate.connect(self.send_previous_data, sender=self) post_migrate.connect(fix_transcript, sender=self) + post_migrate.connect(update_video_passwords, sender=self) def execute_query(self, query, mapping_dict): """ diff --git a/pod/video/models.py b/pod/video/models.py index ebfbf973c3..2843132875 100644 --- a/pod/video/models.py +++ b/pod/video/models.py @@ -34,6 +34,7 @@ from django.db.models.signals import pre_save from pod.main.models import AdditionalChannelTab import importlib +from django.contrib.auth.hashers import make_password from sorl.thumbnail import get_thumbnail from pod.authentication.models import AccessGroup @@ -887,6 +888,8 @@ def save(self, *args, **kwargs): newid = "%04d" % newid self.slug = "%s-%s" % (newid, slugify(self.title)) self.tags = remove_accents(self.tags) + if self.password and not self.password.startswith(('pbkdf2', 'sha256$')): + self.password = make_password(self.password, hasher="pbkdf2_sha256") super(Video, self).save(*args, **kwargs) def __str__(self): diff --git a/pod/video/views.py b/pod/video/views.py index 945ad94413..b44c186351 100644 --- a/pod/video/views.py +++ b/pod/video/views.py @@ -24,6 +24,7 @@ from django.urls import reverse from django.utils import timezone from django.db.models import Sum, Min +from django.contrib.auth.hashers import check_password from dateutil.parser import parse import concurrent.futures as futures @@ -906,7 +907,7 @@ def toggle_render_video_user_can_see_video( show_page and is_password_protected and request.POST.get("password") - and request.POST.get("password") == video.password + and check_password(request.POST.get("password"), video.password) ) or (slug_private and slug_private == video.get_hashkey()) or request.user == video.owner @@ -1010,7 +1011,7 @@ def render_video( ) if ( request.POST.get("password") - and request.POST.get("password") != video.password + and check_password(request.POST.get("password"), video.password) ): messages.add_message( request, messages.ERROR, _("The password is incorrect.") @@ -2221,7 +2222,7 @@ def stats_view(request, slug=None, slug_t=None): and target == "video" and ( request.POST.get("password") - and request.POST.get("password") == videos[0].password + and check_password(request.POST.get("password"), video[0].password) ) ) or ( request.method == "GET" and videos and target in ("videos", "channel", "theme") From 226b6d2944b3098397b9a9ef15826fb26369e6ac Mon Sep 17 00:00:00 2001 From: Aymeric Jakobowski Date: Tue, 19 Sep 2023 14:06:09 +0200 Subject: [PATCH 05/19] Fix flake8 --- pod/video/apps.py | 16 +++++++++------- pod/video/models.py | 8 ++++++-- pod/video/views.py | 2 +- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/pod/video/apps.py b/pod/video/apps.py index 8b59f634f7..3f99e60ce8 100644 --- a/pod/video/apps.py +++ b/pod/video/apps.py @@ -57,14 +57,16 @@ def fix_transcript(sender, **kwargs): Video.objects.filter(transcript="1").update(transcript=F("main_lang")) Video.objects.filter(transcript="0").update(transcript="") + def update_video_passwords(sender, **kwargs): - """Encrypt all video passwords.""" - from pod.video.models import Video - from django.contrib.auth.hashers import make_password - for video in Video.objects.all(): - if video.password and not video.password.startswith(('pbkdf2', 'sha256$')): - video.password = make_password(video.password, hasher="pbkdf2_sha256") - video.save() + """Encrypt all video passwords.""" + from pod.video.models import Video + from django.contrib.auth.hashers import make_password + for video in Video.objects.all(): + if video.password and not video.password.startswith(('pbkdf2', 'sha256$')): + video.password = make_password(video.password, hasher="pbkdf2_sha256") + video.save() + class VideoConfig(AppConfig): name = "pod.video" diff --git a/pod/video/models.py b/pod/video/models.py index 2843132875..1219b115ac 100644 --- a/pod/video/models.py +++ b/pod/video/models.py @@ -859,6 +859,11 @@ class Meta: verbose_name = _("video") verbose_name_plural = _("videos") + def set_password(self): + """Encrypt the password if video is protected. An encrypted password cannot be re-encrypted.""" + if self.password and not self.password.startswith(('pbkdf2', 'sha256$')): + self.password = make_password(self.password, hasher="pbkdf2_sha256") + def save(self, *args, **kwargs): """Store a video object in db.""" newid = -1 @@ -888,8 +893,7 @@ def save(self, *args, **kwargs): newid = "%04d" % newid self.slug = "%s-%s" % (newid, slugify(self.title)) self.tags = remove_accents(self.tags) - if self.password and not self.password.startswith(('pbkdf2', 'sha256$')): - self.password = make_password(self.password, hasher="pbkdf2_sha256") + self.set_password() super(Video, self).save(*args, **kwargs) def __str__(self): diff --git a/pod/video/views.py b/pod/video/views.py index b44c186351..f466afdb55 100644 --- a/pod/video/views.py +++ b/pod/video/views.py @@ -24,7 +24,7 @@ from django.urls import reverse from django.utils import timezone from django.db.models import Sum, Min -from django.contrib.auth.hashers import check_password +from django.contrib.auth.hashers import check_password from dateutil.parser import parse import concurrent.futures as futures From 08709246e211ea30f44493749bbbba54d873e0ab Mon Sep 17 00:00:00 2001 From: Aymeric Jakobowski Date: Tue, 19 Sep 2023 14:51:25 +0200 Subject: [PATCH 06/19] Improve password input --- pod/locale/fr/LC_MESSAGES/django.mo | Bin 165637 -> 165752 bytes pod/locale/fr/LC_MESSAGES/django.po | 51 ++++----- pod/locale/fr/LC_MESSAGES/djangojs.mo | Bin 17821 -> 17417 bytes pod/locale/fr/LC_MESSAGES/djangojs.po | 117 +++++++++------------ pod/locale/nl/LC_MESSAGES/django.po | 14 ++- pod/locale/nl/LC_MESSAGES/djangojs.po | 84 ++++----------- pod/video/models.py | 2 +- pod/video/templates/videos/video_edit.html | 7 ++ 8 files changed, 110 insertions(+), 165 deletions(-) diff --git a/pod/locale/fr/LC_MESSAGES/django.mo b/pod/locale/fr/LC_MESSAGES/django.mo index c906197f3e80d05f05da65895432fa3e22b2ca99..84b047f266c1663e1c78894ca982b4a0ebd27ff1 100644 GIT binary patch delta 32929 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\n" +"Last-Translator: AymericJak \n" "Language-Team: Pod Team pod@esup-portail.org\n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -2117,8 +2117,8 @@ msgid "" msgstr "" "Les champs \"Début\" et \"Fin\" doivent contenir des valeurs en secondes. " "Lancez la lecture de la vidéo, mettez sur pause et cliquez sur \"Récupérer " -"le temps depuis le lecteur\" pour renseigner automatiquement le champ " -"\"Début\". Vous pouvez le faire également pour remplir le champ \"Fin\"." +"le temps depuis le lecteur\" pour renseigner automatiquement le champ \"Début" +"\". Vous pouvez le faire également pour remplir le champ \"Fin\"." #: pod/enrichment/templates/enrichment/edit_enrichment.html msgid "You cannot overlap enrichments." @@ -2622,8 +2622,8 @@ msgid "" "This video was uploaded to Pod; its origin is %(type)s : %(url)s" msgstr "" -"Cette vidéo a été téléversée sur Pod ; son origine est %(type)s : %(url)s" +"Cette vidéo a été téléversée sur Pod ; son origine est %(type)s : %(url)s" #: pod/import_video/views.py pod/meeting/views.py msgid "Try changing the record type or address for this recording." @@ -2634,8 +2634,8 @@ msgstr "" #: pod/import_video/views.py #, python-format msgid "" -"This video '%(name)s' was uploaded to Pod; its origin is Youtube : %(url)s" +"This video '%(name)s' was uploaded to Pod; its origin is Youtube : %(url)s" msgstr "" "Cette vidéo « %(name)s » a été téléversée sur Pod ; son origine est " "Youtube : %(url)s" @@ -5468,16 +5468,16 @@ msgid "" msgstr "" "\n" "

Bonjour,\n" -"

%(owner)s vous invite à une réunion récurrente " -"%(meeting_title)s.

\n" +"

%(owner)s vous invite à une réunion récurrente " +"%(meeting_title)s.

\n" "

Date de début : %(start_date_time)s

\n" "

Récurrent jusqu’à la date : %(end_date)s

\n" "

La réunion se tiendra tou(te)s les %(frequency)s %(recurrence)s \n" "

Voici le lien pour rejoindre la réunion :\n" " %(join_link)s

\n" -"

Vous avez besoin de ce mot de passe pour entrer : " -"%(password)s

\n" +"

Vous avez besoin de ce mot de passe pour entrer : " +"%(password)s

\n" "

Cordialement

\n" " " @@ -5503,8 +5503,8 @@ msgstr "" "

Date de fin : %(end_date)s

\n" "

Voici le lien pour rejoindre la réunion :\n" " %(join_link)s

\n" -"

Vous avez besoin de ce mot de passe pour entrer : " -"%(password)s

\n" +"

Vous avez besoin de ce mot de passe pour entrer : " +"%(password)s

\n" "

Cordialement

\n" " " @@ -6480,8 +6480,8 @@ msgstr "Prévisualisation d’enregistrement" #: pod/video/templates/videos/video-element.html msgid "" "To view this video please enable JavaScript, and consider upgrading to a web " -"browser that supports HTML5 video" +"browser that supports HTML5 video" msgstr "" "Pour visionner cette vidéo, veuillez activer JavaScript et envisager de " "passer à un navigateur Web qui un nouvel enregistrement a été ajouté sur la plateforme " "%(title_site)s à partir de l’enregistreur \"%(recorder)s\".
Pour " -"l’ajouter, cliquez sur le lien ci dessous.

%(link_url)s
Si le lien n’est pas actif, il " -"faut le copier-coller dans la barre d’adresse de votre navigateur.

Cordialement

" +"l’ajouter, cliquez sur le lien ci dessous.

" +"%(link_url)s
Si le lien n’est pas actif, il faut le copier-coller " +"dans la barre d’adresse de votre navigateur.

Cordialement

" #: pod/recorder/views.py msgid "New recording added." @@ -6911,8 +6910,8 @@ msgid "" "%(url)s

\n" msgstr "" "vous pouvez changer la date de suppression en éditant votre vidéo :

\n" -"

%(scheme)s:%(url)s

\n" +"

" +"%(scheme)s:%(url)s

\n" "\n" #: pod/video/management/commands/check_obsolete_videos.py @@ -7136,6 +7135,10 @@ msgstr "" msgid "Date of event" msgstr "Date de l’évènement" +#: pod/video/models.py +msgid "The password is / will be encrypted." +msgstr "Le mot de passe est / sera encrypté." + #: pod/video/models.py msgid "Overview" msgstr "Vue d’ensemble" @@ -7665,8 +7668,8 @@ msgid "" "This video is chaptered. Click the chapter button on the video player to view them." msgstr "" -"Cette vidéo est chapitrée. Cliquez sur le bouton de chapitre sur le lecteur vidéo pour les voir." +"Cette vidéo est chapitrée. Cliquez sur le bouton de chapitre sur le lecteur vidéo pour les voir." #: pod/video/templates/videos/video-all-info.html msgid "Other versions" diff --git a/pod/locale/fr/LC_MESSAGES/djangojs.mo b/pod/locale/fr/LC_MESSAGES/djangojs.mo index 5c3ce79261df81c8eb6f305597a4ce98e900c841..8f51f7cf4c1e7be30b2ce90ca9872d631f583fe6 100644 GIT binary patch delta 4162 zcmYk;dr*{B7{~DkRxaL65|L6?k*lIYMIxYJVVI(nS(!#aQ4*-Bff>WG>T1>wS7RkUiSc+2Ycal?SuW0V?!kPHf5twTd4ZV^ zMN6Q`a3VsDN+Ul@MC0Mr9=upbUX4ftl%b@QDYurJ52 zq6T&hmBf?S3C|$6wsV+(aXq*%&$oeeG~-J#7DpkgVB?WV*hD1THWhW_dr+wixbu&p z2DlN^a0}{whfx#z29=p#QA?3T-j#`DdHjd&NTHr_Sfj+ zb5SXujQZVNfT`rSAfKXS*B6bxgwBveLoF&jrGl7Ef7i4z+6deq1dpdR=w z>VfSqGE2cU)NvW=L3QZI#i(N4ikjgUn1qpBq}2CAmfgxxnX5rPZ+U=@X0R6-tbOSG z0r_W9JWXrc54HB0s3plpJ+K6|JsYtzHlgmf1XW8o1oGSqgNi`sshQA>3gRis~{YUpcJQT>FPSpw7701Hq{I?WwF>pX&f?f)1) zhjKwW&cZ5e!cUOwTRFoo#X2m(mr%v}Co&03X1#P>F)D*oPy=X0rF;!)fICnF-jAtx zz%yX>9UY~tE5B08(vf>xHfsA!a8{#IKNFRqg{TLt#gVuZm7(8|$ysmmeHj*F4$j6r z+>EM`)iQGsOz_*W_ZZ?vHSiQs%E}NE%7fn zBEsw+Y{zjSqX<;e8A*p_vuE%TJcvbDPM!;}6(`{bsF|fR%@{02ZL4xrX6``UrwQ|M z4VK{%Wb0dh3Zw`Na0E7Ivi`&Ayvhls{BP6}^r7CfRVzQC2Hr6%obk9U^3OdigA*k<5jDfLNLko^WI639>W7hRUcEp% zpk6?|Q8OQmjNPt4T{qpGZ$wRGDQYQ}qgOMi-|q~#3l5@g^d5G>YC)jSMVcC+PV3BKp$s z57JQ8J{(mvHK+$SV-c=L>dB5`8piT;T|Wdz;0?$vZ6#`^?;_8(zmQe5K@^UDKLzu7 zzAd7oH9m-a@g#aT=CxJG@eou|O-Ht@wV`hK5o)GU~qx8Mv;H-|Nky@5;zf$d}o8PBTmJ5yc;#J7F02{AzRq?pa%36szxGN#|tnE^}7+M z`&^HHtVU&M0T$zH7|=eA;-fPbqpEZ~dOt+!&Z=YJZ|B>u@tU*0stMdr@Irj0TinBjz>Be9OoQTR$Wq^)e7(wiWYf&TL;*MWOjr2p* z5`B%j{xoW!XE6dJ2_07uYS$2p2)*ak<`T-Vmf>MSjbvJ2G9Pyl8kKJRf15^UJF$aM zinR<+6U&KbiJOVt#Ph@hgr88`N>mf~>42t6*93|PlI;~Hc<&gNG++}s(9G^2t|ipc z!`SV(jF?HhK(OPyt-1@R6KYDUT4ES)nfkcCiuG~g9(SzWrMgm6wi~=5(Yc$5CRPz@ zeTgN6s(Uk`rgfi3>>;%6)b0#p~B9Z2f#aiM<;$b}~L7d;T&D6??T(1{?IW^J0n$YuYr#@(l ziIrZDO2zrE-yN?cdJ}a7yVd(Up%T@!_0DfExdZK-rwAXxyT)s^d_G3pMl|dBHFU~| zE`(ZM81L148T}CPB#}f6BE}JFlZd^mFVd8!XFFI>w8`QRU?Dr(x-*q?p7KRO6`8q7wi!~A#`7STSO=)p<8rtQlF25 z*-3{&5&pB$!GBYm(~IX$tC>}M>(y0t{(`D-f6$#(bu+4G%$Z$RThuVUwlS-|w!S{p ulJ-?(Xi;WTRB-#?%24W%yCOpyb56ztw+=fO+L@mo5js&YKQ>rblJg(ClC3cS delta 4488 zcmYk;4OEr&0mt$GMczeG5D*HwkO&gukOW^)uOfzNC75ps2*OQiz@-b=Sj0^%(U?Wv zaL(3rWg5AecCA^;oRW2NTeHn}JZsv9+uYV!JFCuCXX~7OfA@Ld^c;To^M9UupXdMn z9Cqz=JlE^+U5g9tHyr25%_KM6mvzv)F*Y#X@vVw0sEX zaefTb@b5SVqvDL2gyWD~OopY;6j0Cum*B0q0cWERx!0V+Z{S7D#sA_o%#JrE1uKv? znRSd?=C2ggatFf@iBYJY$JysoFpTr*Nasxf z#^O>`1#3_btU?X#gZB5`sORp%EZmQJ?s-&4FQZRAzfM7OG%?8Tnrhfp2-0B^ysd=xYV zsocdnGs{s!R)ebWDO3*vNN3G2Z2yAX8r)-=<5c#V)hT~3dx+{;D9zQ4IjB`U!?xJIz6`ZC?#A1&9<^QjP}_A7HH9}& z4f_NjMW8q#!IN7if6nT6f+-ZVHN64=EphsHfj;66~Q+l>VXxg zhHSwo+-BR0{F#0}v{ug8*WW^)Zg`J^dUylF@H6}TOVoqHs4X00QFEV&Sq?@CLpfj0 zc-G)bWVx6VxEn8_3#(~mF&@D6_A+w-OHEJ7nqK3+kdf*Y9hi~Iu z7{UtU9b;Ca3%B4x9KZ$mH`EklvjQXWPE_rWExor>X zfrB^>|A(5>X!fWYoQ&!~5o!t+B6XY9Sc=JWfYF&sR)A z6_uiT(1Lov4qSx$a18zqwaue*&=;uA=n<|t~heux_31Xi#{WF@NM zdy)Hn<{$+p7p|kWUuc0fWNFCT)hxhGcpqwN1~CplL;XJdc5BTzaUJJHsQurE%$AAa zCN*#_IO9z)t-K0)<3qsZE( z6{w0IN8KMlE#9lBxld*o({Vm#QNP(pVLtYt7TX2nRbWCHKL*82L-n*0_5D_yjIW`3 z_8w|6{tMNCSjL<6Y-XV5xDvI7+^GASP*bo2gZsaa0(F`J9E-!4h@YTZ8b!ChyC~}zJX=5LL(L8^6~Pakl~^? z*nuo?^FC@HhtSMq%)^_p4AlTP#$z9ow6C?>YD9FfzRXKx57ENZvC(4m zGmTOe(Rxav{@`1!6~9k(Bv_aYw)MD+93dXEnH(e4q?SBO?jbs~cu$cRi1zx+M8{!L zL&lJw5FK9P(_-01%E$oGQAt*lC=yQ&l2W2$t3~j?W6l2^l1}t8d7X?Lheit6Pol{h zQcfNugXC^nzM;c+M_Q!R6$8q=TfA9}ykjv>5$N87*0bUfBJ$ zYZ;Uy$^FDvVSh0f=aU1(ZC@+EnIwYzz`phe)H&-sO-=6Rw!n&sACC!ZZgw}e`U?`) zM%LA~xi@>f9f7WdHyjaOug5$5=;6Suq`2^ymc|ZK;pWrX=J6M&UJGfi_a~)Yj9k@T zSLbeRO%MDb?Tc{#uQRt#@NBBB_c)97>1uCos0%zY^=e4`NR_n>Ubo$fz&+D)!or4* zHM?8=?RoXl)IKyo^$qU8&-1!MqDsA9cYCk}W%)NE5-WxVT0G75Ubh)7IcwVk8FOMB j;mun;9d2(RcW#a&S}huSsrCH9^uX$Q-I4xFC3F4{adhjF diff --git a/pod/locale/fr/LC_MESSAGES/djangojs.po b/pod/locale/fr/LC_MESSAGES/djangojs.po index e9d5b57df1..af955b8f7e 100644 --- a/pod/locale/fr/LC_MESSAGES/djangojs.po +++ b/pod/locale/fr/LC_MESSAGES/djangojs.po @@ -5,9 +5,9 @@ msgid "" msgstr "" "Project-Id-Version: Esup-Pod\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-09-01 13:56+0000\n" +"POT-Creation-Date: 2023-09-19 12:42+0000\n" "PO-Revision-Date: \n" -"Last-Translator: obado \n" +"Last-Translator: AymericJak \n" "Language-Team: \n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -170,16 +170,6 @@ msgstr "Veuillez entrer un texte pour le segment compris entre %s et %s :" msgid "Pause to enter caption for segment from %s to %s." msgstr "Mettez en pause pour entrer le texte du segment entre %s et %s." -#: pod/completion/static/js/caption_maker.js -#: pod/podfile/static/podfile/js/filewidget.js -msgid "Add" -msgstr "Ajouter" - -#: pod/completion/static/js/caption_maker.js -#: pod/video/static/js/comment-script.js -msgid "Delete" -msgstr "Supprimer" - #: pod/completion/static/js/caption_maker.js msgid "Caption" msgstr "Légende / Sous-titre" @@ -512,11 +502,6 @@ msgstr "Sauvegarder" msgid "Network response was not ok." msgstr "La réponse du réseau n'était pas correcte." -#: pod/podfile/static/podfile/js/filewidget.js -#: pod/video/static/js/change_video_owner.js -msgid "Loading…" -msgstr "Chargement en cours…" - #: pod/podfile/static/podfile/js/filewidget.js msgid "Change image" msgstr "Changer d’image" @@ -545,6 +530,10 @@ msgstr "Retirer" msgid "Server error" msgstr "Erreur du serveur" +#: pod/podfile/static/podfile/js/filewidget.js +msgid "Add" +msgstr "Ajouter" + #: pod/podfile/static/podfile/js/filewidget.js msgid "Are you sure you want to delete this folder?" msgstr "Êtes-vous sûr(e) de vouloir supprimer ce dossier ?" @@ -557,10 +546,6 @@ msgstr "Voir plus" msgid "This folder is empty" msgstr "Ce dossier est vide" -#: pod/video/static/js/ajax-display-channels.js -msgid "Channels" -msgstr "Chaînes" - #: pod/video/static/js/ajax-display-channels.js msgid "Channel" msgstr "Chaîne" @@ -573,14 +558,14 @@ msgstr "Aucun chaîne trouvée" msgid "videos" msgstr "vidéos" -#: pod/video/static/js/ajax-display-channels.js -msgid "video" -msgstr "vidéo" - #: pod/video/static/js/change_video_owner.js msgid "No element found" msgstr "Aucun élément trouvé" +#: pod/video/static/js/change_video_owner.js +msgid "Loading…" +msgstr "Chargement en cours…" + #: pod/video/static/js/change_video_owner.js msgid "An error occurred during the change of owner" msgstr "Une erreur s’est produite lors du changement de propriétaire" @@ -598,40 +583,21 @@ msgid "Answers" msgstr "Réponses" #: pod/video/static/js/comment-script.js -msgid "Cancel" -msgstr "Annuler" +msgid "Delete" +msgstr "Supprimer" #: pod/video/static/js/comment-script.js -#, javascript-format -msgid "%s vote" -msgid_plural "%s votes" -msgstr[0] "%s vote" -msgstr[1] "%s votes" +msgid "Cancel" +msgstr "Annuler" #: pod/video/static/js/comment-script.js msgid "Agree with the comment" msgstr "D’accord avec ce commentaire" -#: pod/video/static/js/comment-script.js -msgid "Reply to comment" -msgstr "Répondre au commentaire" - -#: pod/video/static/js/comment-script.js -msgid "Reply" -msgstr "Répondre" - #: pod/video/static/js/comment-script.js msgid "Remove this comment" msgstr "Supprimer ce commentaire" -#: pod/video/static/js/comment-script.js -msgid "Add a public comment" -msgstr "Ajouter un commentaire public" - -#: pod/video/static/js/comment-script.js -msgid "Send" -msgstr "Envoyer" - #: pod/video/static/js/comment-script.js msgid "Show answers" msgstr "Afficher les réponses" @@ -644,6 +610,13 @@ msgstr "Mauvaise réponse du serveur." msgid "Sorry, you're not allowed to vote by now." msgstr "Désolé, vous n’êtes pas autorisé à voter maintenant." +#: pod/video/static/js/comment-script.js +#, javascript-format +msgid "%s vote" +msgid_plural "%s votes" +msgstr[0] "%s vote" +msgstr[1] "%s votes" + #: pod/video/static/js/comment-script.js msgid "Sorry, you can't comment this video by now." msgstr "Désolé, vous ne pouvez pas commenter cette vidéo maintenant." @@ -664,47 +637,38 @@ msgstr[0] "%s commentaire" msgstr[1] "%s commentaires" #: pod/video/static/js/regroup_videos_by_theme.js -#: pod/video/static/js/video_category.js msgid "This content is password protected." msgstr "Ce contenu est protégé par mot de passe." #: pod/video/static/js/regroup_videos_by_theme.js -#: pod/video/static/js/video_category.js msgid "This content is chaptered." msgstr "Ce contenu est chapitré." #: pod/video/static/js/regroup_videos_by_theme.js -#: pod/video/static/js/video_category.js msgid "This content is in draft." msgstr "Ce contenu est en brouillon." #: pod/video/static/js/regroup_videos_by_theme.js -#: pod/video/static/js/video_category.js msgid "Video content." msgstr "Contenu vidéo." #: pod/video/static/js/regroup_videos_by_theme.js -#: pod/video/static/js/video_category.js msgid "Audio content." msgstr "Contenu audio." #: pod/video/static/js/regroup_videos_by_theme.js -#: pod/video/static/js/video_category.js msgid "Edit the video" msgstr "Éditer la vidéo" #: pod/video/static/js/regroup_videos_by_theme.js -#: pod/video/static/js/video_category.js msgid "Complete the video" msgstr "Compléter la vidéo" #: pod/video/static/js/regroup_videos_by_theme.js -#: pod/video/static/js/video_category.js msgid "Chapter the video" msgstr "Chapitrer la vidéo" #: pod/video/static/js/regroup_videos_by_theme.js -#: pod/video/static/js/video_category.js msgid "Delete the video" msgstr "Supprimer la vidéo" @@ -777,18 +741,6 @@ msgstr "Désolé, aucune vidéo trouvée" msgid "Edit the category" msgstr "Éditer la catégorie" -#: pod/video/static/js/video_category.js -msgid "Delete the category" -msgstr "Supprimer la catégorie" - -#: pod/video/static/js/video_category.js -msgid "Success!" -msgstr "Succès !" - -#: pod/video/static/js/video_category.js -msgid "Error…" -msgstr "Erreur…" - #: pod/video/static/js/video_category.js msgid "Category created successfully" msgstr "Catégorie créée avec succès" @@ -861,6 +813,33 @@ msgstr "Ajouts en favoris total depuis la création" msgid "Slug" msgstr "Titre court" +#~ msgid "Channels" +#~ msgstr "Chaînes" + +#~ msgid "video" +#~ msgstr "vidéo" + +#~ msgid "Reply to comment" +#~ msgstr "Répondre au commentaire" + +#~ msgid "Reply" +#~ msgstr "Répondre" + +#~ msgid "Add a public comment" +#~ msgstr "Ajouter un commentaire public" + +#~ msgid "Send" +#~ msgstr "Envoyer" + +#~ msgid "Delete the category" +#~ msgstr "Supprimer la catégorie" + +#~ msgid "Success!" +#~ msgstr "Succès !" + +#~ msgid "Error…" +#~ msgstr "Erreur…" + #~ msgid "Are you sure you want to delete this element?" #~ msgstr "Êtes-vous sûr(e) de vouloir supprimer cet élément ?" diff --git a/pod/locale/nl/LC_MESSAGES/django.po b/pod/locale/nl/LC_MESSAGES/django.po index 34f574ef6e..35b09e041c 100644 --- a/pod/locale/nl/LC_MESSAGES/django.po +++ b/pod/locale/nl/LC_MESSAGES/django.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: Pod\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-09-12 15:15+0000\n" +"POT-Creation-Date: 2023-09-19 12:42+0000\n" "PO-Revision-Date: 2023-06-08 14:37+0200\n" "Last-Translator: obado \n" "Language-Team: \n" @@ -2470,8 +2470,8 @@ msgstr "" #: pod/import_video/views.py #, python-format msgid "" -"This video '%(name)s' was uploaded to Pod; its origin is Youtube : %(url)s" +"This video '%(name)s' was uploaded to Pod; its origin is Youtube : %(url)s" msgstr "" #: pod/import_video/views.py @@ -6124,8 +6124,8 @@ msgstr "" #: pod/video/templates/videos/video-element.html msgid "" "To view this video please enable JavaScript, and consider upgrading to a web " -"browser that supports HTML5 video" +"browser that supports HTML5 video" msgstr "" #: pod/recorder/templates/recorder/link_record.html @@ -6688,6 +6688,10 @@ msgstr "" msgid "Date of event" msgstr "" +#: pod/video/models.py +msgid "The password is / will be encrypted." +msgstr "" + #: pod/video/models.py msgid "Overview" msgstr "" diff --git a/pod/locale/nl/LC_MESSAGES/djangojs.po b/pod/locale/nl/LC_MESSAGES/djangojs.po index 545901be19..41fdb55af7 100644 --- a/pod/locale/nl/LC_MESSAGES/djangojs.po +++ b/pod/locale/nl/LC_MESSAGES/djangojs.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: Esup-Pod\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-09-01 13:56+0000\n" +"POT-Creation-Date: 2023-09-19 12:42+0000\n" "PO-Revision-Date: 2023-02-08 15:22+0100\n" "Last-Translator: obado \n" "Language-Team: \n" @@ -155,16 +155,6 @@ msgstr "" msgid "Pause to enter caption for segment from %s to %s." msgstr "" -#: pod/completion/static/js/caption_maker.js -#: pod/podfile/static/podfile/js/filewidget.js -msgid "Add" -msgstr "" - -#: pod/completion/static/js/caption_maker.js -#: pod/video/static/js/comment-script.js -msgid "Delete" -msgstr "" - #: pod/completion/static/js/caption_maker.js msgid "Caption" msgstr "" @@ -487,11 +477,6 @@ msgstr "" msgid "Network response was not ok." msgstr "" -#: pod/podfile/static/podfile/js/filewidget.js -#: pod/video/static/js/change_video_owner.js -msgid "Loading…" -msgstr "" - #: pod/podfile/static/podfile/js/filewidget.js msgid "Change image" msgstr "" @@ -520,6 +505,10 @@ msgstr "" msgid "Server error" msgstr "" +#: pod/podfile/static/podfile/js/filewidget.js +msgid "Add" +msgstr "" + #: pod/podfile/static/podfile/js/filewidget.js msgid "Are you sure you want to delete this folder?" msgstr "" @@ -532,10 +521,6 @@ msgstr "" msgid "This folder is empty" msgstr "" -#: pod/video/static/js/ajax-display-channels.js -msgid "Channels" -msgstr "" - #: pod/video/static/js/ajax-display-channels.js msgid "Channel" msgstr "" @@ -548,12 +533,12 @@ msgstr "" msgid "videos" msgstr "" -#: pod/video/static/js/ajax-display-channels.js -msgid "video" +#: pod/video/static/js/change_video_owner.js +msgid "No element found" msgstr "" #: pod/video/static/js/change_video_owner.js -msgid "No element found" +msgid "Loading…" msgstr "" #: pod/video/static/js/change_video_owner.js @@ -573,40 +558,21 @@ msgid "Answers" msgstr "" #: pod/video/static/js/comment-script.js -msgid "Cancel" -msgstr "" - -#: pod/video/static/js/comment-script.js -#, javascript-format -msgid "%s vote" -msgid_plural "%s votes" -msgstr[0] "" -msgstr[1] "" - -#: pod/video/static/js/comment-script.js -msgid "Agree with the comment" +msgid "Delete" msgstr "" #: pod/video/static/js/comment-script.js -msgid "Reply to comment" +msgid "Cancel" msgstr "" #: pod/video/static/js/comment-script.js -msgid "Reply" +msgid "Agree with the comment" msgstr "" #: pod/video/static/js/comment-script.js msgid "Remove this comment" msgstr "" -#: pod/video/static/js/comment-script.js -msgid "Add a public comment" -msgstr "" - -#: pod/video/static/js/comment-script.js -msgid "Send" -msgstr "" - #: pod/video/static/js/comment-script.js msgid "Show answers" msgstr "" @@ -619,6 +585,13 @@ msgstr "" msgid "Sorry, you're not allowed to vote by now." msgstr "" +#: pod/video/static/js/comment-script.js +#, javascript-format +msgid "%s vote" +msgid_plural "%s votes" +msgstr[0] "" +msgstr[1] "" + #: pod/video/static/js/comment-script.js msgid "Sorry, you can't comment this video by now." msgstr "" @@ -639,47 +612,38 @@ msgstr[0] "" msgstr[1] "" #: pod/video/static/js/regroup_videos_by_theme.js -#: pod/video/static/js/video_category.js msgid "This content is password protected." msgstr "" #: pod/video/static/js/regroup_videos_by_theme.js -#: pod/video/static/js/video_category.js msgid "This content is chaptered." msgstr "" #: pod/video/static/js/regroup_videos_by_theme.js -#: pod/video/static/js/video_category.js msgid "This content is in draft." msgstr "" #: pod/video/static/js/regroup_videos_by_theme.js -#: pod/video/static/js/video_category.js msgid "Video content." msgstr "" #: pod/video/static/js/regroup_videos_by_theme.js -#: pod/video/static/js/video_category.js msgid "Audio content." msgstr "" #: pod/video/static/js/regroup_videos_by_theme.js -#: pod/video/static/js/video_category.js msgid "Edit the video" msgstr "" #: pod/video/static/js/regroup_videos_by_theme.js -#: pod/video/static/js/video_category.js msgid "Complete the video" msgstr "" #: pod/video/static/js/regroup_videos_by_theme.js -#: pod/video/static/js/video_category.js msgid "Chapter the video" msgstr "" #: pod/video/static/js/regroup_videos_by_theme.js -#: pod/video/static/js/video_category.js msgid "Delete the video" msgstr "" @@ -751,18 +715,6 @@ msgstr "" msgid "Edit the category" msgstr "" -#: pod/video/static/js/video_category.js -msgid "Delete the category" -msgstr "" - -#: pod/video/static/js/video_category.js -msgid "Success!" -msgstr "" - -#: pod/video/static/js/video_category.js -msgid "Error…" -msgstr "" - #: pod/video/static/js/video_category.js msgid "Category created successfully" msgstr "" diff --git a/pod/video/models.py b/pod/video/models.py index 1219b115ac..35b651d9fd 100644 --- a/pod/video/models.py +++ b/pod/video/models.py @@ -816,7 +816,7 @@ class Video(models.Model): ) password = models.CharField( _("password"), - help_text=_("Viewing this video will not be possible without this password."), + help_text=_("Viewing this video will not be possible without this password.") + " " + _("The password is / will be encrypted.") , max_length=50, blank=True, null=True, diff --git a/pod/video/templates/videos/video_edit.html b/pod/video/templates/videos/video_edit.html index e5e3aded6f..4feb648572 100644 --- a/pod/video/templates/videos/video_edit.html +++ b/pod/video/templates/videos/video_edit.html @@ -294,4 +294,11 @@

{% trans "Help for fo + + {% endblock more_script %} From c77995f447a424e91d7fa874d4adff4d5153f188 Mon Sep 17 00:00:00 2001 From: Aymeric Jakobowski Date: Tue, 19 Sep 2023 15:47:25 +0200 Subject: [PATCH 07/19] Fix unittest --- pod/video/tests/test_stats_view.py | 3 ++- pod/video/views.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pod/video/tests/test_stats_view.py b/pod/video/tests/test_stats_view.py index eb52ddc231..7b9744fa35 100644 --- a/pod/video/tests/test_stats_view.py +++ b/pod/video/tests/test_stats_view.py @@ -9,6 +9,7 @@ from pod.video.views import get_all_views_count, stats_view from django.contrib.sites.models import Site from pod.authentication.models import AccessGroup +from django.contrib.auth.hashers import make_password from pod.video_encode_transcript.models import EncodingVideo from pod.video_encode_transcript.models import VideoRendition @@ -314,7 +315,7 @@ def test_stats_view_GET_request_video_access_rights(self): """Test video restrictions (by password, by group, or private video).""" # *********** Test restricted by password ************ # password = "ThisVideoRequireAPassword" - self.video3.password = password + self.video3.password = make_password(password, hasher="pbkdf2_sha256") self.video3.save() url = reverse("video:video_stats_view", kwargs={"slug": self.video3.slug}) response = self.client.get(url, {"from": "video"}) diff --git a/pod/video/views.py b/pod/video/views.py index f466afdb55..801ee1af5f 100644 --- a/pod/video/views.py +++ b/pod/video/views.py @@ -2222,7 +2222,7 @@ def stats_view(request, slug=None, slug_t=None): and target == "video" and ( request.POST.get("password") - and check_password(request.POST.get("password"), video[0].password) + and check_password(request.POST.get("password"), videos[0].password) ) ) or ( request.method == "GET" and videos and target in ("videos", "channel", "theme") From 37d9d5c28c62b7cbafae3b886898fe8f87ba02d2 Mon Sep 17 00:00:00 2001 From: Aymeric Jakobowski Date: Wed, 20 Sep 2023 10:30:40 +0200 Subject: [PATCH 08/19] Fix video notes --- pod/locale/fr/LC_MESSAGES/django.po | 2 +- pod/locale/fr/LC_MESSAGES/djangojs.mo | Bin 17417 -> 17417 bytes pod/locale/fr/LC_MESSAGES/djangojs.po | 6 +++--- pod/locale/nl/LC_MESSAGES/django.po | 2 +- pod/locale/nl/LC_MESSAGES/djangojs.po | 4 ++-- pod/main/static/js/main.js | 2 +- pod/video/views.py | 10 +++++++--- 7 files changed, 15 insertions(+), 11 deletions(-) diff --git a/pod/locale/fr/LC_MESSAGES/django.po b/pod/locale/fr/LC_MESSAGES/django.po index 9659063763..0ced6672ee 100644 --- a/pod/locale/fr/LC_MESSAGES/django.po +++ b/pod/locale/fr/LC_MESSAGES/django.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: Pod\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-09-19 12:42+0000\n" +"POT-Creation-Date: 2023-09-19 13:07+0000\n" "PO-Revision-Date: \n" "Last-Translator: AymericJak \n" "Language-Team: Pod Team pod@esup-portail.org\n" diff --git a/pod/locale/fr/LC_MESSAGES/djangojs.mo b/pod/locale/fr/LC_MESSAGES/djangojs.mo index 8f51f7cf4c1e7be30b2ce90ca9872d631f583fe6..a698c2dc1eb50fa745d7369d649d5cfd77d868d9 100644 GIT binary patch delta 1291 zcmXxjSx8h-9LMo9q~A@QdLzE~X#OkNhzWxrfR|E0!A`#t{0a(2gxA z*YAyUDYcQ}Edz--i#(i4j8`fhi!cRUn2E#az)6((p$Xm#=AbO37z41zupVW>XK+6D z8RLT}^Iv;D_!juM%#?ewyw6&JtLfLG97+dn#&MJ-1aDAk7jDH=`5sr|H0|PhrBbFLvYH3T<;+a;8OZyC=2+FvU$OI-UY^^Fa0D;!?h^C zKZN1fhH_{gl!d*+ML3Bz^vPFhA%>#NbL6{}T0oJ?z&0#Id9qeqg`bdzQq!1+$(&dL z)}h>B)bJNZ(+}oL+4N+T!zjT(JbCdSKiR^&v(nBKK-9z>fX-`Nai6-sjvCcH_uwSJ*N}dtuv2)e&=-{(v#-4%QJ)R|OkmPxX{FD&m3B6HXX)Kg!`=(}^~x zagt`e-{vr#^SEuLw!q5c$D%80k5pG4^h`wl@$-C7XtJA&8LgZf{@Cx?omK0v IzZPWt1F}%7b^rhX delta 1292 zcmXxjSxA&o7{>84s5#~=ZG&5`qmDLhT9T%wriM{a5G{f&Y6FS1Xc{fhKxH|$+Q}A| z%2Lx7HOC6E8>xuyB0{=}x{12TE{X`c>i;@l2OfXtymRLBEZ_K=O}=K+a7nOtfl_KJ zPAMlw#w)cH^Kb?3HO9S$lbAp~lt0;+hV@v9$M8KyxC#p#z&xp5KA1 zaoFiqDxJwjKLO^ zjr5@`Yy>0l6WZ|)&cV>4z`SUj%{aBltJHcr*%V}FO}GfhkWHztScu77SuuK0{=tCZ zBqlHp;zK#~WR%NThcj_A$_ed4xeSdK>_Ay~zu73f)V}cCsMC~!iL@g`4oeR7ocothuk6#QcBv$U2>dAlb?bn zYe@yUN8~`x5_whR(5^D&nKi>YOkY|vxu$U6u?+DUIG zk@xV7uC%*MO@5!f-0uGo_hm+SgXeHVLiPRwHJ;u6cPXbF{_5O)W{Xrk)8!Wf`fYK} EKmN$6)c^nh diff --git a/pod/locale/fr/LC_MESSAGES/djangojs.po b/pod/locale/fr/LC_MESSAGES/djangojs.po index af955b8f7e..79f974b38d 100644 --- a/pod/locale/fr/LC_MESSAGES/djangojs.po +++ b/pod/locale/fr/LC_MESSAGES/djangojs.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: Esup-Pod\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-09-19 12:42+0000\n" +"POT-Creation-Date: 2023-09-19 13:07+0000\n" "PO-Revision-Date: \n" "Last-Translator: AymericJak \n" "Language-Team: \n" @@ -453,8 +453,8 @@ msgid "Add your picture" msgstr "Ajouter votre image" #: pod/main/static/js/main.js -msgid "text copied" -msgstr "texte copié" +msgid "Text copied" +msgstr "Texte copié" #: pod/main/static/js/main.js msgid "Errors appear in the form, please correct them" diff --git a/pod/locale/nl/LC_MESSAGES/django.po b/pod/locale/nl/LC_MESSAGES/django.po index 35b09e041c..13b50eec01 100644 --- a/pod/locale/nl/LC_MESSAGES/django.po +++ b/pod/locale/nl/LC_MESSAGES/django.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: Pod\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-09-19 12:42+0000\n" +"POT-Creation-Date: 2023-09-19 13:07+0000\n" "PO-Revision-Date: 2023-06-08 14:37+0200\n" "Last-Translator: obado \n" "Language-Team: \n" diff --git a/pod/locale/nl/LC_MESSAGES/djangojs.po b/pod/locale/nl/LC_MESSAGES/djangojs.po index 41fdb55af7..fc6a221c73 100644 --- a/pod/locale/nl/LC_MESSAGES/djangojs.po +++ b/pod/locale/nl/LC_MESSAGES/djangojs.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: Esup-Pod\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-09-19 12:42+0000\n" +"POT-Creation-Date: 2023-09-19 13:07+0000\n" "PO-Revision-Date: 2023-02-08 15:22+0100\n" "Last-Translator: obado \n" "Language-Team: \n" @@ -432,7 +432,7 @@ msgid "Add your picture" msgstr "" #: pod/main/static/js/main.js -msgid "text copied" +msgid "Text copied" msgstr "" #: pod/main/static/js/main.js diff --git a/pod/main/static/js/main.js b/pod/main/static/js/main.js index 6cfb4f05e5..4e85dda90f 100644 --- a/pod/main/static/js/main.js +++ b/pod/main/static/js/main.js @@ -1070,7 +1070,7 @@ if (btnpartageprive) { var copyText = document.getElementById("txtpartageprive"); copyText.select(); document.execCommand("copy"); - showalert(gettext("text copied"), "alert-info"); + showalert(gettext("Text copied"), "alert-info"); }); } diff --git a/pod/video/views.py b/pod/video/views.py index 801ee1af5f..4548215c7c 100644 --- a/pod/video/views.py +++ b/pod/video/views.py @@ -1009,9 +1009,8 @@ def render_video( form = ( VideoPasswordForm(request.POST) if request.POST else VideoPasswordForm() ) - if ( - request.POST.get("password") - and check_password(request.POST.get("password"), video.password) + if request.POST.get("password") and check_password( + request.POST.get("password"), video.password ): messages.add_message( request, messages.ERROR, _("The password is incorrect.") @@ -1569,6 +1568,11 @@ def video_note_save(request, slug): idCom = get_id_from_request(request, "idCom") idNote = get_id_from_request(request, "idNote") + if idCom: + com = NoteComments.objects.get(id=idCom) + if idNote: + note = AdvancedNotes.objects.get(id=idNote) + if request.method == "POST" and request.POST.get("action") == "save_note": q = QueryDict(mutable=True) q.update(request.POST) From d67f612ac7eb739f7fdc3a44550339a694687bf1 Mon Sep 17 00:00:00 2001 From: Aymeric Jakobowski Date: Wed, 20 Sep 2023 12:11:50 +0200 Subject: [PATCH 09/19] Fix JS error for import video page --- .../templates/import_video/add_or_edit.html | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pod/import_video/templates/import_video/add_or_edit.html b/pod/import_video/templates/import_video/add_or_edit.html index a6592ca5b7..36dc5e9985 100644 --- a/pod/import_video/templates/import_video/add_or_edit.html +++ b/pod/import_video/templates/import_video/add_or_edit.html @@ -239,12 +239,14 @@

{% trans "Terms of Service parents[parents.length-1].style.display = 'none'; } }; -window.addEventListener('load', function(event) { - is_restricted_elt = document.getElementById("id_is_restricted"); - is_restricted_elt.addEventListener('clicked',function (event) { +is_restricted_elt = document.getElementById("id_is_restricted"); +if (is_restricted_elt !== null) { + window.addEventListener('load', function(event) { + is_restricted_elt.addEventListener('clicked',function (event) { + restrict_access_to_groups(); + }); restrict_access_to_groups(); }); - restrict_access_to_groups(); -}); +} {% endblock more_script %} From 598d8e5aebbce90ad00c03ab1c8cd84cbba03c9f Mon Sep 17 00:00:00 2001 From: Aymeric Jakobowski Date: Wed, 20 Sep 2023 14:33:47 +0200 Subject: [PATCH 10/19] Fix playlist player refresh --- pod/playlist/static/playlist/css/playlist.css | 4 ++++ pod/playlist/static/playlist/js/playlist-player.js | 2 ++ 2 files changed, 6 insertions(+) diff --git a/pod/playlist/static/playlist/css/playlist.css b/pod/playlist/static/playlist/css/playlist.css index 6132ce48b0..05824b9a09 100644 --- a/pod/playlist/static/playlist/css/playlist.css +++ b/pod/playlist/static/playlist/css/playlist.css @@ -183,6 +183,10 @@ a.player-element:not(.disabled):hover { border: var(--bs-border-width) solid var(--pod-primary) !important; } +a.player-element:not(.disabled).selected:hover { + background-color: #bebebe; +} + a.player-element.selected { background-color: #D1D1D1; } diff --git a/pod/playlist/static/playlist/js/playlist-player.js b/pod/playlist/static/playlist/js/playlist-player.js index efb71a500c..93d793c34a 100644 --- a/pod/playlist/static/playlist/js/playlist-player.js +++ b/pod/playlist/static/playlist/js/playlist-player.js @@ -10,6 +10,8 @@ function switchToNextVideo() { } playerElements[currentIndex + 1].classList.add('selected'); selectedElement.classList.remove('selected'); + selectedElement.querySelector("span.rank").innerHTML = selectedElement.id; + playerElements[currentIndex + 1].querySelector("span.rank").innerHTML = ''; let nextElement = playerElements[currentIndex + 1]; if (!(nextElement.classList.contains('disabled'))) { const videoSrc = playerElements[currentIndex + 1].getAttribute('href'); From 6422de5842bd277a5d67b3662e4b28a3ad6614ed Mon Sep 17 00:00:00 2001 From: Aymeric Jakobowski Date: Wed, 20 Sep 2023 15:14:53 +0200 Subject: [PATCH 11/19] Title improvements and aria-hidden for --- pod/chapter/templates/video_chapter.html | 2 +- pod/cut/templates/video_cut.html | 2 +- pod/live/templates/live/event-info.html | 6 +-- pod/locale/fr/LC_MESSAGES/django.mo | Bin 166029 -> 166029 bytes pod/locale/fr/LC_MESSAGES/django.po | 10 ++-- pod/locale/fr/LC_MESSAGES/djangojs.po | 2 +- pod/locale/nl/LC_MESSAGES/django.po | 6 +-- pod/locale/nl/LC_MESSAGES/djangojs.po | 2 +- pod/main/templates/aside.html | 6 +-- pod/main/templates/navbar.html | 2 +- .../playlist/playlist_sort_select.html | 4 +- pod/video/templates/channel/channel.html | 49 +++++++++++++----- pod/video/templates/videos/card.html | 12 ++--- .../templates/videos/category_modal_card.html | 6 +-- pod/video/templates/videos/link_video.html | 16 +++--- pod/video/templates/videos/video-info.html | 6 +-- .../templates/videos/video_collaborate.html | 2 +- pod/video/templates/videos/video_delete.html | 2 +- pod/video/templates/videos/video_notes.html | 8 ++- .../templates/videos/video_sort_select.html | 4 +- pod/video/templates/videos/videos.html | 14 +++-- 21 files changed, 95 insertions(+), 66 deletions(-) diff --git a/pod/chapter/templates/video_chapter.html b/pod/chapter/templates/video_chapter.html index 55afdb495e..749a16aabe 100644 --- a/pod/chapter/templates/video_chapter.html +++ b/pod/chapter/templates/video_chapter.html @@ -38,7 +38,7 @@ {% endif %}

- +  {% trans "Back to the video"%} diff --git a/pod/cut/templates/video_cut.html b/pod/cut/templates/video_cut.html index 2db041b33f..e994ffa62d 100644 --- a/pod/cut/templates/video_cut.html +++ b/pod/cut/templates/video_cut.html @@ -79,7 +79,7 @@
- +  {% trans 'Back to the video' %} diff --git a/pod/live/templates/live/event-info.html b/pod/live/templates/live/event-info.html index 19cb538e25..484319f8c3 100644 --- a/pod/live/templates/live/event-info.html +++ b/pod/live/templates/live/event-info.html @@ -91,19 +91,19 @@