2013-04-13 18:02:30 +00:00
using MediaBrowser.Controller.Dto ;
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-04-13 18:02:30 +00:00
using MediaBrowser.Controller.Persistence ;
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-02-21 01:33:05 +00:00
using ServiceStack.ServiceHost ;
using System ;
using System.Collections.Generic ;
using System.Linq ;
using System.Threading.Tasks ;
namespace MediaBrowser.Api.UserLibrary
{
/// <summary>
/// Class GetItems
/// </summary>
[Route("/Users/{UserId}/Items", "GET")]
2013-03-24 02:45:00 +00:00
[Api(Description = "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>
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public Guid UserId { get ; set ; }
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 ; }
2013-04-12 03:50:47 +00:00
/// <summary>
/// What to sort the results by
/// </summary>
/// <value>The sort by.</value>
2013-05-06 02:23:19 +00:00
[ApiMember(Name = "SortBy", Description = "Optional. Specify one or more sort orders, comma delimeted. Options: Album, AlbumArtist, Artist, Budget, CommunityRating, CriticRating, DateCreated, DatePlayed, PlayCount, PremiereDate, ProductionYear, SortName, Random, Revenue, Runtime", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
2013-04-12 03:50:47 +00:00
public string SortBy { get ; set ; }
2013-02-21 01:33:05 +00:00
/// <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>
/// Search characters used to find items
/// </summary>
/// <value>The index by.</value>
2013-03-09 05:15:51 +00:00
[ApiMember(Name = "SearchTerm", Description = "Optional. If specified, results will be filtered based on a search term.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
2013-02-21 01:33:05 +00:00
public string SearchTerm { get ; set ; }
/// <summary>
/// The dynamic, localized index function name
/// </summary>
/// <value>The index by.</value>
public string IndexBy { get ; set ; }
/// <summary>
/// Limit results to items containing specific genres
/// </summary>
/// <value>The genres.</value>
2013-03-09 05:15:51 +00:00
[ApiMember(Name = "Genres", Description = "Optional. If specified, results will be filtered based on genre. 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 Genres { get ; set ; }
/// <summary>
/// Limit results to items containing specific studios
/// </summary>
/// <value>The studios.</value>
2013-03-09 05:15:51 +00:00
[ApiMember(Name = "Studios", Description = "Optional. If specified, results will be filtered based on studio. 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 Studios { get ; set ; }
2013-04-24 14:05:47 +00:00
/// <summary>
/// Gets or sets the studios.
/// </summary>
/// <value>The studios.</value>
[ApiMember(Name = "Artists", 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)]
public string Artists { get ; set ; }
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 ; }
/// <summary>
/// Gets or sets the image types.
/// </summary>
/// <value>The image types.</value>
2013-04-24 14:05:47 +00:00
[ApiMember(Name = "ImageTypes", Description = "Optional. If specified, results will be filtered based on those containing image types. This allows multiple, comma delimited.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
2013-02-21 01:33:05 +00:00
public string ImageTypes { 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>
[ApiMember(Name = "VideoFormats", Description = "Optional filter by VideoFormat (Standard, Digital3D, Sbs3D). Allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string VideoFormats { 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 ; }
2013-05-16 19:00:42 +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-04-12 03:50:47 +00:00
/// <summary>
/// Gets the order by.
/// </summary>
/// <returns>IEnumerable{ItemSortBy}.</returns>
public IEnumerable < string > GetOrderBy ( )
{
var val = SortBy ;
if ( string . IsNullOrEmpty ( val ) )
{
return new string [ ] { } ;
}
return val . Split ( ',' ) ;
}
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-04-13 18:02:30 +00:00
private readonly IUserDataRepository _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-03-28 22:00:58 +00:00
private readonly ILibrarySearchEngine _searchEngine ;
2013-06-10 17:46:11 +00:00
private readonly ILocalizationManager _localization ;
2013-03-09 05:15:51 +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>
/// <param name="searchEngine">The search engine.</param>
2013-04-13 18:02:30 +00:00
/// <param name="userDataRepository">The user data repository.</param>
2013-06-13 18:17:59 +00:00
public ItemsService ( IUserManager userManager , ILibraryManager libraryManager , ILibrarySearchEngine searchEngine , IUserDataRepository userDataRepository , ILocalizationManager localization )
2013-02-27 20:25:45 +00:00
{
_userManager = userManager ;
2013-02-28 19:32:41 +00:00
_libraryManager = libraryManager ;
2013-03-28 22:00:58 +00:00
_searchEngine = searchEngine ;
2013-04-13 18:02:30 +00:00
_userDataRepository = userDataRepository ;
2013-06-13 18:17:59 +00:00
_localization = localization ;
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 )
{
var result = GetItems ( request ) . Result ;
return ToOptimizedResult ( result ) ;
}
/// <summary>
/// Gets the items.
/// </summary>
/// <param name="request">The request.</param>
/// <returns>Task{ItemsResult}.</returns>
private async Task < ItemsResult > GetItems ( GetItems request )
{
2013-02-27 20:25:45 +00:00
var user = _userManager . GetUserById ( request . UserId ) ;
2013-02-21 01:33:05 +00:00
var items = GetItemsToSerialize ( request , user ) ;
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-04-05 15:58:06 +00:00
items = items . AsEnumerable ( ) ;
2013-02-21 01:33:05 +00:00
items = ApplySearchTerm ( request , items ) ;
2013-04-11 19:36:50 +00:00
items = ApplySortOrder ( request , items , user , _libraryManager ) ;
2013-02-21 01:33:05 +00:00
var itemsArray = items . ToArray ( ) ;
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-04-13 18:02:30 +00:00
var dtoBuilder = new DtoBuilder ( Logger , _libraryManager , _userDataRepository ) ;
2013-02-22 01:26:35 +00:00
2013-05-15 16:56:38 +00:00
var returnItems = await Task . WhenAll ( pagedItems . Select ( i = > dtoBuilder . GetBaseItemDto ( i , fields , user ) ) ) . ConfigureAwait ( false ) ;
2013-02-21 01:33:05 +00:00
return new ItemsResult
{
TotalRecordCount = itemsArray . Length ,
Items = returnItems
} ;
}
/// <summary>
/// Gets the items to serialize.
/// </summary>
/// <param name="request">The request.</param>
/// <param name="user">The user.</param>
/// <returns>IEnumerable{BaseItem}.</returns>
/// <exception cref="System.InvalidOperationException"></exception>
private IEnumerable < BaseItem > GetItemsToSerialize ( GetItems request , User user )
{
2013-02-28 19:32:41 +00:00
var item = string . IsNullOrEmpty ( request . ParentId ) ? user . RootFolder : DtoBuilder . GetItemByClientId ( request . ParentId , _userManager , _libraryManager , user . Id ) ;
2013-02-21 01:33:05 +00:00
// Default list type = children
2013-03-16 01:40:34 +00:00
if ( ! string . IsNullOrEmpty ( request . Ids ) )
{
var idList = request . Ids . Split ( ',' ) . ToList ( ) ;
return idList . Select ( i = > DtoBuilder . GetItemByClientId ( i , _userManager , _libraryManager , user . Id ) ) ;
}
2013-02-21 01:33:05 +00:00
if ( request . Recursive )
{
return ( ( Folder ) item ) . GetRecursiveChildren ( user ) ;
}
2013-03-10 04:22:36 +00:00
return ( ( Folder ) item ) . GetChildren ( user , request . IndexBy ) ;
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-04-12 03:50:47 +00:00
internal static IEnumerable < BaseItem > ApplySortOrder ( GetItems request , IEnumerable < BaseItem > items , User user , ILibraryManager libraryManager )
2013-02-21 01:33:05 +00:00
{
2013-04-11 19:36:50 +00:00
var orderBy = request . GetOrderBy ( ) . ToArray ( ) ;
2013-02-21 01:33:05 +00:00
2013-04-11 19:36:50 +00:00
return orderBy . Length = = 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-04-13 18:02:30 +00:00
internal static IEnumerable < BaseItem > ApplyFilter ( IEnumerable < BaseItem > items , ItemFilter filter , User user , IUserDataRepository repository )
2013-02-21 01:33:05 +00:00
{
switch ( filter )
{
2013-03-30 14:57:30 +00:00
case ItemFilter . Likes :
return items . Where ( item = >
{
2013-04-13 18:02:30 +00:00
var userdata = repository . GetUserData ( user . Id , item . GetUserDataKey ( ) ) . Result ;
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-04-13 18:02:30 +00:00
var userdata = repository . GetUserData ( user . Id , item . GetUserDataKey ( ) ) . Result ;
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-04-13 18:02:30 +00:00
var userdata = repository . GetUserData ( user . Id , item . GetUserDataKey ( ) ) . Result ;
2013-02-21 01:33:05 +00:00
return userdata ! = null & & userdata . IsFavorite ;
} ) ;
case ItemFilter . IsRecentlyAdded :
2013-04-22 04:38:03 +00:00
return items . Where ( item = > item . IsRecentlyAdded ( ) ) ;
2013-02-21 01:33:05 +00:00
case ItemFilter . IsResumable :
return items . Where ( item = >
{
2013-04-13 18:02:30 +00:00
var userdata = repository . GetUserData ( user . Id , item . GetUserDataKey ( ) ) . Result ;
2013-02-21 01:33:05 +00:00
return userdata ! = null & & userdata . PlaybackPositionTicks > 0 ;
} ) ;
case ItemFilter . IsPlayed :
return items . Where ( item = >
{
2013-04-13 18:02:30 +00:00
var userdata = repository . GetUserData ( user . Id , item . GetUserDataKey ( ) ) . Result ;
2013-02-21 01:33:05 +00:00
2013-05-10 16:57:51 +00:00
return userdata ! = null & & userdata . Played ;
2013-02-21 01:33:05 +00:00
} ) ;
case ItemFilter . IsUnplayed :
return items . Where ( item = >
{
2013-04-13 18:02:30 +00:00
var userdata = repository . GetUserData ( user . Id , item . GetUserDataKey ( ) ) . Result ;
2013-02-21 01:33:05 +00:00
2013-05-10 16:57:51 +00:00
return userdata = = null | | ! userdata . Played ;
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 ) ;
}
return items ;
}
/// <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-04-24 14:05:47 +00:00
// Artists
if ( ! string . IsNullOrEmpty ( request . Artists ) )
{
var artists = request . Artists . Split ( '|' ) ;
items = items . Where ( i = >
{
var audio = i as Audio ;
if ( audio ! = null )
{
return artists . Any ( audio . HasArtist ) ;
}
var album = i as MusicAlbum ;
if ( album ! = null )
{
return artists . Any ( album . HasArtist ) ;
}
return false ;
} ) ;
}
2013-05-19 17:35:00 +00:00
if ( ! string . IsNullOrEmpty ( request . AdjacentTo ) )
{
var item = DtoBuilder . GetItemByClientId ( request . AdjacentTo , _userManager , _libraryManager ) ;
var allSiblings = item . Parent . GetChildren ( user ) . OrderBy ( i = > i . SortName ) . ToList ( ) ;
var index = allSiblings . IndexOf ( item ) ;
var previousId = Guid . Empty ;
var nextId = Guid . Empty ;
if ( index > 0 )
{
previousId = allSiblings [ index - 1 ] . Id ;
}
if ( index < allSiblings . Count - 1 )
{
nextId = allSiblings [ index + 1 ] . Id ;
}
items = items . Where ( i = > i . Id = = previousId | | i . Id = = nextId ) ;
}
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 = >
{
var rating = i . CustomRating ? ? i . OfficialRating ;
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-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 = >
{
var rating = i . CustomRating ? ? i . OfficialRating ;
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-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
}
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 ) ) ) ;
}
// Filter by VideoFormat
2013-04-04 15:22:39 +00:00
if ( ! string . IsNullOrEmpty ( request . VideoFormats ) )
{
var formats = request . VideoFormats . Split ( ',' ) ;
items = items . OfType < Video > ( ) . Where ( i = > formats . Contains ( i . VideoFormat . ToString ( ) , StringComparer . OrdinalIgnoreCase ) ) ;
}
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-02-21 01:33:05 +00:00
var imageTypes = GetImageTypes ( request ) . ToArray ( ) ;
if ( imageTypes . Length > 0 )
{
items = items . Where ( item = > imageTypes . Any ( imageType = > HasImage ( item , imageType ) ) ) ;
}
var genres = request . Genres ;
// Apply genre filter
if ( ! string . IsNullOrEmpty ( genres ) )
{
var vals = genres . Split ( ',' ) ;
items = items . Where ( f = > f . Genres ! = null & & vals . Any ( v = > f . Genres . Contains ( v , StringComparer . OrdinalIgnoreCase ) ) ) ;
}
var studios = request . Studios ;
// Apply studio filter
if ( ! string . IsNullOrEmpty ( studios ) )
{
var vals = studios . Split ( ',' ) ;
items = items . Where ( f = > f . Studios ! = null & & vals . Any ( v = > f . Studios . Contains ( v , StringComparer . OrdinalIgnoreCase ) ) ) ;
}
var years = request . Years ;
// Apply year filter
if ( ! string . IsNullOrEmpty ( years ) )
{
var vals = years . Split ( ',' ) . Select ( int . Parse ) ;
items = items . Where ( f = > f . ProductionYear . HasValue & & vals . Contains ( f . ProductionYear . Value ) ) ;
}
var personName = request . Person ;
// Apply person filter
if ( ! string . IsNullOrEmpty ( personName ) )
{
2013-04-13 23:43:41 +00:00
var personTypes = request . PersonTypes ;
if ( string . IsNullOrEmpty ( personTypes ) )
{
items = items . Where ( item = > item . People ! = null & & item . People . Any ( p = > string . Equals ( p . Name , personName , StringComparison . OrdinalIgnoreCase ) ) ) ;
}
else
{
var types = personTypes . Split ( ',' ) ;
items = items . Where ( item = >
item . People ! = null & &
item . People . Any ( p = >
p . Name . Equals ( personName , StringComparison . OrdinalIgnoreCase ) & & types . Contains ( p . Type , StringComparer . OrdinalIgnoreCase ) ) ) ;
}
2013-02-21 01:33:05 +00:00
}
2013-04-30 01:29:04 +00:00
if ( request . HasTrailer . HasValue )
{
2013-05-08 20:58:52 +00:00
items = items . Where ( i = > request . HasTrailer . Value ? i . LocalTrailerIds . Count > 0 : i . LocalTrailerIds . Count = = 0 ) ;
2013-04-30 01:29:04 +00:00
}
if ( request . HasThemeSong . HasValue )
{
2013-05-08 20:58:52 +00:00
items = items . Where ( i = > request . HasThemeSong . Value ? i . ThemeSongIds . Count > 0 : i . ThemeSongIds . Count = = 0 ) ;
2013-04-30 01:29:04 +00:00
}
if ( request . HasThemeVideo . HasValue )
{
2013-05-08 20:58:52 +00:00
items = items . Where ( i = > request . HasThemeVideo . Value ? i . ThemeVideoIds . Count > 0 : i . ThemeVideoIds . Count = = 0 ) ;
2013-04-30 01:29:04 +00:00
}
if ( request . HasSpecialFeature . HasValue )
{
2013-05-08 20:58:52 +00:00
items = items . OfType < Movie > ( ) . Where ( i = > request . HasSpecialFeature . Value ? i . SpecialFeatureIds . Count > 0 : i . SpecialFeatureIds . Count = = 0 ) ;
2013-04-30 01:29:04 +00:00
}
if ( request . HasSubtitles . HasValue )
{
items = items . OfType < Video > ( ) . Where ( i = >
{
if ( request . HasSubtitles . Value )
{
return i . MediaStreams ! = null & & i . MediaStreams . Any ( m = > m . Type = = MediaStreamType . Subtitle ) ;
}
2013-05-08 20:58:52 +00:00
return i . MediaStreams = = null | | i . MediaStreams . All ( m = > m . Type ! = MediaStreamType . Subtitle ) ;
2013-04-30 01:29:04 +00:00
} ) ;
}
2013-02-21 01:33:05 +00:00
return items ;
}
/// <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-04-11 19:36:50 +00:00
private static bool HasImage ( BaseItem item , ImageType imageType )
2013-02-21 01:33:05 +00:00
{
if ( imageType = = ImageType . Backdrop )
{
return item . BackdropImagePaths ! = null & & item . BackdropImagePaths . Count > 0 ;
}
if ( imageType = = ImageType . Screenshot )
{
return item . ScreenshotImagePaths ! = null & & item . ScreenshotImagePaths . Count > 0 ;
}
2013-03-10 01:18:29 +00:00
if ( imageType = = ImageType . Chapter )
2013-02-21 01:33:05 +00:00
{
var video = item as Video ;
if ( video ! = null )
{
return video . Chapters ! = null & & video . Chapters . Any ( c = > ! string . IsNullOrEmpty ( c . ImagePath ) ) ;
}
return false ;
}
return item . HasImage ( imageType ) ;
}
/// <summary>
/// Applies the search term.
/// </summary>
/// <param name="request">The request.</param>
/// <param name="items">The items.</param>
/// <returns>IEnumerable{BaseItem}.</returns>
private IEnumerable < BaseItem > ApplySearchTerm ( GetItems request , IEnumerable < BaseItem > items )
{
var term = request . SearchTerm ;
if ( ! string . IsNullOrEmpty ( term ) )
{
2013-03-28 22:00:58 +00:00
items = _searchEngine . Search ( items , request . SearchTerm ) ;
2013-02-21 01:33:05 +00:00
}
return items ;
}
/// <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>
/// Gets the image types.
/// </summary>
/// <param name="request">The request.</param>
/// <returns>IEnumerable{ImageType}.</returns>
2013-04-11 19:36:50 +00:00
private static IEnumerable < ImageType > GetImageTypes ( GetItems request )
2013-02-21 01:33:05 +00:00
{
var val = request . ImageTypes ;
if ( string . IsNullOrEmpty ( val ) )
{
return new ImageType [ ] { } ;
}
return val . Split ( ',' ) . Select ( v = > ( ImageType ) Enum . Parse ( typeof ( ImageType ) , v , true ) ) ;
}
}
/// <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 ) ;
}
}
}