mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-11 15:56:05 -07:00
The Approving child requests now work!
This commit is contained in:
parent
eb433867af
commit
745ff844ca
10 changed files with 98 additions and 91 deletions
|
@ -16,7 +16,7 @@ namespace Ombi.Core.Tests.Engine
|
||||||
{
|
{
|
||||||
RequestService = new Mock<IRequestService<MovieRequestModel>>();
|
RequestService = new Mock<IRequestService<MovieRequestModel>>();
|
||||||
var requestService = new RequestService(null, RequestService.Object);
|
var requestService = new RequestService(null, RequestService.Object);
|
||||||
Engine = new MovieRequestEngine(null, requestService, null, null, null);
|
Engine = new MovieRequestEngine(null, requestService, null, null, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MovieRequestEngine Engine { get; }
|
private MovieRequestEngine Engine { get; }
|
||||||
|
|
|
@ -96,7 +96,7 @@ namespace Ombi.Core.Engine
|
||||||
Status = movieInfo.Status,
|
Status = movieInfo.Status,
|
||||||
RequestedDate = DateTime.UtcNow,
|
RequestedDate = DateTime.UtcNow,
|
||||||
Approved = false,
|
Approved = false,
|
||||||
RequestedUsers = new List<string> { Username },
|
RequestedUser =Username,
|
||||||
Issues = IssueState.None
|
Issues = IssueState.None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@ namespace Ombi.Core.Engine
|
||||||
results.OtherMessage = request.OtherMessage;
|
results.OtherMessage = request.OtherMessage;
|
||||||
results.Overview = request.Overview;
|
results.Overview = request.Overview;
|
||||||
results.PosterPath = request.PosterPath;
|
results.PosterPath = request.PosterPath;
|
||||||
results.RequestedUsers = request.RequestedUsers?.ToList() ?? new List<string>();
|
results.RequestedUser = request.RequestedUser;
|
||||||
|
|
||||||
var model = MovieRequestService.UpdateRequest(results);
|
var model = MovieRequestService.UpdateRequest(results);
|
||||||
return model;
|
return model;
|
||||||
|
@ -202,21 +202,6 @@ namespace Ombi.Core.Engine
|
||||||
await MovieRequestService.DeleteRequestAsync(requestId);
|
await MovieRequestService.DeleteRequestAsync(requestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<EpisodesModel> GetListDifferences(IEnumerable<EpisodesModel> existing,
|
|
||||||
IEnumerable<EpisodesModel> request)
|
|
||||||
{
|
|
||||||
var newRequest = request
|
|
||||||
.Select(r =>
|
|
||||||
new EpisodesModel
|
|
||||||
{
|
|
||||||
SeasonNumber = r.SeasonNumber,
|
|
||||||
EpisodeNumber = r.EpisodeNumber
|
|
||||||
})
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
return newRequest.Except(existing);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<RequestEngineResult> AddMovieRequest(MovieRequestModel model, string message)
|
private async Task<RequestEngineResult> AddMovieRequest(MovieRequestModel model, string message)
|
||||||
{
|
{
|
||||||
await MovieRequestService.AddRequestAsync(model);
|
await MovieRequestService.AddRequestAsync(model);
|
||||||
|
|
|
@ -71,7 +71,7 @@ namespace Ombi.Core.Engine
|
||||||
Status = showInfo.status,
|
Status = showInfo.status,
|
||||||
RequestedDate = DateTime.UtcNow,
|
RequestedDate = DateTime.UtcNow,
|
||||||
Approved = false,
|
Approved = false,
|
||||||
RequestedUsers = new List<string> { Username },
|
RequestedUser = Username,
|
||||||
Issues = IssueState.None,
|
Issues = IssueState.None,
|
||||||
ProviderId = tv.Id,
|
ProviderId = tv.Id,
|
||||||
RequestAll = tv.RequestAll,
|
RequestAll = tv.RequestAll,
|
||||||
|
@ -95,22 +95,22 @@ namespace Ombi.Core.Engine
|
||||||
|
|
||||||
model.ChildRequests.Add(childRequest);
|
model.ChildRequests.Add(childRequest);
|
||||||
|
|
||||||
if (childRequest.SeasonRequests.Any())
|
//if (childRequest.SeasonRequests.Any())
|
||||||
{
|
//{
|
||||||
var episodes = await TvApi.EpisodeLookup(showInfo.id);
|
// var episodes = await TvApi.EpisodeLookup(showInfo.id);
|
||||||
|
|
||||||
foreach (var e in episodes)
|
// foreach (var e in episodes)
|
||||||
{
|
// {
|
||||||
var season = childRequest.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == e.season);
|
// var season = childRequest.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == e.season);
|
||||||
season?.Episodes.Add(new EpisodesRequested
|
// season?.Episodes.Add(new EpisodesRequested
|
||||||
{
|
// {
|
||||||
Url = e.url,
|
// Url = e.url,
|
||||||
Title = e.name,
|
// Title = e.name,
|
||||||
AirDate = DateTime.Parse(e.airstamp),
|
// AirDate = DateTime.Parse(e.airstamp),
|
||||||
EpisodeNumber = e.number
|
// EpisodeNumber = e.number
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
if (tv.LatestSeason)
|
if (tv.LatestSeason)
|
||||||
{
|
{
|
||||||
|
@ -218,19 +218,45 @@ namespace Ombi.Core.Engine
|
||||||
return await AfterRequest(newRequest);
|
return await AfterRequest(newRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<SeasonRequestModel> GetListDifferences(IEnumerable<SeasonRequestModel> existing,
|
private IEnumerable<SeasonRequestModel> GetListDifferences(List<SeasonRequestModel> existing,
|
||||||
IEnumerable<SeasonRequestModel> request)
|
List<SeasonRequestModel> request)
|
||||||
{
|
{
|
||||||
var newRequest = request
|
var requestsToRemove = new List<SeasonRequestModel>();
|
||||||
.Select(r =>
|
foreach (var r in request)
|
||||||
new SeasonRequestModel
|
{
|
||||||
{
|
// Do we have an existing season?
|
||||||
SeasonNumber = r.SeasonNumber,
|
var existingSeason = existing.FirstOrDefault(x => x.SeasonNumber == r.SeasonNumber);
|
||||||
Episodes = r.Episodes
|
if (existingSeason == null)
|
||||||
})
|
{
|
||||||
.ToList();
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
return newRequest.Except(existing);
|
// Compare the episodes
|
||||||
|
for (var i = r.Episodes.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
var existingEpisode = existingSeason.Episodes.FirstOrDefault(x => x.EpisodeNumber == r.Episodes[i].EpisodeNumber);
|
||||||
|
if (existingEpisode == null)
|
||||||
|
{
|
||||||
|
// we are fine, we have not yet requested this
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We already have this request
|
||||||
|
r.Episodes.RemoveAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!r.Episodes.Any())
|
||||||
|
{
|
||||||
|
requestsToRemove.Add(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var remove in requestsToRemove)
|
||||||
|
{
|
||||||
|
request.Remove(remove);
|
||||||
|
}
|
||||||
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<RequestEngineResult> AddRequest(TvRequestModel model)
|
private async Task<RequestEngineResult> AddRequest(TvRequestModel model)
|
||||||
|
|
|
@ -172,6 +172,7 @@ namespace Ombi.Core.Engine
|
||||||
// Find the existing request season
|
// Find the existing request season
|
||||||
var existingSeason =
|
var existingSeason =
|
||||||
existingRequestChildRequest.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == season.SeasonNumber);
|
existingRequestChildRequest.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == season.SeasonNumber);
|
||||||
|
if(existingSeason == null) continue;
|
||||||
|
|
||||||
foreach (var ep in existingSeason.Episodes)
|
foreach (var ep in existingSeason.Episodes)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Ombi.Store.Entities;
|
using Ombi.Store.Entities;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Ombi.Core.Models.Requests
|
namespace Ombi.Core.Models.Requests
|
||||||
{
|
{
|
||||||
|
@ -22,7 +20,7 @@ namespace Ombi.Core.Models.Requests
|
||||||
public IssueState Issues { get; set; }
|
public IssueState Issues { get; set; }
|
||||||
public string OtherMessage { get; set; }
|
public string OtherMessage { get; set; }
|
||||||
public string AdminNote { get; set; }
|
public string AdminNote { get; set; }
|
||||||
public List<string> RequestedUsers { get; set; } = new List<string>();
|
public string RequestedUser { get; set; }
|
||||||
public int IssueId { get; set; }
|
public int IssueId { get; set; }
|
||||||
public bool Denied { get; set; }
|
public bool Denied { get; set; }
|
||||||
public string DeniedReason { get; set; }
|
public string DeniedReason { get; set; }
|
||||||
|
@ -30,24 +28,13 @@ namespace Ombi.Core.Models.Requests
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public bool Released => DateTime.UtcNow > ReleaseDate;
|
public bool Released => DateTime.UtcNow > ReleaseDate;
|
||||||
|
|
||||||
[JsonIgnore]
|
|
||||||
public IEnumerable<string> AllUsers
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
var u = new List<string>();
|
|
||||||
if (RequestedUsers != null && RequestedUsers.Any())
|
|
||||||
u.AddRange(RequestedUsers);
|
|
||||||
return u;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public bool CanApprove => !Approved && !Available;
|
public bool CanApprove => !Approved && !Available;
|
||||||
|
|
||||||
public bool UserHasRequested(string username)
|
public bool UserHasRequested(string username)
|
||||||
{
|
{
|
||||||
return AllUsers.Any(x => x.Equals(username, StringComparison.OrdinalIgnoreCase));
|
return RequestedUser.Equals(username, StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -14,7 +14,7 @@
|
||||||
available: boolean,
|
available: boolean,
|
||||||
otherMessage: string,
|
otherMessage: string,
|
||||||
adminNote: string,
|
adminNote: string,
|
||||||
requestedUser: string[],
|
requestedUser: string,
|
||||||
issueId: number,
|
issueId: number,
|
||||||
denied: boolean,
|
denied: boolean,
|
||||||
deniedReason: string,
|
deniedReason: string,
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ombi',
|
|
||||||
templateUrl: './request.component.html'
|
templateUrl: './request.component.html'
|
||||||
})
|
})
|
||||||
export class RequestComponent {
|
export class RequestComponent {
|
||||||
|
|
|
@ -78,29 +78,8 @@
|
||||||
</div>
|
</div>
|
||||||
<!--Child Requests-->
|
<!--Child Requests-->
|
||||||
|
|
||||||
<button type="button" class="btn btn-sm btn-info-outline" data-toggle="collapse" (click)="showChildren(request)" [attr.data-target]="'#' + request.id +'childRequests'">Children</button>
|
<button type="button" class="btn btn-sm btn-info-outline" (click)="showChildren(request)">Requests</button>
|
||||||
<div id="{{request.id}}childRequests" class="collapse">
|
|
||||||
|
|
||||||
<div *ngFor="let child of request.childRequests">
|
|
||||||
<hr />
|
|
||||||
<div *ngIf="request.requestedUsers">
|
|
||||||
Requested By: <span *ngFor="let user of request.requestedUsers">{{user}} </span>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="child.seasonRequests">
|
|
||||||
Seasons Requested: <span *ngFor="let s of child.seasonRequests">{{s.seasonNumber}} </span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<span>Request status: </span>
|
|
||||||
<span *ngIf="request.available" class="label label-success">Available</span>
|
|
||||||
<span *ngIf="request.approved && !request.available" class="label label-info">Processing Request</span>
|
|
||||||
<span *ngIf="request.denied" class="label label-danger">Request Denied</span>
|
|
||||||
<span *ngIf="request.deniedReason" title="{{request.deniedReason}}"><i class="fa fa-info-circle"></i></span>
|
|
||||||
<span *ngIf="!request.approved && !request.availble && !request.denied" class="label label-warning">Pending Approval</span>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-3 col-sm-push-3">
|
<div class="col-sm-3 col-sm-push-3">
|
||||||
|
@ -216,12 +195,36 @@
|
||||||
<h4 class="modal-title">{{selectedSeason?.title}}</h4>
|
<h4 class="modal-title">{{selectedSeason?.title}}</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="col-md-8">
|
<div class="row" *ngFor="let child of selectedSeason.childRequests">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<!--Child Requests-->
|
||||||
|
<div class="col-md-9">
|
||||||
|
<span class="col-md-12">Requested By: <b>{{child.requestedUser}}</b></span>
|
||||||
|
|
||||||
</div>
|
<span class="col-md-12" *ngIf="child.requestAll">Requested All Seasons</span>
|
||||||
|
<!--Seasons-->
|
||||||
|
<span *ngIf="child.approved && !child.available" class="label label-info">Processing Request</span>
|
||||||
|
<span *ngIf="child.denied" class="label label-danger">Request Denied</span>
|
||||||
|
<span *ngIf="child.deniedReason" title="{{child.deniedReason}}"><i class="fa fa-info-circle"></i></span>
|
||||||
|
<span *ngIf="!child.approved && !child.availble && !child.denied" class="label label-warning">Pending Approval</span>
|
||||||
|
<div class="col-md-12" *ngFor="let seasons of child.seasonRequests">
|
||||||
|
|
||||||
<div class="col-md-4">
|
|
||||||
|
|
||||||
|
<span>Season: {{seasons.seasonNumber}}</span>
|
||||||
|
<span>Episodes:</span>
|
||||||
|
|
||||||
|
<div *ngFor="let episode of seasons.episodes">
|
||||||
|
<!--Episodes-->
|
||||||
|
<span># {{episode.episodeNumber}}</span>
|
||||||
|
<span *ngIf="episode.available" class="label label-success">Available</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<button *ngIf="!child.approved" type="button" (click)="approveSeasonRequest(child)" class="btn btn-sm btn-success-outline" style="text-align: right"><i class="fa fa-plus"></i> Approve</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
|
|
|
@ -13,7 +13,7 @@ import 'rxjs/add/operator/map';
|
||||||
import { RequestService } from '../services/request.service';
|
import { RequestService } from '../services/request.service';
|
||||||
import { IdentityService } from '../services/identity.service';
|
import { IdentityService } from '../services/identity.service';
|
||||||
|
|
||||||
import { ITvRequestModel } from '../interfaces/IRequestModel';
|
import { ITvRequestModel, IChildTvRequest } from '../interfaces/IRequestModel';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tv-requests',
|
selector: 'tv-requests',
|
||||||
|
@ -98,6 +98,12 @@ export class TvRequestsComponent implements OnInit, OnDestroy {
|
||||||
this.updateRequest(request);
|
this.updateRequest(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public approveSeasonRequest(request: IChildTvRequest) {
|
||||||
|
request.approved = true;
|
||||||
|
this.requestService.updateTvRequest(this.selectedSeason)
|
||||||
|
.subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
public showChildren(request: ITvRequestModel) {
|
public showChildren(request: ITvRequestModel) {
|
||||||
this.selectedSeason = request;
|
this.selectedSeason = request;
|
||||||
this.showChildDialogue = true;
|
this.showChildDialogue = true;
|
||||||
|
|
|
@ -52,7 +52,7 @@ export class RequestService extends ServiceAuthHelpers {
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTvRequest(request: ITvRequestModel): Observable<ITvRequestModel> {
|
updateTvRequest(request: ITvRequestModel): Observable<ITvRequestModel> {
|
||||||
return this.http.post(`${this.url}tv/`, JSON.stringify(request), { headers: this.headers }).map(this.extractData);
|
return this.http.put(`${this.url}tv/`, JSON.stringify(request), { headers: this.headers }).map(this.extractData);
|
||||||
}
|
}
|
||||||
|
|
||||||
getRequestsCount(): Observable<IRequestCountModel> {
|
getRequestsCount(): Observable<IRequestCountModel> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue