aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS.md1
-rw-r--r--Emby.Dlna/DlnaManager.cs9
-rw-r--r--Emby.Dlna/Main/DlnaEntryPoint.cs4
-rw-r--r--Emby.Notifications/Notifications.cs4
-rw-r--r--Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs5
-rw-r--r--Emby.Server.Implementations/ApplicationHost.cs50
-rw-r--r--Emby.Server.Implementations/Collections/CollectionManager.cs2
-rw-r--r--Emby.Server.Implementations/Devices/DeviceManager.cs2
-rw-r--r--Emby.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs4
-rw-r--r--Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs8
-rw-r--r--Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs5
-rw-r--r--Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs5
-rw-r--r--Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs5
-rw-r--r--Emby.Server.Implementations/EntryPoints/StartupWizard.cs7
-rw-r--r--Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs5
-rw-r--r--Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs4
-rw-r--r--Emby.Server.Implementations/IO/LibraryMonitor.cs3
-rw-r--r--Emby.Server.Implementations/Library/MediaSourceManager.cs16
-rw-r--r--Emby.Server.Implementations/Library/UserManager.cs4
-rw-r--r--Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs2
-rw-r--r--Emby.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs5
-rw-r--r--Emby.Server.Implementations/Localization/LocalizationManager.cs282
-rw-r--r--Emby.Server.Implementations/Localization/Ratings/br.csv (renamed from Emby.Server.Implementations/Localization/Ratings/br.txt)0
-rw-r--r--Emby.Server.Implementations/Localization/Ratings/ca.csv (renamed from Emby.Server.Implementations/Localization/Ratings/ca.txt)0
-rw-r--r--Emby.Server.Implementations/Localization/Ratings/co.csv (renamed from Emby.Server.Implementations/Localization/Ratings/co.txt)0
-rw-r--r--Emby.Server.Implementations/Localization/Ratings/dk.csv (renamed from Emby.Server.Implementations/Localization/Ratings/dk.txt)0
-rw-r--r--Emby.Server.Implementations/Localization/Ratings/es.csv (renamed from Emby.Server.Implementations/Localization/Ratings/es.txt)0
-rw-r--r--Emby.Server.Implementations/Localization/Ratings/fr.csv (renamed from Emby.Server.Implementations/Localization/Ratings/fr.txt)0
-rw-r--r--Emby.Server.Implementations/Localization/Ratings/gb.csv (renamed from Emby.Server.Implementations/Localization/Ratings/gb.txt)0
-rw-r--r--Emby.Server.Implementations/Localization/Ratings/ie.csv (renamed from Emby.Server.Implementations/Localization/Ratings/ie.txt)0
-rw-r--r--Emby.Server.Implementations/Localization/Ratings/jp.csv (renamed from Emby.Server.Implementations/Localization/Ratings/jp.txt)0
-rw-r--r--Emby.Server.Implementations/Localization/Ratings/kz.csv (renamed from Emby.Server.Implementations/Localization/Ratings/kz.txt)0
-rw-r--r--Emby.Server.Implementations/Localization/Ratings/mx.csv (renamed from Emby.Server.Implementations/Localization/Ratings/mx.txt)0
-rw-r--r--Emby.Server.Implementations/Localization/Ratings/nl.csv (renamed from Emby.Server.Implementations/Localization/Ratings/nl.txt)0
-rw-r--r--Emby.Server.Implementations/Localization/Ratings/nz.csv (renamed from Emby.Server.Implementations/Localization/Ratings/nz.txt)0
-rw-r--r--Emby.Server.Implementations/Localization/Ratings/ro.csv (renamed from Emby.Server.Implementations/Localization/Ratings/ro.txt)0
-rw-r--r--Emby.Server.Implementations/Localization/Ratings/uk.csv (renamed from Emby.Server.Implementations/Localization/Ratings/uk.txt)0
-rw-r--r--Emby.Server.Implementations/Localization/Ratings/us.csv (renamed from Emby.Server.Implementations/Localization/Ratings/us.txt)0
-rw-r--r--Emby.Server.Implementations/Localization/TextLocalizer.cs63
-rw-r--r--Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs (renamed from Emby.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs)22
-rw-r--r--Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs22
-rw-r--r--Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs22
-rw-r--r--Emby.Server.Implementations/ScheduledTasks/Tasks/PeopleValidationTask.cs (renamed from Emby.Server.Implementations/ScheduledTasks/PeopleValidationTask.cs)22
-rw-r--r--Emby.Server.Implementations/ScheduledTasks/Tasks/PluginUpdateTask.cs119
-rw-r--r--Emby.Server.Implementations/ScheduledTasks/Tasks/RefreshMediaLibraryTask.cs (renamed from Emby.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs)18
-rw-r--r--Emby.Server.Implementations/ScheduledTasks/Triggers/DailyTrigger.cs (renamed from Emby.Server.Implementations/ScheduledTasks/DailyTrigger.cs)0
-rw-r--r--Emby.Server.Implementations/ScheduledTasks/Triggers/IntervalTrigger.cs (renamed from Emby.Server.Implementations/ScheduledTasks/IntervalTrigger.cs)0
-rw-r--r--Emby.Server.Implementations/ScheduledTasks/Triggers/StartupTrigger.cs (renamed from Emby.Server.Implementations/ScheduledTasks/StartupTrigger.cs)0
-rw-r--r--Emby.Server.Implementations/ScheduledTasks/Triggers/WeeklyTrigger.cs (renamed from Emby.Server.Implementations/ScheduledTasks/WeeklyTrigger.cs)0
-rw-r--r--Emby.Server.Implementations/Updates/InstallationManager.cs14
-rw-r--r--Jellyfin.Server/Program.cs6
-rw-r--r--MediaBrowser.Api/ApiEntryPoint.cs7
-rw-r--r--MediaBrowser.Api/ItemUpdateService.cs7
-rw-r--r--MediaBrowser.Common/IApplicationHost.cs4
-rw-r--r--MediaBrowser.Controller/Extensions/StringExtensions.cs46
-rw-r--r--MediaBrowser.Controller/Plugins/IServerEntryPoint.cs3
-rw-r--r--MediaBrowser.Model/Globalization/ILocalizationManager.cs8
-rw-r--r--MediaBrowser.Providers/Manager/MetadataService.cs3
-rw-r--r--MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs15
-rw-r--r--MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs18
-rw-r--r--MediaBrowser.WebDashboard/Api/DashboardService.cs6
-rw-r--r--MediaBrowser.WebDashboard/ServerEntryPoint.cs5
-rw-r--r--MediaBrowser.XbmcMetadata/EntryPoint.cs5
63 files changed, 450 insertions, 417 deletions
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index eca16ad38..5e3455fba 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -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)
diff --git a/Emby.Dlna/DlnaManager.cs b/Emby.Dlna/DlnaManager.cs
index a43888270..c507b14e9 100644
--- a/Emby.Dlna/DlnaManager.cs
+++ b/Emby.Dlna/DlnaManager.cs
@@ -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);
}
}
}
diff --git a/Emby.Dlna/Main/DlnaEntryPoint.cs b/Emby.Dlna/Main/DlnaEntryPoint.cs
index ad90da49b..7398b24cd 100644
--- a/Emby.Dlna/Main/DlnaEntryPoint.cs
+++ b/Emby.Dlna/Main/DlnaEntryPoint.cs
@@ -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();
diff --git a/Emby.Notifications/Notifications.cs b/Emby.Notifications/Notifications.cs
index fbdc39f94..045aa6f16 100644
--- a/Emby.Notifications/Notifications.cs
+++ b/Emby.Notifications/Notifications.cs
@@ -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)
diff --git a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
index 54b70d3b5..739f68767 100644
--- a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
+++ b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
@@ -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)
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index c59a648e5..365eb5856 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -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);
diff --git a/Emby.Server.Implementations/Collections/CollectionManager.cs b/Emby.Server.Implementations/Collections/CollectionManager.cs
index c8b822970..812e48a1f 100644
--- a/Emby.Server.Implementations/Collections/CollectionManager.cs
+++ b/Emby.Server.Implementations/Collections/CollectionManager.cs
@@ -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)
{
diff --git a/Emby.Server.Implementations/Devices/DeviceManager.cs b/Emby.Server.Implementations/Devices/DeviceManager.cs
index e94a649bf..ec3649bca 100644
--- a/Emby.Server.Implementations/Devices/DeviceManager.cs
+++ b/Emby.Server.Implementations/Devices/DeviceManager.cs
@@ -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)
{
diff --git a/Emby.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs
index 0fc4c3858..361656ff2 100644
--- a/Emby.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs
+++ b/Emby.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs
@@ -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)
diff --git a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
index 8755ee3a7..56c730c80 100644
--- a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
+++ b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
@@ -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()
diff --git a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
index a670a289c..9b61809c7 100644
--- a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
+++ b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
@@ -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>();
diff --git a/Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs b/Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs
index e37ea96a1..0186da9e1 100644
--- a/Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs
+++ b/Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs
@@ -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)
diff --git a/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs b/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs
index 92ea3a8f4..091dd6a45 100644
--- a/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs
+++ b/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs
@@ -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)
diff --git a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs
index bb96120f4..8be6db87d 100644
--- a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs
+++ b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs
@@ -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>
diff --git a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs
index 2c8246d13..5b90dc1fb 100644
--- a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs
+++ b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs
@@ -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>
diff --git a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs
index 69784e410..d91a2d581 100644
--- a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs
+++ b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs
@@ -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)
diff --git a/Emby.Server.Implementations/IO/LibraryMonitor.cs b/Emby.Server.Implementations/IO/LibraryMonitor.cs
index ed5fddb52..3a746ef60 100644
--- a/Emby.Server.Implementations/IO/LibraryMonitor.cs
+++ b/Emby.Server.Implementations/IO/LibraryMonitor.cs
@@ -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()
diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs
index b83fb9b39..4f72651d4 100644
--- a/Emby.Server.Implementations/Library/MediaSourceManager.cs
+++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs
@@ -322,18 +322,18 @@ namespace Emby.Server.Implementations.Library
private string[] NormalizeLanguage(string language)
{
- if (language != null)
+ if (language == null)
{
- var culture = _localizationManager.FindLanguageInfo(language);
- if (culture != null)
- {
- return culture.ThreeLetterISOLanguageNames;
- }
+ return Array.Empty<string>();
+ }
- return new string[] { language };
+ var culture = _localizationManager.FindLanguageInfo(language);
+ if (culture != null)
+ {
+ return culture.ThreeLetterISOLanguageNames;
}
- return Array.Empty<string>();
+ return new string[] { language };
}
private void SetDefaultSubtitleStreamIndex(MediaSourceInfo source, UserItemData userData, User user, bool allowRememberingSelection)
diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs
index b33ae72b7..6dd9366b0 100644
--- a/Emby.Server.Implementations/Library/UserManager.cs
+++ b/Emby.Server.Implementations/Library/UserManager.cs
@@ -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)
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
index bce9c240d..c5ab568ae 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
@@ -123,7 +123,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
}
}
- public async void Start()
+ public async Task Start()
{
_timerProvider.RestartTimers();
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs
index 982a54b68..9c9ba09f5 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EntryPoint.cs
@@ -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()
diff --git a/Emby.Server.Implementations/Localization/LocalizationManager.cs b/Emby.Server.Implementations/Localization/LocalizationManager.cs
index 3c2f9b427..262ca24ec 100644
--- a/Emby.Server.Implementations/Localization/LocalizationManager.cs
+++ b/Emby.Server.Implementations/Localization/LocalizationManager.cs
@@ -4,12 +4,14 @@ using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Reflection;
using MediaBrowser.Model.Serialization;
using Microsoft.Extensions.Logging;
@@ -36,8 +38,7 @@ namespace Emby.Server.Implementations.Localization
private readonly IFileSystem _fileSystem;
private readonly IJsonSerializer _jsonSerializer;
private readonly ILogger _logger;
- private readonly IAssemblyInfo _assemblyInfo;
- private readonly ITextLocalizer _textLocalizer;
+ private static readonly Assembly _assembly = typeof(LocalizationManager).Assembly;
/// <summary>
/// Initializes a new instance of the <see cref="LocalizationManager" /> class.
@@ -49,67 +50,57 @@ namespace Emby.Server.Implementations.Localization
IServerConfigurationManager configurationManager,
IFileSystem fileSystem,
IJsonSerializer jsonSerializer,
- ILoggerFactory loggerFactory,
- IAssemblyInfo assemblyInfo,
- ITextLocalizer textLocalizer)
+ ILoggerFactory loggerFactory)
{
_configurationManager = configurationManager;
_fileSystem = fileSystem;
_jsonSerializer = jsonSerializer;
_logger = loggerFactory.CreateLogger(nameof(LocalizationManager));
- _assemblyInfo = assemblyInfo;
- _textLocalizer = textLocalizer;
-
- ExtractAll();
}
- private void ExtractAll()
+ public async Task LoadAll()
{
- var type = GetType();
- var resourcePath = type.Namespace + ".Ratings.";
-
- var localizationPath = LocalizationPath;
+ const string ratingsResource = "Emby.Server.Implementations.Ratings.";
- Directory.CreateDirectory(localizationPath);
+ Directory.CreateDirectory(LocalizationPath);
- var existingFiles = GetRatingsFiles(localizationPath)
- .Select(Path.GetFileName)
- .ToList();
+ var existingFiles = GetRatingsFiles(LocalizationPath).Select(Path.GetFileName);
// Extract from the assembly
- foreach (var resource in _assemblyInfo
- .GetManifestResourceNames(type)
- .Where(i => i.StartsWith(resourcePath)))
+ foreach (var resource in _assembly.GetManifestResourceNames()
+ .Where(i => i.StartsWith(ratingsResource)))
{
- var filename = "ratings-" + resource.Substring(resourcePath.Length);
+ string filename = "ratings-" + resource.Substring(ratingsResource.Length);
if (!existingFiles.Contains(filename))
{
- using (var stream = _assemblyInfo.GetManifestResourceStream(type, resource))
+ using (var stream = _assembly.GetManifestResourceStream(resource))
{
- var target = Path.Combine(localizationPath, filename);
+ string target = Path.Combine(LocalizationPath, filename);
_logger.LogInformation("Extracting ratings to {0}", target);
using (var fs = _fileSystem.GetFileStream(target, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
{
- stream.CopyTo(fs);
+ await stream.CopyToAsync(fs);
}
}
}
}
- foreach (var file in GetRatingsFiles(localizationPath))
+ foreach (var file in GetRatingsFiles(LocalizationPath))
{
- LoadRatings(file);
+ await LoadRatings(file);
}
LoadAdditionalRatings();
+
+ await LoadCultures();
}
private void LoadAdditionalRatings()
{
- LoadRatings("au", new[] {
-
+ LoadRatings("au", new[]
+ {
new ParentalRating("AU-G", 1),
new ParentalRating("AU-PG", 5),
new ParentalRating("AU-M", 6),
@@ -120,8 +111,8 @@ namespace Emby.Server.Implementations.Localization
new ParentalRating("AU-RC", 11)
});
- LoadRatings("be", new[] {
-
+ LoadRatings("be", new[]
+ {
new ParentalRating("BE-AL", 1),
new ParentalRating("BE-MG6", 2),
new ParentalRating("BE-6", 3),
@@ -130,8 +121,8 @@ namespace Emby.Server.Implementations.Localization
new ParentalRating("BE-16", 8)
});
- LoadRatings("de", new[] {
-
+ LoadRatings("de", new[]
+ {
new ParentalRating("DE-0", 1),
new ParentalRating("FSK-0", 1),
new ParentalRating("DE-6", 5),
@@ -144,8 +135,8 @@ namespace Emby.Server.Implementations.Localization
new ParentalRating("FSK-18", 9)
});
- LoadRatings("ru", new[] {
-
+ LoadRatings("ru", new[]
+ {
new ParentalRating("RU-0+", 1),
new ParentalRating("RU-6+", 3),
new ParentalRating("RU-12+", 7),
@@ -159,29 +150,20 @@ namespace Emby.Server.Implementations.Localization
_allParentalRatings[country] = ratings.ToDictionary(i => i.Name);
}
- private List<string> GetRatingsFiles(string directory)
- {
- return _fileSystem.GetFilePaths(directory, false)
- .Where(i => string.Equals(Path.GetExtension(i), ".txt", StringComparison.OrdinalIgnoreCase))
- .Where(i => Path.GetFileName(i).StartsWith("ratings-", StringComparison.OrdinalIgnoreCase))
- .ToList();
- }
+ private IEnumerable<string> GetRatingsFiles(string directory)
+ => _fileSystem.GetFilePaths(directory, false)
+ .Where(i => string.Equals(Path.GetExtension(i), ".csv", StringComparison.OrdinalIgnoreCase))
+ .Where(i => Path.GetFileName(i).StartsWith("ratings-", StringComparison.OrdinalIgnoreCase));
/// <summary>
/// Gets the localization path.
/// </summary>
/// <value>The localization path.</value>
- public string LocalizationPath => Path.Combine(_configurationManager.ApplicationPaths.ProgramDataPath, "localization");
-
- public string RemoveDiacritics(string text)
- {
- return _textLocalizer.RemoveDiacritics(text);
- }
+ public string LocalizationPath
+ => Path.Combine(_configurationManager.ApplicationPaths.ProgramDataPath, "localization");
public string NormalizeFormKD(string text)
- {
- return _textLocalizer.NormalizeFormKD(text);
- }
+ => text.Normalize(NormalizationForm.FormKD);
private CultureDto[] _cultures;
@@ -190,90 +172,88 @@ namespace Emby.Server.Implementations.Localization
/// </summary>
/// <returns>IEnumerable{CultureDto}.</returns>
public CultureDto[] GetCultures()
- {
- var result = _cultures;
- if (result != null)
- {
- return result;
- }
+ => _cultures;
- var type = GetType();
- var path = type.Namespace + ".iso6392.txt";
+ private async Task LoadCultures()
+ {
+ List<CultureDto> list = new List<CultureDto>();
- var list = new List<CultureDto>();
+ const string path = "Emby.Server.Implementations.Localization.iso6392.txt";
- using (var stream = _assemblyInfo.GetManifestResourceStream(type, path))
+ using (var stream = _assembly.GetManifestResourceStream(path))
+ using (var reader = new StreamReader(stream))
{
- using (var reader = new StreamReader(stream))
+ while (!reader.EndOfStream)
{
- while (!reader.EndOfStream)
+ var line = await reader.ReadLineAsync();
+
+ if (string.IsNullOrWhiteSpace(line))
+ {
+ continue;
+ }
+
+ var parts = line.Split('|');
+
+ if (parts.Length == 5)
{
- var line = reader.ReadLine();
+ string name = parts[3];
+ if (string.IsNullOrWhiteSpace(name))
+ {
+ continue;
+ }
- if (!string.IsNullOrWhiteSpace(line))
+ string twoCharName = parts[2];
+ if (string.IsNullOrWhiteSpace(twoCharName))
+ {
+ continue;
+ }
+
+ string[] threeletterNames;
+ if (string.IsNullOrWhiteSpace(parts[1]))
+ {
+ threeletterNames = new [] { parts[0] };
+ }
+ else
{
- var parts = line.Split('|');
-
- if (parts.Length == 5)
- {
- var threeletterNames = new List<string> { parts[0] };
- if (!string.IsNullOrWhiteSpace(parts[1]))
- {
- threeletterNames.Add(parts[1]);
- }
-
- list.Add(new CultureDto
- {
- DisplayName = parts[3],
- Name = parts[3],
- ThreeLetterISOLanguageNames = threeletterNames.ToArray(),
- TwoLetterISOLanguageName = parts[2]
- });
- }
+ threeletterNames = new [] { parts[0], parts[1] };
}
+
+ list.Add(new CultureDto
+ {
+ DisplayName = name,
+ Name = name,
+ ThreeLetterISOLanguageNames = threeletterNames,
+ TwoLetterISOLanguageName = twoCharName
+ });
}
}
}
- result = list.Where(i => !string.IsNullOrWhiteSpace(i.Name) &&
- !string.IsNullOrWhiteSpace(i.DisplayName) &&
- i.ThreeLetterISOLanguageNames.Length > 0 &&
- !string.IsNullOrWhiteSpace(i.TwoLetterISOLanguageName)).ToArray();
-
- _cultures = result;
-
- return result;
+ _cultures = list.ToArray();
}
public CultureDto FindLanguageInfo(string language)
- {
- return GetCultures()
- .FirstOrDefault(i => string.Equals(i.DisplayName, language, StringComparison.OrdinalIgnoreCase) ||
- string.Equals(i.Name, language, StringComparison.OrdinalIgnoreCase) ||
- i.ThreeLetterISOLanguageNames.Contains(language, StringComparer.OrdinalIgnoreCase) ||
- string.Equals(i.TwoLetterISOLanguageName, language, StringComparison.OrdinalIgnoreCase));
- }
+ => GetCultures()
+ .FirstOrDefault(i =>
+ string.Equals(i.DisplayName, language, StringComparison.OrdinalIgnoreCase)
+ || string.Equals(i.Name, language, StringComparison.OrdinalIgnoreCase)
+ || i.ThreeLetterISOLanguageNames.Contains(language, StringComparer.OrdinalIgnoreCase)
+ || string.Equals(i.TwoLetterISOLanguageName, language, StringComparison.OrdinalIgnoreCase));
/// <summary>
/// Gets the countries.
/// </summary>
/// <returns>IEnumerable{CountryInfo}.</returns>
- public CountryInfo[] GetCountries()
- {
- // ToDo: DeserializeFromStream seems broken in this case
- string jsonCountries = "[{\"Name\":\"AF\",\"DisplayName\":\"Afghanistan\",\"TwoLetterISORegionName\":\"AF\",\"ThreeLetterISORegionName\":\"AFG\"},{\"Name\":\"AL\",\"DisplayName\":\"Albania\",\"TwoLetterISORegionName\":\"AL\",\"ThreeLetterISORegionName\":\"ALB\"},{\"Name\":\"DZ\",\"DisplayName\":\"Algeria\",\"TwoLetterISORegionName\":\"DZ\",\"ThreeLetterISORegionName\":\"DZA\"},{\"Name\":\"AR\",\"DisplayName\":\"Argentina\",\"TwoLetterISORegionName\":\"AR\",\"ThreeLetterISORegionName\":\"ARG\"},{\"Name\":\"AM\",\"DisplayName\":\"Armenia\",\"TwoLetterISORegionName\":\"AM\",\"ThreeLetterISORegionName\":\"ARM\"},{\"Name\":\"AU\",\"DisplayName\":\"Australia\",\"TwoLetterISORegionName\":\"AU\",\"ThreeLetterISORegionName\":\"AUS\"},{\"Name\":\"AT\",\"DisplayName\":\"Austria\",\"TwoLetterISORegionName\":\"AT\",\"ThreeLetterISORegionName\":\"AUT\"},{\"Name\":\"AZ\",\"DisplayName\":\"Azerbaijan\",\"TwoLetterISORegionName\":\"AZ\",\"ThreeLetterISORegionName\":\"AZE\"},{\"Name\":\"BH\",\"DisplayName\":\"Bahrain\",\"TwoLetterISORegionName\":\"BH\",\"ThreeLetterISORegionName\":\"BHR\"},{\"Name\":\"BD\",\"DisplayName\":\"Bangladesh\",\"TwoLetterISORegionName\":\"BD\",\"ThreeLetterISORegionName\":\"BGD\"},{\"Name\":\"BY\",\"DisplayName\":\"Belarus\",\"TwoLetterISORegionName\":\"BY\",\"ThreeLetterISORegionName\":\"BLR\"},{\"Name\":\"BE\",\"DisplayName\":\"Belgium\",\"TwoLetterISORegionName\":\"BE\",\"ThreeLetterISORegionName\":\"BEL\"},{\"Name\":\"BZ\",\"DisplayName\":\"Belize\",\"TwoLetterISORegionName\":\"BZ\",\"ThreeLetterISORegionName\":\"BLZ\"},{\"Name\":\"VE\",\"DisplayName\":\"Bolivarian Republic of Venezuela\",\"TwoLetterISORegionName\":\"VE\",\"ThreeLetterISORegionName\":\"VEN\"},{\"Name\":\"BO\",\"DisplayName\":\"Bolivia\",\"TwoLetterISORegionName\":\"BO\",\"ThreeLetterISORegionName\":\"BOL\"},{\"Name\":\"BA\",\"DisplayName\":\"Bosnia and Herzegovina\",\"TwoLetterISORegionName\":\"BA\",\"ThreeLetterISORegionName\":\"BIH\"},{\"Name\":\"BW\",\"DisplayName\":\"Botswana\",\"TwoLetterISORegionName\":\"BW\",\"ThreeLetterISORegionName\":\"BWA\"},{\"Name\":\"BR\",\"DisplayName\":\"Brazil\",\"TwoLetterISORegionName\":\"BR\",\"ThreeLetterISORegionName\":\"BRA\"},{\"Name\":\"BN\",\"DisplayName\":\"Brunei Darussalam\",\"TwoLetterISORegionName\":\"BN\",\"ThreeLetterISORegionName\":\"BRN\"},{\"Name\":\"BG\",\"DisplayName\":\"Bulgaria\",\"TwoLetterISORegionName\":\"BG\",\"ThreeLetterISORegionName\":\"BGR\"},{\"Name\":\"KH\",\"DisplayName\":\"Cambodia\",\"TwoLetterISORegionName\":\"KH\",\"ThreeLetterISORegionName\":\"KHM\"},{\"Name\":\"CM\",\"DisplayName\":\"Cameroon\",\"TwoLetterISORegionName\":\"CM\",\"ThreeLetterISORegionName\":\"CMR\"},{\"Name\":\"CA\",\"DisplayName\":\"Canada\",\"TwoLetterISORegionName\":\"CA\",\"ThreeLetterISORegionName\":\"CAN\"},{\"Name\":\"029\",\"DisplayName\":\"Caribbean\",\"TwoLetterISORegionName\":\"029\",\"ThreeLetterISORegionName\":\"029\"},{\"Name\":\"CL\",\"DisplayName\":\"Chile\",\"TwoLetterISORegionName\":\"CL\",\"ThreeLetterISORegionName\":\"CHL\"},{\"Name\":\"CO\",\"DisplayName\":\"Colombia\",\"TwoLetterISORegionName\":\"CO\",\"ThreeLetterISORegionName\":\"COL\"},{\"Name\":\"CD\",\"DisplayName\":\"Congo [DRC]\",\"TwoLetterISORegionName\":\"CD\",\"ThreeLetterISORegionName\":\"COD\"},{\"Name\":\"CR\",\"DisplayName\":\"Costa Rica\",\"TwoLetterISORegionName\":\"CR\",\"ThreeLetterISORegionName\":\"CRI\"},{\"Name\":\"HR\",\"DisplayName\":\"Croatia\",\"TwoLetterISORegionName\":\"HR\",\"ThreeLetterISORegionName\":\"HRV\"},{\"Name\":\"CZ\",\"DisplayName\":\"Czech Republic\",\"TwoLetterISORegionName\":\"CZ\",\"ThreeLetterISORegionName\":\"CZE\"},{\"Name\":\"DK\",\"DisplayName\":\"Denmark\",\"TwoLetterISORegionName\":\"DK\",\"ThreeLetterISORegionName\":\"DNK\"},{\"Name\":\"DO\",\"DisplayName\":\"Dominican Republic\",\"TwoLetterISORegionName\":\"DO\",\"ThreeLetterISORegionName\":\"DOM\"},{\"Name\":\"EC\",\"DisplayName\":\"Ecuador\",\"TwoLetterISORegionName\":\"EC\",\"ThreeLetterISORegionName\":\"ECU\"},{\"Name\":\"EG\",\"DisplayName\":\"Egypt\",\"TwoLetterISORegionName\":\"EG\",\"ThreeLetterISORegionName\":\"EGY\"},{\"Name\":\"SV\",\"DisplayName\":\"El Salvador\",\"TwoLetterISORegionName\":\"SV\",\"ThreeLetterISORegionName\":\"SLV\"},{\"Name\":\"ER\",\"DisplayName\":\"Eritrea\",\"TwoLetterISORegionName\":\"ER\",\"ThreeLetterISORegionName\":\"ERI\"},{\"Name\":\"EE\",\"DisplayName\":\"Estonia\",\"TwoLetterISORegionName\":\"EE\",\"ThreeLetterISORegionName\":\"EST\"},{\"Name\":\"ET\",\"DisplayName\":\"Ethiopia\",\"TwoLetterISORegionName\":\"ET\",\"ThreeLetterISORegionName\":\"ETH\"},{\"Name\":\"FO\",\"DisplayName\":\"Faroe Islands\",\"TwoLetterISORegionName\":\"FO\",\"ThreeLetterISORegionName\":\"FRO\"},{\"Name\":\"FI\",\"DisplayName\":\"Finland\",\"TwoLetterISORegionName\":\"FI\",\"ThreeLetterISORegionName\":\"FIN\"},{\"Name\":\"FR\",\"DisplayName\":\"France\",\"TwoLetterISORegionName\":\"FR\",\"ThreeLetterISORegionName\":\"FRA\"},{\"Name\":\"GE\",\"DisplayName\":\"Georgia\",\"TwoLetterISORegionName\":\"GE\",\"ThreeLetterISORegionName\":\"GEO\"},{\"Name\":\"DE\",\"DisplayName\":\"Germany\",\"TwoLetterISORegionName\":\"DE\",\"ThreeLetterISORegionName\":\"DEU\"},{\"Name\":\"GR\",\"DisplayName\":\"Greece\",\"TwoLetterISORegionName\":\"GR\",\"ThreeLetterISORegionName\":\"GRC\"},{\"Name\":\"GL\",\"DisplayName\":\"Greenland\",\"TwoLetterISORegionName\":\"GL\",\"ThreeLetterISORegionName\":\"GRL\"},{\"Name\":\"GT\",\"DisplayName\":\"Guatemala\",\"TwoLetterISORegionName\":\"GT\",\"ThreeLetterISORegionName\":\"GTM\"},{\"Name\":\"HT\",\"DisplayName\":\"Haiti\",\"TwoLetterISORegionName\":\"HT\",\"ThreeLetterISORegionName\":\"HTI\"},{\"Name\":\"HN\",\"DisplayName\":\"Honduras\",\"TwoLetterISORegionName\":\"HN\",\"ThreeLetterISORegionName\":\"HND\"},{\"Name\":\"HK\",\"DisplayName\":\"Hong Kong S.A.R.\",\"TwoLetterISORegionName\":\"HK\",\"ThreeLetterISORegionName\":\"HKG\"},{\"Name\":\"HU\",\"DisplayName\":\"Hungary\",\"TwoLetterISORegionName\":\"HU\",\"ThreeLetterISORegionName\":\"HUN\"},{\"Name\":\"IS\",\"DisplayName\":\"Iceland\",\"TwoLetterISORegionName\":\"IS\",\"ThreeLetterISORegionName\":\"ISL\"},{\"Name\":\"IN\",\"DisplayName\":\"India\",\"TwoLetterISORegionName\":\"IN\",\"ThreeLetterISORegionName\":\"IND\"},{\"Name\":\"ID\",\"DisplayName\":\"Indonesia\",\"TwoLetterISORegionName\":\"ID\",\"ThreeLetterISORegionName\":\"IDN\"},{\"Name\":\"IR\",\"DisplayName\":\"Iran\",\"TwoLetterISORegionName\":\"IR\",\"ThreeLetterISORegionName\":\"IRN\"},{\"Name\":\"IQ\",\"DisplayName\":\"Iraq\",\"TwoLetterISORegionName\":\"IQ\",\"ThreeLetterISORegionName\":\"IRQ\"},{\"Name\":\"IE\",\"DisplayName\":\"Ireland\",\"TwoLetterISORegionName\":\"IE\",\"ThreeLetterISORegionName\":\"IRL\"},{\"Name\":\"PK\",\"DisplayName\":\"Islamic Republic of Pakistan\",\"TwoLetterISORegionName\":\"PK\",\"ThreeLetterISORegionName\":\"PAK\"},{\"Name\":\"IL\",\"DisplayName\":\"Israel\",\"TwoLetterISORegionName\":\"IL\",\"ThreeLetterISORegionName\":\"ISR\"},{\"Name\":\"IT\",\"DisplayName\":\"Italy\",\"TwoLetterISORegionName\":\"IT\",\"ThreeLetterISORegionName\":\"ITA\"},{\"Name\":\"CI\",\"DisplayName\":\"Ivory Coast\",\"TwoLetterISORegionName\":\"CI\",\"ThreeLetterISORegionName\":\"CIV\"},{\"Name\":\"JM\",\"DisplayName\":\"Jamaica\",\"TwoLetterISORegionName\":\"JM\",\"ThreeLetterISORegionName\":\"JAM\"},{\"Name\":\"JP\",\"DisplayName\":\"Japan\",\"TwoLetterISORegionName\":\"JP\",\"ThreeLetterISORegionName\":\"JPN\"},{\"Name\":\"JO\",\"DisplayName\":\"Jordan\",\"TwoLetterISORegionName\":\"JO\",\"ThreeLetterISORegionName\":\"JOR\"},{\"Name\":\"KZ\",\"DisplayName\":\"Kazakhstan\",\"TwoLetterISORegionName\":\"KZ\",\"ThreeLetterISORegionName\":\"KAZ\"},{\"Name\":\"KE\",\"DisplayName\":\"Kenya\",\"TwoLetterISORegionName\":\"KE\",\"ThreeLetterISORegionName\":\"KEN\"},{\"Name\":\"KR\",\"DisplayName\":\"Korea\",\"TwoLetterISORegionName\":\"KR\",\"ThreeLetterISORegionName\":\"KOR\"},{\"Name\":\"KW\",\"DisplayName\":\"Kuwait\",\"TwoLetterISORegionName\":\"KW\",\"ThreeLetterISORegionName\":\"KWT\"},{\"Name\":\"KG\",\"DisplayName\":\"Kyrgyzstan\",\"TwoLetterISORegionName\":\"KG\",\"ThreeLetterISORegionName\":\"KGZ\"},{\"Name\":\"LA\",\"DisplayName\":\"Lao P.D.R.\",\"TwoLetterISORegionName\":\"LA\",\"ThreeLetterISORegionName\":\"LAO\"},{\"Name\":\"419\",\"DisplayName\":\"Latin America\",\"TwoLetterISORegionName\":\"419\",\"ThreeLetterISORegionName\":\"419\"},{\"Name\":\"LV\",\"DisplayName\":\"Latvia\",\"TwoLetterISORegionName\":\"LV\",\"ThreeLetterISORegionName\":\"LVA\"},{\"Name\":\"LB\",\"DisplayName\":\"Lebanon\",\"TwoLetterISORegionName\":\"LB\",\"ThreeLetterISORegionName\":\"LBN\"},{\"Name\":\"LY\",\"DisplayName\":\"Libya\",\"TwoLetterISORegionName\":\"LY\",\"ThreeLetterISORegionName\":\"LBY\"},{\"Name\":\"LI\",\"DisplayName\":\"Liechtenstein\",\"TwoLetterISORegionName\":\"LI\",\"ThreeLetterISORegionName\":\"LIE\"},{\"Name\":\"LT\",\"DisplayName\":\"Lithuania\",\"TwoLetterISORegionName\":\"LT\",\"ThreeLetterISORegionName\":\"LTU\"},{\"Name\":\"LU\",\"DisplayName\":\"Luxembourg\",\"TwoLetterISORegionName\":\"LU\",\"ThreeLetterISORegionName\":\"LUX\"},{\"Name\":\"MO\",\"DisplayName\":\"Macao S.A.R.\",\"TwoLetterISORegionName\":\"MO\",\"ThreeLetterISORegionName\":\"MAC\"},{\"Name\":\"MK\",\"DisplayName\":\"Macedonia (FYROM)\",\"TwoLetterISORegionName\":\"MK\",\"ThreeLetterISORegionName\":\"MKD\"},{\"Name\":\"MY\",\"DisplayName\":\"Malaysia\",\"TwoLetterISORegionName\":\"MY\",\"ThreeLetterISORegionName\":\"MYS\"},{\"Name\":\"MV\",\"DisplayName\":\"Maldives\",\"TwoLetterISORegionName\":\"MV\",\"ThreeLetterISORegionName\":\"MDV\"},{\"Name\":\"ML\",\"DisplayName\":\"Mali\",\"TwoLetterISORegionName\":\"ML\",\"ThreeLetterISORegionName\":\"MLI\"},{\"Name\":\"MT\",\"DisplayName\":\"Malta\",\"TwoLetterISORegionName\":\"MT\",\"ThreeLetterISORegionName\":\"MLT\"},{\"Name\":\"MX\",\"DisplayName\":\"Mexico\",\"TwoLetterISORegionName\":\"MX\",\"ThreeLetterISORegionName\":\"MEX\"},{\"Name\":\"MN\",\"DisplayName\":\"Mongolia\",\"TwoLetterISORegionName\":\"MN\",\"ThreeLetterISORegionName\":\"MNG\"},{\"Name\":\"ME\",\"DisplayName\":\"Montenegro\",\"TwoLetterISORegionName\":\"ME\",\"ThreeLetterISORegionName\":\"MNE\"},{\"Name\":\"MA\",\"DisplayName\":\"Morocco\",\"TwoLetterISORegionName\":\"MA\",\"ThreeLetterISORegionName\":\"MAR\"},{\"Name\":\"NP\",\"DisplayName\":\"Nepal\",\"TwoLetterISORegionName\":\"NP\",\"ThreeLetterISORegionName\":\"NPL\"},{\"Name\":\"NL\",\"DisplayName\":\"Netherlands\",\"TwoLetterISORegionName\":\"NL\",\"ThreeLetterISORegionName\":\"NLD\"},{\"Name\":\"NZ\",\"DisplayName\":\"New Zealand\",\"TwoLetterISORegionName\":\"NZ\",\"ThreeLetterISORegionName\":\"NZL\"},{\"Name\":\"NI\",\"DisplayName\":\"Nicaragua\",\"TwoLetterISORegionName\":\"NI\",\"ThreeLetterISORegionName\":\"NIC\"},{\"Name\":\"NG\",\"DisplayName\":\"Nigeria\",\"TwoLetterISORegionName\":\"NG\",\"ThreeLetterISORegionName\":\"NGA\"},{\"Name\":\"NO\",\"DisplayName\":\"Norway\",\"TwoLetterISORegionName\":\"NO\",\"ThreeLetterISORegionName\":\"NOR\"},{\"Name\":\"OM\",\"DisplayName\":\"Oman\",\"TwoLetterISORegionName\":\"OM\",\"ThreeLetterISORegionName\":\"OMN\"},{\"Name\":\"PA\",\"DisplayName\":\"Panama\",\"TwoLetterISORegionName\":\"PA\",\"ThreeLetterISORegionName\":\"PAN\"},{\"Name\":\"PY\",\"DisplayName\":\"Paraguay\",\"TwoLetterISORegionName\":\"PY\",\"ThreeLetterISORegionName\":\"PRY\"},{\"Name\":\"CN\",\"DisplayName\":\"People's Republic of China\",\"TwoLetterISORegionName\":\"CN\",\"ThreeLetterISORegionName\":\"CHN\"},{\"Name\":\"PE\",\"DisplayName\":\"Peru\",\"TwoLetterISORegionName\":\"PE\",\"ThreeLetterISORegionName\":\"PER\"},{\"Name\":\"PH\",\"DisplayName\":\"Philippines\",\"TwoLetterISORegionName\":\"PH\",\"ThreeLetterISORegionName\":\"PHL\"},{\"Name\":\"PL\",\"DisplayName\":\"Poland\",\"TwoLetterISORegionName\":\"PL\",\"ThreeLetterISORegionName\":\"POL\"},{\"Name\":\"PT\",\"DisplayName\":\"Portugal\",\"TwoLetterISORegionName\":\"PT\",\"ThreeLetterISORegionName\":\"PRT\"},{\"Name\":\"MC\",\"DisplayName\":\"Principality of Monaco\",\"TwoLetterISORegionName\":\"MC\",\"ThreeLetterISORegionName\":\"MCO\"},{\"Name\":\"PR\",\"DisplayName\":\"Puerto Rico\",\"TwoLetterISORegionName\":\"PR\",\"ThreeLetterISORegionName\":\"PRI\"},{\"Name\":\"QA\",\"DisplayName\":\"Qatar\",\"TwoLetterISORegionName\":\"QA\",\"ThreeLetterISORegionName\":\"QAT\"},{\"Name\":\"MD\",\"DisplayName\":\"Republica Moldova\",\"TwoLetterISORegionName\":\"MD\",\"ThreeLetterISORegionName\":\"MDA\"},{\"Name\":\"RE\",\"DisplayName\":\"Réunion\",\"TwoLetterISORegionName\":\"RE\",\"ThreeLetterISORegionName\":\"REU\"},{\"Name\":\"RO\",\"DisplayName\":\"Romania\",\"TwoLetterISORegionName\":\"RO\",\"ThreeLetterISORegionName\":\"ROU\"},{\"Name\":\"RU\",\"DisplayName\":\"Russia\",\"TwoLetterISORegionName\":\"RU\",\"ThreeLetterISORegionName\":\"RUS\"},{\"Name\":\"RW\",\"DisplayName\":\"Rwanda\",\"TwoLetterISORegionName\":\"RW\",\"ThreeLetterISORegionName\":\"RWA\"},{\"Name\":\"SA\",\"DisplayName\":\"Saudi Arabia\",\"TwoLetterISORegionName\":\"SA\",\"ThreeLetterISORegionName\":\"SAU\"},{\"Name\":\"SN\",\"DisplayName\":\"Senegal\",\"TwoLetterISORegionName\":\"SN\",\"ThreeLetterISORegionName\":\"SEN\"},{\"Name\":\"RS\",\"DisplayName\":\"Serbia\",\"TwoLetterISORegionName\":\"RS\",\"ThreeLetterISORegionName\":\"SRB\"},{\"Name\":\"CS\",\"DisplayName\":\"Serbia and Montenegro (Former)\",\"TwoLetterISORegionName\":\"CS\",\"ThreeLetterISORegionName\":\"SCG\"},{\"Name\":\"SG\",\"DisplayName\":\"Singapore\",\"TwoLetterISORegionName\":\"SG\",\"ThreeLetterISORegionName\":\"SGP\"},{\"Name\":\"SK\",\"DisplayName\":\"Slovakia\",\"TwoLetterISORegionName\":\"SK\",\"ThreeLetterISORegionName\":\"SVK\"},{\"Name\":\"SI\",\"DisplayName\":\"Slovenia\",\"TwoLetterISORegionName\":\"SI\",\"ThreeLetterISORegionName\":\"SVN\"},{\"Name\":\"SO\",\"DisplayName\":\"Soomaaliya\",\"TwoLetterISORegionName\":\"SO\",\"ThreeLetterISORegionName\":\"SOM\"},{\"Name\":\"ZA\",\"DisplayName\":\"South Africa\",\"TwoLetterISORegionName\":\"ZA\",\"ThreeLetterISORegionName\":\"ZAF\"},{\"Name\":\"ES\",\"DisplayName\":\"Spain\",\"TwoLetterISORegionName\":\"ES\",\"ThreeLetterISORegionName\":\"ESP\"},{\"Name\":\"LK\",\"DisplayName\":\"Sri Lanka\",\"TwoLetterISORegionName\":\"LK\",\"ThreeLetterISORegionName\":\"LKA\"},{\"Name\":\"SE\",\"DisplayName\":\"Sweden\",\"TwoLetterISORegionName\":\"SE\",\"ThreeLetterISORegionName\":\"SWE\"},{\"Name\":\"CH\",\"DisplayName\":\"Switzerland\",\"TwoLetterISORegionName\":\"CH\",\"ThreeLetterISORegionName\":\"CHE\"},{\"Name\":\"SY\",\"DisplayName\":\"Syria\",\"TwoLetterISORegionName\":\"SY\",\"ThreeLetterISORegionName\":\"SYR\"},{\"Name\":\"TW\",\"DisplayName\":\"Taiwan\",\"TwoLetterISORegionName\":\"TW\",\"ThreeLetterISORegionName\":\"TWN\"},{\"Name\":\"TJ\",\"DisplayName\":\"Tajikistan\",\"TwoLetterISORegionName\":\"TJ\",\"ThreeLetterISORegionName\":\"TAJ\"},{\"Name\":\"TH\",\"DisplayName\":\"Thailand\",\"TwoLetterISORegionName\":\"TH\",\"ThreeLetterISORegionName\":\"THA\"},{\"Name\":\"TT\",\"DisplayName\":\"Trinidad and Tobago\",\"TwoLetterISORegionName\":\"TT\",\"ThreeLetterISORegionName\":\"TTO\"},{\"Name\":\"TN\",\"DisplayName\":\"Tunisia\",\"TwoLetterISORegionName\":\"TN\",\"ThreeLetterISORegionName\":\"TUN\"},{\"Name\":\"TR\",\"DisplayName\":\"Turkey\",\"TwoLetterISORegionName\":\"TR\",\"ThreeLetterISORegionName\":\"TUR\"},{\"Name\":\"TM\",\"DisplayName\":\"Turkmenistan\",\"TwoLetterISORegionName\":\"TM\",\"ThreeLetterISORegionName\":\"TKM\"},{\"Name\":\"AE\",\"DisplayName\":\"U.A.E.\",\"TwoLetterISORegionName\":\"AE\",\"ThreeLetterISORegionName\":\"ARE\"},{\"Name\":\"UA\",\"DisplayName\":\"Ukraine\",\"TwoLetterISORegionName\":\"UA\",\"ThreeLetterISORegionName\":\"UKR\"},{\"Name\":\"GB\",\"DisplayName\":\"United Kingdom\",\"TwoLetterISORegionName\":\"GB\",\"ThreeLetterISORegionName\":\"GBR\"},{\"Name\":\"US\",\"DisplayName\":\"United States\",\"TwoLetterISORegionName\":\"US\",\"ThreeLetterISORegionName\":\"USA\"},{\"Name\":\"UY\",\"DisplayName\":\"Uruguay\",\"TwoLetterISORegionName\":\"UY\",\"ThreeLetterISORegionName\":\"URY\"},{\"Name\":\"UZ\",\"DisplayName\":\"Uzbekistan\",\"TwoLetterISORegionName\":\"UZ\",\"ThreeLetterISORegionName\":\"UZB\"},{\"Name\":\"VN\",\"DisplayName\":\"Vietnam\",\"TwoLetterISORegionName\":\"VN\",\"ThreeLetterISORegionName\":\"VNM\"},{\"Name\":\"YE\",\"DisplayName\":\"Yemen\",\"TwoLetterISORegionName\":\"YE\",\"ThreeLetterISORegionName\":\"YEM\"},{\"Name\":\"ZW\",\"DisplayName\":\"Zimbabwe\",\"TwoLetterISORegionName\":\"ZW\",\"ThreeLetterISORegionName\":\"ZWE\"}]";
-
- return _jsonSerializer.DeserializeFromString<CountryInfo[]>(jsonCountries);
- }
+ public Task<CountryInfo[]> GetCountries()
+ => _jsonSerializer.DeserializeFromStreamAsync<CountryInfo[]>(
+ _assembly.GetManifestResourceStream("Emby.Server.Implementations.Localization.countries.json"));
/// <summary>
/// Gets the parental ratings.
/// </summary>
/// <returns>IEnumerable{ParentalRating}.</returns>
- public ParentalRating[] GetParentalRatings()
- {
- return GetParentalRatingsDictionary().Values.ToArray();
- }
+ public IEnumerable<ParentalRating> GetParentalRatings()
+ => GetParentalRatingsDictionary().Values;
/// <summary>
/// Gets the parental ratings dictionary.
@@ -288,14 +268,7 @@ namespace Emby.Server.Implementations.Localization
countryCode = "us";
}
- var ratings = GetRatings(countryCode);
-
- if (ratings == null)
- {
- ratings = GetRatings("us");
- }
-
- return ratings;
+ return GetRatings(countryCode) ?? GetRatings("us");
}
/// <summary>
@@ -314,37 +287,39 @@ namespace Emby.Server.Implementations.Localization
/// </summary>
/// <param name="file">The file.</param>
/// <returns>Dictionary{System.StringParentalRating}.</returns>
- private void LoadRatings(string file)
+ private async Task LoadRatings(string file)
{
- var dict = File.ReadAllLines(file).Select(i =>
+ Dictionary<string, ParentalRating> dict = new Dictionary<string, ParentalRating>(StringComparer.OrdinalIgnoreCase);
+
+ using (var str = File.OpenRead(file))
+ using (var reader = new StreamReader(str))
{
- if (!string.IsNullOrWhiteSpace(i))
+ string line;
+ while ((line = await reader.ReadLineAsync()) != null)
{
- var parts = i.Split(',');
+ if (string.IsNullOrWhiteSpace(line))
+ {
+ continue;
+ }
- if (parts.Length == 2)
+ string[] parts = line.Split(',');
+ if (parts.Length == 2
+ && int.TryParse(parts[1], NumberStyles.Integer, UsCulture, out var value))
{
- if (int.TryParse(parts[1], NumberStyles.Integer, UsCulture, out var value))
- {
- return new ParentalRating { Name = parts[0], Value = value };
- }
+ dict.Add(parts[0], (new ParentalRating { Name = parts[0], Value = value }));
}
+#if DEBUG
+ _logger.LogWarning("Misformed line in {Path}", file);
+#endif
}
+ }
- return null;
-
- })
- .Where(i => i != null)
- .ToDictionary(i => i.Name, StringComparer.OrdinalIgnoreCase);
-
- var countryCode = Path.GetFileNameWithoutExtension(file)
- .Split('-')
- .Last();
+ var countryCode = Path.GetFileNameWithoutExtension(file).Split('-')[1];
_allParentalRatings[countryCode] = dict;
}
- private readonly string[] _unratedValues = { "n/a", "unrated", "not rated" };
+ private static readonly string[] _unratedValues = { "n/a", "unrated", "not rated" };
/// <summary>
/// Gets the rating level.
@@ -435,7 +410,7 @@ namespace Emby.Server.Implementations.Localization
return phrase;
}
- const string DefaultCulture = "en-US";
+ private const string DefaultCulture = "en-US";
private readonly ConcurrentDictionary<string, Dictionary<string, string>> _dictionaries =
new ConcurrentDictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);
@@ -450,10 +425,11 @@ namespace Emby.Server.Implementations.Localization
const string prefix = "Core";
var key = prefix + culture;
- return _dictionaries.GetOrAdd(key, k => GetDictionary(prefix, culture, DefaultCulture + ".json"));
+ return _dictionaries.GetOrAdd(key,
+ f => GetDictionary(prefix, culture, DefaultCulture + ".json").GetAwaiter().GetResult());
}
- private Dictionary<string, string> GetDictionary(string prefix, string culture, string baseFilename)
+ private async Task<Dictionary<string, string>> GetDictionary(string prefix, string culture, string baseFilename)
{
if (string.IsNullOrEmpty(culture))
{
@@ -464,24 +440,21 @@ namespace Emby.Server.Implementations.Localization
var namespaceName = GetType().Namespace + "." + prefix;
- CopyInto(dictionary, namespaceName + "." + baseFilename);
- CopyInto(dictionary, namespaceName + "." + GetResourceFilename(culture));
+ await CopyInto(dictionary, namespaceName + "." + baseFilename);
+ await CopyInto(dictionary, namespaceName + "." + GetResourceFilename(culture));
return dictionary;
}
- private void CopyInto(IDictionary<string, string> dictionary, string resourcePath)
+ private async Task CopyInto(IDictionary<string, string> dictionary, string resourcePath)
{
- using (var stream = _assemblyInfo.GetManifestResourceStream(GetType(), resourcePath))
+ using (var stream = _assembly.GetManifestResourceStream(resourcePath))
{
- if (stream != null)
- {
- var dict = _jsonSerializer.DeserializeFromStream<Dictionary<string, string>>(stream);
+ var dict = await _jsonSerializer.DeserializeFromStreamAsync<Dictionary<string, string>>(stream);
- foreach (var key in dict.Keys)
- {
- dictionary[key] = dict[key];
- }
+ foreach (var key in dict.Keys)
+ {
+ dictionary[key] = dict[key];
}
}
}
@@ -552,11 +525,4 @@ namespace Emby.Server.Implementations.Localization
new LocalizationOption("Vietnamese", "vi")
};
}
-
- public interface ITextLocalizer
- {
- string RemoveDiacritics(string text);
-
- string NormalizeFormKD(string text);
- }
}
diff --git a/Emby.Server.Implementations/Localization/Ratings/br.txt b/Emby.Server.Implementations/Localization/Ratings/br.csv
index e5edaf62c..e5edaf62c 100644
--- a/Emby.Server.Implementations/Localization/Ratings/br.txt
+++ b/Emby.Server.Implementations/Localization/Ratings/br.csv
diff --git a/Emby.Server.Implementations/Localization/Ratings/ca.txt b/Emby.Server.Implementations/Localization/Ratings/ca.csv
index 5aef0580f..5aef0580f 100644
--- a/Emby.Server.Implementations/Localization/Ratings/ca.txt
+++ b/Emby.Server.Implementations/Localization/Ratings/ca.csv
diff --git a/Emby.Server.Implementations/Localization/Ratings/co.txt b/Emby.Server.Implementations/Localization/Ratings/co.csv
index 9684fa052..9684fa052 100644
--- a/Emby.Server.Implementations/Localization/Ratings/co.txt
+++ b/Emby.Server.Implementations/Localization/Ratings/co.csv
diff --git a/Emby.Server.Implementations/Localization/Ratings/dk.txt b/Emby.Server.Implementations/Localization/Ratings/dk.csv
index 5364ae1f2..5364ae1f2 100644
--- a/Emby.Server.Implementations/Localization/Ratings/dk.txt
+++ b/Emby.Server.Implementations/Localization/Ratings/dk.csv
diff --git a/Emby.Server.Implementations/Localization/Ratings/es.txt b/Emby.Server.Implementations/Localization/Ratings/es.csv
index 887d91ba6..887d91ba6 100644
--- a/Emby.Server.Implementations/Localization/Ratings/es.txt
+++ b/Emby.Server.Implementations/Localization/Ratings/es.csv
diff --git a/Emby.Server.Implementations/Localization/Ratings/fr.txt b/Emby.Server.Implementations/Localization/Ratings/fr.csv
index f586a3fa9..f586a3fa9 100644
--- a/Emby.Server.Implementations/Localization/Ratings/fr.txt
+++ b/Emby.Server.Implementations/Localization/Ratings/fr.csv
diff --git a/Emby.Server.Implementations/Localization/Ratings/gb.txt b/Emby.Server.Implementations/Localization/Ratings/gb.csv
index c1f7d0452..c1f7d0452 100644
--- a/Emby.Server.Implementations/Localization/Ratings/gb.txt
+++ b/Emby.Server.Implementations/Localization/Ratings/gb.csv
diff --git a/Emby.Server.Implementations/Localization/Ratings/ie.txt b/Emby.Server.Implementations/Localization/Ratings/ie.csv
index e42be5cd4..e42be5cd4 100644
--- a/Emby.Server.Implementations/Localization/Ratings/ie.txt
+++ b/Emby.Server.Implementations/Localization/Ratings/ie.csv
diff --git a/Emby.Server.Implementations/Localization/Ratings/jp.txt b/Emby.Server.Implementations/Localization/Ratings/jp.csv
index a8fc2d143..a8fc2d143 100644
--- a/Emby.Server.Implementations/Localization/Ratings/jp.txt
+++ b/Emby.Server.Implementations/Localization/Ratings/jp.csv
diff --git a/Emby.Server.Implementations/Localization/Ratings/kz.txt b/Emby.Server.Implementations/Localization/Ratings/kz.csv
index 4441c5650..4441c5650 100644
--- a/Emby.Server.Implementations/Localization/Ratings/kz.txt
+++ b/Emby.Server.Implementations/Localization/Ratings/kz.csv
diff --git a/Emby.Server.Implementations/Localization/Ratings/mx.txt b/Emby.Server.Implementations/Localization/Ratings/mx.csv
index 785a8ba22..785a8ba22 100644
--- a/Emby.Server.Implementations/Localization/Ratings/mx.txt
+++ b/Emby.Server.Implementations/Localization/Ratings/mx.csv
diff --git a/Emby.Server.Implementations/Localization/Ratings/nl.txt b/Emby.Server.Implementations/Localization/Ratings/nl.csv
index 8c005092e..8c005092e 100644
--- a/Emby.Server.Implementations/Localization/Ratings/nl.txt
+++ b/Emby.Server.Implementations/Localization/Ratings/nl.csv
diff --git a/Emby.Server.Implementations/Localization/Ratings/nz.txt b/Emby.Server.Implementations/Localization/Ratings/nz.csv
index bba99b764..bba99b764 100644
--- a/Emby.Server.Implementations/Localization/Ratings/nz.txt
+++ b/Emby.Server.Implementations/Localization/Ratings/nz.csv
diff --git a/Emby.Server.Implementations/Localization/Ratings/ro.txt b/Emby.Server.Implementations/Localization/Ratings/ro.csv
index 4089b282f..4089b282f 100644
--- a/Emby.Server.Implementations/Localization/Ratings/ro.txt
+++ b/Emby.Server.Implementations/Localization/Ratings/ro.csv
diff --git a/Emby.Server.Implementations/Localization/Ratings/uk.txt b/Emby.Server.Implementations/Localization/Ratings/uk.csv
index 6c8005b3f..6c8005b3f 100644
--- a/Emby.Server.Implementations/Localization/Ratings/uk.txt
+++ b/Emby.Server.Implementations/Localization/Ratings/uk.csv
diff --git a/Emby.Server.Implementations/Localization/Ratings/us.txt b/Emby.Server.Implementations/Localization/Ratings/us.csv
index 34c897fe3..34c897fe3 100644
--- a/Emby.Server.Implementations/Localization/Ratings/us.txt
+++ b/Emby.Server.Implementations/Localization/Ratings/us.csv
diff --git a/Emby.Server.Implementations/Localization/TextLocalizer.cs b/Emby.Server.Implementations/Localization/TextLocalizer.cs
deleted file mode 100644
index 96591e5e6..000000000
--- a/Emby.Server.Implementations/Localization/TextLocalizer.cs
+++ /dev/null
@@ -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);
- }
- }
-}
diff --git a/Emby.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs
index 5373b4392..81fdb96d2 100644
--- a/Emby.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs
@@ -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;
}
}
diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs
index 52077b242..6ec83b5c0 100644
--- a/Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs
@@ -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 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 string Key => "DeleteCacheFiles";
+
+ public bool IsHidden => false;
public bool IsEnabled => true;
diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs
index a57fe4945..e468c301a 100644
--- a/Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs
@@ -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;
diff --git a/Emby.Server.Implementations/ScheduledTasks/PeopleValidationTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/PeopleValidationTask.cs
index 68031170f..d70799c47 100644
--- a/Emby.Server.Implementations/ScheduledTasks/PeopleValidationTask.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/PeopleValidationTask.cs
@@ -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;
}
}
diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/PluginUpdateTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/PluginUpdateTask.cs
new file mode 100644
index 000000000..c6431c311
--- /dev/null
+++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/PluginUpdateTask.cs
@@ -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;
+ }
+}
diff --git a/Emby.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/RefreshMediaLibraryTask.cs
index f6fa64d13..1a3d85ad7 100644
--- a/Emby.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/RefreshMediaLibraryTask.cs
@@ -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;
}
}
diff --git a/Emby.Server.Implementations/ScheduledTasks/DailyTrigger.cs b/Emby.Server.Implementations/ScheduledTasks/Triggers/DailyTrigger.cs
index 98685cebe..98685cebe 100644
--- a/Emby.Server.Implementations/ScheduledTasks/DailyTrigger.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/Triggers/DailyTrigger.cs
diff --git a/Emby.Server.Implementations/ScheduledTasks/IntervalTrigger.cs b/Emby.Server.Implementations/ScheduledTasks/Triggers/IntervalTrigger.cs
index 3a34da3af..3a34da3af 100644
--- a/Emby.Server.Implementations/ScheduledTasks/IntervalTrigger.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/Triggers/IntervalTrigger.cs
diff --git a/Emby.Server.Implementations/ScheduledTasks/StartupTrigger.cs b/Emby.Server.Implementations/ScheduledTasks/Triggers/StartupTrigger.cs
index 08ff4f55f..08ff4f55f 100644
--- a/Emby.Server.Implementations/ScheduledTasks/StartupTrigger.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/Triggers/StartupTrigger.cs
diff --git a/Emby.Server.Implementations/ScheduledTasks/WeeklyTrigger.cs b/Emby.Server.Implementations/ScheduledTasks/Triggers/WeeklyTrigger.cs
index 2a6a7b13c..2a6a7b13c 100644
--- a/Emby.Server.Implementations/ScheduledTasks/WeeklyTrigger.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/Triggers/WeeklyTrigger.cs
diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs
index 9a49b97c7..dc7f57f27 100644
--- a/Emby.Server.Implementations/Updates/InstallationManager.cs
+++ b/Emby.Server.Implementations/Updates/InstallationManager.cs
@@ -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)
diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs
index bb0eff291..7826fde35 100644
--- a/Jellyfin.Server/Program.cs
+++ b/Jellyfin.Server/Program.cs
@@ -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)
diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs
index a212d3f3a..88654a42c 100644
--- a/MediaBrowser.Api/ApiEntryPoint.cs
+++ b/MediaBrowser.Api/ApiEntryPoint.cs
@@ -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);
}
diff --git a/MediaBrowser.Api/ItemUpdateService.cs b/MediaBrowser.Api/ItemUpdateService.cs
index 3c8d4b4ff..825732888 100644
--- a/MediaBrowser.Api/ItemUpdateService.cs
+++ b/MediaBrowser.Api/ItemUpdateService.cs
@@ -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()
};
diff --git a/MediaBrowser.Common/IApplicationHost.cs b/MediaBrowser.Common/IApplicationHost.cs
index 385127c54..59e3c1767 100644
--- a/MediaBrowser.Common/IApplicationHost.cs
+++ b/MediaBrowser.Common/IApplicationHost.cs
@@ -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.
diff --git a/MediaBrowser.Controller/Extensions/StringExtensions.cs b/MediaBrowser.Controller/Extensions/StringExtensions.cs
index 73f529fc0..b1aaf6534 100644
--- a/MediaBrowser.Controller/Extensions/StringExtensions.cs
+++ b/MediaBrowser.Controller/Extensions/StringExtensions.cs
@@ -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;
+ }
}
}
}
diff --git a/MediaBrowser.Controller/Plugins/IServerEntryPoint.cs b/MediaBrowser.Controller/Plugins/IServerEntryPoint.cs
index 7b7a591aa..e57929989 100644
--- a/MediaBrowser.Controller/Plugins/IServerEntryPoint.cs
+++ b/MediaBrowser.Controller/Plugins/IServerEntryPoint.cs
@@ -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
diff --git a/MediaBrowser.Model/Globalization/ILocalizationManager.cs b/MediaBrowser.Model/Globalization/ILocalizationManager.cs
index 05efb6681..a9ce60a2a 100644
--- a/MediaBrowser.Model/Globalization/ILocalizationManager.cs
+++ b/MediaBrowser.Model/Globalization/ILocalizationManager.cs
@@ -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);
diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs
index 1972ad290..77028e526 100644
--- a/MediaBrowser.Providers/Manager/MetadataService.cs
+++ b/MediaBrowser.Providers/Manager/MetadataService.cs
@@ -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);
}
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
index afc760dd4..4e11fcbb2 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
@@ -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)
- {
- if (!video.SubtitleFiles
- .SequenceEqual(_subtitleResolver.GetExternalSubtitleFiles(video, directoryService, false), StringComparer.Ordinal))
- {
- _logger.LogDebug("Refreshing {0} due to external subtitles change.", item.Path);
- return true;
- }
- }
+ _logger.LogDebug("Refreshing {0} due to external subtitles change.", item.Path);
+ return true;
}
return false;
diff --git a/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs b/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs
index b7598ef22..74f41f9df 100644
--- a/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs
+++ b/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs
@@ -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;
}
}
diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs
index 2f4e21443..531978e1d 100644
--- a/MediaBrowser.WebDashboard/Api/DashboardService.cs
+++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs
@@ -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))
{
- using (var fs = _fileSystem.GetFileStream(destinationFilePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
- {
- stream.CopyTo(fs);
- }
+ await stream.CopyToAsync(fs);
}
}
diff --git a/MediaBrowser.WebDashboard/ServerEntryPoint.cs b/MediaBrowser.WebDashboard/ServerEntryPoint.cs
index 221fa62c7..18ed54a78 100644
--- a/MediaBrowser.WebDashboard/ServerEntryPoint.cs
+++ b/MediaBrowser.WebDashboard/ServerEntryPoint.cs
@@ -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()
diff --git a/MediaBrowser.XbmcMetadata/EntryPoint.cs b/MediaBrowser.XbmcMetadata/EntryPoint.cs
index 37a1d4c35..992991a7e 100644
--- a/MediaBrowser.XbmcMetadata/EntryPoint.cs
+++ b/MediaBrowser.XbmcMetadata/EntryPoint.cs
@@ -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)