Added a global language flag that now applies to the search by default

pull/2728/head
tidusjar 5 years ago
parent 9cc9bf7e78
commit 947dbe1b6a

@ -157,6 +157,24 @@ namespace Ombi.Core.Engine
}
}
private string defaultLangCode;
protected async Task<string> DefaultLanguageCode(string currentCode)
{
if (currentCode.HasValue())
{
return currentCode;
}
var s = await GetOmbiSettings();
return s.DefaultLanguageCode;
}
private OmbiSettings ombiSettings;
protected async Task<OmbiSettings> GetOmbiSettings()
{
return ombiSettings ?? (ombiSettings = await OmbiSettings.GetSettingsAsync());
}
public class HideResult
{
public bool Hide { get; set; }

@ -16,8 +16,8 @@ namespace Ombi.Core
Task<IEnumerable<SearchMovieViewModel>> UpcomingMovies();
Task<SearchMovieViewModel> LookupImdbInformation(int theMovieDbId, string langCode = "en");
Task<SearchMovieViewModel> LookupImdbInformation(int theMovieDbId, string langCode = null);
Task<IEnumerable<SearchMovieViewModel>> SimilarMovies(int theMovieDbId);
Task<IEnumerable<SearchMovieViewModel>> SimilarMovies(int theMovieDbId, string langCode);
}
}

@ -1,23 +1,22 @@
using System;
using AutoMapper;
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Ombi.Api.TheMovieDb;
using Ombi.Api.TheMovieDb.Models;
using Ombi.Core.Authentication;
using Ombi.Core.Models.Requests;
using Ombi.Core.Models.Search;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Ombi.Core.Rule.Interfaces;
using Microsoft.Extensions.Caching.Memory;
using Ombi.Core.Authentication;
using Ombi.Core.Settings;
using Ombi.Helpers;
using Ombi.Settings.Settings.Models;
using Ombi.Store.Entities;
using Ombi.Store.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Threading.Tasks;
namespace Ombi.Core.Engine
{
@ -43,8 +42,9 @@ namespace Ombi.Core.Engine
/// </summary>
/// <param name="theMovieDbId">The movie database identifier.</param>
/// <returns></returns>
public async Task<SearchMovieViewModel> LookupImdbInformation(int theMovieDbId, string langCode = "en")
public async Task<SearchMovieViewModel> LookupImdbInformation(int theMovieDbId, string langCode = null)
{
langCode = await DefaultLanguageCode(langCode);
var movieInfo = await MovieApi.GetMovieInformationWithExtraInfo(theMovieDbId, langCode);
var viewMovie = Mapper.Map<SearchMovieViewModel>(movieInfo);
@ -58,6 +58,7 @@ namespace Ombi.Core.Engine
/// <returns></returns>
public async Task<IEnumerable<SearchMovieViewModel>> Search(string search, int? year, string langaugeCode)
{
langaugeCode = await DefaultLanguageCode(langaugeCode);
var result = await MovieApi.SearchMovie(search, year, langaugeCode);
if (result != null)
@ -72,9 +73,10 @@ namespace Ombi.Core.Engine
/// </summary>
/// <param name="theMovieDbId"></param>
/// <returns></returns>
public async Task<IEnumerable<SearchMovieViewModel>> SimilarMovies(int theMovieDbId)
public async Task<IEnumerable<SearchMovieViewModel>> SimilarMovies(int theMovieDbId, string langCode)
{
var result = await MovieApi.SimilarMovies(theMovieDbId);
langCode = await DefaultLanguageCode(langCode);
var result = await MovieApi.SimilarMovies(theMovieDbId, langCode);
if (result != null)
{
Logger.LogDebug("Search Result: {result}", result);
@ -89,7 +91,12 @@ namespace Ombi.Core.Engine
/// <returns></returns>
public async Task<IEnumerable<SearchMovieViewModel>> PopularMovies()
{
var result = await Cache.GetOrAdd(CacheKeys.PopularMovies, async () => await MovieApi.PopularMovies(), DateTime.Now.AddHours(12));
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.Take(MovieLimit)); // Take x to stop us overloading the API
@ -103,7 +110,11 @@ namespace Ombi.Core.Engine
/// <returns></returns>
public async Task<IEnumerable<SearchMovieViewModel>> TopRatedMovies()
{
var result = await Cache.GetOrAdd(CacheKeys.TopRatedMovies, async () => await MovieApi.TopRated(), DateTime.Now.AddHours(12));
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.Take(MovieLimit)); // Take x to stop us overloading the API
@ -117,7 +128,11 @@ namespace Ombi.Core.Engine
/// <returns></returns>
public async Task<IEnumerable<SearchMovieViewModel>> UpcomingMovies()
{
var result = await Cache.GetOrAdd(CacheKeys.UpcomingMovies, async () => await MovieApi.Upcoming(), DateTime.Now.AddHours(12));
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);
@ -132,7 +147,11 @@ namespace Ombi.Core.Engine
/// <returns></returns>
public async Task<IEnumerable<SearchMovieViewModel>> NowPlayingMovies()
{
var result = await Cache.GetOrAdd(CacheKeys.NowPlayingMovies, async () => await MovieApi.NowPlaying(), DateTime.Now.AddHours(12));
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.Take(MovieLimit)); // Take x to stop us overloading the API

@ -9,13 +9,13 @@ namespace Ombi.Api.TheMovieDb
{
Task<MovieResponseDto> GetMovieInformation(int movieId);
Task<MovieResponseDto> GetMovieInformationWithExtraInfo(int movieId, string langCode = "en");
Task<List<MovieSearchResult>> NowPlaying();
Task<List<MovieSearchResult>> PopularMovies();
Task<List<MovieSearchResult>> NowPlaying(string languageCode);
Task<List<MovieSearchResult>> PopularMovies(string languageCode);
Task<List<MovieSearchResult>> SearchMovie(string searchTerm, int? year, string languageCode);
Task<List<TvSearchResult>> SearchTv(string searchTerm);
Task<List<MovieSearchResult>> TopRated();
Task<List<MovieSearchResult>> Upcoming();
Task<List<MovieSearchResult>> SimilarMovies(int movieId);
Task<List<MovieSearchResult>> TopRated(string languageCode);
Task<List<MovieSearchResult>> Upcoming(string languageCode);
Task<List<MovieSearchResult>> SimilarMovies(int movieId, string langCode);
Task<FindResult> Find(string externalId, ExternalSource source);
Task<TvExternals> GetTvExternals(int theMovieDbId);
Task<TvInfo> GetTVInfo(string themoviedbid);

@ -63,10 +63,12 @@ namespace Ombi.Api.TheMovieDb
return await Api.Request<TvExternals>(request);
}
public async Task<List<MovieSearchResult>> SimilarMovies(int movieId)
public async Task<List<MovieSearchResult>> SimilarMovies(int movieId, string langCode)
{
var request = new Request($"movie/{movieId}/similar", BaseUri, HttpMethod.Get);
request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken);
request.FullUri = request.FullUri.AddQueryParameter("language", langCode);
AddRetry(request);
var result = await Api.Request<TheMovieDbContainer<SearchResult>>(request);
@ -100,37 +102,41 @@ namespace Ombi.Api.TheMovieDb
return Mapper.Map<List<MovieSearchResult>>(result.results);
}
public async Task<List<MovieSearchResult>> PopularMovies()
public async Task<List<MovieSearchResult>> PopularMovies(string langageCode)
{
var request = new Request($"movie/popular", BaseUri, HttpMethod.Get);
request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken);
request.FullUri = request.FullUri.AddQueryParameter("language", langageCode);
AddRetry(request);
var result = await Api.Request<TheMovieDbContainer<SearchResult>>(request);
return Mapper.Map<List<MovieSearchResult>>(result.results);
}
public async Task<List<MovieSearchResult>> TopRated()
public async Task<List<MovieSearchResult>> TopRated(string langageCode)
{
var request = new Request($"movie/top_rated", BaseUri, HttpMethod.Get);
request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken);
request.FullUri = request.FullUri.AddQueryParameter("language", langageCode);
AddRetry(request);
var result = await Api.Request<TheMovieDbContainer<SearchResult>>(request);
return Mapper.Map<List<MovieSearchResult>>(result.results);
}
public async Task<List<MovieSearchResult>> Upcoming()
public async Task<List<MovieSearchResult>> Upcoming(string langageCode)
{
var request = new Request($"movie/upcoming", BaseUri, HttpMethod.Get);
request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken);
request.FullUri = request.FullUri.AddQueryParameter("language", langageCode);
AddRetry(request);
var result = await Api.Request<TheMovieDbContainer<SearchResult>>(request);
return Mapper.Map<List<MovieSearchResult>>(result.results);
}
public async Task<List<MovieSearchResult>> NowPlaying()
public async Task<List<MovieSearchResult>> NowPlaying(string langageCode)
{
var request = new Request($"movie/now_playing", BaseUri, HttpMethod.Get);
request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken);
request.FullUri = request.FullUri.AddQueryParameter("language", langageCode);
AddRetry(request);
var result = await Api.Request<TheMovieDbContainer<SearchResult>>(request);
return Mapper.Map<List<MovieSearchResult>>(result.results);

@ -154,7 +154,7 @@ export interface IEpisodesRequests {
export interface IMovieRequestModel {
theMovieDbId: number;
languageCode: string;
languageCode: string | undefined;
}
export interface IFilter {

@ -15,6 +15,7 @@ export interface IOmbiSettings extends ISettings {
ignoreCertificateErrors: boolean;
doNotSendNotificationsForAutoApprove: boolean;
hideRequestsUsers: boolean;
defaultLanguageCode: string;
}
export interface IUpdateSettings extends ISettings {

@ -7,7 +7,7 @@ import { debounceTime, distinctUntilChanged } from "rxjs/operators";
import { AuthService } from "../auth/auth.service";
import { IIssueCategory, ILanguageRefine, IRequestEngineResult, ISearchMovieResult } from "../interfaces";
import { NotificationService, RequestService, SearchService } from "../services";
import { NotificationService, RequestService, SearchService, SettingsService } from "../services";
import * as languageData from "../../other/iso-lang.json";
@ -43,7 +43,7 @@ export class MovieSearchComponent implements OnInit {
private searchService: SearchService, private requestService: RequestService,
private notificationService: NotificationService, private authService: AuthService,
private readonly translate: TranslateService, private sanitizer: DomSanitizer,
private readonly platformLocation: PlatformLocation) {
private readonly platformLocation: PlatformLocation, private settingsService: SettingsService) {
this.langauges = <ILanguageRefine[]><any>languageData;
this.searchChanged.pipe(
debounceTime(600), // Wait Xms after the last event before emitting last event
@ -67,7 +67,7 @@ export class MovieSearchComponent implements OnInit {
result: false,
errorMessage: "",
};
this.settingsService.getDefaultLanguage().subscribe(x => this.selectedLanguage = x);
this.popularMovies();
}
@ -159,7 +159,8 @@ export class MovieSearchComponent implements OnInit {
public similarMovies(theMovieDbId: number) {
this.clearResults();
this.searchService.similarMovies(theMovieDbId)
const lang = this.selectedLanguage && this.selectedLanguage.length > 0 ? this.selectedLanguage : "";
this.searchService.similarMovies(theMovieDbId, lang)
.subscribe(x => {
this.movieResults = x;
this.getExtraInfo();

@ -65,7 +65,7 @@ export class MovieSearchGridComponent implements OnInit {
}
try {
this.requestService.requestMovie({ theMovieDbId: searchResult.id })
this.requestService.requestMovie({ theMovieDbId: searchResult.id, languageCode: "en" })
.subscribe(x => {
this.result = x;

@ -1,14 +1,11 @@
import { PlatformLocation } from "@angular/common";
import { Component, Input, OnInit } from "@angular/core";
import { DomSanitizer } from "@angular/platform-browser";
import { TranslateService } from "@ngx-translate/core";
import { Subject } from "rxjs";
import { debounceTime, distinctUntilChanged } from "rxjs/operators";
import { AuthService } from "../../auth/auth.service";
import { IIssueCategory, IRequestEngineResult, ISearchMovieResult } from "../../interfaces";
import { IIssueCategory, IRequestEngineResult } from "../../interfaces";
import { ISearchAlbumResult, ISearchArtistResult } from "../../interfaces/ISearchMusicResult";
import { NotificationService, RequestService, SearchService } from "../../services";
import { SearchService } from "../../services";
@Component({
selector: "music-search",
@ -35,10 +32,8 @@ export class MusicSearchComponent implements OnInit {
public defaultPoster: string;
constructor(
private searchService: SearchService, private requestService: RequestService,
private notificationService: NotificationService, private authService: AuthService,
private readonly translate: TranslateService, private sanitizer: DomSanitizer,
private readonly platformLocation: PlatformLocation) {
private searchService: SearchService, private sanitizer: DomSanitizer,
private platformLocation: PlatformLocation) {
this.searchChanged.pipe(
debounceTime(600), // Wait Xms after the last event before emitting last event
@ -110,45 +105,6 @@ export class MusicSearchComponent implements OnInit {
this.searchChanged.next(`lidarr:${artistId}`);
}
public request(searchResult: ISearchMovieResult) {
searchResult.requested = true;
searchResult.requestProcessing = true;
searchResult.showSubscribe = false;
if (this.authService.hasRole("admin") || this.authService.hasRole("AutoApproveMovie")) {
searchResult.approved = true;
}
try {
this.requestService.requestMovie({ theMovieDbId: searchResult.id })
.subscribe(x => {
this.result = x;
if (this.result.result) {
this.translate.get("Search.RequestAdded", { title: searchResult.title }).subscribe(x => {
this.notificationService.success(x);
searchResult.processed = true;
});
} else {
if (this.result.errorMessage && this.result.message) {
this.notificationService.warning("Request Added", `${this.result.message} - ${this.result.errorMessage}`);
} else {
this.notificationService.warning("Request Added", this.result.message ? this.result.message : this.result.errorMessage);
}
searchResult.requested = false;
searchResult.approved = false;
searchResult.processed = false;
searchResult.requestProcessing = false;
}
});
} catch (e) {
searchResult.processed = false;
searchResult.requestProcessing = false;
this.notificationService.error(e);
}
}
public viewAlbumsForArtist(albums: ISearchAlbumResult[]) {
this.clearArtistResults();
this.searchAlbum = true;

@ -25,8 +25,8 @@ export class SearchService extends ServiceHelpers {
return this.http.post<ISearchMovieResult[]>(`${this.url}/Movie/`, { searchTerm, year, languageCode: langCode });
}
public similarMovies(theMovieDbId: number): Observable<ISearchMovieResult[]> {
return this.http.get<ISearchMovieResult[]>(`${this.url}/Movie/${theMovieDbId}/similar`);
public similarMovies(theMovieDbId: number, langCode: string): Observable<ISearchMovieResult[]> {
return this.http.post<ISearchMovieResult[]>(`${this.url}/Movie/similar`, {theMovieDbId, languageCode: langCode});
}
public popularMovies(): Observable<ISearchMovieResult[]> {

@ -52,6 +52,10 @@ export class SettingsService extends ServiceHelpers {
return this.http.get<IOmbiSettings>(`${this.url}/Ombi/`, {headers: this.headers});
}
public getDefaultLanguage(): Observable<string> {
return this.http.get<string>(`${this.url}/defaultlanguage/`, {headers: this.headers});
}
public saveOmbi(settings: IOmbiSettings): Observable<boolean> {
return this.http.post<boolean>(`${this.url}/Ombi/`, JSON.stringify(settings), {headers: this.headers});
}

@ -22,64 +22,80 @@
</div>
</div>-->
<div class="col-md-6">
<div class="form-group">
<label for="baseUrl" class="control-label">Base Url</label>
<div>
<input type="text" class="form-control form-control-custom" id="baseUrl" name="baseUrl" formControlName="baseUrl">
<div class="form-group">
<label for="baseUrl" class="control-label">Base Url</label>
<div>
<input type="text" class="form-control form-control-custom" id="baseUrl" name="baseUrl"
formControlName="baseUrl">
</div>
</div>
</div>
<div class="form-group">
<label for="ApiKey" class="control-label">Api Key</label>
<div class="input-group">
<input type="text" class="form-control form-control-custom" id="ApiKey" name="ApiKey" formControlName="apiKey" readonly="readonly" #apiKey>
<div class="form-group">
<label for="ApiKey" class="control-label">Api Key</label>
<div class="input-group">
<input type="text" class="form-control form-control-custom" id="ApiKey" name="ApiKey"
formControlName="apiKey" readonly="readonly" #apiKey>
<div class="input-group-addon">
<div (click)="refreshApiKey()" id="refreshKey" class="fa fa-refresh" title="Reset API Key" pTooltip="This will invalidate the old API key" ></div>
</div>
<div class="input-group-addon">
<div (click)="refreshApiKey()" id="refreshKey" class="fa fa-refresh" title="Reset API Key"
pTooltip="This will invalidate the old API key"></div>
</div>
<div class="input-group-addon">
<div ngxClipboard [ngxClipboard]="apiKey" class="fa fa-clipboard" (cbOnSuccess)="successfullyCopied()"></div>
<div class="input-group-addon">
<div ngxClipboard [ngxClipboard]="apiKey" class="fa fa-clipboard" (cbOnSuccess)="successfullyCopied()"></div>
</div>
</div>
</div>
</div>
<br/>
<br />
<div class="form-group">
<div class="checkbox">
<input type="checkbox" id="doNotSendNotificationsForAutoApprove" name="doNotSendNotificationsForAutoApprove" formControlName="doNotSendNotificationsForAutoApprove">
<label for="doNotSendNotificationsForAutoApprove">Do not send Notifications if a User has the Auto Approve permission</label>
<div class="form-group">
<div class="checkbox">
<input type="checkbox" id="doNotSendNotificationsForAutoApprove" name="doNotSendNotificationsForAutoApprove"
formControlName="doNotSendNotificationsForAutoApprove">
<label for="doNotSendNotificationsForAutoApprove">Do not send Notifications if a User has the Auto
Approve permission</label>
</div>
</div>
</div>
<div class="form-group">
<div class="checkbox">
<input type="checkbox" id="hideRequestsUsers" name="hideRequestsUsers" formControlName="hideRequestsUsers">
<label for="hideRequestsUsers">Hide requests from other users</label>
<div class="form-group">
<div class="checkbox">
<input type="checkbox" id="hideRequestsUsers" name="hideRequestsUsers" formControlName="hideRequestsUsers">
<label for="hideRequestsUsers">Hide requests from other users</label>
</div>
</div>
</div>
<div class="form-group">
<div class="checkbox">
<input type="checkbox" id="ignoreCertificateErrors" name="ignoreCertificateErrors" formControlName="ignoreCertificateErrors">
<label for="ignoreCertificateErrors" tooltipPosition="top" pTooltip="Enable if you are having connectivity problems over SSL">Ignore any certificate errors</label>
<div class="form-group">
<div class="checkbox">
<input type="checkbox" id="ignoreCertificateErrors" name="ignoreCertificateErrors" formControlName="ignoreCertificateErrors">
<label for="ignoreCertificateErrors" tooltipPosition="top" pTooltip="Enable if you are having connectivity problems over SSL">Ignore
any certificate errors</label>
</div>
</div>
</div>
<div class="form-group">
<div class="checkbox">
<input type="checkbox" id="CollectAnalyticData" name="CollectAnalyticData" formControlName="collectAnalyticData">
<label for="CollectAnalyticData" tooltipPosition="top" pTooltip="This will allow us to have a better understanding of the userbase so we know what we should be supporting">Allow us to collect anonymous analytical data e.g. browser used</label>
<div class="form-group">
<div class="checkbox">
<input type="checkbox" id="CollectAnalyticData" name="CollectAnalyticData" formControlName="collectAnalyticData">
<label for="CollectAnalyticData" tooltipPosition="top" pTooltip="This will allow us to have a better understanding of the userbase so we know what we should be supporting">Allow
us to collect anonymous analytical data e.g. browser used</label>
</div>
</div>
</div>
<div class="form-group">
<div>
<button [disabled]="form.invalid" type="submit" id="save" class="btn btn-primary-outline">Submit</button>
<div class="form-group" *ngIf="langauges">
<label for="select" class="control-label">Language</label>
<div id="profiles">
<select formControlName="defaultLanguageCode" class="form-control form-control-custom" id="select">
<option *ngFor="let lang of langauges" value="{{lang.code}}">{{lang.nativeName}}</option>
</select>
</div>
</div>
<div class="form-group">
<div>
<button [disabled]="form.invalid" type="submit" id="save" class="btn btn-primary-outline">Submit</button>
</div>
</div>
</div>
</div>
</form>
</fieldset>
</fieldset>

@ -1,16 +1,19 @@
import { Component, OnInit } from "@angular/core";
import { FormBuilder, FormGroup } from "@angular/forms";
import { IOmbiSettings } from "../../interfaces";
import { ILanguageRefine, IOmbiSettings } from "../../interfaces";
import { NotificationService } from "../../services";
import { SettingsService } from "../../services";
import * as languageData from "../../../other/iso-lang.json";
@Component({
templateUrl: "./ombi.component.html",
})
export class OmbiComponent implements OnInit {
public form: FormGroup;
public langauges: ILanguageRefine[];
constructor(private settingsService: SettingsService,
private notificationService: NotificationService,
@ -25,8 +28,10 @@ export class OmbiComponent implements OnInit {
baseUrl: [x.baseUrl],
doNotSendNotificationsForAutoApprove: [x.doNotSendNotificationsForAutoApprove],
hideRequestsUsers: [x.hideRequestsUsers],
defaultLanguageCode: [x.defaultLanguageCode],
});
});
this.langauges = <ILanguageRefine[]><any>languageData;
}
public refreshApiKey() {

@ -47,7 +47,7 @@ namespace Ombi.Controllers
{
Logger.LogDebug("Searching : {searchTerm}", searchTerm);
return await MovieEngine.Search(searchTerm, null, "en");
return await MovieEngine.Search(searchTerm, null, null);
}
}
@ -114,6 +114,21 @@ namespace Ombi.Controllers
return Json(await MovieEngine.LookupImdbInformation(model.TheMovieDbId, model.LanguageCode));
}
/// <summary>
/// Returns similar movies to the movie id passed in
/// </summary>
/// <param name="theMovieDbId">ID of the movie</param>
/// <remarks>
/// We use TheMovieDb as the Movie Provider
/// </remarks>
[HttpPost("movie/similar")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesDefaultResponseType]
public async Task<IEnumerable<SearchMovieViewModel>> SimilarMovies([FromBody] SimilarMoviesRefineModel model)
{
return await MovieEngine.SimilarMovies(model.TheMovieDbId, model.LanguageCode);
}
/// <summary>
/// Returns similar movies to the movie id passed in
/// </summary>
@ -126,7 +141,7 @@ namespace Ombi.Controllers
[ProducesDefaultResponseType]
public async Task<IEnumerable<SearchMovieViewModel>> SimilarMovies(int theMovieDbId)
{
return await MovieEngine.SimilarMovies(theMovieDbId);
return await MovieEngine.SimilarMovies(theMovieDbId, null);
}
/// <summary>

@ -225,6 +225,19 @@ namespace Ombi.Controllers
return await Get<CustomizationSettings>();
}
/// <summary>
/// Gets the default language set in Ombi
/// </summary>
/// <returns></returns>
[HttpGet("defaultlanguage")]
[AllowAnonymous]
public async Task<string> GetDefaultLanguage()
{
var s = await Get<OmbiSettings>();
return s.DefaultLanguageCode;
}
/// <summary>
/// Save the Customization settings.
/// </summary>

@ -0,0 +1,8 @@
namespace Ombi.Models
{
public class SimilarMoviesRefineModel
{
public int TheMovieDbId { get; set; }
public string LanguageCode { get; set; } = "en";
}
}
Loading…
Cancel
Save