Skip to content

Commit

Permalink
Annotated video added source options and video cutting option #1266
Browse files Browse the repository at this point in the history
  • Loading branch information
Jetske committed Jul 2, 2024
1 parent fb97037 commit f5bbf5e
Show file tree
Hide file tree
Showing 12 changed files with 301 additions and 63 deletions.
2 changes: 1 addition & 1 deletion media/js/process_annotated_eaf_files.js
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
7 changes: 6 additions & 1 deletion signbank/dictionary/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -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", )
Expand Down Expand Up @@ -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)
admin.site.register(ExampleSentenceTranslation, ExampleSentenceTranslationAdmin)
admin.site.register(AnnotatedSentenceSource, AnnotatedSentenceSourceAdmin)
61 changes: 47 additions & 14 deletions signbank/dictionary/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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 = []
Expand Down Expand Up @@ -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())
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
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
<input type='hidden' name='redirect' value='{{PREFIX_URL}}/dictionary/gloss/{{gloss.id}}'>
<input type='hidden' name='object_id' value='{{gloss.id}}'>
<input type='hidden' name='object_type' value='annotated_video'>
<input type='hidden' id='check_gloss_label' value='{{annotationidgloss}}'>
<input type='hidden' id='check-gloss-label' value='{{annotationidgloss}}'>
<input type='hidden' id='dataset' value='{{gloss.lemma.dataset.acronym}}'>
<table id="staffops">
<tr>
Expand Down Expand Up @@ -65,8 +65,13 @@
<input type='hidden' name='translations' id='translations-hidden' value=''>

<br><br>
{% trans "From corpus:" %}
<input style="width:100%" id="corpus_name" name="corpus_name" value="" maxlength="100" type="text"/>
{% trans "Source:" %}
<select name="source_id">
<option value="">{% trans "-" %}</option>
{% for source in annotated_sentence_sources %}
<option value="{{ source.id }}">{{ source.name }}</option>
{% endfor %}
</select>

<br><br>
<input class='btn btn-primary' type='submit' value='Upload' />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@

{% get_obj_perms request.user for gloss.lemma.dataset as "dataset_perms" %}
{% if "change_dataset" in dataset_perms %}
<div class='editform', style="width:500px">
<div class='editform', style="width:1000px">
<fieldset>
<legend>{% trans "Edit Annotated Sentence" %}</legend>

{% trans "For the following gloss:" %} {{annotationidgloss}}<br><br>

{% trans "For the following sentence:" %}<br>
{% url 'dictionary:protected_media' '' as protected_media_url %}
<video id="sentenceVideo" controls width="500px">
<video id="sentence-video" controls width="700px">
<source src="{{ protected_media_url }}/{{ annotated_sentence.annotatedvideo.videofile }}" type="video/mp4">
</video>

Expand All @@ -28,16 +28,74 @@
<input type='hidden' name='redirect' value='{{PREFIX_URL}}/dictionary/gloss/{{gloss.id}}'>
<input type='hidden' name='annotatedsentenceid' value='{{annotated_sentence.id}}'>
<input type='hidden' name='glossid' value='{{gloss.id}}'>
<input type='hidden' id='check_gloss_label' value='{{annotationidgloss}}'>
<input type='hidden' id='check-gloss-label' value='{{annotationidgloss}}'>
<input type='hidden' id='dataset' value='{{gloss.lemma.dataset.acronym}}'>
<br>
<br><br>
<input type="checkbox" id="trim-video-checked" name="trim-video-checked" role="button" value="off"> {% trans 'Shorten the video' %}
<div id="trim_video">
{% trans "Instructions: slide to a point in the video and set it as start and/or end point" %}<br>
<button type="button" id="start-button" class="btn btn-primary" data-dismiss="modal">{% trans "Set new start point" %}</button>
Start: <input type="text" id="start-point" name="start-ms" value="0" readonly><br>
<button type="button" id="end-button" class="btn btn-primary" data-dismiss="modal">{% trans "Set new end point" %}</button>
End: <input type="text" id="end-point" name="end-ms" value="{{ annotated_sentence.annotatedvideo.get_end_ms }}" readonly><br>
<button type="button" id="reset-trim" class="btn btn-primary" data-dismiss="modal">{% trans "Reset" %}</button>
<span id="trim-feedback"></span>
</div>

<style>
#trim-video-checked:not(:checked)~#trim_video {
display: none;
}
#start-point, #end-point {
color: #787878;
}
</style>

<script>
var video = document.getElementById('sentence-video');
var startButton = document.getElementById('start-button');
var startPoint = document.getElementById('start-point');
var endButton = document.getElementById('end-button');
var endPoint = document.getElementById('end-point');
var resetTrim = document.getElementById('reset-trim');
var feedback = document.getElementById('trim-feedback');
const end = endPoint.value;

startButton.addEventListener('click', function() {
var currentTime = (video.currentTime * 1000).toFixed(0);
var endValue = parseInt(endPoint.value, 10);
if (!isNaN(endValue) && currentTime > endValue) {
feedback.innerHTML = "Start point must be before end point";
} else {
startPoint.value = currentTime;
feedback.innerHTML = "";
}
});

endButton.addEventListener('click', function() {
var currentTime = (video.currentTime * 1000).toFixed(0);
var startValue = parseInt(startPoint.value, 10);
if (!isNaN(startValue) && currentTime < startValue) {
feedback.innerHTML = "End point must be after start point";
} else {
endPoint.value = currentTime;
feedback.innerHTML = "";
}
});

resetTrim.addEventListener('click', function() {
startPoint.value = 0;
endPoint.value = end;
feedback.innerHTML = "";
});
</script>

<br><br>
{% trans "Download the current .eaf file here:" %}
<a href="{{ annotated_sentence.annotatedvideo.eaffile.url }}" download>{{ annotated_sentence.annotatedvideo.get_eaffile_name }}</a>
<br><br>
{% trans "Choose the updated annotation file (.eaf) here:" %}
<input type="file" id="eaffile" name="eaffile" required>
<input type="file" id="eaffile" name="eaffile">
<br>
<div id="feedback">
{{ annotations_table_html|safe }}
Expand All @@ -56,8 +114,16 @@
{% endfor %}

<br><br>
{% trans "From corpus:" %}
<input style="width:100%" id="corpus_name" name="corpus_name" value="{{ corpus }}" maxlength="100" type="text"/>
{% trans "Source:" %}
<select name="source_id">
{% if annotated_sentence.annotatedvideo.source %}
<option value="{{ annotated_sentence.annotatedvideo.source.id }}">{{ annotated_sentence.annotatedvideo.source.name }}</option>
{% endif %}
<option value="">{% trans "-" %}</option>
{% for source in annotated_sentence_sources %}
<option value="{{ source.id }}">{{ source.name }}</option>
{% endfor %}
</select>

<br><br>
<input class='btn btn-primary' type='submit' value='Save' />
Expand Down
13 changes: 8 additions & 5 deletions signbank/dictionary/templates/dictionary/gloss_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -1202,7 +1202,7 @@ <h2 id='modalTitleSimilarSense'>{% trans "Similar senses" %}</h2>
<span class = "sense-icon pull-right"><a href='{% url "dictionary:add_sentence_video" glossid=gloss.id examplesentenceid=examplesentence.id %}'><img src='{{STATIC_URL}}images/addvideo.png' style="width:25px; height:25px; margin: 0px; cursor: pointer;"></a></span>
{% if examplesentence.has_video %}
<span class="sense-icon pull-right">
<form class="formbutton" action="{{PREFIX_URL}}/video/deletesentencevideo/{{examplesentence.id}}" method='post'>
<form class="formbutton" action="{{PREFIX_URL}}/video/deletesentence_video/{{examplesentence.id}}" method='post'>
{% csrf_token %}
<input type=image value="" src='{{STATIC_URL}}images/deletevideo.png' alt = "submit" style='width: 25px; height: 25px; margin: 0px; cursor: pointer;'>
</form>
Expand Down Expand Up @@ -2405,7 +2405,7 @@ <h2 id='modalTitleDeleteAnnotatedSentence'>{% trans "Delete this annotated sente
<style>.highlight {background-color: rgb(255, 149, 63);}</style>

<video id="myVideo_{{ forloop.counter }}" controls>
<source src="{{ protected_media_url }}/{{ annotated_sentence.annotatedvideo.videofile }}" type="video/mp4">
<source src="{{ protected_media_url }}/{{ annotated_sentence.annotatedvideo.videofile}}?v={% now 'YmdHis' %}" type="video/mp4">
</video>

<br><br><i>Glosses</i><br>
Expand Down Expand Up @@ -2449,9 +2449,12 @@ <h2 id='modalTitleDeleteAnnotatedSentence'>{% trans "Delete this annotated sente
{% endif %}
</p>
<p>
{% if annotated_sentence.annotatedvideo.corpus %}
<i>{% trans "Corpus" %}</i><br>
{{ annotated_sentence.annotatedvideo.corpus }}
{% if annotated_sentence.annotatedvideo.source %}
<i>{% trans "Source" %}</i><br>
{{ annotated_sentence.annotatedvideo.source.source }}
{% if annotated_sentence.annotatedvideo.source.url %}
, <a href="{{ annotated_sentence.annotatedvideo.source.get_absolute_url }}">{{ annotated_sentence.annotatedvideo.source.url }}</a>
{% endif %}
{% endif %}
</p>
</td>
Expand Down
Loading

0 comments on commit f5bbf5e

Please sign in to comment.