Pipeline registrazione/upload con storage S3, archivio web e app, proxy replay per il browser, OAuth YouTube sulla pagina club (Premium Full) e footer legale. Co-authored-by: Cursor <cursoragent@cursor.com>
124 lines
3.1 KiB
Ruby
124 lines
3.1 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)
|
|
@backend.presigned_get_url(key: key, expires_in: expires_in)
|
|
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:)
|
|
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:)
|
|
signer = Aws::S3::Presigner.new(client: client)
|
|
signer.presigned_url(
|
|
:get_object,
|
|
bucket: MatchLiveTv.replay_storage_bucket,
|
|
key: key,
|
|
expires_in: expires_in
|
|
)
|
|
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
|