mirror of
https://github.com/C9Glax/tranga.git
synced 2025-07-01 16:34:17 +02:00
Compare commits
8 Commits
1.4
...
87eade10cf
Author | SHA1 | Date | |
---|---|---|---|
87eade10cf | |||
1f3ac41b30 | |||
6a304bb330 | |||
b0642d1251 | |||
63b5139e93 | |||
e938784388 | |||
c436389426 | |||
5099e25f3f |
@ -6,9 +6,9 @@ COPY . /src/
|
|||||||
RUN dotnet restore Tranga-API/Tranga-API.csproj
|
RUN dotnet restore Tranga-API/Tranga-API.csproj
|
||||||
RUN dotnet publish -c Release -o /publish
|
RUN dotnet publish -c Release -o /publish
|
||||||
|
|
||||||
FROM mcr.microsoft.com/dotnet/aspnet:7.0 as runtime
|
#FROM mcr.microsoft.com/dotnet/aspnet:7.0 as runtime
|
||||||
|
FROM glax/tranga-base:latest as runtime
|
||||||
WORKDIR /publish
|
WORKDIR /publish
|
||||||
COPY --from=build-env /publish .
|
COPY --from=build-env /publish .
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
RUN apt-get update && apt-get install -y libx11-6 libx11-xcb1 libatk1.0-0 libgtk-3-0 libcups2 libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 libxrandr2 libgbm1 libpango-1.0-0 libcairo2 libasound2 libxshmfence1 libnss3
|
|
||||||
ENTRYPOINT ["dotnet", "/publish/Tranga-API.dll"]
|
ENTRYPOINT ["dotnet", "/publish/Tranga-API.dll"]
|
||||||
|
4
Dockerfile-base
Normal file
4
Dockerfile-base
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# syntax=docker/dockerfile:1
|
||||||
|
FROM mcr.microsoft.com/dotnet/aspnet:7.0 as runtime
|
||||||
|
WORKDIR /publish
|
||||||
|
RUN apt-get update && apt-get install -y libx11-6 libx11-xcb1 libatk1.0-0 libgtk-3-0 libcups2 libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 libxrandr2 libgbm1 libpango-1.0-0 libcairo2 libasound2 libxshmfence1 libnss3
|
@ -71,10 +71,10 @@ app.MapGet("/Tranga/GetPublicationsFromConnector", (string connectorName, string
|
|||||||
app.MapGet("/Tasks/GetTaskTypes", () => Enum.GetNames(typeof(TrangaTask.Task)));
|
app.MapGet("/Tasks/GetTaskTypes", () => Enum.GetNames(typeof(TrangaTask.Task)));
|
||||||
|
|
||||||
|
|
||||||
app.MapPost("/Tasks/Create", (string taskType, string? connectorName, string? publicationId, string reoccurrenceTime, string? language) =>
|
app.MapPost("/Tasks/Create", (string taskType, string? connectorName, string? internalId, string reoccurrenceTime, string? language) =>
|
||||||
{
|
{
|
||||||
TrangaTask.Task task = Enum.Parse<TrangaTask.Task>(taskType);
|
TrangaTask.Task task = Enum.Parse<TrangaTask.Task>(taskType);
|
||||||
taskManager.AddTask(task, connectorName, publicationId, TimeSpan.Parse(reoccurrenceTime), language??"");
|
taskManager.AddTask(task, connectorName, internalId, TimeSpan.Parse(reoccurrenceTime), language);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.MapDelete("/Tasks/Delete", (string taskType, string? connectorName, string? publicationId) =>
|
app.MapDelete("/Tasks/Delete", (string taskType, string? connectorName, string? publicationId) =>
|
||||||
|
@ -13,12 +13,14 @@ namespace Tranga;
|
|||||||
public class TaskManager
|
public class TaskManager
|
||||||
{
|
{
|
||||||
public Dictionary<Publication, List<Chapter>> chapterCollection = new();
|
public Dictionary<Publication, List<Chapter>> chapterCollection = new();
|
||||||
private HashSet<TrangaTask> _allTasks = new HashSet<TrangaTask>();
|
private HashSet<TrangaTask> _allTasks = new();
|
||||||
private bool _continueRunning = true;
|
private bool _continueRunning = true;
|
||||||
private readonly Connector[] _connectors;
|
private readonly Connector[] _connectors;
|
||||||
public TrangaSettings settings { get; }
|
public TrangaSettings settings { get; }
|
||||||
private Logger? logger { get; }
|
private Logger? logger { get; }
|
||||||
|
|
||||||
|
private readonly Dictionary<DownloadChapterTask, Task> _runningDownloadChapterTasks = new();
|
||||||
|
|
||||||
/// <param name="downloadFolderPath">Local path to save data (Manga) to</param>
|
/// <param name="downloadFolderPath">Local path to save data (Manga) to</param>
|
||||||
/// <param name="workingDirectory">Path to the working directory</param>
|
/// <param name="workingDirectory">Path to the working directory</param>
|
||||||
/// <param name="imageCachePath">Path to the cover-image cache</param>
|
/// <param name="imageCachePath">Path to the cover-image cache</param>
|
||||||
@ -117,6 +119,25 @@ public class TaskManager
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HashSet<DownloadChapterTask> toRemove = new();
|
||||||
|
foreach (KeyValuePair<DownloadChapterTask,Task> removeTask in _runningDownloadChapterTasks)
|
||||||
|
{
|
||||||
|
if (removeTask.Key.GetType() == typeof(DownloadChapterTask) &&
|
||||||
|
DateTime.Now.Subtract(removeTask.Key.lastChange) > TimeSpan.FromMinutes(3))//3 Minutes since last update to task -> remove
|
||||||
|
{
|
||||||
|
logger?.WriteLine(this.GetType().ToString(), $"Removing failed task {removeTask}.");
|
||||||
|
removeTask.Value.Dispose();
|
||||||
|
DeleteTask(removeTask.Key);
|
||||||
|
AddTask(new DownloadChapterTask(removeTask.Key.task, removeTask.Key.connectorName,
|
||||||
|
removeTask.Key.publication, removeTask.Key.chapter, removeTask.Key.language,
|
||||||
|
removeTask.Key.parentTask));
|
||||||
|
toRemove.Add(removeTask.Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (DownloadChapterTask taskToRemove in toRemove)
|
||||||
|
_runningDownloadChapterTasks.Remove(taskToRemove);
|
||||||
|
|
||||||
if(allTasksWaitingLength != _allTasks.Count(task => task.state is TrangaTask.ExecutionState.Waiting))
|
if(allTasksWaitingLength != _allTasks.Count(task => task.state is TrangaTask.ExecutionState.Waiting))
|
||||||
ExportDataAndSettings();
|
ExportDataAndSettings();
|
||||||
allTasksWaitingLength = _allTasks.Count(task => task.state is TrangaTask.ExecutionState.Waiting);
|
allTasksWaitingLength = _allTasks.Count(task => task.state is TrangaTask.ExecutionState.Waiting);
|
||||||
@ -135,6 +156,8 @@ public class TaskManager
|
|||||||
{
|
{
|
||||||
task.Execute(this, this.logger);
|
task.Execute(this, this.logger);
|
||||||
});
|
});
|
||||||
|
if(task.GetType() == typeof(DownloadChapterTask))
|
||||||
|
_runningDownloadChapterTasks.Add((DownloadChapterTask)task, t);
|
||||||
t.Start();
|
t.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,9 +175,9 @@ public class TaskManager
|
|||||||
case TrangaTask.Task.DownloadNewChapters:
|
case TrangaTask.Task.DownloadNewChapters:
|
||||||
IEnumerable<TrangaTask> matchingdnc =
|
IEnumerable<TrangaTask> matchingdnc =
|
||||||
_allTasks.Where(mTask => mTask.GetType() == typeof(DownloadNewChaptersTask));
|
_allTasks.Where(mTask => mTask.GetType() == typeof(DownloadNewChaptersTask));
|
||||||
if (matchingdnc.All(mTask =>
|
if (!matchingdnc.Any(mTask =>
|
||||||
((DownloadNewChaptersTask)mTask).publication.internalId != ((DownloadNewChaptersTask)newTask).publication.publicationId &&
|
((DownloadNewChaptersTask)mTask).publication.internalId == ((DownloadNewChaptersTask)newTask).publication.internalId &&
|
||||||
((DownloadNewChaptersTask)mTask).connectorName != ((DownloadNewChaptersTask)newTask).connectorName))
|
((DownloadNewChaptersTask)mTask).connectorName == ((DownloadNewChaptersTask)newTask).connectorName))
|
||||||
_allTasks.Add(newTask);
|
_allTasks.Add(newTask);
|
||||||
else
|
else
|
||||||
logger?.WriteLine(this.GetType().ToString(), $"Task already exists {newTask}");
|
logger?.WriteLine(this.GetType().ToString(), $"Task already exists {newTask}");
|
||||||
@ -180,7 +203,7 @@ public class TaskManager
|
|||||||
_allTasks.Remove(removeTask);
|
_allTasks.Remove(removeTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TrangaTask? AddTask(TrangaTask.Task taskType, string? connectorName, string? publicationId,
|
public TrangaTask? AddTask(TrangaTask.Task taskType, string? connectorName, string? internalId,
|
||||||
TimeSpan reoccurrenceTime, string? language = "en")
|
TimeSpan reoccurrenceTime, string? language = "en")
|
||||||
{
|
{
|
||||||
TrangaTask? newTask = null;
|
TrangaTask? newTask = null;
|
||||||
@ -190,10 +213,16 @@ public class TaskManager
|
|||||||
newTask = new UpdateLibrariesTask(taskType, reoccurrenceTime);
|
newTask = new UpdateLibrariesTask(taskType, reoccurrenceTime);
|
||||||
break;
|
break;
|
||||||
case TrangaTask.Task.DownloadNewChapters:
|
case TrangaTask.Task.DownloadNewChapters:
|
||||||
if(connectorName is null || publicationId is null || language is null)
|
if (connectorName is null)
|
||||||
logger?.WriteLine(this.GetType().ToString(), $"Values connectorName, publicationName and language can not be null.");
|
logger?.WriteLine(this.GetType().ToString(), $"Value connectorName can not be null.");
|
||||||
|
if(internalId is null)
|
||||||
|
logger?.WriteLine(this.GetType().ToString(), $"Value internalId can not be null.");
|
||||||
|
if(language is null)
|
||||||
|
logger?.WriteLine(this.GetType().ToString(), $"Value language can not be null.");
|
||||||
|
if (connectorName is null || internalId is null || language is null)
|
||||||
|
return null;
|
||||||
GetConnector(connectorName); //Check if connectorName is valid
|
GetConnector(connectorName); //Check if connectorName is valid
|
||||||
Publication publication = GetAllPublications().First(pub => pub.internalId == publicationId);
|
Publication publication = GetAllPublications().First(pub => pub.internalId == internalId);
|
||||||
newTask = new DownloadNewChaptersTask(taskType, connectorName!, publication, reoccurrenceTime, language!);
|
newTask = new DownloadNewChaptersTask(taskType, connectorName!, publication, reoccurrenceTime, language!);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ public abstract class TrangaTask
|
|||||||
[Newtonsoft.Json.JsonIgnore]public ExecutionState state { get; set; }
|
[Newtonsoft.Json.JsonIgnore]public ExecutionState state { get; set; }
|
||||||
[Newtonsoft.Json.JsonIgnore]public float progress { get; protected set; }
|
[Newtonsoft.Json.JsonIgnore]public float progress { get; protected set; }
|
||||||
[Newtonsoft.Json.JsonIgnore]public DateTime nextExecution => lastExecuted.Add(reoccurrence);
|
[Newtonsoft.Json.JsonIgnore]public DateTime nextExecution => lastExecuted.Add(reoccurrence);
|
||||||
[Newtonsoft.Json.JsonIgnore]public DateTime executionStarted { get; protected set; }
|
[Newtonsoft.Json.JsonIgnore]public DateTime executionStarted { get; private set; }
|
||||||
|
|
||||||
[Newtonsoft.Json.JsonIgnore]
|
[Newtonsoft.Json.JsonIgnore]
|
||||||
public DateTime executionApproximatelyFinished => this.progress != 0
|
public DateTime executionApproximatelyFinished => this.progress != 0
|
||||||
@ -33,6 +33,8 @@ public abstract class TrangaTask
|
|||||||
[Newtonsoft.Json.JsonIgnore]
|
[Newtonsoft.Json.JsonIgnore]
|
||||||
public TimeSpan executionApproximatelyRemaining => this.executionApproximatelyFinished.Subtract(DateTime.Now);
|
public TimeSpan executionApproximatelyRemaining => this.executionApproximatelyFinished.Subtract(DateTime.Now);
|
||||||
|
|
||||||
|
[Newtonsoft.Json.JsonIgnore]public DateTime lastChange { get; protected set; }
|
||||||
|
|
||||||
public enum ExecutionState
|
public enum ExecutionState
|
||||||
{
|
{
|
||||||
Waiting,
|
Waiting,
|
||||||
@ -47,11 +49,13 @@ public abstract class TrangaTask
|
|||||||
this.task = task;
|
this.task = task;
|
||||||
this.progress = 0f;
|
this.progress = 0f;
|
||||||
this.executionStarted = DateTime.Now;
|
this.executionStarted = DateTime.Now;
|
||||||
|
this.lastChange = DateTime.Now;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float IncrementProgress(float amount)
|
public float IncrementProgress(float amount)
|
||||||
{
|
{
|
||||||
this.progress += amount;
|
this.progress += amount;
|
||||||
|
this.lastChange = DateTime.Now;
|
||||||
return this.progress;
|
return this.progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ public class DownloadChapterTask : TrangaTask
|
|||||||
public Publication publication { get; }
|
public Publication publication { get; }
|
||||||
public string language { get; }
|
public string language { get; }
|
||||||
public Chapter chapter { get; }
|
public Chapter chapter { get; }
|
||||||
[JsonIgnore]private DownloadNewChaptersTask? parentTask { get; init; }
|
[JsonIgnore]public DownloadNewChaptersTask? parentTask { get; init; }
|
||||||
|
|
||||||
public DownloadChapterTask(Task task, string connectorName, Publication publication, Chapter chapter, string language = "en", DownloadNewChaptersTask? parentTask = null) : base(task, TimeSpan.Zero)
|
public DownloadChapterTask(Task task, string connectorName, Publication publication, Chapter chapter, string language = "en", DownloadNewChaptersTask? parentTask = null) : base(task, TimeSpan.Zero)
|
||||||
{
|
{
|
||||||
@ -22,15 +22,15 @@ public class DownloadChapterTask : TrangaTask
|
|||||||
|
|
||||||
protected override void ExecuteTask(TaskManager taskManager, Logger? logger)
|
protected override void ExecuteTask(TaskManager taskManager, Logger? logger)
|
||||||
{
|
{
|
||||||
Publication pub = (Publication)this.publication!;
|
|
||||||
Connector connector = taskManager.GetConnector(this.connectorName);
|
Connector connector = taskManager.GetConnector(this.connectorName);
|
||||||
connector.DownloadChapter(pub, this.chapter, this);
|
connector.DownloadChapter(this.publication, this.chapter, this);
|
||||||
taskManager.DeleteTask(this);
|
taskManager.DeleteTask(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public new float IncrementProgress(float amount)
|
public new float IncrementProgress(float amount)
|
||||||
{
|
{
|
||||||
this.progress += amount;
|
this.progress += amount;
|
||||||
|
this.lastChange = DateTime.Now;
|
||||||
parentTask?.IncrementProgress(amount);
|
parentTask?.IncrementProgress(amount);
|
||||||
return this.progress;
|
return this.progress;
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ public class DownloadNewChaptersTask : TrangaTask
|
|||||||
public new float IncrementProgress(float amount)
|
public new float IncrementProgress(float amount)
|
||||||
{
|
{
|
||||||
this.progress += amount / this.childTaskAmount;
|
this.progress += amount / this.childTaskAmount;
|
||||||
|
this.lastChange = DateTime.Now;
|
||||||
return this.progress;
|
return this.progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,8 +89,8 @@ async function GetKomgaTask(){
|
|||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
function CreateTask(taskType, reoccurrence, connectorName, publicationId, language){
|
function CreateTask(taskType, reoccurrence, connectorName, internalId, language){
|
||||||
var uri = apiUri + `/Tasks/Create?taskType=${taskType}&connectorName=${connectorName}&publicationId=${publicationId}&reoccurrenceTime=${reoccurrence}&language=${language}`;
|
var uri = apiUri + `/Tasks/Create?taskType=${taskType}&connectorName=${connectorName}&internalId=${internalId}&reoccurrenceTime=${reoccurrence}&language=${language}`;
|
||||||
PostData(uri);
|
PostData(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user