mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-04-20 00:55:13 +01:00
Merge branch 'master' of https://github.com/MediaBrowser/MediaBrowser
This commit is contained in:
@@ -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())
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -318,6 +322,18 @@ namespace MediaBrowser.Server.Implementations.IO
|
||||
/// <param name="sender">The source of the event.</param>
|
||||
/// <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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -52,7 +52,8 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
|
||||
|
||||
// If there's a collection type and it's not tv, it can't be a series
|
||||
if (!string.IsNullOrEmpty(collectionType) &&
|
||||
!string.Equals(collectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase))
|
||||
!string.Equals(collectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase) &&
|
||||
!string.Equals(collectionType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
{
|
||||
@@ -685,7 +687,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
|
||||
{
|
||||
|
||||
@@ -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,30 +69,20 @@ namespace MediaBrowser.Server.Implementations.Providers
|
||||
throw new ArgumentNullException("mimeType");
|
||||
}
|
||||
|
||||
var saveLocally = _config.Configuration.SaveLocalMeta;
|
||||
var saveLocally = _config.Configuration.SaveLocalMeta || item is IItemByName || item is User;
|
||||
|
||||
if (item is IItemByName)
|
||||
{
|
||||
saveLocally = true;
|
||||
}
|
||||
else if (item is User)
|
||||
{
|
||||
saveLocally = true;
|
||||
}
|
||||
else if (item is Audio || item.Parent == null || string.IsNullOrEmpty(item.MetaLocation))
|
||||
if (item is Audio || item.Parent == null)
|
||||
{
|
||||
saveLocally = false;
|
||||
}
|
||||
|
||||
if (type != ImageType.Primary)
|
||||
if (type != ImageType.Primary && item is Episode)
|
||||
{
|
||||
if (item is Episode)
|
||||
{
|
||||
saveLocally = false;
|
||||
}
|
||||
saveLocally = false;
|
||||
}
|
||||
|
||||
if (item.LocationType == LocationType.Remote || item.LocationType == LocationType.Virtual)
|
||||
var locationType = item.LocationType;
|
||||
if (locationType == LocationType.Remote || locationType == LocationType.Virtual)
|
||||
{
|
||||
saveLocally = false;
|
||||
}
|
||||
@@ -186,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);
|
||||
}
|
||||
@@ -373,7 +365,7 @@ namespace MediaBrowser.Server.Implementations.Providers
|
||||
path = GetSavePathForItemInMixedFolder(item, type, filename, extension);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(path) && !string.IsNullOrEmpty(item.MetaLocation))
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
path = Path.Combine(item.MetaLocation, filename + extension);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Providers;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Providers
|
||||
{
|
||||
@@ -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.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,60 @@ 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="type">The type.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{IEnumerable{RemoteImageInfo}}.</returns>
|
||||
public async Task<IEnumerable<RemoteImageInfo>> GetAvailableRemoteImages(BaseItem item, ImageType type, CancellationToken cancellationToken)
|
||||
{
|
||||
var providers = GetSupportedImageProviders(item, type);
|
||||
|
||||
var tasks = providers.Select(i => Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await i.GetAvailableImages(item, type, cancellationToken).ConfigureAwait(false);
|
||||
return result.ToList();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("{0} failed in GetAvailableImages for type {1}", ex, i.GetType().Name, item.GetType().Name);
|
||||
return new List<RemoteImageInfo>();
|
||||
}
|
||||
}));
|
||||
|
||||
var results = await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
|
||||
return results.SelectMany(i => i);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the supported image providers.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <returns>IEnumerable{IImageProvider}.</returns>
|
||||
private IEnumerable<IImageProvider> GetSupportedImageProviders(BaseItem item, ImageType type)
|
||||
{
|
||||
return ImageProviders.Where(i =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return i.Supports(item, type);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("{0} failed in Supports for type {1}", ex, i.GetType().Name, item.GetType().Name);
|
||||
return false;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user