forked from sim0n00ps/OF-DL
Add auth flow status updates to the GUI
This commit is contained in:
parent
603c998ae9
commit
3b8e575a21
@ -73,19 +73,33 @@ public class AuthService(IServiceProvider serviceProvider) : IAuthService
|
|||||||
/// Launches a browser session and extracts auth data after login.
|
/// Launches a browser session and extracts auth data after login.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>True when auth data is captured successfully.</returns>
|
/// <returns>True when auth data is captured successfully.</returns>
|
||||||
public async Task<bool> LoadFromBrowserAsync()
|
public async Task<bool> LoadFromBrowserAsync(Action<string>? statusCallback = null)
|
||||||
{
|
{
|
||||||
|
statusCallback?.Invoke("Preparing browser dependencies ...");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bool runningInDocker = Environment.GetEnvironmentVariable("OFDL_DOCKER") != null;
|
bool runningInDocker = Environment.GetEnvironmentVariable("OFDL_DOCKER") != null;
|
||||||
|
|
||||||
await SetupBrowser(runningInDocker);
|
await SetupBrowser(runningInDocker);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
statusCallback?.Invoke("Failed to prepare browser dependencies.");
|
||||||
|
Log.Error(ex, "Failed to download browser dependencies");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
statusCallback?.Invoke("Please login using the opened Chromium window.");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
CurrentAuth = await GetAuthFromBrowser();
|
CurrentAuth = await GetAuthFromBrowser();
|
||||||
|
|
||||||
return CurrentAuth != null;
|
return CurrentAuth != null;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
statusCallback?.Invoke("Failed to get auth from browser.");
|
||||||
Log.Error(ex, "Failed to load auth from browser");
|
Log.Error(ex, "Failed to load auth from browser");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -107,7 +121,7 @@ public class AuthService(IServiceProvider serviceProvider) : IAuthService
|
|||||||
{
|
{
|
||||||
string json = JsonConvert.SerializeObject(CurrentAuth, Formatting.Indented);
|
string json = JsonConvert.SerializeObject(CurrentAuth, Formatting.Indented);
|
||||||
await File.WriteAllTextAsync(filePath, json);
|
await File.WriteAllTextAsync(filePath, json);
|
||||||
Log.Debug($"Auth saved to file: {filePath}");
|
Log.Debug("Auth saved to file: {FilePath}", filePath);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -115,7 +129,7 @@ public class AuthService(IServiceProvider serviceProvider) : IAuthService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task SetupBrowser(bool runningInDocker)
|
private Task SetupBrowser(bool runningInDocker) => Task.Run(() =>
|
||||||
{
|
{
|
||||||
if (runningInDocker)
|
if (runningInDocker)
|
||||||
{
|
{
|
||||||
@ -134,15 +148,16 @@ public class AuthService(IServiceProvider serviceProvider) : IAuthService
|
|||||||
if (folders.Any())
|
if (folders.Any())
|
||||||
{
|
{
|
||||||
Log.Information("chromium already downloaded. Skipping install step.");
|
Log.Information("chromium already downloaded. Skipping install step.");
|
||||||
return Task.CompletedTask;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int exitCode = Program.Main(["install", "--with-deps", "chromium"]);
|
int exitCode = Program.Main(["install", "--with-deps", "chromium"]);
|
||||||
return exitCode != 0
|
if (exitCode != 0)
|
||||||
? throw new Exception($"Playwright chromium download failed. Exited with code {exitCode}")
|
{
|
||||||
: Task.CompletedTask;
|
throw new Exception($"Playwright chromium download failed. Exited with code {exitCode}");
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
private static async Task<string> GetBcToken(IPage page) =>
|
private static async Task<string> GetBcToken(IPage page) =>
|
||||||
await page.EvaluateAsync<string>("window.localStorage.getItem('bcTokenSha') || ''");
|
await page.EvaluateAsync<string>("window.localStorage.getItem('bcTokenSha') || ''");
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using FFmpeg.NET;
|
using FFmpeg.NET;
|
||||||
|
|||||||
@ -18,7 +18,10 @@ public interface IAuthService
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Launches a browser session and extracts auth data after login.
|
/// Launches a browser session and extracts auth data after login.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Task<bool> LoadFromBrowserAsync();
|
/// <param name="statusCallback">
|
||||||
|
/// Optional callback for reporting status messages to be displayed in the UI.
|
||||||
|
/// </param>
|
||||||
|
Task<bool> LoadFromBrowserAsync(Action<string>? statusCallback = null);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Persists the current auth data to disk.
|
/// Persists the current auth data to disk.
|
||||||
|
|||||||
@ -258,6 +258,9 @@ public partial class MainWindowViewModel(
|
|||||||
|
|
||||||
[ObservableProperty] private string _authScreenMessage = string.Empty;
|
[ObservableProperty] private string _authScreenMessage = string.Empty;
|
||||||
|
|
||||||
|
[ObservableProperty] [NotifyCanExecuteChangedFor(nameof(StartBrowserLoginCommand))]
|
||||||
|
private bool _isBrowserLoginInProgress;
|
||||||
|
|
||||||
[ObservableProperty] private string _errorMessage = string.Empty;
|
[ObservableProperty] private string _errorMessage = string.Empty;
|
||||||
|
|
||||||
private string _actualFfmpegPath = string.Empty;
|
private string _actualFfmpegPath = string.Empty;
|
||||||
@ -676,7 +679,7 @@ public partial class MainWindowViewModel(
|
|||||||
CreatorConfigEditor.AddCreatorCommand.Execute(null);
|
CreatorConfigEditor.AddCreatorCommand.Execute(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand(CanExecute = nameof(CanStartBrowserLogin))]
|
||||||
private async Task StartBrowserLoginAsync()
|
private async Task StartBrowserLoginAsync()
|
||||||
{
|
{
|
||||||
if (configService.CurrentConfig.DisableBrowserAuth)
|
if (configService.CurrentConfig.DisableBrowserAuth)
|
||||||
@ -685,10 +688,29 @@ public partial class MainWindowViewModel(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetLoading("Opening browser for authentication...");
|
IsBrowserLoginInProgress = true;
|
||||||
AppendLog("Starting browser authentication flow.");
|
AppendLog("Starting browser authentication flow.");
|
||||||
|
|
||||||
bool success = await authService.LoadFromBrowserAsync();
|
StartBrowserLoginCommand.NotifyCanExecuteChanged();
|
||||||
|
bool success;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
success = await authService.LoadFromBrowserAsync(message =>
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(message))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthScreenMessage = message;
|
||||||
|
AppendLog(message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
IsBrowserLoginInProgress = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!success || authService.CurrentAuth == null)
|
if (!success || authService.CurrentAuth == null)
|
||||||
{
|
{
|
||||||
AuthScreenMessage =
|
AuthScreenMessage =
|
||||||
@ -963,6 +985,11 @@ public partial class MainWindowViewModel(
|
|||||||
CurrentScreen != AppScreen.Loading &&
|
CurrentScreen != AppScreen.Loading &&
|
||||||
!IsDownloading;
|
!IsDownloading;
|
||||||
|
|
||||||
|
private bool CanStartBrowserLogin() =>
|
||||||
|
CurrentScreen == AppScreen.Auth &&
|
||||||
|
!IsDownloading &&
|
||||||
|
!IsBrowserLoginInProgress;
|
||||||
|
|
||||||
partial void OnCurrentScreenChanged(AppScreen value)
|
partial void OnCurrentScreenChanged(AppScreen value)
|
||||||
{
|
{
|
||||||
OnPropertyChanged(nameof(IsLoadingScreen));
|
OnPropertyChanged(nameof(IsLoadingScreen));
|
||||||
@ -979,6 +1006,7 @@ public partial class MainWindowViewModel(
|
|||||||
RefreshIgnoredUsersListsCommand.NotifyCanExecuteChanged();
|
RefreshIgnoredUsersListsCommand.NotifyCanExecuteChanged();
|
||||||
LogoutCommand.NotifyCanExecuteChanged();
|
LogoutCommand.NotifyCanExecuteChanged();
|
||||||
EditConfigCommand.NotifyCanExecuteChanged();
|
EditConfigCommand.NotifyCanExecuteChanged();
|
||||||
|
StartBrowserLoginCommand.NotifyCanExecuteChanged();
|
||||||
OpenSinglePostOrMessageModalCommand.NotifyCanExecuteChanged();
|
OpenSinglePostOrMessageModalCommand.NotifyCanExecuteChanged();
|
||||||
SubmitSinglePostOrMessageCommand.NotifyCanExecuteChanged();
|
SubmitSinglePostOrMessageCommand.NotifyCanExecuteChanged();
|
||||||
}
|
}
|
||||||
@ -992,6 +1020,7 @@ public partial class MainWindowViewModel(
|
|||||||
RefreshUsersCommand.NotifyCanExecuteChanged();
|
RefreshUsersCommand.NotifyCanExecuteChanged();
|
||||||
RefreshIgnoredUsersListsCommand.NotifyCanExecuteChanged();
|
RefreshIgnoredUsersListsCommand.NotifyCanExecuteChanged();
|
||||||
LogoutCommand.NotifyCanExecuteChanged();
|
LogoutCommand.NotifyCanExecuteChanged();
|
||||||
|
StartBrowserLoginCommand.NotifyCanExecuteChanged();
|
||||||
OpenSinglePostOrMessageModalCommand.NotifyCanExecuteChanged();
|
OpenSinglePostOrMessageModalCommand.NotifyCanExecuteChanged();
|
||||||
SubmitSinglePostOrMessageCommand.NotifyCanExecuteChanged();
|
SubmitSinglePostOrMessageCommand.NotifyCanExecuteChanged();
|
||||||
}
|
}
|
||||||
@ -1425,7 +1454,8 @@ public partial class MainWindowViewModel(
|
|||||||
|
|
||||||
private bool ValidateConfiguredToolPathsOnStartup()
|
private bool ValidateConfiguredToolPathsOnStartup()
|
||||||
{
|
{
|
||||||
IReadOnlyDictionary<string, string> validationErrors = ConfigValidationService.Validate(configService.CurrentConfig);
|
IReadOnlyDictionary<string, string> validationErrors =
|
||||||
|
ConfigValidationService.Validate(configService.CurrentConfig);
|
||||||
bool hasToolPathErrors = false;
|
bool hasToolPathErrors = false;
|
||||||
FfmpegPathError = string.Empty;
|
FfmpegPathError = string.Empty;
|
||||||
FfprobePathError = string.Empty;
|
FfprobePathError = string.Empty;
|
||||||
|
|||||||
@ -46,8 +46,6 @@ public partial class AboutWindow : Window
|
|||||||
private async void OnOpenFfprobeLicenseClick(object? sender, RoutedEventArgs e) =>
|
private async void OnOpenFfprobeLicenseClick(object? sender, RoutedEventArgs e) =>
|
||||||
await OpenExternalUrlAsync(FfprobeLicenseUrl);
|
await OpenExternalUrlAsync(FfprobeLicenseUrl);
|
||||||
|
|
||||||
private void OnCloseClick(object? sender, RoutedEventArgs e) => Close();
|
|
||||||
|
|
||||||
private async Task OpenExternalUrlAsync(string url)
|
private async Task OpenExternalUrlAsync(string url)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@ -61,10 +61,6 @@ public partial class FaqWindow : Window
|
|||||||
|
|
||||||
public ObservableCollection<FaqEntry> Entries { get; } = [];
|
public ObservableCollection<FaqEntry> Entries { get; } = [];
|
||||||
|
|
||||||
public string RuntimeSummary { get; private set; } = string.Empty;
|
|
||||||
|
|
||||||
private void OnCloseClick(object? sender, RoutedEventArgs e) => Close();
|
|
||||||
|
|
||||||
private void BuildEntries()
|
private void BuildEntries()
|
||||||
{
|
{
|
||||||
Entries.Clear();
|
Entries.Clear();
|
||||||
|
|||||||
@ -994,6 +994,7 @@
|
|||||||
<StackPanel Orientation="Horizontal" Spacing="10" HorizontalAlignment="Center">
|
<StackPanel Orientation="Horizontal" Spacing="10" HorizontalAlignment="Center">
|
||||||
<Button Content="Login with Browser"
|
<Button Content="Login with Browser"
|
||||||
Classes="primary"
|
Classes="primary"
|
||||||
|
IsEnabled="{Binding !IsBrowserLoginInProgress}"
|
||||||
Command="{Binding StartBrowserLoginCommand}" />
|
Command="{Binding StartBrowserLoginCommand}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|||||||
@ -515,7 +515,7 @@ public class ApiServiceTests
|
|||||||
MethodInfo method = typeof(ApiService).GetMethod("TryGetDrmInfo",
|
MethodInfo method = typeof(ApiService).GetMethod("TryGetDrmInfo",
|
||||||
BindingFlags.NonPublic | BindingFlags.Static)
|
BindingFlags.NonPublic | BindingFlags.Static)
|
||||||
?? throw new InvalidOperationException("TryGetDrmInfo not found.");
|
?? throw new InvalidOperationException("TryGetDrmInfo not found.");
|
||||||
object?[] args = { files, null, null, null, null };
|
object?[] args = [files, null, null, null, null];
|
||||||
bool result = (bool)method.Invoke(null, args)!;
|
bool result = (bool)method.Invoke(null, args)!;
|
||||||
manifestDash = (string)args[1]!;
|
manifestDash = (string)args[1]!;
|
||||||
cloudFrontPolicy = (string)args[2]!;
|
cloudFrontPolicy = (string)args[2]!;
|
||||||
|
|||||||
@ -82,9 +82,10 @@ public class DownloadServiceTests
|
|||||||
DownloadService service =
|
DownloadService service =
|
||||||
CreateService(new FakeConfigService(new Config()), new MediaTrackingDbService(), apiService);
|
CreateService(new FakeConfigService(new Config()), new MediaTrackingDbService(), apiService);
|
||||||
|
|
||||||
(string decryptionKey, DateTime lastModified, double? mpdDurationSeconds)? result = await service.GetDecryptionInfo(
|
(string decryptionKey, DateTime lastModified, double? mpdDurationSeconds)? result =
|
||||||
"https://example.com/file.mpd", "policy", "signature", "kvp", "1", "2", "post",
|
await service.GetDecryptionInfo(
|
||||||
true, false);
|
"https://example.com/file.mpd", "policy", "signature", "kvp", "1", "2", "post",
|
||||||
|
true, false);
|
||||||
|
|
||||||
Assert.NotNull(result);
|
Assert.NotNull(result);
|
||||||
Assert.Equal("ofdl-key", result.Value.decryptionKey);
|
Assert.Equal("ofdl-key", result.Value.decryptionKey);
|
||||||
@ -100,9 +101,10 @@ public class DownloadServiceTests
|
|||||||
DownloadService service =
|
DownloadService service =
|
||||||
CreateService(new FakeConfigService(new Config()), new MediaTrackingDbService(), apiService);
|
CreateService(new FakeConfigService(new Config()), new MediaTrackingDbService(), apiService);
|
||||||
|
|
||||||
(string decryptionKey, DateTime lastModified, double? mpdDurationSeconds)? result = await service.GetDecryptionInfo(
|
(string decryptionKey, DateTime lastModified, double? mpdDurationSeconds)? result =
|
||||||
"https://example.com/file.mpd", "policy", "signature", "kvp", "1", "2", "post",
|
await service.GetDecryptionInfo(
|
||||||
false, false);
|
"https://example.com/file.mpd", "policy", "signature", "kvp", "1", "2", "post",
|
||||||
|
false, false);
|
||||||
|
|
||||||
Assert.NotNull(result);
|
Assert.NotNull(result);
|
||||||
Assert.Equal("cdm-key", result.Value.decryptionKey);
|
Assert.Equal("cdm-key", result.Value.decryptionKey);
|
||||||
@ -124,7 +126,8 @@ public class DownloadServiceTests
|
|||||||
await File.WriteAllTextAsync(tempFilename, "abc");
|
await File.WriteAllTextAsync(tempFilename, "abc");
|
||||||
|
|
||||||
MediaTrackingDbService dbService = new();
|
MediaTrackingDbService dbService = new();
|
||||||
DownloadService service = CreateService(new FakeConfigService(new Config { ShowScrapeSize = false }), dbService);
|
DownloadService service =
|
||||||
|
CreateService(new FakeConfigService(new Config { ShowScrapeSize = false }), dbService);
|
||||||
ProgressRecorder progress = new();
|
ProgressRecorder progress = new();
|
||||||
|
|
||||||
MethodInfo? finalizeMethod = typeof(DownloadService).GetMethod("FinalizeDrmDownload",
|
MethodInfo? finalizeMethod = typeof(DownloadService).GetMethod("FinalizeDrmDownload",
|
||||||
@ -136,7 +139,7 @@ public class DownloadServiceTests
|
|||||||
tempFilename, DateTime.UtcNow, folder, path, customFileName, filename, 1L, "Posts", progress
|
tempFilename, DateTime.UtcNow, folder, path, customFileName, filename, 1L, "Posts", progress
|
||||||
]);
|
]);
|
||||||
|
|
||||||
bool result = await Assert.IsType<Task<bool>>(resultObject!);
|
bool result = await Assert.IsType<Task<bool>>(resultObject);
|
||||||
Assert.True(result);
|
Assert.True(result);
|
||||||
Assert.True(File.Exists(tempFilename));
|
Assert.True(File.Exists(tempFilename));
|
||||||
Assert.NotNull(dbService.LastUpdateMedia);
|
Assert.NotNull(dbService.LastUpdateMedia);
|
||||||
|
|||||||
@ -145,36 +145,45 @@ internal sealed class StaticApiService : IApiService
|
|||||||
|
|
||||||
public Task<List<string>?> GetListUsers(string endpoint) => throw new NotImplementedException();
|
public Task<List<string>?> GetListUsers(string endpoint) => throw new NotImplementedException();
|
||||||
|
|
||||||
public Task<OF_DL.Models.Entities.Purchased.PaidPostCollection> GetPaidPosts(string endpoint, string folder,
|
public Task<PurchasedEntities.PaidPostCollection> GetPaidPosts(string endpoint, string folder,
|
||||||
string username, List<long> paidPostIds, IStatusReporter statusReporter, CancellationToken cancellationToken = default) =>
|
string username, List<long> paidPostIds, IStatusReporter statusReporter,
|
||||||
|
CancellationToken cancellationToken = default) =>
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|
||||||
public Task<OF_DL.Models.Entities.Posts.PostCollection> GetPosts(string endpoint, string folder,
|
public Task<PostEntities.PostCollection> GetPosts(string endpoint, string folder,
|
||||||
List<long> paidPostIds, IStatusReporter statusReporter, CancellationToken cancellationToken = default) => throw new NotImplementedException();
|
List<long> paidPostIds, IStatusReporter statusReporter, CancellationToken cancellationToken = default) =>
|
||||||
|
|
||||||
public Task<OF_DL.Models.Entities.Posts.SinglePostCollection> GetPost(string endpoint, string folder, CancellationToken cancellationToken = default) =>
|
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|
||||||
public Task<OF_DL.Models.Entities.Streams.StreamsCollection> GetStreams(string endpoint, string folder,
|
public Task<PostEntities.SinglePostCollection> GetPost(string endpoint, string folder,
|
||||||
List<long> paidPostIds, IStatusReporter statusReporter, CancellationToken cancellationToken = default) => throw new NotImplementedException();
|
CancellationToken cancellationToken = default) =>
|
||||||
|
throw new NotImplementedException();
|
||||||
|
|
||||||
public Task<OF_DL.Models.Entities.Archived.ArchivedCollection> GetArchived(string endpoint, string folder,
|
public Task<StreamEntities.StreamsCollection> GetStreams(string endpoint, string folder,
|
||||||
IStatusReporter statusReporter, CancellationToken cancellationToken = default) => throw new NotImplementedException();
|
List<long> paidPostIds, IStatusReporter statusReporter, CancellationToken cancellationToken = default) =>
|
||||||
|
throw new NotImplementedException();
|
||||||
|
|
||||||
public Task<OF_DL.Models.Entities.Messages.MessageCollection> GetMessages(string endpoint, string folder,
|
public Task<ArchivedEntities.ArchivedCollection> GetArchived(string endpoint, string folder,
|
||||||
IStatusReporter statusReporter, CancellationToken cancellationToken = default) => throw new NotImplementedException();
|
IStatusReporter statusReporter, CancellationToken cancellationToken = default) =>
|
||||||
|
throw new NotImplementedException();
|
||||||
|
|
||||||
public Task<OF_DL.Models.Entities.Purchased.PaidMessageCollection> GetPaidMessages(string endpoint,
|
public Task<MessageEntities.MessageCollection> GetMessages(string endpoint, string folder,
|
||||||
string folder, string username, IStatusReporter statusReporter, CancellationToken cancellationToken = default) => throw new NotImplementedException();
|
IStatusReporter statusReporter, CancellationToken cancellationToken = default) =>
|
||||||
|
throw new NotImplementedException();
|
||||||
|
|
||||||
public Task<OF_DL.Models.Entities.Purchased.SinglePaidMessageCollection> GetPaidMessage(string endpoint,
|
public Task<PurchasedEntities.PaidMessageCollection> GetPaidMessages(string endpoint,
|
||||||
|
string folder, string username, IStatusReporter statusReporter,
|
||||||
|
CancellationToken cancellationToken = default) => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public Task<PurchasedEntities.SinglePaidMessageCollection> GetPaidMessage(string endpoint,
|
||||||
string folder, CancellationToken cancellationToken = default) => throw new NotImplementedException();
|
string folder, CancellationToken cancellationToken = default) => throw new NotImplementedException();
|
||||||
|
|
||||||
public Task<Dictionary<string, long>> GetPurchasedTabUsers(string endpoint, Dictionary<string, long> users, CancellationToken cancellationToken = default) =>
|
public Task<Dictionary<string, long>> GetPurchasedTabUsers(string endpoint, Dictionary<string, long> users,
|
||||||
|
CancellationToken cancellationToken = default) =>
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|
||||||
public Task<List<OF_DL.Models.Entities.Purchased.PurchasedTabCollection>> GetPurchasedTab(string endpoint,
|
public Task<List<PurchasedEntities.PurchasedTabCollection>> GetPurchasedTab(string endpoint,
|
||||||
string folder, Dictionary<string, long> users, CancellationToken cancellationToken = default) => throw new NotImplementedException();
|
string folder, Dictionary<string, long> users, CancellationToken cancellationToken = default) =>
|
||||||
|
throw new NotImplementedException();
|
||||||
|
|
||||||
public Task<UserEntities.User?> GetUserInfo(string endpoint, CancellationToken cancellationToken = default) =>
|
public Task<UserEntities.User?> GetUserInfo(string endpoint, CancellationToken cancellationToken = default) =>
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
@ -222,10 +231,12 @@ internal sealed class ConfigurableApiService : IApiService
|
|||||||
MediaHandler?.Invoke(mediaType, endpoint, username, folder) ??
|
MediaHandler?.Invoke(mediaType, endpoint, username, folder) ??
|
||||||
Task.FromResult<Dictionary<long, string>?>(null);
|
Task.FromResult<Dictionary<long, string>?>(null);
|
||||||
|
|
||||||
public Task<PostEntities.SinglePostCollection> GetPost(string endpoint, string folder, CancellationToken cancellationToken = default) =>
|
public Task<PostEntities.SinglePostCollection> GetPost(string endpoint, string folder,
|
||||||
|
CancellationToken cancellationToken = default) =>
|
||||||
PostHandler?.Invoke(endpoint, folder) ?? Task.FromResult(new PostEntities.SinglePostCollection());
|
PostHandler?.Invoke(endpoint, folder) ?? Task.FromResult(new PostEntities.SinglePostCollection());
|
||||||
|
|
||||||
public Task<PurchasedEntities.SinglePaidMessageCollection> GetPaidMessage(string endpoint, string folder, CancellationToken cancellationToken = default) =>
|
public Task<PurchasedEntities.SinglePaidMessageCollection> GetPaidMessage(string endpoint, string folder,
|
||||||
|
CancellationToken cancellationToken = default) =>
|
||||||
PaidMessageHandler?.Invoke(endpoint, folder) ??
|
PaidMessageHandler?.Invoke(endpoint, folder) ??
|
||||||
Task.FromResult(new PurchasedEntities.SinglePaidMessageCollection());
|
Task.FromResult(new PurchasedEntities.SinglePaidMessageCollection());
|
||||||
|
|
||||||
@ -259,7 +270,8 @@ internal sealed class ConfigurableApiService : IApiService
|
|||||||
string username, IStatusReporter statusReporter, CancellationToken cancellationToken = default) =>
|
string username, IStatusReporter statusReporter, CancellationToken cancellationToken = default) =>
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|
||||||
public Task<Dictionary<string, long>> GetPurchasedTabUsers(string endpoint, Dictionary<string, long> users, CancellationToken cancellationToken = default) =>
|
public Task<Dictionary<string, long>> GetPurchasedTabUsers(string endpoint, Dictionary<string, long> users,
|
||||||
|
CancellationToken cancellationToken = default) =>
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|
||||||
public Task<List<PurchasedEntities.PurchasedTabCollection>> GetPurchasedTab(string endpoint, string folder,
|
public Task<List<PurchasedEntities.PurchasedTabCollection>> GetPurchasedTab(string endpoint, string folder,
|
||||||
@ -295,7 +307,8 @@ internal sealed class OrchestrationDownloadServiceStub : IDownloadService
|
|||||||
string serverFileName, string resolvedFileName, string extension, IProgressReporter progressReporter) =>
|
string serverFileName, string resolvedFileName, string extension, IProgressReporter progressReporter) =>
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|
||||||
public Task<(string decryptionKey, DateTime lastModified, double? mpdDurationSeconds)?> GetDecryptionInfo(string mpdUrl, string policy,
|
public Task<(string decryptionKey, DateTime lastModified, double? mpdDurationSeconds)?> GetDecryptionInfo(
|
||||||
|
string mpdUrl, string policy,
|
||||||
string signature, string kvp, string mediaId, string contentId, string drmType, bool clientIdBlobMissing,
|
string signature, string kvp, string mediaId, string contentId, string drmType, bool clientIdBlobMissing,
|
||||||
bool devicePrivateKeyMissing) =>
|
bool devicePrivateKeyMissing) =>
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
@ -459,14 +472,9 @@ internal sealed class RecordingDownloadEventHandler : IDownloadEventHandler
|
|||||||
public void OnMessage(string message) => Messages.Add(message);
|
public void OnMessage(string message) => Messages.Add(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class RecordingStatusReporter : IStatusReporter
|
internal sealed class RecordingStatusReporter(string initialStatus) : IStatusReporter
|
||||||
{
|
{
|
||||||
private readonly List<string> _statuses;
|
private readonly List<string> _statuses = [initialStatus];
|
||||||
|
|
||||||
public RecordingStatusReporter(string initialStatus)
|
|
||||||
{
|
|
||||||
_statuses = [initialStatus];
|
|
||||||
}
|
|
||||||
|
|
||||||
public IReadOnlyList<string> Statuses => _statuses;
|
public IReadOnlyList<string> Statuses => _statuses;
|
||||||
|
|
||||||
@ -489,7 +497,8 @@ internal sealed class FakeAuthService : IAuthService
|
|||||||
|
|
||||||
public Task<bool> LoadFromFileAsync(string filePath = "auth.json") => throw new NotImplementedException();
|
public Task<bool> LoadFromFileAsync(string filePath = "auth.json") => throw new NotImplementedException();
|
||||||
|
|
||||||
public Task<bool> LoadFromBrowserAsync() => throw new NotImplementedException();
|
public Task<bool> LoadFromBrowserAsync(Action<string>? dependencyStatusCallback = null) =>
|
||||||
|
throw new NotImplementedException();
|
||||||
|
|
||||||
public Task SaveToFileAsync(string filePath = "auth.json") => throw new NotImplementedException();
|
public Task SaveToFileAsync(string filePath = "auth.json") => throw new NotImplementedException();
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user