Dopo auth Rails redirect a URL presigned su /media/ (edge → Garage); aumenta RAILS_MAX_THREADS, corregge ingest log ops via stdin e keystore Play Console. Co-authored-by: Cursor <cursoragent@cursor.com>
129 lines
3.4 KiB
Ruby
129 lines
3.4 KiB
Ruby
require "open-uri"
|
|
require "aws-sdk-s3"
|
|
|
|
module Recordings
|
|
class Storage
|
|
class Error < StandardError; end
|
|
|
|
def initialize
|
|
@backend = MatchLiveTv.replay_storage_local? ? LocalBackend.new : S3Backend.new
|
|
end
|
|
|
|
def upload(local_path:, key:, content_type: "video/mp4")
|
|
@backend.upload(local_path: local_path, key: key, content_type: content_type)
|
|
end
|
|
|
|
def delete(key:)
|
|
@backend.delete(key: key)
|
|
end
|
|
|
|
def download_to_temp(key:)
|
|
local = local_path_for_key(key)
|
|
return local if local && File.exist?(local)
|
|
|
|
url = presigned_get_url(key: key, expires_in: 600)
|
|
raise Error, "Impossibile scaricare file dallo storage" if url.blank?
|
|
|
|
dest = File.join(Dir.tmpdir, "replay-dl-#{SecureRandom.hex(8)}.mp4")
|
|
URI.open(url) do |remote|
|
|
File.binwrite(dest, remote.read)
|
|
end
|
|
dest
|
|
end
|
|
|
|
def presigned_get_url(key:, expires_in: MatchLiveTv.replay_presigned_url_ttl_seconds, response_content_disposition: nil)
|
|
@backend.presigned_get_url(
|
|
key: key,
|
|
expires_in: expires_in,
|
|
response_content_disposition: response_content_disposition
|
|
)
|
|
end
|
|
|
|
def local_path_for_key(key)
|
|
@backend.local_path_for_key(key)
|
|
end
|
|
|
|
def backend_name
|
|
@backend.name
|
|
end
|
|
|
|
class LocalBackend
|
|
def name
|
|
"local"
|
|
end
|
|
|
|
def upload(local_path:, key:, content_type:)
|
|
dest = local_path_for_key(key)
|
|
FileUtils.mkdir_p(File.dirname(dest))
|
|
FileUtils.cp(local_path, dest)
|
|
File.size(dest)
|
|
end
|
|
|
|
def delete(key:)
|
|
path = local_path_for_key(key)
|
|
FileUtils.rm_f(path)
|
|
true
|
|
end
|
|
|
|
def presigned_get_url(key:, expires_in:, response_content_disposition: nil)
|
|
nil
|
|
end
|
|
|
|
def local_path_for_key(key)
|
|
File.join(MatchLiveTv.recordings_local_path, "replays", key)
|
|
end
|
|
end
|
|
|
|
class S3Backend
|
|
def name
|
|
"s3"
|
|
end
|
|
|
|
def upload(local_path:, key:, content_type:)
|
|
client.put_object(
|
|
bucket: MatchLiveTv.replay_storage_bucket,
|
|
key: key,
|
|
body: File.open(local_path, "rb"),
|
|
content_type: content_type
|
|
)
|
|
File.size(local_path)
|
|
end
|
|
|
|
def delete(key:)
|
|
client.delete_object(bucket: MatchLiveTv.replay_storage_bucket, key: key)
|
|
true
|
|
rescue Aws::S3::Errors::ServiceError => e
|
|
raise Error, e.message
|
|
end
|
|
|
|
def presigned_get_url(key:, expires_in:, response_content_disposition: nil)
|
|
signer = Aws::S3::Presigner.new(client: client)
|
|
params = {
|
|
bucket: MatchLiveTv.replay_storage_bucket,
|
|
key: key,
|
|
expires_in: expires_in
|
|
}
|
|
params[:response_content_disposition] = response_content_disposition if response_content_disposition.present?
|
|
signer.presigned_url(:get_object, **params)
|
|
end
|
|
|
|
def local_path_for_key(_key)
|
|
nil
|
|
end
|
|
|
|
private
|
|
|
|
def client
|
|
@client ||= Aws::S3::Client.new(
|
|
access_key_id: MatchLiveTv.replay_storage_access_key_id,
|
|
secret_access_key: MatchLiveTv.replay_storage_secret_access_key,
|
|
endpoint: MatchLiveTv.replay_storage_endpoint,
|
|
region: MatchLiveTv.replay_storage_region,
|
|
force_path_style: MatchLiveTv.replay_storage_force_path_style?,
|
|
response_checksum_validation: "WHEN_REQUIRED"
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|