diff options
130 files changed, 335 insertions, 2985 deletions
diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..0620b64 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "LibMatrix"] + path = LibMatrix + url = https://git.rory.gay/matrix/LibMatrix.git diff --git a/.idea/.idea.MatrixRoomUtils/.idea/vcs.xml b/.idea/.idea.MatrixRoomUtils/.idea/vcs.xml index 94a25f7..4720c89 100644 --- a/.idea/.idea.MatrixRoomUtils/.idea/vcs.xml +++ b/.idea/.idea.MatrixRoomUtils/.idea/vcs.xml @@ -2,5 +2,6 @@ <project version="4"> <component name="VcsDirectoryMappings"> <mapping directory="$PROJECT_DIR$" vcs="Git" /> + <mapping directory="$PROJECT_DIR$/MatrixRoomUtils.Core" vcs="Git" /> </component> </project> \ No newline at end of file diff --git a/LibMatrix b/LibMatrix new file mode 160000 +Subproject 8fdc48e5b21b1eea61534b181585858727500f3 diff --git a/MatrixRoomUtils.Bot/Bot/Commands/CmdCommand.cs b/MatrixRoomUtils.Bot/Bot/Commands/CmdCommand.cs deleted file mode 100644 index 79757ae..0000000 --- a/MatrixRoomUtils.Bot/Bot/Commands/CmdCommand.cs +++ /dev/null @@ -1,46 +0,0 @@ -using MatrixRoomUtils.Bot.Bot.Interfaces; - -namespace MatrixRoomUtils.Bot.Bot.Commands; - -public class CmdCommand : ICommand { - public string Name { get; } = "cmd"; - public string Description { get; } = "Runs a command on the host system"; - - public async Task<bool> CanInvoke(CommandContext ctx) { - return ctx.MessageEvent.Sender.EndsWith(":rory.gay"); - } - - public async Task Invoke(CommandContext ctx) { - var cmd = "\""; - foreach (var arg in ctx.Args) cmd += arg + " "; - - cmd = cmd.Trim(); - cmd += "\""; - - await ctx.Room.SendMessageEventAsync("m.room.message", new() { - Body = $"Command being executed: `{cmd}`" - }); - - var output = ArcaneLibs.Util.GetCommandOutputSync( - Environment.OSVersion.Platform == PlatformID.Unix ? "/bin/sh" : "cmd.exe", - (Environment.OSVersion.Platform == PlatformID.Unix ? "-c " : "/c ") + cmd) - .Replace("`", "\\`") - .Split("\n").ToList(); - foreach (var _out in output) Console.WriteLine($"{_out.Length:0000} {_out}"); - - var msg = ""; - while (output.Count > 0) { - Console.WriteLine("Adding: " + output[0]); - msg += output[0] + "\n"; - output.RemoveAt(0); - if ((output.Count > 0 && (msg + output[0]).Length > 64000) || output.Count == 0) { - await ctx.Room.SendMessageEventAsync("m.room.message", new() { - FormattedBody = $"```ansi\n{msg}\n```", - // Body = Markdig.Markdown.ToHtml(msg), - Format = "org.matrix.custom.html" - }); - msg = ""; - } - } - } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Bot/Bot/Commands/HelpCommand.cs b/MatrixRoomUtils.Bot/Bot/Commands/HelpCommand.cs deleted file mode 100644 index 6db10ae..0000000 --- a/MatrixRoomUtils.Bot/Bot/Commands/HelpCommand.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Text; -using MatrixRoomUtils.Bot.Bot.Interfaces; -using Microsoft.Extensions.DependencyInjection; - -namespace MatrixRoomUtils.Bot.Bot.Commands; - -public class HelpCommand : ICommand { - private readonly IServiceProvider _services; - public HelpCommand(IServiceProvider services) { - _services = services; - } - - public string Name { get; } = "help"; - public string Description { get; } = "Displays this help message"; - - public async Task Invoke(CommandContext ctx) { - var sb = new StringBuilder(); - sb.AppendLine("Available commands:"); - var commands = _services.GetServices<ICommand>().ToList(); - foreach (var command in commands) { - sb.AppendLine($"- {command.Name}: {command.Description}"); - } - - await ctx.Room.SendMessageEventAsync("m.room.message", new() { - Body = sb.ToString(), - }); - } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Bot/Bot/Commands/PingCommand.cs b/MatrixRoomUtils.Bot/Bot/Commands/PingCommand.cs deleted file mode 100644 index 061ca53..0000000 --- a/MatrixRoomUtils.Bot/Bot/Commands/PingCommand.cs +++ /dev/null @@ -1,17 +0,0 @@ -using MatrixRoomUtils.Bot.Bot.Interfaces; - -namespace MatrixRoomUtils.Bot.Bot.Commands; - -public class PingCommand : ICommand { - public PingCommand() { - } - - public string Name { get; } = "ping"; - public string Description { get; } = "Pong!"; - - public async Task Invoke(CommandContext ctx) { - await ctx.Room.SendMessageEventAsync("m.room.message", new() { - Body = "pong!" - }); - } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Bot/Bot/FileStorageProvider.cs b/MatrixRoomUtils.Bot/Bot/FileStorageProvider.cs deleted file mode 100644 index c38591d..0000000 --- a/MatrixRoomUtils.Bot/Bot/FileStorageProvider.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Text.Json; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces.Services; -using Microsoft.Extensions.Logging; - -namespace MatrixRoomUtils.Bot.Bot; - -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), ObjectExtensions.ToJson(value)); - - public async Task<T?> LoadObjectAsync<T>(string key) => JsonSerializer.Deserialize<T>(await File.ReadAllTextAsync(Path.Join(TargetPath, key))); - - public async Task<bool> ObjectExistsAsync(string key) => File.Exists(Path.Join(TargetPath, key)); - - public async Task<List<string>> GetAllKeysAsync() => Directory.GetFiles(TargetPath).Select(Path.GetFileName).ToList(); - - public async Task DeleteObjectAsync(string key) => File.Delete(Path.Join(TargetPath, key)); -} \ No newline at end of file diff --git a/MatrixRoomUtils.Bot/Bot/Interfaces/CommandContext.cs b/MatrixRoomUtils.Bot/Bot/Interfaces/CommandContext.cs deleted file mode 100644 index 94007a5..0000000 --- a/MatrixRoomUtils.Bot/Bot/Interfaces/CommandContext.cs +++ /dev/null @@ -1,12 +0,0 @@ -using MatrixRoomUtils.Core.Responses; -using MatrixRoomUtils.Core.RoomTypes; -using MatrixRoomUtils.Core.StateEventTypes.Spec; - -namespace MatrixRoomUtils.Bot.Bot.Interfaces; - -public class CommandContext { - public GenericRoom Room { get; set; } - public StateEventResponse MessageEvent { get; set; } - public string CommandName => (MessageEvent.TypedContent as RoomMessageEventData).Body.Split(' ')[0][1..]; - public string[] Args => (MessageEvent.TypedContent as RoomMessageEventData).Body.Split(' ')[1..]; -} \ No newline at end of file diff --git a/MatrixRoomUtils.Bot/Bot/Interfaces/ICommand.cs b/MatrixRoomUtils.Bot/Bot/Interfaces/ICommand.cs deleted file mode 100644 index 20805b1..0000000 --- a/MatrixRoomUtils.Bot/Bot/Interfaces/ICommand.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace MatrixRoomUtils.Bot.Bot.Interfaces; - -public interface ICommand { - public string Name { get; } - public string Description { get; } - - public Task<bool> CanInvoke(CommandContext ctx) { - return Task.FromResult(true); - } - - public Task Invoke(CommandContext ctx); -} \ No newline at end of file diff --git a/MatrixRoomUtils.Bot/Bot/MRUBot.cs b/MatrixRoomUtils.Bot/Bot/MRUBot.cs deleted file mode 100644 index bd24ec7..0000000 --- a/MatrixRoomUtils.Bot/Bot/MRUBot.cs +++ /dev/null @@ -1,115 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using MatrixRoomUtils.Bot.Bot.Interfaces; -using MatrixRoomUtils.Core; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Services; -using MatrixRoomUtils.Core.StateEventTypes.Spec; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; - -namespace MatrixRoomUtils.Bot.Bot; - -public class MRUBot : IHostedService { - private readonly HomeserverProviderService _homeserverProviderService; - private readonly ILogger<MRUBot> _logger; - private readonly MRUBotConfiguration _configuration; - private readonly IEnumerable<ICommand> _commands; - - public MRUBot(HomeserverProviderService homeserverProviderService, ILogger<MRUBot> logger, - MRUBotConfiguration configuration, IServiceProvider services) { - logger.LogInformation("MRUBot hosted service instantiated!"); - _homeserverProviderService = homeserverProviderService; - _logger = logger; - _configuration = configuration; - _logger.LogInformation("Getting commands..."); - _commands = services.GetServices<ICommand>(); - _logger.LogInformation($"Got {_commands.Count()} commands!"); - } - - /// <summary>Triggered when the application host is ready to start the service.</summary> - /// <param name="cancellationToken">Indicates that the start process has been aborted.</param> - [SuppressMessage("ReSharper", "FunctionNeverReturns")] - public async Task StartAsync(CancellationToken cancellationToken) { - Directory.GetFiles("bot_data/cache").ToList().ForEach(File.Delete); - AuthenticatedHomeServer hs; - try { - hs = await _homeserverProviderService.GetAuthenticatedWithToken(_configuration.Homeserver, - _configuration.AccessToken); - } - catch (Exception e) { - _logger.LogError(e.Message); - throw; - } - - await (await hs.GetRoom("!DoHEdFablOLjddKWIp:rory.gay")).JoinAsync(); - - // foreach (var room in await hs.GetJoinedRooms()) { - // if(room.RoomId is "!OGEhHVWSdvArJzumhm:matrix.org") continue; - // foreach (var stateEvent in await room.GetStateAsync<List<StateEvent>>("")) { - // var _ = stateEvent.GetType; - // } - // _logger.LogInformation($"Got room state for {room.RoomId}!"); - // } - - hs.SyncHelper.InviteReceivedHandlers.Add(async Task (args) => { - var inviteEvent = - args.Value.InviteState.Events.FirstOrDefault(x => - x.Type == "m.room.member" && x.StateKey == hs.WhoAmI.UserId); - _logger.LogInformation( - $"Got invite to {args.Key} by {inviteEvent.Sender} with reason: {(inviteEvent.TypedContent as RoomMemberEventData).Reason}"); - if (inviteEvent.Sender.EndsWith(":rory.gay") || inviteEvent.Sender == "@mxidupwitch:the-apothecary.club" ) { - try { - var senderProfile = await hs.GetProfile(inviteEvent.Sender); - await (await hs.GetRoom(args.Key)).JoinAsync(reason: $"I was invited by {senderProfile.DisplayName ?? inviteEvent.Sender}!"); - } - catch (Exception e) { - _logger.LogError(e.ToString()); - await (await hs.GetRoom(args.Key)).LeaveAsync(reason: "I was unable to join the room: " + e); - } - } - }); - hs.SyncHelper.TimelineEventHandlers.Add(async @event => { - _logger.LogInformation( - $"Got timeline event in {@event.RoomId}: {@event.ToJson(indent: false, ignoreNull: true)}"); - - var room = await hs.GetRoom(@event.RoomId); - // _logger.LogInformation(eventResponse.ToJson(indent: false)); - if (@event is { Type: "m.room.message", TypedContent: RoomMessageEventData message }) { - if (message is { MessageType: "m.text" } && message.Body.StartsWith(_configuration.Prefix)) { - - var command = _commands.FirstOrDefault(x => x.Name == message.Body.Split(' ')[0][_configuration.Prefix.Length..]); - if (command == null) { - await room.SendMessageEventAsync("m.room.message", - new RoomMessageEventData() { - MessageType = "m.text", - Body = "Command not found!" - }); - return; - } - var ctx = new CommandContext() { - Room = room, - MessageEvent = @event - }; - if (await command.CanInvoke(ctx)) { - await command.Invoke(ctx); - } - else { - await room.SendMessageEventAsync("m.room.message", - new RoomMessageEventData() { - MessageType = "m.text", - Body = "You do not have permission to run this command!" - }); - } - } - } - }); - await hs.SyncHelper.RunSyncLoop(cancellationToken: cancellationToken); - } - - /// <summary>Triggered when the application host is performing a graceful shutdown.</summary> - /// <param name="cancellationToken">Indicates that the shutdown process should no longer be graceful.</param> - public async Task StopAsync(CancellationToken cancellationToken) { - _logger.LogInformation("Shutting down bot!"); - } -} diff --git a/MatrixRoomUtils.Bot/Bot/MRUBotConfiguration.cs b/MatrixRoomUtils.Bot/Bot/MRUBotConfiguration.cs deleted file mode 100644 index 418eebb..0000000 --- a/MatrixRoomUtils.Bot/Bot/MRUBotConfiguration.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Microsoft.Extensions.Configuration; - -namespace MatrixRoomUtils.Bot.Bot; - -public class MRUBotConfiguration { - public MRUBotConfiguration(IConfiguration config) { - config.GetRequiredSection("Bot").Bind(this); - } - public string Homeserver { get; set; } = ""; - public string AccessToken { get; set; } = ""; - public string Prefix { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Bot/MatrixRoomUtils.Bot.csproj b/MatrixRoomUtils.Bot/MatrixRoomUtils.Bot.csproj deleted file mode 100644 index d9b2931..0000000 --- a/MatrixRoomUtils.Bot/MatrixRoomUtils.Bot.csproj +++ /dev/null @@ -1,35 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk"> - - <PropertyGroup> - <OutputType>Exe</OutputType> - <TargetFramework>net8.0</TargetFramework> - <LangVersion>preview</LangVersion> - <ImplicitUsings>enable</ImplicitUsings> - <Nullable>enable</Nullable> - <PublishAot>false</PublishAot> - <InvariantGlobalization>true</InvariantGlobalization> - <PublishTrimmed>true</PublishTrimmed> - <PublishReadyToRun>true</PublishReadyToRun> - <PublishSingleFile>true</PublishSingleFile> - <PublishReadyToRunShowWarnings>true</PublishReadyToRunShowWarnings> - <PublishTrimmedShowLinkerSizeComparison>true</PublishTrimmedShowLinkerSizeComparison> - <PublishTrimmedShowLinkerSizeComparisonWarnings>true</PublishTrimmedShowLinkerSizeComparisonWarnings> - </PropertyGroup> - - <ItemGroup> - <ProjectReference Include="..\MatrixRoomUtils.Core\MatrixRoomUtils.Core.csproj" /> - </ItemGroup> - - <ItemGroup> - <PackageReference Include="ArcaneLibs" Version="1.0.0-preview3020494760.012ed3f" /> - <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0-preview.5.23280.8" /> - </ItemGroup> - <ItemGroup> - <Content Include="appsettings*.json"> - <CopyToOutputDirectory>Always</CopyToOutputDirectory> - </Content> - <Content Update="appsettings.Local.emmalocal.json"> - <CopyToOutputDirectory>Always</CopyToOutputDirectory> - </Content> - </ItemGroup> -</Project> diff --git a/MatrixRoomUtils.Bot/Program.cs b/MatrixRoomUtils.Bot/Program.cs deleted file mode 100644 index 5dae843..0000000 --- a/MatrixRoomUtils.Bot/Program.cs +++ /dev/null @@ -1,29 +0,0 @@ -// See https://aka.ms/new-console-template for more information - -using MatrixRoomUtils.Bot; -using MatrixRoomUtils.Bot.Bot; -using MatrixRoomUtils.Bot.Bot.Interfaces; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Services; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; - -Console.WriteLine("Hello, World!"); - -var host = Host.CreateDefaultBuilder(args).ConfigureServices((_, services) => { - services.AddScoped<TieredStorageService>(x => - new( - cacheStorageProvider: new FileStorageProvider("bot_data/cache/"), - dataStorageProvider: new FileStorageProvider("bot_data/data/") - ) - ); - services.AddScoped<MRUBotConfiguration>(); - services.AddRoryLibMatrixServices(); - foreach (var commandClass in new ClassCollector<ICommand>().ResolveFromAllAccessibleAssemblies()) { - Console.WriteLine($"Adding command {commandClass.Name}"); - services.AddScoped(typeof(ICommand), commandClass); - } - services.AddHostedService<MRUBot>(); -}).UseConsoleLifetime().Build(); - -await host.RunAsync(); \ No newline at end of file diff --git a/MatrixRoomUtils.Bot/Properties/launchSettings.json b/MatrixRoomUtils.Bot/Properties/launchSettings.json deleted file mode 100644 index 997e294..0000000 --- a/MatrixRoomUtils.Bot/Properties/launchSettings.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/launchsettings.json", - "profiles": { - "Default": { - "commandName": "Project", - "dotnetRunMessages": true, - "environmentVariables": { - - } - }, - "Development": { - "commandName": "Project", - "dotnetRunMessages": true, - "environmentVariables": { - "DOTNET_ENVIRONMENT": "Development" - } - }, - "Local config": { - "commandName": "Project", - "dotnetRunMessages": true, - "environmentVariables": { - "DOTNET_ENVIRONMENT": "Local" - } - } - } -} diff --git a/MatrixRoomUtils.Bot/appsettings.Development.json b/MatrixRoomUtils.Bot/appsettings.Development.json deleted file mode 100644 index 27bbd50..0000000 --- a/MatrixRoomUtils.Bot/appsettings.Development.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" - } - } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Bot/appsettings.json b/MatrixRoomUtils.Bot/appsettings.json deleted file mode 100644 index 5668b53..0000000 --- a/MatrixRoomUtils.Bot/appsettings.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" - } - }, - "Bot": { - "Homeserver": "rory.gay", - "AccessToken": "syt_xxxxxxxxxxxxxxxxx" - } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/AuthenticatedHomeServer.cs b/MatrixRoomUtils.Core/AuthenticatedHomeServer.cs deleted file mode 100644 index fbbb99f..0000000 --- a/MatrixRoomUtils.Core/AuthenticatedHomeServer.cs +++ /dev/null @@ -1,175 +0,0 @@ -using System.Net.Http.Headers; -using System.Net.Http.Json; -using System.Text.Json; -using System.Text.Json.Nodes; -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Filters; -using MatrixRoomUtils.Core.Helpers; -using MatrixRoomUtils.Core.Interfaces; -using MatrixRoomUtils.Core.Responses; -using MatrixRoomUtils.Core.Responses.Admin; -using MatrixRoomUtils.Core.RoomTypes; -using MatrixRoomUtils.Core.Services; - -namespace MatrixRoomUtils.Core; - -public class AuthenticatedHomeServer : IHomeServer { - private readonly TieredStorageService _storage; - public readonly HomeserverAdminApi Admin; - public readonly SyncHelper SyncHelper; - - public AuthenticatedHomeServer(TieredStorageService storage, string canonicalHomeServerDomain, string accessToken) { - _storage = storage; - AccessToken = accessToken.Trim(); - HomeServerDomain = canonicalHomeServerDomain.Trim(); - Admin = new HomeserverAdminApi(this); - SyncHelper = new SyncHelper(this, storage); - _httpClient = new MatrixHttpClient(); - } - - public WhoAmIResponse WhoAmI { get; set; } = null!; - public string UserId => WhoAmI.UserId; - public string AccessToken { get; set; } - - - public async Task<GenericRoom> GetRoom(string roomId) => new(this, roomId); - - public async Task<List<GenericRoom>> GetJoinedRooms() { - var rooms = new List<GenericRoom>(); - var roomQuery = await _httpClient.GetAsync("/_matrix/client/v3/joined_rooms"); - - var roomsJson = await roomQuery.Content.ReadFromJsonAsync<JsonElement>(); - foreach (var room in roomsJson.GetProperty("joined_rooms").EnumerateArray()) rooms.Add(new GenericRoom(this, room.GetString())); - - Console.WriteLine($"Fetched {rooms.Count} rooms"); - - return rooms; - } - - public async Task<string> UploadFile(string fileName, Stream fileStream, string contentType = "application/octet-stream") { - var res = await _httpClient.PostAsync($"/_matrix/media/v3/upload?filename={fileName}", new StreamContent(fileStream)); - if (!res.IsSuccessStatusCode) { - Console.WriteLine($"Failed to upload file: {await res.Content.ReadAsStringAsync()}"); - throw new InvalidDataException($"Failed to upload file: {await res.Content.ReadAsStringAsync()}"); - } - - var resJson = await res.Content.ReadFromJsonAsync<JsonElement>(); - return resJson.GetProperty("content_uri").GetString()!; - } - - public async Task<GenericRoom> CreateRoom(CreateRoomRequest creationEvent) { - var res = await _httpClient.PostAsJsonAsync("/_matrix/client/v3/createRoom", creationEvent); - if (!res.IsSuccessStatusCode) { - Console.WriteLine($"Failed to create room: {await res.Content.ReadAsStringAsync()}"); - throw new InvalidDataException($"Failed to create room: {await res.Content.ReadAsStringAsync()}"); - } - - return await GetRoom((await res.Content.ReadFromJsonAsync<JsonObject>())!["room_id"]!.ToString()); - } - - public class HomeserverAdminApi { - private readonly AuthenticatedHomeServer _authenticatedHomeServer; - - public HomeserverAdminApi(AuthenticatedHomeServer authenticatedHomeServer) => _authenticatedHomeServer = authenticatedHomeServer; - - public async IAsyncEnumerable<AdminRoomListingResult.AdminRoomListingResultRoom> SearchRoomsAsync(int limit = int.MaxValue, string orderBy = "name", string dir = "f", string? searchTerm = null, LocalRoomQueryFilter? localFilter = null) { - AdminRoomListingResult? res = null; - var i = 0; - int? totalRooms = null; - do { - var url = $"/_synapse/admin/v1/rooms?limit={Math.Min(limit, 100)}&dir={dir}&order_by={orderBy}"; - if (!string.IsNullOrEmpty(searchTerm)) url += $"&search_term={searchTerm}"; - - if (res?.NextBatch is not null) url += $"&from={res.NextBatch}"; - - Console.WriteLine($"--- ADMIN Querying Room List with URL: {url} - Already have {i} items... ---"); - - res = await _authenticatedHomeServer._httpClient.GetFromJsonAsync<AdminRoomListingResult>(url); - totalRooms ??= res?.TotalRooms; - Console.WriteLine(res.ToJson(false)); - foreach (var room in res.Rooms) { - if (localFilter is not null) { - if (!room.RoomId.Contains(localFilter.RoomIdContains)) { - totalRooms--; - continue; - } - if (!room.Name?.Contains(localFilter.NameContains) == true) { - totalRooms--; - continue; - } - if (!room.CanonicalAlias?.Contains(localFilter.CanonicalAliasContains) == true) { - totalRooms--; - continue; - } - if (!room.Version.Contains(localFilter.VersionContains)) { - totalRooms--; - continue; - } - if (!room.Creator.Contains(localFilter.CreatorContains)) { - totalRooms--; - continue; - } - if (!room.Encryption?.Contains(localFilter.EncryptionContains) == true) { - totalRooms--; - continue; - } - if (!room.JoinRules?.Contains(localFilter.JoinRulesContains) == true) { - totalRooms--; - continue; - } - if(!room.GuestAccess?.Contains(localFilter.GuestAccessContains) == true) { - totalRooms--; - continue; - } - if(!room.HistoryVisibility?.Contains(localFilter.HistoryVisibilityContains) == true) { - totalRooms--; - continue; - } - - if(localFilter.CheckFederation && room.Federatable != localFilter.Federatable) { - totalRooms--; - continue; - } - if(localFilter.CheckPublic && room.Public != localFilter.Public) { - totalRooms--; - continue; - } - - if(room.JoinedMembers < localFilter.JoinedMembersGreaterThan || room.JoinedMembers > localFilter.JoinedMembersLessThan) { - totalRooms--; - continue; - } - if(room.JoinedLocalMembers < localFilter.JoinedLocalMembersGreaterThan || room.JoinedLocalMembers > localFilter.JoinedLocalMembersLessThan) { - totalRooms--; - continue; - } - } - // if (contentSearch is not null && !string.IsNullOrEmpty(contentSearch) && - // !( - // room.Name?.Contains(contentSearch, StringComparison.InvariantCultureIgnoreCase) == true || - // room.CanonicalAlias?.Contains(contentSearch, StringComparison.InvariantCultureIgnoreCase) == true || - // room.Creator?.Contains(contentSearch, StringComparison.InvariantCultureIgnoreCase) == true - // ) - // ) { - // totalRooms--; - // continue; - // } - - i++; - yield return room; - } - } while (i < Math.Min(limit, totalRooms ?? limit)); - } - } -} - -public class WhoAmIResponse { - [JsonPropertyName("user_id")] - public string UserId { get; set; } = null!; - - [JsonPropertyName("device_id")] - public string? DeviceId { get; set; } - [JsonPropertyName("is_guest")] - public bool? IsGuest { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/EventIdResponse.cs b/MatrixRoomUtils.Core/EventIdResponse.cs deleted file mode 100644 index 77dc7f8..0000000 --- a/MatrixRoomUtils.Core/EventIdResponse.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Text.Json.Serialization; - -namespace MatrixRoomUtils.Core; - -public class EventIdResponse { - [JsonPropertyName("event_id")] - public string EventId { get; set; } = null!; -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Extensions/ClassCollector.cs b/MatrixRoomUtils.Core/Extensions/ClassCollector.cs deleted file mode 100644 index d4ba838..0000000 --- a/MatrixRoomUtils.Core/Extensions/ClassCollector.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Reflection; - -namespace MatrixRoomUtils.Core.Extensions; - -public class ClassCollector<T> where T : class { - static ClassCollector() { - if (!typeof(T).IsInterface) - throw new ArgumentException( - $"ClassCollector<T> must be used with an interface type. Passed type: {typeof(T).Name}"); - } - - public List<Type> ResolveFromAllAccessibleAssemblies() => AppDomain.CurrentDomain.GetAssemblies().SelectMany(ResolveFromAssembly).ToList(); - - public List<Type> ResolveFromObjectReference(object obj) => ResolveFromTypeReference(obj.GetType()); - - public List<Type> ResolveFromTypeReference(Type t) => Assembly.GetAssembly(t)?.GetReferencedAssemblies().SelectMany(ResolveFromAssemblyName).ToList() ?? new List<Type>(); - - public List<Type> ResolveFromAssemblyName(AssemblyName assemblyName) => ResolveFromAssembly(Assembly.Load(assemblyName)); - - public List<Type> ResolveFromAssembly(Assembly assembly) => assembly.GetTypes() - .Where(x => x is { IsClass: true, IsAbstract: false } && x.GetInterfaces().Contains(typeof(T))).ToList(); -} diff --git a/MatrixRoomUtils.Core/Extensions/DictionaryExtensions.cs b/MatrixRoomUtils.Core/Extensions/DictionaryExtensions.cs deleted file mode 100644 index 78bbdfa..0000000 --- a/MatrixRoomUtils.Core/Extensions/DictionaryExtensions.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace MatrixRoomUtils.Core.Extensions; - -public static class DictionaryExtensions { - public static bool ChangeKey<TKey, TValue>(this IDictionary<TKey, TValue> dict, - TKey oldKey, TKey newKey) { - TValue value; - if (!dict.Remove(oldKey, out value)) - return false; - - dict[newKey] = value; // or dict.Add(newKey, value) depending on ur comfort - return true; - } - - public static Y GetOrCreate<X, Y>(this IDictionary<X, Y> dict, X key) where Y : new() { - if (dict.TryGetValue(key, out var value)) { - return value; - } - - value = new Y(); - dict.Add(key, value); - return value; - } - - public static Y GetOrCreate<X, Y>(this IDictionary<X, Y> dict, X key, Func<X, Y> valueFactory) { - if (dict.TryGetValue(key, out var value)) { - return value; - } - - value = valueFactory(key); - dict.Add(key, value); - return value; - } -} diff --git a/MatrixRoomUtils.Core/Extensions/HttpClientExtensions.cs b/MatrixRoomUtils.Core/Extensions/HttpClientExtensions.cs deleted file mode 100644 index 009338a..0000000 --- a/MatrixRoomUtils.Core/Extensions/HttpClientExtensions.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System.Net.Http.Headers; -using System.Reflection; -using System.Text.Json; - -namespace MatrixRoomUtils.Core.Extensions; - -public static class HttpClientExtensions { - public static async Task<bool> CheckSuccessStatus(this HttpClient hc, string url) { - //cors causes failure, try to catch - try { - var resp = await hc.GetAsync(url); - return resp.IsSuccessStatusCode; - } - catch (Exception e) { - Console.WriteLine($"Failed to check success status: {e.Message}"); - return false; - } - } -} - -public class MatrixHttpClient : HttpClient { - public override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, - CancellationToken cancellationToken) { - Console.WriteLine($"Sending request to {request.RequestUri}"); - try { - HttpRequestOptionsKey<bool> WebAssemblyEnableStreamingResponseKey = - new HttpRequestOptionsKey<bool>("WebAssemblyEnableStreamingResponse"); - request.Options.Set(WebAssemblyEnableStreamingResponseKey, true); - } - catch (Exception e) { - Console.WriteLine("Failed to set browser response streaming:"); - Console.WriteLine(e); - } - - var a = await base.SendAsync(request, cancellationToken); - if (!a.IsSuccessStatusCode) { - var content = await a.Content.ReadAsStringAsync(cancellationToken); - if (content.StartsWith('{')) { - var ex = JsonSerializer.Deserialize<MatrixException>(content); - ex.RawContent = content; - // Console.WriteLine($"Failed to send request: {ex}"); - if (ex?.RetryAfterMs is not null) { - await Task.Delay(ex.RetryAfterMs.Value, cancellationToken); - typeof(HttpRequestMessage).GetField("_sendStatus", BindingFlags.NonPublic | BindingFlags.Instance) - ?.SetValue(request, 0); - return await SendAsync(request, cancellationToken); - } - - throw ex!; - } - - throw new InvalidDataException("Encountered invalid data:\n" + content); - } - - return a; - } - - // GetFromJsonAsync - public async Task<T> GetFromJsonAsync<T>(string requestUri, CancellationToken cancellationToken = default) { - var request = new HttpRequestMessage(HttpMethod.Get, requestUri); - request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - var response = await SendAsync(request, cancellationToken); - response.EnsureSuccessStatusCode(); - await using var responseStream = await response.Content.ReadAsStreamAsync(cancellationToken); - return await JsonSerializer.DeserializeAsync<T>(responseStream, cancellationToken: cancellationToken); - } - - // GetStreamAsync - public async Task<Stream> GetStreamAsync(string requestUri, CancellationToken cancellationToken = default) { - var request = new HttpRequestMessage(HttpMethod.Get, requestUri); - request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - var response = await SendAsync(request, cancellationToken); - response.EnsureSuccessStatusCode(); - return await response.Content.ReadAsStreamAsync(cancellationToken); - } -} diff --git a/MatrixRoomUtils.Core/Extensions/IEnumerableExtensions.cs b/MatrixRoomUtils.Core/Extensions/IEnumerableExtensions.cs deleted file mode 100644 index 8994529..0000000 --- a/MatrixRoomUtils.Core/Extensions/IEnumerableExtensions.cs +++ /dev/null @@ -1,9 +0,0 @@ -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.Extensions; - -[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] -public class MatrixEventAttribute : Attribute { - public string EventName { get; set; } - public bool Legacy { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Extensions/JsonElementExtensions.cs b/MatrixRoomUtils.Core/Extensions/JsonElementExtensions.cs deleted file mode 100644 index 7701c9e..0000000 --- a/MatrixRoomUtils.Core/Extensions/JsonElementExtensions.cs +++ /dev/null @@ -1,151 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Reflection; -using System.Text.Json; -using System.Text.Json.Nodes; -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Responses; - -namespace MatrixRoomUtils.Core.Extensions; - -public static class JsonElementExtensions { - public static bool FindExtraJsonElementFields(this JsonElement obj, Type objectType, string objectPropertyName) { - if (objectPropertyName == "content" && objectType == typeof(JsonObject)) - objectType = typeof(StateEventResponse); - // if (t == typeof(JsonNode)) - // return false; - - Console.WriteLine($"{objectType.Name} {objectPropertyName}"); - bool unknownPropertyFound = false; - var mappedPropsDict = objectType.GetProperties() - .Where(x => x.GetCustomAttribute<JsonPropertyNameAttribute>() is not null) - .ToDictionary(x => x.GetCustomAttribute<JsonPropertyNameAttribute>()!.Name, x => x); - objectType.GetProperties().Where(x => !mappedPropsDict.ContainsKey(x.Name)) - .ToList().ForEach(x => mappedPropsDict.TryAdd(x.Name, x)); - - foreach (var field in obj.EnumerateObject()) { - if (mappedPropsDict.TryGetValue(field.Name, out var mappedProperty)) { - //dictionary - if (mappedProperty.PropertyType.IsGenericType && - mappedProperty.PropertyType.GetGenericTypeDefinition() == typeof(Dictionary<,>)) { - unknownPropertyFound |= _checkDictionary(field, objectType, mappedProperty.PropertyType); - continue; - } - - if (mappedProperty.PropertyType.IsGenericType && - mappedProperty.PropertyType.GetGenericTypeDefinition() == typeof(List<>)) { - unknownPropertyFound |= _checkList(field, objectType, mappedProperty.PropertyType); - continue; - } - - if (field.Name == "content" && (objectType == typeof(StateEventResponse) || objectType == typeof(StateEvent))) { - unknownPropertyFound |= field.FindExtraJsonPropertyFieldsByValueKind( - StateEvent.GetStateEventType(obj.GetProperty("type").GetString()), - mappedProperty.PropertyType); - continue; - } - - unknownPropertyFound |= - field.FindExtraJsonPropertyFieldsByValueKind(objectType, mappedProperty.PropertyType); - continue; - } - - Console.WriteLine($"[!!] Unknown property {field.Name} in {objectType.Name}!"); - unknownPropertyFound = true; - } - - return unknownPropertyFound; - } - - private static bool FindExtraJsonPropertyFieldsByValueKind(this JsonProperty field, Type containerType, - Type propertyType) { - if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) { - propertyType = propertyType.GetGenericArguments()[0]; - } - - bool switchResult = false; - switch (field.Value.ValueKind) { - case JsonValueKind.Array: - switchResult = field.Value.EnumerateArray().Aggregate(switchResult, - (current, element) => current | element.FindExtraJsonElementFields(propertyType, field.Name)); - break; - case JsonValueKind.Object: - switchResult |= field.Value.FindExtraJsonElementFields(propertyType, field.Name); - break; - case JsonValueKind.True: - case JsonValueKind.False: - return _checkBool(field, containerType, propertyType); - case JsonValueKind.String: - return _checkString(field, containerType, propertyType); - case JsonValueKind.Number: - return _checkNumber(field, containerType, propertyType); - case JsonValueKind.Undefined: - case JsonValueKind.Null: - break; - default: - throw new ArgumentOutOfRangeException(); - } - - return switchResult; - } - - private static bool _checkBool(this JsonProperty field, Type containerType, Type propertyType) { - if (propertyType == typeof(bool)) return true; - Console.WriteLine( - $"[!!] Encountered bool for {field.Name} in {containerType.Name}, the class defines {propertyType.Name}!"); - return false; - } - - private static bool _checkString(this JsonProperty field, Type containerType, Type propertyType) { - if (propertyType == typeof(string)) return true; - // ReSharper disable once BuiltInTypeReferenceStyle - if (propertyType == typeof(String)) return true; - Console.WriteLine( - $"[!!] Encountered string for {field.Name} in {containerType.Name}, the class defines {propertyType.Name}!"); - return false; - } - - private static bool _checkNumber(this JsonProperty field, Type containerType, Type propertyType) { - if (propertyType == typeof(int) || - propertyType == typeof(double) || - propertyType == typeof(float) || - propertyType == typeof(decimal) || - propertyType == typeof(long) || - propertyType == typeof(short) || - propertyType == typeof(uint) || - propertyType == typeof(ulong) || - propertyType == typeof(ushort) || - propertyType == typeof(byte) || - propertyType == typeof(sbyte)) - return true; - Console.WriteLine( - $"[!!] Encountered number for {field.Name} in {containerType.Name}, the class defines {propertyType.Name}!"); - return false; - } - - private static bool _checkDictionary(this JsonProperty field, Type containerType, Type propertyType) { - var keyType = propertyType.GetGenericArguments()[0]; - var valueType = propertyType.GetGenericArguments()[1]; - valueType = Nullable.GetUnderlyingType(valueType) ?? valueType; - Console.WriteLine( - $"Encountered dictionary {field.Name} with key type {keyType.Name} and value type {valueType.Name}!"); - - return field.Value.EnumerateObject() - .Where(key => !valueType.IsPrimitive && valueType != typeof(string)) - .Aggregate(false, (current, key) => - current | key.FindExtraJsonPropertyFieldsByValueKind(containerType, valueType) - ); - } - - private static bool _checkList(this JsonProperty field, Type containerType, Type propertyType) { - var valueType = propertyType.GetGenericArguments()[0]; - valueType = Nullable.GetUnderlyingType(valueType) ?? valueType; - Console.WriteLine( - $"Encountered list {field.Name} with value type {valueType.Name}!"); - - return field.Value.EnumerateArray() - .Where(key => !valueType.IsPrimitive && valueType != typeof(string)) - .Aggregate(false, (current, key) => - current | key.FindExtraJsonElementFields(valueType, field.Name) - ); - } -} diff --git a/MatrixRoomUtils.Core/Extensions/ObjectExtensions.cs b/MatrixRoomUtils.Core/Extensions/ObjectExtensions.cs deleted file mode 100644 index a4b0791..0000000 --- a/MatrixRoomUtils.Core/Extensions/ObjectExtensions.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Text.Encodings.Web; -using System.Text.Json; -using MatrixRoomUtils.Core.Interfaces; -using MatrixRoomUtils.Core.Responses; - -namespace MatrixRoomUtils.Core.Extensions; - -public static class ObjectExtensions { - public static string ToJson(this object obj, bool indent = true, bool ignoreNull = false, bool unsafeContent = false) { - var jso = new JsonSerializerOptions(); - if (indent) jso.WriteIndented = true; - if (ignoreNull) jso.IgnoreNullValues = true; - if (unsafeContent) jso.Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping; - return JsonSerializer.Serialize(obj, jso); - } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Extensions/StringExtensions.cs b/MatrixRoomUtils.Core/Extensions/StringExtensions.cs deleted file mode 100644 index b81d59f..0000000 --- a/MatrixRoomUtils.Core/Extensions/StringExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace MatrixRoomUtils.Core.Extensions; - -public static class StringExtensions { - // public static async Task<string> GetMediaUrl(this string MxcUrl) - // { - // //MxcUrl: mxc://rory.gay/ocRVanZoUTCcifcVNwXgbtTg - // //target: https://matrix.rory.gay/_matrix/media/v3/download/rory.gay/ocRVanZoUTCcifcVNwXgbtTg - // - // var server = MxcUrl.Split('/')[2]; - // var mediaId = MxcUrl.Split('/')[3]; - // return $"{(await new RemoteHomeServer(server).Configure()).FullHomeServerDomain}/_matrix/media/v3/download/{server}/{mediaId}"; - // } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Filters/LocalRoomQueryFilter.cs b/MatrixRoomUtils.Core/Filters/LocalRoomQueryFilter.cs deleted file mode 100644 index 65c7baa..0000000 --- a/MatrixRoomUtils.Core/Filters/LocalRoomQueryFilter.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace MatrixRoomUtils.Core.Filters; - -public class LocalRoomQueryFilter { - public string RoomIdContains { get; set; } = ""; - public string NameContains { get; set; } = ""; - public string CanonicalAliasContains { get; set; } = ""; - public string VersionContains { get; set; } = ""; - public string CreatorContains { get; set; } = ""; - public string EncryptionContains { get; set; } = ""; - public string JoinRulesContains { get; set; } = ""; - public string GuestAccessContains { get; set; } = ""; - public string HistoryVisibilityContains { get; set; } = ""; - - public bool Federatable { get; set; } = true; - public bool Public { get; set; } = true; - - public int JoinedMembersGreaterThan { get; set; } = 0; - public int JoinedMembersLessThan { get; set; } = int.MaxValue; - - public int JoinedLocalMembersGreaterThan { get; set; } = 0; - public int JoinedLocalMembersLessThan { get; set; } = int.MaxValue; - public int StateEventsGreaterThan { get; set; } = 0; - public int StateEventsLessThan { get; set; } = int.MaxValue; - - - public bool CheckFederation { get; set; } - public bool CheckPublic { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Filters/SyncFilter.cs b/MatrixRoomUtils.Core/Filters/SyncFilter.cs deleted file mode 100644 index bc81101..0000000 --- a/MatrixRoomUtils.Core/Filters/SyncFilter.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System.Text.Json.Serialization; - -namespace MatrixRoomUtils.Core.Filters; - -public class SyncFilter { - [JsonPropertyName("account_data")] - public EventFilter? AccountData { get; set; } - - [JsonPropertyName("presence")] - public EventFilter? Presence { get; set; } - - [JsonPropertyName("room")] - public RoomFilter? Room { get; set; } - - public class RoomFilter { - [JsonPropertyName("account_data")] - public StateFilter? AccountData { get; set; } - - [JsonPropertyName("ephemeral")] - public StateFilter? Ephemeral { get; set; } - - [JsonPropertyName("state")] - public StateFilter? State { get; set; } - - [JsonPropertyName("timeline")] - public StateFilter? Timeline { get; set; } - - - public class StateFilter : EventFilter { - [JsonPropertyName("contains_url")] - public bool? ContainsUrl { get; set; } - - [JsonPropertyName("include_redundant_members")] - public bool? IncludeRedundantMembers { get; set; } - - [JsonPropertyName("lazy_load_members")] - public bool? LazyLoadMembers { get; set; } - - [JsonPropertyName("rooms")] - public List<string>? Rooms { get; set; } - - [JsonPropertyName("not_rooms")] - public List<string>? NotRooms { get; set; } - - [JsonPropertyName("unread_thread_notifications")] - public bool? UnreadThreadNotifications { get; set; } - } - } - - public class EventFilter { - [JsonPropertyName("limit")] - public int? Limit { get; set; } - - [JsonPropertyName("types")] - public List<string>? Types { get; set; } - - [JsonPropertyName("not_types")] - public List<string>? NotTypes { get; set; } - - [JsonPropertyName("senders")] - public List<string>? Senders { get; set; } - - [JsonPropertyName("not_senders")] - public List<string>? NotSenders { get; set; } - } -} diff --git a/MatrixRoomUtils.Core/Helpers/MediaResolver.cs b/MatrixRoomUtils.Core/Helpers/MediaResolver.cs deleted file mode 100644 index 0869135..0000000 --- a/MatrixRoomUtils.Core/Helpers/MediaResolver.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace MatrixRoomUtils.Core.Helpers; - -public class MediaResolver { - public static string ResolveMediaUri(string homeserver, string mxc) => - mxc.Replace("mxc://", $"{homeserver}/_matrix/media/v3/download/"); -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Helpers/SyncHelper.cs b/MatrixRoomUtils.Core/Helpers/SyncHelper.cs deleted file mode 100644 index e12164c..0000000 --- a/MatrixRoomUtils.Core/Helpers/SyncHelper.cs +++ /dev/null @@ -1,238 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Net.Http.Json; -using System.Text.Json; -using System.Text.Json.Nodes; -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Filters; -using MatrixRoomUtils.Core.Interfaces; -using MatrixRoomUtils.Core.Responses; -using MatrixRoomUtils.Core.Responses.Admin; -using MatrixRoomUtils.Core.Services; -using MatrixRoomUtils.Core.StateEventTypes; - -namespace MatrixRoomUtils.Core.Helpers; - -public class SyncHelper { - private readonly AuthenticatedHomeServer _homeServer; - private readonly TieredStorageService _storageService; - - public SyncHelper(AuthenticatedHomeServer homeServer, TieredStorageService storageService) { - _homeServer = homeServer; - _storageService = storageService; - } - - public async Task<SyncResult?> Sync( - string? since = null, - int? timeout = 30000, - string? setPresence = "online", - SyncFilter? filter = null, - CancellationToken? cancellationToken = null) { - var outFileName = "sync-" + - (await _storageService.CacheStorageProvider.GetAllKeysAsync()).Count( - x => x.StartsWith("sync")) + - ".json"; - var url = $"/_matrix/client/v3/sync?timeout={timeout}&set_presence={setPresence}"; - if (!string.IsNullOrWhiteSpace(since)) url += $"&since={since}"; - if (filter is not null) url += $"&filter={filter.ToJson(ignoreNull: true, indent: false)}"; - // else url += "&full_state=true"; - Console.WriteLine("Calling: " + url); - try { - var req = await _homeServer._httpClient.GetAsync(url, cancellationToken: cancellationToken ?? CancellationToken.None); - - // var res = await JsonSerializer.DeserializeAsync<SyncResult>(await req.Content.ReadAsStreamAsync()); - -#if DEBUG && false - var jsonObj = await req.Content.ReadFromJsonAsync<JsonElement>(); - try { - await _homeServer._httpClient.PostAsJsonAsync( - "http://localhost:5116/validate/" + typeof(SyncResult).AssemblyQualifiedName, jsonObj); - } - catch (Exception e) { - Console.WriteLine("[!!] Checking sync response failed: " + e); - } - - var res = jsonObj.Deserialize<SyncResult>(); - return res; -#else - return await req.Content.ReadFromJsonAsync<SyncResult>(); -#endif - } - catch (TaskCanceledException) { - Console.WriteLine("Sync cancelled!"); - } - catch (Exception e) { - Console.WriteLine(e); - } - - return null; - } - - [SuppressMessage("ReSharper", "FunctionNeverReturns")] - public async Task RunSyncLoop( - bool skipInitialSyncEvents = true, - string? since = null, - int? timeout = 30000, - string? setPresence = "online", - SyncFilter? filter = null, - CancellationToken? cancellationToken = null - ) { - await Task.WhenAll((await _storageService.CacheStorageProvider.GetAllKeysAsync()) - .Where(x => x.StartsWith("sync")) - .ToList() - .Select(x => _storageService.CacheStorageProvider.DeleteObjectAsync(x))); - SyncResult? sync = null; - string? nextBatch = since; - while (cancellationToken is null || !cancellationToken.Value.IsCancellationRequested) { - sync = await Sync(since: nextBatch, timeout: timeout, setPresence: setPresence, filter: filter, - cancellationToken: cancellationToken); - nextBatch = sync?.NextBatch ?? nextBatch; - if (sync is null) continue; - Console.WriteLine($"Got sync, next batch: {nextBatch}!"); - - if (sync.Rooms is { Invite.Count: > 0 }) { - foreach (var roomInvite in sync.Rooms.Invite) { - var tasks = InviteReceivedHandlers.Select(x => x(roomInvite)).ToList(); - await Task.WhenAll(tasks); - } - } - - if (sync.AccountData is { Events: { Count: > 0 } }) { - foreach (var accountDataEvent in sync.AccountData.Events) { - var tasks = AccountDataReceivedHandlers.Select(x => x(accountDataEvent)).ToList(); - await Task.WhenAll(tasks); - } - } - - // Things that are skipped on the first sync - if (skipInitialSyncEvents) { - skipInitialSyncEvents = false; - continue; - } - - if (sync.Rooms is { Join.Count: > 0 }) { - foreach (var updatedRoom in sync.Rooms.Join) { - foreach (var stateEventResponse in updatedRoom.Value.Timeline.Events) { - stateEventResponse.RoomId = updatedRoom.Key; - var tasks = TimelineEventHandlers.Select(x => x(stateEventResponse)).ToList(); - await Task.WhenAll(tasks); - } - } - } - } - } - - /// <summary> - /// Event fired when a room invite is received - /// </summary> - public List<Func<KeyValuePair<string, SyncResult.RoomsDataStructure.InvitedRoomDataStructure>, Task>> - InviteReceivedHandlers { get; } = new(); - - public List<Func<StateEventResponse, Task>> TimelineEventHandlers { get; } = new(); - public List<Func<StateEventResponse, Task>> AccountDataReceivedHandlers { get; } = new(); -} - -public class SyncResult { - [JsonPropertyName("next_batch")] - public string NextBatch { get; set; } - - [JsonPropertyName("account_data")] - public EventList? AccountData { get; set; } - - [JsonPropertyName("presence")] - public PresenceDataStructure? Presence { get; set; } - - [JsonPropertyName("device_one_time_keys_count")] - public Dictionary<string, int> DeviceOneTimeKeysCount { get; set; } - - [JsonPropertyName("rooms")] - public RoomsDataStructure? Rooms { get; set; } - - [JsonPropertyName("to_device")] - public EventList? ToDevice { get; set; } - - [JsonPropertyName("device_lists")] - public DeviceListsDataStructure? DeviceLists { get; set; } - - public class DeviceListsDataStructure { - [JsonPropertyName("changed")] - public List<string>? Changed { get; set; } - - [JsonPropertyName("left")] - public List<string>? Left { get; set; } - } - - // supporting classes - public class PresenceDataStructure { - [JsonPropertyName("events")] - public List<StateEventResponse> Events { get; set; } - } - - public class RoomsDataStructure { - [JsonPropertyName("join")] - public Dictionary<string, JoinedRoomDataStructure>? Join { get; set; } - - [JsonPropertyName("invite")] - public Dictionary<string, InvitedRoomDataStructure>? Invite { get; set; } - - public class JoinedRoomDataStructure { - [JsonPropertyName("timeline")] - public TimelineDataStructure Timeline { get; set; } - - [JsonPropertyName("state")] - public EventList State { get; set; } - - [JsonPropertyName("account_data")] - public EventList AccountData { get; set; } - - [JsonPropertyName("ephemeral")] - public EventList Ephemeral { get; set; } - - [JsonPropertyName("unread_notifications")] - public UnreadNotificationsDataStructure UnreadNotifications { get; set; } - - [JsonPropertyName("summary")] - public SummaryDataStructure Summary { get; set; } - - public class TimelineDataStructure { - [JsonPropertyName("events")] - public List<StateEventResponse> Events { get; set; } - - [JsonPropertyName("prev_batch")] - public string PrevBatch { get; set; } - - [JsonPropertyName("limited")] - public bool Limited { get; set; } - } - - public class UnreadNotificationsDataStructure { - [JsonPropertyName("notification_count")] - public int NotificationCount { get; set; } - - [JsonPropertyName("highlight_count")] - public int HighlightCount { get; set; } - } - - public class SummaryDataStructure { - [JsonPropertyName("m.heroes")] - public List<string> Heroes { get; set; } - - [JsonPropertyName("m.invited_member_count")] - public int InvitedMemberCount { get; set; } - - [JsonPropertyName("m.joined_member_count")] - public int JoinedMemberCount { get; set; } - } - } - - public class InvitedRoomDataStructure { - [JsonPropertyName("invite_state")] - public EventList InviteState { get; set; } - } - } -} - -public class EventList { - [JsonPropertyName("events")] - public List<StateEventResponse> Events { get; set; } -} diff --git a/MatrixRoomUtils.Core/Interfaces/IHomeServer.cs b/MatrixRoomUtils.Core/Interfaces/IHomeServer.cs deleted file mode 100644 index 3521a51..0000000 --- a/MatrixRoomUtils.Core/Interfaces/IHomeServer.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Net.Http.Json; -using System.Text.Json; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.StateEventTypes; -using MatrixRoomUtils.Core.StateEventTypes.Spec; - -namespace MatrixRoomUtils.Core.Interfaces; - -public class IHomeServer { - private readonly Dictionary<string, object> _profileCache = new(); - public string HomeServerDomain { get; set; } - public string FullHomeServerDomain { get; set; } - - public MatrixHttpClient _httpClient { get; set; } = new(); - - public async Task<ProfileResponseEventData> GetProfile(string mxid) { - if(mxid is null) throw new ArgumentNullException(nameof(mxid)); - if (_profileCache.ContainsKey(mxid)) { - if (_profileCache[mxid] is SemaphoreSlim s) await s.WaitAsync(); - if (_profileCache[mxid] is ProfileResponseEventData p) return p; - } - _profileCache[mxid] = new SemaphoreSlim(1); - - var resp = await _httpClient.GetAsync($"/_matrix/client/v3/profile/{mxid}"); - var data = await resp.Content.ReadFromJsonAsync<ProfileResponseEventData>(); - if (!resp.IsSuccessStatusCode) Console.WriteLine("Profile: " + data); - _profileCache[mxid] = data; - - return data; - } -} diff --git a/MatrixRoomUtils.Core/Interfaces/IStateEventType.cs b/MatrixRoomUtils.Core/Interfaces/IStateEventType.cs deleted file mode 100644 index 053f50c..0000000 --- a/MatrixRoomUtils.Core/Interfaces/IStateEventType.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace MatrixRoomUtils.Core.Interfaces; - -public interface IStateEventType { - -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Interfaces/Services/IStorageProvider.cs b/MatrixRoomUtils.Core/Interfaces/Services/IStorageProvider.cs deleted file mode 100644 index 1de9885..0000000 --- a/MatrixRoomUtils.Core/Interfaces/Services/IStorageProvider.cs +++ /dev/null @@ -1,58 +0,0 @@ -namespace MatrixRoomUtils.Core.Interfaces.Services; - -public interface IStorageProvider { - // save all children of a type with reflection - public Task SaveAllChildrenAsync<T>(string key, T value) { - Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement SaveAllChildren<T>(key, value)!"); - throw new NotImplementedException(); - } - - // load all children of a type with reflection - public Task<T?> LoadAllChildrenAsync<T>(string key) { - Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement LoadAllChildren<T>(key)!"); - throw new NotImplementedException(); - } - - - public Task SaveObjectAsync<T>(string key, T value) { - Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement SaveObject<T>(key, value)!"); - throw new NotImplementedException(); - } - - // load - public Task<T?> LoadObjectAsync<T>(string key) { - Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement LoadObject<T>(key)!"); - throw new NotImplementedException(); - } - - // check if exists - public Task<bool> ObjectExistsAsync(string key) { - Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement ObjectExists(key)!"); - throw new NotImplementedException(); - } - - // get all keys - public Task<List<string>> GetAllKeysAsync() { - Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement GetAllKeys()!"); - throw new NotImplementedException(); - } - - - // delete - public Task DeleteObjectAsync(string key) { - Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement DeleteObject(key)!"); - throw new NotImplementedException(); - } - - // save stream - public Task SaveStreamAsync(string key, Stream stream) { - Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement SaveStream(key, stream)!"); - throw new NotImplementedException(); - } - - // load stream - public Task<Stream?> LoadStreamAsync(string key) { - Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement LoadStream(key)!"); - throw new NotImplementedException(); - } -} diff --git a/MatrixRoomUtils.Core/MatrixException.cs b/MatrixRoomUtils.Core/MatrixException.cs deleted file mode 100644 index a469a62..0000000 --- a/MatrixRoomUtils.Core/MatrixException.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; - -namespace MatrixRoomUtils.Core; - -public class MatrixException : Exception { - [JsonPropertyName("errcode")] - public string ErrorCode { get; set; } - - [JsonPropertyName("error")] - public string Error { get; set; } - - [JsonPropertyName("soft_logout")] - public bool? SoftLogout { get; set; } - - [JsonPropertyName("retry_after_ms")] - public int? RetryAfterMs { get; set; } - - public string RawContent { get; set; } - - public override string Message => - $"{ErrorCode}: {ErrorCode switch { - // common - "M_FORBIDDEN" => $"You do not have permission to perform this action: {Error}", - "M_UNKNOWN_TOKEN" => $"The access token specified was not recognised: {Error}{(SoftLogout == true ? " (soft logout)" : "")}", - "M_MISSING_TOKEN" => $"No access token was specified: {Error}", - "M_BAD_JSON" => $"Request contained valid JSON, but it was malformed in some way: {Error}", - "M_NOT_JSON" => $"Request did not contain valid JSON: {Error}", - "M_NOT_FOUND" => $"The requested resource was not found: {Error}", - "M_LIMIT_EXCEEDED" => $"Too many requests have been sent in a short period of time. Wait a while then try again: {Error}", - "M_UNRECOGNISED" => $"The server did not recognise the request: {Error}", - "M_UNKOWN" => $"The server encountered an unexpected error: {Error}", - // endpoint specific - "M_UNAUTHORIZED" => $"The request did not contain valid authentication information for the target of the request: {Error}", - "M_USER_DEACTIVATED" => $"The user ID associated with the request has been deactivated: {Error}", - "M_USER_IN_USE" => $"The user ID associated with the request is already in use: {Error}", - "M_INVALID_USERNAME" => $"The requested user ID is not valid: {Error}", - "M_ROOM_IN_USE" => $"The room alias requested is already taken: {Error}", - "M_INVALID_ROOM_STATE" => $"The room associated with the request is not in a valid state to perform the request: {Error}", - "M_THREEPID_IN_USE" => $"The threepid requested is already associated with a user ID on this server: {Error}", - "M_THREEPID_NOT_FOUND" => $"The threepid requested is not associated with any user ID: {Error}", - "M_THREEPID_AUTH_FAILED" => $"The provided threepid and/or token was invalid: {Error}", - "M_THREEPID_DENIED" => $"The homeserver does not permit the third party identifier in question: {Error}", - "M_SERVER_NOT_TRUSTED" => $"The homeserver does not trust the identity server: {Error}", - "M_UNSUPPORTED_ROOM_VERSION" => $"The room version is not supported: {Error}", - "M_INCOMPATIBLE_ROOM_VERSION" => $"The room version is incompatible: {Error}", - "M_BAD_STATE" => $"The request was invalid because the state was invalid: {Error}", - "M_GUEST_ACCESS_FORBIDDEN" => $"Guest access is forbidden: {Error}", - "M_CAPTCHA_NEEDED" => $"Captcha needed: {Error}", - "M_CAPTCHA_INVALID" => $"Captcha invalid: {Error}", - "M_MISSING_PARAM" => $"Missing parameter: {Error}", - "M_INVALID_PARAM" => $"Invalid parameter: {Error}", - "M_TOO_LARGE" => $"The request or entity was too large: {Error}", - "M_EXCLUSIVE" => $"The resource being requested is reserved by an application service, or the application service making the request has not created the resource: {Error}", - "M_RESOURCE_LIMIT_EXCEEDED" => $"Exceeded resource limit: {Error}", - "M_CANNOT_LEAVE_SERVER_NOTICE_ROOM" => $"Cannot leave server notice room: {Error}", - _ => $"Unknown error: {new { ErrorCode, Error, SoftLogout, RetryAfterMs }.ToJson(ignoreNull: true)}" - }}"; -} diff --git a/MatrixRoomUtils.Core/MatrixRoomUtils.Core.csproj b/MatrixRoomUtils.Core/MatrixRoomUtils.Core.csproj deleted file mode 100644 index 3571eab..0000000 --- a/MatrixRoomUtils.Core/MatrixRoomUtils.Core.csproj +++ /dev/null @@ -1,14 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk"> - - <PropertyGroup> - <TargetFramework>net7.0</TargetFramework> - <ImplicitUsings>enable</ImplicitUsings> - <Nullable>enable</Nullable> - </PropertyGroup> - - <ItemGroup> - <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" /> - <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.1" /> - </ItemGroup> - -</Project> diff --git a/MatrixRoomUtils.Core/MessagesResponse.cs b/MatrixRoomUtils.Core/MessagesResponse.cs deleted file mode 100644 index 7a303bc..0000000 --- a/MatrixRoomUtils.Core/MessagesResponse.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Interfaces; -using MatrixRoomUtils.Core.Responses; - -namespace MatrixRoomUtils.Core; - -public class MessagesResponse { - [JsonPropertyName("start")] - public string Start { get; set; } - - [JsonPropertyName("end")] - public string? End { get; set; } - - [JsonPropertyName("chunk")] - public List<StateEventResponse> Chunk { get; set; } = new(); - - [JsonPropertyName("state")] - public List<StateEventResponse> State { get; set; } = new(); -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/RemoteHomeServer.cs b/MatrixRoomUtils.Core/RemoteHomeServer.cs deleted file mode 100644 index e6c28c3..0000000 --- a/MatrixRoomUtils.Core/RemoteHomeServer.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Net.Http.Json; -using System.Text.Json; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; -using MatrixRoomUtils.Core.Services; - -namespace MatrixRoomUtils.Core; - -public class RemoteHomeServer : IHomeServer { - public RemoteHomeServer(string canonicalHomeServerDomain) { - HomeServerDomain = canonicalHomeServerDomain; - _httpClient = new MatrixHttpClient(); - _httpClient.Timeout = TimeSpan.FromSeconds(5); - } - -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Responses/Admin/AdminRoomDeleteRequest.cs b/MatrixRoomUtils.Core/Responses/Admin/AdminRoomDeleteRequest.cs deleted file mode 100644 index 5605329..0000000 --- a/MatrixRoomUtils.Core/Responses/Admin/AdminRoomDeleteRequest.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Text.Json.Serialization; - -namespace MatrixRoomUtils.Core.Responses.Admin; - -public class AdminRoomDeleteRequest { - [JsonPropertyName("new_room_user_id")] - public string? NewRoomUserId { get; set; } - [JsonPropertyName("room_name")] - public string? RoomName { get; set; } - [JsonPropertyName("block")] - public bool Block { get; set; } - [JsonPropertyName("purge")] - public bool Purge { get; set; } - [JsonPropertyName("message")] - public string? Message { get; set; } - [JsonPropertyName("force_purge")] - public bool ForcePurge { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Responses/Admin/AdminRoomListingResult.cs b/MatrixRoomUtils.Core/Responses/Admin/AdminRoomListingResult.cs deleted file mode 100644 index d6da859..0000000 --- a/MatrixRoomUtils.Core/Responses/Admin/AdminRoomListingResult.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System.Text.Json.Serialization; - -namespace MatrixRoomUtils.Core.Responses.Admin; - -public class AdminRoomListingResult { - [JsonPropertyName("offset")] - public int Offset { get; set; } - - [JsonPropertyName("total_rooms")] - public int TotalRooms { get; set; } - - [JsonPropertyName("next_batch")] - public int? NextBatch { get; set; } - - [JsonPropertyName("prev_batch")] - public int? PrevBatch { get; set; } - - [JsonPropertyName("rooms")] - public List<AdminRoomListingResultRoom> Rooms { get; set; } = new(); - - public class AdminRoomListingResultRoom { - [JsonPropertyName("room_id")] - public string RoomId { get; set; } - - [JsonPropertyName("name")] - public string? Name { get; set; } - - [JsonPropertyName("canonical_alias")] - public string? CanonicalAlias { get; set; } - - [JsonPropertyName("joined_members")] - public int JoinedMembers { get; set; } - - [JsonPropertyName("joined_local_members")] - public int JoinedLocalMembers { get; set; } - - [JsonPropertyName("version")] - public string Version { get; set; } - - [JsonPropertyName("creator")] - public string Creator { get; set; } - - [JsonPropertyName("encryption")] - public string? Encryption { get; set; } - - [JsonPropertyName("federatable")] - public bool Federatable { get; set; } - - [JsonPropertyName("public")] - public bool Public { get; set; } - - [JsonPropertyName("join_rules")] - public string? JoinRules { get; set; } - - [JsonPropertyName("guest_access")] - public string? GuestAccess { get; set; } - - [JsonPropertyName("history_visibility")] - public string? HistoryVisibility { get; set; } - - [JsonPropertyName("state_events")] - public int StateEvents { get; set; } - } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Responses/CreateRoomRequest.cs b/MatrixRoomUtils.Core/Responses/CreateRoomRequest.cs deleted file mode 100644 index 540a323..0000000 --- a/MatrixRoomUtils.Core/Responses/CreateRoomRequest.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System.Reflection; -using System.Text.Json.Nodes; -using System.Text.Json.Serialization; -using System.Text.RegularExpressions; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; -using MatrixRoomUtils.Core.StateEventTypes; -using MatrixRoomUtils.Core.StateEventTypes.Spec; - -namespace MatrixRoomUtils.Core.Responses; - -public class CreateRoomRequest { - [JsonIgnore] public CreationContentBaseType _creationContentBaseType; - - public CreateRoomRequest() => _creationContentBaseType = new CreationContentBaseType(this); - - [JsonPropertyName("name")] - public string Name { get; set; } = null!; - - [JsonPropertyName("room_alias_name")] - public string RoomAliasName { get; set; } = null!; - - //we dont want to use this, we want more control - // [JsonPropertyName("preset")] - // public string Preset { get; set; } = null!; - - [JsonPropertyName("initial_state")] - public List<StateEvent> InitialState { get; set; } = null!; - - [JsonPropertyName("visibility")] - public string Visibility { get; set; } = null!; - - [JsonPropertyName("power_level_content_override")] - public RoomPowerLevelEventData PowerLevelContentOverride { get; set; } = null!; - - [JsonPropertyName("creation_content")] - public JsonObject CreationContent { get; set; } = new(); - - /// <summary> - /// For use only when you can't use the CreationContent property - /// </summary> - - public StateEvent this[string event_type, string event_key = ""] { - get { - var stateEvent = InitialState.FirstOrDefault(x => x.Type == event_type && x.StateKey == event_key); - if (stateEvent == null) { - InitialState.Add(stateEvent = new StateEvent { - Type = event_type, - StateKey = event_key, - TypedContent = Activator.CreateInstance( - StateEvent.KnownStateEventTypes.FirstOrDefault(x => - x.GetCustomAttributes<MatrixEventAttribute>()? - .Any(y => y.EventName == event_type) ?? false) ?? typeof(object) - ) - }); - } - return stateEvent; - } - set { - var stateEvent = InitialState.FirstOrDefault(x => x.Type == event_type && x.StateKey == event_key); - if (stateEvent == null) - InitialState.Add(value); - else - InitialState[InitialState.IndexOf(stateEvent)] = value; - } - } - - public Dictionary<string, string> Validate() { - Dictionary<string, string> errors = new(); - if (!Regex.IsMatch(RoomAliasName, @"[a-zA-Z0-9_\-]+$")) - errors.Add("room_alias_name", - "Room alias name must only contain letters, numbers, underscores, and hyphens."); - - return errors; - } -} diff --git a/MatrixRoomUtils.Core/Responses/CreationContentBaseType.cs b/MatrixRoomUtils.Core/Responses/CreationContentBaseType.cs deleted file mode 100644 index 743c552..0000000 --- a/MatrixRoomUtils.Core/Responses/CreationContentBaseType.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Text.Json.Serialization; - -namespace MatrixRoomUtils.Core.Responses; - -public class CreationContentBaseType { - private readonly CreateRoomRequest createRoomRequest; - - public CreationContentBaseType(CreateRoomRequest createRoomRequest) => this.createRoomRequest = createRoomRequest; - - [JsonPropertyName("type")] - public string Type { - get => (string)createRoomRequest.CreationContent["type"]; - set { - if (value is "null" or "") createRoomRequest.CreationContent.Remove("type"); - else createRoomRequest.CreationContent["type"] = value; - } - } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Responses/LoginResponse.cs b/MatrixRoomUtils.Core/Responses/LoginResponse.cs deleted file mode 100644 index 239ea03..0000000 --- a/MatrixRoomUtils.Core/Responses/LoginResponse.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Text.Json.Serialization; - -namespace MatrixRoomUtils.Core.Responses; - -public class LoginResponse { - [JsonPropertyName("access_token")] - public string AccessToken { get; set; } - - [JsonPropertyName("device_id")] - public string DeviceId { get; set; } - - [JsonPropertyName("home_server")] - public string Homeserver { get; set; } - - [JsonPropertyName("user_id")] - public string UserId { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Responses/StateEventResponse.cs b/MatrixRoomUtils.Core/Responses/StateEventResponse.cs deleted file mode 100644 index a7f9187..0000000 --- a/MatrixRoomUtils.Core/Responses/StateEventResponse.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System.Text.Json.Nodes; -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.Responses; - -public class StateEventResponse : StateEvent { - [JsonPropertyName("origin_server_ts")] - public ulong OriginServerTs { get; set; } - - [JsonPropertyName("room_id")] - public string RoomId { get; set; } - - [JsonPropertyName("sender")] - public string Sender { get; set; } - - [JsonPropertyName("unsigned")] - public UnsignedData? Unsigned { get; set; } - - [JsonPropertyName("event_id")] - public string EventId { get; set; } - - [JsonPropertyName("user_id")] - public string UserId { get; set; } - - [JsonPropertyName("replaces_state")] - public string ReplacesState { get; set; } - - public class UnsignedData { - [JsonPropertyName("age")] - public ulong? Age { get; set; } - - [JsonPropertyName("redacted_because")] - public object? RedactedBecause { get; set; } - - [JsonPropertyName("transaction_id")] - public string? TransactionId { get; set; } - - [JsonPropertyName("replaces_state")] - public string? ReplacesState { get; set; } - - [JsonPropertyName("prev_sender")] - public string? PrevSender { get; set; } - - [JsonPropertyName("prev_content")] - public JsonObject? PrevContent { get; set; } - } -} diff --git a/MatrixRoomUtils.Core/RoomTypes/GenericRoom.cs b/MatrixRoomUtils.Core/RoomTypes/GenericRoom.cs deleted file mode 100644 index eced379..0000000 --- a/MatrixRoomUtils.Core/RoomTypes/GenericRoom.cs +++ /dev/null @@ -1,187 +0,0 @@ -using System.Net.Http.Json; -using System.Text.Json; -using System.Text.Json.Nodes; -using System.Web; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Responses; -using MatrixRoomUtils.Core.StateEventTypes.Spec; - -namespace MatrixRoomUtils.Core.RoomTypes; - -public class GenericRoom { - internal readonly AuthenticatedHomeServer _homeServer; - internal readonly MatrixHttpClient _httpClient; - - public GenericRoom(AuthenticatedHomeServer homeServer, string roomId) { - _homeServer = homeServer; - _httpClient = homeServer._httpClient; - RoomId = roomId; - if (GetType() != typeof(SpaceRoom)) - AsSpace = new SpaceRoom(homeServer, RoomId); - } - - public string RoomId { get; set; } - - [Obsolete("", true)] - public async Task<JsonElement?> GetStateAsync(string type, string stateKey = "") { - var url = $"/_matrix/client/v3/rooms/{RoomId}/state"; - if (!string.IsNullOrEmpty(type)) url += $"/{type}"; - if (!string.IsNullOrEmpty(stateKey)) url += $"/{stateKey}"; - return await _httpClient.GetFromJsonAsync<JsonElement>(url); - } - - public async IAsyncEnumerable<StateEventResponse?> GetFullStateAsync() { - var res = await _httpClient.GetAsync($"/_matrix/client/v3/rooms/{RoomId}/state"); - var result = - JsonSerializer.DeserializeAsyncEnumerable<StateEventResponse>(await res.Content.ReadAsStreamAsync()); - await foreach (var resp in result) { - yield return resp; - } - } - - public async Task<T?> GetStateAsync<T>(string type, string stateKey = "") { - var url = $"/_matrix/client/v3/rooms/{RoomId}/state"; - if (!string.IsNullOrEmpty(type)) url += $"/{type}"; - if (!string.IsNullOrEmpty(stateKey)) url += $"/{stateKey}"; - try { -#if DEBUG && false - var resp = await _httpClient.GetFromJsonAsync<JsonObject>(url); - try { - _homeServer._httpClient.PostAsJsonAsync( - "http://localhost:5116/validate/" + typeof(T).AssemblyQualifiedName, resp); - } - catch (Exception e) { - Console.WriteLine("[!!] Checking state response failed: " + e); - } - - return resp.Deserialize<T>(); -#else - var resp = await _httpClient.GetFromJsonAsync<T>(url); - return resp; -#endif - } - catch (MatrixException e) { - if (e is not { ErrorCode: "M_NOT_FOUND" }) { - throw; - } - - Console.WriteLine(e); - return default; - } - } - - public async Task<MessagesResponse> GetMessagesAsync(string from = "", int limit = 10, string dir = "b", - string filter = "") { - var url = $"/_matrix/client/v3/rooms/{RoomId}/messages?from={from}&limit={limit}&dir={dir}"; - if (!string.IsNullOrEmpty(filter)) url += $"&filter={filter}"; - var res = await _httpClient.GetFromJsonAsync<MessagesResponse>(url); - return res ?? new MessagesResponse(); - } - - public async Task<string> GetNameAsync() { - try { - var res = await GetStateAsync<RoomNameEventData>("m.room.name"); - return res?.Name ?? RoomId; - } - catch (MatrixException e) { - return $"{RoomId} ({e.ErrorCode})"; - } - } - - public async Task JoinAsync(string[]? homeservers = null, string? reason = null) { - var join_url = $"/_matrix/client/v3/join/{HttpUtility.UrlEncode(RoomId)}"; - Console.WriteLine($"Calling {join_url} with {homeservers?.Length ?? 0} via's..."); - if (homeservers == null || homeservers.Length == 0) homeservers = new[] { RoomId.Split(':')[1] }; - var fullJoinUrl = $"{join_url}?server_name=" + string.Join("&server_name=", homeservers); - var res = await _httpClient.PostAsJsonAsync(fullJoinUrl, new { - reason - }); - } - - public async IAsyncEnumerable<StateEventResponse> GetMembersAsync(bool joinedOnly = true) { - var res = GetFullStateAsync(); - await foreach (var member in res) { - if (member.Type != "m.room.member") continue; - if (joinedOnly && (member.TypedContent as RoomMemberEventData).Membership is not "join") continue; - yield return member; - } - } - - public async Task<List<string>> GetAliasesAsync() { - var res = await GetStateAsync<RoomAliasEventData>("m.room.aliases"); - return res.Aliases; - } - - public async Task<CanonicalAliasEventData?> GetCanonicalAliasAsync() => - await GetStateAsync<CanonicalAliasEventData>("m.room.canonical_alias"); - - public async Task<RoomTopicEventData?> GetTopicAsync() => - await GetStateAsync<RoomTopicEventData>("m.room.topic"); - - public async Task<RoomAvatarEventData?> GetAvatarUrlAsync() => - await GetStateAsync<RoomAvatarEventData>("m.room.avatar"); - - public async Task<JoinRulesEventData> GetJoinRuleAsync() => - await GetStateAsync<JoinRulesEventData>("m.room.join_rules"); - - public async Task<HistoryVisibilityEventData?> GetHistoryVisibilityAsync() => - await GetStateAsync<HistoryVisibilityEventData>("m.room.history_visibility"); - - public async Task<GuestAccessEventData?> GetGuestAccessAsync() => - await GetStateAsync<GuestAccessEventData>("m.room.guest_access"); - - public async Task<RoomCreateEventData> GetCreateEventAsync() => - await GetStateAsync<RoomCreateEventData>("m.room.create"); - - public async Task<string?> GetRoomType() { - var res = await GetStateAsync<RoomCreateEventData>("m.room.create"); - return res.Type; - } - - public async Task ForgetAsync() => - await _httpClient.PostAsync($"/_matrix/client/v3/rooms/{RoomId}/forget", null); - - public async Task LeaveAsync(string? reason = null) => - await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/leave", new { - reason - }); - - public async Task KickAsync(string userId, string? reason = null) => - await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/kick", - new UserIdAndReason() { UserId = userId, Reason = reason }); - - public async Task BanAsync(string userId, string? reason = null) => - await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/ban", - new UserIdAndReason() { UserId = userId, Reason = reason }); - - public async Task UnbanAsync(string userId) => - await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/unban", - new UserIdAndReason() { UserId = userId }); - - public async Task<EventIdResponse> SendStateEventAsync(string eventType, object content) => - await (await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/state/{eventType}", content)) - .Content.ReadFromJsonAsync<EventIdResponse>(); - - public async Task<EventIdResponse> SendMessageEventAsync(string eventType, RoomMessageEventData content) { - var res = await _httpClient.PutAsJsonAsync( - $"/_matrix/client/v3/rooms/{RoomId}/send/{eventType}/" + Guid.NewGuid(), content); - var resu = await res.Content.ReadFromJsonAsync<EventIdResponse>(); - return resu; - } - - public async Task<EventIdResponse> SendFileAsync(string eventType, string fileName, Stream fileStream) { - var content = new MultipartFormDataContent(); - content.Add(new StreamContent(fileStream), "file", fileName); - var res = await - ( - await _httpClient.PutAsync( - $"/_matrix/client/v3/rooms/{RoomId}/send/{eventType}/" + Guid.NewGuid(), - content - ) - ) - .Content.ReadFromJsonAsync<EventIdResponse>(); - return res; - } - - public readonly SpaceRoom AsSpace; -} diff --git a/MatrixRoomUtils.Core/RoomTypes/SpaceRoom.cs b/MatrixRoomUtils.Core/RoomTypes/SpaceRoom.cs deleted file mode 100644 index 1b93064..0000000 --- a/MatrixRoomUtils.Core/RoomTypes/SpaceRoom.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Text.Json; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; -using MatrixRoomUtils.Core.Responses; - -namespace MatrixRoomUtils.Core.RoomTypes; - -public class SpaceRoom : GenericRoom { - private readonly AuthenticatedHomeServer _homeServer; - private readonly GenericRoom _room; - - public SpaceRoom(AuthenticatedHomeServer homeServer, string roomId) : base(homeServer, roomId) { - _homeServer = homeServer; - } - - private static SemaphoreSlim _semaphore = new(1, 1); - public async IAsyncEnumerable<GenericRoom> GetRoomsAsync(bool includeRemoved = false) { - await _semaphore.WaitAsync(); - var rooms = new List<GenericRoom>(); - var state = GetFullStateAsync(); - await foreach (var stateEvent in state) { - if (stateEvent.Type != "m.space.child") continue; - if (stateEvent.RawContent.ToJson() != "{}" || includeRemoved) - yield return await _homeServer.GetRoom(stateEvent.StateKey); - } - _semaphore.Release(); - } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Services/HomeserverProviderService.cs b/MatrixRoomUtils.Core/Services/HomeserverProviderService.cs deleted file mode 100644 index 4bc785a..0000000 --- a/MatrixRoomUtils.Core/Services/HomeserverProviderService.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System.Net.Http.Headers; -using System.Net.Http.Json; -using System.Text.Json; -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Responses; -using Microsoft.Extensions.Logging; - -namespace MatrixRoomUtils.Core.Services; - -public class HomeserverProviderService { - private readonly TieredStorageService _tieredStorageService; - private readonly ILogger<HomeserverProviderService> _logger; - private readonly HomeserverResolverService _homeserverResolverService; - - public HomeserverProviderService(TieredStorageService tieredStorageService, - ILogger<HomeserverProviderService> logger, HomeserverResolverService homeserverResolverService) { - Console.WriteLine("Homeserver provider service instantiated!"); - _tieredStorageService = tieredStorageService; - _logger = logger; - _homeserverResolverService = homeserverResolverService; - logger.LogDebug( - $"New HomeserverProviderService created with TieredStorageService<{string.Join(", ", tieredStorageService.GetType().GetProperties().Select(x => x.Name))}>!"); - } - - private static Dictionary<string, SemaphoreSlim> _authenticatedHomeserverSemaphore = new(); - private static Dictionary<string, AuthenticatedHomeServer> _authenticatedHomeServerCache = new(); - - public async Task<AuthenticatedHomeServer> GetAuthenticatedWithToken(string homeserver, string accessToken, - string? overrideFullDomain = null) { - SemaphoreSlim sem = _authenticatedHomeserverSemaphore.GetOrCreate(homeserver+accessToken, _ => new SemaphoreSlim(1, 1)); - await sem.WaitAsync(); - if (_authenticatedHomeServerCache.ContainsKey(homeserver+accessToken)) { - sem.Release(); - return _authenticatedHomeServerCache[homeserver+accessToken]; - } - - var hs = new AuthenticatedHomeServer(_tieredStorageService, homeserver, accessToken); - hs.FullHomeServerDomain = overrideFullDomain ?? - await _homeserverResolverService.ResolveHomeserverFromWellKnown(homeserver); - hs._httpClient.Dispose(); - hs._httpClient = new MatrixHttpClient { BaseAddress = new Uri(hs.FullHomeServerDomain) }; - hs._httpClient.Timeout = TimeSpan.FromSeconds(120); - hs._httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); - - hs.WhoAmI = (await hs._httpClient.GetFromJsonAsync<WhoAmIResponse>("/_matrix/client/v3/account/whoami"))!; - - _authenticatedHomeServerCache[homeserver+accessToken] = hs; - sem.Release(); - - return hs; - } - - public async Task<RemoteHomeServer> GetRemoteHomeserver(string homeserver, string? overrideFullDomain = null) { - var hs = new RemoteHomeServer(homeserver); - hs.FullHomeServerDomain = overrideFullDomain ?? - await _homeserverResolverService.ResolveHomeserverFromWellKnown(homeserver); - hs._httpClient.Dispose(); - hs._httpClient = new MatrixHttpClient { BaseAddress = new Uri(hs.FullHomeServerDomain) }; - hs._httpClient.Timeout = TimeSpan.FromSeconds(120); - return hs; - } - - public async Task<LoginResponse> Login(string homeserver, string user, string password, - string? overrideFullDomain = null) { - var hs = await GetRemoteHomeserver(homeserver, overrideFullDomain); - var payload = new LoginRequest { - Identifier = new() { User = user }, - Password = password - }; - var resp = await hs._httpClient.PostAsJsonAsync("/_matrix/client/v3/login", payload); - var data = await resp.Content.ReadFromJsonAsync<LoginResponse>(); - return data!; - } - - private class LoginRequest { - [JsonPropertyName("type")] - public string Type { get; set; } = "m.login.password"; - - [JsonPropertyName("identifier")] - public LoginIdentifier Identifier { get; set; } = new(); - - [JsonPropertyName("password")] - public string Password { get; set; } = ""; - - [JsonPropertyName("initial_device_display_name")] - public string InitialDeviceDisplayName { get; set; } = "Rory&::LibMatrix"; - - public class LoginIdentifier { - [JsonPropertyName("type")] - public string Type { get; set; } = "m.id.user"; - - [JsonPropertyName("user")] - public string User { get; set; } = ""; - } - } -} diff --git a/MatrixRoomUtils.Core/Services/HomeserverResolverService.cs b/MatrixRoomUtils.Core/Services/HomeserverResolverService.cs deleted file mode 100644 index 5856000..0000000 --- a/MatrixRoomUtils.Core/Services/HomeserverResolverService.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System.Net.Http.Json; -using System.Text.Json; -using MatrixRoomUtils.Core.Extensions; -using Microsoft.Extensions.Logging; - -namespace MatrixRoomUtils.Core.Services; - -public class HomeserverResolverService { - private readonly MatrixHttpClient _httpClient = new(); - private readonly ILogger<HomeserverResolverService> _logger; - - private static readonly Dictionary<string, string> _wellKnownCache = new(); - private static readonly Dictionary<string, SemaphoreSlim> _wellKnownSemaphores = new(); - - public HomeserverResolverService(ILogger<HomeserverResolverService> logger) { - _logger = logger; - } - - public async Task<string> ResolveHomeserverFromWellKnown(string homeserver) { - var res = await _resolveHomeserverFromWellKnown(homeserver); - if (!res.StartsWith("http")) res = "https://" + res; - if (res.EndsWith(":443")) res = res.Substring(0, res.Length - 4); - return res; - } - - private async Task<string> _resolveHomeserverFromWellKnown(string homeserver) { - if (homeserver is null) throw new ArgumentNullException(nameof(homeserver)); - SemaphoreSlim sem = _wellKnownSemaphores.GetOrCreate(homeserver, _ => new SemaphoreSlim(1, 1)); - await sem.WaitAsync(); - if (_wellKnownCache.ContainsKey(homeserver)) { - sem.Release(); - return _wellKnownCache[homeserver]; - } - - string? result = null; - _logger.LogInformation($"Attempting to resolve homeserver: {homeserver}"); - result ??= await _tryResolveFromClientWellknown(homeserver); - result ??= await _tryResolveFromServerWellknown(homeserver); - result ??= await _tryCheckIfDomainHasHomeserver(homeserver); - - if (result is not null) { - _logger.LogInformation($"Resolved homeserver: {homeserver} -> {result}"); - _wellKnownCache[homeserver] = result; - sem.Release(); - return result; - } - - throw new InvalidDataException($"Failed to resolve homeserver for {homeserver}! Is it online and configured correctly?"); - } - - private async Task<string?> _tryResolveFromClientWellknown(string homeserver) { - if (!homeserver.StartsWith("http")) homeserver = "https://" + homeserver; - if (await _httpClient.CheckSuccessStatus($"{homeserver}/.well-known/matrix/client")) { - var resp = await _httpClient.GetFromJsonAsync<JsonElement>($"{homeserver}/.well-known/matrix/client"); - var hs = resp.GetProperty("m.homeserver").GetProperty("base_url").GetString(); - return hs; - } - - _logger.LogInformation("No client well-known..."); - return null; - } - - private async Task<string?> _tryResolveFromServerWellknown(string homeserver) { - if (!homeserver.StartsWith("http")) homeserver = "https://" + homeserver; - if (await _httpClient.CheckSuccessStatus($"{homeserver}/.well-known/matrix/server")) { - var resp = await _httpClient.GetFromJsonAsync<JsonElement>($"{homeserver}/.well-known/matrix/server"); - var hs = resp.GetProperty("m.server").GetString(); - return hs; - } - - _logger.LogInformation("No server well-known..."); - return null; - } - - private async Task<string?> _tryCheckIfDomainHasHomeserver(string homeserver) { - _logger.LogInformation($"Checking if {homeserver} hosts a homeserver..."); - if (await _httpClient.CheckSuccessStatus($"{homeserver}/_matrix/client/versions")) - return homeserver; - _logger.LogInformation("No homeserver on shortname..."); - return null; - } - - private async Task<string?> _tryCheckIfSubDomainHasHomeserver(string homeserver, string subdomain) { - homeserver = homeserver.Replace("https://", $"https://{subdomain}."); - return await _tryCheckIfDomainHasHomeserver(homeserver); - } -} diff --git a/MatrixRoomUtils.Core/Services/ServiceInstaller.cs b/MatrixRoomUtils.Core/Services/ServiceInstaller.cs deleted file mode 100644 index bd5b1bd..0000000 --- a/MatrixRoomUtils.Core/Services/ServiceInstaller.cs +++ /dev/null @@ -1,30 +0,0 @@ -using MatrixRoomUtils.Core.Extensions; -using Microsoft.Extensions.DependencyInjection; - -namespace MatrixRoomUtils.Core.Services; - -public static class ServiceInstaller { - - public static IServiceCollection AddRoryLibMatrixServices(this IServiceCollection services, RoryLibMatrixConfiguration? config = null) { - //Check required services - if (!services.Any(x => x.ServiceType == typeof(TieredStorageService))) - throw new Exception("[MRUCore/DI] No TieredStorageService has been registered!"); - //Add config - if(config is not null) - services.AddSingleton(config); - else { - services.AddSingleton(new RoryLibMatrixConfiguration()); - } - //Add services - services.AddSingleton<HomeserverProviderService>(); - services.AddSingleton<HomeserverResolverService>(); - // services.AddScoped<MatrixHttpClient>(); - return services; - } - - -} - -public class RoryLibMatrixConfiguration { - public string AppName { get; set; } = "Rory&::LibMatrix"; -} diff --git a/MatrixRoomUtils.Core/Services/TieredStorageService.cs b/MatrixRoomUtils.Core/Services/TieredStorageService.cs deleted file mode 100644 index 2f27443..0000000 --- a/MatrixRoomUtils.Core/Services/TieredStorageService.cs +++ /dev/null @@ -1,13 +0,0 @@ -using MatrixRoomUtils.Core.Interfaces.Services; - -namespace MatrixRoomUtils.Core.Services; - -public class TieredStorageService { - public IStorageProvider CacheStorageProvider { get; } - public IStorageProvider DataStorageProvider { get; } - - public TieredStorageService(IStorageProvider cacheStorageProvider, IStorageProvider dataStorageProvider) { - CacheStorageProvider = cacheStorageProvider; - DataStorageProvider = dataStorageProvider; - } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEvent.cs b/MatrixRoomUtils.Core/StateEvent.cs deleted file mode 100644 index 785c637..0000000 --- a/MatrixRoomUtils.Core/StateEvent.cs +++ /dev/null @@ -1,120 +0,0 @@ -using System.Diagnostics; -using System.Reflection; -using System.Text.Json; -using System.Text.Json.Nodes; -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; -using MatrixRoomUtils.Core.Responses; -using MatrixRoomUtils.Core.StateEventTypes; - -namespace MatrixRoomUtils.Core; - -public class StateEvent { - public static List<Type> KnownStateEventTypes = - new ClassCollector<IStateEventType>().ResolveFromAllAccessibleAssemblies(); - - public static Type GetStateEventType(string type) { - if (type == "m.receipt") { - return typeof(Dictionary<string, JsonObject>); - } - - var eventType = KnownStateEventTypes.FirstOrDefault(x => - x.GetCustomAttributes<MatrixEventAttribute>()?.Any(y => y.EventName == type) ?? false); - - return eventType ?? typeof(object); - } - - public object TypedContent { - get { - try { - return RawContent.Deserialize(GetType)!; - } - catch (JsonException e) { - Console.WriteLine(e); - Console.WriteLine("Content:\n" + ObjectExtensions.ToJson(RawContent)); - } - - return null; - } - set => RawContent = JsonSerializer.Deserialize<JsonObject>(JsonSerializer.Serialize(value)); - } - - [JsonPropertyName("state_key")] - public string StateKey { get; set; } = ""; - - private string _type; - - [JsonPropertyName("type")] - public string Type { - get => _type; - set { - _type = value; - // if (RawContent is not null && this is StateEventResponse stateEventResponse) { - // if (File.Exists($"unknown_state_events/{Type}/{stateEventResponse.EventId}.json")) return; - // var x = GetType.Name; - // } - } - } - - [JsonPropertyName("replaces_state")] - public string? ReplacesState { get; set; } - - private JsonObject? _rawContent; - - [JsonPropertyName("content")] - public JsonObject? RawContent { - get => _rawContent; - set { - _rawContent = value; - // if (Type is not null && this is StateEventResponse stateEventResponse) { - // if (File.Exists($"unknown_state_events/{Type}/{stateEventResponse.EventId}.json")) return; - // var x = GetType.Name; - // } - } - } - - [JsonIgnore] - public Type GetType { - get { - var type = GetStateEventType(Type); - - //special handling for some types - // if (type == typeof(RoomEmotesEventData)) { - // RawContent["emote"] = RawContent["emote"]?.AsObject() ?? new JsonObject(); - // } - // - // if (this is StateEventResponse stateEventResponse) { - // if (type == null || type == typeof(object)) { - // Console.WriteLine($"Warning: unknown event type '{Type}'!"); - // Console.WriteLine(RawContent.ToJson()); - // Directory.CreateDirectory($"unknown_state_events/{Type}"); - // File.WriteAllText($"unknown_state_events/{Type}/{stateEventResponse.EventId}.json", - // RawContent.ToJson()); - // Console.WriteLine($"Saved to unknown_state_events/{Type}/{stateEventResponse.EventId}.json"); - // } - // else if (RawContent is not null && RawContent.FindExtraJsonObjectFields(type)) { - // Directory.CreateDirectory($"unknown_state_events/{Type}"); - // File.WriteAllText($"unknown_state_events/{Type}/{stateEventResponse.EventId}.json", - // RawContent.ToJson()); - // Console.WriteLine($"Saved to unknown_state_events/{Type}/{stateEventResponse.EventId}.json"); - // } - // } - - return type; - } - } - - //debug - public string dtype { - get { - var res = GetType().Name switch { - "StateEvent`1" => $"StateEvent", - _ => GetType().Name - }; - return res; - } - } - - public string cdtype => TypedContent.GetType().Name; -} diff --git a/MatrixRoomUtils.Core/StateEventTypes/Common/MjolnirShortcodeEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Common/MjolnirShortcodeEventData.cs deleted file mode 100644 index 66dcdb9..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Common/MjolnirShortcodeEventData.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Common; - -[MatrixEvent(EventName = "org.matrix.mjolnir.shortcode")] -public class MjolnirShortcodeEventData : IStateEventType { - [JsonPropertyName("shortcode")] - public string? Shortcode { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Common/RoomEmotesEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Common/RoomEmotesEventData.cs deleted file mode 100644 index c263a3a..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Common/RoomEmotesEventData.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Common; - -[MatrixEvent(EventName = "im.ponies.room_emotes")] -public class RoomEmotesEventData : IStateEventType { - [JsonPropertyName("emoticons")] - public Dictionary<string, EmoticonData>? Emoticons { get; set; } - - [JsonPropertyName("images")] - public Dictionary<string, EmoticonData>? Images { get; set; } - - [JsonPropertyName("pack")] - public PackInfo? Pack { get; set; } - - public class EmoticonData { - [JsonPropertyName("url")] - public string? Url { get; set; } - } - - public class PackInfo { - - } -} diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/CanonicalAliasEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/CanonicalAliasEventData.cs deleted file mode 100644 index 354f99d..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/CanonicalAliasEventData.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.canonical_alias")] -public class CanonicalAliasEventData : IStateEventType { - [JsonPropertyName("alias")] - public string? Alias { get; set; } - [JsonPropertyName("alt_aliases")] - public string[]? AltAliases { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/GuestAccessEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/GuestAccessEventData.cs deleted file mode 100644 index c5b92ad..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/GuestAccessEventData.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.guest_access")] -public class GuestAccessEventData : IStateEventType { - [JsonPropertyName("guest_access")] - public string GuestAccess { get; set; } - - public bool IsGuestAccessEnabled { - get => GuestAccess == "can_join"; - set => GuestAccess = value ? "can_join" : "forbidden"; - } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/HistoryVisibilityEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/HistoryVisibilityEventData.cs deleted file mode 100644 index e0785b9..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/HistoryVisibilityEventData.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.history_visibility")] -public class HistoryVisibilityEventData : IStateEventType { - [JsonPropertyName("history_visibility")] - public string HistoryVisibility { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/JoinRulesEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/JoinRulesEventData.cs deleted file mode 100644 index f5410dc..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/JoinRulesEventData.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.join_rules")] -public class JoinRulesEventData : IStateEventType { - private static string Public = "public"; - private static string Invite = "invite"; - private static string Knock = "knock"; - - [JsonPropertyName("join_rule")] - public string JoinRule { get; set; } - - [JsonPropertyName("allow")] - public List<string> Allow { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/PolicyRuleStateEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/PolicyRuleStateEventData.cs deleted file mode 100644 index ef94cff..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/PolicyRuleStateEventData.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.policy.rule.user")] -[MatrixEvent(EventName = "m.policy.rule.server")] -[MatrixEvent(EventName = "org.matrix.mjolnir.rule.server")] -public class PolicyRuleStateEventData : IStateEventType { - /// <summary> - /// Entity this ban applies to, can use * and ? as globs. - /// </summary> - [JsonPropertyName("entity")] - public string Entity { get; set; } - - /// <summary> - /// Reason this user is banned - /// </summary> - [JsonPropertyName("reason")] - public string? Reason { get; set; } - - /// <summary> - /// Suggested action to take - /// </summary> - [JsonPropertyName("recommendation")] - public string? Recommendation { get; set; } - - /// <summary> - /// Expiry time in milliseconds since the unix epoch, or null if the ban has no expiry. - /// </summary> - [JsonPropertyName("support.feline.policy.expiry.rev.2")] //stable prefix: expiry, msc pending - public long? Expiry { get; set; } - - //utils - /// <summary> - /// Readable expiry time, provided for easy interaction - /// </summary> - [JsonPropertyName("gay.rory.matrix_room_utils.readable_expiry_time_utc")] - public DateTime? ExpiryDateTime { - get => Expiry == null ? null : DateTimeOffset.FromUnixTimeMilliseconds(Expiry.Value).DateTime; - set => Expiry = ((DateTimeOffset)value).ToUnixTimeMilliseconds(); - } -} - -public static class PolicyRecommendationTypes { - /// <summary> - /// Ban this user - /// </summary> - public static string Ban = "m.ban"; - - /// <summary> - /// Mute this user - /// </summary> - public static string Mute = "support.feline.policy.recommendation_mute"; //stable prefix: m.mute, msc pending -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/PresenceStateEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/PresenceStateEventData.cs deleted file mode 100644 index c5eb2ea..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/PresenceStateEventData.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.presence")] -public class PresenceStateEventData : IStateEventType { - [JsonPropertyName("presence")] - public string Presence { get; set; } - [JsonPropertyName("last_active_ago")] - public long LastActiveAgo { get; set; } - [JsonPropertyName("currently_active")] - public bool CurrentlyActive { get; set; } - [JsonPropertyName("status_msg")] - public string StatusMessage { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/ProfileResponseEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/ProfileResponseEventData.cs deleted file mode 100644 index f3a0ce9..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/ProfileResponseEventData.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -public class ProfileResponseEventData : IStateEventType { - [JsonPropertyName("avatar_url")] - public string? AvatarUrl { get; set; } = ""; - - [JsonPropertyName("displayname")] - public string? DisplayName { get; set; } = ""; -} diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomAliasEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomAliasEventData.cs deleted file mode 100644 index 611e8a2..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomAliasEventData.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.alias")] -public class RoomAliasEventData : IStateEventType { - [JsonPropertyName("aliases")] - public List<string>? Aliases { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomAvatarEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomAvatarEventData.cs deleted file mode 100644 index a14e4c5..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomAvatarEventData.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.avatar")] -public class RoomAvatarEventData : IStateEventType { - [JsonPropertyName("url")] - public string? Url { get; set; } - - [JsonPropertyName("info")] - public RoomAvatarInfo? Info { get; set; } - - public class RoomAvatarInfo { - [JsonPropertyName("h")] - public int? Height { get; set; } - - [JsonPropertyName("w")] - public int? Width { get; set; } - - [JsonPropertyName("mimetype")] - public string? MimeType { get; set; } - - [JsonPropertyName("size")] - public int? Size { get; set; } - } -} diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomCreateEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomCreateEventData.cs deleted file mode 100644 index 6127028..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomCreateEventData.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.create")] -public class RoomCreateEventData : IStateEventType { - [JsonPropertyName("room_version")] - public string? RoomVersion { get; set; } - [JsonPropertyName("creator")] - public string? Creator { get; set; } - [JsonPropertyName("m.federate")] - public bool? Federate { get; set; } - [JsonPropertyName("predecessor")] - public RoomCreatePredecessor? Predecessor { get; set; } - [JsonPropertyName("type")] - public string? Type { get; set; } - - public class RoomCreatePredecessor { - [JsonPropertyName("room_id")] - public string? RoomId { get; set; } - - [JsonPropertyName("event_id")] - public string? EventId { get; set; } - } -} diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomEncryptionEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomEncryptionEventData.cs deleted file mode 100644 index c473082..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomEncryptionEventData.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.encryption")] -public class RoomEncryptionEventData : IStateEventType { - [JsonPropertyName("algorithm")] - public string? Algorithm { get; set; } - [JsonPropertyName("rotation_period_ms")] - public ulong? RotationPeriodMs { get; set; } - [JsonPropertyName("rotation_period_msgs")] - public ulong? RotationPeriodMsgs { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomMemberEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomMemberEventData.cs deleted file mode 100644 index a543a2f..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomMemberEventData.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.member")] -public class RoomMemberEventData : IStateEventType { - [JsonPropertyName("reason")] - public string? Reason { get; set; } - - [JsonPropertyName("membership")] - public string Membership { get; set; } = null!; - - [JsonPropertyName("displayname")] - public string? Displayname { get; set; } - - [JsonPropertyName("is_direct")] - public bool? IsDirect { get; set; } - - [JsonPropertyName("avatar_url")] - public string? AvatarUrl { get; set; } - - [JsonPropertyName("kind")] - public string? Kind { get; set; } - - [JsonPropertyName("join_authorised_via_users_server")] - public string? JoinAuthorisedViaUsersServer { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomMessageEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomMessageEventData.cs deleted file mode 100644 index 2c56b88..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomMessageEventData.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.message")] -public class RoomMessageEventData : IStateEventType { - [JsonPropertyName("body")] - public string Body { get; set; } - [JsonPropertyName("msgtype")] - public string MessageType { get; set; } = "m.notice"; - - [JsonPropertyName("formatted_body")] - public string FormattedBody { get; set; } - - [JsonPropertyName("format")] - public string Format { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomNameEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomNameEventData.cs deleted file mode 100644 index e5b7d59..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomNameEventData.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.name")] -public class RoomNameEventData : IStateEventType { - [JsonPropertyName("name")] - public string? Name { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomPinnedEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomPinnedEventData.cs deleted file mode 100644 index d84e962..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomPinnedEventData.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.pinned_events")] -public class RoomPinnedEventData : IStateEventType { - [JsonPropertyName("pinned")] - public string[]? PinnedEvents { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomPowerLevelEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomPowerLevelEventData.cs deleted file mode 100644 index 1cde660..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomPowerLevelEventData.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.power_levels")] -public class RoomPowerLevelEventData : IStateEventType { - [JsonPropertyName("ban")] - public int Ban { get; set; } // = 50; - - [JsonPropertyName("events_default")] - public int EventsDefault { get; set; } // = 0; - - [JsonPropertyName("events")] - public Dictionary<string, int> Events { get; set; } // = null!; - - [JsonPropertyName("invite")] - public int Invite { get; set; } // = 50; - - [JsonPropertyName("kick")] - public int Kick { get; set; } // = 50; - - [JsonPropertyName("notifications")] - public NotificationsPL NotificationsPl { get; set; } // = null!; - - [JsonPropertyName("redact")] - public int Redact { get; set; } // = 50; - - [JsonPropertyName("state_default")] - public int StateDefault { get; set; } // = 50; - - [JsonPropertyName("users")] - public Dictionary<string, int> Users { get; set; } // = null!; - - [JsonPropertyName("users_default")] - public int UsersDefault { get; set; } // = 0; - - [Obsolete("Historical was a key related to MSC2716, a spec change on backfill that was dropped!", true)] - [JsonIgnore] - [JsonPropertyName("historical")] - public int Historical { get; set; } // = 50; - - public class NotificationsPL { - [JsonPropertyName("room")] - public int Room { get; set; } = 50; - } - - public bool IsUserAdmin(string userId) { - return Users.TryGetValue(userId, out var level) && level >= Events.Max(x=>x.Value); - } - - public bool UserHasPermission(string userId, string eventType) { - return Users.TryGetValue(userId, out var level) && level >= Events.GetValueOrDefault(eventType, EventsDefault); - } -} diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomTopicEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomTopicEventData.cs deleted file mode 100644 index cdd62a1..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomTopicEventData.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.topic")] -[MatrixEvent(EventName = "org.matrix.msc3765.topic", Legacy = true)] -public class RoomTopicEventData : IStateEventType { - [JsonPropertyName("topic")] - public string? Topic { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomTypingEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomTypingEventData.cs deleted file mode 100644 index 017a117..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/RoomTypingEventData.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.typing")] -public class RoomTypingEventData : IStateEventType { - [JsonPropertyName("user_ids")] - public string[]? UserIds { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/ServerACLEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/ServerACLEventData.cs deleted file mode 100644 index 4b559c6..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/ServerACLEventData.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.room.server_acl")] -public class ServerACLEventData : IStateEventType { - [JsonPropertyName("allow")] - public List<string> Allow { get; set; } // = null!; - - [JsonPropertyName("deny")] - public List<string> Deny { get; set; } // = null!; - - [JsonPropertyName("allow_ip_literals")] - public bool AllowIpLiterals { get; set; } // = false; -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/SpaceChildEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/SpaceChildEventData.cs deleted file mode 100644 index bb62d92..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/SpaceChildEventData.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.space.child")] -public class SpaceChildEventData : IStateEventType { - [JsonPropertyName("auto_join")] - public bool? AutoJoin { get; set; } - [JsonPropertyName("via")] - public string[]? Via { get; set; } - [JsonPropertyName("suggested")] - public bool? Suggested { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/Spec/SpaceParentEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/Spec/SpaceParentEventData.cs deleted file mode 100644 index a40f7ae..0000000 --- a/MatrixRoomUtils.Core/StateEventTypes/Spec/SpaceParentEventData.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Text.Json.Serialization; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces; - -namespace MatrixRoomUtils.Core.StateEventTypes.Spec; - -[MatrixEvent(EventName = "m.space.parent")] -public class SpaceParentEventData : IStateEventType { - [JsonPropertyName("via")] - public string[]? Via { get; set; } - - [JsonPropertyName("canonical")] - public bool? Canonical { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/UserIdAndReason.cs b/MatrixRoomUtils.Core/UserIdAndReason.cs deleted file mode 100644 index 3801077..0000000 --- a/MatrixRoomUtils.Core/UserIdAndReason.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Text.Json.Serialization; - -namespace MatrixRoomUtils.Core; - -internal class UserIdAndReason { - [JsonPropertyName("user_id")] - public string UserId { get; set; } - [JsonPropertyName("reason")] - public string? Reason { get; set; } -} \ No newline at end of file diff --git a/MatrixRoomUtils.DebugDataValidationApi/Controllers/ValidationController.cs b/MatrixRoomUtils.DebugDataValidationApi/Controllers/ValidationController.cs deleted file mode 100644 index 949871a..0000000 --- a/MatrixRoomUtils.DebugDataValidationApi/Controllers/ValidationController.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Text.Json; -using MatrixRoomUtils.Core.Extensions; -using Microsoft.AspNetCore.Mvc; - -namespace MatrixRoomUtils.DebugDataValidationApi.Controllers; - -[ApiController] -[Route("/")] -public class ValidationController : ControllerBase { - private readonly ILogger<ValidationController> _logger; - - public ValidationController(ILogger<ValidationController> logger) { - _logger = logger; - } - - [HttpPost("/validate/{type}")] - public async Task<bool> Get([FromRoute] string type, [FromBody] JsonElement content) { - Type t = Type.GetType(type); - if (t is null) { - Console.WriteLine($"Type `{type}` does not exist!"); - throw new ArgumentException($"Unknown type {type}!"); - } - Console.WriteLine($"Validating {type}..."); - return content.FindExtraJsonElementFields(t, "$"); - } -} diff --git a/MatrixRoomUtils.DebugDataValidationApi/MatrixRoomUtils.DebugDataValidationApi.csproj b/MatrixRoomUtils.DebugDataValidationApi/MatrixRoomUtils.DebugDataValidationApi.csproj deleted file mode 100644 index 4c23207..0000000 --- a/MatrixRoomUtils.DebugDataValidationApi/MatrixRoomUtils.DebugDataValidationApi.csproj +++ /dev/null @@ -1,19 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk.Web"> - - <PropertyGroup> - <TargetFramework>net7.0</TargetFramework> - <Nullable>enable</Nullable> - <ImplicitUsings>enable</ImplicitUsings> - <InvariantGlobalization>true</InvariantGlobalization> - </PropertyGroup> - - <ItemGroup> - <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.9" /> - <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" /> - </ItemGroup> - - <ItemGroup> - <ProjectReference Include="..\MatrixRoomUtils.Core\MatrixRoomUtils.Core.csproj" /> - </ItemGroup> - -</Project> diff --git a/MatrixRoomUtils.DebugDataValidationApi/Program.cs b/MatrixRoomUtils.DebugDataValidationApi/Program.cs deleted file mode 100644 index 047dbcf..0000000 --- a/MatrixRoomUtils.DebugDataValidationApi/Program.cs +++ /dev/null @@ -1,32 +0,0 @@ -var builder = WebApplication.CreateBuilder(args); - -// Add services to the container. - -builder.Services.AddControllers(); -// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle -builder.Services.AddEndpointsApiExplorer(); -builder.Services.AddSwaggerGen(); -builder.Services.AddCors(options => -{ - options.AddPolicy( - "Open", - builder => builder.AllowAnyOrigin().AllowAnyHeader()); -}); - -var app = builder.Build(); - -// Configure the HTTP request pipeline. -if (app.Environment.IsDevelopment()) { - app.UseSwagger(); - app.UseSwaggerUI(); -} - -// app.UseHttpsRedirection(); - -app.UseCors("Open"); - -app.UseAuthorization(); - -app.MapControllers(); - -app.Run(); diff --git a/MatrixRoomUtils.DebugDataValidationApi/Properties/launchSettings.json b/MatrixRoomUtils.DebugDataValidationApi/Properties/launchSettings.json deleted file mode 100644 index c33e091..0000000 --- a/MatrixRoomUtils.DebugDataValidationApi/Properties/launchSettings.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/launchsettings.json", - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:63687", - "sslPort": 44316 - } - }, - "profiles": { - "http": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": false, - "launchUrl": "swagger", - "applicationUrl": "http://localhost:5116", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "https": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "launchUrl": "swagger", - "applicationUrl": "https://localhost:7017;http://localhost:5116", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "launchUrl": "swagger", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} diff --git a/MatrixRoomUtils.DebugDataValidationApi/appsettings.Development.json b/MatrixRoomUtils.DebugDataValidationApi/appsettings.Development.json deleted file mode 100644 index 12c8ab9..0000000 --- a/MatrixRoomUtils.DebugDataValidationApi/appsettings.Development.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Information", - "Microsoft.AspNetCore.Routing": "Warning", - "Microsoft.AspNetCore.Mvc": "Warning", - "Microsoft.AspNetCore.Cors": "Warning" - } - } -} diff --git a/MatrixRoomUtils.DebugDataValidationApi/appsettings.json b/MatrixRoomUtils.DebugDataValidationApi/appsettings.json deleted file mode 100644 index 10f68b8..0000000 --- a/MatrixRoomUtils.DebugDataValidationApi/appsettings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "AllowedHosts": "*" -} diff --git a/MatrixRoomUtils.Desktop/App.axaml.cs b/MatrixRoomUtils.Desktop/App.axaml.cs index 3fe8862..20f2a3c 100644 --- a/MatrixRoomUtils.Desktop/App.axaml.cs +++ b/MatrixRoomUtils.Desktop/App.axaml.cs @@ -1,7 +1,7 @@ using Avalonia; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; -using MatrixRoomUtils.Core.Services; +using LibMatrix.Services; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Sentry; diff --git a/MatrixRoomUtils.Desktop/Components/RoomListEntry.axaml.cs b/MatrixRoomUtils.Desktop/Components/RoomListEntry.axaml.cs index a447701..f29db63 100644 --- a/MatrixRoomUtils.Desktop/Components/RoomListEntry.axaml.cs +++ b/MatrixRoomUtils.Desktop/Components/RoomListEntry.axaml.cs @@ -1,10 +1,10 @@ using Avalonia.Controls; using Avalonia.Interactivity; using Avalonia.Media.Imaging; -using MatrixRoomUtils.Core; -using MatrixRoomUtils.Core.Helpers; -using MatrixRoomUtils.Core.Services; -using MatrixRoomUtils.Core.StateEventTypes.Spec; +using LibMatrix; +using LibMatrix.Helpers; +using LibMatrix.Services; +using LibMatrix.StateEventTypes.Spec; using MatrixRoomUtils.Web.Classes; using Microsoft.Extensions.DependencyInjection; diff --git a/MatrixRoomUtils.Desktop/FileStorageProvider.cs b/MatrixRoomUtils.Desktop/FileStorageProvider.cs index 6c44fd2..36a3c7e 100644 --- a/MatrixRoomUtils.Desktop/FileStorageProvider.cs +++ b/MatrixRoomUtils.Desktop/FileStorageProvider.cs @@ -1,6 +1,6 @@ using System.Text.Json; -using MatrixRoomUtils.Core.Extensions; -using MatrixRoomUtils.Core.Interfaces.Services; +using LibMatrix.Extensions; +using LibMatrix.Interfaces.Services; using Microsoft.Extensions.Logging; namespace MatrixRoomUtils.Desktop; diff --git a/MatrixRoomUtils.Desktop/MRUStorageWrapper.cs b/MatrixRoomUtils.Desktop/MRUStorageWrapper.cs index a5494ad..5444f24 100644 --- a/MatrixRoomUtils.Desktop/MRUStorageWrapper.cs +++ b/MatrixRoomUtils.Desktop/MRUStorageWrapper.cs @@ -1,6 +1,6 @@ -using MatrixRoomUtils.Core; -using MatrixRoomUtils.Core.Responses; -using MatrixRoomUtils.Core.Services; +using LibMatrix; +using LibMatrix.Responses; +using LibMatrix.Services; namespace MatrixRoomUtils.Desktop; diff --git a/MatrixRoomUtils.Desktop/MainWindow.axaml.cs b/MatrixRoomUtils.Desktop/MainWindow.axaml.cs index f89bbfa..89f9d52 100644 --- a/MatrixRoomUtils.Desktop/MainWindow.axaml.cs +++ b/MatrixRoomUtils.Desktop/MainWindow.axaml.cs @@ -25,8 +25,8 @@ public partial class MainWindow : Window { InitializeComponent(); - _logger.LogInformation("Cache location: " + _configuration.CacheStoragePath); - _logger.LogInformation("Data location: " + _configuration.DataStoragePath); + _logger.LogInformation("Cache location: {}", _configuration.CacheStoragePath); + _logger.LogInformation("Data location: {}", _configuration.DataStoragePath); // for (int i = 0; i < 100; i++) { @@ -40,7 +40,7 @@ public partial class MainWindow : Window { var hs = await _storageWrapper.GetCurrentSessionOrPrompt(); var rooms = await hs.GetJoinedRooms(); foreach (var room in rooms) { - roomList.Children.Add(new RoomListEntry(_scopeFactory, new RoomInfo(room))); + // roomList.Children.Add(new RoomListEntry(_scopeFactory, new RoomInfo(room))); } base.OnLoaded(e); } diff --git a/MatrixRoomUtils.Desktop/MatrixRoomUtils.Desktop.csproj b/MatrixRoomUtils.Desktop/MatrixRoomUtils.Desktop.csproj index 6f3e256..e6a8169 100644 --- a/MatrixRoomUtils.Desktop/MatrixRoomUtils.Desktop.csproj +++ b/MatrixRoomUtils.Desktop/MatrixRoomUtils.Desktop.csproj @@ -31,7 +31,7 @@ <ItemGroup> - <ProjectReference Include="..\MatrixRoomUtils.Core\MatrixRoomUtils.Core.csproj" /> + <ProjectReference Include="..\LibMatrix\LibMatrix\LibMatrix.csproj" /> </ItemGroup> <ItemGroup> diff --git a/MatrixRoomUtils.Desktop/RoomInfo.cs b/MatrixRoomUtils.Desktop/RoomInfo.cs index a31d67a..fdd7d03 100644 --- a/MatrixRoomUtils.Desktop/RoomInfo.cs +++ b/MatrixRoomUtils.Desktop/RoomInfo.cs @@ -1,7 +1,6 @@ -using MatrixRoomUtils.Core; -using MatrixRoomUtils.Core.Interfaces; -using MatrixRoomUtils.Core.Responses; -using MatrixRoomUtils.Core.RoomTypes; +using LibMatrix; +using LibMatrix.Responses; +using LibMatrix.RoomTypes; namespace MatrixRoomUtils.Web.Classes; diff --git a/MatrixRoomUtils.Web/Classes/LocalStorageProviderService.cs b/MatrixRoomUtils.Web/Classes/LocalStorageProviderService.cs index 256c43d..02d691a 100644 --- a/MatrixRoomUtils.Web/Classes/LocalStorageProviderService.cs +++ b/MatrixRoomUtils.Web/Classes/LocalStorageProviderService.cs @@ -1,7 +1,7 @@ using Blazored.LocalStorage; -using MatrixRoomUtils.Core.Interfaces.Services; +using LibMatrix.Interfaces.Services; -namespace MatrixRoomUtils.Web.Classes; +namespace MatrixRoomUtils.Web.Classes; public class LocalStorageProviderService : IStorageProvider { private readonly ILocalStorageService _localStorageService; @@ -23,4 +23,4 @@ public class LocalStorageProviderService : IStorageProvider { async Task<List<string>> IStorageProvider.GetAllKeysAsync() => (await _localStorageService.KeysAsync()).ToList(); async Task IStorageProvider.DeleteObjectAsync(string key) => await _localStorageService.RemoveItemAsync(key); -} \ No newline at end of file +} diff --git a/MatrixRoomUtils.Web/Classes/MRUStorageWrapper.cs b/MatrixRoomUtils.Web/Classes/MRUStorageWrapper.cs index d4b256b..e9d56b9 100644 --- a/MatrixRoomUtils.Web/Classes/MRUStorageWrapper.cs +++ b/MatrixRoomUtils.Web/Classes/MRUStorageWrapper.cs @@ -1,6 +1,6 @@ -using MatrixRoomUtils.Core; -using MatrixRoomUtils.Core.Responses; -using MatrixRoomUtils.Core.Services; +using LibMatrix; +using LibMatrix.Responses; +using LibMatrix.Services; using Microsoft.AspNetCore.Components; namespace MatrixRoomUtils.Web.Classes; diff --git a/MatrixRoomUtils.Web/Classes/RoomCreationTemplates/DefaultRoomCreationTemplate.cs b/MatrixRoomUtils.Web/Classes/RoomCreationTemplates/DefaultRoomCreationTemplate.cs index f895173..b6f6d56 100644 --- a/MatrixRoomUtils.Web/Classes/RoomCreationTemplates/DefaultRoomCreationTemplate.cs +++ b/MatrixRoomUtils.Web/Classes/RoomCreationTemplates/DefaultRoomCreationTemplate.cs @@ -1,8 +1,8 @@ using System.Text.Json.Nodes; -using MatrixRoomUtils.Core; -using MatrixRoomUtils.Core.Responses; -using MatrixRoomUtils.Core.StateEventTypes; -using MatrixRoomUtils.Core.StateEventTypes.Spec; +using LibMatrix; +using LibMatrix.Responses; +using LibMatrix.StateEventTypes.Spec; +using LibMatrix.StateEventTypes; namespace MatrixRoomUtils.Web.Classes.RoomCreationTemplates; @@ -89,4 +89,4 @@ public class DefaultRoomCreationTemplate : IRoomCreationTemplate { } } }; -} \ No newline at end of file +} diff --git a/MatrixRoomUtils.Web/Classes/RoomCreationTemplates/IRoomCreationTemplate.cs b/MatrixRoomUtils.Web/Classes/RoomCreationTemplates/IRoomCreationTemplate.cs index bbb09b7..42503f7 100644 --- a/MatrixRoomUtils.Web/Classes/RoomCreationTemplates/IRoomCreationTemplate.cs +++ b/MatrixRoomUtils.Web/Classes/RoomCreationTemplates/IRoomCreationTemplate.cs @@ -1,8 +1,8 @@ -using MatrixRoomUtils.Core.Responses; +using LibMatrix.Responses; namespace MatrixRoomUtils.Web.Classes.RoomCreationTemplates; public interface IRoomCreationTemplate { public CreateRoomRequest CreateRoomRequest { get; } public string Name { get; } -} \ No newline at end of file +} diff --git a/MatrixRoomUtils.Web/Classes/RoomInfo.cs b/MatrixRoomUtils.Web/Classes/RoomInfo.cs index f9d5452..4df81ec 100644 --- a/MatrixRoomUtils.Web/Classes/RoomInfo.cs +++ b/MatrixRoomUtils.Web/Classes/RoomInfo.cs @@ -1,7 +1,6 @@ -using MatrixRoomUtils.Core; -using MatrixRoomUtils.Core.Interfaces; -using MatrixRoomUtils.Core.Responses; -using MatrixRoomUtils.Core.RoomTypes; +using LibMatrix; +using LibMatrix.Responses; +using LibMatrix.RoomTypes; namespace MatrixRoomUtils.Web.Classes; diff --git a/MatrixRoomUtils.Web/Classes/SessionStorageProviderService.cs b/MatrixRoomUtils.Web/Classes/SessionStorageProviderService.cs index e497ee3..6f11cad 100644 --- a/MatrixRoomUtils.Web/Classes/SessionStorageProviderService.cs +++ b/MatrixRoomUtils.Web/Classes/SessionStorageProviderService.cs @@ -1,7 +1,7 @@ using Blazored.SessionStorage; -using MatrixRoomUtils.Core.Interfaces.Services; +using LibMatrix.Interfaces.Services; -namespace MatrixRoomUtils.Web.Classes; +namespace MatrixRoomUtils.Web.Classes; public class SessionStorageProviderService : IStorageProvider { private readonly ISessionStorageService _sessionStorageService; @@ -9,7 +9,7 @@ public class SessionStorageProviderService : IStorageProvider { public SessionStorageProviderService(ISessionStorageService sessionStorage) { _sessionStorageService = sessionStorage; } - + async Task IStorageProvider.SaveAllChildrenAsync<T>(string key, T value) => throw new NotImplementedException(); async Task<T?> IStorageProvider.LoadAllChildrenAsync<T>(string key) where T : default => throw new NotImplementedException(); @@ -23,4 +23,4 @@ public class SessionStorageProviderService : IStorageProvider { async Task<List<string>> IStorageProvider.GetAllKeysAsync() => (await _sessionStorageService.KeysAsync()).ToList(); async Task IStorageProvider.DeleteObjectAsync(string key) => await _sessionStorageService.RemoveItemAsync(key); -} \ No newline at end of file +} diff --git a/MatrixRoomUtils.Web/MatrixRoomUtils.Web.csproj b/MatrixRoomUtils.Web/MatrixRoomUtils.Web.csproj index 4b874c9..e6580e9 100644 --- a/MatrixRoomUtils.Web/MatrixRoomUtils.Web.csproj +++ b/MatrixRoomUtils.Web/MatrixRoomUtils.Web.csproj @@ -14,7 +14,7 @@ </ItemGroup> <ItemGroup> - <ProjectReference Include="..\MatrixRoomUtils.Core\MatrixRoomUtils.Core.csproj" /> + <ProjectReference Include="..\LibMatrix\LibMatrix\LibMatrix.csproj" /> </ItemGroup> </Project> diff --git a/MatrixRoomUtils.Web/Pages/DebugTools.razor b/MatrixRoomUtils.Web/Pages/DebugTools.razor index 5116754..afb1da2 100644 --- a/MatrixRoomUtils.Web/Pages/DebugTools.razor +++ b/MatrixRoomUtils.Web/Pages/DebugTools.razor @@ -1,6 +1,7 @@ @page "/Debug" @using System.Reflection -@using MatrixRoomUtils.Core.Interfaces +@using LibMatrix.Extensions +@using LibMatrix.Interfaces @inject ILocalStorageService LocalStorage @inject NavigationManager NavigationManager <h3>Debug Tools</h3> @@ -74,4 +75,4 @@ else { StateHasChanged(); } -} \ No newline at end of file +} diff --git a/MatrixRoomUtils.Web/Pages/DevOptions.razor b/MatrixRoomUtils.Web/Pages/DevOptions.razor index 70dac31..bf499a3 100644 --- a/MatrixRoomUtils.Web/Pages/DevOptions.razor +++ b/MatrixRoomUtils.Web/Pages/DevOptions.razor @@ -1,4 +1,5 @@ @page "/DevOptions" +@using LibMatrix.Extensions @inject NavigationManager NavigationManager @inject ILocalStorageService LocalStorage @@ -26,4 +27,4 @@ await TieredStorage.DataStorageProvider.SaveObjectAsync("mru.settings", settings); } -} \ No newline at end of file +} diff --git a/MatrixRoomUtils.Web/Pages/HSAdmin/RoomQuery.razor b/MatrixRoomUtils.Web/Pages/HSAdmin/RoomQuery.razor index e3ebc72..b2928ee 100644 --- a/MatrixRoomUtils.Web/Pages/HSAdmin/RoomQuery.razor +++ b/MatrixRoomUtils.Web/Pages/HSAdmin/RoomQuery.razor @@ -1,7 +1,8 @@ @page "/HSAdmin/RoomQuery" -@using MatrixRoomUtils.Core.Filters -@using MatrixRoomUtils.Core.Responses.Admin @using MatrixRoomUtils.Web.Shared.SimpleComponents +@using LibMatrix.Responses.Admin +@using LibMatrix.Filters +@using LibMatrix.Extensions <h3>Homeserver Administration - Room Query</h3> @@ -121,7 +122,7 @@ .tile150 { min-width: 150px; } - .range-sep { + .range-sep { display: inline-block; padding: 4px; width: 150px; @@ -193,4 +194,4 @@ { "state_events", "Number of state events" } }; -} \ No newline at end of file +} diff --git a/MatrixRoomUtils.Web/Pages/Index.razor b/MatrixRoomUtils.Web/Pages/Index.razor index 01e2be4..65ba68b 100644 --- a/MatrixRoomUtils.Web/Pages/Index.razor +++ b/MatrixRoomUtils.Web/Pages/Index.razor @@ -1,7 +1,8 @@ @page "/" -@using MatrixRoomUtils.Core.Helpers -@using MatrixRoomUtils.Core.Responses @using MatrixRoomUtils.Web.Shared.SimpleComponents +@using LibMatrix.Responses +@using LibMatrix +@using LibMatrix.Helpers <PageTitle>Index</PageTitle> diff --git a/MatrixRoomUtils.Web/Pages/InvalidSession.razor b/MatrixRoomUtils.Web/Pages/InvalidSession.razor index 3bcd797..2b030ce 100644 --- a/MatrixRoomUtils.Web/Pages/InvalidSession.razor +++ b/MatrixRoomUtils.Web/Pages/InvalidSession.razor @@ -1,7 +1,7 @@ @page "/InvalidSession" -@using MatrixRoomUtils.Core.Helpers -@using MatrixRoomUtils.Core.Responses @using MatrixRoomUtils.Web.Shared.SimpleComponents +@using LibMatrix.Responses +@using LibMatrix <PageTitle>Invalid session</PageTitle> diff --git a/MatrixRoomUtils.Web/Pages/KnownHomeserverList.razor b/MatrixRoomUtils.Web/Pages/KnownHomeserverList.razor index 5ccecab..10a2929 100644 --- a/MatrixRoomUtils.Web/Pages/KnownHomeserverList.razor +++ b/MatrixRoomUtils.Web/Pages/KnownHomeserverList.razor @@ -1,8 +1,10 @@ @page "/KnownHomeserverList" @using System.Text.Json @using System.Diagnostics -@using MatrixRoomUtils.Core.Responses -@using MatrixRoomUtils.Core.StateEventTypes +@using LibMatrix +@using LibMatrix.Extensions +@using LibMatrix.RoomTypes +@using LibMatrix.StateEventTypes <h3>Known Homeserver List</h3> <hr/> @@ -62,7 +64,7 @@ else { private async Task<List<HomeServerInfo>> GetHomeservers(int memberLimit = 1000, Func<HomeServerInfoQueryProgress, Task<bool>>? progressCallback = null) { HomeServerInfoQueryProgress progress = new(); List<HomeServerInfo> homeServers = new(); - + var rooms = await hs.GetJoinedRooms(); progress.TotalRooms = rooms.Count; @@ -168,4 +170,4 @@ else { } } -} \ No newline at end of file +} diff --git a/MatrixRoomUtils.Web/Pages/LoginPage.razor b/MatrixRoomUtils.Web/Pages/LoginPage.razor index e19dd04..9730cbe 100644 --- a/MatrixRoomUtils.Web/Pages/LoginPage.razor +++ b/MatrixRoomUtils.Web/Pages/LoginPage.razor @@ -1,6 +1,6 @@ @page "/Login" @using System.Text.Json -@using MatrixRoomUtils.Core.Responses +@using LibMatrix.Responses @using MatrixRoomUtils.Web.Shared.SimpleComponents @inject ILocalStorageService LocalStorage @inject IJSRuntime JsRuntime @@ -49,7 +49,7 @@ (string homeserver, string username, string password) newRecordInput = ("", "", ""); List<LoginResponse> LoggedInSessions { get; set; } = new(); - + async Task Login() { var loginTasks = records.Select(async record => { var (homeserver, username, password) = record; @@ -97,4 +97,4 @@ newRecordInput = ("", "", ""); } -} \ No newline at end of file +} diff --git a/MatrixRoomUtils.Web/Pages/MediaLocator.razor b/MatrixRoomUtils.Web/Pages/MediaLocator.razor index 6221041..8c41440 100644 --- a/MatrixRoomUtils.Web/Pages/MediaLocator.razor +++ b/MatrixRoomUtils.Web/Pages/MediaLocator.razor @@ -1,4 +1,5 @@ @page "/MediaLocator" +@using LibMatrix @inject HttpClient Http <h3>Media locator</h3> <hr/> @@ -106,4 +107,4 @@ StateHasChanged(); } -} \ No newline at end of file +} diff --git a/MatrixRoomUtils.Web/Pages/Rooms/Create.razor b/MatrixRoomUtils.Web/Pages/Rooms/Create.razor index 3a98801..ebf6444 100644 --- a/MatrixRoomUtils.Web/Pages/Rooms/Create.razor +++ b/MatrixRoomUtils.Web/Pages/Rooms/Create.razor @@ -1,10 +1,12 @@ @page "/Rooms/Create" -@using MatrixRoomUtils.Core.Responses @using System.Text.Json @using System.Reflection -@using MatrixRoomUtils.Core.Helpers -@using MatrixRoomUtils.Core.StateEventTypes -@using MatrixRoomUtils.Core.StateEventTypes.Spec +@using LibMatrix +@using LibMatrix.Extensions +@using LibMatrix.Helpers +@using LibMatrix.Responses +@using LibMatrix.StateEventTypes.Spec +@using LibMatrix.StateEventTypes @using MatrixRoomUtils.Web.Classes.RoomCreationTemplates @* @* ReSharper disable once RedundantUsingDirective - Must not remove this, Rider marks this as "unused" when it's not */ *@ @using MatrixRoomUtils.Web.Shared.SimpleComponents diff --git a/MatrixRoomUtils.Web/Pages/Rooms/Index.razor b/MatrixRoomUtils.Web/Pages/Rooms/Index.razor index 6d12dc2..89ededf 100644 --- a/MatrixRoomUtils.Web/Pages/Rooms/Index.razor +++ b/MatrixRoomUtils.Web/Pages/Rooms/Index.razor @@ -1,9 +1,9 @@ @page "/Rooms" -@using MatrixRoomUtils.Core.StateEventTypes -@using MatrixRoomUtils.Core.StateEventTypes.Spec -@using MatrixRoomUtils.Core.Filters -@using MatrixRoomUtils.Core.Helpers -@using MatrixRoomUtils.Core.Responses +@using LibMatrix.StateEventTypes +@using LibMatrix.StateEventTypes.Spec +@using LibMatrix.Filters +@using LibMatrix.Helpers +@using LibMatrix.Responses <h3>Room list</h3> <p>@Status</p> @if (RenderContents) { diff --git a/MatrixRoomUtils.Web/Pages/Rooms/PolicyList.razor b/MatrixRoomUtils.Web/Pages/Rooms/PolicyList.razor index cd4788b..3297bcb 100644 --- a/MatrixRoomUtils.Web/Pages/Rooms/PolicyList.razor +++ b/MatrixRoomUtils.Web/Pages/Rooms/PolicyList.razor @@ -1,9 +1,11 @@ @page "/Rooms/{RoomId}/Policies" -@using MatrixRoomUtils.Core.StateEventTypes +@using LibMatrix.StateEventTypes @using System.Text.Json -@using MatrixRoomUtils.Core.Helpers -@using MatrixRoomUtils.Core.Responses -@using MatrixRoomUtils.Core.StateEventTypes.Spec +@using LibMatrix +@using LibMatrix.Extensions +@using LibMatrix.Helpers +@using LibMatrix.Responses +@using LibMatrix.StateEventTypes.Spec <h3>Policy list editor - Editing @RoomId</h3> <hr/> diff --git a/MatrixRoomUtils.Web/Pages/Rooms/Space.razor b/MatrixRoomUtils.Web/Pages/Rooms/Space.razor index 91f97d0..15c7c70 100644 --- a/MatrixRoomUtils.Web/Pages/Rooms/Space.razor +++ b/MatrixRoomUtils.Web/Pages/Rooms/Space.razor @@ -1,6 +1,8 @@ @page "/Rooms/{RoomId}/Space" @using System.Text.Json -@using MatrixRoomUtils.Core.Responses +@using LibMatrix.Extensions +@using LibMatrix.Responses +@using LibMatrix.RoomTypes <h3>Room manager - Viewing Space</h3> <button onclick="@JoinAllRooms">Join all rooms</button> diff --git a/MatrixRoomUtils.Web/Pages/Rooms/StateEditor.razor b/MatrixRoomUtils.Web/Pages/Rooms/StateEditor.razor index 8b2ff0c..e01fca8 100644 --- a/MatrixRoomUtils.Web/Pages/Rooms/StateEditor.razor +++ b/MatrixRoomUtils.Web/Pages/Rooms/StateEditor.razor @@ -1,7 +1,8 @@ @page "/Rooms/{RoomId}/State/Edit" @using System.Net.Http.Headers @using System.Text.Json -@using MatrixRoomUtils.Core.Responses +@using LibMatrix.Extensions +@using LibMatrix.Responses @inject ILocalStorageService LocalStorage @inject NavigationManager NavigationManager <h3>Room state editor - Editing @RoomId</h3> @@ -142,4 +143,4 @@ } private string shownEventJson { get; set; } -} \ No newline at end of file +} diff --git a/MatrixRoomUtils.Web/Pages/Rooms/StateViewer.razor b/MatrixRoomUtils.Web/Pages/Rooms/StateViewer.razor index 09b38f0..cf23c36 100644 --- a/MatrixRoomUtils.Web/Pages/Rooms/StateViewer.razor +++ b/MatrixRoomUtils.Web/Pages/Rooms/StateViewer.razor @@ -1,7 +1,8 @@ @page "/Rooms/{RoomId}/State/View" @using System.Net.Http.Headers @using System.Text.Json -@using MatrixRoomUtils.Core.Responses +@using LibMatrix.Extensions +@using LibMatrix.Responses @inject ILocalStorageService LocalStorage @inject NavigationManager NavigationManager <h3>Room state viewer - Viewing @RoomId</h3> @@ -125,4 +126,4 @@ } private bool _showMembershipEvents; -} \ No newline at end of file +} diff --git a/MatrixRoomUtils.Web/Pages/Rooms/Timeline.razor b/MatrixRoomUtils.Web/Pages/Rooms/Timeline.razor index 2234dd9..7fe89cc 100644 --- a/MatrixRoomUtils.Web/Pages/Rooms/Timeline.razor +++ b/MatrixRoomUtils.Web/Pages/Rooms/Timeline.razor @@ -1,7 +1,8 @@ @page "/Rooms/{RoomId}/Timeline" @using MatrixRoomUtils.Web.Shared.TimelineComponents -@using MatrixRoomUtils.Core.Responses -@using MatrixRoomUtils.Core.StateEventTypes.Spec +@using LibMatrix +@using LibMatrix.Responses +@using LibMatrix.StateEventTypes.Spec <h3>RoomManagerTimeline</h3> <hr/> <p>Loaded @Events.Count events...</p> diff --git a/MatrixRoomUtils.Web/Program.cs b/MatrixRoomUtils.Web/Program.cs index 54d4f0d..c760108 100644 --- a/MatrixRoomUtils.Web/Program.cs +++ b/MatrixRoomUtils.Web/Program.cs @@ -2,7 +2,7 @@ using System.Text.Json; using System.Text.Json.Serialization; using Blazored.LocalStorage; using Blazored.SessionStorage; -using MatrixRoomUtils.Core.Services; +using LibMatrix.Services; using MatrixRoomUtils.Web; using MatrixRoomUtils.Web.Classes; using Microsoft.AspNetCore.Components.Web; @@ -41,4 +41,4 @@ builder.Services.AddScoped<TieredStorageService>(x => builder.Services.AddRoryLibMatrixServices(); builder.Services.AddScoped<MRUStorageWrapper>(); -await builder.Build().RunAsync(); \ No newline at end of file +await builder.Build().RunAsync(); diff --git a/MatrixRoomUtils.Web/Shared/InlineUserItem.razor b/MatrixRoomUtils.Web/Shared/InlineUserItem.razor index 25db838..f3a7162 100644 --- a/MatrixRoomUtils.Web/Shared/InlineUserItem.razor +++ b/MatrixRoomUtils.Web/Shared/InlineUserItem.razor @@ -1,7 +1,7 @@ -@using MatrixRoomUtils.Core.Responses -@using MatrixRoomUtils.Core.StateEventTypes -@using MatrixRoomUtils.Core.Helpers -@using MatrixRoomUtils.Core.StateEventTypes.Spec +@using LibMatrix.StateEventTypes +@using LibMatrix.StateEventTypes.Spec +@using LibMatrix +@using LibMatrix.Helpers <div style="background-color: #ffffff11; border-radius: 0.5em; height: 1em; display: inline-block; vertical-align: middle;" alt="@UserId"> <img style="@(ChildContent is not null ? "vertical-align: baseline;" : "vertical-align: top;") width: 1em; height: 1em; border-radius: 50%;" src="@ProfileAvatar"/> <span style="position: relative; top: -5px;">@ProfileName</span> diff --git a/MatrixRoomUtils.Web/Shared/ModalWindow.razor b/MatrixRoomUtils.Web/Shared/ModalWindow.razor index b40d246..2f001e1 100644 --- a/MatrixRoomUtils.Web/Shared/ModalWindow.razor +++ b/MatrixRoomUtils.Web/Shared/ModalWindow.razor @@ -1,3 +1,4 @@ +@using LibMatrix.Extensions <div class="r-modal" style="top: @(_y)px; left: @(_x)px;"> <div class="titlebar" @onmousedown="MouseDown" @onmouseup="MouseUp" @onmousemove="MouseMove" @onmouseleave="MouseMove"> <b class="title" @ref="_titleRef">@Title</b> diff --git a/MatrixRoomUtils.Web/Shared/RoomList.razor b/MatrixRoomUtils.Web/Shared/RoomList.razor index e3894a6..dc06d90 100644 --- a/MatrixRoomUtils.Web/Shared/RoomList.razor +++ b/MatrixRoomUtils.Web/Shared/RoomList.razor @@ -1,7 +1,8 @@ @using MatrixRoomUtils.Web.Shared.RoomListComponents; -@using MatrixRoomUtils.Core.StateEventTypes -@using MatrixRoomUtils.Core.StateEventTypes.Common -@using MatrixRoomUtils.Core.StateEventTypes.Spec +@using LibMatrix.StateEventTypes +@using LibMatrix.StateEventTypes.Spec +@using LibMatrix +@using LibMatrix.Extensions @if(Rooms.Count != RoomsWithTypes.Sum(x=>x.Value.Count)) { <p>Fetching room details... @RoomsWithTypes.Sum(x=>x.Value.Count) out of @Rooms.Count done!</p> @foreach (var category in RoomsWithTypes.OrderBy(x => x.Value.Count)) { diff --git a/MatrixRoomUtils.Web/Shared/RoomListComponents/RoomListCategory.razor b/MatrixRoomUtils.Web/Shared/RoomListComponents/RoomListCategory.razor index b798d49..c04df3f 100644 --- a/MatrixRoomUtils.Web/Shared/RoomListComponents/RoomListCategory.razor +++ b/MatrixRoomUtils.Web/Shared/RoomListComponents/RoomListCategory.razor @@ -1,6 +1,7 @@ -@using MatrixRoomUtils.Core.StateEventTypes -@using MatrixRoomUtils.Core.StateEventTypes.Spec +@using LibMatrix.StateEventTypes @using MatrixRoomUtils.Web.Classes.Constants +@using LibMatrix.StateEventTypes.Spec +@using LibMatrix <details> <summary>@roomType (@rooms.Count)</summary> @foreach (var room in rooms) { diff --git a/MatrixRoomUtils.Web/Shared/RoomListComponents/RoomListPolicyRoom.razor b/MatrixRoomUtils.Web/Shared/RoomListComponents/RoomListPolicyRoom.razor index f05ac7b..7afdc8c 100644 --- a/MatrixRoomUtils.Web/Shared/RoomListComponents/RoomListPolicyRoom.razor +++ b/MatrixRoomUtils.Web/Shared/RoomListComponents/RoomListPolicyRoom.razor @@ -1,3 +1,4 @@ +@using LibMatrix.RoomTypes <LinkButton href="@($"/Rooms/{Room.RoomId}/Policies")">Manage policies</LinkButton> @code { @@ -9,4 +10,4 @@ await base.OnInitializedAsync(); } -} \ No newline at end of file +} diff --git a/MatrixRoomUtils.Web/Shared/RoomListItem.razor b/MatrixRoomUtils.Web/Shared/RoomListItem.razor index e12f622..6e3adc6 100644 --- a/MatrixRoomUtils.Web/Shared/RoomListItem.razor +++ b/MatrixRoomUtils.Web/Shared/RoomListItem.razor @@ -1,8 +1,9 @@ -@using MatrixRoomUtils.Core.Extensions @using System.Text.Json -@using MatrixRoomUtils.Core.Helpers -@using MatrixRoomUtils.Core.StateEventTypes -@using MatrixRoomUtils.Core.StateEventTypes.Spec +@using LibMatrix +@using LibMatrix.Helpers +@using LibMatrix.RoomTypes +@using LibMatrix.StateEventTypes.Spec +@using LibMatrix.StateEventTypes @using MatrixRoomUtils.Web.Classes.Constants <div class="roomListItem" id="@RoomId" style="background-color: #ffffff11; border-radius: 25px; margin: 8px; width: fit-Content; @(hasDangerousRoomVersion ? "border: red 4px solid;" : hasOldRoomVersion ? "border: #FF0 1px solid;" : "")"> @if (OwnMemberState != null) { diff --git a/MatrixRoomUtils.Web/Shared/SimpleComponents/DictionaryEditor.razor b/MatrixRoomUtils.Web/Shared/SimpleComponents/DictionaryEditor.razor index ea7d2ec..afd1fdc 100644 --- a/MatrixRoomUtils.Web/Shared/SimpleComponents/DictionaryEditor.razor +++ b/MatrixRoomUtils.Web/Shared/SimpleComponents/DictionaryEditor.razor @@ -1,3 +1,4 @@ +@using LibMatrix.Extensions <table> @foreach (var i in Items.Keys) { var key = i; @@ -34,4 +35,4 @@ ItemsChanged.InvokeAsync(); } -} \ No newline at end of file +} diff --git a/MatrixRoomUtils.Web/Shared/TimelineComponents/BaseTimelineItem.razor b/MatrixRoomUtils.Web/Shared/TimelineComponents/BaseTimelineItem.razor index 920a38d..5172fa4 100644 --- a/MatrixRoomUtils.Web/Shared/TimelineComponents/BaseTimelineItem.razor +++ b/MatrixRoomUtils.Web/Shared/TimelineComponents/BaseTimelineItem.razor @@ -1,4 +1,5 @@ -@using MatrixRoomUtils.Core.Responses +@using LibMatrix.Responses +@using LibMatrix <h3>BaseTimelineItem</h3> @code { diff --git a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineMemberItem.razor b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineMemberItem.razor index 44eb06e..8239367 100644 --- a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineMemberItem.razor +++ b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineMemberItem.razor @@ -1,6 +1,6 @@ -@using MatrixRoomUtils.Core.Responses -@using MatrixRoomUtils.Core.StateEventTypes -@using MatrixRoomUtils.Core.StateEventTypes.Spec +@using LibMatrix.StateEventTypes +@using LibMatrix.StateEventTypes.Spec +@using LibMatrix.Extensions @inherits BaseTimelineItem @if (roomMemberData is not null) { diff --git a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineMessageItem.razor b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineMessageItem.razor index bf0e083..411b750 100644 --- a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineMessageItem.razor +++ b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineMessageItem.razor @@ -1,4 +1,4 @@ -@using MatrixRoomUtils.Core.Responses +@using LibMatrix.Extensions @inherits BaseTimelineItem <pre> diff --git a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineRoomCreateItem.razor b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineRoomCreateItem.razor index de204a3..b20cc1a 100644 --- a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineRoomCreateItem.razor +++ b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineRoomCreateItem.razor @@ -1,5 +1,5 @@ -@using MatrixRoomUtils.Core.Responses -@using MatrixRoomUtils.Core.StateEventTypes.Spec +@using LibMatrix.StateEventTypes.Spec +@using LibMatrix.Extensions @inherits BaseTimelineItem <p> diff --git a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineUnknownItem.razor b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineUnknownItem.razor index d0871c3..8166f8a 100644 --- a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineUnknownItem.razor +++ b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineUnknownItem.razor @@ -1,3 +1,4 @@ +@using LibMatrix.Extensions @inherits BaseTimelineItem <div> diff --git a/MatrixRoomUtils.Web/Shared/UserListItem.razor b/MatrixRoomUtils.Web/Shared/UserListItem.razor index 20b1c8c..a85a68d 100644 --- a/MatrixRoomUtils.Web/Shared/UserListItem.razor +++ b/MatrixRoomUtils.Web/Shared/UserListItem.razor @@ -1,7 +1,6 @@ -@using MatrixRoomUtils.Core.Responses -@using MatrixRoomUtils.Core.StateEventTypes -@using MatrixRoomUtils.Core.Helpers -@using MatrixRoomUtils.Core.StateEventTypes.Spec +@using LibMatrix.StateEventTypes +@using LibMatrix.StateEventTypes.Spec +@using LibMatrix.Helpers <div style="background-color: #ffffff11; border-radius: 25px; margin: 8px; width: fit-Content;"> <img style="@(ChildContent is not null ? "vertical-align: baseline;" : "") width: 32px; height: 32px; border-radius: 50%;" src="@profileAvatar"/> <span style="vertical-align: middle; margin-right: 8px; border-radius: 75px;">@profileName</span> @@ -35,7 +34,7 @@ var hs = await MRUStorage.GetCurrentSessionOrNavigate(); if (hs is null) return; - + await _semaphoreSlim.WaitAsync(); if (User == null) { @@ -52,4 +51,4 @@ _semaphoreSlim.Release(); } -} \ No newline at end of file +} diff --git a/MatrixRoomUtils.Web/_Imports.razor b/MatrixRoomUtils.Web/_Imports.razor index b1d9212..cb08515 100644 --- a/MatrixRoomUtils.Web/_Imports.razor +++ b/MatrixRoomUtils.Web/_Imports.razor @@ -1,7 +1,7 @@ @using System.Net.Http @using System.Net.Http.Json @using Blazored.LocalStorage -@using MatrixRoomUtils.Core +@using LibMatrix.Services @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web @@ -11,9 +11,6 @@ @using MatrixRoomUtils.Web @using MatrixRoomUtils.Web.Classes @using MatrixRoomUtils.Web.Shared -@using MatrixRoomUtils.Core.RoomTypes -@using MatrixRoomUtils.Core.Extensions -@using MatrixRoomUtils.Core.Services @using LinkButton = MatrixRoomUtils.Web.Shared.SimpleComponents.LinkButton diff --git a/MatrixRoomUtils.Web/deps.nix b/MatrixRoomUtils.Web/deps.nix new file mode 100644 index 0000000..f300724 --- /dev/null +++ b/MatrixRoomUtils.Web/deps.nix @@ -0,0 +1,49 @@ +{ fetchNuGet }: [ + (fetchNuGet { pname = "Blazored.LocalStorage"; version = "4.3.0"; sha256 = "086zf61frl1rhvppgns0lf9vjacx71z1qc8s4br8x22987ggzbj1"; }) + (fetchNuGet { pname = "Blazored.SessionStorage"; version = "2.3.0"; sha256 = "1fw7pmsf63cqkxpymgxbm4lvvp3770rza2ag968vrcm723jpbw29"; }) + (fetchNuGet { pname = "Microsoft.AspNetCore.App.Runtime.linux-x64"; version = "7.0.8"; sha256 = "1w4x1spgb4x57qn3d1m9a3gyqnwwfk952kaxg8bqrki20a7qkhl4"; }) + (fetchNuGet { pname = "Microsoft.AspNetCore.Authorization"; version = "7.0.0"; sha256 = "17q08sk2sfd68yb9iw1i6wkpk85ac8rj9ifrsb38psr44xs7060r"; }) + (fetchNuGet { pname = "Microsoft.AspNetCore.Authorization"; version = "7.0.1"; sha256 = "0258g82vi5hnhicmdzkq75gdiwb0f5hlf7a75592hdcx23n7pjfx"; }) + (fetchNuGet { pname = "Microsoft.AspNetCore.Authorization"; version = "7.0.7"; sha256 = "014mqxfic81hzacr1inigzwcl3ij03dzd7x1r1cvmjjw5br31yi1"; }) + (fetchNuGet { pname = "Microsoft.AspNetCore.Components"; version = "7.0.0"; sha256 = "01r1wnzmgfmk21rq8w03i7n9rs4fqipki9f6m6qchp5acdi76kx2"; }) + (fetchNuGet { pname = "Microsoft.AspNetCore.Components"; version = "7.0.1"; sha256 = "0y26ghy62qcqn3346dijppdhb8ipvlgg7sxscbpqsccs2607w97r"; }) + (fetchNuGet { pname = "Microsoft.AspNetCore.Components"; version = "7.0.7"; sha256 = "0mggzxclxzk3ap73r2pilhq9gibjcw6zk2nkm0d6swflcsbaa2d8"; }) + (fetchNuGet { pname = "Microsoft.AspNetCore.Components.Analyzers"; version = "7.0.0"; sha256 = "1b9cm4wz7h021al9ywpq3jijwh53hcqkf7q2410mwx1l5iibcam9"; }) + (fetchNuGet { pname = "Microsoft.AspNetCore.Components.Analyzers"; version = "7.0.1"; sha256 = "17f7d2v2akz3d7zihlabjrd3viciilfj5qin9xqk4rzw8qqi2s6x"; }) + (fetchNuGet { pname = "Microsoft.AspNetCore.Components.Analyzers"; version = "7.0.7"; sha256 = "0w14sv0rvwlghsgyyh2mbr37mi5azg9s84g1bpr8zwvwqdp9xkmk"; }) + (fetchNuGet { pname = "Microsoft.AspNetCore.Components.Forms"; version = "7.0.0"; sha256 = "0szkcvkdpxrvldx9dzpnyrfgz9sjrl0am6p61z6da4aafrafzys1"; }) + (fetchNuGet { pname = "Microsoft.AspNetCore.Components.Forms"; version = "7.0.1"; sha256 = "0x6mpaqlrcv2c6gs4arm2smy2c9q9m95jyc20i216hfrigym5vbs"; }) + (fetchNuGet { pname = "Microsoft.AspNetCore.Components.Forms"; version = "7.0.7"; sha256 = "18g7v868113hh0nkljwsxbpdhiz1d1a8zz305cmnzhhwpqyqfn59"; }) + (fetchNuGet { pname = "Microsoft.AspNetCore.Components.Web"; version = "7.0.0"; sha256 = "1w3ph80prpx5sb130mkl3zlgspvdhwygljhf3yjxnay2dd05rw0k"; }) + (fetchNuGet { pname = "Microsoft.AspNetCore.Components.Web"; version = "7.0.1"; sha256 = "1izj62mfn4p98jhjvcr0mhvqyvigpf18hkamm202a2r11j6mvlkq"; }) + (fetchNuGet { pname = "Microsoft.AspNetCore.Components.Web"; version = "7.0.7"; sha256 = "06l07l371ap8jl0nyv2w1yjsvpasqvvxdpc3bk3vlxbqa3gyaq9i"; }) + (fetchNuGet { pname = "Microsoft.AspNetCore.Components.WebAssembly"; version = "7.0.7"; sha256 = "1fjwiala80ndbbp2wmw9hywq1id7lvqsv0c6g8f60rabhw0kndbm"; }) + (fetchNuGet { pname = "Microsoft.AspNetCore.Components.WebAssembly.DevServer"; version = "7.0.7"; sha256 = "010a7l3dp7dg5ljsk3iv1yq3qjafzggss1v5hnycrrzklhy67m6d"; }) + (fetchNuGet { pname = "Microsoft.AspNetCore.Metadata"; version = "7.0.0"; sha256 = "1vnilgndj5cck68a6r3vq40889049w7kmx9jm0c0af4f8xl4rgjz"; }) + (fetchNuGet { pname = "Microsoft.AspNetCore.Metadata"; version = "7.0.1"; sha256 = "0mbhp8gfjfn7p9snd88zkds0jqcyrmw0zm4lpjq10ss6yiq8pxnj"; }) + (fetchNuGet { pname = "Microsoft.AspNetCore.Metadata"; version = "7.0.7"; sha256 = "1jd36lxh130m3fighgkmqbahc1qf17jsn18kr44bvi533h2wzqcm"; }) + (fetchNuGet { pname = "Microsoft.Extensions.Configuration"; version = "7.0.0"; sha256 = "0n1grglxql9llmrsbbnlz5chx8mxrb5cpvjngm0hfyrkgzcwz90d"; }) + (fetchNuGet { pname = "Microsoft.Extensions.Configuration.Abstractions"; version = "7.0.0"; sha256 = "1as8cygz0pagg17w22nsf6mb49lr2mcl1x8i3ad1wi8lyzygy1a3"; }) + (fetchNuGet { pname = "Microsoft.Extensions.Configuration.Binder"; version = "7.0.4"; sha256 = "0nj424i9428p5k0vpr7rmqs54fbr31f043y1bpl007g3xmy2xn4p"; }) + (fetchNuGet { pname = "Microsoft.Extensions.Configuration.FileExtensions"; version = "7.0.0"; sha256 = "1fk7dcz6gfhd1k1d8ksz22rnjvj1waqjzk29ym4i3dz73rsq8j1i"; }) + (fetchNuGet { pname = "Microsoft.Extensions.Configuration.Json"; version = "7.0.0"; sha256 = "05zjmrpp99l128wijp1fy8asskc11ls871qaqr4mjnz3gbfycxnj"; }) + (fetchNuGet { pname = "Microsoft.Extensions.DependencyInjection"; version = "7.0.0"; sha256 = "121zs4jp8iimgbpzm3wsglhjwkc06irg1pxy8c1zcdlsg34cfq1p"; }) + (fetchNuGet { pname = "Microsoft.Extensions.DependencyInjection.Abstractions"; version = "7.0.0"; sha256 = "181d7mp9307fs17lyy42f8cxnjwysddmpsalky4m0pqxcimnr6g7"; }) + (fetchNuGet { pname = "Microsoft.Extensions.FileProviders.Abstractions"; version = "7.0.0"; sha256 = "0ff20yklyjgyjzdyv7sybczgqhgd557m05dbwxzjznr0x41b180d"; }) + (fetchNuGet { pname = "Microsoft.Extensions.FileProviders.Physical"; version = "7.0.0"; sha256 = "1f1h0l47abw0spssd64qkhgd7b54pyzslyb586zp21milimcfmgv"; }) + (fetchNuGet { pname = "Microsoft.Extensions.FileSystemGlobbing"; version = "7.0.0"; sha256 = "1812vnkn8n0i4yr3k5azcxcfx1bbpcsmms95rdyxjfrzfksr05ai"; }) + (fetchNuGet { pname = "Microsoft.Extensions.Logging"; version = "7.0.0"; sha256 = "1bqd3pqn5dacgnkq0grc17cgb2i0w8z1raw12nwm3p3zhrfcvgxf"; }) + (fetchNuGet { pname = "Microsoft.Extensions.Logging.Abstractions"; version = "7.0.0"; sha256 = "1gn7d18i1wfy13vrwhmdv1rmsb4vrk26kqdld4cgvh77yigj90xs"; }) + (fetchNuGet { pname = "Microsoft.Extensions.Logging.Abstractions"; version = "7.0.1"; sha256 = "0xv3sqc1lbx5j4yy6g2w3kakzvrpwqs2ihax6lqasj5sz5map6fk"; }) + (fetchNuGet { pname = "Microsoft.Extensions.Options"; version = "7.0.0"; sha256 = "0b90zkrsk5dw3wr749rbynhpxlg4bgqdnd7d5vdlw2g9c7zlhgx6"; }) + (fetchNuGet { pname = "Microsoft.Extensions.Options"; version = "7.0.1"; sha256 = "0ghz4y4gxnf2vw8yvhz9nkw21p6q2qqwh19phkk1xwxywyilr3mq"; }) + (fetchNuGet { pname = "Microsoft.Extensions.Primitives"; version = "7.0.0"; sha256 = "1b4km9fszid9vp2zb3gya5ni9fn8bq62bzaas2ck2r7gs0sdys80"; }) + (fetchNuGet { pname = "Microsoft.JSInterop"; version = "7.0.0"; sha256 = "11215mbpdzwijikvhd30lzrarg07h94l0993gh94n6yvxp3b6wrp"; }) + (fetchNuGet { pname = "Microsoft.JSInterop"; version = "7.0.1"; sha256 = "0xkggwxd55azqcrwibvjzd4pksprlsk0331vfqrj7hsn7dlbrjkc"; }) + (fetchNuGet { pname = "Microsoft.JSInterop"; version = "7.0.7"; sha256 = "1pnmm8yyn5w3zr2war9jg33yjnvr24d27axsgybpx8n109hgs4aq"; }) + (fetchNuGet { pname = "Microsoft.JSInterop.WebAssembly"; version = "7.0.7"; sha256 = "06vx3amlfavww1xy1jnhrj8q9x4vkacrkgfwvylxj12ji8ski65q"; }) + (fetchNuGet { pname = "Microsoft.NETCore.App.Runtime.Mono.linux-x64"; version = "7.0.8"; sha256 = "1dflhc1dfral612bdqxhm8dznyphvnl56ywjjak6s9nsjc4q8h0s"; }) + (fetchNuGet { pname = "System.IO.Pipelines"; version = "7.0.0"; sha256 = "1ila2vgi1w435j7g2y7ykp2pdbh9c5a02vm85vql89az93b7qvav"; }) + (fetchNuGet { pname = "System.Text.Encodings.Web"; version = "7.0.0"; sha256 = "1151hbyrcf8kyg1jz8k9awpbic98lwz9x129rg7zk1wrs6vjlpxl"; }) + (fetchNuGet { pname = "System.Text.Json"; version = "7.0.0"; sha256 = "0scb0lp7wbgcinaa4kqiqs7b8i5nx4ppfad81138jiwd1sl37pyp"; }) +] diff --git a/MatrixRoomUtils.sln b/MatrixRoomUtils.sln index ff16a2b..2bf2656 100755 --- a/MatrixRoomUtils.sln +++ b/MatrixRoomUtils.sln @@ -4,15 +4,17 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatrixRoomUtils", "MatrixRo EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatrixRoomUtils.Web", "MatrixRoomUtils.Web\MatrixRoomUtils.Web.csproj", "{D38DA95D-DD83-4340-96A4-6F59FC6AE3D9}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatrixRoomUtils.Core", "MatrixRoomUtils.Core\MatrixRoomUtils.Core.csproj", "{CE777A1E-2CDC-431D-82BF-CC2812E2F3A4}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatrixRoomUtils.Web.Server", "MatrixRoomUtils.Web.Server\MatrixRoomUtils.Web.Server.csproj", "{F997F26F-2EC1-4D18-B3DD-C46FB2AD65C0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatrixRoomUtils.Bot", "MatrixRoomUtils.Bot\MatrixRoomUtils.Bot.csproj", "{B397700A-4ABB-4CAF-8DB8-06E01F44514B}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatrixRoomUtils.Desktop", "MatrixRoomUtils.Desktop\MatrixRoomUtils.Desktop.csproj", "{27C08A4F-5AF0-4C2C-AFCB-050E3388C116}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatrixRoomUtils.DebugDataValidationApi", "MatrixRoomUtils.DebugDataValidationApi\MatrixRoomUtils.DebugDataValidationApi.csproj", "{FB0CF653-FD25-4701-9477-1E80221346DB}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "LibMatrix", "LibMatrix", "{8F4F6BEC-0C66-486B-A21A-1C35B2EDAD33}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatrixRoomUtils.Desktop", "MatrixRoomUtils.Desktop\MatrixRoomUtils.Desktop.csproj", "{27C08A4F-5AF0-4C2C-AFCB-050E3388C116}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibMatrix", "LibMatrix\LibMatrix\LibMatrix.csproj", "{F4E241C3-0300-4B87-8707-BCBDEF1F0185}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibMatrix.ExampleBot", "LibMatrix\LibMatrix.ExampleBot\LibMatrix.ExampleBot.csproj", "{4E72793A-AFAD-4E46-B406-2DF1E49994C6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibMatrix.DebugDataValidationApi", "LibMatrix\LibMatrix.DebugDataValidationApi\LibMatrix.DebugDataValidationApi.csproj", "{7762FD80-E7AA-409D-A465-CF208EA4BC53}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -28,25 +30,30 @@ Global {D38DA95D-DD83-4340-96A4-6F59FC6AE3D9}.Debug|Any CPU.Build.0 = Debug|Any CPU {D38DA95D-DD83-4340-96A4-6F59FC6AE3D9}.Release|Any CPU.ActiveCfg = Release|Any CPU {D38DA95D-DD83-4340-96A4-6F59FC6AE3D9}.Release|Any CPU.Build.0 = Release|Any CPU - {CE777A1E-2CDC-431D-82BF-CC2812E2F3A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CE777A1E-2CDC-431D-82BF-CC2812E2F3A4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CE777A1E-2CDC-431D-82BF-CC2812E2F3A4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CE777A1E-2CDC-431D-82BF-CC2812E2F3A4}.Release|Any CPU.Build.0 = Release|Any CPU {F997F26F-2EC1-4D18-B3DD-C46FB2AD65C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F997F26F-2EC1-4D18-B3DD-C46FB2AD65C0}.Debug|Any CPU.Build.0 = Debug|Any CPU {F997F26F-2EC1-4D18-B3DD-C46FB2AD65C0}.Release|Any CPU.ActiveCfg = Release|Any CPU {F997F26F-2EC1-4D18-B3DD-C46FB2AD65C0}.Release|Any CPU.Build.0 = Release|Any CPU - {B397700A-4ABB-4CAF-8DB8-06E01F44514B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B397700A-4ABB-4CAF-8DB8-06E01F44514B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B397700A-4ABB-4CAF-8DB8-06E01F44514B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B397700A-4ABB-4CAF-8DB8-06E01F44514B}.Release|Any CPU.Build.0 = Release|Any CPU - {FB0CF653-FD25-4701-9477-1E80221346DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FB0CF653-FD25-4701-9477-1E80221346DB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FB0CF653-FD25-4701-9477-1E80221346DB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FB0CF653-FD25-4701-9477-1E80221346DB}.Release|Any CPU.Build.0 = Release|Any CPU {27C08A4F-5AF0-4C2C-AFCB-050E3388C116}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {27C08A4F-5AF0-4C2C-AFCB-050E3388C116}.Debug|Any CPU.Build.0 = Debug|Any CPU {27C08A4F-5AF0-4C2C-AFCB-050E3388C116}.Release|Any CPU.ActiveCfg = Release|Any CPU {27C08A4F-5AF0-4C2C-AFCB-050E3388C116}.Release|Any CPU.Build.0 = Release|Any CPU + {F4E241C3-0300-4B87-8707-BCBDEF1F0185}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F4E241C3-0300-4B87-8707-BCBDEF1F0185}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F4E241C3-0300-4B87-8707-BCBDEF1F0185}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F4E241C3-0300-4B87-8707-BCBDEF1F0185}.Release|Any CPU.Build.0 = Release|Any CPU + {4E72793A-AFAD-4E46-B406-2DF1E49994C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4E72793A-AFAD-4E46-B406-2DF1E49994C6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4E72793A-AFAD-4E46-B406-2DF1E49994C6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4E72793A-AFAD-4E46-B406-2DF1E49994C6}.Release|Any CPU.Build.0 = Release|Any CPU + {7762FD80-E7AA-409D-A465-CF208EA4BC53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7762FD80-E7AA-409D-A465-CF208EA4BC53}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7762FD80-E7AA-409D-A465-CF208EA4BC53}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7762FD80-E7AA-409D-A465-CF208EA4BC53}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {F4E241C3-0300-4B87-8707-BCBDEF1F0185} = {8F4F6BEC-0C66-486B-A21A-1C35B2EDAD33} + {4E72793A-AFAD-4E46-B406-2DF1E49994C6} = {8F4F6BEC-0C66-486B-A21A-1C35B2EDAD33} + {7762FD80-E7AA-409D-A465-CF208EA4BC53} = {8F4F6BEC-0C66-486B-A21A-1C35B2EDAD33} EndGlobalSection EndGlobal diff --git a/flake.lock b/flake.lock index ba339ba..c6625fe 100644 --- a/flake.lock +++ b/flake.lock @@ -20,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1689850295, - "narHash": "sha256-fUYf6WdQlhd2H+3aR8jST5dhFH1d0eE22aes8fNIfyk=", + "lastModified": 1691899779, + "narHash": "sha256-IBf4KVr/UQJlzrqB2/IHtlvmwsvyIVLPerSzCPU/6Xk=", "owner": "nixos", "repo": "nixpkgs", - "rev": "5df4d78d54f7a34e9ea1f84a22b4fd9baebc68d0", + "rev": "100a1550b0e7a64b960c625b656f9229bdef5f87", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 34110de..47ab31d 100644 --- a/flake.nix +++ b/flake.nix @@ -24,16 +24,16 @@ # pkg-config #]; }; - frontend = pkgs.buildDotnetModule rec { - pname = "botcore-v${version}"; - version = "4"; + web = pkgs.buildDotnetModule rec { + pname = "MatrixRoomUtils.Web-v${version}"; + version = "1"; dotnet-sdk = pkgs.dotnet-sdk_7; dotnet-runtime = pkgs.dotnet-aspnetcore_7; src = ./.; projectFile = [ - "BotCore.Web.Legacy/BotCore.Web.Legacy.csproj" + "MatrixRoomUtils.Web/MatrixRoomUtils.Web.csproj" ]; - nugetDeps = ./deps.nix; + nugetDeps = MatrixRoomUtils.Web/deps.nix; #nativeBuildInputs = with pkgs; [ # pkg-config #]; diff --git a/global.json b/global.json new file mode 100644 index 0000000..37704f0 --- /dev/null +++ b/global.json @@ -0,0 +1,7 @@ +{ + "sdk": { + "version": "7.0.0", + "rollForward": "latestMajor", + "allowPrerelease": true + } +} diff --git a/mkdeps b/mkdeps index b577e03..e6bea58 100755 --- a/mkdeps +++ b/mkdeps @@ -1,11 +1,28 @@ #!/usr/bin/env nix-shell -#!nix-shell -i "bash -x" -p bash nuget-to-nix +#!nix-shell -i "bash -x" -p bash nuget-to-nix git dotnet-sdk_7 nix curl jq yq +projects=( + MatrixRoomUtils.Web +) + find . | grep -E '(bin|obj)$' | while read d; do rm -rf $d & done wait -MSBUILDLIVELOGGER=false dotnet restore --packages=packages -v n --ucr -nuget-to-nix packages | tee deps.nix -du -sh packages -rm -rf packages -nix flake update -git add deps.nix flake.lock +execDir=$(pwd) + +for p in $projects +do + ( + cd $p + pwd + MSBUILDLIVELOGGER=false dotnet restore --packages=packages -v n --ucr + #dotnet --list-sdks + ${execDir}/nuget-to-nix.sh packages | tee deps.nix + #where nuget-to-nix + pwd + du -sh packages + rm -rf packages + git add deps.nix + ) + nix flake update + git add flake.lock +done diff --git a/nuget-to-nix.sh b/nuget-to-nix.sh new file mode 100755 index 0000000..7aa35fb --- /dev/null +++ b/nuget-to-nix.sh @@ -0,0 +1,88 @@ +#!/bin/sh + +#patched version of nuget-to-nix to inherit env + +set -euo pipefail +shopt -s nullglob + +#export PATH="@binPath@" +# used for glob ordering of package names +export LC_ALL=C + +if [ $# -eq 0 ]; then + >&2 echo "Usage: $0 <packages directory> [path to a file with a list of excluded packages] > deps.nix" + exit 1 +fi + +pkgs=$1 +tmp=$(realpath "$(mktemp -td nuget-to-nix.XXXXXX)") +trap 'rm -r "$tmp"' EXIT + +excluded_list=$(realpath "${2:-/dev/null}") + +export DOTNET_NOLOGO=1 +export DOTNET_CLI_TELEMETRY_OPTOUT=1 + +mapfile -t sources < <(dotnet nuget list source --format short | awk '/^E / { print $2 }') + +declare -A base_addresses + +for index in "${sources[@]}"; do + base_addresses[$index]=$( + curl --compressed --netrc -fsL "$index" | \ + jq -r '.resources[] | select(."@type" == "PackageBaseAddress/3.0.0")."@id"') +done + +echo "{ fetchNuGet }: [" + +cd "$pkgs" +for package in *; do + cd "$package" + for version in *; do + id=$(xq -r .package.metadata.id "$version/$package".nuspec) + + if grep -qxF "$id.$version.nupkg" "$excluded_list"; then + continue + fi + + used_source="$(jq -r '.source' "$version"/.nupkg.metadata)" + for source in "${sources[@]}"; do + url="${base_addresses[$source]}$package/$version/$package.$version.nupkg" + if [[ "$source" == "$used_source" ]]; then + sha256="$(nix-hash --type sha256 --flat --base32 "$version/$package.$version".nupkg)" + found=true + break + else + if sha256=$(nix-prefetch-url "$url" 2>"$tmp"/error); then + # If multiple remote sources are enabled, nuget will try them all + # concurrently and use the one that responds first. We always use the + # first source that has the package. + echo "$package $version is available at $url, but was restored from $used_source" 1>&2 + found=true + break + else + if ! grep -q 'HTTP error 404' "$tmp/error"; then + cat "$tmp/error" 1>&2 + exit 1 + fi + fi + fi + done + + if ! ${found-false}; then + echo "couldn't find $package $version" >&2 + exit 1 + fi + + if [[ "$source" != https://api.nuget.org/v3/index.json ]]; then + echo " (fetchNuGet { pname = \"$id\"; version = \"$version\"; sha256 = \"$sha256\"; url = \"$url\"; })" + else + echo " (fetchNuGet { pname = \"$id\"; version = \"$version\"; sha256 = \"$sha256\"; })" + fi + done + cd .. +done + +cat << EOL +] +EOL |