fixes #97 and creates a library dictionary cache to avoid FindById recursion
This commit is contained in:
parent
b7c3bc592f
commit
9f06eb781f
|
@ -160,11 +160,12 @@ namespace MediaBrowser.Api.Images
|
|||
/// The _library manager
|
||||
/// </summary>
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ImageService" /> class.
|
||||
/// </summary>
|
||||
/// <param name="userManager">The user manager.</param>
|
||||
/// <param name="libraryManager">The library manager.</param>
|
||||
public ImageService(IUserManager userManager, ILibraryManager libraryManager)
|
||||
{
|
||||
_userManager = userManager;
|
||||
|
@ -178,7 +179,7 @@ namespace MediaBrowser.Api.Images
|
|||
/// <returns>System.Object.</returns>
|
||||
public object Get(GetItemImage request)
|
||||
{
|
||||
var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager);
|
||||
var item = string.IsNullOrEmpty(request.Id) ? _libraryManager.RootFolder : DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager);
|
||||
|
||||
return GetImage(request, item);
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
/// </summary>
|
||||
[Route("/Users/{UserId}/Items/{ParentId}/Genres", "GET")]
|
||||
[Route("/Users/{UserId}/Items/Root/Genres", "GET")]
|
||||
[ServiceStack.ServiceHost.Api(Description = "Gets all genres from a given item, folder, or the entire library")]
|
||||
[Api(Description = "Gets all genres from a given item, folder, or the entire library")]
|
||||
public class GetGenres : GetItemsByName
|
||||
{
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
/// Filters to apply to the results
|
||||
/// </summary>
|
||||
/// <value>The filters.</value>
|
||||
[ApiMember(Name = "Filters", Description = "Optional. Specify additional filters to apply. This allows multiple, comma delimeted. Options: IsFolder, IsNotFolder, IsUnplayed, IsPlayed, IsFavorite, IsRecentlyAdded, IsResumable", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
|
||||
[ApiMember(Name = "Filters", Description = "Optional. Specify additional filters to apply. This allows multiple, comma delimeted. Options: IsFolder, IsNotFolder, IsUnplayed, IsPlayed, IsFavorite, IsRecentlyAdded, IsResumable, Likes, Dislikes", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
|
||||
public string Filters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -378,7 +378,7 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
{
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
|
||||
var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
|
||||
var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
|
||||
|
||||
// Get everything
|
||||
var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
|
||||
|
@ -401,7 +401,7 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
{
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
|
||||
var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
|
||||
var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
|
||||
|
||||
// Get everything
|
||||
var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
|
||||
|
@ -422,7 +422,7 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
{
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
|
||||
var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
|
||||
var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
|
||||
|
||||
// Get everything
|
||||
var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
|
||||
|
@ -459,7 +459,7 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
{
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
|
||||
var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
|
||||
var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
|
||||
|
||||
var result = _libraryManager.GetIntros(item, user);
|
||||
|
||||
|
@ -480,12 +480,13 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
|
||||
var user = _userManager.GetUserById(userId);
|
||||
|
||||
var item = (Folder)DtoBuilder.GetItemByClientId(itemId, _userManager, _libraryManager, user.Id);
|
||||
var item = string.IsNullOrEmpty(itemId) ? user.RootFolder : DtoBuilder.GetItemByClientId(itemId, _userManager, _libraryManager, user.Id);
|
||||
var folder = (Folder)item;
|
||||
|
||||
// Serialize to json and then back so that the core doesn't see the request dto type
|
||||
var displayPreferences = _jsonSerializer.DeserializeFromString<DisplayPreferences>(_jsonSerializer.SerializeToString(request));
|
||||
|
||||
var task = _libraryManager.SaveDisplayPreferencesForFolder(user, item, displayPreferences);
|
||||
var task = _libraryManager.SaveDisplayPreferencesForFolder(user, folder, displayPreferences);
|
||||
|
||||
Task.WaitAll(task);
|
||||
}
|
||||
|
@ -498,7 +499,7 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
{
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
|
||||
var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
|
||||
var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
|
||||
|
||||
// Get the user data for this item
|
||||
var data = item.GetUserData(user, true);
|
||||
|
@ -519,7 +520,7 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
{
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
|
||||
var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
|
||||
var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
|
||||
|
||||
// Get the user data for this item
|
||||
var data = item.GetUserData(user, true);
|
||||
|
@ -540,7 +541,7 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
{
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
|
||||
var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
|
||||
var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
|
||||
|
||||
// Get the user data for this item
|
||||
var data = item.GetUserData(user, true);
|
||||
|
@ -560,7 +561,7 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
{
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
|
||||
var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
|
||||
var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
|
||||
|
||||
// Get the user data for this item
|
||||
var data = item.GetUserData(user, true);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Net.Http.Headers;
|
||||
using System.Globalization;
|
||||
using System.Net.Http.Headers;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
|
@ -216,6 +217,8 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||
return GetTempFile(options, tempFile, 0);
|
||||
}
|
||||
|
||||
protected static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the temp file.
|
||||
/// </summary>
|
||||
|
@ -278,7 +281,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||
}
|
||||
else
|
||||
{
|
||||
var length = long.Parse(string.Join(string.Empty, lengthValues.ToArray()));
|
||||
var length = long.Parse(string.Join(string.Empty, lengthValues.ToArray()), UsCulture);
|
||||
|
||||
using (var stream = ProgressStream.CreateReadProgressStream(await response.Content.ReadAsStreamAsync().ConfigureAwait(false), options.Progress.Report, length))
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Management;
|
||||
using System.Globalization;
|
||||
using System.Management;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Model.Net;
|
||||
using System;
|
||||
|
@ -343,6 +344,8 @@ namespace MediaBrowser.Common.Implementations.NetworkManagement
|
|||
return new IPEndPoint(ipaddy, port);
|
||||
}
|
||||
|
||||
protected static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the port.
|
||||
/// </summary>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Model.Logging;
|
||||
using System.Globalization;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
@ -80,6 +81,8 @@ namespace MediaBrowser.Common.Net
|
|||
return NullTaskResult;
|
||||
}
|
||||
|
||||
protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
/// <summary>
|
||||
/// Starts sending messages over a web socket
|
||||
/// </summary>
|
||||
|
@ -88,8 +91,8 @@ namespace MediaBrowser.Common.Net
|
|||
{
|
||||
var vals = message.Data.Split(',');
|
||||
|
||||
var dueTimeMs = long.Parse(vals[0]);
|
||||
var periodMs = long.Parse(vals[1]);
|
||||
var dueTimeMs = long.Parse(vals[0], UsCulture);
|
||||
var periodMs = long.Parse(vals[1], UsCulture);
|
||||
|
||||
var cancellationTokenSource = new CancellationTokenSource();
|
||||
|
||||
|
|
|
@ -950,33 +950,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
return IsParentalAllowed(user);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds an item by ID, recursively
|
||||
/// </summary>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>BaseItem.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">id</exception>
|
||||
public virtual BaseItem FindItemById(Guid id, User user)
|
||||
{
|
||||
if (id == Guid.Empty)
|
||||
{
|
||||
throw new ArgumentNullException("id");
|
||||
}
|
||||
|
||||
if (Id == id)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
if (LocalTrailers != null)
|
||||
{
|
||||
return LocalTrailers.FirstOrDefault(i => i.Id == id);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the particular item by searching through our parents and, if not found there, loading from repo
|
||||
/// </summary>
|
||||
|
|
|
@ -673,7 +673,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
foreach (var item in changedArgs.ItemsRemoved)
|
||||
{
|
||||
Logger.Info("** " + item.Name + " Removed from library.");
|
||||
Logger.Debug("** " + item.Name + " Removed from library.");
|
||||
}
|
||||
|
||||
var childrenReplaced = false;
|
||||
|
@ -688,7 +688,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
foreach (var item in changedArgs.ItemsAdded)
|
||||
{
|
||||
Logger.Info("** " + item.Name + " Added to library.");
|
||||
Logger.Debug("** " + item.Name + " Added to library.");
|
||||
|
||||
if (!childrenReplaced)
|
||||
{
|
||||
|
@ -701,7 +701,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
await Task.WhenAll(saveTasks).ConfigureAwait(false);
|
||||
|
||||
//and save children in repo...
|
||||
Logger.Info("*** Saving " + newChildren.Count + " children for " + Name);
|
||||
Logger.Debug("*** Saving " + newChildren.Count + " children for " + Name);
|
||||
await Kernel.Instance.ItemRepository.SaveChildren(Id, newChildren, CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
@ -913,36 +913,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds an item by ID, recursively
|
||||
/// </summary>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>BaseItem.</returns>
|
||||
public override BaseItem FindItemById(Guid id, User user)
|
||||
{
|
||||
var result = base.FindItemById(id, user);
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
var children = user == null ? ActualChildren : GetChildren(user);
|
||||
|
||||
foreach (var child in children)
|
||||
{
|
||||
result = child.FindItemById(id, user);
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds an item by path, recursively
|
||||
/// </summary>
|
||||
|
|
|
@ -118,30 +118,7 @@ namespace MediaBrowser.Controller.Entities.Movies
|
|||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds an item by ID, recursively
|
||||
/// </summary>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>BaseItem.</returns>
|
||||
public override BaseItem FindItemById(Guid id, User user)
|
||||
{
|
||||
var item = base.FindItemById(id, user);
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
return item;
|
||||
}
|
||||
|
||||
if (SpecialFeatures != null)
|
||||
{
|
||||
return SpecialFeatures.FirstOrDefault(i => i.Id == id);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads special features from the file system
|
||||
|
|
|
@ -191,7 +191,6 @@ namespace MediaBrowser.Controller.Extensions
|
|||
|
||||
if (!string.IsNullOrWhiteSpace(valueString))
|
||||
{
|
||||
|
||||
int.TryParse(valueString, out value);
|
||||
}
|
||||
|
||||
|
|
|
@ -809,15 +809,19 @@ namespace MediaBrowser.Controller.Library
|
|||
/// Gets a BaseItem based upon it's client-side item id
|
||||
/// </summary>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <param name="userManager">The user manager.</param>
|
||||
/// <param name="libraryManager">The library manager.</param>
|
||||
/// <param name="userId">The user id.</param>
|
||||
/// <returns>BaseItem.</returns>
|
||||
public static BaseItem GetItemByClientId(string id, IUserManager userManager, ILibraryManager libraryManager, Guid? userId = null)
|
||||
{
|
||||
var isIdEmpty = string.IsNullOrEmpty(id);
|
||||
if (string.IsNullOrEmpty(id))
|
||||
{
|
||||
throw new ArgumentNullException("id");
|
||||
}
|
||||
|
||||
// If the item is an indexed folder we have to do a special routine to get it
|
||||
var isIndexFolder = !isIdEmpty &&
|
||||
id.IndexOf(IndexFolderDelimeter, StringComparison.OrdinalIgnoreCase) != -1;
|
||||
var isIndexFolder = id.IndexOf(IndexFolderDelimeter, StringComparison.OrdinalIgnoreCase) != -1;
|
||||
|
||||
if (isIndexFolder)
|
||||
{
|
||||
|
@ -831,9 +835,7 @@ namespace MediaBrowser.Controller.Library
|
|||
|
||||
if (userId.HasValue)
|
||||
{
|
||||
item = isIdEmpty
|
||||
? userManager.GetUserById(userId.Value).RootFolder
|
||||
: libraryManager.GetItemById(new Guid(id), userId.Value);
|
||||
item = libraryManager.GetItemById(new Guid(id));
|
||||
}
|
||||
else if (!isIndexFolder)
|
||||
{
|
||||
|
@ -862,6 +864,8 @@ namespace MediaBrowser.Controller.Library
|
|||
/// </summary>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <param name="userId">The user id.</param>
|
||||
/// <param name="userManager">The user manager.</param>
|
||||
/// <param name="libraryManager">The library manager.</param>
|
||||
/// <returns>BaseItem.</returns>
|
||||
private static BaseItem GetIndexFolder(string id, Guid userId, IUserManager userManager, ILibraryManager libraryManager)
|
||||
{
|
||||
|
|
|
@ -136,14 +136,6 @@ namespace MediaBrowser.Controller.Library
|
|||
/// <returns>BaseItem.</returns>
|
||||
BaseItem GetItemById(Guid id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the item by id.
|
||||
/// </summary>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <param name="userId">The user id.</param>
|
||||
/// <returns>BaseItem.</returns>
|
||||
BaseItem GetItemById(Guid id, Guid userId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the intros.
|
||||
/// </summary>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using System.Globalization;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.MediaInfo;
|
||||
|
@ -61,6 +62,8 @@ namespace MediaBrowser.Controller.Providers.MediaInfo
|
|||
get { return MetadataProviderPriority.Second; }
|
||||
}
|
||||
|
||||
protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
/// <summary>
|
||||
/// Fetches metadata and returns true or false indicating if any work that requires persistence was done
|
||||
/// </summary>
|
||||
|
@ -203,7 +206,7 @@ namespace MediaBrowser.Controller.Providers.MediaInfo
|
|||
|
||||
if (!string.IsNullOrEmpty(streamInfo.sample_rate))
|
||||
{
|
||||
stream.SampleRate = int.Parse(streamInfo.sample_rate);
|
||||
stream.SampleRate = int.Parse(streamInfo.sample_rate, UsCulture);
|
||||
}
|
||||
}
|
||||
else if (streamInfo.codec_type.Equals("subtitle", StringComparison.OrdinalIgnoreCase))
|
||||
|
@ -227,12 +230,12 @@ namespace MediaBrowser.Controller.Providers.MediaInfo
|
|||
{
|
||||
if (!string.IsNullOrEmpty(streamInfo.bit_rate))
|
||||
{
|
||||
stream.BitRate = int.Parse(streamInfo.bit_rate);
|
||||
stream.BitRate = int.Parse(streamInfo.bit_rate, UsCulture);
|
||||
}
|
||||
else if (formatInfo != null && !string.IsNullOrEmpty(formatInfo.bit_rate))
|
||||
{
|
||||
// If the stream info doesn't have a bitrate get the value from the media format info
|
||||
stream.BitRate = int.Parse(formatInfo.bit_rate);
|
||||
stream.BitRate = int.Parse(formatInfo.bit_rate, UsCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -265,11 +268,11 @@ namespace MediaBrowser.Controller.Providers.MediaInfo
|
|||
|
||||
if (parts.Length == 2)
|
||||
{
|
||||
result = float.Parse(parts[0])/float.Parse(parts[1]);
|
||||
result = float.Parse(parts[0], UsCulture) / float.Parse(parts[1], UsCulture);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = float.Parse(parts[0]);
|
||||
result = float.Parse(parts[0], UsCulture);
|
||||
}
|
||||
|
||||
return float.IsNaN(result) ? (float?)null : result;
|
||||
|
|
|
@ -69,7 +69,7 @@ namespace MediaBrowser.Controller.Providers.MediaInfo
|
|||
// If we got something, parse it
|
||||
if (!string.IsNullOrEmpty(duration))
|
||||
{
|
||||
audio.RunTimeTicks = TimeSpan.FromSeconds(double.Parse(duration)).Ticks;
|
||||
audio.RunTimeTicks = TimeSpan.FromSeconds(double.Parse(duration, UsCulture)).Ticks;
|
||||
}
|
||||
|
||||
if (data.format.tags != null)
|
||||
|
|
|
@ -198,7 +198,7 @@ namespace MediaBrowser.Controller.Providers.MediaInfo
|
|||
|
||||
if (needToSetRuntime && !string.IsNullOrEmpty(data.format.duration))
|
||||
{
|
||||
video.RunTimeTicks = TimeSpan.FromSeconds(double.Parse(data.format.duration)).Ticks;
|
||||
video.RunTimeTicks = TimeSpan.FromSeconds(double.Parse(data.format.duration, UsCulture)).Ticks;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -127,6 +127,8 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
|||
EndpointHostConfig.Instance.MetadataRedirectPath = "metadata";
|
||||
}
|
||||
|
||||
protected static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
/// <summary>
|
||||
/// Configures the specified container.
|
||||
/// </summary>
|
||||
|
@ -184,7 +186,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
|||
|
||||
if (hasOptions.Options.TryGetValue("Content-Length", out contentLength) && !string.IsNullOrEmpty(contentLength))
|
||||
{
|
||||
var length = long.Parse(contentLength);
|
||||
var length = long.Parse(contentLength, UsCulture);
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
|
|
|
@ -139,11 +139,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
|||
|
||||
if (!string.IsNullOrEmpty(vals[0]))
|
||||
{
|
||||
start = long.Parse(vals[0]);
|
||||
start = long.Parse(vals[0], UsCulture);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(vals[1]))
|
||||
{
|
||||
end = long.Parse(vals[1]);
|
||||
end = long.Parse(vals[1], UsCulture);
|
||||
}
|
||||
|
||||
_requestedRanges.Add(new KeyValuePair<long, long?>(start, end));
|
||||
|
|
|
@ -4,6 +4,7 @@ using MediaBrowser.Common.ScheduledTasks;
|
|||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Resolvers;
|
||||
|
@ -73,6 +74,8 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
/// <param name="args">The <see cref="ChildrenChangedEventArgs" /> instance containing the event data.</param>
|
||||
public void ReportLibraryChanged(ChildrenChangedEventArgs args)
|
||||
{
|
||||
UpdateLibraryCache(args);
|
||||
|
||||
EventHelper.QueueEventIfNotNull(LibraryChanged, this, args, _logger);
|
||||
}
|
||||
#endregion
|
||||
|
@ -109,7 +112,28 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
/// (typically, multiple user roots). We store them here and be sure they all reference a
|
||||
/// single instance.
|
||||
/// </summary>
|
||||
private ConcurrentDictionary<Guid, BaseItem> ByReferenceItems { get; set; }
|
||||
private ConcurrentDictionary<Guid, BaseItem> ByReferenceItems { get; set; }
|
||||
|
||||
private ConcurrentDictionary<Guid, BaseItem> _libraryItemsCache;
|
||||
private object _libraryItemsCacheSyncLock = new object();
|
||||
private bool _libraryItemsCacheInitialized;
|
||||
private ConcurrentDictionary<Guid, BaseItem> LibraryItemsCache
|
||||
{
|
||||
get
|
||||
{
|
||||
LazyInitializer.EnsureInitialized(ref _libraryItemsCache, ref _libraryItemsCacheInitialized, ref _libraryItemsCacheSyncLock, CreateLibraryItemsCache);
|
||||
return _libraryItemsCache;
|
||||
}
|
||||
set
|
||||
{
|
||||
_libraryItemsCache = value;
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
_libraryItemsCacheInitialized = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LibraryManager" /> class.
|
||||
|
@ -219,7 +243,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
{
|
||||
// Any number of configuration settings could change the way the library is refreshed, so do that now
|
||||
_taskManager.CancelIfRunningAndQueue<RefreshMediaLibraryTask>();
|
||||
|
||||
|
||||
if (refreshPeopleAfterUpdate)
|
||||
{
|
||||
_taskManager.CancelIfRunningAndQueue<PeopleValidationTask>();
|
||||
|
@ -227,6 +251,77 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the library items cache.
|
||||
/// </summary>
|
||||
/// <returns>ConcurrentDictionary{GuidBaseItem}.</returns>
|
||||
private ConcurrentDictionary<Guid, BaseItem> CreateLibraryItemsCache()
|
||||
{
|
||||
var items = RootFolder.RecursiveChildren.ToList();
|
||||
|
||||
items.Add(RootFolder);
|
||||
|
||||
var specialFeatures = items.OfType<Movie>().SelectMany(i => i.SpecialFeatures).ToList();
|
||||
var localTrailers = items.SelectMany(i => i.LocalTrailers).ToList();
|
||||
|
||||
items.AddRange(specialFeatures);
|
||||
items.AddRange(localTrailers);
|
||||
|
||||
// Can't add these right now because there could be separate instances with the same id.
|
||||
//items.AddRange(_userManager.Users.Select(i => i.RootFolder).Distinct().ToList());
|
||||
|
||||
items.AddRange(_userManager.Users.SelectMany(i => i.RootFolder.Children).Where(i => !(i is BasePluginFolder)).Distinct().ToList());
|
||||
|
||||
return new ConcurrentDictionary<Guid,BaseItem>(items.ToDictionary(i => i.Id));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the library cache.
|
||||
/// </summary>
|
||||
/// <param name="args">The <see cref="ChildrenChangedEventArgs"/> instance containing the event data.</param>
|
||||
private void UpdateLibraryCache(ChildrenChangedEventArgs args)
|
||||
{
|
||||
UpdateItemInLibraryCache(args.Folder);
|
||||
|
||||
foreach (var item in args.ItemsAdded)
|
||||
{
|
||||
UpdateItemInLibraryCache(item);
|
||||
}
|
||||
|
||||
foreach (var item in args.ItemsUpdated)
|
||||
{
|
||||
UpdateItemInLibraryCache(item);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the item in library cache.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
private void UpdateItemInLibraryCache(BaseItem item)
|
||||
{
|
||||
LibraryItemsCache.AddOrUpdate(item.Id, item, delegate { return item; });
|
||||
|
||||
foreach (var trailer in item.LocalTrailers)
|
||||
{
|
||||
// Prevent access to foreach variable in closure
|
||||
var trailer1 = trailer;
|
||||
LibraryItemsCache.AddOrUpdate(trailer.Id, trailer, delegate { return trailer1; });
|
||||
}
|
||||
|
||||
var movie = item as Movie;
|
||||
|
||||
if (movie != null)
|
||||
{
|
||||
foreach (var special in movie.SpecialFeatures)
|
||||
{
|
||||
// Prevent access to foreach variable in closure
|
||||
Video special1 = special;
|
||||
LibraryItemsCache.AddOrUpdate(special.Id, special, delegate { return special1; });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the item.
|
||||
/// </summary>
|
||||
|
@ -647,11 +742,6 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
|
||||
// Now validate the entire media library
|
||||
await RootFolder.ValidateChildren(progress, cancellationToken, recursive: true).ConfigureAwait(false);
|
||||
|
||||
//foreach (var user in _userManager.Users)
|
||||
//{
|
||||
// await user.ValidateMediaLibrary(new Progress<double> { }, cancellationToken).ConfigureAwait(false);
|
||||
//}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -708,32 +798,6 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds a library item by Id and UserId.
|
||||
/// </summary>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <param name="userId">The user id.</param>
|
||||
/// <param name="userManager">The user manager.</param>
|
||||
/// <returns>BaseItem.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">id</exception>
|
||||
public BaseItem GetItemById(Guid id, Guid userId)
|
||||
{
|
||||
if (id == Guid.Empty)
|
||||
{
|
||||
throw new ArgumentNullException("id");
|
||||
}
|
||||
|
||||
if (userId == Guid.Empty)
|
||||
{
|
||||
throw new ArgumentNullException("userId");
|
||||
}
|
||||
|
||||
var user = _userManager.GetUserById(userId);
|
||||
var userRoot = user.RootFolder;
|
||||
|
||||
return userRoot.FindItemById(id, user);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the item by id.
|
||||
/// </summary>
|
||||
|
@ -747,7 +811,11 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
throw new ArgumentNullException("id");
|
||||
}
|
||||
|
||||
return RootFolder.FindItemById(id, null);
|
||||
BaseItem item;
|
||||
|
||||
LibraryItemsCache.TryGetValue(id, out item);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -236,7 +236,7 @@ namespace MediaBrowser.Server.Implementations.Providers
|
|||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
_logger.Info("Running {0} for {1}", provider.GetType().Name, item.Path ?? item.Name ?? "--Unknown--");
|
||||
_logger.Debug("Running {0} for {1}", provider.GetType().Name, item.Path ?? item.Name ?? "--Unknown--");
|
||||
|
||||
// This provides the ability to cancel just this one provider
|
||||
var innerCancellationTokenSource = new CancellationTokenSource();
|
||||
|
@ -249,7 +249,7 @@ namespace MediaBrowser.Server.Implementations.Providers
|
|||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
_logger.Info("{0} cancelled for {1}", provider.GetType().Name, item.Name);
|
||||
_logger.Debug("{0} cancelled for {1}", provider.GetType().Name, item.Name);
|
||||
|
||||
// If the outer cancellation token is the one that caused the cancellation, throw it
|
||||
if (cancellationToken.IsCancellationRequested && ex.CancellationToken == cancellationToken)
|
||||
|
@ -325,8 +325,6 @@ namespace MediaBrowser.Server.Implementations.Providers
|
|||
/// </summary>
|
||||
private void ValidateCurrentlyRunningProviders()
|
||||
{
|
||||
_logger.Info("Validing currently running providers");
|
||||
|
||||
var enableInternetProviders = ConfigurationManager.Configuration.EnableInternetProviders;
|
||||
var internetProviderExcludeTypes = ConfigurationManager.Configuration.InternetProviderExcludeTypes;
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Common.Net;
|
||||
using System.Globalization;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Weather;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
|
@ -181,6 +182,8 @@ namespace MediaBrowser.Server.Implementations.WorldWeatherOnline
|
|||
/// <value>The weather code.</value>
|
||||
public string weatherCode { get; set; }
|
||||
|
||||
protected static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
/// <summary>
|
||||
/// To the weather status.
|
||||
/// </summary>
|
||||
|
@ -189,9 +192,9 @@ namespace MediaBrowser.Server.Implementations.WorldWeatherOnline
|
|||
{
|
||||
return new WeatherStatus
|
||||
{
|
||||
TemperatureCelsius = int.Parse(temp_C),
|
||||
TemperatureFahrenheit = int.Parse(temp_F),
|
||||
Humidity = int.Parse(humidity),
|
||||
TemperatureCelsius = int.Parse(temp_C, UsCulture),
|
||||
TemperatureFahrenheit = int.Parse(temp_F, UsCulture),
|
||||
Humidity = int.Parse(humidity, UsCulture),
|
||||
Condition = DailyWeatherInfo.GetCondition(weatherCode)
|
||||
};
|
||||
}
|
||||
|
@ -263,6 +266,8 @@ namespace MediaBrowser.Server.Implementations.WorldWeatherOnline
|
|||
/// <value>The windspeed miles.</value>
|
||||
public string windspeedMiles { get; set; }
|
||||
|
||||
protected static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
/// <summary>
|
||||
/// To the weather forecast.
|
||||
/// </summary>
|
||||
|
@ -271,11 +276,11 @@ namespace MediaBrowser.Server.Implementations.WorldWeatherOnline
|
|||
{
|
||||
return new WeatherForecast
|
||||
{
|
||||
Date = DateTime.Parse(date),
|
||||
HighTemperatureCelsius = int.Parse(tempMaxC),
|
||||
HighTemperatureFahrenheit = int.Parse(tempMaxF),
|
||||
LowTemperatureCelsius = int.Parse(tempMinC),
|
||||
LowTemperatureFahrenheit = int.Parse(tempMinF),
|
||||
Date = DateTime.Parse(date, UsCulture),
|
||||
HighTemperatureCelsius = int.Parse(tempMaxC, UsCulture),
|
||||
HighTemperatureFahrenheit = int.Parse(tempMaxF, UsCulture),
|
||||
LowTemperatureCelsius = int.Parse(tempMinC, UsCulture),
|
||||
LowTemperatureFahrenheit = int.Parse(tempMinF, UsCulture),
|
||||
Condition = GetCondition(weatherCode)
|
||||
};
|
||||
}
|
||||
|
|
|
@ -205,4 +205,7 @@ Global
|
|||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(Performance) = preSolution
|
||||
HasPerformanceSessions = true
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
Loading…
Reference in New Issue
Block a user