Files
old-holivud2/app/presenters/matches_presenter.rb
2020-05-31 22:38:19 +02:00

271 lines
7.2 KiB
Ruby

class MatchesPresenter
def initialize(video, video_analysis, audio_analysis, edl_events, graphics_edl_events)
@video = video
@video_analysis = video_analysis
@audio_analysis = audio_analysis
@edl_events = edl_events
@graphics_edl_events = graphics_edl_events
end
def build_chronological_matches
if video.analysis_success?
sort_matches(first_appearances_with_images)
else
[]
end
end
def build_chronological_audio_matches
if video.audio_analysis_success?
sort_matches(audio_matches)
else
[]
end
end
def build_graphics_matches
if video.analysis_success?
confirmed_graphics = video.graphics_elements
sort_matches(
graphics_edl_events.
reject { |edl_event| edl_event.source_file_name.blank? }.
map do |edl_event|
GraphicsMatch.new(
edl_event.source_file_name,
edl_event.start_time,
already_confirmed?(confirmed_graphics, edl_event),
edl_event.timecode_in
)
end.
compact
)
else
[]
end
end
def all_tracks_edl_events
edl_events
end
private
def audio_events
if ENV["DISABLE_EDL_CHANNEL_FILTER"]
edl_events
else
edl_events.find_all { |event| event.channel.include? "A" }
end
end
def video_events
if ENV["DISABLE_EDL_CHANNEL_FILTER"]
edl_events
else
edl_events.find_all { |event| event.channel == "V" }
end
end
def already_confirmed?(confirmation, edl_event)
confirmation.any? { |confirmed| confirmed.source_file_name == edl_event.source_file_name && confirmed.timecode_in == edl_event.timecode_in }
end
attr_reader :video, :video_analysis, :audio_analysis, :edl_events, :graphics_edl_events
def sort_matches(matches)
matches.
sort_by(&:start_time).
reverse
end
def first_appearances_with_images
video_analysis.first_appearances.
reject { |appearance| appearance.external_image_id.blank? }.
map { |appearance| SuggestedMatch.build_from_first_appearance(appearance, appearance.start_time) }
end
def audio_matches
audio_analysis.results.map do |result|
# If it's a library match, use the provided composer and publisher info
# If it's an original music match, use the composer and publisher info we have
# If it's an acquired media match, don't provide any composer and publisher info
if result.type == "acquired_media"
composers = ""
publishers = ""
elsif result.type == "original_music"
file_info = FileInfo.find(result.uid)
composers = file_info.releasable.composers.map { |composer| "#{composer.name}, #{composer.affiliation}, #{composer.percentage}%" }.join("|")
publishers = file_info.releasable.publishers.map { |publisher| "#{publisher.name}, #{publisher.affiliation}, #{publisher.percentage}%" }.join("|")
else
composers = result.audio_data.composers.map { |composer| "#{composer.name}, #{composer.affiliation}, #{composer.percentage}" }.join("|")
publishers = result.audio_data.publishers.map { |publisher| "#{publisher.name}, #{publisher.affiliation}, #{publisher.percentage}" }.join("|")
end
result.edl.map do |edl_event|
is_confirmed = video.audio_confirmations.any? do |confirmation|
# TODO: Use EDL ID in the future to determine this
confirmation.source_file_name == result.requested_filename &&
confirmation.timecode_in == edl_event.timecode_in
end
result_type = result.type == "library" ? "library_music" : result.type
AudioSuggestedMatch.new(
AudioData.new(
result.audio_data.filename,
result.requested_filename,
composers,
publishers,
result.audio_data.catalog,
result.audio_data.title,
),
edl_event.start_time.to_i,
is_confirmed,
edl_event.timecode_in,
result_type,
video.audio_only_edl_file.attached?
)
end
end.flatten
end
class GraphicsMatch
attr_reader :appears_at_timecode, :start_time, :filename, :confirmed, :timecode_in
def initialize(filename, start_time, confirmed, timecode_in)
@filename = filename
@start_time = start_time
@appears_at_timecode = Timecode.from_seconds(start_time.to_f / 1000)
@confirmed = confirmed
@timecode_in = timecode_in
end
def elapsed_time_until_appearance
appears_at_timecode.to_seconds
end
end
class AudioSuggestedMatch
attr_reader :appears_at_timecode, :start_time, :confirmed, :timecode_in, :confirmation_type, :edl_type
def initialize(audio_data, start_time, confirmed, timecode_in, confirmation_type, audio_edl_attached)
@audio_data = audio_data
@start_time = start_time
@confirmed = confirmed
@appears_at_timecode = Timecode.from_seconds(start_time.to_f / 1000)
@timecode_in = timecode_in
@confirmation_type = confirmation_type
@edl_type = audio_edl_attached ? "audio" : "all_tracks"
end
def presented_filename
if confirmation_type == "original_music"
"(O) #{audio_data.requested_filename}"
else
"(L) #{audio_data.requested_filename}"
end
end
def filename
audio_data.requested_filename
end
def composer_info
audio_data.composer
end
def publisher_info
audio_data.publisher
end
def catalog
audio_data.catalog
end
def title
audio_data.title
end
def elapsed_time_until_appearance
appears_at_timecode.to_seconds
end
private
attr_reader :audio_data
end
class FileInfoSuggestedMatch < SimpleDelegator
attr_reader :appears_at_timecode, :start_time, :file_info, :timecode_in
def self.build(file_info, start_time, timecode_in)
release = file_info.releasable
new(release, file_info, start_time, timecode_in)
end
def initialize(release, file_info, start_time, timecode_in)
super(release)
@file_info = file_info
@start_time = start_time
@appears_at_timecode = Timecode.from_seconds(start_time.to_f / 1000)
@timecode_in = timecode_in
end
def elapsed_time_until_appearance
appears_at_timecode.to_seconds
end
end
class SuggestedMatch < SimpleDelegator
attr_reader :appears_at_timecode, :start_time
def self.build_from_first_appearance(appearance, start_time)
release = ExternalImage.new(appearance.external_image_id).release
new(release, start_time)
end
def initialize(release, start_time)
super(release)
@start_time = start_time
@appears_at_timecode = Timecode.from_seconds(start_time.to_f / 1000)
end
def elapsed_time_until_appearance
appears_at_timecode.to_seconds
end
end
class ExternalImage
attr_reader :uid
def initialize(uid)
@uid = uid
end
def release
release_klass.find(id)
end
private
def id
uid.match(/.*_release_(?<id>\d*)/)
Regexp.last_match(:id) || uid
end
def release_klass
release_name.classify.constantize
end
def release_name
uid.match(/(?<type>\w*_release)_\d/)
Regexp.last_match(:type) || "appearance_release"
end
end
end