diff options
Diffstat (limited to 'MediaBrowser.Server.Implementations')
14 files changed, 202 insertions, 56 deletions
diff --git a/MediaBrowser.Server.Implementations/Drawing/ImageHeader.cs b/MediaBrowser.Server.Implementations/Drawing/ImageHeader.cs index 4da836cc6..f9cf90787 100644 --- a/MediaBrowser.Server.Implementations/Drawing/ImageHeader.cs +++ b/MediaBrowser.Server.Implementations/Drawing/ImageHeader.cs @@ -1,4 +1,6 @@ -using MediaBrowser.Model.Logging; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.IO; +using MediaBrowser.Model.Logging; using System; using System.Collections.Generic; using System.Drawing; @@ -40,9 +42,10 @@ namespace MediaBrowser.Server.Implementations.Drawing /// </summary> /// <param name="path">The path of the image to get the dimensions of.</param> /// <param name="logger">The logger.</param> + /// <param name="fileSystem">The file system.</param> /// <returns>The dimensions of the specified image.</returns> /// <exception cref="ArgumentException">The image was of an unrecognised format.</exception> - public static Size GetDimensions(string path, ILogger logger) + public static Size GetDimensions(string path, ILogger logger, IFileSystem fileSystem) { try { @@ -60,7 +63,7 @@ namespace MediaBrowser.Server.Implementations.Drawing } // Buffer to memory stream to avoid image locking file - using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) + using (var fs = fileSystem.GetFileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (var memoryStream = new MemoryStream()) { diff --git a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs index 95a644802..ace633be7 100644 --- a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs +++ b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs @@ -3,6 +3,7 @@ using MediaBrowser.Common.IO; using MediaBrowser.Controller; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.IO; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Drawing; using MediaBrowser.Model.Entities; @@ -51,16 +52,18 @@ namespace MediaBrowser.Server.Implementations.Drawing /// The _app paths /// </summary> private readonly IServerApplicationPaths _appPaths; + private readonly IFileSystem _fileSystem; private readonly string _imageSizeCachePath; private readonly string _croppedWhitespaceImageCachePath; private readonly string _enhancedImageCachePath; private readonly string _resizedImageCachePath; - public ImageProcessor(ILogger logger, IServerApplicationPaths appPaths) + public ImageProcessor(ILogger logger, IServerApplicationPaths appPaths, IFileSystem fileSystem) { _logger = logger; _appPaths = appPaths; + _fileSystem = fileSystem; _imageSizeCachePath = Path.Combine(_appPaths.ImageCachePath, "image-sizes"); _croppedWhitespaceImageCachePath = Path.Combine(_appPaths.ImageCachePath, "cropped-images"); @@ -113,7 +116,7 @@ namespace MediaBrowser.Server.Implementations.Drawing try { - using (var fileStream = new FileStream(cacheFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous)) + using (var fileStream = _fileSystem.GetFileStream(cacheFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, true)) { await fileStream.CopyToAsync(toStream).ConfigureAwait(false); return; @@ -131,7 +134,7 @@ namespace MediaBrowser.Server.Implementations.Drawing // Check again in case of lock contention try { - using (var fileStream = new FileStream(cacheFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous)) + using (var fileStream = _fileSystem.GetFileStream(cacheFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, true)) { await fileStream.CopyToAsync(toStream).ConfigureAwait(false); semaphore.Release(); @@ -150,7 +153,7 @@ namespace MediaBrowser.Server.Implementations.Drawing try { - using (var fileStream = new FileStream(originalImagePath, FileMode.Open, FileAccess.Read, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, true)) + using (var fileStream = _fileSystem.GetFileStream(originalImagePath, FileMode.Open, FileAccess.Read, FileShare.Read, true)) { // Copy to memory stream to avoid Image locking file using (var memoryStream = new MemoryStream()) @@ -228,7 +231,7 @@ namespace MediaBrowser.Server.Implementations.Drawing Directory.CreateDirectory(parentPath); // Save to the cache location - using (var cacheFileStream = new FileStream(cacheFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous)) + using (var cacheFileStream = _fileSystem.GetFileStream(cacheFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, true)) { // Save to the filestream await cacheFileStream.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false); @@ -359,7 +362,7 @@ namespace MediaBrowser.Server.Implementations.Drawing try { - using (var fileStream = new FileStream(originalImagePath, FileMode.Open, FileAccess.Read, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, true)) + using (var fileStream = _fileSystem.GetFileStream(originalImagePath, FileMode.Open, FileAccess.Read, FileShare.Read, true)) { // Copy to memory stream to avoid Image locking file using (var memoryStream = new MemoryStream()) @@ -376,7 +379,7 @@ namespace MediaBrowser.Server.Implementations.Drawing Directory.CreateDirectory(parentPath); - using (var outputStream = new FileStream(croppedImagePath, FileMode.Create, FileAccess.Write, FileShare.Read)) + using (var outputStream = _fileSystem.GetFileStream(croppedImagePath, FileMode.Create, FileAccess.Write, FileShare.Read, false)) { croppedImage.Save(outputFormat, outputStream, 100); } @@ -525,7 +528,7 @@ namespace MediaBrowser.Server.Implementations.Drawing // Cache file doesn't exist no biggie } - var size = ImageHeader.GetDimensions(path, _logger); + var size = ImageHeader.GetDimensions(path, _logger, _fileSystem); var parentPath = Path.GetDirectoryName(fullCachePath); @@ -685,7 +688,7 @@ namespace MediaBrowser.Server.Implementations.Drawing try { - using (var fileStream = new FileStream(originalImagePath, FileMode.Open, FileAccess.Read, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, true)) + using (var fileStream = _fileSystem.GetFileStream(originalImagePath, FileMode.Open, FileAccess.Read, FileShare.Read, true)) { // Copy to memory stream to avoid Image locking file using (var memoryStream = new MemoryStream()) @@ -702,7 +705,7 @@ namespace MediaBrowser.Server.Implementations.Drawing Directory.CreateDirectory(parentDirectory); //And then save it in the cache - using (var outputStream = new FileStream(enhancedImagePath, FileMode.Create, FileAccess.Write, FileShare.Read)) + using (var outputStream = _fileSystem.GetFileStream(enhancedImagePath, FileMode.Create, FileAccess.Write, FileShare.Read, false)) { newImage.Save(ImageFormat.Png, outputStream, 100); } diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 65a161821..19e19f8ea 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -373,6 +373,11 @@ namespace MediaBrowser.Server.Implementations.Dto dto.GameSystem = item.GameSystem; } + private void SetGameSystemProperties(BaseItemDto dto, GameSystem item) + { + dto.GameSystem = item.GameSystemName; + } + /// <summary> /// Gets the backdrop image tags. /// </summary> @@ -1064,6 +1069,13 @@ namespace MediaBrowser.Server.Implementations.Dto SetGameProperties(dto, game); } + var gameSystem = item as GameSystem; + + if (gameSystem != null) + { + SetGameSystemProperties(dto, gameSystem); + } + var musicVideo = item as MusicVideo; if (musicVideo != null) diff --git a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/RemoteNotifications.cs b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/RemoteNotifications.cs index cb6097504..723e4fdd3 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/RemoteNotifications.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/RemoteNotifications.cs @@ -1,5 +1,7 @@ using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; +using MediaBrowser.Controller.IO; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Notifications; using MediaBrowser.Controller.Plugins; @@ -26,11 +28,12 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications private readonly IJsonSerializer _json; private readonly INotificationsRepository _notificationsRepo; private readonly IUserManager _userManager; + private readonly IFileSystem _fileSystem; private readonly TimeSpan _frequency = TimeSpan.FromHours(6); private readonly TimeSpan _maxAge = TimeSpan.FromDays(31); - public RemoteNotifications(IApplicationPaths appPaths, ILogger logger, IHttpClient httpClient, IJsonSerializer json, INotificationsRepository notificationsRepo, IUserManager userManager) + public RemoteNotifications(IApplicationPaths appPaths, ILogger logger, IHttpClient httpClient, IJsonSerializer json, INotificationsRepository notificationsRepo, IUserManager userManager, IFileSystem fileSystem) { _appPaths = appPaths; _logger = logger; @@ -38,6 +41,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications _json = json; _notificationsRepo = notificationsRepo; _userManager = userManager; + _fileSystem = fileSystem; } /// <summary> @@ -56,7 +60,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications { var dataPath = Path.Combine(_appPaths.DataPath, "remotenotifications.json"); - var lastRunTime = File.Exists(dataPath) ? File.GetLastWriteTimeUtc(dataPath) : DateTime.MinValue; + var lastRunTime = File.Exists(dataPath) ? _fileSystem.GetLastWriteTimeUtc(dataPath) : DateTime.MinValue; try { diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs index 356c6fc4d..e6942fae6 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs @@ -1,6 +1,7 @@ using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; +using MediaBrowser.Controller.IO; using MediaBrowser.Model.Logging; using ServiceStack.Common; using ServiceStack.Common.Web; @@ -25,13 +26,15 @@ namespace MediaBrowser.Server.Implementations.HttpServer /// The _logger /// </summary> private readonly ILogger _logger; + private readonly IFileSystem _fileSystem; /// <summary> /// Initializes a new instance of the <see cref="HttpResultFactory"/> class. /// </summary> /// <param name="logManager">The log manager.</param> - public HttpResultFactory(ILogManager logManager) + public HttpResultFactory(ILogManager logManager, IFileSystem fileSystem) { + _fileSystem = fileSystem; _logger = logManager.GetLogger("HttpResultFactory"); } @@ -288,7 +291,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer throw new ArgumentException("FileShare must be either Read or ReadWrite"); } - var dateModified = File.GetLastWriteTimeUtc(path); + var dateModified = _fileSystem.GetLastWriteTimeUtc(path); var cacheKey = path + dateModified.Ticks; @@ -303,7 +306,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer /// <returns>Stream.</returns> private Stream GetFileStream(string path, FileShare fileShare) { - return new FileStream(path, FileMode.Open, FileAccess.Read, fileShare, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous); + return _fileSystem.GetFileStream(path, FileMode.Open, FileAccess.Read, fileShare, true); } /// <summary> diff --git a/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs b/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs index a4d99ae17..330469877 100644 --- a/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs +++ b/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.ScheduledTasks; +using MediaBrowser.Common.IO; +using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.IO; @@ -87,10 +88,12 @@ namespace MediaBrowser.Server.Implementations.IO private ILibraryManager LibraryManager { get; set; } private IServerConfigurationManager ConfigurationManager { get; set; } + private readonly IFileSystem _fileSystem; + /// <summary> /// Initializes a new instance of the <see cref="DirectoryWatchers" /> class. /// </summary> - public DirectoryWatchers(ILogManager logManager, ITaskManager taskManager, ILibraryManager libraryManager, IServerConfigurationManager configurationManager) + public DirectoryWatchers(ILogManager logManager, ITaskManager taskManager, ILibraryManager libraryManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem) { if (taskManager == null) { @@ -101,6 +104,7 @@ namespace MediaBrowser.Server.Implementations.IO TaskManager = taskManager; Logger = logManager.GetLogger("DirectoryWatchers"); ConfigurationManager = configurationManager; + _fileSystem = fileSystem; SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; } @@ -319,6 +323,18 @@ namespace MediaBrowser.Server.Implementations.IO /// <param name="e">The <see cref="FileSystemEventArgs" /> instance containing the event data.</param> void watcher_Changed(object sender, FileSystemEventArgs e) { + try + { + OnWatcherChanged(e); + } + catch (IOException ex) + { + Logger.ErrorException("IOException in watcher changed", ex); + } + } + + private void OnWatcherChanged(FileSystemEventArgs e) + { var name = e.Name; // Ignore certain files @@ -418,7 +434,7 @@ namespace MediaBrowser.Server.Implementations.IO { try { - var data = FileSystem.GetFileSystemInfo(path); + var data = _fileSystem.GetFileSystemInfo(path); if (!data.Exists || data.Attributes.HasFlag(FileAttributes.Directory) @@ -434,7 +450,7 @@ namespace MediaBrowser.Server.Implementations.IO try { - using (new FileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)) + using (_fileSystem.GetFileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)) { //file is not locked return false; diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index cbe15aa62..1aa9e5b9c 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1,4 +1,5 @@ using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.IO; using MediaBrowser.Common.Progress; using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Configuration; @@ -169,6 +170,8 @@ namespace MediaBrowser.Server.Implementations.Library private readonly ConcurrentDictionary<string, UserRootFolder> _userRootFolders = new ConcurrentDictionary<string, UserRootFolder>(); + private readonly IFileSystem _fileSystem; + /// <summary> /// Initializes a new instance of the <see cref="LibraryManager" /> class. /// </summary> @@ -177,7 +180,7 @@ namespace MediaBrowser.Server.Implementations.Library /// <param name="userManager">The user manager.</param> /// <param name="configurationManager">The configuration manager.</param> /// <param name="userDataRepository">The user data repository.</param> - public LibraryManager(ILogger logger, ITaskManager taskManager, IUserManager userManager, IServerConfigurationManager configurationManager, IUserDataManager userDataRepository, Func<IDirectoryWatchers> directoryWatchersFactory) + public LibraryManager(ILogger logger, ITaskManager taskManager, IUserManager userManager, IServerConfigurationManager configurationManager, IUserDataManager userDataRepository, Func<IDirectoryWatchers> directoryWatchersFactory, IFileSystem fileSystem) { _logger = logger; _taskManager = taskManager; @@ -185,6 +188,7 @@ namespace MediaBrowser.Server.Implementations.Library ConfigurationManager = configurationManager; _userDataRepository = userDataRepository; _directoryWatchersFactory = directoryWatchersFactory; + _fileSystem = fileSystem; ByReferenceItems = new ConcurrentDictionary<Guid, BaseItem>(); ConfigurationManager.ConfigurationUpdated += ConfigurationUpdated; @@ -417,7 +421,7 @@ namespace MediaBrowser.Server.Implementations.Library if (item != null) { - ResolverHelper.SetInitialItemValues(item, args); + ResolverHelper.SetInitialItemValues(item, args, _fileSystem); // Now handle the issue with posibly having the same item referenced from multiple physical // places within the library. Be sure we always end up with just one instance. @@ -482,7 +486,7 @@ namespace MediaBrowser.Server.Implementations.Library // When resolving the root, we need it's grandchildren (children of user views) var flattenFolderDepth = isPhysicalRoot ? 2 : 0; - args.FileSystemDictionary = FileData.GetFilteredFileSystemEntries(args.Path, _logger, args, flattenFolderDepth: flattenFolderDepth, resolveShortcuts: isPhysicalRoot || args.IsVf); + args.FileSystemDictionary = FileData.GetFilteredFileSystemEntries(args.Path, _fileSystem, _logger, args, flattenFolderDepth: flattenFolderDepth, resolveShortcuts: isPhysicalRoot || args.IsVf); // Need to remove subpaths that may have been resolved from shortcuts // Example: if \\server\movies exists, then strip out \\server\movies\action @@ -701,7 +705,7 @@ namespace MediaBrowser.Server.Implementations.Library throw new ArgumentNullException(); } - var validFilename = FileSystem.GetValidFilename(name).Trim(); + var validFilename = _fileSystem.GetValidFilename(name).Trim(); string subFolderPrefix = null; @@ -768,8 +772,8 @@ namespace MediaBrowser.Server.Implementations.Library { Name = name, Id = id, - DateCreated = fileInfo.CreationTimeUtc, - DateModified = fileInfo.LastWriteTimeUtc, + DateCreated = _fileSystem.GetCreationTimeUtc(fileInfo), + DateModified = _fileSystem.GetLastWriteTimeUtc(fileInfo), Path = path }; isNew = true; @@ -1066,7 +1070,7 @@ namespace MediaBrowser.Server.Implementations.Library Name = Path.GetFileName(dir), Locations = Directory.EnumerateFiles(dir, "*.mblink", SearchOption.TopDirectoryOnly) - .Select(FileSystem.ResolveShortcut) + .Select(_fileSystem.ResolveShortcut) .OrderBy(i => i) .ToList(), @@ -1150,7 +1154,7 @@ namespace MediaBrowser.Server.Implementations.Library try { // Try to resolve the path into a video - video = ResolvePath(FileSystem.GetFileSystemInfo(info.Path)) as Video; + video = ResolvePath(_fileSystem.GetFileSystemInfo(info.Path)) as Video; if (video == null) { diff --git a/MediaBrowser.Server.Implementations/Library/ResolverHelper.cs b/MediaBrowser.Server.Implementations/Library/ResolverHelper.cs index a6b13f8dd..96057f8b7 100644 --- a/MediaBrowser.Server.Implementations/Library/ResolverHelper.cs +++ b/MediaBrowser.Server.Implementations/Library/ResolverHelper.cs @@ -1,5 +1,7 @@ using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.IO; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.IO; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Resolvers; using System; @@ -18,7 +20,8 @@ namespace MediaBrowser.Server.Implementations.Library /// </summary> /// <param name="item">The item.</param> /// <param name="args">The args.</param> - public static void SetInitialItemValues(BaseItem item, ItemResolveArgs args) + /// <param name="fileSystem">The file system.</param> + public static void SetInitialItemValues(BaseItem item, ItemResolveArgs args, IFileSystem fileSystem) { item.ResetResolveArgs(args); @@ -48,7 +51,7 @@ namespace MediaBrowser.Server.Implementations.Library item.DontFetchMeta = item.Path.IndexOf("[dontfetchmeta]", StringComparison.OrdinalIgnoreCase) != -1; // Make sure DateCreated and DateModified have values - EntityResolutionHelper.EnsureDates(item, args, true); + EntityResolutionHelper.EnsureDates(fileSystem, item, args, true); } /// <summary> diff --git a/MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs b/MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs index c9777e54a..0d428742c 100644 --- a/MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs +++ b/MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs @@ -1,4 +1,6 @@ -using MediaBrowser.Controller.Configuration; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.IO; using MediaBrowser.Controller.Localization; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Globalization; @@ -30,13 +32,16 @@ namespace MediaBrowser.Server.Implementations.Localization private readonly ConcurrentDictionary<string, Dictionary<string, ParentalRating>> _allParentalRatings = new ConcurrentDictionary<string, Dictionary<string, ParentalRating>>(StringComparer.OrdinalIgnoreCase); + private readonly IFileSystem _fileSystem; + /// <summary> /// Initializes a new instance of the <see cref="LocalizationManager"/> class. /// </summary> /// <param name="configurationManager">The configuration manager.</param> - public LocalizationManager(IServerConfigurationManager configurationManager) + public LocalizationManager(IServerConfigurationManager configurationManager, IFileSystem fileSystem) { _configurationManager = configurationManager; + _fileSystem = fileSystem; ExtractAll(); } @@ -65,7 +70,7 @@ namespace MediaBrowser.Server.Implementations.Localization { using (var stream = type.Assembly.GetManifestResourceStream(resource)) { - using (var fs = new FileStream(Path.Combine(localizationPath, filename), FileMode.Create, FileAccess.Write, FileShare.Read)) + using (var fs = _fileSystem.GetFileStream(Path.Combine(localizationPath, filename), FileMode.Create, FileAccess.Write, FileShare.Read)) { stream.CopyTo(fs); } diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 05c5f5a82..017dc2b54 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -46,6 +46,14 @@ </Reference> <Reference Include="System" /> <Reference Include="System.Core" /> + <Reference Include="System.Data.SQLite, Version=1.0.89.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\packages\System.Data.SQLite.x86.1.0.89.0\lib\net45\System.Data.SQLite.dll</HintPath> + </Reference> + <Reference Include="System.Data.SQLite.Linq, Version=1.0.89.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\packages\System.Data.SQLite.x86.1.0.89.0\lib\net45\System.Data.SQLite.Linq.dll</HintPath> + </Reference> <Reference Include="System.Drawing" /> <Reference Include="System.Reactive.Core"> <HintPath>..\packages\Rx-Core.2.1.30214.0\lib\Net45\System.Reactive.Core.dll</HintPath> @@ -88,12 +96,6 @@ <Reference Include="ServiceStack.Text"> <HintPath>..\packages\ServiceStack.Text.3.9.62\lib\net35\ServiceStack.Text.dll</HintPath> </Reference> - <Reference Include="System.Data.SQLite"> - <HintPath>..\packages\System.Data.SQLite.x86.1.0.88.0\lib\net45\System.Data.SQLite.dll</HintPath> - </Reference> - <Reference Include="System.Data.SQLite.Linq"> - <HintPath>..\packages\System.Data.SQLite.x86.1.0.88.0\lib\net45\System.Data.SQLite.Linq.dll</HintPath> - </Reference> <Reference Include="Mono.Data.Sqlite"> <HintPath>..\packages\ServiceStack.OrmLite.Sqlite.Mono.3.9.64\lib\net35\Mono.Data.Sqlite.dll</HintPath> </Reference> diff --git a/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs b/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs index 6f4d01e3e..a29a3d069 100644 --- a/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs +++ b/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs @@ -1,6 +1,7 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Common.IO; using MediaBrowser.Common.MediaInfo; +using MediaBrowser.Controller.IO; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; @@ -53,6 +54,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder /// The FF probe resource pool /// </summary> private readonly SemaphoreSlim _ffProbeResourcePool = new SemaphoreSlim(1, 1); + private readonly IFileSystem _fileSystem; public string FFMpegPath { get; private set; } @@ -61,12 +63,13 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder public string Version { get; private set; } public MediaEncoder(ILogger logger, IApplicationPaths appPaths, - IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, string version) + IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, string version, IFileSystem fileSystem) { _logger = logger; _appPaths = appPaths; _jsonSerializer = jsonSerializer; Version = version; + _fileSystem = fileSystem; FFProbePath = ffProbePath; FFMpegPath = ffMpegPath; } @@ -458,8 +461,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder var logFilePath = Path.Combine(_appPaths.LogDirectoryPath, "ffmpeg-sub-convert-" + Guid.NewGuid() + ".txt"); - var logFileStream = new FileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, - StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous); + var logFileStream = _fileSystem.GetFileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, true); try { @@ -687,7 +689,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder var logFilePath = Path.Combine(_appPaths.LogDirectoryPath, "ffmpeg-sub-extract-" + Guid.NewGuid() + ".txt"); - var logFileStream = new FileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous); + var logFileStream = _fileSystem.GetFileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, true); try { diff --git a/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs b/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs index 3bdef9226..7b5c0df34 100644 --- a/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs +++ b/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs @@ -35,16 +35,18 @@ namespace MediaBrowser.Server.Implementations.Providers /// The _directory watchers /// </summary> private readonly IDirectoryWatchers _directoryWatchers; + private readonly IFileSystem _fileSystem; /// <summary> /// Initializes a new instance of the <see cref="ImageSaver"/> class. /// </summary> /// <param name="config">The config.</param> /// <param name="directoryWatchers">The directory watchers.</param> - public ImageSaver(IServerConfigurationManager config, IDirectoryWatchers directoryWatchers) + public ImageSaver(IServerConfigurationManager config, IDirectoryWatchers directoryWatchers, IFileSystem fileSystem) { _config = config; _directoryWatchers = directoryWatchers; + _fileSystem = fileSystem; _remoteImageCache = new FileSystemRepository(config.ApplicationPaths.DownloadedImagesDataPath); } @@ -67,11 +69,11 @@ namespace MediaBrowser.Server.Implementations.Providers throw new ArgumentNullException("mimeType"); } - var saveLocally = _config.Configuration.SaveLocalMeta || item is IItemByName || item is User; + var saveLocally = _config.Configuration.SaveLocalMeta && item.Parent != null && !(item is Audio); - if (item is Audio || item.Parent == null) + if (item is IItemByName || item is User) { - saveLocally = false; + saveLocally = true; } if (type != ImageType.Primary && item is Episode) @@ -176,7 +178,7 @@ namespace MediaBrowser.Server.Implementations.Providers } } - using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous)) + using (var fs = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true)) { await source.CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, cancellationToken).ConfigureAwait(false); } diff --git a/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs b/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs index 19230cecd..0252373f0 100644 --- a/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs +++ b/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs @@ -7,6 +7,7 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Providers; using System; using System.Collections.Generic; using System.IO; @@ -48,6 +49,9 @@ namespace MediaBrowser.Server.Implementations.Providers /// <value>The metadata providers enumerable.</value> private BaseMetadataProvider[] MetadataProviders { get; set; } + private IImageProvider[] ImageProviders { get; set; } + private readonly IFileSystem _fileSystem; + /// <summary> /// Initializes a new instance of the <see cref="ProviderManager" /> class. /// </summary> @@ -55,22 +59,25 @@ namespace MediaBrowser.Server.Implementations.Providers /// <param name="configurationManager">The configuration manager.</param> /// <param name="directoryWatchers">The directory watchers.</param> /// <param name="logManager">The log manager.</param> - /// <param name="libraryManager">The library manager.</param> - public ProviderManager(IHttpClient httpClient, IServerConfigurationManager configurationManager, IDirectoryWatchers directoryWatchers, ILogManager logManager, ILibraryManager libraryManager) + public ProviderManager(IHttpClient httpClient, IServerConfigurationManager configurationManager, IDirectoryWatchers directoryWatchers, ILogManager logManager, IFileSystem fileSystem) { _logger = logManager.GetLogger("ProviderManager"); _httpClient = httpClient; ConfigurationManager = configurationManager; _directoryWatchers = directoryWatchers; + _fileSystem = fileSystem; } /// <summary> /// Adds the metadata providers. /// </summary> /// <param name="providers">The providers.</param> - public void AddParts(IEnumerable<BaseMetadataProvider> providers) + /// <param name="imageProviders">The image providers.</param> + public void AddParts(IEnumerable<BaseMetadataProvider> providers, IEnumerable<IImageProvider> imageProviders) { MetadataProviders = providers.OrderBy(e => e.Priority).ToArray(); + + ImageProviders = imageProviders.OrderByDescending(i => i.Priority).ToArray(); } /// <summary> @@ -288,7 +295,7 @@ namespace MediaBrowser.Server.Implementations.Providers { using (dataToSave) { - using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous)) + using (var fs = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true)) { await dataToSave.CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, cancellationToken).ConfigureAwait(false); } @@ -342,7 +349,87 @@ namespace MediaBrowser.Server.Implementations.Providers /// <returns>Task.</returns> public Task SaveImage(BaseItem item, Stream source, string mimeType, ImageType type, int? imageIndex, string sourceUrl, CancellationToken cancellationToken) { - return new ImageSaver(ConfigurationManager, _directoryWatchers).SaveImage(item, source, mimeType, type, imageIndex, sourceUrl, cancellationToken); + return new ImageSaver(ConfigurationManager, _directoryWatchers, _fileSystem).SaveImage(item, source, mimeType, type, imageIndex, sourceUrl, cancellationToken); + } + + /// <summary> + /// Gets the available remote images. + /// </summary> + /// <param name="item">The item.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <param name="providerName">Name of the provider.</param> + /// <param name="type">The type.</param> + /// <returns>Task{IEnumerable{RemoteImageInfo}}.</returns> + public async Task<IEnumerable<RemoteImageInfo>> GetAvailableRemoteImages(BaseItem item, CancellationToken cancellationToken, string providerName = null, ImageType? type = null) + { + var providers = GetImageProviders(item); + + if (!string.IsNullOrEmpty(providerName)) + { + providers = providers.Where(i => string.Equals(i.Name, providerName, StringComparison.OrdinalIgnoreCase)); + } + + var preferredLanguage = ConfigurationManager.Configuration.PreferredMetadataLanguage; + + var tasks = providers.Select(i => Task.Run(async () => + { + try + { + if (type.HasValue) + { + var result = await i.GetImages(item, type.Value, cancellationToken).ConfigureAwait(false); + + return FilterImages(result, preferredLanguage); + } + else + { + var result = await i.GetAllImages(item, cancellationToken).ConfigureAwait(false); + return FilterImages(result, preferredLanguage); + } + } + catch (Exception ex) + { + _logger.ErrorException("{0} failed in GetImages for type {1}", ex, i.GetType().Name, item.GetType().Name); + return new List<RemoteImageInfo>(); + } + + }, cancellationToken)); + + var results = await Task.WhenAll(tasks).ConfigureAwait(false); + + return results.SelectMany(i => i); + } + + private IEnumerable<RemoteImageInfo> FilterImages(IEnumerable<RemoteImageInfo> images, string preferredLanguage) + { + if (string.Equals(preferredLanguage, "en", StringComparison.OrdinalIgnoreCase)) + { + images = images.Where(i => string.IsNullOrEmpty(i.Language) || + string.Equals(i.Language, "en", StringComparison.OrdinalIgnoreCase)); + } + + return images; + } + + /// <summary> + /// Gets the supported image providers. + /// </summary> + /// <param name="item">The item.</param> + /// <returns>IEnumerable{IImageProvider}.</returns> + public IEnumerable<IImageProvider> GetImageProviders(BaseItem item) + { + return ImageProviders.Where(i => + { + try + { + return i.Supports(item); + } + catch (Exception ex) + { + _logger.ErrorException("{0} failed in Supports for type {1}", ex, i.GetType().Name, item.GetType().Name); + return false; + } + }); } } } diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index 771a5c8b2..eeeedfe36 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -14,5 +14,5 @@ <package id="ServiceStack.OrmLite.SqlServer" version="3.9.43" targetFramework="net45" />
<package id="ServiceStack.Redis" version="3.9.43" targetFramework="net45" />
<package id="ServiceStack.Text" version="3.9.62" targetFramework="net45" />
- <package id="System.Data.SQLite.x86" version="1.0.88.0" targetFramework="net45" />
+ <package id="System.Data.SQLite.x86" version="1.0.89.0" targetFramework="net45" />
</packages>
\ No newline at end of file |
