improved performance of item counts

pull/702/head
Luke Pulverenti 11 years ago
parent 1496991096
commit 803e8b4a2e

@ -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)

@ -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; }
}
}

@ -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; }
}

@ -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;

@ -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);
}

@ -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;
}

@ -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" />

@ -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>

@ -12,7 +12,6 @@ namespace MediaBrowser.Controller.Entities.Audio
{
public Artist()
{
ItemCounts = new ItemByNameCounts();
UserItemCounts = new Dictionary<Guid, ItemByNameCounts>();
}
@ -27,9 +26,6 @@ namespace MediaBrowser.Controller.Entities.Audio
return "Artist-" + Name;
}
[IgnoreDataMember]
public ItemByNameCounts ItemCounts { get; set; }
[IgnoreDataMember]
public Dictionary<Guid, ItemByNameCounts> UserItemCounts { get; set; }
}

@ -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

@ -12,7 +12,6 @@ namespace MediaBrowser.Controller.Entities.Audio
{
public MusicGenre()
{
ItemCounts = new ItemByNameCounts();
UserItemCounts = new Dictionary<Guid, ItemByNameCounts>();
}
@ -25,9 +24,6 @@ namespace MediaBrowser.Controller.Entities.Audio
return "MusicGenre-" + Name;
}
[IgnoreDataMember]
public ItemByNameCounts ItemCounts { get; set; }
[IgnoreDataMember]
public Dictionary<Guid, ItemByNameCounts> UserItemCounts { get; set; }
}

@ -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>
@ -90,6 +90,42 @@ namespace MediaBrowser.Controller.Entities
/// <value>The id.</value>
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.
@ -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.
@ -580,36 +611,12 @@ namespace MediaBrowser.Controller.Entities
/// <value>The home page URL.</value>
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>
@ -973,12 +980,6 @@ namespace MediaBrowser.Controller.Entities
return themeSongsChanged || results.Contains(true);
}
/// <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>
@ -1255,53 +1256,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>
@ -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();

@ -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
});
}
}
}
}

@ -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>();

@ -9,7 +9,6 @@ namespace MediaBrowser.Controller.Entities
{
public GameGenre()
{
ItemCounts = new ItemByNameCounts();
UserItemCounts = new Dictionary<Guid, ItemByNameCounts>();
}
@ -22,9 +21,6 @@ namespace MediaBrowser.Controller.Entities
return "GameGenre-" + Name;
}
[IgnoreDataMember]
public ItemByNameCounts ItemCounts { get; set; }
[IgnoreDataMember]
public Dictionary<Guid, ItemByNameCounts> UserItemCounts { get; set; }
}

@ -12,7 +12,6 @@ namespace MediaBrowser.Controller.Entities
{
public Genre()
{
ItemCounts = new ItemByNameCounts();
UserItemCounts = new Dictionary<Guid, ItemByNameCounts>();
}
@ -25,9 +24,6 @@ namespace MediaBrowser.Controller.Entities
return "Genre-" + Name;
}
[IgnoreDataMember]
public ItemByNameCounts ItemCounts { get; set; }
[IgnoreDataMember]
public Dictionary<Guid, ItemByNameCounts> UserItemCounts { get; set; }
}

@ -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;

@ -12,13 +12,9 @@ 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; }

@ -12,7 +12,6 @@ namespace MediaBrowser.Controller.Entities
{
public Studio()
{
ItemCounts = new ItemByNameCounts();
UserItemCounts = new Dictionary<Guid, ItemByNameCounts>();
}
@ -25,9 +24,6 @@ namespace MediaBrowser.Controller.Entities
return "Studio-" + Name;
}
[IgnoreDataMember]
public ItemByNameCounts ItemCounts { get; set; }
[IgnoreDataMember]
public Dictionary<Guid, ItemByNameCounts> UserItemCounts { get; set; }
}

@ -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>

@ -12,13 +12,9 @@ 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; }

@ -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>

@ -245,7 +245,7 @@ namespace MediaBrowser.Controller.Library
{
throw new ArgumentNullException();
}
if (MetadataFileDictionary == null)
{
MetadataFileDictionary = new Dictionary<string, FileSystemInfo>(StringComparer.OrdinalIgnoreCase);

@ -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" />

@ -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);

@ -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.

@ -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.

@ -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;

@ -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;

@ -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;

@ -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>();

@ -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>

@ -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();
}
}

@ -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;
}

@ -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>

@ -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
}
}

@ -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)
{

@ -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)
{

@ -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)
{

@ -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)
{

@ -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)
{

@ -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>

@ -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>

@ -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>

@ -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" />

@ -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>

@ -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" />

@ -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>

@ -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>

Loading…
Cancel
Save