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:
@@ -19,7 +19,7 @@ module Youtube
|
||||
when :platform
|
||||
PlatformCredential.configured? ? PlatformCredential.new : nil
|
||||
when :team
|
||||
@team.youtube_credential
|
||||
@team.club.youtube_credential
|
||||
end
|
||||
end
|
||||
|
||||
@@ -32,7 +32,7 @@ module Youtube
|
||||
end
|
||||
|
||||
def team_channel_available?
|
||||
@ent.youtube_enabled? && @ent.premium_full? && @mode == "team" && @team.youtube_credential.present?
|
||||
@ent.youtube_enabled? && @ent.premium_full? && @mode == "team" && @team.club.youtube_credential.present?
|
||||
end
|
||||
|
||||
def effective_channel
|
||||
|
||||
@@ -3,12 +3,18 @@ module Youtube
|
||||
PURPOSE = :youtube_oauth_connect
|
||||
|
||||
class << self
|
||||
def for_team(team_id:, user_id:, return_app: false)
|
||||
payload = [team_id.to_s, user_id.to_s]
|
||||
def for_club(club_id:, user_id:, return_app: false)
|
||||
payload = ["club", club_id.to_s, user_id.to_s]
|
||||
payload << "app" if return_app
|
||||
verifier.generate(payload, expires_in: 1.hour)
|
||||
end
|
||||
|
||||
# API mobile: accetta team_id ma firma OAuth per la società.
|
||||
def for_team(team_id:, user_id:, return_app: false)
|
||||
club_id = Team.find(team_id).club_id
|
||||
for_club(club_id: club_id, user_id: user_id, return_app: return_app)
|
||||
end
|
||||
|
||||
def for_platform(admin_id:)
|
||||
verifier.generate(["platform", admin_id.to_s], expires_in: 1.hour)
|
||||
end
|
||||
@@ -19,10 +25,21 @@ module Youtube
|
||||
when Array
|
||||
if payload.first == "platform"
|
||||
{ kind: :platform, admin_id: payload[1] }
|
||||
elsif payload.size >= 2
|
||||
elsif payload.first == "club" && payload.size >= 3
|
||||
{
|
||||
kind: :team,
|
||||
team_id: payload[0],
|
||||
kind: :club,
|
||||
club_id: payload[1],
|
||||
user_id: payload[2],
|
||||
return_app: payload[3] == "app"
|
||||
}
|
||||
elsif payload.size >= 2
|
||||
# Stato legacy (team_id): risolvi la società
|
||||
team = Team.find_by(id: payload[0])
|
||||
raise ArgumentError, "stato OAuth non valido" unless team
|
||||
|
||||
{
|
||||
kind: :club,
|
||||
club_id: team.club_id,
|
||||
user_id: payload[1],
|
||||
return_app: payload[2] == "app"
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ module Youtube
|
||||
when "matchlivetv_light"
|
||||
PlatformCredential.configured?
|
||||
when "team"
|
||||
@team.youtube_credential.present? || PlatformCredential.configured?
|
||||
@team.club.youtube_credential.present? || PlatformCredential.configured?
|
||||
else
|
||||
false
|
||||
end
|
||||
@@ -31,7 +31,7 @@ module Youtube
|
||||
if @mode == "matchlivetv_light"
|
||||
PlatformCredential.configured?
|
||||
elsif @mode == "team"
|
||||
@team.youtube_credential.blank? && PlatformCredential.configured?
|
||||
@team.club.youtube_credential.blank? && PlatformCredential.configured?
|
||||
else
|
||||
false
|
||||
end
|
||||
@@ -41,12 +41,12 @@ module Youtube
|
||||
if uses_platform_channel?
|
||||
PLATFORM_LABEL
|
||||
else
|
||||
@team.youtube_credential&.channel_title
|
||||
@team.club.youtube_credential&.channel_title
|
||||
end
|
||||
end
|
||||
|
||||
def needs_team_oauth?
|
||||
@mode == "team" && @ent.premium_full? && @team.youtube_credential.blank? && !PlatformCredential.configured?
|
||||
@mode == "team" && @ent.premium_full? && @team.club.youtube_credential.blank? && !PlatformCredential.configured?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
57
backend/app/services/youtube/video_upload_service.rb
Normal file
57
backend/app/services/youtube/video_upload_service.rb
Normal file
@@ -0,0 +1,57 @@
|
||||
module Youtube
|
||||
class VideoUploadService
|
||||
class Error < StandardError; end
|
||||
|
||||
def initialize(team, youtube_channel: nil)
|
||||
@team = team
|
||||
@resolver = CredentialResolver.new(team, channel: youtube_channel)
|
||||
@credential = @resolver.resolve
|
||||
end
|
||||
|
||||
def upload_file!(file_path:, title:, description: nil, privacy_status: "unlisted", tags: [])
|
||||
return mock_upload if @credential.blank? || missing_oauth_config?
|
||||
raise Error, "File non trovato" unless File.exist?(file_path)
|
||||
|
||||
client = authorized_client
|
||||
video = Google::Apis::YoutubeV3::Video.new(
|
||||
snippet: Google::Apis::YoutubeV3::VideoSnippet.new(
|
||||
title: title,
|
||||
description: description,
|
||||
tags: tags.presence
|
||||
),
|
||||
status: Google::Apis::YoutubeV3::VideoStatus.new(
|
||||
privacy_status: privacy_status,
|
||||
self_declared_made_for_kids: false
|
||||
)
|
||||
)
|
||||
|
||||
result = client.insert_video(
|
||||
"snippet,status",
|
||||
video,
|
||||
upload_source: file_path,
|
||||
content_type: "video/mp4"
|
||||
)
|
||||
{
|
||||
video_id: result.id,
|
||||
watch_url: "https://www.youtube.com/watch?v=#{result.id}"
|
||||
}
|
||||
rescue Google::Apis::Error => e
|
||||
raise Error, e.message
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def mock_upload
|
||||
id = "mock_vod_#{SecureRandom.hex(6)}"
|
||||
{ video_id: id, watch_url: "https://www.youtube.com/watch?v=#{id}" }
|
||||
end
|
||||
|
||||
def missing_oauth_config?
|
||||
ENV["YOUTUBE_CLIENT_ID"].blank?
|
||||
end
|
||||
|
||||
def authorized_client
|
||||
OauthRefresh.new(@credential).apply!(Google::Apis::YoutubeV3::YouTubeService.new)
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user