Added the request limits in the ui for music

pull/2525/head
Jamie 6 years ago
parent 550028b9eb
commit be2d88c9ea

@ -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<RequestEngineResult> RequestAlbum(MusicAlbumRequestViewModel model);
Task<IEnumerable<AlbumRequest>> SearchAlbumRequest(string search);
Task<bool> UserHasRequest(string userId);
Task<RequestQuotaCountModel> GetRemainingRequests(OmbiUser user = null);
}
}

@ -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<RequestQuotaCountModel> 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<RequestLog> 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<RequestEngineResult> MarkAvailable(int modelId)
{
@ -453,5 +497,7 @@ namespace Ombi.Core.Engine
return new RequestEngineResult { Result = true, Message = $"{model.Title} has been successfully added!" };
}
}
}

@ -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; }
}

@ -20,6 +20,7 @@ export interface IUser {
// FOR UI
episodeRequestQuota: IRemainingRequests | null;
movieRequestQuota: IRemainingRequests | null;
musicRequestQuota: IRemainingRequests | null;
checked: boolean;
}

@ -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 {

@ -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;

@ -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<void>;
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;
});

@ -28,6 +28,9 @@
<div class='no-search-results-text' [translate]="'Search.NoResults'"></div>
</div>
<remaining-requests [music]="true" [quotaRefreshEvents]="musicRequested.asObservable()" #remainingAlbums></remaining-requests>
<div *ngFor="let result of artistResult">
<artist-search [result]="result" [defaultPoster]="defaultPoster" (viewAlbumsResult)="viewAlbumsForArtist($event)"></artist-search>
<br/>
@ -35,7 +38,7 @@
</div>
<div class="col-md-12">
<div *ngFor="let result of albumResult" class="col-md-4">
<album-search [result]="result" [defaultPoster]="defaultPoster" (setSearch)="setArtistSearch($event)"></album-search>
<album-search [musicRequested]="musicRequested" [result]="result" [defaultPoster]="defaultPoster" (setSearch)="setArtistSearch($event)"></album-search>
<br/>
<br/>
</div>

@ -24,6 +24,7 @@ export class MusicSearchComponent implements OnInit {
public searchApplied = false;
public searchAlbum: boolean = true;
public musicRequested: Subject<void> = new Subject<void>();
@Input() public issueCategories: IIssueCategory[];
@Input() public issuesEnabled: boolean;
public issuesBarVisible = false;

@ -27,7 +27,7 @@
</div>
</div>
<remaining-requests [movie]="false" [quotaRefreshEvents]="tvRequested.asObservable()" #remainingTvShows></remaining-requests>
<remaining-requests [tv]="true" [quotaRefreshEvents]="tvRequested.asObservable()" #remainingTvShows></remaining-requests>
<!-- Movie content -->
<div id="actorMovieList">

@ -26,6 +26,10 @@ export class RequestService extends ServiceHelpers {
return this.http.get<IRemainingRequests>(`${this.url}tv/remaining`, {headers: this.headers});
}
public getRemainingMusicRequests(): Observable<IRemainingRequests> {
return this.http.get<IRemainingRequests>(`${this.url}music/remaining`, {headers: this.headers});
}
public requestMovie(movie: IMovieRequestModel): Observable<IRequestEngineResult> {
return this.http.post<IRequestEngineResult>(`${this.url}Movie/`, JSON.stringify(movie), {headers: this.headers});
}

@ -82,6 +82,7 @@ export class UserManagementUserComponent implements OnInit {
sonarrRootPath: 0,
sonarrRootPathAnime: 0,
},
musicRequestQuota: null,
};
}
}

@ -98,6 +98,9 @@
<div *ngIf="u.episodeRequestQuota != null && u.episodeRequestQuota.hasLimit">
{{'UserManagment.TvRemaining' | translate: {remaining: u.episodeRequestQuota.remaining, total: u.episodeRequestLimit} }}
</div>
<div *ngIf="u.musicRequestQuota != null && u.musicRequestQuota.hasLimit">
{{'UserManagment.MusicRemaining' | translate: {remaining: u.musicRequestQuota.remaining, total: u.musicRequestLimit} }}
</div>
</td>
<td class="td-labelled" data-label="Request Due">
<div *ngIf="u.movieRequestQuota != null && u.movieRequestQuota.remaining != u.movieRequestLimit">
@ -106,6 +109,9 @@
<div *ngIf="u.episodeRequestQuota != null && u.episodeRequestQuota.remaining != u.episodeRequestLimit">
{{'UserManagment.TvDue' | translate: {date: (u.episodeRequestQuota.nextRequest | date: 'short')} }}
</div>
<div *ngIf="u.musicRequestQuota != null && u.musicRequestQuota.remaining != u.musicRequestLimit">
{{'UserManagment.MusicDue' | translate: {date: (u.musicRequestQuota.nextRequest | date: 'short')} }}
</div>
</td>
<td class="td-labelled" data-label="Last Logged In:">
{{u.lastLoggedIn | date: 'short'}}

@ -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<UserQualityProfiles> 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<IdentityController> _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)

@ -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);
}
/// <summary>
/// Gets model containing remaining number of music requests.
/// </summary>
[HttpGet("remaining")]
public async Task<RequestQuotaCountModel> GetRemainingMusicRequests()
{
return await _engine.GetRemainingRequests();
}
}
}

@ -467,7 +467,7 @@ namespace Ombi.Controllers
}
/// <summary>
/// Gets model containing remaining number of requests.
/// Gets model containing remaining number of movie requests.
/// </summary>
[HttpGet("movie/remaining")]
public async Task<RequestQuotaCountModel> GetRemainingMovieRequests()
@ -476,7 +476,7 @@ namespace Ombi.Controllers
}
/// <summary>
/// Gets model containing remaining number of requests.
/// Gets model containing remaining number of tv requests.
/// </summary>
[HttpGet("tv/remaining")]
public async Task<RequestQuotaCountModel> GetRemainingTvRequests()

@ -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}}"
}
}

Loading…
Cancel
Save