2019-01-13 13:01:16 -07:00
using System ;
2019-01-13 12:24:58 -07:00
using System.Collections.Generic ;
using System.IO ;
using System.Linq ;
2019-04-23 14:31:38 -07:00
using System.Net ;
using System.Text.RegularExpressions ;
2019-01-13 12:24:58 -07:00
using System.Threading ;
using System.Threading.Tasks ;
using MediaBrowser.Api.Movies ;
using MediaBrowser.Common.Extensions ;
using MediaBrowser.Common.Progress ;
using MediaBrowser.Controller.Configuration ;
2014-02-20 22:04:11 -07:00
using MediaBrowser.Controller.Dto ;
using MediaBrowser.Controller.Entities ;
using MediaBrowser.Controller.Entities.Audio ;
using MediaBrowser.Controller.Entities.Movies ;
using MediaBrowser.Controller.Entities.TV ;
2013-02-20 18:33:05 -07:00
using MediaBrowser.Controller.Library ;
2014-07-03 19:22:57 -07:00
using MediaBrowser.Controller.Net ;
2019-01-13 12:24:58 -07:00
using MediaBrowser.Controller.Providers ;
2015-02-11 20:54:31 -07:00
using MediaBrowser.Model.Activity ;
2019-01-13 12:24:58 -07:00
using MediaBrowser.Model.Configuration ;
2014-02-20 22:04:11 -07:00
using MediaBrowser.Model.Dto ;
using MediaBrowser.Model.Entities ;
2016-10-23 19:45:23 -07:00
using MediaBrowser.Model.Globalization ;
2019-01-13 12:24:58 -07:00
using MediaBrowser.Model.Querying ;
2016-10-25 12:02:04 -07:00
using MediaBrowser.Model.Services ;
2018-12-13 06:18:25 -07:00
using Microsoft.Extensions.Logging ;
2019-03-05 11:20:28 -07:00
using Microsoft.Net.Http.Headers ;
2013-02-20 18:33:05 -07:00
2013-02-24 20:56:00 -07:00
namespace MediaBrowser.Api.Library
2013-02-20 18:33:05 -07:00
{
2014-11-14 19:31:03 -07:00
[Route("/Items/{Id}/File", "GET", Summary = "Gets the original file of an item")]
[Authenticated]
2014-02-20 22:04:11 -07:00
public class GetFile
{
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get ; set ; }
}
/// <summary>
/// Class GetCriticReviews
/// </summary>
2014-11-14 19:31:03 -07:00
[Route("/Items/{Id}/CriticReviews", "GET", Summary = "Gets critic reviews for an item")]
[Authenticated]
2018-09-12 10:26:21 -07:00
public class GetCriticReviews : IReturn < QueryResult < BaseItemDto > >
2014-02-20 22:04:11 -07:00
{
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get ; set ; }
/// <summary>
/// Skips over a given number of items within the results. Use for paging.
/// </summary>
/// <value>The start index.</value>
[ApiMember(Name = "StartIndex", Description = "Optional. The record index to start at. All items with a lower index will be dropped from the results.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int? StartIndex { get ; set ; }
/// <summary>
/// The maximum number of items to return
/// </summary>
/// <value>The limit.</value>
[ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int? Limit { get ; set ; }
}
/// <summary>
/// Class GetThemeSongs
/// </summary>
2014-11-14 19:31:03 -07:00
[Route("/Items/{Id}/ThemeSongs", "GET", Summary = "Gets theme songs for an item")]
[Authenticated]
2014-02-20 22:04:11 -07:00
public class GetThemeSongs : IReturn < ThemeMediaResult >
{
/// <summary>
/// Gets or sets the user id.
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
2018-09-12 10:26:21 -07:00
public Guid UserId { get ; set ; }
2014-02-20 22:04:11 -07:00
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get ; set ; }
[ApiMember(Name = "InheritFromParent", Description = "Determines whether or not parent items should be searched for theme media.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public bool InheritFromParent { get ; set ; }
}
/// <summary>
/// Class GetThemeVideos
/// </summary>
2014-11-14 19:31:03 -07:00
[Route("/Items/{Id}/ThemeVideos", "GET", Summary = "Gets theme videos for an item")]
[Authenticated]
2014-02-20 22:04:11 -07:00
public class GetThemeVideos : IReturn < ThemeMediaResult >
{
/// <summary>
/// Gets or sets the user id.
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
2018-09-12 10:26:21 -07:00
public Guid UserId { get ; set ; }
2014-02-20 22:04:11 -07:00
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get ; set ; }
[ApiMember(Name = "InheritFromParent", Description = "Determines whether or not parent items should be searched for theme media.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public bool InheritFromParent { get ; set ; }
}
/// <summary>
/// Class GetThemeVideos
/// </summary>
2014-11-14 19:31:03 -07:00
[Route("/Items/{Id}/ThemeMedia", "GET", Summary = "Gets theme videos and songs for an item")]
[Authenticated]
2014-02-20 22:04:11 -07:00
public class GetThemeMedia : IReturn < AllThemeMediaResult >
{
/// <summary>
/// Gets or sets the user id.
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
2018-09-12 10:26:21 -07:00
public Guid UserId { get ; set ; }
2014-02-20 22:04:11 -07:00
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get ; set ; }
[ApiMember(Name = "InheritFromParent", Description = "Determines whether or not parent items should be searched for theme media.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public bool InheritFromParent { get ; set ; }
}
2014-11-14 19:31:03 -07:00
[Route("/Library/Refresh", "POST", Summary = "Starts a library scan")]
[Authenticated(Roles = "Admin")]
2014-02-20 22:04:11 -07:00
public class RefreshLibrary : IReturnVoid
{
}
2014-11-14 19:31:03 -07:00
[Route("/Items/{Id}", "DELETE", Summary = "Deletes an item from the library and file system")]
2014-11-18 19:45:12 -07:00
[Authenticated]
2014-02-20 22:04:11 -07:00
public class DeleteItem : IReturnVoid
{
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
public string Id { get ; set ; }
}
2016-01-19 12:03:46 -07:00
[Route("/Items", "DELETE", Summary = "Deletes an item from the library and file system")]
[Authenticated]
public class DeleteItems : IReturnVoid
{
2018-09-12 10:26:21 -07:00
[ApiMember(Name = "Ids", Description = "Ids", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "DELETE")]
2016-01-19 12:03:46 -07:00
public string Ids { get ; set ; }
}
2014-02-20 22:04:11 -07:00
[Route("/Items/Counts", "GET")]
2014-11-14 19:31:03 -07:00
[Authenticated]
2014-02-20 22:04:11 -07:00
public class GetItemCounts : IReturn < ItemCounts >
{
[ApiMember(Name = "UserId", Description = "Optional. Get counts from a specific user's library.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
2018-09-12 10:26:21 -07:00
public Guid UserId { get ; set ; }
2014-02-20 22:04:11 -07:00
[ApiMember(Name = "IsFavorite", Description = "Optional. Get counts of favorite items", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? IsFavorite { get ; set ; }
}
2014-11-14 19:31:03 -07:00
[Route("/Items/{Id}/Ancestors", "GET", Summary = "Gets all parents of an item")]
[Authenticated]
2014-02-20 22:04:11 -07:00
public class GetAncestors : IReturn < BaseItemDto [ ] >
{
/// <summary>
/// Gets or sets the user id.
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
2018-09-12 10:26:21 -07:00
public Guid UserId { get ; set ; }
2014-02-20 22:04:11 -07:00
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get ; set ; }
}
2013-02-20 18:33:05 -07:00
/// <summary>
/// Class GetPhyscialPaths
/// </summary>
2014-11-14 19:31:03 -07:00
[Route("/Library/PhysicalPaths", "GET", Summary = "Gets a list of physical paths from virtual folders")]
[Authenticated(Roles = "Admin")]
2013-02-20 18:33:05 -07:00
public class GetPhyscialPaths : IReturn < List < string > >
{
}
2014-11-14 19:31:03 -07:00
[Route("/Library/MediaFolders", "GET", Summary = "Gets all user media folders.")]
[Authenticated]
2017-08-19 12:43:35 -07:00
public class GetMediaFolders : IReturn < QueryResult < BaseItemDto > >
2014-02-20 22:04:11 -07:00
{
2014-06-30 21:26:50 -07:00
[ApiMember(Name = "IsHidden", Description = "Optional. Filter by folders that are marked hidden, or not.", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")]
public bool? IsHidden { get ; set ; }
2014-02-20 22:04:11 -07:00
}
2014-11-14 19:31:03 -07:00
[Route("/Library/Series/Added", "POST", Summary = "Reports that new episodes of a series have been added by an external source")]
[Route("/Library/Series/Updated", "POST", Summary = "Reports that new episodes of a series have been added by an external source")]
[Authenticated]
2014-04-26 20:42:05 -07:00
public class PostUpdatedSeries : IReturnVoid
{
2018-09-12 10:26:21 -07:00
[ApiMember(Name = "TvdbId", Description = "Tvdb Id", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "POST")]
2014-04-26 20:42:05 -07:00
public string TvdbId { get ; set ; }
}
2015-09-02 08:33:20 -07:00
[Route("/Library/Movies/Added", "POST", Summary = "Reports that new movies have been added by an external source")]
[Route("/Library/Movies/Updated", "POST", Summary = "Reports that new movies have been added by an external source")]
[Authenticated]
public class PostUpdatedMovies : IReturnVoid
{
2018-09-12 10:26:21 -07:00
[ApiMember(Name = "TmdbId", Description = "Tmdb Id", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "POST")]
2015-09-02 08:33:20 -07:00
public string TmdbId { get ; set ; }
2018-09-12 10:26:21 -07:00
[ApiMember(Name = "ImdbId", Description = "Imdb Id", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "POST")]
2015-09-02 08:33:20 -07:00
public string ImdbId { get ; set ; }
}
2018-09-12 10:26:21 -07:00
public class MediaUpdateInfo
{
public string Path { get ; set ; }
// Created, Modified, Deleted
public string UpdateType { get ; set ; }
}
[Route("/Library/Media/Updated", "POST", Summary = "Reports that new movies have been added by an external source")]
[Authenticated]
public class PostUpdatedMedia : IReturnVoid
{
[ApiMember(Name = "Updates", Description = "A list of updated media paths", IsRequired = false, DataType = "string", ParameterType = "body", Verb = "POST")]
public List < MediaUpdateInfo > Updates { get ; set ; }
}
2015-02-05 22:39:07 -07:00
[Route("/Items/{Id}/Download", "GET", Summary = "Downloads item media")]
[Authenticated(Roles = "download")]
public class GetDownload
{
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get ; set ; }
}
2018-09-12 10:26:21 -07:00
[Route("/Artists/{Id}/Similar", "GET", Summary = "Finds albums similar to a given album.")]
2015-08-20 20:21:27 -07:00
[Route("/Items/{Id}/Similar", "GET", Summary = "Gets similar items")]
2018-09-12 10:26:21 -07:00
[Route("/Albums/{Id}/Similar", "GET", Summary = "Finds albums similar to a given album.")]
[Route("/Shows/{Id}/Similar", "GET", Summary = "Finds tv shows similar to a given one.")]
[Route("/Movies/{Id}/Similar", "GET", Summary = "Finds movies and trailers similar to a given movie.")]
[Route("/Trailers/{Id}/Similar", "GET", Summary = "Finds movies and trailers similar to a given trailer.")]
2015-08-20 20:21:27 -07:00
[Authenticated]
2015-08-20 19:36:30 -07:00
public class GetSimilarItems : BaseGetSimilarItemsFromItem
{
}
2018-09-12 10:26:21 -07:00
[Route("/Libraries/AvailableOptions", "GET")]
[Authenticated(AllowBeforeStartupWizard = true)]
public class GetLibraryOptionsInfo : IReturn < LibraryOptionsResult >
{
public string LibraryContentType { get ; set ; }
public bool IsNewLibrary { get ; set ; }
}
public class LibraryOptionInfo
{
public string Name { get ; set ; }
public bool DefaultEnabled { get ; set ; }
}
public class LibraryOptionsResult
{
public LibraryOptionInfo [ ] MetadataSavers { get ; set ; }
public LibraryOptionInfo [ ] MetadataReaders { get ; set ; }
public LibraryOptionInfo [ ] SubtitleFetchers { get ; set ; }
public LibraryTypeOptions [ ] TypeOptions { get ; set ; }
}
public class LibraryTypeOptions
{
public string Type { get ; set ; }
public LibraryOptionInfo [ ] MetadataFetchers { get ; set ; }
public LibraryOptionInfo [ ] ImageFetchers { get ; set ; }
public ImageType [ ] SupportedImageTypes { get ; set ; }
public ImageOption [ ] DefaultImageOptions { get ; set ; }
}
2013-02-20 18:33:05 -07:00
/// <summary>
/// Class LibraryService
/// </summary>
2013-03-15 22:52:33 -07:00
public class LibraryService : BaseApiService
2013-02-20 18:33:05 -07:00
{
2019-11-17 15:05:39 -07:00
private readonly IProviderManager _providerManager ;
2013-02-28 12:32:41 -07:00
private readonly ILibraryManager _libraryManager ;
2014-02-20 22:04:11 -07:00
private readonly IUserManager _userManager ;
private readonly IDtoService _dtoService ;
2014-11-18 19:45:12 -07:00
private readonly IAuthorizationContext _authContext ;
2015-02-11 20:54:31 -07:00
private readonly IActivityManager _activityManager ;
private readonly ILocalizationManager _localization ;
2015-08-28 12:10:44 -07:00
private readonly ILibraryMonitor _libraryMonitor ;
2013-02-24 14:53:54 -07:00
2020-05-14 17:11:34 -07:00
private readonly ILogger < MoviesService > _moviesServiceLogger ;
2013-02-24 14:53:54 -07:00
/// <summary>
/// Initializes a new instance of the <see cref="LibraryService" /> class.
/// </summary>
2019-11-17 15:05:39 -07:00
public LibraryService (
ILogger < LibraryService > logger ,
2020-05-14 17:11:34 -07:00
ILogger < MoviesService > moviesServiceLogger ,
2019-11-17 15:05:39 -07:00
IServerConfigurationManager serverConfigurationManager ,
IHttpResultFactory httpResultFactory ,
IProviderManager providerManager ,
ILibraryManager libraryManager ,
IUserManager userManager ,
IDtoService dtoService ,
IAuthorizationContext authContext ,
IActivityManager activityManager ,
ILocalizationManager localization ,
ILibraryMonitor libraryMonitor )
: base ( logger , serverConfigurationManager , httpResultFactory )
2013-02-24 14:53:54 -07:00
{
2019-11-17 15:05:39 -07:00
_providerManager = providerManager ;
2014-02-20 22:04:11 -07:00
_libraryManager = libraryManager ;
_userManager = userManager ;
_dtoService = dtoService ;
2014-11-18 19:45:12 -07:00
_authContext = authContext ;
2015-02-11 20:54:31 -07:00
_activityManager = activityManager ;
_localization = localization ;
2015-09-02 08:35:47 -07:00
_libraryMonitor = libraryMonitor ;
2020-05-14 17:11:34 -07:00
_moviesServiceLogger = moviesServiceLogger ;
2015-08-20 19:36:30 -07:00
}
2018-09-12 10:26:21 -07:00
private string [ ] GetRepresentativeItemTypes ( string contentType )
2015-08-20 19:36:30 -07:00
{
2020-04-05 11:44:14 -07:00
return contentType switch
{
CollectionType . BoxSets = > new [ ] { "BoxSet" } ,
CollectionType . Playlists = > new [ ] { "Playlist" } ,
CollectionType . Movies = > new [ ] { "Movie" } ,
CollectionType . TvShows = > new [ ] { "Series" , "Season" , "Episode" } ,
CollectionType . Books = > new [ ] { "Book" } ,
CollectionType . Music = > new [ ] { "MusicAlbum" , "MusicArtist" , "Audio" , "MusicVideo" } ,
CollectionType . HomeVideos = > new [ ] { "Video" , "Photo" } ,
CollectionType . Photos = > new [ ] { "Video" , "Photo" } ,
CollectionType . MusicVideos = > new [ ] { "MusicVideo" } ,
_ = > new [ ] { "Series" , "Season" , "Episode" , "Movie" }
} ;
2018-09-12 10:26:21 -07:00
}
2015-08-20 19:36:30 -07:00
2018-09-12 10:26:21 -07:00
private bool IsSaverEnabledByDefault ( string name , string [ ] itemTypes , bool isNewLibrary )
{
if ( isNewLibrary )
{
return false ;
}
2015-08-20 19:36:30 -07:00
2019-11-17 15:05:39 -07:00
var metadataOptions = ServerConfigurationManager . Configuration . MetadataOptions
2018-09-12 10:26:21 -07:00
. Where ( i = > itemTypes . Contains ( i . ItemType ? ? string . Empty , StringComparer . OrdinalIgnoreCase ) )
. ToArray ( ) ;
if ( metadataOptions . Length = = 0 )
2015-08-20 19:36:30 -07:00
{
2018-09-12 10:26:21 -07:00
return true ;
}
2015-08-20 19:36:30 -07:00
2018-09-12 10:26:21 -07:00
return metadataOptions . Any ( i = > ! i . DisabledMetadataSavers . Contains ( name , StringComparer . OrdinalIgnoreCase ) ) ;
}
private bool IsMetadataFetcherEnabledByDefault ( string name , string type , bool isNewLibrary )
{
if ( isNewLibrary )
{
if ( string . Equals ( name , "TheMovieDb" , StringComparison . OrdinalIgnoreCase ) )
2015-08-20 19:36:30 -07:00
{
2020-04-05 20:12:25 -07:00
return ! ( string . Equals ( type , "Season" , StringComparison . OrdinalIgnoreCase )
2020-04-06 20:17:49 -07:00
| | string . Equals ( type , "Episode" , StringComparison . OrdinalIgnoreCase )
| | string . Equals ( type , "MusicVideo" , StringComparison . OrdinalIgnoreCase ) ) ;
2018-09-12 10:26:21 -07:00
}
2020-04-05 15:06:30 -07:00
2020-04-05 20:12:25 -07:00
return string . Equals ( name , "TheTVDB" , StringComparison . OrdinalIgnoreCase )
2020-04-06 20:17:49 -07:00
| | string . Equals ( name , "TheAudioDB" , StringComparison . OrdinalIgnoreCase )
| | string . Equals ( name , "MusicBrainz" , StringComparison . OrdinalIgnoreCase ) ;
2018-09-12 10:26:21 -07:00
}
2019-11-17 15:05:39 -07:00
var metadataOptions = ServerConfigurationManager . Configuration . MetadataOptions
2018-09-12 10:26:21 -07:00
. Where ( i = > string . Equals ( i . ItemType , type , StringComparison . OrdinalIgnoreCase ) )
. ToArray ( ) ;
2020-04-05 11:44:14 -07:00
return metadataOptions . Length = = 0
2020-04-06 20:17:49 -07:00
| | metadataOptions . Any ( i = > ! i . DisabledMetadataFetchers . Contains ( name , StringComparer . OrdinalIgnoreCase ) ) ;
2018-09-12 10:26:21 -07:00
}
private bool IsImageFetcherEnabledByDefault ( string name , string type , bool isNewLibrary )
{
if ( isNewLibrary )
2015-08-20 19:36:30 -07:00
{
2018-09-12 10:26:21 -07:00
if ( string . Equals ( name , "TheMovieDb" , StringComparison . OrdinalIgnoreCase ) )
2015-08-20 19:36:30 -07:00
{
2020-04-05 20:12:25 -07:00
return ! string . Equals ( type , "Series" , StringComparison . OrdinalIgnoreCase )
& & ! string . Equals ( type , "Season" , StringComparison . OrdinalIgnoreCase )
& & ! string . Equals ( type , "Episode" , StringComparison . OrdinalIgnoreCase )
& & ! string . Equals ( type , "MusicVideo" , StringComparison . OrdinalIgnoreCase ) ;
2018-09-12 10:26:21 -07:00
}
2020-04-05 20:12:25 -07:00
return string . Equals ( name , "TheTVDB" , StringComparison . OrdinalIgnoreCase )
| | string . Equals ( name , "Screen Grabber" , StringComparison . OrdinalIgnoreCase )
| | string . Equals ( name , "TheAudioDB" , StringComparison . OrdinalIgnoreCase )
| | string . Equals ( name , "Emby Designs" , StringComparison . OrdinalIgnoreCase )
| | string . Equals ( name , "Image Extractor" , StringComparison . OrdinalIgnoreCase ) ;
2015-08-20 19:36:30 -07:00
}
2018-09-12 10:26:21 -07:00
2019-11-17 15:05:39 -07:00
var metadataOptions = ServerConfigurationManager . Configuration . MetadataOptions
2018-09-12 10:26:21 -07:00
. Where ( i = > string . Equals ( i . ItemType , type , StringComparison . OrdinalIgnoreCase ) )
. ToArray ( ) ;
if ( metadataOptions . Length = = 0 )
2015-08-20 19:36:30 -07:00
{
2018-09-12 10:26:21 -07:00
return true ;
}
return metadataOptions . Any ( i = > ! i . DisabledImageFetchers . Contains ( name , StringComparer . OrdinalIgnoreCase ) ) ;
}
public object Get ( GetLibraryOptionsInfo request )
{
var result = new LibraryOptionsResult ( ) ;
var types = GetRepresentativeItemTypes ( request . LibraryContentType ) ;
var isNewLibrary = request . IsNewLibrary ;
var typesList = types . ToList ( ) ;
var plugins = _providerManager . GetAllMetadataPlugins ( )
. Where ( i = > types . Contains ( i . ItemType , StringComparer . OrdinalIgnoreCase ) )
. OrderBy ( i = > typesList . IndexOf ( i . ItemType ) )
. ToList ( ) ;
result . MetadataSavers = plugins
. SelectMany ( i = > i . Plugins . Where ( p = > p . Type = = MetadataPluginType . MetadataSaver ) )
. Select ( i = > new LibraryOptionInfo
2015-08-20 19:36:30 -07:00
{
2018-09-12 10:26:21 -07:00
Name = i . Name ,
DefaultEnabled = IsSaverEnabledByDefault ( i . Name , types , isNewLibrary )
} )
2019-02-02 04:27:06 -07:00
. GroupBy ( i = > i . Name , StringComparer . OrdinalIgnoreCase )
. Select ( x = > x . First ( ) )
2018-09-12 10:26:21 -07:00
. ToArray ( ) ;
2015-08-20 19:36:30 -07:00
2018-09-12 10:26:21 -07:00
result . MetadataReaders = plugins
. SelectMany ( i = > i . Plugins . Where ( p = > p . Type = = MetadataPluginType . LocalMetadataProvider ) )
. Select ( i = > new LibraryOptionInfo
2015-08-20 19:36:30 -07:00
{
2018-09-12 10:26:21 -07:00
Name = i . Name ,
DefaultEnabled = true
} )
2019-02-02 04:27:06 -07:00
. GroupBy ( i = > i . Name , StringComparer . OrdinalIgnoreCase )
. Select ( x = > x . First ( ) )
2018-09-12 10:26:21 -07:00
. ToArray ( ) ;
result . SubtitleFetchers = plugins
. SelectMany ( i = > i . Plugins . Where ( p = > p . Type = = MetadataPluginType . SubtitleFetcher ) )
. Select ( i = > new LibraryOptionInfo
{
Name = i . Name ,
DefaultEnabled = true
} )
2019-02-02 04:27:06 -07:00
. GroupBy ( i = > i . Name , StringComparer . OrdinalIgnoreCase )
. Select ( x = > x . First ( ) )
2018-09-12 10:26:21 -07:00
. ToArray ( ) ;
var typeOptions = new List < LibraryTypeOptions > ( ) ;
foreach ( var type in types )
{
2020-04-05 12:56:08 -07:00
TypeOptions . DefaultImageOptions . TryGetValue ( type , out var defaultImageOptions ) ;
2018-09-12 10:26:21 -07:00
typeOptions . Add ( new LibraryTypeOptions
{
Type = type ,
MetadataFetchers = plugins
. Where ( i = > string . Equals ( i . ItemType , type , StringComparison . OrdinalIgnoreCase ) )
. SelectMany ( i = > i . Plugins . Where ( p = > p . Type = = MetadataPluginType . MetadataFetcher ) )
. Select ( i = > new LibraryOptionInfo
{
Name = i . Name ,
DefaultEnabled = IsMetadataFetcherEnabledByDefault ( i . Name , type , isNewLibrary )
} )
2019-02-02 04:27:06 -07:00
. GroupBy ( i = > i . Name , StringComparer . OrdinalIgnoreCase )
. Select ( x = > x . First ( ) )
2018-09-12 10:26:21 -07:00
. ToArray ( ) ,
ImageFetchers = plugins
. Where ( i = > string . Equals ( i . ItemType , type , StringComparison . OrdinalIgnoreCase ) )
. SelectMany ( i = > i . Plugins . Where ( p = > p . Type = = MetadataPluginType . ImageFetcher ) )
. Select ( i = > new LibraryOptionInfo
{
Name = i . Name ,
DefaultEnabled = IsImageFetcherEnabledByDefault ( i . Name , type , isNewLibrary )
} )
2019-02-02 04:27:06 -07:00
. GroupBy ( i = > i . Name , StringComparer . OrdinalIgnoreCase )
. Select ( x = > x . First ( ) )
2018-09-12 10:26:21 -07:00
. ToArray ( ) ,
SupportedImageTypes = plugins
. Where ( i = > string . Equals ( i . ItemType , type , StringComparison . OrdinalIgnoreCase ) )
. SelectMany ( i = > i . SupportedImageTypes ? ? Array . Empty < ImageType > ( ) )
. Distinct ( )
. ToArray ( ) ,
DefaultImageOptions = defaultImageOptions ? ? Array . Empty < ImageOption > ( )
2015-08-20 19:36:30 -07:00
} ) ;
}
2018-09-12 10:26:21 -07:00
result . TypeOptions = typeOptions . ToArray ( ) ;
return result ;
}
public object Get ( GetSimilarItems request )
{
var item = string . IsNullOrEmpty ( request . Id ) ?
( ! request . UserId . Equals ( Guid . Empty ) ? _libraryManager . GetUserRootFolder ( ) :
_libraryManager . RootFolder ) : _libraryManager . GetItemById ( request . Id ) ;
2015-08-20 19:36:30 -07:00
var program = item as IHasProgramAttributes ;
2016-03-19 08:38:05 -07:00
if ( item is Movie | | ( program ! = null & & program . IsMovie ) | | item is Trailer )
2015-08-20 19:36:30 -07:00
{
2019-11-17 15:05:39 -07:00
return new MoviesService (
2020-05-14 17:11:34 -07:00
_moviesServiceLogger ,
2019-11-17 15:05:39 -07:00
ServerConfigurationManager ,
ResultFactory ,
_userManager ,
_libraryManager ,
_dtoService ,
_authContext )
2015-08-20 19:36:30 -07:00
{
Request = Request ,
2018-09-12 10:26:21 -07:00
} . GetSimilarItemsResult ( request ) ;
2015-08-20 19:36:30 -07:00
}
2018-09-12 10:26:21 -07:00
if ( program ! = null & & program . IsSeries )
2015-08-20 19:36:30 -07:00
{
2018-09-12 10:26:21 -07:00
return GetSimilarItemsResult ( request , new [ ] { typeof ( Series ) . Name } ) ;
}
2015-08-20 19:36:30 -07:00
2018-09-12 10:26:21 -07:00
if ( item is Episode | | ( item is IItemByName & & ! ( item is MusicArtist ) ) )
{
return new QueryResult < BaseItemDto > ( ) ;
2015-08-20 19:36:30 -07:00
}
2018-09-12 10:26:21 -07:00
return GetSimilarItemsResult ( request , new [ ] { item . GetType ( ) . Name } ) ;
}
private QueryResult < BaseItemDto > GetSimilarItemsResult ( BaseGetSimilarItemsFromItem request , string [ ] includeItemTypes )
{
var user = ! request . UserId . Equals ( Guid . Empty ) ? _userManager . GetUserById ( request . UserId ) : null ;
var item = string . IsNullOrEmpty ( request . Id ) ?
( ! request . UserId . Equals ( Guid . Empty ) ? _libraryManager . GetUserRootFolder ( ) :
_libraryManager . RootFolder ) : _libraryManager . GetItemById ( request . Id ) ;
var dtoOptions = GetDtoOptions ( _authContext , request ) ;
var query = new InternalItemsQuery ( user )
{
Limit = request . Limit ,
IncludeItemTypes = includeItemTypes ,
SimilarTo = item ,
DtoOptions = dtoOptions ,
EnableTotalRecordCount = false
} ;
// ExcludeArtistIds
if ( ! string . IsNullOrEmpty ( request . ExcludeArtistIds ) )
{
2020-04-05 12:56:08 -07:00
query . ExcludeArtistIds = GetGuids ( request . ExcludeArtistIds ) ;
2018-09-12 10:26:21 -07:00
}
List < BaseItem > itemsResult ;
if ( item is MusicArtist )
{
query . IncludeItemTypes = Array . Empty < string > ( ) ;
itemsResult = _libraryManager . GetArtists ( query ) . Items . Select ( i = > i . Item1 ) . ToList ( ) ;
}
else
{
itemsResult = _libraryManager . GetItemList ( query ) ;
}
var returnList = _dtoService . GetBaseItemDtos ( itemsResult , dtoOptions , user ) ;
var result = new QueryResult < BaseItemDto >
{
Items = returnList ,
TotalRecordCount = itemsResult . Count
} ;
return result ;
2014-02-20 22:04:11 -07:00
}
public object Get ( GetMediaFolders request )
{
2015-11-02 21:34:47 -07:00
var items = _libraryManager . GetUserRootFolder ( ) . Children . Concat ( _libraryManager . RootFolder . VirtualChildren ) . OrderBy ( i = > i . SortName ) . ToList ( ) ;
2014-02-20 22:04:11 -07:00
2014-06-30 21:26:50 -07:00
if ( request . IsHidden . HasValue )
{
var val = request . IsHidden . Value ;
items = items . Where ( i = > i . IsHidden = = val ) . ToList ( ) ;
}
2016-11-10 07:41:24 -07:00
var dtoOptions = GetDtoOptions ( _authContext , request ) ;
2015-02-05 22:39:07 -07:00
2017-08-19 12:43:35 -07:00
var result = new QueryResult < BaseItemDto >
2013-02-24 14:53:54 -07:00
{
2014-02-20 22:04:11 -07:00
TotalRecordCount = items . Count ,
2014-12-26 22:08:39 -07:00
Items = items . Select ( i = > _dtoService . GetBaseItemDto ( i , dtoOptions ) ) . ToArray ( )
2014-02-20 22:04:11 -07:00
} ;
2018-09-12 10:26:21 -07:00
return result ;
2014-02-20 22:04:11 -07:00
}
2014-08-04 20:41:56 -07:00
public void Post ( PostUpdatedSeries request )
{
2016-03-19 23:46:51 -07:00
var series = _libraryManager . GetItemList ( new InternalItemsQuery
2015-08-28 12:10:44 -07:00
{
2017-05-21 00:25:49 -07:00
IncludeItemTypes = new [ ] { typeof ( Series ) . Name } ,
DtoOptions = new DtoOptions ( false )
{
EnableImages = false
}
2015-08-28 12:10:44 -07:00
2016-03-19 23:46:51 -07:00
} ) . Where ( i = > string . Equals ( request . TvdbId , i . GetProviderId ( MetadataProviders . Tvdb ) , StringComparison . OrdinalIgnoreCase ) ) . ToArray ( ) ;
2015-08-28 12:10:44 -07:00
2018-09-12 10:26:21 -07:00
foreach ( var item in series )
2015-08-28 12:10:44 -07:00
{
2018-09-12 10:26:21 -07:00
_libraryMonitor . ReportFileSystemChanged ( item . Path ) ;
}
}
public void Post ( PostUpdatedMedia request )
{
if ( request . Updates ! = null )
{
foreach ( var item in request . Updates )
2015-08-28 12:10:44 -07:00
{
_libraryMonitor . ReportFileSystemChanged ( item . Path ) ;
}
2015-09-02 08:33:20 -07:00
}
}
public void Post ( PostUpdatedMovies request )
{
2016-03-19 23:46:51 -07:00
var movies = _libraryManager . GetItemList ( new InternalItemsQuery
2015-09-02 08:33:20 -07:00
{
2017-05-21 00:25:49 -07:00
IncludeItemTypes = new [ ] { typeof ( Movie ) . Name } ,
DtoOptions = new DtoOptions ( false )
{
EnableImages = false
}
2015-09-02 08:33:20 -07:00
2017-08-09 12:56:38 -07:00
} ) ;
2015-09-02 08:33:20 -07:00
if ( ! string . IsNullOrWhiteSpace ( request . ImdbId ) )
{
2017-08-09 12:56:38 -07:00
movies = movies . Where ( i = > string . Equals ( request . ImdbId , i . GetProviderId ( MetadataProviders . Imdb ) , StringComparison . OrdinalIgnoreCase ) ) . ToList ( ) ;
2015-09-02 08:33:20 -07:00
}
else if ( ! string . IsNullOrWhiteSpace ( request . TmdbId ) )
{
2017-08-09 12:56:38 -07:00
movies = movies . Where ( i = > string . Equals ( request . TmdbId , i . GetProviderId ( MetadataProviders . Tmdb ) , StringComparison . OrdinalIgnoreCase ) ) . ToList ( ) ;
2015-09-02 08:33:20 -07:00
}
else
{
2017-08-09 12:56:38 -07:00
movies = new List < BaseItem > ( ) ;
2015-09-02 08:33:20 -07:00
}
2018-09-12 10:26:21 -07:00
foreach ( var item in movies )
2015-08-28 12:10:44 -07:00
{
2018-09-12 10:26:21 -07:00
_libraryMonitor . ReportFileSystemChanged ( item . Path ) ;
2015-08-28 12:10:44 -07:00
}
2014-08-04 20:41:56 -07:00
}
2016-06-18 23:18:29 -07:00
public Task < object > Get ( GetDownload request )
2015-02-05 22:39:07 -07:00
{
var item = _libraryManager . GetItemById ( request . Id ) ;
2015-02-11 20:54:31 -07:00
var auth = _authContext . GetAuthorizationInfo ( Request ) ;
2015-02-05 22:39:07 -07:00
2018-09-12 10:26:21 -07:00
var user = auth . User ;
2015-02-11 20:54:31 -07:00
if ( user ! = null )
{
if ( ! item . CanDownload ( user ) )
{
throw new ArgumentException ( "Item does not support downloading" ) ;
}
}
else
2015-02-05 22:39:07 -07:00
{
2015-02-11 20:54:31 -07:00
if ( ! item . CanDownload ( ) )
{
throw new ArgumentException ( "Item does not support downloading" ) ;
}
2015-02-05 22:39:07 -07:00
}
var headers = new Dictionary < string , string > ( ) ;
2015-02-11 20:54:31 -07:00
if ( user ! = null )
{
LogDownload ( item , user , auth ) ;
}
2017-09-01 12:24:39 -07:00
var path = item . Path ;
// Quotes are valid in linux. They'll possibly cause issues here
var filename = ( Path . GetFileName ( path ) ? ? string . Empty ) . Replace ( "\"" , string . Empty ) ;
if ( ! string . IsNullOrWhiteSpace ( filename ) )
{
2019-04-23 14:31:38 -07:00
// Kestrel doesn't support non-ASCII characters in headers
2020-02-28 21:11:27 -07:00
if ( Regex . IsMatch ( filename , @"[^\p{IsBasicLatin}]" ) )
2019-04-23 14:31:38 -07:00
{
// Manually encoding non-ASCII characters, following https://tools.ietf.org/html/rfc5987#section-3.2.2
headers [ HeaderNames . ContentDisposition ] = "attachment; filename*=UTF-8''" + WebUtility . UrlEncode ( filename ) ;
}
else
{
headers [ HeaderNames . ContentDisposition ] = "attachment; filename=\"" + filename + "\"" ;
}
2017-09-01 12:24:39 -07:00
}
2015-02-05 22:39:07 -07:00
return ResultFactory . GetStaticFileResult ( Request , new StaticFileResultOptions
{
2017-09-01 12:24:39 -07:00
Path = path ,
2015-02-05 22:39:07 -07:00
ResponseHeaders = headers
} ) ;
}
2017-08-26 17:32:33 -07:00
private void LogDownload ( BaseItem item , User user , AuthorizationInfo auth )
2015-02-11 20:54:31 -07:00
{
try
{
2020-05-02 15:32:22 -07:00
_activityManager . Create ( new Jellyfin . Data . Entities . ActivityLog (
string . Format ( _localization . GetLocalizedString ( "UserDownloadingItemWithValues" ) , user . Name , item . Name ) ,
"UserDownloadingContent" ,
2020-05-13 12:03:35 -07:00
auth . UserId )
2015-02-11 20:54:31 -07:00
{
ShortOverview = string . Format ( _localization . GetLocalizedString ( "AppDeviceValues" ) , auth . Client , auth . Device ) ,
2017-08-26 17:32:33 -07:00
} ) ;
2015-02-11 20:54:31 -07:00
}
catch
{
// Logged at lower levels
}
}
2016-06-18 23:18:29 -07:00
public Task < object > Get ( GetFile request )
2014-02-20 22:04:11 -07:00
{
2014-04-25 13:15:50 -07:00
var item = _libraryManager . GetItemById ( request . Id ) ;
2013-02-24 14:53:54 -07:00
2016-06-18 23:18:29 -07:00
return ResultFactory . GetStaticFileResult ( Request , item . Path ) ;
2014-02-20 22:04:11 -07:00
}
2013-02-20 18:33:05 -07:00
/// <summary>
/// Gets the specified request.
/// </summary>
/// <param name="request">The request.</param>
/// <returns>System.Object.</returns>
public object Get ( GetPhyscialPaths request )
{
2013-12-20 09:51:25 -07:00
var result = _libraryManager . RootFolder . Children
2014-02-10 13:11:46 -07:00
. SelectMany ( c = > c . PhysicalLocations )
2013-12-20 09:51:25 -07:00
. ToList ( ) ;
2013-02-20 18:33:05 -07:00
2018-09-12 10:26:21 -07:00
return ToOptimizedResult ( result ) ;
2013-02-20 18:33:05 -07:00
}
2014-02-20 22:04:11 -07:00
/// <summary>
/// Gets the specified request.
/// </summary>
/// <param name="request">The request.</param>
/// <returns>System.Object.</returns>
public object Get ( GetAncestors request )
{
var result = GetAncestors ( request ) ;
2018-09-12 10:26:21 -07:00
return ToOptimizedResult ( result ) ;
2014-02-20 22:04:11 -07:00
}
/// <summary>
/// Gets the ancestors.
/// </summary>
/// <param name="request">The request.</param>
/// <returns>Task{BaseItemDto[]}.</returns>
public List < BaseItemDto > GetAncestors ( GetAncestors request )
{
2014-04-25 13:15:50 -07:00
var item = _libraryManager . GetItemById ( request . Id ) ;
2014-02-20 22:04:11 -07:00
var baseItemDtos = new List < BaseItemDto > ( ) ;
2018-09-12 10:26:21 -07:00
var user = ! request . UserId . Equals ( Guid . Empty ) ? _userManager . GetUserById ( request . UserId ) : null ;
2014-02-20 22:04:11 -07:00
2016-11-10 07:41:24 -07:00
var dtoOptions = GetDtoOptions ( _authContext , request ) ;
2014-02-20 22:04:11 -07:00
2019-01-17 12:24:39 -07:00
BaseItem parent = item . GetParent ( ) ;
2015-02-05 22:39:07 -07:00
2014-02-20 22:04:11 -07:00
while ( parent ! = null )
{
if ( user ! = null )
{
parent = TranslateParentItem ( parent , user ) ;
}
2014-12-26 22:08:39 -07:00
baseItemDtos . Add ( _dtoService . GetBaseItemDto ( parent , dtoOptions , user ) ) ;
2014-02-20 22:04:11 -07:00
2015-11-11 07:56:31 -07:00
parent = parent . GetParent ( ) ;
2014-02-20 22:04:11 -07:00
}
2017-08-19 12:43:35 -07:00
return baseItemDtos ;
2014-02-20 22:04:11 -07:00
}
private BaseItem TranslateParentItem ( BaseItem item , User user )
{
2020-04-05 11:44:14 -07:00
return item . GetParent ( ) is AggregateFolder
? _libraryManager . GetUserRootFolder ( ) . GetChildren ( user , true )
. FirstOrDefault ( i = > i . PhysicalLocations . Contains ( item . Path ) )
: item ;
2014-02-20 22:04:11 -07:00
}
/// <summary>
/// Gets the specified request.
/// </summary>
/// <param name="request">The request.</param>
/// <returns>System.Object.</returns>
public object Get ( GetCriticReviews request )
{
2018-09-12 10:26:21 -07:00
return new QueryResult < BaseItemDto > ( ) ;
2014-02-20 22:04:11 -07:00
}
/// <summary>
/// Gets the specified request.
/// </summary>
/// <param name="request">The request.</param>
/// <returns>System.Object.</returns>
public object Get ( GetItemCounts request )
{
2018-09-12 10:26:21 -07:00
var user = request . UserId . Equals ( Guid . Empty ) ? null : _userManager . GetUserById ( request . UserId ) ;
2014-02-20 22:04:11 -07:00
var counts = new ItemCounts
{
2016-03-24 20:53:42 -07:00
AlbumCount = GetCount ( typeof ( MusicAlbum ) , user , request ) ,
EpisodeCount = GetCount ( typeof ( Episode ) , user , request ) ,
MovieCount = GetCount ( typeof ( Movie ) , user , request ) ,
SeriesCount = GetCount ( typeof ( Series ) , user , request ) ,
SongCount = GetCount ( typeof ( Audio ) , user , request ) ,
MusicVideoCount = GetCount ( typeof ( MusicVideo ) , user , request ) ,
BoxSetCount = GetCount ( typeof ( BoxSet ) , user , request ) ,
BookCount = GetCount ( typeof ( Book ) , user , request )
2014-02-20 22:04:11 -07:00
} ;
2018-09-12 10:26:21 -07:00
return ToOptimizedResult ( counts ) ;
2014-02-20 22:04:11 -07:00
}
2016-03-24 20:53:42 -07:00
private int GetCount ( Type type , User user , GetItemCounts request )
2015-11-10 11:58:05 -07:00
{
2016-03-24 20:53:42 -07:00
var query = new InternalItemsQuery ( user )
{
IncludeItemTypes = new [ ] { type . Name } ,
Limit = 0 ,
Recursive = true ,
2017-01-09 10:05:34 -07:00
IsVirtualItem = false ,
2017-05-21 00:25:49 -07:00
IsFavorite = request . IsFavorite ,
DtoOptions = new DtoOptions ( false )
{
EnableImages = false
}
2016-03-24 20:53:42 -07:00
} ;
2014-02-20 22:04:11 -07:00
2016-03-24 20:53:42 -07:00
return _libraryManager . GetItemsResult ( query ) . TotalRecordCount ;
2014-02-20 22:04:11 -07:00
}
/// <summary>
/// Posts the specified request.
/// </summary>
/// <param name="request">The request.</param>
2019-02-23 19:16:19 -07:00
public async Task Post ( RefreshLibrary request )
2014-02-20 22:04:11 -07:00
{
2019-02-23 19:16:19 -07:00
try
2014-02-20 22:04:11 -07:00
{
2019-02-23 19:16:19 -07:00
await _libraryManager . ValidateMediaLibrary ( new SimpleProgress < double > ( ) , CancellationToken . None ) . ConfigureAwait ( false ) ;
}
catch ( Exception ex )
{
Logger . LogError ( ex , "Error refreshing library" ) ;
}
2014-02-20 22:04:11 -07:00
}
/// <summary>
/// Deletes the specified request.
/// </summary>
/// <param name="request">The request.</param>
2016-01-19 12:03:46 -07:00
public void Delete ( DeleteItems request )
2014-02-20 22:04:11 -07:00
{
2016-01-19 12:03:46 -07:00
var ids = string . IsNullOrWhiteSpace ( request . Ids )
2019-12-13 20:51:27 -07:00
? Array . Empty < string > ( )
: request . Ids . Split ( ',' ) ;
2014-11-18 19:45:12 -07:00
2018-09-12 10:26:21 -07:00
foreach ( var i in ids )
2014-11-18 19:45:12 -07:00
{
2016-01-19 12:03:46 -07:00
var item = _libraryManager . GetItemById ( i ) ;
var auth = _authContext . GetAuthorizationInfo ( Request ) ;
2018-09-12 10:26:21 -07:00
var user = auth . User ;
2014-11-18 19:45:12 -07:00
2016-01-19 12:03:46 -07:00
if ( ! item . CanDelete ( user ) )
{
if ( ids . Length > 1 )
{
throw new SecurityException ( "Unauthorized access" ) ;
}
2018-09-12 10:26:21 -07:00
continue ;
2016-01-19 12:03:46 -07:00
}
2018-09-12 10:26:21 -07:00
_libraryManager . DeleteItem ( item , new DeleteOptions
2016-01-19 12:03:46 -07:00
{
2016-02-11 21:54:00 -07:00
DeleteFileLocation = true
2018-09-12 10:26:21 -07:00
} , true ) ;
}
2016-01-19 12:03:46 -07:00
}
/// <summary>
/// Deletes the specified request.
/// </summary>
/// <param name="request">The request.</param>
public void Delete ( DeleteItem request )
{
Delete ( new DeleteItems
2015-08-02 19:12:52 -07:00
{
2016-01-19 12:03:46 -07:00
Ids = request . Id
} ) ;
2014-02-20 22:04:11 -07:00
}
public object Get ( GetThemeMedia request )
{
var themeSongs = GetThemeSongs ( new GetThemeSongs
{
InheritFromParent = request . InheritFromParent ,
Id = request . Id ,
UserId = request . UserId
} ) ;
var themeVideos = GetThemeVideos ( new GetThemeVideos
{
InheritFromParent = request . InheritFromParent ,
Id = request . Id ,
UserId = request . UserId
} ) ;
2018-09-12 10:26:21 -07:00
return ToOptimizedResult ( new AllThemeMediaResult
2014-02-20 22:04:11 -07:00
{
ThemeSongsResult = themeSongs ,
ThemeVideosResult = themeVideos ,
2015-04-25 20:25:07 -07:00
SoundtrackSongsResult = new ThemeMediaResult ( )
2014-02-20 22:04:11 -07:00
} ) ;
}
/// <summary>
/// Gets the specified request.
/// </summary>
/// <param name="request">The request.</param>
/// <returns>System.Object.</returns>
public object Get ( GetThemeSongs request )
{
var result = GetThemeSongs ( request ) ;
2018-09-12 10:26:21 -07:00
return ToOptimizedResult ( result ) ;
2014-02-20 22:04:11 -07:00
}
private ThemeMediaResult GetThemeSongs ( GetThemeSongs request )
{
2018-09-12 10:26:21 -07:00
var user = ! request . UserId . Equals ( Guid . Empty ) ? _userManager . GetUserById ( request . UserId ) : null ;
2014-02-20 22:04:11 -07:00
var item = string . IsNullOrEmpty ( request . Id )
2018-09-12 10:26:21 -07:00
? ( ! request . UserId . Equals ( Guid . Empty )
? _libraryManager . GetUserRootFolder ( )
2020-04-05 10:00:35 -07:00
: _libraryManager . RootFolder )
2014-04-25 13:15:50 -07:00
: _libraryManager . GetItemById ( request . Id ) ;
2014-02-20 22:04:11 -07:00
2017-06-11 13:40:25 -07:00
if ( item = = null )
{
throw new ResourceNotFoundException ( "Item not found." ) ;
}
2020-04-05 20:12:25 -07:00
IEnumerable < BaseItem > themeItems ;
2018-09-12 10:26:21 -07:00
2020-04-05 20:12:25 -07:00
while ( true )
2014-02-20 22:04:11 -07:00
{
2020-04-05 12:56:08 -07:00
themeItems = item . GetThemeSongs ( ) ;
2020-04-05 20:12:25 -07:00
if ( themeItems . Any ( ) | | ! request . InheritFromParent )
{
break ;
}
var parent = item . GetParent ( ) ;
if ( parent = = null )
{
break ;
}
item = parent ;
2014-02-20 22:04:11 -07:00
}
2016-11-10 07:41:24 -07:00
var dtoOptions = GetDtoOptions ( _authContext , request ) ;
2020-04-05 12:56:08 -07:00
var items = themeItems
. Select ( i = > _dtoService . GetBaseItemDto ( i , dtoOptions , user , item ) )
. ToArray ( ) ;
2014-02-20 22:04:11 -07:00
return new ThemeMediaResult
{
Items = items ,
TotalRecordCount = items . Length ,
2018-09-12 10:26:21 -07:00
OwnerId = item . Id
2014-02-20 22:04:11 -07:00
} ;
}
/// <summary>
/// Gets the specified request.
/// </summary>
/// <param name="request">The request.</param>
/// <returns>System.Object.</returns>
public object Get ( GetThemeVideos request )
{
2020-04-05 12:56:08 -07:00
return ToOptimizedResult ( GetThemeVideos ( request ) ) ;
2014-02-20 22:04:11 -07:00
}
public ThemeMediaResult GetThemeVideos ( GetThemeVideos request )
{
2018-09-12 10:26:21 -07:00
var user = ! request . UserId . Equals ( Guid . Empty ) ? _userManager . GetUserById ( request . UserId ) : null ;
2014-02-20 22:04:11 -07:00
var item = string . IsNullOrEmpty ( request . Id )
2018-09-12 10:26:21 -07:00
? ( ! request . UserId . Equals ( Guid . Empty )
? _libraryManager . GetUserRootFolder ( )
2020-04-05 10:00:35 -07:00
: _libraryManager . RootFolder )
2014-04-25 13:15:50 -07:00
: _libraryManager . GetItemById ( request . Id ) ;
2014-02-20 22:04:11 -07:00
2017-06-11 13:40:25 -07:00
if ( item = = null )
{
throw new ResourceNotFoundException ( "Item not found." ) ;
}
2020-04-05 20:12:25 -07:00
IEnumerable < BaseItem > themeItems ;
2018-09-12 10:26:21 -07:00
2020-04-05 20:12:25 -07:00
while ( true )
2014-02-20 22:04:11 -07:00
{
2020-04-05 12:56:08 -07:00
themeItems = item . GetThemeVideos ( ) ;
2020-04-05 20:12:25 -07:00
if ( themeItems . Any ( ) | | ! request . InheritFromParent )
{
break ;
}
var parent = item . GetParent ( ) ;
if ( parent = = null )
{
break ;
}
item = parent ;
2014-02-20 22:04:11 -07:00
}
2016-11-10 07:41:24 -07:00
var dtoOptions = GetDtoOptions ( _authContext , request ) ;
2014-12-26 22:08:39 -07:00
2020-04-05 12:56:08 -07:00
var items = themeItems
. Select ( i = > _dtoService . GetBaseItemDto ( i , dtoOptions , user , item ) )
. ToArray ( ) ;
2014-02-20 22:04:11 -07:00
return new ThemeMediaResult
{
Items = items ,
TotalRecordCount = items . Length ,
2018-09-12 10:26:21 -07:00
OwnerId = item . Id
2014-02-20 22:04:11 -07:00
} ;
}
2013-02-20 18:33:05 -07:00
}
}