Aggiunge modulo Replay, Garage dev e YouTube a livello società.
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>
This commit is contained in:
123
backend/app/services/recordings/storage.rb
Normal file
123
backend/app/services/recordings/storage.rb
Normal file
@@ -0,0 +1,123 @@
|
||||
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
|
||||
Reference in New Issue
Block a user