From 48ca28e5d3af9542d577fdc2a1c3918e4dfc7fa2 Mon Sep 17 00:00:00 2001 From: Mason Ballengee Date: Mon, 18 Nov 2024 16:40:11 -0500 Subject: [PATCH] Fix processing of google drive files When we made the switch from mediainfo to ffprobe, we created a new class for processing the file. Because Google Drive utilizes headers/params for its authorization flow, this change resulted in the file information becoming divorced from the auth token. By explicitly passing the auth token through to the classes downloading and processing the file, we are able to fix this oversight. --- app/models/master_file.rb | 2 +- app/services/file_locator.rb | 19 +++++++++++-------- lib/avalon/ffprobe.rb | 4 +++- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/app/models/master_file.rb b/app/models/master_file.rb index 51e8706eae..df55db16d9 100644 --- a/app/models/master_file.rb +++ b/app/models/master_file.rb @@ -727,7 +727,7 @@ def saveDerivativesHash(derivative_hash) def reloadTechnicalMetadata! # Reset ffprobe - @ffprobe = Avalon::FFprobe.new(FileLocator.new(file_location)) + @ffprobe = Avalon::FFprobe.new(FileLocator.new(file_location, { auth_header: @auth_header })) # Formats like MP4 can be caught as both audio and video # so the case statement flows in the preferred order diff --git a/app/services/file_locator.rb b/app/services/file_locator.rb index 65041c88c3..16063c1a74 100644 --- a/app/services/file_locator.rb +++ b/app/services/file_locator.rb @@ -16,7 +16,7 @@ require 'aws-sdk-s3' class FileLocator - attr_reader :source + attr_reader :source, :auth_header class S3File attr_reader :bucket, :key @@ -46,8 +46,9 @@ def download_url end end - def initialize(source) + def initialize(source, opts = {}) @source = source + @auth_header = opts[:auth_header] end def uri @@ -122,13 +123,15 @@ def reader end end - # Ruby 3.0 removed URI#open from being called by Kernel#open. - # Prioritize using URI#open, attempt to fallback to Kernel#open - # if URI fails. def open_uri - URI.open(uri, 'r') - rescue - Kernel::open(uri.to_s, 'r') + # Google Drive download urls have the auth as a param + # so we need to make sure the auth gets passed in + # when we try to access files + if auth_header.present? && auth_header.is_a?(Hash) + URI.open(uri, 'r', auth_header) + else + URI.open(uri, 'r') + end end def attachment diff --git a/lib/avalon/ffprobe.rb b/lib/avalon/ffprobe.rb index 0322b8ec60..2bea318517 100644 --- a/lib/avalon/ffprobe.rb +++ b/lib/avalon/ffprobe.rb @@ -23,7 +23,9 @@ def json_output return @json_output unless @json_output.nil? return @json_output = {} unless valid_content_type?(@media_file) ffprobe = Settings&.ffprobe&.path || 'ffprobe' - raw_output = `#{ffprobe} -i "#{@media_file.location}" -v quiet -show_format -show_streams -of json` + # Include authorization headers for cases like Google Drive + header = "-headers 'Authorization: #{@media_file.auth_header.fetch('Authorization')}'" if @media_file.auth_header.present? + raw_output = `#{ffprobe} #{header} -i "#{@media_file.location}" -v quiet -show_format -show_streams -of json` # $? is a variable for the exit status of the last executed process. # Success == 0, any other value means the command failed in some way. unless $?.exitstatus == 0