using FoxTube.Utils; using Google.Apis.Auth.OAuth2; using Google.Apis.Oauth2.v2; using Google.Apis.Oauth2.v2.Data; using Google.Apis.Services; using Google.Apis.YouTube.v3; using Google.Apis.YouTube.v3.Data; using System; using System.Linq; using System.Collections.Generic; using System.Threading.Tasks; using YouTube; using YoutubeExplode; using FoxTube.Services; namespace FoxTube.Models { public class User { public Userinfoplus UserInfo { get; private set; } public UserCredential Credential { get; private set; } public Channel Channel { get; private set; } public List Subscriptions { get; } = new List(); public ExtendedYouTubeService Service { get; private set; } public YoutubeClient Client { get; private set; } private User() { } public async Task UpdateSubscriptionState(string channelId) { if (Subscriptions.Find(i => i.ChannelId == channelId) is Subscription subscription) { try { await Service.Subscriptions.Delete(subscription.SubscriptionId).ExecuteAsync(); } catch (Exception e) { Metrics.SendReport(new Exception("Failed to unsubscribe", e)); return true; } UserService.SubscriptionsChangedInvoker(this, subscription); Subscriptions.Remove(subscription); return false; } else { var request = Service.Subscriptions.Insert(new Google.Apis.YouTube.v3.Data.Subscription() { Snippet = new SubscriptionSnippet() { ResourceId = new ResourceId() { ChannelId = channelId, Kind = "youtube#channel" } } }, "id"); var subscriptionData = await request.ExecuteAsync(); if (subscriptionData == null) return false; Channel channel = await Extensions.GetChannel(subscriptionData.Snippet.ChannelId, "snippet,statistics,brandingSettins"); subscription = new Subscription { Title = channel.Snippet.Title, ChannelId = channel.Id, SubscriptionId = subscriptionData.Id, VideosCount = channel.Statistics.VideoCount.Value, SubscribersCount = channel.Statistics.SubscriberCount, Avatar = channel.Snippet.Thumbnails, Banner = channel.BrandingSettings.Image }; Subscriptions.Add(subscription); UserService.SubscriptionsChangedInvoker(this, subscription); return true; } } public static async Task GetUser(UserCredential credential) { User user = new User { Credential = credential }; BaseClientService.Initializer initializer = new BaseClientService.Initializer { ApplicationName = "FoxTube", HttpClientInitializer = credential }; user.Service = new ExtendedYouTubeService(initializer); user.UserInfo = await new Oauth2Service(initializer).Userinfo.Get().ExecuteAsync(); var request = user.Service.Channels.List("snippet,contentDetails,brandingSettings"); request.Mine = true; user.Channel = request.Execute().Items[0]; // TODO: Retrieve history and WL await user.LoadSubscriptions(); return user; } public async Task LoadSubscriptions() { Subscriptions.Clear(); SubscriptionsResource.ListRequest subRequest = Service.Subscriptions.List("snippet"); subRequest.Mine = true; subRequest.MaxResults = 50; subRequest.Order = SubscriptionsResource.ListRequest.OrderEnum.Relevance; SubscriptionListResponse subResponse; do { subResponse = await subRequest.ExecuteAsync(); subRequest.PageToken = subResponse.NextPageToken; Subscriptions.AddRange(subResponse.Items.Select(i => new Subscription { Title = i.Snippet.Title, ChannelId = i.Snippet.ResourceId.ChannelId, SubscriptionId = i.Id, Avatar = i.Snippet.Thumbnails, Description = i.Snippet.Description })); } while (!string.IsNullOrWhiteSpace(subRequest.PageToken)); var request = Service.Channels.List("statistics,brandingSettings"); request.Id = string.Join(',', Subscriptions.Select(i => i.ChannelId)); request.MaxResults = 50; ChannelListResponse response; if (Subscriptions.Count > 0) do { response = await request.ExecuteAsync(); request.PageToken = response.NextPageToken; Subscriptions.ForEach(i => { Channel channel = response.Items.FirstOrDefault(c => c.Id == i.ChannelId); i.Banner = channel.BrandingSettings.Image; i.SubscribersCount = channel.Statistics.HiddenSubscriberCount.Value ? null : channel.Statistics.SubscriberCount; i.VideosCount = channel.Statistics.VideoCount.Value; }); } while (!string.IsNullOrWhiteSpace(request.PageToken)); } } }