about summary refs log tree commit diff
path: root/ModerationClient/Services
diff options
context:
space:
mode:
authorRory& <root@rory.gay>2024-07-29 22:45:36 +0200
committerRory& <root@rory.gay>2024-08-08 03:02:10 +0200
commit03f1669d98e1fad81bc4832900ae149ac6510ebc (patch)
tree625361563a92452297f3e2700946e51e513e78b9 /ModerationClient/Services
downloadModerationClient-03f1669d98e1fad81bc4832900ae149ac6510ebc.tar.xz
Initial commit
Diffstat (limited to 'ModerationClient/Services')
-rw-r--r--ModerationClient/Services/CommandLineConfiguration.cs52
-rw-r--r--ModerationClient/Services/FileStorageProvider.cs54
-rw-r--r--ModerationClient/Services/MatrixAuthenticationService.cs56
-rw-r--r--ModerationClient/Services/ModerationClientConfiguration.cs31
4 files changed, 193 insertions, 0 deletions
diff --git a/ModerationClient/Services/CommandLineConfiguration.cs b/ModerationClient/Services/CommandLineConfiguration.cs
new file mode 100644

index 0000000..4debd5c --- /dev/null +++ b/ModerationClient/Services/CommandLineConfiguration.cs
@@ -0,0 +1,52 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using ArcaneLibs; +using Microsoft.Extensions.Logging; + +namespace ModerationClient.Services; + +public class CommandLineConfiguration { + public CommandLineConfiguration(ILogger<CommandLineConfiguration> logger) { + var args = Environment.GetCommandLineArgs(); + logger.LogInformation("Command line arguments: " + string.Join(", ", args)); + for (var i = 0; i < args.Length; i++) { + logger.LogInformation("Processing argument: " + args[i]); + switch (args[i]) { + case "--profile": + case "-p": + if (args.Length <= i + 1 || args[i + 1].StartsWith("-")) { + throw new ArgumentException("No profile specified"); + } + + Profile = args[++i]; + logger.LogInformation("Set profile to: " + Profile); + break; + case "--temporary": + IsTemporary = true; + logger.LogInformation("Using temporary profile"); + break; + case "--profile-dir": + ProfileDirectory = args[++i]; + break; + case "--scale": + Scale = float.Parse(args[++i]); + break; + } + } + + if (string.IsNullOrWhiteSpace(ProfileDirectory)) + ProfileDirectory = IsTemporary + ? Directory.CreateTempSubdirectory("ModerationClient-tmp").FullName + : Util.ExpandPath($"$HOME/.local/share/ModerationClient/{Profile}"); + + logger.LogInformation("Profile directory: " + ProfileDirectory); + Directory.CreateDirectory(ProfileDirectory); + } + + public string Profile { get; private set; } = "default"; + public bool IsTemporary { get; private set; } + + public string ProfileDirectory { get; private set; } + public float Scale { get; private set; } = 1f; +} \ No newline at end of file diff --git a/ModerationClient/Services/FileStorageProvider.cs b/ModerationClient/Services/FileStorageProvider.cs new file mode 100644
index 0000000..3658369 --- /dev/null +++ b/ModerationClient/Services/FileStorageProvider.cs
@@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Linq; +using System.Text.Json; +using System.Threading.Tasks; +using ArcaneLibs.Extensions; +using LibMatrix.Extensions; +using LibMatrix.Interfaces.Services; +using Microsoft.Extensions.Logging; + +namespace MatrixUtils.Abstractions; + +public class FileStorageProvider : IStorageProvider { + private readonly ILogger<FileStorageProvider> _logger; + + public string TargetPath { get; } + + /// <summary> + /// Creates a new instance of <see cref="FileStorageProvider" />. + /// </summary> + /// <param name="targetPath"></param> + public FileStorageProvider(string targetPath) { + // new Logger<FileStorageProvider>(new LoggerFactory()).LogInformation("test"); + Console.WriteLine($"Initialised FileStorageProvider with path {targetPath}"); + TargetPath = targetPath; + if (!Directory.Exists(targetPath)) { + Directory.CreateDirectory(targetPath); + } + } + + public async Task SaveObjectAsync<T>(string key, T value) => await File.WriteAllTextAsync(Path.Join(TargetPath, key), value?.ToJson()); + + [RequiresUnreferencedCode("This API uses reflection to deserialize JSON")] + public async Task<T?> LoadObjectAsync<T>(string key) => JsonSerializer.Deserialize<T>(await File.ReadAllTextAsync(Path.Join(TargetPath, key))); + + public Task<bool> ObjectExistsAsync(string key) => Task.FromResult(File.Exists(Path.Join(TargetPath, key))); + + public Task<List<string>> GetAllKeysAsync() => Task.FromResult(Directory.GetFiles(TargetPath).Select(Path.GetFileName).ToList()); + + public Task DeleteObjectAsync(string key) { + File.Delete(Path.Join(TargetPath, key)); + return Task.CompletedTask; + } + + public async Task SaveStreamAsync(string key, Stream stream) { + Directory.CreateDirectory(Path.GetDirectoryName(Path.Join(TargetPath, key)) ?? throw new InvalidOperationException()); + await using var fileStream = File.Create(Path.Join(TargetPath, key)); + await stream.CopyToAsync(fileStream); + } + + public Task<Stream?> LoadStreamAsync(string key) => Task.FromResult<Stream?>(File.Exists(Path.Join(TargetPath, key)) ? File.OpenRead(Path.Join(TargetPath, key)) : null); +} diff --git a/ModerationClient/Services/MatrixAuthenticationService.cs b/ModerationClient/Services/MatrixAuthenticationService.cs new file mode 100644
index 0000000..69f8810 --- /dev/null +++ b/ModerationClient/Services/MatrixAuthenticationService.cs
@@ -0,0 +1,56 @@ +using System; +using System.IO; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; +using ArcaneLibs; +using ArcaneLibs.Extensions; +using Avalonia.Controls.Diagnostics; +using LibMatrix; +using LibMatrix.Homeservers; +using LibMatrix.Responses; +using LibMatrix.Services; +using MatrixUtils.Desktop; +using Microsoft.Extensions.Logging; + +namespace ModerationClient.Services; + +public class MatrixAuthenticationService(ILogger<MatrixAuthenticationService> logger, HomeserverProviderService hsProvider, CommandLineConfiguration cfg) : NotifyPropertyChanged { + private bool _isLoggedIn = false; + public string Profile => cfg.Profile; + public AuthenticatedHomeserverGeneric? Homeserver { get; private set; } + + public bool IsLoggedIn { + get => _isLoggedIn; + private set => SetField(ref _isLoggedIn, value); + } + + public async Task LoadProfileAsync() { + if (!File.Exists(Util.ExpandPath($"{cfg.ProfileDirectory}/login.json")!)) return; + var loginJson = await File.ReadAllTextAsync(Util.ExpandPath($"{cfg.ProfileDirectory}/login.json")!); + var login = JsonSerializer.Deserialize<LoginResponse>(loginJson); + if (login is null) return; + try { + Homeserver = await hsProvider.GetAuthenticatedWithToken(login.Homeserver, login.AccessToken); + IsLoggedIn = true; + } + catch (MatrixException e) { + if (e is not { Error: MatrixException.ErrorCodes.M_UNKNOWN_TOKEN }) throw; + } + } + + public async Task LoginAsync(string username, string password) { + Directory.CreateDirectory(Util.ExpandPath($"{cfg.ProfileDirectory}")!); + var mxidParts = username.Split(':', 2); + var res = await hsProvider.Login(mxidParts[1], username, password); + await File.WriteAllTextAsync(Path.Combine(cfg.ProfileDirectory, "login.json"), res.ToJson()); + IsLoggedIn = true; + + // Console.WriteLine("Login result: " + res.ToJson()); + } + + public async Task LogoutAsync() { + Directory.Delete(Util.ExpandPath($"{cfg.ProfileDirectory}")!, true); + IsLoggedIn = false; + } +} \ No newline at end of file diff --git a/ModerationClient/Services/ModerationClientConfiguration.cs b/ModerationClient/Services/ModerationClientConfiguration.cs new file mode 100644
index 0000000..f770fef --- /dev/null +++ b/ModerationClient/Services/ModerationClientConfiguration.cs
@@ -0,0 +1,31 @@ +using System; +using System.Collections; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Linq; +using ArcaneLibs; +using ArcaneLibs.Extensions; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace MatrixUtils.Desktop; + +public class ModerationClientConfiguration +{ + private ILogger<ModerationClientConfiguration> _logger; + + [RequiresUnreferencedCode("Uses reflection binding")] + public ModerationClientConfiguration(ILogger<ModerationClientConfiguration> logger, IConfiguration config, HostBuilderContext host) + { + _logger = logger; + logger.LogInformation("Loading configuration for environment: {}...", host.HostingEnvironment.EnvironmentName); + config.GetSection("ModerationClient").Bind(this); + DataStoragePath = Util.ExpandPath(DataStoragePath); + CacheStoragePath = Util.ExpandPath(CacheStoragePath); + } + + public string? DataStoragePath { get; set; } = ""; + public string? CacheStoragePath { get; set; } = ""; + public string? SentryDsn { get; set; } +} \ No newline at end of file