Compare commits

...

7 Commits

Author SHA1 Message Date
72ae124418 Handle unauthorized kavita 2024-02-28 02:25:17 +01:00
bee6e7ba37 Export settings after updating rateLimits 2024-02-28 02:23:58 +01:00
8079ffc742 GlobalBase static is FileInUse 2024-02-28 02:17:48 +01:00
6d6e33491b Indented Json 2024-02-28 02:15:04 +01:00
a8697a14a3 GlobalBase static is FileInUse 2024-02-28 02:14:58 +01:00
e2adac937a Fix settings not being loaded from settingsfile 2024-02-28 02:13:18 +01:00
b4708c5d10 Encoding 850 issue for jsonconvert 2024-02-28 02:12:23 +01:00
6 changed files with 66 additions and 33 deletions

View File

@ -47,7 +47,28 @@ internal sealed class TrangaCli : Command<TrangaCli.Settings>
string? logFilePath = settings.fileLoggerPath ?? ""; string? logFilePath = settings.fileLoggerPath ?? "";
Logger logger = new(enabledLoggers.ToArray(), Console.Out, Console.OutputEncoding, logFilePath); Logger logger = new(enabledLoggers.ToArray(), Console.Out, Console.OutputEncoding, logFilePath);
TrangaSettings trangaSettings = new (settings.downloadLocation, settings.workingDirectory, settings.apiPort); TrangaSettings? trangaSettings = null;
if (settings.downloadLocation is not null && settings.workingDirectory is not null)
{
trangaSettings = new TrangaSettings(settings.downloadLocation, settings.workingDirectory);
}else if (settings.downloadLocation is not null)
{
if (trangaSettings is null)
trangaSettings = new TrangaSettings(downloadLocation: settings.downloadLocation);
else
trangaSettings = new TrangaSettings(downloadLocation: settings.downloadLocation, settings.workingDirectory);
}else if (settings.workingDirectory is not null)
{
if (trangaSettings is null)
trangaSettings = new TrangaSettings(downloadLocation: settings.workingDirectory);
else
trangaSettings = new TrangaSettings(settings.downloadLocation, settings.workingDirectory);
}
else
{
trangaSettings = new TrangaSettings();
}
Directory.CreateDirectory(trangaSettings.downloadLocation); Directory.CreateDirectory(trangaSettings.downloadLocation);
Directory.CreateDirectory(trangaSettings.workingDirectory); Directory.CreateDirectory(trangaSettings.workingDirectory);

View File

@ -9,7 +9,8 @@ namespace Tranga;
public abstract class GlobalBase public abstract class GlobalBase
{ {
protected Logger? logger { get; init; } [JsonIgnore]
public Logger? logger { get; init; }
protected TrangaSettings settings { get; init; } protected TrangaSettings settings { get; init; }
protected HashSet<NotificationConnector> notificationConnectors { get; init; } protected HashSet<NotificationConnector> notificationConnectors { get; init; }
protected HashSet<LibraryConnector> libraryConnectors { get; init; } protected HashSet<LibraryConnector> libraryConnectors { get; init; }
@ -88,7 +89,7 @@ public abstract class GlobalBase
while(IsFileInUse(settings.libraryConnectorsFilePath)) while(IsFileInUse(settings.libraryConnectorsFilePath))
Thread.Sleep(100); Thread.Sleep(100);
Log("Exporting libraryConnectors"); Log("Exporting libraryConnectors");
File.WriteAllText(settings.libraryConnectorsFilePath, JsonConvert.SerializeObject(libraryConnectors)); File.WriteAllText(settings.libraryConnectorsFilePath, JsonConvert.SerializeObject(libraryConnectors, Formatting.Indented));
} }
protected void DeleteLibraryConnector(LibraryConnector.LibraryType libraryType) protected void DeleteLibraryConnector(LibraryConnector.LibraryType libraryType)
@ -98,10 +99,12 @@ public abstract class GlobalBase
while(IsFileInUse(settings.libraryConnectorsFilePath)) while(IsFileInUse(settings.libraryConnectorsFilePath))
Thread.Sleep(100); Thread.Sleep(100);
Log("Exporting libraryConnectors"); Log("Exporting libraryConnectors");
File.WriteAllText(settings.libraryConnectorsFilePath, JsonConvert.SerializeObject(libraryConnectors)); File.WriteAllText(settings.libraryConnectorsFilePath, JsonConvert.SerializeObject(libraryConnectors, Formatting.Indented));
} }
protected bool IsFileInUse(string filePath) protected bool IsFileInUse(string filePath) => IsFileInUse(filePath, this.logger);
public static bool IsFileInUse(string filePath, Logger? logger)
{ {
if (!File.Exists(filePath)) if (!File.Exists(filePath))
return false; return false;
@ -113,7 +116,7 @@ public abstract class GlobalBase
} }
catch (IOException) catch (IOException)
{ {
Log($"File is in use {filePath}"); logger?.WriteLine($"File is in use {filePath}");
return true; return true;
} }
} }

View File

@ -1,4 +1,5 @@
using System.Text.Json.Nodes; using System.Text.Json.Nodes;
using Logging;
using Newtonsoft.Json; using Newtonsoft.Json;
using JsonSerializer = System.Text.Json.JsonSerializer; using JsonSerializer = System.Text.Json.JsonSerializer;
@ -8,7 +9,7 @@ public class Kavita : LibraryConnector
{ {
public Kavita(GlobalBase clone, string baseUrl, string username, string password) : public Kavita(GlobalBase clone, string baseUrl, string username, string password) :
base(clone, baseUrl, GetToken(baseUrl, username, password), LibraryType.Kavita) base(clone, baseUrl, GetToken(baseUrl, username, password, clone.logger), LibraryType.Kavita)
{ {
} }
@ -22,7 +23,7 @@ public class Kavita : LibraryConnector
return $"Kavita {baseUrl}"; return $"Kavita {baseUrl}";
} }
private static string GetToken(string baseUrl, string username, string password) private static string GetToken(string baseUrl, string username, string password, Logger? logger = null)
{ {
HttpClient client = new() HttpClient client = new()
{ {
@ -40,16 +41,24 @@ public class Kavita : LibraryConnector
try try
{ {
HttpResponseMessage response = client.Send(requestMessage); HttpResponseMessage response = client.Send(requestMessage);
logger?.WriteLine($"Kavita | GetToken {requestMessage.RequestUri} -> {response.StatusCode}");
if (response.IsSuccessStatusCode)
{
JsonObject? result = JsonSerializer.Deserialize<JsonObject>(response.Content.ReadAsStream()); JsonObject? result = JsonSerializer.Deserialize<JsonObject>(response.Content.ReadAsStream());
if (result is not null) if (result is not null)
return result["token"]!.GetValue<string>(); return result["token"]!.GetValue<string>();
} }
else
{
logger?.WriteLine($"Kavita | {response.Content}");
}
}
catch (HttpRequestException e) catch (HttpRequestException e)
{ {
Console.WriteLine($"Unable to retrieve token:\n\r{e}"); logger?.WriteLine($"Kavita | Unable to retrieve token:\n\r{e}");
} }
Console.WriteLine("Kavita: Did not receive token."); logger?.WriteLine("Kavita | Did not receive token.");
throw new Exception("Kavita: Did not receive token."); return "";
} }
public override void UpdateLibrary() public override void UpdateLibrary()

View File

@ -23,6 +23,8 @@ public abstract class LibraryConnector : GlobalBase
Log($"Creating libraryConnector {Enum.GetName(libraryType)}"); Log($"Creating libraryConnector {Enum.GetName(libraryType)}");
if (!baseUrlRex.IsMatch(baseUrl)) if (!baseUrlRex.IsMatch(baseUrl))
throw new ArgumentException("Base url does not match pattern"); throw new ArgumentException("Base url does not match pattern");
if(auth == "")
throw new ArgumentNullException(nameof(auth), "Auth can not be empty");
this.baseUrl = baseUrlRex.Match(baseUrl).Value; this.baseUrl = baseUrlRex.Match(baseUrl).Value;
this.auth = auth; this.auth = auth;
this.libraryType = libraryType; this.libraryType = libraryType;

View File

@ -439,6 +439,7 @@ public class Server : GlobalBase
SendResponse(HttpStatusCode.Accepted, response); SendResponse(HttpStatusCode.Accepted, response);
}else }else
SendResponse(HttpStatusCode.BadRequest, response); SendResponse(HttpStatusCode.BadRequest, response);
settings.ExportSettings();
break; break;
case "NotificationConnectors/Update": case "NotificationConnectors/Update":
if (!requestVariables.TryGetValue("notificationConnector", out notificationConnectorStr) || if (!requestVariables.TryGetValue("notificationConnector", out notificationConnectorStr) ||

View File

@ -36,21 +36,28 @@ public class TrangaSettings
public TrangaSettings(string? downloadLocation = null, string? workingDirectory = null, int? apiPortNumber = null) public TrangaSettings(string? downloadLocation = null, string? workingDirectory = null, int? apiPortNumber = null)
{ {
string lockFilePath = $"{settingsFilePath}.lock"; string wd = workingDirectory ?? Path.Join(RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "/usr/share" : Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "tranga-api");
if (File.Exists(settingsFilePath) && !File.Exists(lockFilePath)) string sfp = Path.Join(wd, "settings.json");
string lockFilePath = $"{sfp}.lock";
if (File.Exists(sfp) && !File.Exists(lockFilePath))
{//Load from settings file {//Load from settings file
FileStream lockFile = File.Create(lockFilePath,0, FileOptions.DeleteOnClose); //lock settingsfile FileStream lockFile = File.Create(lockFilePath,0, FileOptions.DeleteOnClose); //lock settingsfile
string settingsStr = File.ReadAllText(settingsFilePath); string settingsStr = File.ReadAllText(sfp);
TrangaSettings settings = JsonConvert.DeserializeObject<TrangaSettings>(settingsStr)!; TrangaSettings settings = JsonConvert.DeserializeObject<TrangaSettings>(settingsStr)!;
this.requestLimits = settings.requestLimits;
this.userAgent = settings.userAgent;
this.downloadLocation = downloadLocation ?? settings.downloadLocation; this.downloadLocation = downloadLocation ?? settings.downloadLocation;
this.workingDirectory = workingDirectory ?? settings.workingDirectory; this.workingDirectory = workingDirectory ?? settings.workingDirectory;
this.apiPortNumber = apiPortNumber ?? settings.apiPortNumber; this.apiPortNumber = apiPortNumber ?? settings.apiPortNumber;
lockFile.Close(); //unlock settingsfile lockFile.Close(); //unlock settingsfile
} }
else if(!File.Exists(settingsFilePath)) else if(!File.Exists(sfp))
{//No settings file exists {//No settings file exists
if (downloadLocation?.Length < 1 || workingDirectory?.Length < 1) if (downloadLocation?.Length < 1 || workingDirectory?.Length < 1)
throw new ArgumentException("Download-location and working-directory paths can not be empty!"); throw new ArgumentException("Download-location and working-directory paths can not be empty!");
this.requestLimits = DefaultRequestLimits;
this.userAgent = DefaultUserAgent;
this.apiPortNumber = apiPortNumber ?? 6531; this.apiPortNumber = apiPortNumber ?? 6531;
this.downloadLocation = downloadLocation ?? (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "/Manga" : Path.Join(Directory.GetCurrentDirectory(), "Downloads")); this.downloadLocation = downloadLocation ?? (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "/Manga" : Path.Join(Directory.GetCurrentDirectory(), "Downloads"));
this.workingDirectory = workingDirectory ?? Path.Join(RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "/usr/share" : Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "tranga-api"); this.workingDirectory = workingDirectory ?? Path.Join(RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "/usr/share" : Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "tranga-api");
@ -58,6 +65,8 @@ public class TrangaSettings
} }
else else
{//Settingsfile is locked {//Settingsfile is locked
this.requestLimits = DefaultRequestLimits;
this.userAgent = DefaultUserAgent;
this.apiPortNumber = apiPortNumber!.Value; this.apiPortNumber = apiPortNumber!.Value;
this.downloadLocation = downloadLocation!; this.downloadLocation = downloadLocation!;
this.workingDirectory = workingDirectory!; this.workingDirectory = workingDirectory!;
@ -130,24 +139,12 @@ public class TrangaSettings
{ {
if (File.Exists(settingsFilePath)) if (File.Exists(settingsFilePath))
{ {
bool inUse = true; while(GlobalBase.IsFileInUse(settingsFilePath, null))
while (inUse)
{
try
{
using FileStream stream = new(settingsFilePath, FileMode.Open, FileAccess.Read, FileShare.None);
stream.Close();
inUse = false;
}
catch (IOException)
{
Thread.Sleep(100); Thread.Sleep(100);
} }
}
}
else else
Directory.CreateDirectory(new FileInfo(settingsFilePath).DirectoryName!); Directory.CreateDirectory(new FileInfo(settingsFilePath).DirectoryName!);
File.WriteAllText(settingsFilePath, JsonConvert.SerializeObject(this)); File.WriteAllText(settingsFilePath, JsonConvert.SerializeObject(this, Formatting.Indented));
} }
public string GetFullCoverPath(Manga manga) public string GetFullCoverPath(Manga manga)