about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--BugMine.DevTools.CLI/Worker.cs132
-rw-r--r--BugMine.Sdk/BugMineClient.cs17
-rw-r--r--BugMine.Sdk/BugMineProject.cs28
-rw-r--r--BugMine.Sdk/Events/State/BugMineRoomMetadata.cs2
-rw-r--r--BugMine.Web/Pages/Auth/LegacyLogin.razor1
-rw-r--r--BugMine.Web/Pages/Projects/Index.razor10
-rw-r--r--BugMine.Web/Pages/Projects/ViewProject.razor6
-rw-r--r--BugMine.sln10
m---------LibMatrix0
10 files changed, 148 insertions, 59 deletions
diff --git a/.gitignore b/.gitignore
index 1821c7e..51eecb3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,3 +16,4 @@ test-proxy.tsv
 homeservers.txt
 LoginPayload.txt
 LoginPayload.txt.old
+BugMine.DevTools.CLI/auth.json
diff --git a/BugMine.DevTools.CLI/Worker.cs b/BugMine.DevTools.CLI/Worker.cs
index 8cd931e..900d742 100644
--- a/BugMine.DevTools.CLI/Worker.cs
+++ b/BugMine.DevTools.CLI/Worker.cs
@@ -1,3 +1,4 @@
+using System.Diagnostics;
 using System.Text.Json;
 using ArcaneLibs.Extensions;
 using BugMine.Web.Classes;
@@ -30,74 +31,90 @@ public class Worker(ILogger<Worker> logger, HomeserverProviderService hsProvider
         while (!stoppingToken.IsCancellationRequested) {
             Console.WriteLine("""
                               1) List all projects
-                              2) Create 500 projects
+                              2) Mass create projects
                               3) Destroy all projects
                               4) Get room count
+                              5) Summarize all projects
+                              6) Mass create regular rooms
+
+                              L) Logout
+                              Q) Quit
                               """);
 
             var input = Console.ReadKey();
             Console.WriteLine();
             switch (input.Key) {
                 case ConsoleKey.D1: {
-                    if (Client is null) {
-                        _logger.LogError("No client available.");
-                        break;
-                    }
-
+                    var sw = Stopwatch.StartNew();
                     var projects = Client.GetProjects();
                     await foreach (var project in projects) {
                         Console.WriteLine(project.ToJson(indent: false));
                     }
 
+                    Console.WriteLine($"Queried in {sw.Elapsed}");
                     break;
                 }
                 case ConsoleKey.D2: {
-                    if (Client is null) {
-                        _logger.LogError("No client available.");
-                        break;
-                    }
-
                     await MassCreateProjects();
                     break;
                 }
                 case ConsoleKey.D3: {
-                    if (Client is null) {
-                        _logger.LogError("No client available.");
-                        break;
-                    }
-
                     await DestroyAllProjects();
                     break;
                 }
                 case ConsoleKey.D4: {
-                    if (Client is null) {
-                        _logger.LogError("No client available.");
-                        break;
+                    var sw = Stopwatch.StartNew();
+                    var rooms = await Client.Homeserver.GetJoinedRooms();
+                    Console.WriteLine(rooms.Count() + " rooms.");
+                    var projectCount = 0;
+                    await foreach (var room in Client.Homeserver.GetJoinedRoomsByType("gay.rory.bugmine.project").WithCancellation(stoppingToken)) {
+                        projectCount++;
                     }
 
-                    var rooms = await Client.Homeserver.GetJoinedRooms();
-                    Console.WriteLine(rooms.Count());
+                    Console.WriteLine($"{projectCount} projects ({rooms.Count} rooms) queried in {sw.Elapsed}");
                     break;
                 }
+                case ConsoleKey.D5: {
+                    await SummarizeAllProjects();
+                    break;
+                }
+                case ConsoleKey.D6: {
+                    var sw = Stopwatch.StartNew();
+                    await Task.WhenAll(Enumerable.Range(0,1000).Select(async _ => {
+                        await Client.Homeserver.CreateRoom(new() {
+                            Name = Guid.NewGuid().ToString()[..8]
+                        });
+                    }));
+                    Console.WriteLine($"Created 1000 rooms in {sw.Elapsed}");
+                    break;
+                }
+                case ConsoleKey.L: {
+                    File.Delete("auth.json");
+                    await ExecuteAsync(stoppingToken);
+                    return;
+                }
+                case ConsoleKey.Q: {
+                    Environment.Exit(0);
+                    return;
+                }
             }
         }
     }
 
     private async Task DestroyAllProjects() {
-        var ss = new SemaphoreSlim(4, 4);
-        await foreach (var proj in Client.Homeserver.GetJoinedRoomsByType(null!)) {
-            if (proj.RoomId == "!UktPWOzit8gmms5FQ6:conduit.matrixunittests.rory.gay") continue;
+        var ss = new SemaphoreSlim(48, 48);
+        await foreach (var proj in Client.Homeserver.GetJoinedRoomsByType("gay.rory.bugmine.project")) {
             Task.Run(async () => {
                 // await ss.WaitAsync();
-                await proj.SendStateEventAsync(RoomNameEventContent.EventId, new RoomNameEventContent() {
-                    Name = "Disbanded BugMine project."
-                });
-                await proj.SendStateEventAsync(RoomJoinRulesEventContent.EventId, new RoomJoinRulesEventContent() {
-                    JoinRule = RoomJoinRulesEventContent.JoinRules.Private
-                });
-                await proj.SendStateEventAsync(RoomCanonicalAliasEventContent.EventId, new RoomCanonicalAliasEventContent() {
-                    Alias = null
-                });
+                // await proj.SendStateEventAsync(RoomNameEventContent.EventId, new RoomNameEventContent() {
+                //     Name = "Disbanded BugMine project."
+                // });
+                // await proj.SendStateEventAsync(RoomJoinRulesEventContent.EventId, new RoomJoinRulesEventContent() {
+                //     JoinRule = RoomJoinRulesEventContent.JoinRules.Private
+                // });
+                // await proj.SendStateEventAsync(RoomCanonicalAliasEventContent.EventId, new RoomCanonicalAliasEventContent() {
+                //     Alias = null
+                // });
                 await proj.LeaveAsync("Disbanded room.");
                 // ss.Release();
             });
@@ -106,18 +123,59 @@ public class Worker(ILogger<Worker> logger, HomeserverProviderService hsProvider
 
     private async Task MassCreateProjects() {
         // var rooms = await Client.Homeserver.GetJoinedRooms();
-        // List<string> roomNames = (await Task.WhenAll(rooms.Select(x => x.GetNameAsync()))).Where(x => x != null).ToList();
+        // List<string> roomNames = (await Task.WhenAll(rooms.Select(x => x.GetNameAsync()))).Where(x => x != 
+        var tasks = new List<Task>();
         for (int i = 0; i < 500; i++) {
-            Task.Run(async () => {
+            tasks.Add(Task.Run(async () => {
                 // var randomName = roomNames[Random.Shared.Next(roomNames.Count)];
                 var proj = await Client.CreateProject(new() {
                     Name = /*randomName + */Guid.NewGuid().ToString()[..8]
                 });
 
                 // await proj.CreateIssue(new() {
-                // Name = "meow"
+                //     Name = "meow"
                 // });
-            });
+                await CreateRandomIssues(proj, Random.Shared.Next(20));
+            }));
+            // await Task.Delay(250);
+        }
+
+        await Task.WhenAll(tasks);
+    }
+
+    private async Task<string> SummarizeProject(BugMineProject project) {
+        string result = $"Project: {project.Info.Name}, slug: {project.ProjectSlug}, metadata: {project.Metadata.ToJson(indent: false)}";
+        await foreach (var issue in project.GetIssues()) {
+            // Console.WriteLine($" - {issue.Data.RawContent.ToJson(indent: false)}");
+            result += $"\n - {issue.Data.RawContent.ToJson(indent: false)}";
+        }
+
+        return result;
+    }
+
+    private async Task SummarizeAllProjects() {
+        var sw = Stopwatch.StartNew();
+        var tasks = new List<Task<string>>();
+        await foreach (var project in Client.GetProjects()) {
+            tasks.Add(SummarizeProject(project));
+        }
+
+        int projects = 0;
+        int issues = 0;
+        await foreach (var res in tasks.ToAsyncEnumerable()) {
+            Console.WriteLine(res + "\n");
+            projects++;
+            issues += res.Count(x => x == '\n');
         }
+
+        Console.WriteLine($"Summarized {projects} projects with {issues} issues in {sw.Elapsed}");
+    }
+
+    private async Task CreateRandomIssues(BugMineProject project, int count) {
+        await Task.WhenAll(Enumerable.Range(0, count).Select(async i => {
+            await project.CreateIssue(new() {
+                Name = $"Issue {i} @ {DateTime.Now}"
+            });
+        }));
     }
 }
\ No newline at end of file
diff --git a/BugMine.Sdk/BugMineClient.cs b/BugMine.Sdk/BugMineClient.cs
index db47b85..21be614 100644
--- a/BugMine.Sdk/BugMineClient.cs
+++ b/BugMine.Sdk/BugMineClient.cs
@@ -11,10 +11,11 @@ namespace BugMine.Web.Classes;
 public class BugMineClient(AuthenticatedHomeserverGeneric homeserver) {
     public AuthenticatedHomeserverGeneric Homeserver { get; } = homeserver;
 
-    public async IAsyncEnumerable<BugMineProject> GetProjects() {
+    public async IAsyncEnumerable<BugMineProject> GetProjects(SemaphoreSlim? semaphore = null) {
         List<Task<BugMineProject>> tasks = [];
-        await foreach (var room in homeserver.GetJoinedRoomsByType(BugMineProject.RoomType)) {
-            tasks.Add(room.AsBugMineProject());
+        int count = 0;
+        await foreach (var room in homeserver.GetJoinedRoomsByType(BugMineProject.RoomType, 64)) {
+            tasks.Add(room.AsBugMineProject(semaphore));
         }
 
         var results = tasks.ToAsyncEnumerable();
@@ -46,10 +47,14 @@ public class BugMineClient(AuthenticatedHomeserverGeneric homeserver) {
             ]
         };
 
-        var response = await Homeserver.CreateRoom(crr);
-        // await response.SendStateEventAsync(ProjectInfo.EventId, request);
+        var newRoom = await Homeserver.CreateRoom(crr);
+        var timeline = await newRoom.GetMessagesAsync();
+        
+        await newRoom.SendStateEventAsync(BugMineRoomMetadata.EventId, new BugMineRoomMetadata() {
+            RoomCreationEventId = timeline.Chunk.Single(m => m.Type == "m.room.create").EventId!
+        });
 
-        return await response.AsBugMineProject();
+        return await newRoom.AsBugMineProject();
     }
 
     public async Task<BugMineProject?> GetProject(string projectSlug) {
diff --git a/BugMine.Sdk/BugMineProject.cs b/BugMine.Sdk/BugMineProject.cs
index babb680..1f56659 100644
--- a/BugMine.Sdk/BugMineProject.cs
+++ b/BugMine.Sdk/BugMineProject.cs
@@ -1,6 +1,4 @@
-using System.Text.Json.Nodes;
-using LibMatrix.EventTypes.Spec.State;
-using LibMatrix.Homeservers;
+using ArcaneLibs.Extensions;
 using LibMatrix.RoomTypes;
 
 namespace BugMine.Web.Classes;
@@ -9,43 +7,51 @@ public class BugMineProject(GenericRoom room) {
     public const string RoomType = "gay.rory.bugmine.project";
     public GenericRoom Room { get; } = room;
     public ProjectInfo Info { get; set; }
+    public BugMineRoomMetadata Metadata { get; set; }
     public string ProjectSlug { get; set; }
 
     public async Task<BugMineProject> InitializeAsync() {
-        Info = (await Room.GetStateAsync<ProjectInfo>(ProjectInfo.EventId))!;
+        var infoTask = Room.GetStateAsync<ProjectInfo>(ProjectInfo.EventId);
+        var metadataTask = Room.GetStateAsync<BugMineRoomMetadata>(BugMineRoomMetadata.EventId)!;
         var alias = await room.GetCanonicalAliasAsync();
 
         if (alias != null)
             ProjectSlug = alias.Alias?[1..] ?? room.RoomId;
         else ProjectSlug = room.RoomId;
 
+        Info = (await infoTask)!;
+        Metadata = (await metadataTask)!;
         return this;
     }
 
     public async Task<BugMineIssue> CreateIssue(BugMineIssueData issue) {
         // add relation to room creation event
         issue.RelatesTo = new() {
-            EventId = await room.GetStateEventIdAsync(RoomCreateEventContent.EventId),
+            EventId = Metadata.RoomCreationEventId,
             RelationType = "gay.rory.bugmine.issue"
         };
         var eventId = await Room.SendTimelineEventAsync(BugMineIssueData.EventId, issue);
 
-        // return new BugMineIssueAccessor(Room, await Room.GetEventAsync<>(eventId));
         var evt = await room.GetEventAsync(eventId.EventId);
-        Console.WriteLine(evt);
+        Console.WriteLine(evt.ToJson(indent: false));
         return new BugMineIssue(Room, evt);
     }
 
     public async IAsyncEnumerable<BugMineIssue> GetIssues() {
-        var creationEventId = await room.GetStateEventIdAsync(RoomCreateEventContent.EventId);
-        await foreach (var evt in room.GetRelatedEventsAsync(creationEventId, "gay.rory.bugmine.issue", BugMineIssueData.EventId)) {
+        await foreach (var evt in room.GetRelatedEventsAsync(Metadata.RoomCreationEventId, "gay.rory.bugmine.issue", BugMineIssueData.EventId)) {
             yield return new BugMineIssue(Room, evt);
         }
     }
 }
 
 public static class ProjectRoomExtensions {
-    public static async Task<BugMineProject> AsBugMineProject(this GenericRoom room) {
-        return await new BugMineProject(room).InitializeAsync();
+    public static async Task<BugMineProject> AsBugMineProject(this GenericRoom room, SemaphoreSlim? semaphore = null) {
+        try {
+            await (semaphore?.WaitAsync() ?? Task.CompletedTask);
+            return await new BugMineProject(room).InitializeAsync();
+        }
+        finally {
+            semaphore?.Release();
+        }
     }
 }
\ No newline at end of file
diff --git a/BugMine.Sdk/Events/State/BugMineRoomMetadata.cs b/BugMine.Sdk/Events/State/BugMineRoomMetadata.cs
index a6686d3..734fd37 100644
--- a/BugMine.Sdk/Events/State/BugMineRoomMetadata.cs
+++ b/BugMine.Sdk/Events/State/BugMineRoomMetadata.cs
@@ -7,5 +7,5 @@ public class BugMineRoomMetadata : EventContent {
     public const string EventId = "gay.rory.bugmine.room_metadata";
     
     public string RoomCreationEventId { get; set; }
-    
+
 }
\ No newline at end of file
diff --git a/BugMine.Web/Pages/Auth/LegacyLogin.razor b/BugMine.Web/Pages/Auth/LegacyLogin.razor
index eec381a..bcfac61 100644
--- a/BugMine.Web/Pages/Auth/LegacyLogin.razor
+++ b/BugMine.Web/Pages/Auth/LegacyLogin.razor
@@ -48,6 +48,7 @@
 
             await BugMineStorage.AddToken(result);
             await BugMineStorage.SetCurrentToken(result);
+            NavigationManager.NavigateTo("/", forceLoad: true);
         }
         catch (Exception e) {
             Console.WriteLine($"Failed to login to {record.Homeserver} as {record.Username}!");
diff --git a/BugMine.Web/Pages/Projects/Index.razor b/BugMine.Web/Pages/Projects/Index.razor
index 47c2f4a..8f46d02 100644
--- a/BugMine.Web/Pages/Projects/Index.razor
+++ b/BugMine.Web/Pages/Projects/Index.razor
@@ -43,12 +43,14 @@ else {
             return;
         }
         StateHasChanged();
-        
-        await foreach (var project in Client.GetProjects()) {
+
+        int count = 0;
+        SemaphoreSlim semaphore = new(16, 16);
+        await foreach (var project in Client.GetProjects(semaphore)) {
             Projects ??= [];
             Projects.Add(project);
-            StateHasChanged();
-            // await Task.Delay(100);
+            if(count++ <= 250 || count % 4 == 0)
+                StateHasChanged();
         }
 
         Projects ??= [];
diff --git a/BugMine.Web/Pages/Projects/ViewProject.razor b/BugMine.Web/Pages/Projects/ViewProject.razor
index a778728..ec10d1c 100644
--- a/BugMine.Web/Pages/Projects/ViewProject.razor
+++ b/BugMine.Web/Pages/Projects/ViewProject.razor
@@ -1,6 +1,7 @@
 @page "/Projects/{ProjectSlug}/"
 @using LibMatrix
 @using BugMine.Web.Classes.Exceptions
+@using ArcaneLibs.Extensions
 
 <ProgressLog ></ProgressLog>
 
@@ -29,6 +30,11 @@ else {
         <p>Loading issues, got @(Issues?.Count ?? 0) so far... <SimpleSpinner/></p>
     }
     @* <p>@Project.Description</p> *@
+    @if (Issues != null) {
+        @foreach(var issue in Issues) {
+            <pre>@issue.Data.RawContent.ToJson()</pre>
+        }
+    }
 }
 
 @code {
diff --git a/BugMine.sln b/BugMine.sln
index c6b4a4b..f6d49f3 100644
--- a/BugMine.sln
+++ b/BugMine.sln
@@ -18,6 +18,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BugMine.Sdk", "BugMine.Sdk\
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BugMine.DevTools.CLI", "BugMine.DevTools.CLI\BugMine.DevTools.CLI.csproj", "{E4E398A6-98CE-4B78-9E80-42A03765CE07}"
 EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{E25BCB86-1123-481D-BA11-920B76006305}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibMatrix.HomeserverEmulator", "LibMatrix\Tests\LibMatrix.HomeserverEmulator\LibMatrix.HomeserverEmulator.csproj", "{630BD644-B739-4876-B45C-085FF60C7269}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -48,11 +52,17 @@ Global
 		{E4E398A6-98CE-4B78-9E80-42A03765CE07}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{E4E398A6-98CE-4B78-9E80-42A03765CE07}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{E4E398A6-98CE-4B78-9E80-42A03765CE07}.Release|Any CPU.Build.0 = Release|Any CPU
+		{630BD644-B739-4876-B45C-085FF60C7269}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{630BD644-B739-4876-B45C-085FF60C7269}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{630BD644-B739-4876-B45C-085FF60C7269}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{630BD644-B739-4876-B45C-085FF60C7269}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(NestedProjects) = preSolution
 		{F4E241C3-0300-4B87-8707-BCBDEF1F0185} = {8F4F6BEC-0C66-486B-A21A-1C35B2EDAD33}
 		{1CAA2B6D-0365-4C8B-96EE-26026514FEE2} = {8F4F6BEC-0C66-486B-A21A-1C35B2EDAD33}
 		{B00E29F5-1ED8-40A0-A70D-DE9F23FC572F} = {B00C5CB6-6200-4B41-96BE-C6EAF1085A14}
 		{2D6F31D7-3139-44EC-9D11-486282DD4ED1} = {B00C5CB6-6200-4B41-96BE-C6EAF1085A14}
+		{E25BCB86-1123-481D-BA11-920B76006305} = {8F4F6BEC-0C66-486B-A21A-1C35B2EDAD33}
+		{630BD644-B739-4876-B45C-085FF60C7269} = {E25BCB86-1123-481D-BA11-920B76006305}
 	EndGlobalSection
 EndGlobal
diff --git a/LibMatrix b/LibMatrix
-Subproject 5ca0a45606ad2ca7e1ca45a3b27be08e9640dd9
+Subproject 508c694c3d551cddb3b15c1b0d4787dae3c0053