diff --git a/pod/favorite/admin.py b/pod/favorite/admin.py deleted file mode 100644 index 3d9c11705d..0000000000 --- a/pod/favorite/admin.py +++ /dev/null @@ -1,19 +0,0 @@ -"""Esup-Pod Favorite video admin.""" -from django.contrib import admin -from .models import Favorite - - -@admin.register(Favorite) -class FavoriteAdmin(admin.ModelAdmin): - """Favorite video admin page.""" - - date_hierarchy = "date_added" - list_display = ( - "id", - "video", - "owner", - "date_added", - "rank", - ) - list_filter = ("owner", "date_added", "rank") - search_fields = ("video__title", "owner__username") diff --git a/pod/favorite/apps.py b/pod/favorite/apps.py deleted file mode 100644 index 14f97fa906..0000000000 --- a/pod/favorite/apps.py +++ /dev/null @@ -1,11 +0,0 @@ -"""Esup-Pod Favorite video app.""" -from django.apps import AppConfig -from django.utils.translation import gettext_lazy as _ - - -class FavoriteConfig(AppConfig): - """Favorite configuration app.""" - - name = "pod.favorite" - default_auto_field = "django.db.models.BigAutoField" - verbose_name = _("Favorite videos") diff --git a/pod/favorite/context_processors.py b/pod/favorite/context_processors.py deleted file mode 100644 index d7cc26d5c9..0000000000 --- a/pod/favorite/context_processors.py +++ /dev/null @@ -1,10 +0,0 @@ -from django.conf import settings as django_settings - -USE_FAVORITES = getattr(django_settings, "USE_FAVORITES", True) - - -def context_settings(request): - """Return all context settings for favorite app""" - new_settings = {} - new_settings["USE_FAVORITES"] = USE_FAVORITES - return new_settings diff --git a/pod/favorite/models.py b/pod/favorite/models.py deleted file mode 100644 index 50f4045728..0000000000 --- a/pod/favorite/models.py +++ /dev/null @@ -1,42 +0,0 @@ -"""Esup-Pod favorite video model.""" -from django.contrib.auth.models import User -from django.db import models -from django.utils import timezone -from django.utils.translation import ugettext as _ - -from pod.video.models import Video - - -class Favorite(models.Model): - """Favorite video model.""" - - video = models.ForeignKey(Video, verbose_name=_("Video"), on_delete=models.CASCADE) - owner = models.ForeignKey(User, verbose_name=_("User"), on_delete=models.CASCADE) - date_added = models.DateTimeField( - verbose_name=_("Date added"), default=timezone.now, editable=False - ) - rank = models.IntegerField(verbose_name=_("Rank"), editable=False) - - class Meta: - """Metadata for favorite video Model.""" - - constraints = [ - # A video can only be favorited once per owner - models.UniqueConstraint( - fields=["video", "owner"], name="unique_favorite_video_owner" - ), - # There mustn't be duplicated ranks for one owner - models.UniqueConstraint( - fields=["owner", "rank"], name="unique_favorite_owner_rank" - ), - ] - # Default ordering for Favorites items (not for Favorite video list) - ordering = ["owner", "rank"] - # Latest by ascending rank. - get_latest_by = "rank" - verbose_name = _("Favorite video") - verbose_name_plural = _("Favorite videos") - - def __str__(self) -> str: - """Display a favorite object as string.""" - return f"{self.owner} - favorite {self.rank} - {self.video}" diff --git a/pod/favorite/static/css/favorites-list.css b/pod/favorite/static/css/favorites-list.css deleted file mode 100644 index df865ed661..0000000000 --- a/pod/favorite/static/css/favorites-list.css +++ /dev/null @@ -1,59 +0,0 @@ -.shake-effect { - animation: shake 2.3s ease-in-out; - animation-iteration-count: infinite; - cursor: grab; -} - -.shake-effect .badge{ - display: block; -} - - -.shake-effect-active { - cursor: grabbing; -} - -@keyframes shake { - 0% { transform: translate(1px, 1px) rotate(0deg); } - 10% { transform: translate(-1px, -2px) rotate(-1deg); } - 20% { transform: translate(-3px, 0px) rotate(1deg); } - 30% { transform: translate(3px, 2px) rotate(0deg); } - 40% { transform: translate(1px, -1px) rotate(1deg); } - 50% { transform: translate(-1px, 2px) rotate(-1deg); } - 60% { transform: translate(-3px, 1px) rotate(0deg); } - 70% { transform: translate(3px, 1px) rotate(-1deg); } - 80% { transform: translate(-1px, -1px) rotate(1deg); } - 90% { transform: translate(1px, 2px) rotate(0deg); } - 100% { transform: translate(1px, 2px) rotate(0deg); } -} - -.no-click { - pointer-events: none; -} - -#sortForm.no-click, #collapse-button.no-click { - opacity: 0; - transition: opacity .9s ease; -} - -.card-hidden { - display: none; -} - -.card-footer, -.draggable-container .badge { - transition: opacity 0.9s ease; -} - -.shake-effect .card-footer, -.draggable-container .badge { - opacity: 0; -} - -.shake-effect .badge { - opacity: 1; -} - -.dropzone-hover { - border: .2rem solid #1F7C85; -} diff --git a/pod/favorite/static/js/video-favorites-card-delete.js b/pod/favorite/static/js/video-favorites-card-delete.js deleted file mode 100644 index 245182cf96..0000000000 --- a/pod/favorite/static/js/video-favorites-card-delete.js +++ /dev/null @@ -1,29 +0,0 @@ -document.addEventListener("DOMContentLoaded", function () { - const cards = document.getElementsByClassName("draggable-container"); - const title = document.getElementById("video_count"); - for (let card of cards) { - const form = card.querySelector(".favorite-button-form-card"); - form.addEventListener("submit", function (e) { - e.preventDefault(); - const formData = new FormData(form); - fetch(form.action, { - method: form.method, - body: formData, - }) - .then((response) => response.text()) // We take the HTML content of the response - .then((data) => { - const parser = new DOMParser(); - const html = parser.parseFromString(data, "text/html"); - card.remove(); - const title = document.getElementById("video_count"); - title.replaceWith(html.getElementById("video_count")); - document.title = html.title; - addEventForReorganizedButton(); - }) - .catch((error) => { - if (!(error instanceof TypeError)) - alert(gettext("The video could not be removed from favorites...")); - }); - }); - } -}); diff --git a/pod/favorite/static/js/video-favorites-card-list.js b/pod/favorite/static/js/video-favorites-card-list.js deleted file mode 100644 index 805b676e1e..0000000000 --- a/pod/favorite/static/js/video-favorites-card-list.js +++ /dev/null @@ -1,27 +0,0 @@ -document.addEventListener("DOMContentLoaded", function () { - const forms = document.getElementsByClassName("favorite-button-form-card"); - for (let form of forms) { - form.addEventListener("submit", function (e) { - e.preventDefault(); - const formData = new FormData(form); - fetch(form.action, { - method: form.method, - body: formData, - }) - .then((response) => { - response.text(); // We take the HTML content of the response - const button = form.querySelector(".star_btn > i"); - button.classList.toggle("bi-star-fill"); - button.classList.toggle("bi-star"); - if (button.classList.contains("bi-star-fill")) { - button.title = gettext("Remove from favorite"); - } else { - button.title = gettext("Add in favorite"); - } - }) - .catch((error) => { - alert(gettext("The deletion couldn't be completed...")); - }); - }); - } -}); diff --git a/pod/favorite/static/js/video-favorites.js b/pod/favorite/static/js/video-favorites.js deleted file mode 100644 index c3049662ca..0000000000 --- a/pod/favorite/static/js/video-favorites.js +++ /dev/null @@ -1,25 +0,0 @@ -document.addEventListener("DOMContentLoaded", function () { - const form = document.getElementById("favorite-button-form"); - if (form !== null) { - form.addEventListener("submit", function (e) { - e.preventDefault(); - const formData = new FormData(form); - fetch(form.action, { - method: form.method, - body: formData, - }) - .then((response) => response.text()) // We take the HTML content of the response - .then((data) => { - const parser = new DOMParser(); - const html = parser.parseFromString(data, "text/html"); - const updatedButton = html.querySelector(".star_btn"); - const button = document.querySelector(".star_btn"); - button.replaceWith(updatedButton); - }) - .catch((error) => { - console.log(error); - alert(gettext("The favorite couldn’t be completed…")); - }); - }); - } -}); diff --git a/pod/favorite/templates/favorite/favorite_video_list.html b/pod/favorite/templates/favorite/favorite_video_list.html deleted file mode 100644 index b69c7c53af..0000000000 --- a/pod/favorite/templates/favorite/favorite_video_list.html +++ /dev/null @@ -1,32 +0,0 @@ -{% load i18n %} -{% load static %} -{% spaceless %} -
- {% for video in videos %} -
-
- {% include "videos/card.html" %} -
{{ video.rank }}
-
-
- {% empty %} -
-

{% trans "Sorry, no video found." %}

-
- {% endfor %} -
-{% if videos.has_next %} - -{% endif %} - -{% endspaceless %} -{% block more_script %} - -{% endblock %} diff --git a/pod/favorite/templates/favorite/favorite_videos.html b/pod/favorite/templates/favorite/favorite_videos.html deleted file mode 100644 index 494c0f2c1a..0000000000 --- a/pod/favorite/templates/favorite/favorite_videos.html +++ /dev/null @@ -1,80 +0,0 @@ -{% extends 'base.html' %} -{% load i18n %} -{% load static %} - -{% block opengraph %}{% load video_filters %} - - - - - - - - -{% endblock %} - -{% block page_extra_head %} - -{% endblock page_extra_head %} - -{% block breadcrumbs %}{{ block.super }} {% endblock %} - -{% block page_content %} -
-

{% blocktrans count counter=count_videos %}{{ counter }} video found{% plural %}{{ counter }} videos found{% endblocktrans %}

- {% if count_videos > 1 %} -
-
- {% csrf_token %} - - - -  {% trans "Cancel" %} - -
-
-
- {% include "videos/video_sort_select.html" with favorite=True %} -
- {% endif %} -
- {% include 'loader.html' %} - {% include "favorite/favorite_video_list.html" %} -{% endblock page_content %} - -{% block page_aside %} - {% include 'videos/filter_aside.html' %} -
-

{% trans "Help - Drag & Drop" %}

-
-
    -
  1. {% trans "Select the video to move by clicking and holding." %}
  2. -
  3. {% trans "While holding down the video, drag it to the desired location." %}
  4. -
  5. {% trans "Drop the video on another to swap their position." %}
  6. -
-
-
-{% endblock page_aside %} - - -{% block more_script %} - - - - - - -{% endblock more_script %} diff --git a/pod/favorite/templatetags/favorite_info.py b/pod/favorite/templatetags/favorite_info.py deleted file mode 100644 index c9ac9e50d5..0000000000 --- a/pod/favorite/templatetags/favorite_info.py +++ /dev/null @@ -1,39 +0,0 @@ -from django.template import Library - -from pod.video.models import Video - -from ..utils import user_has_favorite_video, get_number_favorites - -register = Library() - - -@register.simple_tag(takes_context=True, name="is_favorite") -def is_favorite(context: dict, video: Video) -> bool: - """ - Template tag to check if the user has this video as favorite. - - Args: - context (dict): The template context dictionary - video (:class:`pod.video.models.Video`): The video entity to check - - Returns: - bool: True if the user has the video as favorite, False otherwise - """ - request = context["request"] - if not request.user.is_authenticated: - return False - return user_has_favorite_video(request.user, video) - - -@register.simple_tag(name="number_favorites") -def number_favorites(video: Video) -> int: - """ - Template tag to get the favorite number. - - Args: - video (:class:`pod.video.models.Video`): The video entity - - Returns: - int: The video favorite number - """ - return get_number_favorites(video) diff --git a/pod/favorite/tests/__init__.py b/pod/favorite/tests/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/pod/favorite/tests/test_models.py b/pod/favorite/tests/test_models.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/pod/favorite/tests/test_utils.py b/pod/favorite/tests/test_utils.py deleted file mode 100644 index 7bd446cc4e..0000000000 --- a/pod/favorite/tests/test_utils.py +++ /dev/null @@ -1,174 +0,0 @@ -"""Unit tests for Esup-Pod favorite video utilities.""" - -from django.contrib.auth.models import User -from django.http import HttpRequest -from django.test import TestCase - -from pod.favorite.models import Favorite -from pod.favorite.utils import get_next_rank, user_add_or_remove_favorite_video -from pod.favorite.utils import user_has_favorite_video, get_number_favorites -from pod.favorite.utils import get_all_favorite_videos_for_user -from pod.video.utils import sort_videos_list -from pod.video.models import Type, Video - - -class FavoriteTestUtils(TestCase): - """TestCase for Esup-Pod favorite video utilities.""" - - fixtures = ["initial_data.json"] - - def setUp(self) -> None: - """Set up required objects for next tests.""" - self.user = User.objects.create(username="pod", password="pod1234pod") - self.user2 = User.objects.create(username="pod2", password="pod1234pod2") - self.video = Video.objects.create( - title="Video1", - owner=self.user, - video="test.mp4", - is_draft=False, - type=Type.objects.get(id=1), - ) - self.video2 = Video.objects.create( - title="Video2", - owner=self.user, - video="test2.mp4", - is_draft=False, - type=Type.objects.get(id=1), - ) - self.video3 = Video.objects.create( - title="Video3", - owner=self.user2, - video="test3.mp4", - is_draft=False, - type=Type.objects.get(id=1), - ) - - def test_next_rank(self) -> None: - """Test if get_next_rank works correctly""" - Favorite.objects.create( - owner=self.user, - video=self.video, - rank=1, - ) - self.assertEqual( - 2, - get_next_rank(self.user), - "Test if user with favorite can generate the next rank", - ) - self.assertEqual( - 1, - get_next_rank(self.user2), - "Test if user without favorite can generate the next rank", - ) - print(" ---> test_next_rank ok") - - def test_user_add_or_remove_favorite_video(self) -> None: - """Test if test_user_add_or_remove_favorite_video works correctly""" - user_add_or_remove_favorite_video(self.user, self.video) - favorite_tuple_exists = Favorite.objects.filter( - owner=self.user, video=self.video - ).exists() - self.assertTrue( - favorite_tuple_exists, - "Test if tuple has been correctly inserted", - ) - user_add_or_remove_favorite_video(self.user, self.video) - favorite_tuple_not_exists = Favorite.objects.filter( - owner=self.user, video=self.video - ).exists() - self.assertFalse( - favorite_tuple_not_exists, - "Test if tuple has been correctly deleted", - ) - print(" ---> test_user_add_or_remove_favorite_video ok") - - def test_user_has_favorite_video(self) -> None: - """Test if test_user_has_favorite_video works correctly""" - Favorite.objects.create( - owner=self.user, - video=self.video, - rank=1, - ) - self.assertTrue( - user_has_favorite_video(self.user, self.video), - "Test if user has a favorite video", - ) - self.assertFalse( - user_has_favorite_video(self.user2, self.video), - "Test if user hasn't a favorite video", - ) - print(" ---> test_user_has_favorite_video ok") - - def test_get_number_favorites(self) -> None: - """Test if test_get_number_favorites works correctly""" - self.assertEqual( - get_number_favorites(self.video), - 0, - "Test if there's no favorites in the video", - ) - Favorite.objects.create( - owner=self.user, - video=self.video, - rank=1, - ) - Favorite.objects.create( - owner=self.user2, - video=self.video, - rank=1, - ) - self.assertEqual( - get_number_favorites(self.video), - 2, - "Test if there is 2 favorites in the video", - ) - - print(" ---> test_get_number_favorites ok") - - def test_get_all_favorite_videos_for_user(self) -> None: - """Test if get_all_favorite_videos_for_user works correctly.""" - Favorite.objects.create( - owner=self.user, - video=self.video, - rank=1, - ) - video_list = get_all_favorite_videos_for_user(self.user) - self.assertEqual(video_list.count(), 1) - self.assertEqual(video_list.first(), self.video) - print(" ---> get_all_favorite_videos_for_user ok") - - def test_sort_videos_list_1(self) -> None: - """Test if sort_videos_list works correctly.""" - request = HttpRequest() - Favorite.objects.create( - owner=self.user, - video=self.video, - rank=1, - ) - Favorite.objects.create( - owner=self.user, - video=self.video2, - rank=2, - ) - Favorite.objects.create( - owner=self.user, - video=self.video3, - rank=3, - ) - - sorted_videos = [self.video3, self.video2, self.video] - test_sorted_videos = sort_videos_list( - get_all_favorite_videos_for_user(self.user), request.GET.get("sort", "rank") - ) - self.assertEqual(list(test_sorted_videos), sorted_videos) - - request.GET["sort"] = "rank" - request.GET["sort_direction"] = "on" - sorted_videos = [self.video, self.video2, self.video3] - test_sorted_videos = sort_videos_list( - get_all_favorite_videos_for_user(self.user), - request.GET.get("sort", "rank"), - request.GET.get("sort_direction"), - ) - self.assertEqual(list(test_sorted_videos), sorted_videos) - - print(" ---> sort_videos_list ok") diff --git a/pod/favorite/tests/test_views.py b/pod/favorite/tests/test_views.py deleted file mode 100644 index cba7713bea..0000000000 --- a/pod/favorite/tests/test_views.py +++ /dev/null @@ -1,268 +0,0 @@ -"""Esup-Pod favorite views tests. - -* run with 'python manage.py test pod.favorite.tests.test_views' -""" -from django.test import override_settings, TestCase -from django.contrib.auth.models import User -from django.urls import reverse -from django.utils.translation import ugettext_lazy as _ - -from pod.favorite import context_processors -from pod.favorite.models import Favorite -from pod.video.models import Type, Video - -import importlib - - -class TestShowStarTestCase(TestCase): - """Favorite star icon test case.""" - - fixtures = ["initial_data.json"] - - def setUp(self) -> None: - """Set up required objects for next tests.""" - self.user_with_favorite = User.objects.create( - username="pod", password="pod1234pod" - ) - self.user_without_favorite = User.objects.create( - username="pod2", password="pod1234pod2" - ) - self.video = Video.objects.create( - title="Video1", - owner=self.user_without_favorite, - video="test.mp4", - is_draft=False, - type=Type.objects.get(id=1), - ) - Favorite.objects.create( - owner=self.user_with_favorite, - video=self.video, - rank=1, - ) - self.url = reverse("video:video", args=[self.video.slug]) - - @override_settings(USE_FAVORITES=True) - def test_show_star_unfill(self) -> None: - """Test if the star is unfill when the video isn't favorite.""" - importlib.reload(context_processors) - self.client.force_login(self.user_without_favorite) - response = self.client.get(self.url) - self.assertEqual( - response.status_code, - 200, - "Test if status code equal 200 when the video isn't favorite", - ) - self.assertTrue( - "bi-star" in response.content.decode(), - "Test if the star is correctly present when the video isn't favorite", - ) - self.client.logout() - print(" ---> test_show_star_unfill ok") - - @override_settings(USE_FAVORITES=True) - def test_show_star_fill(self) -> None: - """Test if the star is filled when the video is favorite.""" - importlib.reload(context_processors) - self.client.force_login(self.user_with_favorite) - response = self.client.get(self.url) - self.assertEqual( - response.status_code, - 200, - "Test if status code equal 200 when the video is favorite", - ) - self.assertTrue( - "bi-star-fill" in response.content.decode(), - "Test if the star is correctly present when the video is favorite", - ) - self.client.logout() - print(" ---> test_show_star_fill ok") - - @override_settings(USE_FAVORITES=True) - def test_favorite_star_hidden(self) -> None: - """Test if the favorite star is hidden when the user is disconnected.""" - importlib.reload(context_processors) - response = self.client.get(self.url) - self.assertEqual( - response.status_code, - 200, - "Test if status code equal 200 when the user is disconnected", - ) - self.assertFalse( - 'class="btn btn-lg btn-link p-1 star_btn"' in response.content.decode(), - "Test if the star does not appear when the user is disconnected", - ) - print(" ---> test_favorite_star_hidden ok") - - def test_show_star_404_error(self) -> None: - """Test if we can't navigate in the `favorite/` route with GET method.""" - importlib.reload(context_processors) - response = self.client.get(reverse("favorite:add-or-remove")) - self.assertEqual( - response.status_code, - 404, - """ - Test if status code equal 404 when we try to navigate in - the `favorite/` route with GET method - """, - ) - print(" ---> test_show_star_404_error ok") - - @override_settings(USE_FAVORITES=False) - def test_show_star_when_use_favorites_equal_false(self) -> None: - """Test if the star isn't present when USE_FAVORITES equal False.""" - importlib.reload(context_processors) - self.client.force_login(self.user_without_favorite) - response = self.client.get(self.url) - self.assertEqual( - response.status_code, - 200, - "Test if status code equal 200 when USE_FAVORITES equal False", - ) - self.assertFalse( - "bi-star" in response.content.decode(), - "Test if the star isn't present when USE_FAVORITES equal False", - ) - self.client.logout() - print(" ---> test_show_star_when_use_favorites_equal_false ok") - - -class TestFavoriteVideoListTestCase(TestCase): - """Favorite video list test case.""" - - fixtures = ["initial_data.json"] - - def setUp(self) -> None: - """Set up required objects for next tests.""" - self.user_with_favorite = User.objects.create( - username="pod", password="pod1234pod" - ) - self.user_without_favorite = User.objects.create( - username="pod2", password="pod1234pod2" - ) - self.video = Video.objects.create( - title="Video1", - owner=self.user_without_favorite, - video="test.mp4", - is_draft=False, - type=Type.objects.get(id=1), - ) - Favorite.objects.create( - owner=self.user_with_favorite, - video=self.video, - rank=1, - ) - self.url = reverse("favorite:list") - - @override_settings(USE_FAVORITES=True) - def test_favorite_video_list_not_empty(self) -> None: - """Test if the favorite video list isn't empty when the user has favorites.""" - importlib.reload(context_processors) - self.client.force_login(self.user_with_favorite) - response = self.client.get(self.url) - self.assertEqual( - response.status_code, - 200, - "Test if status code equal 200 when the favorite video list isn't empty", - ) - self.assertTrue( - 'data-countvideos="1"' in response.content.decode(), - "Test if the favorite video list isn't correctly empty", - ) - self.client.logout() - print(" ---> test_favorite_video_list_not_empty ok") - - @override_settings(USE_FAVORITES=True) - def test_favorite_video_list_empty(self) -> None: - """Test if the favorite video list is empty when the user has favorites.""" - importlib.reload(context_processors) - self.client.force_login(self.user_without_favorite) - response = self.client.get(self.url) - self.assertEqual( - response.status_code, - 200, - "Test if status code equal 200 when the favorite video list isn't empty", - ) - self.assertTrue( - 'data-countvideos="0"' in response.content.decode(), - "Test if the favorite video list is correctly empty", - ) - self.client.logout() - print(" ---> test_favorite_video_list_empty ok") - - @override_settings(USE_FAVORITES=True) - def test_favorite_video_list_link_in_navbar(self) -> None: - """Test if the favorite video list link is present in the navbar.""" - importlib.reload(context_processors) - self.client.force_login(self.user_with_favorite) - response = self.client.get("/") - self.assertEqual( - response.status_code, - 200, - "Test if status code equal 200 in test_favorite_video_list_link_in_navbar", - ) - self.assertTrue( - str(_("My favorite videos")) in response.content.decode(), - "Test if the favorite video list link is present in the navbar", - ) - self.client.logout() - print(" ---> test_favorite_video_list_link_in_navbar ok") - - @override_settings(USE_FAVORITES=False) - def test_favorite_video_list_link_in_navbar_when_use_favorites_is_false(self) -> None: - """Test if the favorite video list link is present in the navbar.""" - importlib.reload(context_processors) - self.client.force_login(self.user_with_favorite) - response = self.client.get("/") - self.assertEqual( - response.status_code, - 200, - """ - Test if status code equal 200 in - test_favorite_video_list_link_in_navbar_when_use_favorites_equal_false - """, - ) - self.assertFalse( - str(_("My favorite videos")) in response.content.decode(), - "Test if the favorite video list link is present in the navbar", - ) - self.client.logout() - print( - """ - ---> test_favorite_video_list_link_in_navbar_when_use_favorites_equal_false - ok - """ - ) - - -class TestShowStarInfoTestCase(TestCase): - """Favorite star info test case.""" - - fixtures = ["initial_data.json"] - - def setUp(self) -> None: - """Set up required objects for next tests.""" - self.user = User.objects.create(username="pod", password="pod1234pod") - self.video = Video.objects.create( - title="Video1", - owner=self.user, - video="test.mp4", - is_draft=False, - type=Type.objects.get(id=1), - ) - self.url = reverse("video:video", args=[self.video.slug]) - - @override_settings(USE_FAVORITES=True) - def test_favorites_count(self) -> None: - """Test favorite count.""" - importlib.reload(context_processors) - response = self.client.get(self.url) - self.assertEqual( - response.status_code, - 200, - "Test if status code equal 200 when the user is disconnected", - ) - self.assertTrue( - str(_("Number of favorites")) in response.content.decode(), - "Test if the counter is in video_info", - ) - print(" ---> test_favorites_count ok") diff --git a/pod/favorite/urls.py b/pod/favorite/urls.py deleted file mode 100644 index d8459b8135..0000000000 --- a/pod/favorite/urls.py +++ /dev/null @@ -1,14 +0,0 @@ -from django.urls import path - -from .views import favorite_button_in_video_info, favorite_list -from .views import favorites_save_reorganisation - -app_name = "favorite" - -urlpatterns = [ - path("", favorite_button_in_video_info, name="add-or-remove"), - path("list/", favorite_list, name="list"), - path( - "save-reorganisation/", favorites_save_reorganisation, name="save-reorganisation" - ), -] diff --git a/pod/favorite/utils.py b/pod/favorite/utils.py deleted file mode 100644 index 301b27de8c..0000000000 --- a/pod/favorite/utils.py +++ /dev/null @@ -1,76 +0,0 @@ -"""Esup-Pod favorite video utilities.""" -from django.contrib.auth.models import User -from django.db.models import Max - -from .models import Favorite -from pod.video.models import Video - - -def user_has_favorite_video(user: User, video: Video) -> bool: - """ - Know if user has the video in favorite. - - Args: - user (:class:`django.contrib.auth.models.User`): The user entity - video (:class:`pod.video.models.Video`): The video entity - - Returns: - bool: True if user has the video in favorite, False otherwise - """ - return Favorite.objects.filter(owner=user, video=video).exists() - - -def user_add_or_remove_favorite_video(user: User, video: Video): - """ - Add or remove the video in favorite list of the user. - - Args: - user (:class:`django.contrib.auth.models.User`): The user entity - video (:class:`pod.video.models.Video`): The video entity - """ - if user_has_favorite_video(user, video): - Favorite.objects.filter(owner=user, video=video).delete() - else: - Favorite.objects.create(owner=user, video=video, rank=get_next_rank(user)) - - -def get_next_rank(user: User) -> int: - """ - Get the next favorite rank for the user. - - Args: - user (:class:`django.contrib.auth.models.User`): The user entity - - Returns: - int: The next rank - """ - last_rank = Favorite.objects.filter(owner=user).aggregate(Max("rank"))["rank__max"] - return last_rank + 1 if last_rank is not None else 1 - - -def get_number_favorites(video: Video): - """Return how much a video has been favorited.""" - return Favorite.objects.filter(video=video).count() - - -def get_all_favorite_videos_for_user(user: User) -> list: - """ - Get all favorite videos for a specific user. - - Args: - user (:class:`django.contrib.auth.models.User`): The user entity - - Returns: - list(:class:`pod.video.models.Video`): The video list - """ - favorite_id = Favorite.objects.filter(owner=user).values_list("video_id", flat=True) - video_list = Video.objects.filter(id__in=favorite_id).extra( - select={"rank": "favorite_favorite.rank"}, - tables=["favorite_favorite"], - where=[ - "favorite_favorite.video_id=video_video.id", - "favorite_favorite.owner_id=%s", - ], - params=[user.id], - ) - return video_list diff --git a/pod/favorite/views.py b/pod/favorite/views.py deleted file mode 100644 index d9c08906d2..0000000000 --- a/pod/favorite/views.py +++ /dev/null @@ -1,121 +0,0 @@ -"""Esup-Pod favorite video Views.""" -from django.contrib.sites.shortcuts import get_current_site -from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator -from django.db import transaction -from django.http import Http404, HttpResponseBadRequest -from django.shortcuts import get_object_or_404, redirect, render -from django.views.decorators.csrf import csrf_protect -from django.contrib.auth.decorators import login_required -from django.utils.translation import ugettext_lazy as _ - -from pod.favorite.models import Favorite -from pod.main.utils import is_ajax -from pod.video.models import Video -from pod.video.views import CURSUS_CODES, get_owners_has_instances -from pod.video.utils import sort_videos_list - -from .utils import user_add_or_remove_favorite_video -from .utils import get_all_favorite_videos_for_user - -import json - - -@csrf_protect -def favorite_button_in_video_info(request): - """Add or remove favorite video when the user click on star button.""" - if request.method == "POST": - video = get_object_or_404( - Video, pk=request.POST.get("video"), sites=get_current_site(request) - ) - if video.is_draft: - return False - user_add_or_remove_favorite_video(request.user, video) - return redirect(request.META["HTTP_REFERER"]) - else: - raise Http404() - - -@login_required(redirect_field_name="referrer") -def favorite_list(request): - """Render the main list of favorite videos.""" - sort_field = request.GET.get("sort", "rank") - sort_direction = request.GET.get("sort_direction") - videos_list = sort_videos_list( - get_all_favorite_videos_for_user(request.user), sort_field, sort_direction - ) - count_videos = len(videos_list) - - page = request.GET.get("page", 1) - full_path = "" - if page: - full_path = ( - request.get_full_path() - .replace("?page=%s" % page, "") - .replace("&page=%s" % page, "") - ) - - paginator = Paginator(videos_list, 12) - try: - videos = paginator.page(page) - except PageNotAnInteger: - videos = paginator.page(1) - except EmptyPage: - videos = paginator.page(paginator.num_pages) - - ownersInstances = get_owners_has_instances(request.GET.getlist("owner")) - - if is_ajax(request): - return render( - request, - "favorite/favorite_video_list.html", - {"videos": videos, "full_path": full_path, "count_videos": count_videos}, - ) - - return render( - request, - "favorite/favorite_videos.html", - { - "page_title": _("My favorite videos"), - "videos": videos, - "count_videos": count_videos, - "types": request.GET.getlist("type"), - "owners": request.GET.getlist("owner"), - "disciplines": request.GET.getlist("discipline"), - "tags_slug": request.GET.getlist("tag"), - "cursus_selected": request.GET.getlist("cursus"), - "full_path": full_path, - "ownersInstances": ownersInstances, - "cursus_list": CURSUS_CODES, - "sort_field": sort_field, - "sort_direction": sort_direction, - }, - ) - - -@csrf_protect -def favorites_save_reorganisation(request): - """Save reorganization when the user click on save button.""" - if request.method == "POST": - json_data = request.POST.get("json-data") - try: - dict_data = json.loads(json_data) - except json.JSONDecodeError: - return HttpResponseBadRequest("JSON au mauvais format") - with transaction.atomic(): - for videos_tuple in dict_data.values(): - fav_video_1 = Favorite.objects.filter( - owner_id=request.user.id, - video_id=Video.objects.only("id").get(slug=videos_tuple[0]).id, - ) - fav_video_2 = Favorite.objects.filter( - owner_id=request.user.id, - video_id=Video.objects.only("id").get(slug=videos_tuple[1]).id, - ) - video_1_rank = fav_video_1[0].rank - video_2_rank = fav_video_2[0].rank - fav_video_1.update(rank=video_2_rank) - fav_video_2.update(rank=video_1_rank) - - return redirect(request.META["HTTP_REFERER"]) - else: - raise Http404() diff --git a/pod/locale/fr/LC_MESSAGES/django.mo b/pod/locale/fr/LC_MESSAGES/django.mo index 2503a5d8e6..e925ca5ecd 100644 Binary files a/pod/locale/fr/LC_MESSAGES/django.mo and b/pod/locale/fr/LC_MESSAGES/django.mo differ diff --git a/pod/locale/fr/LC_MESSAGES/django.po b/pod/locale/fr/LC_MESSAGES/django.po index 81c0f70069..3c9a9e4510 100644 --- a/pod/locale/fr/LC_MESSAGES/django.po +++ b/pod/locale/fr/LC_MESSAGES/django.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: Pod\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-05 15:50+0200\n" +"POT-Creation-Date: 2023-08-21 08:32+0000\n" "PO-Revision-Date: \n" "Last-Translator: obado \n" "Language-Team: Pod Team pod@esup-portail.org\n" @@ -101,8 +101,6 @@ msgid "Picture" msgstr "Image" #: pod/authentication/models.py pod/live/models.py pod/meeting/models.py -#: pod/playlist/models.py -#: pod/playlist/templates/playlist/playlist_element_list.html #: pod/podfile/models.py pod/video/admin.py pod/video/models.py #: pod/video_search/templates/search/search.html msgid "Owner" @@ -184,8 +182,7 @@ msgstr "Changer votre image de profil" #: pod/main/templates/navbar.html pod/main/templates/navbar_collapse.html #: pod/meeting/templates/meeting/add_or_edit.html #: pod/meeting/templates/meeting/my_meetings.html -#: pod/playlist/templates/playlist/playlist_video_list.html -#: pod/playlist/templates/playlist_player-iframe.html +#: pod/playlist/templates/playlist/playlist-list-modal.html #: pod/podfile/templates/podfile/customfilewidget.html #: pod/podfile/templates/podfile/home_content.html #: pod/podfile/templates/podfile/userfolder.html @@ -214,6 +211,9 @@ msgstr "Fermer" #: pod/meeting/templates/meeting/delete.html #: pod/meeting/templates/meeting/invite.html #: pod/meeting/templates/meeting/join.html pod/meeting/views.py +#: pod/playlist/templates/playlist/add_or_edit.html +#: pod/playlist/templates/playlist/delete.html +#: pod/playlist/templates/playlist/protected-playlist-form.html #: pod/playlist/views.py pod/recorder/templates/recorder/add_recording.html #: pod/recorder/templates/recorder/record_delete.html pod/recorder/views.py #: pod/video/templates/channel/channel_edit.html @@ -242,7 +242,9 @@ msgstr "Une ou plusieurs erreurs ont été trouvées dans le formulaire." #: pod/meeting/templates/meeting/delete.html #: pod/meeting/templates/meeting/invite.html #: pod/meeting/templates/meeting/join.html -#: pod/playlist/templates/playlist/playlist_video_list.html +#: pod/playlist/templates/playlist/add_or_edit.html +#: pod/playlist/templates/playlist/delete.html +#: pod/playlist/templates/playlist/protected-playlist-form.html #: pod/recorder/templates/recorder/add_recording.html #: pod/recorder/templates/recorder/record_delete.html #: pod/video/templates/channel/channel_edit.html @@ -358,8 +360,8 @@ msgid "URL of the recording thumbnail of the BBB presentation." msgstr "" "URL de la vignette correspondant à l’enregistrement de la présentation BBB." -#: pod/bbb/models.py pod/favorite/models.py pod/import_video/models.py -#: pod/meeting/models.py pod/recorder/models.py +#: pod/bbb/models.py pod/import_video/models.py pod/meeting/models.py +#: pod/playlist/models.py pod/recorder/models.py msgid "User" msgstr "Utilisateur" @@ -380,6 +382,7 @@ msgid "Meeting" msgstr "Session" #: pod/bbb/models.py pod/meeting/apps.py +#: pod/stats/templates/stats/meeting-stats-view.html msgid "Meetings" msgstr "Sessions" @@ -424,7 +427,7 @@ msgstr "Participants" #: pod/bbb/models.py pod/import_video/models.py pod/live/forms.py #: pod/live/models.py pod/meeting/forms.py pod/meeting/models.py -#: pod/video_search/forms.py +#: pod/stats/templates/stats/utils/video-stats.html pod/video_search/forms.py msgid "Start date" msgstr "Date de début" @@ -433,7 +436,7 @@ msgid "Start date of the live." msgstr "Date de début du direct." #: pod/bbb/models.py pod/live/forms.py pod/live/models.py -#: pod/video_search/forms.py +#: pod/stats/templates/stats/utils/video-stats.html pod/video_search/forms.py msgid "End date" msgstr "Date de fin" @@ -744,8 +747,7 @@ msgstr "Désolé, aucune session BigBlueButton en cours n’a été trouvée" #: pod/bbb/templates/bbb/live_record_list.html #: pod/bbb/templates/bbb/record_list.html -#: pod/favorite/templates/favorite/favorite_video_list.html -#: pod/playlist/templates/playlist/playlist_list.html +#: pod/playlist/templates/playlist/playlist-videos-list.html #: pod/recorder/templates/recorder/record_list.html #: pod/video/templates/videos/video_list.html msgid "More" @@ -753,9 +755,8 @@ msgstr "Plus" #: pod/bbb/templates/bbb/live_record_list.html #: pod/bbb/templates/bbb/record_list.html -#: pod/favorite/templates/favorite/favorite_video_list.html #: pod/live/templates/live/events_list.html pod/main/templates/loader.html -#: pod/playlist/templates/playlist/playlist_list.html +#: pod/playlist/templates/playlist/playlist-videos-list.html #: pod/podfile/templates/podfile/home_content.html #: pod/podfile/templates/podfile/list_folder_files.html #: pod/recorder/templates/recorder/record_list.html @@ -816,7 +817,8 @@ msgid "File to import" msgstr "Fichier à importer" #: pod/chapter/models.py pod/completion/models.py pod/enrichment/models.py -#: pod/video/models.py pod/video_encode_transcript/utils.py +#: pod/playlist/templates/playlist/playlist_card.html pod/video/models.py +#: pod/video_encode_transcript/utils.py msgid "video" msgstr "vidéo" @@ -825,7 +827,8 @@ msgstr "vidéo" msgid "title" msgstr "titre" -#: pod/chapter/models.py pod/enrichment/models.py pod/video/models.py +#: pod/chapter/models.py pod/enrichment/models.py pod/playlist/models.py +#: pod/video/models.py msgid "slug" msgstr "titre court" @@ -892,7 +895,7 @@ msgstr "Une ou plusieurs erreurs ont été trouvées dans le formulaire :" #: pod/enrichment/templates/enrichment/group_enrichment.html #: pod/import_video/templates/import_video/add_or_edit.html #: pod/meeting/templates/meeting/add_or_edit.html -#: pod/playlist/templates/playlist.html +#: pod/playlist/templates/playlist/add_or_edit.html #: pod/recorder/templates/recorder/add_recording.html #: pod/video/templates/channel/channel_edit.html #: pod/video/templates/channel/form_theme.html @@ -908,7 +911,7 @@ msgstr "Sauvegarder" #: pod/completion/templates/overlay/form_overlay.html #: pod/completion/templates/track/form_track.html #: pod/enrichment/templates/enrichment/form_enrichment.html -#: pod/favorite/templates/favorite/favorite_videos.html +#: pod/playlist/templates/playlist/playlist.html #: pod/video/templates/channel/form_theme.html #: pod/video/templates/videos/category_modal.html #: pod/video/templates/videos/video_note_comments_display.html @@ -934,7 +937,6 @@ msgstr "Liste des chapitres" #: pod/completion/templates/overlay/list_overlay.html #: 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 msgid "Title" @@ -946,7 +948,6 @@ msgstr "Titre" #: pod/completion/templates/overlay/list_overlay.html #: pod/completion/templates/track/list_track.html #: pod/enrichment/templates/enrichment/list_enrichment.html -#: pod/playlist/templates/playlist/playlist_element_list.html #: pod/video/templates/channel/list_theme.html msgid "Actions" msgstr "Actions" @@ -977,7 +978,7 @@ msgstr "Supprimer le chapitre" #: pod/enrichment/templates/enrichment/list_enrichment.html #: pod/live/templates/live/event_delete.html #: pod/meeting/templates/meeting/delete.html -#: pod/playlist/templates/playlist.html +#: pod/playlist/templates/playlist/delete.html #: pod/recorder/templates/recorder/record_delete.html #: pod/video/templates/channel/list_theme.html #: pod/video/templates/videos/category_modal.html @@ -1181,9 +1182,9 @@ msgstr "" "Il existe déjà un contributeur avec le même nom et le même rôle dans cette " "liste." -#: pod/completion/models.py pod/enrichment/models.py pod/favorite/models.py -#: pod/playlist/models.py pod/recorder/models.py pod/video/models.py -#: pod/video_encode_transcript/models.py +#: pod/completion/models.py pod/enrichment/models.py pod/playlist/models.py +#: pod/recorder/models.py pod/video/models.py +#: pod/video/templates/videos/video.html pod/video_encode_transcript/models.py msgid "Video" msgstr "Vidéo" @@ -1191,7 +1192,7 @@ msgstr "Vidéo" #: pod/completion/templates/document/list_document.html #: pod/enrichment/models.py #: pod/enrichment/templates/enrichment/video_enrichment.html -#: pod/playlist/templates/playlist_player.html pod/podfile/models.py +#: pod/podfile/models.py msgid "Document" msgstr "Document" @@ -1317,8 +1318,7 @@ msgstr "bas à gauche" msgid "left" msgstr "gauche" -#: pod/completion/models.py pod/live/models.py pod/playlist/models.py -#: pod/video/models.py +#: pod/completion/models.py pod/live/models.py pod/video/models.py msgid "Slug" msgstr "Titre court" @@ -1339,8 +1339,6 @@ msgid "Content" msgstr "Contenu" #: pod/completion/models.py pod/completion/templates/overlay/list_overlay.html -#: pod/playlist/models.py -#: pod/playlist/templates/playlist/playlist_element_list.html msgid "Position" msgstr "Position" @@ -1484,7 +1482,6 @@ msgid "Remove the subtitle or caption files" msgstr "Supprimer les fichiers de sous-titres ou de légendes" #: pod/completion/templates/track/list_track.html -#: pod/playlist/templates/playlist/playlist_element_list.html msgid "Remove" msgstr "Retirer" @@ -1716,8 +1713,8 @@ msgstr "" #: pod/completion/templates/video_completion.html msgid "Subtitles and/or caption(s) files must be in \".vtt\" format." msgstr "" -"Les fichiers de sous-titres et/ou de légendes doivent être au format \"." -"vtt\"." +"Les fichiers de sous-titres et/ou de légendes doivent être au format \".vtt" +"\"." #: pod/completion/templates/video_completion.html msgid "You can use" @@ -1822,6 +1819,7 @@ msgid "Total video duration" msgstr "Durée totale de la vidéo" #: pod/cut/templates/video_cut.html +#: pod/playlist/templates/playlist/filter_aside.html #: pod/video/templates/videos/filter_aside.html msgid "Reset" msgstr "Réinitialiser" @@ -1950,7 +1948,7 @@ msgstr "Type" #: pod/enrichment/models.py #: pod/enrichment/templates/enrichment/video_enrichment.html pod/main/models.py -#: pod/playlist/templates/playlist_player.html pod/podfile/models.py +#: pod/podfile/models.py msgid "Image" msgstr "Image" @@ -1960,7 +1958,6 @@ msgstr "Intégrer un document (PDF, texte, html)" #: pod/enrichment/models.py #: pod/enrichment/templates/enrichment/video_enrichment.html -#: pod/playlist/templates/playlist_player.html msgid "Richtext" msgstr "Texte riche" @@ -2074,8 +2071,8 @@ msgid "" msgstr "" "Les champs \"Début\" et \"Fin\" doivent contenir des valeurs en secondes. " "Lancez la lecture de la vidéo, mettez sur pause et cliquez sur \"Récupérer " -"le temps depuis le lecteur\" pour renseigner automatiquement le champ " -"\"Début\". Vous pouvez le faire également pour remplir le champ \"Fin\"." +"le temps depuis le lecteur\" pour renseigner automatiquement le champ \"Début" +"\". Vous pouvez le faire également pour remplir le champ \"Fin\"." #: pod/enrichment/templates/enrichment/edit_enrichment.html msgid "You cannot overlap enrichments." @@ -2107,8 +2104,6 @@ msgstr "Supprimer l’enrichissement" #: pod/enrichment/templates/enrichment/video_enrichment-iframe.html #: pod/enrichment/templates/enrichment/video_enrichment.html -#: pod/playlist/templates/playlist_player-iframe.html -#: pod/playlist/templates/playlist_player.html msgid "Enriched" msgstr "Enrichi" @@ -2118,29 +2113,24 @@ msgid "Added by" msgstr "Ajouté par" #: pod/enrichment/templates/enrichment/video_enrichment.html -#: pod/playlist/templates/playlist_player.html msgid "Informations" msgstr "Informations" #: pod/enrichment/templates/enrichment/video_enrichment.html -#: pod/playlist/templates/playlist_player.html msgid "To help you, the different types of enrichments have specific colors:" msgstr "" "Pour vous aider, les différents types d’enrichissements ont des couleurs " "spécifiques :" #: pod/enrichment/templates/enrichment/video_enrichment.html -#: pod/playlist/templates/playlist_player.html msgid "Weblink" msgstr "Lien web" #: pod/enrichment/templates/enrichment/video_enrichment.html -#: pod/playlist/templates/playlist_player.html msgid "Embed" msgstr "Intégrer" #: pod/enrichment/templates/enrichment/video_enrichment.html -#: pod/playlist/templates/playlist_player.html msgid "They are visible on the video playback bar." msgstr "Ils sont visibles sur la barre de lecture de la vidéo." @@ -2148,85 +2138,6 @@ msgstr "Ils sont visibles sur la barre de lecture de la vidéo." msgid "You cannot enrich this video." msgstr "Vous ne pouvez pas enrichir cette vidéo." -#: pod/favorite/apps.py pod/favorite/models.py -msgid "Favorite videos" -msgstr "Vidéos favorites" - -#: pod/favorite/models.py pod/recorder/models.py pod/video/models.py -#: pod/video/templates/videos/video_sort_select.html -msgid "Date added" -msgstr "Date d’ajout" - -#: pod/favorite/models.py pod/video/templates/videos/video_sort_select.html -msgid "Rank" -msgstr "Rang" - -#: pod/favorite/models.py -msgid "Favorite video" -msgstr "Vidéo favorite" - -#: pod/favorite/templates/favorite/favorite_video_list.html -#: pod/video/templates/videos/video_list.html -msgid "Sorry, no video found." -msgstr "Désolé, aucune vidéo trouvée." - -#: pod/favorite/templates/favorite/favorite_videos.html -#: pod/video/templates/channel/channel.html -#: pod/video/templates/videos/my_videos.html -#: pod/video/templates/videos/videos.html -#: pod/video_search/templates/search/search.html -#, python-format -msgid "%(counter)s video found" -msgid_plural "%(counter)s videos found" -msgstr[0] "%(counter)s vidéo trouvée" -msgstr[1] "%(counter)s vidéos trouvées" - -#: pod/favorite/templates/favorite/favorite_videos.html -#: pod/favorite/tests/test_views.py pod/favorite/views.py -#: pod/main/templates/navbar.html -msgid "My favorite videos" -msgstr "Mes vidéos favorites" - -#: pod/favorite/templates/favorite/favorite_videos.html -msgid "Reorganize your favorite videos" -msgstr "Réorganiser vos vidéos favorites" - -#: pod/favorite/templates/favorite/favorite_videos.html -msgid "Reorganize" -msgstr "Réorganiser" - -#: pod/favorite/templates/favorite/favorite_videos.html -msgid "Sort by descending rank before you can rearrange" -msgstr "Trier par ordre décroissant avant de pouvoir réorganiser" - -#: pod/favorite/templates/favorite/favorite_videos.html -msgid "Sort by descending rank" -msgstr "Trier par ordre décroissant" - -#: pod/favorite/templates/favorite/favorite_videos.html -msgid "Help - Drag & Drop" -msgstr "Aide - Glisser & Déposer" - -#: pod/favorite/templates/favorite/favorite_videos.html -msgid "Select the video to move by clicking and holding." -msgstr "" -"Sélectionnez la vidéo que vous souhaitez en cliquant et maintenant le bouton " -"de la souris." - -#: pod/favorite/templates/favorite/favorite_videos.html -msgid "While holding down the video, drag it to the desired location." -msgstr "" -"Tout en maintenant le bouton de la souris enfoncé, faites-la glisser à " -"l’endroit que vous souhaitez." - -#: pod/favorite/templates/favorite/favorite_videos.html -msgid "Drop the video on another to swap their position." -msgstr "Déposez la vidéo sur une autre pour échanger leur position." - -#: pod/favorite/tests/test_views.py pod/video/templates/videos/video-info.html -msgid "Number of favorites" -msgstr "Nombre de favoris" - #: pod/import_video/apps.py msgid "Import External Video" msgstr "Importer une vidéo externe" @@ -2448,6 +2359,7 @@ msgstr "Conditions d’utilisation de YouTube" #: pod/live/templates/live/filter_aside.html #: pod/meeting/templates/meeting/filter_aside.html #: pod/meeting/templates/meeting/filter_aside_recording.html +#: pod/playlist/templates/playlist/filter_aside.html #: pod/video/templates/videos/filter_aside.html msgid "Filters" msgstr "Filtres" @@ -2501,6 +2413,7 @@ msgstr "" #: pod/import_video/templates/import_video/list.html pod/main/forms.py #: pod/meeting/forms.py pod/meeting/templates/meeting/internal_recordings.html +#: pod/playlist/templates/playlist/playlist_sort_select.html #: pod/podfile/models.py pod/podfile/templates/podfile/home_content.html #: pod/video_encode_transcript/models.py msgid "Name" @@ -2639,8 +2552,8 @@ msgid "" "This video was uploaded to Pod; its origin is %(type)s : %(url)s" msgstr "" -"Cette vidéo a été téléversée sur Pod; son origine est %(type)s : %(url)s" +"Cette vidéo a été téléversée sur Pod; son origine est %(type)s : %(url)s" #: pod/import_video/views.py pod/meeting/views.py msgid "Try changing the record type or address for this recording." @@ -2651,8 +2564,8 @@ msgstr "" #: pod/import_video/views.py #, python-format msgid "" -"This video '%(name)s' was uploaded to Pod; its origin is Youtube : %(url)s" +"This video '%(name)s' was uploaded to Pod; its origin is Youtube : %(url)s" msgstr "" "Cette vidéo « %(name)s » a été téléversée sur Pod; son origine est Youtube : " "%(url)s" @@ -2810,7 +2723,8 @@ msgstr "Erreur de planification." msgid "An event is already planned at these dates" msgstr "Un évenement est déjà planifié à cette date" -#: pod/live/forms.py pod/meeting/forms.py pod/video/forms.py +#: pod/live/forms.py pod/meeting/forms.py pod/playlist/forms.py +#: pod/playlist/models.py pod/video/forms.py msgid "Password" msgstr "Mot de passe" @@ -2826,8 +2740,8 @@ msgstr "Bâtiment" msgid "Broadcaster device" msgstr "Matériel de captation" -#: pod/live/forms.py pod/meeting/forms.py pod/recorder/forms.py -#: pod/video/forms.py +#: pod/live/forms.py pod/meeting/forms.py pod/playlist/forms.py +#: pod/recorder/forms.py pod/video/forms.py msgid "I agree" msgstr "J’accepte" @@ -2965,7 +2879,9 @@ msgstr "" "informations nécessaires, et mettre en forme le résultat en utilisant la " "barre d’outils." -#: pod/live/models.py pod/meeting/models.py pod/video/forms.py +#: pod/live/models.py pod/meeting/models.py pod/playlist/models.py +#: pod/playlist/templates/playlist/playlist-informations-card.html +#: pod/stats/templates/stats/playlist-stats-view.html pod/video/forms.py #: pod/video/models.py msgid "Additional owners" msgstr "Propriétaires additionnels" @@ -3169,8 +3085,7 @@ msgstr "Prochains évènements" msgid "Manage broadcaster" msgstr "Gérer le diffuseur" -#: pod/live/templates/live/direct.html pod/playlist/templates/playlist.html -#: pod/playlist/templates/playlist/playlist_list.html +#: pod/live/templates/live/direct.html #: pod/video/templates/videos/video_edit.html msgid "Edit" msgstr "Éditer" @@ -3244,10 +3159,11 @@ msgstr "Intégrer/Partager" #: pod/live/templates/live/event-form.html msgid "This event is protected by password, please fill in and click send." msgstr "" -"Cet évènement est protégée par un mot de passe, veuillez remplir le " +"Cet évènement est protégé par un mot de passe, veuillez remplir le " "formulaire et cliquez sur envoyer." #: pod/live/templates/live/event-form.html +#: pod/playlist/templates/playlist/protected-playlist-form.html #: pod/video/templates/videos/video-form.html msgid "Password required" msgstr "Mot de passe requis" @@ -3258,6 +3174,7 @@ msgstr "Mot de passe requis" #: pod/live/templates/live/filter_aside.html pod/main/templates/contact_us.html #: pod/meeting/templates/meeting/invite.html #: pod/meeting/templates/meeting/join.html +#: pod/playlist/templates/playlist/protected-playlist-form.html #: pod/video/templates/videos/video-form.html #: pod/video_search/templates/search/search.html msgid "Send" @@ -3456,9 +3373,7 @@ msgstr "Éditer l’évènement" msgid "Delete the event" msgstr "Supprimer l’évènement" -#: pod/live/templates/live/event_card.html -#: pod/playlist/templates/playlist/playlist_video_card.html -#: pod/video/templates/videos/card.html +#: pod/live/templates/live/event_card.html pod/video/templates/videos/card.html msgid "This content is in draft." msgstr "Ce contenu est en mode brouillon." @@ -3499,6 +3414,7 @@ msgstr "Pour supprimer l’évènement, veuillez cocher et cliquer sur envoyer." #: pod/live/templates/live/event_delete.html #: pod/meeting/templates/meeting/delete.html +#: pod/playlist/templates/playlist/delete.html #: pod/recorder/templates/recorder/record_delete.html #: pod/video/templates/videos/video_delete.html msgid "Agree required" @@ -3679,8 +3595,7 @@ msgstr "Vous ne pouvez pas accèder à cette page." msgid "You cannot watch this event." msgstr "Vous ne pouvez pas accèder à cet évènement en direct." -#: pod/live/views.py pod/playlist/templates/playlist/playlist_video_list.html -#: pod/video/views.py +#: pod/live/views.py pod/playlist/views.py pod/video/views.py msgid "The password is incorrect." msgstr "Le mot de passe est incorrect." @@ -4496,7 +4411,7 @@ msgstr "Afficher/masquer le menu latéral" msgid "Breadcrumb" msgstr "Fil d’Ariane" -#: pod/main/templates/base.html pod/playlist/templates/playlist_player.html +#: pod/main/templates/base.html msgid "Home" msgstr "Accueil" @@ -4557,6 +4472,10 @@ msgstr "Version" msgid "videos availables" msgstr "vidéos disponibles" +#: pod/main/templates/footer.html +msgid "See more statistics" +msgstr "Voir plus de statistiques" + #: pod/main/templates/mail/mail.html pod/main/templates/mail/mail_sender.html msgid "Hello" msgstr "Bonjour" @@ -4606,11 +4525,16 @@ msgstr "Contactez nous" msgid "Toggle navigation" msgstr "Basculer le menu" -#: pod/main/templates/navbar.html pod/recorder/models.py pod/video/forms.py +#: pod/main/templates/navbar.html pod/recorder/models.py +#: pod/stats/templates/stats/channel-stats-view.html pod/video/forms.py #: pod/video/models.py msgid "Channels" msgstr "Chaînes" +#: pod/main/templates/navbar.html +msgid "Promoted playlists" +msgstr "Listes de lecture promues" + #: pod/main/templates/navbar.html msgid "Some features are unavailable" msgstr "Certaines fonctionnalités sont indisponibles" @@ -4661,6 +4585,14 @@ msgstr "Police ‘Open Dyslexic’" msgid "Add your picture" msgstr "Ajouter votre image de profil" +#: pod/main/templates/navbar.html +msgid "My playlists" +msgstr "Mes listes de lecture" + +#: pod/main/templates/navbar.html pod/playlist/tests/test_views.py +msgid "My favorite videos" +msgstr "Mes vidéos favorites" + #: pod/main/templates/navbar.html msgid "Video Record" msgstr "Enregistreur" @@ -4675,11 +4607,6 @@ msgstr "Importer une vidéo externe" msgid "My channels" msgstr "Mes chaînes" -#: pod/main/templates/navbar.html pod/playlist/templates/my_playlists.html -#: pod/playlist/templates/playlist.html pod/playlist/views.py -msgid "My playlists" -msgstr "Mes listes de lecture" - #: pod/main/templates/navbar.html pod/podfile/templates/podfile/home.html #: pod/podfile/views.py msgid "My files" @@ -4695,6 +4622,29 @@ msgstr "Revendiquer un enregistrement" msgid "Log out" msgstr "Déconnexion" +#: pod/main/templates/navbar.html +msgid "Your statistics" +msgstr "Vos statistiques" + +#: pod/main/templates/navbar.html +#: pod/stats/templates/stats/channel-stats-view.html +#: pod/stats/templates/stats/general-stats-view.html +#: pod/stats/templates/stats/playlist-stats-view.html +#: pod/stats/templates/stats/user-stats-view.html +#: pod/stats/templates/stats/video-stats-view.html +msgid "Number of videos" +msgstr "Nombre de vidéos" + +#: pod/main/templates/navbar.html +#: pod/stats/templates/stats/playlist-stats-view.html +#: pod/stats/templates/stats/user-stats-view.html +msgid "Number of playlists" +msgstr "Nombre de listes de lecture" + +#: pod/main/templates/navbar.html +msgid "See more" +msgstr "En savoir plus" + #: pod/main/templates/navbar_collapse.html #, python-format msgid "%(counter)s Channel" @@ -4710,8 +4660,6 @@ msgstr[0] "%(counter)s Thème" msgstr[1] "%(counter)s Thèmes" #: pod/main/templates/navbar_collapse.html -#: pod/playlist/templates/playlist/playlist_list.html -#: pod/playlist/templates/playlist/playlist_video_list.html #: pod/video/templates/channel/channel.html #, python-format msgid "%(counter)s video" @@ -4755,9 +4703,7 @@ msgstr "rejoindre" msgid "Recurring" msgstr "Récurrence" -#: pod/meeting/forms.py -#: pod/playlist/templates/playlist/playlist_element_list.html -#: pod/video/feeds.py pod/video/models.py +#: pod/meeting/forms.py pod/video/feeds.py pod/video/models.py #: pod/video/templates/videos/video_sort_select.html msgid "Duration" msgstr "Durée" @@ -4811,7 +4757,7 @@ msgstr "Récurrence" msgid "Record session" msgstr "Enregistrement" -#: pod/meeting/forms.py pod/video/forms.py +#: pod/meeting/forms.py pod/playlist/forms.py pod/video/forms.py msgid "Owner of the video cannot be an additional owner too" msgstr "" "Le propriétaire de la video ne peut pas être propriétaire additionnel en " @@ -5280,7 +5226,7 @@ msgid "Delete the meeting" msgstr "Supprimer la réunion" #: pod/meeting/templates/meeting/meeting_card.html -msgid "Acces to this meeting is restricted" +msgid "Access to this meeting is restricted" msgstr "L’accès à cette réunion est restreint" #: pod/meeting/templates/meeting/meeting_card.html @@ -5444,16 +5390,16 @@ msgid "" msgstr "" "\n" "

Bonjour,\n" -"

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

\n" +"

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

\n" "

Date de début : %(start_date_time)s

\n" "

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

\n" "

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

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

\n" -"

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

\n" +"

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

\n" "

Cordialement

\n" " " @@ -5479,8 +5425,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" " " @@ -5502,215 +5448,425 @@ msgid "Impossible to create the internal recording" msgstr "Impossible de créer l’enregistrement" #: pod/playlist/apps.py pod/playlist/models.py +#: pod/playlist/templates/playlist/add_or_edit.html +#: pod/playlist/templates/playlist/delete.html +#: pod/playlist/templates/playlist/playlist.html +#: pod/playlist/templates/playlist/playlists.html +#: pod/playlist/templates/playlist/protected-playlist-form.html +#: pod/playlist/views.py pod/stats/templates/stats/playlist-stats-view.html msgid "Playlists" msgstr "Listes de lecture" -#: pod/playlist/models.py -msgid "Short description of the playlist." -msgstr "Courte description de la liste de lecture." +#: pod/playlist/apps.py pod/playlist/signals.py +msgid "Your favorites videos." +msgstr "Vos vidéos favorites." -#: pod/playlist/models.py pod/video/models.py -msgid "Visible" -msgstr "Visible" +#: pod/playlist/forms.py +msgid "General informations" +msgstr "Informations générales" + +#: pod/playlist/forms.py +msgid "Security informations" +msgstr "Informations de sécurité" + +#: pod/playlist/forms.py pod/playlist/models.py +msgid "Please choose a password if this playlist is password-protected." +msgstr "" +"Veuillez choisir un mot de passe si cette playlist est protégée par un mot " +"de passe." + +#: pod/playlist/forms.py pod/playlist/models.py +msgid "Promoted" +msgstr "Promue" + +#: pod/playlist/forms.py pod/playlist/models.py +msgid "" +"Selecting this setting causes your playlist to be promoted on the page " +"listing promoted public playlists. However, if this setting is deactivated, " +"your playlist will still be accessible to everyone.
For general use, we " +"recommend that you leave this setting disabled." +msgstr "" +"En sélectionnant ce paramètre, votre liste de lecture sera mise en avant " +"dans la page listant les listes de lecture publiques promues. En revanche, " +"si ce paramètre est désactivé, votre liste de lecture restera tout de même " +"accessible par tous.
Pour une utilisation générale, il est conseillé de " +"laisser ce paramètre désactivé." + +#: pod/playlist/forms.py +#, fuzzy, python-brace-format +#| msgid "You cannot create a playlist named \"{FAVORITE_PLAYLIST_NAME}\"" +msgid "You cannot create a playlist named \"{FAVORITE_PLAYLIST_NAME}\"" +msgstr "Vous ne pouvez créer une liste de lecture nommée \"Favoris\"" + +#: pod/playlist/forms.py +msgid "Remove playlist cannot be undone" +msgstr "La suppression de réunion est définitive" + +#: pod/playlist/models.py +#: pod/playlist/templates/playlist/playlist_visibility_icon.html +#: pod/playlist/utils.py pod/video/models.py +#: pod/video/templates/videos/video_note_comments_display.html +#: pod/video/templates/videos/video_note_display.html +msgid "Public" +msgstr "Public" #: pod/playlist/models.py -msgid "If checked, the playlist can be visible to users other than the owner." -msgstr "Si coché, cette liste de lecture sera visible aux autres utilisateurs." +#: pod/playlist/templates/playlist/playlist_visibility_icon.html +#: pod/playlist/utils.py +msgid "Password-protected" +msgstr "Protégé par un mot de passe" #: pod/playlist/models.py -#: pod/playlist/templates/playlist/playlist_video_list.html -#: pod/playlist/templates/playlist_player.html +#: pod/playlist/templates/playlist/playlist_visibility_icon.html +#: pod/playlist/utils.py +msgid "Private" +msgstr "Privé" + +#: pod/playlist/models.py pod/playlist/tests/test_models.py +#: pod/playlist/views.py pod/video/templates/videos/video.html msgid "Playlist" msgstr "Liste 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." +msgid "Please choose a name between 1 and 250 characters." +msgstr "Veuillez entrer un nom entre 2 et 200 caractères." + +#: pod/playlist/models.py +msgid "Please choose a description. This description is empty by default." +msgstr "Veuillez choisir une description. Celle-ci est vide par défaut." + +#: pod/playlist/models.py pod/playlist/templates/playlist/filter_aside.html +#: pod/playlist/templates/playlist/playlist-informations-card.html +#: pod/stats/templates/stats/playlist-stats-view.html +msgid "Right of access" +msgstr "Droit d'accès" + +#: pod/playlist/models.py +msgid "" +"\n" +" Please chosse a right of access among 'public', 'password-" +"protected', 'private'.\n" +" " +msgstr "" +"\n" +" Veuillez choisir un droit d'accès entre 'public', 'protégée par " +"un mot de passe', 'privée'.\n" +" " + +#: pod/playlist/models.py pod/video/templates/videos/video-info.html +msgid "Autoplay" +msgstr "Lecture automatique" + +#: pod/playlist/models.py +msgid "Please choose if this playlist is an autoplay playlist or not." +msgstr "Veuillez choisir si cette playlist est en lecture automatique ou non." + +#: pod/playlist/models.py +msgid "Editable" +msgstr "Éditable" + +#: pod/playlist/models.py +msgid "Please choose if this playlist is editable or not." +msgstr "Veuillez choisir si cette playlist est éditable ou non." + +#: pod/playlist/models.py +msgid "You can add additional owners to the playlist." +msgstr "Vous pouvez ajouter des propriétaires additionnels à la playlist." + +#: pod/playlist/models.py +msgid "Date created" +msgstr "Date de création" + +#: pod/playlist/models.py +msgid "Date updated" +msgstr "Date de mise à jour" + +#: pod/playlist/models.py pod/recorder/models.py pod/video/models.py +#: pod/video/templates/videos/video_sort_select.html +msgid "Date added" +msgstr "Date d’ajout" + +#: pod/playlist/models.py pod/video/templates/videos/video_sort_select.html +msgid "Rank" +msgstr "Rang" #: pod/playlist/models.py -msgid "Playlist element" +msgid "Playlist content" msgstr "Élément de liste de lecture" #: pod/playlist/models.py -msgid "Playlist elements" +msgid "Playlist contents" msgstr "Éléments de liste de lecture" -#: pod/playlist/models.py pod/playlist/views.py -msgid "A video in draft mode cannot be added to a playlist." -msgstr "" -"Une vidéo en mode brouillon ne peut être ajoutée à une liste de lecture." +#: pod/playlist/templates/playlist/add_or_edit.html +#: pod/playlist/templates/playlist/playlist_link.html +#: pod/playlist/tests/test_views.py pod/playlist/views.py +msgid "Edit the playlist" +msgstr "Éditer la liste de lecture" -#: pod/playlist/models.py pod/playlist/views.py -msgid "A video with a password cannot be added to a playlist." -msgstr "" -"Une vidéo avec mot de passe ne peut être ajoutée à une liste de lecture." +#: pod/playlist/templates/playlist/add_or_edit.html +#: pod/playlist/templates/playlist/playlists.html +#: pod/playlist/tests/test_views.py pod/playlist/views.py +msgid "Add a playlist" +msgstr "Ajouter une liste de lecture" + +#: pod/playlist/templates/playlist/button_start_playlist.html +msgid "Start the playlist" +msgstr "Démarrer la liste de lecture" -#: pod/playlist/templates/my_playlists.html +#: pod/playlist/templates/playlist/delete.html #, python-format -msgid "%(counter)s playlist found" -msgid_plural "%(counter)s playlists found" -msgstr[0] "%(counter)s liste de lecture trouvée" -msgstr[1] "%(counter)s listes de lecture trouvées" +msgid "Delete the playlist %(name)s" +msgstr "Supprimer la liste de lecture %(name)s" -#: pod/playlist/templates/my_playlists.html -msgid "No playlist found" -msgstr "Aucune liste de lecture trouvée" +#: pod/playlist/templates/playlist/delete.html +msgid "Back to my playlists" +msgstr "Retour à mes listes de lecture" -#: 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." +#: pod/playlist/templates/playlist/delete.html +msgid "To delete the playlist, please check the box in and click delete." 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." +"Pour supprimer la liste de lecture, veuillez cocher la case et cliquer sur " +"supprimer." -#: pod/playlist/templates/my_playlists.html -#: pod/playlist/templates/playlist.html -#: pod/playlist/templates/playlist/playlist_list.html -#: pod/playlist/tests/test_views.py -msgid "Add a new playlist" -msgstr "Ajouter une nouvelle liste de lecture" +#: pod/playlist/templates/playlist/filter_aside.html +msgid "See my private playlists" +msgstr "Voir mes listes de lecture privées" -#: pod/playlist/templates/my_playlists.html -msgid "" -"This is the page of your playlists. Here you can create, edit or delete them." -msgstr "" -"C’est la page de vos listes de lecture. Ici vous pouvez les créer, les " -"éditer ou les supprimer." +#: pod/playlist/templates/playlist/filter_aside.html +msgid "See my password-protected playlists" +msgstr "Voir mes listes de lecture protégées par un mot de passe" -#: pod/playlist/templates/my_playlists.html -msgid "" -"A playlist with the eye symbol means that this playlist is visible to all " -"users when they view this page." -msgstr "" -"Une liste de lecture avec un symbole œil signifie que cette liste est " -"visible à tous les utilisateurs qui visiteront cette page." +#: pod/playlist/templates/playlist/filter_aside.html +msgid "See my public playlists" +msgstr "Voir mes listes de lecture publiques" -#: pod/playlist/templates/playlist.html pod/playlist/tests/test_views.py -msgid "Editing the playlist" -msgstr "Éditer la liste de lecture" +#: pod/playlist/templates/playlist/filter_aside.html +msgid "See my playlists" +msgstr "Voir mes listes de lecture" -#: pod/playlist/templates/playlist.html -msgid "This playlist has no videos yet." -msgstr "Cette liste de lecture ne dispose pas encore de vidéos." +#: pod/playlist/templates/playlist/filter_aside.html +msgid "See playlists I can contribute" +msgstr "Voir les listes de lecture additionnelles" -#: pod/playlist/templates/playlist.html -msgid "Back to my playlists" -msgstr "Retour à mes listes de lecture" +#: pod/playlist/templates/playlist/filter_aside.html +msgid "See all public playlists" +msgstr "Voir toutes les listes de lecture publiques" -#: pod/playlist/templates/playlist/player_controls.html -msgid "Repeat the playlist" -msgstr "Répéter la liste de lecture" +#: pod/playlist/templates/playlist/filter_aside.html +msgid "See all promoted playlists" +msgstr "Voir toutes les listes de lecture promues" -#: pod/playlist/templates/playlist/player_controls.html -msgid "Switch to next video automatically" -msgstr "Passer automatiquement à la prochaine vidéo" +#: pod/playlist/templates/playlist/filter_aside.html +msgid "See all playlists" +msgstr "Voir toutes les listes de lecture" -#: pod/playlist/templates/playlist/playlist_element_list.html -msgid "List of videos" -msgstr "Liste des vidéos" +#: pod/playlist/templates/playlist/playlist-informations-card.html +msgid "Informations about the playlist" +msgstr "Informations de la liste de lecture." -#: pod/playlist/templates/playlist/playlist_element_list.html -msgid "Thumbnail" -msgstr "Vignette" +#: pod/playlist/templates/playlist/playlist-informations-card.html +msgid "Last updated on" +msgstr "Mis à jour le" -#: pod/playlist/templates/playlist/playlist_element_list.html -msgid "Video thumbnail" -msgstr "Vignette de la vidéo" +#: pod/playlist/templates/playlist/playlist-informations-card.html +msgid "at" +msgstr "à" -#: pod/playlist/templates/playlist/playlist_element_list.html -msgid "Move up" -msgstr "Déplacer vers le haut" +#: pod/playlist/templates/playlist/playlist-informations-card.html +msgid "Playlist owner" +msgstr "Propriétaire de la liste de lecture" + +#: pod/playlist/templates/playlist/playlist-informations-card.html +msgid "Show statistics for the playlist" +msgstr "Afficher les statistiques de la liste de lecture" + +#: pod/playlist/templates/playlist/playlist-informations-card.html +#: pod/stats/apps.py pod/stats/templates/stats/channel-stats-view.html +#: pod/stats/templates/stats/general-stats-view.html +#: pod/stats/templates/stats/meeting-stats-view.html +#: pod/stats/templates/stats/playlist-stats-view.html +#: pod/stats/templates/stats/user-stats-view.html +#: pod/stats/templates/stats/video-stats-view.html +msgid "Statistics" +msgstr "Statistiques" -#: pod/playlist/templates/playlist/playlist_element_list.html -msgid "Move down" -msgstr "Déplacer vers le bas" +#: pod/playlist/templates/playlist/playlist-list-modal.html +msgid "Your playlists" +msgstr "Vos listes de lecture" -#: pod/playlist/templates/playlist/playlist_element_list.html -msgid "Save position" -msgstr "Enregistrer les positions" +#: pod/playlist/templates/playlist/playlist-list-modal.html +msgid "Add the video in a new playlist" +msgstr "Ajouter une vidéo à une nouvelle liste de lecture" -#: pod/playlist/templates/playlist/playlist_list.html -msgid "This playlist is visible to all users." -msgstr "Cette liste de lecture est visible à d’autres utilisateurs." +#: pod/playlist/templates/playlist/playlist-management-card.html +msgid "Manage playlist" +msgstr "Gérer la liste de lecture" -#: pod/playlist/templates/playlist/playlist_list.html -msgid "This playlist is only visible by you." -msgstr "Vous seul pouvez voir cette liste de lecture." +#: pod/playlist/templates/playlist/playlist-videos-list.html +#: pod/video/templates/videos/video_list.html +msgid "Sorry, no video found." +msgstr "Désolé, aucune vidéo trouvée." -#: pod/playlist/templates/playlist/playlist_list.html -msgid "Launch" -msgstr "Lancer" +#: pod/playlist/templates/playlist/playlist.html +#: pod/playlist/templates/playlist/playlist_content.html +#: pod/video/templates/channel/channel.html +#: pod/video/templates/videos/my_videos.html +#: pod/video/templates/videos/videos.html +#: pod/video_search/templates/search/search.html +#, python-format +msgid "%(counter)s video found" +msgid_plural "%(counter)s videos found" +msgstr[0] "%(counter)s vidéo trouvée" +msgstr[1] "%(counter)s vidéos trouvées" -#: pod/playlist/templates/playlist/playlist_list.html -msgid "Sorry, no playlist found" -msgstr "Désolé, aucune liste de lecture trouvée" +#: pod/playlist/templates/playlist/playlist.html +#: pod/playlist/templates/playlist/playlist_content.html +msgid "Playlist videos" +msgstr "Vidéos de la playlist" -#: pod/playlist/templates/playlist/playlist_video_card.html -#: pod/video/templates/videos/card.html -msgid "This content is password protected." -msgstr "Ce contenu est protégé par un mot de passe." +#: pod/playlist/templates/playlist/playlist.html +msgid "Reorganize your favorite videos" +msgstr "Réorganiser vos vidéos favorites" -#: pod/playlist/templates/playlist/playlist_video_card.html -#: pod/video/templates/videos/card.html -msgid "This content is chaptered." -msgstr "Ce contenu est chapitré." +#: pod/playlist/templates/playlist/playlist.html +msgid "Reorganize" +msgstr "Réorganiser" -#: pod/playlist/templates/playlist/playlist_video_card.html -#: pod/video/templates/videos/card.html -#: pod/video/templates/videos/category_modal_card.html -msgid "Video content." -msgstr "Contenu vidéo." +#: pod/playlist/templates/playlist/playlist.html +msgid "Help - Drag & Drop" +msgstr "Aide - Glisser & Déposer" -#: pod/playlist/templates/playlist/playlist_video_card.html -#: pod/video/templates/videos/card.html -#: pod/video/templates/videos/category_modal_card.html -msgid "Audio content." -msgstr "Contenu audio." +#: pod/playlist/templates/playlist/playlist.html +msgid "Select the video to move by clicking and holding." +msgstr "" +"Sélectionnez la vidéo que vous souhaitez en cliquant et maintenant le bouton " +"de la souris." -#: pod/playlist/views.py -msgid "You cannot edit this playlist." -msgstr "Vous ne pouvez éditer cette liste de lecture." +#: pod/playlist/templates/playlist/playlist.html +msgid "While holding down the video, drag it to the desired location." +msgstr "" +"Tout en maintenant le bouton de la souris enfoncé, faites-la glisser à " +"l’endroit que vous souhaitez." -#: pod/playlist/views.py -msgid "You don't have access to this playlist." -msgstr "Vous n’avez pas les droits d’accès à cette liste de lecture." +#: pod/playlist/templates/playlist/playlist.html +msgid "Drop the video on another to swap their position." +msgstr "Déposez la vidéo sur une autre pour échanger leur position." -#: pod/playlist/views.py +#: pod/playlist/templates/playlist/playlist_card.html pod/video/models.py +msgid "videos" +msgstr "vidéos" + +#: pod/playlist/templates/playlist/playlist_card.html +#: pod/playlist/templates/playlist/playlist_player.html +msgid "Playlist image" +msgstr "Image de la playlist" + +#: pod/playlist/templates/playlist/playlist_link.html +msgid "Remove the playlist" +msgstr "Supprimer la liste de lecture" + +#: pod/playlist/templates/playlist/playlist_player.html +msgid "Playlist:" +msgstr "Liste de lecture :" + +#: pod/playlist/templates/playlist/playlist_sort_select.html +#: pod/video/templates/videos/video_sort_select.html +msgid "Sort" +msgstr "Tri" + +#: pod/playlist/templates/playlist/playlist_sort_select.html +#: pod/video/templates/videos/video_sort_select.html +msgid "Ascending sort" +msgstr "Tri ascendant" + +#: pod/playlist/templates/playlist/playlist_sort_select.html +#: pod/video/templates/videos/video_sort_select.html +msgid "Descending sort" +msgstr "Tri descendant" + +#: pod/playlist/templates/playlist/playlist_sort_select.html +#: pod/video/templates/videos/video_sort_select.html +msgid "Sort Direction" +msgstr "Direction de tri" + +#: pod/playlist/templates/playlist/playlist_sort_select.html +msgid "Modification date" +msgstr "Date de modification" + +#: pod/playlist/templates/playlist/playlist_sort_select.html +msgid "Creation date" +msgstr "Date de création" + +#: pod/playlist/templates/playlist/playlist_visibility_icon.html +msgid "Public and promoted" +msgstr "Public et promu" + +#: pod/playlist/templates/playlist/playlists.html #, python-format -msgid "%(title)s (%(count)d video)" -msgid_plural "%(title)s (%(count)d videos)" -msgstr[0] "%(title)s (%(count)d vidéo)" -msgstr[1] "%(title)s (%(count)d vidéos)" +msgid "%(counter)s playlist found" +msgid_plural "%(counter)s playlists found" +msgstr[0] "%(counter)s liste de lecture trouvée" +msgstr[1] "%(counter)s listes de lecture trouvées" -#: pod/playlist/views.py -msgid "The playlist has been saved!" -msgstr "La liste de lecture a été sauvegardée !" +#: pod/playlist/templates/playlist/playlists.html +msgid "No playlists found" +msgstr "Aucune liste de lecture trouvée" -#: pod/playlist/views.py -msgid "The request is wrong. No video given." -msgstr "La requête est erronée. Aucune vidéo envoyée." +#: pod/playlist/templates/playlist/playlists.html +#, fuzzy +#| msgid "" +#| "You have not created any playlists yet, please use the \"Add a new " +#| "playlist\" button to add one." +msgid "" +"You haven't got any playlist yet, please use the \"Add a 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." -#: pod/playlist/views.py -msgid "Only ajax request are accepted for this action." -msgstr "Uniquement les requêtes ajax sont autorisées pour cette action." +#: pod/playlist/templates/playlist/protected-playlist-form.html +msgid "Protected playlist form" +msgstr "Formulaire de liste de lecture protégée" -#: pod/playlist/views.py -msgid "This video has been removed from your playlist." -msgstr "Cette vidéo a été retirée de votre liste de lecture." +#: pod/playlist/templates/playlist/protected-playlist-form.html +msgid "This playlist is protected by password, please fill in and click send." +msgstr "" +"Cet évènement est protégée par un mot de passe, veuillez remplir le " +"formulaire et cliquez sur envoyer." -#: pod/playlist/views.py -msgid "The playlist have been saved." -msgstr "La liste de lecture a été sauvegardée." +#: pod/playlist/templates/playlist/protected-playlist-form.html +#: pod/video/templates/videos/video-form.html +msgid "If you do not have the password for this content, please" +msgstr "Si vous n’avez pas le mot de passe pour ce contenu, veuillez" -#: pod/playlist/views.py -msgid "The video has been added to your playlist." -msgstr "La vidéo a été ajoutée à votre liste de lecture." +#: pod/playlist/templates/playlist/protected-playlist-form.html +#: pod/video/templates/videos/video-form.html +msgid "contact its owner" +msgstr "contacter son propriétaire" + +#: pod/playlist/templatetags/favorites_playlist.py +msgid "Favorites" +msgstr "Favoris" + +#: pod/playlist/tests/test_forms.py +#, fuzzy +#| msgid "Title field is required" +msgid "This field is required." +msgstr "Champ de titre est requis" + +#: pod/playlist/tests/test_forms.py +msgid "You cannot create a playlist named \"Favorites\"" +msgstr "Vous ne pouvez créer une liste de lecture nommé \"Favoris\"" #: pod/playlist/views.py -msgid "This playlist has been deleted." +msgid "The playlist has been deleted." msgstr "Cette liste de lecture a été supprimée." +#: pod/playlist/views.py +msgid "The playlist has been created and the video has been added in it." +msgstr "La liste de lecture a été créée et la vidéo a été ajoutée dedans." + #: pod/podfile/apps.py msgid "Pod files" msgstr "Fichiers Pod" @@ -5798,7 +5954,7 @@ msgstr "Partager avec quelqu’un" #: pod/podfile/templates/podfile/home_content.html msgid "Already shared with:" -msgstr "Déjà partagé avec :" +msgstr "Déjà partagé avec :" #: pod/podfile/templates/podfile/home_content.html msgid "Username" @@ -6181,8 +6337,8 @@ msgstr "Prévisualisation d’enregistrement" #: pod/video/templates/videos/video-element.html msgid "" "To view this video please enable JavaScript, and consider upgrading to a web " -"browser that supports HTML5 video" +"browser that supports HTML5 video" msgstr "" "Pour visionner cette vidéo, veuillez activer JavaScript et envisager de " "passer à un navigateur Web qui un nouvel enregistrement a été ajouté sur la plateforme " "%(title_site)s à partir de l’enregistreur \"%(recorder)s\".
Pour " -"l’ajouter, cliquez sur le lien ci dessous.

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

Cordialement

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

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

Cordialement

" #: pod/recorder/views.py msgid "New recording added." @@ -6278,6 +6433,246 @@ msgstr "L’enregistrement a été supprimé." msgid "Recorder for Studio not found." msgstr "Enregistreur studio non trouvé." +#: pod/stats/templates/stats/channel-stats-view.html +msgid "Number of themes" +msgstr "Nombre de thèmes" + +#: pod/stats/templates/stats/channel-stats-view.html +#: pod/stats/templates/stats/user-stats-view.html +msgid "Number of channels" +msgstr "Nombre de chaînes" + +#: pod/stats/templates/stats/channel-stats-view.html +msgid "Graph of video evolution for the channel " +msgstr "Graphique de l'évolution des vidéos de la chaîne " + +#: pod/stats/templates/stats/channel-stats-view.html +msgid "Breakdown of video status for the channel " +msgstr "Répartition des statuts des vidéos pour la chaîne " + +#: pod/stats/templates/stats/channel-stats-view.html +#: pod/stats/templates/stats/playlist-stats-view.html pod/stats/views.py +msgid "Statistics for playlists" +msgstr "Statistiques des listes de lecture" + +#: pod/stats/templates/stats/channel-stats-view.html +msgid "Breakdown of channels visibility status " +msgstr "Répartition des statuts de visibilité des chaînes " + +#: pod/stats/templates/stats/general-stats-view.html +#: pod/stats/templates/stats/user-stats-view.html +#: pod/stats/templates/stats/video-stats-view.html +msgid "Duration time of videos" +msgstr "Durée des vidéos" + +#: pod/stats/templates/stats/general-stats-view.html +#: pod/stats/templates/stats/video-stats-view.html +msgid "Most popular discipline" +msgstr "Discipline la plus populaire" + +#: pod/stats/templates/stats/general-stats-view.html +#: pod/stats/templates/stats/video-stats-view.html +msgid "No popular discipline" +msgstr "Aucune discipline populaire" + +#: pod/stats/templates/stats/general-stats-view.html +#: pod/stats/templates/stats/video-stats-view.html +msgid "Most popular video type" +msgstr "Type de vidéo le plus populaire" + +#: pod/stats/templates/stats/general-stats-view.html +#: pod/stats/templates/stats/video-stats-view.html +msgid "No popular video type" +msgstr "Aucun type de vidéo populaire" + +#: pod/stats/templates/stats/general-stats-view.html +msgid "Number of users" +msgstr "Nombre d'utilisateurs" + +#: pod/stats/templates/stats/general-stats-view.html +msgid "Statistics of videos" +msgstr "Statistiques des videos" + +#: pod/stats/templates/stats/general-stats-view.html +msgid "Graph of video evolution for " +msgstr "Graphique de l'évolution de " + +#: pod/stats/templates/stats/general-stats-view.html +msgid "Breakdown of video status for " +msgstr "Répartition des statuts des vidéos de " + +#: pod/stats/templates/stats/playlist-stats-view.html +msgid "Playlist playback time" +msgstr "Temps de lecture de la liste de lecture" + +#: pod/stats/templates/stats/playlist-stats-view.html +msgid "Playlist video statistics" +msgstr "Statistiques des vidéos de la liste de lecture" + +#: pod/stats/templates/stats/playlist-stats-view.html +#: pod/stats/templates/stats/video-stats-view.html +msgid "Graph of video evolution " +msgstr "Graphique de l'évolution des vidéos " + +#: pod/stats/templates/stats/playlist-stats-view.html +msgid "Breakdown of video status for the playlist " +msgstr "Répartition des statuts des vidéos pour la liste de lecture " + +#: pod/stats/templates/stats/playlist-stats-view.html +msgid "Breakdown of playlists visibilities for " +msgstr "Répartition des statuts de visibilité pour la liste de lecture " + +#: pod/stats/templates/stats/user-stats-view.html +msgid "My statistics" +msgstr "Mes statistiques" + +#: pod/stats/templates/stats/user-stats-view.html +msgid "Number of files" +msgstr "Nombre de fichiers" + +#: pod/stats/templates/stats/user-stats-view.html +msgid "Number of videos added in favorites" +msgstr "Nombre de vidéos ajoutées en favoris" + +#: pod/stats/templates/stats/user-stats-view.html +msgid "Number of meetings" +msgstr "Nombre de réunions" + +#: pod/stats/templates/stats/user-stats-view.html +msgid "Prefered discipline" +msgstr "Discipline préférée" + +#: pod/stats/templates/stats/user-stats-view.html +msgid "No prefered discipline" +msgstr "Pas de discipline préférée" + +#: pod/stats/templates/stats/user-stats-view.html +msgid "Prefered type" +msgstr "Type préféré" + +#: pod/stats/templates/stats/user-stats-view.html +msgid "No prefered type" +msgstr "Pas de type préféré" + +#: pod/stats/templates/stats/user-stats-view.html +msgid "Statistics of your videos" +msgstr "Statistiques de vos vidéos" + +#: pod/stats/templates/stats/user-stats-view.html +msgid "Graph of video evolution for the user " +msgstr "Graphique de l'évolution des vidéos de l'utilisateur " + +#: pod/stats/templates/stats/user-stats-view.html +msgid "Breakdown of video status for the user " +msgstr "Répartition des statuts des vidéos pour l'utilisateur " + +#: pod/stats/templates/stats/utils/pie-chart.html +#: pod/stats/templates/stats/utils/video-stats.html +#: pod/stats/templates/stats/utils/years-video-stats.html +msgid "Export to CSV" +msgstr "Exporter au format CSV" + +#: pod/stats/templates/stats/utils/years-video-stats.html +msgid "Start year" +msgstr "Année de début" + +#: pod/stats/templates/stats/utils/years-video-stats.html +msgid "End year" +msgstr "Année de fin" + +#: pod/stats/templates/stats/video-stats-view.html pod/video/apps.py +#: pod/video/models.py pod/video/templates/videos/videos.html +msgid "Videos" +msgstr "Vidéos" + +#: pod/stats/templates/stats/video-stats-view.html +#: pod/video/templates/videos/video-info.html +msgid "Number of favorites" +msgstr "Nombre de favoris" + +#: pod/stats/templates/stats/video-stats-view.html +#: pod/video/templates/videos/video-info.html +msgid "Addition in a playlist" +msgstr "Nombre d'ajouts dans une liste de lecture" + +#: pod/stats/templates/stats/video-stats-view.html +#: pod/video/templates/videos/video-info.html +msgid "Number of views" +msgstr "Nombre de vues" + +#: pod/stats/templates/stats/video-stats-view.html +msgid "Graphics of videos" +msgstr "Graphiques des vidéos" + +#: pod/stats/templates/stats/video-stats-view.html +msgid "Graph of video evolution of " +msgstr "Graphique de l'évolution des vidéos de " + +#: pod/stats/templates/stats/video-stats-view.html +msgid "Breakdown of video status " +msgstr "Répartition des statuts des vidéos " + +#: pod/stats/views.py +#, python-format +msgid "Video statistics: %s" +msgstr "Statistiques des vidéos : %s" + +#: pod/stats/views.py +msgid "Site video statistics" +msgstr "Statistiques des vidéo du site" + +#: pod/stats/views.py +#, python-format +msgid "Video statistics for the theme %s" +msgstr "Statistiques des vidéos du thème %s" + +#: pod/stats/views.py +#, python-format +msgid "Video statistics for the channel %s" +msgstr "Statistiques des vidéos de la chaîne %s" + +#: pod/stats/views.py +msgid "Statistics for channels" +msgstr "Statistiques des chaînes" + +#: pod/stats/views.py +#, python-format +msgid "Statistics for user %s" +msgstr "Statistiques de l'utilisateur %s" + +#: pod/stats/views.py +msgid "Site statistics" +msgstr "Statistiques du site" + +#: pod/stats/views.py +#, python-format +msgid "Statistics for the playlist %s" +msgstr "Statistiques de la liste de lecture %s" + +#: pod/stats/views.py pod/video/templates/videos/videos.html +msgid "Video statistics" +msgstr "Statistiques des vidéos" + +#: pod/stats/views.py +#, python-format +msgid "The following video does not exist: %s" +msgstr "La video suivante n’existe pas : %s" + +#: pod/stats/views.py +#, fuzzy, python-format +#| msgid "You do not have access rights to this video: %s " +msgid "You do not have access rights to this video: %s" +msgstr "Vous n’avez pas les droits d’accès à cette vidéo : %s " + +#: pod/stats/views.py +#, python-format +msgid "Statistics for the meeting %s" +msgstr "Statistiques de la réunion %s" + +#: pod/stats/views.py +msgid "Statistics for meetings" +msgstr "Statistiques des réunions" + #: pod/urls.py msgid "Pod Administration" msgstr "Administration de Pod" @@ -6294,11 +6689,6 @@ 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" @@ -6597,8 +6987,8 @@ msgid "" "%(url)s

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

\n" -"

%(scheme)s:%(url)s

\n" +"

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

\n" "\n" #: pod/video/management/commands/check_obsolete_videos.py @@ -6726,12 +7116,6 @@ msgstr "Privé (moi seulement)" msgid "Shared with video owner" msgstr "Partagé avec le propriétaire de la vidéo" -#: pod/video/models.py -#: pod/video/templates/videos/video_note_comments_display.html -#: pod/video/templates/videos/video_note_display.html -msgid "Public" -msgstr "Public" - #: pod/video/models.py #, python-format msgid "%(app)s version" @@ -6758,6 +7142,10 @@ msgstr "" msgid "The style will be added to your channel to show it" msgstr "Le style sera ajouté à votre chaîne" +#: pod/video/models.py +msgid "Visible" +msgstr "Visible" + #: pod/video/models.py msgid "" "If checked, the channel appear in a list of available channels on the " @@ -6836,10 +7224,6 @@ msgstr "Est une vidéo" msgid "Date to delete" msgstr "Date de suppression" -#: pod/video/models.py -msgid "videos" -msgstr "vidéos" - #: pod/video/models.py msgid "Sum of view" msgstr "Somme des vues" @@ -6979,9 +7363,12 @@ msgid "Show view statistics for all videos in this theme" msgstr "Afficher les statistiques de vue pour toutes les vidéos de ce thème" #: pod/video/templates/channel/channel.html -#: pod/video/templates/videos/videos.html -msgid "Statistics views" -msgstr "Statistiques de vues" +msgid "Theme statistics" +msgstr "Statistiques du thème" + +#: pod/video/templates/channel/channel.html +msgid "Channel statistics" +msgstr "Statistiques de la chaîne" #: pod/video/templates/channel/channel.html #: pod/video/templates/videos/videos.html @@ -7174,6 +7561,24 @@ msgstr "" msgid "Help for form fields" msgstr "Aide pour les champs de formulaire" +#: pod/video/templates/videos/card.html +msgid "This content is password protected." +msgstr "Ce contenu est protégé par un mot de passe." + +#: pod/video/templates/videos/card.html +msgid "This content is chaptered." +msgstr "Ce contenu est chapitré." + +#: pod/video/templates/videos/card.html +#: pod/video/templates/videos/category_modal_card.html +msgid "Video content." +msgstr "Contenu vidéo." + +#: pod/video/templates/videos/card.html +#: pod/video/templates/videos/category_modal_card.html +msgid "Audio content." +msgstr "Contenu audio." + #: pod/video/templates/videos/category_modal.html msgid "category title" msgstr "titre catégorie" @@ -7265,6 +7670,10 @@ msgstr "Dernières vidéos" msgid "Show all videos" msgstr "Afficher toutes les vidéos" +#: pod/video/templates/videos/link_video.html +msgid "Remove from playlist" +msgstr "Retirer de la liste de lecture" + #: pod/video/templates/videos/link_video.html #: pod/video/templates/videos/video-info.html msgid "Remove from favorite" @@ -7326,21 +7735,13 @@ 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" msgstr "Autre version" -#: pod/video/templates/videos/video-all-info.html -msgid "Add the video to a playlist" -msgstr "Ajouter une vidéo à une liste de lecture" - -#: pod/video/templates/videos/video-all-info.html -msgid "Add current video to this playlist" -msgstr "Ajouter la vidéo à cette liste de lecture" - #: pod/video/templates/videos/video-comment.html msgid "Comments have been disabled for this video." msgstr "Les commentaires ont été désactivés pour cette vidéo." @@ -7381,26 +7782,18 @@ msgstr "" "Cette vidéo est protégée par un mot de passe, veuillez le fournir et cliquez " "sur envoyer." -#: pod/video/templates/videos/video-form.html -msgid "If you do not have the password for this content, please" -msgstr "Si vous n’avez pas le mot de passe pour ce contenu, veuillez" - -#: pod/video/templates/videos/video-form.html -msgid "contact its owner" -msgstr "contacter son propriétaire" - #: pod/video/templates/videos/video-info.html msgid "Duration:" msgstr "Durée :" -#: pod/video/templates/videos/video-info.html -msgid "Number of views" -msgstr "Nombre de vues" - #: pod/video/templates/videos/video-info.html msgid "Show details of view statistics" msgstr "Afficher les details des statistiques de visualisation" +#: pod/video/templates/videos/video-info.html +msgid "Add the video to a playlist" +msgstr "Ajouter une vidéo à une liste de lecture" + #: pod/video/templates/videos/video-info.html msgid "Downloads" msgstr "Téléchargements" @@ -7493,10 +7886,6 @@ msgstr "" msgid "Options" msgstr "Options" -#: pod/video/templates/videos/video-info.html -msgid "Autoplay" -msgstr "Lecture automatique" - #: pod/video/templates/videos/video-info.html msgid "Check the box to autoplay the video." msgstr "Cocher cette case pour lancer la lecture automatiquement." @@ -7713,29 +8102,9 @@ 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" - #: pod/video/templates/videos/videos.html -msgid "Show view statistics for all videos" -msgstr "Afficher les statistiques de visualisation de toutes les vidéos" +msgid "Show general statistics" +msgstr "Afficher les statistiques générales" #: pod/video/templatetags/video_tags.py #, python-format @@ -7916,35 +8285,6 @@ msgstr "Horodatage de la note" msgid "You cannot access to this view." msgstr "Vous ne pouvez pas accéder à cette vue." -#: pod/video/views.py -msgid "Pod video viewing statistics" -msgstr "Statistiques de visualisation des vidéos" - -#: pod/video/views.py -#, python-format -msgid "Video viewing statistics for %s" -msgstr "Statistiques de visualisation de la vidéo %s" - -#: pod/video/views.py -#, python-format -msgid "Video viewing statistics for the channel %s" -msgstr "Statistiques de visualisation des vidéos de la chaîne %s" - -#: pod/video/views.py -#, python-format -msgid "Video viewing statistics for the theme %s" -msgstr "Statistiques de visualisation des vidéos du thème %s" - -#: pod/video/views.py -#, python-format -msgid "You do not have access rights to this video: %s " -msgstr "Vous n’avez pas les droits d’accès à cette vidéo : %s " - -#: pod/video/views.py -#, python-format -msgid "The following video does not exist: %s" -msgstr "La video suivante n’existe pas : %s" - #: pod/video/views.py msgid "Media upload" msgstr "Téléverser un média" @@ -8142,7 +8482,7 @@ msgstr "Vous la/le retrouverez ici :" #: pod/video_encode_transcript/utils.py msgid "the:" -msgstr "le :" +msgstr "le:" #: pod/video_search/apps.py msgid "Video search" @@ -8172,6 +8512,133 @@ msgstr "Résultats de la recherche" msgid "Esup-Pod xAPI" msgstr "xAPI Esup-Pod" +#~ msgid "Video statistics for %s" +#~ msgstr "Statistiques des vidéos pour %s" + +#, fuzzy +#~| msgid "Password-protected" +#~ msgid "protected" +#~ msgstr "Protégé par un mot de passe" + +#~ msgid "Prefered video discipline" +#~ msgstr "Discipline de vidéo préférée" + +#~ msgid "Prefered video type" +#~ msgstr "Type de vidéo préféré" + +#~ msgid "Show view statistics for all videos" +#~ msgstr "Afficher les statistiques de visualisation de toutes les vidéos" + +#~ msgid "Pod video viewing statistics" +#~ msgstr "Statistiques de visualisation des vidéos" + +#~ msgid "Please choose a password if this playlist is protected." +#~ msgstr "Veuillez choisir un mot de passe si cette playlist est protégée." + +#~ msgid "Password-protected playlist" +#~ msgstr "Liste de lecture protégée par un mot de passe" + +#~ msgid "Sort by descending rank before you can rearrange" +#~ msgstr "Trier par ordre décroissant avant de pouvoir réorganiser" + +#~ msgid "Sort by descending rank" +#~ msgstr "Trier par ordre décroissant" + +#~ msgid "" +#~ "If checked, the playlist can be visible to users other than the owner." +#~ msgstr "" +#~ "Si coché, cette liste de lecture sera visible aux autres utilisateurs." + +#~ msgid "Position of the video in a playlist." +#~ msgstr "Position de la vidéo dans la liste de lecture." + +#~ msgid "A video in draft mode cannot be added to a playlist." +#~ msgstr "" +#~ "Une vidéo en mode brouillon ne peut être ajoutée à une liste de lecture." + +#~ msgid "A video with a password cannot be added to a playlist." +#~ msgstr "" +#~ "Une vidéo avec mot de passe ne peut être ajoutée à une liste de lecture." + +#~ msgid "" +#~ "This is the page of your playlists. Here you can create, edit or delete " +#~ "them." +#~ msgstr "" +#~ "C’est la page de vos listes de lecture. Ici vous pouvez les créer, les " +#~ "éditer ou les supprimer." + +#~ msgid "" +#~ "A playlist with the eye symbol means that this playlist is visible to all " +#~ "users when they view this page." +#~ msgstr "" +#~ "Une liste de lecture avec un symbole œil signifie que cette liste est " +#~ "visible à tous les utilisateurs qui visiteront cette page." + +#~ msgid "This playlist has no videos yet." +#~ msgstr "Cette liste de lecture ne dispose pas encore de vidéos." + +#~ msgid "Switch to next video automatically" +#~ msgstr "Passer automatiquement à la prochaine vidéo" + +#~ msgid "Thumbnail" +#~ msgstr "Vignette" + +#~ msgid "Video thumbnail" +#~ msgstr "Vignette de la vidéo" + +#~ msgid "Move up" +#~ msgstr "Déplacer vers le haut" + +#~ msgid "Move down" +#~ msgstr "Déplacer vers le bas" + +#~ msgid "Save position" +#~ msgstr "Enregistrer les positions" + +#~ msgid "This playlist is visible to all users." +#~ msgstr "Cette liste de lecture est visible à d’autres utilisateurs." + +#~ msgid "This playlist is only visible by you." +#~ msgstr "Vous seul pouvez voir cette liste de lecture." + +#~ msgid "Launch" +#~ msgstr "Lancer" + +#~ msgid "Sorry, no playlist found" +#~ msgstr "Désolé, aucune liste de lecture trouvée" + +#~ msgid "You don't have access to this playlist." +#~ msgstr "Vous n’avez pas les droits d’accès à cette liste de lecture." + +#~ msgid "%(title)s (%(count)d video)" +#~ msgid_plural "%(title)s (%(count)d videos)" +#~ msgstr[0] "%(title)s (%(count)d vidéo)" +#~ msgstr[1] "%(title)s (%(count)d vidéos)" + +#~ msgid "The playlist has been saved!" +#~ msgstr "La liste de lecture a été sauvegardée !" + +#~ msgid "The request is wrong. No video given." +#~ msgstr "La requête est erronée. Aucune vidéo envoyée." + +#~ msgid "Only ajax request are accepted for this action." +#~ msgstr "Uniquement les requêtes ajax sont autorisées pour cette action." + +#~ msgid "This video has been removed from your playlist." +#~ msgstr "Cette vidéo a été retirée de votre liste de lecture." + +#~ msgid "The playlist have been saved." +#~ msgstr "La liste de lecture a été sauvegardée." + +#~ msgid "The video has been added to your playlist." +#~ msgstr "La vidéo a été ajoutée à votre liste de lecture." + +#~ msgid "Add current video to this playlist" +#~ msgstr "Ajouter la vidéo à cette liste de lecture" + +#~ msgid "Change the date" +#~ msgstr "Modifier la période de visualisation" + #~ msgid "Error in %s: " #~ msgstr "Erreur sur %s : " diff --git a/pod/locale/fr/LC_MESSAGES/djangojs.mo b/pod/locale/fr/LC_MESSAGES/djangojs.mo index f312842499..1dfe5ecbae 100644 Binary files a/pod/locale/fr/LC_MESSAGES/djangojs.mo and b/pod/locale/fr/LC_MESSAGES/djangojs.mo differ diff --git a/pod/locale/fr/LC_MESSAGES/djangojs.po b/pod/locale/fr/LC_MESSAGES/djangojs.po index 97a51c94ec..b7719f36ea 100644 --- a/pod/locale/fr/LC_MESSAGES/djangojs.po +++ b/pod/locale/fr/LC_MESSAGES/djangojs.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: Esup-Pod\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-05 15:50+0200\n" +"POT-Creation-Date: 2023-08-21 08:32+0000\n" "PO-Revision-Date: \n" "Last-Translator: obado \n" "Language-Team: \n" @@ -20,24 +20,18 @@ msgstr "" msgid "Get time from the player" msgstr "Obtenir le temps du lecteur" -#: pod/chapter/static/js/chapters.js pod/enrichment/static/js/enrichment.js -#: pod/main/static/js/main.js pod/video/static/js/comment-script.js -msgid "Close" -msgstr "Fermer" - #: pod/chapter/static/js/chapters.js pod/completion/static/js/completion.js -#: pod/enrichment/static/js/enrichment.js pod/playlist/static/js/playlist.js +#: pod/enrichment/static/js/enrichment.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/playlist/static/js/playlist.js +#: pod/enrichment/static/js/enrichment.js msgid "The form could not be recovered." msgstr "Le formulaire ne peut pas être récupéré." #: pod/chapter/static/js/chapters.js pod/completion/static/js/completion.js #: pod/enrichment/static/js/enrichment.js pod/main/static/js/main.js -#: pod/playlist/static/js/playlist.js #: pod/podfile/static/podfile/js/filewidget.js msgid "You are no longer authenticated. Please log in again." msgstr "Vous n’êtes plus authentifié. Veuillez vous reconnecter." @@ -176,16 +170,6 @@ msgstr "Veuillez entrer un texte pour le segment compris entre %s et %s :" msgid "Pause to enter caption for segment from %s to %s." msgstr "Mettez en pause pour entrer le texte du segment entre %s et %s." -#: pod/completion/static/js/caption_maker.js -#: pod/podfile/static/podfile/js/filewidget.js -msgid "Add" -msgstr "Ajouter" - -#: pod/completion/static/js/caption_maker.js -#: pod/video/static/js/comment-script.js -msgid "Delete" -msgstr "Supprimer" - #: pod/completion/static/js/caption_maker.js msgid "Caption" msgstr "Légende / Sous-titre" @@ -292,6 +276,11 @@ msgstr "Veuillez sélectionner un document" msgid "Iframe and Script tags are not allowed." msgstr "Les balises Iframe et Script ne sont pas autorisées." +#: pod/enrichment/static/js/enrichment.js pod/main/static/js/main.js +#: pod/video/static/js/comment-script.js +msgid "Close" +msgstr "Fermer" + #: pod/enrichment/static/js/enrichment.js msgid "Please enter a correct start from 0 to " msgstr "Veuillez entrer un correct temps de début compris entre 0 et " @@ -384,34 +373,6 @@ msgstr "Ouvrir le gestionnaire de diapositives" msgid "Enrich mode" msgstr "Mode enrichi" -#: pod/favorite/static/js/favorite-reorganize.js -msgid "Save your reorganization" -msgstr "Sauvegarder votre réorganisation" - -#: pod/favorite/static/js/favorite-reorganize.js -msgid "Save" -msgstr "Sauvegarder" - -#: pod/favorite/static/js/video-favorites-card-delete.js -msgid "The video could not be removed from favorites..." -msgstr "Le formulaire ne peut pas être récupéré." - -#: pod/favorite/static/js/video-favorites-card-list.js -msgid "Remove from favorite" -msgstr "Retirer des favoris" - -#: pod/favorite/static/js/video-favorites-card-list.js -msgid "Add in favorite" -msgstr "Ajouter aux favoris" - -#: pod/favorite/static/js/video-favorites-card-list.js -msgid "The deletion couldn't be completed..." -msgstr "La suppression n’a pas pu se faire..." - -#: pod/favorite/static/js/video-favorites.js -msgid "The favorite couldn’t be completed…" -msgstr "Le favori n’a pas pu être complété…" - #: pod/live/static/js/admin_broadcaster.js msgid "An error occurred" msgstr "Une erreur est survenue." @@ -440,6 +401,14 @@ msgstr "Pas de diffuseur pour ce bâtiment" msgid "An error occurred during broadcasters loading..." msgstr "Une erreur s’est produite lors du chargement des diffuseurs…" +#: pod/main/static/js/filter-aside-element-list-refresh.js +msgid "Descending sort" +msgstr "Tri descendant" + +#: pod/main/static/js/filter-aside-element-list-refresh.js +msgid "Ascending sort" +msgstr "Tri ascendant" + #: pod/main/static/js/main.js msgid "User not found" msgstr "Utilisateur non trouvé" @@ -498,41 +467,34 @@ 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/playlist/js/add-or-edit.js +msgid "Public: the playlist can be accessed by anyone." +msgstr "Public : la liste de lecture est accessible par tous." -#: 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." +#: pod/playlist/static/playlist/js/add-or-edit.js +msgid "" +"Password-protected: the playlist can be accessed by anyone with the " +"appropriate link and password." msgstr "" -"Erreur lors de la suppression. La liste de lecture n’a pas pu être supprimée." +"Protégé par un mot de passe : la liste de lecture est accessible à " +"toute personne disposant du lien et du mot de passe appropriés." -#: 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." +#: pod/playlist/static/playlist/js/add-or-edit.js +msgid "Private: only you have access to this playlist." +msgstr "Privé : vous seul avez accès à cette liste de lecture." -#: pod/playlist/static/js/playlist.js -msgid "The video slug not found." -msgstr "La trace (slug) de la vidéo est introuvable." +#: pod/playlist/static/playlist/js/filter-aside-playlist-list-refresh.js +#: pod/video/static/js/filter_aside_video_list_refresh.js +msgid "An Error occurred while processing." +msgstr "Une erreur est survenue durant l’exécution du processus." -#: pod/playlist/static/js/playlist.js -msgid "" -"Error getting video information. The video information could not be " -"retrieved." -msgstr "" -"Erreur lors de l’obtention des informations sur la vidéo. Les informations " -"vidéo n’ont pas pu être récupérées." +#: pod/playlist/static/playlist/js/playlist-reorganize.js +msgid "Save your reorganization" +msgstr "Sauvegarder votre réorganisation" -#: pod/podfile/static/podfile/js/filewidget.js -#: pod/video/static/js/change_video_owner.js -msgid "Loading…" -msgstr "Chargement en cours…" +#: pod/playlist/static/playlist/js/playlist-reorganize.js +msgid "Save" +msgstr "Sauvegarder" #: pod/podfile/static/podfile/js/filewidget.js msgid "Change image" @@ -562,6 +524,10 @@ msgstr "Retirer" msgid "Server error" msgstr "Erreur du serveur" +#: pod/podfile/static/podfile/js/filewidget.js +msgid "Add" +msgstr "Ajouter" + #: pod/podfile/static/podfile/js/filewidget.js msgid "Are you sure you want to delete this folder?" msgstr "Êtes-vous sûr(e) de vouloir supprimer ce dossier ?" @@ -574,10 +540,48 @@ msgstr "Voir plus" msgid "This folder is empty" msgstr "Ce dossier est vide" +#: pod/stats/static/stats/js/video_stats_view.js +#: pod/stats/static/stats/js/video_stats_view_global.js +msgid "Views" +msgstr "Vues" + +#: pod/stats/static/stats/js/video_stats_view.js +#: pod/stats/static/stats/js/video_stats_view_global.js +msgid "Favorites" +msgstr "Favoris" + +#: pod/stats/static/stats/js/video_stats_view.js +#: pod/stats/static/stats/js/video_stats_view_global.js +msgid "Playlist additions" +msgstr "Ajouts dans une liste de lecture" + +#: pod/stats/static/stats/js/video_stats_view.js +#: pod/stats/static/stats/js/video_stats_view_global.js +msgid "Date" +msgstr "Date" + +#: pod/stats/static/stats/js/video_stats_view.js +#: pod/stats/static/stats/js/video_stats_view_global.js +msgid "Value" +msgstr "Valeur" + +#: pod/stats/static/stats/js/video_stats_view.js +#: pod/stats/static/stats/js/video_stats_view_global.js +msgid "Playlists_addition" +msgstr "Ajouts_liste_de_lecture" + +#: pod/stats/static/stats/js/video_stats_view_global.js +msgid "Years" +msgstr "Années" + #: pod/video/static/js/change_video_owner.js msgid "No element found" msgstr "Aucun élément trouvé" +#: pod/video/static/js/change_video_owner.js +msgid "Loading…" +msgstr "Chargement en cours…" + #: pod/video/static/js/change_video_owner.js msgid "An error occurred during the change of owner" msgstr "Une erreur s’est produite lors du changement de propriétaire" @@ -595,40 +599,21 @@ msgid "Answers" msgstr "Réponses" #: pod/video/static/js/comment-script.js -msgid "Cancel" -msgstr "Annuler" +msgid "Delete" +msgstr "Supprimer" #: pod/video/static/js/comment-script.js -#, javascript-format -msgid "%s vote" -msgid_plural "%s votes" -msgstr[0] "%s vote" -msgstr[1] "%s votes" +msgid "Cancel" +msgstr "Annuler" #: pod/video/static/js/comment-script.js msgid "Agree with the comment" msgstr "D’accord avec ce commentaire" -#: pod/video/static/js/comment-script.js -msgid "Reply to comment" -msgstr "Répondre au commentaire" - -#: pod/video/static/js/comment-script.js -msgid "Reply" -msgstr "Répondre" - #: pod/video/static/js/comment-script.js msgid "Remove this comment" msgstr "Supprimer ce commentaire" -#: pod/video/static/js/comment-script.js -msgid "Add a public comment" -msgstr "Ajouter un commentaire public" - -#: pod/video/static/js/comment-script.js -msgid "Send" -msgstr "Envoyer" - #: pod/video/static/js/comment-script.js msgid "Show answers" msgstr "Afficher les réponses" @@ -641,6 +626,13 @@ msgstr "Mauvaise réponse du serveur." msgid "Sorry, you're not allowed to vote by now." msgstr "Désolé, vous n’êtes pas autorisé à voter maintenant." +#: pod/video/static/js/comment-script.js +#, javascript-format +msgid "%s vote" +msgid_plural "%s votes" +msgstr[0] "%s vote" +msgstr[1] "%s votes" + #: pod/video/static/js/comment-script.js msgid "Sorry, you can't comment this video by now." msgstr "Désolé, vous ne pouvez pas commenter cette vidéo maintenant." @@ -660,60 +652,39 @@ msgid_plural "%s comments" msgstr[0] "%s commentaire" msgstr[1] "%s commentaires" -#: pod/video/static/js/filter_aside_video_list_refresh.js -msgid "Descending sort" -msgstr "Tri descendant" - -#: pod/video/static/js/filter_aside_video_list_refresh.js -msgid "Ascending sort" -msgstr "Tri ascendant" - -#: pod/video/static/js/filter_aside_video_list_refresh.js -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" @@ -774,18 +745,6 @@ msgstr "Désolé, aucune vidéo trouvée" msgid "Edit the category" msgstr "Éditer la catégorie" -#: pod/video/static/js/video_category.js -msgid "Delete the category" -msgstr "Supprimer la catégorie" - -#: pod/video/static/js/video_category.js -msgid "Success!" -msgstr "Succès !" - -#: pod/video/static/js/video_category.js -msgid "Error…" -msgstr "Erreur…" - #: pod/video/static/js/video_category.js msgid "Category created successfully" msgstr "Catégorie créée avec succès" @@ -802,45 +761,115 @@ msgstr "Créer catégorie" msgid "Select the general type of the video." msgstr "Sélectionnez le type général de vidéo." -#: pod/video/static/js/video_stats_view.js -msgid "Title" -msgstr "Titre" +#~ msgid "Playlists addition" +#~ msgstr "Ajouts dans une liste de lecture" + +#~ msgid "Date,Views,Favorites" +#~ msgstr "Date,Vues,Favoris" + +#~ msgid "Years,Views,Favorites" +#~ msgstr "Années,Vues,Favoris" + +#~ msgid "Title" +#~ msgstr "Titre" + +#~ msgid "Playlist additions during the month" +#~ msgstr "Ajouts dans une liste de lecture durant le mois" + +#~ msgid "Playlist additions during the year" +#~ msgstr "Ajouts dans une liste de lecture durant l’année" + +#~ msgid "Total Playlist additions from creation" +#~ msgstr "Ajouts en liste de lecture total depuis la création" + +#~ msgid "Favorite additions during the day" +#~ msgstr "Ajouts en favoris de la journée" + +#~ msgid "View during the day" +#~ msgstr "Vue de la journée" + +#~ msgid "View during the month" +#~ msgstr "Vue du mois" + +#~ msgid "View during the year" +#~ msgstr "Vue de l’année" + +#~ msgid "Total view from creation" +#~ msgstr "Vue totale depuis création" + +#~ msgid "Favorite additions during the month" +#~ msgstr "Ajouts en favoris du mois" + +#~ msgid "Favorite additions during the year" +#~ msgstr "Ajouts en favoris de l’année" + +#~ msgid "Total favorite additions from creation" +#~ msgstr "Ajouts en favoris total depuis la création" + +#~ msgid "Slug" +#~ msgstr "Titre court" + +#~ 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 "The video could not be removed from favorites..." +#~ msgstr "Le formulaire ne peut pas être récupéré." + +#~ msgid "Remove from favorite" +#~ msgstr "Retirer des favoris" -#: pod/video/static/js/video_stats_view.js -msgid "View during the day" -msgstr "Vue de la journée" +#~ msgid "Add in favorite" +#~ msgstr "Ajouter aux favoris" -#: pod/video/static/js/video_stats_view.js -msgid "View during the month" -msgstr "Vue du mois" +#~ msgid "The deletion couldn't be completed..." +#~ msgstr "La suppression n’a pas pu se faire..." -#: pod/video/static/js/video_stats_view.js -msgid "View during the year" -msgstr "Vue de l’année" +#~ msgid "The favorite couldn’t be completed…" +#~ msgstr "Le favori n’a pas pu être complété…" -#: pod/video/static/js/video_stats_view.js -msgid "Total view from creation" -msgstr "Vue totale depuis création" +#~ msgid "The video can not be added from this page." +#~ msgstr "La vidéo ne peut être ajoutée depuis cette page." -#: pod/video/static/js/video_stats_view.js -msgid "Favorite additions during the day" -msgstr "Ajouts en favoris de la journée" +#~ msgid "The video slug not found." +#~ msgstr "La trace (slug) de la vidéo est introuvable." -#: pod/video/static/js/video_stats_view.js -msgid "Favorite additions during the month" -msgstr "Ajouts en favoris du mois" +#~ msgid "" +#~ "Error getting video information. The video information could not be " +#~ "retrieved." +#~ msgstr "" +#~ "Erreur lors de l’obtention des informations sur la vidéo. Les " +#~ "informations vidéo n’ont pas pu être récupérées." -#: pod/video/static/js/video_stats_view.js -msgid "Favorite additions during the year" -msgstr "Ajouts en favoris de l’année" +#~ msgid "Position saved" +#~ msgstr "Position enregistrée" -#: pod/video/static/js/video_stats_view.js -msgid "Total favorite additions from creation" -msgstr "Ajouts en favoris total depuis la création" +#~ 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/video/static/js/video_stats_view.js -msgid "Slug" -msgstr "Titre court" +#~ 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 "Are you sure you want to delete this element?" #~ msgstr "Êtes-vous sûr(e) de vouloir supprimer cet élément ?" diff --git a/pod/locale/nl/LC_MESSAGES/django.po b/pod/locale/nl/LC_MESSAGES/django.po index 60c672637a..45a00be645 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-07-05 15:50+0200\n" +"POT-Creation-Date: 2023-08-21 08:32+0000\n" "PO-Revision-Date: 2023-06-08 14:37+0200\n" "Last-Translator: obado \n" "Language-Team: \n" @@ -101,8 +101,6 @@ msgid "Picture" msgstr "" #: pod/authentication/models.py pod/live/models.py pod/meeting/models.py -#: pod/playlist/models.py -#: pod/playlist/templates/playlist/playlist_element_list.html #: pod/podfile/models.py pod/video/admin.py pod/video/models.py #: pod/video_search/templates/search/search.html msgid "Owner" @@ -180,8 +178,7 @@ msgstr "" #: pod/main/templates/navbar.html pod/main/templates/navbar_collapse.html #: pod/meeting/templates/meeting/add_or_edit.html #: pod/meeting/templates/meeting/my_meetings.html -#: pod/playlist/templates/playlist/playlist_video_list.html -#: pod/playlist/templates/playlist_player-iframe.html +#: pod/playlist/templates/playlist/playlist-list-modal.html #: pod/podfile/templates/podfile/customfilewidget.html #: pod/podfile/templates/podfile/home_content.html #: pod/podfile/templates/podfile/userfolder.html @@ -210,6 +207,9 @@ msgstr "" #: pod/meeting/templates/meeting/delete.html #: pod/meeting/templates/meeting/invite.html #: pod/meeting/templates/meeting/join.html pod/meeting/views.py +#: pod/playlist/templates/playlist/add_or_edit.html +#: pod/playlist/templates/playlist/delete.html +#: pod/playlist/templates/playlist/protected-playlist-form.html #: pod/playlist/views.py pod/recorder/templates/recorder/add_recording.html #: pod/recorder/templates/recorder/record_delete.html pod/recorder/views.py #: pod/video/templates/channel/channel_edit.html @@ -238,7 +238,9 @@ msgstr "" #: pod/meeting/templates/meeting/delete.html #: pod/meeting/templates/meeting/invite.html #: pod/meeting/templates/meeting/join.html -#: pod/playlist/templates/playlist/playlist_video_list.html +#: pod/playlist/templates/playlist/add_or_edit.html +#: pod/playlist/templates/playlist/delete.html +#: pod/playlist/templates/playlist/protected-playlist-form.html #: pod/recorder/templates/recorder/add_recording.html #: pod/recorder/templates/recorder/record_delete.html #: pod/video/templates/channel/channel_edit.html @@ -350,8 +352,8 @@ msgstr "" msgid "URL of the recording thumbnail of the BBB presentation." msgstr "" -#: pod/bbb/models.py pod/favorite/models.py pod/import_video/models.py -#: pod/meeting/models.py pod/recorder/models.py +#: pod/bbb/models.py pod/import_video/models.py pod/meeting/models.py +#: pod/playlist/models.py pod/recorder/models.py msgid "User" msgstr "" @@ -372,6 +374,7 @@ msgid "Meeting" msgstr "" #: pod/bbb/models.py pod/meeting/apps.py +#: pod/stats/templates/stats/meeting-stats-view.html msgid "Meetings" msgstr "" @@ -413,7 +416,7 @@ msgstr "" #: pod/bbb/models.py pod/import_video/models.py pod/live/forms.py #: pod/live/models.py pod/meeting/forms.py pod/meeting/models.py -#: pod/video_search/forms.py +#: pod/stats/templates/stats/utils/video-stats.html pod/video_search/forms.py msgid "Start date" msgstr "" @@ -422,7 +425,7 @@ msgid "Start date of the live." msgstr "" #: pod/bbb/models.py pod/live/forms.py pod/live/models.py -#: pod/video_search/forms.py +#: pod/stats/templates/stats/utils/video-stats.html pod/video_search/forms.py msgid "End date" msgstr "" @@ -698,8 +701,7 @@ msgstr "" #: pod/bbb/templates/bbb/live_record_list.html #: pod/bbb/templates/bbb/record_list.html -#: pod/favorite/templates/favorite/favorite_video_list.html -#: pod/playlist/templates/playlist/playlist_list.html +#: pod/playlist/templates/playlist/playlist-videos-list.html #: pod/recorder/templates/recorder/record_list.html #: pod/video/templates/videos/video_list.html msgid "More" @@ -707,9 +709,8 @@ msgstr "" #: pod/bbb/templates/bbb/live_record_list.html #: pod/bbb/templates/bbb/record_list.html -#: pod/favorite/templates/favorite/favorite_video_list.html #: pod/live/templates/live/events_list.html pod/main/templates/loader.html -#: pod/playlist/templates/playlist/playlist_list.html +#: pod/playlist/templates/playlist/playlist-videos-list.html #: pod/podfile/templates/podfile/home_content.html #: pod/podfile/templates/podfile/list_folder_files.html #: pod/recorder/templates/recorder/record_list.html @@ -766,7 +767,8 @@ msgid "File to import" msgstr "" #: pod/chapter/models.py pod/completion/models.py pod/enrichment/models.py -#: pod/video/models.py pod/video_encode_transcript/utils.py +#: pod/playlist/templates/playlist/playlist_card.html pod/video/models.py +#: pod/video_encode_transcript/utils.py msgid "video" msgstr "" @@ -775,7 +777,8 @@ msgstr "" msgid "title" msgstr "titel" -#: pod/chapter/models.py pod/enrichment/models.py pod/video/models.py +#: pod/chapter/models.py pod/enrichment/models.py pod/playlist/models.py +#: pod/video/models.py msgid "slug" msgstr "" @@ -835,7 +838,7 @@ msgstr "" #: pod/enrichment/templates/enrichment/group_enrichment.html #: pod/import_video/templates/import_video/add_or_edit.html #: pod/meeting/templates/meeting/add_or_edit.html -#: pod/playlist/templates/playlist.html +#: pod/playlist/templates/playlist/add_or_edit.html #: pod/recorder/templates/recorder/add_recording.html #: pod/video/templates/channel/channel_edit.html #: pod/video/templates/channel/form_theme.html @@ -851,7 +854,7 @@ msgstr "" #: pod/completion/templates/overlay/form_overlay.html #: pod/completion/templates/track/form_track.html #: pod/enrichment/templates/enrichment/form_enrichment.html -#: pod/favorite/templates/favorite/favorite_videos.html +#: pod/playlist/templates/playlist/playlist.html #: pod/video/templates/channel/form_theme.html #: pod/video/templates/videos/category_modal.html #: pod/video/templates/videos/video_note_comments_display.html @@ -877,7 +880,6 @@ msgstr "" #: pod/completion/templates/overlay/list_overlay.html #: 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 msgid "Title" @@ -889,7 +891,6 @@ msgstr "Titel" #: pod/completion/templates/overlay/list_overlay.html #: pod/completion/templates/track/list_track.html #: pod/enrichment/templates/enrichment/list_enrichment.html -#: pod/playlist/templates/playlist/playlist_element_list.html #: pod/video/templates/channel/list_theme.html msgid "Actions" msgstr "" @@ -920,7 +921,7 @@ msgstr "" #: pod/enrichment/templates/enrichment/list_enrichment.html #: pod/live/templates/live/event_delete.html #: pod/meeting/templates/meeting/delete.html -#: pod/playlist/templates/playlist.html +#: pod/playlist/templates/playlist/delete.html #: pod/recorder/templates/recorder/record_delete.html #: pod/video/templates/channel/list_theme.html #: pod/video/templates/videos/category_modal.html @@ -1116,9 +1117,9 @@ msgstr "" msgid "There is already a contributor with the same name and role in the list." msgstr "" -#: pod/completion/models.py pod/enrichment/models.py pod/favorite/models.py -#: pod/playlist/models.py pod/recorder/models.py pod/video/models.py -#: pod/video_encode_transcript/models.py +#: pod/completion/models.py pod/enrichment/models.py pod/playlist/models.py +#: pod/recorder/models.py pod/video/models.py +#: pod/video/templates/videos/video.html pod/video_encode_transcript/models.py msgid "Video" msgstr "" @@ -1126,7 +1127,7 @@ msgstr "" #: pod/completion/templates/document/list_document.html #: pod/enrichment/models.py #: pod/enrichment/templates/enrichment/video_enrichment.html -#: pod/playlist/templates/playlist_player.html pod/podfile/models.py +#: pod/podfile/models.py msgid "Document" msgstr "" @@ -1250,8 +1251,7 @@ msgstr "" msgid "left" msgstr "" -#: pod/completion/models.py pod/live/models.py pod/playlist/models.py -#: pod/video/models.py +#: pod/completion/models.py pod/live/models.py pod/video/models.py msgid "Slug" msgstr "" @@ -1272,8 +1272,6 @@ msgid "Content" msgstr "" #: pod/completion/models.py pod/completion/templates/overlay/list_overlay.html -#: pod/playlist/models.py -#: pod/playlist/templates/playlist/playlist_element_list.html msgid "Position" msgstr "" @@ -1415,7 +1413,6 @@ msgid "Remove the subtitle or caption files" msgstr "" #: pod/completion/templates/track/list_track.html -#: pod/playlist/templates/playlist/playlist_element_list.html msgid "Remove" msgstr "" @@ -1731,6 +1728,7 @@ msgid "Total video duration" msgstr "" #: pod/cut/templates/video_cut.html +#: pod/playlist/templates/playlist/filter_aside.html #: pod/video/templates/videos/filter_aside.html msgid "Reset" msgstr "" @@ -1851,7 +1849,7 @@ msgstr "" #: pod/enrichment/models.py #: pod/enrichment/templates/enrichment/video_enrichment.html pod/main/models.py -#: pod/playlist/templates/playlist_player.html pod/podfile/models.py +#: pod/podfile/models.py msgid "Image" msgstr "" @@ -1861,7 +1859,6 @@ msgstr "" #: pod/enrichment/models.py #: pod/enrichment/templates/enrichment/video_enrichment.html -#: pod/playlist/templates/playlist_player.html msgid "Richtext" msgstr "" @@ -1998,8 +1995,6 @@ msgstr "" #: pod/enrichment/templates/enrichment/video_enrichment-iframe.html #: pod/enrichment/templates/enrichment/video_enrichment.html -#: pod/playlist/templates/playlist_player-iframe.html -#: pod/playlist/templates/playlist_player.html msgid "Enriched" msgstr "" @@ -2009,27 +2004,22 @@ msgid "Added by" msgstr "" #: pod/enrichment/templates/enrichment/video_enrichment.html -#: pod/playlist/templates/playlist_player.html msgid "Informations" msgstr "" #: pod/enrichment/templates/enrichment/video_enrichment.html -#: pod/playlist/templates/playlist_player.html msgid "To help you, the different types of enrichments have specific colors:" msgstr "" #: pod/enrichment/templates/enrichment/video_enrichment.html -#: pod/playlist/templates/playlist_player.html msgid "Weblink" msgstr "" #: pod/enrichment/templates/enrichment/video_enrichment.html -#: pod/playlist/templates/playlist_player.html msgid "Embed" msgstr "" #: pod/enrichment/templates/enrichment/video_enrichment.html -#: pod/playlist/templates/playlist_player.html msgid "They are visible on the video playback bar." msgstr "" @@ -2037,82 +2027,6 @@ msgstr "" msgid "You cannot enrich this video." msgstr "" -#: 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/video/templates/videos/video_sort_select.html -msgid "Rank" -msgstr "" - -#: pod/favorite/models.py -msgid "Favorite video" -msgstr "" - -#: pod/favorite/templates/favorite/favorite_video_list.html -#: pod/video/templates/videos/video_list.html -msgid "Sorry, no video found." -msgstr "" - -#: pod/favorite/templates/favorite/favorite_videos.html -#: pod/video/templates/channel/channel.html -#: pod/video/templates/videos/my_videos.html -#: pod/video/templates/videos/videos.html -#: pod/video_search/templates/search/search.html -#, python-format -msgid "%(counter)s video found" -msgid_plural "%(counter)s videos found" -msgstr[0] "" -msgstr[1] "" - -#: pod/favorite/templates/favorite/favorite_videos.html -#: pod/favorite/tests/test_views.py pod/favorite/views.py -#: pod/main/templates/navbar.html -msgid "My favorite videos" -msgstr "" - -#: pod/favorite/templates/favorite/favorite_videos.html -msgid "Reorganize your favorite videos" -msgstr "" - -#: pod/favorite/templates/favorite/favorite_videos.html -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 "" - -#: pod/favorite/templates/favorite/favorite_videos.html -msgid "Select the video to move by clicking and holding." -msgstr "Sélectionnez la vidéo à déplacer en cliquant et en maintenant." - -#: pod/favorite/templates/favorite/favorite_videos.html -msgid "While holding down the video, drag it to the desired location." -msgstr "" -"Tout en maintenant la vidéo, faites-la glisser vers l'emplacement souhaité." - -#: pod/favorite/templates/favorite/favorite_videos.html -msgid "Drop the video on another to swap their position." -msgstr "Déposez la vidéo sur une autre pour échanger leur position." - -#: pod/favorite/tests/test_views.py pod/video/templates/videos/video-info.html -msgid "Number of favorites" -msgstr "" - #: pod/import_video/apps.py msgid "Import External Video" msgstr "" @@ -2302,6 +2216,7 @@ msgstr "" #: pod/live/templates/live/filter_aside.html #: pod/meeting/templates/meeting/filter_aside.html #: pod/meeting/templates/meeting/filter_aside_recording.html +#: pod/playlist/templates/playlist/filter_aside.html #: pod/video/templates/videos/filter_aside.html msgid "Filters" msgstr "" @@ -2348,6 +2263,7 @@ msgstr "" #: pod/import_video/templates/import_video/list.html pod/main/forms.py #: pod/meeting/forms.py pod/meeting/templates/meeting/internal_recordings.html +#: pod/playlist/templates/playlist/playlist_sort_select.html #: pod/podfile/models.py pod/podfile/templates/podfile/home_content.html #: pod/video_encode_transcript/models.py msgid "Name" @@ -2484,8 +2400,8 @@ msgstr "" #: pod/import_video/views.py #, python-format msgid "" -"This video '%(name)s' was uploaded to Pod; its origin is Youtube : %(url)s" +"This video '%(name)s' was uploaded to Pod; its origin is Youtube : %(url)s" msgstr "" #: pod/import_video/views.py @@ -2627,7 +2543,8 @@ msgstr "" msgid "An event is already planned at these dates" msgstr "" -#: pod/live/forms.py pod/meeting/forms.py pod/video/forms.py +#: pod/live/forms.py pod/meeting/forms.py pod/playlist/forms.py +#: pod/playlist/models.py pod/video/forms.py msgid "Password" msgstr "" @@ -2643,8 +2560,8 @@ msgstr "" msgid "Broadcaster device" msgstr "" -#: pod/live/forms.py pod/meeting/forms.py pod/recorder/forms.py -#: pod/video/forms.py +#: pod/live/forms.py pod/meeting/forms.py pod/playlist/forms.py +#: pod/recorder/forms.py pod/video/forms.py msgid "I agree" msgstr "" @@ -2769,7 +2686,9 @@ msgid "" "information, and format the result using the toolbar." msgstr "" -#: pod/live/models.py pod/meeting/models.py pod/video/forms.py +#: pod/live/models.py pod/meeting/models.py pod/playlist/models.py +#: pod/playlist/templates/playlist/playlist-informations-card.html +#: pod/stats/templates/stats/playlist-stats-view.html pod/video/forms.py #: pod/video/models.py msgid "Additional owners" msgstr "" @@ -2958,8 +2877,7 @@ msgstr "" msgid "Manage broadcaster" msgstr "" -#: pod/live/templates/live/direct.html pod/playlist/templates/playlist.html -#: pod/playlist/templates/playlist/playlist_list.html +#: pod/live/templates/live/direct.html #: pod/video/templates/videos/video_edit.html msgid "Edit" msgstr "" @@ -3030,6 +2948,7 @@ msgid "This event is protected by password, please fill in and click send." msgstr "" #: pod/live/templates/live/event-form.html +#: pod/playlist/templates/playlist/protected-playlist-form.html #: pod/video/templates/videos/video-form.html msgid "Password required" msgstr "" @@ -3040,6 +2959,7 @@ msgstr "" #: pod/live/templates/live/filter_aside.html pod/main/templates/contact_us.html #: pod/meeting/templates/meeting/invite.html #: pod/meeting/templates/meeting/join.html +#: pod/playlist/templates/playlist/protected-playlist-form.html #: pod/video/templates/videos/video-form.html #: pod/video_search/templates/search/search.html msgid "Send" @@ -3234,9 +3154,7 @@ msgstr "" msgid "Delete the event" msgstr "" -#: pod/live/templates/live/event_card.html -#: pod/playlist/templates/playlist/playlist_video_card.html -#: pod/video/templates/videos/card.html +#: pod/live/templates/live/event_card.html pod/video/templates/videos/card.html msgid "This content is in draft." msgstr "" @@ -3277,6 +3195,7 @@ msgstr "" #: pod/live/templates/live/event_delete.html #: pod/meeting/templates/meeting/delete.html +#: pod/playlist/templates/playlist/delete.html #: pod/recorder/templates/recorder/record_delete.html #: pod/video/templates/videos/video_delete.html msgid "Agree required" @@ -3440,8 +3359,7 @@ msgstr "" msgid "You cannot watch this event." msgstr "" -#: pod/live/views.py pod/playlist/templates/playlist/playlist_video_list.html -#: pod/video/views.py +#: pod/live/views.py pod/playlist/views.py pod/video/views.py msgid "The password is incorrect." msgstr "" @@ -4257,7 +4175,7 @@ msgstr "" msgid "Breadcrumb" msgstr "" -#: pod/main/templates/base.html pod/playlist/templates/playlist_player.html +#: pod/main/templates/base.html msgid "Home" msgstr "" @@ -4313,6 +4231,10 @@ msgstr "" msgid "videos availables" msgstr "" +#: pod/main/templates/footer.html +msgid "See more statistics" +msgstr "" + #: pod/main/templates/mail/mail.html pod/main/templates/mail/mail_sender.html msgid "Hello" msgstr "" @@ -4360,11 +4282,16 @@ msgstr "" msgid "Toggle navigation" msgstr "" -#: pod/main/templates/navbar.html pod/recorder/models.py pod/video/forms.py +#: pod/main/templates/navbar.html pod/recorder/models.py +#: pod/stats/templates/stats/channel-stats-view.html pod/video/forms.py #: pod/video/models.py msgid "Channels" msgstr "" +#: pod/main/templates/navbar.html +msgid "Promoted playlists" +msgstr "" + #: pod/main/templates/navbar.html msgid "Some features are unavailable" msgstr "" @@ -4415,6 +4342,14 @@ msgstr "" msgid "Add your picture" msgstr "" +#: pod/main/templates/navbar.html +msgid "My playlists" +msgstr "" + +#: pod/main/templates/navbar.html pod/playlist/tests/test_views.py +msgid "My favorite videos" +msgstr "" + #: pod/main/templates/navbar.html msgid "Video Record" msgstr "" @@ -4429,11 +4364,6 @@ msgstr "" msgid "My channels" msgstr "" -#: pod/main/templates/navbar.html pod/playlist/templates/my_playlists.html -#: pod/playlist/templates/playlist.html pod/playlist/views.py -msgid "My playlists" -msgstr "" - #: pod/main/templates/navbar.html pod/podfile/templates/podfile/home.html #: pod/podfile/views.py msgid "My files" @@ -4449,6 +4379,29 @@ msgstr "" msgid "Log out" msgstr "Uitloggen" +#: pod/main/templates/navbar.html +msgid "Your statistics" +msgstr "" + +#: pod/main/templates/navbar.html +#: pod/stats/templates/stats/channel-stats-view.html +#: pod/stats/templates/stats/general-stats-view.html +#: pod/stats/templates/stats/playlist-stats-view.html +#: pod/stats/templates/stats/user-stats-view.html +#: pod/stats/templates/stats/video-stats-view.html +msgid "Number of videos" +msgstr "" + +#: pod/main/templates/navbar.html +#: pod/stats/templates/stats/playlist-stats-view.html +#: pod/stats/templates/stats/user-stats-view.html +msgid "Number of playlists" +msgstr "" + +#: pod/main/templates/navbar.html +msgid "See more" +msgstr "" + #: pod/main/templates/navbar_collapse.html #, python-format msgid "%(counter)s Channel" @@ -4464,8 +4417,6 @@ msgstr[0] "" msgstr[1] "" #: pod/main/templates/navbar_collapse.html -#: pod/playlist/templates/playlist/playlist_list.html -#: pod/playlist/templates/playlist/playlist_video_list.html #: pod/video/templates/channel/channel.html #, python-format msgid "%(counter)s video" @@ -4509,9 +4460,7 @@ 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/meeting/forms.py pod/video/feeds.py pod/video/models.py #: pod/video/templates/videos/video_sort_select.html msgid "Duration" msgstr "" @@ -4565,7 +4514,7 @@ msgstr "" msgid "Record session" msgstr "" -#: pod/meeting/forms.py pod/video/forms.py +#: pod/meeting/forms.py pod/playlist/forms.py pod/video/forms.py msgid "Owner of the video cannot be an additional owner too" msgstr "" @@ -5001,7 +4950,7 @@ msgid "Delete the meeting" msgstr "" #: pod/meeting/templates/meeting/meeting_card.html -msgid "Acces to this meeting is restricted" +msgid "Access to this meeting is restricted" msgstr "" #: pod/meeting/templates/meeting/meeting_card.html @@ -5192,205 +5141,398 @@ msgid "Impossible to create the internal recording" msgstr "" #: pod/playlist/apps.py pod/playlist/models.py +#: pod/playlist/templates/playlist/add_or_edit.html +#: pod/playlist/templates/playlist/delete.html +#: pod/playlist/templates/playlist/playlist.html +#: pod/playlist/templates/playlist/playlists.html +#: pod/playlist/templates/playlist/protected-playlist-form.html +#: pod/playlist/views.py pod/stats/templates/stats/playlist-stats-view.html msgid "Playlists" msgstr "" -#: pod/playlist/models.py -msgid "Short description of the playlist." +#: pod/playlist/apps.py pod/playlist/signals.py +msgid "Your favorites videos." msgstr "" -#: pod/playlist/models.py pod/video/models.py -msgid "Visible" +#: pod/playlist/forms.py +msgid "General informations" +msgstr "" + +#: pod/playlist/forms.py +msgid "Security informations" +msgstr "" + +#: pod/playlist/forms.py pod/playlist/models.py +msgid "Please choose a password if this playlist is password-protected." +msgstr "" + +#: pod/playlist/forms.py pod/playlist/models.py +msgid "Promoted" +msgstr "" + +#: pod/playlist/forms.py pod/playlist/models.py +msgid "" +"Selecting this setting causes your playlist to be promoted on the page " +"listing promoted public playlists. However, if this setting is deactivated, " +"your playlist will still be accessible to everyone.
For general use, we " +"recommend that you leave this setting disabled." +msgstr "" + +#: pod/playlist/forms.py +#, python-brace-format +msgid "You cannot create a playlist named \"{FAVORITE_PLAYLIST_NAME}\"" +msgstr "" + +#: pod/playlist/forms.py +msgid "Remove playlist cannot be undone" +msgstr "" + +#: pod/playlist/models.py +#: pod/playlist/templates/playlist/playlist_visibility_icon.html +#: pod/playlist/utils.py pod/video/models.py +#: pod/video/templates/videos/video_note_comments_display.html +#: pod/video/templates/videos/video_note_display.html +msgid "Public" msgstr "" #: pod/playlist/models.py -msgid "If checked, the playlist can be visible to users other than the owner." +#: pod/playlist/templates/playlist/playlist_visibility_icon.html +#: pod/playlist/utils.py +msgid "Password-protected" msgstr "" #: pod/playlist/models.py -#: pod/playlist/templates/playlist/playlist_video_list.html -#: pod/playlist/templates/playlist_player.html +#: pod/playlist/templates/playlist/playlist_visibility_icon.html +#: pod/playlist/utils.py +msgid "Private" +msgstr "" + +#: pod/playlist/models.py pod/playlist/tests/test_models.py +#: pod/playlist/views.py pod/video/templates/videos/video.html msgid "Playlist" msgstr "" #: pod/playlist/models.py -msgid "Position of the video in a playlist." +msgid "Please choose a name between 1 and 250 characters." msgstr "" #: pod/playlist/models.py -msgid "Playlist element" +msgid "Please choose a description. This description is empty by default." +msgstr "" + +#: pod/playlist/models.py pod/playlist/templates/playlist/filter_aside.html +#: pod/playlist/templates/playlist/playlist-informations-card.html +#: pod/stats/templates/stats/playlist-stats-view.html +msgid "Right of access" msgstr "" #: pod/playlist/models.py -msgid "Playlist elements" +msgid "" +"\n" +" Please chosse a right of access among 'public', 'password-" +"protected', 'private'.\n" +" " msgstr "" -#: pod/playlist/models.py pod/playlist/views.py -msgid "A video in draft mode cannot be added to a playlist." +#: pod/playlist/models.py pod/video/templates/videos/video-info.html +msgid "Autoplay" msgstr "" -#: pod/playlist/models.py pod/playlist/views.py -msgid "A video with a password cannot be added to a playlist." +#: pod/playlist/models.py +msgid "Please choose if this playlist is an autoplay playlist or not." msgstr "" -#: pod/playlist/templates/my_playlists.html -#, python-format -msgid "%(counter)s playlist found" -msgid_plural "%(counter)s playlists found" -msgstr[0] "" -msgstr[1] "" +#: pod/playlist/models.py +msgid "Editable" +msgstr "" -#: pod/playlist/templates/my_playlists.html -msgid "No playlist found" +#: pod/playlist/models.py +msgid "Please choose if this playlist is editable or not." 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." +#: pod/playlist/models.py +msgid "You can add additional owners to the playlist." msgstr "" -#: pod/playlist/templates/my_playlists.html -#: pod/playlist/templates/playlist.html -#: pod/playlist/templates/playlist/playlist_list.html -#: pod/playlist/tests/test_views.py -msgid "Add a new playlist" +#: pod/playlist/models.py +msgid "Date created" msgstr "" -#: pod/playlist/templates/my_playlists.html -msgid "" -"This is the page of your playlists. Here you can create, edit or delete them." +#: pod/playlist/models.py +msgid "Date updated" msgstr "" -#: pod/playlist/templates/my_playlists.html -msgid "" -"A playlist with the eye symbol means that this playlist is visible to all " -"users when they view this page." +#: pod/playlist/models.py pod/recorder/models.py pod/video/models.py +#: pod/video/templates/videos/video_sort_select.html +msgid "Date added" +msgstr "" + +#: pod/playlist/models.py pod/video/templates/videos/video_sort_select.html +msgid "Rank" +msgstr "" + +#: pod/playlist/models.py +msgid "Playlist content" msgstr "" -#: pod/playlist/templates/playlist.html pod/playlist/tests/test_views.py -msgid "Editing the playlist" +#: pod/playlist/models.py +msgid "Playlist contents" +msgstr "" + +#: pod/playlist/templates/playlist/add_or_edit.html +#: pod/playlist/templates/playlist/playlist_link.html +#: pod/playlist/tests/test_views.py pod/playlist/views.py +msgid "Edit the playlist" +msgstr "" + +#: pod/playlist/templates/playlist/add_or_edit.html +#: pod/playlist/templates/playlist/playlists.html +#: pod/playlist/tests/test_views.py pod/playlist/views.py +msgid "Add a playlist" +msgstr "" + +#: pod/playlist/templates/playlist/button_start_playlist.html +msgid "Start the playlist" msgstr "" -#: pod/playlist/templates/playlist.html -msgid "This playlist has no videos yet." +#: pod/playlist/templates/playlist/delete.html +#, python-format +msgid "Delete the playlist %(name)s" msgstr "" -#: pod/playlist/templates/playlist.html +#: pod/playlist/templates/playlist/delete.html msgid "Back to my playlists" msgstr "" -#: pod/playlist/templates/playlist/player_controls.html -msgid "Repeat the playlist" +#: pod/playlist/templates/playlist/delete.html +msgid "To delete the playlist, please check the box in and click delete." msgstr "" -#: pod/playlist/templates/playlist/player_controls.html -msgid "Switch to next video automatically" +#: pod/playlist/templates/playlist/filter_aside.html +msgid "See my private playlists" msgstr "" -#: pod/playlist/templates/playlist/playlist_element_list.html -msgid "List of videos" +#: pod/playlist/templates/playlist/filter_aside.html +msgid "See my password-protected playlists" msgstr "" -#: pod/playlist/templates/playlist/playlist_element_list.html -msgid "Thumbnail" +#: pod/playlist/templates/playlist/filter_aside.html +msgid "See my public playlists" msgstr "" -#: pod/playlist/templates/playlist/playlist_element_list.html -msgid "Video thumbnail" +#: pod/playlist/templates/playlist/filter_aside.html +msgid "See my playlists" msgstr "" -#: pod/playlist/templates/playlist/playlist_element_list.html -msgid "Move up" +#: pod/playlist/templates/playlist/filter_aside.html +msgid "See playlists I can contribute" msgstr "" -#: pod/playlist/templates/playlist/playlist_element_list.html -msgid "Move down" +#: pod/playlist/templates/playlist/filter_aside.html +msgid "See all public playlists" msgstr "" -#: pod/playlist/templates/playlist/playlist_element_list.html -msgid "Save position" +#: pod/playlist/templates/playlist/filter_aside.html +msgid "See all promoted playlists" msgstr "" -#: pod/playlist/templates/playlist/playlist_list.html -msgid "This playlist is visible to all users." +#: pod/playlist/templates/playlist/filter_aside.html +msgid "See all playlists" msgstr "" -#: pod/playlist/templates/playlist/playlist_list.html -msgid "This playlist is only visible by you." +#: pod/playlist/templates/playlist/playlist-informations-card.html +msgid "Informations about the playlist" msgstr "" -#: pod/playlist/templates/playlist/playlist_list.html -msgid "Launch" +#: pod/playlist/templates/playlist/playlist-informations-card.html +msgid "Last updated on" msgstr "" -#: pod/playlist/templates/playlist/playlist_list.html -msgid "Sorry, no playlist found" +#: pod/playlist/templates/playlist/playlist-informations-card.html +msgid "at" msgstr "" -#: pod/playlist/templates/playlist/playlist_video_card.html -#: pod/video/templates/videos/card.html -msgid "This content is password protected." +#: pod/playlist/templates/playlist/playlist-informations-card.html +msgid "Playlist owner" msgstr "" -#: pod/playlist/templates/playlist/playlist_video_card.html -#: pod/video/templates/videos/card.html -msgid "This content is chaptered." +#: pod/playlist/templates/playlist/playlist-informations-card.html +msgid "Show statistics for the playlist" msgstr "" -#: pod/playlist/templates/playlist/playlist_video_card.html -#: pod/video/templates/videos/card.html -#: pod/video/templates/videos/category_modal_card.html -msgid "Video content." +#: pod/playlist/templates/playlist/playlist-informations-card.html +#: pod/stats/apps.py pod/stats/templates/stats/channel-stats-view.html +#: pod/stats/templates/stats/general-stats-view.html +#: pod/stats/templates/stats/meeting-stats-view.html +#: pod/stats/templates/stats/playlist-stats-view.html +#: pod/stats/templates/stats/user-stats-view.html +#: pod/stats/templates/stats/video-stats-view.html +msgid "Statistics" msgstr "" -#: pod/playlist/templates/playlist/playlist_video_card.html -#: pod/video/templates/videos/card.html -#: pod/video/templates/videos/category_modal_card.html -msgid "Audio content." +#: pod/playlist/templates/playlist/playlist-list-modal.html +msgid "Your playlists" msgstr "" -#: pod/playlist/views.py -msgid "You cannot edit this playlist." +#: pod/playlist/templates/playlist/playlist-list-modal.html +msgid "Add the video in a new playlist" msgstr "" -#: pod/playlist/views.py -msgid "You don't have access to this playlist." +#: pod/playlist/templates/playlist/playlist-management-card.html +msgid "Manage playlist" msgstr "" -#: pod/playlist/views.py +#: pod/playlist/templates/playlist/playlist-videos-list.html +#: pod/video/templates/videos/video_list.html +msgid "Sorry, no video found." +msgstr "" + +#: pod/playlist/templates/playlist/playlist.html +#: pod/playlist/templates/playlist/playlist_content.html +#: pod/video/templates/channel/channel.html +#: pod/video/templates/videos/my_videos.html +#: pod/video/templates/videos/videos.html +#: pod/video_search/templates/search/search.html #, python-format -msgid "%(title)s (%(count)d video)" -msgid_plural "%(title)s (%(count)d videos)" +msgid "%(counter)s video found" +msgid_plural "%(counter)s videos found" msgstr[0] "" msgstr[1] "" -#: pod/playlist/views.py -msgid "The playlist has been saved!" +#: pod/playlist/templates/playlist/playlist.html +#: pod/playlist/templates/playlist/playlist_content.html +msgid "Playlist videos" msgstr "" -#: pod/playlist/views.py -msgid "The request is wrong. No video given." +#: pod/playlist/templates/playlist/playlist.html +msgid "Reorganize your favorite videos" msgstr "" -#: pod/playlist/views.py -msgid "Only ajax request are accepted for this action." +#: pod/playlist/templates/playlist/playlist.html +msgid "Reorganize" msgstr "" -#: pod/playlist/views.py -msgid "This video has been removed from your playlist." +#: pod/playlist/templates/playlist/playlist.html +msgid "Help - Drag & Drop" msgstr "" -#: pod/playlist/views.py -msgid "The playlist have been saved." +#: pod/playlist/templates/playlist/playlist.html +msgid "Select the video to move by clicking and holding." +msgstr "Sélectionnez la vidéo à déplacer en cliquant et en maintenant." + +#: pod/playlist/templates/playlist/playlist.html +msgid "While holding down the video, drag it to the desired location." +msgstr "" +"Tout en maintenant la vidéo, faites-la glisser vers l'emplacement souhaité." + +#: pod/playlist/templates/playlist/playlist.html +msgid "Drop the video on another to swap their position." +msgstr "Déposez la vidéo sur une autre pour échanger leur position." + +#: pod/playlist/templates/playlist/playlist_card.html pod/video/models.py +msgid "videos" +msgstr "" + +#: pod/playlist/templates/playlist/playlist_card.html +#: pod/playlist/templates/playlist/playlist_player.html +msgid "Playlist image" +msgstr "" + +#: pod/playlist/templates/playlist/playlist_link.html +msgid "Remove the playlist" +msgstr "" + +#: pod/playlist/templates/playlist/playlist_player.html +msgid "Playlist:" +msgstr "" + +#: pod/playlist/templates/playlist/playlist_sort_select.html +#: pod/video/templates/videos/video_sort_select.html +msgid "Sort" +msgstr "" + +#: pod/playlist/templates/playlist/playlist_sort_select.html +#: pod/video/templates/videos/video_sort_select.html +msgid "Ascending sort" +msgstr "" + +#: pod/playlist/templates/playlist/playlist_sort_select.html +#: pod/video/templates/videos/video_sort_select.html +msgid "Descending sort" +msgstr "" + +#: pod/playlist/templates/playlist/playlist_sort_select.html +#: pod/video/templates/videos/video_sort_select.html +msgid "Sort Direction" +msgstr "" + +#: pod/playlist/templates/playlist/playlist_sort_select.html +msgid "Modification date" +msgstr "" + +#: pod/playlist/templates/playlist/playlist_sort_select.html +msgid "Creation date" +msgstr "" + +#: pod/playlist/templates/playlist/playlist_visibility_icon.html +msgid "Public and promoted" +msgstr "" + +#: pod/playlist/templates/playlist/playlists.html +#, python-format +msgid "%(counter)s playlist found" +msgid_plural "%(counter)s playlists found" +msgstr[0] "" +msgstr[1] "" + +#: pod/playlist/templates/playlist/playlists.html +msgid "No playlists found" +msgstr "" + +#: pod/playlist/templates/playlist/playlists.html +msgid "" +"You haven't got any playlist yet, please use the \"Add a playlist\" button " +"to add one." +msgstr "" + +#: pod/playlist/templates/playlist/protected-playlist-form.html +msgid "Protected playlist form" +msgstr "" + +#: pod/playlist/templates/playlist/protected-playlist-form.html +msgid "This playlist is protected by password, please fill in and click send." +msgstr "" + +#: pod/playlist/templates/playlist/protected-playlist-form.html +#: pod/video/templates/videos/video-form.html +msgid "If you do not have the password for this content, please" +msgstr "" + +#: pod/playlist/templates/playlist/protected-playlist-form.html +#: pod/video/templates/videos/video-form.html +msgid "contact its owner" +msgstr "" + +#: pod/playlist/templatetags/favorites_playlist.py +msgid "Favorites" +msgstr "" + +#: pod/playlist/tests/test_forms.py +#, fuzzy +#| msgid "Title field is required" +msgid "This field is required." +msgstr "Titelveld is verplicht" + +#: pod/playlist/tests/test_forms.py +msgid "You cannot create a playlist named \"Favorites\"" msgstr "" #: pod/playlist/views.py -msgid "The video has been added to your playlist." +msgid "The playlist has been deleted." msgstr "" #: pod/playlist/views.py -msgid "This playlist has been deleted." +msgid "The playlist has been created and the video has been added in it." msgstr "" #: pod/podfile/apps.py @@ -5836,8 +5978,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 @@ -5922,6 +6064,245 @@ msgstr "" msgid "Recorder for Studio not found." msgstr "" +#: pod/stats/templates/stats/channel-stats-view.html +msgid "Number of themes" +msgstr "" + +#: pod/stats/templates/stats/channel-stats-view.html +#: pod/stats/templates/stats/user-stats-view.html +msgid "Number of channels" +msgstr "" + +#: pod/stats/templates/stats/channel-stats-view.html +msgid "Graph of video evolution for the channel " +msgstr "" + +#: pod/stats/templates/stats/channel-stats-view.html +msgid "Breakdown of video status for the channel " +msgstr "" + +#: pod/stats/templates/stats/channel-stats-view.html +#: pod/stats/templates/stats/playlist-stats-view.html pod/stats/views.py +msgid "Statistics for playlists" +msgstr "" + +#: pod/stats/templates/stats/channel-stats-view.html +msgid "Breakdown of channels visibility status " +msgstr "" + +#: pod/stats/templates/stats/general-stats-view.html +#: pod/stats/templates/stats/user-stats-view.html +#: pod/stats/templates/stats/video-stats-view.html +msgid "Duration time of videos" +msgstr "" + +#: pod/stats/templates/stats/general-stats-view.html +#: pod/stats/templates/stats/video-stats-view.html +msgid "Most popular discipline" +msgstr "" + +#: pod/stats/templates/stats/general-stats-view.html +#: pod/stats/templates/stats/video-stats-view.html +msgid "No popular discipline" +msgstr "" + +#: pod/stats/templates/stats/general-stats-view.html +#: pod/stats/templates/stats/video-stats-view.html +msgid "Most popular video type" +msgstr "" + +#: pod/stats/templates/stats/general-stats-view.html +#: pod/stats/templates/stats/video-stats-view.html +msgid "No popular video type" +msgstr "" + +#: pod/stats/templates/stats/general-stats-view.html +msgid "Number of users" +msgstr "" + +#: pod/stats/templates/stats/general-stats-view.html +msgid "Statistics of videos" +msgstr "" + +#: pod/stats/templates/stats/general-stats-view.html +msgid "Graph of video evolution for " +msgstr "" + +#: pod/stats/templates/stats/general-stats-view.html +msgid "Breakdown of video status for " +msgstr "" + +#: pod/stats/templates/stats/playlist-stats-view.html +msgid "Playlist playback time" +msgstr "" + +#: pod/stats/templates/stats/playlist-stats-view.html +msgid "Playlist video statistics" +msgstr "" + +#: pod/stats/templates/stats/playlist-stats-view.html +#: pod/stats/templates/stats/video-stats-view.html +msgid "Graph of video evolution " +msgstr "" + +#: pod/stats/templates/stats/playlist-stats-view.html +msgid "Breakdown of video status for the playlist " +msgstr "" + +#: pod/stats/templates/stats/playlist-stats-view.html +msgid "Breakdown of playlists visibilities for " +msgstr "" + +#: pod/stats/templates/stats/user-stats-view.html +msgid "My statistics" +msgstr "" + +#: pod/stats/templates/stats/user-stats-view.html +msgid "Number of files" +msgstr "" + +#: pod/stats/templates/stats/user-stats-view.html +msgid "Number of videos added in favorites" +msgstr "" + +#: pod/stats/templates/stats/user-stats-view.html +msgid "Number of meetings" +msgstr "" + +#: pod/stats/templates/stats/user-stats-view.html +msgid "Prefered discipline" +msgstr "" + +#: pod/stats/templates/stats/user-stats-view.html +msgid "No prefered discipline" +msgstr "" + +#: pod/stats/templates/stats/user-stats-view.html +msgid "Prefered type" +msgstr "" + +#: pod/stats/templates/stats/user-stats-view.html +msgid "No prefered type" +msgstr "" + +#: pod/stats/templates/stats/user-stats-view.html +msgid "Statistics of your videos" +msgstr "" + +#: pod/stats/templates/stats/user-stats-view.html +msgid "Graph of video evolution for the user " +msgstr "" + +#: pod/stats/templates/stats/user-stats-view.html +msgid "Breakdown of video status for the user " +msgstr "" + +#: pod/stats/templates/stats/utils/pie-chart.html +#: pod/stats/templates/stats/utils/video-stats.html +#: pod/stats/templates/stats/utils/years-video-stats.html +msgid "Export to CSV" +msgstr "" + +#: pod/stats/templates/stats/utils/years-video-stats.html +msgid "Start year" +msgstr "" + +#: pod/stats/templates/stats/utils/years-video-stats.html +msgid "End year" +msgstr "" + +#: pod/stats/templates/stats/video-stats-view.html pod/video/apps.py +#: pod/video/models.py pod/video/templates/videos/videos.html +msgid "Videos" +msgstr "" + +#: pod/stats/templates/stats/video-stats-view.html +#: pod/video/templates/videos/video-info.html +msgid "Number of favorites" +msgstr "" + +#: pod/stats/templates/stats/video-stats-view.html +#: pod/video/templates/videos/video-info.html +msgid "Addition in a playlist" +msgstr "" + +#: pod/stats/templates/stats/video-stats-view.html +#: pod/video/templates/videos/video-info.html +msgid "Number of views" +msgstr "" + +#: pod/stats/templates/stats/video-stats-view.html +msgid "Graphics of videos" +msgstr "" + +#: pod/stats/templates/stats/video-stats-view.html +msgid "Graph of video evolution of " +msgstr "" + +#: pod/stats/templates/stats/video-stats-view.html +msgid "Breakdown of video status " +msgstr "" + +#: pod/stats/views.py +#, python-format +msgid "Video statistics: %s" +msgstr "" + +#: pod/stats/views.py +msgid "Site video statistics" +msgstr "" + +#: pod/stats/views.py +#, python-format +msgid "Video statistics for the theme %s" +msgstr "" + +#: pod/stats/views.py +#, python-format +msgid "Video statistics for the channel %s" +msgstr "" + +#: pod/stats/views.py +msgid "Statistics for channels" +msgstr "" + +#: pod/stats/views.py +#, python-format +msgid "Statistics for user %s" +msgstr "" + +#: pod/stats/views.py +msgid "Site statistics" +msgstr "" + +#: pod/stats/views.py +#, python-format +msgid "Statistics for the playlist %s" +msgstr "" + +#: pod/stats/views.py pod/video/templates/videos/videos.html +msgid "Video statistics" +msgstr "" + +#: pod/stats/views.py +#, python-format +msgid "The following video does not exist: %s" +msgstr "" + +#: pod/stats/views.py +#, python-format +msgid "You do not have access rights to this video: %s" +msgstr "" + +#: pod/stats/views.py +#, python-format +msgid "Statistics for the meeting %s" +msgstr "" + +#: pod/stats/views.py +msgid "Statistics for meetings" +msgstr "" + #: pod/urls.py msgid "Pod Administration" msgstr "" @@ -5938,11 +6319,6 @@ 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 "" @@ -6300,12 +6676,6 @@ msgstr "" msgid "Shared with video owner" msgstr "" -#: pod/video/models.py -#: pod/video/templates/videos/video_note_comments_display.html -#: pod/video/templates/videos/video_note_display.html -msgid "Public" -msgstr "" - #: pod/video/models.py #, python-format msgid "%(app)s version" @@ -6327,6 +6697,10 @@ msgstr "" msgid "The style will be added to your channel to show it" msgstr "" +#: pod/video/models.py +msgid "Visible" +msgstr "" + #: pod/video/models.py msgid "" "If checked, the channel appear in a list of available channels on the " @@ -6399,10 +6773,6 @@ msgstr "" msgid "Date to delete" msgstr "" -#: pod/video/models.py -msgid "videos" -msgstr "" - #: pod/video/models.py msgid "Sum of view" msgstr "" @@ -6539,8 +6909,11 @@ msgid "Show view statistics for all videos in this theme" msgstr "" #: pod/video/templates/channel/channel.html -#: pod/video/templates/videos/videos.html -msgid "Statistics views" +msgid "Theme statistics" +msgstr "" + +#: pod/video/templates/channel/channel.html +msgid "Channel statistics" msgstr "" #: pod/video/templates/channel/channel.html @@ -6720,6 +7093,24 @@ msgstr "" msgid "Help for form fields" msgstr "" +#: pod/video/templates/videos/card.html +msgid "This content is password protected." +msgstr "" + +#: pod/video/templates/videos/card.html +msgid "This content is chaptered." +msgstr "" + +#: pod/video/templates/videos/card.html +#: pod/video/templates/videos/category_modal_card.html +msgid "Video content." +msgstr "" + +#: pod/video/templates/videos/card.html +#: pod/video/templates/videos/category_modal_card.html +msgid "Audio content." +msgstr "" + #: pod/video/templates/videos/category_modal.html msgid "category title" msgstr "categorie titel" @@ -6811,6 +7202,10 @@ msgstr "" msgid "Show all videos" msgstr "" +#: pod/video/templates/videos/link_video.html +msgid "Remove from playlist" +msgstr "" + #: pod/video/templates/videos/link_video.html #: pod/video/templates/videos/video-info.html msgid "Remove from favorite" @@ -6873,14 +7268,6 @@ msgstr "" msgid "Other versions" msgstr "" -#: pod/video/templates/videos/video-all-info.html -msgid "Add the video to a playlist" -msgstr "" - -#: pod/video/templates/videos/video-all-info.html -msgid "Add current video to this playlist" -msgstr "" - #: pod/video/templates/videos/video-comment.html msgid "Comments have been disabled for this video." msgstr "" @@ -6917,24 +7304,16 @@ msgstr "" msgid "This video is protected by password, please fill in and click send." msgstr "" -#: pod/video/templates/videos/video-form.html -msgid "If you do not have the password for this content, please" -msgstr "" - -#: pod/video/templates/videos/video-form.html -msgid "contact its owner" -msgstr "" - #: pod/video/templates/videos/video-info.html msgid "Duration:" msgstr "" #: pod/video/templates/videos/video-info.html -msgid "Number of views" +msgid "Show details of view statistics" msgstr "" #: pod/video/templates/videos/video-info.html -msgid "Show details of view statistics" +msgid "Add the video to a playlist" msgstr "" #: pod/video/templates/videos/video-info.html @@ -7024,10 +7403,6 @@ msgstr "" msgid "Options" msgstr "" -#: pod/video/templates/videos/video-info.html -msgid "Autoplay" -msgstr "" - #: pod/video/templates/videos/video-info.html msgid "Check the box to autoplay the video." msgstr "" @@ -7236,28 +7611,8 @@ 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 "" - #: pod/video/templates/videos/videos.html -msgid "Show view statistics for all videos" +msgid "Show general statistics" msgstr "" #: pod/video/templatetags/video_tags.py @@ -7433,35 +7788,6 @@ msgstr "" msgid "You cannot access to this view." msgstr "" -#: pod/video/views.py -msgid "Pod video viewing statistics" -msgstr "" - -#: pod/video/views.py -#, python-format -msgid "Video viewing statistics for %s" -msgstr "" - -#: pod/video/views.py -#, python-format -msgid "Video viewing statistics for the channel %s" -msgstr "" - -#: pod/video/views.py -#, python-format -msgid "Video viewing statistics for the theme %s" -msgstr "" - -#: pod/video/views.py -#, python-format -msgid "You do not have access rights to this video: %s " -msgstr "" - -#: pod/video/views.py -#, python-format -msgid "The following video does not exist: %s" -msgstr "" - #: pod/video/views.py msgid "Media upload" msgstr "" diff --git a/pod/locale/nl/LC_MESSAGES/djangojs.mo b/pod/locale/nl/LC_MESSAGES/djangojs.mo index 6d9a0715fc..e190f09b0b 100644 Binary files a/pod/locale/nl/LC_MESSAGES/djangojs.mo and b/pod/locale/nl/LC_MESSAGES/djangojs.mo differ diff --git a/pod/locale/nl/LC_MESSAGES/djangojs.po b/pod/locale/nl/LC_MESSAGES/djangojs.po index ee5809d4cc..be526d0581 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-07-05 15:50+0200\n" +"POT-Creation-Date: 2023-08-21 08:32+0000\n" "PO-Revision-Date: 2023-02-08 15:22+0100\n" "Last-Translator: obado \n" "Language-Team: \n" @@ -20,24 +20,18 @@ msgstr "" msgid "Get time from the player" msgstr "" -#: pod/chapter/static/js/chapters.js pod/enrichment/static/js/enrichment.js -#: pod/main/static/js/main.js pod/video/static/js/comment-script.js -msgid "Close" -msgstr "" - #: pod/chapter/static/js/chapters.js pod/completion/static/js/completion.js -#: pod/enrichment/static/js/enrichment.js pod/playlist/static/js/playlist.js +#: pod/enrichment/static/js/enrichment.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/playlist/static/js/playlist.js +#: pod/enrichment/static/js/enrichment.js msgid "The form could not be recovered." msgstr "" #: pod/chapter/static/js/chapters.js pod/completion/static/js/completion.js #: pod/enrichment/static/js/enrichment.js pod/main/static/js/main.js -#: pod/playlist/static/js/playlist.js #: pod/podfile/static/podfile/js/filewidget.js msgid "You are no longer authenticated. Please log in again." msgstr "" @@ -161,16 +155,6 @@ msgstr "" msgid "Pause to enter caption for segment from %s to %s." msgstr "" -#: pod/completion/static/js/caption_maker.js -#: pod/podfile/static/podfile/js/filewidget.js -msgid "Add" -msgstr "" - -#: pod/completion/static/js/caption_maker.js -#: pod/video/static/js/comment-script.js -msgid "Delete" -msgstr "" - #: pod/completion/static/js/caption_maker.js msgid "Caption" msgstr "" @@ -273,6 +257,11 @@ msgstr "" msgid "Iframe and Script tags are not allowed." msgstr "" +#: pod/enrichment/static/js/enrichment.js pod/main/static/js/main.js +#: pod/video/static/js/comment-script.js +msgid "Close" +msgstr "" + #: pod/enrichment/static/js/enrichment.js msgid "Please enter a correct start from 0 to " msgstr "" @@ -365,34 +354,6 @@ msgstr "" msgid "Enrich mode" msgstr "" -#: pod/favorite/static/js/favorite-reorganize.js -msgid "Save your reorganization" -msgstr "" - -#: pod/favorite/static/js/favorite-reorganize.js -msgid "Save" -msgstr "" - -#: pod/favorite/static/js/video-favorites-card-delete.js -msgid "The video could not be removed from favorites..." -msgstr "" - -#: pod/favorite/static/js/video-favorites-card-list.js -msgid "Remove from favorite" -msgstr "" - -#: pod/favorite/static/js/video-favorites-card-list.js -msgid "Add in favorite" -msgstr "" - -#: pod/favorite/static/js/video-favorites-card-list.js -msgid "The deletion couldn't be completed..." -msgstr "" - -#: pod/favorite/static/js/video-favorites.js -msgid "The favorite couldn’t be completed…" -msgstr "" - #: pod/live/static/js/admin_broadcaster.js msgid "An error occurred" msgstr "" @@ -419,6 +380,14 @@ msgstr "" msgid "An error occurred during broadcasters loading..." msgstr "" +#: pod/main/static/js/filter-aside-element-list-refresh.js +msgid "Descending sort" +msgstr "" + +#: pod/main/static/js/filter-aside-element-list-refresh.js +msgid "Ascending sort" +msgstr "" + #: pod/main/static/js/main.js msgid "User not found" msgstr "" @@ -475,35 +444,31 @@ msgstr "" msgid "The file extension not in the allowed extension:" msgstr "" -#: pod/playlist/static/js/playlist.js -msgid "Position saved" +#: pod/playlist/static/playlist/js/add-or-edit.js +msgid "Public: the playlist can be accessed by anyone." 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." +#: pod/playlist/static/playlist/js/add-or-edit.js +msgid "" +"Password-protected: the playlist can be accessed by anyone with the " +"appropriate link and password." msgstr "" -#: pod/playlist/static/js/playlist.js -msgid "The video can not be added from this page." +#: pod/playlist/static/playlist/js/add-or-edit.js +msgid "Private: only you have access to this playlist." msgstr "" -#: pod/playlist/static/js/playlist.js -msgid "The video slug not found." +#: pod/playlist/static/playlist/js/filter-aside-playlist-list-refresh.js +#: pod/video/static/js/filter_aside_video_list_refresh.js +msgid "An Error occurred while processing." msgstr "" -#: pod/playlist/static/js/playlist.js -msgid "" -"Error getting video information. The video information could not be " -"retrieved." +#: pod/playlist/static/playlist/js/playlist-reorganize.js +msgid "Save your reorganization" msgstr "" -#: pod/podfile/static/podfile/js/filewidget.js -#: pod/video/static/js/change_video_owner.js -msgid "Loading…" +#: pod/playlist/static/playlist/js/playlist-reorganize.js +msgid "Save" msgstr "" #: pod/podfile/static/podfile/js/filewidget.js @@ -534,6 +499,10 @@ msgstr "" msgid "Server error" msgstr "" +#: pod/podfile/static/podfile/js/filewidget.js +msgid "Add" +msgstr "" + #: pod/podfile/static/podfile/js/filewidget.js msgid "Are you sure you want to delete this folder?" msgstr "" @@ -546,10 +515,48 @@ msgstr "" msgid "This folder is empty" msgstr "" +#: pod/stats/static/stats/js/video_stats_view.js +#: pod/stats/static/stats/js/video_stats_view_global.js +msgid "Views" +msgstr "" + +#: pod/stats/static/stats/js/video_stats_view.js +#: pod/stats/static/stats/js/video_stats_view_global.js +msgid "Favorites" +msgstr "" + +#: pod/stats/static/stats/js/video_stats_view.js +#: pod/stats/static/stats/js/video_stats_view_global.js +msgid "Playlist additions" +msgstr "" + +#: pod/stats/static/stats/js/video_stats_view.js +#: pod/stats/static/stats/js/video_stats_view_global.js +msgid "Date" +msgstr "" + +#: pod/stats/static/stats/js/video_stats_view.js +#: pod/stats/static/stats/js/video_stats_view_global.js +msgid "Value" +msgstr "" + +#: pod/stats/static/stats/js/video_stats_view.js +#: pod/stats/static/stats/js/video_stats_view_global.js +msgid "Playlists_addition" +msgstr "" + +#: pod/stats/static/stats/js/video_stats_view_global.js +msgid "Years" +msgstr "" + #: pod/video/static/js/change_video_owner.js msgid "No element found" msgstr "" +#: pod/video/static/js/change_video_owner.js +msgid "Loading…" +msgstr "" + #: pod/video/static/js/change_video_owner.js msgid "An error occurred during the change of owner" msgstr "" @@ -567,40 +574,21 @@ msgid "Answers" msgstr "" #: pod/video/static/js/comment-script.js -msgid "Cancel" -msgstr "" - -#: pod/video/static/js/comment-script.js -#, javascript-format -msgid "%s vote" -msgid_plural "%s votes" -msgstr[0] "" -msgstr[1] "" - -#: pod/video/static/js/comment-script.js -msgid "Agree with the comment" +msgid "Delete" msgstr "" #: pod/video/static/js/comment-script.js -msgid "Reply to comment" +msgid "Cancel" msgstr "" #: pod/video/static/js/comment-script.js -msgid "Reply" +msgid "Agree with the comment" msgstr "" #: pod/video/static/js/comment-script.js msgid "Remove this comment" msgstr "" -#: pod/video/static/js/comment-script.js -msgid "Add a public comment" -msgstr "" - -#: pod/video/static/js/comment-script.js -msgid "Send" -msgstr "" - #: pod/video/static/js/comment-script.js msgid "Show answers" msgstr "" @@ -613,6 +601,13 @@ msgstr "" msgid "Sorry, you're not allowed to vote by now." msgstr "" +#: pod/video/static/js/comment-script.js +#, javascript-format +msgid "%s vote" +msgid_plural "%s votes" +msgstr[0] "" +msgstr[1] "" + #: pod/video/static/js/comment-script.js msgid "Sorry, you can't comment this video by now." msgstr "" @@ -632,60 +627,39 @@ msgid_plural "%s comments" msgstr[0] "" msgstr[1] "" -#: pod/video/static/js/filter_aside_video_list_refresh.js -msgid "Descending sort" -msgstr "" - -#: pod/video/static/js/filter_aside_video_list_refresh.js -msgid "Ascending sort" -msgstr "" - -#: pod/video/static/js/filter_aside_video_list_refresh.js -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 "" @@ -745,18 +719,6 @@ msgstr "" msgid "Edit the category" msgstr "" -#: pod/video/static/js/video_category.js -msgid "Delete the category" -msgstr "" - -#: pod/video/static/js/video_category.js -msgid "Success!" -msgstr "" - -#: pod/video/static/js/video_category.js -msgid "Error…" -msgstr "" - #: pod/video/static/js/video_category.js msgid "Category created successfully" msgstr "" @@ -773,42 +735,5 @@ msgstr "" msgid "Select the general type of the video." msgstr "" -#: pod/video/static/js/video_stats_view.js -msgid "Title" -msgstr "Titel" - -#: pod/video/static/js/video_stats_view.js -msgid "View during the day" -msgstr "" - -#: pod/video/static/js/video_stats_view.js -msgid "View during the month" -msgstr "" - -#: pod/video/static/js/video_stats_view.js -msgid "View during the year" -msgstr "" - -#: pod/video/static/js/video_stats_view.js -msgid "Total view from creation" -msgstr "" - -#: pod/video/static/js/video_stats_view.js -msgid "Favorite additions during the day" -msgstr "" - -#: pod/video/static/js/video_stats_view.js -msgid "Favorite additions during the month" -msgstr "" - -#: pod/video/static/js/video_stats_view.js -msgid "Favorite additions during the year" -msgstr "" - -#: pod/video/static/js/video_stats_view.js -msgid "Total favorite additions from creation" -msgstr "" - -#: pod/video/static/js/video_stats_view.js -msgid "Slug" -msgstr "" +#~ msgid "Title" +#~ msgstr "Titel" diff --git a/pod/main/configuration.json b/pod/main/configuration.json index a21dff3f0e..48c7640ad1 100644 --- a/pod/main/configuration.json +++ b/pod/main/configuration.json @@ -1563,10 +1563,76 @@ } }, "playlist": { - "description": {}, - "settings": {}, + "description": { + "en": [ + "Playlist app for the playlist management.", + "Set `USE_PLAYLIST` to True to activate this application." + ], + "fr": [ + "Application Playlist pour la gestion des playlists.", + "Mettre `USE_PLAYLIST` à True pour activer cette application." + ] + }, + "settings": { + "DEFAULT_PLAYLIST_THUMBNAIL": { + "default_value": "/static/playlist/img/default-playlist.svg", + "description": { + "en": [ + "Default image displayed as a poster or thumbnail, used to present the playlist.", + "This image must be located in the `static` directory." + ], + "fr": [ + "Image par défaut affichée comme poster ou vignette, utilisée pour présenter la playlist.", + "Cette image doit se situer dans le répertoire `static`." + ] + }, + "pod_version_end": "", + "pod_version_init": "3.4" + }, + "COUNTDOWN_PLAYLIST_PLAYER": { + "default_value": 0, + "description": { + "en": [ + "Countdown used between each video when playing an autoplay playlist.", + "The coutdown is not present if it at 0." + ], + "fr": [ + "Compte à rebours utilisé entre chaque vidéo lors de la lecture d'une playlist en lecture automatique.", + "Le compte à rebours n'est pas présent s'il est à 0." + ] + }, + "pod_version_end": "", + "pod_version_init": "3.4" + }, + "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." + ] + }, + "pod_version_end": "", + "pod_version_init": "3.4" + }, + "USE_PLAYLIST": { + "default_value": true, + "description": { + "en": [ + "Activation of playlist. Allows users to add videos in a playlist." + ], + "fr": [ + "Activation des playlist. Permet aux utilisateurs d'ajouter des vidéos dans une playlist." + ] + }, + "pod_version_end": "", + "pod_version_init": "3.4" + } + }, "title": { - "en": "", + "en": "Playlist application configuration", "fr": "Configuration application playlist" } }, @@ -2237,17 +2303,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_OBSOLESCENCE": { "default_value": false, "description": { diff --git a/pod/main/rest_router.py b/pod/main/rest_router.py index d5e4c04ddf..d828dd2f67 100644 --- a/pod/main/rest_router.py +++ b/pod/main/rest_router.py @@ -4,13 +4,13 @@ from django.conf.urls import include from pod.authentication import rest_views as authentication_views from pod.video import rest_views as video_views -from pod.playlist import rest_views as playlist_views from pod.main import rest_views as main_views from pod.authentication import rest_views as auth_views from pod.video_encode_transcript import rest_views as encode_views from pod.chapter import rest_views as chapter_views from pod.completion import rest_views as completion_views +from pod.playlist import rest_views as playlist_views from pod.recorder import rest_views as recorder_views from django.conf import settings @@ -45,8 +45,7 @@ router.register(r"playlist_videos", encode_views.PlaylistVideoViewSet) router.register(r"view_count", video_views.ViewCountViewSet) -router.register(r"playlist", playlist_views.PlaylistViewSet) -router.register(r"playlist_element", playlist_views.PlaylistElementViewSet) +router.register(r"playlists", playlist_views.PlaylistViewSet) router.register(r"contributors", completion_views.ContributorViewSet) router.register(r"documents", completion_views.DocumentViewSet) diff --git a/pod/main/static/css/pod.css b/pod/main/static/css/pod.css index b648b26b01..5e83d8c8be 100755 --- a/pod/main/static/css/pod.css +++ b/pod/main/static/css/pod.css @@ -537,8 +537,7 @@ tr, margin: .1rem; } -#videos_list .card-header, -.playlist-videos .card-header { +#videos_list .card-header { /*position: absolute; width: 100%; background: var(--color-black-alpha); @@ -1696,3 +1695,9 @@ table .alert.alert-danger.btn.pod-btn-social { z-index: 3000; background-color: var(--pod-background) !important; } + +div.disabled, a.player-element.disabled { + background-image: linear-gradient(45deg, rgba(0, 0, 0, 0.2) 25%, transparent 25%, transparent 50%, rgba(0, 0, 0, 0.2) 50%, rgba(0, 0, 0, 0.2) 75%, transparent 75%, transparent); + background-size: 4px 4px; + background-repeat: repeat; +} diff --git a/pod/main/static/js/filter-aside-element-list-refresh.js b/pod/main/static/js/filter-aside-element-list-refresh.js new file mode 100644 index 0000000000..b2c4897460 --- /dev/null +++ b/pod/main/static/js/filter-aside-element-list-refresh.js @@ -0,0 +1,36 @@ +var sortDirectionChars = ["8600", "8599"]; +var sortDirectionTitle = [ + gettext("Descending sort"), + gettext("Ascending sort"), +]; + +/** + * Update arrow char of ascending or descending sort order. + * @param {*} sortDirectionAsc + */ +function updateSortDirectionChar(sortDirectionAsc) { + document.getElementById("sort_direction_label").innerHTML = + "&#" + sortDirectionChars[+sortDirectionAsc].toString(); +} + +/** + * Update title for input sort direction. + * @param {*} sortDirectionAsc + */ +function updateSortDirectionTitle(sortDirectionAsc) { + let newTitle = sortDirectionTitle[+sortDirectionAsc]; + document + .getElementById("sort_direction_label") + .setAttribute("title", newTitle); +} + +/** + * Toggle direction of sort. + */ +function toggleSortDirection() { + document.getElementById("sort_direction").checked = + !document.getElementById("sort_direction").checked; + const direction = document.getElementById("sort_direction").checked; + updateSortDirectionChar(direction); + updateSortDirectionTitle(direction); +} diff --git a/pod/main/static/js/infinite.js b/pod/main/static/js/infinite.js index ad8bc53190..e7bbb365d5 100644 --- a/pod/main/static/js/infinite.js +++ b/pod/main/static/js/infinite.js @@ -101,6 +101,10 @@ class InfiniteLoader { element.innerHTML += html.getElementById("videos_list").innerHTML; this.next_page_number += 1; + const favoritesButtons = document.getElementsByClassName("favorite-btn-link"); + for (let btn of favoritesButtons) { + preventRefreshButton(btn, true); + } } this.callBackAfterLoad(); }); diff --git a/pod/main/templates/footer.html b/pod/main/templates/footer.html index 747017db2f..cf47ec1059 100644 --- a/pod/main/templates/footer.html +++ b/pod/main/templates/footer.html @@ -1,5 +1,6 @@ {% load static %} {% load i18n %} +{% load general_stats %} {% spaceless %}

@@ -31,6 +32,11 @@

- + + {% endspaceless %} diff --git a/pod/main/templates/navbar.html b/pod/main/templates/navbar.html index 97241c9381..73256d4a1c 100644 --- a/pod/main/templates/navbar.html +++ b/pod/main/templates/navbar.html @@ -5,6 +5,8 @@ {% get_language_info_list for LANGUAGES as languages %} {% load thumbnail %} {% load navbar %} +{% load user_stats %} +{% load favorites_playlist %} +{% endblock page_content %} +{% block collapse_page_aside %}{% endblock collapse_page_aside %} +{% block page_aside %}{% endblock page_aside %} + +{% block more_script %} + +{% endblock %} \ No newline at end of file diff --git a/pod/stats/templates/stats/utils/pie-chart.html b/pod/stats/templates/stats/utils/pie-chart.html new file mode 100644 index 0000000000..24ff94b4e0 --- /dev/null +++ b/pod/stats/templates/stats/utils/pie-chart.html @@ -0,0 +1,70 @@ +{% load static i18n %} +
+ + +
+{% block more_script %} + + + + + +{% endblock %} diff --git a/pod/stats/templates/stats/utils/stats-item.html b/pod/stats/templates/stats/utils/stats-item.html new file mode 100644 index 0000000000..cc9f5d82f2 --- /dev/null +++ b/pod/stats/templates/stats/utils/stats-item.html @@ -0,0 +1,19 @@ +
+
+ +
+
+ {% if url is not None %} + + {{ label }} + + {% else %} + {{ label }} + {% endif %} +
+ {% if number is not None %} +
{{ number }}
+ {% elif text is not None %} +
{{ text }}
+ {% endif %} +
\ No newline at end of file diff --git a/pod/stats/templates/stats/utils/video-stats.html b/pod/stats/templates/stats/utils/video-stats.html new file mode 100644 index 0000000000..14a0f095fe --- /dev/null +++ b/pod/stats/templates/stats/utils/video-stats.html @@ -0,0 +1,29 @@ +{% load static i18n %} + +
+
+ + +
+
+ + +
+
+
+ + +
+{% block more_script %} + + + + + + +{% endblock %} \ No newline at end of file diff --git a/pod/stats/templates/stats/utils/years-video-stats.html b/pod/stats/templates/stats/utils/years-video-stats.html new file mode 100644 index 0000000000..8380680368 --- /dev/null +++ b/pod/stats/templates/stats/utils/years-video-stats.html @@ -0,0 +1,29 @@ +{% load static i18n %} + +
+
+ + +
+
+ + +
+
+
+ + +
+{% block more_script %} + + + + + + +{% endblock %} \ No newline at end of file diff --git a/pod/stats/templates/stats/video-stats-view.html b/pod/stats/templates/stats/video-stats-view.html new file mode 100644 index 0000000000..8c396df215 --- /dev/null +++ b/pod/stats/templates/stats/video-stats-view.html @@ -0,0 +1,84 @@ +{% extends 'stats/utils/base-stats.html' %} +{% load static i18n %} +{% load playlist_stats %} +{% load general_stats %} + +{% block breadcrumbs %} + {{ block.super }} + + {% if not slug %} + + {% else %} + + + {% endif %} +{% endblock %} + +{% block stats_items %} + {% if slug %} + {% get_total_favorites_video video as get_total_favorites_video %} + {% include "stats/utils/stats-item.html" with icon="bi bi-star" label=_("Number of favorites") number=get_total_favorites_video %} + + {% get_count_video_added_in_playlist video as get_count_video_added_in_playlist %} + {% include "stats/utils/stats-item.html" with icon="bi bi-list-ul" label=_("Addition in a playlist") number=get_count_video_added_in_playlist %} + + {% include "stats/utils/stats-item.html" with icon="bi bi-eye" label=_("Number of views") number=video.get_viewcount %} + + {% else %} + {% url 'video:my_videos' as url_for_videos %} + {% include "stats/utils/stats-item.html" with icon="bi bi-film" url=url_for_videos label=_("Number of videos") number=videos|length %} + + {% get_total_time_videos videos as get_total_time_videos %} + {% include "stats/utils/stats-item.html" with icon="bi bi-clock" label=_("Duration time of videos") number=get_total_time_videos %} + + {% if prefered_discipline %} + {% url 'videos:videos' as videos_url %} + {% with url_for_prefered_discipline=videos_url|add:"?discipline="|add:prefered_discipline.slug %} + {% include "stats/utils/stats-item.html" with icon="bi bi-book" url=url_for_prefered_discipline label=_("Most popular discipline") text=prefered_discipline %} + {% endwith %} + {% else %} + {% include "stats/utils/stats-item.html" with icon="bi bi-book" label=_("Most popular discipline") text=_("No popular discipline") %} + {% endif %} + + {% if prefered_type %} + {% url 'videos:videos' as videos_url %} + {% with url_for_prefered_type=videos_url|add:"?type="|add:prefered_type.slug %} + {% include "stats/utils/stats-item.html" with icon="bi bi-tv" url=url_for_prefered_type label=_("Most popular video type") text=prefered_type %} + {% endwith %} + {% else %} + {% include "stats/utils/stats-item.html" with icon="bi bi-tv" label=_("Most popular video type") text=_("No popular video type") %} + {% endif %} + {% endif %} +{% endblock stats_items %} + +{% block other_stats %} +

{% trans "Graphics of videos" %}

+ + {% if slug %} + {% trans "Graph of video evolution of " as graph_title_prefix %} + {% include "stats/utils/video-stats.html" with graph_id="videoEvolutionChart" graph_title=graph_title_prefix|add:slug %} + {% else %} +
+
+ {% trans "Graph of video evolution " as graph_title_prefix %} + {% include "stats/utils/years-video-stats.html" with graph_id="videosEvolutionChart" graph_title=graph_title_prefix %} +
+
+ {% trans "Breakdown of video status " as graph_title_prefix %} + {% include "stats/utils/pie-chart.html" with graph_id="statusChart" graph_data=status_datas graph_title=graph_title_prefix %} +
+
+ {% endif %} +{% endblock other_stats %} diff --git a/pod/favorite/templatetags/__init__.py b/pod/stats/templatetags/__init__.py similarity index 100% rename from pod/favorite/templatetags/__init__.py rename to pod/stats/templatetags/__init__.py diff --git a/pod/stats/templatetags/channel_stats.py b/pod/stats/templatetags/channel_stats.py new file mode 100644 index 0000000000..7ec79113e3 --- /dev/null +++ b/pod/stats/templatetags/channel_stats.py @@ -0,0 +1,20 @@ +from django.template import Library + +from pod.stats.utils import number_themes +from pod.video.models import Channel + +register = Library() + + +@register.simple_tag(takes_context=False, name="get_number_themes") +def get_number_themes(channel: Channel = None) -> int: + """ + Get the total number of themes associated with a channel. + + Args: + channel (Channel, optional): The channel for which to retrieve the number of themes. Defaults to None. + + Returns: + int: The total number of themes associated with the channel. + """ + return number_themes(channel) diff --git a/pod/stats/templatetags/general_stats.py b/pod/stats/templatetags/general_stats.py new file mode 100644 index 0000000000..3273f93e86 --- /dev/null +++ b/pod/stats/templatetags/general_stats.py @@ -0,0 +1,50 @@ +from typing import List +from django.template import Library, RequestContext + +from pod.stats.utils import number_users, number_videos, total_time_videos +from pod.video.models import Video + +register = Library() + + +@register.simple_tag(takes_context=True, name="get_total_time_videos") +def get_total_time_videos(context: RequestContext, video_list: List[Video] = None) -> str: + """ + Get the total duration of videos in the specified list. + + Args: + context (RequestContext): The context. + video_list (List[Video], optional): The list of videos. Defaults to None. + + Returns: + str: The formatted total duration of videos in HH:MM:SS format. + """ + request = context["request"] + return total_time_videos(request, video_list) + + +@register.simple_tag(takes_context=True, name="get_number_videos") +def get_number_videos(context: RequestContext, video_list: List[Video] = None) -> int: + """ + Get the total number of videos in the specified list. + + Args: + context (RequestContext): The context. + video_list (List[Video], optional): The list of videos. Defaults to None. + + Returns: + int: The total number of videos. + """ + request = context["request"] + return number_videos(request, video_list) + + +@register.simple_tag(takes_context=False, name="get_number_users") +def get_number_users() -> int: + """ + Get the total number of users. + + Returns: + int: The total number of users. + """ + return number_users() diff --git a/pod/stats/templatetags/playlist_stats.py b/pod/stats/templatetags/playlist_stats.py new file mode 100644 index 0000000000..372af23c06 --- /dev/null +++ b/pod/stats/templatetags/playlist_stats.py @@ -0,0 +1,84 @@ +from django.template import Library +from pod.playlist.models import Playlist + +from pod.video.models import Video + +from pod.playlist.utils import ( + get_additional_owners, + get_count_video_added_in_playlist as total_additions_playlist_utils, + get_total_favorites_video as total_favorites_utils, + get_number_video_in_playlist as total_videos_in_playlist, + playlist_visibility, +) + +register = Library() + + +@register.simple_tag(name="get_total_favorites_video") +def get_total_favorites_video(video: Video) -> int: + """ + Get the total number of times a video has been marked as a favorite. + + Args: + video (:class:`pod.video.models.Video`): The video for which to retrieve the total number of favorites. + + Returns: + int: The total number of favorites for the video. + """ + return total_favorites_utils(video) + + +@register.simple_tag(name="get_count_video_added_in_playlist") +def get_count_video_added_in_playlist(video: Video) -> int: + """ + Get the total number of times a video has been added to playlists. + + Args: + video (:class:`pod.video.models.Video`): The video for which to retrieve the total number of additions to playlists. + + Returns: + int: The total number of additions to playlists for the video. + """ + return total_additions_playlist_utils(video) + + +@register.simple_tag(name="get_number_video_in_playlist") +def get_number_video_in_playlist(playlist: Playlist) -> int: + """ + Get the number of videos in a playlist. + + Args: + playlist (:class:`pod.playlist.models.Playlist`): The playlist for which to retrieve the number of videos. + + Returns: + int: The number of videos in the playlist. + """ + return total_videos_in_playlist(playlist) + + +@register.simple_tag(name="get_number_additional_owners_playlist") +def get_number_additional_owners_playlist(playlist: Playlist) -> int: + """ + Get the number of additional owners of a playlist. + + Args: + playlist (:class:`pod.playlist.models.Playlist`): The playlist for which to retrieve the number of additional owners. + + Returns: + int: The number of additional owners of the playlist. + """ + return get_additional_owners(playlist).count() + + +@register.simple_tag(name="get_playlist_visibility") +def get_playlist_visibility(playlist: Playlist) -> str: + """ + Get the visibility status of a playlist. + + Args: + playlist (:class:`pod.playlist.models.Playlist`): The playlist for which to retrieve the visibility status. + + Returns: + str: The visibility status of the playlist. + """ + return playlist_visibility(playlist) diff --git a/pod/stats/templatetags/user_stats.py b/pod/stats/templatetags/user_stats.py new file mode 100644 index 0000000000..f06a8a4762 --- /dev/null +++ b/pod/stats/templatetags/user_stats.py @@ -0,0 +1,106 @@ +from django.template import Library, RequestContext +from pod.playlist.utils import get_number_playlist + +from pod.stats.utils import ( + number_channels, + number_favorites, + number_files, + number_meetings, + number_videos, +) + +from pod.video.models import Video + +register = Library() + + +@register.simple_tag(takes_context=True, name="get_number_video_user") +def get_number_video_user(context: RequestContext) -> int: + """ + Get the number of videos for a user. + + Args: + context (RequestContext): The context. + + Returns: + int: The number of videos for the user. + """ + request = context["request"] + user_video_list = Video.objects.filter(owner=request.user) + return number_videos(request, user_video_list) + + +@register.simple_tag(takes_context=True, name="get_number_playlist_user") +def get_number_playlist_user(context: RequestContext): + """ + Get the number of playlists for a user. + + Args: + context (RequestContext): The context. + + Returns: + int: The number of playlists for the user. + """ + request = context["request"] + return get_number_playlist(request.user) + + +@register.simple_tag(takes_context=True, name="get_number_files_user") +def get_number_files_user(context: RequestContext): + """ + Get the number of files for a user. + + Args: + context (RequestContext): The context. + + Returns: + int: The number of files for the user. + """ + request = context["request"] + return number_files(request.user) + + +@register.simple_tag(takes_context=True, name="get_number_favorites_user") +def get_number_favorites_user(context: RequestContext): + """ + Get the number of favorites for a user. + + Args: + context (RequestContext): The context. + + Returns: + int: The number of favorites for user. + """ + request = context["request"] + return number_favorites(request.user) + + +@register.simple_tag(takes_context=True, name="get_number_meetings_user") +def get_number_meetings_user(context: RequestContext): + """ + Get the number of meetings for a user. + + Args: + context (RequestContext): The context. + + Returns: + int: The number of meetings for user. + """ + request = context["request"] + return number_meetings(request.user) + + +@register.simple_tag(takes_context=True, name="get_number_channels") +def get_number_channels(context: RequestContext, target: str = None): + """ + Get the number of channels for a user. + + Args: + context (RequestContext): The context. + target (str, optional): The target can be "user" or "None". Defaults to None. + + Returns: + int: The number of channels for user if the target is "user", or the number of all channels if target is "None". + """ + request = context["request"] + return number_channels(request, target) diff --git a/pod/stats/tests.py b/pod/stats/tests.py new file mode 100644 index 0000000000..7ce503c2dd --- /dev/null +++ b/pod/stats/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/pod/stats/urls.py b/pod/stats/urls.py new file mode 100644 index 0000000000..6940ba8e66 --- /dev/null +++ b/pod/stats/urls.py @@ -0,0 +1,38 @@ +from django.urls import path +from django.conf import settings + +from .views import ( + channel_stats_view, + general_stats_view, + meeting_stats_view, + playlist_stats_view, + to_do, + user_stats_view, + video_stats_view, +) + +app_name = "stats" + +if getattr(settings, "USE_STATS_VIEW", False): + urlpatterns = [ + path("", general_stats_view, name="general-stats"), + # USERS + path("my-stats/", user_stats_view, name="my-stats"), + # VIDEOS + path("videos/", video_stats_view, name="video-stats"), + path("videos/", video_stats_view, name="video-stats"), + # CHANNELS + path("channels/", channel_stats_view, name="channels-stats"), + path("channels/", channel_stats_view, name="channels-stats"), + path( + "channels//", + channel_stats_view, + name="channels-stats", + ), + # PLAYLISTS + path("playlists/", playlist_stats_view, name="playlist-stats"), + path("playlists/", playlist_stats_view, name="playlist-stats"), + # MEETINGS + path("meetings/", meeting_stats_view, name="meeting-stats"), + path("meetings/", meeting_stats_view, name="meeting-stats"), + ] diff --git a/pod/stats/utils.py b/pod/stats/utils.py new file mode 100644 index 0000000000..6323e450d0 --- /dev/null +++ b/pod/stats/utils.py @@ -0,0 +1,469 @@ +"""Esup-Pod stats utilities.""" +from collections import Counter +from typing import List +from datetime import date, timedelta + +from django.http import HttpRequest +from django.shortcuts import get_object_or_404 +from django.db.models import Sum +from django.core.cache import cache +from django.contrib.auth.models import User +from django.contrib.sites.shortcuts import get_current_site +from django.conf import settings + +from pod.meeting.models import Meeting +from pod.playlist.models import Playlist, PlaylistContent +from pod.playlist.apps import FAVORITE_PLAYLIST_NAME +from pod.playlist.utils import ( + get_favorite_playlist_for_user, + get_number_video_in_playlist, +) +from pod.podfile.models import UserFolder +from pod.video.context_processors import get_available_videos +from pod.video.models import Channel, Theme, Video, ViewCount + +from json import dumps + +CACHE_EXPIRATION = 300 # Cache expiration time in seconds + + +def get_videos_stats( + video_list: List[Video], date_filter: date, mode: str = None +) -> dict: + """ + Get aggregated statistics data for a list of videos based on the specified date filter and mode. + + Args: + video_list (List[:class:`pod.video.models.Video`]): List of video objects. + date_filter (date): The date filter to apply. + mode (str, optional): The mode for data aggregation. Defaults to None. + + Returns: + dict: A dictionary containing the aggregated statistics data. + """ + if not mode: + video_stats = get_days_videos_stats(video_list, date_filter) + elif mode == "year": + video_stats = get_years_videos_stats(video_list, date_filter) + return video_stats + + +def get_views_count( + video_list: List[Video], + date_filter: date = date.today(), + years_only: bool = False, + day_only: bool = False, +) -> dict: + """ + Get the total views count for a list of videos based on the specified date filter and options. + + Args: + video_list (List[:class:`pod.video.models.Video`]): List of video objects. + date_filter (date, optional): The date filter to apply. Defaults to today's date. + years_only (bool, optional): If True, calculate views count for years only. Defaults to False. + day_only (bool, optional): If True, calculate views count for a specific day only. Defaults to False. + + Returns: + dict: A dictionary containing the aggregated views count data. + """ + cache_key = f"views_count_{date_filter}_{years_only}_{day_only}" + all_views = cache.get(cache_key) + + if all_views is None: + all_views = {} + if day_only: + all_views["views_day"] = ( + ViewCount.objects.filter( + video_id__in=video_list, date=date_filter + ).aggregate(Sum("count"))["count__sum"] + or 0 + ) + elif years_only: + all_views["views_year"] = ( + ViewCount.objects.filter( + date__year=date_filter.year, video_id__in=video_list + ).aggregate(Sum("count"))["count__sum"] + or 0 + ) + else: + # view count since video was created + all_views["views_since_created"] = ( + ViewCount.objects.filter(video_id__in=video_list).aggregate(Sum("count"))[ + "count__sum" + ] + or 0 + ) + + cache.set(cache_key, all_views, CACHE_EXPIRATION) + + return all_views + + +def get_playlists_count( + video_list: List[Video], + date_filter: date = date.today(), + years_only: bool = False, + day_only: bool = False, +) -> dict: + """ + Get the total playlists count for a list of videos based on the specified date filter and options. + + Args: + video_list (List[:class:`pod.video.models.Video`]): List of video objects. + date_filter (date, optional): The date filter to apply. Defaults to today's date. + years_only (bool, optional): If True, calculate playlist addition for years only. Defaults to False. + day_only (bool, optional): If True, calculate playlist addition for a specific day only. Defaults to False. + + Returns: + dict: A dictionary containing the aggregated playlists count data. + """ + cache_key = f"playlists_count_{date_filter}_{years_only}_{day_only}" + all_playlists = cache.get(cache_key) + + if all_playlists is None: + all_playlists = {} + if day_only: + all_playlists["playlist_addition_day"] = PlaylistContent.objects.filter( + video_id__in=video_list, date_added__date=date_filter + ).count() + elif years_only: + all_playlists["playlist_addition_year"] = PlaylistContent.objects.filter( + video_id__in=video_list, date_added__year=date_filter.year + ).count() + else: + # playlist addition since video was created + all_playlists[ + "playlist_addition_since_created" + ] = PlaylistContent.objects.filter(video_id__in=video_list).count() + + cache.set(cache_key, all_playlists, CACHE_EXPIRATION) + + return all_playlists + + +def get_favorites_count( + video_list: List[Video], + date_filter: date = date.today(), + years_only: bool = False, + day_only: bool = False, +) -> dict: + """ + Get the total favorites count for a list of videos based on the specified date filter and options. + + Args: + video_list (List[:class:`pod.video.models.Video`]): List of video objects. + date_filter (date, optional): The date filter to apply. Defaults to today's date. + years_only (bool, optional): If True, calculate favorites count for years only. Defaults to False. + day_only (bool, optional): If True, calculate favorites count for a specific day only. Defaults to False. + + Returns: + dict: A dictionary containing the aggregated favorites count data. + """ + cache_key = f"favorites_count_{date_filter}_{years_only}_{day_only}" + all_favorites = cache.get(cache_key) + + if all_favorites is None: + all_favorites = {} + favorites_playlists = Playlist.objects.filter(name=FAVORITE_PLAYLIST_NAME) + if day_only: + all_favorites["favorites_day"] = PlaylistContent.objects.filter( + playlist__in=favorites_playlists, + video_id__in=video_list, + date_added__date=date_filter, + ).count() + elif years_only: + all_favorites["favorites_year"] = PlaylistContent.objects.filter( + playlist__in=favorites_playlists, + video_id__in=video_list, + date_added__year=date_filter.year, + ).count() + else: + all_favorites["favorites_since_created"] = PlaylistContent.objects.filter( + playlist__in=favorites_playlists, video_id__in=video_list + ).count() + + cache.set(cache_key, all_favorites, CACHE_EXPIRATION) + + return all_favorites + + +def get_days_videos_stats( + video_list: List[Video], date_filter: date = date.today() +) -> str: + """ + Get daily aggregated statistics data for a list of videos based on the specified date filter. + + Args: + video_list (List[:class:`pod.video.models.Video`]): List of video objects. + date_filter (date, optional): The date filter to apply. Defaults to today's date. + + Returns: + str: A JSON-encoded string containing the aggregated daily statistics data. + """ + all_video_stats = {"date": str(date_filter), "datas": {}} + + all_video_stats["datas"].update( + get_views_count(video_list, date_filter, day_only=True) + ) + if getattr(settings, "USE_PLAYLIST", True): + all_video_stats["datas"].update( + get_playlists_count(video_list, date_filter, day_only=True) + ) + if getattr(settings, "USE_PLAYLIST", True) and getattr( + settings, "USE_FAVORITES", True + ): + all_video_stats["datas"].update( + get_favorites_count(video_list, date_filter, day_only=True) + ) + + return dumps(all_video_stats) + + +def get_years_videos_stats( + video_list: List[Video], date_filter: date = date.today() +) -> str: + """ + Get yearly aggregated statistics data for a list of videos based on the specified date filter. + + Args: + video_list (List[:class:`pod.video.models.Video`]): List of video objects. + date_filter (date, optional): The date filter to apply. Defaults to today's date. + + Returns: + str: A JSON-encoded string containing the aggregated yearly statistics data. + """ + all_years_videos_stats = {"year": date_filter.year, "datas": {}} + + all_years_videos_stats["datas"].update( + get_views_count(video_list, date_filter, years_only=True) + ) + if getattr(settings, "USE_PLAYLIST", True): + all_years_videos_stats["datas"].update( + get_playlists_count(video_list, date_filter, years_only=True) + ) + if getattr(settings, "USE_PLAYLIST", True) and getattr( + settings, "USE_FAVORITES", True + ): + all_years_videos_stats["datas"].update( + get_favorites_count(video_list, date_filter, years_only=True) + ) + + return dumps(all_years_videos_stats) + + +def get_videos_status_stats(video_list: List[Video]) -> str: + """ + Get statistics for the status of videos in the given list. + + Args: + video_list (List[:class:`pod.video.models.Video`]): List of Video objects. + + Returns: + str: JSON-encoded statistics for different video statuses. + """ + stats = {} + number_videos = len(video_list) + draft_number = Video.objects.filter(id__in=video_list, is_draft=True).count() + restricted_number = Video.objects.filter( + id__in=video_list, is_restricted=True + ).count() + password_number = Video.objects.filter( + id__in=video_list, password__isnull=False + ).count() + public_number = number_videos - draft_number - restricted_number - password_number + + stats["public"] = public_number + stats["draft"] = draft_number + stats["restricted"] = restricted_number + stats["password"] = password_number + return dumps(stats) + + +def get_playlists_status_stats(playlist_list: List[Playlist]) -> str: + """ + Get statistics for the visibility statuses of playlists in the given list. + + Args: + playlist_list (List[:class:`pod.playlist.models.Playlist`]): List of Playlist objects. + + Returns: + str: JSON-encoded statistics for different playlist visibility statuses. + """ + stats = {} + visibility_list = list(playlist_list.values_list("visibility", flat=True)) + stats = Counter(visibility_list) + return dumps(stats) + + +def total_time_videos(request: HttpRequest, video_list: List[Video] = None) -> str: + """ + Get the total duration of videos in the specified list or for the user's available videos. + + Args: + request (HttpRequest): The HTTP request object. + video_list (List[:class:`pod.video.models.Video`], optional): List of Video objects. Defaults to None. + + Returns: + str: The formatted total duration of videos in HH:MM:SS format. + """ + if video_list: + total_duration = video_list.aggregate(Sum("duration"))["duration__sum"] + else: + total_duration = get_available_videos(request).aggregate(Sum("duration"))[ + "duration__sum" + ] + return str(timedelta(seconds=total_duration)) if total_duration else "0" + + +def number_videos(request: HttpRequest, video_list: List[Video] = None) -> int: + """ + Get the number of videos in the specified list or for the user's available videos. + + Args: + request (HttpRequest): The HTTP request object. + video_list (List[:class:`pod.video.models.Video`], optional): List of Video objects. Defaults to None. + + Returns: + int: The number of videos. + """ + if video_list: + number_videos = video_list.count() + else: + number_videos = get_available_videos(request).count() + return number_videos + + +def number_files(user: User) -> int: + """ + Get the number of files in the user's home folder. + + Args: + user (:class:`django.contrib.auth.models.User`): The User object. + + Returns: + int: The number of files. + """ + user_home_folder = get_object_or_404(UserFolder, name="home", owner=user) + return len(user_home_folder.get_all_files()) + + +def number_favorites(user: User) -> int: + """ + Get the number of videos in the user's favorite playlist. + + Args: + user (:class:`django.contrib.auth.models.User`): The User object. + + Returns: + int: The number of videos in the favorite playlist. + """ + favorites = get_favorite_playlist_for_user(user) + return get_number_video_in_playlist(favorites) + + +def number_meetings(user: User) -> int: + """ + Get the number of meetings owned by the user. + + Args: + user (:class:`django.contrib.auth.models.User`): The User object. + + Returns: + int: The number of meetings. + """ + return Meeting.objects.filter(owner=user).count() + + +def number_channels(request: HttpRequest, target: str = None) -> int: + """ + Get the number of channels for the user or in total. + + Args: + request (HttpRequest): The HTTP request object. + target (str, optional): The target for counting channels. Defaults to None. + + Returns: + int: The number of channels. + """ + site = get_current_site(request) + if target == "user": + return request.user.owners_channels.all().filter(site=site).count() + return Channel.objects.all().filter(site=site).distinct().count() + + +def get_channels_visibility_stats(channel_list: List[Channel]) -> str: + """ + Get statistics for the visibility statuses of channels in the given list. + + Args: + channel_list (List[:class:`pod.video.models.Channel`]): List of Channel objects. + + Returns: + str: JSON-encoded statistics for different channel visibility statuses. + """ + stats = {} + number_channels = len(channel_list) + + visible_channels = channel_list.filter(visible=True).count() + private_channels = number_channels - visible_channels + + stats["visible"] = visible_channels + stats["private"] = private_channels + return dumps(stats) + + +def get_most_common_type_discipline(video_list: List[Video]): + """ + Get the most common video type and discipline from the given list of videos. + + Args: + video_list (List[:class:`pod.video.models.Video`]): List of Video objects. + + Returns: + Tuple[Type, Discipline]: The most common video type and discipline. + """ + if len(video_list) > 0: + type_counter = Counter() + discipline_counter = Counter() + + for video in video_list: + if video.type and video.type.slug != "other": + type_counter[video.type] += 1 + if video.discipline.exists(): + for discipline in video.discipline.all(): + discipline_counter[discipline] += 1 + + most_common_type = type_counter.most_common(1)[0][0] if type_counter else None + most_common_discipline = ( + discipline_counter.most_common(1)[0][0] if discipline_counter else None + ) + else: + most_common_type = None + most_common_discipline = None + return most_common_type, most_common_discipline + + +def number_users() -> int: + """ + Get the total number of users. + + Returns: + int: The number of users. + """ + return User.objects.all().distinct().count() + + +def number_themes(channel: Channel = None) -> int: + """ + Get the number of themes for the specified channel or in total. + + Args: + channel (:class:`pod.video.models.Channel`, optional): The Channel object. Defaults to None. + + Returns: + int: The number of themes. + """ + if channel: + return Theme.objects.filter(channel=channel).distinct().count() + else: + return Theme.objects.all().distinct().count() diff --git a/pod/stats/views.py b/pod/stats/views.py new file mode 100644 index 0000000000..4c5fc7248b --- /dev/null +++ b/pod/stats/views.py @@ -0,0 +1,464 @@ +"""Esup-Pod stats views.""" +import json +from datetime import date +from dateutil.parser import parse +from typing import List + +from django.conf import settings +from django.contrib.auth.decorators import user_passes_test +from django.contrib.auth.models import User +from django.contrib.sites.shortcuts import get_current_site +from django.http import HttpRequest, HttpResponseNotFound, JsonResponse +from django.shortcuts import get_object_or_404, render +from django.utils.translation import gettext_lazy as _ +from pod.meeting.models import Meeting + +from pod.playlist.utils import ( + get_all_playlists, + get_favorite_playlist_for_user, + get_playlist, + get_video_list_for_playlist, +) +from pod.stats.utils import ( + get_channels_visibility_stats, + get_most_common_type_discipline, + get_playlists_status_stats, + get_videos_stats, + get_videos_status_stats, +) +from pod.video.context_processors import get_available_videos +from pod.video.forms import VideoPasswordForm +from pod.video.models import Channel, Theme, Video +from pod.video.views import get_video_access + +VIEW_STATS_AUTH = getattr(settings, "VIEW_STATS_AUTH", False) + + +def view_stats_if_authenticated(user: User) -> bool: + """ + Check if the user is authenticated and has permission to view statistics. + + + Args: + user (:class:`django.contrib.auth.models.User`): The user object to check. + + + Returns: + bool: False if the user is not authenticated or VIEW_STATS_AUTH is False, else True. + """ + return user.is_authenticated and VIEW_STATS_AUTH + + +STATS_VIEWS = { + "videos": { + "filter_func": lambda kwargs: Video.objects.filter(slug=kwargs.get("video_slug")) + if kwargs.get("video_slug") + else kwargs["available_videos"], + "title_func": lambda kwargs: _("Video statistics: %s") + % kwargs["video_founded"].title.capitalize() + if kwargs["video_founded"] + else _("Site video statistics"), + }, + "channel": { + "filter_func": lambda kwargs: Video.objects.filter( + channel=kwargs["channel_obj"], theme=kwargs["theme_obj"] + ) + if kwargs.get("theme_obj") + else Video.objects.filter(channel=kwargs["channel_obj"]), + "title_func": lambda kwargs: _("Video statistics for the theme %s") + % kwargs["theme_obj"].title + if kwargs.get("theme_obj") + else _("Video statistics for the channel %s") % kwargs["channel_obj"].title + if kwargs["channel_obj"] + else _("Statistics for channels"), + }, + "user": { + "filter_func": lambda kwargs: Video.objects.filter(owner=kwargs["user"]), + "title_func": lambda kwargs: _("Statistics for user %s") % kwargs["user"], + }, + "general": { + "filter_func": lambda kwargs: kwargs["available_videos"], + "title_func": lambda kwargs: _("Site statistics"), + }, + "playlist": { + "filter_func": lambda kwargs: Video.objects.filter( + playlistcontent__playlist=kwargs["playlist_obj"] + ), + "title_func": lambda kwargs: _("Statistics for the playlist %s") + % kwargs["playlist_obj"].name + if kwargs["playlist_obj"] + else _("Statistics for playlists"), + }, +} + + +def get_videos( + request: HttpRequest, + target: str, + video_slug=None, + channel=None, + theme=None, + playlist=None, +): + """ + Get a list of videos based on the specified target and filters. + + + Args: + request (HttpRequest): The HTTP request object. + target (str): The target of the statistics view. + video_slug (str, optional): The slug of the video. Defaults to None. + channel (str, optional): The slug of the channel. Defaults to None. + theme (str, optional): The slug of the theme. Defaults to None. + playlist (str, optional): The slug of the playlist. Defaults to None. + + + Returns: + Tuple[List[Video], str]: A tuple containing a list of videos and the title for the view. + """ + title = _("Video statistics") + available_videos = get_available_videos() + videos = [] + + if target.lower() in STATS_VIEWS: + config = STATS_VIEWS[target.lower()] + filter_args = { + "video_slug": video_slug, + "channel": channel, + "theme": theme, + "playlist": playlist, + "available_videos": available_videos, + "user": request.user if target.lower() == "user" else None, + "channel_obj": get_object_or_404(Channel, slug=channel) if channel else None, + "theme_obj": get_object_or_404(Theme, slug=theme) if theme else None, + "video_founded": Video.objects.filter(slug=video_slug).first() + if video_slug + else None, + "playlist_obj": get_playlist(playlist) if playlist else None, + } + videos = config["filter_func"](filter_args) + title = config["title_func"](filter_args) + + return videos, title + + +def manage_post_request( + request: HttpRequest, videos: List[Video], video: Video = None +) -> JsonResponse: + """ + Process a POST request to fetch video statistics data. + + + Args: + request (HttpRequest): The HTTP request object. + videos (List[Video]): A list of video objects to fetch statistics for. + video (Video, optional): A specific video object for which to fetch statistics. Defaults to None. + + + Returns: + JsonResponse: A JSON response containing the fetched video statistics data. + """ + date_filter = request.POST.get("periode", date.today()) + if isinstance(date_filter, str): + date_filter = parse(date_filter).date() + if video: # For one video + data = get_videos_stats(videos, date_filter) + else: # For some videos + data = get_videos_stats(videos, date_filter, mode="year") + return JsonResponse(data, safe=False) + + +@user_passes_test(view_stats_if_authenticated) +def video_stats_view(request: HttpRequest, video: str = None): + """ + Display video statistics view based on user's authentication status. + + + Args: + request (HttpRequest): The HTTP request object. + video (str, optional): The video slug. Defaults to None. + + + Returns: + HttpResponse: A response containing the rendered video statistics view. + """ + target = "videos" + videos, title = get_videos(request=request, target=target, video_slug=video) + + if not videos: + return HttpResponseNotFound(_("The following video does not exist: %s") % video) + + if request.method == "GET": + if video and videos: + return manage_access_rights_stats_video(request, videos[0], title) + + status_datas_json = get_videos_status_stats(videos) + status_datas = json.loads(status_datas_json) + status_datas.pop("draft", None) + prefered_type, prefered_discipline = get_most_common_type_discipline(videos) + + return render( + request, + "stats/video-stats-view.html", + { + "title": title, + "videos": videos, + "status_datas": json.dumps(status_datas), + "prefered_type": prefered_type, + "prefered_discipline": prefered_discipline, + }, + ) + if request.method == "POST": + return manage_post_request(request, videos, video) + + +def manage_access_rights_stats_video(request: HttpRequest, video: Video, page_title): + """ + Manage access rights to the video statistics view based on user permissions. + + + Args: + request (HttpRequest): The HTTP request object. + video (Video): The video object for which to manage access rights. + page_title (str): The title of the page. + + + Returns: + HttpResponse: A response containing the rendered video statistics view or an error message. + """ + video_access_ok = get_video_access(request, video, slug_private=None) + is_password_protected = video.password is not None and video.password != "" + has_rights = ( + request.user == video.owner + or request.user.is_superuser + or request.user.has_perm("video.change_viewcount") + or request.user in video.additional_owners.all() + ) + if not has_rights and is_password_protected: + form = VideoPasswordForm() + return render( + request, + "stats/video-stats-view.html", + {"form": form, "title": page_title}, + ) + elif ( + (not has_rights and video_access_ok and not is_password_protected) + or (video_access_ok and not is_password_protected) + or has_rights + ): + return render( + request, + "stats/video-stats-view.html", + { + "title": page_title, + "video": video, + "slug": video.slug, + }, + ) + return HttpResponseNotFound( + _("You do not have access rights to this video: %s" % video.slug) + ) + + +def to_do(): + ... + + +@user_passes_test(view_stats_if_authenticated) +def channel_stats_view(request: HttpRequest, channel: str = None, theme: str = None): + """ + Display channel statistics view based on user's authentication status. + + Args: + request (HttpRequest): The HTTP request object. + channel (str): The channel slug. Defaults to None. + theme (str): The theme slug. Defaults to None. + + Returns: + HttpResponse: A response containing the rendered channel statistics view. + """ + target = "channel" + videos, title = get_videos( + request=request, target=target, channel=channel, theme=theme + ) + + if request.method == "GET": + if channel: + status_datas = get_videos_status_stats(videos) + return render( + request, + "stats/channel-stats-view.html", + { + "title": title, + "channel": channel, + "theme": theme, + "status_datas": status_datas, + "videos": videos, + "date": date.today(), + }, + ) + else: + site = get_current_site(request) + channels = Channel.objects.all().filter(site=site).distinct() + visibility_datas = get_channels_visibility_stats(channels) + return render( + request, + "stats/channel-stats-view.html", + { + "title": title, + "visibility_datas": visibility_datas, + }, + ) + + elif request.method == "POST": + return manage_post_request(request, videos) + + +@user_passes_test(view_stats_if_authenticated) +def user_stats_view(request: HttpRequest): + """ + Display user statistics view based on user's authentication status. + + Args: + request (HttpRequest): The HTTP request object. + + Returns: + HttpResponse: A response containing the rendered user statistics view. + """ + target = "user" + videos, title = get_videos(request=request, target=target) + + if request.method == "GET": + status_datas = get_videos_status_stats(videos) + prefered_type, prefered_discipline = get_most_common_type_discipline( + get_video_list_for_playlist(get_favorite_playlist_for_user(request.user)) + ) + return render( + request, + "stats/user-stats-view.html", + { + "title": title, + "videos": videos, + "status_datas": status_datas, + "prefered_type": prefered_type, + "prefered_discipline": prefered_discipline, + }, + ) + elif request.method == "POST": + return manage_post_request(request, videos) + + +@user_passes_test(view_stats_if_authenticated) +def general_stats_view(request: HttpRequest): + """ + Display general statistics view based on user's authentication status. + + Args: + request (HttpRequest): The HTTP request object. + + Returns: + HttpResponse: A response containing the rendered general statistics view. + """ + target = "general" + videos, title = get_videos(request=request, target=target) + + if request.method == "GET": + status_datas_json = get_videos_status_stats(videos) + status_datas = json.loads(status_datas_json) + status_datas.pop("draft", None) + prefered_type, prefered_discipline = get_most_common_type_discipline(videos) + return render( + request, + "stats/general-stats-view.html", + { + "title": title, + "videos": videos, + "status_datas": json.dumps(status_datas), + "prefered_type": prefered_type, + "prefered_discipline": prefered_discipline, + }, + ) + elif request.method == "POST": + return manage_post_request(request, videos) + + +@user_passes_test(view_stats_if_authenticated) +def playlist_stats_view(request: HttpRequest, playlist: str = None): + """ + Display playlist statistics view based on user's authentication status. + + Args: + request (HttpRequest): The HTTP request object. + playlist (str, optional): The playlist slug. Defaults to None. + + Returns: + HttpResponse: A response containing the rendered playlist statistics view. + """ + target = "playlist" + videos, title = get_videos(request=request, target=target, playlist=playlist) + + if request.method == "GET": + if playlist: + status_datas = get_videos_status_stats(videos) + prefered_type, prefered_discipline = get_most_common_type_discipline(videos) + playlist = get_playlist(playlist) + return render( + request, + "stats/playlist-stats-view.html", + { + "title": title, + "videos": videos, + "status_datas": status_datas, + "prefered_type": prefered_type, + "prefered_discipline": prefered_discipline, + "playlist": playlist, + }, + ) + else: + playlists = get_all_playlists() + status_datas = get_playlists_status_stats(playlists) + return render( + request, + "stats/playlist-stats-view.html", + { + "title": title, + "playlists": playlists, + "status_datas": status_datas, + }, + ) + elif request.method == "POST": + return manage_post_request(request, videos) + +@user_passes_test(view_stats_if_authenticated) +def meeting_stats_view(request: HttpRequest, meeting: str = None): + """ + Display meetings statistics view based on user's authentication status. + + Args: + request (HttpRequest): The HTTP request object. + meeting (str, optional): The meeting slug. Defaults to None. + + Returns: + HttpResponse: A response containing the rendered meeting statistics view. + """ + target = "meeting" + # Récupérer les vidéos de réupload de la meeting ?? + + if meeting: + meeting = get_object_or_404(Meeting, meeting_id=meeting) + return render( + request, + "stats/meeting-stats-view.html", + { + "title": _("Statistics for the meeting %s") % meeting.name, + "meeting": meeting + } + ) + else: + return render( + request, + "stats/meeting-stats-view.html", + { + "title": _("Statistics for meetings"), + } + ) diff --git a/pod/urls.py b/pod/urls.py index c39d60191e..d10d86b059 100644 --- a/pod/urls.py +++ b/pod/urls.py @@ -80,10 +80,6 @@ # cut url(r"^cut/", include("pod.cut.urls")), ] -# PLAYLIST -urlpatterns += [ - path("playlist/", include("pod.playlist.urls", namespace="playlist")), -] # CAS if USE_CAS: @@ -128,10 +124,10 @@ url(r"^" + apps + "/", include("pod.%s.urls" % apps, namespace=apps)), ] -# FAVORITE -if getattr(settings, "USE_FAVORITES", True): +# PLAYLIST +if getattr(settings, "USE_PLAYLIST", True): urlpatterns += [ - path("favorite/", include("pod.favorite.urls", namespace="favorite")), + path("playlist/", include("pod.playlist.urls", namespace="playlist")), ] # IMPORT_VIDEO @@ -142,6 +138,12 @@ ), ] +# STATISTICS +if getattr(settings, "USE_STATS_VIEW", True): + urlpatterns += [ + path("stats/", include("pod.stats.urls", namespace="stats")) + ] + if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) if importlib.util.find_spec("debug_toolbar") is not None: diff --git a/pod/video/context_processors.py b/pod/video/context_processors.py index 6c3240822d..b65223a6fc 100644 --- a/pod/video/context_processors.py +++ b/pod/video/context_processors.py @@ -6,13 +6,12 @@ from pod.video.models import Discipline from pod.video.models import Video -from django.db.models import Count, Sum +from django.db.models import Count from django.db.models import Prefetch from django.db.models import Q from django.db.models import Exists from django.db.models import OuterRef -from datetime import timedelta from django.contrib.sites.shortcuts import get_current_site from pod.main.models import AdditionalChannelTab from pod.video_encode_transcript.models import EncodingVideo @@ -142,20 +141,10 @@ def context_navbar(request): .annotate(video_count=Count("video", distinct=True)) ) - list_videos = get_available_videos(request) - VIDEOS_COUNT = list_videos.count() - VIDEOS_DURATION = ( - str(timedelta(seconds=list_videos.aggregate(Sum("duration"))["duration__sum"])) - if list_videos.aggregate(Sum("duration"))["duration__sum"] - else 0 - ) - return { "ALL_CHANNELS": all_channels, "ADD_CHANNELS_TAB": add_channels_tab, "CHANNELS": channels, "TYPES": types, "DISCIPLINES": disciplines, - "VIDEOS_COUNT": VIDEOS_COUNT, - "VIDEOS_DURATION": VIDEOS_DURATION, } diff --git a/pod/video/static/css/video_stats_view.css b/pod/video/static/css/video_stats_view.css deleted file mode 100644 index f46edc2513..0000000000 --- a/pod/video/static/css/video_stats_view.css +++ /dev/null @@ -1,71 +0,0 @@ -.grid-container{ - padding-top: 4em; - display: flex; - align-items: center; - flex-direction: column; - min-height: calc(100vh - 255px); -} -/*.grid-container h1.title{ - margin-bottom: 1em; - font-size: 24px; - padding: 0 .8em; - color: var(--pod-primary) !important; -} -.ui-jqgrid tr.jqgrow td{ - height: 30px; - white-space: normal; - padding: .5em; -} -.ui-state-default .ui-icon{ - background-image: url("/static/img/ui-icons_6da8d5_256x240.png"); -} -.ui-icon .ui-widget-content .ui-icon{ - background-image: url("/static/img/ui-icons_469bdd_256x240.png"); -} -.ui-state-default .ui-icon { - background-image: url("/static/img/ui-icons_6da8d5_256x240.png"); -} -ui-icon, .ui-widget-content .ui-icon { - background-image: url("/static/img/ui-icons_469bdd_256x240.png"); -}*/ - -/* Override jqgrid default css background-image */ -/*.ui-widget-content, -.ui-state-default, -.ui-widget-content .ui-state-default, -.ui-widget-header .ui-state-default, -.ui-state-hover, -.ui-widget-content .ui-state-hover, -.ui-widget-header .ui-state-hover, -.ui-state-focus, -.ui-widget-content .ui-state-focus, -.ui-widget-header .ui-state-focus{ - background-image:none; -}*/ - - -/*.stat-form-group{ - display: flex; - justify-content: flex-start; - max-width: 755px; - align-items: center; -} -.stat-form-group .col-form-label{ - font-weight: 700; - color: var(--secondary); -} -.stat-form-group .col-form-label, -.stat-form-group .col-date{ - width: auto; - flex: none; - max-width: unset; -} -@media only screen and (max-width: 512px){ - .stat-form-group{ - flex-direction: column; - width: 100%; - } - .stat-form-group .col-date{ - width: calc(100% - 2em); - } -}*/ 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 1ee5253b16..461194f418 100644 --- a/pod/video/static/js/filter_aside_video_list_refresh.js +++ b/pod/video/static/js/filter_aside_video_list_refresh.js @@ -1,11 +1,6 @@ var infinite; var checkedInputs = []; var listUser; -var sortDirectionChars = ["8600", "8599"]; -var sortDirectionTitle = [ - gettext("Descending sort"), - gettext("Ascending sort"), -]; let loader = document.querySelector(".lds-ring"); let infinite_loading = document.querySelector(".infinite-loading"); @@ -107,6 +102,15 @@ function refreshVideosSearch() { }); } +// Add trigger event to manage sort direction. +document + .getElementById("sort_direction_label") + .addEventListener("click", function (e) { + e.preventDefault(); + toggleSortDirection(); + refreshVideosSearch(); +}); + // Return url with filter and sort parameters function getUrlForRefresh() { let newUrl = window.location.pathname; @@ -208,38 +212,6 @@ document.getElementById("resetFilters").addEventListener("click", function () { refreshVideosSearch(); }); -// Add trigger event to manage sort direction -document - .getElementById("sort_direction_label") - .addEventListener("click", function (e) { - e.preventDefault(); - toggleSortDirection(); - refreshVideosSearch(); - }); - -// Update arrow char of ascending or descending sort order -function updateSortDirectionChar(sortDirectionAsc) { - document.getElementById("sort_direction_label").innerHTML = - "&#" + sortDirectionChars[+sortDirectionAsc].toString(); -} - -// Update title for input sort direction -function updateSortDirectionTitle(sortDirectionAsc) { - let newTitle = sortDirectionTitle[+sortDirectionAsc]; - document - .getElementById("sort_direction_label") - .setAttribute("title", newTitle); -} - -// Toggle direction of sort -function toggleSortDirection() { - document.getElementById("sort_direction").checked = - !document.getElementById("sort_direction").checked; - const direction = document.getElementById("sort_direction").checked; - updateSortDirectionChar(direction); - updateSortDirectionTitle(direction); -} - // Enable / Disable toggle inputs to prevent user actions during loading function disabledInputs(value) { document @@ -260,7 +232,7 @@ document .querySelectorAll("input[type=checkbox]:checked[class=form-check-input]") .forEach((e) => { checkedInputs.push(e); - }); +}); // First launch of the infinite scroll infinite = new InfiniteLoader( diff --git a/pod/video/static/js/video_stats_view.js b/pod/video/static/js/video_stats_view.js deleted file mode 100644 index 02a8e29ebf..0000000000 --- a/pod/video/static/js/video_stats_view.js +++ /dev/null @@ -1,102 +0,0 @@ -function linkedCell(cellValue, options, rowObject) { - return ( - "" + - cellValue + - "" - ); -} -$(() => { - let data_url = window.location.href; - $("#grid").jqGrid({ - url: data_url, - datatype: "json", - mtype: "POST", - styleUI: "Bootstrap5", - iconSet: "Bootstrap5", - colNames: [ - gettext("Title"), - gettext("View during the day"), - gettext("View during the month"), - gettext("View during the year"), - gettext("Total view from creation"), - gettext("Favorite additions during the day"), - gettext("Favorite additions during the month"), - gettext("Favorite additions during the year"), - gettext("Total favorite additions from creation"), - gettext("Slug"), - ], - colModel: [ - { - name: "title", - align: "center", - sortable: true, - sorttype: "text", - formatter: linkedCell, - }, - { name: "day", align: "center", sortable: true, sorttype: "int" }, - { name: "month", align: "center", sortable: true, sorttype: "int" }, - { name: "year", align: "center", sortable: true, sorttype: "int" }, - { - name: "since_created", - align: "center", - sortable: true, - sorttype: "int", - }, - { name: "fav_day", align: "center", sortable: true, sorttype: "int" }, - { name: "fav_month", align: "center", sortable: true, sorttype: "int" }, - { name: "fav_year", align: "center", sortable: true, sorttype: "int" }, - { - name: "fav_since_created", - align: "center", - sortable: true, - sorttype: "int", - }, - { - name: "slug", - align: "center", - sortable: true, - sorttype: "text", - hidden: true, - }, - ], - loadonce: true, - rowNum: 10, - rowList: [10, 15, 20, 25, 30, 50, 100], - gridview: true, - autoencode: true, - pager: "#pager", - sortorder: "asc", - beforeProcessing: function (data) { - // Set min date - let min_date = data.filter((obj) => { - return obj.min_date != undefined; - }); - // remove date_min in data - data.pop(); - document.querySelector("#jsperiode").min = min_date[0].min_date; - }, - postData: { - csrfmiddlewaretoken: $("[name=csrfmiddlewaretoken]").val(), - }, - }); - let today = new Date().toISOString().split("T")[0]; - $("#jsperiode").val(today); // set date input value to today - document.querySelector("#jsperiode").max = today; - - $("#jsperiode").on("change paste keyup", function (e) { - if ($(this).val() != undefined && $(this).val().trim() !== "") { - try { - let data = { periode: $(this).val() }; - $("#grid") - .jqGrid("setGridParam", { datatype: "json", postData: data }) - .trigger("reloadGrid"); - } catch (e) { - console.log(e); - } - } - }); -}); diff --git a/pod/video/templates/channel/channel.html b/pod/video/templates/channel/channel.html index c873d69776..7141bb2b00 100644 --- a/pod/video/templates/channel/channel.html +++ b/pod/video/templates/channel/channel.html @@ -56,11 +56,11 @@

{% if parent_title %} {{parent_title}} {% else %} {{title}} {% endif %} - {% if USE_STATS_VIEW %} + {% if USE_STATS_VIEW %}{% comment "TODO STATS" %}{% endcomment %} {% if theme %} - {% trans 'Statistics views' %} + {% trans 'Theme statistics' %} {% else %} -  {% trans 'Statistics views' %} +  {% trans 'Channel statistics' %} {% endif %} {% endif %} {% if theme %} @@ -147,13 +147,13 @@

{% if theme %} {% if USE_STATS_VIEW %} - {% trans 'Statistics views' %} + {% trans 'Theme statistics' %} {% endif %}  Video  Audio {% else %} {% if USE_STATS_VIEW %} - {% trans 'Statistics views' %} + {% trans 'Channel statistics' %} {% endif %}  Video  Audio diff --git a/pod/video/templates/videos/card.html b/pod/video/templates/videos/card.html index 3a420d2e5a..9bf2b2066c 100644 --- a/pod/video/templates/videos/card.html +++ b/pod/video/templates/videos/card.html @@ -1,6 +1,12 @@ {% load i18n %} +{% load playlist_buttons %} + {% spaceless %} -
+{% if playlist %} + {% load playlist_buttons %} + {% can_see_playlist_video video as can_see_video %} +{% endif %} +
@@ -34,17 +40,25 @@
@@ -57,7 +71,17 @@ {% endif %} - {% if channel %} + {% if playlist %} + {% if can_see_video %} + 43 %}title="{{video.title|capfirst}}"{% endif %}> + {{video.title|capfirst|truncatechars:43}} + + {% else %} + 43 %}title="{{video.title|capfirst}}"{% endif %}> + {{video.title|capfirst|truncatechars:43}} + + {% endif %} + {% elif channel %} {% if theme %} 43 %}title="{{video.title|capfirst}}"{% endif %}> {{video.title|capfirst|truncatechars:43}} diff --git a/pod/video/templates/videos/link_video.html b/pod/video/templates/videos/link_video.html index 3296c97d93..726b205cb4 100644 --- a/pod/video/templates/videos/link_video.html +++ b/pod/video/templates/videos/link_video.html @@ -1,16 +1,31 @@ {% load i18n %} -{% load favorite_info %} +{% load favorites_playlist %} +{% load playlist_buttons %} + {% spaceless %} -{% is_favorite video as is_fav %} -{% if USE_FAVORITES and video.is_draft is False and not hide_favorite_link is True %} -
- {% csrf_token %} - - -
+{% if playlist %} + {% user_can_edit_or_remove playlist as can_edit_or_remove %} + {% if not in_favorites_playlist and can_edit_or_remove%} +
+ + + {% endif %} +{% endif %} + +{% is_favorite user video as is_favorite %} +{% get_favorite_playlist user as fav_playlist %} +{% if USE_PLAYLIST and USE_FAVORITES and video.is_draft is False and not hide_favorite_link is True %} + {% if is_favorite %} + + + + {% else %} + + + + {% endif %} + {% endif %} {% if video.owner == request.user or request.user.is_superuser or request.user in video.additional_owners.all or perms.video.change_video %} diff --git a/pod/video/templates/videos/my_videos.html b/pod/video/templates/videos/my_videos.html index 8f4af9db8c..c0346900b3 100644 --- a/pod/video/templates/videos/my_videos.html +++ b/pod/video/templates/videos/my_videos.html @@ -54,7 +54,8 @@

{% blocktrans count counter=count_ {% endif %} - + + {% if use_category %} - - + +{% if USE_PLAYLIST and USE_FAVORITES %} + + +{% endif %} @@ -82,8 +85,7 @@ {% endif %} {% if request.user.playlist_set.all %} - - + {% endif %} {% if video.is_360 %} diff --git a/pod/video/templates/videos/video-info.html b/pod/video/templates/videos/video-info.html index a943c1e107..6a6130bae0 100644 --- a/pod/video/templates/videos/video-info.html +++ b/pod/video/templates/videos/video-info.html @@ -3,7 +3,9 @@ {% load tagging_tags %} {% load thumbnail %} {% load video_tags %} -{% load favorite_info %} +{% load playlist_stats %} +{% load favorites_playlist %} +
@@ -12,33 +14,52 @@
- {% if USE_FAVORITES %} + {% if USE_PLAYLIST %} +
+ {% trans 'Addition in a playlist' %} + {% if USE_STATS_VIEW and not video.encoding_in_progress %} + {% get_count_video_added_in_playlist video %} + {% else %} + {% get_count_video_added_in_playlist video %} + {% endif %} +
+ {% endif %} + {% if USE_PLAYLIST and USE_FAVORITES %}
{% trans 'Number of favorites' %} - {% if USE_STATS_VIEW and not video.encoding_in_progress %} - {% number_favorites video %} + {% if USE_STATS_VIEW and not video.encoding_in_progress %} + {% get_total_favorites_video video %} {% else %} - {% number_favorites video %} + {% get_total_favorites_video video %} {% endif %}
{% endif %}
- {% if user.is_authenticated and not video.is_draft %} - {% is_favorite video as is_fav %} - {% if USE_FAVORITES %} -
- {% csrf_token %} - - -
+ {% if USE_PLAYLIST and user.is_authenticated and not video.is_draft %} + + {% include "playlist/playlist-list-modal.html" %} + + {% is_favorite user video as is_favorite %} + {% get_favorite_playlist user as fav_playlist %} + {% if USE_PLAYLIST and USE_FAVORITES and video.is_draft is False and not hide_favorite_link is True %} + {% if is_favorite %} + + + + {% else %} + + + + {% endif %} + {% endif %} {% endif %} {% if video.is_draft == False or video.owner == request.user or request.user in video.additional_owners.all %} @@ -268,7 +289,7 @@

-{% if video.is_draft == False or video.owner == request.user or request.user in video.additional_owners.all%} +{% if video.is_draft == False or video.owner == request.user or request.user in video.additional_owners.all%}