mirror of
https://github.com/C9Glax/tranga.git
synced 2025-09-10 20:08:19 +02:00
Compare commits
2 Commits
dc2c27f4bd
...
24f68b4a8e
Author | SHA1 | Date | |
---|---|---|---|
24f68b4a8e | |||
e51e90aabc |
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.1.0" />
|
<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="HtmlAgilityPack" Version="1.12.0" />
|
||||||
<PackageReference Include="log4net" Version="3.0.4" />
|
<PackageReference Include="log4net" Version="3.0.4" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="9.0.3" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="9.0.3" />
|
||||||
|
@@ -78,12 +78,11 @@ public class SearchController(PgsqlContext context, ILog Log) : Controller
|
|||||||
/// <param name="url">Manga-Page URL</param>
|
/// <param name="url">Manga-Page URL</param>
|
||||||
/// <response code="200"></response>
|
/// <response code="200"></response>
|
||||||
/// <response code="300">Multiple connectors found for URL</response>
|
/// <response code="300">Multiple connectors found for URL</response>
|
||||||
/// <response code="400">No Manga at URL</response>
|
/// <response code="404">Manga not found</response>
|
||||||
/// <response code="404">No connector found for URL</response>
|
|
||||||
/// <response code="500">Error during Database Operation</response>
|
/// <response code="500">Error during Database Operation</response>
|
||||||
[HttpPost("Url")]
|
[HttpPost("Url")]
|
||||||
[ProducesResponseType<Manga>(Status200OK, "application/json")]
|
[ProducesResponseType<Manga>(Status200OK, "application/json")]
|
||||||
[ProducesResponseType(Status400BadRequest)]
|
[ProducesResponseType(Status404NotFound)]
|
||||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||||
public IActionResult GetMangaFromUrl([FromBody]string url)
|
public IActionResult GetMangaFromUrl([FromBody]string url)
|
||||||
{
|
{
|
||||||
@@ -91,7 +90,7 @@ public class SearchController(PgsqlContext context, ILog Log) : Controller
|
|||||||
return StatusCode(Status500InternalServerError, "Could not find Global Connector.");
|
return StatusCode(Status500InternalServerError, "Could not find Global Connector.");
|
||||||
|
|
||||||
if(connector.GetMangaFromUrl(url) is not { } manga)
|
if(connector.GetMangaFromUrl(url) is not { } manga)
|
||||||
return BadRequest();
|
return NotFound();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(AddMangaToContext(manga) is { } add)
|
if(AddMangaToContext(manga) is { } add)
|
||||||
|
@@ -1,10 +1,13 @@
|
|||||||
using API.MangaDownloadClients;
|
using System.Net.Http.Headers;
|
||||||
|
using API.MangaDownloadClients;
|
||||||
using API.Schema;
|
using API.Schema;
|
||||||
using API.Schema.Contexts;
|
using API.Schema.Contexts;
|
||||||
using API.Schema.Jobs;
|
using API.Schema.Jobs;
|
||||||
using Asp.Versioning;
|
using Asp.Versioning;
|
||||||
|
using FlareSolverrSharp;
|
||||||
using log4net;
|
using log4net;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using static Microsoft.AspNetCore.Http.StatusCodes;
|
using static Microsoft.AspNetCore.Http.StatusCodes;
|
||||||
|
|
||||||
@@ -291,4 +294,70 @@ public class SettingsController(PgsqlContext context, ILog Log) : Controller
|
|||||||
return StatusCode(500, e);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@@ -1,27 +1,22 @@
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
|
using FlareSolverrSharp;
|
||||||
using HtmlAgilityPack;
|
using HtmlAgilityPack;
|
||||||
|
|
||||||
namespace API.MangaDownloadClients;
|
namespace API.MangaDownloadClients;
|
||||||
|
|
||||||
internal class HttpDownloadClient : DownloadClient
|
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)
|
internal override RequestResult MakeRequestInternal(string url, string? referrer = null, string? clickButton = null)
|
||||||
{
|
{
|
||||||
if (clickButton is not null)
|
if (clickButton is not null)
|
||||||
Log.Warn("Client can not click button");
|
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);
|
Uri uri = new(url);
|
||||||
HttpRequestMessage requestMessage = new(HttpMethod.Get, uri);
|
HttpRequestMessage requestMessage = new(HttpMethod.Get, uri);
|
||||||
if (referrer is not null)
|
if (referrer is not null)
|
||||||
@@ -29,7 +24,7 @@ internal class HttpDownloadClient : DownloadClient
|
|||||||
Log.Debug($"Requesting {url}");
|
Log.Debug($"Requesting {url}");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
response = Client.Send(requestMessage);
|
response = client.Send(requestMessage);
|
||||||
}
|
}
|
||||||
catch (HttpRequestException e)
|
catch (HttpRequestException e)
|
||||||
{
|
{
|
||||||
|
@@ -15,6 +15,7 @@ public static class TrangaSettings
|
|||||||
public static string userAgent { get; private set; } = DefaultUserAgent;
|
public static string userAgent { get; private set; } = DefaultUserAgent;
|
||||||
public static int compression{ get; private set; } = 40;
|
public static int compression{ get; private set; } = 40;
|
||||||
public static bool bwImages { get; private set; } = false;
|
public static bool bwImages { get; private set; } = false;
|
||||||
|
public static string flareSolverrUrl { get; private set; } = string.Empty;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Placeholders:
|
/// Placeholders:
|
||||||
/// %M Manga Name
|
/// %M Manga Name
|
||||||
@@ -102,6 +103,12 @@ public static class TrangaSettings
|
|||||||
ExportSettings();
|
ExportSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void UpdateFlareSolverrUrl(string url)
|
||||||
|
{
|
||||||
|
flareSolverrUrl = url;
|
||||||
|
ExportSettings();
|
||||||
|
}
|
||||||
|
|
||||||
public static void ResetRequestLimits()
|
public static void ResetRequestLimits()
|
||||||
{
|
{
|
||||||
requestLimits = DefaultRequestLimits;
|
requestLimits = DefaultRequestLimits;
|
||||||
@@ -148,6 +155,7 @@ public static class TrangaSettings
|
|||||||
jobj.Add("bwImages", JToken.FromObject(bwImages));
|
jobj.Add("bwImages", JToken.FromObject(bwImages));
|
||||||
jobj.Add("startNewJobTimeoutMs", JToken.FromObject(startNewJobTimeoutMs));
|
jobj.Add("startNewJobTimeoutMs", JToken.FromObject(startNewJobTimeoutMs));
|
||||||
jobj.Add("chapterNamingScheme", JToken.FromObject(chapterNamingScheme));
|
jobj.Add("chapterNamingScheme", JToken.FromObject(chapterNamingScheme));
|
||||||
|
jobj.Add("flareSolverrUrl", JToken.FromObject(flareSolverrUrl));
|
||||||
return jobj;
|
return jobj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,5 +182,7 @@ public static class TrangaSettings
|
|||||||
startNewJobTimeoutMs = snjt.Value<int>()!;
|
startNewJobTimeoutMs = snjt.Value<int>()!;
|
||||||
if (jobj.TryGetValue("chapterNamingScheme", out JToken? cns))
|
if (jobj.TryGetValue("chapterNamingScheme", out JToken? cns))
|
||||||
chapterNamingScheme = cns.Value<string>()!;
|
chapterNamingScheme = cns.Value<string>()!;
|
||||||
|
if (jobj.TryGetValue("flareSolverrUrl", out JToken? fsu))
|
||||||
|
flareSolverrUrl = fsu.Value<string>()!;
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -86,12 +86,13 @@ Endpoints are documented in Swagger. Just spin up an instance, and go to `http:/
|
|||||||
|
|
||||||
- .NET
|
- .NET
|
||||||
- ASP.NET
|
- ASP.NET
|
||||||
- Entity Framework
|
- Entity Framework Core
|
||||||
- [PostgreSQL](https://www.postgresql.org/about/licence/)
|
- [PostgreSQL](https://www.postgresql.org/about/licence/)
|
||||||
- [Swagger](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/LICENSE)
|
- [Swagger](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/LICENSE)
|
||||||
- [Ngpsql](https://github.com/npgsql/npgsql/blob/main/LICENSE)
|
- [Ngpsql](https://github.com/npgsql/npgsql/blob/main/LICENSE)
|
||||||
- [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json/blob/master/LICENSE.md)
|
- [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json/blob/master/LICENSE.md)
|
||||||
- [PuppeteerSharp](https://github.com/hardkoded/puppeteer-sharp/blob/master/LICENSE)
|
- [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)
|
- [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)
|
- [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)
|
- [Sixlabors.ImageSharp](https://docs-v2.sixlabors.com/articles/imagesharp/index.html#license)
|
||||||
|
Reference in New Issue
Block a user