Added the ability to re-process requests

pull/4185/head v4.0.1345
tidusjar 3 years ago
parent 6c64f3d4a3
commit 264568f396

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Ombi.Core.Models;
using Ombi.Core.Models.Requests;
@ -24,5 +25,6 @@ namespace Ombi.Core.Engine.Interfaces
Task UnSubscribeRequest(int requestId, RequestType type);
Task SubscribeToRequest(int requestId, RequestType type);
Task<RequestQuotaCountModel> GetRemainingRequests(OmbiUser user = null);
Task<RequestEngineResult> ReProcessRequest(int requestId, CancellationToken cancellationToken);
}
}

@ -21,6 +21,7 @@ using Ombi.Settings.Settings.Models;
using Ombi.Store.Entities.Requests;
using Ombi.Store.Repository;
using Ombi.Core.Models;
using System.Threading;
namespace Ombi.Core.Engine
{
@ -555,6 +556,11 @@ namespace Ombi.Core.Engine
await NotificationHelper.Notify(request, NotificationType.RequestApproved);
}
return await ProcessSendingMovie(request);
}
private async Task<RequestEngineResult> ProcessSendingMovie(MovieRequests request)
{
if (request.Approved)
{
var result = await Sender.Send(request);
@ -634,6 +640,21 @@ namespace Ombi.Core.Engine
return await MovieRepository.GetAll().AnyAsync(x => x.RequestedUserId == userId);
}
public async Task<RequestEngineResult> ReProcessRequest(int requestId, CancellationToken cancellationToken)
{
var request = await MovieRepository.Find(requestId);
if (request == null)
{
return new RequestEngineResult
{
Result = false,
ErrorMessage = "Request does not exist"
};
}
return await ProcessSendingMovie(request);
}
public async Task<RequestEngineResult> MarkUnavailable(int modelId)
{
var request = await MovieRepository.Find(modelId);

@ -25,6 +25,7 @@ using Ombi.Settings.Settings.Models;
using Ombi.Store.Entities.Requests;
using Ombi.Store.Repository;
using Ombi.Core.Models;
using System.Threading;
namespace Ombi.Core.Engine
{
@ -896,6 +897,22 @@ namespace Ombi.Core.Engine
}
public async Task<RequestEngineResult> ReProcessRequest(int requestId, CancellationToken cancellationToken)
{
var request = await TvRepository.GetChild().FirstOrDefaultAsync(x => x.Id == requestId, cancellationToken);
if (request == null)
{
return new RequestEngineResult
{
Result = false,
ErrorMessage = "Request does not exist"
};
}
return await ProcessSendingShow(request);
}
private async Task<RequestEngineResult> AfterRequest(ChildRequests model, string requestOnBehalf)
{
var sendRuleResult = await RunSpecificRule(model, SpecificRules.CanSendNotification);
@ -913,6 +930,11 @@ namespace Ombi.Core.Engine
EpisodeCount = model.SeasonRequests.Select(m => m.Episodes.Count).Sum(),
});
return await ProcessSendingShow(model);
}
private async Task<RequestEngineResult> ProcessSendingShow(ChildRequests model)
{
if (model.Approved)
{
// Autosend

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
@ -28,6 +29,11 @@ namespace Ombi.Store.Repository
return await _db.FindAsync(key);
}
public async Task<T> Find(object key, CancellationToken cancellationToken)
{
return await _db.FindAsync(new[] { key }, cancellationToken: cancellationToken);
}
public IQueryable<T> GetAll()
{
return _db.AsQueryable();

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Query;
@ -12,6 +13,7 @@ namespace Ombi.Store.Repository
public interface IRepository<T> where T : Entity
{
Task<T> Find(object key);
Task<T> Find(object key, CancellationToken cancellationToken);
IQueryable<T> GetAll();
Task<T> FirstOrDefaultAsync(Expression<Func<T, bool>> predicate);
Task AddRange(IEnumerable<T> content, bool save = true);

@ -24,6 +24,7 @@
[type]="requestType"
(openTrailer)="openDialog()"
(onAdvancedOptions)="openAdvancedOptions()"
(onReProcessRequest)="reProcessRequest()"
>
</social-icons>

@ -190,6 +190,16 @@ export class MovieDetailsComponent {
});
}
public reProcessRequest() {
this.requestService2.reprocessRequest(this.movieRequest.id, RequestType.movie).subscribe(result => {
if (result.result) {
this.messageService.send(result.message ? result.message : "Successfully Re-processed the request", "Ok");
} else {
this.messageService.send(result.errorMessage, "Ok");
}
});
}
private loadBanner() {
this.imageService.getMovieBanner(this.theMovidDbId.toString()).subscribe(x => {
if (!this.movie.backdropPath) {

@ -35,5 +35,9 @@
<span *ngIf="type === RequestType.movie"> {{ 'MediaDetails.RadarrConfiguration' | translate}}</span>
<span *ngIf="type === RequestType.tvShow"> {{ 'MediaDetails.SonarrConfiguration' | translate}}</span>
</button>
<button *ngIf="type === RequestType.movie" mat-menu-item (click)="reProcessRequest()">
<i class="fas fa-sync icon-spacing"></i>
<span> {{ 'MediaDetails.ReProcessRequest' | translate}}</span>
</button>
</mat-menu>
</div>

@ -26,6 +26,7 @@ export class SocialIconsComponent {
@Output() openTrailer: EventEmitter<any> = new EventEmitter();
@Output() onAdvancedOptions: EventEmitter<any> = new EventEmitter();
@Output() onReProcessRequest: EventEmitter<any> = new EventEmitter();
public RequestType = RequestType;
@ -37,4 +38,8 @@ export class SocialIconsComponent {
public openAdvancedOptions() {
this.onAdvancedOptions.emit();
}
public reProcessRequest() {
this.onReProcessRequest.emit();
}
}

@ -70,6 +70,7 @@
<button *ngIf="request.available" mat-raised-button color="warn" (click)="changeAvailability(request, false);">{{ 'Requests.MarkUnavailable' | translate }}</button>
<button *ngIf="!request.denied" mat-raised-button color="danger" (click)="deny(request);">{{ 'Requests.Deny' | translate }}</button>
<button mat-raised-button color="danger" (click)="delete(request);">{{ 'Requests.RequestPanel.Delete' | translate }}</button>
<button mat-raised-button color="accent" (click)="reProcessRequest(request);">{{ 'MediaDetails.ReProcessRequest' | translate }}</button>
</div>

@ -4,6 +4,7 @@ import { RequestService } from "../../../../../services/request.service";
import { MessageService } from "../../../../../services";
import { MatDialog } from "@angular/material/dialog";
import { DenyDialogComponent } from "../../../shared/deny-dialog/deny-dialog.component";
import { RequestServiceV2 } from "../../../../../services/requestV2.service";
@Component({
templateUrl: "./tv-requests-panel.component.html",
@ -16,7 +17,9 @@ export class TvRequestsPanelComponent {
public displayedColumns: string[] = ['number', 'title', 'airDate', 'status'];
constructor(private requestService: RequestService, private messageService: MessageService,
constructor(private requestService: RequestService,
private requestService2: RequestServiceV2,
private messageService: MessageService,
public dialog: MatDialog) {
}
@ -83,9 +86,9 @@ export class TvRequestsPanelComponent {
width: '250px',
data: {requestId: request.id, requestType: RequestType.tvShow}
});
dialogRef.afterClosed().subscribe(result => {
request.denied = true;
request.denied = true;
request.seasonRequests.forEach((season) => {
season.episodes.forEach((ep) => {
ep.approved = false;
@ -93,4 +96,14 @@ export class TvRequestsPanelComponent {
});
});
}
public reProcessRequest(request: IChildRequests) {
this.requestService2.reprocessRequest(request.id, RequestType.tvShow).subscribe(result => {
if (result.result) {
this.messageService.send(result.message ? result.message : "Successfully Re-processed the request", "Ok");
} else {
this.messageService.send(result.errorMessage, "Ok");
}
});
}
}

@ -187,5 +187,4 @@ export class RequestService extends ServiceHelpers {
public removeAlbumRequest(request: number): any {
return this.http.delete(`${this.url}music/${request}`, {headers: this.headers});
}
}

@ -4,7 +4,7 @@ import { Injectable, Inject } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { Observable } from "rxjs";
import { ServiceHelpers } from "./service.helpers";
import { IRequestsViewModel, IMovieRequests, IChildRequests, IMovieAdvancedOptions as IMediaAdvancedOptions, IRequestEngineResult, IAlbumRequest, ITvRequestViewModelV2 } from "../interfaces";
import { IRequestsViewModel, IMovieRequests, IChildRequests, IMovieAdvancedOptions as IMediaAdvancedOptions, IRequestEngineResult, IAlbumRequest, ITvRequestViewModelV2, RequestType } from "../interfaces";
@Injectable()
@ -92,4 +92,8 @@ export class RequestServiceV2 extends ServiceHelpers {
public requestTv(tv: ITvRequestViewModelV2): Observable<IRequestEngineResult> {
return this.http.post<IRequestEngineResult>(`${this.url}TV/`, JSON.stringify(tv), {headers: this.headers});
}
public reprocessRequest(requestId: number, type: RequestType): Observable<IRequestEngineResult> {
return this.http.post<IRequestEngineResult>(`${this.url}reprocess/${type}/${requestId}`, undefined, { headers: this.headers });
}
}

@ -11,6 +11,7 @@ using System;
using Ombi.Store.Entities;
using System.Linq;
using Microsoft.Extensions.Logging;
using Ombi.Attributes;
namespace Ombi.Controllers.V2
{
@ -134,12 +135,14 @@ namespace Ombi.Controllers.V2
return await _tvRequestEngine.GetUnavailableRequests(count, position, sort, sortOrder);
}
[PowerUser]
[HttpPost("movie/advancedoptions")]
public async Task<RequestEngineResult> UpdateAdvancedOptions([FromBody] MediaAdvancedOptions options)
{
return await _movieRequestEngine.UpdateAdvancedOptions(options);
}
[PowerUser]
[HttpPost("tv/advancedoptions")]
public async Task<RequestEngineResult> UpdateTvAdvancedOptions([FromBody] MediaAdvancedOptions options)
{
@ -198,6 +201,21 @@ namespace Ombi.Controllers.V2
return result;
}
[PowerUser]
[HttpPost("reprocess/{type}/{requestId}")]
public async Task<IActionResult> ReProcessRequest(RequestType type, int requestId)
{
switch (type)
{
case RequestType.TvShow:
return Ok(await _tvRequestEngine.ReProcessRequest(requestId, HttpContext.RequestAborted));
case RequestType.Movie:
return Ok(await _movieRequestEngine.ReProcessRequest(requestId, HttpContext.RequestAborted));
}
return BadRequest();
}
private string GetApiAlias()
{
// Make sure this only applies when using the API KEY

@ -288,7 +288,8 @@
"RadarrConfiguration": "Radarr Configuration",
"RequestOnBehalf": "Request on behalf of",
"PleaseSelectUser": "Please select a user",
"StreamingOn": "Streaming On"
"StreamingOn": "Streaming On",
"ReProcessRequest": "Re-Process Request"
},
"Discovery": {
"PopularTab": "Popular",

Loading…
Cancel
Save