mirror of
https://github.com/C9Glax/tranga.git
synced 2025-07-04 18:04:16 +02:00
TrangaSettings as static field in Tranga instead of Static class
This commit is contained in:
@ -138,8 +138,8 @@ public class MangaController(IServiceScope scope) : Controller
|
|||||||
{
|
{
|
||||||
if (Tranga.GetRunningWorkers().Any(worker => worker is DownloadCoverFromMangaconnectorWorker w && w.MangaConnectorId.ObjId == MangaId))
|
if (Tranga.GetRunningWorkers().Any(worker => worker is DownloadCoverFromMangaconnectorWorker w && w.MangaConnectorId.ObjId == MangaId))
|
||||||
{
|
{
|
||||||
Response.Headers.Append("Retry-After", $"{TrangaSettings.workCycleTimeout * 2 / 1000:D}");
|
Response.Headers.Append("Retry-After", $"{Tranga.Settings.WorkCycleTimeoutMs * 2 / 1000:D}");
|
||||||
return StatusCode(Status503ServiceUnavailable, TrangaSettings.workCycleTimeout * 2 / 1000);
|
return StatusCode(Status503ServiceUnavailable, Tranga.Settings.WorkCycleTimeoutMs * 2 / 1000);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return NoContent();
|
return NoContent();
|
||||||
@ -258,8 +258,8 @@ public class MangaController(IServiceScope scope) : Controller
|
|||||||
{
|
{
|
||||||
if (Tranga.GetRunningWorkers().Any(worker => worker is RetrieveMangaChaptersFromMangaconnectorWorker w && w.MangaConnectorId.ObjId == MangaId && w.State < WorkerExecutionState.Completed))
|
if (Tranga.GetRunningWorkers().Any(worker => worker is RetrieveMangaChaptersFromMangaconnectorWorker w && w.MangaConnectorId.ObjId == MangaId && w.State < WorkerExecutionState.Completed))
|
||||||
{
|
{
|
||||||
Response.Headers.Append("Retry-After", $"{TrangaSettings.workCycleTimeout * 2 / 1000:D}");
|
Response.Headers.Append("Retry-After", $"{Tranga.Settings.WorkCycleTimeoutMs * 2 / 1000:D}");
|
||||||
return StatusCode(Status503ServiceUnavailable, TrangaSettings.workCycleTimeout * 2/ 1000);
|
return StatusCode(Status503ServiceUnavailable, Tranga.Settings.WorkCycleTimeoutMs * 2/ 1000);
|
||||||
}else
|
}else
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
@ -297,8 +297,8 @@ public class MangaController(IServiceScope scope) : Controller
|
|||||||
{
|
{
|
||||||
if (Tranga.GetRunningWorkers().Any(worker => worker is RetrieveMangaChaptersFromMangaconnectorWorker w && w.MangaConnectorId.ObjId == MangaId && w.State < WorkerExecutionState.Completed))
|
if (Tranga.GetRunningWorkers().Any(worker => worker is RetrieveMangaChaptersFromMangaconnectorWorker w && w.MangaConnectorId.ObjId == MangaId && w.State < WorkerExecutionState.Completed))
|
||||||
{
|
{
|
||||||
Response.Headers.Append("Retry-After", $"{TrangaSettings.workCycleTimeout * 2 / 1000:D}");
|
Response.Headers.Append("Retry-After", $"{Tranga.Settings.WorkCycleTimeoutMs * 2 / 1000:D}");
|
||||||
return StatusCode(Status503ServiceUnavailable, TrangaSettings.workCycleTimeout * 2/ 1000);
|
return StatusCode(Status503ServiceUnavailable, Tranga.Settings.WorkCycleTimeoutMs * 2/ 1000);
|
||||||
}else
|
}else
|
||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ using API.Schema.MangaContext;
|
|||||||
using API.Workers;
|
using API.Workers;
|
||||||
using Asp.Versioning;
|
using Asp.Versioning;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using static Microsoft.AspNetCore.Http.StatusCodes;
|
using static Microsoft.AspNetCore.Http.StatusCodes;
|
||||||
// ReSharper disable InconsistentNaming
|
// ReSharper disable InconsistentNaming
|
||||||
|
|
||||||
@ -15,14 +14,14 @@ namespace API.Controllers;
|
|||||||
public class SettingsController(IServiceScope scope) : Controller
|
public class SettingsController(IServiceScope scope) : Controller
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get all Settings
|
/// Get all <see cref="Tranga.Settings"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <response code="200"></response>
|
/// <response code="200"></response>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[ProducesResponseType<JObject>(Status200OK, "application/json")]
|
[ProducesResponseType<TrangaSettings>(Status200OK, "application/json")]
|
||||||
public IActionResult GetSettings()
|
public IActionResult GetSettings()
|
||||||
{
|
{
|
||||||
return Ok(JObject.Parse(TrangaSettings.Serialize()));
|
return Ok(Tranga.Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -33,7 +32,7 @@ public class SettingsController(IServiceScope scope) : Controller
|
|||||||
[ProducesResponseType<string>(Status200OK, "text/plain")]
|
[ProducesResponseType<string>(Status200OK, "text/plain")]
|
||||||
public IActionResult GetUserAgent()
|
public IActionResult GetUserAgent()
|
||||||
{
|
{
|
||||||
return Ok(TrangaSettings.userAgent);
|
return Ok(Tranga.Settings.UserAgent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -44,7 +43,8 @@ public class SettingsController(IServiceScope scope) : Controller
|
|||||||
[ProducesResponseType(Status200OK)]
|
[ProducesResponseType(Status200OK)]
|
||||||
public IActionResult SetUserAgent([FromBody]string userAgent)
|
public IActionResult SetUserAgent([FromBody]string userAgent)
|
||||||
{
|
{
|
||||||
TrangaSettings.UpdateUserAgent(userAgent);
|
//TODO Validate
|
||||||
|
Tranga.Settings.SetUserAgent(userAgent);
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ public class SettingsController(IServiceScope scope) : Controller
|
|||||||
[ProducesResponseType(Status200OK)]
|
[ProducesResponseType(Status200OK)]
|
||||||
public IActionResult ResetUserAgent()
|
public IActionResult ResetUserAgent()
|
||||||
{
|
{
|
||||||
TrangaSettings.UpdateUserAgent(TrangaSettings.DefaultUserAgent);
|
Tranga.Settings.SetUserAgent(TrangaSettings.DefaultUserAgent);
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ public class SettingsController(IServiceScope scope) : Controller
|
|||||||
[ProducesResponseType<Dictionary<RequestType,int>>(Status200OK, "application/json")]
|
[ProducesResponseType<Dictionary<RequestType,int>>(Status200OK, "application/json")]
|
||||||
public IActionResult GetRequestLimits()
|
public IActionResult GetRequestLimits()
|
||||||
{
|
{
|
||||||
return Ok(TrangaSettings.requestLimits);
|
return Ok(Tranga.Settings.RequestLimits);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -96,7 +96,7 @@ public class SettingsController(IServiceScope scope) : Controller
|
|||||||
{
|
{
|
||||||
if (requestLimit <= 0)
|
if (requestLimit <= 0)
|
||||||
return BadRequest();
|
return BadRequest();
|
||||||
TrangaSettings.UpdateRequestLimit(RequestType, requestLimit);
|
Tranga.Settings.SetRequestLimit(RequestType, requestLimit);
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ public class SettingsController(IServiceScope scope) : Controller
|
|||||||
[ProducesResponseType<string>(Status200OK)]
|
[ProducesResponseType<string>(Status200OK)]
|
||||||
public IActionResult ResetRequestLimits(RequestType RequestType)
|
public IActionResult ResetRequestLimits(RequestType RequestType)
|
||||||
{
|
{
|
||||||
TrangaSettings.UpdateRequestLimit(RequestType, TrangaSettings.DefaultRequestLimits[RequestType]);
|
Tranga.Settings.SetRequestLimit(RequestType, TrangaSettings.DefaultRequestLimits[RequestType]);
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,35 +120,35 @@ public class SettingsController(IServiceScope scope) : Controller
|
|||||||
[ProducesResponseType<string>(Status200OK)]
|
[ProducesResponseType<string>(Status200OK)]
|
||||||
public IActionResult ResetRequestLimits()
|
public IActionResult ResetRequestLimits()
|
||||||
{
|
{
|
||||||
TrangaSettings.ResetRequestLimits();
|
Tranga.Settings.ResetRequestLimits();
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns Level of Image-Compression for Images
|
/// Returns Level of Image-Compression for Images
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <response code="200">JPEG compression-level as Integer</response>
|
/// <response code="200">JPEG ImageCompression-level as Integer</response>
|
||||||
[HttpGet("ImageCompression")]
|
[HttpGet("ImageCompressionLevel")]
|
||||||
[ProducesResponseType<int>(Status200OK, "text/plain")]
|
[ProducesResponseType<int>(Status200OK, "text/plain")]
|
||||||
public IActionResult GetImageCompression()
|
public IActionResult GetImageCompression()
|
||||||
{
|
{
|
||||||
return Ok(TrangaSettings.compression);
|
return Ok(Tranga.Settings.ImageCompression);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set the Image-Compression-Level for Images
|
/// Set the Image-Compression-Level for Images
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="level">100 to disable, 0-99 for JPEG compression-Level</param>
|
/// <param name="level">100 to disable, 0-99 for JPEG ImageCompression-Level</param>
|
||||||
/// <response code="200"></response>
|
/// <response code="200"></response>
|
||||||
/// <response code="400">Level outside permitted range</response>
|
/// <response code="400">Level outside permitted range</response>
|
||||||
[HttpPatch("ImageCompression")]
|
[HttpPatch("ImageCompressionLevel/{level}")]
|
||||||
[ProducesResponseType(Status200OK)]
|
[ProducesResponseType(Status200OK)]
|
||||||
[ProducesResponseType(Status400BadRequest)]
|
[ProducesResponseType(Status400BadRequest)]
|
||||||
public IActionResult SetImageCompression([FromBody]int level)
|
public IActionResult SetImageCompression(int level)
|
||||||
{
|
{
|
||||||
if (level < 1 || level > 100)
|
if (level < 1 || level > 100)
|
||||||
return BadRequest();
|
return BadRequest();
|
||||||
TrangaSettings.UpdateCompressImages(level);
|
Tranga.Settings.UpdateImageCompression(level);
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ public class SettingsController(IServiceScope scope) : Controller
|
|||||||
[ProducesResponseType<bool>(Status200OK, "text/plain")]
|
[ProducesResponseType<bool>(Status200OK, "text/plain")]
|
||||||
public IActionResult GetBwImagesToggle()
|
public IActionResult GetBwImagesToggle()
|
||||||
{
|
{
|
||||||
return Ok(TrangaSettings.bwImages);
|
return Ok(Tranga.Settings.BlackWhiteImages);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -168,37 +168,11 @@ public class SettingsController(IServiceScope scope) : Controller
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="enabled">true to enable</param>
|
/// <param name="enabled">true to enable</param>
|
||||||
/// <response code="200"></response>
|
/// <response code="200"></response>
|
||||||
[HttpPatch("BWImages")]
|
[HttpPatch("BWImages/{enabled}")]
|
||||||
[ProducesResponseType(Status200OK)]
|
[ProducesResponseType(Status200OK)]
|
||||||
public IActionResult SetBwImagesToggle([FromBody]bool enabled)
|
public IActionResult SetBwImagesToggle(bool enabled)
|
||||||
{
|
{
|
||||||
TrangaSettings.UpdateBwImages(enabled);
|
Tranga.Settings.SetBlackWhiteImageEnabled(enabled);
|
||||||
return Ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get state of April Fools Mode
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>April Fools Mode disables all downloads on April 1st</remarks>
|
|
||||||
/// <response code="200">True if enabled</response>
|
|
||||||
[HttpGet("AprilFoolsMode")]
|
|
||||||
[ProducesResponseType<bool>(Status200OK, "text/plain")]
|
|
||||||
public IActionResult GetAprilFoolsMode()
|
|
||||||
{
|
|
||||||
return Ok(TrangaSettings.aprilFoolsMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Enable/Disable April Fools Mode
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>April Fools Mode disables all downloads on April 1st</remarks>
|
|
||||||
/// <param name="enabled">true to enable</param>
|
|
||||||
/// <response code="200"></response>
|
|
||||||
[HttpPatch("AprilFoolsMode")]
|
|
||||||
[ProducesResponseType(Status200OK)]
|
|
||||||
public IActionResult SetAprilFoolsMode([FromBody]bool enabled)
|
|
||||||
{
|
|
||||||
TrangaSettings.UpdateAprilFoolsMode(enabled);
|
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,7 +198,7 @@ public class SettingsController(IServiceScope scope) : Controller
|
|||||||
[ProducesResponseType<string>(Status200OK, "text/plain")]
|
[ProducesResponseType<string>(Status200OK, "text/plain")]
|
||||||
public IActionResult GetCustomNamingScheme()
|
public IActionResult GetCustomNamingScheme()
|
||||||
{
|
{
|
||||||
return Ok(TrangaSettings.chapterNamingScheme);
|
return Ok(Tranga.Settings.ChapterNamingScheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -250,7 +224,7 @@ public class SettingsController(IServiceScope scope) : Controller
|
|||||||
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
|
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
|
||||||
|
|
||||||
Dictionary<Chapter, string> oldPaths = context.Chapters.ToDictionary(c => c, c => c.FullArchiveFilePath);
|
Dictionary<Chapter, string> oldPaths = context.Chapters.ToDictionary(c => c, c => c.FullArchiveFilePath);
|
||||||
TrangaSettings.UpdateChapterNamingScheme(namingScheme);
|
Tranga.Settings.SetChapterNamingScheme(namingScheme);
|
||||||
MoveFileOrFolderWorker[] newJobs = oldPaths
|
MoveFileOrFolderWorker[] newJobs = oldPaths
|
||||||
.Select(kv => new MoveFileOrFolderWorker(kv.Value, kv.Key.FullArchiveFilePath)).ToArray();
|
.Select(kv => new MoveFileOrFolderWorker(kv.Value, kv.Key.FullArchiveFilePath)).ToArray();
|
||||||
Tranga.AddWorkers(newJobs);
|
Tranga.AddWorkers(newJobs);
|
||||||
@ -267,7 +241,7 @@ public class SettingsController(IServiceScope scope) : Controller
|
|||||||
[ProducesResponseType(Status200OK)]
|
[ProducesResponseType(Status200OK)]
|
||||||
public IActionResult SetFlareSolverrUrl([FromBody]string flareSolverrUrl)
|
public IActionResult SetFlareSolverrUrl([FromBody]string flareSolverrUrl)
|
||||||
{
|
{
|
||||||
TrangaSettings.UpdateFlareSolverrUrl(flareSolverrUrl);
|
Tranga.Settings.SetFlareSolverrUrl(flareSolverrUrl);
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,7 +253,7 @@ public class SettingsController(IServiceScope scope) : Controller
|
|||||||
[ProducesResponseType(Status200OK)]
|
[ProducesResponseType(Status200OK)]
|
||||||
public IActionResult ClearFlareSolverrUrl()
|
public IActionResult ClearFlareSolverrUrl()
|
||||||
{
|
{
|
||||||
TrangaSettings.UpdateFlareSolverrUrl(string.Empty);
|
Tranga.Settings.SetFlareSolverrUrl(string.Empty);
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,14 +16,14 @@ public abstract class DownloadClient
|
|||||||
public RequestResult MakeRequest(string url, RequestType requestType, string? referrer = null, string? clickButton = null)
|
public RequestResult MakeRequest(string url, RequestType requestType, string? referrer = null, string? clickButton = null)
|
||||||
{
|
{
|
||||||
Log.Debug($"Requesting {requestType} {url}");
|
Log.Debug($"Requesting {requestType} {url}");
|
||||||
if (!TrangaSettings.requestLimits.ContainsKey(requestType))
|
if (!Tranga.Settings.RequestLimits.ContainsKey(requestType))
|
||||||
{
|
{
|
||||||
return new RequestResult(HttpStatusCode.NotAcceptable, null, Stream.Null);
|
return new RequestResult(HttpStatusCode.NotAcceptable, null, Stream.Null);
|
||||||
}
|
}
|
||||||
|
|
||||||
int rateLimit = TrangaSettings.userAgent == TrangaSettings.DefaultUserAgent
|
int rateLimit = Tranga.Settings.UserAgent == TrangaSettings.DefaultUserAgent
|
||||||
? TrangaSettings.DefaultRequestLimits[requestType]
|
? TrangaSettings.DefaultRequestLimits[requestType]
|
||||||
: TrangaSettings.requestLimits[requestType];
|
: Tranga.Settings.RequestLimits[requestType];
|
||||||
|
|
||||||
TimeSpan timeBetweenRequests = TimeSpan.FromMinutes(1).Divide(rateLimit);
|
TimeSpan timeBetweenRequests = TimeSpan.FromMinutes(1).Divide(rateLimit);
|
||||||
DateTime now = DateTime.Now;
|
DateTime now = DateTime.Now;
|
||||||
|
@ -18,13 +18,13 @@ public class FlareSolverrDownloadClient : DownloadClient
|
|||||||
Log.Warn("Client can not click button");
|
Log.Warn("Client can not click button");
|
||||||
if(referrer is not null)
|
if(referrer is not null)
|
||||||
Log.Warn("Client can not set referrer");
|
Log.Warn("Client can not set referrer");
|
||||||
if (TrangaSettings.flareSolverrUrl == string.Empty)
|
if (Tranga.Settings.FlareSolverrUrl == string.Empty)
|
||||||
{
|
{
|
||||||
Log.Error("FlareSolverr URL is empty");
|
Log.Error("FlareSolverr URL is empty");
|
||||||
return new(HttpStatusCode.InternalServerError, null, Stream.Null);
|
return new(HttpStatusCode.InternalServerError, null, Stream.Null);
|
||||||
}
|
}
|
||||||
|
|
||||||
Uri flareSolverrUri = new (TrangaSettings.flareSolverrUrl);
|
Uri flareSolverrUri = new (Tranga.Settings.FlareSolverrUrl);
|
||||||
if (flareSolverrUri.Segments.Last() != "v1")
|
if (flareSolverrUri.Segments.Last() != "v1")
|
||||||
flareSolverrUri = new UriBuilder(flareSolverrUri)
|
flareSolverrUri = new UriBuilder(flareSolverrUri)
|
||||||
{
|
{
|
||||||
@ -35,7 +35,7 @@ public class FlareSolverrDownloadClient : DownloadClient
|
|||||||
{
|
{
|
||||||
Timeout = TimeSpan.FromSeconds(10),
|
Timeout = TimeSpan.FromSeconds(10),
|
||||||
DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher,
|
DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher,
|
||||||
DefaultRequestHeaders = { { "User-Agent", TrangaSettings.userAgent } }
|
DefaultRequestHeaders = { { "User-Agent", Tranga.Settings.UserAgent } }
|
||||||
};
|
};
|
||||||
|
|
||||||
JObject requestObj = new()
|
JObject requestObj = new()
|
||||||
|
@ -12,7 +12,7 @@ internal class HttpDownloadClient : DownloadClient
|
|||||||
HttpClient client = new();
|
HttpClient client = new();
|
||||||
client.Timeout = TimeSpan.FromSeconds(10);
|
client.Timeout = TimeSpan.FromSeconds(10);
|
||||||
client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher;
|
client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher;
|
||||||
client.DefaultRequestHeaders.Add("User-Agent", TrangaSettings.userAgent);
|
client.DefaultRequestHeaders.Add("User-Agent", Tranga.Settings.UserAgent);
|
||||||
HttpResponseMessage? response;
|
HttpResponseMessage? response;
|
||||||
Uri uri = new(url);
|
Uri uri = new(url);
|
||||||
HttpRequestMessage requestMessage = new(HttpMethod.Get, uri);
|
HttpRequestMessage requestMessage = new(HttpMethod.Get, uri);
|
||||||
|
@ -97,8 +97,7 @@ app.MapControllers()
|
|||||||
app.UseSwagger();
|
app.UseSwagger();
|
||||||
app.UseSwaggerUI(options =>
|
app.UseSwaggerUI(options =>
|
||||||
{
|
{
|
||||||
options.SwaggerEndpoint(
|
options.SwaggerEndpoint($"/swagger/v2/swagger.json", "v2");
|
||||||
$"/swagger/v2/swagger.json", "v2");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.UseHttpsRedirection();
|
app.UseHttpsRedirection();
|
||||||
@ -119,7 +118,7 @@ using (IServiceScope scope = app.Services.CreateScope())
|
|||||||
MangaConnector[] newConnectors = connectors.Where(c => !context.MangaConnectors.Contains(c)).ToArray();
|
MangaConnector[] newConnectors = connectors.Where(c => !context.MangaConnectors.Contains(c)).ToArray();
|
||||||
context.MangaConnectors.AddRange(newConnectors);
|
context.MangaConnectors.AddRange(newConnectors);
|
||||||
if (!context.FileLibraries.Any())
|
if (!context.FileLibraries.Any())
|
||||||
context.FileLibraries.Add(new FileLibrary(TrangaSettings.downloadLocation, "Default FileLibrary"));
|
context.FileLibraries.Add(new FileLibrary(Tranga.Settings.DownloadLocation, "Default FileLibrary"));
|
||||||
|
|
||||||
context.Sync();
|
context.Sync();
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,7 @@ public class Chapter : Identifiable, IComparable<Chapter>
|
|||||||
private static readonly Regex ReplaceRexx = new(@"%([a-zA-Z])|(.+?)");
|
private static readonly Regex ReplaceRexx = new(@"%([a-zA-Z])|(.+?)");
|
||||||
private string GetArchiveFilePath()
|
private string GetArchiveFilePath()
|
||||||
{
|
{
|
||||||
string archiveNamingScheme = TrangaSettings.chapterNamingScheme;
|
string archiveNamingScheme = Tranga.Settings.ChapterNamingScheme;
|
||||||
StringBuilder stringBuilder = new();
|
StringBuilder stringBuilder = new();
|
||||||
foreach (Match nullable in NullableRex.Matches(archiveNamingScheme))
|
foreach (Match nullable in NullableRex.Matches(archiveNamingScheme))
|
||||||
{
|
{
|
||||||
|
@ -34,7 +34,7 @@ public class NotificationConnector(string name, string url, Dictionary<string, s
|
|||||||
[NotMapped]
|
[NotMapped]
|
||||||
private readonly HttpClient Client = new()
|
private readonly HttpClient Client = new()
|
||||||
{
|
{
|
||||||
DefaultRequestHeaders = { { "User-Agent", TrangaSettings.userAgent } }
|
DefaultRequestHeaders = { { "User-Agent", Tranga.Settings.UserAgent } }
|
||||||
};
|
};
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
|
@ -21,6 +21,7 @@ public static class Tranga
|
|||||||
public static Thread PeriodicWorkerStarterThread { get; } = new (WorkerStarter);
|
public static Thread PeriodicWorkerStarterThread { get; } = new (WorkerStarter);
|
||||||
private static readonly ILog Log = LogManager.GetLogger(typeof(Tranga));
|
private static readonly ILog Log = LogManager.GetLogger(typeof(Tranga));
|
||||||
internal static readonly MetadataFetcher[] MetadataFetchers = [new MyAnimeList()];
|
internal static readonly MetadataFetcher[] MetadataFetchers = [new MyAnimeList()];
|
||||||
|
internal static TrangaSettings Settings = TrangaSettings.Load();
|
||||||
|
|
||||||
internal static void StartLogger()
|
internal static void StartLogger()
|
||||||
{
|
{
|
||||||
@ -80,7 +81,7 @@ public static class Tranga
|
|||||||
scopedWorker.SetScope(serviceProvider.CreateScope());
|
scopedWorker.SetScope(serviceProvider.CreateScope());
|
||||||
RunningWorkers.Add(worker, worker.DoWork());
|
RunningWorkers.Add(worker, worker.DoWork());
|
||||||
}
|
}
|
||||||
Thread.Sleep(TrangaSettings.workCycleTimeout);
|
Thread.Sleep(Settings.WorkCycleTimeoutMs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,16 +6,22 @@ using Newtonsoft.Json.Linq;
|
|||||||
|
|
||||||
namespace API;
|
namespace API;
|
||||||
|
|
||||||
public static class TrangaSettings
|
public struct TrangaSettings()
|
||||||
{
|
{
|
||||||
public static string downloadLocation { get; private set; } = (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "/Obj" : Path.Join(Directory.GetCurrentDirectory(), "Downloads"));
|
|
||||||
public static string workingDirectory { get; private set; } = Path.Join(RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "/usr/share" : Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "tranga-api");
|
[JsonIgnore]
|
||||||
|
public static string workingDirectory => Path.Join(RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "/usr/share" : Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "tranga-api");
|
||||||
|
[JsonIgnore]
|
||||||
|
public static string settingsFilePath => Path.Join(workingDirectory, "settings.json");
|
||||||
|
[JsonIgnore]
|
||||||
|
public static string coverImageCache => Path.Join(workingDirectory, "imageCache");
|
||||||
|
public string DownloadLocation => RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "/Manga" : Path.Join(Directory.GetCurrentDirectory(), "Manga");
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
internal static readonly string DefaultUserAgent = $"Tranga/2.0 ({Enum.GetName(Environment.OSVersion.Platform)}; {(Environment.Is64BitOperatingSystem ? "x64" : "")})";
|
internal static readonly string DefaultUserAgent = $"Tranga/2.0 ({Enum.GetName(Environment.OSVersion.Platform)}; {(Environment.Is64BitOperatingSystem ? "x64" : "")})";
|
||||||
public static string userAgent { get; private set; } = DefaultUserAgent;
|
public string UserAgent { get; private set; } = DefaultUserAgent;
|
||||||
public static int compression{ get; private set; } = 40;
|
public int ImageCompression{ get; private set; } = 40;
|
||||||
public static bool bwImages { get; private set; } = false;
|
public bool BlackWhiteImages { get; private set; } = false;
|
||||||
public static string flareSolverrUrl { get; private set; } = string.Empty;
|
public string FlareSolverrUrl { get; private set; } = string.Empty;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Placeholders:
|
/// Placeholders:
|
||||||
/// %M Obj Name
|
/// %M Obj Name
|
||||||
@ -30,13 +36,8 @@ public static class TrangaSettings
|
|||||||
/// ?_(...) replace _ with a value from above:
|
/// ?_(...) replace _ with a value from above:
|
||||||
/// Everything inside the braces will only be added if the value of %_ is not null
|
/// Everything inside the braces will only be added if the value of %_ is not null
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string chapterNamingScheme { get; private set; } = "%M - ?V(Vol.%V )Ch.%C?T( - %T)";
|
public string ChapterNamingScheme { get; private set; } = "%M - ?V(Vol.%V )Ch.%C?T( - %T)";
|
||||||
[JsonIgnore]
|
public int WorkCycleTimeoutMs { get; private set; } = 20000;
|
||||||
public static string settingsFilePath => Path.Join(workingDirectory, "settings.json");
|
|
||||||
[JsonIgnore]
|
|
||||||
public static string coverImageCache => Path.Join(workingDirectory, "imageCache");
|
|
||||||
public static bool aprilFoolsMode { get; private set; } = true;
|
|
||||||
public static int workCycleTimeout { get; private set; } = 20000;
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
internal static readonly Dictionary<RequestType, int> DefaultRequestLimits = new ()
|
internal static readonly Dictionary<RequestType, int> DefaultRequestLimits = new ()
|
||||||
{
|
{
|
||||||
@ -47,142 +48,57 @@ public static class TrangaSettings
|
|||||||
{RequestType.MangaCover, 60},
|
{RequestType.MangaCover, 60},
|
||||||
{RequestType.Default, 60}
|
{RequestType.Default, 60}
|
||||||
};
|
};
|
||||||
public static Dictionary<RequestType, int> requestLimits { get; private set; } = DefaultRequestLimits;
|
public Dictionary<RequestType, int> RequestLimits { get; private set; } = DefaultRequestLimits;
|
||||||
|
|
||||||
public static TimeSpan NotificationUrgencyDelay(NotificationUrgency urgency) => urgency switch
|
public static TrangaSettings Load()
|
||||||
{
|
{
|
||||||
NotificationUrgency.High => TimeSpan.Zero,
|
return JsonConvert.DeserializeObject<TrangaSettings>(File.ReadAllText(settingsFilePath));
|
||||||
NotificationUrgency.Normal => TimeSpan.FromMinutes(5),
|
|
||||||
NotificationUrgency.Low => TimeSpan.FromMinutes(10),
|
|
||||||
_ => TimeSpan.FromHours(1)
|
|
||||||
}; //TODO make this a setting?
|
|
||||||
|
|
||||||
public static void Load()
|
|
||||||
{
|
|
||||||
if(File.Exists(settingsFilePath))
|
|
||||||
Deserialize(File.ReadAllText(settingsFilePath));
|
|
||||||
else return;
|
|
||||||
|
|
||||||
Directory.CreateDirectory(downloadLocation);
|
|
||||||
ExportSettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdateAprilFoolsMode(bool enabled)
|
public void Save()
|
||||||
{
|
{
|
||||||
aprilFoolsMode = enabled;
|
File.WriteAllText(settingsFilePath, JsonConvert.SerializeObject(this));
|
||||||
ExportSettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdateCompressImages(int value)
|
public void SetUserAgent(string value)
|
||||||
{
|
{
|
||||||
compression = int.Clamp(value, 1, 100);
|
this.UserAgent = value;
|
||||||
ExportSettings();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdateBwImages(bool enabled)
|
public void SetRequestLimit(RequestType type, int value)
|
||||||
{
|
{
|
||||||
bwImages = enabled;
|
this.RequestLimits[type] = value;
|
||||||
ExportSettings();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdateUserAgent(string? customUserAgent)
|
public void ResetRequestLimits()
|
||||||
{
|
{
|
||||||
userAgent = customUserAgent ?? DefaultUserAgent;
|
this.RequestLimits = DefaultRequestLimits;
|
||||||
ExportSettings();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdateRequestLimit(RequestType requestType, int newLimit)
|
public void UpdateImageCompression(int value)
|
||||||
{
|
{
|
||||||
requestLimits[requestType] = newLimit;
|
this.ImageCompression = value;
|
||||||
ExportSettings();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdateChapterNamingScheme(string namingScheme)
|
public void SetBlackWhiteImageEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
chapterNamingScheme = namingScheme;
|
this.BlackWhiteImages = enabled;
|
||||||
ExportSettings();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdateFlareSolverrUrl(string url)
|
public void SetChapterNamingScheme(string scheme)
|
||||||
{
|
{
|
||||||
flareSolverrUrl = url;
|
this.ChapterNamingScheme = scheme;
|
||||||
ExportSettings();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ResetRequestLimits()
|
public void SetFlareSolverrUrl(string url)
|
||||||
{
|
{
|
||||||
requestLimits = DefaultRequestLimits;
|
this.FlareSolverrUrl = url;
|
||||||
ExportSettings();
|
Save();
|
||||||
}
|
|
||||||
|
|
||||||
public static void ExportSettings()
|
|
||||||
{
|
|
||||||
if (File.Exists(settingsFilePath))
|
|
||||||
{
|
|
||||||
while(IsFileInUse(settingsFilePath))
|
|
||||||
Thread.Sleep(100);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Directory.CreateDirectory(new FileInfo(settingsFilePath).DirectoryName!);
|
|
||||||
File.WriteAllText(settingsFilePath, Serialize());
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static bool IsFileInUse(string filePath)
|
|
||||||
{
|
|
||||||
if (!File.Exists(filePath))
|
|
||||||
return false;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using FileStream stream = new (filePath, FileMode.Open, FileAccess.Read, FileShare.None);
|
|
||||||
stream.Close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
catch (IOException)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static JObject AsJObject()
|
|
||||||
{
|
|
||||||
JObject jobj = new ();
|
|
||||||
jobj.Add("downloadLocation", JToken.FromObject(downloadLocation));
|
|
||||||
jobj.Add("workingDirectory", JToken.FromObject(workingDirectory));
|
|
||||||
jobj.Add("userAgent", JToken.FromObject(userAgent));
|
|
||||||
jobj.Add("aprilFoolsMode", JToken.FromObject(aprilFoolsMode));
|
|
||||||
jobj.Add("requestLimits", JToken.FromObject(requestLimits));
|
|
||||||
jobj.Add("compression", JToken.FromObject(compression));
|
|
||||||
jobj.Add("bwImages", JToken.FromObject(bwImages));
|
|
||||||
jobj.Add("workCycleTimeout", JToken.FromObject(workCycleTimeout));
|
|
||||||
jobj.Add("chapterNamingScheme", JToken.FromObject(chapterNamingScheme));
|
|
||||||
jobj.Add("flareSolverrUrl", JToken.FromObject(flareSolverrUrl));
|
|
||||||
return jobj;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string Serialize() => AsJObject().ToString();
|
|
||||||
|
|
||||||
public static void Deserialize(string serialized)
|
|
||||||
{
|
|
||||||
JObject jobj = JObject.Parse(serialized);
|
|
||||||
if (jobj.TryGetValue("downloadLocation", out JToken? dl))
|
|
||||||
downloadLocation = dl.Value<string>()!;
|
|
||||||
if (jobj.TryGetValue("workingDirectory", out JToken? wd))
|
|
||||||
workingDirectory = wd.Value<string>()!;
|
|
||||||
if (jobj.TryGetValue("userAgent", out JToken? ua))
|
|
||||||
userAgent = ua.Value<string>()!;
|
|
||||||
if (jobj.TryGetValue("aprilFoolsMode", out JToken? afm))
|
|
||||||
aprilFoolsMode = afm.Value<bool>()!;
|
|
||||||
if (jobj.TryGetValue("requestLimits", out JToken? rl))
|
|
||||||
requestLimits = rl.ToObject<Dictionary<RequestType, int>>()!;
|
|
||||||
if (jobj.TryGetValue("compression", out JToken? ci))
|
|
||||||
compression = ci.Value<int>()!;
|
|
||||||
if (jobj.TryGetValue("bwImages", out JToken? bwi))
|
|
||||||
bwImages = bwi.Value<bool>()!;
|
|
||||||
if (jobj.TryGetValue("workCycleTimeout", out JToken? snjt))
|
|
||||||
workCycleTimeout = 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>()!;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -101,7 +101,7 @@ public abstract class BaseWorker : Identifiable
|
|||||||
Log.Info($"Waiting for {MissingDependencies.Count()} Dependencies {this}:\n\t{string.Join("\n\t", MissingDependencies.Select(d => d.ToString()))}");
|
Log.Info($"Waiting for {MissingDependencies.Count()} Dependencies {this}:\n\t{string.Join("\n\t", MissingDependencies.Select(d => d.ToString()))}");
|
||||||
while (CancellationTokenSource.IsCancellationRequested == false && MissingDependencies.Any())
|
while (CancellationTokenSource.IsCancellationRequested == false && MissingDependencies.Any())
|
||||||
{
|
{
|
||||||
Thread.Sleep(TrangaSettings.workCycleTimeout);
|
Thread.Sleep(Tranga.Settings.WorkCycleTimeoutMs);
|
||||||
}
|
}
|
||||||
return [this];
|
return [this];
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ public class DownloadChapterFromMangaconnectorWorker(Chapter chapter, IEnumerabl
|
|||||||
|
|
||||||
private void ProcessImage(string imagePath)
|
private void ProcessImage(string imagePath)
|
||||||
{
|
{
|
||||||
if (!TrangaSettings.bwImages && TrangaSettings.compression == 100)
|
if (!Tranga.Settings.BlackWhiteImages && Tranga.Settings.ImageCompression == 100)
|
||||||
{
|
{
|
||||||
Log.Debug("No processing requested for image");
|
Log.Debug("No processing requested for image");
|
||||||
return;
|
return;
|
||||||
@ -107,12 +107,12 @@ public class DownloadChapterFromMangaconnectorWorker(Chapter chapter, IEnumerabl
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
using Image image = Image.Load(imagePath);
|
using Image image = Image.Load(imagePath);
|
||||||
if (TrangaSettings.bwImages)
|
if (Tranga.Settings.BlackWhiteImages)
|
||||||
image.Mutate(i => i.ApplyProcessor(new AdaptiveThresholdProcessor()));
|
image.Mutate(i => i.ApplyProcessor(new AdaptiveThresholdProcessor()));
|
||||||
File.Delete(imagePath);
|
File.Delete(imagePath);
|
||||||
image.SaveAsJpeg(imagePath, new JpegEncoder()
|
image.SaveAsJpeg(imagePath, new JpegEncoder()
|
||||||
{
|
{
|
||||||
Quality = TrangaSettings.compression
|
Quality = Tranga.Settings.ImageCompression
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
Reference in New Issue
Block a user