2014-11-09 18:24:57 +00:00
using MediaBrowser.Controller.Collections ;
2014-04-22 17:25:54 +00:00
using MediaBrowser.Controller.Dto ;
2013-04-13 18:02:30 +00:00
using MediaBrowser.Controller.Entities ;
2013-04-24 14:05:47 +00:00
using MediaBrowser.Controller.Entities.Audio ;
2013-04-30 01:29:04 +00:00
using MediaBrowser.Controller.Entities.Movies ;
2013-04-07 20:55:05 +00:00
using MediaBrowser.Controller.Entities.TV ;
2013-02-21 01:33:05 +00:00
using MediaBrowser.Controller.Library ;
2013-04-14 00:17:25 +00:00
using MediaBrowser.Controller.Localization ;
2014-07-02 18:34:08 +00:00
using MediaBrowser.Controller.Net ;
2013-02-21 01:33:05 +00:00
using MediaBrowser.Model.Entities ;
2013-03-10 05:36:39 +00:00
using MediaBrowser.Model.Querying ;
2013-12-07 15:52:38 +00:00
using ServiceStack ;
2013-02-21 01:33:05 +00:00
using System ;
using System.Collections.Generic ;
2013-12-28 23:09:24 +00:00
using System.Globalization ;
2013-02-21 01:33:05 +00:00
using System.Linq ;
2014-10-06 23:58:46 +00:00
using System.Threading.Tasks ;
2013-02-21 01:33:05 +00:00
namespace MediaBrowser.Api.UserLibrary
{
/// <summary>
/// Class GetItems
/// </summary>
2014-03-28 19:58:18 +00:00
[Route("/Items", "GET", Summary = "Gets items based on a query.")]
[Route("/Users/{UserId}/Items", "GET", Summary = "Gets items based on a query.")]
2013-03-11 05:06:55 +00:00
public class GetItems : BaseItemsRequest , IReturn < ItemsResult >
2013-02-21 01:33:05 +00:00
{
2013-04-22 04:38:03 +00:00
/// <summary>
/// Gets or sets the user id.
/// </summary>
/// <value>The user id.</value>
2014-01-22 17:05:23 +00:00
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "GET")]
public Guid ? UserId { get ; set ; }
2013-04-22 04:38:03 +00:00
2013-02-21 01:33:05 +00:00
/// <summary>
/// Limit results to items containing a specific person
/// </summary>
/// <value>The person.</value>
2013-03-09 05:15:51 +00:00
[ApiMember(Name = "Person", Description = "Optional. If specified, results will be filtered to include only those containing the specified person.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
2013-02-21 01:33:05 +00:00
public string Person { get ; set ; }
/// <summary>
/// If the Person filter is used, this can also be used to restrict to a specific person type
/// </summary>
/// <value>The type of the person.</value>
2013-04-13 23:43:41 +00:00
[ApiMember(Name = "PersonTypes", Description = "Optional. If specified, along with Person, results will be filtered to include only those containing the specified person and PersonType. Allows multiple, comma-delimited", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string PersonTypes { get ; set ; }
2013-02-21 01:33:05 +00:00
2014-01-05 03:50:29 +00:00
[ApiMember(Name = "AllGenres", Description = "Optional. If specified, results will be filtered based on genre. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
2013-09-22 17:00:42 +00:00
public string AllGenres { get ; set ; }
2013-02-21 01:33:05 +00:00
/// <summary>
/// Limit results to items containing specific studios
/// </summary>
/// <value>The studios.</value>
2014-01-05 03:50:29 +00:00
[ApiMember(Name = "Studios", Description = "Optional. If specified, results will be filtered based on studio. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
2013-02-21 01:33:05 +00:00
public string Studios { get ; set ; }
2013-04-24 14:05:47 +00:00
/// <summary>
/// Gets or sets the studios.
/// </summary>
/// <value>The studios.</value>
2013-08-08 12:19:11 +00:00
[ApiMember(Name = "Artists", Description = "Optional. If specified, results will be filtered based on artist. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
2013-04-24 14:05:47 +00:00
public string Artists { get ; set ; }
2013-08-08 12:19:11 +00:00
[ApiMember(Name = "Albums", Description = "Optional. If specified, results will be filtered based on album. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string Albums { get ; set ; }
2013-09-06 05:13:43 +00:00
2013-03-16 01:40:34 +00:00
/// <summary>
/// Gets or sets the item ids.
/// </summary>
/// <value>The item ids.</value>
2013-04-24 14:05:47 +00:00
[ApiMember(Name = "Ids", Description = "Optional. If specific items are needed, specify a list of item id's to retrieve. This allows multiple, comma delimited.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
2013-03-16 01:40:34 +00:00
public string Ids { get ; set ; }
2013-04-04 15:22:39 +00:00
/// <summary>
/// Gets or sets the video types.
/// </summary>
/// <value>The video types.</value>
[ApiMember(Name = "VideoTypes", Description = "Optional filter by VideoType (videofile, dvd, bluray, iso). Allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string VideoTypes { get ; set ; }
/// <summary>
/// Gets or sets the video formats.
/// </summary>
/// <value>The video formats.</value>
2013-06-25 18:10:39 +00:00
[ApiMember(Name = "Is3D", Description = "Optional filter by items that are 3D, or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? Is3D { get ; set ; }
2013-04-07 20:55:05 +00:00
/// <summary>
/// Gets or sets the series status.
/// </summary>
/// <value>The series status.</value>
[ApiMember(Name = "SeriesStatus", Description = "Optional filter by Series Status. Allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string SeriesStatus { get ; set ; }
2013-05-17 03:24:41 +00:00
[ApiMember(Name = "NameStartsWithOrGreater", Description = "Optional filter by items whose name is sorted equally or greater than a given input string.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string NameStartsWithOrGreater { get ; set ; }
2014-03-06 02:59:48 +00:00
2014-03-05 21:46:32 +00:00
[ApiMember(Name = "NameStartsWith", Description = "Optional filter by items whose name is sorted equally than a given input string.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string NameStartsWith { get ; set ; }
2014-03-18 17:05:57 +00:00
2014-03-05 21:46:32 +00:00
[ApiMember(Name = "NameLessThan", Description = "Optional filter by items whose name is equally or lesser than a given input string.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string NameLessThan { get ; set ; }
2013-05-16 19:00:42 +00:00
2013-09-06 19:17:15 +00:00
[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 ; }
2013-09-11 17:54:59 +00:00
2013-04-07 20:55:05 +00:00
/// <summary>
/// Gets or sets the air days.
/// </summary>
/// <value>The air days.</value>
[ApiMember(Name = "AirDays", Description = "Optional filter by Series Air Days. Allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string AirDays { get ; set ; }
2013-04-12 03:50:47 +00:00
2013-04-14 00:17:25 +00:00
/// <summary>
/// Gets or sets the min offical rating.
/// </summary>
/// <value>The min offical rating.</value>
2013-04-24 19:52:28 +00:00
[ApiMember(Name = "MinOfficialRating", Description = "Optional filter by minimum official rating (PG, PG-13, TV-MA, etc).", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string MinOfficialRating { get ; set ; }
2013-04-14 00:17:25 +00:00
/// <summary>
/// Gets or sets the max offical rating.
/// </summary>
/// <value>The max offical rating.</value>
2013-04-24 19:52:28 +00:00
[ApiMember(Name = "MaxOfficialRating", Description = "Optional filter by maximum official rating (PG, PG-13, TV-MA, etc).", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string MaxOfficialRating { get ; set ; }
2013-04-30 01:29:04 +00:00
[ApiMember(Name = "HasThemeSong", Description = "Optional filter by items with theme songs.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public bool? HasThemeSong { get ; set ; }
[ApiMember(Name = "HasThemeVideo", Description = "Optional filter by items with theme videos.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public bool? HasThemeVideo { get ; set ; }
[ApiMember(Name = "HasSubtitles", Description = "Optional filter by items with subtitles.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public bool? HasSubtitles { get ; set ; }
[ApiMember(Name = "HasSpecialFeature", Description = "Optional filter by items with special features.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public bool? HasSpecialFeature { get ; set ; }
[ApiMember(Name = "HasTrailer", Description = "Optional filter by items with trailers.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public bool? HasTrailer { get ; set ; }
2013-05-16 19:00:42 +00:00
2013-05-19 17:35:00 +00:00
[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 ; }
2013-09-11 17:54:59 +00:00
[ApiMember(Name = "MinIndexNumber", Description = "Optional filter by minimum index number.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
2013-08-31 01:08:32 +00:00
public int? MinIndexNumber { get ; set ; }
2013-09-11 17:54:59 +00:00
2013-09-15 19:33:23 +00:00
[ApiMember(Name = "MinPlayers", Description = "Optional filter by minimum number of game players.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int? MinPlayers { get ; set ; }
2013-10-06 03:03:08 +00:00
[ApiMember(Name = "MaxPlayers", Description = "Optional filter by maximum number of game players.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int? MaxPlayers { get ; set ; }
2013-09-13 20:45:27 +00:00
[ApiMember(Name = "ParentIndexNumber", Description = "Optional filter by parent index number.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int? ParentIndexNumber { get ; set ; }
2013-09-11 17:54:59 +00:00
[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 ; }
2013-10-15 22:16:39 +00:00
2013-10-16 23:35:11 +00:00
[ApiMember(Name = "LocationTypes", Description = "Optional. If specified, results will be filtered based on LocationType. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string LocationTypes { get ; set ; }
2013-10-26 22:01:21 +00:00
[ApiMember(Name = "ExcludeLocationTypes", Description = "Optional. If specified, results will be filtered based on LocationType. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string ExcludeLocationTypes { get ; set ; }
2013-10-16 23:35:11 +00:00
2013-10-26 22:01:21 +00:00
public bool IncludeIndexContainers { get ; set ; }
2013-10-16 23:35:11 +00:00
2013-10-26 22:01:21 +00:00
[ApiMember(Name = "IsMissing", Description = "Optional filter by items that are missing episodes or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? IsMissing { get ; set ; }
2013-10-16 23:35:11 +00:00
2013-10-26 22:01:21 +00:00
[ApiMember(Name = "IsUnaired", Description = "Optional filter by items that are unaired episodes or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? IsUnaired { get ; set ; }
2013-10-26 22:40:53 +00:00
[ApiMember(Name = "IsVirtualUnaired", Description = "Optional filter by items that are virtual unaired episodes or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? IsVirtualUnaired { get ; set ; }
2013-11-03 16:19:33 +00:00
[ApiMember(Name = "MinCommunityRating", Description = "Optional filter by minimum community rating.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public double? MinCommunityRating { get ; set ; }
[ApiMember(Name = "MinCriticRating", Description = "Optional filter by minimum critic rating.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public double? MinCriticRating { get ; set ; }
2013-11-15 21:31:33 +00:00
[ApiMember(Name = "AiredDuringSeason", Description = "Gets all episodes that aired during a season, including specials.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int? AiredDuringSeason { get ; set ; }
2013-11-20 21:08:12 +00:00
2014-01-07 18:39:35 +00:00
[ApiMember(Name = "MinPremiereDate", Description = "Optional. The minimum premiere date. Format = ISO", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
2013-11-19 17:17:14 +00:00
public string MinPremiereDate { get ; set ; }
2014-01-07 18:39:35 +00:00
[ApiMember(Name = "MaxPremiereDate", Description = "Optional. The maximum premiere date. Format = ISO", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
2013-11-19 17:17:14 +00:00
public string MaxPremiereDate { get ; set ; }
2013-12-02 02:24:14 +00:00
[ApiMember(Name = "HasOverview", Description = "Optional filter by items that have an overview or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? HasOverview { get ; set ; }
[ApiMember(Name = "HasImdbId", Description = "Optional filter by items that have an imdb id or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? HasImdbId { get ; set ; }
[ApiMember(Name = "HasTmdbId", Description = "Optional filter by items that have a tmdb id or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? HasTmdbId { get ; set ; }
[ApiMember(Name = "HasTvdbId", Description = "Optional filter by items that have a tvdb id or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? HasTvdbId { get ; set ; }
2013-12-06 03:39:44 +00:00
2013-12-02 02:24:14 +00:00
[ApiMember(Name = "IsYearMismatched", Description = "Optional filter by items that are potentially misidentified.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? IsYearMismatched { get ; set ; }
2014-01-19 19:25:29 +00:00
[ApiMember(Name = "IsInBoxSet", Description = "Optional filter by items that are in boxsets, or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? IsInBoxSet { get ; set ; }
2014-03-03 05:11:03 +00:00
[ApiMember(Name = "IsLocked", Description = "Optional filter by items that are locked.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public bool? IsLocked { get ; set ; }
2014-03-04 04:53:48 +00:00
[ApiMember(Name = "IsUnidentified", Description = "Optional filter by items that are unidentified by internet metadata providers.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
2014-03-03 05:11:03 +00:00
public bool? IsUnidentified { get ; set ; }
2014-03-04 04:53:48 +00:00
[ApiMember(Name = "IsPlaceHolder", Description = "Optional filter by items that are placeholders", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public bool? IsPlaceHolder { get ; set ; }
[ApiMember(Name = "HasOfficialRating", Description = "Optional filter by items that have official ratings", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public bool? HasOfficialRating { get ; set ; }
2014-03-15 04:14:07 +00:00
[ApiMember(Name = "CollapseBoxSetItems", Description = "Whether or not to hide items behind their boxsets.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
2014-03-18 17:05:57 +00:00
public bool? CollapseBoxSetItems { get ; set ; }
2014-10-08 01:37:45 +00:00
public string [ ] GetAllGenres ( )
{
return ( AllGenres ? ? string . Empty ) . Split ( new [ ] { '|' } , StringSplitOptions . RemoveEmptyEntries ) ;
}
public string [ ] GetStudios ( )
{
return ( Studios ? ? string . Empty ) . Split ( new [ ] { '|' } , StringSplitOptions . RemoveEmptyEntries ) ;
}
public string [ ] GetPersonTypes ( )
{
return ( PersonTypes ? ? string . Empty ) . Split ( new [ ] { ',' } , StringSplitOptions . RemoveEmptyEntries ) ;
}
public IEnumerable < VideoType > GetVideoTypes ( )
{
var val = VideoTypes ;
if ( string . IsNullOrEmpty ( val ) )
{
return new VideoType [ ] { } ;
}
return val . Split ( new [ ] { ',' } , StringSplitOptions . RemoveEmptyEntries ) . Select ( v = > ( VideoType ) Enum . Parse ( typeof ( VideoType ) , v , true ) ) ;
}
2013-02-21 01:33:05 +00:00
}
/// <summary>
/// Class ItemsService
/// </summary>
2014-07-02 18:34:08 +00:00
[Authenticated]
2013-03-16 05:52:33 +00:00
public class ItemsService : BaseApiService
2013-02-21 01:33:05 +00:00
{
2013-02-27 20:25:45 +00:00
/// <summary>
/// The _user manager
/// </summary>
private readonly IUserManager _userManager ;
2013-10-02 16:08:58 +00:00
private readonly IUserDataManager _userDataRepository ;
2013-02-27 20:25:45 +00:00
2013-02-28 19:32:41 +00:00
/// <summary>
/// The _library manager
/// </summary>
private readonly ILibraryManager _libraryManager ;
2013-06-10 17:46:11 +00:00
private readonly ILocalizationManager _localization ;
2013-03-09 05:15:51 +00:00
2013-09-04 17:02:19 +00:00
private readonly IDtoService _dtoService ;
2014-04-22 17:25:54 +00:00
private readonly ICollectionManager _collectionManager ;
2013-09-04 17:02:19 +00:00
2013-02-27 20:25:45 +00:00
/// <summary>
/// Initializes a new instance of the <see cref="ItemsService" /> class.
/// </summary>
/// <param name="userManager">The user manager.</param>
2013-03-28 22:00:58 +00:00
/// <param name="libraryManager">The library manager.</param>
2013-04-13 18:02:30 +00:00
/// <param name="userDataRepository">The user data repository.</param>
2014-04-22 17:25:54 +00:00
/// <param name="localization">The localization.</param>
/// <param name="dtoService">The dto service.</param>
/// <param name="collectionManager">The collection manager.</param>
public ItemsService ( IUserManager userManager , ILibraryManager libraryManager , IUserDataManager userDataRepository , ILocalizationManager localization , IDtoService dtoService , ICollectionManager collectionManager )
2013-02-27 20:25:45 +00:00
{
_userManager = userManager ;
2013-02-28 19:32:41 +00:00
_libraryManager = libraryManager ;
2013-04-13 18:02:30 +00:00
_userDataRepository = userDataRepository ;
2013-06-13 18:17:59 +00:00
_localization = localization ;
2013-09-04 17:02:19 +00:00
_dtoService = dtoService ;
2014-04-22 17:25:54 +00:00
_collectionManager = collectionManager ;
2013-02-27 20:25:45 +00:00
}
2013-02-21 01:33:05 +00:00
/// <summary>
/// Gets the specified request.
/// </summary>
/// <param name="request">The request.</param>
/// <returns>System.Object.</returns>
2014-10-06 23:58:46 +00:00
public async Task < object > Get ( GetItems request )
2013-02-21 01:33:05 +00:00
{
2014-10-06 23:58:46 +00:00
var result = await GetItems ( request ) . ConfigureAwait ( false ) ;
2013-02-21 01:33:05 +00:00
2014-02-04 04:04:19 +00:00
return ToOptimizedSerializedResultUsingCache ( result ) ;
2013-02-21 01:33:05 +00:00
}
/// <summary>
/// Gets the items.
/// </summary>
/// <param name="request">The request.</param>
/// <returns>Task{ItemsResult}.</returns>
2014-10-06 23:58:46 +00:00
private async Task < ItemsResult > GetItems ( GetItems request )
2013-02-21 01:33:05 +00:00
{
2014-04-27 03:42:05 +00:00
var parentItem = string . IsNullOrEmpty ( request . ParentId ) ? null : _libraryManager . GetItemById ( request . ParentId ) ;
2014-01-22 17:05:23 +00:00
var user = request . UserId . HasValue ? _userManager . GetUserById ( request . UserId . Value ) : null ;
2013-02-21 01:33:05 +00:00
2014-10-06 23:58:46 +00:00
var result = await GetItemsToSerialize ( request , user , parentItem ) . ConfigureAwait ( false ) ;
2013-02-21 01:33:05 +00:00
2014-10-06 23:58:46 +00:00
var isFiltered = result . Item2 ;
2013-04-05 15:58:06 +00:00
2014-10-06 23:58:46 +00:00
if ( isFiltered )
{
var currentFields = request . GetItemFields ( ) . ToList ( ) ;
return new ItemsResult
{
TotalRecordCount = result . Item1 . TotalRecordCount ,
Items = result . Item1 . Items . Select ( i = > _dtoService . GetBaseItemDto ( i , currentFields , user ) ) . ToArray ( )
} ;
}
2014-11-16 22:46:01 +00:00
var items = result . Item1 . Items . Where ( i = > ApplyAdditionalFilters ( request , i , user , false , _libraryManager ) ) ;
2013-04-09 05:06:13 +00:00
2013-02-21 01:33:05 +00:00
// Apply filters
// Run them starting with the ones that are likely to reduce the list the most
2013-04-11 19:36:50 +00:00
foreach ( var filter in request . GetFilters ( ) . OrderByDescending ( f = > ( int ) f ) )
2013-02-21 01:33:05 +00:00
{
2013-04-13 18:02:30 +00:00
items = ApplyFilter ( items , filter , user , _userDataRepository ) ;
2013-02-21 01:33:05 +00:00
}
2014-10-08 01:37:45 +00:00
items = UserViewBuilder . FilterVirtualEpisodes ( items ,
request . IsMissing ,
request . IsVirtualUnaired ,
request . IsUnaired ) ;
2013-10-26 22:01:21 +00:00
2014-10-08 01:37:45 +00:00
var internalQuery = GetItemsQuery ( request , user ) ;
2014-03-15 04:14:07 +00:00
2014-10-08 01:37:45 +00:00
items = UserViewBuilder . CollapseBoxSetItemsIfNeeded ( items , internalQuery , parentItem , user ) ;
2014-10-06 23:58:46 +00:00
items = _libraryManager . Sort ( items , user , request . GetOrderBy ( ) , request . SortOrder ? ? SortOrder . Ascending ) ;
2013-02-21 01:33:05 +00:00
2013-12-04 04:18:50 +00:00
// This must be the last filter
if ( ! string . IsNullOrEmpty ( request . AdjacentTo ) )
{
2014-10-08 01:37:45 +00:00
items = UserViewBuilder . FilterForAdjacency ( items , request . AdjacentTo ) ;
2013-12-04 04:18:50 +00:00
}
2013-09-20 00:53:18 +00:00
var itemsArray = items . ToList ( ) ;
2013-02-21 01:33:05 +00:00
var pagedItems = ApplyPaging ( request , itemsArray ) ;
2013-04-11 19:36:50 +00:00
var fields = request . GetItemFields ( ) . ToList ( ) ;
2013-02-21 01:33:05 +00:00
2013-09-17 02:44:06 +00:00
var returnItems = pagedItems . Select ( i = > _dtoService . GetBaseItemDto ( i , fields , user ) ) . ToArray ( ) ;
2013-02-21 01:33:05 +00:00
return new ItemsResult
{
2013-09-20 00:53:18 +00:00
TotalRecordCount = itemsArray . Count ,
2013-02-21 01:33:05 +00:00
Items = returnItems
} ;
}
/// <summary>
/// Gets the items to serialize.
/// </summary>
/// <param name="request">The request.</param>
/// <param name="user">The user.</param>
2014-04-27 03:42:05 +00:00
/// <param name="parentItem">The parent item.</param>
2013-02-21 01:33:05 +00:00
/// <returns>IEnumerable{BaseItem}.</returns>
2014-10-06 23:58:46 +00:00
private async Task < Tuple < QueryResult < BaseItem > , bool > > GetItemsToSerialize ( GetItems request , User user , BaseItem parentItem )
2013-02-21 01:33:05 +00:00
{
2014-01-22 17:05:23 +00:00
var item = string . IsNullOrEmpty ( request . ParentId ) ?
2014-03-03 02:17:12 +00:00
user = = null ? _libraryManager . RootFolder : user . RootFolder :
2014-04-27 03:42:05 +00:00
parentItem ;
2013-02-21 01:33:05 +00:00
// Default list type = children
2013-10-15 22:16:39 +00:00
IEnumerable < BaseItem > items ;
2013-02-21 01:33:05 +00:00
2013-03-16 01:40:34 +00:00
if ( ! string . IsNullOrEmpty ( request . Ids ) )
{
var idList = request . Ids . Split ( ',' ) . ToList ( ) ;
2014-04-25 20:15:50 +00:00
items = idList . Select ( i = > _libraryManager . GetItemById ( i ) ) ;
2013-10-15 22:16:39 +00:00
}
else if ( request . Recursive )
{
2014-10-06 23:58:46 +00:00
if ( user = = null )
{
items = ( ( Folder ) item ) . RecursiveChildren ;
items = _libraryManager . ReplaceVideosWithPrimaryVersions ( items ) ;
}
else
{
var result = await ( ( Folder ) item ) . GetItems ( GetItemsQuery ( request , user ) ) ;
2014-03-19 04:59:45 +00:00
2014-10-06 23:58:46 +00:00
return new Tuple < QueryResult < BaseItem > , bool > ( result , true ) ;
}
2013-10-15 22:16:39 +00:00
}
else
{
2014-10-06 23:58:46 +00:00
if ( user = = null )
{
items = ( ( Folder ) item ) . Children ;
items = _libraryManager . ReplaceVideosWithPrimaryVersions ( items ) ;
}
else
{
var userRoot = item as UserRootFolder ;
if ( userRoot = = null )
{
var result = await ( ( Folder ) item ) . GetItems ( GetItemsQuery ( request , user ) ) ;
return new Tuple < QueryResult < BaseItem > , bool > ( result , true ) ;
}
2014-03-19 04:59:45 +00:00
2014-10-06 23:58:46 +00:00
items = ( ( Folder ) item ) . GetChildren ( user , true ) ;
}
2013-03-16 01:40:34 +00:00
}
2013-10-15 22:16:39 +00:00
if ( request . IncludeIndexContainers )
2013-02-21 01:33:05 +00:00
{
2013-10-15 22:16:39 +00:00
var list = items . ToList ( ) ;
var containers = list . Select ( i = > i . IndexContainer )
. Where ( i = > i ! = null ) ;
list . AddRange ( containers ) ;
2014-10-06 23:58:46 +00:00
items = list . Distinct ( ) ;
2013-02-21 01:33:05 +00:00
}
2014-10-06 23:58:46 +00:00
return new Tuple < QueryResult < BaseItem > , bool > ( new QueryResult < BaseItem >
{
Items = items . ToArray ( )
} , false ) ;
2013-02-21 01:33:05 +00:00
}
2014-10-06 23:58:46 +00:00
private InternalItemsQuery GetItemsQuery ( GetItems request , User user )
2013-02-21 01:33:05 +00:00
{
2014-10-06 23:58:46 +00:00
var query = new InternalItemsQuery
{
User = user ,
IsPlayed = request . IsPlayed ,
MediaTypes = request . GetMediaTypes ( ) ,
IncludeItemTypes = request . GetIncludeItemTypes ( ) ,
ExcludeItemTypes = request . GetExcludeItemTypes ( ) ,
Recursive = request . Recursive ,
SortBy = request . GetOrderBy ( ) ,
SortOrder = request . SortOrder ? ? SortOrder . Ascending ,
2014-11-16 22:46:01 +00:00
Filter = ( i , u ) = > ApplyAdditionalFilters ( request , i , u , true , _libraryManager ) ,
2014-10-06 23:58:46 +00:00
Limit = request . Limit ,
2014-10-08 01:37:45 +00:00
StartIndex = request . StartIndex ,
IsMissing = request . IsMissing ,
IsVirtualUnaired = request . IsVirtualUnaired ,
IsUnaired = request . IsUnaired ,
CollapseBoxSetItems = request . CollapseBoxSetItems ,
NameLessThan = request . NameLessThan ,
NameStartsWith = request . NameStartsWith ,
NameStartsWithOrGreater = request . NameStartsWithOrGreater ,
HasImdbId = request . HasImdbId ,
IsYearMismatched = request . IsYearMismatched ,
IsUnidentified = request . IsUnidentified ,
IsPlaceHolder = request . IsPlaceHolder ,
IsLocked = request . IsLocked ,
IsInBoxSet = request . IsInBoxSet ,
IsHD = request . IsHD ,
Is3D = request . Is3D ,
HasTvdbId = request . HasTvdbId ,
HasTmdbId = request . HasTmdbId ,
HasOverview = request . HasOverview ,
HasOfficialRating = request . HasOfficialRating ,
HasParentalRating = request . HasParentalRating ,
HasSpecialFeature = request . HasSpecialFeature ,
HasSubtitles = request . HasSubtitles ,
HasThemeSong = request . HasThemeSong ,
HasThemeVideo = request . HasThemeVideo ,
HasTrailer = request . HasTrailer ,
2014-11-10 04:20:11 +00:00
Tags = request . GetTags ( ) ,
OfficialRatings = request . GetOfficialRatings ( ) ,
2014-10-08 01:37:45 +00:00
Genres = request . GetGenres ( ) ,
AllGenres = request . GetAllGenres ( ) ,
Studios = request . GetStudios ( ) ,
Person = request . Person ,
PersonTypes = request . GetPersonTypes ( ) ,
Years = request . GetYears ( ) ,
ImageTypes = request . GetImageTypes ( ) . ToArray ( ) ,
VideoTypes = request . GetVideoTypes ( ) . ToArray ( ) ,
AdjacentTo = request . AdjacentTo
2014-10-06 23:58:46 +00:00
} ;
2014-10-08 01:37:45 +00:00
if ( ! string . IsNullOrWhiteSpace ( request . Ids ) )
{
query . CollapseBoxSetItems = false ;
}
2014-10-06 23:58:46 +00:00
foreach ( var filter in request . GetFilters ( ) )
{
switch ( filter )
{
case ItemFilter . Dislikes :
query . IsLiked = false ;
break ;
case ItemFilter . IsFavorite :
query . IsFavorite = true ;
break ;
case ItemFilter . IsFavoriteOrLikes :
query . IsFavoriteOrLiked = true ;
break ;
case ItemFilter . IsFolder :
query . IsFolder = true ;
break ;
case ItemFilter . IsNotFolder :
query . IsFolder = false ;
break ;
case ItemFilter . IsPlayed :
query . IsPlayed = true ;
break ;
case ItemFilter . IsRecentlyAdded :
break ;
case ItemFilter . IsResumable :
query . IsResumable = true ;
break ;
case ItemFilter . IsUnplayed :
query . IsPlayed = false ;
break ;
case ItemFilter . Likes :
query . IsLiked = true ;
break ;
}
}
2013-02-21 01:33:05 +00:00
2014-10-06 23:58:46 +00:00
return query ;
2013-02-21 01:33:05 +00:00
}
/// <summary>
/// Applies filtering
/// </summary>
/// <param name="items">The items.</param>
/// <param name="filter">The filter.</param>
/// <param name="user">The user.</param>
2013-04-13 18:02:30 +00:00
/// <param name="repository">The repository.</param>
2013-02-21 01:33:05 +00:00
/// <returns>IEnumerable{BaseItem}.</returns>
2013-10-02 16:08:58 +00:00
internal static IEnumerable < BaseItem > ApplyFilter ( IEnumerable < BaseItem > items , ItemFilter filter , User user , IUserDataManager repository )
2013-02-21 01:33:05 +00:00
{
2014-01-15 22:19:37 +00:00
// Avoid implicitly captured closure
var currentUser = user ;
2013-02-21 01:33:05 +00:00
switch ( filter )
{
2013-07-30 20:31:25 +00:00
case ItemFilter . IsFavoriteOrLikes :
return items . Where ( item = >
{
var userdata = repository . GetUserData ( user . Id , item . GetUserDataKey ( ) ) ;
if ( userdata = = null )
{
return false ;
}
var likes = userdata . Likes ? ? false ;
var favorite = userdata . IsFavorite ;
return likes | | favorite ;
} ) ;
2013-03-30 14:57:30 +00:00
case ItemFilter . Likes :
return items . Where ( item = >
{
2013-06-17 20:35:43 +00:00
var userdata = repository . GetUserData ( user . Id , item . GetUserDataKey ( ) ) ;
2013-03-30 14:57:30 +00:00
return userdata ! = null & & userdata . Likes . HasValue & & userdata . Likes . Value ;
} ) ;
case ItemFilter . Dislikes :
return items . Where ( item = >
{
2013-06-17 20:35:43 +00:00
var userdata = repository . GetUserData ( user . Id , item . GetUserDataKey ( ) ) ;
2013-03-30 14:57:30 +00:00
return userdata ! = null & & userdata . Likes . HasValue & & ! userdata . Likes . Value ;
} ) ;
2013-02-21 01:33:05 +00:00
case ItemFilter . IsFavorite :
return items . Where ( item = >
{
2013-06-17 20:35:43 +00:00
var userdata = repository . GetUserData ( user . Id , item . GetUserDataKey ( ) ) ;
2013-02-21 01:33:05 +00:00
return userdata ! = null & & userdata . IsFavorite ;
} ) ;
case ItemFilter . IsResumable :
return items . Where ( item = >
{
2013-06-17 20:35:43 +00:00
var userdata = repository . GetUserData ( user . Id , item . GetUserDataKey ( ) ) ;
2013-02-21 01:33:05 +00:00
return userdata ! = null & & userdata . PlaybackPositionTicks > 0 ;
} ) ;
case ItemFilter . IsPlayed :
2014-01-15 22:19:37 +00:00
return items . Where ( item = > item . IsPlayed ( currentUser ) ) ;
2013-02-21 01:33:05 +00:00
case ItemFilter . IsUnplayed :
2014-01-18 05:55:21 +00:00
return items . Where ( item = > item . IsUnplayed ( currentUser ) ) ;
2013-02-21 01:33:05 +00:00
case ItemFilter . IsFolder :
return items . Where ( item = > item . IsFolder ) ;
case ItemFilter . IsNotFolder :
return items . Where ( item = > ! item . IsFolder ) ;
2014-05-07 02:28:19 +00:00
case ItemFilter . IsRecentlyAdded :
return items . Where ( item = > ( DateTime . UtcNow - item . DateCreated ) . TotalDays < = 10 ) ;
2013-02-21 01:33:05 +00:00
}
return items ;
}
2014-11-16 22:46:01 +00:00
private bool ApplyAdditionalFilters ( GetItems request , BaseItem i , User user , bool isPreFiltered , ILibraryManager libraryManager )
2013-02-21 01:33:05 +00:00
{
2014-10-06 23:58:46 +00:00
if ( ! isPreFiltered )
{
var mediaTypes = request . GetMediaTypes ( ) ;
if ( mediaTypes . Length > 0 )
{
if ( ! ( ! string . IsNullOrEmpty ( i . MediaType ) & & mediaTypes . Contains ( i . MediaType , StringComparer . OrdinalIgnoreCase ) ) )
{
return false ;
}
}
if ( request . IsPlayed . HasValue )
{
var val = request . IsPlayed . Value ;
if ( i . IsPlayed ( user ) ! = val )
{
return false ;
}
}
// Exclude item types
var excluteItemTypes = request . GetExcludeItemTypes ( ) ;
if ( excluteItemTypes . Length > 0 & & excluteItemTypes . Contains ( i . GetType ( ) . Name , StringComparer . OrdinalIgnoreCase ) )
{
return false ;
}
// Include item types
var includeItemTypes = request . GetIncludeItemTypes ( ) ;
if ( includeItemTypes . Length > 0 & & ! includeItemTypes . Contains ( i . GetType ( ) . Name , StringComparer . OrdinalIgnoreCase ) )
{
return false ;
}
2014-10-08 01:37:45 +00:00
if ( request . IsInBoxSet . HasValue )
{
var val = request . IsInBoxSet . Value ;
if ( i . Parents . OfType < BoxSet > ( ) . Any ( ) ! = val )
{
return false ;
}
}
2013-11-03 16:19:33 +00:00
2014-10-08 01:37:45 +00:00
// Filter by Video3DFormat
if ( request . Is3D . HasValue )
2014-10-06 23:58:46 +00:00
{
2014-10-08 01:37:45 +00:00
var val = request . Is3D . Value ;
var video = i as Video ;
if ( video = = null | | val ! = video . Video3DFormat . HasValue )
{
return false ;
}
2014-10-06 23:58:46 +00:00
}
2013-11-03 16:19:33 +00:00
2014-10-08 01:37:45 +00:00
if ( request . IsHD . HasValue )
{
var val = request . IsHD . Value ;
var video = i as Video ;
2013-11-03 16:19:33 +00:00
2014-10-08 01:37:45 +00:00
if ( video = = null | | val ! = video . IsHD )
{
return false ;
}
}
2013-11-06 16:06:16 +00:00
2014-10-08 01:37:45 +00:00
if ( request . IsUnidentified . HasValue )
2014-10-06 23:58:46 +00:00
{
2014-10-08 01:37:45 +00:00
var val = request . IsUnidentified . Value ;
if ( i . IsUnidentified ! = val )
2013-11-06 16:06:16 +00:00
{
2014-10-06 23:58:46 +00:00
return false ;
2013-11-06 16:06:16 +00:00
}
2014-10-06 23:58:46 +00:00
}
2014-10-08 01:37:45 +00:00
if ( request . IsLocked . HasValue )
2014-10-06 23:58:46 +00:00
{
2014-10-08 01:37:45 +00:00
var val = request . IsLocked . Value ;
if ( i . IsLocked ! = val )
{
return false ;
}
2014-10-06 23:58:46 +00:00
}
2013-11-03 16:19:33 +00:00
2014-10-08 01:37:45 +00:00
if ( request . HasOverview . HasValue )
{
var filterValue = request . HasOverview . Value ;
2013-04-24 14:05:47 +00:00
2014-10-08 01:37:45 +00:00
var hasValue = ! string . IsNullOrEmpty ( i . Overview ) ;
2013-04-24 14:05:47 +00:00
2014-10-08 01:37:45 +00:00
if ( hasValue ! = filterValue )
{
return false ;
}
2014-10-06 23:58:46 +00:00
}
2013-04-24 14:05:47 +00:00
2014-10-08 01:37:45 +00:00
if ( request . HasImdbId . HasValue )
{
var filterValue = request . HasImdbId . Value ;
2013-08-08 12:19:11 +00:00
2014-10-08 01:37:45 +00:00
var hasValue = ! string . IsNullOrEmpty ( i . GetProviderId ( MetadataProviders . Imdb ) ) ;
2013-08-08 12:19:11 +00:00
2014-10-08 01:37:45 +00:00
if ( hasValue ! = filterValue )
2013-08-08 12:19:11 +00:00
{
2014-10-06 23:58:46 +00:00
return false ;
2013-08-08 12:19:11 +00:00
}
2014-10-06 23:58:46 +00:00
}
2013-08-08 12:19:11 +00:00
2014-10-08 01:37:45 +00:00
if ( request . HasTmdbId . HasValue )
2014-10-06 23:58:46 +00:00
{
2014-10-08 01:37:45 +00:00
var filterValue = request . HasTmdbId . Value ;
var hasValue = ! string . IsNullOrEmpty ( i . GetProviderId ( MetadataProviders . Tmdb ) ) ;
if ( hasValue ! = filterValue )
2013-08-08 12:19:11 +00:00
{
2014-10-06 23:58:46 +00:00
return false ;
2013-08-08 12:19:11 +00:00
}
2014-10-06 23:58:46 +00:00
}
2013-08-08 12:19:11 +00:00
2014-10-08 01:37:45 +00:00
if ( request . HasTvdbId . HasValue )
2014-10-06 23:58:46 +00:00
{
2014-10-08 01:37:45 +00:00
var filterValue = request . HasTvdbId . Value ;
var hasValue = ! string . IsNullOrEmpty ( i . GetProviderId ( MetadataProviders . Tvdb ) ) ;
if ( hasValue ! = filterValue )
2013-08-08 12:19:11 +00:00
{
2014-10-06 23:58:46 +00:00
return false ;
2013-08-08 12:19:11 +00:00
}
2014-10-06 23:58:46 +00:00
}
2013-08-08 12:19:11 +00:00
2014-10-08 01:37:45 +00:00
if ( request . IsYearMismatched . HasValue )
2014-10-06 23:58:46 +00:00
{
2014-10-08 01:37:45 +00:00
var filterValue = request . IsYearMismatched . Value ;
2014-11-16 22:46:01 +00:00
if ( UserViewBuilder . IsYearMismatched ( i , libraryManager ) ! = filterValue )
2014-10-08 01:37:45 +00:00
{
return false ;
}
2014-10-06 23:58:46 +00:00
}
2013-08-31 01:08:32 +00:00
2014-10-08 01:37:45 +00:00
if ( request . HasOfficialRating . HasValue )
{
var filterValue = request . HasOfficialRating . Value ;
2013-04-14 00:17:25 +00:00
2014-10-08 01:37:45 +00:00
var hasValue = ! string . IsNullOrEmpty ( i . OfficialRating ) ;
if ( hasValue ! = filterValue )
{
return false ;
}
}
if ( request . IsPlaceHolder . HasValue )
2013-06-10 17:46:11 +00:00
{
2014-10-08 01:37:45 +00:00
var filterValue = request . IsPlaceHolder . Value ;
2014-10-06 23:58:46 +00:00
2014-10-08 01:37:45 +00:00
var isPlaceHolder = false ;
var hasPlaceHolder = i as ISupportsPlaceHolders ;
if ( hasPlaceHolder ! = null )
2013-06-10 17:46:11 +00:00
{
2014-10-08 01:37:45 +00:00
isPlaceHolder = hasPlaceHolder . IsPlaceHolder ;
2014-10-06 23:58:46 +00:00
}
2013-09-11 17:54:59 +00:00
2014-10-08 01:37:45 +00:00
if ( isPlaceHolder ! = filterValue )
2014-10-06 23:58:46 +00:00
{
2014-10-08 01:37:45 +00:00
return false ;
}
}
2013-06-10 17:46:11 +00:00
2014-10-08 01:37:45 +00:00
if ( request . HasSpecialFeature . HasValue )
{
var filterValue = request . HasSpecialFeature . Value ;
var movie = i as IHasSpecialFeatures ;
if ( movie ! = null )
{
var ok = filterValue
? movie . SpecialFeatureIds . Count > 0
: movie . SpecialFeatureIds . Count = = 0 ;
if ( ! ok )
2013-06-10 17:46:11 +00:00
{
2014-10-06 23:58:46 +00:00
return false ;
2013-06-10 17:46:11 +00:00
}
2014-10-06 23:58:46 +00:00
}
2014-10-08 01:37:45 +00:00
else
{
return false ;
}
2013-06-10 17:46:11 +00:00
}
2013-04-14 00:17:25 +00:00
2014-10-08 01:37:45 +00:00
if ( request . HasSubtitles . HasValue )
{
var val = request . HasSubtitles . Value ;
2013-04-14 00:17:25 +00:00
2014-10-08 01:37:45 +00:00
var video = i as Video ;
if ( video = = null | | val ! = video . HasSubtitles )
{
return false ;
}
}
if ( request . HasParentalRating . HasValue )
2013-06-10 17:46:11 +00:00
{
2014-10-08 01:37:45 +00:00
var val = request . HasParentalRating . Value ;
2014-10-06 23:58:46 +00:00
var rating = i . CustomRating ;
if ( string . IsNullOrEmpty ( rating ) )
2013-06-10 17:46:11 +00:00
{
2014-10-06 23:58:46 +00:00
rating = i . OfficialRating ;
}
2013-09-11 17:54:59 +00:00
2014-10-08 01:37:45 +00:00
if ( val )
2014-10-06 23:58:46 +00:00
{
2014-10-08 01:37:45 +00:00
if ( string . IsNullOrEmpty ( rating ) )
{
return false ;
}
}
else
{
if ( ! string . IsNullOrEmpty ( rating ) )
2013-06-10 17:46:11 +00:00
{
2014-10-06 23:58:46 +00:00
return false ;
2013-06-10 17:46:11 +00:00
}
2014-10-06 23:58:46 +00:00
}
2013-06-10 17:46:11 +00:00
}
2013-04-14 00:17:25 +00:00
2014-10-08 01:37:45 +00:00
if ( request . HasTrailer . HasValue )
2014-10-06 23:58:46 +00:00
{
2014-10-08 01:37:45 +00:00
var val = request . HasTrailer . Value ;
var trailerCount = 0 ;
2013-10-16 23:35:11 +00:00
2014-10-08 01:37:45 +00:00
var hasTrailers = i as IHasTrailers ;
if ( hasTrailers ! = null )
{
trailerCount = hasTrailers . LocalTrailerIds . Count ;
}
2013-10-26 22:01:21 +00:00
2014-10-08 01:37:45 +00:00
var ok = val ? trailerCount > 0 : trailerCount = = 0 ;
2014-10-06 23:58:46 +00:00
2014-10-08 01:37:45 +00:00
if ( ! ok )
{
return false ;
}
2014-10-06 23:58:46 +00:00
}
2013-04-07 20:55:05 +00:00
2014-10-08 01:37:45 +00:00
if ( request . HasThemeSong . HasValue )
2014-10-06 23:58:46 +00:00
{
2014-10-08 01:37:45 +00:00
var filterValue = request . HasThemeSong . Value ;
2013-04-07 20:55:05 +00:00
2014-10-08 01:37:45 +00:00
var themeCount = 0 ;
var iHasThemeMedia = i as IHasThemeMedia ;
2013-04-07 20:55:05 +00:00
2014-10-08 01:37:45 +00:00
if ( iHasThemeMedia ! = null )
{
themeCount = iHasThemeMedia . ThemeSongIds . Count ;
}
var ok = filterValue ? themeCount > 0 : themeCount = = 0 ;
2014-10-06 23:58:46 +00:00
2014-10-08 01:37:45 +00:00
if ( ! ok )
{
return false ;
}
2014-10-06 23:58:46 +00:00
}
2014-10-08 01:37:45 +00:00
if ( request . HasThemeVideo . HasValue )
2014-10-06 23:58:46 +00:00
{
2014-10-08 01:37:45 +00:00
var filterValue = request . HasThemeVideo . Value ;
2013-04-04 15:22:39 +00:00
2014-10-08 01:37:45 +00:00
var themeCount = 0 ;
var iHasThemeMedia = i as IHasThemeMedia ;
2013-04-04 15:22:39 +00:00
2014-10-08 01:37:45 +00:00
if ( iHasThemeMedia ! = null )
{
themeCount = iHasThemeMedia . ThemeVideoIds . Count ;
}
var ok = filterValue ? themeCount > 0 : themeCount = = 0 ;
2013-05-16 19:00:42 +00:00
2014-10-08 01:37:45 +00:00
if ( ! ok )
{
return false ;
}
2014-10-06 23:58:46 +00:00
}
2013-02-21 01:33:05 +00:00
2014-11-10 04:20:11 +00:00
// Apply tag filter
var tags = request . GetTags ( ) ;
if ( tags . Length > 0 )
{
var hasTags = i as IHasTags ;
if ( hasTags = = null )
{
return false ;
}
if ( ! ( tags . Any ( v = > hasTags . Tags . Contains ( v , StringComparer . OrdinalIgnoreCase ) ) ) )
{
return false ;
}
}
// Apply official rating filter
var officialRatings = request . GetOfficialRatings ( ) ;
if ( officialRatings . Length > 0 & & ! officialRatings . Contains ( i . OfficialRating ? ? string . Empty ) )
{
return false ;
}
2014-10-08 01:37:45 +00:00
// Apply genre filter
var genres = request . GetGenres ( ) ;
if ( genres . Length > 0 & & ! ( genres . Any ( v = > i . Genres . Contains ( v , StringComparer . OrdinalIgnoreCase ) ) ) )
2014-10-06 23:58:46 +00:00
{
return false ;
}
2013-02-21 01:33:05 +00:00
2014-10-08 01:37:45 +00:00
// Apply genre filter
var allGenres = request . GetAllGenres ( ) ;
if ( allGenres . Length > 0 & & ! allGenres . All ( v = > i . Genres . Contains ( v , StringComparer . OrdinalIgnoreCase ) ) )
2014-10-06 23:58:46 +00:00
{
return false ;
}
2013-10-16 23:35:11 +00:00
2014-10-08 01:37:45 +00:00
// Filter by VideoType
if ( ! string . IsNullOrEmpty ( request . VideoTypes ) )
2014-10-06 23:58:46 +00:00
{
2014-10-08 01:37:45 +00:00
var types = request . VideoTypes . Split ( ',' ) ;
2013-04-13 23:43:41 +00:00
2014-10-08 01:37:45 +00:00
var video = i as Video ;
if ( video = = null | | ! types . Contains ( video . VideoType . ToString ( ) , StringComparer . OrdinalIgnoreCase ) )
2014-10-06 23:58:46 +00:00
{
return false ;
}
2013-04-13 23:43:41 +00:00
}
2014-10-08 01:37:45 +00:00
var imageTypes = request . GetImageTypes ( ) . ToList ( ) ;
if ( imageTypes . Count > 0 )
{
if ( ! ( imageTypes . Any ( i . HasImage ) ) )
2014-10-06 23:58:46 +00:00
{
return false ;
}
2013-04-13 23:43:41 +00:00
}
2014-10-06 23:58:46 +00:00
2014-10-08 01:37:45 +00:00
// Apply studio filter
var studios = request . GetStudios ( ) ;
if ( studios . Length > 0 & & ! studios . Any ( v = > i . Studios . Contains ( v , StringComparer . OrdinalIgnoreCase ) ) )
2013-12-02 16:46:25 +00:00
{
2014-10-08 01:37:45 +00:00
return false ;
2014-10-06 23:58:46 +00:00
}
2013-12-02 16:46:25 +00:00
2014-10-08 01:37:45 +00:00
// Apply year filter
var years = request . GetYears ( ) ;
if ( years . Length > 0 & & ! ( i . ProductionYear . HasValue & & years . Contains ( i . ProductionYear . Value ) ) )
2014-10-06 23:58:46 +00:00
{
return false ;
}
2013-04-30 01:29:04 +00:00
2014-10-08 01:37:45 +00:00
// Apply person filter
if ( ! string . IsNullOrEmpty ( request . Person ) )
{
var personTypes = request . GetPersonTypes ( ) ;
2013-12-05 16:50:21 +00:00
2014-10-08 01:37:45 +00:00
if ( personTypes . Length = = 0 )
{
if ( ! ( i . People . Any ( p = > string . Equals ( p . Name , request . Person , StringComparison . OrdinalIgnoreCase ) ) ) )
{
return false ;
}
}
else
{
var types = personTypes ;
2014-10-06 23:58:46 +00:00
2014-10-08 01:37:45 +00:00
var ok = new [ ] { i } . Any ( item = >
item . People ! = null & &
item . People . Any ( p = >
p . Name . Equals ( request . Person , StringComparison . OrdinalIgnoreCase ) & & ( types . Contains ( p . Type , StringComparer . OrdinalIgnoreCase ) | | types . Contains ( p . Role , StringComparer . OrdinalIgnoreCase ) ) ) ) ;
2013-12-05 16:50:21 +00:00
2014-10-08 01:37:45 +00:00
if ( ! ok )
{
return false ;
}
}
2014-10-06 23:58:46 +00:00
}
2013-04-30 01:29:04 +00:00
}
2014-10-08 01:37:45 +00:00
if ( request . MinCommunityRating . HasValue )
2013-04-30 01:29:04 +00:00
{
2014-10-08 01:37:45 +00:00
var val = request . MinCommunityRating . Value ;
2013-12-05 16:50:21 +00:00
2014-10-08 01:37:45 +00:00
if ( ! ( i . CommunityRating . HasValue & & i . CommunityRating > = val ) )
2014-10-06 23:58:46 +00:00
{
return false ;
}
2013-04-30 01:29:04 +00:00
}
2014-10-08 01:37:45 +00:00
if ( request . MinCriticRating . HasValue )
2013-09-15 19:33:23 +00:00
{
2014-10-08 01:37:45 +00:00
var val = request . MinCriticRating . Value ;
2013-09-15 19:33:23 +00:00
2014-10-08 01:37:45 +00:00
var hasCriticRating = i as IHasCriticRating ;
2014-10-06 23:58:46 +00:00
2014-10-08 01:37:45 +00:00
if ( hasCriticRating ! = null )
2013-09-15 19:33:23 +00:00
{
2014-10-08 01:37:45 +00:00
if ( ! ( hasCriticRating . CriticRating . HasValue & & hasCriticRating . CriticRating > = val ) )
2014-10-06 23:58:46 +00:00
{
return false ;
2013-09-15 19:33:23 +00:00
}
2014-10-06 23:58:46 +00:00
}
else
{
2013-09-15 19:33:23 +00:00
return false ;
2014-10-06 23:58:46 +00:00
}
2013-09-15 19:33:23 +00:00
}
2014-10-08 01:37:45 +00:00
// Artists
if ( ! string . IsNullOrEmpty ( request . Artists ) )
2013-10-06 03:03:08 +00:00
{
2014-10-08 01:37:45 +00:00
var artists = request . Artists . Split ( '|' ) ;
2013-10-06 03:03:08 +00:00
2014-10-08 01:37:45 +00:00
var audio = i as IHasArtist ;
2013-10-06 03:03:08 +00:00
2014-10-08 01:37:45 +00:00
if ( ! ( audio ! = null & & artists . Any ( audio . HasArtist ) ) )
2014-10-06 23:58:46 +00:00
{
2013-10-06 03:03:08 +00:00
return false ;
2014-10-06 23:58:46 +00:00
}
2013-10-06 03:03:08 +00:00
}
2014-10-08 01:37:45 +00:00
// Albums
if ( ! string . IsNullOrEmpty ( request . Albums ) )
2013-04-30 01:29:04 +00:00
{
2014-10-08 01:37:45 +00:00
var albums = request . Albums . Split ( '|' ) ;
2013-09-13 18:43:27 +00:00
2014-10-08 01:37:45 +00:00
var audio = i as Audio ;
2014-10-06 23:58:46 +00:00
2014-10-08 01:37:45 +00:00
if ( audio ! = null )
2013-09-13 18:43:27 +00:00
{
2014-10-08 01:37:45 +00:00
if ( ! albums . Any ( a = > string . Equals ( a , audio . Album , StringComparison . OrdinalIgnoreCase ) ) )
2013-09-13 18:43:27 +00:00
{
2014-10-06 23:58:46 +00:00
return false ;
2013-09-13 18:43:27 +00:00
}
2014-10-06 23:58:46 +00:00
}
2013-04-30 01:29:04 +00:00
2014-10-08 01:37:45 +00:00
var album = i as MusicAlbum ;
2013-09-11 17:54:59 +00:00
2014-10-08 01:37:45 +00:00
if ( album ! = null )
2014-10-06 23:58:46 +00:00
{
2014-10-08 01:37:45 +00:00
if ( ! albums . Any ( a = > string . Equals ( a , album . Name , StringComparison . OrdinalIgnoreCase ) ) )
2013-09-11 17:54:59 +00:00
{
2014-10-06 23:58:46 +00:00
return false ;
2013-09-11 17:54:59 +00:00
}
2014-10-06 23:58:46 +00:00
}
2014-10-08 01:37:45 +00:00
var musicVideo = i as MusicVideo ;
if ( musicVideo ! = null )
2014-10-06 23:58:46 +00:00
{
2014-10-08 01:37:45 +00:00
if ( ! albums . Any ( a = > string . Equals ( a , musicVideo . Album , StringComparison . OrdinalIgnoreCase ) ) )
2013-09-11 17:54:59 +00:00
{
2014-10-06 23:58:46 +00:00
return false ;
2013-09-11 17:54:59 +00:00
}
2014-10-06 23:58:46 +00:00
}
2014-10-08 01:37:45 +00:00
return false ;
2013-09-11 17:54:59 +00:00
}
2014-10-08 01:37:45 +00:00
// Min index number
if ( request . MinIndexNumber . HasValue )
2014-01-19 19:25:29 +00:00
{
2014-10-08 01:37:45 +00:00
if ( ! ( i . IndexNumber . HasValue & & i . IndexNumber . Value > = request . MinIndexNumber . Value ) )
2014-10-06 23:58:46 +00:00
{
return false ;
}
2014-01-19 19:25:29 +00:00
}
2014-10-08 01:37:45 +00:00
// Min official rating
if ( ! string . IsNullOrEmpty ( request . MinOfficialRating ) )
2014-03-03 05:11:03 +00:00
{
2014-10-08 01:37:45 +00:00
var level = _localization . GetRatingLevel ( request . MinOfficialRating ) ;
2014-03-03 05:11:03 +00:00
2014-10-08 01:37:45 +00:00
if ( level . HasValue )
2014-10-06 23:58:46 +00:00
{
2014-10-08 01:37:45 +00:00
var rating = i . CustomRating ;
2013-09-13 20:45:27 +00:00
2014-10-08 01:37:45 +00:00
if ( string . IsNullOrEmpty ( rating ) )
2013-09-13 20:45:27 +00:00
{
2014-10-08 01:37:45 +00:00
rating = i . OfficialRating ;
2013-09-13 20:45:27 +00:00
}
2014-10-08 01:37:45 +00:00
if ( ! string . IsNullOrEmpty ( rating ) )
2013-09-13 20:45:27 +00:00
{
2014-10-08 01:37:45 +00:00
var itemLevel = _localization . GetRatingLevel ( rating ) ;
if ( ! ( ! itemLevel . HasValue | | itemLevel . Value > = level . Value ) )
{
return false ;
}
2013-09-13 20:45:27 +00:00
}
2014-10-06 23:58:46 +00:00
}
2013-09-13 20:45:27 +00:00
}
2014-10-08 01:37:45 +00:00
// Max official rating
if ( ! string . IsNullOrEmpty ( request . MaxOfficialRating ) )
2013-11-15 21:31:33 +00:00
{
2014-10-08 01:37:45 +00:00
var level = _localization . GetRatingLevel ( request . MaxOfficialRating ) ;
2014-10-06 23:58:46 +00:00
2014-10-08 01:37:45 +00:00
if ( level . HasValue )
2014-10-06 23:58:46 +00:00
{
2014-10-08 01:37:45 +00:00
var rating = i . CustomRating ;
2014-10-06 23:58:46 +00:00
2014-10-08 01:37:45 +00:00
if ( string . IsNullOrEmpty ( rating ) )
{
rating = i . OfficialRating ;
}
if ( ! string . IsNullOrEmpty ( rating ) )
{
var itemLevel = _localization . GetRatingLevel ( rating ) ;
if ( ! ( ! itemLevel . HasValue | | itemLevel . Value < = level . Value ) )
{
return false ;
}
}
2014-10-06 23:58:46 +00:00
}
2013-11-15 21:31:33 +00:00
}
2014-10-08 01:37:45 +00:00
// LocationTypes
if ( ! string . IsNullOrEmpty ( request . LocationTypes ) )
2013-11-19 17:17:14 +00:00
{
2014-10-08 01:37:45 +00:00
var vals = request . LocationTypes . Split ( ',' ) ;
if ( ! vals . Contains ( i . LocationType . ToString ( ) , StringComparer . OrdinalIgnoreCase ) )
2014-10-06 23:58:46 +00:00
{
return false ;
}
2013-11-19 17:17:14 +00:00
}
2014-10-08 01:37:45 +00:00
// ExcludeLocationTypes
if ( ! string . IsNullOrEmpty ( request . ExcludeLocationTypes ) )
2013-11-19 17:17:14 +00:00
{
2014-10-08 01:37:45 +00:00
var vals = request . ExcludeLocationTypes . Split ( ',' ) ;
if ( vals . Contains ( i . LocationType . ToString ( ) , StringComparer . OrdinalIgnoreCase ) )
2014-10-06 23:58:46 +00:00
{
return false ;
}
2013-11-19 17:17:14 +00:00
}
2014-10-08 01:37:45 +00:00
if ( ! string . IsNullOrEmpty ( request . AlbumArtistStartsWithOrGreater ) )
2013-12-02 02:24:14 +00:00
{
2014-10-08 01:37:45 +00:00
var ok = new [ ] { i } . OfType < IHasAlbumArtist > ( )
. Any ( p = > string . Compare ( request . AlbumArtistStartsWithOrGreater , p . AlbumArtists . FirstOrDefault ( ) , StringComparison . CurrentCultureIgnoreCase ) < 1 ) ;
2013-12-02 02:24:14 +00:00
2014-10-08 01:37:45 +00:00
if ( ! ok )
2014-10-06 23:58:46 +00:00
{
return false ;
}
2013-12-02 02:24:14 +00:00
}
2014-10-08 01:37:45 +00:00
// Filter by Series Status
if ( ! string . IsNullOrEmpty ( request . SeriesStatus ) )
2013-12-02 02:24:14 +00:00
{
2014-10-08 01:37:45 +00:00
var vals = request . SeriesStatus . Split ( ',' ) ;
2013-12-02 02:24:14 +00:00
2014-10-08 01:37:45 +00:00
var ok = new [ ] { i } . OfType < Series > ( ) . Any ( p = > p . Status . HasValue & & vals . Contains ( p . Status . Value . ToString ( ) , StringComparer . OrdinalIgnoreCase ) ) ;
2013-12-02 02:24:14 +00:00
2014-10-08 01:37:45 +00:00
if ( ! ok )
2014-10-06 23:58:46 +00:00
{
return false ;
}
2013-12-02 02:24:14 +00:00
}
2014-10-08 01:37:45 +00:00
// Filter by Series AirDays
if ( ! string . IsNullOrEmpty ( request . AirDays ) )
2013-12-02 02:24:14 +00:00
{
2014-10-08 01:37:45 +00:00
var days = request . AirDays . Split ( ',' ) . Select ( d = > ( DayOfWeek ) Enum . Parse ( typeof ( DayOfWeek ) , d , true ) ) ;
2013-12-02 02:24:14 +00:00
2014-10-08 01:37:45 +00:00
var ok = new [ ] { i } . OfType < Series > ( ) . Any ( p = > p . AirDays ! = null & & days . Any ( d = > p . AirDays . Contains ( d ) ) ) ;
2013-12-02 02:24:14 +00:00
2014-10-08 01:37:45 +00:00
if ( ! ok )
2014-10-06 23:58:46 +00:00
{
return false ;
}
2013-12-02 02:24:14 +00:00
}
2014-10-08 01:37:45 +00:00
if ( request . MinPlayers . HasValue )
2013-12-02 02:24:14 +00:00
{
2014-10-08 01:37:45 +00:00
var filterValue = request . MinPlayers . Value ;
2013-12-02 02:24:14 +00:00
2014-10-08 01:37:45 +00:00
var game = i as Game ;
2013-12-02 02:24:14 +00:00
2014-10-08 01:37:45 +00:00
if ( game ! = null )
2014-10-06 23:58:46 +00:00
{
2014-10-08 01:37:45 +00:00
var players = game . PlayersSupported ? ? 1 ;
2013-12-02 02:24:14 +00:00
2014-10-08 01:37:45 +00:00
var ok = players > = filterValue ;
2013-12-02 02:24:14 +00:00
2014-10-08 01:37:45 +00:00
if ( ! ok )
{
return false ;
}
}
else
2014-10-06 23:58:46 +00:00
{
return false ;
}
2013-12-02 02:24:14 +00:00
}
2014-10-08 01:37:45 +00:00
if ( request . MaxPlayers . HasValue )
2014-03-04 04:53:48 +00:00
{
2014-10-08 01:37:45 +00:00
var filterValue = request . MaxPlayers . Value ;
2014-03-04 04:53:48 +00:00
2014-10-08 01:37:45 +00:00
var game = i as Game ;
2014-03-04 04:53:48 +00:00
2014-10-08 01:37:45 +00:00
if ( game ! = null )
2014-10-06 23:58:46 +00:00
{
2014-10-08 01:37:45 +00:00
var players = game . PlayersSupported ? ? 1 ;
2014-03-04 04:53:48 +00:00
2014-10-08 01:37:45 +00:00
var ok = players < = filterValue ;
2014-03-04 04:53:48 +00:00
2014-10-08 01:37:45 +00:00
if ( ! ok )
{
return false ;
}
2014-10-06 23:58:46 +00:00
}
2014-10-08 01:37:45 +00:00
else
2014-10-06 23:58:46 +00:00
{
return false ;
}
2014-03-04 04:53:48 +00:00
}
2014-10-08 01:37:45 +00:00
if ( request . ParentIndexNumber . HasValue )
2014-06-04 02:53:22 +00:00
{
2014-10-08 01:37:45 +00:00
var filterValue = request . ParentIndexNumber . Value ;
2014-10-06 23:58:46 +00:00
2014-10-08 01:37:45 +00:00
var episode = i as Episode ;
2013-12-02 02:24:14 +00:00
2014-10-08 01:37:45 +00:00
if ( episode ! = null )
2013-12-02 02:24:14 +00:00
{
2014-10-08 01:37:45 +00:00
if ( episode . ParentIndexNumber . HasValue & & episode . ParentIndexNumber . Value ! = filterValue )
2013-12-02 02:24:14 +00:00
{
2014-10-08 01:37:45 +00:00
return false ;
2013-12-02 02:24:14 +00:00
}
2014-10-08 01:37:45 +00:00
}
2013-12-02 02:24:14 +00:00
2014-10-08 01:37:45 +00:00
var song = i as Audio ;
if ( song ! = null )
{
if ( song . ParentIndexNumber . HasValue & & song . ParentIndexNumber . Value ! = filterValue )
2013-12-02 02:24:14 +00:00
{
2014-10-08 01:37:45 +00:00
return false ;
2013-12-02 02:24:14 +00:00
}
}
}
2014-10-08 01:37:45 +00:00
if ( request . AiredDuringSeason . HasValue )
2014-04-22 17:25:54 +00:00
{
2014-10-08 01:37:45 +00:00
var episode = i as Episode ;
2014-04-22 17:25:54 +00:00
2014-10-08 01:37:45 +00:00
if ( episode = = null )
{
return false ;
}
2014-04-22 17:25:54 +00:00
2014-10-08 01:37:45 +00:00
if ( ! Series . FilterEpisodesBySeason ( new [ ] { episode } , request . AiredDuringSeason . Value , true ) . Any ( ) )
{
return false ;
}
2014-04-22 17:25:54 +00:00
}
2014-10-08 01:37:45 +00:00
if ( ! string . IsNullOrEmpty ( request . MinPremiereDate ) )
2014-04-22 17:25:54 +00:00
{
2014-10-08 01:37:45 +00:00
var date = DateTime . Parse ( request . MinPremiereDate , null , DateTimeStyles . RoundtripKind ) . ToUniversalTime ( ) ;
2014-04-22 17:25:54 +00:00
2014-10-08 01:37:45 +00:00
if ( ! ( i . PremiereDate . HasValue & & i . PremiereDate . Value > = date ) )
{
return false ;
}
2014-04-22 17:25:54 +00:00
}
2014-10-08 01:37:45 +00:00
if ( ! string . IsNullOrEmpty ( request . MaxPremiereDate ) )
2014-04-22 17:25:54 +00:00
{
2014-10-08 01:37:45 +00:00
var date = DateTime . Parse ( request . MaxPremiereDate , null , DateTimeStyles . RoundtripKind ) . ToUniversalTime ( ) ;
2014-04-22 17:25:54 +00:00
2014-10-08 01:37:45 +00:00
if ( ! ( i . PremiereDate . HasValue & & i . PremiereDate . Value < = date ) )
{
return false ;
}
2014-04-22 17:25:54 +00:00
}
2014-04-27 03:42:05 +00:00
2014-03-15 04:14:07 +00:00
return true ;
}
2013-02-21 01:33:05 +00:00
/// <summary>
/// Applies the paging.
/// </summary>
/// <param name="request">The request.</param>
/// <param name="items">The items.</param>
/// <returns>IEnumerable{BaseItem}.</returns>
private IEnumerable < BaseItem > ApplyPaging ( GetItems request , IEnumerable < BaseItem > items )
{
// Start at
if ( request . StartIndex . HasValue )
{
items = items . Skip ( request . StartIndex . Value ) ;
}
// Return limit
if ( request . Limit . HasValue )
{
items = items . Take ( request . Limit . Value ) ;
}
return items ;
}
}
/// <summary>
/// Class DateCreatedComparer
/// </summary>
public class DateCreatedComparer : IComparer < BaseItem >
{
/// <summary>
/// Compares the specified x.
/// </summary>
/// <param name="x">The x.</param>
/// <param name="y">The y.</param>
/// <returns>System.Int32.</returns>
public int Compare ( BaseItem x , BaseItem y )
{
return x . DateCreated . CompareTo ( y . DateCreated ) ;
}
}
}