Skip to content

Commit

Permalink
Merge pull request #5763 from avalonmediasystem/caption_as_transcript
Browse files Browse the repository at this point in the history
Add option to treat a caption file as transcript
  • Loading branch information
masaball authored Apr 5, 2024
2 parents d3a94c3 + 1c6b8a6 commit 6cf022d
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 29 deletions.
20 changes: 14 additions & 6 deletions app/controllers/supplemental_files_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,20 @@ def edit_structure_path
end

def edit_file_information
ident = "machine_generated_#{params[:id]}".to_sym

if params[ident] && !@supplemental_file.machine_generated?
@supplemental_file.tags += ['machine_generated']
elsif !params[ident] && @supplemental_file.machine_generated?
@supplemental_file.tags -= ['machine_generated']
file_params = [
{ param: "machine_generated_#{params[:id]}".to_sym, tag: "machine_generated", method: :machine_generated? },
{ param: "treat_as_transcript_#{params[:id]}".to_sym, tag: "transcript", method: :caption_transcript? }
]

file_params.each do |v|
param_name = v[:param]
tag = v[:tag]
method = v[:method]
if params[param_name] && !@supplemental_file.send(method)
@supplemental_file.tags += [tag]
elsif !params[param_name] && @supplemental_file.send(method)
@supplemental_file.tags -= [tag]
end
end
@supplemental_file.label = supplemental_file_params[:label]
return unless supplemental_file_params[:language].present?
Expand Down
38 changes: 25 additions & 13 deletions app/models/iiif_canvas_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def display_content
end

def annotation_content
supplemental_captions_transcripts.collect { |file| supplementing_content_data(file) }
supplemental_captions_transcripts.uniq.collect { |file| supplementing_content_data(file) }.flatten
end

def sequence_rendering
Expand Down Expand Up @@ -103,16 +103,28 @@ def audio_display_content(quality)
end

def supplementing_content_data(file)
url = if !file.is_a?(SupplementalFile)
Rails.application.routes.url_helpers.captions_master_file_url(master_file.id)
elsif file.tags.include?('caption')
Rails.application.routes.url_helpers.captions_master_file_supplemental_file_url(master_file.id, file.id)
elsif file.tags.include?('transcript')
Rails.application.routes.url_helpers.transcripts_master_file_supplemental_file_url(master_file.id, file.id)
else
Rails.application.routes.url_helpers.master_file_supplemental_file_url(master_file.id, file.id)
end
IIIFManifest::V3::AnnotationContent.new(body_id: url, **supplemental_attributes(file))
unless file.is_a?(SupplementalFile)
url = Rails.application.routes.url_helpers.captions_master_file_url(master_file.id)
return IIIFManifest::V3::AnnotationContent.new(body_id: url, **supplemental_attributes(file))
end

tags = file.tags.reject { |t| t == 'machine_generated' }.compact
case tags
when ['caption']
url = Rails.application.routes.url_helpers.captions_master_file_supplemental_file_url(master_file.id, file.id)
IIIFManifest::V3::AnnotationContent.new(body_id: url, **supplemental_attributes(file, type: 'caption'))
when ['transcript']
url = Rails.application.routes.url_helpers.transcripts_master_file_supplemental_file_url(master_file.id, file.id)
IIIFManifest::V3::AnnotationContent.new(body_id: url, **supplemental_attributes(file, type: 'transcript'))
when ['caption', 'transcript']
caption_url = Rails.application.routes.url_helpers.captions_master_file_supplemental_file_url(master_file.id, file.id)
transcript_url = Rails.application.routes.url_helpers.transcripts_master_file_supplemental_file_url(master_file.id, file.id)
[IIIFManifest::V3::AnnotationContent.new(body_id: caption_url, **supplemental_attributes(file, type: 'caption')),
IIIFManifest::V3::AnnotationContent.new(body_id: transcript_url, **supplemental_attributes(file, type: 'transcript'))]
else
url = Rails.application.routes.url_helpers.master_file_supplemental_file_url(master_file.id, file.id)
IIIFManifest::V3::AnnotationContent.new(body_id: url, **supplemental_attributes(file))
end
end

def stream_urls
Expand Down Expand Up @@ -206,10 +218,10 @@ def manifest_attributes(quality, media_type)
end
end

def supplemental_attributes(file)
def supplemental_attributes(file, type: nil)
if file.is_a?(SupplementalFile)
label = file.tags.include?('machine_generated') ? file.label + ' (machine generated)' : file.label
format = if file.file.content_type == 'text/srt' && file.tags.include?('caption')
format = if file.file.content_type == 'text/srt' && type == 'caption'
'text/vtt'
else
file.file.content_type
Expand Down
4 changes: 4 additions & 0 deletions app/models/supplemental_file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ def machine_generated?
tags.include?('machine_generated')
end

def caption_transcript?
tags.include?('caption') && tags.include?('transcript')
end

# Adapted from https://github.com/opencoconut/webvtt-ruby/blob/e07d59220260fce33ba5a0c3b355e3ae88b99457/lib/webvtt/parser.rb#L11-L30
def self.convert_from_srt(srt)
# normalize timestamps in srt
Expand Down
24 changes: 17 additions & 7 deletions app/views/media_objects/_supplemental_files_list.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,26 @@ Unless required by applicable law or agreed to in writing, software distributed
<div class="file_view <% if tag == "caption" %>captions<% end %>">
<% if tag == "caption" %>
<div class="row supplemental-file-data edit-item" id="edit-label-row">
<div class="col-md-4 col-4">
<label class="caption-form-label">Label</label>
</div>
<div class="col-md-4 col-4">
<label class="caption-form-label">Language</label>
<div class="row col-sm-9 col-md-8 col-9">
<div class="col-md-4 col-4">
<label class="caption-form-label">Label</label>
</div>
<div class="col-md-4 col-4">
<label class="caption-form-label">Language</label>
</div>
</div>
</div>
<% end %>
<% files.each do |file| %>
<% next if tag == 'transcript' and file.tags.include?('caption') %>
<div class="supplemental-file-data" data-file-id="<%= file.id %>" data-masterfile-id="<%= section.id %>" data-tag="<%= tag %>" >
<span name="label_<%= section.id + "_" + file.id.to_s %>" class="display-item"><%= file.label %></span>
<%= form_for :supplemental_file, url: object_supplemental_file_path(section, file), remote: true,
html: { method: "put", class: "supplemental-file-form edit-item", id: "form-#{file.id}" },
data: { file_id: file.id, masterfile_id: section.id } do |form| %>
<div class="col-sm-9 col-md-8 col-9 form-row p-0">
<div class="form-group col-md-6 col-sm-6 col-6">
<% col = tag == 'caption' ? 4 : 6 %>
<div class="form-group col-md-<%= col %> col-sm-<%= col %> col-<%= col %>">
<%= form.text_field :label, id: "supplemental_file_input_#{section.id}_#{file.id}", value: file.label %>
</div>
<% if tag == 'transcript' %>
Expand All @@ -45,11 +49,17 @@ Unless required by applicable law or agreed to in writing, software distributed
</span>
<% end %>
<% if tag == 'caption' %>
<div class="form-group col-md-6 col p-0">
<div class="form-group col-md-4 col p-0">
<%= form.text_field :language, id: "supplemental_file_language_#{section.id}_#{file.id}", value: LanguageTerm.find(file.language).text,
class: "typeahead from-model form-control",
data: { model: 'languageTerm', validate: false } %>
</div>
<span class="form-group col-md-4 col-sm-4 col-4 p-0">
<%= label_tag "treat_as_transcript_#{file.id}", class: "ml-3" do %>
<%= check_box_tag "treat_as_transcript_#{file.id}", '1', file.caption_transcript? %>
Treat as transcript
<% end %>
</span>
<% end %>
</div>
<div class="col-sm-3 col-md-4 col-3 p-0">
Expand Down
28 changes: 25 additions & 3 deletions spec/models/iiif_canvas_presenter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -269,14 +269,20 @@
expect(subject.any? { |content| content.body_id =~ /master_files\/#{master_file.id}\/captions/ }).to eq false
end

context 'srt captions' do
context 'srt files' do
let(:srt_caption_file) { FactoryBot.create(:supplemental_file, :with_caption_srt_file, :with_caption_tag) }
let(:supplemental_files) { [supplemental_file, transcript_file, caption_file, srt_caption_file] }
it 'sets format to "text/vtt"' do
let(:srt_transcript_file) { FactoryBot.create(:supplemental_file, :with_caption_srt_file, :with_transcript_tag) }
let(:supplemental_files) { [transcript_file, caption_file, srt_caption_file, srt_transcript_file] }
it 'sets caption format to "text/vtt"' do
captions = subject.select { |s| s.body_id.include?('captions') }
expect(captions.none? { |content| content.format == 'text/srt' }).to eq true
expect(captions.all? { |content| content.format == 'text/vtt' }).to eq true
end
it 'sets other formats to the original file content_type' do
supplemental_files = subject.reject { |s| s.body_id.include?('captions') }
expect(supplemental_files[0].format).to eq transcript_file.file.content_type
expect(supplemental_files[1].format).to eq srt_transcript_file.file.content_type
end
end

context 'legacy master file captions' do
Expand All @@ -298,6 +304,22 @@
expect(subject.any? { |content| content.label['eng'][0] =~ /#{transcript_file.label} \(machine generated\)/ }).to eq true
end
end

context 'caption being treated as a transcript' do
let(:caption_file) { FactoryBot.create(:supplemental_file, :with_caption_file, tags: ['caption', 'transcript']) }
let(:srt_caption_file) { FactoryBot.create(:supplemental_file, :with_caption_srt_file, tags: ['caption', 'transcript']) }
let(:supplemental_files) { [caption_file, srt_caption_file] }

it 'returns a caption entry and a transcript entry with proper formats' do
captions = subject.select { |s| s.body_id.include?('captions') }
transcripts = subject.select { |s| s.body_id.include?('transcripts') }
expect(captions.count).to eq 2
expect(transcripts.count).to eq 2
expect(captions.all? { |content| content.format == 'text/vtt' }).to eq true
expect(transcripts.any? { |content| content.format == 'text/vtt' }).to eq true
expect(transcripts.any? { |content| content.format == 'text/srt' }).to eq true
end
end
end
end

Expand Down
28 changes: 28 additions & 0 deletions spec/support/supplemental_files_controller_examples.rb
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,34 @@
end
end

context "caption treated as transcript" do
let(:transcript_param) { "treat_as_transcript_#{supplemental_file.id}".to_sym }
context "missing transcript tag" do
let(:supplemental_file) { FactoryBot.create(:supplemental_file, :with_caption_file, :with_caption_tag, label: 'label') }
it "adds transcript note to tags" do
expect {
put :update, params: { class_id => object.id, id: supplemental_file.id, transcript_param => 1, supplemental_file: valid_update_attributes, format: :html }, session: valid_session
}.to change { master_file.reload.supplemental_files.first.tags }.from(['caption']).to(['caption', 'transcript'])
end
end
context "with transcript tag" do
let(:supplemental_file) { FactoryBot.create(:supplemental_file, :with_transcript_file, tags: ['caption', 'transcript'], label: 'label') }
it "does not add more instances of transcript note" do
expect {
put :update, params: { class_id => object.id, id: supplemental_file.id, transcript_param => 1, supplemental_file: valid_update_attributes, format: :html }, session: valid_session
}.to not_change { master_file.reload.supplemental_files.first.tags }.from(['caption', 'transcript'])
end
end
context "removing transcript designation" do
let(:supplemental_file) { FactoryBot.create(:supplemental_file, :with_transcript_file, tags: ['caption', 'transcript'], label: 'label (machine generated)') }
it "removes transcript note from tags" do
expect {
put :update, params: { class_id => object.id, id: supplemental_file.id, supplemental_file: valid_update_attributes, format: :html }, session: valid_session
}.to change { master_file.reload.supplemental_files.first.tags }.from(['caption', 'transcript']).to(['caption'])
end
end
end

context "with invalid params" do
it "returns a 400" do
put :update, params: { class_id => object.id, id: supplemental_file.id, supplemental_file: invalid_update_attributes, format: :html }, session: valid_session
Expand Down

0 comments on commit 6cf022d

Please sign in to comment.