174 lines
5.5 KiB
C#
174 lines
5.5 KiB
C#
using System.Net;
|
|
using Manager.App.Models.Library;
|
|
using Manager.YouTube;
|
|
using Microsoft.AspNetCore.Components;
|
|
using MudBlazor;
|
|
|
|
namespace Manager.App.Components.Dialogs
|
|
{
|
|
public partial class AccountDialog : ComponentBase
|
|
{
|
|
[CascadingParameter] private IMudDialogInstance? MudDialog { get; set; }
|
|
[Parameter] public string DefaultUserAgent { get; set; } = "";
|
|
private ClientChannel? ClientChannel { get; set; }
|
|
private CookieCollection ImportCookies { get; set; } = [];
|
|
private bool _isLoading;
|
|
private AccountImportSteps _steps = AccountImportSteps.Authenticate;
|
|
|
|
private bool _cookieImportTextValid;
|
|
private string _cookieText = "";
|
|
private string _cookieDomain = ".youtube.com";
|
|
|
|
private bool CanSave()
|
|
{
|
|
return ClientChannel?.YouTubeClient?.State?.LoggedIn == true;
|
|
}
|
|
|
|
private bool CanContinue()
|
|
{
|
|
switch (_steps)
|
|
{
|
|
case AccountImportSteps.Authenticate:
|
|
if (ImportCookies.Count != 0)
|
|
{
|
|
return true;
|
|
}
|
|
break;
|
|
case AccountImportSteps.Validate:
|
|
if (ClientChannel?.YouTubeClient?.State?.LoggedIn == true)
|
|
{
|
|
return true;
|
|
}
|
|
break;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private async Task OnNextStep()
|
|
{
|
|
switch (_steps)
|
|
{
|
|
case AccountImportSteps.Authenticate:
|
|
if (CanContinue())
|
|
{
|
|
_steps = AccountImportSteps.Validate;
|
|
await BuildClient();
|
|
await InvokeAsync(StateHasChanged);
|
|
return;
|
|
}
|
|
SnackbarService.Add("Cannot continue!", Severity.Warning);
|
|
break;
|
|
case AccountImportSteps.Validate:
|
|
if (CanSave())
|
|
{
|
|
MudDialog?.Close(DialogResult.Ok(ClientChannel));
|
|
await InvokeAsync(StateHasChanged);
|
|
return;
|
|
}
|
|
SnackbarService.Add("Cannot save!", Severity.Warning);
|
|
break;
|
|
}
|
|
await InvokeAsync(StateHasChanged);
|
|
}
|
|
|
|
private void ParseCookies()
|
|
{
|
|
try
|
|
{
|
|
ImportCookies.Clear();
|
|
ImportCookies.Add(ParseCookieHeader(_cookieText, _cookieDomain));
|
|
_cookieText = string.Empty;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
SnackbarService.Add($"Parsing cookies failed: {e.Message}", Severity.Error);
|
|
}
|
|
StateHasChanged();
|
|
}
|
|
|
|
private void ClearPreparedClient()
|
|
{
|
|
ClientChannel?.YouTubeClient?.Dispose();
|
|
ClientChannel = null;
|
|
ImportCookies.Clear();
|
|
_steps = AccountImportSteps.Authenticate;
|
|
StateHasChanged();
|
|
}
|
|
|
|
private static string? ValidateCookieText(string text)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(text))
|
|
return "Cookies are required";
|
|
|
|
var pairs = text.Split(';', StringSplitOptions.RemoveEmptyEntries);
|
|
foreach (var pair in pairs)
|
|
{
|
|
if (!pair.Contains('=')) return "Invalid.";
|
|
var key = pair[..pair.IndexOf('=')].Trim();
|
|
if (string.IsNullOrEmpty(key)) return "Invalid.";
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public static CookieCollection ParseCookieHeader(string cookieHeader, string domain = "")
|
|
{
|
|
var collection = new CookieCollection();
|
|
|
|
if (string.IsNullOrWhiteSpace(cookieHeader))
|
|
return collection;
|
|
|
|
var cookies = cookieHeader.Split(';', StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
foreach (var cookieStr in cookies)
|
|
{
|
|
var parts = cookieStr.Split('=', 2);
|
|
if (parts.Length != 2) continue;
|
|
|
|
var name = parts[0].Trim();
|
|
var value = parts[1].Trim();
|
|
|
|
var cookie = new Cookie(name, value)
|
|
{
|
|
Path = "/",
|
|
Domain = domain
|
|
};
|
|
collection.Add(cookie);
|
|
}
|
|
|
|
return collection;
|
|
}
|
|
|
|
private async Task BuildClient()
|
|
{
|
|
_isLoading = true;
|
|
ClientChannel = new ClientChannel();
|
|
var clientResult = await YouTubeClient.CreateAsync(ImportCookies, DefaultUserAgent);
|
|
if (clientResult.IsSuccess)
|
|
{
|
|
ClientChannel.YouTubeClient = clientResult.Value;
|
|
}
|
|
|
|
if (ClientChannel.YouTubeClient == null)
|
|
{
|
|
SnackbarService.Add("Failed to get client!", Severity.Error);
|
|
_isLoading = false;
|
|
return;
|
|
}
|
|
|
|
var accountResult = await ClientChannel.YouTubeClient.GetChannelByIdAsync(ClientChannel.YouTubeClient.Id);
|
|
if (accountResult.IsSuccess)
|
|
{
|
|
ClientChannel.Channel = accountResult.Value;
|
|
}
|
|
_isLoading = false;
|
|
await InvokeAsync(StateHasChanged);
|
|
}
|
|
}
|
|
|
|
public enum AccountImportSteps
|
|
{
|
|
Authenticate,
|
|
Validate
|
|
}
|
|
} |