2014-04-22 17:25:54 +00:00
using MediaBrowser.Controller.Collections ;
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 ;
2013-12-02 02:24:14 +00:00
using MediaBrowser.Controller.Providers ;
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 ;
using System.IO ;
2013-02-21 01:33:05 +00:00
using System.Linq ;
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
/// <summary>
/// Limit results to items containing specific genres
/// </summary>
/// <value>The genres.</value>
2014-01-05 03:50:29 +00:00
[ApiMember(Name = "Genres", 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-02-21 01:33:05 +00:00
public string Genres { get ; set ; }
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-02-21 01:33:05 +00:00
/// <summary>
/// Limit results to items containing specific years
/// </summary>
/// <value>The years.</value>
2013-03-09 05:15:51 +00:00
[ApiMember(Name = "Years", Description = "Optional. If specified, results will be filtered based on production year. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
2013-02-21 01:33:05 +00:00
public string Years { get ; set ; }
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 ; }
2013-02-21 01:33:05 +00:00
}
/// <summary>
/// Class ItemsService
/// </summary>
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>
public object Get ( GetItems request )
{
2013-09-19 15:12:28 +00:00
var result = GetItems ( request ) ;
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>
2013-09-19 15:12:28 +00:00
private 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-04-27 03:42:05 +00:00
var items = GetItemsToSerialize ( request , user , parentItem ) ;
2013-02-21 01:33:05 +00:00
2013-04-05 15:58:06 +00:00
items = items . AsParallel ( ) ;
2013-05-19 17:35:00 +00:00
items = ApplyAdditionalFilters ( request , items , user ) ;
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
}
2013-10-26 22:01:21 +00:00
items = FilterVirtualEpisodes ( request , items , user ) ;
2013-04-05 15:58:06 +00:00
items = items . AsEnumerable ( ) ;
2014-04-29 03:56:20 +00:00
if ( CollapseBoxSetItems ( request , parentItem , user ) )
2014-03-15 04:14:07 +00:00
{
2014-04-22 17:25:54 +00:00
items = _collectionManager . CollapseItemsWithinBoxSets ( items , user ) ;
2014-03-15 04:14:07 +00:00
}
2013-04-11 19:36:50 +00:00
items = ApplySortOrder ( request , items , user , _libraryManager ) ;
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 ) )
{
items = FilterForAdjacency ( items , request . AdjacentTo ) ;
}
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
} ;
}
2014-04-29 03:56:20 +00:00
private bool CollapseBoxSetItems ( GetItems request , BaseItem parentItem , User user )
2014-03-18 17:05:57 +00:00
{
2014-04-27 03:42:05 +00:00
// Could end up stuck in a loop like this
if ( parentItem is BoxSet )
{
return false ;
}
2014-03-18 17:05:57 +00:00
var param = request . CollapseBoxSetItems ;
if ( ! param . HasValue )
{
2014-04-29 03:56:20 +00:00
if ( user ! = null & & ! user . Configuration . GroupMoviesIntoBoxSets )
{
return false ;
}
2014-03-18 17:05:57 +00:00
if ( ! string . IsNullOrWhiteSpace ( request . IncludeItemTypes ) & &
request . IncludeItemTypes . Split ( ',' ) . Contains ( "Movie" , StringComparer . OrdinalIgnoreCase ) )
{
param = true ;
}
}
return param . HasValue & & param . Value & & AllowBoxSetCollapsing ( request ) ;
}
2013-02-21 01:33:05 +00:00
/// <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>
/// <exception cref="System.InvalidOperationException"></exception>
2014-04-27 03:42:05 +00:00
private IEnumerable < BaseItem > 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-01-22 17:05:23 +00:00
items = user = = null ?
( ( Folder ) item ) . RecursiveChildren :
( ( Folder ) item ) . GetRecursiveChildren ( user ) ;
2014-03-19 04:59:45 +00:00
items = _libraryManager . ReplaceVideosWithPrimaryVersions ( items ) ;
2013-10-15 22:16:39 +00:00
}
else
{
2014-01-22 17:05:23 +00:00
items = user = = null ?
( ( Folder ) item ) . Children :
( ( Folder ) item ) . GetChildren ( user , true ) ;
2014-03-19 04:59:45 +00:00
items = _libraryManager . ReplaceVideosWithPrimaryVersions ( items ) ;
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 ) ;
return list . Distinct ( ) ;
2013-02-21 01:33:05 +00:00
}
2013-10-15 22:16:39 +00:00
return items ;
2013-02-21 01:33:05 +00:00
}
/// <summary>
/// Applies sort order
/// </summary>
/// <param name="request">The request.</param>
/// <param name="items">The items.</param>
/// <param name="user">The user.</param>
2013-04-11 19:36:50 +00:00
/// <param name="libraryManager">The library manager.</param>
2013-02-21 01:33:05 +00:00
/// <returns>IEnumerable{BaseItem}.</returns>
2013-09-10 19:57:38 +00:00
internal static IEnumerable < BaseItem > ApplySortOrder ( BaseItemsRequest request , IEnumerable < BaseItem > items , User user , ILibraryManager libraryManager )
2013-02-21 01:33:05 +00:00
{
2013-09-20 00:53:18 +00:00
var orderBy = request . GetOrderBy ( ) . ToList ( ) ;
2013-02-21 01:33:05 +00:00
2013-09-20 00:53:18 +00:00
return orderBy . Count = = 0 ? items : libraryManager . Sort ( items , user , orderBy , request . SortOrder ? ? SortOrder . Ascending ) ;
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 ;
}
2013-10-26 22:01:21 +00:00
private IEnumerable < BaseItem > FilterVirtualEpisodes ( GetItems request , IEnumerable < BaseItem > items , User user )
{
items = FilterVirtualSeasons ( request , items , user ) ;
if ( request . IsMissing . HasValue )
{
var val = request . IsMissing . Value ;
items = items . Where ( i = >
{
var e = i as Episode ;
if ( e ! = null )
{
return e . IsMissingEpisode = = val ;
}
return true ;
} ) ;
}
if ( request . IsUnaired . HasValue )
{
var val = request . IsUnaired . Value ;
items = items . Where ( i = >
{
var e = i as Episode ;
if ( e ! = null )
{
return e . IsUnaired = = val ;
}
return true ;
} ) ;
}
2013-10-26 22:40:53 +00:00
if ( request . IsVirtualUnaired . HasValue )
{
var val = request . IsVirtualUnaired . Value ;
items = items . Where ( i = >
{
var e = i as Episode ;
if ( e ! = null )
{
return e . IsVirtualUnaired = = val ;
}
return true ;
} ) ;
}
2013-10-26 22:01:21 +00:00
return items ;
}
private IEnumerable < BaseItem > FilterVirtualSeasons ( GetItems request , IEnumerable < BaseItem > items , User user )
{
2013-11-01 17:37:27 +00:00
if ( request . IsMissing . HasValue & & request . IsVirtualUnaired . HasValue )
2013-10-26 22:01:21 +00:00
{
var isMissing = request . IsMissing . Value ;
2013-11-01 17:37:27 +00:00
var isVirtualUnaired = request . IsVirtualUnaired . Value ;
2013-10-26 22:01:21 +00:00
2013-11-01 17:37:27 +00:00
if ( ! isMissing & & ! isVirtualUnaired )
2013-10-26 22:01:21 +00:00
{
return items . Where ( i = >
{
var e = i as Season ;
if ( e ! = null )
{
2013-10-26 22:40:53 +00:00
return ! e . IsMissingOrVirtualUnaired ;
2013-10-26 22:01:21 +00:00
}
return true ;
} ) ;
}
}
if ( request . IsMissing . HasValue )
{
var val = request . IsMissing . Value ;
items = items . Where ( i = >
{
var e = i as Season ;
if ( e ! = null )
{
return e . IsMissingSeason = = val ;
}
return true ;
} ) ;
}
if ( request . IsUnaired . HasValue )
{
var val = request . IsUnaired . Value ;
items = items . Where ( i = >
{
var e = i as Season ;
if ( e ! = null )
{
return e . IsUnaired = = val ;
}
return true ;
2013-10-26 22:40:53 +00:00
} ) ;
}
if ( request . IsVirtualUnaired . HasValue )
{
var val = request . IsVirtualUnaired . Value ;
items = items . Where ( i = >
{
var e = i as Season ;
if ( e ! = null )
{
return e . IsVirtualUnaired = = val ;
}
return true ;
2013-10-26 22:01:21 +00:00
} ) ;
}
return items ;
}
2013-02-21 01:33:05 +00:00
/// <summary>
/// Applies the additional filters.
/// </summary>
2013-04-13 18:02:30 +00:00
/// <param name="request">The request.</param>
2013-02-21 01:33:05 +00:00
/// <param name="items">The items.</param>
/// <returns>IEnumerable{BaseItem}.</returns>
2013-05-19 17:35:00 +00:00
private IEnumerable < BaseItem > ApplyAdditionalFilters ( GetItems request , IEnumerable < BaseItem > items , User user )
2013-02-21 01:33:05 +00:00
{
2013-11-03 16:19:33 +00:00
if ( request . MinCommunityRating . HasValue )
{
var val = request . MinCommunityRating . Value ;
items = items . Where ( i = > i . CommunityRating . HasValue & & i . CommunityRating > = val ) ;
}
if ( request . MinCriticRating . HasValue )
{
var val = request . MinCriticRating . Value ;
2013-11-06 16:06:16 +00:00
items = items . Where ( i = >
{
var hasCriticRating = i as IHasCriticRating ;
if ( hasCriticRating ! = null )
{
return hasCriticRating . CriticRating . HasValue & & hasCriticRating . CriticRating > = val ;
}
return false ;
} ) ;
2013-11-03 16:19:33 +00:00
}
2013-04-24 14:05:47 +00:00
// Artists
if ( ! string . IsNullOrEmpty ( request . Artists ) )
{
var artists = request . Artists . Split ( '|' ) ;
items = items . Where ( i = >
{
2013-09-10 18:56:00 +00:00
var audio = i as IHasArtist ;
2013-04-24 14:05:47 +00:00
2013-09-10 18:56:00 +00:00
return audio ! = null & & artists . Any ( audio . HasArtist ) ;
2013-04-24 14:05:47 +00:00
} ) ;
}
2013-08-08 12:19:11 +00:00
// Albums
if ( ! string . IsNullOrEmpty ( request . Albums ) )
{
var albums = request . Albums . Split ( '|' ) ;
items = items . Where ( i = >
{
var audio = i as Audio ;
if ( audio ! = null )
{
return albums . Any ( a = > string . Equals ( a , audio . Album , StringComparison . OrdinalIgnoreCase ) ) ;
}
var album = i as MusicAlbum ;
if ( album ! = null )
{
return albums . Any ( a = > string . Equals ( a , album . Name , StringComparison . OrdinalIgnoreCase ) ) ;
}
var musicVideo = i as MusicVideo ;
if ( musicVideo ! = null )
{
return albums . Any ( a = > string . Equals ( a , musicVideo . Album , StringComparison . OrdinalIgnoreCase ) ) ;
}
return false ;
} ) ;
}
2013-08-31 01:08:32 +00:00
// Min index number
if ( request . MinIndexNumber . HasValue )
{
items = items . Where ( i = > i . IndexNumber . HasValue & & i . IndexNumber . Value > = request . MinIndexNumber . Value ) ;
}
2013-04-14 00:17:25 +00:00
// Min official rating
2013-04-24 19:52:28 +00:00
if ( ! string . IsNullOrEmpty ( request . MinOfficialRating ) )
2013-04-14 00:17:25 +00:00
{
2013-06-10 17:46:11 +00:00
var level = _localization . GetRatingLevel ( request . MinOfficialRating ) ;
2013-04-14 00:17:25 +00:00
2013-06-10 17:46:11 +00:00
if ( level . HasValue )
{
items = items . Where ( i = >
{
2013-09-11 17:54:59 +00:00
var rating = i . CustomRating ;
if ( string . IsNullOrEmpty ( rating ) )
{
rating = i . OfficialRating ;
}
2013-06-10 17:46:11 +00:00
if ( string . IsNullOrEmpty ( rating ) )
{
return true ;
}
var itemLevel = _localization . GetRatingLevel ( rating ) ;
return ! itemLevel . HasValue | | itemLevel . Value > = level . Value ;
} ) ;
}
2013-04-14 00:17:25 +00:00
}
// Max official rating
2013-04-24 19:52:28 +00:00
if ( ! string . IsNullOrEmpty ( request . MaxOfficialRating ) )
2013-04-14 00:17:25 +00:00
{
2013-09-12 01:35:18 +00:00
var level = _localization . GetRatingLevel ( request . MaxOfficialRating ) ;
2013-04-14 00:17:25 +00:00
2013-06-10 17:46:11 +00:00
if ( level . HasValue )
{
items = items . Where ( i = >
{
2013-09-11 17:54:59 +00:00
var rating = i . CustomRating ;
if ( string . IsNullOrEmpty ( rating ) )
{
rating = i . OfficialRating ;
}
2013-06-10 17:46:11 +00:00
if ( string . IsNullOrEmpty ( rating ) )
{
return true ;
}
var itemLevel = _localization . GetRatingLevel ( rating ) ;
return ! itemLevel . HasValue | | itemLevel . Value < = level . Value ;
} ) ;
}
2013-04-14 00:17:25 +00:00
}
2013-04-13 19:47:41 +00:00
// Exclude item types
if ( ! string . IsNullOrEmpty ( request . ExcludeItemTypes ) )
{
var vals = request . ExcludeItemTypes . Split ( ',' ) ;
items = items . Where ( f = > ! vals . Contains ( f . GetType ( ) . Name , StringComparer . OrdinalIgnoreCase ) ) ;
}
// Include item types
if ( ! string . IsNullOrEmpty ( request . IncludeItemTypes ) )
{
var vals = request . IncludeItemTypes . Split ( ',' ) ;
items = items . Where ( f = > vals . Contains ( f . GetType ( ) . Name , StringComparer . OrdinalIgnoreCase ) ) ;
}
2013-05-16 19:00:42 +00:00
2013-10-16 23:35:11 +00:00
// LocationTypes
if ( ! string . IsNullOrEmpty ( request . LocationTypes ) )
{
var vals = request . LocationTypes . Split ( ',' ) ;
items = items . Where ( f = > vals . Contains ( f . LocationType . ToString ( ) , StringComparer . OrdinalIgnoreCase ) ) ;
}
2013-10-26 22:01:21 +00:00
// ExcludeLocationTypes
if ( ! string . IsNullOrEmpty ( request . ExcludeLocationTypes ) )
{
var vals = request . ExcludeLocationTypes . Split ( ',' ) ;
items = items . Where ( f = > ! vals . Contains ( f . LocationType . ToString ( ) , StringComparer . OrdinalIgnoreCase ) ) ;
}
2013-05-17 03:24:41 +00:00
if ( ! string . IsNullOrEmpty ( request . NameStartsWithOrGreater ) )
2013-05-16 19:00:42 +00:00
{
2013-05-17 18:05:49 +00:00
items = items . Where ( i = > string . Compare ( request . NameStartsWithOrGreater , i . SortName , StringComparison . CurrentCultureIgnoreCase ) < 1 ) ;
2013-05-16 19:00:42 +00:00
}
2014-03-05 21:46:32 +00:00
if ( ! string . IsNullOrEmpty ( request . NameStartsWith ) )
{
items = items . Where ( i = > string . Compare ( request . NameStartsWith , i . SortName . Substring ( 0 , 1 ) , StringComparison . CurrentCultureIgnoreCase ) = = 0 ) ;
}
2014-03-18 17:05:57 +00:00
2014-03-05 21:46:32 +00:00
if ( ! string . IsNullOrEmpty ( request . NameLessThan ) )
{
items = items . Where ( i = > string . Compare ( request . NameLessThan , i . SortName , StringComparison . CurrentCultureIgnoreCase ) = = 1 ) ;
}
2013-05-16 19:00:42 +00:00
2013-09-06 19:17:15 +00:00
if ( ! string . IsNullOrEmpty ( request . AlbumArtistStartsWithOrGreater ) )
{
items = items . OfType < IHasAlbumArtist > ( )
. Where ( i = > string . Compare ( request . AlbumArtistStartsWithOrGreater , i . AlbumArtist , StringComparison . CurrentCultureIgnoreCase ) < 1 )
. Cast < BaseItem > ( ) ;
}
2013-04-07 20:55:05 +00:00
// Filter by Series Status
if ( ! string . IsNullOrEmpty ( request . SeriesStatus ) )
{
var vals = request . SeriesStatus . Split ( ',' ) ;
items = items . OfType < Series > ( ) . Where ( i = > i . Status . HasValue & & vals . Contains ( i . Status . Value . ToString ( ) , StringComparer . OrdinalIgnoreCase ) ) ;
}
// Filter by Series AirDays
if ( ! string . IsNullOrEmpty ( request . AirDays ) )
{
var days = request . AirDays . Split ( ',' ) . Select ( d = > ( DayOfWeek ) Enum . Parse ( typeof ( DayOfWeek ) , d , true ) ) ;
items = items . OfType < Series > ( ) . Where ( i = > i . AirDays ! = null & & days . Any ( d = > i . AirDays . Contains ( d ) ) ) ;
}
2013-06-27 18:25:07 +00:00
// Filter by Video3DFormat
2013-06-25 18:10:39 +00:00
if ( request . Is3D . HasValue )
2013-04-04 15:22:39 +00:00
{
2013-06-25 18:10:39 +00:00
items = items . OfType < Video > ( ) . Where ( i = > request . Is3D . Value = = i . Video3DFormat . HasValue ) ;
2013-04-04 15:22:39 +00:00
}
2013-04-07 20:55:05 +00:00
// Filter by VideoType
2013-04-04 15:22:39 +00:00
if ( ! string . IsNullOrEmpty ( request . VideoTypes ) )
{
var types = request . VideoTypes . Split ( ',' ) ;
items = items . OfType < Video > ( ) . Where ( i = > types . Contains ( i . VideoType . ToString ( ) , StringComparer . OrdinalIgnoreCase ) ) ;
}
if ( ! string . IsNullOrEmpty ( request . MediaTypes ) )
{
var types = request . MediaTypes . Split ( ',' ) ;
items = items . Where ( i = > ! string . IsNullOrEmpty ( i . MediaType ) & & types . Contains ( i . MediaType , StringComparer . OrdinalIgnoreCase ) ) ;
}
2013-05-16 19:00:42 +00:00
2013-09-20 00:53:18 +00:00
var imageTypes = request . GetImageTypes ( ) . ToList ( ) ;
if ( imageTypes . Count > 0 )
2013-02-21 01:33:05 +00:00
{
items = items . Where ( item = > imageTypes . Any ( imageType = > HasImage ( item , imageType ) ) ) ;
}
// Apply genre filter
2013-09-22 17:00:42 +00:00
if ( ! string . IsNullOrEmpty ( request . Genres ) )
2013-02-21 01:33:05 +00:00
{
2014-01-05 03:50:29 +00:00
var vals = request . Genres . Split ( '|' ) ;
2013-09-22 17:00:42 +00:00
items = items . Where ( f = > vals . Any ( v = > f . Genres . Contains ( v , StringComparer . OrdinalIgnoreCase ) ) ) ;
2013-02-21 01:33:05 +00:00
}
2013-09-22 17:00:42 +00:00
// Apply genre filter
if ( ! string . IsNullOrEmpty ( request . AllGenres ) )
{
2014-01-05 03:50:29 +00:00
var vals = request . AllGenres . Split ( '|' ) ;
2013-09-22 17:00:42 +00:00
items = items . Where ( f = > vals . All ( v = > f . Genres . Contains ( v , StringComparer . OrdinalIgnoreCase ) ) ) ;
}
2013-10-16 23:35:11 +00:00
2013-02-21 01:33:05 +00:00
// Apply studio filter
2013-09-22 17:00:42 +00:00
if ( ! string . IsNullOrEmpty ( request . Studios ) )
2013-02-21 01:33:05 +00:00
{
2014-01-05 03:50:29 +00:00
var vals = request . Studios . Split ( '|' ) ;
2013-09-22 17:00:42 +00:00
items = items . Where ( f = > vals . Any ( v = > f . Studios . Contains ( v , StringComparer . OrdinalIgnoreCase ) ) ) ;
2013-02-21 01:33:05 +00:00
}
// Apply year filter
2013-09-22 17:00:42 +00:00
if ( ! string . IsNullOrEmpty ( request . Years ) )
2013-02-21 01:33:05 +00:00
{
2013-09-22 17:00:42 +00:00
var vals = request . Years . Split ( ',' ) . Select ( int . Parse ) . ToList ( ) ;
2013-02-21 01:33:05 +00:00
items = items . Where ( f = > f . ProductionYear . HasValue & & vals . Contains ( f . ProductionYear . Value ) ) ;
}
// Apply person filter
2013-09-22 17:00:42 +00:00
if ( ! string . IsNullOrEmpty ( request . Person ) )
2013-02-21 01:33:05 +00:00
{
2013-04-13 23:43:41 +00:00
var personTypes = request . PersonTypes ;
if ( string . IsNullOrEmpty ( personTypes ) )
{
2013-10-15 22:16:39 +00:00
items = items . Where ( item = > item . People . Any ( p = > string . Equals ( p . Name , request . Person , StringComparison . OrdinalIgnoreCase ) ) ) ;
2013-04-13 23:43:41 +00:00
}
else
{
var types = personTypes . Split ( ',' ) ;
items = items . Where ( item = >
item . People ! = null & &
item . People . Any ( p = >
2013-09-22 17:00:42 +00:00
p . Name . Equals ( request . Person , StringComparison . OrdinalIgnoreCase ) & & ( types . Contains ( p . Type , StringComparer . OrdinalIgnoreCase ) | | types . Contains ( p . Role , StringComparer . OrdinalIgnoreCase ) ) ) ) ;
2013-04-13 23:43:41 +00:00
}
2013-02-21 01:33:05 +00:00
}
2013-04-30 01:29:04 +00:00
if ( request . HasTrailer . HasValue )
{
2013-12-02 16:46:25 +00:00
var val = request . HasTrailer . Value ;
items = items . Where ( i = >
{
var trailerCount = 0 ;
var hasTrailers = i as IHasTrailers ;
if ( hasTrailers ! = null )
{
trailerCount = hasTrailers . LocalTrailerIds . Count ;
}
return val ? trailerCount > 0 : trailerCount = = 0 ;
} ) ;
2013-04-30 01:29:04 +00:00
}
if ( request . HasThemeSong . HasValue )
{
2013-12-05 16:50:21 +00:00
var filterValue = request . HasThemeSong . Value ;
items = items . Where ( i = >
{
var themeCount = 0 ;
var iHasThemeMedia = i as IHasThemeMedia ;
if ( iHasThemeMedia ! = null )
{
themeCount = iHasThemeMedia . ThemeSongIds . Count ;
}
return filterValue ? themeCount > 0 : themeCount = = 0 ;
} ) ;
2013-04-30 01:29:04 +00:00
}
if ( request . HasThemeVideo . HasValue )
{
2013-12-05 16:50:21 +00:00
var filterValue = request . HasThemeVideo . Value ;
items = items . Where ( i = >
{
var themeCount = 0 ;
var iHasThemeMedia = i as IHasThemeMedia ;
if ( iHasThemeMedia ! = null )
{
themeCount = iHasThemeMedia . ThemeVideoIds . Count ;
}
return filterValue ? themeCount > 0 : themeCount = = 0 ;
} ) ;
2013-04-30 01:29:04 +00:00
}
2013-09-15 19:33:23 +00:00
if ( request . MinPlayers . HasValue )
{
var filterValue = request . MinPlayers . Value ;
items = items . Where ( i = >
{
var game = i as Game ;
if ( game ! = null )
{
var players = game . PlayersSupported ? ? 1 ;
return players > = filterValue ;
}
return false ;
} ) ;
}
2013-10-06 03:03:08 +00:00
if ( request . MaxPlayers . HasValue )
{
var filterValue = request . MaxPlayers . Value ;
items = items . Where ( i = >
{
var game = i as Game ;
if ( game ! = null )
{
var players = game . PlayersSupported ? ? 1 ;
return players < = filterValue ;
}
return false ;
} ) ;
}
2013-04-30 01:29:04 +00:00
if ( request . HasSpecialFeature . HasValue )
{
2013-09-13 18:43:27 +00:00
var filterValue = request . HasSpecialFeature . Value ;
items = items . Where ( i = >
{
var movie = i as Movie ;
if ( movie ! = null )
{
return filterValue
? movie . SpecialFeatureIds . Count > 0
: movie . SpecialFeatureIds . Count = = 0 ;
}
var series = i as Series ;
if ( series ! = null )
{
return filterValue
? series . SpecialFeatureIds . Count > 0
: series . SpecialFeatureIds . Count = = 0 ;
}
return false ;
} ) ;
2013-04-30 01:29:04 +00:00
}
if ( request . HasSubtitles . HasValue )
{
2013-12-06 03:39:44 +00:00
var val = request . HasSubtitles . Value ;
2013-05-08 20:58:52 +00:00
2013-12-06 03:39:44 +00:00
items = items . OfType < Video > ( ) . Where ( i = > val = = i . HasSubtitles ) ;
2013-04-30 01:29:04 +00:00
}
2013-09-11 17:54:59 +00:00
if ( request . HasParentalRating . HasValue )
{
2014-01-19 19:25:29 +00:00
var val = request . HasParentalRating . Value ;
2013-09-11 17:54:59 +00:00
items = items . Where ( i = >
{
var rating = i . CustomRating ;
if ( string . IsNullOrEmpty ( rating ) )
{
rating = i . OfficialRating ;
}
2014-01-19 19:25:29 +00:00
if ( val )
2013-09-11 17:54:59 +00:00
{
return ! string . IsNullOrEmpty ( rating ) ;
}
return string . IsNullOrEmpty ( rating ) ;
} ) ;
}
if ( request . IsHD . HasValue )
{
2013-10-26 22:01:21 +00:00
var val = request . IsHD . Value ;
items = items . OfType < Video > ( ) . Where ( i = > i . IsHD = = val ) ;
2013-09-11 17:54:59 +00:00
}
2014-01-19 19:25:29 +00:00
if ( request . IsInBoxSet . HasValue )
{
var val = request . IsHD . Value ;
items = items . Where ( i = > i . Parents . OfType < BoxSet > ( ) . Any ( ) = = val ) ;
}
if ( request . IsPlayed . HasValue )
{
var val = request . IsPlayed . Value ;
items = items . Where ( i = > i . IsPlayed ( user ) = = val ) ;
}
2014-03-03 05:11:03 +00:00
if ( request . IsUnidentified . HasValue )
{
var val = request . IsUnidentified . Value ;
items = items . Where ( i = > i . IsUnidentified = = val ) ;
}
if ( request . IsLocked . HasValue )
{
var val = request . IsLocked . Value ;
items = items . Where ( i = > i . IsLocked = = val ) ;
}
2013-09-13 20:45:27 +00:00
if ( request . ParentIndexNumber . HasValue )
{
var filterValue = request . ParentIndexNumber . Value ;
items = items . Where ( i = >
{
var episode = i as Episode ;
if ( episode ! = null )
{
return episode . ParentIndexNumber . HasValue & & episode . ParentIndexNumber . Value = = filterValue ;
}
var song = i as Audio ;
if ( song ! = null )
{
return song . ParentIndexNumber . HasValue & & song . ParentIndexNumber . Value = = filterValue ;
}
2013-10-16 23:35:11 +00:00
2013-09-13 20:45:27 +00:00
return true ;
} ) ;
}
2013-11-15 21:31:33 +00:00
if ( request . AiredDuringSeason . HasValue )
{
2013-12-10 20:42:42 +00:00
items = Series . FilterEpisodesBySeason ( items . OfType < Episode > ( ) , request . AiredDuringSeason . Value , true ) ;
2013-11-15 21:31:33 +00:00
}
2013-11-19 17:17:14 +00:00
if ( ! string . IsNullOrEmpty ( request . MinPremiereDate ) )
{
2014-01-07 18:39:35 +00:00
var date = DateTime . Parse ( request . MinPremiereDate , null , DateTimeStyles . RoundtripKind ) . ToUniversalTime ( ) ;
2013-11-19 17:17:14 +00:00
items = items . Where ( i = > i . PremiereDate . HasValue & & i . PremiereDate . Value > = date ) ;
}
if ( ! string . IsNullOrEmpty ( request . MaxPremiereDate ) )
{
2014-01-07 18:39:35 +00:00
var date = DateTime . Parse ( request . MaxPremiereDate , null , DateTimeStyles . RoundtripKind ) . ToUniversalTime ( ) ;
2013-11-19 17:17:14 +00:00
items = items . Where ( i = > i . PremiereDate . HasValue & & i . PremiereDate . Value < = date ) ;
}
2013-12-02 02:24:14 +00:00
if ( request . HasOverview . HasValue )
{
var filterValue = request . HasOverview . Value ;
items = items . Where ( i = >
{
var hasValue = ! string . IsNullOrEmpty ( i . Overview ) ;
return hasValue = = filterValue ;
} ) ;
}
if ( request . HasImdbId . HasValue )
{
var filterValue = request . HasImdbId . Value ;
items = items . Where ( i = >
{
var hasValue = ! string . IsNullOrEmpty ( i . GetProviderId ( MetadataProviders . Imdb ) ) ;
return hasValue = = filterValue ;
} ) ;
}
if ( request . HasTmdbId . HasValue )
{
var filterValue = request . HasTmdbId . Value ;
items = items . Where ( i = >
{
var hasValue = ! string . IsNullOrEmpty ( i . GetProviderId ( MetadataProviders . Tmdb ) ) ;
return hasValue = = filterValue ;
} ) ;
}
if ( request . HasTvdbId . HasValue )
{
var filterValue = request . HasTvdbId . Value ;
items = items . Where ( i = >
{
var hasValue = ! string . IsNullOrEmpty ( i . GetProviderId ( MetadataProviders . Tvdb ) ) ;
return hasValue = = filterValue ;
} ) ;
}
if ( request . IsYearMismatched . HasValue )
{
var filterValue = request . IsYearMismatched . Value ;
items = items . Where ( i = > IsYearMismatched ( i ) = = filterValue ) ;
}
2014-03-04 04:53:48 +00:00
if ( request . HasOfficialRating . HasValue )
{
var filterValue = request . HasOfficialRating . Value ;
items = items . Where ( i = >
{
var hasValue = ! string . IsNullOrEmpty ( i . OfficialRating ) ;
return hasValue = = filterValue ;
} ) ;
}
if ( request . IsPlaceHolder . HasValue )
{
var filterValue = request . IsPlaceHolder . Value ;
items = items . Where ( i = >
{
var isPlaceHolder = false ;
var hasPlaceHolder = i as ISupportsPlaceHolders ;
if ( hasPlaceHolder ! = null )
{
isPlaceHolder = hasPlaceHolder . IsPlaceHolder ;
}
return isPlaceHolder = = filterValue ;
} ) ;
}
2013-02-21 01:33:05 +00:00
return items ;
}
2013-12-02 02:24:14 +00:00
private bool IsYearMismatched ( BaseItem item )
{
if ( item . ProductionYear . HasValue )
{
var path = item . Path ;
if ( ! string . IsNullOrEmpty ( path ) )
{
int? yearInName ;
string name ;
NameParser . ParseName ( Path . GetFileName ( path ) , out name , out yearInName ) ;
// Go up a level if we didn't get a year
if ( ! yearInName . HasValue )
{
NameParser . ParseName ( Path . GetFileName ( Path . GetDirectoryName ( path ) ) , out name , out yearInName ) ;
}
if ( yearInName . HasValue )
{
return yearInName . Value ! = item . ProductionYear . Value ;
}
}
}
return false ;
}
2014-04-22 17:25:54 +00:00
private bool AllowBoxSetCollapsing ( GetItems request )
2014-03-15 04:14:07 +00:00
{
2014-04-22 17:25:54 +00:00
if ( ! string . IsNullOrWhiteSpace ( request . Filters ) )
{
return false ;
}
2014-03-15 04:14:07 +00:00
2014-04-22 17:25:54 +00:00
if ( ! string . IsNullOrWhiteSpace ( request . AllGenres ) )
{
return false ;
}
2014-03-15 04:14:07 +00:00
2014-04-22 17:25:54 +00:00
if ( ! string . IsNullOrWhiteSpace ( request . Genres ) )
2014-03-15 04:14:07 +00:00
{
2014-04-22 17:25:54 +00:00
return false ;
}
2014-03-15 04:14:07 +00:00
2014-04-22 17:25:54 +00:00
if ( request . HasImdbId . HasValue )
{
return false ;
2014-03-15 04:14:07 +00:00
}
2014-04-22 17:25:54 +00:00
if ( request . HasOfficialRating . HasValue )
{
return false ;
}
2014-03-15 04:14:07 +00:00
2014-04-22 17:25:54 +00:00
if ( request . HasOverview . HasValue )
2014-03-15 04:14:07 +00:00
{
return false ;
}
2014-04-22 17:25:54 +00:00
if ( request . HasParentalRating . HasValue )
{
return false ;
}
if ( request . HasSpecialFeature . HasValue )
{
return false ;
}
if ( request . HasSubtitles . HasValue )
{
return false ;
}
if ( request . HasThemeSong . HasValue )
{
return false ;
}
if ( request . HasThemeVideo . HasValue )
{
return false ;
}
if ( request . HasTmdbId . HasValue )
{
return false ;
}
if ( request . HasTrailer . HasValue )
{
return false ;
}
if ( ! string . IsNullOrWhiteSpace ( request . Ids ) )
{
return false ;
}
if ( ! string . IsNullOrWhiteSpace ( request . ImageTypes ) )
{
return false ;
}
if ( request . Is3D . HasValue )
{
return false ;
}
if ( request . IsHD . HasValue )
{
return false ;
}
if ( request . IsInBoxSet . HasValue )
{
return false ;
}
if ( request . IsLocked . HasValue )
{
return false ;
}
if ( request . IsPlaceHolder . HasValue )
{
return false ;
}
if ( request . IsPlayed . HasValue )
{
return false ;
}
if ( request . IsUnidentified . HasValue )
{
return false ;
}
if ( request . IsYearMismatched . HasValue )
{
return false ;
}
if ( ! string . IsNullOrWhiteSpace ( request . Person ) )
{
return false ;
}
if ( ! string . IsNullOrWhiteSpace ( request . Studios ) )
{
return false ;
}
if ( ! string . IsNullOrWhiteSpace ( request . VideoTypes ) )
{
return false ;
}
if ( ! string . IsNullOrWhiteSpace ( request . Years ) )
{
return false ;
}
2014-04-27 03:42:05 +00:00
2014-03-15 04:14:07 +00:00
return true ;
}
2013-12-04 04:18:50 +00:00
internal static IEnumerable < BaseItem > FilterForAdjacency ( IEnumerable < BaseItem > items , string adjacentToId )
{
var list = items . ToList ( ) ;
var adjacentToIdGuid = new Guid ( adjacentToId ) ;
var adjacentToItem = list . FirstOrDefault ( i = > i . Id = = adjacentToIdGuid ) ;
var index = list . IndexOf ( adjacentToItem ) ;
var previousId = Guid . Empty ;
var nextId = Guid . Empty ;
if ( index > 0 )
{
previousId = list [ index - 1 ] . Id ;
}
if ( index < list . Count - 1 )
{
nextId = list [ index + 1 ] . Id ;
}
return list . Where ( i = > i . Id = = previousId | | i . Id = = nextId ) ;
}
2013-02-21 01:33:05 +00:00
/// <summary>
/// Determines whether the specified item has image.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="imageType">Type of the image.</param>
/// <returns><c>true</c> if the specified item has image; otherwise, <c>false</c>.</returns>
2013-09-06 05:13:43 +00:00
internal static bool HasImage ( BaseItem item , ImageType imageType )
2013-02-21 01:33:05 +00:00
{
return item . HasImage ( imageType ) ;
}
/// <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 ) ;
}
}
}