Merge branch 'master' into fix-env
This commit is contained in:
commit
20033f2275
|
@ -15,6 +15,7 @@
|
|||
- [cvium](https://github.com/cvium)
|
||||
- [wtayl0r](https://github.com/wtayl0r)
|
||||
- [TtheCreator](https://github.com/Tthecreator)
|
||||
- [dkanada](https://github.com/dkanada)
|
||||
- [LogicalPhallacy](https://github.com/LogicalPhallacy/)
|
||||
- [RazeLighter777](https://github.com/RazeLighter777)
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Emby.Dlna.Profiles;
|
||||
using Emby.Dlna.Server;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
|
@ -48,11 +49,11 @@ namespace Emby.Dlna
|
|||
_assemblyInfo = assemblyInfo;
|
||||
}
|
||||
|
||||
public void InitProfiles()
|
||||
public async Task InitProfilesAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
ExtractSystemProfiles();
|
||||
await ExtractSystemProfilesAsync();
|
||||
LoadProfiles();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -359,7 +360,7 @@ namespace Emby.Dlna
|
|||
};
|
||||
}
|
||||
|
||||
private void ExtractSystemProfiles()
|
||||
private async Task ExtractSystemProfilesAsync()
|
||||
{
|
||||
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))
|
||||
{
|
||||
stream.CopyTo(fileStream);
|
||||
await stream.CopyToAsync(fileStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -125,9 +125,9 @@ namespace Emby.Dlna.Main
|
|||
Current = this;
|
||||
}
|
||||
|
||||
public void Run()
|
||||
public async Task RunAsync()
|
||||
{
|
||||
((DlnaManager)_dlnaManager).InitProfiles();
|
||||
await ((DlnaManager)_dlnaManager).InitProfilesAsync().ConfigureAwait(false);
|
||||
|
||||
ReloadComponents();
|
||||
|
||||
|
|
|
@ -71,12 +71,14 @@ namespace Emby.Notifications
|
|||
_coreNotificationTypes = new CoreNotificationTypes(localization, appHost).GetNotificationTypes().Select(i => i.Type).ToArray();
|
||||
}
|
||||
|
||||
public void Run()
|
||||
public Task RunAsync()
|
||||
{
|
||||
_libraryManager.ItemAdded += _libraryManager_ItemAdded;
|
||||
_appHost.HasPendingRestartChanged += _appHost_HasPendingRestartChanged;
|
||||
_appHost.HasUpdateAvailableChanged += _appHost_HasUpdateAvailableChanged;
|
||||
_activityManager.EntryCreated += _activityManager_EntryCreated;
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async void _appHost_HasPendingRestartChanged(object sender, EventArgs e)
|
||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.Plugins;
|
||||
using MediaBrowser.Common.Updates;
|
||||
|
@ -58,7 +59,7 @@ namespace Emby.Server.Implementations.Activity
|
|||
_deviceManager = deviceManager;
|
||||
}
|
||||
|
||||
public void Run()
|
||||
public Task RunAsync()
|
||||
{
|
||||
_taskManager.TaskCompleted += _taskManager_TaskCompleted;
|
||||
|
||||
|
@ -90,6 +91,8 @@ namespace Emby.Server.Implementations.Activity
|
|||
_deviceManager.CameraImageUploaded += _deviceManager_CameraImageUploaded;
|
||||
|
||||
_appHost.ApplicationUpdated += _appHost_ApplicationUpdated;
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
void _deviceManager_CameraImageUploaded(object sender, GenericEventArgs<CameraImageUploadInfo> e)
|
||||
|
|
|
@ -110,7 +110,6 @@ using MediaBrowser.XbmcMetadata.Providers;
|
|||
using Microsoft.Extensions.Logging;
|
||||
using ServiceStack;
|
||||
using ServiceStack.Text.Jsv;
|
||||
using StringExtensions = MediaBrowser.Controller.Extensions.StringExtensions;
|
||||
using X509Certificate = System.Security.Cryptography.X509Certificates.X509Certificate;
|
||||
|
||||
namespace Emby.Server.Implementations
|
||||
|
@ -302,7 +301,7 @@ namespace Emby.Server.Implementations
|
|||
|
||||
private ILiveTvManager LiveTvManager { get; set; }
|
||||
|
||||
public ILocalizationManager LocalizationManager { get; set; }
|
||||
public LocalizationManager LocalizationManager { get; set; }
|
||||
|
||||
private IEncodingManager EncodingManager { get; set; }
|
||||
private IChannelManager ChannelManager { get; set; }
|
||||
|
@ -646,8 +645,10 @@ namespace Emby.Server.Implementations
|
|||
/// <summary>
|
||||
/// Runs the startup tasks.
|
||||
/// </summary>
|
||||
public Task RunStartupTasks()
|
||||
public async Task RunStartupTasks()
|
||||
{
|
||||
Logger.LogInformation("Running startup tasks");
|
||||
|
||||
Resolve<ITaskManager>().AddTasks(GetExports<IScheduledTask>(false));
|
||||
|
||||
ConfigurationManager.ConfigurationUpdated += OnConfigurationUpdated;
|
||||
|
@ -666,20 +667,20 @@ namespace Emby.Server.Implementations
|
|||
Logger.LogInformation("ServerId: {0}", SystemId);
|
||||
|
||||
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");
|
||||
HttpServer.GlobalResponse = null;
|
||||
|
||||
Logger.LogInformation("Post-init migrations complete");
|
||||
|
||||
RunEntryPoints(entryPoints, false);
|
||||
Logger.LogInformation("All entry points have started");
|
||||
|
||||
return Task.CompletedTask;
|
||||
now = DateTime.UtcNow;
|
||||
await Task.WhenAll(StartEntryPoints(entryPoints, false));
|
||||
Logger.LogInformation("Executed all post-startup entry points in {Elapsed:fff} ms", DateTime.Now - now);
|
||||
}
|
||||
|
||||
private void RunEntryPoints(IEnumerable<IServerEntryPoint> entryPoints, bool isBeforeStartup)
|
||||
private IEnumerable<Task> StartEntryPoints(IEnumerable<IServerEntryPoint> entryPoints, bool isBeforeStartup)
|
||||
{
|
||||
foreach (var entryPoint in entryPoints)
|
||||
{
|
||||
|
@ -688,22 +689,13 @@ namespace Emby.Server.Implementations
|
|||
continue;
|
||||
}
|
||||
|
||||
var name = entryPoint.GetType().FullName;
|
||||
Logger.LogInformation("Starting entry point {Name}", name);
|
||||
var now = DateTime.UtcNow;
|
||||
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");
|
||||
Logger.LogDebug("Starting entry point {Type}", entryPoint.GetType());
|
||||
|
||||
yield return entryPoint.RunAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public void Init()
|
||||
public async Task Init()
|
||||
{
|
||||
HttpPort = ServerConfigurationManager.Configuration.HttpServerPortNumber;
|
||||
HttpsPort = ServerConfigurationManager.Configuration.HttpsPortNumber;
|
||||
|
@ -733,7 +725,7 @@ namespace Emby.Server.Implementations
|
|||
|
||||
SetHttpLimit();
|
||||
|
||||
RegisterResources();
|
||||
await RegisterResources();
|
||||
|
||||
FindParts();
|
||||
}
|
||||
|
@ -748,7 +740,7 @@ namespace Emby.Server.Implementations
|
|||
/// <summary>
|
||||
/// Registers resources that classes will depend on
|
||||
/// </summary>
|
||||
protected void RegisterResources()
|
||||
protected async Task RegisterResources()
|
||||
{
|
||||
RegisterSingleInstance(ConfigurationManager);
|
||||
RegisterSingleInstance<IApplicationHost>(this);
|
||||
|
@ -809,9 +801,9 @@ namespace Emby.Server.Implementations
|
|||
IAssemblyInfo assemblyInfo = new AssemblyInfo();
|
||||
RegisterSingleInstance(assemblyInfo);
|
||||
|
||||
LocalizationManager = new LocalizationManager(ServerConfigurationManager, FileSystemManager, JsonSerializer, LoggerFactory, assemblyInfo, new TextLocalizer());
|
||||
StringExtensions.LocalizationManager = LocalizationManager;
|
||||
RegisterSingleInstance(LocalizationManager);
|
||||
LocalizationManager = new LocalizationManager(ServerConfigurationManager, FileSystemManager, JsonSerializer, LoggerFactory);
|
||||
await LocalizationManager.LoadAll();
|
||||
RegisterSingleInstance<ILocalizationManager>(LocalizationManager);
|
||||
|
||||
BlurayExaminer = new BdInfoExaminer(FileSystemManager);
|
||||
RegisterSingleInstance(BlurayExaminer);
|
||||
|
|
|
@ -353,7 +353,7 @@ namespace Emby.Server.Implementations.Collections
|
|||
_logger = logger;
|
||||
}
|
||||
|
||||
public async void Run()
|
||||
public async Task RunAsync()
|
||||
{
|
||||
if (!_config.Configuration.CollectionsUpgraded && _config.Configuration.IsStartupWizardCompleted)
|
||||
{
|
||||
|
|
|
@ -425,7 +425,7 @@ namespace Emby.Server.Implementations.Devices
|
|||
_logger = logger;
|
||||
}
|
||||
|
||||
public async void Run()
|
||||
public async Task RunAsync()
|
||||
{
|
||||
if (!_config.Configuration.CameraUploadUpgraded && _config.Configuration.IsStartupWizardCompleted)
|
||||
{
|
||||
|
|
|
@ -37,12 +37,14 @@ namespace Emby.Server.Implementations.EntryPoints
|
|||
_timerFactory = timerFactory;
|
||||
}
|
||||
|
||||
public void Run()
|
||||
public Task RunAsync()
|
||||
{
|
||||
if (_appHost.CanSelfRestart)
|
||||
{
|
||||
_appHost.HasPendingRestartChanged += _appHost_HasPendingRestartChanged;
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
void _appHost_HasPendingRestartChanged(object sender, EventArgs e)
|
||||
|
|
|
@ -61,17 +61,17 @@ namespace Emby.Server.Implementations.EntryPoints
|
|||
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))
|
||||
{
|
||||
DisposeNat();
|
||||
|
||||
Run();
|
||||
await RunAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public void Run()
|
||||
public Task RunAsync()
|
||||
{
|
||||
if (_config.Configuration.EnableUPnP && _config.Configuration.EnableRemoteAccess)
|
||||
{
|
||||
|
@ -80,6 +80,8 @@ namespace Emby.Server.Implementations.EntryPoints
|
|||
|
||||
_config.ConfigurationUpdated -= _config_ConfigurationUpdated;
|
||||
_config.ConfigurationUpdated += _config_ConfigurationUpdated;
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Controller.Channels;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
|
@ -65,7 +66,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
|||
_providerManager = providerManager;
|
||||
}
|
||||
|
||||
public void Run()
|
||||
public Task RunAsync()
|
||||
{
|
||||
_libraryManager.ItemAdded += libraryManager_ItemAdded;
|
||||
_libraryManager.ItemUpdated += libraryManager_ItemUpdated;
|
||||
|
@ -74,6 +75,8 @@ namespace Emby.Server.Implementations.EntryPoints
|
|||
_providerManager.RefreshCompleted += _providerManager_RefreshCompleted;
|
||||
_providerManager.RefreshStarted += _providerManager_RefreshStarted;
|
||||
_providerManager.RefreshProgress += _providerManager_RefreshProgress;
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Dictionary<Guid, DateTime> _lastProgressMessageTimes = new Dictionary<Guid, DateTime>();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.LiveTv;
|
||||
using MediaBrowser.Controller.Plugins;
|
||||
|
@ -24,12 +25,14 @@ namespace Emby.Server.Implementations.EntryPoints
|
|||
_liveTvManager = liveTvManager;
|
||||
}
|
||||
|
||||
public void Run()
|
||||
public Task RunAsync()
|
||||
{
|
||||
_liveTvManager.TimerCancelled += _liveTvManager_TimerCancelled;
|
||||
_liveTvManager.SeriesTimerCancelled += _liveTvManager_SeriesTimerCancelled;
|
||||
_liveTvManager.TimerCreated += _liveTvManager_TimerCreated;
|
||||
_liveTvManager.SeriesTimerCreated += _liveTvManager_SeriesTimerCreated;
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void _liveTvManager_SeriesTimerCreated(object sender, MediaBrowser.Model.Events.GenericEventArgs<TimerEventInfo> e)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.Plugins;
|
||||
using MediaBrowser.Common.Updates;
|
||||
using MediaBrowser.Controller;
|
||||
|
@ -49,7 +50,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
|||
_sessionManager = sessionManager;
|
||||
}
|
||||
|
||||
public void Run()
|
||||
public Task RunAsync()
|
||||
{
|
||||
_userManager.UserDeleted += userManager_UserDeleted;
|
||||
_userManager.UserUpdated += userManager_UserUpdated;
|
||||
|
@ -65,6 +66,8 @@ namespace Emby.Server.Implementations.EntryPoints
|
|||
_installationManager.PackageInstallationFailed += _installationManager_PackageInstallationFailed;
|
||||
|
||||
_taskManager.TaskCompleted += _taskManager_TaskCompleted;
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
void _installationManager_PackageInstalling(object sender, InstallationEventArgs e)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System.Threading.Tasks;
|
||||
using Emby.Server.Implementations.Browser;
|
||||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
|
@ -32,11 +33,11 @@ namespace Emby.Server.Implementations.EntryPoints
|
|||
/// <summary>
|
||||
/// Runs this instance.
|
||||
/// </summary>
|
||||
public void Run()
|
||||
public Task RunAsync()
|
||||
{
|
||||
if (!_appHost.CanLaunchWebBrowser)
|
||||
{
|
||||
return;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
if (!_config.Configuration.IsStartupWizardCompleted)
|
||||
|
@ -52,6 +53,8 @@ namespace Emby.Server.Implementations.EntryPoints
|
|||
BrowserLauncher.OpenWebApp(_appHost);
|
||||
}
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Emby.Server.Implementations.Udp;
|
||||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Controller.Plugins;
|
||||
|
@ -43,7 +44,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
|||
/// <summary>
|
||||
/// Runs this instance.
|
||||
/// </summary>
|
||||
public void Run()
|
||||
public Task RunAsync()
|
||||
{
|
||||
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");
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -38,9 +38,11 @@ namespace Emby.Server.Implementations.EntryPoints
|
|||
_timerFactory = timerFactory;
|
||||
}
|
||||
|
||||
public void Run()
|
||||
public Task RunAsync()
|
||||
{
|
||||
_userDataManager.UserDataSaved += _userDataManager_UserDataSaved;
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
void _userDataManager_UserDataSaved(object sender, UserDataSaveEventArgs e)
|
||||
|
|
|
@ -633,9 +633,10 @@ namespace Emby.Server.Implementations.IO
|
|||
_monitor = monitor;
|
||||
}
|
||||
|
||||
public void Run()
|
||||
public Task RunAsync()
|
||||
{
|
||||
_monitor.Start();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
|
@ -322,8 +322,11 @@ namespace Emby.Server.Implementations.Library
|
|||
|
||||
private string[] NormalizeLanguage(string language)
|
||||
{
|
||||
if (language != null)
|
||||
if (language == null)
|
||||
{
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
|
||||
var culture = _localizationManager.FindLanguageInfo(language);
|
||||
if (culture != null)
|
||||
{
|
||||
|
@ -333,9 +336,6 @@ namespace Emby.Server.Implementations.Library
|
|||
return new string[] { language };
|
||||
}
|
||||
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
|
||||
private void SetDefaultSubtitleStreamIndex(MediaSourceInfo source, UserItemData userData, User user, bool allowRememberingSelection)
|
||||
{
|
||||
if (userData.SubtitleStreamIndex.HasValue && user.Configuration.RememberSubtitleSelections && user.Configuration.SubtitleMode != SubtitlePlaybackMode.None && allowRememberingSelection)
|
||||
|
|
|
@ -1182,9 +1182,11 @@ namespace Emby.Server.Implementations.Library
|
|||
_sessionManager = sessionManager;
|
||||
}
|
||||
|
||||
public void Run()
|
||||
public Task RunAsync()
|
||||
{
|
||||
_userManager.UserPolicyUpdated += _userManager_UserPolicyUpdated;
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void _userManager_UserPolicyUpdated(object sender, GenericEventArgs<User> e)
|
||||
|
|
|
@ -123,7 +123,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|||
}
|
||||
}
|
||||
|
||||
public async void Start()
|
||||
public async Task Start()
|
||||
{
|
||||
_timerProvider.RestartTimers();
|
||||
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Controller.Plugins;
|
||||
|
||||
namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||
{
|
||||
public class EntryPoint : IServerEntryPoint
|
||||
{
|
||||
public void Run()
|
||||
public Task RunAsync()
|
||||
{
|
||||
EmbyTV.Current.Start();
|
||||
return EmbyTV.Current.Start();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -68,8 +68,6 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||
};
|
||||
}
|
||||
|
||||
public string Key => "RefreshChapterImages";
|
||||
|
||||
/// <summary>
|
||||
/// Returns the task to be executed
|
||||
/// </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";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the description.
|
||||
/// </summary>
|
||||
/// <value>The description.</value>
|
||||
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 Key => "RefreshChapterImages";
|
||||
|
||||
public bool IsHidden => false;
|
||||
|
||||
public bool IsEnabled => true;
|
||||
|
||||
public bool IsLogged => true;
|
||||
}
|
||||
}
|
|
@ -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 Description => "Deletes cache files no longer needed by the system";
|
||||
|
||||
public string Category => "Maintenance";
|
||||
|
||||
public string Key => "DeleteCacheFiles";
|
||||
|
||||
/// <summary>
|
||||
/// 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 IsHidden => false;
|
||||
|
||||
public bool IsEnabled => true;
|
||||
|
||||
|
|
|
@ -81,31 +81,15 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
|||
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";
|
||||
|
||||
/// <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);
|
||||
|
||||
/// <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 string Key => "CleanLogFiles";
|
||||
|
||||
public bool IsHidden => false;
|
||||
|
||||
public bool IsEnabled => true;
|
||||
|
||||
|
|
|
@ -47,8 +47,6 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||
};
|
||||
}
|
||||
|
||||
public string Key => "RefreshPeople";
|
||||
|
||||
/// <summary>
|
||||
/// Returns the task to be executed
|
||||
/// </summary>
|
||||
|
@ -60,22 +58,18 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||
return _libraryManager.ValidatePeople(cancellationToken, progress);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the task
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
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.";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the category.
|
||||
/// </summary>
|
||||
/// <value>The category.</value>
|
||||
public string Category => "Library";
|
||||
|
||||
public string Key => "RefreshPeople";
|
||||
|
||||
public bool IsHidden => false;
|
||||
|
||||
public bool IsEnabled => true;
|
||||
|
||||
public bool IsLogged => true;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -58,24 +58,18 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
|||
return ((LibraryManager)_libraryManager).ValidateMediaLibraryInternal(progress, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
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.";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the category.
|
||||
/// </summary>
|
||||
/// <value>The category.</value>
|
||||
public string Category => "Library";
|
||||
|
||||
public string Key => "RefreshLibrary";
|
||||
|
||||
public bool IsHidden => false;
|
||||
|
||||
public bool IsEnabled => true;
|
||||
|
||||
public bool IsLogged => true;
|
||||
}
|
||||
}
|
|
@ -164,15 +164,13 @@ namespace Emby.Server.Implementations.Updates
|
|||
/// Gets all available packages.
|
||||
/// </summary>
|
||||
/// <returns>Task{List{PackageInfo}}.</returns>
|
||||
public Task<List<PackageInfo>> GetAvailablePackages(CancellationToken cancellationToken,
|
||||
public async Task<List<PackageInfo>> GetAvailablePackages(CancellationToken cancellationToken,
|
||||
bool withRegistration = true,
|
||||
string packageType = null,
|
||||
Version applicationVersion = null)
|
||||
{
|
||||
// TODO cvium: when plugins get back this would need to be fixed
|
||||
// var packages = await GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return Task.FromResult(new List<PackageInfo>()); //FilterPackages(packages, packageType, applicationVersion);
|
||||
var packages = await GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false);
|
||||
return FilterPackages(packages, packageType, applicationVersion);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -184,12 +182,10 @@ namespace Emby.Server.Implementations.Updates
|
|||
{
|
||||
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,
|
||||
Progress = new SimpleProgress<double>(),
|
||||
CacheLength = GetCacheLength(),
|
||||
CacheMode = CacheMode.Unconditional
|
||||
|
||||
CacheLength = GetCacheLength()
|
||||
}, "GET").ConfigureAwait(false))
|
||||
{
|
||||
using (var stream = response.Content)
|
||||
|
|
|
@ -114,12 +114,10 @@ namespace Jellyfin.Server
|
|||
new NullImageEncoder(),
|
||||
new NetworkManager(_loggerFactory, environmentInfo)))
|
||||
{
|
||||
appHost.Init();
|
||||
await appHost.Init();
|
||||
|
||||
appHost.ImageProcessor.ImageEncoder = GetImageEncoder(fileSystem, appPaths, appHost.LocalizationManager);
|
||||
|
||||
_logger.LogInformation("Running startup tasks");
|
||||
|
||||
await appHost.RunStartupTasks();
|
||||
|
||||
// TODO: read input for a stop command
|
||||
|
@ -133,8 +131,6 @@ namespace Jellyfin.Server
|
|||
{
|
||||
// Don't throw on cancellation
|
||||
}
|
||||
|
||||
_logger.LogInformation("Disposing app host");
|
||||
}
|
||||
|
||||
if (_restartOnShutdown)
|
||||
|
|
|
@ -130,7 +130,7 @@ namespace MediaBrowser.Api
|
|||
/// <summary>
|
||||
/// Runs this instance.
|
||||
/// </summary>
|
||||
public void Run()
|
||||
public Task RunAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -148,6 +148,8 @@ namespace MediaBrowser.Api
|
|||
{
|
||||
Logger.LogError(ex, "Error deleting encoded media cache");
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public EncodingOptions GetEncodingOptions()
|
||||
|
@ -162,8 +164,7 @@ namespace MediaBrowser.Api
|
|||
{
|
||||
var path = _config.ApplicationPaths.TranscodingTempPath;
|
||||
|
||||
foreach (var file in _fileSystem.GetFilePaths(path, true)
|
||||
.ToList())
|
||||
foreach (var file in _fileSystem.GetFilePaths(path, true))
|
||||
{
|
||||
_fileSystem.DeleteFile(file);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
|
@ -60,15 +61,15 @@ namespace MediaBrowser.Api
|
|||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
public object Get(GetMetadataEditorInfo request)
|
||||
public async Task<object> Get(GetMetadataEditorInfo request)
|
||||
{
|
||||
var item = _libraryManager.GetItemById(request.ItemId);
|
||||
|
||||
var info = new MetadataEditorInfo
|
||||
{
|
||||
ParentalRatingOptions = _localizationManager.GetParentalRatings(),
|
||||
ParentalRatingOptions = _localizationManager.GetParentalRatings().ToArray(),
|
||||
ExternalIdInfos = _providerManager.GetExternalIdInfos(item).ToArray(),
|
||||
Countries = _localizationManager.GetCountries(),
|
||||
Countries = await _localizationManager.GetCountries(),
|
||||
Cultures = _localizationManager.GetCultures()
|
||||
};
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ namespace MediaBrowser.Common
|
|||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="manageLiftime">if set to <c>true</c> [manage liftime].</param>
|
||||
/// <returns>IEnumerable{``0}.</returns>
|
||||
IEnumerable<T> GetExports<T>(bool manageLiftime = true);
|
||||
IEnumerable<T> GetExports<T>(bool manageLifetime = true);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the application.
|
||||
|
@ -131,7 +131,7 @@ namespace MediaBrowser.Common
|
|||
/// <summary>
|
||||
/// Inits this instance.
|
||||
/// </summary>
|
||||
void Init();
|
||||
Task Init();
|
||||
|
||||
/// <summary>
|
||||
/// Creates the instance.
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
@ -7,11 +11,45 @@ namespace MediaBrowser.Controller.Extensions
|
|||
/// </summary>
|
||||
public static class StringExtensions
|
||||
{
|
||||
public static ILocalizationManager LocalizationManager { get; set; }
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Controller.Plugins
|
||||
{
|
||||
|
@ -10,7 +11,7 @@ namespace MediaBrowser.Controller.Plugins
|
|||
/// <summary>
|
||||
/// Runs this instance.
|
||||
/// </summary>
|
||||
void Run();
|
||||
Task RunAsync();
|
||||
}
|
||||
|
||||
public interface IRunBeforeStartup
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Model.Globalization
|
||||
|
@ -17,12 +19,12 @@ namespace MediaBrowser.Model.Globalization
|
|||
/// Gets the countries.
|
||||
/// </summary>
|
||||
/// <returns>IEnumerable{CountryInfo}.</returns>
|
||||
CountryInfo[] GetCountries();
|
||||
Task<CountryInfo[]> GetCountries();
|
||||
/// <summary>
|
||||
/// Gets the parental ratings.
|
||||
/// </summary>
|
||||
/// <returns>IEnumerable{ParentalRating}.</returns>
|
||||
ParentalRating[] GetParentalRatings();
|
||||
IEnumerable<ParentalRating> GetParentalRatings();
|
||||
/// <summary>
|
||||
/// Gets the rating level.
|
||||
/// </summary>
|
||||
|
@ -51,8 +53,6 @@ namespace MediaBrowser.Model.Globalization
|
|||
/// <returns>IEnumerable{LocalizatonOption}.</returns>
|
||||
LocalizationOption[] GetLocalizationOptions();
|
||||
|
||||
string RemoveDiacritics(string text);
|
||||
|
||||
string NormalizeFormKD(string text);
|
||||
|
||||
bool HasUnicodeCategory(string value, UnicodeCategory category);
|
||||
|
|
|
@ -566,8 +566,7 @@ namespace MediaBrowser.Providers.Manager
|
|||
var providersWithChanges = providers
|
||||
.Where(i =>
|
||||
{
|
||||
var hasFileChangeMonitor = i as IHasItemChangeMonitor;
|
||||
if (hasFileChangeMonitor != null)
|
||||
if (i is IHasItemChangeMonitor hasFileChangeMonitor)
|
||||
{
|
||||
return HasChanged(item, hasFileChangeMonitor, options.DirectoryService);
|
||||
}
|
||||
|
|
|
@ -74,18 +74,13 @@ namespace MediaBrowser.Providers.MediaInfo
|
|||
}
|
||||
}
|
||||
|
||||
if (item.SupportsLocalMetadata)
|
||||
{
|
||||
if (video != null && !video.IsPlaceHolder)
|
||||
{
|
||||
if (!video.SubtitleFiles
|
||||
.SequenceEqual(_subtitleResolver.GetExternalSubtitleFiles(video, directoryService, false), StringComparer.Ordinal))
|
||||
if (item.SupportsLocalMetadata && video != null && !video.IsPlaceHolder
|
||||
&& !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;
|
||||
}
|
||||
|
|
|
@ -36,12 +36,6 @@ namespace MediaBrowser.Providers.MediaInfo
|
|||
_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()
|
||||
{
|
||||
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 bool IsHidden => false;
|
||||
|
||||
public bool IsEnabled => true;
|
||||
|
||||
public bool IsLogged => true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -425,11 +425,9 @@ namespace MediaBrowser.WebDashboard.Api
|
|||
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 fs = _fileSystem.GetFileStream(destinationFilePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
|
||||
{
|
||||
stream.CopyTo(fs);
|
||||
}
|
||||
await stream.CopyToAsync(fs);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common;
|
||||
using MediaBrowser.Controller.Plugins;
|
||||
|
||||
|
@ -23,9 +24,11 @@ namespace MediaBrowser.WebDashboard
|
|||
Instance = this;
|
||||
}
|
||||
|
||||
public void Run()
|
||||
public Task RunAsync()
|
||||
{
|
||||
PluginConfigurationPages = _appHost.GetExports<IPluginConfigurationPage>().ToList();
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
|
@ -28,9 +29,11 @@ namespace MediaBrowser.XbmcMetadata
|
|||
_config = config;
|
||||
}
|
||||
|
||||
public void Run()
|
||||
public Task RunAsync()
|
||||
{
|
||||
_userDataManager.UserDataSaved += _userDataManager_UserDataSaved;
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
void _userDataManager_UserDataSaved(object sender, UserDataSaveEventArgs e)
|
||||
|
|
|
@ -68,8 +68,7 @@ new_version="$1"
|
|||
# Parse the version from the AssemblyVersion
|
||||
old_version="$(
|
||||
grep "AssemblyVersion" ${shared_version_file} \
|
||||
| sed -E 's/\[assembly: ?AssemblyVersion\("([0-9\.]+)"\)\]/\1/' \
|
||||
| sed -E 's/.0$//'
|
||||
| sed -E 's/\[assembly: ?AssemblyVersion\("([0-9\.]+)"\)\]/\1/'
|
||||
)"
|
||||
|
||||
# Set the shared version to the specified new_version
|
||||
|
|
15
deployment/centos-package-x64/Dockerfile
Normal file
15
deployment/centos-package-x64/Dockerfile
Normal 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;
|
1
deployment/centos-package-x64/clean.sh
Symbolic link
1
deployment/centos-package-x64/clean.sh
Symbolic link
|
@ -0,0 +1 @@
|
|||
../fedora-package-x64/clean.sh
|
1
deployment/centos-package-x64/package.sh
Symbolic link
1
deployment/centos-package-x64/package.sh
Symbolic link
|
@ -0,0 +1 @@
|
|||
../fedora-package-x64/package.sh
|
1
deployment/centos-package-x64/pkg-src
Symbolic link
1
deployment/centos-package-x64/pkg-src
Symbolic link
|
@ -0,0 +1 @@
|
|||
../fedora-package-x64/pkg-src
|
|
@ -18,7 +18,7 @@
|
|||
JELLYFIN_DATA_DIRECTORY="/var/lib/jellyfin"
|
||||
JELLYFIN_CONFIG_DIRECTORY="/etc/jellyfin"
|
||||
JELLYFIN_LOG_DIRECTORY="/var/log/jellyfin"
|
||||
JELLYFIN_CACHE_DIRECTORY="/var/log/jellyfin"
|
||||
JELLYFIN_CACHE_DIRECTORY="/var/cache/jellyfin"
|
||||
|
||||
# In-App service control
|
||||
JELLYFIN_RESTART_OPT="--restartpath=/usr/libexec/jellyfin/restart.sh"
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
%global debug_package %{nil}
|
||||
# jellyfin tag to package
|
||||
%global gittag v10.1.0
|
||||
# Taglib-sharp commit of the submodule since github archive doesn't include submodules
|
||||
%global taglib_commit ee5ab21742b71fd1b87ee24895582327e9e04776
|
||||
%global taglib_shortcommit %(c=%{taglib_commit}; echo ${c:0:7})
|
||||
# Set the dotnet runtime
|
||||
%if 0%{?fedora}
|
||||
%global dotnet_runtime fedora-x64
|
||||
%else
|
||||
%global dotnet_runtime centos-x64
|
||||
%endif
|
||||
|
||||
AutoReq: no
|
||||
Name: jellyfin
|
||||
Version: 10.1.0
|
||||
Release: 1%{?dist}
|
||||
|
@ -31,13 +31,11 @@ BuildRequires: dotnet-sdk-2.2
|
|||
# RPMfusion free
|
||||
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:Requires: compat-openssl10}
|
||||
# Disable Automatic Dependency Processing for Centos
|
||||
%{?el7:AutoReqProv: no}
|
||||
|
||||
# Disable Automatic Dependency Processing
|
||||
AutoReqProv: no
|
||||
|
||||
%description
|
||||
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
|
||||
export DOTNET_CLI_TELEMETRY_OPTOUT=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 %{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
|
||||
|
@ -63,6 +61,7 @@ EOF
|
|||
%{__mkdir} -p %{buildroot}%{_sharedstatedir}/jellyfin
|
||||
%{__mkdir} -p %{buildroot}%{_sysconfdir}/%{name}
|
||||
%{__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 %{SOURCE2} %{buildroot}%{_sysconfdir}/sysconfig/%{name}
|
||||
|
@ -90,8 +89,9 @@ EOF
|
|||
%config(noreplace) %attr(600,root,root) %{_sysconfdir}/sudoers.d/%{name}-sudoers
|
||||
%config(noreplace) %{_sysconfdir}/systemd/system/%{name}.service.d/override.conf
|
||||
%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(750,jellyfin,jellyfin) %dir %{_var}/cache/jellyfin
|
||||
%if 0%{?fedora}
|
||||
%license LICENSE
|
||||
%else
|
||||
|
@ -106,7 +106,7 @@ getent passwd jellyfin >/dev/null || \
|
|||
exit 0
|
||||
|
||||
%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
|
||||
service_state=$(systemctl is-active jellyfin.service)
|
||||
if [ "${service_state}" = "active" ]; then
|
||||
|
@ -122,6 +122,11 @@ if [ $1 -gt 1 ] ; then
|
|||
rmdir %{_sharedstatedir}/%{name}/logs
|
||||
ln -sf %{_var}/log/jellyfin %{_sharedstatedir}/%{name}/logs
|
||||
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
|
||||
systemctl start jellyfin.service
|
||||
fi
|
||||
|
|
Loading…
Reference in New Issue
Block a user