about summary refs log tree commit diff
path: root/MatrixRoomUtils.Core
diff options
context:
space:
mode:
authorTheArcaneBrony <myrainbowdash949@gmail.com>2023-06-19 02:36:32 +0200
committerTheArcaneBrony <myrainbowdash949@gmail.com>2023-06-19 02:36:32 +0200
commited2205972a7b7d6fdd4563c3775a83616920597a (patch)
tree54aec1cfdf861fd8a7739be131fbe79ae24d91e4 /MatrixRoomUtils.Core
parentPartial refactor (diff)
downloadMatrixUtils-ed2205972a7b7d6fdd4563c3775a83616920597a.tar.xz
Working sync
Diffstat (limited to 'MatrixRoomUtils.Core')
-rw-r--r--MatrixRoomUtils.Core/AuthenticatedHomeServer.cs11
-rw-r--r--MatrixRoomUtils.Core/Helpers/SyncHelper.cs121
-rw-r--r--MatrixRoomUtils.Core/Interfaces/IHomeServer.cs2
-rw-r--r--MatrixRoomUtils.Core/Interfaces/Services/IStorageProvider.cs39
-rw-r--r--MatrixRoomUtils.Core/MatrixRoomUtils.Core.csproj6
-rw-r--r--MatrixRoomUtils.Core/Room.cs49
-rw-r--r--MatrixRoomUtils.Core/Services/HomeserverProviderService.cs18
-rw-r--r--MatrixRoomUtils.Core/Services/HomeserverService.cs8
-rw-r--r--MatrixRoomUtils.Core/Services/ServiceInstaller.cs16
-rw-r--r--MatrixRoomUtils.Core/Services/TieredStorageService.cs6
-rw-r--r--MatrixRoomUtils.Core/StateEventTypes/PresenceStateEventData.cs14
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