Compare commits
No commits in common. "1265c7a0720844026b88f7f73784ef8ccfeff3a7" and "5f2c66b7295432a62969d0f43051d0e9efc63147" have entirely different histories.
1265c7a072
...
5f2c66b729
@ -4,7 +4,7 @@ namespace Logging;
|
|||||||
|
|
||||||
public class FileLogger : LoggerBase
|
public class FileLogger : LoggerBase
|
||||||
{
|
{
|
||||||
internal string logFilePath { get; }
|
private string logFilePath { get; }
|
||||||
private const int MaxNumberOfLogFiles = 5;
|
private const int MaxNumberOfLogFiles = 5;
|
||||||
|
|
||||||
public FileLogger(string logFilePath, Encoding? encoding = null) : base (encoding)
|
public FileLogger(string logFilePath, Encoding? encoding = null) : base (encoding)
|
||||||
|
@ -8,7 +8,6 @@ public class Logger : TextWriter
|
|||||||
private static readonly string LogDirectoryPath = RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
|
private static readonly string LogDirectoryPath = RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
|
||||||
? "/var/log/tranga-api"
|
? "/var/log/tranga-api"
|
||||||
: Path.Join(Directory.GetCurrentDirectory(), "logs");
|
: Path.Join(Directory.GetCurrentDirectory(), "logs");
|
||||||
public string? logFilePath => _fileLogger?.logFilePath;
|
|
||||||
public override Encoding Encoding { get; }
|
public override Encoding Encoding { get; }
|
||||||
public enum LoggerType
|
public enum LoggerType
|
||||||
{
|
{
|
||||||
@ -70,9 +69,4 @@ public class Logger : TextWriter
|
|||||||
{
|
{
|
||||||
return _memoryLogger.GetNewLines();
|
return _memoryLogger.GetNewLines();
|
||||||
}
|
}
|
||||||
|
|
||||||
public string[] GetLog()
|
|
||||||
{
|
|
||||||
return _memoryLogger.GetLogMessages();
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -24,7 +24,7 @@ public class MemoryLogger : LoggerBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string[] GetLogMessages()
|
public string[] GetLogMessage()
|
||||||
{
|
{
|
||||||
return Tail(Convert.ToUInt32(_logMessages.Count));
|
return Tail(Convert.ToUInt32(_logMessages.Count));
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using System.Globalization;
|
using Logging;
|
||||||
using Logging;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Tranga.LibraryConnectors;
|
using Tranga.LibraryConnectors;
|
||||||
using Tranga.NotificationConnectors;
|
using Tranga.NotificationConnectors;
|
||||||
@ -13,7 +12,6 @@ public abstract class GlobalBase
|
|||||||
protected HashSet<NotificationConnector> notificationConnectors { get; init; }
|
protected HashSet<NotificationConnector> notificationConnectors { get; init; }
|
||||||
protected HashSet<LibraryConnector> libraryConnectors { get; init; }
|
protected HashSet<LibraryConnector> libraryConnectors { get; init; }
|
||||||
protected List<Manga> cachedPublications { get; init; }
|
protected List<Manga> cachedPublications { get; init; }
|
||||||
protected static readonly NumberFormatInfo numberFormatDecimalPoint = new (){ NumberDecimalSeparator = "." };
|
|
||||||
|
|
||||||
protected GlobalBase(GlobalBase clone)
|
protected GlobalBase(GlobalBase clone)
|
||||||
{
|
{
|
||||||
|
@ -28,7 +28,7 @@ public struct Manga
|
|||||||
public string? originalLanguage { get; }
|
public string? originalLanguage { get; }
|
||||||
// ReSharper disable once MemberCanBePrivate.Global
|
// ReSharper disable once MemberCanBePrivate.Global
|
||||||
public string status { get; }
|
public string status { get; }
|
||||||
public string folderName { get; private set; }
|
public string folderName { get; }
|
||||||
public string publicationId { get; }
|
public string publicationId { get; }
|
||||||
public string internalId { get; }
|
public string internalId { get; }
|
||||||
public float ignoreChaptersBelow { get; set; }
|
public float ignoreChaptersBelow { get; set; }
|
||||||
@ -73,15 +73,6 @@ public struct Manga
|
|||||||
return publicationFolder;
|
return publicationFolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void MovePublicationFolder(string downloadDirectory, string newFolderName)
|
|
||||||
{
|
|
||||||
string oldPath = Path.Join(downloadDirectory, this.folderName);
|
|
||||||
this.folderName = newFolderName;
|
|
||||||
string newPath = CreatePublicationFolder(downloadDirectory);
|
|
||||||
if(Directory.Exists(oldPath))
|
|
||||||
Directory.Move(oldPath, newPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SaveSeriesInfoJson(string downloadDirectory)
|
public void SaveSeriesInfoJson(string downloadDirectory)
|
||||||
{
|
{
|
||||||
string publicationFolder = CreatePublicationFolder(downloadDirectory);
|
string publicationFolder = CreatePublicationFolder(downloadDirectory);
|
||||||
|
@ -52,9 +52,10 @@ public abstract class MangaConnector : GlobalBase
|
|||||||
{
|
{
|
||||||
Log($"Getting new Chapters for {manga}");
|
Log($"Getting new Chapters for {manga}");
|
||||||
Chapter[] newChapters = this.GetChapters(manga, language);
|
Chapter[] newChapters = this.GetChapters(manga, language);
|
||||||
|
NumberFormatInfo decimalPoint = new (){ NumberDecimalSeparator = "." };
|
||||||
Log($"Checking for duplicates {manga}");
|
Log($"Checking for duplicates {manga}");
|
||||||
List<Chapter> newChaptersList = newChapters.Where(nChapter =>
|
List<Chapter> newChaptersList = newChapters.Where(nChapter =>
|
||||||
float.Parse(nChapter.chapterNumber, numberFormatDecimalPoint) > manga.ignoreChaptersBelow &&
|
float.Parse(nChapter.chapterNumber, decimalPoint) > manga.ignoreChaptersBelow &&
|
||||||
!nChapter.CheckChapterIsDownloaded(settings.downloadLocation)).ToList();
|
!nChapter.CheckChapterIsDownloaded(settings.downloadLocation)).ToList();
|
||||||
Log($"{newChaptersList.Count} new chapters. {manga}");
|
Log($"{newChaptersList.Count} new chapters. {manga}");
|
||||||
|
|
||||||
|
@ -221,8 +221,9 @@ public class MangaDex : MangaConnector
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Return Chapters ordered by Chapter-Number
|
//Return Chapters ordered by Chapter-Number
|
||||||
|
NumberFormatInfo chapterNumberFormatInfo = new() { NumberDecimalSeparator = "." };
|
||||||
Log($"Got {chapters.Count} chapters. {manga}");
|
Log($"Got {chapters.Count} chapters. {manga}");
|
||||||
return chapters.OrderBy(chapter => Convert.ToSingle(chapter.chapterNumber, numberFormatDecimalPoint)).ToArray();
|
return chapters.OrderBy(chapter => Convert.ToSingle(chapter.chapterNumber, chapterNumberFormatInfo)).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override HttpStatusCode DownloadChapter(Chapter chapter, ProgressToken? progressToken = null)
|
public override HttpStatusCode DownloadChapter(Chapter chapter, ProgressToken? progressToken = null)
|
||||||
|
@ -156,9 +156,13 @@ public class MangaKatana : MangaConnector
|
|||||||
return Array.Empty<Chapter>();
|
return Array.Empty<Chapter>();
|
||||||
|
|
||||||
//Return Chapters ordered by Chapter-Number
|
//Return Chapters ordered by Chapter-Number
|
||||||
|
NumberFormatInfo chapterNumberFormatInfo = new()
|
||||||
|
{
|
||||||
|
NumberDecimalSeparator = "."
|
||||||
|
};
|
||||||
List<Chapter> chapters = ParseChaptersFromHtml(manga, requestUrl);
|
List<Chapter> chapters = ParseChaptersFromHtml(manga, requestUrl);
|
||||||
Log($"Got {chapters.Count} chapters. {manga}");
|
Log($"Got {chapters.Count} chapters. {manga}");
|
||||||
return chapters.OrderBy(chapter => Convert.ToSingle(chapter.chapterNumber, numberFormatDecimalPoint)).ToArray();
|
return chapters.OrderBy(chapter => Convert.ToSingle(chapter.chapterNumber, chapterNumberFormatInfo)).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Chapter> ParseChaptersFromHtml(Manga manga, string mangaUrl)
|
private List<Chapter> ParseChaptersFromHtml(Manga manga, string mangaUrl)
|
||||||
|
@ -144,9 +144,13 @@ public class Manganato : MangaConnector
|
|||||||
return Array.Empty<Chapter>();
|
return Array.Empty<Chapter>();
|
||||||
|
|
||||||
//Return Chapters ordered by Chapter-Number
|
//Return Chapters ordered by Chapter-Number
|
||||||
|
NumberFormatInfo chapterNumberFormatInfo = new()
|
||||||
|
{
|
||||||
|
NumberDecimalSeparator = "."
|
||||||
|
};
|
||||||
List<Chapter> chapters = ParseChaptersFromHtml(manga, requestResult.result);
|
List<Chapter> chapters = ParseChaptersFromHtml(manga, requestResult.result);
|
||||||
Log($"Got {chapters.Count} chapters. {manga}");
|
Log($"Got {chapters.Count} chapters. {manga}");
|
||||||
return chapters.OrderBy(chapter => Convert.ToSingle(chapter.chapterNumber, numberFormatDecimalPoint)).ToArray();
|
return chapters.OrderBy(chapter => Convert.ToSingle(chapter.chapterNumber, chapterNumberFormatInfo)).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Chapter> ParseChaptersFromHtml(Manga manga, Stream html)
|
private List<Chapter> ParseChaptersFromHtml(Manga manga, Stream html)
|
||||||
|
@ -235,8 +235,12 @@ public class Mangasee : MangaConnector
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Return Chapters ordered by Chapter-Number
|
//Return Chapters ordered by Chapter-Number
|
||||||
|
NumberFormatInfo chapterNumberFormatInfo = new()
|
||||||
|
{
|
||||||
|
NumberDecimalSeparator = "."
|
||||||
|
};
|
||||||
Log($"Got {chapters.Count} chapters. {manga}");
|
Log($"Got {chapters.Count} chapters. {manga}");
|
||||||
return chapters.OrderBy(chapter => Convert.ToSingle(chapter.chapterNumber, numberFormatDecimalPoint)).ToArray();
|
return chapters.OrderBy(chapter => Convert.ToSingle(chapter.chapterNumber, chapterNumberFormatInfo)).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override HttpStatusCode DownloadChapter(Chapter chapter, ProgressToken? progressToken = null)
|
public override HttpStatusCode DownloadChapter(Chapter chapter, ProgressToken? progressToken = null)
|
||||||
|
@ -222,80 +222,41 @@ public class Server : GlobalBase
|
|||||||
private void HandlePost(HttpListenerRequest request, HttpListenerResponse response)
|
private void HandlePost(HttpListenerRequest request, HttpListenerResponse response)
|
||||||
{
|
{
|
||||||
Dictionary<string, string> requestVariables = GetRequestVariables(request.Url!.Query);
|
Dictionary<string, string> requestVariables = GetRequestVariables(request.Url!.Query);
|
||||||
string? connectorName, internalId, jobId, chapterNumStr, customFolderName;
|
string? connectorName, internalId, jobId;
|
||||||
MangaConnector? connector;
|
MangaConnector connector;
|
||||||
Manga? tmpManga;
|
|
||||||
Manga manga;
|
Manga manga;
|
||||||
Job? job;
|
Job? job;
|
||||||
string path = Regex.Match(request.Url!.LocalPath, @"[A-z0-9]+(\/[A-z0-9]+)*").Value;
|
string path = Regex.Match(request.Url!.LocalPath, @"[A-z0-9]+(\/[A-z0-9]+)*").Value;
|
||||||
switch (path)
|
switch (path)
|
||||||
{
|
{
|
||||||
case "Manga":
|
|
||||||
if(!requestVariables.TryGetValue("internalId", out internalId) ||
|
|
||||||
!_parent.TryGetPublicationById(internalId, out tmpManga))
|
|
||||||
{
|
|
||||||
SendResponse(HttpStatusCode.BadRequest, response);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
manga = (Manga)tmpManga!;
|
|
||||||
SendResponse(HttpStatusCode.OK, response, manga);
|
|
||||||
break;
|
|
||||||
case "Jobs/MonitorManga":
|
case "Jobs/MonitorManga":
|
||||||
if(!requestVariables.TryGetValue("connector", out connectorName) ||
|
if(!requestVariables.TryGetValue("connector", out connectorName) ||
|
||||||
!requestVariables.TryGetValue("internalId", out internalId) ||
|
!requestVariables.TryGetValue("internalId", out internalId) ||
|
||||||
!requestVariables.TryGetValue("interval", out string? intervalStr) ||
|
!requestVariables.TryGetValue("interval", out string? intervalStr) ||
|
||||||
!_parent.TryGetConnector(connectorName, out connector)||
|
_parent.GetConnector(connectorName) is null ||
|
||||||
!_parent.TryGetPublicationById(internalId, out tmpManga) ||
|
_parent.GetPublicationById(internalId) is null ||
|
||||||
!TimeSpan.TryParse(intervalStr, out TimeSpan interval))
|
!TimeSpan.TryParse(intervalStr, out TimeSpan interval))
|
||||||
{
|
{
|
||||||
SendResponse(HttpStatusCode.BadRequest, response);
|
SendResponse(HttpStatusCode.BadRequest, response);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
connector = _parent.GetConnector(connectorName)!;
|
||||||
manga = (Manga)tmpManga!;
|
manga = (Manga)_parent.GetPublicationById(internalId)!;
|
||||||
|
_parent.jobBoss.AddJob(new DownloadNewChapters(this, connector, manga, true, interval));
|
||||||
if (requestVariables.TryGetValue("ignoreBelowChapterNum", out chapterNumStr))
|
|
||||||
{
|
|
||||||
if (!float.TryParse(chapterNumStr, numberFormatDecimalPoint, out float chapterNum))
|
|
||||||
{
|
|
||||||
SendResponse(HttpStatusCode.BadRequest, response);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
manga.ignoreChaptersBelow = chapterNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (requestVariables.TryGetValue("customFolderName", out customFolderName))
|
|
||||||
manga.MovePublicationFolder(settings.downloadLocation, customFolderName);
|
|
||||||
|
|
||||||
_parent.jobBoss.AddJob(new DownloadNewChapters(this, connector!, manga, true, interval));
|
|
||||||
SendResponse(HttpStatusCode.Accepted, response);
|
SendResponse(HttpStatusCode.Accepted, response);
|
||||||
break;
|
break;
|
||||||
case "Jobs/DownloadNewChapters":
|
case "Jobs/DownloadNewChapters":
|
||||||
if(!requestVariables.TryGetValue("connector", out connectorName) ||
|
if(!requestVariables.TryGetValue("connector", out connectorName) ||
|
||||||
!requestVariables.TryGetValue("internalId", out internalId) ||
|
!requestVariables.TryGetValue("internalId", out internalId) ||
|
||||||
!_parent.TryGetConnector(connectorName, out connector)||
|
_parent.GetConnector(connectorName) is null ||
|
||||||
!_parent.TryGetPublicationById(internalId, out tmpManga))
|
_parent.GetPublicationById(internalId) is null)
|
||||||
{
|
{
|
||||||
SendResponse(HttpStatusCode.BadRequest, response);
|
SendResponse(HttpStatusCode.BadRequest, response);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
connector = _parent.GetConnector(connectorName)!;
|
||||||
manga = (Manga)tmpManga!;
|
manga = (Manga)_parent.GetPublicationById(internalId)!;
|
||||||
|
_parent.jobBoss.AddJob(new DownloadNewChapters(this, connector, manga, false));
|
||||||
if (requestVariables.TryGetValue("ignoreBelowChapterNum", out chapterNumStr))
|
|
||||||
{
|
|
||||||
if (!float.TryParse(chapterNumStr, numberFormatDecimalPoint, out float chapterNum))
|
|
||||||
{
|
|
||||||
SendResponse(HttpStatusCode.BadRequest, response);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
manga.ignoreChaptersBelow = chapterNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (requestVariables.TryGetValue("customFolderName", out customFolderName))
|
|
||||||
manga.MovePublicationFolder(settings.downloadLocation, customFolderName);
|
|
||||||
|
|
||||||
_parent.jobBoss.AddJob(new DownloadNewChapters(this, connector!, manga, false));
|
|
||||||
SendResponse(HttpStatusCode.Accepted, response);
|
SendResponse(HttpStatusCode.Accepted, response);
|
||||||
break;
|
break;
|
||||||
case "Jobs/StartNow":
|
case "Jobs/StartNow":
|
||||||
@ -407,27 +368,6 @@ public class Server : GlobalBase
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "LogMessages":
|
|
||||||
if (logger is null || !File.Exists(logger?.logFilePath))
|
|
||||||
{
|
|
||||||
SendResponse(HttpStatusCode.NotFound, response);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
SendResponse(HttpStatusCode.OK, response, logger.GetLog());
|
|
||||||
break;
|
|
||||||
case "LogFile":
|
|
||||||
if (logger is null || !File.Exists(logger?.logFilePath))
|
|
||||||
{
|
|
||||||
SendResponse(HttpStatusCode.NotFound, response);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
string logDir = new FileInfo(logger.logFilePath).DirectoryName!;
|
|
||||||
string tmpFilePath = Path.Join(logDir, "Tranga.log");
|
|
||||||
File.Copy(logger.logFilePath, tmpFilePath);
|
|
||||||
SendResponse(HttpStatusCode.OK, response, new FileStream(tmpFilePath, FileMode.Open));
|
|
||||||
File.Delete(tmpFilePath);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
SendResponse(HttpStatusCode.BadRequest, response);
|
SendResponse(HttpStatusCode.BadRequest, response);
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user