Remove windows deployments

This commit is contained in:
Zoe Roux 2022-09-28 13:48:57 +09:00
parent 03b05dfc87
commit 9f455b8065
23 changed files with 71 additions and 842 deletions

View File

@ -1,3 +1,5 @@
TVDB__APIKEY= TVDB__APIKEY=
THEMOVIEDB__APIKEY= THEMOVIEDB__APIKEY=
AUTHENTICATION_SECRET= AUTHENTICATION_SECRET=
POSTGRES_USERNAME=
POSTGRES_PASSWORD=

View File

@ -5,3 +5,7 @@ body:
- type: input - type: input
attributes: attributes:
label: "Kyoo's version" label: "Kyoo's version"
- type: textarea
attributes:
label: What happened?
description: Also tell us, what did you expect to happen?

View File

@ -1,3 +1,7 @@
name: Feature Request name: Feature Request
description: Suggest a new feature for Kyoo (don't forget to check projects first) description: Suggest a new feature for Kyoo (don't forget to check projects first)
labels: [enhancement] labels: [enhancement]
body:
- type: textarea
attributes:
label: Feature description

View File

@ -1,184 +0,0 @@
name: Build
on: [push, pull_request, workflow_dispatch]
jobs:
build:
name: "${{matrix.artifact}}'s Build"
runs-on: ${{matrix.os}}
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
runtime: linux-x64
artifact: linux
- os: windows-latest
runtime: win-x64
artifact: windows
- os: macOS-latest
runtime: osx-x64
artifact: macos
outputs:
version: ${{ steps.gitversion.outputs.majorMinorPatch }}
steps:
- uses: actions/checkout@v1
with:
submodules: recursive
fetch-depth: 0
- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: 6.0.x
- name: Install ffmpeg
shell: bash
run: |
if [[ "${{runner.os}}" == "Windows" ]]; then
choco install ffmpeg-shared
elif [[ "${{runner.os}}" == "macOS" ]]; then
brew install ffmpeg
else
sudo apt-get update
sudo apt-get install -y libavutil-dev libavcodec-dev libavformat-dev
fi
- name: Enabling windows compilations tools
if: matrix.artifact == 'windows'
uses: ilammy/msvc-dev-cmd@v1
- name: Select the project to build
shell: bash
run: |
echo "PROJECT=$([ "${{runner.os}}" == "Windows" ] \
&& echo " -p:IncludeConsole=true -p:CheckCodingStyle=false src/Kyoo.Host.WindowsTrait" \
|| echo " -p:CheckCodingStyle=false src/Kyoo.Host.Console")" >> $GITHUB_ENV
- name: Build the app
env:
INCLUDE: ${{env.INCLUDE}};C:\Program Files\FFmpeg\include
LIB: ${{env.LIB}};C:\Program Files\FFmpeg\lib
LIBPATH: ${{env.LIBPATH}};C:\Program Files\FFmpeg\lib
CFLAGS: -I/usr/local/include
LDFLAGS: -L/usr/local/lib
run: dotnet publish -r ${{matrix.runtime}} --self-contained -c Release -o dist ${{env.PROJECT}}
- name: Compression output
shell: bash
run: |
assets=kyoo_${{matrix.artifact}}
if [[ "${{runner.os}}" == "Windows" ]]; then
cd dist
cp -r "/C/Program Files/FFmpeg/bin/." .
7z a "../$assets.zip"
else
rootgrp=$([ "${{runner.os}}" == "macOS" ] && echo wheel || echo root)
sudo chown -R root:$rootgrp dist
tar -C dist -czf "$assets.tar.gz" .
fi
- uses: actions/upload-artifact@v2
with:
name: kyoo_${{matrix.artifact}}
path: |
*.zip
*.tar.gz
- name: Install GitVersion
uses: gittools/actions/gitversion/setup@v0.9.13
with:
versionSpec: '5.x'
- name: Determine Version
id: gitversion
uses: gittools/actions/gitversion/execute@v0.9.13
with:
useConfigFile: true
windows_release:
name: Create windows release
runs-on: windows-latest
needs: build
if: ${{ github.ref == 'refs/heads/master' || contains(github.ref, 'tags') }}
env:
version: ${{ needs.build.outputs.version }}
steps:
- uses: actions/checkout@v1
- name: Download windows build
uses: actions/download-artifact@v2
with:
name: kyoo_windows
path: artifact
- name: Unzip windows files
run: mkdir dist_win && 7z x artifact/kyoo_windows.zip -odist_win
- name: Install Inno Setup
shell: cmd
run: |
curl -L https://jrsoftware.org/download.php/is.exe > innosetup.exe
innosetup.exe /VERYSILENT /SUPPRESSMSGBOXES /Log=log.txt || (cat log.txt && exit 1)
- name: Create windows installer
shell: bash
run: iscc -Dkyoo=$(realpath dist_win) -Dversion=${version} -O./ -Fkyoo-windows deployment/kyoo-windows.iss
- uses: actions/upload-artifact@v2
with:
name: kyoo_windows_installer
path: ./kyoo-windows.exe
release:
name: Create debian, rpm & arch releases
runs-on: ubuntu-latest
needs: build
if: ${{ github.ref == 'refs/heads/master' || contains(github.ref, 'tags') }}
env:
description: "A portable and vast media library solution."
version: ${{ needs.build.outputs.version }}
steps:
- uses: actions/checkout@v1
- name: Download linux build
uses: actions/download-artifact@v2
with:
name: kyoo_linux
path: artifact
- name: Unzip the published files.
run: mkdir dist && tar -C dist -xzf artifact/kyoo_linux.tar.gz
- name: Create the package structure
run: |
sudo mkdir -p pkg/usr/lib/
sudo cp -r --no-preserve ownership dist pkg/usr/lib/kyoo
sudo install -Dm 644 deployment/kyoo.service -t pkg/usr/lib/systemd/system/
sudo install -Dm 644 deployment/kyoo.sysusers pkg/usr/lib/sysusers.d/kyoo.conf
sudo install -Dm 644 deployment/kyoo.tmpfiles pkg/usr/lib/tmpfiles.d/kyoo.conf
- name: Build debian package
uses: jiro4989/build-deb-action@v2
with:
package: kyoo
package_root: pkg
maintainer: Zoe Roux <zoe.roux@sdg.moe>
version: ${{env.version}}
depends: "libavutil-dev, libavcodec-dev, libavformat-dev"
arch: amd64
desc: ${{env.description}}
- name: Build rpm package
run: |
mkdir out
sudo rm -rf pkg/DEBIAN
rpmbuild -bb --buildroot $(pwd)/out --build-in-place --define "_rpmdir $(pwd)/rpm" --define "version_ ${version}" deployment/kyoo.spec
- name: Prepare arch package
run: |
mkdir deployment/output
sed -i s/\$version/${version}/ deployment/PKGBUILD #doing the substitution here since the pkgbuild is run in a docker without env
cp -a pkg/usr deployment/output/usr
- uses: edlanglois/pkgbuild-action@v1
id: makepkg
with:
pkgdir: deployment
namcapDisable: true
- uses: actions/upload-artifact@v2
with:
name: kyoo_rpm
path: ./rpm/x86_64/*.rpm
- uses: actions/upload-artifact@v2
with:
name: kyoo_debian
path: ./*.deb
- uses: actions/upload-artifact@v2
with:
name: kyoo_arch
path: ${{steps.makepkg.outputs.pkgfile0}}

View File

@ -20,13 +20,6 @@ jobs:
repo-token: ${{secrets.GITHUB_TOKEN}} repo-token: ${{secrets.GITHUB_TOKEN}}
running-workflow-name: release running-workflow-name: release
allowed-conclusions: success,skipped,cancelled,neutral allowed-conclusions: success,skipped,cancelled,neutral
- name: Download artifacts
uses: dawidd6/action-download-artifact@v2
with:
commit: ${{env.COMMIT_SHA}}
workflow: build.yml
path: ./artifacts
github_token: ${{secrets.GITHUB_TOKEN}}
# - name: Public the abstractions to nuget # - name: Public the abstractions to nuget
# id: publish_nuget # id: publish_nuget
# uses: rohith/publish-nuget@v2 # uses: rohith/publish-nuget@v2
@ -40,5 +33,4 @@ jobs:
uses: ncipollo/release-action@v1 uses: ncipollo/release-action@v1
with: with:
generateReleaseNotes: true generateReleaseNotes: true
artifacts: ./artifacts/**/*
token: ${{secrets.GITHUB_TOKEN}} token: ${{secrets.GITHUB_TOKEN}}

View File

@ -20,7 +20,7 @@ jobs:
- name: Perform healthchecks - name: Perform healthchecks
run: | run: |
docker-compose ps -a docker-compose ps -a
wget --retry-connrefused http://localhost:5000 # /healthcheck wget --retry-connrefused http://localhost:8901 # /healthcheck
- name: Run robot tests - name: Run robot tests
run: | run: |

View File

@ -1,5 +0,0 @@
Kyoo/
src/
pkg/
kyoo-1.0.0-1-x86_64.pkg.tar.zst

View File

@ -1,28 +0,0 @@
# Maintainer: Zoe Roux <zoe.roux@sdg.moe>
pkgname=kyoo-bin
pkgver=1.0.0
pkgrel=1
epoch=
pkgdesc="A portable and vast media library solution."
arch=("i686" "x86_64" "armv6h")
url="https://github.com/AnonymusRaccoon/Kyoo"
license=("GPLv3")
groups=()
depends=("ffmpeg")
makedepends=()
# The output folder is needed but we can't use directory in the source array.
source=()
sha256sums=()
options=('staticlibs')
pkgver() {
echo $version # The version is available as an environment variable.
}
build() {
cp -a "$srcdir/../output" "$srcdir"
}
package() {
cp -a "$srcdir/output/." "$pkgdir"
}

View File

@ -1,67 +0,0 @@
[Setup]
AppId={{31A61284-7939-46BC-B584-D2279A6EEEE8}
AppName=Kyoo
AppVersion={#version}
AppPublisher=SDG
AppPublisherURL=https://github.com/AnonymusRaccoon/Kyoo
AppSupportURL=https://github.com/AnonymusRaccoon/Kyoo
AppUpdatesURL=https://github.com/AnonymusRaccoon/Kyoo
DefaultDirName={commonpf}\Kyoo
DisableProgramGroupPage=yes
LicenseFile={#kyoo}\LICENSE
SetupIconFile={#kyoo}\wwwroot\icon-256x256.ico
Compression=lzma
SolidCompression=yes
WizardStyle=modern
AppCopyright=GPL-3.0
ArchitecturesInstallIn64BitMode=x64 arm64 ia64
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
Name: "startupShortcut"; Description: "Create shortcut in Startup folder (Starts when you log into Windows)"; GroupDescription: "Start automatically"; Flags: exclusive
Name: "none"; Description: "Do not start automatically"; GroupDescription: "Start automatically"; Flags: exclusive unchecked
[Files]
Source: "{#kyoo}\Kyoo.Host.Console.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#kyoo}\Kyoo.Host.WindowsTrait.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#kyoo}\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
[Registry]
Root: HKA; Subkey: "Software\SDG"; Flags: uninsdeletekeyifempty
Root: HKA; Subkey: "Software\SDG\Kyoo"; Flags: uninsdeletekey
Root: HKA; Subkey: "Software\SDG\Kyoo\Settings"; ValueType: string; ValueName: "DataDir"; ValueData: "{code:GetDataDir}"
[UninstallDelete]
Type: filesandordirs; Name: "{code:GetDataDir}"
[Icons]
Name: "{autoprograms}\Kyoo"; Filename: "{app}\Kyoo.Host.WindowsTrait.exe"
Name: "{autoprograms}\Kyoo (Console)"; Filename: "{app}\Kyoo.Host.Console.exe"
Name: "{autodesktop}\Kyoo"; Filename: "{app}\Kyoo.Host.WindowsTrait.exe"; Tasks: desktopicon
Name: "{autostartup}\Kyoo"; Filename: "{app}\Kyoo.Host.WindowsTrait.exe"; Tasks: startupShortcut
[Run]
Filename: "{app}\Kyoo.Host.WindowsTrait.exe"; Description: "{cm:LaunchProgram,Kyoo}"; Flags: nowait postinstall skipifsilent
[Code]
var
DataDirPage: TInputDirWizardPage;
procedure InitializeWizard;
begin
DataDirPage := CreateInputDirPage(wpSelectDir,
'Choose Data Location', 'Choose the folder in which to install the Kyoo data',
'The installer will set the following folder for Kyoo. To install in a different folder, click Browse and select another folder.' +
'Please make sure the folder exists and is accessible. Do not choose the server install folder. Click Next to continue.',
False, '');
DataDirPage.Add('');
DataDirPage.Values[0] := GetPreviousData('DataDir', 'C:\ProgramData\Kyoo');
end;
function GetDataDir(Param: String): String;
begin
Result := DataDirPage.Values[0];
end;

View File

@ -1,15 +0,0 @@
[Unit]
Description=Kyoo Media Server
After=network.target
[Service]
User=kyoo
Environment=KYOO_DATADIR=/var/lib/kyoo
ExecStart=/usr/lib/kyoo/Kyoo.Host.Console
Restart=on-abort
TimeoutSec=20
StandardOutput=null
StandardError=null
[Install]
WantedBy=multi-user.target

View File

@ -1,26 +0,0 @@
%define _build_id_links none
Name: kyoo
Version: %{version_}
Release: 1%{?dist}
Summary: A portable and vast media library solution.
URL: https://github.com/AnonymusRaccoon/Kyoo
License: GPL-3.0
BuildArch: x86_64
Requires: ffmpeg-devel
AutoReqProv: no
%description
A media browser
%install
cp -a pkg/. %{buildroot}
%clean
rm -rf %{buildroot}
%files
/usr/lib/kyoo
/usr/lib/systemd/system/*
/usr/lib/sysusers.d/kyoo.conf
/usr/lib/tmpfiles.d/kyoo.conf

View File

@ -1 +0,0 @@
u kyoo - "Kyoo Media Server" /var/lib/kyoo

View File

@ -1 +0,0 @@
d /var/lib/kyoo 0755 kyoo kyoo

55
docker-compose.dev.yml Normal file
View File

@ -0,0 +1,55 @@
version: "3.8"
services:
kyoo:
build:
context: ./back
dockerfile: Dockerfile.dev
restart: on-failure
environment:
- KYOO_DATADIR=/var/lib/kyoo
- DATABASE__ENABLED=postgres
- DATABASE__CONFIGURATIONS__POSTGRES__SERVER=postgres
- DATABASE__CONFIGURATIONS__POSTGRES__USER=kyoo
- DATABASE__CONFIGURATIONS__POSTGRES__PASSWORD=kyooPassword
- TVDB__APIKEY=${TVDB__APIKEY}
- THEMOVIEDB__APIKEY=${THEMOVIEDB__APIKEY}
depends_on:
- postgres
volumes:
- kyoo:/var/lib/kyoo
- ./video:/video
front:
build:
context: ./front
dockerfile: Dockerfile.dev
restart: on-failure
environment:
- KYOO_URL=http://kyoo:5000
ingress:
image: nginx
restart: on-failure
environment:
- PORT=8901
- FRONT_URL=http://front:8901
- BACK_URL=http://kyoo:5000
volumes:
- ./nginx.conf.template:/etc/nginx/templates/kyoo.conf.template:ro
depends_on:
- kyoo
- front
ports:
- "8901:8901"
postgres:
image: "postgres"
restart: on-failure
environment:
- POSTGRES_USER=kyoo
- POSTGRES_PASSWORD=kyooPassword
volumes:
- db:/var/lib/postgresql/data
volumes:
kyoo:
db:

View File

@ -2,14 +2,14 @@ version: "3.8"
services: services:
kyoo: kyoo:
build: . build: ./back
restart: on-failure restart: on-failure
environment: environment:
- KYOO_DATADIR=/var/lib/kyoo - KYOO_DATADIR=/var/lib/kyoo
- DATABASE__ENABLED=postgres - DATABASE__ENABLED=postgres
- DATABASE__CONFIGURATIONS__POSTGRES__SERVER=postgres - DATABASE__CONFIGURATIONS__POSTGRES__SERVER=postgres
- DATABASE__CONFIGURATIONS__POSTGRES__USER=kyoo - DATABASE__CONFIGURATIONS__POSTGRES__USER=${POSTGRES_USER}
- DATABASE__CONFIGURATIONS__POSTGRES__PASSWORD=kyooPassword - DATABASE__CONFIGURATIONS__POSTGRES__PASSWORD=${POSTGRES_PASSWORD}
- TVDB__APIKEY=${TVDB__APIKEY} - TVDB__APIKEY=${TVDB__APIKEY}
- THEMOVIEDB__APIKEY=${THEMOVIEDB__APIKEY} - THEMOVIEDB__APIKEY=${THEMOVIEDB__APIKEY}
depends_on: depends_on:
@ -40,8 +40,8 @@ services:
image: "postgres" image: "postgres"
restart: on-failure restart: on-failure
environment: environment:
- POSTGRES_USER=kyoo - POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=kyooPassword - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
volumes: volumes:
- db:/var/lib/postgresql/data - db:/var/lib/postgresql/data

View File

@ -32,7 +32,6 @@ using Kyoo.Swagger;
using Kyoo.TheMovieDb; using Kyoo.TheMovieDb;
using Kyoo.TheTvdb; using Kyoo.TheTvdb;
using Kyoo.Utils; using Kyoo.Utils;
using Kyoo.WebApp;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
@ -77,7 +76,6 @@ namespace Kyoo.Host.Generic
_hostModule = new HostModule(_plugins); _hostModule = new HostModule(_plugins);
_plugins.LoadPlugins( _plugins.LoadPlugins(
typeof(CoreModule), typeof(CoreModule),
typeof(WebAppModule),
typeof(AuthenticationModule), typeof(AuthenticationModule),
typeof(PostgresModule), typeof(PostgresModule),
typeof(SqLiteModule), typeof(SqLiteModule),

View File

@ -1,16 +0,0 @@
<Project>
<Target Name="Build">
<Message Importance="high" Text="Detected current operating system is not windows, skipping WindowsHost build." />
</Target>
<Target Name="Clean"/>
<Target Name="Pack"/>
<Target Name="Restore"/>
<Target Name="Publish">
<Message Importance="high" Text="Detected current operating system is not windows, skipping WindowsHost build." />
</Target>
<ItemGroup>
<None Include="@(Compile)" Visible="true" />
<Compile Remove="*" />
</ItemGroup>
</Project>

View File

@ -1,33 +0,0 @@
<Project ToolsVersion="Current">
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
<PropertyGroup Condition="$(IsWindows) == true">
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<LangVersion>default</LangVersion>
<UseWindowsForms>true</UseWindowsForms>
<AssemblyName>Kyoo.Host.WindowsTrait</AssemblyName>
<RootNamespace>Kyoo.Host.WindowsTrait</RootNamespace>
</PropertyGroup>
<ItemGroup Condition="$(IsWindows) == true">
<ProjectReference Include="../Kyoo.Core/Kyoo.Core.csproj" />
<ProjectReference Include="../Kyoo.Host.Console/Kyoo.Host.Console.csproj" Condition="$(IncludeConsole) == true" />
<None Remove="kyoo.ico" />
<Content Include="kyoo.ico">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<PropertyGroup Condition="$(IsWindows) != true">
<TargetFramework>net6.0</TargetFramework>
<NoWarn>NU1503</NoWarn>
</PropertyGroup>
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
<Import Project="Kyoo.Host.WindowsTrait.Skipped.target" Condition="$(IsWindows) != true" />
<ItemGroup>
<None Remove="*.target" />
</ItemGroup>
</Project>

View File

@ -1,55 +0,0 @@
// Kyoo - A portable and vast media library solution.
// Copyright (c) Kyoo.
//
// See AUTHORS.md and LICENSE file in the project root for full license information.
//
// Kyoo is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// Kyoo is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
using System.Threading.Tasks;
using Autofac;
using Kyoo.Host.Generic;
namespace Kyoo.Host.WindowsTrait
{
/// <summary>
/// Windows's program entrypoint.
/// </summary>
public static class Program
{
/// <summary>
/// The string representation of the environment used in IWebHostEnvironment.
/// </summary>
#if DEBUG
private const string Environment = "Development";
#else
private const string Environment = "Production";
#endif
/// <summary>
/// The main entry point for the application that overrides the default host.
/// It adds a system trait for windows and since the host is build as a windows executable instead of a console
/// app, the console is not showed.
/// </summary>
/// <param name="args">Command line arguments</param>
/// <returns>A <see cref="Task"/> representing the lifetime of the program.</returns>
public static Task Main(string[] args)
{
Application application = new(Environment);
return application.Start(args, builder =>
{
builder.RegisterType<SystemTrait>().As<IStartable>().SingleInstance();
});
}
}
}

View File

@ -1,182 +0,0 @@
// Kyoo - A portable and vast media library solution.
// Copyright (c) Kyoo.
//
// See AUTHORS.md and LICENSE file in the project root for full license information.
//
// Kyoo is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// Kyoo is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using Autofac;
using Kyoo.Abstractions.Controllers;
using Kyoo.Core.Models.Options;
using Microsoft.Extensions.Options;
namespace Kyoo.Host.WindowsTrait
{
/// <summary>
/// A singleton that add an notification icon on the window's toolbar.
/// </summary>
public sealed class SystemTrait : IStartable, IDisposable
{
/// <summary>
/// The application running Kyoo.
/// </summary>
private readonly IApplication _application;
/// <summary>
/// The options containing the <see cref="BasicOptions.Url"/>.
/// </summary>
private readonly IOptions<BasicOptions> _options;
/// <summary>
/// The thread where the trait is running.
/// </summary>
private Thread _thread;
/// <summary>
/// Create a new <see cref="SystemTrait"/>.
/// </summary>
/// <param name="application">The application running Kyoo.</param>
/// <param name="options">The options to use.</param>
public SystemTrait(IApplication application, IOptions<BasicOptions> options)
{
_application = application;
_options = options;
}
/// <inheritdoc />
public void Start()
{
_thread = new Thread(() => InternalSystemTrait.Run(_application, _options))
{
IsBackground = true
};
_thread.Start();
}
/// <inheritdoc />
public void Dispose()
{
Application.Exit();
_thread?.Join();
_thread = null;
}
/// <summary>
/// The internal class for <see cref="SystemTrait"/>. It should be invoked via
/// <see cref="InternalSystemTrait.Run"/>.
/// </summary>
private class InternalSystemTrait : ApplicationContext
{
/// <summary>
/// The application running Kyoo.
/// </summary>
private readonly IApplication _application;
/// <summary>
/// The options containing the <see cref="BasicOptions.Url"/>.
/// </summary>
private readonly IOptions<BasicOptions> _options;
/// <summary>
/// The Icon that is displayed in the window's bar.
/// </summary>
private readonly NotifyIcon _icon;
/// <summary>
/// Create a new <see cref="InternalSystemTrait"/>. Used only by <see cref="Run"/>.
/// </summary>
/// <param name="application">The application running Kyoo.</param>
/// <param name="options">The option containing the public url.</param>
private InternalSystemTrait(IApplication application, IOptions<BasicOptions> options)
{
_application = application;
_options = options;
AppDomain.CurrentDomain.ProcessExit += (_, _) => Dispose();
Application.ApplicationExit += (_, _) => Dispose();
_icon = new NotifyIcon
{
Text = "Kyoo",
Icon = new Icon(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "kyoo.ico")),
Visible = true
};
_icon.MouseClick += (_, e) =>
{
if (e.Button != MouseButtons.Left)
return;
_StartBrowser();
};
_icon.ContextMenuStrip = new ContextMenuStrip();
_icon.ContextMenuStrip.Items.AddRange(new ToolStripItem[]
{
new ToolStripMenuItem("Open browser", null, (_, _) => { _StartBrowser(); }),
new ToolStripMenuItem("Open logs", null, (_, _) => { _OpenLogs(); }),
new ToolStripSeparator(),
new ToolStripMenuItem("Exit", null, (_, _) => { _application.Shutdown(); })
});
}
/// <summary>
/// Run the trait in the current thread, this method does not return while the trait is running.
/// </summary>
/// <param name="application">The application running Kyoo.</param>
/// <param name="options">The options to pass to <see cref="InternalSystemTrait"/>.</param>
public static void Run(IApplication application, IOptions<BasicOptions> options)
{
using InternalSystemTrait trait = new(application, options);
Application.Run(trait);
}
/// <inheritdoc />
protected override void Dispose(bool disposing)
{
_icon.Visible = false;
base.Dispose(disposing);
_icon.Dispose();
}
/// <summary>
/// Open kyoo's page in the user's default browser.
/// </summary>
private void _StartBrowser()
{
Process browser = new()
{
StartInfo = new ProcessStartInfo(_options.Value.Url.ToString().Replace("//*:", "//localhost:"))
{
UseShellExecute = true
}
};
browser.Start();
}
/// <summary>
/// Open the log directory in windows's explorer.
/// </summary>
private void _OpenLogs()
{
string logDir = Path.Combine(_application.GetDataDirectory(), "logs");
Process.Start("explorer.exe", logDir);
}
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,78 +0,0 @@
<Project>
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
<PropertyGroup>
<AssemblyName>Kyoo.WebApp</AssemblyName>
<RootNamespace>Kyoo.WebApp</RootNamespace>
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
<TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
<IsPackable>false</IsPackable>
<DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules/**</DefaultItemExcludes>
<SpaRoot>../../front/</SpaRoot>
<Icons>../../icons/</Icons>
<NpmStamp>$(SpaRoot)node_modules/.install-stamp</NpmStamp>
<!-- Set this to true if you enable server-side prerendering -->
<BuildServerSideRenderer>false</BuildServerSideRenderer>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="5.0.0-preview.8.20414.8" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="5.0.8" />
<ProjectReference Include="../Kyoo.Abstractions/Kyoo.Abstractions.csproj" />
</ItemGroup>
<ItemGroup>
<Content Remove="$(SpaRoot)**" />
<Compile Remove="$(SpaRoot)**" />
<None Remove="$(SpaRoot)dist/**; $(SpaRoot)dist-server/**" />
<Content Include="$(Icons)**" Visible="false">
<Link>wwwroot/%(RecursiveDir)%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="$(SpaRoot)static/**" Visible="false">
<Link>wwwroot/%(RecursiveDir)%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<Target Name="NpmInstall" BeforeTargets="RunWebpack" Inputs="$(SpaRoot)/package.json" Outputs="$(NpmStamp)" Condition="$(SkipWebApp) != true">
<Exec Command="node --version" ContinueOnError="true">
<Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
</Exec>
<Error Condition="'$(ErrorCode)' != '0'" Text="Node.js is required to build and run this project. To continue, please install Node.js from https://nodejs.org/, and then restart your command prompt or IDE." />
<Message Importance="high" Text="Restoring dependencies using 'yarn'. This may take several minutes..." />
<Exec WorkingDirectory="$(SpaRoot)" Command="yarn install" />
<Touch Files="$(NpmStamp)" AlwaysCreate="true" />
</Target>
<Target Name="RunWebpack" Condition="'$(SkipWebApp)' != 'true' And '$(Configuration)' == 'Release'">
<Message Importance="high" Text="Building the web app. This may take several minutes..." />
<Exec WorkingDirectory="$(SpaRoot)" Command="yarn run build --configuration production" />
<Exec WorkingDirectory="$(SpaRoot)" Command="yarn run build:ssr --configuration production" Condition="'$(BuildServerSideRenderer)' == 'true'" />
</Target>
<Target Name="CopyFrontEndFiles" AfterTargets="RunWebpack" BeforeTargets="GetCopyToOutputDirectoryItems" Condition="'$(Configuration)' != 'Debug'">
<ItemGroup>
<NewContent Include="$(SpaRoot)dist/**; $(SpaRoot)dist-server/**" Visible="false" />
<Content Include="@(NewContent)">
<Link>wwwroot/%(NewContent.RecursiveDir)%(NewContent.Filename)%(NewContent.Extension)</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Target>
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
<PropertyGroup>
<BuildDependsOn>
NpmInstall;
RunWebpack;
$(BuildDependsOn)
</BuildDependsOn>
</PropertyGroup>
</Project>

View File

@ -1,135 +0,0 @@
// Kyoo - A portable and vast media library solution.
// Copyright (c) Kyoo.
//
// See AUTHORS.md and LICENSE file in the project root for full license information.
//
// Kyoo is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// Kyoo is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using Kyoo.Abstractions.Controllers;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.SpaServices.AngularCli;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace Kyoo.WebApp
{
/// <summary>
/// A module to enable the web-app (the front-end of kyoo).
/// </summary>
public class WebAppModule : IPlugin
{
/// <inheritdoc />
public string Slug => "webapp";
/// <inheritdoc />
public string Name => "WebApp";
/// <inheritdoc />
public string Description => "A module to enable the web-app (the front-end of kyoo).";
/// <inheritdoc />
public Dictionary<string, Type> Configuration => new();
/// <inheritdoc />
public bool Enabled => false; // Directory.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wwwroot"));
/// <summary>
/// Create a new <see cref="WebAppModule"/>.
/// </summary>
/// <param name="logger">A logger only used to inform the user if the webapp could not be enabled.</param>
public WebAppModule(ILogger<WebAppModule> logger)
{
if (!Enabled)
logger.LogError("The web app files could not be found, it will be disabled");
}
/// <inheritdoc />
public void Configure(IServiceCollection services)
{
services.AddSpaStaticFiles(x =>
{
x.RootPath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "wwwroot");
});
}
/// <inheritdoc />
public IEnumerable<IStartupAction> ConfigureSteps => new IStartupAction[]
{
SA.New<IApplicationBuilder, IWebHostEnvironment>((app, env) =>
{
if (!env.IsDevelopment())
app.UseSpaStaticFiles();
}, SA.StaticFiles),
SA.New<IApplicationBuilder, IContentTypeProvider>((app, contentTypeProvider) =>
{
app.UseStaticFiles(new StaticFileOptions
{
ContentTypeProvider = contentTypeProvider,
FileProvider = new PhysicalFileProvider(Path.Join(AppDomain.CurrentDomain.BaseDirectory, "wwwroot"))
});
}, SA.StaticFiles),
SA.New<IApplicationBuilder>(app =>
{
app.Use((ctx, next) =>
{
ctx.Response.Headers.Remove("X-Powered-By");
ctx.Response.Headers.Remove("Server");
ctx.Response.Headers.Add("Feature-Policy", "autoplay 'self'; fullscreen");
ctx.Response.Headers.Add("Content-Security-Policy", "default-src 'self' blob:; script-src 'self' blob: 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src 'self'");
ctx.Response.Headers.Add("X-Frame-Options", "SAMEORIGIN");
ctx.Response.Headers.Add("Referrer-Policy", "no-referrer");
ctx.Response.Headers.Add("Access-Control-Allow-Origin", "null");
ctx.Response.Headers.Add("X-Content-Type-Options", "nosniff");
return next();
});
}, SA.Endpoint - 499),
SA.New<IApplicationBuilder, IWebHostEnvironment>((app, env) =>
{
app.UseSpa(spa =>
{
spa.Options.SourcePath = _GetSpaSourcePath();
if (env.IsDevelopment())
spa.UseAngularCliServer("start");
});
}, SA.Endpoint - 500)
};
/// <summary>
/// Get the root directory of the web app
/// </summary>
/// <returns>The path of the source code of the web app or null if the directory has been deleted.</returns>
private static string _GetSpaSourcePath()
{
static string GetRepoRootPath([CallerFilePath] string path = null)
{
// path is {RepoRoot}/src/Kyoo.WebApp/WebAppModules.cs
for (int i = 0; i < 3; i++)
path = Path.GetDirectoryName(path);
return path;
}
string path = Path.Join(GetRepoRootPath(), "front");
return Directory.Exists(path) ? path : null;
}
}
}