forked from sim0n00ps/OF-DL
527 lines
25 KiB
C#
527 lines
25 KiB
C#
using Newtonsoft.Json.Linq;
|
|
using OF_DL.Enumerations;
|
|
using OF_DL.Models;
|
|
using OF_DL.Models.Config;
|
|
using OF_DL.Models.Downloads;
|
|
using OF_DL.Services;
|
|
using Serilog.Core;
|
|
using Serilog.Events;
|
|
using ArchivedEntities = OF_DL.Models.Entities.Archived;
|
|
using MessageEntities = OF_DL.Models.Entities.Messages;
|
|
using PostEntities = OF_DL.Models.Entities.Posts;
|
|
using PurchasedEntities = OF_DL.Models.Entities.Purchased;
|
|
using StreamEntities = OF_DL.Models.Entities.Streams;
|
|
using UserEntities = OF_DL.Models.Entities.Users;
|
|
|
|
namespace OF_DL.Tests.Services;
|
|
|
|
internal sealed class TempFolder : IDisposable
|
|
{
|
|
public TempFolder()
|
|
{
|
|
Path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "ofdl-tests", Guid.NewGuid().ToString("N"));
|
|
Directory.CreateDirectory(Path);
|
|
}
|
|
|
|
public string Path { get; }
|
|
|
|
public void Dispose()
|
|
{
|
|
try
|
|
{
|
|
Directory.Delete(Path, true);
|
|
}
|
|
catch
|
|
{
|
|
// ignored
|
|
}
|
|
}
|
|
}
|
|
|
|
internal sealed class ProgressRecorder : IProgressReporter
|
|
{
|
|
public long Total { get; private set; }
|
|
|
|
public CancellationToken CancellationToken { get; } = CancellationToken.None;
|
|
|
|
public void ReportProgress(long increment) => Total += increment;
|
|
}
|
|
|
|
internal sealed class FakeConfigService(Config config) : IConfigService
|
|
{
|
|
public Config CurrentConfig { get; private set; } = config;
|
|
|
|
public bool IsCliNonInteractive { get; } = config.NonInteractiveMode;
|
|
|
|
public Task<bool> LoadConfigurationAsync(string[] args) => Task.FromResult(true);
|
|
|
|
public Task SaveConfigurationAsync(string filePath = "config.conf") => Task.CompletedTask;
|
|
|
|
public void UpdateConfig(Config newConfig) => CurrentConfig = newConfig;
|
|
|
|
public List<(string Name, bool Value)> GetToggleableProperties() => [];
|
|
|
|
public bool ApplyToggleableSelections(List<string> selectedNames) => false;
|
|
}
|
|
|
|
internal sealed class MediaTrackingDbService : IDbService
|
|
{
|
|
public bool CheckDownloadedResult { get; init; }
|
|
|
|
public long StoredFileSize { get; init; }
|
|
|
|
public (string folder, long mediaId, string apiType, string directory, string filename, long size,
|
|
bool downloaded, DateTime createdAt)? LastUpdateMedia { get; private set; }
|
|
|
|
public Task UpdateMedia(string folder, long mediaId, string apiType, string directory, string filename,
|
|
long size, bool downloaded, DateTime createdAt)
|
|
{
|
|
LastUpdateMedia = (folder, mediaId, apiType, directory, filename, size, downloaded, createdAt);
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public Task<long> GetStoredFileSize(string folder, long mediaId, string apiType) =>
|
|
Task.FromResult(StoredFileSize);
|
|
|
|
public Task<bool> CheckDownloaded(string folder, long mediaId, string apiType) =>
|
|
Task.FromResult(CheckDownloadedResult);
|
|
|
|
public Task AddMessage(string folder, long postId, string messageText, string price, bool isPaid,
|
|
bool isArchived, DateTime createdAt, long userId) => throw new NotImplementedException();
|
|
|
|
public Task AddPost(string folder, long postId, string messageText, string price, bool isPaid, bool isArchived,
|
|
DateTime createdAt) => throw new NotImplementedException();
|
|
|
|
public Task AddStory(string folder, long postId, string messageText, string price, bool isPaid, bool isArchived,
|
|
DateTime createdAt) => throw new NotImplementedException();
|
|
|
|
public Task CreateDb(string folder) => throw new NotImplementedException();
|
|
|
|
public Task CreateUsersDb(Dictionary<string, long> users) => throw new NotImplementedException();
|
|
|
|
public Task CheckUsername(KeyValuePair<string, long> user, string path) => throw new NotImplementedException();
|
|
|
|
public Task AddMedia(string folder, long mediaId, long postId, string link, string? directory,
|
|
string? filename, long? size, string apiType, string mediaType, bool preview, bool downloaded,
|
|
DateTime? createdAt) => throw new NotImplementedException();
|
|
|
|
public Task<DateTime?> GetMostRecentPostDate(string folder) => throw new NotImplementedException();
|
|
}
|
|
|
|
internal sealed class StaticApiService : IApiService
|
|
{
|
|
public Dictionary<long, string>? MediaToReturn { get; init; }
|
|
|
|
public DateTime LastModifiedToReturn { get; set; } = new(2024, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
|
|
|
public bool OfdlCalled { get; private set; }
|
|
|
|
public bool CdmCalled { get; private set; }
|
|
|
|
public Task<(string pssh, DateTime lastModified, double? durationSeconds)> GetDrmMpdInfo(
|
|
string mpdUrl, string policy, string signature, string kvp) =>
|
|
Task.FromResult<(string pssh, DateTime lastModified, double? durationSeconds)>(
|
|
("pssh", LastModifiedToReturn, null));
|
|
|
|
public Task<string> GetDecryptionKeyOfdl(Dictionary<string, string> drmHeaders, string licenceUrl, string pssh)
|
|
{
|
|
OfdlCalled = true;
|
|
return Task.FromResult("ofdl-key");
|
|
}
|
|
|
|
public Task<string> GetDecryptionKeyCdm(Dictionary<string, string> drmHeaders, string licenceUrl, string pssh)
|
|
{
|
|
CdmCalled = true;
|
|
return Task.FromResult("cdm-key");
|
|
}
|
|
|
|
public Dictionary<string, string> GetDynamicHeaders(string path, string queryParam) =>
|
|
new() { { "X-Test", "value" } };
|
|
|
|
public Task<Dictionary<long, string>?> GetMedia(MediaType mediaType, string endpoint, string? username,
|
|
string folder, CancellationToken cancellationToken = default) => Task.FromResult(MediaToReturn);
|
|
|
|
public Task<Dictionary<string, long>?> GetLists(string endpoint) => throw new NotImplementedException();
|
|
|
|
public Task<List<string>?> GetListUsers(string endpoint) => throw new NotImplementedException();
|
|
|
|
public Task<PurchasedEntities.PaidPostCollection> GetPaidPosts(string endpoint, string folder,
|
|
string username, List<long> paidPostIds, IStatusReporter statusReporter,
|
|
CancellationToken cancellationToken = default) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<PostEntities.PostCollection> GetPosts(string endpoint, string folder,
|
|
List<long> paidPostIds, IStatusReporter statusReporter, CancellationToken cancellationToken = default) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<PostEntities.SinglePostCollection> GetPost(string endpoint, string folder,
|
|
CancellationToken cancellationToken = default) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<StreamEntities.StreamsCollection> GetStreams(string endpoint, string folder,
|
|
List<long> paidPostIds, IStatusReporter statusReporter, CancellationToken cancellationToken = default) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<ArchivedEntities.ArchivedCollection> GetArchived(string endpoint, string folder,
|
|
IStatusReporter statusReporter, CancellationToken cancellationToken = default) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<MessageEntities.MessageCollection> GetMessages(string endpoint, string folder,
|
|
IStatusReporter statusReporter, CancellationToken cancellationToken = default) =>
|
|
throw new NotImplementedException();
|
|
|
|
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();
|
|
|
|
public Task<Dictionary<string, long>> GetPurchasedTabUsers(string endpoint, Dictionary<string, long> users,
|
|
CancellationToken cancellationToken = default) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<List<PurchasedEntities.PurchasedTabCollection>> GetPurchasedTab(string endpoint,
|
|
string folder, Dictionary<string, long> users, CancellationToken cancellationToken = default) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<UserEntities.User?> GetUserInfo(string endpoint, CancellationToken cancellationToken = default) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<JObject?> GetUserInfoById(string endpoint) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<Dictionary<string, long>?> GetActiveSubscriptions(string endpoint,
|
|
bool includeRestrictedSubscriptions) => throw new NotImplementedException();
|
|
|
|
public Task<Dictionary<string, long>?> GetExpiredSubscriptions(string endpoint,
|
|
bool includeRestrictedSubscriptions) => throw new NotImplementedException();
|
|
}
|
|
|
|
internal sealed class ConfigurableApiService : IApiService
|
|
{
|
|
public Func<string, bool, Task<Dictionary<string, long>?>>? ActiveSubscriptionsHandler { get; init; }
|
|
public Func<string, bool, Task<Dictionary<string, long>?>>? ExpiredSubscriptionsHandler { get; init; }
|
|
public Func<string, Task<Dictionary<string, long>?>>? ListsHandler { get; init; }
|
|
public Func<string, Task<List<string>?>>? ListUsersHandler { get; init; }
|
|
public Func<MediaType, string, string?, string, Task<Dictionary<long, string>?>>? MediaHandler { get; init; }
|
|
public Func<string, string, Task<PostEntities.SinglePostCollection>>? PostHandler { get; init; }
|
|
public Func<string, string, Task<PurchasedEntities.SinglePaidMessageCollection>>? PaidMessageHandler { get; init; }
|
|
public Func<string, Task<UserEntities.User?>>? UserInfoHandler { get; init; }
|
|
public Func<string, Task<JObject?>>? UserInfoByIdHandler { get; init; }
|
|
|
|
public Task<Dictionary<string, long>?> GetActiveSubscriptions(string endpoint,
|
|
bool includeRestrictedSubscriptions) =>
|
|
ActiveSubscriptionsHandler?.Invoke(endpoint, includeRestrictedSubscriptions) ??
|
|
Task.FromResult<Dictionary<string, long>?>(null);
|
|
|
|
public Task<Dictionary<string, long>?> GetExpiredSubscriptions(string endpoint,
|
|
bool includeRestrictedSubscriptions) =>
|
|
ExpiredSubscriptionsHandler?.Invoke(endpoint, includeRestrictedSubscriptions) ??
|
|
Task.FromResult<Dictionary<string, long>?>(null);
|
|
|
|
public Task<Dictionary<string, long>?> GetLists(string endpoint) =>
|
|
ListsHandler?.Invoke(endpoint) ?? Task.FromResult<Dictionary<string, long>?>(null);
|
|
|
|
public Task<List<string>?> GetListUsers(string endpoint) =>
|
|
ListUsersHandler?.Invoke(endpoint) ?? Task.FromResult<List<string>?>(null);
|
|
|
|
public Task<Dictionary<long, string>?> GetMedia(MediaType mediaType, string endpoint, string? username,
|
|
string folder, CancellationToken cancellationToken = default) =>
|
|
MediaHandler?.Invoke(mediaType, endpoint, username, folder) ??
|
|
Task.FromResult<Dictionary<long, string>?>(null);
|
|
|
|
public Task<PostEntities.SinglePostCollection> GetPost(string endpoint, string folder,
|
|
CancellationToken cancellationToken = default) =>
|
|
PostHandler?.Invoke(endpoint, folder) ?? Task.FromResult(new PostEntities.SinglePostCollection());
|
|
|
|
public Task<PurchasedEntities.SinglePaidMessageCollection> GetPaidMessage(string endpoint, string folder,
|
|
CancellationToken cancellationToken = default) =>
|
|
PaidMessageHandler?.Invoke(endpoint, folder) ??
|
|
Task.FromResult(new PurchasedEntities.SinglePaidMessageCollection());
|
|
|
|
public Task<UserEntities.User?> GetUserInfo(string endpoint, CancellationToken cancellationToken = default) =>
|
|
UserInfoHandler?.Invoke(endpoint) ?? Task.FromResult<UserEntities.User?>(null);
|
|
|
|
public Task<JObject?> GetUserInfoById(string endpoint) =>
|
|
UserInfoByIdHandler?.Invoke(endpoint) ?? Task.FromResult<JObject?>(null);
|
|
|
|
public Task<PurchasedEntities.PaidPostCollection> GetPaidPosts(string endpoint, string folder, string username,
|
|
List<long> paidPostIds, IStatusReporter statusReporter, CancellationToken cancellationToken = default) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<PostEntities.PostCollection> GetPosts(string endpoint, string folder, List<long> paidPostIds,
|
|
IStatusReporter statusReporter, CancellationToken cancellationToken = default) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<StreamEntities.StreamsCollection> GetStreams(string endpoint, string folder, List<long> paidPostIds,
|
|
IStatusReporter statusReporter, CancellationToken cancellationToken = default) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<ArchivedEntities.ArchivedCollection> GetArchived(string endpoint, string folder,
|
|
IStatusReporter statusReporter, CancellationToken cancellationToken = default) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<MessageEntities.MessageCollection> GetMessages(string endpoint, string folder,
|
|
IStatusReporter statusReporter, CancellationToken cancellationToken = default) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<PurchasedEntities.PaidMessageCollection> GetPaidMessages(string endpoint, string folder,
|
|
string username, IStatusReporter statusReporter, CancellationToken cancellationToken = default) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<Dictionary<string, long>> GetPurchasedTabUsers(string endpoint, Dictionary<string, long> users,
|
|
CancellationToken cancellationToken = default) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<List<PurchasedEntities.PurchasedTabCollection>> GetPurchasedTab(string endpoint, string folder,
|
|
Dictionary<string, long> users, CancellationToken cancellationToken = default) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Dictionary<string, string> GetDynamicHeaders(string path, string queryParam) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<string> GetDecryptionKeyCdm(Dictionary<string, string> drmHeaders, string licenceUrl, string pssh) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<(string pssh, DateTime lastModified, double? durationSeconds)> GetDrmMpdInfo(
|
|
string mpdUrl, string policy, string signature, string kvp) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<string> GetDecryptionKeyOfdl(Dictionary<string, string> drmHeaders, string licenceUrl, string pssh) =>
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
internal sealed class OrchestrationDownloadServiceStub : IDownloadService
|
|
{
|
|
public bool SinglePostCalled { get; private set; }
|
|
public bool SinglePaidMessageCalled { get; private set; }
|
|
|
|
public DownloadResult? SinglePostResult { get; init; }
|
|
public DownloadResult? SinglePaidMessageResult { get; init; }
|
|
public DownloadResult? StoriesResult { get; init; }
|
|
|
|
public Task<long> CalculateTotalFileSize(List<string> urls) => Task.FromResult((long)urls.Count);
|
|
|
|
public Task<bool> ProcessMediaDownload(string folder, long mediaId, string apiType, string url, string path,
|
|
string serverFileName, string resolvedFileName, string extension, IProgressReporter progressReporter) =>
|
|
throw new NotImplementedException();
|
|
|
|
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,
|
|
bool devicePrivateKeyMissing) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task DownloadAvatarHeader(string? avatarUrl, string? headerUrl, string folder, string username) =>
|
|
Task.CompletedTask;
|
|
|
|
public Task<DownloadResult> DownloadHighlights(string username, long userId, string path,
|
|
HashSet<long> paidPostIds, IProgressReporter progressReporter) =>
|
|
Task.FromResult(new DownloadResult());
|
|
|
|
public Task<DownloadResult> DownloadStories(string username, long userId, string path,
|
|
HashSet<long> paidPostIds, IProgressReporter progressReporter) =>
|
|
Task.FromResult(StoriesResult ?? new DownloadResult());
|
|
|
|
public Task<DownloadResult> DownloadArchived(string username, long userId, string path,
|
|
Dictionary<string, long> users, bool clientIdBlobMissing, bool devicePrivateKeyMissing,
|
|
ArchivedEntities.ArchivedCollection archived, IProgressReporter progressReporter) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<DownloadResult> DownloadMessages(string username, long userId, string path,
|
|
Dictionary<string, long> users, bool clientIdBlobMissing, bool devicePrivateKeyMissing,
|
|
MessageEntities.MessageCollection messages, IProgressReporter progressReporter) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<DownloadResult> DownloadPaidMessages(string username, string path, Dictionary<string, long> users,
|
|
bool clientIdBlobMissing, bool devicePrivateKeyMissing,
|
|
PurchasedEntities.PaidMessageCollection paidMessageCollection, IProgressReporter progressReporter) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<DownloadResult> DownloadStreams(string username, long userId, string path,
|
|
Dictionary<string, long> users, bool clientIdBlobMissing, bool devicePrivateKeyMissing,
|
|
StreamEntities.StreamsCollection streams, IProgressReporter progressReporter) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<DownloadResult> DownloadFreePosts(string username, long userId, string path,
|
|
Dictionary<string, long> users, bool clientIdBlobMissing, bool devicePrivateKeyMissing,
|
|
PostEntities.PostCollection posts, IProgressReporter progressReporter) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<DownloadResult> DownloadPaidPosts(string username, long userId, string path,
|
|
Dictionary<string, long> users, bool clientIdBlobMissing, bool devicePrivateKeyMissing,
|
|
PurchasedEntities.PaidPostCollection purchasedPosts, IProgressReporter progressReporter) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<DownloadResult> DownloadPaidPostsPurchasedTab(string username, string path,
|
|
Dictionary<string, long> users, bool clientIdBlobMissing, bool devicePrivateKeyMissing,
|
|
PurchasedEntities.PaidPostCollection purchasedPosts, IProgressReporter progressReporter) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<DownloadResult> DownloadPaidMessagesPurchasedTab(string username, string path,
|
|
Dictionary<string, long> users, bool clientIdBlobMissing, bool devicePrivateKeyMissing,
|
|
PurchasedEntities.PaidMessageCollection paidMessageCollection, IProgressReporter progressReporter) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<DownloadResult> DownloadSinglePost(string username, string path, Dictionary<string, long> users,
|
|
bool clientIdBlobMissing, bool devicePrivateKeyMissing, PostEntities.SinglePostCollection post,
|
|
IProgressReporter progressReporter)
|
|
{
|
|
SinglePostCalled = true;
|
|
return Task.FromResult(SinglePostResult ?? new DownloadResult());
|
|
}
|
|
|
|
public Task<DownloadResult> DownloadSinglePaidMessage(string username, string path,
|
|
Dictionary<string, long> users, bool clientIdBlobMissing, bool devicePrivateKeyMissing,
|
|
PurchasedEntities.SinglePaidMessageCollection singlePaidMessageCollection,
|
|
IProgressReporter progressReporter)
|
|
{
|
|
SinglePaidMessageCalled = true;
|
|
return Task.FromResult(SinglePaidMessageResult ?? new DownloadResult());
|
|
}
|
|
}
|
|
|
|
internal sealed class UserTrackingDbService : IDbService
|
|
{
|
|
public Dictionary<string, long>? CreatedUsers { get; private set; }
|
|
public List<string> CreatedDbs { get; } = [];
|
|
public (KeyValuePair<string, long> user, string path)? CheckedUser { get; private set; }
|
|
|
|
public Task CreateDb(string folder)
|
|
{
|
|
CreatedDbs.Add(folder);
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public Task CreateUsersDb(Dictionary<string, long> users)
|
|
{
|
|
CreatedUsers = new Dictionary<string, long>(users);
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public Task CheckUsername(KeyValuePair<string, long> user, string path)
|
|
{
|
|
CheckedUser = (user, path);
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public Task AddMessage(string folder, long postId, string messageText, string price, bool isPaid,
|
|
bool isArchived, DateTime createdAt, long userId) => throw new NotImplementedException();
|
|
|
|
public Task AddPost(string folder, long postId, string messageText, string price, bool isPaid,
|
|
bool isArchived, DateTime createdAt) => throw new NotImplementedException();
|
|
|
|
public Task AddStory(string folder, long postId, string messageText, string price, bool isPaid,
|
|
bool isArchived, DateTime createdAt) => throw new NotImplementedException();
|
|
|
|
public Task AddMedia(string folder, long mediaId, long postId, string link, string? directory,
|
|
string? filename, long? size, string apiType, string mediaType, bool preview, bool downloaded,
|
|
DateTime? createdAt) => throw new NotImplementedException();
|
|
|
|
public Task UpdateMedia(string folder, long mediaId, string apiType, string directory, string filename,
|
|
long size, bool downloaded, DateTime createdAt) => throw new NotImplementedException();
|
|
|
|
public Task<long> GetStoredFileSize(string folder, long mediaId, string apiType) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<bool> CheckDownloaded(string folder, long mediaId, string apiType) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<DateTime?> GetMostRecentPostDate(string folder) => throw new NotImplementedException();
|
|
}
|
|
|
|
internal sealed class RecordingDownloadEventHandler : IDownloadEventHandler
|
|
{
|
|
public List<string> Messages { get; } = [];
|
|
public List<(string contentType, int mediaCount, int objectCount)> ContentFound { get; } = [];
|
|
public List<string> NoContent { get; } = [];
|
|
public List<(string contentType, DownloadResult result)> DownloadCompletes { get; } = [];
|
|
public List<(string description, long maxValue, bool showSize)> ProgressCalls { get; } = [];
|
|
|
|
public CancellationToken CancellationToken { get; } = CancellationToken.None;
|
|
|
|
public Task<T> WithStatusAsync<T>(string statusMessage, Func<IStatusReporter, Task<T>> work) =>
|
|
work(new RecordingStatusReporter(statusMessage));
|
|
|
|
public Task<T> WithProgressAsync<T>(string description, long maxValue, bool showSize,
|
|
Func<IProgressReporter, Task<T>> work)
|
|
{
|
|
ProgressCalls.Add((description, maxValue, showSize));
|
|
return work(new ProgressRecorder());
|
|
}
|
|
|
|
public void OnContentFound(string contentType, int mediaCount, int objectCount) =>
|
|
ContentFound.Add((contentType, mediaCount, objectCount));
|
|
|
|
public void OnNoContentFound(string contentType) => NoContent.Add(contentType);
|
|
|
|
public void OnDownloadComplete(string contentType, DownloadResult result) =>
|
|
DownloadCompletes.Add((contentType, result));
|
|
|
|
public void OnUserStarting(string username) => Messages.Add($"Starting {username}");
|
|
|
|
public void OnUserComplete(string username, CreatorDownloadResult result) =>
|
|
Messages.Add($"Completed {username}");
|
|
|
|
public void OnPurchasedTabUserComplete(string username, int paidPostCount, int paidMessagesCount) =>
|
|
Messages.Add($"Purchased {username}");
|
|
|
|
public void OnScrapeComplete(TimeSpan elapsed) => Messages.Add("Scrape complete");
|
|
|
|
public void OnMessage(string message) => Messages.Add(message);
|
|
}
|
|
|
|
internal sealed class RecordingStatusReporter(string initialStatus) : IStatusReporter
|
|
{
|
|
private readonly List<string> _statuses = [initialStatus];
|
|
|
|
public IReadOnlyList<string> Statuses => _statuses;
|
|
|
|
public void ReportStatus(string message) => _statuses.Add(message);
|
|
}
|
|
|
|
internal sealed class FakeFileNameService : IFileNameService
|
|
{
|
|
public Task<string> BuildFilename(string fileFormat, Dictionary<string, string> values) =>
|
|
throw new NotImplementedException();
|
|
|
|
public Task<Dictionary<string, string>> GetFilename(object info, object media, object author,
|
|
List<string> selectedProperties, string username, Dictionary<string, long>? users = null) =>
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
internal sealed class FakeAuthService : IAuthService
|
|
{
|
|
public Auth? CurrentAuth { get; set; }
|
|
|
|
public Task<bool> LoadFromFileAsync(string filePath = "auth.json") => 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 void ValidateCookieString() => throw new NotImplementedException();
|
|
|
|
public Task<UserEntities.User?> ValidateAuthAsync() => throw new NotImplementedException();
|
|
|
|
public void Logout() => throw new NotImplementedException();
|
|
}
|
|
|
|
internal sealed class FakeLoggingService : ILoggingService
|
|
{
|
|
public LoggingLevelSwitch LevelSwitch { get; } = new();
|
|
public LoggingLevel LastLevel { get; private set; } = LoggingLevel.Error;
|
|
public int UpdateCount { get; private set; }
|
|
|
|
public void UpdateLoggingLevel(LoggingLevel newLevel)
|
|
{
|
|
UpdateCount++;
|
|
LastLevel = newLevel;
|
|
LevelSwitch.MinimumLevel = (LogEventLevel)newLevel;
|
|
}
|
|
|
|
public LoggingLevel GetCurrentLoggingLevel() => (LoggingLevel)LevelSwitch.MinimumLevel;
|
|
}
|