mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-15 01:32:55 -07:00
Got TV working nicely
This commit is contained in:
parent
62cceb803d
commit
5e6edc2ad8
17 changed files with 176 additions and 123 deletions
|
@ -67,7 +67,7 @@ namespace Ombi.Core.Engine
|
||||||
$"{movieInfo.Title}{(!string.IsNullOrEmpty(movieInfo.ReleaseDate) ? $" ({DateTime.Parse(movieInfo.ReleaseDate).Year})" : string.Empty)}";
|
$"{movieInfo.Title}{(!string.IsNullOrEmpty(movieInfo.ReleaseDate) ? $" ({DateTime.Parse(movieInfo.ReleaseDate).Year})" : string.Empty)}";
|
||||||
|
|
||||||
var userDetails = await GetUser();
|
var userDetails = await GetUser();
|
||||||
var canRequestOnBehalf = false;
|
var canRequestOnBehalf = model.RequestOnBehalf.HasValue();
|
||||||
|
|
||||||
var isAdmin = await UserManager.IsInRoleAsync(userDetails, OmbiRoles.PowerUser) || await UserManager.IsInRoleAsync(userDetails, OmbiRoles.Admin);
|
var isAdmin = await UserManager.IsInRoleAsync(userDetails, OmbiRoles.PowerUser) || await UserManager.IsInRoleAsync(userDetails, OmbiRoles.Admin);
|
||||||
if (model.RequestOnBehalf.HasValue() && !isAdmin)
|
if (model.RequestOnBehalf.HasValue() && !isAdmin)
|
||||||
|
|
|
@ -140,7 +140,7 @@ namespace Ombi.Core.Engine
|
||||||
ErrorMessage = "This has already been requested"
|
ErrorMessage = "This has already been requested"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return await AddExistingRequest(tvBuilder.ChildRequest, existingRequest, tv.RequestOnBehalf);
|
return await AddExistingRequest(tvBuilder.ChildRequest, existingRequest, tv.RequestOnBehalf, tv.RootFolderOverride.GetValueOrDefault(), tv.QualityPathOverride.GetValueOrDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a new request
|
// This is a new request
|
||||||
|
@ -151,13 +151,10 @@ namespace Ombi.Core.Engine
|
||||||
public async Task<RequestEngineResult> RequestTvShow(TvRequestViewModelV2 tv)
|
public async Task<RequestEngineResult> RequestTvShow(TvRequestViewModelV2 tv)
|
||||||
{
|
{
|
||||||
var user = await GetUser();
|
var user = await GetUser();
|
||||||
var canRequestOnBehalf = false;
|
var canRequestOnBehalf = tv.RequestOnBehalf.HasValue();
|
||||||
|
|
||||||
if (tv.RequestOnBehalf.HasValue())
|
var isAdmin = await UserManager.IsInRoleAsync(user, OmbiRoles.PowerUser) || await UserManager.IsInRoleAsync(user, OmbiRoles.Admin);
|
||||||
{
|
if (tv.RequestOnBehalf.HasValue() && !isAdmin)
|
||||||
canRequestOnBehalf = await UserManager.IsInRoleAsync(user, OmbiRoles.PowerUser) || await UserManager.IsInRoleAsync(user, OmbiRoles.Admin);
|
|
||||||
|
|
||||||
if (!canRequestOnBehalf)
|
|
||||||
{
|
{
|
||||||
return new RequestEngineResult
|
return new RequestEngineResult
|
||||||
{
|
{
|
||||||
|
@ -166,6 +163,15 @@ namespace Ombi.Core.Engine
|
||||||
ErrorMessage = $"You do not have the correct permissions to request on behalf of users!"
|
ErrorMessage = $"You do not have the correct permissions to request on behalf of users!"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((tv.RootFolderOverride.HasValue || tv.QualityPathOverride.HasValue) && !isAdmin)
|
||||||
|
{
|
||||||
|
return new RequestEngineResult
|
||||||
|
{
|
||||||
|
Result = false,
|
||||||
|
Message = "You do not have the correct permissions!",
|
||||||
|
ErrorMessage = $"You do not have the correct permissions!"
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var tvBuilder = new TvShowRequestBuilderV2(MovieDbApi);
|
var tvBuilder = new TvShowRequestBuilderV2(MovieDbApi);
|
||||||
|
@ -240,11 +246,11 @@ namespace Ombi.Core.Engine
|
||||||
ErrorMessage = "This has already been requested"
|
ErrorMessage = "This has already been requested"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return await AddExistingRequest(tvBuilder.ChildRequest, existingRequest, tv.RequestOnBehalf);
|
return await AddExistingRequest(tvBuilder.ChildRequest, existingRequest, tv.RequestOnBehalf, tv.RootFolderOverride.GetValueOrDefault(), tv.QualityPathOverride.GetValueOrDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a new request
|
// This is a new request
|
||||||
var newRequest = tvBuilder.CreateNewRequest(tv);
|
var newRequest = tvBuilder.CreateNewRequest(tv, tv.RootFolderOverride.GetValueOrDefault(), tv.QualityPathOverride.GetValueOrDefault());
|
||||||
return await AddRequest(newRequest.NewRequest, tv.RequestOnBehalf);
|
return await AddRequest(newRequest.NewRequest, tv.RequestOnBehalf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -852,10 +858,18 @@ namespace Ombi.Core.Engine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<RequestEngineResult> AddExistingRequest(ChildRequests newRequest, TvRequests existingRequest, string requestOnBehalf)
|
private async Task<RequestEngineResult> AddExistingRequest(ChildRequests newRequest, TvRequests existingRequest, string requestOnBehalf, int rootFolder, int qualityProfile)
|
||||||
{
|
{
|
||||||
// Add the child
|
// Add the child
|
||||||
existingRequest.ChildRequests.Add(newRequest);
|
existingRequest.ChildRequests.Add(newRequest);
|
||||||
|
if (qualityProfile > 0)
|
||||||
|
{
|
||||||
|
existingRequest.QualityOverride = qualityProfile;
|
||||||
|
}
|
||||||
|
if (rootFolder > 0)
|
||||||
|
{
|
||||||
|
existingRequest.RootFolder = rootFolder;
|
||||||
|
}
|
||||||
|
|
||||||
await TvRepository.Update(existingRequest);
|
await TvRepository.Update(existingRequest);
|
||||||
|
|
||||||
|
|
|
@ -217,7 +217,7 @@ namespace Ombi.Core.Helpers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public TvShowRequestBuilderV2 CreateNewRequest(TvRequestViewModelV2 tv)
|
public TvShowRequestBuilderV2 CreateNewRequest(TvRequestViewModelV2 tv, int rootPathOverride, int qualityOverride)
|
||||||
{
|
{
|
||||||
int.TryParse(TheMovieDbRecord.ExternalIds?.TvDbId, out var tvdbId);
|
int.TryParse(TheMovieDbRecord.ExternalIds?.TvDbId, out var tvdbId);
|
||||||
NewRequest = new TvRequests
|
NewRequest = new TvRequests
|
||||||
|
@ -232,7 +232,9 @@ namespace Ombi.Core.Helpers
|
||||||
TvDbId = tvdbId,
|
TvDbId = tvdbId,
|
||||||
ChildRequests = new List<ChildRequests>(),
|
ChildRequests = new List<ChildRequests>(),
|
||||||
TotalSeasons = tv.Seasons.Count(),
|
TotalSeasons = tv.Seasons.Count(),
|
||||||
Background = BackdropPath
|
Background = BackdropPath,
|
||||||
|
RootFolder = rootPathOverride,
|
||||||
|
QualityOverride = qualityOverride
|
||||||
};
|
};
|
||||||
NewRequest.ChildRequests.Add(ChildRequest);
|
NewRequest.ChildRequests.Add(ChildRequest);
|
||||||
|
|
||||||
|
|
|
@ -208,6 +208,10 @@ namespace Ombi.Core.Senders
|
||||||
{
|
{
|
||||||
qualityToUse = model.ParentRequest.QualityOverride.Value;
|
qualityToUse = model.ParentRequest.QualityOverride.Value;
|
||||||
}
|
}
|
||||||
|
if (model.ParentRequest.RootFolder.HasValue)
|
||||||
|
{
|
||||||
|
rootFolderPath = await GetSonarrRootPath(model.ParentRequest.RootFolder.Value, s);
|
||||||
|
}
|
||||||
|
|
||||||
// Are we using v3 sonarr?
|
// Are we using v3 sonarr?
|
||||||
var sonarrV3 = s.V3;
|
var sonarrV3 = s.V3;
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="discoverResults" class="row full-height">
|
<div *ngIf="discoverResults" class="row full-height">
|
||||||
<div class="col-xl-2 col-lg-3 col-md-3 col-6 col-sm-4 small-padding" *ngFor="let result of discoverResults">
|
<div class="col-xl-2 col-lg-3 col-md-3 col-6 col-sm-4 small-padding" *ngFor="let result of discoverResults">
|
||||||
<discover-card [result]="result"></discover-card>
|
<discover-card [isAdmin]="isAdmin" [result]="result"></discover-card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -1,25 +1,29 @@
|
||||||
import { Component, AfterViewInit } from "@angular/core";
|
import { Component } from "@angular/core";
|
||||||
import { ActivatedRoute } from "@angular/router";
|
import { ActivatedRoute } from "@angular/router";
|
||||||
import { SearchV2Service } from "../../../services";
|
import { SearchV2Service } from "../../../services";
|
||||||
import { IActorCredits } from "../../../interfaces/ISearchTvResultV2";
|
import { IActorCredits } from "../../../interfaces/ISearchTvResultV2";
|
||||||
import { IDiscoverCardResult } from "../../interfaces";
|
import { IDiscoverCardResult } from "../../interfaces";
|
||||||
import { RequestType } from "../../../interfaces";
|
import { RequestType } from "../../../interfaces";
|
||||||
|
import { AuthService } from "../../../auth/auth.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./discover-actor.component.html",
|
templateUrl: "./discover-actor.component.html",
|
||||||
styleUrls: ["./discover-actor.component.scss"],
|
styleUrls: ["./discover-actor.component.scss"],
|
||||||
})
|
})
|
||||||
export class DiscoverActorComponent implements AfterViewInit {
|
export class DiscoverActorComponent {
|
||||||
public actorId: number;
|
public actorId: number;
|
||||||
public actorCredits: IActorCredits;
|
public actorCredits: IActorCredits;
|
||||||
public loadingFlag: boolean;
|
public loadingFlag: boolean;
|
||||||
|
public isAdmin: boolean;
|
||||||
|
|
||||||
public discoverResults: IDiscoverCardResult[] = [];
|
public discoverResults: IDiscoverCardResult[] = [];
|
||||||
|
|
||||||
constructor(private searchService: SearchV2Service,
|
constructor(private searchService: SearchV2Service,
|
||||||
private route: ActivatedRoute) {
|
private route: ActivatedRoute,
|
||||||
|
private auth: AuthService) {
|
||||||
this.route.params.subscribe((params: any) => {
|
this.route.params.subscribe((params: any) => {
|
||||||
this.actorId = params.actorId;
|
this.actorId = params.actorId;
|
||||||
|
this.isAdmin = this.auth.isAdmin();
|
||||||
this.loading();
|
this.loading();
|
||||||
this.searchService.getMoviesByActor(this.actorId).subscribe(res => {
|
this.searchService.getMoviesByActor(this.actorId).subscribe(res => {
|
||||||
this.actorCredits = res;
|
this.actorCredits = res;
|
||||||
|
@ -28,18 +32,6 @@ export class DiscoverActorComponent implements AfterViewInit {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async ngAfterViewInit() {
|
|
||||||
// this.discoverResults.forEach((result) => {
|
|
||||||
// this.searchService.getFullMovieDetails(result.id).subscribe(x => {
|
|
||||||
// result.available = x.available;
|
|
||||||
// result.approved = x.approved;
|
|
||||||
// result.rating = x.voteAverage;
|
|
||||||
// result.requested = x.requested;
|
|
||||||
// result.url = x.homepage;
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
|
|
||||||
private createModel() {
|
private createModel() {
|
||||||
this.finishLoading();
|
this.finishLoading();
|
||||||
this.discoverResults = [];
|
this.discoverResults = [];
|
||||||
|
|
|
@ -118,12 +118,17 @@ export class DiscoverCardComponent implements OnInit {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
switch (this.result.type) {
|
switch (this.result.type) {
|
||||||
case RequestType.tvShow:
|
case RequestType.tvShow:
|
||||||
const dia = this.dialog.open(EpisodeRequestComponent, { width: "700px", data: { series: this.tvSearchResult }, panelClass: 'modal-panel' });
|
const dia = this.dialog.open(EpisodeRequestComponent, { width: "700px", data: { series: this.tvSearchResult, isAdmin: this.isAdmin }, panelClass: 'modal-panel' });
|
||||||
dia.afterClosed().subscribe(x => this.loading = false);
|
dia.afterClosed().subscribe(x => this.loading = false);
|
||||||
return;
|
return;
|
||||||
case RequestType.movie:
|
case RequestType.movie:
|
||||||
if (this.isAdmin) {
|
if (this.isAdmin) {
|
||||||
this.dialog.open(AdminRequestDialogComponent, { width: "700px", data: { type: RequestType.movie, id: this.result.id }, panelClass: 'modal-panel' });
|
const dialog = this.dialog.open(AdminRequestDialogComponent, { width: "700px", data: { type: RequestType.movie, id: this.result.id }, panelClass: 'modal-panel' });
|
||||||
|
dialog.afterClosed().subscribe((result) => {
|
||||||
|
if (result) {
|
||||||
|
this.result.requested = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
this.requestService.requestMovie({ theMovieDbId: +this.result.id, languageCode: null, requestOnBehalf: null, qualityPathOverride: null, rootFolderOverride: null }).subscribe(x => {
|
this.requestService.requestMovie({ theMovieDbId: +this.result.id, languageCode: null, requestOnBehalf: null, qualityPathOverride: null, rootFolderOverride: null }).subscribe(x => {
|
||||||
if (x.result) {
|
if (x.result) {
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="discoverResults" class="row full-height">
|
<div *ngIf="discoverResults" class="row full-height">
|
||||||
<div class="col-xl-2 col-lg-3 col-md-3 col-6 col-sm-4 small-padding" *ngFor="let result of discoverResults">
|
<div class="col-xl-2 col-lg-3 col-md-3 col-6 col-sm-4 small-padding" *ngFor="let result of discoverResults">
|
||||||
<discover-card [result]="result"></discover-card>
|
<discover-card [isAdmin]="isAdmins" [result]="result"></discover-card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -4,6 +4,7 @@ import { SearchV2Service, RequestService, MessageService } from "../../../servic
|
||||||
import { IMovieCollectionsViewModel } from "../../../interfaces/ISearchTvResultV2";
|
import { IMovieCollectionsViewModel } from "../../../interfaces/ISearchTvResultV2";
|
||||||
import { IDiscoverCardResult } from "../../interfaces";
|
import { IDiscoverCardResult } from "../../interfaces";
|
||||||
import { RequestType } from "../../../interfaces";
|
import { RequestType } from "../../../interfaces";
|
||||||
|
import { AuthService } from "../../../auth/auth.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./discover-collections.component.html",
|
templateUrl: "./discover-collections.component.html",
|
||||||
|
@ -14,13 +15,15 @@ export class DiscoverCollectionsComponent implements OnInit {
|
||||||
public collectionId: number;
|
public collectionId: number;
|
||||||
public collection: IMovieCollectionsViewModel;
|
public collection: IMovieCollectionsViewModel;
|
||||||
public loadingFlag: boolean;
|
public loadingFlag: boolean;
|
||||||
|
public isAdmin: boolean;
|
||||||
|
|
||||||
public discoverResults: IDiscoverCardResult[] = [];
|
public discoverResults: IDiscoverCardResult[] = [];
|
||||||
|
|
||||||
constructor(private searchService: SearchV2Service,
|
constructor(private searchService: SearchV2Service,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private requestService: RequestService,
|
private requestService: RequestService,
|
||||||
private messageService: MessageService) {
|
private messageService: MessageService,
|
||||||
|
private auth: AuthService) {
|
||||||
this.route.params.subscribe((params: any) => {
|
this.route.params.subscribe((params: any) => {
|
||||||
this.collectionId = params.collectionId;
|
this.collectionId = params.collectionId;
|
||||||
});
|
});
|
||||||
|
@ -28,6 +31,7 @@ export class DiscoverCollectionsComponent implements OnInit {
|
||||||
|
|
||||||
public async ngOnInit() {
|
public async ngOnInit() {
|
||||||
this.loadingFlag = true;
|
this.loadingFlag = true;
|
||||||
|
this.isAdmin = this.auth.isAdmin();
|
||||||
this.collection = await this.searchService.getMovieCollections(this.collectionId);
|
this.collection = await this.searchService.getMovieCollections(this.collectionId);
|
||||||
this.createModel();
|
this.createModel();
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,15 +89,27 @@ export class MovieDetailsComponent {
|
||||||
const dialog = this.dialog.open(AdminRequestDialogComponent, { width: "700px", data: { type: RequestType.movie, id: this.movie.id }, panelClass: 'modal-panel' });
|
const dialog = this.dialog.open(AdminRequestDialogComponent, { width: "700px", data: { type: RequestType.movie, id: this.movie.id }, panelClass: 'modal-panel' });
|
||||||
dialog.afterClosed().subscribe(async (result) => {
|
dialog.afterClosed().subscribe(async (result) => {
|
||||||
if (result) {
|
if (result) {
|
||||||
|
const requestResult = await this.requestService.requestMovie({ theMovieDbId: this.theMovidDbId,
|
||||||
|
languageCode: null,
|
||||||
|
qualityPathOverride: result.radarrPathId,
|
||||||
|
requestOnBehalf: result.username?.id,
|
||||||
|
rootFolderOverride: result.radarrFolderId, }).toPromise();
|
||||||
|
if (requestResult.result) {
|
||||||
this.movie.requested = true;
|
this.movie.requested = true;
|
||||||
this.movie.requestId = result.requestId;
|
this.movie.requestId = result.requestId;
|
||||||
this.movieRequest = await this.requestService.getMovieRequest(this.movie.requestId);
|
this.movieRequest = await this.requestService.getMovieRequest(this.movie.requestId);
|
||||||
|
this.messageService.send(requestResult.message, "Ok");
|
||||||
|
} else {
|
||||||
|
this.messageService.send(requestResult.errorMessage, "Ok");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const result = await this.requestService.requestMovie({ theMovieDbId: this.theMovidDbId, languageCode: null, requestOnBehalf: userId, qualityPathOverride: undefined, rootFolderOverride: undefined }).toPromise();
|
const result = await this.requestService.requestMovie({ theMovieDbId: this.theMovidDbId, languageCode: null, requestOnBehalf: userId, qualityPathOverride: undefined, rootFolderOverride: undefined }).toPromise();
|
||||||
if (result.result) {
|
if (result.result) {
|
||||||
this.movie.requested = true;
|
this.movie.requested = true;
|
||||||
|
this.movie.requestId = result.requestId;
|
||||||
|
this.movieRequest = await this.requestService.getMovieRequest(this.movie.requestId);
|
||||||
this.messageService.send(result.message, "Ok");
|
this.messageService.send(result.message, "Ok");
|
||||||
} else {
|
} else {
|
||||||
this.messageService.send(result.errorMessage, "Ok");
|
this.messageService.send(result.errorMessage, "Ok");
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
|
|
||||||
<div *ngIf="request">
|
<div *ngIf="request">
|
||||||
<span class="label">{{'Requests.RequestedBy' | translate }}:</span>
|
<span class="label">{{'Requests.RequestedBy' | translate }}:</span>
|
||||||
{{request.requestedUser.userAlias}}
|
<span id="requestedByInfo">{{request.requestedUser.userAlias}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="request">
|
<div *ngIf="request">
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Component, Input } from "@angular/core";
|
import { Component, Input } from "@angular/core";
|
||||||
import { IChildRequests, IEpisodesRequests, INewSeasonRequests, ISeasonsViewModel, ITvRequestViewModelV2, RequestType } from "../../../../../interfaces";
|
import { IChildRequests, IEpisodesRequests, INewSeasonRequests, IRequestEngineResult, ISeasonsViewModel, ITvRequestViewModelV2, RequestType } from "../../../../../interfaces";
|
||||||
import { RequestService } from "../../../../../services/request.service";
|
import { RequestService } from "../../../../../services/request.service";
|
||||||
import { MessageService } from "../../../../../services";
|
import { MessageService } from "../../../../../services";
|
||||||
import { DenyDialogComponent } from "../../../shared/deny-dialog/deny-dialog.component";
|
import { DenyDialogComponent } from "../../../shared/deny-dialog/deny-dialog.component";
|
||||||
|
@ -7,6 +7,7 @@ import { ISearchTvResultV2 } from "../../../../../interfaces/ISearchTvResultV2";
|
||||||
import { MatDialog } from "@angular/material/dialog";
|
import { MatDialog } from "@angular/material/dialog";
|
||||||
import { SelectionModel } from "@angular/cdk/collections";
|
import { SelectionModel } from "@angular/cdk/collections";
|
||||||
import { RequestServiceV2 } from "../../../../../services/requestV2.service";
|
import { RequestServiceV2 } from "../../../../../services/requestV2.service";
|
||||||
|
import { AdminRequestDialogComponent } from "../../../../../shared/admin-request-dialog/admin-request-dialog.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./tv-request-grid.component.html",
|
templateUrl: "./tv-request-grid.component.html",
|
||||||
|
@ -59,38 +60,21 @@ export class TvRequestGridComponent {
|
||||||
viewModel.seasons.push(seasonsViewModel);
|
viewModel.seasons.push(seasonsViewModel);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (this.isAdmin) {
|
||||||
|
const dialog = this.dialog.open(AdminRequestDialogComponent, { width: "700px", data: { type: RequestType.tvShow, id: this.tv.id }, panelClass: 'modal-panel' });
|
||||||
|
dialog.afterClosed().subscribe(async (result) => {
|
||||||
|
if (result) {
|
||||||
|
viewModel.requestOnBehalf = result.username?.id;
|
||||||
|
viewModel.qualityPathOverride = result?.sonarrPathId;
|
||||||
|
viewModel.rootFolderOverride = result?.sonarrFolderId;
|
||||||
|
|
||||||
const requestResult = await this.requestServiceV2.requestTv(viewModel).toPromise();
|
const requestResult = await this.requestServiceV2.requestTv(viewModel).toPromise();
|
||||||
|
this.postRequest(requestResult);
|
||||||
if (requestResult.result) {
|
|
||||||
this.notificationService.send(
|
|
||||||
`Request for ${this.tv.title} has been added successfully`);
|
|
||||||
|
|
||||||
debugger;
|
|
||||||
this.selection.clear();
|
|
||||||
|
|
||||||
if (this.tv.firstSeason) {
|
|
||||||
this.tv.seasonRequests[0].episodes.forEach(ep => {
|
|
||||||
ep.requested = true;
|
|
||||||
ep.requestStatus = "Common.PendingApproval";
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
if (this.tv.requestAll) {
|
|
||||||
this.tv.seasonRequests.forEach(season => {
|
|
||||||
season.episodes.forEach(ep => {
|
|
||||||
ep.requested = true;
|
|
||||||
ep.requestStatus = "Common.PendingApproval";
|
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
if (this.tv.latestSeason) {
|
|
||||||
this.tv.seasonRequests[this.tv.seasonRequests.length - 1].episodes.forEach(ep => {
|
|
||||||
ep.requested = true;
|
|
||||||
ep.requestStatus = "Common.PendingApproval";
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
this.notificationService.send(requestResult.errorMessage ? requestResult.errorMessage : requestResult.message);
|
const requestResult = await this.requestServiceV2.requestTv(viewModel).toPromise();
|
||||||
|
this.postRequest(requestResult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,4 +220,37 @@ export class TvRequestGridComponent {
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private postRequest(requestResult: IRequestEngineResult) {
|
||||||
|
if (requestResult.result) {
|
||||||
|
this.notificationService.send(
|
||||||
|
`Request for ${this.tv.title} has been added successfully`);
|
||||||
|
|
||||||
|
this.selection.clear();
|
||||||
|
|
||||||
|
if (this.tv.firstSeason) {
|
||||||
|
this.tv.seasonRequests[0].episodes.forEach(ep => {
|
||||||
|
ep.requested = true;
|
||||||
|
ep.requestStatus = "Common.PendingApproval";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (this.tv.requestAll) {
|
||||||
|
this.tv.seasonRequests.forEach(season => {
|
||||||
|
season.episodes.forEach(ep => {
|
||||||
|
ep.requested = true;
|
||||||
|
ep.requestStatus = "Common.PendingApproval";
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (this.tv.latestSeason) {
|
||||||
|
this.tv.seasonRequests[this.tv.seasonRequests.length - 1].episodes.forEach(ep => {
|
||||||
|
ep.requested = true;
|
||||||
|
ep.requestStatus = "Common.PendingApproval";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.notificationService.send(requestResult.errorMessage ? requestResult.errorMessage : requestResult.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ export class TvDetailsComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async request(userId: string) {
|
public async request(userId: string) {
|
||||||
this.dialog.open(EpisodeRequestComponent, { width: "800px", data: <EpisodeRequestData> { series: this.tv, requestOnBehalf: userId }, panelClass: 'modal-panel' })
|
this.dialog.open(EpisodeRequestComponent, { width: "800px", data: <EpisodeRequestData> { series: this.tv, requestOnBehalf: userId, isAdmin: this.isAdmin }, panelClass: 'modal-panel' })
|
||||||
}
|
}
|
||||||
|
|
||||||
public async issue() {
|
public async issue() {
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
<form [formGroup]="form" *ngIf="form">
|
<form [formGroup]="form" *ngIf="form">
|
||||||
<h1 id="advancedOptionsTitle">{{'MediaDetails.AdvancedOptions' | translate }}</h1>
|
<h1 id="advancedOptionsTitle">{{'MediaDetails.AdvancedOptions' | translate }}</h1>
|
||||||
<div class="alert alert-info" role="alert">
|
<div class="alert alert-info" role="alert">
|
||||||
{{'MediaDetails.AutoApproveOptions' | translate }}
|
<span *ngIf="data.type === RequestType.movie">{{'MediaDetails.AutoApproveOptions' | translate }}</span>
|
||||||
|
<span *ngIf="data.type === RequestType.tvShow">{{'MediaDetails.AutoApproveOptionsTv' | translate }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="max-width: 0; max-height: 0; overflow: hidden;">
|
<div style="max-width: 0; max-height: 0; overflow: hidden;">
|
||||||
|
@ -31,7 +32,7 @@
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<!-- Sonarr -->
|
<!-- Sonarr -->
|
||||||
<div *ngIf="data.type === RequestType.tvShow">
|
<div *ngIf="data.type === RequestType.tvShow && sonarrEnabled">
|
||||||
<div>
|
<div>
|
||||||
<h3>Sonarr Overrides</h3>
|
<h3>Sonarr Overrides</h3>
|
||||||
<mat-form-field appearance="outline" floatLabel=auto>
|
<mat-form-field appearance="outline" floatLabel=auto>
|
||||||
|
|
|
@ -21,12 +21,9 @@ export class AdminRequestDialogComponent implements OnInit {
|
||||||
constructor(
|
constructor(
|
||||||
public dialogRef: MatDialogRef<AdminRequestDialogComponent>,
|
public dialogRef: MatDialogRef<AdminRequestDialogComponent>,
|
||||||
@Inject(MAT_DIALOG_DATA) public data: IAdminRequestDialogData,
|
@Inject(MAT_DIALOG_DATA) public data: IAdminRequestDialogData,
|
||||||
private requestServiceV2: RequestServiceV2,
|
|
||||||
private notificationService: MessageService,
|
|
||||||
private identityService: IdentityService,
|
private identityService: IdentityService,
|
||||||
private sonarrService: SonarrService,
|
private sonarrService: SonarrService,
|
||||||
private radarrService: RadarrService,
|
private radarrService: RadarrService,
|
||||||
private requestService: RequestService,
|
|
||||||
private fb: FormBuilder
|
private fb: FormBuilder
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
@ -38,7 +35,7 @@ export class AdminRequestDialogComponent implements OnInit {
|
||||||
public userId: string;
|
public userId: string;
|
||||||
|
|
||||||
public radarrEnabled: boolean;
|
public radarrEnabled: boolean;
|
||||||
|
public sonarrEnabled: boolean;
|
||||||
|
|
||||||
public sonarrProfiles: ISonarrProfile[];
|
public sonarrProfiles: ISonarrProfile[];
|
||||||
public sonarrRootFolders: ISonarrRootFolder[];
|
public sonarrRootFolders: ISonarrRootFolder[];
|
||||||
|
@ -63,6 +60,8 @@ export class AdminRequestDialogComponent implements OnInit {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (this.data.type === RequestType.tvShow) {
|
if (this.data.type === RequestType.tvShow) {
|
||||||
|
this.sonarrEnabled = await this.sonarrService.isEnabled();
|
||||||
|
if (this.sonarrEnabled) {
|
||||||
this.sonarrService.getQualityProfilesWithoutSettings().subscribe(c => {
|
this.sonarrService.getQualityProfilesWithoutSettings().subscribe(c => {
|
||||||
this.sonarrProfiles = c;
|
this.sonarrProfiles = c;
|
||||||
});
|
});
|
||||||
|
@ -70,6 +69,7 @@ export class AdminRequestDialogComponent implements OnInit {
|
||||||
this.sonarrRootFolders = c;
|
this.sonarrRootFolders = c;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (this.data.type === RequestType.movie) {
|
if (this.data.type === RequestType.movie) {
|
||||||
this.radarrEnabled = await this.radarrService.isRadarrEnabled();
|
this.radarrEnabled = await this.radarrService.isRadarrEnabled();
|
||||||
if (this.radarrEnabled) {
|
if (this.radarrEnabled) {
|
||||||
|
@ -102,29 +102,10 @@ export class AdminRequestDialogComponent implements OnInit {
|
||||||
|
|
||||||
public async submitRequest() {
|
public async submitRequest() {
|
||||||
const model = this.form.value;
|
const model = this.form.value;
|
||||||
if (this.data.type === RequestType.movie) {
|
|
||||||
this.requestService.requestMovie({
|
|
||||||
qualityPathOverride: model.radarrPathId,
|
|
||||||
requestOnBehalf: model.username?.id,
|
|
||||||
rootFolderOverride: model.radarrFolderId,
|
|
||||||
theMovieDbId: this.data.id,
|
|
||||||
languageCode: null
|
|
||||||
}).subscribe((x) => {
|
|
||||||
if (x.result) {
|
|
||||||
this.notificationService.send(x.message, "Ok");
|
|
||||||
model.radarrQualityOverrideTitle = this.radarrProfiles?.filter(x => x.id == model.radarrPathId)[0]?.name;
|
model.radarrQualityOverrideTitle = this.radarrProfiles?.filter(x => x.id == model.radarrPathId)[0]?.name;
|
||||||
model.radarrRootFolderTitle = this.radarrRootFolders?.filter(x => x.id == model.radarrFolderId)[0]?.path;
|
model.radarrRootFolderTitle = this.radarrRootFolders?.filter(x => x.id == model.radarrFolderId)[0]?.path;
|
||||||
|
model.sonarrRootFolderTitle = this.sonarrRootFolders?.filter(x => x.id == model.sonarrFolderId)[0]?.path;
|
||||||
model.requestId = x.requestId;
|
model.sonarrQualityOverrideTitle = this.sonarrProfiles?.filter(x => x.id == model.sonarrPathId)[0]?.name;
|
||||||
|
|
||||||
this.dialogRef.close(model);
|
this.dialogRef.close(model);
|
||||||
|
|
||||||
} else {
|
|
||||||
this.notificationService.send(x.errorMessage, "Ok");
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
import { Component, Inject } from "@angular/core";
|
import { Component, Inject } from "@angular/core";
|
||||||
import { MatCheckboxChange } from "@angular/material/checkbox";
|
import { MatCheckboxChange } from "@angular/material/checkbox";
|
||||||
import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material/dialog";
|
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from "@angular/material/dialog";
|
||||||
import { ISearchTvResultV2 } from "../../interfaces/ISearchTvResultV2";
|
import { ISearchTvResultV2 } from "../../interfaces/ISearchTvResultV2";
|
||||||
import { MessageService } from "../../services";
|
import { MessageService } from "../../services";
|
||||||
import { ISeasonsViewModel, IEpisodesRequests, INewSeasonRequests, ITvRequestViewModelV2 } from "../../interfaces";
|
import { ISeasonsViewModel, IEpisodesRequests, INewSeasonRequests, ITvRequestViewModelV2, IRequestEngineResult, RequestType } from "../../interfaces";
|
||||||
import { RequestServiceV2 } from "../../services/requestV2.service";
|
import { RequestServiceV2 } from "../../services/requestV2.service";
|
||||||
|
import { AdminRequestDialogComponent } from "../admin-request-dialog/admin-request-dialog.component";
|
||||||
|
|
||||||
export interface EpisodeRequestData {
|
export interface EpisodeRequestData {
|
||||||
series: ISearchTvResultV2;
|
series: ISearchTvResultV2;
|
||||||
|
isAdmin: boolean;
|
||||||
requestOnBehalf: string | undefined;
|
requestOnBehalf: string | undefined;
|
||||||
}
|
}
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -21,7 +23,7 @@ export class EpisodeRequestComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(public dialogRef: MatDialogRef<EpisodeRequestComponent>, @Inject(MAT_DIALOG_DATA) public data: EpisodeRequestData,
|
constructor(public dialogRef: MatDialogRef<EpisodeRequestComponent>, @Inject(MAT_DIALOG_DATA) public data: EpisodeRequestData,
|
||||||
private requestService: RequestServiceV2, private notificationService: MessageService) { }
|
private requestService: RequestServiceV2, private notificationService: MessageService, private dialog: MatDialog) { }
|
||||||
|
|
||||||
|
|
||||||
public async submitRequests() {
|
public async submitRequests() {
|
||||||
|
@ -57,21 +59,23 @@ export class EpisodeRequestComponent {
|
||||||
viewModel.seasons.push(seasonsViewModel);
|
viewModel.seasons.push(seasonsViewModel);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (this.data.isAdmin) {
|
||||||
|
const dialog = this.dialog.open(AdminRequestDialogComponent, { width: "700px", data: { type: RequestType.tvShow, id: this.data.series.id }, panelClass: 'modal-panel' });
|
||||||
|
dialog.afterClosed().subscribe(async (result) => {
|
||||||
|
if (result) {
|
||||||
|
viewModel.requestOnBehalf = result.username?.id;
|
||||||
|
viewModel.qualityPathOverride = result?.sonarrPathId;
|
||||||
|
viewModel.rootFolderOverride = result?.sonarrFolderId;
|
||||||
|
|
||||||
const requestResult = await this.requestService.requestTv(viewModel).toPromise();
|
const requestResult = await this.requestService.requestTv(viewModel).toPromise();
|
||||||
|
this.postRequest(requestResult);
|
||||||
if (requestResult.result) {
|
|
||||||
this.notificationService.send(
|
|
||||||
`Request for ${this.data.series.title} has been added successfully`);
|
|
||||||
|
|
||||||
this.data.series.seasonRequests.forEach((season) => {
|
|
||||||
season.episodes.forEach((ep) => {
|
|
||||||
ep.selected = false;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
|
||||||
this.notificationService.send(requestResult.errorMessage ? requestResult.errorMessage : requestResult.message);
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const requestResult = await this.requestService.requestTv(viewModel).toPromise();
|
||||||
|
this.postRequest(requestResult);
|
||||||
|
}
|
||||||
|
|
||||||
this.dialogRef.close();
|
this.dialogRef.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,4 +118,20 @@ export class EpisodeRequestComponent {
|
||||||
this.data.series.latestSeason = true;
|
this.data.series.latestSeason = true;
|
||||||
await this.submitRequests();
|
await this.submitRequests();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private postRequest(requestResult: IRequestEngineResult) {
|
||||||
|
if (requestResult.result) {
|
||||||
|
this.notificationService.send(
|
||||||
|
`Request for ${this.data.series.title} has been added successfully`);
|
||||||
|
|
||||||
|
this.data.series.seasonRequests.forEach((season) => {
|
||||||
|
season.episodes.forEach((ep) => {
|
||||||
|
ep.selected = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.notificationService.send(requestResult.errorMessage ? requestResult.errorMessage : requestResult.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -253,6 +253,7 @@
|
||||||
"NotEnoughInfo": "Unfortunately there is not enough information about this show yet!",
|
"NotEnoughInfo": "Unfortunately there is not enough information about this show yet!",
|
||||||
"AdvancedOptions":"Advanced Options",
|
"AdvancedOptions":"Advanced Options",
|
||||||
"AutoApproveOptions":"You can configure the request here, once requested it will be send to your DVR application and will be auto approved!",
|
"AutoApproveOptions":"You can configure the request here, once requested it will be send to your DVR application and will be auto approved!",
|
||||||
|
"AutoApproveOptionsTv":"You can configure the request here, once requested it will be send to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it!",
|
||||||
"QualityProfilesSelect":"Select A Quality Profile",
|
"QualityProfilesSelect":"Select A Quality Profile",
|
||||||
"RootFolderSelect":"Select A Root Folder",
|
"RootFolderSelect":"Select A Root Folder",
|
||||||
"Status":"Status",
|
"Status":"Status",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue