Merge from dev

pull/3895/head
tidusjar 6 years ago
commit 41ae641732

@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Ombi.Api.TheMovieDb;
using Ombi.Api.TheMovieDb.Models;
using Ombi.Config;
using Ombi.Core.Authentication;
using Ombi.Core.Models.Requests;
using Ombi.Core.Models.Search;
using Ombi.Core.Rule.Interfaces;
using Ombi.Core.Settings;
using Ombi.Helpers;
using Ombi.Settings.Settings.Models;
using Ombi.Store.Entities;
using Ombi.Store.Repository;
namespace Ombi.Core.Engine.Demo
{
public class DemoMovieSearchEngine : MovieSearchEngine, IDemoMovieSearchEngine
{
public DemoMovieSearchEngine(IPrincipal identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper,
ILogger<MovieSearchEngine> logger, IRuleEvaluator r, OmbiUserManager um, ICacheService mem, ISettingsService<OmbiSettings> s,
IRepository<RequestSubscription> sub, IOptions<DemoLists> lists)
: base(identity, service, movApi, mapper, logger, r, um, mem, s, sub)
{
_demoLists = lists.Value;
}
private readonly DemoLists _demoLists;
public async Task<IEnumerable<SearchMovieViewModel>> Search(string search)
{
var result = await MovieApi.SearchMovie(search, null, "en");
for (var i = 0; i < result.Count; i++)
{
if (!_demoLists.Movies.Contains(result[i].Id))
{
result.RemoveAt(i);
}
}
if(result.Count > 0)
return await TransformMovieResultsToResponse(result.Take(MovieLimit)); // Take x to stop us overloading the API
return null;
}
public async Task<IEnumerable<SearchMovieViewModel>> NowPlayingMovies()
{
var rand = new Random();
var responses = new List<SearchMovieViewModel>();
for (int i = 0; i < 10; i++)
{
var item = rand.Next(_demoLists.Movies.Length);
var movie = _demoLists.Movies[item];
if (responses.Any(x => x.Id == movie))
{
i--;
continue;
}
var movieResult = await MovieApi.GetMovieInformationWithExtraInfo(movie);
var viewMovie = Mapper.Map<SearchMovieViewModel>(movieResult);
responses.Add(await ProcessSingleMovie(viewMovie));
}
return responses;
}
public async Task<IEnumerable<SearchMovieViewModel>> PopularMovies()
{
return await NowPlayingMovies();
}
public async Task<IEnumerable<SearchMovieViewModel>> TopRatedMovies()
{
return await NowPlayingMovies();
}
public async Task<IEnumerable<SearchMovieViewModel>> UpcomingMovies()
{
return await NowPlayingMovies();
}
}
public interface IDemoMovieSearchEngine
{
Task<IEnumerable<SearchMovieViewModel>> NowPlayingMovies();
Task<IEnumerable<SearchMovieViewModel>> PopularMovies();
Task<IEnumerable<SearchMovieViewModel>> Search(string search);
Task<IEnumerable<SearchMovieViewModel>> TopRatedMovies();
Task<IEnumerable<SearchMovieViewModel>> UpcomingMovies();
}
}

@ -0,0 +1,96 @@
using AutoMapper;
using Microsoft.Extensions.Options;
using Ombi.Api.Trakt;
using Ombi.Api.TvMaze;
using Ombi.Config;
using Ombi.Core.Authentication;
using Ombi.Core.Models.Requests;
using Ombi.Core.Models.Search;
using Ombi.Core.Rule.Interfaces;
using Ombi.Core.Settings;
using Ombi.Core.Settings.Models.External;
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.Demo
{
public class DemoTvSearchEngine : TvSearchEngine, IDemoTvSearchEngine
{
public DemoTvSearchEngine(IPrincipal identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper,
ISettingsService<PlexSettings> plexSettings, ISettingsService<EmbySettings> embySettings, IPlexContentRepository repo,
IEmbyContentRepository embyRepo, ITraktApi trakt, IRuleEvaluator r, OmbiUserManager um, ICacheService memCache,
ISettingsService<OmbiSettings> s, IRepository<RequestSubscription> sub, IOptions<DemoLists> lists)
: base(identity, service, tvMaze, mapper, plexSettings, embySettings, repo, embyRepo, trakt, r, um, memCache, s, sub)
{
_demoLists = lists.Value;
}
private readonly DemoLists _demoLists;
public async Task<IEnumerable<SearchTvShowViewModel>> Search(string search)
{
var searchResult = await TvMazeApi.Search(search);
for (var i = 0; i < searchResult.Count; i++)
{
if (!_demoLists.TvShows.Contains(searchResult[i].show?.externals?.thetvdb ?? 0))
{
searchResult.RemoveAt(i);
}
}
if (searchResult != null)
{
var retVal = new List<SearchTvShowViewModel>();
foreach (var tvMazeSearch in searchResult)
{
if (tvMazeSearch.show.externals == null || !(tvMazeSearch.show.externals?.thetvdb.HasValue ?? false))
{
continue;
}
retVal.Add(ProcessResult(tvMazeSearch));
}
return retVal;
}
return null;
}
public async Task<IEnumerable<SearchTvShowViewModel>> NowPlayingMovies()
{
var rand = new Random();
var responses = new List<SearchTvShowViewModel>();
for (int i = 0; i < 10; i++)
{
var item = rand.Next(_demoLists.TvShows.Length);
var tv = _demoLists.TvShows[item];
if (responses.Any(x => x.Id == tv))
{
i--;
continue;
}
var movieResult = await TvMazeApi.ShowLookup(tv);
responses.Add(ProcessResult(movieResult));
}
return responses;
}
}
public interface IDemoTvSearchEngine
{
Task<IEnumerable<SearchTvShowViewModel>> Search(string search);
Task<IEnumerable<SearchTvShowViewModel>> NowPlayingMovies();
}
}

@ -31,10 +31,11 @@ namespace Ombi.Core.Engine
Logger = logger; Logger = logger;
} }
private IMovieDbApi MovieApi { get; } protected IMovieDbApi MovieApi { get; }
private IMapper Mapper { get; } protected IMapper Mapper { get; }
private ILogger<MovieSearchEngine> Logger { get; } private ILogger<MovieSearchEngine> Logger { get; }
protected const int MovieLimit = 10;
/// <summary> /// <summary>
/// Lookups the imdb information. /// Lookups the imdb information.
@ -185,7 +186,7 @@ namespace Ombi.Core.Engine
return null; return null;
} }
private async Task<List<SearchMovieViewModel>> TransformMovieResultsToResponse( protected async Task<List<SearchMovieViewModel>> TransformMovieResultsToResponse(
IEnumerable<MovieSearchResult> movies) IEnumerable<MovieSearchResult> movies)
{ {
var viewMovies = new List<SearchMovieViewModel>(); var viewMovies = new List<SearchMovieViewModel>();
@ -196,7 +197,7 @@ namespace Ombi.Core.Engine
return viewMovies; return viewMovies;
} }
private async Task<SearchMovieViewModel> ProcessSingleMovie(SearchMovieViewModel viewMovie, bool lookupExtraInfo = false) protected async Task<SearchMovieViewModel> ProcessSingleMovie(SearchMovieViewModel viewMovie, bool lookupExtraInfo = false)
{ {
if (lookupExtraInfo && viewMovie.ImdbId.IsNullOrEmpty()) if (lookupExtraInfo && viewMovie.ImdbId.IsNullOrEmpty())
{ {

@ -40,8 +40,8 @@ namespace Ombi.Core.Engine
EmbyContentRepo = embyRepo; EmbyContentRepo = embyRepo;
} }
private ITvMazeApi TvMazeApi { get; } protected ITvMazeApi TvMazeApi { get; }
private IMapper Mapper { get; } protected IMapper Mapper { get; }
private ISettingsService<PlexSettings> PlexSettings { get; } private ISettingsService<PlexSettings> PlexSettings { get; }
private ISettingsService<EmbySettings> EmbySettings { get; } private ISettingsService<EmbySettings> EmbySettings { get; }
private IPlexContentRepository PlexContentRepo { get; } private IPlexContentRepository PlexContentRepo { get; }
@ -149,7 +149,7 @@ namespace Ombi.Core.Engine
return processed; return processed;
} }
private IEnumerable<SearchTvShowViewModel> ProcessResults<T>(IEnumerable<T> items) protected IEnumerable<SearchTvShowViewModel> ProcessResults<T>(IEnumerable<T> items)
{ {
var retVal = new List<SearchTvShowViewModel>(); var retVal = new List<SearchTvShowViewModel>();
foreach (var tvMazeSearch in items) foreach (var tvMazeSearch in items)
@ -159,7 +159,7 @@ namespace Ombi.Core.Engine
return retVal; return retVal;
} }
private SearchTvShowViewModel ProcessResult<T>(T tvMazeSearch) protected SearchTvShowViewModel ProcessResult<T>(T tvMazeSearch)
{ {
return Mapper.Map<SearchTvShowViewModel>(tvMazeSearch); return Mapper.Map<SearchTvShowViewModel>(tvMazeSearch);
} }

@ -52,6 +52,7 @@ using Ombi.Store.Repository.Requests;
using Ombi.Updater; using Ombi.Updater;
using Ombi.Api.Telegram; using Ombi.Api.Telegram;
using Ombi.Core.Authentication; using Ombi.Core.Authentication;
using Ombi.Core.Engine.Demo;
using Ombi.Core.Engine.V2; using Ombi.Core.Engine.V2;
using Ombi.Core.Processor; using Ombi.Core.Processor;
using Ombi.Schedule.Jobs.Lidarr; using Ombi.Schedule.Jobs.Lidarr;
@ -92,6 +93,8 @@ namespace Ombi.DependencyInjection
services.AddTransient<IMassEmailSender, MassEmailSender>(); services.AddTransient<IMassEmailSender, MassEmailSender>();
services.AddTransient<IPlexOAuthManager, PlexOAuthManager>(); services.AddTransient<IPlexOAuthManager, PlexOAuthManager>();
services.AddTransient<IVoteEngine, VoteEngine>(); services.AddTransient<IVoteEngine, VoteEngine>();
services.AddTransient<IDemoMovieSearchEngine, DemoMovieSearchEngine>();
services.AddTransient<IDemoTvSearchEngine, DemoTvSearchEngine>();
} }
public static void RegisterEnginesV2(this IServiceCollection services) public static void RegisterEnginesV2(this IServiceCollection services)

@ -0,0 +1,11 @@
namespace Ombi.Config
{
public class DemoLists
{
public bool Enabled { get; set; }
public int[] Movies { get; set; }
public int[] TvShows { get; set; }
}
}

@ -0,0 +1,13 @@
namespace Ombi.Helpers
{
public class DemoSingleton
{
private static DemoSingleton instance;
private DemoSingleton() { }
public static DemoSingleton Instance => instance ?? (instance = new DemoSingleton());
public bool Demo { get; set; }
}
}

@ -15,5 +15,6 @@
public const string Disabled = nameof(Disabled); public const string Disabled = nameof(Disabled);
public const string ReceivesNewsletter = nameof(ReceivesNewsletter); public const string ReceivesNewsletter = nameof(ReceivesNewsletter);
public const string ManageOwnRequests = nameof(ManageOwnRequests); public const string ManageOwnRequests = nameof(ManageOwnRequests);
public const string EditCustomPage = nameof(EditCustomPage);
} }
} }

@ -124,6 +124,16 @@ namespace Ombi.Store.Context
SaveChanges(); SaveChanges();
} }
var editCustomPage = Roles.Where(x => x.Name == OmbiRoles.EditCustomPage);
if (!editCustomPage.Any())
{
Roles.Add(new IdentityRole(OmbiRoles.EditCustomPage)
{
NormalizedName = OmbiRoles.EditCustomPage.ToUpper()
});
SaveChanges();
}
// Make sure we have the API User // Make sure we have the API User
var apiUserExists = Users.Any(x => x.UserName.Equals("Api", StringComparison.CurrentCultureIgnoreCase)); var apiUserExists = Users.Any(x => x.UserName.Equals("Api", StringComparison.CurrentCultureIgnoreCase));
if (!apiUserExists) if (!apiUserExists)

@ -8,6 +8,7 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Ombi.Core.Authentication; using Ombi.Core.Authentication;
using Ombi.Core.Settings; using Ombi.Core.Settings;
using Ombi.Helpers;
using Ombi.Settings.Settings.Models; using Ombi.Settings.Settings.Models;
namespace Ombi namespace Ombi
@ -98,6 +99,10 @@ namespace Ombi
if (context.Request.Headers.Keys.Contains("UserName", StringComparer.InvariantCultureIgnoreCase)) if (context.Request.Headers.Keys.Contains("UserName", StringComparer.InvariantCultureIgnoreCase))
{ {
var username = context.Request.Headers["UserName"].FirstOrDefault(); var username = context.Request.Headers["UserName"].FirstOrDefault();
if (username.IsNullOrEmpty())
{
UseApiUser(context);
}
var um = context.RequestServices.GetService<OmbiUserManager>(); var um = context.RequestServices.GetService<OmbiUserManager>();
var user = await um.Users.FirstOrDefaultAsync(x => var user = await um.Users.FirstOrDefaultAsync(x =>
x.UserName.Equals(username, StringComparison.InvariantCultureIgnoreCase)); x.UserName.Equals(username, StringComparison.InvariantCultureIgnoreCase));
@ -114,13 +119,18 @@ namespace Ombi
} }
else else
{ {
var identity = new GenericIdentity("API"); UseApiUser(context);
var principal = new GenericPrincipal(identity, new[] { "Admin", "ApiUser" });
context.User = principal;
} }
await next.Invoke(context); await next.Invoke(context);
} }
} }
private void UseApiUser(HttpContext context)
{
var identity = new GenericIdentity("API");
var principal = new GenericPrincipal(identity, new[] { "Admin", "ApiUser" });
context.User = principal;
}
} }
} }

@ -0,0 +1,25 @@
import { PlatformLocation } from "@angular/common";
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
import {
ICustomPage,
} from "../interfaces";
import { ServiceHelpers } from "./service.helpers";
@Injectable()
export class CustomPageService extends ServiceHelpers {
constructor(public http: HttpClient, public platformLocation: PlatformLocation) {
super(http, "/api/v1/CustomPage", platformLocation);
}
public getCustomPage(): Observable<ICustomPage> {
return this.http.get<ICustomPage>(this.url, {headers: this.headers});
}
public saveCustomPage(model: ICustomPage): Observable<boolean> {
return this.http.post<boolean>(this.url, model, {headers: this.headers});
}
}

@ -2,7 +2,7 @@
import { FormBuilder, FormGroup, Validators } from "@angular/forms"; import { FormBuilder, FormGroup, Validators } from "@angular/forms";
import { DomSanitizer } from "@angular/platform-browser"; import { DomSanitizer } from "@angular/platform-browser";
import { AuthService } from "../auth/auth.service"; import { AuthService } from "../auth/auth.service";
import { NotificationService, SettingsService } from "../services"; import { CustomPageService, NotificationService } from "../services";
@Component({ @Component({
templateUrl: "./custompage.component.html", templateUrl: "./custompage.component.html",
@ -14,7 +14,7 @@ export class CustomPageComponent implements OnInit {
public isEditing: boolean; public isEditing: boolean;
public isAdmin: boolean; public isAdmin: boolean;
constructor(private auth: AuthService, private settings: SettingsService, private fb: FormBuilder, constructor(private auth: AuthService, private settings: CustomPageService, private fb: FormBuilder,
private notificationService: NotificationService, private notificationService: NotificationService,
private sanitizer: DomSanitizer) { private sanitizer: DomSanitizer) {
} }
@ -29,7 +29,7 @@ export class CustomPageComponent implements OnInit {
fontAwesomeIcon: [x.fontAwesomeIcon, [Validators.required]], fontAwesomeIcon: [x.fontAwesomeIcon, [Validators.required]],
}); });
}); });
this.isAdmin = this.auth.hasRole("admin") || this.auth.hasRole("poweruser"); this.isAdmin = this.auth.hasRole("EditCustomPage");
} }
public onSubmit() { public onSubmit() {

@ -17,3 +17,4 @@ export * from "./recentlyAdded.service";
export * from "./vote.service"; export * from "./vote.service";
export * from "./requestretry.service"; export * from "./requestretry.service";
export * from "./searchV2.service"; export * from "./searchV2.service";
export * from "./custompage.service";

@ -10,7 +10,6 @@ import {
ICronTestModel, ICronTestModel,
ICronViewModelBody, ICronViewModelBody,
ICustomizationSettings, ICustomizationSettings,
ICustomPage,
IDiscordNotifcationSettings, IDiscordNotifcationSettings,
IDogNzbSettings, IDogNzbSettings,
IEmailNotificationSettings, IEmailNotificationSettings,
@ -113,14 +112,6 @@ export class SettingsService extends ServiceHelpers {
return this.http.get<IAuthenticationSettings>(`${this.url}/Authentication`, {headers: this.headers}); return this.http.get<IAuthenticationSettings>(`${this.url}/Authentication`, {headers: this.headers});
} }
public getCustomPage(): Observable<ICustomPage> {
return this.http.get<ICustomPage>(`${this.url}/CustomPage`, {headers: this.headers});
}
public saveCustomPage(model: ICustomPage): Observable<boolean> {
return this.http.post<boolean>(`${this.url}/CustomPage`, model, {headers: this.headers});
}
public getClientId(): Observable<string> { public getClientId(): Observable<string> {
return this.http.get<string>(`${this.url}/clientid`, {headers: this.headers}); return this.http.get<string>(`${this.url}/clientid`, {headers: this.headers});
} }

@ -75,7 +75,7 @@
<div class="form-group"> <div class="form-group">
<div class="checkbox"> <div class="checkbox">
<input type="checkbox" id="useCustomPage" name="useCustomPage" [(ngModel)]="settings.useCustomPage"> <input type="checkbox" id="useCustomPage" name="useCustomPage" [(ngModel)]="settings.useCustomPage">
<label for="useCustomPage" tooltipPosition="top" pTooltip="Enabled a custom page where you can fully edit">Use <label for="useCustomPage" tooltipPosition="top" pTooltip="Enabled a custom page where you can fully edit. You will need the Edit Custom Page role.">Use
Custom Page</label> Custom Page</label>
</div> </div>

@ -0,0 +1,53 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Ombi.Core.Settings;
using Ombi.Helpers;
using Ombi.Settings.Settings.Models;
namespace Ombi.Controllers
{
[ApiV1]
[Produces("application/json")]
[ApiController]
public class CustomPageController : ControllerBase
{
public CustomPageController(ISettingsService<CustomPageSettings> settings)
{
_settings = settings;
}
private readonly ISettingsService<CustomPageSettings> _settings;
/// <summary>
/// Gets the Custom Page Settings.
/// </summary>
/// <returns></returns>
[HttpGet]
[AllowAnonymous]
public async Task<CustomPageSettings> CustomPageSettings()
{
return await Get();
}
/// <summary>
/// Saves the Custom Page Settings.
/// </summary>
/// <returns></returns>
[HttpPost]
[Authorize(Roles = OmbiRoles.EditCustomPage)]
public async Task<bool> CustomPageSettings([FromBody] CustomPageSettings page)
{
return await Save(page);
}
private async Task<CustomPageSettings> Get()
{
return await _settings.GetSettingsAsync();
}
private async Task<bool> Save(CustomPageSettings settingsModel)
{
return await _settings.SaveSettingsAsync(settingsModel);
}
}
}

@ -239,6 +239,7 @@ namespace Ombi.Controllers.V1
await CreateRole(OmbiRoles.Disabled); await CreateRole(OmbiRoles.Disabled);
await CreateRole(OmbiRoles.ReceivesNewsletter); await CreateRole(OmbiRoles.ReceivesNewsletter);
await CreateRole(OmbiRoles.ManageOwnRequests); await CreateRole(OmbiRoles.ManageOwnRequests);
await CreateRole(OmbiRoles.EditCustomPage);
} }
private async Task CreateRole(string role) private async Task CreateRole(string role)

@ -10,6 +10,9 @@ using Ombi.Core.Engine.Interfaces;
using Ombi.Core.Models.Search; using Ombi.Core.Models.Search;
using Ombi.Models; using Ombi.Models;
using StackExchange.Profiling; using StackExchange.Profiling;
using Microsoft.AspNetCore.Http;
using Ombi.Core.Engine.Demo;
using Ombi.Helpers;
namespace Ombi.Controllers.V1 namespace Ombi.Controllers.V1
{ {
@ -19,18 +22,26 @@ namespace Ombi.Controllers.V1
[ApiController] [ApiController]
public class SearchController : Controller public class SearchController : Controller
{ {
public SearchController(IMovieEngine movie, ITvSearchEngine tvEngine, ILogger<SearchController> logger, IMusicSearchEngine music) public SearchController(IMovieEngine movie, ITvSearchEngine tvEngine, ILogger<SearchController> logger, IMusicSearchEngine music,
IDemoMovieSearchEngine demoMovieSearch, IDemoTvSearchEngine demoTvSearchEngine)
{ {
MovieEngine = movie; MovieEngine = movie;
TvEngine = tvEngine; TvEngine = tvEngine;
Logger = logger; Logger = logger;
MusicEngine = music; MusicEngine = music;
DemoMovieSearch = demoMovieSearch;
DemoTvSearch = demoTvSearchEngine;
IsDemo = DemoSingleton.Instance.Demo;
} }
private ILogger<SearchController> Logger { get; } private ILogger<SearchController> Logger { get; }
private IMovieEngine MovieEngine { get; } private IMovieEngine MovieEngine { get; }
private ITvSearchEngine TvEngine { get; } private ITvSearchEngine TvEngine { get; }
private IMusicSearchEngine MusicEngine { get; } private IMusicSearchEngine MusicEngine { get; }
private IDemoMovieSearchEngine DemoMovieSearch { get; }
private IDemoTvSearchEngine DemoTvSearch { get; }
private readonly bool IsDemo;
/// <summary> /// <summary>
/// Searches for a movie. /// Searches for a movie.
@ -47,6 +58,10 @@ namespace Ombi.Controllers.V1
{ {
Logger.LogDebug("Searching : {searchTerm}", searchTerm); Logger.LogDebug("Searching : {searchTerm}", searchTerm);
if (IsDemo)
{
return await DemoMovieSearch.Search(searchTerm);
}
return await MovieEngine.Search(searchTerm, null, null); return await MovieEngine.Search(searchTerm, null, null);
} }
} }
@ -54,13 +69,13 @@ namespace Ombi.Controllers.V1
/// <summary> /// <summary>
/// Searches for movies by a certain actor. /// Searches for movies by a certain actor.
/// </summary> /// </summary>
/// <param name="model">The refinement model, language code and year are both optional. Language code uses ISO 639-1</param> /// <param name="model">language code is optional, by default it will be en. Language code uses ISO 639-1</param>
/// <returns></returns> /// <returns></returns>
[HttpPost("movie/actor")] [HttpPost("movie/actor")]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesDefaultResponseType] [ProducesDefaultResponseType]
public async Task<IActionResult> SearchActor([FromBody] SearchMovieRefineModel model) public async Task<IActionResult> SearchActor([FromBody] SearchActorModel model)
{ {
if (model == null) if (model == null)
{ {
@ -172,6 +187,10 @@ namespace Ombi.Controllers.V1
[ProducesDefaultResponseType] [ProducesDefaultResponseType]
public async Task<IEnumerable<SearchMovieViewModel>> Popular() public async Task<IEnumerable<SearchMovieViewModel>> Popular()
{ {
if (IsDemo)
{
return await DemoMovieSearch.PopularMovies();
}
return await MovieEngine.PopularMovies(); return await MovieEngine.PopularMovies();
} }
/// <summary> /// <summary>
@ -184,6 +203,10 @@ namespace Ombi.Controllers.V1
[ProducesDefaultResponseType] [ProducesDefaultResponseType]
public async Task<IEnumerable<SearchMovieViewModel>> NowPlayingMovies() public async Task<IEnumerable<SearchMovieViewModel>> NowPlayingMovies()
{ {
if (IsDemo)
{
return await DemoMovieSearch.NowPlayingMovies();
}
return await MovieEngine.NowPlayingMovies(); return await MovieEngine.NowPlayingMovies();
} }
/// <summary> /// <summary>
@ -196,6 +219,10 @@ namespace Ombi.Controllers.V1
[ProducesDefaultResponseType] [ProducesDefaultResponseType]
public async Task<IEnumerable<SearchMovieViewModel>> TopRatedMovies() public async Task<IEnumerable<SearchMovieViewModel>> TopRatedMovies()
{ {
if (IsDemo)
{
return await DemoMovieSearch.TopRatedMovies();
}
return await MovieEngine.TopRatedMovies(); return await MovieEngine.TopRatedMovies();
} }
/// <summary> /// <summary>
@ -208,6 +235,10 @@ namespace Ombi.Controllers.V1
[ProducesDefaultResponseType] [ProducesDefaultResponseType]
public async Task<IEnumerable<SearchMovieViewModel>> UpcomingMovies() public async Task<IEnumerable<SearchMovieViewModel>> UpcomingMovies()
{ {
if (IsDemo)
{
return await DemoMovieSearch.UpcomingMovies();
}
return await MovieEngine.UpcomingMovies(); return await MovieEngine.UpcomingMovies();
} }
@ -222,6 +253,10 @@ namespace Ombi.Controllers.V1
[ProducesDefaultResponseType] [ProducesDefaultResponseType]
public async Task<IEnumerable<SearchTvShowViewModel>> SearchTv(string searchTerm) public async Task<IEnumerable<SearchTvShowViewModel>> SearchTv(string searchTerm)
{ {
if (IsDemo)
{
return await DemoTvSearch.Search(searchTerm);
}
return await TvEngine.Search(searchTerm); return await TvEngine.Search(searchTerm);
} }
@ -249,6 +284,10 @@ namespace Ombi.Controllers.V1
[ProducesDefaultResponseType] [ProducesDefaultResponseType]
public async Task<IEnumerable<SearchTvShowViewModel>> PopularTv() public async Task<IEnumerable<SearchTvShowViewModel>> PopularTv()
{ {
if (IsDemo)
{
return await DemoTvSearch.NowPlayingMovies();
}
return await TvEngine.Popular(); return await TvEngine.Popular();
} }
@ -262,6 +301,10 @@ namespace Ombi.Controllers.V1
[ProducesDefaultResponseType] [ProducesDefaultResponseType]
public async Task<IEnumerable<SearchTvShowViewModel>> AnticipatedTv() public async Task<IEnumerable<SearchTvShowViewModel>> AnticipatedTv()
{ {
if (IsDemo)
{
return await DemoTvSearch.NowPlayingMovies();
}
return await TvEngine.Anticipated(); return await TvEngine.Anticipated();
} }
@ -276,6 +319,10 @@ namespace Ombi.Controllers.V1
[ProducesDefaultResponseType] [ProducesDefaultResponseType]
public async Task<IEnumerable<SearchTvShowViewModel>> MostWatched() public async Task<IEnumerable<SearchTvShowViewModel>> MostWatched()
{ {
if (IsDemo)
{
return await DemoTvSearch.NowPlayingMovies();
}
return await TvEngine.MostWatches(); return await TvEngine.MostWatches();
} }
@ -289,6 +336,10 @@ namespace Ombi.Controllers.V1
[ProducesDefaultResponseType] [ProducesDefaultResponseType]
public async Task<IEnumerable<SearchTvShowViewModel>> Trending() public async Task<IEnumerable<SearchTvShowViewModel>> Trending()
{ {
if (IsDemo)
{
return await DemoTvSearch.NowPlayingMovies();
}
return await TvEngine.Trending(); return await TvEngine.Trending();
} }

@ -728,27 +728,6 @@ namespace Ombi.Controllers.V1
return emailSettings.Enabled; return emailSettings.Enabled;
} }
/// <summary>
/// Gets the Custom Page Settings.
/// </summary>
/// <returns></returns>
[HttpGet("CustomPage")]
[AllowAnonymous]
public async Task<CustomPageSettings> CustomPageSettings()
{
return await Get<CustomPageSettings>();
}
/// <summary>
/// Saves the Custom Page Settings.
/// </summary>
/// <returns></returns>
[HttpPost("CustomPage")]
public async Task<bool> CustomPageSettings([FromBody] CustomPageSettings page)
{
return await Save(page);
}
/// <summary> /// <summary>
/// Saves the discord notification settings. /// Saves the discord notification settings.
/// </summary> /// </summary>

@ -0,0 +1,8 @@
namespace Ombi.Models
{
public class SearchActorModel
{
public string SearchTerm { get; set; }
public string LanguageCode { get; set; } = "en";
}
}

@ -3,7 +3,6 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Ombi.Store.Context; using Ombi.Store.Context;
using Ombi.Store.Entities; using Ombi.Store.Entities;
using CommandLine; using CommandLine;
@ -24,12 +23,14 @@ namespace Ombi
var host = string.Empty; var host = string.Empty;
var storagePath = string.Empty; var storagePath = string.Empty;
var baseUrl = string.Empty; var baseUrl = string.Empty;
var demo = false;
var result = Parser.Default.ParseArguments<Options>(args) var result = Parser.Default.ParseArguments<Options>(args)
.WithParsed(o => .WithParsed(o =>
{ {
host = o.Host; host = o.Host;
storagePath = o.StoragePath; storagePath = o.StoragePath;
baseUrl = o.BaseUrl; baseUrl = o.BaseUrl;
demo = o.Demo;
}).WithNotParsed(err => }).WithNotParsed(err =>
{ {
foreach (var e in err) foreach (var e in err)
@ -44,6 +45,8 @@ namespace Ombi
var urlValue = string.Empty; var urlValue = string.Empty;
var instance = StoragePathSingleton.Instance; var instance = StoragePathSingleton.Instance;
var demoInstance = DemoSingleton.Instance;
demoInstance.Demo = demo;
instance.StoragePath = storagePath ?? string.Empty; instance.StoragePath = storagePath ?? string.Empty;
// Check if we need to migrate the settings // Check if we need to migrate the settings
CheckAndMigrate(); CheckAndMigrate();
@ -269,5 +272,8 @@ namespace Ombi
[Option("baseurl", Required = false, HelpText = "The base URL for reverse proxy scenarios")] [Option("baseurl", Required = false, HelpText = "The base URL for reverse proxy scenarios")]
public string BaseUrl { get; set; } public string BaseUrl { get; set; }
[Option("demo", Required = false, HelpText = "Demo mode, you will never need to use this, fuck that fruit company...")]
public bool Demo { get; set; }
} }
} }

@ -30,6 +30,7 @@ using Ombi.Store.Repository;
using Serilog; using Serilog;
using System; using System;
using System.IO; using System.IO;
using ILogger = Serilog.ILogger;
namespace Ombi namespace Ombi
{ {
@ -47,36 +48,12 @@ namespace Ombi
.AddEnvironmentVariables(); .AddEnvironmentVariables();
Configuration = builder.Build(); Configuration = builder.Build();
//if (env.IsDevelopment()) ILogger config = new LoggerConfiguration()
//{
Serilog.ILogger config;
if (string.IsNullOrEmpty(StoragePath.StoragePath))
{
config = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.RollingFile(Path.Combine(env.ContentRootPath, "Logs", "log-{Date}.txt"))
.CreateLogger();
}
else
{
config = new LoggerConfiguration()
.MinimumLevel.Debug() .MinimumLevel.Debug()
.WriteTo.RollingFile(Path.Combine(StoragePath.StoragePath, "Logs", "log-{Date}.txt")) .WriteTo.RollingFile(Path.Combine(StoragePath.StoragePath.IsNullOrEmpty() ? env.ContentRootPath : StoragePath.StoragePath, "Logs", "log-{Date}.txt"))
.CreateLogger(); .CreateLogger();
}
Log.Logger = config; Log.Logger = config;
//}
//if (env.IsProduction())
//{
// Log.Logger = new LoggerConfiguration()
// .MinimumLevel.Debug()
// .WriteTo.RollingFile(Path.Combine(env.ContentRootPath, "Logs", "log-{Date}.txt"))
// .WriteTo.SQLite("Ombi.db", "Logs", LogEventLevel.Debug)
// .CreateLogger();
//}
} }
public IConfigurationRoot Configuration { get; } public IConfigurationRoot Configuration { get; }
@ -131,7 +108,6 @@ namespace Ombi
{ {
x.UseSQLiteStorage(sqliteStorage); x.UseSQLiteStorage(sqliteStorage);
x.UseActivator(new IoCJobActivator(services.BuildServiceProvider())); x.UseActivator(new IoCJobActivator(services.BuildServiceProvider()));
//x.UseConsole();
}); });
services.AddCors(o => o.AddPolicy("MyPolicy", builder => services.AddCors(o => o.AddPolicy("MyPolicy", builder =>

@ -110,6 +110,9 @@ namespace Ombi
services.Configure<UserSettings>(configuration.GetSection("UserSettings")); services.Configure<UserSettings>(configuration.GetSection("UserSettings"));
services.Configure<TokenAuthentication>(configuration.GetSection("TokenAuthentication")); services.Configure<TokenAuthentication>(configuration.GetSection("TokenAuthentication"));
services.Configure<LandingPageBackground>(configuration.GetSection("LandingPageBackground")); services.Configure<LandingPageBackground>(configuration.GetSection("LandingPageBackground"));
services.Configure<DemoLists>(configuration.GetSection("Demo"));
var enabledDemo = Convert.ToBoolean(configuration.GetSection("Demo:Enabled").Value);
DemoSingleton.Instance.Demo = enabledDemo;
} }
public static void AddJwtAuthentication(this IServiceCollection services, IConfigurationRoot configuration) public static void AddJwtAuthentication(this IServiceCollection services, IConfigurationRoot configuration)

@ -47,5 +47,68 @@
296762, 296762,
280619 280619
] ]
},
// Please ignore the below
"Demo": {
"Enabled": false,
"Movies": [
//https://en.wikipedia.org/wiki/List_of_films_in_the_public_domain_in_the_United_States
130816,
20278,
22657,
29998,
22356,
120862,
23325,
22718,
10378,
22733,
144613,
156397,
43888,
262743,
92341,
75888,
53828,
38346,
33468,
72012,
22642,
15401,
16093,
4808,
111370,
22948,
165009,
43386,
105852,
166316,
18449,
28503,
20367,
41021 //The Devil Bat
],
"TvShows": [
//https://infogalactic.com/info/List_of_TV_series_with_episodes_in_the_public_domain
26741,
9475,
4379,
17434,
12751,
17436,
4378,
7792,
10643,
23503,
19339,
10632,
12740,
23466,
6910,
3327,
2122,
22148,
25941 // Front Row Center
]
} }
} }

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save