Loads more work *phew* !wip

This commit is contained in:
Jamie 2018-08-24 16:07:53 +01:00
parent f72e48659c
commit 70db3c7bca
33 changed files with 841 additions and 487 deletions

BIN
music-placeholder.psd Normal file

Binary file not shown.

View file

@ -11,7 +11,8 @@ namespace Ombi.Api.Lidarr
Task<List<LidarrProfile>> GetProfiles(string apiKey, string baseUrl); Task<List<LidarrProfile>> GetProfiles(string apiKey, string baseUrl);
Task<List<LidarrRootFolder>> GetRootFolders(string apiKey, string baseUrl); Task<List<LidarrRootFolder>> GetRootFolders(string apiKey, string baseUrl);
Task<ArtistResult> GetArtist(int artistId, string apiKey, string baseUrl); Task<ArtistResult> GetArtist(int artistId, string apiKey, string baseUrl);
Task<ArtistResult> GetArtistByForignId(string foreignArtistId, string apiKey, string baseUrl); Task<ArtistResult> GetArtistByForeignId(string foreignArtistId, string apiKey, string baseUrl);
Task<AlbumByArtistResponse> GetAlbumsByArtist(int artistId, string apiKey, string baseUrl); Task<AlbumByArtistResponse> GetAlbumsByArtist(int artistId, string apiKey, string baseUrl);
Task<AlbumLookup> GetAlbumByForeignId(string foreignArtistId, string apiKey, string baseUrl);
} }
} }

View file

@ -62,7 +62,7 @@ namespace Ombi.Api.Lidarr
return Api.Request<ArtistResult>(request); return Api.Request<ArtistResult>(request);
} }
public Task<ArtistResult> GetArtistByForignId(string foreignArtistId, string apiKey, string baseUrl) public Task<ArtistResult> GetArtistByForeignId(string foreignArtistId, string apiKey, string baseUrl)
{ {
var request = new Request($"{ApiVersion}/artist/lookup", baseUrl, HttpMethod.Get); var request = new Request($"{ApiVersion}/artist/lookup", baseUrl, HttpMethod.Get);
@ -71,6 +71,16 @@ namespace Ombi.Api.Lidarr
return Api.Request<ArtistResult>(request); return Api.Request<ArtistResult>(request);
} }
public Task<AlbumLookup> GetAlbumByForeignId(string foreignArtistId, string apiKey, string baseUrl)
{
var request = new Request($"{ApiVersion}/album/lookup", baseUrl, HttpMethod.Get);
request.AddQueryString("term", $"lidarr:{foreignArtistId}");
AddHeaders(request, apiKey);
return Api.Request<AlbumLookup>(request);
}
public Task<AlbumByArtistResponse> GetAlbumsByArtist(int artistId, string apiKey, string baseUrl) public Task<AlbumByArtistResponse> GetAlbumsByArtist(int artistId, string apiKey, string baseUrl)
{ {
var request = new Request($"{ApiVersion}/album", baseUrl, HttpMethod.Get); var request = new Request($"{ApiVersion}/album", baseUrl, HttpMethod.Get);

View file

@ -36,6 +36,7 @@ namespace Ombi.Core.Engine
protected IRequestServiceMain RequestService { get; } protected IRequestServiceMain RequestService { get; }
protected IMovieRequestRepository MovieRepository => RequestService.MovieRequestService; protected IMovieRequestRepository MovieRepository => RequestService.MovieRequestService;
protected ITvRequestRepository TvRepository => RequestService.TvRequestService; protected ITvRequestRepository TvRepository => RequestService.TvRequestService;
protected IMusicRequestRepository MusicRepository => RequestService.MusicRequestRepository;
protected readonly ICacheService Cache; protected readonly ICacheService Cache;
protected readonly ISettingsService<OmbiSettings> OmbiSettings; protected readonly ISettingsService<OmbiSettings> OmbiSettings;
protected readonly IRepository<RequestSubscription> _subscriptionRepository; protected readonly IRepository<RequestSubscription> _subscriptionRepository;

View file

@ -0,0 +1,24 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Ombi.Core.Models.Requests;
using Ombi.Core.Models.UI;
using Ombi.Store.Entities.Requests;
namespace Ombi.Core.Engine
{
public interface IMusicRequestEngine
{
Task<RequestEngineResult>ApproveAlbum(AlbumRequest request);
Task<RequestEngineResult> ApproveAlbumById(int requestId);
Task<RequestEngineResult> DenyAlbumById(int modelId);
Task<IEnumerable<AlbumRequest>> GetRequests();
Task<RequestsViewModel<AlbumRequest>> GetRequests(int count, int position, OrderFilterModel orderFilter);
Task<int> GetTotal();
Task<RequestEngineResult> MarkAvailable(int modelId);
Task<RequestEngineResult> MarkUnavailable(int modelId);
Task RemoveAlbumRequest(int requestId);
Task<RequestEngineResult> RequestAlbum(MusicAlbumRequestViewModel model);
Task<IEnumerable<AlbumRequest>> SearchAlbumRequest(string search);
Task<bool> UserHasRequest(string userId);
}
}

View file

@ -1,492 +1,456 @@
//using Ombi.Api.TheMovieDb; using Ombi.Api.TheMovieDb;
//using Ombi.Core.Models.Requests; using Ombi.Core.Models.Requests;
//using Ombi.Helpers; using Ombi.Helpers;
//using Ombi.Store.Entities; using Ombi.Store.Entities;
//using System; using System;
//using System.Collections.Generic; using System.Collections.Generic;
//using System.Globalization; using System.Globalization;
//using System.Linq; using System.Linq;
//using System.Security.Principal; using System.Security.Principal;
//using System.Threading.Tasks; using System.Threading.Tasks;
//using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
//using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
//using Ombi.Api.Lidarr; using Ombi.Api.Lidarr;
//using Ombi.Api.TheMovieDb.Models; using Ombi.Core.Authentication;
//using Ombi.Core.Authentication; using Ombi.Core.Engine.Interfaces;
//using Ombi.Core.Engine.Interfaces; using Ombi.Core.Models.UI;
//using Ombi.Core.Models.UI; using Ombi.Core.Rule.Interfaces;
//using Ombi.Core.Rule.Interfaces; using Ombi.Core.Settings;
//using Ombi.Core.Settings; using Ombi.Settings.Settings.Models;
//using Ombi.Settings.Settings.Models; using Ombi.Settings.Settings.Models.External;
//using Ombi.Settings.Settings.Models.External; using Ombi.Store.Entities.Requests;
//using Ombi.Store.Entities.Requests; using Ombi.Store.Repository;
//using Ombi.Store.Repository;
//namespace Ombi.Core.Engine namespace Ombi.Core.Engine
//{ {
// public class MusicRequestEngine : BaseMediaEngine public class MusicRequestEngine : BaseMediaEngine, IMusicRequestEngine
// { {
// public MusicRequestEngine(IMovieDbApi movieApi, IRequestServiceMain requestService, IPrincipal user, public MusicRequestEngine(IRequestServiceMain requestService, IPrincipal user,
// INotificationHelper helper, IRuleEvaluator r, IMovieSender sender, ILogger<MovieRequestEngine> log, INotificationHelper helper, IRuleEvaluator r, ILogger<MusicRequestEngine> log,
// OmbiUserManager manager, IRepository<RequestLog> rl, ICacheService cache, OmbiUserManager manager, IRepository<RequestLog> rl, ICacheService cache,
// ISettingsService<OmbiSettings> ombiSettings, IRepository<RequestSubscription> sub, ILidarrApi lidarr, ISettingsService<OmbiSettings> ombiSettings, IRepository<RequestSubscription> sub, ILidarrApi lidarr,
// ISettingsService<LidarrSettings> lidarrSettings) ISettingsService<LidarrSettings> lidarrSettings)
// : base(user, requestService, r, manager, cache, ombiSettings, sub) : base(user, requestService, r, manager, cache, ombiSettings, sub)
// { {
// MovieApi = movieApi; NotificationHelper = helper;
// NotificationHelper = helper; //Sender = sender;
// Sender = sender; Logger = log;
// Logger = log; _requestLog = rl;
// _requestLog = rl; _lidarrApi = lidarr;
// _lidarrApi = lidarr; _lidarrSettings = lidarrSettings;
// _lidarrSettings = lidarrSettings; }
// }
// private IMovieDbApi MovieApi { get; } private INotificationHelper NotificationHelper { get; }
// private INotificationHelper NotificationHelper { get; } //private IMovieSender Sender { get; }
// private IMovieSender Sender { get; } private ILogger Logger { get; }
// private ILogger<MovieRequestEngine> Logger { get; } private readonly IRepository<RequestLog> _requestLog;
// private readonly IRepository<RequestLog> _requestLog; private readonly ISettingsService<LidarrSettings> _lidarrSettings;
// private readonly ISettingsService<LidarrSettings> _lidarrSettings; private readonly ILidarrApi _lidarrApi;
// private readonly ILidarrApi _lidarrApi;
// /// <summary> /// <summary>
// /// Requests the movie. /// Requests the Album.
// /// </summary> /// </summary>
// /// <param name="model">The model.</param> /// <param name="model">The model.</param>
// /// <returns></returns> /// <returns></returns>
// public async Task<RequestEngineResult> RequestArtist(MusicArtistRequestViewModel model) public async Task<RequestEngineResult> RequestAlbum(MusicAlbumRequestViewModel model)
// { {
// var s = await _lidarrSettings.GetSettingsAsync(); var s = await _lidarrSettings.GetSettingsAsync();
// var artist = await _lidarrApi.GetArtistByForignId(model.ForeignArtistId, s.ApiKey, s.FullUri); var album = await _lidarrApi.GetAlbumByForeignId(model.ForeignAlbumId, s.ApiKey, s.FullUri);
// if (artist == null) if (album == null)
// { {
// return new RequestEngineResult return new RequestEngineResult
// { {
// Result = false, Result = false,
// Message = "There was an issue adding this Artist!", Message = "There was an issue adding this album!",
// ErrorMessage = "Please try again later" ErrorMessage = "Please try again later"
// }; };
// } }
// var userDetails = await GetUser(); var userDetails = await GetUser();
// var requestModel = new MovieRequests var requestModel = new AlbumRequest
// { {
// TheMovieDbId = movieInfo.Id, ForeignAlbumId = model.ForeignAlbumId,
// RequestType = RequestType.Movie, ArtistName = album.artist?.artistName,
// Overview = movieInfo.Overview, ReleaseDate = album.releaseDate,
// ImdbId = movieInfo.ImdbId, RequestedDate = DateTime.Now,
// PosterPath = PosterPathHelper.FixPosterPath(movieInfo.PosterPath), RequestType = RequestType.Album,
// Title = movieInfo.Title, Rating = album.ratings?.value ?? 0m,
// ReleaseDate = !string.IsNullOrEmpty(movieInfo.ReleaseDate) RequestedUserId = userDetails.Id,
// ? DateTime.Parse(movieInfo.ReleaseDate) Title = album.title,
// : DateTime.MinValue, Disk = album.images?.FirstOrDefault(x => x.coverType.Equals("disc"))?.url,
// Status = movieInfo.Status, Cover = album.images?.FirstOrDefault(x => x.coverType.Equals("cover"))?.url
// RequestedDate = DateTime.UtcNow, };
// Approved = false, if (requestModel.Cover.IsNullOrEmpty())
// RequestedUserId = userDetails.Id, {
// Background = movieInfo.BackdropPath requestModel.Cover = album.remoteCover;
// }; }
// var usDates = movieInfo.ReleaseDates?.Results?.FirstOrDefault(x => x.IsoCode == "US"); var ruleResults = (await RunRequestRules(requestModel)).ToList();
// requestModel.DigitalReleaseDate = usDates?.ReleaseDate if (ruleResults.Any(x => !x.Success))
// ?.FirstOrDefault(x => x.Type == ReleaseDateType.Digital)?.ReleaseDate; {
return new RequestEngineResult
{
ErrorMessage = ruleResults.FirstOrDefault(x => x.Message.HasValue()).Message
};
}
// var ruleResults = (await RunRequestRules(requestModel)).ToList(); if (requestModel.Approved) // The rules have auto approved this
// if (ruleResults.Any(x => !x.Success)) {
// { var requestEngineResult = await AddAlbumRequest(requestModel);
// return new RequestEngineResult if (requestEngineResult.Result)
// { {
// ErrorMessage = ruleResults.FirstOrDefault(x => x.Message.HasValue()).Message var result = await ApproveAlbum(requestModel);
// }; if (result.IsError)
// } {
Logger.LogWarning("Tried auto sending Album but failed. Message: {0}", result.Message);
return new RequestEngineResult
{
Message = result.Message,
ErrorMessage = result.Message,
Result = false
};
}
// if (requestModel.Approved) // The rules have auto approved this return requestEngineResult;
// { }
// var requestEngineResult = await AddMovieRequest(requestModel, fullMovieName);
// if (requestEngineResult.Result)
// {
// var result = await ApproveMovie(requestModel);
// if (result.IsError)
// {
// Logger.LogWarning("Tried auto sending movie but failed. Message: {0}", result.Message);
// return new RequestEngineResult
// {
// Message = result.Message,
// ErrorMessage = result.Message,
// Result = false
// };
// }
// return requestEngineResult; // If there are no providers then it's successful but album has not been sent
// } }
// // If there are no providers then it's successful but movie has not been sent return await AddAlbumRequest(requestModel);
// } }
// return await AddMovieRequest(requestModel, fullMovieName);
// }
// /// <summary> /// <summary>
// /// Gets the requests. /// Gets the requests.
// /// </summary> /// </summary>
// /// <param name="count">The count.</param> /// <param name="count">The count.</param>
// /// <param name="position">The position.</param> /// <param name="position">The position.</param>
// /// <param name="orderFilter">The order/filter type.</param> /// <param name="orderFilter">The order/filter type.</param>
// /// <returns></returns> /// <returns></returns>
// public async Task<RequestsViewModel<MovieRequests>> GetRequests(int count, int position, public async Task<RequestsViewModel<AlbumRequest>> GetRequests(int count, int position,
// OrderFilterModel orderFilter) OrderFilterModel orderFilter)
// { {
// var shouldHide = await HideFromOtherUsers(); var shouldHide = await HideFromOtherUsers();
// IQueryable<MovieRequests> allRequests; IQueryable<AlbumRequest> allRequests;
// if (shouldHide.Hide) if (shouldHide.Hide)
// { {
// allRequests = allRequests =
// MovieRepository.GetWithUser(shouldHide MusicRepository.GetWithUser(shouldHide
// .UserId); //.Skip(position).Take(count).OrderByDescending(x => x.ReleaseDate).ToListAsync(); .UserId); //.Skip(position).Take(count).OrderByDescending(x => x.ReleaseDate).ToListAsync();
// } }
// else else
// { {
// allRequests = allRequests =
// MovieRepository MusicRepository
// .GetWithUser(); //.Skip(position).Take(count).OrderByDescending(x => x.ReleaseDate).ToListAsync(); .GetWithUser(); //.Skip(position).Take(count).OrderByDescending(x => x.ReleaseDate).ToListAsync();
// } }
// switch (orderFilter.AvailabilityFilter) switch (orderFilter.AvailabilityFilter)
// { {
// case FilterType.None: case FilterType.None:
// break; break;
// case FilterType.Available: case FilterType.Available:
// allRequests = allRequests.Where(x => x.Available); allRequests = allRequests.Where(x => x.Available);
// break; break;
// case FilterType.NotAvailable: case FilterType.NotAvailable:
// allRequests = allRequests.Where(x => !x.Available); allRequests = allRequests.Where(x => !x.Available);
// break; break;
// default: default:
// throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
// } }
// switch (orderFilter.StatusFilter) switch (orderFilter.StatusFilter)
// { {
// case FilterType.None: case FilterType.None:
// break; break;
// case FilterType.Approved: case FilterType.Approved:
// allRequests = allRequests.Where(x => x.Approved); allRequests = allRequests.Where(x => x.Approved);
// break; break;
// case FilterType.Processing: case FilterType.Processing:
// allRequests = allRequests.Where(x => x.Approved && !x.Available); allRequests = allRequests.Where(x => x.Approved && !x.Available);
// break; break;
// case FilterType.PendingApproval: case FilterType.PendingApproval:
// allRequests = allRequests.Where(x => !x.Approved && !x.Available && !(x.Denied ?? false)); allRequests = allRequests.Where(x => !x.Approved && !x.Available && !(x.Denied ?? false));
// break; break;
// default: default:
// throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
// } }
// var total = allRequests.Count(); var total = allRequests.Count();
// var requests = await (OrderMovies(allRequests, orderFilter.OrderType)).Skip(position).Take(count) var requests = await (OrderAlbums(allRequests, orderFilter.OrderType)).Skip(position).Take(count)
// .ToListAsync(); .ToListAsync();
// requests.ForEach(async x => requests.ForEach(async x =>
// { {
// x.PosterPath = PosterPathHelper.FixPosterPath(x.PosterPath); await CheckForSubscription(shouldHide, x);
// await CheckForSubscription(shouldHide, x); });
// }); return new RequestsViewModel<AlbumRequest>
// return new RequestsViewModel<MovieRequests> {
// { Collection = requests,
// Collection = requests, Total = total
// Total = total };
// }; }
// }
// private IQueryable<MovieRequests> OrderMovies(IQueryable<MovieRequests> allRequests, OrderType type) private IQueryable<AlbumRequest> OrderAlbums(IQueryable<AlbumRequest> allRequests, OrderType type)
// { {
// switch (type) switch (type)
// { {
// case OrderType.RequestedDateAsc: case OrderType.RequestedDateAsc:
// return allRequests.OrderBy(x => x.RequestedDate); return allRequests.OrderBy(x => x.RequestedDate);
// case OrderType.RequestedDateDesc: case OrderType.RequestedDateDesc:
// return allRequests.OrderByDescending(x => x.RequestedDate); return allRequests.OrderByDescending(x => x.RequestedDate);
// case OrderType.TitleAsc: case OrderType.TitleAsc:
// return allRequests.OrderBy(x => x.Title); return allRequests.OrderBy(x => x.Title);
// case OrderType.TitleDesc: case OrderType.TitleDesc:
// return allRequests.OrderByDescending(x => x.Title); return allRequests.OrderByDescending(x => x.Title);
// case OrderType.StatusAsc: default:
// return allRequests.OrderBy(x => x.Status); throw new ArgumentOutOfRangeException(nameof(type), type, null);
// case OrderType.StatusDesc: }
// return allRequests.OrderByDescending(x => x.Status); }
// default:
// throw new ArgumentOutOfRangeException(nameof(type), type, null);
// }
// }
// public async Task<int> GetTotal() public async Task<int> GetTotal()
// { {
// var shouldHide = await HideFromOtherUsers(); var shouldHide = await HideFromOtherUsers();
// if (shouldHide.Hide) if (shouldHide.Hide)
// { {
// return await MovieRepository.GetWithUser(shouldHide.UserId).CountAsync(); return await MusicRepository.GetWithUser(shouldHide.UserId).CountAsync();
// } }
// else else
// { {
// return await MovieRepository.GetWithUser().CountAsync(); return await MusicRepository.GetWithUser().CountAsync();
// } }
// } }
// /// <summary> /// <summary>
// /// Gets the requests. /// Gets the requests.
// /// </summary> /// </summary>
// /// <returns></returns> /// <returns></returns>
// public async Task<IEnumerable<MovieRequests>> GetRequests() public async Task<IEnumerable<AlbumRequest>> GetRequests()
// { {
// var shouldHide = await HideFromOtherUsers(); var shouldHide = await HideFromOtherUsers();
// List<MovieRequests> allRequests; List<AlbumRequest> allRequests;
// if (shouldHide.Hide) if (shouldHide.Hide)
// { {
// allRequests = await MovieRepository.GetWithUser(shouldHide.UserId).ToListAsync(); allRequests = await MusicRepository.GetWithUser(shouldHide.UserId).ToListAsync();
// } }
// else else
// { {
// allRequests = await MovieRepository.GetWithUser().ToListAsync(); allRequests = await MusicRepository.GetWithUser().ToListAsync();
// } }
// allRequests.ForEach(async x => allRequests.ForEach(async x =>
// { {
// x.PosterPath = PosterPathHelper.FixPosterPath(x.PosterPath); await CheckForSubscription(shouldHide, x);
// await CheckForSubscription(shouldHide, x); });
// }); return allRequests;
// return allRequests; }
// }
// private async Task CheckForSubscription(HideResult shouldHide, MovieRequests x) private async Task CheckForSubscription(HideResult shouldHide, AlbumRequest x)
// { {
// if (shouldHide.UserId == x.RequestedUserId) if (shouldHide.UserId == x.RequestedUserId)
// { {
// x.ShowSubscribe = false; x.ShowSubscribe = false;
// } }
// else else
// { {
// x.ShowSubscribe = true; x.ShowSubscribe = true;
// var sub = await _subscriptionRepository.GetAll().FirstOrDefaultAsync(s => var sub = await _subscriptionRepository.GetAll().FirstOrDefaultAsync(s =>
// s.UserId == shouldHide.UserId && s.RequestId == x.Id && s.RequestType == RequestType.Movie); s.UserId == shouldHide.UserId && s.RequestId == x.Id && s.RequestType == RequestType.Album);
// x.Subscribed = sub != null; x.Subscribed = sub != null;
// } }
// } }
// /// <summary> /// <summary>
// /// Searches the movie request. /// Searches the album request.
// /// </summary> /// </summary>
// /// <param name="search">The search.</param> /// <param name="search">The search.</param>
// /// <returns></returns> /// <returns></returns>
// public async Task<IEnumerable<MovieRequests>> SearchMovieRequest(string search) public async Task<IEnumerable<AlbumRequest>> SearchAlbumRequest(string search)
// { {
// var shouldHide = await HideFromOtherUsers(); var shouldHide = await HideFromOtherUsers();
// List<MovieRequests> allRequests; List<AlbumRequest> allRequests;
// if (shouldHide.Hide) if (shouldHide.Hide)
// { {
// allRequests = await MovieRepository.GetWithUser(shouldHide.UserId).ToListAsync(); allRequests = await MusicRepository.GetWithUser(shouldHide.UserId).ToListAsync();
// } }
// else else
// { {
// allRequests = await MovieRepository.GetWithUser().ToListAsync(); allRequests = await MusicRepository.GetWithUser().ToListAsync();
// } }
// var results = allRequests.Where(x => x.Title.Contains(search, CompareOptions.IgnoreCase)).ToList(); var results = allRequests.Where(x => x.Title.Contains(search, CompareOptions.IgnoreCase)).ToList();
// results.ForEach(async x => results.ForEach(async x =>
// { {
// x.PosterPath = PosterPathHelper.FixPosterPath(x.PosterPath); await CheckForSubscription(shouldHide, x);
// await CheckForSubscription(shouldHide, x); });
// }); return results;
// return results; }
// }
// public async Task<RequestEngineResult> ApproveMovieById(int requestId) public async Task<RequestEngineResult> ApproveAlbumById(int requestId)
// { {
// var request = await MovieRepository.Find(requestId); var request = await MusicRepository.Find(requestId);
// return await ApproveMovie(request); return await ApproveAlbum(request);
// } }
// public async Task<RequestEngineResult> DenyMovieById(int modelId) public async Task<RequestEngineResult> DenyAlbumById(int modelId)
// { {
// var request = await MovieRepository.Find(modelId); var request = await MusicRepository.Find(modelId);
// if (request == null) if (request == null)
// { {
// return new RequestEngineResult return new RequestEngineResult
// { {
// ErrorMessage = "Request does not exist" ErrorMessage = "Request does not exist"
// }; };
// } }
// request.Denied = true; request.Denied = true;
// // We are denying a request // We are denying a request
// NotificationHelper.Notify(request, NotificationType.RequestDeclined); NotificationHelper.Notify(request, NotificationType.RequestDeclined);
// await MovieRepository.Update(request); await MusicRepository.Update(request);
// return new RequestEngineResult return new RequestEngineResult
// { {
// Message = "Request successfully deleted", Message = "Request successfully deleted",
// }; };
// } }
// public async Task<RequestEngineResult> ApproveMovie(MovieRequests request) public async Task<RequestEngineResult> ApproveAlbum(AlbumRequest request)
// { {
// if (request == null) if (request == null)
// { {
// return new RequestEngineResult return new RequestEngineResult
// { {
// ErrorMessage = "Request does not exist" ErrorMessage = "Request does not exist"
// }; };
// } }
// request.Approved = true; if (!request.Approved)
// request.Denied = false; {
// await MovieRepository.Update(request); request.Approved = true;
request.Denied = false;
await MusicRepository.Update(request);
}
// var canNotify = await RunSpecificRule(request, SpecificRules.CanSendNotification); var canNotify = await RunSpecificRule(request, SpecificRules.CanSendNotification);
// if (canNotify.Success) if (canNotify.Success)
// { {
// NotificationHelper.Notify(request, NotificationType.RequestApproved); NotificationHelper.Notify(request, NotificationType.RequestApproved);
// } }
// if (request.Approved) if (request.Approved)
// { {
// var result = await Sender.Send(request); //TODO
// if (result.Success && result.Sent) //var result = await Sender.Send(request);
// { //if (result.Success && result.Sent)
// return new RequestEngineResult //{
// { // return new RequestEngineResult
// Result = true // {
// }; // Result = true
// } // };
//}
// if (!result.Success) //if (!result.Success)
// { //{
// Logger.LogWarning("Tried auto sending movie but failed. Message: {0}", result.Message); // Logger.LogWarning("Tried auto sending movie but failed. Message: {0}", result.Message);
// return new RequestEngineResult // return new RequestEngineResult
// { // {
// Message = result.Message, // Message = result.Message,
// ErrorMessage = result.Message, // ErrorMessage = result.Message,
// Result = false // Result = false
// }; // };
// } //}
// // If there are no providers then it's successful but movie has not been sent // If there are no providers then it's successful but movie has not been sent
// } }
// return new RequestEngineResult return new RequestEngineResult
// { {
// Result = true Result = true
// }; };
// } }
// /// <summary> /// <summary>
// /// Updates the movie request. /// Removes the Album request.
// /// </summary> /// </summary>
// /// <param name="request">The request.</param> /// <param name="requestId">The request identifier.</param>
// /// <returns></returns> /// <returns></returns>
// public async Task<MovieRequests> UpdateMovieRequest(MovieRequests request) public async Task RemoveAlbumRequest(int requestId)
// { {
// var allRequests = await MovieRepository.GetWithUser().ToListAsync(); var request = await MusicRepository.GetAll().FirstOrDefaultAsync(x => x.Id == requestId);
// var results = allRequests.FirstOrDefault(x => x.Id == request.Id); await MusicRepository.Delete(request);
}
// results.Approved = request.Approved; public async Task<bool> UserHasRequest(string userId)
// results.Available = request.Available; {
// results.Denied = request.Denied; return await MusicRepository.GetAll().AnyAsync(x => x.RequestedUserId == userId);
// results.DeniedReason = request.DeniedReason; }
// results.ImdbId = request.ImdbId;
// results.IssueId = request.IssueId;
// results.Issues = request.Issues;
// results.Overview = request.Overview;
// results.PosterPath = PosterPathHelper.FixPosterPath(request.PosterPath);
// results.QualityOverride = request.QualityOverride;
// results.RootPathOverride = request.RootPathOverride;
// await MovieRepository.Update(results); public async Task<RequestEngineResult> MarkUnavailable(int modelId)
// return results; {
// } var request = await MusicRepository.Find(modelId);
if (request == null)
{
return new RequestEngineResult
{
ErrorMessage = "Request does not exist"
};
}
// /// <summary> request.Available = false;
// /// Removes the movie request. await MusicRepository.Update(request);
// /// </summary>
// /// <param name="requestId">The request identifier.</param>
// /// <returns></returns>
// public async Task RemoveMovieRequest(int requestId)
// {
// var request = await MovieRepository.GetAll().FirstOrDefaultAsync(x => x.Id == requestId);
// await MovieRepository.Delete(request);
// }
// public async Task<bool> UserHasRequest(string userId) return new RequestEngineResult
// { {
// return await MovieRepository.GetAll().AnyAsync(x => x.RequestedUserId == userId); Message = "Request is now unavailable",
// } Result = true
};
}
// public async Task<RequestEngineResult> MarkUnavailable(int modelId) public async Task<RequestEngineResult> MarkAvailable(int modelId)
// { {
// var request = await MovieRepository.Find(modelId); var request = await MusicRepository.Find(modelId);
// if (request == null) if (request == null)
// { {
// return new RequestEngineResult return new RequestEngineResult
// { {
// ErrorMessage = "Request does not exist" ErrorMessage = "Request does not exist"
// }; };
// } }
// request.Available = false; request.Available = true;
// await MovieRepository.Update(request); request.MarkedAsAvailable = DateTime.Now;
NotificationHelper.Notify(request, NotificationType.RequestAvailable);
await MusicRepository.Update(request);
// return new RequestEngineResult return new RequestEngineResult
// { {
// Message = "Request is now unavailable", Message = "Request is now available",
// Result = true Result = true
// }; };
// } }
// public async Task<RequestEngineResult> MarkAvailable(int modelId) private async Task<RequestEngineResult> AddAlbumRequest(AlbumRequest model)
// { {
// var request = await MovieRepository.Find(modelId); await MusicRepository.Add(model);
// if (request == null)
// {
// return new RequestEngineResult
// {
// ErrorMessage = "Request does not exist"
// };
// }
// request.Available = true; var result = await RunSpecificRule(model, SpecificRules.CanSendNotification);
// request.MarkedAsAvailable = DateTime.Now; if (result.Success)
// NotificationHelper.Notify(request, NotificationType.RequestAvailable); {
// await MovieRepository.Update(request); NotificationHelper.NewRequest(model);
}
// return new RequestEngineResult await _requestLog.Add(new RequestLog
// { {
// Message = "Request is now available", UserId = (await GetUser()).Id,
// Result = true RequestDate = DateTime.UtcNow,
// }; RequestId = model.Id,
// } RequestType = RequestType.Album,
});
// private async Task<RequestEngineResult> AddMovieRequest(MovieRequests model, string movieName) return new RequestEngineResult { Result = true, Message = $"{model.Title} has been successfully added!" };
// { }
// await MovieRepository.Add(model); }
}
// var result = await RunSpecificRule(model, SpecificRules.CanSendNotification);
// if (result.Success)
// {
// NotificationHelper.NewRequest(model);
// }
// await _requestLog.Add(new RequestLog
// {
// UserId = (await GetUser()).Id,
// RequestDate = DateTime.UtcNow,
// RequestId = model.Id,
// RequestType = RequestType.Movie,
// });
// return new RequestEngineResult {Result = true, Message = $"{movieName} has been successfully added!"};
// }
// }
//}

View file

@ -87,7 +87,7 @@ namespace Ombi.Core.Engine
public async Task<ArtistResult> GetArtistAlbums(string foreignArtistId) public async Task<ArtistResult> GetArtistAlbums(string foreignArtistId)
{ {
var settings = await GetSettings(); var settings = await GetSettings();
return await _lidarrApi.GetArtistByForignId(foreignArtistId, settings.ApiKey, settings.FullUri); return await _lidarrApi.GetArtistByForeignId(foreignArtistId, settings.ApiKey, settings.FullUri);
} }
/// <summary> /// <summary>
@ -98,7 +98,7 @@ namespace Ombi.Core.Engine
public async Task<ArtistResult> GetAlbumArtist(string foreignArtistId) public async Task<ArtistResult> GetAlbumArtist(string foreignArtistId)
{ {
var settings = await GetSettings(); var settings = await GetSettings();
return await _lidarrApi.GetArtistByForignId(foreignArtistId, settings.ApiKey, settings.FullUri); return await _lidarrApi.GetArtistByForeignId(foreignArtistId, settings.ApiKey, settings.FullUri);
} }
public async Task<ArtistResult> GetArtist(int artistId) public async Task<ArtistResult> GetArtist(int artistId)
@ -157,7 +157,7 @@ namespace Ombi.Core.Engine
} }
vm.Cover = a.images?.FirstOrDefault(x => x.coverType.Equals("cover"))?.url; vm.Cover = a.images?.FirstOrDefault(x => x.coverType.Equals("cover"))?.url;
if (vm.Cover == null) if (vm.Cover.IsNullOrEmpty())
{ {
vm.Cover = a.remoteCover; vm.Cover = a.remoteCover;
} }

View file

@ -40,6 +40,18 @@ namespace Ombi.Core
BackgroundJob.Enqueue(() => NotificationService.Publish(notificationModel)); BackgroundJob.Enqueue(() => NotificationService.Publish(notificationModel));
} }
public void NewRequest(AlbumRequest model)
{
var notificationModel = new NotificationOptions
{
RequestId = model.Id,
DateTime = DateTime.Now,
NotificationType = NotificationType.NewRequest,
RequestType = model.RequestType
};
BackgroundJob.Enqueue(() => NotificationService.Publish(notificationModel));
}
public void Notify(MovieRequests model, NotificationType type) public void Notify(MovieRequests model, NotificationType type)
{ {
@ -66,5 +78,19 @@ namespace Ombi.Core
}; };
BackgroundJob.Enqueue(() => NotificationService.Publish(notificationModel)); BackgroundJob.Enqueue(() => NotificationService.Publish(notificationModel));
} }
public void Notify(AlbumRequest model, NotificationType type)
{
var notificationModel = new NotificationOptions
{
RequestId = model.Id,
DateTime = DateTime.Now,
NotificationType = type,
RequestType = model.RequestType,
Recipient = model.RequestedUser?.Email ?? string.Empty
};
BackgroundJob.Enqueue(() => NotificationService.Publish(notificationModel));
}
} }
} }

View file

@ -7,5 +7,6 @@ namespace Ombi.Core.Models.Requests
{ {
IMovieRequestRepository MovieRequestService { get; } IMovieRequestRepository MovieRequestService { get; }
ITvRequestRepository TvRequestService { get; } ITvRequestRepository TvRequestService { get; }
IMusicRequestRepository MusicRequestRepository { get; }
} }
} }

View file

@ -1,15 +1,7 @@
namespace Ombi.Core.Models.Requests namespace Ombi.Core.Models.Requests
{ {
public class MusicArtistRequestViewModel public class MusicAlbumRequestViewModel
{ {
public string ForeignArtistId { get; set; } public string ForeignAlbumId { get; set; }
public ArtistRequestOption RequestOption { get; set; }
}
public enum ArtistRequestOption
{
AllAlbums = 0,
LatestAlbum = 1,
FirstAlbum = 2
} }
} }

View file

@ -14,7 +14,6 @@
<PackageReference Include="Hangfire" Version="1.6.19" /> <PackageReference Include="Hangfire" Version="1.6.19" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="2.1.1" /> <PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="2.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Design" Version="2.0.0-preview1-final" />
<PackageReference Include="MiniProfiler.AspNetCore" Version="4.0.0-alpha6-79" /> <PackageReference Include="MiniProfiler.AspNetCore" Version="4.0.0-alpha6-79" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="System.Diagnostics.Process" Version="4.3.0" /> <PackageReference Include="System.Diagnostics.Process" Version="4.3.0" />

View file

@ -29,6 +29,8 @@ namespace Ombi.Core.Rule.Rules.Request
obj.Approved = true; obj.Approved = true;
if (obj.RequestType == RequestType.TvShow && User.IsInRole(OmbiRoles.AutoApproveTv)) if (obj.RequestType == RequestType.TvShow && User.IsInRole(OmbiRoles.AutoApproveTv))
obj.Approved = true; obj.Approved = true;
if (obj.RequestType == RequestType.Album && User.IsInRole(OmbiRoles.AutoApproveMusic))
obj.Approved = true;
return Task.FromResult(Success()); // We don't really care, we just don't set the obj to approve return Task.FromResult(Success()); // We don't really care, we just don't set the obj to approve
} }
} }

View file

@ -23,13 +23,23 @@ namespace Ombi.Core.Rule.Rules
if (obj.RequestType == RequestType.Movie) if (obj.RequestType == RequestType.Movie)
{ {
if (User.IsInRole(OmbiRoles.RequestMovie)) if (User.IsInRole(OmbiRoles.RequestMovie) || User.IsInRole(OmbiRoles.AutoApproveMovie))
return Task.FromResult(Success()); return Task.FromResult(Success());
return Task.FromResult(Fail("You do not have permissions to Request a Movie")); return Task.FromResult(Fail("You do not have permissions to Request a Movie"));
} }
if (User.IsInRole(OmbiRoles.RequestTv)) if (obj.RequestType == RequestType.TvShow)
{
if (User.IsInRole(OmbiRoles.RequestTv) || User.IsInRole(OmbiRoles.AutoApproveTv))
return Task.FromResult(Success()); return Task.FromResult(Success());
}
if (obj.RequestType == RequestType.Album)
{
if (User.IsInRole(OmbiRoles.RequestMusic) || User.IsInRole(OmbiRoles.AutoApproveMusic))
return Task.FromResult(Success());
}
return Task.FromResult(Fail("You do not have permissions to Request a TV Show")); return Task.FromResult(Fail("You do not have permissions to Request a TV Show"));
} }
} }

View file

@ -54,6 +54,7 @@ namespace Ombi.Core.Rule.Rules.Request
var movieLimit = user.MovieRequestLimit; var movieLimit = user.MovieRequestLimit;
var episodeLimit = user.EpisodeRequestLimit; var episodeLimit = user.EpisodeRequestLimit;
var musicLimit = user.MusicRequestLimit;
var requestLog = _requestLog.GetAll().Where(x => x.UserId == obj.RequestedUserId); var requestLog = _requestLog.GetAll().Where(x => x.UserId == obj.RequestedUserId);
if (obj.RequestType == RequestType.Movie) if (obj.RequestType == RequestType.Movie)
@ -71,7 +72,7 @@ namespace Ombi.Core.Rule.Rules.Request
return Fail("You have exceeded your Movie request quota!"); return Fail("You have exceeded your Movie request quota!");
} }
} }
else else if (obj.RequestType == RequestType.TvShow)
{ {
if (episodeLimit <= 0) if (episodeLimit <= 0)
return Success(); return Success();
@ -94,6 +95,20 @@ namespace Ombi.Core.Rule.Rules.Request
{ {
return Fail("You have exceeded your Episode request quota!"); return Fail("You have exceeded your Episode request quota!");
} }
} else if (obj.RequestType == RequestType.Album)
{
if (musicLimit <= 0)
return Success();
var albumLogs = requestLog.Where(x => x.RequestType == RequestType.Album);
// Count how many requests in the past 7 days
var count = await albumLogs.CountAsync(x => x.RequestDate >= DateTime.UtcNow.AddDays(-7));
count += 1; // Since we are including this request
if (count > musicLimit)
{
return Fail("You have exceeded your Album request quota!");
}
} }
return Success(); return Success();
} }

View file

@ -20,11 +20,11 @@ namespace Ombi.Core.Rule.Rules.Search
private IMovieRequestRepository Movie { get; } private IMovieRequestRepository Movie { get; }
private ITvRequestRepository Tv { get; } private ITvRequestRepository Tv { get; }
public Task<RuleResult> Execute(SearchViewModel obj) public async Task<RuleResult> Execute(SearchViewModel obj)
{ {
if (obj.Type == RequestType.Movie) if (obj.Type == RequestType.Movie)
{ {
var movieRequests = Movie.GetRequest(obj.Id); var movieRequests = await Movie.GetRequestAsync(obj.Id);
if (movieRequests != null) // Do we already have a request for this? if (movieRequests != null) // Do we already have a request for this?
{ {
@ -33,11 +33,11 @@ namespace Ombi.Core.Rule.Rules.Search
obj.Approved = movieRequests.Approved; obj.Approved = movieRequests.Approved;
obj.Available = movieRequests.Available; obj.Available = movieRequests.Available;
return Task.FromResult(Success()); return Success();
} }
return Task.FromResult(Success()); return Success();
} }
else else if (obj.Type == RequestType.Album)
{ {
//var tvRequests = Tv.GetRequest(obj.Id); //var tvRequests = Tv.GetRequest(obj.Id);
//if (tvRequests != null) // Do we already have a request for this? //if (tvRequests != null) // Do we already have a request for this?
@ -94,8 +94,9 @@ namespace Ombi.Core.Rule.Rules.Search
request.PartlyAvailable = true; request.PartlyAvailable = true;
} }
return Task.FromResult(Success()); return Success();
} }
return Success();
} }
} }
} }

View file

@ -42,6 +42,13 @@ namespace Ombi.Core.Rule.Rules.Specific
sendNotification = !await UserManager.IsInRoleAsync(requestedUser, OmbiRoles.AutoApproveTv); sendNotification = !await UserManager.IsInRoleAsync(requestedUser, OmbiRoles.AutoApproveTv);
} }
} }
else if (req.RequestType == RequestType.Album)
{
if (settings.DoNotSendNotificationsForAutoApprove)
{
sendNotification = !await UserManager.IsInRoleAsync(requestedUser, OmbiRoles.AutoApproveMusic);
}
}
if (await UserManager.IsInRoleAsync(requestedUser, OmbiRoles.Admin)) if (await UserManager.IsInRoleAsync(requestedUser, OmbiRoles.Admin))
{ {

View file

@ -8,7 +8,9 @@ namespace Ombi.Core
{ {
void NewRequest(FullBaseRequest model); void NewRequest(FullBaseRequest model);
void NewRequest(ChildRequests model); void NewRequest(ChildRequests model);
void NewRequest(AlbumRequest model);
void Notify(MovieRequests model, NotificationType type); void Notify(MovieRequests model, NotificationType type);
void Notify(ChildRequests model, NotificationType type); void Notify(ChildRequests model, NotificationType type);
void Notify(AlbumRequest model, NotificationType type);
} }
} }

View file

@ -84,6 +84,7 @@ namespace Ombi.DependencyInjection
services.AddTransient<IMovieSender, MovieSender>(); services.AddTransient<IMovieSender, MovieSender>();
services.AddTransient<IRecentlyAddedEngine, RecentlyAddedEngine>(); services.AddTransient<IRecentlyAddedEngine, RecentlyAddedEngine>();
services.AddTransient<IMusicSearchEngine, MusicSearchEngine>(); services.AddTransient<IMusicSearchEngine, MusicSearchEngine>();
services.AddTransient<IMusicRequestEngine, MusicRequestEngine>();
services.AddTransient<ITvSender, TvSender>(); services.AddTransient<ITvSender, TvSender>();
services.AddTransient<IMassEmailSender, MassEmailSender>(); services.AddTransient<IMassEmailSender, MassEmailSender>();
services.AddTransient<IPlexOAuthManager, PlexOAuthManager>(); services.AddTransient<IPlexOAuthManager, PlexOAuthManager>();
@ -134,6 +135,7 @@ namespace Ombi.DependencyInjection
services.AddTransient<ITvRequestRepository, TvRequestRepository>(); services.AddTransient<ITvRequestRepository, TvRequestRepository>();
services.AddTransient<IMovieRequestRepository, MovieRequestRepository>(); services.AddTransient<IMovieRequestRepository, MovieRequestRepository>();
services.AddTransient<IMusicRequestRepository, MusicRequestRepository>();
services.AddTransient<IAuditRepository, AuditRepository>(); services.AddTransient<IAuditRepository, AuditRepository>();
services.AddTransient<IApplicationConfigRepository, ApplicationConfigRepository>(); services.AddTransient<IApplicationConfigRepository, ApplicationConfigRepository>();
services.AddTransient<ITokenRepository, TokenRepository>(); services.AddTransient<ITokenRepository, TokenRepository>();

View file

@ -7,9 +7,11 @@
public const string Admin = nameof(Admin); public const string Admin = nameof(Admin);
public const string AutoApproveMovie = nameof(AutoApproveMovie); public const string AutoApproveMovie = nameof(AutoApproveMovie);
public const string AutoApproveTv = nameof(AutoApproveTv); public const string AutoApproveTv = nameof(AutoApproveTv);
public const string AutoApproveMusic = nameof(AutoApproveMusic);
public const string PowerUser = nameof(PowerUser); public const string PowerUser = nameof(PowerUser);
public const string RequestTv = nameof(RequestTv); public const string RequestTv = nameof(RequestTv);
public const string RequestMovie = nameof(RequestMovie); public const string RequestMovie = nameof(RequestMovie);
public const string RequestMusic = nameof(RequestMusic);
public const string Disabled = nameof(Disabled); public const string Disabled = nameof(Disabled);
public const string ReceivesNewsletter = nameof(ReceivesNewsletter); public const string ReceivesNewsletter = nameof(ReceivesNewsletter);
} }

View file

@ -28,6 +28,7 @@ namespace Ombi.Store.Context
void Seed(); void Seed();
DbSet<Audit> Audit { get; set; } DbSet<Audit> Audit { get; set; }
DbSet<MovieRequests> MovieRequests { get; set; } DbSet<MovieRequests> MovieRequests { get; set; }
DbSet<AlbumRequest> AlbumRequests { get; set; }
DbSet<TvRequests> TvRequests { get; set; } DbSet<TvRequests> TvRequests { get; set; }
DbSet<ChildRequests> ChildRequests { get; set; } DbSet<ChildRequests> ChildRequests { get; set; }
DbSet<Issues> Issues { get; set; } DbSet<Issues> Issues { get; set; }

View file

@ -31,6 +31,7 @@ namespace Ombi.Store.Context
public DbSet<EmbyEpisode> EmbyEpisode { get; set; } public DbSet<EmbyEpisode> EmbyEpisode { get; set; }
public DbSet<MovieRequests> MovieRequests { get; set; } public DbSet<MovieRequests> MovieRequests { get; set; }
public DbSet<AlbumRequest> AlbumRequests { get; set; }
public DbSet<TvRequests> TvRequests { get; set; } public DbSet<TvRequests> TvRequests { get; set; }
public DbSet<ChildRequests> ChildRequests { get; set; } public DbSet<ChildRequests> ChildRequests { get; set; }

View file

@ -23,6 +23,7 @@ namespace Ombi.Store.Entities
public int? MovieRequestLimit { get; set; } public int? MovieRequestLimit { get; set; }
public int? EpisodeRequestLimit { get; set; } public int? EpisodeRequestLimit { get; set; }
public int? MusicRequestLimit { get; set; }
public string UserAccessToken { get; set; } public string UserAccessToken { get; set; }
@ -59,5 +60,6 @@ namespace Ombi.Store.Entities
get => base.ConcurrencyStamp; get => base.ConcurrencyStamp;
set => base.ConcurrencyStamp = value; set => base.ConcurrencyStamp = value;
} }
} }
} }

View file

@ -7,6 +7,7 @@ namespace Ombi.Store.Entities
public enum RequestType public enum RequestType
{ {
TvShow = 0, TvShow = 0,
Movie = 1 Movie = 1,
Album = 2,
} }
} }

View file

@ -0,0 +1,21 @@
using System;
using System.ComponentModel.DataAnnotations.Schema;
namespace Ombi.Store.Entities.Requests
{
[Table("AlbumRequests")]
public class AlbumRequest : BaseRequest
{
public string ForeignAlbumId { get; set; }
public string ForeignArtistId { get; set; }
public string Disk { get; set; }
public string Cover { get; set; }
public decimal Rating { get; set; }
public DateTime ReleaseDate { get; set; }
public string ArtistName { get; set; }
[NotMapped]
public bool Subscribed { get; set; }
[NotMapped]
public bool ShowSubscribe { get; set; }
}
}

View file

@ -0,0 +1,17 @@
using System.Linq;
using System.Threading.Tasks;
using Ombi.Store.Entities.Requests;
namespace Ombi.Store.Repository.Requests
{
public interface IMusicRequestRepository : IRepository<AlbumRequest>
{
IQueryable<AlbumRequest> GetAll(string userId);
AlbumRequest GetRequest(string foreignAlbumId);
Task<AlbumRequest> GetRequestAsync(string foreignAlbumId);
IQueryable<AlbumRequest> GetWithUser();
IQueryable<AlbumRequest> GetWithUser(string userId);
Task Save();
Task Update(AlbumRequest request);
}
}

View file

@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Ombi.Store.Context;
using Ombi.Store.Entities.Requests;
namespace Ombi.Store.Repository.Requests
{
public class MusicRequestRepository : Repository<AlbumRequest>, IMusicRequestRepository
{
public MusicRequestRepository(IOmbiContext ctx) : base(ctx)
{
Db = ctx;
}
private IOmbiContext Db { get; }
public Task<AlbumRequest> GetRequestAsync(string foreignAlbumId)
{
return Db.AlbumRequests.Where(x => x.ForeignAlbumId == foreignAlbumId)
.Include(x => x.RequestedUser)
.FirstOrDefaultAsync();
}
public IQueryable<AlbumRequest> GetAll(string userId)
{
return GetWithUser().Where(x => x.RequestedUserId == userId);
}
public AlbumRequest GetRequest(string foreignAlbumId)
{
return Db.AlbumRequests.Where(x => x.ForeignAlbumId == foreignAlbumId)
.Include(x => x.RequestedUser)
.FirstOrDefault();
}
public IQueryable<AlbumRequest> GetWithUser()
{
return Db.AlbumRequests
.Include(x => x.RequestedUser)
.ThenInclude(x => x.NotificationUserIds)
.AsQueryable();
}
public IQueryable<AlbumRequest> GetWithUser(string userId)
{
return Db.AlbumRequests
.Where(x => x.RequestedUserId == userId)
.Include(x => x.RequestedUser)
.ThenInclude(x => x.NotificationUserIds)
.AsQueryable();
}
public async Task Update(AlbumRequest request)
{
if (Db.Entry(request).State == EntityState.Detached)
{
Db.AlbumRequests.Attach(request);
Db.Update(request);
}
await Db.SaveChangesAsync();
}
public async Task Save()
{
await Db.SaveChangesAsync();
}
}
}

View file

@ -1,4 +1,4 @@
<div> <div class="row">
<!--Backdrop--> <!--Backdrop-->
<div class="album-bg backdrop" [style.background-image]="result.background"></div> <div class="album-bg backdrop" [style.background-image]="result.background"></div>
<div class="album-tint" style="background-image: linear-gradient(to bottom, rgba(0,0,0,0.6) 0%,rgba(0,0,0,0.6) 100%);"></div> <div class="album-tint" style="background-image: linear-gradient(to bottom, rgba(0,0,0,0.6) 0%,rgba(0,0,0,0.6) 100%);"></div>
@ -12,14 +12,16 @@
<div class="col-sm-12 small-padding"> <div class="col-sm-12 small-padding">
<div> <div>
<h4> <h4>
<a href="" (click)="selectArtist($event, result.foreignArtistId)">
{{result.artistName}}
</a>
-
<a href="" target="_blank"> <a href="" target="_blank">
{{result.title}} {{result.title}}
</a> </a>
</h4> </h4>
<h5>
<a href="" (click)="selectArtist($event, result.foreignArtistId)">
{{result.artistName}}
</a>
</h5>
</div> </div>
<!--Tags--> <!--Tags-->
@ -82,7 +84,8 @@
<button style="text-align: right" class="btn btn-primary-outline" (click)="request(result)"> <button style="text-align: right" class="btn btn-primary-outline" (click)="request(result)">
<i *ngIf="result.requestProcessing" class="fa fa-circle-o-notch fa-spin fa-fw"></i> <i *ngIf="result.requestProcessing" class="fa fa-circle-o-notch fa-spin fa-fw"></i>
<i *ngIf="!result.requestProcessing && !result.processed" class="fa fa-plus"></i> <i *ngIf="!result.requestProcessing && !result.processed" class="fa fa-plus"></i>
<i *ngIf="result.processed && !result.requestProcessing" class="fa fa-check"></i> {{ 'Common.Request' | translate }}</button> <i *ngIf="result.processed && !result.requestProcessing" class="fa fa-check"></i> {{ 'Common.Request'
| translate }}</button>
</ng-template> </ng-template>
</div> </div>
<!-- <button style="text-align: right" class="btn btn-sm btn-info-outline" (click)="similarMovies(result.id)"> <i class="fa fa-eye"></i> {{ 'Search.Similar' | translate }}</button> --> <!-- <button style="text-align: right" class="btn btn-sm btn-info-outline" (click)="similarMovies(result.id)"> <i class="fa fa-eye"></i> {{ 'Search.Similar' | translate }}</button> -->

View file

@ -22,7 +22,7 @@ export class MusicSearchComponent implements OnInit {
public albumResult: ISearchAlbumResult[]; public albumResult: ISearchAlbumResult[];
public result: IRequestEngineResult; public result: IRequestEngineResult;
public searchApplied = false; public searchApplied = false;
public searchAlbum: boolean = true; public searchAlbum: boolean = false;
@Input() public issueCategories: IIssueCategory[]; @Input() public issueCategories: IIssueCategory[];
@Input() public issuesEnabled: boolean; @Input() public issuesEnabled: boolean;
@ -72,10 +72,10 @@ export class MusicSearchComponent implements OnInit {
}); });
} }
}); });
this.defaultPoster = "../../../images/default_movie_poster.png"; this.defaultPoster = "../../../images/default-music-placeholder.png";
const base = this.platformLocation.getBaseHrefFromDOM(); const base = this.platformLocation.getBaseHrefFromDOM();
if (base) { if (base) {
this.defaultPoster = "../../.." + base + "/images/default_movie_poster.png"; this.defaultPoster = "../../.." + base + "/images/default-music-placeholder.png";
} }
} }

View file

@ -22,11 +22,11 @@
<div class="tab-content"> <div class="tab-content">
<div [hidden]="!showMovie"> <div [hidden]="!showMovie">
<!-- <movie-search [issueCategories]="issueCategories" [issuesEnabled]="issuesEnabled"></movie-search> --> <movie-search [issueCategories]="issueCategories" [issuesEnabled]="issuesEnabled"></movie-search>
</div> </div>
<div [hidden]="!showTv"> <div [hidden]="!showTv">
<!-- <tv-search [issueCategories]="issueCategories" [issuesEnabled]="issuesEnabled"></tv-search> --> <tv-search [issueCategories]="issueCategories" [issuesEnabled]="issuesEnabled"></tv-search>
</div> </div>
<div [hidden]="!showMusic"> <div [hidden]="!showMusic">
<music-search></music-search> <music-search></music-search>

View file

@ -21,9 +21,9 @@ export class SearchComponent implements OnInit {
public ngOnInit() { public ngOnInit() {
this.settingsService.getLidarr().subscribe(x => this.musicEnabled = x.enabled); this.settingsService.getLidarr().subscribe(x => this.musicEnabled = x.enabled);
this.showMovie = false; this.showMovie = true;
this.showTv = false; this.showTv = false;
this.showMusic = true; this.showMusic = false;
this.issuesService.getCategories().subscribe(x => this.issueCategories = x); this.issuesService.getCategories().subscribe(x => this.issueCategories = x);
this.settingsService.getIssueSettings().subscribe(x => this.issuesEnabled = x.enabled); this.settingsService.getIssueSettings().subscribe(x => this.issuesEnabled = x.enabled);
} }

View file

@ -0,0 +1,144 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Ombi.Core.Engine;
using Ombi.Core.Models.Requests;
using System.Collections.Generic;
using System.Threading.Tasks;
using Ombi.Store.Entities.Requests;
using Ombi.Attributes;
using Ombi.Core.Models.UI;
namespace Ombi.Controllers
{
[Authorize]
[Route("api/v1/request/music")]
[Produces("application/json")]
public class MusicRequestController : Controller
{
public MusicRequestController(IMusicRequestEngine engine)
{
_engine = engine;
}
private readonly IMusicRequestEngine _engine;
/// <summary>
/// Gets album requests.
/// </summary>
/// <param name="count">The count of items you want to return.</param>
/// <param name="position">The position.</param>
/// <param name="orderType"> The way we want to order.</param>
/// <param name="statusType"></param>
/// <param name="availabilityType"></param>
[HttpGet("{count:int}/{position:int}/{orderType:int}/{statusType:int}/{availabilityType:int}")]
public async Task<RequestsViewModel<AlbumRequest>> GetRequests(int count, int position, int orderType, int statusType, int availabilityType)
{
return await _engine.GetRequests(count, position, new OrderFilterModel
{
OrderType = (OrderType)orderType,
AvailabilityFilter = (FilterType)availabilityType,
StatusFilter = (FilterType)statusType,
});
}
/// <summary>
/// Gets the total amount of album requests.
/// </summary>
[HttpGet("total")]
public async Task<int> GetTotalAlbums()
{
return await _engine.GetTotal();
}
/// <summary>
/// Gets all album requests.
/// </summary>
[HttpGet]
public async Task<IEnumerable<AlbumRequest>> GetRequests()
{
return await _engine.GetRequests();
}
/// <summary>
/// Requests a album.
/// </summary>
/// <param name="album">The album.</param>
/// <returns></returns>
[HttpPost]
public async Task<RequestEngineResult> Request([FromBody] MusicAlbumRequestViewModel album)
{
return await _engine.RequestAlbum(album);
}
/// <summary>
/// Searches for a specific album request
/// </summary>
/// <param name="searchTerm">The search term.</param>
/// <returns></returns>
[HttpGet("search/{searchTerm}")]
public async Task<IEnumerable<AlbumRequest>> Search(string searchTerm)
{
return await _engine.SearchAlbumRequest(searchTerm);
}
/// <summary>
/// Deletes the specified album request.
/// </summary>
/// <param name="requestId">The request identifier.</param>
/// <returns></returns>
[HttpDelete("{requestId:int}")]
[PowerUser]
public async Task DeleteRequest(int requestId)
{
await _engine.RemoveAlbumRequest(requestId);
}
/// <summary>
/// Approves the specified album request.
/// </summary>
/// <param name="model">The albums's ID</param>
/// <returns></returns>
[HttpPost("approve")]
[PowerUser]
public async Task<RequestEngineResult> ApproveAlbum([FromBody] AlbumUpdateModel model)
{
return await _engine.ApproveAlbumById(model.Id);
}
/// <summary>
/// Set's the specified album as available
/// </summary>
/// <param name="model">The album's ID</param>
/// <returns></returns>
[HttpPost("available")]
[PowerUser]
public async Task<RequestEngineResult> MarkAvailable([FromBody] AlbumUpdateModel model)
{
return await _engine.MarkAvailable(model.Id);
}
/// <summary>
/// Set's the specified album as unavailable
/// </summary>
/// <param name="model">The album's ID</param>
/// <returns></returns>
[HttpPost("unavailable")]
[PowerUser]
public async Task<RequestEngineResult> MarkUnAvailable([FromBody] AlbumUpdateModel model)
{
return await _engine.MarkUnavailable(model.Id);
}
/// <summary>
/// Denies the specified album request.
/// </summary>
/// <param name="model">The album's ID</param>
/// <returns></returns>
[HttpPut("deny")]
[PowerUser]
public async Task<RequestEngineResult> Deny([FromBody] AlbumUpdateModel model)
{
return await _engine.DenyAlbumById(model.Id);
}
}
}

View file

@ -0,0 +1,33 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2017 Jamie Rees
// File: MovieUpdateModel.cs
// Created By: Jamie Rees
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ************************************************************************/
#endregion
namespace Ombi.Core.Models.Requests
{
public class AlbumUpdateModel
{
public int Id { get; set; }
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB