From 3ca9e98c5d61f70faf350d22ab8c916a82964e4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9line=20Perv=C3=A8s?= Date: Wed, 10 Feb 2021 10:14:10 +0100 Subject: [PATCH 001/261] moodle pod plugin webservices needs --- pod/video/models.py | 67 ++++++++++++++++++++++++++++++++++++++++- pod/video/rest_views.py | 39 +++++++++++++++++++----- 2 files changed, 98 insertions(+), 8 deletions(-) diff --git a/pod/video/models.py b/pod/video/models.py index d113a90f0e..19697911c2 100755 --- a/pod/video/models.py +++ b/pod/video/models.py @@ -36,6 +36,7 @@ from pod.main.lang_settings import ALL_LANG_CHOICES, PREF_LANG_CHOICES from django.db.models import Count, Case, When, Value, BooleanField, Q from django.db.models.functions import Concat +from os.path import splitext if getattr(settings, 'USE_PODFILE', False): from pod.podfile.models import CustomImageModel @@ -807,14 +808,78 @@ def get_video_mp4(self): return EncodingVideo.objects.filter( video=self, encoding_format="video/mp4") + def get_video_json(self,extensions): + list_src = [] + dict_src = {} + extension_list = extensions.split(',') if extensions else [] + list_video = EncodingVideo.objects.filter( + video=self) + for video in list_video: + file_extension = splitext(video.source_file.url)[-1] + if extensions is None or file_extension[1:] in extension_list : + video_object = { + 'id': video.id, + 'type': video.encoding_format, + 'src': video.source_file.url, + 'height': video.height, + 'extension': file_extension, + 'label': video.name} + dict_entry = dict_src.get(file_extension[1:], None) + if dict_entry is None : + dict_src[file_extension[1:]] = [video_object] + else: + dict_entry.append(video_object) + + list_src.append( + { + 'id' : video.id, + 'type': video.encoding_format, + 'src': video.source_file.url, + 'height': video.height, + 'extension': file_extension, + 'label': video.name}) + sorted_dict_src = {x: sorted(dict_src[x], key= lambda i:i['height']) for x in dict_src.keys()} + return sorted_dict_src + + def get_audio_json(self, extensions): + list_src = [] + dict_src = {} + extension_list = extensions.split(',') if extensions else [] + list_audio = EncodingAudio.objects.filter( + name="audio", video=self) + for audio in list_audio: + file_extension = splitext(audio.source_file.url)[-1] + audio_object = { + 'id': audio.id, + 'type': audio.encoding_format, + 'src': audio.source_file.url, + 'height': None, + 'extension': file_extension, + 'label': audio.name} + if extensions is None or file_extension[1:] in extension_list: + dict_entry = dict_src.get(file_extension[1:], None) + if dict_entry is None : + dict_src[file_extension[1:]] = [audio_object] + else: + dict_entry.append(audio_object) + + list_src.append( + audio_object) + return dict_src + + def get_audio_and_video_json(self, extensions): + return {**self.get_video_json(extensions), **self.get_audio_json(extensions)} def get_video_mp4_json(self): list_src = [] list_video = sorted(self.get_video_mp4(), key=lambda m: m.height) for video in list_video: list_src.append( - {'type': video.encoding_format, + { + 'id' : video.id, + 'type': video.encoding_format, 'src': video.source_file.url, 'height': video.height, + 'extension': splitext(video.source_file.url)[-1], 'label': video.name}) return list_src diff --git a/pod/video/rest_views.py b/pod/video/rest_views.py index 11ea3c6701..4cc9026c32 100644 --- a/pod/video/rest_views.py +++ b/pod/video/rest_views.py @@ -17,6 +17,7 @@ from .views import VIDEOS from .remote_encode import start_store_remote_encoding_video from .transcript import start_transcript +from os.path import splitext import json @@ -78,6 +79,7 @@ class VideoUserSerializer(serializers.ModelSerializer): def to_representation(self, instance): data = super(VideoUserSerializer, self).to_representation(instance) + request = self.context['request'] video_data = json.loads(instance.get_json_to_index()) video_data.update({"encoded": instance.encoded}) video_data.update( @@ -86,11 +88,10 @@ def to_representation(self, instance): {"get_encoding_step": instance.get_encoding_step}) video_data.update( {"get_thumbnail_admin": instance.get_thumbnail_admin}) - video_data.update({"mp4_file": instance.get_video_mp4_json()}) - video_data.update({"mp3_file": instance.get_video_mp3( - ).source_file.url if instance.get_video_mp3() else ""}) - video_data.update({"m4a_file": instance.get_video_m4a( - ).source_file.url if instance.get_video_m4a() else ""}) + video_data.update({'video_files': + instance.get_audio_and_video_json(request.GET.get('extensions', default=None)) + if instance.get_audio_and_video_json(request.GET.get('extensions', default=None)) + else ""}) data["video_data"] = video_data return data @@ -175,8 +176,6 @@ class VideoViewSet(viewsets.ModelViewSet): @action(detail=False, methods=['get']) def user_videos(self, request): - # user_videos = Video.objects.filter( - # owner__username=request.GET.get('username')) user_videos = self.filter_queryset(self.get_queryset()).filter( owner__username=request.GET.get('username')) if request.GET.get('encoded') and request.GET.get('encoded') == "true": @@ -201,11 +200,37 @@ class VideoRenditionViewSet(viewsets.ModelViewSet): class EncodingVideoViewSet(viewsets.ModelViewSet): queryset = EncodingVideo.objects.all() serializer_class = EncodingVideoSerializer + filter_fields = ('video',) + + @action(detail=False, methods=['get']) + def video_encodedfiles(self, request): + if request.GET.get('extension') : + encoded_videos = self.filter_queryset(self.get_queryset()).filter( + video__id=request.GET.get('video'), source_file__iendswith = request.GET.get('extension')) + else : + encoded_videos = self.filter_queryset(self.get_queryset()).filter( + video__id=request.GET.get('video')) + encoded_videos = sorted(encoded_videos, key = lambda x : x.height) + serializer = EncodingVideoSerializer( + encoded_videos, many=True, context={'request': request}) + return Response(serializer.data) class EncodingAudioViewSet(viewsets.ModelViewSet): queryset = EncodingAudio.objects.all() serializer_class = EncodingAudioSerializer + filter_fields = ('video',) + + @action(detail=False, methods=['get']) + def audio_encodedfiles(self, request): + if request.GET.get('extension') : + encoded_audios= self.filter_queryset(self.get_queryset()).filter( + video__id=request.GET.get('video'), source_file__iendswith = request.GET.get('extension')) + encoded_audios = self.filter_queryset(self.get_queryset()).filter( + video__id=request.GET.get('video')) + serializer = EncodingAudioSerializer( + encoded_audios, many=True, context={'request': request}) + return Response(serializer.data) class PlaylistVideoViewSet(viewsets.ModelViewSet): From b3b0745148b1f9790d3f16f1e52e4fde5e7f47d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9line=20Perv=C3=A8s?= Date: Wed, 10 Feb 2021 14:02:44 +0100 Subject: [PATCH 002/261] PEP formatting corrections --- pod/video/models.py | 79 ++++++++++++++++++++++++----------------- pod/video/rest_views.py | 45 ++++++++++++++--------- 2 files changed, 74 insertions(+), 50 deletions(-) diff --git a/pod/video/models.py b/pod/video/models.py index 19697911c2..70db1fb428 100755 --- a/pod/video/models.py +++ b/pod/video/models.py @@ -40,6 +40,7 @@ if getattr(settings, 'USE_PODFILE', False): from pod.podfile.models import CustomImageModel + FILEPICKER = True else: FILEPICKER = False @@ -68,8 +69,10 @@ ('1', _("Other")) )) -LANG_CHOICES_DICT = {key: value for key, - value in LANG_CHOICES[0][1] + LANG_CHOICES[1][1]} +LANG_CHOICES_DICT = { + key: value for key, + value in LANG_CHOICES[0][1] + LANG_CHOICES[1][1] +} CURSUS_CODES_DICT = {key: value for key, value in CURSUS_CODES} DEFAULT_TYPE_ID = getattr( @@ -129,7 +132,7 @@ THIRD_PARTY_APPS_CHOICES = THIRD_PARTY_APPS.copy() THIRD_PARTY_APPS_CHOICES.remove("live") if ( - "live" in THIRD_PARTY_APPS_CHOICES) else THIRD_PARTY_APPS_CHOICES + "live" in THIRD_PARTY_APPS_CHOICES) else THIRD_PARTY_APPS_CHOICES THIRD_PARTY_APPS_CHOICES.insert(0, 'Original') VERSION_CHOICES = [ @@ -167,6 +170,7 @@ DEFAULT_YEAR_DATE_DELETE = getattr(settings, 'DEFAULT_YEAR_DATE_DELETE', 2) + # FUNCTIONS @@ -635,6 +639,7 @@ def establishment(self): @property def viewcount(self): return self.get_viewcount() + viewcount.fget.short_description = _('Sum of view') @property @@ -644,6 +649,7 @@ def get_encoding_step(self): except ObjectDoesNotExist: return "" return "%s : %s" % (es.num_step, es.desc_step) + get_encoding_step.fget.short_description = _('Encoding step') def get_thumbnail_url(self): @@ -682,6 +688,7 @@ def get_thumbnail_admin(self): self.title.replace("{", "").replace("}", "") ) ) + get_thumbnail_admin.fget.short_description = _('Thumbnails') def get_thumbnail_card(self): @@ -704,14 +711,15 @@ def get_thumbnail_card(self): @property def duration_in_time(self): return time.strftime('%H:%M:%S', time.gmtime(self.duration)) + duration_in_time.fget.short_description = _('Duration') @property def encoded(self): return ( - self.get_playlist_master() is not None or - self.get_video_mp4() is not None or - self.get_video_m4a() is not None) + self.get_playlist_master() is not None or + self.get_video_mp4() is not None or + self.get_video_m4a() is not None) encoded.fget.short_description = _('Is the video encoded ?') @@ -750,7 +758,7 @@ def get_default_version_link(self, slug_private): for version in self.get_other_version(): if version["link"] == VERSION_CHOICES_DICT[self.get_version]: if slug_private: - return version["url"]+slug_private+"/" + return version["url"] + slug_private + "/" else: return version["url"] @@ -808,7 +816,7 @@ def get_video_mp4(self): return EncodingVideo.objects.filter( video=self, encoding_format="video/mp4") - def get_video_json(self,extensions): + def get_video_json(self, extensions): list_src = [] dict_src = {} extension_list = extensions.split(',') if extensions else [] @@ -816,7 +824,7 @@ def get_video_json(self,extensions): video=self) for video in list_video: file_extension = splitext(video.source_file.url)[-1] - if extensions is None or file_extension[1:] in extension_list : + if extensions is None or file_extension[1:] in extension_list: video_object = { 'id': video.id, 'type': video.encoding_format, @@ -825,20 +833,24 @@ def get_video_json(self,extensions): 'extension': file_extension, 'label': video.name} dict_entry = dict_src.get(file_extension[1:], None) - if dict_entry is None : + if dict_entry is None: dict_src[file_extension[1:]] = [video_object] else: dict_entry.append(video_object) list_src.append( { - 'id' : video.id, + 'id': video.id, 'type': video.encoding_format, 'src': video.source_file.url, 'height': video.height, 'extension': file_extension, 'label': video.name}) - sorted_dict_src = {x: sorted(dict_src[x], key= lambda i:i['height']) for x in dict_src.keys()} + sorted_dict_src = { + x: sorted( + dict_src[x], + key=lambda i: i['height'] + ) for x in dict_src.keys()} return sorted_dict_src def get_audio_json(self, extensions): @@ -858,7 +870,7 @@ def get_audio_json(self, extensions): 'label': audio.name} if extensions is None or file_extension[1:] in extension_list: dict_entry = dict_src.get(file_extension[1:], None) - if dict_entry is None : + if dict_entry is None: dict_src[file_extension[1:]] = [audio_object] else: dict_entry.append(audio_object) @@ -868,19 +880,21 @@ def get_audio_json(self, extensions): return dict_src def get_audio_and_video_json(self, extensions): - return {**self.get_video_json(extensions), **self.get_audio_json(extensions)} + return {**self.get_video_json(extensions), + **self.get_audio_json(extensions)} + def get_video_mp4_json(self): list_src = [] list_video = sorted(self.get_video_mp4(), key=lambda m: m.height) for video in list_video: list_src.append( { - 'id' : video.id, - 'type': video.encoding_format, - 'src': video.source_file.url, - 'height': video.height, - 'extension': splitext(video.source_file.url)[-1], - 'label': video.name}) + 'id': video.id, + 'type': video.encoding_format, + 'src': video.source_file.url, + 'height': video.height, + 'extension': splitext(video.source_file.url)[-1], + 'label': video.name}) return list_src def get_json_to_index(self): @@ -903,7 +917,7 @@ def get_json_to_index(self): "tags": list([ { 'name': name[0], - 'slug':slugify(name) + 'slug': slugify(name) } for name in Tag.objects.get_for_object( self).values_list('name')]), "type": {"title": self.type.title, "slug": self.type.slug}, @@ -996,7 +1010,6 @@ def default_site(sender, instance, created, **kwargs): @receiver(pre_delete, sender=Video, dispatch_uid='pre_delete-video_files_removal') def video_files_removal(sender, instance, using, **kwargs): - remove_video_file(instance) previous_encoding_video = EncodingVideo.objects.filter( @@ -1165,7 +1178,7 @@ class EncodingVideo(models.Model): choices=ENCODING_CHOICES, default="360p", help_text=_("Please use the only format in encoding choices:") - + " %s" % ' '.join(str(key) for key, value in ENCODING_CHOICES) + + " %s" % ' '.join(str(key) for key, value in ENCODING_CHOICES) ) video = models.ForeignKey(Video, verbose_name=_('Video')) rendition = models.ForeignKey( @@ -1176,7 +1189,7 @@ class EncodingVideo(models.Model): choices=FORMAT_CHOICES, default="video/mp4", help_text=_("Please use the only format in format choices:") - + " %s" % ' '.join(str(key) for key, value in FORMAT_CHOICES)) + + " %s" % ' '.join(str(key) for key, value in FORMAT_CHOICES)) source_file = models.FileField( _('encoding source file'), upload_to=get_storage_path_video, @@ -1205,11 +1218,11 @@ class Meta: def __str__(self): return ( - "EncodingVideo num: %s with resolution %s for video %s in %s" - % ('%04d' % self.id, - self.name, - self.video.id, - self.encoding_format)) + "EncodingVideo num: %s with resolution %s for video %s in %s" + % ('%04d' % self.id, + self.name, + self.video.id, + self.encoding_format)) @property def owner(self): @@ -1234,13 +1247,13 @@ class EncodingAudio(models.Model): name = models.CharField( _('Name'), max_length=10, choices=ENCODING_CHOICES, default="audio", help_text=_("Please use the only format in encoding choices:") - + " %s" % ' '.join(str(key) for key, value in ENCODING_CHOICES)) + + " %s" % ' '.join(str(key) for key, value in ENCODING_CHOICES)) video = models.ForeignKey(Video, verbose_name=_('Video')) encoding_format = models.CharField( _('Format'), max_length=22, choices=FORMAT_CHOICES, default="audio/mp3", help_text=_("Please use the only format in format choices:") - + " %s" % ' '.join(str(key) for key, value in FORMAT_CHOICES)) + + " %s" % ' '.join(str(key) for key, value in FORMAT_CHOICES)) source_file = models.FileField( _('encoding source file'), upload_to=get_storage_path_video, @@ -1288,13 +1301,13 @@ class PlaylistVideo(models.Model): name = models.CharField( _('Name'), max_length=10, choices=ENCODING_CHOICES, default="360p", help_text=_("Please use the only format in encoding choices:") - + " %s" % ' '.join(str(key) for key, value in ENCODING_CHOICES)) + + " %s" % ' '.join(str(key) for key, value in ENCODING_CHOICES)) video = select2_fields.ForeignKey(Video, verbose_name=_('Video')) encoding_format = models.CharField( _('Format'), max_length=22, choices=FORMAT_CHOICES, default="application/x-mpegURL", help_text=_("Please use the only format in format choices:") - + " %s" % ' '.join(str(key) for key, value in FORMAT_CHOICES)) + + " %s" % ' '.join(str(key) for key, value in FORMAT_CHOICES)) source_file = models.FileField( _('encoding source file'), upload_to=get_storage_path_video, diff --git a/pod/video/rest_views.py b/pod/video/rest_views.py index 4cc9026c32..7a00b6b050 100644 --- a/pod/video/rest_views.py +++ b/pod/video/rest_views.py @@ -17,7 +17,6 @@ from .views import VIDEOS from .remote_encode import start_store_remote_encoding_video from .transcript import start_transcript -from os.path import splitext import json @@ -88,10 +87,16 @@ def to_representation(self, instance): {"get_encoding_step": instance.get_encoding_step}) video_data.update( {"get_thumbnail_admin": instance.get_thumbnail_admin}) - video_data.update({'video_files': - instance.get_audio_and_video_json(request.GET.get('extensions', default=None)) - if instance.get_audio_and_video_json(request.GET.get('extensions', default=None)) - else ""}) + video_data.update({ + 'video_files': + instance.get_audio_and_video_json( + request.GET.get('extensions', default=None) + ) + if instance.get_audio_and_video_json( + request.GET.get('extensions', default=None) + ) + else "" + }) data["video_data"] = video_data return data @@ -186,7 +191,6 @@ def user_videos(self, request): serializer = VideoUserSerializer( page, many=True, context={'request': request}) return self.get_paginated_response(serializer.data) - serializer = VideoUserSerializer( user_videos, many=True, context={'request': request}) return Response(serializer.data) @@ -204,13 +208,16 @@ class EncodingVideoViewSet(viewsets.ModelViewSet): @action(detail=False, methods=['get']) def video_encodedfiles(self, request): - if request.GET.get('extension') : - encoded_videos = self.filter_queryset(self.get_queryset()).filter( - video__id=request.GET.get('video'), source_file__iendswith = request.GET.get('extension')) - else : + if request.GET.get('extension'): + encoded_videos = self.filter_queryset( + self.get_queryset()).filter( + video__id=request.GET.get('video'), + source_file__iendswith=request.GET.get('extension') + ) + else: encoded_videos = self.filter_queryset(self.get_queryset()).filter( video__id=request.GET.get('video')) - encoded_videos = sorted(encoded_videos, key = lambda x : x.height) + encoded_videos = sorted(encoded_videos, key=lambda x: x.height) serializer = EncodingVideoSerializer( encoded_videos, many=True, context={'request': request}) return Response(serializer.data) @@ -222,12 +229,16 @@ class EncodingAudioViewSet(viewsets.ModelViewSet): filter_fields = ('video',) @action(detail=False, methods=['get']) - def audio_encodedfiles(self, request): - if request.GET.get('extension') : - encoded_audios= self.filter_queryset(self.get_queryset()).filter( - video__id=request.GET.get('video'), source_file__iendswith = request.GET.get('extension')) - encoded_audios = self.filter_queryset(self.get_queryset()).filter( - video__id=request.GET.get('video')) + def audio_encodedescription_nldfiles(self, request): + if request.GET.get('extension'): + encoded_audios = self.filter_queryset( + self.get_queryset()).filter( + video__id=request.GET.get('video'), + source_file__iendswith=request.GET.get('extension') + ) + else: + encoded_audios = self.filter_queryset(self.get_queryset()).filter( + video__id=request.GET.get('video')) serializer = EncodingAudioSerializer( encoded_audios, many=True, context={'request': request}) return Response(serializer.data) From c132b88b8123b25210210dbf3dc6590996eed975 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9line=20Perv=C3=A8s?= Date: Wed, 10 Feb 2021 14:13:01 +0100 Subject: [PATCH 003/261] PEP formatting corrections --- pod/video/models.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pod/video/models.py b/pod/video/models.py index 70db1fb428..6ccc483bc0 100755 --- a/pod/video/models.py +++ b/pod/video/models.py @@ -1178,7 +1178,7 @@ class EncodingVideo(models.Model): choices=ENCODING_CHOICES, default="360p", help_text=_("Please use the only format in encoding choices:") - + " %s" % ' '.join(str(key) for key, value in ENCODING_CHOICES) + + " %s" % ' '.join(str(key) for key, value in ENCODING_CHOICES) ) video = models.ForeignKey(Video, verbose_name=_('Video')) rendition = models.ForeignKey( @@ -1189,7 +1189,7 @@ class EncodingVideo(models.Model): choices=FORMAT_CHOICES, default="video/mp4", help_text=_("Please use the only format in format choices:") - + " %s" % ' '.join(str(key) for key, value in FORMAT_CHOICES)) + + " %s" % ' '.join(str(key) for key, value in FORMAT_CHOICES)) source_file = models.FileField( _('encoding source file'), upload_to=get_storage_path_video, @@ -1247,13 +1247,13 @@ class EncodingAudio(models.Model): name = models.CharField( _('Name'), max_length=10, choices=ENCODING_CHOICES, default="audio", help_text=_("Please use the only format in encoding choices:") - + " %s" % ' '.join(str(key) for key, value in ENCODING_CHOICES)) + + " %s" % ' '.join(str(key) for key, value in ENCODING_CHOICES)) video = models.ForeignKey(Video, verbose_name=_('Video')) encoding_format = models.CharField( _('Format'), max_length=22, choices=FORMAT_CHOICES, default="audio/mp3", help_text=_("Please use the only format in format choices:") - + " %s" % ' '.join(str(key) for key, value in FORMAT_CHOICES)) + + " %s" % ' '.join(str(key) for key, value in FORMAT_CHOICES)) source_file = models.FileField( _('encoding source file'), upload_to=get_storage_path_video, @@ -1301,13 +1301,13 @@ class PlaylistVideo(models.Model): name = models.CharField( _('Name'), max_length=10, choices=ENCODING_CHOICES, default="360p", help_text=_("Please use the only format in encoding choices:") - + " %s" % ' '.join(str(key) for key, value in ENCODING_CHOICES)) + + " %s" % ' '.join(str(key) for key, value in ENCODING_CHOICES)) video = select2_fields.ForeignKey(Video, verbose_name=_('Video')) encoding_format = models.CharField( _('Format'), max_length=22, choices=FORMAT_CHOICES, default="application/x-mpegURL", help_text=_("Please use the only format in format choices:") - + " %s" % ' '.join(str(key) for key, value in FORMAT_CHOICES)) + + " %s" % ' '.join(str(key) for key, value in FORMAT_CHOICES)) source_file = models.FileField( _('encoding source file'), upload_to=get_storage_path_video, From 784a5fb46880a4911d35421889861b8b713edff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9line=20Perv=C3=A8s?= Date: Thu, 11 Feb 2021 17:02:58 +0100 Subject: [PATCH 004/261] work on code review --- pod/video/models.py | 80 +++++++++++------------------------------ pod/video/rest_views.py | 35 +++++++++--------- 2 files changed, 37 insertions(+), 78 deletions(-) diff --git a/pod/video/models.py b/pod/video/models.py index 6ccc483bc0..aa187ab96c 100755 --- a/pod/video/models.py +++ b/pod/video/models.py @@ -817,35 +817,10 @@ def get_video_mp4(self): video=self, encoding_format="video/mp4") def get_video_json(self, extensions): - list_src = [] - dict_src = {} extension_list = extensions.split(',') if extensions else [] list_video = EncodingVideo.objects.filter( video=self) - for video in list_video: - file_extension = splitext(video.source_file.url)[-1] - if extensions is None or file_extension[1:] in extension_list: - video_object = { - 'id': video.id, - 'type': video.encoding_format, - 'src': video.source_file.url, - 'height': video.height, - 'extension': file_extension, - 'label': video.name} - dict_entry = dict_src.get(file_extension[1:], None) - if dict_entry is None: - dict_src[file_extension[1:]] = [video_object] - else: - dict_entry.append(video_object) - - list_src.append( - { - 'id': video.id, - 'type': video.encoding_format, - 'src': video.source_file.url, - 'height': video.height, - 'extension': file_extension, - 'label': video.name}) + dict_src = Video.get_media_json(extension_list, list_video) sorted_dict_src = { x: sorted( dict_src[x], @@ -854,48 +829,35 @@ def get_video_json(self, extensions): return sorted_dict_src def get_audio_json(self, extensions): - list_src = [] - dict_src = {} extension_list = extensions.split(',') if extensions else [] list_audio = EncodingAudio.objects.filter( name="audio", video=self) - for audio in list_audio: - file_extension = splitext(audio.source_file.url)[-1] - audio_object = { - 'id': audio.id, - 'type': audio.encoding_format, - 'src': audio.source_file.url, - 'height': None, - 'extension': file_extension, - 'label': audio.name} - if extensions is None or file_extension[1:] in extension_list: - dict_entry = dict_src.get(file_extension[1:], None) - if dict_entry is None: - dict_src[file_extension[1:]] = [audio_object] - else: - dict_entry.append(audio_object) - - list_src.append( - audio_object) + dict_src = Video.get_media_json(extension_list, list_audio) return dict_src def get_audio_and_video_json(self, extensions): return {**self.get_video_json(extensions), **self.get_audio_json(extensions)} - def get_video_mp4_json(self): - list_src = [] - list_video = sorted(self.get_video_mp4(), key=lambda m: m.height) - for video in list_video: - list_src.append( - { - 'id': video.id, - 'type': video.encoding_format, - 'src': video.source_file.url, - 'height': video.height, - 'extension': splitext(video.source_file.url)[-1], - 'label': video.name}) - return list_src + @staticmethod + def get_media_json(self, extension_list, list_video): + dict_src = {} + for media in list_video: + file_extension = splitext(media.source_file.url)[-1] + if not extension_list or file_extension[1:] in extension_list: + video_object = { + 'id': media.id, + 'type': media.encoding_format, + 'src': media.source_file.url, + 'height': media.height, + 'extension': file_extension, + 'label': media.name} + dict_entry = dict_src.get(file_extension[1:], None) + if dict_entry is None: + dict_src[file_extension[1:]] = [video_object] + else: + dict_entry.append(video_object) + return dict_src def get_json_to_index(self): try: diff --git a/pod/video/rest_views.py b/pod/video/rest_views.py index 7a00b6b050..941962b48b 100644 --- a/pod/video/rest_views.py +++ b/pod/video/rest_views.py @@ -208,20 +208,24 @@ class EncodingVideoViewSet(viewsets.ModelViewSet): @action(detail=False, methods=['get']) def video_encodedfiles(self, request): - if request.GET.get('extension'): - encoded_videos = self.filter_queryset( - self.get_queryset()).filter( - video__id=request.GET.get('video'), - source_file__iendswith=request.GET.get('extension') - ) - else: - encoded_videos = self.filter_queryset(self.get_queryset()).filter( - video__id=request.GET.get('video')) + encoded_videos = EncodingVideoViewSet.filter_encoded_medias( + self.queryset, request) encoded_videos = sorted(encoded_videos, key=lambda x: x.height) serializer = EncodingVideoSerializer( encoded_videos, many=True, context={'request': request}) return Response(serializer.data) + @staticmethod + def filter_encoded_medias(queryset, request): + encoded_audios = queryset + if request.GET.get('video'): + encoded_audios = encoded_audios.filter( + video__id=request.GET.get('video')) + if request.GET.get('extension'): + encoded_audios = encoded_audios.filter( + source_file__iendswith=request.GET.get('extension')) + return encoded_audios + class EncodingAudioViewSet(viewsets.ModelViewSet): queryset = EncodingAudio.objects.all() @@ -229,16 +233,9 @@ class EncodingAudioViewSet(viewsets.ModelViewSet): filter_fields = ('video',) @action(detail=False, methods=['get']) - def audio_encodedescription_nldfiles(self, request): - if request.GET.get('extension'): - encoded_audios = self.filter_queryset( - self.get_queryset()).filter( - video__id=request.GET.get('video'), - source_file__iendswith=request.GET.get('extension') - ) - else: - encoded_audios = self.filter_queryset(self.get_queryset()).filter( - video__id=request.GET.get('video')) + def audio_encodedfiles(self, request): + encoded_audios = EncodingVideoViewSet.filter_encoded_medias( + self.queryset, request) serializer = EncodingAudioSerializer( encoded_audios, many=True, context={'request': request}) return Response(serializer.data) From 316faaf76226b46f4cb31b7e9c812a25c6f064bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Sen=C3=A9?= Date: Fri, 19 Feb 2021 18:27:04 +0100 Subject: [PATCH 005/261] wip: darkmode --- pod/main/static/css/pod.css | 1040 ++++++++++++++++++-------------- pod/main/templates/base.html | 31 + pod/main/templates/navbar.html | 9 + 3 files changed, 616 insertions(+), 464 deletions(-) diff --git a/pod/main/static/css/pod.css b/pod/main/static/css/pod.css index e452d2af88..26f8177ed9 100755 --- a/pod/main/static/css/pod.css +++ b/pod/main/static/css/pod.css @@ -1,464 +1,576 @@ -.submit-row a.deletelink { - height: 35px; -} - -.select2-container{ - position: static !important; - height:auto; -} - -tr ,.rowl{ - display: table-row !important; -} - -body[data-admin-utc-offset] -{ - padding-top: 0; -} - -body { - padding-top: 3.5rem; -} -.jumbotron { - padding: 1rem 2rem; -} -h1{ - font-size: 2rem; -} -label { - font-variant: small-caps; -} -.pod-mt-7{ - margin-top: 3.5rem; -} -.breadcrumb, .jumbotron{ - background: #f8f9fa; -} -.list-group-item{ - padding:.25rem 1.25rem; -} - -.container-pod{ - max-width: 1400px; -} - -/*** video ***/ -#myTabContent #info p { - margin-top: .5rem; - margin-bottom: .5rem; -} -#share legend{ - /* align text with feather-icon */ - line-height: 1em; -} - -.hidespinner { - display: none; -} - -.link-center-pod { - margin-left: auto; - margin-right: auto; -} - -/*** navbar **/ -/*.nav-link.btn-connexion{ - background: #b03c7e; - color: white !important; -}*/ -.btn-lang{ - padding: 0.2rem 0.25rem; - background: transparent; - width: 100%; - text-align: left; -} -.btn-lang-active{ - background: white; -} -.navbar-inner-pod{ - position: relative; -} -.navbar-toggler{ - padding: 0.5rem; - line-height: inherit; - font-size: 1rem; -} - -.userpicture { - height: 34px; -} - -/** modal **/ -.modal-title svg { - height: 40px; - width: 40px; - /*color:#b03c7e;*/ -} - -.modal-title{ - display: flex; - align-items: center; -} - -/*.modal-pod-full { - max-width: 90%; -}*/ -.modal-pod-full .close{ - font-size:3rem; -} - -.title-chaine{ - margin-right: 0.5rem; - font-weight: 600; -} -#listeChaines{ - max-height: 30rem; - overflow: auto; - border-bottom: 1px solid black; -} -.liste-collapse{ - z-index: 900; -} -/**end modal **/ -/*** tab **/ -.tab-content>.active{ - border: 1px solid #ddd; - padding: 1.5rem; - background: white; -} -.nav-tabs{ - border: 0; -} - -/***aside ***/ -.open-aside{ - margin-right: 15px; -} -#card-takenote .dropdown-menu{ - border: none; -} -/*** modif taille logo ***/ -@media (max-width: 576px ){ - .navbar-brand img{ - height: 35px; - } - .navbar-brand{ - font-size: 0.9rem; - } -} -@media (max-width: 992px){ - .langs{ - border-top: 1px solid silver; - } - .langs .active{ - /*background:#b03c7e; */ - border: none; - color: white; - } - .btn-connexion{ - font-size: 0.9rem; - } - .navbar-items-pod{ - position: absolute; - top:53px; - left:0; - padding: 1rem; - width: 100%; - } - .navbar-nav .login .dropdown-menu { - position: absolute; - float: left; - } - #s::-webkit-input-placeholder { /* Chrome/Opera/Safari */ - color: white; - } - #s::-moz-placeholder { /* Firefox 19+ */ - color: white; - } - #s:-ms-input-placeholder { /* IE 10+ */ - color: white; - } - #s:-moz-placeholder { /* Firefox 18- */ - color: white; - } - #s{ - width:1px; - border-radius:0; - box-shadow:none; - outline: none; - padding:0; - margin:0; - border:0; - background-color: transparent; - opacity:0; - position: absolute; - } - #s:focus{ - width:100%; - opacity:1; - display: inline-block !important; - position: absolute; - /*background: #b03c7e !important;*/ - padding: 0.5rem 1rem; - left: 0; - top:0; - z-index: 99; - color:white !important; - height: 74px; - } - .navbar label{ - padding-left: 1px; - display:inline-block; - margin-top:0.3em; - color:rgba(218,208,190,1); - text-shadow:0 0 0.1em rgba(60,60,60,0.3); - position: relative; - left:0.1em; - cursor:pointer; - } - -} -/*** end MQueries **/ - -.login > .initials{ - border-radius: 50%; - /*background: #f8f9fa;*/ - color: white !important; - font-weight: 600; - height: 3rem; - width: 3rem; -} -.nav-link{ - padding: 0.25rem 0.5rem; -} -button.nav-link{ - background: none; - border: none; - cursor: pointer; -} - -/*** CARD ***/ -.infinite-item .card-body { - padding: 0.9rem; - height: 3.5rem; - overflow: hidden; -} -.infinite-item .card-header .octicon { - height:0.9rem; - margin:0.1rem; -} - -#videos_list .card-header, .playlist-videos .card-header { - position:absolute; - width:100%; - background: rgba(0, 0, 0, 0.6); - padding: 0 0.25rem; - z-index: 9; -} -#videos_list .card-header .text-muted { - color:white !important; -} - -#videos_list .video-title{ - line-height: 1.2; - display: inline-block; -} - -div.video-card .d-flex { - min-height:70%; - /*position:relative;*/ - top:0; -} -div.card a{ - overflow:hidden; -} -div.card a img { - transition:-webkit-transform .5s ease; - transition:transform .5s ease; - transition:transform .5s ease, -webkit-transform .5s ease -} -div.card a:hover>img { - -webkit-transform:scale(1.1); - transform:scale(1.1); - z-index:0; -} -.card-footer-pod { - position: absolute; - bottom: 57px; - right: 2px; - /*width: 100%; - text-align: center;*/ - border:none; - /*background: rgba(220,220,220);*/ - /*height: 1rem;*/ -} -.card-footer .feather, .card-header .feather{ - height: 1rem; -} -/* menu channels */ -.dropdown-submenu > .dropdown-menu { - top: 0; - left: 100%; - margin-top: -6px; - margin-left: -1px; - border-radius: 0 6px 6px 6px; -} -.dropdown-submenu:hover { - background-color: white; -} -.dropdown-submenu:hover > .dropdown-menu { - display: block; -} -.dropdown-submenu > a:after { - display: block; - content: " "; - float: right; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; - border-width: 5px 0 5px 5px; - border-left-color: #ccc; - margin-top: 5px; - margin-right: -10px; -} - -/** aside list video **/ -#filterType div.collapse:not(.show), #filterDiscipline div.collapse:not(.show), #filterTag div.collapse:not(.show) { - height: 148px !important; - overflow: hidden; - - display: -webkit-box; - -webkit-line-clamp: 2; - -webkit-box-orient: vertical; -} - -#filterType div.collapsing, #filterDiscipline div.collapsing, #filterTag div.collapsing{ - min-height: 148px !important; -} - -#filterType a.collapsed:after, #filterDiscipline a.collapsed:after, #filterTag a.collapsed:after { - content: '+'; -} - -#filterType a:not(.collapsed):after, #filterDiscipline a:not(.collapsed):after, #filterTag a:not(.collapsed):after { - content: '-'; -} -/** ckeditor **/ -.django-ckeditor-widget { - width: 100%; -} -/** video form **/ -.required { - color:red; - font-size: 1.3rem; -} -/*.form-group-required { - border-left: 3px solid rgba(201, 76, 76, 0.3); - padding-left : 5px; -}*/ -.form-group-required .errors { - background-color: rgba(201, 76, 76, 0.3); -} -#base-message-alert, #formalertdiv{ - position:fixed; - top:50%; - text-align: center; - margin:0 auto; - left: 50%; - transform: translate(-50%, 0); - z-index:1000; -} - -/** channel form **/ -#channel_form .selector, #enrichment_group_form .selector{ - width: 100% !important; -} -#channel_form .selector select, #enrichment_group_form .selector select { - width:100% !important; -} -#channel_form .selector-available, #channel_form .selector-chosen, #enrichment_group_form .selector-available, #enrichment_group_form .selector-chosen { - width: 47% !important; -} -#channel_form .selector-available h2, #channel_form .selector-chosen h2, #enrichment_group_form .selector-available h2, #enrichment_group_form .selector-chosen h2 { - margin: 0; - padding: 8px; - font-weight: 400; - font-size: 13px; - text-align: left; -} - -/* vignettes video */ -@media (max-width: 575.98px) { - .pod-flex-direction{ - flex-direction: column; - } -} -@media screen and (min-width:768px){ - .card-img-top { - max-height:184.13px; - } -} -@media screen and (min-width:992px){ - .card-img-top { - max-height:195.36px; - } - .flex-2{ - flex: 2; - } -} -/*** footer **/ -footer{ - color:#aaa; -} -footer a, footer a:hover{ - color: white; -} - -.footer_links{ - list-style:none; -} -.footer_links>li:before{ - margin-right:.5em; - content: ">"; - font-weight: bold; -} - -.top_link:before{ - content: "\21E7"; - padding-right: 4px; - text-decoration: none; - display: inline-block; - font-size: 1.2em; -} - -/*** Useful for additional owners ***/ -input.select2-input{ - width: 100% !important; -} - -#view-counter-icon{ - color: var(--primary2); -} - - -#viewers-list { - position: absolute; - right: 0; - margin-right: 80px; - color: #FFF; - text-align: center; - font-size: 20px; - background-color: rgba(40,48,56, 0.5); - padding: 10px 0; - z-index: 2147483647; - bottom: 100px; - display: none; -} - -.live-video { - z-index: 1; -} - -#viewers-ul{height:200px;list-style-type: none;padding-left: 0; } -#viewers-ul{overflow:hidden; overflow-y:scroll;} +[data-theme="light"] { + --primary-background-color: #fff !important; + --third-background-color: #fff !important; + --bg-color: #111; + --font-color: #212529; + --title-color: #fec150; + --title-background: #222; + --main-border: 1px solid rgba(255, 255, 255, 0.2); + --main-bg: #fff; + --jumbotron-bg: #f8f9fa; + --breadcrumbs-bg: #f8f9fa; + --card-bg: #fff; + --tab-active: #fff; +} + +[data-theme="dark"] { + --primary-background-color: rgba(70,70,70) !important; + --third-background-color: #484848 !important; + --bg-color: #111; + --font-color: #d8d8d8; + --title-color: #fec150; + --title-background: #222; + --main-border: 1px solid rgba(255, 255, 255, 0.2); + --main-bg: rgba(70,70,70); + --jumbotron-bg: #4e4e4e; + --breadcrumbs-bg: #333333; + --card-bg: #2f2f2f; + --tab-active: #484848; +} + +.submit-row a.deletelink { + height: 35px; +} + +.select2-container{ + position: static !important; + height:auto; +} + +tr ,.rowl{ + display: table-row !important; +} + +body[data-admin-utc-offset] +{ + padding-top: 0; +} + +body { + background-color: var(--main-bg); + padding-top: 3.5rem; + color: var(--font-color); +} +.jumbotron { + background-color: var(--jumbotron-bg) !important; + padding: 1rem 2rem; +} +h1{ + font-size: 2rem; +} +label { + font-variant: small-caps; +} +.pod-mt-7{ + margin-top: 3.5rem; +} +.breadcrumb, .jumbotron{ + background: var(--breadcrumbs-bg) !important; +} +.list-group-item{ + padding:.25rem 1.25rem; +} + +.container-pod{ + max-width: 1400px; +} + +/*** video ***/ +#myTabContent #info p { + margin-top: .5rem; + margin-bottom: .5rem; +} +#share legend{ + /* align text with feather-icon */ + line-height: 1em; +} + +.hidespinner { + display: none; +} + +.link-center-pod { + margin-left: auto; + margin-right: auto; +} + +/*** navbar **/ +/*.nav-link.btn-connexion{ + background: #b03c7e; + color: white !important; +}*/ +.btn-lang{ + padding: 0.2rem 0.25rem; + background: transparent; + width: 100%; + text-align: left; +} +.btn-lang-active{ + background: white; +} +.navbar-inner-pod{ + position: relative; +} +.navbar-toggler{ + padding: 0.5rem; + line-height: inherit; + font-size: 1rem; +} + +.userpicture { + height: 34px; +} + +/** modal **/ +.modal-title svg { + height: 40px; + width: 40px; + /*color:#b03c7e;*/ +} + +.modal-title{ + display: flex; + align-items: center; +} + +/*.modal-pod-full { + max-width: 90%; +}*/ +.modal-pod-full .close{ + font-size:3rem; +} + +.title-chaine{ + margin-right: 0.5rem; + font-weight: 600; +} +#listeChaines{ + max-height: 30rem; + overflow: auto; + border-bottom: 1px solid black; +} +.liste-collapse{ + z-index: 900; +} +/**end modal **/ +/*** tab **/ +.tab-content>.active{ + border: 1px solid #ddd; + padding: 1.5rem; + background: var(--tab-active); +} +.nav-tabs{ + border: 0; +} + +/***aside ***/ +.open-aside{ + margin-right: 15px; +} +#card-takenote .dropdown-menu{ + border: none; +} +/*** modif taille logo ***/ +@media (max-width: 576px ){ + .navbar-brand img{ + height: 35px; + } + .navbar-brand{ + font-size: 0.9rem; + } +} +@media (max-width: 992px){ + .langs{ + border-top: 1px solid silver; + } + .langs .active{ + /*background:#b03c7e; */ + border: none; + color: white; + } + .btn-connexion{ + font-size: 0.9rem; + } + .navbar-items-pod{ + position: absolute; + top:53px; + left:0; + padding: 1rem; + width: 100%; + } + .navbar-nav .login .dropdown-menu { + position: absolute; + float: left; + } + #s::-webkit-input-placeholder { /* Chrome/Opera/Safari */ + color: white; + } + #s::-moz-placeholder { /* Firefox 19+ */ + color: white; + } + #s:-ms-input-placeholder { /* IE 10+ */ + color: white; + } + #s:-moz-placeholder { /* Firefox 18- */ + color: white; + } + #s{ + width:1px; + border-radius:0; + box-shadow:none; + outline: none; + padding:0; + margin:0; + border:0; + background-color: transparent; + opacity:0; + position: absolute; + } + #s:focus{ + width:100%; + opacity:1; + display: inline-block !important; + position: absolute; + /*background: #b03c7e !important;*/ + padding: 0.5rem 1rem; + left: 0; + top:0; + z-index: 99; + color:white !important; + height: 74px; + } + .navbar label{ + padding-left: 1px; + display:inline-block; + margin-top:0.3em; + color:rgba(218,208,190,1); + text-shadow:0 0 0.1em rgba(60,60,60,0.3); + position: relative; + left:0.1em; + cursor:pointer; + } + +} +/*** end MQueries **/ + +.login > .initials{ + border-radius: 50%; + /*background: #f8f9fa;*/ + color: white !important; + font-weight: 600; + height: 3rem; + width: 3rem; +} +.nav-link{ + padding: 0.25rem 0.5rem; +} +button.nav-link{ + background: none; + border: none; + cursor: pointer; +} + +/*** CARD ***/ +.card { + background: var(--card-bg); +} + +.infinite-item .card-body { + padding: 0.9rem; + height: 3.5rem; + overflow: hidden; +} +.infinite-item .card-header .octicon { + height:0.9rem; + margin:0.1rem; +} + +#videos_list .card-header, .playlist-videos .card-header { + position:absolute; + width:100%; + background: rgba(0, 0, 0, 0.6); + padding: 0 0.25rem; + z-index: 9; +} +#videos_list .card-header .text-muted { + color:white !important; +} + +#videos_list .video-title{ + line-height: 1.2; + display: inline-block; +} + +div.video-card .d-flex { + min-height:70%; + /*position:relative;*/ + top:0; +} +div.card a{ + overflow:hidden; +} +div.card a img { + transition:-webkit-transform .5s ease; + transition:transform .5s ease; + transition:transform .5s ease, -webkit-transform .5s ease +} +div.card a:hover>img { + -webkit-transform:scale(1.1); + transform:scale(1.1); + z-index:0; +} +.card-footer-pod { + position: absolute; + bottom: 57px; + right: 2px; + /*width: 100%; + text-align: center;*/ + border:none; + /*background: rgba(220,220,220);*/ + /*height: 1rem;*/ +} +.card-footer .feather, .card-header .feather{ + height: 1rem; +} +/* menu channels */ +.dropdown-submenu > .dropdown-menu { + top: 0; + left: 100%; + margin-top: -6px; + margin-left: -1px; + border-radius: 0 6px 6px 6px; +} +.dropdown-submenu:hover { + background-color: white; +} +.dropdown-submenu:hover > .dropdown-menu { + display: block; +} +.dropdown-submenu > a:after { + display: block; + content: " "; + float: right; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; + border-width: 5px 0 5px 5px; + border-left-color: #ccc; + margin-top: 5px; + margin-right: -10px; +} + +/** aside list video **/ +#filterType div.collapse:not(.show), #filterDiscipline div.collapse:not(.show), #filterTag div.collapse:not(.show) { + height: 148px !important; + overflow: hidden; + + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; +} + +#filterType div.collapsing, #filterDiscipline div.collapsing, #filterTag div.collapsing{ + min-height: 148px !important; +} + +#filterType a.collapsed:after, #filterDiscipline a.collapsed:after, #filterTag a.collapsed:after { + content: '+'; +} + +#filterType a:not(.collapsed):after, #filterDiscipline a:not(.collapsed):after, #filterTag a:not(.collapsed):after { + content: '-'; +} +/** ckeditor **/ +.django-ckeditor-widget { + width: 100%; +} +/** video form **/ +.required { + color:red; + font-size: 1.3rem; +} +/*.form-group-required { + border-left: 3px solid rgba(201, 76, 76, 0.3); + padding-left : 5px; +}*/ +.form-group-required .errors { + background-color: rgba(201, 76, 76, 0.3); +} +#base-message-alert, #formalertdiv{ + position:fixed; + top:50%; + text-align: center; + margin:0 auto; + left: 50%; + transform: translate(-50%, 0); + z-index:1000; +} + +/** channel form **/ +#channel_form .selector, #enrichment_group_form .selector{ + width: 100% !important; +} +#channel_form .selector select, #enrichment_group_form .selector select { + width:100% !important; +} +#channel_form .selector-available, #channel_form .selector-chosen, #enrichment_group_form .selector-available, #enrichment_group_form .selector-chosen { + width: 47% !important; +} +#channel_form .selector-available h2, #channel_form .selector-chosen h2, #enrichment_group_form .selector-available h2, #enrichment_group_form .selector-chosen h2 { + margin: 0; + padding: 8px; + font-weight: 400; + font-size: 13px; + text-align: left; +} + +/* vignettes video */ +@media (max-width: 575.98px) { + .pod-flex-direction{ + flex-direction: column; + } +} +@media screen and (min-width:768px){ + .card-img-top { + max-height:184.13px; + } +} +@media screen and (min-width:992px){ + .card-img-top { + max-height:195.36px; + } + .flex-2{ + flex: 2; + } +} +/*** footer **/ +footer{ + color:#aaa; +} +footer a, footer a:hover{ + color: white; +} + +.footer_links{ + list-style:none; +} +.footer_links>li:before{ + margin-right:.5em; + content: ">"; + font-weight: bold; +} + +.top_link:before{ + content: "\21E7"; + padding-right: 4px; + text-decoration: none; + display: inline-block; + font-size: 1.2em; +} + +/*** Useful for additional owners ***/ +input.select2-input{ + width: 100% !important; +} + +#view-counter-icon{ + color: var(--primary2); +} + + +#viewers-list { + position: absolute; + right: 0; + margin-right: 80px; + color: #FFF; + text-align: center; + font-size: 20px; + background-color: rgba(40,48,56, 0.5); + padding: 10px 0; + z-index: 2147483647; + bottom: 100px; + display: none; +} + +.live-video { + z-index: 1; +} + +#viewers-ul{height:200px;list-style-type: none;padding-left: 0; } +#viewers-ul{overflow:hidden; overflow-y:scroll;} + +/*** DARK MODE SWITCH ***/ +.theme-switch-wrapper { + display: flex; + align-items: center; +} +.theme-switch-wrapper em { + margin-left: 10px; + font-size: 1rem; +} +.theme-switch { + display: inline-block; + height: 34px; + position: relative; + width: 60px; + top:7px; +} +.theme-switch input { + display: none; +} +.slider { + background-color: #ccc; + bottom: 0; + cursor: pointer; + left: 0; + position: absolute; + right: 0; + top: 0; + transition: 0.4s; + border-radius: 34px; +} +.slider:before { + background-color: #fff; + bottom: 4px; + content: ""; + height: 26px; + left: 4px; + position: absolute; + transition: 0.4s; + width: 26px; + border-radius: 50%; +} +input:checked + .slider { + background-color: var(--primary); +} +input:checked + .slider:before { + transform: translateX(26px); +} +.slider svg { + color: #222; + position: absolute; + transition: opacity 0.2s ease 0s, transform 0.35s ease 0s; + pointer-events: none; +} +.feather-moon { + opacity: 0; + left: 2px; + bottom: 5px; + color: white !important; + transform: translateX(4px); +} +.feather-sun { + opacity: 1; + right: 2px; + bottom: 5px; + transform: translateX(0px); +} +input:checked + .slider .feather-moon { + opacity: 1; + transform: translateX(0); +} +input:checked + .slider .feather-sun { + opacity: 0; + transform: translateX(-4px); +} diff --git a/pod/main/templates/base.html b/pod/main/templates/base.html index b9cde31166..2c6daacfba 100644 --- a/pod/main/templates/base.html +++ b/pod/main/templates/base.html @@ -137,6 +137,37 @@ + + + {% if POST_FOOTER_TEMPLATE %}{% include POST_FOOTER_TEMPLATE %}{% endif %} {% if TRACKING_TEMPLATE %}{% include TRACKING_TEMPLATE %}{% endif %} diff --git a/pod/main/templates/navbar.html b/pod/main/templates/navbar.html index d1fa8d4ef7..1aa4b48e98 100644 --- a/pod/main/templates/navbar.html +++ b/pod/main/templates/navbar.html @@ -137,6 +137,15 @@ {% endif %} + {% endspaceless %} From 9046854e3f061cb644824c35fd4ca8ff131e99f8 Mon Sep 17 00:00:00 2001 From: Olivier Bado Date: Tue, 23 Feb 2021 17:37:59 +0100 Subject: [PATCH 006/261] Improve Pod accessibility : + add some "role="button" on some links + "local login" button has now secondary class + replace the "×" in remove filter links by CSS + re-display labels in search form + rename "#mytabcontent" into "#video-meta", as it represents more its purpose + some code formatting on pod.css + some code formating in .py (add __author__ and __license__ pydoc) + Fix a small css bug by adding "col-md-9" in base.html to prevent aside behing diplayed on bottom of page when main content very large strings (like long URL) --- .../templates/authentication/login.html | 6 +- pod/custom/settings_local.py.example | 10 +- .../interactive/video_interactive.html | 18 +- pod/locale/fr/LC_MESSAGES/django.mo | Bin 97286 -> 97467 bytes pod/locale/fr/LC_MESSAGES/django.po | 240 +++++----- pod/locale/fr/LC_MESSAGES/djangojs.po | 22 +- pod/locale/nl/LC_MESSAGES/django.po | 218 ++++----- pod/locale/nl/LC_MESSAGES/djangojs.po | 22 +- pod/main/static/css/pod.css | 148 ++++--- pod/main/templates/base.html | 4 +- pod/video/encode.py | 7 +- pod/video/encode_gpu.py | 15 +- pod/video/templates/videos/video-iframe.html | 2 +- pod/video/templates/videos/video-info.html | 418 ++++++++++-------- pod/video_search/templates/search/search.html | 36 +- pod/video_search/views.py | 9 +- 16 files changed, 639 insertions(+), 536 deletions(-) diff --git a/pod/authentication/templates/authentication/login.html b/pod/authentication/templates/authentication/login.html index d44521ecde..64d9acbc4d 100644 --- a/pod/authentication/templates/authentication/login.html +++ b/pod/authentication/templates/authentication/login.html @@ -13,13 +13,13 @@

{% trans 'Authentication' %}

{% if USE_CAS %} -

{% trans "Single sign on" %} {{TITLE_ETB}}

+

{% trans "Single sign on" %} {{TITLE_ETB}}

{% endif %} {% if USE_SHIB %} -

{{ SHIB_NAME}}

+

{{ SHIB_NAME}}

{% endif %} {% if not local_login %} -

{% trans "Local sign on" %}

+

{% trans "Local sign on" %}

{% endif %}
diff --git a/pod/custom/settings_local.py.example b/pod/custom/settings_local.py.example index 3c2135720f..12bcc71bab 100644 --- a/pod/custom/settings_local.py.example +++ b/pod/custom/settings_local.py.example @@ -421,13 +421,13 @@ ES_TIMEOUT = 30 """ ES_MAX_RETRIES = 10 """ -# Valeur la version d'ElasticSearch -# valeurs possibles 6 ou 7 (pour indiquer utiliser elasticsearch 6 ou 7) -# pour utiliser la version 7, faire une mise à jour du paquet elasticsearch-py +# Version d'ElasticSearch +# valeurs possibles 6 ou 7 (pour indiquer utiliser ElasticSearch 6 ou 7) +# pour utiliser la version 7, faire une mise à jour du paquet elasticsearch-py # elasticsearch==7.10.1 # https://elasticsearch-py.readthedocs.io/en/v7.10.1/ """ -ES_VERSION = 6 # Si 7, faire un une mise à jour du paquet +ES_VERSION = 6 # Si 7, faire un une mise à jour du paquet # ## Configuration encodage ## # @@ -1179,6 +1179,6 @@ SESSION_COOKIE_SAMESITE = 'Lax' # Exemple valeur: ["discipline", "tags"] # NB: les champs cachés et suivant ne sont pas pris en compte: # (video, title, type, owner, date_added, cursus, main_lang) -# +# """ VIDEO_REQUIRED_FIELDS = [] diff --git a/pod/interactive/templates/interactive/video_interactive.html b/pod/interactive/templates/interactive/video_interactive.html index d8da530e89..33f572601b 100644 --- a/pod/interactive/templates/interactive/video_interactive.html +++ b/pod/interactive/templates/interactive/video_interactive.html @@ -21,7 +21,7 @@ {% endblock page_extra_head %} -{% block breadcrumbs %}{{ block.super }} +{% block breadcrumbs %}{{ block.super }} {% endblock %} {% block page_title %}{%if channel %}{{channel.title}} - {%endif%}{%if theme %}{{theme.title}} - {%endif%}({% trans 'Interactive video' %}) {{video.title}}{% endblock %} @@ -40,7 +40,7 @@
{% csrf_token %}
- +

{% if video.licence %}{% endif %} {{video.title|title}} {% if video.date_evt %}[{{ video.date_evt }}]{% endif %} @@ -119,9 +119,9 @@

- + {% include 'videos/video-info.html' with interactive=True %} - +
 {% trans 'Scoreboard' %}
{% trans 'Click below to refresh the information.' %} @@ -180,7 +180,7 @@
 {% trans 'Scoreboard' %}
{% endif %} - + {%endif%} @@ -188,7 +188,7 @@

 {% trans 'Scoreboard' %}
{% endblock video-element %} {% block page_aside %} - {{ block.super }} + {{ block.super }} {% endblock page_aside %} {% block more_script %} @@ -242,11 +242,11 @@
 {% trans 'Scoreboard' %}
} }); }); - + // Add dynamically the scoreboard to the panel - var $myTabContent = $("#myTabContent"); + var $videoMeta = $("#video-meta"); var divScore = document.getElementById("score"); - $myTabContent.append(divScore); + $videoMeta.append(divScore); {% endblock more_script %} diff --git a/pod/locale/fr/LC_MESSAGES/django.mo b/pod/locale/fr/LC_MESSAGES/django.mo index 71571b780c34674cf14165f5f21a9f5273db4cf5..db2eba8abc35dace5cb1ba5a5c84d56c80a0de00 100644 GIT binary patch delta 24852 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�@zeU-#H3UrjB@>`^R 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 diff --git a/pod/locale/fr/LC_MESSAGES/django.po b/pod/locale/fr/LC_MESSAGES/django.po index 8142ccfb9c..cbccaf71aa 100755 --- 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: 2021-02-19 08:39+0000\n" +"POT-Creation-Date: 2021-02-23 16:32+0000\n" "PO-Revision-Date: \n" "Last-Translator: obado \n" "Language-Team: \n" @@ -90,7 +90,7 @@ msgid "registered-reader" msgstr "lecteur enregistré" #: pod/authentication/models.py:68 pod/recorder/models.py:266 -#: pod/video/models.py:1421 pod/video/models.py:1473 pod/video/views.py:1306 +#: pod/video/models.py:1421 pod/video/models.py:1473 pod/video/views.py:1301 msgid "Comment" msgstr "Commentaire" @@ -163,9 +163,9 @@ msgstr "Changer votre image de profil" #: pod/video/templates/videos/video_note_comments_display.html:148 #: pod/video/templates/videos/video_note_display.html:27 #: pod/video/templates/videos/video_notes.html:80 -#: pod/video/templates/videos/video_notes.html:116 pod/video/views.py:259 -#: pod/video/views.py:742 pod/video/views.py:796 pod/video/views.py:1226 -#: pod/video_search/templates/search/search.html:42 +#: pod/video/templates/videos/video_notes.html:116 pod/video/views.py:254 +#: pod/video/views.py:737 pod/video/views.py:791 pod/video/views.py:1221 +#: pod/video_search/templates/search/search.html:50 msgid "One or more errors have been found in the form." msgstr "Une ou plusieurs erreurs ont été trouvées dans le formulaire." @@ -934,7 +934,7 @@ msgstr "Fin" msgid "End time of the overlay, in seconds." msgstr "Fin de la superposition, en secondes." -#: pod/completion/models.py:279 pod/video/views.py:1335 +#: pod/completion/models.py:279 pod/video/views.py:1330 msgid "Content" msgstr "Contenu" @@ -1362,10 +1362,14 @@ msgstr "Le fichier n’a pas été enregistré." #: pod/completion/views.py:237 pod/completion/views.py:413 #: pod/completion/views.py:814 pod/podfile/views.py:470 -#: pod/podfile/views.py:520 pod/video/views.py:349 pod/video/views.py:1384 +#: pod/podfile/views.py:520 pod/video/views.py:344 pod/video/views.py:1379 msgid "Please correct errors" msgstr "Veuillez corriger les erreurs" +#: pod/custom/settings_local.py:76 +msgid "Dutch (Netherlands)" +msgstr "Néerlandais (Pays-Bas)" + #: pod/enrichment/apps.py:7 msgid "Enrichment version" msgstr "Version enrichie" @@ -1429,7 +1433,7 @@ msgstr "Temps de fin de l'affichage de l'enrichissement en secondes." #: pod/enrichment/models.py:137 #: pod/enrichment/templates/enrichment/list_enrichment.html:11 #: pod/video/forms.py:103 pod/video/models.py:418 pod/video/models.py:473 -#: pod/video/views.py:1332 pod/video_search/templates/search/search.html:77 +#: pod/video/views.py:1327 pod/video_search/templates/search/search.html:87 msgid "Type" msgstr "Type" @@ -1632,7 +1636,7 @@ msgstr "Description" #: pod/enrichment/templates/enrichment/video_enrichment.html:75 #: pod/interactive/templates/interactive/video_interactive.html:61 #: pod/interactive/templates/interactive/video_interactive.html:62 -#: pod/video/templates/videos/video-info.html:33 +#: pod/video/templates/videos/video-info.html:36 #: pod/video/templates/videos/video.html:175 #: pod/video/templates/videos/video.html:177 #: pod/video/templates/videos/video.html:179 @@ -1643,7 +1647,7 @@ msgstr "Informations" #: pod/enrichment/templates/enrichment/video_enrichment.html:81 #: pod/interactive/templates/interactive/video_interactive.html:67 #: pod/interactive/templates/interactive/video_interactive.html:68 -#: pod/video/templates/videos/video-info.html:109 +#: pod/video/templates/videos/video-info.html:156 #: pod/video/templates/videos/video.html:184 #: pod/video/templates/videos/video.html:185 msgid "Downloads" @@ -1653,7 +1657,7 @@ msgstr "Téléchargements" #: pod/enrichment/templates/enrichment/video_enrichment.html:87 #: pod/interactive/templates/interactive/video_interactive.html:73 #: pod/interactive/templates/interactive/video_interactive.html:74 -#: pod/video/templates/videos/video-info.html:155 +#: pod/video/templates/videos/video-info.html:198 #: pod/video/templates/videos/video.html:191 #: pod/video/templates/videos/video.html:192 msgid "Embed/Share" @@ -2040,7 +2044,7 @@ msgstr "Mot de passe requis" #: pod/video/templates/videos/filter_aside.html:78 #: pod/video/templates/videos/video-form.html:31 #: pod/video/templates/videos/video_delete.html:61 -#: pod/video_search/templates/search/search.html:54 +#: pod/video_search/templates/search/search.html:64 msgid "Send" msgstr "Envoyer" @@ -2053,7 +2057,7 @@ msgid "access map" msgstr "plan d'accès" #: pod/live/templates/live/live.html:132 -#: pod/video/templates/videos/video-script.html:26 +#: pod/video/templates/videos/video-script.html:27 msgid "Please use different browser" msgstr "Utilisez un navigateur compatible" @@ -2086,7 +2090,7 @@ msgstr "Désolé, aucun bâtiment trouvé" msgid "You cannot view this page." msgstr "Vous ne pouvez pas éditer cette image." -#: pod/live/views.py:91 pod/video/views.py:652 +#: pod/live/views.py:91 pod/video/views.py:647 msgid "The password is incorrect." msgstr "Le mot de passe est incorrect." @@ -2841,9 +2845,9 @@ msgstr "Partager" #: pod/main/templates/aside.html:11 pod/main/templates/aside.html:12 #: pod/main/templates/aside.html:13 -#: pod/video/templates/videos/video-info.html:159 -#: pod/video/templates/videos/video-info.html:160 -#: pod/video/templates/videos/video-info.html:161 +#: pod/video/templates/videos/video-info.html:204 +#: pod/video/templates/videos/video-info.html:205 +#: pod/video/templates/videos/video-info.html:206 msgid "Share on" msgstr "Partager sur" @@ -2856,7 +2860,7 @@ msgstr "Disciplines" #: pod/main/templates/aside.html:40 pod/recorder/models.py:184 #: pod/video/forms.py:132 pod/video/models.py:519 #: pod/video/templates/videos/filter_aside.html:78 -#: pod/video_search/templates/search/search.html:89 +#: pod/video_search/templates/search/search.html:99 msgid "Tags" msgstr "Mots clés" @@ -2984,7 +2988,6 @@ msgstr "Types" #: pod/video/templates/videos/filter_aside_category.html:24 #: pod/video_search/forms.py:8 pod/video_search/templates/search/search.html:8 #: pod/video_search/templates/search/search.html:17 -#: pod/video_search/templates/search/search.html:38 msgid "Search" msgstr "Rechercher" @@ -3074,7 +3077,7 @@ msgstr "Votre message a été envoyé." #: pod/playlist/models.py:20 #: pod/playlist/templates/playlist/playlist_element_list.html:12 #: pod/podfile/models.py:30 pod/video/admin.py:168 pod/video/models.py:477 -#: pod/video_search/templates/search/search.html:65 +#: pod/video_search/templates/search/search.html:75 msgid "Owner" msgstr "Propriétaire" @@ -3474,7 +3477,7 @@ msgstr "Master" msgid "Doctorate" msgstr "Doctorat" -#: pod/recorder/models.py:34 pod/video/models.py:67 pod/video/views.py:164 +#: pod/recorder/models.py:34 pod/video/models.py:67 pod/video/views.py:159 msgid "Other" msgstr "Autre" @@ -3592,7 +3595,7 @@ msgid "Viewing this video will not be possible without this password." msgstr "Voir cette vidéo n'est pas possible sans mot de passe." #: pod/recorder/models.py:169 pod/video/forms.py:122 pod/video/models.py:504 -#: pod/video_search/templates/search/search.html:140 +#: pod/video_search/templates/search/search.html:150 msgid "University course" msgstr "Cursus universitaire" @@ -3602,7 +3605,7 @@ msgstr "" "Sélectionner un cursus universitaire qui convient à l'audience de ce contenu." #: pod/recorder/models.py:174 pod/video/forms.py:129 pod/video/models.py:509 -#: pod/video_search/templates/search/search.html:127 +#: pod/video_search/templates/search/search.html:137 msgid "Main language" msgstr "Langue principale" @@ -3931,7 +3934,7 @@ msgstr "Fichier" msgid "You can send an audio or video file." msgstr "Vous pouvez envoyer un fichier audio ou vidéo." -#: pod/video/forms.py:91 pod/video/views.py:1644 +#: pod/video/forms.py:91 pod/video/views.py:1639 #, python-format msgid "The following formats are supported: %s" msgstr "Les formats suivants sont supportés: %s" @@ -4304,7 +4307,7 @@ msgstr "" "Si coché, la chaîne apparaîtra dans la liste des chaînes de la plateforme." #: pod/video/models.py:260 pod/video/models.py:322 -#: pod/video_search/templates/search/search.html:114 +#: pod/video_search/templates/search/search.html:124 msgid "Channel" msgstr "Chaîne" @@ -4320,7 +4323,7 @@ msgstr "Thème" msgid "Icon" msgstr "Icone" -#: pod/video/models.py:444 pod/video_search/templates/search/search.html:101 +#: pod/video/models.py:444 pod/video_search/templates/search/search.html:111 msgid "Discipline" msgstr "Discipline" @@ -4503,7 +4506,7 @@ msgid "Encoding steps" msgstr "Etapes de l'encodage" #: pod/video/models.py:1337 pod/video/models.py:1344 pod/video/models.py:1360 -#: pod/video/views.py:1317 +#: pod/video/views.py:1312 msgid "Note" msgstr "Note" @@ -4652,7 +4655,7 @@ msgstr "Éditer la chaîne" #: pod/video/templates/videos/videos.html:12 #: pod/video/templates/videos/videos.html:19 #: pod/video/templates/videos/videos.html:24 -#: pod/video_search/templates/search/search.html:25 +#: pod/video_search/templates/search/search.html:36 #, python-format msgid "%(counter)s video found" msgid_plural "%(counter)s videos found" @@ -4874,6 +4877,7 @@ msgstr "Filtres" #: pod/video/templates/videos/filter_aside.html:53 #: pod/video/templates/videos/filter_aside.html:75 #: pod/video/templates/videos/filter_aside.html:99 +#: pod/video_search/templates/search/search.html:71 msgid "Filter" msgstr "Filtre" @@ -4997,94 +5001,94 @@ msgstr "Mots clés :" msgid "No information available" msgstr "Aucune information disponible" -#: pod/video/templates/videos/video-info.html:36 +#: pod/video/templates/videos/video-info.html:39 msgid "Added by:" msgstr "Ajouté par :" -#: pod/video/templates/videos/video-info.html:46 -msgid "Additional owners:" -msgstr "Propriétaires additionels :" +#: pod/video/templates/videos/video-info.html:52 +msgid "Additional owner(s):" +msgstr "Propriétaire(s) additionnel(s) :" -#: pod/video/templates/videos/video-info.html:59 -msgid "Contributors:" -msgstr "Contributeurs :" +#: pod/video/templates/videos/video-info.html:70 +msgid "Contributor(s):" +msgstr "Contributeur(s) :" -#: pod/video/templates/videos/video-info.html:63 +#: pod/video/templates/videos/video-info.html:76 msgid "send an email" msgstr "envoyer un courriel" -#: pod/video/templates/videos/video-info.html:68 +#: pod/video/templates/videos/video-info.html:81 msgid "contributor web link" msgstr "lien du contributeur" -#: pod/video/templates/videos/video-info.html:78 +#: pod/video/templates/videos/video-info.html:92 msgid "Updated on:" msgstr "Mis à jour le :" -#: pod/video/templates/videos/video-info.html:79 +#: pod/video/templates/videos/video-info.html:97 msgid "Duration:" msgstr "Durée :" -#: pod/video/templates/videos/video-info.html:80 +#: pod/video/templates/videos/video-info.html:103 msgid "Channel:" msgid_plural " Channels:" msgstr[0] "Chaîne:" msgstr[1] " Chaînes:" -#: pod/video/templates/videos/video-info.html:81 -msgid "Number of view:" +#: pod/video/templates/videos/video-info.html:111 +msgid "Number of views:" msgstr "Nombre de vues :" -#: pod/video/templates/videos/video-info.html:81 +#: pod/video/templates/videos/video-info.html:114 msgid "Show details of view statistics" msgstr "Afficher les details des statistiques de visualisation" -#: pod/video/templates/videos/video-info.html:81 +#: pod/video/templates/videos/video-info.html:114 msgid "Show details views" msgstr "Afficher les details de visualisation" -#: pod/video/templates/videos/video-info.html:85 +#: pod/video/templates/videos/video-info.html:119 msgid "Type:" msgstr "Type :" -#: pod/video/templates/videos/video-info.html:86 +#: pod/video/templates/videos/video-info.html:124 msgid "Main language:" msgstr "Langue principale :" -#: pod/video/templates/videos/video-info.html:88 +#: pod/video/templates/videos/video-info.html:130 msgid "Audience:" msgstr "Public :" -#: pod/video/templates/videos/video-info.html:92 -msgid "Disciplines:" -msgstr "Disciplines :" +#: pod/video/templates/videos/video-info.html:137 +msgid "Discipline(s):" +msgstr "Discipline(s) :" -#: pod/video/templates/videos/video-info.html:101 +#: pod/video/templates/videos/video-info.html:148 msgid "Licence:" msgstr "Licence :" -#: pod/video/templates/videos/video-info.html:113 +#: pod/video/templates/videos/video-info.html:160 msgid "Video file(s):" msgstr "Fichiers vidéos :" -#: pod/video/templates/videos/video-info.html:127 +#: pod/video/templates/videos/video-info.html:171 msgid "Audio file:" msgstr "Fichier audio :" -#: pod/video/templates/videos/video-info.html:139 +#: pod/video/templates/videos/video-info.html:183 msgid "Document:" msgstr "Document :" -#: pod/video/templates/videos/video-info.html:155 +#: pod/video/templates/videos/video-info.html:198 #: pod/video/templates/videos/video_edit.html:161 msgid "Embed/Share (Draft Mode)" msgstr "Intégrer/Partager (Mode brouillon)" -#: pod/video/templates/videos/video-info.html:158 +#: pod/video/templates/videos/video-info.html:201 msgid "Social Networks" msgstr "Réseaux sociaux" -#: pod/video/templates/videos/video-info.html:168 +#: pod/video/templates/videos/video-info.html:215 msgid "" "Please note that your video is in draft mode.
The following links " "contain a key allowing access. Anyone with this links can access it." @@ -5093,55 +5097,55 @@ msgstr "" "suivants contiennent une clé permettant l’accès. Toute personne disposant de " "ces liens peut y accéder." -#: pod/video/templates/videos/video-info.html:174 +#: pod/video/templates/videos/video-info.html:222 msgid "Options" msgstr "Options" -#: pod/video/templates/videos/video-info.html:177 +#: pod/video/templates/videos/video-info.html:225 msgid "Autoplay" msgstr "Lecture automatique" -#: pod/video/templates/videos/video-info.html:178 +#: pod/video/templates/videos/video-info.html:226 msgid "Check the box to autoplay the video." msgstr "Cocher cette case pour lancer la lecture automatiquement." -#: pod/video/templates/videos/video-info.html:183 +#: pod/video/templates/videos/video-info.html:231 msgid "Loop" msgstr "Boucle" -#: pod/video/templates/videos/video-info.html:184 +#: pod/video/templates/videos/video-info.html:232 msgid "Check the box to loop the video." msgstr "Cocher cette case pour lire la vidéo en boucle." -#: pod/video/templates/videos/video-info.html:190 +#: pod/video/templates/videos/video-info.html:238 msgid "Start video" msgstr "Début de la vidéo" -#: pod/video/templates/videos/video-info.html:191 +#: pod/video/templates/videos/video-info.html:239 msgid "Start at" msgstr "Démarrer à" -#: pod/video/templates/videos/video-info.html:194 +#: pod/video/templates/videos/video-info.html:242 msgid "Check the box to indicate the beginning of playing desired." msgstr "Cocher la case pour indiquer le début de lecture souhaité." -#: pod/video/templates/videos/video-info.html:199 +#: pod/video/templates/videos/video-info.html:247 msgid "Embed in a web page" msgstr "Intégrer dans une page web" -#: pod/video/templates/videos/video-info.html:201 +#: pod/video/templates/videos/video-info.html:249 msgid "Copy the content of this text box and paste it in the page:" msgstr "Copier le contenu de cette boite de texte et coller le sur la page :" -#: pod/video/templates/videos/video-info.html:206 +#: pod/video/templates/videos/video-info.html:254 msgid "Share the link" msgstr "Partager le lien" -#: pod/video/templates/videos/video-info.html:208 +#: pod/video/templates/videos/video-info.html:256 msgid "Use this link to share the video:" msgstr "Utiliser ce lien pour partager la vidéo :" -#: pod/video/templates/videos/video-info.html:212 +#: pod/video/templates/videos/video-info.html:260 msgid "QR code for this link:" msgstr "QR code pour le lien :" @@ -5400,149 +5404,149 @@ msgstr "" "La vidéo \"%(content_title)s\" a été encodée au format web, et est " "maintenant disponible sur %(site_title)s." -#: pod/video/views.py:237 pod/video/views.py:277 +#: pod/video/views.py:232 pod/video/views.py:272 msgid "You cannot edit this channel." msgstr "Vous ne pouvez éditer cette chaîne." -#: pod/video/views.py:254 pod/video/views.py:729 +#: pod/video/views.py:249 pod/video/views.py:724 msgid "The changes have been saved." msgstr "Les modifications ont été sauvegardées." -#: pod/video/views.py:606 +#: pod/video/views.py:601 msgid "You don't have access to this playlist." msgstr "Vous n'avez pas les droits d'accès à cette liste de lecture." -#: pod/video/views.py:667 +#: pod/video/views.py:662 msgid "You cannot watch this video." msgstr "Vous ne pouvez pas voir cette vidéo." -#: pod/video/views.py:701 +#: pod/video/views.py:696 msgid "You cannot edit this video." msgstr "Vous ne pouvez pas éditer cette vidéo." -#: pod/video/views.py:779 +#: pod/video/views.py:774 msgid "You cannot delete this video." msgstr "Vous ne pouvez pas supprimer cette vidéo." -#: pod/video/views.py:789 +#: pod/video/views.py:784 msgid "The video has been deleted." msgstr "La vidéo a été supprimée." -#: pod/video/views.py:905 +#: pod/video/views.py:900 #, python-format msgid "You cannot %s this note or comment." msgstr "Vous ne pouvez pas %s cette note ou ce commentaire." -#: pod/video/views.py:928 +#: pod/video/views.py:923 msgid "You cannot see this note or comment." msgstr "Vous ne pouvez pas voir cette note ou ce commentaire." -#: pod/video/views.py:1164 pod/video/views.py:1178 pod/video/views.py:1201 +#: pod/video/views.py:1159 pod/video/views.py:1173 pod/video/views.py:1196 msgid "The comment has been saved." msgstr "Le commentaire a été enregistré." -#: pod/video/views.py:1191 pod/video/views.py:1216 +#: pod/video/views.py:1186 pod/video/views.py:1211 msgid "The note has been saved." msgstr "La note a été sauvegardée." -#: pod/video/views.py:1256 +#: pod/video/views.py:1251 msgid "The note has been deleted." msgstr "La note a été supprimée." -#: pod/video/views.py:1264 +#: pod/video/views.py:1259 msgid "The comment has been deleted." msgstr "Le commentaire a été supprimé." -#: pod/video/views.py:1310 pod/video/views.py:1313 pod/video/views.py:1319 +#: pod/video/views.py:1305 pod/video/views.py:1308 pod/video/views.py:1314 msgid "None" msgstr "Aucun" -#: pod/video/views.py:1332 +#: pod/video/views.py:1327 msgid "ID" msgstr "ID" -#: pod/video/views.py:1332 +#: pod/video/views.py:1327 msgid "Status" msgstr "Status" -#: pod/video/views.py:1333 +#: pod/video/views.py:1328 msgid "Parent note id" msgstr "Identifiant de note parent" -#: pod/video/views.py:1333 +#: pod/video/views.py:1328 msgid "Parent comment id" msgstr "ID du commentaire parent" -#: pod/video/views.py:1334 +#: pod/video/views.py:1329 msgid "Created on" msgstr "Créé le" -#: pod/video/views.py:1334 +#: pod/video/views.py:1329 msgid "Modified on" msgstr "Modifié le" -#: pod/video/views.py:1335 +#: pod/video/views.py:1330 msgid "Note timestamp" msgstr "Horodatage de la note" -#: pod/video/views.py:1362 pod/video/views.py:1390 +#: pod/video/views.py:1357 pod/video/views.py:1385 msgid "You cannot access to this view." msgstr "Vous ne pouvez pas accéder à cette vue." -#: pod/video/views.py:1511 +#: pod/video/views.py:1506 msgid "Pod video viewing statistics" msgstr "Statistiques de visualisation des vidéos" -#: pod/video/views.py:1518 +#: pod/video/views.py:1513 #, python-format msgid "Video viewing statistics for %s" msgstr "Statistiques de visualisation de la vidéo %s" -#: pod/video/views.py:1522 +#: pod/video/views.py:1517 #, 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:1526 +#: pod/video/views.py:1521 #, 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:1568 +#: pod/video/views.py:1563 #, 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:1588 +#: pod/video/views.py:1583 #, python-format msgid "The following video does not exist : %s" msgstr "La video suivante n'existe pas : %s" -#: pod/video/views.py:1919 +#: pod/video/views.py:1914 msgid "You do not have rights to delete this comment" msgstr "Vous n'avez pas les droits pour supprimer ce commentaire" -#: pod/video/views.py:2010 pod/video/views.py:2076 +#: pod/video/views.py:2005 pod/video/views.py:2071 msgid "One or many videos already have a category." msgstr "Une ou plusieurs vidéos possèdent déjà une catégorie." -#: pod/video/views.py:2046 pod/video/views.py:2116 +#: pod/video/views.py:2041 pod/video/views.py:2111 msgid "Title field is required" msgstr "Champ de titre est requis" -#: pod/video/views.py:2051 pod/video/views.py:2121 pod/video/views.py:2163 +#: pod/video/views.py:2046 pod/video/views.py:2116 pod/video/views.py:2158 msgid "Method Not Allowed" msgstr "Méthode non autorisée" -#: pod/video/views.py:2093 +#: pod/video/views.py:2088 msgid "Category updated successfully." msgstr "Catégorie mise à jour avec succès." -#: pod/video/views.py:2111 +#: pod/video/views.py:2106 msgid "You do not have rights to edit this category" msgstr "Vous n'avez pas les droits pour éditer cette catégorie" -#: pod/video/views.py:2157 +#: pod/video/views.py:2152 msgid "You do not have rights to delete this category" msgstr "Vous n'avez pas les droits pour supprimer cette catégorie" @@ -5560,19 +5564,25 @@ msgid "Search results" msgstr "Résultats de la recherche" #: pod/video_search/templates/search/search.html:28 -msgid "Remove filters" -msgstr "Retirer les filtres" +msgid "Active filters (click to remove):" +msgstr "Filtres actifs (cliquer pour en retirer) :" + +#: pod/video_search/templates/search/search.html:46 +msgid "Advanced search" +msgstr "Recherche avancée" + +#: pod/video_search/views.py:60 +msgid "Remove this filter" +msgstr "Retirer ce filtre" -#: pod/video_search/templates/search/search.html:61 -msgid "faceting" -msgstr "facettage" +#~ msgid "Contributors:" +#~ msgstr "Contributeurs :" -#: pod/video_search/views.py:57 -msgid "Remove selection" -msgstr "Retirer la sélection" +#~ msgid "faceting" +#~ msgstr "facettage" -#~ msgid "Dutch (Netherlands)" -#~ msgstr "Néerlandais (Pays-Bas)" +#~ msgid "Remove selection" +#~ msgstr "Retirer la sélection" #~ msgid "file" #~ msgstr "fichier" diff --git a/pod/locale/fr/LC_MESSAGES/djangojs.po b/pod/locale/fr/LC_MESSAGES/djangojs.po index a499e668a9..b046ca2775 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: 2021-01-29 15:49+0100\n" +"POT-Creation-Date: 2021-02-23 17:32+0100\n" "PO-Revision-Date: 2021-01-29 15:57+0100\n" "Last-Translator: obado \n" "Language-Team: \n" @@ -464,40 +464,40 @@ msgstr "Réponse" msgid "Answers" msgstr "Réponses" -#: pod/video/static/js/comment-script.js:76 -#: pod/video/static/js/comment-script.js:181 +#: pod/video/static/js/comment-script.js:81 +#: pod/video/static/js/comment-script.js:226 msgid "Delete" msgstr "Supprimer" -#: pod/video/static/js/comment-script.js:87 +#: pod/video/static/js/comment-script.js:94 msgid "Cancel" msgstr "Annuler" -#: pod/video/static/js/comment-script.js:148 +#: pod/video/static/js/comment-script.js:175 msgid "Agree with the comment" msgstr "D'accord avec ce commentaire" -#: pod/video/static/js/comment-script.js:165 +#: pod/video/static/js/comment-script.js:202 msgid "Reply to comment" msgstr "Répondre au commentaire" -#: pod/video/static/js/comment-script.js:165 +#: pod/video/static/js/comment-script.js:205 msgid "Reply" msgstr "Répondre" -#: pod/video/static/js/comment-script.js:178 +#: pod/video/static/js/comment-script.js:223 msgid "Remove this comment" msgstr "Supprimer ce commentaire" -#: pod/video/static/js/comment-script.js:194 +#: pod/video/static/js/comment-script.js:245 msgid "Add a public comment" msgstr "Ajouter un commentaire public" -#: pod/video/static/js/comment-script.js:282 +#: pod/video/static/js/comment-script.js:369 msgid "Show answers" msgstr "Afficher les réponses" -#: pod/video/static/js/comment-script.js:442 +#: pod/video/static/js/comment-script.js:572 msgid "Comment has been deleted successfully." msgstr "Commentaire a été supprimé avec succès." diff --git a/pod/locale/nl/LC_MESSAGES/django.po b/pod/locale/nl/LC_MESSAGES/django.po index 9f0c6de264..21378bec07 100755 --- 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: 2021-02-19 08:39+0000\n" +"POT-Creation-Date: 2021-02-23 16:32+0000\n" "PO-Revision-Date: 2021-01-22 12:27+0100\n" "Last-Translator: obado \n" "Language-Team: \n" @@ -90,7 +90,7 @@ msgid "registered-reader" msgstr "" #: pod/authentication/models.py:68 pod/recorder/models.py:266 -#: pod/video/models.py:1421 pod/video/models.py:1473 pod/video/views.py:1306 +#: pod/video/models.py:1421 pod/video/models.py:1473 pod/video/views.py:1301 msgid "Comment" msgstr "" @@ -161,9 +161,9 @@ msgstr "" #: pod/video/templates/videos/video_note_comments_display.html:148 #: pod/video/templates/videos/video_note_display.html:27 #: pod/video/templates/videos/video_notes.html:80 -#: pod/video/templates/videos/video_notes.html:116 pod/video/views.py:259 -#: pod/video/views.py:742 pod/video/views.py:796 pod/video/views.py:1226 -#: pod/video_search/templates/search/search.html:42 +#: pod/video/templates/videos/video_notes.html:116 pod/video/views.py:254 +#: pod/video/views.py:737 pod/video/views.py:791 pod/video/views.py:1221 +#: pod/video_search/templates/search/search.html:50 msgid "One or more errors have been found in the form." msgstr "" @@ -895,7 +895,7 @@ msgstr "" msgid "End time of the overlay, in seconds." msgstr "" -#: pod/completion/models.py:279 pod/video/views.py:1335 +#: pod/completion/models.py:279 pod/video/views.py:1330 msgid "Content" msgstr "" @@ -1296,10 +1296,14 @@ msgstr "" #: pod/completion/views.py:237 pod/completion/views.py:413 #: pod/completion/views.py:814 pod/podfile/views.py:470 -#: pod/podfile/views.py:520 pod/video/views.py:349 pod/video/views.py:1384 +#: pod/podfile/views.py:520 pod/video/views.py:344 pod/video/views.py:1379 msgid "Please correct errors" msgstr "" +#: pod/custom/settings_local.py:76 +msgid "Dutch (Netherlands)" +msgstr "" + #: pod/enrichment/apps.py:7 msgid "Enrichment version" msgstr "" @@ -1363,7 +1367,7 @@ msgstr "" #: pod/enrichment/models.py:137 #: pod/enrichment/templates/enrichment/list_enrichment.html:11 #: pod/video/forms.py:103 pod/video/models.py:418 pod/video/models.py:473 -#: pod/video/views.py:1332 pod/video_search/templates/search/search.html:77 +#: pod/video/views.py:1327 pod/video_search/templates/search/search.html:87 msgid "Type" msgstr "" @@ -1558,7 +1562,7 @@ msgstr "" #: pod/enrichment/templates/enrichment/video_enrichment.html:75 #: pod/interactive/templates/interactive/video_interactive.html:61 #: pod/interactive/templates/interactive/video_interactive.html:62 -#: pod/video/templates/videos/video-info.html:33 +#: pod/video/templates/videos/video-info.html:36 #: pod/video/templates/videos/video.html:175 #: pod/video/templates/videos/video.html:177 #: pod/video/templates/videos/video.html:179 @@ -1569,7 +1573,7 @@ msgstr "" #: pod/enrichment/templates/enrichment/video_enrichment.html:81 #: pod/interactive/templates/interactive/video_interactive.html:67 #: pod/interactive/templates/interactive/video_interactive.html:68 -#: pod/video/templates/videos/video-info.html:109 +#: pod/video/templates/videos/video-info.html:156 #: pod/video/templates/videos/video.html:184 #: pod/video/templates/videos/video.html:185 msgid "Downloads" @@ -1579,7 +1583,7 @@ msgstr "" #: pod/enrichment/templates/enrichment/video_enrichment.html:87 #: pod/interactive/templates/interactive/video_interactive.html:73 #: pod/interactive/templates/interactive/video_interactive.html:74 -#: pod/video/templates/videos/video-info.html:155 +#: pod/video/templates/videos/video-info.html:198 #: pod/video/templates/videos/video.html:191 #: pod/video/templates/videos/video.html:192 msgid "Embed/Share" @@ -1950,7 +1954,7 @@ msgstr "" #: pod/video/templates/videos/filter_aside.html:78 #: pod/video/templates/videos/video-form.html:31 #: pod/video/templates/videos/video_delete.html:61 -#: pod/video_search/templates/search/search.html:54 +#: pod/video_search/templates/search/search.html:64 msgid "Send" msgstr "" @@ -1963,7 +1967,7 @@ msgid "access map" msgstr "" #: pod/live/templates/live/live.html:132 -#: pod/video/templates/videos/video-script.html:26 +#: pod/video/templates/videos/video-script.html:27 msgid "Please use different browser" msgstr "" @@ -1989,7 +1993,7 @@ msgstr "" msgid "You cannot view this page." msgstr "" -#: pod/live/views.py:91 pod/video/views.py:652 +#: pod/live/views.py:91 pod/video/views.py:647 msgid "The password is incorrect." msgstr "" @@ -2744,9 +2748,9 @@ msgstr "" #: pod/main/templates/aside.html:11 pod/main/templates/aside.html:12 #: pod/main/templates/aside.html:13 -#: pod/video/templates/videos/video-info.html:159 -#: pod/video/templates/videos/video-info.html:160 -#: pod/video/templates/videos/video-info.html:161 +#: pod/video/templates/videos/video-info.html:204 +#: pod/video/templates/videos/video-info.html:205 +#: pod/video/templates/videos/video-info.html:206 msgid "Share on" msgstr "" @@ -2759,7 +2763,7 @@ msgstr "" #: pod/main/templates/aside.html:40 pod/recorder/models.py:184 #: pod/video/forms.py:132 pod/video/models.py:519 #: pod/video/templates/videos/filter_aside.html:78 -#: pod/video_search/templates/search/search.html:89 +#: pod/video_search/templates/search/search.html:99 msgid "Tags" msgstr "" @@ -2885,7 +2889,6 @@ msgstr "" #: pod/video/templates/videos/filter_aside_category.html:24 #: pod/video_search/forms.py:8 pod/video_search/templates/search/search.html:8 #: pod/video_search/templates/search/search.html:17 -#: pod/video_search/templates/search/search.html:38 msgid "Search" msgstr "" @@ -2975,7 +2978,7 @@ msgstr "" #: pod/playlist/models.py:20 #: pod/playlist/templates/playlist/playlist_element_list.html:12 #: pod/podfile/models.py:30 pod/video/admin.py:168 pod/video/models.py:477 -#: pod/video_search/templates/search/search.html:65 +#: pod/video_search/templates/search/search.html:75 msgid "Owner" msgstr "" @@ -3361,7 +3364,7 @@ msgstr "" msgid "Doctorate" msgstr "" -#: pod/recorder/models.py:34 pod/video/models.py:67 pod/video/views.py:164 +#: pod/recorder/models.py:34 pod/video/models.py:67 pod/video/views.py:159 msgid "Other" msgstr "" @@ -3462,7 +3465,7 @@ msgid "Viewing this video will not be possible without this password." msgstr "" #: pod/recorder/models.py:169 pod/video/forms.py:122 pod/video/models.py:504 -#: pod/video_search/templates/search/search.html:140 +#: pod/video_search/templates/search/search.html:150 msgid "University course" msgstr "" @@ -3471,7 +3474,7 @@ msgid "Select an university course as audience target of the content." msgstr "" #: pod/recorder/models.py:174 pod/video/forms.py:129 pod/video/models.py:509 -#: pod/video_search/templates/search/search.html:127 +#: pod/video_search/templates/search/search.html:137 msgid "Main language" msgstr "" @@ -3771,7 +3774,7 @@ msgstr "" msgid "You can send an audio or video file." msgstr "" -#: pod/video/forms.py:91 pod/video/views.py:1644 +#: pod/video/forms.py:91 pod/video/views.py:1639 #, python-format msgid "The following formats are supported: %s" msgstr "" @@ -4077,7 +4080,7 @@ msgid "" msgstr "" #: pod/video/models.py:260 pod/video/models.py:322 -#: pod/video_search/templates/search/search.html:114 +#: pod/video_search/templates/search/search.html:124 msgid "Channel" msgstr "" @@ -4093,7 +4096,7 @@ msgstr "" msgid "Icon" msgstr "" -#: pod/video/models.py:444 pod/video_search/templates/search/search.html:101 +#: pod/video/models.py:444 pod/video_search/templates/search/search.html:111 msgid "Discipline" msgstr "" @@ -4267,7 +4270,7 @@ msgid "Encoding steps" msgstr "" #: pod/video/models.py:1337 pod/video/models.py:1344 pod/video/models.py:1360 -#: pod/video/views.py:1317 +#: pod/video/views.py:1312 msgid "Note" msgstr "" @@ -4413,7 +4416,7 @@ msgstr "" #: pod/video/templates/videos/videos.html:12 #: pod/video/templates/videos/videos.html:19 #: pod/video/templates/videos/videos.html:24 -#: pod/video_search/templates/search/search.html:25 +#: pod/video_search/templates/search/search.html:36 #, python-format msgid "%(counter)s video found" msgid_plural "%(counter)s videos found" @@ -4624,6 +4627,7 @@ msgstr "" #: pod/video/templates/videos/filter_aside.html:53 #: pod/video/templates/videos/filter_aside.html:75 #: pod/video/templates/videos/filter_aside.html:99 +#: pod/video_search/templates/search/search.html:71 msgid "Filter" msgstr "" @@ -4739,148 +4743,148 @@ msgstr "" msgid "No information available" msgstr "" -#: pod/video/templates/videos/video-info.html:36 +#: pod/video/templates/videos/video-info.html:39 msgid "Added by:" msgstr "" -#: pod/video/templates/videos/video-info.html:46 -msgid "Additional owners:" +#: pod/video/templates/videos/video-info.html:52 +msgid "Additional owner(s):" msgstr "" -#: pod/video/templates/videos/video-info.html:59 -msgid "Contributors:" +#: pod/video/templates/videos/video-info.html:70 +msgid "Contributor(s):" msgstr "" -#: pod/video/templates/videos/video-info.html:63 +#: pod/video/templates/videos/video-info.html:76 msgid "send an email" msgstr "" -#: pod/video/templates/videos/video-info.html:68 +#: pod/video/templates/videos/video-info.html:81 msgid "contributor web link" msgstr "" -#: pod/video/templates/videos/video-info.html:78 +#: pod/video/templates/videos/video-info.html:92 msgid "Updated on:" msgstr "" -#: pod/video/templates/videos/video-info.html:79 +#: pod/video/templates/videos/video-info.html:97 msgid "Duration:" msgstr "" -#: pod/video/templates/videos/video-info.html:80 +#: pod/video/templates/videos/video-info.html:103 msgid "Channel:" msgid_plural " Channels:" msgstr[0] "" msgstr[1] "" -#: pod/video/templates/videos/video-info.html:81 -msgid "Number of view:" +#: pod/video/templates/videos/video-info.html:111 +msgid "Number of views:" msgstr "" -#: pod/video/templates/videos/video-info.html:81 +#: pod/video/templates/videos/video-info.html:114 msgid "Show details of view statistics" msgstr "" -#: pod/video/templates/videos/video-info.html:81 +#: pod/video/templates/videos/video-info.html:114 msgid "Show details views" msgstr "" -#: pod/video/templates/videos/video-info.html:85 +#: pod/video/templates/videos/video-info.html:119 msgid "Type:" msgstr "" -#: pod/video/templates/videos/video-info.html:86 +#: pod/video/templates/videos/video-info.html:124 msgid "Main language:" msgstr "" -#: pod/video/templates/videos/video-info.html:88 +#: pod/video/templates/videos/video-info.html:130 msgid "Audience:" msgstr "" -#: pod/video/templates/videos/video-info.html:92 -msgid "Disciplines:" +#: pod/video/templates/videos/video-info.html:137 +msgid "Discipline(s):" msgstr "" -#: pod/video/templates/videos/video-info.html:101 +#: pod/video/templates/videos/video-info.html:148 msgid "Licence:" msgstr "" -#: pod/video/templates/videos/video-info.html:113 +#: pod/video/templates/videos/video-info.html:160 msgid "Video file(s):" msgstr "" -#: pod/video/templates/videos/video-info.html:127 +#: pod/video/templates/videos/video-info.html:171 msgid "Audio file:" msgstr "" -#: pod/video/templates/videos/video-info.html:139 +#: pod/video/templates/videos/video-info.html:183 msgid "Document:" msgstr "" -#: pod/video/templates/videos/video-info.html:155 +#: pod/video/templates/videos/video-info.html:198 #: pod/video/templates/videos/video_edit.html:161 msgid "Embed/Share (Draft Mode)" msgstr "" -#: pod/video/templates/videos/video-info.html:158 +#: pod/video/templates/videos/video-info.html:201 msgid "Social Networks" msgstr "" -#: pod/video/templates/videos/video-info.html:168 +#: pod/video/templates/videos/video-info.html:215 msgid "" "Please note that your video is in draft mode.
The following links " "contain a key allowing access. Anyone with this links can access it." msgstr "" -#: pod/video/templates/videos/video-info.html:174 +#: pod/video/templates/videos/video-info.html:222 msgid "Options" msgstr "" -#: pod/video/templates/videos/video-info.html:177 +#: pod/video/templates/videos/video-info.html:225 msgid "Autoplay" msgstr "" -#: pod/video/templates/videos/video-info.html:178 +#: pod/video/templates/videos/video-info.html:226 msgid "Check the box to autoplay the video." msgstr "" -#: pod/video/templates/videos/video-info.html:183 +#: pod/video/templates/videos/video-info.html:231 msgid "Loop" msgstr "" -#: pod/video/templates/videos/video-info.html:184 +#: pod/video/templates/videos/video-info.html:232 msgid "Check the box to loop the video." msgstr "" -#: pod/video/templates/videos/video-info.html:190 +#: pod/video/templates/videos/video-info.html:238 msgid "Start video" msgstr "" -#: pod/video/templates/videos/video-info.html:191 +#: pod/video/templates/videos/video-info.html:239 msgid "Start at" msgstr "" -#: pod/video/templates/videos/video-info.html:194 +#: pod/video/templates/videos/video-info.html:242 msgid "Check the box to indicate the beginning of playing desired." msgstr "" -#: pod/video/templates/videos/video-info.html:199 +#: pod/video/templates/videos/video-info.html:247 msgid "Embed in a web page" msgstr "" -#: pod/video/templates/videos/video-info.html:201 +#: pod/video/templates/videos/video-info.html:249 msgid "Copy the content of this text box and paste it in the page:" msgstr "" -#: pod/video/templates/videos/video-info.html:206 +#: pod/video/templates/videos/video-info.html:254 msgid "Share the link" msgstr "" -#: pod/video/templates/videos/video-info.html:208 +#: pod/video/templates/videos/video-info.html:256 msgid "Use this link to share the video:" msgstr "" -#: pod/video/templates/videos/video-info.html:212 +#: pod/video/templates/videos/video-info.html:260 msgid "QR code for this link:" msgstr "" @@ -5127,149 +5131,149 @@ msgid "" "available on %(site_title)s." msgstr "" -#: pod/video/views.py:237 pod/video/views.py:277 +#: pod/video/views.py:232 pod/video/views.py:272 msgid "You cannot edit this channel." msgstr "" -#: pod/video/views.py:254 pod/video/views.py:729 +#: pod/video/views.py:249 pod/video/views.py:724 msgid "The changes have been saved." msgstr "" -#: pod/video/views.py:606 +#: pod/video/views.py:601 msgid "You don't have access to this playlist." msgstr "" -#: pod/video/views.py:667 +#: pod/video/views.py:662 msgid "You cannot watch this video." msgstr "" -#: pod/video/views.py:701 +#: pod/video/views.py:696 msgid "You cannot edit this video." msgstr "" -#: pod/video/views.py:779 +#: pod/video/views.py:774 msgid "You cannot delete this video." msgstr "" -#: pod/video/views.py:789 +#: pod/video/views.py:784 msgid "The video has been deleted." msgstr "" -#: pod/video/views.py:905 +#: pod/video/views.py:900 #, python-format msgid "You cannot %s this note or comment." msgstr "" -#: pod/video/views.py:928 +#: pod/video/views.py:923 msgid "You cannot see this note or comment." msgstr "" -#: pod/video/views.py:1164 pod/video/views.py:1178 pod/video/views.py:1201 +#: pod/video/views.py:1159 pod/video/views.py:1173 pod/video/views.py:1196 msgid "The comment has been saved." msgstr "" -#: pod/video/views.py:1191 pod/video/views.py:1216 +#: pod/video/views.py:1186 pod/video/views.py:1211 msgid "The note has been saved." msgstr "" -#: pod/video/views.py:1256 +#: pod/video/views.py:1251 msgid "The note has been deleted." msgstr "" -#: pod/video/views.py:1264 +#: pod/video/views.py:1259 msgid "The comment has been deleted." msgstr "" -#: pod/video/views.py:1310 pod/video/views.py:1313 pod/video/views.py:1319 +#: pod/video/views.py:1305 pod/video/views.py:1308 pod/video/views.py:1314 msgid "None" msgstr "" -#: pod/video/views.py:1332 +#: pod/video/views.py:1327 msgid "ID" msgstr "" -#: pod/video/views.py:1332 +#: pod/video/views.py:1327 msgid "Status" msgstr "" -#: pod/video/views.py:1333 +#: pod/video/views.py:1328 msgid "Parent note id" msgstr "" -#: pod/video/views.py:1333 +#: pod/video/views.py:1328 msgid "Parent comment id" msgstr "" -#: pod/video/views.py:1334 +#: pod/video/views.py:1329 msgid "Created on" msgstr "" -#: pod/video/views.py:1334 +#: pod/video/views.py:1329 msgid "Modified on" msgstr "" -#: pod/video/views.py:1335 +#: pod/video/views.py:1330 msgid "Note timestamp" msgstr "" -#: pod/video/views.py:1362 pod/video/views.py:1390 +#: pod/video/views.py:1357 pod/video/views.py:1385 msgid "You cannot access to this view." msgstr "" -#: pod/video/views.py:1511 +#: pod/video/views.py:1506 msgid "Pod video viewing statistics" msgstr "" -#: pod/video/views.py:1518 +#: pod/video/views.py:1513 #, python-format msgid "Video viewing statistics for %s" msgstr "" -#: pod/video/views.py:1522 +#: pod/video/views.py:1517 #, python-format msgid "Video viewing statistics for the channel %s" msgstr "" -#: pod/video/views.py:1526 +#: pod/video/views.py:1521 #, python-format msgid "Video viewing statistics for the theme %s" msgstr "" -#: pod/video/views.py:1568 +#: pod/video/views.py:1563 #, python-format msgid "You do not have access rights to this video: %s " msgstr "" -#: pod/video/views.py:1588 +#: pod/video/views.py:1583 #, python-format msgid "The following video does not exist : %s" msgstr "" -#: pod/video/views.py:1919 +#: pod/video/views.py:1914 msgid "You do not have rights to delete this comment" msgstr "" -#: pod/video/views.py:2010 pod/video/views.py:2076 +#: pod/video/views.py:2005 pod/video/views.py:2071 msgid "One or many videos already have a category." msgstr "" -#: pod/video/views.py:2046 pod/video/views.py:2116 +#: pod/video/views.py:2041 pod/video/views.py:2111 msgid "Title field is required" msgstr "" -#: pod/video/views.py:2051 pod/video/views.py:2121 pod/video/views.py:2163 +#: pod/video/views.py:2046 pod/video/views.py:2116 pod/video/views.py:2158 msgid "Method Not Allowed" msgstr "" -#: pod/video/views.py:2093 +#: pod/video/views.py:2088 msgid "Category updated successfully." msgstr "" -#: pod/video/views.py:2111 +#: pod/video/views.py:2106 msgid "You do not have rights to edit this category" msgstr "" -#: pod/video/views.py:2157 +#: pod/video/views.py:2152 msgid "You do not have rights to delete this category" msgstr "" @@ -5287,13 +5291,13 @@ msgid "Search results" msgstr "" #: pod/video_search/templates/search/search.html:28 -msgid "Remove filters" +msgid "Active filters (click to remove):" msgstr "" -#: pod/video_search/templates/search/search.html:61 -msgid "faceting" +#: pod/video_search/templates/search/search.html:46 +msgid "Advanced search" msgstr "" -#: pod/video_search/views.py:57 -msgid "Remove selection" +#: pod/video_search/views.py:60 +msgid "Remove this filter" msgstr "" diff --git a/pod/locale/nl/LC_MESSAGES/djangojs.po b/pod/locale/nl/LC_MESSAGES/djangojs.po index ce4fde9b06..8bd280b083 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: 2021-01-29 15:49+0100\n" +"POT-Creation-Date: 2021-02-23 17:32+0100\n" "PO-Revision-Date: 2021-01-22 12:27+0100\n" "Last-Translator: obado \n" "Language-Team: \n" @@ -454,40 +454,40 @@ msgstr "" msgid "Answers" msgstr "" -#: pod/video/static/js/comment-script.js:76 -#: pod/video/static/js/comment-script.js:181 +#: pod/video/static/js/comment-script.js:81 +#: pod/video/static/js/comment-script.js:226 msgid "Delete" msgstr "" -#: pod/video/static/js/comment-script.js:87 +#: pod/video/static/js/comment-script.js:94 msgid "Cancel" msgstr "" -#: pod/video/static/js/comment-script.js:148 +#: pod/video/static/js/comment-script.js:175 msgid "Agree with the comment" msgstr "" -#: pod/video/static/js/comment-script.js:165 +#: pod/video/static/js/comment-script.js:202 msgid "Reply to comment" msgstr "" -#: pod/video/static/js/comment-script.js:165 +#: pod/video/static/js/comment-script.js:205 msgid "Reply" msgstr "" -#: pod/video/static/js/comment-script.js:178 +#: pod/video/static/js/comment-script.js:223 msgid "Remove this comment" msgstr "" -#: pod/video/static/js/comment-script.js:194 +#: pod/video/static/js/comment-script.js:245 msgid "Add a public comment" msgstr "" -#: pod/video/static/js/comment-script.js:282 +#: pod/video/static/js/comment-script.js:369 msgid "Show answers" msgstr "" -#: pod/video/static/js/comment-script.js:442 +#: pod/video/static/js/comment-script.js:572 msgid "Comment has been deleted successfully." msgstr "" diff --git a/pod/main/static/css/pod.css b/pod/main/static/css/pod.css index e452d2af88..c5970aa95a 100755 --- a/pod/main/static/css/pod.css +++ b/pod/main/static/css/pod.css @@ -1,4 +1,6 @@ -.submit-row a.deletelink { +/* Esup-Pod main CSS */ + +.submit-row a.deletelink{ height: 35px; } @@ -7,20 +9,19 @@ height:auto; } -tr ,.rowl{ +tr, .rowl{ display: table-row !important; } -body[data-admin-utc-offset] -{ +body[data-admin-utc-offset]{ padding-top: 0; } -body { +body{ padding-top: 3.5rem; } -.jumbotron { - padding: 1rem 2rem; +.jumbotron{ + padding: 1rem 2rem; } h1{ font-size: 2rem; @@ -43,10 +44,24 @@ label { } /*** video ***/ -#myTabContent #info p { +#video-meta{ + word-wrap: break-word; +} +#info p { margin-top: .5rem; margin-bottom: .5rem; } +.meta-title{ + font-weight: bold; + font-size: 1rem; + margin-bottom: 0; + margin-top: .5em; +} +.tab-title{ + font-size: 1.4rem; + padding-bottom: 2px; + border-bottom: 1px solid var(--primary2); +} #share legend{ /* align text with feather-icon */ line-height: 1em; @@ -67,7 +82,7 @@ label { color: white !important; }*/ .btn-lang{ - padding: 0.2rem 0.25rem; + padding: .2rem .25rem; background: transparent; width: 100%; text-align: left; @@ -79,7 +94,7 @@ label { position: relative; } .navbar-toggler{ - padding: 0.5rem; + padding: .5rem; line-height: inherit; font-size: 1rem; } @@ -94,12 +109,10 @@ label { width: 40px; /*color:#b03c7e;*/ } - .modal-title{ display: flex; align-items: center; } - /*.modal-pod-full { max-width: 90%; }*/ @@ -108,7 +121,7 @@ label { } .title-chaine{ - margin-right: 0.5rem; + margin-right: .5rem; font-weight: 600; } #listeChaines{ @@ -138,12 +151,12 @@ label { border: none; } /*** modif taille logo ***/ -@media (max-width: 576px ){ +@media (max-width: 576px){ .navbar-brand img{ height: 35px; } .navbar-brand{ - font-size: 0.9rem; + font-size: .9rem; } } @media (max-width: 992px){ @@ -160,8 +173,8 @@ label { } .navbar-items-pod{ position: absolute; - top:53px; - left:0; + top: 53px; + left: 0; padding: 1rem; width: 100%; } @@ -182,41 +195,40 @@ label { color: white; } #s{ - width:1px; - border-radius:0; - box-shadow:none; + width: 1px; + border-radius: 0; + box-shadow: none; outline: none; - padding:0; - margin:0; - border:0; + padding: 0; + margin: 0; + border: 0; background-color: transparent; - opacity:0; + opacity: 0; position: absolute; } #s:focus{ - width:100%; - opacity:1; + width: 100%; + opacity: 1; display: inline-block !important; position: absolute; /*background: #b03c7e !important;*/ - padding: 0.5rem 1rem; + padding: .5rem 1rem; left: 0; - top:0; + top: 0; z-index: 99; - color:white !important; + color: white !important; height: 74px; } .navbar label{ padding-left: 1px; - display:inline-block; - margin-top:0.3em; - color:rgba(218,208,190,1); - text-shadow:0 0 0.1em rgba(60,60,60,0.3); + display: inline-block; + margin-top: .3em; + color: rgba(218,208,190,1); + text-shadow: 0 0 .1em rgba(60,60,60,.3); position: relative; - left:0.1em; + left: .1em; cursor:pointer; } - } /*** end MQueries **/ @@ -229,7 +241,7 @@ label { width: 3rem; } .nav-link{ - padding: 0.25rem 0.5rem; + padding: .25rem .5rem; } button.nav-link{ background: none; @@ -237,23 +249,32 @@ button.nav-link{ cursor: pointer; } +.remove-link:before { + content: '×'; + color: transparent; + margin-right: 2px; +} +.remove-link:hover:before{ + color: var(--danger); +} + /*** CARD ***/ .infinite-item .card-body { - padding: 0.9rem; + padding: .9rem; height: 3.5rem; overflow: hidden; } .infinite-item .card-header .octicon { - height:0.9rem; - margin:0.1rem; + height: .9rem; + margin: .1rem; } #videos_list .card-header, .playlist-videos .card-header { - position:absolute; - width:100%; - background: rgba(0, 0, 0, 0.6); - padding: 0 0.25rem; - z-index: 9; + position:absolute; + width:100%; + background: rgba(0, 0, 0, .6); + padding: 0 .25rem; + z-index: 9; } #videos_list .card-header .text-muted { color:white !important; @@ -278,9 +299,9 @@ div.card a img { transition:transform .5s ease, -webkit-transform .5s ease } div.card a:hover>img { - -webkit-transform:scale(1.1); - transform:scale(1.1); - z-index:0; + -webkit-transform: scale(1.1); + transform: scale(1.1); + z-index: 0; } .card-footer-pod { position: absolute; @@ -288,13 +309,18 @@ div.card a:hover>img { right: 2px; /*width: 100%; text-align: center;*/ - border:none; + border: none; /*background: rgba(220,220,220);*/ /*height: 1rem;*/ } .card-footer .feather, .card-header .feather{ height: 1rem; } +h2 .feather{ + width: 1em; + height: 1em; +} + /* menu channels */ .dropdown-submenu > .dropdown-menu { top: 0; @@ -350,7 +376,7 @@ div.card a:hover>img { } /** video form **/ .required { - color:red; + color: red; font-size: 1.3rem; } /*.form-group-required { @@ -361,13 +387,13 @@ div.card a:hover>img { background-color: rgba(201, 76, 76, 0.3); } #base-message-alert, #formalertdiv{ - position:fixed; - top:50%; + position: fixed; + top: 50%; text-align: center; - margin:0 auto; + margin: 0 auto; left: 50%; transform: translate(-50%, 0); - z-index:1000; + z-index: 1000; } /** channel form **/ @@ -375,7 +401,7 @@ div.card a:hover>img { width: 100% !important; } #channel_form .selector select, #enrichment_group_form .selector select { - width:100% !important; + width: 100% !important; } #channel_form .selector-available, #channel_form .selector-chosen, #enrichment_group_form .selector-available, #enrichment_group_form .selector-chosen { width: 47% !important; @@ -396,12 +422,12 @@ div.card a:hover>img { } @media screen and (min-width:768px){ .card-img-top { - max-height:184.13px; + max-height: 184.13px; } } @media screen and (min-width:992px){ .card-img-top { - max-height:195.36px; + max-height: 195.36px; } .flex-2{ flex: 2; @@ -409,17 +435,17 @@ div.card a:hover>img { } /*** footer **/ footer{ - color:#aaa; + color: #aaa; } footer a, footer a:hover{ color: white; } .footer_links{ - list-style:none; + list-style: none; } .footer_links>li:before{ - margin-right:.5em; + margin-right: .5em; content: ">"; font-weight: bold; } @@ -460,5 +486,5 @@ input.select2-input{ z-index: 1; } -#viewers-ul{height:200px;list-style-type: none;padding-left: 0; } -#viewers-ul{overflow:hidden; overflow-y:scroll;} +#viewers-ul{height: 200px;list-style-type: none;padding-left: 0;} +#viewers-ul{overflow: hidden; overflow-y: scroll;} diff --git a/pod/main/templates/base.html b/pod/main/templates/base.html index b9cde31166..b43a4953f4 100644 --- a/pod/main/templates/base.html +++ b/pod/main/templates/base.html @@ -81,7 +81,7 @@
-
+
{% block page_content %} @@ -92,7 +92,7 @@ {% if request.path == "/" %} {% include "videos/last_videos.html" %} {% endif %} -
+
From a9f88a0089d29adedbd934a93df9f77306325aa2 Mon Sep 17 00:00:00 2001 From: Olivier Bado Date: Thu, 25 Feb 2021 14:24:45 +0100 Subject: [PATCH 026/261] [JS] Allow anchor links to automatically load tabs in video metadata (i.e http://pod_url#share will directly open the "share" tab) --- pod/main/static/css/pod.css | 2 +- pod/video/templates/videos/video.html | 96 ++++++++++--------- pod/video_search/templates/search/search.html | 10 +- 3 files changed, 57 insertions(+), 51 deletions(-) diff --git a/pod/main/static/css/pod.css b/pod/main/static/css/pod.css index c5970aa95a..3f55b60740 100755 --- a/pod/main/static/css/pod.css +++ b/pod/main/static/css/pod.css @@ -36,7 +36,7 @@ label { background: #f8f9fa; } .list-group-item{ - padding:.25rem 1.25rem; + padding: .25rem 1.25rem; } .container-pod{ diff --git a/pod/video/templates/videos/video.html b/pod/video/templates/videos/video.html index 5ede401f46..c2ab478f0f 100644 --- a/pod/video/templates/videos/video.html +++ b/pod/video/templates/videos/video.html @@ -50,9 +50,9 @@ {% endblock page_extra_head %} @@ -136,28 +136,25 @@

{{theme.title}}

{% block video-element %} {% if form %} - -{% include 'videos/video-form.html' %} - + {% include 'videos/video-form.html' %} {% else %} + {% if playlist %} + {% include 'playlist/playlist_player.html' with playlist=playlist %} + {% endif %} -{% if playlist %} - {% include 'playlist/playlist_player.html' with playlist=playlist %} -{% endif %} + {% include 'videos/video-element.html' %} -{% include 'videos/video-element.html' %} - -

-{% if video.licence %} {% include "videos/video_licencebox.html" %}{% endif %} {{video.title|capfirst}} -{% if video.date_evt %}[{{ video.date_evt }}]{% endif %} - +

+ {% if video.licence %} {% include "videos/video_licencebox.html" %}{% endif %} {{video.title|capfirst}} + {% if video.date_evt %}[{{ video.date_evt }}]{% endif %} + - -

+ +

-{% if video.chapter_set.all %} - -{%endif%} + {% if video.chapter_set.all %} + + {%endif%}
Retrouvez toute la documentation (installation, paramétrage etc.) en suivant ce lien : [Documentation technique](https://www.esup-portail.org/wiki/display/ES/esup-pod "Documentation") - | | Ministère de lʼEnseignement supérieur, de la Recherche et de lʼInnovation + | | Ministère de lʼEnseignement supérieur, de la Recherche et de lʼInnovation :-----:|:-----:|:----: diff --git a/docs/index.md b/docs/index.md index dd8cd5b3fc..0f80fe6c44 100644 --- a/docs/index.md +++ b/docs/index.md @@ -3,5 +3,5 @@ ## Retrouvez toute la documentation à cette adresse : https://www.esup-portail.org/wiki/display/ES/esup-pod -[](https://www.univ-lille.fr "Université de Lille") | [](https://www.esup-portail.org "Esup Portail") | [ Ministère de lʼEnseignement supérieur, de la Recherche et de lʼInnovation](http://www.enseignementsup-recherche.gouv.fr "Ministère de lʼEnseignement supérieur, de la Recherche et de lʼInnovation") +[](https://www.univ-lille.fr "Université de Lille") | [](https://www.esup-portail.org "Esup Portail") | [ Ministère de lʼEnseignement supérieur, de la Recherche et de lʼInnovation](http://www.enseignementsup-recherche.gouv.fr "Ministère de lʼEnseignement supérieur, de la Recherche et de lʼInnovation") :-----:|:-----:|:----: diff --git a/pod/bbb/templates/bbb/card.html b/pod/bbb/templates/bbb/card.html index 6000a8a900..6b0b0f1313 100644 --- a/pod/bbb/templates/bbb/card.html +++ b/pod/bbb/templates/bbb/card.html @@ -24,7 +24,7 @@
diff --git a/pod/bbb/templates/bbb/list_meeting.html b/pod/bbb/templates/bbb/list_meeting.html index 994efd0918..dcecae1166 100644 --- a/pod/bbb/templates/bbb/list_meeting.html +++ b/pod/bbb/templates/bbb/list_meeting.html @@ -37,7 +37,7 @@
+ + {% trans "Please note: this page refreshes automatically every 30 seconds." %} {% endblock page_content %} From e772e76572a34d42dbbcc2de967880db391d3afd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Bonavent?= Date: Fri, 5 Mar 2021 15:24:08 +0100 Subject: [PATCH 042/261] Minor modification for this template --- pod/bbb/templates/bbb/publish_meeting.html | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pod/bbb/templates/bbb/publish_meeting.html b/pod/bbb/templates/bbb/publish_meeting.html index 0eb92551e7..a9e35a1956 100644 --- a/pod/bbb/templates/bbb/publish_meeting.html +++ b/pod/bbb/templates/bbb/publish_meeting.html @@ -14,7 +14,12 @@ {% endblock page_extra_head %} {% block breadcrumbs %}{{ block.super }} - + + {% endblock %} From a255d3bc478b17a0a912acb73e8140bac597811f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Bonavent?= Date: Fri, 5 Mar 2021 15:24:08 +0100 Subject: [PATCH 043/261] Add tests for the new BBB livestream model --- pod/bbb/tests/test_models.py | 130 ++++++++++++++++++++++++++--------- 1 file changed, 96 insertions(+), 34 deletions(-) diff --git a/pod/bbb/tests/test_models.py b/pod/bbb/tests/test_models.py index 2924805abb..f023f6b07f 100644 --- a/pod/bbb/tests/test_models.py +++ b/pod/bbb/tests/test_models.py @@ -2,7 +2,7 @@ from django.test import TestCase from django.contrib.auth.models import User from django.utils import timezone -from ..models import Meeting, User as BBBUser +from ..models import Meeting, Attendee, Livestream class MeetingTestCase(TestCase): @@ -68,7 +68,7 @@ def test_delete_object(self): " ---> test_delete_object of MeetingTestCase : OK !") -class BBBUserTestCase(TestCase): +class AttendeeTestCase(TestCase): fixtures = ['initial_data.json', ] def setUp(self): @@ -77,56 +77,118 @@ def setUp(self): meeting_name="Session BBB1", encoding_step=0) - BBBUser.objects.create(id=1, full_name="John Doe", - role="MODERATOR", - meeting=meeting1) + Attendee.objects.create(id=1, full_name="John Doe", + role="MODERATOR", + meeting=meeting1) User.objects.create(username="pod") userJaneDoe = User.objects.create(username="pod2") - BBBUser.objects.create(id=2, full_name="Jane Doe", - role="MODERATOR", - username="pod2", - meeting=meeting1, - user=userJaneDoe) + Attendee.objects.create(id=2, full_name="Jane Doe", + role="MODERATOR", + username="pod2", + meeting=meeting1, + user=userJaneDoe) - print(" ---> SetUp of BBBUserTestCase : OK !") + print(" ---> SetUp of AttendeeTestCase : OK !") # Test attributes def test_attributes(self): - bbbUser = BBBUser.objects.get(id=1) + attendee = Attendee.objects.get(id=1) meeting = Meeting.objects.get(id=1) - self.assertEqual(bbbUser.full_name, "John Doe") - self.assertEqual(bbbUser.role, "MODERATOR") - self.assertEqual(bbbUser.meeting, meeting) + self.assertEqual(attendee.full_name, "John Doe") + self.assertEqual(attendee.role, "MODERATOR") + self.assertEqual(attendee.meeting, meeting) userJaneDoe = User.objects.get(username="pod2") - bbbUser2 = BBBUser.objects.get(id=2) - self.assertEqual(bbbUser2.full_name, "Jane Doe") - self.assertEqual(bbbUser2.role, "MODERATOR") - self.assertEqual(bbbUser2.meeting, meeting) - self.assertEqual(bbbUser2.username, "pod2") - self.assertEqual(bbbUser2.user, userJaneDoe) + attendee2 = Attendee.objects.get(id=2) + self.assertEqual(attendee2.full_name, "Jane Doe") + self.assertEqual(attendee2.role, "MODERATOR") + self.assertEqual(attendee2.meeting, meeting) + self.assertEqual(attendee2.username, "pod2") + self.assertEqual(attendee2.user, userJaneDoe) print( - " ---> test_attributs of BBBUserTestCase : OK !") + " ---> test_attributs of AttendeeTestCase : OK !") # Test update attributes def test_update_attributes(self): - bbbUser = BBBUser.objects.get(id=1) + attendee = Attendee.objects.get(id=1) userJohnDoe = User.objects.get(username="pod") - bbbUser.username = "pod" - bbbUser.user = userJohnDoe - bbbUser.save() - self.assertEqual(bbbUser.username, "pod") - self.assertEqual(bbbUser.user, userJohnDoe) + attendee.username = "pod" + attendee.user = userJohnDoe + attendee.save() + self.assertEqual(attendee.username, "pod") + self.assertEqual(attendee.user, userJohnDoe) print( - " ---> test_update_attributes of BBBUserTestCase : OK !") + " ---> test_update_attributes of AttendeeTestCase : OK !") # Test delete object def test_delete_object(self): - BBBUser.objects.filter(id=1).delete() - self.assertEquals(BBBUser.objects.all().count(), 1) - BBBUser.objects.filter(id=2).delete() - self.assertEquals(BBBUser.objects.all().count(), 0) + Attendee.objects.filter(id=1).delete() + self.assertEquals(Attendee.objects.all().count(), 1) + Attendee.objects.filter(id=2).delete() + self.assertEquals(Attendee.objects.all().count(), 0) print( - " ---> test_delete_object of BBBUserTestCase : OK !") + " ---> test_delete_object of AttendeeTestCase : OK !") + + +class LivestreamTestCase(TestCase): + fixtures = ['initial_data.json', ] + + def setUp(self): + meeting1 = Meeting.objects.create(id=1, meeting_id="id1", + internal_meeting_id="internalid1", + meeting_name="Session BBB1", + encoding_step=0) + + user1 = User.objects.create(username="pod") + + Livestream.objects.create(id=1, + start_date=timezone.now(), + meeting=meeting1, + user=user1) + + print(" ---> SetUp of LivestreamTestCase : OK !") + + # Test attributes + def test_attributes(self): + meeting = Meeting.objects.get(id=1) + user = User.objects.get(username="pod") + livestream = Livestream.objects.get(id=1) + self.assertEqual(livestream.status, 0) + self.assertEqual(livestream.meeting, meeting) + self.assertEqual(livestream.user, user) + date = timezone.now() + self.assertEqual(livestream.start_date.year, date.year) + self.assertEqual(livestream.start_date.month, date.month) + self.assertEqual(livestream.start_date.day, date.day) + + print( + " ---> test_attributs of LivestreamTestCase : OK !") + + # Test update attributes + def test_update_attributes(self): + livestream = Livestream.objects.get(id=1) + livestream.status = 1 + livestream.download_meeting = 1 + livestream.enable_chat = 1 + livestream.is_restricted = 1 + livestream.redis_hostname = "localhost" + livestream.redis_port = 6379 + livestream.broadcaster_id = 1 + livestream.save() + self.assertEqual(livestream.status, 1) + self.assertEqual(livestream.download_meeting, 1) + self.assertEqual(livestream.redis_hostname, "localhost") + self.assertEqual(livestream.redis_port, 6379) + self.assertEqual(livestream.broadcaster_id, 1) + print( + " ---> test_update_attributes of LivestreamTestCase : OK !") + + # Test delete object + def test_delete_object(self): + Livestream.objects.filter(id=1).delete() + self.assertEquals(Livestream.objects.all().count(), 0) + + print( + " ---> test_delete_object of LivestreamTestCase : OK !") From aa4b94dd5891460d7197a37378d60769e4ada42c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Bonavent?= Date: Fri, 5 Mar 2021 15:24:08 +0100 Subject: [PATCH 044/261] Add tests for the new BBB livestream views --- pod/bbb/tests/test_views.py | 76 +++++++++++++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 8 deletions(-) diff --git a/pod/bbb/tests/test_views.py b/pod/bbb/tests/test_views.py index c837ddfccb..d688602872 100644 --- a/pod/bbb/tests/test_views.py +++ b/pod/bbb/tests/test_views.py @@ -6,10 +6,11 @@ from django.test import Client from django.contrib.auth.models import User from django.core.exceptions import PermissionDenied -from ..models import Meeting, User as BBBUser +from ..models import Meeting, Attendee, Livestream +from django.utils import timezone -class meetingViewsTestCase(TestCase): +class MeetingViewsTestCase(TestCase): fixtures = ['initial_data.json', ] def setUp(self): @@ -20,12 +21,12 @@ def setUp(self): recording_available=True, encoding_step=0) userJohnDoe = User.objects.create(username="pod") - BBBUser.objects.create(id=1, full_name="John Doe", - role="MODERATOR", - username="pod", - meeting=meeting1, - user=userJohnDoe) - print(" ---> SetUp of meetingViewsTestCase : OK !") + Attendee.objects.create(id=1, full_name="John Doe", + role="MODERATOR", + username="pod", + meeting=meeting1, + user=userJohnDoe) + print(" ---> SetUp of MeetingViewsTestCase : OK !") def test_list_meeting(self): self.client = Client() @@ -61,3 +62,62 @@ def test_publish_meeting(self): self.assertEqual(response.status_code, 301) print( " ---> test_publish_meeting of MeetingViewsTestCase : OK !") + + +class LivestreamViewsTestCase(TestCase): + fixtures = ['initial_data.json', ] + + def setUp(self): + meeting1 = Meeting.objects.create(id=1, meeting_id="id1", + internal_meeting_id="internalid1", + meeting_name="Session BBB1", + session_date=timezone.now(), + encoding_step=0) + userJohnDoe = User.objects.create(username="john.doe") + Attendee.objects.create(id=1, full_name="John Doe", + role="MODERATOR", + username="john.doe", + meeting=meeting1, + user=userJohnDoe) + + Livestream.objects.create(id=1, + start_date=timezone.now(), + meeting=meeting1, + status=0, + user=userJohnDoe) + print(" ---> SetUp of LivestreamViewsTestCase : OK !") + + def test_live_list_meeting(self): + self.client = Client() + response = self.client.get("/bbb/live_list_meeting/") + self.assertRaises(PermissionDenied) + + self.user = User.objects.get(username="john.doe") + self.user.is_staff = True + self.user.save() + + self.client.force_login(self.user) + response = self.client.get("/bbb/live_list_meeting/") + self.assertTrue(b"Session BBB1" in response.content) + self.assertEqual(response.status_code, 200) + + print( + " ---> test_live_list_meeting of LivestreamViewsTestCase : OK !") + + def test_live_publish_meeting(self): + self.client = Client() + response = self.client.get("/bbb/live_publish_meeting/1") + self.assertRaises(PermissionDenied) + + self.user = User.objects.get(username="john.doe") + self.user.is_staff = True + self.user.save() + + response = self.client.post("/bbb/live_publish_meeting/1") + # Possible status : 200 or 301 + if response.status_code == 200: + self.assertEqual(response.status_code, 200) + else: + self.assertEqual(response.status_code, 301) + print( + " ---> test_live_publish_meeting of LivestreamViewsTestCase:OK!") From f6ecce05ed4b8aa05c651dac01c0cf8785ffdd99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Bonavent?= Date: Fri, 5 Mar 2021 15:24:08 +0100 Subject: [PATCH 045/261] Add URLs for livestream views --- pod/bbb/urls.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pod/bbb/urls.py b/pod/bbb/urls.py index 68e7f3f84c..4ab7ac70ba 100644 --- a/pod/bbb/urls.py +++ b/pod/bbb/urls.py @@ -1,6 +1,6 @@ from django.conf.urls import url -from .views import list_meeting -from .views import publish_meeting +from .views import list_meeting, publish_meeting, live_list_meeting +from .views import live_publish_meeting, live_publish_chat app_name = "bbb" @@ -8,4 +8,9 @@ url(r'^list_meeting/$', list_meeting, name='list_meeting'), url(r'^publish_meeting/(?P[\d]+)/$', publish_meeting, name='publish_meeting'), + url(r'^live_list_meeting/$', live_list_meeting, name='live_list_meeting'), + url(r'^live_publish_meeting/(?P[\d]+)/$', live_publish_meeting, + name='live_publish_meeting'), + url(r'^live_publish_chat/(?P[\d]+)/$', live_publish_chat, + name='live_publish_chat'), ] From 737756a8d479458864f09764e97a58a6a0673002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Bonavent?= Date: Fri, 5 Mar 2021 15:24:08 +0100 Subject: [PATCH 046/261] Views for BBB livestreams --- pod/bbb/views.py | 173 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 169 insertions(+), 4 deletions(-) diff --git a/pod/bbb/views.py b/pod/bbb/views.py index 78703f2ba8..a5131ff9d9 100644 --- a/pod/bbb/views.py +++ b/pod/bbb/views.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.contrib.auth.decorators import login_required from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage from django.shortcuts import render from django.conf import settings @@ -12,11 +11,18 @@ from django.views.decorators.csrf import csrf_protect from django.utils.translation import ugettext_lazy as _ from pod.bbb.models import Meeting -from .forms import MeetingForm +from .models import Livestream +from .forms import MeetingForm, LivestreamForm from django.contrib import messages from django.shortcuts import get_object_or_404 +from django.utils import timezone +from django.http import JsonResponse +from django.contrib.auth.decorators import login_required, user_passes_test +import redis USE_BBB = getattr(settings, 'USE_BBB', False) +USE_BBB_LIVE = getattr(settings, 'USE_BBB_LIVE', False) +BBB_NUMBER_MAX_LIVES = getattr(settings, 'BBB_NUMBER_MAX_LIVES', 1) @csrf_protect @@ -25,7 +31,7 @@ def list_meeting(request): # Get meetings list, which recordings are available, ordered by date meetings_list = Meeting.objects.\ - filter(user__user_id=request.user.id, recording_available=True) + filter(attendee__user_id=request.user.id, recording_available=True) meetings_list = meetings_list.order_by('-session_date') # print(str(meetings_list.query)) @@ -77,7 +83,7 @@ def publish_meeting(request, id=None): # Check security : a normal user can publish only a meeting # where he was moderator meetings_list = Meeting.objects.\ - filter(user__user_id=request.user.id, id=id) + filter(attendee__user_id=request.user.id, id=id) if not meetings_list and not request.user.is_superuser: messages.add_message( request, messages.ERROR, @@ -113,3 +119,162 @@ def publish_meeting(request, id=None): 'record': record, 'form': form} ) + + +@csrf_protect +@login_required(redirect_field_name='referrer') +@staff_member_required(redirect_field_name='referrer') +def live_list_meeting(request): + # Get meetings list in progress + dateSince10Min = timezone.now() - timezone.timedelta(minutes=10) + meetings_list = Meeting.objects.\ + filter(attendee__user_id=request.user.id, + last_date_in_progress__gte=dateSince10Min) + meetings_list = meetings_list.order_by('-session_date') + # print(str(meetings_list.query)) + + meetings_list = check_meetings_have_live_in_progress(meetings_list, + request) + + # Get number of lives in progress + lives_in_progress = Livestream.objects.filter(status=1) + if len(lives_in_progress) >= BBB_NUMBER_MAX_LIVES: + max_limit_reached = True + else: + max_limit_reached = False + + 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(meetings_list, 12) + try: + records = paginator.page(page) + except PageNotAnInteger: + records = paginator.page(1) + except EmptyPage: + records = paginator.page(paginator.num_pages) + + if request.is_ajax(): + return render( + request, 'bbb/live_record_list.html', + {'records': records, 'full_path': full_path, + 'max_limit_reached': max_limit_reached}) + + return render(request, 'bbb/live_list_meeting.html', { + 'records': records, 'full_path': full_path, + 'max_limit_reached': max_limit_reached + }) + + +def check_meetings_have_live_in_progress(meetings_list, request): + # Check if these meetings have a live in progress + dateToday = timezone.now() - timezone.timedelta(days=1) + if len(meetings_list) > 0: + for meeting in meetings_list: + # Get the live object that corresponds to this meeting in progress + lives_list = Livestream.objects.\ + filter(user_id=request.user.id, start_date__gte=dateToday, + meeting_id=meeting.id) + if len(lives_list) > 0: + # Use case : only 1 live for a meeting + for live in lives_list: + # Add the information directly on the meeting + # on a specific property live + meeting.live = live + return meetings_list + + +@csrf_protect +@staff_member_required(redirect_field_name='referrer') +def live_publish_meeting(request, id=None): + # Allows you to create a live streaming from a BigBlueButton presentation + + record = get_object_or_404(Meeting, id=id) + + initial = { + 'meeting': record, + 'status': 0, + 'end_date': None, + 'server': None + } + + form = LivestreamForm(request, initial=initial) + + # Check security : a normal user can publish only a meeting + # where he was moderator + meetings_list = Meeting.objects.\ + filter(attendee__user_id=request.user.id, id=id) + if not meetings_list and not request.user.is_superuser: + messages.add_message( + request, messages.ERROR, + _(u'You aren\'t the moderator of this BigBlueButton session.')) + raise PermissionDenied + + if request.method == "POST": + form = LivestreamForm(request, request.POST) + if form.is_valid(): + live = form.save(commit=False) + live.meeting = record + live.user = request.user + live.save() + messages.add_message( + request, messages.INFO, + _(u'The BigBlueButton live has been performed.')) + return redirect( + reverse('bbb:live_list_meeting') + ) + else: + messages.add_message( + request, messages.ERROR, + _(u'One or more errors have been found in the form.')) + + return render(request, 'bbb/live_publish_meeting.html', { + 'record': record, + 'form': form} + ) + + +def live_publish_chat_if_authenticated(user): + if user.__str__() == "AnonymousUser": + return False + return True + + +@csrf_protect +@user_passes_test(live_publish_chat_if_authenticated, + redirect_field_name="referrer") +def live_publish_chat(request, id=None): + # Allows an authenticated user to send chat question to BBB + who_sent = "(%s %s) " % (request.user.first_name, request.user.last_name) + message = request.GET.get('message', None) + + livestreams_list = Livestream.objects.filter(broadcaster_id=id) + + data = { + 'message_return': 'error_no_broadcaster_found', + 'is_sent': False + } + if len(livestreams_list) > 0: + for livestream in livestreams_list: + try: + # Publish on Redis + r = redis.Redis(host=livestream.redis_hostname, + port=str(livestream.redis_port), + db=0) + r.publish(livestream.redis_channel, who_sent + message) + + data = { + 'message_return': 'message_sent', + 'is_sent': True + } + except Exception: + data = { + 'message_return': 'error_no_connection', + 'is_sent': False + } + + return JsonResponse(data) From fe63f7d67218a8834885442b0b5bc8c97f682174 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Bonavent?= Date: Fri, 5 Mar 2021 15:24:08 +0100 Subject: [PATCH 047/261] Add new settings: USE_BBB_LIVE, USE_BBB_LIVE_DOWNLOADING, BBB_NUMBER_MAX_LIVES --- pod/custom/settings_local.py.example | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/pod/custom/settings_local.py.example b/pod/custom/settings_local.py.example index 12bcc71bab..3ca5b082f4 100644 --- a/pod/custom/settings_local.py.example +++ b/pod/custom/settings_local.py.example @@ -1104,6 +1104,21 @@ BBB_USERNAME_FORMAT = 'first_name last_name' """ BBB_NUMBER_DAYS_BEFORE_DELETE = 0 +""" +# Utilisation du système de diffusion de Webinaires en lien avec BigBlueButton +""" +USE_BBB_LIVE = False + +""" +# Autoriser les utilisateurs à enregistrer leur direct BigBlueButton directement dans Mes vidéos +""" +USE_BBB_LIVE_DOWNLOADING = False + +""" +# Nombre maximum de directs BBB simultanés gérés par le système +""" +BBB_NUMBER_MAX_LIVES = 4 + """ # # Permet d'activer le fonctionnement de categorie au niveau de ses vidéos From a90c120173b11d3bac78bbb658eef0aa9139356b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Bonavent?= Date: Fri, 5 Mar 2021 15:24:08 +0100 Subject: [PATCH 048/261] Change API Rest for lives --- pod/live/rest_views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pod/live/rest_views.py b/pod/live/rest_views.py index df2b521e13..e9e6ce33f2 100644 --- a/pod/live/rest_views.py +++ b/pod/live/rest_views.py @@ -17,7 +17,7 @@ class Meta: model = Broadcaster fields = ('id', 'url', 'name', 'slug', 'building', 'description', 'poster', - 'url', 'status') + 'url', 'status', 'is_restricted') lookup_field = 'slug' From 6a90a1bcd04ef1b5a12fb031fa429c96e7446065 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Bonavent?= Date: Fri, 5 Mar 2021 15:24:08 +0100 Subject: [PATCH 049/261] Modification of live template to manage BBB livestream, particularly due to public chat and connection with REDIS hostname --- pod/live/templates/live/live.html | 134 +++++++++++++++++++++--------- 1 file changed, 96 insertions(+), 38 deletions(-) diff --git a/pod/live/templates/live/live.html b/pod/live/templates/live/live.html index b9ef769ced..ee45364864 100644 --- a/pod/live/templates/live/live.html +++ b/pod/live/templates/live/live.html @@ -30,56 +30,71 @@ {% include 'live/live-form.html' %} {% else %} +

 {{broadcaster.name}}

-

 {{broadcaster.name}}

- - - -{% if broadcaster.video_on_hold.is_video %} -
- -
- -{% else %} - -
    - -
-{% endif %} +
    +
+ {% endif %} -

{{ broadcaster.description|safe }}

-{% if broadcaster.iframe_url != "" and broadcaster.iframe_url != None %} - -{% endif %} +

{{ broadcaster.description|safe }}

+ {% if broadcaster.iframe_url != "" and broadcaster.iframe_url != None %} + + {% endif %} + + {% if USE_BBB and USE_BBB_LIVE and display_chat %} +
+ +
+

{% trans 'Send message' %}

+ {% if user.is_authenticated %} + {% trans 'You can send a message (100 characters maximum) to the BigBlueButton session. It will be displayed within 15 to 30 seconds on the live video.' %} + + {% else %} + {% trans 'You must be authenticated to send a message.' %} + {% endif %} +
+
+
+ {% if user.is_authenticated %} + + {% endif %} + +
+ {% endif %} {%endif%} - + +
{% endblock page_content %} @@ -219,6 +234,49 @@
if ($("#divvideoonhold")) { $("#divvideoonhold").html("");} if ($("#divvideoplayer")) { $("#divvideoplayer").css("display", "block"); } }) - +{% if USE_BBB and USE_BBB_LIVE and display_chat %} + +{% endif %} + {% endblock more_script %} From 15ba3676d2c978eefa03e0c9906a463a2f467679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Bonavent?= Date: Fri, 5 Mar 2021 15:24:08 +0100 Subject: [PATCH 050/261] Modification of live views to manage if broadcaster is used to display a BBB streaming live --- pod/live/views.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pod/live/views.py b/pod/live/views.py index f246109e3d..edd07b81d0 100644 --- a/pod/live/views.py +++ b/pod/live/views.py @@ -14,6 +14,7 @@ from django.core.exceptions import PermissionDenied import json from django.utils import timezone +from pod.bbb.models import Livestream VIEWERS_ONLY_FOR_STAFF = getattr( settings, 'VIEWERS_ONLY_FOR_STAFF', False) @@ -21,6 +22,9 @@ HEARTBEAT_DELAY = getattr( settings, 'HEARTBEAT_DELAY', 45) +USE_BBB = getattr(settings, 'USE_BBB', False) +USE_BBB_LIVE = getattr(settings, 'USE_BBB_LIVE', False) + def lives(request): # affichage des directs site = get_current_site(request) @@ -96,7 +100,17 @@ def video_live(request, slug): # affichage des directs 'heartbeat_delay': HEARTBEAT_DELAY } ) + # Search if broadcaster is used to display a BBB streaming live + # for which students can send message from this live page + display_chat = False + if USE_BBB and USE_BBB_LIVE: + livestreams_list = Livestream.objects.\ + filter(broadcaster_id=broadcaster.id) + if len(livestreams_list) > 0: + for livestream in livestreams_list: + display_chat = livestream.enable_chat return render(request, "live/live.html", { + 'display_chat': display_chat, 'broadcaster': broadcaster, 'heartbeat_delay': HEARTBEAT_DELAY }) From 2df84dfdf64e22a5736a2849aff97f0b986ce50f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Bonavent?= Date: Fri, 5 Mar 2021 15:24:08 +0100 Subject: [PATCH 051/261] Add USE_BBB_LIVE setting --- pod/main/context_processors.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pod/main/context_processors.py b/pod/main/context_processors.py index ab1920dd42..6102a70090 100644 --- a/pod/main/context_processors.py +++ b/pod/main/context_processors.py @@ -104,6 +104,9 @@ USE_BBB = getattr( django_settings, 'USE_BBB', False) +USE_BBB_LIVE = getattr( + django_settings, 'USE_BBB_LIVE', False) + def context_settings(request): maintenance_mode = False @@ -148,6 +151,7 @@ def context_settings(request): new_settings['MAINTENANCE_REASON'] = maintenance_text_short new_settings['MAINTENANCE_MODE'] = maintenance_mode new_settings['USE_BBB'] = USE_BBB + new_settings['USE_BBB_LIVE'] = USE_BBB_LIVE return new_settings From eb8bb7f0c65df5aadf3037a727db952be4954f1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Bonavent?= Date: Fri, 5 Mar 2021 15:24:08 +0100 Subject: [PATCH 052/261] Add routes for BBB livestream --- pod/main/rest_router.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pod/main/rest_router.py b/pod/main/rest_router.py index e30a9559e4..15063780b3 100644 --- a/pod/main/rest_router.py +++ b/pod/main/rest_router.py @@ -16,6 +16,9 @@ if getattr(settings, 'USE_PODFILE', False): from pod.podfile import rest_views as podfile_views +if getattr(settings, 'USE_BBB', True): + from pod.bbb import rest_views as bbb_views + router = routers.DefaultRouter() router.register(r'mainfiles', main_views.CustomFileModelViewSet) @@ -55,6 +58,11 @@ router.register(r'images', podfile_views.CustomImageModelSerializerViewSet) +if getattr(settings, 'USE_BBB', True): + router.register(r'bbb_meeting', bbb_views.MeetingModelViewSet) + router.register(r'bbb_attendee', bbb_views.AttendeeModelViewSet) + router.register(r'bbb_livestream', bbb_views.LivestreamModelViewSet) + urlpatterns = [ url(r'dublincore/$', video_views.DublinCoreView.as_view(), name='dublincore'), From d5a2544270188177576e50a9ed8945c9b6c30b30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Bonavent?= Date: Fri, 5 Mar 2021 15:24:08 +0100 Subject: [PATCH 053/261] Change link description if USE_BBB_LIVE used --- pod/main/templates/navbar.html | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pod/main/templates/navbar.html b/pod/main/templates/navbar.html index d1fa8d4ef7..0e44f640d7 100644 --- a/pod/main/templates/navbar.html +++ b/pod/main/templates/navbar.html @@ -103,7 +103,11 @@  {% trans 'Claim a record' %} {% endif %} {% if request.user.is_staff and USE_BBB %} -  {% trans 'My BigBlueButton records' %} + {% if USE_BBB_LIVE %} +  {% trans 'My BigBlueButton records and lives' %} + {% else %} +  {% trans 'My BigBlueButton records' %} + {% endif %} {% endif %} From 40a9dec20758a3b6fe0a0f53ffe0b9b311221e0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Bonavent?= Date: Fri, 5 Mar 2021 15:24:08 +0100 Subject: [PATCH 054/261] Allow the management of video files recorded by bbb-liveStreaming (mkv format) --- pod/video/management/commands/bbb.py | 42 +++++++++++++++------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/pod/video/management/commands/bbb.py b/pod/video/management/commands/bbb.py index b236739401..ae6f12f93c 100644 --- a/pod/video/management/commands/bbb.py +++ b/pod/video/management/commands/bbb.py @@ -37,7 +37,7 @@ Finally, if there was at least one error, an email is sent to Pod admins. This script must be executed regurlaly (for an example, with a CRON task). -Example : crontab -e */5 * * * * /usr/bin/bash -c 'export +Example : crontab -e */2 * * * * /usr/bin/bash -c 'export WORKON_HOME=/data/www/%userpod%/.virtualenvs; export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3.6; cd /data/www/%userpod%/django_projects/podv2; source @@ -48,8 +48,7 @@ from django.utils import translation from django.core.management.base import BaseCommand from django.conf import settings -from pod.bbb.models import Meeting -from pod.bbb.models import User as BBBUser +from pod.bbb.models import Meeting, Attendee import hashlib import requests import datetime @@ -290,7 +289,10 @@ def get_meeting(meeting, html_message_error, message_error): if oMeeting.recorded is False and recording == "true": print_if_debug(" + Recording this meeting. ") oMeeting.recorded = True - oMeeting.save() + # In all case, save the last date where BBB session was in progress + lastDateInProgress = timezone.now() + oMeeting.last_date_in_progress = lastDateInProgress + oMeeting.save() else: # Create the meeting in Pod database print_if_debug(" + Create the meeting in Pod database. " @@ -340,22 +342,22 @@ def get_attendee(attendee, idActualMeeting, html_message_error, message_error): # We save only the BBB moderator if role == "MODERATOR": # Search if the BBB user already exists in Pod - oBBBUser = BBBUser.objects.filter( + oAttendee = Attendee.objects.filter( full_name=fullName, meeting_id=idActualMeeting).first() - if oBBBUser: + if oAttendee: print_if_debug(" + User already exists " "in Pod database : " - "" + oBBBUser.full_name) + "" + oAttendee.full_name) else: # Create the meeting user in Pod database print_if_debug(" + Create the meeting user " "in Pod database : " + fullName) - bbbUserToCreate = BBBUser() - bbbUserToCreate.full_name = fullName - bbbUserToCreate.role = 'MODERATOR' - bbbUserToCreate.meeting_id = idActualMeeting + attendeeToCreate = Attendee() + attendeeToCreate.full_name = fullName + attendeeToCreate.role = 'MODERATOR' + attendeeToCreate.meeting_id = idActualMeeting - bbbUserToCreate.save() + attendeeToCreate.save() except Exception as e: err = "Problem to get BBB attendee "\ "and save in Pod database : " + str(e) + ". "\ @@ -374,7 +376,7 @@ def matching_bbb_pod_user(html_message_error, message_error): # Search for BBB users already in Pod database, without matching # By security : take only the 500 last BBB users, to avoid process # too long. Usefull when users are not known in Pod. - bbbUsers = BBBUser.objects.filter( + attendees = Attendee.objects.filter( user_id__isnull=True ).order_by('-id')[:500] @@ -384,25 +386,25 @@ def matching_bbb_pod_user(html_message_error, message_error): else: bbbUsernameFormat = Concat('first_name', Value(' '), 'last_name') - for bbbUser in bbbUsers: + for attendee in attendees: # Search if this BBB user matching to a Pod user. # Take the first one (This can cause an error in case of namesake!) podUser = User.objects.annotate( name=bbbUsernameFormat, - ).filter(name__icontains=bbbUser.full_name).first() + ).filter(name__icontains=attendee.full_name).first() if podUser: # Update the id and the username of this user print_if_debug(" - A Pod user matching a BBB user " "was found in Pod database. " - "BBB user : " + bbbUser.full_name + ". " + "BBB user : " + attendee.full_name + ". " "Pod user : " + podUser.username) - bbbUser.username = podUser.username - bbbUser.user_id = podUser.id - bbbUser.save() + attendee.username = podUser.username + attendee.user_id = podUser.id + attendee.save() else: print_if_debug(" - A Pod user matching a BBB user " "was NOT found in Pod database. " - "BBB user : " + bbbUser.full_name) + "BBB user : " + attendee.full_name) except Exception as e: err = "Problem to matching BBB user to Pod user : " + str(e) + ". "\ From 400120e528d904c61dc2bd6b1291b27d11d3501c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Bonavent?= Date: Fri, 5 Mar 2021 15:24:08 +0100 Subject: [PATCH 055/261] This feature requires REDIS --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index db442a6c18..fb45b851b7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -27,3 +27,4 @@ django-chunked-upload==2.0.0 requests==2.25.1 chardet==4.0.0 django-cookies-samesite==0.8.0 +redis==3.5.3 \ No newline at end of file From 10a4b9023c2fc7001939596176527d3e945670ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Bonavent?= Date: Fri, 5 Mar 2021 15:24:10 +0100 Subject: [PATCH 056/261] Templates for meetings list useful for livestream --- pod/bbb/templates/bbb/live_card.html | 67 +++++++++++ pod/bbb/templates/bbb/live_list_meeting.html | 107 ++++++++++++++++++ .../templates/bbb/live_publish_meeting.html | 102 +++++++++++++++++ pod/bbb/templates/bbb/live_record_list.html | 20 ++++ 4 files changed, 296 insertions(+) create mode 100644 pod/bbb/templates/bbb/live_card.html create mode 100644 pod/bbb/templates/bbb/live_list_meeting.html create mode 100644 pod/bbb/templates/bbb/live_publish_meeting.html create mode 100644 pod/bbb/templates/bbb/live_record_list.html diff --git a/pod/bbb/templates/bbb/live_card.html b/pod/bbb/templates/bbb/live_card.html new file mode 100644 index 0000000000..75c1c4e227 --- /dev/null +++ b/pod/bbb/templates/bbb/live_card.html @@ -0,0 +1,67 @@ +{% load i18n %} +{% spaceless %} + +{% block page_extra_head %} + +{% endblock page_extra_head %} + +
+
+
+ {{record.meeting_name}} ({{ record.session_date }}) +
+
+
+
+ {% if not record.live %} + +
+ {% if not max_limit_reached %} + + {% trans "Perform a BigBlueButton live"%} + + {% else %} + {% trans "Impossible to perform a BigBlueButton live for the moment (all resources are busy)"%} + {% endif %} +
+ {% else %} + {% if record.live.status == 0 %} + + {% endif %} + {% if record.live.status == 1 %} + + {% endif %} + {% if record.live.status == 2 %} + + {% endif %} + {% endif %} +
+
+ {% if not record.live %} + {% trans "Live not published"%} + {% else %} + {% if record.live.status == 0 %} + {% trans "Live not already started"%} + {% endif %} + {% if record.live.status == 1 %} + {% trans "Live in progress"%} + {% endif %} + {% if record.live.status == 2 %} + {% trans "Live stopped"%} + {% endif %} + {% endif %} +
+ +
+
+{% endspaceless %} \ No newline at end of file diff --git a/pod/bbb/templates/bbb/live_list_meeting.html b/pod/bbb/templates/bbb/live_list_meeting.html new file mode 100644 index 0000000000..1465e7656f --- /dev/null +++ b/pod/bbb/templates/bbb/live_list_meeting.html @@ -0,0 +1,107 @@ +{% extends 'base.html' %} +{% load i18n %} +{% load staticfiles %} + +{% block page_extra_head %} + +{% endblock %} + +{% block breadcrumbs %}{{ block.super }} + {% if USE_BBB_LIVE %} + + {% else %} + + {% endif %} + +{% endblock %} + +{% block page_title %} + {% trans 'Perform a BigBlueButton live' %} +{% endblock %} + +{% block page_content %} + +

{% trans "Perform a BigBlueButton live" %}

+ {% if records.paginator.count == 0 %} +
{% trans "No BigBlueButton session in progress found"%}
+ {% else %} +
{% blocktrans count counter=records.paginator.count %}{{ counter }} BigBlueButton session in progress found{% plural %}{{ counter }} BigBlueButton sessions in progress found{% endblocktrans %}
+ {% endif %} + + {% trans "This is the list of current BigBlueButton sessions for which you are moderator. This module allows you to make a live stream from this BigBlueButton session (useful if there are more than 100 users)." %} + {% trans "Remember to not use breakout rooms in this case and end the meeting once it is over." %}
+ {% trans "Shortly after clicking the \"Perform a BigBlueButton live\" button, and select the desired options, the live stream will be available to users on the Lives page." %}
+
+ + {% if records.paginator.count == 0 %} +

{% trans 'There are no BigBlueButton sessions in progress.'%}

+ {% else %} + {% include "bbb/live_record_list.html" %} + {% endif %} + + + {% trans "Please note: this page refreshes automatically every 30 seconds." %} + +{% endblock page_content %} + +{% block collapse_page_aside %} +{% endblock collapse_page_aside %} + +{% block page_aside %} +{% endblock page_aside %} + +{% block more_script %} + + + +{% endblock more_script %} \ No newline at end of file diff --git a/pod/bbb/templates/bbb/live_publish_meeting.html b/pod/bbb/templates/bbb/live_publish_meeting.html new file mode 100644 index 0000000000..fab5166439 --- /dev/null +++ b/pod/bbb/templates/bbb/live_publish_meeting.html @@ -0,0 +1,102 @@ +{% extends 'base.html' %} +{% load i18n %} +{% load staticfiles %} +{% load thumbnail %} +{% block page_extra_head %} + +{% endblock page_extra_head %} + +{% block breadcrumbs %}{{ block.super }} + + + +{% endblock %} + +{% block page_title %} + {% trans "Confirmation of performing a BigBlueButton live" %} +{% endblock %} + + +{% block page_content %} +

{% trans "Are you sure you want to perform a BigBlueButton live ?" %}

+ + +
+ {% csrf_token %} + +
+ {% trans "Select the desired options than validate this form by clicking \"Perform a BigBlueButton live\"." %}
+

+ {% trans "This live will be stopped automatically when BigBlueButton session ends." %} +

+
+ {% if form.errors %} +

{% trans "One or more errors have been found in the form." %}

+ {% endif %} + {% for field_hidden in form.hidden_fields %} + {{field_hidden.errors}} + {{field_hidden}} + {% endfor %} + {% if form.errors %} + {% for error in form.errors %} + {{ error }} + {% endfor %} + {% endif %} + {% for field in form.visible_fields %} + {% spaceless %} +
+
+
+ {{ field.errors }} + {% if "form-check-input" in field.field.widget.attrs.class %} +
+ {{ field }} +
+ {% else %} + + {{ field }} + {% endif %} + {% if field.help_text %} + {{ field.help_text|safe }} + {% endif %} + {% if field.field.required %}
{% trans "Please provide a valid value for this field" %}.
{%endif%} +
+
+
+ {% endspaceless %} + {% endfor %} +
+ {% trans "Please note: shortly after clicking the \"Perform a BigBlueButton live\" button, the live stream will be available to users on the Lives page." %}
+
+
+ +
+
+{% endblock page_content %} + +{% block collapse_page_aside %} + +{% endblock collapse_page_aside %} + +{% block page_aside %} + +{% endblock page_aside %} + +{% block more_script %} +{{form.media}} +{% endblock more_script %} \ No newline at end of file diff --git a/pod/bbb/templates/bbb/live_record_list.html b/pod/bbb/templates/bbb/live_record_list.html new file mode 100644 index 0000000000..d3e1fd5afc --- /dev/null +++ b/pod/bbb/templates/bbb/live_record_list.html @@ -0,0 +1,20 @@ +{% load i18n %} +{% spaceless %} +
+ {% for record in records %} +
+ {% include "bbb/live_card.html" %} +
+ {% empty %} +
+

{% trans "Sorry, no BigBlueButton session in progress found" %}

+
+ {% endfor %} +
+{% if records.has_next %} + More +{% endif %} + +{% endspaceless %} \ No newline at end of file From 5ea32c178728977be7032117e03c800d3fa30766 Mon Sep 17 00:00:00 2001 From: Olivier Bado Date: Fri, 5 Mar 2021 16:06:49 +0100 Subject: [PATCH 057/261] Accessibility : remove some unwanted text displayed to screen readers + remove column layout for some "no record" messages when there are no other columns + replace list of links with
by
  • and css in footer_links.html + code formatting --- pod/bbb/templates/bbb/record_list.html | 20 +- pod/completion/static/js/completion.js | 594 +++++++-------- pod/custom/settings_local.py.example | 5 + .../interactive/edit_interactive.html | 402 +++++----- .../interactive/video_interactive.html | 183 +++-- pod/main/static/css/pod.css | 1 + .../templates/podfile/customfilewidget.html | 93 ++- .../templates/podfile/list_folder_files.html | 704 +++++++++--------- .../templates/recorder/record_list.html | 22 +- .../static/js/jquery-iframe-transport.js | 404 +++++----- pod/video/templates/channel/channel.html | 54 +- pod/video/templates/videos/footer_link.html | 17 +- pod/video/templates/videos/video_list.html | 20 +- 13 files changed, 1263 insertions(+), 1256 deletions(-) diff --git a/pod/bbb/templates/bbb/record_list.html b/pod/bbb/templates/bbb/record_list.html index 6ea68220e6..7d7769eaef 100644 --- a/pod/bbb/templates/bbb/record_list.html +++ b/pod/bbb/templates/bbb/record_list.html @@ -2,19 +2,19 @@ {% spaceless %}
    {% for record in records %} -
    - {% include "bbb/card.html" %} -
    - {% empty %} -
    -

    {% trans "Sorry, no record found" %}

    -
    +
    + {% include "bbb/card.html" %} +
    + {% empty %} +
    +

    {% trans "Sorry, no record found" %}

    +
    {% endfor %}
    {% if records.has_next %} - More + More {% endif %} -{% endspaceless %} \ No newline at end of file +{% endspaceless %} diff --git a/pod/completion/static/js/completion.js b/pod/completion/static/js/completion.js index 2606c8fd30..131b3138bf 100644 --- a/pod/completion/static/js/completion.js +++ b/pod/completion/static/js/completion.js @@ -1,22 +1,22 @@ $(window).on('load', function() { - $('li.contenuTitre').css('display', 'none'); + $('li.contenuTitre').css('display', 'none'); - var accordeon_head = $('#accordeon li a.title'); - var accordeon_body = $('#accordeon li.contenuTitre'); + var accordeon_head = $('#accordeon li a.title'); + var accordeon_body = $('#accordeon li.contenuTitre'); - accordeon_head.first().addClass('active').parent().next().slideDown('normal'); + accordeon_head.first().addClass('active').parent().next().slideDown('normal'); - // Click on .titre - accordeon_head.on('click', function(event) { - event.preventDefault(); - if ($(this).attr('class') != 'title active') { - $(this).parent().next().slideToggle('normal'); - $(this).addClass('active'); - } else if ($(this).attr('class') == 'title active') { - $(this).parent().next().slideUp('normal'); - $(this).removeClass('active'); - } - }); + // Click on .titre + accordeon_head.on('click', function(event) { + event.preventDefault(); + if ($(this).attr('class') != 'title active') { + $(this).parent().next().slideToggle('normal'); + $(this).addClass('active'); + } else if ($(this).attr('class') == 'title active') { + $(this).parent().next().slideUp('normal'); + $(this).removeClass('active'); + } + }); }); // Video form @@ -25,313 +25,313 @@ var name = ''; // RESET $(document).on('reset', '#accordeon form.completion', function(event) { - var id_form = $(this).attr('id'); - var name_form = id_form.substring(5, id_form.length); - var form_new = 'form_new_' + name_form; - var list = 'list_' + name_form - $('span#' + id_form).html(''); - if(id_form == "form_track") - $('span#form_track').css('width', 'auto'); - $('form#' + form_new).show(); - $('form').show(); - $('a.title').css('display', 'initial'); - $('table tr').removeClass('info'); - $('#fileModal_id_document').remove(); - $('#fileModal_id_src').remove(); + var id_form = $(this).attr('id'); + var name_form = id_form.substring(5, id_form.length); + var form_new = 'form_new_' + name_form; + var list = 'list_' + name_form + $('span#' + id_form).html(''); + if(id_form == "form_track") + $('span#form_track').css('width', 'auto'); + $('form#' + form_new).show(); + $('form').show(); + $('a.title').css('display', 'initial'); + $('table tr').removeClass('info'); + $('#fileModal_id_document').remove(); + $('#fileModal_id_src').remove(); }); function show_form(data, form) { - $('#'+form).hide().html(data).fadeIn(); - if(form === "form_track") - $('#form_track').css('width', '100%'); + $('#'+form).hide().html(data).fadeIn(); + if(form === "form_track") + $('#form_track').css('width', '100%'); }; var ajaxfail = function(data, form) { - showalert(gettext('Error getting form.') + ' (' + data + ') ' + gettext('The form could not be recovered.'), 'alert-danger'); + showalert(gettext('Error getting form.') + ' (' + data + ') ' + gettext('The form could not be recovered.'), 'alert-danger'); }; //SUBMIT $(document).on('submit', '#accordeon form.completion', function(e) { - e.preventDefault(); - var jqxhr = ''; - var exp = /_([a-z]*)\s?/g; - var id_form = $(this).attr('id'); - var name_form = ''; - var result_regexp = ''; - if (id_form == undefined) { - var form_class = $(this).find('input[type=submit]').attr('class'); - result_regexp = exp.exec(form_class); - name_form = result_regexp[1]; - } else { - result_regexp = id_form.split(exp); - name_form = result_regexp[result_regexp.length - 2]; - } - var form = 'form_' + name_form; - var list = 'list_' + name_form; - var action = $(this).find('input[name=action]').val(); - sendandgetform(this, action, name_form, form, list); + e.preventDefault(); + var jqxhr = ''; + var exp = /_([a-z]*)\s?/g; + var id_form = $(this).attr('id'); + var name_form = ''; + var result_regexp = ''; + if (id_form == undefined) { + var form_class = $(this).find('input[type=submit]').attr('class'); + result_regexp = exp.exec(form_class); + name_form = result_regexp[1]; + } else { + result_regexp = id_form.split(exp); + name_form = result_regexp[result_regexp.length - 2]; + } + var form = 'form_' + name_form; + var list = 'list_' + name_form; + var action = $(this).find('input[name=action]').val(); + sendandgetform(this, action, name_form, form, list); }); var sendandgetform = function(elt, action, name, form, list) { - var href = $(elt).attr('action'); - if (action == 'new' || action == 'form_save_new') { - $('#'+form).html( - '
    '); - $('.info-card').hide(); - $('#' + name + '-info').show(); - var jqxhr = $.ajax({ - method: 'POST', - url: window.location.origin + href, - data: {'action': action, 'csrfmiddlewaretoken': $(elt).find('input[name="csrfmiddlewaretoken"]').val()}, - dataType: 'html' - }); - jqxhr.done(function(data) { - if (data.indexOf(form) == -1) { - showalert(gettext('You are no longer authenticated. Please log in again.', 'alert-danger')); - } else { - show_form(data, form); - } - }); - jqxhr.fail(function($xhr) { - var data = $xhr.status + ' : ' + $xhr.statusText; - ajaxfail(data); - $('form.form_change').show(); - $('form.form_modif').show(); - $('form.form_delete').show(); - $('form.form_new').show(); - $('#' + form).html(''); - }); - $('form.form_new').hide(); - $('form.form_change').hide(); - $('form.form_modif').hide(); - $('form.form_delete').hide(); - $('a.title').css('display', 'none'); - hide_others_sections(name); - } - if (action == 'modify' || action == 'form_save_modify') { - var id = $(elt).find('input[name=id]').val(); - var jqxhr = $.ajax({ - method: 'POST', - url: window.location.origin + href, - data: {'action': action, 'id': id, 'csrfmiddlewaretoken': $(elt).find('input[name="csrfmiddlewaretoken"]').val()}, - dataType: 'html' - }); - jqxhr.done(function(data) { - if (data.indexOf(form) == -1) { - showalert(gettext('You are no longer authenticated. Please log in again.', 'alert-danger')); - } else { - show_form(data, form); - } - }); - jqxhr.fail(function($xhr) { - var data = $xhr.status + ' : ' + $xhr.statusText; - ajaxfail(data, form); - $('form.form_modif').show(); - $('form.form_delete').show(); - $('form.form_new').show(); - $('#' + form).html(''); - }); - $('form.form_new').hide(); - $('form.form_modif').hide(); - $('form.form_delete').hide(); - $('a.title').css('display', 'none'); - hide_others_sections(name); - } - if (action == 'delete') { - var deleteConfirm = ''; - if (name == 'track') { - deleteConfirm = confirm(gettext('Are you sure you want to delete this file?')); - } else if (name == 'contributor') { - deleteConfirm = confirm(gettext('Are you sure you want to delete this contributor?')); - } else if (name == 'document') { - deleteConfirm = confirm(gettext('Are you sure you want to delete this document?')); - } else if (name == 'overlay') { - deleteConfirm = confirm(gettext('Are you sure you want to delete this overlay?')); - } - if (deleteConfirm) { - var id = $(elt).find('input[name=id]').val(); - jqxhr = $.ajax({ - method: 'POST', - url: window.location.origin + href, - data: {'action': action, 'id': id, 'csrfmiddlewaretoken': $(elt).find('input[name="csrfmiddlewaretoken"]').val()}, - dataType: 'html' - }); - jqxhr.done(function(data) { - data = JSON.parse(data); - if (data.list_data) { - refresh_list(data, form, list); - } else { - showalert(gettext('You are no longer authenticated. Please log in again.', 'alert-danger')); - } - }); - jqxhr.fail(function($xhr) { - var data = $xhr.status + ' : ' + $xhr.statusText; - ajaxfail(data, form); - }); - } - } - if (action == 'save') { - $('.form-help-inline').parents('div.form-group').removeClass('has-error'); - $('.form-help-inline').remove(); - if (verify_fields(form)) { - var data_form = $('form#' + form).serialize(); - var jqxhr = $.ajax({ - method: 'POST', - url: window.location.origin + href, - data: data_form, - dataType: 'html' - }); - jqxhr.done(function(data) { - data = JSON.parse(data); - if (data.list_data || data.form) { - if (data.errors) { - $('#fileModal_id_src').remove(); - show_form(data.form, form); - } else { - refresh_list(data, form, list); - $(window).scrollTop(100); - showalert(gettext('Changes have been saved.'), 'alert-info'); - } - } else { - showalert(gettext('You are no longer authenticated. Please log in again.'), 'alert-danger'); - } - }); - jqxhr.fail(function($xhr) { - var data = $xhr.status + ' : ' + $xhr.statusText; - ajaxfail(data, form); - }); - $('form.form_new').hide(); - $('form.form_modif').hide(); - $('form.form_delete').hide(); - } - } - feather.replace({ class: 'align-bottom'}); + var href = $(elt).attr('action'); + if (action == 'new' || action == 'form_save_new') { + $('#'+form).html( + '
    '); + $('.info-card').hide(); + $('#' + name + '-info').show(); + var jqxhr = $.ajax({ + method: 'POST', + url: window.location.origin + href, + data: {'action': action, 'csrfmiddlewaretoken': $(elt).find('input[name="csrfmiddlewaretoken"]').val()}, + dataType: 'html' + }); + jqxhr.done(function(data) { + if (data.indexOf(form) == -1) { + showalert(gettext('You are no longer authenticated. Please log in again.', 'alert-danger')); + } else { + show_form(data, form); + } + }); + jqxhr.fail(function($xhr) { + var data = $xhr.status + ' : ' + $xhr.statusText; + ajaxfail(data); + $('form.form_change').show(); + $('form.form_modif').show(); + $('form.form_delete').show(); + $('form.form_new').show(); + $('#' + form).html(''); + }); + $('form.form_new').hide(); + $('form.form_change').hide(); + $('form.form_modif').hide(); + $('form.form_delete').hide(); + $('a.title').css('display', 'none'); + hide_others_sections(name); + } + if (action == 'modify' || action == 'form_save_modify') { + var id = $(elt).find('input[name=id]').val(); + var jqxhr = $.ajax({ + method: 'POST', + url: window.location.origin + href, + data: {'action': action, 'id': id, 'csrfmiddlewaretoken': $(elt).find('input[name="csrfmiddlewaretoken"]').val()}, + dataType: 'html' + }); + jqxhr.done(function(data) { + if (data.indexOf(form) == -1) { + showalert(gettext('You are no longer authenticated. Please log in again.', 'alert-danger')); + } else { + show_form(data, form); + } + }); + jqxhr.fail(function($xhr) { + var data = $xhr.status + ' : ' + $xhr.statusText; + ajaxfail(data, form); + $('form.form_modif').show(); + $('form.form_delete').show(); + $('form.form_new').show(); + $('#' + form).html(''); + }); + $('form.form_new').hide(); + $('form.form_modif').hide(); + $('form.form_delete').hide(); + $('a.title').css('display', 'none'); + hide_others_sections(name); + } + if (action == 'delete') { + var deleteConfirm = ''; + if (name == 'track') { + deleteConfirm = confirm(gettext('Are you sure you want to delete this file?')); + } else if (name == 'contributor') { + deleteConfirm = confirm(gettext('Are you sure you want to delete this contributor?')); + } else if (name == 'document') { + deleteConfirm = confirm(gettext('Are you sure you want to delete this document?')); + } else if (name == 'overlay') { + deleteConfirm = confirm(gettext('Are you sure you want to delete this overlay?')); + } + if (deleteConfirm) { + var id = $(elt).find('input[name=id]').val(); + jqxhr = $.ajax({ + method: 'POST', + url: window.location.origin + href, + data: {'action': action, 'id': id, 'csrfmiddlewaretoken': $(elt).find('input[name="csrfmiddlewaretoken"]').val()}, + dataType: 'html' + }); + jqxhr.done(function(data) { + data = JSON.parse(data); + if (data.list_data) { + refresh_list(data, form, list); + } else { + showalert(gettext('You are no longer authenticated. Please log in again.', 'alert-danger')); + } + }); + jqxhr.fail(function($xhr) { + var data = $xhr.status + ' : ' + $xhr.statusText; + ajaxfail(data, form); + }); + } + } + if (action == 'save') { + $('.form-help-inline').parents('div.form-group').removeClass('has-error'); + $('.form-help-inline').remove(); + if (verify_fields(form)) { + var data_form = $('form#' + form).serialize(); + var jqxhr = $.ajax({ + method: 'POST', + url: window.location.origin + href, + data: data_form, + dataType: 'html' + }); + jqxhr.done(function(data) { + data = JSON.parse(data); + if (data.list_data || data.form) { + if (data.errors) { + $('#fileModal_id_src').remove(); + show_form(data.form, form); + } else { + refresh_list(data, form, list); + $(window).scrollTop(100); + showalert(gettext('Changes have been saved.'), 'alert-info'); + } + } else { + showalert(gettext('You are no longer authenticated. Please log in again.'), 'alert-danger'); + } + }); + jqxhr.fail(function($xhr) { + var data = $xhr.status + ' : ' + $xhr.statusText; + ajaxfail(data, form); + }); + $('form.form_new').hide(); + $('form.form_modif').hide(); + $('form.form_delete').hide(); + } + } + feather.replace({ class: 'align-bottom'}); } // Hide others sections function hide_others_sections(name_form) { - var sections = $('a.title.active').not('a[id="section_' + name_form + '"]'); - if (sections.length > 0) { - sections.parent().next().slideUp('normal'); - sections.removeClass('active'); - var i; - for ( i = 0; i < sections.length; i++) { - var section = sections[i]; - var text = section.text; - var name_section = '\'' + text.replace(/\s/g, '') + '\'' - section.title = gettext('Display') + " " + name_section + " " + gettext('section'); - section.firstElementChild.className = 'glyphicon glyphicon-chevron-down'; - } - } + var sections = $('a.title.active').not('a[id="section_' + name_form + '"]'); + if (sections.length > 0) { + sections.parent().next().slideUp('normal'); + sections.removeClass('active'); + var i; + for ( i = 0; i < sections.length; i++) { + var section = sections[i]; + var text = section.text; + var name_section = '\'' + text.replace(/\s/g, '') + '\'' + section.title = gettext('Display') + " " + name_section + " " + gettext('section'); + section.firstElementChild.className = 'glyphicon glyphicon-chevron-down'; + } + } } // Refreshes the list function refresh_list(data, form, list) { - $('#' + form).html(''); - $('form.form_new').show(); - $('form').show(); - $('a.title').css('display', 'initial'); - $('span#enrich_player').html(data.player); - $('span#' + list).html(data.list_data); + $('#' + form).html(''); + $('form.form_new').show(); + $('form').show(); + $('a.title').css('display', 'initial'); + $('span#enrich_player').html(data.player); + $('span#' + list).html(data.list_data); } // Check fields function verify_fields(form) { - var error = false; - if (form == 'form_contributor') { - if ((document.getElementById('id_name').value == '') || (document.getElementById('id_name').value.length < 2) || (document.getElementById('id_name').length > 200)) { - $('input#id_name') - .after("  " + gettext('Please enter a name from 2 to 100 caracteres.') + "") - .parents('div.form-group').addClass('has-error'); - error = true; - } - if (document.getElementById('id_weblink').value.length >= 200) { - $('input#id_weblink') - .after("  " + gettext('You cannot enter a weblink with more than 200 caracteres.') + "") - .parents('div.form-group').addClass('has-error'); - error = true; - } - if (document.getElementById('id_role').value == '') { - $('select#id_role') - .after("  " + gettext('Please enter a role.') + "") - .parents('div.form-group').addClass('has-error'); - error = true; - } - var id = parseInt(document.getElementById('id_contributor').value); - var new_role = document.getElementById('id_role').value; - var new_name = document.getElementById('id_name').value; - $('#table_list_contributors tbody > tr').each(function() { - if (id != $(this).find('input[name=id]')[0].value && $(this).find('td[class=contributor_name]')[0].innerHTML == new_name && $(this).find('td[class=contributor_role]')[0].innerHTML == new_role) { - var text = gettext('There is already a contributor with this same name and role in the list.'); - showalert(text, 'alert-danger'); - error = true; - } - }); - } else if (form == 'form_track') { - var element = document.getElementById('id_kind'); - var value = element.options[element.selectedIndex].value.trim().toLowerCase(); - var kind = element.options[element.selectedIndex].text.trim().toLowerCase(); - if (value !== 'subtitles' && value !== 'captions') { - $('select#id_kind') - .after("" + gettext('Please enter a correct kind.') + "") - .parents('div.form-group').addClass('has-error'); - error = true; - } - var element = document.getElementById('id_lang'); - var lang = element.options[element.selectedIndex].value.trim().toLowerCase(); - if (element.options[element.selectedIndex].value.trim() === '') { - $('select#id_lang') - .after("" + gettext('Please select a language.') + "") - .parents('div.form-group').addClass('has-error'); - error = true; - } - var file_abs_path = document.getElementById('fileinput_id_src').getElementsByTagName('a')[0].getAttribute('href'); - if (document.getElementById('id_src').value.trim() === '') { - $('input#id_src') - .after("" + gettext('Please specify a track file.') + "") - .parents('div.form-group').addClass('has-error'); - error = true; - } - else if (!file_abs_path.match(/\.vtt$/)) { - $('input#id_src') - .after("" + gettext('Only .vtt format is allowed.') + "") - .parents('div.form-group').addClass('has-error'); - error = true; - } - var is_duplicate = false; - var file_name = file_abs_path.match(/([\w\d_\-]+)(\.vtt)/)[1].toLowerCase(); - $('.grid-list-track .track_kind.kind').each(function() { - if ( - kind === $(this).text().trim().toLowerCase() && - lang === $(this).siblings("#"+$(this).attr('id')+".track_kind.lang").text().trim().toLowerCase() && - file_name === $(this).siblings("#"+$(this).attr('id')+".track_kind.file").text().trim().split(' ')[0].toLowerCase()) { - is_duplicate = true; - return false; - } - }); - if (is_duplicate) { - $('input#id_src') - .after("
    " + gettext('There is already a track with the same kind and language in the list.') + "") - .parents('div.form-group').addClass('has-error'); - error = true; - } - } else if (form == 'form_document') { - if ($('img#id_document_thumbnail_img').attr('src') == '/static/icons/nofile_48x48.png') { - $('img#id_document_thubmanil_img') - .after("  " + gettext('Please select a document.') + "") - .parents('div.form-group').addClass('has-error'); - error = true; - } - } else if (form == 'form_overlay') { - var tags = /|/; - if (tags.exec(document.getElementById('id_content').value) != null) { - $('textarea#id_content') - .after("  " + gettext('Iframe and Script tags are not allowed.') + "") - .parents('div.form-group').addClass('has-error'); - error = true; - } - } - return !error; + var error = false; + if (form == 'form_contributor') { + if ((document.getElementById('id_name').value == '') || (document.getElementById('id_name').value.length < 2) || (document.getElementById('id_name').length > 200)) { + $('input#id_name') + .after("  " + gettext('Please enter a name from 2 to 100 caracteres.') + "") + .parents('div.form-group').addClass('has-error'); + error = true; + } + if (document.getElementById('id_weblink').value.length >= 200) { + $('input#id_weblink') + .after("  " + gettext('You cannot enter a weblink with more than 200 caracteres.') + "") + .parents('div.form-group').addClass('has-error'); + error = true; + } + if (document.getElementById('id_role').value == '') { + $('select#id_role') + .after("  " + gettext('Please enter a role.') + "") + .parents('div.form-group').addClass('has-error'); + error = true; + } + var id = parseInt(document.getElementById('id_contributor').value); + var new_role = document.getElementById('id_role').value; + var new_name = document.getElementById('id_name').value; + $('#table_list_contributors tbody > tr').each(function() { + if (id != $(this).find('input[name=id]')[0].value && $(this).find('td[class=contributor_name]')[0].innerHTML == new_name && $(this).find('td[class=contributor_role]')[0].innerHTML == new_role) { + var text = gettext('There is already a contributor with this same name and role in the list.'); + showalert(text, 'alert-danger'); + error = true; + } + }); + } else if (form == 'form_track') { + var element = document.getElementById('id_kind'); + var value = element.options[element.selectedIndex].value.trim().toLowerCase(); + var kind = element.options[element.selectedIndex].text.trim().toLowerCase(); + if (value !== 'subtitles' && value !== 'captions') { + $('select#id_kind') + .after("" + gettext('Please enter a correct kind.') + "") + .parents('div.form-group').addClass('has-error'); + error = true; + } + var element = document.getElementById('id_lang'); + var lang = element.options[element.selectedIndex].value.trim().toLowerCase(); + if (element.options[element.selectedIndex].value.trim() === '') { + $('select#id_lang') + .after("" + gettext('Please select a language.') + "") + .parents('div.form-group').addClass('has-error'); + error = true; + } + var file_abs_path = document.getElementById('fileinput_id_src').getElementsByTagName('a')[0].getAttribute('href'); + if (document.getElementById('id_src').value.trim() === '') { + $('input#id_src') + .after("" + gettext('Please specify a track file.') + "") + .parents('div.form-group').addClass('has-error'); + error = true; + } + else if (!file_abs_path.match(/\.vtt$/)) { + $('input#id_src') + .after("" + gettext('Only .vtt format is allowed.') + "") + .parents('div.form-group').addClass('has-error'); + error = true; + } + var is_duplicate = false; + var file_name = file_abs_path.match(/([\w\d_\-]+)(\.vtt)/)[1].toLowerCase(); + $('.grid-list-track .track_kind.kind').each(function() { + if ( + kind === $(this).text().trim().toLowerCase() && + lang === $(this).siblings("#"+$(this).attr('id')+".track_kind.lang").text().trim().toLowerCase() && + file_name === $(this).siblings("#"+$(this).attr('id')+".track_kind.file").text().trim().split(' ')[0].toLowerCase()) { + is_duplicate = true; + return false; + } + }); + if (is_duplicate) { + $('input#id_src') + .after("
    " + gettext('There is already a track with the same kind and language in the list.') + "") + .parents('div.form-group').addClass('has-error'); + error = true; + } + } else if (form == 'form_document') { + if ($('img#id_document_thumbnail_img').attr('src') == '/static/icons/nofile_48x48.png') { + $('img#id_document_thubmanil_img') + .after("  " + gettext('Please select a document.') + "") + .parents('div.form-group').addClass('has-error'); + error = true; + } + } else if (form == 'form_overlay') { + var tags = /|/; + if (tags.exec(document.getElementById('id_content').value) != null) { + $('textarea#id_content') + .after("  " + gettext('Iframe and Script tags are not allowed.') + "") + .parents('div.form-group').addClass('has-error'); + error = true; + } + } + return !error; } diff --git a/pod/custom/settings_local.py.example b/pod/custom/settings_local.py.example index 12bcc71bab..2e0db783c0 100644 --- a/pod/custom/settings_local.py.example +++ b/pod/custom/settings_local.py.example @@ -90,6 +90,11 @@ ADMINS = (('Name', 'adminmail@univ.fr'),) """ MANAGERS = ADMINS +""" +# Liste des adresses destinataires des courriels de contact +""" +CONTACT_US_EMAIL = [] + """ # Un dictionnaire contenant les réglages de toutes les bases de données # à utiliser avec Django. diff --git a/pod/interactive/templates/interactive/edit_interactive.html b/pod/interactive/templates/interactive/edit_interactive.html index ae9e6f7060..f078aab30a 100644 --- a/pod/interactive/templates/interactive/edit_interactive.html +++ b/pod/interactive/templates/interactive/edit_interactive.html @@ -6,27 +6,27 @@ {% block page_extra_head %} {% endblock page_extra_head %} @@ -34,73 +34,73 @@ {% block video-element %}
    - {% trans 'Loading, please wait...' %} + {% trans 'Loading, please wait...' %}
    {% if not request.GET.is_iframe%} {% endif %} {% if video.interactive.is_interactive == True %} - + {% else %} - + {% endif %} {% if not request.GET.is_iframe%} {% endif %} @@ -108,148 +108,148 @@

    {% block page_aside %} -
    -
    -  {% trans 'Informations' %} -
    -
    - {% if video.owner == request.user or request.user.is_superuser %} -

     {% trans 'You can specify the group(s) of users who can access this page' %}

    - {% endif %} -

    - {% trans 'Do not forget to save your work regularly. Especially if you add an interaction.' %} -
    - {% trans "To save and continue your work click on the button [Save and continue]. If you have completed your work click on the button [Save and see the interactive video] to view your new interactive video." %} -

    -
    -
    - {% if video.owner == request.user or request.user.is_superuser or request.user in video.additional_owners.all %} -
    -
     {% trans "Manage video"%}
    -
    - {% include "videos/link_video.html" %} -
    +
    +
    +  {% trans 'Informations' %} +
    +
    + {% if video.owner == request.user or request.user.is_superuser %} +

     {% trans 'You can specify the group(s) of users who can access this page' %}

    + {% endif %} +

    + {% trans 'Do not forget to save your work regularly. Especially if you add an interaction.' %} +
    + {% trans "To save and continue your work click on the button [Save and continue]. If you have completed your work click on the button [Save and see the interactive video] to view your new interactive video." %} +

    - {% endif %} +
    + {% if video.owner == request.user or request.user.is_superuser or request.user in video.additional_owners.all %} +
    +
     {% trans "Manage video"%}
    +
    + {% include "videos/link_video.html" %} +
    +
    + {% endif %} {% endblock page_aside %} {% block more_script %} {% endblock more_script %} \ No newline at end of file diff --git a/pod/interactive/templates/interactive/video_interactive.html b/pod/interactive/templates/interactive/video_interactive.html index e288d94a73..fadc9fb626 100644 --- a/pod/interactive/templates/interactive/video_interactive.html +++ b/pod/interactive/templates/interactive/video_interactive.html @@ -5,17 +5,17 @@ {% block page_extra_head %} {% endblock page_extra_head %} @@ -130,54 +130,54 @@
     {% trans 'Scoreboard' %}
    {% if more_data.score and request.user == video.owner or request.user.is_superuser or request.user in video.additional_owners.all %} {% trans 'The scoreboard displays the users who viewed your interactive video and their results.' %} - + - - - - + + + + - - - {% for user in more_data.score %} - {% if user.max_points and user.max_points != ".." %} - - - - - - - {% else %} - - - - - - {% endif %} - {% endfor %} - + + + {% for user in more_data.score %} + {% if user.max_points and user.max_points != ".." %} + + + + + + + {% else %} + + + + + + {% endif %} + {% endfor %} +
    {% trans 'User' %}{% trans 'Points' %}{% trans 'started' %}{% trans 'finished' %}{% trans 'User' %}{% trans 'Points' %}{% trans 'started' %}{% trans 'finished' %}
    {{user.user}}{{user.points}} / {{user.max_points}}{{user.date_started}}{{user.date_finished}}
    {{user.user}}{% trans 'No score available' %}{{user.date_started}}{{user.date_finished}}
    {{user.user}}{{user.points}} / {{user.max_points}}{{user.date_started}}{{user.date_finished}}
    {{user.user}}{% trans 'No score available' %}{{user.date_started}}{{user.date_finished}}
    {% elif request.user.is_authenticated %} -
    +
    {% if more_data.score %} - {% with more_data.score|first as userscore %} + {% with more_data.score|first as userscore %} {% trans 'You got the following score on this video' %}: {{userscore.points}} / {{userscore.max_points}} - {% endwith %} + {% endwith %} {% else %} - {% trans "no score found" %} + {% trans "no score found" %} {% endif %} -
    +
    {% else %} -
    +

    {% trans 'You are watching this video as anonymous user'%}

    {% if more_data.score %} - {% with more_data.score|first as userscore %} + {% with more_data.score|first as userscore %} {% trans 'You got the following score on this video' %}: {{userscore.points}} / {{userscore.max_points}} - {% endwith %} + {% endwith %} {% else %} - {% trans "no score found" %} + {% trans "no score found" %} {% endif %} -
    +
    {% endif %}
    @@ -188,65 +188,64 @@

     {% trans 'Scoreboard' %}
    {% endblock video-element %} {% block page_aside %} - {{ block.super }} + {{ block.super }} {% endblock page_aside %} {% block more_script %} {% endblock more_script %} - diff --git a/pod/main/static/css/pod.css b/pod/main/static/css/pod.css index 3f55b60740..fe8cdb98d1 100755 --- a/pod/main/static/css/pod.css +++ b/pod/main/static/css/pod.css @@ -443,6 +443,7 @@ footer a, footer a:hover{ .footer_links{ list-style: none; + padding-left: 1em; } .footer_links>li:before{ margin-right: .5em; diff --git a/pod/podfile/templates/podfile/customfilewidget.html b/pod/podfile/templates/podfile/customfilewidget.html index 36d6347882..10e445473e 100644 --- a/pod/podfile/templates/podfile/customfilewidget.html +++ b/pod/podfile/templates/podfile/customfilewidget.html @@ -3,54 +3,53 @@ {% endblock more_style %}
    -{{input|safe}} - -{% if value %} - - {% if document.class_name == "CustomImageModel" and document.file_exist %}{{document.name}}  + {{input|safe}} + + {% if value %} + + {% if document.class_name == "CustomImageModel" and document.file_exist %}{{document.name}}  + {% else %} +   + {%endif%} + {% if document.file_exist %} + {{document.name}}  + ({{document.file_type}} - {{document.file.size|filesizeformat}}) + {% else %} + {{document.name}} + {%endif%} + + + {% else %} -   - {%endif%} - {% if document.file_exist %} - {{document.name}}  - ({{document.file_type}} - {{document.file.size|filesizeformat}}) - {% else %} - {{document.name}} - {%endif%} - - - -{% else %} - - - - -{% endif%} - + + + + {% endif%} +
  • +
+
- {% for file in folder.get_all_files %} -
-
-
- {% if request.user == file.created_by or request.user.is_superuser or perms.podfile.change_customfilemodel or perms.podfile.change_customimagemodel or request.user in folder.users.all %} - - {% endif %} -
- {% if file.class_name.lower == "customimagemodel" and file.file_exist %} - {% if type.lower == "image" and file.class_name.lower == "customimagemodel" %} + + + + {% trans "Modify"%} + + + + + +
+ + {% endif %} +
+ {% if file.class_name.lower == "customimagemodel" and file.file_exist %} + {% if type.lower == "image" and file.class_name.lower == "customimagemodel" %} + + Card image + + {% else %} + Card image + {% endif %} + {% else %} + {% with file.file.name|icon_exists as icon %} + {% if type.lower == "file" and file.class_name.lower == "customfilemodel" or type.lower == "image" and file.class_name.lower == "customimagemodel" %} + Card image + + {% else %} + Card image + {% endif%} + {%endwith%} + {% endif %} +
+

+ {% if type %} + {% if type == "image" and file.class_name == "CustomImageModel" %} + - Card image - - {% else %} - Card image - {% endif %} - {% else %} - {% with file.file.name|icon_exists as icon %} - {% if type.lower == "file" and file.class_name.lower == "customfilemodel" or type.lower == "image" and file.class_name.lower == "customimagemodel" %} - + {{file.name}} + + {% elif type == "file" and file.class_name == "CustomFileModel"%} + + {{file.name}} + + {% else %} + {{file.name}} + {% endif %} + {% else %} + - Card image + {{file.name}} - {% else %} - Card image - {% endif%} - {%endwith%} {% endif %} -

-

- {% if type %} - {% if type == "image" and file.class_name == "CustomImageModel" %} - - {{file.name}} - - {% elif type == "file" and file.class_name == "CustomFileModel"%} - - {{file.name}} - - {% else %} - {{file.name}} - {% endif %} - {% else %} - - {{file.name}} - - {% endif %} -

-
-
+

+
- {% endfor %} - + + {% endfor %} + diff --git a/pod/recorder/templates/recorder/record_list.html b/pod/recorder/templates/recorder/record_list.html index b4fc4aaa13..ab50843b8e 100644 --- a/pod/recorder/templates/recorder/record_list.html +++ b/pod/recorder/templates/recorder/record_list.html @@ -1,20 +1,20 @@ {% load i18n %} {% spaceless %}
-{% for record in records %} -
-{% include "recorder/card.html" %} -
-{% empty %} -
-

{% trans "Sorry, no record found" %}

-
-{% endfor %} + {% for record in records %} +
+ {% include "recorder/card.html" %} +
+ {% empty %} +
+

{% trans "Sorry, no record found" %}

+
+ {% endfor %}
{% if records.has_next %} -More + More {% endif %} {% endspaceless %} \ No newline at end of file diff --git a/pod/video/static/js/jquery-iframe-transport.js b/pod/video/static/js/jquery-iframe-transport.js index 794d24efc3..e2fa0aec90 100644 --- a/pod/video/static/js/jquery-iframe-transport.js +++ b/pod/video/static/js/jquery-iframe-transport.js @@ -12,216 +12,216 @@ /* global define, require */ (function (factory) { - 'use strict'; - if (typeof define === 'function' && define.amd) { - // Register as an anonymous AMD module: - define(['jquery'], factory); - } else if (typeof exports === 'object') { - // Node/CommonJS: - factory(require('jquery')); - } else { - // Browser globals: - factory(window.jQuery); - } - })(function ($) { - 'use strict'; - - // Helper variable to create unique names for the transport iframes: - var counter = 0, - jsonAPI = $, - jsonParse = 'parseJSON'; - - if ('JSON' in window && 'parse' in JSON) { - jsonAPI = JSON; - jsonParse = 'parse'; - } - - // The iframe transport accepts four additional options: - // options.fileInput: a jQuery collection of file input fields - // options.paramName: the parameter name for the file form data, - // overrides the name property of the file input field(s), - // can be a string or an array of strings. - // options.formData: an array of objects with name and value properties, - // equivalent to the return data of .serializeArray(), e.g.: - // [{name: 'a', value: 1}, {name: 'b', value: 2}] - // options.initialIframeSrc: the URL of the initial iframe src, - // by default set to "javascript:false;" - $.ajaxTransport('iframe', function (options) { - if (options.async) { - // javascript:false as initial iframe src - // prevents warning popups on HTTPS in IE6: - // eslint-disable-next-line no-script-url - var initialIframeSrc = options.initialIframeSrc || 'javascript:false;', - form, - iframe, - addParamChar; - return { - send: function (_, completeCallback) { - form = $('
'); - form.attr('accept-charset', options.formAcceptCharset); - addParamChar = /\?/.test(options.url) ? '&' : '?'; - // XDomainRequest only supports GET and POST: - if (options.type === 'DELETE') { - options.url = options.url + addParamChar + '_method=DELETE'; - options.type = 'POST'; - } else if (options.type === 'PUT') { - options.url = options.url + addParamChar + '_method=PUT'; - options.type = 'POST'; - } else if (options.type === 'PATCH') { - options.url = options.url + addParamChar + '_method=PATCH'; - options.type = 'POST'; - } - // IE versions below IE8 cannot set the name property of - // elements that have already been added to the DOM, - // so we set the name along with the iframe HTML markup: - counter += 1; - iframe = $( - '' - ).on('load', function () { - var fileInputClones, - paramNames = $.isArray(options.paramName) - ? options.paramName - : [options.paramName]; - iframe.off('load').on('load', function () { - var response; - // Wrap in a try/catch block to catch exceptions thrown - // when trying to access cross-domain iframe contents: - try { - response = iframe.contents(); - // Google Chrome and Firefox do not throw an - // exception when calling iframe.contents() on - // cross-domain requests, so we unify the response: - if (!response.length || !response[0].firstChild) { - throw new Error(); - } - } catch (e) { - response = undefined; + 'use strict'; + if (typeof define === 'function' && define.amd) { + // Register as an anonymous AMD module: + define(['jquery'], factory); + } else if (typeof exports === 'object') { + // Node/CommonJS: + factory(require('jquery')); + } else { + // Browser globals: + factory(window.jQuery); + } +})(function ($) { + 'use strict'; + + // Helper variable to create unique names for the transport iframes: + var counter = 0, + jsonAPI = $, + jsonParse = 'parseJSON'; + + if ('JSON' in window && 'parse' in JSON) { + jsonAPI = JSON; + jsonParse = 'parse'; + } + + // The iframe transport accepts four additional options: + // options.fileInput: a jQuery collection of file input fields + // options.paramName: the parameter name for the file form data, + // overrides the name property of the file input field(s), + // can be a string or an array of strings. + // options.formData: an array of objects with name and value properties, + // equivalent to the return data of .serializeArray(), e.g.: + // [{name: 'a', value: 1}, {name: 'b', value: 2}] + // options.initialIframeSrc: the URL of the initial iframe src, + // by default set to "javascript:false;" + $.ajaxTransport('iframe', function (options) { + if (options.async) { + // javascript:false as initial iframe src + // prevents warning popups on HTTPS in IE6: + // eslint-disable-next-line no-script-url + var initialIframeSrc = options.initialIframeSrc || 'javascript:false;', + form, + iframe, + addParamChar; + return { + send: function (_, completeCallback) { + form = $('
'); + form.attr('accept-charset', options.formAcceptCharset); + addParamChar = /\?/.test(options.url) ? '&' : '?'; + // XDomainRequest only supports GET and POST: + if (options.type === 'DELETE') { + options.url = options.url + addParamChar + '_method=DELETE'; + options.type = 'POST'; + } else if (options.type === 'PUT') { + options.url = options.url + addParamChar + '_method=PUT'; + options.type = 'POST'; + } else if (options.type === 'PATCH') { + options.url = options.url + addParamChar + '_method=PATCH'; + options.type = 'POST'; + } + // IE versions below IE8 cannot set the name property of + // elements that have already been added to the DOM, + // so we set the name along with the iframe HTML markup: + counter += 1; + iframe = $( + '' + ).on('load', function () { + var fileInputClones, + paramNames = $.isArray(options.paramName) + ? options.paramName + : [options.paramName]; + iframe.off('load').on('load', function () { + var response; + // Wrap in a try/catch block to catch exceptions thrown + // when trying to access cross-domain iframe contents: + try { + response = iframe.contents(); + // Google Chrome and Firefox do not throw an + // exception when calling iframe.contents() on + // cross-domain requests, so we unify the response: + if (!response.length || !response[0].firstChild) { + throw new Error(); } - // The complete callback returns the - // iframe content document as response object: - completeCallback(200, 'success', { iframe: response }); - // Fix for IE endless progress bar activity bug - // (happens on form submits to iframe targets): - $('').appendTo( - form - ); - window.setTimeout(function () { - // Removing the form in a setTimeout call - // allows Chrome's developer tools to display - // the response result - form.remove(); - }, 0); - }); - form - .prop('target', iframe.prop('name')) - .prop('action', options.url) - .prop('method', options.type); - if (options.formData) { - $.each(options.formData, function (index, field) { - $('') - .prop('name', field.name) - .val(field.value) - .appendTo(form); - }); + } catch (e) { + response = undefined; } - if ( - options.fileInput && - options.fileInput.length && - options.type === 'POST' - ) { - fileInputClones = options.fileInput.clone(); - // Insert a clone for each file input field: - options.fileInput.after(function (index) { - return fileInputClones[index]; - }); - if (options.paramName) { - options.fileInput.each(function (index) { - $(this).prop('name', paramNames[index] || options.paramName); - }); - } - // Appending the file input fields to the hidden form - // removes them from their original location: + // The complete callback returns the + // iframe content document as response object: + completeCallback(200, 'success', { iframe: response }); + // Fix for IE endless progress bar activity bug + // (happens on form submits to iframe targets): + $('').appendTo( form - .append(options.fileInput) - .prop('enctype', 'multipart/form-data') - // enctype must be set as encoding for IE: - .prop('encoding', 'multipart/form-data'); - // Remove the HTML5 form attribute from the input(s): - options.fileInput.removeAttr('form'); - } + ); window.setTimeout(function () { - // Submitting the form in a setTimeout call fixes an issue with - // Safari 13 not triggering the iframe load event after resetting - // the load event handler, see also: - // https://github.com/blueimp/jQuery-File-Upload/issues/3633 - form.submit(); - // Insert the file input fields at their original location - // by replacing the clones with the originals: - if (fileInputClones && fileInputClones.length) { - options.fileInput.each(function (index, input) { - var clone = $(fileInputClones[index]); - // Restore the original name and form properties: - $(input) - .prop('name', clone.prop('name')) - .attr('form', clone.attr('form')); - clone.replaceWith(input); - }); - } + // Removing the form in a setTimeout call + // allows Chrome's developer tools to display + // the response result + form.remove(); }, 0); }); - form.append(iframe).appendTo(document.body); - }, - abort: function () { - if (iframe) { - // javascript:false as iframe src aborts the request - // and prevents warning popups on HTTPS in IE6. - iframe.off('load').prop('src', initialIframeSrc); + form + .prop('target', iframe.prop('name')) + .prop('action', options.url) + .prop('method', options.type); + if (options.formData) { + $.each(options.formData, function (index, field) { + $('') + .prop('name', field.name) + .val(field.value) + .appendTo(form); + }); } - if (form) { - form.remove(); + if ( + options.fileInput && + options.fileInput.length && + options.type === 'POST' + ) { + fileInputClones = options.fileInput.clone(); + // Insert a clone for each file input field: + options.fileInput.after(function (index) { + return fileInputClones[index]; + }); + if (options.paramName) { + options.fileInput.each(function (index) { + $(this).prop('name', paramNames[index] || options.paramName); + }); + } + // Appending the file input fields to the hidden form + // removes them from their original location: + form + .append(options.fileInput) + .prop('enctype', 'multipart/form-data') + // enctype must be set as encoding for IE: + .prop('encoding', 'multipart/form-data'); + // Remove the HTML5 form attribute from the input(s): + options.fileInput.removeAttr('form'); } - } - }; - } - }); - - // The iframe transport returns the iframe content document as response. - // The following adds converters from iframe to text, json, html, xml - // and script. - // Please note that the Content-Type for JSON responses has to be text/plain - // or text/html, if the browser doesn't include application/json in the - // Accept header, else IE will show a download dialog. - // The Content-Type for XML responses on the other hand has to be always - // application/xml or text/xml, so IE properly parses the XML response. - // See also - // https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation - $.ajaxSetup({ - converters: { - 'iframe text': function (iframe) { - return iframe && $(iframe[0].body).text(); - }, - 'iframe json': function (iframe) { - return iframe && jsonAPI[jsonParse]($(iframe[0].body).text()); - }, - 'iframe html': function (iframe) { - return iframe && $(iframe[0].body).html(); - }, - 'iframe xml': function (iframe) { - var xmlDoc = iframe && iframe[0]; - return xmlDoc && $.isXMLDoc(xmlDoc) - ? xmlDoc - : $.parseXML( - (xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) || - $(xmlDoc.body).html() - ); + window.setTimeout(function () { + // Submitting the form in a setTimeout call fixes an issue with + // Safari 13 not triggering the iframe load event after resetting + // the load event handler, see also: + // https://github.com/blueimp/jQuery-File-Upload/issues/3633 + form.submit(); + // Insert the file input fields at their original location + // by replacing the clones with the originals: + if (fileInputClones && fileInputClones.length) { + options.fileInput.each(function (index, input) { + var clone = $(fileInputClones[index]); + // Restore the original name and form properties: + $(input) + .prop('name', clone.prop('name')) + .attr('form', clone.attr('form')); + clone.replaceWith(input); + }); + } + }, 0); + }); + form.append(iframe).appendTo(document.body); }, - 'iframe script': function (iframe) { - return iframe && $.globalEval($(iframe[0].body).text()); + abort: function () { + if (iframe) { + // javascript:false as iframe src aborts the request + // and prevents warning popups on HTTPS in IE6. + iframe.off('load').prop('src', initialIframeSrc); + } + if (form) { + form.remove(); + } } + }; + } + }); + + // The iframe transport returns the iframe content document as response. + // The following adds converters from iframe to text, json, html, xml + // and script. + // Please note that the Content-Type for JSON responses has to be text/plain + // or text/html, if the browser doesn't include application/json in the + // Accept header, else IE will show a download dialog. + // The Content-Type for XML responses on the other hand has to be always + // application/xml or text/xml, so IE properly parses the XML response. + // See also + // https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation + $.ajaxSetup({ + converters: { + 'iframe text': function (iframe) { + return iframe && $(iframe[0].body).text(); + }, + 'iframe json': function (iframe) { + return iframe && jsonAPI[jsonParse]($(iframe[0].body).text()); + }, + 'iframe html': function (iframe) { + return iframe && $(iframe[0].body).html(); + }, + 'iframe xml': function (iframe) { + var xmlDoc = iframe && iframe[0]; + return xmlDoc && $.isXMLDoc(xmlDoc) + ? xmlDoc + : $.parseXML( + (xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) || + $(xmlDoc.body).html() + ); + }, + 'iframe script': function (iframe) { + return iframe && $.globalEval($(iframe[0].body).text()); } - }); - }); \ No newline at end of file + } + }); +}); diff --git a/pod/video/templates/channel/channel.html b/pod/video/templates/channel/channel.html index ea8356a8ea..34e3f5e2d8 100644 --- a/pod/video/templates/channel/channel.html +++ b/pod/video/templates/channel/channel.html @@ -36,7 +36,7 @@ {% endblock %} -{% block breadcrumbs %}{{ block.super }} +{% block breadcrumbs %}{{ block.super }} {% if theme %} {% for t in theme.get_all_parents reversed %} @@ -58,45 +58,47 @@

{{channel.title}} {% if theme %} - {% if USE_STATS_VIEW %} - {% trans 'Statistics views' %} - {% endif %} -  Video -  Audio + {% if USE_STATS_VIEW %} + {% trans 'Statistics views' %} + {% endif %} +  Video +  Audio {% else %} - {% if USE_STATS_VIEW %} - {% trans 'Statistics views' %} - {% endif %} -  Video -  Audio + {% if USE_STATS_VIEW %} + {% trans 'Statistics views' %} + {% endif %} +  Video +  Audio {% endif %} {% if request.user in channel.owners.all %} - -  {% trans "Edit the channel"%} {%endif%}

+ +  {% trans "Edit the channel"%}  + {%endif%} + {% if channel.headband %} - {% trans 'Headband' %} {{ channel.title }} + {% trans 'Headband' %} {{ channel.title }} {% endif %} {% if channel.description %} - {{ channel.description|safe }} + {{ channel.description|safe }} {% endif %} {% if theme %} -

{{theme.title}}

- {% if theme.headband %} -
- {% trans 'Headband' %} {{ theme.title }} -
- {% endif %} - {% if theme.description %} +

{{theme.title}}

+ {% if theme.headband %} +
+ {% trans 'Headband' %} {{ theme.title }} +
+ {% endif %} + {% if theme.description %} {{ theme.description|safe }} - {% endif %} + {% endif %} {%endif%}

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

- {% if organize_theme %} + {% if organize_theme %} {% for t_obj, videos in videos_theme %}
{% if t_obj|isinstance:"Theme" %} @@ -174,9 +176,9 @@
diff --git a/pod/video/templates/videos/footer_link.html b/pod/video/templates/videos/footer_link.html index c3aaeb57f2..708259b8d8 100644 --- a/pod/video/templates/videos/footer_link.html +++ b/pod/video/templates/videos/footer_link.html @@ -1,12 +1,11 @@ {% load i18n %} - - \ No newline at end of file diff --git a/pod/video/templates/videos/video_list.html b/pod/video/templates/videos/video_list.html index 0843e731d9..a767a10408 100644 --- a/pod/video/templates/videos/video_list.html +++ b/pod/video/templates/videos/video_list.html @@ -1,20 +1,20 @@ {% load i18n %} {% spaceless %}
- {% for video in videos %} + {% for video in videos %}
- {% include "videos/card.html" %} -
- {% empty %} -
-

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

-
- {% endfor %} + {% include "videos/card.html" %} +
+ {% empty %} +
+

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

+
+ {% endfor %}
{% if videos.has_next %} - More + {% trans "More" %} {% endif %} {% endspaceless %} From 2b50cc034e82c9e64c01de450445b917d01c4598 Mon Sep 17 00:00:00 2001 From: Olivier Bado Date: Fri, 5 Mar 2021 16:48:12 +0100 Subject: [PATCH 058/261] [bugfix] correct a bug in video_search/views.py causing user using a recorded url pointing to a previous video_search where some tags no more exists cause a 500 error. + update .po/mo strings + some code formatting --- .../interactive/edit_interactive.html | 4 +- pod/locale/fr/LC_MESSAGES/django.mo | Bin 97469 -> 97682 bytes pod/locale/fr/LC_MESSAGES/django.po | 525 +++++++++--------- pod/locale/nl/LC_MESSAGES/django.po | 515 ++++++++--------- pod/video/models.py | 3 +- pod/video/templates/videos/video-script.html | 4 +- pod/video_search/views.py | 3 +- 7 files changed, 540 insertions(+), 514 deletions(-) diff --git a/pod/interactive/templates/interactive/edit_interactive.html b/pod/interactive/templates/interactive/edit_interactive.html index f078aab30a..947bc557c9 100644 --- a/pod/interactive/templates/interactive/edit_interactive.html +++ b/pod/interactive/templates/interactive/edit_interactive.html @@ -249,7 +249,5 @@
 {% trans "Manag $('#ieditor').contents().find('#submit_editor').hide(); }); - - -{% endblock more_script %} \ No newline at end of file +{% endblock more_script %} diff --git a/pod/locale/fr/LC_MESSAGES/django.mo b/pod/locale/fr/LC_MESSAGES/django.mo index af859ec21886962bffd04ef9183661ad0e9d26a6..a5f5aa016227e49301150bb2268e77e88701beea 100644 GIT binary patch delta 24274 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 delta 24057 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\n" "Language-Team: \n" @@ -29,7 +29,7 @@ msgstr "Etablissement" #: pod/bbb/models.py:141 pod/main/templates/navbar.html:22 #: pod/main/templates/navbar_collapse.html:76 pod/podfile/models.py:37 #: pod/video/forms.py:236 pod/video/forms.py:589 pod/video/forms.py:593 -#: pod/video/models.py:248 pod/video/templates/videos/filter_aside.html:13 +#: pod/video/models.py:253 pod/video/templates/videos/filter_aside.html:13 msgid "Users" msgstr "Utilisateurs" @@ -90,7 +90,7 @@ msgid "registered-reader" msgstr "lecteur enregistré" #: pod/authentication/models.py:68 pod/recorder/models.py:266 -#: pod/video/models.py:1421 pod/video/models.py:1473 pod/video/views.py:1301 +#: pod/video/models.py:1465 pod/video/models.py:1517 pod/video/views.py:1303 msgid "Comment" msgstr "Commentaire" @@ -163,8 +163,8 @@ msgstr "Changer votre image de profil" #: pod/video/templates/videos/video_note_comments_display.html:148 #: pod/video/templates/videos/video_note_display.html:27 #: pod/video/templates/videos/video_notes.html:80 -#: pod/video/templates/videos/video_notes.html:116 pod/video/views.py:254 -#: pod/video/views.py:737 pod/video/views.py:791 pod/video/views.py:1221 +#: pod/video/templates/videos/video_notes.html:116 pod/video/views.py:255 +#: pod/video/views.py:739 pod/video/views.py:793 pod/video/views.py:1223 #: pod/video_search/templates/search/search.html:50 msgid "One or more errors have been found in the form." msgstr "Une ou plusieurs erreurs ont été trouvées dans le formulaire." @@ -191,7 +191,7 @@ msgid "Please provide a valid value for this field" msgstr "Veuillez renseigner une valeur valide pour ce champ" #: pod/authentication/templates/userpicture/userpicture.html:56 -#: pod/bbb/templates/bbb/list_meeting.html:44 pod/main/templates/base.html:114 +#: pod/bbb/templates/bbb/list_meeting.html:44 pod/main/templates/base.html:113 #: pod/main/templates/navbar_collapse.html:43 #: pod/main/templates/navbar_collapse.html:66 #: pod/main/templates/navbar_collapse.html:100 @@ -234,7 +234,7 @@ msgstr "Nom de la session BBB." msgid "Session date" msgstr "Date de session" -#: pod/bbb/models.py:40 pod/video/models.py:646 pod/video/models.py:1327 +#: pod/bbb/models.py:40 pod/video/models.py:653 pod/video/models.py:1371 msgid "Encoding step" msgstr "Étape de l'encodage" @@ -343,7 +343,7 @@ msgstr "Publier cette présentation" msgid "Waiting for encoding" msgstr "En attente d'encodage" -#: pod/bbb/templates/bbb/card.html:40 pod/video/models.py:575 +#: pod/bbb/templates/bbb/card.html:40 pod/video/models.py:580 msgid "Encoding in progress" msgstr "Encodage en cours" @@ -460,24 +460,24 @@ msgid "File to import" msgstr "Fichier à importer" #: pod/chapter/models.py:14 pod/completion/models.py:53 -#: pod/enrichment/models.py:114 pod/video/models.py:591 +#: pod/enrichment/models.py:114 pod/video/models.py:596 msgid "video" msgstr "vidéo" #: pod/chapter/models.py:15 pod/enrichment/models.py:115 -#: pod/recorder/models.py:259 pod/video/models.py:423 +#: pod/recorder/models.py:259 pod/video/models.py:428 msgid "title" msgstr "titre" #: pod/chapter/models.py:17 pod/enrichment/models.py:117 -#: pod/video/models.py:425 +#: pod/video/models.py:430 msgid "slug" msgstr "titre court" #: pod/chapter/models.py:20 pod/completion/models.py:262 #: pod/enrichment/models.py:120 pod/live/models.py:71 pod/playlist/models.py:17 -#: pod/video/models.py:224 pod/video/models.py:308 pod/video/models.py:401 -#: pod/video/models.py:427 pod/video/models.py:468 pod/video/models.py:1539 +#: pod/video/models.py:229 pod/video/models.py:313 pod/video/models.py:406 +#: pod/video/models.py:432 pod/video/models.py:473 pod/video/models.py:1583 msgid "" "Used to access this instance, the \"slug\" is a short label containing only " "letters, numbers, underscore or dash top." @@ -580,8 +580,8 @@ msgstr "Liste des chapitres" #: pod/enrichment/templates/enrichment/list_enrichment.html:10 #: pod/main/models.py:103 pod/main/views.py:165 pod/playlist/models.py:12 #: pod/playlist/templates/playlist/playlist_element_list.html:11 -#: pod/video/models.py:215 pod/video/models.py:301 pod/video/models.py:397 -#: pod/video/models.py:460 pod/video/templates/channel/list_theme.html:9 +#: pod/video/models.py:220 pod/video/models.py:306 pod/video/models.py:402 +#: pod/video/models.py:465 pod/video/templates/channel/list_theme.html:9 msgid "Title" msgstr "Titre" @@ -593,7 +593,7 @@ msgstr "Éditer le chapitre" #: pod/completion/templates/track/list_track.html:23 #: pod/completion/templates/track/list_track.html:42 #: pod/enrichment/templates/enrichment/list_enrichment.html:30 -#: pod/podfile/templates/podfile/list_folder_files.html:249 +#: pod/podfile/templates/podfile/list_folder_files.html:251 #: pod/video/templates/channel/list_theme.html:27 msgid "Modify" msgstr "Modifier" @@ -606,7 +606,7 @@ msgstr "Supprimer le chapitre" #: pod/enrichment/templates/enrichment/list_enrichment.html:38 #: pod/playlist/templates/playlist.html:68 #: pod/podfile/templates/podfile/list_folder_files.html:104 -#: pod/podfile/templates/podfile/list_folder_files.html:297 +#: pod/podfile/templates/podfile/list_folder_files.html:299 #: pod/recorder/templates/recorder/record_delete.html:9 #: pod/video/templates/channel/list_theme.html:35 #: pod/video/templates/videos/category_modal.html:66 @@ -659,7 +659,7 @@ msgstr "Ajouter un nouveau chapitre" #: pod/enrichment/templates/enrichment/group_enrichment.html:71 #: pod/interactive/templates/interactive/edit_interactive.html:128 #: pod/interactive/templates/interactive/group_interactive.html:71 -#: pod/video/templates/videos/video.html:251 +#: pod/video/templates/videos/video.html:248 #: pod/video/templates/videos/video_edit.html:143 msgid "Manage video" msgstr "Gérer la vidéo" @@ -808,10 +808,10 @@ msgstr "" #: pod/completion/templates/video_caption_maker.html:85 #: pod/enrichment/models.py:291 pod/enrichment/models.py:322 #: pod/interactive/models.py:16 pod/interactive/models.py:37 -#: pod/playlist/models.py:79 pod/recorder/models.py:78 pod/video/models.py:456 -#: pod/video/models.py:957 pod/video/models.py:1105 pod/video/models.py:1173 -#: pod/video/models.py:1227 pod/video/models.py:1276 pod/video/models.py:1294 -#: pod/video/models.py:1315 +#: pod/playlist/models.py:79 pod/recorder/models.py:78 pod/video/models.py:461 +#: pod/video/models.py:1001 pod/video/models.py:1149 pod/video/models.py:1217 +#: pod/video/models.py:1271 pod/video/models.py:1320 pod/video/models.py:1338 +#: pod/video/models.py:1359 msgid "Video" msgstr "Vidéo" @@ -917,8 +917,8 @@ msgid "left" msgstr "gauche" #: pod/completion/models.py:259 pod/live/models.py:69 pod/playlist/models.py:14 -#: pod/video/models.py:222 pod/video/models.py:306 pod/video/models.py:399 -#: pod/video/models.py:466 pod/video/models.py:1537 +#: pod/video/models.py:227 pod/video/models.py:311 pod/video/models.py:404 +#: pod/video/models.py:471 pod/video/models.py:1581 msgid "Slug" msgstr "Titre court" @@ -934,7 +934,7 @@ msgstr "Fin" msgid "End time of the overlay, in seconds." msgstr "Fin de la superposition, en secondes." -#: pod/completion/models.py:279 pod/video/views.py:1330 +#: pod/completion/models.py:279 pod/video/views.py:1332 msgid "Content" msgstr "Contenu" @@ -1362,7 +1362,7 @@ msgstr "Le fichier n’a pas été enregistré." #: pod/completion/views.py:237 pod/completion/views.py:413 #: pod/completion/views.py:814 pod/podfile/views.py:470 -#: pod/podfile/views.py:520 pod/video/views.py:344 pod/video/views.py:1379 +#: pod/podfile/views.py:520 pod/video/views.py:345 pod/video/views.py:1381 msgid "Please correct errors" msgstr "Veuillez corriger les erreurs" @@ -1390,7 +1390,7 @@ msgstr "Éditer l'enrichissement" #: pod/enrichment/forms.py:35 pod/enrichment/models.py:326 #: pod/interactive/forms.py:13 pod/interactive/models.py:41 -#: pod/podfile/models.py:33 pod/recorder/models.py:161 pod/video/models.py:557 +#: pod/podfile/models.py:33 pod/recorder/models.py:161 pod/video/models.py:562 msgid "Groups" msgstr "Groupes" @@ -1432,8 +1432,8 @@ msgstr "Temps de fin de l'affichage de l'enrichissement en secondes." #: pod/enrichment/models.py:137 #: pod/enrichment/templates/enrichment/list_enrichment.html:11 -#: pod/video/forms.py:103 pod/video/models.py:418 pod/video/models.py:473 -#: pod/video/views.py:1327 pod/video_search/templates/search/search.html:87 +#: pod/video/forms.py:103 pod/video/models.py:423 pod/video/models.py:478 +#: pod/video/views.py:1329 pod/video_search/templates/search/search.html:87 msgid "Type" msgstr "Type" @@ -1618,7 +1618,7 @@ msgstr "Enrichi" #: pod/enrichment/templates/enrichment/video_enrichment.html:60 #: pod/interactive/templates/interactive/video_interactive.html:47 -#: pod/video/templates/videos/video.html:153 +#: pod/video/templates/videos/video.html:150 msgid "Report the video" msgstr "Signaler la vidéo" @@ -1627,8 +1627,8 @@ msgstr "Signaler la vidéo" #: pod/interactive/templates/interactive/video_interactive.html:56 #: pod/interactive/templates/interactive/video_interactive.html:57 #: pod/video/templates/videos/video-info.html:9 -#: pod/video/templates/videos/video.html:168 -#: pod/video/templates/videos/video.html:169 +#: pod/video/templates/videos/video.html:165 +#: pod/video/templates/videos/video.html:166 msgid "Summary" msgstr "Description" @@ -1637,9 +1637,9 @@ msgstr "Description" #: pod/interactive/templates/interactive/video_interactive.html:61 #: pod/interactive/templates/interactive/video_interactive.html:62 #: pod/video/templates/videos/video-info.html:36 -#: pod/video/templates/videos/video.html:175 -#: pod/video/templates/videos/video.html:177 -#: pod/video/templates/videos/video.html:179 +#: pod/video/templates/videos/video.html:172 +#: pod/video/templates/videos/video.html:174 +#: pod/video/templates/videos/video.html:176 msgid "Infos" msgstr "Informations" @@ -1648,8 +1648,8 @@ msgstr "Informations" #: pod/interactive/templates/interactive/video_interactive.html:67 #: pod/interactive/templates/interactive/video_interactive.html:68 #: pod/video/templates/videos/video-info.html:156 -#: pod/video/templates/videos/video.html:184 -#: pod/video/templates/videos/video.html:185 +#: pod/video/templates/videos/video.html:181 +#: pod/video/templates/videos/video.html:182 msgid "Downloads" msgstr "Téléchargements" @@ -1658,8 +1658,8 @@ msgstr "Téléchargements" #: pod/interactive/templates/interactive/video_interactive.html:73 #: pod/interactive/templates/interactive/video_interactive.html:74 #: pod/video/templates/videos/video-info.html:198 -#: pod/video/templates/videos/video.html:191 -#: pod/video/templates/videos/video.html:192 +#: pod/video/templates/videos/video.html:188 +#: pod/video/templates/videos/video.html:189 msgid "Embed/Share" msgstr "Intégrer/Partager" @@ -1667,8 +1667,8 @@ msgstr "Intégrer/Partager" #: pod/enrichment/templates/enrichment/video_enrichment.html:93 #: pod/interactive/templates/interactive/video_interactive.html:85 #: pod/interactive/templates/interactive/video_interactive.html:86 -#: pod/video/templates/videos/video.html:199 -#: pod/video/templates/videos/video.html:200 +#: pod/video/templates/videos/video.html:196 +#: pod/video/templates/videos/video.html:197 msgid "Other versions" msgstr "Autre version" @@ -1682,7 +1682,7 @@ msgstr "Version originale" #: pod/enrichment/templates/enrichment/video_enrichment.html:105 #: pod/interactive/templates/interactive/video_interactive.html:100 -#: pod/video/templates/videos/video.html:217 +#: pod/video/templates/videos/video.html:214 msgid "Add the video to a playlist" msgstr "Ajouter une vidéo à une liste de lecture" @@ -1692,7 +1692,7 @@ msgstr "Ajouter une vidéo à une liste de lecture" #: pod/playlist/templates/my_playlists.html:10 #: pod/playlist/templates/my_playlists.html:17 #: pod/playlist/templates/playlist.html:14 -#: pod/video/templates/videos/video.html:218 +#: pod/video/templates/videos/video.html:215 msgid "My playlists" msgstr "Mes listes de lecture" @@ -1748,11 +1748,11 @@ msgstr "Chargement, veuillez patienter..." #: pod/interactive/templates/interactive/edit_interactive.html:47 #: pod/interactive/templates/interactive/edit_interactive.html:49 -#: pod/interactive/templates/interactive/edit_interactive.html:56 msgid "Delete the interactive part of this video" msgstr "Supprimer la version interactive de cette vidéo" #: pod/interactive/templates/interactive/edit_interactive.html:54 +#: pod/interactive/templates/interactive/edit_interactive.html:56 #: pod/interactive/templates/interactive/edit_interactive.html:66 #: pod/interactive/templates/interactive/edit_interactive.html:68 msgid "Back" @@ -1763,23 +1763,21 @@ msgstr "Retour" msgid "Manage scores" msgstr "Gérer les scores" -#: pod/interactive/templates/interactive/edit_interactive.html:77 -#: pod/interactive/templates/interactive/edit_interactive.html:78 +#: pod/interactive/templates/interactive/edit_interactive.html:79 #: pod/interactive/templates/interactive/edit_interactive.html:96 -#: pod/interactive/templates/interactive/edit_interactive.html:97 +#: pod/interactive/templates/interactive/edit_interactive.html:98 msgid "Save and continue" msgstr "Sauvegarder et continuer" -#: pod/interactive/templates/interactive/edit_interactive.html:81 +#: pod/interactive/templates/interactive/edit_interactive.html:83 +#: pod/interactive/templates/interactive/edit_interactive.html:102 +msgid "Save and see the interactive video" +msgstr "Sauvegarder et voir la vidéo interactive" + #: pod/interactive/templates/interactive/edit_interactive.html:100 msgid "Save and return to video" msgstr "Sauvegarder et voir la video" -#: pod/interactive/templates/interactive/edit_interactive.html:82 -#: pod/interactive/templates/interactive/edit_interactive.html:101 -msgid "Save and see the interactive video" -msgstr "Sauvegarder et voir la vidéo interactive" - #: pod/interactive/templates/interactive/edit_interactive.html:120 msgid "" "Do not forget to save your work regularly. Especially if you add an " @@ -1881,9 +1879,9 @@ msgid "name" msgstr "nom" #: pod/live/models.py:31 pod/live/templates/live/live.html:94 -#: pod/video/models.py:235 pod/video/models.py:319 -#: pod/video/templates/channel/channel.html:79 -#: pod/video/templates/channel/channel.html:90 +#: pod/video/models.py:240 pod/video/models.py:324 +#: pod/video/templates/channel/channel.html:81 +#: pod/video/templates/channel/channel.html:92 #: pod/video/templates/channel/channel_edit.html:38 #: pod/video/templates/videos/video.html:100 #: pod/video/templates/videos/video.html:109 @@ -1952,7 +1950,7 @@ msgid "Enable viewers count on live." msgstr "Active le compteur de spectateurs sur le direct." #: pod/live/models.py:102 pod/recorder/models.py:155 pod/video/forms.py:186 -#: pod/video/models.py:551 +#: pod/video/models.py:556 msgid "Restricted access" msgstr "Accès restreint" @@ -1972,7 +1970,7 @@ msgstr "" "Si cette case est cochée, la page du direct sera accessible publiquement " "dans l'onglet Directs" -#: pod/live/models.py:112 pod/recorder/models.py:164 pod/video/models.py:560 +#: pod/live/models.py:112 pod/recorder/models.py:164 pod/video/models.py:565 msgid "password" msgstr "mot de passe" @@ -2019,7 +2017,7 @@ msgstr "Signaux" msgid "Lives" msgstr "Directs" -#: pod/live/templates/live/building.html:39 +#: pod/live/templates/live/building.html:38 #: pod/live/templates/live/live.html:104 pod/live/templates/live/lives.html:37 msgid "Sorry, no lives found" msgstr "Désolé, aucun direct trouvé" @@ -2090,7 +2088,7 @@ msgstr "Désolé, aucun bâtiment trouvé" msgid "You cannot view this page." msgstr "Vous ne pouvez pas éditer cette image." -#: pod/live/views.py:91 pod/video/views.py:647 +#: pod/live/views.py:91 pod/video/views.py:649 msgid "The password is incorrect." msgstr "Le mot de passe est incorrect." @@ -2135,8 +2133,8 @@ msgid "Other (please specify)" msgstr "Autre (spécifiez)" #: pod/main/forms.py:50 pod/podfile/models.py:27 pod/podfile/models.py:105 -#: pod/podfile/templates/podfile/home_content.html:32 pod/video/models.py:1098 -#: pod/video/models.py:1170 pod/video/models.py:1224 +#: pod/podfile/templates/podfile/home_content.html:32 pod/video/models.py:1142 +#: pod/video/models.py:1214 pod/video/models.py:1268 msgid "Name" msgstr "Nom" @@ -2150,7 +2148,7 @@ msgstr "Veuillez choisir un sujet en lien avec votre requête" #: pod/main/forms.py:60 pod/main/models.py:142 pod/playlist/models.py:22 #: pod/video/forms.py:113 pod/video/forms.py:227 pod/video/forms.py:253 -#: pod/video/models.py:228 pod/video/models.py:312 pod/video/models.py:494 +#: pod/video/models.py:233 pod/video/models.py:317 pod/video/models.py:499 msgid "Description" msgstr "Description" @@ -2852,27 +2850,27 @@ msgid "Share on" msgstr "Partager sur" #: pod/main/templates/aside.html:21 pod/main/templates/aside.html:27 -#: pod/recorder/models.py:188 pod/video/forms.py:136 pod/video/models.py:445 -#: pod/video/models.py:523 pod/video/templates/videos/filter_aside.html:56 +#: pod/recorder/models.py:188 pod/video/forms.py:136 pod/video/models.py:450 +#: pod/video/models.py:528 pod/video/templates/videos/filter_aside.html:56 msgid "Disciplines" msgstr "Disciplines" #: pod/main/templates/aside.html:40 pod/recorder/models.py:184 -#: pod/video/forms.py:132 pod/video/models.py:519 +#: pod/video/forms.py:132 pod/video/models.py:524 #: pod/video/templates/videos/filter_aside.html:78 #: pod/video_search/templates/search/search.html:99 msgid "Tags" msgstr "Mots clés" -#: pod/main/templates/base.html:68 +#: pod/main/templates/base.html:66 msgid "Breadcrumb" msgstr "Fil d’Ariane" -#: pod/main/templates/base.html:71 +#: pod/main/templates/base.html:69 msgid "Home" msgstr "Accueil" -#: pod/main/templates/base.html:76 +#: pod/main/templates/base.html:74 msgid "Toggle side Menu" msgstr "Afficher/masquer le menu latéral" @@ -2915,7 +2913,7 @@ msgstr "ESUP-Portail" msgid "Pod Project" msgstr "Projet Pod" -#: pod/main/templates/footer.html:34 pod/video/feeds.py:107 +#: pod/main/templates/footer.html:34 pod/video/feeds.py:108 msgid "video platform of" msgstr "plateforme vidéos de" @@ -2972,11 +2970,11 @@ msgid "Return to homepage" msgstr "Revenir à la page d'accueil" #: pod/main/templates/navbar.html:17 pod/recorder/models.py:194 -#: pod/video/forms.py:172 pod/video/models.py:261 pod/video/models.py:529 +#: pod/video/forms.py:172 pod/video/models.py:266 pod/video/models.py:534 msgid "Channels" msgstr "Chaînes" -#: pod/main/templates/navbar.html:27 pod/video/models.py:419 +#: pod/main/templates/navbar.html:27 pod/video/models.py:424 #: pod/video/templates/videos/filter_aside.html:34 msgid "Types" msgstr "Types" @@ -3076,7 +3074,7 @@ msgstr "Votre message a été envoyé." #: pod/playlist/models.py:20 #: pod/playlist/templates/playlist/playlist_element_list.html:12 -#: pod/podfile/models.py:30 pod/video/admin.py:168 pod/video/models.py:477 +#: pod/podfile/models.py:30 pod/video/admin.py:168 pod/video/models.py:482 #: pod/video_search/templates/search/search.html:75 msgid "Owner" msgstr "Propriétaire" @@ -3085,7 +3083,7 @@ msgstr "Propriétaire" msgid "Short description of the playlist." msgstr "Courte description de la liste de lecture." -#: pod/playlist/models.py:28 pod/video/models.py:251 +#: pod/playlist/models.py:28 pod/video/models.py:256 msgid "Visible" msgstr "Visible" @@ -3195,7 +3193,7 @@ msgid "Thumbnail" msgstr "Vignette" #: pod/playlist/templates/playlist/playlist_element_list.html:13 -#: pod/video/feeds.py:188 pod/video/models.py:569 pod/video/models.py:706 +#: pod/video/feeds.py:189 pod/video/models.py:574 pod/video/models.py:719 msgid "Duration" msgstr "Durée" @@ -3302,26 +3300,26 @@ msgid "Change file" msgstr "Changer de fichier" #: pod/podfile/templates/podfile/customfilewidget.html:30 -#: pod/podfile/templates/podfile/customfilewidget.html:47 -#: pod/podfile/templates/podfile/customfilewidget.html:107 +#: pod/podfile/templates/podfile/customfilewidget.html:46 +#: pod/podfile/templates/podfile/customfilewidget.html:106 msgid "Remove image" msgstr "Retirer l’image" #: pod/podfile/templates/podfile/customfilewidget.html:32 -#: pod/podfile/templates/podfile/customfilewidget.html:49 -#: pod/podfile/templates/podfile/customfilewidget.html:109 +#: pod/podfile/templates/podfile/customfilewidget.html:48 +#: pod/podfile/templates/podfile/customfilewidget.html:108 msgid "Remove file" msgstr "Retirer le fichier" -#: pod/podfile/templates/podfile/customfilewidget.html:40 -#: pod/podfile/templates/podfile/customfilewidget.html:61 -#: pod/podfile/templates/podfile/customfilewidget.html:100 +#: pod/podfile/templates/podfile/customfilewidget.html:39 +#: pod/podfile/templates/podfile/customfilewidget.html:60 +#: pod/podfile/templates/podfile/customfilewidget.html:99 msgid "Select an image" msgstr "Sélectionner une image" -#: pod/podfile/templates/podfile/customfilewidget.html:42 -#: pod/podfile/templates/podfile/customfilewidget.html:61 -#: pod/podfile/templates/podfile/customfilewidget.html:102 +#: pod/podfile/templates/podfile/customfilewidget.html:41 +#: pod/podfile/templates/podfile/customfilewidget.html:60 +#: pod/podfile/templates/podfile/customfilewidget.html:101 msgid "Select a file" msgstr "Sélectionner un fichier" @@ -3331,7 +3329,7 @@ msgid "Enter new name of folder" msgstr "Indiquer un nouveau nom à ce dossier" #: pod/podfile/templates/podfile/home_content.html:53 -#: pod/podfile/templates/podfile/list_folder_files.html:187 +#: pod/podfile/templates/podfile/list_folder_files.html:189 #: pod/video/templates/videos/video_edit.html:119 msgid "Loading" msgstr "Chargement" @@ -3356,15 +3354,15 @@ msgstr "Entrer un nom d'utilsateur" msgid "Rename" msgstr "Renomer" -#: pod/podfile/templates/podfile/list_folder_files.html:134 +#: pod/podfile/templates/podfile/list_folder_files.html:135 msgid "Share this folder" msgstr "Partager ce dossier" -#: pod/podfile/templates/podfile/list_folder_files.html:177 +#: pod/podfile/templates/podfile/list_folder_files.html:179 msgid "Upload Files" msgstr "Téléverser des fichiers" -#: pod/podfile/templates/podfile/list_folder_files.html:271 +#: pod/podfile/templates/podfile/list_folder_files.html:273 msgid "Download" msgstr "Télécharger" @@ -3461,54 +3459,54 @@ msgstr "J'accepte" msgid "Delete this record cannot be undo" msgstr "La suppression d'un enregistrement est définitive" -#: pod/recorder/models.py:30 pod/video/models.py:63 +#: pod/recorder/models.py:30 pod/video/models.py:65 msgid "None / All" msgstr "Aucun / Tous" -#: pod/recorder/models.py:31 pod/video/models.py:64 +#: pod/recorder/models.py:31 pod/video/models.py:66 msgid "Bachelor’s Degree" msgstr "Licence" -#: pod/recorder/models.py:32 pod/video/models.py:65 +#: pod/recorder/models.py:32 pod/video/models.py:67 msgid "Master’s Degree" msgstr "Master" -#: pod/recorder/models.py:33 pod/video/models.py:66 +#: pod/recorder/models.py:33 pod/video/models.py:68 msgid "Doctorate" msgstr "Doctorat" -#: pod/recorder/models.py:34 pod/video/models.py:67 pod/video/views.py:159 +#: pod/recorder/models.py:34 pod/video/models.py:69 pod/video/views.py:160 msgid "Other" msgstr "Autre" -#: pod/recorder/models.py:39 pod/video/forms.py:147 pod/video/models.py:78 +#: pod/recorder/models.py:39 pod/video/forms.py:147 pod/video/models.py:82 msgid "Attribution 4.0 International (CC BY 4.0)" msgstr "Attribution 4.0 International (CC BY 4.0)" -#: pod/recorder/models.py:40 pod/video/forms.py:150 pod/video/models.py:79 +#: pod/recorder/models.py:40 pod/video/forms.py:150 pod/video/models.py:83 msgid "Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0)" msgstr "Attribution - Pas de Modification 4.0 International (CC BY-ND 4.0)" -#: pod/recorder/models.py:44 pod/video/forms.py:154 pod/video/models.py:83 +#: pod/recorder/models.py:44 pod/video/forms.py:154 pod/video/models.py:87 msgid "" "Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)" msgstr "" "Attribution - Pas d'Utilisation Commerciale - Pas de Modification 4.0 " "International (CC BY-NC-ND 4.0)" -#: pod/recorder/models.py:47 pod/video/forms.py:158 pod/video/models.py:86 +#: pod/recorder/models.py:47 pod/video/forms.py:158 pod/video/models.py:90 msgid "Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)" msgstr "" "Attribution - Pas d’Utilisation Commerciale 4.0 International (CC BY-NC 4.0)" -#: pod/recorder/models.py:50 pod/video/forms.py:163 pod/video/models.py:89 +#: pod/recorder/models.py:50 pod/video/forms.py:163 pod/video/models.py:93 msgid "" "Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)" msgstr "" "Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes " "Conditions 4.0 International (CC BY-NC-SA 4.0)" -#: pod/recorder/models.py:54 pod/video/forms.py:169 pod/video/models.py:93 +#: pod/recorder/models.py:54 pod/video/forms.py:169 pod/video/models.py:97 msgid "Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)" msgstr "" "Attribution - Partage dans les Mêmes Conditions 4.0 International (CC BY-SA " @@ -3566,11 +3564,11 @@ msgstr "" msgid "Video type by default." msgstr "Type par défaut des vidéos." -#: pod/recorder/models.py:148 pod/video/forms.py:182 pod/video/models.py:544 +#: pod/recorder/models.py:148 pod/video/forms.py:182 pod/video/models.py:549 msgid "Draft" msgstr "Brouillon" -#: pod/recorder/models.py:150 pod/video/models.py:546 +#: pod/recorder/models.py:150 pod/video/models.py:551 msgid "" "If this box is checked, the video will be visible and accessible only by you " "and the additional owners." @@ -3578,7 +3576,7 @@ msgstr "" "Si la case est cochée, la vidéo sera visible et accessible uniquement par " "vous et les propriétaires additionnels." -#: pod/recorder/models.py:157 pod/video/models.py:553 +#: pod/recorder/models.py:157 pod/video/models.py:558 msgid "" "If this box is checked, the video will only be accessible to authenticated " "users." @@ -3586,47 +3584,47 @@ msgstr "" "Si cette case est cochée, la vidéo sera uniquement accessible aux " "utilisateurs authentifiés." -#: pod/recorder/models.py:162 pod/video/models.py:558 +#: pod/recorder/models.py:162 pod/video/models.py:563 msgid "Select one or more groups who can access to this video" msgstr "Sélectionner un ou plusieurs groupes qui auront accès à cette vidéo" -#: pod/recorder/models.py:166 pod/video/models.py:562 +#: pod/recorder/models.py:166 pod/video/models.py:567 msgid "Viewing this video will not be possible without this password." msgstr "Voir cette vidéo n'est pas possible sans mot de passe." -#: pod/recorder/models.py:169 pod/video/forms.py:122 pod/video/models.py:504 +#: pod/recorder/models.py:169 pod/video/forms.py:122 pod/video/models.py:509 #: pod/video_search/templates/search/search.html:150 msgid "University course" msgstr "Cursus universitaire" -#: pod/recorder/models.py:171 pod/video/forms.py:123 pod/video/models.py:506 +#: pod/recorder/models.py:171 pod/video/forms.py:123 pod/video/models.py:511 msgid "Select an university course as audience target of the content." msgstr "" "Sélectionner un cursus universitaire qui convient à l'audience de ce contenu." -#: pod/recorder/models.py:174 pod/video/forms.py:129 pod/video/models.py:509 +#: pod/recorder/models.py:174 pod/video/forms.py:129 pod/video/models.py:514 #: pod/video_search/templates/search/search.html:137 msgid "Main language" msgstr "Langue principale" -#: pod/recorder/models.py:176 pod/video/forms.py:130 pod/video/models.py:511 +#: pod/recorder/models.py:176 pod/video/forms.py:130 pod/video/models.py:516 msgid "Select the main language used in the content." msgstr "Sélectionner la langue principalement utilisée dans ce contenu." -#: pod/recorder/models.py:178 pod/video/forms.py:201 pod/video/models.py:513 +#: pod/recorder/models.py:178 pod/video/forms.py:201 pod/video/models.py:518 #: pod/video/templates/videos/add_video.html:52 #: pod/video/templates/videos/add_video.html:98 msgid "Transcript" msgstr "Transcrire" -#: pod/recorder/models.py:179 pod/video/models.py:514 +#: pod/recorder/models.py:179 pod/video/models.py:519 #: pod/video/templates/videos/add_video.html:53 msgid "Check this box if you want to transcript the audio.(beta version)" msgstr "" "Cocher cette case si vous voulez transcrire l’audio (version bêta, voir aide " "dans la colonne de droite)" -#: pod/recorder/models.py:182 pod/video/models.py:517 +#: pod/recorder/models.py:182 pod/video/models.py:522 msgid "" "Separate tags with spaces, enclose the tags consist of several words in " "quotation marks." @@ -3634,47 +3632,47 @@ msgstr "" "Séparer les mots clés par des espaces, écrire les mots clés en plusieurs " "mots entre guillemets." -#: pod/recorder/models.py:190 pod/video/forms.py:143 pod/video/models.py:525 +#: pod/recorder/models.py:190 pod/video/forms.py:143 pod/video/models.py:530 msgid "Licence" msgstr "Licence" -#: pod/recorder/models.py:198 pod/video/forms.py:172 pod/video/models.py:392 -#: pod/video/models.py:533 +#: pod/recorder/models.py:198 pod/video/forms.py:172 pod/video/models.py:397 +#: pod/video/models.py:538 msgid "Themes" msgstr "Thèmes" #: pod/recorder/models.py:200 pod/video/forms.py:140 pod/video/forms.py:176 -#: pod/video/models.py:535 pod/video/models.py:1534 +#: pod/video/models.py:540 pod/video/models.py:1578 msgid "" "Hold down \"Control\", or \"Command\" on a Mac, to select more than one." msgstr "" "Maintenez \"Control\", ou \"Command\" sur un Mac, pour en sélectionner " "plusieurs." -#: pod/recorder/models.py:203 pod/video/models.py:538 +#: pod/recorder/models.py:203 pod/video/models.py:543 msgid "allow downloading" msgstr "autoriser le téléchargement" -#: pod/recorder/models.py:204 pod/video/models.py:539 +#: pod/recorder/models.py:204 pod/video/models.py:544 msgid "Check this box if you to allow downloading of the encoded files" msgstr "" "Cocher cette case si vous voulez autoriser le téléchargement des fichiers " "encodés" -#: pod/recorder/models.py:207 pod/video/models.py:540 +#: pod/recorder/models.py:207 pod/video/models.py:545 msgid "video 360" msgstr "vidéo 360" -#: pod/recorder/models.py:208 pod/video/models.py:541 +#: pod/recorder/models.py:208 pod/video/models.py:546 msgid "Check this box if you want to use the 360 player for the video" msgstr "" "Cocher cette case si vous voulez utiliser le lecteur 360 pour cette vidéo" -#: pod/recorder/models.py:211 pod/video/models.py:584 +#: pod/recorder/models.py:211 pod/video/models.py:589 msgid "Disable comment" msgstr "Désactiver les commentaires" -#: pod/recorder/models.py:213 pod/video/models.py:585 +#: pod/recorder/models.py:213 pod/video/models.py:590 msgid "Allows you to turn off all comments on this video." msgstr "Vous permet de désactiver les commentaires sur cette vidéo." @@ -3736,8 +3734,8 @@ msgstr "Fichier source de la vidéo publiée." msgid "File size" msgstr "Taille du fichier" -#: pod/recorder/models.py:320 pod/video/models.py:500 pod/video/models.py:1364 -#: pod/video/models.py:1423 +#: pod/recorder/models.py:320 pod/video/models.py:505 pod/video/models.py:1408 +#: pod/video/models.py:1467 msgid "Date added" msgstr "Date d'ajout" @@ -3921,7 +3919,7 @@ msgid "Transcript selected" msgstr "Transcription selectionnée" #: pod/video/admin.py:268 pod/video/forms.py:236 pod/video/forms.py:596 -#: pod/video/forms.py:598 pod/video/models.py:245 +#: pod/video/forms.py:598 pod/video/models.py:250 msgid "Owners" msgstr "Propriétaires" @@ -3929,12 +3927,12 @@ msgstr "Propriétaires" msgid "File field" msgstr "Fichier" -#: pod/video/forms.py:90 pod/video/models.py:458 +#: pod/video/forms.py:90 pod/video/models.py:463 #: pod/video/templates/videos/add_video.html:88 msgid "You can send an audio or video file." msgstr "Vous pouvez envoyer un fichier audio ou vidéo." -#: pod/video/forms.py:91 pod/video/views.py:1639 +#: pod/video/forms.py:91 pod/video/views.py:1644 #, python-format msgid "The following formats are supported: %s" msgstr "Les formats suivants sont supportés : %s" @@ -3977,7 +3975,7 @@ msgstr "" "n’apparaît pas dans la liste, veuillez temporairement choisir \"Autres\" et " "contactez-nous pour expliquer vos besoins." -#: pod/video/forms.py:108 pod/video/models.py:487 +#: pod/video/forms.py:108 pod/video/models.py:492 msgid "Additional owners" msgstr "Propriétaires additionels" @@ -3992,7 +3990,7 @@ msgstr "" "que vous sauf qu'ils ne peuvent pas supprimer cette vidéo." #: pod/video/forms.py:114 pod/video/forms.py:228 pod/video/forms.py:254 -#: pod/video/models.py:230 pod/video/models.py:313 pod/video/models.py:497 +#: pod/video/models.py:235 pod/video/models.py:318 pod/video/models.py:502 msgid "" "In this field you can describe your content, add all needed related " "information, and format the result using the toolbar." @@ -4105,11 +4103,11 @@ msgstr "" "Vous aurez probablement à améliorer ce fichier en utilisant l’outil de sous-" "titrage accessible sur la page de complétion de la video." -#: pod/video/forms.py:232 pod/video/models.py:242 +#: pod/video/forms.py:232 pod/video/models.py:247 msgid "Extra style" msgstr "Style supplémentaire" -#: pod/video/forms.py:232 pod/video/models.py:237 +#: pod/video/forms.py:232 pod/video/models.py:242 msgid "Background color" msgstr "Couleur d'arrière-plan" @@ -4261,24 +4259,24 @@ msgstr "Les vidéos archivées sur Pod" msgid "In %(deadline)s days" msgstr "Dans %(deadline)s jours" -#: pod/video/models.py:120 +#: pod/video/models.py:124 msgid "Private -" msgstr "Privé (moi seulement)" -#: pod/video/models.py:121 +#: pod/video/models.py:125 msgid "Private +" msgstr "Partagé avec le propriétaire de la vidéo" -#: pod/video/models.py:122 +#: pod/video/models.py:126 msgid "Public" msgstr "Public" -#: pod/video/models.py:135 +#: pod/video/models.py:139 #, python-format msgid "%(app)s version" msgstr "Version %(app)s" -#: pod/video/models.py:218 pod/video/models.py:302 +#: pod/video/models.py:223 pod/video/models.py:307 msgid "" "Please choose a title as short and accurate as possible, reflecting the main " "subject / context of the content.(max length: 100 characters)" @@ -4287,7 +4285,7 @@ msgstr "" "sujet principal / le contexte de votre contenu. (taille maximale : 100 " "caractères)" -#: pod/video/models.py:239 +#: pod/video/models.py:244 msgid "" "The background color for your channel. You can use the format #. i.e.: " "#ff0000 for red" @@ -4295,39 +4293,39 @@ msgstr "" "La couleur d'arrière-plan pour votre chaîne. Vous pouvez utiliser le format " "#. i.e.: #ff0000 pour le rouge" -#: pod/video/models.py:243 +#: pod/video/models.py:248 msgid "The style will be added to your channel to show it" msgstr "Le style sera ajouté à votre chaîne" -#: pod/video/models.py:253 +#: pod/video/models.py:258 msgid "" "If checked, the channel appear in a list of available channels on the " "platform." msgstr "" "Si coché, la chaîne apparaîtra dans la liste des chaînes de la plateforme." -#: pod/video/models.py:260 pod/video/models.py:322 +#: pod/video/models.py:265 pod/video/models.py:327 #: pod/video_search/templates/search/search.html:124 msgid "Channel" msgstr "Chaîne" -#: pod/video/models.py:299 +#: pod/video/models.py:304 msgid "Theme parent" msgstr "Thème parent" -#: pod/video/models.py:391 +#: pod/video/models.py:396 msgid "Theme" msgstr "Thème" -#: pod/video/models.py:406 pod/video/models.py:432 +#: pod/video/models.py:411 pod/video/models.py:437 msgid "Icon" msgstr "Icone" -#: pod/video/models.py:444 pod/video_search/templates/search/search.html:111 +#: pod/video/models.py:449 pod/video_search/templates/search/search.html:111 msgid "Discipline" msgstr "Discipline" -#: pod/video/models.py:462 +#: pod/video/models.py:467 msgid "" "Please choose a title as short and accurate as possible, reflecting the main " "subject / context of the content.(max length: 250 characters)" @@ -4336,7 +4334,7 @@ msgstr "" "sujet principal / le contexte de ce contenu (taille maximale : 250 " "caractères)." -#: pod/video/models.py:490 +#: pod/video/models.py:495 msgid "" "You can add additional owners to the video. They will have the same rights " "as you except that they can't delete this video." @@ -4344,59 +4342,59 @@ msgstr "" "Vous pouvez ajouter des propriétaires additionnels à la vidéo. Ils auront " "les mêmes droits que vous sauf qu'ils ne peuvent pas supprimer cette vidéo." -#: pod/video/models.py:502 +#: pod/video/models.py:507 msgid "Date of event" msgstr "Date de l'évènement" -#: pod/video/models.py:567 pod/video/models.py:684 +#: pod/video/models.py:572 pod/video/models.py:694 msgid "Thumbnails" msgstr "Vignettes" -#: pod/video/models.py:571 +#: pod/video/models.py:576 msgid "Overview" msgstr "Vue d'ensemble" -#: pod/video/models.py:577 +#: pod/video/models.py:582 msgid "Is Video" msgstr "Est une vidéo" -#: pod/video/models.py:580 +#: pod/video/models.py:585 msgid "Date to delete" msgstr "Date de suppression" -#: pod/video/models.py:592 +#: pod/video/models.py:597 msgid "videos" msgstr "vidéos" -#: pod/video/models.py:637 +#: pod/video/models.py:643 msgid "Sum of view" msgstr "Somme des vues" -#: pod/video/models.py:715 +#: pod/video/models.py:728 msgid "Is the video encoded ?" msgstr "Est-ce que la vidéo est encodée ?" -#: pod/video/models.py:960 +#: pod/video/models.py:1004 msgid "Date" msgstr "Date" -#: pod/video/models.py:962 +#: pod/video/models.py:1006 msgid "Number of view" msgstr "Nombre de vues" -#: pod/video/models.py:970 +#: pod/video/models.py:1014 msgid "View count" msgstr "Nombre de vues" -#: pod/video/models.py:971 +#: pod/video/models.py:1015 msgid "View counts" msgstr "Statistiques" -#: pod/video/models.py:976 +#: pod/video/models.py:1020 msgid "resolution" msgstr "résolution" -#: pod/video/models.py:979 +#: pod/video/models.py:1023 msgid "" "Please use the only format x. i.e.: 640x360 or 1280x720 or " "1920x1080." @@ -4404,12 +4402,12 @@ msgstr "" "Veuillez utiliser le format LxH. soit: 640x360 ou 1280x720 " "ou 1920x1080." -#: pod/video/models.py:983 pod/video/models.py:1052 pod/video/models.py:1059 +#: pod/video/models.py:1027 pod/video/models.py:1096 pod/video/models.py:1103 msgid "minrate" msgstr "débit minimum" -#: pod/video/models.py:985 pod/video/models.py:991 pod/video/models.py:997 -#: pod/video/models.py:1003 +#: pod/video/models.py:1029 pod/video/models.py:1035 pod/video/models.py:1041 +#: pod/video/models.py:1047 msgid "" "Please use the only format k. i.e.: 300k or 600k or " "1000k." @@ -4417,179 +4415,179 @@ msgstr "" "Veuillez utiliser le format XXk soit: 300k ou 600k ou " "1000k." -#: pod/video/models.py:989 pod/video/models.py:1028 pod/video/models.py:1035 +#: pod/video/models.py:1033 pod/video/models.py:1072 pod/video/models.py:1079 msgid "bitrate video" msgstr "débit binaire de la vidéo" -#: pod/video/models.py:995 pod/video/models.py:1040 pod/video/models.py:1047 +#: pod/video/models.py:1039 pod/video/models.py:1084 pod/video/models.py:1091 msgid "maxrate" msgstr "débit maximum" -#: pod/video/models.py:1001 pod/video/models.py:1077 pod/video/models.py:1084 +#: pod/video/models.py:1045 pod/video/models.py:1121 pod/video/models.py:1128 msgid "bitrate audio" msgstr "débit binaire de l'audio" -#: pod/video/models.py:1006 +#: pod/video/models.py:1050 msgid "Make a MP4 version" msgstr "Faire une version MP4" -#: pod/video/models.py:1019 pod/video/models.py:1107 +#: pod/video/models.py:1063 pod/video/models.py:1151 msgid "rendition" msgstr "rendu" -#: pod/video/models.py:1020 +#: pod/video/models.py:1064 msgid "renditions" msgstr "rendus" -#: pod/video/models.py:1102 pod/video/models.py:1171 pod/video/models.py:1225 +#: pod/video/models.py:1146 pod/video/models.py:1215 pod/video/models.py:1269 msgid "Please use the only format in encoding choices:" msgstr "Merci de sélectionner un format d’encodage valide :" -#: pod/video/models.py:1109 pod/video/models.py:1175 pod/video/models.py:1229 +#: pod/video/models.py:1153 pod/video/models.py:1219 pod/video/models.py:1273 msgid "Format" msgstr "Format" -#: pod/video/models.py:1113 pod/video/models.py:1177 pod/video/models.py:1231 +#: pod/video/models.py:1157 pod/video/models.py:1221 pod/video/models.py:1275 msgid "Please use the only format in format choices:" msgstr "Merci de sélectionner un format valide :" -#: pod/video/models.py:1116 pod/video/models.py:1180 pod/video/models.py:1234 +#: pod/video/models.py:1160 pod/video/models.py:1224 pod/video/models.py:1278 msgid "encoding source file" msgstr "fichier source d'encodage" -#: pod/video/models.py:1138 +#: pod/video/models.py:1182 msgid "Encoding video" msgstr "Encodage vidéo" -#: pod/video/models.py:1139 +#: pod/video/models.py:1183 msgid "Encoding videos" msgstr "Encodage des vidéos" -#: pod/video/models.py:1190 +#: pod/video/models.py:1234 msgid "Encoding audio" msgstr "Encodage audio" -#: pod/video/models.py:1191 +#: pod/video/models.py:1235 msgid "Encoding audios" msgstr "Encodage des audios" -#: pod/video/models.py:1239 +#: pod/video/models.py:1283 msgid "Video Playlist" msgstr "Liste de lecture" -#: pod/video/models.py:1240 +#: pod/video/models.py:1284 msgid "Video Playlists" msgstr "Listes de lecture" -#: pod/video/models.py:1286 +#: pod/video/models.py:1330 msgid "Encoding log" msgstr "Journal de l'encodage" -#: pod/video/models.py:1287 +#: pod/video/models.py:1331 msgid "Encoding logs" msgstr "Journaux des encodages" -#: pod/video/models.py:1297 pod/video/models.py:1302 +#: pod/video/models.py:1341 pod/video/models.py:1346 msgid "Video version" msgstr "Version de la video" -#: pod/video/models.py:1299 +#: pod/video/models.py:1343 msgid "Video default version." msgstr "Version par défaut de la vidéo." -#: pod/video/models.py:1303 +#: pod/video/models.py:1347 msgid "Video versions" msgstr "Versions de la video" -#: pod/video/models.py:1328 +#: pod/video/models.py:1372 msgid "Encoding steps" msgstr "Etapes de l'encodage" -#: pod/video/models.py:1337 pod/video/models.py:1344 pod/video/models.py:1360 -#: pod/video/views.py:1312 +#: pod/video/models.py:1381 pod/video/models.py:1388 pod/video/models.py:1404 +#: pod/video/views.py:1314 msgid "Note" msgstr "Note" -#: pod/video/models.py:1345 +#: pod/video/models.py:1389 msgid "Notes" msgstr "Notes" -#: pod/video/models.py:1356 +#: pod/video/models.py:1400 msgid "Note availibility level" msgstr "Niveau de disponibilité de la note" -#: pod/video/models.py:1358 +#: pod/video/models.py:1402 msgid "Select an availability level for the note." msgstr "Sélectionner le niveau de disponibilité de la note." -#: pod/video/models.py:1362 +#: pod/video/models.py:1406 msgid "Timestamp" msgstr "Horodatage" -#: pod/video/models.py:1366 pod/video/models.py:1425 +#: pod/video/models.py:1410 pod/video/models.py:1469 msgid "Date modified" msgstr "Date de modification" -#: pod/video/models.py:1369 +#: pod/video/models.py:1413 msgid "Advanced Note" msgstr "Note avancée" -#: pod/video/models.py:1370 +#: pod/video/models.py:1414 msgid "Advanced Notes" msgstr "Notes avancées" -#: pod/video/models.py:1416 +#: pod/video/models.py:1460 msgid "Comment availibility level" msgstr "Niveau de disponibilité du commentaire" -#: pod/video/models.py:1418 +#: pod/video/models.py:1462 msgid "Select an availability level for the comment." msgstr "Sélectionnez un niveau de disponibilité pour le commentaire." -#: pod/video/models.py:1428 +#: pod/video/models.py:1472 msgid "Note comment" msgstr "Commentaire de la note" -#: pod/video/models.py:1429 +#: pod/video/models.py:1473 msgid "Note comments" msgstr "Commentaires de notes" -#: pod/video/models.py:1447 +#: pod/video/models.py:1491 msgid "Date for deletion" msgstr "Date pour la suppression" -#: pod/video/models.py:1450 pod/video/models.py:1532 +#: pod/video/models.py:1494 pod/video/models.py:1576 #: pod/video/templates/videos/video.html:76 #: pod/video/templates/videos/videos.html:8 #: pod/video/templates/videos/videos.html:17 msgid "Videos" msgstr "Vidéos" -#: pod/video/models.py:1453 +#: pod/video/models.py:1497 msgid "Video to delete" msgstr "Vidéo à supprimer" -#: pod/video/models.py:1454 +#: pod/video/models.py:1498 msgid "Videos to delete" msgstr "Vidéos à supprimer" -#: pod/video/models.py:1474 pod/video/templates/videos/video-comment.html:9 +#: pod/video/models.py:1518 pod/video/templates/videos/video-comment.html:9 msgid "Comments" msgstr "Commentaires" -#: pod/video/models.py:1515 +#: pod/video/models.py:1559 msgid "Vote" msgstr "Vote" -#: pod/video/models.py:1516 +#: pod/video/models.py:1560 msgid "Votes" msgstr "Votes" -#: pod/video/models.py:1524 pod/video/templates/videos/category_modal.html:13 +#: pod/video/models.py:1568 pod/video/templates/videos/category_modal.html:13 msgid "Category title" msgstr "Titre catégorie" -#: pod/video/models.py:1526 +#: pod/video/models.py:1570 msgid "" "Please choose a title as short and accurate as possible, reflecting the main " "subject / context of the content.(max length : 100 characters)" @@ -4598,11 +4596,11 @@ msgstr "" "sujet principal / le contexte de votre contenu. (taille maximale : 100 " "caractères)" -#: pod/video/models.py:1552 pod/video/templates/videos/category_modal.html:7 +#: pod/video/models.py:1596 pod/video/templates/videos/category_modal.html:7 msgid "Category" msgstr "Catégorie" -#: pod/video/models.py:1553 +#: pod/video/models.py:1597 #: pod/video/templates/videos/filter_aside_category.html:14 msgid "Categories" msgstr "Catégories" @@ -4648,7 +4646,7 @@ msgstr "Editer les thèmes" msgid "Edit the channel" msgstr "Éditer la chaîne" -#: pod/video/templates/channel/channel.html:98 +#: pod/video/templates/channel/channel.html:100 #: pod/video/templates/videos/my_videos.html:14 #: pod/video/templates/videos/my_videos.html:33 #: pod/video/templates/videos/videos.html:6 @@ -4662,7 +4660,7 @@ msgid_plural "%(counter)s videos found" msgstr[0] "%(counter)s vidéo trouvée" msgstr[1] "%(counter)s vidéos trouvées" -#: pod/video/templates/channel/channel.html:135 +#: pod/video/templates/channel/channel.html:137 msgid "Themes of " msgstr "Thèmes de " @@ -4893,9 +4891,9 @@ msgstr "Ajouter catégorie" msgid "Edit the category" msgstr "Éditer la catégorie" -#: pod/video/templates/videos/footer_link.html:5 -msgid "link" -msgstr "lien" +#: pod/video/templates/videos/footer_link.html:4 +msgid "Links" +msgstr "Liens" #: pod/video/templates/videos/last_videos.html:7 msgid "Last videos" @@ -5165,7 +5163,7 @@ msgstr "La vidéo est actuellement en attente d’encodage." msgid "The video is currently being transcripted." msgstr "La vidéo est en cours de transcription." -#: pod/video/templates/videos/video.html:159 +#: pod/video/templates/videos/video.html:156 msgid "" "This video is chaptered. Click the chapter button on the video player to view them." @@ -5273,8 +5271,16 @@ msgid "Creative Commons license" msgstr "Licence Creative Commons" #: pod/video/templates/videos/video_list.html:10 -msgid "Sorry, no video found" -msgstr "Désolé, aucune vidéo trouvée" +msgid "Sorry, no video found." +msgstr "Désolé, aucune vidéo trouvée." + +#: pod/video/templates/videos/video_list.html:15 +msgid "More" +msgstr "Plus" + +#: pod/video/templates/videos/video_list.html:18 +msgid "Loading..." +msgstr "Chargement…" #: pod/video/templates/videos/video_note_comments_display.html:8 #: pod/video/templates/videos/video_note_display.html:14 @@ -5404,149 +5410,155 @@ msgstr "" "La vidéo \"%(content_title)s\" a été encodée au format web, et est " "maintenant disponible sur %(site_title)s." -#: pod/video/views.py:232 pod/video/views.py:272 +#: pod/video/views.py:233 pod/video/views.py:273 msgid "You cannot edit this channel." msgstr "Vous ne pouvez éditer cette chaîne." -#: pod/video/views.py:249 pod/video/views.py:724 +#: pod/video/views.py:250 pod/video/views.py:726 msgid "The changes have been saved." msgstr "Les modifications ont été sauvegardées." -#: pod/video/views.py:601 +#: pod/video/views.py:603 msgid "You don't have access to this playlist." msgstr "Vous n'avez pas les droits d'accès à cette liste de lecture." -#: pod/video/views.py:662 +#: pod/video/views.py:664 msgid "You cannot watch this video." msgstr "Vous ne pouvez pas voir cette vidéo." -#: pod/video/views.py:696 +#: pod/video/views.py:698 msgid "You cannot edit this video." msgstr "Vous ne pouvez pas éditer cette vidéo." -#: pod/video/views.py:774 +#: pod/video/views.py:776 msgid "You cannot delete this video." msgstr "Vous ne pouvez pas supprimer cette vidéo." -#: pod/video/views.py:784 +#: pod/video/views.py:786 msgid "The video has been deleted." msgstr "La vidéo a été supprimée." -#: pod/video/views.py:900 +#: pod/video/views.py:902 #, python-format msgid "You cannot %s this note or comment." msgstr "Vous ne pouvez pas %s cette note ou ce commentaire." -#: pod/video/views.py:923 +#: pod/video/views.py:925 msgid "You cannot see this note or comment." msgstr "Vous ne pouvez pas voir cette note ou ce commentaire." -#: pod/video/views.py:1159 pod/video/views.py:1173 pod/video/views.py:1196 +#: pod/video/views.py:1161 pod/video/views.py:1175 pod/video/views.py:1198 msgid "The comment has been saved." msgstr "Le commentaire a été enregistré." -#: pod/video/views.py:1186 pod/video/views.py:1211 +#: pod/video/views.py:1188 pod/video/views.py:1213 msgid "The note has been saved." msgstr "La note a été sauvegardée." -#: pod/video/views.py:1251 +#: pod/video/views.py:1253 msgid "The note has been deleted." msgstr "La note a été supprimée." -#: pod/video/views.py:1259 +#: pod/video/views.py:1261 msgid "The comment has been deleted." msgstr "Le commentaire a été supprimé." -#: pod/video/views.py:1305 pod/video/views.py:1308 pod/video/views.py:1314 +#: pod/video/views.py:1307 pod/video/views.py:1310 pod/video/views.py:1316 msgid "None" msgstr "Aucun" -#: pod/video/views.py:1327 +#: pod/video/views.py:1329 msgid "ID" msgstr "ID" -#: pod/video/views.py:1327 +#: pod/video/views.py:1329 msgid "Status" msgstr "Status" -#: pod/video/views.py:1328 +#: pod/video/views.py:1330 msgid "Parent note id" msgstr "Identifiant de note parent" -#: pod/video/views.py:1328 +#: pod/video/views.py:1330 msgid "Parent comment id" msgstr "ID du commentaire parent" -#: pod/video/views.py:1329 +#: pod/video/views.py:1331 msgid "Created on" msgstr "Créé le" -#: pod/video/views.py:1329 +#: pod/video/views.py:1331 msgid "Modified on" msgstr "Modifié le" -#: pod/video/views.py:1330 +#: pod/video/views.py:1332 msgid "Note timestamp" msgstr "Horodatage de la note" -#: pod/video/views.py:1357 pod/video/views.py:1385 +#: pod/video/views.py:1359 pod/video/views.py:1387 msgid "You cannot access to this view." msgstr "Vous ne pouvez pas accéder à cette vue." -#: pod/video/views.py:1506 +#: pod/video/views.py:1509 msgid "Pod video viewing statistics" msgstr "Statistiques de visualisation des vidéos" -#: pod/video/views.py:1513 +#: pod/video/views.py:1516 #, python-format msgid "Video viewing statistics for %s" msgstr "Statistiques de visualisation de la vidéo %s" -#: pod/video/views.py:1517 +#: pod/video/views.py:1520 #, 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:1521 +#: pod/video/views.py:1524 #, 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:1563 +#: pod/video/views.py:1566 #, 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:1583 +# First %s can be ("channel", "theme", "videos ») +#: pod/video/views.py:1582 #, python-format -msgid "The following video does not exist : %s" -msgstr "La video suivante n'existe pas : %s" +msgid "The following %s does not exist or contain any videos: %s" +msgstr "La/le %s suivant n'existe pas, ou ne contient aucune vidéo : %s" -#: pod/video/views.py:1914 +#: pod/video/views.py:1588 +#, python-format +msgid "The following video does not exist: %s" +msgstr "La video suivante n'existe pas : %s" + +#: pod/video/views.py:1920 msgid "You do not have rights to delete this comment" msgstr "Vous n'avez pas les droits pour supprimer ce commentaire" -#: pod/video/views.py:2005 pod/video/views.py:2071 +#: pod/video/views.py:2011 pod/video/views.py:2077 msgid "One or many videos already have a category." msgstr "Une ou plusieurs vidéos possèdent déjà une catégorie." -#: pod/video/views.py:2041 pod/video/views.py:2111 +#: pod/video/views.py:2047 pod/video/views.py:2117 msgid "Title field is required" msgstr "Champ de titre est requis" -#: pod/video/views.py:2046 pod/video/views.py:2116 pod/video/views.py:2158 +#: pod/video/views.py:2052 pod/video/views.py:2122 pod/video/views.py:2164 msgid "Method Not Allowed" msgstr "Méthode non autorisée" -#: pod/video/views.py:2088 +#: pod/video/views.py:2094 msgid "Category updated successfully." msgstr "Catégorie mise à jour avec succès." -#: pod/video/views.py:2106 +#: pod/video/views.py:2112 msgid "You do not have rights to edit this category" msgstr "Vous n'avez pas les droits pour éditer cette catégorie" -#: pod/video/views.py:2152 +#: pod/video/views.py:2158 msgid "You do not have rights to delete this category" msgstr "Vous n'avez pas les droits pour supprimer cette catégorie" @@ -5571,10 +5583,13 @@ msgstr "Filtres actifs (cliquer pour en retirer) :" msgid "Advanced search" msgstr "Recherche avancée" -#: pod/video_search/views.py:60 +#: pod/video_search/views.py:63 msgid "Remove this filter" msgstr "Retirer ce filtre" +#~ msgid "link" +#~ msgstr "lien" + #~ msgid "Contributors:" #~ msgstr "Contributeurs :" diff --git a/pod/locale/nl/LC_MESSAGES/django.po b/pod/locale/nl/LC_MESSAGES/django.po index 85fd05efef..cf8abb2d42 100755 --- 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: 2021-02-24 08:35+0000\n" +"POT-Creation-Date: 2021-03-05 15:42+0000\n" "PO-Revision-Date: 2021-01-22 12:27+0100\n" "Last-Translator: obado \n" "Language-Team: \n" @@ -29,7 +29,7 @@ msgstr "" #: pod/bbb/models.py:141 pod/main/templates/navbar.html:22 #: pod/main/templates/navbar_collapse.html:76 pod/podfile/models.py:37 #: pod/video/forms.py:236 pod/video/forms.py:589 pod/video/forms.py:593 -#: pod/video/models.py:248 pod/video/templates/videos/filter_aside.html:13 +#: pod/video/models.py:253 pod/video/templates/videos/filter_aside.html:13 msgid "Users" msgstr "" @@ -90,7 +90,7 @@ msgid "registered-reader" msgstr "" #: pod/authentication/models.py:68 pod/recorder/models.py:266 -#: pod/video/models.py:1421 pod/video/models.py:1473 pod/video/views.py:1301 +#: pod/video/models.py:1465 pod/video/models.py:1517 pod/video/views.py:1303 msgid "Comment" msgstr "" @@ -161,8 +161,8 @@ msgstr "" #: pod/video/templates/videos/video_note_comments_display.html:148 #: pod/video/templates/videos/video_note_display.html:27 #: pod/video/templates/videos/video_notes.html:80 -#: pod/video/templates/videos/video_notes.html:116 pod/video/views.py:254 -#: pod/video/views.py:737 pod/video/views.py:791 pod/video/views.py:1221 +#: pod/video/templates/videos/video_notes.html:116 pod/video/views.py:255 +#: pod/video/views.py:739 pod/video/views.py:793 pod/video/views.py:1223 #: pod/video_search/templates/search/search.html:50 msgid "One or more errors have been found in the form." msgstr "" @@ -189,7 +189,7 @@ msgid "Please provide a valid value for this field" msgstr "" #: pod/authentication/templates/userpicture/userpicture.html:56 -#: pod/bbb/templates/bbb/list_meeting.html:44 pod/main/templates/base.html:114 +#: pod/bbb/templates/bbb/list_meeting.html:44 pod/main/templates/base.html:113 #: pod/main/templates/navbar_collapse.html:43 #: pod/main/templates/navbar_collapse.html:66 #: pod/main/templates/navbar_collapse.html:100 @@ -232,7 +232,7 @@ msgstr "" msgid "Session date" msgstr "" -#: pod/bbb/models.py:40 pod/video/models.py:646 pod/video/models.py:1327 +#: pod/bbb/models.py:40 pod/video/models.py:653 pod/video/models.py:1371 msgid "Encoding step" msgstr "" @@ -336,7 +336,7 @@ msgstr "" msgid "Waiting for encoding" msgstr "" -#: pod/bbb/templates/bbb/card.html:40 pod/video/models.py:575 +#: pod/bbb/templates/bbb/card.html:40 pod/video/models.py:580 msgid "Encoding in progress" msgstr "" @@ -438,24 +438,24 @@ msgid "File to import" msgstr "" #: pod/chapter/models.py:14 pod/completion/models.py:53 -#: pod/enrichment/models.py:114 pod/video/models.py:591 +#: pod/enrichment/models.py:114 pod/video/models.py:596 msgid "video" msgstr "" #: pod/chapter/models.py:15 pod/enrichment/models.py:115 -#: pod/recorder/models.py:259 pod/video/models.py:423 +#: pod/recorder/models.py:259 pod/video/models.py:428 msgid "title" msgstr "titel" #: pod/chapter/models.py:17 pod/enrichment/models.py:117 -#: pod/video/models.py:425 +#: pod/video/models.py:430 msgid "slug" msgstr "" #: pod/chapter/models.py:20 pod/completion/models.py:262 #: pod/enrichment/models.py:120 pod/live/models.py:71 pod/playlist/models.py:17 -#: pod/video/models.py:224 pod/video/models.py:308 pod/video/models.py:401 -#: pod/video/models.py:427 pod/video/models.py:468 pod/video/models.py:1539 +#: pod/video/models.py:229 pod/video/models.py:313 pod/video/models.py:406 +#: pod/video/models.py:432 pod/video/models.py:473 pod/video/models.py:1583 msgid "" "Used to access this instance, the \"slug\" is a short label containing only " "letters, numbers, underscore or dash top." @@ -551,8 +551,8 @@ msgstr "" #: pod/enrichment/templates/enrichment/list_enrichment.html:10 #: pod/main/models.py:103 pod/main/views.py:165 pod/playlist/models.py:12 #: pod/playlist/templates/playlist/playlist_element_list.html:11 -#: pod/video/models.py:215 pod/video/models.py:301 pod/video/models.py:397 -#: pod/video/models.py:460 pod/video/templates/channel/list_theme.html:9 +#: pod/video/models.py:220 pod/video/models.py:306 pod/video/models.py:402 +#: pod/video/models.py:465 pod/video/templates/channel/list_theme.html:9 msgid "Title" msgstr "" @@ -564,7 +564,7 @@ msgstr "" #: pod/completion/templates/track/list_track.html:23 #: pod/completion/templates/track/list_track.html:42 #: pod/enrichment/templates/enrichment/list_enrichment.html:30 -#: pod/podfile/templates/podfile/list_folder_files.html:249 +#: pod/podfile/templates/podfile/list_folder_files.html:251 #: pod/video/templates/channel/list_theme.html:27 msgid "Modify" msgstr "" @@ -577,7 +577,7 @@ msgstr "" #: pod/enrichment/templates/enrichment/list_enrichment.html:38 #: pod/playlist/templates/playlist.html:68 #: pod/podfile/templates/podfile/list_folder_files.html:104 -#: pod/podfile/templates/podfile/list_folder_files.html:297 +#: pod/podfile/templates/podfile/list_folder_files.html:299 #: pod/recorder/templates/recorder/record_delete.html:9 #: pod/video/templates/channel/list_theme.html:35 #: pod/video/templates/videos/category_modal.html:66 @@ -630,7 +630,7 @@ msgstr "" #: pod/enrichment/templates/enrichment/group_enrichment.html:71 #: pod/interactive/templates/interactive/edit_interactive.html:128 #: pod/interactive/templates/interactive/group_interactive.html:71 -#: pod/video/templates/videos/video.html:251 +#: pod/video/templates/videos/video.html:248 #: pod/video/templates/videos/video_edit.html:143 msgid "Manage video" msgstr "" @@ -771,10 +771,10 @@ msgstr "" #: pod/completion/templates/video_caption_maker.html:85 #: pod/enrichment/models.py:291 pod/enrichment/models.py:322 #: pod/interactive/models.py:16 pod/interactive/models.py:37 -#: pod/playlist/models.py:79 pod/recorder/models.py:78 pod/video/models.py:456 -#: pod/video/models.py:957 pod/video/models.py:1105 pod/video/models.py:1173 -#: pod/video/models.py:1227 pod/video/models.py:1276 pod/video/models.py:1294 -#: pod/video/models.py:1315 +#: pod/playlist/models.py:79 pod/recorder/models.py:78 pod/video/models.py:461 +#: pod/video/models.py:1001 pod/video/models.py:1149 pod/video/models.py:1217 +#: pod/video/models.py:1271 pod/video/models.py:1320 pod/video/models.py:1338 +#: pod/video/models.py:1359 msgid "Video" msgstr "" @@ -878,8 +878,8 @@ msgid "left" msgstr "" #: pod/completion/models.py:259 pod/live/models.py:69 pod/playlist/models.py:14 -#: pod/video/models.py:222 pod/video/models.py:306 pod/video/models.py:399 -#: pod/video/models.py:466 pod/video/models.py:1537 +#: pod/video/models.py:227 pod/video/models.py:311 pod/video/models.py:404 +#: pod/video/models.py:471 pod/video/models.py:1581 msgid "Slug" msgstr "" @@ -895,7 +895,7 @@ msgstr "" msgid "End time of the overlay, in seconds." msgstr "" -#: pod/completion/models.py:279 pod/video/views.py:1330 +#: pod/completion/models.py:279 pod/video/views.py:1332 msgid "Content" msgstr "" @@ -1296,7 +1296,7 @@ msgstr "" #: pod/completion/views.py:237 pod/completion/views.py:413 #: pod/completion/views.py:814 pod/podfile/views.py:470 -#: pod/podfile/views.py:520 pod/video/views.py:344 pod/video/views.py:1379 +#: pod/podfile/views.py:520 pod/video/views.py:345 pod/video/views.py:1381 msgid "Please correct errors" msgstr "" @@ -1324,7 +1324,7 @@ msgstr "" #: pod/enrichment/forms.py:35 pod/enrichment/models.py:326 #: pod/interactive/forms.py:13 pod/interactive/models.py:41 -#: pod/podfile/models.py:33 pod/recorder/models.py:161 pod/video/models.py:557 +#: pod/podfile/models.py:33 pod/recorder/models.py:161 pod/video/models.py:562 msgid "Groups" msgstr "" @@ -1366,8 +1366,8 @@ msgstr "" #: pod/enrichment/models.py:137 #: pod/enrichment/templates/enrichment/list_enrichment.html:11 -#: pod/video/forms.py:103 pod/video/models.py:418 pod/video/models.py:473 -#: pod/video/views.py:1327 pod/video_search/templates/search/search.html:87 +#: pod/video/forms.py:103 pod/video/models.py:423 pod/video/models.py:478 +#: pod/video/views.py:1329 pod/video_search/templates/search/search.html:87 msgid "Type" msgstr "" @@ -1544,7 +1544,7 @@ msgstr "" #: pod/enrichment/templates/enrichment/video_enrichment.html:60 #: pod/interactive/templates/interactive/video_interactive.html:47 -#: pod/video/templates/videos/video.html:153 +#: pod/video/templates/videos/video.html:150 msgid "Report the video" msgstr "" @@ -1553,8 +1553,8 @@ msgstr "" #: pod/interactive/templates/interactive/video_interactive.html:56 #: pod/interactive/templates/interactive/video_interactive.html:57 #: pod/video/templates/videos/video-info.html:9 -#: pod/video/templates/videos/video.html:168 -#: pod/video/templates/videos/video.html:169 +#: pod/video/templates/videos/video.html:165 +#: pod/video/templates/videos/video.html:166 msgid "Summary" msgstr "" @@ -1563,9 +1563,9 @@ msgstr "" #: pod/interactive/templates/interactive/video_interactive.html:61 #: pod/interactive/templates/interactive/video_interactive.html:62 #: pod/video/templates/videos/video-info.html:36 -#: pod/video/templates/videos/video.html:175 -#: pod/video/templates/videos/video.html:177 -#: pod/video/templates/videos/video.html:179 +#: pod/video/templates/videos/video.html:172 +#: pod/video/templates/videos/video.html:174 +#: pod/video/templates/videos/video.html:176 msgid "Infos" msgstr "" @@ -1574,8 +1574,8 @@ msgstr "" #: pod/interactive/templates/interactive/video_interactive.html:67 #: pod/interactive/templates/interactive/video_interactive.html:68 #: pod/video/templates/videos/video-info.html:156 -#: pod/video/templates/videos/video.html:184 -#: pod/video/templates/videos/video.html:185 +#: pod/video/templates/videos/video.html:181 +#: pod/video/templates/videos/video.html:182 msgid "Downloads" msgstr "" @@ -1584,8 +1584,8 @@ msgstr "" #: pod/interactive/templates/interactive/video_interactive.html:73 #: pod/interactive/templates/interactive/video_interactive.html:74 #: pod/video/templates/videos/video-info.html:198 -#: pod/video/templates/videos/video.html:191 -#: pod/video/templates/videos/video.html:192 +#: pod/video/templates/videos/video.html:188 +#: pod/video/templates/videos/video.html:189 msgid "Embed/Share" msgstr "" @@ -1593,8 +1593,8 @@ msgstr "" #: pod/enrichment/templates/enrichment/video_enrichment.html:93 #: pod/interactive/templates/interactive/video_interactive.html:85 #: pod/interactive/templates/interactive/video_interactive.html:86 -#: pod/video/templates/videos/video.html:199 -#: pod/video/templates/videos/video.html:200 +#: pod/video/templates/videos/video.html:196 +#: pod/video/templates/videos/video.html:197 msgid "Other versions" msgstr "" @@ -1608,7 +1608,7 @@ msgstr "" #: pod/enrichment/templates/enrichment/video_enrichment.html:105 #: pod/interactive/templates/interactive/video_interactive.html:100 -#: pod/video/templates/videos/video.html:217 +#: pod/video/templates/videos/video.html:214 msgid "Add the video to a playlist" msgstr "" @@ -1618,7 +1618,7 @@ msgstr "" #: pod/playlist/templates/my_playlists.html:10 #: pod/playlist/templates/my_playlists.html:17 #: pod/playlist/templates/playlist.html:14 -#: pod/video/templates/videos/video.html:218 +#: pod/video/templates/videos/video.html:215 msgid "My playlists" msgstr "" @@ -1672,11 +1672,11 @@ msgstr "" #: pod/interactive/templates/interactive/edit_interactive.html:47 #: pod/interactive/templates/interactive/edit_interactive.html:49 -#: pod/interactive/templates/interactive/edit_interactive.html:56 msgid "Delete the interactive part of this video" msgstr "" #: pod/interactive/templates/interactive/edit_interactive.html:54 +#: pod/interactive/templates/interactive/edit_interactive.html:56 #: pod/interactive/templates/interactive/edit_interactive.html:66 #: pod/interactive/templates/interactive/edit_interactive.html:68 msgid "Back" @@ -1687,21 +1687,19 @@ msgstr "" msgid "Manage scores" msgstr "" -#: pod/interactive/templates/interactive/edit_interactive.html:77 -#: pod/interactive/templates/interactive/edit_interactive.html:78 +#: pod/interactive/templates/interactive/edit_interactive.html:79 #: pod/interactive/templates/interactive/edit_interactive.html:96 -#: pod/interactive/templates/interactive/edit_interactive.html:97 +#: pod/interactive/templates/interactive/edit_interactive.html:98 msgid "Save and continue" msgstr "" -#: pod/interactive/templates/interactive/edit_interactive.html:81 -#: pod/interactive/templates/interactive/edit_interactive.html:100 -msgid "Save and return to video" +#: pod/interactive/templates/interactive/edit_interactive.html:83 +#: pod/interactive/templates/interactive/edit_interactive.html:102 +msgid "Save and see the interactive video" msgstr "" -#: pod/interactive/templates/interactive/edit_interactive.html:82 -#: pod/interactive/templates/interactive/edit_interactive.html:101 -msgid "Save and see the interactive video" +#: pod/interactive/templates/interactive/edit_interactive.html:100 +msgid "Save and return to video" msgstr "" #: pod/interactive/templates/interactive/edit_interactive.html:120 @@ -1797,9 +1795,9 @@ msgid "name" msgstr "" #: pod/live/models.py:31 pod/live/templates/live/live.html:94 -#: pod/video/models.py:235 pod/video/models.py:319 -#: pod/video/templates/channel/channel.html:79 -#: pod/video/templates/channel/channel.html:90 +#: pod/video/models.py:240 pod/video/models.py:324 +#: pod/video/templates/channel/channel.html:81 +#: pod/video/templates/channel/channel.html:92 #: pod/video/templates/channel/channel_edit.html:38 #: pod/video/templates/videos/video.html:100 #: pod/video/templates/videos/video.html:109 @@ -1868,7 +1866,7 @@ msgid "Enable viewers count on live." msgstr "" #: pod/live/models.py:102 pod/recorder/models.py:155 pod/video/forms.py:186 -#: pod/video/models.py:551 +#: pod/video/models.py:556 msgid "Restricted access" msgstr "" @@ -1884,7 +1882,7 @@ msgstr "" msgid "Live is accessible from the Live tab" msgstr "" -#: pod/live/models.py:112 pod/recorder/models.py:164 pod/video/models.py:560 +#: pod/live/models.py:112 pod/recorder/models.py:164 pod/video/models.py:565 msgid "password" msgstr "" @@ -1931,7 +1929,7 @@ msgstr "" msgid "Lives" msgstr "" -#: pod/live/templates/live/building.html:39 +#: pod/live/templates/live/building.html:38 #: pod/live/templates/live/live.html:104 pod/live/templates/live/lives.html:37 msgid "Sorry, no lives found" msgstr "" @@ -1993,7 +1991,7 @@ msgstr "" msgid "You cannot view this page." msgstr "" -#: pod/live/views.py:91 pod/video/views.py:647 +#: pod/live/views.py:91 pod/video/views.py:649 msgid "The password is incorrect." msgstr "" @@ -2038,8 +2036,8 @@ msgid "Other (please specify)" msgstr "" #: pod/main/forms.py:50 pod/podfile/models.py:27 pod/podfile/models.py:105 -#: pod/podfile/templates/podfile/home_content.html:32 pod/video/models.py:1098 -#: pod/video/models.py:1170 pod/video/models.py:1224 +#: pod/podfile/templates/podfile/home_content.html:32 pod/video/models.py:1142 +#: pod/video/models.py:1214 pod/video/models.py:1268 msgid "Name" msgstr "" @@ -2053,7 +2051,7 @@ msgstr "" #: pod/main/forms.py:60 pod/main/models.py:142 pod/playlist/models.py:22 #: pod/video/forms.py:113 pod/video/forms.py:227 pod/video/forms.py:253 -#: pod/video/models.py:228 pod/video/models.py:312 pod/video/models.py:494 +#: pod/video/models.py:233 pod/video/models.py:317 pod/video/models.py:499 msgid "Description" msgstr "" @@ -2755,27 +2753,27 @@ msgid "Share on" msgstr "" #: pod/main/templates/aside.html:21 pod/main/templates/aside.html:27 -#: pod/recorder/models.py:188 pod/video/forms.py:136 pod/video/models.py:445 -#: pod/video/models.py:523 pod/video/templates/videos/filter_aside.html:56 +#: pod/recorder/models.py:188 pod/video/forms.py:136 pod/video/models.py:450 +#: pod/video/models.py:528 pod/video/templates/videos/filter_aside.html:56 msgid "Disciplines" msgstr "" #: pod/main/templates/aside.html:40 pod/recorder/models.py:184 -#: pod/video/forms.py:132 pod/video/models.py:519 +#: pod/video/forms.py:132 pod/video/models.py:524 #: pod/video/templates/videos/filter_aside.html:78 #: pod/video_search/templates/search/search.html:99 msgid "Tags" msgstr "" -#: pod/main/templates/base.html:68 +#: pod/main/templates/base.html:66 msgid "Breadcrumb" msgstr "" -#: pod/main/templates/base.html:71 +#: pod/main/templates/base.html:69 msgid "Home" msgstr "" -#: pod/main/templates/base.html:76 +#: pod/main/templates/base.html:74 msgid "Toggle side Menu" msgstr "" @@ -2816,7 +2814,7 @@ msgstr "" msgid "Pod Project" msgstr "" -#: pod/main/templates/footer.html:34 pod/video/feeds.py:107 +#: pod/main/templates/footer.html:34 pod/video/feeds.py:108 msgid "video platform of" msgstr "" @@ -2873,11 +2871,11 @@ msgid "Return to homepage" msgstr "" #: pod/main/templates/navbar.html:17 pod/recorder/models.py:194 -#: pod/video/forms.py:172 pod/video/models.py:261 pod/video/models.py:529 +#: pod/video/forms.py:172 pod/video/models.py:266 pod/video/models.py:534 msgid "Channels" msgstr "" -#: pod/main/templates/navbar.html:27 pod/video/models.py:419 +#: pod/main/templates/navbar.html:27 pod/video/models.py:424 #: pod/video/templates/videos/filter_aside.html:34 msgid "Types" msgstr "" @@ -2977,7 +2975,7 @@ msgstr "" #: pod/playlist/models.py:20 #: pod/playlist/templates/playlist/playlist_element_list.html:12 -#: pod/podfile/models.py:30 pod/video/admin.py:168 pod/video/models.py:477 +#: pod/podfile/models.py:30 pod/video/admin.py:168 pod/video/models.py:482 #: pod/video_search/templates/search/search.html:75 msgid "Owner" msgstr "" @@ -2986,7 +2984,7 @@ msgstr "" msgid "Short description of the playlist." msgstr "" -#: pod/playlist/models.py:28 pod/video/models.py:251 +#: pod/playlist/models.py:28 pod/video/models.py:256 msgid "Visible" msgstr "" @@ -3088,7 +3086,7 @@ msgid "Thumbnail" msgstr "" #: pod/playlist/templates/playlist/playlist_element_list.html:13 -#: pod/video/feeds.py:188 pod/video/models.py:569 pod/video/models.py:706 +#: pod/video/feeds.py:189 pod/video/models.py:574 pod/video/models.py:719 msgid "Duration" msgstr "" @@ -3193,26 +3191,26 @@ msgid "Change file" msgstr "" #: pod/podfile/templates/podfile/customfilewidget.html:30 -#: pod/podfile/templates/podfile/customfilewidget.html:47 -#: pod/podfile/templates/podfile/customfilewidget.html:107 +#: pod/podfile/templates/podfile/customfilewidget.html:46 +#: pod/podfile/templates/podfile/customfilewidget.html:106 msgid "Remove image" msgstr "" #: pod/podfile/templates/podfile/customfilewidget.html:32 -#: pod/podfile/templates/podfile/customfilewidget.html:49 -#: pod/podfile/templates/podfile/customfilewidget.html:109 +#: pod/podfile/templates/podfile/customfilewidget.html:48 +#: pod/podfile/templates/podfile/customfilewidget.html:108 msgid "Remove file" msgstr "" -#: pod/podfile/templates/podfile/customfilewidget.html:40 -#: pod/podfile/templates/podfile/customfilewidget.html:61 -#: pod/podfile/templates/podfile/customfilewidget.html:100 +#: pod/podfile/templates/podfile/customfilewidget.html:39 +#: pod/podfile/templates/podfile/customfilewidget.html:60 +#: pod/podfile/templates/podfile/customfilewidget.html:99 msgid "Select an image" msgstr "" -#: pod/podfile/templates/podfile/customfilewidget.html:42 -#: pod/podfile/templates/podfile/customfilewidget.html:61 -#: pod/podfile/templates/podfile/customfilewidget.html:102 +#: pod/podfile/templates/podfile/customfilewidget.html:41 +#: pod/podfile/templates/podfile/customfilewidget.html:60 +#: pod/podfile/templates/podfile/customfilewidget.html:101 msgid "Select a file" msgstr "" @@ -3222,7 +3220,7 @@ msgid "Enter new name of folder" msgstr "" #: pod/podfile/templates/podfile/home_content.html:53 -#: pod/podfile/templates/podfile/list_folder_files.html:187 +#: pod/podfile/templates/podfile/list_folder_files.html:189 #: pod/video/templates/videos/video_edit.html:119 msgid "Loading" msgstr "" @@ -3247,15 +3245,15 @@ msgstr "" msgid "Rename" msgstr "" -#: pod/podfile/templates/podfile/list_folder_files.html:134 +#: pod/podfile/templates/podfile/list_folder_files.html:135 msgid "Share this folder" msgstr "" -#: pod/podfile/templates/podfile/list_folder_files.html:177 +#: pod/podfile/templates/podfile/list_folder_files.html:179 msgid "Upload Files" msgstr "" -#: pod/podfile/templates/podfile/list_folder_files.html:271 +#: pod/podfile/templates/podfile/list_folder_files.html:273 msgid "Download" msgstr "" @@ -3348,49 +3346,49 @@ msgstr "" msgid "Delete this record cannot be undo" msgstr "" -#: pod/recorder/models.py:30 pod/video/models.py:63 +#: pod/recorder/models.py:30 pod/video/models.py:65 msgid "None / All" msgstr "" -#: pod/recorder/models.py:31 pod/video/models.py:64 +#: pod/recorder/models.py:31 pod/video/models.py:66 msgid "Bachelor’s Degree" msgstr "" -#: pod/recorder/models.py:32 pod/video/models.py:65 +#: pod/recorder/models.py:32 pod/video/models.py:67 msgid "Master’s Degree" msgstr "" -#: pod/recorder/models.py:33 pod/video/models.py:66 +#: pod/recorder/models.py:33 pod/video/models.py:68 msgid "Doctorate" msgstr "" -#: pod/recorder/models.py:34 pod/video/models.py:67 pod/video/views.py:159 +#: pod/recorder/models.py:34 pod/video/models.py:69 pod/video/views.py:160 msgid "Other" msgstr "" -#: pod/recorder/models.py:39 pod/video/forms.py:147 pod/video/models.py:78 +#: pod/recorder/models.py:39 pod/video/forms.py:147 pod/video/models.py:82 msgid "Attribution 4.0 International (CC BY 4.0)" msgstr "" -#: pod/recorder/models.py:40 pod/video/forms.py:150 pod/video/models.py:79 +#: pod/recorder/models.py:40 pod/video/forms.py:150 pod/video/models.py:83 msgid "Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0)" msgstr "" -#: pod/recorder/models.py:44 pod/video/forms.py:154 pod/video/models.py:83 +#: pod/recorder/models.py:44 pod/video/forms.py:154 pod/video/models.py:87 msgid "" "Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)" msgstr "" -#: pod/recorder/models.py:47 pod/video/forms.py:158 pod/video/models.py:86 +#: pod/recorder/models.py:47 pod/video/forms.py:158 pod/video/models.py:90 msgid "Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)" msgstr "" -#: pod/recorder/models.py:50 pod/video/forms.py:163 pod/video/models.py:89 +#: pod/recorder/models.py:50 pod/video/forms.py:163 pod/video/models.py:93 msgid "" "Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)" msgstr "" -#: pod/recorder/models.py:54 pod/video/forms.py:169 pod/video/models.py:93 +#: pod/recorder/models.py:54 pod/video/forms.py:169 pod/video/models.py:97 msgid "Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)" msgstr "" @@ -3440,101 +3438,101 @@ msgstr "" msgid "Video type by default." msgstr "" -#: pod/recorder/models.py:148 pod/video/forms.py:182 pod/video/models.py:544 +#: pod/recorder/models.py:148 pod/video/forms.py:182 pod/video/models.py:549 msgid "Draft" msgstr "" -#: pod/recorder/models.py:150 pod/video/models.py:546 +#: pod/recorder/models.py:150 pod/video/models.py:551 msgid "" "If this box is checked, the video will be visible and accessible only by you " "and the additional owners." msgstr "" -#: pod/recorder/models.py:157 pod/video/models.py:553 +#: pod/recorder/models.py:157 pod/video/models.py:558 msgid "" "If this box is checked, the video will only be accessible to authenticated " "users." msgstr "" -#: pod/recorder/models.py:162 pod/video/models.py:558 +#: pod/recorder/models.py:162 pod/video/models.py:563 msgid "Select one or more groups who can access to this video" msgstr "" -#: pod/recorder/models.py:166 pod/video/models.py:562 +#: pod/recorder/models.py:166 pod/video/models.py:567 msgid "Viewing this video will not be possible without this password." msgstr "" -#: pod/recorder/models.py:169 pod/video/forms.py:122 pod/video/models.py:504 +#: pod/recorder/models.py:169 pod/video/forms.py:122 pod/video/models.py:509 #: pod/video_search/templates/search/search.html:150 msgid "University course" msgstr "" -#: pod/recorder/models.py:171 pod/video/forms.py:123 pod/video/models.py:506 +#: pod/recorder/models.py:171 pod/video/forms.py:123 pod/video/models.py:511 msgid "Select an university course as audience target of the content." msgstr "" -#: pod/recorder/models.py:174 pod/video/forms.py:129 pod/video/models.py:509 +#: pod/recorder/models.py:174 pod/video/forms.py:129 pod/video/models.py:514 #: pod/video_search/templates/search/search.html:137 msgid "Main language" msgstr "" -#: pod/recorder/models.py:176 pod/video/forms.py:130 pod/video/models.py:511 +#: pod/recorder/models.py:176 pod/video/forms.py:130 pod/video/models.py:516 msgid "Select the main language used in the content." msgstr "" -#: pod/recorder/models.py:178 pod/video/forms.py:201 pod/video/models.py:513 +#: pod/recorder/models.py:178 pod/video/forms.py:201 pod/video/models.py:518 #: pod/video/templates/videos/add_video.html:52 #: pod/video/templates/videos/add_video.html:98 msgid "Transcript" msgstr "" -#: pod/recorder/models.py:179 pod/video/models.py:514 +#: pod/recorder/models.py:179 pod/video/models.py:519 #: pod/video/templates/videos/add_video.html:53 msgid "Check this box if you want to transcript the audio.(beta version)" msgstr "" -#: pod/recorder/models.py:182 pod/video/models.py:517 +#: pod/recorder/models.py:182 pod/video/models.py:522 msgid "" "Separate tags with spaces, enclose the tags consist of several words in " "quotation marks." msgstr "" -#: pod/recorder/models.py:190 pod/video/forms.py:143 pod/video/models.py:525 +#: pod/recorder/models.py:190 pod/video/forms.py:143 pod/video/models.py:530 msgid "Licence" msgstr "" -#: pod/recorder/models.py:198 pod/video/forms.py:172 pod/video/models.py:392 -#: pod/video/models.py:533 +#: pod/recorder/models.py:198 pod/video/forms.py:172 pod/video/models.py:397 +#: pod/video/models.py:538 msgid "Themes" msgstr "" #: pod/recorder/models.py:200 pod/video/forms.py:140 pod/video/forms.py:176 -#: pod/video/models.py:535 pod/video/models.py:1534 +#: pod/video/models.py:540 pod/video/models.py:1578 msgid "" "Hold down \"Control\", or \"Command\" on a Mac, to select more than one." msgstr "" -#: pod/recorder/models.py:203 pod/video/models.py:538 +#: pod/recorder/models.py:203 pod/video/models.py:543 msgid "allow downloading" msgstr "" -#: pod/recorder/models.py:204 pod/video/models.py:539 +#: pod/recorder/models.py:204 pod/video/models.py:544 msgid "Check this box if you to allow downloading of the encoded files" msgstr "" -#: pod/recorder/models.py:207 pod/video/models.py:540 +#: pod/recorder/models.py:207 pod/video/models.py:545 msgid "video 360" msgstr "" -#: pod/recorder/models.py:208 pod/video/models.py:541 +#: pod/recorder/models.py:208 pod/video/models.py:546 msgid "Check this box if you want to use the 360 player for the video" msgstr "" -#: pod/recorder/models.py:211 pod/video/models.py:584 +#: pod/recorder/models.py:211 pod/video/models.py:589 msgid "Disable comment" msgstr "" -#: pod/recorder/models.py:213 pod/video/models.py:585 +#: pod/recorder/models.py:213 pod/video/models.py:590 msgid "Allows you to turn off all comments on this video." msgstr "" @@ -3596,8 +3594,8 @@ msgstr "" msgid "File size" msgstr "" -#: pod/recorder/models.py:320 pod/video/models.py:500 pod/video/models.py:1364 -#: pod/video/models.py:1423 +#: pod/recorder/models.py:320 pod/video/models.py:505 pod/video/models.py:1408 +#: pod/video/models.py:1467 msgid "Date added" msgstr "" @@ -3761,7 +3759,7 @@ msgid "Transcript selected" msgstr "" #: pod/video/admin.py:268 pod/video/forms.py:236 pod/video/forms.py:596 -#: pod/video/forms.py:598 pod/video/models.py:245 +#: pod/video/forms.py:598 pod/video/models.py:250 msgid "Owners" msgstr "" @@ -3769,12 +3767,12 @@ msgstr "" msgid "File field" msgstr "" -#: pod/video/forms.py:90 pod/video/models.py:458 +#: pod/video/forms.py:90 pod/video/models.py:463 #: pod/video/templates/videos/add_video.html:88 msgid "You can send an audio or video file." msgstr "" -#: pod/video/forms.py:91 pod/video/views.py:1639 +#: pod/video/forms.py:91 pod/video/views.py:1644 #, python-format msgid "The following formats are supported: %s" msgstr "" @@ -3807,7 +3805,7 @@ msgid "" "list, please temporary select “Other” and contact us to explain your needs." msgstr "" -#: pod/video/forms.py:108 pod/video/models.py:487 +#: pod/video/forms.py:108 pod/video/models.py:492 msgid "Additional owners" msgstr "" @@ -3819,7 +3817,7 @@ msgid "" msgstr "" #: pod/video/forms.py:114 pod/video/forms.py:228 pod/video/forms.py:254 -#: pod/video/models.py:230 pod/video/models.py:313 pod/video/models.py:497 +#: pod/video/models.py:235 pod/video/models.py:318 pod/video/models.py:502 msgid "" "In this field you can describe your content, add all needed related " "information, and format the result using the toolbar." @@ -3903,11 +3901,11 @@ msgid "" "completion page to improve it." msgstr "" -#: pod/video/forms.py:232 pod/video/models.py:242 +#: pod/video/forms.py:232 pod/video/models.py:247 msgid "Extra style" msgstr "" -#: pod/video/forms.py:232 pod/video/models.py:237 +#: pod/video/forms.py:232 pod/video/models.py:242 msgid "Background color" msgstr "" @@ -4040,330 +4038,330 @@ msgstr "" msgid "In %(deadline)s days" msgstr "" -#: pod/video/models.py:120 +#: pod/video/models.py:124 msgid "Private -" msgstr "" -#: pod/video/models.py:121 +#: pod/video/models.py:125 msgid "Private +" msgstr "" -#: pod/video/models.py:122 +#: pod/video/models.py:126 msgid "Public" msgstr "" -#: pod/video/models.py:135 +#: pod/video/models.py:139 #, python-format msgid "%(app)s version" msgstr "" -#: pod/video/models.py:218 pod/video/models.py:302 +#: pod/video/models.py:223 pod/video/models.py:307 msgid "" "Please choose a title as short and accurate as possible, reflecting the main " "subject / context of the content.(max length: 100 characters)" msgstr "" -#: pod/video/models.py:239 +#: pod/video/models.py:244 msgid "" "The background color for your channel. You can use the format #. i.e.: " "#ff0000 for red" msgstr "" -#: pod/video/models.py:243 +#: pod/video/models.py:248 msgid "The style will be added to your channel to show it" msgstr "" -#: pod/video/models.py:253 +#: pod/video/models.py:258 msgid "" "If checked, the channel appear in a list of available channels on the " "platform." msgstr "" -#: pod/video/models.py:260 pod/video/models.py:322 +#: pod/video/models.py:265 pod/video/models.py:327 #: pod/video_search/templates/search/search.html:124 msgid "Channel" msgstr "" -#: pod/video/models.py:299 +#: pod/video/models.py:304 msgid "Theme parent" msgstr "" -#: pod/video/models.py:391 +#: pod/video/models.py:396 msgid "Theme" msgstr "" -#: pod/video/models.py:406 pod/video/models.py:432 +#: pod/video/models.py:411 pod/video/models.py:437 msgid "Icon" msgstr "" -#: pod/video/models.py:444 pod/video_search/templates/search/search.html:111 +#: pod/video/models.py:449 pod/video_search/templates/search/search.html:111 msgid "Discipline" msgstr "" -#: pod/video/models.py:462 +#: pod/video/models.py:467 msgid "" "Please choose a title as short and accurate as possible, reflecting the main " "subject / context of the content.(max length: 250 characters)" msgstr "" -#: pod/video/models.py:490 +#: pod/video/models.py:495 msgid "" "You can add additional owners to the video. They will have the same rights " "as you except that they can't delete this video." msgstr "" -#: pod/video/models.py:502 +#: pod/video/models.py:507 msgid "Date of event" msgstr "" -#: pod/video/models.py:567 pod/video/models.py:684 +#: pod/video/models.py:572 pod/video/models.py:694 msgid "Thumbnails" msgstr "" -#: pod/video/models.py:571 +#: pod/video/models.py:576 msgid "Overview" msgstr "" -#: pod/video/models.py:577 +#: pod/video/models.py:582 msgid "Is Video" msgstr "" -#: pod/video/models.py:580 +#: pod/video/models.py:585 msgid "Date to delete" msgstr "" -#: pod/video/models.py:592 +#: pod/video/models.py:597 msgid "videos" msgstr "" -#: pod/video/models.py:637 +#: pod/video/models.py:643 msgid "Sum of view" msgstr "" -#: pod/video/models.py:715 +#: pod/video/models.py:728 msgid "Is the video encoded ?" msgstr "" -#: pod/video/models.py:960 +#: pod/video/models.py:1004 msgid "Date" msgstr "" -#: pod/video/models.py:962 +#: pod/video/models.py:1006 msgid "Number of view" msgstr "" -#: pod/video/models.py:970 +#: pod/video/models.py:1014 msgid "View count" msgstr "" -#: pod/video/models.py:971 +#: pod/video/models.py:1015 msgid "View counts" msgstr "" -#: pod/video/models.py:976 +#: pod/video/models.py:1020 msgid "resolution" msgstr "" -#: pod/video/models.py:979 +#: pod/video/models.py:1023 msgid "" "Please use the only format x. i.e.: 640x360 or 1280x720 or " "1920x1080." msgstr "" -#: pod/video/models.py:983 pod/video/models.py:1052 pod/video/models.py:1059 +#: pod/video/models.py:1027 pod/video/models.py:1096 pod/video/models.py:1103 msgid "minrate" msgstr "" -#: pod/video/models.py:985 pod/video/models.py:991 pod/video/models.py:997 -#: pod/video/models.py:1003 +#: pod/video/models.py:1029 pod/video/models.py:1035 pod/video/models.py:1041 +#: pod/video/models.py:1047 msgid "" "Please use the only format k. i.e.: 300k or 600k or " "1000k." msgstr "" -#: pod/video/models.py:989 pod/video/models.py:1028 pod/video/models.py:1035 +#: pod/video/models.py:1033 pod/video/models.py:1072 pod/video/models.py:1079 msgid "bitrate video" msgstr "" -#: pod/video/models.py:995 pod/video/models.py:1040 pod/video/models.py:1047 +#: pod/video/models.py:1039 pod/video/models.py:1084 pod/video/models.py:1091 msgid "maxrate" msgstr "" -#: pod/video/models.py:1001 pod/video/models.py:1077 pod/video/models.py:1084 +#: pod/video/models.py:1045 pod/video/models.py:1121 pod/video/models.py:1128 msgid "bitrate audio" msgstr "" -#: pod/video/models.py:1006 +#: pod/video/models.py:1050 msgid "Make a MP4 version" msgstr "" -#: pod/video/models.py:1019 pod/video/models.py:1107 +#: pod/video/models.py:1063 pod/video/models.py:1151 msgid "rendition" msgstr "" -#: pod/video/models.py:1020 +#: pod/video/models.py:1064 msgid "renditions" msgstr "" -#: pod/video/models.py:1102 pod/video/models.py:1171 pod/video/models.py:1225 +#: pod/video/models.py:1146 pod/video/models.py:1215 pod/video/models.py:1269 msgid "Please use the only format in encoding choices:" msgstr "" -#: pod/video/models.py:1109 pod/video/models.py:1175 pod/video/models.py:1229 +#: pod/video/models.py:1153 pod/video/models.py:1219 pod/video/models.py:1273 msgid "Format" msgstr "" -#: pod/video/models.py:1113 pod/video/models.py:1177 pod/video/models.py:1231 +#: pod/video/models.py:1157 pod/video/models.py:1221 pod/video/models.py:1275 msgid "Please use the only format in format choices:" msgstr "" -#: pod/video/models.py:1116 pod/video/models.py:1180 pod/video/models.py:1234 +#: pod/video/models.py:1160 pod/video/models.py:1224 pod/video/models.py:1278 msgid "encoding source file" msgstr "" -#: pod/video/models.py:1138 +#: pod/video/models.py:1182 msgid "Encoding video" msgstr "" -#: pod/video/models.py:1139 +#: pod/video/models.py:1183 msgid "Encoding videos" msgstr "" -#: pod/video/models.py:1190 +#: pod/video/models.py:1234 msgid "Encoding audio" msgstr "" -#: pod/video/models.py:1191 +#: pod/video/models.py:1235 msgid "Encoding audios" msgstr "" -#: pod/video/models.py:1239 +#: pod/video/models.py:1283 msgid "Video Playlist" msgstr "" -#: pod/video/models.py:1240 +#: pod/video/models.py:1284 msgid "Video Playlists" msgstr "" -#: pod/video/models.py:1286 +#: pod/video/models.py:1330 msgid "Encoding log" msgstr "" -#: pod/video/models.py:1287 +#: pod/video/models.py:1331 msgid "Encoding logs" msgstr "" -#: pod/video/models.py:1297 pod/video/models.py:1302 +#: pod/video/models.py:1341 pod/video/models.py:1346 msgid "Video version" msgstr "" -#: pod/video/models.py:1299 +#: pod/video/models.py:1343 msgid "Video default version." msgstr "" -#: pod/video/models.py:1303 +#: pod/video/models.py:1347 msgid "Video versions" msgstr "" -#: pod/video/models.py:1328 +#: pod/video/models.py:1372 msgid "Encoding steps" msgstr "" -#: pod/video/models.py:1337 pod/video/models.py:1344 pod/video/models.py:1360 -#: pod/video/views.py:1312 +#: pod/video/models.py:1381 pod/video/models.py:1388 pod/video/models.py:1404 +#: pod/video/views.py:1314 msgid "Note" msgstr "" -#: pod/video/models.py:1345 +#: pod/video/models.py:1389 msgid "Notes" msgstr "" -#: pod/video/models.py:1356 +#: pod/video/models.py:1400 msgid "Note availibility level" msgstr "" -#: pod/video/models.py:1358 +#: pod/video/models.py:1402 msgid "Select an availability level for the note." msgstr "" -#: pod/video/models.py:1362 +#: pod/video/models.py:1406 msgid "Timestamp" msgstr "" -#: pod/video/models.py:1366 pod/video/models.py:1425 +#: pod/video/models.py:1410 pod/video/models.py:1469 msgid "Date modified" msgstr "" -#: pod/video/models.py:1369 +#: pod/video/models.py:1413 msgid "Advanced Note" msgstr "" -#: pod/video/models.py:1370 +#: pod/video/models.py:1414 msgid "Advanced Notes" msgstr "" -#: pod/video/models.py:1416 +#: pod/video/models.py:1460 msgid "Comment availibility level" msgstr "" -#: pod/video/models.py:1418 +#: pod/video/models.py:1462 msgid "Select an availability level for the comment." msgstr "" -#: pod/video/models.py:1428 +#: pod/video/models.py:1472 msgid "Note comment" msgstr "" -#: pod/video/models.py:1429 +#: pod/video/models.py:1473 msgid "Note comments" msgstr "" -#: pod/video/models.py:1447 +#: pod/video/models.py:1491 msgid "Date for deletion" msgstr "" -#: pod/video/models.py:1450 pod/video/models.py:1532 +#: pod/video/models.py:1494 pod/video/models.py:1576 #: pod/video/templates/videos/video.html:76 #: pod/video/templates/videos/videos.html:8 #: pod/video/templates/videos/videos.html:17 msgid "Videos" msgstr "" -#: pod/video/models.py:1453 +#: pod/video/models.py:1497 msgid "Video to delete" msgstr "" -#: pod/video/models.py:1454 +#: pod/video/models.py:1498 msgid "Videos to delete" msgstr "" -#: pod/video/models.py:1474 pod/video/templates/videos/video-comment.html:9 +#: pod/video/models.py:1518 pod/video/templates/videos/video-comment.html:9 msgid "Comments" msgstr "" -#: pod/video/models.py:1515 +#: pod/video/models.py:1559 msgid "Vote" msgstr "" -#: pod/video/models.py:1516 +#: pod/video/models.py:1560 msgid "Votes" msgstr "" -#: pod/video/models.py:1524 pod/video/templates/videos/category_modal.html:13 +#: pod/video/models.py:1568 pod/video/templates/videos/category_modal.html:13 msgid "Category title" msgstr "" -#: pod/video/models.py:1526 +#: pod/video/models.py:1570 msgid "" "Please choose a title as short and accurate as possible, reflecting the main " "subject / context of the content.(max length : 100 characters)" msgstr "" -#: pod/video/models.py:1552 pod/video/templates/videos/category_modal.html:7 +#: pod/video/models.py:1596 pod/video/templates/videos/category_modal.html:7 msgid "Category" msgstr "" -#: pod/video/models.py:1553 +#: pod/video/models.py:1597 #: pod/video/templates/videos/filter_aside_category.html:14 msgid "Categories" msgstr "" @@ -4409,7 +4407,7 @@ msgstr "" msgid "Edit the channel" msgstr "" -#: pod/video/templates/channel/channel.html:98 +#: pod/video/templates/channel/channel.html:100 #: pod/video/templates/videos/my_videos.html:14 #: pod/video/templates/videos/my_videos.html:33 #: pod/video/templates/videos/videos.html:6 @@ -4423,7 +4421,7 @@ msgid_plural "%(counter)s videos found" msgstr[0] "" msgstr[1] "" -#: pod/video/templates/channel/channel.html:135 +#: pod/video/templates/channel/channel.html:137 msgid "Themes of " msgstr "" @@ -4643,8 +4641,8 @@ msgstr "" msgid "Edit the category" msgstr "" -#: pod/video/templates/videos/footer_link.html:5 -msgid "link" +#: pod/video/templates/videos/footer_link.html:4 +msgid "Links" msgstr "" #: pod/video/templates/videos/last_videos.html:7 @@ -4904,7 +4902,7 @@ msgstr "" msgid "The video is currently being transcripted." msgstr "" -#: pod/video/templates/videos/video.html:159 +#: pod/video/templates/videos/video.html:156 msgid "" "This video is chaptered. Click the chapter button on the video player to view them." @@ -5004,7 +5002,15 @@ msgid "Creative Commons license" msgstr "" #: pod/video/templates/videos/video_list.html:10 -msgid "Sorry, no video found" +msgid "Sorry, no video found." +msgstr "" + +#: pod/video/templates/videos/video_list.html:15 +msgid "More" +msgstr "" + +#: pod/video/templates/videos/video_list.html:18 +msgid "Loading..." msgstr "" #: pod/video/templates/videos/video_note_comments_display.html:8 @@ -5131,149 +5137,154 @@ msgid "" "available on %(site_title)s." msgstr "" -#: pod/video/views.py:232 pod/video/views.py:272 +#: pod/video/views.py:233 pod/video/views.py:273 msgid "You cannot edit this channel." msgstr "" -#: pod/video/views.py:249 pod/video/views.py:724 +#: pod/video/views.py:250 pod/video/views.py:726 msgid "The changes have been saved." msgstr "" -#: pod/video/views.py:601 +#: pod/video/views.py:603 msgid "You don't have access to this playlist." msgstr "" -#: pod/video/views.py:662 +#: pod/video/views.py:664 msgid "You cannot watch this video." msgstr "" -#: pod/video/views.py:696 +#: pod/video/views.py:698 msgid "You cannot edit this video." msgstr "" -#: pod/video/views.py:774 +#: pod/video/views.py:776 msgid "You cannot delete this video." msgstr "" -#: pod/video/views.py:784 +#: pod/video/views.py:786 msgid "The video has been deleted." msgstr "" -#: pod/video/views.py:900 +#: pod/video/views.py:902 #, python-format msgid "You cannot %s this note or comment." msgstr "" -#: pod/video/views.py:923 +#: pod/video/views.py:925 msgid "You cannot see this note or comment." msgstr "" -#: pod/video/views.py:1159 pod/video/views.py:1173 pod/video/views.py:1196 +#: pod/video/views.py:1161 pod/video/views.py:1175 pod/video/views.py:1198 msgid "The comment has been saved." msgstr "" -#: pod/video/views.py:1186 pod/video/views.py:1211 +#: pod/video/views.py:1188 pod/video/views.py:1213 msgid "The note has been saved." msgstr "" -#: pod/video/views.py:1251 +#: pod/video/views.py:1253 msgid "The note has been deleted." msgstr "" -#: pod/video/views.py:1259 +#: pod/video/views.py:1261 msgid "The comment has been deleted." msgstr "" -#: pod/video/views.py:1305 pod/video/views.py:1308 pod/video/views.py:1314 +#: pod/video/views.py:1307 pod/video/views.py:1310 pod/video/views.py:1316 msgid "None" msgstr "" -#: pod/video/views.py:1327 +#: pod/video/views.py:1329 msgid "ID" msgstr "" -#: pod/video/views.py:1327 +#: pod/video/views.py:1329 msgid "Status" msgstr "" -#: pod/video/views.py:1328 +#: pod/video/views.py:1330 msgid "Parent note id" msgstr "" -#: pod/video/views.py:1328 +#: pod/video/views.py:1330 msgid "Parent comment id" msgstr "" -#: pod/video/views.py:1329 +#: pod/video/views.py:1331 msgid "Created on" msgstr "" -#: pod/video/views.py:1329 +#: pod/video/views.py:1331 msgid "Modified on" msgstr "" -#: pod/video/views.py:1330 +#: pod/video/views.py:1332 msgid "Note timestamp" msgstr "" -#: pod/video/views.py:1357 pod/video/views.py:1385 +#: pod/video/views.py:1359 pod/video/views.py:1387 msgid "You cannot access to this view." msgstr "" -#: pod/video/views.py:1506 +#: pod/video/views.py:1509 msgid "Pod video viewing statistics" msgstr "" -#: pod/video/views.py:1513 +#: pod/video/views.py:1516 #, python-format msgid "Video viewing statistics for %s" msgstr "" -#: pod/video/views.py:1517 +#: pod/video/views.py:1520 #, python-format msgid "Video viewing statistics for the channel %s" msgstr "" -#: pod/video/views.py:1521 +#: pod/video/views.py:1524 #, python-format msgid "Video viewing statistics for the theme %s" msgstr "" -#: pod/video/views.py:1563 +#: pod/video/views.py:1566 #, python-format msgid "You do not have access rights to this video: %s " msgstr "" -#: pod/video/views.py:1583 +#: pod/video/views.py:1582 +#, python-format +msgid "The following %s does not exist or contain any videos: %s" +msgstr "" + +#: pod/video/views.py:1588 #, python-format -msgid "The following video does not exist : %s" +msgid "The following video does not exist: %s" msgstr "" -#: pod/video/views.py:1914 +#: pod/video/views.py:1920 msgid "You do not have rights to delete this comment" msgstr "" -#: pod/video/views.py:2005 pod/video/views.py:2071 +#: pod/video/views.py:2011 pod/video/views.py:2077 msgid "One or many videos already have a category." msgstr "" -#: pod/video/views.py:2041 pod/video/views.py:2111 +#: pod/video/views.py:2047 pod/video/views.py:2117 msgid "Title field is required" msgstr "" -#: pod/video/views.py:2046 pod/video/views.py:2116 pod/video/views.py:2158 +#: pod/video/views.py:2052 pod/video/views.py:2122 pod/video/views.py:2164 msgid "Method Not Allowed" msgstr "" -#: pod/video/views.py:2088 +#: pod/video/views.py:2094 msgid "Category updated successfully." msgstr "" -#: pod/video/views.py:2106 +#: pod/video/views.py:2112 msgid "You do not have rights to edit this category" msgstr "" -#: pod/video/views.py:2152 +#: pod/video/views.py:2158 msgid "You do not have rights to delete this category" msgstr "" @@ -5298,6 +5309,6 @@ msgstr "" msgid "Advanced search" msgstr "" -#: pod/video_search/views.py:60 +#: pod/video_search/views.py:63 msgid "Remove this filter" msgstr "" diff --git a/pod/video/models.py b/pod/video/models.py index 8b943b69f3..0e03599ea0 100755 --- a/pod/video/models.py +++ b/pod/video/models.py @@ -708,7 +708,8 @@ def get_thumbnail_card(self): get_current_site(None).domain, settings.STATIC_URL, DEFAULT_THUMBNAIL]) - return '%s' % ( + return '%s' % ( thumbnail_url, self.title.replace('"', "'")) @property diff --git a/pod/video/templates/videos/video-script.html b/pod/video/templates/videos/video-script.html index fea3f2bdf7..8fd274ba35 100644 --- a/pod/video/templates/videos/video-script.html +++ b/pod/video/templates/videos/video-script.html @@ -121,7 +121,7 @@ src: '{% if request.is_secure %}https://{%else%}http://{% endif %}{{request.get_host}}{{video.overview.url}}' }); {%endif%} - + {% if video.overlay_set.all %} var list_overlays = []; $('ul#overlays li').each(function() { @@ -147,7 +147,7 @@ {% if request.GET.is_iframe %} player.videoJsInfo(); {%endif%} - + player.videoJsLogo({imgsrc: '{% static LOGO_PLAYER %}', linktitle:'{{TITLE_ETB}} - {{TITLE_SITE}}', link:'{{LINK_PLAYER}}'}); {% else %} {% if video.get_video_m4a %} diff --git a/pod/video_search/views.py b/pod/video_search/views.py index 667b202910..67e918e581 100644 --- a/pod/video_search/views.py +++ b/pod/video_search/views.py @@ -77,7 +77,8 @@ def get_result_aggregations(result, selected_facets): else: if agg_term == "type.slug": del result["aggregations"]["type_title"] - if agg_term == "tags.slug": + if agg_term == "tags.slug" and ( + "tags_name" in result["aggregations"]): del result["aggregations"]["tags_name"] if agg_term == "disciplines.slug": del result["aggregations"]["disciplines_title"] From 891d229fdf5054b6bee36bd8c34204bb624c23ba Mon Sep 17 00:00:00 2001 From: Olivier Bado Date: Fri, 5 Mar 2021 17:12:49 +0100 Subject: [PATCH 059/261] Web optimization : + add "?ver={{VERSION}}" parameters to all static css/js links to force browser to ask server on each Pod upgrade. + add django-static-compress + some code formatting --- pod/custom/settings_local.py.example | 9 + pod/main/templates/base.html | 262 +++++++++++++-------------- pod/video/views.py | 7 +- pod_nginx.conf | 74 ++++---- requirements.txt | 1 + 5 files changed, 186 insertions(+), 167 deletions(-) diff --git a/pod/custom/settings_local.py.example b/pod/custom/settings_local.py.example index 2e0db783c0..2f9d9f6972 100644 --- a/pod/custom/settings_local.py.example +++ b/pod/custom/settings_local.py.example @@ -143,6 +143,15 @@ FILE_UPLOAD_TEMP_DIR = "/var/tmp" """ STATIC_ROOT = "/pod/static" +""" +# Indique à django de compresser automatiquement +# les fichiers css/js les plus gros lors du collectstatic +# pour optimiser les tailles de requetes. +# À combiner avec un réglage webserver ("gzip_static on;" sur nginx) +# voir https://github.com/whs/django-static-compress +""" +STATICFILES_STORAGE = 'static_compress.CompressedStaticFilesStorage' + """ # Chemin absolu du système de fichiers pointant vers le répertoire # qui contiendra les fichiers téléversés par les utilisateurs. diff --git a/pod/main/templates/base.html b/pod/main/templates/base.html index b43a4953f4..cef689739a 100644 --- a/pod/main/templates/base.html +++ b/pod/main/templates/base.html @@ -2,142 +2,142 @@ {% get_current_language as LANGUAGE_CODE %} - {% spaceless %} + {% spaceless %} - - - - - {% block opengraph %} - - - - - - - - - {% endblock %} - {% if FAVICON %} - - {% endif %} - - {% if BOOTSTRAP_CUSTOM %} - - {% else %} - - {% endif %} - - - {% if CSS_OVERRIDE %} - - {% endif %} + + + + + {% block opengraph %} + + + + + + + + + {% endblock %} + {% if FAVICON %} + + {% endif %} + + {% if BOOTSTRAP_CUSTOM %} + + {% else %} + + {% endif %} + + + {% if CSS_OVERRIDE %} + + {% endif %} - - {% block more_style %} - {% endblock more_style %} + + {% block more_style %}{% endblock more_style %} - - - - - - {{ TITLE_SITE }} - {% block page_title %}{% endblock %} + + + + + + {{ TITLE_SITE }} - {% block page_title %}{% endblock %} - {% block page_extra_head %}{% endblock %} - {% if request.GET.is_iframe %} - - {% endif %} + {% block page_extra_head %}{% endblock %} + {% if request.GET.is_iframe %} + + {% endif %} + {% endspaceless %} - {% endspaceless %} - - - {% if PRE_HEADER_TEMPLATE %}{% include PRE_HEADER_TEMPLATE %}{% endif %} - - - {% include 'navbar_collapse.html' %} - {% block content %} - {% if request.path == "/" and MAINTENANCE_MODE %} - {% get_maintenance_welcome as maintenance_text %} -
{{maintenance_text}}
- {%endif%} -
-
- + + {% if PRE_HEADER_TEMPLATE %}{% include PRE_HEADER_TEMPLATE %}{% endif %} + + + {% include 'navbar_collapse.html' %} + {% block content %} + {% if request.path == "/" and MAINTENANCE_MODE %} + {% get_maintenance_welcome as maintenance_text %} +
{{maintenance_text}}
+ {%endif%} +
+
+ -
-
- -
- {% block page_content %} -

Contenu block page_content

- {% endblock page_content %} -
- - {% if request.path == "/" %} - {% include "videos/last_videos.html" %} - {% endif %} -
- -
-
-
- {% endblock content %} -
- {% include 'footer.html' %} -
+
+
+ +
+ {% block page_content %} +

Contenu block page_content

+ {% endblock page_content %} +
+ + {% if request.path == "/" %} + {% include "videos/last_videos.html" %} + {% endif %} +
+ +
+
+
+ {% endblock content %} - {% if messages %} -
- {% for message in messages %} - - {% endfor %} -
- {% endif %} - - - - {% block more_script %} - {% endblock more_script %} - - - {% if POST_FOOTER_TEMPLATE %}{% include POST_FOOTER_TEMPLATE %}{% endif %} - {% if TRACKING_TEMPLATE %}{% include TRACKING_TEMPLATE %}{% endif %} - +
+ {% include 'footer.html' %} +
+ + {% if messages %} +
+ {% for message in messages %} + + {% endfor %} +
+ {% endif %} + + + + + {% block more_script %}{% endblock more_script %} + + + + {% if POST_FOOTER_TEMPLATE %}{% include POST_FOOTER_TEMPLATE %}{% endif %} + {% if TRACKING_TEMPLATE %}{% include TRACKING_TEMPLATE %}{% endif %} + diff --git a/pod/video/views.py b/pod/video/views.py index 66ea3c4d6d..de89b1a152 100644 --- a/pod/video/views.py +++ b/pod/video/views.py @@ -1425,8 +1425,9 @@ def video_oembed(request): data['provider_url'], reverse('videos'), video.owner.username) data['html'] = ( "" + + "?is_iframe=true\" width=\"640\" height=\"360\" " + + "style=\"padding: 0; margin: 0; border:0\" " + + "allowfullscreen loading='lazy'>" ) % { 'provider': data['provider_url'], 'video_url': reverse('video', kwargs={'slug': video.slug}), @@ -1584,7 +1585,7 @@ def stats_view(request, slug=None, slug_t=None): elif request.method == "GET" and target == "video" and not videos: return HttpResponseNotFound( - _("The following video does not exist : %s") % slug) + _("The following video does not exist: %s") % slug) if request.method == "GET" and ( not videos and target in ("channel", "theme", "videos")): diff --git a/pod_nginx.conf b/pod_nginx.conf index 8f3379cabc..5eafe3f921 100644 --- a/pod_nginx.conf +++ b/pod_nginx.conf @@ -8,47 +8,55 @@ #} # the upstream component nginx needs to connect to upstream django { - # server unix:///path/to/your/mysite/mysite.sock; # for a file socket - server unix:///usr/local/django_projects/podv2/podv2.sock; - # server 127.0.0.1:8001; # for a web port socket (we'll use this first) + # server unix:///path/to/your/mysite/mysite.sock; # for a file socket + server unix:///usr/local/django_projects/podv2/podv2.sock; + # server 127.0.0.1:8001; # for a web port socket (we'll use this first) } # configuration of the server server { - # the port your site will be served on - listen 80; - # the domain name it will serve for - server_name pod.univ.fr; # substitute your machine's IP address or FQDN - charset utf-8; + # the port your site will be served on + listen 80; + # the domain name it will serve for + server_name pod.univ.fr; # substitute your machine's IP address or FQDN + charset utf-8; - # max upload size - client_max_body_size 4G; # adjust to taste - # Allow to download large files - uwsgi_max_temp_file_size 0; + # max upload size + client_max_body_size 4G; # adjust to taste + # Allow to download large files + uwsgi_max_temp_file_size 0; - #location ^~ /video_edit { - # track_uploads uploadp 30s - #} + #location ^~ /video_edit { + # track_uploads uploadp 30s + #} - location ^~ /progressbarupload/upload_progress { - # JSON document rather than JSONP callback, pls - upload_progress_json_output; - report_uploads uploadp; - } + location ^~ /progressbarupload/upload_progress { + # JSON document rather than JSONP callback, pls + upload_progress_json_output; + report_uploads uploadp; + } - # Django media - location /media { - alias /usr/local/django_projects/podv2/pod/media; # your Django project's media files - amend as required - } + # Django media + location /media { + expires 1y; + add_header Cache-Control "public"; + gzip on; + gzip_types text/vtt; + alias /usr/local/django_projects/podv2/pod/media; # your Django project's media files - amend as required + } - location /static { - alias /usr/local/django_projects/podv2/pod/static; # your Django project's static files - amend as required - } + location /static { + expires 1y; + add_header Cache-Control "public"; + gzip_static on; + gzip_types text/plain application/xml text/css text/javascript application/javascript image/svg+xml; + alias /usr/local/django_projects/podv2/pod/static; # your Django project's static files - amend as required + } - # Finally, send all non-media requests to the Django server. - location / { - uwsgi_pass django; - include /usr/local/django_projects/podv2/uwsgi_params; # the uwsgi_params file you installed - track_uploads uploadp 30s; - } + # Finally, send all non-media requests to the Django server. + location / { + uwsgi_pass django; + include /usr/local/django_projects/podv2/uwsgi_params; # the uwsgi_params file you installed + track_uploads uploadp 30s; + } } diff --git a/requirements.txt b/requirements.txt index db442a6c18..15d2ea4082 100644 --- a/requirements.txt +++ b/requirements.txt @@ -27,3 +27,4 @@ django-chunked-upload==2.0.0 requests==2.25.1 chardet==4.0.0 django-cookies-samesite==0.8.0 +django-static-compress>=1.2.1 From 70f874da8b7835bbb6119a69b008869362fa9f95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Bonavent?= Date: Tue, 9 Mar 2021 09:34:40 +0100 Subject: [PATCH 060/261] Main PHP script for bbb-pod-live. Must be installed on bbb-pod-live servers --- scripts/bbb-pod-live/bbb-pod-live.php | 843 ++++++++++++++++++++++++++ 1 file changed, 843 insertions(+) create mode 100644 scripts/bbb-pod-live/bbb-pod-live.php diff --git a/scripts/bbb-pod-live/bbb-pod-live.php b/scripts/bbb-pod-live/bbb-pod-live.php new file mode 100644 index 0000000000..b0bb80ac6a --- /dev/null +++ b/scripts/bbb-pod-live/bbb-pod-live.php @@ -0,0 +1,843 @@ +getMessage(); +} + +// Envoi d'un message à l'administrateur en cas d'erreur de script +if ($GLOBALS["txtErrorInScript"] != "") { + $to = ADMIN_EMAIL; + $subject = "[BBB-POD-LIVE] Erreur rencontrée"; + $message = nl2br($GLOBALS["txtErrorInScript"]); + + $headers = "MIME-Version: 1.0\r\n"; + $headers .= "Content-type: text/html; charset=utf-8\r\n"; + + mail ($to, $subject, $message, $headers); +} +/********** Fin de la phase principale**********/ + +/** + * Procédure de création et de configuration initile des différents plugin BigBlueButton-liveStreaming. + * Un répertoire, par nombre de directs gérés par ce serveur (cf. NUMBER_LIVES), sera créé sous la forme bbb-live-streaming+incrémental. + * Le fichier compose.yml sera copié depuis le répertoire courant (fichier docker-compose.default.yml). + */ +function configureInitialBigBlueButtonLiveStreaming() { + writeLog("----- Configuration des plugins nécessaires : configureBigBlueButtonLiveStreaming()-----", "DEBUG"); + // Création des répertoires et des fichiers compose pour le plugin BigBlueButton-liveStreaming + for ($i = 1; $i <= NUMBER_LIVES; $i++) { + // Définition du répertoire + $directoryLiveStreaming = checkEndSlash(PHYSICAL_BASE_ROOT) . "bbb-live-streaming$i/"; + writeLog("Vérification pour le direct $i : $directoryLiveStreaming", "DEBUG"); + // Définition du fichier compose.yml dans ce répertoire + $fichierCompose = $directoryLiveStreaming . "docker-compose.yml"; + // Création du répertoire et du fichier la 1° fois + if (! file_exists($fichierCompose)) { + // Création du répertoire + writeLog(" + Création du répertoire $directoryLiveStreaming", "DEBUG"); + @mkdir("$directoryLiveStreaming", 0755); + // Téléchargement du fichier compose depuis Github + writeLog(" + Copie du fichier docker-compose.default.yml du répertoire courant", "DEBUG"); + $cmdCp = "cp ./docker-compose.default.yml $fichierCompose"; + exec("$cmdCp 2>&1", $aRetourVerificationCp, $sRetourVerificationCp); + if ($sRetourVerificationCp == 0) { + writeLog(" + Copie du fichier $fichierCompose réalisée", "DEBUG"); + } + else { + writeLog(" - Commande '$cmdCp' : $aRetourVerificationCp[0]", "ERROR", __FILE__, __LINE__); + } + } + } +} + +/** + * Procédure permettant de démarrer des directs, si des usagers en ont fait la demande dans Pod. + * Pour cela, on utilise l'API Rest de Pod. + * Cette procédure permet d'identifier si un slot est disponible pour être utilisé pour lancer un direct. + */ +function startLives() { + writeLog("-----Démarrage des directs : startLives()-----", "DEBUG"); + + // Recherche si des lives sont en cours + $cmdStatus1 = "curl --silent -H 'Content-Type: application/json' "; + $cmdStatus1 .= "-H 'Authorization: Token " . POD_TOKEN . "' "; + $cmdStatus1 .= "-X GET " . checkEndWithoutSlash(POD_URL). "/rest/bbb_livestream/?status=1"; + + $verificationStatus1 = exec("$cmdStatus1 2>&1", $aRetourVerificationStatus1, $sRetourVerificationStatus1); + + writeLog("Recherche si des lives sont en cours", "DEBUG"); + + // En cas d'erreur, le code de retour est différent de 0 + if ($sRetourVerificationStatus1 == 0) { + writeLog(" + Commande '$cmdStatus1' : $aRetourVerificationStatus1[0]", "DEBUG"); + + $oListeSessions = json_decode($aRetourVerificationStatus1[0]); + // Recherche des lives existants en cours, sauvegardés dans Pod + for ($i = 0; $i < $oListeSessions->count; $i++) { + // Identifiant du live dans Pod + $idLive = $oListeSessions->results[$i]->id; + // Dans Pod, l'information est sauvegardé sous la forme NUMERO_SERVEUR/NUMERO_REPERTOIRE_bbb_live_streaming + $server = $oListeSessions->results[$i]->server; + // Le live est il déjà en cours sur un des serveurs BBB-POD-LIVE ? + $status = $oListeSessions->results[$i]->status; + // Utilisateur ayant lancé ce live + $user = $oListeSessions->results[$i]->user; + // Prise en compte seulement des lives en cours de ce serveur + if (($status == 1) && (strpos("$server", SERVER_NUMBER . "/") !== false)) { + // Sauvegarde du NUMERO_REPERTOIRE_bbb_live_streaming + $processInProgress = str_replace(SERVER_NUMBER . "/", "", $server); + // Utilisation d'une classe standard + $liveInProgress = new stdClass(); + $liveInProgress->id = $idLive; + $liveInProgress->idBbbLiveStreaming = $processInProgress; + // Ajout de cet objet au tableau des lives en cours sur ce serveur + $GLOBALS["livesInProgressOnThisServer"][] = $liveInProgress; + writeLog(" => Le live $idLive de $user est toujours en cours sur le serveur/bbb_live_streaming : $server.", "DEBUG"); + } + } + } + else { + writeLog(" + Commande '$cmdStatus1' : $sRetourVerificationStatus1[0]", "ERROR", __FILE__, __LINE__); + } + + // Recherche si des utilisateurs ont lancé des lives depuis Pod + $cmdStatus0 = "curl --silent -H 'Content-Type: application/json' "; + $cmdStatus0 .= "-H 'Authorization: Token " . POD_TOKEN . "' "; + $cmdStatus0 .= "-X GET " . checkEndWithoutSlash(POD_URL) . "/rest/bbb_livestream/?status=0"; + + $verificationStatus0 = exec("$cmdStatus0 2>&1", $aRetourVerificationStatus0, $sRetourVerificationStatus0); + + writeLog("Recherche si des utilisateurs ont lancé des lives depuis Pod", "DEBUG"); + + // En cas d'erreur, le code de retour est différent de 0 + if ($sRetourVerificationStatus0 == 0) { + writeLog(" + Commande '$cmdStatus0' : $aRetourVerificationStatus0[0]", "DEBUG"); + + $oListeSessions = json_decode($aRetourVerificationStatus0[0]); + // Recherche des nouvelles demandes de lives, sauvegardées dans Pod + for ($i = 0; $i < $oListeSessions->count; $i++) { + // Identifiant du live BBB dans Pod + $idLive = $oListeSessions->results[$i]->id; + // Adresse de la session dans Pod + $urlMeeting = $oListeSessions->results[$i]->meeting; + // Nom du serveur/processus déjà en charge de ce live + $server = $oListeSessions->results[$i]->server; + // Le live est il déjà en cours sur un des serveurs BBB-POD-LIVE ? + $status = $oListeSessions->results[$i]->status; + // Utilisateur ayant lancé ce live + $user = $oListeSessions->results[$i]->user; + // Identifiant du répertoire bbb-live-streaming qui s'occupera de réaliser le live, si disponible + $idBbbLiveStreaming = 0; + // Recherche si ce serveur peut encore lancer un direct + for ($j = 1; $j <= NUMBER_LIVES; $j++) { + // Variable de travail + $idBbbLiveStreamingUsed = false; + foreach ($GLOBALS["livesInProgressOnThisServer"] as $ligneLiveInProgressOnThisServer) { + // Cet idBbbLiveStreaming est déjà utilisé + if ($ligneLiveInProgressOnThisServer->idBbbLiveStreaming == $j) { + $idBbbLiveStreamingUsed = true; + } + } + // Le slot idBbbLiveStreaming est non utilisé + if (! $idBbbLiveStreamingUsed) { + // Un slot est disponible + $idBbbLiveStreaming = $j; + // Ajout de l'information aux lives en cours sur ce serveur + $liveInProgress2 = new stdClass(); + $liveInProgress2->id = $idLive; + $liveInProgress2->idBbbLiveStreaming = $idBbbLiveStreaming; + $GLOBALS["livesInProgressOnThisServer"][] = $liveInProgress2; + break; + } + } + // Un slot est disponible sur ce serveur pour réaliser un live ? + if ($idBbbLiveStreaming == 0) { + writeLog(" => Impossible de lancer le live $idLive de $user sur ce serveur : il y a déjà " . NUMBER_LIVES . " directs qui sont gérés par ce serveur.", "INFO"); + } + else { + writeLog(" => Lancement du live $idLive de $user, via bbb-live-streaming$idBbbLiveStreaming", "INFO"); + configureAndStartLive($idLive, $urlMeeting, $idBbbLiveStreaming); + } + } + } + else { + writeLog(" + Commande '$cmdStatus0' : $sRetourVerificationStatus0[0]", "ERROR", __FILE__, __LINE__); + } +} + +/** + * Procédure permettant de configurer, puis de lancer, le plugin nécessaire au démarrage d'un direct. + * Cette procédure créé également le diffuseur nécessaire à l'affichage du live dans Pod. + * @param string $idLive - Identifiant du live BBB de Pod à démarrer (cf. table bbb_meeting) + * @param string $urlMeeting - URL de la session BBB de Pod à démarrer (cf. table bbb_livestream) + * @param string $idBbbLiveStreaming - Identifiant du répertoire bbb-live-streaming qui va être utilisé pour lancer ce direct + */ +function configureAndStartLive($idLive, $urlMeeting, $idBbbLiveStreaming) { + writeLog("-----Configuration et démarrage du direct : configureAndStartLive($idLive, '$urlMeeting', $idBbbLiveStreaming)-----", "DEBUG"); + + $cmd = "curl --silent -H 'Content-Type: application/json' "; + $cmd .= "-H 'Authorization: Token " . POD_TOKEN . "' "; + $cmd .= "-X GET $urlMeeting"; + $verification = exec("$cmd 2>&1", $aRetourVerification, $sRetourVerification); + + writeLog("Récupération de l'objet meeting ($urlMeeting) depuis Pod", "DEBUG"); + + if ($sRetourVerification == 0) { + writeLog(" + Commande '$cmd' : $aRetourVerification[0]", "DEBUG"); + + // Récupération de l'objet meeting + $oMeeting = json_decode($aRetourVerification[0]); + // Nom de la session, sans caractères problématiques ni espaces, et la chaîne bbb- en premier pour éviter toute confusion avec un diffuseur existant + $nameMeeting = "bbb-" . formatString($oMeeting->meeting_name); + // Nom de la session, sans caractères problématiques avec espaces, et la chaîne (BBB) en premier pour éviter toute confusion avec un diffuseur existant + $nameMeetingToDisplay = "(BBB) " . formatStringToDisplay($oMeeting->meeting_name); + // Id de la session + $idMeeting = $oMeeting->meeting_id; + + + // Récupération des informations concernant les options saisies par l'utilisateur + $cmdOptions = "curl --silent -H 'Content-Type: application/json' "; + $cmdOptions .= "-H 'Authorization: Token " . POD_TOKEN . "' "; + $cmdOptions .= "-X GET " . checkEndWithoutSlash(POD_URL) . "/rest/bbb_livestream/$idLive/"; + $verificationOptions = exec("$cmdOptions 2>&1", $aRetourVerificationOptions, $sRetourVerificationOptions); + + writeLog("Récupération des options de l'objet bbb_livestream (/rest/bbb_livestream/$idLive/) depuis Pod", "DEBUG"); + + $isRestricted = "false"; + $enableChat = "false"; + $showChat = "true"; + $downloadMeeting = "false"; + if ($sRetourVerificationOptions == 0) { + // Récupération de l'objet live + $oLive = json_decode($aRetourVerificationOptions[0]); + // Accès restreint + if ($oLive->is_restricted == 1) { + $isRestricted = "true"; + } else { + $isRestricted = "false"; + } + // Utilisation du chat + if ($oLive->enable_chat == 1) { + $enableChat = "true"; + } else { + $enableChat = "false"; + } + // Affichage du chat dans la vidéo + if ($oLive->show_chat == 1) { + $showChat = "true"; + } else { + $showChat = "false"; + } + // Téléchargement de la vidéo en fin de live + if ($oLive->download_meeting == 1) { + $downloadMeeting = "true"; + } else { + $downloadMeeting = "false"; + } + } + else { + writeLog(" + Commande '$cmdOptions' : $sRetourVerificationOptions[0]", "ERROR", __FILE__, __LINE__); + } + + /* Modification de la configuration du docker-compose.yml */ + writeLog(" + Modification de la configuration du docker-compose.yml", "DEBUG"); + $dockerFile = checkEndSlash(PHYSICAL_BASE_ROOT) . "bbb-live-streaming" . $idBbbLiveStreaming . "/docker-compose.yml"; + // Configuration du nom du container (container_name) + $nameContainer = "liveStreaming" . $idBbbLiveStreaming; + $cmdSed0 = "sed -i \"s/^.*container_name:.*/ container_name: $nameContainer/\" $dockerFile"; + exec("$cmdSed0 2>&1", $aRetourVerificationSed0, $sRetourVerificationSed0); + if ($sRetourVerificationSed0 != 0) { writeLog(" - Commande '$cmdSed0' : $aRetourVerificationSed0[0]", "ERROR", __FILE__, __LINE__); } + // Configuration du port utilisé par le host (ligne sous ports:), de la forme - "6379:6379" pour 1°, - "6380:6379" pour le 2°.... + $port = 6378 + $idBbbLiveStreaming; + $cmdSed01 = "sed -i \"s/^.*:6379:.*/ - \"$port:6379\"/\" $dockerFile"; + exec("$cmdSed01 2>&1", $aRetourVerificationSed01, $sRetourVerificationSed01); + if ($sRetourVerificationSed01 != 0) { writeLog(" - Commande '$cmdSed01' : $aRetourVerificationSed01[0]", "ERROR", __FILE__, __LINE__); } + // Configuration du serveur BBB/Scalelite (BBB_URL) + // Gestion des caractères / de BBB_URL pour être utilisé via sed + $bbbURL = str_replace("/", "\/", checkEndWithoutSlash(BBB_URL)); + $cmdSed1 = "sed -i \"s/^.*BBB_URL=.*/ - BBB_URL=$bbbURL/\" $dockerFile"; + exec("$cmdSed1 2>&1", $aRetourVerificationSed1, $sRetourVerificationSed1); + if ($sRetourVerificationSed1 != 0) { writeLog(" - Commande '$cmdSed1' : $aRetourVerificationSed1[0]", "ERROR", __FILE__, __LINE__); } + // Configuration de la clé secrète (BBB_SECRET) + $cmdSed2 = "sed -i \"s/^.*BBB_SECRET=.*/ - BBB_SECRET=".BBB_SECRET."/\" $dockerFile"; + exec("$cmdSed2 2>&1", $aRetourVerificationSed2, $sRetourVerificationSed2); + if ($sRetourVerificationSed2 != 0) { writeLog(" - Commande '$cmdSed2' : $aRetourVerificationSed2[0]", "ERROR", __FILE__, __LINE__); } + // Configuration de la timezone (TZ) + $cmdSed3 = "sed -i \"s/^.*TZ=.*/ - TZ=Europe\/Paris/\" $dockerFile"; + exec("$cmdSed3 2>&1", $aRetourVerificationSed3, $sRetourVerificationSed3); + if ($sRetourVerificationSed3 != 0) { writeLog(" - Commande '$cmdSed3' : $aRetourVerificationSed3[0]", "ERROR", __FILE__, __LINE__); } + // Configuration de la résolution (BBB_RESOLUTION) + $cmdSed4 = "sed -i \"s/^.*BBB_RESOLUTION=.*/ - BBB_RESOLUTION=".BBB_RESOLUTION."/\" $dockerFile"; + exec("$cmdSed4 2>&1", $aRetourVerificationSed4, $sRetourVerificationSed4); + if ($sRetourVerificationSed4 != 0) { writeLog(" - Commande '$cmdSed4' : $aRetourVerificationSed4[0]", "ERROR", __FILE__, __LINE__); } + // Configuration du bitrate de la vidéo (FFMPEG_STREAM_VIDEO_BITRATE) + $cmdSed5 = "sed -i \"s/^.*FFMPEG_STREAM_VIDEO_BITRATE=.*/ - FFMPEG_STREAM_VIDEO_BITRATE=".FFMPEG_STREAM_VIDEO_BITRATE."/\" $dockerFile"; + exec("$cmdSed5 2>&1", $aRetourVerificationSed5, $sRetourVerificationSed5); + if ($sRetourVerificationSed5 != 0) { writeLog(" - Commande '$cmdSed5' : $aRetourVerificationSed5[0]", "ERROR", __FILE__, __LINE__); } + // Configuration du nombre de threads (FFMPEG_STREAM_THREADS) + $cmdSed6 = "sed -i \"s/^.*FFMPEG_STREAM_THREADS=.*/ - FFMPEG_STREAM_THREADS=".FFMPEG_STREAM_THREADS."/\" $dockerFile"; + exec("$cmdSed6 2>&1", $aRetourVerificationSed6, $sRetourVerificationSed6); + if ($sRetourVerificationSed6 != 0) { writeLog(" - Commande '$cmdSed6' : $aRetourVerificationSed6[0]", "ERROR", __FILE__, __LINE__); } + // Modification de la ligne concernant l'id de la session à streamer (BBB_MEETING_ID) + $cmdSed7 = "sed -i \"s/^.*BBB_MEETING_ID=.*/ - BBB_MEETING_ID=$idMeeting/\" " . $dockerFile; + exec("$cmdSed7 2>&1", $aRetourVerificationSed7, $sRetourVerificationSed7); + if ($sRetourVerificationSed7 != 0) { writeLog(" - Commande '$cmdSed7' : $aRetourVerificationSed7[0]", "ERROR", __FILE__, __LINE__); } + // Modification de la ligne concernant le flux RTMP (BBB_STREAM_URL) + // Gestion des caractères / du serveur RTMP pour être utilisé via sed + $rtmpServer = str_replace("/", "\/", checkEndSlash(BBB_STREAM_URL)); + $cmdSed8 = "sed -i \"s/^.*BBB_STREAM_URL=.*/ - BBB_STREAM_URL=" . $rtmpServer . "$nameMeeting/\" " . $dockerFile; + exec("$cmdSed8 2>&1", $aRetourVerificationSed8, $sRetourVerificationSed8); + if ($sRetourVerificationSed8 != 0) { writeLog(" - Commande '$cmdSed8' : $aRetourVerificationSed8[0]", "ERROR", __FILE__, __LINE__); } + // Modification de la ligne concernant l'utilisation de chat (BBB_ENABLE_CHAT) + $cmdSed9 = "sed -i \"s/^.*BBB_ENABLE_CHAT=.*/ - BBB_ENABLE_CHAT=$enableChat/\" " . $dockerFile; + exec("$cmdSed9 2>&1", $aRetourVerificationSed9, $sRetourVerificationSed9); + if ($sRetourVerificationSed9 != 0) { writeLog(" - Commande '$cmdSed9' : $aRetourVerificationSed9[0]", "ERROR", __FILE__, __LINE__); } + // Modification de la ligne concernant l'affichage du chat dans la vidéo (BBB_SHOW_CHAT) + $cmdSed10 = "sed -i \"s/^.*BBB_SHOW_CHAT=.*/ - BBB_SHOW_CHAT=$showChat/\" " . $dockerFile; + exec("$cmdSed10 2>&1", $aRetourVerificationSed10, $sRetourVerificationSed10); + if ($sRetourVerificationSed10 != 0) { writeLog(" - Commande '$cmdSed10' : $aRetourVerificationSed10[0]", "ERROR", __FILE__, __LINE__); } + // Modification de la ligne concernant l'enregistrement de la vidéo du live (BBB_DOWNLOAD_MEETING) + $cmdSed11 = "sed -i \"s/^.*BBB_DOWNLOAD_MEETING=.*/ - BBB_DOWNLOAD_MEETING=$downloadMeeting/\" " . $dockerFile; + exec("$cmdSed11 2>&1", $aRetourVerificationSed11, $sRetourVerificationSed11); + if ($sRetourVerificationSed11 != 0) { writeLog(" - Commande '$cmdSed11' : $aRetourVerificationSed11[0]", "ERROR", __FILE__, __LINE__); } + // Modification de la ligne concernant le titre de la session (BBB_MEETING_TITLE) + $cmdSed12 = "sed -i \"s/^.*BBB_MEETING_TITLE=.*/ - BBB_MEETING_TITLE=$nameMeetingToDisplay/\" " . $dockerFile; + exec("$cmdSed12 2>&1", $aRetourVerificationSed12, $sRetourVerificationSed12); + if ($sRetourVerificationSed12 != 0) { writeLog(" - Commande '$cmdSed12' : $aRetourVerificationSed12[0]", "ERROR", __FILE__, __LINE__); } + // Modification de la ligne concernant le mot de passe d'un participant de la session (BBB_ATTENDEE_PASSWORD) + $cmdSed13 = "sed -i \"s/^.*BBB_ATTENDEE_PASSWORD=.*/ - BBB_ATTENDEE_PASSWORD=".BBB_ATTENDEE_PASSWORD."/\" " . $dockerFile; + exec("$cmdSed13 2>&1", $aRetourVerificationSed13, $sRetourVerificationSed13); + if ($sRetourVerificationSed13 != 0) { writeLog(" - Commande '$cmdSed13' : $aRetourVerificationSed13[0]", "ERROR", __FILE__, __LINE__); } + // Modification de la ligne concernant le mot de passe d'un modérateur de la session (BBB_MODERATOR_PASSWORD) + $cmdSed14 = "sed -i \"s/^.*BBB_MODERATOR_PASSWORD=.*/ - BBB_MODERATOR_PASSWORD=".BBB_MODERATOR_PASSWORD."/\" " . $dockerFile; + exec("$cmdSed14 2>&1", $aRetourVerificationSed14, $sRetourVerificationSed14); + if ($sRetourVerificationSed14 != 0) { writeLog(" - Commande '$cmdSed14' : $aRetourVerificationSed14[0]", "ERROR", __FILE__, __LINE__); } + // Modification de la ligne concernant le channel pour REDIS, encas d'utilisation du chat (BBB_REDIS_CHANNEL) + // Typiquement pour le répertoire 1 => chat1, 2 => chat2, 3 => chat3... + $channelRedis = "chat" . $idBbbLiveStreaming; + $cmdSed15 = "sed -i \"s/^.*BBB_REDIS_CHANNEL=.*/ - BBB_REDIS_CHANNEL=$channelRedis/\" " . $dockerFile; + exec("$cmdSed15 2>&1", $aRetourVerificationSed15, $sRetourVerificationSed15); + if ($sRetourVerificationSed15 != 0) { writeLog(" - Commande '$cmdSed15' : $aRetourVerificationSed15[0]", "ERROR", __FILE__, __LINE__); } + // Modification de la ligne concernant le mode DEBUG (DEBUG) + if (DEBUG) { $debug = "true"; } else { $debug = "false"; } + $cmdSed16 = "sed -i \"s/^.*DEBUG=.*/ - DEBUG=$debug/\" " . $dockerFile; + exec("$cmdSed16 2>&1", $aRetourVerificationSed16, $sRetourVerificationSed16); + if ($sRetourVerificationSed16 != 0) { writeLog(" - Commande '$cmdSed16' : $aRetourVerificationSed16[0]", "ERROR", __FILE__, __LINE__); } + + + /* Création du diffuseur correspondant dans Pod */ + $cmdBroadcaster = "curl --silent -H 'Content-Type: multipart/form-data' "; + $cmdBroadcaster .= "-H 'Authorization: Token " . POD_TOKEN . "' "; + $cmdBroadcaster .= "-F 'url=" . checkEndSlash(POD_HLS_STREAM) . "$nameMeeting.m3u8' "; + $cmdBroadcaster .= "-F 'building=" . checkEndWithoutSlash(POD_URL) . "/rest/buildings/" . POD_ID_BUILDING . "/' "; + $cmdBroadcaster .= "-F 'name=$nameMeetingToDisplay' -F 'status=true' -F 'is_restricted=$isRestricted' '" . checkEndWithoutSlash(POD_URL) . "/rest/broadcasters/'"; + $verificationBroadcaster = exec("$cmdBroadcaster 2>&1", $aRetourVerificationBroadcaster, $sRetourVerificationBroadcaster); + + writeLog(" + Création du diffuseur correspondant dans Pod", "DEBUG"); + + if ($sRetourVerificationBroadcaster == 0) { + writeLog(" - Commande '$cmdBroadcaster' : $aRetourVerificationBroadcaster[0]", "DEBUG"); + // Id du diffuseur + $idBroadcaster = 0; + + // Récupération du diffuseur créé + $oBroadcaster = json_decode($aRetourVerificationBroadcaster[0]); + + // Si le diffuseur existe déjà, $aRetourVerificationBroadcaster[0] contiendra un message d'avertissement du type : + // {"url":["Un objet Diffuseur avec ce champ URL existe déjà."],"name":["Un objet Diffuseur avec ce champ nom existe déjà."]} + if (strpos($aRetourVerificationBroadcaster[0], "Un objet Diffuseur avec ce champ nom existe déjà.") !== false) { + $cmdBroadcaster2 = "curl --silent -H 'Content-Type: application/json' "; + $cmdBroadcaster2 .= "-H 'Authorization: Token " . POD_TOKEN . "' "; + $cmdBroadcaster2 .= "-X GET " . checkEndWithoutSlash(POD_URL) . "/rest/broadcasters/$nameMeeting/"; + $verificationBroadcaster2 = exec("$cmdBroadcaster2 2>&1", $aRetourVerificationBroadcaster2, $sRetourVerificationBroadcaster2); + + writeLog(" + Récupération du diffuseur déjà existant dans Pod", "DEBUG"); + if ($sRetourVerificationBroadcaster2 == 0) { + writeLog(" - Commande '$cmdBroadcaster2' : $aRetourVerificationBroadcaster2[0]", "DEBUG"); + $oBroadcaster2 = json_decode($aRetourVerificationBroadcaster2[0]); + $idBroadcaster = $oBroadcaster2->id; + } + else { + writeLog(" + Commande '$cmdBroadcaster2' : $aRetourVerificationBroadcaster2[0]", "ERROR", __FILE__, __LINE__); + } + } + else { + $idBroadcaster = $oBroadcaster->id; + } + + if ($idBroadcaster != 0) { + writeLog(" + Utilisation du diffuseur $idBroadcaster", "DEBUG"); + + // Démarrage du live, si nécessaire + startLive($idLive, checkEndSlash(BBB_STREAM_URL) . "$nameMeeting", $idBbbLiveStreaming, $idBroadcaster); + } + else { + writeLog(" + Démarrage impossible du live : aucun identifiant du diffuseur défini.", "ERROR", __FILE__, __LINE__); + } + } + else { + writeLog(" + Commande '$cmdBroadcaster' : $aRetourVerificationBroadcaster[0]", "ERROR", __FILE__, __LINE__); + } + } + else { + writeLog(" + Commande '$cmd' : $sRetourVerification[0]", "ERROR", __FILE__, __LINE__); + } +} + +/** + * Procédure permettant de démarrer un direct. + * @param string $idLive - Identifiant du live BBB de Pod à démarrer (cf. table bbb_meeting) + * @param string $streamName - Nom du stream utilisé, en correspondance avec le diffuseur créé précédemment + * @param string $idBbbLiveStreaming - Identifiant du répertoire bbb-live-streaming qui va être utilisé pour lancer ce direct + * @param string $idBroadcaster - Identifiant du diffuseur qui va être utilisé pour lancer ce direct + */ +function startLive($idLive, $streamName, $idBbbLiveStreaming, $idBroadcaster) { + writeLog("-----Démarrage du direct : startLive($idLive, '$streamName', $idBbbLiveStreaming, $idBroadcaster)-----", "DEBUG"); + + if (DEBUG) { + // Avec gestions des logs, dans le répertoire des logs. Le nom du fichier correspond à l'id du live BBB de Pod ((cf. table bbb_meeting) + $cmd = "cd " . checkEndSlash(PHYSICAL_BASE_ROOT) . "bbb-live-streaming" . $idBbbLiveStreaming . " ; docker-compose up 1>" . checkEndSlash(PHYSICAL_LOG_ROOT) . "$idLive.log"; + exec("$cmd 2>&1 &", $aRetourVerification, $sRetourVerification); + } + else { + // En mode daemon + $cmd = "cd " . checkEndSlash(PHYSICAL_BASE_ROOT) . "bbb-live-streaming" . $idBbbLiveStreaming . " ; docker-compose up -d"; + exec("$cmd 2>&1", $aRetourVerification, $sRetourVerification); + } + + writeLog("Démarrage du live", "DEBUG"); + + if ($sRetourVerification == 0) { + writeLog(" + Commande '$cmd'", "DEBUG"); + + // Définition du port pour REDIS (en cas d'utilisation du chat) + // Typiquement pour le répertoire 1 => 6379, 2 => 6380, 3 => 6381... + $portRedis = 6378 + $idBbbLiveStreaming; + + // Définition du channel pour REDIS (en cas d'utilisation du chat) + // Typiquement pour le répertoire 1 => chat1, 2 => chat2, 3 => chat3... + $channelRedis = "chat" . $idBbbLiveStreaming; + + // Mise à jour de l'information dans Pod, via l'API Rest + $cmdMajPod = "curl --silent -H 'Content-Type: application/json' "; + $cmdMajPod .= "-H 'Authorization: Token " . POD_TOKEN . "' "; + $cmdMajPod .= "-X PATCH -d '{\"server\":\"" . SERVER_NUMBER . "/" . $idBbbLiveStreaming . "\", \"status\":1, \"broadcaster_id\": $idBroadcaster, \"redis_hostname\":\"" . SERVER_HOSTNAME . "\", \"redis_port\": $portRedis, \"redis_channel\":\"$channelRedis\"}' "; + $cmdMajPod .= "" . checkEndWithoutSlash(POD_URL) . "/rest/bbb_livestream/$idLive/"; + exec("$cmdMajPod", $aRetourVerificationMajPod, $sRetourVerificationMajPod); + + writeLog(" + Mise à jour de l'information du bbb_livestream dans Pod", "DEBUG"); + + if ($sRetourVerificationMajPod == 0) { + writeLog(" - Commande '$cmdMajPod' : $aRetourVerificationMajPod[0]", "DEBUG"); + } + else { + writeLog(" - Commande '$cmdMajPod' : $sRetourVerificationMajPod[0]", "ERROR", __FILE__, __LINE__); + } + } + else { + writeLog(" + Commande '$cmd' : $sRetourVerification[0]", "ERROR", __FILE__, __LINE__); + } +} + +/** + * Procédure permettant d'identifier et d'arrêter des directs dont la session BigBlueButton a été arrêtée. + */ +function stopLives() { + writeLog("-----Arrêt des directs : stopLives()-----", "DEBUG"); + + // Checksum utile pour récupérer les informations des sessions en cours sur BigBlueButton/Scalelite + $checksum = sha1("getMeetings" . BBB_SECRET); + // Adresse utile pour récupérer les informations des sessions en cours sur BigBlueButton/Scalelite + $bbbUrlGetMeetings = checkEndWithoutSlash(BBB_URL) . "/getMeetings?checksum=" . $checksum; + // Variable permettant de connaitre les sessions en cours sur le serveur BigBlueButton/Scalelite + $meetingsInProgressOnBBB = array(); + + // On ne récupère les sessions du serveur BigBlueButton/Scalelite que s'il existe des lives en cours sur ce serveur + if (count($GLOBALS["livesInProgressOnThisServer"]) > 0) { + $xml = simplexml_load_file($bbbUrlGetMeetings); + writeLog("Récupération des sessions depuis le serveur BigBlueButton/Scalelite", "DEBUG"); + if($xml === FALSE) { + writeLog(" + Impossible de se connecter au serveur BBB/Scalelite : $bbbUrlGetMeetings", "ERROR", __FILE__, __LINE__); + } else { + writeLog(" + Requête sur le serveur BBB/Scalelite : $bbbUrlGetMeetings", "DEBUG"); + foreach ($xml->meetings->meeting as $meeting) { + // Ajout du meetingID au tableau des sessions BBB en cours + $meetingsInProgressOnBBB[] = $meeting->meetingID; + } + } + + // Recherche de tous les directs marqués comme étant en cours + foreach ($GLOBALS["livesInProgressOnThisServer"] as $ligneLiveInProgressOnThisServer) { + // Récupération du BBB_MEETING_ID correspondant dans le docker-compose.yml + $dockerFile = checkEndSlash(PHYSICAL_BASE_ROOT) . "bbb-live-streaming" . $ligneLiveInProgressOnThisServer->idBbbLiveStreaming . "/docker-compose.yml"; + $dockerDirectory = checkEndSlash(PHYSICAL_BASE_ROOT) . "bbb-live-streaming" . $ligneLiveInProgressOnThisServer->idBbbLiveStreaming; + $cmdGrep1="grep BBB_MEETING_ID $dockerFile| cut -d\"=\" -f2"; + $verificationGrep1 = exec("$cmdGrep1 2>&1", $aRetourVerificationGrep1, $sRetourVerificationGrep1); + if ($sRetourVerificationGrep1 == 0) { + writeLog(" + Commande '$cmdGrep1' : $aRetourVerificationGrep1[0]", "DEBUG"); + // Meeting ID correspondant + $bbbMeetingId = $aRetourVerificationGrep1[0]; + + // Recherche du nom du diffuseur correspondant (sauvegardé aussi dans BBB_MEETING_TITLE du fichier compose) + $broadcasterName = ""; + $cmdGrep2="grep BBB_MEETING_TITLE $dockerFile| cut -d\"=\" -f2"; + $verificationGrep2 = exec("$cmdGrep2 2>&1", $aRetourVerificationGrep2, $sRetourVerificationGrep2); + if ($sRetourVerificationGrep2 == 0) { + writeLog(" + Commande '$cmdGrep2' : $aRetourVerificationGrep2[0]", "DEBUG"); + // Nom du diffuseur correspondant + $broadcasterName = formatString($aRetourVerificationGrep2[0]); + } + else { + writeLog(" + Commande '$cmdGrep2' : $sRetourVerificationGrep2[0]", "ERROR", __FILE__, __LINE__); + } + + // Cet ID n'est plus dans la liste des sessions en cours sur BBB : + // - on arrête le container docker correspondant + // - on supprime le diffuseur correspondant + // - on copie, pour permettre l'encodage, le fichier vidéo si l'utilisateur a enregistré la session + if (! in_array($bbbMeetingId, $meetingsInProgressOnBBB)) { + writeLog(" + La session BigBlueButton $bbbMeetingId est arrêtée. Arrêt du container docker $dockerFile, suppression du diffuseur correspondant, copie du fichier vidéo généré selon le souhait de l'utilisateur", "INFO"); + $cmdStop = "cd $dockerDirectory; docker-compose down"; + exec("$cmdStop 2>&1", $aRetourVerificationStop, $sRetourVerificationStop); + if ($sRetourVerificationStop == 0) { + writeLog(" - Le container docker $dockerDirectory est bien arrêté", "DEBUG"); + // Formatage de la date d'arrêt dans le bon format + $endDate = date('Y-m-d H:i:s'); + // On sauvegarde cette information dans la base de Pod via l'appel à l'API Rest + $cmdMajPod1 = "curl --silent -H 'Content-Type: application/json' "; + $cmdMajPod1 .= "-H 'Authorization: Token " . POD_TOKEN . "' "; + $cmdMajPod1 .= "-X PATCH -d '{\"end_date\":\"$endDate\", \"status\":2}' "; + $cmdMajPod1 .= "" . checkEndWithoutSlash(POD_URL) . "/rest/bbb_livestream/" . $ligneLiveInProgressOnThisServer->id . "/"; + exec("$cmdMajPod1", $aRetourVerificationMajPod1, $sRetourVerificationMajPod1); + + writeLog(" + Mise à jour de l'information du bbb_livestream dans Pod", "DEBUG"); + + // URL de l'API Rest du meeting en cours d'arrêt + $urlApiRestMeeting = ""; + // URL de l'API Rest du user qui a réalisé le live qui en cours d'arrêt + $urlApiRestUser = ""; + if ($sRetourVerificationMajPod1 == 0) { + writeLog(" - Commande '$cmdMajPod1' : $aRetourVerificationMajPod1[0]", "DEBUG"); + $oLive = json_decode($aRetourVerificationMajPod1[0]); + if (isset($oLive->meeting)) { + $urlApiRestMeeting = $oLive->meeting; + $urlApiRestUser = $oLive->user; + } + } + else { + writeLog(" - Commande '$cmdMajPod1' : $sRetourVerificationMajPod1[0]", "ERROR", __FILE__, __LINE__); + } + // Suppression du diffuseur + if ($broadcasterName != "") { + deleteBroadcaster($broadcasterName); + } + + // Recherche si l'utilisateur a souhaité cet enregistrement (sauvegardé aussi dans BBB_DOWNLOAD_MEETING du fichier compose) + $downloadMeeting = false; + $cmdGrep3="grep BBB_DOWNLOAD_MEETING $dockerFile| cut -d\"=\" -f2"; + $verificationGrep3 = exec("$cmdGrep3 2>&1", $aRetourVerificationGrep3, $sRetourVerificationGrep3); + if ($sRetourVerificationGrep3 == 0) { + writeLog(" + Commande '$cmdGrep3' : $aRetourVerificationGrep3[0]", "DEBUG"); + // Nom du diffuseur correspondant + if ($aRetourVerificationGrep3[0] == "true") { + $downloadMeeting = true; + } + } + else { + writeLog(" + Commande '$cmdGrep3' : $sRetourVerificationGrep3[0]", "ERROR", __FILE__, __LINE__); + } + + // Copie du fichier vidéo créé : si c'est configuré pour et que l'utilisateur a souhaité cet enregistrement + if (POD_DEFAULT_BBB_PATH != "" && $downloadMeeting) { + // Recherche de internal_meeting_id correspondant à cette session + $cmdMajPod2 = "curl --silent -H 'Content-Type: application/json' "; + $cmdMajPod2 .= "-H 'Authorization: Token " . POD_TOKEN . "' "; + $cmdMajPod2 .= "-X PATCH -d '{\"encoded_by\":\"$urlApiRestUser\", \"encoding_step\":3}' "; + $cmdMajPod2 .= "$urlApiRestMeeting"; + $verificationMajPod2 = exec("$cmdMajPod2 2>&1", $aRetourVerificationMajPod2, $sRetourVerificationMajPod2); + + writeLog(" + Récupération de l'internal_meeting_id correspondant à l'objet bbb_meeting $bbbMeetingId depuis Pod", "DEBUG"); + $internalMeetingId = ""; + if ($sRetourVerificationMajPod2 == 0) { + writeLog(" - Commande '$cmdMajPod2' : $aRetourVerificationMajPod2[0]", "DEBUG"); + + // Recherche de l'internal_meeting_id correspondant au meeting + $oMeeting = json_decode($aRetourVerificationMajPod2[0]); + if (isset($oMeeting->internal_meeting_id)) { + $internalMeetingId = $oMeeting->internal_meeting_id; + } + } + else { + writeLog(" - Commande '$cmdMajPod2' : $sRetourVerificationMajPod2[0]", "ERROR", __FILE__, __LINE__); + } + + if ($internalMeetingId != "") { + processDirectory($ligneLiveInProgressOnThisServer->idBbbLiveStreaming, $internalMeetingId); + } + else { + writeLog(" - Impossible de récupérer l'internal meeting id pour le direct " . $ligneLiveInProgressOnThisServer->idBbbLiveStreaming, "ERROR", __FILE__, __LINE__); + } + } + } + else { + writeLog(" + Commande '$cmdStop' : $sRetourVerificationStop[0]", "ERROR", __FILE__, __LINE__); + } + } + } + else { + writeLog(" + Commande '$cmdGrep1' : $sRetourVerificationGrep1[0]", "ERROR", __FILE__, __LINE__); + } + } + } +} + +/** + * Procédure permettant de supprimer un diffuseur dans Pod. + * @param string $broadcasterName - Nom du diffuseur à supprimer + */ +function deleteBroadcaster($broadcasterName) { + // Via l'API, il faut utiliser le slug et non le nom + $slug = str_replace("(BBB)", "bbb", $broadcasterName); + /* Suppression du diffuseur correspondant dans Pod */ + $cmdBroadcaster = "curl --silent "; + $cmdBroadcaster .= "-H 'Authorization: Token " . POD_TOKEN . "' "; + $cmdBroadcaster .= "-X DELETE '" . checkEndWithoutSlash(POD_URL) . "/rest/broadcasters/$slug/'"; + $verificationBroadcaster = exec("$cmdBroadcaster 2>&1", $aRetourVerificationBroadcaster, $sRetourVerificationBroadcaster); + + writeLog(" + Suppression du diffuseur $slug dans Pod", "DEBUG"); + + if ($sRetourVerificationBroadcaster == 0) { + writeLog(" - Commande '$cmdBroadcaster' exécutée", "DEBUG"); + } + else { + writeLog(" + Commande '$cmdBroadcaster' : $aRetourVerificationBroadcaster[0]", "ERROR", __FILE__, __LINE__); + } +} + +/** + * Procédure permettant de copier le fichier vidéo créé, si un enregistrement existe de ce dernier. + * Le fichier vidéo est créé dans le répertoire videodata du répertoire BigBlueButton-liveStreaming concerné. + * Ce fichier vidéo sera copié dans le POD_DEFAULT_BBB_PATH et renommé sous la forme internalMeetingId.mkv. + * Ce nommage est très important et permet au CRON Job bbb de Pod d'assigner le bon propriétaire à cette vidéo. + * @param string $idBbbLiveStreaming - Identifiant du répertoire BigBlueButton-liveStreaming concerné. + * @param string $internalMeetingId - Identifiant interne de la session BBB enregistrée. + */ +function processDirectory($idBbbLiveStreaming, $internalMeetingId) { + writeLog("-----Copie des fichiers vidéos enregistrées sur le partage NFS, pour traitement automatique par POD : processDirectory($idBbbLiveStreaming, $internalMeetingId)-----", "DEBUG"); + // Parcours du répertoire videodata du répertoire BigBlueButton-liveStreaming concerné + // Définition du répertoire + $directoryLiveStreaming = checkEndSlash(PHYSICAL_BASE_ROOT) . "bbb-live-streaming$idBbbLiveStreaming/videodata"; + writeLog("Recherche de fichiers vidéos pour le direct $idBbbLiveStreaming : $directoryLiveStreaming", "DEBUG"); + if (file_exists($directoryLiveStreaming)) { + $listFiles = scandir("$directoryLiveStreaming"); + // Mise en place d'une boucle, mais il ne doit y avoir qu'un seul fichier au maximum + foreach ($listFiles as $key => $value) { + if (strrpos($value, ".mkv")) { + // Déplacer et renommer le fichier avec l'internalMeetingId + $oldFilename = "$directoryLiveStreaming/$value"; + $newFilename = checkEndSlash(POD_DEFAULT_BBB_PATH) . "$internalMeetingId" . ".mkv"; + writeLog(" + Déplacement du fichier $oldFilename vers $newFilename", "DEBUG"); + @rename("$oldFilename", "$newFilename"); + // Positionnement de droits adéquats pour pouvoir être encodé par Pod + // Normalement, il n'y en a pas besoin : le fichier généré a les droits 644, ce qui est suffisant. + @chmod("$newFilename", 0755); + } + } + } +} + +/** + * Fonction d'écriture dans le fichier de logs. + * Les messages au niveau debug ne seront écris que si l'application est configuré en mode DEBUG (DEBUG = true). + * @param string $message - Message à écrire + * @param string $level - Niveau de log de ce message (debug, info, warning, error) + * @param string $file - Nom du fichier PHP concerné (en cas d'erreur) + * @param int $line - Ligne dans le fichier PHP concerné (en cas d'erreur) + * @return nombre d'octets écris, false sinon + */ +function writeLog($message, $level, $file=null, $line=null) { + // Ecriture des lignes de debug seulement en cas de mode DEBUG + if (($level == "DEBUG") && (! DEBUG)) { + return false; + } + + // Création du répertoire des logs si besoin + if (! file_exists(checkEndSlash(PHYSICAL_LOG_ROOT))) { + // Création du répertoire + @mkdir(checkEndSlash(PHYSICAL_LOG_ROOT), 0755); + } + + // Configuration du fichier de log, 1 par jour + $logFile = checkEndSlash(PHYSICAL_LOG_ROOT) . gmdate("Y-m-d") . "_bbb-pod-live.log"; + + // En cas de non existence, on créé ce fichier + if (!file_exists($logFile)) { + $file = fopen($logFile, "x+"); + // Une exception est levée en cas de non existence du fichier (problème manifeste de droits utilisateurs) + if (!file_exists($logFile)) { + echo "Erreur de configuration : impossible de créer le fichier $logFile."; + throw new Exception("Impossible de créer le fichier $logFile."); + } + } + + // Une exception est levée en cas de problème d'écriture (problème manifeste de droits utilisateurs) + if(!is_writeable($logFile)) { + throw new Exception("$logFile n'a pas les droits en écriture."); + } + + $message = gmdate("Y-m-d H:i:s") . " - [$level] - " . $message; + $message .= is_null($file) ? '' : " - Fichier [$file]"; + $message .= is_null($line) ? '' : " - Ligne [$line]."; + $message .= "\n"; + + // Surcharge de la variable globale signifiant une erreur dans le script + if ($level == "ERROR") { + $GLOBALS["txtErrorInScript"] .= "$message"; + } + + return file_put_contents( $logFile, $message, FILE_APPEND ); +} + +/** + * Fonction permettant de vérifier que la chaîne de caractères finit par un /. En ajoute un si nécessaire. + * @param string - Chaîne de caractères. + * @return Chaîne de caractères identique à celle en entrée, mais avec un / comme dernier caractère. + */ +function checkEndSlash($string) { + if (substr($string, -1) !== "/" ) { + $string .= "/"; + } + return $string; +} + +/** + * Fonction permettant de vérifier que la chaîne de caractères ne finit pas par un /. Supprime ce / un si nécessaire. + * @param string - Chaîne de caractères. + * @return Chaîne de caractères identique à celle en entrée, mais sans / à la fin. + */ +function checkEndWithoutSlash($string) { + if (substr($string, -1) == "/" ) { + $string = substr($string, 0, -1); + } + return $string; +} + +/** +* Fonction permettant de supprimer les caractères accentués et autres caractéres problématiques d'une chaîne de caractères. +* Remplace aussi les espaces par des tirets +* @param $string - chaîne avec accents +* @return chaîne sans accents +*/ +function formatString($string) { + $string = htmlentities($string, ENT_NOQUOTES, 'utf-8'); + $string = preg_replace('#&([A-za-z])(?:uml|circ|tilde|acute|grave|cedil|ring);#', '\1', $string); + $string = preg_replace('#&([A-za-z]{2})(?:lig);#', '\1', $string); + $string = preg_replace('#&[^;]+;".()\'#', '', $string); + $string = preg_replace('/\s+/', '-', $string); + return $string; +} + +/** +* Fonction permettant de supprimer les caractères accentués et autres caractéres problématiques d'une chaîne de caractères. +* Ne replace pas les espaces. +* @param $string - chaîne avec accents +* @return chaîne sans accents +*/ +function formatStringToDisplay($string) { + $string = htmlentities($string, ENT_NOQUOTES, 'utf-8'); + $string = preg_replace('#&([A-za-z])(?:uml|circ|tilde|acute|grave|cedil|ring);#', '\1', $string); + $string = preg_replace('#&([A-za-z]{2})(?:lig);#', '\1', $string); + $string = preg_replace('#&[^;]+;".()\'#', '', $string); + return $string; +} +?> \ No newline at end of file From cef5e1006260c815e015ccc82ab5131b9d0e920a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Bonavent?= Date: Tue, 9 Mar 2021 09:34:51 +0100 Subject: [PATCH 061/261] bigbluebutton-liveStreaming default configuration. This file will be copied, by bbb-pod-live script, the first time, in the differntes bbb-liveStreaming directories --- .../bbb-pod-live/docker-compose.default.yml | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 scripts/bbb-pod-live/docker-compose.default.yml diff --git a/scripts/bbb-pod-live/docker-compose.default.yml b/scripts/bbb-pod-live/docker-compose.default.yml new file mode 100644 index 0000000000..01bde907fc --- /dev/null +++ b/scripts/bbb-pod-live/docker-compose.default.yml @@ -0,0 +1,59 @@ +version: '3.3' +services: + redis: + image: redis + ports: + - "6379:6379" + networks: + - app-tier + bbb-streamer: + image: aauzid/bigbluebutton-livestreaming + container_name: liveStreaming1 + shm_size: '2gb' + environment: + # BigBlueButton Server url: + - BBB_URL=https://bbb.univ.fr/bigbluebutton/api + # BigBlueButton secret: + - BBB_SECRET=abcd + # BigBlueButton meetingID: + - BBB_MEETING_ID=abcd + # start meeting (optional): + - BBB_START_MEETING=false + # attendee password (optional - has to be set to the attendee password of moodle/greenlight or any other frontend to allow joining via their links): + - BBB_ATTENDEE_PASSWORD=JAMHEVcAdpoS + # moderator password (optional - has to be set to the moderator password of moodle/greenlight or any other frontend to allow joining via their links): + - BBB_MODERATOR_PASSWORD=AOcEHxFFDtrD + # meeting title (optional): + - BBB_MEETING_TITLE=(BBB) Webinaire de test 01 + # download / save BigBlueButton meeting + - BBB_DOWNLOAD_MEETING=false + # Media server url: + - BBB_STREAM_URL=rtmp://live.univ.fr/live/bbb-Webinaire-de-test-01 + # Resolution to be streamed/downloaded in format WxH (default 1920x1080) + - BBB_RESOLUTION=1280x720 + # stream video bitrate + - FFMPEG_STREAM_VIDEO_BITRATE=3000 + # threads used for stream (0=auto) + - FFMPEG_STREAM_THREADS=0 + # Enable chat functionality + - BBB_ENABLE_CHAT=true + # shows the chat on the left side of the window (Default: false) + - BBB_SHOW_CHAT=true + # Timezone (default: Europe/Vienna): + - TZ=Europe/Paris + # Set REDIS host (default: 'redis') + #- BBB_REDIS_HOST=ts-sun-video.infra.umontpellier.fr + - BBB_REDIS_HOST=redis + # Set REDIS channel to subscribe (default: 'chat') + - BBB_REDIS_CHANNEL=chat1 + # Username for the chat (default: 'Chat') + - BBB_CHAT_NAME=Chat + # DEBUG + - DEBUG=true + networks: + - app-tier + volumes: + - ./videodata:/video +networks: + app-tier: + driver: bridge From 2207c92363a7e7f8afea10d2e6ca51f26d6819e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Bonavent?= Date: Tue, 9 Mar 2021 09:46:38 +0100 Subject: [PATCH 062/261] Main PHP script for bbb-pod-live. Must be installed on bbb-pod-live servers --- scripts/bbb-pod-live/bbb-pod-live.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/bbb-pod-live/bbb-pod-live.php b/scripts/bbb-pod-live/bbb-pod-live.php index b0bb80ac6a..36cd37e10c 100644 --- a/scripts/bbb-pod-live/bbb-pod-live.php +++ b/scripts/bbb-pod-live/bbb-pod-live.php @@ -39,10 +39,10 @@ define ("BBB_STREAM_URL", "rtmp://live.univ.fr/live/"); // Mot de passe des participants cf. BBB_ATTENDEE_PASSWORD // Doit être défini comme le mot de passe du participant de Moodle / Greenlight ou de tout autre frontend pour permettre la participation via leurs liens -define ("BBB_ATTENDEE_PASSWORD", "JAMHEVcAdpoS"); +define ("BBB_ATTENDEE_PASSWORD", "xxxxxxx"); // Mot de passe des modérateurs cf. BBB_ATTENDEE_PASSWORD // Doit être défini comme le mot de passe du modérateur de Moodle / Greenlight ou de tout autre frontend pour permettre la participation via leurs liens -define ("BBB_MODERATOR_PASSWORD", "AOcEHxFFDtrD"); +define ("BBB_MODERATOR_PASSWORD", "xxxxxxx"); /* PARAMETRAGE NECESSAIRE POUR POD */ From 9159519283bc3de9a9e3977dfe8055e9980392b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Bonavent?= Date: Tue, 9 Mar 2021 09:47:03 +0100 Subject: [PATCH 063/261] bigbluebutton-liveStreaming default configuration. This file will be copied, by bbb-pod-live script, the first time, in the differntes bbb-liveStreaming directories --- scripts/bbb-pod-live/docker-compose.default.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/bbb-pod-live/docker-compose.default.yml b/scripts/bbb-pod-live/docker-compose.default.yml index 01bde907fc..a845df3d13 100644 --- a/scripts/bbb-pod-live/docker-compose.default.yml +++ b/scripts/bbb-pod-live/docker-compose.default.yml @@ -20,9 +20,9 @@ services: # start meeting (optional): - BBB_START_MEETING=false # attendee password (optional - has to be set to the attendee password of moodle/greenlight or any other frontend to allow joining via their links): - - BBB_ATTENDEE_PASSWORD=JAMHEVcAdpoS + - BBB_ATTENDEE_PASSWORD=xxxxxxxxxx # moderator password (optional - has to be set to the moderator password of moodle/greenlight or any other frontend to allow joining via their links): - - BBB_MODERATOR_PASSWORD=AOcEHxFFDtrD + - BBB_MODERATOR_PASSWORD=xxxxxxxxxx # meeting title (optional): - BBB_MEETING_TITLE=(BBB) Webinaire de test 01 # download / save BigBlueButton meeting From 835ba6278655bb32849af77f41d7d844af4cb36c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Bonavent?= Date: Tue, 9 Mar 2021 11:45:14 +0100 Subject: [PATCH 064/261] bigbluebutton-liveStreaming default configuration. This file will be copied, by bbb-pod-live script, the first time, in the differntes bbb-liveStreaming directories --- scripts/bbb-pod-live/docker-compose.default.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/bbb-pod-live/docker-compose.default.yml b/scripts/bbb-pod-live/docker-compose.default.yml index a845df3d13..663825ed20 100644 --- a/scripts/bbb-pod-live/docker-compose.default.yml +++ b/scripts/bbb-pod-live/docker-compose.default.yml @@ -42,7 +42,6 @@ services: # Timezone (default: Europe/Vienna): - TZ=Europe/Paris # Set REDIS host (default: 'redis') - #- BBB_REDIS_HOST=ts-sun-video.infra.umontpellier.fr - BBB_REDIS_HOST=redis # Set REDIS channel to subscribe (default: 'chat') - BBB_REDIS_CHANNEL=chat1 From b5f4b182d6995adbbefe52a1cf921af6b0991d7d Mon Sep 17 00:00:00 2001 From: ptitloup Date: Wed, 10 Mar 2021 10:30:47 +0100 Subject: [PATCH 065/261] replace get_video_mp4_json, fix call with static method --- pod/video/models.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pod/video/models.py b/pod/video/models.py index 0e03599ea0..a4bf2560d1 100755 --- a/pod/video/models.py +++ b/pod/video/models.py @@ -832,6 +832,10 @@ def get_video_json(self, extensions): ) for x in dict_src.keys()} return sorted_dict_src + def get_video_mp4_json(self): + list_mp4 = self.get_video_json(extensions="mp4") + return list_mp4["mp4"] + def get_audio_json(self, extensions): extension_list = extensions.split(',') if extensions else [] list_audio = EncodingAudio.objects.filter( @@ -844,7 +848,7 @@ def get_audio_and_video_json(self, extensions): **self.get_audio_json(extensions)} @staticmethod - def get_media_json(self, extension_list, list_video): + def get_media_json(extension_list, list_video): dict_src = {} for media in list_video: file_extension = splitext(media.source_file.url)[-1] From 89cf0e65a3d938686ac67712c53d9ccdd6f43ad6 Mon Sep 17 00:00:00 2001 From: ptitloup Date: Wed, 10 Mar 2021 10:39:11 +0100 Subject: [PATCH 066/261] check if mp4 key exist --- pod/video/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pod/video/models.py b/pod/video/models.py index a4bf2560d1..72a567fac4 100755 --- a/pod/video/models.py +++ b/pod/video/models.py @@ -834,7 +834,7 @@ def get_video_json(self, extensions): def get_video_mp4_json(self): list_mp4 = self.get_video_json(extensions="mp4") - return list_mp4["mp4"] + return list_mp4["mp4"] if list_mp4.get("mp4") else [] def get_audio_json(self, extensions): extension_list = extensions.split(',') if extensions else [] From 60188d0b527f234762784c12891aa914e93df520 Mon Sep 17 00:00:00 2001 From: ptitloup Date: Wed, 10 Mar 2021 11:17:05 +0100 Subject: [PATCH 067/261] add valid human check box to contact form --- pod/main/forms.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pod/main/forms.py b/pod/main/forms.py index 02c1df72e1..a449bb1ba5 100644 --- a/pod/main/forms.py +++ b/pod/main/forms.py @@ -67,6 +67,10 @@ class ContactUsForm(forms.Form): url_referrer = forms.URLField(required=False, widget=forms.HiddenInput()) + valid_human = forms.BooleanField( + label=_('check this box if you are a metal human'), + widget=forms.CheckboxInput()) + def __init__(self, request, *args, **kwargs): super(ContactUsForm, self).__init__(*args, **kwargs) From 1ec1554acabe34790e3b27bd469a345c93e50124 Mon Sep 17 00:00:00 2001 From: ptitloup Date: Wed, 10 Mar 2021 11:19:37 +0100 Subject: [PATCH 068/261] specfy required=False --- pod/main/forms.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pod/main/forms.py b/pod/main/forms.py index a449bb1ba5..cd259edf51 100644 --- a/pod/main/forms.py +++ b/pod/main/forms.py @@ -68,6 +68,7 @@ class ContactUsForm(forms.Form): url_referrer = forms.URLField(required=False, widget=forms.HiddenInput()) valid_human = forms.BooleanField( + required=False, label=_('check this box if you are a metal human'), widget=forms.CheckboxInput()) From cb9f58cf703b35c3c4e5e1b1039383987291d615 Mon Sep 17 00:00:00 2001 From: ptitloup Date: Wed, 10 Mar 2021 11:35:20 +0100 Subject: [PATCH 069/261] add class for human valid checkbox list item and css to hide it --- pod/main/static/css/pod.css | 16 ++++++++++++++++ pod/main/templates/contact_us.html | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/pod/main/static/css/pod.css b/pod/main/static/css/pod.css index fe8cdb98d1..81c6cbc5bf 100755 --- a/pod/main/static/css/pod.css +++ b/pod/main/static/css/pod.css @@ -489,3 +489,19 @@ input.select2-input{ #viewers-ul{height: 200px;list-style-type: none;padding-left: 0;} #viewers-ul{overflow: hidden; overflow-y: scroll;} + +/* use to hide valid human chekbox in contact form to prevent spam */ +#contact_us .valid_human { + display: block; + overflow: hidden; + position:absolute !important; + left:0 !important; + top:0 !important; + width:1px !important; + height:1px !important; + padding: 0 !important; + margin: 0 !important; +} + + + diff --git a/pod/main/templates/contact_us.html b/pod/main/templates/contact_us.html index c8c803294c..a57e312551 100644 --- a/pod/main/templates/contact_us.html +++ b/pod/main/templates/contact_us.html @@ -29,7 +29,7 @@

{% trans "Contact us" %}

{% endfor %} {% for field in form.visible_fields %} {% spaceless %} -
+
{{ field.errors }} {% if "form-check-input" in field.field.widget.attrs.class %} From 951ca5e9a96d9e8dec2b01098527ebbf69b099a0 Mon Sep 17 00:00:00 2001 From: ptitloup Date: Wed, 10 Mar 2021 11:50:07 +0100 Subject: [PATCH 070/261] get valid_human value and return without sending mail if checked --- pod/main/views.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pod/main/views.py b/pod/main/views.py index f2e535ad39..39c29a7113 100644 --- a/pod/main/views.py +++ b/pod/main/views.py @@ -196,6 +196,10 @@ def contact_us(request): email = form.cleaned_data['email'] message = form.cleaned_data['description'] + valid_human = form.cleaned_data['valid_human'] + if valid_human: + return redirect(form.cleaned_data['url_referrer']) + text_content = loader.get_template('mail/mail.txt').render({ 'name': name, 'email': email, From d82cc1c405f3c4b5402e421ade82539d7848e78b Mon Sep 17 00:00:00 2001 From: ptitloup Date: Wed, 10 Mar 2021 12:18:55 +0100 Subject: [PATCH 071/261] add required in checkbox label and translate it --- pod/locale/fr/LC_MESSAGES/django.mo | Bin 97682 -> 97755 bytes pod/locale/fr/LC_MESSAGES/django.po | 21 ++++++++++++--------- pod/locale/nl/LC_MESSAGES/django.po | 18 +++++++++--------- pod/main/forms.py | 2 +- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/pod/locale/fr/LC_MESSAGES/django.mo b/pod/locale/fr/LC_MESSAGES/django.mo index a5f5aa016227e49301150bb2268e77e88701beea..66dd397a1b10085eee2cba2eafa69f53ba6597a2 100644 GIT binary patch delta 18149 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 delta 18127 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 KT_^ty^8O#5O{KE{ diff --git a/pod/locale/fr/LC_MESSAGES/django.po b/pod/locale/fr/LC_MESSAGES/django.po index 57318aa4de..56630edabb 100755 --- 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: 2021-03-05 15:42+0000\n" +"POT-Creation-Date: 2021-03-10 11:14+0000\n" "PO-Revision-Date: \n" "Last-Translator: obado \n" "Language-Team: \n" @@ -150,7 +150,7 @@ msgstr "Changer votre image de profil" #: pod/enrichment/templates/enrichment/group_enrichment.html:29 #: pod/interactive/templates/interactive/group_interactive.html:29 #: pod/live/templates/live/live-form.html:10 -#: pod/main/templates/contact_us.html:24 pod/main/views.py:255 +#: pod/main/templates/contact_us.html:24 pod/main/views.py:259 #: pod/playlist/views.py:140 #: pod/recorder/templates/recorder/add_recording.html:36 #: pod/recorder/templates/recorder/record_delete.html:32 @@ -1366,10 +1366,6 @@ msgstr "Le fichier n’a pas été enregistré." msgid "Please correct errors" msgstr "Veuillez corriger les erreurs" -#: pod/custom/settings_local.py:76 -msgid "Dutch (Netherlands)" -msgstr "Néerlandais (Pays-Bas)" - #: pod/enrichment/apps.py:7 msgid "Enrichment version" msgstr "Version enrichie" @@ -2160,7 +2156,11 @@ msgstr "Renseignez une description complète pour votre requête" msgid "Please indicate the result of the following operation" msgstr "Veuillez indiquer le résultat de l'opération suivante" -#: pod/main/forms.py:86 +#: pod/main/forms.py:72 +msgid "Check this box if you are a metal human (required)" +msgstr "Cocher cette case si vous êtes un humain en métal (obligatoire)" + +#: pod/main/forms.py:91 msgid "Please specify a subject" msgstr "Veuillez spécifier un sujet" @@ -3064,11 +3064,11 @@ msgstr "Utiliser le champ pour filtrer les utilisateurs par nom de famille." msgid "Link" msgstr "Lien" -#: pod/main/views.py:229 +#: pod/main/views.py:233 msgid "your message untitled" msgstr "votre message intitulé" -#: pod/main/views.py:248 +#: pod/main/views.py:252 msgid "Your message have been sent." msgstr "Votre message a été envoyé." @@ -5587,6 +5587,9 @@ msgstr "Recherche avancée" msgid "Remove this filter" msgstr "Retirer ce filtre" +#~ msgid "Dutch (Netherlands)" +#~ msgstr "Néerlandais (Pays-Bas)" + #~ msgid "link" #~ msgstr "lien" diff --git a/pod/locale/nl/LC_MESSAGES/django.po b/pod/locale/nl/LC_MESSAGES/django.po index cf8abb2d42..2a19f99843 100755 --- 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: 2021-03-05 15:42+0000\n" +"POT-Creation-Date: 2021-03-10 11:14+0000\n" "PO-Revision-Date: 2021-01-22 12:27+0100\n" "Last-Translator: obado \n" "Language-Team: \n" @@ -148,7 +148,7 @@ msgstr "" #: pod/enrichment/templates/enrichment/group_enrichment.html:29 #: pod/interactive/templates/interactive/group_interactive.html:29 #: pod/live/templates/live/live-form.html:10 -#: pod/main/templates/contact_us.html:24 pod/main/views.py:255 +#: pod/main/templates/contact_us.html:24 pod/main/views.py:259 #: pod/playlist/views.py:140 #: pod/recorder/templates/recorder/add_recording.html:36 #: pod/recorder/templates/recorder/record_delete.html:32 @@ -1300,10 +1300,6 @@ msgstr "" msgid "Please correct errors" msgstr "" -#: pod/custom/settings_local.py:76 -msgid "Dutch (Netherlands)" -msgstr "" - #: pod/enrichment/apps.py:7 msgid "Enrichment version" msgstr "" @@ -2063,7 +2059,11 @@ msgstr "" msgid "Please indicate the result of the following operation" msgstr "" -#: pod/main/forms.py:86 +#: pod/main/forms.py:72 +msgid "Check this box if you are a metal human (required)" +msgstr "" + +#: pod/main/forms.py:91 msgid "Please specify a subject" msgstr "" @@ -2965,11 +2965,11 @@ msgstr "" msgid "Link" msgstr "" -#: pod/main/views.py:229 +#: pod/main/views.py:233 msgid "your message untitled" msgstr "" -#: pod/main/views.py:248 +#: pod/main/views.py:252 msgid "Your message have been sent." msgstr "" diff --git a/pod/main/forms.py b/pod/main/forms.py index cd259edf51..1386881d61 100644 --- a/pod/main/forms.py +++ b/pod/main/forms.py @@ -69,7 +69,7 @@ class ContactUsForm(forms.Form): valid_human = forms.BooleanField( required=False, - label=_('check this box if you are a metal human'), + label=_('Check this box if you are a metal human (required)'), widget=forms.CheckboxInput()) def __init__(self, request, *args, **kwargs): From d7e16eeb5a3dd22f9741b808236956fe2853555d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9line=20Perv=C3=A8s?= Date: Wed, 10 Mar 2021 12:40:18 +0100 Subject: [PATCH 072/261] height property of media does not exists when this is an audio --- pod/video/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pod/video/models.py b/pod/video/models.py index aa187ab96c..cf02452e29 100755 --- a/pod/video/models.py +++ b/pod/video/models.py @@ -849,7 +849,7 @@ def get_media_json(self, extension_list, list_video): 'id': media.id, 'type': media.encoding_format, 'src': media.source_file.url, - 'height': media.height, + 'height': media.height if hasattr(media, 'height') else None, 'extension': file_extension, 'label': media.name} dict_entry = dict_src.get(file_extension[1:], None) From ca3e917d60b94d1ac8fe2d0ffcef642c55496df7 Mon Sep 17 00:00:00 2001 From: Joshua Baubry Date: Wed, 10 Mar 2021 14:47:24 +0100 Subject: [PATCH 073/261] accessgroup for podfile --- pod/podfile/static/podfile/js/filewidget.js | 1 + pod/podfile/templates/podfile/userfolder.html | 3 +- pod/podfile/views.py | 31 +++++++++++-------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/pod/podfile/static/podfile/js/filewidget.js b/pod/podfile/static/podfile/js/filewidget.js index 60a39b85c7..514ffa4aa0 100644 --- a/pod/podfile/static/podfile/js/filewidget.js +++ b/pod/podfile/static/podfile/js/filewidget.js @@ -35,6 +35,7 @@ if(typeof loaded == 'undefined') { $(document).on("click", "a.folder", function(e) { e.preventDefault(); + console.log("opened file") $('#podfile #list_folders_sub a.folder-opened').removeClass('folder-opened'); $(this).addClass('folder-opened'); $('#files').addClass('loading'); diff --git a/pod/podfile/templates/podfile/userfolder.html b/pod/podfile/templates/podfile/userfolder.html index 3181305a6a..8dce7360cd 100644 --- a/pod/podfile/templates/podfile/userfolder.html +++ b/pod/podfile/templates/podfile/userfolder.html @@ -119,7 +119,7 @@ - {% else %} get_folder_file") if type is None: type = request.GET.get('type', None) folder = get_object_or_404(UserFolder, id=id) + if (request.user != folder.owner - and not request.user.groups.filter( + and not (folder.groups.filter( name__in=[ name[0] - for name in folder.groups.values_list('name') - ] - ).exists() + for name in AccessGroup.objects.filter(users__user=request.user).values_list('name') + ]).exists()) and not ( request.user.is_superuser or request.user.has_perm( "podfile.change_userfolder")) and not ( request.user in folder.users.all())): + print("not access") messages.add_message( request, messages.ERROR, _(u'You cannot see this folder.')) @@ -170,7 +174,8 @@ def get_rendered(request): ).exclude(owner=request.user, name="home") share_folder = UserFolder.objects.filter( - groups__in=request.user.groups.all() + groups__in=AccessGroup.objects.filter( + users__user=request.user) ).exclude(owner=request.user).order_by('owner', 'id') share_folder_user = UserFolder.objects.filter( @@ -529,6 +534,7 @@ def file_edit_save(request, folder): @csrf_protect @staff_member_required(redirect_field_name='referrer') def get_file(request, type): + print("==> get_file") id = None if request.method == 'POST' and request.POST.get('src'): id = request.POST.get('src') @@ -539,12 +545,11 @@ def get_file(request, type): else: reqfile = get_object_or_404(CustomFileModel, id=id) if (request.user != reqfile.folder.owner - and not request.user.groups.filter( + and not reqfile.folder.groups.filter( name__in=[ name[0] - for name in reqfile.folder.groups.values_list('name') - ] - ).exists() + for name in AccessGroup.objects.filter(users__user=request.user).values_list('name') + ]).exists() and not (request.user.is_superuser or request.user.has_perm( "podfile.change_customfilemodel") or request.user.has_perm( "podfile.change_customimagemodel") or ( From 854d4feb904abab2330d252ef54b34841b437ca5 Mon Sep 17 00:00:00 2001 From: Olivier Bado Date: Wed, 10 Mar 2021 16:22:28 +0100 Subject: [PATCH 074/261] Minor code formatting --- .../templates/userpicture/userpicture.html | 52 ++++---- pod/bbb/templates/bbb/publish_meeting.html | 111 +++++++++--------- .../enrichment/group_enrichment.html | 14 +-- pod/main/templates/contact_us.html | 83 +++++++------ .../templates/recorder/add_recording.html | 2 +- 5 files changed, 128 insertions(+), 134 deletions(-) diff --git a/pod/authentication/templates/userpicture/userpicture.html b/pod/authentication/templates/userpicture/userpicture.html index bcd58f315b..20734e96e8 100644 --- a/pod/authentication/templates/userpicture/userpicture.html +++ b/pod/authentication/templates/userpicture/userpicture.html @@ -11,43 +11,43 @@
-
\ No newline at end of file + diff --git a/pod/bbb/templates/bbb/publish_meeting.html b/pod/bbb/templates/bbb/publish_meeting.html index 0eb92551e7..bd9503cd98 100644 --- a/pod/bbb/templates/bbb/publish_meeting.html +++ b/pod/bbb/templates/bbb/publish_meeting.html @@ -6,87 +6,84 @@ {% endblock page_extra_head %} -{% block breadcrumbs %}{{ block.super }} - - +{% block breadcrumbs %}{{ block.super }} + + {% endblock %} {% block page_title %} -{% trans "Publish the BigBlueButton presentation" %} + {% trans "Publish the BigBlueButton presentation" %} {% endblock %} {% block page_content %}

{% trans "Are you sure you want to publish this BigBlueButton presentation ?" %}

-
- {% csrf_token %} + action="{{request.get_full_path}}" + accept-charset="utf-8" class="needs-validation" novalidate> + {% csrf_token %} -
-
- {% if form.errors %} -

{% trans "One or more errors have been found in the form." %}

- {% endif %} - {% for field_hidden in form.hidden_fields %} - {{field_hidden.errors}} - {{field_hidden}} - {% endfor %} - {% if form.errors %} - {% for error in form.errors %} - {{ error }} - {% endfor %} - {% endif %} - {% for field in form.visible_fields %} - {% spaceless %} -
-
-
- {{ field.errors }} - {% if "form-check-input" in field.field.widget.attrs.class %} -
- {{ field }} -
- {% else %} - - {{ field }} - {% endif %} - {% if field.help_text %} - {{ field.help_text|safe }} - {% endif %} - {% if field.field.required %}
{% trans "Please provide a valid value for this field" %}.
{%endif%} -
-
+
+
+ {% if form.errors %} +

{% trans "One or more errors have been found in the form." %}

+ {% endif %} + {% for field_hidden in form.hidden_fields %} + {{field_hidden.errors}} + {{field_hidden}} + {% endfor %} + {% if form.errors %} + {% for error in form.errors %} + {{ error }} + {% endfor %} + {% endif %} + {% for field in form.visible_fields %} + {% spaceless %} +
+
+
+ {{ field.errors }} + {% if "form-check-input" in field.field.widget.attrs.class %} +
+ {{ field }}
- {% endspaceless %} - {% endfor %} -
- {% trans "A video will be created from the BigBlueButton presentation and will be available on this platform." %}
- {% trans "Please note: this treatment can take a long time. You will receive an email when this treatment is completed." %} -
-
- -
+ {% else %} + + {{ field }} + {% endif %} + {% if field.help_text %} + {{ field.help_text|safe }} + {% endif %} + {% if field.field.required %}
{% trans "Please provide a valid value for this field" %}.
{%endif%} +
+
+ + {% endspaceless %} + {% endfor %} + + {% trans "A video will be created from the BigBlueButton presentation and will be available on this platform." %}
+ {% trans "Please note: this treatment can take a long time. You will receive an email when this treatment is completed." %} + +
+ +
{% endblock page_content %} {% block collapse_page_aside %} - {% endblock collapse_page_aside %} {% block page_aside %} - {% endblock page_aside %} {% block more_script %} {{form.media}} -{% endblock more_script %} \ No newline at end of file +{% endblock more_script %} diff --git a/pod/enrichment/templates/enrichment/group_enrichment.html b/pod/enrichment/templates/enrichment/group_enrichment.html index 86d4375435..4cd08e0efd 100644 --- a/pod/enrichment/templates/enrichment/group_enrichment.html +++ b/pod/enrichment/templates/enrichment/group_enrichment.html @@ -6,7 +6,7 @@ {% endblock page_extra_head %} -{% block breadcrumbs %}{{ block.super }} +{% block breadcrumbs %}{{ block.super }} {% endblock %} @@ -43,7 +43,7 @@
{% csrf_token %}
- {% trans "Select the desired options than validate this form by clicking \"Perform a BigBlueButton live\"." %}
+ {% trans 'Select the desired options than validate this form by clicking "Perform a BigBlueButton live".' %}

{% trans "This live will be stopped automatically when BigBlueButton session ends." %}

@@ -80,7 +80,7 @@

{% trans "Are you sure you want to perform a BigBlueButton live ?" %}

{% endspaceless %} {% endfor %} - {% trans "Please note: shortly after clicking the \"Perform a BigBlueButton live\" button, the live stream will be available to users on the Lives page." %}
+ {% trans 'Please note: shortly after clicking the "Perform a BigBlueButton live" button, the live stream will be available to users on the Lives page.' %}
diff --git a/pod/bbb/templates/bbb/live_record_list.html b/pod/bbb/templates/bbb/live_record_list.html index 5889777974..e263fe4348 100644 --- a/pod/bbb/templates/bbb/live_record_list.html +++ b/pod/bbb/templates/bbb/live_record_list.html @@ -12,7 +12,7 @@ {% endfor %}
{% if records.has_next %} - More + {% trans "More" %} {% endif %} {% endif %} diff --git a/pod/video/templates/videos/video-element.html b/pod/video/templates/videos/video-element.html index 8bfe1c25b2..4451de6165 100644 --- a/pod/video/templates/videos/video-element.html +++ b/pod/video/templates/videos/video-element.html @@ -1,37 +1,36 @@ {% load i18n %}
{% csrf_token %}
{% if video.overlay_set.all %} - + {% endif %} {% if video.chapter_set.all %}

{% trans "Editing group for the enrichment of the video" %} "{{video.title}}
{{ field.errors }} - + {{ field }} {% if field.help_text %} {{ field.help_text|safe }} @@ -57,7 +57,7 @@

{% trans "Editing group for the enrichment of the video" %} "{{video.title}}

- + {% trans 'back to editing enrichment' %}
@@ -77,10 +77,10 @@
 {% trans "Manag {% endblock page_aside %} {% block more_script %} - - - - + + + + {{form.media}} {% endblock more_script %} \ No newline at end of file diff --git a/pod/main/templates/contact_us.html b/pod/main/templates/contact_us.html index c8c803294c..0efbbe2cec 100644 --- a/pod/main/templates/contact_us.html +++ b/pod/main/templates/contact_us.html @@ -2,79 +2,76 @@ {% load i18n %} {% load staticfiles %} - {% block breadcrumbs %} -{{ block.super }} +{{ block.super }} {% endblock %} -{% block page_title %} -{% trans "Contact us" %} -{% endblock %} - +{% block page_title %}{% trans "Contact us" %}{% endblock %} {% block page_content %}

{% trans "Contact us" %}

- {% csrf_token %} -
+ {% csrf_token %} +
- {% if form.errors %} + {% if form.errors %}

{% trans "One or more errors have been found in the form." %}

- {% endif %} - {% for field_hidden in form.hidden_fields %} - {{ field_hidden.errors }} - {{field_hidden}} - {% endfor %} - {% for field in form.visible_fields %} - {% spaceless %} -
+ {% endif %} + + {% for field_hidden in form.hidden_fields %} + {{ field_hidden.errors }} + {{ field_hidden }} + {% endfor %} + + {% for field in form.visible_fields %} + {% spaceless %} +
- {{ field.errors }} - {% if "form-check-input" in field.field.widget.attrs.class %} + {{ field.errors }} + {% if "form-check-input" in field.field.widget.attrs.class %}
- {{ field }} + {{ field }}
- {% else %} - + {% else %} + {% if "form-control-file" in field.field.widget.attrs.class and form.instance.video %}
{%endif%} {{ field }} - {% endif %} - {% if field.help_text %} + {% endif %} + {% if field.help_text %} {{ field.help_text|safe }} - {% endif %} - {% if field.field.required %}
{% trans "Please provide a valid value for this field" %}.
{%endif%} -
+ {% endif %} + {% if field.field.required %}
{% trans "Please provide a valid value for this field" %}.
{%endif%}
- {% endspaceless %} - {% endfor %} -
- -
- +
+ {% endspaceless %} + {% endfor %} +
+ +
+
-
+
{% endblock page_content %} {% block collapse_page_aside %} -{{block.super}} + {{block.super}} {% endblock collapse_page_aside %} {% block page_aside %} -
+
{% trans "Mandatory fields" %}
-

{% trans "Fields marked with an asterisk are mandatory."%}

+

{% trans "Fields marked with an asterisk are mandatory." %}

-
-{{block.super}} +
+ {{block.super}} {% endblock page_aside %} {% block more_script %} - -{% endblock more_script %} \ No newline at end of file +{% endblock more_script %} diff --git a/pod/recorder/templates/recorder/add_recording.html b/pod/recorder/templates/recorder/add_recording.html index 277874ad18..055ad17b72 100644 --- a/pod/recorder/templates/recorder/add_recording.html +++ b/pod/recorder/templates/recorder/add_recording.html @@ -13,7 +13,7 @@ {% endblock page_extra_head %} -{% block breadcrumbs %}{{ block.super }} +{% block breadcrumbs %}{{ block.super }} {% endblock %} From 12d79ac4a81c45cc17661dd9aae9db4a68f91bf0 Mon Sep 17 00:00:00 2001 From: Olivier Bado Date: Wed, 10 Mar 2021 16:25:08 +0100 Subject: [PATCH 075/261] [Bugfix] correct a small bug caused when user search for a non numeric video id. Now search returns nothing instead of a 500 error. --- pod/main/views.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pod/main/views.py b/pod/main/views.py index f2e535ad39..cae6370053 100644 --- a/pod/main/views.py +++ b/pod/main/views.py @@ -156,6 +156,7 @@ def contact_us(request): video = Video.objects.get(id=request.GET.get('video'), sites=get_current_site(request)) if ( request.GET.get('video') + and request.GET.get('video').isdigit() and Video.objects.filter( id=request.GET.get('video'), sites=get_current_site(request)).first() From b37decd697e06f598c8efc455a529f9001088af5 Mon Sep 17 00:00:00 2001 From: Olivier Bado Date: Wed, 10 Mar 2021 16:44:52 +0100 Subject: [PATCH 076/261] [BugFix] Correct a bug I introduced in PR #439 preventing main content from enlarging when Aside was closed. + Now only "success" type alert will be automatically closed, alert-danger and alert-warning will remain on screen --- pod/main/static/js/main.js | 40 +++++++++++++++++++----------- pod/main/templates/base.html | 2 +- pod/main/templates/contact_us.html | 25 +++++-------------- 3 files changed, 33 insertions(+), 34 deletions(-) diff --git a/pod/main/static/js/main.js b/pod/main/static/js/main.js index 944b71adb3..7ae56c20e3 100644 --- a/pod/main/static/js/main.js +++ b/pod/main/static/js/main.js @@ -171,39 +171,51 @@ $('#ownerboxnavbar').keyup(function() { /** MENU ASIDE **/ $(document).ready(function () { + //.collapseAside is on the toggle button + //#collapseAside is the side menu - //when a group is shown, save it as the active accordion group + // Fired when #collapseAside has been made visible $("#collapseAside").on('shown.bs.collapse', function () { Cookies.set('activeCollapseAside', "open"); $(".collapseAside").html(''); feather.replace({ class: 'align-bottom'}); + $("#mainContent").addClass("col-md-9"); }); + // Fired when #collapseAside has been hidden $("#collapseAside").on('hidden.bs.collapse', function () { Cookies.set('activeCollapseAside', "close"); $(".collapseAside").html(''); feather.replace({ class: 'align-bottom'}); + $("#mainContent").removeClass("col-md-9"); }); - var last = Cookies.get('activeCollapseAside'); - //alert('last '+last); - if (last != null && last=="close") { - //show the account_last visible group - $("#collapseAside").addClass("hide"); - $(".collapseAside").html(''); - feather.replace({ class: 'align-bottom'}); - } else { - $("#collapseAside").addClass("show"); - $(".collapseAside").html(''); - feather.replace({ class: 'align-bottom'}); - } + + // If aside menu is empty, hide container and button if ($("#collapseAside").find("div").length == 0) { + $(".collapseAside").hide(); $("#collapseAside").collapse('hide'); + // Destroy collapse object + $("#collapseAside").collapse('dispose'); + $("#mainContent").removeClass("col-md-9"); + } else { + // Use the last aside state, stored in Cookies + var last = Cookies.get('activeCollapseAside'); + if (last != null && last=="close") { + $("#collapseAside").collapse('hide'); + $(".collapseAside").html(''); + feather.replace({ class: 'align-bottom'}); + $("#mainContent").removeClass("col-md-9"); + } else { + $("#collapseAside").collapse('show'); + } } TriggerAlertClose(); }); function TriggerAlertClose() { + // Automatically hide success type alerts + // (alert-warning and alert-danger will remain on screen) window.setTimeout(function () { - $(".alert").fadeTo(1000, 0).slideUp(1000, function () { + $(".alert.alert-success").fadeTo(1000, 0).slideUp(1000, function () { $(this).remove(); }); }, 5000); diff --git a/pod/main/templates/base.html b/pod/main/templates/base.html index cef689739a..c9ff205abb 100644 --- a/pod/main/templates/base.html +++ b/pod/main/templates/base.html @@ -79,7 +79,7 @@
-
+
{% block page_content %} diff --git a/pod/main/templates/contact_us.html b/pod/main/templates/contact_us.html index f8c03836ac..8a82d84318 100644 --- a/pod/main/templates/contact_us.html +++ b/pod/main/templates/contact_us.html @@ -18,27 +18,14 @@

{% trans "Contact us" %}

{% if form.errors %}

{% trans "One or more errors have been found in the form." %}

-<<<<<<< HEAD - {% endif %} - - {% for field_hidden in form.hidden_fields %} - {{ field_hidden.errors }} - {{ field_hidden }} - {% endfor %} - - {% for field in form.visible_fields %} - {% spaceless %} -
-======= {% endif %} {% for field_hidden in form.hidden_fields %} - {{ field_hidden.errors }} - {{field_hidden}} - {% endfor %} - {% for field in form.visible_fields %} - {% spaceless %} -
->>>>>>> a00ab33f612a07cdd391dc8b41e7f9a802af54ef + {{ field_hidden.errors }} + {{ field_hidden }} + {% endfor %} + {% for field in form.visible_fields %} + {% spaceless %} +
{{ field.errors }} {% if "form-check-input" in field.field.widget.attrs.class %} From 5aeaaf0bd591030baa7c15e26454a7d1b17778ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9line=20Perv=C3=A8s?= Date: Thu, 11 Mar 2021 08:26:50 +0100 Subject: [PATCH 077/261] resolve pep8 trouble --- pod/video/models.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pod/video/models.py b/pod/video/models.py index cf02452e29..3e190dd305 100755 --- a/pod/video/models.py +++ b/pod/video/models.py @@ -845,11 +845,14 @@ def get_media_json(self, extension_list, list_video): for media in list_video: file_extension = splitext(media.source_file.url)[-1] if not extension_list or file_extension[1:] in extension_list: + media_height = None + if hasattr(media, 'height'): + media_height = media.height video_object = { 'id': media.id, 'type': media.encoding_format, 'src': media.source_file.url, - 'height': media.height if hasattr(media, 'height') else None, + 'height': media_height, 'extension': file_extension, 'label': media.name} dict_entry = dict_src.get(file_extension[1:], None) From 9d218e78603fd52428b1728d3c45efdbfa30997d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Sen=C3=A9?= Date: Thu, 11 Mar 2021 09:05:50 +0100 Subject: [PATCH 078/261] Revert CSS Override Changes --- pod/main/templates/base.html | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pod/main/templates/base.html b/pod/main/templates/base.html index f8609cedca..af5e5dbf22 100644 --- a/pod/main/templates/base.html +++ b/pod/main/templates/base.html @@ -27,12 +27,10 @@ {% else %} {% endif %} - + + {% if CSS_OVERRIDE %} - {% else %} - - {% endif %} From e53bce882a80c200ecb2e406c6a2e7bf1f779408 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Sen=C3=A9?= Date: Thu, 11 Mar 2021 09:12:55 +0100 Subject: [PATCH 079/261] use darmode css as base for dislexia --- pod/main/static/css/pod.css | 1292 +++++++++++++++++++---------------- 1 file changed, 698 insertions(+), 594 deletions(-) diff --git a/pod/main/static/css/pod.css b/pod/main/static/css/pod.css index 16b73b6c15..f07b551068 100755 --- a/pod/main/static/css/pod.css +++ b/pod/main/static/css/pod.css @@ -3,630 +3,734 @@ font-family: "Open Dyslexic"; src: url("https://cdn.jsdelivr.net/npm/open-dyslexic@1.0.3/woff/OpenDyslexic-Regular.woff") format("woff"); } + /* COMMON COLORS */ :root { ---color-transparent: transparent; ---color-white: white; ---color-black: black; ---color-alto: #ddd; ---color-sisal: rgba(218,208,190,1); ---color-mine-shaft: rgba(60,60,60,0.3); ---color-black-alpha: rgba(0, 0, 0, 0.6); ---color-silver: #ccc; ---color-fuzzy-wuzzy-brown: rgba(201, 76, 76, 0.3); ---color-silver-chalice: #aaa; ---color-white: #FFF; ---color-outer-space: rgba(40,48,56, 0.5); ---color-red: #FF0000; ---color-mine-shaft: #222; -} - -[data-theme="light"] { -/* CUSTOM COLORS */ ---bg-color: #FFF; ---font-color: #222; -/* BOOTSTRAP COLORS */ ---primary: #b03c7e; ---primary2: #b03c7e; ---light: #f2f2f2; ---dark: #343a40; ---color-formfields: #f1f1f1; -} -[data-theme="dark"] { -/* CUSTOM COLORS */ ---color-shark: #212529; ---bg-color: #343a40; ---font-color: #f8f9fa; -/* BOOTSTRAP COLORS */ ---primary: #b03c7e; ---primary2: #b03c7e; ---light: #393f46; ---dark: #f8f9fa; ---color-formfields: #454c52; -} - -[data-dyslexia="on"] { ---font-family-sans-serif: "Open Dyslexic"; -} -.btn-primary.focus, .btn-primary:focus, .btn-primary:hover { - background-color: var(--primary2); - border-color: var(--primary2); -} - -.btn-outline-primary:hover { - background-color: var(--primary2); - border-color: var(--primary2); -} -.close { - color: var(--font-color); -} -.close:hover { - color: var(--primary2); -} -.btn-link:hover { - color: var(--primary2); -} - -.navbar-light .navbar-nav .nav-link { + --color-transparent: transparent; + --color-white: white; + --color-black: black; + --color-alto: #ddd; + --color-sisal: rgba(218,208,190,1); + --color-mine-shaft: rgba(60,60,60,0.3); + --color-black-alpha: rgba(0, 0, 0, 0.6); + --color-silver: #ccc; + --color-fuzzy-wuzzy-brown: rgba(201, 76, 76, 0.3); + --color-silver-chalice: #aaa; + --color-white: #FFF; + --color-outer-space: rgba(40,48,56, 0.5); + --color-red: #FF0000; + --color-mine-shaft: #222; + } + + [data-theme="light"] { + /* CUSTOM COLORS */ + --bg-color: #FFF; + --font-color: #222; + /* BOOTSTRAP COLORS */ + --primary: #b03c7e; + --primary2: #b03c7e; + --light: #f8f9fa; + --dark: #343a40; + --color-formfields: #f1f1f1; + } + [data-theme="dark"] { + /* CUSTOM COLORS */ + --color-shark: #212529; + --bg-color: #343a40; + --font-color: #f8f9fa; + /* BOOTSTRAP COLORS */ + --primary: #b03c7e; + --primary2: #b03c7e; + --light: #393f46; + --dark: #f8f9fa; + --color-formfields: #454c52; + } + + /* DARK MODE CUSTOM COLORS and CSS */ + [data-theme="dark"] { + --background-color: #1e1e2c; + /* CUSTOM COLORS */ + --link-color: #fdb6de; + --color-shark: #212529; + --bg-color: #303238; + --font-color: #f8f9fa; + /* BOOTSTRAP COLORS */ + --primary: #b03c7e; + --primary2: var(--primary); + --light: var(--dark); + --dark: #202025; + --gray: var(--dark); + --color-formfields: #454c52; + --color-silver-chalice: #000; + --color-alto: var(--bg-color); + /* Video Comment variable */ + --primary-background-color: var(--bg-color) !important; + --third-background-color: var(--bg-color) !important; + --content-primary-color: var(--font-color) !important; + + } + [data-theme="dark"] a{ + color: var(--link-color); + } + [data-theme="dark"] .btn, + [data-theme="dark"] .dropdown-item, + [data-theme="dark"] footer{ color: var(--font-color); -} -.navbar-light .navbar-nav .nav-link:focus, .navbar-light .navbar-nav .nav-link:hover { - color: var(--primary2); -} -.navbar-brand { - color: var(--font-color) !important; -} -.nav-link-icone { - color: var(--primary); -} -.btn-primary { - /* color: var(--font-color); */ - background-color: var(--primary); - border-color: var(--primary); -} - -.modal-title svg { - color: var(--primary)!important; -} - -.bg-light { - background-color: var(--light)!important; -} - -.bg-dark { - background-color: var(--gray)!important; -} - -.nav-tabs .nav-item.show .nav-link, .nav-tabs .nav-link.active { - color: var(--color-white); - background-color: var(--primary); - border-color: var(--color-alto) var(--color-alto) var(--color-alto); -}b03c7e - -.btn-link { - font-weight: 400; - color: var(--primary); - text-decoration: none; -} - -.btn-outline-primary { + } + [data-theme="dark"] .btn:hover{ + color: inherit; + } + [data-theme="dark"] .btn.btn-light{ + background-color: var(--dark); + border-color: var(--dark); color: var(--primary); + } + [data-theme="dark"] .btn-primary.focus, + [data-theme="dark"] .btn-outline-primary:focus, + [data-theme="dark"] .btn-outline-primary:active, + [data-theme="dark"] .btn-primary:focus, + [data-theme="dark"] .btn-primary:hover, + [data-theme="dark"] .dropdown-item:hover, + [data-theme="dark"] .btn-outline-primary:hover, + [data-theme="dark"] .btn-primary:not(:disabled):not(.disabled).active, + [data-theme="dark"] .btn-primary:not(:disabled):not(.disabled):active, + [data-theme="dark"] .show>.btn-primary.dropdown-toggle, + [data-theme] .badge-primary, + [data-theme="dark"] .btn-primary + { + background: var(--primary); border-color: var(--primary); -} - -a.btn-outline-primary svg { - fill: var(--primary); -} - -#formfields .btn { - color: var(--font-color); - background-color: var(--color-formfields); -} - -.card-footer-pod .btn { -color: var(--font-color); -} - -.card-footer-pod .btn-light { + box-shadow: none; color: var(--font-color); - background-color: var(--light); - border-color: var(--color-alto); -} - -.submit-row a.deletelink { - height: 35px; -} - -.select2-container{ - position: static !important; - height:auto; -} - -tr ,.rowl{ - display: table-row !important; -} - -body[data-admin-utc-offset] -{ - padding-top: 0; -} - -body { - font-family: var(--font-family-sans-serif); - padding-top: 3.5rem; - color: var(--font-color); - background-color: var(--bg-color); -} -.jumbotron { - padding: 1rem 2rem; -} -h1{ - font-size: 2rem; -} -label { - font-variant: small-caps; -} -.pod-mt-7{ - margin-top: 3.5rem; -} -.breadcrumb, .jumbotron{ - background: var(--light); -} -.list-group-item{ - background: var(--bg-color); - padding:.25rem 1.25rem; -} - -.container-pod{ - max-width: 1400px; -} - -/*** video ***/ -#myTabContent #info p { - margin-top: .5rem; - margin-bottom: .5rem; -} -#share legend{ - /* align text with feather-icon */ - line-height: 1em; -} - -.hidespinner { - display: none; -} - -.link-center-pod { - margin-left: auto; - margin-right: auto; -} - -/*** navbar **/ -/*.nav-link.btn-connexion{ - background: var(--primary); - color: var(--white) .btn-outline-primary { - color: #b03c7e; - border-color: #b03c7e; -}!important; -}*/ -.btn-lang{ - padding: 0.2rem 0.25rem; - background: var(--color-transparent); - width: 100%; - text-align: left; -} -.btn-lang-active{ - background: var(--bg-color); - color: var(--font-color); -} -.navbar-inner-pod{ - position: relative; -} -.navbar-toggler{ - padding: 0.5rem; - line-height: inherit; - font-size: 1rem; -} - -.userpicture { - height: 34px; -} - -/** modal **/ -.modal-title svg { - height: 40px; - width: 40px; - /*color:var(--primary);*/ -} - -.modal-content { - background-color: var(--bg-color); -} - -.modal-title{ - display: flex; - align-items: center; -} - -/*.modal-pod-full { - max-width: 90%; -}*/ -.modal-pod-full .close{ - font-size:3rem; -} - -.title-chaine{ - margin-right: 0.5rem; - font-weight: 600; -} -#listeChaines{ - max-height: 30rem; - overflow: auto; - border-bottom: 1px solid var(--color-black); -} -.liste-collapse{ - z-index: 900; -} -/**end modal **/ -/*** tab **/ -.tab-content>.active{ - border: 1px solid var(--color-alto); - padding: 1.5rem; - background: var(--bg-color); -} -.nav-tabs{ - border: 0; -} + } + + [data-theme="dark"] .card{ + background-color: var(--dark); + border-color: var(--dark); + } + + body.dark { + background-color: var(--background-color) !important; + } + + /* Video Comment override css dark mode */ + [data-theme="dark"] .comment_main .comment .comment_content + { + box-shadow: 2px 2px 12px var(--dark); + } + [data-theme="dark"] .comment_main .add_comment .add_comment_btn{ + box-shadow: 4px 8px var(--bg-color); + } + + /* Modal override css dark mode */ + [data-theme="dark"] .comment_main .comment .comment_content_footer .add_comment, /* comment text-area wrapper */ + [data-theme="dark"] .comment_main .add_comment .form-wrapper .new_comment.new_parent_comment, /* comment text-area */ + [data-theme="dark"] .comment_main .comment .comment_content_footer .add_comment .new_comment, /* comment text-area */ + [data-theme] #podfile #dirs .folder-search, + [data-theme="dark"] #podfile .list_folders .folder_container:nth-child(2n), + [data-theme="dark"] #podfile .list_folders_sub .folder_container:nth-child(2n), + [data-theme="dark"] .modal-content{ + background-color: var(--dark) !important; + border-color: var(--dark) !important; + color: #fff !important; + } + [data-theme="dark"] #podfile #dirs .folder-search::placeholder{ + color: #ccc; + } + [data-theme="dark"] #podfile .col{ + background-color: var(--bg-color); + } + [data-theme="dark"] .list-group-item-action:focus, .list-group-item-action:hover + { + background-color: var(--dark); + } + + /* INPUT TEXT-AREA SELECT dark mode */ + [data-theme="dark"] select, + [data-theme="dark"] input:not(.btn-lang), + [data-theme="dark"] text-area, + [data-theme="dark"] .select2-container, + [data-theme="dark"] .select2-container-multi .select2-choices .select2-search-field input, + [data-theme="dark"] .select2-container-multi .select2-choices, + [data-theme="dark"] .select2-drop-active, + [data-theme="dark"] .select2-choice, + [data-theme="dark"] .select2-choice .select2-search-choice-close + div, + [data-theme="dark"] .select2-dropdown-open .select2-choice, + [data-theme="dark"] .select2-results .select2-no-results, + [data-theme="dark"] .select2-results .select2-searching + { + background: var(--bg-color) !important; + border-color: var(--bg-color) !important; + color: var(--font-color) !important; + box-shadow: none !important; + } + /* END DARK MODE */ + + /* START DISLEXIA FONT */ + [data-dyslexia="on"] { + --font-family-sans-serif: "Open Dyslexic"; + } + /* END DISLEXIA MODE */ -.dropdown-menu { - background-color: var(--color-alto); + .navbar-light .navbar-nav .nav-link { + color: var(--font-color); + } + .navbar-light .navbar-nav .nav-link:focus, .navbar-light .navbar-nav .nav-link:hover { + color: var(--primary); + } + .navbar-brand { + color: var(--font-color) !important; + } + .nav-link-icone { + color: var(--primary); + } + .btn-primary { + /* color: var(--font-color); */ + background-color: var(--primary); + border-color: var(--primary); + } + + .modal-title svg { + color: var(--primary)!important; + } + + .bg-light { + background-color: var(--light)!important; + } + + .bg-dark { + background-color: var(--gray)!important; + } + + .nav-tabs .nav-item.show .nav-link, .nav-tabs .nav-link.active { + color: var(--color-white); + background-color: var(--primary); + border-color: var(--color-alto) var(--color-alto) var(--color-alto); + } + + .btn-link { + font-weight: 400; + color: var(--primary); + text-decoration: none; + } + + .btn-outline-primary { + color: var(--primary); + border-color: var(--primary); + } + + a.btn-outline-primary svg { + fill: var(--primary); + } + + #formfields .btn { + color: var(--font-color); + background-color: var(--color-formfields); + } + + .card-footer-pod .btn { color: var(--font-color); - border: 1px solid var(--color-silver-chalice); -} - -/***aside ***/ -.open-aside{ - margin-right: 15px; -} -#card-takenote .dropdown-menu{ - border: none; -} -/*** modif taille logo ***/ -@media (max-width: 576px ){ - .navbar-brand img{ + } + + .card-footer-pod .btn-light { + color: var(--font-color); + background-color: var(--light); + border-color: var(--color-alto); + } + + .submit-row a.deletelink { height: 35px; } - .navbar-brand{ - font-size: 0.9rem; + + .select2-container{ + position: static !important; + height:auto; } -} -@media (max-width: 992px){ - .langs{ - border-top: 1px solid var(--color-silver); + + tr ,.rowl{ + display: table-row !important; + } + + body[data-admin-utc-offset] + { + padding-top: 0; + } + + body { + padding-top: 3.5rem; + color: var(--font-color); + background-color: var(--bg-color); + } + .jumbotron { + padding: 1rem 2rem; + } + h1{ + font-size: 2rem; + } + label { + font-variant: small-caps; + } + .pod-mt-7{ + margin-top: 3.5rem; + } + .breadcrumb, .jumbotron{ + background: var(--light); + } + .list-group-item{ + background: var(--bg-color); + padding:.25rem 1.25rem; + } + + .container-pod{ + max-width: 1400px; + } + + /*** video ***/ + #myTabContent #info p { + margin-top: .5rem; + margin-bottom: .5rem; + } + #share legend{ + /* align text with feather-icon */ + line-height: 1em; } - .langs .active{ - /*background:var(--primary); */ + + .hidespinner { + display: none; + } + + .link-center-pod { + margin-left: auto; + margin-right: auto; + } + + /*** navbar **/ + /*.nav-link.btn-connexion{ + background: var(--primary); + color: var(--white) .btn-outline-primary { + color: #b03c7e; + border-color: #b03c7e; + }!important; + }*/ + .btn-lang{ + padding: 0.2rem 0.25rem; + background: var(--color-transparent); + width: 100%; + text-align: left; + } + .btn-lang-active{ + background: var(--bg-color); + color: var(--font-color); + } + .navbar-inner-pod{ + position: relative; + } + .navbar-toggler{ + padding: 0.5rem; + line-height: inherit; + font-size: 1rem; + } + + .userpicture { + height: 34px; + } + + /** modal **/ + .modal-title svg { + height: 40px; + width: 40px; + /*color:var(--primary);*/ + } + + .modal-content { + background-color: var(--bg-color); + } + + .modal-title{ + display: flex; + align-items: center; + } + + /*.modal-pod-full { + max-width: 90%; + }*/ + .modal-pod-full .close{ + font-size:3rem; + } + + .title-chaine{ + margin-right: 0.5rem; + font-weight: 600; + } + #listeChaines{ + max-height: 30rem; + overflow: auto; + border-bottom: 1px solid var(--color-black); + } + .liste-collapse{ + z-index: 900; + } + /**end modal **/ + /*** tab **/ + .tab-content>.active{ + border: 1px solid var(--color-alto); + padding: 1.5rem; + background: var(--bg-color); + } + .nav-tabs{ + border: 0; + } + + .dropdown-menu { + background-color: var(--bg-color); + color: var(--font-color); + border: 1px solid var(--color-silver-chalice); + } + + /***aside ***/ + .open-aside{ + margin-right: 15px; + } + #card-takenote .dropdown-menu{ border: none; - color: var(--white); } - .btn-connexion{ - font-size: 0.9rem; + /*** modif taille logo ***/ + @media (max-width: 576px ){ + .navbar-brand img{ + height: 35px; + } + .navbar-brand{ + font-size: 0.9rem; + } + } + @media (max-width: 992px){ + .langs{ + border-top: 1px solid var(--color-silver); + } + .langs .active{ + /*background:var(--primary); */ + border: none; + color: var(--white); + } + .btn-connexion{ + font-size: 0.9rem; + } + .navbar-items-pod{ + position: absolute; + top:53px; + left:0; + padding: 1rem; + width: 100%; + } + .navbar-nav .login .dropdown-menu { + position: absolute; + float: left; + } + #s::-webkit-input-placeholder { /* Chrome/Opera/Safari */ + color: var(--white); + } + #s::-moz-placeholder { /* Firefox 19+ */ + color: var(--white); + } + #s:-ms-input-placeholder { /* IE 10+ */ + color: var(--white); + } + #s:-moz-placeholder { /* Firefox 18- */ + color: var(--white); + } + #s{ + width:1px; + border-radius:0; + box-shadow:none; + outline: none; + padding:0; + margin:0; + border:0; + background-color: var(--color-transparent); + opacity:0; + position: absolute; + } + #s:focus{ + width:100%; + opacity:1; + display: inline-block !important; + position: absolute; + /*background: var(--primary) !important;*/ + padding: 0.5rem 1rem; + left: 0; + top:0; + z-index: 99; + color:var(--white) !important; + height: 74px; + } + .navbar label{ + padding-left: 1px; + display:inline-block; + margin-top:0.3em; + color:var(--color-sisal); + text-shadow:0 0 0.1em var(--color-mine-shaft); + position: relative; + left:0.1em; + cursor:pointer; + } + + } + /*** end MQueries **/ + + .login > .initials{ + border-radius: 50%; + /*background: var(--light);*/ + color: var(--white) !important; + font-weight: 600; + height: 3rem; + width: 3rem; + } + .nav-link{ + padding: 0.25rem 0.5rem; + } + button.nav-link{ + background: none; + border: none; + cursor: pointer; + } + + /*** CARD ***/ + .infinite-item .card-body { + padding: 0.9rem; + height: 3.5rem; + overflow: hidden; + } + .infinite-item .card-header .octicon { + height:0.9rem; + margin:0.1rem; + } + + #videos_list .card-header, .playlist-videos .card-header { + position:absolute; + width:100%; + background: var(--color-black-alpha); + padding: 0 0.25rem; + z-index: 9; + } + #videos_list .card-header .text-muted { + color:var(--white) !important; + } + + #videos_list .video-title{ + line-height: 1.2; + display: inline-block; + } + + div.video-card .d-flex { + min-height:70%; + /*position:relative;*/ + top:0; + } + + a:hover { + color: var(--primary); + } + + div.card a{ + overflow:hidden; + } + div.card a img { + transition:-webkit-transform .5s ease; + transition:transform .5s ease; + transition:transform .5s ease, -webkit-transform .5s ease } - .navbar-items-pod{ + div.card a:hover>img { + -webkit-transform:scale(1.1); + transform:scale(1.1); + z-index:0; + } + + .card { + background-color: var(--bg-color); + border-color: var(--color-silver-chalice); + } + + .card-footer-pod { position: absolute; - top:53px; - left:0; - padding: 1rem; + bottom: 57px; + right: 2px; + /*width: 100%; + text-align: center;*/ + border:none; + /*background: rgba(220,220,220);*/ + /*height: 1rem;*/ + } + .card-footer .feather, .card-header .feather{ + height: 1rem; + } + /* menu channels */ + .dropdown-submenu > .dropdown-menu { + top: 0; + left: 100%; + margin-top: -6px; + margin-left: -1px; + border-radius: 0 6px 6px 6px; + } + .dropdown-submenu:hover { + background-color: var(--white); + } + .dropdown-submenu:hover > .dropdown-menu { + display: block; + } + .dropdown-submenu > a:after { + display: block; + content: " "; + float: right; + width: 0; + height: 0; + border-color: var(--color-transparent); + border-style: solid; + border-width: 5px 0 5px 5px; + border-left-color: var(--color-silver); + margin-top: 5px; + margin-right: -10px; + } + + /** aside list video **/ + #filterType div.collapse:not(.show), #filterDiscipline div.collapse:not(.show), #filterTag div.collapse:not(.show) { + height: 148px !important; + overflow: hidden; + + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + } + + #filterType div.collapsing, #filterDiscipline div.collapsing, #filterTag div.collapsing{ + min-height: 148px !important; + } + + #filterType a.collapsed:after, #filterDiscipline a.collapsed:after, #filterTag a.collapsed:after { + content: '+'; + } + + #filterType a:not(.collapsed):after, #filterDiscipline a:not(.collapsed):after, #filterTag a:not(.collapsed):after { + content: '-'; + } + /** ckeditor **/ + .django-ckeditor-widget { width: 100%; } - .navbar-nav .login .dropdown-menu { - position: absolute; - float: left; + /** video form **/ + .required { + color:var(--primary); + font-size: 1.3rem; } - #s::-webkit-input-placeholder { /* Chrome/Opera/Safari */ - color: var(--white); + /*.form-group-required { + border-left: 3px solid var(--color-fuzzy-wuzzy-brown); + padding-left : 5px; + }*/ + .form-group-required .errors { + background-color: var(--color-fuzzy-wuzzy-brown); } - #s::-moz-placeholder { /* Firefox 19+ */ - color: var(--white); + #base-message-alert, #formalertdiv{ + position:fixed; + top:50%; + text-align: center; + margin:0 auto; + left: 50%; + transform: translate(-50%, 0); + z-index:1000; } - #s:-ms-input-placeholder { /* IE 10+ */ - color: var(--white); + + /** channel form **/ + #channel_form .selector, #enrichment_group_form .selector{ + width: 100% !important; + } + #channel_form .selector select, #enrichment_group_form .selector select { + width:100% !important; + } + #channel_form .selector-available, #channel_form .selector-chosen, #enrichment_group_form .selector-available, #enrichment_group_form .selector-chosen { + width: 47% !important; + } + #channel_form .selector-available h2, #channel_form .selector-chosen h2, #enrichment_group_form .selector-available h2, #enrichment_group_form .selector-chosen h2 { + margin: 0; + padding: 8px; + font-weight: 400; + font-size: 13px; + text-align: left; } - #s:-moz-placeholder { /* Firefox 18- */ + + /* vignettes video */ + @media (max-width: 575.98px) { + .pod-flex-direction{ + flex-direction: column; + } + } + @media screen and (min-width:768px){ + .card-img-top { + max-height:184.13px; + } + } + @media screen and (min-width:992px){ + .card-img-top { + max-height:195.36px; + } + .flex-2{ + flex: 2; + } + } + /*** footer **/ + footer{ + color:var(--color-silver-chalice); + } + footer a, footer a:hover{ color: var(--white); } - #s{ - width:1px; - border-radius:0; - box-shadow:none; - outline: none; - padding:0; - margin:0; - border:0; - background-color: var(--color-transparent); - opacity:0; - position: absolute; + + .footer_links{ + list-style:none; } - #s:focus{ - width:100%; - opacity:1; - display: inline-block !important; - position: absolute; - /*background: var(--primary) !important;*/ - padding: 0.5rem 1rem; - left: 0; - top:0; - z-index: 99; - color:var(--white) !important; - height: 74px; - } - .navbar label{ - padding-left: 1px; - display:inline-block; - margin-top:0.3em; - color:var(--color-sisal); - text-shadow:0 0 0.1em var(--color-mine-shaft); - position: relative; - left:0.1em; - cursor:pointer; + .footer_links>li:before{ + margin-right:.5em; + content: ">"; + font-weight: bold; } - -} -/*** end MQueries **/ - -.login > .initials{ - border-radius: 50%; - /*background: var(--light);*/ - color: var(--white) !important; - font-weight: 600; - height: 3rem; - width: 3rem; -} -.nav-link{ - padding: 0.25rem 0.5rem; -} -button.nav-link{ - background: none; - border: none; - cursor: pointer; -} - -/*** CARD ***/ -.infinite-item .card-body { - padding: 0.9rem; - height: 3.5rem; - overflow: hidden; -} -.infinite-item .card-header .octicon { - height:0.9rem; - margin:0.1rem; -} - -#videos_list .card-header, .playlist-videos .card-header { - position:absolute; - width:100%; - background: var(--color-black-alpha); - padding: 0 0.25rem; - z-index: 9; -} -#videos_list .card-header .text-muted { - color:var(--white) !important; -} - -#videos_list .video-title{ - line-height: 1.2; - display: inline-block; -} - -div.video-card .d-flex { - min-height:70%; - /*position:relative;*/ - top:0; -} - -a:hover { - color: var(--primary); -} - -div.card a{ - overflow:hidden; -} -div.card a img { - transition:-webkit-transform .5s ease; - transition:transform .5s ease; - transition:transform .5s ease, -webkit-transform .5s ease -} -div.card a:hover>img { - -webkit-transform:scale(1.1); - transform:scale(1.1); - z-index:0; -} - -.card { - background-color: var(--bg-color); - border-color: var(--color-silver-chalice); -} - -.card-footer-pod { - position: absolute; - bottom: 57px; - right: 2px; - /*width: 100%; - text-align: center;*/ - border:none; - /*background: rgba(220,220,220);*/ - /*height: 1rem;*/ -} -.card-footer .feather, .card-header .feather{ - height: 1rem; -} -/* menu channels */ -.dropdown-submenu > .dropdown-menu { - top: 0; - left: 100%; - margin-top: -6px; - margin-left: -1px; - border-radius: 0 6px 6px 6px; -} -.dropdown-submenu:hover { - background-color: var(--white); -} -.dropdown-submenu:hover > .dropdown-menu { - display: block; -} -.dropdown-submenu > a:after { - display: block; - content: " "; - float: right; - width: 0; - height: 0; - border-color: var(--color-transparent); - border-style: solid; - border-width: 5px 0 5px 5px; - border-left-color: var(--color-silver); - margin-top: 5px; - margin-right: -10px; -} - -/** aside list video **/ -#filterType div.collapse:not(.show), #filterDiscipline div.collapse:not(.show), #filterTag div.collapse:not(.show) { - height: 148px !important; - overflow: hidden; - - display: -webkit-box; - -webkit-line-clamp: 2; - -webkit-box-orient: vertical; -} - -#filterType div.collapsing, #filterDiscipline div.collapsing, #filterTag div.collapsing{ - min-height: 148px !important; -} - -#filterType a.collapsed:after, #filterDiscipline a.collapsed:after, #filterTag a.collapsed:after { - content: '+'; -} - -#filterType a:not(.collapsed):after, #filterDiscipline a:not(.collapsed):after, #filterTag a:not(.collapsed):after { - content: '-'; -} -/** ckeditor **/ -.django-ckeditor-widget { - width: 100%; -} -/** video form **/ -.required { - color:var(--primary); - font-size: 1.3rem; -} -/*.form-group-required { - border-left: 3px solid var(--color-fuzzy-wuzzy-brown); - padding-left : 5px; -}*/ -.form-group-required .errors { - background-color: var(--color-fuzzy-wuzzy-brown); -} -#base-message-alert, #formalertdiv{ - position:fixed; - top:50%; - text-align: center; - margin:0 auto; - left: 50%; - transform: translate(-50%, 0); - z-index:1000; -} - -/** channel form **/ -#channel_form .selector, #enrichment_group_form .selector{ - width: 100% !important; -} -#channel_form .selector select, #enrichment_group_form .selector select { - width:100% !important; -} -#channel_form .selector-available, #channel_form .selector-chosen, #enrichment_group_form .selector-available, #enrichment_group_form .selector-chosen { - width: 47% !important; -} -#channel_form .selector-available h2, #channel_form .selector-chosen h2, #enrichment_group_form .selector-available h2, #enrichment_group_form .selector-chosen h2 { - margin: 0; - padding: 8px; - font-weight: 400; - font-size: 13px; - text-align: left; -} - -/* vignettes video */ -@media (max-width: 575.98px) { - .pod-flex-direction{ - flex-direction: column; + + .top_link:before{ + content: "\21E7"; + padding-right: 4px; + text-decoration: none; + display: inline-block; + font-size: 1.2em; } -} -@media screen and (min-width:768px){ - .card-img-top { - max-height:184.13px; + + /*** Useful for additional owners ***/ + input.select2-input{ + width: 100% !important; } -} -@media screen and (min-width:992px){ - .card-img-top { - max-height:195.36px; + + #view-counter-icon{ + color: var(--primary); } - .flex-2{ - flex: 2; + + + #viewers-list { + position: absolute; + right: 0; + margin-right: 80px; + color: var(--white); + text-align: center; + font-size: 20px; + background-color: var(--color-outer-space); + padding: 10px 0; + z-index: 2147483647; + bottom: 100px; + display: none; } -} -/*** footer **/ -footer{ - color:var(--color-silver-chalice); -} -footer a, footer a:hover{ - color: var(--white); -} - -.footer_links{ - list-style:none; -} -.footer_links>li:before{ - margin-right:.5em; - content: ">"; - font-weight: bold; -} - -.top_link:before{ - content: "\21E7"; - padding-right: 4px; - text-decoration: none; - display: inline-block; - font-size: 1.2em; -} - -/*** Useful for additional owners ***/ -input.select2-input{ - width: 100% !important; -} - -#view-counter-icon{ - color: var(--primary); -} - - -#viewers-list { - position: absolute; - right: 0; - margin-right: 80px; - color: var(--white); - text-align: center; - font-size: 20px; - background-color: var(--color-outer-space); - padding: 10px 0; - z-index: 2147483647; - bottom: 100px; - display: none; -} - -.live-video { - z-index: 1; -} - -#viewers-ul{height:200px;list-style-type: none;padding-left: 0; } -#viewers-ul{overflow:hidden; overflow-y:scroll;} - + + .live-video { + z-index: 1; + } + + #viewers-ul{height:200px;list-style-type: none;padding-left: 0; } + #viewers-ul{overflow:hidden; overflow-y:scroll;} + /*** DARK MODE SWITCH ***/ .theme-switch-wrapper { display: flex; From a5d6962621fb81a65698c3a249d4a4e35e8ba6a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Sen=C3=A9?= Date: Thu, 11 Mar 2021 09:23:54 +0100 Subject: [PATCH 080/261] add dislexia setting to config file example --- pod/custom/settings_local.py.example | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pod/custom/settings_local.py.example b/pod/custom/settings_local.py.example index 1754a5df4a..2367ef05ab 100644 --- a/pod/custom/settings_local.py.example +++ b/pod/custom/settings_local.py.example @@ -1187,3 +1187,8 @@ VIDEO_REQUIRED_FIELDS = [] # Activation du darkmode """ DARKMODE_ENABLED = False + +""" +# Activation du mode dyslexie +""" +DYSLEXIAMODE_ENABLED = False \ No newline at end of file From 37384910afdc96671622b13086ce9a8c2f4882b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Sen=C3=A9?= Date: Thu, 11 Mar 2021 11:27:33 +0100 Subject: [PATCH 081/261] Add conditions to js loading for dark mode and dyslexia mode --- pod/main/templates/base.html | 12 +++++++++--- pod/main/templates/navbar.html | 4 ++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/pod/main/templates/base.html b/pod/main/templates/base.html index 69c929d8ec..344a3a4323 100644 --- a/pod/main/templates/base.html +++ b/pod/main/templates/base.html @@ -134,7 +134,9 @@ - - +{% endif %} +{% if DYSLEXIAMODE_ENABLED == True %} - +{% endif %} {% if POST_FOOTER_TEMPLATE %}{% include POST_FOOTER_TEMPLATE %}{% endif %} {% if TRACKING_TEMPLATE %}{% include TRACKING_TEMPLATE %}{% endif %} diff --git a/pod/main/templates/navbar.html b/pod/main/templates/navbar.html index aa63fcc69f..8dd4cb4efe 100644 --- a/pod/main/templates/navbar.html +++ b/pod/main/templates/navbar.html @@ -137,7 +137,7 @@
- {% endif %} + {% endif %}{% if DARKMODE_ENABLED == True or DYSLEXIAMODE_ENABLED == True %}
{% if DARKMODE_ENABLED == True %}
- {% endif %}
+ {% endif %}
{% endif %}
{% endspaceless %} From 9794303b14f596ee77cc8eaa5f26e8938d997da8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Sen=C3=A9?= Date: Thu, 11 Mar 2021 11:39:16 +0100 Subject: [PATCH 082/261] add {{VERSION}} to feather.min.js --- pod/main/templates/base.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pod/main/templates/base.html b/pod/main/templates/base.html index 344a3a4323..0b0e49a967 100644 --- a/pod/main/templates/base.html +++ b/pod/main/templates/base.html @@ -130,7 +130,7 @@ {% block more_script %} {% endblock more_script %} - + From b54a24f00c52d45168b92fb06ecda504c05c9a1c Mon Sep 17 00:00:00 2001 From: Ptitloup Date: Thu, 11 Mar 2021 12:12:24 +0100 Subject: [PATCH 083/261] Update AUTHORS.md Add Frederic Sene of INSA Rennes --- AUTHORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.md b/AUTHORS.md index 66dedaa956..202f2c1296 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -16,5 +16,6 @@ A list of much-appreciated contributors who have submitted patches and reported * Guillaume Condesse, University of Bordeaux * Franck Charneau and Joshua Baubry, University of La Rochelle * Olivier Bado, University Cote d'Azur +* Frederic Sene, INSA Rennes * Nicolas Lahoche, University of Lille (design and template) * Charlotte Benard (Logo and color) From 3e1ad0ef35a34840858be02266da3a7b9d181341 Mon Sep 17 00:00:00 2001 From: Ptitloup Date: Thu, 11 Mar 2021 12:13:15 +0100 Subject: [PATCH 084/261] Update settings.py Bump version to 2.8 --- pod/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pod/settings.py b/pod/settings.py index 9c6fb73ed0..95d2e881e8 100644 --- a/pod/settings.py +++ b/pod/settings.py @@ -9,7 +9,7 @@ ## # Version of the project # -VERSION = '2.7.3.1' +VERSION = '2.8' ## # Installed applications list From 219ba10888f6575d2d7e220fa128723cdffb9a4b Mon Sep 17 00:00:00 2001 From: Eliam LOTONGA Date: Thu, 11 Mar 2021 14:36:02 +0100 Subject: [PATCH 085/261] Extract darkmode css in dark.css file --- pod/main/static/css/dark.css | 216 +++++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 pod/main/static/css/dark.css diff --git a/pod/main/static/css/dark.css b/pod/main/static/css/dark.css new file mode 100644 index 0000000000..ab45188412 --- /dev/null +++ b/pod/main/static/css/dark.css @@ -0,0 +1,216 @@ + +[data-theme="light"] { + /* CUSTOM COLORS */ + --bg-color: #FFF; + --font-color: #222; + /* BOOTSTRAP COLORS */ + --primary: #b03c7e; + --primary2: #b03c7e; + --light: #f8f9fa; + --dark: #343a40; + --color-formfields: #f1f1f1; +} +[data-theme="dark"] { + /* CUSTOM COLORS */ + --color-shark: #212529; + --bg-color: #343a40; + --font-color: #f8f9fa; + /* BOOTSTRAP COLORS */ + --primary: #b03c7e; + --primary2: #b03c7e; + --light: #393f46; + --dark: #f8f9fa; + --color-formfields: #454c52; +} +[data-theme="dark"] { + --background-color: #1e1e2c; + /* CUSTOM COLORS */ + --link-color: #fdb6de; + --color-shark: #212529; + --bg-color: #303238; + --font-color: #f8f9fa; + /* BOOTSTRAP COLORS */ + --primary: #b03c7e; + --primary2: var(--primary); + --light: var(--dark); + --dark: #202025; + --gray: var(--dark); + --color-formfields: #454c52; + --color-silver-chalice: #000; + --color-alto: var(--bg-color); + /* Video Comment variable */ + --primary-background-color: var(--bg-color) !important; + --third-background-color: var(--bg-color) !important; + --content-primary-color: var(--font-color) !important; + +} +[data-theme="dark"] a{ + color: var(--link-color); +} +[data-theme="dark"] .btn, +[data-theme="dark"] .dropdown-item, +[data-theme="dark"] footer{ + color: var(--font-color); +} +[data-theme="dark"] .btn:hover{ + color: inherit; +} +[data-theme="dark"] .btn.btn-light{ + background-color: var(--dark); + border-color: var(--dark); + color: var(--primary); +} +[data-theme="dark"] .btn-primary.focus, +[data-theme="dark"] .btn-outline-primary:focus, +[data-theme="dark"] .btn-outline-primary:active, +[data-theme="dark"] .btn-primary:focus, +[data-theme="dark"] .btn-primary:hover, +[data-theme="dark"] .dropdown-item:hover, +[data-theme="dark"] .btn-outline-primary:hover, +[data-theme="dark"] .btn-primary:not(:disabled):not(.disabled).active, +[data-theme="dark"] .btn-primary:not(:disabled):not(.disabled):active, +[data-theme="dark"] .show>.btn-primary.dropdown-toggle, +[data-theme] .badge-primary, +[data-theme="dark"] .btn-primary +{ + background: var(--primary); + border-color: var(--primary); + box-shadow: none; + color: var(--font-color); +} + +[data-theme="dark"] .card{ + background-color: var(--dark); + border-color: var(--dark); +} + +body.dark { + background-color: var(--background-color) !important; +} + +/* Video Comment override css dark mode */ +[data-theme="dark"] .comment_main .comment .comment_content +{ + box-shadow: 2px 2px 12px var(--dark); +} +[data-theme="dark"] .comment_main .add_comment .add_comment_btn{ + box-shadow: 4px 8px var(--bg-color); +} + +/* Modal override css dark mode */ +[data-theme="dark"] .comment_main .comment .comment_content_footer .add_comment, /* comment text-area wrapper */ +[data-theme="dark"] .comment_main .add_comment .form-wrapper .new_comment.new_parent_comment, /* comment text-area */ +[data-theme="dark"] .comment_main .comment .comment_content_footer .add_comment .new_comment, /* comment text-area */ +[data-theme] #podfile #dirs .folder-search, +[data-theme="dark"] #podfile .list_folders .folder_container:nth-child(2n), +[data-theme="dark"] #podfile .list_folders_sub .folder_container:nth-child(2n), +[data-theme="dark"] .modal-content{ + background-color: var(--dark) !important; + border-color: var(--dark) !important; + color: #fff !important; +} +[data-theme="dark"] #podfile #dirs .folder-search::placeholder{ + color: #ccc; +} +[data-theme="dark"] #podfile .col{ + background-color: var(--bg-color); +} +[data-theme="dark"] .list-group-item-action:focus, .list-group-item-action:hover +{ + background-color: var(--dark); +} + +/* INPUT TEXT-AREA SELECT dark mode */ +[data-theme="dark"] select, +[data-theme="dark"] input:not(.btn-lang), +[data-theme="dark"] text-area, +[data-theme="dark"] .select2-container, +[data-theme="dark"] .select2-container-multi .select2-choices .select2-search-field input, +[data-theme="dark"] .select2-container-multi .select2-choices, +[data-theme="dark"] .select2-drop-active, +[data-theme="dark"] .select2-choice, +[data-theme="dark"] .select2-choice .select2-search-choice-close + div, +[data-theme="dark"] .select2-dropdown-open .select2-choice, +[data-theme="dark"] .select2-results .select2-no-results, +[data-theme="dark"] .select2-results .select2-searching +{ + background: var(--bg-color) !important; + border-color: var(--bg-color) !important; + color: var(--font-color) !important; + box-shadow: none !important; +} +.theme-switch-wrapper { + display: flex; + align-items: center; +} +.theme-switch-wrapper em { + margin-left: 10px; + font-size: 1rem; +} +.theme-switch { + display: inline-block; + height: 24px; + position: relative; + width: 50px; + top:7px; +} +.theme-switch input { + display: none; +} +.slider { + background-color: var(--color-silver-chalice); + bottom: 0; + cursor: pointer; + left: 0; + position: absolute; + right: 0; + top: 0; + transition: 0.4s; + border-radius: 24px; +} +.slider:before { + background-color: var(--white); + bottom: 2px; + content: ""; + height: 20px; + left: 2px; + position: absolute; + transition: 0.4s; + width: 20px; + border-radius: 50%; +} +input:checked + .slider { + background-color: var(--primary); +} +input:checked + .slider:before { + transform: translateX(26px); +} +.slider svg { + color: var(--color-mine-shaft); + width: 15px; + position: absolute; + transition: opacity 0.2s ease 0s, transform 0.35s ease 0s; + pointer-events: none; +} +.feather-moon { + opacity: 0; + left: 5px; + bottom: 0px; + color: var(--white) !important; + transform: translateX(4px); +} +.feather-sun { + opacity: 1; + right: 5px; + bottom: 0px; + transform: translateX(0px); +} +input:checked + .slider .feather-moon { + opacity: 1; + transform: translateX(0); +} +input:checked + .slider .feather-sun { + opacity: 0; + transform: translateX(-4px); +} + \ No newline at end of file From 1b16935a0fd0fa10cbe6837d3eab4c59540d2509 Mon Sep 17 00:00:00 2001 From: Eliam LOTONGA Date: Thu, 11 Mar 2021 14:36:23 +0100 Subject: [PATCH 086/261] Extract dyslexia css in dyslexia.css file --- pod/main/static/css/dyslexia.css | 50 ++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 pod/main/static/css/dyslexia.css diff --git a/pod/main/static/css/dyslexia.css b/pod/main/static/css/dyslexia.css new file mode 100644 index 0000000000..3139387fbd --- /dev/null +++ b/pod/main/static/css/dyslexia.css @@ -0,0 +1,50 @@ +/* OpenDyslexic Font via CDN */ +@font-face { + font-family: "Open Dyslexic"; + src: url("https://cdn.jsdelivr.net/npm/open-dyslexic@1.0.3/woff/OpenDyslexic-Regular.woff") format("woff"); + } + +[data-dyslexia="on"] { + --font-family-sans-serif: "Open Dyslexic"; +} + +.dyslexia-switch-wrapper { + display: flex; + align-items: center; +} +.dyslexia-switch-wrapper em { + margin-left: 10px; + font-size: 1rem; +} +.dyslexia-switch { + display: inline-block; + height: 24px; + position: relative; + width: 50px; + top:7px; +} +.dyslexia-switch input { + display: none; +} + +.feather-eye { + opacity: 0; + left: 5px; + bottom: 0px; + color: var(--white) !important; + transform: translateX(4px); +} +.feather-eye-off { + opacity: 1; + right: 5px; + bottom: 0px; + transform: translateX(0px); +} + input:checked + .slider .feather-eye { + opacity: 1; + transform: translateX(0); +} +input:checked + .slider .feather-eye-off { + opacity: 0; + transform: translateX(-4px); +} \ No newline at end of file From 62bf6498038275cffacda2e9b59cfc621c3ddfd5 Mon Sep 17 00:00:00 2001 From: Eliam LOTONGA Date: Thu, 11 Mar 2021 14:36:58 +0100 Subject: [PATCH 087/261] Remove darkmode and dyslexiamode css --- pod/main/static/css/pod.css | 743 ++++++++++++------------------------ 1 file changed, 237 insertions(+), 506 deletions(-) diff --git a/pod/main/static/css/pod.css b/pod/main/static/css/pod.css index 63ba430c7d..4c18c9f5ce 100755 --- a/pod/main/static/css/pod.css +++ b/pod/main/static/css/pod.css @@ -1,444 +1,292 @@ /* OpenDyslexic Font via CDN */ -@font-face { +/* @font-face { font-family: "Open Dyslexic"; src: url("https://cdn.jsdelivr.net/npm/open-dyslexic@1.0.3/woff/OpenDyslexic-Regular.woff") format("woff"); -} +} */ +/* @import url('./dyslexie.css') screen; */ /* COMMON COLORS */ :root { - --color-transparent: transparent; + --color-transparent:transparent; --color-white: white; --color-black: black; - --color-alto: #ddd; + --color-alto:#ddd; --color-sisal: rgba(218,208,190,1); - --color-mine-shaft: rgba(60,60,60,0.3); --color-black-alpha: rgba(0, 0, 0, 0.6); - --color-silver: #ccc; + --color-silver:#ccc; --color-fuzzy-wuzzy-brown: rgba(201, 76, 76, 0.3); - --color-silver-chalice: #aaa; - --color-white: #FFF; + --color-silver-chalice:#aaa; --color-outer-space: rgba(40,48,56, 0.5); - --color-red: #FF0000; - --color-mine-shaft: #222; - } - - [data-theme="light"] { - /* CUSTOM COLORS */ - --bg-color: #FFF; - --font-color: #222; - /* BOOTSTRAP COLORS */ - --primary: #b03c7e; - --primary2: #b03c7e; - --light: #f8f9fa; - --dark: #343a40; - --color-formfields: #f1f1f1; - } - [data-theme="dark"] { - /* CUSTOM COLORS */ - --color-shark: #212529; - --bg-color: #343a40; - --font-color: #f8f9fa; - /* BOOTSTRAP COLORS */ - --primary: #b03c7e; - --primary2: #b03c7e; - --light: #393f46; - --dark: #f8f9fa; - --color-formfields: #454c52; - } - - /* DARK MODE CUSTOM COLORS and CSS */ - [data-theme="dark"] { - --background-color: #1e1e2c; - /* CUSTOM COLORS */ - --link-color: #fdb6de; - --color-shark: #212529; - --bg-color: #303238; - --font-color: #f8f9fa; - /* BOOTSTRAP COLORS */ - --primary: #b03c7e; - --primary2: var(--primary); - --light: var(--dark); - --dark: #202025; - --gray: var(--dark); - --color-formfields: #454c52; - --color-silver-chalice: #000; - --color-alto: var(--bg-color); - /* Video Comment variable */ - --primary-background-color: var(--bg-color) !important; - --third-background-color: var(--bg-color) !important; - --content-primary-color: var(--font-color) !important; - - } - [data-theme="dark"] a{ - color: var(--link-color); - } - [data-theme="dark"] .btn, - [data-theme="dark"] .dropdown-item, - [data-theme="dark"] footer{ - color: var(--font-color); - } - [data-theme="dark"] .btn:hover{ - color: inherit; - } - [data-theme="dark"] .btn.btn-light{ - background-color: var(--dark); - border-color: var(--dark); - color: var(--primary); - } - [data-theme="dark"] .btn-primary.focus, - [data-theme="dark"] .btn-outline-primary:focus, - [data-theme="dark"] .btn-outline-primary:active, - [data-theme="dark"] .btn-primary:focus, - [data-theme="dark"] .btn-primary:hover, - [data-theme="dark"] .dropdown-item:hover, - [data-theme="dark"] .btn-outline-primary:hover, - [data-theme="dark"] .btn-primary:not(:disabled):not(.disabled).active, - [data-theme="dark"] .btn-primary:not(:disabled):not(.disabled):active, - [data-theme="dark"] .show>.btn-primary.dropdown-toggle, - [data-theme] .badge-primary, - [data-theme="dark"] .btn-primary - { - background: var(--primary); - border-color: var(--primary); - box-shadow: none; - color: var(--font-color); - } - - [data-theme="dark"] .card{ - background-color: var(--dark); - border-color: var(--dark); - } - - body.dark { - background-color: var(--background-color) !important; - } - - /* Video Comment override css dark mode */ - [data-theme="dark"] .comment_main .comment .comment_content - { - box-shadow: 2px 2px 12px var(--dark); - } - [data-theme="dark"] .comment_main .add_comment .add_comment_btn{ - box-shadow: 4px 8px var(--bg-color); - } - - /* Modal override css dark mode */ - [data-theme="dark"] .comment_main .comment .comment_content_footer .add_comment, /* comment text-area wrapper */ - [data-theme="dark"] .comment_main .add_comment .form-wrapper .new_comment.new_parent_comment, /* comment text-area */ - [data-theme="dark"] .comment_main .comment .comment_content_footer .add_comment .new_comment, /* comment text-area */ - [data-theme] #podfile #dirs .folder-search, - [data-theme="dark"] #podfile .list_folders .folder_container:nth-child(2n), - [data-theme="dark"] #podfile .list_folders_sub .folder_container:nth-child(2n), - [data-theme="dark"] .modal-content{ - background-color: var(--dark) !important; - border-color: var(--dark) !important; - color: #fff !important; - } - [data-theme="dark"] #podfile #dirs .folder-search::placeholder{ - color: #ccc; - } - [data-theme="dark"] #podfile .col{ - background-color: var(--bg-color); - } - [data-theme="dark"] .list-group-item-action:focus, .list-group-item-action:hover - { - background-color: var(--dark); - } - - /* INPUT TEXT-AREA SELECT dark mode */ - [data-theme="dark"] select, - [data-theme="dark"] input:not(.btn-lang), - [data-theme="dark"] text-area, - [data-theme="dark"] .select2-container, - [data-theme="dark"] .select2-container-multi .select2-choices .select2-search-field input, - [data-theme="dark"] .select2-container-multi .select2-choices, - [data-theme="dark"] .select2-drop-active, - [data-theme="dark"] .select2-choice, - [data-theme="dark"] .select2-choice .select2-search-choice-close + div, - [data-theme="dark"] .select2-dropdown-open .select2-choice, - [data-theme="dark"] .select2-results .select2-no-results, - [data-theme="dark"] .select2-results .select2-searching - { - background: var(--bg-color) !important; - border-color: var(--bg-color) !important; - color: var(--font-color) !important; - box-shadow: none !important; - } - /* END DARK MODE */ - - /* START DISLEXIA FONT */ - [data-dyslexia="on"] { - --font-family-sans-serif: "Open Dyslexic"; - } - /* END DISLEXIA MODE */ - - .navbar-light .navbar-nav .nav-link { + --color-red:#FF0000; + --color-mine-shaft:#222; +} +.navbar-light.navbar-nav.nav-link { color: var(--font-color); - } - .navbar-light .navbar-nav .nav-link:focus, .navbar-light .navbar-nav .nav-link:hover { +} +.navbar-light.navbar-nav.nav-link:focus,.navbar-light.navbar-nav.nav-link:hover { color: var(--primary); - } - .navbar-brand { +} +.navbar-brand { color: var(--font-color) !important; - } - .nav-link-icone { +} +.nav-link-icone { color: var(--primary); - } - .btn-primary { +} +.btn-primary { /* color: var(--font-color); */ background-color: var(--primary); border-color: var(--primary); - } +} - .modal-title svg { +.modal-title svg { color: var(--primary)!important; - } +} - .bg-light { +.bg-light { background-color: var(--light)!important; - } +} - .bg-dark { +.bg-dark { background-color: var(--gray)!important; - } +} - .nav-tabs .nav-item.show .nav-link, .nav-tabs .nav-link.active { +.nav-tabs.nav-item.show.nav-link,.nav-tabs.nav-link.active { color: var(--color-white); background-color: var(--primary); border-color: var(--color-alto) var(--color-alto) var(--color-alto); - } +} - .btn-link { +.btn-link { font-weight: 400; color: var(--primary); text-decoration: none; - } +} - .btn-outline-primary { +.btn-outline-primary { color: var(--primary); border-color: var(--primary); - } +} - a.btn-outline-primary svg { +a.btn-outline-primary svg { fill: var(--primary); - } +} - #formfields .btn { +#formfields.btn { color: var(--font-color); background-color: var(--color-formfields); - } +} - .card-footer-pod .btn { +.card-footer-pod.btn { color: var(--font-color); - } +} - .card-footer-pod .btn-light { +.card-footer-pod.btn-light { color: var(--font-color); background-color: var(--light); border-color: var(--color-alto); - } +} - .submit-row a.deletelink { +.submit-rowa.deletelink { height: 35px; - } +} - .select2-container{ +.select2-container{ position: static !important; height:auto; - } +} - tr ,.rowl{ +tr ,.rowl{ display: table-row !important; - } +} - body[data-admin-utc-offset] +body[data-admin-utc-offset] { padding-top: 0; - } +} - body { +body { padding-top: 3.5rem; color: var(--font-color); background-color: var(--bg-color); - } - .jumbotron { +} +.jumbotron { padding: 1rem 2rem; - } - h1{ +} +h1{ font-size: 2rem; - } +} label { font-variant: small-caps; - } - .pod-mt-7{ +} +.pod-mt-7{ margin-top: 3.5rem; - } - .breadcrumb, .jumbotron{ +} +.breadcrumb,.jumbotron{ background: var(--light); - } - .list-group-item{ +} +.list-group-item{ background: var(--bg-color); padding:.25rem 1.25rem; - } +} - .container-pod{ +.container-pod{ max-width: 1400px; - } +} /*** video ***/ - #myTabContent #info p { - margin-top: .5rem; - margin-bottom: .5rem; - } - #share legend{ +#myTabContent#info p { + margin-top:.5rem; + margin-bottom:.5rem; +} +#share legend{ /* align text with feather-icon */ line-height: 1em; - } +} - .hidespinner { +.hidespinner { display: none; - } +} - .link-center-pod { +.link-center-pod { margin-left: auto; margin-right: auto; - } +} /*** navbar **/ /*.nav-link.btn-connexion{ background: var(--primary); - color: var(--white) .btn-outline-primary { - color: #b03c7e; - border-color: #b03c7e; - }!important; - }*/ - .btn-lang{ + color: var(--white).btn-outline-primary { + color:#b03c7e; + border-color:#b03c7e; +}!important; +}*/ +.btn-lang{ padding: 0.2rem 0.25rem; background: var(--color-transparent); width: 100%; text-align: left; - } - .btn-lang-active{ +} +.btn-lang-active{ background: var(--bg-color); color: var(--font-color); - } - .navbar-inner-pod{ +} +.navbar-inner-pod{ position: relative; - } - .navbar-toggler{ +} +.navbar-toggler{ padding: 0.5rem; line-height: inherit; font-size: 1rem; - } +} - .userpicture { +.userpicture { height: 34px; - } +} /** modal **/ - .modal-title svg { +.modal-title svg { height: 40px; width: 40px; /*color:var(--primary);*/ - } +} - .modal-content { +.modal-content { background-color: var(--bg-color); - } +} - .modal-title{ +.modal-title{ display: flex; align-items: center; - } +} /*.modal-pod-full { max-width: 90%; - }*/ - .modal-pod-full .close{ +}*/ +.modal-pod-full.close{ font-size:3rem; - } +} - .title-chaine{ +.title-chaine{ margin-right: 0.5rem; font-weight: 600; - } - #listeChaines{ +} +#listeChaines{ max-height: 30rem; overflow: auto; border-bottom: 1px solid var(--color-black); - } - .liste-collapse{ +} +.liste-collapse{ z-index: 900; - } +} /**end modal **/ /*** tab **/ - .tab-content>.active{ +.tab-content>.active{ border: 1px solid var(--color-alto); padding: 1.5rem; background: var(--bg-color); - } - .nav-tabs{ +} +.nav-tabs{ border: 0; - } +} - .dropdown-menu { +.dropdown-menu { background-color: var(--bg-color); color: var(--font-color); border: 1px solid var(--color-silver-chalice); - } +} /***aside ***/ - .open-aside{ +.open-aside{ margin-right: 15px; - } - #card-takenote .dropdown-menu{ +} +#card-takenote.dropdown-menu{ border: none; - } +} /*** modif taille logo ***/ @media (max-width: 576px ){ - .navbar-brand img{ +.navbar-brand img{ height: 35px; - } - .navbar-brand{ +} +.navbar-brand{ font-size: 0.9rem; - } - } +} +} @media (max-width: 992px){ - .langs{ +.langs{ border-top: 1px solid var(--color-silver); - } - .langs .active{ +} +.langs.active{ /*background:var(--primary); */ border: none; color: var(--white); - } - .btn-connexion{ +} +.btn-connexion{ font-size: 0.9rem; - } - .navbar-items-pod{ +} +.navbar-items-pod{ position: absolute; top:53px; left:0; padding: 1rem; width: 100%; - } - .navbar-nav .login .dropdown-menu { +} +.navbar-nav.login.dropdown-menu { position: absolute; float: left; - } - #s::-webkit-input-placeholder { /* Chrome/Opera/Safari */ +} +#s::-webkit-input-placeholder { /* Chrome/Opera/Safari */ color: var(--white); - } - #s::-moz-placeholder { /* Firefox 19+ */ +} +#s::-moz-placeholder { /* Firefox 19+ */ color: var(--white); - } - #s:-ms-input-placeholder { /* IE 10+ */ +} +#s:-ms-input-placeholder { /* IE 10+ */ color: var(--white); - } - #s:-moz-placeholder { /* Firefox 18- */ +} +#s:-moz-placeholder { /* Firefox 18- */ color: var(--white); - } - #s{ +} +#s{ width:1px; border-radius:0; box-shadow:none; @@ -449,8 +297,8 @@ src: url("https://cdn.jsdelivr.net/npm/open-dyslexic@1.0.3/woff/OpenDyslexic-Reg background-color: var(--color-transparent); opacity:0; position: absolute; - } - #s:focus{ +} +#s:focus{ width:100%; opacity:1; display: inline-block !important; @@ -462,8 +310,8 @@ src: url("https://cdn.jsdelivr.net/npm/open-dyslexic@1.0.3/woff/OpenDyslexic-Reg z-index: 99; color:var(--white) !important; height: 74px; - } - .navbar label{ +} +.navbar label{ padding-left: 1px; display:inline-block; margin-top:0.3em; @@ -472,85 +320,85 @@ src: url("https://cdn.jsdelivr.net/npm/open-dyslexic@1.0.3/woff/OpenDyslexic-Reg position: relative; left:0.1em; cursor:pointer; - } +} - } +} /*** end MQueries **/ - .login > .initials{ +.login >.initials{ border-radius: 50%; /*background: var(--light);*/ color: var(--white) !important; font-weight: 600; height: 3rem; width: 3rem; - } - .nav-link{ +} +.nav-link{ padding: 0.25rem 0.5rem; - } +} button.nav-link{ background: none; border: none; cursor: pointer; - } +} /*** CARD ***/ - .infinite-item .card-body { +.infinite-item.card-body { padding: 0.9rem; height: 3.5rem; overflow: hidden; - } - .infinite-item .card-header .octicon { +} +.infinite-item.card-header.octicon { height:0.9rem; margin:0.1rem; - } +} - #videos_list .card-header, .playlist-videos .card-header { +#videos_list.card-header,.playlist-videos.card-header { position:absolute; width:100%; background: var(--color-black-alpha); padding: 0 0.25rem; z-index: 9; - } - #videos_list .card-header .text-muted { +} +#videos_list.card-header.text-muted { color:var(--white) !important; - } +} - #videos_list .video-title{ +#videos_list.video-title{ line-height: 1.2; display: inline-block; - } +} - div.video-card .d-flex { + div.video-card.d-flex { min-height:70%; /*position:relative;*/ top:0; - } +} a:hover { color: var(--primary); - } +} div.card a{ overflow:hidden; - } +} div.card a img { - transition:-webkit-transform .5s ease; - transition:transform .5s ease; - transition:transform .5s ease, -webkit-transform .5s ease - } +transition: -webkit-transform.5s ease; +transition: transform.5s ease; +transition: transform.5s ease, -webkit-transform.5s ease +} div.card a:hover>img { -webkit-transform:scale(1.1); transform:scale(1.1); z-index:0; - } +} - .card { +.card { background-color: var(--bg-color); border-color: var(--color-silver-chalice); - } +} - .card-footer-pod { +.card-footer-pod { position: absolute; bottom: 57px; right: 2px; @@ -559,25 +407,25 @@ src: url("https://cdn.jsdelivr.net/npm/open-dyslexic@1.0.3/woff/OpenDyslexic-Reg border:none; /*background: rgba(220,220,220);*/ /*height: 1rem;*/ - } - .card-footer .feather, .card-header .feather{ +} +.card-footer.feather,.card-header.feather{ height: 1rem; - } +} /* menu channels */ - .dropdown-submenu > .dropdown-menu { +.dropdown-submenu >.dropdown-menu { top: 0; left: 100%; margin-top: -6px; margin-left: -1px; border-radius: 0 6px 6px 6px; - } - .dropdown-submenu:hover { +} +.dropdown-submenu:hover { background-color: var(--white); - } - .dropdown-submenu:hover > .dropdown-menu { +} +.dropdown-submenu:hover >.dropdown-menu { display: block; - } - .dropdown-submenu > a:after { +} +.dropdown-submenu > a:after { display: block; content: " "; float: right; @@ -589,128 +437,128 @@ src: url("https://cdn.jsdelivr.net/npm/open-dyslexic@1.0.3/woff/OpenDyslexic-Reg border-left-color: var(--color-silver); margin-top: 5px; margin-right: -10px; - } +} /** aside list video **/ - #filterType div.collapse:not(.show), #filterDiscipline div.collapse:not(.show), #filterTag div.collapse:not(.show) { +#filterType div.collapse:not(.show),#filterDiscipline div.collapse:not(.show),#filterTag div.collapse:not(.show) { height: 148px !important; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; - } +} - #filterType div.collapsing, #filterDiscipline div.collapsing, #filterTag div.collapsing{ +#filterType div.collapsing,#filterDiscipline div.collapsing,#filterTag div.collapsing{ min-height: 148px !important; - } +} - #filterType a.collapsed:after, #filterDiscipline a.collapsed:after, #filterTag a.collapsed:after { +#filterTypea.collapsed:after,#filterDisciplinea.collapsed:after,#filterTaga.collapsed:after { content: '+'; - } +} - #filterType a:not(.collapsed):after, #filterDiscipline a:not(.collapsed):after, #filterTag a:not(.collapsed):after { +#filterType a:not(.collapsed):after,#filterDiscipline a:not(.collapsed):after,#filterTag a:not(.collapsed):after { content: '-'; - } +} /** ckeditor **/ - .django-ckeditor-widget { +.django-ckeditor-widget { width: 100%; - } +} /** video form **/ - .required { +.required { color:var(--primary); font-size: 1.3rem; - } +} /*.form-group-required { border-left: 3px solid var(--color-fuzzy-wuzzy-brown); padding-left : 5px; - }*/ - .form-group-required .errors { +}*/ +.form-group-required.errors { background-color: var(--color-fuzzy-wuzzy-brown); - } - #base-message-alert, #formalertdiv{ +} +#base-message-alert,#formalertdiv{ position:fixed; top:50%; text-align: center; margin:0 auto; left: 50%; - transform: translate(-50%, 0); +transform:translate(-50%, 0); z-index:1000; - } +} /** channel form **/ - #channel_form .selector, #enrichment_group_form .selector{ +#channel_form.selector,#enrichment_group_form.selector{ width: 100% !important; - } - #channel_form .selector select, #enrichment_group_form .selector select { +} +#channel_form.selector select,#enrichment_group_form.selector select { width:100% !important; - } - #channel_form .selector-available, #channel_form .selector-chosen, #enrichment_group_form .selector-available, #enrichment_group_form .selector-chosen { +} +#channel_form.selector-available,#channel_form.selector-chosen,#enrichment_group_form.selector-available,#enrichment_group_form.selector-chosen { width: 47% !important; - } - #channel_form .selector-available h2, #channel_form .selector-chosen h2, #enrichment_group_form .selector-available h2, #enrichment_group_form .selector-chosen h2 { +} +#channel_form.selector-available h2,#channel_form.selector-chosen h2,#enrichment_group_form.selector-available h2,#enrichment_group_form.selector-chosen h2 { margin: 0; padding: 8px; font-weight: 400; font-size: 13px; text-align: left; - } +} /* vignettes video */ @media (max-width: 575.98px) { - .pod-flex-direction{ +.pod-flex-direction{ flex-direction: column; - } - } +} +} @media screen and (min-width:768px){ - .card-img-top { +.card-img-top { max-height:184.13px; - } - } +} +} @media screen and (min-width:992px){ - .card-img-top { +.card-img-top { max-height:195.36px; - } - .flex-2{ +} +.flex-2{ flex: 2; - } - } +} +} /*** footer **/ footer{ color:var(--color-silver-chalice); - } +} footer a, footer a:hover{ color: var(--white); - } +} - .footer_links{ +.footer_links{ list-style:none; - } - .footer_links>li:before{ +} +.footer_links>li:before{ margin-right:.5em; content: ">"; font-weight: bold; - } +} - .top_link:before{ +.top_link:before{ content: "\21E7"; padding-right: 4px; text-decoration: none; display: inline-block; font-size: 1.2em; - } +} /*** Useful for additional owners ***/ input.select2-input{ width: 100% !important; - } +} - #view-counter-icon{ +#view-counter-icon{ color: var(--primary); - } +} - #viewers-list { +#viewers-list { position: absolute; right: 0; margin-right: 80px; @@ -722,134 +570,17 @@ src: url("https://cdn.jsdelivr.net/npm/open-dyslexic@1.0.3/woff/OpenDyslexic-Reg z-index: 2147483647; bottom: 100px; display: none; - } +} - .live-video { +.live-video { z-index: 1; - } - - #viewers-ul{height:200px;list-style-type: none;padding-left: 0; } - #viewers-ul{overflow:hidden; overflow-y:scroll;} - -/*** DARK MODE SWITCH ***/ -.theme-switch-wrapper { - display: flex; - align-items: center; -} -.theme-switch-wrapper em { - margin-left: 10px; - font-size: 1rem; -} -.theme-switch { - display: inline-block; - height: 24px; - position: relative; - width: 50px; - top:7px; -} -.theme-switch input { - display: none; -} -.slider { - background-color: var(--color-silver-chalice); - bottom: 0; - cursor: pointer; - left: 0; - position: absolute; - right: 0; - top: 0; - transition: 0.4s; - border-radius: 24px; -} -.slider:before { - background-color: var(--white); - bottom: 2px; - content: ""; - height: 20px; - left: 2px; - position: absolute; - transition: 0.4s; - width: 20px; - border-radius: 50%; -} -input:checked + .slider { - background-color: var(--primary); -} -input:checked + .slider:before { - transform: translateX(26px); -} -.slider svg { - color: var(--color-mine-shaft); - width: 15px; - position: absolute; - transition: opacity 0.2s ease 0s, transform 0.35s ease 0s; - pointer-events: none; -} -.feather-moon { - opacity: 0; - left: 5px; - bottom: 0px; - color: var(--white) !important; - transform: translateX(4px); -} -.feather-sun { - opacity: 1; - right: 5px; - bottom: 0px; - transform: translateX(0px); -} -input:checked + .slider .feather-moon { - opacity: 1; - transform: translateX(0); -} -input:checked + .slider .feather-sun { - opacity: 0; - transform: translateX(-4px); -} - -/* DYSLEXIA SWITCH */ -.dyslexia-switch-wrapper { - display: flex; - align-items: center; -} -.dyslexia-switch-wrapper em { - margin-left: 10px; - font-size: 1rem; -} -.dyslexia-switch { - display: inline-block; - height: 24px; - position: relative; - width: 50px; - top:7px; -} -.dyslexia-switch input { - display: none; -} - -.feather-eye { - opacity: 0; - left: 5px; - bottom: 0px; - color: var(--white) !important; - transform: translateX(4px); -} -.feather-eye-off { - opacity: 1; - right: 5px; - bottom: 0px; - transform: translateX(0px); -} -input:checked + .slider .feather-eye { - opacity: 1; - transform: translateX(0); -} -input:checked + .slider .feather-eye-off { - opacity: 0; - transform: translateX(-4px); } + +#viewers-ul{height:200px;list-style-type: none;padding-left: 0;} +#viewers-ul{overflow:hidden; overflow-y:scroll;} + /* use to hide valid human chekbox in contact form to prevent spam */ -#contact_us .valid_human { +#contact_us.valid_human { display: block; overflow: hidden; position:absolute !important; From 81e2c30e11715684e1db96343f39e2da3200ca19 Mon Sep 17 00:00:00 2001 From: Eliam LOTONGA Date: Thu, 11 Mar 2021 14:37:46 +0100 Subject: [PATCH 088/261] Conditional link dark and dyslexia css files --- pod/main/templates/base.html | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pod/main/templates/base.html b/pod/main/templates/base.html index 0b0e49a967..0de3704318 100644 --- a/pod/main/templates/base.html +++ b/pod/main/templates/base.html @@ -29,6 +29,12 @@ {% endif %} + {% if DARKMODE_ENABLED == True %} + + {% endif %} + {% if DYSLEXIAMODE_ENABLED == True %} + + {% endif %} {% if CSS_OVERRIDE %} {% endif %} From 05a93d0643720a0a86e4ac2bd2be25220a25b2ae Mon Sep 17 00:00:00 2001 From: Olivier Bado Date: Thu, 11 Mar 2021 15:44:04 +0100 Subject: [PATCH 089/261] [CSS] imrpove accessibility of new dark mode feature --- pod/main/static/css/dark.css | 269 ++++++----- pod/main/static/css/dyslexia.css | 60 +-- pod/main/static/css/pod.css | 800 ++++++++++++++++--------------- 3 files changed, 577 insertions(+), 552 deletions(-) diff --git a/pod/main/static/css/dark.css b/pod/main/static/css/dark.css index ab45188412..38c7efc8c7 100644 --- a/pod/main/static/css/dark.css +++ b/pod/main/static/css/dark.css @@ -1,64 +1,78 @@ - + [data-theme="light"] { - /* CUSTOM COLORS */ - --bg-color: #FFF; - --font-color: #222; - /* BOOTSTRAP COLORS */ - --primary: #b03c7e; - --primary2: #b03c7e; - --light: #f8f9fa; - --dark: #343a40; - --color-formfields: #f1f1f1; + /* CUSTOM COLORS */ + --bg-color: #FFF; + --font-color: #222; + /* BOOTSTRAP COLORS */ + --primary: #b03c7e; + --primary2: #b03c7e; + --light: #f8f9fa; + --dark: #343a40; + --color-formfields: #f1f1f1; } [data-theme="dark"] { - /* CUSTOM COLORS */ - --color-shark: #212529; - --bg-color: #343a40; - --font-color: #f8f9fa; - /* BOOTSTRAP COLORS */ - --primary: #b03c7e; - --primary2: #b03c7e; - --light: #393f46; - --dark: #f8f9fa; - --color-formfields: #454c52; -} -[data-theme="dark"] { - --background-color: #1e1e2c; - /* CUSTOM COLORS */ - --link-color: #fdb6de; - --color-shark: #212529; - --bg-color: #303238; - --font-color: #f8f9fa; - /* BOOTSTRAP COLORS */ - --primary: #b03c7e; - --primary2: var(--primary); - --light: var(--dark); - --dark: #202025; - --gray: var(--dark); - --color-formfields: #454c52; - --color-silver-chalice: #000; - --color-alto: var(--bg-color); - /* Video Comment variable */ - --primary-background-color: var(--bg-color) !important; - --third-background-color: var(--bg-color) !important; - --content-primary-color: var(--font-color) !important; - -} -[data-theme="dark"] a{ - color: var(--link-color); -} + --background-color: #1e1e2c; + /* CUSTOM COLORS */ + --link-color: #fdb6de; + --activelink-color: #fbdfef; + --color-shark: #212529; + --bg-color: #303238; + --font-color: #f8f9fa; + /* BOOTSTRAP COLORS */ + --primary: #b03c7e; + --primary2: var(--primary); + --light: var(--dark); + --dark: #202025; + --gray-dark: var(--dark); + --color-formfields: #454c52; + --color-silver-chalice: #000; + --color-alto: var(--bg-color); + /* Video Comment variable */ + --primary-background-color: var(--bg-color) !important; + --third-background-color: var(--bg-color) !important; + --content-primary-color: var(--font-color) !important; +} + +[data-theme="dark"] a, +[data-theme="dark"] .navbar-light .navbar-nav .nav-link{ + color: var(--link-color); +} +[data-theme="dark"] .navbar-light .navbar-nav .nav-link:focus, +[data-theme="dark"] .navbar-light .navbar-nav .nav-link:hover{ + color: var(--activelink-color); +} + +[data-theme="dark"] .form-control::placeholder{ + color: #BEC1C6; +} + +[data-theme="dark"] .breadcrumb-item + .breadcrumb-item::before{ + color:var(--white); +} +[data-theme="dark"] .breadcrumb-item.active{ + color:#A8ABB3; +} + +[data-theme="dark"] .nav-tabs .nav-item.show .nav-link, +[data-theme="dark"] .nav-tabs .nav-link.active{ + background-color: var(--bg-color); + color:var(--white); + border-bottom: none; +} + + [data-theme="dark"] .btn, [data-theme="dark"] .dropdown-item, [data-theme="dark"] footer{ - color: var(--font-color); + color: var(--font-color); } [data-theme="dark"] .btn:hover{ - color: inherit; + color: inherit; } [data-theme="dark"] .btn.btn-light{ - background-color: var(--dark); - border-color: var(--dark); - color: var(--primary); + background-color: var(--dark); + border-color: var(--dark); + color: var(--primary); } [data-theme="dark"] .btn-primary.focus, [data-theme="dark"] .btn-outline-primary:focus, @@ -73,30 +87,33 @@ [data-theme] .badge-primary, [data-theme="dark"] .btn-primary { - background: var(--primary); - border-color: var(--primary); - box-shadow: none; - color: var(--font-color); + background: var(--primary); + border-color: var(--primary); + box-shadow: none; + color: var(--font-color); } - +[data-theme="dark"] .btn-secondary{ + color: var(--white); +} + [data-theme="dark"] .card{ - background-color: var(--dark); - border-color: var(--dark); + background-color: var(--dark); + border-color: var(--dark); } - + body.dark { - background-color: var(--background-color) !important; + background-color: var(--background-color) !important; } - + /* Video Comment override css dark mode */ [data-theme="dark"] .comment_main .comment .comment_content { - box-shadow: 2px 2px 12px var(--dark); + box-shadow: 2px 2px 12px var(--dark); } [data-theme="dark"] .comment_main .add_comment .add_comment_btn{ - box-shadow: 4px 8px var(--bg-color); + box-shadow: 4px 8px var(--bg-color); } - + /* Modal override css dark mode */ [data-theme="dark"] .comment_main .comment .comment_content_footer .add_comment, /* comment text-area wrapper */ [data-theme="dark"] .comment_main .add_comment .form-wrapper .new_comment.new_parent_comment, /* comment text-area */ @@ -105,24 +122,27 @@ body.dark { [data-theme="dark"] #podfile .list_folders .folder_container:nth-child(2n), [data-theme="dark"] #podfile .list_folders_sub .folder_container:nth-child(2n), [data-theme="dark"] .modal-content{ - background-color: var(--dark) !important; - border-color: var(--dark) !important; - color: #fff !important; + background-color: var(--dark) !important; + border-color: var(--dark) !important; + color: #fff !important; +} +[data-theme="dark"] .close{ + color: #fff; } [data-theme="dark"] #podfile #dirs .folder-search::placeholder{ - color: #ccc; + color: #ccc; } [data-theme="dark"] #podfile .col{ - background-color: var(--bg-color); + background-color: var(--bg-color); } [data-theme="dark"] .list-group-item-action:focus, .list-group-item-action:hover { - background-color: var(--dark); + background-color: var(--dark); } - + /* INPUT TEXT-AREA SELECT dark mode */ [data-theme="dark"] select, -[data-theme="dark"] input:not(.btn-lang), +[data-theme="dark"] input:not(.btn-lang), [data-theme="dark"] text-area, [data-theme="dark"] .select2-container, [data-theme="dark"] .select2-container-multi .select2-choices .select2-search-field input, @@ -134,83 +154,82 @@ body.dark { [data-theme="dark"] .select2-results .select2-no-results, [data-theme="dark"] .select2-results .select2-searching { - background: var(--bg-color) !important; - border-color: var(--bg-color) !important; - color: var(--font-color) !important; - box-shadow: none !important; + background: var(--bg-color) !important; + border-color: var(--bg-color) !important; + color: var(--font-color) !important; + box-shadow: none !important; } .theme-switch-wrapper { - display: flex; - align-items: center; + display: flex; + align-items: center; } .theme-switch-wrapper em { - margin-left: 10px; - font-size: 1rem; + margin-left: 10px; + font-size: 1rem; } .theme-switch { - display: inline-block; - height: 24px; - position: relative; - width: 50px; - top:7px; + display: inline-block; + height: 24px; + position: relative; + width: 50px; + top:7px; } .theme-switch input { - display: none; + display: none; } .slider { - background-color: var(--color-silver-chalice); - bottom: 0; - cursor: pointer; - left: 0; - position: absolute; - right: 0; - top: 0; - transition: 0.4s; - border-radius: 24px; + background-color: var(--color-silver-chalice); + bottom: 0; + cursor: pointer; + left: 0; + position: absolute; + right: 0; + top: 0; + transition: 0.4s; + border-radius: 24px; } .slider:before { - background-color: var(--white); - bottom: 2px; - content: ""; - height: 20px; - left: 2px; - position: absolute; - transition: 0.4s; - width: 20px; - border-radius: 50%; + background-color: var(--white); + bottom: 2px; + content: ""; + height: 20px; + left: 2px; + position: absolute; + transition: 0.4s; + width: 20px; + border-radius: 50%; } input:checked + .slider { - background-color: var(--primary); + background-color: var(--primary); } input:checked + .slider:before { - transform: translateX(26px); + transform: translateX(26px); } .slider svg { - color: var(--color-mine-shaft); - width: 15px; - position: absolute; - transition: opacity 0.2s ease 0s, transform 0.35s ease 0s; - pointer-events: none; + color: var(--color-mine-shaft); + width: 15px; + position: absolute; + transition: opacity 0.2s ease 0s, transform 0.35s ease 0s; + pointer-events: none; } .feather-moon { - opacity: 0; - left: 5px; - bottom: 0px; - color: var(--white) !important; - transform: translateX(4px); + opacity: 0; + left: 5px; + bottom: 0px; + color: var(--white) !important; + transform: translateX(4px); } .feather-sun { - opacity: 1; - right: 5px; - bottom: 0px; - transform: translateX(0px); + opacity: 1; + right: 5px; + bottom: 0px; + transform: translateX(0px); } input:checked + .slider .feather-moon { - opacity: 1; - transform: translateX(0); + opacity: 1; + transform: translateX(0); } input:checked + .slider .feather-sun { - opacity: 0; - transform: translateX(-4px); + opacity: 0; + transform: translateX(-4px); } - \ No newline at end of file diff --git a/pod/main/static/css/dyslexia.css b/pod/main/static/css/dyslexia.css index 3139387fbd..b102433e06 100644 --- a/pod/main/static/css/dyslexia.css +++ b/pod/main/static/css/dyslexia.css @@ -1,50 +1,50 @@ /* OpenDyslexic Font via CDN */ @font-face { - font-family: "Open Dyslexic"; - src: url("https://cdn.jsdelivr.net/npm/open-dyslexic@1.0.3/woff/OpenDyslexic-Regular.woff") format("woff"); - } + font-family: "Open Dyslexic"; + src: url("https://cdn.jsdelivr.net/npm/open-dyslexic@1.0.3/woff/OpenDyslexic-Regular.woff") format("woff"); +} [data-dyslexia="on"] { - --font-family-sans-serif: "Open Dyslexic"; + --font-family-sans-serif: "Open Dyslexic"; } .dyslexia-switch-wrapper { - display: flex; - align-items: center; + display: flex; + align-items: center; } .dyslexia-switch-wrapper em { - margin-left: 10px; - font-size: 1rem; + margin-left: 10px; + font-size: 1rem; } .dyslexia-switch { - display: inline-block; - height: 24px; - position: relative; - width: 50px; - top:7px; + display: inline-block; + height: 24px; + position: relative; + width: 50px; + top: 7px; } .dyslexia-switch input { - display: none; + display: none; } - + .feather-eye { - opacity: 0; - left: 5px; - bottom: 0px; - color: var(--white) !important; - transform: translateX(4px); + opacity: 0; + left: 5px; + bottom: 0; + color: var(--white) !important; + transform: translateX(4px); } .feather-eye-off { - opacity: 1; - right: 5px; - bottom: 0px; - transform: translateX(0px); + opacity: 1; + right: 5px; + bottom: 0; + transform: translateX(0px); } - input:checked + .slider .feather-eye { - opacity: 1; - transform: translateX(0); +input:checked + .slider .feather-eye { + opacity: 1; + transform: translateX(0); } input:checked + .slider .feather-eye-off { - opacity: 0; - transform: translateX(-4px); -} \ No newline at end of file + opacity: 0; + transform: translateX(-4px); +} diff --git a/pod/main/static/css/pod.css b/pod/main/static/css/pod.css index 4c18c9f5ce..b88e9a8038 100755 --- a/pod/main/static/css/pod.css +++ b/pod/main/static/css/pod.css @@ -12,582 +12,588 @@ src: url("https://cdn.jsdelivr.net/npm/open-dyslexic@1.0.3/woff/OpenDyslexic-Reg --color-black: black; --color-alto:#ddd; --color-sisal: rgba(218,208,190,1); - --color-black-alpha: rgba(0, 0, 0, 0.6); + --color-black-alpha: rgba(0, 0, 0, .6); --color-silver:#ccc; - --color-fuzzy-wuzzy-brown: rgba(201, 76, 76, 0.3); + --color-fuzzy-wuzzy-brown: rgba(201, 76, 76, .3); --color-silver-chalice:#aaa; - --color-outer-space: rgba(40,48,56, 0.5); + --color-outer-space: rgba(40,48,56, .5); --color-red:#FF0000; --color-mine-shaft:#222; } .navbar-light.navbar-nav.nav-link { - color: var(--font-color); + color: var(--font-color); } .navbar-light.navbar-nav.nav-link:focus,.navbar-light.navbar-nav.nav-link:hover { - color: var(--primary); + color: var(--primary); } .navbar-brand { - color: var(--font-color) !important; + color: var(--font-color) !important; } .nav-link-icone { - color: var(--primary); + color: var(--primary); } .btn-primary { - /* color: var(--font-color); */ - background-color: var(--primary); - border-color: var(--primary); + /* color: var(--font-color); */ + background-color: var(--primary); + border-color: var(--primary); } - + .modal-title svg { - color: var(--primary)!important; + color: var(--primary)!important; } - + .bg-light { - background-color: var(--light)!important; + background-color: var(--light)!important; } - + .bg-dark { - background-color: var(--gray)!important; + background-color: var(--gray-dark); } - + .nav-tabs.nav-item.show.nav-link,.nav-tabs.nav-link.active { - color: var(--color-white); - background-color: var(--primary); - border-color: var(--color-alto) var(--color-alto) var(--color-alto); + color: var(--color-white); + background-color: var(--primary); + border-color: var(--color-alto) var(--color-alto) var(--color-alto); +} + +.tab-title{ + font-size: 1.5rem; } - +.meta-title{ + font-size: 1.2rem; +} + .btn-link { - font-weight: 400; - color: var(--primary); - text-decoration: none; + font-weight: 400; + color: var(--primary); + text-decoration: none; } - + .btn-outline-primary { - color: var(--primary); - border-color: var(--primary); + color: var(--primary); + border-color: var(--primary); } - + a.btn-outline-primary svg { - fill: var(--primary); + fill: var(--primary); } - + #formfields.btn { - color: var(--font-color); - background-color: var(--color-formfields); + color: var(--font-color); + background-color: var(--color-formfields); } - + .card-footer-pod.btn { color: var(--font-color); } - + .card-footer-pod.btn-light { - color: var(--font-color); - background-color: var(--light); - border-color: var(--color-alto); + color: var(--font-color); + background-color: var(--light); + border-color: var(--color-alto); } - + .submit-rowa.deletelink { - height: 35px; + height: 35px; } - + .select2-container{ - position: static !important; - height:auto; + position: static !important; + height:auto; } - -tr ,.rowl{ - display: table-row !important; + +tr,.rowl{ + display: table-row !important; } - -body[data-admin-utc-offset] - { - padding-top: 0; + +body[data-admin-utc-offset]{ + padding-top: 0; } - + body { - padding-top: 3.5rem; - color: var(--font-color); - background-color: var(--bg-color); + padding-top: 3.5rem; + color: var(--font-color); + background-color: var(--bg-color); } .jumbotron { - padding: 1rem 2rem; + padding: 1rem 2rem; } h1{ - font-size: 2rem; + font-size: 2rem; } - label { - font-variant: small-caps; +label { + font-variant: small-caps; } .pod-mt-7{ - margin-top: 3.5rem; + margin-top: 3.5rem; } .breadcrumb,.jumbotron{ - background: var(--light); + background: var(--light); } .list-group-item{ - background: var(--bg-color); - padding:.25rem 1.25rem; + background: var(--bg-color); + padding:.25rem 1.25rem; } - + .container-pod{ - max-width: 1400px; + max-width: 1400px; } - + /*** video ***/ #myTabContent#info p { - margin-top:.5rem; - margin-bottom:.5rem; + margin-top:.5rem; + margin-bottom:.5rem; } #share legend{ - /* align text with feather-icon */ - line-height: 1em; + /* align text with feather-icon */ + line-height: 1em; } - + .hidespinner { - display: none; + display: none; } - + .link-center-pod { - margin-left: auto; - margin-right: auto; -} - - /*** navbar **/ - /*.nav-link.btn-connexion{ - background: var(--primary); - color: var(--white).btn-outline-primary { - color:#b03c7e; - border-color:#b03c7e; -}!important; + margin-left: auto; + margin-right: auto; +} + +/*** navbar **/ +/*.nav-link.btn-connexion{ + background: var(--primary); + color: var(--white).btn-outline-primary { + color:#b03c7e; + border-color:#b03c7e; + }!important; }*/ .btn-lang{ - padding: 0.2rem 0.25rem; - background: var(--color-transparent); - width: 100%; - text-align: left; + padding: 0.2rem 0.25rem; + background: var(--color-transparent); + width: 100%; + text-align: left; } .btn-lang-active{ - background: var(--bg-color); - color: var(--font-color); + background: var(--bg-color); + color: var(--font-color); } .navbar-inner-pod{ - position: relative; + position: relative; } .navbar-toggler{ - padding: 0.5rem; - line-height: inherit; - font-size: 1rem; + padding: 0.5rem; + line-height: inherit; + font-size: 1rem; } - + .userpicture { - height: 34px; + height: 34px; } - - /** modal **/ + +/** modal **/ .modal-title svg { - height: 40px; - width: 40px; - /*color:var(--primary);*/ + height: 40px; + width: 40px; + /*color:var(--primary);*/ } - + .modal-content { - background-color: var(--bg-color); + background-color: var(--bg-color); } - + .modal-title{ - display: flex; - align-items: center; + display: flex; + align-items: center; } - - /*.modal-pod-full { - max-width: 90%; + +/*.modal-pod-full { + max-width: 90%; }*/ .modal-pod-full.close{ - font-size:3rem; + font-size:3rem; } - + .title-chaine{ - margin-right: 0.5rem; - font-weight: 600; + margin-right: 0.5rem; + font-weight: 600; } #listeChaines{ - max-height: 30rem; - overflow: auto; - border-bottom: 1px solid var(--color-black); + max-height: 30rem; + overflow: auto; + border-bottom: 1px solid var(--color-black); } .liste-collapse{ - z-index: 900; + z-index: 900; } - /**end modal **/ - /*** tab **/ +/**end modal **/ +/*** tab **/ .tab-content>.active{ - border: 1px solid var(--color-alto); - padding: 1.5rem; - background: var(--bg-color); + border: 1px solid var(--color-alto); + padding: 1.5rem; + background: var(--bg-color); } .nav-tabs{ - border: 0; + border: 0; } - + .dropdown-menu { - background-color: var(--bg-color); - color: var(--font-color); - border: 1px solid var(--color-silver-chalice); + background-color: var(--bg-color); + color: var(--font-color); + border: 1px solid var(--color-silver-chalice); } - - /***aside ***/ + +/***aside ***/ .open-aside{ - margin-right: 15px; + margin-right: 15px; } #card-takenote.dropdown-menu{ - border: none; + border: none; } - /*** modif taille logo ***/ - @media (max-width: 576px ){ -.navbar-brand img{ - height: 35px; -} -.navbar-brand{ - font-size: 0.9rem; -} -} - @media (max-width: 992px){ -.langs{ - border-top: 1px solid var(--color-silver); -} -.langs.active{ - /*background:var(--primary); */ - border: none; - color: var(--white); -} -.btn-connexion{ - font-size: 0.9rem; -} -.navbar-items-pod{ - position: absolute; - top:53px; - left:0; - padding: 1rem; - width: 100%; -} -.navbar-nav.login.dropdown-menu { - position: absolute; - float: left; -} -#s::-webkit-input-placeholder { /* Chrome/Opera/Safari */ - color: var(--white); -} -#s::-moz-placeholder { /* Firefox 19+ */ - color: var(--white); -} -#s:-ms-input-placeholder { /* IE 10+ */ - color: var(--white); -} -#s:-moz-placeholder { /* Firefox 18- */ - color: var(--white); -} -#s{ - width:1px; - border-radius:0; - box-shadow:none; - outline: none; - padding:0; - margin:0; - border:0; - background-color: var(--color-transparent); - opacity:0; - position: absolute; -} -#s:focus{ - width:100%; - opacity:1; - display: inline-block !important; - position: absolute; - /*background: var(--primary) !important;*/ - padding: 0.5rem 1rem; - left: 0; - top:0; - z-index: 99; - color:var(--white) !important; - height: 74px; -} -.navbar label{ - padding-left: 1px; - display:inline-block; - margin-top:0.3em; - color:var(--color-sisal); - text-shadow:0 0 0.1em var(--color-mine-shaft); - position: relative; - left:0.1em; - cursor:pointer; -} - +/*** modif taille logo ***/ +@media (max-width: 576px ){ + .navbar-brand img{ + height: 35px; + } + .navbar-brand{ + font-size: .9rem; + } +} +@media (max-width: 992px){ + .langs{ + border-top: 1px solid var(--color-silver); + } + .langs.active{ + /*background:var(--primary); */ + border: none; + color: var(--white); + } + .btn-connexion{ + font-size: .9rem; + } + .navbar-items-pod{ + position: absolute; + top:53px; + left:0; + padding: 1rem; + width: 100%; + } + .navbar-nav.login.dropdown-menu { + position: absolute; + float: left; + } + #s::-webkit-input-placeholder { /* Chrome/Opera/Safari */ + color: var(--white); + } + #s::-moz-placeholder { /* Firefox 19+ */ + color: var(--white); + } + #s:-ms-input-placeholder { /* IE 10+ */ + color: var(--white); + } + #s:-moz-placeholder { /* Firefox 18- */ + color: var(--white); + } + #s{ + width:1px; + border-radius:0; + box-shadow:none; + outline: none; + padding:0; + margin:0; + border:0; + background-color: var(--color-transparent); + opacity:0; + position: absolute; + } + #s:focus{ + width:100%; + opacity:1; + display: inline-block !important; + position: absolute; + /*background: var(--primary) !important;*/ + padding: .5rem 1rem; + left: 0; + top:0; + z-index: 99; + color:var(--white) !important; + height: 74px; + } + .navbar label{ + padding-left: 1px; + display:inline-block; + margin-top:0.3em; + color:var(--color-sisal); + text-shadow:0 0 0.1em var(--color-mine-shaft); + position: relative; + left:0.1em; + cursor:pointer; + } + } /*** end MQueries **/ - + .login >.initials{ - border-radius: 50%; - /*background: var(--light);*/ - color: var(--white) !important; - font-weight: 600; - height: 3rem; - width: 3rem; + border-radius: 50%; + /*background: var(--light);*/ + color: var(--white) !important; + font-weight: 600; + height: 3rem; + width: 3rem; } .nav-link{ - padding: 0.25rem 0.5rem; + padding: .25rem .5rem; } - button.nav-link{ - background: none; - border: none; - cursor: pointer; +button.nav-link{ + background: none; + border: none; + cursor: pointer; } - + /*** CARD ***/ .infinite-item.card-body { - padding: 0.9rem; - height: 3.5rem; - overflow: hidden; + padding: .9rem; + height: 3.5rem; + overflow: hidden; } .infinite-item.card-header.octicon { - height:0.9rem; - margin:0.1rem; + height: .9rem; + margin: .1rem; } - + #videos_list.card-header,.playlist-videos.card-header { - position:absolute; - width:100%; - background: var(--color-black-alpha); - padding: 0 0.25rem; - z-index: 9; + position:absolute; + width:100%; + background: var(--color-black-alpha); + padding: 0 .25rem; + z-index: 9; } #videos_list.card-header.text-muted { - color:var(--white) !important; + color:var(--white) !important; } - + #videos_list.video-title{ - line-height: 1.2; - display: inline-block; + line-height: 1.2; + display: inline-block; } - - div.video-card.d-flex { - min-height:70%; - /*position:relative;*/ - top:0; + +div.video-card.d-flex { + min-height:70%; + /*position:relative;*/ + top:0; } - - a:hover { - color: var(--primary); + +a:hover { + color: var(--primary); } - - div.card a{ - overflow:hidden; + +div.card a{ + overflow:hidden; } - div.card a img { -transition: -webkit-transform.5s ease; -transition: transform.5s ease; -transition: transform.5s ease, -webkit-transform.5s ease +div.card a img { + transition: -webkit-transform.5s ease; + transition: transform.5s ease; + transition: transform.5s ease, -webkit-transform.5s ease } - div.card a:hover>img { - -webkit-transform:scale(1.1); - transform:scale(1.1); - z-index:0; +div.card a:hover>img { + -webkit-transform:scale(1.1); + transform:scale(1.1); + z-index:0; } - + .card { - background-color: var(--bg-color); - border-color: var(--color-silver-chalice); + background-color: var(--bg-color); + border-color: var(--color-silver-chalice); } - + .card-footer-pod { - position: absolute; - bottom: 57px; - right: 2px; - /*width: 100%; - text-align: center;*/ - border:none; - /*background: rgba(220,220,220);*/ - /*height: 1rem;*/ + position: absolute; + bottom: 57px; + right: 2px; + /*width: 100%; + text-align: center;*/ + border:none; + /*background: rgba(220,220,220);*/ + /*height: 1rem;*/ } .card-footer.feather,.card-header.feather{ - height: 1rem; + height: 1rem; } /* menu channels */ .dropdown-submenu >.dropdown-menu { - top: 0; - left: 100%; - margin-top: -6px; - margin-left: -1px; - border-radius: 0 6px 6px 6px; + top: 0; + left: 100%; + margin-top: -6px; + margin-left: -1px; + border-radius: 0 6px 6px 6px; } .dropdown-submenu:hover { - background-color: var(--white); + background-color: var(--white); } .dropdown-submenu:hover >.dropdown-menu { - display: block; + display: block; } .dropdown-submenu > a:after { - display: block; - content: " "; - float: right; - width: 0; - height: 0; - border-color: var(--color-transparent); - border-style: solid; - border-width: 5px 0 5px 5px; - border-left-color: var(--color-silver); - margin-top: 5px; - margin-right: -10px; -} - - /** aside list video **/ + display: block; + content: " "; + float: right; + width: 0; + height: 0; + border-color: var(--color-transparent); + border-style: solid; + border-width: 5px 0 5px 5px; + border-left-color: var(--color-silver); + margin-top: 5px; + margin-right: -10px; +} + +/** aside list video **/ #filterType div.collapse:not(.show),#filterDiscipline div.collapse:not(.show),#filterTag div.collapse:not(.show) { - height: 148px !important; - overflow: hidden; - - display: -webkit-box; - -webkit-line-clamp: 2; - -webkit-box-orient: vertical; -} - + height: 148px !important; + overflow: hidden; + + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; +} + #filterType div.collapsing,#filterDiscipline div.collapsing,#filterTag div.collapsing{ - min-height: 148px !important; + min-height: 148px !important; } - + #filterTypea.collapsed:after,#filterDisciplinea.collapsed:after,#filterTaga.collapsed:after { - content: '+'; + content: '+'; } - + #filterType a:not(.collapsed):after,#filterDiscipline a:not(.collapsed):after,#filterTag a:not(.collapsed):after { - content: '-'; + content: '-'; } - /** ckeditor **/ +/** ckeditor **/ .django-ckeditor-widget { - width: 100%; + width: 100%; } - /** video form **/ +/** video form **/ .required { - color:var(--primary); - font-size: 1.3rem; + color:var(--primary); + font-size: 1.3rem; } - /*.form-group-required { - border-left: 3px solid var(--color-fuzzy-wuzzy-brown); - padding-left : 5px; +/*.form-group-required { + border-left: 3px solid var(--color-fuzzy-wuzzy-brown); + padding-left : 5px; }*/ .form-group-required.errors { - background-color: var(--color-fuzzy-wuzzy-brown); + background-color: var(--color-fuzzy-wuzzy-brown); } #base-message-alert,#formalertdiv{ - position:fixed; - top:50%; - text-align: center; - margin:0 auto; - left: 50%; -transform:translate(-50%, 0); - z-index:1000; -} - + position:fixed; + top:50%; + text-align: center; + margin:0 auto; + left: 50%; + transform:translate(-50%, 0); + z-index:1000; +} + /** channel form **/ #channel_form.selector,#enrichment_group_form.selector{ - width: 100% !important; + width: 100% !important; } #channel_form.selector select,#enrichment_group_form.selector select { - width:100% !important; + width:100% !important; } #channel_form.selector-available,#channel_form.selector-chosen,#enrichment_group_form.selector-available,#enrichment_group_form.selector-chosen { - width: 47% !important; + width: 47% !important; } #channel_form.selector-available h2,#channel_form.selector-chosen h2,#enrichment_group_form.selector-available h2,#enrichment_group_form.selector-chosen h2 { - margin: 0; - padding: 8px; - font-weight: 400; - font-size: 13px; - text-align: left; -} - - /* vignettes video */ - @media (max-width: 575.98px) { -.pod-flex-direction{ - flex-direction: column; -} -} - @media screen and (min-width:768px){ -.card-img-top { - max-height:184.13px; -} + margin: 0; + padding: 8px; + font-weight: 400; + font-size: 13px; + text-align: left; } - @media screen and (min-width:992px){ -.card-img-top { - max-height:195.36px; -} -.flex-2{ - flex: 2; -} -} - /*** footer **/ - footer{ - color:var(--color-silver-chalice); -} - footer a, footer a:hover{ - color: var(--white); + +/* vignettes video */ +@media (max-width: 575.98px) { + .pod-flex-direction{ + flex-direction: column; + } +} +@media screen and (min-width:768px){ + .card-img-top { + max-height:184.13px; + } +} +@media screen and (min-width:992px){ + .card-img-top { + max-height:195.36px; + } + .flex-2{ + flex: 2; + } +} +/*** footer **/ +footer{ + color:var(--color-silver-chalice); +} +footer a, footer a:hover{ + color: var(--white); } - + .footer_links{ - list-style:none; + list-style:none; } .footer_links>li:before{ - margin-right:.5em; - content: ">"; - font-weight: bold; + margin-right:.5em; + content: ">"; + font-weight: bold; } - + .top_link:before{ - content: "\21E7"; - padding-right: 4px; - text-decoration: none; - display: inline-block; - font-size: 1.2em; -} - - /*** Useful for additional owners ***/ - input.select2-input{ - width: 100% !important; -} - + content: "\21E7"; + padding-right: 4px; + text-decoration: none; + display: inline-block; + font-size: 1.2em; +} + +/*** Useful for additional owners ***/ +input.select2-input{ + width: 100% !important; +} + #view-counter-icon{ - color: var(--primary); + color: var(--primary); } - - + + #viewers-list { - position: absolute; - right: 0; - margin-right: 80px; - color: var(--white); - text-align: center; - font-size: 20px; - background-color: var(--color-outer-space); - padding: 10px 0; - z-index: 2147483647; - bottom: 100px; - display: none; -} - + position: absolute; + right: 0; + margin-right: 80px; + color: var(--white); + text-align: center; + font-size: 20px; + background-color: var(--color-outer-space); + padding: 10px 0; + z-index: 2147483647; + bottom: 100px; + display: none; +} + .live-video { - z-index: 1; + z-index: 1; } - + #viewers-ul{height:200px;list-style-type: none;padding-left: 0;} #viewers-ul{overflow:hidden; overflow-y:scroll;} - + /* use to hide valid human chekbox in contact form to prevent spam */ #contact_us.valid_human { display: block; overflow: hidden; - position:absolute !important; - left:0 !important; - top:0 !important; - width:1px !important; - height:1px !important; + position: absolute !important; + left: 0 !important; + top: 0 !important; + width: 1px !important; + height: 1px !important; padding: 0 !important; margin: 0 !important; } From 1b8bebb2406a31db004ac7f569547f1faafa8f34 Mon Sep 17 00:00:00 2001 From: Olivier Bado Date: Thu, 11 Mar 2021 16:07:26 +0100 Subject: [PATCH 090/261] Improve also social links --- pod/main/static/css/dark.css | 15 +++++++++++---- pod/main/static/css/pod.css | 6 +++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/pod/main/static/css/dark.css b/pod/main/static/css/dark.css index 38c7efc8c7..bc2b1bb63d 100644 --- a/pod/main/static/css/dark.css +++ b/pod/main/static/css/dark.css @@ -95,6 +95,13 @@ [data-theme="dark"] .btn-secondary{ color: var(--white); } +[data-theme="dark"] .btn-outline-primary>svg{ + color: var(--primary); +} +[data-theme="dark"] .btn-outline-primary:hover>svg, +[data-theme="dark"] .btn-outline-primary:focus>svg{ + color: var(--white); +} [data-theme="dark"] .card{ background-color: var(--dark); @@ -154,10 +161,10 @@ body.dark { [data-theme="dark"] .select2-results .select2-no-results, [data-theme="dark"] .select2-results .select2-searching { - background: var(--bg-color) !important; - border-color: var(--bg-color) !important; - color: var(--font-color) !important; - box-shadow: none !important; + background: var(--bg-color); + border-color: var(--bg-color); + color: var(--font-color); + box-shadow: none; } .theme-switch-wrapper { display: flex; diff --git a/pod/main/static/css/pod.css b/pod/main/static/css/pod.css index b88e9a8038..8c8f024c40 100755 --- a/pod/main/static/css/pod.css +++ b/pod/main/static/css/pod.css @@ -47,7 +47,7 @@ src: url("https://cdn.jsdelivr.net/npm/open-dyslexic@1.0.3/woff/OpenDyslexic-Reg } .bg-dark { - background-color: var(--gray-dark); + background-color: var(--gray-dark)!important; } .nav-tabs.nav-item.show.nav-link,.nav-tabs.nav-link.active { @@ -74,9 +74,9 @@ src: url("https://cdn.jsdelivr.net/npm/open-dyslexic@1.0.3/woff/OpenDyslexic-Reg border-color: var(--primary); } -a.btn-outline-primary svg { +/*a.btn-outline-primary svg { fill: var(--primary); -} +}*/ #formfields.btn { color: var(--font-color); From 452aaf0ea2f91e118769fe0f0fdd55661af9f963 Mon Sep 17 00:00:00 2001 From: Olivier Bado Date: Thu, 11 Mar 2021 17:25:22 +0100 Subject: [PATCH 091/261] some more accessibility changes : - change slider background color when dark - add missing text in sliders labels - replace a wrong aria-labelledby="headingOne" - remove redundants titles with same text inside link + some code formatting --- pod/custom/settings_local.py.example | 2 +- pod/locale/fr/LC_MESSAGES/django.mo | Bin 97755 -> 97850 bytes pod/locale/fr/LC_MESSAGES/django.po | 218 ++++++++++++------------ pod/locale/fr/LC_MESSAGES/djangojs.po | 34 ++-- pod/locale/nl/LC_MESSAGES/django.po | 218 ++++++++++++------------ pod/locale/nl/LC_MESSAGES/djangojs.po | 34 ++-- pod/main/static/css/pod.css | 9 +- pod/main/templates/aside.html | 30 ++-- pod/main/templates/navbar.html | 47 ++--- pod/main/templates/navbar_collapse.html | 44 ++--- pod/video/static/js/video_category.js | 2 +- pod/video/templates/videos/card.html | 114 ++++++------- 12 files changed, 386 insertions(+), 366 deletions(-) diff --git a/pod/custom/settings_local.py.example b/pod/custom/settings_local.py.example index 5eb4cb690b..1bfedc1401 100644 --- a/pod/custom/settings_local.py.example +++ b/pod/custom/settings_local.py.example @@ -1205,4 +1205,4 @@ DARKMODE_ENABLED = False """ # Activation du mode dyslexie """ -DYSLEXIAMODE_ENABLED = False \ No newline at end of file +DYSLEXIAMODE_ENABLED = False diff --git a/pod/locale/fr/LC_MESSAGES/django.mo b/pod/locale/fr/LC_MESSAGES/django.mo index 66dd397a1b10085eee2cba2eafa69f53ba6597a2..39ce792890d5139919664a313007d54b64a99105 100644 GIT binary patch delta 24521 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 diff --git a/pod/locale/fr/LC_MESSAGES/django.po b/pod/locale/fr/LC_MESSAGES/django.po index 56630edabb..a4235db9a0 100755 --- 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: 2021-03-10 11:14+0000\n" +"POT-Creation-Date: 2021-03-11 16:17+0000\n" "PO-Revision-Date: \n" "Last-Translator: obado \n" "Language-Team: \n" @@ -26,7 +26,7 @@ msgid "Establishment" msgstr "Etablissement" #: pod/authentication/forms.py:60 pod/authentication/forms.py:61 -#: pod/bbb/models.py:141 pod/main/templates/navbar.html:22 +#: pod/bbb/models.py:141 pod/main/templates/navbar.html:23 #: pod/main/templates/navbar_collapse.html:76 pod/podfile/models.py:37 #: pod/video/forms.py:236 pod/video/forms.py:589 pod/video/forms.py:593 #: pod/video/models.py:253 pod/video/templates/videos/filter_aside.html:13 @@ -90,7 +90,7 @@ msgid "registered-reader" msgstr "lecteur enregistré" #: pod/authentication/models.py:68 pod/recorder/models.py:266 -#: pod/video/models.py:1465 pod/video/models.py:1517 pod/video/views.py:1303 +#: pod/video/models.py:1472 pod/video/models.py:1524 pod/video/views.py:1303 msgid "Comment" msgstr "Commentaire" @@ -114,7 +114,7 @@ msgstr "Authentification locale" #: pod/authentication/templates/registration/login.html:9 #: pod/authentication/templates/registration/login.html:12 #: pod/authentication/templates/registration/login.html:63 -#: pod/main/templates/navbar.html:117 +#: pod/main/templates/navbar.html:118 msgid "Log in" msgstr "Connexion" @@ -140,17 +140,17 @@ msgid "Forgotten your password or username?" msgstr "Mot de passe ou identifiant perdu ?" #: pod/authentication/templates/userpicture/userpicture.html:7 -#: pod/main/templates/navbar.html:88 +#: pod/main/templates/navbar.html:89 msgid "Change your picture" msgstr "Changer votre image de profil" #: pod/authentication/templates/userpicture/userpicture.html:29 -#: pod/authentication/views.py:98 pod/bbb/templates/bbb/publish_meeting.html:38 +#: pod/authentication/views.py:98 pod/bbb/templates/bbb/publish_meeting.html:37 #: pod/bbb/views.py:110 pod/completion/templates/video_caption_maker.html:57 #: pod/enrichment/templates/enrichment/group_enrichment.html:29 #: pod/interactive/templates/interactive/group_interactive.html:29 #: pod/live/templates/live/live-form.html:10 -#: pod/main/templates/contact_us.html:24 pod/main/views.py:259 +#: pod/main/templates/contact_us.html:20 pod/main/views.py:260 #: pod/playlist/views.py:140 #: pod/recorder/templates/recorder/add_recording.html:36 #: pod/recorder/templates/recorder/record_delete.html:32 @@ -170,12 +170,12 @@ msgid "One or more errors have been found in the form." msgstr "Une ou plusieurs erreurs ont été trouvées dans le formulaire." #: pod/authentication/templates/userpicture/userpicture.html:42 -#: pod/bbb/templates/bbb/publish_meeting.html:66 +#: pod/bbb/templates/bbb/publish_meeting.html:65 #: pod/completion/templates/video_caption_maker.html:69 #: pod/enrichment/templates/enrichment/group_enrichment.html:51 #: pod/interactive/templates/interactive/group_interactive.html:51 #: pod/live/templates/live/live-form.html:25 -#: pod/main/templates/contact_us.html:47 +#: pod/main/templates/contact_us.html:43 #: pod/recorder/templates/recorder/add_recording.html:59 #: pod/recorder/templates/recorder/record_delete.html:54 #: pod/video/templates/channel/channel_edit.html:70 @@ -191,7 +191,7 @@ msgid "Please provide a valid value for this field" msgstr "Veuillez renseigner une valeur valide pour ce champ" #: pod/authentication/templates/userpicture/userpicture.html:56 -#: pod/bbb/templates/bbb/list_meeting.html:44 pod/main/templates/base.html:113 +#: pod/bbb/templates/bbb/list_meeting.html:44 pod/main/templates/base.html:117 #: pod/main/templates/navbar_collapse.html:43 #: pod/main/templates/navbar_collapse.html:66 #: pod/main/templates/navbar_collapse.html:100 @@ -234,7 +234,7 @@ msgstr "Nom de la session BBB." msgid "Session date" msgstr "Date de session" -#: pod/bbb/models.py:40 pod/video/models.py:653 pod/video/models.py:1371 +#: pod/bbb/models.py:40 pod/video/models.py:653 pod/video/models.py:1378 msgid "Encoding step" msgstr "Étape de l'encodage" @@ -335,7 +335,7 @@ msgid "Publish the BigBlueButton presentation on this platform" msgstr "Publier la présentation BigBlueButton sur cette plateforme" #: pod/bbb/templates/bbb/card.html:33 -#: pod/bbb/templates/bbb/publish_meeting.html:77 +#: pod/bbb/templates/bbb/publish_meeting.html:76 msgid "Publish this presentation" msgstr "Publier cette présentation" @@ -357,7 +357,7 @@ msgstr "par" #: pod/bbb/templates/bbb/list_meeting.html:5 #: pod/bbb/templates/bbb/publish_meeting.html:17 -#: pod/main/templates/navbar.html:106 +#: pod/main/templates/navbar.html:107 msgid "My BigBlueButton records" msgstr "Mes sessions BigBlueButton" @@ -426,7 +426,7 @@ msgstr "Publier la présentation BigBlueButton" msgid "Are you sure you want to publish this BigBlueButton presentation ?" msgstr "Voulez-vous vraiment publier cette présentation BigBlueButton ?" -#: pod/bbb/templates/bbb/publish_meeting.html:73 +#: pod/bbb/templates/bbb/publish_meeting.html:72 msgid "" "A video will be created from the BigBlueButton presentation and will be " "available on this platform." @@ -434,7 +434,7 @@ msgstr "" "Une vidéo sera créée à partir de la présentation BigBlueButton et sera " "disponible sur cette plateforme." -#: pod/bbb/templates/bbb/publish_meeting.html:74 +#: pod/bbb/templates/bbb/publish_meeting.html:73 msgid "" "Please note: this treatment can take a long time. You will receive an email " "when this treatment is completed." @@ -477,7 +477,7 @@ msgstr "titre court" #: pod/chapter/models.py:20 pod/completion/models.py:262 #: pod/enrichment/models.py:120 pod/live/models.py:71 pod/playlist/models.py:17 #: pod/video/models.py:229 pod/video/models.py:313 pod/video/models.py:406 -#: pod/video/models.py:432 pod/video/models.py:473 pod/video/models.py:1583 +#: pod/video/models.py:432 pod/video/models.py:473 pod/video/models.py:1590 msgid "" "Used to access this instance, the \"slug\" is a short label containing only " "letters, numbers, underscore or dash top." @@ -578,7 +578,7 @@ msgstr "Liste des chapitres" #: pod/completion/models.py:257 #: pod/completion/templates/overlay/list_overlay.html:10 #: pod/enrichment/templates/enrichment/list_enrichment.html:10 -#: pod/main/models.py:103 pod/main/views.py:165 pod/playlist/models.py:12 +#: pod/main/models.py:103 pod/main/views.py:166 pod/playlist/models.py:12 #: pod/playlist/templates/playlist/playlist_element_list.html:11 #: pod/video/models.py:220 pod/video/models.py:306 pod/video/models.py:402 #: pod/video/models.py:465 pod/video/templates/channel/list_theme.html:9 @@ -624,7 +624,7 @@ msgstr "Chapitre vidéo" #: pod/completion/templates/video_completion.html:13 #: pod/enrichment/templates/enrichment/group_enrichment.html:10 #: pod/interactive/templates/interactive/group_interactive.html:10 -#: pod/main/templates/navbar.html:94 +#: pod/main/templates/navbar.html:95 #: pod/video/templates/videos/add_video.html:12 #: pod/video/templates/videos/my_videos.html:11 #: pod/video/templates/videos/video_collaborate.html:12 @@ -809,9 +809,9 @@ msgstr "" #: pod/enrichment/models.py:291 pod/enrichment/models.py:322 #: pod/interactive/models.py:16 pod/interactive/models.py:37 #: pod/playlist/models.py:79 pod/recorder/models.py:78 pod/video/models.py:461 -#: pod/video/models.py:1001 pod/video/models.py:1149 pod/video/models.py:1217 -#: pod/video/models.py:1271 pod/video/models.py:1320 pod/video/models.py:1338 -#: pod/video/models.py:1359 +#: pod/video/models.py:1008 pod/video/models.py:1156 pod/video/models.py:1224 +#: pod/video/models.py:1278 pod/video/models.py:1327 pod/video/models.py:1345 +#: pod/video/models.py:1366 msgid "Video" msgstr "Vidéo" @@ -918,7 +918,7 @@ msgstr "gauche" #: pod/completion/models.py:259 pod/live/models.py:69 pod/playlist/models.py:14 #: pod/video/models.py:227 pod/video/models.py:311 pod/video/models.py:404 -#: pod/video/models.py:471 pod/video/models.py:1581 +#: pod/video/models.py:471 pod/video/models.py:1588 msgid "Slug" msgstr "Titre court" @@ -1684,7 +1684,7 @@ msgstr "Ajouter une vidéo à une liste de lecture" #: pod/enrichment/templates/enrichment/video_enrichment.html:106 #: pod/interactive/templates/interactive/video_interactive.html:101 -#: pod/main/templates/navbar.html:98 +#: pod/main/templates/navbar.html:99 #: pod/playlist/templates/my_playlists.html:10 #: pod/playlist/templates/my_playlists.html:17 #: pod/playlist/templates/playlist.html:14 @@ -2009,7 +2009,7 @@ msgstr "Signaux" #: pod/live/templates/live/building.html:11 #: pod/live/templates/live/live.html:20 pod/live/templates/live/live.html:24 #: pod/live/templates/live/lives.html:15 pod/live/templates/live/lives.html:18 -#: pod/live/templates/live/lives.html:21 pod/main/templates/navbar.html:32 +#: pod/live/templates/live/lives.html:21 pod/main/templates/navbar.html:33 msgid "Lives" msgstr "Directs" @@ -2030,7 +2030,7 @@ msgid "Password required" msgstr "Mot de passe requis" #: pod/live/templates/live/live-form.html:31 -#: pod/main/templates/contact_us.html:53 +#: pod/main/templates/contact_us.html:49 #: pod/recorder/templates/recorder/record_delete.html:60 #: pod/video/templates/videos/filter_aside.html:13 #: pod/video/templates/videos/filter_aside.html:34 @@ -2129,8 +2129,8 @@ msgid "Other (please specify)" msgstr "Autre (spécifiez)" #: pod/main/forms.py:50 pod/podfile/models.py:27 pod/podfile/models.py:105 -#: pod/podfile/templates/podfile/home_content.html:32 pod/video/models.py:1142 -#: pod/video/models.py:1214 pod/video/models.py:1268 +#: pod/podfile/templates/podfile/home_content.html:32 pod/video/models.py:1149 +#: pod/video/models.py:1221 pod/video/models.py:1275 msgid "Name" msgstr "Nom" @@ -2862,35 +2862,35 @@ msgstr "Disciplines" msgid "Tags" msgstr "Mots clés" -#: pod/main/templates/base.html:66 +#: pod/main/templates/base.html:72 msgid "Breadcrumb" msgstr "Fil d’Ariane" -#: pod/main/templates/base.html:69 +#: pod/main/templates/base.html:75 msgid "Home" msgstr "Accueil" -#: pod/main/templates/base.html:74 +#: pod/main/templates/base.html:80 msgid "Toggle side Menu" msgstr "Afficher/masquer le menu latéral" -#: pod/main/templates/contact_us.html:8 pod/main/templates/contact_us.html:12 -#: pod/main/templates/contact_us.html:17 pod/main/templates/maintenance.html:15 +#: pod/main/templates/contact_us.html:7 pod/main/templates/contact_us.html:10 +#: pod/main/templates/contact_us.html:13 pod/main/templates/maintenance.html:15 msgid "Contact us" msgstr "Contactez nous" -#: pod/main/templates/contact_us.html:56 +#: pod/main/templates/contact_us.html:52 msgid "Back to the previous page" msgstr "Retour à la page précédente" -#: pod/main/templates/contact_us.html:70 +#: pod/main/templates/contact_us.html:66 #: pod/video/templates/channel/channel_edit.html:93 #: pod/video/templates/channel/theme_edit.html:65 #: pod/video/templates/videos/video_edit.html:188 msgid "Mandatory fields" msgstr "Champs obligatoires" -#: pod/main/templates/contact_us.html:72 +#: pod/main/templates/contact_us.html:68 #: pod/video/templates/channel/channel_edit.html:95 #: pod/video/templates/channel/theme_edit.html:67 #: pod/video/templates/videos/video_edit.html:190 @@ -2969,17 +2969,17 @@ msgstr "Vous venez d'envoyer un message depuis" msgid "Return to homepage" msgstr "Revenir à la page d'accueil" -#: pod/main/templates/navbar.html:17 pod/recorder/models.py:194 +#: pod/main/templates/navbar.html:18 pod/recorder/models.py:194 #: pod/video/forms.py:172 pod/video/models.py:266 pod/video/models.py:534 msgid "Channels" msgstr "Chaînes" -#: pod/main/templates/navbar.html:27 pod/video/models.py:424 +#: pod/main/templates/navbar.html:28 pod/video/models.py:424 #: pod/video/templates/videos/filter_aside.html:34 msgid "Types" msgstr "Types" -#: pod/main/templates/navbar.html:53 pod/main/templates/navbar.html:55 +#: pod/main/templates/navbar.html:54 pod/main/templates/navbar.html:56 #: pod/main/templates/navbar_collapse.html:85 #: pod/main/templates/navbar_collapse.html:86 #: pod/video/templates/videos/filter_aside.html:15 @@ -2989,19 +2989,19 @@ msgstr "Types" msgid "Search" msgstr "Rechercher" -#: pod/main/templates/navbar.html:60 +#: pod/main/templates/navbar.html:61 msgid "Some features are unavailable" msgstr "Certaines fonctionnalités sont indisponibles" -#: pod/main/templates/navbar.html:63 pod/main/templates/navbar.html:65 +#: pod/main/templates/navbar.html:64 pod/main/templates/navbar.html:66 msgid "Add a video" msgstr "Ajouter une vidéo" -#: pod/main/templates/navbar.html:91 +#: pod/main/templates/navbar.html:92 msgid "Add your picture" msgstr "Ajouter votre image de profil" -#: pod/main/templates/navbar.html:96 +#: pod/main/templates/navbar.html:97 #: pod/video/templates/channel/channel_edit.html:17 #: pod/video/templates/channel/my_channels.html:6 #: pod/video/templates/channel/my_channels.html:9 @@ -3009,22 +3009,30 @@ msgstr "Ajouter votre image de profil" msgid "My channels" msgstr "Mes chaînes" -#: pod/main/templates/navbar.html:100 pod/podfile/templates/podfile/home.html:6 +#: pod/main/templates/navbar.html:101 pod/podfile/templates/podfile/home.html:6 #: pod/podfile/templates/podfile/home.html:10 msgid "My files" msgstr "Mes fichiers" -#: pod/main/templates/navbar.html:103 +#: pod/main/templates/navbar.html:104 #: pod/recorder/templates/recorder/claim_record.html:11 #: pod/recorder/templates/recorder/record_delete.html:8 #: pod/recorder/templates/recorder/record_delete.html:20 msgid "Claim a record" msgstr "Revendiquer un enregistrement" -#: pod/main/templates/navbar.html:110 pod/main/templates/navbar.html:111 +#: pod/main/templates/navbar.html:111 pod/main/templates/navbar.html:112 msgid "Log out" msgstr "Déconnexion" +#: pod/main/templates/navbar.html:143 pod/main/templates/navbar.html:145 +msgid "Dark mode" +msgstr "Mode sombre" + +#: pod/main/templates/navbar.html:154 pod/main/templates/navbar.html:156 +msgid "Dyslexia mode" +msgstr "Police ‘Open Dyslexic’" + #: pod/main/templates/navbar_collapse.html:8 #, python-format msgid "%(counter)s Channel" @@ -3060,15 +3068,15 @@ msgstr "Types de vidéos" msgid "Use the input to filter user by last name." msgstr "Utiliser le champ pour filtrer les utilisateurs par nom de famille." -#: pod/main/views.py:166 +#: pod/main/views.py:167 msgid "Link" msgstr "Lien" -#: pod/main/views.py:233 +#: pod/main/views.py:234 msgid "your message untitled" msgstr "votre message intitulé" -#: pod/main/views.py:252 +#: pod/main/views.py:253 msgid "Your message have been sent." msgstr "Votre message a été envoyé." @@ -3642,7 +3650,7 @@ msgid "Themes" msgstr "Thèmes" #: pod/recorder/models.py:200 pod/video/forms.py:140 pod/video/forms.py:176 -#: pod/video/models.py:540 pod/video/models.py:1578 +#: pod/video/models.py:540 pod/video/models.py:1585 msgid "" "Hold down \"Control\", or \"Command\" on a Mac, to select more than one." msgstr "" @@ -3734,8 +3742,8 @@ msgstr "Fichier source de la vidéo publiée." msgid "File size" msgstr "Taille du fichier" -#: pod/recorder/models.py:320 pod/video/models.py:505 pod/video/models.py:1408 -#: pod/video/models.py:1467 +#: pod/recorder/models.py:320 pod/video/models.py:505 pod/video/models.py:1415 +#: pod/video/models.py:1474 msgid "Date added" msgstr "Date d'ajout" @@ -4374,27 +4382,27 @@ msgstr "Somme des vues" msgid "Is the video encoded ?" msgstr "Est-ce que la vidéo est encodée ?" -#: pod/video/models.py:1004 +#: pod/video/models.py:1011 msgid "Date" msgstr "Date" -#: pod/video/models.py:1006 +#: pod/video/models.py:1013 msgid "Number of view" msgstr "Nombre de vues" -#: pod/video/models.py:1014 +#: pod/video/models.py:1021 msgid "View count" msgstr "Nombre de vues" -#: pod/video/models.py:1015 +#: pod/video/models.py:1022 msgid "View counts" msgstr "Statistiques" -#: pod/video/models.py:1020 +#: pod/video/models.py:1027 msgid "resolution" msgstr "résolution" -#: pod/video/models.py:1023 +#: pod/video/models.py:1030 msgid "" "Please use the only format x. i.e.: 640x360 or 1280x720 or " "1920x1080." @@ -4402,12 +4410,12 @@ msgstr "" "Veuillez utiliser le format LxH. soit: 640x360 ou 1280x720 " "ou 1920x1080." -#: pod/video/models.py:1027 pod/video/models.py:1096 pod/video/models.py:1103 +#: pod/video/models.py:1034 pod/video/models.py:1103 pod/video/models.py:1110 msgid "minrate" msgstr "débit minimum" -#: pod/video/models.py:1029 pod/video/models.py:1035 pod/video/models.py:1041 -#: pod/video/models.py:1047 +#: pod/video/models.py:1036 pod/video/models.py:1042 pod/video/models.py:1048 +#: pod/video/models.py:1054 msgid "" "Please use the only format k. i.e.: 300k or 600k or " "1000k." @@ -4415,179 +4423,179 @@ msgstr "" "Veuillez utiliser le format XXk soit: 300k ou 600k ou " "1000k." -#: pod/video/models.py:1033 pod/video/models.py:1072 pod/video/models.py:1079 +#: pod/video/models.py:1040 pod/video/models.py:1079 pod/video/models.py:1086 msgid "bitrate video" msgstr "débit binaire de la vidéo" -#: pod/video/models.py:1039 pod/video/models.py:1084 pod/video/models.py:1091 +#: pod/video/models.py:1046 pod/video/models.py:1091 pod/video/models.py:1098 msgid "maxrate" msgstr "débit maximum" -#: pod/video/models.py:1045 pod/video/models.py:1121 pod/video/models.py:1128 +#: pod/video/models.py:1052 pod/video/models.py:1128 pod/video/models.py:1135 msgid "bitrate audio" msgstr "débit binaire de l'audio" -#: pod/video/models.py:1050 +#: pod/video/models.py:1057 msgid "Make a MP4 version" msgstr "Faire une version MP4" -#: pod/video/models.py:1063 pod/video/models.py:1151 +#: pod/video/models.py:1070 pod/video/models.py:1158 msgid "rendition" msgstr "rendu" -#: pod/video/models.py:1064 +#: pod/video/models.py:1071 msgid "renditions" msgstr "rendus" -#: pod/video/models.py:1146 pod/video/models.py:1215 pod/video/models.py:1269 +#: pod/video/models.py:1153 pod/video/models.py:1222 pod/video/models.py:1276 msgid "Please use the only format in encoding choices:" msgstr "Merci de sélectionner un format d’encodage valide :" -#: pod/video/models.py:1153 pod/video/models.py:1219 pod/video/models.py:1273 +#: pod/video/models.py:1160 pod/video/models.py:1226 pod/video/models.py:1280 msgid "Format" msgstr "Format" -#: pod/video/models.py:1157 pod/video/models.py:1221 pod/video/models.py:1275 +#: pod/video/models.py:1164 pod/video/models.py:1228 pod/video/models.py:1282 msgid "Please use the only format in format choices:" msgstr "Merci de sélectionner un format valide :" -#: pod/video/models.py:1160 pod/video/models.py:1224 pod/video/models.py:1278 +#: pod/video/models.py:1167 pod/video/models.py:1231 pod/video/models.py:1285 msgid "encoding source file" msgstr "fichier source d'encodage" -#: pod/video/models.py:1182 +#: pod/video/models.py:1189 msgid "Encoding video" msgstr "Encodage vidéo" -#: pod/video/models.py:1183 +#: pod/video/models.py:1190 msgid "Encoding videos" msgstr "Encodage des vidéos" -#: pod/video/models.py:1234 +#: pod/video/models.py:1241 msgid "Encoding audio" msgstr "Encodage audio" -#: pod/video/models.py:1235 +#: pod/video/models.py:1242 msgid "Encoding audios" msgstr "Encodage des audios" -#: pod/video/models.py:1283 +#: pod/video/models.py:1290 msgid "Video Playlist" msgstr "Liste de lecture" -#: pod/video/models.py:1284 +#: pod/video/models.py:1291 msgid "Video Playlists" msgstr "Listes de lecture" -#: pod/video/models.py:1330 +#: pod/video/models.py:1337 msgid "Encoding log" msgstr "Journal de l'encodage" -#: pod/video/models.py:1331 +#: pod/video/models.py:1338 msgid "Encoding logs" msgstr "Journaux des encodages" -#: pod/video/models.py:1341 pod/video/models.py:1346 +#: pod/video/models.py:1348 pod/video/models.py:1353 msgid "Video version" msgstr "Version de la video" -#: pod/video/models.py:1343 +#: pod/video/models.py:1350 msgid "Video default version." msgstr "Version par défaut de la vidéo." -#: pod/video/models.py:1347 +#: pod/video/models.py:1354 msgid "Video versions" msgstr "Versions de la video" -#: pod/video/models.py:1372 +#: pod/video/models.py:1379 msgid "Encoding steps" msgstr "Etapes de l'encodage" -#: pod/video/models.py:1381 pod/video/models.py:1388 pod/video/models.py:1404 +#: pod/video/models.py:1388 pod/video/models.py:1395 pod/video/models.py:1411 #: pod/video/views.py:1314 msgid "Note" msgstr "Note" -#: pod/video/models.py:1389 +#: pod/video/models.py:1396 msgid "Notes" msgstr "Notes" -#: pod/video/models.py:1400 +#: pod/video/models.py:1407 msgid "Note availibility level" msgstr "Niveau de disponibilité de la note" -#: pod/video/models.py:1402 +#: pod/video/models.py:1409 msgid "Select an availability level for the note." msgstr "Sélectionner le niveau de disponibilité de la note." -#: pod/video/models.py:1406 +#: pod/video/models.py:1413 msgid "Timestamp" msgstr "Horodatage" -#: pod/video/models.py:1410 pod/video/models.py:1469 +#: pod/video/models.py:1417 pod/video/models.py:1476 msgid "Date modified" msgstr "Date de modification" -#: pod/video/models.py:1413 +#: pod/video/models.py:1420 msgid "Advanced Note" msgstr "Note avancée" -#: pod/video/models.py:1414 +#: pod/video/models.py:1421 msgid "Advanced Notes" msgstr "Notes avancées" -#: pod/video/models.py:1460 +#: pod/video/models.py:1467 msgid "Comment availibility level" msgstr "Niveau de disponibilité du commentaire" -#: pod/video/models.py:1462 +#: pod/video/models.py:1469 msgid "Select an availability level for the comment." msgstr "Sélectionnez un niveau de disponibilité pour le commentaire." -#: pod/video/models.py:1472 +#: pod/video/models.py:1479 msgid "Note comment" msgstr "Commentaire de la note" -#: pod/video/models.py:1473 +#: pod/video/models.py:1480 msgid "Note comments" msgstr "Commentaires de notes" -#: pod/video/models.py:1491 +#: pod/video/models.py:1498 msgid "Date for deletion" msgstr "Date pour la suppression" -#: pod/video/models.py:1494 pod/video/models.py:1576 +#: pod/video/models.py:1501 pod/video/models.py:1583 #: pod/video/templates/videos/video.html:76 #: pod/video/templates/videos/videos.html:8 #: pod/video/templates/videos/videos.html:17 msgid "Videos" msgstr "Vidéos" -#: pod/video/models.py:1497 +#: pod/video/models.py:1504 msgid "Video to delete" msgstr "Vidéo à supprimer" -#: pod/video/models.py:1498 +#: pod/video/models.py:1505 msgid "Videos to delete" msgstr "Vidéos à supprimer" -#: pod/video/models.py:1518 pod/video/templates/videos/video-comment.html:9 +#: pod/video/models.py:1525 pod/video/templates/videos/video-comment.html:9 msgid "Comments" msgstr "Commentaires" -#: pod/video/models.py:1559 +#: pod/video/models.py:1566 msgid "Vote" msgstr "Vote" -#: pod/video/models.py:1560 +#: pod/video/models.py:1567 msgid "Votes" msgstr "Votes" -#: pod/video/models.py:1568 pod/video/templates/videos/category_modal.html:13 +#: pod/video/models.py:1575 pod/video/templates/videos/category_modal.html:13 msgid "Category title" msgstr "Titre catégorie" -#: pod/video/models.py:1570 +#: pod/video/models.py:1577 msgid "" "Please choose a title as short and accurate as possible, reflecting the main " "subject / context of the content.(max length : 100 characters)" @@ -4596,11 +4604,11 @@ msgstr "" "sujet principal / le contexte de votre contenu. (taille maximale : 100 " "caractères)" -#: pod/video/models.py:1596 pod/video/templates/videos/category_modal.html:7 +#: pod/video/models.py:1603 pod/video/templates/videos/category_modal.html:7 msgid "Category" msgstr "Catégorie" -#: pod/video/models.py:1597 +#: pod/video/models.py:1604 #: pod/video/templates/videos/filter_aside_category.html:14 msgid "Categories" msgstr "Catégories" diff --git a/pod/locale/fr/LC_MESSAGES/djangojs.po b/pod/locale/fr/LC_MESSAGES/djangojs.po index 9f8198aa92..0329413ee4 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: 2021-02-24 09:35+0100\n" +"POT-Creation-Date: 2021-03-11 17:17+0100\n" "PO-Revision-Date: 2021-01-29 15:57+0100\n" "Last-Translator: obado \n" "Language-Team: \n" @@ -47,17 +47,17 @@ msgstr "Le formulaire ne peut pas être récupéré." #: pod/enrichment/static/js/enrichment.js:72 #: pod/enrichment/static/js/enrichment.js:93 #: pod/enrichment/static/js/enrichment.js:120 -#: pod/enrichment/static/js/enrichment.js:149 pod/main/static/js/main.js:293 -#: pod/main/static/js/main.js:300 pod/main/static/js/main.js:311 -#: pod/main/static/js/main.js:325 +#: pod/enrichment/static/js/enrichment.js:149 pod/main/static/js/main.js:305 +#: pod/main/static/js/main.js:312 pod/main/static/js/main.js:323 +#: pod/main/static/js/main.js:337 #: pod/podfile/static/podfile/js/filewidget.js:365 #: pod/podfile/static/podfile/js/filewidget.js:398 msgid "You are no longer authenticated. Please log in again." msgstr "Vous n'êtes plus authentifié. Veuillez vous reconnectez." #: pod/chapter/static/js/chapters.js:146 -#: pod/enrichment/static/js/enrichment.js:136 pod/main/static/js/main.js:263 -#: pod/main/static/js/main.js:317 +#: pod/enrichment/static/js/enrichment.js:136 pod/main/static/js/main.js:275 +#: pod/main/static/js/main.js:329 msgid "One or more errors have been found in the form." msgstr "Une ou plusieurs erreurs ont été trouvées dans le formulaire." @@ -129,7 +129,7 @@ msgstr "Êtes-vous sûr(e) de vouloir supprimer ce document ?" msgid "Are you sure you want to delete this overlay?" msgstr "Êtes-vous sûr(e) de vouloir supprimer cette superposition ?" -#: pod/completion/static/js/completion.js:195 pod/main/static/js/main.js:265 +#: pod/completion/static/js/completion.js:195 pod/main/static/js/main.js:277 msgid "Changes have been saved." msgstr "Les modifications ont été sauvegardées." @@ -363,46 +363,46 @@ msgstr "" msgid "gridErrorText" msgstr "" -#: pod/main/static/js/main.js:244 +#: pod/main/static/js/main.js:256 msgid "Are you sure you want to delete this element?" msgstr "Êtes-vous sûr(e) de vouloir supprimer cet élément ?" -#: pod/main/static/js/main.js:286 +#: pod/main/static/js/main.js:298 #: pod/podfile/static/podfile/js/filewidget.js:114 #: pod/podfile/static/podfile/js/filewidget.js:391 msgid "Error during exchange" msgstr "Erreur durant le téléversement" -#: pod/main/static/js/main.js:286 +#: pod/main/static/js/main.js:298 #: pod/podfile/static/podfile/js/filewidget.js:114 msgid "No data could be stored." msgstr "Aucune donnée ne peut être stockée." -#: pod/main/static/js/main.js:339 +#: pod/main/static/js/main.js:351 msgid "Change your picture" msgstr "Changer votre image" -#: pod/main/static/js/main.js:345 +#: pod/main/static/js/main.js:357 msgid "Add your picture" msgstr "Ajouter votre image" -#: pod/main/static/js/main.js:443 +#: pod/main/static/js/main.js:453 msgid "text copied" msgstr "texte copié" -#: pod/main/static/js/main.js:490 +#: pod/main/static/js/main.js:500 msgid "Errors appear in the form, please correct them" msgstr "Des erreurs sont présentes dans le formulaire, veuillez les corriger" -#: pod/main/static/js/main.js:513 +#: pod/main/static/js/main.js:523 msgid "The file size exceeds the maximum allowed value:" msgstr "Le fichier dépasse la taille maximum autorisée :" -#: pod/main/static/js/main.js:513 +#: pod/main/static/js/main.js:523 msgid " GB." msgstr " Go." -#: pod/main/static/js/main.js:528 +#: pod/main/static/js/main.js:538 msgid "The file extension not in the allowed extension:" msgstr "" "Cette extension de fichier n'est pas présente dans les extensions " diff --git a/pod/locale/nl/LC_MESSAGES/django.po b/pod/locale/nl/LC_MESSAGES/django.po index 2a19f99843..38f5aa3060 100755 --- 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: 2021-03-10 11:14+0000\n" +"POT-Creation-Date: 2021-03-11 16:17+0000\n" "PO-Revision-Date: 2021-01-22 12:27+0100\n" "Last-Translator: obado \n" "Language-Team: \n" @@ -26,7 +26,7 @@ msgid "Establishment" msgstr "" #: pod/authentication/forms.py:60 pod/authentication/forms.py:61 -#: pod/bbb/models.py:141 pod/main/templates/navbar.html:22 +#: pod/bbb/models.py:141 pod/main/templates/navbar.html:23 #: pod/main/templates/navbar_collapse.html:76 pod/podfile/models.py:37 #: pod/video/forms.py:236 pod/video/forms.py:589 pod/video/forms.py:593 #: pod/video/models.py:253 pod/video/templates/videos/filter_aside.html:13 @@ -90,7 +90,7 @@ msgid "registered-reader" msgstr "" #: pod/authentication/models.py:68 pod/recorder/models.py:266 -#: pod/video/models.py:1465 pod/video/models.py:1517 pod/video/views.py:1303 +#: pod/video/models.py:1472 pod/video/models.py:1524 pod/video/views.py:1303 msgid "Comment" msgstr "" @@ -114,7 +114,7 @@ msgstr "" #: pod/authentication/templates/registration/login.html:9 #: pod/authentication/templates/registration/login.html:12 #: pod/authentication/templates/registration/login.html:63 -#: pod/main/templates/navbar.html:117 +#: pod/main/templates/navbar.html:118 msgid "Log in" msgstr "Inloggen" @@ -138,17 +138,17 @@ msgid "Forgotten your password or username?" msgstr "" #: pod/authentication/templates/userpicture/userpicture.html:7 -#: pod/main/templates/navbar.html:88 +#: pod/main/templates/navbar.html:89 msgid "Change your picture" msgstr "" #: pod/authentication/templates/userpicture/userpicture.html:29 -#: pod/authentication/views.py:98 pod/bbb/templates/bbb/publish_meeting.html:38 +#: pod/authentication/views.py:98 pod/bbb/templates/bbb/publish_meeting.html:37 #: pod/bbb/views.py:110 pod/completion/templates/video_caption_maker.html:57 #: pod/enrichment/templates/enrichment/group_enrichment.html:29 #: pod/interactive/templates/interactive/group_interactive.html:29 #: pod/live/templates/live/live-form.html:10 -#: pod/main/templates/contact_us.html:24 pod/main/views.py:259 +#: pod/main/templates/contact_us.html:20 pod/main/views.py:260 #: pod/playlist/views.py:140 #: pod/recorder/templates/recorder/add_recording.html:36 #: pod/recorder/templates/recorder/record_delete.html:32 @@ -168,12 +168,12 @@ msgid "One or more errors have been found in the form." msgstr "" #: pod/authentication/templates/userpicture/userpicture.html:42 -#: pod/bbb/templates/bbb/publish_meeting.html:66 +#: pod/bbb/templates/bbb/publish_meeting.html:65 #: pod/completion/templates/video_caption_maker.html:69 #: pod/enrichment/templates/enrichment/group_enrichment.html:51 #: pod/interactive/templates/interactive/group_interactive.html:51 #: pod/live/templates/live/live-form.html:25 -#: pod/main/templates/contact_us.html:47 +#: pod/main/templates/contact_us.html:43 #: pod/recorder/templates/recorder/add_recording.html:59 #: pod/recorder/templates/recorder/record_delete.html:54 #: pod/video/templates/channel/channel_edit.html:70 @@ -189,7 +189,7 @@ msgid "Please provide a valid value for this field" msgstr "" #: pod/authentication/templates/userpicture/userpicture.html:56 -#: pod/bbb/templates/bbb/list_meeting.html:44 pod/main/templates/base.html:113 +#: pod/bbb/templates/bbb/list_meeting.html:44 pod/main/templates/base.html:117 #: pod/main/templates/navbar_collapse.html:43 #: pod/main/templates/navbar_collapse.html:66 #: pod/main/templates/navbar_collapse.html:100 @@ -232,7 +232,7 @@ msgstr "" msgid "Session date" msgstr "" -#: pod/bbb/models.py:40 pod/video/models.py:653 pod/video/models.py:1371 +#: pod/bbb/models.py:40 pod/video/models.py:653 pod/video/models.py:1378 msgid "Encoding step" msgstr "" @@ -328,7 +328,7 @@ msgid "Publish the BigBlueButton presentation on this platform" msgstr "" #: pod/bbb/templates/bbb/card.html:33 -#: pod/bbb/templates/bbb/publish_meeting.html:77 +#: pod/bbb/templates/bbb/publish_meeting.html:76 msgid "Publish this presentation" msgstr "" @@ -350,7 +350,7 @@ msgstr "" #: pod/bbb/templates/bbb/list_meeting.html:5 #: pod/bbb/templates/bbb/publish_meeting.html:17 -#: pod/main/templates/navbar.html:106 +#: pod/main/templates/navbar.html:107 msgid "My BigBlueButton records" msgstr "" @@ -408,13 +408,13 @@ msgstr "" msgid "Are you sure you want to publish this BigBlueButton presentation ?" msgstr "" -#: pod/bbb/templates/bbb/publish_meeting.html:73 +#: pod/bbb/templates/bbb/publish_meeting.html:72 msgid "" "A video will be created from the BigBlueButton presentation and will be " "available on this platform." msgstr "" -#: pod/bbb/templates/bbb/publish_meeting.html:74 +#: pod/bbb/templates/bbb/publish_meeting.html:73 msgid "" "Please note: this treatment can take a long time. You will receive an email " "when this treatment is completed." @@ -455,7 +455,7 @@ msgstr "" #: pod/chapter/models.py:20 pod/completion/models.py:262 #: pod/enrichment/models.py:120 pod/live/models.py:71 pod/playlist/models.py:17 #: pod/video/models.py:229 pod/video/models.py:313 pod/video/models.py:406 -#: pod/video/models.py:432 pod/video/models.py:473 pod/video/models.py:1583 +#: pod/video/models.py:432 pod/video/models.py:473 pod/video/models.py:1590 msgid "" "Used to access this instance, the \"slug\" is a short label containing only " "letters, numbers, underscore or dash top." @@ -549,7 +549,7 @@ msgstr "" #: pod/completion/models.py:257 #: pod/completion/templates/overlay/list_overlay.html:10 #: pod/enrichment/templates/enrichment/list_enrichment.html:10 -#: pod/main/models.py:103 pod/main/views.py:165 pod/playlist/models.py:12 +#: pod/main/models.py:103 pod/main/views.py:166 pod/playlist/models.py:12 #: pod/playlist/templates/playlist/playlist_element_list.html:11 #: pod/video/models.py:220 pod/video/models.py:306 pod/video/models.py:402 #: pod/video/models.py:465 pod/video/templates/channel/list_theme.html:9 @@ -595,7 +595,7 @@ msgstr "" #: pod/completion/templates/video_completion.html:13 #: pod/enrichment/templates/enrichment/group_enrichment.html:10 #: pod/interactive/templates/interactive/group_interactive.html:10 -#: pod/main/templates/navbar.html:94 +#: pod/main/templates/navbar.html:95 #: pod/video/templates/videos/add_video.html:12 #: pod/video/templates/videos/my_videos.html:11 #: pod/video/templates/videos/video_collaborate.html:12 @@ -772,9 +772,9 @@ msgstr "" #: pod/enrichment/models.py:291 pod/enrichment/models.py:322 #: pod/interactive/models.py:16 pod/interactive/models.py:37 #: pod/playlist/models.py:79 pod/recorder/models.py:78 pod/video/models.py:461 -#: pod/video/models.py:1001 pod/video/models.py:1149 pod/video/models.py:1217 -#: pod/video/models.py:1271 pod/video/models.py:1320 pod/video/models.py:1338 -#: pod/video/models.py:1359 +#: pod/video/models.py:1008 pod/video/models.py:1156 pod/video/models.py:1224 +#: pod/video/models.py:1278 pod/video/models.py:1327 pod/video/models.py:1345 +#: pod/video/models.py:1366 msgid "Video" msgstr "" @@ -879,7 +879,7 @@ msgstr "" #: pod/completion/models.py:259 pod/live/models.py:69 pod/playlist/models.py:14 #: pod/video/models.py:227 pod/video/models.py:311 pod/video/models.py:404 -#: pod/video/models.py:471 pod/video/models.py:1581 +#: pod/video/models.py:471 pod/video/models.py:1588 msgid "Slug" msgstr "" @@ -1610,7 +1610,7 @@ msgstr "" #: pod/enrichment/templates/enrichment/video_enrichment.html:106 #: pod/interactive/templates/interactive/video_interactive.html:101 -#: pod/main/templates/navbar.html:98 +#: pod/main/templates/navbar.html:99 #: pod/playlist/templates/my_playlists.html:10 #: pod/playlist/templates/my_playlists.html:17 #: pod/playlist/templates/playlist.html:14 @@ -1921,7 +1921,7 @@ msgstr "" #: pod/live/templates/live/building.html:11 #: pod/live/templates/live/live.html:20 pod/live/templates/live/live.html:24 #: pod/live/templates/live/lives.html:15 pod/live/templates/live/lives.html:18 -#: pod/live/templates/live/lives.html:21 pod/main/templates/navbar.html:32 +#: pod/live/templates/live/lives.html:21 pod/main/templates/navbar.html:33 msgid "Lives" msgstr "" @@ -1940,7 +1940,7 @@ msgid "Password required" msgstr "" #: pod/live/templates/live/live-form.html:31 -#: pod/main/templates/contact_us.html:53 +#: pod/main/templates/contact_us.html:49 #: pod/recorder/templates/recorder/record_delete.html:60 #: pod/video/templates/videos/filter_aside.html:13 #: pod/video/templates/videos/filter_aside.html:34 @@ -2032,8 +2032,8 @@ msgid "Other (please specify)" msgstr "" #: pod/main/forms.py:50 pod/podfile/models.py:27 pod/podfile/models.py:105 -#: pod/podfile/templates/podfile/home_content.html:32 pod/video/models.py:1142 -#: pod/video/models.py:1214 pod/video/models.py:1268 +#: pod/podfile/templates/podfile/home_content.html:32 pod/video/models.py:1149 +#: pod/video/models.py:1221 pod/video/models.py:1275 msgid "Name" msgstr "" @@ -2765,35 +2765,35 @@ msgstr "" msgid "Tags" msgstr "" -#: pod/main/templates/base.html:66 +#: pod/main/templates/base.html:72 msgid "Breadcrumb" msgstr "" -#: pod/main/templates/base.html:69 +#: pod/main/templates/base.html:75 msgid "Home" msgstr "" -#: pod/main/templates/base.html:74 +#: pod/main/templates/base.html:80 msgid "Toggle side Menu" msgstr "" -#: pod/main/templates/contact_us.html:8 pod/main/templates/contact_us.html:12 -#: pod/main/templates/contact_us.html:17 pod/main/templates/maintenance.html:15 +#: pod/main/templates/contact_us.html:7 pod/main/templates/contact_us.html:10 +#: pod/main/templates/contact_us.html:13 pod/main/templates/maintenance.html:15 msgid "Contact us" msgstr "" -#: pod/main/templates/contact_us.html:56 +#: pod/main/templates/contact_us.html:52 msgid "Back to the previous page" msgstr "" -#: pod/main/templates/contact_us.html:70 +#: pod/main/templates/contact_us.html:66 #: pod/video/templates/channel/channel_edit.html:93 #: pod/video/templates/channel/theme_edit.html:65 #: pod/video/templates/videos/video_edit.html:188 msgid "Mandatory fields" msgstr "" -#: pod/main/templates/contact_us.html:72 +#: pod/main/templates/contact_us.html:68 #: pod/video/templates/channel/channel_edit.html:95 #: pod/video/templates/channel/theme_edit.html:67 #: pod/video/templates/videos/video_edit.html:190 @@ -2870,17 +2870,17 @@ msgstr "" msgid "Return to homepage" msgstr "" -#: pod/main/templates/navbar.html:17 pod/recorder/models.py:194 +#: pod/main/templates/navbar.html:18 pod/recorder/models.py:194 #: pod/video/forms.py:172 pod/video/models.py:266 pod/video/models.py:534 msgid "Channels" msgstr "" -#: pod/main/templates/navbar.html:27 pod/video/models.py:424 +#: pod/main/templates/navbar.html:28 pod/video/models.py:424 #: pod/video/templates/videos/filter_aside.html:34 msgid "Types" msgstr "" -#: pod/main/templates/navbar.html:53 pod/main/templates/navbar.html:55 +#: pod/main/templates/navbar.html:54 pod/main/templates/navbar.html:56 #: pod/main/templates/navbar_collapse.html:85 #: pod/main/templates/navbar_collapse.html:86 #: pod/video/templates/videos/filter_aside.html:15 @@ -2890,19 +2890,19 @@ msgstr "" msgid "Search" msgstr "" -#: pod/main/templates/navbar.html:60 +#: pod/main/templates/navbar.html:61 msgid "Some features are unavailable" msgstr "" -#: pod/main/templates/navbar.html:63 pod/main/templates/navbar.html:65 +#: pod/main/templates/navbar.html:64 pod/main/templates/navbar.html:66 msgid "Add a video" msgstr "" -#: pod/main/templates/navbar.html:91 +#: pod/main/templates/navbar.html:92 msgid "Add your picture" msgstr "" -#: pod/main/templates/navbar.html:96 +#: pod/main/templates/navbar.html:97 #: pod/video/templates/channel/channel_edit.html:17 #: pod/video/templates/channel/my_channels.html:6 #: pod/video/templates/channel/my_channels.html:9 @@ -2910,22 +2910,30 @@ msgstr "" msgid "My channels" msgstr "" -#: pod/main/templates/navbar.html:100 pod/podfile/templates/podfile/home.html:6 +#: pod/main/templates/navbar.html:101 pod/podfile/templates/podfile/home.html:6 #: pod/podfile/templates/podfile/home.html:10 msgid "My files" msgstr "" -#: pod/main/templates/navbar.html:103 +#: pod/main/templates/navbar.html:104 #: pod/recorder/templates/recorder/claim_record.html:11 #: pod/recorder/templates/recorder/record_delete.html:8 #: pod/recorder/templates/recorder/record_delete.html:20 msgid "Claim a record" msgstr "" -#: pod/main/templates/navbar.html:110 pod/main/templates/navbar.html:111 +#: pod/main/templates/navbar.html:111 pod/main/templates/navbar.html:112 msgid "Log out" msgstr "" +#: pod/main/templates/navbar.html:143 pod/main/templates/navbar.html:145 +msgid "Dark mode" +msgstr "" + +#: pod/main/templates/navbar.html:154 pod/main/templates/navbar.html:156 +msgid "Dyslexia mode" +msgstr "" + #: pod/main/templates/navbar_collapse.html:8 #, python-format msgid "%(counter)s Channel" @@ -2961,15 +2969,15 @@ msgstr "" msgid "Use the input to filter user by last name." msgstr "" -#: pod/main/views.py:166 +#: pod/main/views.py:167 msgid "Link" msgstr "" -#: pod/main/views.py:233 +#: pod/main/views.py:234 msgid "your message untitled" msgstr "" -#: pod/main/views.py:252 +#: pod/main/views.py:253 msgid "Your message have been sent." msgstr "" @@ -3507,7 +3515,7 @@ msgid "Themes" msgstr "" #: pod/recorder/models.py:200 pod/video/forms.py:140 pod/video/forms.py:176 -#: pod/video/models.py:540 pod/video/models.py:1578 +#: pod/video/models.py:540 pod/video/models.py:1585 msgid "" "Hold down \"Control\", or \"Command\" on a Mac, to select more than one." msgstr "" @@ -3594,8 +3602,8 @@ msgstr "" msgid "File size" msgstr "" -#: pod/recorder/models.py:320 pod/video/models.py:505 pod/video/models.py:1408 -#: pod/video/models.py:1467 +#: pod/recorder/models.py:320 pod/video/models.py:505 pod/video/models.py:1415 +#: pod/video/models.py:1474 msgid "Date added" msgstr "" @@ -4142,226 +4150,226 @@ msgstr "" msgid "Is the video encoded ?" msgstr "" -#: pod/video/models.py:1004 +#: pod/video/models.py:1011 msgid "Date" msgstr "" -#: pod/video/models.py:1006 +#: pod/video/models.py:1013 msgid "Number of view" msgstr "" -#: pod/video/models.py:1014 +#: pod/video/models.py:1021 msgid "View count" msgstr "" -#: pod/video/models.py:1015 +#: pod/video/models.py:1022 msgid "View counts" msgstr "" -#: pod/video/models.py:1020 +#: pod/video/models.py:1027 msgid "resolution" msgstr "" -#: pod/video/models.py:1023 +#: pod/video/models.py:1030 msgid "" "Please use the only format x. i.e.: 640x360 or 1280x720 or " "1920x1080." msgstr "" -#: pod/video/models.py:1027 pod/video/models.py:1096 pod/video/models.py:1103 +#: pod/video/models.py:1034 pod/video/models.py:1103 pod/video/models.py:1110 msgid "minrate" msgstr "" -#: pod/video/models.py:1029 pod/video/models.py:1035 pod/video/models.py:1041 -#: pod/video/models.py:1047 +#: pod/video/models.py:1036 pod/video/models.py:1042 pod/video/models.py:1048 +#: pod/video/models.py:1054 msgid "" "Please use the only format k. i.e.: 300k or 600k or " "1000k." msgstr "" -#: pod/video/models.py:1033 pod/video/models.py:1072 pod/video/models.py:1079 +#: pod/video/models.py:1040 pod/video/models.py:1079 pod/video/models.py:1086 msgid "bitrate video" msgstr "" -#: pod/video/models.py:1039 pod/video/models.py:1084 pod/video/models.py:1091 +#: pod/video/models.py:1046 pod/video/models.py:1091 pod/video/models.py:1098 msgid "maxrate" msgstr "" -#: pod/video/models.py:1045 pod/video/models.py:1121 pod/video/models.py:1128 +#: pod/video/models.py:1052 pod/video/models.py:1128 pod/video/models.py:1135 msgid "bitrate audio" msgstr "" -#: pod/video/models.py:1050 +#: pod/video/models.py:1057 msgid "Make a MP4 version" msgstr "" -#: pod/video/models.py:1063 pod/video/models.py:1151 +#: pod/video/models.py:1070 pod/video/models.py:1158 msgid "rendition" msgstr "" -#: pod/video/models.py:1064 +#: pod/video/models.py:1071 msgid "renditions" msgstr "" -#: pod/video/models.py:1146 pod/video/models.py:1215 pod/video/models.py:1269 +#: pod/video/models.py:1153 pod/video/models.py:1222 pod/video/models.py:1276 msgid "Please use the only format in encoding choices:" msgstr "" -#: pod/video/models.py:1153 pod/video/models.py:1219 pod/video/models.py:1273 +#: pod/video/models.py:1160 pod/video/models.py:1226 pod/video/models.py:1280 msgid "Format" msgstr "" -#: pod/video/models.py:1157 pod/video/models.py:1221 pod/video/models.py:1275 +#: pod/video/models.py:1164 pod/video/models.py:1228 pod/video/models.py:1282 msgid "Please use the only format in format choices:" msgstr "" -#: pod/video/models.py:1160 pod/video/models.py:1224 pod/video/models.py:1278 +#: pod/video/models.py:1167 pod/video/models.py:1231 pod/video/models.py:1285 msgid "encoding source file" msgstr "" -#: pod/video/models.py:1182 +#: pod/video/models.py:1189 msgid "Encoding video" msgstr "" -#: pod/video/models.py:1183 +#: pod/video/models.py:1190 msgid "Encoding videos" msgstr "" -#: pod/video/models.py:1234 +#: pod/video/models.py:1241 msgid "Encoding audio" msgstr "" -#: pod/video/models.py:1235 +#: pod/video/models.py:1242 msgid "Encoding audios" msgstr "" -#: pod/video/models.py:1283 +#: pod/video/models.py:1290 msgid "Video Playlist" msgstr "" -#: pod/video/models.py:1284 +#: pod/video/models.py:1291 msgid "Video Playlists" msgstr "" -#: pod/video/models.py:1330 +#: pod/video/models.py:1337 msgid "Encoding log" msgstr "" -#: pod/video/models.py:1331 +#: pod/video/models.py:1338 msgid "Encoding logs" msgstr "" -#: pod/video/models.py:1341 pod/video/models.py:1346 +#: pod/video/models.py:1348 pod/video/models.py:1353 msgid "Video version" msgstr "" -#: pod/video/models.py:1343 +#: pod/video/models.py:1350 msgid "Video default version." msgstr "" -#: pod/video/models.py:1347 +#: pod/video/models.py:1354 msgid "Video versions" msgstr "" -#: pod/video/models.py:1372 +#: pod/video/models.py:1379 msgid "Encoding steps" msgstr "" -#: pod/video/models.py:1381 pod/video/models.py:1388 pod/video/models.py:1404 +#: pod/video/models.py:1388 pod/video/models.py:1395 pod/video/models.py:1411 #: pod/video/views.py:1314 msgid "Note" msgstr "" -#: pod/video/models.py:1389 +#: pod/video/models.py:1396 msgid "Notes" msgstr "" -#: pod/video/models.py:1400 +#: pod/video/models.py:1407 msgid "Note availibility level" msgstr "" -#: pod/video/models.py:1402 +#: pod/video/models.py:1409 msgid "Select an availability level for the note." msgstr "" -#: pod/video/models.py:1406 +#: pod/video/models.py:1413 msgid "Timestamp" msgstr "" -#: pod/video/models.py:1410 pod/video/models.py:1469 +#: pod/video/models.py:1417 pod/video/models.py:1476 msgid "Date modified" msgstr "" -#: pod/video/models.py:1413 +#: pod/video/models.py:1420 msgid "Advanced Note" msgstr "" -#: pod/video/models.py:1414 +#: pod/video/models.py:1421 msgid "Advanced Notes" msgstr "" -#: pod/video/models.py:1460 +#: pod/video/models.py:1467 msgid "Comment availibility level" msgstr "" -#: pod/video/models.py:1462 +#: pod/video/models.py:1469 msgid "Select an availability level for the comment." msgstr "" -#: pod/video/models.py:1472 +#: pod/video/models.py:1479 msgid "Note comment" msgstr "" -#: pod/video/models.py:1473 +#: pod/video/models.py:1480 msgid "Note comments" msgstr "" -#: pod/video/models.py:1491 +#: pod/video/models.py:1498 msgid "Date for deletion" msgstr "" -#: pod/video/models.py:1494 pod/video/models.py:1576 +#: pod/video/models.py:1501 pod/video/models.py:1583 #: pod/video/templates/videos/video.html:76 #: pod/video/templates/videos/videos.html:8 #: pod/video/templates/videos/videos.html:17 msgid "Videos" msgstr "" -#: pod/video/models.py:1497 +#: pod/video/models.py:1504 msgid "Video to delete" msgstr "" -#: pod/video/models.py:1498 +#: pod/video/models.py:1505 msgid "Videos to delete" msgstr "" -#: pod/video/models.py:1518 pod/video/templates/videos/video-comment.html:9 +#: pod/video/models.py:1525 pod/video/templates/videos/video-comment.html:9 msgid "Comments" msgstr "" -#: pod/video/models.py:1559 +#: pod/video/models.py:1566 msgid "Vote" msgstr "" -#: pod/video/models.py:1560 +#: pod/video/models.py:1567 msgid "Votes" msgstr "" -#: pod/video/models.py:1568 pod/video/templates/videos/category_modal.html:13 +#: pod/video/models.py:1575 pod/video/templates/videos/category_modal.html:13 msgid "Category title" msgstr "" -#: pod/video/models.py:1570 +#: pod/video/models.py:1577 msgid "" "Please choose a title as short and accurate as possible, reflecting the main " "subject / context of the content.(max length : 100 characters)" msgstr "" -#: pod/video/models.py:1596 pod/video/templates/videos/category_modal.html:7 +#: pod/video/models.py:1603 pod/video/templates/videos/category_modal.html:7 msgid "Category" msgstr "" -#: pod/video/models.py:1597 +#: pod/video/models.py:1604 #: pod/video/templates/videos/filter_aside_category.html:14 msgid "Categories" msgstr "" diff --git a/pod/locale/nl/LC_MESSAGES/djangojs.po b/pod/locale/nl/LC_MESSAGES/djangojs.po index c4198fd0c3..7391d8fce7 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: 2021-02-24 09:35+0100\n" +"POT-Creation-Date: 2021-03-11 17:17+0100\n" "PO-Revision-Date: 2021-01-22 12:27+0100\n" "Last-Translator: obado \n" "Language-Team: \n" @@ -47,17 +47,17 @@ msgstr "" #: pod/enrichment/static/js/enrichment.js:72 #: pod/enrichment/static/js/enrichment.js:93 #: pod/enrichment/static/js/enrichment.js:120 -#: pod/enrichment/static/js/enrichment.js:149 pod/main/static/js/main.js:293 -#: pod/main/static/js/main.js:300 pod/main/static/js/main.js:311 -#: pod/main/static/js/main.js:325 +#: pod/enrichment/static/js/enrichment.js:149 pod/main/static/js/main.js:305 +#: pod/main/static/js/main.js:312 pod/main/static/js/main.js:323 +#: pod/main/static/js/main.js:337 #: pod/podfile/static/podfile/js/filewidget.js:365 #: pod/podfile/static/podfile/js/filewidget.js:398 msgid "You are no longer authenticated. Please log in again." msgstr "" #: pod/chapter/static/js/chapters.js:146 -#: pod/enrichment/static/js/enrichment.js:136 pod/main/static/js/main.js:263 -#: pod/main/static/js/main.js:317 +#: pod/enrichment/static/js/enrichment.js:136 pod/main/static/js/main.js:275 +#: pod/main/static/js/main.js:329 msgid "One or more errors have been found in the form." msgstr "" @@ -125,7 +125,7 @@ msgstr "" msgid "Are you sure you want to delete this overlay?" msgstr "" -#: pod/completion/static/js/completion.js:195 pod/main/static/js/main.js:265 +#: pod/completion/static/js/completion.js:195 pod/main/static/js/main.js:277 msgid "Changes have been saved." msgstr "" @@ -355,46 +355,46 @@ msgstr "" msgid "gridErrorText" msgstr "" -#: pod/main/static/js/main.js:244 +#: pod/main/static/js/main.js:256 msgid "Are you sure you want to delete this element?" msgstr "" -#: pod/main/static/js/main.js:286 +#: pod/main/static/js/main.js:298 #: pod/podfile/static/podfile/js/filewidget.js:114 #: pod/podfile/static/podfile/js/filewidget.js:391 msgid "Error during exchange" msgstr "" -#: pod/main/static/js/main.js:286 +#: pod/main/static/js/main.js:298 #: pod/podfile/static/podfile/js/filewidget.js:114 msgid "No data could be stored." msgstr "" -#: pod/main/static/js/main.js:339 +#: pod/main/static/js/main.js:351 msgid "Change your picture" msgstr "" -#: pod/main/static/js/main.js:345 +#: pod/main/static/js/main.js:357 msgid "Add your picture" msgstr "" -#: pod/main/static/js/main.js:443 +#: pod/main/static/js/main.js:453 msgid "text copied" msgstr "" -#: pod/main/static/js/main.js:490 +#: pod/main/static/js/main.js:500 msgid "Errors appear in the form, please correct them" msgstr "" -#: pod/main/static/js/main.js:513 +#: pod/main/static/js/main.js:523 msgid "The file size exceeds the maximum allowed value:" msgstr "" -#: pod/main/static/js/main.js:513 +#: pod/main/static/js/main.js:523 msgid " GB." msgstr "" -#: pod/main/static/js/main.js:528 +#: pod/main/static/js/main.js:538 msgid "The file extension not in the allowed extension:" msgstr "" diff --git a/pod/main/static/css/pod.css b/pod/main/static/css/pod.css index 8c8f024c40..6a0678fd0d 100755 --- a/pod/main/static/css/pod.css +++ b/pod/main/static/css/pod.css @@ -114,6 +114,7 @@ body { padding-top: 3.5rem; color: var(--font-color); background-color: var(--bg-color); + font-family: var(--font-family-sans-serif); } .jumbotron { padding: 1rem 2rem; @@ -483,13 +484,13 @@ div.card a:hover>img { background-color: var(--color-fuzzy-wuzzy-brown); } #base-message-alert,#formalertdiv{ - position:fixed; - top:50%; + position: fixed; + top: 50%; text-align: center; - margin:0 auto; + margin: 0 auto; left: 50%; transform:translate(-50%, 0); - z-index:1000; + z-index: 1000; } /** channel form **/ diff --git a/pod/main/templates/aside.html b/pod/main/templates/aside.html index a5e4d5a040..fbc62cd703 100644 --- a/pod/main/templates/aside.html +++ b/pod/main/templates/aside.html @@ -4,14 +4,14 @@ {% if HIDE_SHARE == False %}
-
- {% trans 'Share' %} -
-

- - - -

+
+  {% trans 'Share' %} +
+

+ + + +

{% endif %} {% if HIDE_DISCIPLINES == False %} @@ -24,10 +24,10 @@
@@ -46,9 +46,9 @@
{% tag_cloud_for_model video.Video as tagscloud with distribution=log steps=16 min_count=4 %} {% with tagslist=tagscloud|dictsortreversed:"count"|slice:":20" %} {% for tag in tagslist %} - - {{tag.name}} {{tag.count}} - + + {{tag.name}} {{tag.count}} + {% endfor %} {% endwith %}

diff --git a/pod/main/templates/navbar.html b/pod/main/templates/navbar.html index 8dd4cb4efe..b947b23832 100644 --- a/pod/main/templates/navbar.html +++ b/pod/main/templates/navbar.html @@ -138,27 +138,32 @@
{% endif %}{% if DARKMODE_ENABLED == True or DYSLEXIAMODE_ENABLED == True %} -
- {% if DARKMODE_ENABLED == True %} - {% endif %} - {% if DYSLEXIAMODE_ENABLED == True %} - {% endif %}
{% endif %} +
+ {% if DARKMODE_ENABLED == True %} + + {% endif %}{% if DYSLEXIAMODE_ENABLED == True %} + + {% endif %} +
+ {% endif %}
{% endspaceless %} diff --git a/pod/main/templates/navbar_collapse.html b/pod/main/templates/navbar_collapse.html index 58c286b9d0..3ba87f96ec 100644 --- a/pod/main/templates/navbar_collapse.html +++ b/pod/main/templates/navbar_collapse.html @@ -13,29 +13,29 @@
`; diff --git a/pod/video/templates/videos/card.html b/pod/video/templates/videos/card.html index 2e6c67bf95..5ea93e8baa 100644 --- a/pod/video/templates/videos/card.html +++ b/pod/video/templates/videos/card.html @@ -1,79 +1,77 @@ {% load i18n %} {% spaceless %}
-
-
- {{video.duration_in_time}} - - {% if video.password or video.is_restricted %} - - - - {% endif %} +
+
+ {{video.duration_in_time}} + + {% if video.password or video.is_restricted %} + + + + {% endif %} - {% if video.is_draft %} - - - - {% endif %} - {% if video.chapter_set.all %} - - - - {% endif %} - {% if video.is_video %} - - - - {% else %} - - - - {% endif %} - -
+ {% if video.is_draft %} + + + + {% endif %} + {% if video.chapter_set.all %} + + + + {% endif %} + {% if video.is_video %} + + + + {% else %} + + + + {% endif %} +
-
+
+
{% if channel %} - {% if theme %} - - {{video.get_thumbnail_card|safe}} - - {% else %} - - {{video.get_thumbnail_card|safe}} - - {% endif %} + {% if theme %} + + {{video.get_thumbnail_card|safe}} + + {% else %} + + {{video.get_thumbnail_card|safe}} + + {% endif %} {% else %} - + {{video.get_thumbnail_card|safe}} - + {% endif %} -
-
- - {% if video.owner == request.user or request.user.is_superuser or perms.video.change_video or request.user in video.additional_owners.all %} +
+
+ {% if video.owner == request.user or request.user.is_superuser or perms.video.change_video or request.user in video.additional_owners.all %}
{% include "videos/link_video.html" %}
- {% endif %} + {% endif %} - - {% if channel %} + + {% if channel %} {% if theme %} - + {{video.title|capfirst|truncatechars:43}} - + {% else %} - + {{video.title|capfirst|truncatechars:43}} - + {% endif %} - {% else %} + {% else %} {{video.title|capfirst|truncatechars:43}} - {% endif %} - - -
+ {% endif %} +
+
{% endspaceless %} From 4c2eeef6d3198933e62596690a719c868e2ba051 Mon Sep 17 00:00:00 2001 From: Olivier Bado Date: Fri, 12 Mar 2021 10:58:47 +0100 Subject: [PATCH 092/261] CSS/JS : now alert-info will also fade out after 5s, like alert-succes + each alert has right color, not all in green 'succes' like --- pod/main/static/js/main.js | 580 ++++++++++++------------- pod/video/static/css/comment-style.css | 134 +++--- 2 files changed, 360 insertions(+), 354 deletions(-) diff --git a/pod/main/static/js/main.js b/pod/main/static/js/main.js index 7ae56c20e3..ba8dd8a59f 100644 --- a/pod/main/static/js/main.js +++ b/pod/main/static/js/main.js @@ -148,134 +148,134 @@ $('.collapsibleThemes').on('hidden.bs.collapse', function () { $(this).parents("li").find('.chevron-down').attr('style', ''); }) $('#ownerboxnavbar').keyup(function() { - if($(this).val() && $(this).val().length > 2) { - var searchTerm = $(this).val(); - $.ajax( - { - type: "GET", - url: "/ajax_calls/search_user?term=" + searchTerm, - cache: false, - success: function (response) { - $("#accordion").html(""); - response.forEach(elt => { - $("#accordion").append('
  • '+elt.first_name+' '+elt.last_name+((!HIDE_USERNAME)?' ('+elt.username+')
  • ': '')); - }) - } - } - ); - - } else { - $("#accordion").html(""); - } + if($(this).val() && $(this).val().length > 2) { + var searchTerm = $(this).val(); + $.ajax( + { + type: "GET", + url: "/ajax_calls/search_user?term=" + searchTerm, + cache: false, + success: function (response) { + $("#accordion").html(""); + response.forEach(elt => { + $("#accordion").append('
  • '+elt.first_name+' '+elt.last_name+((!HIDE_USERNAME)?' ('+elt.username+')
  • ': '')); + }) + } + } + ); + + } else { + $("#accordion").html(""); + } }); /** MENU ASIDE **/ $(document).ready(function () { - //.collapseAside is on the toggle button - //#collapseAside is the side menu - - // Fired when #collapseAside has been made visible - $("#collapseAside").on('shown.bs.collapse', function () { - Cookies.set('activeCollapseAside', "open"); - $(".collapseAside").html(''); - feather.replace({ class: 'align-bottom'}); - $("#mainContent").addClass("col-md-9"); - }); - // Fired when #collapseAside has been hidden - $("#collapseAside").on('hidden.bs.collapse', function () { - Cookies.set('activeCollapseAside', "close"); - $(".collapseAside").html(''); - feather.replace({ class: 'align-bottom'}); - $("#mainContent").removeClass("col-md-9"); - }); + //.collapseAside is on the toggle button + //#collapseAside is the side menu + + // Fired when #collapseAside has been made visible + $("#collapseAside").on('shown.bs.collapse', function () { + Cookies.set('activeCollapseAside', "open"); + $(".collapseAside").html(''); + feather.replace({ class: 'align-bottom'}); + $("#mainContent").addClass("col-md-9"); + }); + // Fired when #collapseAside has been hidden + $("#collapseAside").on('hidden.bs.collapse', function () { + Cookies.set('activeCollapseAside', "close"); + $(".collapseAside").html(''); + feather.replace({ class: 'align-bottom'}); + $("#mainContent").removeClass("col-md-9"); + }); - // If aside menu is empty, hide container and button - if ($("#collapseAside").find("div").length == 0) { - $(".collapseAside").hide(); - $("#collapseAside").collapse('hide'); - // Destroy collapse object - $("#collapseAside").collapse('dispose'); - $("#mainContent").removeClass("col-md-9"); + // If aside menu is empty, hide container and button + if ($("#collapseAside").find("div").length == 0) { + $(".collapseAside").hide(); + $("#collapseAside").collapse('hide'); + // Destroy collapse object + $("#collapseAside").collapse('dispose'); + $("#mainContent").removeClass("col-md-9"); + } else { + // Use the last aside state, stored in Cookies + var last = Cookies.get('activeCollapseAside'); + if (last != null && last=="close") { + $("#collapseAside").collapse('hide'); + $(".collapseAside").html(''); + feather.replace({ class: 'align-bottom'}); + $("#mainContent").removeClass("col-md-9"); } else { - // Use the last aside state, stored in Cookies - var last = Cookies.get('activeCollapseAside'); - if (last != null && last=="close") { - $("#collapseAside").collapse('hide'); - $(".collapseAside").html(''); - feather.replace({ class: 'align-bottom'}); - $("#mainContent").removeClass("col-md-9"); - } else { - $("#collapseAside").collapse('show'); - } + $("#collapseAside").collapse('show'); } - TriggerAlertClose(); + } + TriggerAlertClose(); }); function TriggerAlertClose() { - // Automatically hide success type alerts - // (alert-warning and alert-danger will remain on screen) - window.setTimeout(function () { - $(".alert.alert-success").fadeTo(1000, 0).slideUp(1000, function () { - $(this).remove(); - }); - }, 5000); + // Automatically hide success type alerts + // (alert-warning and alert-danger will remain on screen) + window.setTimeout(function () { + $(".alert.alert-success, .alert.alert-info").fadeTo(1000, 0).slideUp(1000, function () { + $(this).remove(); + }); + }, 5000); } /*** FORM THEME USER PICTURE ***/ /** PICTURE **/ $(document).on("click", ".get_form_userpicture", function() { - send_form_data($(this).data('url'), {}, "append_picture_form", "get"); + send_form_data($(this).data('url'), {}, "append_picture_form", "get"); }); $(document).on('hidden.bs.modal', '#userpictureModal', function (e) { - $('#userpictureModal').remove(); - $('#fileModal_id_userpicture').remove(); + $('#userpictureModal').remove(); + $('#fileModal_id_userpicture').remove(); }); $(document).on("submit", "#userpicture_form", function (e) { - e.preventDefault(); - var data_form = $( "#userpicture_form" ).serializeArray(); - send_form_data($( "#userpicture_form" ).attr("action"), data_form, "show_picture_form"); + e.preventDefault(); + var data_form = $( "#userpicture_form" ).serializeArray(); + send_form_data($( "#userpicture_form" ).attr("action"), data_form, "show_picture_form"); }); /** THEME **/ $(document).on("submit", "#form_theme", function (e) { - e.preventDefault(); - var data_form = $( "#form_theme" ).serializeArray(); - send_form_data($( "#form_theme" ).attr("action"), data_form, "show_theme_form"); + e.preventDefault(); + var data_form = $( "#form_theme" ).serializeArray(); + send_form_data($( "#form_theme" ).attr("action"), data_form, "show_theme_form"); }); $(document).on('click', '#cancel_theme', function(){ - $('form.get_form_theme').show(); - show_form_theme(""); - $("#table_list_theme tr").removeClass('table-primary'); - window.scrollTo({ - top: parseInt($("#list_theme").offset().top), - behavior: "smooth" - }); + $('form.get_form_theme').show(); + show_form_theme(""); + $("#table_list_theme tr").removeClass('table-primary'); + window.scrollTo({ + top: parseInt($("#list_theme").offset().top), + behavior: "smooth" + }); }); $(document).on("submit", "form.get_form_theme", function (e) { - e.preventDefault(); - var action = $(this).find('input[name=action]').val(); // new, modify and delete - if(action == "delete"){ - var deleteConfirm = confirm(gettext("Are you sure you want to delete this element?")); - if (deleteConfirm){ - send_form_data(window.location.href, $(this).serializeArray(), "show_form_theme_"+action); - } - } else { - send_form_data(window.location.href, $(this).serializeArray(), "show_form_theme_"+action); + e.preventDefault(); + var action = $(this).find('input[name=action]').val(); // new, modify and delete + if(action == "delete"){ + var deleteConfirm = confirm(gettext("Are you sure you want to delete this element?")); + if (deleteConfirm){ + send_form_data(window.location.href, $(this).serializeArray(), "show_form_theme_"+action); } + } else { + send_form_data(window.location.href, $(this).serializeArray(), "show_form_theme_"+action); + } }); /** VIDEO DEFAULT VERSION **/ $(document).on("change", "#video_version_form input[type=radio][name=version]", function (e) { - $('#video_version_form').submit(); + $('#video_version_form').submit(); }); $(document).on("submit", "#video_version_form", function (e) { - e.preventDefault(); - var data_form = $( "#video_version_form" ).serializeArray(); - send_form_data($( "#video_version_form" ).attr("action"), data_form, "result_video_form"); + e.preventDefault(); + var data_form = $( "#video_version_form" ).serializeArray(); + send_form_data($( "#video_version_form" ).attr("action"), data_form, "result_video_form"); }); var result_video_form = function(data) { - if(data.errors){ - showalert(gettext('One or more errors have been found in the form.'), "alert-danger"); - } else { - showalert(gettext('Changes have been saved.'), 'alert-info'); - } + if(data.errors){ + showalert(gettext('One or more errors have been found in the form.'), "alert-danger"); + } else { + showalert(gettext('Changes have been saved.'), 'alert-info'); + } } /** FOLDER **/ @@ -286,135 +286,133 @@ var send_form_data = function(url,data_form, fct, method, callbackSuccess=undefi callbackFail = typeof(callbackFail) === 'function'? callbackFail : function($xhr){}; method = method || "post"; - var jqxhr= ''; - if(method=="post") jqxhr = $.post(url, data_form); - else jqxhr = $.get(url); - jqxhr.done(function($data){ - $data = callbackSuccess($data); - window[fct]($data); - }); - jqxhr.fail(function($xhr) { - var data = $xhr.status+ " : " +$xhr.statusText; - showalert(gettext("Error during exchange") + "("+data+")
    "+gettext("No data could be stored."), "alert-danger"); - callbackFail($xhr); - }); + var jqxhr= ''; + if(method=="post") jqxhr = $.post(url, data_form); + else jqxhr = $.get(url); + jqxhr.done(function($data){ + $data = callbackSuccess($data); + window[fct]($data); + }); + jqxhr.fail(function($xhr) { + var data = $xhr.status+ " : " +$xhr.statusText; + showalert(gettext("Error during exchange") + "("+data+")
    "+gettext("No data could be stored."), "alert-danger"); + callbackFail($xhr); + }); } var show_form_theme_new = function(data) { - if(data.indexOf("form_theme")==-1) { - showalert(gettext('You are no longer authenticated. Please log in again.'), "alert-danger"); - } else { - show_form_theme(data); - } + if(data.indexOf("form_theme")==-1) { + showalert(gettext('You are no longer authenticated. Please log in again.'), "alert-danger"); + } else { + show_form_theme(data); + } } var show_form_theme_modify = function(data) { - if(data.indexOf("theme")==-1) { - showalert(gettext('You are no longer authenticated. Please log in again.'), "alert-danger"); - } else { - show_form_theme(data); - var id = $(data).find('#id_theme').val(); - $("#theme_"+id).addClass('table-primary'); - } + if(data.indexOf("theme")==-1) { + showalert(gettext('You are no longer authenticated. Please log in again.'), "alert-danger"); + } else { + show_form_theme(data); + var id = $(data).find('#id_theme').val(); + $("#theme_"+id).addClass('table-primary'); + } } var show_form_theme_delete = function(data) { - if(data.list_element) { - show_list_theme(data.list_element); - } else { - showalert(gettext('You are no longer authenticated. Please log in again.'), "alert-danger"); - } + if(data.list_element) { + show_list_theme(data.list_element); + } else { + showalert(gettext('You are no longer authenticated. Please log in again.'), "alert-danger"); + } } var show_theme_form = function(data) { - if(data.list_element || data.form) { - if(data.errors){ - showalert(gettext('One or more errors have been found in the form.'), "alert-danger"); - show_form_theme(data.form); - }else{ - show_form_theme(""); - $('form.get_form_theme').show(); - show_list_theme(data.list_element); - } + if(data.list_element || data.form) { + if(data.errors){ + showalert(gettext('One or more errors have been found in the form.'), "alert-danger"); + show_form_theme(data.form); } else { - showalert(gettext('You are no longer authenticated. Please log in again.'), "alert-danger"); + show_form_theme(""); + $('form.get_form_theme').show(); + show_list_theme(data.list_element); } + } else { + showalert(gettext('You are no longer authenticated. Please log in again.'), "alert-danger"); + } } var show_picture_form = function(data) { - $( "#userpicture_form" ).html($(data).find("#userpicture_form").html()); - if($(data).find("#userpictureurl").val()) { - //$(".get_form_userpicture").html('Change your picture'); - $("#navbarDropdown .userpicture").remove(); - $("#navbarDropdown .userinitial").hide(); - $("#navbarDropdown").removeClass('initials'); - $("#navbarDropdown").append( - 'avatar' - ); - $('.get_form_userpicture').html($('.get_form_userpicture').children()); - $(".get_form_userpicture").append(' '+gettext('Change your picture')); - } else { - $("#navbarDropdown .userpicture").remove(); - $("#navbarDropdown .userinitial").show(); - $("#navbarDropdown").addClass('initials'); - $('.get_form_userpicture').html($('.get_form_userpicture').children()); - $(".get_form_userpicture").html(' '+gettext('Add your picture')); - } - $('#userpictureModal').modal('hide'); + $( "#userpicture_form" ).html($(data).find("#userpicture_form").html()); + if($(data).find("#userpictureurl").val()) { + //$(".get_form_userpicture").html('Change your picture'); + $("#navbarDropdown .userpicture").remove(); + $("#navbarDropdown .userinitial").hide(); + $("#navbarDropdown").removeClass('initials'); + $("#navbarDropdown").append( + 'avatar' + ); + $('.get_form_userpicture').html($('.get_form_userpicture').children()); + $(".get_form_userpicture").append(' '+gettext('Change your picture')); + } else { + $("#navbarDropdown .userpicture").remove(); + $("#navbarDropdown .userinitial").show(); + $("#navbarDropdown").addClass('initials'); + $('.get_form_userpicture').html($('.get_form_userpicture').children()); + $(".get_form_userpicture").html(' '+gettext('Add your picture')); + } + $('#userpictureModal').modal('hide'); } var append_picture_form = function(data) { - $('body').append(data); - $('#userpictureModal').modal('show'); + $('body').append(data); + $('#userpictureModal').modal('show'); } function show_form_theme(data) { - $("#div_form_theme").hide().html(data).fadeIn(); - if(data!="") $('form.get_form_theme').hide(); - window.scrollTo({ - top: parseInt($("#div_form_theme").offset().top), - behavior: "smooth" - }); + $("#div_form_theme").hide().html(data).fadeIn(); + if(data!="") $('form.get_form_theme').hide(); + window.scrollTo({ + top: parseInt($("#div_form_theme").offset().top), + behavior: "smooth" + }); } function show_list_theme(data) { - $("#list_theme").hide().html(data).fadeIn(); - //$('form.get_form_theme').show(); - window.scrollTo({ - top: parseInt($("#list_theme").offset().top), - behavior: "smooth" - }); + $("#list_theme").hide().html(data).fadeIn(); + //$('form.get_form_theme').show(); + window.scrollTo({ + top: parseInt($("#list_theme").offset().top), + behavior: "smooth" + }); } /***** VIDEOS *****/ $('#ownerbox').keyup(function() { if($(this).val() && $(this).val().length > 2) { var searchTerm = $(this).val(); - $.ajax( - { - type: "GET", - url: "/ajax_calls/search_user?term=" + searchTerm, - cache: false, - success: function (response) { - $("#collapseFilterOwner .added").each(function(index){ - var c = $(this).find("input"); - if(!c.prop("checked")){ - $(this).remove(); - } - }) - - - - response.forEach(elt => { - if (listUserChecked.indexOf(elt.username)==-1 && $("#collapseFilterOwner #id" + elt.username).length == 0) { - let username = HIDE_USERNAME?'':(' ('+elt.username+')'); - var chekboxhtml = '
    '; - $("#collapseFilterOwner").append(chekboxhtml); - } - }) - } - } - ); + $.ajax( + { + type: "GET", + url: "/ajax_calls/search_user?term=" + searchTerm, + cache: false, + success: function (response) { + $("#collapseFilterOwner .added").each(function(index){ + var c = $(this).find("input"); + if(!c.prop("checked")){ + $(this).remove(); + } + }) + + response.forEach(elt => { + if (listUserChecked.indexOf(elt.username)==-1 && $("#collapseFilterOwner #id" + elt.username).length == 0) { + let username = HIDE_USERNAME?'':(' ('+elt.username+')'); + var chekboxhtml = '
    '; + $("#collapseFilterOwner").append(chekboxhtml); + } + }) + } + } + ); } else { $("#collapseFilterOwner .added").each(function(index){ - var c = $(this).find("input"); - if(!c.prop("checked")){ - $(this).remove(); - } + var c = $(this).find("input"); + if(!c.prop("checked")){ + $(this).remove(); + } }) } }); @@ -424,7 +422,7 @@ $('#ownerbox').keyup(function() { var tab_initial = new Array(); $('#id_theme option:selected').each(function () { - tab_initial.push($(this).val()); + tab_initial.push($(this).val()); }); $('#id_theme option').remove(); @@ -432,57 +430,57 @@ $('#id_theme option').remove(); //$('#id_channel').change(function() { // use click instead of change due to select2 usage : https://github.com/theatlantic/django-select2-forms/blob/master/select2/static/select2/js/select2.js#L1502 $('#id_channel').on('click', function (e) { - $('#id_theme option').remove(); - var tab_channel_selected = $(this).val(); - var str = ""; - for (var id in tab_channel_selected) { - var chan = $("#id_channel option[value="+tab_channel_selected[id]+"]").text(); - str += get_list(listTheme["channel_"+tab_channel_selected[id]], 0, [], tag_type="option", li_class="", attrs='', add_link=false, current="", channel=chan+": "); - } - $('#id_theme').append(str); + $('#id_theme option').remove(); + var tab_channel_selected = $(this).val(); + var str = ""; + for (var id in tab_channel_selected) { + var chan = $("#id_channel option[value="+tab_channel_selected[id]+"]").text(); + str += get_list(listTheme["channel_"+tab_channel_selected[id]], 0, [], tag_type="option", li_class="", attrs='', add_link=false, current="", channel=chan+": "); + } + $('#id_theme').append(str); }); $("#id_channel option:selected").each(function () { - var str = get_list(listTheme["channel_"+$(this).val()], 0, tab_initial, tag_type="option", li_class="", attrs='', add_link=false, current=""); - $('#id_theme').append(str); + var str = get_list(listTheme["channel_"+$(this).val()], 0, tab_initial, tag_type="option", li_class="", attrs='', add_link=false, current=""); + $('#id_theme').append(str); }); /** end channel **/ /*** Copy to clipboard ***/ $('#btnpartageprive').click(function() { - var copyText = document.getElementById("txtpartageprive"); - copyText.select(); - document.execCommand("copy"); - showalert(gettext("text copied"),"alert-info"); - }); + var copyText = document.getElementById("txtpartageprive"); + copyText.select(); + document.execCommand("copy"); + showalert(gettext("text copied"),"alert-info"); +}); /** Restrict access **/ /** restrict access to group */ $("#id_is_restricted").change(function () { - restrict_access_to_groups(); + restrict_access_to_groups(); }) var restrict_access_to_groups = function () { - if ($('#id_is_restricted').prop("checked")) { - $("#id_restrict_access_to_groups").parents(".restricted_access").show(); - } else { - $("#id_restrict_access_to_groups option:selected").prop("selected", false); - $("#id_restrict_access_to_groups").parents(".restricted_access").hide(); - } + if ($('#id_is_restricted').prop("checked")) { + $("#id_restrict_access_to_groups").parents(".restricted_access").show(); + } else { + $("#id_restrict_access_to_groups option:selected").prop("selected", false); + $("#id_restrict_access_to_groups").parents(".restricted_access").hide(); + } } $('#id_is_draft').change(function(){ - restricted_access(); + restricted_access(); }); var restricted_access = function() { - if($('#id_is_draft').prop( "checked" )){ - $('.restricted_access').addClass('hide'); - $('.restricted_access').removeClass('show'); - $("#id_password").val(''); - $("#id_restrict_access_to_groups option:selected").prop("selected", false); - $("#id_is_restricted").prop( "checked", false ); - } else { - $('.restricted_access').addClass('show'); - $('.restricted_access').removeClass('hide'); - } - restrict_access_to_groups(); + if($('#id_is_draft').prop( "checked" )){ + $('.restricted_access').addClass('hide'); + $('.restricted_access').removeClass('show'); + $("#id_password").val(''); + $("#id_restrict_access_to_groups option:selected").prop("selected", false); + $("#id_is_restricted").prop( "checked", false ); + } else { + $('.restricted_access').addClass('show'); + $('.restricted_access').removeClass('hide'); + } + restrict_access_to_groups(); } restricted_access(); //restrict_access_to_groups(); @@ -503,9 +501,9 @@ restricted_access(); event.preventDefault(); event.stopPropagation(); } else { - if($(form).data("morecheck")) { - window[$(form).data("morecheck")](form, event); - } + if($(form).data("morecheck")) { + window[$(form).data("morecheck")](form, event); + } } form.classList.add('was-validated'); }, false); @@ -514,70 +512,70 @@ restricted_access(); })(); /*** VIDEOCHECK FORM ***/ var videocheck = function(form,event) { - var fileInput = $('#id_video'); - if(fileInput.get(0).files.length){ - var fileSize = fileInput.get(0).files[0].size; - var fileName = fileInput.get(0).files[0].name; - var extension = fileName.substring(fileName.lastIndexOf('.')+1).toLowerCase(); - if(listext.indexOf(extension) !== -1) { - if(fileSize>video_max_upload_size){ - window.scrollTo($("#video_form").scrollTop(), 0); - showalert(gettext("The file size exceeds the maximum allowed value:")+" "+VIDEO_MAX_UPLOAD_SIZE+ gettext(" GB."),"alert-danger"); - event.preventDefault(); - event.stopPropagation(); - } else { - $("#video_form fieldset").hide(); - $("#video_form button").hide(); - $("#js-process").show(); - window.scrollTo($("#js-process").scrollTop(), 0); - if(!show_progress_bar(form)) { - event.preventDefault(); - event.stopPropagation(); - } - } - } else { - window.scrollTo($("#video_form").scrollTop(), 0); - showalert(gettext("The file extension not in the allowed extension:")+" "+listext+".","alert-danger"); - event.preventDefault(); - event.stopPropagation(); + var fileInput = $('#id_video'); + if(fileInput.get(0).files.length){ + var fileSize = fileInput.get(0).files[0].size; + var fileName = fileInput.get(0).files[0].name; + var extension = fileName.substring(fileName.lastIndexOf('.')+1).toLowerCase(); + if(listext.indexOf(extension) !== -1) { + if(fileSize>video_max_upload_size){ + window.scrollTo($("#video_form").scrollTop(), 0); + showalert(gettext("The file size exceeds the maximum allowed value:")+" "+VIDEO_MAX_UPLOAD_SIZE+ gettext(" GB."),"alert-danger"); + event.preventDefault(); + event.stopPropagation(); + } else { + $("#video_form fieldset").hide(); + $("#video_form button").hide(); + $("#js-process").show(); + window.scrollTo($("#js-process").scrollTop(), 0); + if(!show_progress_bar(form)) { + event.preventDefault(); + event.stopPropagation(); } + } + } else { + window.scrollTo($("#video_form").scrollTop(), 0); + showalert(gettext("The file extension not in the allowed extension:")+" "+listext+".","alert-danger"); + event.preventDefault(); + event.stopPropagation(); } + } } /***** SHOW ALERT *****/ var showalert = function(message,alerttype) { - $('body').append(''); - setTimeout(function() { $("#formalertdiv").remove(); }, 5000); + $('body').append(''); + setTimeout(function() { $("#formalertdiv").remove(); }, 5000); }; function show_messages(msgText, msgClass, loadUrl) { - var $msgContainer = $('#show_messages'); - var close_button = ''; - msgClass = typeof msgClass !== 'undefined' ? msgClass : 'warning'; - loadUrl = typeof loadUrl !== 'undefined' ? loadUrl : false; - - if (!loadUrl) { - close_button = ''; - } - - var $msgBox = $('
    ', { - 'class': 'alert alert-' + msgClass + ' alert-dismissable fade in', - 'role': 'alert', - 'html': close_button + msgText - }); - $msgContainer.html($msgBox); - - if (loadUrl) { - $msgBox.delay(4000).fadeOut(function() { - if (loadUrl) { - window.location.reload(); - } else { - window.location.assign(loadUrl); - } - }); - } else if ( msgClass === 'info' || msgClass === 'success') { - $msgBox.delay(3000).fadeOut(function() { - $msgBox.remove(); - }); - } + var $msgContainer = $('#show_messages'); + var close_button = ''; + msgClass = typeof msgClass !== 'undefined' ? msgClass : 'warning'; + loadUrl = typeof loadUrl !== 'undefined' ? loadUrl : false; + + if (!loadUrl) { + close_button = ''; + } + + var $msgBox = $('
    ', { + 'class': 'alert alert-' + msgClass + ' alert-dismissable fade in', + 'role': 'alert', + 'html': close_button + msgText + }); + $msgContainer.html($msgBox); + + if (loadUrl) { + $msgBox.delay(4000).fadeOut(function() { + if (loadUrl) { + window.location.reload(); + } else { + window.location.assign(loadUrl); + } + }); + } else if ( msgClass === 'info' || msgClass === 'success') { + $msgBox.delay(3000).fadeOut(function() { + $msgBox.remove(); + }); + } } diff --git a/pod/video/static/css/comment-style.css b/pod/video/static/css/comment-style.css index 3c5dd167ea..d307dc70c3 100644 --- a/pod/video/static/css/comment-style.css +++ b/pod/video/static/css/comment-style.css @@ -2,8 +2,8 @@ --primary-background-color: #f8f9fa; --secondary-background-color: #f3f3f3; --third-background-color: rgb(255, 255, 255); - --content-primary-color: rgba(6, 14, 29, 0.75); - --content-secondary-color: rgba(54, 56, 58, 0.65); + --content-primary-color: rgba(6, 14, 29, .75); + --content-secondary-color: rgba(54, 56, 58, .65); --content-third-color: rgb(156, 154, 154); --background-color: #ccc; --padding-comment-content: 25px; @@ -14,10 +14,10 @@ } .comment_disable { text-align: center; - padding: 0.4em 0.8em; + padding: .4em .8em; color: #386066; background: #afe0e8; - margin-top: 0.8em; + margin-top: .8em; display: -webkit-box; display: -ms-flexbox; display: flex; @@ -54,8 +54,8 @@ .reply_to { letter-spacing: 1.1px; color: var(--content-third-color) !important; - margin-bottom: 0.8em; - margin-left: 0.8em; + margin-bottom: .8em; + margin-left: .8em; } .reply_to svg { width: 16px; @@ -154,15 +154,15 @@ right: 20px; font-size: 16px; color: #fff; - -webkit-animation: up 1s cubic-bezier(0.77, 0, 0.18, 1) forwards; - animation: up 1s cubic-bezier(0.77, 0, 0.18, 1) forwards; + -webkit-animation: up 1s cubic-bezier(.77, 0, .18, 1) forwards; + animation: up 1s cubic-bezier(.77, 0, .18, 1) forwards; -webkit-animation-direction: normal; animation-direction: normal; z-index: 9; } .alert_close { - -webkit-animation: down 1s cubic-bezier(0.77, 0, 0.18, 1) forwards; - animation: down 1s cubic-bezier(0.77, 0, 0.18, 1) forwards; + -webkit-animation: down 1s cubic-bezier(.77, 0, .18, 1) forwards; + animation: down 1s cubic-bezier(.77, 0, .18, 1) forwards; } .alert_success { background-color: #99c93d; @@ -186,41 +186,49 @@ @-webkit-keyframes down { 0% { bottom: 20px; - background-color: rgba(153, 201, 61, 1); + /*background-color: rgba(153, 201, 61, 1);*/ + opacity: 1; } 100% { bottom: -100%; - background-color: rgba(153, 201, 61, 0); + opacity: 0; + /*background-color: rgba(153, 201, 61, 0);*/ } } @keyframes down { 0% { bottom: 20px; - background-color: rgba(153, 201, 61, 1); + /*background-color: rgba(153, 201, 61, 1);*/ + opacity: 1; } 100% { bottom: -100%; - background-color: rgba(153, 201, 61, 0); + /*background-color: rgba(153, 201, 61, 0);*/ + opacity: 0; } } @-webkit-keyframes up { 0% { bottom: -100%; - background-color: rgba(153, 201, 61, 0.1); + /*background-color: rgba(153, 201, 61, .1);*/ + opacity: .1; } 100% { bottom: 20px; - background-color: rgba(153, 201, 61, 1); + /*background-color: rgba(153, 201, 61, 1);*/ + opacity: 1; } } @keyframes up { 0% { bottom: -100%; - background-color: rgba(153, 201, 61, 0.1); + /*background-color: rgba(153, 201, 61, .1);*/ + opacity: .1; } 100% { bottom: 20px; - background-color: rgba(153, 201, 61, 1); + /*background-color: rgba(153, 201, 61, 1);*/ + opacity: 1; } } /* End Alert message */ @@ -242,7 +250,7 @@ top: 0; bottom: 0; min-height: 100vh; - background-color: rgba(54, 56, 58, 0.5); + background-color: rgba(54, 56, 58, .5); } .comment_main .confirm_delete.show { display: -webkit-box; @@ -262,9 +270,9 @@ width: 500px; background-color: #fff; border-radius: 4px; - padding: 0.8em; - -webkit-box-shadow: 2px 2px 4px rgba(54, 56, 58, 0.6); - box-shadow: 2px 2px 4px rgba(54, 56, 58, 0.6); + padding: .8em; + -webkit-box-shadow: 2px 2px 4px rgba(54, 56, 58, .6); + box-shadow: 2px 2px 4px rgba(54, 56, 58, .6); } .comment_main .confirm_delete_container .confirm_title { text-align: center; @@ -274,8 +282,8 @@ border: none; text-align: center; font-size: 16px; - padding-top: 0.8em; - padding-bottom: 0.4em; + padding-top: .8em; + padding-bottom: .4em; font-weight: 400; } .comment_main .confirm_delete_container .actions { @@ -287,21 +295,21 @@ -webkit-box-align: center; -ms-flex-align: center; align-items: center; - padding: 0.8em 0; + padding: .8em 0; } .comment_main .confirm_delete_container .actions .delete, .comment_main .confirm_delete_container .actions .cancel { border: 1px solid var(--red-color); background-color: var(--red-color); color: #fff; - padding: 0.8em 2em; + padding: .8em 2em; border-radius: 4px; -webkit-box-shadow: 0 4px 8px var(--content-third-color); box-shadow: 0 4px 8px var(--content-third-color); cursor: pointer; - -webkit-transition: 0.3s box-shadow; - -o-transition: 0.3s box-shadow; - transition: 0.3s box-shadow; + -webkit-transition: .3s box-shadow; + -o-transition: .3s box-shadow; + transition: .3s box-shadow; font-weight: 600; } .comment_main .confirm_delete_container .actions .cancel { @@ -348,7 +356,7 @@ } .comment_main .add_comment .form-wrapper .new_comment.new_parent_comment { border: 1px solid var(--background-color); - padding: 0.4em 0.8em; + padding: .4em .8em; border-radius: 4px; } .comment_main .add_comment .new_comment::-webkit-input-placeholder { @@ -379,12 +387,12 @@ box-shadow: 0 4px 8px var(--content-third-color); outline: none; color: #fff; - padding: 0.4em 0.8em; - margin-top: 0.4em; + padding: .4em .8em; + margin-top: .4em; cursor: pointer; - -webkit-transition: 0.3s all; - -o-transition: 0.3s all; - transition: 0.3s all; + -webkit-transition: .3s all; + -o-transition: .3s all; + transition: .3s all; text-transform: uppercase; font-weight: 600; } @@ -426,7 +434,7 @@ -ms-flex-pack: justify; justify-content: space-between; border-left: 4px solid var(--primary); - padding: 0.4em; + padding: .4em; background-color: var(--third-background-color); -webkit-box-shadow: 2px 2px 12px #e6e2e2; box-shadow: 2px 2px 12px #e6e2e2; @@ -439,9 +447,9 @@ > .comments_children_container { height: 0; overflow: hidden; - -webkit-transition: 0.5s height; - -o-transition: 0.5s height; - transition: 0.5s height; + -webkit-transition: .5s height; + -o-transition: .5s height; + transition: .5s height; } .comment_main .comment_element.show @@ -457,7 +465,7 @@ display: -webkit-box; display: -ms-flexbox; display: flex; - margin-top: calc(var(--margin-between-comment) - 0.2em); + margin-top: calc(var(--margin-between-comment) - .2em); } .comment_main .comment_element > .comment.onDelete, .comment_main @@ -516,7 +524,7 @@ overflow: hidden; -o-text-overflow: ellipsis; text-overflow: ellipsis; - margin-bottom: 0.8em; + margin-bottom: .8em; } .comment_main .comment .comment_content_body .comment_text { font-weight: 500; @@ -558,9 +566,9 @@ -ms-flex-align: center; align-items: center; color: var(--content-third-color); - -webkit-transition: 0.3s color; - -o-transition: 0.3s color; - transition: 0.3s color; + -webkit-transition: .3s color; + -o-transition: .3s color; + transition: .3s color; font-weight: 400; } .comment_main .comment .comment_content_footer .comment_actions:hover { @@ -581,7 +589,7 @@ -webkit-box-align: center; -ms-flex-align: center; align-items: center; - margin-right: 0.4em; + margin-right: .4em; } .comment_main .comment @@ -619,9 +627,9 @@ .comment_main .comment_element .comment_content_footer .form { height: 0; overflow: hidden; - -webkit-transition: 0.5s height; - -o-transition: 0.5s height; - transition: 0.5s height; + -webkit-transition: .5s height; + -o-transition: .5s height; + transition: .5s height; } .comment_main .comment_element .comment_content_footer .form.show { height: 60px; @@ -630,7 +638,7 @@ z-index: 9; width: 100%; border: 1px solid var(--background-color); - padding: 0.8em 0.2em 0; + padding: .8em .2em 0; display: flex; border-radius: 4px; } @@ -679,9 +687,9 @@ } .comment_main .comment .comment_content_footer .add_comment .send_reply { width: 44px; - padding: 0 0.8em; + padding: 0 .8em; flex: none; - transform: translateY(-0.4em); + transform: translateY(-.4em); cursor: default; color: var(--background-color); } @@ -731,8 +739,8 @@ @-webkit-keyframes deletecomment { 0% { position: relative; - -webkit-box-shadow: 0 0 8px 8px rgba(255, 0, 0, 0.3) !important; - box-shadow: 0 0 8px 8px rgba(255, 0, 0, 0.3) !important; + -webkit-box-shadow: 0 0 8px 8px rgba(255, 0, 0, .3) !important; + box-shadow: 0 0 8px 8px rgba(255, 0, 0, .3) !important; z-index: 9999; -webkit-transform: translateX(0); transform: translateX(0); @@ -745,8 +753,8 @@ @keyframes deletecomment { 0% { position: relative; - -webkit-box-shadow: 0 0 8px 8px rgba(255, 0, 0, 0.3) !important; - box-shadow: 0 0 8px 8px rgba(255, 0, 0, 0.3) !important; + -webkit-box-shadow: 0 0 8px 8px rgba(255, 0, 0, .3) !important; + box-shadow: 0 0 8px 8px rgba(255, 0, 0, .3) !important; z-index: 9999; -webkit-transform: translateX(0); transform: translateX(0); @@ -784,21 +792,21 @@ margin: 8px; border: 4px solid #fff; border-radius: 50%; - -webkit-animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite; - animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite; + -webkit-animation: lds-ring 1.2s cubic-bezier(.5, 0, .5, 1) infinite; + animation: lds-ring 1.2s cubic-bezier(.5, 0, .5, 1) infinite; border-color: var(--background-color) transparent transparent transparent; } .lds-ring div:nth-child(1) { - -webkit-animation-delay: -0.45s; - animation-delay: -0.45s; + -webkit-animation-delay: -.45s; + animation-delay: -.45s; } .lds-ring div:nth-child(2) { - -webkit-animation-delay: -0.3s; - animation-delay: -0.3s; + -webkit-animation-delay: -.3s; + animation-delay: -.3s; } .lds-ring div:nth-child(3) { - -webkit-animation-delay: -0.15s; - animation-delay: -0.15s; + -webkit-animation-delay: -.15s; + animation-delay: -.15s; } @-webkit-keyframes lds-ring { 0% { From 0a3246b76411990165887ea8af271a7e2f409cda Mon Sep 17 00:00:00 2001 From: Olivier Bado Date: Fri, 12 Mar 2021 17:23:00 +0100 Subject: [PATCH 093/261] + Replace default.png by a default.svg without background (more adaptable to different themes) + comment some useless styles in dark.css + video/models.py now use "static()" function instead of custom string concat (now default thumbnail will display on other http ports) + add an opacity transition to alerts + code formatting --- README.md | 3 +- pod/custom/settings_local.py.example | 2 +- pod/live/models.py | 2 +- pod/main/static/css/dark.css | 20 +- pod/main/static/css/dyslexia.css | 4 +- pod/main/static/css/pod.css | 8 +- pod/main/static/img/default.png | Bin 27209 -> 0 bytes pod/main/static/img/default.svg | 45 ++++ pod/main/templates/base.html | 4 +- pod/podfile/static/podfile/js/filewidget.js | 2 +- .../templates/podfile/customfilewidget.html | 2 +- pod/video/models.py | 28 +-- pod/video/static/css/comment-style.css | 13 +- pod/video/static/js/comment-script.js | 2 + pod/video/templates/videos/video.html | 222 +++++++++--------- 15 files changed, 197 insertions(+), 160 deletions(-) delete mode 100644 pod/main/static/img/default.png create mode 100644 pod/main/static/img/default.svg diff --git a/README.md b/README.md index ebd612d5bd..3e93cead3e 100644 --- a/README.md +++ b/README.md @@ -12,5 +12,6 @@ Le projet et la plateforme qui porte le même nom ont pour but de faciliter la m | | Ministère de lʼEnseignement supérieur, de la Recherche et de lʼInnovation :-----:|:-----:|:----: - +### Crédits +* static/default.svg : Icon made by Freepik diff --git a/pod/custom/settings_local.py.example b/pod/custom/settings_local.py.example index 1bfedc1401..dd0c836179 100644 --- a/pod/custom/settings_local.py.example +++ b/pod/custom/settings_local.py.example @@ -561,7 +561,7 @@ RESTRICT_EDIT_VIDEO_ACCESS_TO_STAFF_ONLY = False # utilisée pour présenter la vidéo. # Cette image doit se situer dans le répertoire static. """ -DEFAULT_THUMBNAIL = "img/default.png" +DEFAULT_THUMBNAIL = "img/default.svg" """ # Encodage possible sur la plateforme. diff --git a/pod/live/models.py b/pod/live/models.py index fc1a62f4eb..67ad488325 100644 --- a/pod/live/models.py +++ b/pod/live/models.py @@ -21,7 +21,7 @@ from pod.main.models import CustomImageModel DEFAULT_THUMBNAIL = getattr( - settings, 'DEFAULT_THUMBNAIL', 'img/default.png') + settings, 'DEFAULT_THUMBNAIL', 'img/default.svg') class Building(models.Model): diff --git a/pod/main/static/css/dark.css b/pod/main/static/css/dark.css index bc2b1bb63d..d95cf63813 100644 --- a/pod/main/static/css/dark.css +++ b/pod/main/static/css/dark.css @@ -1,3 +1,4 @@ +/** Dark mode for Esup Pod **/ [data-theme="light"] { /* CUSTOM COLORS */ @@ -74,7 +75,7 @@ border-color: var(--dark); color: var(--primary); } -[data-theme="dark"] .btn-primary.focus, +/*[data-theme="dark"] .btn-primary.focus, [data-theme="dark"] .btn-outline-primary:focus, [data-theme="dark"] .btn-outline-primary:active, [data-theme="dark"] .btn-primary:focus, @@ -91,7 +92,7 @@ border-color: var(--primary); box-shadow: none; color: var(--font-color); -} +}*/ [data-theme="dark"] .btn-secondary{ color: var(--white); } @@ -192,7 +193,7 @@ body.dark { position: absolute; right: 0; top: 0; - transition: 0.4s; + transition: .4s; border-radius: 24px; } .slider:before { @@ -202,10 +203,13 @@ body.dark { height: 20px; left: 2px; position: absolute; - transition: 0.4s; + transition: .4s; width: 20px; border-radius: 50%; } +[data-theme="dark"] .slider { + background-color: var(--gray); +} input:checked + .slider { background-color: var(--primary); } @@ -216,21 +220,21 @@ input:checked + .slider:before { color: var(--color-mine-shaft); width: 15px; position: absolute; - transition: opacity 0.2s ease 0s, transform 0.35s ease 0s; + transition: opacity .2s ease 0s, transform .35s ease 0s; pointer-events: none; } .feather-moon { opacity: 0; left: 5px; - bottom: 0px; + bottom: 0; color: var(--white) !important; transform: translateX(4px); } .feather-sun { opacity: 1; right: 5px; - bottom: 0px; - transform: translateX(0px); + bottom: 0; + transform: translateX(0); } input:checked + .slider .feather-moon { opacity: 1; diff --git a/pod/main/static/css/dyslexia.css b/pod/main/static/css/dyslexia.css index b102433e06..dc72615d6f 100644 --- a/pod/main/static/css/dyslexia.css +++ b/pod/main/static/css/dyslexia.css @@ -1,3 +1,5 @@ +/** Dyslexia mode for Esup Pod **/ + /* OpenDyslexic Font via CDN */ @font-face { font-family: "Open Dyslexic"; @@ -38,7 +40,7 @@ opacity: 1; right: 5px; bottom: 0; - transform: translateX(0px); + transform: translateX(0); } input:checked + .slider .feather-eye { opacity: 1; diff --git a/pod/main/static/css/pod.css b/pod/main/static/css/pod.css index 6a0678fd0d..d7348578ce 100755 --- a/pod/main/static/css/pod.css +++ b/pod/main/static/css/pod.css @@ -1,10 +1,5 @@ -/* OpenDyslexic Font via CDN */ -/* @font-face { -font-family: "Open Dyslexic"; -src: url("https://cdn.jsdelivr.net/npm/open-dyslexic@1.0.3/woff/OpenDyslexic-Regular.woff") format("woff"); -} */ +/*** Esup Pod main CSS ***/ -/* @import url('./dyslexie.css') screen; */ /* COMMON COLORS */ :root { --color-transparent:transparent; @@ -61,6 +56,7 @@ src: url("https://cdn.jsdelivr.net/npm/open-dyslexic@1.0.3/woff/OpenDyslexic-Reg } .meta-title{ font-size: 1.2rem; + margin: .5em 0 .2rem 0; } .btn-link { diff --git a/pod/main/static/img/default.png b/pod/main/static/img/default.png deleted file mode 100644 index 4346765c1c3cec09e0102feb5c6a95f57803eb26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27209 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 z⩔LbizsYP#c-1&P-B<%B;^qZw+(sR29$e#x!k)sFSfWYgHf`N$GKS-nG9-`dPy? zG<4j_+LaY!*y&8Y%Q*cTrWh`dMhfjUrn?<=Trq9z^;h=U;UU&W+^Q zI3Y3c#e4TTnlqlJ1rlqQ0|U^Yp8Lb9LBcy!CpTgFZ?aAug5q#9g$KEyMh&M4D) z$n6&*hOBp>4e|J5^(@j2{U;<(G(76`o@GGE%x(JR#Lf$-OM7h z9Y6FeAWk3R^F61=#@vTXU=_FBlEfsHBrJ$?Dk``{2))q6?%JnuQIjZMywaVT?5Cvg zRl;3t=~UBuiKpWH5#zCk4NNX%2y)&+xv)}SPDkNzUS+D>B`;&~9)ogADBi`iVJMC z(ZUc{?!)5otE4xPtKA;n4ej(|&yB?jM|==8BFi@jd{pK9f)ifouio*!b3YCS-3|6p zA^xra=fc;b0n1(3uHLpr>eHL&U*jF`P~sA6+dsu_OJt3E;V=q?Oua~iK9zgHg{e5R zhS=rpm1<#DS{^4EXH~8728GOuWrotyVj${XrE2$x){OYtKm@$ZXq@FQU;Y}+T9as7 z3W&GvRb<7qKOC#H?RmFqw*&WaWj0ciV$E)rRNz^}8mxI%siL6ldqrC;|66aA~vvonZwZ=tT% z7+9{LDCC?(OU<Bn*PtVD6q?);?1%*P&hKZ4oakK^h? z2(#B36-y**48LmXxV--(7~I%!)E`IGkK^hSkvjg~8z{1!`|%j~aa{d4#y&XM@Z(te cz(4>00H@-+_fAp{O8@`>07*qoM6N<$f{O}>^Z)<= diff --git a/pod/main/static/img/default.svg b/pod/main/static/img/default.svg new file mode 100644 index 0000000000..2dcda899f1 --- /dev/null +++ b/pod/main/static/img/default.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + diff --git a/pod/main/templates/base.html b/pod/main/templates/base.html index 0de3704318..7cd959e449 100644 --- a/pod/main/templates/base.html +++ b/pod/main/templates/base.html @@ -30,10 +30,10 @@ {% if DARKMODE_ENABLED == True %} - + {% endif %} {% if DYSLEXIAMODE_ENABLED == True %} - + {% endif %} {% if CSS_OVERRIDE %} diff --git a/pod/podfile/static/podfile/js/filewidget.js b/pod/podfile/static/podfile/js/filewidget.js index 4097a2ba94..5d8321fab2 100644 --- a/pod/podfile/static/podfile/js/filewidget.js +++ b/pod/podfile/static/podfile/js/filewidget.js @@ -23,7 +23,7 @@ if(typeof loaded == 'undefined') { if($(this).data("filetype")=="CustomImageModel"){ html += ''+$(this).attr('title')+' '; } else { - html += ' '; + html += ' '; } html += ''+$(this).attr('title')+' '; $("#fileinput_"+id_input).html(html); diff --git a/pod/podfile/templates/podfile/customfilewidget.html b/pod/podfile/templates/podfile/customfilewidget.html index 10e445473e..7bb7fb9e96 100644 --- a/pod/podfile/templates/podfile/customfilewidget.html +++ b/pod/podfile/templates/podfile/customfilewidget.html @@ -9,7 +9,7 @@ {% if document.class_name == "CustomImageModel" and document.file_exist %}{{document.name}}  {% else %} -   +   {%endif%} {% if document.file_exist %} {{document.name}}  diff --git a/pod/video/models.py b/pod/video/models.py index f8f078dd99..eb7f68000b 100755 --- a/pod/video/models.py +++ b/pod/video/models.py @@ -1,3 +1,5 @@ +"""Esup-Pod Video models.""" + import os import time import unicodedata @@ -17,6 +19,7 @@ from django.core.exceptions import ValidationError from django.core.exceptions import ObjectDoesNotExist from django.contrib.sites.shortcuts import get_current_site +from django.contrib.staticfiles.templatetags.staticfiles import static from django.dispatch import receiver from django.utils.html import format_html from django.db.models.signals import pre_delete @@ -116,7 +119,7 @@ ("playlist", "playlist") )) DEFAULT_THUMBNAIL = getattr( - settings, 'DEFAULT_THUMBNAIL', 'img/default.png') + settings, 'DEFAULT_THUMBNAIL', 'img/default.svg') SECRET_KEY = getattr(settings, 'SECRET_KEY', '') NOTES_STATUS = getattr( @@ -200,7 +203,10 @@ def remove_accents(input_str): def get_storage_path_video(instance, filename): - """ Get the storage path. Instance needs to implement owner """ + """Get the storage path. + + Instance needs to implement owner + """ fname, dot, extension = filename.rpartition('.') try: fname.index("/") @@ -660,11 +666,7 @@ def get_thumbnail_url(self): get_current_site(request).domain, self.thumbnail.file.url]) else: - thumbnail_url = ''.join( - ['//', - get_current_site(request).domain, - settings.STATIC_URL, - DEFAULT_THUMBNAIL]) + thumbnail_url = static(DEFAULT_THUMBNAIL) return thumbnail_url @property @@ -677,11 +679,7 @@ def get_thumbnail_admin(self): # else: - thumbnail_url = ''.join( - ['//', - get_current_site(None).domain, - settings.STATIC_URL, - DEFAULT_THUMBNAIL]) + thumbnail_url = static(DEFAULT_THUMBNAIL) return format_html('%s' % ( thumbnail_url, @@ -703,11 +701,7 @@ def get_thumbnail_card(self): # else: - thumbnail_url = ''.join( - ['//', - get_current_site(None).domain, - settings.STATIC_URL, - DEFAULT_THUMBNAIL]) + thumbnail_url = static(DEFAULT_THUMBNAIL) return '%s' % ( thumbnail_url, self.title.replace('"', "'")) diff --git a/pod/video/static/css/comment-style.css b/pod/video/static/css/comment-style.css index d307dc70c3..841fd7ff48 100644 --- a/pod/video/static/css/comment-style.css +++ b/pod/video/static/css/comment-style.css @@ -144,7 +144,7 @@ -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; - background-color: #00baf3; + /*background-color: #00baf3;*/ font-family: "Source Sans Pro", Arial, sans-serif; padding: 11px 30px; border-radius: 4px; @@ -153,7 +153,8 @@ bottom: 20px; right: 20px; font-size: 16px; - color: #fff; + /*color: #fff;*/ + transition: opacity 1s; -webkit-animation: up 1s cubic-bezier(.77, 0, .18, 1) forwards; animation: up 1s cubic-bezier(.77, 0, .18, 1) forwards; -webkit-animation-direction: normal; @@ -187,11 +188,9 @@ 0% { bottom: 20px; /*background-color: rgba(153, 201, 61, 1);*/ - opacity: 1; } 100% { bottom: -100%; - opacity: 0; /*background-color: rgba(153, 201, 61, 0);*/ } } @@ -199,36 +198,30 @@ 0% { bottom: 20px; /*background-color: rgba(153, 201, 61, 1);*/ - opacity: 1; } 100% { bottom: -100%; /*background-color: rgba(153, 201, 61, 0);*/ - opacity: 0; } } @-webkit-keyframes up { 0% { bottom: -100%; /*background-color: rgba(153, 201, 61, .1);*/ - opacity: .1; } 100% { bottom: 20px; /*background-color: rgba(153, 201, 61, 1);*/ - opacity: 1; } } @keyframes up { 0% { bottom: -100%; /*background-color: rgba(153, 201, 61, .1);*/ - opacity: .1; } 100% { bottom: 20px; /*background-color: rgba(153, 201, 61, 1);*/ - opacity: 1; } } /* End Alert message */ diff --git a/pod/video/static/js/comment-script.js b/pod/video/static/js/comment-script.js index 0e76f957c1..96d3981cd7 100644 --- a/pod/video/static/js/comment-script.js +++ b/pod/video/static/js/comment-script.js @@ -1,3 +1,5 @@ +/** Comment Scripts **/ + let base_url = window.location.href.replace("/video/", "/comment/"); let base_vote_url = base_url.replace("comment", "comment/vote"); let base_delete_url = base_url.replace("comment", "comment/del"); diff --git a/pod/video/templates/videos/video.html b/pod/video/templates/videos/video.html index fd2e58ab24..baa71f0a59 100644 --- a/pod/video/templates/videos/video.html +++ b/pod/video/templates/videos/video.html @@ -95,41 +95,41 @@ {%if channel %} -

    {{channel.title}}{% if request.user in channel.owners.all %} {% trans "Edit the channel"%}{%endif%}

    -{% if channel.headband %} -{% trans 'Headband' %} {{ channel.title }} -{% endif %} -{% if channel.description %} -{{ channel.description|safe }} -{% endif %} -{% if theme %} -

    {{theme.title}}

    -{% if theme.headband %} -
    - {% trans 'Headband' %} {{ theme.title }} -
    -{% endif %} -{% if theme.description %} -{{ theme.description|safe }} -{% endif %} -{%endif%} +

    {{channel.title}}{% if request.user in channel.owners.all %} {% trans "Edit the channel"%}{%endif%}

    + {% if channel.headband %} + {% trans 'Headband' %} {{ channel.title }} + {% endif %} + {% if channel.description %} + {{ channel.description|safe }} + {% endif %} + {% if theme %} +

    {{theme.title}}

    + {% if theme.headband %} +
    + {% trans 'Headband' %} {{ theme.title }} +
    + {% endif %} + {% if theme.description %} + {{ theme.description|safe }} + {% endif %} + {%endif%} {%endif%} {% if video.get_encoding_step == "" %} - {% endif %} {% if video.encoding_in_progress %} - {% endif %} {% if video.get_encoding_step == "5 : transcripting audio" %} -

    +

    {% trans "The video is currently being transcripted." %} -

    +

    {% endif %} @@ -156,106 +156,106 @@

    {%endif%} -
    - + + {% endif %} + +
    + {% include 'videos/video-info.html' %} +

    + {% if active_video_comment %} + {% include 'videos/video-comment.html' with is_auth=request.user.is_authenticated disable=video.disable_comment %} + {% endif %} {%endif%} {% endblock video-element %}
    {% endblock page_content %} {% block page_aside %} -{% if video.owner == request.user or request.user.is_superuser or request.user in video.additional_owners.all %} -
    -
     {% trans "Manage video"%}
    + {% if video.owner == request.user or request.user.is_superuser or request.user in video.additional_owners.all %} +
    +
     {% trans "Manage video"%}
    {% include "videos/link_video.html" %}
    -
    -{% endif %} +
    + {% endif %} -
    - {% include 'videos/video_notes.html' %} -
    -{% include 'aside.html' %} +
    + {% include 'videos/video_notes.html' %} +
    + {% include 'aside.html' %} {% endblock page_aside %} From 83f0314744901ddb7ed99f184e9d3af3a8b76a39 Mon Sep 17 00:00:00 2001 From: Joshua Baubry Date: Mon, 15 Mar 2021 13:37:51 +0100 Subject: [PATCH 094/261] rest views for accessgroup + fix flake8 --- pod/authentication/rest_views.py | 13 ++++++++++++- pod/podfile/admin.py | 2 +- pod/podfile/models.py | 1 - pod/podfile/views.py | 6 ++++-- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/pod/authentication/rest_views.py b/pod/authentication/rest_views.py index 93ac607e1a..b1b7f06a2b 100644 --- a/pod/authentication/rest_views.py +++ b/pod/authentication/rest_views.py @@ -1,6 +1,6 @@ from django.contrib.auth.models import User, Group from django.contrib.sites.models import Site -from .models import Owner +from .models import Owner, AccessGroup from rest_framework import serializers, viewsets # Serializers define the API representation. @@ -35,6 +35,12 @@ class Meta: model = Site fields = ('url', 'name', 'domain') + +class AccessGroupSerializer(serializers.HyperlinkedModelSerializer): + + class Meta: + model = AccessGroup + fields = ('display_name', 'name', 'sites', 'users') # ViewSets define the view behavior. @@ -56,3 +62,8 @@ class GroupViewSet(viewsets.ModelViewSet): class SiteViewSet(viewsets.ModelViewSet): queryset = Site.objects.all() serializer_class = SiteSerializer + + +class AccessGroupViewSet(viewsets.ModelViewSet): + queryset = AccessGroup.objects.all() + serializer_class = SiteSerializer diff --git a/pod/podfile/admin.py b/pod/podfile/admin.py index 4442b4d580..f3f169589d 100644 --- a/pod/podfile/admin.py +++ b/pod/podfile/admin.py @@ -3,7 +3,6 @@ from .models import CustomImageModel from .models import UserFolder from django.contrib.sites.shortcuts import get_current_site -from django.contrib.auth.models import Group from django.contrib.auth.models import User from django.contrib.sites.models import Site from pod.authentication.models import AccessGroup @@ -28,6 +27,7 @@ def formfield_for_manytomany(self, db_field, request, **kwargs): kwargs["queryset"] = AccessGroup.objects.filter( sites=Site.objects.get_current()) return super().formfield_for_foreignkey(db_field, request, **kwargs) + def get_queryset(self, request): qs = super().get_queryset(request) if not request.user.is_superuser: diff --git a/pod/podfile/models.py b/pod/podfile/models.py index ee9cfede50..d50739ddfa 100644 --- a/pod/podfile/models.py +++ b/pod/podfile/models.py @@ -6,7 +6,6 @@ from django.template.defaultfilters import slugify from django.dispatch import receiver from django.db.models.signals import post_save -from django.contrib.auth.models import Group from select2 import fields as select2_fields from sorl.thumbnail import delete from itertools import chain diff --git a/pod/podfile/views.py b/pod/podfile/views.py index a1b2f40be7..a367332928 100644 --- a/pod/podfile/views.py +++ b/pod/podfile/views.py @@ -137,7 +137,8 @@ def get_folder_files(request, id, type=None): and not (folder.groups.filter( name__in=[ name[0] - for name in AccessGroup.objects.filter(users__user=request.user).values_list('name') + for name in AccessGroup.objects.filter( + users__user=request.user).values_list('name') ]).exists()) and not ( request.user.is_superuser or request.user.has_perm( @@ -548,7 +549,8 @@ def get_file(request, type): and not reqfile.folder.groups.filter( name__in=[ name[0] - for name in AccessGroup.objects.filter(users__user=request.user).values_list('name') + for name in AccessGroup.objects.filter( + users__user=request.user).values_list('name') ]).exists() and not (request.user.is_superuser or request.user.has_perm( "podfile.change_customfilemodel") or request.user.has_perm( From ef9576c9b34089e5ffa6c732b81d80ae5187ae01 Mon Sep 17 00:00:00 2001 From: Joshua Baubry Date: Mon, 15 Mar 2021 13:55:42 +0100 Subject: [PATCH 095/261] finish to configure APi --- pod/authentication/rest_views.py | 2 +- pod/main/rest_router.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pod/authentication/rest_views.py b/pod/authentication/rest_views.py index b1b7f06a2b..a41e500b3b 100644 --- a/pod/authentication/rest_views.py +++ b/pod/authentication/rest_views.py @@ -66,4 +66,4 @@ class SiteViewSet(viewsets.ModelViewSet): class AccessGroupViewSet(viewsets.ModelViewSet): queryset = AccessGroup.objects.all() - serializer_class = SiteSerializer + serializer_class = AccessGroupSerializer diff --git a/pod/main/rest_router.py b/pod/main/rest_router.py index e30a9559e4..34c9a6d523 100644 --- a/pod/main/rest_router.py +++ b/pod/main/rest_router.py @@ -25,6 +25,7 @@ router.register(r'groups', authentication_views.GroupViewSet) router.register(r'owners', authentication_views.OwnerViewSet) router.register(r'sites', authentication_views.SiteViewSet) +router.register(r'accessgroups', authentication_views.AccessGroupViewSet) router.register(r'channels', video_views.ChannelViewSet) router.register(r'themes', video_views.ThemeViewSet) From 0f7ee77fda9784cd6f385b8578a27cc541c279e7 Mon Sep 17 00:00:00 2001 From: Olivier Bado Date: Mon, 15 Mar 2021 16:45:43 +0100 Subject: [PATCH 096/261] Add a "code of conduct" and a "contributing" file to follow open sources guidelines (https://opensource.guide/fr/ & https://docs.github.com/en/github/building-a-strong-community/setting-guidelines-for-repository-contributors) --- CODE_OF_CONDUCT.md | 133 +++++++++++++++++++++++++++++++++++++++++ CONTRIBUTING.md | 146 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 279 insertions(+) create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000..9324ffdae1 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,133 @@ + +# Code de conduite _Contributor Covenant_ + +## Notre engagement + +En tant que membres, contributeur·trice·s et dirigeant·e·s, nous nous +engageons à faire de la participation à notre communauté +une expérience sans harcèlement, quel que soit l'âge, +la taille corporelle, le handicap visible ou invisible, l'appartenance ethnique, +les caractéristiques sexuelles, l'identité et l'expression de genre, +le niveau d'expérience, l'éducation, le statut socio-économique, +la nationalité, l'apparence personnelle, la race, la religion, +ou l'identité et l'orientation sexuelle. + +Nous nous engageons à agir et interagir de manière à contribuer à une communauté +ouverte, accueillante, diversifiée, inclusive et saine. + +## Nos critères + +Exemples de comportements qui contribuent à créer un environnement positif : + +* Faire preuve d'empathie et de bienveillance envers les autres +* Être respectueux des opinions, points de vue et expériences divergents +* Donner et recevoir avec grâce les critiques constructives +* Assumer ses responsabilités et s'excuser auprès des personnes affectées par nos erreurs et apprendre de ces expériences +* Se concentrer sur ce qui est le meilleur non pas uniquement pour nous en tant qu'individu, mais aussi pour l'ensemble de la communauté + +Exemples de comportements inacceptables : + +* L'utilisation de langage ou d'images sexualisés et d'attentions ou d'avances sexuelles de toute nature +* Le _trolling_, les commentaires insultants ou désobligeants et les attaques + personnelles ou d'ordre politique +* Le harcèlement en public ou en privé +* La publication d'informations privées d'autrui, telle qu'une + adresse postale ou une adresse électronique, sans leur autorisation explicite +* Toute autre conduite qui pourrait raisonnablement être considérée comme inappropriée + dans un cadre professionnel + +## Responsabilités d'application + +Les dirigeant·e·s de la communauté sont chargé·e·s de clarifier et de faire respecter nos normes de +comportements acceptables et prendront des mesures correctives appropriées et équitables en +réponse à tout comportement qu'ils ou elles jugent inapproprié, menaçant, offensant ou nuisible. + +Les dirigeant·e·s de la communauté ont le droit et la responsabilité de supprimer, modifier ou rejeter +les commentaires, les contributions, le code, les modifications de wikis, les rapports d'incidents ou de bogues et autres contributions qui +ne sont pas alignés sur ce code de conduite, et communiqueront les raisons des décisions de modération +le cas échéant. + +## Portée d'application + +Ce code de conduite s'applique à la fois au sein des espaces du projet ainsi que +dans les espaces publics lorsqu'un individu représente officiellement le projet ou sa +communauté. Font parties des exemples de représentation d'un projet ou d'une +communauté l'utilisation d'une adresse électronique officielle, la publication sur +les réseaux sociaux à l'aide d'un compte officiel ou le fait d'agir en tant que représentant·e désigné·e +lors d'un événement en ligne ou hors-ligne. + +## Application + +Les cas de comportements abusifs, harcelants ou tout autre comportement +inacceptables peuvent être signalés aux dirigeant·e·s de la communauté responsables de l'application du code de conduite à +[INSÉRER UNE ADRESSE EMAIL]. +Toutes les plaintes seront examinées et feront l'objet d'une enquête rapide et équitable. + +Tou·te·s les dirigeant·e·s de la communauté sont tenu·e·s de respecter la vie privée et la sécurité des +personnes ayant signalé un incident. + +## Directives d'application + +Les dirigeant·e·s de communauté suivront ces directives d'application sur l'impact communautaire afin de déterminer +les conséquences de toute action qu'ils jugent contraire au présent code de conduite : + +### 1. Correction + +**Impact communautaire** : utilisation d'un langage inapproprié ou tout autre comportement jugé +non professionnel ou indésirable dans la communauté. + +**Conséquence** : un avertissement écrit et privé de la part des dirigeant·e·s de la communauté, clarifiant +la nature du non-respect et expliquant pourquoi +le comportement était inapproprié. Des excuses publiques peuvent être demandées. + +### 2. Avertissement + +**Impact communautaire** : un non-respect par un seul incident ou une série d'actions. + +**Conséquence** : un avertissement avec des conséquences dû à la poursuite du comportement. +Aucune interaction avec les personnes concernées, y compris l'interaction non sollicitée avec +celles et ceux qui sont chargé·e·s de l'application de ce code de conduite, pendant une période déterminée. +Cela comprend le fait d'éviter les interactions dans les espaces communautaires ainsi que sur les canaux externes +comme les médias sociaux. Le non-respect de ces conditions peut entraîner +un bannissement temporaire ou permanent. + +### 3. Bannissement temporaire + +**Impact communautaire** : un non-respect grave des normes communautaires, notamment +un comportement inapproprié soutenu. + +**Conséquence** : un bannissement temporaire de toutes formes d'interactions ou de +communications avec la communauté pendant une période déterminée. Aucune interaction publique ou +privée avec les personnes concernées, y compris les interactions non sollicitées +avec celles et ceux qui appliquent ce code de conduite, n'est autorisée pendant cette période. +Le non-respect de ces conditions peut entraîner un bannissement permanent. + +### 4. Bannissement permanent + +**Impact communautaire** : démontrer un schéma récurrent de non-respect des normes de la +communauté y compris un comportement inapproprié soutenu, le harcèlement d'un individu +ainsi que l'agression ou le dénigrement de catégories d'individus. + +**Conséquence** : un bannissement permanent de toutes formes d'interactions publiques au sein de +la communauté. + +## Attributions + +Ce code de conduite est adapté du +[Contributor Covenant](https://www.contributor-covenant.org), version 2.0, +disponible à +[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0]. + +Les Directives d'application ont été inspirées par le +[Code of conduct enforcement ladder][Mozilla CoC] de Mozilla. + +Pour obtenir des réponses aux questions courantes sur ce code de conduite, consultez la FAQ à +[https://www.contributor-covenant.org/faq][FAQ]. Les traductions sont disponibles +sur [https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..d3ebbd2dc3 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,146 @@ +# Contributing to Esup-Pod + +:+1::tada: First off, thanks for taking the time to contribute! :tada::+1: + +The following is a set of guidelines for contributing to Pod, which is hosted in the [Esup Organization](https://github.com/EsupPortail) on GitHub. +These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request. + +#### Table Of Contents + +* [Code of Conduct](#code-of-conduct) + +* [How Can I Contribute?](#how-can-i-contribute) + * [Reporting Bugs](#reporting-bugs) + * [Suggesting Enhancements](#suggesting-enhancements) + * [Pull Requests](#pull-requests) + +* [Styleguides](#styleguides) + * [Git Commit Messages](#git-commit-messages) + +* [Coding conventions](#coding-conventions) + * [JavaScript Styleguide](#javascript-styleguide) + + +## Code of Conduct + +This project and everyone participating in it is governed by the [Pod Code of Conduct](CODE_OF_CONDUCT.md). +By participating, you are expected to uphold this code. Please report unacceptable behavior to us. + +## I don't want to read this whole thing I just have a question!!! + +If chat is more your speed, you can join the Pod team on Rocket: https://rocket.esup-portail.org/channel/esup_-_pod + + + +## How Can I Contribute? + +### Reporting Bugs + +This section guides you through submitting a bug report. +Following these guidelines helps maintainers and the community understand your report :pencil:, reproduce the behavior :computer: :computer:, +and find related reports :mag_right:. + +When you are creating a bug report, please [include as many details as possible](#how-do-i-submit-a-good-bug-report). + +> **Note:** If you find a **Closed** issue that seems like it is the same thing that you're experiencing, open a new issue and include a link to the original issue in the body of your new one. + + +#### How Do I Submit A (Good) Bug Report? + +Bugs are tracked as [GitHub issues](https://guides.github.com/features/issues/). +Create an issue and explain the problem and include additional details to help maintainers reproduce the problem: + +* **Use a clear and descriptive title** for the issue to identify the problem. +* **Describe the exact steps which reproduce the problem** in as many details as possible. +* **Provide specific examples to demonstrate the steps**. Include links to files or GitHub projects, or copy/pasteable snippets, which you use in those examples. +* **Describe the behavior you observed after following the steps** and point out what exactly is the problem with that behavior. +* **Explain which behavior you expected to see instead and why.** +* **Include screenshots and animated GIFs** which show you following the described steps and clearly demonstrate the problem. You can use [this tool](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux. +* **If the problem wasn't triggered by a specific action**, describe what you were doing before the problem happened and share more information using the guidelines below. +* **Can you reliably reproduce the issue?** If not, provide details about how often the problem happens and under which conditions it normally happens. + +Include details about your configuration and environment: + +* **Which version of Pod are you using?** +* **What's the name and version of the browser you're using**? + + +### Suggesting Enhancements + +This section guides you through submitting an enhancement suggestion for Pod, including completely new features and minor improvements to existing functionality. Following these guidelines helps maintainers and the community understand your suggestion :pencil: and find related suggestions :mag_right:. + + +#### How Do I Submit A (Good) Enhancement Suggestion? + +Enhancement suggestions are tracked as [GitHub issues](https://guides.github.com/features/issues/). Create an issue and provide the following information: + +* **Use a clear and descriptive title** for the issue to identify the suggestion. +* **Provide a step-by-step description of the suggested enhancement** in as many details as possible. +* **Provide specific examples to demonstrate the steps**. Include copy/pasteable snippets which you use in those examples, as [Markdown code blocks](https://help.github.com/articles/markdown-basics/#multiple-lines). +* **Describe the current behavior** and **explain which behavior you expected to see instead** and why. +* **Include screenshots and animated GIFs** which help you demonstrate the steps or point out the part which the suggestion is related to. You can use [this tool](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux. +* **Specify which version of Pod you're using.** +* **Specify the name and version of the browser you're using.** + + +### Pull Requests + +The process described here has several goals: + +- Maintain quality +- Fix problems that are important to users +- Engage the community in working toward the best possible Pod +- Enable a sustainable system for maintainers to review contributions + +Please follow these steps to have your contribution considered by the maintainers: + +1. Follow all instructions in [the template](PULL_REQUEST_TEMPLATE.md) +2. Follow the [styleguides](#styleguides) +3. After you submit your pull request, verify that all [status checks](https://help.github.com/articles/about-status-checks/) are passing
    What if the status checks are failing?If a status check is failing, and you believe that the failure is unrelated to your change, please leave a comment on the pull request explaining why you believe the failure is unrelated. A maintainer will re-run the status check for you. If we conclude that the failure was a false positive, then we will open an issue to track that problem with our status check suite.
    + +While the prerequisites above must be satisfied prior to having your pull request reviewed, the reviewer(s) may ask you to complete additional design work, tests, or other changes before your pull request can be ultimately accepted. + +## Styleguides + +### Git Commit Messages + +* Use the present tense ("Add feature" not "Added feature") +* Use the imperative mood ("Move cursor to..." not "Moves cursor to...") +* Limit the first line to 72 characters or less +* Reference issues and pull requests liberally after the first line +* When only changing documentation, include `[ci skip]` in the commit title +* Consider starting the commit message with an applicable emoji: + * :art: `:art:` when improving the format/structure of the code + * :racehorse: `:racehorse:` when improving performance + * :non-potable_water: `:non-potable_water:` when plugging memory leaks + * :memo: `:memo:` when writing docs + * :penguin: `:penguin:` when fixing something on Linux + * :apple: `:apple:` when fixing something on macOS + * :checkered_flag: `:checkered_flag:` when fixing something on Windows + * :bug: `:bug:` when fixing a bug + * :fire: `:fire:` when removing code or files + * :green_heart: `:green_heart:` when fixing the CI build + * :white_check_mark: `:white_check_mark:` when adding tests + * :lock: `:lock:` when dealing with security + * :arrow_up: `:arrow_up:` when upgrading dependencies + * :arrow_down: `:arrow_down:` when downgrading dependencies + * :shirt: `:shirt:` when removing linter warnings + + +## Coding conventions + +Start reading our code and you'll get the hang of it. We optimize for readability: + + * We indent using two spaces (soft tabs) + * This is open source software. Consider the people who will read your code, and make it look nice for them. It's sort of like driving a car: Perhaps you love doing donuts when you're alone, but with passengers the goal is to make the ride as smooth as possible. + +### JavaScript Styleguide + +All JavaScript code is linted with [Prettier](https://prettier.io/). + +* Prefer the object spread operator (`{...anotherObj}`) to `Object.assign()` + + + + + From c45240a74a108075ec5770c8b2a2306f544c8b06 Mon Sep 17 00:00:00 2001 From: Olivier Bado Date: Mon, 15 Mar 2021 16:46:11 +0100 Subject: [PATCH 097/261] update code of conduct --- CODE_OF_CONDUCT.md | 57 ++++++++++++++++------------------------------ 1 file changed, 20 insertions(+), 37 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 9324ffdae1..ebe8985996 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,5 +1,5 @@ -# Code de conduite _Contributor Covenant_ +# Code de conduite _Esup-Pod_ ## Notre engagement @@ -12,8 +12,7 @@ le niveau d'expérience, l'éducation, le statut socio-économique, la nationalité, l'apparence personnelle, la race, la religion, ou l'identité et l'orientation sexuelle. -Nous nous engageons à agir et interagir de manière à contribuer à une communauté -ouverte, accueillante, diversifiée, inclusive et saine. +Nous nous engageons à agir et interagir de manière à contribuer à une communauté ouverte, accueillante, diversifiée, inclusive et saine. ## Nos critères @@ -49,35 +48,28 @@ le cas échéant. ## Portée d'application -Ce code de conduite s'applique à la fois au sein des espaces du projet ainsi que -dans les espaces publics lorsqu'un individu représente officiellement le projet ou sa -communauté. Font parties des exemples de représentation d'un projet ou d'une -communauté l'utilisation d'une adresse électronique officielle, la publication sur -les réseaux sociaux à l'aide d'un compte officiel ou le fait d'agir en tant que représentant·e désigné·e -lors d'un événement en ligne ou hors-ligne. +Ce code de conduite s'applique à la fois au sein des espaces du projet ainsi que dans les espaces publics lorsqu'un individu représente officiellement le projet ou sa communauté. +Font parties des exemples de représentation d'un projet ou d'une +communauté l'utilisation d'une adresse électronique officielle, la publication sur les réseaux sociaux à l'aide d'un compte officiel ou le fait d'agir en tant que représentant·e désigné·e lors d'un événement en ligne ou hors-ligne. ## Application Les cas de comportements abusifs, harcelants ou tout autre comportement inacceptables peuvent être signalés aux dirigeant·e·s de la communauté responsables de l'application du code de conduite à -[INSÉRER UNE ADRESSE EMAIL]. +[Esup-Pod](https://github.com/EsupPortail/Esup-Pod). Toutes les plaintes seront examinées et feront l'objet d'une enquête rapide et équitable. -Tou·te·s les dirigeant·e·s de la communauté sont tenu·e·s de respecter la vie privée et la sécurité des -personnes ayant signalé un incident. +Tou·te·s les dirigeant·e·s de la communauté sont tenu·e·s de respecter la vie privée et la sécurité des personnes ayant signalé un incident. ## Directives d'application -Les dirigeant·e·s de communauté suivront ces directives d'application sur l'impact communautaire afin de déterminer -les conséquences de toute action qu'ils jugent contraire au présent code de conduite : +Les dirigeant·e·s de communauté suivront ces directives d'application sur l'impact communautaire afin de déterminer les conséquences de toute action qu'ils jugent contraire au présent code de conduite : ### 1. Correction -**Impact communautaire** : utilisation d'un langage inapproprié ou tout autre comportement jugé -non professionnel ou indésirable dans la communauté. +**Impact communautaire** : utilisation d'un langage inapproprié ou tout autre comportement jugé non professionnel ou indésirable dans la communauté. -**Conséquence** : un avertissement écrit et privé de la part des dirigeant·e·s de la communauté, clarifiant -la nature du non-respect et expliquant pourquoi +**Conséquence** : un avertissement écrit et privé de la part des dirigeant·e·s de la communauté, clarifiant la nature du non-respect et expliquant pourquoi le comportement était inapproprié. Des excuses publiques peuvent être demandées. ### 2. Avertissement @@ -85,31 +77,23 @@ le comportement était inapproprié. Des excuses publiques peuvent être demand **Impact communautaire** : un non-respect par un seul incident ou une série d'actions. **Conséquence** : un avertissement avec des conséquences dû à la poursuite du comportement. -Aucune interaction avec les personnes concernées, y compris l'interaction non sollicitée avec -celles et ceux qui sont chargé·e·s de l'application de ce code de conduite, pendant une période déterminée. -Cela comprend le fait d'éviter les interactions dans les espaces communautaires ainsi que sur les canaux externes -comme les médias sociaux. Le non-respect de ces conditions peut entraîner -un bannissement temporaire ou permanent. +Aucune interaction avec les personnes concernées, y compris l'interaction non sollicitée avec celles et ceux qui sont chargé·e·s de l'application de ce code de conduite, pendant une période déterminée. +Cela comprend le fait d'éviter les interactions dans les espaces communautaires ainsi que sur les canaux externes comme les médias sociaux. +Le non-respect de ces conditions peut entraîner un bannissement temporaire ou permanent. ### 3. Bannissement temporaire -**Impact communautaire** : un non-respect grave des normes communautaires, notamment -un comportement inapproprié soutenu. +**Impact communautaire** : un non-respect grave des normes communautaires, notamment un comportement inapproprié soutenu. -**Conséquence** : un bannissement temporaire de toutes formes d'interactions ou de -communications avec la communauté pendant une période déterminée. Aucune interaction publique ou -privée avec les personnes concernées, y compris les interactions non sollicitées -avec celles et ceux qui appliquent ce code de conduite, n'est autorisée pendant cette période. +**Conséquence** : un bannissement temporaire de toutes formes d'interactions ou de communications avec la communauté pendant une période déterminée. +Aucune interaction publique ou privée avec les personnes concernées, y compris les interactions non sollicitées avec celles et ceux qui appliquent ce code de conduite, n'est autorisée pendant cette période. Le non-respect de ces conditions peut entraîner un bannissement permanent. ### 4. Bannissement permanent -**Impact communautaire** : démontrer un schéma récurrent de non-respect des normes de la -communauté y compris un comportement inapproprié soutenu, le harcèlement d'un individu -ainsi que l'agression ou le dénigrement de catégories d'individus. +**Impact communautaire** : démontrer un schéma récurrent de non-respect des normes de la communauté y compris un comportement inapproprié soutenu, le harcèlement d'un individu ainsi que l'agression ou le dénigrement de catégories d'individus. -**Conséquence** : un bannissement permanent de toutes formes d'interactions publiques au sein de -la communauté. +**Conséquence** : un bannissement permanent de toutes formes d'interactions publiques au sein de la communauté. ## Attributions @@ -121,9 +105,8 @@ disponible à Les Directives d'application ont été inspirées par le [Code of conduct enforcement ladder][Mozilla CoC] de Mozilla. -Pour obtenir des réponses aux questions courantes sur ce code de conduite, consultez la FAQ à -[https://www.contributor-covenant.org/faq][FAQ]. Les traductions sont disponibles -sur [https://www.contributor-covenant.org/translations][translations]. +Pour obtenir des réponses aux questions courantes sur ce code de conduite, consultez la FAQ à [https://www.contributor-covenant.org/faq][FAQ]. +Les traductions sont disponibles sur [https://www.contributor-covenant.org/translations][translations]. [homepage]: https://www.contributor-covenant.org [v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html From 936fa356da6f8d7b6da02e04c1a1752dce0b0659 Mon Sep 17 00:00:00 2001 From: Joshua Baubry Date: Mon, 15 Mar 2021 17:25:27 +0100 Subject: [PATCH 098/261] command to import groups --- pod/video/management/commands/accessgroups.py | 98 +++++++++++++++++++ test.json | 14 +++ 2 files changed, 112 insertions(+) create mode 100644 pod/video/management/commands/accessgroups.py create mode 100644 test.json diff --git a/pod/video/management/commands/accessgroups.py b/pod/video/management/commands/accessgroups.py new file mode 100644 index 0000000000..5d5778b6a1 --- /dev/null +++ b/pod/video/management/commands/accessgroups.py @@ -0,0 +1,98 @@ +import json +from django.core.management.base import BaseCommand +from django.utils import translation +from django.conf import settings +from pod.authentication.models import AccessGroup, Owner +from django.core.exceptions import ObjectDoesNotExist + +LANGUAGE_CODE = getattr(settings, "LANGUAGE_CODE", 'fr') + + +def edit_group_properties(group): + existing_group = AccessGroup.objects.get( + name=group["name"]) + print("--> Already exists") + if group["display_name"] != existing_group.display_name: + print( + "---> Changing display_name from \"" + + existing_group.display_name + + "\" to \"" + group["display_name"] + "\"") + existing_group.display_name = group["display_name"] + return existing_group + + +def add_users_to_group(group, existing_group): + if group["users_to_add"]: + print("---> There is some users to add") + for user in group["users_to_add"]: + try: + owner = Owner.objects.get(user__username=user) + if owner in existing_group.users.all(): + print("----> User with username \"" + + user + "\" is already in group") + else: + print("----> Adding \"" + user + "\" to the group") + existing_group.users.add(owner) + except ObjectDoesNotExist: + print( + "----> User with username \"" + user + "\" doesn't exist") + + +def remove_users_to_group(group, existing_group): + if group["users_to_remove"]: + print("---> There is some users to remove") + for user in group["users_to_remove"]: + try: + owner = Owner.objects.get(user__username=user) + if owner not in existing_group.users.all(): + print("----> User with username \"" + + user + "\" is not in group") + else: + print("----> Removing \"" + user + "\" to the group") + existing_group.users.remove(owner) + except ObjectDoesNotExist: + print( + "----> User with username \"" + user + "\" doesn't exist") + + +class Command(BaseCommand): + # First possible argument : checkDirectory + args = 'import_json' + help = 'Import groups from json' + 'published by the recorders. ' + valid_args = ['import_json'] + + def add_arguments(self, parser): + parser.add_argument('task') + parser.add_argument('file') + + def handle(self, *args, **options): + + # Activate a fixed locale fr + translation.activate(LANGUAGE_CODE) + if options['task'] and options['task'] in self.valid_args: + json_data = open(options['file']) + groups = json.load(json_data) + for group in groups: + print("\n-> Processing " + group["name"]) + try: + existing_group = edit_group_properties(group) + add_users_to_group(group, existing_group) + remove_users_to_group(group, existing_group) + existing_group.save() + except ObjectDoesNotExist: + print("Group with name " + group[ + "name"] + " doesn't exists") + if not (group["name"] and group["display_name"]): + print( + "No such informations to create " + group["name"]) + else: + AccessGroup.objects.create( + name=group[ + "name"], display_name=group["display_name"]) + print("Successfully creating " + group["name"]) + json_data.close() + else: + print( + "*** Warning: you must give some arguments: %s ***" % + self.valid_args) diff --git a/test.json b/test.json new file mode 100644 index 0000000000..a007033a62 --- /dev/null +++ b/test.json @@ -0,0 +1,14 @@ +[ +{ + "name" : "mygroup12", + "display_name": "My grookkoup 1jj22", + "users_to_add" : [], + "users_to_remove" : ["admin"] +}, +{ + "name" : "mygroup2", + "display_name" : "My group 2", + "users_to_add" : ["login1","login2"], + "users_to_remove" : ["login3","login4"] +} +] \ No newline at end of file From 3047879af390fa5fdea5a249515981c0bc0ddf2f Mon Sep 17 00:00:00 2001 From: Eliam LOTONGA Date: Tue, 16 Mar 2021 07:15:05 +0100 Subject: [PATCH 099/261] Fix z-index on confirm delete dialog --- pod/video/static/css/comment-style.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pod/video/static/css/comment-style.css b/pod/video/static/css/comment-style.css index d307dc70c3..a636e87ae3 100644 --- a/pod/video/static/css/comment-style.css +++ b/pod/video/static/css/comment-style.css @@ -243,7 +243,7 @@ -ms-flex-pack: center; justify-content: center; padding-top: 20px; - z-index: 9; + z-index: 99; position: fixed; left: 0; right: 0; From 815cd0cade1c5675a1915d4558f3aa9e6cf65d8d Mon Sep 17 00:00:00 2001 From: Eliam LOTONGA Date: Tue, 16 Mar 2021 07:17:10 +0100 Subject: [PATCH 100/261] Check element is in viewPort before scroll to it --- pod/video/static/js/comment-script.js | 60 +++++++++++++++++---------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/pod/video/static/js/comment-script.js b/pod/video/static/js/comment-script.js index 0e76f957c1..60caf4bd32 100644 --- a/pod/video/static/js/comment-script.js +++ b/pod/video/static/js/comment-script.js @@ -187,7 +187,7 @@ class Comment extends HTMLElement { if (!vote_action.classList.contains("voting")) vote_action.classList.add("voting"); let comment_id = get_comment_attribute(document.getElementById(id)); - vote(vote_action, comment_id, vote_action); + vote(vote_action, comment_id); }); } comment_container @@ -404,10 +404,10 @@ customElements.define("comment-element", Comment); /******************* Voting for a comment ******************** ***************************************************************/ -function vote(comment_action_html, comment_id, target_html_el) { +function vote(comment_action_html, comment_id) { // send request to the server to check if the current user already vote let vote_url = base_vote_url + comment_id + "/"; - let btn = target_html_el.querySelector(".comment_vote_btn"); + let btn = comment_action_html.querySelector(".comment_vote_btn"); let data = new FormData(); data.append("csrfmiddlewaretoken", Cookies.get("csrftoken")); fetch(vote_url, { @@ -417,7 +417,7 @@ function vote(comment_action_html, comment_id, target_html_el) { .then((response) => { response.json().then((data) => { comment_action_html.classList.remove("voting"); - const target_comment = get_node(target_html_el, "comment_element"); + const target_comment = get_node(comment_action_html, "comment_element"); if (data.voted === true) { const nb_vote = update_comment_attribute( @@ -427,8 +427,8 @@ function vote(comment_action_html, comment_id, target_html_el) { "increment" ); btn.innerHTML = nb_vote + (nb_vote > 1 ? " votes" : " vote"); - if (!target_html_el.classList.contains("voted")) - target_html_el.classList.add("voted"); + if (!comment_action_html.classList.contains("voted")) + comment_action_html.classList.add("voted"); } else { const nb_vote = update_comment_attribute( target_comment, @@ -437,8 +437,8 @@ function vote(comment_action_html, comment_id, target_html_el) { "decrement" ); btn.innerHTML = nb_vote + (nb_vote > 1 ? " votes" : " vote"); - if (target_html_el.classList.contains("voted")) - target_html_el.classList.remove("voted"); + if (comment_action_html.classList.contains("voted")) + comment_action_html.classList.remove("voted"); } }); }) @@ -649,24 +649,42 @@ function getElementPosition(element) { return { x: xPosition, y: yPosition - bodyPaddingTop }; } +/***** Check if element is visible in the viewport ***** + * ****************************************************/ + function isInViewport(el) { + const rect = el.getBoundingClientRect(); + return ( + rect.top >= 0 && + rect.left >= 0 && + rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && + rect.right <= (window.innerWidth || document.documentElement.clientWidth) + + ); +} /*********** Scroll to a specific comment ************* * ****************************************************/ function scrollToComment(targetComment) { - let currentElementPosition = getElementPosition(targetComment); - window.scrollTo({ - top: currentElementPosition.y, - left: currentElementPosition.x, - behavior: "smooth", - }); - let htmlTarget = targetComment.querySelector(".comment_content"); - if (htmlTarget.classList.contains("scroll_to")) - htmlTarget.classList.remove("scroll_to"); + const alreadyInViewPort = isInViewport(targetComment); + const animationDuration = alreadyInViewPort?2000:4000; + if(!alreadyInViewPort) + { - window.setTimeout(() => { + let currentElementPosition = getElementPosition(targetComment); + window.scrollTo({ + top: currentElementPosition.y, + left: currentElementPosition.x, + behavior: "smooth", + }); + } + let htmlTarget = targetComment.querySelector(".comment_content"); + if (htmlTarget.classList.contains("scroll_to")) htmlTarget.classList.remove("scroll_to"); - }, 4000); - - htmlTarget.classList.add("scroll_to"); + + window.setTimeout(() => { + htmlTarget.classList.remove("scroll_to"); + }, animationDuration); + + htmlTarget.classList.add("scroll_to"); } /****** Add the owner of parent comment as a tag ****** From 3a2ad14581d91c4e985093d26f12be1177b09b19 Mon Sep 17 00:00:00 2001 From: Eliam LOTONGA Date: Tue, 16 Mar 2021 07:21:50 +0100 Subject: [PATCH 101/261] Charging dayjs instead of momentjs library --- pod/video/templates/videos/video.html | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pod/video/templates/videos/video.html b/pod/video/templates/videos/video.html index fd2e58ab24..856da25090 100644 --- a/pod/video/templates/videos/video.html +++ b/pod/video/templates/videos/video.html @@ -290,7 +290,11 @@
     {% trans "Manag var is_authenticated = JSON.parse("{{request.user.is_authenticated|yesno:"true,false"}}"); var is_superuser = JSON.parse("{{request.user.is_superuser|yesno:"true,false"}}"); - - + + + + + + {% endif %} {% endblock more_script %} From 4d60c84e8a797afca62f81cb988d4a4ef5f9fbaa Mon Sep 17 00:00:00 2001 From: Eliam LOTONGA Date: Tue, 16 Mar 2021 07:24:42 +0100 Subject: [PATCH 102/261] Use dayjs instead of momentjs, format code --- pod/video/static/js/comment-script.js | 83 ++++++++++++++------------- 1 file changed, 43 insertions(+), 40 deletions(-) diff --git a/pod/video/static/js/comment-script.js b/pod/video/static/js/comment-script.js index 60caf4bd32..7f651d1a32 100644 --- a/pod/video/static/js/comment-script.js +++ b/pod/video/static/js/comment-script.js @@ -1,3 +1,4 @@ +// import relativeTime from "/static/js/dayjs_relativeTime.min.js"; let base_url = window.location.href.replace("/video/", "/comment/"); let base_vote_url = base_url.replace("comment", "comment/vote"); let base_delete_url = base_url.replace("comment", "comment/del"); @@ -19,6 +20,9 @@ const COLORS = [ "darkgray", ]; const LANG = lang_btn ? lang_btn.textContent.trim() : "fr"; +dayjs.extend(dayjs_plugin_relativeTime) +dayjs.locale(LANG); + const ACTION_COMMENT = { comment_to_delete: null, }; @@ -112,13 +116,13 @@ class CommentSince extends HTMLElement { since = this.getAttribute("since") ? this.getAttribute("since") : since; since = typeof since === "string" ? new Date(since) : since; this.setAttribute("title", since.toLocaleString()); - let date_since = moment(since).locale(LANG).fromNow(); + let date_since = dayjs(since).fromNow(); let div = document.createElement("DIV"); div.setAttribute("class", "comment_since"); div.innerText = date_since; this.appendChild(div); window.setInterval(() => { - date_since = moment(since).locale(LANG).fromNow(); + date_since = dayjs(since).fromNow(); div.innerText = date_since; }, 60000); } @@ -507,7 +511,7 @@ function save_comment( fetch_comment_children( top_parent_comment_html, top_parent_id, - (scroll_to_last = true) + true ); else { // Add comment child into the DOM @@ -580,7 +584,7 @@ function delete_comment(comment) { parent_el, "nbr_child" ); - deleteWithAnimation(comment, (is_child = true)); // delete comment from the DOM + deleteWithAnimation(comment, true); // delete comment from the DOM hide_or_add_show_children_btn( parent_el, parent_id, @@ -591,7 +595,7 @@ function delete_comment(comment) { return; } all_comment = all_comment.filter((c) => c.id != data.comment_deleted); - deleteWithAnimation(comment, (is_child = false)); + deleteWithAnimation(comment, false); set_comments_number(); } else document.body.appendChild(new AlertMessage(data.message)); }); @@ -619,7 +623,7 @@ function delete_comment_child_DOM(comment, comment_top_parent_id, is_child) { child_comment.added ).getTime()}`; let child_comment_html = document.querySelector(html_id); - deleteWithAnimation(child_comment_html, (is_child = true)); + deleteWithAnimation(child_comment_html, true); } return !list_parent_id.includes(child_comment.direct_parent__id); // Remove comment data from all_comment }); @@ -690,10 +694,9 @@ function scrollToComment(targetComment) { /****** Add the owner of parent comment as a tag ****** ******************************************************/ function add_user_tag(comment_value, parent_comment) { - let reply_to = get_comment_attribute(parent_comment, (attr = "author_name")); - reply_content = get_comment_attribute(parent_comment, (attr = "content")); - let htmlTarget = parent_comment.querySelector(".comment_content"); - let tag = document.createElement("a"); + const reply_to = get_comment_attribute(parent_comment, "author_name"); + const reply_content = get_comment_attribute(parent_comment,"content"); + const tag = document.createElement("a"); tag.setAttribute("href", "#"); tag.addEventListener("click", (e) => { e.preventDefault(); @@ -706,11 +709,11 @@ function add_user_tag(comment_value, parent_comment) { @${reply_to} ${reply_content} `; - let comment_text = document.createElement("span"); + const comment_text = document.createElement("span"); comment_text.setAttribute("class", "comment_text"); comment_text.innerText = comment_value; - let comment_content = document.createElement("p"); + const comment_content = document.createElement("p"); comment_content.appendChild(tag); comment_content.appendChild(comment_text); return comment_content; @@ -757,13 +760,13 @@ if (is_authenticated) { if (el.value.trim() != "") { let comment_content = el.value; let c = new Comment( - (owner = user_fullName), - (content = comment_content), - (likes = 0), - (added_since = date_added), - (id = `comment_${date_added.getTime()}`), - (is_parent = true), - (is_comment_owner = true) + user_fullName, + comment_content, + 0, + date_added, + `comment_${date_added.getTime()}`, + true, + true ); c.dataset.level = "-1"; el.value = ""; @@ -835,13 +838,13 @@ function fetch_comment_children( ); let comment_child_html = new Comment( - (owner = `${comment_child.author_name}`), - (content = comment_child_content), - (likes = comment_child.nbr_vote), - (added_since = date_added), - (id = `comment_${date_added.getTime()}`), - (is_parent = false), - (is_comment_owner = comment_child.is_owner) + `${comment_child.author_name}`, + comment_child_content, + comment_child.nbr_vote, + date_added, + `comment_${date_added.getTime()}`, + false, + comment_child.is_owner ); parent_comment_html @@ -876,13 +879,13 @@ function add_child_comment(el, container_el, top_parent_comment_html) { let comment_child_content = add_user_tag(el.value, child_direct_parent); let c = new Comment( - (owner = user_fullName), - (content = comment_child_content), - (likes = 0), - (added_since = date_added), - (id = `comment_${date_added.getTime()}`), - (is_parent = false), - (is_comment_owner = true) + user_fullName, + comment_child_content, + 0, + date_added, + `comment_${date_added.getTime()}`, + false, + true ); setBorderLeftColor(c, child_direct_parent); // INSERT INTO DATABASE THE CURRENT COMMENT CHILD @@ -1049,13 +1052,13 @@ fetch(base_vote_url) let date_added = new Date(comment_data.added); let html_id = `comment_${date_added.getTime().toString()}`; let parent_c = new Comment( - (owner = `${comment_data.author_name}`), - (content = comment_data.content), - (likes = comment_data.nbr_vote), - (added_since = date_added), - (id = html_id), - (is_parent = true), - (is_comment_owner = comment_data.is_owner) + `${comment_data.author_name}`, + comment_data.content, + comment_data.nbr_vote, + date_added, + html_id, + true, + comment_data.is_owner ); parent_c.dataset.level = "-1"; manage_vote_frontend(comment_data.id, parent_c); From c3da4b4674b6f969559ef5e581f3ec0d8f25836b Mon Sep 17 00:00:00 2001 From: Eliam LOTONGA Date: Tue, 16 Mar 2021 07:26:07 +0100 Subject: [PATCH 103/261] remove momentjs librairie --- pod/video/static/js/moment_with_locales.min.js | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 pod/video/static/js/moment_with_locales.min.js diff --git a/pod/video/static/js/moment_with_locales.min.js b/pod/video/static/js/moment_with_locales.min.js deleted file mode 100644 index 4a866a7abc..0000000000 --- a/pod/video/static/js/moment_with_locales.min.js +++ /dev/null @@ -1,2 +0,0 @@ -!function(e,a){"object"==typeof exports&&"undefined"!=typeof module?module.exports=a():"function"==typeof define&&define.amd?define(a):e.moment=a()}(this,function(){"use strict";var e,n;function M(){return e.apply(null,arguments)}function _(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function i(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function h(e,a){return Object.prototype.hasOwnProperty.call(e,a)}function o(e){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(e).length;var a;for(a in e)if(h(e,a))return;return 1}function r(e){return void 0===e}function m(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function d(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function u(e,a){for(var t=[],s=0;s>>0,s=0;sFe(e)?(r=e+1,d-Fe(e)):(r=e,d);return{year:r,dayOfYear:_}}function Ce(e,a,t){var s,n,r=Je(e.year(),a,t),d=Math.floor((e.dayOfYear()-r-1)/7)+1;return d<1?s=d+Ie(n=e.year()-1,a,t):d>Ie(e.year(),a,t)?(s=d-Ie(e.year(),a,t),n=e.year()+1):(n=e.year(),s=d),{week:s,year:n}}function Ie(e,a,t){var s=Je(e,a,t),n=Je(e+1,a,t);return(Fe(e)-s+n)/7}W("w",["ww",2],"wo","week"),W("W",["WW",2],"Wo","isoWeek"),z("week","w"),z("isoWeek","W"),C("week",5),C("isoWeek",5),le("w",ae),le("ww",ae,$),le("W",ae),le("WW",ae,$),Ye(["w","ww","W","WW"],function(e,a,t,s){a[s.substr(0,1)]=G(e)});function Ue(e,a){return e.slice(a,7).concat(e.slice(0,a))}W("d",0,"do","day"),W("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),W("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),W("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),W("e",0,0,"weekday"),W("E",0,0,"isoWeekday"),z("day","d"),z("weekday","e"),z("isoWeekday","E"),C("day",11),C("weekday",11),C("isoWeekday",11),le("d",ae),le("e",ae),le("E",ae),le("dd",function(e,a){return a.weekdaysMinRegex(e)}),le("ddd",function(e,a){return a.weekdaysShortRegex(e)}),le("dddd",function(e,a){return a.weekdaysRegex(e)}),Ye(["dd","ddd","dddd"],function(e,a,t,s){var n=t._locale.weekdaysParse(e,s,t._strict);null!=n?a.d=n:L(t).invalidWeekday=e}),Ye(["d","e","E"],function(e,a,t,s){a[s]=G(e)});var Ge="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Ve="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Be="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),Ke=ue,qe=ue,Ze=ue;function $e(){function e(e,a){return a.length-e.length}for(var a,t,s,n,r=[],d=[],_=[],i=[],o=0;o<7;o++)a=c([2e3,1]).day(o),t=he(this.weekdaysMin(a,"")),s=he(this.weekdaysShort(a,"")),n=he(this.weekdays(a,"")),r.push(t),d.push(s),_.push(n),i.push(t),i.push(s),i.push(n);r.sort(e),d.sort(e),_.sort(e),i.sort(e),this._weekdaysRegex=new RegExp("^("+i.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+_.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+d.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+r.join("|")+")","i")}function Qe(){return this.hours()%12||12}function Xe(e,a){W(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),a)})}function ea(e,a){return a._meridiemParse}W("H",["HH",2],0,"hour"),W("h",["hh",2],0,Qe),W("k",["kk",2],0,function(){return this.hours()||24}),W("hmm",0,0,function(){return""+Qe.apply(this)+S(this.minutes(),2)}),W("hmmss",0,0,function(){return""+Qe.apply(this)+S(this.minutes(),2)+S(this.seconds(),2)}),W("Hmm",0,0,function(){return""+this.hours()+S(this.minutes(),2)}),W("Hmmss",0,0,function(){return""+this.hours()+S(this.minutes(),2)+S(this.seconds(),2)}),Xe("a",!0),Xe("A",!1),z("hour","h"),C("hour",13),le("a",ea),le("A",ea),le("H",ae),le("h",ae),le("k",ae),le("HH",ae,$),le("hh",ae,$),le("kk",ae,$),le("hmm",te),le("hmmss",se),le("Hmm",te),le("Hmmss",se),Le(["H","HH"],De),Le(["k","kk"],function(e,a,t){var s=G(e);a[De]=24===s?0:s}),Le(["a","A"],function(e,a,t){t._isPm=t._locale.isPM(e),t._meridiem=e}),Le(["h","hh"],function(e,a,t){a[De]=G(e),L(t).bigHour=!0}),Le("hmm",function(e,a,t){var s=e.length-2;a[De]=G(e.substr(0,s)),a[Te]=G(e.substr(s)),L(t).bigHour=!0}),Le("hmmss",function(e,a,t){var s=e.length-4,n=e.length-2;a[De]=G(e.substr(0,s)),a[Te]=G(e.substr(s,2)),a[ge]=G(e.substr(n)),L(t).bigHour=!0}),Le("Hmm",function(e,a,t){var s=e.length-2;a[De]=G(e.substr(0,s)),a[Te]=G(e.substr(s))}),Le("Hmmss",function(e,a,t){var s=e.length-4,n=e.length-2;a[De]=G(e.substr(0,s)),a[Te]=G(e.substr(s,2)),a[ge]=G(e.substr(n))});var aa=V("Hours",!0);var ta,sa={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",w:"a week",ww:"%d weeks",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Se,monthsShort:je,week:{dow:0,doy:6},weekdays:Ge,weekdaysMin:Be,weekdaysShort:Ve,meridiemParse:/[ap]\.?m?\.?/i},na={},ra={};function da(e){return e?e.toLowerCase().replace("_","-"):e}function _a(e){for(var a,t,s,n,r=0;r=a&&function(e,a){for(var t=Math.min(e.length,a.length),s=0;s=a-1)break;a--}r++}return ta}function ia(a){var e=null;if(void 0===na[a]&&"undefined"!=typeof module&&module&&module.exports)try{e=ta._abbr,require("./locale/"+a),oa(e)}catch(e){na[a]=null}return na[a]}function oa(e,a){var t;return e&&((t=r(a)?ua(e):ma(e,a))?ta=t:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),ta._abbr}function ma(e,a){if(null===a)return delete na[e],null;var t,s=sa;if(a.abbr=e,null!=na[e])w("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),s=na[e]._config;else if(null!=a.parentLocale)if(null!=na[a.parentLocale])s=na[a.parentLocale]._config;else{if(null==(t=ia(a.parentLocale)))return ra[a.parentLocale]||(ra[a.parentLocale]=[]),ra[a.parentLocale].push({name:e,config:a}),null;s=t._config}return na[e]=new H(b(s,a)),ra[e]&&ra[e].forEach(function(e){ma(e.name,e.config)}),oa(e),na[e]}function ua(e){var a;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return ta;if(!_(e)){if(a=ia(e))return a;e=[e]}return _a(e)}function la(e){var a,t=e._a;return t&&-2===L(e).overflow&&(a=t[pe]<0||11He(t[fe],t[pe])?ke:t[De]<0||24Ie(t,r,d)?L(e)._overflowWeeks=!0:null!=i?L(e)._overflowWeekday=!0:(_=Re(t,s,n,r,d),e._a[fe]=_.year,e._dayOfYear=_.dayOfYear)}(e),null!=e._dayOfYear&&(r=ga(e._a[fe],s[fe]),(e._dayOfYear>Fe(r)||0===e._dayOfYear)&&(L(e)._overflowDayOfYear=!0),t=Ne(r,0,e._dayOfYear),e._a[pe]=t.getUTCMonth(),e._a[ke]=t.getUTCDate()),a=0;a<3&&null==e._a[a];++a)e._a[a]=i[a]=s[a];for(;a<7;a++)e._a[a]=i[a]=null==e._a[a]?2===a?1:0:e._a[a];24===e._a[De]&&0===e._a[Te]&&0===e._a[ge]&&0===e._a[we]&&(e._nextDay=!0,e._a[De]=0),e._d=(e._useUTC?Ne:function(e,a,t,s,n,r,d){var _;return e<100&&0<=e?(_=new Date(e+400,a,t,s,n,r,d),isFinite(_.getFullYear())&&_.setFullYear(e)):_=new Date(e,a,t,s,n,r,d),_}).apply(null,i),n=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[De]=24),e._w&&void 0!==e._w.d&&e._w.d!==n&&(L(e).weekdayMismatch=!0)}}function va(e){if(e._f!==M.ISO_8601)if(e._f!==M.RFC_2822){e._a=[],L(e).empty=!0;for(var a,t,s,n,r,d,_,i=""+e._i,o=i.length,m=0,u=E(e._f,e._locale).match(j)||[],l=0;lt.valueOf():t.valueOf()"}),yt.toJSON=function(){return this.isValid()?this.toISOString():null},yt.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},yt.unix=function(){return Math.floor(this.valueOf()/1e3)},yt.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},yt.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},yt.eraName=function(){for(var e,a=this.localeData().eras(),t=0,s=a.length;tthis.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},yt.isLocal=function(){return!!this.isValid()&&!this._isUTC},yt.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},yt.isUtc=Ca,yt.isUTC=Ca,yt.zoneAbbr=function(){return this._isUTC?"UTC":""},yt.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},yt.dates=t("dates accessor is deprecated. Use date instead.",lt),yt.months=t("months accessor is deprecated. Use month instead",Ae),yt.years=t("years accessor is deprecated. Use year instead",ze),yt.zone=t("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,a){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,a),this):-this.utcOffset()}),yt.isDSTShifted=t("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!r(this._isDSTShifted))return this._isDSTShifted;var e,a={};return p(a,this),(a=ba(a))._a?(e=(a._isUTC?c:Sa)(a._a),this._isDSTShifted=this.isValid()&&0 Date: Tue, 16 Mar 2021 07:27:08 +0100 Subject: [PATCH 104/261] Add dayjs librairie files(en,fr,nl) --- pod/video/static/js/dayjs.min.js | 1 + pod/video/static/js/dayjs_en.min.js | 1 + pod/video/static/js/dayjs_fr.min.js | 1 + pod/video/static/js/dayjs_nl.min.js | 1 + pod/video/static/js/dayjs_relativeTime.min.js | 1 + 5 files changed, 5 insertions(+) create mode 100644 pod/video/static/js/dayjs.min.js create mode 100644 pod/video/static/js/dayjs_en.min.js create mode 100644 pod/video/static/js/dayjs_fr.min.js create mode 100644 pod/video/static/js/dayjs_nl.min.js create mode 100644 pod/video/static/js/dayjs_relativeTime.min.js diff --git a/pod/video/static/js/dayjs.min.js b/pod/video/static/js/dayjs.min.js new file mode 100644 index 0000000000..ac8df8cd4d --- /dev/null +++ b/pod/video/static/js/dayjs.min.js @@ -0,0 +1 @@ +!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):t.dayjs=n()}(this,function(){"use strict";var t="millisecond",n="second",e="minute",r="hour",i="day",s="week",u="month",o="quarter",a="year",h=/^(\d{4})-?(\d{1,2})-?(\d{0,2})[^0-9]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?.?(\d{1,3})?$/,f=/\[([^\]]+)]|Y{2,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,c=function(t,n,e){var r=String(t);return!r||r.length>=n?t:""+Array(n+1-r.length).join(e)+t},d={s:c,z:function(t){var n=-t.utcOffset(),e=Math.abs(n),r=Math.floor(e/60),i=e%60;return(n<=0?"+":"-")+c(r,2,"0")+":"+c(i,2,"0")},m:function(t,n){var e=12*(n.year()-t.year())+(n.month()-t.month()),r=t.clone().add(e,u),i=n-r<0,s=t.clone().add(e+(i?-1:1),u);return Number(-(e+(n-r)/(i?r-s:s-r))||0)},a:function(t){return t<0?Math.ceil(t)||0:Math.floor(t)},p:function(h){return{M:u,y:a,w:s,d:i,D:"date",h:r,m:e,s:n,ms:t,Q:o}[h]||String(h||"").toLowerCase().replace(/s$/,"")},u:function(t){return void 0===t}},$={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_")},l="en",m={};m[l]=$;var y=function(t){return t instanceof v},M=function(t,n,e){var r;if(!t)return l;if("string"==typeof t)m[t]&&(r=t),n&&(m[t]=n,r=t);else{var i=t.name;m[i]=t,r=i}return e||(l=r),r},g=function(t,n,e){if(y(t))return t.clone();var r=n?"string"==typeof n?{format:n,pl:e}:n:{};return r.date=t,new v(r)},D=d;D.l=M,D.i=y,D.w=function(t,n){return g(t,{locale:n.$L,utc:n.$u,$offset:n.$offset})};var v=function(){function c(t){this.$L=this.$L||M(t.locale,null,!0),this.parse(t)}var d=c.prototype;return d.parse=function(t){this.$d=function(t){var n=t.date,e=t.utc;if(null===n)return new Date(NaN);if(D.u(n))return new Date;if(n instanceof Date)return new Date(n);if("string"==typeof n&&!/Z$/i.test(n)){var r=n.match(h);if(r)return e?new Date(Date.UTC(r[1],r[2]-1,r[3]||1,r[4]||0,r[5]||0,r[6]||0,r[7]||0)):new Date(r[1],r[2]-1,r[3]||1,r[4]||0,r[5]||0,r[6]||0,r[7]||0)}return new Date(n)}(t),this.init()},d.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},d.$utils=function(){return D},d.isValid=function(){return!("Invalid Date"===this.$d.toString())},d.isSame=function(t,n){var e=g(t);return this.startOf(n)<=e&&e<=this.endOf(n)},d.isAfter=function(t,n){return g(t) Date: Tue, 16 Mar 2021 11:11:41 +0100 Subject: [PATCH 105/261] Variable ENCODE_SHELL --- pod/custom/settings_local.py.example | 5 +++++ pod/video/encode.py | 15 +++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/pod/custom/settings_local.py.example b/pod/custom/settings_local.py.example index 1bfedc1401..aff11f78ca 100644 --- a/pod/custom/settings_local.py.example +++ b/pod/custom/settings_local.py.example @@ -503,6 +503,11 @@ FFMPEG_MISC_PARAMS = " -hide_banner -y " FFMPEG_SCALE = ' -vf "scale=-2:{height}" ' # to use in GPU, specify ' -vf "scale_npp=-2:{height}:interp_algo=super" ' +""" +# Pour spécifier le shell utilisé pour lancer la commande ffmpeg (/bin/sh par défaut) +""" +ENCODE_SHELL = '/bin/sh' + """ # bitrate audio pour l'encodage M4A # (encodage des fichiers audio envoyés sur la plateforme) diff --git a/pod/video/encode.py b/pod/video/encode.py index b046fb3ab0..3ca3d4577c 100755 --- a/pod/video/encode.py +++ b/pod/video/encode.py @@ -48,6 +48,9 @@ 'start_transcript' ) +ENCODE_SHELL = getattr( + settings, 'ENCODE_SHELL', '/bin/sh') + USE_ESTABLISHMENT = getattr( settings, 'USE_ESTABLISHMENT_FIELD', False) @@ -547,7 +550,11 @@ def encode_video_mp4(source, cmd, output_dir): msg += "- %s\n" % ffmpegMp4Command with open(logfile, "ab") as f: procs.append(subprocess.Popen( - ffmpegMp4Command, shell=True, stdout=f, stderr=f)) + ffmpegMp4Command, + shell=True, + executable=ENCODE_SHELL + stdout=f, + stderr=f)) msg += "\n- Encoding Mp4: %s" % time.ctime() with open(logfile, "a") as f: f.write(msg) @@ -790,7 +797,11 @@ def encode_video_playlist(source, cmd, output_dir): msg += "- %s\n" % ffmpegPlaylistCommand with open(logfile, "ab") as f: procs.append(subprocess.Popen( - ffmpegPlaylistCommand, shell=True, stdout=f, stderr=f)) + ffmpegMp4Command, + shell=True, + executable=ENCODE_SHELL + stdout=f, + stderr=f)) msg += "\n- Encoding Playlist: %s" % time.ctime() with open(logfile, "a") as f: f.write(msg) From e62026ec9aec967047aa69875588caa3f073833c Mon Sep 17 00:00:00 2001 From: Frederic Colau Date: Tue, 16 Mar 2021 11:21:54 +0100 Subject: [PATCH 106/261] fix syntax --- pod/video/encode.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pod/video/encode.py b/pod/video/encode.py index 3ca3d4577c..3ff9026179 100755 --- a/pod/video/encode.py +++ b/pod/video/encode.py @@ -552,7 +552,7 @@ def encode_video_mp4(source, cmd, output_dir): procs.append(subprocess.Popen( ffmpegMp4Command, shell=True, - executable=ENCODE_SHELL + executable=ENCODE_SHELL, stdout=f, stderr=f)) msg += "\n- Encoding Mp4: %s" % time.ctime() @@ -799,7 +799,7 @@ def encode_video_playlist(source, cmd, output_dir): procs.append(subprocess.Popen( ffmpegMp4Command, shell=True, - executable=ENCODE_SHELL + executable=ENCODE_SHELL, stdout=f, stderr=f)) msg += "\n- Encoding Playlist: %s" % time.ctime() From c34a99cdd669eecdb37fca02000d0682f95dcaf3 Mon Sep 17 00:00:00 2001 From: Frederic Colau Date: Tue, 16 Mar 2021 11:25:09 +0100 Subject: [PATCH 107/261] fix flak8 --- pod/video/encode.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pod/video/encode.py b/pod/video/encode.py index 3ff9026179..4cb066d662 100755 --- a/pod/video/encode.py +++ b/pod/video/encode.py @@ -797,7 +797,7 @@ def encode_video_playlist(source, cmd, output_dir): msg += "- %s\n" % ffmpegPlaylistCommand with open(logfile, "ab") as f: procs.append(subprocess.Popen( - ffmpegMp4Command, + ffmpegPlaylistCommand, shell=True, executable=ENCODE_SHELL, stdout=f, From e5ab0d23ec798d69ffcccedcb71ed9927a8808b9 Mon Sep 17 00:00:00 2001 From: Olivier Bado Date: Tue, 16 Mar 2021 11:40:42 +0100 Subject: [PATCH 108/261] USe markdown format for LICENCE file + minor changes on README --- .gitignore | 1 + LICENSE | 165 --------------------------------------------- LICENSE.md | 157 ++++++++++++++++++++++++++++++++++++++++++ README.md | 20 +++--- pod/live/models.py | 2 + 5 files changed, 171 insertions(+), 174 deletions(-) delete mode 100644 LICENSE create mode 100644 LICENSE.md diff --git a/.gitignore b/.gitignore index 64f36e0eb5..53ac41a8e5 100644 --- a/.gitignore +++ b/.gitignore @@ -52,6 +52,7 @@ settings_local.py pod/static/ *.bak .coverage +htmlcov # IDE Files # ############# diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 65c5ca88a6..0000000000 --- a/LICENSE +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..44e857283c --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,157 @@ +### GNU LESSER GENERAL PUBLIC LICENSE + +Version 3, 29 June 2007 + +Copyright (C) 2007 Free Software Foundation, Inc. + + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + +This version of the GNU Lesser General Public License incorporates the +terms and conditions of version 3 of the GNU General Public License, +supplemented by the additional permissions listed below. + +#### 0. Additional Definitions. + +As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the +GNU General Public License. + +"The Library" refers to a covered work governed by this License, other +than an Application or a Combined Work as defined below. + +An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + +A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + +The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + +The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + +#### 1. Exception to Section 3 of the GNU GPL. + +You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + +#### 2. Conveying Modified Versions. + +If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + +- a) under this License, provided that you make a good faith effort + to ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or +- b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + +#### 3. Object Code Incorporating Material from Library Header Files. + +The object code form of an Application may incorporate material from a +header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + +- a) Give prominent notice with each copy of the object code that + the Library is used in it and that the Library and its use are + covered by this License. +- b) Accompany the object code with a copy of the GNU GPL and this + license document. + +#### 4. Combined Works. + +You may convey a Combined Work under terms of your choice that, taken +together, effectively do not restrict modification of the portions of +the Library contained in the Combined Work and reverse engineering for +debugging such modifications, if you also do each of the following: + +- a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. +- b) Accompany the Combined Work with a copy of the GNU GPL and this + license document. +- c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. +- d) Do one of the following: + - 0) Convey the Minimal Corresponding Source under the terms of + this License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + - 1) Use a suitable shared library mechanism for linking with + the Library. A suitable mechanism is one that (a) uses at run + time a copy of the Library already present on the user's + computer system, and (b) will operate properly with a modified + version of the Library that is interface-compatible with the + Linked Version. +- e) Provide Installation Information, but only if you would + otherwise be required to provide such information under section 6 + of the GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the Application + with a modified version of the Linked Version. (If you use option + 4d0, the Installation Information must accompany the Minimal + Corresponding Source and Corresponding Application Code. If you + use option 4d1, you must provide the Installation Information in + the manner specified by section 6 of the GNU GPL for conveying + Corresponding Source.) + +#### 5. Combined Libraries. + +You may place library facilities that are a work based on the Library +side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + +- a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities, conveyed under the terms of this License. +- b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + +#### 6. Revised Versions of the GNU Lesser General Public License. + +The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +as you received it specifies that a certain numbered version of the +GNU Lesser General Public License "or any later version" applies to +it, you have the option of following the terms and conditions either +of that published version or of any later version published by the +Free Software Foundation. If the Library as you received it does not +specify a version number of the GNU Lesser General Public License, you +may choose any version of the GNU Lesser General Public License ever +published by the Free Software Foundation. + +If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/README.md b/README.md index 3e93cead3e..5d1f4531e7 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,19 @@ - -# Pod Version 2 +# Pod v2 +Testing status -**Plateforme de gestion de fichier vidéo** +## Plateforme de gestion de fichier vidéo -Créer en 2014, le projet Pod a connu de nombreux changement ces dernières années. Initié à l'[Université de Lille](https://www.univ-lille.fr/ "Université de Lille"), il est depuis septembre 2015 piloté par le consortium [Esup Portail](https://www.esup-portail.org/ "Esup Portail") et soutenu également par le [Ministère de l'Enseignement supérieur, de la Recherche et de l'Innovation](http://www.enseignementsup-recherche.gouv.fr/ "Ministère de l'Enseignement supérieur, de la Recherche et de l'Innovation"). +Créé en 2014, le projet Pod a connu de nombreux changement ces dernières années. Initié à l’[Université de Lille](https://www.univ-lille.fr/), il est depuis septembre 2015 piloté par le consortium [Esup Portail](https://www.esup-portail.org/) et soutenu également par le [Ministère de l’Enseignement supérieur, de la Recherche et de l’Innovation](http://www.enseignementsup-recherche.gouv.fr/). -Le projet et la plateforme qui porte le même nom ont pour but de faciliter la mise à disposition de vidéo et de ce fait, d'encourager l'utilisation de celles-ci dans le cadre de l'enseignement et la recherche. +Le projet et la plateforme qui porte le même nom ont pour but de faciliter la mise à disposition de vidéo et de ce fait, d’encourager l’utilisation de celles-ci dans le cadre de l’enseignement et la recherche. -### Retrouvez toute la documentation (installation, paramétrage etc.) en suivant ce lien : [Documentation technique](https://www.esup-portail.org/wiki/display/ES/esup-pod "Documentation") +### Documentation technique +* Accédez à toute la documentation (installation, paramétrage etc.) [sur notre wiki](https://www.esup-portail.org/wiki/display/ES/esup-pod "Documentation") - | | Ministère de lʼEnseignement supérieur, de la Recherche et de lʼInnovation + + | | Ministère de lʼEnseignement supérieur, de la Recherche et de lʼInnovation :-----:|:-----:|:----: -### Crédits -* static/default.svg : Icon made by Freepik +## Crédits tiers +* static/default.svg : Icon made by [Freepik](https://www.freepik.com) diff --git a/pod/live/models.py b/pod/live/models.py index 67ad488325..99b75ce9be 100644 --- a/pod/live/models.py +++ b/pod/live/models.py @@ -1,3 +1,5 @@ +"""Esup-Pod "live" models.""" + from django.db import models from django.conf import settings from django.utils.translation import ugettext_lazy as _ From 03a10987b092613a964cd8f39689429ced774a31 Mon Sep 17 00:00:00 2001 From: Joshua Baubry Date: Tue, 16 Mar 2021 15:02:42 +0100 Subject: [PATCH 109/261] fix flake8 + fix somes issues --- pod/podfile/static/podfile/js/filewidget.js | 1 - pod/podfile/views.py | 22 ++++++++------------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/pod/podfile/static/podfile/js/filewidget.js b/pod/podfile/static/podfile/js/filewidget.js index e89d591b43..4097a2ba94 100644 --- a/pod/podfile/static/podfile/js/filewidget.js +++ b/pod/podfile/static/podfile/js/filewidget.js @@ -35,7 +35,6 @@ if(typeof loaded == 'undefined') { $(document).on("click", "a.folder", function(e) { e.preventDefault(); - console.log("opened file") $('#podfile #list_folders_sub a.folder-opened').removeClass('folder-opened'); $(this).addClass('folder-opened'); $('#files').addClass('loading'); diff --git a/pod/podfile/views.py b/pod/podfile/views.py index a367332928..2137dad78c 100644 --- a/pod/podfile/views.py +++ b/pod/podfile/views.py @@ -14,7 +14,6 @@ from django.core.exceptions import ObjectDoesNotExist from django.contrib.auth.models import User from .models import UserFolder -from pod.authentication.models import AccessGroup from .models import CustomFileModel from .models import CustomImageModel from .forms import UserFolderForm @@ -71,7 +70,7 @@ def home(request, type=None): UserFolder, name="home", owner=request.user) share_folder = UserFolder.objects.filter( - groups=AccessGroup.objects.filter(users__user=request.user)).exclude( + groups=request.user.owner.accessgroup_set.all()).exclude( owner=request.user).order_by('owner', 'id') share_folder_user = UserFolder.objects.filter( @@ -105,8 +104,8 @@ def get_current_session_folder(request): 'current_session_folder', "home")) | Q( users=request.user, name=request.session.get( 'current_session_folder', "home")) | Q( - groups=AccessGroup.objects.filter( - users__user=request.user), name=request.session.get( + groups=request.user.owner.accessgroup_set.all( + ), name=request.session.get( 'current_session_folder', "home"))) except ObjectDoesNotExist: if(request.user.is_superuser): @@ -127,8 +126,6 @@ def get_current_session_folder(request): @csrf_protect @staff_member_required(redirect_field_name='referrer') def get_folder_files(request, id, type=None): - print("==> get_folder_file") - if type is None: type = request.GET.get('type', None) folder = get_object_or_404(UserFolder, id=id) @@ -137,14 +134,13 @@ def get_folder_files(request, id, type=None): and not (folder.groups.filter( name__in=[ name[0] - for name in AccessGroup.objects.filter( - users__user=request.user).values_list('name') + for name in request.user.owner.accessgroup_set.values_list( + 'name') ]).exists()) and not ( request.user.is_superuser or request.user.has_perm( "podfile.change_userfolder")) and not ( request.user in folder.users.all())): - print("not access") messages.add_message( request, messages.ERROR, _(u'You cannot see this folder.')) @@ -175,8 +171,7 @@ def get_rendered(request): ).exclude(owner=request.user, name="home") share_folder = UserFolder.objects.filter( - groups__in=AccessGroup.objects.filter( - users__user=request.user) + groups__in=request.user.owner.accessgroup_set.all() ).exclude(owner=request.user).order_by('owner', 'id') share_folder_user = UserFolder.objects.filter( @@ -535,7 +530,6 @@ def file_edit_save(request, folder): @csrf_protect @staff_member_required(redirect_field_name='referrer') def get_file(request, type): - print("==> get_file") id = None if request.method == 'POST' and request.POST.get('src'): id = request.POST.get('src') @@ -549,8 +543,8 @@ def get_file(request, type): and not reqfile.folder.groups.filter( name__in=[ name[0] - for name in AccessGroup.objects.filter( - users__user=request.user).values_list('name') + for name in request.user.owner.accessgroup_set.values_list( + 'name') ]).exists() and not (request.user.is_superuser or request.user.has_perm( "podfile.change_customfilemodel") or request.user.has_perm( From 0fcdaf5ff04728ae3ed238a0f48775f6bd5e8f4a Mon Sep 17 00:00:00 2001 From: Joshua Baubry Date: Tue, 16 Mar 2021 15:20:37 +0100 Subject: [PATCH 110/261] change name to code_name --- pod/authentication/models.py | 2 +- pod/podfile/views.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pod/authentication/models.py b/pod/authentication/models.py index 77d0a1db1a..b1511acdbb 100644 --- a/pod/authentication/models.py +++ b/pod/authentication/models.py @@ -144,7 +144,7 @@ def create_groupsite_profile(sender, instance, created, **kwargs): class AccessGroup(models.Model): display_name = models.CharField( max_length=64, unique=True, blank=False, default="") - name = models.CharField( + code_name = models.CharField( max_length=64, unique=True, blank=False, default="") sites = models.ManyToManyField(Site) users = models.ManyToManyField(Owner, blank=True) diff --git a/pod/podfile/views.py b/pod/podfile/views.py index 2137dad78c..1c677af857 100644 --- a/pod/podfile/views.py +++ b/pod/podfile/views.py @@ -132,10 +132,10 @@ def get_folder_files(request, id, type=None): if (request.user != folder.owner and not (folder.groups.filter( - name__in=[ + code_name__in=[ name[0] for name in request.user.owner.accessgroup_set.values_list( - 'name') + 'code_name') ]).exists()) and not ( request.user.is_superuser or request.user.has_perm( @@ -541,10 +541,10 @@ def get_file(request, type): reqfile = get_object_or_404(CustomFileModel, id=id) if (request.user != reqfile.folder.owner and not reqfile.folder.groups.filter( - name__in=[ + code_name__in=[ name[0] for name in request.user.owner.accessgroup_set.values_list( - 'name') + 'code_name') ]).exists() and not (request.user.is_superuser or request.user.has_perm( "podfile.change_customfilemodel") or request.user.has_perm( From ab2c8ed03429bffa4e3102a7ee88d138872b34ca Mon Sep 17 00:00:00 2001 From: Joshua Baubry Date: Tue, 16 Mar 2021 17:07:04 +0100 Subject: [PATCH 111/261] fix unit test --- pod/video/tests/test_stats_view.py | 5 +++-- pod/video/tests/test_views.py | 12 ++++++++---- pod/video/views.py | 6 +++--- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/pod/video/tests/test_stats_view.py b/pod/video/tests/test_stats_view.py index 7b07e79db1..3ef10f2d17 100644 --- a/pod/video/tests/test_stats_view.py +++ b/pod/video/tests/test_stats_view.py @@ -9,6 +9,7 @@ from pod.video.models import Channel, Theme, Video, Type from pod.video.views import get_all_views_count, stats_view from django.contrib.sites.models import Site +from pod.authentication.models import AccessGroup import json import logging @@ -324,7 +325,7 @@ def test_stats_view_GET_request_video_access_rights(self): # **************************************************** # # ************ Test restricted by group ************** # # **************************************************** # - group1 = Group.objects.create(name="group1") + group1 = AccessGroup.objects.create(code_name="group1") self.video3.password = None self.video3.is_restricted = True self.video3.restrict_access_to_groups.add(group1) @@ -343,7 +344,7 @@ def test_stats_view_GET_request_video_access_rights(self): status_code=404) # add visitor to the group of the video # test that visitor has access rights - self.visitor.groups.add(group1) + self.visitor.owner.accessgroup_set.add(group1) response = self.client.get(url, {"from": "video"}) self.assertContains( response, diff --git a/pod/video/tests/test_views.py b/pod/video/tests/test_views.py index 6a26c9b4c0..b1962bd702 100644 --- a/pod/video/tests/test_views.py +++ b/pod/video/tests/test_views.py @@ -3,6 +3,7 @@ from django.test import Client from django.contrib.auth.models import User from django.contrib.auth.models import Group +from pod.authentication.models import AccessGroup from ..models import Channel from ..models import Theme @@ -427,6 +428,9 @@ def setUp(self): Group.objects.create(name='student') Group.objects.create(name='employee') Group.objects.create(name='member') + AccessGroup.objects.create(code_name='group1',display_name="Group 1") + AccessGroup.objects.create(code_name='group2',display_name="Group 2") + AccessGroup.objects.create(code_name='group3',display_name="Group 3") v0 = Video.objects.create( title="Video1", owner=user, video="test1.mp4", type=Type.objects.get(id=1)) @@ -478,14 +482,14 @@ def test_video_get_request(self): response = self.client.get("/video/%s/" % v.slug) self.assertEqual(response.status_code, 200) # test restricted group - v.restrict_access_to_groups.add(Group.objects.get(name='employee')) - v.restrict_access_to_groups.add(Group.objects.get(name='member')) + v.restrict_access_to_groups.add(AccessGroup.objects.get(code_name='group2')) + v.restrict_access_to_groups.add(AccessGroup.objects.get(code_name='group3')) response = self.client.get("/video/%s/" % v.slug) self.assertEqual(response.status_code, 403) - self.user.groups.add(Group.objects.get(name='student')) + self.user.owner.accessgroup_set.add(AccessGroup.objects.get(code_name='group1')) response = self.client.get("/video/%s/" % v.slug) self.assertEqual(response.status_code, 403) - self.user.groups.add(Group.objects.get(name='employee')) + self.user.owner.accessgroup_set.add(AccessGroup.objects.get(code_name='group2')) response = self.client.get("/video/%s/" % v.slug) self.assertEqual(response.status_code, 200) # TODO test with password diff --git a/pod/video/views.py b/pod/video/views.py index e7ca8a3b86..64742e53ff 100644 --- a/pod/video/views.py +++ b/pod/video/views.py @@ -492,10 +492,10 @@ def videos(request): def is_in_video_groups(user, video): - return user.groups.filter( - name__in=[ + return user.owner.accessgroup_set.filter( + code_name__in=[ name[0] - for name in video.restrict_access_to_groups.values_list('name') + for name in video.restrict_access_to_groups.values_list('code_name') ] ).exists() From 8ae686c0744fee107b62aed25bf69eb687482714 Mon Sep 17 00:00:00 2001 From: Joshua Baubry Date: Wed, 17 Mar 2021 12:38:22 +0100 Subject: [PATCH 112/261] fix flake8 --- pod/video/tests/test_stats_view.py | 1 - pod/video/tests/test_views.py | 18 +++++++++++------- pod/video/views.py | 3 ++- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/pod/video/tests/test_stats_view.py b/pod/video/tests/test_stats_view.py index 3ef10f2d17..48396bc1ec 100644 --- a/pod/video/tests/test_stats_view.py +++ b/pod/video/tests/test_stats_view.py @@ -4,7 +4,6 @@ from django.conf import settings from django.test import TestCase, Client from django.urls import reverse, NoReverseMatch -from django.contrib.auth.models import Group from pod.authentication.models import User from pod.video.models import Channel, Theme, Video, Type from pod.video.views import get_all_views_count, stats_view diff --git a/pod/video/tests/test_views.py b/pod/video/tests/test_views.py index b1962bd702..901b995c6a 100644 --- a/pod/video/tests/test_views.py +++ b/pod/video/tests/test_views.py @@ -428,9 +428,9 @@ def setUp(self): Group.objects.create(name='student') Group.objects.create(name='employee') Group.objects.create(name='member') - AccessGroup.objects.create(code_name='group1',display_name="Group 1") - AccessGroup.objects.create(code_name='group2',display_name="Group 2") - AccessGroup.objects.create(code_name='group3',display_name="Group 3") + AccessGroup.objects.create(code_name='group1', display_name="Group 1") + AccessGroup.objects.create(code_name='group2', display_name="Group 2") + AccessGroup.objects.create(code_name='group3', display_name="Group 3") v0 = Video.objects.create( title="Video1", owner=user, video="test1.mp4", type=Type.objects.get(id=1)) @@ -482,14 +482,18 @@ def test_video_get_request(self): response = self.client.get("/video/%s/" % v.slug) self.assertEqual(response.status_code, 200) # test restricted group - v.restrict_access_to_groups.add(AccessGroup.objects.get(code_name='group2')) - v.restrict_access_to_groups.add(AccessGroup.objects.get(code_name='group3')) + v.restrict_access_to_groups.add(AccessGroup.objects.get( + code_name='group2')) + v.restrict_access_to_groups.add(AccessGroup.objects.get( + code_name='group3')) response = self.client.get("/video/%s/" % v.slug) self.assertEqual(response.status_code, 403) - self.user.owner.accessgroup_set.add(AccessGroup.objects.get(code_name='group1')) + self.user.owner.accessgroup_set.add(AccessGroup.objects.get( + code_name='group1')) response = self.client.get("/video/%s/" % v.slug) self.assertEqual(response.status_code, 403) - self.user.owner.accessgroup_set.add(AccessGroup.objects.get(code_name='group2')) + self.user.owner.accessgroup_set.add(AccessGroup.objects.get( + code_name='group2')) response = self.client.get("/video/%s/" % v.slug) self.assertEqual(response.status_code, 200) # TODO test with password diff --git a/pod/video/views.py b/pod/video/views.py index 64742e53ff..ed27d7b13e 100644 --- a/pod/video/views.py +++ b/pod/video/views.py @@ -495,7 +495,8 @@ def is_in_video_groups(user, video): return user.owner.accessgroup_set.filter( code_name__in=[ name[0] - for name in video.restrict_access_to_groups.values_list('code_name') + for name in video.restrict_access_to_groups.values_list( + 'code_name') ] ).exists() From b9f83b33d5e9b6e24d89a41033e1236f9bcd06d2 Mon Sep 17 00:00:00 2001 From: Joshua Baubry Date: Wed, 17 Mar 2021 13:13:11 +0100 Subject: [PATCH 113/261] channel access group is now for upload videos on channel --- pod/video/forms.py | 5 ++++- pod/video/views.py | 15 --------------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/pod/video/forms.py b/pod/video/forms.py index 30220914f8..9650e0ac88 100644 --- a/pod/video/forms.py +++ b/pod/video/forms.py @@ -538,10 +538,13 @@ def remove_field(self, field): def set_queryset(self): if self.current_user is not None: + users_groups = self.current_user.owner.accessgroup_set.all() user_channels = Channel.objects.all() if self.is_superuser else ( self.current_user.owners_channels.all( - ) | self.current_user.users_channels.all() + ) | self.current_user.users_channels.all( + ) | Channel.objects.filter(allow_to_groups=users_groups) ).distinct() + print(user_channels.all()) user_channels.filter(sites=get_current_site(None)) if user_channels: self.fields["channel"].queryset = user_channels diff --git a/pod/video/views.py b/pod/video/views.py index ed27d7b13e..1fbe735ddb 100644 --- a/pod/video/views.py +++ b/pod/video/views.py @@ -175,25 +175,10 @@ def paginator(videos_list, page): return videos -def check_access_to_channel(request, channel): - if channel.allow_to_groups.exists(): - has_access = False - for group in channel.allow_to_groups.all(): - if request.user in group.users.all(): - has_access = True - if not has_access: - messages.add_message( - request, messages.ERROR, _( - u'You cannot view this channel.')) - raise PermissionDenied - - def channel(request, slug_c, slug_t=None): channel = get_object_or_404(Channel, slug=slug_c, sites=get_current_site(request)) - check_access_to_channel(request, channel) - videos_list = VIDEOS.filter(channel=channel) theme = None From 3a6101cd5f91c5b6c398f0bf8e0916f51cc27f6c Mon Sep 17 00:00:00 2001 From: Olivier Bado Date: Wed, 17 Mar 2021 16:28:02 +0100 Subject: [PATCH 114/261] :bug: Correct a CSS bug when dark mode is not enabled + remove un unwanted css fill on some feather icons + replace "http" by "feed" protocol for RSS links + Update contributing.md and add licence badge in Readme --- .coveragerc | 7 + CONTRIBUTING.md | 14 +- README.md | 2 + pod/bbb/templates/bbb/card.html | 4 +- pod/main/static/css/dark.css | 65 +++-- pod/main/static/css/pod.css | 266 ++++++++++++--------- pod/main/templates/aside.html | 2 +- pod/main/templates/navbar_collapse.html | 10 +- pod/video/templates/channel/channel.html | 4 +- pod/video/templates/videos/card.html | 7 +- pod/video/templates/videos/video-info.html | 6 +- pod/video/templates/videos/videos.html | 10 +- 12 files changed, 214 insertions(+), 183 deletions(-) create mode 100755 .coveragerc diff --git a/.coveragerc b/.coveragerc new file mode 100755 index 0000000000..09009dbc55 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,7 @@ + +[report] +# Here you can exclude a file from coverage testing + +# nb : you can also add a "# pragma: no cover" +# on each function you don't want to be covered +omit = */migrations/* diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d3ebbd2dc3..3c4a86b558 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,6 +19,7 @@ These are mostly guidelines, not rules. Use your best judgment, and feel free to * [Coding conventions](#coding-conventions) * [JavaScript Styleguide](#javascript-styleguide) + * [Python Styleguide](#python-styleguide) ## Code of Conduct @@ -28,7 +29,7 @@ By participating, you are expected to uphold this code. Please report unacceptab ## I don't want to read this whole thing I just have a question!!! -If chat is more your speed, you can join the Pod team on Rocket: https://rocket.esup-portail.org/channel/esup_-_pod +If chat is more your speed, you can join the Pod team on Rocket chat: https://rocket.esup-portail.org/channel/esup_-_pod @@ -114,9 +115,6 @@ While the prerequisites above must be satisfied prior to having your pull reques * :racehorse: `:racehorse:` when improving performance * :non-potable_water: `:non-potable_water:` when plugging memory leaks * :memo: `:memo:` when writing docs - * :penguin: `:penguin:` when fixing something on Linux - * :apple: `:apple:` when fixing something on macOS - * :checkered_flag: `:checkered_flag:` when fixing something on Windows * :bug: `:bug:` when fixing a bug * :fire: `:fire:` when removing code or files * :green_heart: `:green_heart:` when fixing the CI build @@ -136,11 +134,9 @@ Start reading our code and you'll get the hang of it. We optimize for readabilit ### JavaScript Styleguide -All JavaScript code is linted with [Prettier](https://prettier.io/). - -* Prefer the object spread operator (`{...anotherObj}`) to `Object.assign()` - - +All JavaScript code is linted with [eslint](https://eslint.org/). +### Python Styleguide +All python code is linted with [flake8](https://flake8.pycqa.org/en/latest/) diff --git a/README.md b/README.md index 5d1f4531e7..dbacc8c5b8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # Pod v2 Testing status +![Licence LGPL 3.0](https://img.shields.io/github/license/EsupPortail/Esup-Pod) + ## Plateforme de gestion de fichier vidéo Créé en 2014, le projet Pod a connu de nombreux changement ces dernières années. Initié à l’[Université de Lille](https://www.univ-lille.fr/), il est depuis septembre 2015 piloté par le consortium [Esup Portail](https://www.esup-portail.org/) et soutenu également par le [Ministère de l’Enseignement supérieur, de la Recherche et de l’Innovation](http://www.enseignementsup-recherche.gouv.fr/). diff --git a/pod/bbb/templates/bbb/card.html b/pod/bbb/templates/bbb/card.html index 6b0b0f1313..6bb492f3e8 100644 --- a/pod/bbb/templates/bbb/card.html +++ b/pod/bbb/templates/bbb/card.html @@ -44,11 +44,11 @@ {% trans "Already published"%} {% if request.user != record.encoded_by %} {% trans "by"%} {{ record.encoded_by.first_name }} {{ record.encoded_by.last_name }} ({{ record.encoded_by.email }}) - {% endif %} + {% endif %} {% endif %} - +
    {% endspaceless %} \ No newline at end of file diff --git a/pod/main/static/css/dark.css b/pod/main/static/css/dark.css index d95cf63813..ede0da335a 100644 --- a/pod/main/static/css/dark.css +++ b/pod/main/static/css/dark.css @@ -1,24 +1,15 @@ /** Dark mode for Esup Pod **/ -[data-theme="light"] { - /* CUSTOM COLORS */ - --bg-color: #FFF; - --font-color: #222; - /* BOOTSTRAP COLORS */ - --primary: #b03c7e; - --primary2: #b03c7e; - --light: #f8f9fa; - --dark: #343a40; - --color-formfields: #f1f1f1; -} [data-theme="dark"] { --background-color: #1e1e2c; + /* CUSTOM COLORS */ --link-color: #fdb6de; --activelink-color: #fbdfef; --color-shark: #212529; --bg-color: #303238; --font-color: #f8f9fa; + /* BOOTSTRAP COLORS */ --primary: #b03c7e; --primary2: var(--primary); @@ -28,6 +19,7 @@ --color-formfields: #454c52; --color-silver-chalice: #000; --color-alto: var(--bg-color); + /* Video Comment variable */ --primary-background-color: var(--bg-color) !important; --third-background-color: var(--bg-color) !important; @@ -35,27 +27,27 @@ } [data-theme="dark"] a, -[data-theme="dark"] .navbar-light .navbar-nav .nav-link{ +[data-theme="dark"] .navbar-light .navbar-nav .nav-link { color: var(--link-color); } [data-theme="dark"] .navbar-light .navbar-nav .nav-link:focus, -[data-theme="dark"] .navbar-light .navbar-nav .nav-link:hover{ +[data-theme="dark"] .navbar-light .navbar-nav .nav-link:hover { color: var(--activelink-color); } -[data-theme="dark"] .form-control::placeholder{ +[data-theme="dark"] .form-control::placeholder { color: #BEC1C6; } -[data-theme="dark"] .breadcrumb-item + .breadcrumb-item::before{ +[data-theme="dark"] .breadcrumb-item + .breadcrumb-item::before { color:var(--white); } -[data-theme="dark"] .breadcrumb-item.active{ +[data-theme="dark"] .breadcrumb-item.active { color:#A8ABB3; } [data-theme="dark"] .nav-tabs .nav-item.show .nav-link, -[data-theme="dark"] .nav-tabs .nav-link.active{ +[data-theme="dark"] .nav-tabs .nav-link.active { background-color: var(--bg-color); color:var(--white); border-bottom: none; @@ -64,13 +56,13 @@ [data-theme="dark"] .btn, [data-theme="dark"] .dropdown-item, -[data-theme="dark"] footer{ +[data-theme="dark"] footer { color: var(--font-color); } -[data-theme="dark"] .btn:hover{ +[data-theme="dark"] .btn:hover { color: inherit; } -[data-theme="dark"] .btn.btn-light{ +[data-theme="dark"] .btn.btn-light { background-color: var(--dark); border-color: var(--dark); color: var(--primary); @@ -86,25 +78,24 @@ [data-theme="dark"] .btn-primary:not(:disabled):not(.disabled):active, [data-theme="dark"] .show>.btn-primary.dropdown-toggle, [data-theme] .badge-primary, -[data-theme="dark"] .btn-primary -{ +[data-theme="dark"] .btn-primary { background: var(--primary); border-color: var(--primary); box-shadow: none; color: var(--font-color); }*/ -[data-theme="dark"] .btn-secondary{ +[data-theme="dark"] .btn-secondary { color: var(--white); } -[data-theme="dark"] .btn-outline-primary>svg{ +[data-theme="dark"] .btn-outline-primary>svg { color: var(--primary); } [data-theme="dark"] .btn-outline-primary:hover>svg, -[data-theme="dark"] .btn-outline-primary:focus>svg{ +[data-theme="dark"] .btn-outline-primary:focus>svg { color: var(--white); } -[data-theme="dark"] .card{ +[data-theme="dark"] .card { background-color: var(--dark); border-color: var(--dark); } @@ -114,11 +105,10 @@ body.dark { } /* Video Comment override css dark mode */ -[data-theme="dark"] .comment_main .comment .comment_content -{ +[data-theme="dark"] .comment_main .comment .comment_content { box-shadow: 2px 2px 12px var(--dark); } -[data-theme="dark"] .comment_main .add_comment .add_comment_btn{ +[data-theme="dark"] .comment_main .add_comment .add_comment_btn { box-shadow: 4px 8px var(--bg-color); } @@ -126,25 +116,25 @@ body.dark { [data-theme="dark"] .comment_main .comment .comment_content_footer .add_comment, /* comment text-area wrapper */ [data-theme="dark"] .comment_main .add_comment .form-wrapper .new_comment.new_parent_comment, /* comment text-area */ [data-theme="dark"] .comment_main .comment .comment_content_footer .add_comment .new_comment, /* comment text-area */ -[data-theme] #podfile #dirs .folder-search, +[data-theme="dark"] #podfile #dirs .folder-search, [data-theme="dark"] #podfile .list_folders .folder_container:nth-child(2n), [data-theme="dark"] #podfile .list_folders_sub .folder_container:nth-child(2n), -[data-theme="dark"] .modal-content{ +[data-theme="dark"] .modal-content { background-color: var(--dark) !important; border-color: var(--dark) !important; color: #fff !important; } -[data-theme="dark"] .close{ +[data-theme="dark"] .close { color: #fff; } -[data-theme="dark"] #podfile #dirs .folder-search::placeholder{ +[data-theme="dark"] #podfile #dirs .folder-search::placeholder { color: #ccc; } -[data-theme="dark"] #podfile .col{ +[data-theme="dark"] #podfile .col { background-color: var(--bg-color); } -[data-theme="dark"] .list-group-item-action:focus, .list-group-item-action:hover -{ +[data-theme="dark"] .list-group-item-action:focus, +[data-theme="dark"] .list-group-item-action:hover { background-color: var(--dark); } @@ -160,8 +150,7 @@ body.dark { [data-theme="dark"] .select2-choice .select2-search-choice-close + div, [data-theme="dark"] .select2-dropdown-open .select2-choice, [data-theme="dark"] .select2-results .select2-no-results, -[data-theme="dark"] .select2-results .select2-searching -{ +[data-theme="dark"] .select2-results .select2-searching { background: var(--bg-color); border-color: var(--bg-color); color: var(--font-color); diff --git a/pod/main/static/css/pod.css b/pod/main/static/css/pod.css index d7348578ce..d50d3df792 100755 --- a/pod/main/static/css/pod.css +++ b/pod/main/static/css/pod.css @@ -1,24 +1,36 @@ /*** Esup Pod main CSS ***/ -/* COMMON COLORS */ :root { + /* CUSTOM COLORS */ + --bg-color: #FFF; + --font-color: #222; + + /* BOOTSTRAP COLORS */ + --primary: #b03c7e; + --primary2: #b03c7e; + --light: #f8f9fa; + --dark: #343a40; + --color-formfields: #f1f1f1; + + /* COMMON COLORS */ --color-transparent:transparent; --color-white: white; --color-black: black; - --color-alto:#ddd; + --color-alto: #ddd; --color-sisal: rgba(218,208,190,1); --color-black-alpha: rgba(0, 0, 0, .6); - --color-silver:#ccc; + --color-silver: #ccc; --color-fuzzy-wuzzy-brown: rgba(201, 76, 76, .3); - --color-silver-chalice:#aaa; + --color-silver-chalice: #aaa; --color-outer-space: rgba(40,48,56, .5); - --color-red:#FF0000; - --color-mine-shaft:#222; + --color-red: #FF0000; + --color-mine-shaft: #222; } .navbar-light.navbar-nav.nav-link { color: var(--font-color); } -.navbar-light.navbar-nav.nav-link:focus,.navbar-light.navbar-nav.nav-link:hover { +.navbar-light.navbar-nav.nav-link:focus, +.navbar-light.navbar-nav.nav-link:hover { color: var(--primary); } .navbar-brand { @@ -45,7 +57,8 @@ background-color: var(--gray-dark)!important; } -.nav-tabs.nav-item.show.nav-link,.nav-tabs.nav-link.active { +.nav-tabs.nav-item.show.nav-link, +.nav-tabs.nav-link.active { color: var(--color-white); background-color: var(--primary); border-color: var(--color-alto) var(--color-alto) var(--color-alto); @@ -70,9 +83,12 @@ border-color: var(--primary); } -/*a.btn-outline-primary svg { +a.btn-outline-primary svg.feather { + fill: transparent; +} +.social_links a svg.feather{ fill: var(--primary); -}*/ +} #formfields.btn { color: var(--font-color); @@ -93,16 +109,16 @@ height: 35px; } -.select2-container{ +.select2-container { position: static !important; height:auto; } -tr,.rowl{ +tr,.rowl { display: table-row !important; } -body[data-admin-utc-offset]{ +body[data-admin-utc-offset] { padding-top: 0; } @@ -115,33 +131,33 @@ body { .jumbotron { padding: 1rem 2rem; } -h1{ +h1 { font-size: 2rem; } label { font-variant: small-caps; } -.pod-mt-7{ +.pod-mt-7 { margin-top: 3.5rem; } -.breadcrumb,.jumbotron{ +.breadcrumb,.jumbotron { background: var(--light); } -.list-group-item{ +.list-group-item { background: var(--bg-color); - padding:.25rem 1.25rem; + padding: .25rem 1.25rem; } -.container-pod{ +.container-pod { max-width: 1400px; } /*** video ***/ #myTabContent#info p { - margin-top:.5rem; - margin-bottom:.5rem; + margin-top: .5rem; + margin-bottom: .5rem; } -#share legend{ +#share legend { /* align text with feather-icon */ line-height: 1em; } @@ -153,6 +169,8 @@ label { .link-center-pod { margin-left: auto; margin-right: auto; + display: block; + overflow: hidden; } /*** navbar **/ @@ -163,21 +181,21 @@ label { border-color:#b03c7e; }!important; }*/ -.btn-lang{ - padding: 0.2rem 0.25rem; +.btn-lang { + padding: .2rem .25rem; background: var(--color-transparent); width: 100%; text-align: left; } -.btn-lang-active{ +.btn-lang-active { background: var(--bg-color); color: var(--font-color); } -.navbar-inner-pod{ +.navbar-inner-pod { position: relative; } -.navbar-toggler{ - padding: 0.5rem; +.navbar-toggler { + padding: .5rem; line-height: inherit; font-size: 1rem; } @@ -197,7 +215,7 @@ label { background-color: var(--bg-color); } -.modal-title{ +.modal-title { display: flex; align-items: center; } @@ -205,30 +223,30 @@ label { /*.modal-pod-full { max-width: 90%; }*/ -.modal-pod-full.close{ - font-size:3rem; +.modal-pod-full.close { + font-size: 3rem; } -.title-chaine{ - margin-right: 0.5rem; +.title-chaine { + margin-right: .5rem; font-weight: 600; } -#listeChaines{ +#listeChaines { max-height: 30rem; overflow: auto; border-bottom: 1px solid var(--color-black); } -.liste-collapse{ +.liste-collapse { z-index: 900; } /**end modal **/ /*** tab **/ -.tab-content>.active{ +.tab-content>.active { border: 1px solid var(--color-alto); padding: 1.5rem; background: var(--bg-color); } -.nav-tabs{ +.nav-tabs { border: 0; } @@ -239,37 +257,37 @@ label { } /***aside ***/ -.open-aside{ +.open-aside { margin-right: 15px; } -#card-takenote.dropdown-menu{ +#card-takenote.dropdown-menu { border: none; } /*** modif taille logo ***/ -@media (max-width: 576px ){ - .navbar-brand img{ +@media (max-width: 576px ) { + .navbar-brand img { height: 35px; } - .navbar-brand{ + .navbar-brand { font-size: .9rem; } } -@media (max-width: 992px){ - .langs{ +@media (max-width: 992px) { + .langs { border-top: 1px solid var(--color-silver); } - .langs.active{ + .langs.active { /*background:var(--primary); */ border: none; color: var(--white); } - .btn-connexion{ + .btn-connexion { font-size: .9rem; } - .navbar-items-pod{ + .navbar-items-pod { position: absolute; - top:53px; - left:0; + top: 53px; + left: 0; padding: 1rem; width: 100%; } @@ -289,46 +307,46 @@ label { #s:-moz-placeholder { /* Firefox 18- */ color: var(--white); } - #s{ - width:1px; - border-radius:0; - box-shadow:none; + #s { + width: 1px; + border-radius: 0; + box-shadow: none; outline: none; - padding:0; - margin:0; - border:0; + padding: 0; + margin: 0; + border: 0; background-color: var(--color-transparent); - opacity:0; + opacity: 0; position: absolute; } - #s:focus{ - width:100%; - opacity:1; + #s:focus { + width: 100%; + opacity: 1; display: inline-block !important; position: absolute; /*background: var(--primary) !important;*/ padding: .5rem 1rem; left: 0; - top:0; + top: 0; z-index: 99; - color:var(--white) !important; + color: var(--white) !important; height: 74px; } - .navbar label{ + .navbar label { padding-left: 1px; - display:inline-block; - margin-top:0.3em; - color:var(--color-sisal); - text-shadow:0 0 0.1em var(--color-mine-shaft); + display: inline-block; + margin-top: .3em; + color: var(--color-sisal); + text-shadow: 0 0 .1em var(--color-mine-shaft); position: relative; - left:0.1em; - cursor:pointer; + left: .1em; + cursor: pointer; } } /*** end MQueries **/ -.login >.initials{ +.login >.initials { border-radius: 50%; /*background: var(--light);*/ color: var(--white) !important; @@ -336,10 +354,10 @@ label { height: 3rem; width: 3rem; } -.nav-link{ +.nav-link { padding: .25rem .5rem; } -button.nav-link{ +button.nav-link { background: none; border: none; cursor: pointer; @@ -357,43 +375,43 @@ button.nav-link{ } #videos_list.card-header,.playlist-videos.card-header { - position:absolute; - width:100%; + position: absolute; + width: 100%; background: var(--color-black-alpha); padding: 0 .25rem; z-index: 9; } #videos_list.card-header.text-muted { - color:var(--white) !important; + color: var(--white) !important; } -#videos_list.video-title{ +#videos_list.video-title { line-height: 1.2; display: inline-block; } div.video-card.d-flex { - min-height:70%; + min-height: 70%; /*position:relative;*/ - top:0; + top: 0; } a:hover { color: var(--primary); } -div.card a{ - overflow:hidden; -} +/*.card-img-top { + overflow: hidden; +}*/ div.card a img { transition: -webkit-transform.5s ease; transition: transform.5s ease; transition: transform.5s ease, -webkit-transform.5s ease } div.card a:hover>img { - -webkit-transform:scale(1.1); - transform:scale(1.1); - z-index:0; + -webkit-transform: scale(1.1); + transform: scale(1.1); + z-index: 0; } .card { @@ -407,11 +425,11 @@ div.card a:hover>img { right: 2px; /*width: 100%; text-align: center;*/ - border:none; + border: none; /*background: rgba(220,220,220);*/ /*height: 1rem;*/ } -.card-footer.feather,.card-header.feather{ +.card-footer.feather,.card-header.feather { height: 1rem; } /* menu channels */ @@ -443,7 +461,9 @@ div.card a:hover>img { } /** aside list video **/ -#filterType div.collapse:not(.show),#filterDiscipline div.collapse:not(.show),#filterTag div.collapse:not(.show) { +#filterType div.collapse:not(.show), +#filterDiscipline div.collapse:not(.show), +#filterTag div.collapse:not(.show) { height: 148px !important; overflow: hidden; @@ -452,15 +472,21 @@ div.card a:hover>img { -webkit-box-orient: vertical; } -#filterType div.collapsing,#filterDiscipline div.collapsing,#filterTag div.collapsing{ +#filterType div.collapsing, +#filterDiscipline div.collapsing, +#filterTag div.collapsing{ min-height: 148px !important; } -#filterTypea.collapsed:after,#filterDisciplinea.collapsed:after,#filterTaga.collapsed:after { +#filterTypea.collapsed:after, +#filterDisciplinea.collapsed:after, +#filterTaga.collapsed:after { content: '+'; } -#filterType a:not(.collapsed):after,#filterDiscipline a:not(.collapsed):after,#filterTag a:not(.collapsed):after { +#filterType a:not(.collapsed):after, +#filterDiscipline a:not(.collapsed):after, +#filterTag a:not(.collapsed):after { content: '-'; } /** ckeditor **/ @@ -469,7 +495,7 @@ div.card a:hover>img { } /** video form **/ .required { - color:var(--primary); + color: var(--primary); font-size: 1.3rem; } /*.form-group-required { @@ -479,27 +505,36 @@ div.card a:hover>img { .form-group-required.errors { background-color: var(--color-fuzzy-wuzzy-brown); } -#base-message-alert,#formalertdiv{ +#base-message-alert, +#formalertdiv { position: fixed; top: 50%; text-align: center; margin: 0 auto; left: 50%; - transform:translate(-50%, 0); + transform: translate(-50%, 0); z-index: 1000; } /** channel form **/ -#channel_form.selector,#enrichment_group_form.selector{ +#channel_form.selector, +#enrichment_group_form.selector { width: 100% !important; } -#channel_form.selector select,#enrichment_group_form.selector select { - width:100% !important; +#channel_form.selector select, +#enrichment_group_form.selector select { + width: 100% !important; } -#channel_form.selector-available,#channel_form.selector-chosen,#enrichment_group_form.selector-available,#enrichment_group_form.selector-chosen { +#channel_form.selector-available, +#channel_form.selector-chosen, +#enrichment_group_form.selector-available, +#enrichment_group_form.selector-chosen { width: 47% !important; } -#channel_form.selector-available h2,#channel_form.selector-chosen h2,#enrichment_group_form.selector-available h2,#enrichment_group_form.selector-chosen h2 { +#channel_form.selector-available h2, +#channel_form.selector-chosen h2, +#enrichment_group_form.selector-available h2, +#enrichment_group_form.selector-chosen h2 { margin: 0; padding: 8px; font-weight: 400; @@ -509,41 +544,42 @@ div.card a:hover>img { /* vignettes video */ @media (max-width: 575.98px) { - .pod-flex-direction{ + .pod-flex-direction { flex-direction: column; } } -@media screen and (min-width:768px){ +@media screen and (min-width:768px) { .card-img-top { - max-height:184.13px; + max-height: 184.13px; } } -@media screen and (min-width:992px){ +@media screen and (min-width:992px) { .card-img-top { - max-height:195.36px; + max-height: 195.36px; } .flex-2{ flex: 2; } } /*** footer **/ -footer{ - color:var(--color-silver-chalice); +footer { + color: var(--color-silver-chalice); } -footer a, footer a:hover{ +footer a, +footer a:hover { color: var(--white); } -.footer_links{ +.footer_links { list-style:none; } -.footer_links>li:before{ - margin-right:.5em; +.footer_links>li:before { + margin-right: .5em; content: ">"; font-weight: bold; } -.top_link:before{ +.top_link:before { content: "\21E7"; padding-right: 4px; text-decoration: none; @@ -552,15 +588,14 @@ footer a, footer a:hover{ } /*** Useful for additional owners ***/ -input.select2-input{ +input.select2-input { width: 100% !important; } -#view-counter-icon{ +#view-counter-icon { color: var(--primary); } - #viewers-list { position: absolute; right: 0; @@ -579,8 +614,8 @@ input.select2-input{ z-index: 1; } -#viewers-ul{height:200px;list-style-type: none;padding-left: 0;} -#viewers-ul{overflow:hidden; overflow-y:scroll;} +#viewers-ul {height:200px; list-style-type: none; padding-left: 0;} +#viewers-ul {overflow:hidden; overflow-y:scroll;} /* use to hide valid human chekbox in contact form to prevent spam */ #contact_us.valid_human { @@ -594,3 +629,4 @@ input.select2-input{ padding: 0 !important; margin: 0 !important; } + diff --git a/pod/main/templates/aside.html b/pod/main/templates/aside.html index fbc62cd703..441765c132 100644 --- a/pod/main/templates/aside.html +++ b/pod/main/templates/aside.html @@ -7,7 +7,7 @@
     {% trans 'Share' %}
    -

    +

    {% spaceless %} {% endspaceless %}
    -
    -
      -
    •  
    • -
    -
    +
    +
      +
    •  
    • +
    +
    - {% endif %} - + + {% endif %} + {% endspaceless %} diff --git a/pod/podfile/static/podfile/css/podfile.css b/pod/podfile/static/podfile/css/podfile.css index 625b523e6b..1e2044e21e 100644 --- a/pod/podfile/static/podfile/css/podfile.css +++ b/pod/podfile/static/podfile/css/podfile.css @@ -6,964 +6,965 @@ */ button.close { - padding: 0; - background-color: transparent; - border: 0; - -webkit-appearance: none; - } - - .modal-open { - overflow: hidden; - } - - .modal { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1050; - display: none; - overflow: hidden; - outline: 0; - } - - .modal-open .modal { - overflow-x: hidden; - overflow-y: auto; - } - - .modal-dialog { - position: relative; - width: auto; - margin: 0 auto; - pointer-events: none; - width: calc(100% - 2em); - max-width: 950px; - padding: 0 !important; - } - - .modal.fade .modal-dialog { - transition: -webkit-transform 0.3s ease-out; - -webkit-transition: -webkit-transform 0.3s ease-out; - -o-transition: transform 0.3s ease-out; - transition: transform 0.3s ease-out; - transition: transform 0.3s ease-out, -webkit-transform 0.3s ease-out; - -webkit-transform: translate(0, -25%); - -ms-transform: translate(0, -25%); - transform: translate(0, -25%); - } - - .modal.show .modal-dialog { - -webkit-transform: translate(0, 0); - -ms-transform: translate(0, 0); - transform: translate(0, 0); - } - - .modal-dialog-centered { - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-align: center; + padding: 0; + background-color: transparent; + border: 0; + -webkit-appearance: none; +} + +.modal-open { + overflow: hidden; +} + +.modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + display: none; + overflow: hidden; + outline: 0; +} + +.modal-open .modal { + overflow-x: hidden; + overflow-y: auto; +} + +.modal-dialog { + position: relative; + width: auto; + margin: 0 auto; + pointer-events: none; + width: calc(100% - 2em); + max-width: 950px; + padding: 0 !important; +} + +.modal.fade .modal-dialog { + transition: -webkit-transform 0.3s ease-out; + -webkit-transition: -webkit-transform 0.3s ease-out; + -o-transition: transform 0.3s ease-out; + transition: transform 0.3s ease-out; + transition: transform 0.3s ease-out, -webkit-transform 0.3s ease-out; + -webkit-transform: translate(0, -25%); + -ms-transform: translate(0, -25%); + transform: translate(0, -25%); +} + +.modal.show .modal-dialog { + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + transform: translate(0, 0); +} + +.modal-dialog-centered { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + min-height: calc(100% - (0.5rem * 2)); +} + +.modal-content { + position: relative; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + pointer-events: auto; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.2); + outline: 0; + max-width: 100% !important; + width: calc(100% - 2em); + margin: 0 auto !important; +} + +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000; +} + +.modal-backdrop.fade { + opacity: 0; +} + +.modal-backdrop.show { + opacity: 0.5; +} + +.modal-header { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: start; + -ms-flex-align: start; + align-items: flex-start; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; + padding: 1rem; + border-bottom: 1px solid #e9ecef; + border-top-left-radius: 0.3rem; + border-top-right-radius: 0.3rem; +} + +.modal-header .close { + padding: 1rem; + margin: -1rem -1rem -1rem auto; +} + +.modal-title { + margin-bottom: 0; + line-height: 1.5; + font-size: 1.4rem; +} + +.modal-body { + position: relative; + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + padding: 1rem; +} + +.modal-footer { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: end; + -ms-flex-pack: end; + justify-content: flex-end; + padding: 1rem; + border-top: 1px solid #e9ecef; +} + +.modal-footer > :not(:first-child) { + margin-left: .25rem; +} + +.modal-footer > :not(:last-child) { + margin-right: .25rem; +} + +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; +} +/* +.modal-dialog { + margin: 1.75rem auto; +} +.modal-dialog-centered { + min-height: calc(100% - (1.75rem * 2)); + } +.modal-sm { + max-width: 300px; +} +*/ + +/********************************** + ********** Improve css *********** + **********************************/ +@media only screen and (min-width: 950px) +{ + .modal-dialog{ width: 850px; } +} +#podfile .row{ + margin: 10px 10px 5px 10px; +} +#podfile .col{ + padding: 5px; + background: white; + border: 1px solid rgba(0,0,0,.125); +} +#podifle .card-body{ + padding: 0; + font-size: .8rem; +} +#podfile .card-img-top { + width: 100%; + height: 10vh; + -o-object-fit: cover; + object-fit: cover; +} +#podifle img.directory-image { + height: 26px; + vertical-align: middle; +} +#podfile a, #podifle .folder_title{ + font-size: .8rem; +} +#podfile .list_folders{ + padding-left: 15px; + max-height:350px; + overflow: auto; +} + +#podfile .list_folders .folder_name{ + max-width: 600px; + display: inline-block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +#podfile #listfiles{ + max-height:600px; + overflow: auto; +} + +/********************************** + ********** Overrid css *********** + **********************************/ +#modal-folder_id_src .modal-body{ + padding-top: 0 !important; + padding-bottom: 0 !important; +} +#shareModalCenter #shared-people.list-group .list-group-item{ + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + border: 1px solid rgba(0,0,0,.08); + padding: .8em; +} +#shareModalCenter #shared-people.list-group .list-group-item:not(:last-child){ + border-bottom: none; +} +#shareModalCenter #shared-people.list-group .list-group-item .username{ + color: var(--gray-dark); + font-weight: 700; +} +#shareModalCenter #shared-people.list-group .list-group-item .btn-share.btn-remove{ + -webkit-box-ordinal-group: 2; + -ms-flex-order: 1; + order: 1; + padding: .4em .8em; + color: #fff !important; + background-color: var(--danger); + line-height: 1; + -webkit-box-flex: 0; + -ms-flex: none; + flex: none; +} +#shareModalCenter #shareFormName .form-group{position: relative;} +#shareModalCenter #shareFormName .form-group .form-control{ outline: none !important; -webkit-box-shadow: none !important; box-shadow: none !important;} +#shareModalCenter #user-search.list-group{ + padding: .8em 0; + width: 400px; + max-width: 100%; + border: 1px solid rgba(0,0,0,.1); + -webkit-box-shadow: 0 8px 10px 4px rgba(0,0,0,.08); + box-shadow: 0 8px 10px 4px rgba(0,0,0,.08); + position: absolute; + top: 100%; +} +#shareModalCenter #user-search.list-group .list-group-item{ + border: none !important; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + padding: .8em; + line-height: 1; +} +#shareModalCenter #user-search.list-group .list-group-item .btn-share.btn-add{ + padding: .4em .8em; + line-height: 1; + -webkit-box-flex: 0; + -ms-flex: none; + flex: none; +} +#shareModalCenter #user-search.list-group .list-group-item .username{ + font-weight: 700; + color: var(--gray); +} + +.modal-header { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: start; + -ms-flex-align: start; + align-items: flex-start; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; +} +.modal-header .modal-title{ + color: var(--primary); +} +.modal-header .close { + margin: 0; + color: var(--font-color); + opacity: 1; + padding: 0; + -webkit-transform: translate(10px, -15px); + -ms-transform: translate(10px, -15px); + transform: translate(10px, -15px); +} +.podfilemodal{ + padding: 0 !important; +} +#podfile{ + position: relative; + padding-bottom: 4em; + overflow: hidden; +} +#podfile > .row{ + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; +} +#podfile #dirs{ + position: absolute; + left: 0; + width: calc(100% - 25px); + max-width: 100%; + height: 100%; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + opacity: 0; + z-index: -1; + -webkit-transition: .5s opacity; + -o-transition: .5s opacity; + transition: .5s opacity; + border: none; + border-top-right-radius: 4px; + -webkit-box-shadow: 5px 0 5px -5px #ccc; + box-shadow: 5px 0 5px -5px #ccc; +} +#podfile #dirs.open{ + opacity: 1; + z-index: 9; +} +#podfile #dirs .close-folder, #podfile #dirs .close-folder svg{ + width: 30px; + color: var(--secondary); + cursor: pointer; +} +#podfile #dirs .dirs-nav{ + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + padding-left: 0; +} +#podfile #dirs .dirs-nav .dirs-nav-container{ + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} +#podfile .list_folders .folder_container:nth-child(2n), +#podfile .list_folders_sub .folder_container:nth-child(2n) { + background-color: #ececec; +} +#podfile .list_folders .folder_container, +#podfile .list_folders_sub .folder_container{padding: .4em;} +#podfile .list_folders .folder, +#podfile .list_folders_sub .folder, +#podfile #dirs .dirs-nav a.folder{ + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: end; + -ms-flex-align: end; + align-items: flex-end; + margin-right: 1em; +} +#podfile .list_folders .folder, +#podfile .list_folders_sub .folder{ align-items: center;} +#podfile .list_folders_sub .folder > *, +#podfile .list_folders .folder > *{flex: none;} +#podfile #dirs .dirs-nav-container .add-folder-btn{ color: var(--secondary); -webkit-transition: .3s transform; -o-transition: .3s transform; transition: .3s transform; } +#podfile #dirs .dirs-nav-container .add-folder-btn:hover{ text-decoration: none; -webkit-transform: scale(1.1); -ms-transform: scale(1.1); transform: scale(1.1);} + +#podfile .share-folders{ padding-top: .4em; border-top: 2px dotted var(--primary); } +#podfile .share-folders, +#podfile #list_folders_sub{ overflow: auto; max-height: 250px; margin-bottom: 1em; } +#podfile .share-folders .folder_title{ display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-align: center; -ms-flex-align: center; align-items: center; margin-bottom: .4em; color: var(--primary);} +#podfile .share-folders .home-directory{-webkit-transform: translateY(-8px);-ms-transform: translateY(-8px);transform: translateY(-8px) } +#podfile #list_folders_sub a.folder:not(.folder-opened) span.folder-open, +#podfile #list_folders_sub a.folder-opened span#folder-icon +{ display: none;} +#podfile #list_folders_sub a.folder:not(.folder-opened) span#folder-icon, +#podfile #list_folders_sub a.folder.folder-opened span.folder-open +{ display: inline-block;} + +#podfile #dirs .dirs-nav span.home-directory, +#podfile #dirs .share-folders span.home-directory, +#podfile #dirs .dirs-nav span.add-folder, +#podfile .list_folders span#folder-icon, +#podfile .list_folders span.folder-open +{ + display: inline-block; + width: 22px; + height: 22px; + margin-right: 8px; + color: inherit; +} +#podfile #dirs .share-folder span.home-directory{ color: var(--primary); } +#podfile #dirs .folder-search{ + border: 1px solid #ccc; + font-size: 14px; + padding: .4em; + color: rgba(0,0,0,.75); + margin-top: .8em; +} +#podfile #dirs .folder-search::-webkit-input-placeholder{ + color: rgba(0,0,0,.5); + text-transform: capitalize; +} +#podfile #dirs .folder-search::-moz-placeholder{ + color: rgba(0,0,0,.5); + text-transform: capitalize; +} +#podfile #dirs .folder-search:-ms-input-placeholder{ + color: rgba(0,0,0,.5); + text-transform: capitalize; +} +#podfile #dirs .folder-search::-ms-input-placeholder{ + color: rgba(0,0,0,.5); + text-transform: capitalize; +} +#podfile #dirs .folder-search::placeholder{ + color: rgba(0,0,0,.5); + text-transform: capitalize; +} +#podfile #list_folders_sub .view-more-container{ + position: relative; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + height: 40px; + margin-top: 1em; +} +#podfile #list_folders_sub .view-more-container::after{ + content: ""; + width: 100%; + -webkit-transform: translateY(50%); + -ms-transform: translateY(50%); + transform: translateY(50%); + height: 100%; + border-top: 1px solid var(--secondary); +} +#podfile #list_folders_sub .view-more-container a#more{ + text-align: center; + padding: .4em 2em; + border: 1px solid var(--secondary); + width: 50%; + margin: 0 auto; + border-radius: 4em; + z-index: 9; + background: white; + position: absolute; + -webkit-transition: all .2s linear .0s; + -o-transition: all .2s linear .0s; + transition: all .2s linear .0s; + font-weight: 600; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + overflow: hidden; +} +#podfile #list_folders_sub .view-more-container a#more:hover{ + background: var(--secondary); + color: #fff !important; +} +#podfile #list_folders_sub .view-more-container.loading a#more:hover{ + background: white; + color: var(--secondary); +} +#podfile #list_folders_sub .view-more-container a#more .text{ + -ms-flex-item-align: center; + -ms-grid-row-align: center; + align-self: center; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; +} +#podfile #list_folders_sub .view-more-container.loading .loader{ + display: -webkit-box; + display: -ms-flexbox; + display: flex; +} +#podfile #list_folders_sub .view-more-container .see-more{ + display: block; + position: absolute; + width: 15px; + left: 15px; +} +#podfile .alert-warning{ + position: relative; + color: #856404!important; + padding: .4em .8em; + padding-right: 25px; + text-align: center; + border-radius: 4px; + font-size: 14px; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; -ms-flex-align: center; - align-items: center; - min-height: calc(100% - (0.5rem * 2)); + align-items: center; + margin-bottom: .8em; +} +#podfile .alert-warning .close{ + position:absolute; + right: 5px; + top: 2px; + font-size: 20px; + font-weight: 900; + color: var(--gray-dark); + cursor: pointer; +} +#podfile .alert-warning .warning-icon{ + display: inline-block; + width: 20px; + -webkit-transform: translateY(-2px); + -ms-transform: translateY(-2px); + transform: translateY(-2px); + margin-right: 8px; +} +#podfile .open-folder{ + min-height: 400px; +} +#podfile .open-folder, #podifle .open-folder svg{ + width: 30px; + cursor: pointer; + -webkit-transform: translateX(-10px); + -ms-transform: translateX(-10px); + transform: translateX(-10px); + color: var(--primary); +} +#podfile #files{ + max-width: calc(100% - 30px); + z-index: 1; + -webkit-box-flex: 0; + -ms-flex: none; + flex: none; + border-top-right-radius: 4px; + padding: 0; +} +#podfile #files .navbar{ + position: relative; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; + background: var(--primary); + color: var(--white); + height: 35px; +} +#podfile #files #currentfolder{ + -webkit-box-flex: unset; + -ms-flex-positive: unset; + flex-grow: unset; + -ms-flex-preferred-size: auto; + flex-basis: auto; +} +#podfile .current-folder-icon{ + width: 25px; + display: inline-block; + -webkit-transform: translateY(-3px); + -ms-transform: translateY(-3px); + transform: translateY(-3px); +} +#podfile #files #currentfolder .delete-folder svg, +#podfile #files #currentfolder .edit-folder svg, +#podfile #files #currentfolder .download-file svg, +#podfile #files #currentfolder .upload-file svg, +#podfile #files #currentfolder .share-folder svg{ + width: 20px; + display: inline-block; + -webkit-transition: .3s color; + -o-transition: .3s color; + transition: .3s color; + height: 20px; + color: #fff; +} +#podfile #files #currentfolder .share-folder:hover svg, +#podfile #files #currentfolder .download-file:hover svg, +#podfile #files #currentfolder .edit-folder:hover svg, +#podfile #files #currentfolder .delete-folder:hover svg, +#podfile #files #currentfolder .upload-file:hover svg{ color: var(--secondary); } +#podfile #files .btn.navbar-toggler{ + width: 15px; + color: #fff; + padding: 0; + color: #fff; + background: transparent !important; +} +#podfile #files .navbar-toggler svg{ height: 22px; } + +#podfile #currentfolder .nav-item:not(:last-child){margin-right: .8em} +#podfile #files #currentfolder .edit-folder svg{width: 25px; height: 25px;} +#podfile #currentfolder .nav-item{ + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} +#podfile #currentfolder .nav-item > form{ height: 26px;} + +#podfile #currentfolder .nav-item .btn{padding: 0;} +#podfile .current-folder-name{ + font-weight: 700; + text-transform: uppercase; + font-size: 16px; +} +#podfile .flex{ + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; +} +#podfile .list_folders{ + height: auto; + max-height: unset; +} +#podfile #listfiles{ + display: -ms-grid; + display: grid; + grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); + grid-gap: 5px; +} +#podfile #files.loading .container-loader{ + position: relative; + margin: 0 auto; + margin-top: 4em; + width: 75px; + +} +#podfile #files.loading .lds-ellipsis{ + display: block; + -webkit-transform: translateX(-50%); + -ms-transform: translateX(-50%); + transform: translateX(-50%); + width: 75px; +} +#podfile #listfiles .empty-folder-warning{ + grid-column: 1/-1; + -ms-grid-row: 10; + grid-row: 10; + text-align: center; + background: #fff3cd; + color: #856404; + font-weight: 600; +} +#podfile #listfiles .navbar-toggler-icon{ + background: none; +} +#podfile #listfiles .col-sm-2{ + max-width: unset; +} +#podfile #listfiles .navbar{ + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: end; + -ms-flex-pack: end; + justify-content: flex-end; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} +#podfile #listfiles .card{ + overflow: unset; +} +#podfile #listfiles .file{ + position: absolute; + bottom: 4px; + left: 0; + right: 0; + -webkit-transform: translateY(100%); + -ms-transform: translateY(100%); + transform: translateY(100%); + background: var(--primary); + padding: .4em; + -webkit-transition: .1s all; + -o-transition: .1s all; + transition: .1s all; +} +#podfile #listfiles .file-navbar{ + -ms-flex-pack: distribute; + justify-content: space-around; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; + -webkit-box-align: end; + -ms-flex-align: end; + align-items: flex-end; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + overflow-y: auto; + max-height: 110px; +} +#podfile #listfiles .file-navbar .nav-item{ + width: 25px; + display: inline-block; + height: 25px; + margin: 0 .4em .4em .4em !important; +} +#podfile #listfiles .file-navbar .nav-item .edit-file{ + display: inline-block; + width: 24px; height: 24px; +} +#podfile #listfiles .file-navbar .nav-item .download-file{ + display: inline-block; + width: 24px; height: 24px; +} +#podfile #listfiles .file-navbar .nav-item .delete-file{ + display: inline-block; + width: 22px; height: 22px; +} +#podfile #listfiles .file-navbar .nav-item form{ + height: 100%; + width: 100%; + margin: 0 !important; +} + +#podfile #listfiles .navbar .btn{ + background: none; + color: #fff; + width: 25px; + height: 100%; + border: none; + opacity: 1!important; +} +#podfile #listfiles .navbar{ + background: var(--primary) !important; + position: relative; +} +#podfile #listfiles .navbar svg{ + height: 100%; +} + +#podfile #listfiles .card-body{ + overflow: hidden; +} +@media only screen and (max-width: 992px){ + #podfile #currentfolder{ + position: absolute; + right: 0; + bottom: 0; + -webkit-transform: translateY(100%); + -ms-transform: translateY(100%); + transform: translateY(100%); + max-width: 180px; + z-index: 9; + -webkit-transition: all .1s linear 0s; + -o-transition: all .1s linear 0s; + transition: all .1s linear 0s; + } + #podfile #currentfolder .navbar-nav{ + margin: O !important; + width: 100%; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; + } + #podfile #currentfolder .custom-file label{ + margin: 0; + } - - .modal-content { - position: relative; - display: -webkit-box; - display: -ms-flexbox; - display: flex; +} + +@media only screen and (max-width: 550px) +{ + #podfile .alert-warning{ -webkit-box-orient: vertical; -webkit-box-direction: normal; - -ms-flex-direction: column; - flex-direction: column; - pointer-events: auto; - background-color: #fff; - background-clip: padding-box; - border: 1px solid rgba(0, 0, 0, 0.2); - outline: 0; - max-width: 100% !important; - width: calc(100% - 2em); - margin: 0 auto !important; - } - - .modal-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1040; - background-color: #000; - } - - .modal-backdrop.fade { - opacity: 0; + -ms-flex-direction: column; + flex-direction: column; + line-height: 1.2; } - - .modal-backdrop.show { - opacity: 0.5; - } - - .modal-header { - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-align: start; + #podfile #dirs .dirs-nav .dirs-nav-container{ + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-align: start; -ms-flex-align: start; - align-items: flex-start; - -webkit-box-pack: justify; - -ms-flex-pack: justify; - justify-content: space-between; - padding: 1rem; - border-bottom: 1px solid #e9ecef; - border-top-left-radius: 0.3rem; - border-top-right-radius: 0.3rem; - } - - .modal-header .close { - padding: 1rem; - margin: -1rem -1rem -1rem auto; + align-items: flex-start; } - - .modal-title { - margin-bottom: 0; - line-height: 1.5; - font-size: 1.4rem; + #podfile #dirs .dirs-nav .dirs-nav-container .add-folder-btn{ + padding-left: 0; + margin-left: 0; } - - .modal-body { - position: relative; - -webkit-box-flex: 1; - -ms-flex: 1 1 auto; - flex: 1 1 auto; - padding: 1rem; - } - - .modal-footer { - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-align: center; +} + +/*** Loader CSS ***/ +.lds-ellipsis { + display: none; + -webkit-box-align: center; -ms-flex-align: center; - align-items: center; - -webkit-box-pack: end; - -ms-flex-pack: end; - justify-content: flex-end; - padding: 1rem; - border-top: 1px solid #e9ecef; - } - - .modal-footer > :not(:first-child) { - margin-left: .25rem; - } - - .modal-footer > :not(:last-child) { - margin-right: .25rem; - } - - .modal-scrollbar-measure { - position: absolute; - top: -9999px; - width: 50px; - height: 50px; - overflow: scroll; - } - /* - .modal-dialog { - margin: 1.75rem auto; - } - .modal-dialog-centered { - min-height: calc(100% - (1.75rem * 2)); - } - .modal-sm { - max-width: 300px; - } - */ - - /********************************** - ********** Improve css *********** - **********************************/ - @media only screen and (min-width: 950px) - { - .modal-dialog{ width: 850px; } - } - #podfile .row{ - margin: 10px 10px 5px 10px; - } - #podfile .col{ - padding: 5px; - background: white; - border: 1px solid rgba(0,0,0,.125); - } - #podifle .card-body{ - padding:0; - font-size: .8rem; - } - #podfile .card-img-top { - width: 100%; - height: 10vh; - -o-object-fit: cover; - object-fit: cover; - } - #podifle img.directory-image { - height: 26px; - vertical-align: middle; - } - #podfile a, #podifle .folder_title{ - font-size: .8rem; - } - #podfile .list_folders{ - padding-left: 15px; - max-height:350px; - overflow: auto; - } - - #podfile .list_folders .folder_name{ - max-width: 600px; - display: inline-block; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - #podfile #listfiles{ - max-height:600px; - overflow: auto; - } - - /********************************** - ********** Overrid css *********** - **********************************/ - #modal-folder_id_src .modal-body{ - padding-top: 0 !important; - padding-bottom: 0 !important; - } - #shareModalCenter #shared-people.list-group .list-group-item{ - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -ms-flex-pack: justify; - justify-content: space-between; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 1px solid rgba(0,0,0,.08); - padding: .8em; - } - #shareModalCenter #shared-people.list-group .list-group-item:not(:last-child){ - border-bottom: none; - } - #shareModalCenter #shared-people.list-group .list-group-item .username{ - color: var(--gray-dark); - font-weight: 700; - } - #shareModalCenter #shared-people.list-group .list-group-item .btn-share.btn-remove{ - -webkit-box-ordinal-group: 2; - -ms-flex-order: 1; - order: 1; - padding: .4em .8em; - color: #fff !important; - background-color: var(--danger); - line-height: 1; - -webkit-box-flex: 0; - -ms-flex: none; - flex: none; - } - #shareModalCenter #shareFormName .form-group{position: relative;} - #shareModalCenter #shareFormName .form-group .form-control{ outline: none !important; -webkit-box-shadow: none !important; box-shadow: none !important;} - #shareModalCenter #user-search.list-group{ - padding: .8em 0; - width: 400px; - max-width: 100%; - border: 1px solid rgba(0,0,0,.1); - -webkit-box-shadow: 0px 8px 10px 4px rgba(0,0,0,.08); - box-shadow: 0px 8px 10px 4px rgba(0,0,0,.08); - position: absolute; - top: 100%; - } - #shareModalCenter #user-search.list-group .list-group-item{ - border: none !important; - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -ms-flex-pack: justify; - justify-content: space-between; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - padding: .8em; - line-height: 1; - } - #shareModalCenter #user-search.list-group .list-group-item .btn-share.btn-add{ - padding: .4em .8em; - line-height: 1; - -webkit-box-flex: 0; - -ms-flex: none; - flex: none; - } - #shareModalCenter #user-search.list-group .list-group-item .username{ - font-weight: 700; - color: var(--gray); - } - - .modal-header { - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-align: start; - -ms-flex-align: start; - align-items: flex-start; - -webkit-box-pack: justify; - -ms-flex-pack: justify; - justify-content: space-between; - } - .modal-header .modal-title{ - color: var(--primary); - } - .modal-header .close { - margin: 0; - color: var(--primary); - opacity: 1; - padding: 0; - -webkit-transform: translate(10px, -15px); - -ms-transform: translate(10px, -15px); - transform: translate(10px, -15px); - } - .podfilemodal{ - padding: 0 !important; - } - #podfile{ - position: relative; - padding-bottom: 4em; - overflow: hidden; - } - #podfile > .row{ - -webkit-box-pack: justify; - -ms-flex-pack: justify; - justify-content: space-between; - } - #podfile #dirs{ - position: absolute; - left: 0; - width: calc(100% - 25px); - max-width: 100%; - height: 100%; - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -ms-flex-direction: column; - flex-direction: column; - opacity: 0; - z-index: -1; - -webkit-transition: .5s opacity; - -o-transition: .5s opacity; - transition: .5s opacity; - border: none; - border-top-right-radius: 4px; - -webkit-box-shadow: 5px 0 5px -5px #ccc; - box-shadow: 5px 0 5px -5px #ccc; - } - #podfile #dirs.open{ - opacity: 1; - z-index: 9; - } - #podfile #dirs .close-folder, #podfile #dirs .close-folder svg{ - width: 30px; - color: var(--secondary); - cursor: pointer; - } - #podfile #dirs .dirs-nav{ - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -ms-flex-pack: justify; - justify-content: space-between; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - padding-left: 0; - } - #podfile #dirs .dirs-nav .dirs-nav-container{ - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - } - #podfile .list_folders .folder_container:nth-child(2n), - #podfile .list_folders_sub .folder_container:nth-child(2n) { - background-color: #ececec; - } - #podfile .list_folders .folder_container, - #podfile .list_folders_sub .folder_container{padding: .4em;} - #podfile .list_folders .folder, - #podfile .list_folders_sub .folder, - #podfile #dirs .dirs-nav a.folder{ - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-align: end; - -ms-flex-align: end; - align-items: flex-end; - margin-right: 1em; - } - #podfile .list_folders .folder, - #podfile .list_folders_sub .folder{ align-items: center;} - #podfile .list_folders_sub .folder > *, - #podfile .list_folders .folder > *{flex: none;} - #podfile #dirs .dirs-nav-container .add-folder-btn{ color: var(--secondary); -webkit-transition: .3s transform; -o-transition: .3s transform; transition: .3s transform; } - #podfile #dirs .dirs-nav-container .add-folder-btn:hover{ text-decoration: none; -webkit-transform: scale(1.1); -ms-transform: scale(1.1); transform: scale(1.1);} - - #podfile .share-folders{ padding-top: .4em; border-top: 2px dotted var(--primary); } - #podfile .share-folders, - #podfile #list_folders_sub{ overflow: auto; max-height: 250px; margin-bottom: 1em; } - #podfile .share-folders .folder_title{ display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-align: center; -ms-flex-align: center; align-items: center; margin-bottom: .4em; color: var(--primary);} - #podfile .share-folders .home-directory{-webkit-transform: translateY(-8px);-ms-transform: translateY(-8px);transform: translateY(-8px) } - #podfile #list_folders_sub a.folder:not(.folder-opened) span.folder-open, - #podfile #list_folders_sub a.folder-opened span#folder-icon - { display: none;} - #podfile #list_folders_sub a.folder:not(.folder-opened) span#folder-icon, - #podfile #list_folders_sub a.folder.folder-opened span.folder-open - { display: inline-block;} - - #podfile #dirs .dirs-nav span.home-directory, - #podfile #dirs .share-folders span.home-directory, - #podfile #dirs .dirs-nav span.add-folder, - #podfile .list_folders span#folder-icon, - #podfile .list_folders span.folder-open - { - display: inline-block; - width: 22px; - height: 22px; - margin-right: 8px; - color: inherit; - } - #podfile #dirs .share-folder span.home-directory{ color: var(--primary); } - #podfile #dirs .folder-search{ - border: 1px solid #ccc; - font-size: 14px; - padding: .4em; - color: rgba(0,0,0,.75); - margin-top: .8em; - } - #podfile #dirs .folder-search::-webkit-input-placeholder{ - color: rgba(0,0,0,.5); - text-transform: capitalize; - } - #podfile #dirs .folder-search::-moz-placeholder{ - color: rgba(0,0,0,.5); - text-transform: capitalize; - } - #podfile #dirs .folder-search:-ms-input-placeholder{ - color: rgba(0,0,0,.5); - text-transform: capitalize; - } - #podfile #dirs .folder-search::-ms-input-placeholder{ - color: rgba(0,0,0,.5); - text-transform: capitalize; - } - #podfile #dirs .folder-search::placeholder{ - color: rgba(0,0,0,.5); - text-transform: capitalize; - } - #podfile #list_folders_sub .view-more-container{ - position: relative; - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: center; - -ms-flex-pack: center; - justify-content: center; - height: 40px; - margin-top: 1em; - } - #podfile #list_folders_sub .view-more-container::after{ - content: ""; - width: 100%; - -webkit-transform: translateY(50%); - -ms-transform: translateY(50%); - transform: translateY(50%); - height: 100%; - border-top: 1px solid var(--secondary); - } - #podfile #list_folders_sub .view-more-container a#more{ - text-align: center; - padding: .4em 2em; - border: 1px solid var(--secondary); - width: 50%; - margin: 0 auto; - border-radius: 4em; - z-index: 9; - background: white; - position: absolute; - -webkit-transition: all .2s linear .0s; - -o-transition: all .2s linear .0s; - transition: all .2s linear .0s; - font-weight: 600; - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - overflow: hidden; - } - #podfile #list_folders_sub .view-more-container a#more:hover{ - background: var(--secondary); - color: #fff !important; - } - #podfile #list_folders_sub .view-more-container.loading a#more:hover{ - background: white; - color: var(--secondary); - } - #podfile #list_folders_sub .view-more-container a#more .text{ - -ms-flex-item-align: center; - -ms-grid-row-align: center; - align-self: center; - -webkit-box-flex: 1; - -ms-flex-positive: 1; - flex-grow: 1; - } - #podfile #list_folders_sub .view-more-container.loading .loader{ - display: -webkit-box; - display: -ms-flexbox; - display: flex; - } - #podfile #list_folders_sub .view-more-container .see-more{ - display: block; - position: absolute; - width: 15px; - left: 15px; - } - #podfile .alert-warning{ - position: relative; - color: #856404!important; - padding: .4em .8em; - padding-right: 25px; - text-align: center; - border-radius: 4px; - font-size: 14px; - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - margin-bottom: .8em; - } - #podfile .alert-warning .close{ - position:absolute; - right: 5px; - top: 2px; - font-size: 20px; - font-weight: 900; - color: var(--gray-dark); - cursor: pointer; - } - #podfile .alert-warning .warning-icon{ - display: inline-block; - width: 20px; - -webkit-transform: translateY(-2px); - -ms-transform: translateY(-2px); - transform: translateY(-2px); - margin-right: 8px; - } - #podfile .open-folder{ - min-height: 400px; - } - #podfile .open-folder, #podifle .open-folder svg{ - width: 30px; - cursor: pointer; - -webkit-transform: translateX(-10px); - -ms-transform: translateX(-10px); - transform: translateX(-10px); - color: var(--primary); - } - #podfile #files{ - max-width: calc(100% - 30px); - z-index: 1; - -webkit-box-flex: 0; - -ms-flex: none; - flex: none; - border-top-right-radius: 4px; - padding: 0; - } - #podfile #files .navbar{ - position: relative; - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -ms-flex-pack: justify; - justify-content: space-between; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -ms-flex-wrap: nowrap; - flex-wrap: nowrap; - background: var(--primary) !important; - height: 35px; - } - #podfile #files #currentfolder{ - -webkit-box-flex: unset; - -ms-flex-positive: unset; - flex-grow: unset; - -ms-flex-preferred-size: auto; - flex-basis: auto; - } - #podfile .current-folder-icon{ - width: 25px; - display: inline-block; - -webkit-transform: translateY(-3px); - -ms-transform: translateY(-3px); - transform: translateY(-3px); - } - #podfile #files #currentfolder .delete-folder svg, - #podfile #files #currentfolder .edit-folder svg, - #podfile #files #currentfolder .download-file svg, - #podfile #files #currentfolder .upload-file svg, - #podfile #files #currentfolder .share-folder svg{ - width: 20px; - display: inline-block; - -webkit-transition: .3s color; - -o-transition: .3s color; - transition: .3s color; - height: 20px; - color: #fff; - } - #podfile #files #currentfolder .share-folder:hover svg, - #podfile #files #currentfolder .download-file:hover svg, - #podfile #files #currentfolder .edit-folder:hover svg, - #podfile #files #currentfolder .delete-folder:hover svg, - #podfile #files #currentfolder .upload-file:hover svg{ color: var(--secondary); } - #podfile #files .btn.navbar-toggler{ - width: 15px; - color: #fff; - padding: 0; - color: #fff; - background: transparent !important; - } - #podfile #files .navbar-toggler svg{ height: 22px; } - - #podfile #currentfolder .nav-item:not(:last-child){margin-right: .8em} - #podfile #files #currentfolder .edit-folder svg{width: 25px; height: 25px;} - #podfile #currentfolder .nav-item{ - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - } - #podfile #currentfolder .nav-item > form{ height: 26px;} - - #podfile #currentfolder .nav-item .btn{padding: 0;} - #podfile .current-folder-name{ - font-weight: 700; - text-transform: uppercase; - font-size: 16px; - } - #podfile .flex{ - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -ms-flex-direction: column; - flex-direction: column; - } - #podfile .list_folders{ - height: auto; - max-height: unset; - } - #podfile #listfiles{ - display: -ms-grid; - display: grid; - grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); - grid-gap: 5px; - } - #podfile #files.loading .container-loader{ - position: relative; - margin: 0 auto; - margin-top: 4em; - width: 75px; - - } - #podfile #files.loading .lds-ellipsis{ - display: block; - -webkit-transform: translateX(-50%); - -ms-transform: translateX(-50%); - transform: translateX(-50%); - width: 75px; - } - #podfile #listfiles .empty-folder-warning{ - grid-column: 1/-1; - -ms-grid-row: 10; - grid-row: 10; - text-align: center; - background: #fff3cd; - color: #856404; - font-weight: 600; - } - #podfile #listfiles .navbar-toggler-icon{ - background: none; - } - #podfile #listfiles .col-sm-2{ - max-width: unset; - } - #podfile #listfiles .navbar{ - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: end; - -ms-flex-pack: end; - justify-content: flex-end; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - } - #podfile #listfiles .card{ - overflow: unset; - } - #podfile #listfiles .file{ - position: absolute; - bottom: 4px; - left: 0; - right: 0; - -webkit-transform: translateY(100%); - -ms-transform: translateY(100%); - transform: translateY(100%); - background: var(--primary); - padding: .4em; - -webkit-transition: .1s all; - -o-transition: .1s all; - transition: .1s all; - } - #podfile #listfiles .file-navbar{ - -ms-flex-pack: distribute; - justify-content: space-around; - -webkit-box-orient: horizontal; - -webkit-box-direction: normal; - -ms-flex-direction: row; - flex-direction: row; - -webkit-box-align: end; - -ms-flex-align: end; - align-items: flex-end; - -ms-flex-wrap: wrap; - flex-wrap: wrap; - overflow-y: auto; - max-height: 110px; - } - #podfile #listfiles .file-navbar .nav-item{ - width: 25px; - display: inline-block; - height: 25px; - margin: 0 .4em .4em .4em !important; - } - #podfile #listfiles .file-navbar .nav-item .edit-file{ - display: inline-block; - width: 24px; height: 24px; - } - #podfile #listfiles .file-navbar .nav-item .download-file{ - display: inline-block; - width: 24px; height: 24px; - } - #podfile #listfiles .file-navbar .nav-item .delete-file{ - display: inline-block; - width: 22px; height: 22px; - } - #podfile #listfiles .file-navbar .nav-item form{ - height: 100%; - width: 100%; - margin: 0 !important; - } - - #podfile #listfiles .navbar .btn{ - background: none; - color: #fff; - width: 25px; - height: 100%; - border: none; - opacity: 1!important; - } - #podfile #listfiles .navbar{ - background: var(--primary) !important; - position: relative; - } - #podfile #listfiles .navbar svg{ - height: 100%; - } - - #podfile #listfiles .card-body{ - overflow: hidden; - } - @media only screen and (max-width: 992px){ - #podfile #currentfolder{ - position: absolute; - right: 0; - bottom: 0; - -webkit-transform: translateY(100%); - -ms-transform: translateY(100%); - transform: translateY(100%); - max-width: 180px; - z-index: 9; - -webkit-transition: all .1s linear 0s; - -o-transition: all .1s linear 0s; - transition: all .1s linear 0s; - } - #podfile #currentfolder .navbar-nav{ - margin: O !important; - width: 100%; - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: horizontal; - -webkit-box-direction: normal; - -ms-flex-direction: row; - flex-direction: row; - } - #podfile #currentfolder .custom-file label{ - margin: 0; - - } - } - - @media only screen and (max-width: 550px) - { - #podfile .alert-warning{ - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -ms-flex-direction: column; - flex-direction: column; - line-height: 1.2; - } - #podfile #dirs .dirs-nav .dirs-nav-container{ - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -ms-flex-direction: column; - flex-direction: column; - -webkit-box-align: start; - -ms-flex-align: start; - align-items: flex-start; - } - #podfile #dirs .dirs-nav .dirs-nav-container .add-folder-btn{ - padding-left: 0; - margin-left: 0; - } - } - - /*** Loader CSS ***/ - .lds-ellipsis { - display: none; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: white; - z-index: 9; - } - .lds-ellipsis div { - position: absolute; - width: 13px; - height: 13px; - border-radius: 50%; - background: var(--secondary); - -webkit-animation-timing-function: cubic-bezier(0, 1, 1, 0); - animation-timing-function: cubic-bezier(0, 1, 1, 0); - } - .lds-ellipsis div:nth-child(1) { - left: 8px; - -webkit-animation: lds-ellipsis1 0.6s infinite; - animation: lds-ellipsis1 0.6s infinite; - } - .lds-ellipsis div:nth-child(2) { - left: 8px; - -webkit-animation: lds-ellipsis2 0.6s infinite; - animation: lds-ellipsis2 0.6s infinite; - } - .lds-ellipsis div:nth-child(3) { - left: 32px; - -webkit-animation: lds-ellipsis2 0.6s infinite; - animation: lds-ellipsis2 0.6s infinite; - } - .lds-ellipsis div:nth-child(4) { - left: 56px; - -webkit-animation: lds-ellipsis3 0.6s infinite; - animation: lds-ellipsis3 0.6s infinite; - } - @-webkit-keyframes lds-ellipsis1 { - 0% { - -webkit-transform: scale(0); - transform: scale(0); - } - 100% { - -webkit-transform: scale(1); - transform: scale(1); - } - } - @keyframes lds-ellipsis1 { - 0% { - -webkit-transform: scale(0); - transform: scale(0); - } - 100% { - -webkit-transform: scale(1); - transform: scale(1); - } - } - @-webkit-keyframes lds-ellipsis3 { - 0% { - -webkit-transform: scale(1); - transform: scale(1); - } - 100% { - -webkit-transform: scale(0); - transform: scale(0); - } - } - @keyframes lds-ellipsis3 { - 0% { - -webkit-transform: scale(1); - transform: scale(1); - } - 100% { - -webkit-transform: scale(0); - transform: scale(0); - } - } - @-webkit-keyframes lds-ellipsis2 { - 0% { - -webkit-transform: translate(0, 0); - transform: translate(0, 0); - } - 100% { - -webkit-transform: translate(24px, 0); - transform: translate(24px, 0); - } - } - @keyframes lds-ellipsis2 { - 0% { - -webkit-transform: translate(0, 0); - transform: translate(0, 0); - } - 100% { - -webkit-transform: translate(24px, 0); - transform: translate(24px, 0); - } - } - + align-items: center; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: white; + z-index: 9; +} +.lds-ellipsis div { + position: absolute; + width: 13px; + height: 13px; + border-radius: 50%; + background: var(--secondary); + -webkit-animation-timing-function: cubic-bezier(0, 1, 1, 0); + animation-timing-function: cubic-bezier(0, 1, 1, 0); +} +.lds-ellipsis div:nth-child(1) { + left: 8px; + -webkit-animation: lds-ellipsis1 0.6s infinite; + animation: lds-ellipsis1 0.6s infinite; +} +.lds-ellipsis div:nth-child(2) { + left: 8px; + -webkit-animation: lds-ellipsis2 0.6s infinite; + animation: lds-ellipsis2 0.6s infinite; +} +.lds-ellipsis div:nth-child(3) { + left: 32px; + -webkit-animation: lds-ellipsis2 0.6s infinite; + animation: lds-ellipsis2 0.6s infinite; +} +.lds-ellipsis div:nth-child(4) { + left: 56px; + -webkit-animation: lds-ellipsis3 0.6s infinite; + animation: lds-ellipsis3 0.6s infinite; +} +@-webkit-keyframes lds-ellipsis1 { + 0% { + -webkit-transform: scale(0); + transform: scale(0); + } + 100% { + -webkit-transform: scale(1); + transform: scale(1); + } +} +@keyframes lds-ellipsis1 { + 0% { + -webkit-transform: scale(0); + transform: scale(0); + } + 100% { + -webkit-transform: scale(1); + transform: scale(1); + } +} +@-webkit-keyframes lds-ellipsis3 { + 0% { + -webkit-transform: scale(1); + transform: scale(1); + } + 100% { + -webkit-transform: scale(0); + transform: scale(0); + } +} +@keyframes lds-ellipsis3 { + 0% { + -webkit-transform: scale(1); + transform: scale(1); + } + 100% { + -webkit-transform: scale(0); + transform: scale(0); + } +} +@-webkit-keyframes lds-ellipsis2 { + 0% { + -webkit-transform: translate(0, 0); + transform: translate(0, 0); + } + 100% { + -webkit-transform: translate(24px, 0); + transform: translate(24px, 0); + } +} +@keyframes lds-ellipsis2 { + 0% { + -webkit-transform: translate(0, 0); + transform: translate(0, 0); + } + 100% { + -webkit-transform: translate(24px, 0); + transform: translate(24px, 0); + } +} + diff --git a/pod/podfile/templates/podfile/list_folder_files.html b/pod/podfile/templates/podfile/list_folder_files.html index 141da03fc6..ed7ea2b22c 100644 --- a/pod/podfile/templates/podfile/list_folder_files.html +++ b/pod/podfile/templates/podfile/list_folder_files.html @@ -193,8 +193,8 @@
    {% for file in folder.get_all_files %}
    -
    -
    +
    +
    {% if request.user == file.created_by or request.user.is_superuser or perms.podfile.change_customfilemodel or perms.podfile.change_customimagemodel or request.user in folder.users.all %}
    -
    -
    - {% endspaceless %} - {% endfor %} - -
    -
    - -
    + {% if field.name == "description" %}{%endif%} + {% if field.name == "title" %}{%endif%} +
    +
    + + {% endspaceless %} + {% endfor %} + +
    + +
    {% endblock page_content %} {% block collapse_page_aside %} -{{ block.super }} + {{ block.super }} {% endblock collapse_page_aside %} {% block page_aside %}
    -
    {% trans "Mandatory fields" %}
    -
    -

    {% trans "Fields marked with an asterisk are mandatory."%}

    -
    +
    {% trans "Mandatory fields" %}
    +
    +

    {% trans "Fields marked with an asterisk are mandatory."%}

    +
    -
    {% trans "Form fields"%}
    -
    - {% for title, values in form.CHANNEL_FORM_FIELDS_HELP_TEXT.items %} -
    - -
    - {% for value in values %} -

    {{value|safe}}

    - {%endfor%} -
    -
    - {% endfor %} -
    +
    {% trans "Form fields"%}
    +
    + {% for title, values in form.CHANNEL_FORM_FIELDS_HELP_TEXT.items %} +
    + +
    + {% for value in values %} +

    {{value|safe}}

    + {%endfor%} +
    +
    + {% endfor %} +
    {% endblock page_aside %} {% block more_script %} - - - - - -{{form.media}} + + + + + + {{form.media}} {% endblock more_script %} \ No newline at end of file diff --git a/pod/video/templates/channel/form_theme.html b/pod/video/templates/channel/form_theme.html index 868ad3bfa7..1874ff053c 100644 --- a/pod/video/templates/channel/form_theme.html +++ b/pod/video/templates/channel/form_theme.html @@ -8,43 +8,43 @@

    {% csrf_token %}
    {% if form_theme.errors or form_theme.non_field_errors %} -

    {% trans 'One or more errors have been found in the form:' %}
    - {% for error in form_theme.non_field_errors %} - - {{error}}
    - {% endfor %} - {% for field in form %} - - {{ field.errors }}
    - {% endfor %} -

    +
    {% trans 'One or more errors have been found in the form:' %}
    + {% for error in form_theme.non_field_errors %} + - {{error}}
    + {% endfor %} + {% for field in form %} + - {{ field.errors }}
    + {% endfor %} +
    {% endif %} {% for field_hidden in form_theme.hidden_fields %} {{field_hidden}} {% endfor %} {% for field in form_theme.visible_fields %} - {% spaceless %} -
    -
    -
    - {{ field.errors }} - -
    {{field}} - {% if field.help_text %} - {{ field.help_text|safe }} + {% spaceless %} +
    +
    +
    + {{ field.errors }} + +
    {{field}} + {% if field.help_text %} + {{ field.help_text|safe }} {% endif %} -
    - {% if field.name == "description" %}{%endif%} - {% if field.name == "title" %}{%endif%} -
    -
    -
    - {% endspaceless %} +
    + {% if field.name == "description" %}{%endif%} + {% if field.name == "title" %}{%endif%} +
    +
    +
    + {% endspaceless %} {% endfor %} {% if form_theme.instance %} {% endif %} - +
    -{{form_theme.media}} \ No newline at end of file +{{form_theme.media}} diff --git a/pod/video/templates/channel/list_theme.html b/pod/video/templates/channel/list_theme.html index 3332e2baa4..5c63922667 100644 --- a/pod/video/templates/channel/list_theme.html +++ b/pod/video/templates/channel/list_theme.html @@ -1,43 +1,40 @@ {% load i18n %}
    -

    {% trans 'List of themes' %} ({{list_theme|length}})

    -
    - - - - - - - - - - - - {% for theme in list_theme %} - - - - - - - - {% endfor %} - -
    {% trans 'Title' %}{% trans 'description' %}{% trans 'headband' %}  
    {{theme.title}}{{theme.description}}{{theme.headband}} -
    - {% csrf_token %} - - - -
    -
    -
    - {% csrf_token %} - - - -
    -
    -
    -
    \ No newline at end of file +

    {% trans 'List of themes' %} ({{list_theme|length}})

    +
    + + + + + + + + + + + {% for theme in list_theme %} + + + + + + + {% endfor %} + +
    {% trans 'Title' %}{% trans 'Description' %}{% trans 'Headband' %}{% trans 'Actions' %}
    {{theme.title}}{{theme.description}}{{theme.headband}} +
    + {% csrf_token %} + + + +
    +
    + {% csrf_token %} + + + +
    +
    +
    + diff --git a/pod/video/templates/channel/theme_edit.html b/pod/video/templates/channel/theme_edit.html index 97c148951b..6c5eb68ca9 100644 --- a/pod/video/templates/channel/theme_edit.html +++ b/pod/video/templates/channel/theme_edit.html @@ -5,87 +5,87 @@ {% block page_extra_head %} {% endblock page_extra_head %} -{% block breadcrumbs %}{{ block.super }} - -{% endblock %} +{% block breadcrumbs %}{{ block.super }} + + +{% endblock breadcrumbs %} {% block page_title %} -{% trans "Editing the channel's themes" %} "{{channel.title}}" + {% trans "Editing the channel's themes" %} "{{channel.title}}" {% endblock %} {% block page_content %}

    {% trans "Editing the channel's themes" %} {{channel.title}} - - -  {% trans "View the channel"%} + + +  {% trans "View the channel"%} - -  {% trans "Edit the channel"%} + +  {% trans "Edit the channel"%} - +

    - {% include 'channel/list_theme.html' with list_theme=channel.themes.all %} + {% include 'channel/list_theme.html' with list_theme=channel.themes.all %}


    - {% if form_theme %} - {% include 'channel/form_theme.html' %} - {% else %} -
    - {% csrf_token %} - - -
    - {% endif %} + {% if form_theme %} + {% include 'channel/form_theme.html' %} + {% else %} +
    + {% csrf_token %} + + +
    + {% endif %}
    -
    - {% csrf_token %} - - + + {% csrf_token %} + +
    {% endblock page_content %} {% block collapse_page_aside %} -{{ block.super }} + {{ block.super }} {% endblock collapse_page_aside %} {% block page_aside %}
    -
    {% trans "Mandatory fields" %}
    -
    -

    {% trans "Fields marked with an asterisk are mandatory."%}

    -
    +
    {% trans "Mandatory fields" %}
    +
    +

    {% trans "Fields marked with an asterisk are mandatory."%}

    +
    -
    {% trans "Form fields"%}
    -
    - {% for title, values in form_theme.THEME_FORM_FIELDS_HELP_TEXT.items %} -
    - -
    - {% for value in values %} -

    {{value}}

    - {%endfor%} -
    -
    - {% endfor %} -
    +
    {% trans "Form fields"%}
    +
    + {% for title, values in form_theme.THEME_FORM_FIELDS_HELP_TEXT.items %} +
    + +
    + {% for value in values %} +

    {{value}}

    + {%endfor%} +
    +
    + {% endfor %} +
    {% endblock page_aside %} {% block more_script %} - -{% endblock more_script %} \ No newline at end of file +{% endblock more_script %} diff --git a/pod/video/templates/videos/video_edit.html b/pod/video/templates/videos/video_edit.html index 6536dc9f12..9a9e8c23be 100644 --- a/pod/video/templates/videos/video_edit.html +++ b/pod/video/templates/videos/video_edit.html @@ -5,28 +5,27 @@ {% load progress_bar %} {% block page_extra_head %} - {% endblock page_extra_head %} {% block breadcrumbs %}{{ block.super }} - -{% if form.instance.title and form.instance.slug != '' %} - - -{%else%} - -{%endif%} + + {% if form.instance.title and form.instance.slug != '' %} + + + {%else%} + + {%endif%} {% endblock %} {% block page_title %}{% if form.instance.title %}{% trans "Editing the video" %} "{{form.instance.title}}"{% else %}{% trans "Add a new video" %}{%endif%}{% endblock %} {% block collapse_page_aside %} -{% if access_not_allowed == True %} + {% if access_not_allowed == True %} -{% else %} -{{block.super}} -{% endif %} + {% else %} + {{block.super}} + {% endif %} {% endblock collapse_page_aside %} @@ -34,102 +33,101 @@ {% spaceless %}

    {% if form.instance.title and form.instance.slug != '' %}{% trans "Editing the video" %} "{{form.instance.title}}" - +  {% trans "View the video"%} - +  {% trans "Delete the video"%} - + {% else %}{% trans "Add a new video" %}{%endif%}

    {% if access_not_allowed == True %} -

    +

     {% trans "Access to adding video has been restricted. If you want to add videos on the platform, please" %} {% trans 'contact us' %} -

    -{% else %} -{% if form.instance.slug and form.instance.slug != '' %} -
    +

    {% else %} - -{% endif %} - {% csrf_token %} - -
    - {% if form.errors %} -

    {% trans "One or more errors have been found in the form." %}

    - {{form.errors}} - {% endif %} + {% if form.instance.slug and form.instance.slug != '' %} + + {% else %} + + {% endif %} + {% csrf_token %} + + {% if form.errors %} +

    {% trans "One or more errors have been found in the form." %}

    + {{form.errors}} + {% endif %} - {% if form.instance.id and form.instance.get_encoding_step == "" %} - - {% endif %} + {% if form.instance.id and form.instance.get_encoding_step == "" %} + + {% endif %} - {% if form.instance.encoding_in_progress %} - - {% endif %} + {% if form.instance.encoding_in_progress %} + + {% endif %} - {% if form.instance.get_encoding_step == "5 : transcripting audio" %} -

    - {% trans "The video is currently being transcripted." %} -

    - {% endif %} + {% if form.instance.get_encoding_step == "5 : transcripting audio" %} +

    + {% trans "The video is currently being transcripted." %} +

    + {% endif %} - {% for field_hidden in form.hidden_fields %} - {{field_hidden}} - {% endfor %} - {% for field in form.visible_fields %} - {% spaceless %} -
    -
    - {{ field.errors }} - {% if "form-check-input" in field.field.widget.attrs.class %} -
    - {{ field }} -
    - {% else %} - - {% if "form-control-file" in field.field.widget.attrs.class and form.instance.video %}
    {%endif%} - {{ field }} - {% endif %} - {% if field.help_text %} - {{ field.help_text|safe }} - {% endif %} - {% if field.field.required %}
    {% trans "Please provide a valid value for this field" %}.
    {%endif%} - {% if field.name == "description" %}{%endif%} - {% if field.name == "title" %}{%endif%} -
    -
    - {% endspaceless %} - {% endfor %} -
    -
    -
    -
    {% trans "Sending, please wait." %}
    -
    - {% trans "Loading" %}... -
    -

    {% progress_bar %}

    + {% for field_hidden in form.hidden_fields %} + {{field_hidden}} + {% endfor %} + {% for field in form.visible_fields %} + {% spaceless %} +
    +
    + {{ field.errors }} + {% if "form-check-input" in field.field.widget.attrs.class %} +
    + {{ field }}
    - -
    - -
    - - {% if form.instance.title and form.instance.slug != '' %} {%endif%} - {% trans 'back to my videos' %} + {% else %} + + {% if "form-control-file" in field.field.widget.attrs.class and form.instance.video %}
    {%endif%} + {{ field }} + {% endif %} + {% if field.help_text %} + {{ field.help_text|safe }} + {% endif %} + {% if field.field.required %}
    {% trans "Please provide a valid value for this field" %}.
    {%endif%} + {% if field.name == "description" %}{%endif%} + {% if field.name == "title" %}{%endif%} +
    +
    + {% endspaceless %} + {% endfor %} + +
    +
    +
    {% trans "Sending, please wait." %}
    +
    + {% trans "Loading" %}... +
    +

    {% progress_bar %}

    +
    + +
    + +
    + + {% if form.instance.title and form.instance.slug != '' %} {%endif%} + {% trans 'back to my videos' %} +
    {% endif %} {% endspaceless %} @@ -213,33 +211,30 @@
    {% trans "Help for form fields"%}
    {% block more_script %} - - - + + + - + {{form.media}} - - {% if USE_CHUNKED_UPLOAD %} - - + {% else %} - - + {%endif%} - + {% endblock more_script %} diff --git a/setup.cfg b/setup.cfg index 247fc19d9d..a06c1fc9b4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,2 +1,3 @@ [flake8] -exclude = .git +exclude = .git,pod/*/migrations/*.py,test_settings.py +max-complexity = 7 From f96e3151f18e51eb0cd8cfa0a84da178610d5199 Mon Sep 17 00:00:00 2001 From: Olivier Bado Date: Fri, 19 Mar 2021 18:36:54 +0100 Subject: [PATCH 135/261] Add minor corrections from Lille override.css --- pod/main/templates/navbar.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pod/main/templates/navbar.html b/pod/main/templates/navbar.html index 6051a294ac..bd5251afec 100644 --- a/pod/main/templates/navbar.html +++ b/pod/main/templates/navbar.html @@ -11,7 +11,7 @@ {{ TITLE_SITE }}
    -