diff --git a/ModerationClient/Services/ClientContainer.cs b/ModerationClient/Services/ClientContainer.cs
new file mode 100644
index 0000000..fa3abef
--- /dev/null
+++ b/ModerationClient/Services/ClientContainer.cs
@@ -0,0 +1,8 @@
+namespace ModerationClient.Services;
+
+public class ClientContainer {
+ public ClientContainer(MatrixAuthenticationService authService, CommandLineConfiguration cfg)
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/ModerationClient/Services/CommandLineConfiguration.cs b/ModerationClient/Services/CommandLineConfiguration.cs
index 63c3691..4f7da2d 100644
--- a/ModerationClient/Services/CommandLineConfiguration.cs
+++ b/ModerationClient/Services/CommandLineConfiguration.cs
@@ -2,15 +2,14 @@ using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
+using System.Text.Json;
using ArcaneLibs;
-using Microsoft.Extensions.Logging;
+using ArcaneLibs.Extensions;
namespace ModerationClient.Services;
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
public record CommandLineConfiguration {
- private readonly string? _loginData;
-
public static CommandLineConfiguration FromProcessArgs() {
// logger.LogInformation("Command line arguments: " + string.Join(", ", Environment.GetCommandLineArgs()));
CommandLineConfiguration cfg = FromSerialised(Environment.GetCommandLineArgs());
@@ -27,24 +26,27 @@ public record CommandLineConfiguration {
if (!string.IsNullOrWhiteSpace(cfg.LoginData)) {
File.WriteAllText(Path.Combine(cfg.ProfileDirectory, "login.json"), cfg.LoginData);
}
+
+
return cfg;
}
-
public string[] Serialise() {
+ var current = FromProcessArgs();
List<string> args = new();
- if (Profile != "default") args.AddRange(["--profile", Profile]);
+ if (Profile != current.Profile) args.AddRange(["--profile", Profile]);
if (IsTemporary) args.Add("--temporary");
if (Math.Abs(Scale - 1f) > float.Epsilon) args.AddRange(["--scale", Scale.ToString()]);
- if (ProfileDirectory != Util.ExpandPath("$HOME/.local/share/ModerationClient/default")) args.AddRange(["--profile-dir", ProfileDirectory]);
- if (!string.IsNullOrWhiteSpace(_loginData)) args.AddRange(["--login-data", _loginData!]);
+ if (ProfileDirectory != current.ProfileDirectory) args.AddRange(["--profile-dir", ProfileDirectory]);
+ if (!string.IsNullOrWhiteSpace(_loginData) && _loginData != current.LoginData) args.AddRange(["--login-data", _loginData!]);
+ if (TestConfiguration is not null && TestConfiguration != current.TestConfiguration) args.AddRange(["--test-config", TestConfiguration!.ToJson()]);
return args.ToArray();
}
-
public static CommandLineConfiguration FromSerialised(string[] args) {
CommandLineConfiguration cfg = new();
for (var i = 0; i < args.Length; i++) {
switch (args[i]) {
case "--profile":
+ case "-p":
cfg = cfg with { Profile = args[++i] };
break;
case "--temporary":
@@ -59,12 +61,16 @@ public record CommandLineConfiguration {
case "--login-data":
cfg = cfg with { LoginData = args[++i] };
break;
+ case "--test-config":
+ cfg = cfg with { testConfiguration = args[++i] };
+ break;
}
}
return cfg;
}
+ private readonly string? _loginData;
public string Profile { get; init; } = "default";
public bool IsTemporary { get; init; }
@@ -78,4 +84,15 @@ public record CommandLineConfiguration {
_loginData = value;
}
}
+
+ private string? testConfiguration {
+ get => TestConfiguration?.ToJson();
+ init => TestConfiguration = value is null ? null : JsonSerializer.Deserialize<TestConfig>(value);
+ }
+
+ public TestConfig? TestConfiguration { get; init; }
+
+ public class TestConfig {
+ public List<string> Mxids { get; set; } = new();
+ }
}
\ No newline at end of file
diff --git a/ModerationClient/Services/FileStorageProvider.cs b/ModerationClient/Services/FileStorageProvider.cs
index 3658369..5b43ce4 100644
--- a/ModerationClient/Services/FileStorageProvider.cs
+++ b/ModerationClient/Services/FileStorageProvider.cs
@@ -1,19 +1,28 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
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;
+namespace ModerationClient.Services;
public class FileStorageProvider : IStorageProvider {
- private readonly ILogger<FileStorageProvider> _logger;
+ // private readonly ILogger<FileStorageProvider> _logger;
+ private static readonly JsonSerializerOptions Options = new() {
+ WriteIndented = true
+ };
+
+ private static readonly EnumerationOptions EnumOpts = new EnumerationOptions() {
+ MatchType = MatchType.Simple,
+ AttributesToSkip = FileAttributes.None,
+ IgnoreInaccessible = false,
+ RecurseSubdirectories = true
+ };
public string TargetPath { get; }
@@ -30,25 +39,58 @@ public class FileStorageProvider : IStorageProvider {
}
}
- public async Task SaveObjectAsync<T>(string key, T value) => await File.WriteAllTextAsync(Path.Join(TargetPath, key), value?.ToJson());
+ public async Task SaveObjectAsync<T>(string key, T value) {
+ EnsureContainingDirectoryExists(GetFullPath(key));
+ await using var fileStream = File.Create(GetFullPath(key));
+ await JsonSerializer.SerializeAsync(fileStream, value, Options);
+ }
[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 async Task<T?> LoadObjectAsync<T>(string key) {
+ await using var fileStream = File.OpenRead(GetFullPath(key));
+ return JsonSerializer.Deserialize<T>(fileStream);
+ }
- public Task<bool> ObjectExistsAsync(string key) => Task.FromResult(File.Exists(Path.Join(TargetPath, key)));
+ public Task<bool> ObjectExistsAsync(string key) => Task.FromResult(File.Exists(GetFullPath(key)));
- public Task<List<string>> GetAllKeysAsync() => Task.FromResult(Directory.GetFiles(TargetPath).Select(Path.GetFileName).ToList());
+ public async Task<IEnumerable<string>> GetAllKeysAsync() {
+ var sw = Stopwatch.StartNew();
+ // var result = Directory.EnumerateFiles(TargetPath, "*", SearchOption.AllDirectories)
+ var result = Directory.EnumerateFiles(TargetPath, "*", EnumOpts)
+ .Select(s => s.Replace(TargetPath, "").TrimStart('/'));
+ // Console.WriteLine($"GetAllKeysAsync got {result.Count()} results in {sw.ElapsedMilliseconds}ms");
+ // Environment.Exit(0);
+ return result;
+ }
public Task DeleteObjectAsync(string key) {
- File.Delete(Path.Join(TargetPath, key));
+ File.Delete(GetFullPath(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));
+ EnsureContainingDirectoryExists(GetFullPath(key));
+ await using var fileStream = File.Create(GetFullPath(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);
-}
+ public Task<Stream?> LoadStreamAsync(string key) => Task.FromResult<Stream?>(File.Exists(GetFullPath(key)) ? File.OpenRead(GetFullPath(key)) : null);
+
+ public Task CopyObjectAsync(string sourceKey, string destKey) {
+ EnsureContainingDirectoryExists(GetFullPath(destKey));
+ File.Copy(GetFullPath(sourceKey), GetFullPath(destKey));
+ return Task.CompletedTask;
+ }
+
+ public Task MoveObjectAsync(string sourceKey, string destKey) {
+ EnsureContainingDirectoryExists(GetFullPath(destKey));
+ File.Move(GetFullPath(sourceKey), GetFullPath(destKey));
+ return Task.CompletedTask;
+ }
+
+ private string GetFullPath(string key) => Path.Join(TargetPath, key);
+
+ private void EnsureContainingDirectoryExists(string path) {
+ Directory.CreateDirectory(Path.GetDirectoryName(path) ?? throw new InvalidOperationException());
+ }
+}
\ No newline at end of file
diff --git a/ModerationClient/Services/MatrixAuthenticationService.cs b/ModerationClient/Services/MatrixAuthenticationService.cs
index 7e9ce70..46ec067 100644
--- a/ModerationClient/Services/MatrixAuthenticationService.cs
+++ b/ModerationClient/Services/MatrixAuthenticationService.cs
@@ -1,16 +1,12 @@
-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;
diff --git a/ModerationClient/Services/ModerationClientConfiguration.cs b/ModerationClient/Services/ModerationClientConfiguration.cs
index f770fef..3cc4ffb 100644
--- a/ModerationClient/Services/ModerationClientConfiguration.cs
+++ b/ModerationClient/Services/ModerationClientConfiguration.cs
@@ -1,10 +1,5 @@
-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;
diff --git a/ModerationClient/Services/StatusBarService.cs b/ModerationClient/Services/StatusBarService.cs
new file mode 100644
index 0000000..57aff21
--- /dev/null
+++ b/ModerationClient/Services/StatusBarService.cs
@@ -0,0 +1,19 @@
+using System;
+using ArcaneLibs;
+
+namespace ModerationClient.Services;
+
+public class StatusBarService : NotifyPropertyChanged {
+ private string _statusText = "Ready";
+ private bool _isBusy;
+
+ public string StatusText {
+ get => _statusText + " " + DateTime.Now.ToString("u")[..^1];
+ set => SetField(ref _statusText, value);
+ }
+
+ public bool IsBusy {
+ get => _isBusy;
+ set => SetField(ref _isBusy, value);
+ }
+}
\ No newline at end of file
diff --git a/ModerationClient/Services/TestRunner.cs b/ModerationClient/Services/TestRunner.cs
new file mode 100644
index 0000000..dbacf99
--- /dev/null
+++ b/ModerationClient/Services/TestRunner.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Hosting;
+
+namespace ModerationClient.Services;
+
+public class TestRunner(CommandLineConfiguration.TestConfig testConfig, MatrixAuthenticationService mas) : IHostedService {
+ public async Task StartAsync(CancellationToken cancellationToken) {
+ Console.WriteLine("TestRunner: Starting test runner");
+ mas.PropertyChanged += (_, args) => {
+ if (args.PropertyName == nameof(MatrixAuthenticationService.IsLoggedIn) && mas.IsLoggedIn) {
+ Console.WriteLine("TestRunner: Logged in, starting test");
+ _ = Run();
+ }
+ };
+ }
+
+ public async Task StopAsync(CancellationToken cancellationToken) {
+ Console.WriteLine("TestRunner: Stopping test runner");
+ }
+
+ private async Task Run() {
+ var hs = mas.Homeserver!;
+ Console.WriteLine("TestRunner: Running test on homeserver " + hs);
+ foreach (var mxid in testConfig.Mxids) {
+ var room = await hs.CreateRoom(new() {
+ Name = mxid,
+ Invite = testConfig.Mxids
+ });
+
+ await room.SendMessageEventAsync(new("test"));
+
+ }
+ }
+}
\ No newline at end of file
|