Merge branch 'master' into fix-env

This commit is contained in:
Joshua M. Boniface 2019-02-03 22:34:40 -05:00 committed by GitHub
commit 20033f2275
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
70 changed files with 495 additions and 440 deletions

View File

@ -15,6 +15,7 @@
- [cvium](https://github.com/cvium) - [cvium](https://github.com/cvium)
- [wtayl0r](https://github.com/wtayl0r) - [wtayl0r](https://github.com/wtayl0r)
- [TtheCreator](https://github.com/Tthecreator) - [TtheCreator](https://github.com/Tthecreator)
- [dkanada](https://github.com/dkanada)
- [LogicalPhallacy](https://github.com/LogicalPhallacy/) - [LogicalPhallacy](https://github.com/LogicalPhallacy/)
- [RazeLighter777](https://github.com/RazeLighter777) - [RazeLighter777](https://github.com/RazeLighter777)

View File

@ -4,6 +4,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Emby.Dlna.Profiles; using Emby.Dlna.Profiles;
using Emby.Dlna.Server; using Emby.Dlna.Server;
using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Configuration;
@ -48,11 +49,11 @@ namespace Emby.Dlna
_assemblyInfo = assemblyInfo; _assemblyInfo = assemblyInfo;
} }
public void InitProfiles() public async Task InitProfilesAsync()
{ {
try try
{ {
ExtractSystemProfiles(); await ExtractSystemProfilesAsync();
LoadProfiles(); LoadProfiles();
} }
catch (Exception ex) catch (Exception ex)
@ -359,7 +360,7 @@ namespace Emby.Dlna
}; };
} }
private void ExtractSystemProfiles() private async Task ExtractSystemProfilesAsync()
{ {
var namespaceName = GetType().Namespace + ".Profiles.Xml."; var namespaceName = GetType().Namespace + ".Profiles.Xml.";
@ -383,7 +384,7 @@ namespace Emby.Dlna
using (var fileStream = _fileSystem.GetFileStream(path, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read)) using (var fileStream = _fileSystem.GetFileStream(path, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
{ {
stream.CopyTo(fileStream); await stream.CopyToAsync(fileStream);
} }
} }
} }

View File

@ -125,9 +125,9 @@ namespace Emby.Dlna.Main
Current = this; Current = this;
} }
public void Run() public async Task RunAsync()
{ {
((DlnaManager)_dlnaManager).InitProfiles(); await ((DlnaManager)_dlnaManager).InitProfilesAsync().ConfigureAwait(false);
ReloadComponents(); ReloadComponents();

View File

@ -71,12 +71,14 @@ namespace Emby.Notifications
_coreNotificationTypes = new CoreNotificationTypes(localization, appHost).GetNotificationTypes().Select(i => i.Type).ToArray(); _coreNotificationTypes = new CoreNotificationTypes(localization, appHost).GetNotificationTypes().Select(i => i.Type).ToArray();
} }
public void Run() public Task RunAsync()
{ {
_libraryManager.ItemAdded += _libraryManager_ItemAdded; _libraryManager.ItemAdded += _libraryManager_ItemAdded;
_appHost.HasPendingRestartChanged += _appHost_HasPendingRestartChanged; _appHost.HasPendingRestartChanged += _appHost_HasPendingRestartChanged;
_appHost.HasUpdateAvailableChanged += _appHost_HasUpdateAvailableChanged; _appHost.HasUpdateAvailableChanged += _appHost_HasUpdateAvailableChanged;
_activityManager.EntryCreated += _activityManager_EntryCreated; _activityManager.EntryCreated += _activityManager_EntryCreated;
return Task.CompletedTask;
} }
private async void _appHost_HasPendingRestartChanged(object sender, EventArgs e) private async void _appHost_HasPendingRestartChanged(object sender, EventArgs e)

View File

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks;
using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Plugins; using MediaBrowser.Common.Plugins;
using MediaBrowser.Common.Updates; using MediaBrowser.Common.Updates;
@ -58,7 +59,7 @@ namespace Emby.Server.Implementations.Activity
_deviceManager = deviceManager; _deviceManager = deviceManager;
} }
public void Run() public Task RunAsync()
{ {
_taskManager.TaskCompleted += _taskManager_TaskCompleted; _taskManager.TaskCompleted += _taskManager_TaskCompleted;
@ -90,6 +91,8 @@ namespace Emby.Server.Implementations.Activity
_deviceManager.CameraImageUploaded += _deviceManager_CameraImageUploaded; _deviceManager.CameraImageUploaded += _deviceManager_CameraImageUploaded;
_appHost.ApplicationUpdated += _appHost_ApplicationUpdated; _appHost.ApplicationUpdated += _appHost_ApplicationUpdated;
return Task.CompletedTask;
} }
void _deviceManager_CameraImageUploaded(object sender, GenericEventArgs<CameraImageUploadInfo> e) void _deviceManager_CameraImageUploaded(object sender, GenericEventArgs<CameraImageUploadInfo> e)

View File

@ -110,7 +110,6 @@ using MediaBrowser.XbmcMetadata.Providers;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using ServiceStack; using ServiceStack;
using ServiceStack.Text.Jsv; using ServiceStack.Text.Jsv;
using StringExtensions = MediaBrowser.Controller.Extensions.StringExtensions;
using X509Certificate = System.Security.Cryptography.X509Certificates.X509Certificate; using X509Certificate = System.Security.Cryptography.X509Certificates.X509Certificate;
namespace Emby.Server.Implementations namespace Emby.Server.Implementations
@ -302,7 +301,7 @@ namespace Emby.Server.Implementations
private ILiveTvManager LiveTvManager { get; set; } private ILiveTvManager LiveTvManager { get; set; }
public ILocalizationManager LocalizationManager { get; set; } public LocalizationManager LocalizationManager { get; set; }
private IEncodingManager EncodingManager { get; set; } private IEncodingManager EncodingManager { get; set; }
private IChannelManager ChannelManager { get; set; } private IChannelManager ChannelManager { get; set; }
@ -646,8 +645,10 @@ namespace Emby.Server.Implementations
/// <summary> /// <summary>
/// Runs the startup tasks. /// Runs the startup tasks.
/// </summary> /// </summary>
public Task RunStartupTasks() public async Task RunStartupTasks()
{ {
Logger.LogInformation("Running startup tasks");
Resolve<ITaskManager>().AddTasks(GetExports<IScheduledTask>(false)); Resolve<ITaskManager>().AddTasks(GetExports<IScheduledTask>(false));
ConfigurationManager.ConfigurationUpdated += OnConfigurationUpdated; ConfigurationManager.ConfigurationUpdated += OnConfigurationUpdated;
@ -666,20 +667,20 @@ namespace Emby.Server.Implementations
Logger.LogInformation("ServerId: {0}", SystemId); Logger.LogInformation("ServerId: {0}", SystemId);
var entryPoints = GetExports<IServerEntryPoint>(); var entryPoints = GetExports<IServerEntryPoint>();
RunEntryPoints(entryPoints, true);
var now = DateTime.UtcNow;
await Task.WhenAll(StartEntryPoints(entryPoints, true));
Logger.LogInformation("Executed all pre-startup entry points in {Elapsed:fff} ms", DateTime.Now - now);
Logger.LogInformation("Core startup complete"); Logger.LogInformation("Core startup complete");
HttpServer.GlobalResponse = null; HttpServer.GlobalResponse = null;
Logger.LogInformation("Post-init migrations complete"); now = DateTime.UtcNow;
await Task.WhenAll(StartEntryPoints(entryPoints, false));
RunEntryPoints(entryPoints, false); Logger.LogInformation("Executed all post-startup entry points in {Elapsed:fff} ms", DateTime.Now - now);
Logger.LogInformation("All entry points have started");
return Task.CompletedTask;
} }
private void RunEntryPoints(IEnumerable<IServerEntryPoint> entryPoints, bool isBeforeStartup) private IEnumerable<Task> StartEntryPoints(IEnumerable<IServerEntryPoint> entryPoints, bool isBeforeStartup)
{ {
foreach (var entryPoint in entryPoints) foreach (var entryPoint in entryPoints)
{ {
@ -688,22 +689,13 @@ namespace Emby.Server.Implementations
continue; continue;
} }
var name = entryPoint.GetType().FullName; Logger.LogDebug("Starting entry point {Type}", entryPoint.GetType());
Logger.LogInformation("Starting entry point {Name}", name);
var now = DateTime.UtcNow; yield return entryPoint.RunAsync();
try
{
entryPoint.Run();
}
catch (Exception ex)
{
Logger.LogError(ex, "Error while running entrypoint {Name}", name);
}
Logger.LogInformation("Entry point completed: {Name}. Duration: {Duration} seconds", name, (DateTime.UtcNow - now).TotalSeconds.ToString(CultureInfo.InvariantCulture), "ImageInfos");
} }
} }
public void Init() public async Task Init()
{ {
HttpPort = ServerConfigurationManager.Configuration.HttpServerPortNumber; HttpPort = ServerConfigurationManager.Configuration.HttpServerPortNumber;
HttpsPort = ServerConfigurationManager.Configuration.HttpsPortNumber; HttpsPort = ServerConfigurationManager.Configuration.HttpsPortNumber;
@ -733,7 +725,7 @@ namespace Emby.Server.Implementations
SetHttpLimit(); SetHttpLimit();
RegisterResources(); await RegisterResources();
FindParts(); FindParts();
} }
@ -748,7 +740,7 @@ namespace Emby.Server.Implementations
/// <summary> /// <summary>
/// Registers resources that classes will depend on /// Registers resources that classes will depend on
/// </summary> /// </summary>
protected void RegisterResources() protected async Task RegisterResources()
{ {
RegisterSingleInstance(ConfigurationManager); RegisterSingleInstance(ConfigurationManager);
RegisterSingleInstance<IApplicationHost>(this); RegisterSingleInstance<IApplicationHost>(this);
@ -809,9 +801,9 @@ namespace Emby.Server.Implementations
IAssemblyInfo assemblyInfo = new AssemblyInfo(); IAssemblyInfo assemblyInfo = new AssemblyInfo();
RegisterSingleInstance(assemblyInfo); RegisterSingleInstance(assemblyInfo);
LocalizationManager = new LocalizationManager(ServerConfigurationManager, FileSystemManager, JsonSerializer, LoggerFactory, assemblyInfo, new TextLocalizer()); LocalizationManager = new LocalizationManager(ServerConfigurationManager, FileSystemManager, JsonSerializer, LoggerFactory);
StringExtensions.LocalizationManager = LocalizationManager; await LocalizationManager.LoadAll();
RegisterSingleInstance(LocalizationManager); RegisterSingleInstance<ILocalizationManager>(LocalizationManager);
BlurayExaminer = new BdInfoExaminer(FileSystemManager); BlurayExaminer = new BdInfoExaminer(FileSystemManager);
RegisterSingleInstance(BlurayExaminer); RegisterSingleInstance(BlurayExaminer);

View File

@ -353,7 +353,7 @@ namespace Emby.Server.Implementations.Collections
_logger = logger; _logger = logger;
} }
public async void Run() public async Task RunAsync()
{ {
if (!_config.Configuration.CollectionsUpgraded && _config.Configuration.IsStartupWizardCompleted) if (!_config.Configuration.CollectionsUpgraded && _config.Configuration.IsStartupWizardCompleted)
{ {

View File

@ -425,7 +425,7 @@ namespace Emby.Server.Implementations.Devices
_logger = logger; _logger = logger;
} }
public async void Run() public async Task RunAsync()
{ {
if (!_config.Configuration.CameraUploadUpgraded && _config.Configuration.IsStartupWizardCompleted) if (!_config.Configuration.CameraUploadUpgraded && _config.Configuration.IsStartupWizardCompleted)
{ {

View File

@ -37,12 +37,14 @@ namespace Emby.Server.Implementations.EntryPoints
_timerFactory = timerFactory; _timerFactory = timerFactory;
} }
public void Run() public Task RunAsync()
{ {
if (_appHost.CanSelfRestart) if (_appHost.CanSelfRestart)
{ {
_appHost.HasPendingRestartChanged += _appHost_HasPendingRestartChanged; _appHost.HasPendingRestartChanged += _appHost_HasPendingRestartChanged;
} }
return Task.CompletedTask;
} }
void _appHost_HasPendingRestartChanged(object sender, EventArgs e) void _appHost_HasPendingRestartChanged(object sender, EventArgs e)

View File

@ -61,17 +61,17 @@ namespace Emby.Server.Implementations.EntryPoints
return string.Join("|", values.ToArray()); return string.Join("|", values.ToArray());
} }
void _config_ConfigurationUpdated(object sender, EventArgs e) private async void _config_ConfigurationUpdated(object sender, EventArgs e)
{ {
if (!string.Equals(_lastConfigIdentifier, GetConfigIdentifier(), StringComparison.OrdinalIgnoreCase)) if (!string.Equals(_lastConfigIdentifier, GetConfigIdentifier(), StringComparison.OrdinalIgnoreCase))
{ {
DisposeNat(); DisposeNat();
Run(); await RunAsync();
} }
} }
public void Run() public Task RunAsync()
{ {
if (_config.Configuration.EnableUPnP && _config.Configuration.EnableRemoteAccess) if (_config.Configuration.EnableUPnP && _config.Configuration.EnableRemoteAccess)
{ {
@ -80,6 +80,8 @@ namespace Emby.Server.Implementations.EntryPoints
_config.ConfigurationUpdated -= _config_ConfigurationUpdated; _config.ConfigurationUpdated -= _config_ConfigurationUpdated;
_config.ConfigurationUpdated += _config_ConfigurationUpdated; _config.ConfigurationUpdated += _config_ConfigurationUpdated;
return Task.CompletedTask;
} }
private void Start() private void Start()

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.Audio;
@ -65,7 +66,7 @@ namespace Emby.Server.Implementations.EntryPoints
_providerManager = providerManager; _providerManager = providerManager;
} }
public void Run() public Task RunAsync()
{ {
_libraryManager.ItemAdded += libraryManager_ItemAdded; _libraryManager.ItemAdded += libraryManager_ItemAdded;
_libraryManager.ItemUpdated += libraryManager_ItemUpdated; _libraryManager.ItemUpdated += libraryManager_ItemUpdated;
@ -74,6 +75,8 @@ namespace Emby.Server.Implementations.EntryPoints
_providerManager.RefreshCompleted += _providerManager_RefreshCompleted; _providerManager.RefreshCompleted += _providerManager_RefreshCompleted;
_providerManager.RefreshStarted += _providerManager_RefreshStarted; _providerManager.RefreshStarted += _providerManager_RefreshStarted;
_providerManager.RefreshProgress += _providerManager_RefreshProgress; _providerManager.RefreshProgress += _providerManager_RefreshProgress;
return Task.CompletedTask;
} }
private Dictionary<Guid, DateTime> _lastProgressMessageTimes = new Dictionary<Guid, DateTime>(); private Dictionary<Guid, DateTime> _lastProgressMessageTimes = new Dictionary<Guid, DateTime>();

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Plugins; using MediaBrowser.Controller.Plugins;
@ -24,12 +25,14 @@ namespace Emby.Server.Implementations.EntryPoints
_liveTvManager = liveTvManager; _liveTvManager = liveTvManager;
} }
public void Run() public Task RunAsync()
{ {
_liveTvManager.TimerCancelled += _liveTvManager_TimerCancelled; _liveTvManager.TimerCancelled += _liveTvManager_TimerCancelled;
_liveTvManager.SeriesTimerCancelled += _liveTvManager_SeriesTimerCancelled; _liveTvManager.SeriesTimerCancelled += _liveTvManager_SeriesTimerCancelled;
_liveTvManager.TimerCreated += _liveTvManager_TimerCreated; _liveTvManager.TimerCreated += _liveTvManager_TimerCreated;
_liveTvManager.SeriesTimerCreated += _liveTvManager_SeriesTimerCreated; _liveTvManager.SeriesTimerCreated += _liveTvManager_SeriesTimerCreated;
return Task.CompletedTask;
} }
private void _liveTvManager_SeriesTimerCreated(object sender, MediaBrowser.Model.Events.GenericEventArgs<TimerEventInfo> e) private void _liveTvManager_SeriesTimerCreated(object sender, MediaBrowser.Model.Events.GenericEventArgs<TimerEventInfo> e)

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Plugins; using MediaBrowser.Common.Plugins;
using MediaBrowser.Common.Updates; using MediaBrowser.Common.Updates;
using MediaBrowser.Controller; using MediaBrowser.Controller;
@ -49,7 +50,7 @@ namespace Emby.Server.Implementations.EntryPoints
_sessionManager = sessionManager; _sessionManager = sessionManager;
} }
public void Run() public Task RunAsync()
{ {
_userManager.UserDeleted += userManager_UserDeleted; _userManager.UserDeleted += userManager_UserDeleted;
_userManager.UserUpdated += userManager_UserUpdated; _userManager.UserUpdated += userManager_UserUpdated;
@ -65,6 +66,8 @@ namespace Emby.Server.Implementations.EntryPoints
_installationManager.PackageInstallationFailed += _installationManager_PackageInstallationFailed; _installationManager.PackageInstallationFailed += _installationManager_PackageInstallationFailed;
_taskManager.TaskCompleted += _taskManager_TaskCompleted; _taskManager.TaskCompleted += _taskManager_TaskCompleted;
return Task.CompletedTask;
} }
void _installationManager_PackageInstalling(object sender, InstallationEventArgs e) void _installationManager_PackageInstalling(object sender, InstallationEventArgs e)

View File

@ -1,3 +1,4 @@
using System.Threading.Tasks;
using Emby.Server.Implementations.Browser; using Emby.Server.Implementations.Browser;
using MediaBrowser.Controller; using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Configuration;
@ -32,11 +33,11 @@ namespace Emby.Server.Implementations.EntryPoints
/// <summary> /// <summary>
/// Runs this instance. /// Runs this instance.
/// </summary> /// </summary>
public void Run() public Task RunAsync()
{ {
if (!_appHost.CanLaunchWebBrowser) if (!_appHost.CanLaunchWebBrowser)
{ {
return; return Task.CompletedTask;
} }
if (!_config.Configuration.IsStartupWizardCompleted) if (!_config.Configuration.IsStartupWizardCompleted)
@ -52,6 +53,8 @@ namespace Emby.Server.Implementations.EntryPoints
BrowserLauncher.OpenWebApp(_appHost); BrowserLauncher.OpenWebApp(_appHost);
} }
} }
return Task.CompletedTask;
} }
/// <summary> /// <summary>

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Threading.Tasks;
using Emby.Server.Implementations.Udp; using Emby.Server.Implementations.Udp;
using MediaBrowser.Controller; using MediaBrowser.Controller;
using MediaBrowser.Controller.Plugins; using MediaBrowser.Controller.Plugins;
@ -43,7 +44,7 @@ namespace Emby.Server.Implementations.EntryPoints
/// <summary> /// <summary>
/// Runs this instance. /// Runs this instance.
/// </summary> /// </summary>
public void Run() public Task RunAsync()
{ {
var udpServer = new UdpServer(_logger, _appHost, _json, _socketFactory); var udpServer = new UdpServer(_logger, _appHost, _json, _socketFactory);
@ -57,6 +58,8 @@ namespace Emby.Server.Implementations.EntryPoints
{ {
_logger.LogError(ex, "Failed to start UDP Server"); _logger.LogError(ex, "Failed to start UDP Server");
} }
return Task.CompletedTask;
} }
/// <summary> /// <summary>

View File

@ -38,9 +38,11 @@ namespace Emby.Server.Implementations.EntryPoints
_timerFactory = timerFactory; _timerFactory = timerFactory;
} }
public void Run() public Task RunAsync()
{ {
_userDataManager.UserDataSaved += _userDataManager_UserDataSaved; _userDataManager.UserDataSaved += _userDataManager_UserDataSaved;
return Task.CompletedTask;
} }
void _userDataManager_UserDataSaved(object sender, UserDataSaveEventArgs e) void _userDataManager_UserDataSaved(object sender, UserDataSaveEventArgs e)

View File

@ -633,9 +633,10 @@ namespace Emby.Server.Implementations.IO
_monitor = monitor; _monitor = monitor;
} }
public void Run() public Task RunAsync()
{ {
_monitor.Start(); _monitor.Start();
return Task.CompletedTask;
} }
public void Dispose() public void Dispose()

View File

@ -322,18 +322,18 @@ namespace Emby.Server.Implementations.Library
private string[] NormalizeLanguage(string language) private string[] NormalizeLanguage(string language)
{ {
if (language != null) if (language == null)
{ {
var culture = _localizationManager.FindLanguageInfo(language); return Array.Empty<string>();
if (culture != null)
{
return culture.ThreeLetterISOLanguageNames;
}
return new string[] { language };
} }
return Array.Empty<string>(); var culture = _localizationManager.FindLanguageInfo(language);
if (culture != null)
{
return culture.ThreeLetterISOLanguageNames;
}
return new string[] { language };
} }
private void SetDefaultSubtitleStreamIndex(MediaSourceInfo source, UserItemData userData, User user, bool allowRememberingSelection) private void SetDefaultSubtitleStreamIndex(MediaSourceInfo source, UserItemData userData, User user, bool allowRememberingSelection)

View File

@ -1182,9 +1182,11 @@ namespace Emby.Server.Implementations.Library
_sessionManager = sessionManager; _sessionManager = sessionManager;
} }
public void Run() public Task RunAsync()
{ {
_userManager.UserPolicyUpdated += _userManager_UserPolicyUpdated; _userManager.UserPolicyUpdated += _userManager_UserPolicyUpdated;
return Task.CompletedTask;
} }
private void _userManager_UserPolicyUpdated(object sender, GenericEventArgs<User> e) private void _userManager_UserPolicyUpdated(object sender, GenericEventArgs<User> e)

View File

@ -123,7 +123,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
} }
} }
public async void Start() public async Task Start()
{ {
_timerProvider.RestartTimers(); _timerProvider.RestartTimers();

View File

@ -1,12 +1,13 @@
using System.Threading.Tasks;
using MediaBrowser.Controller.Plugins; using MediaBrowser.Controller.Plugins;
namespace Emby.Server.Implementations.LiveTv.EmbyTV namespace Emby.Server.Implementations.LiveTv.EmbyTV
{ {
public class EntryPoint : IServerEntryPoint public class EntryPoint : IServerEntryPoint
{ {
public void Run() public Task RunAsync()
{ {
EmbyTV.Current.Start(); return EmbyTV.Current.Start();
} }
public void Dispose() public void Dispose()

File diff suppressed because one or more lines are too long

View File

@ -1,63 +0,0 @@
using System;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace Emby.Server.Implementations.Localization
{
public class TextLocalizer : ITextLocalizer
{
public string RemoveDiacritics(string text)
{
if (text == null)
{
throw new ArgumentNullException(nameof(text));
}
var chars = Normalize(text, NormalizationForm.FormD)
.Where(ch => CharUnicodeInfo.GetUnicodeCategory(ch) != UnicodeCategory.NonSpacingMark);
return Normalize(string.Concat(chars), NormalizationForm.FormC);
}
private static string Normalize(string text, NormalizationForm form, bool stripStringOnFailure = true)
{
if (stripStringOnFailure)
{
try
{
return text.Normalize(form);
}
catch (ArgumentException)
{
// will throw if input contains invalid unicode chars
// https://mnaoumov.wordpress.com/2014/06/14/stripping-invalid-characters-from-utf-16-strings/
text = StripInvalidUnicodeCharacters(text);
return Normalize(text, form, false);
}
}
try
{
return text.Normalize(form);
}
catch (ArgumentException)
{
// if it still fails, return the original text
return text;
}
}
private static string StripInvalidUnicodeCharacters(string str)
{
var invalidCharactersRegex = new Regex("([\ud800-\udbff](?![\udc00-\udfff]))|((?<![\ud800-\udbff])[\udc00-\udfff])");
return invalidCharactersRegex.Replace(str, "");
}
public string NormalizeFormKD(string text)
{
return text.Normalize(NormalizationForm.FormKD);
}
}
}

View File

@ -68,8 +68,6 @@ namespace Emby.Server.Implementations.ScheduledTasks
}; };
} }
public string Key => "RefreshChapterImages";
/// <summary> /// <summary>
/// Returns the task to be executed /// Returns the task to be executed
/// </summary> /// </summary>
@ -161,22 +159,18 @@ namespace Emby.Server.Implementations.ScheduledTasks
} }
} }
/// <summary>
/// Gets the name of the task
/// </summary>
/// <value>The name.</value>
public string Name => "Chapter image extraction"; public string Name => "Chapter image extraction";
/// <summary>
/// Gets the description.
/// </summary>
/// <value>The description.</value>
public string Description => "Creates thumbnails for videos that have chapters."; public string Description => "Creates thumbnails for videos that have chapters.";
/// <summary>
/// Gets the category.
/// </summary>
/// <value>The category.</value>
public string Category => "Library"; public string Category => "Library";
public string Key => "RefreshChapterImages";
public bool IsHidden => false;
public bool IsEnabled => true;
public bool IsLogged => true;
} }
} }

View File

@ -158,31 +158,15 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
} }
} }
/// <summary>
/// Gets the name of the task
/// </summary>
/// <value>The name.</value>
public string Name => "Cache file cleanup"; public string Name => "Cache file cleanup";
public string Description => "Deletes cache files no longer needed by the system";
public string Category => "Maintenance";
public string Key => "DeleteCacheFiles"; public string Key => "DeleteCacheFiles";
/// <summary> public bool IsHidden => false;
/// Gets the description.
/// </summary>
/// <value>The description.</value>
public string Description => "Deletes cache files no longer needed by the system";
/// <summary>
/// Gets the category.
/// </summary>
/// <value>The category.</value>
public string Category => "Maintenance";
/// <summary>
/// Gets a value indicating whether this instance is hidden.
/// </summary>
/// <value><c>true</c> if this instance is hidden; otherwise, <c>false</c>.</value>
public bool IsHidden => true;
public bool IsEnabled => true; public bool IsEnabled => true;

View File

@ -81,31 +81,15 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
return Task.CompletedTask; return Task.CompletedTask;
} }
public string Key => "CleanLogFiles";
/// <summary>
/// Gets the name of the task
/// </summary>
/// <value>The name.</value>
public string Name => "Log file cleanup"; public string Name => "Log file cleanup";
/// <summary>
/// Gets the description.
/// </summary>
/// <value>The description.</value>
public string Description => string.Format("Deletes log files that are more than {0} days old.", ConfigurationManager.CommonConfiguration.LogFileRetentionDays); public string Description => string.Format("Deletes log files that are more than {0} days old.", ConfigurationManager.CommonConfiguration.LogFileRetentionDays);
/// <summary>
/// Gets the category.
/// </summary>
/// <value>The category.</value>
public string Category => "Maintenance"; public string Category => "Maintenance";
/// <summary> public string Key => "CleanLogFiles";
/// Gets a value indicating whether this instance is hidden.
/// </summary> public bool IsHidden => false;
/// <value><c>true</c> if this instance is hidden; otherwise, <c>false</c>.</value>
public bool IsHidden => true;
public bool IsEnabled => true; public bool IsEnabled => true;

View File

@ -47,8 +47,6 @@ namespace Emby.Server.Implementations.ScheduledTasks
}; };
} }
public string Key => "RefreshPeople";
/// <summary> /// <summary>
/// Returns the task to be executed /// Returns the task to be executed
/// </summary> /// </summary>
@ -60,22 +58,18 @@ namespace Emby.Server.Implementations.ScheduledTasks
return _libraryManager.ValidatePeople(cancellationToken, progress); return _libraryManager.ValidatePeople(cancellationToken, progress);
} }
/// <summary>
/// Gets the name of the task
/// </summary>
/// <value>The name.</value>
public string Name => "Refresh people"; public string Name => "Refresh people";
/// <summary>
/// Gets the description.
/// </summary>
/// <value>The description.</value>
public string Description => "Updates metadata for actors and directors in your media library."; public string Description => "Updates metadata for actors and directors in your media library.";
/// <summary>
/// Gets the category.
/// </summary>
/// <value>The category.</value>
public string Category => "Library"; public string Category => "Library";
public string Key => "RefreshPeople";
public bool IsHidden => false;
public bool IsEnabled => true;
public bool IsLogged => true;
} }
} }

View File

@ -0,0 +1,119 @@
using MediaBrowser.Common;
using MediaBrowser.Common.Updates;
using MediaBrowser.Model.Net;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Progress;
using MediaBrowser.Model.Tasks;
using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.ScheduledTasks
{
/// <summary>
/// Plugin Update Task
/// </summary>
public class PluginUpdateTask : IScheduledTask, IConfigurableScheduledTask
{
/// <summary>
/// The _logger
/// </summary>
private readonly ILogger _logger;
private readonly IInstallationManager _installationManager;
private readonly IApplicationHost _appHost;
public PluginUpdateTask(ILogger logger, IInstallationManager installationManager, IApplicationHost appHost)
{
_logger = logger;
_installationManager = installationManager;
_appHost = appHost;
}
/// <summary>
/// Creates the triggers that define when the task will run
/// </summary>
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
{
return new[] {
// At startup
new TaskTriggerInfo {Type = TaskTriggerInfo.TriggerStartup},
// Every so often
new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks}
};
}
/// <summary>
/// Update installed plugins
/// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="progress">The progress.</param>
/// <returns>Task.</returns>
public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
{
progress.Report(0);
var packagesToInstall = (await _installationManager.GetAvailablePluginUpdates(typeof(PluginUpdateTask).Assembly.GetName().Version, true, cancellationToken).ConfigureAwait(false)).ToList();
progress.Report(10);
var numComplete = 0;
foreach (var package in packagesToInstall)
{
cancellationToken.ThrowIfCancellationRequested();
try
{
await _installationManager.InstallPackage(package, true, new SimpleProgress<double>(), cancellationToken).ConfigureAwait(false);
}
catch (OperationCanceledException)
{
// InstallPackage has it's own inner cancellation token, so only throw this if it's ours
if (cancellationToken.IsCancellationRequested)
{
throw;
}
}
catch (HttpException ex)
{
_logger.LogError(ex, "Error downloading {0}", package.name);
}
catch (IOException ex)
{
_logger.LogError(ex, "Error updating {0}", package.name);
}
// Update progress
lock (progress)
{
numComplete++;
progress.Report(90.0 * numComplete / packagesToInstall.Count + 10);
}
}
progress.Report(100);
}
public string Name => "Check for plugin updates";
public string Description => "Downloads and installs updates for plugins that are configured to update automatically.";
public string Category => "Application";
public string Key => "PluginUpdates";
public bool IsHidden => false;
public bool IsEnabled => true;
public bool IsLogged => true;
}
}

View File

@ -58,24 +58,18 @@ namespace Emby.Server.Implementations.ScheduledTasks
return ((LibraryManager)_libraryManager).ValidateMediaLibraryInternal(progress, cancellationToken); return ((LibraryManager)_libraryManager).ValidateMediaLibraryInternal(progress, cancellationToken);
} }
/// <summary>
/// Gets the name.
/// </summary>
/// <value>The name.</value>
public string Name => "Scan media library"; public string Name => "Scan media library";
/// <summary>
/// Gets the description.
/// </summary>
/// <value>The description.</value>
public string Description => "Scans your media library and refreshes metatata based on configuration."; public string Description => "Scans your media library and refreshes metatata based on configuration.";
/// <summary>
/// Gets the category.
/// </summary>
/// <value>The category.</value>
public string Category => "Library"; public string Category => "Library";
public string Key => "RefreshLibrary"; public string Key => "RefreshLibrary";
public bool IsHidden => false;
public bool IsEnabled => true;
public bool IsLogged => true;
} }
} }

View File

@ -164,15 +164,13 @@ namespace Emby.Server.Implementations.Updates
/// Gets all available packages. /// Gets all available packages.
/// </summary> /// </summary>
/// <returns>Task{List{PackageInfo}}.</returns> /// <returns>Task{List{PackageInfo}}.</returns>
public Task<List<PackageInfo>> GetAvailablePackages(CancellationToken cancellationToken, public async Task<List<PackageInfo>> GetAvailablePackages(CancellationToken cancellationToken,
bool withRegistration = true, bool withRegistration = true,
string packageType = null, string packageType = null,
Version applicationVersion = null) Version applicationVersion = null)
{ {
// TODO cvium: when plugins get back this would need to be fixed var packages = await GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false);
// var packages = await GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false); return FilterPackages(packages, packageType, applicationVersion);
return Task.FromResult(new List<PackageInfo>()); //FilterPackages(packages, packageType, applicationVersion);
} }
/// <summary> /// <summary>
@ -184,12 +182,10 @@ namespace Emby.Server.Implementations.Updates
{ {
using (var response = await _httpClient.SendAsync(new HttpRequestOptions using (var response = await _httpClient.SendAsync(new HttpRequestOptions
{ {
Url = "https://www.mb3admin.local/admin/service/EmbyPackages.json", Url = "https://repo.jellyfin.org/releases/plugin/manifest.json",
CancellationToken = cancellationToken, CancellationToken = cancellationToken,
Progress = new SimpleProgress<double>(), Progress = new SimpleProgress<double>(),
CacheLength = GetCacheLength(), CacheLength = GetCacheLength()
CacheMode = CacheMode.Unconditional
}, "GET").ConfigureAwait(false)) }, "GET").ConfigureAwait(false))
{ {
using (var stream = response.Content) using (var stream = response.Content)

View File

@ -114,12 +114,10 @@ namespace Jellyfin.Server
new NullImageEncoder(), new NullImageEncoder(),
new NetworkManager(_loggerFactory, environmentInfo))) new NetworkManager(_loggerFactory, environmentInfo)))
{ {
appHost.Init(); await appHost.Init();
appHost.ImageProcessor.ImageEncoder = GetImageEncoder(fileSystem, appPaths, appHost.LocalizationManager); appHost.ImageProcessor.ImageEncoder = GetImageEncoder(fileSystem, appPaths, appHost.LocalizationManager);
_logger.LogInformation("Running startup tasks");
await appHost.RunStartupTasks(); await appHost.RunStartupTasks();
// TODO: read input for a stop command // TODO: read input for a stop command
@ -133,8 +131,6 @@ namespace Jellyfin.Server
{ {
// Don't throw on cancellation // Don't throw on cancellation
} }
_logger.LogInformation("Disposing app host");
} }
if (_restartOnShutdown) if (_restartOnShutdown)

View File

@ -130,7 +130,7 @@ namespace MediaBrowser.Api
/// <summary> /// <summary>
/// Runs this instance. /// Runs this instance.
/// </summary> /// </summary>
public void Run() public Task RunAsync()
{ {
try try
{ {
@ -148,6 +148,8 @@ namespace MediaBrowser.Api
{ {
Logger.LogError(ex, "Error deleting encoded media cache"); Logger.LogError(ex, "Error deleting encoded media cache");
} }
return Task.CompletedTask;
} }
public EncodingOptions GetEncodingOptions() public EncodingOptions GetEncodingOptions()
@ -162,8 +164,7 @@ namespace MediaBrowser.Api
{ {
var path = _config.ApplicationPaths.TranscodingTempPath; var path = _config.ApplicationPaths.TranscodingTempPath;
foreach (var file in _fileSystem.GetFilePaths(path, true) foreach (var file in _fileSystem.GetFilePaths(path, true))
.ToList())
{ {
_fileSystem.DeleteFile(file); _fileSystem.DeleteFile(file);
} }

View File

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.Audio;
@ -60,15 +61,15 @@ namespace MediaBrowser.Api
_fileSystem = fileSystem; _fileSystem = fileSystem;
} }
public object Get(GetMetadataEditorInfo request) public async Task<object> Get(GetMetadataEditorInfo request)
{ {
var item = _libraryManager.GetItemById(request.ItemId); var item = _libraryManager.GetItemById(request.ItemId);
var info = new MetadataEditorInfo var info = new MetadataEditorInfo
{ {
ParentalRatingOptions = _localizationManager.GetParentalRatings(), ParentalRatingOptions = _localizationManager.GetParentalRatings().ToArray(),
ExternalIdInfos = _providerManager.GetExternalIdInfos(item).ToArray(), ExternalIdInfos = _providerManager.GetExternalIdInfos(item).ToArray(),
Countries = _localizationManager.GetCountries(), Countries = await _localizationManager.GetCountries(),
Cultures = _localizationManager.GetCultures() Cultures = _localizationManager.GetCultures()
}; };

View File

@ -89,7 +89,7 @@ namespace MediaBrowser.Common
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <param name="manageLiftime">if set to <c>true</c> [manage liftime].</param> /// <param name="manageLiftime">if set to <c>true</c> [manage liftime].</param>
/// <returns>IEnumerable{``0}.</returns> /// <returns>IEnumerable{``0}.</returns>
IEnumerable<T> GetExports<T>(bool manageLiftime = true); IEnumerable<T> GetExports<T>(bool manageLifetime = true);
/// <summary> /// <summary>
/// Updates the application. /// Updates the application.
@ -131,7 +131,7 @@ namespace MediaBrowser.Common
/// <summary> /// <summary>
/// Inits this instance. /// Inits this instance.
/// </summary> /// </summary>
void Init(); Task Init();
/// <summary> /// <summary>
/// Creates the instance. /// Creates the instance.

View File

@ -1,4 +1,8 @@
using MediaBrowser.Model.Globalization; using System;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace MediaBrowser.Controller.Extensions namespace MediaBrowser.Controller.Extensions
{ {
@ -7,11 +11,45 @@ namespace MediaBrowser.Controller.Extensions
/// </summary> /// </summary>
public static class StringExtensions public static class StringExtensions
{ {
public static ILocalizationManager LocalizationManager { get; set; }
public static string RemoveDiacritics(this string text) public static string RemoveDiacritics(this string text)
{ {
return LocalizationManager.RemoveDiacritics(text); if (text == null)
{
throw new ArgumentNullException(nameof(text));
}
var chars = Normalize(text, NormalizationForm.FormD)
.Where(ch => CharUnicodeInfo.GetUnicodeCategory(ch) != UnicodeCategory.NonSpacingMark);
return Normalize(string.Concat(chars), NormalizationForm.FormC);
}
private static string Normalize(string text, NormalizationForm form, bool stripStringOnFailure = true)
{
if (stripStringOnFailure)
{
try
{
return text.Normalize(form);
}
catch (ArgumentException)
{
// will throw if input contains invalid unicode chars
// https://mnaoumov.wordpress.com/2014/06/14/stripping-invalid-characters-from-utf-16-strings/
text = Regex.Replace(text, "([\ud800-\udbff](?![\udc00-\udfff]))|((?<![\ud800-\udbff])[\udc00-\udfff])", "");
return Normalize(text, form, false);
}
}
try
{
return text.Normalize(form);
}
catch (ArgumentException)
{
// if it still fails, return the original text
return text;
}
} }
} }
} }

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Threading.Tasks;
namespace MediaBrowser.Controller.Plugins namespace MediaBrowser.Controller.Plugins
{ {
@ -10,7 +11,7 @@ namespace MediaBrowser.Controller.Plugins
/// <summary> /// <summary>
/// Runs this instance. /// Runs this instance.
/// </summary> /// </summary>
void Run(); Task RunAsync();
} }
public interface IRunBeforeStartup public interface IRunBeforeStartup

View File

@ -1,4 +1,6 @@
using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Threading.Tasks;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Entities;
namespace MediaBrowser.Model.Globalization namespace MediaBrowser.Model.Globalization
@ -17,12 +19,12 @@ namespace MediaBrowser.Model.Globalization
/// Gets the countries. /// Gets the countries.
/// </summary> /// </summary>
/// <returns>IEnumerable{CountryInfo}.</returns> /// <returns>IEnumerable{CountryInfo}.</returns>
CountryInfo[] GetCountries(); Task<CountryInfo[]> GetCountries();
/// <summary> /// <summary>
/// Gets the parental ratings. /// Gets the parental ratings.
/// </summary> /// </summary>
/// <returns>IEnumerable{ParentalRating}.</returns> /// <returns>IEnumerable{ParentalRating}.</returns>
ParentalRating[] GetParentalRatings(); IEnumerable<ParentalRating> GetParentalRatings();
/// <summary> /// <summary>
/// Gets the rating level. /// Gets the rating level.
/// </summary> /// </summary>
@ -51,8 +53,6 @@ namespace MediaBrowser.Model.Globalization
/// <returns>IEnumerable{LocalizatonOption}.</returns> /// <returns>IEnumerable{LocalizatonOption}.</returns>
LocalizationOption[] GetLocalizationOptions(); LocalizationOption[] GetLocalizationOptions();
string RemoveDiacritics(string text);
string NormalizeFormKD(string text); string NormalizeFormKD(string text);
bool HasUnicodeCategory(string value, UnicodeCategory category); bool HasUnicodeCategory(string value, UnicodeCategory category);

View File

@ -566,8 +566,7 @@ namespace MediaBrowser.Providers.Manager
var providersWithChanges = providers var providersWithChanges = providers
.Where(i => .Where(i =>
{ {
var hasFileChangeMonitor = i as IHasItemChangeMonitor; if (i is IHasItemChangeMonitor hasFileChangeMonitor)
if (hasFileChangeMonitor != null)
{ {
return HasChanged(item, hasFileChangeMonitor, options.DirectoryService); return HasChanged(item, hasFileChangeMonitor, options.DirectoryService);
} }

View File

@ -74,17 +74,12 @@ namespace MediaBrowser.Providers.MediaInfo
} }
} }
if (item.SupportsLocalMetadata) if (item.SupportsLocalMetadata && video != null && !video.IsPlaceHolder
&& !video.SubtitleFiles.SequenceEqual(
_subtitleResolver.GetExternalSubtitleFiles(video, directoryService, false), StringComparer.Ordinal))
{ {
if (video != null && !video.IsPlaceHolder) _logger.LogDebug("Refreshing {0} due to external subtitles change.", item.Path);
{ return true;
if (!video.SubtitleFiles
.SequenceEqual(_subtitleResolver.GetExternalSubtitleFiles(video, directoryService, false), StringComparer.Ordinal))
{
_logger.LogDebug("Refreshing {0} due to external subtitles change.", item.Path);
return true;
}
}
} }
return false; return false;

View File

@ -36,12 +36,6 @@ namespace MediaBrowser.Providers.MediaInfo
_json = json; _json = json;
} }
public string Name => "Download missing subtitles";
public string Description => "Searches the internet for missing subtitles based on metadata configuration.";
public string Category => "Library";
private SubtitleOptions GetOptions() private SubtitleOptions GetOptions()
{ {
return _config.GetConfiguration<SubtitleOptions>("subtitles"); return _config.GetConfiguration<SubtitleOptions>("subtitles");
@ -204,6 +198,18 @@ namespace MediaBrowser.Providers.MediaInfo
}; };
} }
public string Name => "Download missing subtitles";
public string Description => "Searches the internet for missing subtitles based on metadata configuration.";
public string Category => "Library";
public string Key => "DownloadSubtitles"; public string Key => "DownloadSubtitles";
public bool IsHidden => false;
public bool IsEnabled => true;
public bool IsLogged => true;
} }
} }

View File

@ -425,11 +425,9 @@ namespace MediaBrowser.WebDashboard.Api
private async Task DumpFile(PackageCreator packageCreator, string resourceVirtualPath, string destinationFilePath, string mode, string appVersion) private async Task DumpFile(PackageCreator packageCreator, string resourceVirtualPath, string destinationFilePath, string mode, string appVersion)
{ {
using (var stream = await packageCreator.GetResource(resourceVirtualPath, mode, null, appVersion).ConfigureAwait(false)) using (var stream = await packageCreator.GetResource(resourceVirtualPath, mode, null, appVersion).ConfigureAwait(false))
using (var fs = _fileSystem.GetFileStream(destinationFilePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
{ {
using (var fs = _fileSystem.GetFileStream(destinationFilePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read)) await stream.CopyToAsync(fs);
{
stream.CopyTo(fs);
}
} }
} }

View File

@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using MediaBrowser.Common; using MediaBrowser.Common;
using MediaBrowser.Controller.Plugins; using MediaBrowser.Controller.Plugins;
@ -23,9 +24,11 @@ namespace MediaBrowser.WebDashboard
Instance = this; Instance = this;
} }
public void Run() public Task RunAsync()
{ {
PluginConfigurationPages = _appHost.GetExports<IPluginConfigurationPage>().ToList(); PluginConfigurationPages = _appHost.GetExports<IPluginConfigurationPage>().ToList();
return Task.CompletedTask;
} }
public void Dispose() public void Dispose()

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Threading.Tasks;
using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
@ -28,9 +29,11 @@ namespace MediaBrowser.XbmcMetadata
_config = config; _config = config;
} }
public void Run() public Task RunAsync()
{ {
_userDataManager.UserDataSaved += _userDataManager_UserDataSaved; _userDataManager.UserDataSaved += _userDataManager_UserDataSaved;
return Task.CompletedTask;
} }
void _userDataManager_UserDataSaved(object sender, UserDataSaveEventArgs e) void _userDataManager_UserDataSaved(object sender, UserDataSaveEventArgs e)

View File

@ -68,8 +68,7 @@ new_version="$1"
# Parse the version from the AssemblyVersion # Parse the version from the AssemblyVersion
old_version="$( old_version="$(
grep "AssemblyVersion" ${shared_version_file} \ grep "AssemblyVersion" ${shared_version_file} \
| sed -E 's/\[assembly: ?AssemblyVersion\("([0-9\.]+)"\)\]/\1/' \ | sed -E 's/\[assembly: ?AssemblyVersion\("([0-9\.]+)"\)\]/\1/'
| sed -E 's/.0$//'
)" )"
# Set the shared version to the specified new_version # Set the shared version to the specified new_version

View File

@ -0,0 +1,15 @@
FROM centos:7
ARG HOME=/build
RUN mkdir /build && \
yum install -y @buildsys-build rpmdevtools yum-plugins-core && \
rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm && \
rpmdev-setuptree
WORKDIR /build/rpmbuild
COPY ./deployment/centos-package-x64/pkg-src/jellyfin.spec SPECS
COPY ./deployment/centos-package-x64/pkg-src/ SOURCES
RUN spectool -g -R SPECS/jellyfin.spec && \
rpmbuild -bs SPECS/jellyfin.spec && \
yum-builddep -y SRPMS/jellyfin-*.src.rpm && \
rpmbuild -bb SPECS/jellyfin.spec;

View File

@ -0,0 +1 @@
../fedora-package-x64/clean.sh

View File

@ -0,0 +1 @@
../fedora-package-x64/package.sh

View File

@ -0,0 +1 @@
../fedora-package-x64/pkg-src

View File

@ -18,7 +18,7 @@
JELLYFIN_DATA_DIRECTORY="/var/lib/jellyfin" JELLYFIN_DATA_DIRECTORY="/var/lib/jellyfin"
JELLYFIN_CONFIG_DIRECTORY="/etc/jellyfin" JELLYFIN_CONFIG_DIRECTORY="/etc/jellyfin"
JELLYFIN_LOG_DIRECTORY="/var/log/jellyfin" JELLYFIN_LOG_DIRECTORY="/var/log/jellyfin"
JELLYFIN_CACHE_DIRECTORY="/var/log/jellyfin" JELLYFIN_CACHE_DIRECTORY="/var/cache/jellyfin"
# In-App service control # In-App service control
JELLYFIN_RESTART_OPT="--restartpath=/usr/libexec/jellyfin/restart.sh" JELLYFIN_RESTART_OPT="--restartpath=/usr/libexec/jellyfin/restart.sh"

View File

@ -1,11 +1,11 @@
%global debug_package %{nil} %global debug_package %{nil}
# jellyfin tag to package # Set the dotnet runtime
%global gittag v10.1.0 %if 0%{?fedora}
# Taglib-sharp commit of the submodule since github archive doesn't include submodules %global dotnet_runtime fedora-x64
%global taglib_commit ee5ab21742b71fd1b87ee24895582327e9e04776 %else
%global taglib_shortcommit %(c=%{taglib_commit}; echo ${c:0:7}) %global dotnet_runtime centos-x64
%endif
AutoReq: no
Name: jellyfin Name: jellyfin
Version: 10.1.0 Version: 10.1.0
Release: 1%{?dist} Release: 1%{?dist}
@ -31,13 +31,11 @@ BuildRequires: dotnet-sdk-2.2
# RPMfusion free # RPMfusion free
Requires: ffmpeg Requires: ffmpeg
# For the update-db-paths.sh script to fix emby paths to jellyfin
%{?fedora:Recommends: sqlite}
# Fedora has openssl1.1 which is incompatible with dotnet # Fedora has openssl1.1 which is incompatible with dotnet
%{?fedora:Requires: compat-openssl10} %{?fedora:Requires: compat-openssl10}
# Disable Automatic Dependency Processing for Centos
%{?el7:AutoReqProv: no} # Disable Automatic Dependency Processing
AutoReqProv: no
%description %description
Jellyfin is a free software media system that puts you in control of managing and streaming your media. Jellyfin is a free software media system that puts you in control of managing and streaming your media.
@ -51,7 +49,7 @@ Jellyfin is a free software media system that puts you in control of managing an
%install %install
export DOTNET_CLI_TELEMETRY_OPTOUT=1 export DOTNET_CLI_TELEMETRY_OPTOUT=1
export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
dotnet publish --configuration Release --output='%{buildroot}%{_libdir}/jellyfin' --self-contained --runtime fedora-x64 Jellyfin.Server dotnet publish --configuration Release --output='%{buildroot}%{_libdir}/jellyfin' --self-contained --runtime %{dotnet_runtime} Jellyfin.Server
%{__install} -D -m 0644 LICENSE %{buildroot}%{_datadir}/licenses/%{name}/LICENSE %{__install} -D -m 0644 LICENSE %{buildroot}%{_datadir}/licenses/%{name}/LICENSE
%{__install} -D -m 0644 %{SOURCE5} %{buildroot}%{_sysconfdir}/systemd/system/%{name}.service.d/override.conf %{__install} -D -m 0644 %{SOURCE5} %{buildroot}%{_sysconfdir}/systemd/system/%{name}.service.d/override.conf
%{__install} -D -m 0644 Jellyfin.Server/Resources/Configuration/logging.json %{buildroot}%{_sysconfdir}/%{name}/logging.json %{__install} -D -m 0644 Jellyfin.Server/Resources/Configuration/logging.json %{buildroot}%{_sysconfdir}/%{name}/logging.json
@ -63,6 +61,7 @@ EOF
%{__mkdir} -p %{buildroot}%{_sharedstatedir}/jellyfin %{__mkdir} -p %{buildroot}%{_sharedstatedir}/jellyfin
%{__mkdir} -p %{buildroot}%{_sysconfdir}/%{name} %{__mkdir} -p %{buildroot}%{_sysconfdir}/%{name}
%{__mkdir} -p %{buildroot}%{_var}/log/jellyfin %{__mkdir} -p %{buildroot}%{_var}/log/jellyfin
%{__mkdir} -p %{buildroot}%{_var}/cache/jellyfin
%{__install} -D -m 0644 %{SOURCE1} %{buildroot}%{_unitdir}/%{name}.service %{__install} -D -m 0644 %{SOURCE1} %{buildroot}%{_unitdir}/%{name}.service
%{__install} -D -m 0644 %{SOURCE2} %{buildroot}%{_sysconfdir}/sysconfig/%{name} %{__install} -D -m 0644 %{SOURCE2} %{buildroot}%{_sysconfdir}/sysconfig/%{name}
@ -90,8 +89,9 @@ EOF
%config(noreplace) %attr(600,root,root) %{_sysconfdir}/sudoers.d/%{name}-sudoers %config(noreplace) %attr(600,root,root) %{_sysconfdir}/sudoers.d/%{name}-sudoers
%config(noreplace) %{_sysconfdir}/systemd/system/%{name}.service.d/override.conf %config(noreplace) %{_sysconfdir}/systemd/system/%{name}.service.d/override.conf
%config(noreplace) %attr(644,jellyfin,jellyfin) %{_sysconfdir}/%{name}/logging.json %config(noreplace) %attr(644,jellyfin,jellyfin) %{_sysconfdir}/%{name}/logging.json
%attr(-,jellyfin,jellyfin) %dir %{_sharedstatedir}/jellyfin %attr(750,jellyfin,jellyfin) %dir %{_sharedstatedir}/jellyfin
%attr(-,jellyfin,jellyfin) %dir %{_var}/log/jellyfin %attr(-,jellyfin,jellyfin) %dir %{_var}/log/jellyfin
%attr(750,jellyfin,jellyfin) %dir %{_var}/cache/jellyfin
%if 0%{?fedora} %if 0%{?fedora}
%license LICENSE %license LICENSE
%else %else
@ -106,7 +106,7 @@ getent passwd jellyfin >/dev/null || \
exit 0 exit 0
%post %post
# Move existing configuration to /etc/jellyfin and symlink config to /etc/jellyfin # Move existing configuration cache and logs to their new locations and symlink them.
if [ $1 -gt 1 ] ; then if [ $1 -gt 1 ] ; then
service_state=$(systemctl is-active jellyfin.service) service_state=$(systemctl is-active jellyfin.service)
if [ "${service_state}" = "active" ]; then if [ "${service_state}" = "active" ]; then
@ -122,6 +122,11 @@ if [ $1 -gt 1 ] ; then
rmdir %{_sharedstatedir}/%{name}/logs rmdir %{_sharedstatedir}/%{name}/logs
ln -sf %{_var}/log/jellyfin %{_sharedstatedir}/%{name}/logs ln -sf %{_var}/log/jellyfin %{_sharedstatedir}/%{name}/logs
fi fi
if [ ! -L %{_sharedstatedir}/%{name}/cache ]; then
mv %{_sharedstatedir}/%{name}/cache/* %{_var}/cache/jellyfin
rmdir %{_sharedstatedir}/%{name}/cache
ln -sf %{_var}/cache/jellyfin %{_sharedstatedir}/%{name}/cache
fi
if [ "${service_state}" = "active" ]; then if [ "${service_state}" = "active" ]; then
systemctl start jellyfin.service systemctl start jellyfin.service
fi fi