Merge branch 'master' of https://github.com/MediaBrowser/MediaBrowser
This commit is contained in:
commit
e8f8d6651c
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using System;
|
||||
|
@ -12,20 +13,27 @@ namespace MediaBrowser.Api.Library
|
|||
/// </summary>
|
||||
public static class LibraryHelpers
|
||||
{
|
||||
/// <summary>
|
||||
/// The shortcut file extension
|
||||
/// </summary>
|
||||
private const string ShortcutFileExtension = ".mblink";
|
||||
/// <summary>
|
||||
/// The shortcut file search
|
||||
/// </summary>
|
||||
private const string ShortcutFileSearch = "*" + ShortcutFileExtension;
|
||||
|
||||
/// <summary>
|
||||
/// Adds the virtual folder.
|
||||
/// </summary>
|
||||
/// <param name="fileSystem">The file system.</param>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="collectionType">Type of the collection.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="appPaths">The app paths.</param>
|
||||
/// <exception cref="System.ArgumentException">There is already a media collection with the name + name + .</exception>
|
||||
public static void AddVirtualFolder(string name, string collectionType, User user, IServerApplicationPaths appPaths)
|
||||
public static void AddVirtualFolder(IFileSystem fileSystem, string name, string collectionType, User user, IServerApplicationPaths appPaths)
|
||||
{
|
||||
name = FileSystem.GetValidFilename(name);
|
||||
name = fileSystem.GetValidFilename(name);
|
||||
|
||||
var rootFolderPath = user != null ? user.RootFolderPath : appPaths.DefaultUserViewsPath;
|
||||
var virtualFolderPath = Path.Combine(rootFolderPath, name);
|
||||
|
@ -106,12 +114,13 @@ namespace MediaBrowser.Api.Library
|
|||
/// <summary>
|
||||
/// Deletes a shortcut from within a virtual folder, within either the default view or a user view
|
||||
/// </summary>
|
||||
/// <param name="fileSystem">The file system.</param>
|
||||
/// <param name="virtualFolderName">Name of the virtual folder.</param>
|
||||
/// <param name="mediaPath">The media path.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="appPaths">The app paths.</param>
|
||||
/// <exception cref="System.IO.DirectoryNotFoundException">The media folder does not exist</exception>
|
||||
public static void RemoveMediaPath(string virtualFolderName, string mediaPath, User user, IServerApplicationPaths appPaths)
|
||||
public static void RemoveMediaPath(IFileSystem fileSystem, string virtualFolderName, string mediaPath, User user, IServerApplicationPaths appPaths)
|
||||
{
|
||||
var rootFolderPath = user != null ? user.RootFolderPath : appPaths.DefaultUserViewsPath;
|
||||
var path = Path.Combine(rootFolderPath, virtualFolderName);
|
||||
|
@ -121,7 +130,7 @@ namespace MediaBrowser.Api.Library
|
|||
throw new DirectoryNotFoundException(string.Format("The media collection {0} does not exist", virtualFolderName));
|
||||
}
|
||||
|
||||
var shortcut = Directory.EnumerateFiles(path, ShortcutFileSearch, SearchOption.AllDirectories).FirstOrDefault(f => FileSystem.ResolveShortcut(f).Equals(mediaPath, StringComparison.OrdinalIgnoreCase));
|
||||
var shortcut = Directory.EnumerateFiles(path, ShortcutFileSearch, SearchOption.AllDirectories).FirstOrDefault(f => fileSystem.ResolveShortcut(f).Equals(mediaPath, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (!string.IsNullOrEmpty(shortcut))
|
||||
{
|
||||
|
@ -132,13 +141,14 @@ namespace MediaBrowser.Api.Library
|
|||
/// <summary>
|
||||
/// Adds an additional mediaPath to an existing virtual folder, within either the default view or a user view
|
||||
/// </summary>
|
||||
/// <param name="fileSystem">The file system.</param>
|
||||
/// <param name="virtualFolderName">Name of the virtual folder.</param>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="appPaths">The app paths.</param>
|
||||
/// <exception cref="System.ArgumentException">The path is not valid.</exception>
|
||||
/// <exception cref="System.IO.DirectoryNotFoundException">The path does not exist.</exception>
|
||||
public static void AddMediaPath(string virtualFolderName, string path, User user, IServerApplicationPaths appPaths)
|
||||
public static void AddMediaPath(IFileSystem fileSystem, string virtualFolderName, string path, User user, IServerApplicationPaths appPaths)
|
||||
{
|
||||
if (!Path.IsPathRooted(path))
|
||||
{
|
||||
|
@ -160,7 +170,7 @@ namespace MediaBrowser.Api.Library
|
|||
var rootFolderPath = user != null ? user.RootFolderPath : appPaths.DefaultUserViewsPath;
|
||||
var virtualFolderPath = Path.Combine(rootFolderPath, virtualFolderName);
|
||||
|
||||
ValidateNewMediaPath(rootFolderPath, path, appPaths);
|
||||
ValidateNewMediaPath(fileSystem, rootFolderPath, path, appPaths);
|
||||
|
||||
var shortcutFilename = Path.GetFileNameWithoutExtension(path);
|
||||
|
||||
|
@ -172,20 +182,22 @@ namespace MediaBrowser.Api.Library
|
|||
lnk = Path.Combine(virtualFolderPath, shortcutFilename + ShortcutFileExtension);
|
||||
}
|
||||
|
||||
FileSystem.CreateShortcut(lnk, path);
|
||||
fileSystem.CreateShortcut(lnk, path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates that a new media path can be added
|
||||
/// </summary>
|
||||
/// <param name="fileSystem">The file system.</param>
|
||||
/// <param name="currentViewRootFolderPath">The current view root folder path.</param>
|
||||
/// <param name="mediaPath">The media path.</param>
|
||||
/// <param name="appPaths">The app paths.</param>
|
||||
/// <exception cref="System.ArgumentException"></exception>
|
||||
private static void ValidateNewMediaPath(string currentViewRootFolderPath, string mediaPath, IServerApplicationPaths appPaths)
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// </exception>
|
||||
private static void ValidateNewMediaPath(IFileSystem fileSystem, string currentViewRootFolderPath, string mediaPath, IServerApplicationPaths appPaths)
|
||||
{
|
||||
var duplicate = Directory.EnumerateFiles(appPaths.RootFolderPath, ShortcutFileSearch, SearchOption.AllDirectories)
|
||||
.Select(FileSystem.ResolveShortcut)
|
||||
.Select(fileSystem.ResolveShortcut)
|
||||
.FirstOrDefault(p => !IsNewPathValid(mediaPath, p, false));
|
||||
|
||||
if (!string.IsNullOrEmpty(duplicate))
|
||||
|
@ -196,7 +208,7 @@ namespace MediaBrowser.Api.Library
|
|||
// Don't allow duplicate sub-paths within the same user library, or it will result in duplicate items
|
||||
// See comments in IsNewPathValid
|
||||
duplicate = Directory.EnumerateFiles(currentViewRootFolderPath, ShortcutFileSearch, SearchOption.AllDirectories)
|
||||
.Select(FileSystem.ResolveShortcut)
|
||||
.Select(fileSystem.ResolveShortcut)
|
||||
.FirstOrDefault(p => !IsNewPathValid(mediaPath, p, true));
|
||||
|
||||
if (!string.IsNullOrEmpty(duplicate))
|
||||
|
@ -206,7 +218,7 @@ namespace MediaBrowser.Api.Library
|
|||
|
||||
// Make sure the current root folder doesn't already have a shortcut to the same path
|
||||
duplicate = Directory.EnumerateFiles(currentViewRootFolderPath, ShortcutFileSearch, SearchOption.AllDirectories)
|
||||
.Select(FileSystem.ResolveShortcut)
|
||||
.Select(fileSystem.ResolveShortcut)
|
||||
.FirstOrDefault(p => mediaPath.Equals(p, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (!string.IsNullOrEmpty(duplicate))
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
@ -186,6 +187,8 @@ namespace MediaBrowser.Api.Library
|
|||
|
||||
private readonly IDirectoryWatchers _directoryWatchers;
|
||||
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LibraryStructureService"/> class.
|
||||
/// </summary>
|
||||
|
@ -193,7 +196,7 @@ namespace MediaBrowser.Api.Library
|
|||
/// <param name="userManager">The user manager.</param>
|
||||
/// <param name="libraryManager">The library manager.</param>
|
||||
/// <exception cref="System.ArgumentNullException">appPaths</exception>
|
||||
public LibraryStructureService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IDirectoryWatchers directoryWatchers)
|
||||
public LibraryStructureService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IDirectoryWatchers directoryWatchers, IFileSystem fileSystem)
|
||||
{
|
||||
if (appPaths == null)
|
||||
{
|
||||
|
@ -204,6 +207,7 @@ namespace MediaBrowser.Api.Library
|
|||
_appPaths = appPaths;
|
||||
_libraryManager = libraryManager;
|
||||
_directoryWatchers = directoryWatchers;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -241,13 +245,13 @@ namespace MediaBrowser.Api.Library
|
|||
{
|
||||
if (string.IsNullOrEmpty(request.UserId))
|
||||
{
|
||||
LibraryHelpers.AddVirtualFolder(request.Name, request.CollectionType, null, _appPaths);
|
||||
LibraryHelpers.AddVirtualFolder(_fileSystem, request.Name, request.CollectionType, null, _appPaths);
|
||||
}
|
||||
else
|
||||
{
|
||||
var user = _userManager.GetUserById(new Guid(request.UserId));
|
||||
|
||||
LibraryHelpers.AddVirtualFolder(request.Name, request.CollectionType, user, _appPaths);
|
||||
LibraryHelpers.AddVirtualFolder(_fileSystem, request.Name, request.CollectionType, user, _appPaths);
|
||||
}
|
||||
|
||||
// Need to add a delay here or directory watchers may still pick up the changes
|
||||
|
@ -352,13 +356,13 @@ namespace MediaBrowser.Api.Library
|
|||
{
|
||||
if (string.IsNullOrEmpty(request.UserId))
|
||||
{
|
||||
LibraryHelpers.AddMediaPath(request.Name, request.Path, null, _appPaths);
|
||||
LibraryHelpers.AddMediaPath(_fileSystem, request.Name, request.Path, null, _appPaths);
|
||||
}
|
||||
else
|
||||
{
|
||||
var user = _userManager.GetUserById(new Guid(request.UserId));
|
||||
|
||||
LibraryHelpers.AddMediaPath(request.Name, request.Path, user, _appPaths);
|
||||
LibraryHelpers.AddMediaPath(_fileSystem, request.Name, request.Path, user, _appPaths);
|
||||
}
|
||||
|
||||
// Need to add a delay here or directory watchers may still pick up the changes
|
||||
|
@ -389,13 +393,13 @@ namespace MediaBrowser.Api.Library
|
|||
{
|
||||
if (string.IsNullOrEmpty(request.UserId))
|
||||
{
|
||||
LibraryHelpers.RemoveMediaPath(request.Name, request.Path, null, _appPaths);
|
||||
LibraryHelpers.RemoveMediaPath(_fileSystem, request.Name, request.Path, null, _appPaths);
|
||||
}
|
||||
else
|
||||
{
|
||||
var user = _userManager.GetUserById(new Guid(request.UserId));
|
||||
|
||||
LibraryHelpers.RemoveMediaPath(request.Name, request.Path, user, _appPaths);
|
||||
LibraryHelpers.RemoveMediaPath(_fileSystem, request.Name, request.Path, user, _appPaths);
|
||||
}
|
||||
|
||||
// Need to add a delay here or directory watchers may still pick up the changes
|
||||
|
|
|
@ -5,8 +5,10 @@ using MediaBrowser.Controller.Entities.Movies;
|
|||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Providers;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using ServiceStack.ServiceHost;
|
||||
using System;
|
||||
|
@ -32,6 +34,21 @@ namespace MediaBrowser.Api
|
|||
public string Id { get; set; }
|
||||
}
|
||||
|
||||
[Route("/Items/{Id}/RemoteImages/{Type}", "GET")]
|
||||
[Api(Description = "Gets available remote images for an item")]
|
||||
public class GetRemoteImages : IReturn<List<RemoteImageInfo>>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the id.
|
||||
/// </summary>
|
||||
/// <value>The id.</value>
|
||||
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
|
||||
public string Id { get; set; }
|
||||
|
||||
[ApiMember(Name = "Type", Description = "The image type", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
|
||||
public ImageType Type { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class GetCriticReviews
|
||||
/// </summary>
|
||||
|
@ -208,6 +225,7 @@ namespace MediaBrowser.Api
|
|||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly IUserDataManager _userDataManager;
|
||||
private readonly IProviderManager _providerManager;
|
||||
|
||||
private readonly IDtoService _dtoService;
|
||||
|
||||
|
@ -215,13 +233,14 @@ namespace MediaBrowser.Api
|
|||
/// Initializes a new instance of the <see cref="LibraryService" /> class.
|
||||
/// </summary>
|
||||
public LibraryService(IItemRepository itemRepo, ILibraryManager libraryManager, IUserManager userManager,
|
||||
IDtoService dtoService, IUserDataManager userDataManager)
|
||||
IDtoService dtoService, IUserDataManager userDataManager, IProviderManager providerManager)
|
||||
{
|
||||
_itemRepo = itemRepo;
|
||||
_libraryManager = libraryManager;
|
||||
_userManager = userManager;
|
||||
_dtoService = dtoService;
|
||||
_userDataManager = userDataManager;
|
||||
_providerManager = providerManager;
|
||||
}
|
||||
|
||||
public object Get(GetFile request)
|
||||
|
@ -240,6 +259,15 @@ namespace MediaBrowser.Api
|
|||
return ToStaticFileResult(item.Path);
|
||||
}
|
||||
|
||||
public object Get(GetRemoteImages request)
|
||||
{
|
||||
var item = _dtoService.GetItemByDtoId(request.Id);
|
||||
|
||||
var result = _providerManager.GetAvailableRemoteImages(item, request.Type, CancellationToken.None).Result;
|
||||
|
||||
return ToOptimizedResult(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the specified request.
|
||||
/// </summary>
|
||||
|
@ -335,7 +363,9 @@ namespace MediaBrowser.Api
|
|||
/// <returns>System.Object.</returns>
|
||||
public object Get(GetItemCounts request)
|
||||
{
|
||||
var items = GetAllLibraryItems(request.UserId, _userManager, _libraryManager).ToList();
|
||||
var items = GetAllLibraryItems(request.UserId, _userManager, _libraryManager)
|
||||
.Where(i => i.LocationType != LocationType.Virtual)
|
||||
.ToList();
|
||||
|
||||
var filteredItems = request.UserId.HasValue ? FilterItems(items, request, request.UserId.Value).ToList() : items;
|
||||
|
||||
|
|
|
@ -59,6 +59,8 @@ namespace MediaBrowser.Api.Playback
|
|||
protected IMediaEncoder MediaEncoder { get; private set; }
|
||||
protected IDtoService DtoService { get; private set; }
|
||||
|
||||
protected IFileSystem FileSystem { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BaseStreamingService" /> class.
|
||||
/// </summary>
|
||||
|
@ -67,8 +69,9 @@ namespace MediaBrowser.Api.Playback
|
|||
/// <param name="libraryManager">The library manager.</param>
|
||||
/// <param name="isoManager">The iso manager.</param>
|
||||
/// <param name="mediaEncoder">The media encoder.</param>
|
||||
protected BaseStreamingService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService)
|
||||
protected BaseStreamingService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem)
|
||||
{
|
||||
FileSystem = fileSystem;
|
||||
DtoService = dtoService;
|
||||
ApplicationPaths = appPaths;
|
||||
UserManager = userManager;
|
||||
|
@ -269,7 +272,7 @@ namespace MediaBrowser.Api.Playback
|
|||
// If fixed dimensions were supplied
|
||||
if (request.Width.HasValue && request.Height.HasValue)
|
||||
{
|
||||
return string.Format(" -vf \"scale={0}:{1}{2}\"", request.Width.Value, request.Height.Value, assSubtitleParam);
|
||||
return string.Format(" -vf \"scale=trunc({0}/2)*2:trunc({1}/2)*2{2}\"", request.Width.Value, request.Height.Value, assSubtitleParam);
|
||||
}
|
||||
|
||||
var isH264Output = outputVideoCodec.Equals("libx264", StringComparison.OrdinalIgnoreCase);
|
||||
|
@ -653,7 +656,7 @@ namespace MediaBrowser.Api.Playback
|
|||
var logFilePath = Path.Combine(ApplicationPaths.LogDirectoryPath, "ffmpeg-" + Guid.NewGuid() + ".txt");
|
||||
|
||||
// FFMpeg writes debug/error info to stderr. This is useful when debugging so let's put it in the log directory.
|
||||
state.LogFileStream = new FileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous);
|
||||
state.LogFileStream = FileSystem.GetFileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, true);
|
||||
|
||||
process.Exited += (sender, args) => OnFfMpegProcessExited(process, state);
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Common.MediaInfo;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.MediaInfo;
|
||||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Library;
|
||||
|
@ -32,8 +33,8 @@ namespace MediaBrowser.Api.Playback.Hls
|
|||
/// <param name="libraryManager">The library manager.</param>
|
||||
/// <param name="isoManager">The iso manager.</param>
|
||||
/// <param name="mediaEncoder">The media encoder.</param>
|
||||
public AudioHlsService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService)
|
||||
: base(appPaths, userManager, libraryManager, isoManager, mediaEncoder, dtoService)
|
||||
public AudioHlsService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem)
|
||||
: base(appPaths, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -38,8 +38,8 @@ namespace MediaBrowser.Api.Playback.Hls
|
|||
/// <param name="libraryManager">The library manager.</param>
|
||||
/// <param name="isoManager">The iso manager.</param>
|
||||
/// <param name="mediaEncoder">The media encoder.</param>
|
||||
protected BaseHlsService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService)
|
||||
: base(appPaths, userManager, libraryManager, isoManager, mediaEncoder, dtoService)
|
||||
protected BaseHlsService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem)
|
||||
: base(appPaths, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -209,7 +209,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
|||
string fileText;
|
||||
|
||||
// Need to use FileShare.ReadWrite because we're reading the file at the same time it's being written
|
||||
using (var fileStream = new FileStream(playlist, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous))
|
||||
using (var fileStream = FileSystem.GetFileStream(playlist, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true))
|
||||
{
|
||||
using (var reader = new StreamReader(fileStream))
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Common.MediaInfo;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.MediaInfo;
|
||||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Library;
|
||||
|
@ -39,8 +40,8 @@ namespace MediaBrowser.Api.Playback.Hls
|
|||
/// <param name="isoManager">The iso manager.</param>
|
||||
/// <param name="mediaEncoder">The media encoder.</param>
|
||||
/// <param name="dtoService">The dto service.</param>
|
||||
public VideoHlsService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService)
|
||||
: base(appPaths, userManager, libraryManager, isoManager, mediaEncoder, dtoService)
|
||||
public VideoHlsService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem)
|
||||
: base(appPaths, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Common.MediaInfo;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.MediaInfo;
|
||||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Controller.Drawing;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
|
@ -40,8 +41,8 @@ namespace MediaBrowser.Api.Playback.Progressive
|
|||
/// </summary>
|
||||
public class AudioService : BaseProgressiveStreamingService
|
||||
{
|
||||
public AudioService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IItemRepository itemRepo, IDtoService dtoService, IImageProcessor imageProcessor)
|
||||
: base(appPaths, userManager, libraryManager, isoManager, mediaEncoder, itemRepo, dtoService, imageProcessor)
|
||||
public AudioService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IItemRepository itemRepo, IDtoService dtoService, IImageProcessor imageProcessor, IFileSystem fileSystem)
|
||||
: base(appPaths, userManager, libraryManager, isoManager, mediaEncoder, itemRepo, dtoService, imageProcessor, fileSystem)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Api.Images;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.MediaInfo;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller;
|
||||
|
@ -27,8 +28,8 @@ namespace MediaBrowser.Api.Playback.Progressive
|
|||
protected readonly IItemRepository ItemRepository;
|
||||
protected readonly IImageProcessor ImageProcessor;
|
||||
|
||||
protected BaseProgressiveStreamingService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IItemRepository itemRepository, IDtoService dtoService, IImageProcessor imageProcessor) :
|
||||
base(appPaths, userManager, libraryManager, isoManager, mediaEncoder, dtoService)
|
||||
protected BaseProgressiveStreamingService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IItemRepository itemRepository, IDtoService dtoService, IImageProcessor imageProcessor, IFileSystem fileSystem) :
|
||||
base(appPaths, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem)
|
||||
{
|
||||
ItemRepository = itemRepository;
|
||||
ImageProcessor = imageProcessor;
|
||||
|
@ -346,7 +347,7 @@ namespace MediaBrowser.Api.Playback.Progressive
|
|||
ApiEntryPoint.Instance.OnTranscodeBeginRequest(outputPath, TranscodingJobType.Progressive);
|
||||
}
|
||||
|
||||
var result = new ProgressiveStreamWriter(outputPath, Logger);
|
||||
var result = new ProgressiveStreamWriter(outputPath, Logger, FileSystem);
|
||||
|
||||
result.Options["Accept-Ranges"] = "none";
|
||||
result.Options["Content-Type"] = contentType;
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace MediaBrowser.Api.Playback.Progressive
|
|||
{
|
||||
private string Path { get; set; }
|
||||
private ILogger Logger { get; set; }
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// The _options
|
||||
|
@ -32,10 +33,11 @@ namespace MediaBrowser.Api.Playback.Progressive
|
|||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
public ProgressiveStreamWriter(string path, ILogger logger)
|
||||
public ProgressiveStreamWriter(string path, ILogger logger, IFileSystem fileSystem)
|
||||
{
|
||||
Path = path;
|
||||
Logger = logger;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -83,7 +85,7 @@ namespace MediaBrowser.Api.Playback.Progressive
|
|||
var eofCount = 0;
|
||||
long position = 0;
|
||||
|
||||
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous))
|
||||
using (var fs = _fileSystem.GetFileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true))
|
||||
{
|
||||
while (eofCount < 15)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Common.MediaInfo;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.MediaInfo;
|
||||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Controller.Drawing;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
|
@ -54,8 +55,8 @@ namespace MediaBrowser.Api.Playback.Progressive
|
|||
/// </summary>
|
||||
public class VideoService : BaseProgressiveStreamingService
|
||||
{
|
||||
public VideoService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IItemRepository itemRepo, IDtoService dtoService, IImageProcessor imageProcessor)
|
||||
: base(appPaths, userManager, libraryManager, isoManager, mediaEncoder, itemRepo, dtoService, imageProcessor)
|
||||
public VideoService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IItemRepository itemRepo, IDtoService dtoService, IImageProcessor imageProcessor, IFileSystem fileSystem)
|
||||
: base(appPaths, userManager, libraryManager, isoManager, mediaEncoder, itemRepo, dtoService, imageProcessor, fileSystem)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Session;
|
||||
using MediaBrowser.Model.Session;
|
||||
using ServiceStack.ServiceHost;
|
||||
|
@ -182,16 +183,18 @@ namespace MediaBrowser.Api
|
|||
private readonly ISessionManager _sessionManager;
|
||||
|
||||
private readonly IDtoService _dtoService;
|
||||
private readonly IUserManager _userManager;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SessionsService" /> class.
|
||||
/// </summary>
|
||||
/// <param name="sessionManager">The session manager.</param>
|
||||
/// <param name="dtoService">The dto service.</param>
|
||||
public SessionsService(ISessionManager sessionManager, IDtoService dtoService)
|
||||
public SessionsService(ISessionManager sessionManager, IDtoService dtoService, IUserManager userManager)
|
||||
{
|
||||
_sessionManager = sessionManager;
|
||||
_dtoService = dtoService;
|
||||
_userManager = userManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -208,6 +211,16 @@ namespace MediaBrowser.Api
|
|||
result = result.Where(i => i.SupportsRemoteControl == request.SupportsRemoteControl.Value);
|
||||
}
|
||||
|
||||
if (request.ControllableByUserId.HasValue)
|
||||
{
|
||||
var user = _userManager.GetUserById(request.ControllableByUserId.Value);
|
||||
|
||||
if (!user.Configuration.EnableRemoteControlOfOtherUsers)
|
||||
{
|
||||
result = result.Where(i => i.User == null || i.User.Id == request.ControllableByUserId.Value);
|
||||
}
|
||||
}
|
||||
|
||||
return ToOptimizedResult(result.Select(_dtoService.GetSessionInfoDto).ToList());
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using MediaBrowser.Model.System;
|
||||
|
@ -75,6 +77,9 @@ namespace MediaBrowser.Api
|
|||
/// </summary>
|
||||
private readonly IServerConfigurationManager _configurationManager;
|
||||
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SystemService" /> class.
|
||||
/// </summary>
|
||||
|
@ -82,7 +87,7 @@ namespace MediaBrowser.Api
|
|||
/// <param name="appHost">The app host.</param>
|
||||
/// <param name="configurationManager">The configuration manager.</param>
|
||||
/// <exception cref="System.ArgumentNullException">jsonSerializer</exception>
|
||||
public SystemService(IJsonSerializer jsonSerializer, IServerApplicationHost appHost, IServerConfigurationManager configurationManager)
|
||||
public SystemService(IJsonSerializer jsonSerializer, IServerApplicationHost appHost, IServerConfigurationManager configurationManager, IFileSystem fileSystem)
|
||||
: base()
|
||||
{
|
||||
if (jsonSerializer == null)
|
||||
|
@ -96,6 +101,7 @@ namespace MediaBrowser.Api
|
|||
|
||||
_appHost = appHost;
|
||||
_configurationManager = configurationManager;
|
||||
_fileSystem = fileSystem;
|
||||
_jsonSerializer = jsonSerializer;
|
||||
}
|
||||
|
||||
|
@ -118,7 +124,7 @@ namespace MediaBrowser.Api
|
|||
/// <returns>System.Object.</returns>
|
||||
public object Get(GetConfiguration request)
|
||||
{
|
||||
var dateModified = File.GetLastWriteTimeUtc(_configurationManager.ApplicationPaths.SystemConfigurationFilePath);
|
||||
var dateModified = _fileSystem.GetLastWriteTimeUtc(_configurationManager.ApplicationPaths.SystemConfigurationFilePath);
|
||||
|
||||
var cacheKey = (_configurationManager.ApplicationPaths.SystemConfigurationFilePath + dateModified.Ticks).GetMD5();
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
using System.Collections;
|
||||
using System.Globalization;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using ServiceStack.ServiceHost;
|
||||
using System;
|
||||
|
@ -48,18 +47,9 @@ namespace MediaBrowser.Api
|
|||
[ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, CriticRatingSummary, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, OverviewHtml, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines, TrailerUrls", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
|
||||
public string Fields { get; set; }
|
||||
|
||||
[ApiMember(Name = "ExcludeLocationTypes", Description = "Optional. If specified, results will be filtered based on LocationType. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
|
||||
public string ExcludeLocationTypes { get; set; }
|
||||
[ApiMember(Name = "SeriesId", Description = "Optional. Filter by series id", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public string SeriesId { get; set; }
|
||||
|
||||
[ApiMember(Name = "MinPremiereDate", Description = "Optional. The minimum premiere date. Format = yyyyMMddHHmmss", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
|
||||
public string MinPremiereDate { get; set; }
|
||||
|
||||
[ApiMember(Name = "MaxPremiereDate", Description = "Optional. The maximum premiere date. Format = yyyyMMddHHmmss", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
|
||||
public string MaxPremiereDate { get; set; }
|
||||
|
||||
[ApiMember(Name = "HasPremiereDate", Description = "Optional filter by items with premiere dates.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public bool? HasPremiereDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the item fields.
|
||||
/// </summary>
|
||||
|
@ -170,10 +160,15 @@ namespace MediaBrowser.Api
|
|||
{
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
|
||||
var itemsList = user.RootFolder
|
||||
.GetRecursiveChildren(user, i => i is Series)
|
||||
var items = user.RootFolder
|
||||
.GetRecursiveChildren(user)
|
||||
.OfType<Series>();
|
||||
|
||||
items = FilterSeries(request, items);
|
||||
|
||||
var itemsList = items
|
||||
.AsParallel()
|
||||
.Select(i => GetNextUp((Series)i, user, request))
|
||||
.Select(i => GetNextUp(i, user, request))
|
||||
.ToList();
|
||||
|
||||
itemsList = itemsList
|
||||
|
@ -264,35 +259,19 @@ namespace MediaBrowser.Api
|
|||
|
||||
private IEnumerable<Episode> FilterItems(GetNextUpEpisodes request, IEnumerable<Episode> items)
|
||||
{
|
||||
// ExcludeLocationTypes
|
||||
if (!string.IsNullOrEmpty(request.ExcludeLocationTypes))
|
||||
// Make this configurable when needed
|
||||
items = items.Where(i => i.LocationType != LocationType.Virtual);
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
private IEnumerable<Series> FilterSeries(GetNextUpEpisodes request, IEnumerable<Series> items)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(request.SeriesId))
|
||||
{
|
||||
var vals = request.ExcludeLocationTypes.Split(',');
|
||||
var id = new Guid(request.SeriesId);
|
||||
|
||||
items = items
|
||||
.Where(f => !vals.Contains(f.LocationType.ToString(), StringComparer.OrdinalIgnoreCase))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(request.MinPremiereDate))
|
||||
{
|
||||
var date = DateTime.ParseExact(request.MinPremiereDate, "yyyyMMddHHmmss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
|
||||
|
||||
items = items.Where(i => !i.PremiereDate.HasValue || i.PremiereDate.Value >= date);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(request.MaxPremiereDate))
|
||||
{
|
||||
var date = DateTime.ParseExact(request.MaxPremiereDate, "yyyyMMddHHmmss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
|
||||
|
||||
items = items.Where(i => !i.PremiereDate.HasValue || i.PremiereDate.Value <= date);
|
||||
}
|
||||
|
||||
if (request.HasPremiereDate.HasValue)
|
||||
{
|
||||
var val = request.HasPremiereDate.Value;
|
||||
|
||||
items = items.Where(i => i.PremiereDate.HasValue == val);
|
||||
items = items.Where(i => i.Id == id);
|
||||
}
|
||||
|
||||
return items;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System.Globalization;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
|
@ -181,22 +180,22 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
[ApiMember(Name = "IsHD", Description = "Optional filter by items that are HD or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
|
||||
public bool? IsHD { get; set; }
|
||||
|
||||
[ApiMember(Name = "ExcludeLocationTypes", Description = "Optional. If specified, results will be filtered based on LocationType. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
|
||||
public string ExcludeLocationTypes { get; set; }
|
||||
|
||||
[ApiMember(Name = "LocationTypes", Description = "Optional. If specified, results will be filtered based on LocationType. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
|
||||
public string LocationTypes { get; set; }
|
||||
|
||||
[ApiMember(Name = "MinPremiereDate", Description = "Optional. The minimum premiere date. Format = yyyyMMddHHmmss", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
|
||||
public string MinPremiereDate { get; set; }
|
||||
|
||||
[ApiMember(Name = "MaxPremiereDate", Description = "Optional. The maximum premiere date. Format = yyyyMMddHHmmss", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
|
||||
public string MaxPremiereDate { get; set; }
|
||||
|
||||
[ApiMember(Name = "HasPremiereDate", Description = "Optional filter by items with premiere dates.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public bool? HasPremiereDate { get; set; }
|
||||
[ApiMember(Name = "ExcludeLocationTypes", Description = "Optional. If specified, results will be filtered based on LocationType. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
|
||||
public string ExcludeLocationTypes { get; set; }
|
||||
|
||||
public bool IncludeIndexContainers { get; set; }
|
||||
|
||||
[ApiMember(Name = "IsMissing", Description = "Optional filter by items that are missing episodes or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
|
||||
public bool? IsMissing { get; set; }
|
||||
|
||||
[ApiMember(Name = "IsUnaired", Description = "Optional filter by items that are unaired episodes or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
|
||||
public bool? IsUnaired { get; set; }
|
||||
|
||||
[ApiMember(Name = "IsVirtualUnaired", Description = "Optional filter by items that are virtual unaired episodes or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
|
||||
public bool? IsVirtualUnaired { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -270,6 +269,8 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
items = ApplyFilter(items, filter, user, _userDataRepository);
|
||||
}
|
||||
|
||||
items = FilterVirtualEpisodes(request, items, user);
|
||||
|
||||
items = items.AsEnumerable();
|
||||
|
||||
items = ApplySearchTerm(request, items);
|
||||
|
@ -440,6 +441,121 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
return items;
|
||||
}
|
||||
|
||||
private IEnumerable<BaseItem> FilterVirtualEpisodes(GetItems request, IEnumerable<BaseItem> items, User user)
|
||||
{
|
||||
items = FilterVirtualSeasons(request, items, user);
|
||||
|
||||
if (request.IsMissing.HasValue)
|
||||
{
|
||||
var val = request.IsMissing.Value;
|
||||
items = items.Where(i =>
|
||||
{
|
||||
var e = i as Episode;
|
||||
if (e != null)
|
||||
{
|
||||
return e.IsMissingEpisode == val;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
if (request.IsUnaired.HasValue)
|
||||
{
|
||||
var val = request.IsUnaired.Value;
|
||||
items = items.Where(i =>
|
||||
{
|
||||
var e = i as Episode;
|
||||
if (e != null)
|
||||
{
|
||||
return e.IsUnaired == val;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
if (request.IsVirtualUnaired.HasValue)
|
||||
{
|
||||
var val = request.IsVirtualUnaired.Value;
|
||||
items = items.Where(i =>
|
||||
{
|
||||
var e = i as Episode;
|
||||
if (e != null)
|
||||
{
|
||||
return e.IsVirtualUnaired == val;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
private IEnumerable<BaseItem> FilterVirtualSeasons(GetItems request, IEnumerable<BaseItem> items, User user)
|
||||
{
|
||||
if (request.IsMissing.HasValue && request.IsUnaired.HasValue)
|
||||
{
|
||||
var isMissing = request.IsMissing.Value;
|
||||
var isUnaired = request.IsUnaired.Value;
|
||||
|
||||
if (!isMissing && !isUnaired)
|
||||
{
|
||||
return items.Where(i =>
|
||||
{
|
||||
var e = i as Season;
|
||||
if (e != null)
|
||||
{
|
||||
return !e.IsMissingOrVirtualUnaired;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (request.IsMissing.HasValue)
|
||||
{
|
||||
var val = request.IsMissing.Value;
|
||||
items = items.Where(i =>
|
||||
{
|
||||
var e = i as Season;
|
||||
if (e != null)
|
||||
{
|
||||
return e.IsMissingSeason == val;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
if (request.IsUnaired.HasValue)
|
||||
{
|
||||
var val = request.IsUnaired.Value;
|
||||
items = items.Where(i =>
|
||||
{
|
||||
var e = i as Season;
|
||||
if (e != null)
|
||||
{
|
||||
return e.IsUnaired == val;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
if (request.IsVirtualUnaired.HasValue)
|
||||
{
|
||||
var val = request.IsVirtualUnaired.Value;
|
||||
items = items.Where(i =>
|
||||
{
|
||||
var e = i as Season;
|
||||
if (e != null)
|
||||
{
|
||||
return e.IsVirtualUnaired == val;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies the additional filters.
|
||||
/// </summary>
|
||||
|
@ -593,13 +709,6 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
items = items.Where(f => vals.Contains(f.GetType().Name, StringComparer.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
// ExcludeLocationTypes
|
||||
if (!string.IsNullOrEmpty(request.ExcludeLocationTypes))
|
||||
{
|
||||
var vals = request.ExcludeLocationTypes.Split(',');
|
||||
items = items.Where(f => !vals.Contains(f.LocationType.ToString(), StringComparer.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
// LocationTypes
|
||||
if (!string.IsNullOrEmpty(request.LocationTypes))
|
||||
{
|
||||
|
@ -607,6 +716,13 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
items = items.Where(f => vals.Contains(f.LocationType.ToString(), StringComparer.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
// ExcludeLocationTypes
|
||||
if (!string.IsNullOrEmpty(request.ExcludeLocationTypes))
|
||||
{
|
||||
var vals = request.ExcludeLocationTypes.Split(',');
|
||||
items = items.Where(f => !vals.Contains(f.LocationType.ToString(), StringComparer.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(request.NameStartsWithOrGreater))
|
||||
{
|
||||
items = items.Where(i => string.Compare(request.NameStartsWithOrGreater, i.SortName, StringComparison.CurrentCultureIgnoreCase) < 1);
|
||||
|
@ -826,7 +942,8 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
|
||||
if (request.IsHD.HasValue)
|
||||
{
|
||||
items = items.OfType<Video>().Where(i => i.IsHD == request.IsHD.Value);
|
||||
var val = request.IsHD.Value;
|
||||
items = items.OfType<Video>().Where(i => i.IsHD == val);
|
||||
}
|
||||
|
||||
if (request.ParentIndexNumber.HasValue)
|
||||
|
@ -853,27 +970,6 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
});
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(request.MinPremiereDate))
|
||||
{
|
||||
var date = DateTime.ParseExact(request.MinPremiereDate, "yyyyMMddHHmmss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
|
||||
|
||||
items = items.Where(i => !i.PremiereDate.HasValue || i.PremiereDate.Value >= date);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(request.MaxPremiereDate))
|
||||
{
|
||||
var date = DateTime.ParseExact(request.MaxPremiereDate, "yyyyMMddHHmmss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
|
||||
|
||||
items = items.Where(i => !i.PremiereDate.HasValue || i.PremiereDate.Value <= date);
|
||||
}
|
||||
|
||||
if (request.HasPremiereDate.HasValue)
|
||||
{
|
||||
var val = request.HasPremiereDate.Value;
|
||||
|
||||
items = items.Where(i => i.PremiereDate.HasValue == val);
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -27,16 +28,18 @@ namespace MediaBrowser.Api.WebSocket
|
|||
/// The _kernel
|
||||
/// </summary>
|
||||
private readonly ILogManager _logManager;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LogFileWebSocketListener" /> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="logManager">The log manager.</param>
|
||||
public LogFileWebSocketListener(ILogger logger, ILogManager logManager)
|
||||
public LogFileWebSocketListener(ILogger logger, ILogManager logManager, IFileSystem fileSystem)
|
||||
: base(logger)
|
||||
{
|
||||
_logManager = logManager;
|
||||
_fileSystem = fileSystem;
|
||||
_logManager.LoggerLoaded += kernel_LoggerLoaded;
|
||||
}
|
||||
|
||||
|
@ -53,7 +56,7 @@ namespace MediaBrowser.Api.WebSocket
|
|||
state.StartLine = 0;
|
||||
}
|
||||
|
||||
var lines = await GetLogLines(state.LastLogFilePath, state.StartLine).ConfigureAwait(false);
|
||||
var lines = await GetLogLines(state.LastLogFilePath, state.StartLine, _fileSystem).ConfigureAwait(false);
|
||||
|
||||
state.StartLine += lines.Count;
|
||||
|
||||
|
@ -96,11 +99,11 @@ namespace MediaBrowser.Api.WebSocket
|
|||
/// <param name="logFilePath">The log file path.</param>
|
||||
/// <param name="startLine">The start line.</param>
|
||||
/// <returns>Task{IEnumerable{System.String}}.</returns>
|
||||
internal static async Task<List<string>> GetLogLines(string logFilePath, int startLine)
|
||||
internal static async Task<List<string>> GetLogLines(string logFilePath, int startLine, IFileSystem fileSystem)
|
||||
{
|
||||
var lines = new List<string>();
|
||||
|
||||
using (var fs = new FileStream(logFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, StreamDefaults.DefaultFileStreamBufferSize, true))
|
||||
using (var fs = fileSystem.GetFileStream(logFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true))
|
||||
{
|
||||
using (var reader = new StreamReader(fs))
|
||||
{
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System.Net;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.Events;
|
||||
using MediaBrowser.Common.Implementations.Archiving;
|
||||
using MediaBrowser.Common.Implementations.IO;
|
||||
|
@ -7,6 +6,7 @@ using MediaBrowser.Common.Implementations.ScheduledTasks;
|
|||
using MediaBrowser.Common.Implementations.Security;
|
||||
using MediaBrowser.Common.Implementations.Serialization;
|
||||
using MediaBrowser.Common.Implementations.Updates;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Common.Plugins;
|
||||
using MediaBrowser.Common.ScheduledTasks;
|
||||
|
@ -21,6 +21,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
|
@ -150,15 +151,17 @@ namespace MediaBrowser.Common.Implementations
|
|||
/// Gets or sets the installation manager.
|
||||
/// </summary>
|
||||
/// <value>The installation manager.</value>
|
||||
protected IInstallationManager InstallationManager { get; set; }
|
||||
protected IInstallationManager InstallationManager { get; private set; }
|
||||
|
||||
protected IFileSystem FileSystemManager { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the zip client.
|
||||
/// </summary>
|
||||
/// <value>The zip client.</value>
|
||||
protected IZipClient ZipClient { get; set; }
|
||||
protected IZipClient ZipClient { get; private set; }
|
||||
|
||||
protected IIsoManager IsoManager { get; set; }
|
||||
protected IIsoManager IsoManager { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BaseApplicationHost{TApplicationPathsType}"/> class.
|
||||
|
@ -347,7 +350,10 @@ namespace MediaBrowser.Common.Implementations
|
|||
|
||||
RegisterSingleInstance(TaskManager);
|
||||
|
||||
HttpClient = new HttpClientManager.HttpClientManager(ApplicationPaths, Logger, CreateHttpClient);
|
||||
FileSystemManager = CreateFileSystemManager();
|
||||
RegisterSingleInstance(FileSystemManager);
|
||||
|
||||
HttpClient = new HttpClientManager.HttpClientManager(ApplicationPaths, Logger, CreateHttpClient, FileSystemManager);
|
||||
RegisterSingleInstance(HttpClient);
|
||||
|
||||
NetworkManager = CreateNetworkManager();
|
||||
|
@ -367,6 +373,11 @@ namespace MediaBrowser.Common.Implementations
|
|||
});
|
||||
}
|
||||
|
||||
protected virtual IFileSystem CreateFileSystemManager()
|
||||
{
|
||||
return new CommonFileSystem(Logger, true);
|
||||
}
|
||||
|
||||
protected abstract HttpClient CreateHttpClient(bool enableHttpCompression);
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -34,6 +34,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||
public delegate HttpClient GetHttpClientHandler(bool enableHttpCompression);
|
||||
|
||||
private readonly GetHttpClientHandler _getHttpClientHandler;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HttpClientManager"/> class.
|
||||
|
@ -46,7 +47,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||
/// or
|
||||
/// logger
|
||||
/// </exception>
|
||||
public HttpClientManager(IApplicationPaths appPaths, ILogger logger, GetHttpClientHandler getHttpClientHandler)
|
||||
public HttpClientManager(IApplicationPaths appPaths, ILogger logger, GetHttpClientHandler getHttpClientHandler, IFileSystem fileSystem)
|
||||
{
|
||||
if (appPaths == null)
|
||||
{
|
||||
|
@ -59,6 +60,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||
|
||||
_logger = logger;
|
||||
_getHttpClientHandler = getHttpClientHandler;
|
||||
_fileSystem = fileSystem;
|
||||
_appPaths = appPaths;
|
||||
}
|
||||
|
||||
|
@ -417,7 +419,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||
// We're not able to track progress
|
||||
using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
|
||||
{
|
||||
using (var fs = new FileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous))
|
||||
using (var fs = _fileSystem.GetFileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.Read, true))
|
||||
{
|
||||
await stream.CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, options.CancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -427,7 +429,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||
{
|
||||
using (var stream = ProgressStream.CreateReadProgressStream(await response.Content.ReadAsStreamAsync().ConfigureAwait(false), options.Progress.Report, contentLength.Value))
|
||||
{
|
||||
using (var fs = new FileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous))
|
||||
using (var fs = _fileSystem.GetFileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.Read, true))
|
||||
{
|
||||
await stream.CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, options.CancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
|
|
@ -1,24 +1,96 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace MediaBrowser.Controller.IO
|
||||
namespace MediaBrowser.Common.Implementations.IO
|
||||
{
|
||||
/// <summary>
|
||||
/// Class FileSystem
|
||||
/// Class CommonFileSystem
|
||||
/// </summary>
|
||||
public static class FileSystem
|
||||
public class CommonFileSystem : IFileSystem
|
||||
{
|
||||
protected ILogger Logger;
|
||||
|
||||
private readonly bool _supportsAsyncFileStreams;
|
||||
|
||||
public CommonFileSystem(ILogger logger, bool supportsAsyncFileStreams)
|
||||
{
|
||||
Logger = logger;
|
||||
_supportsAsyncFileStreams = supportsAsyncFileStreams;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified filename is shortcut.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <returns><c>true</c> if the specified filename is shortcut; otherwise, <c>false</c>.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">filename</exception>
|
||||
public virtual bool IsShortcut(string filename)
|
||||
{
|
||||
if (string.IsNullOrEmpty(filename))
|
||||
{
|
||||
throw new ArgumentNullException("filename");
|
||||
}
|
||||
|
||||
var extension = Path.GetExtension(filename);
|
||||
|
||||
return string.Equals(extension, ".mblink", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the shortcut.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">filename</exception>
|
||||
public virtual string ResolveShortcut(string filename)
|
||||
{
|
||||
if (string.IsNullOrEmpty(filename))
|
||||
{
|
||||
throw new ArgumentNullException("filename");
|
||||
}
|
||||
|
||||
if (string.Equals(Path.GetExtension(filename), ".mblink", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return File.ReadAllText(filename);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the shortcut.
|
||||
/// </summary>
|
||||
/// <param name="shortcutPath">The shortcut path.</param>
|
||||
/// <param name="target">The target.</param>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// shortcutPath
|
||||
/// or
|
||||
/// target
|
||||
/// </exception>
|
||||
public void CreateShortcut(string shortcutPath, string target)
|
||||
{
|
||||
if (string.IsNullOrEmpty(shortcutPath))
|
||||
{
|
||||
throw new ArgumentNullException("shortcutPath");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(target))
|
||||
{
|
||||
throw new ArgumentNullException("target");
|
||||
}
|
||||
|
||||
File.WriteAllText(shortcutPath, target);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the file system info.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <returns>FileSystemInfo.</returns>
|
||||
public static FileSystemInfo GetFileSystemInfo(string path)
|
||||
public FileSystemInfo GetFileSystemInfo(string path)
|
||||
{
|
||||
// Take a guess to try and avoid two file system hits, but we'll double-check by calling Exists
|
||||
if (Path.HasExtension(path))
|
||||
|
@ -45,48 +117,6 @@ namespace MediaBrowser.Controller.IO
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the creation time UTC.
|
||||
/// </summary>
|
||||
/// <param name="info">The info.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <returns>DateTime.</returns>
|
||||
public static DateTime GetLastWriteTimeUtc(FileSystemInfo info, ILogger logger)
|
||||
{
|
||||
// This could throw an error on some file systems that have dates out of range
|
||||
|
||||
try
|
||||
{
|
||||
return info.LastWriteTimeUtc;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.ErrorException("Error determining LastAccessTimeUtc for {0}", ex, info.FullName);
|
||||
return DateTime.MinValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the creation time UTC.
|
||||
/// </summary>
|
||||
/// <param name="info">The info.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <returns>DateTime.</returns>
|
||||
public static DateTime GetCreationTimeUtc(FileSystemInfo info, ILogger logger)
|
||||
{
|
||||
// This could throw an error on some file systems that have dates out of range
|
||||
|
||||
try
|
||||
{
|
||||
return info.CreationTimeUtc;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.ErrorException("Error determining CreationTimeUtc for {0}", ex, info.FullName);
|
||||
return DateTime.MinValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The space char
|
||||
/// </summary>
|
||||
|
@ -102,7 +132,7 @@ namespace MediaBrowser.Controller.IO
|
|||
/// <param name="filename">The filename.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">filename</exception>
|
||||
public static string GetValidFilename(string filename)
|
||||
public string GetValidFilename(string filename)
|
||||
{
|
||||
if (string.IsNullOrEmpty(filename))
|
||||
{
|
||||
|
@ -120,144 +150,71 @@ namespace MediaBrowser.Controller.IO
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the shortcut.
|
||||
/// Gets the creation time UTC.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">filename</exception>
|
||||
public static string ResolveShortcut(string filename)
|
||||
/// <param name="info">The info.</param>
|
||||
/// <returns>DateTime.</returns>
|
||||
public DateTime GetCreationTimeUtc(FileSystemInfo info)
|
||||
{
|
||||
if (string.IsNullOrEmpty(filename))
|
||||
// This could throw an error on some file systems that have dates out of range
|
||||
try
|
||||
{
|
||||
throw new ArgumentNullException("filename");
|
||||
return info.CreationTimeUtc;
|
||||
}
|
||||
|
||||
if (string.Equals(Path.GetExtension(filename), ".mblink", StringComparison.OrdinalIgnoreCase))
|
||||
catch (Exception ex)
|
||||
{
|
||||
return File.ReadAllText(filename);
|
||||
}
|
||||
|
||||
//return new WindowsShortcut(filename).ResolvedPath;
|
||||
|
||||
var link = new ShellLink();
|
||||
((IPersistFile)link).Load(filename, NativeMethods.STGM_READ);
|
||||
// TODO: if I can get hold of the hwnd call resolve first. This handles moved and renamed files.
|
||||
// ((IShellLinkW)link).Resolve(hwnd, 0)
|
||||
var sb = new StringBuilder(NativeMethods.MAX_PATH);
|
||||
WIN32_FIND_DATA data;
|
||||
((IShellLinkW)link).GetPath(sb, sb.Capacity, out data, 0);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a shortcut file pointing to a specified path
|
||||
/// </summary>
|
||||
/// <param name="shortcutPath">The shortcut path.</param>
|
||||
/// <param name="target">The target.</param>
|
||||
/// <exception cref="System.ArgumentNullException">shortcutPath</exception>
|
||||
public static void CreateShortcut(string shortcutPath, string target)
|
||||
{
|
||||
if (string.IsNullOrEmpty(shortcutPath))
|
||||
{
|
||||
throw new ArgumentNullException("shortcutPath");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(target))
|
||||
{
|
||||
throw new ArgumentNullException("target");
|
||||
}
|
||||
|
||||
File.WriteAllText(shortcutPath, target);
|
||||
|
||||
//var link = new ShellLink();
|
||||
|
||||
//((IShellLinkW)link).SetPath(target);
|
||||
|
||||
//((IPersistFile)link).Save(shortcutPath, true);
|
||||
}
|
||||
|
||||
private static readonly Dictionary<string, string> ShortcutExtensionsDictionary = new[] { ".mblink", ".lnk" }
|
||||
.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified filename is shortcut.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <returns><c>true</c> if the specified filename is shortcut; otherwise, <c>false</c>.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">filename</exception>
|
||||
public static bool IsShortcut(string filename)
|
||||
{
|
||||
if (string.IsNullOrEmpty(filename))
|
||||
{
|
||||
throw new ArgumentNullException("filename");
|
||||
}
|
||||
|
||||
var extension = Path.GetExtension(filename);
|
||||
|
||||
return !string.IsNullOrEmpty(extension) && ShortcutExtensionsDictionary.ContainsKey(extension);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies all.
|
||||
/// </summary>
|
||||
/// <param name="source">The source.</param>
|
||||
/// <param name="target">The target.</param>
|
||||
/// <exception cref="System.ArgumentNullException">source</exception>
|
||||
/// <exception cref="System.ArgumentException">The source and target directories are the same</exception>
|
||||
public static void CopyAll(string source, string target)
|
||||
{
|
||||
if (string.IsNullOrEmpty(source))
|
||||
{
|
||||
throw new ArgumentNullException("source");
|
||||
}
|
||||
if (string.IsNullOrEmpty(target))
|
||||
{
|
||||
throw new ArgumentNullException("target");
|
||||
}
|
||||
|
||||
if (source.Equals(target, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new ArgumentException("The source and target directories are the same");
|
||||
}
|
||||
|
||||
// Check if the target directory exists, if not, create it.
|
||||
Directory.CreateDirectory(target);
|
||||
|
||||
foreach (var file in Directory.EnumerateFiles(source))
|
||||
{
|
||||
File.Copy(file, Path.Combine(target, Path.GetFileName(file)), true);
|
||||
}
|
||||
|
||||
// Copy each subdirectory using recursion.
|
||||
foreach (var dir in Directory.EnumerateDirectories(source))
|
||||
{
|
||||
CopyAll(dir, Path.Combine(target, Path.GetFileName(dir)));
|
||||
Logger.ErrorException("Error determining CreationTimeUtc for {0}", ex, info.FullName);
|
||||
return DateTime.MinValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses the ini file.
|
||||
/// Gets the creation time UTC.
|
||||
/// </summary>
|
||||
/// <param name="info">The info.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <returns>DateTime.</returns>
|
||||
public DateTime GetLastWriteTimeUtc(FileSystemInfo info)
|
||||
{
|
||||
// This could throw an error on some file systems that have dates out of range
|
||||
try
|
||||
{
|
||||
return info.LastWriteTimeUtc;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.ErrorException("Error determining LastAccessTimeUtc for {0}", ex, info.FullName);
|
||||
return DateTime.MinValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last write time UTC.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <returns>NameValueCollection.</returns>
|
||||
public static NameValueCollection ParseIniFile(string path)
|
||||
/// <returns>DateTime.</returns>
|
||||
public DateTime GetLastWriteTimeUtc(string path)
|
||||
{
|
||||
var values = new NameValueCollection();
|
||||
return GetLastWriteTimeUtc(GetFileSystemInfo(path));
|
||||
}
|
||||
|
||||
foreach (var line in File.ReadAllLines(path))
|
||||
/// <summary>
|
||||
/// Gets the file stream.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <param name="mode">The mode.</param>
|
||||
/// <param name="access">The access.</param>
|
||||
/// <param name="share">The share.</param>
|
||||
/// <param name="isAsync">if set to <c>true</c> [is asynchronous].</param>
|
||||
/// <returns>FileStream.</returns>
|
||||
public FileStream GetFileStream(string path, FileMode mode, FileAccess access, FileShare share, bool isAsync = false)
|
||||
{
|
||||
if (_supportsAsyncFileStreams && isAsync)
|
||||
{
|
||||
var data = line.Split('=');
|
||||
|
||||
if (data.Length < 2) continue;
|
||||
|
||||
var key = data[0];
|
||||
|
||||
var value = data.Length == 2 ? data[1] : string.Join(string.Empty, data, 1, data.Length - 1);
|
||||
|
||||
values[key] = value;
|
||||
return new FileStream(path, mode, access, share, 4096, true);
|
||||
}
|
||||
|
||||
return values;
|
||||
return new FileStream(path, mode, access, share);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -381,4 +338,5 @@ namespace MediaBrowser.Controller.IO
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -44,6 +44,10 @@
|
|||
<Reference Include="SharpCompress">
|
||||
<HintPath>..\packages\sharpcompress.0.10.1.3\lib\net40\SharpCompress.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SimpleInjector, Version=2.3.6.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\SimpleInjector.2.3.6\lib\net40-client\SimpleInjector.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Core" />
|
||||
|
@ -54,9 +58,6 @@
|
|||
<Reference Include="ServiceStack.Text">
|
||||
<HintPath>..\packages\ServiceStack.Text.3.9.62\lib\net35\ServiceStack.Text.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SimpleInjector">
|
||||
<HintPath>..\packages\SimpleInjector.2.3.5\lib\net40-client\SimpleInjector.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\SharedVersion.cs">
|
||||
|
@ -68,6 +69,7 @@
|
|||
<Compile Include="Configuration\BaseConfigurationManager.cs" />
|
||||
<Compile Include="HttpClientManager\HttpClientInfo.cs" />
|
||||
<Compile Include="HttpClientManager\HttpClientManager.cs" />
|
||||
<Compile Include="IO\CommonFileSystem.cs" />
|
||||
<Compile Include="IO\IsoManager.cs" />
|
||||
<Compile Include="Logging\LogHelper.cs" />
|
||||
<Compile Include="Logging\NLogger.cs" />
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.ScheduledTasks;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
||||
namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
|
||||
{
|
||||
|
@ -23,14 +24,17 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
|
|||
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DeleteCacheFileTask" /> class.
|
||||
/// </summary>
|
||||
/// <param name="appPaths">The app paths.</param>
|
||||
public DeleteCacheFileTask(IApplicationPaths appPaths, ILogger logger)
|
||||
public DeleteCacheFileTask(IApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem)
|
||||
{
|
||||
ApplicationPaths = appPaths;
|
||||
_logger = logger;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -94,7 +98,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
|
|||
private void DeleteCacheFilesFromDirectory(CancellationToken cancellationToken, string directory, DateTime minDateModified, IProgress<double> progress)
|
||||
{
|
||||
var filesToDelete = new DirectoryInfo(directory).EnumerateFiles("*", SearchOption.AllDirectories)
|
||||
.Where(f => f.LastWriteTimeUtc < minDateModified)
|
||||
.Where(f => _fileSystem.GetLastWriteTimeUtc(f) < minDateModified)
|
||||
.ToList();
|
||||
|
||||
var index = 0;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.ScheduledTasks;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -20,13 +21,16 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
|
|||
/// <value>The configuration manager.</value>
|
||||
private IConfigurationManager ConfigurationManager { get; set; }
|
||||
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DeleteLogFileTask" /> class.
|
||||
/// </summary>
|
||||
/// <param name="configurationManager">The configuration manager.</param>
|
||||
public DeleteLogFileTask(IConfigurationManager configurationManager)
|
||||
public DeleteLogFileTask(IConfigurationManager configurationManager, IFileSystem fileSystem)
|
||||
{
|
||||
ConfigurationManager = configurationManager;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -58,7 +62,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks
|
|||
var minDateModified = DateTime.UtcNow.AddDays(-(ConfigurationManager.CommonConfiguration.LogFileRetentionDays));
|
||||
|
||||
var filesToDelete = new DirectoryInfo(ConfigurationManager.CommonApplicationPaths.LogDirectoryPath).EnumerateFileSystemInfos("*", SearchOption.AllDirectories)
|
||||
.Where(f => f.LastWriteTimeUtc < minDateModified)
|
||||
.Where(f => _fileSystem.GetLastWriteTimeUtc(f) < minDateModified)
|
||||
.ToList();
|
||||
|
||||
var index = 0;
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
<package id="NLog" version="2.1.0" targetFramework="net45" />
|
||||
<package id="ServiceStack.Text" version="3.9.62" targetFramework="net45" />
|
||||
<package id="sharpcompress" version="0.10.1.3" targetFramework="net45" />
|
||||
<package id="SimpleInjector" version="2.3.5" targetFramework="net45" />
|
||||
<package id="SimpleInjector" version="2.3.6" targetFramework="net45" />
|
||||
</packages>
|
78
MediaBrowser.Common/IO/IFileSystem.cs
Normal file
78
MediaBrowser.Common/IO/IFileSystem.cs
Normal file
|
@ -0,0 +1,78 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace MediaBrowser.Common.IO
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IFileSystem
|
||||
/// </summary>
|
||||
public interface IFileSystem
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines whether the specified filename is shortcut.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <returns><c>true</c> if the specified filename is shortcut; otherwise, <c>false</c>.</returns>
|
||||
bool IsShortcut(string filename);
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the shortcut.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
string ResolveShortcut(string filename);
|
||||
|
||||
/// <summary>
|
||||
/// Creates the shortcut.
|
||||
/// </summary>
|
||||
/// <param name="shortcutPath">The shortcut path.</param>
|
||||
/// <param name="target">The target.</param>
|
||||
void CreateShortcut(string shortcutPath, string target);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the file system info.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <returns>FileSystemInfo.</returns>
|
||||
FileSystemInfo GetFileSystemInfo(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the valid filename.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
string GetValidFilename(string filename);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the creation time UTC.
|
||||
/// </summary>
|
||||
/// <param name="info">The info.</param>
|
||||
/// <returns>DateTime.</returns>
|
||||
DateTime GetCreationTimeUtc(FileSystemInfo info);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last write time UTC.
|
||||
/// </summary>
|
||||
/// <param name="info">The information.</param>
|
||||
/// <returns>DateTime.</returns>
|
||||
DateTime GetLastWriteTimeUtc(FileSystemInfo info);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last write time UTC.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <returns>DateTime.</returns>
|
||||
DateTime GetLastWriteTimeUtc(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the file stream.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <param name="mode">The mode.</param>
|
||||
/// <param name="access">The access.</param>
|
||||
/// <param name="share">The share.</param>
|
||||
/// <param name="isAsync">if set to <c>true</c> [is asynchronous].</param>
|
||||
/// <returns>FileStream.</returns>
|
||||
FileStream GetFileStream(string path, FileMode mode, FileAccess access, FileShare share, bool isAsync = false);
|
||||
}
|
||||
}
|
|
@ -60,6 +60,7 @@
|
|||
<Compile Include="Events\GenericEventArgs.cs" />
|
||||
<Compile Include="Extensions\ResourceNotFoundException.cs" />
|
||||
<Compile Include="IO\FileSystemRepository.cs" />
|
||||
<Compile Include="IO\IFileSystem.cs" />
|
||||
<Compile Include="IO\ProgressStream.cs" />
|
||||
<Compile Include="IO\StreamDefaults.cs" />
|
||||
<Compile Include="MediaInfo\MediaInfoResult.cs" />
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.IO;
|
||||
|
@ -212,6 +213,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
public static IProviderManager ProviderManager { get; set; }
|
||||
public static ILocalizationManager LocalizationManager { get; set; }
|
||||
public static IItemRepository ItemRepository { get; set; }
|
||||
public static IFileSystem FileSystem { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String" /> that represents this instance.
|
||||
|
@ -395,7 +397,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
// 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
|
||||
|
@ -413,7 +415,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
}
|
||||
|
||||
//update our dates
|
||||
EntityResolutionHelper.EnsureDates(this, args, false);
|
||||
EntityResolutionHelper.EnsureDates(FileSystem, this, args, false);
|
||||
|
||||
IsOffline = false;
|
||||
|
||||
|
@ -1337,6 +1339,13 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
var data = userManager.GetUserData(user.Id, key);
|
||||
|
||||
if (datePlayed.HasValue)
|
||||
{
|
||||
// Incremenet
|
||||
data.PlayCount++;
|
||||
}
|
||||
|
||||
// Ensure it's at least one
|
||||
data.PlayCount = Math.Max(data.PlayCount, 1);
|
||||
|
||||
data.LastPlayedDate = datePlayed ?? data.LastPlayedDate;
|
||||
|
@ -1530,7 +1539,8 @@ namespace MediaBrowser.Controller.Entities
|
|||
}
|
||||
|
||||
// Refresh metadata
|
||||
return RefreshMetadata(CancellationToken.None, forceSave: true);
|
||||
// Need to disable slow providers or the image might get re-downloaded
|
||||
return RefreshMetadata(CancellationToken.None, forceSave: true, allowSlowProviders: false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1728,7 +1738,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
if (locationType == LocationType.Remote ||
|
||||
locationType == LocationType.Virtual)
|
||||
{
|
||||
return File.GetLastWriteTimeUtc(imagePath);
|
||||
return FileSystem.GetLastWriteTimeUtc(imagePath);
|
||||
}
|
||||
|
||||
var metaFileEntry = ResolveArgs.GetMetaFileByPath(imagePath);
|
||||
|
@ -1745,7 +1755,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
}
|
||||
|
||||
// See if we can avoid a file system lookup by looking for the file in ResolveArgs
|
||||
return metaFileEntry == null ? File.GetLastWriteTimeUtc(imagePath) : metaFileEntry.LastWriteTimeUtc;
|
||||
return metaFileEntry == null ? FileSystem.GetLastWriteTimeUtc(imagePath) : FileSystem.GetLastWriteTimeUtc(metaFileEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -693,7 +693,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
//existing item - check if it has changed
|
||||
if (currentChild.HasChanged(child))
|
||||
{
|
||||
EntityResolutionHelper.EnsureDates(currentChild, child.ResolveArgs, false);
|
||||
EntityResolutionHelper.EnsureDates(FileSystem, currentChild, child.ResolveArgs, false);
|
||||
|
||||
validChildren.Add(new Tuple<BaseItem, bool>(currentChild, true));
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
|
@ -191,5 +192,23 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsMissingEpisode
|
||||
{
|
||||
get
|
||||
{
|
||||
return LocationType == Model.Entities.LocationType.Virtual && PremiereDate.HasValue && PremiereDate.Value < DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsUnaired
|
||||
{
|
||||
get { return PremiereDate.HasValue && PremiereDate.Value.ToLocalTime().Date >= DateTime.Now.Date; }
|
||||
}
|
||||
|
||||
public bool IsVirtualUnaired
|
||||
{
|
||||
get { return LocationType == Model.Entities.LocationType.Virtual && IsUnaired; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Controller.Library;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Localization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -147,5 +148,25 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
{
|
||||
return IndexNumber != null ? IndexNumber.Value.ToString("0000") : Name;
|
||||
}
|
||||
|
||||
public bool IsMissingSeason
|
||||
{
|
||||
get { return LocationType == Model.Entities.LocationType.Virtual && Children.OfType<Episode>().All(i => i.IsMissingEpisode); }
|
||||
}
|
||||
|
||||
public bool IsUnaired
|
||||
{
|
||||
get { return Children.OfType<Episode>().All(i => i.IsUnaired); }
|
||||
}
|
||||
|
||||
public bool IsVirtualUnaired
|
||||
{
|
||||
get { return LocationType == Model.Entities.LocationType.Virtual && IsUnaired; }
|
||||
}
|
||||
|
||||
public bool IsMissingOrVirtualUnaired
|
||||
{
|
||||
get { return LocationType == Model.Entities.LocationType.Virtual && Children.OfType<Episode>().All(i => i.IsVirtualUnaired || i.IsMissingEpisode); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -165,7 +165,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
// Ensure it's been lazy loaded
|
||||
var config = Configuration;
|
||||
|
||||
return File.GetLastWriteTimeUtc(ConfigurationFilePath);
|
||||
return FileSystem.GetLastWriteTimeUtc(ConfigurationFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -15,6 +16,7 @@ namespace MediaBrowser.Controller.IO
|
|||
/// Gets the filtered file system entries.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <param name="fileSystem">The file system.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="args">The args.</param>
|
||||
/// <param name="searchPattern">The search pattern.</param>
|
||||
|
@ -22,7 +24,7 @@ namespace MediaBrowser.Controller.IO
|
|||
/// <param name="resolveShortcuts">if set to <c>true</c> [resolve shortcuts].</param>
|
||||
/// <returns>Dictionary{System.StringFileSystemInfo}.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">path</exception>
|
||||
public static Dictionary<string, FileSystemInfo> GetFilteredFileSystemEntries(string path, ILogger logger, ItemResolveArgs args, string searchPattern = "*", int flattenFolderDepth = 0, bool resolveShortcuts = true)
|
||||
public static Dictionary<string, FileSystemInfo> GetFilteredFileSystemEntries(string path, IFileSystem fileSystem, ILogger logger, ItemResolveArgs args, string searchPattern = "*", int flattenFolderDepth = 0, bool resolveShortcuts = true)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
|
@ -56,9 +58,9 @@ namespace MediaBrowser.Controller.IO
|
|||
|
||||
var fullName = entry.FullName;
|
||||
|
||||
if (resolveShortcuts && FileSystem.IsShortcut(fullName))
|
||||
if (resolveShortcuts && fileSystem.IsShortcut(fullName))
|
||||
{
|
||||
var newPath = FileSystem.ResolveShortcut(fullName);
|
||||
var newPath = fileSystem.ResolveShortcut(fullName);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(newPath))
|
||||
{
|
||||
|
@ -77,7 +79,7 @@ namespace MediaBrowser.Controller.IO
|
|||
}
|
||||
else if (flattenFolderDepth > 0 && isDirectory)
|
||||
{
|
||||
foreach (var child in GetFilteredFileSystemEntries(fullName, logger, args, flattenFolderDepth: flattenFolderDepth - 1, resolveShortcuts: resolveShortcuts))
|
||||
foreach (var child in GetFilteredFileSystemEntries(fullName, fileSystem, logger, args, flattenFolderDepth: flattenFolderDepth - 1, resolveShortcuts: resolveShortcuts))
|
||||
{
|
||||
dict[child.Key] = child.Value;
|
||||
}
|
||||
|
|
|
@ -108,6 +108,7 @@
|
|||
<Compile Include="Notifications\INotificationsRepository.cs" />
|
||||
<Compile Include="Notifications\NotificationUpdateEventArgs.cs" />
|
||||
<Compile Include="Providers\IDynamicInfoProvider.cs" />
|
||||
<Compile Include="Providers\IImageProvider.cs" />
|
||||
<Compile Include="Session\ISessionManager.cs" />
|
||||
<Compile Include="Drawing\ImageExtensions.cs" />
|
||||
<Compile Include="Entities\AggregateFolder.cs" />
|
||||
|
@ -139,9 +140,7 @@
|
|||
<Compile Include="Entities\Video.cs" />
|
||||
<Compile Include="Entities\CollectionFolder.cs" />
|
||||
<Compile Include="Entities\Year.cs" />
|
||||
<Compile Include="IO\FileSystem.cs" />
|
||||
<Compile Include="IO\IDirectoryWatchers.cs" />
|
||||
<Compile Include="IO\NativeMethods.cs" />
|
||||
<Compile Include="IServerApplicationHost.cs" />
|
||||
<Compile Include="IServerApplicationPaths.cs" />
|
||||
<Compile Include="Library\SearchHintInfo.cs" />
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.MediaInfo;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
@ -35,6 +36,8 @@ namespace MediaBrowser.Controller.MediaInfo
|
|||
private readonly ILogger _logger;
|
||||
private readonly IItemRepository _itemRepo;
|
||||
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FFMpegManager" /> class.
|
||||
/// </summary>
|
||||
|
@ -43,12 +46,13 @@ namespace MediaBrowser.Controller.MediaInfo
|
|||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="itemRepo">The item repo.</param>
|
||||
/// <exception cref="System.ArgumentNullException">zipClient</exception>
|
||||
public FFMpegManager(IServerApplicationPaths appPaths, IMediaEncoder encoder, ILogger logger, IItemRepository itemRepo)
|
||||
public FFMpegManager(IServerApplicationPaths appPaths, IMediaEncoder encoder, ILogger logger, IItemRepository itemRepo, IFileSystem fileSystem)
|
||||
{
|
||||
_appPaths = appPaths;
|
||||
_encoder = encoder;
|
||||
_logger = logger;
|
||||
_itemRepo = itemRepo;
|
||||
_fileSystem = fileSystem;
|
||||
|
||||
VideoImageCache = new FileSystemRepository(VideoImagesDataPath);
|
||||
SubtitleCache = new FileSystemRepository(SubtitleCachePath);
|
||||
|
@ -203,7 +207,7 @@ namespace MediaBrowser.Controller.MediaInfo
|
|||
|
||||
if (stream.IsExternal)
|
||||
{
|
||||
ticksParam += File.GetLastWriteTimeUtc(stream.Path).Ticks;
|
||||
ticksParam += _fileSystem.GetLastWriteTimeUtc(stream.Path).Ticks;
|
||||
}
|
||||
|
||||
return SubtitleCache.GetResourcePath(input.Id + "_" + subtitleStreamIndex + "_" + input.DateModified.Ticks + ticksParam, outputExtension);
|
||||
|
|
|
@ -552,32 +552,6 @@ namespace MediaBrowser.Controller.Providers
|
|||
}
|
||||
break;
|
||||
|
||||
case "GamesDbId":
|
||||
var gamesdbId = reader.ReadElementContentAsString();
|
||||
if (!string.IsNullOrWhiteSpace(gamesdbId))
|
||||
{
|
||||
item.SetProviderId(MetadataProviders.Gamesdb, gamesdbId);
|
||||
}
|
||||
break;
|
||||
|
||||
case "Players":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
int num;
|
||||
|
||||
if (int.TryParse(val, NumberStyles.Integer, _usCulture, out num))
|
||||
{
|
||||
var game = item as Game;
|
||||
if (game != null)
|
||||
{
|
||||
game.PlayersSupported = num;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "VoteCount":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
@ -592,19 +566,6 @@ namespace MediaBrowser.Controller.Providers
|
|||
}
|
||||
break;
|
||||
}
|
||||
case "GameSystem":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
var game = item as Game;
|
||||
if (game != null)
|
||||
{
|
||||
game.GameSystem = val;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "MusicbrainzId":
|
||||
{
|
||||
var mbz = reader.ReadElementContentAsString();
|
||||
|
|
38
MediaBrowser.Controller/Providers/IImageProvider.cs
Normal file
38
MediaBrowser.Controller/Providers/IImageProvider.cs
Normal file
|
@ -0,0 +1,38 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Providers;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IImageProvider
|
||||
/// </summary>
|
||||
public interface IImageProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Supportses the specified item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="imageType">Type of the image.</param>
|
||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
|
||||
bool Supports(BaseItem item, ImageType imageType);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the available images.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="imageType">Type of the image.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{IEnumerable{RemoteImageInfo}}.</returns>
|
||||
Task<IEnumerable<RemoteImageInfo>> GetAvailableImages(BaseItem item, ImageType imageType, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Providers;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
@ -52,6 +53,16 @@ namespace MediaBrowser.Controller.Providers
|
|||
/// Adds the metadata providers.
|
||||
/// </summary>
|
||||
/// <param name="providers">The providers.</param>
|
||||
void AddParts(IEnumerable<BaseMetadataProvider> providers);
|
||||
/// <param name="imageProviders">The image providers.</param>
|
||||
void AddParts(IEnumerable<BaseMetadataProvider> providers, IEnumerable<IImageProvider> imageProviders);
|
||||
|
||||
/// <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>
|
||||
Task<IEnumerable<RemoteImageInfo>> GetAvailableRemoteImages(BaseItem item, ImageType type, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using System;
|
||||
|
@ -44,7 +45,8 @@ namespace MediaBrowser.Controller.Resolvers
|
|||
".f4v",
|
||||
".3gp",
|
||||
".webm",
|
||||
".mts"
|
||||
".mts",
|
||||
".rec"
|
||||
};
|
||||
|
||||
private static readonly Dictionary<string, string> VideoFileExtensionsDictionary = VideoFileExtensions.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
|
||||
|
@ -125,10 +127,11 @@ namespace MediaBrowser.Controller.Resolvers
|
|||
/// <summary>
|
||||
/// Ensures DateCreated and DateModified have values
|
||||
/// </summary>
|
||||
/// <param name="fileSystem">The file system.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="args">The args.</param>
|
||||
/// <param name="includeCreationTime">if set to <c>true</c> [include creation time].</param>
|
||||
public static void EnsureDates(BaseItem item, ItemResolveArgs args, bool includeCreationTime)
|
||||
public static void EnsureDates(IFileSystem fileSystem, BaseItem item, ItemResolveArgs args, bool includeCreationTime)
|
||||
{
|
||||
if (!Path.IsPathRooted(item.Path))
|
||||
{
|
||||
|
@ -144,22 +147,22 @@ namespace MediaBrowser.Controller.Resolvers
|
|||
{
|
||||
if (includeCreationTime)
|
||||
{
|
||||
item.DateCreated = childData.CreationTimeUtc;
|
||||
item.DateCreated = fileSystem.GetCreationTimeUtc(childData);
|
||||
}
|
||||
|
||||
item.DateModified = childData.LastWriteTimeUtc;
|
||||
item.DateModified = fileSystem.GetLastWriteTimeUtc(childData);
|
||||
}
|
||||
else
|
||||
{
|
||||
var fileData = FileSystem.GetFileSystemInfo(item.Path);
|
||||
var fileData = fileSystem.GetFileSystemInfo(item.Path);
|
||||
|
||||
if (fileData.Exists)
|
||||
{
|
||||
if (includeCreationTime)
|
||||
{
|
||||
item.DateCreated = fileData.CreationTimeUtc;
|
||||
item.DateCreated = fileSystem.GetCreationTimeUtc(fileData);
|
||||
}
|
||||
item.DateModified = fileData.LastWriteTimeUtc;
|
||||
item.DateModified = fileSystem.GetLastWriteTimeUtc(fileData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -167,9 +170,9 @@ namespace MediaBrowser.Controller.Resolvers
|
|||
{
|
||||
if (includeCreationTime)
|
||||
{
|
||||
item.DateCreated = args.FileInfo.CreationTimeUtc;
|
||||
item.DateCreated = fileSystem.GetCreationTimeUtc(args.FileInfo);
|
||||
}
|
||||
item.DateModified = args.FileInfo.LastWriteTimeUtc;
|
||||
item.DateModified = fileSystem.GetLastWriteTimeUtc(args.FileInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -290,6 +290,9 @@
|
|||
<Compile Include="..\MediaBrowser.Model\Plugins\PluginInfo.cs">
|
||||
<Link>Plugins\PluginInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Providers\RemoteImageInfo.cs">
|
||||
<Link>Providers\RemoteImageInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Querying\ArtistsQuery.cs">
|
||||
<Link>Querying\ArtistsQuery.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -277,6 +277,9 @@
|
|||
<Compile Include="..\MediaBrowser.Model\Plugins\PluginInfo.cs">
|
||||
<Link>Plugins\PluginInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Providers\RemoteImageInfo.cs">
|
||||
<Link>Providers\RemoteImageInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Querying\ArtistsQuery.cs">
|
||||
<Link>Querying\ArtistsQuery.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -56,16 +56,18 @@ namespace MediaBrowser.Model.Configuration
|
|||
|
||||
public bool IsDisabled { get; set; }
|
||||
|
||||
public bool DisplayVirtualEpisodes { get; set; }
|
||||
|
||||
public bool DisplayMissingEpisodes { get; set; }
|
||||
public bool DisplayUnairedEpisodes { get; set; }
|
||||
public bool EnableRemoteControlOfOtherUsers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UserConfiguration" /> class.
|
||||
/// </summary>
|
||||
public UserConfiguration()
|
||||
{
|
||||
IsAdministrator = true;
|
||||
EnableRemoteControlOfOtherUsers = true;
|
||||
BlockNotRated = false;
|
||||
DisplayVirtualEpisodes = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,8 @@ namespace MediaBrowser.Model.Entities
|
|||
/// </summary>
|
||||
TmdbCollection,
|
||||
MusicBrainzReleaseGroup,
|
||||
Zap2It
|
||||
Zap2It,
|
||||
NesBox,
|
||||
NesBoxRom
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<Compile Include="Dto\ItemByNameCounts.cs" />
|
||||
<Compile Include="Dto\ItemCounts.cs" />
|
||||
<Compile Include="Dto\ItemIndex.cs" />
|
||||
<Compile Include="Providers\RemoteImageInfo.cs" />
|
||||
<Compile Include="Dto\StudioDto.cs" />
|
||||
<Compile Include="Entities\CollectionType.cs" />
|
||||
<Compile Include="Entities\ItemReview.cs" />
|
||||
|
|
59
MediaBrowser.Model/Providers/RemoteImageInfo.cs
Normal file
59
MediaBrowser.Model/Providers/RemoteImageInfo.cs
Normal file
|
@ -0,0 +1,59 @@
|
|||
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Model.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Class RemoteImageInfo
|
||||
/// </summary>
|
||||
public class RemoteImageInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the provider.
|
||||
/// </summary>
|
||||
/// <value>The name of the provider.</value>
|
||||
public string ProviderName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the URL.
|
||||
/// </summary>
|
||||
/// <value>The URL.</value>
|
||||
public string Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the height.
|
||||
/// </summary>
|
||||
/// <value>The height.</value>
|
||||
public int? Height { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the width.
|
||||
/// </summary>
|
||||
/// <value>The width.</value>
|
||||
public int? Width { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the community rating.
|
||||
/// </summary>
|
||||
/// <value>The community rating.</value>
|
||||
public double? CommunityRating { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the vote count.
|
||||
/// </summary>
|
||||
/// <value>The vote count.</value>
|
||||
public int? VoteCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the language.
|
||||
/// </summary>
|
||||
/// <value>The language.</value>
|
||||
public string Language { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type.
|
||||
/// </summary>
|
||||
/// <value>The type.</value>
|
||||
public ImageType Type { get; set; }
|
||||
}
|
||||
}
|
|
@ -241,16 +241,27 @@ namespace MediaBrowser.Model.Querying
|
|||
/// </summary>
|
||||
/// <value>The location types.</value>
|
||||
public LocationType[] LocationTypes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is missing episode.
|
||||
/// </summary>
|
||||
/// <value><c>null</c> if [is missing episode] contains no value, <c>true</c> if [is missing episode]; otherwise, <c>false</c>.</value>
|
||||
public bool? IsMissing { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is unaired episode.
|
||||
/// </summary>
|
||||
/// <value><c>null</c> if [is unaired episode] contains no value, <c>true</c> if [is unaired episode]; otherwise, <c>false</c>.</value>
|
||||
public bool? IsUnaired { get; set; }
|
||||
|
||||
public bool? IsVirtualUnaired { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the exclude location types.
|
||||
/// </summary>
|
||||
/// <value>The exclude location types.</value>
|
||||
public LocationType[] ExcludeLocationTypes { get; set; }
|
||||
|
||||
public bool? HasPremiereDate { get; set; }
|
||||
public DateTime? MinPremiereDate { get; set; }
|
||||
public DateTime? MaxPremiereDate { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ItemQuery" /> class.
|
||||
/// </summary>
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
|
||||
|
||||
namespace MediaBrowser.Model.Querying
|
||||
{
|
||||
public class NextUpQuery
|
||||
|
@ -11,6 +9,12 @@ namespace MediaBrowser.Model.Querying
|
|||
/// <value>The user id.</value>
|
||||
public string UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the series id.
|
||||
/// </summary>
|
||||
/// <value>The series id.</value>
|
||||
public string SeriesId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Skips over a given number of items within the results. Use for paging.
|
||||
/// </summary>
|
||||
|
@ -28,20 +32,5 @@ namespace MediaBrowser.Model.Querying
|
|||
/// </summary>
|
||||
/// <value>The fields.</value>
|
||||
public ItemFields[] Fields { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the exclude location types.
|
||||
/// </summary>
|
||||
/// <value>The exclude location types.</value>
|
||||
public LocationType[] ExcludeLocationTypes { get; set; }
|
||||
|
||||
public bool? HasPremiereDate { get; set; }
|
||||
public DateTime? MinPremiereDate { get; set; }
|
||||
public DateTime? MaxPremiereDate { get; set; }
|
||||
|
||||
public NextUpQuery()
|
||||
{
|
||||
ExcludeLocationTypes = new LocationType[] { };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +1,24 @@
|
|||
<Properties>
|
||||
<MonoDevelop.Ide.Workspace ActiveConfiguration="Release|x86" />
|
||||
<MonoDevelop.Ide.Workspace ActiveConfiguration="Debug|x86" />
|
||||
<MonoDevelop.Ide.Workbench ActiveDocument="MediaBrowser.Server.Mono\Program.cs">
|
||||
<Files>
|
||||
<File FileName="MediaBrowser.Server.Mono\Program.cs" Line="60" Column="5" />
|
||||
<File FileName="MediaBrowser.Server.Mono\Program.cs" Line="259" Column="4" />
|
||||
<File FileName="MediaBrowser.ServerApplication\ApplicationHost.cs" Line="58" Column="12" />
|
||||
<File FileName="MediaBrowser.Server.Mono\IO\FileSystemFactory.cs" Line="22" Column="1" />
|
||||
</Files>
|
||||
<Pads>
|
||||
<Pad Id="ProjectPad">
|
||||
<State expanded="True">
|
||||
<Node name="MediaBrowser.Common.Implementations" expanded="True">
|
||||
<Node name="HttpClientManager" expanded="True" />
|
||||
</Node>
|
||||
<Node name="MediaBrowser.Controller" expanded="True">
|
||||
<Node name="Drawing" expanded="True" />
|
||||
</Node>
|
||||
<Node name="MediaBrowser.Common" expanded="True" />
|
||||
<Node name="MediaBrowser.Common.Implementations" expanded="True" />
|
||||
<Node name="MediaBrowser.Controller" expanded="True" />
|
||||
<Node name="MediaBrowser.Model" expanded="True">
|
||||
<Node name="References" expanded="True" />
|
||||
<Node name="Web" expanded="True" />
|
||||
</Node>
|
||||
<Node name="MediaBrowser.Server.Implementations" expanded="True" />
|
||||
<Node name="MediaBrowser.Server.Mono" expanded="True">
|
||||
<Node name="FFMpeg" expanded="True" />
|
||||
<Node name="IO" expanded="True" />
|
||||
<Node name="Program.cs" selected="True" />
|
||||
</Node>
|
||||
</State>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
|
@ -17,10 +18,12 @@ namespace MediaBrowser.Providers
|
|||
public class FolderProviderFromXml : BaseMetadataProvider
|
||||
{
|
||||
public static FolderProviderFromXml Current;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
public FolderProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager)
|
||||
public FolderProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
Current = this;
|
||||
}
|
||||
|
||||
|
@ -53,7 +56,7 @@ namespace MediaBrowser.Providers
|
|||
return false;
|
||||
}
|
||||
|
||||
return FileSystem.GetLastWriteTimeUtc(xml, Logger) > providerInfo.LastRefreshed;
|
||||
return _fileSystem.GetLastWriteTimeUtc(xml) > providerInfo.LastRefreshed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,27 +1,30 @@
|
|||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Providers.Savers;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Providers.Savers;
|
||||
|
||||
namespace MediaBrowser.Providers.Games
|
||||
{
|
||||
public class GameProviderFromXml : BaseMetadataProvider
|
||||
{
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="logManager"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public GameProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager)
|
||||
public GameProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -45,7 +48,7 @@ namespace MediaBrowser.Providers.Games
|
|||
return false;
|
||||
}
|
||||
|
||||
return FileSystem.GetLastWriteTimeUtc(xml, Logger) > providerInfo.LastRefreshed;
|
||||
return _fileSystem.GetLastWriteTimeUtc(xml) > providerInfo.LastRefreshed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -78,7 +81,7 @@ namespace MediaBrowser.Providers.Games
|
|||
|
||||
try
|
||||
{
|
||||
new BaseItemXmlParser<Game>(Logger).Fetch(game, metaFile, cancellationToken);
|
||||
new GameXmlParser(Logger).Fetch(game, metaFile, cancellationToken);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
|
@ -14,10 +15,12 @@ namespace MediaBrowser.Providers.Games
|
|||
public class GameSystemProviderFromXml : BaseMetadataProvider
|
||||
{
|
||||
internal static GameSystemProviderFromXml Current { get; private set; }
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
public GameSystemProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager)
|
||||
public GameSystemProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
Current = this;
|
||||
}
|
||||
|
||||
|
@ -50,7 +53,7 @@ namespace MediaBrowser.Providers.Games
|
|||
return false;
|
||||
}
|
||||
|
||||
return FileSystem.GetLastWriteTimeUtc(xml, Logger) > providerInfo.LastRefreshed;
|
||||
return _fileSystem.GetLastWriteTimeUtc(xml) > providerInfo.LastRefreshed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
110
MediaBrowser.Providers/Games/GameXmlParser.cs
Normal file
110
MediaBrowser.Providers/Games/GameXmlParser.cs
Normal file
|
@ -0,0 +1,110 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
|
||||
namespace MediaBrowser.Providers.Games
|
||||
{
|
||||
/// <summary>
|
||||
/// Class EpisodeXmlParser
|
||||
/// </summary>
|
||||
public class GameXmlParser : BaseItemXmlParser<Game>
|
||||
{
|
||||
private Task _chaptersTask = null;
|
||||
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
||||
|
||||
public GameXmlParser(ILogger logger)
|
||||
: base(logger)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task FetchAsync(Game item, string metadataFile, CancellationToken cancellationToken)
|
||||
{
|
||||
_chaptersTask = null;
|
||||
|
||||
Fetch(item, metadataFile, cancellationToken);
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
if (_chaptersTask != null)
|
||||
{
|
||||
await _chaptersTask.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches the data from XML node.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
protected override void FetchDataFromXmlNode(XmlReader reader, Game item)
|
||||
{
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "GameSystem":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
item.GameSystem = val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "GamesDbId":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
item.SetProviderId(MetadataProviders.Gamesdb, val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "NesBox":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
item.SetProviderId(MetadataProviders.NesBox, val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "NesBoxRom":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
item.SetProviderId(MetadataProviders.NesBoxRom, val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "Players":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
int num;
|
||||
|
||||
if (int.TryParse(val, NumberStyles.Integer, _usCulture, out num))
|
||||
{
|
||||
item.PlayersSupported = num;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
base.FetchDataFromXmlNode(reader, item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.IO;
|
||||
|
@ -18,9 +19,12 @@ namespace MediaBrowser.Providers
|
|||
/// </summary>
|
||||
public class ImagesByNameProvider : ImageFromMediaLocationProvider
|
||||
{
|
||||
public ImagesByNameProvider(ILogManager logManager, IServerConfigurationManager configurationManager)
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
public ImagesByNameProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
public override ItemUpdateType ItemUpdateType
|
||||
|
@ -110,8 +114,8 @@ namespace MediaBrowser.Providers
|
|||
|
||||
return files.Select(f =>
|
||||
{
|
||||
var lastWriteTime = FileSystem.GetLastWriteTimeUtc(f, Logger);
|
||||
var creationTime = FileSystem.GetCreationTimeUtc(f, Logger);
|
||||
var lastWriteTime = _fileSystem.GetLastWriteTimeUtc(f);
|
||||
var creationTime = _fileSystem.GetCreationTimeUtc(f);
|
||||
|
||||
return creationTime > lastWriteTime ? creationTime : lastWriteTime;
|
||||
|
||||
|
@ -150,7 +154,7 @@ namespace MediaBrowser.Providers
|
|||
/// <returns>System.String.</returns>
|
||||
protected string GetLocation(BaseItem item)
|
||||
{
|
||||
var name = FileSystem.GetValidFilename(item.Name);
|
||||
var name = _fileSystem.GetValidFilename(item.Name);
|
||||
|
||||
return Path.Combine(ConfigurationManager.ApplicationPaths.GeneralPath, name);
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
<ItemGroup>
|
||||
<Compile Include="FanartBaseProvider.cs" />
|
||||
<Compile Include="FolderProviderFromXml.cs" />
|
||||
<Compile Include="Games\GameXmlParser.cs" />
|
||||
<Compile Include="Games\GameProviderFromXml.cs" />
|
||||
<Compile Include="Games\GameSystemProviderFromXml.cs" />
|
||||
<Compile Include="ImageFromMediaLocationProvider.cs" />
|
||||
|
@ -59,6 +60,7 @@
|
|||
<Compile Include="MediaInfo\FFProbeVideoInfoProvider.cs" />
|
||||
<Compile Include="MediaInfo\VideoImageProvider.cs" />
|
||||
<Compile Include="Movies\BoxSetProviderFromXml.cs" />
|
||||
<Compile Include="Movies\ManualMovieDbImageProvider.cs" />
|
||||
<Compile Include="Movies\MovieUpdatesPrescanTask.cs" />
|
||||
<Compile Include="Movies\MovieXmlParser.cs" />
|
||||
<Compile Include="Movies\FanArtMovieProvider.cs" />
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.IO;
|
||||
|
@ -18,10 +19,12 @@ namespace MediaBrowser.Providers.Movies
|
|||
public class BoxSetProviderFromXml : BaseMetadataProvider
|
||||
{
|
||||
public static BoxSetProviderFromXml Current;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
public BoxSetProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager)
|
||||
public BoxSetProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
Current = this;
|
||||
}
|
||||
|
||||
|
@ -54,7 +57,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
return false;
|
||||
}
|
||||
|
||||
return FileSystem.GetLastWriteTimeUtc(xml, Logger) > providerInfo.LastRefreshed;
|
||||
return _fileSystem.GetLastWriteTimeUtc(xml) > providerInfo.LastRefreshed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -4,6 +4,7 @@ using MediaBrowser.Common.Net;
|
|||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
@ -40,6 +41,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
internal static FanArtMovieProvider Current { get; private set; }
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FanArtMovieProvider" /> class.
|
||||
|
@ -49,7 +51,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
/// <param name="configurationManager">The configuration manager.</param>
|
||||
/// <param name="providerManager">The provider manager.</param>
|
||||
/// <exception cref="System.ArgumentNullException">httpClient</exception>
|
||||
public FanArtMovieProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager)
|
||||
public FanArtMovieProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager, IFileSystem fileSystem)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
if (httpClient == null)
|
||||
|
@ -58,6 +60,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
}
|
||||
HttpClient = httpClient;
|
||||
_providerManager = providerManager;
|
||||
_fileSystem = fileSystem;
|
||||
Current = this;
|
||||
}
|
||||
|
||||
|
@ -174,7 +177,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
{
|
||||
var files = new DirectoryInfo(path)
|
||||
.EnumerateFiles("*.xml", SearchOption.TopDirectoryOnly)
|
||||
.Select(i => i.LastWriteTimeUtc)
|
||||
.Select(i => _fileSystem.GetLastWriteTimeUtc(i))
|
||||
.ToList();
|
||||
|
||||
if (files.Count > 0)
|
||||
|
@ -275,7 +278,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
|
||||
}).ConfigureAwait(false))
|
||||
{
|
||||
using (var xmlFileStream = new FileStream(xmlPath, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous))
|
||||
using (var xmlFileStream = _fileSystem.GetFileStream(xmlPath, FileMode.Create, FileAccess.Write, FileShare.Read, true))
|
||||
{
|
||||
await response.CopyToAsync(xmlFileStream).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -300,14 +303,14 @@ namespace MediaBrowser.Providers.Movies
|
|||
|
||||
string path;
|
||||
|
||||
if (ConfigurationManager.Configuration.DownloadMovieImages.Disc && !item.HasImage(ImageType.Disc))
|
||||
if (ConfigurationManager.Configuration.DownloadMovieImages.Primary && !item.HasImage(ImageType.Primary))
|
||||
{
|
||||
var node = doc.SelectSingleNode("//fanart/movie/movieposters/movieposter[@lang = \"" + language + "\"]/@url") ??
|
||||
doc.SelectSingleNode("//fanart/movie/movieposters/movieposter/@url");
|
||||
path = node != null ? node.Value : null;
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
await _providerManager.SaveImage(item, path, FanArtResourcePool, ImageType.Disc, null, cancellationToken)
|
||||
await _providerManager.SaveImage(item, path, FanArtResourcePool, ImageType.Primary, null, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
@ -32,15 +33,17 @@ namespace MediaBrowser.Providers.Movies
|
|||
/// </summary>
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
public FanArtMovieUpdatesPrescanTask(IJsonSerializer jsonSerializer, IServerConfigurationManager config, ILogger logger, IHttpClient httpClient)
|
||||
public FanArtMovieUpdatesPrescanTask(IJsonSerializer jsonSerializer, IServerConfigurationManager config, ILogger logger, IHttpClient httpClient, IFileSystem fileSystem)
|
||||
{
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_config = config;
|
||||
_logger = logger;
|
||||
_httpClient = httpClient;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -66,7 +69,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
var timestampFileInfo = new FileInfo(timestampFile);
|
||||
|
||||
// Don't check for tvdb updates anymore frequently than 24 hours
|
||||
if (timestampFileInfo.Exists && (DateTime.UtcNow - timestampFileInfo.LastWriteTimeUtc).TotalDays < 1)
|
||||
if (timestampFileInfo.Exists && (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(timestampFileInfo)).TotalDays < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
168
MediaBrowser.Providers/Movies/ManualMovieDbImageProvider.cs
Normal file
168
MediaBrowser.Providers/Movies/ManualMovieDbImageProvider.cs
Normal file
|
@ -0,0 +1,168 @@
|
|||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Providers;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Providers.Movies
|
||||
{
|
||||
class ManualMovieDbImageProvider : IImageProvider
|
||||
{
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly IServerConfigurationManager _config;
|
||||
|
||||
public ManualMovieDbImageProvider(IJsonSerializer jsonSerializer, IServerConfigurationManager config)
|
||||
{
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "TheMovieDB"; }
|
||||
}
|
||||
|
||||
public bool Supports(BaseItem item, ImageType imageType)
|
||||
{
|
||||
if (MovieDbImagesProvider.SupportsItem(item))
|
||||
{
|
||||
return imageType == ImageType.Primary || imageType == ImageType.Backdrop;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RemoteImageInfo>> GetAvailableImages(BaseItem item, ImageType imageType, CancellationToken cancellationToken)
|
||||
{
|
||||
var images = await GetAllImages(item, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return images.Where(i => i.Type == imageType);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RemoteImageInfo>> GetAllImages(BaseItem item, CancellationToken cancellationToken)
|
||||
{
|
||||
var list = new List<RemoteImageInfo>();
|
||||
|
||||
var results = FetchImages(item, _jsonSerializer);
|
||||
|
||||
if (results == null)
|
||||
{
|
||||
return list;
|
||||
}
|
||||
|
||||
var tmdbSettings = await MovieDbProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var tmdbImageUrl = tmdbSettings.images.base_url + "original";
|
||||
|
||||
list.AddRange(GetPosters(results, item).Select(i => new RemoteImageInfo
|
||||
{
|
||||
Url = tmdbImageUrl + i.file_path,
|
||||
CommunityRating = i.vote_average,
|
||||
VoteCount = i.vote_count,
|
||||
Width = i.width,
|
||||
Height = i.height,
|
||||
Language = i.iso_639_1,
|
||||
ProviderName = Name,
|
||||
Type = ImageType.Primary
|
||||
}));
|
||||
|
||||
list.AddRange(GetBackdrops(results, item).Select(i => new RemoteImageInfo
|
||||
{
|
||||
Url = tmdbImageUrl + i.file_path,
|
||||
CommunityRating = i.vote_average,
|
||||
VoteCount = i.vote_count,
|
||||
Width = i.width,
|
||||
Height = i.height,
|
||||
ProviderName = Name,
|
||||
Type = ImageType.Backdrop
|
||||
}));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the posters.
|
||||
/// </summary>
|
||||
/// <param name="images">The images.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>IEnumerable{MovieDbProvider.Poster}.</returns>
|
||||
private IEnumerable<MovieDbProvider.Poster> GetPosters(MovieDbProvider.Images images, BaseItem item)
|
||||
{
|
||||
var language = _config.Configuration.PreferredMetadataLanguage;
|
||||
|
||||
var isLanguageEn = string.Equals(language, "en", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
var eligiblePosters = images.posters == null ?
|
||||
new List<MovieDbProvider.Poster>() :
|
||||
images.posters.Where(i => i.width >= _config.Configuration.MinMoviePosterWidth)
|
||||
.ToList();
|
||||
|
||||
return eligiblePosters.OrderByDescending(i =>
|
||||
{
|
||||
if (string.Equals(language, i.iso_639_1, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
if (!isLanguageEn)
|
||||
{
|
||||
if (string.Equals("en", i.iso_639_1, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
if (string.IsNullOrEmpty(i.iso_639_1))
|
||||
{
|
||||
return isLanguageEn ? 3 : 2;
|
||||
}
|
||||
return 0;
|
||||
})
|
||||
.ThenByDescending(i => i.vote_average)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the backdrops.
|
||||
/// </summary>
|
||||
/// <param name="images">The images.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>IEnumerable{MovieDbProvider.Backdrop}.</returns>
|
||||
private IEnumerable<MovieDbProvider.Backdrop> GetBackdrops(MovieDbProvider.Images images, BaseItem item)
|
||||
{
|
||||
var eligibleBackdrops = images.backdrops == null ? new List<MovieDbProvider.Backdrop>() :
|
||||
images.backdrops.Where(i => i.width >= _config.Configuration.MinMovieBackdropWidth)
|
||||
.ToList();
|
||||
|
||||
return eligibleBackdrops.OrderByDescending(i => i.vote_average);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches the images.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="jsonSerializer">The json serializer.</param>
|
||||
/// <returns>Task{MovieImages}.</returns>
|
||||
private MovieDbProvider.Images FetchImages(BaseItem item, IJsonSerializer jsonSerializer)
|
||||
{
|
||||
var path = MovieDbProvider.Current.GetDataFilePath(item, "default");
|
||||
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
var fileInfo = new FileInfo(path);
|
||||
|
||||
if (fileInfo.Exists)
|
||||
{
|
||||
return jsonSerializer.DeserializeFromFile<MovieDbProvider.CompleteMovieData>(path).images;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
|
@ -6,6 +7,7 @@ using MediaBrowser.Controller.Library;
|
|||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Providers;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -21,11 +23,6 @@ namespace MediaBrowser.Providers.Movies
|
|||
/// </summary>
|
||||
public class MovieDbImagesProvider : BaseMetadataProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// The get images
|
||||
/// </summary>
|
||||
private const string GetImages = @"http://api.themoviedb.org/3/{2}/{0}/images?api_key={1}";
|
||||
|
||||
/// <summary>
|
||||
/// The _provider manager
|
||||
/// </summary>
|
||||
|
@ -35,6 +32,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
/// The _json serializer
|
||||
/// </summary>
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MovieDbImagesProvider"/> class.
|
||||
|
@ -43,11 +41,12 @@ namespace MediaBrowser.Providers.Movies
|
|||
/// <param name="configurationManager">The configuration manager.</param>
|
||||
/// <param name="providerManager">The provider manager.</param>
|
||||
/// <param name="jsonSerializer">The json serializer.</param>
|
||||
public MovieDbImagesProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager, IJsonSerializer jsonSerializer)
|
||||
public MovieDbImagesProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager, IJsonSerializer jsonSerializer, IFileSystem fileSystem)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
_providerManager = providerManager;
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -65,6 +64,11 @@ namespace MediaBrowser.Providers.Movies
|
|||
/// <param name="item">The item.</param>
|
||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
|
||||
public override bool Supports(BaseItem item)
|
||||
{
|
||||
return SupportsItem(item);
|
||||
}
|
||||
|
||||
public static bool SupportsItem(BaseItem item)
|
||||
{
|
||||
var trailer = item as Trailer;
|
||||
|
||||
|
@ -149,7 +153,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
var path = MovieDbProvider.Current.GetDataFilePath(item, "default");
|
||||
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
|
@ -158,7 +162,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
|
||||
if (fileInfo.Exists)
|
||||
{
|
||||
return fileInfo.LastWriteTimeUtc > providerInfo.LastRefreshed;
|
||||
return _fileSystem.GetLastWriteTimeUtc(fileInfo) > providerInfo.LastRefreshed;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,44 +180,18 @@ namespace MediaBrowser.Providers.Movies
|
|||
{
|
||||
var id = item.GetProviderId(MetadataProviders.Tmdb);
|
||||
|
||||
var status = ProviderRefreshStatus.Success;
|
||||
|
||||
if (!string.IsNullOrEmpty(id))
|
||||
{
|
||||
var images = FetchImages(item);
|
||||
var images = await new ManualMovieDbImageProvider(_jsonSerializer, ConfigurationManager).GetAllImages(item,
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (images != null)
|
||||
{
|
||||
status = await ProcessImages(item, images, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
await ProcessImages(item, images.ToList(), cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
SetLastRefreshed(item, DateTime.UtcNow, status);
|
||||
SetLastRefreshed(item, DateTime.UtcNow);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches the images.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>Task{MovieImages}.</returns>
|
||||
private MovieDbProvider.Images FetchImages(BaseItem item)
|
||||
{
|
||||
var path = MovieDbProvider.Current.GetDataFilePath(item, "default");
|
||||
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
var fileInfo = new FileInfo(path);
|
||||
|
||||
if (fileInfo.Exists)
|
||||
{
|
||||
return _jsonSerializer.DeserializeFromFile<MovieDbProvider.CompleteMovieData>(path).images;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes the images.
|
||||
/// </summary>
|
||||
|
@ -221,68 +199,36 @@ namespace MediaBrowser.Providers.Movies
|
|||
/// <param name="images">The images.</param>
|
||||
/// <param name="cancellationToken">The cancellation token</param>
|
||||
/// <returns>Task.</returns>
|
||||
private async Task<ProviderRefreshStatus> ProcessImages(BaseItem item, MovieDbProvider.Images images, CancellationToken cancellationToken)
|
||||
private async Task ProcessImages(BaseItem item, List<RemoteImageInfo> images, CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var status = ProviderRefreshStatus.Success;
|
||||
|
||||
var eligiblePosters = images.posters == null ?
|
||||
new List<MovieDbProvider.Poster>() :
|
||||
images.posters.Where(i => i.width >= ConfigurationManager.Configuration.MinMoviePosterWidth)
|
||||
var eligiblePosters = images
|
||||
.Where(i => i.Type == ImageType.Primary)
|
||||
.ToList();
|
||||
|
||||
eligiblePosters = eligiblePosters.OrderByDescending(i => i.vote_average).ToList();
|
||||
|
||||
// poster
|
||||
if (eligiblePosters.Count > 0 && !item.HasImage(ImageType.Primary))
|
||||
{
|
||||
var tmdbSettings = await MovieDbProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false);
|
||||
var poster = eligiblePosters[0];
|
||||
|
||||
var tmdbImageUrl = tmdbSettings.images.base_url + "original";
|
||||
// get highest rated poster for our language
|
||||
var url = poster.Url;
|
||||
|
||||
var poster = eligiblePosters.FirstOrDefault(p => string.Equals(p.iso_639_1, ConfigurationManager.Configuration.PreferredMetadataLanguage, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (poster == null)
|
||||
var img = await MovieDbProvider.Current.GetMovieDbResponse(new HttpRequestOptions
|
||||
{
|
||||
// couldn't find our specific language, find english
|
||||
poster = eligiblePosters.FirstOrDefault(p => string.Equals(p.iso_639_1, "en", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
Url = url,
|
||||
CancellationToken = cancellationToken
|
||||
|
||||
if (poster == null)
|
||||
{
|
||||
//still couldn't find it - try highest rated null one
|
||||
poster = eligiblePosters.FirstOrDefault(p => p.iso_639_1 == null);
|
||||
}
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
if (poster == null)
|
||||
{
|
||||
//finally - just get the highest rated one
|
||||
poster = eligiblePosters.FirstOrDefault();
|
||||
}
|
||||
|
||||
if (poster != null)
|
||||
{
|
||||
var url = tmdbImageUrl + poster.file_path;
|
||||
|
||||
var img = await MovieDbProvider.Current.GetMovieDbResponse(new HttpRequestOptions
|
||||
{
|
||||
Url = url,
|
||||
CancellationToken = cancellationToken
|
||||
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
await _providerManager.SaveImage(item, img, MimeTypes.GetMimeType(poster.file_path), ImageType.Primary, null, url, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
}
|
||||
await _providerManager.SaveImage(item, img, MimeTypes.GetMimeType(url), ImageType.Primary, null, url, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var eligibleBackdrops = images.backdrops == null ? new List<MovieDbProvider.Backdrop>() :
|
||||
images.backdrops.Where(i => i.width >= ConfigurationManager.Configuration.MinMovieBackdropWidth)
|
||||
var eligibleBackdrops = images
|
||||
.Where(i => i.Type == ImageType.Backdrop)
|
||||
.ToList();
|
||||
|
||||
var backdropLimit = ConfigurationManager.Configuration.MaxBackdrops;
|
||||
|
@ -290,13 +236,9 @@ namespace MediaBrowser.Providers.Movies
|
|||
// backdrops - only download if earlier providers didn't find any (fanart)
|
||||
if (eligibleBackdrops.Count > 0 && ConfigurationManager.Configuration.DownloadMovieImages.Backdrops && item.BackdropImagePaths.Count < backdropLimit)
|
||||
{
|
||||
var tmdbSettings = await MovieDbProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var tmdbImageUrl = tmdbSettings.images.base_url + "original";
|
||||
|
||||
for (var i = 0; i < eligibleBackdrops.Count; i++)
|
||||
{
|
||||
var url = tmdbImageUrl + eligibleBackdrops[i].file_path;
|
||||
var url = eligibleBackdrops[i].Url;
|
||||
|
||||
if (!item.ContainsImageWithSourceUrl(url))
|
||||
{
|
||||
|
@ -307,7 +249,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
await _providerManager.SaveImage(item, img, MimeTypes.GetMimeType(eligibleBackdrops[i].file_path), ImageType.Backdrop, item.BackdropImagePaths.Count, url, cancellationToken)
|
||||
await _providerManager.SaveImage(item, img, MimeTypes.GetMimeType(url), ImageType.Backdrop, item.BackdropImagePaths.Count, url, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
@ -317,8 +259,6 @@ namespace MediaBrowser.Providers.Movies
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
|
@ -47,6 +48,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
/// </summary>
|
||||
/// <value>The HTTP client.</value>
|
||||
protected IHttpClient HttpClient { get; private set; }
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MovieDbProvider" /> class.
|
||||
|
@ -56,12 +58,13 @@ namespace MediaBrowser.Providers.Movies
|
|||
/// <param name="jsonSerializer">The json serializer.</param>
|
||||
/// <param name="httpClient">The HTTP client.</param>
|
||||
/// <param name="providerManager">The provider manager.</param>
|
||||
public MovieDbProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IJsonSerializer jsonSerializer, IHttpClient httpClient, IProviderManager providerManager)
|
||||
public MovieDbProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IJsonSerializer jsonSerializer, IHttpClient httpClient, IProviderManager providerManager, IFileSystem fileSystem)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
JsonSerializer = jsonSerializer;
|
||||
HttpClient = httpClient;
|
||||
ProviderManager = providerManager;
|
||||
_fileSystem = fileSystem;
|
||||
Current = this;
|
||||
}
|
||||
|
||||
|
@ -189,6 +192,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
|
||||
static readonly Regex[] NameMatches = new[] {
|
||||
new Regex(@"(?<name>.*)\((?<year>\d{4})\)"), // matches "My Movie (2001)" and gives us the name and the year
|
||||
new Regex(@"(?<name>.*)(\.(?<year>\d{4})(\.|$)).*$"),
|
||||
new Regex(@"(?<name>.*)") // last resort matches the whole string as the name
|
||||
};
|
||||
|
||||
|
@ -215,7 +219,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
|
||||
if (fileInfo.Exists)
|
||||
{
|
||||
return fileInfo.LastWriteTimeUtc > providerInfo.LastRefreshed;
|
||||
return _fileSystem.GetLastWriteTimeUtc(fileInfo) > providerInfo.LastRefreshed;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -320,7 +324,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
/// <param name="name">The name.</param>
|
||||
/// <param name="justName">Name of the just.</param>
|
||||
/// <param name="year">The year.</param>
|
||||
protected void ParseName(string name, out string justName, out int? year)
|
||||
public static void ParseName(string name, out string justName, out int? year)
|
||||
{
|
||||
justName = null;
|
||||
year = null;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
@ -21,11 +21,13 @@ namespace MediaBrowser.Providers.Movies
|
|||
{
|
||||
internal static MovieProviderFromXml Current { get; private set; }
|
||||
private readonly IItemRepository _itemRepo;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
public MovieProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager, IItemRepository itemRepo)
|
||||
public MovieProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager, IItemRepository itemRepo, IFileSystem fileSystem)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
_itemRepo = itemRepo;
|
||||
_fileSystem = fileSystem;
|
||||
Current = this;
|
||||
}
|
||||
|
||||
|
@ -71,7 +73,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
return false;
|
||||
}
|
||||
|
||||
return FileSystem.GetLastWriteTimeUtc(xml, Logger) > providerInfo.LastRefreshed;
|
||||
return _fileSystem.GetLastWriteTimeUtc(xml) > providerInfo.LastRefreshed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Common.Progress;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Library;
|
||||
|
@ -35,6 +36,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
/// </summary>
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly IJsonSerializer _json;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MovieUpdatesPreScanTask"/> class.
|
||||
|
@ -43,12 +45,13 @@ namespace MediaBrowser.Providers.Movies
|
|||
/// <param name="httpClient">The HTTP client.</param>
|
||||
/// <param name="config">The config.</param>
|
||||
/// <param name="json">The json.</param>
|
||||
public MovieUpdatesPreScanTask(ILogger logger, IHttpClient httpClient, IServerConfigurationManager config, IJsonSerializer json)
|
||||
public MovieUpdatesPreScanTask(ILogger logger, IHttpClient httpClient, IServerConfigurationManager config, IJsonSerializer json, IFileSystem fileSystem)
|
||||
{
|
||||
_logger = logger;
|
||||
_httpClient = httpClient;
|
||||
_config = config;
|
||||
_json = json;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
@ -100,7 +103,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
var refreshDays = _config.Configuration.EnableTmdbUpdates ? 1 : 7;
|
||||
|
||||
// Don't check for tvdb updates anymore frequently than 24 hours
|
||||
if (timestampFileInfo.Exists && (DateTime.UtcNow - timestampFileInfo.LastWriteTimeUtc).TotalDays < refreshDays)
|
||||
if (timestampFileInfo.Exists && (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(timestampFileInfo)).TotalDays < refreshDays)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
|
@ -13,10 +14,12 @@ namespace MediaBrowser.Providers.Movies
|
|||
class PersonProviderFromXml : BaseMetadataProvider
|
||||
{
|
||||
internal static PersonProviderFromXml Current { get; private set; }
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
public PersonProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager)
|
||||
public PersonProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
Current = this;
|
||||
}
|
||||
|
||||
|
@ -49,7 +52,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
return false;
|
||||
}
|
||||
|
||||
return FileSystem.GetLastWriteTimeUtc(xml, Logger) > providerInfo.LastRefreshed;
|
||||
return _fileSystem.GetLastWriteTimeUtc(xml) > providerInfo.LastRefreshed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
@ -34,6 +35,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
/// </summary>
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly IJsonSerializer _json;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PersonUpdatesPreScanTask"/> class.
|
||||
|
@ -41,12 +43,13 @@ namespace MediaBrowser.Providers.Movies
|
|||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="httpClient">The HTTP client.</param>
|
||||
/// <param name="config">The config.</param>
|
||||
public PersonUpdatesPreScanTask(ILogger logger, IHttpClient httpClient, IServerConfigurationManager config, IJsonSerializer json)
|
||||
public PersonUpdatesPreScanTask(ILogger logger, IHttpClient httpClient, IServerConfigurationManager config, IJsonSerializer json, IFileSystem fileSystem)
|
||||
{
|
||||
_logger = logger;
|
||||
_httpClient = httpClient;
|
||||
_config = config;
|
||||
_json = json;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
@ -74,7 +77,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
var timestampFileInfo = new FileInfo(timestampFile);
|
||||
|
||||
// Don't check for tvdb updates anymore frequently than 24 hours
|
||||
if (timestampFileInfo.Exists && (DateTime.UtcNow - timestampFileInfo.LastWriteTimeUtc).TotalDays < 1)
|
||||
if (timestampFileInfo.Exists && (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(timestampFileInfo)).TotalDays < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -30,8 +30,9 @@ namespace MediaBrowser.Providers.Movies
|
|||
internal static TmdbPersonProvider Current { get; private set; }
|
||||
|
||||
const string DataFileName = "info.json";
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
public TmdbPersonProvider(IJsonSerializer jsonSerializer, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager)
|
||||
public TmdbPersonProvider(IJsonSerializer jsonSerializer, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager, IFileSystem fileSystem)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
if (jsonSerializer == null)
|
||||
|
@ -40,6 +41,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
}
|
||||
JsonSerializer = jsonSerializer;
|
||||
ProviderManager = providerManager;
|
||||
_fileSystem = fileSystem;
|
||||
Current = this;
|
||||
}
|
||||
|
||||
|
@ -105,7 +107,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
|
||||
if (fileInfo.Exists)
|
||||
{
|
||||
return fileInfo.LastWriteTimeUtc > providerInfo.LastRefreshed;
|
||||
return _fileSystem.GetLastWriteTimeUtc(fileInfo) > providerInfo.LastRefreshed;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -270,7 +272,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
{
|
||||
Directory.CreateDirectory(personDataPath);
|
||||
|
||||
using (var fs = new FileStream(Path.Combine(personDataPath, DataFileName), FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, true))
|
||||
using (var fs = _fileSystem.GetFileStream(Path.Combine(personDataPath, DataFileName), FileMode.Create, FileAccess.Write, FileShare.Read, true))
|
||||
{
|
||||
await json.CopyToAsync(fs).ConfigureAwait(false);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.IO;
|
||||
|
@ -15,10 +16,12 @@ namespace MediaBrowser.Providers.Music
|
|||
class ArtistProviderFromXml : BaseMetadataProvider
|
||||
{
|
||||
public static ArtistProviderFromXml Current;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
public ArtistProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager)
|
||||
public ArtistProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
Current = this;
|
||||
}
|
||||
|
||||
|
@ -51,7 +54,7 @@ namespace MediaBrowser.Providers.Music
|
|||
return false;
|
||||
}
|
||||
|
||||
return FileSystem.GetLastWriteTimeUtc(xml, Logger) > providerInfo.LastRefreshed;
|
||||
return _fileSystem.GetLastWriteTimeUtc(xml) > providerInfo.LastRefreshed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
|
@ -37,6 +38,7 @@ namespace MediaBrowser.Providers.Music
|
|||
protected IHttpClient HttpClient { get; private set; }
|
||||
|
||||
internal static FanArtAlbumProvider Current { get; private set; }
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FanArtAlbumProvider"/> class.
|
||||
|
@ -45,10 +47,11 @@ namespace MediaBrowser.Providers.Music
|
|||
/// <param name="logManager">The log manager.</param>
|
||||
/// <param name="configurationManager">The configuration manager.</param>
|
||||
/// <param name="providerManager">The provider manager.</param>
|
||||
public FanArtAlbumProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager)
|
||||
public FanArtAlbumProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager, IFileSystem fileSystem)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
_providerManager = providerManager;
|
||||
_fileSystem = fileSystem;
|
||||
HttpClient = httpClient;
|
||||
|
||||
Current = this;
|
||||
|
@ -140,7 +143,7 @@ namespace MediaBrowser.Providers.Music
|
|||
|
||||
if (file.Exists)
|
||||
{
|
||||
return file.LastWriteTimeUtc;
|
||||
return _fileSystem.GetLastWriteTimeUtc(file);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
||||
|
@ -15,12 +17,8 @@ namespace MediaBrowser.Providers.Music
|
|||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FanArtArtistByNameProvider" /> class.
|
||||
/// </summary>
|
||||
/// <param name="httpClient">The HTTP client.</param>
|
||||
/// <param name="logManager">The log manager.</param>
|
||||
/// <param name="configurationManager">The configuration manager.</param>
|
||||
/// <param name="providerManager">The provider manager.</param>
|
||||
public FanArtArtistByNameProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager)
|
||||
: base(httpClient, logManager, configurationManager, providerManager)
|
||||
public FanArtArtistByNameProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager, IFileSystem fileSystem)
|
||||
: base(httpClient, logManager, configurationManager, providerManager, fileSystem)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -1,24 +1,23 @@
|
|||
using System.Net;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Net;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using MediaBrowser.Model.Net;
|
||||
|
||||
namespace MediaBrowser.Providers.Music
|
||||
{
|
||||
|
@ -39,6 +38,7 @@ namespace MediaBrowser.Providers.Music
|
|||
private readonly IProviderManager _providerManager;
|
||||
|
||||
internal static FanArtArtistProvider Current;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FanArtArtistProvider"/> class.
|
||||
|
@ -48,7 +48,7 @@ namespace MediaBrowser.Providers.Music
|
|||
/// <param name="configurationManager">The configuration manager.</param>
|
||||
/// <param name="providerManager">The provider manager.</param>
|
||||
/// <exception cref="System.ArgumentNullException">httpClient</exception>
|
||||
public FanArtArtistProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager)
|
||||
public FanArtArtistProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager, IFileSystem fileSystem)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
if (httpClient == null)
|
||||
|
@ -57,6 +57,7 @@ namespace MediaBrowser.Providers.Music
|
|||
}
|
||||
HttpClient = httpClient;
|
||||
_providerManager = providerManager;
|
||||
_fileSystem = fileSystem;
|
||||
|
||||
Current = this;
|
||||
}
|
||||
|
@ -167,7 +168,7 @@ namespace MediaBrowser.Providers.Music
|
|||
{
|
||||
var files = new DirectoryInfo(path)
|
||||
.EnumerateFiles("*.xml", SearchOption.TopDirectoryOnly)
|
||||
.Select(i => i.LastWriteTimeUtc)
|
||||
.Select(i => _fileSystem.GetLastWriteTimeUtc(i))
|
||||
.ToList();
|
||||
|
||||
if (files.Count > 0)
|
||||
|
@ -284,7 +285,7 @@ namespace MediaBrowser.Providers.Music
|
|||
|
||||
}).ConfigureAwait(false))
|
||||
{
|
||||
using (var xmlFileStream = new FileStream(xmlPath, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous))
|
||||
using (var xmlFileStream = _fileSystem.GetFileStream(xmlPath, FileMode.Create, FileAccess.Write, FileShare.Read, true))
|
||||
{
|
||||
await response.CopyToAsync(xmlFileStream).ConfigureAwait(false);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
@ -31,15 +32,17 @@ namespace MediaBrowser.Providers.Music
|
|||
/// </summary>
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
public FanArtUpdatesPrescanTask(IJsonSerializer jsonSerializer, IServerConfigurationManager config, ILogger logger, IHttpClient httpClient)
|
||||
public FanArtUpdatesPrescanTask(IJsonSerializer jsonSerializer, IServerConfigurationManager config, ILogger logger, IHttpClient httpClient, IFileSystem fileSystem)
|
||||
{
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_config = config;
|
||||
_logger = logger;
|
||||
_httpClient = httpClient;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -65,7 +68,7 @@ namespace MediaBrowser.Providers.Music
|
|||
var timestampFileInfo = new FileInfo(timestampFile);
|
||||
|
||||
// Don't check for tvdb updates anymore frequently than 24 hours
|
||||
if (timestampFileInfo.Exists && (DateTime.UtcNow - timestampFileInfo.LastWriteTimeUtc).TotalDays < 1)
|
||||
if (timestampFileInfo.Exists && (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(timestampFileInfo)).TotalDays < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System;
|
||||
|
@ -22,15 +23,18 @@ namespace MediaBrowser.Providers
|
|||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RefreshIntrosTask"/> class.
|
||||
/// </summary>
|
||||
/// <param name="libraryManager">The library manager.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
public RefreshIntrosTask(ILibraryManager libraryManager, ILogger logger)
|
||||
public RefreshIntrosTask(ILibraryManager libraryManager, ILogger logger, IFileSystem fileSystem)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
_logger = logger;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -77,7 +81,7 @@ namespace MediaBrowser.Providers
|
|||
/// <returns>Task.</returns>
|
||||
private async Task RefreshIntro(string path, CancellationToken cancellationToken)
|
||||
{
|
||||
var item = _libraryManager.ResolvePath(FileSystem.GetFileSystemInfo(path));
|
||||
var item = _libraryManager.ResolvePath(_fileSystem.GetFileSystemInfo(path));
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Providers.Movies;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -70,6 +71,20 @@ namespace MediaBrowser.Providers.Savers
|
|||
builder.Append("<GameSystem>" + SecurityElement.Escape(game.GameSystem) + "</GameSystem>");
|
||||
}
|
||||
|
||||
var val = game.GetProviderId(MetadataProviders.NesBox);
|
||||
|
||||
if (!string.IsNullOrEmpty(val))
|
||||
{
|
||||
builder.Append("<NesBox>" + SecurityElement.Escape(val) + "</NesBox>");
|
||||
}
|
||||
|
||||
val = game.GetProviderId(MetadataProviders.NesBoxRom);
|
||||
|
||||
if (!string.IsNullOrEmpty(val))
|
||||
{
|
||||
builder.Append("<NesBoxRom>" + SecurityElement.Escape(val) + "</NesBoxRom>");
|
||||
}
|
||||
|
||||
XmlSaverHelpers.AddCommonNodes(item, builder);
|
||||
|
||||
builder.Append("</Item>");
|
||||
|
@ -79,7 +94,9 @@ namespace MediaBrowser.Providers.Savers
|
|||
XmlSaverHelpers.Save(builder, xmlFilePath, new List<string>
|
||||
{
|
||||
"Players",
|
||||
"GameSystem"
|
||||
"GameSystem",
|
||||
"NesBox",
|
||||
"NesBoxRom"
|
||||
});
|
||||
|
||||
// Set last refreshed so that the provider doesn't trigger after the file save
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.IO;
|
||||
|
@ -20,11 +21,13 @@ namespace MediaBrowser.Providers.TV
|
|||
{
|
||||
internal static EpisodeProviderFromXml Current { get; private set; }
|
||||
private readonly IItemRepository _itemRepo;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
public EpisodeProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager, IItemRepository itemRepo)
|
||||
public EpisodeProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager, IItemRepository itemRepo, IFileSystem fileSystem)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
_itemRepo = itemRepo;
|
||||
_fileSystem = fileSystem;
|
||||
Current = this;
|
||||
}
|
||||
|
||||
|
@ -76,7 +79,7 @@ namespace MediaBrowser.Providers.TV
|
|||
return false;
|
||||
}
|
||||
|
||||
return FileSystem.GetLastWriteTimeUtc(file, Logger) > providerInfo.LastRefreshed;
|
||||
return _fileSystem.GetLastWriteTimeUtc(file) > providerInfo.LastRefreshed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
|
@ -22,6 +23,7 @@ namespace MediaBrowser.Providers.TV
|
|||
/// The _provider manager
|
||||
/// </summary>
|
||||
private readonly IProviderManager _providerManager;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FanArtSeasonProvider"/> class.
|
||||
|
@ -29,10 +31,11 @@ namespace MediaBrowser.Providers.TV
|
|||
/// <param name="logManager">The log manager.</param>
|
||||
/// <param name="configurationManager">The configuration manager.</param>
|
||||
/// <param name="providerManager">The provider manager.</param>
|
||||
public FanArtSeasonProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager)
|
||||
public FanArtSeasonProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager, IFileSystem fileSystem)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
_providerManager = providerManager;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
public override ItemUpdateType ItemUpdateType
|
||||
|
@ -76,7 +79,7 @@ namespace MediaBrowser.Providers.TV
|
|||
|
||||
if (imagesFileInfo.Exists)
|
||||
{
|
||||
return imagesFileInfo.LastWriteTimeUtc;
|
||||
return _fileSystem.GetLastWriteTimeUtc(imagesFileInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ using MediaBrowser.Common.Net;
|
|||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
@ -31,8 +32,9 @@ namespace MediaBrowser.Providers.TV
|
|||
protected IHttpClient HttpClient { get; private set; }
|
||||
|
||||
private readonly IProviderManager _providerManager;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
public FanArtTvProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager)
|
||||
public FanArtTvProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager, IFileSystem fileSystem)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
if (httpClient == null)
|
||||
|
@ -41,6 +43,7 @@ namespace MediaBrowser.Providers.TV
|
|||
}
|
||||
HttpClient = httpClient;
|
||||
_providerManager = providerManager;
|
||||
_fileSystem = fileSystem;
|
||||
Current = this;
|
||||
}
|
||||
|
||||
|
@ -115,7 +118,7 @@ namespace MediaBrowser.Providers.TV
|
|||
{
|
||||
var files = new DirectoryInfo(path)
|
||||
.EnumerateFiles("*.xml", SearchOption.TopDirectoryOnly)
|
||||
.Select(i => i.LastWriteTimeUtc)
|
||||
.Select(i => _fileSystem.GetLastWriteTimeUtc(i))
|
||||
.ToList();
|
||||
|
||||
if (files.Count > 0)
|
||||
|
@ -353,7 +356,7 @@ namespace MediaBrowser.Providers.TV
|
|||
|
||||
}).ConfigureAwait(false))
|
||||
{
|
||||
using (var xmlFileStream = new FileStream(xmlPath, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous))
|
||||
using (var xmlFileStream = _fileSystem.GetFileStream(xmlPath, FileMode.Create, FileAccess.Write, FileShare.Read, true))
|
||||
{
|
||||
await response.CopyToAsync(xmlFileStream).ConfigureAwait(false);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
@ -32,15 +33,17 @@ namespace MediaBrowser.Providers.TV
|
|||
/// </summary>
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
public FanArtTvUpdatesPrescanTask(IJsonSerializer jsonSerializer, IServerConfigurationManager config, ILogger logger, IHttpClient httpClient)
|
||||
public FanArtTvUpdatesPrescanTask(IJsonSerializer jsonSerializer, IServerConfigurationManager config, ILogger logger, IHttpClient httpClient, IFileSystem fileSystem)
|
||||
{
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_config = config;
|
||||
_logger = logger;
|
||||
_httpClient = httpClient;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -66,7 +69,7 @@ namespace MediaBrowser.Providers.TV
|
|||
var timestampFileInfo = new FileInfo(timestampFile);
|
||||
|
||||
// Don't check for tvdb updates anymore frequently than 24 hours
|
||||
if (timestampFileInfo.Exists && (DateTime.UtcNow - timestampFileInfo.LastWriteTimeUtc).TotalDays < 1)
|
||||
if (timestampFileInfo.Exists && (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(timestampFileInfo)).TotalDays < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
|
@ -36,6 +37,7 @@ namespace MediaBrowser.Providers.TV
|
|||
/// </summary>
|
||||
/// <value>The HTTP client.</value>
|
||||
protected IHttpClient HttpClient { get; private set; }
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RemoteEpisodeProvider" /> class.
|
||||
|
@ -44,11 +46,12 @@ namespace MediaBrowser.Providers.TV
|
|||
/// <param name="logManager">The log manager.</param>
|
||||
/// <param name="configurationManager">The configuration manager.</param>
|
||||
/// <param name="providerManager">The provider manager.</param>
|
||||
public RemoteEpisodeProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager)
|
||||
public RemoteEpisodeProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager, IFileSystem fileSystem)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
HttpClient = httpClient;
|
||||
_providerManager = providerManager;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -149,7 +152,7 @@ namespace MediaBrowser.Providers.TV
|
|||
|
||||
if (files.Count > 0)
|
||||
{
|
||||
return files.Select(i => i.LastWriteTimeUtc).Max() > providerInfo.LastRefreshed;
|
||||
return files.Select(i => _fileSystem.GetLastWriteTimeUtc(i)).Max() > providerInfo.LastRefreshed;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -240,17 +243,16 @@ namespace MediaBrowser.Providers.TV
|
|||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var status = ProviderRefreshStatus.Success;
|
||||
|
||||
var episode = (Episode)item;
|
||||
|
||||
var seriesId = episode.Series != null ? episode.Series.GetProviderId(MetadataProviders.Tvdb) : null;
|
||||
|
||||
if (!string.IsNullOrEmpty(seriesId))
|
||||
{
|
||||
var seriesDataPath = RemoteSeriesProvider.GetSeriesDataPath(ConfigurationManager.ApplicationPaths,
|
||||
seriesId);
|
||||
var seriesDataPath = RemoteSeriesProvider.GetSeriesDataPath(ConfigurationManager.ApplicationPaths, seriesId);
|
||||
|
||||
var status = ProviderRefreshStatus.Success;
|
||||
|
||||
try
|
||||
{
|
||||
status = await FetchEpisodeData(episode, seriesDataPath, cancellationToken).ConfigureAwait(false);
|
||||
|
@ -259,20 +261,10 @@ namespace MediaBrowser.Providers.TV
|
|||
{
|
||||
// Don't fail the provider because this will just keep on going and going.
|
||||
}
|
||||
|
||||
BaseProviderInfo data;
|
||||
if (!item.ProviderData.TryGetValue(Id, out data))
|
||||
{
|
||||
data = new BaseProviderInfo();
|
||||
item.ProviderData[Id] = data;
|
||||
}
|
||||
|
||||
SetLastRefreshed(item, DateTime.UtcNow, status);
|
||||
return true;
|
||||
}
|
||||
|
||||
Logger.Info("Episode provider not fetching because series does not have a tvdb id: " + item.Path);
|
||||
return false;
|
||||
SetLastRefreshed(item, DateTime.UtcNow, status);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
|
@ -23,6 +24,7 @@ namespace MediaBrowser.Providers.TV
|
|||
/// The _provider manager
|
||||
/// </summary>
|
||||
private readonly IProviderManager _providerManager;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RemoteSeasonProvider"/> class.
|
||||
|
@ -31,10 +33,11 @@ namespace MediaBrowser.Providers.TV
|
|||
/// <param name="configurationManager">The configuration manager.</param>
|
||||
/// <param name="providerManager">The provider manager.</param>
|
||||
/// <exception cref="System.ArgumentNullException">httpClient</exception>
|
||||
public RemoteSeasonProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager)
|
||||
public RemoteSeasonProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager, IFileSystem fileSystem)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
_providerManager = providerManager;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -115,7 +118,7 @@ namespace MediaBrowser.Providers.TV
|
|||
|
||||
if (imagesFileInfo.Exists)
|
||||
{
|
||||
return imagesFileInfo.LastWriteTimeUtc > providerInfo.LastRefreshed;
|
||||
return _fileSystem.GetLastWriteTimeUtc(imagesFileInfo) > providerInfo.LastRefreshed;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -275,6 +278,7 @@ namespace MediaBrowser.Providers.TV
|
|||
string url = null;
|
||||
int? bannerSeason = null;
|
||||
string resolution = null;
|
||||
string language = null;
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
|
@ -282,6 +286,12 @@ namespace MediaBrowser.Providers.TV
|
|||
{
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "Language":
|
||||
{
|
||||
language = reader.ReadElementContentAsString() ?? string.Empty;
|
||||
break;
|
||||
}
|
||||
|
||||
case "BannerType":
|
||||
{
|
||||
bannerType = reader.ReadElementContentAsString() ?? string.Empty;
|
||||
|
@ -325,11 +335,30 @@ namespace MediaBrowser.Providers.TV
|
|||
{
|
||||
if (string.Equals(bannerType2, "season", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
data.Poster = url;
|
||||
// Just grab the first
|
||||
if (string.IsNullOrWhiteSpace(data.Poster))
|
||||
{
|
||||
data.Poster = url;
|
||||
}
|
||||
}
|
||||
else if (string.Equals(bannerType2, "seasonwide", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
data.Banner = url;
|
||||
if (string.IsNullOrWhiteSpace(language) || string.Equals(language, "en", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// Just grab the first
|
||||
if (string.IsNullOrWhiteSpace(data.Banner))
|
||||
{
|
||||
data.Banner = url;
|
||||
}
|
||||
}
|
||||
else if (string.Equals(language, ConfigurationManager.Configuration.PreferredMetadataLanguage, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// Just grab the first
|
||||
if (string.IsNullOrWhiteSpace(data.LanguageBanner))
|
||||
{
|
||||
data.LanguageBanner = url;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (string.Equals(bannerType, "fanart", StringComparison.OrdinalIgnoreCase))
|
||||
|
|
|
@ -4,6 +4,7 @@ using MediaBrowser.Common.Net;
|
|||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
@ -49,6 +50,8 @@ namespace MediaBrowser.Providers.TV
|
|||
/// <value>The HTTP client.</value>
|
||||
protected IHttpClient HttpClient { get; private set; }
|
||||
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RemoteSeriesProvider" /> class.
|
||||
/// </summary>
|
||||
|
@ -57,7 +60,7 @@ namespace MediaBrowser.Providers.TV
|
|||
/// <param name="configurationManager">The configuration manager.</param>
|
||||
/// <param name="zipClient">The zip client.</param>
|
||||
/// <exception cref="System.ArgumentNullException">httpClient</exception>
|
||||
public RemoteSeriesProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IZipClient zipClient)
|
||||
public RemoteSeriesProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IZipClient zipClient, IFileSystem fileSystem)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
if (httpClient == null)
|
||||
|
@ -66,6 +69,7 @@ namespace MediaBrowser.Providers.TV
|
|||
}
|
||||
HttpClient = httpClient;
|
||||
_zipClient = zipClient;
|
||||
_fileSystem = fileSystem;
|
||||
Current = this;
|
||||
}
|
||||
|
||||
|
@ -176,7 +180,7 @@ namespace MediaBrowser.Providers.TV
|
|||
{
|
||||
var files = new DirectoryInfo(path)
|
||||
.EnumerateFiles("*.xml", SearchOption.TopDirectoryOnly)
|
||||
.Select(i => i.LastWriteTimeUtc)
|
||||
.Select(i => _fileSystem.GetLastWriteTimeUtc(i))
|
||||
.ToList();
|
||||
|
||||
if (files.Count > 0)
|
||||
|
@ -344,7 +348,7 @@ namespace MediaBrowser.Providers.TV
|
|||
{
|
||||
string validXml;
|
||||
|
||||
using (var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, true))
|
||||
using (var fileStream = _fileSystem.GetFileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read, true))
|
||||
{
|
||||
using (var reader = new StreamReader(fileStream))
|
||||
{
|
||||
|
@ -354,7 +358,7 @@ namespace MediaBrowser.Providers.TV
|
|||
}
|
||||
}
|
||||
|
||||
using (var fileStream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, true))
|
||||
using (var fileStream = _fileSystem.GetFileStream(file, FileMode.Create, FileAccess.Write, FileShare.Read, true))
|
||||
{
|
||||
using (var writer = new StreamWriter(fileStream))
|
||||
{
|
||||
|
@ -1109,21 +1113,37 @@ namespace MediaBrowser.Providers.TV
|
|||
var nodes = doc.SelectNodes("//Series");
|
||||
var comparableName = GetComparableName(name);
|
||||
if (nodes != null)
|
||||
{
|
||||
foreach (XmlNode node in nodes)
|
||||
{
|
||||
var n = node.SelectSingleNode("./SeriesName");
|
||||
if (n != null && string.Equals(GetComparableName(n.InnerText), comparableName, StringComparison.OrdinalIgnoreCase))
|
||||
var titles = new List<string>();
|
||||
|
||||
var nameNode = node.SelectSingleNode("./SeriesName");
|
||||
if (nameNode != null)
|
||||
{
|
||||
n = node.SelectSingleNode("./seriesid");
|
||||
if (n != null)
|
||||
return n.InnerText;
|
||||
titles.Add(GetComparableName(nameNode.InnerText));
|
||||
}
|
||||
else
|
||||
|
||||
var aliasNode = node.SelectSingleNode("./AliasNames");
|
||||
if (aliasNode != null)
|
||||
{
|
||||
if (n != null)
|
||||
Logger.Info("TVDb Provider - " + n.InnerText + " did not match " + comparableName);
|
||||
var alias = aliasNode.InnerText.Split('|').Select(GetComparableName);
|
||||
titles.AddRange(alias);
|
||||
}
|
||||
|
||||
if (titles.Any(t => string.Equals(t, comparableName, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
var id = node.SelectSingleNode("./seriesid");
|
||||
if (id != null)
|
||||
return id.InnerText;
|
||||
}
|
||||
|
||||
foreach (var title in titles)
|
||||
{
|
||||
Logger.Info("TVDb Provider - " + title + " did not match " + comparableName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try stripping off the year if it was supplied
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.IO;
|
||||
|
@ -18,10 +19,12 @@ namespace MediaBrowser.Providers.TV
|
|||
public class SeasonProviderFromXml : BaseMetadataProvider
|
||||
{
|
||||
public static SeasonProviderFromXml Current;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
public SeasonProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager)
|
||||
public SeasonProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
Current = this;
|
||||
}
|
||||
|
||||
|
@ -54,7 +57,7 @@ namespace MediaBrowser.Providers.TV
|
|||
return false;
|
||||
}
|
||||
|
||||
return FileSystem.GetLastWriteTimeUtc(xml, Logger) > providerInfo.LastRefreshed;
|
||||
return _fileSystem.GetLastWriteTimeUtc(xml) > providerInfo.LastRefreshed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -39,6 +39,13 @@ namespace MediaBrowser.Providers.TV
|
|||
|
||||
private async Task RunInternal(IProgress<double> progress, CancellationToken cancellationToken)
|
||||
{
|
||||
if (!_config.Configuration.EnableInternetProviders ||
|
||||
_config.Configuration.InternetProviderExcludeTypes.Contains(typeof(Series).Name, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
progress.Report(100);
|
||||
return;
|
||||
}
|
||||
|
||||
var seriesList = _libraryManager.RootFolder
|
||||
.RecursiveChildren
|
||||
.OfType<Series>()
|
||||
|
@ -136,21 +143,27 @@ namespace MediaBrowser.Providers.TV
|
|||
.Where(i => i.Item1 != -1 && i.Item2 != -1)
|
||||
.ToList();
|
||||
|
||||
var anySeasonsRemoved = await RemoveObsoleteOrMissingSeasons(series, episodeLookup, cancellationToken).ConfigureAwait(false);
|
||||
var anySeasonsRemoved = await RemoveObsoleteOrMissingSeasons(series, episodeLookup, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var anyEpisodesRemoved = await RemoveObsoleteOrMissingEpisodes(series, episodeLookup, cancellationToken).ConfigureAwait(false);
|
||||
var anyEpisodesRemoved = await RemoveObsoleteOrMissingEpisodes(series, episodeLookup, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var hasNewEpisodes = false;
|
||||
|
||||
if (_config.Configuration.EnableInternetProviders)
|
||||
{
|
||||
hasNewEpisodes = await AddMissingEpisodes(series, seriesDataPath, episodeLookup, cancellationToken).ConfigureAwait(false);
|
||||
hasNewEpisodes = await AddMissingEpisodes(series, seriesDataPath, episodeLookup, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (hasNewEpisodes || anySeasonsRemoved || anyEpisodesRemoved)
|
||||
{
|
||||
await series.RefreshMetadata(cancellationToken, true).ConfigureAwait(false);
|
||||
await series.ValidateChildren(new Progress<double>(), cancellationToken, true).ConfigureAwait(false);
|
||||
await series.RefreshMetadata(cancellationToken, true)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
await series.ValidateChildren(new Progress<double>(), cancellationToken, true)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -211,7 +224,7 @@ namespace MediaBrowser.Providers.TV
|
|||
else if (airDate.Value > now)
|
||||
{
|
||||
// tvdb has a lot of nearly blank episodes
|
||||
_logger.Info("Creating virtual future episode {0} {1}x{2}", series.Name, tuple.Item1, tuple.Item2);
|
||||
_logger.Info("Creating virtual unaired episode {0} {1}x{2}", series.Name, tuple.Item1, tuple.Item2);
|
||||
|
||||
await AddEpisode(series, tuple.Item1, tuple.Item2, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.IO;
|
||||
|
@ -18,10 +19,12 @@ namespace MediaBrowser.Providers.TV
|
|||
public class SeriesProviderFromXml : BaseMetadataProvider
|
||||
{
|
||||
internal static SeriesProviderFromXml Current { get; private set; }
|
||||
|
||||
public SeriesProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager)
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
public SeriesProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
Current = this;
|
||||
}
|
||||
|
||||
|
@ -54,7 +57,7 @@ namespace MediaBrowser.Providers.TV
|
|||
return false;
|
||||
}
|
||||
|
||||
return FileSystem.GetLastWriteTimeUtc(xml, Logger) > providerInfo.LastRefreshed;
|
||||
return _fileSystem.GetLastWriteTimeUtc(xml) > providerInfo.LastRefreshed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
using System.Globalization;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Net;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
@ -42,6 +44,7 @@ namespace MediaBrowser.Providers.TV
|
|||
/// The _config
|
||||
/// </summary>
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TvdbPrescanTask"/> class.
|
||||
|
@ -49,11 +52,12 @@ namespace MediaBrowser.Providers.TV
|
|||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="httpClient">The HTTP client.</param>
|
||||
/// <param name="config">The config.</param>
|
||||
public TvdbPrescanTask(ILogger logger, IHttpClient httpClient, IServerConfigurationManager config)
|
||||
public TvdbPrescanTask(ILogger logger, IHttpClient httpClient, IServerConfigurationManager config, IFileSystem fileSystem)
|
||||
{
|
||||
_logger = logger;
|
||||
_httpClient = httpClient;
|
||||
_config = config;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
@ -66,7 +70,8 @@ namespace MediaBrowser.Providers.TV
|
|||
/// <returns>Task.</returns>
|
||||
public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
||||
{
|
||||
if (!_config.Configuration.EnableInternetProviders)
|
||||
if (!_config.Configuration.EnableInternetProviders ||
|
||||
_config.Configuration.InternetProviderExcludeTypes.Contains(typeof(Series).Name, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
progress.Report(100);
|
||||
return;
|
||||
|
@ -81,7 +86,7 @@ namespace MediaBrowser.Providers.TV
|
|||
var timestampFileInfo = new FileInfo(timestampFile);
|
||||
|
||||
// Don't check for tvdb updates anymore frequently than 24 hours
|
||||
if (timestampFileInfo.Exists && (DateTime.UtcNow - timestampFileInfo.LastWriteTimeUtc).TotalDays < 1)
|
||||
if (timestampFileInfo.Exists && (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(timestampFileInfo)).TotalDays < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
using System.Linq;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
@ -11,6 +12,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -30,6 +32,7 @@ namespace MediaBrowser.Providers.TV
|
|||
/// The _provider manager
|
||||
/// </summary>
|
||||
private readonly IProviderManager _providerManager;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TvdbSeriesImageProvider"/> class.
|
||||
|
@ -39,7 +42,7 @@ namespace MediaBrowser.Providers.TV
|
|||
/// <param name="configurationManager">The configuration manager.</param>
|
||||
/// <param name="providerManager">The provider manager.</param>
|
||||
/// <exception cref="System.ArgumentNullException">httpClient</exception>
|
||||
public TvdbSeriesImageProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager)
|
||||
public TvdbSeriesImageProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager, IFileSystem fileSystem)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
if (httpClient == null)
|
||||
|
@ -48,6 +51,7 @@ namespace MediaBrowser.Providers.TV
|
|||
}
|
||||
HttpClient = httpClient;
|
||||
_providerManager = providerManager;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -127,7 +131,7 @@ namespace MediaBrowser.Providers.TV
|
|||
|
||||
if (imagesFileInfo.Exists)
|
||||
{
|
||||
return imagesFileInfo.LastWriteTimeUtc;
|
||||
return _fileSystem.GetLastWriteTimeUtc(imagesFileInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -373,11 +377,19 @@ namespace MediaBrowser.Providers.TV
|
|||
{
|
||||
if (string.Equals(type, "poster", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
data.Poster = url;
|
||||
// Just grab the first
|
||||
if (string.IsNullOrWhiteSpace(data.Poster))
|
||||
{
|
||||
data.Poster = url;
|
||||
}
|
||||
}
|
||||
else if (string.Equals(type, "series", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
data.Banner = url;
|
||||
// Just grab the first
|
||||
if (string.IsNullOrWhiteSpace(data.Banner))
|
||||
{
|
||||
data.Banner = url;
|
||||
}
|
||||
}
|
||||
else if (string.Equals(type, "fanart", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
|
|
|
@ -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>
|
21
MediaBrowser.Server.Mono/IO/FileSystemFactory.cs
Normal file
21
MediaBrowser.Server.Mono/IO/FileSystemFactory.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Common.Implementations.IO;
|
||||
|
||||
namespace MediaBrowser.ServerApplication.IO
|
||||
{
|
||||
/// <summary>
|
||||
/// Class FileSystemFactory
|
||||
/// </summary>
|
||||
public static class FileSystemFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates the file system manager.
|
||||
/// </summary>
|
||||
/// <returns>IFileSystem.</returns>
|
||||
public static IFileSystem CreateFileSystemManager(ILogManager logManager)
|
||||
{
|
||||
return new CommonFileSystem(logManager.GetLogger("FileSystem"), false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -88,6 +88,7 @@
|
|||
<Link>FFMpeg\FFMpegDownloader.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="FFMpeg\FFMpegDownloadInfo.cs" />
|
||||
<Compile Include="IO\FileSystemFactory.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ItemGroup>
|
||||
|
@ -129,6 +130,7 @@
|
|||
<Folder Include="Native\" />
|
||||
<Folder Include="FFMpeg\" />
|
||||
<Folder Include="Networking\" />
|
||||
<Folder Include="IO\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
|
|
|
@ -17,6 +17,7 @@ using System.Security.Cryptography.X509Certificates;
|
|||
using Gtk;
|
||||
using Gdk;
|
||||
using System.Threading.Tasks;
|
||||
using System.Reflection;
|
||||
|
||||
namespace MediaBrowser.Server.Mono
|
||||
{
|
||||
|
@ -203,6 +204,8 @@ namespace MediaBrowser.Server.Mono
|
|||
|
||||
logger.Info("Server: {0}", Environment.MachineName);
|
||||
logger.Info("Operating system: {0}", Environment.OSVersion.ToString());
|
||||
|
||||
MonoBug11817WorkAround.Apply ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -280,4 +283,34 @@ namespace MediaBrowser.Server.Mono
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public class MonoBug11817WorkAround
|
||||
{
|
||||
public static void Apply()
|
||||
{
|
||||
var property = typeof(TimeZoneInfo).GetProperty("TimeZoneDirectory", BindingFlags.Static | BindingFlags.NonPublic);
|
||||
|
||||
if (property == null) return;
|
||||
|
||||
var zoneInfo = FindZoneInfoFolder();
|
||||
property.SetValue(null, zoneInfo, new object[0]);
|
||||
}
|
||||
|
||||
public static string FindZoneInfoFolder()
|
||||
{
|
||||
var current = new DirectoryInfo(Directory.GetCurrentDirectory());
|
||||
|
||||
while(current != null)
|
||||
{
|
||||
var zoneinfoTestPath = Path.Combine(current.FullName, "zoneinfo");
|
||||
|
||||
if (Directory.Exists(zoneinfoTestPath))
|
||||
return zoneinfoTestPath;
|
||||
|
||||
current = current.Parent;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user