{% blocktrans count counter=records.paginator.count %}{{ counter }} record found{% plural %}{{ counter }} records found{% endblocktrans %}
- {% trans "This is the list of the recorded BigBlueButton sessions for which you were moderator. This module allows you to create a video from a BigBlueButton presentation." %}
- {% trans "Shortly after the presentation is published, the corresponding video will appear in your videos." %}
+ {% trans "This is the list of the recorded BigBlueButton sessions for which you were moderator. This module allows you to create a video from a BigBlueButton presentation." %}
+ {% trans "Shortly after the presentation is published, the corresponding video will appear in your videos." %}
{% trans "Please note: a BigBlueButton presentation can be encoded by another moderator." %}
{% trans "If such a case occurs, this information will be displayed directly in the list. You can then contact this user directly to ask him/her to share the video with you, or even to put you as additional owner of the video." %}
-
+
{% include "bbb/record_list.html" %}
{% endif %}
diff --git a/pod/bbb/templates/bbb/live_card.html b/pod/bbb/templates/bbb/live_card.html
index 7d116eabb9..f0bc97ed0a 100644
--- a/pod/bbb/templates/bbb/live_card.html
+++ b/pod/bbb/templates/bbb/live_card.html
@@ -11,7 +11,7 @@
{% if form_document.errors or form_document.non_field_errors %}
- {% trans 'Your form contains errors:' %}
+ {% trans 'Your form contains errors:' %}
{% for error in form_document.non_field_errors %}
- - {{error}}
+ - {{error}}
{% endfor %}
{% endif %}
{% for field_hidden in form_document.hidden_fields %}
@@ -20,10 +20,10 @@
{% trans 'You will need the URL of this video to make subtitles and/or captions. This URL is a direct access to this video. Please do not communicate it outside of this site to avoid any misuse.' %}
{% for vid in video.get_video_mp4 %}
-
{{vid.name}} :
+
{{vid.name}} :
{% endfor %}
{% if video.is_video == False and video.get_video_mp3 %}
-
{% endif %}
{% for otherbroadcaster in broadcaster.building.broadcaster_set.all %}
diff --git a/pod/live/templates/live/directs.html b/pod/live/templates/live/directs.html
index c55f4c6308..177f0b4de8 100644
--- a/pod/live/templates/live/directs.html
+++ b/pod/live/templates/live/directs.html
@@ -17,7 +17,7 @@
{% block page_content %}
{{building.name}}
{% if building.headband %}
-
+
{% endif %}
diff --git a/pod/live/templates/live/event-info.html b/pod/live/templates/live/event-info.html
index c08d893b23..581885a125 100644
--- a/pod/live/templates/live/event-info.html
+++ b/pod/live/templates/live/event-info.html
@@ -7,7 +7,7 @@
{% if event.description %}
{% trans 'Summary' %}
-
+
{{ event.description|safe }}
{% endif %}
@@ -20,7 +20,7 @@
{% trans 'Summary' %}
{% endif %}
>
-
+
{% trans 'Broadcasted on:' %}
@@ -70,7 +70,7 @@
{% if event.is_draft %}
- {% blocktrans %}Please note that your event is in draft mode. The following links contain a key allowing access. Anyone with this links can access it.{% endblocktrans %}
+ {% blocktrans %}Please note that your event is in draft mode. The following links contain a key allowing access. Anyone with this links can access it.{% endblocktrans %}
{% else %}
{% endif %}
diff --git a/pod/main/management/commands/createconfiguration.py b/pod/main/management/commands/createconfiguration.py
index 224fdbb584..b92a028814 100644
--- a/pod/main/management/commands/createconfiguration.py
+++ b/pod/main/management/commands/createconfiguration.py
@@ -50,7 +50,7 @@ def get_information(self):
msg += "\n## %s \n" % self.data[0]["information"]["title"][self.language]
for line in self.data[0]["information"]["description"][self.language]:
if line != "":
- msg += "\n%s " % line
+ msg += "\n%s " % line
else:
msg += "\n"
msg += self.get_settings(self.data[0]["information"]["settings"])
@@ -66,7 +66,7 @@ def get_configuration(self, app):
msg += "\n\n### %s" % desc["title"][self.language]
for line in desc["description"].get(self.language, []):
if line != "":
- msg += "\n%s " % line
+ msg += "\n%s " % line
else:
msg += "\n"
msg += self.get_settings(desc["settings"])
diff --git a/pod/main/static/js/main.js b/pod/main/static/js/main.js
index dccbbc4e77..a8c6027eca 100644
--- a/pod/main/static/js/main.js
+++ b/pod/main/static/js/main.js
@@ -724,7 +724,7 @@ var send_form_data = async function (
gettext("Error during exchange") +
"(" +
error +
- ") " +
+ ") " +
gettext("No data could be stored."),
"alert-danger"
);
@@ -786,7 +786,7 @@ var send_form_data_vanilla = function (
gettext("Error during exchange") +
" (" +
err +
- ") " +
+ ") " +
gettext("No data could be stored."),
"alert-danger"
);
diff --git a/pod/main/templates/base.html b/pod/main/templates/base.html
index d668fb805e..9b5a05488f 100644
--- a/pod/main/templates/base.html
+++ b/pod/main/templates/base.html
@@ -5,17 +5,17 @@
{% spaceless %}
-
+
{% block opengraph %}
-
-
-
-
-
-
+
+
+
+
+
+
{% endblock %}
{% if FAVICON %}
@@ -35,7 +35,7 @@
{% endif %}
{% if SHOW_EVENTS_ON_HOMEPAGE and "live" in THIRD_PARTY_APPS %}
-
+
{% endif %}
{% block more_style %}
@@ -142,7 +142,7 @@
{{page_title|capfirst}}
-
+
{% trans 'We use third party cookies to personalize content, manage session and analyze site traffic.' %}
{% if COOKIE_LEARN_MORE != "" %}
{% trans 'Learn more' %}
diff --git a/pod/main/templates/contact_us.html b/pod/main/templates/contact_us.html
index 125e26e6d5..63eccd03ca 100644
--- a/pod/main/templates/contact_us.html
+++ b/pod/main/templates/contact_us.html
@@ -34,7 +34,7 @@
{% trans "Start the video than click the + icon to write a comment at the choosen time. Video will be paused." %}
- {% trans "Click on comment's timecode to go at this time in the video." %}
+
{% trans "Start the video than click the + icon to write a comment at the choosen time. Video will be paused." %}
+ {% trans "Click on comment's timecode to go at this time in the video." %}
{% trans "Black notes are public. The clearest are private. The intermediary is visible to the owner of the video." %}
{% trans "Cancel" %}
From e25fe9b08309aba4783e202ca86efb85819735ee Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 23 May 2023 01:01:00 +0000
Subject: [PATCH 05/63] Bump requests from 2.25.1 to 2.31.0
Bumps [requests](https://github.com/psf/requests) from 2.25.1 to 2.31.0.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.25.1...v2.31.0)
---
updated-dependencies:
- dependency-name: requests
dependency-type: direct:production
...
Signed-off-by: dependabot[bot]
---
requirements.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/requirements.txt b/requirements.txt
index 066ba5debc..3dfc3fd624 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -24,7 +24,7 @@ django-chunked-upload==2.0.0
django-select2
django_select2_forms
django-redis
-requests==2.25.1
+requests==2.31.0
chardet==4.0.0
django-static-compress>=1.2.1
redis==4.5.4
From f89622a9053b4dbe819d5d451c83306b881a08b8 Mon Sep 17 00:00:00 2001
From: github-actions
Date: Tue, 23 May 2023 08:55:45 +0000
Subject: [PATCH 06/63] Fixup. Format code with Prettier
---
pod/main/static/js/infinite.js | 4 +---
pod/video/static/js/filter_aside_video_list_refresh.js | 8 +++-----
2 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/pod/main/static/js/infinite.js b/pod/main/static/js/infinite.js
index bedfdda677..d5604eb655 100644
--- a/pod/main/static/js/infinite.js
+++ b/pod/main/static/js/infinite.js
@@ -94,9 +94,7 @@ class InfiniteLoader {
this.getData(url, this.next_page_number).then((data) => {
const html = new DOMParser().parseFromString(data, "text/html");
- if (
- html.getElementById("videos_list").dataset.nextPage !== "True"
- ) {
+ if (html.getElementById("videos_list").dataset.nextPage !== "True") {
this.nextPage = false;
}
diff --git a/pod/video/static/js/filter_aside_video_list_refresh.js b/pod/video/static/js/filter_aside_video_list_refresh.js
index 03d4301ae1..a7a92ca40e 100644
--- a/pod/video/static/js/filter_aside_video_list_refresh.js
+++ b/pod/video/static/js/filter_aside_video_list_refresh.js
@@ -88,13 +88,11 @@ function refreshVideosSearch() {
document.getElementById("videos_list").dataset.countvideos
);
nextPage =
- document.getElementById("videos_list").dataset.nextPage ===
- "true";
+ document.getElementById("videos_list").dataset.nextPage === "true";
window.history.pushState({}, "", url);
if (nextPage) {
- pageNext = document
- .querySelector("a.infinite-more-link")
- .dataset.nextPageNumber;
+ pageNext = document.querySelector("a.infinite-more-link").dataset
+ .nextPageNumber;
refreshInfiniteLoader(url, pageNext);
}
})
From 8f8ff2d72c3f8528298717e5be3bb861cd8e321a Mon Sep 17 00:00:00 2001
From: github-actions
Date: Tue, 23 May 2023 08:56:23 +0000
Subject: [PATCH 07/63] Auto-update configuration files
---
CONFIGURATION_FR.md | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/CONFIGURATION_FR.md b/CONFIGURATION_FR.md
index f82685eec4..46ce94a3b4 100644
--- a/CONFIGURATION_FR.md
+++ b/CONFIGURATION_FR.md
@@ -5,15 +5,15 @@
## Information générale
-La plateforme Esup-Pod se base sur le framework Django écrit en Python.
-Elle supporte les versions 3.7, 3.8 et 3.9 de Python.
+La plateforme Esup-Pod se base sur le framework Django écrit en Python.
+Elle supporte les versions 3.7, 3.8 et 3.9 de Python.
-**Django Version : 3.2 LTS**
+**Django Version : 3.2 LTS**
-> La documentation complète du framework : [https://docs.djangoproject.com/fr/3.2/]() (ou [https://docs.djangoproject.com/en/3.2/]())
-> L’ensemble des variables de configuration du framework est accessible à cette adresse : [https://docs.djangoproject.com/fr/3.2/ref/settings/]()
+> La documentation complète du framework : [https://docs.djangoproject.com/fr/3.2/]() (ou [https://docs.djangoproject.com/en/3.2/]())
+> L’ensemble des variables de configuration du framework est accessible à cette adresse : [https://docs.djangoproject.com/fr/3.2/ref/settings/]()
-Voici les configurations des applications tierces utilisées par Esup-Pod.
+Voici les configurations des applications tierces utilisées par Esup-Pod.
- `CAS`
@@ -440,8 +440,8 @@ Voici les configurations des applications tierces utilisées par Esup-Pod.
>> Répertoire par défaut pour le téléversement des vidéos.
### Langue
-Par défaut, Esup-Pod est fournie en Francais et en anglais.
-Vous pouvez tout à fait rajouter des langues comme vous le souhaitez. Il faudra pour cela créer un fichier de langue et traduire chaque entrée.
+Par défaut, Esup-Pod est fournie en Francais et en anglais.
+Vous pouvez tout à fait rajouter des langues comme vous le souhaitez. Il faudra pour cela créer un fichier de langue et traduire chaque entrée.
- `LANGUAGES`
@@ -1572,9 +1572,9 @@ Vous pouvez tout à fait rajouter des langues comme vous le souhaitez. Il faudra
### Configuration application meeting
-Application Meeting pour la gestion de reunion avec BBB.
-Mettre `USE_MEETING` à True pour activer cette application.
-`BBB_API_URL` et `BBB_SECRET_KEY` sont obligatoires pour faire fonctionner l’application
+Application Meeting pour la gestion de reunion avec BBB.
+Mettre `USE_MEETING` à True pour activer cette application.
+`BBB_API_URL` et `BBB_SECRET_KEY` sont obligatoires pour faire fonctionner l’application
- `BBB_API_URL`
@@ -2600,9 +2600,9 @@ Mettre `USE_MEETING` à True pour activer cette application.
### Configuration application xapi
-Application pour l’envoi d‘instructions xAPI à un LRS.
-Aucune instruction ne persiste dans Pod, elles sont toutes envoyées au LRS paramétré.
-Attention, il faut configurer Celery pour l’envoi des instructions.
+Application pour l’envoi d‘instructions xAPI à un LRS.
+Aucune instruction ne persiste dans Pod, elles sont toutes envoyées au LRS paramétré.
+Attention, il faut configurer Celery pour l’envoi des instructions.
- `USE_XAPI`
From beef6a2a6f420c65332d6286c15ff216de3f9bb1 Mon Sep 17 00:00:00 2001
From: mattbild
Date: Tue, 23 May 2023 11:07:30 +0200
Subject: [PATCH 08/63] add pydoc in test file
---
pod/live/tests/test_utils.py | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/pod/live/tests/test_utils.py b/pod/live/tests/test_utils.py
index c718b20601..46296aefba 100644
--- a/pod/live/tests/test_utils.py
+++ b/pod/live/tests/test_utils.py
@@ -30,6 +30,7 @@ def setUp(self):
)
def test_send_email(self):
+ """Teste l'envoi d'email et les paramètres d'envoi."""
from pod.live.utils import send_email_confirmation, get_bcc, get_cc
event = Event.objects.get(id=1)
@@ -62,6 +63,7 @@ def test_send_email(self):
print(" ---> test_utils send_email_confirmation ok")
def test_date_string_to_second(self):
+ """Teste la conversion d'une chaine de caractère en nombre de secondes."""
from pod.live.utils import date_string_to_second
self.assertEquals(0, date_string_to_second("a"))
@@ -78,6 +80,7 @@ def test_date_string_to_second(self):
print(" ---> test_utils date_string_to_second ok")
def test_get_event_id_and_broadcaster_id(self):
+ """Teste la récupération et le renvoi des éléments 'idevent' et 'idbroadcaster' de la requête."""
from pod.live.utils import get_event_id_and_broadcaster_id
rf = RequestFactory()
@@ -107,6 +110,7 @@ def test_get_event_id_and_broadcaster_id(self):
print(" ---> test_utils test_get_event_id_and_broadcaster_id ok")
def test_check_size_not_changing(self):
+ """Teste que la taille d'une ressource sur le filesystem ne change pas."""
import threading
from pod.live.utils import check_size_not_changing
from time import sleep
@@ -145,6 +149,7 @@ def modify_file():
self.assertEqual(str(cm.exception), "checkFileSize aborted")
def test_check_exists(self):
+ """Teste qu'une ressource existe sur le filesystem."""
from pod.live.utils import check_exists, check_size_not_changing
with self.assertRaises(Exception):
From 25415296c0738f2ec48ceb8badb341315d502bf7 Mon Sep 17 00:00:00 2001
From: secale
Date: Tue, 23 May 2023 14:33:41 +0200
Subject: [PATCH 09/63] =?UTF-8?q?[DONE]=20ajout=20param=C3=A8tre=20HOMEPAG?=
=?UTF-8?q?E=5FVIEW=5FVIDEOS=5FFROM=5FNON=5FVISIBLE=5FCHANNELS=20(#859)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* ajout paramètre HOMEPAGE_VIEW_VIDEOS_FROM_NON_VISIBLE_CHANNELS
---
pod/main/configuration.json | 35 +++++++++++++++++++---------
pod/video/templatetags/video_tags.py | 13 ++++++-----
2 files changed, 31 insertions(+), 17 deletions(-)
diff --git a/pod/main/configuration.json b/pod/main/configuration.json
index 095edfd862..3b4dcb8a7a 100644
--- a/pod/main/configuration.json
+++ b/pod/main/configuration.json
@@ -1217,6 +1217,19 @@
},
"pod_version_end": "",
"pod_version_init": "3.1.0"
+ },
+ "HOMEPAGE_VIEW_VIDEOS_FROM_NON_VISIBLE_CHANNELS": {
+ "default_value": false,
+ "description": {
+ "en": [
+ "Display videos from non visible channels on the homepage"
+ ],
+ "fr": [
+ "Affiche les vidéos de chaines non visibles sur la page d'accueil"
+ ]
+ },
+ "pod_version_end": "",
+ "pod_version_init": "3.2.0"
}
},
"title": {
@@ -2304,6 +2317,17 @@
"pod_version_end": "",
"pod_version_init": "3.1.0"
},
+ "USE_FAVORITES": {
+ "default_value": true,
+ "description": {
+ "en": [
+ "Activation of favorite videos. Allows users to add videos to their favorites."
+ ],
+ "fr": [
+ "Activation des vidéos favorites. Permet aux utilisateurs d'ajouter des vidéos dans leurs favoris."
+ ]
+ }
+ },
"USE_OBSOLESCENCE": {
"default_value": false,
"description": {
@@ -2318,17 +2342,6 @@
"pod_version_end": "",
"pod_version_init": "3.1.0"
},
- "USE_FAVORITES": {
- "default_value": true,
- "description": {
- "en": [
- "Activation of favorite videos. Allows users to add videos to their favorites."
- ],
- "fr": [
- "Activation des vidéos favorites. Permet aux utilisateurs d'ajouter des vidéos dans leurs favoris."
- ]
- }
- },
"USE_STATS_VIEW": {
"default_value": false,
"description": {
diff --git a/pod/video/templatetags/video_tags.py b/pod/video/templatetags/video_tags.py
index 76ac30a48b..16eb801dcb 100644
--- a/pod/video/templatetags/video_tags.py
+++ b/pod/video/templatetags/video_tags.py
@@ -14,8 +14,7 @@
from tagging.utils import LOGARITHMIC
from ..forms import VideoVersionForm
-from ..models import Video
-from ..utils import check_file
+from ..utils import check_file, get_available_videos
import importlib
import os
@@ -25,6 +24,7 @@
HOMEPAGE_SHOWS_PASSWORDED = getattr(django_settings, "HOMEPAGE_SHOWS_PASSWORDED", True)
HOMEPAGE_SHOWS_RESTRICTED = getattr(django_settings, "HOMEPAGE_SHOWS_RESTRICTED", True)
HOMEPAGE_NB_VIDEOS = getattr(django_settings, "HOMEPAGE_NB_VIDEOS", 12)
+HOMEPAGE_VIEW_VIDEOS_FROM_NON_VISIBLE_CHANNELS = getattr(django_settings, "HOMEPAGE_VIEW_VIDEOS_FROM_NON_VISIBLE_CHANNELS", False)
@register.filter(name="file_exists")
@@ -78,11 +78,12 @@ def get_version_form(video):
@register.simple_tag(takes_context=True)
def get_last_videos(context):
request = context["request"]
- videos = Video.objects.filter(
- encoding_in_progress=False,
- is_draft=False,
+ videos = get_available_videos().filter(
sites=get_current_site(request),
- ).exclude(channel__visible=0)
+ )
+
+ if not HOMEPAGE_VIEW_VIDEOS_FROM_NON_VISIBLE_CHANNELS:
+ videos = videos.exclude(channel__visible=0)
if not HOMEPAGE_SHOWS_PASSWORDED:
videos = videos.filter(Q(password="") | Q(password__isnull=True))
From fc813bda4c07c3b9e4ff3150492a8c3cab85298a Mon Sep 17 00:00:00 2001
From: github-actions
Date: Tue, 23 May 2023 12:34:11 +0000
Subject: [PATCH 10/63] Fixup. Format code with Black
---
pod/video/templatetags/video_tags.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/pod/video/templatetags/video_tags.py b/pod/video/templatetags/video_tags.py
index 16eb801dcb..3bf154b454 100644
--- a/pod/video/templatetags/video_tags.py
+++ b/pod/video/templatetags/video_tags.py
@@ -24,7 +24,9 @@
HOMEPAGE_SHOWS_PASSWORDED = getattr(django_settings, "HOMEPAGE_SHOWS_PASSWORDED", True)
HOMEPAGE_SHOWS_RESTRICTED = getattr(django_settings, "HOMEPAGE_SHOWS_RESTRICTED", True)
HOMEPAGE_NB_VIDEOS = getattr(django_settings, "HOMEPAGE_NB_VIDEOS", 12)
-HOMEPAGE_VIEW_VIDEOS_FROM_NON_VISIBLE_CHANNELS = getattr(django_settings, "HOMEPAGE_VIEW_VIDEOS_FROM_NON_VISIBLE_CHANNELS", False)
+HOMEPAGE_VIEW_VIDEOS_FROM_NON_VISIBLE_CHANNELS = getattr(
+ django_settings, "HOMEPAGE_VIEW_VIDEOS_FROM_NON_VISIBLE_CHANNELS", False
+)
@register.filter(name="file_exists")
From 206362f9cebf34c200fcab39cf2fc83a35872ace Mon Sep 17 00:00:00 2001
From: github-actions
Date: Tue, 23 May 2023 12:34:31 +0000
Subject: [PATCH 11/63] Auto-update configuration files
---
CONFIGURATION_FR.md | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/CONFIGURATION_FR.md b/CONFIGURATION_FR.md
index 46ce94a3b4..dd7a2a4b0d 100644
--- a/CONFIGURATION_FR.md
+++ b/CONFIGURATION_FR.md
@@ -1570,6 +1570,12 @@ Vous pouvez tout à fait rajouter des langues comme vous le souhaitez. Il faudra
>> Version courante du projet
+ - `HOMEPAGE_VIEW_VIDEOS_FROM_NON_VISIBLE_CHANNELS`
+
+ > valeur par défaut : `False`
+
+ >> Affiche les vidéos de chaines non visibles sur la page d'accueil
+
### Configuration application meeting
Application Meeting pour la gestion de reunion avec BBB.
@@ -2173,6 +2179,12 @@ Mettre `USE_MEETING` à True pour activer cette application.
>> Vous pouvez créer des catégories pour pouvoir ranger vos propres vidéos.
>> Les catégories sont liées à l’utilisateur.
+ - `USE_FAVORITES`
+
+ > valeur par défaut : `True`
+
+ >> Activation des vidéos favorites. Permet aux utilisateurs d'ajouter des vidéos dans leurs favoris.
+
- `USE_OBSOLESCENCE`
> valeur par défaut : `False`
@@ -2180,12 +2192,6 @@ Mettre `USE_MEETING` à True pour activer cette application.
>> Activation de l’obsolescence des video. Permet d’afficher la date de suppression de la video
>> dans le formulaire d’edition et dans la partie admin.
- - `USE_FAVORITES`
-
- > valeur par défaut : `True`
-
- >> Activation des vidéos favorites. Permet aux utilisateurs d'ajouter des vidéos dans leurs favoris.
-
- `USE_STATS_VIEW`
> valeur par défaut : `False`
From 54cee5d2d35b9d05f8b53f998cd6e3ed38e0a905 Mon Sep 17 00:00:00 2001
From: Ptitloup
Date: Wed, 24 May 2023 11:07:02 +0200
Subject: [PATCH 12/63] [WIP] Update Ralph to fix unit test (#865)
* bump ralph to 3.6.0
* test by downgrading request
* bump requests to 2.31.0
---
requirements.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/requirements.txt b/requirements.txt
index 3dfc3fd624..8572dd3edd 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -32,5 +32,5 @@ mozilla_django_oidc==3.0.0
ics==0.7.2
django-honeypot==1.0.3
qrcode
-ralph-malph==3.3.0
+ralph-malph==3.6.0
bleach==6.0.0
\ No newline at end of file
From 5e57b5d561646d81eb83c82db21d93cbe4ab8e38 Mon Sep 17 00:00:00 2001
From: thinhantran <126411793+thinhantran@users.noreply.github.com>
Date: Wed, 24 May 2023 16:55:20 +0200
Subject: [PATCH 13/63] [DONE] edit file views of podfile and recoder (#862)
* edit file views of podfile
* separate duplicate code in views recorder
* fix flake8 and add functions to utils
* fix flake8 and delete duplicate code
* add pydoc
* add fct in podfile/utils
* add fct in podfile/utils
* add pydoc
* fix flake8
---
pod/podfile/utils.py | 23 ++++
pod/podfile/views.py | 29 +----
pod/recorder/utils.py | 145 +++++++++++++++++++++++++
pod/recorder/views.py | 239 +++++-------------------------------------
4 files changed, 197 insertions(+), 239 deletions(-)
create mode 100644 pod/podfile/utils.py
diff --git a/pod/podfile/utils.py b/pod/podfile/utils.py
new file mode 100644
index 0000000000..eb529a30df
--- /dev/null
+++ b/pod/podfile/utils.py
@@ -0,0 +1,23 @@
+from django.http import HttpResponse
+from django.http import HttpResponseBadRequest
+from .models import UserFolder
+from django.contrib.auth.models import User
+
+
+def update_shared_user(request, action):
+ """Update shared user for a folder based on the specified action."""
+ foldid = request.GET.get("foldid", 0)
+ userid = request.GET.get("userid", 0)
+ if foldid == 0 or userid == 0:
+ return HttpResponseBadRequest()
+ folder = UserFolder.objects.get(id=foldid)
+ user = User.objects.get(id=userid)
+ if folder.owner == request.user or request.user.is_superuser:
+ if action == "add":
+ folder.users.add(user)
+ elif action == "remove":
+ folder.users.remove(user)
+ folder.save()
+ return HttpResponse(status=201)
+ else:
+ return HttpResponseBadRequest()
diff --git a/pod/podfile/views.py b/pod/podfile/views.py
index 99e780f84e..c93567bec9 100644
--- a/pod/podfile/views.py
+++ b/pod/podfile/views.py
@@ -27,6 +27,7 @@
import json
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from pod.main.utils import is_ajax
+from .utils import update_shared_user
__FOLDER_FILE_TYPE__ = ["image", "file"]
@@ -594,38 +595,18 @@ def user_share_autocomplete(request):
@login_required(redirect_field_name="referrer")
def remove_shared_user(request):
+ """Removes a shared user from the system."""
if is_ajax(request):
- foldid = request.GET.get("foldid", 0)
- userid = request.GET.get("userid", 0)
- if foldid == 0 or userid == 0:
- return HttpResponseBadRequest()
- folder = UserFolder.objects.get(id=foldid)
- user = User.objects.get(id=userid)
- if folder.owner == request.user or request.user.is_superuser:
- folder.users.remove(user)
- folder.save()
- return HttpResponse(status=201)
- else:
- return HttpResponseBadRequest()
+ return update_shared_user(request, "remove")
else:
return HttpResponseBadRequest()
@login_required(redirect_field_name="referrer")
def add_shared_user(request):
+ """Add a shared user from the system."""
if is_ajax(request):
- foldid = request.GET.get("foldid", 0)
- userid = request.GET.get("userid", 0)
- if foldid == 0 or userid == 0:
- return HttpResponseBadRequest()
- folder = UserFolder.objects.get(id=foldid)
- user = User.objects.get(id=userid)
- if folder.owner == request.user or request.user.is_superuser:
- folder.users.add(user)
- folder.save()
- return HttpResponse(status=201)
- else:
- return HttpResponseBadRequest()
+ return update_shared_user(request, "add")
else:
return HttpResponseBadRequest()
diff --git a/pod/recorder/utils.py b/pod/recorder/utils.py
index 5c2f5083c0..f5e6ccf487 100644
--- a/pod/recorder/utils.py
+++ b/pod/recorder/utils.py
@@ -1,16 +1,29 @@
import time
import os
+import uuid
from .models import Recording
from django.conf import settings
+from xml.dom import minidom
+from django.core.exceptions import PermissionDenied
+from django.http import HttpResponse
+
+OPENCAST_FILES_DIR = getattr(settings, "OPENCAST_FILES_DIR", "opencast-files")
+MEDIA_URL = getattr(settings, "MEDIA_URL", "/media/")
def add_comment(recording_id, comment):
+ """Adds a comment to a recording."""
recording = Recording.objects.get(id=recording_id)
recording.comment = "%s\n%s" % (recording.comment, comment)
recording.save()
def studio_clean_old_files():
+ """
+ Cleans up old files in the "opencast-files" folder.
+ The function removes files that are older than 7 days
+ from the "opencast-files" folder in the media root.
+ """
folder_to_clean = os.path.join(settings.MEDIA_ROOT, "opencast-files")
now = time.time()
@@ -19,3 +32,135 @@ def studio_clean_old_files():
if os.stat(f).st_mtime < now - 7 * 86400:
if os.path.isfile(f):
os.remove(f)
+
+
+def handle_upload_file(request, element_name, mimetype, tag_name):
+ """
+ Handle file upload and create XML element in the media package.
+
+ Args:
+ request : The HTTP request object.
+ element_name (str): The name of the XML element.
+ mimetype (str): The mimetype of the uploaded file.
+ tag_name (str): The tag name of the media package element.
+
+ Returns:
+ HttpResponse: The HTTP response containing the generated XML content.
+ """
+ idMedia = ""
+ type_name = ""
+ opencast_filename = None
+ # tags = "" # not use actually
+ idMedia = get_id_media(request)
+ if request.POST.get("flavor") and request.POST.get("flavor") != "":
+ type_name = request.POST.get("flavor")
+ mediaPackage_dir = os.path.join(
+ settings.MEDIA_ROOT, OPENCAST_FILES_DIR, "%s" % idMedia
+ )
+
+ mediaPackage_content, mediaPackage_file = get_media_package_content(
+ mediaPackage_dir, idMedia)
+
+ if (element_name != "attachment"):
+ if (element_name == "track"):
+ opencast_filename, ext = os.path.splitext(request.FILES["BODY"].name)
+ filename = "%s%s" % (type_name.replace("/", "_").replace(" ", ""), ext)
+ elif (element_name == "catalog"):
+ filename = request.FILES["BODY"].name
+
+ opencastMediaFile = os.path.join(mediaPackage_dir, filename)
+ with open(opencastMediaFile, "wb+") as destination:
+ for chunk in request.FILES["BODY"].chunks():
+ destination.write(chunk)
+
+ url_text = "%(http)s://%(host)s%(media)sopencast-files/%(idMedia)s/%(fn)s" % {
+ "http": "https" if request.is_secure() else "http",
+ "host": request.get_host(),
+ "media": MEDIA_URL,
+ "idMedia": "%s" % idMedia,
+ "fn": filename,
+ }
+ else:
+ url_text = ""
+ element = create_xml_element(mediaPackage_content, element_name,
+ type_name, mimetype, url_text, opencast_filename,)
+ media = mediaPackage_content.getElementsByTagName(tag_name)[0]
+ media.appendChild(element)
+
+ with open(mediaPackage_file, "w+") as f:
+ f.write(mediaPackage_content.toxml())
+
+ return HttpResponse(mediaPackage_content.toxml(), content_type="application/xml")
+
+
+def get_id_media(request):
+ """
+ Extracts and returns idMedia from the mediaPackage in the request.
+ """
+ if (
+ request.POST.get("mediaPackage") != ""
+ and request.POST.get("mediaPackage") != "{}"
+ ):
+ mediaPackage = request.POST.get("mediaPackage")
+ # XML result to parse
+ xmldoc = minidom.parseString(mediaPackage)
+ # Get the idMedia
+ idMedia = xmldoc.getElementsByTagName("mediapackage")[0].getAttribute("id")
+ return idMedia
+ return None
+
+
+def get_media_package_content(mediaPackage_dir, idMedia):
+ """
+ Retrieve the media package content and the media package file by parsing an XML file.
+ """
+ mediaPackage_file = os.path.join(mediaPackage_dir, "%s.xml" % idMedia)
+ mediaPackage_content = minidom.parse(mediaPackage_file) # parse an open file
+ mediapackage = mediaPackage_content.getElementsByTagName("mediapackage")[0]
+ if mediapackage.getAttribute("id") != idMedia:
+ raise PermissionDenied("Access denied: ID mismatch.")
+
+ return mediaPackage_content, mediaPackage_file
+
+
+def create_xml_element(mediaPackage_content,
+ element_name,
+ type_name,
+ mimetype,
+ url_text,
+ opencast_filename=None
+ ):
+ """
+ Create an XML element with the specified attributes.
+
+ Args:
+ mediaPackage_content: The media package content.
+ element_name (str): The name of the XML element.
+ type_name (str): The type of the XML element.
+ mimetype (str): The mimetype of the XML element.
+ url_text (str): The URL text of the XML element.
+ opencast_filename : defaults to None.
+
+ Returns:
+ element : The created XML element.
+ """
+ element = mediaPackage_content.createElement(element_name)
+ element.setAttributeNode(mediaPackage_content.createAttribute("id"))
+ element.setAttributeNode(mediaPackage_content.createAttribute("type"))
+ element.setAttribute("id", "%s" % uuid.uuid4())
+ element.setAttribute("type", type_name)
+ if (element_name == "track"):
+ element.setAttributeNode(mediaPackage_content.createAttribute("filename"))
+ element.setAttribute("filename", opencast_filename)
+ mimetype_element = mediaPackage_content.createElement("mimetype")
+ mimetype_element.appendChild(mediaPackage_content.createTextNode(mimetype))
+ element.appendChild(mimetype_element)
+ url = mediaPackage_content.createElement("url")
+ url.appendChild(mediaPackage_content.createTextNode(url_text))
+ element.appendChild(url)
+ if (element_name == "track"):
+ live = mediaPackage_content.createElement("live")
+ live.appendChild(mediaPackage_content.createTextNode("false"))
+ element.appendChild(live)
+
+ return element
diff --git a/pod/recorder/views.py b/pod/recorder/views.py
index 6a2d36cc02..db45d82cc9 100644
--- a/pod/recorder/views.py
+++ b/pod/recorder/views.py
@@ -43,6 +43,13 @@
from django.views.decorators.csrf import csrf_exempt
from xml.dom import minidom
+from .utils import (
+ get_id_media,
+ handle_upload_file,
+ create_xml_element,
+ get_media_package_content
+)
+
DEFAULT_RECORDER_PATH = getattr(settings, "DEFAULT_RECORDER_PATH", "/data/ftp-pod/ftp/")
# USE_CAS = getattr(settings, "USE_CAS", False)
@@ -104,13 +111,12 @@ def fetch_user(request, form):
@csrf_protect
@staff_member_required(redirect_field_name="referrer")
def add_recording(request):
+ """ Adds a recording to the system."""
if in_maintenance():
return redirect(reverse("maintenance"))
- mediapath = request.GET.get("mediapath") if (request.GET.get("mediapath")) else ""
- course_title = (
- request.GET.get("course_title") if request.GET.get("course_title") else ""
- )
- recorder = request.GET.get("recorder") or None
+ mediapath = request.GET.get("mediapath", "")
+ course_title = request.GET.get("course_title", "")
+ recorder = request.GET.get("recorder", None)
recorder = check_recorder(recorder, request)
@@ -492,21 +498,12 @@ def ingest_addDCCatalog(request):
):
typeCatalog = "dublincore/episode"
# Id catalog. Example format: 798017b1-2c45-42b1-85b0-41ce804fa527
- idCatalog = uuid.uuid4()
+ # idCatalog = uuid.uuid4()
# Id media package
idMedia = ""
# dublinCore
dublinCore = ""
- if (
- request.POST.get("mediaPackage") != ""
- and request.POST.get("mediaPackage") != "{}"
- ):
- mediaPackage = request.POST.get("mediaPackage")
- # XML result to parse
- xmldoc = minidom.parseString(mediaPackage)
- # Get the good id and start date
- idMedia = xmldoc.getElementsByTagName("mediapackage")[0].getAttribute("id")
-
+ idMedia = get_id_media(request)
if request.POST.get("flavor") and request.POST.get("flavor") != "":
typeCatalog = request.POST.get("flavor")
if request.POST.get("dublinCore") and request.POST.get("dublinCore") != "":
@@ -515,7 +512,6 @@ def ingest_addDCCatalog(request):
mediaPackage_dir = os.path.join(
settings.MEDIA_ROOT, OPENCAST_FILES_DIR, "%s" % idMedia
)
- mediaPackage_file = os.path.join(mediaPackage_dir, "%s.xml" % idMedia)
# create directory to store the dublincore file.
os.makedirs(mediaPackage_dir, exist_ok=True)
# store the dublin core file
@@ -523,10 +519,8 @@ def ingest_addDCCatalog(request):
with open(dublinCore_file, "w+") as f:
f.write(unquote(dublinCore))
- mediaPackage_content = minidom.parse(mediaPackage_file) # parse an open file
- mediapackage = mediaPackage_content.getElementsByTagName("mediapackage")[0]
- if mediapackage.getAttribute("id") != idMedia:
- raise PermissionDenied
+ mediaPackage_content, mediaPackage_file = get_media_package_content(
+ mediaPackage_dir, idMedia)
dc_url = str(
"%(http)s://%(host)s%(media)sopencast-files/%(idMedia)s/dublincore.xml"
@@ -537,17 +531,8 @@ def ingest_addDCCatalog(request):
"idMedia": "%s" % idMedia,
}
)
- catalog = mediaPackage_content.createElement("catalog")
- catalog.setAttributeNode(mediaPackage_content.createAttribute("type"))
- catalog.setAttributeNode(mediaPackage_content.createAttribute("id"))
- catalog.setAttribute("id", "%s" % idCatalog)
- catalog.setAttribute("type", typeCatalog)
- mimetype = mediaPackage_content.createElement("mimetype")
- mimetype.appendChild(mediaPackage_content.createTextNode("text/xml"))
- catalog.appendChild(mimetype)
- url = mediaPackage_content.createElement("url")
- url.appendChild(mediaPackage_content.createTextNode(dc_url))
- catalog.appendChild(url)
+ catalog = create_xml_element(mediaPackage_content, "catalog", typeCatalog,
+ "text/xml", dc_url)
metadata = mediaPackage_content.getElementsByTagName("metadata")[0]
metadata.appendChild(catalog)
@@ -570,50 +555,7 @@ def ingest_addAttachment(request):
and request.POST.get("flavor")
and request.FILES.get("BODY")
):
- idMedia = ""
- typeAttachment = ""
- if (
- request.POST.get("mediaPackage") != ""
- and request.POST.get("mediaPackage") != "{}"
- ):
- mediaPackage = request.POST.get("mediaPackage")
- # XML result to parse
- xmldoc = minidom.parseString(mediaPackage)
- # Get the good id and start date
- idMedia = xmldoc.getElementsByTagName("mediapackage")[0].getAttribute("id")
- if request.POST.get("flavor") and request.POST.get("flavor") != "":
- typeAttachment = request.POST.get("flavor")
- # save the ACLFile ???
-
- mediaPackage_dir = os.path.join(
- settings.MEDIA_ROOT, OPENCAST_FILES_DIR, "%s" % idMedia
- )
- mediaPackage_file = os.path.join(mediaPackage_dir, "%s.xml" % idMedia)
- mediaPackage_content = minidom.parse(mediaPackage_file) # parse an open file
- mediapackage = mediaPackage_content.getElementsByTagName("mediapackage")[0]
- if mediapackage.getAttribute("id") != idMedia:
- raise PermissionDenied
-
- attachment = mediaPackage_content.createElement("attachment")
- attachment.setAttributeNode(mediaPackage_content.createAttribute("type"))
- attachment.setAttributeNode(mediaPackage_content.createAttribute("id"))
- attachment.setAttribute("id", "%s" % uuid.uuid4())
- attachment.setAttribute("type", typeAttachment)
- mimetype = mediaPackage_content.createElement("mimetype")
- mimetype.appendChild(mediaPackage_content.createTextNode("text/xml"))
- attachment.appendChild(mimetype)
- url = mediaPackage_content.createElement("url")
- url.appendChild(mediaPackage_content.createTextNode(""))
- attachment.appendChild(url)
-
- attachments = mediaPackage_content.getElementsByTagName("attachments")[0]
- attachments.appendChild(attachment)
-
- with open(mediaPackage_file, "w+") as f:
- f.write(mediaPackage_content.toxml())
-
- return HttpResponse(mediaPackage_content.toxml(), content_type="application/xml")
-
+ return handle_upload_file(request, "attachment", "text/xml", "attachments")
return HttpResponseBadRequest()
@@ -628,73 +570,7 @@ def ingest_addTrack(request):
# and request.POST.get("tags") # unused tags
and request.FILES.get("BODY")
):
- idMedia = ""
- typeTrack = ""
- # tags = "" # not use actually
- if (
- request.POST.get("mediaPackage") != ""
- and request.POST.get("mediaPackage") != "{}"
- ):
- mediaPackage = request.POST.get("mediaPackage")
- # XML result to parse
- xmldoc = minidom.parseString(mediaPackage)
- # Get the good id and start date
- idMedia = xmldoc.getElementsByTagName("mediapackage")[0].getAttribute("id")
- if request.POST.get("flavor") and request.POST.get("flavor") != "":
- typeTrack = request.POST.get("flavor")
- # if request.POST.get("tags") and request.POST.get("tags") != "":
- # tags = request.POST.get("tags")
-
- mediaPackage_dir = os.path.join(
- settings.MEDIA_ROOT, OPENCAST_FILES_DIR, "%s" % idMedia
- )
- mediaPackage_file = os.path.join(mediaPackage_dir, "%s.xml" % idMedia)
- mediaPackage_content = minidom.parse(mediaPackage_file) # parse an open file
- mediapackage = mediaPackage_content.getElementsByTagName("mediapackage")[0]
-
- if mediapackage.getAttribute("id") != idMedia:
- raise PermissionDenied
-
- opencast_filename, ext = os.path.splitext(request.FILES["BODY"].name)
-
- dest_filename = "%s%s" % (typeTrack.replace("/", "_").replace(" ", ""), ext)
- # Upload the video file
- opencastMediaFile = os.path.join(mediaPackage_dir, dest_filename)
- with open(opencastMediaFile, "wb+") as destination:
- for chunk in request.FILES["BODY"].chunks():
- destination.write(chunk)
-
- track = mediaPackage_content.createElement("track")
- track.setAttributeNode(mediaPackage_content.createAttribute("id"))
- track.setAttributeNode(mediaPackage_content.createAttribute("type"))
- track.setAttributeNode(mediaPackage_content.createAttribute("filename"))
- track.setAttribute("id", "%s" % uuid.uuid4())
- track.setAttribute("type", typeTrack)
- track.setAttribute("filename", opencast_filename)
- mimetype = mediaPackage_content.createElement("mimetype")
- mimetype.appendChild(mediaPackage_content.createTextNode("video/webm"))
- track.appendChild(mimetype)
- track_url = "%(http)s://%(host)s%(media)sopencast-files/%(idMedia)s/%(fn)s" % {
- "http": "https" if request.is_secure() else "http",
- "host": request.get_host(),
- "media": MEDIA_URL,
- "idMedia": "%s" % idMedia,
- "fn": dest_filename,
- }
- url = mediaPackage_content.createElement("url")
- url.appendChild(mediaPackage_content.createTextNode(track_url))
- track.appendChild(url)
- live = mediaPackage_content.createElement("live")
- live.appendChild(mediaPackage_content.createTextNode("false"))
- track.appendChild(live)
-
- media = mediaPackage_content.getElementsByTagName("media")[0]
- media.appendChild(track)
-
- with open(mediaPackage_file, "w+") as f:
- f.write(mediaPackage_content.toxml())
-
- return HttpResponse(mediaPackage_content.toxml(), content_type="application/xml")
+ return handle_upload_file(request, "track", "video/webm", "media")
return HttpResponseBadRequest()
@@ -708,62 +584,7 @@ def ingest_addCatalog(request):
and request.POST.get("flavor")
and request.FILES.get("BODY")
):
- idMedia = ""
- typeCatalog = ""
- # tags = "" # not use actually
- if (
- request.POST.get("mediaPackage") != ""
- and request.POST.get("mediaPackage") != "{}"
- ):
- mediaPackage = request.POST.get("mediaPackage")
- # XML result to parse
- xmldoc = minidom.parseString(mediaPackage)
- # Get the good id and start date
- idMedia = xmldoc.getElementsByTagName("mediapackage")[0].getAttribute("id")
- if request.POST.get("flavor") and request.POST.get("flavor") != "":
- typeCatalog = request.POST.get("flavor")
-
- mediaPackage_dir = os.path.join(
- settings.MEDIA_ROOT, OPENCAST_FILES_DIR, "%s" % idMedia
- )
- mediaPackage_file = os.path.join(mediaPackage_dir, "%s.xml" % idMedia)
- mediaPackage_content = minidom.parse(mediaPackage_file) # parse an open file
- mediapackage = mediaPackage_content.getElementsByTagName("mediapackage")[0]
-
- if mediapackage.getAttribute("id") != idMedia:
- raise PermissionDenied
-
- opencast_filename = request.FILES["BODY"].name
- # Upload the cutting file
- opencastMediaFile = os.path.join(mediaPackage_dir, opencast_filename)
- with open(opencastMediaFile, "wb+") as destination:
- for chunk in request.FILES["BODY"].chunks():
- destination.write(chunk)
-
- catalog_url = "%(http)s://%(host)s%(media)sopencast-files/%(idMedia)s/%(fn)s" % {
- "http": "https" if request.is_secure() else "http",
- "host": request.get_host(),
- "media": MEDIA_URL,
- "idMedia": "%s" % idMedia,
- "fn": opencast_filename,
- }
- catalog = mediaPackage_content.createElement("catalog")
- catalog.setAttributeNode(mediaPackage_content.createAttribute("type"))
- catalog.setAttributeNode(mediaPackage_content.createAttribute("id"))
- catalog.setAttribute("id", "%s" % uuid.uuid4())
- catalog.setAttribute("type", typeCatalog)
- mimetype = mediaPackage_content.createElement("mimetype")
- mimetype.appendChild(mediaPackage_content.createTextNode("text/xml"))
- catalog.appendChild(mimetype)
- url = mediaPackage_content.createElement("url")
- url.appendChild(mediaPackage_content.createTextNode(catalog_url))
- catalog.appendChild(url)
-
- metadata = mediaPackage_content.getElementsByTagName("metadata")[0]
- metadata.appendChild(catalog)
- with open(mediaPackage_file, "w+") as f:
- f.write(mediaPackage_content.toxml())
- return HttpResponse(mediaPackage_content.toxml(), content_type="application/xml")
+ return handle_upload_file(request, "catalog", "text/xml", "metadata")
return HttpResponseBadRequest()
@@ -773,25 +594,13 @@ def ingest_ingest(request):
# URI ingest useful for OpenCast Studio
# Form management with 1 parameter : mediaPackage
# Management of the mediaPackage (XML)
- if (
- request.POST.get("mediaPackage")
- and request.POST.get("mediaPackage") != ""
- and request.POST.get("mediaPackage") != "{}"
- ):
- mediaPackage = request.POST.get("mediaPackage")
- # XML result to parse
- xmldoc = minidom.parseString(mediaPackage)
- idMedia = xmldoc.getElementsByTagName("mediapackage")[0].getAttribute("id")
+ if request.POST.get("mediaPackage"):
+ idMedia = get_id_media(request)
mediaPackage_dir = os.path.join(
settings.MEDIA_ROOT, OPENCAST_FILES_DIR, "%s" % idMedia
)
- mediaPackage_file = os.path.join(mediaPackage_dir, "%s.xml" % idMedia)
- mediaPackage_content = minidom.parse(mediaPackage_file) # parse an open file
- mediapackage = mediaPackage_content.getElementsByTagName("mediapackage")[0]
-
- if mediapackage.getAttribute("id") != idMedia:
- raise PermissionDenied
-
+ mediaPackage_content, mediaPackage_file = get_media_package_content(
+ mediaPackage_dir, idMedia)
# Create the recording
# Search for the recorder corresponding to the Studio
recorder = Recorder.objects.filter(
From c565f875ef2215b31325ef5d331299717b91c548 Mon Sep 17 00:00:00 2001
From: github-actions
Date: Wed, 24 May 2023 14:55:53 +0000
Subject: [PATCH 14/63] Fixup. Format code with Black
---
pod/recorder/utils.py | 38 +++++++++++++++++++++++---------------
pod/recorder/views.py | 15 +++++++++------
2 files changed, 32 insertions(+), 21 deletions(-)
diff --git a/pod/recorder/utils.py b/pod/recorder/utils.py
index f5e6ccf487..51b2aea06c 100644
--- a/pod/recorder/utils.py
+++ b/pod/recorder/utils.py
@@ -59,13 +59,14 @@ def handle_upload_file(request, element_name, mimetype, tag_name):
)
mediaPackage_content, mediaPackage_file = get_media_package_content(
- mediaPackage_dir, idMedia)
+ mediaPackage_dir, idMedia
+ )
- if (element_name != "attachment"):
- if (element_name == "track"):
+ if element_name != "attachment":
+ if element_name == "track":
opencast_filename, ext = os.path.splitext(request.FILES["BODY"].name)
filename = "%s%s" % (type_name.replace("/", "_").replace(" ", ""), ext)
- elif (element_name == "catalog"):
+ elif element_name == "catalog":
filename = request.FILES["BODY"].name
opencastMediaFile = os.path.join(mediaPackage_dir, filename)
@@ -82,8 +83,14 @@ def handle_upload_file(request, element_name, mimetype, tag_name):
}
else:
url_text = ""
- element = create_xml_element(mediaPackage_content, element_name,
- type_name, mimetype, url_text, opencast_filename,)
+ element = create_xml_element(
+ mediaPackage_content,
+ element_name,
+ type_name,
+ mimetype,
+ url_text,
+ opencast_filename,
+ )
media = mediaPackage_content.getElementsByTagName(tag_name)[0]
media.appendChild(element)
@@ -123,13 +130,14 @@ def get_media_package_content(mediaPackage_dir, idMedia):
return mediaPackage_content, mediaPackage_file
-def create_xml_element(mediaPackage_content,
- element_name,
- type_name,
- mimetype,
- url_text,
- opencast_filename=None
- ):
+def create_xml_element(
+ mediaPackage_content,
+ element_name,
+ type_name,
+ mimetype,
+ url_text,
+ opencast_filename=None,
+):
"""
Create an XML element with the specified attributes.
@@ -149,7 +157,7 @@ def create_xml_element(mediaPackage_content,
element.setAttributeNode(mediaPackage_content.createAttribute("type"))
element.setAttribute("id", "%s" % uuid.uuid4())
element.setAttribute("type", type_name)
- if (element_name == "track"):
+ if element_name == "track":
element.setAttributeNode(mediaPackage_content.createAttribute("filename"))
element.setAttribute("filename", opencast_filename)
mimetype_element = mediaPackage_content.createElement("mimetype")
@@ -158,7 +166,7 @@ def create_xml_element(mediaPackage_content,
url = mediaPackage_content.createElement("url")
url.appendChild(mediaPackage_content.createTextNode(url_text))
element.appendChild(url)
- if (element_name == "track"):
+ if element_name == "track":
live = mediaPackage_content.createElement("live")
live.appendChild(mediaPackage_content.createTextNode("false"))
element.appendChild(live)
diff --git a/pod/recorder/views.py b/pod/recorder/views.py
index db45d82cc9..daebb0d71a 100644
--- a/pod/recorder/views.py
+++ b/pod/recorder/views.py
@@ -47,7 +47,7 @@
get_id_media,
handle_upload_file,
create_xml_element,
- get_media_package_content
+ get_media_package_content,
)
DEFAULT_RECORDER_PATH = getattr(settings, "DEFAULT_RECORDER_PATH", "/data/ftp-pod/ftp/")
@@ -111,7 +111,7 @@ def fetch_user(request, form):
@csrf_protect
@staff_member_required(redirect_field_name="referrer")
def add_recording(request):
- """ Adds a recording to the system."""
+ """Adds a recording to the system."""
if in_maintenance():
return redirect(reverse("maintenance"))
mediapath = request.GET.get("mediapath", "")
@@ -520,7 +520,8 @@ def ingest_addDCCatalog(request):
f.write(unquote(dublinCore))
mediaPackage_content, mediaPackage_file = get_media_package_content(
- mediaPackage_dir, idMedia)
+ mediaPackage_dir, idMedia
+ )
dc_url = str(
"%(http)s://%(host)s%(media)sopencast-files/%(idMedia)s/dublincore.xml"
@@ -531,8 +532,9 @@ def ingest_addDCCatalog(request):
"idMedia": "%s" % idMedia,
}
)
- catalog = create_xml_element(mediaPackage_content, "catalog", typeCatalog,
- "text/xml", dc_url)
+ catalog = create_xml_element(
+ mediaPackage_content, "catalog", typeCatalog, "text/xml", dc_url
+ )
metadata = mediaPackage_content.getElementsByTagName("metadata")[0]
metadata.appendChild(catalog)
@@ -600,7 +602,8 @@ def ingest_ingest(request):
settings.MEDIA_ROOT, OPENCAST_FILES_DIR, "%s" % idMedia
)
mediaPackage_content, mediaPackage_file = get_media_package_content(
- mediaPackage_dir, idMedia)
+ mediaPackage_dir, idMedia
+ )
# Create the recording
# Search for the recorder corresponding to the Studio
recorder = Recorder.objects.filter(
From 13ae735cb02c283c17e0ec82c6c5ee0f70721247 Mon Sep 17 00:00:00 2001
From: Olivier Bado-Faustin
Date: Fri, 26 May 2023 14:14:22 +0200
Subject: [PATCH 15/63] [DONE] Keep sort order in video URL (#861)
* Sort order set in URL is keeped and can be shared by link
* Delete redundant occurence of "sort_videos_list" function
* Delete favorite_video_sort_select (redundant with video_sort_select)
* Remove request param from sort_videos_list()
+ Add title on favorite video page
* Update .po/.mo lang files
* add "if sort_field:"
* ensure that given sort_field is in sortable fields list
* Rename the "refresh" button to "sort by rank"
* Add "None" to sort options
* Add verbose_name for each Pod apps
* * Add unique constraint for favorite (There mustn't be duplicated ranks for one owner)
* Display favorite video rank while reorganizing
* Use the default video ordering when no sort_field selected.
* Add "date_evt" as sort field
* Some Pydocs cleaning
* Cleanup merge conflict artifacts
+ Some Pydoc cleaning
* flake8
* Update test_sort_videos_list_1
* Update .po/.mo lang files
* correct a small bug causing "download" title not being displayed
* * remove debugging console.log
* W3C compliance
* Do not display sorter if there is less than one video
---
pod/authentication/apps.py | 2 +
pod/authentication/tests/test_populated.py | 18 +-
pod/chapter/apps.py | 2 +
pod/completion/apps.py | 2 +
.../templates/video_completion.html | 2 +-
pod/cut/apps.py | 2 +
pod/cut/templates/video_cut.html | 2 +-
pod/enrichment/apps.py | 1 +
pod/favorite/admin.py | 5 +-
pod/favorite/apps.py | 5 +
pod/favorite/models.py | 21 +-
pod/favorite/static/css/favorites-list.css | 58 ++--
pod/favorite/static/js/favorite-reorganize.js | 52 ++--
.../static/js/video-favorites-card-list.js | 2 +-
pod/favorite/static/js/video-favorites.js | 7 +-
.../favorite/favorite_video_list.html | 5 +-
.../favorite/favorite_video_sort_select.html | 13 -
.../templates/favorite/favorite_videos.html | 42 ++-
pod/favorite/tests/test_utils.py | 23 +-
pod/favorite/tests/test_views.py | 36 ++-
pod/favorite/utils.py | 13 +-
pod/favorite/views.py | 16 +-
pod/live/apps.py | 2 +
pod/live/views.py | 5 +-
pod/locale/fr/LC_MESSAGES/django.mo | Bin 147910 -> 148377 bytes
pod/locale/fr/LC_MESSAGES/django.po | 261 ++++++++++--------
pod/locale/fr/LC_MESSAGES/djangojs.mo | Bin 16500 -> 17181 bytes
pod/locale/fr/LC_MESSAGES/djangojs.po | 144 +++++-----
pod/locale/nl/LC_MESSAGES/django.po | 212 +++++++-------
pod/locale/nl/LC_MESSAGES/djangojs.po | 93 +++++--
pod/lti/apps.py | 2 +
pod/main/apps.py | 9 +-
pod/main/fixtures/initial_data.json | 2 +-
pod/main/static/css/pod.css | 5 +-
pod/meeting/apps.py | 2 +
pod/meeting/models.py | 7 +-
pod/playlist/apps.py | 2 +
pod/podfile/apps.py | 2 +
pod/recorder/apps.py | 2 +
pod/video/apps.py | 3 +
pod/video/models.py | 4 +
.../js/filter_aside_video_list_refresh.js | 13 +-
pod/video/templates/videos/link_video.html | 4 +-
pod/video/templates/videos/my_videos.html | 20 +-
pod/video/templates/videos/video-info.html | 2 +-
pod/video/templates/videos/video.html | 7 +-
.../templates/videos/video_sort_select.html | 19 +-
pod/video/utils.py | 17 ++
pod/video/views.py | 48 ++--
pod/video_search/apps.py | 2 +
pod/xapi/apps.py | 2 +
51 files changed, 718 insertions(+), 502 deletions(-)
delete mode 100644 pod/favorite/templates/favorite/favorite_video_sort_select.html
diff --git a/pod/authentication/apps.py b/pod/authentication/apps.py
index 69405e5b21..b753a5727a 100644
--- a/pod/authentication/apps.py
+++ b/pod/authentication/apps.py
@@ -1,6 +1,7 @@
from django.apps import AppConfig
from django.db.models.signals import post_migrate
from django.core.exceptions import ObjectDoesNotExist
+from django.utils.translation import gettext_lazy as _
def create_groupsite_if_not_exists(g):
@@ -33,6 +34,7 @@ def set_default_site(sender, **kwargs):
class AuthConfig(AppConfig):
name = "pod.authentication"
default_auto_field = "django.db.models.BigAutoField"
+ verbose_name = _("Authentication")
def ready(self):
post_migrate.connect(set_default_site, sender=self)
diff --git a/pod/authentication/tests/test_populated.py b/pod/authentication/tests/test_populated.py
index 8daef06289..996ee8f02d 100644
--- a/pod/authentication/tests/test_populated.py
+++ b/pod/authentication/tests/test_populated.py
@@ -441,7 +441,7 @@ def setUp(self):
print(" ---> SetUp of PopulatedShibTestCase: OK!")
def _authenticate_shib_user(self, u):
- """Simulate shibboleth header"""
+ """Simulate shibboleth header."""
fake_shib_header = {
"REMOTE_USER": u["username"],
self.hmap["username"]: u["username"],
@@ -455,13 +455,13 @@ def _authenticate_shib_user(self, u):
fake_shib_header[self.hmap["affiliation"]] = u["affiliations"].split(";")[0]
fake_shib_header[self.hmap["affiliations"]] = u["affiliations"]
- """ Get valid shib_meta from simulated shibboleth header """
+ """Get valid shib_meta from simulated shibboleth header """
request = RequestFactory().get("/", REMOTE_USER=u["username"])
request.META.update(**fake_shib_header)
shib_meta, error = shibmiddleware.ShibbMiddleware.parse_attributes(request)
self.assertFalse(error, "Generating shibboleth attribute mapping contains errors")
- """ Check user authentication """
+ """Check user authentication """
user = ShibbBackend.authenticate(
ShibbBackend(),
request=request,
@@ -489,7 +489,7 @@ def test_make_profile(self):
self.assertEqual(user.first_name, "John")
self.assertEqual(user.last_name, "Do")
- """ Test if user can be staff if SHIBBOLETH_STAFF_ALLOWED_DOMAINS is None """
+ """Test if user can be staff if SHIBBOLETH_STAFF_ALLOWED_DOMAINS is None """
settings.SHIBBOLETH_STAFF_ALLOWED_DOMAINS = None
reload(shibmiddleware)
shibmiddleware.ShibbMiddleware.make_profile(
@@ -500,7 +500,7 @@ def test_make_profile(self):
owner = Owner.objects.get(user__username="jdo@univ.fr")
self.assertEqual(owner.affiliation, "teacher")
- """ Test if user can be staff when SHIBBOLETH_STAFF_ALLOWED_DOMAINS
+ """Test if user can be staff when SHIBBOLETH_STAFF_ALLOWED_DOMAINS
is restricted """
settings.SHIBBOLETH_STAFF_ALLOWED_DOMAINS = (
"univ-a.fr",
@@ -514,7 +514,7 @@ def test_make_profile(self):
)
self.assertFalse(user.is_staff)
- """ Test if user become staff when SHIBBOLETH_STAFF_ALLOWED_DOMAINS
+ """Test if user become staff when SHIBBOLETH_STAFF_ALLOWED_DOMAINS
is restrict and contains his domain """
settings.SHIBBOLETH_STAFF_ALLOWED_DOMAINS = ("univ.fr",)
reload(shibmiddleware)
@@ -523,7 +523,7 @@ def test_make_profile(self):
)
self.assertTrue(user.is_staff)
- """ Test if same user with new unstaffable affiliation keep his staff status """
+ """Test if same user with new unstaffable affiliation keep his staff status """
for a in UNSTAFFABLE_AFFILIATIONS:
self.assertFalse(a in AFFILIATION_STAFF)
user, shib_meta = self._authenticate_shib_user(
@@ -540,12 +540,12 @@ def test_make_profile(self):
)
self.assertTrue(user.is_staff) # Staff status is not remove
- """ Test if the main affiliation of this same user
+ """Test if the main affiliation of this same user
with new unstaffable affiliation has changed """
owner = Owner.objects.get(user__username="jdo@univ.fr")
self.assertEqual(owner.affiliation, "member")
- """ Test if a new user with same unstaffable affiliations has no staff status"""
+ """Test if a new user with same unstaffable affiliations has no staff status"""
user, shib_meta = self._authenticate_shib_user(
{
"username": "ada@univ.fr",
diff --git a/pod/chapter/apps.py b/pod/chapter/apps.py
index 9991e1d636..932e0fa297 100644
--- a/pod/chapter/apps.py
+++ b/pod/chapter/apps.py
@@ -1,6 +1,8 @@
from django.apps import AppConfig
+from django.utils.translation import gettext_lazy as _
class ChapterConfig(AppConfig):
name = "pod.chapter"
default_auto_field = "django.db.models.BigAutoField"
+ verbose_name = _("Chapters")
diff --git a/pod/completion/apps.py b/pod/completion/apps.py
index 760b752a36..a93f23a0ef 100644
--- a/pod/completion/apps.py
+++ b/pod/completion/apps.py
@@ -1,6 +1,8 @@
from django.apps import AppConfig
+from django.utils.translation import gettext_lazy as _
class CompletionConfig(AppConfig):
name = "pod.completion"
default_auto_field = "django.db.models.BigAutoField"
+ verbose_name = _("Video additions")
diff --git a/pod/completion/templates/video_completion.html b/pod/completion/templates/video_completion.html
index 73304d9f92..5101a3d44c 100644
--- a/pod/completion/templates/video_completion.html
+++ b/pod/completion/templates/video_completion.html
@@ -2,7 +2,7 @@
{% extends 'base.html' %}
{% load i18n %}
{% load static %}
-{% block page_title %}{% trans 'Complements of the video' %} "{{video.title}}"{% endblock page_title %}
+{% block page_title %}{% trans 'Video additions' %} "{{video.title}}"{% endblock page_title %}
{% block page_extra_head %}
diff --git a/pod/cut/apps.py b/pod/cut/apps.py
index 7c76a66625..d8548dcd1b 100644
--- a/pod/cut/apps.py
+++ b/pod/cut/apps.py
@@ -1,6 +1,8 @@
from django.apps import AppConfig
+from django.utils.translation import gettext_lazy as _
class CutConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "pod.cut"
+ verbose_name = _("Video cuts")
diff --git a/pod/cut/templates/video_cut.html b/pod/cut/templates/video_cut.html
index 22abace6be..8750f936e6 100644
--- a/pod/cut/templates/video_cut.html
+++ b/pod/cut/templates/video_cut.html
@@ -117,7 +117,7 @@
{% trans "Help"%}
{% trans 'The video cut allows you to set a start and an end to trim your video.' %}
-
{% trans 'Your original video is kept and you can therefore modify your changes at any time' %}
+
{% trans 'Your original video is kept and you can therefore modify your changes at any time.' %}
{% trans 'When saving your cut, an encoding is restarted to replace the old one.' %}
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"
" "
@@ -5064,8 +5060,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"
" "
@@ -5094,6 +5090,10 @@ msgstr ""
"L’enregistrement a été téléversé sur Pod.Vous pouvez voir la vidéo "
"directement dans Mes vidéos."
+#: pod/playlist/apps.py pod/playlist/models.py
+msgid "Playlists"
+msgstr "Listes de lecture"
+
#: pod/playlist/models.py
msgid "Short description of the playlist."
msgstr "Courte description de la liste de lecture."
@@ -5112,10 +5112,6 @@ msgstr "Si coché, cette liste de lecture sera visible aux autres utilisateurs."
msgid "Playlist"
msgstr "Liste de lecture"
-#: pod/playlist/models.py
-msgid "Playlists"
-msgstr "Listes de lecture"
-
#: pod/playlist/models.py
msgid "Position of the video in a playlist."
msgstr "Position de la vidéo dans la liste de lecture."
@@ -5151,8 +5147,8 @@ msgstr "Aucune liste de lecture trouvée"
#: pod/playlist/templates/my_playlists.html
msgid ""
-"You have not created any playlists yet, please use the \"Add a new playlist"
-"\" button to add one."
+"You have not created any playlists yet, please use the \"Add a new "
+"playlist\" button to add one."
msgstr ""
"Vous n’avez pas encore créé de liste de lecture, veuillez cliquer sur le "
"bouton « Ajouter une nouvelle liste de lecture » pour en ajouter une."
@@ -5304,6 +5300,10 @@ msgstr "La vidéo a été ajoutée à votre liste de lecture."
msgid "This playlist has been deleted."
msgstr "Cette liste de lecture a été supprimée."
+#: pod/podfile/apps.py
+msgid "Pod files"
+msgstr "Fichiers Pod"
+
#: pod/podfile/forms.py pod/video/forms.py
#, python-format
msgid ""
@@ -5497,6 +5497,10 @@ msgstr ""
"Supprimer les traitements de fichiers d’enregistrement sélectionnés + les "
"fichiers source"
+#: pod/recorder/apps.py pod/recorder/models.py
+msgid "Recorders"
+msgstr "Enregistreurs"
+
#: pod/recorder/forms.py
msgid "source_file"
msgstr "fichier source"
@@ -5677,10 +5681,6 @@ msgstr "Répertoire de base des vidéos publiées par l’enregistreur."
msgid "Recorder"
msgstr "Enregistreur"
-#: pod/recorder/models.py
-msgid "Recorders"
-msgstr "Enregistreurs"
-
#: pod/recorder/models.py
msgid "Recorder that made this recording."
msgstr "Enregistreur qui a fait cet enregistrement."
@@ -5772,8 +5772,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 a new recording has just be added on %(title_site)s from the "
-"recorder \"%(recorder)s\". To add it, just click on link below.
%(link_url)s if you cannot click on link, "
+"recorder \"%(recorder)s\". To add it, just click on link below.
%(link_url)s if you cannot click on link, "
"just copy-paste it in your browser.
Regards
"
msgstr ""
"Bonjour,
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
"
+"%(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."
+"i>
Cordialement
"
#: pod/recorder/views.py
msgid "New recording added."
@@ -5884,6 +5885,11 @@ msgstr "Définir comme brouillon"
msgid "Transcript selected"
msgstr "Transcription selectionnée"
+#: pod/video/apps.py pod/video/models.py pod/video/templates/videos/video.html
+#: pod/video/templates/videos/videos.html
+msgid "Videos"
+msgstr "Vidéos"
+
#: pod/video/forms.py
msgid "File field"
msgstr "Fichier"
@@ -6164,10 +6170,10 @@ msgstr ""
#: pod/video/management/commands/check_obsolete_videos.py
#, python-format
msgid ""
-"It will be deleted on %(date_delete)s. \n"
+"It will be deleted on %(date_delete)s. \n"
"If you want to keep it, "
msgstr ""
-"Elle sera supprimée le %(date_delete)s. \n"
+"Elle sera supprimée le %(date_delete)s. \n"
"Si vous souhaitez la conserver, "
#: pod/video/management/commands/check_obsolete_videos.py
@@ -6388,7 +6394,7 @@ msgstr ""
"Vous pouvez ajouter des propriétaires additionnels à la vidéo. Ils auront "
"les mêmes droits que vous sauf qu’ils ne peuvent pas supprimer cette vidéo."
-#: pod/video/models.py
+#: pod/video/models.py pod/video/templates/videos/video_sort_select.html
msgid "Date of event"
msgstr "Date de l'évènement"
@@ -6609,11 +6615,6 @@ msgstr "Commentaires de notes"
msgid "Date for deletion"
msgstr "Date pour la suppression"
-#: pod/video/models.py pod/video/templates/videos/video.html
-#: pod/video/templates/videos/videos.html
-msgid "Videos"
-msgstr "Vidéos"
-
#: pod/video/models.py
msgid "Video to delete"
msgstr "Vidéo à supprimer"
@@ -7011,8 +7012,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"
@@ -7166,11 +7167,11 @@ msgstr "Document :"
#: pod/video/templates/videos/video-info.html
msgid ""
-"Please note that your video is in draft mode. \n"
+"Please note that your video is in draft mode. \n"
"The following links contain a key allowing access.\n"
"Anyone with this links can access it."
msgstr ""
-"Veuillez noter que votre vidéo est en mode brouillon. \n"
+"Veuillez noter que votre vidéo est en mode brouillon. \n"
"Les liens suivants contiennent une clé permettant l’accès.\n"
"Toute personne disposant de ces liens peut y accéder."
@@ -7398,6 +7399,22 @@ msgstr "Télécharger les notes"
msgid "New note"
msgstr "Nouvelle note"
+#: pod/video/templates/videos/video_sort_select.html
+msgid "Sort"
+msgstr "Tri"
+
+#: pod/video/templates/videos/video_sort_select.html
+msgid "Ascending sort"
+msgstr "Tri ascendant"
+
+#: pod/video/templates/videos/video_sort_select.html
+msgid "Descending sort"
+msgstr "Tri descendant"
+
+#: pod/video/templates/videos/video_sort_select.html
+msgid "Sort Direction"
+msgstr "Direction de tri"
+
#: pod/video/templates/videos/video_stats_view.html
msgid "Change the date"
msgstr "Modifier la période de visualisation"
@@ -7699,6 +7716,10 @@ msgstr "Vous n’avez pas les droits pour supprimer cette catégorie"
msgid "Update successfully"
msgstr "Mise à jour réussie"
+#: pod/video_search/apps.py
+msgid "Video search"
+msgstr "Recherche de vidéo"
+
#: pod/video_search/templates/search/search.html
msgid "Active filters (click to unfilter):"
msgstr "Filtres actifs (cliquer pour en retirer) :"
@@ -7719,6 +7740,10 @@ msgstr "Désolé, la recherche de vidéos est limitée à 500 pages maximum."
msgid "Search results"
msgstr "Résultats de la recherche"
+#: pod/xapi/apps.py
+msgid "Esup-Pod xAPI"
+msgstr "Esup-Pod xAPI"
+
#~ msgid "The video file for this recording was notfound in the HTML file."
#~ msgstr ""
#~ "Le fichier vidéo de cet enregistrement est introuvable dans le fichier "
diff --git a/pod/locale/fr/LC_MESSAGES/djangojs.mo b/pod/locale/fr/LC_MESSAGES/djangojs.mo
index fd074a66f37b9b9fb042301e4e18154539777f2d..0e5e8e55637e87484c540b1bfb9468a9d2b3f1fd 100644
GIT binary patch
delta 4619
zcmaLZ32aoy9mnxmz{Y?vmu(J1{Wt>VT4TZ)E@R47!ey>PDP`?_m~Ga(X1!};AX#%K
zKncx4xX-qL328`|0BMw>;3NgA5LE?hI?@-9>QGw4o6{bTVtAH
zDQ4q*t&GXP7lFNU!T?!|OGi_P&39Egor
zg#SV>_H6H5FU5Ye>rwr^pFljY@r!j*dmB%q&IyZXGI<$59Wwg0t}sY63$#k$=s6G2dz?L2QZ7
z;Bb5nOYtr2h1s2*r5K4^G7C@{szMELEf(S-w|xy6qxl3`e$#{vRfIXH{w8-J|61E1
z7aqecsP-9Dhu6@;Pf(jQGtU|M7|f?_qc-D4WED&jm66M+419$eXdaz01~bHU2CDz%
zaXz(n8&PY&6V=gv)DoOQZI-uDGrfu$$OounnaOBdV>{G?@=;4O0yUxWsNYqfHfPYa
z&b=PrL`7@975n2+)UkOFbqv2jElIEMIRhy~Jzyy60b@~{%a7V@Rj8TocfY@gTFQ@6
z1Mf!KNe?)iT-a
zJpH~9HK3`e%vPcXybjZJ{
zU)=ULsQa?W|0o=Y(=mX>cpk^$zi}*%V3x{gEoR`}zT{ssJH~}4@U-jSa2V|#YzXa*
zg{Tz1;CdO=;eFKZAH&Yo5=}!5co8Uk>W~KFCYY6ruW=iW=~b<5ZN2
zAgbdSYQ#rS9h}4Qco~~wORtlWEX<@m8MW!=q9(E%XX9@%fSJ4wEv!Mk8F%xs5`T}{
zgz;j|m{PwAHPY8mDY}U2IIYO(U<&Fu1yCtokG$N>Q7pqZQA=d8#g)1FnEE|xcE%
z+=n{OpCJQ|o517F1Gb@d_sghMT}Q3ar&x@cL!47G9ocuL7WMnXs7>}Rk|dMPDEi_M
z)TUg5TH1Z6&G$Rh{U72Oo&OAWnl{rU*5#m5B&y
zpgWM|H)k*hZ=v?m7uW&sq3&V_+*J@O}1
z$M>-vrn8XxeJ9lYg=pa@RAv_Acszj0$Zc$mU0CWfP4T-1PQLqSyafYx7rT-Vii^Oqa2XT&2sV8(2&J(AICB!O1Ma!W9
zlX3Gjq2)SBFn%4wxS2~uDK95V2^DR!?L-;zJh7H|nc#@0(wW4c5-QqAD!C4+Pi0PJ
zGO?4WRfEEjPaRFwmHucdPgJUjFtLwd52jARc$`C=AXG*Y&kz@g?u5!R2Qv#-5ZW8R
zA@m-3v@D?U+#?qf)VB~lv`&2qKk+N#2+^LHMC>M>CDsrsT5lbr9}qtxDv3_SR$@M(
zqq>LSkUT8&+}dn>+^y&1N@5zJ=bKmcLHQ-IH&t_Xy<1Ifyoofr5EaBI;%CHS;?bgi
z$T||QxfcuZ7}1m%?p}MqQYx$Ud>@q=gm%5kFo)DXN`tANB@Poh_x*^Ogvt*c%pqLv
z)~CAm$0@`JVmeVn93a*cD*K5LQLOpDq$`xuM0Tpizss(oty@2ezjo`Qj%Xly5AUoI}}asYE#%Oqudv@E5ebwT2u0)9JeEsKOJAKvJ6<9zY|`baG6**5WMc0*II*PDDk
zXG2={tZ;Q88VHB1YF~}*H>GxExF%7YH!!m*SVxObD;iFeB?$673EUu
zocs$jM8vQY~n
zXn8C`Nud<56hsT{Rx2%nqa8t*(ORE4ildIUQ!S2FT8kF?{oOrO@9^8txp(iLd+z_7
zd&7>^fv-9P;WO!Rj~d${l0&w~n|-c!Pd?b*PBx3f(>MpuUj(1BpW6U;2nvX1;hK#{luse1l#kGf!E^IxfaDCfNLmmDWxj8$mFYqL4VDI2y{1DY)
zQs3Ae<)H4o2sH&WQ5Bet8rT{vz|E)uJ&Tv&n@Cso8HT6O&{55O9qP^(p-Q{Kc?@;u
zXWjRyOsFa~9M$o3oQg|O1AQKK1Aj*i_&g?IuS~OY%*1-E%cTBS(AdoZmHIfU!;evw
zxPTg13I~T^F=~Gn(x)v)m2v|P#XYG0-az$t9tUDpc5Htv`oBkyo#
z)EWtYLPLw@pQt;_rEWT*8q2X6HPW5VKcmNfATRbD4?z9?77XHQ)cOCxd$5plszQ5l
zB0h)Xv4`g`&al`|A0BiAD_v&Y((`&(da)HW{zRg*Xg%;V66^wN{cDoz5SD>TnKf
zAR+95>z&(B1KopK6DQsAzhD;Ew|8mi&dxalEMaxf8#U*dm>ytdV;uYC%+DOGK&osz
za3&r>T_A(2=}z-dPsuR1KM8gIY#f6f7_O!942>#G;I^*82{;xXM2ccBqDuQW)WE*L
z(fEyXL;+P`|1KPf`%snpz?n&z)L$)Xkw1)@nyxFUzvg~F2NLl(s+6ywR`bU=9@AK1
znv&^A_3dt?Sk{I5-BHwg;6>C6=QOGUpCbS4qT4T|(;n=P#RQyKME$k6>Nubu-tJBa
zp*rY9jdU}1$33VHpFj=tE!6M+fz@~syJ0oYpeivQHH9m&2G^l(;AQmii!cqn+0uF2
zEW;YqBKsq%#OF{IC@YP15JHdr!>Fg^9aIIsLS7A)PG@tm6g34KQ3E`VI{!3kO?-*<
z7*670)pI%~IF9mwq1v&b^AzoO1h;Ze~V8i9=6La6f|
zLoK?OQB#+6mA|&aR!T!1+<=w147FIEMi#uCLw;lZhR5!p7WI8I>T%nP8u&3(B|bzA
zRJTuY&BG+DMQ++=U>{tAS$h7r)6iT!g+1{sszm28AJbUcS~ORo=Drfsa6V?>3e@j5
zqK7+B6*!93cmZ|iRlH7nV+U&St;Ia9ZyRZ-gG0zP+7Z-+K1CjB%V2a`6BT$PhLEDz
zNz@%)Kvk%SlXU!6d=xjKzAs=Q9mZ*>DM?{84Oofc=`=ReV7l!yWC2@lMXc15kUtAH
z4>h1pROt?&27C+t~U
zPQFHsxR?p2PrDhba4TMmZ=)`dL%roB^e}{4j9XDtcNDb-PM|9F8tT1~P!*0npUG9R
zk@v@5d{K@X={VG!-Gmz8Tnu0?@kle-L@sTbzF(3$cR+n;AY8^4xno@0f3&sx1ATFj
z{FF=}>xrKChsY|T?HQbVQ?tr1<{
zU;Pi_{Y2|PTWbve*}aMOPPhMk_ONq^)VqU^VUBA*fSSU^_n
z{ZD5jyIaWuqNidtX(HORc(ko0Gs%5Ke-CQOb~1@*yCR0ahSc0bwBYo(@m}(`WM>Ob
z_3Q5ri2Y<236XU~k5dNu8PRri4BP9>$AM%i89}Cz4de-OJ=sRI@u2vxU4Ms<1oCqd
z&f;SqnMcNuUlBd4vq&4cmW(6w$&EzYtug#RSn0GMCkIFexr2Ovt9Cm*v64(AzaUFU
zw(9>A8kdtxTb^qqI%i-b*-Q#Z30Y2VBif3{3cnS5M|8Qih>$1AC=w*skwRkLgql(t
z*ydG4UK`XL>5)1$+L~Gz7k#pCb|7+H#xv2x%$4ya^-XsKo7(1^(_7x!9`u$pHaB@~
zt=jSCHMV%crp92fv86e(EvF>%Ue3djmfYjfv3W-lqbY+P4@BP@+#DZmC|MYY465lD
z-8v*M5It75FA$wStUZ2Y^}MC+jf)nvH3jYe%@tm#b!o6EcAX{u6\n"
"Language-Team: \n"
"Language: fr\n"
"MIME-Version: 1.0\n"
@@ -26,12 +26,12 @@ msgid "Close"
msgstr "Fermer"
#: pod/chapter/static/js/chapters.js pod/completion/static/js/completion.js
-#: pod/enrichment/static/js/enrichment.js
+#: pod/enrichment/static/js/enrichment.js pod/playlist/static/js/playlist.js
msgid "Error getting form."
msgstr "Erreur lors de la récupération du formulaire."
#: pod/chapter/static/js/chapters.js pod/completion/static/js/completion.js
-#: pod/enrichment/static/js/enrichment.js
+#: pod/enrichment/static/js/enrichment.js pod/playlist/static/js/playlist.js
msgid "The form could not be recovered."
msgstr "Le formulaire ne peut pas être récupéré."
@@ -63,7 +63,7 @@ msgstr ""
#: pod/chapter/static/js/chapters.js
msgid "Invalid action."
-msgstr "Action non valide"
+msgstr "Action non valide."
#: pod/chapter/static/js/chapters.js pod/enrichment/static/js/enrichment.js
msgid "Please enter a title from 2 to 100 characters."
@@ -176,6 +176,16 @@ 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"
@@ -374,14 +384,6 @@ msgstr "Ouvrir le gestionnaire de diapositives"
msgid "Enrich mode"
msgstr "Mode enrichi"
-#: pod/favorite/static/js/favorite-reorganize.js
-msgid "Refresh your page so you can rearrange"
-msgstr "Actualisez votre page pour pouvoir réorganiser"
-
-#: pod/favorite/static/js/favorite-reorganize.js
-msgid "Refresh"
-msgstr "Actualiser"
-
#: pod/favorite/static/js/favorite-reorganize.js
msgid "Save your reorganization"
msgstr "Sauvegarder votre réorganisation"
@@ -484,6 +486,21 @@ msgstr ""
"Cette extension de fichier n’est pas présente dans les extensions "
"autorisées :"
+#: pod/playlist/static/js/playlist.js
+msgid "Position saved"
+msgstr "Position enregistrée"
+
+#: pod/playlist/static/js/playlist.js
+msgid "Error deleting video from playlist. The video could not be deleted."
+msgstr ""
+"Erreur lors de la suppression de la vidéo de la liste de lecture. La vidéo "
+"n’a pas pu être retirée."
+
+#: pod/playlist/static/js/playlist.js
+msgid "Error deleting playlist. The playlist could not be deleted."
+msgstr ""
+"Erreur lors de la suppression. La liste de lecture n’a pas pu être supprimée."
+
#: pod/playlist/static/js/playlist.js
msgid "The video can not be added from this page."
msgstr "La vidéo ne peut être ajoutée depuis cette page."
@@ -521,12 +538,12 @@ msgid "Enter new name of folder"
msgstr "Indiquer un nouveau nom au dossier"
#: pod/podfile/static/podfile/js/filewidget.js
-msgid "Server error"
-msgstr "Erreur du serveur"
+msgid "Remove"
+msgstr "Retirer"
#: pod/podfile/static/podfile/js/filewidget.js
-msgid "Add"
-msgstr "Ajouter"
+msgid "Server error"
+msgstr "Erreur du serveur"
#: pod/podfile/static/podfile/js/filewidget.js
msgid "Are you sure you want to delete this folder?"
@@ -564,22 +581,41 @@ msgstr "Réponse"
msgid "Answers"
msgstr "Réponses"
-#: pod/video/static/js/comment-script.js
-msgid "Delete"
-msgstr "Supprimer"
-
#: pod/video/static/js/comment-script.js
msgid "Cancel"
msgstr "Annuler"
+#: 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 "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"
@@ -592,13 +628,6 @@ 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."
@@ -631,38 +660,47 @@ msgid "An Error occurred while processing."
msgstr "Une erreur est survenue durant l’exécution du processus."
#: 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"
@@ -719,6 +757,18 @@ 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"
@@ -775,42 +825,8 @@ msgstr "Ajouts en favoris total depuis la création"
msgid "Slug"
msgstr "Titre court"
-#~ msgid "Position saved"
-#~ msgstr "Position enregistrée"
-
-#~ msgid "Error deleting video from playlist. The video could not be deleted."
-#~ msgstr ""
-#~ "Erreur lors de la suppression de la vidéo de la liste de lecture. La "
-#~ "vidéo n’a pas pu être retirée."
-
-#~ msgid "Error deleting playlist. The playlist could not be deleted."
-#~ msgstr ""
-#~ "Erreur lors de la suppression. La liste de lecture n’a pas pu être "
-#~ "supprimée."
-
-#~ msgid "Remove"
-#~ msgstr "Retirer"
-
-#~ 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 "Refresh"
+#~ msgstr "Actualiser"
#~ msgid "Video add to playlist"
#~ msgstr "Ajouter une vidéo à une playlist"
diff --git a/pod/locale/nl/LC_MESSAGES/django.po b/pod/locale/nl/LC_MESSAGES/django.po
index 31ff44fe99..86aa423bd7 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-05-16 14:51+0000\n"
+"POT-Creation-Date: 2023-05-24 16:19+0000\n"
"PO-Revision-Date: 2023-02-15 16:55+0100\n"
"Last-Translator: obado \n"
"Language-Team: \n"
@@ -24,6 +24,10 @@ msgstr "E-mail"
msgid "Establishment"
msgstr ""
+#: pod/authentication/apps.py pod/authentication/views.py
+msgid "Authentication"
+msgstr ""
+
#: pod/authentication/forms.py pod/main/templates/navbar.html
#: pod/main/templates/navbar_collapse.html pod/podfile/models.py
#: pod/video/forms.py pod/video/models.py
@@ -249,10 +253,6 @@ msgstr ""
msgid "Save changes"
msgstr ""
-#: pod/authentication/views.py
-msgid "Authentication"
-msgstr ""
-
#: pod/bbb/admin.py pod/video/admin.py
msgid "Encode selected"
msgstr ""
@@ -368,7 +368,7 @@ msgstr ""
msgid "Meeting"
msgstr ""
-#: pod/bbb/models.py
+#: pod/bbb/models.py pod/meeting/apps.py
msgid "Meetings"
msgstr ""
@@ -751,6 +751,12 @@ msgstr ""
msgid "The BigBlueButton live has been performed."
msgstr ""
+#: pod/chapter/apps.py pod/chapter/models.py
+#: pod/chapter/templates/video_chapter.html
+#: pod/video/templates/videos/video-element.html
+msgid "Chapters"
+msgstr ""
+
#: pod/chapter/forms.py
msgid "File to import"
msgstr ""
@@ -789,11 +795,6 @@ msgstr ""
msgid "Chapter"
msgstr ""
-#: pod/chapter/models.py pod/chapter/templates/video_chapter.html
-#: pod/video/templates/videos/video-element.html
-msgid "Chapters"
-msgstr ""
-
#: pod/chapter/models.py pod/completion/models.py pod/enrichment/models.py
msgid "Please enter a title from 2 to 100 characters."
msgstr ""
@@ -869,10 +870,8 @@ msgstr ""
#: pod/chapter/templates/chapter/list_chapter.html pod/completion/models.py
#: pod/completion/templates/overlay/list_overlay.html
-#: pod/enrichment/templates/enrichment/list_enrichment.html
-#: pod/favorite/templates/favorite/favorite_video_sort_select.html
-#: pod/live/models.py pod/main/models.py pod/main/views.py
-#: pod/playlist/models.py
+#: pod/enrichment/templates/enrichment/list_enrichment.html pod/live/models.py
+#: pod/main/models.py pod/main/views.py pod/playlist/models.py
#: pod/playlist/templates/playlist/playlist_element_list.html
#: pod/video/models.py pod/video/templates/channel/list_theme.html
#: pod/video/templates/videos/video_sort_select.html
@@ -1005,6 +1004,11 @@ msgstr ""
msgid "Enrich with selected subtitles"
msgstr ""
+#: pod/completion/apps.py pod/completion/templates/video_completion.html
+#: pod/completion/views.py
+msgid "Video additions"
+msgstr ""
+
#: pod/completion/models.py
msgid "actor"
msgstr ""
@@ -1544,10 +1548,6 @@ msgstr ""
msgid "Override"
msgstr ""
-#: pod/completion/templates/video_completion.html
-msgid "Complements of the video"
-msgstr ""
-
#: pod/completion/templates/video_completion.html
msgid "Completion video"
msgstr ""
@@ -1690,20 +1690,16 @@ msgstr ""
msgid "The file has not been saved."
msgstr ""
-#: pod/completion/views.py
-msgid "Video additions"
-msgstr ""
-
#: pod/completion/views.py pod/podfile/views.py pod/video/views.py
msgid "Please correct errors"
msgstr ""
-#: pod/cut/models.py
-msgid "Video cut"
+#: pod/cut/apps.py pod/cut/models.py
+msgid "Video cuts"
msgstr ""
#: pod/cut/models.py
-msgid "Video cuts"
+msgid "Video cut"
msgstr ""
#: pod/cut/models.py pod/cut/views.py
@@ -1762,7 +1758,7 @@ msgstr ""
#: pod/cut/templates/video_cut.html
msgid ""
"Your original video is kept and you can therefore modify your changes at any "
-"time"
+"time."
msgstr ""
#: pod/cut/templates/video_cut.html
@@ -1777,6 +1773,10 @@ msgstr ""
msgid "The cut was made."
msgstr ""
+#: pod/enrichment/apps.py pod/enrichment/models.py
+msgid "Enrichments"
+msgstr ""
+
#: pod/enrichment/apps.py
msgid "Enrichment version"
msgstr ""
@@ -1867,10 +1867,6 @@ msgstr ""
msgid "Paste here a code from an external source to embed it."
msgstr ""
-#: pod/enrichment/models.py
-msgid "Enrichments"
-msgstr ""
-
#: pod/enrichment/models.py
#, python-brace-format
msgid "Please enter a correct {0}."
@@ -2035,24 +2031,21 @@ msgstr ""
msgid "You cannot enrich this video."
msgstr ""
-#: pod/favorite/models.py
-#: pod/favorite/templates/favorite/favorite_video_sort_select.html
-#: pod/recorder/models.py pod/video/models.py
+#: pod/favorite/apps.py pod/favorite/models.py
+msgid "Favorite videos"
+msgstr ""
+
+#: pod/favorite/models.py pod/recorder/models.py pod/video/models.py
#: pod/video/templates/videos/video_sort_select.html
msgid "Date added"
msgstr ""
-#: pod/favorite/models.py
-#: pod/favorite/templates/favorite/favorite_video_sort_select.html
+#: pod/favorite/models.py pod/video/templates/videos/video_sort_select.html
msgid "Rank"
msgstr ""
#: pod/favorite/models.py
-msgid "Favorite"
-msgstr ""
-
-#: pod/favorite/models.py
-msgid "Favorites"
+msgid "Favorite video"
msgstr ""
#: pod/favorite/templates/favorite/favorite_video_list.html
@@ -2060,29 +2053,6 @@ msgstr ""
msgid "Sorry, no video found."
msgstr ""
-#: pod/favorite/templates/favorite/favorite_video_sort_select.html
-#: pod/video/templates/videos/video_sort_select.html
-msgid "Sort"
-msgstr ""
-
-#: pod/favorite/templates/favorite/favorite_video_sort_select.html
-#: pod/video/templates/videos/video_sort_select.html
-msgid "Descending sort"
-msgstr ""
-
-#: pod/favorite/templates/favorite/favorite_video_sort_select.html
-#: pod/video/templates/videos/video_sort_select.html
-msgid "Sort Direction"
-msgstr ""
-
-#: pod/favorite/templates/favorite/favorite_video_sort_select.html
-#: pod/meeting/forms.py pod/meeting/templates/meeting/recordings.html
-#: pod/playlist/templates/playlist/playlist_element_list.html
-#: pod/video/feeds.py pod/video/models.py
-#: pod/video/templates/videos/video_sort_select.html
-msgid "Duration"
-msgstr ""
-
#: pod/favorite/templates/favorite/favorite_videos.html
#: pod/video/templates/channel/channel.html
#: pod/video/templates/videos/my_videos.html
@@ -2095,7 +2065,8 @@ msgstr[0] ""
msgstr[1] ""
#: pod/favorite/templates/favorite/favorite_videos.html
-#: pod/favorite/tests/test_views.py pod/main/templates/navbar.html
+#: pod/favorite/tests/test_views.py pod/favorite/views.py
+#: pod/main/templates/navbar.html
msgid "My favorite videos"
msgstr ""
@@ -2107,6 +2078,14 @@ msgstr ""
msgid "Reorganize"
msgstr ""
+#: pod/favorite/templates/favorite/favorite_videos.html
+msgid "Sort by descending rank before you can rearrange"
+msgstr ""
+
+#: pod/favorite/templates/favorite/favorite_videos.html
+msgid "Sort by descending rank"
+msgstr ""
+
#: pod/favorite/templates/favorite/favorite_videos.html
msgid "Help - Drag & Drop"
msgstr ""
@@ -2157,6 +2136,12 @@ msgstr ""
msgid "Thumbnails"
msgstr ""
+#: pod/live/apps.py pod/live/templates/live/direct.html
+#: pod/live/templates/live/directs.html
+#: pod/live/templates/live/directs_all.html pod/main/templates/navbar.html
+msgid "Lives"
+msgstr ""
+
#: pod/live/forms.py pod/live/models.py
msgid "Piloting implementation"
msgstr ""
@@ -2490,11 +2475,6 @@ msgstr ""
msgid "Submit"
msgstr ""
-#: pod/live/templates/live/direct.html pod/live/templates/live/directs.html
-#: pod/live/templates/live/directs_all.html pod/main/templates/navbar.html
-msgid "Lives"
-msgstr ""
-
#: pod/live/templates/live/direct.html
msgid "Live"
msgstr ""
@@ -2644,6 +2624,7 @@ msgstr ""
#: pod/live/templates/live/event-info.html
#: pod/video/templates/videos/video-info.html
+#: pod/video/templates/videos/video.html
msgid "Added by:"
msgstr ""
@@ -2660,8 +2641,8 @@ msgstr ""
#: pod/live/templates/live/event-info.html
msgid ""
-"Please note that your event is in draft mode. The following links "
-"contain a key allowing access. Anyone with this links can access it."
+"Please note that your event is in draft mode. The following links contain "
+"a key allowing access. Anyone with this links can access it."
msgstr ""
#: pod/live/templates/live/event-info.html
@@ -2999,6 +2980,10 @@ msgstr ""
msgid "on %(start_date)s from %(start_time)s to %(end_time)s"
msgstr ""
+#: pod/lti/apps.py
+msgid "LTI provider"
+msgstr ""
+
#: pod/lti/templates/lti_provider/assignment.html
msgid "Your browser does not support iframes."
msgstr ""
@@ -3015,6 +3000,10 @@ msgstr ""
msgid "Advanced options"
msgstr ""
+#: pod/main/apps.py
+msgid "Main configurations"
+msgstr ""
+
#: pod/main/forms.py
msgid "Request more information"
msgstr ""
@@ -4049,6 +4038,13 @@ msgstr ""
msgid "Recurring"
msgstr ""
+#: pod/meeting/forms.py
+#: pod/playlist/templates/playlist/playlist_element_list.html
+#: pod/video/feeds.py pod/video/models.py
+#: pod/video/templates/videos/video_sort_select.html
+msgid "Duration"
+msgstr ""
+
#: pod/meeting/forms.py
#, python-format
msgid "Specify a duration in hour between 1 and %(max_duration)s hours"
@@ -4841,6 +4837,10 @@ msgid ""
"videos."
msgstr ""
+#: pod/playlist/apps.py pod/playlist/models.py
+msgid "Playlists"
+msgstr ""
+
#: pod/playlist/models.py
msgid "Short description of the playlist."
msgstr ""
@@ -4859,10 +4859,6 @@ msgstr ""
msgid "Playlist"
msgstr ""
-#: pod/playlist/models.py
-msgid "Playlists"
-msgstr ""
-
#: pod/playlist/models.py
msgid "Position of the video in a playlist."
msgstr ""
@@ -4896,8 +4892,8 @@ msgstr ""
#: pod/playlist/templates/my_playlists.html
msgid ""
-"You have not created any playlists yet, please use the \"Add a new playlist"
-"\" button to add one."
+"You have not created any playlists yet, please use the \"Add a new "
+"playlist\" button to add one."
msgstr ""
#: pod/playlist/templates/my_playlists.html
@@ -5043,6 +5039,10 @@ msgstr ""
msgid "This playlist has been deleted."
msgstr ""
+#: pod/podfile/apps.py
+msgid "Pod files"
+msgstr ""
+
#: pod/podfile/forms.py pod/video/forms.py
#, python-format
msgid ""
@@ -5230,6 +5230,10 @@ msgstr ""
msgid "Delete selected Recording file treatments + source files"
msgstr ""
+#: pod/recorder/apps.py pod/recorder/models.py
+msgid "Recorders"
+msgstr ""
+
#: pod/recorder/forms.py
msgid "source_file"
msgstr ""
@@ -5390,10 +5394,6 @@ msgstr ""
msgid "Recorder"
msgstr ""
-#: pod/recorder/models.py
-msgid "Recorders"
-msgstr ""
-
#: pod/recorder/models.py
msgid "Recorder that made this recording."
msgstr ""
@@ -5482,8 +5482,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
@@ -5551,8 +5551,8 @@ msgstr ""
#, python-format
msgid ""
"Hello,
a new recording has just be added on %(title_site)s from the "
-"recorder \"%(recorder)s\". To add it, just click on link below.
%(link_url)s if you cannot click on link, "
+"recorder \"%(recorder)s\". To add it, just click on link below.%(link_url)s if you cannot click on link, "
"just copy-paste it in your browser.
Regards
"
msgstr ""
@@ -5584,6 +5584,11 @@ msgstr ""
msgid "Transcript selected"
msgstr ""
+#: pod/video/apps.py pod/video/models.py pod/video/templates/videos/video.html
+#: pod/video/templates/videos/videos.html
+msgid "Videos"
+msgstr ""
+
#: pod/video/forms.py
msgid "File field"
msgstr ""
@@ -5814,7 +5819,7 @@ msgstr ""
#: pod/video/management/commands/check_obsolete_videos.py
#, python-format
msgid ""
-"It will be deleted on %(date_delete)s. \n"
+"It will be deleted on %(date_delete)s. \n"
"If you want to keep it, "
msgstr ""
@@ -6008,7 +6013,7 @@ msgid ""
"as you except that they can't delete this video."
msgstr ""
-#: pod/video/models.py
+#: pod/video/models.py pod/video/templates/videos/video_sort_select.html
msgid "Date of event"
msgstr ""
@@ -6225,11 +6230,6 @@ msgstr ""
msgid "Date for deletion"
msgstr ""
-#: pod/video/models.py pod/video/templates/videos/video.html
-#: pod/video/templates/videos/videos.html
-msgid "Videos"
-msgstr ""
-
#: pod/video/models.py
msgid "Video to delete"
msgstr ""
@@ -6751,7 +6751,7 @@ msgstr ""
#: pod/video/templates/videos/video-info.html
msgid ""
-"Please note that your video is in draft mode. \n"
+"Please note that your video is in draft mode. \n"
"The following links contain a key allowing access.\n"
"Anyone with this links can access it."
msgstr ""
@@ -6972,6 +6972,22 @@ msgstr ""
msgid "New note"
msgstr ""
+#: pod/video/templates/videos/video_sort_select.html
+msgid "Sort"
+msgstr ""
+
+#: pod/video/templates/videos/video_sort_select.html
+msgid "Ascending sort"
+msgstr ""
+
+#: pod/video/templates/videos/video_sort_select.html
+msgid "Descending sort"
+msgstr ""
+
+#: pod/video/templates/videos/video_sort_select.html
+msgid "Sort Direction"
+msgstr ""
+
#: pod/video/templates/videos/video_stats_view.html
msgid "Change the date"
msgstr ""
@@ -7259,6 +7275,10 @@ msgstr ""
msgid "Update successfully"
msgstr ""
+#: pod/video_search/apps.py
+msgid "Video search"
+msgstr ""
+
#: pod/video_search/templates/search/search.html
msgid "Active filters (click to unfilter):"
msgstr ""
@@ -7278,3 +7298,7 @@ msgstr ""
#: pod/video_search/views.py
msgid "Search results"
msgstr ""
+
+#: pod/xapi/apps.py
+msgid "Esup-Pod xAPI"
+msgstr ""
diff --git a/pod/locale/nl/LC_MESSAGES/djangojs.po b/pod/locale/nl/LC_MESSAGES/djangojs.po
index eebfc35055..c8a53f8619 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-05-16 14:51+0000\n"
+"POT-Creation-Date: 2023-05-24 16:20+0000\n"
"PO-Revision-Date: 2023-02-08 15:22+0100\n"
"Last-Translator: obado \n"
"Language-Team: \n"
@@ -26,12 +26,12 @@ msgid "Close"
msgstr ""
#: pod/chapter/static/js/chapters.js pod/completion/static/js/completion.js
-#: pod/enrichment/static/js/enrichment.js
+#: pod/enrichment/static/js/enrichment.js pod/playlist/static/js/playlist.js
msgid "Error getting form."
msgstr ""
#: pod/chapter/static/js/chapters.js pod/completion/static/js/completion.js
-#: pod/enrichment/static/js/enrichment.js
+#: pod/enrichment/static/js/enrichment.js pod/playlist/static/js/playlist.js
msgid "The form could not be recovered."
msgstr ""
@@ -161,6 +161,16 @@ 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 ""
@@ -355,14 +365,6 @@ msgstr ""
msgid "Enrich mode"
msgstr ""
-#: pod/favorite/static/js/favorite-reorganize.js
-msgid "Refresh your page so you can rearrange"
-msgstr ""
-
-#: pod/favorite/static/js/favorite-reorganize.js
-msgid "Refresh"
-msgstr ""
-
#: pod/favorite/static/js/favorite-reorganize.js
msgid "Save your reorganization"
msgstr ""
@@ -461,6 +463,18 @@ msgstr ""
msgid "The file extension not in the allowed extension:"
msgstr ""
+#: pod/playlist/static/js/playlist.js
+msgid "Position saved"
+msgstr ""
+
+#: pod/playlist/static/js/playlist.js
+msgid "Error deleting video from playlist. The video could not be deleted."
+msgstr ""
+
+#: pod/playlist/static/js/playlist.js
+msgid "Error deleting playlist. The playlist could not be deleted."
+msgstr ""
+
#: pod/playlist/static/js/playlist.js
msgid "The video can not be added from this page."
msgstr ""
@@ -496,11 +510,11 @@ msgid "Enter new name of folder"
msgstr ""
#: pod/podfile/static/podfile/js/filewidget.js
-msgid "Server error"
+msgid "Remove"
msgstr ""
#: pod/podfile/static/podfile/js/filewidget.js
-msgid "Add"
+msgid "Server error"
msgstr ""
#: pod/podfile/static/podfile/js/filewidget.js
@@ -540,21 +554,40 @@ msgid "Answers"
msgstr ""
#: pod/video/static/js/comment-script.js
-msgid "Delete"
+msgid "Cancel"
msgstr ""
#: pod/video/static/js/comment-script.js
-msgid "Cancel"
-msgstr ""
+#, 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"
msgstr ""
+#: pod/video/static/js/comment-script.js
+msgid "Reply to comment"
+msgstr ""
+
+#: pod/video/static/js/comment-script.js
+msgid "Reply"
+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 ""
@@ -567,13 +600,6 @@ 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 ""
@@ -606,38 +632,47 @@ msgid "An Error occurred while processing."
msgstr ""
#: 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 ""
@@ -693,6 +728,18 @@ 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/lti/apps.py b/pod/lti/apps.py
index ee1df9e76f..53e8c66bbf 100644
--- a/pod/lti/apps.py
+++ b/pod/lti/apps.py
@@ -1,6 +1,8 @@
from django.apps import AppConfig
+from django.utils.translation import gettext_lazy as _
class LtiConfig(AppConfig):
name = "pod.lti"
default_auto_field = "django.db.models.BigAutoField"
+ verbose_name = _("LTI provider")
diff --git a/pod/main/apps.py b/pod/main/apps.py
index bdd4b9c030..a2c6d7a3db 100644
--- a/pod/main/apps.py
+++ b/pod/main/apps.py
@@ -1,5 +1,7 @@
from django.apps import AppConfig
from django.db.models.signals import post_migrate
+from django.utils.translation import gettext_lazy as _
+
import json
@@ -7,7 +9,7 @@ def create_missing_conf(sender, **kwargs):
from pod.main.models import Configuration
from django.core.exceptions import ObjectDoesNotExist
- print("---> Creating missing configurations ...")
+ print("---> Creating missing configurations...")
json_data = open("./pod/main/fixtures/initial_data.json")
json_data = json.load(json_data)
updated_count = 0
@@ -25,13 +27,13 @@ def create_missing_conf(sender, **kwargs):
):
updated_count = updated_count + 1
print("--> " + key)
- print("-> Updating description ...")
+ print("-> Updating description...")
conf.description_fr = description_fr
conf.description_en = description_en
conf.save()
except ObjectDoesNotExist:
print("--> " + key)
- print("-> Creating ...")
+ print("-> Creating...")
updated_count = updated_count + 1
Configuration.objects.create(
key=key,
@@ -46,6 +48,7 @@ def create_missing_conf(sender, **kwargs):
class MainConfig(AppConfig):
name = "pod.main"
default_auto_field = "django.db.models.BigAutoField"
+ verbose_name = _("Main configurations")
def ready(self):
post_migrate.connect(create_missing_conf, sender=self)
diff --git a/pod/main/fixtures/initial_data.json b/pod/main/fixtures/initial_data.json
index 824040dc5c..e9c72feb83 100644
--- a/pod/main/fixtures/initial_data.json
+++ b/pod/main/fixtures/initial_data.json
@@ -29,7 +29,7 @@
"pk": 2,
"model": "flatpages.flatpage",
"fields": {
- "content_fr": "
Mentions légales
Le texte ci-dessous sert de modèle de base et est à modifier par l'établissement hébergeur.
Description du site
\r\n
Esup-Pod est une plateforme de gestion de documents audio et vidéo à vocation culturelle, scientifique et pédagogique.
Hébergement
La plateforme « Pod » ainsi que les sauvegardes sont hébergées par## À COMPLÉTER##.
Droit d'auteur et respect de la propriété intellectuelle
\r\n
L'ensemble de ce site relève de la législation française et internationale sur le droit d'auteur et la propriété intellectuelle. Tous les droits de reproduction sont réservés.
\r\n
La reproduction de tout ou partie d’un document de cette plateforme sur un support électronique quel qu'il soit est formellement interdite sauf autorisation expresse de l’auteur de ce document.
\r\n
Avertissement concernant les documents publiés
\r\n
Préalablement à toute mise en ligne d’un document sur le service « Pod » l’usager est tenu de vérifier qu’il respecte bien la législation en vigueur.
\r\n
Chaque usager est responsable du contenu qu’il publie sur le service « Pod ».
Droit à l’image : L’usager s’engage à obtenir les autorisations des personnes identifiables sur le document audio ou vidéo. Si la personne identifiable est mineure, le consentement des représentants légaux est nécessaire avant toute diffusion.
\r\n
Protection de la vie privée et des données à caractère personnel
\r\n
Dans le cadre de la diffusion des podcasts, certaines données personnelles peuvent être communiquées aux utilisateurs de la plateforme.
\r\n",
+ "content_fr": "
Mentions légales
Le texte ci-dessous sert de modèle de base et est à modifier par l’établissement hébergeur.
Description du site
\r\n
Esup-Pod est une plateforme de gestion de documents audio et vidéo à vocation culturelle, scientifique et pédagogique.
Hébergement
La plateforme « Pod » ainsi que les sauvegardes sont hébergées par ## À COMPLÉTER##.
Droit d’auteur et respect de la propriété intellectuelle
\r\n
L’ensemble de ce site relève de la législation française et internationale sur le droit d’auteur et la propriété intellectuelle. Tous les droits de reproduction sont réservés.
\r\n
La reproduction de tout ou partie d’un document de cette plateforme sur un support électronique quel qu'il soit est formellement interdite sauf autorisation expresse de l’auteur de ce document.
\r\n
Avertissement concernant les documents publiés
\r\n
Préalablement à toute mise en ligne d’un document sur le service « Pod » l’usager est tenu de vérifier qu’il respecte bien la législation en vigueur.
\r\n
Chaque usager est responsable du contenu qu’il publie sur le service « Pod ».
Droit à l’image : L’usager s’engage à obtenir les autorisations des personnes identifiables sur le document audio ou vidéo. Si la personne identifiable est mineure, le consentement des représentants légaux est nécessaire avant toute diffusion.
\r\n
Protection de la vie privée et des données à caractère personnel
\r\n
Dans le cadre de la diffusion des podcasts, certaines données personnelles peuvent être communiquées aux utilisateurs de la plateforme.