1.0-dev17 (Subscription page created)

This commit is contained in:
2022-05-05 15:06:10 +02:00
Unverified
parent b4347f2b5c
commit e23258a638
34 changed files with 121 additions and 526 deletions

View File

@@ -7,19 +7,22 @@ using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using VDownload.Core.Enums;
using VDownload.Core.Exceptions;
using VDownload.Core.Interfaces;
using VDownload.Core.Services.Sources.Twitch.Helpers;
namespace VDownload.Core.Services.Sources.Twitch
{
public class Channel : IPlaylistService
[Serializable]
public class Channel : IPlaylist
{
#region CONSTRUCTORS
public Channel(string id)
{
ID = id;
Source = PlaylistSource.TwitchChannel;
}
#endregion
@@ -29,9 +32,11 @@ namespace VDownload.Core.Services.Sources.Twitch
#region PROPERTIES
public string ID { get; private set; }
public Uri PlaylistUrl { get; private set; }
public PlaylistSource Source { get; private set; }
public Uri Url { get; private set; }
public string Name { get; private set; }
public IVideoService[] Videos { get; private set; }
public IVideo[] Videos { get; private set; }
private string UniqueUserID { get; set; }
#endregion
@@ -55,14 +60,15 @@ namespace VDownload.Core.Services.Sources.Twitch
}
// Create unified playlist url
PlaylistUrl = new Uri($"https://twitch.tv/{ID}");
Url = new Uri($"https://twitch.tv/{ID}");
// Set parameters
if (!ID.All(char.IsDigit)) ID = (string)response["id"];
UniqueUserID = (string)response["id"];
Name = (string)response["display_name"];
}
// GET CHANNEL VIDEOS
public async Task GetVideosAsync(CancellationToken cancellationToken = default) => await GetVideosAsync(0, cancellationToken);
public async Task GetVideosAsync(int numberOfVideos, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -89,7 +95,7 @@ namespace VDownload.Core.Services.Sources.Twitch
JToken response = null;
using (WebClient client = await Client.Helix())
{
client.QueryString.Add("user_id", ID);
client.QueryString.Add("user_id", UniqueUserID);
client.QueryString.Add("first", count.ToString());
client.QueryString.Add("after", pagination);
response = JObject.Parse(await client.DownloadStringTaskAsync("https://api.twitch.tv/helix/videos"));

View File

@@ -18,13 +18,15 @@ using Windows.Storage;
namespace VDownload.Core.Services.Sources.Twitch
{
public class Clip : IVideoService
[Serializable]
public class Clip : IVideo
{
#region CONSTRUCTORS
public Clip(string id)
{
ID = id;
Source = VideoSource.TwitchClip;
}
#endregion
@@ -33,8 +35,9 @@ namespace VDownload.Core.Services.Sources.Twitch
#region PROPERTIES
public VideoSource Source { get; private set; }
public string ID { get; private set; }
public Uri VideoUrl { get; private set; }
public Uri Url { get; private set; }
public Metadata Metadata { get; private set; }
public BaseStream[] BaseStreams { get; private set; }
@@ -60,7 +63,7 @@ namespace VDownload.Core.Services.Sources.Twitch
}
// Create unified video url
VideoUrl = new Uri($"https://clips.twitch.tv/{ID}");
Url = new Uri($"https://clips.twitch.tv/{ID}");
// Set metadata
Metadata = new Metadata()

View File

@@ -8,17 +8,12 @@ using Windows.Storage;
namespace VDownload.Core.Services.Sources.Twitch.Helpers
{
public class Auth
public static class Auth
{
#region CONSTANTS
// CLIENT ID
public readonly static string ClientID = "yukkqkwp61wsv3u1pya17crpyaa98y";
// GQL API CLIENT ID
public readonly static string GQLApiClientID = "kimne78kx3ncx6brgo4mv6wki5h1ko";
// REDIRECT URL
public readonly static Uri RedirectUrl = new Uri("https://www.vd.com");
// AUTHORIZATION URL
@@ -35,16 +30,13 @@ namespace VDownload.Core.Services.Sources.Twitch.Helpers
#region METHODS
// READ ACCESS TOKEN
public static async Task<string> ReadAccessTokenAsync()
{
try
{
// Get file
StorageFolder authDataFolder = await ApplicationData.Current.LocalCacheFolder.GetFolderAsync("AuthData");
StorageFile authDataFile = await authDataFolder.GetFileAsync("Twitch.auth");
// Return data
return await FileIO.ReadTextAsync(authDataFile);
}
catch (FileNotFoundException)
@@ -53,42 +45,33 @@ namespace VDownload.Core.Services.Sources.Twitch.Helpers
}
}
// SAVE ACCESS TOKEN
public static async Task SaveAccessTokenAsync(string accessToken)
{
// Get file
StorageFolder authDataFolder = await ApplicationData.Current.LocalCacheFolder.CreateFolderAsync("AuthData", CreationCollisionOption.OpenIfExists);
StorageFile authDataFile = await authDataFolder.CreateFileAsync("Twitch.auth", CreationCollisionOption.ReplaceExisting);
// Save data
await FileIO.WriteTextAsync(authDataFile, accessToken);
}
// DELETE ACCESS TOKEN
public static async Task DeleteAccessTokenAsync()
{
try
{
// Get file
StorageFolder authDataFolder = await ApplicationData.Current.LocalCacheFolder.GetFolderAsync("AuthData");
StorageFile authDataFile = await authDataFolder.GetFileAsync("Twitch.auth");
// Delete file
await authDataFile.DeleteAsync();
}
catch (FileNotFoundException) { }
}
// VALIDATE ACCESS TOKEN
public static async Task<(bool IsValid, string Login, DateTime? ExpirationDate)> ValidateAccessTokenAsync(string accessToken)
{
// Create client
WebClient client = new WebClient { Encoding = Encoding.UTF8 };
client.Headers.Add("Authorization", $"Bearer {accessToken}");
try
{
// Check access token
JObject response = JObject.Parse(await client.DownloadStringTaskAsync("https://id.twitch.tv/oauth2/validate"));
string login = response["login"].ToString();
@@ -108,13 +91,10 @@ namespace VDownload.Core.Services.Sources.Twitch.Helpers
}
}
// REVOKE ACCESS TOKEN
public static async Task RevokeAccessTokenAsync(string accessToken)
{
// Create client
WebClient client = new WebClient { Encoding = Encoding.UTF8 };
// Revoke access token
await client.UploadStringTaskAsync(new Uri("https://id.twitch.tv/oauth2/revoke"), $"client_id={ClientID}&token={accessToken}");
}

View File

@@ -4,34 +4,28 @@ using VDownload.Core.Exceptions;
namespace VDownload.Core.Services.Sources.Twitch.Helpers
{
internal class Client
internal static class Client
{
internal static async Task<WebClient> Helix()
{
// Get access token
string accessToken = await Auth.ReadAccessTokenAsync();
if (accessToken == null) throw new TwitchAccessTokenNotFoundException();
// Check access token
var twitchAccessTokenValidation = await Auth.ValidateAccessTokenAsync(accessToken);
if (!twitchAccessTokenValidation.IsValid) throw new TwitchAccessTokenNotValidException();
// Create client
WebClient client = new WebClient();
client.Headers.Add("Authorization", $"Bearer {accessToken}");
client.Headers.Add("Client-Id", Auth.ClientID);
// Return client
return client;
}
internal static WebClient GQL()
{
// Create client
WebClient client = new WebClient();
client.Headers.Add("Client-Id", Auth.GQLApiClientID);
// Return client
return client;
}
}

View File

@@ -17,13 +17,15 @@ using Windows.Storage;
namespace VDownload.Core.Services.Sources.Twitch
{
public class Vod : IVideoService
[Serializable]
public class Vod : IVideo
{
#region CONSTRUCTORS
public Vod(string id)
{
ID = id;
Source = VideoSource.TwitchVod;
}
#endregion
@@ -32,8 +34,9 @@ namespace VDownload.Core.Services.Sources.Twitch
#region PROPERTIES
public VideoSource Source { get; private set; }
public string ID { get; private set; }
public Uri VideoUrl { get; private set; }
public Uri Url { get; private set; }
public Metadata Metadata { get; private set; }
public BaseStream[] BaseStreams { get; private set; }
@@ -72,7 +75,7 @@ namespace VDownload.Core.Services.Sources.Twitch
internal void GetMetadataAsync(JToken response)
{
// Create unified video url
VideoUrl = new Uri($"https://www.twitch.tv/videos/{ID}");
Url = new Uri($"https://www.twitch.tv/videos/{ID}");
// Set metadata
Metadata = new Metadata()