about summary refs log tree commit diff
path: root/MatrixUtils.Web/Pages/Tools/Info/PolicyListActivity.razor
blob: c94d0b08360adc3cd477188de746b4f285c67b16 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
@page "/Tools/PolicyListActivity"
@using LibMatrix.EventTypes.Spec.State.Policy
@using System.Diagnostics
@using LibMatrix.RoomTypes
@using LibMatrix.EventTypes.Common


@if (RoomData.Count == 0)
{
    <p>Loading...</p>
}
else
    foreach (var room in RoomData)
    {
        <h3>@room.Key</h3>
        @foreach (var year in room.Value.OrderBy(x => x.Key))
        {
            <h5>@year.Key</h5>
            <ActivityGraph Data="@year.Value" GlobalMax="MaxValue"
                           RLabel="removed" GLabel="new" BLabel="updated policies">
            </ActivityGraph>
        }
    }


@code {
    public AuthenticatedHomeserverGeneric? Homeserver { get; set; }
    public List<GenericRoom> FilteredRooms = new();

    public Dictionary<DateOnly, ActivityGraph.RGB> TestData { get; set; } = new();

    public ActivityGraph.RGB MaxValue { get; set; } = new()
    {
        R = 255, G = 255, B = 255
    };

    public Dictionary<string, Dictionary<int, Dictionary<DateOnly, ActivityGraph.RGB>>> 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>(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>(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<GenericRoom>());
        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);
            }
    }


}