mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-30 03:28:28 -07:00
Make the movies results random once the cache expires #2837
This commit is contained in:
parent
c1cdb91bf1
commit
fefd0c0242
4 changed files with 175 additions and 13 deletions
|
@ -1,12 +1,18 @@
|
||||||
using Ombi.Core.Models.Search;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Ombi.Core.Models.Search;
|
||||||
using Ombi.Core.Models.Search.V2;
|
using Ombi.Core.Models.Search.V2;
|
||||||
|
|
||||||
namespace Ombi.Core
|
namespace Ombi.Core.Engine.Interfaces
|
||||||
{
|
{
|
||||||
public interface IMovieEngineV2
|
public interface IMovieEngineV2
|
||||||
{
|
{
|
||||||
Task<MovieFullInfoViewModel> GetFullMovieInformation(int theMovieDbId, string langCode = null);
|
Task<MovieFullInfoViewModel> GetFullMovieInformation(int theMovieDbId, string langCode = null);
|
||||||
|
Task<IEnumerable<SearchMovieViewModel>> SimilarMovies(int theMovieDbId, string langCode);
|
||||||
|
Task<IEnumerable<SearchMovieViewModel>> PopularMovies();
|
||||||
|
Task<IEnumerable<SearchMovieViewModel>> TopRatedMovies();
|
||||||
|
Task<IEnumerable<SearchMovieViewModel>> UpcomingMovies();
|
||||||
|
Task<IEnumerable<SearchMovieViewModel>> NowPlayingMovies();
|
||||||
|
int ResultLimit { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,7 @@
|
||||||
using AutoMapper;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using AutoMapper;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Ombi.Api.TheMovieDb;
|
using Ombi.Api.TheMovieDb;
|
||||||
|
@ -14,6 +17,7 @@ using Ombi.Store.Entities;
|
||||||
using Ombi.Store.Repository;
|
using Ombi.Store.Repository;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Ombi.Core.Engine.Interfaces;
|
||||||
using Ombi.Core.Models.Search.V2;
|
using Ombi.Core.Models.Search.V2;
|
||||||
|
|
||||||
namespace Ombi.Core.Engine.V2
|
namespace Ombi.Core.Engine.V2
|
||||||
|
@ -42,6 +46,114 @@ namespace Ombi.Core.Engine.V2
|
||||||
return await ProcessSingleMovie(movieInfo);
|
return await ProcessSingleMovie(movieInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get similar movies to the id passed in
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="theMovieDbId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<IEnumerable<SearchMovieViewModel>> SimilarMovies(int theMovieDbId, string langCode)
|
||||||
|
{
|
||||||
|
langCode = await DefaultLanguageCode(langCode);
|
||||||
|
var result = await MovieApi.SimilarMovies(theMovieDbId, langCode);
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
Logger.LogDebug("Search Result: {result}", result);
|
||||||
|
return await TransformMovieResultsToResponse(result.Shuffle().Take(ResultLimit)); // Take x to stop us overloading the API
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets popular movies.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<IEnumerable<SearchMovieViewModel>> PopularMovies()
|
||||||
|
{
|
||||||
|
|
||||||
|
var result = await Cache.GetOrAdd(CacheKeys.PopularMovies, async () =>
|
||||||
|
{
|
||||||
|
var langCode = await DefaultLanguageCode(null);
|
||||||
|
return await MovieApi.PopularMovies(langCode);
|
||||||
|
}, DateTime.Now.AddHours(12));
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
return await TransformMovieResultsToResponse(result.Shuffle().Take(ResultLimit)); // Take x to stop us overloading the API
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets top rated movies.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<IEnumerable<SearchMovieViewModel>> TopRatedMovies()
|
||||||
|
{
|
||||||
|
var result = await Cache.GetOrAdd(CacheKeys.TopRatedMovies, async () =>
|
||||||
|
{
|
||||||
|
var langCode = await DefaultLanguageCode(null);
|
||||||
|
return await MovieApi.TopRated(langCode);
|
||||||
|
}, DateTime.Now.AddHours(12));
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
return await TransformMovieResultsToResponse(result.Shuffle().Take(ResultLimit)); // Take x to stop us overloading the API
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets upcoming movies.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<IEnumerable<SearchMovieViewModel>> UpcomingMovies()
|
||||||
|
{
|
||||||
|
var result = await Cache.GetOrAdd(CacheKeys.UpcomingMovies, async () =>
|
||||||
|
{
|
||||||
|
var langCode = await DefaultLanguageCode(null);
|
||||||
|
return await MovieApi.Upcoming(langCode);
|
||||||
|
}, DateTime.Now.AddHours(12));
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
Logger.LogDebug("Search Result: {result}", result);
|
||||||
|
return await TransformMovieResultsToResponse(result.Shuffle().Take(ResultLimit)); // Take x to stop us overloading the API
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets now playing movies.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<IEnumerable<SearchMovieViewModel>> NowPlayingMovies()
|
||||||
|
{
|
||||||
|
var result = await Cache.GetOrAdd(CacheKeys.NowPlayingMovies, async () =>
|
||||||
|
{
|
||||||
|
var langCode = await DefaultLanguageCode(null);
|
||||||
|
return await MovieApi.NowPlaying(langCode);
|
||||||
|
}, DateTime.Now.AddHours(12));
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
return await TransformMovieResultsToResponse(result.Shuffle().Take(ResultLimit)); // Take x to stop us overloading the API
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async Task<List<SearchMovieViewModel>> TransformMovieResultsToResponse(
|
||||||
|
IEnumerable<MovieSearchResult> movies)
|
||||||
|
{
|
||||||
|
var viewMovies = new List<SearchMovieViewModel>();
|
||||||
|
foreach (var movie in movies)
|
||||||
|
{
|
||||||
|
viewMovies.Add(await ProcessSingleMovie(movie));
|
||||||
|
}
|
||||||
|
return viewMovies;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<SearchMovieViewModel> ProcessSingleMovie(MovieSearchResult movie)
|
||||||
|
{
|
||||||
|
var viewMovie = Mapper.Map<SearchMovieViewModel>(movie);
|
||||||
|
return await ProcessSingleMovie(viewMovie);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<MovieFullInfoViewModel> ProcessSingleMovie(FullMovieInfo movie)
|
private async Task<MovieFullInfoViewModel> ProcessSingleMovie(FullMovieInfo movie)
|
||||||
{
|
{
|
||||||
var viewMovie = Mapper.Map<SearchMovieViewModel>(movie);
|
var viewMovie = Mapper.Map<SearchMovieViewModel>(movie);
|
||||||
|
@ -62,6 +174,25 @@ namespace Ombi.Core.Engine.V2
|
||||||
return mapped;
|
return mapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<SearchMovieViewModel> ProcessSingleMovie(SearchMovieViewModel viewMovie)
|
||||||
|
{
|
||||||
|
if (viewMovie.ImdbId.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
var showInfo = await MovieApi.GetMovieInformation(viewMovie.Id);
|
||||||
|
viewMovie.Id = showInfo.Id; // TheMovieDbId
|
||||||
|
viewMovie.ImdbId = showInfo.ImdbId;
|
||||||
|
}
|
||||||
|
|
||||||
|
viewMovie.TheMovieDbId = viewMovie.Id.ToString();
|
||||||
|
|
||||||
|
await RunSearchRules(viewMovie);
|
||||||
|
|
||||||
|
// This requires the rules to be run first to populate the RequestId property
|
||||||
|
await CheckForSubscription(viewMovie);
|
||||||
|
|
||||||
|
return viewMovie;
|
||||||
|
}
|
||||||
|
|
||||||
private async Task CheckForSubscription(SearchViewModel viewModel)
|
private async Task CheckForSubscription(SearchViewModel viewModel)
|
||||||
{
|
{
|
||||||
// Check if this user requested it
|
// Check if this user requested it
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace Ombi.Helpers
|
namespace Ombi.Helpers
|
||||||
{
|
{
|
||||||
|
@ -21,5 +22,31 @@ namespace Ombi.Helpers
|
||||||
{
|
{
|
||||||
return new HashSet<T>(source, comparer);
|
return new HashSet<T>(source, comparer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source)
|
||||||
|
{
|
||||||
|
return source.Shuffle(new Random());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng)
|
||||||
|
{
|
||||||
|
if (source == null) throw new ArgumentNullException(nameof(source));
|
||||||
|
if (rng == null) throw new ArgumentNullException(nameof(rng));
|
||||||
|
|
||||||
|
return source.ShuffleIterator(rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<T> ShuffleIterator<T>(
|
||||||
|
this IEnumerable<T> source, Random rng)
|
||||||
|
{
|
||||||
|
var buffer = source.ToList();
|
||||||
|
for (int i = 0; i < buffer.Count; i++)
|
||||||
|
{
|
||||||
|
int j = rng.Next(i, buffer.Count);
|
||||||
|
yield return buffer[j];
|
||||||
|
|
||||||
|
buffer[j] = buffer[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -18,20 +18,18 @@ namespace Ombi.Controllers.V2
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class SearchController : ControllerBase
|
public class SearchController : ControllerBase
|
||||||
{
|
{
|
||||||
public SearchController(IMultiSearchEngine multiSearchEngine, IMovieEngine movieEngine,
|
public SearchController(IMultiSearchEngine multiSearchEngine,
|
||||||
ITvSearchEngine tvSearchEngine, IMovieEngineV2 v2Movie, ITVSearchEngineV2 v2Tv)
|
ITvSearchEngine tvSearchEngine, IMovieEngineV2 v2Movie, ITVSearchEngineV2 v2Tv)
|
||||||
{
|
{
|
||||||
_multiSearchEngine = multiSearchEngine;
|
_multiSearchEngine = multiSearchEngine;
|
||||||
_movieEngine = movieEngine;
|
|
||||||
_movieEngine.ResultLimit = 12;
|
|
||||||
_tvSearchEngine = tvSearchEngine;
|
_tvSearchEngine = tvSearchEngine;
|
||||||
_tvSearchEngine.ResultLimit = 12;
|
_tvSearchEngine.ResultLimit = 12;
|
||||||
_movieEngineV2 = v2Movie;
|
_movieEngineV2 = v2Movie;
|
||||||
|
_movieEngineV2.ResultLimit = 12;
|
||||||
_tvEngineV2 = v2Tv;
|
_tvEngineV2 = v2Tv;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly IMultiSearchEngine _multiSearchEngine;
|
private readonly IMultiSearchEngine _multiSearchEngine;
|
||||||
private readonly IMovieEngine _movieEngine;
|
|
||||||
private readonly IMovieEngineV2 _movieEngineV2;
|
private readonly IMovieEngineV2 _movieEngineV2;
|
||||||
private readonly ITVSearchEngineV2 _tvEngineV2;
|
private readonly ITVSearchEngineV2 _tvEngineV2;
|
||||||
private readonly ITvSearchEngine _tvSearchEngine;
|
private readonly ITvSearchEngine _tvSearchEngine;
|
||||||
|
@ -78,7 +76,7 @@ namespace Ombi.Controllers.V2
|
||||||
[ProducesDefaultResponseType]
|
[ProducesDefaultResponseType]
|
||||||
public async Task<IEnumerable<SearchMovieViewModel>> SimilarMovies([FromBody] SimilarMoviesRefineModel model)
|
public async Task<IEnumerable<SearchMovieViewModel>> SimilarMovies([FromBody] SimilarMoviesRefineModel model)
|
||||||
{
|
{
|
||||||
return await _movieEngine.SimilarMovies(model.TheMovieDbId, model.LanguageCode);
|
return await _movieEngineV2.SimilarMovies(model.TheMovieDbId, model.LanguageCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -92,7 +90,7 @@ namespace Ombi.Controllers.V2
|
||||||
[ProducesDefaultResponseType]
|
[ProducesDefaultResponseType]
|
||||||
public async Task<IEnumerable<SearchMovieViewModel>> Popular()
|
public async Task<IEnumerable<SearchMovieViewModel>> Popular()
|
||||||
{
|
{
|
||||||
return await _movieEngine.PopularMovies();
|
return await _movieEngineV2.PopularMovies();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -105,7 +103,7 @@ namespace Ombi.Controllers.V2
|
||||||
[ProducesDefaultResponseType]
|
[ProducesDefaultResponseType]
|
||||||
public async Task<IEnumerable<SearchMovieViewModel>> NowPlayingMovies()
|
public async Task<IEnumerable<SearchMovieViewModel>> NowPlayingMovies()
|
||||||
{
|
{
|
||||||
return await _movieEngine.NowPlayingMovies();
|
return await _movieEngineV2.NowPlayingMovies();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -118,7 +116,7 @@ namespace Ombi.Controllers.V2
|
||||||
[ProducesDefaultResponseType]
|
[ProducesDefaultResponseType]
|
||||||
public async Task<IEnumerable<SearchMovieViewModel>> TopRatedMovies()
|
public async Task<IEnumerable<SearchMovieViewModel>> TopRatedMovies()
|
||||||
{
|
{
|
||||||
return await _movieEngine.TopRatedMovies();
|
return await _movieEngineV2.TopRatedMovies();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -131,7 +129,7 @@ namespace Ombi.Controllers.V2
|
||||||
[ProducesDefaultResponseType]
|
[ProducesDefaultResponseType]
|
||||||
public async Task<IEnumerable<SearchMovieViewModel>> UpcomingMovies()
|
public async Task<IEnumerable<SearchMovieViewModel>> UpcomingMovies()
|
||||||
{
|
{
|
||||||
return await _movieEngine.UpcomingMovies();
|
return await _movieEngineV2.UpcomingMovies();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue