Major refactor #141

Merged
sim0n00ps merged 55 commits from whimsical-c4lic0/OF-DL:refactor-architecture into master 2026-02-13 00:21:58 +00:00
12 changed files with 709 additions and 704 deletions
Showing only changes of commit 04004c7084 - Show all commits

View File

@ -2,8 +2,11 @@ namespace OF_DL.Helpers;
public static class Constants
{
public const string API_URL = "https://onlyfans.com/api2/v2";
public const string ApiUrl = "https://onlyfans.com/api2/v2";
public const int WIDEVINE_RETRY_DELAY = 10;
public const int WIDEVINE_MAX_RETRIES = 3;
public const int ApiPageSize = 50;
public const int WidevineRetryDelay = 10;
public const int WidevineMaxRetries = 3;
}

View File

@ -6,15 +6,15 @@ namespace OF_DL.Helpers;
public static class VersionHelper
{
private const string url = "https://git.ofdl.tools/api/v1/repos/sim0n00ps/OF-DL/releases/latest";
private static readonly HttpClient httpClient = new();
private const string Url = "https://git.ofdl.tools/api/v1/repos/sim0n00ps/OF-DL/releases/latest";
private static readonly HttpClient s_httpClient = new();
public static async Task<string?> GetLatestReleaseTag(CancellationToken cancellationToken = default)
{
Log.Debug("Calling GetLatestReleaseTag");
try
{
HttpResponseMessage response = await httpClient.GetAsync(url, cancellationToken);
HttpResponseMessage response = await s_httpClient.GetAsync(Url, cancellationToken);
if (!response.IsSuccessStatusCode)
{
@ -22,21 +22,20 @@ public static class VersionHelper
return null;
}
string body = await response.Content.ReadAsStringAsync();
string body = await response.Content.ReadAsStringAsync(cancellationToken);
Log.Debug("GetLatestReleaseTag API Response: ");
Log.Debug(body);
Log.Debug("GetLatestReleaseTag API Response: {Body}", body);
LatestReleaseApiResponse? versionCheckResponse =
JsonConvert.DeserializeObject<LatestReleaseApiResponse>(body);
if (versionCheckResponse == null || versionCheckResponse.TagName == "")
if (versionCheckResponse != null && versionCheckResponse.TagName != "")
{
Log.Debug("GetLatestReleaseTag did not return a valid tag name");
return null;
return versionCheckResponse.TagName;
}
return versionCheckResponse.TagName;
Log.Debug("GetLatestReleaseTag did not return a valid tag name");
return null;
}
catch (OperationCanceledException)
{

File diff suppressed because it is too large Load Diff

View File

@ -572,11 +572,13 @@ public class DbService(IConfigService configService) : IDbService
while (await reader.ReadAsync())
{
if (reader["name"].ToString() == "record_created_at")
if (reader["name"].ToString() != "record_created_at")
{
columnExists = true;
break;
continue;
}
columnExists = true;
break;
}
if (!columnExists)

View File

@ -18,10 +18,10 @@ public class DownloadOrchestrationService(
/// <summary>
/// Gets the list of paid post media IDs to avoid duplicates.
/// </summary>
public List<long> PaidPostIds { get; } = new();
public List<long> PaidPostIds { get; } = [];
/// <summary>
/// Retrieves the available users and lists based on current configuration.
/// Retrieves the available users and lists based on the current configuration.
/// </summary>
/// <returns>A result containing users, lists, and any errors.</returns>
public async Task<UserListResult> GetAvailableUsersAsync()
@ -235,9 +235,9 @@ public class DownloadOrchestrationService(
{
eventHandler.OnMessage("Getting Stories");
Dictionary<long, string>? tempStories = await apiService.GetMedia(MediaType.Stories,
$"/users/{userId}/stories", null, path, PaidPostIds);
$"/users/{userId}/stories", null, path);
if (tempStories != null && tempStories.Count > 0)
if (tempStories is { Count: > 0 })
{
eventHandler.OnContentFound("Stories", tempStories.Count, tempStories.Count);
@ -263,9 +263,9 @@ public class DownloadOrchestrationService(
{
eventHandler.OnMessage("Getting Highlights");
Dictionary<long, string>? tempHighlights = await apiService.GetMedia(MediaType.Highlights,
$"/users/{userId}/stories/highlights", null, path, PaidPostIds);
$"/users/{userId}/stories/highlights", null, path);
if (tempHighlights != null && tempHighlights.Count > 0)
if (tempHighlights is { Count: > 0 })
{
eventHandler.OnContentFound("Highlights", tempHighlights.Count, tempHighlights.Count);

View File

@ -500,15 +500,9 @@ public class DownloadService(
client.DefaultRequestHeaders.Add("User-Agent", auth.UserAgent);
using HttpResponseMessage response = await client.GetAsync(mpdUrl, HttpCompletionOption.ResponseHeadersRead);
if (response.IsSuccessStatusCode)
{
if (response.Content.Headers.LastModified != null)
{
return response.Content.Headers.LastModified.Value.DateTime;
}
}
return DateTime.Now;
return response is { IsSuccessStatusCode: true, Content.Headers.LastModified: not null }
? response.Content.Headers.LastModified.Value.DateTime
: DateTime.Now;
}
/// <summary>
@ -842,7 +836,7 @@ public class DownloadService(
/// <param name="author">Author info.</param>
/// <param name="users">Known users map.</param>
/// <returns>True when the media is newly downloaded.</returns>
public async Task<bool> DownloadMedia(string url, string folder, long mediaId, string apiType,
private async Task<bool> DownloadMedia(string url, string folder, long mediaId, string apiType,
IProgressReporter progressReporter, string path,
string? filenameFormat, object? postInfo, object? postMedia,
object? author, Dictionary<string, long> users)
@ -876,7 +870,7 @@ public class DownloadService(
/// <param name="author">Author info.</param>
/// <param name="users">Known users map.</param>
/// <returns>True when the media is newly downloaded.</returns>
public async Task<bool> DownloadDrmVideo(string policy, string signature, string kvp, string url,
private async Task<bool> DownloadDrmVideo(string policy, string signature, string kvp, string url,
string decryptionKey, string folder, DateTime lastModified, long mediaId, string apiType,
IProgressReporter progressReporter, string path,
string? filenameFormat, object? postInfo, object? postMedia,
@ -1028,7 +1022,7 @@ public class DownloadService(
Log.Debug($"Calling DownloadHighlights - {username}");
Dictionary<long, string>? highlights = await apiService.GetMedia(MediaType.Highlights,
$"/users/{userId}/stories/highlights", null, path, paidPostIds.ToList());
$"/users/{userId}/stories/highlights", null, path);
if (highlights == null || highlights.Count == 0)
{
@ -1091,7 +1085,7 @@ public class DownloadService(
Log.Debug($"Calling DownloadStories - {username}");
Dictionary<long, string>? stories = await apiService.GetMedia(MediaType.Stories, $"/users/{userId}/stories",
null, path, paidPostIds.ToList());
null, path);
if (stories == null || stories.Count == 0)
{

View File

@ -39,8 +39,7 @@ public interface IApiService
/// <summary>
/// Retrieves media URLs for stories or highlights.
/// </summary>
Task<Dictionary<long, string>?> GetMedia(MediaType mediaType, string endpoint, string? username, string folder,
List<long> paidPostIds);
Task<Dictionary<long, string>?> GetMedia(MediaType mediaType, string endpoint, string? username, string folder);
/// <summary>
/// Retrieves paid posts and their media.
@ -125,7 +124,7 @@ public interface IApiService
Task<Dictionary<string, long>?> GetExpiredSubscriptions(string endpoint, bool includeRestrictedSubscriptions);
/// <summary>
/// Retrieves a decryption key via the OFDL fallback service.
/// Retrieves a decryption key via the OF DL fallback service.
/// </summary>
Task<string> GetDecryptionKeyOfdl(Dictionary<string, string> drmHeaders, string licenceUrl, string pssh);
}

View File

@ -11,7 +11,7 @@ public interface IAuthService
Auth? CurrentAuth { get; set; }
/// <summary>
/// Loads authentication data from disk.
/// Loads authentication data from the disk.
/// </summary>
Task<bool> LoadFromFileAsync(string filePath = "auth.json");

View File

@ -20,23 +20,6 @@ public interface IDownloadService
Task<bool> ProcessMediaDownload(string folder, long mediaId, string apiType, string url, string path,
string serverFileName, string resolvedFileName, string extension, IProgressReporter progressReporter);
/// <summary>
/// Downloads a single media item.
/// </summary>
Task<bool> DownloadMedia(string url, string folder, long mediaId, string apiType,
IProgressReporter progressReporter, string path,
string? filenameFormat, object? postInfo, object? postMedia,
object? author, Dictionary<string, long> users);
/// <summary>
/// Downloads a DRM-protected video.
/// </summary>
Task<bool> DownloadDrmVideo(string policy, string signature, string kvp, string url,
string decryptionKey, string folder, DateTime lastModified, long mediaId, string apiType,
IProgressReporter progressReporter, string path,
string? filenameFormat, object? postInfo, object? postMedia,
object? author, Dictionary<string, long> users);
/// <summary>
/// Retrieves decryption information for a DRM media item.
/// </summary>

View File

@ -11,10 +11,4 @@ public interface IProgressReporter
/// </summary>
/// <param name="increment">The amount to increment progress by</param>
void ReportProgress(long increment);
/// <summary>
/// Reports a status message (optional for implementations).
/// </summary>
/// <param name="message">The status message to report</param>
void ReportStatus(string message);
}

View File

@ -111,13 +111,13 @@ internal class HttpUtil
int retryCount = 0;
while (retryCount < Constants.WIDEVINE_MAX_RETRIES && response.StatusCode == HttpStatusCode.TooManyRequests)
while (retryCount < Constants.WidevineMaxRetries && response.StatusCode == HttpStatusCode.TooManyRequests)
{
//
// We've hit a rate limit, so we should wait before retrying.
//
int retryAfterSeconds =
Constants.WIDEVINE_RETRY_DELAY * (retryCount + 1); // Default retry time. Increases with each retry.
Constants.WidevineRetryDelay * (retryCount + 1); // Default retry time. Increases with each retry.
if (response.Headers.RetryAfter != null && response.Headers.RetryAfter.Delta.HasValue)
{
if (response.Headers.RetryAfter.Delta.Value.TotalSeconds > 0)

View File

@ -11,10 +11,4 @@ public class SpectreProgressReporter(ProgressTask task) : IProgressReporter
private readonly ProgressTask _task = task ?? throw new ArgumentNullException(nameof(task));
public void ReportProgress(long increment) => _task.Increment(increment);
public void ReportStatus(string message)
{
// Optionally update task description or handle status messages
// For now, we'll leave this empty as the task description is set when creating the progress bar
}
}