aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2013-06-03 22:02:49 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2013-06-03 22:02:49 -0400
commit02fedead11f738c09e503c3bdc74e2dd98e21cc8 (patch)
tree5e32fb80c23fa910dbdd0cc6a8be6bf105abd631
parent08d9004d8f361aaf13756cab70fc659e5fbb775c (diff)
re-factored some file system access
-rw-r--r--MediaBrowser.Api/Images/ImageService.cs3
-rw-r--r--MediaBrowser.Api/Images/ImageWriter.cs5
-rw-r--r--MediaBrowser.Api/Playback/BaseStreamingService.cs14
-rw-r--r--MediaBrowser.Api/SimilarItemsHelper.cs27
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs75
-rw-r--r--MediaBrowser.Common/IO/FileSystemRepository.cs65
-rw-r--r--MediaBrowser.Controller/Drawing/ImageManager.cs112
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs1
-rw-r--r--MediaBrowser.Controller/Entities/User.cs26
-rw-r--r--MediaBrowser.Controller/MediaInfo/FFMpegManager.cs57
-rw-r--r--MediaBrowser.Controller/Providers/MediaInfo/AudioImageProvider.cs14
-rw-r--r--MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj3
-rw-r--r--MediaBrowser.Model/ApiClient/IApiClient.cs28
-rw-r--r--MediaBrowser.Model/MediaBrowser.Model.csproj1
-rw-r--r--MediaBrowser.Model/Querying/SimilarItemsQuery.cs29
-rw-r--r--MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs39
-rw-r--r--MediaBrowser.Server.Implementations/Providers/ProviderManager.cs15
-rw-r--r--MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs8
-rw-r--r--MediaBrowser.Server.Implementations/ScheduledTasks/ImageCleanupTask.cs21
-rw-r--r--MediaBrowser.Server.Implementations/ScheduledTasks/VideoImagesTask.cs16
-rw-r--r--MediaBrowser.Server.Implementations/Sqlite/SQLiteItemRepository.cs28
-rw-r--r--Nuget/MediaBrowser.Common.Internal.nuspec4
-rw-r--r--Nuget/MediaBrowser.Common.nuspec2
-rw-r--r--Nuget/MediaBrowser.Server.Core.nuspec4
24 files changed, 339 insertions, 258 deletions
diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs
index 68e7d0686..967c449c2 100644
--- a/MediaBrowser.Api/Images/ImageService.cs
+++ b/MediaBrowser.Api/Images/ImageService.cs
@@ -696,7 +696,8 @@ namespace MediaBrowser.Api.Images
Item = item,
Request = request,
CropWhiteSpace = request.Type == ImageType.Logo || request.Type == ImageType.Art,
- OriginalImageDateModified = originalFileImageDateModified
+ OriginalImageDateModified = originalFileImageDateModified,
+ Enhancers = supportedImageEnhancers
}, contentType);
}
diff --git a/MediaBrowser.Api/Images/ImageWriter.cs b/MediaBrowser.Api/Images/ImageWriter.cs
index c130364fb..e77a2f9b0 100644
--- a/MediaBrowser.Api/Images/ImageWriter.cs
+++ b/MediaBrowser.Api/Images/ImageWriter.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Controller;
using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Providers;
using ServiceStack.Service;
using ServiceStack.ServiceHost;
using System;
@@ -14,6 +15,8 @@ namespace MediaBrowser.Api.Images
/// </summary>
public class ImageWriter : IStreamWriter, IHasOptions
{
+ public List<IImageEnhancer> Enhancers;
+
/// <summary>
/// Gets or sets the request.
/// </summary>
@@ -67,7 +70,7 @@ namespace MediaBrowser.Api.Images
{
return Kernel.Instance.ImageManager.ProcessImage(Item, Request.Type, Request.Index ?? 0, CropWhiteSpace,
OriginalImageDateModified, responseStream, Request.Width, Request.Height, Request.MaxWidth,
- Request.MaxHeight, Request.Quality);
+ Request.MaxHeight, Request.Quality, Enhancers);
}
}
}
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index 8b07145de..9d5f73141 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -340,6 +340,13 @@ namespace MediaBrowser.Api.Playback
try
{
+ var parentPath = Path.GetDirectoryName(path);
+
+ if (!Directory.Exists(parentPath))
+ {
+ Directory.CreateDirectory(parentPath);
+ }
+
var task = MediaEncoder.ExtractTextSubtitle(inputPath, type, subtitleStream.Index, offset, path, CancellationToken.None);
Task.WaitAll(task);
@@ -371,6 +378,13 @@ namespace MediaBrowser.Api.Playback
{
try
{
+ var parentPath = Path.GetDirectoryName(path);
+
+ if (!Directory.Exists(parentPath))
+ {
+ Directory.CreateDirectory(parentPath);
+ }
+
var task = MediaEncoder.ConvertTextSubtitleToAss(subtitleStream.Path, path, offset, CancellationToken.None);
Task.WaitAll(task);
diff --git a/MediaBrowser.Api/SimilarItemsHelper.cs b/MediaBrowser.Api/SimilarItemsHelper.cs
index e64ccb11d..bd4aecd0d 100644
--- a/MediaBrowser.Api/SimilarItemsHelper.cs
+++ b/MediaBrowser.Api/SimilarItemsHelper.cs
@@ -1,6 +1,5 @@
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Entities;
@@ -38,6 +37,29 @@ namespace MediaBrowser.Api
/// <value>The limit.</value>
[ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int? Limit { get; set; }
+
+ /// <summary>
+ /// Fields to return within the items, in addition to basic information
+ /// </summary>
+ /// <value>The fields.</value>
+ [ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: AudioInfo, Budget, Chapters, CriticRatingSummary, DateCreated, DisplayMediaType, EndDate, Genres, HomePageUrl, ItemCounts, IndexOptions, Locations, MediaStreams, Overview, OverviewHtml, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SeriesInfo, SortName, Studios, Taglines, TrailerUrls, UserData", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
+ public string Fields { get; set; }
+
+ /// <summary>
+ /// Gets the item fields.
+ /// </summary>
+ /// <returns>IEnumerable{ItemFields}.</returns>
+ public IEnumerable<ItemFields> GetItemFields()
+ {
+ var val = Fields;
+
+ if (string.IsNullOrEmpty(val))
+ {
+ return new ItemFields[] { };
+ }
+
+ return val.Split(',').Select(v => (ItemFields)Enum.Parse(typeof(ItemFields), v, true));
+ }
}
/// <summary>
@@ -64,8 +86,7 @@ namespace MediaBrowser.Api
(request.UserId.HasValue ? user.RootFolder :
(Folder)libraryManager.RootFolder) : DtoBuilder.GetItemByClientId(request.Id, userManager, libraryManager, request.UserId);
- // Get everything
- var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
+ var fields = request.GetItemFields().ToList();
var dtoBuilder = new DtoBuilder(logger, libraryManager, userDataRepository);
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
index 94fb3ce86..ab6b3786d 100644
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
@@ -123,9 +123,14 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
{
try
{
- return JsonSerializer.DeserializeFromFile<TaskResult>(GetHistoryFilePath());
+ return JsonSerializer.DeserializeFromFile<TaskResult>(GetHistoryFilePath(false));
}
- catch (IOException)
+ catch (DirectoryNotFoundException)
+ {
+ // File doesn't exist. No biggie
+ return null;
+ }
+ catch (FileNotFoundException)
{
// File doesn't exist. No biggie
return null;
@@ -414,62 +419,45 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
}
/// <summary>
- /// The _scheduled tasks configuration directory
- /// </summary>
- private string _scheduledTasksConfigurationDirectory;
- /// <summary>
/// Gets the scheduled tasks configuration directory.
/// </summary>
- /// <value>The scheduled tasks configuration directory.</value>
- private string ScheduledTasksConfigurationDirectory
+ /// <param name="create">if set to <c>true</c> [create].</param>
+ /// <returns>System.String.</returns>
+ private string GetScheduledTasksConfigurationDirectory(bool create)
{
- get
- {
- if (_scheduledTasksConfigurationDirectory == null)
- {
- _scheduledTasksConfigurationDirectory = Path.Combine(ApplicationPaths.ConfigurationDirectoryPath, "ScheduledTasks");
+ var path = Path.Combine(ApplicationPaths.ConfigurationDirectoryPath, "ScheduledTasks");
- if (!Directory.Exists(_scheduledTasksConfigurationDirectory))
- {
- Directory.CreateDirectory(_scheduledTasksConfigurationDirectory);
- }
- }
- return _scheduledTasksConfigurationDirectory;
+ if (create && !Directory.Exists(path))
+ {
+ Directory.CreateDirectory(path);
}
+
+ return path;
}
/// <summary>
- /// The _scheduled tasks data directory
- /// </summary>
- private string _scheduledTasksDataDirectory;
- /// <summary>
/// Gets the scheduled tasks data directory.
/// </summary>
- /// <value>The scheduled tasks data directory.</value>
- private string ScheduledTasksDataDirectory
+ /// <param name="create">if set to <c>true</c> [create].</param>
+ /// <returns>System.String.</returns>
+ private string GetScheduledTasksDataDirectory(bool create)
{
- get
- {
- if (_scheduledTasksDataDirectory == null)
- {
- _scheduledTasksDataDirectory = Path.Combine(ApplicationPaths.DataPath, "ScheduledTasks");
+ var path = Path.Combine(ApplicationPaths.DataPath, "ScheduledTasks");
- if (!Directory.Exists(_scheduledTasksDataDirectory))
- {
- Directory.CreateDirectory(_scheduledTasksDataDirectory);
- }
- }
- return _scheduledTasksDataDirectory;
+ if (create && !Directory.Exists(path))
+ {
+ Directory.CreateDirectory(path);
}
+ return path;
}
/// <summary>
/// Gets the history file path.
/// </summary>
/// <value>The history file path.</value>
- private string GetHistoryFilePath()
+ private string GetHistoryFilePath(bool createDirectory)
{
- return Path.Combine(ScheduledTasksDataDirectory, Id + ".js");
+ return Path.Combine(GetScheduledTasksDataDirectory(createDirectory), Id + ".js");
}
/// <summary>
@@ -478,7 +466,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
/// <returns>System.String.</returns>
private string GetConfigurationFilePath()
{
- return Path.Combine(ScheduledTasksConfigurationDirectory, Id + ".js");
+ return Path.Combine(GetScheduledTasksConfigurationDirectory(false), Id + ".js");
}
/// <summary>
@@ -493,7 +481,12 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
.Select(ScheduledTaskHelpers.GetTrigger)
.ToList();
}
- catch (IOException)
+ catch (FileNotFoundException)
+ {
+ // File doesn't exist. No biggie. Return defaults.
+ return ScheduledTask.GetDefaultTriggers();
+ }
+ catch (DirectoryNotFoundException)
{
// File doesn't exist. No biggie. Return defaults.
return ScheduledTask.GetDefaultTriggers();
@@ -530,7 +523,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
Id = Id
};
- JsonSerializer.SerializeToFile(result, GetHistoryFilePath());
+ JsonSerializer.SerializeToFile(result, GetHistoryFilePath(true));
LastExecutionResult = result;
diff --git a/MediaBrowser.Common/IO/FileSystemRepository.cs b/MediaBrowser.Common/IO/FileSystemRepository.cs
index f2fa8ce54..07328d72d 100644
--- a/MediaBrowser.Common/IO/FileSystemRepository.cs
+++ b/MediaBrowser.Common/IO/FileSystemRepository.cs
@@ -1,6 +1,5 @@
using MediaBrowser.Common.Extensions;
using System;
-using System.Collections.Concurrent;
using System.IO;
namespace MediaBrowser.Common.IO
@@ -12,12 +11,6 @@ namespace MediaBrowser.Common.IO
public class FileSystemRepository
{
/// <summary>
- /// Contains the list of subfolders under the main directory
- /// The directory entry is created when the item is first added to the dictionary
- /// </summary>
- private readonly ConcurrentDictionary<string, string> _subFolderPaths = new ConcurrentDictionary<string, string>();
-
- /// <summary>
/// Gets or sets the path.
/// </summary>
/// <value>The path.</value>
@@ -36,18 +29,6 @@ namespace MediaBrowser.Common.IO
}
Path = path;
- Initialize();
- }
-
- /// <summary>
- /// Initializes this instance.
- /// </summary>
- protected void Initialize()
- {
- if (!Directory.Exists(Path))
- {
- Directory.CreateDirectory(Path);
- }
}
/// <summary>
@@ -56,17 +37,18 @@ namespace MediaBrowser.Common.IO
/// <param name="uniqueName">Name of the unique.</param>
/// <param name="fileExtension">The file extension.</param>
/// <returns>System.String.</returns>
- /// <exception cref="System.ArgumentNullException"></exception>
+ /// <exception cref="System.ArgumentNullException">
+ /// </exception>
public string GetResourcePath(string uniqueName, string fileExtension)
{
if (string.IsNullOrEmpty(uniqueName))
{
- throw new ArgumentNullException();
+ throw new ArgumentNullException("uniqueName");
}
if (string.IsNullOrEmpty(fileExtension))
{
- throw new ArgumentNullException();
+ throw new ArgumentNullException("fileExtension");
}
var filename = uniqueName.GetMD5() + fileExtension;
@@ -75,7 +57,7 @@ namespace MediaBrowser.Common.IO
}
/// <summary>
- /// Gets the full path of where a file should be stored within the repository
+ /// Gets the resource path.
/// </summary>
/// <param name="filename">The filename.</param>
/// <returns>System.String.</returns>
@@ -84,41 +66,14 @@ namespace MediaBrowser.Common.IO
{
if (string.IsNullOrEmpty(filename))
{
- throw new ArgumentNullException();
+ throw new ArgumentNullException("filename");
}
- return GetInternalResourcePath(filename);
- }
-
- /// <summary>
- /// Takes a filename and returns the full path of where it should be stored
- /// </summary>
- /// <param name="filename">The filename.</param>
- /// <returns>System.String.</returns>
- private string GetInternalResourcePath(string filename)
- {
var prefix = filename.Substring(0, 1);
- var folder = _subFolderPaths.GetOrAdd(prefix, GetCachePath);
-
- return System.IO.Path.Combine(folder, filename);
- }
-
- /// <summary>
- /// Creates a subfolder under the image cache directory and returns the full path
- /// </summary>
- /// <param name="prefix">The prefix.</param>
- /// <returns>System.String.</returns>
- private string GetCachePath(string prefix)
- {
var path = System.IO.Path.Combine(Path, prefix);
-
- if (!Directory.Exists(path))
- {
- Directory.CreateDirectory(path);
- }
-
- return path;
+
+ return System.IO.Path.Combine(path, filename);
}
/// <summary>
@@ -144,8 +99,8 @@ namespace MediaBrowser.Common.IO
{
throw new ArgumentNullException();
}
-
- return ContainsFilePath(GetInternalResourcePath(filename));
+
+ return ContainsFilePath(GetResourcePath(filename));
}
/// <summary>
diff --git a/MediaBrowser.Controller/Drawing/ImageManager.cs b/MediaBrowser.Controller/Drawing/ImageManager.cs
index b728fe71f..b8406438c 100644
--- a/MediaBrowser.Controller/Drawing/ImageManager.cs
+++ b/MediaBrowser.Controller/Drawing/ImageManager.cs
@@ -31,7 +31,7 @@ namespace MediaBrowser.Controller.Drawing
/// </summary>
/// <value>The image enhancers.</value>
public IEnumerable<IImageEnhancer> ImageEnhancers { get; set; }
-
+
/// <summary>
/// Gets the image size cache.
/// </summary>
@@ -106,9 +106,10 @@ namespace MediaBrowser.Controller.Drawing
/// <param name="maxWidth">Use if a max width is required. Aspect ratio will be preserved.</param>
/// <param name="maxHeight">Use if a max height is required. Aspect ratio will be preserved.</param>
/// <param name="quality">Quality level, from 0-100. Currently only applies to JPG. The default value should suffice.</param>
+ /// <param name="enhancers">The enhancers.</param>
/// <returns>Task.</returns>
/// <exception cref="System.ArgumentNullException">entity</exception>
- public async Task ProcessImage(BaseItem entity, ImageType imageType, int imageIndex, bool cropWhitespace, DateTime dateModified, Stream toStream, int? width, int? height, int? maxWidth, int? maxHeight, int? quality)
+ public async Task ProcessImage(BaseItem entity, ImageType imageType, int imageIndex, bool cropWhitespace, DateTime dateModified, Stream toStream, int? width, int? height, int? maxWidth, int? maxHeight, int? quality, List<IImageEnhancer> enhancers)
{
if (entity == null)
{
@@ -127,28 +128,13 @@ namespace MediaBrowser.Controller.Drawing
originalImagePath = await GetCroppedImage(originalImagePath, dateModified).ConfigureAwait(false);
}
- var supportedEnhancers = ImageEnhancers.Where(i =>
- {
- try
- {
- return i.Supports(entity, imageType);
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error in image enhancer: {0}", ex, i.GetType().Name);
-
- return false;
- }
-
- }).ToList();
-
// No enhancement - don't cache
- if (supportedEnhancers.Count > 0)
+ if (enhancers.Count > 0)
{
try
{
// Enhance if we have enhancers
- var ehnancedImagePath = await GetEnhancedImage(originalImagePath, dateModified, entity, imageType, imageIndex, supportedEnhancers).ConfigureAwait(false);
+ var ehnancedImagePath = await GetEnhancedImage(originalImagePath, dateModified, entity, imageType, imageIndex, enhancers).ConfigureAwait(false);
// If the path changed update dateModified
if (!ehnancedImagePath.Equals(originalImagePath, StringComparison.OrdinalIgnoreCase))
@@ -175,6 +161,19 @@ namespace MediaBrowser.Controller.Drawing
var cacheFilePath = GetCacheFilePath(originalImagePath, newSize, quality.Value, dateModified);
+ try
+ {
+ using (var fileStream = new FileStream(cacheFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous))
+ {
+ await fileStream.CopyToAsync(toStream).ConfigureAwait(false);
+ return;
+ }
+ }
+ catch (IOException)
+ {
+ // Cache file doesn't exist or is currently being written ro
+ }
+
var semaphore = GetLock(cacheFilePath);
await semaphore.WaitAsync().ConfigureAwait(false);
@@ -262,6 +261,13 @@ namespace MediaBrowser.Controller.Drawing
/// <param name="bytes">The bytes.</param>
private async Task CacheResizedImage(string cacheFilePath, byte[] bytes)
{
+ var parentPath = Path.GetDirectoryName(cacheFilePath);
+
+ if (!Directory.Exists(parentPath))
+ {
+ Directory.CreateDirectory(parentPath);
+ }
+
// Save to the cache location
using (var cacheFileStream = new FileStream(cacheFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous))
{
@@ -323,7 +329,7 @@ namespace MediaBrowser.Controller.Drawing
}
protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
-
+
/// <summary>
/// Gets the size of the image.
/// </summary>
@@ -335,25 +341,53 @@ namespace MediaBrowser.Controller.Drawing
// Now check the file system cache
var fullCachePath = ImageSizeCache.GetResourcePath(keyName, ".txt");
+ try
+ {
+ var result = File.ReadAllText(fullCachePath).Split('|').Select(i => double.Parse(i, UsCulture)).ToArray();
+
+ return new ImageSize { Width = result[0], Height = result[1] };
+ }
+ catch (IOException)
+ {
+ // Cache file doesn't exist or is currently being written to
+ }
+
var semaphore = GetLock(fullCachePath);
await semaphore.WaitAsync().ConfigureAwait(false);
try
{
- try
- {
- var result = File.ReadAllText(fullCachePath).Split('|').Select(i => double.Parse(i, UsCulture)).ToArray();
+ var result = File.ReadAllText(fullCachePath).Split('|').Select(i => double.Parse(i, UsCulture)).ToArray();
- return new ImageSize { Width = result[0], Height = result[1] };
- }
- catch (FileNotFoundException)
- {
- // Cache file doesn't exist no biggie
- }
+ return new ImageSize { Width = result[0], Height = result[1] };
+ }
+ catch (FileNotFoundException)
+ {
+ // Cache file doesn't exist no biggie
+ }
+ catch (DirectoryNotFoundException)
+ {
+ // Cache file doesn't exist no biggie
+ }
+ catch
+ {
+ semaphore.Release();
+
+ throw;
+ }
+ try
+ {
var size = await ImageHeader.GetDimensions(imagePath, _logger).ConfigureAwait(false);
+ var parentPath = Path.GetDirectoryName(fullCachePath);
+
+ if (!Directory.Exists(parentPath))
+ {
+ Directory.CreateDirectory(parentPath);
+ }
+
// Update the file system cache
File.WriteAllText(fullCachePath, size.Width.ToString(UsCulture) + @"|" + size.Height.ToString(UsCulture));
@@ -490,12 +524,12 @@ namespace MediaBrowser.Controller.Drawing
await semaphore.WaitAsync().ConfigureAwait(false);
// Check again in case of contention
- if (CroppedImageCache.ContainsFilePath(croppedImagePath))
+ if (File.Exists(croppedImagePath))
{
semaphore.Release();
return croppedImagePath;
}
-
+
try
{
using (var fileStream = new FileStream(originalImagePath, FileMode.Open, FileAccess.Read, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, true))
@@ -511,6 +545,13 @@ namespace MediaBrowser.Controller.Drawing
using (var croppedImage = originalImage.CropWhitespace())
{
+ var parentPath = Path.GetDirectoryName(croppedImagePath);
+
+ if (!Directory.Exists(parentPath))
+ {
+ Directory.CreateDirectory(parentPath);
+ }
+
using (var outputStream = new FileStream(croppedImagePath, FileMode.Create, FileAccess.Write, FileShare.Read))
{
croppedImage.Save(outputFormat, outputStream, 100);
@@ -568,7 +609,7 @@ namespace MediaBrowser.Controller.Drawing
await semaphore.WaitAsync().ConfigureAwait(false);
// Check again in case of contention
- if (EnhancedImageCache.ContainsFilePath(enhancedImagePath))
+ if (File.Exists(enhancedImagePath))
{
semaphore.Release();
return enhancedImagePath;
@@ -588,6 +629,13 @@ namespace MediaBrowser.Controller.Drawing
//Pass the image through registered enhancers
using (var newImage = await ExecuteImageEnhancers(supportedEnhancers, originalImage, item, imageType, imageIndex).ConfigureAwait(false))
{
+ var parentDirectory = Path.GetDirectoryName(enhancedImagePath);
+
+ if (!Directory.Exists(parentDirectory))
+ {
+ Directory.CreateDirectory(parentDirectory);
+ }
+
//And then save it in the cache
using (var outputStream = new FileStream(enhancedImagePath, FileMode.Create, FileAccess.Write, FileShare.Read))
{
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index ef1efd8af..f5aed6d21 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -304,7 +304,6 @@ namespace MediaBrowser.Controller.Entities
/// <summary>
/// We attach these to the item so that we only ever have to hit the file system once
/// (this includes the children of the containing folder)
- /// Use ResolveArgs.FileSystemDictionary to check for the existence of files instead of File.Exists
/// </summary>
/// <value>The resolve args.</value>
[IgnoreDataMember]
diff --git a/MediaBrowser.Controller/Entities/User.cs b/MediaBrowser.Controller/Entities/User.cs
index e186119d6..65884332a 100644
--- a/MediaBrowser.Controller/Entities/User.cs
+++ b/MediaBrowser.Controller/Entities/User.cs
@@ -20,10 +20,6 @@ namespace MediaBrowser.Controller.Entities
public static IXmlSerializer XmlSerializer { get; set; }
/// <summary>
- /// The _root folder path
- /// </summary>
- private string _rootFolderPath;
- /// <summary>
/// Gets the root folder path.
/// </summary>
/// <value>The root folder path.</value>
@@ -32,23 +28,19 @@ namespace MediaBrowser.Controller.Entities
{
get
{
- if (_rootFolderPath == null)
+ if (Configuration.UseCustomLibrary)
{
- if (Configuration.UseCustomLibrary)
- {
- _rootFolderPath = GetRootFolderPath(Name);
+ var rootFolderPath = GetRootFolderPath(Name);
- if (!Directory.Exists(_rootFolderPath))
- {
- Directory.CreateDirectory(_rootFolderPath);
- }
- }
- else
+ if (!Directory.Exists(rootFolderPath))
{
- _rootFolderPath = ConfigurationManager.ApplicationPaths.DefaultUserViewsPath;
+ Directory.CreateDirectory(rootFolderPath);
}
+
+ return rootFolderPath;
}
- return _rootFolderPath;
+
+ return ConfigurationManager.ApplicationPaths.DefaultUserViewsPath;
}
}
@@ -261,7 +253,6 @@ namespace MediaBrowser.Controller.Entities
// Force these to be lazy loaded again
_configurationDirectoryPath = null;
- _rootFolderPath = null;
RootFolder = null;
// Kick off a task to validate the media library
@@ -378,7 +369,6 @@ namespace MediaBrowser.Controller.Entities
// Force these to be lazy loaded again
if (customLibraryChanged)
{
- _rootFolderPath = null;
RootFolder = null;
}
}
diff --git a/MediaBrowser.Controller/MediaInfo/FFMpegManager.cs b/MediaBrowser.Controller/MediaInfo/FFMpegManager.cs
index 111f5aff8..91359cd29 100644
--- a/MediaBrowser.Controller/MediaInfo/FFMpegManager.cs
+++ b/MediaBrowser.Controller/MediaInfo/FFMpegManager.cs
@@ -56,10 +56,6 @@ namespace MediaBrowser.Controller.MediaInfo
}
/// <summary>
- /// The _video images data path
- /// </summary>
- private string _videoImagesDataPath;
- /// <summary>
/// Gets the video images data path.
/// </summary>
/// <value>The video images data path.</value>
@@ -67,25 +63,11 @@ namespace MediaBrowser.Controller.MediaInfo
{
get
{
- if (_videoImagesDataPath == null)
- {
- _videoImagesDataPath = Path.Combine(_appPaths.DataPath, "extracted-video-images");
-
- if (!Directory.Exists(_videoImagesDataPath))
- {
- Directory.CreateDirectory(_videoImagesDataPath);
- }
- }
-
- return _videoImagesDataPath;
+ return Path.Combine(_appPaths.DataPath, "extracted-video-images");
}
}
/// <summary>
- /// The _audio images data path
- /// </summary>
- private string _audioImagesDataPath;
- /// <summary>
/// Gets the audio images data path.
/// </summary>
/// <value>The audio images data path.</value>
@@ -93,25 +75,11 @@ namespace MediaBrowser.Controller.MediaInfo
{
get
{
- if (_audioImagesDataPath == null)
- {
- _audioImagesDataPath = Path.Combine(_appPaths.DataPath, "extracted-audio-images");
-
- if (!Directory.Exists(_audioImagesDataPath))
- {
- Directory.CreateDirectory(_audioImagesDataPath);
- }
- }
-
- return _audioImagesDataPath;
+ return Path.Combine(_appPaths.DataPath, "extracted-audio-images");
}
}
/// <summary>
- /// The _subtitle cache path
- /// </summary>
- private string _subtitleCachePath;
- /// <summary>
/// Gets the subtitle cache path.
/// </summary>
/// <value>The subtitle cache path.</value>
@@ -119,17 +87,7 @@ namespace MediaBrowser.Controller.MediaInfo
{
get
{
- if (_subtitleCachePath == null)
- {
- _subtitleCachePath = Path.Combine(_appPaths.CachePath, "subtitles");
-
- if (!Directory.Exists(_subtitleCachePath))
- {
- Directory.CreateDirectory(_subtitleCachePath);
- }
- }
-
- return _subtitleCachePath;
+ return Path.Combine(_appPaths.CachePath, "subtitles");
}
}
@@ -177,7 +135,7 @@ namespace MediaBrowser.Controller.MediaInfo
var path = VideoImageCache.GetResourcePath(filename, ".jpg");
- if (!VideoImageCache.ContainsFilePath(path))
+ if (!File.Exists(path))
{
if (extractImages)
{
@@ -204,6 +162,13 @@ namespace MediaBrowser.Controller.MediaInfo
try
{
+ var parentPath = Path.GetDirectoryName(path);
+
+ if (!Directory.Exists(parentPath))
+ {
+ Directory.CreateDirectory(parentPath);
+ }
+
await _encoder.ExtractImage(inputPath, type, time, path, cancellationToken).ConfigureAwait(false);
chapter.ImagePath = path;
changesMade = true;
diff --git a/MediaBrowser.Controller/Providers/MediaInfo/AudioImageProvider.cs b/MediaBrowser.Controller/Providers/MediaInfo/AudioImageProvider.cs
index 881065ea6..9fd67f477 100644
--- a/MediaBrowser.Controller/Providers/MediaInfo/AudioImageProvider.cs
+++ b/MediaBrowser.Controller/Providers/MediaInfo/AudioImageProvider.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Common.IO;
+using System.IO;
+using MediaBrowser.Common.IO;
using MediaBrowser.Common.MediaInfo;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
@@ -156,7 +157,7 @@ namespace MediaBrowser.Controller.Providers.MediaInfo
var path = ImageCache.GetResourcePath(filename + "_primary", ".jpg");
- if (!ImageCache.ContainsFilePath(path))
+ if (!File.Exists(path))
{
var semaphore = GetLock(path);
@@ -164,10 +165,17 @@ namespace MediaBrowser.Controller.Providers.MediaInfo
await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
// Check again
- if (!ImageCache.ContainsFilePath(path))
+ if (!File.Exists(path))
{
try
{
+ var parentPath = Path.GetDirectoryName(path);
+
+ if (!Directory.Exists(parentPath))
+ {
+ Directory.CreateDirectory(parentPath);
+ }
+
await _mediaEncoder.ExtractImage(new[] { item.Path }, InputType.AudioFile, null, path, cancellationToken).ConfigureAwait(false);
}
finally
diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
index 2eb76c731..82193c27c 100644
--- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
+++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
@@ -244,6 +244,9 @@
<Compile Include="..\MediaBrowser.Model\Querying\PersonsQuery.cs">
<Link>Querying\PersonsQuery.cs</Link>
</Compile>
+ <Compile Include="..\MediaBrowser.Model\Querying\SimilarItemsQuery.cs">
+ <Link>Querying\SimilarItemsQuery.cs</Link>
+ </Compile>
<Compile Include="..\MediaBrowser.Model\Querying\ThemeSongsResult.cs">
<Link>Querying\ThemeSongsResult.cs</Link>
</Compile>
diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs
index d2b729ffd..785dfdfd7 100644
--- a/MediaBrowser.Model/ApiClient/IApiClient.cs
+++ b/MediaBrowser.Model/ApiClient/IApiClient.cs
@@ -73,6 +73,34 @@ namespace MediaBrowser.Model.ApiClient
Task<ItemsResult> GetItemsAsync(ItemQuery query);
/// <summary>
+ /// Gets the similar movies async.
+ /// </summary>
+ /// <param name="query">The query.</param>
+ /// <returns>Task{ItemsResult}.</returns>
+ Task<ItemsResult> GetSimilarMoviesAsync(SimilarItemsQuery query);
+
+ /// <summary>
+ /// Gets the similar series async.
+ /// </summary>
+ /// <param name="query">The query.</param>
+ /// <returns>Task{ItemsResult}.</returns>
+ Task<ItemsResult> GetSimilarSeriesAsync(SimilarItemsQuery query);
+
+ /// <summary>
+ /// Gets the similar albums async.
+ /// </summary>
+ /// <param name="query">The query.</param>
+ /// <returns>Task{ItemsResult}.</returns>
+ Task<ItemsResult> GetSimilarAlbumsAsync(SimilarItemsQuery query);
+
+ /// <summary>
+ /// Gets the similar games async.
+ /// </summary>
+ /// <param name="query">The query.</param>
+ /// <returns>Task{ItemsResult}.</returns>
+ Task<ItemsResult> GetSimilarGamesAsync(SimilarItemsQuery query);
+
+ /// <summary>
/// Gets the people async.
/// </summary>
/// <param name="query">The query.</param>
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index 7d56e4743..a13c8ef0c 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -60,6 +60,7 @@
<Compile Include="Querying\ItemReviewsResult.cs" />
<Compile Include="Querying\ItemsByNameQuery.cs" />
<Compile Include="Entities\BaseItemInfo.cs" />
+ <Compile Include="Querying\SimilarItemsQuery.cs" />
<Compile Include="Session\BrowseRequest.cs" />
<Compile Include="Session\PlayRequest.cs" />
<Compile Include="Session\PlaystateRequest.cs" />
diff --git a/MediaBrowser.Model/Querying/SimilarItemsQuery.cs b/MediaBrowser.Model/Querying/SimilarItemsQuery.cs
new file mode 100644
index 000000000..0dd491550
--- /dev/null
+++ b/MediaBrowser.Model/Querying/SimilarItemsQuery.cs
@@ -0,0 +1,29 @@
+namespace MediaBrowser.Model.Querying
+{
+ public class SimilarItemsQuery
+ {
+ /// <summary>
+ /// The user to localize search results for
+ /// </summary>
+ /// <value>The user id.</value>
+ public string UserId { get; set; }
+
+ /// <summary>
+ /// Gets or sets the id.
+ /// </summary>
+ /// <value>The id.</value>
+ public string Id { get; set; }
+
+ /// <summary>
+ /// The maximum number of items to return
+ /// </summary>
+ /// <value>The limit.</value>
+ public int? Limit { get; set; }
+
+ /// <summary>
+ /// Fields to return within the items, in addition to basic information
+ /// </summary>
+ /// <value>The fields.</value>
+ public ItemFields[] Fields { get; set; }
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs b/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs
index ce39ffc06..fbb5a2010 100644
--- a/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs
+++ b/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs
@@ -94,29 +94,20 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
}
/// <summary>
- /// The _media tools path
+ /// Gets the media tools path.
/// </summary>
- private string _mediaToolsPath;
- /// <summary>
- /// Gets the folder path to tools
- /// </summary>
- /// <value>The media tools path.</value>
- private string MediaToolsPath
+ /// <param name="create">if set to <c>true</c> [create].</param>
+ /// <returns>System.String.</returns>
+ private string GetMediaToolsPath(bool create)
{
- get
- {
- if (_mediaToolsPath == null)
- {
- _mediaToolsPath = Path.Combine(_appPaths.ProgramDataPath, "ffmpeg");
-
- if (!Directory.Exists(_mediaToolsPath))
- {
- Directory.CreateDirectory(_mediaToolsPath);
- }
- }
+ var path = Path.Combine(_appPaths.ProgramDataPath, "ffmpeg");
- return _mediaToolsPath;
+ if (create && !Directory.Exists(path))
+ {
+ Directory.CreateDirectory(path);
}
+
+ return path;
}
/// <summary>
@@ -185,7 +176,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
var filename = resource.Substring(resource.IndexOf(prefix, StringComparison.OrdinalIgnoreCase) + prefix.Length);
- var versionedDirectoryPath = Path.Combine(MediaToolsPath, Path.GetFileNameWithoutExtension(filename));
+ var versionedDirectoryPath = Path.Combine(GetMediaToolsPath(true), Path.GetFileNameWithoutExtension(filename));
if (!Directory.Exists(versionedDirectoryPath))
{
@@ -570,14 +561,14 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
}
var offsetParam = offset.Ticks > 0 ? "-ss " + offset.TotalSeconds + " " : string.Empty;
-
+
var process = new Process
{
StartInfo = new ProcessStartInfo
{
RedirectStandardOutput = false,
RedirectStandardError = true,
-
+
CreateNoWindow = true,
UseShellExecute = false,
FileName = FFMpegPath,
@@ -744,7 +735,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
RedirectStandardOutput = false,
RedirectStandardError = true,
-
+
FileName = FFMpegPath,
Arguments = string.Format("{0}-i {1} -map 0:{2} -an -vn -c:s ass \"{3}\"", offsetParam, inputPath, subtitleStreamIndex, outputPath),
WindowStyle = ProcessWindowStyle.Hidden,
@@ -759,7 +750,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);
-
+
try
{
process.Start();
diff --git a/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs b/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs
index 2ba222ca5..ea1b83dec 100644
--- a/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs
+++ b/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs
@@ -328,9 +328,7 @@ namespace MediaBrowser.Server.Implementations.Providers
public async Task<string> SaveImage(BaseItem item, Stream source, string targetName, bool saveLocally, CancellationToken cancellationToken)
{
//download and save locally
- var localPath = (saveLocally && item.MetaLocation != null) ?
- Path.Combine(item.MetaLocation, targetName) :
- _remoteImageCache.GetResourcePath(item.GetType().FullName + item.Path.ToLower(), targetName);
+ var localPath = GetSavePath(item, targetName, saveLocally);
if (saveLocally) // queue to media directories
{
@@ -374,9 +372,18 @@ namespace MediaBrowser.Server.Implementations.Providers
/// <returns>System.String.</returns>
public string GetSavePath(BaseItem item, string targetFileName, bool saveLocally)
{
- return (saveLocally && item.MetaLocation != null) ?
+ var path = (saveLocally && item.MetaLocation != null) ?
Path.Combine(item.MetaLocation, targetFileName) :
_remoteImageCache.GetResourcePath(item.GetType().FullName + item.Id.ToString(), targetFileName);
+
+ var parentPath = Path.GetDirectoryName(path);
+
+ if (!Directory.Exists(parentPath))
+ {
+ Directory.CreateDirectory(parentPath);
+ }
+
+ return path;
}
/// <summary>
diff --git a/MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs
index 95dc4e7ae..2d9d5abfe 100644
--- a/MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs
+++ b/MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs
@@ -168,6 +168,14 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
if (!success)
{
previouslyFailedImages.Add(key);
+
+ var parentPath = Path.GetDirectoryName(failHistoryPath);
+
+ if (!Directory.Exists(parentPath))
+ {
+ Directory.CreateDirectory(parentPath);
+ }
+
_jsonSerializer.SerializeToFile(previouslyFailedImages, failHistoryPath);
}
diff --git a/MediaBrowser.Server.Implementations/ScheduledTasks/ImageCleanupTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/ImageCleanupTask.cs
index 0c3016552..0e78824c1 100644
--- a/MediaBrowser.Server.Implementations/ScheduledTasks/ImageCleanupTask.cs
+++ b/MediaBrowser.Server.Implementations/ScheduledTasks/ImageCleanupTask.cs
@@ -165,7 +165,7 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
var specialFeattures = _itemRepo.GetItems(movie.SpecialFeatureIds).ToList();
images = specialFeattures.Aggregate(images, (current, subItem) => current.Concat(GetPathsInUse(subItem)));
}
-
+
return images;
}
@@ -176,13 +176,20 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
/// <returns>IEnumerable{System.String}.</returns>
private IEnumerable<string> GetFiles(string path)
{
- return Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories)
- .Where(i =>
- {
- var ext = Path.GetExtension(i);
+ try
+ {
+ return Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories)
+ .Where(i =>
+ {
+ var ext = Path.GetExtension(i);
- return !string.IsNullOrEmpty(ext) && BaseItem.SupportedImageExtensions.Contains(ext, StringComparer.OrdinalIgnoreCase);
- });
+ return !string.IsNullOrEmpty(ext) && BaseItem.SupportedImageExtensions.Contains(ext, StringComparer.OrdinalIgnoreCase);
+ });
+ }
+ catch (DirectoryNotFoundException)
+ {
+ return new string[] { };
+ }
}
/// <summary>
diff --git a/MediaBrowser.Server.Implementations/ScheduledTasks/VideoImagesTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/VideoImagesTask.cs
index f0afe6358..2233f6fdf 100644
--- a/MediaBrowser.Server.Implementations/ScheduledTasks/VideoImagesTask.cs
+++ b/MediaBrowser.Server.Implementations/ScheduledTasks/VideoImagesTask.cs
@@ -8,14 +8,15 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers.MediaInfo;
using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Logging;
+using MoreLinq;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
-using MediaBrowser.Model.Logging;
-using MoreLinq;
namespace MediaBrowser.Server.Implementations.ScheduledTasks
{
@@ -263,7 +264,7 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
var path = ImageCache.GetResourcePath(filename, ".jpg");
- if (!ImageCache.ContainsFilePath(path))
+ if (!File.Exists(path))
{
var semaphore = GetLock(path);
@@ -271,10 +272,17 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
// Check again
- if (!ImageCache.ContainsFilePath(path))
+ if (!File.Exists(path))
{
try
{
+ var parentPath = Path.GetDirectoryName(path);
+
+ if (!Directory.Exists(parentPath))
+ {
+ Directory.CreateDirectory(parentPath);
+ }
+
await ExtractImageInternal(item, path, cancellationToken).ConfigureAwait(false);
}
finally
diff --git a/MediaBrowser.Server.Implementations/Sqlite/SQLiteItemRepository.cs b/MediaBrowser.Server.Implementations/Sqlite/SQLiteItemRepository.cs
index a0acd523e..bead1360b 100644
--- a/MediaBrowser.Server.Implementations/Sqlite/SQLiteItemRepository.cs
+++ b/MediaBrowser.Server.Implementations/Sqlite/SQLiteItemRepository.cs
@@ -471,20 +471,18 @@ namespace MediaBrowser.Server.Implementations.Sqlite
/// <summary>
/// Gets the critic reviews path.
/// </summary>
- /// <value>The critic reviews path.</value>
- private string CriticReviewsPath
+ /// <param name="create">if set to <c>true</c> [create].</param>
+ /// <returns>System.String.</returns>
+ private string GetCriticReviewsPath(bool create)
{
- get
- {
- var path = Path.Combine(_appPaths.DataPath, "critic-reviews");
-
- if (!Directory.Exists(path))
- {
- Directory.CreateDirectory(path);
- }
+ var path = Path.Combine(_appPaths.DataPath, "critic-reviews");
- return path;
+ if (create && !Directory.Exists(path))
+ {
+ Directory.CreateDirectory(path);
}
+
+ return path;
}
/// <summary>
@@ -499,10 +497,14 @@ namespace MediaBrowser.Server.Implementations.Sqlite
try
{
- var path = Path.Combine(CriticReviewsPath, itemId + ".json");
+ var path = Path.Combine(GetCriticReviewsPath(false), itemId + ".json");
return _jsonSerializer.DeserializeFromFile<List<ItemReview>>(path);
}
+ catch (DirectoryNotFoundException)
+ {
+ return new List<ItemReview>();
+ }
catch (FileNotFoundException)
{
return new List<ItemReview>();
@@ -521,7 +523,7 @@ namespace MediaBrowser.Server.Implementations.Sqlite
{
return Task.Run(() =>
{
- var path = Path.Combine(CriticReviewsPath, itemId + ".json");
+ var path = Path.Combine(GetCriticReviewsPath(true), itemId + ".json");
_jsonSerializer.SerializeToFile(criticReviews.ToList(), path);
});
diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec
index 45da5849b..5425e0b9a 100644
--- a/Nuget/MediaBrowser.Common.Internal.nuspec
+++ b/Nuget/MediaBrowser.Common.Internal.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common.Internal</id>
- <version>3.0.112</version>
+ <version>3.0.113</version>
<title>MediaBrowser.Common.Internal</title>
<authors>Luke</authors>
<owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
<description>Contains common components shared by Media Browser Theatre and Media Browser Server. Not intended for plugin developer consumption.</description>
<copyright>Copyright © Media Browser 2013</copyright>
<dependencies>
- <dependency id="MediaBrowser.Common" version="3.0.112" />
+ <dependency id="MediaBrowser.Common" version="3.0.113" />
<dependency id="NLog" version="2.0.1.2" />
<dependency id="ServiceStack.Text" version="3.9.45" />
<dependency id="SimpleInjector" version="2.2.3" />
diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec
index 96926c2b9..1b03690ef 100644
--- a/Nuget/MediaBrowser.Common.nuspec
+++ b/Nuget/MediaBrowser.Common.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common</id>
- <version>3.0.112</version>
+ <version>3.0.113</version>
<title>MediaBrowser.Common</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>
diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec
index b522a0f1a..48ebcad5f 100644
--- a/Nuget/MediaBrowser.Server.Core.nuspec
+++ b/Nuget/MediaBrowser.Server.Core.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>MediaBrowser.Server.Core</id>
- <version>3.0.112</version>
+ <version>3.0.113</version>
<title>Media Browser.Server.Core</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
<description>Contains core components required to build plugins for Media Browser Server.</description>
<copyright>Copyright © Media Browser 2013</copyright>
<dependencies>
- <dependency id="MediaBrowser.Common" version="3.0.112" />
+ <dependency id="MediaBrowser.Common" version="3.0.113" />
</dependencies>
</metadata>
<files>