Snarky comments. Documentation

This commit is contained in:
glax 2023-05-20 15:05:41 +02:00
parent 430ee2301f
commit 4ee47ed65c
6 changed files with 71 additions and 13 deletions

View File

@ -4,6 +4,12 @@ using Tranga.Connectors;
namespace Tranga_CLI; namespace Tranga_CLI;
/*
* This is written with pure hatred for readability.
* At some point do this properly.
* Read at own risk.
*/
public static class Tranga_Cli public static class Tranga_Cli
{ {
public static void Main(string[] args) public static void Main(string[] args)
@ -11,7 +17,7 @@ public static class Tranga_Cli
TaskManager.SettingsData settings; TaskManager.SettingsData settings;
string settingsPath = Path.Join(Directory.GetCurrentDirectory(), "data.json"); string settingsPath = Path.Join(Directory.GetCurrentDirectory(), "data.json");
if (File.Exists(settingsPath)) if (File.Exists(settingsPath))
settings = TaskManager.ImportData(Directory.GetCurrentDirectory()); settings = TaskManager.LoadData(Directory.GetCurrentDirectory());
else else
settings = new TaskManager.SettingsData(Directory.GetCurrentDirectory(), null, new HashSet<TrangaTask>()); settings = new TaskManager.SettingsData(Directory.GetCurrentDirectory(), null, new HashSet<TrangaTask>());

View File

@ -68,6 +68,11 @@ public abstract class Connector
File.WriteAllText(seriesInfoPath,publication.GetSeriesInfoJson()); File.WriteAllText(seriesInfoPath,publication.GetSeriesInfoJson());
} }
/// <summary>
/// Creates a string containing XML of publication and chapter.
/// See ComicInfo.xml
/// </summary>
/// <returns>XML-string</returns>
protected static string CreateComicInfo(Publication publication, Chapter chapter) protected static string CreateComicInfo(Publication publication, Chapter chapter)
{ {
XElement comicInfo = new XElement("ComicInfo", XElement comicInfo = new XElement("ComicInfo",
@ -80,11 +85,19 @@ public abstract class Connector
return comicInfo.ToString(); return comicInfo.ToString();
} }
/// <summary>
/// Checks if a chapter-archive is already present
/// </summary>
/// <returns>true if chapter is present</returns>
public bool ChapterIsDownloaded(Publication publication, Chapter chapter) public bool ChapterIsDownloaded(Publication publication, Chapter chapter)
{ {
return File.Exists(CreateFullFilepath(publication, chapter)); return File.Exists(CreateFullFilepath(publication, chapter));
} }
/// <summary>
/// Creates full file path of chapter-archive
/// </summary>
/// <returns>Filepath</returns>
protected string CreateFullFilepath(Publication publication, Chapter chapter) protected string CreateFullFilepath(Publication publication, Chapter chapter)
{ {
return Path.Join(downloadLocation, publication.folderName, chapter.fileName); return Path.Join(downloadLocation, publication.folderName, chapter.fileName);

View File

@ -5,17 +5,26 @@ using JsonSerializer = System.Text.Json.JsonSerializer;
namespace Tranga; namespace Tranga;
/// <summary>
/// Provides connectivity to Komga-API
/// Can fetch and update libraries
/// </summary>
public class Komga public class Komga
{ {
[System.Text.Json.Serialization.JsonRequired]public string baseUrl { get; } public string baseUrl { get; }
[System.Text.Json.Serialization.JsonRequired]public string auth { get; } public string auth { get; } //Base64 encoded, if you use your password everywhere, you have problems
/// <param name="baseUrl">Base-URL of Komga instance, no trailing slashes(/)</param>
/// <param name="username">Komga Username</param>
/// <param name="password">Komga password, will be base64 encoded. yea</param>
public Komga(string baseUrl, string username, string password) public Komga(string baseUrl, string username, string password)
{ {
this.baseUrl = baseUrl; this.baseUrl = baseUrl;
this.auth = Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes($"{username}:{password}")); this.auth = Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes($"{username}:{password}"));
} }
/// <param name="baseUrl">Base-URL of Komga instance, no trailing slashes(/)</param>
/// <param name="auth">Base64 string of username and password (username):(password)</param>
[JsonConstructor] [JsonConstructor]
public Komga(string baseUrl, string auth) public Komga(string baseUrl, string auth)
{ {
@ -23,6 +32,10 @@ public class Komga
this.auth = auth; this.auth = auth;
} }
/// <summary>
/// Fetches all libraries available to the user
/// </summary>
/// <returns>Array of KomgaLibraries</returns>
public KomgaLibrary[] GetLibraries() public KomgaLibrary[] GetLibraries()
{ {
Stream data = NetClient.MakeRequest($"{baseUrl}/api/v1/libraries", auth); Stream data = NetClient.MakeRequest($"{baseUrl}/api/v1/libraries", auth);
@ -43,6 +56,11 @@ public class Komga
return ret.ToArray(); return ret.ToArray();
} }
/// <summary>
/// Updates library with given id
/// </summary>
/// <param name="libraryId">Id of the Komga-Library</param>
/// <returns>true if successful</returns>
public bool UpdateLibrary(string libraryId) public bool UpdateLibrary(string libraryId)
{ {
return NetClient.MakePost($"{baseUrl}/api/v1/libraries/{libraryId}/scan", auth); return NetClient.MakePost($"{baseUrl}/api/v1/libraries/{libraryId}/scan", auth);

View File

@ -35,10 +35,7 @@ public readonly struct Publication
this.downloadUrl = downloadUrl; this.downloadUrl = downloadUrl;
this.folderName = string.Concat(sortName.Split(Path.GetInvalidPathChars().Concat(Path.GetInvalidFileNameChars()).ToArray())); this.folderName = string.Concat(sortName.Split(Path.GetInvalidPathChars().Concat(Path.GetInvalidFileNameChars()).ToArray()));
} }
/// <summary>
///
/// </summary>
/// <returns>Serialized JSON String for series.json</returns> /// <returns>Serialized JSON String for series.json</returns>
public string GetSeriesInfoJson() public string GetSeriesInfoJson()
{ {
@ -57,13 +54,13 @@ public readonly struct Publication
//Only for series.json what an abomination, why are all the fields not-null???? //Only for series.json what an abomination, why are all the fields not-null????
private struct Metadata private struct Metadata
{ {
// ReSharper disable UnusedAutoPropertyAccessor.Local we need it, trust // ReSharper disable UnusedAutoPropertyAccessor.Local we need them all, trust me
[JsonRequired] public string type { get; } [JsonRequired] public string type { get; }
[JsonRequired] public string publisher { get; } [JsonRequired] public string publisher { get; }
// ReSharper disable twice IdentifierTypo // ReSharper disable twice IdentifierTypo
[JsonRequired] public int comicid { get; } [JsonRequired] public int comicid { get; }
[JsonRequired] public string booktype { get; } [JsonRequired] public string booktype { get; }
// ReSharper disable InconsistentNaming // ReSharper disable InconsistentNaming This one property is capitalized. Why?
[JsonRequired] public string ComicImage { get; } [JsonRequired] public string ComicImage { get; }
[JsonRequired] public int total_issues { get; } [JsonRequired] public int total_issues { get; }
[JsonRequired] public string publication_run { get; } [JsonRequired] public string publication_run { get; }
@ -84,7 +81,7 @@ public readonly struct Publication
this.status = status; this.status = status;
this.description_text = description_text; this.description_text = description_text;
//kill it with fire //kill it with fire, but otherwise Komga will not parse
type = "Manga"; type = "Manga";
publisher = ""; publisher = "";
comicid = 0; comicid = 0;

View File

@ -16,10 +16,12 @@ public static class TaskExecutor
/// <exception cref="ArgumentException">Is thrown when there is no Connector available with the name of the TrangaTask.connectorName</exception> /// <exception cref="ArgumentException">Is thrown when there is no Connector available with the name of the TrangaTask.connectorName</exception>
public static void Execute(TaskManager taskManager, TrangaTask trangaTask, Dictionary<Publication, List<Chapter>> chapterCollection) public static void Execute(TaskManager taskManager, TrangaTask trangaTask, Dictionary<Publication, List<Chapter>> chapterCollection)
{ {
//Only execute task if it is not already being executed.
if (trangaTask.state == TrangaTask.ExecutionState.Running) if (trangaTask.state == TrangaTask.ExecutionState.Running)
return; return;
trangaTask.state = TrangaTask.ExecutionState.Running; trangaTask.state = TrangaTask.ExecutionState.Running;
//Connector is not needed for all tasks
Connector? connector = null; Connector? connector = null;
if (trangaTask.task != TrangaTask.Task.UpdateKomgaLibrary) if (trangaTask.task != TrangaTask.Task.UpdateKomgaLibrary)
connector = taskManager.GetConnector(trangaTask.connectorName!); connector = taskManager.GetConnector(trangaTask.connectorName!);

View File

@ -20,6 +20,8 @@ public class TaskManager
/// <param name="folderPath">Local path to save data (Manga) to</param> /// <param name="folderPath">Local path to save data (Manga) to</param>
/// <param name="komgaBaseUrl">The Url of the Komga-instance that you want to update</param> /// <param name="komgaBaseUrl">The Url of the Komga-instance that you want to update</param>
/// <param name="komgaUsername">The Komga username</param>
/// <param name="komgaPassword">The Komga password</param>
public TaskManager(string folderPath, string? komgaBaseUrl = null, string? komgaUsername = null, string? komgaPassword = null) public TaskManager(string folderPath, string? komgaBaseUrl = null, string? komgaUsername = null, string? komgaPassword = null)
{ {
this.downloadLocation = folderPath; this.downloadLocation = folderPath;
@ -47,10 +49,15 @@ public class TaskManager
taskChecker.Start(); taskChecker.Start();
} }
/// <summary>
/// Runs continuously until shutdown.
/// Checks if tasks have to be executed (time elapsed)
/// </summary>
private void TaskCheckerThread() private void TaskCheckerThread()
{ {
while (_continueRunning) while (_continueRunning)
{ {
//Check if previous tasks have finished and execute new tasks
foreach (KeyValuePair<Connector, List<TrangaTask>> connectorTaskQueue in tasksToExecute) foreach (KeyValuePair<Connector, List<TrangaTask>> connectorTaskQueue in tasksToExecute)
{ {
connectorTaskQueue.Value.RemoveAll(task => task.state == TrangaTask.ExecutionState.Waiting); connectorTaskQueue.Value.RemoveAll(task => task.state == TrangaTask.ExecutionState.Waiting);
@ -58,6 +65,8 @@ public class TaskManager
ExecuteTaskNow(connectorTaskQueue.Value.First()); ExecuteTaskNow(connectorTaskQueue.Value.First());
} }
//Check if task should be executed
//Depending on type execute immediately or enqueue
foreach (TrangaTask task in _allTasks.Where(aTask => aTask.ShouldExecute())) foreach (TrangaTask task in _allTasks.Where(aTask => aTask.ShouldExecute()))
{ {
task.state = TrangaTask.ExecutionState.Enqueued; task.state = TrangaTask.ExecutionState.Enqueued;
@ -172,6 +181,11 @@ public class TaskManager
return this._chapterCollection.Keys.ToArray(); return this._chapterCollection.Keys.ToArray();
} }
/// <summary>
/// Return Connector with given Name
/// </summary>
/// <param name="connectorName">Connector-name (exact)</param>
/// <exception cref="Exception">If Connector is not available</exception>
public Connector GetConnector(string connectorName) public Connector GetConnector(string connectorName)
{ {
Connector? ret = this._connectors.FirstOrDefault(connector => connector.name == connectorName); Connector? ret = this._connectors.FirstOrDefault(connector => connector.name == connectorName);
@ -198,7 +212,11 @@ public class TaskManager
Environment.Exit(0); Environment.Exit(0);
} }
public static SettingsData ImportData(string importFolderPath) /// <summary>
/// Loads stored data (settings, tasks) from file
/// </summary>
/// <param name="importFolderPath">working directory, filename has to be data.json</param>
public static SettingsData LoadData(string importFolderPath)
{ {
string importPath = Path.Join(importFolderPath, "data.json"); string importPath = Path.Join(importFolderPath, "data.json");
if (!File.Exists(importPath)) if (!File.Exists(importPath))
@ -210,6 +228,10 @@ public class TaskManager
return data; return data;
} }
/// <summary>
/// Exports data (settings, tasks) to file
/// </summary>
/// <param name="exportFolderPath">Folder path, filename will be data.json</param>
private void ExportData(string exportFolderPath) private void ExportData(string exportFolderPath)
{ {
SettingsData data = new SettingsData(this.downloadLocation, this.komga, this._allTasks); SettingsData data = new SettingsData(this.downloadLocation, this.komga, this._allTasks);