Fixed the issue where movie requests were no longer being requested.

Changed the API for movie requests so we only need to pass the ID to approve/Deny

TV Requests next #1601
pull/1614/head
tidusjar 7 years ago
parent b7b0381ce7
commit 7c5bca3b2b

@ -38,7 +38,7 @@ namespace Ombi.Core.Engine
var now = DateTime.Now.Ticks;
if (_dbMovies == null || now - _cacheTime > 10000)
{
var allResults = await MovieRepository.Get().ToListAsync();
var allResults = await MovieRepository.GetAll().ToListAsync();
var distinctResults = allResults.DistinctBy(x => x.TheMovieDbId);
_dbMovies = distinctResults.ToDictionary(x => x.TheMovieDbId);
@ -63,7 +63,7 @@ namespace Ombi.Core.Engine
public RequestCountModel RequestCount()
{
var movieQuery = MovieRepository.Get();
var movieQuery = MovieRepository.GetAll();
var tvQuery = TvRepository.Get();
var pendingMovies = movieQuery.Count(x => !x.Approved && !x.Available);

@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Ombi.Core.Models.Requests;
using Ombi.Core.Models.Search;
using Ombi.Store.Entities;
using Ombi.Store.Entities.Requests;
@ -16,5 +17,7 @@ namespace Ombi.Core.Engine.Interfaces
Task<MovieRequests> UpdateMovieRequest(MovieRequests request);
Task<RequestEngineResult> ApproveMovie(MovieRequests request);
Task<RequestEngineResult> ApproveMovieById(int requestId);
Task<RequestEngineResult> DenyMovieById(int modelId);
}
}

@ -86,21 +86,24 @@ namespace Ombi.Core.Engine
if (requestModel.Approved) // The rules have auto approved this
{
var result = await ApproveMovie(requestModel);
if (result.RequestAdded)
var requestEngineResult = await AddMovieRequest(requestModel, fullMovieName);
if (requestEngineResult.RequestAdded)
{
return await AddMovieRequest(requestModel, fullMovieName);
}
if (!result.IsError)
{
Logger.LogWarning("Tried auto sending movie but failed. Message: {0}", result.Message);
return new RequestEngineResult
var result = await ApproveMovie(requestModel);
if (result.IsError)
{
Message = result.Message,
ErrorMessage = result.Message,
RequestAdded = false
};
Logger.LogWarning("Tried auto sending movie but failed. Message: {0}", result.Message);
return new RequestEngineResult
{
Message = result.Message,
ErrorMessage = result.Message,
RequestAdded = false
};
}
return requestEngineResult;
}
// If there are no providers then it's successful but movie has not been sent
}
@ -116,7 +119,7 @@ namespace Ombi.Core.Engine
/// <returns></returns>
public async Task<IEnumerable<MovieRequests>> GetRequests(int count, int position)
{
var allRequests = await MovieRepository.Get().Skip(position).Take(count).ToListAsync();
var allRequests = await MovieRepository.GetWithUser().Skip(position).Take(count).ToListAsync();
allRequests.ForEach(x => PosterPathHelper.FixPosterPath(x.PosterPath));
return allRequests;
}
@ -127,7 +130,7 @@ namespace Ombi.Core.Engine
/// <returns></returns>
public async Task<IEnumerable<MovieRequests>> GetRequests()
{
var allRequests = await MovieRepository.Get().ToListAsync();
var allRequests = await MovieRepository.GetWithUser().ToListAsync();
return allRequests;
}
@ -138,10 +141,37 @@ namespace Ombi.Core.Engine
/// <returns></returns>
public async Task<IEnumerable<MovieRequests>> SearchMovieRequest(string search)
{
var allRequests = await MovieRepository.Get().ToListAsync();
var allRequests = await MovieRepository.GetWithUser().ToListAsync();
var results = allRequests.Where(x => x.Title.Contains(search, CompareOptions.IgnoreCase));
return results;
}
public async Task<RequestEngineResult> ApproveMovieById(int requestId)
{
var request = await MovieRepository.Find(requestId);
return await ApproveMovie(request);
}
public async Task<RequestEngineResult> DenyMovieById(int modelId)
{
var request = await MovieRepository.Find(modelId);
if (request == null)
{
return new RequestEngineResult
{
ErrorMessage = "Request does not exist"
};
}
request.Denied = true;
// We are denying a request
NotificationHelper.Notify(request, NotificationType.RequestDeclined);
await MovieRepository.Update(request);
return new RequestEngineResult
{
Message = "Request successfully deleted",
};
}
/// <summary>
/// This is the method that is triggered by pressing Approve on the requests page
@ -150,9 +180,19 @@ namespace Ombi.Core.Engine
/// <returns></returns>
public async Task<RequestEngineResult> ApproveMovie(MovieRequests request)
{
if (request == null)
{
return new RequestEngineResult
{
ErrorMessage = "Request does not exist"
};
}
request.Approved = true;
await MovieRepository.Update(request);
NotificationHelper.Notify(request, NotificationType.RequestApproved);
if (request.Approved)
if (request.Approved)
{
var result = await Sender.Send(request);
if (result.Success && result.Sent)
@ -188,20 +228,9 @@ namespace Ombi.Core.Engine
/// <returns></returns>
public async Task<MovieRequests> UpdateMovieRequest(MovieRequests request)
{
var allRequests = await MovieRepository.Get().ToListAsync();
var allRequests = await MovieRepository.GetWithUser().ToListAsync();
var results = allRequests.FirstOrDefault(x => x.Id == request.Id);
if (!(results.Denied ?? false) && (request.Denied ?? false))
{
// We are denying a request
NotificationHelper.Notify(request, NotificationType.RequestDeclined);
}
if (!results.Available && request.Available)
{
// We changed the availability manually
NotificationHelper.Notify(request, NotificationType.RequestAvailable);
}
results.Approved = request.Approved;
results.Available = request.Available;
results.Denied = request.Denied;
@ -225,7 +254,7 @@ namespace Ombi.Core.Engine
/// <returns></returns>
public async Task RemoveMovieRequest(int requestId)
{
var request = await MovieRepository.Get().FirstOrDefaultAsync(x => x.Id == requestId);
var request = await MovieRepository.GetAll().FirstOrDefaultAsync(x => x.Id == requestId);
await MovieRepository.Delete(request);
}
@ -244,19 +273,19 @@ namespace Ombi.Core.Engine
public async Task<IEnumerable<MovieRequests>> GetApprovedRequests()
{
var allRequests = MovieRepository.Get();
var allRequests = MovieRepository.GetWithUser();
return await allRequests.Where(x => x.Approved && !x.Available).ToListAsync();
}
public async Task<IEnumerable<MovieRequests>> GetNewRequests()
{
var allRequests = MovieRepository.Get();
var allRequests = MovieRepository.GetWithUser();
return await allRequests.Where(x => !x.Approved && !x.Available).ToListAsync();
}
public async Task<IEnumerable<MovieRequests>> GetAvailableRequests()
{
var allRequests = MovieRepository.Get();
var allRequests = MovieRepository.GetWithUser();
return await allRequests.Where(x => !x.Approved && x.Available).ToListAsync();
}
}

@ -49,7 +49,7 @@ namespace Ombi.Core
DateTime = DateTime.Now,
NotificationType = type,
RequestType = model.RequestType,
Recipient = model.RequestedUser.Email
Recipient = model.RequestedUser?.Email ?? string.Empty
};
BackgroundJob.Enqueue(() => NotificationService.Publish(notificationModel));
}
@ -61,7 +61,7 @@ namespace Ombi.Core
DateTime = DateTime.Now,
NotificationType = type,
RequestType = model.RequestType,
Recipient = model.RequestedUser.Email
Recipient = model.RequestedUser?.Email ?? string.Empty
};
BackgroundJob.Enqueue(() => NotificationService.Publish(notificationModel));
}

@ -26,7 +26,7 @@ namespace Ombi.Core.Rule.Rules.Request
if (obj.RequestType == RequestType.Movie)
{
var movie = (MovieRequests) obj;
var movieRequests = Movie.Get();
var movieRequests = Movie.GetAll();
var existing = await movieRequests.FirstOrDefaultAsync(x => x.TheMovieDbId == movie.TheMovieDbId);
if (existing != null) // Do we already have a request for this?
{

@ -104,7 +104,7 @@ namespace Ombi.Notifications.Interfaces
{
if (type == RequestType.Movie)
{
MovieRequest = await MovieRepository.Get().FirstOrDefaultAsync(x => x.Id == requestId);
MovieRequest = await MovieRepository.GetAll().FirstOrDefaultAsync(x => x.Id == requestId);
MovieRequest.PosterPath = $"https://image.tmdb.org/t/p/w300/{MovieRequest.PosterPath}";
}
else

@ -43,7 +43,7 @@ namespace Ombi.Schedule.Tests
{
ImdbId = "test"
};
_movie.Setup(x => x.Get()).Returns(new List<MovieRequests> { request }.AsQueryable());
_movie.Setup(x => x.GetAll()).Returns(new List<MovieRequests> { request }.AsQueryable());
_repo.Setup(x => x.Get("test")).ReturnsAsync(new PlexContent());
await Checker.Start();
@ -60,7 +60,7 @@ namespace Ombi.Schedule.Tests
{
ImdbId = "test"
};
_movie.Setup(x => x.Get()).Returns(new List<MovieRequests> { request }.AsQueryable());
_movie.Setup(x => x.GetAll()).Returns(new List<MovieRequests> { request }.AsQueryable());
await Checker.Start();

@ -63,7 +63,7 @@ namespace Ombi.Schedule.Jobs.Emby
private async Task ProcessMovies()
{
var movies = _movieRepo.Get().Where(x => !x.Available);
var movies = _movieRepo.GetAll().Where(x => !x.Available);
foreach (var movie in movies)
{

@ -83,7 +83,7 @@ namespace Ombi.Schedule.Jobs.Plex
private async Task ProcessMovies()
{
// Get all non available
var movies = _movieRepo.Get().Where(x => !x.Available);
var movies = _movieRepo.GetAll().Where(x => !x.Available);
foreach (var movie in movies)
{

@ -4,14 +4,14 @@ using Ombi.Store.Entities.Requests;
namespace Ombi.Store.Repository
{
public interface IMovieRequestRepository
public interface IMovieRequestRepository : IRepository<MovieRequests>
{
Task<MovieRequests> Add(MovieRequests request);
Task Delete(MovieRequests request);
IQueryable<MovieRequests> Get();
Task<MovieRequests> GetRequestAsync(int theMovieDbId);
MovieRequests GetRequest(int theMovieDbId);
Task Update(MovieRequests request);
Task Save();
IQueryable<MovieRequests> GetWithUser();
}
}

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
@ -8,9 +7,9 @@ using Ombi.Store.Entities.Requests;
namespace Ombi.Store.Repository.Requests
{
public class MovieRequestRepository : IMovieRequestRepository
public class MovieRequestRepository : Repository<MovieRequests>, IMovieRequestRepository
{
public MovieRequestRepository(IOmbiContext ctx)
public MovieRequestRepository(IOmbiContext ctx) : base(ctx)
{
Db = ctx;
}
@ -40,20 +39,13 @@ namespace Ombi.Store.Repository.Requests
.FirstOrDefault();
}
public IQueryable<MovieRequests> Get()
public IQueryable<MovieRequests> GetWithUser()
{
return Db.MovieRequests
.Include(x => x.RequestedUser)
.AsQueryable();
}
public async Task<MovieRequests> Add(MovieRequests request)
{
await Db.MovieRequests.AddAsync(request);
await Db.SaveChangesAsync();
return request;
}
public async Task Delete(MovieRequests request)
{
Db.MovieRequests.Remove(request);

@ -1,146 +1,149 @@
import { IUser } from "./IUser";
export interface IMediaBase {
imdbId: string;
id: number;
providerId: number;
title: string;
overview: string;
posterPath: string;
releaseDate: Date;
status: string;
requestedDate: Date;
approved: boolean;
type: RequestType;
requested: boolean;
available: boolean;
otherMessage: string;
adminNote: string;
requestedUser: string;
issueId: number;
denied: boolean;
deniedReason: string;
released: boolean;
imdbId: string;
id: number;
providerId: number;
title: string;
overview: string;
posterPath: string;
releaseDate: Date;
status: string;
requestedDate: Date;
approved: boolean;
type: RequestType;
requested: boolean;
available: boolean;
otherMessage: string;
adminNote: string;
requestedUser: string;
issueId: number;
denied: boolean;
deniedReason: string;
released: boolean;
}
//export interface IMovieRequestModel extends IMediaBase { }
export interface ITvRequestModel extends IMediaBase {
imdbId: string;
tvDbId: string;
childRequests: IChildTvRequest[];
rootFolderSelected: number;
firstAired: string;
imdbId: string;
tvDbId: string;
childRequests: IChildTvRequest[];
rootFolderSelected: number;
firstAired: string;
}
export interface IRequestCountModel {
pending: number;
approved: number;
available: number;
pending: number;
approved: number;
available: number;
}
export interface IChildTvRequest extends IMediaBase {
requestAll: boolean;
seasonRequests: ISeasonRequests[];
requestAll: boolean;
seasonRequests: ISeasonRequests[];
}
export interface ISeasonRequests {
seasonNumber: number;
episodes: IEpisodesRequested[];
seasonNumber: number;
episodes: IEpisodesRequested[];
}
export interface IEpisodesRequested {
episodeNumber: number;
title: string;
airDate: Date;
url: string;
requested: boolean;
status: string;
available: boolean;
episodeNumber: number;
title: string;
airDate: Date;
url: string;
requested: boolean;
status: string;
available: boolean;
}
export enum RequestType {
movie = 1,
tvShow = 2,
movie = 1,
tvShow = 2
}
export interface IRequestsPageScroll {
count: number;
position: number;
count: number;
position: number;
}
export interface IRequestGrid<T> {
available: T[];
new: T[];
approved: T[];
available: T[];
new: T[];
approved: T[];
}
// NEW WORLD
export interface IMovieRequests extends IFullBaseRequest {
theMovieDbId: number;
rootPathOverride: number;
qualityOverride: number;
theMovieDbId: number;
rootPathOverride: number;
qualityOverride: number;
rootPathOverrideTitle: string;
qualityOverrideTitle: string;
rootPathOverrideTitle: string;
qualityOverrideTitle: string;
}
export interface IMovieUpdateModel {
id: number;
}
export interface IFullBaseRequest extends IBaseRequest {
imdbId: string;
overview: string;
title: string;
posterPath: string;
releaseDate: Date;
status: string;
released: boolean;
imdbId: string;
overview: string;
title: string;
posterPath: string;
releaseDate: Date;
status: string;
released: boolean;
}
export interface IBaseRequest {
id: number;
approved: boolean;
requestedDate: Date;
available: boolean;
requestedUserId: number;
issueId: number;
denied: boolean;
deniedReason: string;
requestType: RequestType;
requestedUser: IUser;
canApprove: boolean;
id: number;
approved: boolean;
requestedDate: Date;
available: boolean;
requestedUserId: number;
issueId: number;
denied: boolean;
deniedReason: string;
requestType: RequestType;
requestedUser: IUser;
canApprove: boolean;
}
export interface ITvRequests {
id: number;
imdbId: string;
rootFolder: number;
overview: string;
title: string;
posterPath: string;
releaseDate: Date;
status: string;
childRequests: IChildRequests[];
id: number;
imdbId: string;
rootFolder: number;
overview: string;
title: string;
posterPath: string;
releaseDate: Date;
status: string;
childRequests: IChildRequests[];
}
export interface IChildRequests extends IBaseRequest {
seasonRequests: INewSeasonRequests[];
seasonRequests: INewSeasonRequests[];
}
export interface INewSeasonRequests {
id: number;
seasonNumber: number;
episodes: IEpisodesRequests[];
id: number;
seasonNumber: number;
episodes: IEpisodesRequests[];
}
export interface IEpisodesRequests {
id: number;
episodeNumber: number;
title: string;
airDate: Date;
url: string;
available: boolean;
requested: boolean;
approved: boolean;
selected: boolean; // This is for the UI only
id: number;
episodeNumber: number;
title: string;
airDate: Date;
url: string;
available: boolean;
requested: boolean;
approved: boolean;
selected: boolean; // This is for the UI only
}

@ -30,9 +30,9 @@
<br />
<div>
<span>Requested By: </span>
<span *ngIf="!isAdmin">{{request.requestedUser.userName}}</span>
<span *ngIf="!isAdmin">{{request.requestedUser.username}}</span>
<span *ngIf="isAdmin && request.requestedUser.alias">{{request.requestedUser.alias}}</span>
<span *ngIf="isAdmin && !request.requestedUser.alias">{{request.requestedUser.userName}}</span>
<span *ngIf="isAdmin && !request.requestedUser.alias">{{request.requestedUser.username}}</span>
</div>
<div>
<span>Status: </span>

@ -76,7 +76,6 @@ export class MovieRequestsComponent implements OnInit {
public approve(request: IMovieRequests) {
request.approved = true;
request.denied = false;
this.approveRequest(request);
}
@ -118,7 +117,7 @@ export class MovieRequestsComponent implements OnInit {
}
private approveRequest(request: IMovieRequests) {
this.requestService.approveMovie(request)
this.requestService.approveMovie({ id: request.id })
.subscribe(x => {
if (x.requestAdded) {

@ -6,7 +6,7 @@ import { Observable } from "rxjs/Rx";
import { TreeNode } from "primeng/primeng";
import { IRequestEngineResult } from "../interfaces";
import { IChildRequests, IMovieRequests, IRequestCountModel, IRequestGrid, ITvRequests } from "../interfaces";
import { IChildRequests, IMovieRequests, IMovieUpdateModel, IRequestCountModel, IRequestGrid, ITvRequests } from "../interfaces";
import { ISearchMovieResult } from "../interfaces";
import { ISearchTvResult } from "../interfaces";
import { ServiceAuthHelpers } from "./service.helpers";
@ -25,7 +25,7 @@ export class RequestService extends ServiceAuthHelpers {
return this.http.post(`${this.url}TV/`, JSON.stringify(tv), { headers: this.headers }).map(this.extractData);
}
public approveMovie(movie: IMovieRequests): Observable<IRequestEngineResult> {
public approveMovie(movie: IMovieUpdateModel): Observable<IRequestEngineResult> {
return this.http.post(`${this.url}Movie/Approve`, JSON.stringify(movie), { headers: this.headers }).map(this.extractData);
}

@ -90,14 +90,25 @@ namespace Ombi.Controllers
}
/// <summary>
/// Updates the specified movie request.
/// Approves the specified movie request.
/// </summary>
/// <param name="model">The model.</param>
/// <returns></returns>
[HttpPost("movie/approve")]
public async Task<RequestEngineResult> ApproveMovie([FromBody] MovieRequests model)
public async Task<RequestEngineResult> ApproveMovie([FromBody] MovieUpdateModel model)
{
return await MovieRequestEngine.ApproveMovieById(model.Id);
}
/// <summary>
/// Denies the specified movie request.
/// </summary>
/// <param name="model">The model.</param>
/// <returns></returns>
[HttpPost("movie/deny")]
public async Task<RequestEngineResult> DenyMovie([FromBody] MovieUpdateModel model)
{
return await MovieRequestEngine.ApproveMovie(model);
return await MovieRequestEngine.DenyMovieById(model.Id);
}
/// <summary>

@ -0,0 +1,33 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2017 Jamie Rees
// File: MovieUpdateModel.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.Requests
{
public class MovieUpdateModel
{
public int Id { get; set; }
}
}
Loading…
Cancel
Save