FlareSolverr by FlareSolverrSharp

#372
This commit is contained in:
2025-06-17 00:23:38 +02:00
parent dc2c27f4bd
commit e51e90aabc
5 changed files with 92 additions and 16 deletions

View File

@ -11,6 +11,7 @@
<ItemGroup>
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.1.0" />
<PackageReference Include="FlareSolverrSharp" Version="3.0.7" />
<PackageReference Include="HtmlAgilityPack" Version="1.12.0" />
<PackageReference Include="log4net" Version="3.0.4" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="9.0.3" />

View File

@ -1,10 +1,13 @@
using API.MangaDownloadClients;
using System.Net.Http.Headers;
using API.MangaDownloadClients;
using API.Schema;
using API.Schema.Contexts;
using API.Schema.Jobs;
using Asp.Versioning;
using FlareSolverrSharp;
using log4net;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using static Microsoft.AspNetCore.Http.StatusCodes;
@ -291,4 +294,70 @@ public class SettingsController(PgsqlContext context, ILog Log) : Controller
return StatusCode(500, e);
}
}
/// <summary>
/// Sets the FlareSolverr-URL
/// </summary>
/// <param name="flareSolverrUrl">URL of FlareSolverr-Instance</param>
/// <response code="200"></response>
[HttpPost("FlareSolverr/Url")]
[ProducesResponseType(Status200OK)]
public IActionResult SetFlareSolverrUrl([FromBody]string flareSolverrUrl)
{
TrangaSettings.UpdateFlareSolverrUrl(flareSolverrUrl);
return Ok();
}
/// <summary>
/// Resets the FlareSolverr-URL (HttpClient does not use FlareSolverr anymore)
/// </summary>
/// <response code="200"></response>
[HttpDelete("FlareSolverr/Url")]
[ProducesResponseType(Status200OK)]
public IActionResult ClearFlareSolverrUrl()
{
TrangaSettings.UpdateFlareSolverrUrl(string.Empty);
return Ok();
}
/// <summary>
///
/// </summary>
/// <response code="200">FlareSolverr is working!</response>
/// <response code="400">FlareSolverr URL is malformed</response>
/// <response code="500">FlareSolverr is not working</response>
/// <response code="503">FlareSolverr could not be reached</response>
[HttpPost("FlareSolverr/Test")]
[ProducesResponseType(Status200OK)]
[ProducesResponseType(Status400BadRequest)]
[ProducesResponseType(Status500InternalServerError)]
[ProducesResponseType(Status503ServiceUnavailable)]
public IActionResult TestFlareSolverrReachable()
{
const string knownProtectedUrl = "https://prowlarr.servarr.com/v1/ping";
HttpClient client = new();
if (!Uri.TryCreate(new(TrangaSettings.flareSolverrUrl), "v1", out Uri? uri))
return BadRequest();
HttpRequestMessage request = new(HttpMethod.Post, uri);
JObject data = new()
{
["cmd"] = "request.get",
["url"] = knownProtectedUrl
};
request.Content = new StringContent(JsonConvert.SerializeObject(data));
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
HttpResponseMessage response = client.Send(request);
if (!response.IsSuccessStatusCode)
return StatusCode(Status503ServiceUnavailable);
client = new(new ClearanceHandler(TrangaSettings.flareSolverrUrl));
try
{
client.GetStringAsync(knownProtectedUrl).Wait();
return Ok();
}
catch (Exception e)
{
return StatusCode(Status500InternalServerError);
}
}
}

View File

@ -1,27 +1,22 @@
using System.Net;
using FlareSolverrSharp;
using HtmlAgilityPack;
namespace API.MangaDownloadClients;
internal class HttpDownloadClient : DownloadClient
{
private static readonly HttpClient Client = new()
{
Timeout = TimeSpan.FromSeconds(10),
DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher
};
public HttpDownloadClient()
{
if(Client.DefaultRequestHeaders.UserAgent.Count < 1)
Client.DefaultRequestHeaders.UserAgent.ParseAdd(TrangaSettings.userAgent);
}
internal override RequestResult MakeRequestInternal(string url, string? referrer = null, string? clickButton = null)
{
if (clickButton is not null)
Log.Warn("Client can not click button");
HttpResponseMessage? response = null;
HttpClient client = TrangaSettings.flareSolverrUrl == string.Empty
? new ()
: new (new ClearanceHandler(TrangaSettings.flareSolverrUrl));
client.Timeout = TimeSpan.FromSeconds(10);
client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher;
client.DefaultRequestHeaders.Add("User-Agent", TrangaSettings.userAgent);
HttpResponseMessage? response;
Uri uri = new(url);
HttpRequestMessage requestMessage = new(HttpMethod.Get, uri);
if (referrer is not null)
@ -29,7 +24,7 @@ internal class HttpDownloadClient : DownloadClient
Log.Debug($"Requesting {url}");
try
{
response = Client.Send(requestMessage);
response = client.Send(requestMessage);
}
catch (HttpRequestException e)
{

View File

@ -15,6 +15,7 @@ public static class TrangaSettings
public static string userAgent { get; private set; } = DefaultUserAgent;
public static int compression{ get; private set; } = 40;
public static bool bwImages { get; private set; } = false;
public static string flareSolverrUrl { get; private set; } = string.Empty;
/// <summary>
/// Placeholders:
/// %M Manga Name
@ -102,6 +103,12 @@ public static class TrangaSettings
ExportSettings();
}
public static void UpdateFlareSolverrUrl(string url)
{
flareSolverrUrl = url;
ExportSettings();
}
public static void ResetRequestLimits()
{
requestLimits = DefaultRequestLimits;
@ -148,6 +155,7 @@ public static class TrangaSettings
jobj.Add("bwImages", JToken.FromObject(bwImages));
jobj.Add("startNewJobTimeoutMs", JToken.FromObject(startNewJobTimeoutMs));
jobj.Add("chapterNamingScheme", JToken.FromObject(chapterNamingScheme));
jobj.Add("flareSolverrUrl", JToken.FromObject(flareSolverrUrl));
return jobj;
}
@ -174,5 +182,7 @@ public static class TrangaSettings
startNewJobTimeoutMs = snjt.Value<int>()!;
if (jobj.TryGetValue("chapterNamingScheme", out JToken? cns))
chapterNamingScheme = cns.Value<string>()!;
if (jobj.TryGetValue("flareSolverrUrl", out JToken? fsu))
flareSolverrUrl = fsu.Value<string>()!;
}
}

View File

@ -86,12 +86,13 @@ Endpoints are documented in Swagger. Just spin up an instance, and go to `http:/
- .NET
- ASP.NET
- Entity Framework
- Entity Framework Core
- [PostgreSQL](https://www.postgresql.org/about/licence/)
- [Swagger](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/LICENSE)
- [Ngpsql](https://github.com/npgsql/npgsql/blob/main/LICENSE)
- [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json/blob/master/LICENSE.md)
- [PuppeteerSharp](https://github.com/hardkoded/puppeteer-sharp/blob/master/LICENSE)
- [FlareSolverrSharp](https://github.com/FlareSolverr/FlareSolverrSharp)
- [Html Agility Pack (HAP)](https://github.com/zzzprojects/html-agility-pack/blob/master/LICENSE)
- [Soenneker.Utils.String.NeedlemanWunsch](https://github.com/soenneker/soenneker.utils.string.needlemanwunsch/blob/main/LICENSE)
- [Sixlabors.ImageSharp](https://docs-v2.sixlabors.com/articles/imagesharp/index.html#license)