From be2d88c9ea79cc8c8b36b3d1e3f59a5ca2184efd Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 20 Sep 2018 22:18:26 +0100 Subject: [PATCH] Added the request limits in the ui for music --- src/Ombi.Core/Engine/IMusicRequestEngine.cs | 3 ++ src/Ombi.Core/Engine/MusicRequestEngine.cs | 46 +++++++++++++++++++ src/Ombi.Core/Models/UI/UserViewModel.cs | 1 + src/Ombi/ClientApp/app/interfaces/IUser.ts | 1 + .../requests/remainingrequests.component.ts | 8 +++- .../app/search/moviesearch.component.ts | 2 +- .../app/search/music/albumsearch.component.ts | 7 ++- .../search/music/musicsearch.component.html | 5 +- .../app/search/music/musicsearch.component.ts | 1 + .../app/search/tvsearch.component.html | 2 +- .../ClientApp/app/services/request.service.ts | 4 ++ .../usermanagement-user.component.ts | 1 + .../usermanagement.component.html | 6 +++ src/Ombi/Controllers/IdentityController.cs | 11 ++++- .../Controllers/MusicRequestController.cs | 10 ++++ src/Ombi/Controllers/RequestController.cs | 4 +- src/Ombi/wwwroot/translations/en.json | 4 +- 17 files changed, 107 insertions(+), 9 deletions(-) diff --git a/src/Ombi.Core/Engine/IMusicRequestEngine.cs b/src/Ombi.Core/Engine/IMusicRequestEngine.cs index d81ccb429..5caba8a34 100644 --- a/src/Ombi.Core/Engine/IMusicRequestEngine.cs +++ b/src/Ombi.Core/Engine/IMusicRequestEngine.cs @@ -1,7 +1,9 @@ using System.Collections.Generic; using System.Threading.Tasks; +using Ombi.Core.Models; using Ombi.Core.Models.Requests; using Ombi.Core.Models.UI; +using Ombi.Store.Entities; using Ombi.Store.Entities.Requests; namespace Ombi.Core.Engine @@ -20,5 +22,6 @@ namespace Ombi.Core.Engine Task RequestAlbum(MusicAlbumRequestViewModel model); Task> SearchAlbumRequest(string search); Task UserHasRequest(string userId); + Task GetRemainingRequests(OmbiUser user = null); } } \ No newline at end of file diff --git a/src/Ombi.Core/Engine/MusicRequestEngine.cs b/src/Ombi.Core/Engine/MusicRequestEngine.cs index a27b17c38..89d1a221e 100644 --- a/src/Ombi.Core/Engine/MusicRequestEngine.cs +++ b/src/Ombi.Core/Engine/MusicRequestEngine.cs @@ -13,6 +13,7 @@ using Microsoft.Extensions.Logging; using Ombi.Api.Lidarr; using Ombi.Core.Authentication; using Ombi.Core.Engine.Interfaces; +using Ombi.Core.Models; using Ombi.Core.Models.UI; using Ombi.Core.Rule.Interfaces; using Ombi.Core.Senders; @@ -409,6 +410,49 @@ namespace Ombi.Core.Engine Result = true }; } + public async Task GetRemainingRequests(OmbiUser user) + { + if (user == null) + { + user = await GetUser(); + + // If user is still null after attempting to get the logged in user, return null. + if (user == null) + { + return null; + } + } + + int limit = user.MusicRequestLimit ?? 0; + + if (limit <= 0) + { + return new RequestQuotaCountModel() + { + HasLimit = false, + Limit = 0, + Remaining = 0, + NextRequest = DateTime.Now, + }; + } + + IQueryable log = _requestLog.GetAll().Where(x => x.UserId == user.Id && x.RequestType == RequestType.Album); + + int count = limit - await log.CountAsync(x => x.RequestDate >= DateTime.UtcNow.AddDays(-7)); + + DateTime oldestRequestedAt = await log.Where(x => x.RequestDate >= DateTime.UtcNow.AddDays(-7)) + .OrderBy(x => x.RequestDate) + .Select(x => x.RequestDate) + .FirstOrDefaultAsync(); + + return new RequestQuotaCountModel() + { + HasLimit = true, + Limit = limit, + Remaining = count, + NextRequest = DateTime.SpecifyKind(oldestRequestedAt.AddDays(7), DateTimeKind.Utc), + }; + } public async Task MarkAvailable(int modelId) { @@ -453,5 +497,7 @@ namespace Ombi.Core.Engine return new RequestEngineResult { Result = true, Message = $"{model.Title} has been successfully added!" }; } + + } } \ No newline at end of file diff --git a/src/Ombi.Core/Models/UI/UserViewModel.cs b/src/Ombi.Core/Models/UI/UserViewModel.cs index 8d01c066b..ca40c2ec5 100644 --- a/src/Ombi.Core/Models/UI/UserViewModel.cs +++ b/src/Ombi.Core/Models/UI/UserViewModel.cs @@ -19,6 +19,7 @@ namespace Ombi.Core.Models.UI public int EpisodeRequestLimit { get; set; } public RequestQuotaCountModel EpisodeRequestQuota { get; set; } public RequestQuotaCountModel MovieRequestQuota { get; set; } + public RequestQuotaCountModel MusicRequestQuota { get; set; } public int MusicRequestLimit { get; set; } public UserQualityProfiles UserQualityProfiles { get; set; } } diff --git a/src/Ombi/ClientApp/app/interfaces/IUser.ts b/src/Ombi/ClientApp/app/interfaces/IUser.ts index 0cb4123a7..a44750040 100644 --- a/src/Ombi/ClientApp/app/interfaces/IUser.ts +++ b/src/Ombi/ClientApp/app/interfaces/IUser.ts @@ -20,6 +20,7 @@ export interface IUser { // FOR UI episodeRequestQuota: IRemainingRequests | null; movieRequestQuota: IRemainingRequests | null; + musicRequestQuota: IRemainingRequests | null; checked: boolean; } diff --git a/src/Ombi/ClientApp/app/requests/remainingrequests.component.ts b/src/Ombi/ClientApp/app/requests/remainingrequests.component.ts index 4de649f6a..c88e63009 100644 --- a/src/Ombi/ClientApp/app/requests/remainingrequests.component.ts +++ b/src/Ombi/ClientApp/app/requests/remainingrequests.component.ts @@ -12,6 +12,8 @@ import { Observable } from "rxjs"; export class RemainingRequestsComponent implements OnInit { public remaining: IRemainingRequests; @Input() public movie: boolean; + @Input() public tv: boolean; + @Input() public music: boolean; public daysUntil: number; public hoursUntil: number; public minutesUntil: number; @@ -42,9 +44,13 @@ export class RemainingRequestsComponent implements OnInit { if (this.movie) { this.requestService.getRemainingMovieRequests().subscribe(callback); - } else { + } + if(this.tv) { this.requestService.getRemainingTvRequests().subscribe(callback); } + if(this.music) { + this.requestService.getRemainingMusicRequests().subscribe(callback); + } } private calculateTime(): void { diff --git a/src/Ombi/ClientApp/app/search/moviesearch.component.ts b/src/Ombi/ClientApp/app/search/moviesearch.component.ts index 59e9fc1b8..f4d19565a 100644 --- a/src/Ombi/ClientApp/app/search/moviesearch.component.ts +++ b/src/Ombi/ClientApp/app/search/moviesearch.component.ts @@ -89,9 +89,9 @@ export class MovieSearchComponent implements OnInit { try { this.requestService.requestMovie({ theMovieDbId: searchResult.id }) .subscribe(x => { - this.movieRequested.next(); this.result = x; if (this.result.result) { + this.movieRequested.next(); this.translate.get("Search.RequestAdded", { title: searchResult.title }).subscribe(x => { this.notificationService.success(x); searchResult.processed = true; diff --git a/src/Ombi/ClientApp/app/search/music/albumsearch.component.ts b/src/Ombi/ClientApp/app/search/music/albumsearch.component.ts index 9dac4aa8b..1a44e120e 100644 --- a/src/Ombi/ClientApp/app/search/music/albumsearch.component.ts +++ b/src/Ombi/ClientApp/app/search/music/albumsearch.component.ts @@ -1,6 +1,7 @@ import { Component, EventEmitter, Input, Output } from "@angular/core"; import { TranslateService } from "@ngx-translate/core"; +import { Subject } from "rxjs"; import { AuthService } from "../../auth/auth.service"; import { IIssueCategory, IRequestEngineResult } from "../../interfaces"; import { ISearchAlbumResult } from "../../interfaces/ISearchMusicResult"; @@ -18,6 +19,8 @@ export class AlbumSearchComponent { @Input() public issueCategories: IIssueCategory[]; @Input() public issuesEnabled: boolean; + + @Input() public musicRequested: Subject; public issuesBarVisible = false; public issueRequestTitle: string; public issueRequestId: number; @@ -56,10 +59,12 @@ export class AlbumSearchComponent { try { this.requestService.requestAlbum({ foreignAlbumId: searchResult.foreignAlbumId }) .subscribe(x => { + this.engineResult = x; if (this.engineResult.result) { - this.translate.get("Search.RequestAdded", { title: searchResult.title }).subscribe(x => { + this.musicRequested.next(); + this.translate.get("Search.RequestAdded", { title: searchResult.title }).subscribe(x => { this.notificationService.success(x); searchResult.processed = true; }); diff --git a/src/Ombi/ClientApp/app/search/music/musicsearch.component.html b/src/Ombi/ClientApp/app/search/music/musicsearch.component.html index b73ee553b..e0d95203b 100644 --- a/src/Ombi/ClientApp/app/search/music/musicsearch.component.html +++ b/src/Ombi/ClientApp/app/search/music/musicsearch.component.html @@ -28,6 +28,9 @@
+ + +

@@ -35,7 +38,7 @@
- +

diff --git a/src/Ombi/ClientApp/app/search/music/musicsearch.component.ts b/src/Ombi/ClientApp/app/search/music/musicsearch.component.ts index e022ab6c3..54d941da8 100644 --- a/src/Ombi/ClientApp/app/search/music/musicsearch.component.ts +++ b/src/Ombi/ClientApp/app/search/music/musicsearch.component.ts @@ -24,6 +24,7 @@ export class MusicSearchComponent implements OnInit { public searchApplied = false; public searchAlbum: boolean = true; + public musicRequested: Subject = new Subject(); @Input() public issueCategories: IIssueCategory[]; @Input() public issuesEnabled: boolean; public issuesBarVisible = false; diff --git a/src/Ombi/ClientApp/app/search/tvsearch.component.html b/src/Ombi/ClientApp/app/search/tvsearch.component.html index 127077b3b..44570687a 100644 --- a/src/Ombi/ClientApp/app/search/tvsearch.component.html +++ b/src/Ombi/ClientApp/app/search/tvsearch.component.html @@ -27,7 +27,7 @@
- +
diff --git a/src/Ombi/ClientApp/app/services/request.service.ts b/src/Ombi/ClientApp/app/services/request.service.ts index dd64a14b5..0021dc208 100644 --- a/src/Ombi/ClientApp/app/services/request.service.ts +++ b/src/Ombi/ClientApp/app/services/request.service.ts @@ -26,6 +26,10 @@ export class RequestService extends ServiceHelpers { return this.http.get(`${this.url}tv/remaining`, {headers: this.headers}); } + public getRemainingMusicRequests(): Observable { + return this.http.get(`${this.url}music/remaining`, {headers: this.headers}); + } + public requestMovie(movie: IMovieRequestModel): Observable { return this.http.post(`${this.url}Movie/`, JSON.stringify(movie), {headers: this.headers}); } diff --git a/src/Ombi/ClientApp/app/usermanagement/usermanagement-user.component.ts b/src/Ombi/ClientApp/app/usermanagement/usermanagement-user.component.ts index ee02e53f5..5be0a4509 100644 --- a/src/Ombi/ClientApp/app/usermanagement/usermanagement-user.component.ts +++ b/src/Ombi/ClientApp/app/usermanagement/usermanagement-user.component.ts @@ -82,6 +82,7 @@ export class UserManagementUserComponent implements OnInit { sonarrRootPath: 0, sonarrRootPathAnime: 0, }, + musicRequestQuota: null, }; } } diff --git a/src/Ombi/ClientApp/app/usermanagement/usermanagement.component.html b/src/Ombi/ClientApp/app/usermanagement/usermanagement.component.html index 856e8785c..179709e5d 100644 --- a/src/Ombi/ClientApp/app/usermanagement/usermanagement.component.html +++ b/src/Ombi/ClientApp/app/usermanagement/usermanagement.component.html @@ -98,6 +98,9 @@
{{'UserManagment.TvRemaining' | translate: {remaining: u.episodeRequestQuota.remaining, total: u.episodeRequestLimit} }}
+
+ {{'UserManagment.MusicRemaining' | translate: {remaining: u.musicRequestQuota.remaining, total: u.musicRequestLimit} }} +
@@ -106,6 +109,9 @@
{{'UserManagment.TvDue' | translate: {date: (u.episodeRequestQuota.nextRequest | date: 'short')} }}
+
+ {{'UserManagment.MusicDue' | translate: {date: (u.musicRequestQuota.nextRequest | date: 'short')} }} +
{{u.lastLoggedIn | date: 'short'}} diff --git a/src/Ombi/Controllers/IdentityController.cs b/src/Ombi/Controllers/IdentityController.cs index d9d8be7b1..d138e973e 100644 --- a/src/Ombi/Controllers/IdentityController.cs +++ b/src/Ombi/Controllers/IdentityController.cs @@ -16,6 +16,7 @@ using Ombi.Api.Plex; using Ombi.Attributes; using Ombi.Config; using Ombi.Core.Authentication; +using Ombi.Core.Engine; using Ombi.Core.Engine.Interfaces; using Ombi.Core.Helpers; using Ombi.Core.Models.UI; @@ -66,7 +67,8 @@ namespace Ombi.Controllers IRepository userProfiles, IMusicRequestRepository musicRepo, IMovieRequestEngine movieRequestEngine, - ITvRequestEngine tvRequestEngine) + ITvRequestEngine tvRequestEngine, + IMusicRequestEngine musicEngine) { UserManager = user; Mapper = mapper; @@ -92,6 +94,7 @@ namespace Ombi.Controllers MovieRequestEngine = movieRequestEngine; _userNotificationPreferences = notificationPreferences; _userQualityProfiles = userProfiles; + MusicRequestEngine = musicEngine; } private OmbiUserManager UserManager { get; } @@ -106,6 +109,7 @@ namespace Ombi.Controllers private IMovieRequestRepository MovieRepo { get; } private ITvRequestRepository TvRepo { get; } private IMovieRequestEngine MovieRequestEngine { get; } + private IMusicRequestEngine MusicRequestEngine { get; } private ITvRequestEngine TvRequestEngine { get; } private IMusicRequestRepository MusicRepo { get; } private readonly ILogger _log; @@ -342,6 +346,11 @@ namespace Ombi.Controllers vm.MovieRequestQuota = await MovieRequestEngine.GetRemainingRequests(user); } + if (vm.MusicRequestLimit > 0) + { + vm.MusicRequestQuota = await MusicRequestEngine.GetRemainingRequests(user); + } + // Get the quality profiles vm.UserQualityProfiles = await _userQualityProfiles.GetAll().FirstOrDefaultAsync(x => x.UserId == user.Id); if (vm.UserQualityProfiles == null) diff --git a/src/Ombi/Controllers/MusicRequestController.cs b/src/Ombi/Controllers/MusicRequestController.cs index 3758da9d8..0d763cd86 100644 --- a/src/Ombi/Controllers/MusicRequestController.cs +++ b/src/Ombi/Controllers/MusicRequestController.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Ombi.Store.Entities.Requests; using Ombi.Attributes; +using Ombi.Core.Models; using Ombi.Core.Models.UI; namespace Ombi.Controllers @@ -140,5 +141,14 @@ namespace Ombi.Controllers { return await _engine.DenyAlbumById(model.Id); } + + /// + /// Gets model containing remaining number of music requests. + /// + [HttpGet("remaining")] + public async Task GetRemainingMusicRequests() + { + return await _engine.GetRemainingRequests(); + } } } \ No newline at end of file diff --git a/src/Ombi/Controllers/RequestController.cs b/src/Ombi/Controllers/RequestController.cs index f2412727f..25270f9dd 100644 --- a/src/Ombi/Controllers/RequestController.cs +++ b/src/Ombi/Controllers/RequestController.cs @@ -467,7 +467,7 @@ namespace Ombi.Controllers } /// - /// Gets model containing remaining number of requests. + /// Gets model containing remaining number of movie requests. /// [HttpGet("movie/remaining")] public async Task GetRemainingMovieRequests() @@ -476,7 +476,7 @@ namespace Ombi.Controllers } /// - /// Gets model containing remaining number of requests. + /// Gets model containing remaining number of tv requests. /// [HttpGet("tv/remaining")] public async Task GetRemainingTvRequests() diff --git a/src/Ombi/wwwroot/translations/en.json b/src/Ombi/wwwroot/translations/en.json index ca8dbcd3e..cbe2c034e 100644 --- a/src/Ombi/wwwroot/translations/en.json +++ b/src/Ombi/wwwroot/translations/en.json @@ -189,7 +189,9 @@ "UserManagment": { "TvRemaining": "TV: {{remaining}}/{{total}} remaining", "MovieRemaining": "Movies: {{remaining}}/{{total}} remaining", + "MusicRemaining": "Music: {{remaining}}/{{total}} remaining", "TvDue": "TV: {{date}}", - "MovieDue": "Movie: {{date}}" + "MovieDue": "Movie: {{date}}", + "MusicDue": "Music: {{date}}" } }