4 Commits

Author SHA1 Message Date
1b6af73a0c MangaDex nullvalue checks and allow null-fields in response
Some checks failed
Docker Image CI / build (push) Has been cancelled
2025-06-15 23:55:23 +02:00
70fe23857b Update UserAgent-String to Version 2.0 2025-06-15 23:26:30 +02:00
0027af2d36 Fix: First startup coverImageCache does not exist (on stale check) 2025-06-15 23:07:34 +02:00
1a8f70f501 Cleanup code for HttpDownloadClient and error-log 2025-06-15 23:00:01 +02:00
4 changed files with 31 additions and 32 deletions

View File

@@ -18,33 +18,28 @@ internal class HttpDownloadClient : DownloadClient
internal override RequestResult MakeRequestInternal(string url, string? referrer = null, string? clickButton = null)
{
if (clickButton is not null)
Log.Warn("Can not click button on static site.");
Log.Warn("Client can not click button");
HttpResponseMessage? response = null;
while (response is null)
{
HttpRequestMessage requestMessage = new(HttpMethod.Get, url);
if (referrer is not null)
requestMessage.Headers.Referrer = new Uri(referrer);
requestMessage.Headers.Referrer = new (referrer);
Log.Debug($"Requesting {url}");
try
{
response = Client.Send(requestMessage);
}
catch (Exception e)
catch (HttpRequestException e)
{
switch (e)
{
case TaskCanceledException:
return new RequestResult(HttpStatusCode.RequestTimeout, null, Stream.Null);
case HttpRequestException:
return new RequestResult(HttpStatusCode.BadRequest, null, Stream.Null);
}
Log.Error(e);
return new (HttpStatusCode.Unused, null, Stream.Null);
}
}
if (!response.IsSuccessStatusCode)
{
return new RequestResult(response.StatusCode, null, Stream.Null);
return new (response.StatusCode, null, Stream.Null);
}
Stream stream;
@@ -55,7 +50,7 @@ internal class HttpDownloadClient : DownloadClient
catch (Exception e)
{
Log.Error(e);
return new RequestResult(HttpStatusCode.InternalServerError, null, Stream.Null);
return new (HttpStatusCode.Unused, null, Stream.Null);
}
HtmlDocument? document = null;
@@ -71,10 +66,9 @@ internal class HttpDownloadClient : DownloadClient
// Request has been redirected to another page. For example, it redirects directly to the results when there is only 1 result
if (response.RequestMessage is not null && response.RequestMessage.RequestUri is not null)
{
return new RequestResult(response.StatusCode, document, stream, true,
response.RequestMessage.RequestUri.AbsoluteUri);
return new (response.StatusCode, document, stream, true, response.RequestMessage.RequestUri.AbsoluteUri);
}
return new RequestResult(response.StatusCode, document, stream);
return new (response.StatusCode, document, stream);
}
}

View File

@@ -226,22 +226,25 @@ public class MangaDex : MangaConnector
private Manga ParseMangaFromJToken(JToken jToken)
{
string? id = jToken.Value<string>("id");
if(id is null)
throw new Exception("jToken was not in expected format");
JObject? attributes = jToken["attributes"] as JObject;
string? name = attributes?["title"]?.Value<string>("en") ?? attributes?["title"]?.First?.First?.Value<string>();
string? description = attributes?["description"]?.Value<string>("en")??attributes?["description"]?.First?.First?.Value<string>();
string? status = attributes?["status"]?.Value<string>();
uint? year = attributes?["year"]?.Value<uint?>();
string? originalLanguage = attributes?["originalLanguage"]?.Value<string>();
JArray? altTitlesJArray = attributes?["altTitles"] as JArray;
JArray? tagsJArray = attributes?["tags"] as JArray;
if(attributes is null)
throw new Exception("jToken was not in expected format");
string? name = attributes["title"]?.Value<string>("en") ?? attributes["title"]?.First?.First?.Value<string>();
string description = attributes["description"]?.Value<string>("en")??attributes["description"]?.First?.First?.Value<string>()??"";
string? status = attributes["status"]?.Value<string>();
uint? year = attributes["year"]?.Value<uint?>();
string? originalLanguage = attributes["originalLanguage"]?.Value<string>();
JArray? altTitlesJArray = attributes.TryGetValue("altTitles", out JToken? altTitlesArray) ? altTitlesArray as JArray : null;
JArray? tagsJArray = attributes.TryGetValue("tags", out JToken? tagsArray) ? tagsArray as JArray : null;
JArray? relationships = jToken["relationships"] as JArray;
string? coverFileName =
relationships?.FirstOrDefault(r => r["type"]?.Value<string>() == "cover_art")?["attributes"]?.Value<string>("fileName");
if (name is null || status is null || relationships is null)
throw new Exception("jToken was not in expected format");
if (id is null || attributes is null || name is null || description is null || status is null ||
altTitlesJArray is null || tagsJArray is null || relationships is null || coverFileName is null)
string? coverFileName = relationships.FirstOrDefault(r => r["type"]?.Value<string>() == "cover_art")?["attributes"]?.Value<string>("fileName");
if(coverFileName is null)
throw new Exception("jToken was not in expected format");
List<Link> links = attributes["links"]?
@@ -276,7 +279,7 @@ public class MangaDex : MangaConnector
return new Link(key, url);
}).ToList()!;
List<MangaAltTitle> altTitles = altTitlesJArray
List<MangaAltTitle> altTitles = (altTitlesJArray??[])
.Select(t =>
{
JObject? j = t as JObject;
@@ -286,7 +289,7 @@ public class MangaDex : MangaConnector
return new MangaAltTitle(p.Name, p.Value.ToString());
}).Where(x => x is not null).ToList()!;
List<MangaTag> tags = tagsJArray
List<MangaTag> tags = (tagsJArray??[])
.Where(t => t.Value<string>("type") == "tag")
.Select(t => t["attributes"]?["name"]?.Value<string>("en")??t["attributes"]?["name"]?.First?.First?.Value<string>())
.Select(str => str is not null ? new MangaTag(str) : null)

View File

@@ -34,7 +34,9 @@ public static class Tranga
internal static void RemoveStaleFiles(PgsqlContext context)
{
Log.Info($"Removing stale files...");
Log.Info("Removing stale files...");
if (!Directory.Exists(TrangaSettings.coverImageCache))
return;
string[] usedFiles = context.Mangas.Select(m => m.CoverFileNameInCache).Where(s => s != null).ToArray()!;
string[] extraneousFiles = new DirectoryInfo(TrangaSettings.coverImageCache).GetFiles()
.Where(f => usedFiles.Contains(f.FullName) == false)

View File

@@ -11,7 +11,7 @@ public static class TrangaSettings
public static string downloadLocation { get; private set; } = (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "/Manga" : 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]
internal static readonly string DefaultUserAgent = $"Tranga ({Enum.GetName(Environment.OSVersion.Platform)}; {(Environment.Is64BitOperatingSystem ? "x64" : "")}) / 1.0";
internal static readonly string DefaultUserAgent = $"Tranga ({Enum.GetName(Environment.OSVersion.Platform)}; {(Environment.Is64BitOperatingSystem ? "x64" : "")}) / 2.0";
public static string userAgent { get; private set; } = DefaultUserAgent;
public static int compression{ get; private set; } = 40;
public static bool bwImages { get; private set; } = false;