diff options
51 files changed, 499 insertions, 381 deletions
diff --git a/MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs b/MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs index 71001a657..d4f824198 100644 --- a/MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs +++ b/MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs @@ -4,8 +4,10 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Localization; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Querying; using ServiceStack.ServiceHost; using System; using System.Collections.Generic; @@ -26,8 +28,11 @@ namespace MediaBrowser.Api.DefaultTheme { [ApiMember(Name = "UserId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] public Guid UserId { get; set; } + + [ApiMember(Name = "FamilyRating", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public string FamilyRating { get; set; } } - + public class DefaultThemeService : BaseApiService { private readonly IUserManager _userManager; @@ -35,12 +40,15 @@ namespace MediaBrowser.Api.DefaultTheme private readonly ILogger _logger; private readonly ILibraryManager _libraryManager; - public DefaultThemeService(IUserManager userManager, IDtoService dtoService, ILogger logger, ILibraryManager libraryManager) + private readonly ILocalizationManager _localization; + + public DefaultThemeService(IUserManager userManager, IDtoService dtoService, ILogger logger, ILibraryManager libraryManager, ILocalizationManager localization) { _userManager = userManager; _dtoService = dtoService; _logger = logger; _libraryManager = libraryManager; + _localization = localization; } public object Get(GetTvView request) @@ -62,19 +70,16 @@ namespace MediaBrowser.Api.DefaultTheme var view = new TvView(); - view.BackdropItems = seriesWithBackdrops + var fields = Enum.GetNames(typeof(ItemFields)) + .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)) + .ToList(); + + var spotlightItemTasks = seriesWithBackdrops .OrderBy(i => Guid.NewGuid()) - .Select(i => GetItemStub(i, ImageType.Backdrop)) - .Where(i => i != null) .Take(30) - .ToArray(); + .Select(i => _dtoService.GetBaseItemDto(i, fields, user)); - view.SpotlightItems = seriesWithBackdrops - .OrderBy(i => Guid.NewGuid()) - .Select(i => GetItemStub(i, ImageType.Backdrop)) - .Where(i => i != null) - .Take(30) - .ToArray(); + view.SpotlightItems = await Task.WhenAll(spotlightItemTasks).ConfigureAwait(false); view.ShowsItems = series .Where(i => !string.IsNullOrEmpty(i.PrimaryImagePath)) @@ -104,31 +109,43 @@ namespace MediaBrowser.Api.DefaultTheme .Where(i => i is Movie || i is Trailer || i is BoxSet) .ToList(); + var actorsTask = GetActors(items); + // Exclude trailers from backdrops because they're not always 1080p var itemsWithBackdrops = items.Where(i => i.BackdropImagePaths.Count > 0 && !(i is Trailer)) .ToList(); - var movies = items.OfType<Movie>().ToList(); + var baselineRating = _localization.GetRatingLevel(request.FamilyRating ?? "PG"); + + var view = new MoviesView(); + + var movies = items.OfType<Movie>() + .ToList(); + + var hdMovies = movies.Where(i => i.IsHd).ToList(); + + var familyMovies = movies.Where(i => IsFamilyMovie(i, baselineRating)).ToList(); + + view.HDMoviePercentage = 100 * hdMovies.Count; + view.HDMoviePercentage /= movies.Count; + view.FamilyMoviePercentage = 100 * familyMovies.Count; + view.FamilyMoviePercentage /= movies.Count; + var moviesWithImages = movies .Where(i => !string.IsNullOrEmpty(i.PrimaryImagePath)) .ToList(); - var view = new MoviesView(); + var fields = Enum.GetNames(typeof(ItemFields)) + .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)) + .ToList(); - view.BackdropItems = itemsWithBackdrops + var spotlightItemTasks = itemsWithBackdrops .OrderBy(i => Guid.NewGuid()) - .Select(i => GetItemStub(i, ImageType.Backdrop)) - .Where(i => i != null) .Take(30) - .ToArray(); + .Select(i => _dtoService.GetBaseItemDto(i, fields, user)); - view.SpotlightItems = itemsWithBackdrops - .OrderBy(i => Guid.NewGuid()) - .Select(i => GetItemStub(i, ImageType.Backdrop)) - .Where(i => i != null) - .Take(30) - .ToArray(); + view.SpotlightItems = await Task.WhenAll(spotlightItemTasks).ConfigureAwait(false); view.MovieItems = moviesWithImages .OrderBy(i => Guid.NewGuid()) @@ -155,8 +172,6 @@ namespace MediaBrowser.Api.DefaultTheme .Take(3) .ToArray(); - view.PeopleItems = await GetActors(items).ConfigureAwait(false); - view.ThreeDItems = moviesWithImages .Where(i => i.Is3D) .OrderBy(i => Guid.NewGuid()) @@ -165,17 +180,51 @@ namespace MediaBrowser.Api.DefaultTheme .Take(3) .ToArray(); - view.HDItems = moviesWithImages - .Where(i => i.IsHd) + view.HDItems = hdMovies + .Where(i => !string.IsNullOrEmpty(i.PrimaryImagePath)) .OrderBy(i => Guid.NewGuid()) .Select(i => GetItemStub(i, ImageType.Primary)) .Where(i => i != null) .Take(3) .ToArray(); + view.FamilyMovies = familyMovies + .Where(i => !string.IsNullOrEmpty(i.PrimaryImagePath)) + .OrderBy(i => Guid.NewGuid()) + .Select(i => GetItemStub(i, ImageType.Primary)) + .Where(i => i != null) + .Take(3) + .ToArray(); + + view.PeopleItems = await actorsTask.ConfigureAwait(false); + return view; } + private bool IsFamilyMovie(BaseItem item, int? baselineRating) + { + var ratingString = item.CustomRating; + + if (string.IsNullOrEmpty(ratingString)) + { + ratingString = item.OfficialRating; + } + + if (string.IsNullOrEmpty(ratingString)) + { + return false; + } + + var rating = _localization.GetRatingLevel(ratingString); + + if (!baselineRating.HasValue || !rating.HasValue) + { + return false; + } + + return rating.Value <= baselineRating.Value; + } + private async Task<ItemStub[]> GetActors(IEnumerable<BaseItem> mediaItems) { var actorStubs = new List<ItemStub>(); @@ -183,6 +232,7 @@ namespace MediaBrowser.Api.DefaultTheme var actors = mediaItems.SelectMany(i => i.People) .Select(i => i.Name) .Distinct(StringComparer.OrdinalIgnoreCase) + .OrderBy(i => Guid.NewGuid()) .ToList(); foreach (var actor in actors) diff --git a/MediaBrowser.Api/DefaultTheme/MoviesView.cs b/MediaBrowser.Api/DefaultTheme/MoviesView.cs index 0802473d2..6bf1bfdd9 100644 --- a/MediaBrowser.Api/DefaultTheme/MoviesView.cs +++ b/MediaBrowser.Api/DefaultTheme/MoviesView.cs @@ -1,10 +1,10 @@ - +using MediaBrowser.Model.Dto; + namespace MediaBrowser.Api.DefaultTheme { public class MoviesView { - public ItemStub[] SpotlightItems { get; set; } - public ItemStub[] BackdropItems { get; set; } + public BaseItemDto[] SpotlightItems { get; set; } public ItemStub[] MovieItems { get; set; } public ItemStub[] PeopleItems { get; set; } @@ -12,5 +12,11 @@ namespace MediaBrowser.Api.DefaultTheme public ItemStub[] TrailerItems { get; set; } public ItemStub[] HDItems { get; set; } public ItemStub[] ThreeDItems { get; set; } + + public ItemStub[] FamilyMovies { get; set; } + + public double FamilyMoviePercentage { get; set; } + + public double HDMoviePercentage { get; set; } } } diff --git a/MediaBrowser.Api/DefaultTheme/TvView.cs b/MediaBrowser.Api/DefaultTheme/TvView.cs index b7379699d..ba7d120f1 100644 --- a/MediaBrowser.Api/DefaultTheme/TvView.cs +++ b/MediaBrowser.Api/DefaultTheme/TvView.cs @@ -1,10 +1,10 @@ - +using MediaBrowser.Model.Dto; + namespace MediaBrowser.Api.DefaultTheme { public class TvView { - public ItemStub[] SpotlightItems { get; set; } - public ItemStub[] BackdropItems { get; set; } + public BaseItemDto[] SpotlightItems { get; set; } public ItemStub[] ShowsItems { get; set; } public ItemStub[] ActorItems { get; set; } } diff --git a/MediaBrowser.Api/ItemUpdateService.cs b/MediaBrowser.Api/ItemUpdateService.cs index df5c32b99..0428570cc 100644 --- a/MediaBrowser.Api/ItemUpdateService.cs +++ b/MediaBrowser.Api/ItemUpdateService.cs @@ -207,13 +207,15 @@ namespace MediaBrowser.Api item.ForcedSortName = request.SortName; } - item.DisplayMediaType = request.DisplayMediaType; - item.CommunityRating = request.CommunityRating; - item.HomePageUrl = request.HomePageUrl; item.Budget = request.Budget; item.Revenue = request.Revenue; + item.CriticRating = request.CriticRating; item.CriticRatingSummary = request.CriticRatingSummary; + + item.DisplayMediaType = request.DisplayMediaType; + item.CommunityRating = request.CommunityRating; + item.HomePageUrl = request.HomePageUrl; item.IndexNumber = request.IndexNumber; item.ParentIndexNumber = request.ParentIndexNumber; item.Overview = request.Overview; diff --git a/MediaBrowser.Api/SimilarItemsHelper.cs b/MediaBrowser.Api/SimilarItemsHelper.cs index 5d10afd2c..987786045 100644 --- a/MediaBrowser.Api/SimilarItemsHelper.cs +++ b/MediaBrowser.Api/SimilarItemsHelper.cs @@ -139,7 +139,6 @@ namespace MediaBrowser.Api .Select(i => new Tuple<BaseItem, int>(i, getSimilarityScore(item, i))) .Where(i => i.Item2 > 2) .OrderByDescending(i => i.Item2) - .ThenByDescending(i => i.Item1.CriticRating ?? 0) .Select(i => i.Item1); } diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index 1cf8fda20..80246a5d8 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -121,7 +121,7 @@ namespace MediaBrowser.Api.UserLibrary [ApiMember(Name = "AlbumArtistStartsWithOrGreater", Description = "Optional filter by items whose album artist is sorted equally or greater than a given input string.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string AlbumArtistStartsWithOrGreater { get; set; } - + /// <summary> /// Gets or sets the air days. /// </summary> @@ -161,8 +161,14 @@ namespace MediaBrowser.Api.UserLibrary [ApiMember(Name = "AdjacentTo", Description = "Optional. Return items that are siblings of a supplied item.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string AdjacentTo { get; set; } - [ApiMember(Name = "MinIndexNumber", Description = "Optional filter index number.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] + [ApiMember(Name = "MinIndexNumber", Description = "Optional filter by minimum index number.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] public int? MinIndexNumber { get; set; } + + [ApiMember(Name = "HasParentalRating", Description = "Optional filter by items that have or do not have a parental rating", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] + public bool? HasParentalRating { get; set; } + + [ApiMember(Name = "IsHD", Description = "Optional filter by items that are HD or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] + public bool? IsHD { get; set; } } /// <summary> @@ -481,7 +487,12 @@ namespace MediaBrowser.Api.UserLibrary { items = items.Where(i => { - var rating = i.CustomRating ?? i.OfficialRating; + var rating = i.CustomRating; + + if (string.IsNullOrEmpty(rating)) + { + rating = i.OfficialRating; + } if (string.IsNullOrEmpty(rating)) { @@ -504,7 +515,12 @@ namespace MediaBrowser.Api.UserLibrary { items = items.Where(i => { - var rating = i.CustomRating ?? i.OfficialRating; + var rating = i.CustomRating; + + if (string.IsNullOrEmpty(rating)) + { + rating = i.OfficialRating; + } if (string.IsNullOrEmpty(rating)) { @@ -669,6 +685,31 @@ namespace MediaBrowser.Api.UserLibrary }); } + if (request.HasParentalRating.HasValue) + { + items = items.Where(i => + { + var rating = i.CustomRating; + + if (string.IsNullOrEmpty(rating)) + { + rating = i.OfficialRating; + } + + if (request.HasParentalRating.Value) + { + return !string.IsNullOrEmpty(rating); + } + + return string.IsNullOrEmpty(rating); + }); + } + + if (request.IsHD.HasValue) + { + items = items.OfType<Video>().Where(i => i.IsHd == request.IsHD.Value); + } + return items; } diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj index aa7a45206..350d1eba5 100644 --- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj +++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj @@ -43,9 +43,9 @@ <SpecificVersion>False</SpecificVersion> <HintPath>..\packages\ServiceStack.Text.3.9.58\lib\net35\ServiceStack.Text.dll</HintPath> </Reference> - <Reference Include="SimpleInjector, Version=2.3.2.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL"> + <Reference Include="SimpleInjector, Version=2.3.5.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\SimpleInjector.2.3.2\lib\net40-client\SimpleInjector.dll</HintPath> + <HintPath>..\packages\SimpleInjector.2.3.5\lib\net40-client\SimpleInjector.dll</HintPath> </Reference> <Reference Include="System" /> <Reference Include="System.Configuration" /> diff --git a/MediaBrowser.Common.Implementations/packages.config b/MediaBrowser.Common.Implementations/packages.config index 136ec1439..406db6d1a 100644 --- a/MediaBrowser.Common.Implementations/packages.config +++ b/MediaBrowser.Common.Implementations/packages.config @@ -2,5 +2,5 @@ <packages> <package id="NLog" version="2.0.1.2" targetFramework="net45" /> <package id="ServiceStack.Text" version="3.9.58" targetFramework="net45" /> - <package id="SimpleInjector" version="2.3.2" targetFramework="net45" /> + <package id="SimpleInjector" version="2.3.5" targetFramework="net45" /> </packages>
\ No newline at end of file diff --git a/MediaBrowser.Controller/Entities/Audio/Artist.cs b/MediaBrowser.Controller/Entities/Audio/Artist.cs index 49aa9b525..e0d80527c 100644 --- a/MediaBrowser.Controller/Entities/Audio/Artist.cs +++ b/MediaBrowser.Controller/Entities/Audio/Artist.cs @@ -12,7 +12,6 @@ namespace MediaBrowser.Controller.Entities.Audio { public Artist() { - ItemCounts = new ItemByNameCounts(); UserItemCounts = new Dictionary<Guid, ItemByNameCounts>(); } @@ -28,9 +27,6 @@ namespace MediaBrowser.Controller.Entities.Audio } [IgnoreDataMember] - public ItemByNameCounts ItemCounts { get; set; } - - [IgnoreDataMember] public Dictionary<Guid, ItemByNameCounts> UserItemCounts { get; set; } } } diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs index 46b4bc73c..0c88eed5b 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; @@ -11,7 +12,7 @@ namespace MediaBrowser.Controller.Entities.Audio { public MusicAlbum() { - Artists = new string[] { }; + Artists = new List<string>(); } public string LastFmImageUrl { get; set; } @@ -72,7 +73,7 @@ namespace MediaBrowser.Controller.Entities.Audio public string AlbumArtist { get; set; } - public string[] Artists { get; set; } + public List<string> Artists { get; set; } } public class MusicAlbumDisc : Folder diff --git a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs index 5254a36bc..ec2995fb2 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs @@ -12,7 +12,6 @@ namespace MediaBrowser.Controller.Entities.Audio { public MusicGenre() { - ItemCounts = new ItemByNameCounts(); UserItemCounts = new Dictionary<Guid, ItemByNameCounts>(); } @@ -26,9 +25,6 @@ namespace MediaBrowser.Controller.Entities.Audio } [IgnoreDataMember] - public ItemByNameCounts ItemCounts { get; set; } - - [IgnoreDataMember] public Dictionary<Guid, ItemByNameCounts> UserItemCounts { get; set; } } } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 4887af2cf..84b6d8097 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -31,10 +31,8 @@ namespace MediaBrowser.Controller.Entities protected BaseItem() { Genres = new List<string>(); - RemoteTrailers = new List<MediaUrl>(); Studios = new List<string>(); People = new List<PersonInfo>(); - Taglines = new List<string>(); ScreenshotImagePaths = new List<string>(); BackdropImagePaths = new List<string>(); ProductionLocations = new List<string>(); @@ -46,6 +44,8 @@ namespace MediaBrowser.Controller.Entities SoundtrackIds = new List<Guid>(); LocalTrailerIds = new List<Guid>(); LockedFields = new List<MetadataFields>(); + Taglines = new List<string>(); + RemoteTrailers = new List<MediaUrl>(); } /// <summary> @@ -91,6 +91,42 @@ namespace MediaBrowser.Controller.Entities public Guid Id { get; set; } /// <summary> + /// Gets or sets the budget. + /// </summary> + /// <value>The budget.</value> + public double? Budget { get; set; } + + /// <summary> + /// Gets or sets the taglines. + /// </summary> + /// <value>The taglines.</value> + public List<string> Taglines { get; set; } + + /// <summary> + /// Gets or sets the revenue. + /// </summary> + /// <value>The revenue.</value> + public double? Revenue { get; set; } + + /// <summary> + /// Gets or sets the critic rating. + /// </summary> + /// <value>The critic rating.</value> + public float? CriticRating { get; set; } + + /// <summary> + /// Gets or sets the critic rating summary. + /// </summary> + /// <value>The critic rating summary.</value> + public string CriticRatingSummary { get; set; } + + /// <summary> + /// Gets or sets the trailer URL. + /// </summary> + /// <value>The trailer URL.</value> + public List<MediaUrl> RemoteTrailers { get; set; } + + /// <summary> /// Return the id that should be used to key display prefs for this item. /// Default is based on the type for everything except actual generic folders. /// </summary> @@ -522,11 +558,6 @@ namespace MediaBrowser.Controller.Entities /// </summary> /// <value>The overview.</value> public string Overview { get; set; } - /// <summary> - /// Gets or sets the taglines. - /// </summary> - /// <value>The taglines.</value> - public List<string> Taglines { get; set; } /// <summary> /// Gets or sets the people. @@ -581,36 +612,12 @@ namespace MediaBrowser.Controller.Entities public string HomePageUrl { get; set; } /// <summary> - /// Gets or sets the budget. - /// </summary> - /// <value>The budget.</value> - public double? Budget { get; set; } - - /// <summary> - /// Gets or sets the revenue. - /// </summary> - /// <value>The revenue.</value> - public double? Revenue { get; set; } - - /// <summary> /// Gets or sets the production locations. /// </summary> /// <value>The production locations.</value> public List<string> ProductionLocations { get; set; } /// <summary> - /// Gets or sets the critic rating. - /// </summary> - /// <value>The critic rating.</value> - public float? CriticRating { get; set; } - - /// <summary> - /// Gets or sets the critic rating summary. - /// </summary> - /// <value>The critic rating summary.</value> - public string CriticRatingSummary { get; set; } - - /// <summary> /// Gets or sets the community rating. /// </summary> /// <value>The community rating.</value> @@ -974,12 +981,6 @@ namespace MediaBrowser.Controller.Entities } /// <summary> - /// Gets or sets the trailer URL. - /// </summary> - /// <value>The trailer URL.</value> - public List<MediaUrl> RemoteTrailers { get; set; } - - /// <summary> /// Gets or sets the provider ids. /// </summary> /// <value>The provider ids.</value> @@ -1256,53 +1257,6 @@ namespace MediaBrowser.Controller.Entities } /// <summary> - /// Adds a tagline to the item - /// </summary> - /// <param name="name">The name.</param> - /// <exception cref="System.ArgumentNullException"></exception> - public void AddTagline(string name) - { - if (string.IsNullOrWhiteSpace(name)) - { - throw new ArgumentNullException("name"); - } - - if (!Taglines.Contains(name, StringComparer.OrdinalIgnoreCase)) - { - Taglines.Add(name); - } - } - - /// <summary> - /// Adds a TrailerUrl to the item - /// </summary> - /// <param name="url">The URL.</param> - /// <param name="isDirectLink">if set to <c>true</c> [is direct link].</param> - /// <exception cref="System.ArgumentNullException">url</exception> - public void AddTrailerUrl(string url, bool isDirectLink) - { - if (string.IsNullOrWhiteSpace(url)) - { - throw new ArgumentNullException("url"); - } - - var current = RemoteTrailers.FirstOrDefault(i => string.Equals(i.Url, url, StringComparison.OrdinalIgnoreCase)); - - if (current != null) - { - current.IsDirectLink = isDirectLink; - } - else - { - RemoteTrailers.Add(new MediaUrl - { - Url = url, - IsDirectLink = isDirectLink - }); - } - } - - /// <summary> /// Adds a genre to the item /// </summary> /// <param name="name">The name.</param> @@ -1545,7 +1499,6 @@ namespace MediaBrowser.Controller.Entities { // Only validate paths from the same directory - need to copy to a list because we are going to potentially modify the collection below var deletedKeys = Images - .ToList() .Where(image => !File.Exists(image.Value)) .Select(i => i.Key) .ToList(); diff --git a/MediaBrowser.Controller/Entities/Extensions.cs b/MediaBrowser.Controller/Entities/Extensions.cs new file mode 100644 index 000000000..311e28cbb --- /dev/null +++ b/MediaBrowser.Controller/Entities/Extensions.cs @@ -0,0 +1,51 @@ +using MediaBrowser.Model.Entities; +using System; +using System.Linq; + +namespace MediaBrowser.Controller.Entities +{ + public static class Extensions + { + /// <summary> + /// Adds the tagline. + /// </summary> + /// <param name="item">The item.</param> + /// <param name="tagline">The tagline.</param> + /// <exception cref="System.ArgumentNullException">tagline</exception> + public static void AddTagline(this BaseItem item, string tagline) + { + if (string.IsNullOrWhiteSpace(tagline)) + { + throw new ArgumentNullException("tagline"); + } + + if (!item.Taglines.Contains(tagline, StringComparer.OrdinalIgnoreCase)) + { + item.Taglines.Add(tagline); + } + } + + public static void AddTrailerUrl(this BaseItem item, string url, bool isDirectLink) + { + if (string.IsNullOrWhiteSpace(url)) + { + throw new ArgumentNullException("url"); + } + + var current = item.RemoteTrailers.FirstOrDefault(i => string.Equals(i.Url, url, StringComparison.OrdinalIgnoreCase)); + + if (current != null) + { + current.IsDirectLink = isDirectLink; + } + else + { + item.RemoteTrailers.Add(new MediaUrl + { + Url = url, + IsDirectLink = isDirectLink + }); + } + } + } +} diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index bc009e548..d7e1db743 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -499,7 +499,7 @@ namespace MediaBrowser.Controller.Entities { get { - return ActualChildren.Values.ToList(); + return ActualChildren.Values.ToArray(); } } @@ -757,7 +757,7 @@ namespace MediaBrowser.Controller.Entities { var list = children.ToList(); - var percentages = new Dictionary<Guid, double>(); + var percentages = new Dictionary<Guid, double>(list.Count); var tasks = new List<Task>(); diff --git a/MediaBrowser.Controller/Entities/GameGenre.cs b/MediaBrowser.Controller/Entities/GameGenre.cs index b34df2abd..0c877782e 100644 --- a/MediaBrowser.Controller/Entities/GameGenre.cs +++ b/MediaBrowser.Controller/Entities/GameGenre.cs @@ -9,7 +9,6 @@ namespace MediaBrowser.Controller.Entities { public GameGenre() { - ItemCounts = new ItemByNameCounts(); UserItemCounts = new Dictionary<Guid, ItemByNameCounts>(); } @@ -23,9 +22,6 @@ namespace MediaBrowser.Controller.Entities } [IgnoreDataMember] - public ItemByNameCounts ItemCounts { get; set; } - - [IgnoreDataMember] public Dictionary<Guid, ItemByNameCounts> UserItemCounts { get; set; } } } diff --git a/MediaBrowser.Controller/Entities/Genre.cs b/MediaBrowser.Controller/Entities/Genre.cs index 0aa4e478a..71fa05720 100644 --- a/MediaBrowser.Controller/Entities/Genre.cs +++ b/MediaBrowser.Controller/Entities/Genre.cs @@ -12,7 +12,6 @@ namespace MediaBrowser.Controller.Entities { public Genre() { - ItemCounts = new ItemByNameCounts(); UserItemCounts = new Dictionary<Guid, ItemByNameCounts>(); } @@ -26,9 +25,6 @@ namespace MediaBrowser.Controller.Entities } [IgnoreDataMember] - public ItemByNameCounts ItemCounts { get; set; } - - [IgnoreDataMember] public Dictionary<Guid, ItemByNameCounts> UserItemCounts { get; set; } } } diff --git a/MediaBrowser.Controller/Entities/IItemByName.cs b/MediaBrowser.Controller/Entities/IItemByName.cs index ea23d7e3f..7284bf101 100644 --- a/MediaBrowser.Controller/Entities/IItemByName.cs +++ b/MediaBrowser.Controller/Entities/IItemByName.cs @@ -9,8 +9,6 @@ namespace MediaBrowser.Controller.Entities /// </summary> public interface IItemByName { - ItemByNameCounts ItemCounts { get; set; } - Dictionary<Guid, ItemByNameCounts> UserItemCounts { get; set; } } @@ -20,7 +18,7 @@ namespace MediaBrowser.Controller.Entities { if (user == null) { - return item.ItemCounts; + throw new ArgumentNullException("user"); } ItemByNameCounts counts; diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs index 89ab2d289..e5cf48ad0 100644 --- a/MediaBrowser.Controller/Entities/Person.cs +++ b/MediaBrowser.Controller/Entities/Person.cs @@ -12,14 +12,10 @@ namespace MediaBrowser.Controller.Entities { public Person() { - ItemCounts = new ItemByNameCounts(); UserItemCounts = new Dictionary<Guid, ItemByNameCounts>(); } [IgnoreDataMember] - public ItemByNameCounts ItemCounts { get; set; } - - [IgnoreDataMember] public Dictionary<Guid, ItemByNameCounts> UserItemCounts { get; set; } /// <summary> diff --git a/MediaBrowser.Controller/Entities/Studio.cs b/MediaBrowser.Controller/Entities/Studio.cs index d3b356661..bbe96a88b 100644 --- a/MediaBrowser.Controller/Entities/Studio.cs +++ b/MediaBrowser.Controller/Entities/Studio.cs @@ -12,7 +12,6 @@ namespace MediaBrowser.Controller.Entities { public Studio() { - ItemCounts = new ItemByNameCounts(); UserItemCounts = new Dictionary<Guid, ItemByNameCounts>(); } @@ -26,9 +25,6 @@ namespace MediaBrowser.Controller.Entities } [IgnoreDataMember] - public ItemByNameCounts ItemCounts { get; set; } - - [IgnoreDataMember] public Dictionary<Guid, ItemByNameCounts> UserItemCounts { get; set; } } } diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs index 044de3d6b..e7d47f7ec 100644 --- a/MediaBrowser.Controller/Entities/Trailer.cs +++ b/MediaBrowser.Controller/Entities/Trailer.cs @@ -1,5 +1,6 @@ -using System.Runtime.Serialization; -using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Entities; +using System.Collections.Generic; +using System.Runtime.Serialization; namespace MediaBrowser.Controller.Entities { @@ -8,6 +9,12 @@ namespace MediaBrowser.Controller.Entities /// </summary> public class Trailer : Video { + public Trailer() + { + RemoteTrailers = new List<MediaUrl>(); + Taglines = new List<string>(); + } + /// <summary> /// Gets a value indicating whether this instance is local trailer. /// </summary> diff --git a/MediaBrowser.Controller/Entities/Year.cs b/MediaBrowser.Controller/Entities/Year.cs index 737feb777..d0f457718 100644 --- a/MediaBrowser.Controller/Entities/Year.cs +++ b/MediaBrowser.Controller/Entities/Year.cs @@ -12,14 +12,10 @@ namespace MediaBrowser.Controller.Entities { public Year() { - ItemCounts = new ItemByNameCounts(); UserItemCounts = new Dictionary<Guid, ItemByNameCounts>(); } [IgnoreDataMember] - public ItemByNameCounts ItemCounts { get; set; } - - [IgnoreDataMember] public Dictionary<Guid, ItemByNameCounts> UserItemCounts { get; set; } /// <summary> diff --git a/MediaBrowser.Controller/IO/FileSystem.cs b/MediaBrowser.Controller/IO/FileSystem.cs index e5f80533a..3d425f13f 100644 --- a/MediaBrowser.Controller/IO/FileSystem.cs +++ b/MediaBrowser.Controller/IO/FileSystem.cs @@ -106,13 +106,15 @@ namespace MediaBrowser.Controller.IO { throw new ArgumentNullException("filename"); } + + var builder = new StringBuilder(filename); foreach (var c in InvalidFileNameChars) { - filename = filename.Replace(c, SpaceChar); + builder = builder.Replace(c, SpaceChar); } - return filename; + return builder.ToString(); } /// <summary> diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index b6b80586a..678050ca4 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -48,6 +48,8 @@ namespace MediaBrowser.Controller.Library /// <value>The root folder.</value> AggregateFolder RootFolder { get; } + Person GetPersonSync(string name); + /// <summary> /// Gets a Person /// </summary> diff --git a/MediaBrowser.Controller/Library/ItemResolveArgs.cs b/MediaBrowser.Controller/Library/ItemResolveArgs.cs index daecefe5c..e296e0f18 100644 --- a/MediaBrowser.Controller/Library/ItemResolveArgs.cs +++ b/MediaBrowser.Controller/Library/ItemResolveArgs.cs @@ -245,7 +245,7 @@ namespace MediaBrowser.Controller.Library { throw new ArgumentNullException(); } - + if (MetadataFileDictionary == null) { MetadataFileDictionary = new Dictionary<string, FileSystemInfo>(StringComparer.OrdinalIgnoreCase); diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 990c5f670..0e97a9f2a 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -78,6 +78,7 @@ <Compile Include="Entities\Book.cs" /> <Compile Include="Configuration\IServerConfigurationManager.cs" /> <Compile Include="Entities\Audio\MusicGenre.cs" /> + <Compile Include="Entities\Extensions.cs" /> <Compile Include="Entities\Game.cs" /> <Compile Include="Entities\GameGenre.cs" /> <Compile Include="Entities\IByReferenceItem.cs" /> diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs index 5a0159370..13113c2b2 100644 --- a/MediaBrowser.Model/ApiClient/IApiClient.cs +++ b/MediaBrowser.Model/ApiClient/IApiClient.cs @@ -19,8 +19,14 @@ using System.Threading.Tasks; namespace MediaBrowser.Model.ApiClient { + /// <summary> + /// Interface IApiClient + /// </summary> public interface IApiClient : IDisposable { + /// <summary> + /// Occurs when [server location changed]. + /// </summary> event EventHandler ServerLocationChanged; /// <summary> @@ -28,12 +34,23 @@ namespace MediaBrowser.Model.ApiClient /// </summary> event EventHandler<HttpResponseEventArgs> HttpResponseReceived; - Task<T> GetAsync<T>(string url, CancellationToken cancellationToken); + string GetApiUrl(string handler); + + /// <summary> + /// Gets the async. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="url">The URL.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task{``0}.</returns> + Task<T> GetAsync<T>(string url, CancellationToken cancellationToken) + where T : class; /// <summary> /// Gets the critic reviews. /// </summary> /// <param name="itemId">The item id.</param> + /// <param name="cancellationToken">The cancellation token.</param> /// <param name="startIndex">The start index.</param> /// <param name="limit">The limit.</param> /// <returns>Task{ItemReviewsResult}.</returns> @@ -45,6 +62,7 @@ namespace MediaBrowser.Model.ApiClient /// <param name="userId">The user id.</param> /// <param name="itemId">The item id.</param> /// <param name="inheritFromParents">if set to <c>true</c> [inherit from parents].</param> + /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{ThemeMediaResult}.</returns> Task<ThemeMediaResult> GetThemeSongsAsync(string userId, string itemId, bool inheritFromParents, CancellationToken cancellationToken); @@ -65,6 +83,7 @@ namespace MediaBrowser.Model.ApiClient /// <param name="userId">The user id.</param> /// <param name="itemId">The item id.</param> /// <param name="inheritFromParents">if set to <c>true</c> [inherit from parents].</param> + /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{ThemeMediaResult}.</returns> Task<ThemeMediaResult> GetThemeVideosAsync(string userId, string itemId, bool inheritFromParents, CancellationToken cancellationToken); @@ -74,6 +93,7 @@ namespace MediaBrowser.Model.ApiClient /// <param name="userId">The user id.</param> /// <param name="itemId">The item id.</param> /// <param name="inheritFromParents">if set to <c>true</c> [inherit from parents].</param> + /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{AllThemeMediaResult}.</returns> Task<AllThemeMediaResult> GetAllThemeMediaAsync(string userId, string itemId, bool inheritFromParents, CancellationToken cancellationToken); @@ -152,12 +172,14 @@ namespace MediaBrowser.Model.ApiClient /// <summary> /// Gets the users async. /// </summary> + /// <param name="query">The query.</param> /// <returns>Task{UserDto[]}.</returns> Task<UserDto[]> GetUsersAsync(UserQuery query); /// <summary> /// Gets the public users async. /// </summary> + /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{UserDto[]}.</returns> Task<UserDto[]> GetPublicUsersAsync(CancellationToken cancellationToken); @@ -469,6 +491,7 @@ namespace MediaBrowser.Model.ApiClient /// <param name="userId">The user id.</param> /// <param name="positionTicks">The position ticks.</param> /// <param name="isPaused">if set to <c>true</c> [is paused].</param> + /// <param name="isMuted">if set to <c>true</c> [is muted].</param> /// <returns>Task{UserItemDataDto}.</returns> /// <exception cref="ArgumentNullException">itemId</exception> Task ReportPlaybackProgressAsync(string itemId, string userId, long? positionTicks, bool isPaused, bool isMuted); @@ -508,29 +531,27 @@ namespace MediaBrowser.Model.ApiClient /// <param name="sessionId">The session id.</param> /// <param name="request">The request.</param> /// <returns>Task.</returns> - /// <exception cref="ArgumentNullException"> - /// sessionId + /// <exception cref="ArgumentNullException">sessionId /// or - /// request - /// </exception> + /// request</exception> Task SendPlayCommandAsync(string sessionId, PlayRequest request); /// <summary> /// Sends a system command to the client /// </summary> - /// <param name="sessionId"></param> - /// <param name="command"></param> - /// <returns></returns> + /// <param name="sessionId">The session id.</param> + /// <param name="command">The command.</param> + /// <returns>Task.</returns> Task SendSystemCommandAsync(string sessionId, SystemCommand command); /// <summary> /// Instructs the client to display a message to the user /// </summary> - /// <param name="sessionId"></param> - /// <param name="command"></param> - /// <returns></returns> + /// <param name="sessionId">The session id.</param> + /// <param name="command">The command.</param> + /// <returns>Task.</returns> Task SendMessageCommandAsync(string sessionId, MessageCommand command); - + /// <summary> /// Clears a user's rating for an item /// </summary> @@ -582,14 +603,17 @@ namespace MediaBrowser.Model.ApiClient /// <param name="id">The id.</param> /// <param name="userId">The user id.</param> /// <param name="client">The client.</param> + /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{BaseItemDto}.</returns> Task<DisplayPreferences> GetDisplayPreferencesAsync(string id, string userId, string client, CancellationToken cancellationToken); /// <summary> /// Updates display preferences for a user /// </summary> - /// <param name="id">The id.</param> /// <param name="displayPreferences">The display preferences.</param> + /// <param name="userId">The user id.</param> + /// <param name="client">The client.</param> + /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{DisplayPreferences}.</returns> /// <exception cref="System.ArgumentNullException">userId</exception> Task UpdateDisplayPreferencesAsync(DisplayPreferences displayPreferences, string userId, string client, CancellationToken cancellationToken); diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index 63b819d69..e1dcb1f97 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -348,7 +348,7 @@ namespace MediaBrowser.Model.Dto /// Gets or sets the artists. /// </summary> /// <value>The artists.</value> - public string[] Artists { get; set; } + public List<string> Artists { get; set; } /// <summary> /// Gets or sets the album. diff --git a/MediaBrowser.Model/Querying/ItemQuery.cs b/MediaBrowser.Model/Querying/ItemQuery.cs index fe9848513..5a61d1c80 100644 --- a/MediaBrowser.Model/Querying/ItemQuery.cs +++ b/MediaBrowser.Model/Querying/ItemQuery.cs @@ -177,6 +177,10 @@ namespace MediaBrowser.Model.Querying public string MaxOfficialRating { get; set; } public int? MinIndexNumber { get; set; } + + public bool? HasParentalRating { get; set; } + + public bool? IsHD { get; set; } /// <summary> /// Initializes a new instance of the <see cref="ItemQuery"/> class. diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs index e4468dfe4..751712c71 100644 --- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs @@ -12,7 +12,6 @@ using System.Globalization; using System.IO; using System.Linq; using System.Net; -using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; @@ -550,6 +549,7 @@ namespace MediaBrowser.Providers.Movies movie.Overview = movie.Overview != null ? movie.Overview.Replace("\n\n", "\n") : null; } movie.HomePageUrl = movieData.homepage; + movie.Budget = movieData.budget; movie.Revenue = movieData.revenue; diff --git a/MediaBrowser.Providers/Movies/OpenMovieDatabaseProvider.cs b/MediaBrowser.Providers/Movies/OpenMovieDatabaseProvider.cs index c4a331891..b41b74ee7 100644 --- a/MediaBrowser.Providers/Movies/OpenMovieDatabaseProvider.cs +++ b/MediaBrowser.Providers/Movies/OpenMovieDatabaseProvider.cs @@ -73,17 +73,6 @@ namespace MediaBrowser.Providers.Movies } } - protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo) - { - // These values are now saved in movie.xml, so don't refresh if they're present - if (MovieDbProvider.HasAltMeta(item) && item.CriticRating.HasValue && !string.IsNullOrEmpty(item.CriticRatingSummary)) - { - return false; - } - - return base.NeedsRefreshInternal(item, providerInfo); - } - /// <summary> /// Supports the specified item. /// </summary> @@ -151,23 +140,20 @@ namespace MediaBrowser.Providers.Movies // Seeing some bogus RT data on omdb for series, so filter it out here // RT doesn't even have tv series - if (!(item is Series)) + int tomatoMeter; + + if (!string.IsNullOrEmpty(result.tomatoMeter) + && int.TryParse(result.tomatoMeter, NumberStyles.Integer, UsCulture, out tomatoMeter) + && tomatoMeter >= 0) + { + item.CriticRating = tomatoMeter; + } + + if (!string.IsNullOrEmpty(result.tomatoConsensus) + && !string.Equals(result.tomatoConsensus, "n/a", StringComparison.OrdinalIgnoreCase) + && !string.Equals(result.tomatoConsensus, "No consensus yet.", StringComparison.OrdinalIgnoreCase)) { - int tomatoMeter; - - if (!string.IsNullOrEmpty(result.tomatoMeter) - && int.TryParse(result.tomatoMeter, NumberStyles.Integer, UsCulture, out tomatoMeter) - && tomatoMeter >= 0) - { - item.CriticRating = tomatoMeter; - } - - if (!string.IsNullOrEmpty(result.tomatoConsensus) - && !string.Equals(result.tomatoConsensus, "n/a", StringComparison.OrdinalIgnoreCase) - && !string.Equals(result.tomatoConsensus, "No consensus yet.", StringComparison.OrdinalIgnoreCase)) - { - item.CriticRatingSummary = result.tomatoConsensus; - } + item.CriticRatingSummary = result.tomatoConsensus; } int voteCount; diff --git a/MediaBrowser.Providers/Music/MusicAlbumDynamicInfoProvider.cs b/MediaBrowser.Providers/Music/MusicAlbumDynamicInfoProvider.cs index 3d4c401e7..521d29d89 100644 --- a/MediaBrowser.Providers/Music/MusicAlbumDynamicInfoProvider.cs +++ b/MediaBrowser.Providers/Music/MusicAlbumDynamicInfoProvider.cs @@ -67,7 +67,7 @@ namespace MediaBrowser.Providers.Music album.Artists = songs.SelectMany(i => i.Artists) .Distinct(StringComparer.OrdinalIgnoreCase) - .ToArray(); + .ToList(); // Don't save to the db return FalseTaskResult; diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 5f383f1a0..948e9a14a 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -137,7 +137,8 @@ namespace MediaBrowser.Server.Implementations.Dto if (user == null) { - counts = item.ItemCounts; + //counts = item.ItemCounts; + return; } else { @@ -376,7 +377,7 @@ namespace MediaBrowser.Server.Implementations.Dto } dto.Album = item.Album; - dto.Artists = string.IsNullOrEmpty(item.Artist) ? new string[] { } : new[] { item.Artist }; + dto.Artists = string.IsNullOrEmpty(item.Artist) ? new List<string>() : new List<string> { item.Artist }; } private void SetGameProperties(BaseItemDto dto, Game item) @@ -804,6 +805,7 @@ namespace MediaBrowser.Server.Implementations.Dto dto.Language = item.Language; dto.MediaType = item.MediaType; dto.LocationType = item.LocationType; + dto.CriticRating = item.CriticRating; if (fields.Contains(ItemFields.CriticRatingSummary)) @@ -938,7 +940,7 @@ namespace MediaBrowser.Server.Implementations.Dto if (audio != null) { dto.Album = audio.Album; - dto.Artists = audio.Artists.ToArray(); + dto.Artists = audio.Artists; var albumParent = audio.FindParent<MusicAlbum>(); diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index d017a5f7e..602f81c33 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -581,6 +581,11 @@ namespace MediaBrowser.Server.Implementations.Library (UserRootFolder)ResolvePath(new DirectoryInfo(userRootPath))); } + public Person GetPersonSync(string name) + { + return GetItemByName<Person>(ConfigurationManager.ApplicationPaths.PeoplePath, name); + } + /// <summary> /// Gets a Person /// </summary> @@ -752,6 +757,37 @@ namespace MediaBrowser.Server.Implementations.Library /// </summary> private readonly ConcurrentDictionary<string, BaseItem> _itemsByName = new ConcurrentDictionary<string, BaseItem>(StringComparer.OrdinalIgnoreCase); + private T GetItemByName<T>(string path, string name) + where T : BaseItem, new() + { + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentNullException(); + } + + if (string.IsNullOrEmpty(name)) + { + throw new ArgumentNullException(); + } + + var validFilename = FileSystem.GetValidFilename(name); + + var key = Path.Combine(path, validFilename); + + BaseItem obj; + + if (!_itemsByName.TryGetValue(key, out obj)) + { + var tuple = CreateItemByName<T>(key, name); + + obj = tuple.Item2; + + _itemsByName.AddOrUpdate(key, obj, (keyName, oldValue) => obj); + } + + return obj as T; + } + /// <summary> /// Generically retrieves an IBN item /// </summary> @@ -777,13 +813,15 @@ namespace MediaBrowser.Server.Implementations.Library throw new ArgumentNullException(); } - var key = Path.Combine(path, FileSystem.GetValidFilename(name)); + var validFilename = FileSystem.GetValidFilename(name); + + var key = Path.Combine(path, validFilename); BaseItem obj; if (!_itemsByName.TryGetValue(key, out obj)) { - var tuple = CreateItemByName<T>(path, name, cancellationToken); + var tuple = CreateItemByName<T>(key, name); obj = tuple.Item2; @@ -815,16 +853,11 @@ namespace MediaBrowser.Server.Implementations.Library /// <typeparam name="T"></typeparam> /// <param name="path">The path.</param> /// <param name="name">The name.</param> - /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{``0}.</returns> /// <exception cref="System.IO.IOException">Path not created: + path</exception> - private Tuple<bool, T> CreateItemByName<T>(string path, string name, CancellationToken cancellationToken) + private Tuple<bool, T> CreateItemByName<T>(string path, string name) where T : BaseItem, new() { - cancellationToken.ThrowIfCancellationRequested(); - - path = Path.Combine(path, FileSystem.GetValidFilename(name)); - var fileInfo = new DirectoryInfo(path); var isNew = false; @@ -842,8 +875,6 @@ namespace MediaBrowser.Server.Implementations.Library isNew = true; } - cancellationToken.ThrowIfCancellationRequested(); - var type = typeof(T); var id = path.GetMBId(type); @@ -866,7 +897,7 @@ namespace MediaBrowser.Server.Implementations.Library // Set this now so we don't cause additional file system access during provider executions item.ResetResolveArgs(fileInfo); - return new Tuple<bool,T>(isNew, item); + return new Tuple<bool, T>(isNew, item); } /// <summary> @@ -878,16 +909,12 @@ namespace MediaBrowser.Server.Implementations.Library /// <returns>Task.</returns> public async Task ValidatePeople(CancellationToken cancellationToken, IProgress<double> progress) { - const int maxTasks = 10; + const int maxTasks = 5; var tasks = new List<Task>(); - var includedPersonTypes = new[] { PersonType.Actor, PersonType.Director, PersonType.GuestStar, PersonType.Writer, PersonType.Producer } - .ToDictionary(i => i, StringComparer.OrdinalIgnoreCase); - var people = RootFolder.RecursiveChildren - .Where(c => c.People != null) - .SelectMany(c => c.People.Where(p => includedPersonTypes.ContainsKey(p.Type ?? string.Empty) || includedPersonTypes.ContainsKey(p.Role ?? string.Empty))) + .SelectMany(c => c.People) .DistinctBy(p => p.Name, StringComparer.OrdinalIgnoreCase) .ToList(); @@ -1050,6 +1077,10 @@ namespace MediaBrowser.Server.Implementations.Library await RunPostScanTasks(progress, cancellationToken).ConfigureAwait(false); progress.Report(100); + + // Bad practice, i know. But we keep a lot in memory, unfortunately. + GC.Collect(2, GCCollectionMode.Forced, true); + GC.Collect(2, GCCollectionMode.Forced, true); } /// <summary> diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs index 485784397..3c6cc654f 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs @@ -30,10 +30,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio { if (EntityResolutionHelper.IsAudioFile(args.Path)) { - return new Controller.Entities.Audio.Audio - { - DisplayMediaType = "Song" - }; + return new Controller.Entities.Audio.Audio(); } } diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs index e35352407..73c26dd64 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs @@ -46,11 +46,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio return null; } - return IsMusicAlbum(args) ? new MusicAlbum - { - DisplayMediaType = "Album" - - } : null; + return IsMusicAlbum(args) ? new MusicAlbum() : null; } diff --git a/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs index 8109208e7..54d816cb0 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs @@ -108,7 +108,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators } // Populate counts of items - SetItemCounts(artist, null, allItems.OfType<IHasArtist>()); + //SetItemCounts(artist, null, allItems.OfType<IHasArtist>()); foreach (var lib in userLibraries) { @@ -155,10 +155,6 @@ namespace MediaBrowser.Server.Implementations.Library.Validators { artist.UserItemCounts[userId.Value] = counts; } - else - { - artist.ItemCounts = counts; - } } /// <summary> diff --git a/MediaBrowser.Server.Implementations/Library/Validators/CountHelpers.cs b/MediaBrowser.Server.Implementations/Library/Validators/CountHelpers.cs index ea4d887ea..084d720ae 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/CountHelpers.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/CountHelpers.cs @@ -18,46 +18,46 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// </summary> /// <param name="item">The item.</param> /// <param name="counts">The counts.</param> - internal static void AddToDictionary(BaseItem item, Dictionary<string, int> counts) + internal static void AddToDictionary(BaseItem item, Dictionary<CountType, int> counts) { if (item is Movie) { - IncrementCount(counts, "Movie"); + IncrementCount(counts, CountType.Movie); } else if (item is Trailer) { - IncrementCount(counts, "Trailer"); + IncrementCount(counts, CountType.Trailer); } else if (item is Series) { - IncrementCount(counts, "Series"); + IncrementCount(counts, CountType.Series); } else if (item is Game) { - IncrementCount(counts, "Game"); + IncrementCount(counts, CountType.Game); } else if (item is Audio) { - IncrementCount(counts, "Audio"); + IncrementCount(counts, CountType.Song); } else if (item is MusicAlbum) { - IncrementCount(counts, "MusicAlbum"); + IncrementCount(counts, CountType.MusicAlbum); } else if (item is Episode) { - IncrementCount(counts, "Episode"); + IncrementCount(counts, CountType.Episode); } else if (item is MusicVideo) { - IncrementCount(counts, "MusicVideo"); + IncrementCount(counts, CountType.MusicVideo); } else if (item is AdultVideo) { - IncrementCount(counts, "AdultVideo"); + IncrementCount(counts, CountType.AdultVideo); } - IncrementCount(counts, "Total"); + IncrementCount(counts, CountType.Total); } /// <summary> @@ -65,7 +65,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// </summary> /// <param name="counts">The counts.</param> /// <param name="key">The key.</param> - internal static void IncrementCount(Dictionary<string, int> counts, string key) + internal static void IncrementCount(Dictionary<CountType, int> counts, CountType key) { int count; @@ -85,20 +85,20 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// </summary> /// <param name="counts">The counts.</param> /// <returns>ItemByNameCounts.</returns> - internal static ItemByNameCounts GetCounts(Dictionary<string, int> counts) + internal static ItemByNameCounts GetCounts(Dictionary<CountType, int> counts) { return new ItemByNameCounts { - AdultVideoCount = GetCount(counts, "AdultVideo"), - AlbumCount = GetCount(counts, "MusicAlbum"), - EpisodeCount = GetCount(counts, "Episode"), - GameCount = GetCount(counts, "Game"), - MovieCount = GetCount(counts, "Movie"), - MusicVideoCount = GetCount(counts, "MusicVideo"), - SeriesCount = GetCount(counts, "Series"), - SongCount = GetCount(counts, "Audio"), - TrailerCount = GetCount(counts, "Trailer"), - TotalCount = GetCount(counts, "Total") + AdultVideoCount = GetCount(counts, CountType.AdultVideo), + AlbumCount = GetCount(counts, CountType.MusicAlbum), + EpisodeCount = GetCount(counts, CountType.Episode), + GameCount = GetCount(counts, CountType.Game), + MovieCount = GetCount(counts, CountType.Movie), + MusicVideoCount = GetCount(counts, CountType.MusicVideo), + SeriesCount = GetCount(counts, CountType.Series), + SongCount = GetCount(counts, CountType.Song), + TrailerCount = GetCount(counts, CountType.Trailer), + TotalCount = GetCount(counts, CountType.Total) }; } @@ -108,7 +108,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// <param name="counts">The counts.</param> /// <param name="key">The key.</param> /// <returns>System.Int32.</returns> - internal static int GetCount(Dictionary<string, int> counts, string key) + internal static int GetCount(Dictionary<CountType, int> counts, CountType key) { int count; @@ -127,24 +127,24 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// <param name="media">The media.</param> /// <param name="names">The names.</param> /// <param name="masterDictionary">The master dictionary.</param> - internal static void SetItemCounts(Guid? userId, BaseItem media, List<string> names, Dictionary<string, Dictionary<Guid, Dictionary<string, int>>> masterDictionary) + internal static void SetItemCounts(Guid userId, BaseItem media, List<string> names, Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>> masterDictionary) { foreach (var name in names) { - Dictionary<Guid, Dictionary<string, int>> libraryCounts; + Dictionary<Guid, Dictionary<CountType, int>> libraryCounts; if (!masterDictionary.TryGetValue(name, out libraryCounts)) { - libraryCounts = new Dictionary<Guid, Dictionary<string, int>>(); + libraryCounts = new Dictionary<Guid, Dictionary<CountType, int>>(); masterDictionary.Add(name, libraryCounts); } - var userLibId = userId ?? Guid.Empty; - Dictionary<string, int> userDictionary; + var userLibId = userId/* ?? Guid.Empty*/; + Dictionary<CountType, int> userDictionary; if (!libraryCounts.TryGetValue(userLibId, out userDictionary)) { - userDictionary = new Dictionary<string, int>(); + userDictionary = new Dictionary<CountType, int>(); libraryCounts.Add(userLibId, userDictionary); } @@ -152,4 +152,18 @@ namespace MediaBrowser.Server.Implementations.Library.Validators } } } + + internal enum CountType + { + AdultVideo, + MusicAlbum, + Episode, + Game, + Movie, + MusicVideo, + Series, + Song, + Trailer, + Total + } } diff --git a/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs index f8aeadda1..eba7193e0 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs @@ -49,10 +49,10 @@ namespace MediaBrowser.Server.Implementations.Library.Validators var allLibraryItems = allItems; - var masterDictionary = new Dictionary<string, Dictionary<Guid, Dictionary<string, int>>>(StringComparer.OrdinalIgnoreCase); + var masterDictionary = new Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>>(StringComparer.OrdinalIgnoreCase); // Populate counts of items - SetItemCounts(null, allLibraryItems, masterDictionary); + //SetItemCounts(null, allLibraryItems, masterDictionary); progress.Report(2); @@ -72,10 +72,10 @@ namespace MediaBrowser.Server.Implementations.Library.Validators progress.Report(10); - var names = masterDictionary.Keys.ToList(); + var count = masterDictionary.Count; numComplete = 0; - foreach (var name in names) + foreach (var name in masterDictionary.Keys) { try { @@ -88,7 +88,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators numComplete++; double percent = numComplete; - percent /= names.Count; + percent /= count; percent *= 90; progress.Report(percent + 10); @@ -97,26 +97,19 @@ namespace MediaBrowser.Server.Implementations.Library.Validators progress.Report(100); } - private async Task UpdateItemByNameCounts(string name, CancellationToken cancellationToken, Dictionary<Guid, Dictionary<string, int>> counts) + private async Task UpdateItemByNameCounts(string name, CancellationToken cancellationToken, Dictionary<Guid, Dictionary<CountType, int>> counts) { var itemByName = await _libraryManager.GetGameGenre(name, cancellationToken, true, true).ConfigureAwait(false); - foreach (var libraryId in counts.Keys.ToList()) + foreach (var libraryId in counts.Keys) { var itemCounts = CountHelpers.GetCounts(counts[libraryId]); - if (libraryId == Guid.Empty) - { - itemByName.ItemCounts = itemCounts; - } - else - { - itemByName.UserItemCounts[libraryId] = itemCounts; - } + itemByName.UserItemCounts[libraryId] = itemCounts; } } - private void SetItemCounts(Guid? userId, IEnumerable<BaseItem> allItems, Dictionary<string, Dictionary<Guid, Dictionary<string, int>>> masterDictionary) + private void SetItemCounts(Guid userId, IEnumerable<BaseItem> allItems, Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>> masterDictionary) { foreach (var media in allItems) { diff --git a/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs index 852984a5c..c605961f7 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs @@ -52,10 +52,10 @@ namespace MediaBrowser.Server.Implementations.Library.Validators var allLibraryItems = allItems; - var masterDictionary = new Dictionary<string, Dictionary<Guid, Dictionary<string, int>>>(StringComparer.OrdinalIgnoreCase); + var masterDictionary = new Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>>(StringComparer.OrdinalIgnoreCase); // Populate counts of items - SetItemCounts(null, allLibraryItems, masterDictionary); + //SetItemCounts(null, allLibraryItems, masterDictionary); progress.Report(2); @@ -75,10 +75,10 @@ namespace MediaBrowser.Server.Implementations.Library.Validators progress.Report(10); - var names = masterDictionary.Keys.ToList(); + var count = masterDictionary.Count; numComplete = 0; - foreach (var name in names) + foreach (var name in masterDictionary.Keys) { try { @@ -91,7 +91,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators numComplete++; double percent = numComplete; - percent /= names.Count; + percent /= count; percent *= 90; progress.Report(percent + 10); @@ -100,26 +100,19 @@ namespace MediaBrowser.Server.Implementations.Library.Validators progress.Report(100); } - private async Task UpdateItemByNameCounts(string name, CancellationToken cancellationToken, Dictionary<Guid, Dictionary<string, int>> counts) + private async Task UpdateItemByNameCounts(string name, CancellationToken cancellationToken, Dictionary<Guid, Dictionary<CountType, int>> counts) { var itemByName = await _libraryManager.GetGenre(name, cancellationToken, true, true).ConfigureAwait(false); - foreach (var libraryId in counts.Keys.ToList()) + foreach (var libraryId in counts.Keys) { var itemCounts = CountHelpers.GetCounts(counts[libraryId]); - if (libraryId == Guid.Empty) - { - itemByName.ItemCounts = itemCounts; - } - else - { - itemByName.UserItemCounts[libraryId] = itemCounts; - } + itemByName.UserItemCounts[libraryId] = itemCounts; } } - private void SetItemCounts(Guid? userId, IEnumerable<BaseItem> allItems, Dictionary<string, Dictionary<Guid, Dictionary<string, int>>> masterDictionary) + private void SetItemCounts(Guid userId, IEnumerable<BaseItem> allItems, Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>> masterDictionary) { foreach (var media in allItems) { diff --git a/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs index 53e443527..9063027ec 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs @@ -52,10 +52,10 @@ namespace MediaBrowser.Server.Implementations.Library.Validators var allLibraryItems = allItems; - var masterDictionary = new Dictionary<string, Dictionary<Guid, Dictionary<string, int>>>(StringComparer.OrdinalIgnoreCase); + var masterDictionary = new Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>>(StringComparer.OrdinalIgnoreCase); // Populate counts of items - SetItemCounts(null, allLibraryItems, masterDictionary); + //SetItemCounts(null, allLibraryItems, masterDictionary); progress.Report(2); @@ -75,10 +75,10 @@ namespace MediaBrowser.Server.Implementations.Library.Validators progress.Report(10); - var names = masterDictionary.Keys.ToList(); + var count = masterDictionary.Count; numComplete = 0; - foreach (var name in names) + foreach (var name in masterDictionary.Keys) { try { @@ -91,7 +91,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators numComplete++; double percent = numComplete; - percent /= names.Count; + percent /= count; percent *= 90; progress.Report(percent + 10); @@ -100,26 +100,19 @@ namespace MediaBrowser.Server.Implementations.Library.Validators progress.Report(100); } - private async Task UpdateItemByNameCounts(string name, CancellationToken cancellationToken, Dictionary<Guid, Dictionary<string, int>> counts) + private async Task UpdateItemByNameCounts(string name, CancellationToken cancellationToken, Dictionary<Guid, Dictionary<CountType, int>> counts) { var itemByName = await _libraryManager.GetMusicGenre(name, cancellationToken, true, true).ConfigureAwait(false); - foreach (var libraryId in counts.Keys.ToList()) + foreach (var libraryId in counts.Keys) { var itemCounts = CountHelpers.GetCounts(counts[libraryId]); - if (libraryId == Guid.Empty) - { - itemByName.ItemCounts = itemCounts; - } - else - { - itemByName.UserItemCounts[libraryId] = itemCounts; - } + itemByName.UserItemCounts[libraryId] = itemCounts; } } - private void SetItemCounts(Guid? userId, IEnumerable<BaseItem> allItems, Dictionary<string, Dictionary<Guid, Dictionary<string, int>>> masterDictionary) + private void SetItemCounts(Guid userId, IEnumerable<BaseItem> allItems, Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>> masterDictionary) { foreach (var media in allItems) { diff --git a/MediaBrowser.Server.Implementations/Library/Validators/PeoplePostScanTask.cs b/MediaBrowser.Server.Implementations/Library/Validators/PeoplePostScanTask.cs index 7d7728030..708f8bfa4 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/PeoplePostScanTask.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/PeoplePostScanTask.cs @@ -39,7 +39,13 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// <param name="progress">The progress.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> - public async Task Run(IProgress<double> progress, CancellationToken cancellationToken) + public Task Run(IProgress<double> progress, CancellationToken cancellationToken) + { + return RunInternal(progress, cancellationToken); + //return Task.Run(() => RunInternal(progress, cancellationToken)); + } + + private async Task RunInternal(IProgress<double> progress, CancellationToken cancellationToken) { var allItems = _libraryManager.RootFolder.RecursiveChildren.ToList(); @@ -49,10 +55,10 @@ namespace MediaBrowser.Server.Implementations.Library.Validators var allLibraryItems = allItems; - var masterDictionary = new Dictionary<string, Dictionary<Guid, Dictionary<string, int>>>(StringComparer.OrdinalIgnoreCase); + var masterDictionary = new Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>>(StringComparer.OrdinalIgnoreCase); // Populate counts of items - SetItemCounts(null, allLibraryItems, masterDictionary); + //SetItemCounts(null, allLibraryItems, masterDictionary); progress.Report(2); @@ -74,16 +80,25 @@ namespace MediaBrowser.Server.Implementations.Library.Validators progress.Report(10); - var names = masterDictionary.Keys.ToList(); + var count = masterDictionary.Count; numComplete = 0; - foreach (var name in names) + foreach (var name in masterDictionary.Keys) { cancellationToken.ThrowIfCancellationRequested(); - + try { - await UpdateItemByNameCounts(name, masterDictionary[name]).ConfigureAwait(false); + var counts = masterDictionary[name]; + + var itemByName = await _libraryManager.GetPerson(name).ConfigureAwait(false); + + foreach (var libraryId in counts.Keys) + { + var itemCounts = CountHelpers.GetCounts(counts[libraryId]); + + itemByName.UserItemCounts[libraryId] = itemCounts; + } } catch (Exception ex) { @@ -92,7 +107,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators numComplete++; double percent = numComplete; - percent /= names.Count; + percent /= count; percent *= 90; progress.Report(percent + 10); @@ -101,26 +116,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators progress.Report(100); } - private async Task UpdateItemByNameCounts(string name, Dictionary<Guid, Dictionary<string, int>> counts) - { - var itemByName = await _libraryManager.GetPerson(name).ConfigureAwait(false); - - foreach (var libraryId in counts.Keys.ToList()) - { - var itemCounts = CountHelpers.GetCounts(counts[libraryId]); - - if (libraryId == Guid.Empty) - { - itemByName.ItemCounts = itemCounts; - } - else - { - itemByName.UserItemCounts[libraryId] = itemCounts; - } - } - } - - private void SetItemCounts(Guid? userId, IEnumerable<BaseItem> allItems, Dictionary<string, Dictionary<Guid, Dictionary<string, int>>> masterDictionary) + private void SetItemCounts(Guid userId, IEnumerable<BaseItem> allItems, Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>> masterDictionary) { foreach (var media in allItems) { diff --git a/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs index 1814e7c4f..202cd9414 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs @@ -49,10 +49,10 @@ namespace MediaBrowser.Server.Implementations.Library.Validators var allLibraryItems = allItems; - var masterDictionary = new Dictionary<string, Dictionary<Guid, Dictionary<string, int>>>(StringComparer.OrdinalIgnoreCase); + var masterDictionary = new Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>>(StringComparer.OrdinalIgnoreCase); // Populate counts of items - SetItemCounts(null, allLibraryItems, masterDictionary); + //SetItemCounts(null, allLibraryItems, masterDictionary); progress.Report(2); @@ -72,10 +72,10 @@ namespace MediaBrowser.Server.Implementations.Library.Validators progress.Report(10); - var names = masterDictionary.Keys.ToList(); + var count = masterDictionary.Count; numComplete = 0; - foreach (var name in names) + foreach (var name in masterDictionary.Keys) { try { @@ -88,7 +88,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators numComplete++; double percent = numComplete; - percent /= names.Count; + percent /= count; percent *= 90; progress.Report(percent + 10); @@ -97,26 +97,19 @@ namespace MediaBrowser.Server.Implementations.Library.Validators progress.Report(100); } - private async Task UpdateItemByNameCounts(string name, CancellationToken cancellationToken, Dictionary<Guid, Dictionary<string, int>> counts) + private async Task UpdateItemByNameCounts(string name, CancellationToken cancellationToken, Dictionary<Guid, Dictionary<CountType, int>> counts) { var itemByName = await _libraryManager.GetStudio(name, cancellationToken, true, true).ConfigureAwait(false); - foreach (var libraryId in counts.Keys.ToList()) + foreach (var libraryId in counts.Keys) { var itemCounts = CountHelpers.GetCounts(counts[libraryId]); - if (libraryId == Guid.Empty) - { - itemByName.ItemCounts = itemCounts; - } - else - { - itemByName.UserItemCounts[libraryId] = itemCounts; - } + itemByName.UserItemCounts[libraryId] = itemCounts; } } - private void SetItemCounts(Guid? userId, IEnumerable<BaseItem> allItems, Dictionary<string, Dictionary<Guid, Dictionary<string, int>>> masterDictionary) + private void SetItemCounts(Guid userId, IEnumerable<BaseItem> allItems, Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>> masterDictionary) { foreach (var media in allItems) { diff --git a/MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs b/MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs index 41f18b9a0..b511ae80c 100644 --- a/MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs +++ b/MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs @@ -204,7 +204,7 @@ namespace MediaBrowser.Server.Implementations.Localization }) .Where(i => i != null) - .ToDictionary(i => i.Name); + .ToDictionary(i => i.Name, StringComparer.OrdinalIgnoreCase); var countryCode = Path.GetFileNameWithoutExtension(file).Split('-').Last(); diff --git a/MediaBrowser.Server.Implementations/Sorting/BudgetComparer.cs b/MediaBrowser.Server.Implementations/Sorting/BudgetComparer.cs index 39bdc6363..d2dac6549 100644 --- a/MediaBrowser.Server.Implementations/Sorting/BudgetComparer.cs +++ b/MediaBrowser.Server.Implementations/Sorting/BudgetComparer.cs @@ -14,7 +14,12 @@ namespace MediaBrowser.Server.Implementations.Sorting /// <returns>System.Int32.</returns> public int Compare(BaseItem x, BaseItem y) { - return (x.Budget ?? 0).CompareTo(y.Budget ?? 0); + return GetValue(x).CompareTo(GetValue(y)); + } + + private double GetValue(BaseItem x) + { + return x.Budget ?? 0; } /// <summary> diff --git a/MediaBrowser.Server.Implementations/Sorting/CriticRatingComparer.cs b/MediaBrowser.Server.Implementations/Sorting/CriticRatingComparer.cs index 358e06f3b..9484130cb 100644 --- a/MediaBrowser.Server.Implementations/Sorting/CriticRatingComparer.cs +++ b/MediaBrowser.Server.Implementations/Sorting/CriticRatingComparer.cs @@ -17,7 +17,12 @@ namespace MediaBrowser.Server.Implementations.Sorting /// <returns>System.Int32.</returns> public int Compare(BaseItem x, BaseItem y) { - return (x.CriticRating ?? 0).CompareTo(y.CriticRating ?? 0); + return GetValue(x).CompareTo(GetValue(y)); + } + + private float GetValue(BaseItem x) + { + return x.CriticRating ?? 0; } /// <summary> diff --git a/MediaBrowser.Server.Implementations/Sorting/RevenueComparer.cs b/MediaBrowser.Server.Implementations/Sorting/RevenueComparer.cs index 8764c97d0..e9d7912a1 100644 --- a/MediaBrowser.Server.Implementations/Sorting/RevenueComparer.cs +++ b/MediaBrowser.Server.Implementations/Sorting/RevenueComparer.cs @@ -14,7 +14,12 @@ namespace MediaBrowser.Server.Implementations.Sorting /// <returns>System.Int32.</returns> public int Compare(BaseItem x, BaseItem y) { - return (x.Revenue ?? 0).CompareTo(y.Revenue ?? 0); + return GetValue(x).CompareTo(GetValue(y)); + } + + private double GetValue(BaseItem x) + { + return x.Revenue ?? 0; } /// <summary> diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index c3adbfdf7..ec6babdd1 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -168,9 +168,9 @@ <SpecificVersion>False</SpecificVersion> <HintPath>..\packages\ServiceStack.Text.3.9.58\lib\net35\ServiceStack.Text.dll</HintPath> </Reference> - <Reference Include="SimpleInjector, Version=2.3.2.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL"> + <Reference Include="SimpleInjector, Version=2.3.5.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\SimpleInjector.2.3.2\lib\net40-client\SimpleInjector.dll</HintPath> + <HintPath>..\packages\SimpleInjector.2.3.5\lib\net40-client\SimpleInjector.dll</HintPath> </Reference> <Reference Include="System" /> <Reference Include="System.Data" /> diff --git a/MediaBrowser.ServerApplication/packages.config b/MediaBrowser.ServerApplication/packages.config index 8ec4bce27..c657eb00c 100644 --- a/MediaBrowser.ServerApplication/packages.config +++ b/MediaBrowser.ServerApplication/packages.config @@ -11,6 +11,6 @@ <package id="ServiceStack.OrmLite.SqlServer" version="3.9.44" targetFramework="net45" /> <package id="ServiceStack.Redis" version="3.9.44" targetFramework="net45" /> <package id="ServiceStack.Text" version="3.9.58" targetFramework="net45" /> - <package id="SimpleInjector" version="2.3.2" targetFramework="net45" /> + <package id="SimpleInjector" version="2.3.5" targetFramework="net45" /> <package id="System.Data.SQLite.x86" version="1.0.88.0" targetFramework="net45" /> </packages>
\ No newline at end of file diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index 2309bc87f..901e44193 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.192</version> + <version>3.0.198</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 Theater 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.192" /> + <dependency id="MediaBrowser.Common" version="3.0.198" /> <dependency id="NLog" version="2.0.1.2" /> <dependency id="ServiceStack.Text" version="3.9.58" /> <dependency id="SimpleInjector" version="2.3.2" /> diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index f773f15ef..87a6a3856 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.192</version> + <version>3.0.198</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 134d6eb10..4f8cd1357 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.192</version> + <version>3.0.198</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.192" /> + <dependency id="MediaBrowser.Common" version="3.0.198" /> </dependencies> </metadata> <files> |
