diff options
| -rw-r--r-- | MediaBrowser.Api/Library/LibraryService.cs | 126 | ||||
| -rw-r--r-- | MediaBrowser.Api/Movies/MoviesService.cs | 29 | ||||
| -rw-r--r-- | MediaBrowser.Api/Movies/TrailersService.cs | 39 | ||||
| -rw-r--r-- | MediaBrowser.Api/Music/AlbumsService.cs | 50 | ||||
| -rw-r--r-- | MediaBrowser.Api/UserLibrary/GenresService.cs | 2 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Entities/IHasProgramAttributes.cs | 1 | ||||
| -rw-r--r-- | MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs | 1 | ||||
| -rw-r--r-- | MediaBrowser.Model/ApiClient/IApiClient.cs | 48 | ||||
| -rw-r--r-- | MediaBrowser.Model/Dto/BaseItemDto.cs | 9 | ||||
| -rw-r--r-- | MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs | 4 | ||||
| -rw-r--r-- | MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs | 7 |
11 files changed, 217 insertions, 99 deletions
diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index 50c4ad14f..945e803b2 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -1,4 +1,7 @@ -using MediaBrowser.Controller.Activity; +using MediaBrowser.Api.Movies; +using MediaBrowser.Api.Music; +using MediaBrowser.Controller.Activity; +using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; @@ -9,7 +12,9 @@ using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Persistence; +using MediaBrowser.Controller.TV; using MediaBrowser.Model.Activity; +using MediaBrowser.Model.Channels; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; @@ -238,6 +243,12 @@ namespace MediaBrowser.Api.Library public string Id { get; set; } } + [Route("/Items/{Id}/Similar", "GET", Summary = "Downloads item media")] + [Authenticated(Roles = "download")] + public class GetSimilarItems : BaseGetSimilarItemsFromItem + { + } + /// <summary> /// Class LibraryService /// </summary> @@ -257,12 +268,14 @@ namespace MediaBrowser.Api.Library private readonly IActivityManager _activityManager; private readonly ILocalizationManager _localization; private readonly ILiveTvManager _liveTv; + private readonly IChannelManager _channelManager; + private readonly ITVSeriesManager _tvManager; /// <summary> /// Initializes a new instance of the <see cref="LibraryService" /> class. /// </summary> public LibraryService(IItemRepository itemRepo, ILibraryManager libraryManager, IUserManager userManager, - IDtoService dtoService, IUserDataManager userDataManager, IAuthorizationContext authContext, IActivityManager activityManager, ILocalizationManager localization, ILiveTvManager liveTv) + IDtoService dtoService, IUserDataManager userDataManager, IAuthorizationContext authContext, IActivityManager activityManager, ILocalizationManager localization, ILiveTvManager liveTv, IChannelManager channelManager, ITVSeriesManager tvManager) { _itemRepo = itemRepo; _libraryManager = libraryManager; @@ -273,6 +286,115 @@ namespace MediaBrowser.Api.Library _activityManager = activityManager; _localization = localization; _liveTv = liveTv; + _channelManager = channelManager; + _tvManager = tvManager; + } + + public object Get(GetSimilarItems request) + { + var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; + + var item = string.IsNullOrEmpty(request.Id) ? + (!string.IsNullOrWhiteSpace(request.UserId) ? user.RootFolder : + _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id); + + if (item is Game) + { + return new GamesService(_userManager, _userDataManager, _libraryManager, _itemRepo, _dtoService) + { + AuthorizationContext = AuthorizationContext, + Logger = Logger, + Request = Request, + SessionContext = SessionContext, + ResultFactory = ResultFactory + + }.Get(new GetSimilarGames + { + Fields = request.Fields, + Id = request.Id, + Limit = request.Limit, + UserId = request.UserId + }); + } + if (item is MusicAlbum) + { + return new AlbumsService(_userManager, _userDataManager, _libraryManager, _itemRepo, _dtoService) + { + AuthorizationContext = AuthorizationContext, + Logger = Logger, + Request = Request, + SessionContext = SessionContext, + ResultFactory = ResultFactory + + }.Get(new GetSimilarAlbums + { + Fields = request.Fields, + Id = request.Id, + Limit = request.Limit, + UserId = request.UserId + }); + } + if (item is MusicArtist) + { + return new AlbumsService(_userManager, _userDataManager, _libraryManager, _itemRepo, _dtoService) + { + AuthorizationContext = AuthorizationContext, + Logger = Logger, + Request = Request, + SessionContext = SessionContext, + ResultFactory = ResultFactory + + }.Get(new GetSimilarArtists + { + Fields = request.Fields, + Id = request.Id, + Limit = request.Limit, + UserId = request.UserId + }); + } + + var program = item as IHasProgramAttributes; + var channelItem = item as ChannelVideoItem; + + if (item is Movie || (program != null && program.IsMovie) || (channelItem != null && channelItem.ContentType == ChannelMediaContentType.Movie && channelItem.ContentType == ChannelMediaContentType.MovieExtra)) + { + return new MoviesService(_userManager, _userDataManager, _libraryManager, _itemRepo, _dtoService, _channelManager) + { + AuthorizationContext = AuthorizationContext, + Logger = Logger, + Request = Request, + SessionContext = SessionContext, + ResultFactory = ResultFactory + + }.Get(new GetSimilarMovies + { + Fields = request.Fields, + Id = request.Id, + Limit = request.Limit, + UserId = request.UserId + }); + } + + if (item is Series || (program != null && program.IsSeries) || (channelItem != null && channelItem.ContentType == ChannelMediaContentType.Episode)) + { + return new TvShowsService(_userManager, _userDataManager, _libraryManager, _itemRepo, _dtoService, _tvManager) + { + AuthorizationContext = AuthorizationContext, + Logger = Logger, + Request = Request, + SessionContext = SessionContext, + ResultFactory = ResultFactory + + }.Get(new GetSimilarShows + { + Fields = request.Fields, + Id = request.Id, + Limit = request.Limit, + UserId = request.UserId + }); + } + + return new ItemsResult(); } public object Get(GetMediaFolders request) diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs index 97e9aa9c8..fe8bae1a5 100644 --- a/MediaBrowser.Api/Movies/MoviesService.cs +++ b/MediaBrowser.Api/Movies/MoviesService.cs @@ -28,6 +28,14 @@ namespace MediaBrowser.Api.Movies { } + /// <summary> + /// Class GetSimilarTrailers + /// </summary> + [Route("/Trailers/{Id}/Similar", "GET", Summary = "Finds movies and trailers similar to a given trailer.")] + public class GetSimilarTrailers : BaseGetSimilarItemsFromItem + { + } + [Route("/Movies/Recommendations", "GET", Summary = "Gets movie recommendations")] public class GetMovieRecommendations : IReturn<RecommendationDto[]>, IHasItemFields { @@ -117,6 +125,17 @@ namespace MediaBrowser.Api.Movies return ToOptimizedSerializedResultUsingCache(result); } + public async Task<object> Get(GetSimilarTrailers request) + { + var result = await GetSimilarItemsResult( + // Strip out secondary versions + request, item => (item is Movie) && !((Video)item).PrimaryVersionId.HasValue, + + SimilarItemsHelper.GetSimiliarityScore).ConfigureAwait(false); + + return ToOptimizedSerializedResultUsingCache(result); + } + public async Task<object> Get(GetMovieRecommendations request) { var user = _userManager.GetUserById(request.UserId); @@ -126,7 +145,7 @@ namespace MediaBrowser.Api.Movies movies = _libraryManager.ReplaceVideosWithPrimaryVersions(movies); var listEligibleForCategories = new List<BaseItem>(); - var listEligibleForSuggestion = new List<BaseItem> (); + var listEligibleForSuggestion = new List<BaseItem>(); var list = movies.ToList(); @@ -159,7 +178,7 @@ namespace MediaBrowser.Api.Movies var dtoOptions = GetDtoOptions(request); dtoOptions.Fields = request.GetItemFields().ToList(); - + var result = GetRecommendationCategories(user, listEligibleForCategories, listEligibleForSuggestion, request.CategoryLimit, request.ItemLimit, dtoOptions); return ToOptimizedResult(result); @@ -174,14 +193,14 @@ namespace MediaBrowser.Api.Movies _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id); Func<BaseItem, bool> filter = i => i.Id != item.Id && includeInSearch(i); - + var inputItems = user == null ? _libraryManager.RootFolder.GetRecursiveChildren(filter) : user.RootFolder.GetRecursiveChildren(user, filter); var list = inputItems.ToList(); - if (item is Movie && user != null && user.Configuration.IncludeTrailersInSuggestions) + if (user != null && user.Configuration.IncludeTrailersInSuggestions) { var trailerResult = await _channelManager.GetAllMediaInternal(new AllChannelMediaQuery { @@ -224,7 +243,7 @@ namespace MediaBrowser.Api.Movies } var dtoOptions = GetDtoOptions(request); - + var result = new ItemsResult { Items = _dtoService.GetBaseItemDtos(returnItems, dtoOptions, user).ToArray(), diff --git a/MediaBrowser.Api/Movies/TrailersService.cs b/MediaBrowser.Api/Movies/TrailersService.cs index 0847fc7ed..ed197911a 100644 --- a/MediaBrowser.Api/Movies/TrailersService.cs +++ b/MediaBrowser.Api/Movies/TrailersService.cs @@ -2,15 +2,12 @@ using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Net; -using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Channels; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; using ServiceStack; -using System; using System.Collections.Generic; using System.Linq; using System.Threading; @@ -18,14 +15,6 @@ using System.Threading.Tasks; namespace MediaBrowser.Api.Movies { - /// <summary> - /// Class GetSimilarTrailers - /// </summary> - [Route("/Trailers/{Id}/Similar", "GET", Summary = "Finds movies and trailers similar to a given trailer.")] - public class GetSimilarTrailers : BaseGetSimilarItemsFromItem - { - } - [Route("/Trailers", "GET", Summary = "Finds movies and trailers similar to a given trailer.")] public class Getrailers : BaseItemsRequest, IReturn<ItemsResult> { @@ -51,7 +40,6 @@ namespace MediaBrowser.Api.Movies /// </summary> private readonly ILibraryManager _libraryManager; - private readonly IItemRepository _itemRepo; private readonly IDtoService _dtoService; private readonly IChannelManager _channelManager; @@ -61,40 +49,15 @@ namespace MediaBrowser.Api.Movies /// <param name="userManager">The user manager.</param> /// <param name="userDataRepository">The user data repository.</param> /// <param name="libraryManager">The library manager.</param> - public TrailersService(IUserManager userManager, IUserDataManager userDataRepository, ILibraryManager libraryManager, IItemRepository itemRepo, IDtoService dtoService, IChannelManager channelManager) + public TrailersService(IUserManager userManager, IUserDataManager userDataRepository, ILibraryManager libraryManager, IDtoService dtoService, IChannelManager channelManager) { _userManager = userManager; _userDataRepository = userDataRepository; _libraryManager = libraryManager; - _itemRepo = itemRepo; _dtoService = dtoService; _channelManager = channelManager; } - /// <summary> - /// Gets the specified request. - /// </summary> - /// <param name="request">The request.</param> - /// <returns>System.Object.</returns> - public object Get(GetSimilarTrailers request) - { - var dtoOptions = GetDtoOptions(request); - - var result = SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager, - _itemRepo, - _libraryManager, - _userDataRepository, - _dtoService, - Logger, - - // Strip out secondary versions - request, item => (item is Movie) && !((Video)item).PrimaryVersionId.HasValue, - - SimilarItemsHelper.GetSimiliarityScore); - - return ToOptimizedSerializedResultUsingCache(result); - } - public async Task<object> Get(Getrailers request) { var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; diff --git a/MediaBrowser.Api/Music/AlbumsService.cs b/MediaBrowser.Api/Music/AlbumsService.cs index ea87c3ad3..548598d42 100644 --- a/MediaBrowser.Api/Music/AlbumsService.cs +++ b/MediaBrowser.Api/Music/AlbumsService.cs @@ -4,6 +4,7 @@ using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Persistence; +using MediaBrowser.Model.Querying; using ServiceStack; using System; using System.Collections.Generic; @@ -16,6 +17,11 @@ namespace MediaBrowser.Api.Music { } + [Route("/Artists/{Id}/Similar", "GET", Summary = "Finds albums similar to a given album.")] + public class GetSimilarArtists : BaseGetSimilarItemsFromItem + { + } + [Authenticated] public class AlbumsService : BaseApiService { @@ -44,6 +50,17 @@ namespace MediaBrowser.Api.Music _dtoService = dtoService; } + public object Get(GetSimilarArtists request) + { + var result = GetSimilarItemsResult( + + request, + + SimilarItemsHelper.GetSimiliarityScore); + + return ToOptimizedSerializedResultUsingCache(result); + } + /// <summary> /// Gets the specified request. /// </summary> @@ -65,6 +82,39 @@ namespace MediaBrowser.Api.Music return ToOptimizedSerializedResultUsingCache(result); } + private ItemsResult GetSimilarItemsResult(BaseGetSimilarItemsFromItem request, Func<BaseItem, List<PersonInfo>, List<PersonInfo>, BaseItem, int> getSimilarityScore) + { + var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; + + var item = string.IsNullOrEmpty(request.Id) ? + (!string.IsNullOrWhiteSpace(request.UserId) ? user.RootFolder : + _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id); + + var inputItems = _libraryManager.GetArtists(user.RootFolder.GetRecursiveChildren(user, i => i is IHasArtist).OfType<IHasArtist>()); + + var list = inputItems.ToList(); + + var items = SimilarItemsHelper.GetSimilaritems(item, _libraryManager, list, getSimilarityScore).ToList(); + + IEnumerable<BaseItem> returnItems = items; + + if (request.Limit.HasValue) + { + returnItems = returnItems.Take(request.Limit.Value); + } + + var dtoOptions = GetDtoOptions(request); + + var result = new ItemsResult + { + Items = _dtoService.GetBaseItemDtos(returnItems, dtoOptions, user).ToArray(), + + TotalRecordCount = items.Count + }; + + return result; + } + /// <summary> /// Gets the album similarity score. /// </summary> diff --git a/MediaBrowser.Api/UserLibrary/GenresService.cs b/MediaBrowser.Api/UserLibrary/GenresService.cs index 9e56907da..d383bd0ad 100644 --- a/MediaBrowser.Api/UserLibrary/GenresService.cs +++ b/MediaBrowser.Api/UserLibrary/GenresService.cs @@ -1,12 +1,10 @@ using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Querying; using ServiceStack; using System; using System.Collections.Generic; diff --git a/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs b/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs index 391c8f7a7..9938a4489 100644 --- a/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs +++ b/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs @@ -11,6 +11,7 @@ namespace MediaBrowser.Controller.Entities bool IsKids { get; set; } bool IsRepeat { get; set; } bool? IsHD { get; set; } + bool IsSeries { get; set; } bool IsLive { get; set; } bool IsPremiere { get; set; } ProgramAudio? Audio { get; set; } diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs b/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs index 9fc60beb9..ba0b82a0b 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs @@ -37,7 +37,6 @@ namespace MediaBrowser.Controller.LiveTv string ExternalId { get; set; } string EpisodeTitle { get; set; } - bool IsSeries { get; set; } string SeriesTimerId { get; set; } RecordingStatus Status { get; set; } DateTime? EndDate { get; set; } diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs index e52e7535b..6d441ccf8 100644 --- a/MediaBrowser.Model/ApiClient/IApiClient.cs +++ b/MediaBrowser.Model/ApiClient/IApiClient.cs @@ -353,39 +353,7 @@ namespace MediaBrowser.Model.ApiClient /// <param name="query">The query.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{ItemsResult}.</returns> - Task<ItemsResult> GetSimilarMoviesAsync(SimilarItemsQuery query, CancellationToken cancellationToken = default(CancellationToken)); - - /// <summary> - /// Gets the similar trailers async. - /// </summary> - /// <param name="query">The query.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task{ItemsResult}.</returns> - Task<ItemsResult> GetSimilarTrailersAsync(SimilarItemsQuery query, CancellationToken cancellationToken = default(CancellationToken)); - - /// <summary> - /// Gets the similar series async. - /// </summary> - /// <param name="query">The query.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task{ItemsResult}.</returns> - Task<ItemsResult> GetSimilarSeriesAsync(SimilarItemsQuery query, CancellationToken cancellationToken = default(CancellationToken)); - - /// <summary> - /// Gets the similar albums async. - /// </summary> - /// <param name="query">The query.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task{ItemsResult}.</returns> - Task<ItemsResult> GetSimilarAlbumsAsync(SimilarItemsQuery query, CancellationToken cancellationToken = default(CancellationToken)); - - /// <summary> - /// Gets the similar games async. - /// </summary> - /// <param name="query">The query.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task{ItemsResult}.</returns> - Task<ItemsResult> GetSimilarGamesAsync(SimilarItemsQuery query, CancellationToken cancellationToken = default(CancellationToken)); + Task<ItemsResult> GetSimilarItemsAsync(SimilarItemsQuery query, CancellationToken cancellationToken = default(CancellationToken)); /// <summary> /// Gets the people async. @@ -443,20 +411,6 @@ namespace MediaBrowser.Model.ApiClient Task<ItemsResult> GetGenresAsync(ItemsByNameQuery query); /// <summary> - /// Gets the music genres async. - /// </summary> - /// <param name="query">The query.</param> - /// <returns>Task{ItemsResult}.</returns> - Task<ItemsResult> GetMusicGenresAsync(ItemsByNameQuery query); - - /// <summary> - /// Gets the game genres async. - /// </summary> - /// <param name="query">The query.</param> - /// <returns>Task{ItemsResult}.</returns> - Task<ItemsResult> GetGameGenresAsync(ItemsByNameQuery query); - - /// <summary> /// Gets the studios async. /// </summary> /// <param name="query">The query.</param> diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index aa68e09a0..ac8fa3370 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -1081,6 +1081,15 @@ namespace MediaBrowser.Model.Dto get { return StringHelper.EqualsIgnoreCase(Type, "Studio"); } } + [IgnoreDataMember] + public bool SupportsSimilarItems + { + get + { + return IsType("Movie") || IsType("Series") || IsType("MusicAlbum") || IsType("MusicArtist") || IsType("Program") || IsType("Recording") || IsType("ChannelVideoItem") || IsType("Game"); + } + } + /// <summary> /// Occurs when [property changed]. /// </summary> diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index ebb5037d0..200c6c9a6 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -517,7 +517,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV recordPath = Path.Combine(recordPath, "TV", _fileSystem.GetValidFilename(info.Name)); } - recordPath = Path.Combine(recordPath, _fileSystem.GetValidFilename(RecordingHelper.GetRecordingName(timer, info))); + var recordingFileName = _fileSystem.GetValidFilename(RecordingHelper.GetRecordingName(timer, info)) + ".ts"; + + recordPath = Path.Combine(recordPath, recordingFileName); Directory.CreateDirectory(Path.GetDirectoryName(recordPath)); var recording = _recordingProvider.GetAll().FirstOrDefault(x => string.Equals(x.ProgramId, info.Id, StringComparison.OrdinalIgnoreCase)); diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs index 1b8cd2e61..f8f65c6d5 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs @@ -37,7 +37,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { if (info == null) { - return timer.ProgramId + ".ts"; + return timer.ProgramId; } var name = info.Name; @@ -52,7 +52,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { name += " " + info.OriginalAirDate.Value.ToString("yyyy-MM-dd"); } - else if (!string.IsNullOrWhiteSpace(info.EpisodeTitle)) + + if (!string.IsNullOrWhiteSpace(info.EpisodeTitle)) { name += " " + info.EpisodeTitle; } @@ -63,7 +64,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV name += " (" + info.ProductionYear + ")"; } - return name + ".ts"; + return name; } } } |
