From 13c96fd09a4fdbe3f515ea45af9f77928ce6c858 Mon Sep 17 00:00:00 2001 From: glax Date: Sun, 21 May 2023 16:51:14 +0200 Subject: [PATCH 01/13] Create Appdata Directories for API --- Tranga-API/Program.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Tranga-API/Program.cs b/Tranga-API/Program.cs index a044dd2..6356e38 100644 --- a/Tranga-API/Program.cs +++ b/Tranga-API/Program.cs @@ -6,6 +6,8 @@ string applicationFolderPath = Path.Join(Environment.GetFolderPath(Environment. string logsFolderPath = Path.Join(applicationFolderPath, "logs"); string logFilePath = Path.Join(logsFolderPath, $"log-{DateTime.Now:dd-M-yyyy-HH-mm-ss}.txt"); string settingsFilePath = Path.Join(applicationFolderPath, "data.json"); +Directory.CreateDirectory(applicationFolderPath); +Directory.CreateDirectory(logsFolderPath); Console.WriteLine($"Logfile-Path: {logFilePath}"); Console.WriteLine($"Settings-File-Path: {settingsFilePath}"); From df991e3da67552953d86da954e3b9146ea7b4560 Mon Sep 17 00:00:00 2001 From: glax Date: Sun, 21 May 2023 17:59:24 +0200 Subject: [PATCH 02/13] Remove APi for testing --- Tranga-API/Dockerfile | 20 --- Tranga-API/Program.cs | 186 ---------------------- Tranga-API/Properties/launchSettings.json | 37 ----- Tranga-API/Tranga-API.csproj | 21 --- Tranga-API/appsettings.Development.json | 8 - Tranga-API/appsettings.json | 9 -- Tranga-API/tasks.json | 1 - Tranga.sln | 6 - 8 files changed, 288 deletions(-) delete mode 100644 Tranga-API/Dockerfile delete mode 100644 Tranga-API/Program.cs delete mode 100644 Tranga-API/Properties/launchSettings.json delete mode 100644 Tranga-API/Tranga-API.csproj delete mode 100644 Tranga-API/appsettings.Development.json delete mode 100644 Tranga-API/appsettings.json delete mode 100644 Tranga-API/tasks.json diff --git a/Tranga-API/Dockerfile b/Tranga-API/Dockerfile deleted file mode 100644 index 6a0e453..0000000 --- a/Tranga-API/Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base -WORKDIR /app -EXPOSE 80 -EXPOSE 443 - -FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build -WORKDIR /src -COPY ["Tranga-API/Tranga-API.csproj", "Tranga-API/"] -RUN dotnet restore "Tranga-API/Tranga-API.csproj" -COPY . . -WORKDIR "/src/Tranga-API" -RUN dotnet build "Tranga-API.csproj" -c Release -o /app/build - -FROM build AS publish -RUN dotnet publish "Tranga-API.csproj" -c Release -o /app/publish /p:UseAppHost=false - -FROM base AS final -WORKDIR /app -COPY --from=publish /app/publish . -ENTRYPOINT ["dotnet", "Tranga-API.dll"] diff --git a/Tranga-API/Program.cs b/Tranga-API/Program.cs deleted file mode 100644 index 6356e38..0000000 --- a/Tranga-API/Program.cs +++ /dev/null @@ -1,186 +0,0 @@ -using System.Text.Json; -using Tranga; -using Logging; - -string applicationFolderPath = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Tranga-API"); -string logsFolderPath = Path.Join(applicationFolderPath, "logs"); -string logFilePath = Path.Join(logsFolderPath, $"log-{DateTime.Now:dd-M-yyyy-HH-mm-ss}.txt"); -string settingsFilePath = Path.Join(applicationFolderPath, "data.json"); -Directory.CreateDirectory(applicationFolderPath); -Directory.CreateDirectory(logsFolderPath); - -Console.WriteLine($"Logfile-Path: {logFilePath}"); -Console.WriteLine($"Settings-File-Path: {settingsFilePath}"); - -Logger logger = new(new[] { Logger.LoggerType.FileLogger }, null, null, logFilePath); - -logger.WriteLine("Tranga_API", "Loading Taskmanager."); - -TaskManager.SettingsData settings; -if (File.Exists(settingsFilePath)) - settings = TaskManager.LoadData(settingsFilePath); -else - settings = new TaskManager.SettingsData(Directory.GetCurrentDirectory(), settingsFilePath, null, new HashSet()); - -TaskManager taskManager = new (settings, logger); - -var builder = WebApplication.CreateBuilder(args); -var app = builder.Build(); - -app.MapGet("/GetConnectors", () => JsonSerializer.Serialize(taskManager.GetAvailableConnectors().Values.ToArray())); - -app.MapGet("/GetPublications", (string connectorName, string? publicationName) => -{ - Connector connector = taskManager.GetConnector(connectorName); - - Publication[] publications; - if (publicationName is not null) - publications = connector.GetPublications(publicationName); - else - publications = connector.GetPublications(); - - return JsonSerializer.Serialize(publications); -}); - -app.MapGet("/ListTasks", () => JsonSerializer.Serialize(taskManager.GetAllTasks())); - -app.MapGet("/TaskTypes", () => -{ - string[] availableTasks = Enum.GetNames(typeof(TrangaTask.Task)); - return JsonSerializer.Serialize(availableTasks); -}); - -app.MapGet("/CreateTask", - (TrangaTask.Task task, string? connectorName, string? publicationInternalId, TimeSpan reoccurrence, string? language) => - { - switch (task) - { - case TrangaTask.Task.UpdateKomgaLibrary: - taskManager.AddTask(TrangaTask.Task.UpdateKomgaLibrary, null, null, reoccurrence); - break; - case TrangaTask.Task.DownloadNewChapters: - try - { - Publication? publication = taskManager.GetAllPublications() - .FirstOrDefault(pub => pub.internalId == publicationInternalId); - - if (publication is null) - { - return JsonSerializer.Serialize($"Publication {publicationInternalId} is unknown."); - } - else - { - taskManager.AddTask(TrangaTask.Task.DownloadNewChapters, connectorName, publication, reoccurrence, language ?? ""); - return JsonSerializer.Serialize("Success"); - } - } - catch (Exception e) - { - return JsonSerializer.Serialize(e.Message); - } - - default: return JsonSerializer.Serialize("Not Implemented"); - } - - return JsonSerializer.Serialize("Not Implemented"); - }); - -app.MapGet("/RemoveTask", (TrangaTask.Task task, string? connectorName, string? publicationInternalId) => -{ - switch (task) - { - case TrangaTask.Task.UpdateKomgaLibrary: - taskManager.DeleteTask(TrangaTask.Task.UpdateKomgaLibrary, null, null); - return JsonSerializer.Serialize("Success"); - case TrangaTask.Task.DownloadNewChapters: - Publication? publication = taskManager.GetAllPublications().FirstOrDefault(pub => pub.internalId == publicationInternalId); - if (publication is null) - JsonSerializer.Serialize($"Publication with id {publicationInternalId} is unknown."); - - taskManager.DeleteTask(TrangaTask.Task.DownloadNewChapters, connectorName, publication); - - return JsonSerializer.Serialize("Success"); - - default: return JsonSerializer.Serialize("Not Implemented"); - } -}); - -app.MapGet("/StartTask", (TrangaTask.Task task, string? connectorName, string? publicationInternalId) => -{ - TrangaTask[] allTasks = taskManager.GetAllTasks(); - TrangaTask? taskToStart = allTasks.FirstOrDefault(tTask => - tTask.task == task && tTask.connectorName == connectorName && - tTask.publication?.internalId == publicationInternalId); - if(taskToStart is null) - JsonSerializer.Serialize($"Task with parameters {task} {connectorName} {publicationInternalId} is unknown."); - taskManager.ExecuteTaskNow(taskToStart!); - return JsonSerializer.Serialize("Success"); -}); - -app.MapGet("/TaskQueue", () => -{ - return JsonSerializer.Serialize(taskManager.GetAllTasks() - .Where(task => task.state is TrangaTask.ExecutionState.Enqueued or TrangaTask.ExecutionState.Running) - .ToArray()); -}); - -app.MapGet("/TaskEnqueue", (TrangaTask.Task task, string? connectorName, string? publicationInternalId) => -{ - TrangaTask[] allTasks = taskManager.GetAllTasks(); - TrangaTask? taskToEnqueue = allTasks.FirstOrDefault(tTask => - tTask.task == task && tTask.connectorName == connectorName && - tTask.publication?.internalId == publicationInternalId); - if(taskToEnqueue is null) - JsonSerializer.Serialize($"Task with parameters {task} {connectorName} {publicationInternalId} is unknown."); - taskManager.AddTaskToQueue(taskToEnqueue!); - return JsonSerializer.Serialize("Success"); -}); - -app.MapGet("/TaskDequeue", (TrangaTask.Task task, string? connectorName, string? publicationInternalId) => -{ - TrangaTask[] allTasks = taskManager.GetAllTasks(); - TrangaTask? taskToDequeue = allTasks.FirstOrDefault(tTask => - tTask.task == task && tTask.connectorName == connectorName && - tTask.publication?.internalId == publicationInternalId); - if(taskToDequeue is null) - JsonSerializer.Serialize($"Task with parameters {task} {connectorName} {publicationInternalId} is unknown."); - taskManager.RemoveTaskFromQueue(taskToDequeue); - return JsonSerializer.Serialize("Success"); -}); - -app.MapGet("/Settings", () => JsonSerializer.Serialize(new Settings(taskManager.settings))); - -app.MapGet("/EditSettings", (string downloadLocation, string komgaBaseUrl, string komgaAuthString) => -{ - taskManager.settings.downloadLocation = downloadLocation; - taskManager.settings.komga = new Komga(komgaBaseUrl, komgaAuthString, logger); -}); - -app.Run(); - -struct Settings -{ - public Komga? komga { get; set; } - public string downloadLocation { get; set; } - public string settingsFilePath { get; set; } - public Settings(TaskManager.SettingsData data) - { - this.settingsFilePath = data.settingsFilePath; - this.downloadLocation = data.downloadLocation; - this.komga = data.komga; - } - - public Settings(string downloadLocation, string settingsFilePath, Komga komga) - { - this.downloadLocation = downloadLocation; - this.settingsFilePath = settingsFilePath; - this.komga = komga; - } - - public void Update(string? newDownloadLocation = null, string? newSettingsFilePath = null, Komga? newKomga= null) - { - this.downloadLocation = newDownloadLocation ?? this.downloadLocation; - this.settingsFilePath = newSettingsFilePath ?? this.settingsFilePath; - this.komga = newKomga ?? this.komga; - } -} \ No newline at end of file diff --git a/Tranga-API/Properties/launchSettings.json b/Tranga-API/Properties/launchSettings.json deleted file mode 100644 index 773e2c3..0000000 --- a/Tranga-API/Properties/launchSettings.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:14826", - "sslPort": 44333 - } - }, - "profiles": { - "http": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "applicationUrl": "http://localhost:5119", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "https": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "applicationUrl": "https://localhost:7070;http://localhost:5119", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} diff --git a/Tranga-API/Tranga-API.csproj b/Tranga-API/Tranga-API.csproj deleted file mode 100644 index ade20c4..0000000 --- a/Tranga-API/Tranga-API.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - net7.0 - enable - enable - Tranga_API - Linux - - - - - .dockerignore - - - - - - - - diff --git a/Tranga-API/appsettings.Development.json b/Tranga-API/appsettings.Development.json deleted file mode 100644 index 0c208ae..0000000 --- a/Tranga-API/appsettings.Development.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - } -} diff --git a/Tranga-API/appsettings.json b/Tranga-API/appsettings.json deleted file mode 100644 index 10f68b8..0000000 --- a/Tranga-API/appsettings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "AllowedHosts": "*" -} diff --git a/Tranga-API/tasks.json b/Tranga-API/tasks.json deleted file mode 100644 index 8cbf4a7..0000000 --- a/Tranga-API/tasks.json +++ /dev/null @@ -1 +0,0 @@ -[{"reoccurrence":"00:00:00","lastExecuted":"2023-05-19T17:34:40.5349215+02:00","connectorName":"MangaDex","task":0,"publication":{"sortName":null,"description":null,"tags":null,"posterUrl":null,"year":null,"originalLanguage":null,"status":null,"folderName":null,"downloadUrl":null},"language":"en"}] \ No newline at end of file diff --git a/Tranga.sln b/Tranga.sln index f11d582..d67d5c6 100644 --- a/Tranga.sln +++ b/Tranga.sln @@ -4,8 +4,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tranga", ".\Tranga\Tranga.c EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tranga-CLI", "Tranga-CLI\Tranga-CLI.csproj", "{4899E3B2-B259-479A-B43E-042D043E9501}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tranga-API", "Tranga-API\Tranga-API.csproj", "{6284C936-4E90-486B-BC46-0AFAD85AD8EE}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Logging", "Logging\Logging.csproj", "{415BE889-BB7D-426F-976F-8D977876A462}" EndProject Global @@ -22,10 +20,6 @@ Global {4899E3B2-B259-479A-B43E-042D043E9501}.Debug|Any CPU.Build.0 = Debug|Any CPU {4899E3B2-B259-479A-B43E-042D043E9501}.Release|Any CPU.ActiveCfg = Release|Any CPU {4899E3B2-B259-479A-B43E-042D043E9501}.Release|Any CPU.Build.0 = Release|Any CPU - {6284C936-4E90-486B-BC46-0AFAD85AD8EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6284C936-4E90-486B-BC46-0AFAD85AD8EE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6284C936-4E90-486B-BC46-0AFAD85AD8EE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6284C936-4E90-486B-BC46-0AFAD85AD8EE}.Release|Any CPU.Build.0 = Release|Any CPU {415BE889-BB7D-426F-976F-8D977876A462}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {415BE889-BB7D-426F-976F-8D977876A462}.Debug|Any CPU.Build.0 = Debug|Any CPU {415BE889-BB7D-426F-976F-8D977876A462}.Release|Any CPU.ActiveCfg = Release|Any CPU From 455c87b2e1875d1b116fb18990990942b7574fc7 Mon Sep 17 00:00:00 2001 From: glax Date: Sun, 21 May 2023 21:12:32 +0200 Subject: [PATCH 03/13] New API --- Tranga-API/Dockerfile | 20 ++++ Tranga-API/Program.cs | 122 ++++++++++++++++++++++ Tranga-API/Properties/launchSettings.json | 37 +++++++ Tranga-API/Tranga-API.csproj | 26 +++++ Tranga-API/appsettings.Development.json | 8 ++ Tranga-API/appsettings.json | 9 ++ Tranga.sln | 6 ++ Tranga/Connectors/MangaDex.cs | 17 ++- Tranga/Publication.cs | 16 +-- Tranga/TaskExecutor.cs | 16 +-- Tranga/TaskManager.cs | 15 ++- 11 files changed, 265 insertions(+), 27 deletions(-) create mode 100644 Tranga-API/Dockerfile create mode 100644 Tranga-API/Program.cs create mode 100644 Tranga-API/Properties/launchSettings.json create mode 100644 Tranga-API/Tranga-API.csproj create mode 100644 Tranga-API/appsettings.Development.json create mode 100644 Tranga-API/appsettings.json diff --git a/Tranga-API/Dockerfile b/Tranga-API/Dockerfile new file mode 100644 index 0000000..6a0e453 --- /dev/null +++ b/Tranga-API/Dockerfile @@ -0,0 +1,20 @@ +FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base +WORKDIR /app +EXPOSE 80 +EXPOSE 443 + +FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build +WORKDIR /src +COPY ["Tranga-API/Tranga-API.csproj", "Tranga-API/"] +RUN dotnet restore "Tranga-API/Tranga-API.csproj" +COPY . . +WORKDIR "/src/Tranga-API" +RUN dotnet build "Tranga-API.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "Tranga-API.csproj" -c Release -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "Tranga-API.dll"] diff --git a/Tranga-API/Program.cs b/Tranga-API/Program.cs new file mode 100644 index 0000000..b7f0a70 --- /dev/null +++ b/Tranga-API/Program.cs @@ -0,0 +1,122 @@ + +using Logging; +using Tranga; + +string applicationFolderPath = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Tranga-API"); +string logsFolderPath = Path.Join(applicationFolderPath, "logs"); +string logFilePath = Path.Join(logsFolderPath, $"log-{DateTime.Now:dd-M-yyyy-HH-mm-ss}.txt"); +string settingsFilePath = Path.Join(applicationFolderPath, "data.json"); + +Directory.CreateDirectory(applicationFolderPath); +Directory.CreateDirectory(logsFolderPath); + +Console.WriteLine($"Logfile-Path: {logFilePath}"); +Console.WriteLine($"Settings-File-Path: {settingsFilePath}"); + +Logger logger = new(new[] { Logger.LoggerType.FileLogger }, null, null, logFilePath); + +logger.WriteLine("Tranga_CLI", "Loading Taskmanager."); +TaskManager.SettingsData settings; +if (File.Exists(settingsFilePath)) + settings = TaskManager.LoadData(settingsFilePath); +else + settings = new TaskManager.SettingsData(Directory.GetCurrentDirectory(), settingsFilePath, null, new HashSet()); + +TaskManager taskManager = new (settings, logger); + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddControllers().AddNewtonsoftJson(); +var app = builder.Build(); + +app.MapGet("/GetAvailableControllers", () => taskManager.GetAvailableConnectors()); + +app.MapGet("/GetKnownPublications", () => taskManager.GetAllPublications()); + +app.MapGet("/GetPublicationsFromConnector", (string connectorName, string title) => +{ + Connector? connector = taskManager.GetAvailableConnectors().FirstOrDefault(con => con.Key == connectorName).Value; + if (connector is null) + return Array.Empty(); + if(title.Length < 4) + return Array.Empty(); + return taskManager.GetPublicationsFromConnector(connector, title); +}); + +app.MapGet("/Tasks/GetTaskTypes", () => Enum.GetNames(typeof(TrangaTask.Task))); + + +app.MapPost("/Tasks/Create", (string taskType, string? connectorName, string? publicationId, string reoccurrenceTime, string? language) => +{ + Publication? publication = taskManager.GetAllPublications().FirstOrDefault(pub => pub.internalId == publicationId); + TrangaTask.Task task = Enum.Parse(taskType); + taskManager.AddTask(task, connectorName, publication, TimeSpan.Parse(reoccurrenceTime), language??""); +}); + +app.MapPost("/Tasks/Delete", (string taskType, string? connectorName, string? publicationId) => +{ + Publication? publication = taskManager.GetAllPublications().FirstOrDefault(pub => pub.internalId == publicationId); + TrangaTask.Task task = Enum.Parse(taskType); + taskManager.DeleteTask(task, connectorName, publication); +}); + +app.MapGet("/Tasks/GetList", () => taskManager.GetAllTasks()); + +app.MapPost("/Tasks/Start", (string taskType, string? connectorName, string? publicationId) => +{ + TrangaTask.Task pTask = Enum.Parse(taskType); + TrangaTask? task = taskManager.GetAllTasks().FirstOrDefault(tTask => + tTask.task == pTask && tTask.publication?.internalId == publicationId && tTask.connectorName == connectorName); + if (task is null) + return; + taskManager.ExecuteTaskNow(task); +}); + +app.MapGet("/Tasks/GetRunningTasks", + () => taskManager.GetAllTasks().Where(task => task.state is TrangaTask.ExecutionState.Running)); + +app.MapGet("/Queue/GetList", + () => taskManager.GetAllTasks().Where(task => task.state is TrangaTask.ExecutionState.Enqueued)); + +app.MapPost("/Queue/Enqueue", (string taskType, string? connectorName, string? publicationId) => +{ + TrangaTask.Task pTask = Enum.Parse(taskType); + TrangaTask? task = taskManager.GetAllTasks().FirstOrDefault(tTask => + tTask.task == pTask && tTask.publication?.internalId == publicationId && tTask.connectorName == connectorName); + if (task is null) + return; + taskManager.AddTaskToQueue(task); +}); + +app.MapPost("/Queue/Dequeue", (string taskType, string? connectorName, string? publicationId) => +{ + TrangaTask.Task pTask = Enum.Parse(taskType); + TrangaTask? task = taskManager.GetAllTasks().FirstOrDefault(tTask => + tTask.task == pTask && tTask.publication?.internalId == publicationId && tTask.connectorName == connectorName); + if (task is null) + return; + taskManager.RemoveTaskFromQueue(task); +}); + +app.MapGet("/Settings/Get", () => new Settings(taskManager.settings)); + +app.MapPost("/Setting/Update", (string? downloadLocation, string? komgaUrl, string? komgaAuth) => +{ + if(downloadLocation is not null) + taskManager.settings.downloadLocation = downloadLocation; + if(komgaUrl is not null && komgaAuth is not null) + taskManager.settings.komga = new Komga(komgaUrl, komgaAuth, logger); +}); + +app.Run(); + +class Settings +{ + public string downloadLocation; + public Komga? komga; + + public Settings(TaskManager.SettingsData settings) + { + this.downloadLocation = settings.downloadLocation; + this.komga = komga; + } +} \ No newline at end of file diff --git a/Tranga-API/Properties/launchSettings.json b/Tranga-API/Properties/launchSettings.json new file mode 100644 index 0000000..fd6862f --- /dev/null +++ b/Tranga-API/Properties/launchSettings.json @@ -0,0 +1,37 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:1716", + "sslPort": 44391 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:5177", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:7036;http://localhost:5177", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/Tranga-API/Tranga-API.csproj b/Tranga-API/Tranga-API.csproj new file mode 100644 index 0000000..3b1d193 --- /dev/null +++ b/Tranga-API/Tranga-API.csproj @@ -0,0 +1,26 @@ + + + + net7.0 + enable + enable + Tranga_API + Linux + + + + + .dockerignore + + + + + + + + + + + + + diff --git a/Tranga-API/appsettings.Development.json b/Tranga-API/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/Tranga-API/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/Tranga-API/appsettings.json b/Tranga-API/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/Tranga-API/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/Tranga.sln b/Tranga.sln index d67d5c6..7bf8e4f 100644 --- a/Tranga.sln +++ b/Tranga.sln @@ -6,6 +6,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tranga-CLI", "Tranga-CLI\Tr EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Logging", "Logging\Logging.csproj", "{415BE889-BB7D-426F-976F-8D977876A462}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tranga-API", "Tranga-API\Tranga-API.csproj", "{48F4E495-75BC-4402-8E03-DEC5B79D7E83}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -24,5 +26,9 @@ Global {415BE889-BB7D-426F-976F-8D977876A462}.Debug|Any CPU.Build.0 = Debug|Any CPU {415BE889-BB7D-426F-976F-8D977876A462}.Release|Any CPU.ActiveCfg = Release|Any CPU {415BE889-BB7D-426F-976F-8D977876A462}.Release|Any CPU.Build.0 = Release|Any CPU + {48F4E495-75BC-4402-8E03-DEC5B79D7E83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {48F4E495-75BC-4402-8E03-DEC5B79D7E83}.Debug|Any CPU.Build.0 = Debug|Any CPU + {48F4E495-75BC-4402-8E03-DEC5B79D7E83}.Release|Any CPU.ActiveCfg = Release|Any CPU + {48F4E495-75BC-4402-8E03-DEC5B79D7E83}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/Tranga/Connectors/MangaDex.cs b/Tranga/Connectors/MangaDex.cs index 56dcbee..251bc30 100644 --- a/Tranga/Connectors/MangaDex.cs +++ b/Tranga/Connectors/MangaDex.cs @@ -58,14 +58,12 @@ public class MangaDex : Connector : null; JsonArray altTitlesObject = attributes["altTitles"]!.AsArray(); - string[,] altTitles = new string[altTitlesObject.Count, 2]; - int titleIndex = 0; + Dictionary altTitlesDict = new(); foreach (JsonNode? altTitleNode in altTitlesObject) { JsonObject altTitleObject = (JsonObject)altTitleNode!; string key = ((IDictionary)altTitleObject).Keys.ToArray()[0]; - altTitles[titleIndex, 0] = key; - altTitles[titleIndex++, 1] = altTitleObject[key]!.GetValue(); + altTitlesDict.Add(key, altTitleObject[key]!.GetValue()); } JsonArray tagsObject = attributes["tags"]!.AsArray(); @@ -84,16 +82,14 @@ public class MangaDex : Connector poster = relationships.FirstOrDefault(relationship => relationship!["type"]!.GetValue() == "cover_art")!["id"]!.GetValue(); } + Dictionary linksDict = new(); string[,]? links = null; if (attributes.ContainsKey("links") && attributes["links"] is not null) { JsonObject linksObject = attributes["links"]!.AsObject(); - links = new string[linksObject.Count, 2]; - int linkIndex = 0; foreach (string key in ((IDictionary)linksObject).Keys) { - links[linkIndex, 0] = key; - links[linkIndex++, 1] = linksObject[key]!.GetValue(); + linksDict.Add(key, linksObject[key]!.GetValue()); } } @@ -110,14 +106,13 @@ public class MangaDex : Connector Publication pub = new Publication( title, description, - altTitles, + altTitlesDict, tags.ToArray(), poster, - links, + linksDict, year, originalLanguage, status, - manga["id"]!.GetValue(), manga["id"]!.GetValue() ); publications.Add(pub); //Add Publication (Manga) to result diff --git a/Tranga/Publication.cs b/Tranga/Publication.cs index b5c18a2..e3470a0 100644 --- a/Tranga/Publication.cs +++ b/Tranga/Publication.cs @@ -9,34 +9,38 @@ public readonly struct Publication { public string sortName { get; } // ReSharper disable UnusedAutoPropertyAccessor.Global we need it, trust - [JsonIgnore]public string[,] altTitles { get; } + [JsonIgnore]public Dictionary altTitles { get; } // ReSharper disable trice MemberCanBePrivate.Global, trust public string? description { get; } public string[] tags { get; } public string? posterUrl { get; } - [JsonIgnore]public string[,]? links { get; } + [JsonIgnore]public Dictionary links { get; } public int? year { get; } public string? originalLanguage { get; } public string status { get; } public string folderName { get; } public string downloadUrl { get; } - public string internalId { get; } - public Publication(string sortName, string? description, string[,] altTitles, string[] tags, string? posterUrl, string[,]? links, int? year, string? originalLanguage, string status, string downloadUrl, string internalId) + public readonly struct ValueTuple + { + + } + + public Publication(string sortName, string? description, Dictionary altTitles, string[] tags, string? posterUrl, Dictionary? links, int? year, string? originalLanguage, string status, string downloadUrl) { this.sortName = sortName; this.description = description; this.altTitles = altTitles; this.tags = tags; this.posterUrl = posterUrl; - this.links = links; + this.links = links ?? new Dictionary(); this.year = year; this.originalLanguage = originalLanguage; this.status = status; this.downloadUrl = downloadUrl; this.folderName = string.Concat(sortName.Split(Path.GetInvalidPathChars().Concat(Path.GetInvalidFileNameChars()).ToArray())); - this.internalId = internalId; + this.internalId = Guid.NewGuid().ToString(); } /// Serialized JSON String for series.json diff --git a/Tranga/TaskExecutor.cs b/Tranga/TaskExecutor.cs index aa8ca7a..8f2c0d0 100644 --- a/Tranga/TaskExecutor.cs +++ b/Tranga/TaskExecutor.cs @@ -17,7 +17,7 @@ public static class TaskExecutor /// Current chapterCollection to update /// /// Is thrown when there is no Connector available with the name of the TrangaTask.connectorName - public static void Execute(TaskManager taskManager, TrangaTask trangaTask, Dictionary> chapterCollection, Logger? logger) + public static void Execute(TaskManager taskManager, TrangaTask trangaTask, Logger? logger) { //Only execute task if it is not already being executed. if (trangaTask.state == TrangaTask.ExecutionState.Running) @@ -37,13 +37,13 @@ public static class TaskExecutor switch (trangaTask.task) { case TrangaTask.Task.DownloadNewChapters: - DownloadNewChapters(connector!, (Publication)trangaTask.publication!, trangaTask.language, chapterCollection); + DownloadNewChapters(connector!, (Publication)trangaTask.publication!, trangaTask.language, ref taskManager._chapterCollection); break; case TrangaTask.Task.UpdateChapters: - UpdateChapters(connector!, (Publication)trangaTask.publication!, trangaTask.language, chapterCollection); + UpdateChapters(connector!, (Publication)trangaTask.publication!, trangaTask.language, ref taskManager._chapterCollection); break; case TrangaTask.Task.UpdatePublications: - UpdatePublications(connector!, chapterCollection); + UpdatePublications(connector!, ref taskManager._chapterCollection); break; case TrangaTask.Task.UpdateKomgaLibrary: UpdateKomgaLibrary(taskManager); @@ -75,7 +75,7 @@ public static class TaskExecutor /// /// Connector to receive Publications from /// - private static void UpdatePublications(Connector connector, Dictionary> chapterCollection) + private static void UpdatePublications(Connector connector, ref Dictionary> chapterCollection) { Publication[] publications = connector.GetPublications(); foreach (Publication publication in publications) @@ -90,9 +90,9 @@ public static class TaskExecutor /// Publication to check /// Language to receive chapters for /// - private static void DownloadNewChapters(Connector connector, Publication publication, string language, Dictionary> chapterCollection) + private static void DownloadNewChapters(Connector connector, Publication publication, string language, ref Dictionary> chapterCollection) { - List newChapters = UpdateChapters(connector, publication, language, chapterCollection); + List newChapters = UpdateChapters(connector, publication, language, ref chapterCollection); connector.DownloadCover(publication); //Check if Publication already has a Folder and a series.json @@ -116,7 +116,7 @@ public static class TaskExecutor /// Language to receive chapters for /// /// List of Chapters that were previously not in collection - private static List UpdateChapters(Connector connector, Publication publication, string language, Dictionary> chapterCollection) + private static List UpdateChapters(Connector connector, Publication publication, string language, ref Dictionary> chapterCollection) { List newChaptersList = new(); chapterCollection.TryAdd(publication, newChaptersList); //To ensure publication is actually in collection diff --git a/Tranga/TaskManager.cs b/Tranga/TaskManager.cs index 23f577a..2fb421d 100644 --- a/Tranga/TaskManager.cs +++ b/Tranga/TaskManager.cs @@ -10,7 +10,7 @@ namespace Tranga; /// public class TaskManager { - private readonly Dictionary> _chapterCollection = new(); + public Dictionary> _chapterCollection = new(); private readonly HashSet _allTasks; private bool _continueRunning = true; private readonly Connector[] _connectors; @@ -106,7 +106,7 @@ public class TaskManager logger?.WriteLine(this.GetType().ToString(), $"Forcing Execution: {task}"); Task t = new Task(() => { - TaskExecutor.Execute(this, task, this._chapterCollection, logger); + TaskExecutor.Execute(this, task, logger); }); t.Start(); } @@ -227,6 +227,14 @@ public class TaskManager _allTasks.CopyTo(ret); return ret; } + + public Publication[] GetPublicationsFromConnector(Connector connector, string? title = null) + { + Publication[] ret = connector.GetPublications(title ?? ""); + foreach(Publication publication in ret) + this._chapterCollection.TryAdd(publication, new List()); + return ret; + } /// All added Publications public Publication[] GetAllPublications() @@ -290,8 +298,11 @@ public class TaskManager private void ExportData() { logger?.WriteLine(this.GetType().ToString(), $"Exporting data to {settings.settingsFilePath}"); + + string serializedData = JsonConvert.SerializeObject(settings); + File.WriteAllText(settings.settingsFilePath, serializedData); } From 84dbc36bbf3418e4983cb2ba6b6ae8d7ac0680fe Mon Sep 17 00:00:00 2001 From: glax Date: Sun, 21 May 2023 21:23:51 +0200 Subject: [PATCH 04/13] dont add duplicates --- Tranga/TaskManager.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Tranga/TaskManager.cs b/Tranga/TaskManager.cs index 2fb421d..76dffd1 100644 --- a/Tranga/TaskManager.cs +++ b/Tranga/TaskManager.cs @@ -231,8 +231,11 @@ public class TaskManager public Publication[] GetPublicationsFromConnector(Connector connector, string? title = null) { Publication[] ret = connector.GetPublications(title ?? ""); - foreach(Publication publication in ret) - this._chapterCollection.TryAdd(publication, new List()); + foreach (Publication publication in ret) + { + if(!_chapterCollection.Any(pub => pub.Key.sortName == publication.sortName)) + this._chapterCollection.TryAdd(publication, new List()); + } return ret; } From ea69b355b5a502db9d88b262460c49ab70e571b1 Mon Sep 17 00:00:00 2001 From: glax Date: Sun, 21 May 2023 21:24:04 +0200 Subject: [PATCH 05/13] No duplicate keys --- Tranga/Connectors/MangaDex.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tranga/Connectors/MangaDex.cs b/Tranga/Connectors/MangaDex.cs index 251bc30..cfaa60a 100644 --- a/Tranga/Connectors/MangaDex.cs +++ b/Tranga/Connectors/MangaDex.cs @@ -63,7 +63,7 @@ public class MangaDex : Connector { JsonObject altTitleObject = (JsonObject)altTitleNode!; string key = ((IDictionary)altTitleObject).Keys.ToArray()[0]; - altTitlesDict.Add(key, altTitleObject[key]!.GetValue()); + altTitlesDict.TryAdd(key, altTitleObject[key]!.GetValue()); } JsonArray tagsObject = attributes["tags"]!.AsArray(); From 9afb81cee2cc4ed203aa26cd9790de469ffa11a7 Mon Sep 17 00:00:00 2001 From: glax Date: Sun, 21 May 2023 21:24:18 +0200 Subject: [PATCH 06/13] string and json --- Tranga-API/Program.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tranga-API/Program.cs b/Tranga-API/Program.cs index b7f0a70..84c0698 100644 --- a/Tranga-API/Program.cs +++ b/Tranga-API/Program.cs @@ -99,7 +99,7 @@ app.MapPost("/Queue/Dequeue", (string taskType, string? connectorName, string? p app.MapGet("/Settings/Get", () => new Settings(taskManager.settings)); -app.MapPost("/Setting/Update", (string? downloadLocation, string? komgaUrl, string? komgaAuth) => +app.MapPost("/Settings/Update", (string? downloadLocation, string? komgaUrl, string? komgaAuth) => { if(downloadLocation is not null) taskManager.settings.downloadLocation = downloadLocation; @@ -111,8 +111,8 @@ app.Run(); class Settings { - public string downloadLocation; - public Komga? komga; + public string downloadLocation { get; } + public Komga? komga { get; } public Settings(TaskManager.SettingsData settings) { From 431a602a40e24f9ec0603118f82037cb705812ce Mon Sep 17 00:00:00 2001 From: glax Date: Sun, 21 May 2023 22:01:04 +0200 Subject: [PATCH 07/13] Added Method UpdateSettings to SettingsData Added Method UpdateSettings to TaskManager (to export data after update) --- Tranga/TaskManager.cs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/Tranga/TaskManager.cs b/Tranga/TaskManager.cs index 76dffd1..74121c9 100644 --- a/Tranga/TaskManager.cs +++ b/Tranga/TaskManager.cs @@ -43,6 +43,15 @@ public class TaskManager taskChecker.Start(); } + public void UpdateSettings(string? downloadLocation, string? komgaUrl, string? komgaAuth) + { + Komga? komga = null; + if (komgaUrl is not null && komgaAuth is not null) + komga = new Komga(komgaUrl, komgaAuth, null); + settings.UpdateSettings(downloadLocation, komga); + ExportData(); + } + public TaskManager(SettingsData settings, Logger? logger = null) { this.logger = logger; @@ -311,9 +320,9 @@ public class TaskManager public class SettingsData { - public string downloadLocation { get; set; } + public string downloadLocation { get; private set; } public string settingsFilePath { get; } - public Komga? komga { get; set; } + public Komga? komga { get; private set; } public HashSet allTasks { get; } public SettingsData(string downloadLocation, string? settingsFilePath, Komga? komga, HashSet allTasks) @@ -325,5 +334,13 @@ public class TaskManager this.komga = komga; this.allTasks = allTasks; } + + public void UpdateSettings(string? pDownloadLocation, Komga? pKomga) + { + if(pDownloadLocation is not null) + this.downloadLocation = pDownloadLocation; + if(pKomga is not null) + this.komga = pKomga; + } } } \ No newline at end of file From 53bff61174eeb7aaa8c67a5ca898cbf363f21152 Mon Sep 17 00:00:00 2001 From: glax Date: Sun, 21 May 2023 22:01:28 +0200 Subject: [PATCH 08/13] Added Swagger --- Tranga-API/Program.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Tranga-API/Program.cs b/Tranga-API/Program.cs index 84c0698..78f2773 100644 --- a/Tranga-API/Program.cs +++ b/Tranga-API/Program.cs @@ -25,8 +25,14 @@ else TaskManager taskManager = new (settings, logger); var builder = WebApplication.CreateBuilder(args); +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); builder.Services.AddControllers().AddNewtonsoftJson(); var app = builder.Build(); +app.UseSwagger(); +app.UseSwaggerUI(); +app.UseSwagger(); +app.UseSwaggerUI(); app.MapGet("/GetAvailableControllers", () => taskManager.GetAvailableConnectors()); From aef01b684cae18ae712248c4bf7c249341c79907 Mon Sep 17 00:00:00 2001 From: glax Date: Sun, 21 May 2023 22:01:40 +0200 Subject: [PATCH 09/13] Fixed null on settings.komga --- Tranga-API/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tranga-API/Program.cs b/Tranga-API/Program.cs index 78f2773..deffeb7 100644 --- a/Tranga-API/Program.cs +++ b/Tranga-API/Program.cs @@ -123,6 +123,6 @@ class Settings public Settings(TaskManager.SettingsData settings) { this.downloadLocation = settings.downloadLocation; - this.komga = komga; + this.komga = settings.komga; } } \ No newline at end of file From 737eebf599ce903ae010cd826b074492da32e835 Mon Sep 17 00:00:00 2001 From: glax Date: Sun, 21 May 2023 22:01:56 +0200 Subject: [PATCH 10/13] bring /settings/update in line with new methods --- Tranga-API/Program.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Tranga-API/Program.cs b/Tranga-API/Program.cs index deffeb7..5681423 100644 --- a/Tranga-API/Program.cs +++ b/Tranga-API/Program.cs @@ -105,13 +105,7 @@ app.MapPost("/Queue/Dequeue", (string taskType, string? connectorName, string? p app.MapGet("/Settings/Get", () => new Settings(taskManager.settings)); -app.MapPost("/Settings/Update", (string? downloadLocation, string? komgaUrl, string? komgaAuth) => -{ - if(downloadLocation is not null) - taskManager.settings.downloadLocation = downloadLocation; - if(komgaUrl is not null && komgaAuth is not null) - taskManager.settings.komga = new Komga(komgaUrl, komgaAuth, logger); -}); +app.MapPost("/Settings/Update", (string? downloadLocation, string? komgaUrl, string? komgaAuth) => taskManager.UpdateSettings(downloadLocation, komgaUrl, komgaAuth) ); app.Run(); From b55d2a2d0654b8f4126ea618afcf6c4add984fff Mon Sep 17 00:00:00 2001 From: glax Date: Sun, 21 May 2023 22:02:05 +0200 Subject: [PATCH 11/13] no duplicate keys --- Tranga/TaskManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tranga/TaskManager.cs b/Tranga/TaskManager.cs index 74121c9..6419f8f 100644 --- a/Tranga/TaskManager.cs +++ b/Tranga/TaskManager.cs @@ -163,7 +163,7 @@ public class TaskManager trangaTask.publication?.downloadUrl == publication?.downloadUrl)) { if(task != TrangaTask.Task.UpdatePublications) - _chapterCollection.Add((Publication)publication!, new List()); + _chapterCollection.TryAdd((Publication)publication!, new List()); _allTasks.Add(newTask); } } From 6d49b4b934cce70690c9671a09be51d579916fa8 Mon Sep 17 00:00:00 2001 From: glax Date: Sun, 21 May 2023 22:02:19 +0200 Subject: [PATCH 12/13] Swagger --- Tranga-API/Tranga-API.csproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Tranga-API/Tranga-API.csproj b/Tranga-API/Tranga-API.csproj index 3b1d193..376581d 100644 --- a/Tranga-API/Tranga-API.csproj +++ b/Tranga-API/Tranga-API.csproj @@ -21,6 +21,8 @@ + + From cf171d5c381e515e9ace06838928438d60ccaf97 Mon Sep 17 00:00:00 2001 From: glax Date: Sun, 21 May 2023 22:02:35 +0200 Subject: [PATCH 13/13] Bring CLI in line with new Methods --- Tranga-CLI/Tranga_Cli.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tranga-CLI/Tranga_Cli.cs b/Tranga-CLI/Tranga_Cli.cs index 3f7e48e..72169e5 100644 --- a/Tranga-CLI/Tranga_Cli.cs +++ b/Tranga-CLI/Tranga_Cli.cs @@ -41,7 +41,7 @@ public static class Tranga_Cli while(tmpPath is null) tmpPath = Console.ReadLine(); if(tmpPath.Length > 0) - settings.downloadLocation = tmpPath; + settings.UpdateSettings(pDownloadLocation: tmpPath, null); Console.WriteLine($"Komga BaseURL [{settings.komga?.baseUrl}]:"); string? tmpUrl = Console.ReadLine(); @@ -73,8 +73,8 @@ public static class Tranga_Cli tmpPass += keyInfo.KeyChar; } } while (key != ConsoleKey.Enter); - - settings.komga = new Komga(tmpUrl, tmpUser, tmpPass, logger); + + settings.UpdateSettings(null, new Komga(tmpUrl, tmpUser, tmpPass, logger)); } logger.WriteLine("Tranga_CLI", "Loaded.");