diff --git a/src/Ombi.Core/Engine/Interfaces/IMovieEngineV2.cs b/src/Ombi.Core/Engine/Interfaces/IMovieEngineV2.cs index 5a3624c5e..2d86443d1 100644 --- a/src/Ombi.Core/Engine/Interfaces/IMovieEngineV2.cs +++ b/src/Ombi.Core/Engine/Interfaces/IMovieEngineV2.cs @@ -29,5 +29,6 @@ namespace Ombi.Core.Engine.Interfaces Task> GetStreamInformation(int movieDbId, CancellationToken cancellationToken); Task> RecentlyRequestedMovies(int currentlyLoaded, int toLoad, CancellationToken cancellationToken); Task> SeasonalList(int currentPosition, int amountToLoad, CancellationToken cancellationToken); + Task> AdvancedSearch(DiscoverModel model, int currentlyLoaded, int toLoad, CancellationToken cancellationToken); } } \ No newline at end of file diff --git a/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs b/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs index 25c0fc2a2..acc390aec 100644 --- a/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs +++ b/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs @@ -137,7 +137,22 @@ namespace Ombi.Core.Engine.V2 foreach (var pagesToLoad in pages) { var apiResult = await Cache.GetOrAddAsync(nameof(PopularMovies) + pagesToLoad.Page + langCode, - () => MovieApi.PopularMovies(langCode, pagesToLoad.Page, cancellationToken), DateTimeOffset.Now.AddHours(12)); + () => MovieApi.PopularMovies(langCode, pagesToLoad.Page, cancellationToken), DateTimeOffset.Now.AddHours(12)); + results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take)); + } + return await TransformMovieResultsToResponse(results); + } + + public async Task> AdvancedSearch(DiscoverModel model, int currentlyLoaded, int toLoad, CancellationToken cancellationToken) + { + var langCode = await DefaultLanguageCode(null); + + var pages = PaginationHelper.GetNextPages(currentlyLoaded, toLoad, _theMovieDbMaxPageItems); + + var results = new List(); + foreach (var pagesToLoad in pages) + { + var apiResult = await MovieApi.AdvancedSearch(model, cancellationToken); results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take)); } return await TransformMovieResultsToResponse(results); diff --git a/src/Ombi.TheMovieDbApi/IMovieDbApi.cs b/src/Ombi.TheMovieDbApi/IMovieDbApi.cs index 202392c5f..6d0859cef 100644 --- a/src/Ombi.TheMovieDbApi/IMovieDbApi.cs +++ b/src/Ombi.TheMovieDbApi/IMovieDbApi.cs @@ -40,5 +40,7 @@ namespace Ombi.Api.TheMovieDb Task GetMovieWatchProviders(int theMoviedbId, CancellationToken token); Task GetTvWatchProviders(int theMoviedbId, CancellationToken token); Task> GetGenres(string media, CancellationToken cancellationToken); + Task> SearchWatchProviders(string media, string searchTerm, CancellationToken cancellationToken); + Task> AdvancedSearch(DiscoverModel model, CancellationToken cancellationToken); } } diff --git a/src/Ombi.TheMovieDbApi/Models/DiscoverModel.cs b/src/Ombi.TheMovieDbApi/Models/DiscoverModel.cs new file mode 100644 index 000000000..53f3bfb21 --- /dev/null +++ b/src/Ombi.TheMovieDbApi/Models/DiscoverModel.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Ombi.Api.TheMovieDb.Models +{ + public class DiscoverModel + { + public string Type { get; set; } + public int? ReleaseYear { get; set; } + public List GenreIds { get; set; } = new List(); + public List KeywordIds { get; set; } = new List(); + public List WatchProviders { get; set; } = new List(); + public List Companies { get; set; } = new List(); + } +} diff --git a/src/Ombi.TheMovieDbApi/Models/DiscoverTv.cs b/src/Ombi.TheMovieDbApi/Models/DiscoverTv.cs new file mode 100644 index 000000000..3edb7320b --- /dev/null +++ b/src/Ombi.TheMovieDbApi/Models/DiscoverTv.cs @@ -0,0 +1,21 @@ +namespace Ombi.Api.TheMovieDb.Models { + + public class DiscoverTv + { + public int vote_count { get; set; } + public int id { get; set; } + public bool video { get; set; } + public float vote_average { get; set; } + public string title { get; set; } + public float popularity { get; set; } + public string poster_path { get; set; } + public string original_language { get; set; } + public string original_title { get; set; } + public int[] genre_ids { get; set; } + public string backdrop_path { get; set; } + public bool adult { get; set; } + public string overview { get; set; } + public string release_date { get; set; } + } + +} \ No newline at end of file diff --git a/src/Ombi.TheMovieDbApi/Models/WatchProvidersResults.cs b/src/Ombi.TheMovieDbApi/Models/WatchProvidersResults.cs new file mode 100644 index 000000000..44462018b --- /dev/null +++ b/src/Ombi.TheMovieDbApi/Models/WatchProvidersResults.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Ombi.Api.TheMovieDb.Models +{ + public class WatchProvidersResults + { + public int provider_id { get; set; } + public string logo_path { get; set; } + public string provider_name { get; set; } + public string origin_country { get; set; } + } +} diff --git a/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs b/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs index a8fdc3269..7e89b48fd 100644 --- a/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs +++ b/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs @@ -68,6 +68,34 @@ namespace Ombi.Api.TheMovieDb return await Api.Request>(request); } + + + public async Task> AdvancedSearch(DiscoverModel model, CancellationToken cancellationToken) + { + var request = new Request($"discover/{model.Type}", BaseUri, HttpMethod.Get); + request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken); + if(model.ReleaseYear.HasValue && model.ReleaseYear.Value > 1900) + { + request.FullUri = request.FullUri.AddQueryParameter("year", model.ReleaseYear.Value.ToString()); + } + if (model.KeywordIds.Any()) + { + request.FullUri = request.FullUri.AddQueryParameter("with_keyword", string.Join(',', model.KeywordIds)); + } + if (model.GenreIds.Any()) + { + request.FullUri = request.FullUri.AddQueryParameter("with_genres", string.Join(',', model.GenreIds)); + } + if (model.WatchProviders.Any()) + { + request.FullUri = request.FullUri.AddQueryParameter("with_watch_providers", string.Join(',', model.WatchProviders)); + } + request.FullUri = request.FullUri.AddQueryParameter("sort_by", "popularity.desc"); + + var result = await Api.Request>(request, cancellationToken); + return Mapper.Map>(result.results); + } + public async Task GetCollection(string langCode, int collectionId, CancellationToken cancellationToken) { // https://developers.themoviedb.org/3/discover/movie-discover @@ -368,6 +396,17 @@ namespace Ombi.Api.TheMovieDb return result.results ?? new List(); } + public async Task> SearchWatchProviders(string media, string searchTerm, CancellationToken cancellationToken) + { + var request = new Request($"/watch/providers/{media}", BaseUri, HttpMethod.Get); + request.AddQueryString("api_key", ApiToken); + request.AddQueryString("query", searchTerm); + AddRetry(request); + + var result = await Api.Request>(request, cancellationToken); + return result.results ?? new List(); + } + public async Task GetKeyword(int keywordId) { var request = new Request($"keyword/{keywordId}", BaseUri, HttpMethod.Get); diff --git a/src/Ombi/ClientApp/src/app/interfaces/IMovieDb.ts b/src/Ombi/ClientApp/src/app/interfaces/IMovieDb.ts index 63443ae4c..f82225434 100644 --- a/src/Ombi/ClientApp/src/app/interfaces/IMovieDb.ts +++ b/src/Ombi/ClientApp/src/app/interfaces/IMovieDb.ts @@ -2,3 +2,18 @@ id: number; name: string; } + +export interface IWatchProvidersResults { + provider_id: number; + logo_path: string; + provider_name: string; +} + +export interface IDiscoverModel { + type: string; + releaseYear?: number|undefined; + genreIds?: number[]; + keywordIds?: number[]; + watchProviders?: number[]; + companies?: number[]; +} diff --git a/src/Ombi/ClientApp/src/app/my-nav/my-nav.component.html b/src/Ombi/ClientApp/src/app/my-nav/my-nav.component.html index 84ae81fe8..940002d9f 100644 --- a/src/Ombi/ClientApp/src/app/my-nav/my-nav.component.html +++ b/src/Ombi/ClientApp/src/app/my-nav/my-nav.component.html @@ -78,7 +78,7 @@ {{ 'NavigationBar.Filter.Music' | translate}} - + diff --git a/src/Ombi/ClientApp/src/app/my-nav/my-nav.component.scss b/src/Ombi/ClientApp/src/app/my-nav/my-nav.component.scss index 2b018ee8e..4f17a636d 100644 --- a/src/Ombi/ClientApp/src/app/my-nav/my-nav.component.scss +++ b/src/Ombi/ClientApp/src/app/my-nav/my-nav.component.scss @@ -230,4 +230,8 @@ ::ng-deep .mat-sidenav-fixed .mat-list-base .mat-list-item .mat-list-item-content, .mat-list-base .mat-list-option .mat-list-item-content{ padding:0; margin: 0 4em 0 0.5em; +} + +.advanced-search { + margin-left: 10px; } \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/services/applications/themoviedb.service.ts b/src/Ombi/ClientApp/src/app/services/applications/themoviedb.service.ts index 0af37c508..a49fb4146 100644 --- a/src/Ombi/ClientApp/src/app/services/applications/themoviedb.service.ts +++ b/src/Ombi/ClientApp/src/app/services/applications/themoviedb.service.ts @@ -4,7 +4,7 @@ import { Injectable, Inject } from "@angular/core"; import { empty, Observable, throwError } from "rxjs"; import { catchError } from "rxjs/operators"; -import { IMovieDbKeyword } from "../../interfaces"; +import { IMovieDbKeyword, IWatchProvidersResults } from "../../interfaces"; import { ServiceHelpers } from "../service.helpers"; @Injectable({ @@ -28,4 +28,8 @@ export class TheMovieDbService extends ServiceHelpers { public getGenres(media: string): Observable { return this.http.get(`${this.url}/Genres/${media}`, { headers: this.headers }) } + + public getWatchProviders(media: string): Observable { + return this.http.get(`${this.url}/WatchProviders/${media}`, {headers: this.headers}); + } } diff --git a/src/Ombi/ClientApp/src/app/services/searchV2.service.ts b/src/Ombi/ClientApp/src/app/services/searchV2.service.ts index 99e5afb39..348db936b 100644 --- a/src/Ombi/ClientApp/src/app/services/searchV2.service.ts +++ b/src/Ombi/ClientApp/src/app/services/searchV2.service.ts @@ -4,7 +4,7 @@ import { Injectable, Inject } from "@angular/core"; import { HttpClient } from "@angular/common/http"; import { Observable } from "rxjs"; -import { IMultiSearchResult, ISearchMovieResult, ISearchTvResult } from "../interfaces"; +import { IDiscoverModel, IMultiSearchResult, ISearchMovieResult, ISearchTvResult } from "../interfaces"; import { ServiceHelpers } from "./service.helpers"; import { ISearchMovieResultV2 } from "../interfaces/ISearchMovieResultV2"; @@ -51,6 +51,10 @@ export class SearchV2Service extends ServiceHelpers { return this.http.get(`${this.url}/Movie/Popular/${currentlyLoaded}/${toLoad}`).toPromise(); } + public advancedSearch(model: IDiscoverModel, currentlyLoaded: number, toLoad: number): Promise { + return this.http.post(`${this.url}/advancedSearch/Movie/${currentlyLoaded}/${toLoad}`, model).toPromise(); + } + public upcomingMovies(): Observable { return this.http.get(`${this.url}/Movie/upcoming`); } diff --git a/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog.component.html b/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog.component.html index 02f9ac35b..67bd1c2d5 100644 --- a/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog.component.html +++ b/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog.component.html @@ -1,4 +1,4 @@ -
+

Advanced Search

@@ -34,6 +34,10 @@
+ +
+ +
@@ -49,10 +53,10 @@
diff --git a/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog.component.ts b/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog.component.ts index e59f7fab7..a06d43b43 100644 --- a/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog.component.ts +++ b/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog.component.ts @@ -1,6 +1,8 @@ import { Component, Inject, OnInit } from "@angular/core"; import { FormBuilder, FormGroup } from "@angular/forms"; import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material/dialog"; +import { IDiscoverModel } from "../../interfaces"; +import { SearchV2Service } from "../../services"; @Component({ @@ -12,7 +14,8 @@ export class AdvancedSearchDialogComponent implements OnInit { constructor( public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: any, - private fb: FormBuilder + private fb: FormBuilder, + private searchService: SearchV2Service, ) {} public form: FormGroup; @@ -21,16 +24,28 @@ export class AdvancedSearchDialogComponent implements OnInit { public async ngOnInit() { this.form = this.fb.group({ - keywords: [[]], - genres: [[]], + keywordIds: [[]], + genreIds: [[]], releaseYear: [], type: ['movie'], + watchProviders: [[]], }) this.form.controls.type.valueChanges.subscribe(val => { this.form.controls.genres.setValue([]); + this.form.controls.watchProviders.setValue([]); }); } + + public async onSubmit() { + const watchProviderIds = this.form.controls.watchProviders.value.map(x => x.provider_id); + const genres = this.form.controls.genreIds.value.map(x => x.id); + await this.searchService.advancedSearch({ + watchProviders: watchProviderIds, + genreIds: genres, + type: this.form.controls.type.value, + }, 0, 30); + } } diff --git a/src/Ombi/ClientApp/src/app/shared/components/genre-select/genre-select.component.html b/src/Ombi/ClientApp/src/app/shared/components/genre-select/genre-select.component.html index 523974a90..9907b002c 100644 --- a/src/Ombi/ClientApp/src/app/shared/components/genre-select/genre-select.component.html +++ b/src/Ombi/ClientApp/src/app/shared/components/genre-select/genre-select.component.html @@ -3,7 +3,7 @@ Genres {{word.name}} diff --git a/src/Ombi/ClientApp/src/app/shared/components/genre-select/genre-select.component.ts b/src/Ombi/ClientApp/src/app/shared/components/genre-select/genre-select.component.ts index c80eb4ae8..06c92e4cf 100644 --- a/src/Ombi/ClientApp/src/app/shared/components/genre-select/genre-select.component.ts +++ b/src/Ombi/ClientApp/src/app/shared/components/genre-select/genre-select.component.ts @@ -11,7 +11,7 @@ import { TheMovieDbService } from "../../../services"; selector: "genre-select", templateUrl: "genre-select.component.html" }) -export class GenreSelectComponent implements OnInit { +export class GenreSelectComponent { constructor( private tmdbService: TheMovieDbService ) {} @@ -39,32 +39,24 @@ export class GenreSelectComponent implements OnInit { @ViewChild('keywordInput') input: ElementRef; - async ngOnInit() { - - // this.genres = await this.tmdbService.getGenres(this.mediaType).toPromise(); - - - - } - remove(word: IMovieDbKeyword): void { - const exisiting = this.form.controls.genres.value; + const exisiting = this.form.controls.genreIds.value; const index = exisiting.indexOf(word); if (index >= 0) { exisiting.splice(index, 1); - this.form.controls.genres.setValue(exisiting); + this.form.controls.genreIds.setValue(exisiting); } } selected(event: MatAutocompleteSelectedEvent): void { const val = event.option.value; - const exisiting = this.form.controls.genres.value; + const exisiting = this.form.controls.genreIds.value; if(exisiting.indexOf(val) < 0) { exisiting.push(val); } - this.form.controls.genres.setValue(exisiting); + this.form.controls.genreIds.setValue(exisiting); this.input.nativeElement.value = ''; this.control.setValue(null); } diff --git a/src/Ombi/ClientApp/src/app/shared/components/keyword-search/keyword-search.component.html b/src/Ombi/ClientApp/src/app/shared/components/keyword-search/keyword-search.component.html index 1ff1874e9..631c42596 100644 --- a/src/Ombi/ClientApp/src/app/shared/components/keyword-search/keyword-search.component.html +++ b/src/Ombi/ClientApp/src/app/shared/components/keyword-search/keyword-search.component.html @@ -15,7 +15,7 @@ Keywords {{word.name}} diff --git a/src/Ombi/ClientApp/src/app/shared/components/keyword-search/keyword-search.component.ts b/src/Ombi/ClientApp/src/app/shared/components/keyword-search/keyword-search.component.ts index 1ea8bcef1..67427c6e4 100644 --- a/src/Ombi/ClientApp/src/app/shared/components/keyword-search/keyword-search.component.ts +++ b/src/Ombi/ClientApp/src/app/shared/components/keyword-search/keyword-search.component.ts @@ -40,23 +40,23 @@ export class KeywordSearchComponent implements OnInit { }; remove(word: IMovieDbKeyword): void { - const exisiting = this.form.controls.keywords.value; + const exisiting = this.form.controls.keywordIds.value; const index = exisiting.indexOf(word); if (index >= 0) { exisiting.splice(index, 1); - this.form.controls.keywords.setValue(exisiting); + this.form.controls.keywordIds.setValue(exisiting); } } selected(event: MatAutocompleteSelectedEvent): void { const val = event.option.value; - const exisiting = this.form.controls.keywords.value; + const exisiting = this.form.controls.keywordIds.value; if (exisiting.indexOf(val) < 0) { exisiting.push(val); } - this.form.controls.keywords.setValue(exisiting); + this.form.controls.keywordIds.setValue(exisiting); this.input.nativeElement.value = ''; this.control.setValue(null); } diff --git a/src/Ombi/ClientApp/src/app/shared/components/watch-providers-select/watch-providers-select.component.html b/src/Ombi/ClientApp/src/app/shared/components/watch-providers-select/watch-providers-select.component.html new file mode 100644 index 000000000..3c22c7d33 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/shared/components/watch-providers-select/watch-providers-select.component.html @@ -0,0 +1,24 @@ + + Watch Providers + + + {{word.provider_name}} + cancel + + + + + + {{word.provider_name}} + + + + diff --git a/src/Ombi/ClientApp/src/app/shared/components/watch-providers-select/watch-providers-select.component.ts b/src/Ombi/ClientApp/src/app/shared/components/watch-providers-select/watch-providers-select.component.ts new file mode 100644 index 000000000..2c89756e4 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/shared/components/watch-providers-select/watch-providers-select.component.ts @@ -0,0 +1,77 @@ +import { Component, ElementRef, Input, OnInit, ViewChild } from "@angular/core"; +import { FormControl, FormGroup } from "@angular/forms"; +import { IMovieDbKeyword, IWatchProvidersResults } from "../../../interfaces"; +import { debounceTime, distinctUntilChanged, map, startWith, switchMap } from "rxjs/operators"; + +import { MatAutocompleteSelectedEvent } from "@angular/material/autocomplete"; +import { Observable } from "rxjs"; +import { TheMovieDbService } from "../../../services"; + +@Component({ + selector: "watch-providers-select", + templateUrl: "watch-providers-select.component.html" +}) +export class WatchProvidersSelectComponent { + constructor( + private tmdbService: TheMovieDbService + ) {} + + private _mediaType: string; + @Input() set mediaType(type: string) { + this._mediaType = type; + this.tmdbService.getWatchProviders(this._mediaType).subscribe((res) => { + this.watchProviders = res; + this.filteredList = this.control.valueChanges.pipe( + startWith(''), + map((genre: string | null) => genre ? this._filter(genre) : this.watchProviders.slice())); + }); + + } + get mediaType(): string { + return this._mediaType; + } + @Input() public form: FormGroup; + + public watchProviders: IWatchProvidersResults[] = []; + public control = new FormControl(); + public filteredTags: IWatchProvidersResults[]; + public filteredList: Observable; + + @ViewChild('keywordInput') input: ElementRef; + + + remove(word: IWatchProvidersResults): void { + const exisiting = this.form.controls.watchProviders.value; + const index = exisiting.indexOf(word); + + if (index >= 0) { + exisiting.splice(index, 1); + this.form.controls.watchProviders.setValue(exisiting); + } + } + + + selected(event: MatAutocompleteSelectedEvent): void { + const val = event.option.value; + const exisiting = this.form.controls.watchProviders.value; + if (exisiting.indexOf(val) < 0) { + exisiting.push(val); + } + this.form.controls.watchProviders.setValue(exisiting); + this.input.nativeElement.value = ''; + this.control.setValue(null); + } + + private _filter(value: string|IWatchProvidersResults): IWatchProvidersResults[] { + if (typeof value === 'object') { + const filterValue = value.provider_name.toLowerCase(); + return this.watchProviders.filter(g => g.provider_name.toLowerCase().includes(filterValue)); + } else if (typeof value === 'string') { + const filterValue = value.toLowerCase(); + return this.watchProviders.filter(g => g.provider_name.toLowerCase().includes(filterValue)); + } + + return this.watchProviders; + } + +} diff --git a/src/Ombi/ClientApp/src/app/shared/shared.module.ts b/src/Ombi/ClientApp/src/app/shared/shared.module.ts index a76914470..50dfc4538 100644 --- a/src/Ombi/ClientApp/src/app/shared/shared.module.ts +++ b/src/Ombi/ClientApp/src/app/shared/shared.module.ts @@ -41,6 +41,7 @@ import { SidebarModule } from "primeng/sidebar"; import { TheMovieDbService } from "../services"; import { TranslateModule } from "@ngx-translate/core"; import { TruncateModule } from "@yellowspot/ng-truncate"; +import { WatchProvidersSelectComponent } from "./components/watch-providers-select/watch-providers-select.component"; @NgModule({ declarations: [ @@ -51,6 +52,7 @@ import { TruncateModule } from "@yellowspot/ng-truncate"; AdvancedSearchDialogComponent, KeywordSearchComponent, GenreSelectComponent, + WatchProvidersSelectComponent, ], imports: [ SidebarModule, @@ -99,6 +101,7 @@ import { TruncateModule } from "@yellowspot/ng-truncate"; AdvancedSearchDialogComponent, GenreSelectComponent, KeywordSearchComponent, + WatchProvidersSelectComponent, DetailsGroupComponent, TruncateModule, InputSwitchModule, diff --git a/src/Ombi/Controllers/V1/External/TheMovieDbController.cs b/src/Ombi/Controllers/V1/External/TheMovieDbController.cs index 3dacdb406..f5fdb996f 100644 --- a/src/Ombi/Controllers/V1/External/TheMovieDbController.cs +++ b/src/Ombi/Controllers/V1/External/TheMovieDbController.cs @@ -46,5 +46,23 @@ namespace Ombi.Controllers.External [HttpGet("Genres/{media}")] public async Task> GetGenres(string media) => await TmdbApi.GetGenres(media, HttpContext.RequestAborted); + + /// + /// Searches for the watch providers matching the specified term. + /// + /// The search term. + [HttpGet("WatchProviders/movie")] + public async Task> GetWatchProvidersMovies([FromQuery] string searchTerm) => + await TmdbApi.SearchWatchProviders("movie", searchTerm, HttpContext.RequestAborted); + + + /// + /// Searches for the watch providers matching the specified term. + /// + /// The search term. + [HttpGet("WatchProviders/tv")] + public async Task> GetWatchProvidersTv([FromQuery] string searchTerm) => + await TmdbApi.SearchWatchProviders("tv", searchTerm, HttpContext.RequestAborted); + } } diff --git a/src/Ombi/Controllers/V2/SearchController.cs b/src/Ombi/Controllers/V2/SearchController.cs index 4bf8f15da..0b58244b3 100644 --- a/src/Ombi/Controllers/V2/SearchController.cs +++ b/src/Ombi/Controllers/V2/SearchController.cs @@ -183,6 +183,19 @@ namespace Ombi.Controllers.V2 DateTimeOffset.Now.AddHours(12)); } + /// + /// Returns Advanced Searched Media using paging + /// + /// We use TheMovieDb as the Movie Provider + /// + [HttpPost("advancedSearch/movie/{currentPosition}/{amountToLoad}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesDefaultResponseType] + public Task> AdvancedSearchMovie([FromBody]DiscoverModel model, int currentPosition, int amountToLoad) + { + return _movieEngineV2.AdvancedSearch(model, currentPosition, amountToLoad, Request.HttpContext.RequestAborted); + } + /// /// Returns Seasonal Movies ///