@page "/Tools/PolicyListActivity" @using LibMatrix.EventTypes.Spec.State.Policy @using System.Diagnostics @using LibMatrix.RoomTypes @using LibMatrix.EventTypes.Common @if (RoomData.Count == 0) {

Loading...

} else foreach (var room in RoomData) {

@room.Key

@foreach (var year in room.Value.OrderBy(x => x.Key)) {
@year.Key
} } @code { public AuthenticatedHomeserverGeneric? Homeserver { get; set; } public List FilteredRooms = new(); public Dictionary TestData { get; set; } = new(); public ActivityGraph.RGB MaxValue { get; set; } = new() { R = 255, G = 255, B = 255 }; public Dictionary>> RoomData { get; set; } = new(); protected override async Task OnInitializedAsync() { var sw = Stopwatch.StartNew(); await base.OnInitializedAsync(); Homeserver = (await RMUStorage.GetCurrentSessionOrNavigate())!; if (Homeserver is null) return; //random test data for (DateOnly i = new DateOnly(2020, 1, 1); i < new DateOnly(2020, 12, 30); i = i.AddDays(Random.Shared.Next(5))) { TestData[i] = new() { R = (int)(Random.Shared.NextSingle() * 255), G = (int)(Random.Shared.NextSingle() * 255), B = (int)(Random.Shared.NextSingle() * 255) }; } StateHasChanged(); // return; var rooms = await Homeserver.GetJoinedRooms(); // foreach (var room in rooms) // { // var type = await room.GetRoomType(); // if (type == "support.feline.policy.lists.msc.v1") // { // Console.WriteLine($"{room.RoomId} is policy list by type"); // FilteredRooms.Add(room); // } // else if(await room.GetStateOrNullAsync(MjolnirShortcodeEventContent.EventId) is not null) // { // Console.WriteLine($"{room.RoomId} is policy list by shortcode"); // FilteredRooms.Add(room); // } // } var roomFilterTasks = rooms.Select(async room => { var type = await room.GetRoomType(); if (type == "support.feline.policy.lists.msc.v1") { Console.WriteLine($"{room.RoomId} is policy list by type"); return room; } else if (await room.GetStateOrNullAsync(MjolnirShortcodeEventContent.EventId) is not null) { Console.WriteLine($"{room.RoomId} is policy list by shortcode"); return room; } return null; }).ToList(); var filteredRooms = await Task.WhenAll(roomFilterTasks); FilteredRooms.AddRange(filteredRooms.Where(x => x is not null).Cast()); Console.WriteLine($"Filtered {FilteredRooms.Count} rooms in {sw.ElapsedMilliseconds}ms"); var roomTasks = FilteredRooms.Select(FetchRoomHistory).ToList(); await Task.WhenAll(roomTasks); Console.WriteLine($"Max value is {MaxValue.R} {MaxValue.G} {MaxValue.B}"); Console.WriteLine($"Filtered {FilteredRooms.Count} rooms in {sw.ElapsedMilliseconds}ms"); } public async Task FetchRoomHistory(GenericRoom room) { var roomName = await room.GetNameOrFallbackAsync(); if (string.IsNullOrWhiteSpace(roomName)) roomName = room.RoomId; if (!RoomData.ContainsKey(roomName)) { RoomData[roomName] = new(); } //use timeline var timeline = room.GetManyMessagesAsync(limit: int.MaxValue, chunkSize: 5000); await foreach (var response in timeline) { Console.WriteLine($"Got {response.State.Count} state, {response.Chunk.Count} timeline"); if (response.State.Count != 0) throw new Exception("Why the hell did we receive state events?"); foreach (var message in response.Chunk) { if (!message.MappedType.IsAssignableTo(typeof(PolicyRuleEventContent))) continue; //OriginServerTs to datetime var dt = DateTimeOffset.FromUnixTimeMilliseconds((long)message.OriginServerTs!.Value).DateTime; var date = new DateOnly(dt.Year, dt.Month, dt.Day); if (!RoomData[roomName].ContainsKey(date.Year)) { RoomData[roomName][date.Year] = new(); } if (!RoomData[roomName][date.Year].ContainsKey(date)) { // Console.WriteLine($"Adding {date} to {roomName}"); RoomData[roomName][date.Year][date] = new(); } var rgb = RoomData[roomName][date.Year][date]; if (message.RawContent?.Count == 0) rgb.R++; else if (string.IsNullOrWhiteSpace(message.Unsigned?.ReplacesState)) rgb.G++; else rgb.B++; RoomData[roomName][date.Year][date] = rgb; } var max = RoomData.SelectMany(x => x.Value.Values).Aggregate(new ActivityGraph.RGB(), (current, next) => new() { R = Math.Max(current.R, next.Average(x => x.Value.R)), G = Math.Max(current.G, next.Average(x => x.Value.G)), B = Math.Max(current.B, next.Average(x => x.Value.B)) }); MaxValue = new ActivityGraph.RGB( r: Math.Max(max.R, Math.Max(max.G, max.B)), g: Math.Max(max.R, Math.Max(max.G, max.B)), b: Math.Max(max.R, Math.Max(max.G, max.B))); Console.WriteLine($"Max value is {MaxValue.R} {MaxValue.G} {MaxValue.B}"); StateHasChanged(); await Task.Delay(100); } } }