aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Server/Program.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Jellyfin.Server/Program.cs')
-rw-r--r--Jellyfin.Server/Program.cs144
1 files changed, 57 insertions, 87 deletions
diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs
index ac5aab460..d4b10c8c8 100644
--- a/Jellyfin.Server/Program.cs
+++ b/Jellyfin.Server/Program.cs
@@ -12,7 +12,6 @@ using System.Threading.Tasks;
using CommandLine;
using Emby.Drawing;
using Emby.Server.Implementations;
-using Emby.Server.Implementations.EnvironmentInfo;
using Emby.Server.Implementations.IO;
using Emby.Server.Implementations.Networking;
using Jellyfin.Drawing.Skia;
@@ -35,6 +34,7 @@ namespace Jellyfin.Server
private static readonly ILoggerFactory _loggerFactory = new SerilogLoggerFactory();
private static ILogger _logger;
private static bool _restartOnShutdown;
+ private static IConfiguration appConfig;
public static async Task Main(string[] args)
{
@@ -44,7 +44,6 @@ namespace Jellyfin.Server
const string pattern = @"^(-[^-\s]{2})"; // Match -xx, not -x, not --xx, not xx
const string substitution = @"-$1"; // Prepend with additional single-hyphen
var regex = new Regex(pattern);
-
for (var i = 0; i < args.Length; i++)
{
args[i] = regex.Replace(args[i], substitution);
@@ -52,9 +51,7 @@ namespace Jellyfin.Server
// Parse the command line arguments and either start the app or exit indicating error
await Parser.Default.ParseArguments<StartupOptions>(args)
- .MapResult(
- options => StartApp(options),
- errs => Task.FromResult(0)).ConfigureAwait(false);
+ .MapResult(StartApp, _ => Task.CompletedTask).ConfigureAwait(false);
}
public static void Shutdown()
@@ -78,7 +75,11 @@ namespace Jellyfin.Server
// $JELLYFIN_LOG_DIR needs to be set for the logger configuration manager
Environment.SetEnvironmentVariable("JELLYFIN_LOG_DIR", appPaths.LogDirectoryPath);
- await CreateLogger(appPaths).ConfigureAwait(false);
+
+ appConfig = await CreateConfiguration(appPaths).ConfigureAwait(false);
+
+ CreateLogger(appConfig, appPaths);
+
_logger = _loggerFactory.CreateLogger("Main");
AppDomain.CurrentDomain.UnhandledException += (sender, e)
@@ -113,32 +114,29 @@ namespace Jellyfin.Server
_logger.LogInformation("Jellyfin version: {Version}", Assembly.GetEntryAssembly().GetName().Version);
- EnvironmentInfo environmentInfo = new EnvironmentInfo(GetOperatingSystem());
- ApplicationHost.LogEnvironmentInfo(_logger, appPaths, environmentInfo);
+ ApplicationHost.LogEnvironmentInfo(_logger, appPaths);
SQLitePCL.Batteries_V2.Init();
// Allow all https requests
- ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return true; } );
+ ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return true; });
- var fileSystem = new ManagedFileSystem(_loggerFactory, environmentInfo, null, appPaths.TempDirectory, true);
+ var fileSystem = new ManagedFileSystem(_loggerFactory, appPaths);
using (var appHost = new CoreAppHost(
appPaths,
_loggerFactory,
options,
fileSystem,
- environmentInfo,
new NullImageEncoder(),
- new NetworkManager(_loggerFactory, environmentInfo)))
+ new NetworkManager(_loggerFactory),
+ appConfig))
{
- await appHost.Init(new ServiceCollection()).ConfigureAwait(false);
+ await appHost.InitAsync(new ServiceCollection()).ConfigureAwait(false);
appHost.ImageProcessor.ImageEncoder = GetImageEncoder(fileSystem, appPaths, appHost.LocalizationManager);
- await appHost.RunStartupTasks().ConfigureAwait(false);
-
- // TODO: read input for a stop command
+ await appHost.RunStartupTasksAsync().ConfigureAwait(false);
try
{
@@ -169,35 +167,19 @@ namespace Jellyfin.Server
{
// dataDir
// IF --datadir
- // ELSE IF $JELLYFIN_DATA_PATH
+ // ELSE IF $JELLYFIN_DATA_DIR
// ELSE IF windows, use <%APPDATA%>/jellyfin
// ELSE IF $XDG_DATA_HOME then use $XDG_DATA_HOME/jellyfin
// ELSE use $HOME/.local/share/jellyfin
var dataDir = options.DataDir;
-
if (string.IsNullOrEmpty(dataDir))
{
- dataDir = Environment.GetEnvironmentVariable("JELLYFIN_DATA_PATH");
+ dataDir = Environment.GetEnvironmentVariable("JELLYFIN_DATA_DIR");
if (string.IsNullOrEmpty(dataDir))
{
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- dataDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
- }
- else
- {
- // $XDG_DATA_HOME defines the base directory relative to which user specific data files should be stored.
- dataDir = Environment.GetEnvironmentVariable("XDG_DATA_HOME");
-
- // If $XDG_DATA_HOME is either not set or empty, a default equal to $HOME/.local/share should be used.
- if (string.IsNullOrEmpty(dataDir))
- {
- dataDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "share");
- }
- }
-
- dataDir = Path.Combine(dataDir, "jellyfin");
+ // LocalApplicationData follows the XDG spec on unix machines
+ dataDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "jellyfin");
}
}
@@ -210,7 +192,6 @@ namespace Jellyfin.Server
// ELSE IF $XDG_CONFIG_HOME use $XDG_CONFIG_HOME/jellyfin
// ELSE $HOME/.config/jellyfin
var configDir = options.ConfigDir;
-
if (string.IsNullOrEmpty(configDir))
{
configDir = Environment.GetEnvironmentVariable("JELLYFIN_CONFIG_DIR");
@@ -245,7 +226,6 @@ namespace Jellyfin.Server
// ELSE IF XDG_CACHE_HOME, use $XDG_CACHE_HOME/jellyfin
// ELSE HOME/.cache/jellyfin
var cacheDir = options.CacheDir;
-
if (string.IsNullOrEmpty(cacheDir))
{
cacheDir = Environment.GetEnvironmentVariable("JELLYFIN_CACHE_DIR");
@@ -273,13 +253,29 @@ namespace Jellyfin.Server
}
}
+ // webDir
+ // IF --webdir
+ // ELSE IF $JELLYFIN_WEB_DIR
+ // ELSE use <bindir>/jellyfin-web
+ var webDir = options.WebDir;
+
+ if (string.IsNullOrEmpty(webDir))
+ {
+ webDir = Environment.GetEnvironmentVariable("JELLYFIN_WEB_DIR");
+
+ if (string.IsNullOrEmpty(webDir))
+ {
+ // Use default location under ResourcesPath
+ webDir = Path.Combine(AppContext.BaseDirectory, "jellyfin-web", "src");
+ }
+ }
+
// logDir
// IF --logdir
// ELSE IF $JELLYFIN_LOG_DIR
// ELSE IF --datadir, use <datadir>/log (assume portable run)
// ELSE <datadir>/log
var logDir = options.LogDir;
-
if (string.IsNullOrEmpty(logDir))
{
logDir = Environment.GetEnvironmentVariable("JELLYFIN_LOG_DIR");
@@ -306,32 +302,36 @@ namespace Jellyfin.Server
Environment.Exit(1);
}
- return new ServerApplicationPaths(dataDir, logDir, configDir, cacheDir);
+ return new ServerApplicationPaths(dataDir, logDir, configDir, cacheDir, webDir);
}
- private static async Task CreateLogger(IApplicationPaths appPaths)
+ private static async Task<IConfiguration> CreateConfiguration(IApplicationPaths appPaths)
{
- try
- {
- string configPath = Path.Combine(appPaths.ConfigurationDirectoryPath, "logging.json");
+ string configPath = Path.Combine(appPaths.ConfigurationDirectoryPath, "logging.json");
- if (!File.Exists(configPath))
+ if (!File.Exists(configPath))
+ {
+ // For some reason the csproj name is used instead of the assembly name
+ using (Stream rscstr = typeof(Program).Assembly
+ .GetManifestResourceStream("Jellyfin.Server.Resources.Configuration.logging.json"))
+ using (Stream fstr = File.Open(configPath, FileMode.CreateNew))
{
- // For some reason the csproj name is used instead of the assembly name
- using (Stream rscstr = typeof(Program).Assembly
- .GetManifestResourceStream("Jellyfin.Server.Resources.Configuration.logging.json"))
- using (Stream fstr = File.Open(configPath, FileMode.CreateNew))
- {
- await rscstr.CopyToAsync(fstr).ConfigureAwait(false);
- }
+ await rscstr.CopyToAsync(fstr).ConfigureAwait(false);
}
+ }
- var configuration = new ConfigurationBuilder()
- .SetBasePath(appPaths.ConfigurationDirectoryPath)
- .AddJsonFile("logging.json")
- .AddEnvironmentVariables("JELLYFIN_")
- .Build();
+ return new ConfigurationBuilder()
+ .SetBasePath(appPaths.ConfigurationDirectoryPath)
+ .AddJsonFile("logging.json")
+ .AddEnvironmentVariables("JELLYFIN_")
+ .AddInMemoryCollection(ConfigurationOptions.Configuration)
+ .Build();
+ }
+ private static void CreateLogger(IConfiguration configuration, IApplicationPaths appPaths)
+ {
+ try
+ {
// Serilog.Log is used by SerilogLoggerFactory when no logger is specified
Serilog.Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
@@ -370,36 +370,6 @@ namespace Jellyfin.Server
return new NullImageEncoder();
}
- private static MediaBrowser.Model.System.OperatingSystem GetOperatingSystem()
- {
- switch (Environment.OSVersion.Platform)
- {
- case PlatformID.MacOSX:
- return MediaBrowser.Model.System.OperatingSystem.OSX;
- case PlatformID.Win32NT:
- return MediaBrowser.Model.System.OperatingSystem.Windows;
- case PlatformID.Unix:
- default:
- {
- string osDescription = RuntimeInformation.OSDescription;
- if (osDescription.Contains("linux", StringComparison.OrdinalIgnoreCase))
- {
- return MediaBrowser.Model.System.OperatingSystem.Linux;
- }
- else if (osDescription.Contains("darwin", StringComparison.OrdinalIgnoreCase))
- {
- return MediaBrowser.Model.System.OperatingSystem.OSX;
- }
- else if (osDescription.Contains("bsd", StringComparison.OrdinalIgnoreCase))
- {
- return MediaBrowser.Model.System.OperatingSystem.BSD;
- }
-
- throw new Exception($"Can't resolve OS with description: '{osDescription}'");
- }
- }
- }
-
private static void StartNewInstance(StartupOptions options)
{
_logger.LogInformation("Starting new instance");