diff --git a/pod/import_video/models.py b/pod/import_video/models.py
index a724b77a0a..c6e4ec6228 100644
--- a/pod/import_video/models.py
+++ b/pod/import_video/models.py
@@ -1,4 +1,8 @@
"""Models for the Import_video module."""
+import requests
+
+from urllib.parse import urlencode
+import xml.etree.ElementTree as et
from django.conf import settings
from django.contrib.sites.models import Site
@@ -9,7 +13,15 @@
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
+from pod.meeting.utils import (
+ api_call,
+ parseXmlToJson,
+ slash_join,
+)
+
SITE_ID = getattr(settings, "SITE_ID", 1)
+USE_MEETING = getattr(settings, "USE_MEETING", False)
+BBB_API_URL = getattr(settings, "BBB_API_URL", "")
class ExternalRecording(models.Model):
@@ -121,6 +133,48 @@ class ExternalRecording(models.Model):
help_text=_("User who uploaded to Pod the video file"),
)
+ def search_internal_recording(self, recording_id):
+ """Search for an internal recording that corresponds to recording_id.
+
+ This function checks whether an external recording has been made on the BBB
+ environment used by internal recordings and the meetings module.
+ Typically, this function recovers the single-use token of a BBB session
+ performed on the ESR infrastructure.
+ """
+ if USE_MEETING:
+ action = "getRecordings"
+ parameters = {}
+ parameters["recordID"] = recording_id
+ query = urlencode(parameters)
+ hashed = api_call(query, action)
+ if BBB_API_URL == "":
+ msg = {}
+ msg["error"] = _("Unable to call BBB server.")
+ msg["message"] = _("Parameter %s needs to be defined.") % "BBB_API_URL"
+ raise ValueError(msg)
+ url = slash_join(BBB_API_URL, action, "?%s" % hashed)
+ response = requests.get(url)
+ if response.status_code != 200:
+ msg = {}
+ msg["error"] = _("Unable to call BBB server.")
+ msg["returncode"] = response.status_code
+ msg["message"] = response.content.decode("utf-8")
+ raise ValueError(msg)
+ result = response.content.decode("utf-8")
+ xmldoc = et.fromstring(result)
+ recording_json = parseXmlToJson(xmldoc)
+ if recording_json.get("returncode", "") != "SUCCESS":
+ msg = {}
+ msg["error"] = _("Unable to get recording!")
+ msg["returncode"] = recording_json.get("returncode", "")
+ msg["messageKey"] = recording_json.get("messageKey", "")
+ msg["message"] = recording_json.get("message", "")
+ raise ValueError(msg)
+ else:
+ return recording_json
+ else:
+ return ValueError(_("Method not allowed"))
+
def __unicode__(self):
return "%s - %s" % (self.id, self.name)
diff --git a/pod/import_video/templates/import_video/list.html b/pod/import_video/templates/import_video/list.html
index 2906f44c75..14d5434ed1 100644
--- a/pod/import_video/templates/import_video/list.html
+++ b/pod/import_video/templates/import_video/list.html
@@ -57,14 +57,28 @@
{{ record.type }} |
{% if record.presentationUrl != "" %}
-
-
-
+ {% if record.recordingId == "" %}
+
+
+
+ {% else %}
+
+
+
+ {% endif %}
{% endif %}
{% if record.videoUrl != "" and record.videoUrl != record.presentationUrl %}
-
-
-
+ {% if record.recordingId == "" %}
+
+
+
+ {% else %}
+
+
+
+ {% endif %}
{% endif %}
|
@@ -144,5 +158,42 @@
}
return answer;
}
+
+ /**
+ * Function that allow to manage the link of recordings (video and presentation playback) to take into account the single-use token.
+ **/
+ function manageTokenLink(type, element) {
+ // Get important information from element
+ let recordId = element.dataset.podRecordingId;
+ // AJAX Pod server to re-request the BBB server
+ urlGetRecording = "/import_video/recording_with_token/" + recordId + "/";
+
+ // Get infos from the recording (new token appears here)
+ fetch(urlGetRecording, {
+ method: "GET",
+ headers: {
+ "X-CSRFToken": "{{ csrf_token }}",
+ "X-Requested-With": "XMLHttpRequest",
+ },
+ dataType: "html",
+ cache: "no-store",
+ })
+ .then((response) => response.text())
+ .then((data) => {
+ // Get new playback URL
+ let jsonData = JSON.parse(data);
+ var urlNew;
+ if (type == "presentation") {
+ urlNew = jsonData.presentationUrl;
+ } else {
+ urlNew = jsonData.videoUrl;
+ }
+ // Open the good URL in a new tab
+ window.open(urlNew, '_blank');
+ })
+ .catch((error) => {
+ console.debug(error);
+ });
+ }
{% endblock more_script %}
diff --git a/pod/import_video/urls.py b/pod/import_video/urls.py
index b53de34fe3..f101470917 100644
--- a/pod/import_video/urls.py
+++ b/pod/import_video/urls.py
@@ -28,4 +28,9 @@
views.delete_external_recording,
name="delete_external_recording",
),
+ path(
+ "recording_with_token//",
+ views.recording_with_token,
+ name="recording_with_token",
+ ),
]
diff --git a/pod/import_video/utils.py b/pod/import_video/utils.py
index fe87b5a85f..28e335a3c1 100644
--- a/pod/import_video/utils.py
+++ b/pod/import_video/utils.py
@@ -11,6 +11,7 @@
from django.utils.html import mark_safe
from django.utils.translation import gettext_lazy as _
from html.parser import HTMLParser
+from pod.meeting.utils import slash_join
from pod.video.models import Video
from pod.video.models import Type
from urllib.parse import parse_qs, urlparse
@@ -48,6 +49,11 @@
VIDEOS_DIR = getattr(settings, "VIDEOS_DIR", "videos")
+# The meeting application is activated?
+USE_MEETING = getattr(settings, "USE_MEETING", False)
+# BBB server API
+BBB_API_URL = getattr(settings, "BBB_API_URL", "")
+
def secure_request_for_upload(request):
"""Check that the request is correct for uploading a recording.
@@ -85,13 +91,8 @@ def parse_remote_file(session: Session, source_html_url: str):
try:
response = session.get(source_html_url)
if response.status_code != 200:
- msg = {}
- msg["error"] = _(
- "The HTML file for this recording was not found on the server."
- )
- # If we want to display the 404/500... page to the user
- # msg["message"] = response.content.decode("utf-8")
- msg["message"] = _("Error number: %s") % response.status_code
+ # No more informations needed for common error
+ msg = ''
raise ValueError(msg)
# Parse the BBB video HTML file
@@ -160,7 +161,7 @@ def manage_recording_url(source_url: str, video_file_add: str) -> str:
if url.query:
query = parse_qs(url.query, keep_blank_values=True)
if query["token"][0]:
- # 1st case (ex: ESR URL), URL likes (ex for ESR URL:)
+ # 1st case (ex: ESR URL), URL likes
# https://_site_/recording/_recording_id/video?token=_token_
# Get recording unique identifier
recording_id = url.path.split("/")[2]
@@ -236,7 +237,7 @@ def download_video_file(session: Session, source_video_url: str, dest_file: str)
# print(session.cookies.get_dict())
if response.status_code != 200:
raise ValueError(
- _("The video file for this recording " "was not found on the server.")
+ _("The video file for this recording was not found on the server.")
)
with open(dest_file, "wb+") as file:
@@ -361,7 +362,8 @@ def check_source_url(source_url: str): # noqa: C901
Platforms managed :
- Mediacad platform (Médiathèque académique) : rewrite source URL if required
and manage JSON API.
- - Old BigBlueButton : source URL for old BBB presentation playback
+ - BBB ESR infrastructure : rewrite source URL if required
+ - Old BigBlueButton presentation : source URL for old BBB presentation playback
"""
base_url = ""
media_id = ""
@@ -428,6 +430,27 @@ def check_source_url(source_url: str): # noqa: C901
media_id,
)
platform = "Mediacad"
+ elif source_url.find("bbb.numerique-esr.fr/video/") != -1:
+ # BBB ESR video link
+ # https://univ.scalelite.bbb.numerique-esr.fr/video/#id#/
+ source_video_url = source_url
+ format = "m4v"
+ platform = "BBB_ESR"
+ elif source_url.find("bbb.numerique-esr.fr/playback/presentation/2.3/") != -1:
+ # BBB ESR presentation link : rewrite for video source URL
+ # https://univ.scalelite.bbb.numerique-esr.fr/playback/presentation/2.3/#id#
+ source_video_url = source_url.replace(
+ "/playback/presentation/2.3/", "/video/"
+ ) + "/"
+ format = "m4v"
+ platform = "BBB_ESR"
+ elif source_url.find("bbb.numerique-esr.fr/recording/") != -1:
+ # BBB ESR video or presentation link : rewrite for video source URL if pres
+ # https://univ.scalelite.bbb.numerique-esr.fr/recording/#id#/presentation?
+ # https://univ.scalelite.bbb.numerique-esr.fr/recording/#id#/video?
+ source_video_url = source_url.replace("/presentation", "/video")
+ format = "m4v"
+ platform = "BBB_ESR"
elif source_url.find("/playback/presentation/2.0/playback.html?") != -1:
# Old BBB 2.x (<2.3) presentation link
# Conversion from
@@ -454,8 +477,8 @@ def check_source_url(source_url: str): # noqa: C901
platform_type = TypeSourceURL(
platform, source_video_url, format, url_api_video
)
- if platform == "BBB_Presentation":
- # Platform type: older BBB, format presentation
+ # Platform type: BBB ESR or older BBB, format presentation
+ if platform == "BBB_ESR" or platform == "BBB_Presentation":
platform_type = TypeSourceURL(platform, source_video_url, format, "")
return platform_type
@@ -507,6 +530,79 @@ def move_file(source: str, destination: str):
print(f"Error moving the file: {e}")
+def check_url_format_presentation(source_url: str) -> bool:
+ """ Check if the URL looks like a BBB presentation."""
+ presentation = False
+ # Management for old presentation URLs with BBB or Scalelite server
+ if source_url.find("/playback/presentation/2.0/playback.html?") != -1:
+ presentation = True
+ # Management for standard presentation URLs with BBB or Scalelite server
+ elif source_url.find("/playback/presentation/2.3/") != -1:
+ presentation = True
+ return presentation
+
+
+def check_url_need_token(source_url: str) -> str:
+ """ Check if the URL is used by an infrastructure that need a token.
+
+ Useful for generating the single-use token required to access video file.
+ 2 conditions :
+ - URL was created on the same BBB infrastructure as the meeting module,
+ - At present, only ESR's BBB infrastructure uses single-use tokens.
+ If both conditions are met, then returns the recording_id.
+ """
+ if USE_MEETING:
+ # Calculate base URL for BBB meeting
+ meeting_base_url = slash_join(BBB_API_URL.replace("bigbluebutton/api", ""))
+ # If the URL was created on the same BBB ESR infrastructure as the meeting module
+ # Ex:
+ # https://univ.scalelite.bbb.numerique-esr.fr/video/##id##/
+ # https://univ.scalelite.bbb.numerique-esr.fr/presentation/##id##/
+ # https://univ.scalelite.bbb.numerique-esr.fr/recording/##id##/video?xxx
+ # https://univ.scalelite.bbb.numerique-esr.fr/recording/##id##/presentation?xxx
+ # https://univ.scalelite.bbb.numerique-esr.fr/playback/presentation/2.3/##id##
+ if (
+ source_url.find(meeting_base_url) != -1
+ and source_url.find("bbb.numerique-esr.fr/") != -1
+ ):
+ # Get recording id
+ array_url = source_url.split("/")
+ recording_id = array_url[-2]
+ # Specific case
+ if recording_id == "2.3":
+ recording_id = array_url[-1]
+ return recording_id
+ else:
+ return ""
+ else:
+ return ""
+
+
+def get_playbacks_urls_with_token(recording):
+ """ Get presentation and video source URL, with token, for a recording.
+
+ Check if the recording was made by an infrastructure that need a token.
+ In such a case, request the BBB infrastructure to get playbacks with token.
+ """
+ # Default values
+ presentation_url = ""
+ video_url = ""
+ # Check if the URL is used by an infrastructure that need a token
+ recording_id = check_url_need_token(recording.source_url)
+ if recording_id != "":
+ # Request the BBB infrastructure to get playbacks with token
+ recordings = recording.search_internal_recording(recording_id)
+ if type(recordings.get("recordings")) is dict:
+ for data in recordings["recordings"].values():
+ for playback in data["playback"]:
+ if data["playback"][playback]["type"] == "video":
+ video_url = data["playback"][playback]["url"]
+ if data["playback"][playback]["type"] == "presentation":
+ presentation_url = data["playback"][playback]["url"]
+ # Return the 2 usefuls playbacks
+ return presentation_url, video_url
+
+
class TypeSourceURL:
"""Manage external recording source URL.
@@ -599,6 +695,8 @@ class StatelessRecording:
presentationUrl = ""
# Video playback URL, used as the source URL for the video file
videoUrl = ""
+ # Recording id (BBB format), when created on the same BBB infra as meeting module
+ recordingId = ""
def __init__(self, id, name, state):
"""Initiliaze."""
diff --git a/pod/import_video/views.py b/pod/import_video/views.py
index 157ba5362b..c5f6d80df1 100644
--- a/pod/import_video/views.py
+++ b/pod/import_video/views.py
@@ -14,12 +14,13 @@
from .models import ExternalRecording
from .forms import ExternalRecordingForm
-from .utils import StatelessRecording, check_url_exists, download_video_file
+from .utils import StatelessRecording, download_video_file
from .utils import manage_recording_url, check_source_url, parse_remote_file
from .utils import save_video, secure_request_for_upload
from .utils import check_video_size, verify_video_exists_and_size
from .utils import define_dest_file_and_path, check_file_exists, move_file
-from .utils import TypeSourceURL
+from .utils import check_url_format_presentation, check_url_need_token
+from .utils import get_playbacks_urls_with_token, TypeSourceURL
from datetime import datetime
from django.conf import settings
from django.contrib.auth.decorators import login_required
@@ -27,6 +28,7 @@
from django.contrib.sites.shortcuts import get_current_site
from django.core.exceptions import PermissionDenied
from django.contrib import messages
+from django.http import HttpResponse, HttpResponseBadRequest
from django.shortcuts import render, redirect
from django.shortcuts import get_object_or_404
from django.urls import reverse
@@ -212,14 +214,12 @@ def external_recordings(request):
owner__id=request.user.id, site=site
)
# | request.user.owners_external_recordings.all().filter(site=site)
- external_recordings = external_recordings.order_by("-id").distinct()
+ external_recordings = external_recordings.order_by("-start_at").distinct()
recordings = []
for data in external_recordings:
recording = get_stateless_recording(request, data)
-
recordings.append(recording)
-
return render(
request,
"import_video/list.html",
@@ -467,6 +467,13 @@ def upload_video_recording_to_pod(request, record_id: int): # noqa: C901
return True
else:
return False
+ elif type_source_url is not None and type_source_url.type == "BBB_ESR":
+ # BBB ESR platform
+ # For BBB ESR infrastructure, there is always a video playback
+ return upload_bbb_esr_video_recording_to_pod(
+ record_id,
+ type_source_url.url
+ )
else:
# Video file (or BBB video file, same process) source URL
return upload_standard_video_recording_to_pod(record_id)
@@ -507,8 +514,8 @@ def upload_standard_video_recording_to_pod(record_id: int) -> bool:
recording = ExternalRecording.objects.get(id=record_id)
# Step 1: Download and parse the remote HTML file if necessary
- # Check if extension is a video extension
source_url = recording.source_url
+ # Check if extension is a video extension
extension = source_url.split(".")[-1].lower()
# Name of the video file to add to the URL (if necessary)
@@ -548,6 +555,59 @@ def upload_standard_video_recording_to_pod(record_id: int) -> bool:
manage_standard_exception(exc)
+def upload_bbb_esr_video_recording_to_pod(record_id: int, source_url: str) -> bool:
+ """Upload a BBB - from BBB ESR infrastructure - video file recording to Pod.
+
+ Useful for generating the single-use token required to access the video file.
+ This is only possible for recordings made on the same BBB infrastructure used
+ by the meetings module.
+ """
+ try:
+ # Session useful to achieve requests (and keep cookies between)
+ session = requests.Session()
+
+ recording = ExternalRecording.objects.get(id=record_id)
+
+ # Check if the URL is used by an infrastructure that need a token
+ # In such a case, request the BBB infrastructure to get playbacks with token
+ presentation_url, video_url = get_playbacks_urls_with_token(recording)
+ if video_url != "":
+ # Define the new source URL, with token
+ recording.source_url = video_url
+ source_url = video_url
+
+ # Download and parse the remote HTML file (BBB specific)
+ video_file_add = parse_remote_file(session, source_url)
+ extension = video_file_add.split(".")[-1].lower()
+
+ # Impossible to check simply that video exists
+ # and not oversized for BBB ESR infrastructure.
+ # This seems to be a technical constraint.
+
+ # Step 2: Define destination source file
+ dest_file, dest_path = define_dest_file_and_path(
+ recording.owner, recording.id, extension
+ )
+
+ # Step 3: Download the video file
+ manage_download(session, source_url, video_file_add, dest_file)
+
+ # Step 4: Save informations about the recording
+ save_external_recording(recording.owner, record_id)
+
+ # Step 5: Save and encode Pod video
+ description = _(
+ 'This video has been uploaded to Pod and its source is the virtual '
+ 'classroom solution of the French Ministry of Higher Education and Research.'
+ )
+
+ save_video(recording.owner, dest_path, recording.name, description)
+
+ return True
+ except Exception as exc:
+ manage_standard_exception(exc)
+
+
def upload_local_video_recording_to_pod(record_id: id, dest_file: str, dest_path: str):
"""Upload a local (typically in Pod filesystem) video file recording to Pod.
Useful for video files that have been encoded following
@@ -1078,32 +1138,33 @@ def get_stateless_recording(request, data: ExternalRecording):
recording.state = get_status_recording(data)
# Management of the external recording type
- if data.type == "bigbluebutton":
+ if data.type == "bigbluebutton" or data.type == "video":
# Manage BBB recording URL
- # Management for old presentation URLs with BBB or Scalelite server
- if data.source_url.find("/playback/presentation/2.0/playback.html?") != -1:
- recording.presentationUrl = data.source_url
- # Management for standard presentation URLs with BBB or Scalelite server
- elif data.source_url.find("/playback/presentation/2.3/") != -1:
+ if check_url_format_presentation(data.source_url):
+ # Presentation format
recording.presentationUrl = data.source_url
- # Management of other situations
else:
+ # Management of other situations
recording.videoUrl = data.source_url
+ # Check if the URL is used by an infrastructure that need a token
+ recording.recordingId = check_url_need_token(data.source_url)
+
# If possible to encode BBB presentation
# Useful for old BBB or BBB 2.6+ without video playback
if USE_IMPORT_VIDEO_BBB_RECORDER and recording.presentationUrl != "":
recording.canUpload = True
recording.videoUrl = recording.presentationUrl
- # In all case
- if recording.videoUrl == "" or check_url_exists(recording.videoUrl) is False:
+
+ # To optimize, do not check that url exists
+ if recording.videoUrl == "":
recording.state = _(
"No video file found. Upload to Pod as a video is not possible."
)
recording.canUpload = False
recording.videoUrl = ""
else:
- # For PeerTube, Video file, Youtube
+ # For PeerTube, Youtube
recording.videoUrl = data.source_url
# Display type label
@@ -1116,8 +1177,39 @@ def get_status_recording(data: ExternalRecording) -> str:
"""Get the status of an external recording."""
if data.uploaded_to_pod_by is None and data.state is None:
state = _("Video file not uploaded to Pod")
- elif data.uploaded_to_pod_by is not None and data.state is None:
+ elif data.uploaded_to_pod_by is not None:
state = _("Video file already uploaded to Pod")
else:
state = data.state
return state
+
+
+@csrf_protect
+@ensure_csrf_cookie
+@login_required(redirect_field_name="referrer")
+def recording_with_token(request, id):
+ """Get for specific recording (recording created on BBB infrastructure that need a
+ token and used by meeting module), the presentation and video source URL, in JSON.
+
+ Args:
+ request (Request): HTTP request
+ record_id (int): record id
+
+ Raises:
+ PermissionDenied: if user not allowed
+
+ Returns:
+ HTTPResponse: internal recording (JSON format)
+ """
+ recording = ExternalRecording.objects.get(id=id)
+
+ # Check if the URL is used by an infrastructure that need a token
+ # In such a case, request the BBB infrastructure to get playbacks with token
+ presentation_url, video_url = get_playbacks_urls_with_token(recording)
+
+ # JSON format
+ data = '{"presentationUrl": "%s", "videoUrl": "%s"}' % (presentation_url, video_url)
+ if request.is_ajax():
+ return HttpResponse(data, content_type="application/json")
+ else:
+ return HttpResponseBadRequest()
diff --git a/pod/locale/fr/LC_MESSAGES/django.po b/pod/locale/fr/LC_MESSAGES/django.po
index 4ee0860109..a4e9c88e11 100644
--- a/pod/locale/fr/LC_MESSAGES/django.po
+++ b/pod/locale/fr/LC_MESSAGES/django.po
@@ -5,7 +5,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Pod\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2024-02-29 10:01+0000\n"
+"POT-Creation-Date: 2024-03-01 13:49+0100\n"
"PO-Revision-Date: \n"
"Last-Translator: obado \n"
"Language-Team: Pod Team cotech-esup-pod@esup-portail.org\n"
@@ -2545,6 +2545,23 @@ msgstr "Etat de l’enregistrement"
msgid "User who uploaded to Pod the video file"
msgstr "Utilisateur qui a téléversé le fichier vidéo sur Pod"
+#: pod/import_video/models.py pod/meeting/models.py
+msgid "Unable to call BBB server."
+msgstr "Impossible de joindre le serveur BBB."
+
+#: pod/import_video/models.py
+#, python-format
+msgid "Parameter %s needs to be defined."
+msgstr "Le paramètre %s doit être défini."
+
+#: pod/import_video/models.py pod/meeting/models.py
+msgid "Unable to get recording!"
+msgstr "Impossible d’obtenir l’enregistrement !"
+
+#: pod/import_video/models.py
+msgid "Method not allowed"
+msgstr "Méthode non autorisée"
+
#: pod/import_video/models.py
msgid "External recordings"
msgstr "Enregistrements externes"
@@ -2855,15 +2872,6 @@ msgstr ""
"Essayez de modifier le type d’enregistrement ou l’adresse de cet "
"enregistrement"
-#: pod/import_video/utils.py
-msgid "The HTML file for this recording was not found on the server."
-msgstr "Le fichier HTML de cet enregistrement est introuvable sur le serveur."
-
-#: pod/import_video/utils.py
-#, python-format
-msgid "Error number: %s"
-msgstr "Numéro d’erreur : %s"
-
#: pod/import_video/utils.py
msgid "The video file for this recording was not found in the HTML file."
msgstr ""
@@ -2947,8 +2955,17 @@ msgid ""
"This video was uploaded to Pod; its origin is %(type)s: %(url)s"
msgstr ""
-"Cette vidéo a été téléversée sur Pod ; son origine est %(type)s : %(url)s"
+"Cette vidéo a été téléversée sur Pod ; son origine est %(type)s : %(url)s"
+
+#: pod/import_video/views.py
+msgid ""
+"This video has been uploaded to Pod and its source is the virtual classroom "
+"solution of the French Ministry of Higher Education and Research."
+msgstr ""
+"Cette vidéo a été téléversée sur Pod et sa source est la solution de classe "
+"virtuelle du Ministère Français de l'Enseignement Supérieur et de la "
+"Recherche."
#: pod/import_video/views.py
#, python-format
@@ -5594,10 +5611,6 @@ msgstr "Impossible de terminer la réunion !"
msgid "Unable to get meeting recordings!"
msgstr "Impossible d’obtenir les enregistrements de la réunion !"
-#: pod/meeting/models.py
-msgid "Unable to get recording!"
-msgstr "Impossible d’obtenir l’enregistrement !"
-
#: pod/meeting/models.py
msgid "Unable to delete recording!"
msgstr "Impossible de supprimer l’enregistrement !"
@@ -9265,6 +9278,14 @@ msgstr "Résultats de la recherche"
msgid "Esup-Pod xAPI"
msgstr "xAPI Esup-Pod"
+#~ msgid "The HTML file for this recording was not found on the server."
+#~ msgstr ""
+#~ "Le fichier HTML de cet enregistrement est introuvable sur le serveur."
+
+#, python-format
+#~ msgid "Error number: %s"
+#~ msgstr "Numéro d’erreur : %s"
+
#~ msgid "Playlist image"
#~ msgstr "Image de la playlist"
diff --git a/pod/locale/fr/LC_MESSAGES/djangojs.po b/pod/locale/fr/LC_MESSAGES/djangojs.po
index ffae9cd7d0..11a9ebb8a1 100644
--- a/pod/locale/fr/LC_MESSAGES/djangojs.po
+++ b/pod/locale/fr/LC_MESSAGES/djangojs.po
@@ -5,7 +5,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Esup-Pod\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2024-02-29 10:01+0000\n"
+"POT-Creation-Date: 2024-03-01 13:49+0100\n"
"PO-Revision-Date: \n"
"Last-Translator: obado \n"
"Language-Team: \n"
diff --git a/pod/locale/nl/LC_MESSAGES/django.po b/pod/locale/nl/LC_MESSAGES/django.po
index 7acb5d6772..a2d63bde3c 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: 2024-02-29 10:01+0000\n"
+"POT-Creation-Date: 2024-03-01 13:49+0100\n"
"PO-Revision-Date: 2023-06-08 14:37+0200\n"
"Last-Translator: obado \n"
"Language-Team: \n"
@@ -2421,6 +2421,23 @@ msgstr ""
msgid "User who uploaded to Pod the video file"
msgstr ""
+#: pod/import_video/models.py pod/meeting/models.py
+msgid "Unable to call BBB server."
+msgstr ""
+
+#: pod/import_video/models.py
+#, python-format
+msgid "Parameter %s needs to be defined."
+msgstr ""
+
+#: pod/import_video/models.py pod/meeting/models.py
+msgid "Unable to get recording!"
+msgstr ""
+
+#: pod/import_video/models.py
+msgid "Method not allowed"
+msgstr ""
+
#: pod/import_video/models.py
msgid "External recordings"
msgstr ""
@@ -2684,15 +2701,6 @@ msgstr ""
msgid "Try changing the record type or address for this recording"
msgstr ""
-#: pod/import_video/utils.py
-msgid "The HTML file for this recording was not found on the server."
-msgstr ""
-
-#: pod/import_video/utils.py
-#, python-format
-msgid "Error number: %s"
-msgstr ""
-
#: pod/import_video/utils.py
msgid "The video file for this recording was not found in the HTML file."
msgstr ""
@@ -2770,6 +2778,12 @@ msgid ""
"target=\"_blank\">%(url)s"
msgstr ""
+#: pod/import_video/views.py
+msgid ""
+"This video has been uploaded to Pod and its source is the virtual classroom "
+"solution of the French Ministry of Higher Education and Research."
+msgstr ""
+
#: pod/import_video/views.py
#, python-format
msgid ""
@@ -5299,10 +5313,6 @@ msgstr ""
msgid "Unable to get meeting recordings!"
msgstr ""
-#: pod/meeting/models.py
-msgid "Unable to get recording!"
-msgstr ""
-
#: pod/meeting/models.py
msgid "Unable to delete recording!"
msgstr ""
diff --git a/pod/locale/nl/LC_MESSAGES/djangojs.po b/pod/locale/nl/LC_MESSAGES/djangojs.po
index ca7c586d33..af89d1a839 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: 2024-02-29 10:01+0000\n"
+"POT-Creation-Date: 2024-03-01 13:49+0100\n"
"PO-Revision-Date: 2023-02-08 15:22+0100\n"
"Last-Translator: obado \n"
"Language-Team: \n"
diff --git a/pod/meeting/models.py b/pod/meeting/models.py
index bb45dfc512..7ee879af89 100644
--- a/pod/meeting/models.py
+++ b/pod/meeting/models.py
@@ -635,7 +635,7 @@ def create(self, request=None):
response = self.get_create_response(url)
if response.status_code != 200:
msg = {}
- msg["error"] = "Unable to call BBB server."
+ msg["error"] = _("Unable to call BBB server.")
msg["returncode"] = response.status_code
msg["message"] = response.content.decode("utf-8")
raise ValueError(msg)
@@ -774,7 +774,7 @@ def get_is_meeting_running(self):
response = requests.get(url)
if response.status_code != 200:
msg = {}
- msg["error"] = "Unable to call BBB server."
+ msg["error"] = _("Unable to call BBB server.")
msg["returncode"] = response.status_code
msg["message"] = response.content.decode("utf-8")
raise ValueError(msg)
@@ -810,7 +810,7 @@ def get_meeting_info(self):
response = requests.get(url)
if response.status_code != 200:
msg = {}
- msg["error"] = "Unable to call BBB server."
+ msg["error"] = _("Unable to call BBB server.")
msg["returncode"] = response.status_code
msg["message"] = response.content.decode("utf-8")
raise ValueError(msg)
@@ -838,7 +838,7 @@ def end(self):
response = requests.get(url)
if response.status_code != 200:
msg = {}
- msg["error"] = "Unable to call BBB server."
+ msg["error"] = _("Unable to call BBB server.")
msg["returncode"] = response.status_code
msg["message"] = response.content.decode("utf-8")
raise ValueError(msg)
@@ -868,7 +868,7 @@ def get_recordings(self):
response = requests.get(url)
if response.status_code != 200:
msg = {}
- msg["error"] = "Unable to call BBB server."
+ msg["error"] = _("Unable to call BBB server.")
msg["returncode"] = response.status_code
msg["message"] = response.content.decode("utf-8")
raise ValueError(msg)
@@ -897,7 +897,7 @@ def get_recording(self, record_id):
response = requests.get(url)
if response.status_code != 200:
msg = {}
- msg["error"] = "Unable to call BBB server."
+ msg["error"] = _("Unable to call BBB server.")
msg["returncode"] = response.status_code
msg["message"] = response.content.decode("utf-8")
raise ValueError(msg)
@@ -925,7 +925,7 @@ def delete_recording(self, record_id):
response = requests.get(url)
if response.status_code != 200:
msg = {}
- msg["error"] = "Unable to call BBB server."
+ msg["error"] = _("Unable to call BBB server.")
msg["returncode"] = response.status_code
msg["message"] = response.content.decode("utf-8")
raise ValueError(msg)
@@ -955,7 +955,7 @@ def get_all_meetings():
response = requests.get(url)
if response.status_code != 200:
msg = {}
- msg["error"] = "Unable to call BBB server."
+ msg["error"] = _("Unable to call BBB server.")
msg["returncode"] = response.status_code
msg["message"] = response.content.decode("utf-8")
raise ValueError(msg)
|