diff --git a/Ombi.Api/TheMovieDbApi.cs b/Ombi.Api/TheMovieDbApi.cs index ad3f01251..7a072caa4 100644 --- a/Ombi.Api/TheMovieDbApi.cs +++ b/Ombi.Api/TheMovieDbApi.cs @@ -69,6 +69,11 @@ namespace Ombi.Api return movies?.Results ?? new List(); } + private async Task GetMovie(int id) + { + return await Client.GetMovie(id); + } + public TmdbMovieDetails GetMovieInformationWithVideos(int tmdbId) { var request = new RestRequest { Resource = "movie/{movieId}", Method = Method.GET }; @@ -100,5 +105,33 @@ namespace Ombi.Api var movies = await Client.GetMovie(imdbId); return movies ?? new Movie(); } + + public async Task> SearchActor(string searchTerm) + { + SearchContainer result = await Client.SearchPerson(searchTerm); + var person = result?.Results[0] ?? null; + var movies = new List(); + var counter = 0; + try + { + if (person != null) + { + var credits = await Client.GetPersonMovieCredits(person.Id); + //only get the first 10 movies and delay a bit between each request so we don't overload the API + foreach (var credit in credits.Cast) + { if (counter == 10) + break; + movies.Add(await GetMovie(credit.Id)); + counter++; + await Task.Delay(50); + } + } + } + catch(Exception e) + { + Log.LogException(LogLevel.Error, $"Aggregating movies for {searchTerm} failed.", e); + } + return movies; + } } } diff --git a/Ombi.Core/SettingModels/PlexRequestSettings.cs b/Ombi.Core/SettingModels/PlexRequestSettings.cs index 6c77ba727..026c84c24 100644 --- a/Ombi.Core/SettingModels/PlexRequestSettings.cs +++ b/Ombi.Core/SettingModels/PlexRequestSettings.cs @@ -41,6 +41,7 @@ namespace Ombi.Core.SettingModels public int Port { get; set; } public string BaseUrl { get; set; } public bool SearchForMovies { get; set; } + public bool SearchForActors { get; set; } public bool SearchForTvShows { get; set; } public bool SearchForMusic { get; set; } [Obsolete("Use the user management settings")] diff --git a/Ombi.Core/Setup.cs b/Ombi.Core/Setup.cs index f70749a40..c7df43ed3 100644 --- a/Ombi.Core/Setup.cs +++ b/Ombi.Core/Setup.cs @@ -77,6 +77,7 @@ namespace Ombi.Core { SearchForMovies = true, SearchForTvShows = true, + SearchForActors = true, BaseUrl = baseUrl ?? string.Empty, CollectAnalyticData = true, }; diff --git a/Ombi.UI/Modules/SearchModule.cs b/Ombi.UI/Modules/SearchModule.cs index 4aa29c316..601ba1914 100644 --- a/Ombi.UI/Modules/SearchModule.cs +++ b/Ombi.UI/Modules/SearchModule.cs @@ -115,6 +115,7 @@ namespace Ombi.UI.Modules Get["SearchIndex", "/", true] = async (x, ct) => await RequestLoad(); + Get["actor/{searchTerm}", true] = async (x, ct) => await SearchActor((string)x.searchTerm); Get["movie/{searchTerm}", true] = async (x, ct) => await SearchMovie((string)x.searchTerm); Get["tv/{searchTerm}", true] = async (x, ct) => await SearchTvShow((string)x.searchTerm); Get["music/{searchTerm}", true] = async (x, ct) => await SearchAlbum((string)x.searchTerm); @@ -209,6 +210,12 @@ namespace Ombi.UI.Modules return await ProcessMovies(MovieSearchType.Search, searchTerm); } + private async Task SearchActor(string searchTerm) + { + var movies = TransformMovieListToMovieResultList(await MovieApi.SearchActor(searchTerm).ConfigureAwait(false)); + return await TransformMovieResultsToResponse(movies); + } + private Response GetTvPoster(int theTvDbId) { var result = TvApi.ShowLookupByTheTvDbId(theTvDbId); @@ -220,15 +227,10 @@ namespace Ombi.UI.Modules } return banner; } - private async Task ProcessMovies(MovieSearchType searchType, string searchTerm) - { - List apiMovies; - switch (searchType) - { - case MovieSearchType.Search: - var movies = await MovieApi.SearchMovie(searchTerm).ConfigureAwait(false); - apiMovies = movies.Select(x => + private List TransformSearchMovieListToMovieResultList(List searchMovies) + { + return searchMovies.Select(x => new MovieResult { Adult = x.Adult, @@ -247,6 +249,39 @@ namespace Ombi.UI.Modules VoteCount = x.VoteCount }) .ToList(); + } + + private List TransformMovieListToMovieResultList(List movies) + { + return movies.Select(x => + new MovieResult + { + Adult = x.Adult, + BackdropPath = x.BackdropPath, + GenreIds = x.Genres.Select(y => y.Id).ToList(), + Id = x.Id, + OriginalLanguage = x.OriginalLanguage, + OriginalTitle = x.OriginalTitle, + Overview = x.Overview, + Popularity = x.Popularity, + PosterPath = x.PosterPath, + ReleaseDate = x.ReleaseDate, + Title = x.Title, + Video = x.Video, + VoteAverage = x.VoteAverage, + VoteCount = x.VoteCount + }) + .ToList(); + } + private async Task ProcessMovies(MovieSearchType searchType, string searchTerm) + { + List apiMovies; + + switch (searchType) + { + case MovieSearchType.Search: + var movies = await MovieApi.SearchMovie(searchTerm).ConfigureAwait(false); + apiMovies = TransformSearchMovieListToMovieResultList(movies); break; case MovieSearchType.CurrentlyPlaying: apiMovies = await MovieApi.GetCurrentPlayingMovies(); @@ -259,6 +294,11 @@ namespace Ombi.UI.Modules break; } + return await TransformMovieResultsToResponse(apiMovies); + } + + private async Task TransformMovieResultsToResponse(List movies) + { var allResults = await RequestService.GetAllAsync(); allResults = allResults.Where(x => x.Type == RequestType.Movie); @@ -273,7 +313,7 @@ namespace Ombi.UI.Modules var plexMovies = Checker.GetPlexMovies(content); var viewMovies = new List(); var counter = 0; - foreach (var movie in apiMovies) + foreach (var movie in movies) { var viewMovie = new SearchMovieViewModel { @@ -297,7 +337,7 @@ namespace Ombi.UI.Modules if (counter <= 5) // Let's only do it for the first 5 items { var movieInfo = MovieApi.GetMovieInformationWithVideos(movie.Id); - + // TODO needs to be careful about this, it's adding extra time to search... // https://www.themoviedb.org/talk/5807f4cdc3a36812160041f2 viewMovie.ImdbId = movieInfo?.imdb_id; @@ -313,7 +353,7 @@ namespace Ombi.UI.Modules counter++; } - + var canSee = CanUserSeeThisRequest(viewMovie.Id, Security.HasPermissions(User, Permissions.UsersCanViewOnlyOwnRequests), dbMovies); var plexMovie = Checker.GetMovie(plexMovies.ToArray(), movie.Title, movie.ReleaseDate?.Year.ToString(), imdbId); @@ -335,7 +375,7 @@ namespace Ombi.UI.Modules viewMovie.Approved = true; viewMovie.Requested = true; } - else if(watcherCached.Contains(imdbId) && canSee) // compare to the watcher db + else if (watcherCached.Contains(imdbId) && canSee) // compare to the watcher db { viewMovie.Approved = true; viewMovie.Requested = true; @@ -349,6 +389,7 @@ namespace Ombi.UI.Modules } return Response.AsJson(viewMovies); + } private bool CanUserSeeThisRequest(int movieId, bool usersCanViewOnlyOwnRequests,