Updated EllieHub to 1.0.1.0

This commit is contained in:
Toastie 2024-04-27 01:26:32 +12:00
parent 50f40f01d1
commit fe5c273143
Signed by: toastie_t0ast
GPG key ID: 27F3B6855AFD40A4
8 changed files with 114 additions and 90 deletions

View file

@ -95,19 +95,16 @@ public static class AppResources
/// </summary> /// </summary>
public const string LightBackground = "LightBackground"; public const string LightBackground = "LightBackground";
/// <summary> /// <summary>
/// Resource type: <see cref="ImmutableSolidColorBrush"/> /// Resource type: <see cref="ImmutableSolidColorBrush"/>
/// </summary> /// </summary>
public const string MediumBackground = "MediumBackground"; public const string MediumBackground = "MediumBackground";
/// <summary> /// <summary>
/// Resource type: <see cref="ImmutableSolidColorBrush"/> /// Resource type: <see cref="ImmutableSolidColorBrush"/>
/// </summary> /// </summary>
public const string HeavyBackground = "HeavyBackground"; public const string HeavyBackground = "HeavyBackground";
/// <summary> /// <summary>
/// Resource type: <see cref="ImmutableSolidColorBrush"/> /// Resource type: <see cref="ImmutableSolidColorBrush"/>
/// </summary> /// </summary>

View file

@ -1,41 +1,42 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<!--Project Settings--> <!--Project Settings-->
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>net7.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<AnalysisLevel>latest</AnalysisLevel> <AnalysisLevel>latest</AnalysisLevel>
<LangVersion>latest</LangVersion> <LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors> <WarningsAsErrors>Nullable</WarningsAsErrors>
<TreatWarningsAsErrors>True</TreatWarningsAsErrors> <TreatWarningsAsErrors>True</TreatWarningsAsErrors>
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild> <EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
<GenerateDocumentationFile>True</GenerateDocumentationFile> <GenerateDocumentationFile>True</GenerateDocumentationFile>
<BuiltInComInteropSupport>True</BuiltInComInteropSupport> <BuiltInComInteropSupport>True</BuiltInComInteropSupport>
<ApplicationIcon>Assets/Light/ellieupdatericon.ico</ApplicationIcon> <ApplicationIcon>Assets/Light/ellieupdatericon.ico</ApplicationIcon>
<!--Publishing--> <!--Publishing-->
<PublishSingleFile>true</PublishSingleFile> <PublishSingleFile>true</PublishSingleFile>
<DebugType>embedded</DebugType> <SelfContained>true</SelfContained>
<DebugType>embedded</DebugType>
<!--Version--> <!--Version-->
<VersionPrefix>1.0.0.0</VersionPrefix> <VersionPrefix>1.0.1.0</VersionPrefix>
<!--Avalonia Settings--> <!--Avalonia Settings-->
<ApplicationManifest>app.manifest</ApplicationManifest> <ApplicationManifest>app.manifest</ApplicationManifest>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault> <AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
<!--Generate app host, so the final MacOS .app binary works--> <!--Generate app host, so the final MacOS .app binary works-->
<UseAppHost>true</UseAppHost> <UseAppHost>true</UseAppHost>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<AvaloniaResource Include="Assets\**" /> <AvaloniaResource Include="Assets\**" />
<!--Watch XAML files for hot reload--> <!--Watch XAML files for hot reload-->
<Watch Include="**\*.xaml" /> <Watch Include="**\*.xaml" />
<Watch Include="**\*.axaml" /> <Watch Include="**\*.axaml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Avalonia" Version="11.0.4" /> <PackageReference Include="Avalonia" Version="11.0.4" />
@ -54,9 +55,9 @@
<PackageReference Include="SkiaImageView.Avalonia11" Version="1.5.0" /> <PackageReference Include="SkiaImageView.Avalonia11" Version="1.5.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Update="Views\Windows\AppView.axaml.cs"> <Compile Update="Views\Windows\AppView.axaml.cs">
<DependentUpon>AppView.axaml</DependentUpon> <DependentUpon>AppView.axaml</DependentUpon>
</Compile> </Compile>
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -30,12 +30,10 @@ public sealed class EllieOrchestrator : IBotOrchestrator
public EllieOrchestrator(ReadOnlyAppConfig appConfig) public EllieOrchestrator(ReadOnlyAppConfig appConfig)
=> _appConfig = appConfig; => _appConfig = appConfig;
/// <inheritdoc/> /// <inheritdoc/>
public bool IsBotRunning(Guid botId) public bool IsBotRunning(Guid botId)
=> _runningBots.ContainsKey(botId); => _runningBots.ContainsKey(botId);
/// <inheritdoc/> /// <inheritdoc/>
public bool Start(Guid botId) public bool Start(Guid botId)
{ {

View file

@ -162,52 +162,15 @@ public sealed partial class EllieResolver : IBotResolver
cToken cToken
); );
// Move the bot root directory while renaming it // Move the bot root directory
if (Environment.OSVersion.Platform is not PlatformID.Unix) if (Environment.OSVersion.Platform is not PlatformID.Unix)
{ await InstallToWindowsAsync(downloadStream, installationUri, zipTempLocation, botTempLocation, cToken);
// Save the zip file
using (var fileStream = new FileStream(zipTempLocation, FileMode.Create))
await downloadStream.CopyToAsync(fileStream, cToken);
// Extract the zip file
await Task.Run(() => ZipFile.ExtractToDirectory(zipTempLocation, _tempDirectory), cToken);
// Move the bot root directory while renaming it
Directory.Move(botTempLocation, installationUri);
}
else else
{ await InstallToUnixAsync(downloadStream, installationUri, botTempLocation, cToken);
// Extract the tar ball
await TarFile.ExtractToDirectoryAsync(downloadStream, _tempDirectory, true, cToken);
// Move the bot root directory with "mv" to circumvent this issue on Unix systems: https://github.com/dotnet/runtime/issues/31149
using var moveProcess = Utilities.StartProcess("mv", $"\"{botTempLocation}\" \"{installationUri}\"");
await moveProcess.WaitForExitAsync(cToken);
// Set executable permission
using var chmod = Utilities.StartProcess("chmod", $"+x \"{Path.Combine(installationUri, FileName)}\"");
await chmod.WaitForExitAsync(cToken);
}
// Reapply bot settings // Reapply bot settings
if (File.Exists(backupFileUri)) if (File.Exists(backupFileUri))
{ await ReaplyBotSettingsAsync(installationUri, backupFileUri, cToken);
using var zipFile = ZipFile.OpenRead(backupFileUri);
var zippedFiles = zipFile.Entries
.Where(x =>
x.Name is "creds.yml" or "creds_example.yml"
|| (!string.IsNullOrWhiteSpace(x.Name) && x.FullName.Contains("data/"))
);
foreach (var zippedFile in zippedFiles)
{
var fileDestinationPath = zippedFile.FullName.Split('/')
.Prepend(Directory.GetParent(installationUri)?.FullName ?? string.Empty)
.ToArray();
await RestoreFileAsync(zippedFile, Path.Combine(fileDestinationPath), cToken);
}
}
// Update settings // Update settings
await _appConfigManager.UpdateBotEntryAsync(Id, x => x with { Version = latestVersion }, cToken); await _appConfigManager.UpdateBotEntryAsync(Id, x => x with { Version = latestVersion }, cToken);
@ -230,6 +193,73 @@ public sealed partial class EllieResolver : IBotResolver
} }
} }
/// <summary>
/// Installs the Nadeko instance on a Unix system.
/// </summary>
/// <param name="downloadStream">The stream of data downloaded from the source.</param>
/// <param name="installationUri">The absolute path to the directory the bot got installed to.</param>
/// <param name="botTempLocation">The absolute path to the temporary directory the bot is extracted to.</param>
/// <param name="cToken">The cancellation token.</param>
private async ValueTask InstallToUnixAsync(Stream downloadStream, string installationUri, string botTempLocation, CancellationToken cToken = default)
{
// Extract the tar ball
await TarFile.ExtractToDirectoryAsync(downloadStream, _tempDirectory, true, cToken);
// Move the bot root directory with "mv" to circumvent this issue on Unix systems: https://github.com/dotnet/runtime/issues/31149
using var moveProcess = Utilities.StartProcess("mv", $"\"{botTempLocation}\" \"{installationUri}\"");
await moveProcess.WaitForExitAsync(cToken);
// Set executable permission
using var chmod = Utilities.StartProcess("chmod", $"+x \"{Path.Combine(installationUri, FileName)}\"");
await chmod.WaitForExitAsync(cToken);
}
/// <summary>
/// Installs the Nadeko instance on a non-Unix system.
/// </summary>
/// <param name="downloadStream">The stream of data downloaded from the source.</param>
/// <param name="installationUri">The absolute path to the directory the bot got installed to.</param>
/// <param name="zipTempLocation">The absolute path to the zip file the bot is initially on.</param>
/// <param name="botTempLocation">The absolute path to the temporary directory the bot is extracted to.</param>
/// <param name="cToken">The cancellation token.</param>
private async static ValueTask InstallToWindowsAsync(Stream downloadStream, string installationUri, string zipTempLocation, string botTempLocation, CancellationToken cToken = default)
{
// Save the zip file
using (var fileStream = new FileStream(zipTempLocation, FileMode.Create))
await downloadStream.CopyToAsync(fileStream, cToken);
// Extract the zip file
await Task.Run(() => ZipFile.ExtractToDirectory(zipTempLocation, _tempDirectory), cToken);
// Move the bot root directory while renaming it
Directory.Move(botTempLocation, installationUri);
}
/// <summary>
/// Reaplies the bot settings and user-defined data from the specified backup.
/// </summary>
/// <param name="installationUri">The absolute path to the directory the bot got installed to.</param>
/// <param name="backupFileUri">The absolute path to the backup zip file.</param>
/// <param name="cToken">The cancellation token.</param>
private async static ValueTask ReaplyBotSettingsAsync(string installationUri, string backupFileUri, CancellationToken cToken = default)
{
using var zipFile = ZipFile.OpenRead(backupFileUri);
var zippedFiles = zipFile.Entries
.Where(x =>
x.Name is "creds.yml" or "creds_example.yml"
|| (!string.IsNullOrWhiteSpace(x.Name) && x.FullName.Contains("data/"))
);
foreach (var zippedFile in zippedFiles)
{
var fileDestinationPath = zippedFile.FullName.Split('/')
.Prepend(Directory.GetParent(installationUri)?.FullName ?? string.Empty)
.ToArray();
await RestoreFileAsync(zippedFile, Path.Combine(fileDestinationPath), cToken);
}
}
/// <summary> /// <summary>
/// Extracts the specified <paramref name="zippedFile"/> to the <paramref name="destinationPath"/>. /// Extracts the specified <paramref name="zippedFile"/> to the <paramref name="destinationPath"/>.
/// </summary> /// </summary>

View file

@ -48,7 +48,7 @@ public sealed class LogWriter : ILogWriter
var botEntry = _appConfig.BotEntries[botId]; var botEntry = _appConfig.BotEntries[botId];
var now = DateTimeOffset.Now; var now = DateTimeOffset.Now;
var date = new DateOnly(now.Year, now.Month, now.Day).ToShortDateString().Replace('/', '-'); var date = new DateOnly(now.Year, now.Month, now.Day).ToShortDateString().Replace('/', '-');
var fileUri = Path.Combine(_appConfig.LogsDirectoryUri, $"{botEntry.Name}_{date}-{now.ToUnixTimeSeconds()}.txt"); var fileUri = Path.Combine(_appConfig.LogsDirectoryUri, $"{botEntry.Name}_v{botEntry.Version}_{date}-{now.ToUnixTimeSeconds()}.txt");
await File.WriteAllTextAsync(fileUri, logStringBuilder.ToString(), cToken); await File.WriteAllTextAsync(fileUri, logStringBuilder.ToString(), cToken);

View file

@ -10,7 +10,6 @@ using ReactiveUI;
using SkiaSharp; using SkiaSharp;
using System.Diagnostics; using System.Diagnostics;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Runtime.InteropServices;
namespace EllieHub.ViewModels.Controls; namespace EllieHub.ViewModels.Controls;

View file

@ -1,4 +1,3 @@
using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Styling; using Avalonia.Styling;
using MsBox.Avalonia.Enums; using MsBox.Avalonia.Enums;