mirror of
https://github.com/C9Glax/tranga.git
synced 2025-10-11 05:09:49 +02:00
Add RefreshLibrariesWorker.cs
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using API.MangaDownloadClients;
|
using API.MangaDownloadClients;
|
||||||
|
using API.Workers;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace API;
|
namespace API;
|
||||||
@@ -54,6 +55,10 @@ public struct TrangaSettings()
|
|||||||
|
|
||||||
public int MaxConcurrentWorkers { get; set; } = Math.Max(Environment.ProcessorCount, 4); // Minimum of 4 Tasks, maximum of 1 per Core
|
public int MaxConcurrentWorkers { get; set; } = Math.Max(Environment.ProcessorCount, 4); // Minimum of 4 Tasks, maximum of 1 per Core
|
||||||
|
|
||||||
|
public LibraryRefreshSetting LibraryRefreshSetting { get; set; } = LibraryRefreshSetting.AfterMangaFinished;
|
||||||
|
|
||||||
|
public int RefreshLibraryWhileDownloadingEveryMinutes { get; set; } = 10;
|
||||||
|
|
||||||
public static TrangaSettings Load()
|
public static TrangaSettings Load()
|
||||||
{
|
{
|
||||||
if (!File.Exists(SettingsFilePath))
|
if (!File.Exists(SettingsFilePath))
|
||||||
@@ -125,4 +130,16 @@ public struct TrangaSettings()
|
|||||||
this.MaxConcurrentWorkers = value;
|
this.MaxConcurrentWorkers = value;
|
||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetLibraryRefreshSetting(LibraryRefreshSetting setting)
|
||||||
|
{
|
||||||
|
this.LibraryRefreshSetting = setting;
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetRefreshLibraryWhileDownloadingEveryMinutes(int value)
|
||||||
|
{
|
||||||
|
this.RefreshLibraryWhileDownloadingEveryMinutes = value;
|
||||||
|
Save();
|
||||||
|
}
|
||||||
}
|
}
|
@@ -3,6 +3,7 @@ using System.Runtime.InteropServices;
|
|||||||
using API.MangaConnectors;
|
using API.MangaConnectors;
|
||||||
using API.MangaDownloadClients;
|
using API.MangaDownloadClients;
|
||||||
using API.Schema.MangaContext;
|
using API.Schema.MangaContext;
|
||||||
|
using API.Workers.PeriodicWorkers;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||||
using SixLabors.ImageSharp;
|
using SixLabors.ImageSharp;
|
||||||
@@ -21,16 +22,16 @@ namespace API.Workers.MangaDownloadWorkers;
|
|||||||
public class DownloadChapterFromMangaconnectorWorker(MangaConnectorId<Chapter> chId, IEnumerable<BaseWorker>? dependsOn = null)
|
public class DownloadChapterFromMangaconnectorWorker(MangaConnectorId<Chapter> chId, IEnumerable<BaseWorker>? dependsOn = null)
|
||||||
: BaseWorkerWithContext<MangaContext>(dependsOn)
|
: BaseWorkerWithContext<MangaContext>(dependsOn)
|
||||||
{
|
{
|
||||||
internal readonly string MangaConnectorIdId = chId.Key;
|
private readonly string _mangaConnectorIdId = chId.Key;
|
||||||
protected override async Task<BaseWorker[]> DoWorkInternal()
|
protected override async Task<BaseWorker[]> DoWorkInternal()
|
||||||
{
|
{
|
||||||
Log.Debug($"Downloading chapter for MangaConnectorId {MangaConnectorIdId}...");
|
Log.Debug($"Downloading chapter for MangaConnectorId {_mangaConnectorIdId}...");
|
||||||
// Getting MangaConnector info
|
// Getting MangaConnector info
|
||||||
if (await DbContext.MangaConnectorToChapter
|
if (await DbContext.MangaConnectorToChapter
|
||||||
.Include(id => id.Obj)
|
.Include(id => id.Obj)
|
||||||
.ThenInclude(c => c.ParentManga)
|
.ThenInclude(c => c.ParentManga)
|
||||||
.ThenInclude(m => m.Library)
|
.ThenInclude(m => m.Library)
|
||||||
.FirstOrDefaultAsync(c => c.Key == MangaConnectorIdId, CancellationToken) is not { } mangaConnectorId)
|
.FirstOrDefaultAsync(c => c.Key == _mangaConnectorIdId, CancellationToken) is not { } mangaConnectorId)
|
||||||
{
|
{
|
||||||
Log.Error("Could not get MangaConnectorId.");
|
Log.Error("Could not get MangaConnectorId.");
|
||||||
return []; //TODO Exception?
|
return []; //TODO Exception?
|
||||||
@@ -137,8 +138,19 @@ public class DownloadChapterFromMangaconnectorWorker(MangaConnectorId<Chapter> c
|
|||||||
|
|
||||||
Log.Debug($"Downloaded chapter {chapter}.");
|
Log.Debug($"Downloaded chapter {chapter}.");
|
||||||
|
|
||||||
return [];
|
bool refreshLibrary = await CheckLibraryRefresh();
|
||||||
|
|
||||||
|
return refreshLibrary? [new RefreshLibrariesWorker()] : [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<bool> CheckLibraryRefresh() => Tranga.Settings.LibraryRefreshSetting switch
|
||||||
|
{
|
||||||
|
LibraryRefreshSetting.AfterAllFinished => (await StartNewChapterDownloadsWorker.GetMissingChapters(DbContext, CancellationToken)).Count == 0,
|
||||||
|
LibraryRefreshSetting.AfterMangaFinished => await DbContext.MangaConnectorToChapter.Include(chId => chId.Obj).Where(chId => chId.UseForDownload).AllAsync(chId => chId.Obj.Downloaded, CancellationToken),
|
||||||
|
LibraryRefreshSetting.AfterEveryChapter => true,
|
||||||
|
LibraryRefreshSetting.WhileDownloading => DateTime.UtcNow.Subtract(RefreshLibrariesWorker.LastRefresh).TotalMinutes > Tranga.Settings.RefreshLibraryWhileDownloadingEveryMinutes,
|
||||||
|
_ => true
|
||||||
|
};
|
||||||
|
|
||||||
private void ProcessImage(string imagePath)
|
private void ProcessImage(string imagePath)
|
||||||
{
|
{
|
||||||
@@ -232,5 +244,5 @@ public class DownloadChapterFromMangaconnectorWorker(MangaConnectorId<Chapter> c
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString() => $"{base.ToString()} {MangaConnectorIdId}";
|
public override string ToString() => $"{base.ToString()} {_mangaConnectorIdId}";
|
||||||
}
|
}
|
@@ -18,10 +18,7 @@ public class StartNewChapterDownloadsWorker(TimeSpan? interval = null, IEnumerab
|
|||||||
Log.Debug("Checking for missing chapters...");
|
Log.Debug("Checking for missing chapters...");
|
||||||
|
|
||||||
// Get missing chapters
|
// Get missing chapters
|
||||||
List<MangaConnectorId<Chapter>> missingChapters = await DbContext.MangaConnectorToChapter
|
List<MangaConnectorId<Chapter>> missingChapters = await GetMissingChapters(DbContext, CancellationToken);
|
||||||
.Include(id => id.Obj)
|
|
||||||
.Where(id => id.Obj.Downloaded == false && id.UseForDownload)
|
|
||||||
.ToListAsync(CancellationToken);
|
|
||||||
|
|
||||||
Log.Debug($"Found {missingChapters.Count} missing downloads.");
|
Log.Debug($"Found {missingChapters.Count} missing downloads.");
|
||||||
|
|
||||||
@@ -37,4 +34,9 @@ public class StartNewChapterDownloadsWorker(TimeSpan? interval = null, IEnumerab
|
|||||||
|
|
||||||
return newWorkers.ToArray();
|
return newWorkers.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static async Task<List<MangaConnectorId<Chapter>>> GetMissingChapters(MangaContext ctx, CancellationToken cancellationToken) => await ctx.MangaConnectorToChapter
|
||||||
|
.Include(id => id.Obj)
|
||||||
|
.Where(id => id.Obj.Downloaded == false && id.UseForDownload)
|
||||||
|
.ToListAsync(cancellationToken);
|
||||||
}
|
}
|
29
API/Workers/RefreshLibrariesWorker.cs
Normal file
29
API/Workers/RefreshLibrariesWorker.cs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
using API.Schema.LibraryContext;
|
||||||
|
using API.Schema.LibraryContext.LibraryConnectors;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace API.Workers;
|
||||||
|
|
||||||
|
public class RefreshLibrariesWorker(IEnumerable<BaseWorker>? dependsOn = null) : BaseWorkerWithContext<LibraryContext>(dependsOn)
|
||||||
|
{
|
||||||
|
public static DateTime LastRefresh { get; set; } = DateTime.UnixEpoch;
|
||||||
|
|
||||||
|
protected override async Task<BaseWorker[]> DoWorkInternal()
|
||||||
|
{
|
||||||
|
Log.Debug("Refreshing libraries...");
|
||||||
|
LastRefresh = DateTime.UtcNow;
|
||||||
|
List<LibraryConnector> libraries = await DbContext.LibraryConnectors.ToListAsync(CancellationToken);
|
||||||
|
foreach (LibraryConnector connector in libraries)
|
||||||
|
await connector.UpdateLibrary(CancellationToken);
|
||||||
|
Log.Debug("Libraries Refreshed...");
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum LibraryRefreshSetting : byte
|
||||||
|
{
|
||||||
|
AfterAllFinished = 0,
|
||||||
|
AfterMangaFinished = 1,
|
||||||
|
AfterEveryChapter = 2,
|
||||||
|
WhileDownloading = 3
|
||||||
|
}
|
@@ -8,6 +8,7 @@
|
|||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=kitsu/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=kitsu/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Komga/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Komga/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=lunasea/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=lunasea/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=mangaconnector/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=mangakatana/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=mangakatana/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Manganato/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Manganato/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Mangasee/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Mangasee/@EntryIndexedValue">True</s:Boolean>
|
||||||
@@ -15,4 +16,5 @@
|
|||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Ntfy/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Ntfy/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=solverr/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=solverr/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Taskmanager/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Taskmanager/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Tranga/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Tranga/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=trangatemp/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
Reference in New Issue
Block a user