small cleanup #865

pull/1425/head
Jamie.Rees 7 years ago
parent ecae241049
commit e0018f63fa

@ -1,30 +1,4 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2017 Jamie Rees
// File: OmbiClaims.cs
// Created By: Jamie Rees
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ************************************************************************/
#endregion
namespace Ombi.Core.Claims
namespace Ombi.Core.Claims
{
public static class OmbiClaims
{

@ -1,20 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Threading.Tasks;
using Ombi.Core.Claims;
using Ombi.Core.Engine.Interfaces;
using Ombi.Core.Engine.Interfaces;
using Ombi.Core.Models.Requests;
using Ombi.Core.Models.Requests.Movie;
using Ombi.Core.Requests.Models;
using Ombi.Core.Rules;
using Ombi.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Threading.Tasks;
namespace Ombi.Core.Engine
{
public abstract class BaseMediaEngine : BaseEngine
{
protected BaseMediaEngine(IPrincipal identity, IRequestServiceMain requestService) : base(identity)
private long _cacheTime;
private Dictionary<int, MovieRequestModel> _dbMovies;
private Dictionary<int, TvRequestModel> _dbTv;
protected BaseMediaEngine(IPrincipal identity, IRequestServiceMain requestService,
IRuleEvaluator rules) : base(identity, rules)
{
RequestService = requestService;
}
@ -23,13 +28,10 @@ namespace Ombi.Core.Engine
protected IRequestService<MovieRequestModel> MovieRequestService => RequestService.MovieRequestService;
protected IRequestService<TvRequestModel> TvRequestService => RequestService.TvRequestService;
private long _cacheTime = 0;
private Dictionary<int, MovieRequestModel> _dbMovies;
private Dictionary<int, TvRequestModel> _dbTv;
protected async Task<Dictionary<int, MovieRequestModel>> GetMovieRequests()
{
long now = DateTime.Now.Ticks;
if (_dbMovies == null || (now - _cacheTime) > 10000)
var now = DateTime.Now.Ticks;
if (_dbMovies == null || now - _cacheTime > 10000)
{
var allResults = await MovieRequestService.GetAllAsync();
@ -42,8 +44,8 @@ namespace Ombi.Core.Engine
protected async Task<Dictionary<int, TvRequestModel>> GetTvRequests()
{
long now = DateTime.Now.Ticks;
if (_dbTv == null || (now - _cacheTime) > 10000)
var now = DateTime.Now.Ticks;
if (_dbTv == null || now - _cacheTime > 10000)
{
var allResults = await TvRequestService.GetAllAsync();

@ -1,18 +1,26 @@
using System.Security.Principal;
using Ombi.Core.Claims;
using Ombi.Core.Claims;
using Ombi.Core.Models.Requests;
using Ombi.Core.Rule;
using Ombi.Core.Rules;
using Ombi.Store.Entities;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
namespace Ombi.Core.Engine.Interfaces
{
public abstract class BaseEngine
{
protected BaseEngine(IPrincipal user)
protected BaseEngine(IPrincipal user, IRuleEvaluator rules)
{
User = user;
Rules = rules;
}
protected IPrincipal User { get; }
protected IRuleEvaluator Rules { get; }
protected string Username => User.Identity.Name;
protected bool HasRole(string roleName)
@ -25,10 +33,7 @@ namespace Ombi.Core.Engine.Interfaces
var sendNotification = !ShouldAutoApprove(type); /*|| !prSettings.IgnoreNotifyForAutoApprovedRequests;*/
if (HasRole(OmbiClaims.Admin))
{
sendNotification = false; // Don't bother sending a notification if the user is an admin
}
return sendNotification;
}
@ -43,13 +48,19 @@ namespace Ombi.Core.Engine.Interfaces
{
case RequestType.Movie:
return HasRole(OmbiClaims.AutoApproveMovie);
case RequestType.TvShow:
return HasRole(OmbiClaims.AutoApproveTv);
default:
return false;
}
}
public IEnumerable<RuleResult> RunRules(BaseRequestModel model)
{
var ruleResults = Rules.StartRequestRules(model).ToList();
return ruleResults;
}
}
}

@ -1,16 +1,21 @@
using System.Collections.Generic;
using Ombi.Core.Models.Search;
using System.Collections.Generic;
using System.Threading.Tasks;
using Ombi.Core.Models.Search;
namespace Ombi.Core
{
public interface IMovieEngine
{
Task<IEnumerable<SearchMovieViewModel>> NowPlayingMovies();
Task<IEnumerable<SearchMovieViewModel>> PopularMovies();
Task<IEnumerable<SearchMovieViewModel>> Search(string search);
Task<IEnumerable<SearchMovieViewModel>> TopRatedMovies();
Task<IEnumerable<SearchMovieViewModel>> UpcomingMovies();
Task<IEnumerable<SearchMovieViewModel>> LookupImdbInformation(IEnumerable<SearchMovieViewModel> movies);
}
}

@ -1,20 +1,26 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Ombi.Core.Models.Requests;
using Ombi.Core.Models.Requests;
using Ombi.Core.Models.Requests.Movie;
using Ombi.Core.Models.Search;
using Ombi.Store.Entities;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Ombi.Core.Engine
{
public interface IMovieRequestEngine
{
Task<RequestEngineResult> RequestMovie(SearchMovieViewModel model);
bool ShouldAutoApprove(RequestType requestType);
Task<IEnumerable<MovieRequestModel>> GetMovieRequests(int count, int position);
Task<IEnumerable<MovieRequestModel>> SearchMovieRequest(string search);
Task RemoveMovieRequest(int requestId);
Task<MovieRequestModel> UpdateMovieRequest(MovieRequestModel request);
RequestCountModel RequestCount();
}
}

@ -1,17 +1,22 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Ombi.Core.Models.Requests;
using Ombi.Core.Models.Requests;
using Ombi.Core.Models.Search;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Ombi.Core.Engine
{
public interface ITvRequestEngine
{
Task<IEnumerable<TvRequestModel>> GetTvRequests(int count, int position);
Task RemoveTvRequest(int requestId);
Task<RequestEngineResult> RequestTvShow(SearchTvShowViewModel tv);
Task<IEnumerable<TvRequestModel>> SearchTvRequest(string search);
Task<TvRequestModel> UpdateTvRequest(TvRequestModel request);
RequestCountModel RequestCount();
}
}

@ -1,6 +1,6 @@
using System.Collections.Generic;
using Ombi.Core.Models.Search;
using System.Collections.Generic;
using System.Threading.Tasks;
using Ombi.Core.Models.Search;
namespace Ombi.Core.Engine.Interfaces
{
@ -9,10 +9,13 @@ namespace Ombi.Core.Engine.Interfaces
Task<IEnumerable<SearchTvShowViewModel>> Search(string searchTerm);
Task<SearchTvShowViewModel> GetShowInformation(int tvdbId);
Task<IEnumerable<SearchTvShowViewModel>> Popular();
Task<IEnumerable<SearchTvShowViewModel>> Anticipated();
Task<IEnumerable<SearchTvShowViewModel>> MostWatches();
Task<IEnumerable<SearchTvShowViewModel>> Trending();
Task<IEnumerable<SearchTvShowViewModel>> Trending();
}
}

@ -1,62 +1,58 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Security.Principal;
using System.Threading.Tasks;
using Hangfire;
using Hangfire;
using Ombi.Api.TheMovieDb;
using Ombi.Api.TvMaze;
using Ombi.Core.Models.Requests;
using Ombi.Core.Models.Requests.Movie;
using Ombi.Core.Models.Search;
using Ombi.Core.Requests.Models;
using Ombi.Store.Entities;
using Ombi.Core.Rules;
using Ombi.Helpers;
using Ombi.Notifications;
using Ombi.Notifications.Models;
using Ombi.Store.Entities;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Security.Principal;
using System.Threading.Tasks;
namespace Ombi.Core.Engine
{
public class MovieRequestEngine : BaseMediaEngine, IMovieRequestEngine
{
public MovieRequestEngine(IMovieDbApi movieApi, IRequestServiceMain requestService, IPrincipal user, INotificationService notificationService) : base(user, requestService)
public MovieRequestEngine(IMovieDbApi movieApi, IRequestServiceMain requestService, IPrincipal user,
INotificationService notificationService, IRuleEvaluator r) : base(user, requestService, r)
{
MovieApi = movieApi;
NotificationService = notificationService;
}
private IMovieDbApi MovieApi { get; }
private INotificationService NotificationService { get; }
public async Task<RequestEngineResult> RequestMovie(SearchMovieViewModel model)
{
var movieInfo = await MovieApi.GetMovieInformation(model.Id);
if (movieInfo == null)
{
return new RequestEngineResult
{
RequestAdded = false,
Message = "There was an issue adding this movie!",
ErrorMessage = $"TheMovieDb didn't have any information for ID {model.Id}"
};
}
var fullMovieName =
$"{movieInfo.Title}{(!string.IsNullOrEmpty(movieInfo.ReleaseDate) ? $" ({DateTime.Parse(movieInfo.ReleaseDate).Year})" : string.Empty)}";
var existingRequest = await MovieRequestService.CheckRequestAsync(model.Id);
if (existingRequest != null)
{
return new RequestEngineResult
{
RequestAdded = false,
Message = $"{fullMovieName} has already been requested"
};
}
// TODO
//try
//{
// var content = PlexContentRepository.GetAll();
// var movies = PlexChecker.GetPlexMovies(content);
// if (PlexChecker.IsMovieAvailable(movies.ToArray(), movieInfo.Title, movieInfo.ReleaseDate?.Year.ToString()))
@ -88,20 +84,27 @@ namespace Ombi.Core.Engine
ImdbId = movieInfo.ImdbId,
PosterPath = movieInfo.PosterPath,
Title = movieInfo.Title,
ReleaseDate = !string.IsNullOrEmpty(movieInfo.ReleaseDate) ? DateTime.Parse(movieInfo.ReleaseDate) : DateTime.MinValue,
ReleaseDate = !string.IsNullOrEmpty(movieInfo.ReleaseDate)
? DateTime.Parse(movieInfo.ReleaseDate)
: DateTime.MinValue,
Status = movieInfo.Status,
RequestedDate = DateTime.UtcNow,
Approved = false,
RequestedUsers = new List<string> { Username },
Issues = IssueState.None,
RequestedUsers = new List<string> {Username},
Issues = IssueState.None
};
try
{
if (ShouldAutoApprove(RequestType.Movie))
{
model.Approved = true;
var ruleResults = RunRules(requestModel).ToList();
if (ruleResults.Any(x => !x.Success))
return new RequestEngineResult
{
ErrorMessage = ruleResults.FirstOrDefault(x => !string.IsNullOrEmpty(x.Message)).Message
};
if (requestModel.Approved) // The rules have auto approved this
{
// var result = await MovieSender.Send(model);
// if (result.Result)
// {
@ -120,7 +123,6 @@ namespace Ombi.Core.Engine
// }
// if (!result.MovieSendingEnabled)
// {
// return await AddRequest(model, settings, $"{fullMovieName} {Resources.UI.Search_SuccessfullyAdded}");
// }
@ -131,10 +133,8 @@ namespace Ombi.Core.Engine
// });
}
return await AddMovieRequest(requestModel, /*settings,*/
$"{fullMovieName} has been successfully added!");
$"{fullMovieName} has been successfully added!");
}
catch (Exception e)
{
@ -160,8 +160,48 @@ namespace Ombi.Core.Engine
return null;
}
private IEnumerable<EpisodesModel> GetListDifferences(IEnumerable<EpisodesModel> existing, IEnumerable<EpisodesModel> request)
public async Task<IEnumerable<MovieRequestModel>> GetMovieRequests(int count, int position)
{
var allRequests = await MovieRequestService.GetAllAsync(count, position);
return allRequests;
}
public async Task<IEnumerable<MovieRequestModel>> SearchMovieRequest(string search)
{
var allRequests = await MovieRequestService.GetAllAsync();
var results = allRequests.Where(x => x.Title.Contains(search, CompareOptions.IgnoreCase));
return results;
}
public async Task<MovieRequestModel> UpdateMovieRequest(MovieRequestModel request)
{
var allRequests = await MovieRequestService.GetAllAsync();
var results = allRequests.FirstOrDefault(x => x.Id == request.Id);
results.Approved = request.Approved;
results.Available = request.Available;
results.Denied = request.Denied;
results.DeniedReason = request.DeniedReason;
results.AdminNote = request.AdminNote;
results.ImdbId = request.ImdbId;
results.IssueId = request.IssueId;
results.Issues = request.Issues;
results.OtherMessage = request.OtherMessage;
results.Overview = request.Overview;
results.PosterPath = request.PosterPath;
results.RequestedUsers = request.RequestedUsers?.ToList() ?? new List<string>();
var model = MovieRequestService.UpdateRequest(results);
return model;
}
public async Task RemoveMovieRequest(int requestId)
{
await MovieRequestService.DeleteRequestAsync(requestId);
}
private IEnumerable<EpisodesModel> GetListDifferences(IEnumerable<EpisodesModel> existing,
IEnumerable<EpisodesModel> request)
{
var newRequest = request
.Select(r =>
@ -169,12 +209,12 @@ namespace Ombi.Core.Engine
{
SeasonNumber = r.SeasonNumber,
EpisodeNumber = r.EpisodeNumber
}).ToList();
})
.ToList();
return newRequest.Except(existing);
}
private async Task<RequestEngineResult> AddMovieRequest(MovieRequestModel model, string message)
{
await MovieRequestService.AddRequestAsync(model);
@ -188,7 +228,9 @@ namespace Ombi.Core.Engine
DateTime = DateTime.Now,
NotificationType = NotificationType.NewRequest,
RequestType = model.Type,
ImgSrc = model.Type == RequestType.Movie ? $"https://image.tmdb.org/t/p/w300/{model.PosterPath}" : model.PosterPath
ImgSrc = model.Type == RequestType.Movie
? $"https://image.tmdb.org/t/p/w300/{model.PosterPath}"
: model.PosterPath
};
BackgroundJob.Enqueue(() => NotificationService.Publish(notificationModel).Wait());
@ -212,46 +254,7 @@ namespace Ombi.Core.Engine
// await RequestLimitRepo.UpdateAsync(usersLimit);
//}
return new RequestEngineResult { RequestAdded = true };
}
public async Task<IEnumerable<MovieRequestModel>> GetMovieRequests(int count, int position)
{
var allRequests = await MovieRequestService.GetAllAsync(count, position);
return allRequests;
}
public async Task<IEnumerable<MovieRequestModel>> SearchMovieRequest(string search)
{
var allRequests = await MovieRequestService.GetAllAsync();
var results = allRequests.Where(x => x.Title.Contains(search, CompareOptions.IgnoreCase));
return results;
}
public async Task<MovieRequestModel> UpdateMovieRequest(MovieRequestModel request)
{
var allRequests = await MovieRequestService.GetAllAsync();
var results = allRequests.FirstOrDefault(x => x.Id == request.Id);
results.Approved = request.Approved;
results.Available = request.Available;
results.Denied = request.Denied;
results.DeniedReason = request.DeniedReason;
results.AdminNote = request.AdminNote;
results.ImdbId = request.ImdbId;
results.IssueId = request.IssueId;
results.Issues = request.Issues;
results.OtherMessage = request.OtherMessage;
results.Overview = request.Overview;
results.PosterPath = request.PosterPath;
results.RequestedUsers = request.RequestedUsers?.ToList() ?? new List<string>();
var model = MovieRequestService.UpdateRequest(results);
return model;
}
public async Task RemoveMovieRequest(int requestId)
{
await MovieRequestService.DeleteRequestAsync(requestId);
return new RequestEngineResult {RequestAdded = true};
}
}
}

@ -1,30 +1,28 @@
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Threading.Tasks;
using AutoMapper;
using AutoMapper;
using Microsoft.Extensions.Logging;
using Ombi.Api.TheMovieDb;
using Ombi.Api.TheMovieDb.Models;
using Ombi.Core.IdentityResolver;
using Ombi.Core.Models.Requests;
using Ombi.Core.Models.Requests.Movie;
using Ombi.Core.Models.Search;
using Ombi.Core.Requests.Models;
using Ombi.Core.Rules;
using Ombi.Core.Settings;
using Ombi.Core.Settings.Models.External;
using Ombi.Store.Entities;
using Ombi.Store.Repository;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Threading.Tasks;
namespace Ombi.Core.Engine
{
public class MovieSearchEngine : BaseMediaEngine, IMovieEngine
{
public MovieSearchEngine(IPrincipal identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper, ISettingsService<PlexSettings> plexSettings,
public MovieSearchEngine(IPrincipal identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper,
ISettingsService<PlexSettings> plexSettings,
ISettingsService<EmbySettings> embySettings, IPlexContentRepository repo,
ILogger<MovieSearchEngine> logger)
: base(identity, service)
ILogger<MovieSearchEngine> logger, IRuleEvaluator r)
: base(identity, service, r)
{
MovieApi = movApi;
Mapper = mapper;
@ -41,18 +39,16 @@ namespace Ombi.Core.Engine
private ILogger<MovieSearchEngine> Logger { get; }
private IPlexContentRepository PlexContentRepo { get; }
public async Task<IEnumerable<SearchMovieViewModel>> LookupImdbInformation(IEnumerable<SearchMovieViewModel> movies)
public async Task<IEnumerable<SearchMovieViewModel>> LookupImdbInformation(
IEnumerable<SearchMovieViewModel> movies)
{
var searchMovieViewModels
= movies as IList<SearchMovieViewModel> ?? movies.ToList();
if (searchMovieViewModels == null || !searchMovieViewModels.Any())
{
return new List<SearchMovieViewModel>();
}
var retVal = new List<SearchMovieViewModel>();
Dictionary<int, MovieRequestModel> dbMovies = await GetMovieRequests();
var dbMovies = await GetMovieRequests();
var plexSettings = await PlexSettings.GetSettingsAsync();
var embySettings = await EmbySettings.GetSettingsAsync();
@ -77,6 +73,7 @@ namespace Ombi.Core.Engine
}
return null;
}
public async Task<IEnumerable<SearchMovieViewModel>> PopularMovies()
{
var result = await MovieApi.PopularMovies();
@ -109,32 +106,28 @@ namespace Ombi.Core.Engine
}
return null;
}
public async Task<IEnumerable<SearchMovieViewModel>> NowPlayingMovies()
{
var result = await MovieApi.NowPlaying();
if (result != null)
{
Logger.LogDebug("Search Result: {result}", result);
return await TransformMovieResultsToResponse(result);
}
return null;
}
private async Task<List<SearchMovieViewModel>> TransformMovieResultsToResponse(IEnumerable<MovieSearchResult> movies)
private async Task<List<SearchMovieViewModel>> TransformMovieResultsToResponse(
IEnumerable<MovieSearchResult> movies)
{
var viewMovies = new List<SearchMovieViewModel>();
Dictionary<int, MovieRequestModel> dbMovies = await GetMovieRequests();
var dbMovies = await GetMovieRequests();
var plexSettings = await PlexSettings.GetSettingsAsync();
var embySettings = await EmbySettings.GetSettingsAsync();
foreach (var movie in movies)
{
viewMovies.Add(await ProcessSingleMovie(movie, dbMovies, plexSettings, embySettings));
}
return viewMovies;
}
@ -144,9 +137,8 @@ namespace Ombi.Core.Engine
var showInfo = await MovieApi.GetMovieInformation(viewMovie.Id);
if (plexSettings.Enable)
{
var item = await PlexContentRepo.Get(showInfo.ImdbId.ToString());
if(item != null)
var item = await PlexContentRepo.Get(showInfo.ImdbId);
if (item != null)
{
viewMovie.Available = true;
viewMovie.PlexUrl = item.Url;
@ -186,14 +178,14 @@ namespace Ombi.Core.Engine
viewMovie.Available = requestedMovie.Available;
}
return viewMovie;
}
private async Task<SearchMovieViewModel> ProcessSingleMovie(MovieSearchResult movie, Dictionary<int, MovieRequestModel> existingRequests, PlexSettings plexSettings, EmbySettings embySettings)
private async Task<SearchMovieViewModel> ProcessSingleMovie(MovieSearchResult movie,
Dictionary<int, MovieRequestModel> existingRequests, PlexSettings plexSettings, EmbySettings embySettings)
{
var viewMovie = Mapper.Map<SearchMovieViewModel>(movie);
return await ProcessSingleMovie(viewMovie, existingRequests, plexSettings, embySettings);
}
}
}
}

@ -1,36 +1,36 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Security.Principal;
using System.Threading.Tasks;
using AutoMapper;
using AutoMapper;
using Hangfire;
using Ombi.Api.TvMaze;
using Ombi.Core.Models.Requests;
using Ombi.Core.Models.Search;
using Ombi.Store.Entities;
using Ombi.Core.Rules;
using Ombi.Helpers;
using Ombi.Notifications;
using Ombi.Notifications.Models;
using Ombi.Core.Rules;
using Ombi.Store.Entities;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Security.Principal;
using System.Threading.Tasks;
namespace Ombi.Core.Engine
{
public class TvRequestEngine : BaseMediaEngine, ITvRequestEngine
{
public TvRequestEngine(ITvMazeApi tvApi, IRequestServiceMain requestService, IPrincipal user, INotificationService notificationService, IMapper map,
IRuleEvaluator rule) : base(user, requestService)
public TvRequestEngine(ITvMazeApi tvApi, IRequestServiceMain requestService, IPrincipal user,
INotificationService notificationService, IMapper map,
IRuleEvaluator rule) : base(user, requestService, rule)
{
TvApi = tvApi;
NotificationService = notificationService;
Mapper = map;
Rules = rule;
}
private INotificationService NotificationService { get; }
private ITvMazeApi TvApi { get; }
private IMapper Mapper { get; }
private IRuleEvaluator Rules { get; }
public async Task<RequestEngineResult> RequestTvShow(SearchTvShowViewModel tv)
{
@ -51,11 +51,11 @@ namespace Ombi.Core.Engine
Status = showInfo.status,
RequestedDate = DateTime.UtcNow,
Approved = false,
RequestedUsers = new List<string> { Username },
RequestedUsers = new List<string> {Username},
Issues = IssueState.None,
ProviderId = tv.Id,
RequestAll = tv.RequestAll,
SeasonRequests = tv.SeasonRequests,
SeasonRequests = tv.SeasonRequests
};
var model = new TvRequestModel
@ -70,8 +70,7 @@ namespace Ombi.Core.Engine
Approved = false,
ImdbId = showInfo.externals?.imdb ?? string.Empty,
TvDbId = tv.Id.ToString(),
ProviderId = tv.Id,
ProviderId = tv.Id
};
model.ChildRequests.Add(childRequest);
@ -88,7 +87,7 @@ namespace Ombi.Core.Engine
Url = e.url,
Title = e.name,
AirDate = DateTime.Parse(e.airstamp),
EpisodeNumber = e.number,
EpisodeNumber = e.number
});
}
}
@ -97,46 +96,29 @@ namespace Ombi.Core.Engine
{
var latest = showInfo.Season.OrderBy(x => x.SeasonNumber).FirstOrDefault();
foreach (var modelSeasonRequest in childRequest.SeasonRequests)
{
if (modelSeasonRequest.SeasonNumber == latest.SeasonNumber)
{
foreach (var episodesRequested in modelSeasonRequest.Episodes)
{
episodesRequested.Requested = true;
}
}
}
}
if (tv.FirstSeason)
{
var first = showInfo.Season.OrderByDescending(x => x.SeasonNumber).FirstOrDefault();
foreach (var modelSeasonRequest in childRequest.SeasonRequests)
{
if (modelSeasonRequest.SeasonNumber == first.SeasonNumber)
{
foreach (var episodesRequested in modelSeasonRequest.Episodes)
{
episodesRequested.Requested = true;
}
}
}
}
var ruleResults = Rules.StartRequestRules(model);
var ruleResults = RunRules(model).ToList();
if (ruleResults.Any(x => !x.Success))
{
return new RequestEngineResult()
return new RequestEngineResult
{
ErrorMessage = ruleResults.FirstOrDefault(x => !string.IsNullOrEmpty(x.Message)).Message,
ErrorMessage = ruleResults.FirstOrDefault(x => !string.IsNullOrEmpty(x.Message)).Message
};
}
var existingRequest = await TvRequestService.CheckRequestAsync(model.Id);
if (existingRequest != null)
{
return await AddExistingRequest(model, existingRequest);
}
// This is a new request
return await AddRequest(model);
@ -147,12 +129,14 @@ namespace Ombi.Core.Engine
var allRequests = await TvRequestService.GetAllAsync(count, position);
return allRequests;
}
public async Task<IEnumerable<TvRequestModel>> SearchTvRequest(string search)
{
var allRequests = await TvRequestService.GetAllAsync();
var results = allRequests.Where(x => x.Title.Contains(search, CompareOptions.IgnoreCase));
return results;
}
public async Task<TvRequestModel> UpdateTvRequest(TvRequestModel request)
{
var allRequests = await TvRequestService.GetAllAsync();
@ -168,25 +152,20 @@ namespace Ombi.Core.Engine
await TvRequestService.DeleteRequestAsync(requestId);
}
private async Task<RequestEngineResult> AddExistingRequest(TvRequestModel newRequest, TvRequestModel existingRequest)
private async Task<RequestEngineResult> AddExistingRequest(TvRequestModel newRequest,
TvRequestModel existingRequest)
{
var child = newRequest.ChildRequests.FirstOrDefault(); // There will only be 1
var episodeDiff = new List<SeasonRequestModel>();
foreach (var existingChild in existingRequest.ChildRequests)
{
var difference = GetListDifferences(existingChild.SeasonRequests, child.SeasonRequests).ToList();
if (difference.Any())
{
episodeDiff = difference;
}
}
if (episodeDiff.Any())
{
// This is where there are some episodes that have been requested, but this list contains the 'new' requests
child.SeasonRequests = episodeDiff;
}
existingRequest.ChildRequests.AddRange(newRequest.ChildRequests);
TvRequestService.UpdateRequest(existingRequest);
@ -198,7 +177,8 @@ namespace Ombi.Core.Engine
return await AfterRequest(newRequest);
}
private IEnumerable<SeasonRequestModel> GetListDifferences(IEnumerable<SeasonRequestModel> existing, IEnumerable<SeasonRequestModel> request)
private IEnumerable<SeasonRequestModel> GetListDifferences(IEnumerable<SeasonRequestModel> existing,
IEnumerable<SeasonRequestModel> request)
{
var newRequest = request
.Select(r =>
@ -206,7 +186,8 @@ namespace Ombi.Core.Engine
{
SeasonNumber = r.SeasonNumber,
Episodes = r.Episodes
}).ToList();
})
.ToList();
return newRequest.Except(existing);
}
@ -253,9 +234,7 @@ namespace Ombi.Core.Engine
// await RequestLimitRepo.UpdateAsync(usersLimit);
//}
return new RequestEngineResult { RequestAdded = true };
return new RequestEngineResult {RequestAdded = true};
}
}
}

@ -1,29 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Threading.Tasks;
using AutoMapper;
using AutoMapper;
using Ombi.Api.Trakt;
using Ombi.Api.TvMaze;
using Ombi.Api.TvMaze.Models;
using Ombi.Core.Engine.Interfaces;
using Ombi.Core.Models.Requests;
using Ombi.Core.Models.Search;
using Ombi.Core.Requests.Models;
using Ombi.Core.Rules;
using Ombi.Core.Settings;
using Ombi.Core.Settings.Models.External;
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
{
public class TvSearchEngine : BaseMediaEngine, ITvSearchEngine
{
public TvSearchEngine(IPrincipal identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper, ISettingsService<PlexSettings> plexSettings,
ISettingsService<EmbySettings> embySettings, IPlexContentRepository repo, ITraktApi trakt)
: base(identity, service)
ISettingsService<EmbySettings> embySettings, IPlexContentRepository repo, ITraktApi trakt, IRuleEvaluator r)
: base(identity, service, r)
{
TvMazeApi = tvMaze;
Mapper = mapper;
@ -40,7 +39,6 @@ namespace Ombi.Core.Engine
private IPlexContentRepository PlexContentRepo { get; }
private ITraktApi TraktApi { get; }
public async Task<IEnumerable<SearchTvShowViewModel>> Search(string searchTerm)
{
var searchResult = await TvMazeApi.Search(searchTerm);
@ -76,7 +74,6 @@ namespace Ombi.Core.Engine
EpisodeNumber = e.number,
});
mapped.SeasonRequests.Add(newSeason);
}
else
{
@ -86,7 +83,6 @@ namespace Ombi.Core.Engine
Title = e.name,
AirDate = DateTime.Parse(e.airstamp),
EpisodeNumber = e.number,
});
}
}
@ -108,11 +104,13 @@ namespace Ombi.Core.Engine
var result = await TraktApi.GetAnticipatedShows();
return await ProcessResults(result);
}
public async Task<IEnumerable<SearchTvShowViewModel>> MostWatches()
{
var result = await TraktApi.GetMostWatchesShows();
return await ProcessResults(result);
}
public async Task<IEnumerable<SearchTvShowViewModel>> Trending()
{
var result = await TraktApi.GetTrendingShows();
@ -158,7 +156,6 @@ namespace Ombi.Core.Engine
if (item.Id > 0 && item.Available)
{
// TODO need to check if the episodes are available
var tvdbid = item.Id;
if (existingRequests.ContainsKey(tvdbid))
@ -173,7 +170,6 @@ namespace Ombi.Core.Engine
{
foreach (var existingRequestChildRequest in existingRequest.ChildRequests)
{
// Find the existing request season
var existingSeason =
existingRequestChildRequest.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == season.SeasonNumber);
@ -187,7 +183,6 @@ namespace Ombi.Core.Engine
episodeSearching.Approved = ep.Approved;
}
}
}
}
//if (sonarrCached.Select(x => x.TvdbId).Contains(tvdbid) || sickRageCache.Contains(tvdbid))
@ -200,4 +195,4 @@ namespace Ombi.Core.Engine
return item;
}
}
}
}

@ -1,16 +1,21 @@
using System.Collections.Generic;
using Ombi.Core.Models;
using System.Collections.Generic;
using System.Threading.Tasks;
using Ombi.Core.Models;
namespace Ombi.Core.IdentityResolver
{
public interface IUserIdentityManager
{
Task<UserDto> CreateUser(UserDto user);
Task<bool> CredentialsValid(string username, string password);
Task<UserDto> GetUser(string username);
Task<IEnumerable<UserDto>> GetUsers();
Task DeleteUser(UserDto user);
Task<UserDto> UpdateUser(UserDto userDto);
}
}

@ -1,40 +1,13 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2017 Jamie Rees
// File: UserIdentityManager.cs
// Created By: Jamie Rees
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ************************************************************************/
#endregion
using AutoMapper;
using Microsoft.AspNetCore.Cryptography.KeyDerivation;
using Ombi.Core.Models;
using Ombi.Store.Entities;
using Ombi.Store.Repository;
using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.AspNetCore.Cryptography.KeyDerivation;
using Ombi.Core.Models;
using Ombi.Store.Entities;
using Ombi.Store.Repository;
namespace Ombi.Core.IdentityResolver
{
@ -46,7 +19,7 @@ namespace Ombi.Core.IdentityResolver
Mapper = mapper;
}
private IMapper Mapper { get; }
private IMapper Mapper { get; }
private IUserRepository UserRepository { get; }
public async Task<bool> CredentialsValid(string username, string password)
@ -96,7 +69,7 @@ namespace Ombi.Core.IdentityResolver
private UserHash HashPassword(string password)
{
// generate a 128-bit salt using a secure PRNG
byte[] salt = new byte[128 / 8];
var salt = new byte[128 / 8];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(salt);
@ -104,18 +77,17 @@ namespace Ombi.Core.IdentityResolver
return HashPassword(password, salt);
}
private UserHash HashPassword(string password, byte[] salt)
{
// derive a 256-bit subkey (use HMACSHA1 with 10,000 iterations)
var hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
password: password,
salt: salt,
prf: KeyDerivationPrf.HMACSHA1,
iterationCount: 10000,
numBytesRequested: 256 / 8));
password,
salt,
KeyDerivationPrf.HMACSHA1,
10000,
256 / 8));
return new UserHash { HashedPass = hashed, Salt = salt };
return new UserHash {HashedPass = hashed, Salt = salt};
}
private class UserHash

@ -1,13 +1,13 @@
using System;
using Newtonsoft.Json;
using Ombi.Store.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Ombi.Store.Entities;
namespace Ombi.Core.Models.Requests
{
public class BaseRequestModel : Entity
{
{
public int ProviderId { get; set; }
public string Overview { get; set; }
public string Title { get; set; }
@ -29,7 +29,7 @@ namespace Ombi.Core.Models.Requests
[JsonIgnore]
public bool Released => DateTime.UtcNow > ReleaseDate;
[JsonIgnore]
public IEnumerable<string> AllUsers
{
@ -37,16 +37,14 @@ namespace Ombi.Core.Models.Requests
{
var u = new List<string>();
if (RequestedUsers != null && RequestedUsers.Any())
{
u.AddRange(RequestedUsers);
}
return u;
}
}
[JsonIgnore]
public bool CanApprove => !Approved && !Available;
public bool UserHasRequested(string username)
{
return AllUsers.Any(x => x.Equals(username, StringComparison.OrdinalIgnoreCase));

@ -1,28 +1,42 @@
using System.Collections.Generic;
using Ombi.Core.Models.Requests;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Ombi.Core.Models.Requests;
using Ombi.Store.Entities;
namespace Ombi.Core.Requests.Models
{
public interface IRequestService<T> where T : BaseRequestModel
{
int AddRequest(T model);
Task<int> AddRequestAsync(T model);
void BatchDelete(IEnumerable<T> model);
void BatchUpdate(IEnumerable<T> model);
T CheckRequest(int providerId);
Task<T> CheckRequestAsync(int providerId);
void DeleteRequest(T request);
Task DeleteRequestAsync(int request);
Task DeleteRequestAsync(T request);
T Get(int id);
IEnumerable<T> GetAll();
Task<IEnumerable<T>> GetAllAsync();
Task<IEnumerable<T>> GetAllAsync(int count, int position);
Task<T> GetAsync(int id);
T UpdateRequest(T model);
IQueryable<T> GetAllQueryable();
}
}

@ -1,11 +1,10 @@
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using Ombi.Core.Requests.Models;
using Ombi.Core.Requests.Models;
using Ombi.Helpers;
using Ombi.Store.Entities;
using Ombi.Store.Repository;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Ombi.Core.Models.Requests
{
@ -16,11 +15,18 @@ namespace Ombi.Core.Models.Requests
Repo = repo;
RequestType = typeof(T) == typeof(TvRequestModel) ? RequestType.TvShow : RequestType.Movie;
}
private RequestType RequestType { get; }
private IRequestRepository Repo { get; }
public int AddRequest(T model)
{
var entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId };
var entity = new RequestBlobs
{
Type = model.Type,
Content = ByteConverterHelper.ReturnBytes(model),
ProviderId = model.ProviderId
};
var id = Repo.Insert(entity);
return id.Id;
@ -28,7 +34,12 @@ namespace Ombi.Core.Models.Requests
public async Task<int> AddRequestAsync(T model)
{
var entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId };
var entity = new RequestBlobs
{
Type = model.Type,
Content = ByteConverterHelper.ReturnBytes(model),
ProviderId = model.ProviderId
};
var id = await Repo.InsertAsync(entity).ConfigureAwait(false);
return id.Id;
@ -40,9 +51,7 @@ namespace Ombi.Core.Models.Requests
var blob = blobs.FirstOrDefault(x => x.ProviderId == providerId && x.Type == RequestType);
if (blob == null)
{
return null;
}
var model = ByteConverterHelper.ReturnObject<T>(blob.Content);
model.Id = blob.Id;
return model;
@ -51,10 +60,9 @@ namespace Ombi.Core.Models.Requests
public async Task<T> CheckRequestAsync(int providerId)
{
var blobs = await Repo.GetAllAsync().ConfigureAwait(false);
var blob = blobs.FirstOrDefault(x => x.ProviderId == providerId && x.Type == RequestType); if (blob == null)
{
var blob = blobs.FirstOrDefault(x => x.ProviderId == providerId && x.Type == RequestType);
if (blob == null)
return null;
}
var model = ByteConverterHelper.ReturnObject<T>(blob.Content);
model.Id = blob.Id;
return model;
@ -71,6 +79,7 @@ namespace Ombi.Core.Models.Requests
var blob = await Repo.GetAsync(request.Id).ConfigureAwait(false);
Repo.Delete(blob);
}
public async Task DeleteRequestAsync(int request)
{
var blob = await Repo.GetAsync(request).ConfigureAwait(false);
@ -83,18 +92,17 @@ namespace Ombi.Core.Models.Requests
b.Content = ByteConverterHelper.ReturnBytes(model);
var blob = Repo.Update(b);
return model;
}
public T Get(int id)
{
var blob = Repo.Get(id);
if (blob == null)
{
return default(T);
}
var model = ByteConverterHelper.ReturnObject<T>(blob.Content);
model.Id = blob.Id; // They should always be the same, but for somereason a user didn't have it in the db https://github.com/tidusjar/Ombi/issues/862#issuecomment-269743847
model.Id =
blob
.Id; // They should always be the same, but for somereason a user didn't have it in the db https://github.com/tidusjar/Ombi/issues/862#issuecomment-269743847
return model;
}
@ -102,9 +110,7 @@ namespace Ombi.Core.Models.Requests
{
var blob = await Repo.GetAsync(id).ConfigureAwait(false);
if (blob == null)
{
return default(T);
}
var model = ByteConverterHelper.ReturnObject<T>(blob.Content);
model.Id = blob.Id;
return model;
@ -118,9 +124,7 @@ namespace Ombi.Core.Models.Requests
foreach (var b in blobs)
{
if (b == null)
{
continue;
}
var model = ByteConverterHelper.ReturnObject<T>(b.Content);
model.Id = b.Id;
retVal.Add(model);
@ -135,9 +139,7 @@ namespace Ombi.Core.Models.Requests
foreach (var b in blobs)
{
if (b == null)
{
continue;
}
var model = ByteConverterHelper.ReturnObject<T>(b.Content);
model.Id = b.Id;
retVal.Add(model);
@ -153,9 +155,7 @@ namespace Ombi.Core.Models.Requests
foreach (var b in blobs.Where(x => x.Type == RequestType))
{
if (b == null)
{
continue;
}
var model = ByteConverterHelper.ReturnObject<T>(b.Content);
model.Id = b.Id;
retVal.Add(model);
@ -171,9 +171,7 @@ namespace Ombi.Core.Models.Requests
foreach (var b in blobs.Where(x => x.Type == RequestType))
{
if (b == null)
{
continue;
}
var model = ByteConverterHelper.ReturnObject<T>(b.Content);
model.Id = b.Id;
retVal.Add(model);
@ -183,13 +181,29 @@ namespace Ombi.Core.Models.Requests
public void BatchUpdate(IEnumerable<T> model)
{
var entities = model.Select(m => new RequestBlobs { Type = m.Type, Content = ByteConverterHelper.ReturnBytes(m), ProviderId = m.ProviderId, Id = m.Id }).ToList();
var entities = model
.Select(m => new RequestBlobs
{
Type = m.Type,
Content = ByteConverterHelper.ReturnBytes(m),
ProviderId = m.ProviderId,
Id = m.Id
})
.ToList();
Repo.UpdateAll(entities);
}
public void BatchDelete(IEnumerable<T> model)
{
var entities = model.Select(m => new RequestBlobs { Type = m.Type, Content = ByteConverterHelper.ReturnBytes(m), ProviderId = m.ProviderId, Id = m.Id }).ToList();
var entities = model
.Select(m => new RequestBlobs
{
Type = m.Type,
Content = ByteConverterHelper.ReturnBytes(m),
ProviderId = m.ProviderId,
Id = m.Id
})
.ToList();
Repo.DeleteAll(entities);
}
}

@ -2,8 +2,6 @@
{
public class MovieRequestModel : BaseRequestModel
{
public string ImdbId { get; set; }
}
}

@ -1,6 +1,6 @@
using System;
using Ombi.Store.Entities;
using System;
using System.Collections.Generic;
using Ombi.Store.Entities;
namespace Ombi.Core.Models.Requests
{
@ -12,8 +12,10 @@ namespace Ombi.Core.Models.Requests
{
case RequestType.Movie:
return "Movie";
case RequestType.TvShow:
return "TV Show";
default:
return string.Empty;
}
@ -27,13 +29,14 @@ namespace Ombi.Core.Models.Requests
NoSubtitles = 1,
WrongContent = 2,
PlaybackIssues = 3,
Other = 4, // Provide a message
Other = 4 // Provide a message
}
public class EpisodesModel : IEquatable<EpisodesModel>
{
public int SeasonNumber { get; set; }
public int EpisodeNumber { get; set; }
public bool Equals(EpisodesModel other)
{
// Check whether the compared object is null.
@ -73,5 +76,4 @@ namespace Ombi.Core.Models.Requests
public bool Available { get; set; }
public bool Approved { get; set; }
}
}

@ -1,5 +1,5 @@
using System;
using Ombi.Store.Entities;
using Ombi.Store.Entities;
using System;
namespace Ombi.Core.Models.Requests
{

@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using Ombi.Store.Entities;
using System.Collections.Generic;
namespace Ombi.Core.Models.Requests
{
@ -10,16 +8,17 @@ namespace Ombi.Core.Models.Requests
{
ChildRequests = new List<ChildTvRequest>();
}
public string ImdbId { get; set; }
public string TvDbId { get; set; }
public List<ChildTvRequest> ChildRequests { get; set; }
/// <summary>
/// For TV Shows with a custom root folder
/// For TV Shows with a custom root folder
/// </summary>
/// <value>
/// The root folder selected.
/// The root folder selected.
/// </value>
public int RootFolderSelected { get; set; }
}
@ -28,6 +27,5 @@ namespace Ombi.Core.Models.Requests
{
public bool RequestAll { get; set; }
public List<SeasonRequestModel> SeasonRequests { get; set; } = new List<SeasonRequestModel>();
}
}

@ -1,31 +1,4 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2017 Jamie Rees
// File: SearchMovieViewModel.cs
// Created By: Jamie Rees
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ************************************************************************/
#endregion
using System;
using System;
using System.Collections.Generic;
namespace Ombi.Core.Models.Search

@ -1,5 +1,5 @@
using System.Collections.Generic;
using Ombi.Core.Models.Requests;
using Ombi.Core.Models.Requests;
using System.Collections.Generic;
namespace Ombi.Core.Models.Search
{
@ -25,29 +25,29 @@ namespace Ombi.Core.Models.Search
public int SiteRating { get; set; }
/// <summary>
/// This is used from the Trakt API
/// This is used from the Trakt API
/// </summary>
/// <value>
/// The trailer.
/// The trailer.
/// </value>
public string Trailer { get; set; }
/// <summary>
/// This is used from the Trakt API
/// This is used from the Trakt API
/// </summary>
/// <value>
/// The trailer.
/// The trailer.
/// </value>
public string Homepage { get; set; }
public List<SeasonRequestModel> SeasonRequests { get; set; } = new List<SeasonRequestModel>();
/// <summary>
/// If we are requesting the entire series
/// If we are requesting the entire series
/// </summary>
public bool RequestAll { get; set; }
public bool FirstSeason { get; set; }
public bool LatestSeason { get; set; }
}
}

@ -1,30 +1,4 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2017 Jamie Rees
// File: SearchViewModel.cs
// Created By: Jamie Rees
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ************************************************************************/
#endregion
namespace Ombi.Core.Models.Search
namespace Ombi.Core.Models.Search
{
public class SearchViewModel
{

@ -18,4 +18,4 @@ namespace Ombi.Core.Models.UI
public string Value { get; set; }
public bool Enabled { get; set; }
}
}
}

@ -1,6 +1,5 @@
using System.Collections.Generic;
using System.Security.Claims;
using System.Security.Principal;
namespace Ombi.Core.Models
{
@ -14,16 +13,12 @@ namespace Ombi.Core.Models
public string Password { get; set; }
public byte[] Salt { get; set; }
public UserType UserType { get; set; }
}
public enum UserType
{
LocalUser = 1,
PlexUser = 2,
EmbyUser = 3,
EmbyUser = 3
}
}

@ -1,14 +1,12 @@
using System.Threading.Tasks;
using Ombi.Core.Models.Requests;
using Ombi.Core.Models.Requests.Movie;
using Ombi.Core.Models.Requests.Movie;
using Ombi.Core.Settings;
using Ombi.Settings.Settings.Models.External;
using System.Threading.Tasks;
namespace Ombi.Core
{
public class MovieSender
{
public MovieSender(ISettingsService<RadarrSettings> radarrSettings)
{
RadarrSettings = radarrSettings;
@ -37,12 +35,17 @@ namespace Ombi.Core
//return SendToRadarr(model, radarrSettings, qualityId);
}
return new MovieSenderResult { Success = false, MovieSent = false, Message = "There are no movie providers enabled!"};
return new MovieSenderResult
{
Success = false,
MovieSent = false,
Message = "There are no movie providers enabled!"
};
}
//private MovieSenderResult SendToRadarr(MovieRequestModel model, RadarrSettings settings, string qualityId)
//{
// var qualityProfile = 0;
//{
//private MovieSenderResult SendToRadarr(MovieRequestModel model, RadarrSettings settings, string qualityId)
// if (!string.IsNullOrEmpty(qualityId)) // try to parse the passed in quality, otherwise use the settings default quality
// {
// int.TryParse(qualityId, out qualityProfile);
@ -67,6 +70,5 @@ namespace Ombi.Core
// }
// return new MovieSenderResult { Result = false, MovieSendingEnabled = true };
//}
}
}

@ -1,17 +1,15 @@
using Ombi.Core.Rules;
namespace Ombi.Core.Rule
namespace Ombi.Core.Rule
{
public abstract class BaseRule
{
public RuleResult Success()
{
return new RuleResult { Success = true };
return new RuleResult {Success = true};
}
public RuleResult Fail(string message)
{
return new RuleResult { Message = message };
return new RuleResult {Message = message};
}
}
}
}

@ -1,4 +1,5 @@
using Ombi.Core.Models.Requests;
using Ombi.Core.Rule;
namespace Ombi.Core.Rules
{
@ -6,4 +7,4 @@ namespace Ombi.Core.Rules
{
RuleResult Execute(T obj);
}
}
}

@ -1,5 +1,6 @@
using System.Collections.Generic;
using Ombi.Core.Models.Requests;
using Ombi.Core.Models.Requests;
using Ombi.Core.Rule;
using System.Collections.Generic;
namespace Ombi.Core.Rules
{

@ -1,11 +1,11 @@
using Ombi.Core.Models.Requests;
using Ombi.Core.Rule;
using Ombi.Core.Rules;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Ombi.Core.Rules
namespace Ombi.Core.Rule
{
public class RuleEvaluator : IRuleEvaluator
{
@ -14,26 +14,22 @@ namespace Ombi.Core.Rules
RequestRules = new List<IRequestRules<BaseRequestModel>>();
var baseType = typeof(BaseRule).FullName;
System.Reflection.Assembly ass = typeof(RuleEvaluator).GetTypeInfo().Assembly;
var ass = typeof(RuleEvaluator).GetTypeInfo().Assembly;
foreach (TypeInfo ti in ass.DefinedTypes)
{
foreach (var ti in ass.DefinedTypes)
if (ti?.BaseType?.FullName == baseType)
{
var type = ti.AsType();
var type = ti?.AsType();
var ctors = type.GetConstructors();
var ctor = ctors.FirstOrDefault();
var services = new List<object>();
foreach (var param in ctor.GetParameters())
{
services.Add(provider.GetService(param.ParameterType));
}
var item = Activator.CreateInstance(type, services.ToArray());// ti.GetType is wrong
RequestRules.Add((IRequestRules<BaseRequestModel>)item);
var item = Activator.CreateInstance(type, services.ToArray()); // ti.GetType is wrong
RequestRules.Add((IRequestRules<BaseRequestModel>) item);
}
}
}
private List<IRequestRules<BaseRequestModel>> RequestRules { get; }
@ -50,4 +46,4 @@ namespace Ombi.Core.Rules
return results;
}
}
}
}

@ -1,12 +1,8 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Ombi.Core.Rules
namespace Ombi.Core.Rule
{
public class RuleResult
{
public bool Success { get; set; }
public string Message { get; set; }
}
}
}

@ -1,10 +1,8 @@
using Ombi.Core.Claims;
using Ombi.Core.Models.Requests;
using Ombi.Core.Rules;
using System;
using System.Collections.Generic;
using Ombi.Store.Entities;
using System.Security.Principal;
using System.Text;
namespace Ombi.Core.Rule.Rules
{
@ -16,23 +14,20 @@ namespace Ombi.Core.Rule.Rules
}
private IPrincipal User { get; }
public RuleResult Execute(BaseRequestModel obj)
{
if(User.IsInRole(OmbiClaims.Admin))
if (User.IsInRole(OmbiClaims.Admin))
{
obj.Approved = true;
return Success();
}
if (obj.Type == Store.Entities.RequestType.Movie && User.IsInRole(OmbiClaims.AutoApproveMovie))
{
if (obj.Type == RequestType.Movie && User.IsInRole(OmbiClaims.AutoApproveMovie))
obj.Approved = true;
}
if (obj.Type == Store.Entities.RequestType.TvShow && User.IsInRole(OmbiClaims.AutoApproveTv))
{
if (obj.Type == RequestType.TvShow && User.IsInRole(OmbiClaims.AutoApproveTv))
obj.Approved = true;
}
return Success(); // We don't really care, we just don't set the obj to approve
}
}
}
}

@ -1,6 +1,7 @@
using Ombi.Core.Claims;
using Ombi.Core.Models.Requests;
using Ombi.Core.Rules;
using Ombi.Store.Entities;
using System.Security.Principal;
namespace Ombi.Core.Rule.Rules
@ -13,29 +14,22 @@ namespace Ombi.Core.Rule.Rules
}
private IPrincipal User { get; }
public RuleResult Execute(BaseRequestModel obj)
{
if(User.IsInRole(OmbiClaims.Admin))
{
if (User.IsInRole(OmbiClaims.Admin))
return Success();
}
if (obj.Type == Store.Entities.RequestType.Movie)
if (obj.Type == RequestType.Movie)
{
if (User.IsInRole(OmbiClaims.RequestMovie))
{
return Success();
}
return Fail("You do not have permissions to Request a Movie");
}
else
{
if (User.IsInRole(OmbiClaims.RequestTv))
{
return Success();
}
return Fail("You do not have permissions to Request a Movie");
}
if (User.IsInRole(OmbiClaims.RequestTv))
return Success();
return Fail("You do not have permissions to Request a Movie");
}
}
}
}

@ -1,10 +1,8 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging;
using Ombi.Api.Sonarr;
using Ombi.Core.Models.Requests;
using Ombi.Core.Settings.Models.External;
using System.Linq;
using System.Threading.Tasks;
namespace Ombi.Core
{
@ -71,14 +69,10 @@ namespace Ombi.Core
private async Task<string> GetSonarrRootPath(int pathId, SonarrSettings sonarrSettings)
{
var rootFoldersResult = await SonarrApi.GetRootFolders(sonarrSettings.ApiKey, sonarrSettings.FullUri);
foreach (var r in rootFoldersResult.Where(r => r.id == pathId))
{
return r.path;
}
return string.Empty;
}
}
}

@ -15,6 +15,7 @@ using Ombi.Core.Engine.Interfaces;
using Ombi.Core.IdentityResolver;
using Ombi.Core.Models.Requests;
using Ombi.Core.Requests.Models;
using Ombi.Core.Rule;
using Ombi.Core.Settings;
using Ombi.Notifications;
using Ombi.Schedule;

@ -1,31 +1,4 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2017 Jamie Rees
// File: BaseV1ApiController.cs
// Created By: Jamie Rees
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ************************************************************************/
#endregion
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc;
namespace Ombi.Controllers
{

@ -1,14 +1,12 @@

<settings-menu></settings-menu>
<settings-menu></settings-menu>
<div *ngIf="settings">
<fieldset>
<legend>Plex Configuration</legend>
<div class="checkbox col-md-2 " style="float: right;">
<input type="checkbox" id="advanced" [(ngModel)]="advanced" ng-checked="advanced">
<label for="advanced">Advanced</label>
</div>
<div class="checkbox col-md-2 " style="float: right;">
<input type="checkbox" id="advanced" [(ngModel)]="advanced" ng-checked="advanced">
<label for="advanced">Advanced</label>
</div>
<div class="form-group col-md-3">
<div class="checkbox">
@ -47,27 +45,26 @@
<div class="form-group">
<div>
<button id="requestToken" (click)="requestServers(server)" class="btn btn-primary-outline">Load Servers <i class="fa fa-key"></i></button>
</div>
</div>
<br />
<br />
<div class="form-group">
<label for="username" class="control-label">Please select the server</label><br />
<label for="username" class="control-label">Please select the server</label><br />
<div class="btn-group">
<div class="btn-group">
<div class="btn-group">
<a [attr.disabled]="!serversButton ? true : null" href="#" class="btn btn-info-outline dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
Servers
<span class="caret"></span>
</a>
<ul *ngIf="loadedServers" class="dropdown-menu"><li *ngFor="let s of loadedServers.servers.server"><a (click)="selectServer(s,server)">{{s.name}}</a></li>
</ul>
</div>
<a [attr.disabled]="!serversButton ? true : null" href="#" class="btn btn-info-outline dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
Servers
<span class="caret"></span>
</a>
<ul *ngIf="loadedServers" class="dropdown-menu">
<li *ngFor="let s of loadedServers.servers.server">
<a (click)="selectServer(s,server)">{{s.name}}</a>
</li>
</ul>
</div>
</div>
</div>
<div *ngIf="advanced">
@ -102,10 +99,8 @@
<div class="form-group">
<div class="checkbox">
<input type="checkbox" id="EnableTvEpisodeSearching" [(ngModel)]="server.enableEpisodeSearching" ng-checked="server.enableEpisodeSearching">
<label for="EnableTvEpisodeSearching">Enable Episode Searching</label>
</div>
<small>
If enabled then we will lookup all episodes on your Plex server and store them in the local database. This will stop episode requests that already exist on Plex (that might not be in Sonarr).
@ -113,7 +108,6 @@
</small>
</div>
<div class="form-group">
<label for="authToken" class="control-label">Plex Authorization Token</label>
<div class="">
@ -127,10 +121,6 @@
<input type="text" class="form-control-custom form-control" id="MachineIdentifier" name="MachineIdentifier" [(ngModel)]="server.machineIdentifier" value="{{server.machineIdentifier}}">
</div>
</div>
</div>
<label>Please select the libraries you want Ombi to look in for content</label>
<br />
@ -148,7 +138,6 @@
<label for="{{lib.title}}">{{lib.title}}</label>
</div>
</div>
</div>
</div>
@ -165,9 +154,6 @@
</div>
</ngb-tabset>
<div class="form-group">
<div>
<button (click)="save()" type="submit" id="save" class="btn btn-primary-outline">Submit</button>

@ -5,7 +5,6 @@ import "rxjs/add/operator/takeUntil";
import { IPlexSettings, IPlexLibraries, IPlexServer } from '../../interfaces/ISettings';
import { IPlexServerResponse, IPlexServerViewModel } from '../../interfaces/IPlex'
import { SettingsService } from '../../services/settings.service';
import { PlexService } from '../../services/applications/plex.service';
import { NotificationService } from "../../services/notification.service";
@ -16,7 +15,6 @@ import { NotificationService } from "../../services/notification.service";
templateUrl: './plex.component.html',
})
export class PlexComponent implements OnInit, OnDestroy {
constructor(private settingsService: SettingsService, private notificationService: NotificationService, private plexService: PlexService) { }
settings: IPlexSettings;
@ -27,7 +25,6 @@ export class PlexComponent implements OnInit, OnDestroy {
advanced = false;
serversButton = false;
ngOnInit(): void {
this.settingsService.getPlex().subscribe(x => {
this.settings = x;
@ -49,8 +46,7 @@ export class PlexComponent implements OnInit, OnDestroy {
});
}
selectServer(selectedServer: IPlexServerResponse, server : IPlexServer)
{
selectServer(selectedServer: IPlexServerResponse, server: IPlexServer) {
server.ip = selectedServer.localAddresses.split(',')[0];
server.name = selectedServer.name;
server.machineIdentifier = selectedServer.machineIdentifier;
@ -75,7 +71,6 @@ export class PlexComponent implements OnInit, OnDestroy {
}
removeServer(server: IPlexServer) {
this.notificationService.warning("Disabled", "This feature is currently disabled");
//var index = this.settings.servers.indexOf(server, 0);
//if (index > -1) {
@ -84,13 +79,11 @@ export class PlexComponent implements OnInit, OnDestroy {
}
loadLibraries(server: IPlexServer) {
if (server.ip == null)
{
if (server.ip == null) {
this.notificationService.error("Not Configured", "Plex is not yet configured correctly")
return;
}
this.plexService.getLibraries(server).subscribe(x => {
server.plexSelectedLibraries = [];
x.mediaContainer.directory.forEach((item, index) => {
var lib: IPlexLibraries = {
@ -99,7 +92,6 @@ export class PlexComponent implements OnInit, OnDestroy {
enabled: false
};
server.plexSelectedLibraries.push(lib);
});
});
}

Loading…
Cancel
Save