diff options
author | TheArcaneBrony <myrainbowdash949@gmail.com> | 2023-06-19 02:36:32 +0200 |
---|---|---|
committer | TheArcaneBrony <myrainbowdash949@gmail.com> | 2023-06-19 02:36:32 +0200 |
commit | ed2205972a7b7d6fdd4563c3775a83616920597a (patch) | |
tree | 54aec1cfdf861fd8a7739be131fbe79ae24d91e4 /MatrixRoomUtils.Core | |
parent | Partial refactor (diff) | |
download | MatrixUtils-ed2205972a7b7d6fdd4563c3775a83616920597a.tar.xz |
Working sync
Diffstat (limited to 'MatrixRoomUtils.Core')
-rw-r--r-- | MatrixRoomUtils.Core/AuthenticatedHomeServer.cs | 11 | ||||
-rw-r--r-- | MatrixRoomUtils.Core/Helpers/SyncHelper.cs | 121 | ||||
-rw-r--r-- | MatrixRoomUtils.Core/Interfaces/IHomeServer.cs | 2 | ||||
-rw-r--r-- | MatrixRoomUtils.Core/Interfaces/Services/IStorageProvider.cs | 39 | ||||
-rw-r--r-- | MatrixRoomUtils.Core/MatrixRoomUtils.Core.csproj | 6 | ||||
-rw-r--r-- | MatrixRoomUtils.Core/Room.cs | 49 | ||||
-rw-r--r-- | MatrixRoomUtils.Core/Services/HomeserverProviderService.cs | 18 | ||||
-rw-r--r-- | MatrixRoomUtils.Core/Services/HomeserverService.cs | 8 | ||||
-rw-r--r-- | MatrixRoomUtils.Core/Services/ServiceInstaller.cs | 16 | ||||
-rw-r--r-- | MatrixRoomUtils.Core/Services/TieredStorageService.cs | 6 | ||||
-rw-r--r-- | MatrixRoomUtils.Core/StateEventTypes/PresenceStateEventData.cs | 14 |
11 files changed, 271 insertions, 19 deletions
diff --git a/MatrixRoomUtils.Core/AuthenticatedHomeServer.cs b/MatrixRoomUtils.Core/AuthenticatedHomeServer.cs index 7e5650f..74e85b1 100644 --- a/MatrixRoomUtils.Core/AuthenticatedHomeServer.cs +++ b/MatrixRoomUtils.Core/AuthenticatedHomeServer.cs @@ -4,24 +4,29 @@ using System.Text.Json; using System.Text.Json.Nodes; using MatrixRoomUtils.Core.Extensions; using MatrixRoomUtils.Core.Filters; +using MatrixRoomUtils.Core.Helpers; using MatrixRoomUtils.Core.Interfaces; using MatrixRoomUtils.Core.Responses; using MatrixRoomUtils.Core.Responses.Admin; +using MatrixRoomUtils.Core.Services; namespace MatrixRoomUtils.Core; public class AuthenticatedHomeServer : IHomeServer { + private readonly TieredStorageService _storage; public readonly HomeserverAdminApi Admin; + public readonly SyncHelper SyncHelper; - public AuthenticatedHomeServer(string userId, string accessToken, string canonicalHomeServerDomain) { - UserId = userId; + public AuthenticatedHomeServer(string canonicalHomeServerDomain, string accessToken, TieredStorageService storage) { + _storage = storage; AccessToken = accessToken; HomeServerDomain = canonicalHomeServerDomain; Admin = new HomeserverAdminApi(this); + SyncHelper = new SyncHelper(this, storage); _httpClient = new MatrixHttpClient(); } - public string UserId { get; set; } + public string UserId { get; } public string AccessToken { get; set; } public async Task<AuthenticatedHomeServer> Configure() { diff --git a/MatrixRoomUtils.Core/Helpers/SyncHelper.cs b/MatrixRoomUtils.Core/Helpers/SyncHelper.cs new file mode 100644 index 0000000..edbb646 --- /dev/null +++ b/MatrixRoomUtils.Core/Helpers/SyncHelper.cs @@ -0,0 +1,121 @@ +using System.Net.Http.Json; +using System.Text.Json.Serialization; +using MatrixRoomUtils.Core.Responses; +using MatrixRoomUtils.Core.Services; +using MatrixRoomUtils.Core.StateEventTypes; + +namespace MatrixRoomUtils.Core.Helpers; + +public class SyncHelper { + private readonly AuthenticatedHomeServer _homeServer; + private readonly TieredStorageService _storageService; + + public SyncHelper(AuthenticatedHomeServer homeServer, TieredStorageService storageService) { + _homeServer = homeServer; + _storageService = storageService; + } + + public async Task<SyncResult?> Sync(string? since = null) { + var outFileName = "sync-" + + (await _storageService.CacheStorageProvider.GetAllKeys()).Count(x => x.StartsWith("sync")) + + ".json"; + var url = "/_matrix/client/v3/sync?timeout=30000&set_presence=online"; + if (!string.IsNullOrWhiteSpace(since)) url += $"&since={since}"; + else url += "&full_state=true"; + Console.WriteLine("Calling: " + url); + var res = await _homeServer._httpClient.GetFromJsonAsync<SyncResult>(url); + await _storageService.CacheStorageProvider.SaveObject(outFileName, res); + return res; + } + + public event EventHandler<SyncResult>? ; +} + +public class SyncResult { + [JsonPropertyName("next_batch")] + public string NextBatch { get; set; } + + [JsonPropertyName("account_data")] + public EventList AccountData { get; set; } + + [JsonPropertyName("presence")] + public PresenceDataStructure Presence { get; set; } + + [JsonPropertyName("device_one_time_keys_count")] + public Dictionary<string, int> DeviceOneTimeKeysCount { get; set; } + + [JsonPropertyName("rooms")] + public RoomsDataStructure Rooms { get; set; } + + // supporting classes + public class PresenceDataStructure { + [JsonPropertyName("events")] + public List<StateEventResponse<PresenceStateEventData>> Events { get; set; } + } + + public class RoomsDataStructure { + [JsonPropertyName("join")] + public Dictionary<string, JoinedRoomDataStructure> Join { get; set; } + + [JsonPropertyName("invite")] + public Dictionary<string, InvitedRoomDataStructure> Invite { get; set; } + + public class JoinedRoomDataStructure { + [JsonPropertyName("timeline")] + public TimelineDataStructure Timeline { get; set; } + + [JsonPropertyName("state")] + public EventList State { get; set; } + + [JsonPropertyName("account_data")] + public EventList AccountData { get; set; } + + [JsonPropertyName("ephemeral")] + public EventList Ephemeral { get; set; } + + [JsonPropertyName("unread_notifications")] + public UnreadNotificationsDataStructure UnreadNotifications { get; set; } + + [JsonPropertyName("summary")] + public SummaryDataStructure Summary { get; set; } + + public class TimelineDataStructure { + [JsonPropertyName("events")] + public List<StateEventResponse> Events { get; set; } + + [JsonPropertyName("prev_batch")] + public string PrevBatch { get; set; } + + [JsonPropertyName("limited")] + public bool Limited { get; set; } + } + + public class UnreadNotificationsDataStructure { + [JsonPropertyName("notification_count")] + public int NotificationCount { get; set; } + + [JsonPropertyName("highlight_count")] + public int HighlightCount { get; set; } + } + + public class SummaryDataStructure { + [JsonPropertyName("m.heroes")] + public List<string> Heroes { get; set; } + [JsonPropertyName("m.invited_member_count")] + public int InvitedMemberCount { get; set; } + [JsonPropertyName("m.joined_member_count")] + public int JoinedMemberCount { get; set; } + } + } + + public class InvitedRoomDataStructure { + [JsonPropertyName("invite_state")] + public EventList InviteState { get; set; } + } + } +} + +public class EventList { + [JsonPropertyName("events")] + public List<StateEventResponse> Events { get; set; } +} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Interfaces/IHomeServer.cs b/MatrixRoomUtils.Core/Interfaces/IHomeServer.cs index a808c3d..c5645e6 100644 --- a/MatrixRoomUtils.Core/Interfaces/IHomeServer.cs +++ b/MatrixRoomUtils.Core/Interfaces/IHomeServer.cs @@ -10,7 +10,7 @@ public class IHomeServer { public string HomeServerDomain { get; set; } public string FullHomeServerDomain { get; set; } - private protected MatrixHttpClient _httpClient { get; set; } = new(); + protected internal MatrixHttpClient _httpClient { get; set; } = new(); public async Task<string> ResolveHomeserverFromWellKnown(string homeserver) { var res = await _resolveHomeserverFromWellKnown(homeserver); diff --git a/MatrixRoomUtils.Core/Interfaces/Services/IStorageProvider.cs b/MatrixRoomUtils.Core/Interfaces/Services/IStorageProvider.cs index 2540ad7..01314da 100644 --- a/MatrixRoomUtils.Core/Interfaces/Services/IStorageProvider.cs +++ b/MatrixRoomUtils.Core/Interfaces/Services/IStorageProvider.cs @@ -1,17 +1,46 @@ namespace MatrixRoomUtils.Core.Interfaces.Services; public interface IStorageProvider { - // save - public async Task SaveAll() { - Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement Save()!"); + // save all children of a type with reflection + public Task SaveAllChildren<T>(string key, T value) { + Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement SaveAllChildren<T>(key, value)!"); + return Task.CompletedTask; } + + // load all children of a type with reflection + public Task<T?> LoadAllChildren<T>(string key) { + Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement LoadAllChildren<T>(key)!"); + return Task.FromResult(default(T)); + } + - public async Task SaveObject<T>(string key, T value) { + public Task SaveObject<T>(string key, T value) { Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement SaveObject<T>(key, value)!"); + return Task.CompletedTask; + } + + // load + public Task<T?> LoadObject<T>(string key) { + Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement LoadObject<T>(key)!"); + return Task.FromResult(default(T)); + } + + // check if exists + public Task<bool> ObjectExists(string key) { + Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement ObjectExists(key)!"); + return Task.FromResult(false); + } + + // get all keys + public Task<List<string>> GetAllKeys() { + Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement GetAllKeys()!"); + return Task.FromResult(new List<string>()); } + // delete - public async Task DeleteObject(string key) { + public Task DeleteObject(string key) { Console.WriteLine($"StorageProvider<{GetType().Name}> does not implement DeleteObject(key)!"); + return Task.CompletedTask; } } \ No newline at end of file diff --git a/MatrixRoomUtils.Core/MatrixRoomUtils.Core.csproj b/MatrixRoomUtils.Core/MatrixRoomUtils.Core.csproj index 6836c68..5ca40bd 100644 --- a/MatrixRoomUtils.Core/MatrixRoomUtils.Core.csproj +++ b/MatrixRoomUtils.Core/MatrixRoomUtils.Core.csproj @@ -6,4 +6,10 @@ <Nullable>enable</Nullable> </PropertyGroup> + <ItemGroup> + <Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions"> + <HintPath>..\..\..\.cache\NuGetPackages\microsoft.extensions.dependencyinjection.abstractions\7.0.0\lib\net7.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath> + </Reference> + </ItemGroup> + </Project> diff --git a/MatrixRoomUtils.Core/Room.cs b/MatrixRoomUtils.Core/Room.cs index 4f6bbca..1568746 100644 --- a/MatrixRoomUtils.Core/Room.cs +++ b/MatrixRoomUtils.Core/Room.cs @@ -1,4 +1,5 @@ using System.Net.Http.Json; +using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using System.Web; @@ -148,11 +149,57 @@ public class Room { if (res.Value.TryGetProperty("type", out var type)) return type.GetString(); return null; } + + public async Task ForgetAsync() { + var res = await _httpClient.PostAsync($"/_matrix/client/r0/rooms/{RoomId}/forget", null); + if (!res.IsSuccessStatusCode) { + Console.WriteLine($"Failed to forget room {RoomId} - got status: {res.StatusCode}"); + throw new Exception($"Failed to forget room {RoomId} - got status: {res.StatusCode}"); + } + } + + public async Task LeaveAsync(string? reason = null) { + var res = await _httpClient.PostAsync($"/_matrix/client/r0/rooms/{RoomId}/leave", string.IsNullOrWhiteSpace(reason) ? null : new StringContent($"{{\"reason\":\"{reason}\"}}", Encoding.UTF8, "application/json")); + if (!res.IsSuccessStatusCode) { + Console.WriteLine($"Failed to leave room {RoomId} - got status: {res.StatusCode}"); + throw new Exception($"Failed to leave room {RoomId} - got status: {res.StatusCode}"); + } + } + + public async Task KickAsync(string userId, string? reason = null) { + + var res = await _httpClient.PostAsJsonAsync($"/_matrix/client/r0/rooms/{RoomId}/kick", new UserIdAndReason() { user_id = userId, reason = reason }); + if (!res.IsSuccessStatusCode) { + Console.WriteLine($"Failed to kick {userId} from room {RoomId} - got status: {res.StatusCode}"); + throw new Exception($"Failed to kick {userId} from room {RoomId} - got status: {res.StatusCode}"); + } + } + + public async Task BanAsync(string userId, string? reason = null) { + var res = await _httpClient.PostAsJsonAsync($"/_matrix/client/r0/rooms/{RoomId}/ban", new UserIdAndReason() { user_id = userId, reason = reason }); + if (!res.IsSuccessStatusCode) { + Console.WriteLine($"Failed to ban {userId} from room {RoomId} - got status: {res.StatusCode}"); + throw new Exception($"Failed to ban {userId} from room {RoomId} - got status: {res.StatusCode}"); + } + } + + public async Task UnbanAsync(string userId) { + var res = await _httpClient.PostAsJsonAsync($"/_matrix/client/r0/rooms/{RoomId}/unban", new UserIdAndReason() { user_id = userId }); + if (!res.IsSuccessStatusCode) { + Console.WriteLine($"Failed to unban {userId} from room {RoomId} - got status: {res.StatusCode}"); + throw new Exception($"Failed to unban {userId} from room {RoomId} - got status: {res.StatusCode}"); + } + } + - public SpaceRoom AsSpace; + public readonly SpaceRoom AsSpace; } +internal class UserIdAndReason { + public string user_id { get; set; } + public string? reason { get; set; } +} public class MessagesResponse { [JsonPropertyName("start")] public string Start { get; set; } diff --git a/MatrixRoomUtils.Core/Services/HomeserverProviderService.cs b/MatrixRoomUtils.Core/Services/HomeserverProviderService.cs new file mode 100644 index 0000000..3db4584 --- /dev/null +++ b/MatrixRoomUtils.Core/Services/HomeserverProviderService.cs @@ -0,0 +1,18 @@ +using MatrixRoomUtils.Core.Attributes; + +namespace MatrixRoomUtils.Core.Services; + +public class HomeserverProviderService { + private readonly TieredStorageService _tieredStorageService; + + public HomeserverProviderService(TieredStorageService tieredStorageService) { + Console.WriteLine("Homeserver provider service instantiated!"); + _tieredStorageService = tieredStorageService; + Console.WriteLine( + $"New HomeserverProviderService created with TieredStorageService<{string.Join(", ", tieredStorageService.GetType().GetProperties().Select(x => x.Name))}>!"); + } + + public async Task<AuthenticatedHomeServer> GetAuthenticatedWithToken(string homeserver, string accessToken) { + return await new AuthenticatedHomeServer(homeserver, accessToken, _tieredStorageService).Configure(); + } +} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Services/HomeserverService.cs b/MatrixRoomUtils.Core/Services/HomeserverService.cs deleted file mode 100644 index ba48e6c..0000000 --- a/MatrixRoomUtils.Core/Services/HomeserverService.cs +++ /dev/null @@ -1,8 +0,0 @@ -using MatrixRoomUtils.Core.Attributes; - -namespace MatrixRoomUtils.Core.Services; - -[Trace] -public class HomeserverService { - -} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Services/ServiceInstaller.cs b/MatrixRoomUtils.Core/Services/ServiceInstaller.cs new file mode 100644 index 0000000..43255d8 --- /dev/null +++ b/MatrixRoomUtils.Core/Services/ServiceInstaller.cs @@ -0,0 +1,16 @@ +using MatrixRoomUtils.Core.Interfaces.Services; +using Microsoft.Extensions.DependencyInjection; + +namespace MatrixRoomUtils.Core.Services; + +public static class ServiceInstaller { + + public static IServiceCollection AddRoryLibMatrixServices(this IServiceCollection services) { + if (!services.Any(x => x.ServiceType == typeof(TieredStorageService))) + throw new Exception("[MRUCore/DI] No TieredStorageService has been registered!"); + services.AddScoped<HomeserverProviderService>(); + return services; + } + + +} \ No newline at end of file diff --git a/MatrixRoomUtils.Core/Services/TieredStorageService.cs b/MatrixRoomUtils.Core/Services/TieredStorageService.cs index f6beddd..2f27443 100644 --- a/MatrixRoomUtils.Core/Services/TieredStorageService.cs +++ b/MatrixRoomUtils.Core/Services/TieredStorageService.cs @@ -3,7 +3,11 @@ using MatrixRoomUtils.Core.Interfaces.Services; namespace MatrixRoomUtils.Core.Services; public class TieredStorageService { + public IStorageProvider CacheStorageProvider { get; } + public IStorageProvider DataStorageProvider { get; } + public TieredStorageService(IStorageProvider cacheStorageProvider, IStorageProvider dataStorageProvider) { - + CacheStorageProvider = cacheStorageProvider; + DataStorageProvider = dataStorageProvider; } } \ No newline at end of file diff --git a/MatrixRoomUtils.Core/StateEventTypes/PresenceStateEventData.cs b/MatrixRoomUtils.Core/StateEventTypes/PresenceStateEventData.cs new file mode 100644 index 0000000..d835c95 --- /dev/null +++ b/MatrixRoomUtils.Core/StateEventTypes/PresenceStateEventData.cs @@ -0,0 +1,14 @@ +using System.Text.Json.Serialization; + +namespace MatrixRoomUtils.Core.StateEventTypes; + +public class PresenceStateEventData { + [JsonPropertyName("presence")] + public string Presence { get; set; } + [JsonPropertyName("last_active_ago")] + public long LastActiveAgo { get; set; } + [JsonPropertyName("currently_active")] + public bool CurrentlyActive { get; set; } + [JsonPropertyName("status_msg")] + public string StatusMessage { get; set; } +} \ No newline at end of file |