mirror of
https://github.com/C9Glax/tranga.git
synced 2025-02-23 15:50:13 +01:00
commit
c706824222
@ -28,15 +28,13 @@ public class UpdateMetadata : Job
|
|||||||
if (possibleUpdatedManga is { } updatedManga)
|
if (possibleUpdatedManga is { } updatedManga)
|
||||||
{
|
{
|
||||||
if (updatedManga.Equals(this.manga)) //Check if anything changed
|
if (updatedManga.Equals(this.manga)) //Check if anything changed
|
||||||
|
{
|
||||||
|
this.progressToken.Complete();
|
||||||
return Array.Empty<Job>();
|
return Array.Empty<Job>();
|
||||||
|
}
|
||||||
|
|
||||||
this.manga.UpdateMetadata(updatedManga);
|
this.manga.UpdateMetadata(updatedManga);
|
||||||
this.manga.SaveSeriesInfoJson(settings.downloadLocation, true);
|
this.manga.SaveSeriesInfoJson(settings.downloadLocation, true);
|
||||||
|
|
||||||
if (parentJobId is not null && jobBoss.GetJobById(this.parentJobId) is DownloadNewChapters dncJob)
|
|
||||||
{
|
|
||||||
dncJob.manga = updatedManga;
|
|
||||||
}
|
|
||||||
this.progressToken.Complete();
|
this.progressToken.Complete();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -62,8 +62,17 @@ internal class ChromiumDownloadClient : DownloadClient
|
|||||||
{
|
{
|
||||||
IPage page = this.browser.NewPageAsync().Result;
|
IPage page = this.browser.NewPageAsync().Result;
|
||||||
page.DefaultTimeout = 10000;
|
page.DefaultTimeout = 10000;
|
||||||
IResponse response = page.GoToAsync(url, WaitUntilNavigation.Networkidle0).Result;
|
IResponse response;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
response = page.GoToAsync(url, WaitUntilNavigation.Networkidle0).Result;
|
||||||
Log("Page loaded.");
|
Log("Page loaded.");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log($"Could not load Page:\n{e.Message}");
|
||||||
|
return new RequestResult(HttpStatusCode.InternalServerError, null, Stream.Null);
|
||||||
|
}
|
||||||
|
|
||||||
Stream stream = Stream.Null;
|
Stream stream = Stream.Null;
|
||||||
HtmlDocument? document = null;
|
HtmlDocument? document = null;
|
||||||
|
@ -16,6 +16,14 @@ internal abstract class DownloadClient : GlobalBase
|
|||||||
_rateLimit.Add(limit.Key, TimeSpan.FromMinutes(1).Divide(limit.Value));
|
_rateLimit.Add(limit.Key, TimeSpan.FromMinutes(1).Divide(limit.Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void SetCustomRequestLimit(byte requestType, int limit)
|
||||||
|
{
|
||||||
|
if (_rateLimit.ContainsKey(requestType))
|
||||||
|
_rateLimit[requestType] = TimeSpan.FromMinutes(1).Divide(limit);
|
||||||
|
else
|
||||||
|
_rateLimit.Add(requestType, TimeSpan.FromMinutes(1).Divide(limit));
|
||||||
|
}
|
||||||
|
|
||||||
public RequestResult MakeRequest(string url, byte requestType, string? referrer = null, string? clickButton = null)
|
public RequestResult MakeRequest(string url, byte requestType, string? referrer = null, string? clickButton = null)
|
||||||
{
|
{
|
||||||
if (_rateLimit.TryGetValue(requestType, out TimeSpan value))
|
if (_rateLimit.TryGetValue(requestType, out TimeSpan value))
|
||||||
|
@ -8,20 +8,13 @@ internal class HttpDownloadClient : DownloadClient
|
|||||||
{
|
{
|
||||||
private static readonly HttpClient Client = new()
|
private static readonly HttpClient Client = new()
|
||||||
{
|
{
|
||||||
Timeout = TimeSpan.FromSeconds(60),
|
Timeout = TimeSpan.FromSeconds(10)
|
||||||
DefaultRequestHeaders =
|
|
||||||
{
|
|
||||||
UserAgent =
|
|
||||||
{
|
|
||||||
new ProductInfoHeaderValue("Tranga", "0.1")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
public HttpDownloadClient(GlobalBase clone, Dictionary<byte, int> rateLimitRequestsPerMinute) : base(clone, rateLimitRequestsPerMinute)
|
public HttpDownloadClient(GlobalBase clone, Dictionary<byte, int> rateLimitRequestsPerMinute) : base(clone, rateLimitRequestsPerMinute)
|
||||||
{
|
{
|
||||||
|
Client.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", settings.userAgent);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override RequestResult MakeRequestInternal(string url, string? referrer = null, string? clickButton = null)
|
protected override RequestResult MakeRequestInternal(string url, string? referrer = null, string? clickButton = null)
|
||||||
@ -44,10 +37,10 @@ internal class HttpDownloadClient : DownloadClient
|
|||||||
switch (e)
|
switch (e)
|
||||||
{
|
{
|
||||||
case TaskCanceledException:
|
case TaskCanceledException:
|
||||||
Log($"Request timed out.\n\r{e}");
|
Log($"Request timed out {url}.\n\r{e}");
|
||||||
return new RequestResult(HttpStatusCode.RequestTimeout, null, Stream.Null);
|
return new RequestResult(HttpStatusCode.RequestTimeout, null, Stream.Null);
|
||||||
case HttpRequestException:
|
case HttpRequestException:
|
||||||
Log($"Request failed\n\r{e}");
|
Log($"Request failed {url}\n\r{e}");
|
||||||
return new RequestResult(HttpStatusCode.BadRequest, null, Stream.Null);
|
return new RequestResult(HttpStatusCode.BadRequest, null, Stream.Null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -55,7 +48,7 @@ internal class HttpDownloadClient : DownloadClient
|
|||||||
|
|
||||||
if (!response.IsSuccessStatusCode)
|
if (!response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
Log($"Request-Error {response.StatusCode}: {response.ReasonPhrase}");
|
Log($"Request-Error {response.StatusCode}: {url}");
|
||||||
return new RequestResult(response.StatusCode, null, Stream.Null);
|
return new RequestResult(response.StatusCode, null, Stream.Null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ public abstract class MangaConnector : GlobalBase
|
|||||||
string fileInCache = Path.Join(settings.coverImageCache, manga.coverFileNameInCache);
|
string fileInCache = Path.Join(settings.coverImageCache, manga.coverFileNameInCache);
|
||||||
if (!File.Exists(fileInCache))
|
if (!File.Exists(fileInCache))
|
||||||
{
|
{
|
||||||
Log($"Cloníng cover failed: File missing {fileInCache}.");
|
Log($"Cloning cover failed: File missing {fileInCache}.");
|
||||||
if (retries > 0 && manga.coverUrl is not null)
|
if (retries > 0 && manga.coverUrl is not null)
|
||||||
{
|
{
|
||||||
Log($"Trying {retries} more times");
|
Log($"Trying {retries} more times");
|
||||||
|
@ -19,7 +19,7 @@ public class Mangaworld: MangaConnector
|
|||||||
{
|
{
|
||||||
Log($"Searching Publications. Term=\"{publicationTitle}\"");
|
Log($"Searching Publications. Term=\"{publicationTitle}\"");
|
||||||
string sanitizedTitle = string.Join(' ', Regex.Matches(publicationTitle, "[A-z]*").Where(str => str.Length > 0)).ToLower();
|
string sanitizedTitle = string.Join(' ', Regex.Matches(publicationTitle, "[A-z]*").Where(str => str.Length > 0)).ToLower();
|
||||||
string requestUrl = $"https://www.mangaworld.bz/archive?keyword={sanitizedTitle}";
|
string requestUrl = $"https://www.mangaworld.ac/archive?keyword={sanitizedTitle}";
|
||||||
RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest(requestUrl, 1);
|
downloadClient.MakeRequest(requestUrl, 1);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
@ -56,7 +56,7 @@ public class Mangaworld: MangaConnector
|
|||||||
|
|
||||||
public override Manga? GetMangaFromId(string publicationId)
|
public override Manga? GetMangaFromId(string publicationId)
|
||||||
{
|
{
|
||||||
return GetMangaFromUrl($"https://www.mangaworld.bz/manga/{publicationId}");
|
return GetMangaFromUrl($"https://www.mangaworld.ac/manga/{publicationId}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Manga? GetMangaFromUrl(string url)
|
public override Manga? GetMangaFromUrl(string url)
|
||||||
@ -69,7 +69,7 @@ public class Mangaworld: MangaConnector
|
|||||||
if (requestResult.htmlDocument is null)
|
if (requestResult.htmlDocument is null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
Regex idRex = new (@"https:\/\/www\.mangaworld\.bz\/manga\/([0-9]+\/[0-9A-z\-]+)");
|
Regex idRex = new (@"https:\/\/www\.mangaworld\.[a-z]{0,63}\/manga\/([0-9]+\/[0-9A-z\-]+)");
|
||||||
string id = idRex.Match(url).Groups[1].Value;
|
string id = idRex.Match(url).Groups[1].Value;
|
||||||
return ParseSinglePublicationFromHtml(requestResult.htmlDocument, id);
|
return ParseSinglePublicationFromHtml(requestResult.htmlDocument, id);
|
||||||
}
|
}
|
||||||
@ -130,7 +130,7 @@ public class Mangaworld: MangaConnector
|
|||||||
public override Chapter[] GetChapters(Manga manga, string language="en")
|
public override Chapter[] GetChapters(Manga manga, string language="en")
|
||||||
{
|
{
|
||||||
Log($"Getting chapters {manga}");
|
Log($"Getting chapters {manga}");
|
||||||
string requestUrl = $"https://www.mangaworld.bz/manga/{manga.publicationId}";
|
string requestUrl = $"https://www.mangaworld.ac/manga/{manga.publicationId}";
|
||||||
RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest(requestUrl, 1);
|
downloadClient.MakeRequest(requestUrl, 1);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
|
@ -200,6 +200,9 @@ public class Server : GlobalBase
|
|||||||
case "Settings":
|
case "Settings":
|
||||||
SendResponse(HttpStatusCode.OK, response, settings);
|
SendResponse(HttpStatusCode.OK, response, settings);
|
||||||
break;
|
break;
|
||||||
|
case "Settings/userAgent":
|
||||||
|
SendResponse(HttpStatusCode.OK, response, settings.userAgent);
|
||||||
|
break;
|
||||||
case "NotificationConnectors":
|
case "NotificationConnectors":
|
||||||
SendResponse(HttpStatusCode.OK, response, notificationConnectors);
|
SendResponse(HttpStatusCode.OK, response, notificationConnectors);
|
||||||
break;
|
break;
|
||||||
@ -384,6 +387,29 @@ public class Server : GlobalBase
|
|||||||
settings.UpdateWorkingDirectory(workingDirectory);
|
settings.UpdateWorkingDirectory(workingDirectory);
|
||||||
SendResponse(HttpStatusCode.Accepted, response);
|
SendResponse(HttpStatusCode.Accepted, response);
|
||||||
break;*/
|
break;*/
|
||||||
|
case "Settings/userAgent":
|
||||||
|
if(!requestVariables.TryGetValue("userAgent", out string? customUserAgent))
|
||||||
|
{
|
||||||
|
SendResponse(HttpStatusCode.BadRequest, response);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
settings.UpdateUserAgent(customUserAgent);
|
||||||
|
SendResponse(HttpStatusCode.Accepted, response);
|
||||||
|
break;
|
||||||
|
case "Settings/customRequestLimit":
|
||||||
|
if (!requestVariables.TryGetValue("requestType", out string? requestTypeStr) ||
|
||||||
|
!requestVariables.TryGetValue("requestsPerMinute", out string? requestsPerMinuteStr) ||
|
||||||
|
!requestVariables.TryGetValue("connector", out connectorName) ||
|
||||||
|
!byte.TryParse(requestTypeStr, out byte requestType) ||
|
||||||
|
!int.TryParse(requestsPerMinuteStr, out int requestsPerMinute) ||
|
||||||
|
!_parent.TryGetConnector(connectorName, out connector))
|
||||||
|
{
|
||||||
|
SendResponse(HttpStatusCode.BadRequest, response);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
connector!.downloadClient.SetCustomRequestLimit(requestType, requestsPerMinute);
|
||||||
|
SendResponse(HttpStatusCode.Accepted, response);
|
||||||
|
break;
|
||||||
case "NotificationConnectors/Update":
|
case "NotificationConnectors/Update":
|
||||||
if (!requestVariables.TryGetValue("notificationConnector", out string? notificationConnectorStr) ||
|
if (!requestVariables.TryGetValue("notificationConnector", out string? notificationConnectorStr) ||
|
||||||
!Enum.TryParse(notificationConnectorStr, out NotificationConnector.NotificationConnectorType notificationConnectorType))
|
!Enum.TryParse(notificationConnectorStr, out NotificationConnector.NotificationConnectorType notificationConnectorType))
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System.Runtime.InteropServices;
|
using System.Net.Http.Headers;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Tranga.LibraryConnectors;
|
using Tranga.LibraryConnectors;
|
||||||
using Tranga.NotificationConnectors;
|
using Tranga.NotificationConnectors;
|
||||||
@ -12,6 +13,9 @@ public class TrangaSettings
|
|||||||
public string workingDirectory { get; private set; }
|
public string workingDirectory { get; private set; }
|
||||||
public int apiPortNumber { get; init; }
|
public int apiPortNumber { get; init; }
|
||||||
public string styleSheet { get; private set; }
|
public string styleSheet { get; private set; }
|
||||||
|
|
||||||
|
public string userAgent { get; set; } =
|
||||||
|
$"Tranga ({Enum.GetName(Environment.OSVersion.Platform)}; {(Environment.Is64BitOperatingSystem ? "x64" : "")}) / 1.0";
|
||||||
[JsonIgnore] public string settingsFilePath => Path.Join(workingDirectory, "settings.json");
|
[JsonIgnore] public string settingsFilePath => Path.Join(workingDirectory, "settings.json");
|
||||||
[JsonIgnore] public string libraryConnectorsFilePath => Path.Join(workingDirectory, "libraryConnectors.json");
|
[JsonIgnore] public string libraryConnectorsFilePath => Path.Join(workingDirectory, "libraryConnectors.json");
|
||||||
[JsonIgnore] public string notificationConnectorsFilePath => Path.Join(workingDirectory, "notificationConnectors.json");
|
[JsonIgnore] public string notificationConnectorsFilePath => Path.Join(workingDirectory, "notificationConnectors.json");
|
||||||
@ -119,6 +123,12 @@ public class TrangaSettings
|
|||||||
ExportSettings();
|
ExportSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UpdateUserAgent(string customUserAgent)
|
||||||
|
{
|
||||||
|
this.userAgent = customUserAgent;
|
||||||
|
ExportSettings();
|
||||||
|
}
|
||||||
|
|
||||||
public void ExportSettings()
|
public void ExportSettings()
|
||||||
{
|
{
|
||||||
if (File.Exists(settingsFilePath))
|
if (File.Exists(settingsFilePath))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user