@page "/Tools/UserTrace" @using ArcaneLibs.Extensions @using LibMatrix.RoomTypes @using System.Collections.ObjectModel @using LibMatrix @using System.Collections.Frozen @using LibMatrix.EventTypes.Spec.State @using LibMatrix.Filters @using MatrixUtils.Abstractions

User Trace


Users:


Import from room (ID)
Rooms to be searched (@rooms.Count) @foreach (var room in rooms) { @room.RoomId
}

Execute
Results @foreach (var (userId, events) in matches) {

@userId

}

@foreach (var line in log.Reverse()) {
@line
} @code { private ObservableCollection log { get; set; } = new(); // List rooms { get; set; } = new(); List rooms { get; set; } = []; Dictionary> matches = new(); private string UserIdString { get => string.Join("\n", UserIDs); set => UserIDs = value.Split("\n").Select(x => x.Trim()).Where(x => !string.IsNullOrWhiteSpace(x)).ToList(); } private List UserIDs { get; set; } = new(); protected override async Task OnInitializedAsync() { log.CollectionChanged += (sender, args) => StateHasChanged(); var hs = await RMUStorage.GetCurrentSessionOrNavigate(); if (hs is null) return; // var sessions = await RMUStorage.GetAllTokens(); // var baseRooms = new List(); // foreach (var userAuth in sessions) { // var session = await RMUStorage.GetSession(userAuth); // if (session is not null) { // baseRooms.AddRange(await session.GetJoinedRooms()); // var sessionRooms = (await session.GetJoinedRooms()).Where(x => !rooms.Any(y => y.Room.RoomId == x.RoomId)).ToList(); // StateHasChanged(); // log.Add($"Got {sessionRooms.Count} rooms for {userAuth.UserId}"); // } // } // // log.Add("Done fetching rooms!"); // // baseRooms = baseRooms.DistinctBy(x => x.RoomId).ToList(); // // // rooms.CollectionChanged += (sender, args) => StateHasChanged(); // var tasks = baseRooms.Select(async newRoom => { // bool success = false; // while (!success) // try { // var state = await newRoom.GetFullStateAsListAsync(); // var newRoomInfo = new RoomInfo(newRoom, state); // rooms.Add(newRoomInfo); // log.Add($"Got {newRoomInfo.StateEvents.Count} events for {newRoomInfo.RoomName}"); // success = true; // } // catch (MatrixException e) { // log.Add($"Failed to fetch room {newRoom.RoomId}! {e}"); // throw; // } // catch (HttpRequestException e) { // log.Add($"Failed to fetch room {newRoom.RoomId}! {e}"); // } // }); // await Task.WhenAll(tasks); // // log.Add($"Done fetching members!"); // // UserIDs.RemoveAll(x => sessions.Any(y => y.UserId == x)); foreach (var session in await RMUStorage.GetAllTokens()) { var _hs = await RMUStorage.GetSession(session); if (_hs is not null) { rooms.AddRange(await _hs.GetJoinedRooms()); log.Add($"Got {rooms.Count} rooms after adding {_hs.UserId}"); } } //get distinct rooms evenly distributed per session, accounting for count per session rooms = rooms.OrderBy(x => rooms.Count(y => y.Homeserver == x.Homeserver)).DistinctBy(x => x.RoomId).ToList(); log.Add($"Got {rooms.Count} rooms"); StateHasChanged(); Console.WriteLine("Rerendered!"); await base.OnInitializedAsync(); } private async Task Execute() { foreach (var userId in UserIDs) { matches.Add(userId, new List()); // foreach (var room in rooms) { // var state = room.StateEvents.Where(x => x!.Type == RoomMemberEventContent.EventId).ToList(); // if (state!.Any(x => x.StateKey == userId)) { // matches[userId].Add(new() { // Event = state.First(x => x.StateKey == userId), // Room = room.Room, // RoomName = room.RoomName ?? "No name" // }); // } // } log.Add($"Searching for {userId}..."); await foreach (var match in GetMatches(userId)) { matches[userId].Add(match); } } log.Add("Done!"); StateHasChanged(); return ""; } public string? ImportFromRoomId { get; set; } private async Task DoImportFromRoomId() { try { if (ImportFromRoomId is null) return; var room = rooms.FirstOrDefault(x => x.RoomId == ImportFromRoomId); UserIdString = string.Join("\n", (await room.GetMembersListAsync()).Select(x => x.StateKey)); } catch (Exception e) { Console.WriteLine(e); log.Add("Could not fetch members list!\n" + e.ToString()); } StateHasChanged(); } private class Match { public GenericRoom Room; public StateEventResponse Event; public string RoomName { get; set; } } private async IAsyncEnumerable GetMatches(string userId) { var results = rooms.Select(async room => { var state = await room.GetStateEventOrNullAsync(room.RoomId, userId); if (state is not null) { return new Match { Room = room, Event = state, RoomName = await room.GetNameOrFallbackAsync() }; } return null; }).ToAsyncEnumerable(); await foreach (var result in results) { if (result is not null) { yield return result; } } } }