Browse Source

add tv suggestions

Luke Pulverenti 9 years ago
parent
commit
ddcebc4ff7

+ 124 - 2
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)

+ 24 - 5
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(),

+ 1 - 38
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;

+ 50 - 0
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>

+ 0 - 2
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;

+ 1 - 0
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; }

+ 0 - 1
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; }

+ 1 - 47
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.
@@ -442,20 +410,6 @@ namespace MediaBrowser.Model.ApiClient
         /// <returns>Task{ItemsResult}.</returns>
         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>

+ 9 - 0
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>

+ 3 - 1
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));

+ 4 - 3
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;
         }
     }
 }