diff --git a/Utilities/LibMatrix.TestDataGenerator/Bot/DataFetcher.cs b/Utilities/LibMatrix.TestDataGenerator/Bot/DataFetcher.cs
new file mode 100644
index 0000000..66b8a03
--- /dev/null
+++ b/Utilities/LibMatrix.TestDataGenerator/Bot/DataFetcher.cs
@@ -0,0 +1,59 @@
+using ArcaneLibs.Extensions;
+using LibMatrix.EventTypes.Spec;
+using LibMatrix.Homeservers;
+using LibMatrix.RoomTypes;
+using LibMatrix.Utilities.Bot;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+
+#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
+
+namespace TestDataGenerator.Bot;
+
+public class DataFetcher(AuthenticatedHomeserverGeneric hs, ILogger<DataFetcher> logger, LibMatrixBotConfiguration botConfiguration) : IHostedService {
+ private Task? _listenerTask;
+
+ private GenericRoom? _logRoom;
+
+ /// <summary>Triggered when the application host is ready to start the service.</summary>
+ /// <param name="cancellationToken">Indicates that the start process has been aborted.</param>
+ public async Task StartAsync(CancellationToken cancellationToken) {
+ _listenerTask = Run(cancellationToken);
+ logger.LogInformation("Bot started!");
+ }
+
+ private async Task Run(CancellationToken cancellationToken) {
+ Directory.GetFiles("bot_data/cache").ToList().ForEach(File.Delete);
+ _logRoom = hs.GetRoom(botConfiguration.LogRoom!);
+
+ await _logRoom.SendMessageEventAsync(new RoomMessageEventContent(body: "Test data collector started!"));
+ await _logRoom.SendMessageEventAsync(new RoomMessageEventContent(body: "Fetching rooms..."));
+
+ var rooms = await hs.GetJoinedRooms();
+ await _logRoom.SendMessageEventAsync(new RoomMessageEventContent(body: $"Fetched {rooms.Count} rooms!"));
+
+ await _logRoom.SendMessageEventAsync(new RoomMessageEventContent(body: "Fetching room data..."));
+
+ var roomAliasTasks = rooms.Select(room => room.GetCanonicalAliasAsync()).ToAsyncEnumerable();
+ List<Task<(string, string)>> aliasResolutionTasks = new();
+ await foreach (var @event in roomAliasTasks)
+ if (@event?.Alias != null) {
+ await _logRoom.SendMessageEventAsync(new RoomMessageEventContent(body: $"Fetched room alias {@event.Alias}!"));
+ aliasResolutionTasks.Add(Task.Run(async () => {
+ var alias = await hs.ResolveRoomAliasAsync(@event.Alias);
+ return (@event.Alias, alias.RoomId);
+ }, cancellationToken));
+ }
+
+ var aliasResolutionTaskEnumerator = aliasResolutionTasks.ToAsyncEnumerable();
+ await foreach (var result in aliasResolutionTaskEnumerator)
+ await _logRoom.SendMessageEventAsync(new RoomMessageEventContent(body: $"Resolved room alias {result.Item1} to {result.Item2}!"));
+ }
+
+ /// <summary>Triggered when the application host is performing a graceful shutdown.</summary>
+ /// <param name="cancellationToken">Indicates that the shutdown process should no longer be graceful.</param>
+ public async Task StopAsync(CancellationToken cancellationToken) {
+ logger.LogInformation("Shutting down bot!");
+ _listenerTask?.Dispose();
+ }
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.TestDataGenerator/Bot/DataFetcherConfiguration.cs b/Utilities/LibMatrix.TestDataGenerator/Bot/DataFetcherConfiguration.cs
new file mode 100644
index 0000000..4f53a2a
--- /dev/null
+++ b/Utilities/LibMatrix.TestDataGenerator/Bot/DataFetcherConfiguration.cs
@@ -0,0 +1,9 @@
+using Microsoft.Extensions.Configuration;
+
+namespace TestDataGenerator.Bot;
+
+public class DataFetcherConfiguration {
+ public DataFetcherConfiguration(IConfiguration config) => config.GetRequiredSection("DataFetcher").Bind(this);
+
+ // public string
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.TestDataGenerator/LibMatrix.TestDataGenerator.csproj b/Utilities/LibMatrix.TestDataGenerator/LibMatrix.TestDataGenerator.csproj
new file mode 100644
index 0000000..879693e
--- /dev/null
+++ b/Utilities/LibMatrix.TestDataGenerator/LibMatrix.TestDataGenerator.csproj
@@ -0,0 +1,32 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <OutputType>Exe</OutputType>
+ <TargetFramework>net8.0</TargetFramework>
+ <LangVersion>preview</LangVersion>
+ <ImplicitUsings>enable</ImplicitUsings>
+ <Nullable>enable</Nullable>
+ <PublishAot>false</PublishAot>
+ <InvariantGlobalization>true</InvariantGlobalization>
+ <!-- <PublishTrimmed>true</PublishTrimmed>-->
+ <!-- <PublishReadyToRun>true</PublishReadyToRun>-->
+ <!-- <PublishSingleFile>true</PublishSingleFile>-->
+ <!-- <PublishReadyToRunShowWarnings>true</PublishReadyToRunShowWarnings>-->
+ <!-- <PublishTrimmedShowLinkerSizeComparison>true</PublishTrimmedShowLinkerSizeComparison>-->
+ <!-- <PublishTrimmedShowLinkerSizeComparisonWarnings>true</PublishTrimmedShowLinkerSizeComparisonWarnings>-->
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0"/>
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="appsettings*.json">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\LibMatrix\LibMatrix.csproj"/>
+ <ProjectReference Include="..\..\Utilities\LibMatrix.Utilities.Bot\LibMatrix.Utilities.Bot.csproj"/>
+ <ProjectReference Include="..\LibMatrix.Tests\LibMatrix.Tests.csproj"/>
+ </ItemGroup>
+</Project>
diff --git a/Utilities/LibMatrix.TestDataGenerator/Program.cs b/Utilities/LibMatrix.TestDataGenerator/Program.cs
new file mode 100644
index 0000000..2583817
--- /dev/null
+++ b/Utilities/LibMatrix.TestDataGenerator/Program.cs
@@ -0,0 +1,27 @@
+// See https://aka.ms/new-console-template for more information
+
+using LibMatrix.Services;
+using LibMatrix.Utilities.Bot;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using TestDataGenerator.Bot;
+
+Console.WriteLine("Hello, World!");
+
+var host = Host.CreateDefaultBuilder(args).ConfigureServices((_, services) => {
+ services.AddScoped<TieredStorageService>(_ =>
+ new TieredStorageService(
+ new FileStorageProvider("bot_data/cache/"),
+ new FileStorageProvider("bot_data/data/")
+ )
+ );
+ // services.AddSingleton<DataFetcherConfiguration>();
+ services.AddSingleton<AppServiceConfiguration>();
+
+ services.AddRoryLibMatrixServices();
+ services.AddMatrixBot();//.AddCommandHandler().AddCommands([typeof()]);
+
+ services.AddHostedService<DataFetcher>();
+}).UseConsoleLifetime().Build();
+
+await host.RunAsync();
\ No newline at end of file
diff --git a/Utilities/LibMatrix.TestDataGenerator/Properties/launchSettings.json b/Utilities/LibMatrix.TestDataGenerator/Properties/launchSettings.json
new file mode 100644
index 0000000..6c504ff
--- /dev/null
+++ b/Utilities/LibMatrix.TestDataGenerator/Properties/launchSettings.json
@@ -0,0 +1,25 @@
+{
+ "$schema": "http://json.schemastore.org/launchsettings.json",
+ "profiles": {
+ "Default": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "environmentVariables": {
+ }
+ },
+ "Development": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "environmentVariables": {
+ "DOTNET_ENVIRONMENT": "Development"
+ }
+ },
+ "Local config": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "environmentVariables": {
+ "DOTNET_ENVIRONMENT": "Local"
+ }
+ }
+ }
+}
diff --git a/Utilities/LibMatrix.TestDataGenerator/appsettings.Development.json b/Utilities/LibMatrix.TestDataGenerator/appsettings.Development.json
new file mode 100644
index 0000000..38c45c4
--- /dev/null
+++ b/Utilities/LibMatrix.TestDataGenerator/appsettings.Development.json
@@ -0,0 +1,18 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Debug",
+ "System": "Information",
+ "Microsoft": "Information"
+ }
+ },
+ "LibMatrixBot": {
+ // The homeserver to connect to
+ "Homeserver": "rory.gay",
+ // The access token to use
+ "AccessToken": "syt_xxxxxxxxxxxxxxxxx",
+ // The command prefix
+ "Prefix": "?",
+ "LogRoom": "!xxxxxxxxxxxxxxxxxxxxxx:example.com"
+ }
+}
diff --git a/Utilities/LibMatrix.TestDataGenerator/appsettings.json b/Utilities/LibMatrix.TestDataGenerator/appsettings.json
new file mode 100644
index 0000000..e203e94
--- /dev/null
+++ b/Utilities/LibMatrix.TestDataGenerator/appsettings.json
@@ -0,0 +1,9 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Debug",
+ "System": "Information",
+ "Microsoft": "Information"
+ }
+ }
+}
|