mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-03-26 20:16:33 +00:00
Merge remote-tracking branch 'upstream/master' into integration-tests
This commit is contained in:
@@ -422,7 +422,7 @@ namespace Emby.Server.Implementations.Activity
|
||||
});
|
||||
}
|
||||
|
||||
private void OnPluginUpdated(object sender, GenericEventArgs<(IPlugin, PackageVersionInfo)> e)
|
||||
private void OnPluginUpdated(object sender, GenericEventArgs<(IPlugin, VersionInfo)> e)
|
||||
{
|
||||
CreateLogEntry(new ActivityLogEntry
|
||||
{
|
||||
@@ -434,8 +434,8 @@ namespace Emby.Server.Implementations.Activity
|
||||
ShortOverview = string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
_localization.GetLocalizedString("VersionNumber"),
|
||||
e.Argument.Item2.versionStr),
|
||||
Overview = e.Argument.Item2.description
|
||||
e.Argument.Item2.version),
|
||||
Overview = e.Argument.Item2.changelog
|
||||
});
|
||||
}
|
||||
|
||||
@@ -451,7 +451,7 @@ namespace Emby.Server.Implementations.Activity
|
||||
});
|
||||
}
|
||||
|
||||
private void OnPluginInstalled(object sender, GenericEventArgs<PackageVersionInfo> e)
|
||||
private void OnPluginInstalled(object sender, GenericEventArgs<VersionInfo> e)
|
||||
{
|
||||
CreateLogEntry(new ActivityLogEntry
|
||||
{
|
||||
@@ -463,7 +463,7 @@ namespace Emby.Server.Implementations.Activity
|
||||
ShortOverview = string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
_localization.GetLocalizedString("VersionNumber"),
|
||||
e.Argument.versionStr)
|
||||
e.Argument.version)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,6 @@ using MediaBrowser.Model.Activity;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Cryptography;
|
||||
using MediaBrowser.Model.Dlna;
|
||||
using MediaBrowser.Model.Events;
|
||||
using MediaBrowser.Model.Globalization;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.MediaInfo;
|
||||
@@ -104,7 +103,6 @@ using MediaBrowser.WebDashboard.Api;
|
||||
using MediaBrowser.XbmcMetadata.Providers;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Extensions;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using OperatingSystem = MediaBrowser.Common.System.OperatingSystem;
|
||||
@@ -121,14 +119,20 @@ namespace Emby.Server.Implementations
|
||||
/// </summary>
|
||||
private static readonly string[] _relevantEnvVarPrefixes = { "JELLYFIN_", "DOTNET_", "ASPNETCORE_" };
|
||||
|
||||
private SqliteUserRepository _userRepository;
|
||||
private SqliteDisplayPreferencesRepository _displayPreferencesRepository;
|
||||
private readonly IFileSystem _fileSystemManager;
|
||||
private readonly INetworkManager _networkManager;
|
||||
private readonly IXmlSerializer _xmlSerializer;
|
||||
private readonly IStartupOptions _startupOptions;
|
||||
|
||||
private IMediaEncoder _mediaEncoder;
|
||||
private ISessionManager _sessionManager;
|
||||
private IHttpServer _httpServer;
|
||||
private IHttpClient _httpClient;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance can self restart.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance can self restart; otherwise, <c>false</c>.</value>
|
||||
public abstract bool CanSelfRestart { get; }
|
||||
public bool CanSelfRestart => _startupOptions.RestartPath != null;
|
||||
|
||||
public virtual bool CanLaunchWebBrowser
|
||||
{
|
||||
@@ -139,7 +143,7 @@ namespace Emby.Server.Implementations
|
||||
return false;
|
||||
}
|
||||
|
||||
if (StartupOptions.IsService)
|
||||
if (_startupOptions.IsService)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -209,21 +213,6 @@ namespace Emby.Server.Implementations
|
||||
/// <value>The configuration manager.</value>
|
||||
protected IConfigurationManager ConfigurationManager { get; set; }
|
||||
|
||||
public IFileSystem FileSystemManager { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public PackageVersionClass SystemUpdateLevel
|
||||
{
|
||||
get
|
||||
{
|
||||
#if BETA
|
||||
return PackageVersionClass.Beta;
|
||||
#else
|
||||
return PackageVersionClass.Release;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the service provider.
|
||||
/// </summary>
|
||||
@@ -245,110 +234,6 @@ namespace Emby.Server.Implementations
|
||||
/// <value>The server configuration manager.</value>
|
||||
public IServerConfigurationManager ServerConfigurationManager => (IServerConfigurationManager)ConfigurationManager;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the user manager.
|
||||
/// </summary>
|
||||
/// <value>The user manager.</value>
|
||||
public IUserManager UserManager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the library manager.
|
||||
/// </summary>
|
||||
/// <value>The library manager.</value>
|
||||
internal ILibraryManager LibraryManager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the directory watchers.
|
||||
/// </summary>
|
||||
/// <value>The directory watchers.</value>
|
||||
private ILibraryMonitor LibraryMonitor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the provider manager.
|
||||
/// </summary>
|
||||
/// <value>The provider manager.</value>
|
||||
private IProviderManager ProviderManager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the HTTP server.
|
||||
/// </summary>
|
||||
/// <value>The HTTP server.</value>
|
||||
private IHttpServer HttpServer { get; set; }
|
||||
|
||||
private IDtoService DtoService { get; set; }
|
||||
|
||||
public IImageProcessor ImageProcessor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the media encoder.
|
||||
/// </summary>
|
||||
/// <value>The media encoder.</value>
|
||||
private IMediaEncoder MediaEncoder { get; set; }
|
||||
|
||||
private ISubtitleEncoder SubtitleEncoder { get; set; }
|
||||
|
||||
private ISessionManager SessionManager { get; set; }
|
||||
|
||||
private ILiveTvManager LiveTvManager { get; set; }
|
||||
|
||||
public LocalizationManager LocalizationManager { get; set; }
|
||||
|
||||
private IEncodingManager EncodingManager { get; set; }
|
||||
|
||||
private IChannelManager ChannelManager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the user data repository.
|
||||
/// </summary>
|
||||
/// <value>The user data repository.</value>
|
||||
private IUserDataManager UserDataManager { get; set; }
|
||||
|
||||
internal SqliteItemRepository ItemRepository { get; set; }
|
||||
|
||||
private INotificationManager NotificationManager { get; set; }
|
||||
|
||||
private ISubtitleManager SubtitleManager { get; set; }
|
||||
|
||||
private IChapterManager ChapterManager { get; set; }
|
||||
|
||||
private IDeviceManager DeviceManager { get; set; }
|
||||
|
||||
internal IUserViewManager UserViewManager { get; set; }
|
||||
|
||||
private IAuthenticationRepository AuthenticationRepository { get; set; }
|
||||
|
||||
private ITVSeriesManager TVSeriesManager { get; set; }
|
||||
|
||||
private ICollectionManager CollectionManager { get; set; }
|
||||
|
||||
private IMediaSourceManager MediaSourceManager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the installation manager.
|
||||
/// </summary>
|
||||
/// <value>The installation manager.</value>
|
||||
protected IInstallationManager InstallationManager { get; private set; }
|
||||
|
||||
protected IAuthService AuthService { get; private set; }
|
||||
|
||||
public IStartupOptions StartupOptions { get; }
|
||||
|
||||
internal IImageEncoder ImageEncoder { get; private set; }
|
||||
|
||||
protected readonly IXmlSerializer XmlSerializer;
|
||||
|
||||
protected ISocketFactory SocketFactory { get; private set; }
|
||||
|
||||
protected ITaskManager TaskManager { get; private set; }
|
||||
|
||||
public IHttpClient HttpClient { get; private set; }
|
||||
|
||||
protected INetworkManager NetworkManager { get; set; }
|
||||
|
||||
public IJsonSerializer JsonSerializer { get; private set; }
|
||||
|
||||
protected IIsoManager IsoManager { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ApplicationHost" /> class.
|
||||
/// </summary>
|
||||
@@ -357,29 +242,33 @@ namespace Emby.Server.Implementations
|
||||
ILoggerFactory loggerFactory,
|
||||
IStartupOptions options,
|
||||
IFileSystem fileSystem,
|
||||
IImageEncoder imageEncoder,
|
||||
INetworkManager networkManager)
|
||||
{
|
||||
XmlSerializer = new MyXmlSerializer();
|
||||
_xmlSerializer = new MyXmlSerializer();
|
||||
|
||||
NetworkManager = networkManager;
|
||||
_networkManager = networkManager;
|
||||
networkManager.LocalSubnetsFn = GetConfiguredLocalSubnets;
|
||||
|
||||
ApplicationPaths = applicationPaths;
|
||||
LoggerFactory = loggerFactory;
|
||||
FileSystemManager = fileSystem;
|
||||
_fileSystemManager = fileSystem;
|
||||
|
||||
ConfigurationManager = new ServerConfigurationManager(ApplicationPaths, LoggerFactory, XmlSerializer, FileSystemManager);
|
||||
ConfigurationManager = new ServerConfigurationManager(ApplicationPaths, LoggerFactory, _xmlSerializer, _fileSystemManager);
|
||||
|
||||
Logger = LoggerFactory.CreateLogger("App");
|
||||
Logger = LoggerFactory.CreateLogger<ApplicationHost>();
|
||||
|
||||
StartupOptions = options;
|
||||
|
||||
ImageEncoder = imageEncoder;
|
||||
_startupOptions = options;
|
||||
|
||||
fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem));
|
||||
|
||||
NetworkManager.NetworkChanged += OnNetworkChanged;
|
||||
_networkManager.NetworkChanged += OnNetworkChanged;
|
||||
|
||||
CertificateInfo = new CertificateInfo
|
||||
{
|
||||
Path = ServerConfigurationManager.Configuration.CertificatePath,
|
||||
Password = ServerConfigurationManager.Configuration.CertificatePassword
|
||||
};
|
||||
Certificate = GetCertificate(CertificateInfo);
|
||||
}
|
||||
|
||||
public string ExpandVirtualPath(string path)
|
||||
@@ -447,10 +336,7 @@ namespace Emby.Server.Implementations
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
/// <inheritdoc/>
|
||||
public string Name => ApplicationProductName;
|
||||
|
||||
/// <summary>
|
||||
@@ -540,7 +426,7 @@ namespace Emby.Server.Implementations
|
||||
|
||||
ConfigurationManager.ConfigurationUpdated += OnConfigurationUpdated;
|
||||
|
||||
MediaEncoder.SetFFmpegPath();
|
||||
_mediaEncoder.SetFFmpegPath();
|
||||
|
||||
Logger.LogInformation("ServerId: {0}", SystemId);
|
||||
|
||||
@@ -552,7 +438,7 @@ namespace Emby.Server.Implementations
|
||||
Logger.LogInformation("Executed all pre-startup entry points in {Elapsed:g}", stopWatch.Elapsed);
|
||||
|
||||
Logger.LogInformation("Core startup complete");
|
||||
HttpServer.GlobalResponse = null;
|
||||
_httpServer.GlobalResponse = null;
|
||||
|
||||
stopWatch.Restart();
|
||||
await Task.WhenAll(StartEntryPoints(entryPoints, false)).ConfigureAwait(false);
|
||||
@@ -576,7 +462,7 @@ namespace Emby.Server.Implementations
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task InitAsync(IServiceCollection serviceCollection, IConfiguration startupConfig)
|
||||
public void Init(IServiceCollection serviceCollection)
|
||||
{
|
||||
HttpPort = ServerConfigurationManager.Configuration.HttpServerPortNumber;
|
||||
HttpsPort = ServerConfigurationManager.Configuration.HttpsPortNumber;
|
||||
@@ -588,8 +474,6 @@ namespace Emby.Server.Implementations
|
||||
HttpsPort = ServerConfiguration.DefaultHttpsPort;
|
||||
}
|
||||
|
||||
JsonSerializer = new JsonSerializer();
|
||||
|
||||
if (Plugins != null)
|
||||
{
|
||||
var pluginBuilder = new StringBuilder();
|
||||
@@ -609,7 +493,7 @@ namespace Emby.Server.Implementations
|
||||
|
||||
DiscoverTypes();
|
||||
|
||||
await RegisterServices(serviceCollection, startupConfig).ConfigureAwait(false);
|
||||
RegisterServices(serviceCollection);
|
||||
}
|
||||
|
||||
public async Task ExecuteWebsocketHandlerAsync(HttpContext context, Func<Task> next)
|
||||
@@ -620,7 +504,7 @@ namespace Emby.Server.Implementations
|
||||
return;
|
||||
}
|
||||
|
||||
await HttpServer.ProcessWebSocketRequest(context).ConfigureAwait(false);
|
||||
await _httpServer.ProcessWebSocketRequest(context).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task ExecuteHttpHandlerAsync(HttpContext context, Func<Task> next)
|
||||
@@ -636,14 +520,16 @@ namespace Emby.Server.Implementations
|
||||
var localPath = context.Request.Path.ToString();
|
||||
|
||||
var req = new WebSocketSharpRequest(request, response, request.Path, LoggerFactory.CreateLogger<WebSocketSharpRequest>());
|
||||
await HttpServer.RequestHandler(req, request.GetDisplayUrl(), request.Host.ToString(), localPath, context.RequestAborted).ConfigureAwait(false);
|
||||
await _httpServer.RequestHandler(req, request.GetDisplayUrl(), request.Host.ToString(), localPath, context.RequestAborted).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers services/resources with the service collection that will be available via DI.
|
||||
/// </summary>
|
||||
protected async Task RegisterServices(IServiceCollection serviceCollection, IConfiguration startupConfig)
|
||||
protected virtual void RegisterServices(IServiceCollection serviceCollection)
|
||||
{
|
||||
serviceCollection.AddSingleton(_startupOptions);
|
||||
|
||||
serviceCollection.AddMemoryCache();
|
||||
|
||||
serviceCollection.AddSingleton(ConfigurationManager);
|
||||
@@ -651,240 +537,169 @@ namespace Emby.Server.Implementations
|
||||
|
||||
serviceCollection.AddSingleton<IApplicationPaths>(ApplicationPaths);
|
||||
|
||||
serviceCollection.AddSingleton(JsonSerializer);
|
||||
serviceCollection.AddSingleton<IJsonSerializer, JsonSerializer>();
|
||||
|
||||
// TODO: Support for injecting ILogger should be deprecated in favour of ILogger<T> and this removed
|
||||
serviceCollection.AddSingleton<ILogger>(Logger);
|
||||
// TODO: Remove support for injecting ILogger completely
|
||||
serviceCollection.AddSingleton((provider) =>
|
||||
{
|
||||
Logger.LogWarning("Injecting ILogger directly is deprecated and should be replaced with ILogger<T>");
|
||||
return Logger;
|
||||
});
|
||||
|
||||
serviceCollection.AddSingleton(FileSystemManager);
|
||||
serviceCollection.AddSingleton(_fileSystemManager);
|
||||
serviceCollection.AddSingleton<TvdbClientManager>();
|
||||
|
||||
HttpClient = new HttpClientManager.HttpClientManager(
|
||||
ApplicationPaths,
|
||||
LoggerFactory.CreateLogger<HttpClientManager.HttpClientManager>(),
|
||||
FileSystemManager,
|
||||
() => ApplicationUserAgent);
|
||||
serviceCollection.AddSingleton(HttpClient);
|
||||
serviceCollection.AddSingleton<IHttpClient, HttpClientManager.HttpClientManager>();
|
||||
|
||||
serviceCollection.AddSingleton(NetworkManager);
|
||||
serviceCollection.AddSingleton(_networkManager);
|
||||
|
||||
IsoManager = new IsoManager();
|
||||
serviceCollection.AddSingleton(IsoManager);
|
||||
serviceCollection.AddSingleton<IIsoManager, IsoManager>();
|
||||
|
||||
TaskManager = new TaskManager(ApplicationPaths, JsonSerializer, LoggerFactory, FileSystemManager);
|
||||
serviceCollection.AddSingleton(TaskManager);
|
||||
serviceCollection.AddSingleton<ITaskManager, TaskManager>();
|
||||
|
||||
serviceCollection.AddSingleton(XmlSerializer);
|
||||
serviceCollection.AddSingleton(_xmlSerializer);
|
||||
|
||||
serviceCollection.AddSingleton(typeof(IStreamHelper), typeof(StreamHelper));
|
||||
serviceCollection.AddSingleton<IStreamHelper, StreamHelper>();
|
||||
|
||||
var cryptoProvider = new CryptographyProvider();
|
||||
serviceCollection.AddSingleton<ICryptoProvider>(cryptoProvider);
|
||||
serviceCollection.AddSingleton<ICryptoProvider, CryptographyProvider>();
|
||||
|
||||
SocketFactory = new SocketFactory();
|
||||
serviceCollection.AddSingleton(SocketFactory);
|
||||
serviceCollection.AddSingleton<ISocketFactory, SocketFactory>();
|
||||
|
||||
serviceCollection.AddSingleton(typeof(IInstallationManager), typeof(InstallationManager));
|
||||
serviceCollection.AddSingleton<IInstallationManager, InstallationManager>();
|
||||
|
||||
serviceCollection.AddSingleton(typeof(IZipClient), typeof(ZipClient));
|
||||
serviceCollection.AddSingleton<IZipClient, ZipClient>();
|
||||
|
||||
serviceCollection.AddSingleton(typeof(IHttpResultFactory), typeof(HttpResultFactory));
|
||||
serviceCollection.AddSingleton<IHttpResultFactory, HttpResultFactory>();
|
||||
|
||||
serviceCollection.AddSingleton<IServerApplicationHost>(this);
|
||||
serviceCollection.AddSingleton<IServerApplicationPaths>(ApplicationPaths);
|
||||
|
||||
serviceCollection.AddSingleton(ServerConfigurationManager);
|
||||
|
||||
LocalizationManager = new LocalizationManager(ServerConfigurationManager, JsonSerializer, LoggerFactory.CreateLogger<LocalizationManager>());
|
||||
await LocalizationManager.LoadAll().ConfigureAwait(false);
|
||||
serviceCollection.AddSingleton<ILocalizationManager>(LocalizationManager);
|
||||
serviceCollection.AddSingleton<ILocalizationManager, LocalizationManager>();
|
||||
|
||||
serviceCollection.AddSingleton<IBlurayExaminer>(new BdInfoExaminer(FileSystemManager));
|
||||
serviceCollection.AddSingleton<IBlurayExaminer, BdInfoExaminer>();
|
||||
|
||||
UserDataManager = new UserDataManager(LoggerFactory, ServerConfigurationManager, () => UserManager);
|
||||
serviceCollection.AddSingleton(UserDataManager);
|
||||
serviceCollection.AddSingleton<IUserDataRepository, SqliteUserDataRepository>();
|
||||
serviceCollection.AddSingleton<IUserDataManager, UserDataManager>();
|
||||
|
||||
_displayPreferencesRepository = new SqliteDisplayPreferencesRepository(
|
||||
LoggerFactory.CreateLogger<SqliteDisplayPreferencesRepository>(),
|
||||
ApplicationPaths,
|
||||
FileSystemManager);
|
||||
serviceCollection.AddSingleton<IDisplayPreferencesRepository>(_displayPreferencesRepository);
|
||||
serviceCollection.AddSingleton<IDisplayPreferencesRepository, SqliteDisplayPreferencesRepository>();
|
||||
|
||||
ItemRepository = new SqliteItemRepository(ServerConfigurationManager, this, LoggerFactory.CreateLogger<SqliteItemRepository>(), LocalizationManager);
|
||||
serviceCollection.AddSingleton<IItemRepository>(ItemRepository);
|
||||
serviceCollection.AddSingleton<IItemRepository, SqliteItemRepository>();
|
||||
|
||||
AuthenticationRepository = GetAuthenticationRepository();
|
||||
serviceCollection.AddSingleton(AuthenticationRepository);
|
||||
serviceCollection.AddSingleton<IAuthenticationRepository, AuthenticationRepository>();
|
||||
|
||||
_userRepository = GetUserRepository();
|
||||
serviceCollection.AddSingleton<IUserRepository, SqliteUserRepository>();
|
||||
|
||||
UserManager = new UserManager(
|
||||
LoggerFactory.CreateLogger<UserManager>(),
|
||||
_userRepository,
|
||||
XmlSerializer,
|
||||
NetworkManager,
|
||||
() => ImageProcessor,
|
||||
() => DtoService,
|
||||
this,
|
||||
JsonSerializer,
|
||||
FileSystemManager,
|
||||
cryptoProvider);
|
||||
// TODO: Refactor to eliminate the circular dependency here so that Lazy<T> isn't required
|
||||
serviceCollection.AddTransient(provider => new Lazy<IDtoService>(provider.GetRequiredService<IDtoService>));
|
||||
serviceCollection.AddSingleton<IUserManager, UserManager>();
|
||||
|
||||
serviceCollection.AddSingleton(UserManager);
|
||||
// TODO: Refactor to eliminate the circular dependency here so that Lazy<T> isn't required
|
||||
// TODO: Add StartupOptions.FFmpegPath to IConfiguration and remove this custom activation
|
||||
serviceCollection.AddTransient(provider => new Lazy<EncodingHelper>(provider.GetRequiredService<EncodingHelper>));
|
||||
serviceCollection.AddSingleton<IMediaEncoder>(provider =>
|
||||
ActivatorUtilities.CreateInstance<MediaBrowser.MediaEncoding.Encoder.MediaEncoder>(provider, _startupOptions.FFmpegPath ?? string.Empty));
|
||||
|
||||
MediaEncoder = new MediaBrowser.MediaEncoding.Encoder.MediaEncoder(
|
||||
LoggerFactory.CreateLogger<MediaBrowser.MediaEncoding.Encoder.MediaEncoder>(),
|
||||
ServerConfigurationManager,
|
||||
FileSystemManager,
|
||||
LocalizationManager,
|
||||
() => SubtitleEncoder,
|
||||
startupConfig,
|
||||
StartupOptions.FFmpegPath);
|
||||
serviceCollection.AddSingleton(MediaEncoder);
|
||||
// TODO: Refactor to eliminate the circular dependencies here so that Lazy<T> isn't required
|
||||
serviceCollection.AddTransient(provider => new Lazy<ILibraryMonitor>(provider.GetRequiredService<ILibraryMonitor>));
|
||||
serviceCollection.AddTransient(provider => new Lazy<IProviderManager>(provider.GetRequiredService<IProviderManager>));
|
||||
serviceCollection.AddTransient(provider => new Lazy<IUserViewManager>(provider.GetRequiredService<IUserViewManager>));
|
||||
serviceCollection.AddSingleton<ILibraryManager, LibraryManager>();
|
||||
|
||||
LibraryManager = new LibraryManager(this, LoggerFactory, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, () => ProviderManager, () => UserViewManager, MediaEncoder);
|
||||
serviceCollection.AddSingleton(LibraryManager);
|
||||
serviceCollection.AddSingleton<IMusicManager, MusicManager>();
|
||||
|
||||
var musicManager = new MusicManager(LibraryManager);
|
||||
serviceCollection.AddSingleton<IMusicManager>(musicManager);
|
||||
serviceCollection.AddSingleton<ILibraryMonitor, LibraryMonitor>();
|
||||
|
||||
LibraryMonitor = new LibraryMonitor(LoggerFactory, LibraryManager, ServerConfigurationManager, FileSystemManager);
|
||||
serviceCollection.AddSingleton(LibraryMonitor);
|
||||
|
||||
serviceCollection.AddSingleton<ISearchEngine>(new SearchEngine(LoggerFactory, LibraryManager, UserManager));
|
||||
|
||||
CertificateInfo = GetCertificateInfo(true);
|
||||
Certificate = GetCertificate(CertificateInfo);
|
||||
serviceCollection.AddSingleton<ISearchEngine, SearchEngine>();
|
||||
|
||||
serviceCollection.AddSingleton<ServiceController>();
|
||||
serviceCollection.AddSingleton<IHttpListener, WebSocketSharpListener>();
|
||||
serviceCollection.AddSingleton<IHttpServer, HttpListenerHost>();
|
||||
|
||||
ImageProcessor = new ImageProcessor(LoggerFactory.CreateLogger<ImageProcessor>(), ServerConfigurationManager.ApplicationPaths, FileSystemManager, ImageEncoder, () => LibraryManager, () => MediaEncoder);
|
||||
serviceCollection.AddSingleton(ImageProcessor);
|
||||
serviceCollection.AddSingleton<IImageProcessor, ImageProcessor>();
|
||||
|
||||
TVSeriesManager = new TVSeriesManager(UserManager, UserDataManager, LibraryManager, ServerConfigurationManager);
|
||||
serviceCollection.AddSingleton(TVSeriesManager);
|
||||
serviceCollection.AddSingleton<ITVSeriesManager, TVSeriesManager>();
|
||||
|
||||
DeviceManager = new DeviceManager(AuthenticationRepository, JsonSerializer, LibraryManager, LocalizationManager, UserManager, FileSystemManager, LibraryMonitor, ServerConfigurationManager);
|
||||
serviceCollection.AddSingleton(DeviceManager);
|
||||
serviceCollection.AddSingleton<IDeviceManager, DeviceManager>();
|
||||
|
||||
MediaSourceManager = new MediaSourceManager(ItemRepository, ApplicationPaths, LocalizationManager, UserManager, LibraryManager, LoggerFactory, JsonSerializer, FileSystemManager, UserDataManager, () => MediaEncoder);
|
||||
serviceCollection.AddSingleton(MediaSourceManager);
|
||||
serviceCollection.AddSingleton<IMediaSourceManager, MediaSourceManager>();
|
||||
|
||||
SubtitleManager = new SubtitleManager(LoggerFactory, FileSystemManager, LibraryMonitor, MediaSourceManager, LocalizationManager);
|
||||
serviceCollection.AddSingleton(SubtitleManager);
|
||||
serviceCollection.AddSingleton<ISubtitleManager, SubtitleManager>();
|
||||
|
||||
ProviderManager = new ProviderManager(HttpClient, SubtitleManager, ServerConfigurationManager, LibraryMonitor, LoggerFactory, FileSystemManager, ApplicationPaths, () => LibraryManager, JsonSerializer);
|
||||
serviceCollection.AddSingleton(ProviderManager);
|
||||
serviceCollection.AddSingleton<IProviderManager, ProviderManager>();
|
||||
|
||||
DtoService = new DtoService(LoggerFactory, LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ProviderManager, this, () => MediaSourceManager, () => LiveTvManager);
|
||||
serviceCollection.AddSingleton(DtoService);
|
||||
// TODO: Refactor to eliminate the circular dependency here so that Lazy<T> isn't required
|
||||
serviceCollection.AddTransient(provider => new Lazy<ILiveTvManager>(provider.GetRequiredService<ILiveTvManager>));
|
||||
serviceCollection.AddSingleton<IDtoService, DtoService>();
|
||||
|
||||
ChannelManager = new ChannelManager(
|
||||
UserManager,
|
||||
DtoService,
|
||||
LibraryManager,
|
||||
LoggerFactory.CreateLogger<ChannelManager>(),
|
||||
ServerConfigurationManager,
|
||||
FileSystemManager,
|
||||
UserDataManager,
|
||||
JsonSerializer,
|
||||
ProviderManager);
|
||||
serviceCollection.AddSingleton(ChannelManager);
|
||||
serviceCollection.AddSingleton<IChannelManager, ChannelManager>();
|
||||
|
||||
SessionManager = new SessionManager(
|
||||
LoggerFactory.CreateLogger<SessionManager>(),
|
||||
UserDataManager,
|
||||
LibraryManager,
|
||||
UserManager,
|
||||
musicManager,
|
||||
DtoService,
|
||||
ImageProcessor,
|
||||
this,
|
||||
AuthenticationRepository,
|
||||
DeviceManager,
|
||||
MediaSourceManager);
|
||||
serviceCollection.AddSingleton(SessionManager);
|
||||
serviceCollection.AddSingleton<ISessionManager, SessionManager>();
|
||||
|
||||
serviceCollection.AddSingleton<IDlnaManager>(
|
||||
new DlnaManager(XmlSerializer, FileSystemManager, ApplicationPaths, LoggerFactory, JsonSerializer, this));
|
||||
serviceCollection.AddSingleton<IDlnaManager, DlnaManager>();
|
||||
|
||||
CollectionManager = new CollectionManager(LibraryManager, ApplicationPaths, LocalizationManager, FileSystemManager, LibraryMonitor, LoggerFactory, ProviderManager);
|
||||
serviceCollection.AddSingleton(CollectionManager);
|
||||
serviceCollection.AddSingleton<ICollectionManager, CollectionManager>();
|
||||
|
||||
serviceCollection.AddSingleton(typeof(IPlaylistManager), typeof(PlaylistManager));
|
||||
serviceCollection.AddSingleton<IPlaylistManager, PlaylistManager>();
|
||||
|
||||
LiveTvManager = new LiveTvManager(this, ServerConfigurationManager, LoggerFactory, ItemRepository, ImageProcessor, UserDataManager, DtoService, UserManager, LibraryManager, TaskManager, LocalizationManager, JsonSerializer, FileSystemManager, () => ChannelManager);
|
||||
serviceCollection.AddSingleton(LiveTvManager);
|
||||
serviceCollection.AddSingleton<LiveTvDtoService>();
|
||||
serviceCollection.AddSingleton<ILiveTvManager, LiveTvManager>();
|
||||
|
||||
UserViewManager = new UserViewManager(LibraryManager, LocalizationManager, UserManager, ChannelManager, LiveTvManager, ServerConfigurationManager);
|
||||
serviceCollection.AddSingleton(UserViewManager);
|
||||
serviceCollection.AddSingleton<IUserViewManager, UserViewManager>();
|
||||
|
||||
NotificationManager = new NotificationManager(
|
||||
LoggerFactory.CreateLogger<NotificationManager>(),
|
||||
UserManager,
|
||||
ServerConfigurationManager);
|
||||
serviceCollection.AddSingleton(NotificationManager);
|
||||
serviceCollection.AddSingleton<INotificationManager, NotificationManager>();
|
||||
|
||||
serviceCollection.AddSingleton<IDeviceDiscovery>(new DeviceDiscovery(ServerConfigurationManager));
|
||||
serviceCollection.AddSingleton<IDeviceDiscovery, DeviceDiscovery>();
|
||||
|
||||
ChapterManager = new ChapterManager(ItemRepository);
|
||||
serviceCollection.AddSingleton(ChapterManager);
|
||||
serviceCollection.AddSingleton<IChapterManager, ChapterManager>();
|
||||
|
||||
EncodingManager = new MediaEncoder.EncodingManager(
|
||||
LoggerFactory.CreateLogger<MediaEncoder.EncodingManager>(),
|
||||
FileSystemManager,
|
||||
MediaEncoder,
|
||||
ChapterManager,
|
||||
LibraryManager);
|
||||
serviceCollection.AddSingleton(EncodingManager);
|
||||
serviceCollection.AddSingleton<IEncodingManager, MediaEncoder.EncodingManager>();
|
||||
|
||||
var activityLogRepo = GetActivityLogRepository();
|
||||
serviceCollection.AddSingleton(activityLogRepo);
|
||||
serviceCollection.AddSingleton<IActivityManager>(new ActivityManager(activityLogRepo, UserManager));
|
||||
serviceCollection.AddSingleton<IActivityRepository, ActivityRepository>();
|
||||
serviceCollection.AddSingleton<IActivityManager, ActivityManager>();
|
||||
|
||||
var authContext = new AuthorizationContext(AuthenticationRepository, UserManager);
|
||||
serviceCollection.AddSingleton<IAuthorizationContext>(authContext);
|
||||
serviceCollection.AddSingleton<ISessionContext>(new SessionContext(UserManager, authContext, SessionManager));
|
||||
serviceCollection.AddSingleton<IAuthorizationContext, AuthorizationContext>();
|
||||
serviceCollection.AddSingleton<ISessionContext, SessionContext>();
|
||||
|
||||
AuthService = new AuthService(LoggerFactory.CreateLogger<AuthService>(), authContext, ServerConfigurationManager, SessionManager, NetworkManager);
|
||||
serviceCollection.AddSingleton(AuthService);
|
||||
serviceCollection.AddSingleton<IAuthService, AuthService>();
|
||||
|
||||
SubtitleEncoder = new MediaBrowser.MediaEncoding.Subtitles.SubtitleEncoder(
|
||||
LibraryManager,
|
||||
LoggerFactory.CreateLogger<MediaBrowser.MediaEncoding.Subtitles.SubtitleEncoder>(),
|
||||
ApplicationPaths,
|
||||
FileSystemManager,
|
||||
MediaEncoder,
|
||||
HttpClient,
|
||||
MediaSourceManager);
|
||||
serviceCollection.AddSingleton(SubtitleEncoder);
|
||||
serviceCollection.AddSingleton<ISubtitleEncoder, MediaBrowser.MediaEncoding.Subtitles.SubtitleEncoder>();
|
||||
|
||||
serviceCollection.AddSingleton(typeof(IResourceFileManager), typeof(ResourceFileManager));
|
||||
serviceCollection.AddSingleton<IResourceFileManager, ResourceFileManager>();
|
||||
serviceCollection.AddSingleton<EncodingHelper>();
|
||||
|
||||
serviceCollection.AddSingleton(typeof(IAttachmentExtractor), typeof(MediaBrowser.MediaEncoding.Attachments.AttachmentExtractor));
|
||||
|
||||
_displayPreferencesRepository.Initialize();
|
||||
|
||||
var userDataRepo = new SqliteUserDataRepository(LoggerFactory.CreateLogger<SqliteUserDataRepository>(), ApplicationPaths);
|
||||
|
||||
SetStaticProperties();
|
||||
|
||||
((UserManager)UserManager).Initialize();
|
||||
|
||||
((UserDataManager)UserDataManager).Repository = userDataRepo;
|
||||
ItemRepository.Initialize(userDataRepo, UserManager);
|
||||
((LibraryManager)LibraryManager).ItemRepository = ItemRepository;
|
||||
serviceCollection.AddSingleton<IAttachmentExtractor, MediaBrowser.MediaEncoding.Attachments.AttachmentExtractor>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create services registered with the service container that need to be initialized at application startup.
|
||||
/// </summary>
|
||||
public void InitializeServices()
|
||||
/// <returns>A task representing the service initialization operation.</returns>
|
||||
public async Task InitializeServices()
|
||||
{
|
||||
HttpServer = Resolve<IHttpServer>();
|
||||
var localizationManager = (LocalizationManager)Resolve<ILocalizationManager>();
|
||||
await localizationManager.LoadAll().ConfigureAwait(false);
|
||||
|
||||
_mediaEncoder = Resolve<IMediaEncoder>();
|
||||
_sessionManager = Resolve<ISessionManager>();
|
||||
_httpServer = Resolve<IHttpServer>();
|
||||
_httpClient = Resolve<IHttpClient>();
|
||||
|
||||
((SqliteDisplayPreferencesRepository)Resolve<IDisplayPreferencesRepository>()).Initialize();
|
||||
((AuthenticationRepository)Resolve<IAuthenticationRepository>()).Initialize();
|
||||
((SqliteUserRepository)Resolve<IUserRepository>()).Initialize();
|
||||
((ActivityRepository)Resolve<IActivityRepository>()).Initialize();
|
||||
|
||||
SetStaticProperties();
|
||||
|
||||
var userManager = (UserManager)Resolve<IUserManager>();
|
||||
userManager.Initialize();
|
||||
|
||||
var userDataRepo = (SqliteUserDataRepository)Resolve<IUserDataRepository>();
|
||||
((SqliteItemRepository)Resolve<IItemRepository>()).Initialize(userDataRepo, userManager);
|
||||
|
||||
FindParts();
|
||||
}
|
||||
|
||||
public static void LogEnvironmentInfo(ILogger logger, IApplicationPaths appPaths)
|
||||
@@ -953,75 +768,38 @@ namespace Emby.Server.Implementations
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user repository.
|
||||
/// </summary>
|
||||
/// <returns><see cref="Task{SqliteUserRepository}" />.</returns>
|
||||
private SqliteUserRepository GetUserRepository()
|
||||
{
|
||||
var repo = new SqliteUserRepository(
|
||||
LoggerFactory.CreateLogger<SqliteUserRepository>(),
|
||||
ApplicationPaths);
|
||||
|
||||
repo.Initialize();
|
||||
|
||||
return repo;
|
||||
}
|
||||
|
||||
private IAuthenticationRepository GetAuthenticationRepository()
|
||||
{
|
||||
var repo = new AuthenticationRepository(LoggerFactory, ServerConfigurationManager);
|
||||
|
||||
repo.Initialize();
|
||||
|
||||
return repo;
|
||||
}
|
||||
|
||||
private IActivityRepository GetActivityLogRepository()
|
||||
{
|
||||
var repo = new ActivityRepository(LoggerFactory.CreateLogger<ActivityRepository>(), ServerConfigurationManager.ApplicationPaths, FileSystemManager);
|
||||
|
||||
repo.Initialize();
|
||||
|
||||
return repo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dirty hacks.
|
||||
/// </summary>
|
||||
private void SetStaticProperties()
|
||||
{
|
||||
ItemRepository.ImageProcessor = ImageProcessor;
|
||||
|
||||
// For now there's no real way to inject these properly
|
||||
BaseItem.Logger = LoggerFactory.CreateLogger("BaseItem");
|
||||
BaseItem.Logger = Resolve<ILogger<BaseItem>>();
|
||||
BaseItem.ConfigurationManager = ServerConfigurationManager;
|
||||
BaseItem.LibraryManager = LibraryManager;
|
||||
BaseItem.ProviderManager = ProviderManager;
|
||||
BaseItem.LocalizationManager = LocalizationManager;
|
||||
BaseItem.ItemRepository = ItemRepository;
|
||||
User.UserManager = UserManager;
|
||||
BaseItem.FileSystem = FileSystemManager;
|
||||
BaseItem.UserDataManager = UserDataManager;
|
||||
BaseItem.ChannelManager = ChannelManager;
|
||||
Video.LiveTvManager = LiveTvManager;
|
||||
Folder.UserViewManager = UserViewManager;
|
||||
UserView.TVSeriesManager = TVSeriesManager;
|
||||
UserView.CollectionManager = CollectionManager;
|
||||
BaseItem.MediaSourceManager = MediaSourceManager;
|
||||
CollectionFolder.XmlSerializer = XmlSerializer;
|
||||
CollectionFolder.JsonSerializer = JsonSerializer;
|
||||
BaseItem.LibraryManager = Resolve<ILibraryManager>();
|
||||
BaseItem.ProviderManager = Resolve<IProviderManager>();
|
||||
BaseItem.LocalizationManager = Resolve<ILocalizationManager>();
|
||||
BaseItem.ItemRepository = Resolve<IItemRepository>();
|
||||
User.UserManager = Resolve<IUserManager>();
|
||||
BaseItem.FileSystem = _fileSystemManager;
|
||||
BaseItem.UserDataManager = Resolve<IUserDataManager>();
|
||||
BaseItem.ChannelManager = Resolve<IChannelManager>();
|
||||
Video.LiveTvManager = Resolve<ILiveTvManager>();
|
||||
Folder.UserViewManager = Resolve<IUserViewManager>();
|
||||
UserView.TVSeriesManager = Resolve<ITVSeriesManager>();
|
||||
UserView.CollectionManager = Resolve<ICollectionManager>();
|
||||
BaseItem.MediaSourceManager = Resolve<IMediaSourceManager>();
|
||||
CollectionFolder.XmlSerializer = _xmlSerializer;
|
||||
CollectionFolder.JsonSerializer = Resolve<IJsonSerializer>();
|
||||
CollectionFolder.ApplicationHost = this;
|
||||
AuthenticatedAttribute.AuthService = AuthService;
|
||||
AuthenticatedAttribute.AuthService = Resolve<IAuthService>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the parts.
|
||||
/// Finds plugin components and register them with the appropriate services.
|
||||
/// </summary>
|
||||
public void FindParts()
|
||||
private void FindParts()
|
||||
{
|
||||
InstallationManager = ServiceProvider.GetService<IInstallationManager>();
|
||||
|
||||
if (!ServerConfigurationManager.Configuration.IsPortAuthorized)
|
||||
{
|
||||
ServerConfigurationManager.Configuration.IsPortAuthorized = true;
|
||||
@@ -1034,34 +812,34 @@ namespace Emby.Server.Implementations
|
||||
.Where(i => i != null)
|
||||
.ToArray();
|
||||
|
||||
HttpServer.Init(GetExportTypes<IService>(), GetExports<IWebSocketListener>(), GetUrlPrefixes());
|
||||
_httpServer.Init(GetExportTypes<IService>(), GetExports<IWebSocketListener>(), GetUrlPrefixes());
|
||||
|
||||
LibraryManager.AddParts(
|
||||
Resolve<ILibraryManager>().AddParts(
|
||||
GetExports<IResolverIgnoreRule>(),
|
||||
GetExports<IItemResolver>(),
|
||||
GetExports<IIntroProvider>(),
|
||||
GetExports<IBaseItemComparer>(),
|
||||
GetExports<ILibraryPostScanTask>());
|
||||
|
||||
ProviderManager.AddParts(
|
||||
Resolve<IProviderManager>().AddParts(
|
||||
GetExports<IImageProvider>(),
|
||||
GetExports<IMetadataService>(),
|
||||
GetExports<IMetadataProvider>(),
|
||||
GetExports<IMetadataSaver>(),
|
||||
GetExports<IExternalId>());
|
||||
|
||||
LiveTvManager.AddParts(GetExports<ILiveTvService>(), GetExports<ITunerHost>(), GetExports<IListingsProvider>());
|
||||
Resolve<ILiveTvManager>().AddParts(GetExports<ILiveTvService>(), GetExports<ITunerHost>(), GetExports<IListingsProvider>());
|
||||
|
||||
SubtitleManager.AddParts(GetExports<ISubtitleProvider>());
|
||||
Resolve<ISubtitleManager>().AddParts(GetExports<ISubtitleProvider>());
|
||||
|
||||
ChannelManager.AddParts(GetExports<IChannel>());
|
||||
Resolve<IChannelManager>().AddParts(GetExports<IChannel>());
|
||||
|
||||
MediaSourceManager.AddParts(GetExports<IMediaSourceProvider>());
|
||||
Resolve<IMediaSourceManager>().AddParts(GetExports<IMediaSourceProvider>());
|
||||
|
||||
NotificationManager.AddParts(GetExports<INotificationService>(), GetExports<INotificationTypeFactory>());
|
||||
UserManager.AddParts(GetExports<IAuthenticationProvider>(), GetExports<IPasswordResetProvider>());
|
||||
Resolve<INotificationManager>().AddParts(GetExports<INotificationService>(), GetExports<INotificationTypeFactory>());
|
||||
Resolve<IUserManager>().AddParts(GetExports<IAuthenticationProvider>(), GetExports<IPasswordResetProvider>());
|
||||
|
||||
IsoManager.AddParts(GetExports<IIsoMounter>());
|
||||
Resolve<IIsoManager>().AddParts(GetExports<IIsoMounter>());
|
||||
}
|
||||
|
||||
private IPlugin LoadPlugin(IPlugin plugin)
|
||||
@@ -1168,16 +946,6 @@ namespace Emby.Server.Implementations
|
||||
});
|
||||
}
|
||||
|
||||
private CertificateInfo GetCertificateInfo(bool generateCertificate)
|
||||
{
|
||||
// Custom cert
|
||||
return new CertificateInfo
|
||||
{
|
||||
Path = ServerConfigurationManager.Configuration.CertificatePath,
|
||||
Password = ServerConfigurationManager.Configuration.CertificatePassword
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when [configuration updated].
|
||||
/// </summary>
|
||||
@@ -1204,14 +972,13 @@ namespace Emby.Server.Implementations
|
||||
}
|
||||
}
|
||||
|
||||
if (!HttpServer.UrlPrefixes.SequenceEqual(GetUrlPrefixes(), StringComparer.OrdinalIgnoreCase))
|
||||
if (!_httpServer.UrlPrefixes.SequenceEqual(GetUrlPrefixes(), StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
requiresRestart = true;
|
||||
}
|
||||
|
||||
var currentCertPath = CertificateInfo?.Path;
|
||||
var newCertInfo = GetCertificateInfo(false);
|
||||
var newCertPath = newCertInfo?.Path;
|
||||
var newCertPath = ServerConfigurationManager.Configuration.CertificatePath;
|
||||
|
||||
if (!string.Equals(currentCertPath, newCertPath, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
@@ -1264,7 +1031,7 @@ namespace Emby.Server.Implementations
|
||||
{
|
||||
try
|
||||
{
|
||||
await SessionManager.SendServerRestartNotification(CancellationToken.None).ConfigureAwait(false);
|
||||
await _sessionManager.SendServerRestartNotification(CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -1368,7 +1135,7 @@ namespace Emby.Server.Implementations
|
||||
IsShuttingDown = IsShuttingDown,
|
||||
Version = ApplicationVersionString,
|
||||
WebSocketPortNumber = HttpPort,
|
||||
CompletedInstallations = InstallationManager.CompletedInstallations.ToArray(),
|
||||
CompletedInstallations = Resolve<IInstallationManager>().CompletedInstallations.ToArray(),
|
||||
Id = SystemId,
|
||||
ProgramDataPath = ApplicationPaths.ProgramDataPath,
|
||||
WebPath = ApplicationPaths.WebPath,
|
||||
@@ -1388,15 +1155,14 @@ namespace Emby.Server.Implementations
|
||||
ServerName = FriendlyName,
|
||||
LocalAddress = localAddress,
|
||||
SupportsLibraryMonitor = true,
|
||||
EncoderLocation = MediaEncoder.EncoderLocation,
|
||||
EncoderLocation = _mediaEncoder.EncoderLocation,
|
||||
SystemArchitecture = RuntimeInformation.OSArchitecture,
|
||||
SystemUpdateLevel = SystemUpdateLevel,
|
||||
PackageName = StartupOptions.PackageName
|
||||
PackageName = _startupOptions.PackageName
|
||||
};
|
||||
}
|
||||
|
||||
public IEnumerable<WakeOnLanInfo> GetWakeOnLanInfo()
|
||||
=> NetworkManager.GetMacAddresses()
|
||||
=> _networkManager.GetMacAddresses()
|
||||
.Select(i => new WakeOnLanInfo(i))
|
||||
.ToList();
|
||||
|
||||
@@ -1508,7 +1274,7 @@ namespace Emby.Server.Implementations
|
||||
|
||||
if (addresses.Count == 0)
|
||||
{
|
||||
addresses.AddRange(NetworkManager.GetLocalIpAddresses(ServerConfigurationManager.Configuration.IgnoreVirtualInterfaces));
|
||||
addresses.AddRange(_networkManager.GetLocalIpAddresses(ServerConfigurationManager.Configuration.IgnoreVirtualInterfaces));
|
||||
}
|
||||
|
||||
var resultList = new List<IPAddress>();
|
||||
@@ -1575,7 +1341,7 @@ namespace Emby.Server.Implementations
|
||||
|
||||
try
|
||||
{
|
||||
using (var response = await HttpClient.SendAsync(
|
||||
using (var response = await _httpClient.SendAsync(
|
||||
new HttpRequestOptions
|
||||
{
|
||||
Url = apiUrl,
|
||||
@@ -1628,7 +1394,7 @@ namespace Emby.Server.Implementations
|
||||
|
||||
try
|
||||
{
|
||||
await SessionManager.SendServerShutdownNotification(CancellationToken.None).ConfigureAwait(false);
|
||||
await _sessionManager.SendServerShutdownNotification(CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -1749,14 +1515,8 @@ namespace Emby.Server.Implementations
|
||||
Logger.LogError(ex, "Error disposing {Type}", part.GetType().Name);
|
||||
}
|
||||
}
|
||||
|
||||
_userRepository?.Dispose();
|
||||
_displayPreferencesRepository?.Dispose();
|
||||
}
|
||||
|
||||
_userRepository = null;
|
||||
_displayPreferencesRepository = null;
|
||||
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Emby.Server.Implementations
|
||||
{
|
||||
{ HostWebClientKey, bool.TrueString },
|
||||
{ HttpListenerHost.DefaultRedirectKey, "web/index.html" },
|
||||
{ InstallationManager.PluginManifestUrlKey, "https://repo.jellyfin.org/releases/plugin/manifest.json" },
|
||||
{ InstallationManager.PluginManifestUrlKey, "https://repo.jellyfin.org/releases/plugin/manifest-stable.json" },
|
||||
{ FfmpegProbeSizeKey, "1G" },
|
||||
{ FfmpegAnalyzeDurationKey, "200M" },
|
||||
{ PlaylistsAllowDuplicatesKey, bool.TrueString }
|
||||
|
||||
@@ -39,12 +39,11 @@ namespace Emby.Server.Implementations.Data
|
||||
{
|
||||
private const string ChaptersTableName = "Chapters2";
|
||||
|
||||
/// <summary>
|
||||
/// The _app paths
|
||||
/// </summary>
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly IServerApplicationHost _appHost;
|
||||
private readonly ILocalizationManager _localization;
|
||||
// TODO: Remove this dependency. GetImageCacheTag() is the only method used and it can be converted to a static helper method
|
||||
private readonly IImageProcessor _imageProcessor;
|
||||
|
||||
private readonly TypeMapper _typeMapper;
|
||||
private readonly JsonSerializerOptions _jsonOptions;
|
||||
@@ -71,7 +70,8 @@ namespace Emby.Server.Implementations.Data
|
||||
IServerConfigurationManager config,
|
||||
IServerApplicationHost appHost,
|
||||
ILogger<SqliteItemRepository> logger,
|
||||
ILocalizationManager localization)
|
||||
ILocalizationManager localization,
|
||||
IImageProcessor imageProcessor)
|
||||
: base(logger)
|
||||
{
|
||||
if (config == null)
|
||||
@@ -82,6 +82,7 @@ namespace Emby.Server.Implementations.Data
|
||||
_config = config;
|
||||
_appHost = appHost;
|
||||
_localization = localization;
|
||||
_imageProcessor = imageProcessor;
|
||||
|
||||
_typeMapper = new TypeMapper();
|
||||
_jsonOptions = JsonDefaults.GetOptions();
|
||||
@@ -98,8 +99,6 @@ namespace Emby.Server.Implementations.Data
|
||||
/// <inheritdoc />
|
||||
protected override TempStoreMode TempStore => TempStoreMode.Memory;
|
||||
|
||||
public IImageProcessor ImageProcessor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Opens the connection to the database
|
||||
/// </summary>
|
||||
@@ -1991,7 +1990,14 @@ namespace Emby.Server.Implementations.Data
|
||||
|
||||
if (!string.IsNullOrEmpty(chapter.ImagePath))
|
||||
{
|
||||
chapter.ImageTag = ImageProcessor.GetImageCacheTag(item, chapter);
|
||||
try
|
||||
{
|
||||
chapter.ImageTag = _imageProcessor.GetImageCacheTag(item, chapter);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex, "Failed to create image cache tag.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,10 +38,11 @@ namespace Emby.Server.Implementations.Devices
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly ILocalizationManager _localizationManager;
|
||||
|
||||
private readonly IAuthenticationRepository _authRepo;
|
||||
private readonly Dictionary<string, ClientCapabilities> _capabilitiesCache;
|
||||
|
||||
public event EventHandler<GenericEventArgs<Tuple<string, DeviceOptions>>> DeviceOptionsUpdated;
|
||||
|
||||
public event EventHandler<GenericEventArgs<CameraImageUploadInfo>> CameraImageUploaded;
|
||||
|
||||
private readonly object _cameraUploadSyncLock = new object();
|
||||
@@ -65,10 +66,9 @@ namespace Emby.Server.Implementations.Devices
|
||||
_libraryManager = libraryManager;
|
||||
_localizationManager = localizationManager;
|
||||
_authRepo = authRepo;
|
||||
_capabilitiesCache = new Dictionary<string, ClientCapabilities>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
|
||||
private Dictionary<string, ClientCapabilities> _capabilitiesCache = new Dictionary<string, ClientCapabilities>(StringComparer.OrdinalIgnoreCase);
|
||||
public void SaveCapabilities(string deviceId, ClientCapabilities capabilities)
|
||||
{
|
||||
var path = Path.Combine(GetDevicePath(deviceId), "capabilities.json");
|
||||
|
||||
@@ -38,21 +38,23 @@ namespace Emby.Server.Implementations.Dto
|
||||
private readonly IProviderManager _providerManager;
|
||||
|
||||
private readonly IApplicationHost _appHost;
|
||||
private readonly Func<IMediaSourceManager> _mediaSourceManager;
|
||||
private readonly Func<ILiveTvManager> _livetvManager;
|
||||
private readonly IMediaSourceManager _mediaSourceManager;
|
||||
private readonly Lazy<ILiveTvManager> _livetvManagerFactory;
|
||||
|
||||
private ILiveTvManager LivetvManager => _livetvManagerFactory.Value;
|
||||
|
||||
public DtoService(
|
||||
ILoggerFactory loggerFactory,
|
||||
ILogger<DtoService> logger,
|
||||
ILibraryManager libraryManager,
|
||||
IUserDataManager userDataRepository,
|
||||
IItemRepository itemRepo,
|
||||
IImageProcessor imageProcessor,
|
||||
IProviderManager providerManager,
|
||||
IApplicationHost appHost,
|
||||
Func<IMediaSourceManager> mediaSourceManager,
|
||||
Func<ILiveTvManager> livetvManager)
|
||||
IMediaSourceManager mediaSourceManager,
|
||||
Lazy<ILiveTvManager> livetvManagerFactory)
|
||||
{
|
||||
_logger = loggerFactory.CreateLogger(nameof(DtoService));
|
||||
_logger = logger;
|
||||
_libraryManager = libraryManager;
|
||||
_userDataRepository = userDataRepository;
|
||||
_itemRepo = itemRepo;
|
||||
@@ -60,7 +62,7 @@ namespace Emby.Server.Implementations.Dto
|
||||
_providerManager = providerManager;
|
||||
_appHost = appHost;
|
||||
_mediaSourceManager = mediaSourceManager;
|
||||
_livetvManager = livetvManager;
|
||||
_livetvManagerFactory = livetvManagerFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -125,12 +127,12 @@ namespace Emby.Server.Implementations.Dto
|
||||
|
||||
if (programTuples.Count > 0)
|
||||
{
|
||||
_livetvManager().AddInfoToProgramDto(programTuples, options.Fields, user).GetAwaiter().GetResult();
|
||||
LivetvManager.AddInfoToProgramDto(programTuples, options.Fields, user).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
if (channelTuples.Count > 0)
|
||||
{
|
||||
_livetvManager().AddChannelInfo(channelTuples, options, user);
|
||||
LivetvManager.AddChannelInfo(channelTuples, options, user);
|
||||
}
|
||||
|
||||
return returnItems;
|
||||
@@ -142,12 +144,12 @@ namespace Emby.Server.Implementations.Dto
|
||||
if (item is LiveTvChannel tvChannel)
|
||||
{
|
||||
var list = new List<(BaseItemDto, LiveTvChannel)>(1) { (dto, tvChannel) };
|
||||
_livetvManager().AddChannelInfo(list, options, user);
|
||||
LivetvManager.AddChannelInfo(list, options, user);
|
||||
}
|
||||
else if (item is LiveTvProgram)
|
||||
{
|
||||
var list = new List<(BaseItem, BaseItemDto)>(1) { (item, dto) };
|
||||
var task = _livetvManager().AddInfoToProgramDto(list, options.Fields, user);
|
||||
var task = LivetvManager.AddInfoToProgramDto(list, options.Fields, user);
|
||||
Task.WaitAll(task);
|
||||
}
|
||||
|
||||
@@ -223,7 +225,7 @@ namespace Emby.Server.Implementations.Dto
|
||||
if (item is IHasMediaSources
|
||||
&& options.ContainsField(ItemFields.MediaSources))
|
||||
{
|
||||
dto.MediaSources = _mediaSourceManager().GetStaticMediaSources(item, true, user).ToArray();
|
||||
dto.MediaSources = _mediaSourceManager.GetStaticMediaSources(item, true, user).ToArray();
|
||||
|
||||
NormalizeMediaSourceContainers(dto);
|
||||
}
|
||||
@@ -254,7 +256,7 @@ namespace Emby.Server.Implementations.Dto
|
||||
dto.Etag = item.GetEtag(user);
|
||||
}
|
||||
|
||||
var liveTvManager = _livetvManager();
|
||||
var liveTvManager = LivetvManager;
|
||||
var activeRecording = liveTvManager.GetActiveRecordingInfo(item.Path);
|
||||
if (activeRecording != null)
|
||||
{
|
||||
@@ -1045,7 +1047,7 @@ namespace Emby.Server.Implementations.Dto
|
||||
}
|
||||
else
|
||||
{
|
||||
mediaStreams = _mediaSourceManager().GetStaticMediaSources(item, true)[0].MediaStreams.ToArray();
|
||||
mediaStreams = _mediaSourceManager.GetStaticMediaSources(item, true)[0].MediaStreams.ToArray();
|
||||
}
|
||||
|
||||
dto.MediaStreams = mediaStreams;
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<!-- ProjectGuid is only included as a requirement for SonarQube analysis -->
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{E383961B-9356-4D5D-8233-9A1079D03055}</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Emby.Naming\Emby.Naming.csproj" />
|
||||
<ProjectReference Include="..\Emby.Notifications\Emby.Notifications.csproj" />
|
||||
|
||||
@@ -16,46 +16,63 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
private readonly IServerApplicationHost _appHost;
|
||||
private readonly IConfiguration _appConfig;
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly IStartupOptions _startupOptions;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="StartupWizard"/> class.
|
||||
/// </summary>
|
||||
/// <param name="appHost">The application host.</param>
|
||||
/// <param name="appConfig">The application configuration.</param>
|
||||
/// <param name="config">The configuration manager.</param>
|
||||
public StartupWizard(IServerApplicationHost appHost, IConfiguration appConfig, IServerConfigurationManager config)
|
||||
/// <param name="startupOptions">The application startup options.</param>
|
||||
public StartupWizard(
|
||||
IServerApplicationHost appHost,
|
||||
IConfiguration appConfig,
|
||||
IServerConfigurationManager config,
|
||||
IStartupOptions startupOptions)
|
||||
{
|
||||
_appHost = appHost;
|
||||
_appConfig = appConfig;
|
||||
_config = config;
|
||||
_startupOptions = startupOptions;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task RunAsync()
|
||||
{
|
||||
Run();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void Run()
|
||||
{
|
||||
if (!_appHost.CanLaunchWebBrowser)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_appConfig.HostWebClient())
|
||||
// Always launch the startup wizard if possible when it has not been completed
|
||||
if (!_config.Configuration.IsStartupWizardCompleted && _appConfig.HostWebClient())
|
||||
{
|
||||
BrowserLauncher.OpenSwaggerPage(_appHost);
|
||||
BrowserLauncher.OpenWebApp(_appHost);
|
||||
return;
|
||||
}
|
||||
else if (!_config.Configuration.IsStartupWizardCompleted)
|
||||
|
||||
// Do nothing if the web app is configured to not run automatically
|
||||
if (!_config.Configuration.AutoRunWebApp || _startupOptions.NoAutoRunWebApp)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Launch the swagger page if the web client is not hosted, otherwise open the web client
|
||||
if (_appConfig.HostWebClient())
|
||||
{
|
||||
BrowserLauncher.OpenWebApp(_appHost);
|
||||
}
|
||||
else if (_config.Configuration.AutoRunWebApp)
|
||||
else
|
||||
{
|
||||
var options = ((ApplicationHost)_appHost).StartupOptions;
|
||||
|
||||
if (!options.NoAutoRunWebApp)
|
||||
{
|
||||
BrowserLauncher.OpenWebApp(_appHost);
|
||||
}
|
||||
BrowserLauncher.OpenSwaggerPage(_appHost);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Common.Net;
|
||||
@@ -24,7 +25,7 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||
private readonly ILogger _logger;
|
||||
private readonly IApplicationPaths _appPaths;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly Func<string> _defaultUserAgentFn;
|
||||
private readonly IApplicationHost _appHost;
|
||||
|
||||
/// <summary>
|
||||
/// Holds a dictionary of http clients by host. Use GetHttpClient(host) to retrieve or create a client for web requests.
|
||||
@@ -40,12 +41,12 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||
IApplicationPaths appPaths,
|
||||
ILogger<HttpClientManager> logger,
|
||||
IFileSystem fileSystem,
|
||||
Func<string> defaultUserAgentFn)
|
||||
IApplicationHost appHost)
|
||||
{
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
_fileSystem = fileSystem;
|
||||
_appPaths = appPaths ?? throw new ArgumentNullException(nameof(appPaths));
|
||||
_defaultUserAgentFn = defaultUserAgentFn;
|
||||
_appHost = appHost;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -91,7 +92,7 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||
if (options.EnableDefaultUserAgent
|
||||
&& !request.Headers.TryGetValues(HeaderNames.UserAgent, out _))
|
||||
{
|
||||
request.Headers.Add(HeaderNames.UserAgent, _defaultUserAgentFn());
|
||||
request.Headers.Add(HeaderNames.UserAgent, _appHost.ApplicationUserAgent);
|
||||
}
|
||||
|
||||
switch (options.DecompressionMethod)
|
||||
|
||||
@@ -14,6 +14,7 @@ using Emby.Server.Implementations.Services;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Controller.Authentication;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Net;
|
||||
using MediaBrowser.Model.Events;
|
||||
@@ -230,7 +231,8 @@ namespace Emby.Server.Implementations.HttpServer
|
||||
switch (ex)
|
||||
{
|
||||
case ArgumentException _: return 400;
|
||||
case SecurityException _: return 401;
|
||||
case AuthenticationException _: return 401;
|
||||
case SecurityException _: return 403;
|
||||
case DirectoryNotFoundException _:
|
||||
case FileNotFoundException _:
|
||||
case ResourceNotFoundException _: return 404;
|
||||
@@ -239,55 +241,52 @@ namespace Emby.Server.Implementations.HttpServer
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ErrorHandler(Exception ex, IRequest httpReq, bool logExceptionStackTrace, string urlToLog)
|
||||
private async Task ErrorHandler(Exception ex, IRequest httpReq, int statusCode, string urlToLog)
|
||||
{
|
||||
try
|
||||
bool ignoreStackTrace =
|
||||
ex is SocketException
|
||||
|| ex is IOException
|
||||
|| ex is OperationCanceledException
|
||||
|| ex is SecurityException
|
||||
|| ex is AuthenticationException
|
||||
|| ex is FileNotFoundException;
|
||||
|
||||
if (ignoreStackTrace)
|
||||
{
|
||||
ex = GetActualException(ex);
|
||||
|
||||
if (logExceptionStackTrace)
|
||||
{
|
||||
_logger.LogError(ex, "Error processing request. URL: {Url}", urlToLog);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogError("Error processing request: {Message}. URL: {Url}", ex.Message.TrimEnd('.'), urlToLog);
|
||||
}
|
||||
|
||||
var httpRes = httpReq.Response;
|
||||
|
||||
if (httpRes.HasStarted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var statusCode = GetStatusCode(ex);
|
||||
httpRes.StatusCode = statusCode;
|
||||
|
||||
var errContent = NormalizeExceptionMessage(ex.Message);
|
||||
httpRes.ContentType = "text/plain";
|
||||
httpRes.ContentLength = errContent.Length;
|
||||
await httpRes.WriteAsync(errContent).ConfigureAwait(false);
|
||||
_logger.LogError("Error processing request: {Message}. URL: {Url}", ex.Message.TrimEnd('.'), urlToLog);
|
||||
}
|
||||
catch (Exception errorEx)
|
||||
else
|
||||
{
|
||||
_logger.LogError(errorEx, "Error this.ProcessRequest(context)(Exception while writing error to the response). URL: {Url}", urlToLog);
|
||||
_logger.LogError(ex, "Error processing request. URL: {Url}", urlToLog);
|
||||
}
|
||||
|
||||
var httpRes = httpReq.Response;
|
||||
|
||||
if (httpRes.HasStarted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
httpRes.StatusCode = statusCode;
|
||||
|
||||
var errContent = NormalizeExceptionMessage(ex) ?? string.Empty;
|
||||
httpRes.ContentType = "text/plain";
|
||||
httpRes.ContentLength = errContent.Length;
|
||||
await httpRes.WriteAsync(errContent).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private string NormalizeExceptionMessage(string msg)
|
||||
private string NormalizeExceptionMessage(Exception ex)
|
||||
{
|
||||
if (msg == null)
|
||||
// Do not expose the exception message for AuthenticationException
|
||||
if (ex is AuthenticationException)
|
||||
{
|
||||
return string.Empty;
|
||||
return null;
|
||||
}
|
||||
|
||||
// Strip any information we don't want to reveal
|
||||
|
||||
msg = msg.Replace(_config.ApplicationPaths.ProgramSystemPath, string.Empty, StringComparison.OrdinalIgnoreCase);
|
||||
msg = msg.Replace(_config.ApplicationPaths.ProgramDataPath, string.Empty, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
return msg;
|
||||
return ex.Message
|
||||
?.Replace(_config.ApplicationPaths.ProgramSystemPath, string.Empty, StringComparison.OrdinalIgnoreCase)
|
||||
.Replace(_config.ApplicationPaths.ProgramDataPath, string.Empty, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -536,22 +535,32 @@ namespace Emby.Server.Implementations.HttpServer
|
||||
throw new FileNotFoundException();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (Exception requestEx)
|
||||
{
|
||||
// Do not handle exceptions manually when in development mode
|
||||
// The framework-defined development exception page will be returned instead
|
||||
if (_hostEnvironment.IsDevelopment())
|
||||
try
|
||||
{
|
||||
throw;
|
||||
}
|
||||
var requestInnerEx = GetActualException(requestEx);
|
||||
var statusCode = GetStatusCode(requestInnerEx);
|
||||
|
||||
bool ignoreStackTrace =
|
||||
ex is SocketException
|
||||
|| ex is IOException
|
||||
|| ex is OperationCanceledException
|
||||
|| ex is SecurityException
|
||||
|| ex is FileNotFoundException;
|
||||
await ErrorHandler(ex, httpReq, !ignoreStackTrace, urlToLog).ConfigureAwait(false);
|
||||
// Do not handle 500 server exceptions manually when in development mode
|
||||
// The framework-defined development exception page will be returned instead
|
||||
if (statusCode == 500 && _hostEnvironment.IsDevelopment())
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
await ErrorHandler(requestInnerEx, httpReq, statusCode, urlToLog).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception handlerException)
|
||||
{
|
||||
var aggregateEx = new AggregateException("Error while handling request exception", requestEx, handlerException);
|
||||
_logger.LogError(aggregateEx, "Error while handling exception in response to {Url}", urlToLog);
|
||||
|
||||
if (_hostEnvironment.IsDevelopment())
|
||||
{
|
||||
throw aggregateEx;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Security.Authentication;
|
||||
using Emby.Server.Implementations.SocketSharp;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
@@ -68,7 +69,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
|
||||
|
||||
if (user == null && auth.UserId != Guid.Empty)
|
||||
{
|
||||
throw new SecurityException("User with Id " + auth.UserId + " not found");
|
||||
throw new AuthenticationException("User with Id " + auth.UserId + " not found");
|
||||
}
|
||||
|
||||
if (user != null)
|
||||
@@ -108,18 +109,12 @@ namespace Emby.Server.Implementations.HttpServer.Security
|
||||
{
|
||||
if (user.Policy.IsDisabled)
|
||||
{
|
||||
throw new SecurityException("User account has been disabled.")
|
||||
{
|
||||
SecurityExceptionType = SecurityExceptionType.Unauthenticated
|
||||
};
|
||||
throw new SecurityException("User account has been disabled.");
|
||||
}
|
||||
|
||||
if (!user.Policy.EnableRemoteAccess && !_networkManager.IsInLocalNetwork(request.RemoteIp))
|
||||
{
|
||||
throw new SecurityException("User account has been disabled.")
|
||||
{
|
||||
SecurityExceptionType = SecurityExceptionType.Unauthenticated
|
||||
};
|
||||
throw new SecurityException("User account has been disabled.");
|
||||
}
|
||||
|
||||
if (!user.Policy.IsAdministrator
|
||||
@@ -128,10 +123,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
|
||||
{
|
||||
request.Response.Headers.Add("X-Application-Error-Code", "ParentalControl");
|
||||
|
||||
throw new SecurityException("This user account is not allowed access at this time.")
|
||||
{
|
||||
SecurityExceptionType = SecurityExceptionType.ParentalControl
|
||||
};
|
||||
throw new SecurityException("This user account is not allowed access at this time.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,10 +182,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
|
||||
{
|
||||
if (user == null || !user.Policy.IsAdministrator)
|
||||
{
|
||||
throw new SecurityException("User does not have admin access.")
|
||||
{
|
||||
SecurityExceptionType = SecurityExceptionType.Unauthenticated
|
||||
};
|
||||
throw new SecurityException("User does not have admin access.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,10 +190,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
|
||||
{
|
||||
if (user == null || !user.Policy.EnableContentDeletion)
|
||||
{
|
||||
throw new SecurityException("User does not have delete access.")
|
||||
{
|
||||
SecurityExceptionType = SecurityExceptionType.Unauthenticated
|
||||
};
|
||||
throw new SecurityException("User does not have delete access.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,10 +198,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
|
||||
{
|
||||
if (user == null || !user.Policy.EnableContentDownloading)
|
||||
{
|
||||
throw new SecurityException("User does not have download access.")
|
||||
{
|
||||
SecurityExceptionType = SecurityExceptionType.Unauthenticated
|
||||
};
|
||||
throw new SecurityException("User does not have download access.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -230,14 +213,14 @@ namespace Emby.Server.Implementations.HttpServer.Security
|
||||
{
|
||||
if (string.IsNullOrEmpty(token))
|
||||
{
|
||||
throw new SecurityException("Access token is required.");
|
||||
throw new AuthenticationException("Access token is required.");
|
||||
}
|
||||
|
||||
var info = GetTokenInfo(request);
|
||||
|
||||
if (info == null)
|
||||
{
|
||||
throw new SecurityException("Access token is invalid or expired.");
|
||||
throw new AuthenticationException("Access token is invalid or expired.");
|
||||
}
|
||||
|
||||
//if (!string.IsNullOrEmpty(info.UserId))
|
||||
|
||||
@@ -17,6 +17,11 @@ namespace Emby.Server.Implementations.IO
|
||||
{
|
||||
public class LibraryMonitor : ILibraryMonitor
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly IServerConfigurationManager _configurationManager;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// The file system watchers.
|
||||
/// </summary>
|
||||
@@ -113,34 +118,23 @@ namespace Emby.Server.Implementations.IO
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex, "Error in ReportFileSystemChanged for {path}", path);
|
||||
_logger.LogError(ex, "Error in ReportFileSystemChanged for {path}", path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the logger.
|
||||
/// </summary>
|
||||
/// <value>The logger.</value>
|
||||
private ILogger Logger { get; set; }
|
||||
|
||||
private ILibraryManager LibraryManager { get; set; }
|
||||
private IServerConfigurationManager ConfigurationManager { get; set; }
|
||||
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LibraryMonitor" /> class.
|
||||
/// </summary>
|
||||
public LibraryMonitor(
|
||||
ILoggerFactory loggerFactory,
|
||||
ILogger<LibraryMonitor> logger,
|
||||
ILibraryManager libraryManager,
|
||||
IServerConfigurationManager configurationManager,
|
||||
IFileSystem fileSystem)
|
||||
{
|
||||
LibraryManager = libraryManager;
|
||||
Logger = loggerFactory.CreateLogger(GetType().Name);
|
||||
ConfigurationManager = configurationManager;
|
||||
_libraryManager = libraryManager;
|
||||
_logger = logger;
|
||||
_configurationManager = configurationManager;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
@@ -151,7 +145,7 @@ namespace Emby.Server.Implementations.IO
|
||||
return false;
|
||||
}
|
||||
|
||||
var options = LibraryManager.GetLibraryOptions(item);
|
||||
var options = _libraryManager.GetLibraryOptions(item);
|
||||
|
||||
if (options != null)
|
||||
{
|
||||
@@ -163,12 +157,12 @@ namespace Emby.Server.Implementations.IO
|
||||
|
||||
public void Start()
|
||||
{
|
||||
LibraryManager.ItemAdded += OnLibraryManagerItemAdded;
|
||||
LibraryManager.ItemRemoved += OnLibraryManagerItemRemoved;
|
||||
_libraryManager.ItemAdded += OnLibraryManagerItemAdded;
|
||||
_libraryManager.ItemRemoved += OnLibraryManagerItemRemoved;
|
||||
|
||||
var pathsToWatch = new List<string>();
|
||||
|
||||
var paths = LibraryManager
|
||||
var paths = _libraryManager
|
||||
.RootFolder
|
||||
.Children
|
||||
.Where(IsLibraryMonitorEnabled)
|
||||
@@ -261,7 +255,7 @@ namespace Emby.Server.Implementations.IO
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
// Seeing a crash in the mono runtime due to an exception being thrown on a different thread
|
||||
Logger.LogInformation("Skipping realtime monitor for {Path} because the path does not exist", path);
|
||||
_logger.LogInformation("Skipping realtime monitor for {Path} because the path does not exist", path);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -297,7 +291,7 @@ namespace Emby.Server.Implementations.IO
|
||||
if (_fileSystemWatchers.TryAdd(path, newWatcher))
|
||||
{
|
||||
newWatcher.EnableRaisingEvents = true;
|
||||
Logger.LogInformation("Watching directory " + path);
|
||||
_logger.LogInformation("Watching directory " + path);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -307,7 +301,7 @@ namespace Emby.Server.Implementations.IO
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex, "Error watching path: {path}", path);
|
||||
_logger.LogError(ex, "Error watching path: {path}", path);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -333,7 +327,7 @@ namespace Emby.Server.Implementations.IO
|
||||
{
|
||||
using (watcher)
|
||||
{
|
||||
Logger.LogInformation("Stopping directory watching for path {Path}", watcher.Path);
|
||||
_logger.LogInformation("Stopping directory watching for path {Path}", watcher.Path);
|
||||
|
||||
watcher.Created -= OnWatcherChanged;
|
||||
watcher.Deleted -= OnWatcherChanged;
|
||||
@@ -372,7 +366,7 @@ namespace Emby.Server.Implementations.IO
|
||||
var ex = e.GetException();
|
||||
var dw = (FileSystemWatcher)sender;
|
||||
|
||||
Logger.LogError(ex, "Error in Directory watcher for: {Path}", dw.Path);
|
||||
_logger.LogError(ex, "Error in Directory watcher for: {Path}", dw.Path);
|
||||
|
||||
DisposeWatcher(dw, true);
|
||||
}
|
||||
@@ -390,7 +384,7 @@ namespace Emby.Server.Implementations.IO
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex, "Exception in ReportFileSystemChanged. Path: {FullPath}", e.FullPath);
|
||||
_logger.LogError(ex, "Exception in ReportFileSystemChanged. Path: {FullPath}", e.FullPath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -416,13 +410,13 @@ namespace Emby.Server.Implementations.IO
|
||||
{
|
||||
if (_fileSystem.AreEqual(i, path))
|
||||
{
|
||||
Logger.LogDebug("Ignoring change to {Path}", path);
|
||||
_logger.LogDebug("Ignoring change to {Path}", path);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_fileSystem.ContainsSubPath(i, path))
|
||||
{
|
||||
Logger.LogDebug("Ignoring change to {Path}", path);
|
||||
_logger.LogDebug("Ignoring change to {Path}", path);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -430,7 +424,7 @@ namespace Emby.Server.Implementations.IO
|
||||
var parent = Path.GetDirectoryName(i);
|
||||
if (!string.IsNullOrEmpty(parent) && _fileSystem.AreEqual(parent, path))
|
||||
{
|
||||
Logger.LogDebug("Ignoring change to {Path}", path);
|
||||
_logger.LogDebug("Ignoring change to {Path}", path);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -485,7 +479,7 @@ namespace Emby.Server.Implementations.IO
|
||||
}
|
||||
}
|
||||
|
||||
var newRefresher = new FileRefresher(path, ConfigurationManager, LibraryManager, Logger);
|
||||
var newRefresher = new FileRefresher(path, _configurationManager, _libraryManager, _logger);
|
||||
newRefresher.Completed += NewRefresher_Completed;
|
||||
_activeRefreshers.Add(newRefresher);
|
||||
}
|
||||
@@ -502,8 +496,8 @@ namespace Emby.Server.Implementations.IO
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
LibraryManager.ItemAdded -= OnLibraryManagerItemAdded;
|
||||
LibraryManager.ItemRemoved -= OnLibraryManagerItemRemoved;
|
||||
_libraryManager.ItemAdded -= OnLibraryManagerItemAdded;
|
||||
_libraryManager.ItemRemoved -= OnLibraryManagerItemRemoved;
|
||||
|
||||
foreach (var watcher in _fileSystemWatchers.Values.ToList())
|
||||
{
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Emby.Server.Implementations.Library
|
||||
{
|
||||
if (resolvedUser == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(resolvedUser));
|
||||
throw new AuthenticationException($"Specified user does not exist.");
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
|
||||
@@ -54,9 +54,29 @@ namespace Emby.Server.Implementations.Library
|
||||
/// </summary>
|
||||
public class LibraryManager : ILibraryManager
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly ITaskManager _taskManager;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly IUserDataManager _userDataRepository;
|
||||
private readonly IServerConfigurationManager _configurationManager;
|
||||
private readonly Lazy<ILibraryMonitor> _libraryMonitorFactory;
|
||||
private readonly Lazy<IProviderManager> _providerManagerFactory;
|
||||
private readonly Lazy<IUserViewManager> _userviewManagerFactory;
|
||||
private readonly IServerApplicationHost _appHost;
|
||||
private readonly IMediaEncoder _mediaEncoder;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly IItemRepository _itemRepository;
|
||||
private readonly ConcurrentDictionary<Guid, BaseItem> _libraryItemsCache;
|
||||
|
||||
private NamingOptions _namingOptions;
|
||||
private string[] _videoFileExtensions;
|
||||
|
||||
private ILibraryMonitor LibraryMonitor => _libraryMonitorFactory.Value;
|
||||
|
||||
private IProviderManager ProviderManager => _providerManagerFactory.Value;
|
||||
|
||||
private IUserViewManager UserViewManager => _userviewManagerFactory.Value;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the postscan tasks.
|
||||
/// </summary>
|
||||
@@ -89,12 +109,6 @@ namespace Emby.Server.Implementations.Library
|
||||
/// <value>The comparers.</value>
|
||||
private IBaseItemComparer[] Comparers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the active item repository
|
||||
/// </summary>
|
||||
/// <value>The item repository.</value>
|
||||
public IItemRepository ItemRepository { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [item added].
|
||||
/// </summary>
|
||||
@@ -110,90 +124,47 @@ namespace Emby.Server.Implementations.Library
|
||||
/// </summary>
|
||||
public event EventHandler<ItemChangeEventArgs> ItemRemoved;
|
||||
|
||||
/// <summary>
|
||||
/// The _logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// The _task manager
|
||||
/// </summary>
|
||||
private readonly ITaskManager _taskManager;
|
||||
|
||||
/// <summary>
|
||||
/// The _user manager
|
||||
/// </summary>
|
||||
private readonly IUserManager _userManager;
|
||||
|
||||
/// <summary>
|
||||
/// The _user data repository
|
||||
/// </summary>
|
||||
private readonly IUserDataManager _userDataRepository;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the configuration manager.
|
||||
/// </summary>
|
||||
/// <value>The configuration manager.</value>
|
||||
private IServerConfigurationManager ConfigurationManager { get; set; }
|
||||
|
||||
private readonly Func<ILibraryMonitor> _libraryMonitorFactory;
|
||||
private readonly Func<IProviderManager> _providerManagerFactory;
|
||||
private readonly Func<IUserViewManager> _userviewManager;
|
||||
public bool IsScanRunning { get; private set; }
|
||||
|
||||
private IServerApplicationHost _appHost;
|
||||
private readonly IMediaEncoder _mediaEncoder;
|
||||
|
||||
/// <summary>
|
||||
/// The _library items cache
|
||||
/// </summary>
|
||||
private readonly ConcurrentDictionary<Guid, BaseItem> _libraryItemsCache;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the library items cache.
|
||||
/// </summary>
|
||||
/// <value>The library items cache.</value>
|
||||
private ConcurrentDictionary<Guid, BaseItem> LibraryItemsCache => _libraryItemsCache;
|
||||
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LibraryManager" /> class.
|
||||
/// </summary>
|
||||
/// <param name="appHost">The application host</param>
|
||||
/// <param name="loggerFactory">The logger factory.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="taskManager">The task manager.</param>
|
||||
/// <param name="userManager">The user manager.</param>
|
||||
/// <param name="configurationManager">The configuration manager.</param>
|
||||
/// <param name="userDataRepository">The user data repository.</param>
|
||||
public LibraryManager(
|
||||
IServerApplicationHost appHost,
|
||||
ILoggerFactory loggerFactory,
|
||||
ILogger<LibraryManager> logger,
|
||||
ITaskManager taskManager,
|
||||
IUserManager userManager,
|
||||
IServerConfigurationManager configurationManager,
|
||||
IUserDataManager userDataRepository,
|
||||
Func<ILibraryMonitor> libraryMonitorFactory,
|
||||
Lazy<ILibraryMonitor> libraryMonitorFactory,
|
||||
IFileSystem fileSystem,
|
||||
Func<IProviderManager> providerManagerFactory,
|
||||
Func<IUserViewManager> userviewManager,
|
||||
IMediaEncoder mediaEncoder)
|
||||
Lazy<IProviderManager> providerManagerFactory,
|
||||
Lazy<IUserViewManager> userviewManagerFactory,
|
||||
IMediaEncoder mediaEncoder,
|
||||
IItemRepository itemRepository)
|
||||
{
|
||||
_appHost = appHost;
|
||||
_logger = loggerFactory.CreateLogger(nameof(LibraryManager));
|
||||
_logger = logger;
|
||||
_taskManager = taskManager;
|
||||
_userManager = userManager;
|
||||
ConfigurationManager = configurationManager;
|
||||
_configurationManager = configurationManager;
|
||||
_userDataRepository = userDataRepository;
|
||||
_libraryMonitorFactory = libraryMonitorFactory;
|
||||
_fileSystem = fileSystem;
|
||||
_providerManagerFactory = providerManagerFactory;
|
||||
_userviewManager = userviewManager;
|
||||
_userviewManagerFactory = userviewManagerFactory;
|
||||
_mediaEncoder = mediaEncoder;
|
||||
_itemRepository = itemRepository;
|
||||
|
||||
_libraryItemsCache = new ConcurrentDictionary<Guid, BaseItem>();
|
||||
|
||||
ConfigurationManager.ConfigurationUpdated += ConfigurationUpdated;
|
||||
_configurationManager.ConfigurationUpdated += ConfigurationUpdated;
|
||||
|
||||
RecordConfigurationValues(configurationManager.Configuration);
|
||||
}
|
||||
@@ -272,7 +243,7 @@ namespace Emby.Server.Implementations.Library
|
||||
/// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
|
||||
private void ConfigurationUpdated(object sender, EventArgs e)
|
||||
{
|
||||
var config = ConfigurationManager.Configuration;
|
||||
var config = _configurationManager.Configuration;
|
||||
|
||||
var wizardChanged = config.IsStartupWizardCompleted != _wizardCompleted;
|
||||
|
||||
@@ -306,7 +277,7 @@ namespace Emby.Server.Implementations.Library
|
||||
}
|
||||
}
|
||||
|
||||
LibraryItemsCache.AddOrUpdate(item.Id, item, delegate { return item; });
|
||||
_libraryItemsCache.AddOrUpdate(item.Id, item, delegate { return item; });
|
||||
}
|
||||
|
||||
public void DeleteItem(BaseItem item, DeleteOptions options)
|
||||
@@ -437,10 +408,10 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
item.SetParent(null);
|
||||
|
||||
ItemRepository.DeleteItem(item.Id);
|
||||
_itemRepository.DeleteItem(item.Id);
|
||||
foreach (var child in children)
|
||||
{
|
||||
ItemRepository.DeleteItem(child.Id);
|
||||
_itemRepository.DeleteItem(child.Id);
|
||||
}
|
||||
|
||||
_libraryItemsCache.TryRemove(item.Id, out BaseItem removed);
|
||||
@@ -509,15 +480,15 @@ namespace Emby.Server.Implementations.Library
|
||||
throw new ArgumentNullException(nameof(type));
|
||||
}
|
||||
|
||||
if (key.StartsWith(ConfigurationManager.ApplicationPaths.ProgramDataPath, StringComparison.Ordinal))
|
||||
if (key.StartsWith(_configurationManager.ApplicationPaths.ProgramDataPath, StringComparison.Ordinal))
|
||||
{
|
||||
// Try to normalize paths located underneath program-data in an attempt to make them more portable
|
||||
key = key.Substring(ConfigurationManager.ApplicationPaths.ProgramDataPath.Length)
|
||||
key = key.Substring(_configurationManager.ApplicationPaths.ProgramDataPath.Length)
|
||||
.TrimStart(new[] { '/', '\\' })
|
||||
.Replace("/", "\\");
|
||||
}
|
||||
|
||||
if (forceCaseInsensitive || !ConfigurationManager.Configuration.EnableCaseSensitiveItemIds)
|
||||
if (forceCaseInsensitive || !_configurationManager.Configuration.EnableCaseSensitiveItemIds)
|
||||
{
|
||||
key = key.ToLowerInvariant();
|
||||
}
|
||||
@@ -550,7 +521,7 @@ namespace Emby.Server.Implementations.Library
|
||||
collectionType = GetContentTypeOverride(fullPath, true);
|
||||
}
|
||||
|
||||
var args = new ItemResolveArgs(ConfigurationManager.ApplicationPaths, directoryService)
|
||||
var args = new ItemResolveArgs(_configurationManager.ApplicationPaths, directoryService)
|
||||
{
|
||||
Parent = parent,
|
||||
Path = fullPath,
|
||||
@@ -720,7 +691,7 @@ namespace Emby.Server.Implementations.Library
|
||||
/// <exception cref="InvalidOperationException">Cannot create the root folder until plugins have loaded.</exception>
|
||||
public AggregateFolder CreateRootFolder()
|
||||
{
|
||||
var rootFolderPath = ConfigurationManager.ApplicationPaths.RootFolderPath;
|
||||
var rootFolderPath = _configurationManager.ApplicationPaths.RootFolderPath;
|
||||
|
||||
Directory.CreateDirectory(rootFolderPath);
|
||||
|
||||
@@ -734,7 +705,7 @@ namespace Emby.Server.Implementations.Library
|
||||
}
|
||||
|
||||
// Add in the plug-in folders
|
||||
var path = Path.Combine(ConfigurationManager.ApplicationPaths.DataPath, "playlists");
|
||||
var path = Path.Combine(_configurationManager.ApplicationPaths.DataPath, "playlists");
|
||||
|
||||
Directory.CreateDirectory(path);
|
||||
|
||||
@@ -786,7 +757,7 @@ namespace Emby.Server.Implementations.Library
|
||||
{
|
||||
if (_userRootFolder == null)
|
||||
{
|
||||
var userRootPath = ConfigurationManager.ApplicationPaths.DefaultUserViewsPath;
|
||||
var userRootPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath;
|
||||
|
||||
_logger.LogDebug("Creating userRootPath at {path}", userRootPath);
|
||||
Directory.CreateDirectory(userRootPath);
|
||||
@@ -980,7 +951,7 @@ namespace Emby.Server.Implementations.Library
|
||||
where T : BaseItem, new()
|
||||
{
|
||||
var path = getPathFn(name);
|
||||
var forceCaseInsensitiveId = ConfigurationManager.Configuration.EnableNormalizedItemByNameIds;
|
||||
var forceCaseInsensitiveId = _configurationManager.Configuration.EnableNormalizedItemByNameIds;
|
||||
return GetNewItemIdInternal(path, typeof(T), forceCaseInsensitiveId);
|
||||
}
|
||||
|
||||
@@ -994,7 +965,7 @@ namespace Emby.Server.Implementations.Library
|
||||
public Task ValidatePeople(CancellationToken cancellationToken, IProgress<double> progress)
|
||||
{
|
||||
// Ensure the location is available.
|
||||
Directory.CreateDirectory(ConfigurationManager.ApplicationPaths.PeoplePath);
|
||||
Directory.CreateDirectory(_configurationManager.ApplicationPaths.PeoplePath);
|
||||
|
||||
return new PeopleValidator(this, _logger, _fileSystem).ValidatePeople(cancellationToken, progress);
|
||||
}
|
||||
@@ -1031,7 +1002,7 @@ namespace Emby.Server.Implementations.Library
|
||||
public async Task ValidateMediaLibraryInternal(IProgress<double> progress, CancellationToken cancellationToken)
|
||||
{
|
||||
IsScanRunning = true;
|
||||
_libraryMonitorFactory().Stop();
|
||||
LibraryMonitor.Stop();
|
||||
|
||||
try
|
||||
{
|
||||
@@ -1039,7 +1010,7 @@ namespace Emby.Server.Implementations.Library
|
||||
}
|
||||
finally
|
||||
{
|
||||
_libraryMonitorFactory().Start();
|
||||
LibraryMonitor.Start();
|
||||
IsScanRunning = false;
|
||||
}
|
||||
}
|
||||
@@ -1148,7 +1119,7 @@ namespace Emby.Server.Implementations.Library
|
||||
progress.Report(percent * 100);
|
||||
}
|
||||
|
||||
ItemRepository.UpdateInheritedValues(cancellationToken);
|
||||
_itemRepository.UpdateInheritedValues(cancellationToken);
|
||||
|
||||
progress.Report(100);
|
||||
}
|
||||
@@ -1168,9 +1139,9 @@ namespace Emby.Server.Implementations.Library
|
||||
var topLibraryFolders = GetUserRootFolder().Children.ToList();
|
||||
|
||||
_logger.LogDebug("Getting refreshQueue");
|
||||
var refreshQueue = includeRefreshState ? _providerManagerFactory().GetRefreshQueue() : null;
|
||||
var refreshQueue = includeRefreshState ? ProviderManager.GetRefreshQueue() : null;
|
||||
|
||||
return _fileSystem.GetDirectoryPaths(ConfigurationManager.ApplicationPaths.DefaultUserViewsPath)
|
||||
return _fileSystem.GetDirectoryPaths(_configurationManager.ApplicationPaths.DefaultUserViewsPath)
|
||||
.Select(dir => GetVirtualFolderInfo(dir, topLibraryFolders, refreshQueue))
|
||||
.ToList();
|
||||
}
|
||||
@@ -1245,7 +1216,7 @@ namespace Emby.Server.Implementations.Library
|
||||
throw new ArgumentException("Guid can't be empty", nameof(id));
|
||||
}
|
||||
|
||||
if (LibraryItemsCache.TryGetValue(id, out BaseItem item))
|
||||
if (_libraryItemsCache.TryGetValue(id, out BaseItem item))
|
||||
{
|
||||
return item;
|
||||
}
|
||||
@@ -1276,7 +1247,7 @@ namespace Emby.Server.Implementations.Library
|
||||
AddUserToQuery(query, query.User, allowExternalContent);
|
||||
}
|
||||
|
||||
return ItemRepository.GetItemList(query);
|
||||
return _itemRepository.GetItemList(query);
|
||||
}
|
||||
|
||||
public List<BaseItem> GetItemList(InternalItemsQuery query)
|
||||
@@ -1300,7 +1271,7 @@ namespace Emby.Server.Implementations.Library
|
||||
AddUserToQuery(query, query.User);
|
||||
}
|
||||
|
||||
return ItemRepository.GetCount(query);
|
||||
return _itemRepository.GetCount(query);
|
||||
}
|
||||
|
||||
public List<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents)
|
||||
@@ -1315,7 +1286,7 @@ namespace Emby.Server.Implementations.Library
|
||||
}
|
||||
}
|
||||
|
||||
return ItemRepository.GetItemList(query);
|
||||
return _itemRepository.GetItemList(query);
|
||||
}
|
||||
|
||||
public QueryResult<BaseItem> QueryItems(InternalItemsQuery query)
|
||||
@@ -1327,12 +1298,12 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
if (query.EnableTotalRecordCount)
|
||||
{
|
||||
return ItemRepository.GetItems(query);
|
||||
return _itemRepository.GetItems(query);
|
||||
}
|
||||
|
||||
return new QueryResult<BaseItem>
|
||||
{
|
||||
Items = ItemRepository.GetItemList(query).ToArray()
|
||||
Items = _itemRepository.GetItemList(query).ToArray()
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1343,7 +1314,7 @@ namespace Emby.Server.Implementations.Library
|
||||
AddUserToQuery(query, query.User);
|
||||
}
|
||||
|
||||
return ItemRepository.GetItemIdsList(query);
|
||||
return _itemRepository.GetItemIdsList(query);
|
||||
}
|
||||
|
||||
public QueryResult<(BaseItem, ItemCounts)> GetStudios(InternalItemsQuery query)
|
||||
@@ -1354,7 +1325,7 @@ namespace Emby.Server.Implementations.Library
|
||||
}
|
||||
|
||||
SetTopParentOrAncestorIds(query);
|
||||
return ItemRepository.GetStudios(query);
|
||||
return _itemRepository.GetStudios(query);
|
||||
}
|
||||
|
||||
public QueryResult<(BaseItem, ItemCounts)> GetGenres(InternalItemsQuery query)
|
||||
@@ -1365,7 +1336,7 @@ namespace Emby.Server.Implementations.Library
|
||||
}
|
||||
|
||||
SetTopParentOrAncestorIds(query);
|
||||
return ItemRepository.GetGenres(query);
|
||||
return _itemRepository.GetGenres(query);
|
||||
}
|
||||
|
||||
public QueryResult<(BaseItem, ItemCounts)> GetMusicGenres(InternalItemsQuery query)
|
||||
@@ -1376,7 +1347,7 @@ namespace Emby.Server.Implementations.Library
|
||||
}
|
||||
|
||||
SetTopParentOrAncestorIds(query);
|
||||
return ItemRepository.GetMusicGenres(query);
|
||||
return _itemRepository.GetMusicGenres(query);
|
||||
}
|
||||
|
||||
public QueryResult<(BaseItem, ItemCounts)> GetAllArtists(InternalItemsQuery query)
|
||||
@@ -1387,7 +1358,7 @@ namespace Emby.Server.Implementations.Library
|
||||
}
|
||||
|
||||
SetTopParentOrAncestorIds(query);
|
||||
return ItemRepository.GetAllArtists(query);
|
||||
return _itemRepository.GetAllArtists(query);
|
||||
}
|
||||
|
||||
public QueryResult<(BaseItem, ItemCounts)> GetArtists(InternalItemsQuery query)
|
||||
@@ -1398,7 +1369,7 @@ namespace Emby.Server.Implementations.Library
|
||||
}
|
||||
|
||||
SetTopParentOrAncestorIds(query);
|
||||
return ItemRepository.GetArtists(query);
|
||||
return _itemRepository.GetArtists(query);
|
||||
}
|
||||
|
||||
private void SetTopParentOrAncestorIds(InternalItemsQuery query)
|
||||
@@ -1439,7 +1410,7 @@ namespace Emby.Server.Implementations.Library
|
||||
}
|
||||
|
||||
SetTopParentOrAncestorIds(query);
|
||||
return ItemRepository.GetAlbumArtists(query);
|
||||
return _itemRepository.GetAlbumArtists(query);
|
||||
}
|
||||
|
||||
public QueryResult<BaseItem> GetItemsResult(InternalItemsQuery query)
|
||||
@@ -1460,10 +1431,10 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
if (query.EnableTotalRecordCount)
|
||||
{
|
||||
return ItemRepository.GetItems(query);
|
||||
return _itemRepository.GetItems(query);
|
||||
}
|
||||
|
||||
var list = ItemRepository.GetItemList(query);
|
||||
var list = _itemRepository.GetItemList(query);
|
||||
|
||||
return new QueryResult<BaseItem>
|
||||
{
|
||||
@@ -1509,7 +1480,7 @@ namespace Emby.Server.Implementations.Library
|
||||
string.IsNullOrEmpty(query.SeriesPresentationUniqueKey) &&
|
||||
query.ItemIds.Length == 0)
|
||||
{
|
||||
var userViews = _userviewManager().GetUserViews(new UserViewQuery
|
||||
var userViews = UserViewManager.GetUserViews(new UserViewQuery
|
||||
{
|
||||
UserId = user.Id,
|
||||
IncludeHidden = true,
|
||||
@@ -1809,7 +1780,7 @@ namespace Emby.Server.Implementations.Library
|
||||
// Don't iterate multiple times
|
||||
var itemsList = items.ToList();
|
||||
|
||||
ItemRepository.SaveItems(itemsList, cancellationToken);
|
||||
_itemRepository.SaveItems(itemsList, cancellationToken);
|
||||
|
||||
foreach (var item in itemsList)
|
||||
{
|
||||
@@ -1846,7 +1817,7 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
public void UpdateImages(BaseItem item)
|
||||
{
|
||||
ItemRepository.SaveImages(item);
|
||||
_itemRepository.SaveImages(item);
|
||||
|
||||
RegisterItem(item);
|
||||
}
|
||||
@@ -1863,7 +1834,7 @@ namespace Emby.Server.Implementations.Library
|
||||
{
|
||||
if (item.IsFileProtocol)
|
||||
{
|
||||
_providerManagerFactory().SaveMetadata(item, updateReason);
|
||||
ProviderManager.SaveMetadata(item, updateReason);
|
||||
}
|
||||
|
||||
item.DateLastSaved = DateTime.UtcNow;
|
||||
@@ -1871,7 +1842,7 @@ namespace Emby.Server.Implementations.Library
|
||||
RegisterItem(item);
|
||||
}
|
||||
|
||||
ItemRepository.SaveItems(itemsList, cancellationToken);
|
||||
_itemRepository.SaveItems(itemsList, cancellationToken);
|
||||
|
||||
if (ItemUpdated != null)
|
||||
{
|
||||
@@ -1947,7 +1918,7 @@ namespace Emby.Server.Implementations.Library
|
||||
/// <returns>BaseItem.</returns>
|
||||
public BaseItem RetrieveItem(Guid id)
|
||||
{
|
||||
return ItemRepository.RetrieveItem(id);
|
||||
return _itemRepository.RetrieveItem(id);
|
||||
}
|
||||
|
||||
public List<Folder> GetCollectionFolders(BaseItem item)
|
||||
@@ -2066,7 +2037,7 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
private string GetContentTypeOverride(string path, bool inherit)
|
||||
{
|
||||
var nameValuePair = ConfigurationManager.Configuration.ContentTypes
|
||||
var nameValuePair = _configurationManager.Configuration.ContentTypes
|
||||
.FirstOrDefault(i => _fileSystem.AreEqual(i.Name, path)
|
||||
|| (inherit && !string.IsNullOrEmpty(i.Name)
|
||||
&& _fileSystem.ContainsSubPath(i.Name, path)));
|
||||
@@ -2115,7 +2086,7 @@ namespace Emby.Server.Implementations.Library
|
||||
string sortName)
|
||||
{
|
||||
var path = Path.Combine(
|
||||
ConfigurationManager.ApplicationPaths.InternalMetadataPath,
|
||||
_configurationManager.ApplicationPaths.InternalMetadataPath,
|
||||
"views",
|
||||
_fileSystem.GetValidFilename(viewType));
|
||||
|
||||
@@ -2147,7 +2118,7 @@ namespace Emby.Server.Implementations.Library
|
||||
if (refresh)
|
||||
{
|
||||
item.UpdateToRepository(ItemUpdateType.MetadataImport, CancellationToken.None);
|
||||
_providerManagerFactory().QueueRefresh(item.Id, new MetadataRefreshOptions(new DirectoryService(_fileSystem)), RefreshPriority.Normal);
|
||||
ProviderManager.QueueRefresh(item.Id, new MetadataRefreshOptions(new DirectoryService(_fileSystem)), RefreshPriority.Normal);
|
||||
}
|
||||
|
||||
return item;
|
||||
@@ -2165,7 +2136,7 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
var id = GetNewItemId(idValues, typeof(UserView));
|
||||
|
||||
var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N", CultureInfo.InvariantCulture));
|
||||
var path = Path.Combine(_configurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N", CultureInfo.InvariantCulture));
|
||||
|
||||
var item = GetItemById(id) as UserView;
|
||||
|
||||
@@ -2202,7 +2173,7 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
if (refresh)
|
||||
{
|
||||
_providerManagerFactory().QueueRefresh(
|
||||
ProviderManager.QueueRefresh(
|
||||
item.Id,
|
||||
new MetadataRefreshOptions(new DirectoryService(_fileSystem))
|
||||
{
|
||||
@@ -2269,7 +2240,7 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
if (refresh)
|
||||
{
|
||||
_providerManagerFactory().QueueRefresh(
|
||||
ProviderManager.QueueRefresh(
|
||||
item.Id,
|
||||
new MetadataRefreshOptions(new DirectoryService(_fileSystem))
|
||||
{
|
||||
@@ -2303,7 +2274,7 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
var id = GetNewItemId(idValues, typeof(UserView));
|
||||
|
||||
var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N", CultureInfo.InvariantCulture));
|
||||
var path = Path.Combine(_configurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N", CultureInfo.InvariantCulture));
|
||||
|
||||
var item = GetItemById(id) as UserView;
|
||||
|
||||
@@ -2346,7 +2317,7 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
if (refresh)
|
||||
{
|
||||
_providerManagerFactory().QueueRefresh(
|
||||
ProviderManager.QueueRefresh(
|
||||
item.Id,
|
||||
new MetadataRefreshOptions(new DirectoryService(_fileSystem))
|
||||
{
|
||||
@@ -2675,8 +2646,8 @@ namespace Emby.Server.Implementations.Library
|
||||
}
|
||||
}
|
||||
|
||||
var metadataPath = ConfigurationManager.Configuration.MetadataPath;
|
||||
var metadataNetworkPath = ConfigurationManager.Configuration.MetadataNetworkPath;
|
||||
var metadataPath = _configurationManager.Configuration.MetadataPath;
|
||||
var metadataNetworkPath = _configurationManager.Configuration.MetadataNetworkPath;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(metadataPath) && !string.IsNullOrWhiteSpace(metadataNetworkPath))
|
||||
{
|
||||
@@ -2687,7 +2658,7 @@ namespace Emby.Server.Implementations.Library
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var map in ConfigurationManager.Configuration.PathSubstitutions)
|
||||
foreach (var map in _configurationManager.Configuration.PathSubstitutions)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(map.From))
|
||||
{
|
||||
@@ -2756,7 +2727,7 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
public List<PersonInfo> GetPeople(InternalPeopleQuery query)
|
||||
{
|
||||
return ItemRepository.GetPeople(query);
|
||||
return _itemRepository.GetPeople(query);
|
||||
}
|
||||
|
||||
public List<PersonInfo> GetPeople(BaseItem item)
|
||||
@@ -2779,7 +2750,7 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
public List<Person> GetPeopleItems(InternalPeopleQuery query)
|
||||
{
|
||||
return ItemRepository.GetPeopleNames(query).Select(i =>
|
||||
return _itemRepository.GetPeopleNames(query).Select(i =>
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -2796,7 +2767,7 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
public List<string> GetPeopleNames(InternalPeopleQuery query)
|
||||
{
|
||||
return ItemRepository.GetPeopleNames(query);
|
||||
return _itemRepository.GetPeopleNames(query);
|
||||
}
|
||||
|
||||
public void UpdatePeople(BaseItem item, List<PersonInfo> people)
|
||||
@@ -2806,7 +2777,7 @@ namespace Emby.Server.Implementations.Library
|
||||
return;
|
||||
}
|
||||
|
||||
ItemRepository.UpdatePeople(item.Id, people);
|
||||
_itemRepository.UpdatePeople(item.Id, people);
|
||||
}
|
||||
|
||||
public async Task<ItemImageInfo> ConvertImageToLocal(BaseItem item, ItemImageInfo image, int imageIndex)
|
||||
@@ -2817,7 +2788,7 @@ namespace Emby.Server.Implementations.Library
|
||||
{
|
||||
_logger.LogDebug("ConvertImageToLocal item {0} - image url: {1}", item.Id, url);
|
||||
|
||||
await _providerManagerFactory().SaveImage(item, url, image.Type, imageIndex, CancellationToken.None).ConfigureAwait(false);
|
||||
await ProviderManager.SaveImage(item, url, image.Type, imageIndex, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
item.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
|
||||
|
||||
@@ -2850,7 +2821,7 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
name = _fileSystem.GetValidFilename(name);
|
||||
|
||||
var rootFolderPath = ConfigurationManager.ApplicationPaths.DefaultUserViewsPath;
|
||||
var rootFolderPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath;
|
||||
|
||||
var virtualFolderPath = Path.Combine(rootFolderPath, name);
|
||||
while (Directory.Exists(virtualFolderPath))
|
||||
@@ -2869,7 +2840,7 @@ namespace Emby.Server.Implementations.Library
|
||||
}
|
||||
}
|
||||
|
||||
_libraryMonitorFactory().Stop();
|
||||
LibraryMonitor.Stop();
|
||||
|
||||
try
|
||||
{
|
||||
@@ -2904,7 +2875,7 @@ namespace Emby.Server.Implementations.Library
|
||||
{
|
||||
// Need to add a delay here or directory watchers may still pick up the changes
|
||||
await Task.Delay(1000).ConfigureAwait(false);
|
||||
_libraryMonitorFactory().Start();
|
||||
LibraryMonitor.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2964,7 +2935,7 @@ namespace Emby.Server.Implementations.Library
|
||||
throw new FileNotFoundException("The network path does not exist.");
|
||||
}
|
||||
|
||||
var rootFolderPath = ConfigurationManager.ApplicationPaths.DefaultUserViewsPath;
|
||||
var rootFolderPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath;
|
||||
var virtualFolderPath = Path.Combine(rootFolderPath, virtualFolderName);
|
||||
|
||||
var shortcutFilename = Path.GetFileNameWithoutExtension(path);
|
||||
@@ -3007,7 +2978,7 @@ namespace Emby.Server.Implementations.Library
|
||||
throw new FileNotFoundException("The network path does not exist.");
|
||||
}
|
||||
|
||||
var rootFolderPath = ConfigurationManager.ApplicationPaths.DefaultUserViewsPath;
|
||||
var rootFolderPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath;
|
||||
var virtualFolderPath = Path.Combine(rootFolderPath, virtualFolderName);
|
||||
|
||||
var libraryOptions = CollectionFolder.GetLibraryOptions(virtualFolderPath);
|
||||
@@ -3060,7 +3031,7 @@ namespace Emby.Server.Implementations.Library
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
}
|
||||
|
||||
var rootFolderPath = ConfigurationManager.ApplicationPaths.DefaultUserViewsPath;
|
||||
var rootFolderPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath;
|
||||
|
||||
var path = Path.Combine(rootFolderPath, name);
|
||||
|
||||
@@ -3069,7 +3040,7 @@ namespace Emby.Server.Implementations.Library
|
||||
throw new FileNotFoundException("The media folder does not exist");
|
||||
}
|
||||
|
||||
_libraryMonitorFactory().Stop();
|
||||
LibraryMonitor.Stop();
|
||||
|
||||
try
|
||||
{
|
||||
@@ -3089,7 +3060,7 @@ namespace Emby.Server.Implementations.Library
|
||||
{
|
||||
// Need to add a delay here or directory watchers may still pick up the changes
|
||||
await Task.Delay(1000).ConfigureAwait(false);
|
||||
_libraryMonitorFactory().Start();
|
||||
LibraryMonitor.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3103,7 +3074,7 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
var removeList = new List<NameValuePair>();
|
||||
|
||||
foreach (var contentType in ConfigurationManager.Configuration.ContentTypes)
|
||||
foreach (var contentType in _configurationManager.Configuration.ContentTypes)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(contentType.Name))
|
||||
{
|
||||
@@ -3118,11 +3089,11 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
if (removeList.Count > 0)
|
||||
{
|
||||
ConfigurationManager.Configuration.ContentTypes = ConfigurationManager.Configuration.ContentTypes
|
||||
_configurationManager.Configuration.ContentTypes = _configurationManager.Configuration.ContentTypes
|
||||
.Except(removeList)
|
||||
.ToArray();
|
||||
.ToArray();
|
||||
|
||||
ConfigurationManager.SaveConfiguration();
|
||||
_configurationManager.SaveConfiguration();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3133,7 +3104,7 @@ namespace Emby.Server.Implementations.Library
|
||||
throw new ArgumentNullException(nameof(mediaPath));
|
||||
}
|
||||
|
||||
var rootFolderPath = ConfigurationManager.ApplicationPaths.DefaultUserViewsPath;
|
||||
var rootFolderPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath;
|
||||
var virtualFolderPath = Path.Combine(rootFolderPath, virtualFolderName);
|
||||
|
||||
if (!Directory.Exists(virtualFolderPath))
|
||||
|
||||
@@ -33,13 +33,13 @@ namespace Emby.Server.Implementations.Library
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
private IMediaSourceProvider[] _providers;
|
||||
private readonly ILogger _logger;
|
||||
private readonly IUserDataManager _userDataManager;
|
||||
private readonly Func<IMediaEncoder> _mediaEncoder;
|
||||
private ILocalizationManager _localizationManager;
|
||||
private IApplicationPaths _appPaths;
|
||||
private readonly IMediaEncoder _mediaEncoder;
|
||||
private readonly ILocalizationManager _localizationManager;
|
||||
private readonly IApplicationPaths _appPaths;
|
||||
|
||||
private IMediaSourceProvider[] _providers;
|
||||
|
||||
public MediaSourceManager(
|
||||
IItemRepository itemRepo,
|
||||
@@ -47,16 +47,16 @@ namespace Emby.Server.Implementations.Library
|
||||
ILocalizationManager localizationManager,
|
||||
IUserManager userManager,
|
||||
ILibraryManager libraryManager,
|
||||
ILoggerFactory loggerFactory,
|
||||
ILogger<MediaSourceManager> logger,
|
||||
IJsonSerializer jsonSerializer,
|
||||
IFileSystem fileSystem,
|
||||
IUserDataManager userDataManager,
|
||||
Func<IMediaEncoder> mediaEncoder)
|
||||
IMediaEncoder mediaEncoder)
|
||||
{
|
||||
_itemRepo = itemRepo;
|
||||
_userManager = userManager;
|
||||
_libraryManager = libraryManager;
|
||||
_logger = loggerFactory.CreateLogger(nameof(MediaSourceManager));
|
||||
_logger = logger;
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_fileSystem = fileSystem;
|
||||
_userDataManager = userDataManager;
|
||||
@@ -496,7 +496,7 @@ namespace Emby.Server.Implementations.Library
|
||||
// hack - these two values were taken from LiveTVMediaSourceProvider
|
||||
string cacheKey = request.OpenToken;
|
||||
|
||||
await new LiveStreamHelper(_mediaEncoder(), _logger, _jsonSerializer, _appPaths)
|
||||
await new LiveStreamHelper(_mediaEncoder, _logger, _jsonSerializer, _appPaths)
|
||||
.AddMediaInfoWithProbe(mediaSource, isAudio, cacheKey, true, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
@@ -621,7 +621,7 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
if (liveStreamInfo is IDirectStreamProvider)
|
||||
{
|
||||
var info = await _mediaEncoder().GetMediaInfo(new MediaInfoRequest
|
||||
var info = await _mediaEncoder.GetMediaInfo(new MediaInfoRequest
|
||||
{
|
||||
MediaSource = mediaSource,
|
||||
ExtractChapters = false,
|
||||
@@ -674,7 +674,7 @@ namespace Emby.Server.Implementations.Library
|
||||
mediaSource.AnalyzeDurationMs = 3000;
|
||||
}
|
||||
|
||||
mediaInfo = await _mediaEncoder().GetMediaInfo(new MediaInfoRequest
|
||||
mediaInfo = await _mediaEncoder.GetMediaInfo(new MediaInfoRequest
|
||||
{
|
||||
MediaSource = mediaSource,
|
||||
MediaType = isAudio ? DlnaProfileType.Audio : DlnaProfileType.Video,
|
||||
|
||||
@@ -17,16 +17,15 @@ namespace Emby.Server.Implementations.Library
|
||||
{
|
||||
public class SearchEngine : ISearchEngine
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public SearchEngine(ILoggerFactory loggerFactory, ILibraryManager libraryManager, IUserManager userManager)
|
||||
public SearchEngine(ILogger<SearchEngine> logger, ILibraryManager libraryManager, IUserManager userManager)
|
||||
{
|
||||
_logger = logger;
|
||||
_libraryManager = libraryManager;
|
||||
_userManager = userManager;
|
||||
|
||||
_logger = loggerFactory.CreateLogger("SearchEngine");
|
||||
}
|
||||
|
||||
public QueryResult<SearchHintInfo> GetSearchHints(SearchQuery query)
|
||||
|
||||
@@ -28,25 +28,24 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
private readonly ILogger _logger;
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly IUserDataRepository _repository;
|
||||
|
||||
private Func<IUserManager> _userManager;
|
||||
|
||||
public UserDataManager(ILoggerFactory loggerFactory, IServerConfigurationManager config, Func<IUserManager> userManager)
|
||||
public UserDataManager(
|
||||
ILogger<UserDataManager> logger,
|
||||
IServerConfigurationManager config,
|
||||
IUserManager userManager,
|
||||
IUserDataRepository repository)
|
||||
{
|
||||
_logger = logger;
|
||||
_config = config;
|
||||
_logger = loggerFactory.CreateLogger(GetType().Name);
|
||||
_userManager = userManager;
|
||||
_repository = repository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the repository.
|
||||
/// </summary>
|
||||
/// <value>The repository.</value>
|
||||
public IUserDataRepository Repository { get; set; }
|
||||
|
||||
public void SaveUserData(Guid userId, BaseItem item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken)
|
||||
{
|
||||
var user = _userManager().GetUserById(userId);
|
||||
var user = _userManager.GetUserById(userId);
|
||||
|
||||
SaveUserData(user, item, userData, reason, cancellationToken);
|
||||
}
|
||||
@@ -71,7 +70,7 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
foreach (var key in keys)
|
||||
{
|
||||
Repository.SaveUserData(userId, key, userData, cancellationToken);
|
||||
_repository.SaveUserData(userId, key, userData, cancellationToken);
|
||||
}
|
||||
|
||||
var cacheKey = GetCacheKey(userId, item.Id);
|
||||
@@ -96,9 +95,9 @@ namespace Emby.Server.Implementations.Library
|
||||
/// <returns></returns>
|
||||
public void SaveAllUserData(Guid userId, UserItemData[] userData, CancellationToken cancellationToken)
|
||||
{
|
||||
var user = _userManager().GetUserById(userId);
|
||||
var user = _userManager.GetUserById(userId);
|
||||
|
||||
Repository.SaveAllUserData(user.InternalId, userData, cancellationToken);
|
||||
_repository.SaveAllUserData(user.InternalId, userData, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -108,14 +107,14 @@ namespace Emby.Server.Implementations.Library
|
||||
/// <returns></returns>
|
||||
public List<UserItemData> GetAllUserData(Guid userId)
|
||||
{
|
||||
var user = _userManager().GetUserById(userId);
|
||||
var user = _userManager.GetUserById(userId);
|
||||
|
||||
return Repository.GetAllUserData(user.InternalId);
|
||||
return _repository.GetAllUserData(user.InternalId);
|
||||
}
|
||||
|
||||
public UserItemData GetUserData(Guid userId, Guid itemId, List<string> keys)
|
||||
{
|
||||
var user = _userManager().GetUserById(userId);
|
||||
var user = _userManager.GetUserById(userId);
|
||||
|
||||
return GetUserData(user, itemId, keys);
|
||||
}
|
||||
@@ -131,7 +130,7 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
private UserItemData GetUserDataInternal(long internalUserId, List<string> keys)
|
||||
{
|
||||
var userData = Repository.GetUserData(internalUserId, keys);
|
||||
var userData = _repository.GetUserData(internalUserId, keys);
|
||||
|
||||
if (userData != null)
|
||||
{
|
||||
|
||||
@@ -20,6 +20,7 @@ using MediaBrowser.Controller.Drawing;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Net;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Controller.Plugins;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
@@ -44,22 +45,14 @@ namespace Emby.Server.Implementations.Library
|
||||
{
|
||||
private readonly object _policySyncLock = new object();
|
||||
private readonly object _configSyncLock = new object();
|
||||
/// <summary>
|
||||
/// The logger.
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the active user repository.
|
||||
/// </summary>
|
||||
/// <value>The user repository.</value>
|
||||
private readonly ILogger _logger;
|
||||
private readonly IUserRepository _userRepository;
|
||||
private readonly IXmlSerializer _xmlSerializer;
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly INetworkManager _networkManager;
|
||||
|
||||
private readonly Func<IImageProcessor> _imageProcessorFactory;
|
||||
private readonly Func<IDtoService> _dtoServiceFactory;
|
||||
private readonly IImageProcessor _imageProcessor;
|
||||
private readonly Lazy<IDtoService> _dtoServiceFactory;
|
||||
private readonly IServerApplicationHost _appHost;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly ICryptoProvider _cryptoProvider;
|
||||
@@ -74,13 +67,15 @@ namespace Emby.Server.Implementations.Library
|
||||
private IPasswordResetProvider[] _passwordResetProviders;
|
||||
private DefaultPasswordResetProvider _defaultPasswordResetProvider;
|
||||
|
||||
private IDtoService DtoService => _dtoServiceFactory.Value;
|
||||
|
||||
public UserManager(
|
||||
ILogger<UserManager> logger,
|
||||
IUserRepository userRepository,
|
||||
IXmlSerializer xmlSerializer,
|
||||
INetworkManager networkManager,
|
||||
Func<IImageProcessor> imageProcessorFactory,
|
||||
Func<IDtoService> dtoServiceFactory,
|
||||
IImageProcessor imageProcessor,
|
||||
Lazy<IDtoService> dtoServiceFactory,
|
||||
IServerApplicationHost appHost,
|
||||
IJsonSerializer jsonSerializer,
|
||||
IFileSystem fileSystem,
|
||||
@@ -90,7 +85,7 @@ namespace Emby.Server.Implementations.Library
|
||||
_userRepository = userRepository;
|
||||
_xmlSerializer = xmlSerializer;
|
||||
_networkManager = networkManager;
|
||||
_imageProcessorFactory = imageProcessorFactory;
|
||||
_imageProcessor = imageProcessor;
|
||||
_dtoServiceFactory = dtoServiceFactory;
|
||||
_appHost = appHost;
|
||||
_jsonSerializer = jsonSerializer;
|
||||
@@ -327,23 +322,19 @@ namespace Emby.Server.Implementations.Library
|
||||
if (user.Policy.IsDisabled)
|
||||
{
|
||||
_logger.LogInformation("Authentication request for {UserName} has been denied because this account is currently disabled (IP: {IP}).", username, remoteEndPoint);
|
||||
throw new AuthenticationException(
|
||||
string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"The {0} account is currently disabled. Please consult with your administrator.",
|
||||
user.Name));
|
||||
throw new SecurityException($"The {user.Name} account is currently disabled. Please consult with your administrator.");
|
||||
}
|
||||
|
||||
if (!user.Policy.EnableRemoteAccess && !_networkManager.IsInLocalNetwork(remoteEndPoint))
|
||||
{
|
||||
_logger.LogInformation("Authentication request for {UserName} forbidden: remote access disabled and user not in local network (IP: {IP}).", username, remoteEndPoint);
|
||||
throw new AuthenticationException("Forbidden.");
|
||||
throw new SecurityException("Forbidden.");
|
||||
}
|
||||
|
||||
if (!user.IsParentalScheduleAllowed())
|
||||
{
|
||||
_logger.LogInformation("Authentication request for {UserName} is not allowed at this time due parental restrictions (IP: {IP}).", username, remoteEndPoint);
|
||||
throw new AuthenticationException("User is not allowed access at this time.");
|
||||
throw new SecurityException("User is not allowed access at this time.");
|
||||
}
|
||||
|
||||
// Update LastActivityDate and LastLoginDate, then save
|
||||
@@ -605,7 +596,7 @@ namespace Emby.Server.Implementations.Library
|
||||
|
||||
try
|
||||
{
|
||||
_dtoServiceFactory().AttachPrimaryImageAspectRatio(dto, user);
|
||||
DtoService.AttachPrimaryImageAspectRatio(dto, user);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -630,7 +621,7 @@ namespace Emby.Server.Implementations.Library
|
||||
{
|
||||
try
|
||||
{
|
||||
return _imageProcessorFactory().GetImageCacheTag(item, image);
|
||||
return _imageProcessor.GetImageCacheTag(item, image);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -28,7 +28,6 @@ namespace Emby.Server.Implementations.LiveTv
|
||||
|
||||
private readonly ILogger _logger;
|
||||
private readonly IImageProcessor _imageProcessor;
|
||||
|
||||
private readonly IDtoService _dtoService;
|
||||
private readonly IApplicationHost _appHost;
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
|
||||
@@ -49,29 +49,24 @@ namespace Emby.Server.Implementations.LiveTv
|
||||
private readonly ILogger _logger;
|
||||
private readonly IItemRepository _itemRepo;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly IDtoService _dtoService;
|
||||
private readonly IUserDataManager _userDataManager;
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly ITaskManager _taskManager;
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly Func<IChannelManager> _channelManager;
|
||||
|
||||
private readonly IDtoService _dtoService;
|
||||
private readonly ILocalizationManager _localization;
|
||||
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly IChannelManager _channelManager;
|
||||
private readonly LiveTvDtoService _tvDtoService;
|
||||
|
||||
private ILiveTvService[] _services = Array.Empty<ILiveTvService>();
|
||||
|
||||
private ITunerHost[] _tunerHosts = Array.Empty<ITunerHost>();
|
||||
private IListingsProvider[] _listingProviders = Array.Empty<IListingsProvider>();
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
public LiveTvManager(
|
||||
IServerApplicationHost appHost,
|
||||
IServerConfigurationManager config,
|
||||
ILoggerFactory loggerFactory,
|
||||
ILogger<LiveTvManager> logger,
|
||||
IItemRepository itemRepo,
|
||||
IImageProcessor imageProcessor,
|
||||
IUserDataManager userDataManager,
|
||||
IDtoService dtoService,
|
||||
IUserManager userManager,
|
||||
@@ -80,10 +75,11 @@ namespace Emby.Server.Implementations.LiveTv
|
||||
ILocalizationManager localization,
|
||||
IJsonSerializer jsonSerializer,
|
||||
IFileSystem fileSystem,
|
||||
Func<IChannelManager> channelManager)
|
||||
IChannelManager channelManager,
|
||||
LiveTvDtoService liveTvDtoService)
|
||||
{
|
||||
_config = config;
|
||||
_logger = loggerFactory.CreateLogger(nameof(LiveTvManager));
|
||||
_logger = logger;
|
||||
_itemRepo = itemRepo;
|
||||
_userManager = userManager;
|
||||
_libraryManager = libraryManager;
|
||||
@@ -94,8 +90,7 @@ namespace Emby.Server.Implementations.LiveTv
|
||||
_dtoService = dtoService;
|
||||
_userDataManager = userDataManager;
|
||||
_channelManager = channelManager;
|
||||
|
||||
_tvDtoService = new LiveTvDtoService(dtoService, imageProcessor, loggerFactory.CreateLogger<LiveTvDtoService>(), appHost, _libraryManager);
|
||||
_tvDtoService = liveTvDtoService;
|
||||
}
|
||||
|
||||
public event EventHandler<GenericEventArgs<TimerEventInfo>> SeriesTimerCancelled;
|
||||
@@ -2496,7 +2491,7 @@ namespace Emby.Server.Implementations.LiveTv
|
||||
.OrderBy(i => i.SortName)
|
||||
.ToList();
|
||||
|
||||
folders.AddRange(_channelManager().GetChannelsInternal(new MediaBrowser.Model.Channels.ChannelQuery
|
||||
folders.AddRange(_channelManager.GetChannelsInternal(new MediaBrowser.Model.Channels.ChannelQuery
|
||||
{
|
||||
UserId = user.Id,
|
||||
IsRecordingsFolder = true,
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
"HeaderFavoriteEpisodes": "قسمتهای مورد علاقه",
|
||||
"HeaderFavoriteShows": "سریالهای مورد علاقه",
|
||||
"HeaderFavoriteSongs": "آهنگهای مورد علاقه",
|
||||
"HeaderLiveTV": "تلویزیون زنده",
|
||||
"HeaderLiveTV": "پخش زنده",
|
||||
"HeaderNextUp": "قسمت بعدی",
|
||||
"HeaderRecordingGroups": "گروههای ضبط",
|
||||
"HomeVideos": "ویدیوهای خانگی",
|
||||
|
||||
@@ -104,13 +104,14 @@
|
||||
"TasksMaintenanceCategory": "メンテナンス",
|
||||
"TaskRefreshChannelsDescription": "ネットチャンネルの情報をリフレッシュします。",
|
||||
"TaskRefreshChannels": "チャンネルのリフレッシュ",
|
||||
"TaskCleanTranscodeDescription": "一日以上前のトランスコードを消去します。",
|
||||
"TaskCleanTranscode": "トランスコード用のディレクトリの掃除",
|
||||
"TaskCleanTranscodeDescription": "1日以上経過したトランスコードファイルを削除します。",
|
||||
"TaskCleanTranscode": "トランスコードディレクトリの削除",
|
||||
"TaskUpdatePluginsDescription": "自動更新可能なプラグインのアップデートをダウンロードしてインストールします。",
|
||||
"TaskUpdatePlugins": "プラグインの更新",
|
||||
"TaskRefreshPeopleDescription": "メディアライブラリで俳優や監督のメタデータをリフレッシュします。",
|
||||
"TaskRefreshPeople": "俳優や監督のデータのリフレッシュ",
|
||||
"TaskRefreshPeopleDescription": "メディアライブラリで俳優や監督のメタデータを更新します。",
|
||||
"TaskRefreshPeople": "俳優や監督のデータの更新",
|
||||
"TaskDownloadMissingSubtitlesDescription": "メタデータ構成に基づいて、欠落している字幕をインターネットで検索します。",
|
||||
"TaskRefreshChapterImagesDescription": "チャプターのあるビデオのサムネイルを作成します。",
|
||||
"TaskRefreshChapterImages": "チャプター画像を抽出する"
|
||||
"TaskRefreshChapterImages": "チャプター画像を抽出する",
|
||||
"TaskDownloadMissingSubtitles": "不足している字幕をダウンロードする"
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"Albums": "Albums",
|
||||
"AppDeviceValues": "App: {0}, Apparaat: {1}",
|
||||
"Application": "Applicatie",
|
||||
"Application": "Programma",
|
||||
"Artists": "Artiesten",
|
||||
"AuthenticationSucceededWithUserName": "{0} succesvol geauthenticeerd",
|
||||
"AuthenticationSucceededWithUserName": "{0} is succesvol geverifieerd",
|
||||
"Books": "Boeken",
|
||||
"CameraImageUploadedFrom": "Er is een nieuwe foto toegevoegd van {0}",
|
||||
"CameraImageUploadedFrom": "Er is een nieuwe afbeelding toegevoegd via {0}",
|
||||
"Channels": "Kanalen",
|
||||
"ChapterNameValue": "Hoofdstuk {0}",
|
||||
"Collections": "Verzamelingen",
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"HeaderLiveTV": "TV em Direto",
|
||||
"HeaderNextUp": "A Seguir",
|
||||
"HeaderRecordingGroups": "Grupos de Gravação",
|
||||
"HomeVideos": "Home videos",
|
||||
"HomeVideos": "Videos caseiros",
|
||||
"Inherit": "Herdar",
|
||||
"ItemAddedWithName": "{0} foi adicionado à biblioteca",
|
||||
"ItemRemovedWithName": "{0} foi removido da biblioteca",
|
||||
@@ -92,5 +92,27 @@
|
||||
"UserStoppedPlayingItemWithValues": "{0} terminou a reprodução de {1} em {2}",
|
||||
"ValueHasBeenAddedToLibrary": "{0} foi adicionado à sua biblioteca multimédia",
|
||||
"ValueSpecialEpisodeName": "Especial - {0}",
|
||||
"VersionNumber": "Versão {0}"
|
||||
"VersionNumber": "Versão {0}",
|
||||
"TaskDownloadMissingSubtitlesDescription": "Procurar na internet por legendas em falta baseado na configuração de metadados.",
|
||||
"TaskDownloadMissingSubtitles": "Fazer download de legendas em falta",
|
||||
"TaskRefreshChannelsDescription": "Atualizar informação sobre canais da Internet.",
|
||||
"TaskRefreshChannels": "Atualizar Canais",
|
||||
"TaskCleanTranscodeDescription": "Apagar ficheiros de transcode com mais de um dia.",
|
||||
"TaskCleanTranscode": "Limpar a Diretoria de Transcode",
|
||||
"TaskUpdatePluginsDescription": "Faz o download e instala updates para os plugins que estão configurados para atualizar automaticamente.",
|
||||
"TaskUpdatePlugins": "Atualizar Plugins",
|
||||
"TaskRefreshPeopleDescription": "Atualizar metadados para atores e diretores na biblioteca.",
|
||||
"TaskRefreshPeople": "Atualizar Pessoas",
|
||||
"TaskCleanLogsDescription": "Apagar ficheiros de log que têm mais de {0} dias.",
|
||||
"TaskCleanLogs": "Limpar a Diretoria de Logs",
|
||||
"TaskRefreshLibraryDescription": "Scannear a biblioteca de música para novos ficheiros e atualizar os metadados.",
|
||||
"TaskRefreshLibrary": "Scannear Biblioteca de Música",
|
||||
"TaskRefreshChapterImagesDescription": "Criar thumbnails para os vídeos que têm capítulos.",
|
||||
"TaskRefreshChapterImages": "Extrair Imagens dos Capítulos",
|
||||
"TaskCleanCacheDescription": "Apagar ficheiros em cache que já não são necessários.",
|
||||
"TaskCleanCache": "Limpar Cache",
|
||||
"TasksChannelsCategory": "Canais da Internet",
|
||||
"TasksApplicationCategory": "Aplicação",
|
||||
"TasksLibraryCategory": "Biblioteca",
|
||||
"TasksMaintenanceCategory": "Manutenção"
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
"NotificationOptionAudioPlayback": "Ses çalma başladı",
|
||||
"NotificationOptionAudioPlaybackStopped": "Ses çalma durduruldu",
|
||||
"NotificationOptionCameraImageUploaded": "Kamera fotoğrafı yüklendi",
|
||||
"NotificationOptionInstallationFailed": "Yükleme başarısız oldu",
|
||||
"NotificationOptionInstallationFailed": "Kurulum hatası",
|
||||
"NotificationOptionNewLibraryContent": "Yeni içerik eklendi",
|
||||
"NotificationOptionPluginError": "Eklenti hatası",
|
||||
"NotificationOptionPluginInstalled": "Eklenti yüklendi",
|
||||
@@ -95,7 +95,24 @@
|
||||
"VersionNumber": "Versiyon {0}",
|
||||
"TaskCleanCache": "Geçici dosya klasörünü temizle",
|
||||
"TasksChannelsCategory": "İnternet kanalları",
|
||||
"TasksApplicationCategory": "Yazılım",
|
||||
"TasksApplicationCategory": "Uygulama",
|
||||
"TasksLibraryCategory": "Kütüphane",
|
||||
"TasksMaintenanceCategory": "Onarım"
|
||||
"TasksMaintenanceCategory": "Onarım",
|
||||
"TaskRefreshPeopleDescription": "Medya kütüphanenizdeki videoların oyuncu ve yönetmen bilgilerini günceller.",
|
||||
"TaskDownloadMissingSubtitlesDescription": "Metadata ayarlarını baz alarak eksik altyazıları internette arar.",
|
||||
"TaskDownloadMissingSubtitles": "Eksik altyazıları indir",
|
||||
"TaskRefreshChannelsDescription": "Internet kanal bilgilerini yenile.",
|
||||
"TaskRefreshChannels": "Kanalları Yenile",
|
||||
"TaskCleanTranscodeDescription": "Bir günü dolmuş dönüştürme bilgisi içeren dosyaları siler.",
|
||||
"TaskCleanTranscode": "Dönüşüm Dizinini Temizle",
|
||||
"TaskUpdatePluginsDescription": "Otomatik güncellenmeye ayarlanmış eklentilerin güncellemelerini indirir ve kurar.",
|
||||
"TaskUpdatePlugins": "Eklentileri Güncelle",
|
||||
"TaskRefreshPeople": "Kullanıcıları Yenile",
|
||||
"TaskCleanLogsDescription": "{0} günden eski log dosyalarını siler.",
|
||||
"TaskCleanLogs": "Log Dizinini Temizle",
|
||||
"TaskRefreshLibraryDescription": "Medya kütüphanenize eklenen yeni dosyaları arar ve bilgileri yeniler.",
|
||||
"TaskRefreshLibrary": "Medya Kütüphanesini Tara",
|
||||
"TaskRefreshChapterImagesDescription": "Sahnelere ayrılmış videolar için küçük resimler oluştur.",
|
||||
"TaskRefreshChapterImages": "Bölüm Resimlerini Çıkar",
|
||||
"TaskCleanCacheDescription": "Sistem tarafından artık ihtiyaç duyulmayan önbellek dosyalarını siler."
|
||||
}
|
||||
|
||||
@@ -50,10 +50,10 @@
|
||||
"NotificationOptionCameraImageUploaded": "相機相片已上傳",
|
||||
"NotificationOptionInstallationFailed": "安裝失敗",
|
||||
"NotificationOptionNewLibraryContent": "已新增新內容",
|
||||
"NotificationOptionPluginError": "擴充元件錯誤",
|
||||
"NotificationOptionPluginInstalled": "擴充元件已安裝",
|
||||
"NotificationOptionPluginUninstalled": "擴充元件已移除",
|
||||
"NotificationOptionPluginUpdateInstalled": "已更新擴充元件",
|
||||
"NotificationOptionPluginError": "插件安裝錯誤",
|
||||
"NotificationOptionPluginInstalled": "插件已安裝",
|
||||
"NotificationOptionPluginUninstalled": "插件已移除",
|
||||
"NotificationOptionPluginUpdateInstalled": "插件已更新",
|
||||
"NotificationOptionServerRestartRequired": "伺服器需要重新啟動",
|
||||
"NotificationOptionTaskFailed": "排程任務失敗",
|
||||
"NotificationOptionUserLockedOut": "使用者已鎖定",
|
||||
@@ -61,7 +61,7 @@
|
||||
"NotificationOptionVideoPlaybackStopped": "影片停止播放",
|
||||
"Photos": "相片",
|
||||
"Playlists": "播放清單",
|
||||
"Plugin": "外掛",
|
||||
"Plugin": "插件",
|
||||
"PluginInstalledWithName": "{0} 已安裝",
|
||||
"PluginUninstalledWithName": "{0} 已移除",
|
||||
"PluginUpdatedWithName": "{0} 已更新",
|
||||
@@ -91,5 +91,27 @@
|
||||
"VersionNumber": "版本 {0}",
|
||||
"HeaderRecordingGroups": "錄製組",
|
||||
"Inherit": "繼承",
|
||||
"SubtitleDownloadFailureFromForItem": "無法為 {1} 從 {0} 下載字幕"
|
||||
"SubtitleDownloadFailureFromForItem": "無法為 {1} 從 {0} 下載字幕",
|
||||
"TaskDownloadMissingSubtitlesDescription": "在網路上透過描述資料搜尋遺失的字幕。",
|
||||
"TaskDownloadMissingSubtitles": "下載遺失的字幕",
|
||||
"TaskRefreshChannels": "重新整理頻道",
|
||||
"TaskUpdatePlugins": "更新插件",
|
||||
"TaskRefreshPeople": "重新整理人員",
|
||||
"TaskCleanLogsDescription": "刪除超過{0}天的紀錄檔案。",
|
||||
"TaskCleanLogs": "清空紀錄資料夾",
|
||||
"TaskRefreshLibraryDescription": "掃描媒體庫內新的檔案並重新整理描述資料。",
|
||||
"TaskRefreshLibrary": "掃描媒體庫",
|
||||
"TaskRefreshChapterImages": "擷取章節圖片",
|
||||
"TaskCleanCacheDescription": "刪除系統長時間不需要的快取。",
|
||||
"TaskCleanCache": "清除快取資料夾",
|
||||
"TasksLibraryCategory": "媒體庫",
|
||||
"TaskRefreshChannelsDescription": "重新整理網絡頻道資料。",
|
||||
"TaskCleanTranscodeDescription": "刪除超過一天的轉碼檔案。",
|
||||
"TaskCleanTranscode": "清除轉碼資料夾",
|
||||
"TaskUpdatePluginsDescription": "下載並安裝配置為自動更新的插件的更新。",
|
||||
"TaskRefreshPeopleDescription": "更新媒體庫中演員和導演的中繼資料。",
|
||||
"TaskRefreshChapterImagesDescription": "為有章節的視頻創建縮圖。",
|
||||
"TasksChannelsCategory": "網絡頻道",
|
||||
"TasksApplicationCategory": "應用程式",
|
||||
"TasksMaintenanceCategory": "維修"
|
||||
}
|
||||
|
||||
@@ -23,9 +23,6 @@ namespace Emby.Server.Implementations.Localization
|
||||
private static readonly Assembly _assembly = typeof(LocalizationManager).Assembly;
|
||||
private static readonly string[] _unratedValues = { "n/a", "unrated", "not rated" };
|
||||
|
||||
/// <summary>
|
||||
/// The _configuration manager.
|
||||
/// </summary>
|
||||
private readonly IServerConfigurationManager _configurationManager;
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
@@ -32,22 +32,8 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
||||
private readonly ConcurrentQueue<Tuple<Type, TaskOptions>> _taskQueue =
|
||||
new ConcurrentQueue<Tuple<Type, TaskOptions>>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the json serializer.
|
||||
/// </summary>
|
||||
/// <value>The json serializer.</value>
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the application paths.
|
||||
/// </summary>
|
||||
/// <value>The application paths.</value>
|
||||
private readonly IApplicationPaths _applicationPaths;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the logger.
|
||||
/// </summary>
|
||||
/// <value>The logger.</value>
|
||||
private readonly ILogger _logger;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
@@ -56,17 +42,17 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
||||
/// </summary>
|
||||
/// <param name="applicationPaths">The application paths.</param>
|
||||
/// <param name="jsonSerializer">The json serializer.</param>
|
||||
/// <param name="loggerFactory">The logger factory.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="fileSystem">The filesystem manager.</param>
|
||||
public TaskManager(
|
||||
IApplicationPaths applicationPaths,
|
||||
IJsonSerializer jsonSerializer,
|
||||
ILoggerFactory loggerFactory,
|
||||
ILogger<TaskManager> logger,
|
||||
IFileSystem fileSystem)
|
||||
{
|
||||
_applicationPaths = applicationPaths;
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_logger = loggerFactory.CreateLogger(nameof(TaskManager));
|
||||
_logger = logger;
|
||||
_fileSystem = fileSystem;
|
||||
|
||||
ScheduledTasks = Array.Empty<IScheduledTaskWorker>();
|
||||
|
||||
@@ -15,8 +15,8 @@ namespace Emby.Server.Implementations.Security
|
||||
{
|
||||
public class AuthenticationRepository : BaseSqliteRepository, IAuthenticationRepository
|
||||
{
|
||||
public AuthenticationRepository(ILoggerFactory loggerFactory, IServerConfigurationManager config)
|
||||
: base(loggerFactory.CreateLogger(nameof(AuthenticationRepository)))
|
||||
public AuthenticationRepository(ILogger<AuthenticationRepository> logger, IServerConfigurationManager config)
|
||||
: base(logger)
|
||||
{
|
||||
DbFilePath = Path.Combine(config.ApplicationPaths.DataPath, "authentication.db");
|
||||
}
|
||||
|
||||
@@ -1414,7 +1414,7 @@ namespace Emby.Server.Implementations.Session
|
||||
if (user == null)
|
||||
{
|
||||
AuthenticationFailed?.Invoke(this, new GenericEventArgs<AuthenticationRequest>(request));
|
||||
throw new SecurityException("Invalid username or password entered.");
|
||||
throw new AuthenticationException("Invalid username or password entered.");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(request.DeviceId)
|
||||
|
||||
@@ -26,7 +26,7 @@ using Microsoft.Extensions.Logging;
|
||||
namespace Emby.Server.Implementations.Updates
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages all install, uninstall and update operations (both plugins and system).
|
||||
/// Manages all install, uninstall, and update operations for the system and individual plugins.
|
||||
/// </summary>
|
||||
public class InstallationManager : IInstallationManager
|
||||
{
|
||||
@@ -36,7 +36,7 @@ namespace Emby.Server.Implementations.Updates
|
||||
public const string PluginManifestUrlKey = "InstallationManager:PluginManifestUrl";
|
||||
|
||||
/// <summary>
|
||||
/// The _logger.
|
||||
/// The logger.
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
private readonly IApplicationPaths _appPaths;
|
||||
@@ -112,10 +112,10 @@ namespace Emby.Server.Implementations.Updates
|
||||
public event EventHandler<GenericEventArgs<IPlugin>> PluginUninstalled;
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<GenericEventArgs<(IPlugin, PackageVersionInfo)>> PluginUpdated;
|
||||
public event EventHandler<GenericEventArgs<(IPlugin, VersionInfo)>> PluginUpdated;
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<GenericEventArgs<PackageVersionInfo>> PluginInstalled;
|
||||
public event EventHandler<GenericEventArgs<VersionInfo>> PluginInstalled;
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<InstallationInfo> CompletedInstallations => _completedInstallationsInternal;
|
||||
@@ -183,61 +183,56 @@ namespace Emby.Server.Implementations.Updates
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<PackageVersionInfo> GetCompatibleVersions(
|
||||
IEnumerable<PackageVersionInfo> availableVersions,
|
||||
Version minVersion = null,
|
||||
PackageVersionClass classification = PackageVersionClass.Release)
|
||||
public IEnumerable<VersionInfo> GetCompatibleVersions(
|
||||
IEnumerable<VersionInfo> availableVersions,
|
||||
Version minVersion = null)
|
||||
{
|
||||
var appVer = _applicationHost.ApplicationVersion;
|
||||
availableVersions = availableVersions
|
||||
.Where(x => x.classification == classification
|
||||
&& Version.Parse(x.requiredVersionStr) <= appVer);
|
||||
.Where(x => Version.Parse(x.targetAbi) <= appVer);
|
||||
|
||||
if (minVersion != null)
|
||||
{
|
||||
availableVersions = availableVersions.Where(x => x.Version >= minVersion);
|
||||
availableVersions = availableVersions.Where(x => x.version >= minVersion);
|
||||
}
|
||||
|
||||
return availableVersions.OrderByDescending(x => x.Version);
|
||||
return availableVersions.OrderByDescending(x => x.version);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<PackageVersionInfo> GetCompatibleVersions(
|
||||
public IEnumerable<VersionInfo> GetCompatibleVersions(
|
||||
IEnumerable<PackageInfo> availablePackages,
|
||||
string name = null,
|
||||
Guid guid = default,
|
||||
Version minVersion = null,
|
||||
PackageVersionClass classification = PackageVersionClass.Release)
|
||||
Version minVersion = null)
|
||||
{
|
||||
var package = FilterPackages(availablePackages, name, guid).FirstOrDefault();
|
||||
|
||||
// Package not found.
|
||||
// Package not found in repository
|
||||
if (package == null)
|
||||
{
|
||||
return Enumerable.Empty<PackageVersionInfo>();
|
||||
return Enumerable.Empty<VersionInfo>();
|
||||
}
|
||||
|
||||
return GetCompatibleVersions(
|
||||
package.versions,
|
||||
minVersion,
|
||||
classification);
|
||||
minVersion);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IEnumerable<PackageVersionInfo>> GetAvailablePluginUpdates(CancellationToken cancellationToken = default)
|
||||
public async Task<IEnumerable<VersionInfo>> GetAvailablePluginUpdates(CancellationToken cancellationToken = default)
|
||||
{
|
||||
var catalog = await GetAvailablePackages(cancellationToken).ConfigureAwait(false);
|
||||
return GetAvailablePluginUpdates(catalog);
|
||||
}
|
||||
|
||||
private IEnumerable<PackageVersionInfo> GetAvailablePluginUpdates(IReadOnlyList<PackageInfo> pluginCatalog)
|
||||
private IEnumerable<VersionInfo> GetAvailablePluginUpdates(IReadOnlyList<PackageInfo> pluginCatalog)
|
||||
{
|
||||
foreach (var plugin in _applicationHost.Plugins)
|
||||
{
|
||||
var compatibleversions = GetCompatibleVersions(pluginCatalog, plugin.Name, plugin.Id, plugin.Version, _applicationHost.SystemUpdateLevel);
|
||||
var version = compatibleversions.FirstOrDefault(y => y.Version > plugin.Version);
|
||||
if (version != null
|
||||
&& !CompletedInstallations.Any(x => string.Equals(x.AssemblyGuid, version.guid, StringComparison.OrdinalIgnoreCase)))
|
||||
var compatibleversions = GetCompatibleVersions(pluginCatalog, plugin.Name, plugin.Id, plugin.Version);
|
||||
var version = compatibleversions.FirstOrDefault(y => y.version > plugin.Version);
|
||||
if (version != null && !CompletedInstallations.Any(x => string.Equals(x.Guid, version.guid, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
yield return version;
|
||||
}
|
||||
@@ -245,7 +240,7 @@ namespace Emby.Server.Implementations.Updates
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task InstallPackage(PackageVersionInfo package, CancellationToken cancellationToken)
|
||||
public async Task InstallPackage(VersionInfo package, CancellationToken cancellationToken)
|
||||
{
|
||||
if (package == null)
|
||||
{
|
||||
@@ -254,11 +249,9 @@ namespace Emby.Server.Implementations.Updates
|
||||
|
||||
var installationInfo = new InstallationInfo
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Guid = package.guid,
|
||||
Name = package.name,
|
||||
AssemblyGuid = package.guid,
|
||||
UpdateClass = package.classification,
|
||||
Version = package.versionStr
|
||||
Version = package.version.ToString()
|
||||
};
|
||||
|
||||
var innerCancellationTokenSource = new CancellationTokenSource();
|
||||
@@ -276,7 +269,7 @@ namespace Emby.Server.Implementations.Updates
|
||||
var installationEventArgs = new InstallationEventArgs
|
||||
{
|
||||
InstallationInfo = installationInfo,
|
||||
PackageVersionInfo = package
|
||||
VersionInfo = package
|
||||
};
|
||||
|
||||
PackageInstalling?.Invoke(this, installationEventArgs);
|
||||
@@ -301,7 +294,7 @@ namespace Emby.Server.Implementations.Updates
|
||||
_currentInstallations.Remove(tuple);
|
||||
}
|
||||
|
||||
_logger.LogInformation("Package installation cancelled: {0} {1}", package.name, package.versionStr);
|
||||
_logger.LogInformation("Package installation cancelled: {0} {1}", package.name, package.version);
|
||||
|
||||
PackageInstallationCancelled?.Invoke(this, installationEventArgs);
|
||||
|
||||
@@ -337,7 +330,7 @@ namespace Emby.Server.Implementations.Updates
|
||||
/// <param name="package">The package.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns><see cref="Task" />.</returns>
|
||||
private async Task InstallPackageInternal(PackageVersionInfo package, CancellationToken cancellationToken)
|
||||
private async Task InstallPackageInternal(VersionInfo package, CancellationToken cancellationToken)
|
||||
{
|
||||
// Set last update time if we were installed before
|
||||
IPlugin plugin = _applicationHost.Plugins.FirstOrDefault(p => string.Equals(p.Id.ToString(), package.guid, StringComparison.OrdinalIgnoreCase))
|
||||
@@ -349,26 +342,26 @@ namespace Emby.Server.Implementations.Updates
|
||||
// Do plugin-specific processing
|
||||
if (plugin == null)
|
||||
{
|
||||
_logger.LogInformation("New plugin installed: {0} {1} {2}", package.name, package.versionStr ?? string.Empty, package.classification);
|
||||
_logger.LogInformation("New plugin installed: {0} {1} {2}", package.name, package.version);
|
||||
|
||||
PluginInstalled?.Invoke(this, new GenericEventArgs<PackageVersionInfo>(package));
|
||||
PluginInstalled?.Invoke(this, new GenericEventArgs<VersionInfo>(package));
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogInformation("Plugin updated: {0} {1} {2}", package.name, package.versionStr ?? string.Empty, package.classification);
|
||||
_logger.LogInformation("Plugin updated: {0} {1} {2}", package.name, package.version);
|
||||
|
||||
PluginUpdated?.Invoke(this, new GenericEventArgs<(IPlugin, PackageVersionInfo)>((plugin, package)));
|
||||
PluginUpdated?.Invoke(this, new GenericEventArgs<(IPlugin, VersionInfo)>((plugin, package)));
|
||||
}
|
||||
|
||||
_applicationHost.NotifyPendingRestart();
|
||||
}
|
||||
|
||||
private async Task PerformPackageInstallation(PackageVersionInfo package, CancellationToken cancellationToken)
|
||||
private async Task PerformPackageInstallation(VersionInfo package, CancellationToken cancellationToken)
|
||||
{
|
||||
var extension = Path.GetExtension(package.targetFilename);
|
||||
var extension = Path.GetExtension(package.filename);
|
||||
if (!string.Equals(extension, ".zip", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
_logger.LogError("Only zip packages are supported. {Filename} is not a zip archive.", package.targetFilename);
|
||||
_logger.LogError("Only zip packages are supported. {Filename} is not a zip archive.", package.filename);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -415,7 +408,7 @@ namespace Emby.Server.Implementations.Updates
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uninstalls a plugin
|
||||
/// Uninstalls a plugin.
|
||||
/// </summary>
|
||||
/// <param name="plugin">The plugin.</param>
|
||||
public void UninstallPlugin(IPlugin plugin)
|
||||
@@ -473,7 +466,7 @@ namespace Emby.Server.Implementations.Updates
|
||||
{
|
||||
lock (_currentInstallationsLock)
|
||||
{
|
||||
var install = _currentInstallations.Find(x => x.info.Id == id);
|
||||
var install = _currentInstallations.Find(x => x.info.Guid == id.ToString());
|
||||
if (install == default((InstallationInfo, CancellationTokenSource)))
|
||||
{
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user