about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--MatrixUtils.Web/Pages/Tools/MigrateRoom.razor104
1 files changed, 104 insertions, 0 deletions
diff --git a/MatrixUtils.Web/Pages/Tools/MigrateRoom.razor b/MatrixUtils.Web/Pages/Tools/MigrateRoom.razor
new file mode 100644
index 0000000..3234098
--- /dev/null
+++ b/MatrixUtils.Web/Pages/Tools/MigrateRoom.razor
@@ -0,0 +1,104 @@
+@page "/Tools/MigrateRoom"
+@using ArcaneLibs.Extensions
+@using LibMatrix
+@using LibMatrix.EventTypes.Spec.State
+@using LibMatrix.RoomTypes
+<h3>Migrate room</h3>
+<hr/>
+<span>Old room: </span>
+<FancyTextBox @bind-Value="@roomId"></FancyTextBox><br/>
+<span>New room: </span>
+<FancyTextBox @bind-Value="@newRoomId"></FancyTextBox><br/>
+
+<details>
+    <summary>Users:</summary>
+    @foreach (var user in users) {
+        <p>@user</p>
+    }
+</details>
+
+<br/>
+<LinkButton OnClick="Execute">Execute</LinkButton>
+<br/>
+@foreach (var line in Enumerable.Reverse(log)) {
+    <p>@line</p>
+}
+
+@code {
+    private string _roomId;
+    private List<string> log { get; set; } = new();
+    private List<string> users { get; set; } = new();
+
+    string roomId {
+        get => _roomId;
+        set {
+            _roomId = value;
+            TryFetchUsers();
+        }
+    }
+
+    private string newRoomId { get; set; }
+
+    protected override async Task OnInitializedAsync() {
+        var hs = await RMUStorage.GetCurrentSessionOrNavigate();
+        if (hs is null) return;
+
+        StateHasChanged();
+        Console.WriteLine("Rerendered!");
+        await base.OnInitializedAsync();
+    }
+
+    private async Task Execute() {
+        var hs = await RMUStorage.GetCurrentSessionOrNavigate();
+        if (hs is null) return;
+        var oldRoom = hs.GetRoom(roomId);
+        var newRoom = hs.GetRoom(newRoomId);
+        var members = await oldRoom.GetMembersListAsync();
+        var tasks = members.Select(x => ExecuteInvite(hs, newRoom, x.StateKey)).ToAsyncEnumerable();
+        // var tasks = hss.Select(ExecuteInvite).ToAsyncEnumerable();
+        await foreach (var a in tasks) {
+            if (!string.IsNullOrWhiteSpace(a)) {
+                log.Add(a);
+                StateHasChanged();
+            }
+        }
+    }
+
+    private async Task<string> ExecuteInvite(AuthenticatedHomeserverGeneric hs, GenericRoom newRoom, string mxid) {
+        try {
+            var pls = await newRoom.GetPowerLevelsAsync();
+            if (pls.GetUserPowerLevel(hs.WhoAmI.UserId) < pls.Invite) return "I do not have permission to send invite in " + newRoom.RoomId;
+            await newRoom.InviteUserAsync(mxid);
+            return $"Invited {mxid} to {newRoom.RoomId}";
+        }
+        catch (MatrixException e) {
+            log.Add($"Failed to invite {mxid} to {newRoom.RoomId}: {e.Message}");
+            if (e is { ErrorCode: "M_LIMIT_EXCEEDED" }) {
+                log.Add($"Retrying after {e.RetryAfterMs}");
+                await Task.Delay(e.RetryAfterMs!.Value);
+                return await ExecuteInvite(hs, newRoom, mxid);
+            }
+
+            return "";
+        }
+        catch (Exception e) {
+            return $"Failed to invite {mxid} to {newRoom.RoomId}: {e.Message}";
+        }
+
+        StateHasChanged();
+        return "";
+    }
+
+    private async Task TryFetchUsers() {
+        try {
+            var hs = await RMUStorage.GetCurrentSessionOrNavigate();
+            if (hs is null) return;
+            var room = hs.GetRoom(roomId);
+            var members = await room.GetMembersListAsync();
+            users = members.Select(x => x.StateKey).ToList();
+            StateHasChanged();
+        }
+        catch { }
+    }
+
+}
\ No newline at end of file