Compare commits

..

No commits in common. "9af5c1603eb085d01e023e5da1b42dafb5afbe5d" and "3b542c04f647dad096e622028db02f8295cb9006" have entirely different histories.

9 changed files with 82 additions and 99 deletions

View File

@ -1,5 +1,4 @@
using System.IO.Compression; using System.IO.Compression;
using System.Net;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Xml.Linq; using System.Xml.Linq;
@ -134,7 +133,7 @@ public abstract class Connector
/// <param name="chapter">Chapter with Images to retrieve</param> /// <param name="chapter">Chapter with Images to retrieve</param>
/// <param name="parentTask">Will be used for progress-tracking</param> /// <param name="parentTask">Will be used for progress-tracking</param>
/// <param name="cancellationToken"></param> /// <param name="cancellationToken"></param>
public abstract HttpStatusCode DownloadChapter(Publication publication, Chapter chapter, DownloadChapterTask parentTask, CancellationToken? cancellationToken = null); public abstract bool DownloadChapter(Publication publication, Chapter chapter, DownloadChapterTask parentTask, CancellationToken? cancellationToken = null);
/// <summary> /// <summary>
/// Copies the already downloaded cover from cache to downloadLocation /// Copies the already downloaded cover from cache to downloadLocation
@ -213,15 +212,15 @@ public abstract class Connector
/// <param name="fullPath"></param> /// <param name="fullPath"></param>
/// <param name="requestType">RequestType for Rate-Limit</param> /// <param name="requestType">RequestType for Rate-Limit</param>
/// <param name="referrer">referrer used in html request header</param> /// <param name="referrer">referrer used in html request header</param>
private HttpStatusCode DownloadImage(string imageUrl, string fullPath, byte requestType, string? referrer = null) private bool DownloadImage(string imageUrl, string fullPath, byte requestType, string? referrer = null)
{ {
DownloadClient.RequestResult requestResult = downloadClient.MakeRequest(imageUrl, requestType, referrer); DownloadClient.RequestResult requestResult = downloadClient.MakeRequest(imageUrl, requestType, referrer);
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300 || requestResult.result == Stream.Null) if (!requestResult.success || requestResult.result == Stream.Null)
return requestResult.statusCode; return false;
byte[] buffer = new byte[requestResult.result.Length]; byte[] buffer = new byte[requestResult.result.Length];
requestResult.result.ReadExactly(buffer, 0, buffer.Length); requestResult.result.ReadExactly(buffer, 0, buffer.Length);
File.WriteAllBytes(fullPath, buffer); File.WriteAllBytes(fullPath, buffer);
return requestResult.statusCode; return true;
} }
/// <summary> /// <summary>
@ -234,10 +233,10 @@ public abstract class Connector
/// <param name="requestType">RequestType for RateLimits</param> /// <param name="requestType">RequestType for RateLimits</param>
/// <param name="referrer">Used in http request header</param> /// <param name="referrer">Used in http request header</param>
/// <param name="cancellationToken"></param> /// <param name="cancellationToken"></param>
protected HttpStatusCode DownloadChapterImages(string[] imageUrls, string saveArchiveFilePath, byte requestType, DownloadChapterTask parentTask, string? comicInfoPath = null, string? referrer = null, CancellationToken? cancellationToken = null) protected bool DownloadChapterImages(string[] imageUrls, string saveArchiveFilePath, byte requestType, DownloadChapterTask parentTask, string? comicInfoPath = null, string? referrer = null, CancellationToken? cancellationToken = null)
{ {
if (cancellationToken?.IsCancellationRequested??false) if (cancellationToken?.IsCancellationRequested??false)
return HttpStatusCode.RequestTimeout; return false;
logger?.WriteLine("Connector", $"Downloading Images for {saveArchiveFilePath}"); logger?.WriteLine("Connector", $"Downloading Images for {saveArchiveFilePath}");
//Check if Publication Directory already exists //Check if Publication Directory already exists
string directoryPath = Path.GetDirectoryName(saveArchiveFilePath)!; string directoryPath = Path.GetDirectoryName(saveArchiveFilePath)!;
@ -245,7 +244,7 @@ public abstract class Connector
Directory.CreateDirectory(directoryPath); Directory.CreateDirectory(directoryPath);
if (File.Exists(saveArchiveFilePath)) //Don't download twice. if (File.Exists(saveArchiveFilePath)) //Don't download twice.
return HttpStatusCode.OK; return false;
//Create a temporary folder to store images //Create a temporary folder to store images
string tempFolder = Directory.CreateTempSubdirectory().FullName; string tempFolder = Directory.CreateTempSubdirectory().FullName;
@ -257,12 +256,11 @@ public abstract class Connector
string[] split = imageUrl.Split('.'); string[] split = imageUrl.Split('.');
string extension = split[^1]; string extension = split[^1];
logger?.WriteLine("Connector", $"Downloading Image {chapter + 1:000}/{imageUrls.Length:000} {parentTask.publication.sortName} {parentTask.publication.internalId} Vol.{parentTask.chapter.volumeNumber} Ch.{parentTask.chapter.chapterNumber} {parentTask.progress:P2}"); logger?.WriteLine("Connector", $"Downloading Image {chapter + 1:000}/{imageUrls.Length:000} {parentTask.publication.sortName} {parentTask.publication.internalId} Vol.{parentTask.chapter.volumeNumber} Ch.{parentTask.chapter.chapterNumber} {parentTask.progress:P2}");
HttpStatusCode status = DownloadImage(imageUrl, Path.Join(tempFolder, $"{chapter++}.{extension}"), requestType, referrer); if (!DownloadImage(imageUrl, Path.Join(tempFolder, $"{chapter++}.{extension}"), requestType, referrer))
if ((int)status < 200 || (int)status >= 300) return false;
return status;
parentTask.IncrementProgress(1.0 / imageUrls.Length); parentTask.IncrementProgress(1.0 / imageUrls.Length);
if (cancellationToken?.IsCancellationRequested??false) if (cancellationToken?.IsCancellationRequested??false)
return HttpStatusCode.RequestTimeout; return false;
} }
if(comicInfoPath is not null) if(comicInfoPath is not null)
@ -274,7 +272,7 @@ public abstract class Connector
if(RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) if(RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
File.SetUnixFileMode(saveArchiveFilePath, GroupRead | GroupWrite | OtherRead | OtherWrite | UserRead | UserWrite); File.SetUnixFileMode(saveArchiveFilePath, GroupRead | GroupWrite | OtherRead | OtherWrite | UserRead | UserWrite);
Directory.Delete(tempFolder, true); //Cleanup Directory.Delete(tempFolder, true); //Cleanup
return HttpStatusCode.OK; return true;
} }
protected string SaveCoverImageToCache(string url, byte requestType) protected string SaveCoverImageToCache(string url, byte requestType)
@ -334,7 +332,7 @@ public abstract class Connector
else else
{ {
logger?.WriteLine(this.GetType().ToString(), "RequestType not configured for rate-limit."); logger?.WriteLine(this.GetType().ToString(), "RequestType not configured for rate-limit.");
return new RequestResult(HttpStatusCode.NotAcceptable, Stream.Null); return new RequestResult(false, Stream.Null);
} }
TimeSpan rateLimitTimeout = _rateLimit[requestType] TimeSpan rateLimitTimeout = _rateLimit[requestType]
@ -364,19 +362,19 @@ public abstract class Connector
if (!response.IsSuccessStatusCode) if (!response.IsSuccessStatusCode)
{ {
logger?.WriteLine(this.GetType().ToString(), $"Request-Error {response.StatusCode}: {response.ReasonPhrase}"); logger?.WriteLine(this.GetType().ToString(), $"Request-Error {response.StatusCode}: {response.ReasonPhrase}");
return new RequestResult(response.StatusCode, Stream.Null); return new RequestResult(false, Stream.Null);
} }
return new RequestResult(response.StatusCode, response.Content.ReadAsStream()); return new RequestResult(true, response.Content.ReadAsStream());
} }
public struct RequestResult public struct RequestResult
{ {
public HttpStatusCode statusCode { get; } public bool success { get; }
public Stream result { get; } public Stream result { get; }
public RequestResult(HttpStatusCode statusCode, Stream result) public RequestResult(bool success, Stream result)
{ {
this.statusCode = statusCode; this.success = success;
this.result = result; this.result = result;
} }
} }

View File

@ -46,7 +46,7 @@ public class MangaDex : Connector
DownloadClient.RequestResult requestResult = DownloadClient.RequestResult requestResult =
downloadClient.MakeRequest( downloadClient.MakeRequest(
$"https://api.mangadex.org/manga?limit={limit}&title={publicationTitle}&offset={offset}", (byte)RequestType.Manga); $"https://api.mangadex.org/manga?limit={limit}&title={publicationTitle}&offset={offset}", (byte)RequestType.Manga);
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300) if (!requestResult.success)
break; break;
JsonObject? result = JsonSerializer.Deserialize<JsonObject>(requestResult.result); JsonObject? result = JsonSerializer.Deserialize<JsonObject>(requestResult.result);
@ -165,7 +165,7 @@ public class MangaDex : Connector
DownloadClient.RequestResult requestResult = DownloadClient.RequestResult requestResult =
downloadClient.MakeRequest( downloadClient.MakeRequest(
$"https://api.mangadex.org/manga/{publication.publicationId}/feed?limit={limit}&offset={offset}&translatedLanguage%5B%5D={language}", (byte)RequestType.Feed); $"https://api.mangadex.org/manga/{publication.publicationId}/feed?limit={limit}&offset={offset}&translatedLanguage%5B%5D={language}", (byte)RequestType.Feed);
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300) if (!requestResult.success)
break; break;
JsonObject? result = JsonSerializer.Deserialize<JsonObject>(requestResult.result); JsonObject? result = JsonSerializer.Deserialize<JsonObject>(requestResult.result);
@ -207,19 +207,19 @@ public class MangaDex : Connector
return chapters.OrderBy(chapter => Convert.ToSingle(chapter.chapterNumber, chapterNumberFormatInfo)).ToArray(); return chapters.OrderBy(chapter => Convert.ToSingle(chapter.chapterNumber, chapterNumberFormatInfo)).ToArray();
} }
public override HttpStatusCode DownloadChapter(Publication publication, Chapter chapter, DownloadChapterTask parentTask, CancellationToken? cancellationToken = null) public override bool DownloadChapter(Publication publication, Chapter chapter, DownloadChapterTask parentTask, CancellationToken? cancellationToken = null)
{ {
if (cancellationToken?.IsCancellationRequested??false) if (cancellationToken?.IsCancellationRequested??false)
return HttpStatusCode.RequestTimeout; return false;
logger?.WriteLine(this.GetType().ToString(), $"Downloading Chapter-Info {publication.sortName} {publication.internalId} {chapter.volumeNumber}-{chapter.chapterNumber}"); logger?.WriteLine(this.GetType().ToString(), $"Downloading Chapter-Info {publication.sortName} {publication.internalId} {chapter.volumeNumber}-{chapter.chapterNumber}");
//Request URLs for Chapter-Images //Request URLs for Chapter-Images
DownloadClient.RequestResult requestResult = DownloadClient.RequestResult requestResult =
downloadClient.MakeRequest($"https://api.mangadex.org/at-home/server/{chapter.url}?forcePort443=false'", (byte)RequestType.AtHomeServer); downloadClient.MakeRequest($"https://api.mangadex.org/at-home/server/{chapter.url}?forcePort443=false'", (byte)RequestType.AtHomeServer);
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300) if (!requestResult.success)
return requestResult.statusCode; return false;
JsonObject? result = JsonSerializer.Deserialize<JsonObject>(requestResult.result); JsonObject? result = JsonSerializer.Deserialize<JsonObject>(requestResult.result);
if (result is null) if (result is null)
return HttpStatusCode.NoContent; return false;
string baseUrl = result["baseUrl"]!.GetValue<string>(); string baseUrl = result["baseUrl"]!.GetValue<string>();
string hash = result["chapter"]!["hash"]!.GetValue<string>(); string hash = result["chapter"]!["hash"]!.GetValue<string>();
@ -248,7 +248,7 @@ public class MangaDex : Connector
//Request information where to download Cover //Request information where to download Cover
DownloadClient.RequestResult requestResult = DownloadClient.RequestResult requestResult =
downloadClient.MakeRequest($"https://api.mangadex.org/cover/{posterId}", (byte)RequestType.CoverUrl); downloadClient.MakeRequest($"https://api.mangadex.org/cover/{posterId}", (byte)RequestType.CoverUrl);
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300) if (!requestResult.success)
return null; return null;
JsonObject? result = JsonSerializer.Deserialize<JsonObject>(requestResult.result); JsonObject? result = JsonSerializer.Deserialize<JsonObject>(requestResult.result);
if (result is null) if (result is null)
@ -268,7 +268,7 @@ public class MangaDex : Connector
{ {
DownloadClient.RequestResult requestResult = DownloadClient.RequestResult requestResult =
downloadClient.MakeRequest($"https://api.mangadex.org/author/{authorId}", (byte)RequestType.Author); downloadClient.MakeRequest($"https://api.mangadex.org/author/{authorId}", (byte)RequestType.Author);
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300) if (!requestResult.success)
return ret; return ret;
JsonObject? result = JsonSerializer.Deserialize<JsonObject>(requestResult.result); JsonObject? result = JsonSerializer.Deserialize<JsonObject>(requestResult.result);
if (result is null) if (result is null)

View File

@ -27,7 +27,7 @@ public class Manganato : Connector
string requestUrl = $"https://manganato.com/search/story/{sanitizedTitle}"; string requestUrl = $"https://manganato.com/search/story/{sanitizedTitle}";
DownloadClient.RequestResult requestResult = DownloadClient.RequestResult requestResult =
downloadClient.MakeRequest(requestUrl, (byte)1); downloadClient.MakeRequest(requestUrl, (byte)1);
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300) if (!requestResult.success)
return Array.Empty<Publication>(); return Array.Empty<Publication>();
return ParsePublicationsFromHtml(requestResult.result); return ParsePublicationsFromHtml(requestResult.result);
@ -52,7 +52,7 @@ public class Manganato : Connector
{ {
DownloadClient.RequestResult requestResult = DownloadClient.RequestResult requestResult =
downloadClient.MakeRequest(url, (byte)1); downloadClient.MakeRequest(url, (byte)1);
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300) if (!requestResult.success)
return Array.Empty<Publication>(); return Array.Empty<Publication>();
ret.Add(ParseSinglePublicationFromHtml(requestResult.result, url.Split('/')[^1])); ret.Add(ParseSinglePublicationFromHtml(requestResult.result, url.Split('/')[^1]));
@ -131,7 +131,7 @@ public class Manganato : Connector
string requestUrl = $"https://chapmanganato.com/{publication.publicationId}"; string requestUrl = $"https://chapmanganato.com/{publication.publicationId}";
DownloadClient.RequestResult requestResult = DownloadClient.RequestResult requestResult =
downloadClient.MakeRequest(requestUrl, (byte)1); downloadClient.MakeRequest(requestUrl, (byte)1);
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300) if (!requestResult.success)
return Array.Empty<Chapter>(); return Array.Empty<Chapter>();
//Return Chapters ordered by Chapter-Number //Return Chapters ordered by Chapter-Number
@ -169,16 +169,16 @@ public class Manganato : Connector
return ret; return ret;
} }
public override HttpStatusCode DownloadChapter(Publication publication, Chapter chapter, DownloadChapterTask parentTask, CancellationToken? cancellationToken = null) public override bool DownloadChapter(Publication publication, Chapter chapter, DownloadChapterTask parentTask, CancellationToken? cancellationToken = null)
{ {
if (cancellationToken?.IsCancellationRequested??false) if (cancellationToken?.IsCancellationRequested??false)
return HttpStatusCode.RequestTimeout; return false;
logger?.WriteLine(this.GetType().ToString(), $"Downloading Chapter-Info {publication.sortName} {publication.internalId} {chapter.volumeNumber}-{chapter.chapterNumber}"); logger?.WriteLine(this.GetType().ToString(), $"Downloading Chapter-Info {publication.sortName} {publication.internalId} {chapter.volumeNumber}-{chapter.chapterNumber}");
string requestUrl = chapter.url; string requestUrl = chapter.url;
DownloadClient.RequestResult requestResult = DownloadClient.RequestResult requestResult =
downloadClient.MakeRequest(requestUrl, (byte)1); downloadClient.MakeRequest(requestUrl, (byte)1);
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300) if (!requestResult.success)
return requestResult.statusCode; return false;
string[] imageUrls = ParseImageUrlsFromHtml(requestResult.result); string[] imageUrls = ParseImageUrlsFromHtml(requestResult.result);

View File

@ -80,7 +80,7 @@ public class Mangasee : Connector
string requestUrl = $"https://mangasee123.com/_search.php"; string requestUrl = $"https://mangasee123.com/_search.php";
DownloadClient.RequestResult requestResult = DownloadClient.RequestResult requestResult =
downloadClient.MakeRequest(requestUrl, (byte)1); downloadClient.MakeRequest(requestUrl, (byte)1);
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300) if (!requestResult.success)
return Array.Empty<Publication>(); return Array.Empty<Publication>();
return ParsePublicationsFromHtml(requestResult.result, publicationTitle); return ParsePublicationsFromHtml(requestResult.result, publicationTitle);
@ -110,7 +110,7 @@ public class Mangasee : Connector
{ {
DownloadClient.RequestResult requestResult = DownloadClient.RequestResult requestResult =
downloadClient.MakeRequest($"https://mangasee123.com/manga/{orderedItem.i}", (byte)1); downloadClient.MakeRequest($"https://mangasee123.com/manga/{orderedItem.i}", (byte)1);
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300) if (!requestResult.success)
return Array.Empty<Publication>(); return Array.Empty<Publication>();
ret.Add(ParseSinglePublicationFromHtml(requestResult.result, orderedItem.s, orderedItem.i, orderedItem.a)); ret.Add(ParseSinglePublicationFromHtml(requestResult.result, orderedItem.s, orderedItem.i, orderedItem.a));
} }
@ -209,17 +209,17 @@ public class Mangasee : Connector
return ret.OrderBy(chapter => Convert.ToSingle(chapter.chapterNumber, chapterNumberFormatInfo)).ToArray(); return ret.OrderBy(chapter => Convert.ToSingle(chapter.chapterNumber, chapterNumberFormatInfo)).ToArray();
} }
public override HttpStatusCode DownloadChapter(Publication publication, Chapter chapter, DownloadChapterTask parentTask, CancellationToken? cancellationToken = null) public override bool DownloadChapter(Publication publication, Chapter chapter, DownloadChapterTask parentTask, CancellationToken? cancellationToken = null)
{ {
if (cancellationToken?.IsCancellationRequested ?? false) if (cancellationToken?.IsCancellationRequested ?? false)
return HttpStatusCode.RequestTimeout; return false;
while (this._browser is null && !(cancellationToken?.IsCancellationRequested??false)) while (this._browser is null && !(cancellationToken?.IsCancellationRequested??false))
{ {
logger?.WriteLine(this.GetType().ToString(), "Waiting for headless browser to download..."); logger?.WriteLine(this.GetType().ToString(), "Waiting for headless browser to download...");
Thread.Sleep(1000); Thread.Sleep(1000);
} }
if (cancellationToken?.IsCancellationRequested??false) if (cancellationToken?.IsCancellationRequested??false)
return HttpStatusCode.RequestTimeout; return false;
logger?.WriteLine(this.GetType().ToString(), $"Downloading Chapter-Info {publication.sortName} {publication.internalId} {chapter.volumeNumber}-{chapter.chapterNumber}"); logger?.WriteLine(this.GetType().ToString(), $"Downloading Chapter-Info {publication.sortName} {publication.internalId} {chapter.volumeNumber}-{chapter.chapterNumber}");
IPage page = _browser!.NewPageAsync().Result; IPage page = _browser!.NewPageAsync().Result;
@ -240,6 +240,7 @@ public class Mangasee : Connector
return DownloadChapterImages(urls.ToArray(), GetArchiveFilePath(publication, chapter), (byte)1, parentTask, comicInfoPath, cancellationToken:cancellationToken); return DownloadChapterImages(urls.ToArray(), GetArchiveFilePath(publication, chapter), (byte)1, parentTask, comicInfoPath, cancellationToken:cancellationToken);
} }
return response.Status;
return false;
} }
} }

View File

@ -82,21 +82,18 @@ public class TaskManager
} }
} }
TrangaTask[] failedDownloadChapterTasks = _allTasks.Where(taskQuery => foreach (TrangaTask failedTask in _allTasks.Where(taskQuery =>
taskQuery.state is TrangaTask.ExecutionState.Failed && taskQuery is DownloadChapterTask).ToArray(); taskQuery.state is TrangaTask.ExecutionState.Failed))
foreach (TrangaTask failedDownloadChapterTask in failedDownloadChapterTasks)
{ {
DeleteTask(failedDownloadChapterTask); switch (failedTask.task)
TrangaTask newTask = failedDownloadChapterTask.Clone(); {
failedDownloadChapterTask.parentTask?.AddChildTask(newTask); case TrangaTask.Task.DownloadChapter:
DeleteTask(failedTask);
TrangaTask newTask = failedTask.Clone();
failedTask.parentTask?.AddChildTask(newTask);
AddTask(newTask); AddTask(newTask);
break;
} }
TrangaTask[] successfulDownloadChapterTasks = _allTasks.Where(taskQuery =>
taskQuery.state is TrangaTask.ExecutionState.Success && taskQuery is DownloadChapterTask).ToArray();
foreach(TrangaTask successfulDownloadChapterTask in successfulDownloadChapterTasks)
{
DeleteTask(successfulDownloadChapterTask);
} }
if(waitingTasksCount != _allTasks.Count(task => task.state is TrangaTask.ExecutionState.Waiting)) if(waitingTasksCount != _allTasks.Count(task => task.state is TrangaTask.ExecutionState.Waiting))

View File

@ -1,5 +1,4 @@
using System.Net; using System.Text.Json.Serialization;
using System.Text.Json.Serialization;
using Logging; using Logging;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
@ -33,7 +32,7 @@ public abstract class TrangaTask
[Newtonsoft.Json.JsonIgnore]public TimeSpan executionApproximatelyRemaining => executionApproximatelyFinished.Subtract(DateTime.Now); [Newtonsoft.Json.JsonIgnore]public TimeSpan executionApproximatelyRemaining => executionApproximatelyFinished.Subtract(DateTime.Now);
[Newtonsoft.Json.JsonIgnore]public DateTime nextExecution => lastExecuted.Add(reoccurrence); [Newtonsoft.Json.JsonIgnore]public DateTime nextExecution => lastExecuted.Add(reoccurrence);
public enum ExecutionState { Waiting, Enqueued, Running, Failed, Success } public enum ExecutionState { Waiting, Enqueued, Running, Failed }
protected TrangaTask(Task task, TimeSpan reoccurrence, TrangaTask? parentTask = null) protected TrangaTask(Task task, TimeSpan reoccurrence, TrangaTask? parentTask = null)
{ {
@ -54,7 +53,7 @@ public abstract class TrangaTask
/// <param name="taskManager"></param> /// <param name="taskManager"></param>
/// <param name="logger"></param> /// <param name="logger"></param>
/// <param name="cancellationToken"></param> /// <param name="cancellationToken"></param>
protected abstract HttpStatusCode ExecuteTask(TaskManager taskManager, Logger? logger, CancellationToken? cancellationToken = null); protected abstract bool ExecuteTask(TaskManager taskManager, Logger? logger, CancellationToken? cancellationToken = null);
public abstract TrangaTask Clone(); public abstract TrangaTask Clone();
@ -70,31 +69,21 @@ public abstract class TrangaTask
{ {
logger?.WriteLine(this.GetType().ToString(), $"Executing Task {this}"); logger?.WriteLine(this.GetType().ToString(), $"Executing Task {this}");
this.state = ExecutionState.Running; this.state = ExecutionState.Running;
if(this.parentTask is not null)
this.parentTask.state = ExecutionState.Running;
this.executionStarted = DateTime.Now; this.executionStarted = DateTime.Now;
this.lastChange = DateTime.Now; this.lastChange = DateTime.Now;
HttpStatusCode statusCode = ExecuteTask(taskManager, logger, cancellationToken); bool success = ExecuteTask(taskManager, logger, cancellationToken);
while(childTasks.Any(ct => ct.state is ExecutionState.Enqueued or ExecutionState.Running)) while(childTasks.Any(ct => ct.state is ExecutionState.Enqueued or ExecutionState.Running))
Thread.Sleep(1000); Thread.Sleep(1000);
if ((int)statusCode >= 200 && (int)statusCode < 300) if (success)
{ {
this.lastExecuted = DateTime.Now; this.lastExecuted = DateTime.Now;
if (this is DownloadChapterTask)
this.state = ExecutionState.Success;
else
this.state = ExecutionState.Waiting; this.state = ExecutionState.Waiting;
} }
else else
{ {
if (this is DownloadChapterTask && statusCode == HttpStatusCode.NotFound)
this.state = ExecutionState.Success;
else
this.state = ExecutionState.Failed;
this.lastExecuted = DateTime.MaxValue; this.lastExecuted = DateTime.MaxValue;
this.state = ExecutionState.Failed;
} }
if(this.parentTask is not null)
this.parentTask.state = ExecutionState.Waiting;
logger?.WriteLine(this.GetType().ToString(), $"Finished Executing Task {this}"); logger?.WriteLine(this.GetType().ToString(), $"Finished Executing Task {this}");
} }
@ -110,8 +99,8 @@ public abstract class TrangaTask
private TimeSpan GetRemainingTime() private TimeSpan GetRemainingTime()
{ {
if(progress == 0 || lastChange == DateTime.MaxValue || executionStarted == DateTime.UnixEpoch) if(progress == 0 || lastChange > executionStarted)
return TimeSpan.Zero; return DateTime.MaxValue.Subtract(DateTime.Now.AddYears(1));
TimeSpan elapsed = lastChange.Subtract(executionStarted); TimeSpan elapsed = lastChange.Subtract(executionStarted);
return elapsed.Divide(progress).Subtract(elapsed); return elapsed.Divide(progress).Subtract(elapsed);
} }

View File

@ -1,5 +1,4 @@
using System.Net; using Logging;
using Logging;
namespace Tranga.TrangaTasks; namespace Tranga.TrangaTasks;
@ -20,14 +19,15 @@ public class DownloadChapterTask : TrangaTask
this.language = language; this.language = language;
} }
protected override HttpStatusCode ExecuteTask(TaskManager taskManager, Logger? logger, CancellationToken? cancellationToken = null) protected override bool ExecuteTask(TaskManager taskManager, Logger? logger, CancellationToken? cancellationToken = null)
{ {
if (cancellationToken?.IsCancellationRequested??false) if (cancellationToken?.IsCancellationRequested??false)
return HttpStatusCode.RequestTimeout; return false;
Connector connector = taskManager.GetConnector(this.connectorName); Connector connector = taskManager.GetConnector(this.connectorName);
connector.CopyCoverFromCacheToDownloadLocation(this.publication, taskManager.settings); connector.CopyCoverFromCacheToDownloadLocation(this.publication, taskManager.settings);
HttpStatusCode downloadSuccess = connector.DownloadChapter(this.publication, this.chapter, this, cancellationToken); bool downloadSuccess = connector.DownloadChapter(this.publication, this.chapter, this, cancellationToken);
if((int)downloadSuccess >= 200 && (int)downloadSuccess < 300 && parentTask is not null) taskManager.DeleteTask(this);
if(downloadSuccess && parentTask is not null)
foreach(NotificationManager nm in taskManager.settings.notificationManagers) foreach(NotificationManager nm in taskManager.settings.notificationManagers)
nm.SendNotification("New Chapter downloaded", $"{this.publication.sortName} {this.chapter.chapterNumber} {this.chapter.name}"); nm.SendNotification("New Chapter downloaded", $"{this.publication.sortName} {this.chapter.chapterNumber} {this.chapter.name}");
return downloadSuccess; return downloadSuccess;

View File

@ -1,5 +1,4 @@
using System.Net; using Logging;
using Logging;
namespace Tranga.TrangaTasks; namespace Tranga.TrangaTasks;
@ -15,10 +14,10 @@ public class MonitorPublicationTask : TrangaTask
this.language = language; this.language = language;
} }
protected override HttpStatusCode ExecuteTask(TaskManager taskManager, Logger? logger, CancellationToken? cancellationToken = null) protected override bool ExecuteTask(TaskManager taskManager, Logger? logger, CancellationToken? cancellationToken = null)
{ {
if (cancellationToken?.IsCancellationRequested??false) if (cancellationToken?.IsCancellationRequested??false)
return HttpStatusCode.RequestTimeout; return false;
Connector connector = taskManager.GetConnector(this.connectorName); Connector connector = taskManager.GetConnector(this.connectorName);
//Check if Publication already has a Folder //Check if Publication already has a Folder
@ -37,7 +36,7 @@ public class MonitorPublicationTask : TrangaTask
taskManager.AddTask(newTask); taskManager.AddTask(newTask);
} }
return HttpStatusCode.OK; return true;
} }
public override TrangaTask Clone() public override TrangaTask Clone()

View File

@ -1,5 +1,4 @@
using System.Net; using Logging;
using Logging;
namespace Tranga.TrangaTasks; namespace Tranga.TrangaTasks;
@ -9,13 +8,13 @@ public class UpdateLibrariesTask : TrangaTask
{ {
} }
protected override HttpStatusCode ExecuteTask(TaskManager taskManager, Logger? logger, CancellationToken? cancellationToken = null) protected override bool ExecuteTask(TaskManager taskManager, Logger? logger, CancellationToken? cancellationToken = null)
{ {
if (cancellationToken?.IsCancellationRequested??false) if (cancellationToken?.IsCancellationRequested??false)
return HttpStatusCode.RequestTimeout; return false;
foreach(LibraryManager lm in taskManager.settings.libraryManagers) foreach(LibraryManager lm in taskManager.settings.libraryManagers)
lm.UpdateLibrary(); lm.UpdateLibrary();
return HttpStatusCode.OK; return true;
} }
public override TrangaTask Clone() public override TrangaTask Clone()