using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Threading; using System.Threading.Tasks; using Flurl; using Sony.Filtr.Contracts.Abstractions; using Sony.Filtr.Contracts.Entities; using Sony.Filtr.Utility; namespace Sony.Filtr.YouTube.Api { public class AuthenticatedYoutubeApi : YouTubeApi { public AuthenticatedYoutubeApi(ServiceAccount serviceAccount, IServiceAccountManager serviceAccountManager, GoogleOAuth2Api googleOAuth2Api, IRateLimiter rateLimiter) : base(BuildAuthenticatedClient(serviceAccount, serviceAccountManager, googleOAuth2Api, rateLimiter)) { } private static HttpClient BuildAuthenticatedClient(ServiceAccount serviceAccount, IServiceAccountManager serviceAccountManager, GoogleOAuth2Api googleOAuth2Api, IRateLimiter rateLimiter) { var rateLimitedHandler = new RateLimitedHttpMessageHandler(new HttpClientHandler() {AutomaticDecompression = DecompressionMethods.GZip}, rateLimiter); var youtubeOAuthMessageHandler = new YouTubeOAuthHttpMessageHandler(serviceAccount, serviceAccountManager, googleOAuth2Api, rateLimitedHandler); HttpClient client = new HttpClient(youtubeOAuthMessageHandler); client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip")); client.DefaultRequestHeaders.UserAgent.ParseAdd("Filtr/1.0 (gzip)"); return client; } public async Task AddVideoToPlaylistAsync(string playlistId, Id videoId, int? position = null) { var url = new Url("https://www.googleapis.com/youtube/v3/playlistItems"); url.SetQueryParam("part", "snippet"); var response = await GetDefaultClient().PostAsJsonAsync(url, new { snippet = new { playlistId = playlistId, resourceId = new { videoId = videoId.videoId, kind = "youtube#video" }, position = position } }); if (!response.IsSuccessStatusCode) { throw YoutubeApiException.FromHttpResponseMessage(response, "Could not add videos to youtube playlists"); } } public async Task AddVideosToPlaylistAsync(string playlistId, List videoIds, CancellationToken cancellationToken) { foreach (var videoId in videoIds) { var youtubeId = new Id() {videoId = videoId}; await AddVideoToPlaylistAsync(playlistId, youtubeId); } } public async Task DeletePlaylistItemsAsync(PlaylistItem playlistItem) { if (playlistItem == null) return; var url = new Url("https://www.googleapis.com/youtube/v3/playlistItems"); url.SetQueryParam("id", playlistItem.id); var response = await GetDefaultClient().DeleteAsync(url); if (!response.IsSuccessStatusCode) { throw YoutubeApiException.FromHttpResponseMessage(response, "Could not delete playlists items in youtube playlist"); } } public async Task DeletePlaylistItemsAsync(List playlistItems) { if (playlistItems == null || !playlistItems.Any()) return; foreach (var playlistItem in playlistItems) { await DeletePlaylistItemsAsync(playlistItem); } } public async Task UpdatePlaylistItemAsync(PlaylistItem playlistItem) { if (playlistItem == null) return; var simpleItem = new SimplePlaylistItem(playlistItem); var url = new Url("https://www.googleapis.com/youtube/v3/playlistItems"); url.SetQueryParam("part", "snippet"); var response = await GetDefaultClient().PutAsJsonAsync(url, simpleItem); if (!response.IsSuccessStatusCode) { throw YoutubeApiException.FromHttpResponseMessage(response, "Could not update playlist item in youtube playlist."); } } public async Task UpdatePlaylistAsync(Playlist playlist) { if (playlist == null) return; var url = new Url("https://www.googleapis.com/youtube/v3/playlists"); url.SetQueryParam("part", "snippet"); var response = await GetDefaultClient().PutAsJsonAsync(url, playlist); if (!response.IsSuccessStatusCode) { throw YoutubeApiException.FromHttpResponseMessage(response, "Could not update playlist"); } } public async Task GetMyChannelsAsync() { var url = new Url("https://www.googleapis.com/youtube/v3/channels"); url.SetQueryParam("part", "snippet"); url.SetQueryParam("mine", "true"); var response = await GetDefaultClient().GetAsync(url); var playlistResponse = await response.Content.ReadAsAsync(); return playlistResponse; } } }