Requests now work for albums !wip

This commit is contained in:
Jamie 2018-08-24 16:32:19 +01:00
parent 70db3c7bca
commit d47e7a7c57
13 changed files with 1250 additions and 17 deletions

View file

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -72,13 +73,14 @@ namespace Ombi.Api.Lidarr
} }
public Task<AlbumLookup> GetAlbumByForeignId(string foreignArtistId, string apiKey, string baseUrl) public async Task<AlbumLookup> GetAlbumByForeignId(string foreignArtistId, string apiKey, string baseUrl)
{ {
var request = new Request($"{ApiVersion}/album/lookup", baseUrl, HttpMethod.Get); var request = new Request($"{ApiVersion}/album/lookup", baseUrl, HttpMethod.Get);
request.AddQueryString("term", $"lidarr:{foreignArtistId}"); request.AddQueryString("term", $"lidarr:{foreignArtistId}");
AddHeaders(request, apiKey); AddHeaders(request, apiKey);
return Api.Request<AlbumLookup>(request); var albums = await Api.Request<List<AlbumLookup>>(request);
return albums.FirstOrDefault();
} }
public Task<AlbumByArtistResponse> GetAlbumsByArtist(int artistId, string apiKey, string baseUrl) public Task<AlbumByArtistResponse> GetAlbumsByArtist(int artistId, string apiKey, string baseUrl)

View file

@ -336,6 +336,7 @@ namespace Ombi.Core.Engine
}; };
} }
request.MarkedAsApproved = DateTime.Now;
request.Approved = true; request.Approved = true;
request.Denied = false; request.Denied = false;
await MovieRepository.Update(request); await MovieRepository.Update(request);

View file

@ -327,12 +327,11 @@ namespace Ombi.Core.Engine
}; };
} }
if (!request.Approved) request.MarkedAsApproved = DateTime.Now;
{ request.Approved = true;
request.Approved = true; request.Denied = false;
request.Denied = false; await MusicRepository.Update(request);
await MusicRepository.Update(request);
}
var canNotify = await RunSpecificRule(request, SpecificRules.CanSendNotification); var canNotify = await RunSpecificRule(request, SpecificRules.CanSendNotification);
if (canNotify.Success) if (canNotify.Success)

View file

@ -5,13 +5,15 @@ namespace Ombi.Core.Models.Requests
{ {
public class RequestService : IRequestServiceMain public class RequestService : IRequestServiceMain
{ {
public RequestService(ITvRequestRepository tv, IMovieRequestRepository movie) public RequestService(ITvRequestRepository tv, IMovieRequestRepository movie, IMusicRequestRepository music)
{ {
TvRequestService = tv; TvRequestService = tv;
MovieRequestService = movie; MovieRequestService = movie;
MusicRequestRepository = music;
} }
public ITvRequestRepository TvRequestService { get; } public ITvRequestRepository TvRequestService { get; }
public IMusicRequestRepository MusicRequestRepository { get; }
public IMovieRequestRepository MovieRequestService { get; } public IMovieRequestRepository MovieRequestService { get; }
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,67 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Ombi.Store.Migrations
{
public partial class MusicRequests : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "MusicRequestLimit",
table: "AspNetUsers",
nullable: true);
migrationBuilder.CreateTable(
name: "AlbumRequests",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Title = table.Column<string>(nullable: true),
Approved = table.Column<bool>(nullable: false),
MarkedAsApproved = table.Column<DateTime>(nullable: false),
RequestedDate = table.Column<DateTime>(nullable: false),
Available = table.Column<bool>(nullable: false),
MarkedAsAvailable = table.Column<DateTime>(nullable: true),
RequestedUserId = table.Column<string>(nullable: true),
Denied = table.Column<bool>(nullable: true),
MarkedAsDenied = table.Column<DateTime>(nullable: false),
DeniedReason = table.Column<string>(nullable: true),
RequestType = table.Column<int>(nullable: false),
ForeignAlbumId = table.Column<string>(nullable: true),
ForeignArtistId = table.Column<string>(nullable: true),
Disk = table.Column<string>(nullable: true),
Cover = table.Column<string>(nullable: true),
Rating = table.Column<decimal>(nullable: false),
ReleaseDate = table.Column<DateTime>(nullable: false),
ArtistName = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AlbumRequests", x => x.Id);
table.ForeignKey(
name: "FK_AlbumRequests_AspNetUsers_RequestedUserId",
column: x => x.RequestedUserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateIndex(
name: "IX_AlbumRequests_RequestedUserId",
table: "AlbumRequests",
column: "RequestedUserId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AlbumRequests");
migrationBuilder.DropColumn(
name: "MusicRequestLimit",
table: "AspNetUsers");
}
}
}

View file

@ -311,6 +311,8 @@ namespace Ombi.Store.Migrations
b.Property<int?>("MovieRequestLimit"); b.Property<int?>("MovieRequestLimit");
b.Property<int?>("MusicRequestLimit");
b.Property<string>("NormalizedEmail") b.Property<string>("NormalizedEmail")
.HasMaxLength(256); .HasMaxLength(256);
@ -460,6 +462,54 @@ namespace Ombi.Store.Migrations
b.ToTable("RecentlyAddedLog"); b.ToTable("RecentlyAddedLog");
}); });
modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<bool>("Approved");
b.Property<string>("ArtistName");
b.Property<bool>("Available");
b.Property<string>("Cover");
b.Property<bool?>("Denied");
b.Property<string>("DeniedReason");
b.Property<string>("Disk");
b.Property<string>("ForeignAlbumId");
b.Property<string>("ForeignArtistId");
b.Property<DateTime>("MarkedAsApproved");
b.Property<DateTime?>("MarkedAsAvailable");
b.Property<DateTime>("MarkedAsDenied");
b.Property<decimal>("Rating");
b.Property<DateTime>("ReleaseDate");
b.Property<int>("RequestType");
b.Property<DateTime>("RequestedDate");
b.Property<string>("RequestedUserId");
b.Property<string>("Title");
b.HasKey("Id");
b.HasIndex("RequestedUserId");
b.ToTable("AlbumRequests");
});
modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
@ -894,6 +944,13 @@ namespace Ombi.Store.Migrations
.HasForeignKey("PlexServerContentId"); .HasForeignKey("PlexServerContentId");
}); });
modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b =>
{
b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser")
.WithMany()
.HasForeignKey("RequestedUserId");
});
modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b =>
{ {
b.HasOne("Ombi.Store.Entities.Requests.TvRequests", "ParentRequest") b.HasOne("Ombi.Store.Entities.Requests.TvRequests", "ParentRequest")

View file

@ -20,6 +20,22 @@ export interface IMovieRequests extends IFullBaseRequest {
qualityOverrideTitle: string; qualityOverrideTitle: string;
} }
export interface IAlbumRequest extends IBaseRequest {
foreignAlbumId: string;
foreignArtistId: string;
Disk: string;
cover: string;
releaseDate: Date;
artistName: string;
subscribed: boolean;
showSubscribe: boolean;
}
export interface IAlbumRequestModel {
foreignAlbumId: string;
}
export interface IRequestsViewModel<T> { export interface IRequestsViewModel<T> {
total: number; total: number;
collection: T[]; collection: T[];
@ -29,6 +45,10 @@ export interface IMovieUpdateModel {
id: number; id: number;
} }
export interface IAlbumUpdateModel {
id: number;
}
export interface IFullBaseRequest extends IBaseRequest { export interface IFullBaseRequest extends IBaseRequest {
imdbId: string; imdbId: string;
overview: string; overview: string;

View file

@ -45,6 +45,7 @@ export interface ISearchAlbumResult {
available: boolean; available: boolean;
// for the UI // for the UI
showSubscribe: boolean;
requestProcessing: boolean; requestProcessing: boolean;
processed: boolean; processed: boolean;
background: any; background: any;

View file

@ -1,8 +1,8 @@
import { Component, OnInit } from "@angular/core"; import { Component, OnInit } from "@angular/core";
import { NguCarouselConfig } from "@ngu/carousel"; import { NguCarouselConfig } from "@ngu/carousel";
import { ImageService, RecentlyAddedService } from "../services";
import { IRecentlyAddedMovies, IRecentlyAddedTvShows } from "../interfaces"; import { IRecentlyAddedMovies, IRecentlyAddedTvShows } from "../interfaces";
import { ImageService, RecentlyAddedService } from "../services";
@Component({ @Component({
templateUrl: "recentlyAdded.component.html", templateUrl: "recentlyAdded.component.html",

View file

@ -2,7 +2,7 @@ import { Component, EventEmitter, Input, Output } from "@angular/core";
import { TranslateService } from "@ngx-translate/core"; import { TranslateService } from "@ngx-translate/core";
import { AuthService } from "../../auth/auth.service"; import { AuthService } from "../../auth/auth.service";
import { IRequestEngineResult, ISearchMovieResult } from "../../interfaces"; import { IRequestEngineResult } from "../../interfaces";
import { ISearchAlbumResult } from "../../interfaces/ISearchMusicResult"; import { ISearchAlbumResult } from "../../interfaces/ISearchMusicResult";
import { NotificationService, RequestService } from "../../services"; import { NotificationService, RequestService } from "../../services";
@ -30,16 +30,16 @@ export class AlbumSearchComponent {
this.setSearch.emit(artistId); this.setSearch.emit(artistId);
} }
public request(searchResult: ISearchMovieResult) { public request(searchResult: ISearchAlbumResult) {
searchResult.requested = true; searchResult.requested = true;
searchResult.requestProcessing = true; searchResult.requestProcessing = true;
searchResult.showSubscribe = false; searchResult.showSubscribe = false;
if (this.authService.hasRole("admin") || this.authService.hasRole("AutoApproveMovie")) { if (this.authService.hasRole("admin") || this.authService.hasRole("AutoApproveMusic")) {
searchResult.approved = true; searchResult.approved = true;
} }
try { try {
this.requestService.requestMovie({ theMovieDbId: searchResult.id }) this.requestService.requestAlbum({ foreignAlbumId: searchResult.foreignAlbumId })
.subscribe(x => { .subscribe(x => {
this.engineResult = x; this.engineResult = x;

View file

@ -5,7 +5,8 @@ import { HttpClient } from "@angular/common/http";
import { Observable } from "rxjs"; import { Observable } from "rxjs";
import { TreeNode } from "primeng/primeng"; import { TreeNode } from "primeng/primeng";
import { FilterType, IChildRequests, IFilter, IMovieRequestModel, IMovieRequests, IMovieUpdateModel, IRequestEngineResult, IRequestsViewModel, ITvRequests, ITvUpdateModel, OrderType } from "../interfaces"; import { FilterType, IAlbumRequest, IAlbumRequestModel, IAlbumUpdateModel, IChildRequests, IFilter, IMovieRequestModel, IMovieRequests,
IMovieUpdateModel, IRequestEngineResult, IRequestsViewModel, ITvRequests, ITvUpdateModel, OrderType } from "../interfaces";
import { ITvRequestViewModel } from "../interfaces"; import { ITvRequestViewModel } from "../interfaces";
import { ServiceHelpers } from "./service.helpers"; import { ServiceHelpers } from "./service.helpers";
@ -132,4 +133,42 @@ export class RequestService extends ServiceHelpers {
public setRootFolder(requestId: number, rootFolderId: number): Observable<boolean> { public setRootFolder(requestId: number, rootFolderId: number): Observable<boolean> {
return this.http.put<boolean>(`${this.url}tv/root/${requestId}/${rootFolderId}`, {headers: this.headers}); return this.http.put<boolean>(`${this.url}tv/root/${requestId}/${rootFolderId}`, {headers: this.headers});
} }
// Music
public requestAlbum(Album: IAlbumRequestModel): Observable<IRequestEngineResult> {
return this.http.post<IRequestEngineResult>(`${this.url}music/`, JSON.stringify(Album), {headers: this.headers});
}
public getTotalAlbums(): Observable<number> {
return this.http.get<number>(`${this.url}music/total`, {headers: this.headers});
}
public approveAlbum(Album: IAlbumUpdateModel): Observable<IRequestEngineResult> {
return this.http.post<IRequestEngineResult>(`${this.url}music/Approve`, JSON.stringify(Album), {headers: this.headers});
}
public denyAlbum(Album: IAlbumUpdateModel): Observable<IRequestEngineResult> {
return this.http.put<IRequestEngineResult>(`${this.url}music/Deny`, JSON.stringify(Album), {headers: this.headers});
}
public markAlbumAvailable(Album: IAlbumUpdateModel): Observable<IRequestEngineResult> {
return this.http.post<IRequestEngineResult>(`${this.url}music/available`, JSON.stringify(Album), {headers: this.headers});
}
public markAlbumUnavailable(Album: IAlbumUpdateModel): Observable<IRequestEngineResult> {
return this.http.post<IRequestEngineResult>(`${this.url}music/unavailable`, JSON.stringify(Album), {headers: this.headers});
}
public getAlbumRequests(count: number, position: number, order: OrderType, filter: IFilter): Observable<IRequestsViewModel<IMovieRequests>> {
return this.http.get<IRequestsViewModel<IMovieRequests>>(`${this.url}music/${count}/${position}/${order}/${filter.statusFilter}/${filter.availabilityFilter}`, {headers: this.headers});
}
public searchAlbumRequests(search: string): Observable<IAlbumRequest[]> {
return this.http.get<IAlbumRequest[]>(`${this.url}music/search/${search}`, {headers: this.headers});
}
public removeAlbumRequest(request: IAlbumRequest) {
this.http.delete(`${this.url}music/${request.id}`, {headers: this.headers}).subscribe();
}
} }

View file

@ -1,8 +1,8 @@
import { Component, OnInit } from "@angular/core"; import { Component, OnInit } from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router"; import { ActivatedRoute, Router } from "@angular/router";
import { IdentityService, PlexOAuthService } from "../../services";
import { AuthService } from "../../auth/auth.service"; import { AuthService } from "../../auth/auth.service";
import { IdentityService, PlexOAuthService } from "../../services";
@Component({ @Component({
templateUrl: "./plexoauth.component.html", templateUrl: "./plexoauth.component.html",