Writed test for DASH manifests generation,
Added Watch later retrieval module
This commit is contained in:
@@ -17,7 +17,7 @@ namespace YouTube.API.Test
|
|||||||
public void ValidManifestTest()
|
public void ValidManifestTest()
|
||||||
{
|
{
|
||||||
YouTubeService service = new YouTubeService();
|
YouTubeService service = new YouTubeService();
|
||||||
IReadOnlyList<DashManifest> manifests = service.DashManifests.List("VC5-YkjMHuw").Execute();
|
IReadOnlyList<DashManifest> manifests = service.DashManifests.List("NkGbcQwWxqk").Execute();
|
||||||
foreach (var i in manifests)
|
foreach (var i in manifests)
|
||||||
Console.WriteLine(i.Label);
|
Console.WriteLine(i.Label);
|
||||||
Assert.IsNotNull(manifests);
|
Assert.IsNotNull(manifests);
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using Google.Apis.Auth.OAuth2;
|
||||||
|
using Google.Apis.Services;
|
||||||
|
using Google.Apis.YouTube.v3.Data;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using YouTube.Authorization;
|
||||||
|
using YouTube.Resources;
|
||||||
|
|
||||||
|
namespace YouTube.API.Test
|
||||||
|
{
|
||||||
|
public class WatchLaterTest
|
||||||
|
{
|
||||||
|
const string testVideoId = "NkGbcQwWxqk";
|
||||||
|
YouTubeService service;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
var task = AuthorizationHelpers.ExchangeToken(new ClientSecrets
|
||||||
|
{
|
||||||
|
ClientId = "1096685398208-u95rcpkqb4e1ijfmb8jdq3jsg37l8igv.apps.googleusercontent.com",
|
||||||
|
ClientSecret = "IU5bbdjwvmx8ttJoXQ7e6JWd"
|
||||||
|
}, "4/twFMhT4xSaAxls-rEayp8MxFI2Oy0knUdDbAXKnfyMkbDHaNyqhV6uM");
|
||||||
|
task.Wait();
|
||||||
|
|
||||||
|
UserCredential credential = task.Result;
|
||||||
|
service = new YouTubeService(new BaseClientService.Initializer
|
||||||
|
{
|
||||||
|
HttpClientInitializer = credential,
|
||||||
|
ApplicationName = "FoxTube"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void AddVideoTest()
|
||||||
|
{
|
||||||
|
WatchLaterResource.InsertRequest request = service.WatchLater.Insert(testVideoId, "snippet");
|
||||||
|
PlaylistItem item = request.Execute();
|
||||||
|
Console.WriteLine(JsonConvert.SerializeObject(item));
|
||||||
|
Assert.IsNotNull(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void DeleteVideoTest()
|
||||||
|
{
|
||||||
|
WatchLaterResource.DeleteRequest request = service.WatchLater.Delete(testVideoId);
|
||||||
|
request.Execute();
|
||||||
|
Assert.Pass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -62,7 +62,7 @@ namespace YouTube.Authorization
|
|||||||
AuthorizationCodeFlow authorizationCodeFlow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer()
|
AuthorizationCodeFlow authorizationCodeFlow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer()
|
||||||
{
|
{
|
||||||
ClientSecrets = clientSecrets,
|
ClientSecrets = clientSecrets,
|
||||||
Scopes = responseData.scope.Split(' ')
|
Scopes = responseData.scope.ToString().Split(' ')
|
||||||
});
|
});
|
||||||
|
|
||||||
return new UserCredential(authorizationCodeFlow, "user", tokenResponse);
|
return new UserCredential(authorizationCodeFlow, "user", tokenResponse);
|
||||||
|
|||||||
@@ -1,28 +1,109 @@
|
|||||||
using System;
|
using AngleSharp.Html.Dom;
|
||||||
|
using AngleSharp.Html.Parser;
|
||||||
|
using Google.Apis.Http;
|
||||||
|
using Google.Apis.Services;
|
||||||
|
using Google.Apis.YouTube.v3;
|
||||||
|
using Google.Apis.YouTube.v3.Data;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace YouTube.Resources
|
namespace YouTube.Resources
|
||||||
{
|
{
|
||||||
public class WatchLaterResource
|
public class WatchLaterResource
|
||||||
{
|
{
|
||||||
public class ListRequest { }
|
IClientService Service { get; }
|
||||||
public class InsertRequest { }
|
|
||||||
public class DeleteRequest { }
|
public WatchLaterResource(IClientService service) =>
|
||||||
|
Service = service;
|
||||||
|
|
||||||
public ListRequest List()
|
public ListRequest List()
|
||||||
{
|
{
|
||||||
return new ListRequest();
|
return new ListRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
public InsertRequest Insert(string videoId)
|
public InsertRequest Insert(string videoId, string part) =>
|
||||||
{
|
new InsertRequest(Service, videoId, part);
|
||||||
return new InsertRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
public DeleteRequest Delete(string videoId)
|
public DeleteRequest Delete(string videoId) =>
|
||||||
|
new DeleteRequest(Service, videoId);
|
||||||
|
|
||||||
|
public class ListRequest { }
|
||||||
|
public class InsertRequest
|
||||||
{
|
{
|
||||||
return new DeleteRequest();
|
IClientService Service { get; set; }
|
||||||
|
public string Id { get; set; }
|
||||||
|
public string Part { get; set; }
|
||||||
|
|
||||||
|
public InsertRequest(IClientService service, string videoId, string part)
|
||||||
|
{
|
||||||
|
Service = service;
|
||||||
|
Id = videoId;
|
||||||
|
Part = part;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<PlaylistItem> ExecuteAsync()
|
||||||
|
{
|
||||||
|
PlaylistItem playlist = new PlaylistItem
|
||||||
|
{
|
||||||
|
Snippet = new PlaylistItemSnippet
|
||||||
|
{
|
||||||
|
PlaylistId = "WL",
|
||||||
|
ResourceId = new ResourceId
|
||||||
|
{
|
||||||
|
VideoId = Id,
|
||||||
|
Kind = "youtube#video"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
PlaylistItemsResource.InsertRequest request = (Service as YouTubeService).PlaylistItems.Insert(playlist, Part);
|
||||||
|
|
||||||
|
return await request.ExecuteAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlaylistItem Execute()
|
||||||
|
{
|
||||||
|
Task<PlaylistItem> task = ExecuteAsync();
|
||||||
|
task.Wait();
|
||||||
|
return task.Result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class DeleteRequest
|
||||||
|
{
|
||||||
|
IClientService Service { get; set; }
|
||||||
|
public string Id { get; set; }
|
||||||
|
|
||||||
|
public DeleteRequest(IClientService service, string videoId)
|
||||||
|
{
|
||||||
|
Service = service;
|
||||||
|
Id = videoId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ExecuteAsync()
|
||||||
|
{
|
||||||
|
ConfigurableHttpClient client = Service.HttpClient;
|
||||||
|
string data = await client.GetStringAsync($"https://youtube.com/watch?v={Id}&disable_polymer=true&bpctr=9999999999&hl=en");
|
||||||
|
string plid = Regex.Match(data, @"(?<=plid=).?\w+").Value;
|
||||||
|
IHtmlDocument html = await new HtmlParser().ParseDocumentAsync(data);
|
||||||
|
string sessionToken = html.GetElementsByTagName("input").FirstOrDefault(i => i.GetAttribute("name") == "session_token")?.GetAttribute("value");
|
||||||
|
Dictionary<string, string> body = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "video_ids", Id },
|
||||||
|
{ "full_list_id", "WL" },
|
||||||
|
{ "plid", plid },
|
||||||
|
{ "session_token", sessionToken }
|
||||||
|
};
|
||||||
|
HttpResponseMessage response = await client.PostAsync("https://www.youtube.com/playlist_video_ajax?action_delete_from_playlist=1", new FormUrlEncodedContent(body));
|
||||||
|
string responseStr = await response.Content.ReadAsStringAsync();
|
||||||
|
if (!responseStr.Contains("SUCCESS"))
|
||||||
|
throw new Exception(responseStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Execute() =>
|
||||||
|
ExecuteAsync().Wait();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,13 +8,10 @@ namespace YouTube
|
|||||||
public VideoPlaybackResource VideoPlayback => new VideoPlaybackResource(this);
|
public VideoPlaybackResource VideoPlayback => new VideoPlaybackResource(this);
|
||||||
public new CaptionsResource Captions => new CaptionsResource(this);
|
public new CaptionsResource Captions => new CaptionsResource(this);
|
||||||
public HistoryResource History { get; }
|
public HistoryResource History { get; }
|
||||||
public WatchLaterResource WatchLater { get; }
|
public WatchLaterResource WatchLater => new WatchLaterResource(this);
|
||||||
// TODO: Add Activities override for recomendations and subscriptions and implementation of cc retrieval
|
// TODO: Add Activities override for recomendations and subscriptions
|
||||||
|
|
||||||
public YouTubeService() : base()
|
public YouTubeService() : base() { }
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public YouTubeService(Initializer initializer) : base(initializer) { }
|
public YouTubeService(Initializer initializer) : base(initializer) { }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user