Compare commits

...

8 Commits

5 changed files with 157 additions and 52 deletions

View File

@ -31,6 +31,8 @@ public class APIHelper : IAPIHelper
private readonly Auth auth;
private static DateTime? cachedDynamicRulesExpiration;
private static DynamicRules? cachedDynamicRules;
private const int MaxAttempts = 30;
private const int DelayBetweenAttempts = 3000;
static APIHelper()
{
@ -2674,13 +2676,10 @@ public class APIHelper : IAPIHelper
return DateTime.Now;
}
public async Task<string> GetDecryptionKeyCDRMProject(Dictionary<string, string> drmHeaders, string licenceURL, string pssh)
{
Log.Debug("Calling GetDecryptionKey");
const int maxAttempts = 30;
const int delayBetweenAttempts = 3000;
int attempt = 0;
try
@ -2701,7 +2700,7 @@ public class APIHelper : IAPIHelper
Log.Debug($"Posting to CDRM Project: {json}");
while (attempt < maxAttempts)
while (attempt < MaxAttempts)
{
attempt++;
@ -2727,19 +2726,19 @@ public class APIHelper : IAPIHelper
}
else
{
Log.Debug($"CDRM response status not successful. Retrying... Attempt {attempt} of {maxAttempts}");
if (attempt < maxAttempts)
Log.Debug($"CDRM response status not successful. Retrying... Attempt {attempt} of {MaxAttempts}");
if (attempt < MaxAttempts)
{
await Task.Delay(delayBetweenAttempts);
await Task.Delay(DelayBetweenAttempts);
}
}
}
else
{
Log.Debug($"Status not in CDRM response. Retrying... Attempt {attempt} of {maxAttempts}");
if (attempt < maxAttempts)
Log.Debug($"Status not in CDRM response. Retrying... Attempt {attempt} of {MaxAttempts}");
if (attempt < MaxAttempts)
{
await Task.Delay(delayBetweenAttempts);
await Task.Delay(DelayBetweenAttempts);
}
}
}
@ -2764,11 +2763,10 @@ public class APIHelper : IAPIHelper
{
Log.Debug("Calling GetDecryptionOFDL");
try
{
string dcValue = string.Empty;
HttpClient client = new();
int attempt = 0;
OFDLRequest ofdlRequest = new OFDLRequest
{
@ -2781,6 +2779,10 @@ public class APIHelper : IAPIHelper
Log.Debug($"Posting to ofdl.tools: {json}");
while (attempt < MaxAttempts)
{
attempt++;
HttpRequestMessage request = new(HttpMethod.Post, "https://ofdl.tools/WV")
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
@ -2788,10 +2790,16 @@ public class APIHelper : IAPIHelper
using var response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
if (!response.IsSuccessStatusCode)
continue;
string body = await response.Content.ReadAsStringAsync();
if (!body.TrimStart().StartsWith('{'))
return body;
Log.Debug($"Received JSON object instead of string. Retrying... Attempt {attempt} of {MaxAttempts}");
await Task.Delay(DelayBetweenAttempts);
}
}
catch (Exception ex)
@ -2805,6 +2813,7 @@ public class APIHelper : IAPIHelper
Log.Error("Inner Exception: {0}\n\nStackTrace: {1}", ex.InnerException.Message, ex.InnerException.StackTrace);
}
}
return null;
}

View File

@ -6,14 +6,15 @@ namespace OF_DL.Helpers;
public static class VersionHelper
{
public static string? GetLatestReleaseTag()
private static readonly HttpClient httpClient = new HttpClient();
private const string url = "https://git.ofdl.tools/api/v1/repos/sim0n00ps/OF-DL/releases/latest";
public static async Task<string?> GetLatestReleaseTag(CancellationToken cancellationToken = default)
{
Log.Debug("Calling GetLatestReleaseTag");
try
{
HttpClient client = new();
HttpRequestMessage request = new(HttpMethod.Get, "https://git.ofdl.tools/api/v1/repos/sim0n00ps/OF-DL/releases/latest");
using var response = client.Send(request);
var response = await httpClient.GetAsync(url, cancellationToken);
if (!response.IsSuccessStatusCode)
{
@ -21,7 +22,7 @@ public static class VersionHelper
return null;
}
var body = response.Content.ReadAsStringAsync().Result;
var body = await response.Content.ReadAsStringAsync();
Log.Debug("GetLatestReleaseTag API Response: ");
Log.Debug(body);
@ -36,6 +37,10 @@ public static class VersionHelper
return versionCheckResponse.TagName;
}
catch (OperationCanceledException)
{
throw; // Rethrow timeout exceptions to be handled by the caller
}
catch (Exception ex)
{
Console.WriteLine("Exception caught: {0}\n\nStackTrace: {1}", ex.Message, ex.StackTrace);

View File

@ -526,7 +526,21 @@ public class Program
// Only run the version check if not in DEBUG mode
#if !DEBUG
Version localVersion = Assembly.GetEntryAssembly()?.GetName().Version; //Only tested with numeric values.
String? latestReleaseTag = VersionHelper.GetLatestReleaseTag();
// Create a cancellation token with 30 second timeout
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
String? latestReleaseTag = null;
try
{
latestReleaseTag = await VersionHelper.GetLatestReleaseTag(cts.Token);
}
catch (OperationCanceledException)
{
AnsiConsole.Markup("[yellow]Version check timed out after 30 seconds.\n[/]");
Log.Warning("Version check timed out after 30 seconds");
latestReleaseTag = null;
}
if (latestReleaseTag == null)
{
@ -543,7 +557,7 @@ public class Program
{
// The version on GitHub is more up to date than this local release.
AnsiConsole.Markup("[red]You are running OF-DL version " + $"{localVersion.Major}.{localVersion.Minor}.{localVersion.Build}\n[/]");
AnsiConsole.Markup("[red]Please update to the current release, " + $"{latestGiteaRelease.Major}.{latestGiteaRelease.Minor}.{latestGiteaRelease.Build}: [link]https://git.ofdl.tools/sim0n00ps/OF-DL/releases[/]\n[/]");
AnsiConsole.Markup("[red]Please update to the current release, " + $"{latestGiteaRelease.Major}.{latestGiteaRelease.Minor}.{latestGiteaRelease.Build}: [link=https://git.ofdl.tools/sim0n00ps/OF-DL/releases]https://git.ofdl.tools/sim0n00ps/OF-DL/releases[/]\n[/]");
Log.Debug("Detected outdated client running version " + $"{localVersion.Major}.{localVersion.Minor}.{localVersion.Build}");
Log.Debug("Latest release version " + $"{latestGiteaRelease.Major}.{latestGiteaRelease.Minor}.{latestGiteaRelease.Build}");
}
@ -748,6 +762,61 @@ public class Program
{
config.FFmpegPath = config.FFmpegPath.Replace(@"\", @"\\");
}
// Get FFmpeg version
try
{
var processStartInfo = new System.Diagnostics.ProcessStartInfo
{
FileName = config.FFmpegPath,
Arguments = "-version",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
using (var process = System.Diagnostics.Process.Start(processStartInfo))
{
if (process != null)
{
string output = await process.StandardOutput.ReadToEndAsync();
await process.WaitForExitAsync();
// Log full output
Log.Information("FFmpeg version output:\n{Output}", output);
// Parse first line for console output
string firstLine = output.Split('\n')[0].Trim();
if (firstLine.StartsWith("ffmpeg version"))
{
// Extract version string (text between "ffmpeg version " and " Copyright")
int versionStart = "ffmpeg version ".Length;
int copyrightIndex = firstLine.IndexOf(" Copyright");
if (copyrightIndex > versionStart)
{
string version = firstLine.Substring(versionStart, copyrightIndex - versionStart);
AnsiConsole.Markup($"[green]ffmpeg version detected as {version}[/]\n");
}
else
{
// Fallback if Copyright not found
string version = firstLine.Substring(versionStart);
AnsiConsole.Markup($"[green]ffmpeg version detected as {version}[/]\n");
}
}
else
{
AnsiConsole.Markup($"[yellow]ffmpeg version could not be parsed[/]\n");
}
}
}
}
catch (Exception ex)
{
Log.Warning(ex, "Failed to get FFmpeg version");
AnsiConsole.Markup($"[yellow]Could not retrieve ffmpeg version[/]\n");
}
}
else
{

View File

@ -516,3 +516,23 @@ Allowed values: Any positive integer or `-1`
Description: You won't need to set this, but if you see errors about the configured timeout of 100 seconds elapsing then
you could set this to be more than 100. It is recommended that you leave this as the default value.
## DisableTextSanitization
Type: `boolean`
Default: `false`
Allowed values: `true`, `false`
Description: When enabled, post/message text is stored as-is without XML stripping.
## DownloadVideoResolution
Type: `string`
Default: `"source"`
Allowed values: `"source"`, `"240"`, `"720"`
Description: This allows you to download videos in alternative resolutions, by default videos are downloaded in source resolution but some people prefer smoother videos at a lower resolution.

View File

@ -20,6 +20,8 @@ information about what it does, its default value, and the allowed values.
- [DownloadDateSelection](/config/all-configuration-options#downloaddateselection)
- [CustomDate](/config/all-configuration-options#customdate)
- [ShowScrapeSize](/config/all-configuration-options#showscrapesize)
- [DisableTextSanitization](/config/all-configuration-options#disabletextsanitization)
- [DownloadVideoResolution](/config/all-configuration-options#downloadvideoresolution)
- Media
- [DownloadAvatarHeaderPhoto](/config/all-configuration-options#downloadavatarheaderphoto)
- [DownloadPaidPosts](/config/all-configuration-options#downloadpaidposts)