Skip to content

Commit

Permalink
Merge branch 'develop' into feature/flags-with-custom-images
Browse files Browse the repository at this point in the history
  • Loading branch information
pre-martin authored Sep 13, 2024
2 parents c97d9b4 + 4dea3dc commit da3a5e8
Show file tree
Hide file tree
Showing 28 changed files with 812 additions and 54 deletions.
2 changes: 2 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ version: 2
updates:
- package-ecosystem: "nuget"
directory: "/" # Location of package manifests
target-branch: "develop"
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/"
target-branch: "develop"
schedule:
interval: "weekly"
15 changes: 8 additions & 7 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ name: "CodeQL"

on:
push:
branches: [ "main", release/* ]
branches: [ "main", release/*, "develop" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "main" ]
branches: [ "main", "develop" ]
schedule:
- cron: '23 3 * * 4'

Expand Down Expand Up @@ -59,18 +59,19 @@ jobs:

# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v3
# - name: Autobuild
# uses: github/codeql-action/autobuild@v3

# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun

# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.

# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Build
run: |
dotnet build StreamDeckSimHub.Plugin/StreamDeckSimHub.Plugin.csproj
dotnet build StreamDeckSimHub.PluginTests/StreamDeckSimHub.PluginTests.csproj
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
Expand Down
17 changes: 11 additions & 6 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# This workflow will build a .NET project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net

name: .NET
name: .NET Build and Test

on:
push:
branches: [ "main" ]
branches: [ "main", "develop" ]
pull_request:
branches: [ "main" ]
branches: [ "main", "develop" ]

jobs:
build:
Expand All @@ -23,8 +23,13 @@ jobs:
with:
dotnet-version: 8.0.x
- name: Restore dependencies
run: dotnet restore
run: |
dotnet restore StreamDeckSimHub.Plugin/StreamDeckSimHub.Plugin.csproj
dotnet restore StreamDeckSimHub.PluginTests/StreamDeckSimHub.PluginTests.csproj
- name: Build
run: dotnet build --no-restore
run: |
dotnet build --no-restore StreamDeckSimHub.Plugin/StreamDeckSimHub.Plugin.csproj
dotnet build --no-restore StreamDeckSimHub.PluginTests/StreamDeckSimHub.PluginTests.csproj
- name: Test
run: dotnet test --no-build --verbosity normal
run: |
dotnet test --no-build --verbosity normal StreamDeckSimHub.PluginTests/StreamDeckSimHub.PluginTests.csproj
3 changes: 3 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@
<Version>3.6.143</Version>
</PackageReference>
</ItemGroup>
<PropertyGroup>
<GitVersionBaseDirectory>$(MSBuildThisFileDirectory)</GitVersionBaseDirectory>
</PropertyGroup>
</Project>
4 changes: 2 additions & 2 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ image::images/teaser/Teaser-2.png[Teaser 2,800]

== Installation

WARNING: To download, do not use the green button! Instead, click on "Releases" on the right side and download the file with extension `streamDeckPlugin`.
WARNING: To download, do not use the green button! Instead, click on "Releases" on the right side and download the installer file.

Be sure to have the SimHub Property Server plugin installed into SimHub (see above). When updating this plugin, be sure to also check the SimHub Property Server plugin for updates.

TIP: For the usage of this plugin, the https://dotnet.microsoft.com/en-us/download/dotnet/8.0[.NET Runtime 8.0] has to be installed. Without this, the plugin won't even start. Download ".NET Desktop Runtime 8.0.x (x64)" from Microsoft.

Download the file `net.planetrenner.simhub.streamDeckPlugin` from the GitHub "Releases" page and double-click it to install it into Stream Deck.
Download the installer from the GitHub "Releases" page and double-click it to install it into Stream Deck.


== Usage
Expand Down
71 changes: 71 additions & 0 deletions StreamDeckSimHub.Installer/Actions/AbstractInstallerAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright (C) 2024 Martin Renner
// LGPL-3.0-or-later (see file COPYING and COPYING.LESSER)

using System.Windows.Media;
using CommunityToolkit.Mvvm.ComponentModel;

namespace StreamDeckSimHub.Installer.Actions;

public abstract partial class AbstractInstallerAction : ObservableObject, IInstallerAction
{
private readonly NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();

public abstract string Name { get; }

[ObservableProperty]
private string _message = string.Empty;

[ObservableProperty]
private Brush _actionResultColor = ActionColors.InactiveBrush;

public async Task<ActionResult> Execute()
{
_logger.Info($"Starting action {GetType().Name}");

ActionResultColor = ActionColors.RunningBrush;
try
{
var result = await ExecuteInternal();
ActionResultColor = result switch
{
ActionResult.Success => ActionColors.SuccessBrush,
ActionResult.Error => ActionColors.ErrorBrush,
ActionResult.NotRequired => ActionColors.InactiveBrush,
ActionResult.Warning => ActionColors.WarningBrush,
_ => throw new ArgumentOutOfRangeException()
};

_logger.Info($"Finished action {GetType().Name} with result {result}");

// Give the user a tiny moment to realize that there is something going on.
await Task.Delay(1000);

return result;
}
catch (Exception e)
{
SetAndLogError(e, $"Action {GetType().Name} failed with exception");
return ActionResult.Error;
}
}

protected abstract Task<ActionResult> ExecuteInternal();

protected void SetAndLogInfo(string message)
{
Message = message;
_logger.Info(message);
}

protected void SetAndLogError(string message)
{
Message = message;
_logger.Info(message);
}

protected void SetAndLogError(Exception e, string message)
{
Message = message;
_logger.Error(e, message);
}
}
51 changes: 51 additions & 0 deletions StreamDeckSimHub.Installer/Actions/IInstallerAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (C) 2024 Martin Renner
// LGPL-3.0-or-later (see file COPYING and COPYING.LESSER)

using System.Windows.Media;

namespace StreamDeckSimHub.Installer.Actions;

public enum ActionResult
{
NotRequired,
Success,
Warning,
Error,
}

public abstract class ActionColors
{
public static readonly Brush InactiveBrush = Brushes.Gray;
public static readonly Brush RunningBrush = Brushes.Orange;
public static readonly Brush SuccessBrush = Brushes.Green;
public static readonly Brush ErrorBrush = Brushes.Red;
public static readonly Brush WarningBrush = Brushes.Yellow;
}

/// <summary>
/// An action that can be executed by the installer.
/// </summary>
/// <remarks>Holds the action logic, but is also misused as a ViewModel.</remarks>
public interface IInstallerAction
{
/// <summary>
/// Displayed as header in the UI.
/// </summary>
string Name { get; }

/// <summary>
/// Detailed message below the header.
/// </summary>
string Message { get; }

/// <summary>
/// Result of the action in the form of a colored brush.
/// </summary>
Brush ActionResultColor { get; }

/// <summary>
/// Executes the action.
/// </summary>
/// <returns>matic result of the action. Is used in the installer logic.</returns>
Task<ActionResult> Execute();
}
88 changes: 88 additions & 0 deletions StreamDeckSimHub.Installer/Actions/InstallStreamDeckPlugin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright (C) 2024 Martin Renner
// LGPL-3.0-or-later (see file COPYING and COPYING.LESSER)

using System.IO;
using System.IO.Compression;
using StreamDeckSimHub.Installer.Tools;

namespace StreamDeckSimHub.Installer.Actions;

public class InstallStreamDeckPlugin : AbstractInstallerAction
{
public override string Name => "Installing Stream Deck SimHub Plugin";

protected override Task<ActionResult> ExecuteInternal()
{
if (Directory.Exists(Path.Combine(Configuration.StreamDeckPluginDir, Configuration.PluginDirName)))
{
SetAndLogInfo("Deleting existing Stream Deck SimHub Plugin");
var result = DeleteExistingInstallation(Path.Combine(Configuration.StreamDeckPluginDir, Configuration.PluginDirName));
if (!result)
{
return Task.FromResult(ActionResult.Error);
}
}

SetAndLogInfo("Installing Stream Deck SimHub Plugin");
if (!ExtractPlugin(Configuration.StreamDeckPluginDir))
{
return Task.FromResult(ActionResult.Error);
}

SetAndLogInfo("Successfully installed Stream Deck SimHub Plugin");
return Task.FromResult(ActionResult.Success);
}

private bool DeleteExistingInstallation(string pluginDir)
{
try
{
// Delete all files in the base directory
var baseDirInfo = new DirectoryInfo(pluginDir);
foreach (var fileInfo in baseDirInfo.EnumerateFiles())
{
fileInfo.Delete();
}

// Delete all directories recursive in the base directory - except "images"
foreach (var dirInfo in baseDirInfo.EnumerateDirectories().Where(dirInfo => dirInfo.Name != "images"))
{
dirInfo.Delete(true);
}

// Delete all directories recursive in the "images" directory - except "custom"
var imagesDirInfo = new DirectoryInfo(Path.Combine(pluginDir, "images"));
foreach (var dirInfo in imagesDirInfo.EnumerateDirectories().Where(dirInfo => dirInfo.Name != "custom"))
{
dirInfo.Delete(true);
}

return true;
}
catch (Exception e)
{
SetAndLogError(e, $"Could not delete existing installation: {e.Message}");
return false;
}
}

private bool ExtractPlugin(string streamDeckPluginDir)
{
var myAssembly = typeof(App).Assembly;
var resourcePaths = myAssembly.GetManifestResourceNames().Where(res => res.EndsWith(Configuration.PluginZipName)).ToList();
if (resourcePaths.Count == 1)
{
using var pluginStream = myAssembly.GetManifestResourceStream(resourcePaths[0]);
if (pluginStream == null)
{
SetAndLogError("Could not find embedded Stream Deck SimHub Plugin (stream is null)");
return false;
}
ZipFile.ExtractToDirectory(pluginStream, streamDeckPluginDir, true);
return true;
}

SetAndLogError($"Could not find embedded Stream Deck SimHub Plugin ({resourcePaths.Count} streams)");
return false;
}
}
38 changes: 38 additions & 0 deletions StreamDeckSimHub.Installer/Actions/StartStreamDeckSoftware.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (C) 2024 Martin Renner
// LGPL-3.0-or-later (see file COPYING and COPYING.LESSER)

using System.IO;
using Microsoft.Win32;
using StreamDeckSimHub.Installer.Tools;

namespace StreamDeckSimHub.Installer.Actions;

/// <summary>
/// Starts the Stream Deck software.
/// </summary>
public class StartStreamDeckSoftware : AbstractInstallerAction
{
public override string Name => "Starting Stream Deck software";

protected override Task<ActionResult> ExecuteInternal()
{
var installFolder = GetStreamDeckInstallFolder();
ProcessTools.StartProcess(Path.Combine(installFolder, "StreamDeck.exe"), installFolder);

SetAndLogInfo("Stream Deck software started");
return Task.FromResult(ActionResult.Success);
}

private string GetStreamDeckInstallFolder()
{
var installPath = (string?) Registry.GetValue(Configuration.StreamDeckRegistryFolder, Configuration.StreamDeckRegistryInstallFolder, null);
if (!string.IsNullOrEmpty(installPath))
{
SetAndLogInfo($"Found Stream Deck directory in registry: {installPath}");
return installPath;
}

SetAndLogInfo($"Could not find Stream Deck directory in registry. Using default.");
return Configuration.StreamDeckDefaultInstallFolder;
}
}
Loading

0 comments on commit da3a5e8

Please sign in to comment.