diff options
22 files changed, 182 insertions, 177 deletions
diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs index 8498292da..cb26688e3 100644 --- a/MediaBrowser.Api/Images/ImageService.cs +++ b/MediaBrowser.Api/Images/ImageService.cs @@ -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); } diff --git a/MediaBrowser.Api/UserLibrary/GenresService.cs b/MediaBrowser.Api/UserLibrary/GenresService.cs index 1962dff5c..5957c7ce6 100644 --- a/MediaBrowser.Api/UserLibrary/GenresService.cs +++ b/MediaBrowser.Api/UserLibrary/GenresService.cs @@ -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 { } diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index a8a9109c1..77b991a54 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -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> diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs index 3e0f24999..5c9c8e1f3 100644 --- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs +++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs @@ -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); diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs index 0e9696648..8508fcdf5 100644 --- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs +++ b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs @@ -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)) { diff --git a/MediaBrowser.Common.Implementations/NetworkManagement/NetworkManager.cs b/MediaBrowser.Common.Implementations/NetworkManagement/NetworkManager.cs index 513339eef..d88b57be5 100644 --- a/MediaBrowser.Common.Implementations/NetworkManagement/NetworkManager.cs +++ b/MediaBrowser.Common.Implementations/NetworkManagement/NetworkManager.cs @@ -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> diff --git a/MediaBrowser.Common/Net/BasePeriodicWebSocketListener.cs b/MediaBrowser.Common/Net/BasePeriodicWebSocketListener.cs index a8e8d7a8c..4ff34cfa1 100644 --- a/MediaBrowser.Common/Net/BasePeriodicWebSocketListener.cs +++ b/MediaBrowser.Common/Net/BasePeriodicWebSocketListener.cs @@ -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(); diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 474d14ee1..d30f11f7d 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -951,33 +951,6 @@ namespace MediaBrowser.Controller.Entities } /// <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> /// <param name="id">The id.</param> diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 83f29e58b..5a61844c2 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -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); } @@ -914,36 +914,6 @@ namespace MediaBrowser.Controller.Entities } /// <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> /// <param name="path">The path.</param> diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs index 5d8ada21f..a9dfde7f9 100644 --- a/MediaBrowser.Controller/Entities/Movies/Movie.cs +++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs @@ -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 diff --git a/MediaBrowser.Controller/Extensions/XmlExtensions.cs b/MediaBrowser.Controller/Extensions/XmlExtensions.cs index 00bee7d1d..8698730d4 100644 --- a/MediaBrowser.Controller/Extensions/XmlExtensions.cs +++ b/MediaBrowser.Controller/Extensions/XmlExtensions.cs @@ -191,7 +191,6 @@ namespace MediaBrowser.Controller.Extensions if (!string.IsNullOrWhiteSpace(valueString)) { - int.TryParse(valueString, out value); } diff --git a/MediaBrowser.Controller/Library/DtoBuilder.cs b/MediaBrowser.Controller/Library/DtoBuilder.cs index c3102ab64..36c7eba1f 100644 --- a/MediaBrowser.Controller/Library/DtoBuilder.cs +++ b/MediaBrowser.Controller/Library/DtoBuilder.cs @@ -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) { diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index 84a39db69..1b9d2f4b2 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -137,14 +137,6 @@ namespace MediaBrowser.Controller.Library 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> /// <param name="item">The item.</param> diff --git a/MediaBrowser.Controller/Providers/MediaInfo/BaseFFProbeProvider.cs b/MediaBrowser.Controller/Providers/MediaInfo/BaseFFProbeProvider.cs index e61611828..a465adeb6 100644 --- a/MediaBrowser.Controller/Providers/MediaInfo/BaseFFProbeProvider.cs +++ b/MediaBrowser.Controller/Providers/MediaInfo/BaseFFProbeProvider.cs @@ -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; diff --git a/MediaBrowser.Controller/Providers/MediaInfo/FFProbeAudioInfoProvider.cs b/MediaBrowser.Controller/Providers/MediaInfo/FFProbeAudioInfoProvider.cs index 603b7dcaa..a7cc4985b 100644 --- a/MediaBrowser.Controller/Providers/MediaInfo/FFProbeAudioInfoProvider.cs +++ b/MediaBrowser.Controller/Providers/MediaInfo/FFProbeAudioInfoProvider.cs @@ -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) diff --git a/MediaBrowser.Controller/Providers/MediaInfo/FFProbeVideoInfoProvider.cs b/MediaBrowser.Controller/Providers/MediaInfo/FFProbeVideoInfoProvider.cs index 06692b2bc..957000ae2 100644 --- a/MediaBrowser.Controller/Providers/MediaInfo/FFProbeVideoInfoProvider.cs +++ b/MediaBrowser.Controller/Providers/MediaInfo/FFProbeVideoInfoProvider.cs @@ -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; } } diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs index 681b08825..edb227c79 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs @@ -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) { diff --git a/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs b/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs index a355a2db5..24292f0a1 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs @@ -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)); diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index cf12d6ad5..303580a49 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -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>(); @@ -228,6 +252,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> /// <param name="args">The args.</param> @@ -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> @@ -709,32 +799,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> /// <param name="id">The id.</param> @@ -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> diff --git a/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs b/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs index a8239deb4..df6e06174 100644 --- a/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs +++ b/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs @@ -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; diff --git a/MediaBrowser.Server.Implementations/WorldWeatherOnline/WeatherProvider.cs b/MediaBrowser.Server.Implementations/WorldWeatherOnline/WeatherProvider.cs index ae8b1ff97..195bfeee3 100644 --- a/MediaBrowser.Server.Implementations/WorldWeatherOnline/WeatherProvider.cs +++ b/MediaBrowser.Server.Implementations/WorldWeatherOnline/WeatherProvider.cs @@ -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) }; } diff --git a/MediaBrowser.sln b/MediaBrowser.sln index e5ccebc7b..c3a809c3f 100644 --- a/MediaBrowser.sln +++ b/MediaBrowser.sln @@ -205,4 +205,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(Performance) = preSolution + HasPerformanceSessions = true + EndGlobalSection EndGlobal |
