diff options
author | Emma [it/its]@Rory& <root@rory.gay> | 2023-11-23 05:42:33 +0100 |
---|---|---|
committer | Emma [it/its]@Rory& <root@rory.gay> | 2023-11-23 05:42:33 +0100 |
commit | 3e934eee892f69a8f78b94950993000522702769 (patch) | |
tree | 6aa0d3d26c9a07a7a3e097fe28abb785400bfbd6 /LibMatrix/RoomTypes/GenericRoom.cs | |
parent | Add license retroactively, matching where the code originated from (MatrixRoo... (diff) | |
download | LibMatrix-3e934eee892f69a8f78b94950993000522702769.tar.xz |
Moderation bot work
Diffstat (limited to 'LibMatrix/RoomTypes/GenericRoom.cs')
-rw-r--r-- | LibMatrix/RoomTypes/GenericRoom.cs | 88 |
1 files changed, 80 insertions, 8 deletions
diff --git a/LibMatrix/RoomTypes/GenericRoom.cs b/LibMatrix/RoomTypes/GenericRoom.cs index b81713a..d26b1f8 100644 --- a/LibMatrix/RoomTypes/GenericRoom.cs +++ b/LibMatrix/RoomTypes/GenericRoom.cs @@ -29,13 +29,16 @@ public class GenericRoom { public string RoomId { get; set; } public async IAsyncEnumerable<StateEventResponse?> GetFullStateAsync() { - var result = _httpClient.GetAsyncEnumerableFromJsonAsync<StateEventResponse>( - $"/_matrix/client/v3/rooms/{RoomId}/state"); + var result = _httpClient.GetAsyncEnumerableFromJsonAsync<StateEventResponse>($"/_matrix/client/v3/rooms/{RoomId}/state"); await foreach (var resp in result) { yield return resp; } } + public async Task<List<StateEventResponse>> GetFullStateAsListAsync() { + return await _httpClient.GetFromJsonAsync<List<StateEventResponse>>($"/_matrix/client/v3/rooms/{RoomId}/state"); + } + public async Task<T?> GetStateAsync<T>(string type, string stateKey = "") { var url = $"/_matrix/client/v3/rooms/{RoomId}/state"; if (!string.IsNullOrEmpty(type)) url += $"/{type}"; @@ -77,17 +80,82 @@ public class GenericRoom { } } - public async Task<MessagesResponse> GetMessagesAsync(string from = "", int limit = 10, string dir = "b", - string filter = "") { - var url = $"/_matrix/client/v3/rooms/{RoomId}/messages?from={from}&limit={limit}&dir={dir}"; - if (!string.IsNullOrEmpty(filter)) url += $"&filter={filter}"; + public async Task<MessagesResponse> GetMessagesAsync(string from = "", int? limit = null, string dir = "b", string filter = "") { + var url = $"/_matrix/client/v3/rooms/{RoomId}/messages?dir={dir}"; + if (!string.IsNullOrWhiteSpace(from)) url += $"&from={from}"; + if (limit is not null) url += $"&limit={limit}"; + if (!string.IsNullOrWhiteSpace(filter)) url += $"&filter={filter}"; var res = await _httpClient.GetFromJsonAsync<MessagesResponse>(url); return res ?? new MessagesResponse(); } + /// <summary> + /// Same as <see cref="GetMessagesAsync"/>, except keeps fetching more responses until the beginning of the room is found, or the target message limit is reached + /// </summary> + public async IAsyncEnumerable<MessagesResponse> GetManyMessagesAsync(string from = "", int limit = 100, string dir = "b", string filter = "", bool includeState = true, + bool fixForward = false) { + if (dir == "f" && fixForward) { + var concat = new List<MessagesResponse>(); + while (true) { + var resp = await GetMessagesAsync(from, int.MaxValue, "b", filter); + concat.Add(resp); + if (!includeState) + resp.State.Clear(); + from = resp.End; + if (resp.End is null) break; + } + + concat.Reverse(); + foreach (var eventResponse in concat) { + limit -= eventResponse.State.Count + eventResponse.Chunk.Count; + while (limit < 0) { + if (eventResponse.State.Count > 0 && eventResponse.State.Max(x => x.OriginServerTs) > eventResponse.Chunk.Max(x => x.OriginServerTs)) + eventResponse.State.Remove(eventResponse.State.MaxBy(x => x.OriginServerTs)); + else + eventResponse.Chunk.Remove(eventResponse.Chunk.MaxBy(x => x.OriginServerTs)); + + limit++; + } + + eventResponse.Chunk.Reverse(); + eventResponse.State.Reverse(); + yield return eventResponse; + if (limit <= 0) yield break; + } + } + else { + while (limit > 0) { + var resp = await GetMessagesAsync(from, limit, dir, filter); + + if (!includeState) + resp.State.Clear(); + + limit -= resp.Chunk.Count + resp.State.Count; + from = resp.End; + yield return resp; + if (resp.End is null) { + Console.WriteLine("End is null"); + yield break; + } + } + } + + Console.WriteLine("End of GetManyAsync"); + } + public async Task<string?> GetNameAsync() => (await GetStateAsync<RoomNameEventContent>("m.room.name"))?.Name; - public async Task<RoomIdResponse> JoinAsync(string[]? homeservers = null, string? reason = null) { + public async Task<RoomIdResponse> JoinAsync(string[]? homeservers = null, string? reason = null, bool checkIfAlreadyMember = true) { + if (checkIfAlreadyMember) { + try { + var ce = await GetCreateEventAsync(); + return new() { + RoomId = RoomId + }; + } + catch { } //ignore + } + var join_url = $"/_matrix/client/v3/join/{HttpUtility.UrlEncode(RoomId)}"; Console.WriteLine($"Calling {join_url} with {homeservers?.Length ?? 0} via's..."); if (homeservers == null || homeservers.Length == 0) homeservers = new[] { RoomId.Split(':')[1] }; @@ -235,13 +303,17 @@ public class GenericRoom { return await res.Content.ReadFromJsonAsync<EventIdResponse>(); } - public async Task<EventIdResponse?> SendFileAsync(string fileName, Stream fileStream, string messageType = "m.file") { + public async Task<EventIdResponse?> SendFileAsync(string fileName, Stream fileStream, string messageType = "m.file", string contentType = "application/octet-stream") { var url = await Homeserver.UploadFile(fileName, fileStream); var content = new RoomMessageEventContent() { MessageType = messageType, Url = url, Body = fileName, FileName = fileName, + FileInfo = new() { + Size = fileStream.Length, + MimeType = contentType + } }; return await SendTimelineEventAsync("m.room.message", content); } |