From f5bbf5e56458b584339b941f9aec8e17302e6a03 Mon Sep 17 00:00:00 2001 From: Jetske Date: Tue, 2 Jul 2024 16:20:15 +0200 Subject: [PATCH] Annotated video added source options and video cutting option #1266 --- media/js/process_annotated_eaf_files.js | 2 +- signbank/dictionary/admin.py | 7 +- signbank/dictionary/models.py | 61 ++++++++--- .../dictionary/add_annotated_sentence.html | 11 +- .../dictionary/edit_annotated_sentence.html | 80 ++++++++++++-- .../templates/dictionary/gloss_detail.html | 13 ++- signbank/dictionary/update.py | 51 ++++++--- signbank/dictionary/urls.py | 2 +- signbank/video/forms.py | 19 +++- signbank/video/models.py | 103 +++++++++++++++++- signbank/video/urls.py | 2 +- signbank/video/views.py | 13 ++- 12 files changed, 301 insertions(+), 63 deletions(-) diff --git a/media/js/process_annotated_eaf_files.js b/media/js/process_annotated_eaf_files.js index e54716ed5..78da892a9 100644 --- a/media/js/process_annotated_eaf_files.js +++ b/media/js/process_annotated_eaf_files.js @@ -3,7 +3,7 @@ $(document).ready(function () { $('#eaffile').change(function () { var formData = new FormData(); formData.append('eaffile', $('#eaffile')[0].files[0]); // Add the file input to the FormData object - formData.append('check_gloss_label', [$('#check_gloss_label').val()]); // Add the gloss label to check in checkbox + formData.append('check_gloss_label', [$('#check-gloss-label').val()]); // Add the gloss label to check in checkbox formData.append('csrfmiddlewaretoken', $('input[name=csrfmiddlewaretoken]').val()); // Include the CSRF token in the FormData object formData.append('dataset', $('#dataset').val()); // add the dataset to the formdata diff --git a/signbank/dictionary/admin.py b/signbank/dictionary/admin.py index 3e8eadad7..9bc6922df 100755 --- a/signbank/dictionary/admin.py +++ b/signbank/dictionary/admin.py @@ -1358,6 +1358,10 @@ class ExampleSentenceTranslationAdmin(admin.ModelAdmin): search_fields = ['text'] list_filter = ['language'] +class AnnotatedSentenceSourceAdmin(admin.ModelAdmin): + list_display = ("name", "source", "url", "dataset") + search_fields = ['name'] + list_filter = ['dataset'] class AffiliationAdmin(admin.ModelAdmin): list_display = ("name", ) @@ -1408,4 +1412,5 @@ class AffiliatedUserAdmin(admin.ModelAdmin): admin.site.register(GlossSense, GlossSenseAdmin) admin.site.register(Sense, SenseAdmin) admin.site.register(ExampleSentence, ExampleSentenceAdmin) -admin.site.register(ExampleSentenceTranslation, ExampleSentenceTranslationAdmin) \ No newline at end of file +admin.site.register(ExampleSentenceTranslation, ExampleSentenceTranslationAdmin) +admin.site.register(AnnotatedSentenceSource, AnnotatedSentenceSourceAdmin) \ No newline at end of file diff --git a/signbank/dictionary/models.py b/signbank/dictionary/models.py index f4948da56..3f31d857e 100755 --- a/signbank/dictionary/models.py +++ b/signbank/dictionary/models.py @@ -3881,7 +3881,7 @@ def has_contexts(self): return True return False - def add_annotations(self, annotations, gloss): + def add_annotations(self, annotations, gloss, start_cut=-1, end_cut=-1): """Add annotations to the annotated sentence""" dataset = gloss.lemma.dataset @@ -3902,7 +3902,31 @@ def add_annotations(self, annotations, gloss): repr = False if annotation[1] == "1": repr = True - AnnotatedGloss.objects.create(gloss=annotationIdGlossTranslation.gloss, annotatedsentence=self, isRepresentative=repr, starttime=annotation[2], endtime=annotation[3]) + + starttime = int(annotation[2]) + endtime = int(annotation[3]) + + excluded = False + if start_cut >= 0 and end_cut >= 0: + # If completely outside of the cut, exclude it + if starttime >= end_cut or endtime <= 0: + print(gloss_translation, " is outside of the cut") + excluded = True + elif (min(endtime, end_cut) - max(starttime, start_cut)) < 100: + print(gloss_translation, " is too short") + excluded = True + # If the annotation is partially outside the cut, make it fit + elif starttime < start_cut and endtime > start_cut and endtime < end_cut: + starttime = start_cut + elif starttime >= start_cut and starttime < end_cut and endtime > end_cut: + endtime = end_cut + elif starttime < start_cut and endtime > end_cut: + starttime = start_cut + endtime = end_cut + starttime = starttime - start_cut + endtime = endtime - start_cut + if not excluded: + AnnotatedGloss.objects.create(gloss=annotationIdGlossTranslation.gloss, annotatedsentence=self, isRepresentative=repr, starttime=starttime, endtime=endtime) def get_annotated_glosses_list(self): annotated_glosses = [] @@ -3990,23 +4014,32 @@ def has_video(self): return self.get_video() not in ['', None] - def add_video(self, user, videofile, eaffile, corpus): + def add_video(self, user, videofile, eaffile, source): """Add a video to the annotated sentence""" from signbank.video.models import AnnotatedVideo - if ((isinstance(videofile, File) or videofile.content_type == 'django.core.files.uploadedfile.InMemoryUploadedFile' \ - or videofile.content_type == 'django.core.files.uploadedfile.TemporaryUploadedFile')\ - and (eaffile.content_type == 'application/octet-stream' or eaffile.content_type == 'django.core.files.uploadedfile.TemporaryUploadedFile'\ - or eaffile.content_type == 'django.core.files.uploadedfile.InMemoryUploadedFile')): - annotatedVideo = AnnotatedVideo.objects.create(annotatedsentence=self, videofile=videofile, eaffile=eaffile) - else: - return None - - annotatedVideo.corpus = corpus + annotatedVideo = AnnotatedVideo.objects.create(annotatedsentence=self, videofile=videofile, eaffile=eaffile) + annotatedVideo.source = source annotatedVideo.save() return annotatedVideo - def __str__(self): - return " | ".join(self.get_annotatedstc_translations()) \ No newline at end of file + return " | ".join(self.get_annotatedstc_translations()) + +class AnnotatedSentenceSource(models.Model): + """A source to choose for a sentence""" + name = models.CharField(max_length=200) + source = models.TextField() + url = models.TextField(blank=True) + dataset = models.ForeignKey(Dataset, on_delete=models.CASCADE) + + def __str__(self): + return self.source + + def get_absolute_url(self): + from urllib.parse import urlparse + parsed_url = urlparse(self.url) + if not parsed_url.scheme: + return 'http://' + self.url + return self.url \ No newline at end of file diff --git a/signbank/dictionary/templates/dictionary/add_annotated_sentence.html b/signbank/dictionary/templates/dictionary/add_annotated_sentence.html index 80658d4e6..fcebc73b9 100644 --- a/signbank/dictionary/templates/dictionary/add_annotated_sentence.html +++ b/signbank/dictionary/templates/dictionary/add_annotated_sentence.html @@ -30,7 +30,7 @@ - + @@ -65,8 +65,13 @@

- {% trans "From corpus:" %} - + {% trans "Source:" %} +

diff --git a/signbank/dictionary/templates/dictionary/edit_annotated_sentence.html b/signbank/dictionary/templates/dictionary/edit_annotated_sentence.html index 43f6fccac..ce0cefc76 100644 --- a/signbank/dictionary/templates/dictionary/edit_annotated_sentence.html +++ b/signbank/dictionary/templates/dictionary/edit_annotated_sentence.html @@ -11,7 +11,7 @@ {% get_obj_perms request.user for gloss.lemma.dataset as "dataset_perms" %} {% if "change_dataset" in dataset_perms %} -
+
{% trans "Edit Annotated Sentence" %} @@ -19,7 +19,7 @@ {% trans "For the following sentence:" %}
{% url 'dictionary:protected_media' '' as protected_media_url %} -