mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-11 07:46:05 -07:00
Finished #633 (First part of the queuing)
This commit is contained in:
parent
1c7fb2e93e
commit
2bd7ece9d0
10 changed files with 460 additions and 155 deletions
|
@ -34,6 +34,7 @@ namespace PlexRequests.Core.Models
|
|||
RequestApproved,
|
||||
AdminNote,
|
||||
Test,
|
||||
|
||||
RequestDeclined,
|
||||
ItemAddedToFaultQueue
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,10 @@
|
|||
<HintPath>..\packages\Common.Logging.Core.3.0.0\lib\net40\Common.Logging.Core.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Dapper, Version=1.50.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Dapper.1.50.0-beta8\lib\net45\Dapper.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Mono.Data.Sqlite">
|
||||
<HintPath>..\Assemblies\Mono.Data.Sqlite.dll</HintPath>
|
||||
</Reference>
|
||||
|
@ -105,6 +109,7 @@
|
|||
<Compile Include="Notification\Templates\IEmailBasicTemplate.cs" />
|
||||
<Compile Include="Notification\TransportType.cs" />
|
||||
<Compile Include="PlexReadOnlyDatabase.cs" />
|
||||
<Compile Include="Queue\ITransientFaultQueue.cs" />
|
||||
<Compile Include="Queue\TransientFaultQueue.cs" />
|
||||
<Compile Include="SettingModels\AuthenticationSettings.cs" />
|
||||
<Compile Include="SettingModels\ExternalSettings.cs" />
|
||||
|
|
17
PlexRequests.Core/Queue/ITransientFaultQueue.cs
Normal file
17
PlexRequests.Core/Queue/ITransientFaultQueue.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using PlexRequests.Store;
|
||||
using PlexRequests.Store.Models;
|
||||
|
||||
namespace PlexRequests.Core.Queue
|
||||
{
|
||||
public interface ITransientFaultQueue
|
||||
{
|
||||
void Dequeue();
|
||||
Task DequeueAsync();
|
||||
IEnumerable<RequestQueue> GetQueue();
|
||||
Task<IEnumerable<RequestQueue>> GetQueueAsync();
|
||||
void QueueItem(RequestedModel request, RequestType type, FaultType faultType);
|
||||
Task QueueItemAsync(RequestedModel request, RequestType type, FaultType faultType);
|
||||
}
|
||||
}
|
|
@ -26,7 +26,9 @@
|
|||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Dapper;
|
||||
using PlexRequests.Helpers;
|
||||
using PlexRequests.Store;
|
||||
using PlexRequests.Store.Models;
|
||||
|
@ -34,7 +36,7 @@ using PlexRequests.Store.Repository;
|
|||
|
||||
namespace PlexRequests.Core.Queue
|
||||
{
|
||||
public class TransientFaultQueue
|
||||
public class TransientFaultQueue : ITransientFaultQueue
|
||||
{
|
||||
public TransientFaultQueue(IRepository<RequestQueue> queue)
|
||||
{
|
||||
|
@ -44,44 +46,84 @@ namespace PlexRequests.Core.Queue
|
|||
private IRepository<RequestQueue> RequestQueue { get; }
|
||||
|
||||
|
||||
public void QueueItem(RequestedModel request, RequestType type)
|
||||
public void QueueItem(RequestedModel request, RequestType type, FaultType faultType)
|
||||
{
|
||||
//Ensure there is not a duplicate queued item
|
||||
var existingItem = RequestQueue.Custom(
|
||||
connection =>
|
||||
{
|
||||
connection.Open();
|
||||
var result = connection.Query<RequestQueue>("select * from RequestQueue where PrimaryIdentifier = @ProviderId", new { ProviderId = request.ProviderId });
|
||||
|
||||
return result;
|
||||
}).FirstOrDefault();
|
||||
|
||||
if (existingItem != null)
|
||||
{
|
||||
// It's already in the queue
|
||||
return;
|
||||
}
|
||||
|
||||
var queue = new RequestQueue
|
||||
{
|
||||
Type = type,
|
||||
Content = ByteConverterHelper.ReturnBytes(request),
|
||||
PrimaryIdentifier = request.ProviderId
|
||||
PrimaryIdentifier = request.ProviderId,
|
||||
FaultType = faultType
|
||||
};
|
||||
RequestQueue.Insert(queue);
|
||||
}
|
||||
|
||||
public async Task QueueItemAsync(RequestedModel request, RequestType type)
|
||||
public async Task QueueItemAsync(RequestedModel request, RequestType type, FaultType faultType)
|
||||
{
|
||||
//Ensure there is not a duplicate queued item
|
||||
var existingItem = await RequestQueue.CustomAsync(async connection =>
|
||||
{
|
||||
connection.Open();
|
||||
var result = await connection.QueryAsync<RequestQueue>("select * from RequestQueue where PrimaryIdentifier = @ProviderId", new { ProviderId = request.ProviderId });
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
if (existingItem.FirstOrDefault() != null)
|
||||
{
|
||||
// It's already in the queue
|
||||
return;
|
||||
}
|
||||
|
||||
var queue = new RequestQueue
|
||||
{
|
||||
Type = type,
|
||||
Content = ByteConverterHelper.ReturnBytes(request),
|
||||
PrimaryIdentifier = request.ProviderId
|
||||
PrimaryIdentifier = request.ProviderId,
|
||||
FaultType = faultType
|
||||
};
|
||||
await RequestQueue.InsertAsync(queue);
|
||||
}
|
||||
|
||||
public IEnumerable<RequestQueue> Dequeue()
|
||||
public IEnumerable<RequestQueue> GetQueue()
|
||||
{
|
||||
var items = RequestQueue.GetAll();
|
||||
|
||||
RequestQueue.DeleteAll("RequestQueue");
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RequestQueue>> DequeueAsync()
|
||||
public async Task<IEnumerable<RequestQueue>> GetQueueAsync()
|
||||
{
|
||||
var items = RequestQueue.GetAllAsync();
|
||||
|
||||
await RequestQueue.DeleteAllAsync("RequestQueue");
|
||||
|
||||
|
||||
return await items;
|
||||
}
|
||||
|
||||
public void Dequeue()
|
||||
{
|
||||
RequestQueue.DeleteAll("RequestQueue");
|
||||
}
|
||||
|
||||
public async Task DequeueAsync()
|
||||
{
|
||||
await RequestQueue.DeleteAllAsync("RequestQueue");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
<packages>
|
||||
<package id="Common.Logging" version="3.0.0" targetFramework="net45" />
|
||||
<package id="Common.Logging.Core" version="3.0.0" targetFramework="net45" />
|
||||
<package id="Dapper" version="1.50.0-beta8" targetFramework="net45" />
|
||||
<package id="Nancy" version="1.4.3" targetFramework="net45" />
|
||||
<package id="Nancy.Authentication.Forms" version="1.4.1" targetFramework="net45" />
|
||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
|
||||
|
|
|
@ -87,6 +87,14 @@ namespace PlexRequests.Services.Notification
|
|||
case NotificationType.Test:
|
||||
await EmailTest(model, emailSettings);
|
||||
break;
|
||||
case NotificationType.RequestDeclined:
|
||||
throw new NotImplementedException();
|
||||
|
||||
case NotificationType.ItemAddedToFaultQueue:
|
||||
await EmailAddedToRequestQueue(model, emailSettings);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -129,7 +137,7 @@ namespace PlexRequests.Services.Notification
|
|||
$"Plex Requests: New {model.RequestType.GetString()?.ToLower()} request for {model.Title}!",
|
||||
$"Hello! The user '{model.User}' has requested the {model.RequestType.GetString()?.ToLower()} '{model.Title}'! Please log in to approve this request. Request Date: {model.DateTime.ToString("f")}",
|
||||
model.ImgSrc);
|
||||
var body = new BodyBuilder { HtmlBody = html, TextBody = "This email is only available on devices that support HTML." };
|
||||
var body = new BodyBuilder { HtmlBody = html, TextBody = $"Hello! The user '{model.User}' has requested the {model.RequestType.GetString()?.ToLower()} '{model.Title}'! Please log in to approve this request. Request Date: {model.DateTime.ToString("f")}" };
|
||||
|
||||
var message = new MimeMessage
|
||||
{
|
||||
|
@ -150,7 +158,7 @@ namespace PlexRequests.Services.Notification
|
|||
$"Plex Requests: New issue for {model.Title}!",
|
||||
$"Hello! The user '{model.User}' has reported a new issue {model.Body} for the title {model.Title}!",
|
||||
model.ImgSrc);
|
||||
var body = new BodyBuilder { HtmlBody = html, TextBody = "This email is only available on devices that support HTML." };
|
||||
var body = new BodyBuilder { HtmlBody = html, TextBody = $"Hello! The user '{model.User}' has reported a new issue {model.Body} for the title {model.Title}!"};
|
||||
|
||||
var message = new MimeMessage
|
||||
{
|
||||
|
@ -164,6 +172,27 @@ namespace PlexRequests.Services.Notification
|
|||
await Send(message, settings);
|
||||
}
|
||||
|
||||
private async Task EmailAddedToRequestQueue(NotificationModel model, EmailNotificationSettings settings)
|
||||
{
|
||||
var email = new EmailBasicTemplate();
|
||||
var html = email.LoadTemplate(
|
||||
"Plex Requests: A request could not be added.",
|
||||
$"Hello! The user '{model.User}' has requested {model.Title} but it could not be added. This has been added into the requests queue and will keep retrying",
|
||||
model.ImgSrc);
|
||||
var body = new BodyBuilder { HtmlBody = html, TextBody = $"Hello! The user '{model.User}' has requested {model.Title} but it could not be added. This has been added into the requests queue and will keep retrying" };
|
||||
|
||||
var message = new MimeMessage
|
||||
{
|
||||
Body = body.ToMessageBody(),
|
||||
Subject = $"Plex Requests: A request could not be added"
|
||||
};
|
||||
message.From.Add(new MailboxAddress(settings.EmailSender, settings.EmailSender));
|
||||
message.To.Add(new MailboxAddress(settings.RecipientEmail, settings.RecipientEmail));
|
||||
|
||||
|
||||
await Send(message, settings);
|
||||
}
|
||||
|
||||
private async Task EmailAvailableRequest(NotificationModel model, EmailNotificationSettings settings)
|
||||
{
|
||||
if (!settings.EnableUserEmailNotifications)
|
||||
|
@ -175,7 +204,7 @@ namespace PlexRequests.Services.Notification
|
|||
$"Plex Requests: {model.Title} is now available!",
|
||||
$"Hello! You requested {model.Title} on PlexRequests! This is now available on Plex! :)",
|
||||
model.ImgSrc);
|
||||
var body = new BodyBuilder { HtmlBody = html, TextBody = "This email is only available on devices that support HTML." };
|
||||
var body = new BodyBuilder { HtmlBody = html, TextBody = $"Hello! You requested {model.Title} on PlexRequests! This is now available on Plex! :)" };
|
||||
|
||||
var message = new MimeMessage
|
||||
{
|
||||
|
|
|
@ -38,5 +38,12 @@ namespace PlexRequests.Store.Models
|
|||
|
||||
public byte[] Content { get; set; }
|
||||
|
||||
public FaultType FaultType { get; set; }
|
||||
}
|
||||
|
||||
public enum FaultType
|
||||
{
|
||||
RequestFault,
|
||||
MissingInformation
|
||||
}
|
||||
}
|
|
@ -138,6 +138,7 @@ CREATE TABLE IF NOT EXISTS RequestQueue
|
|||
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
PrimaryIdentifier INTEGER NOT NULL,
|
||||
Type INTEGER NOT NULL,
|
||||
FaultType INTEGER NOT NULL,
|
||||
Content BLOB NOT NULL
|
||||
);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS PlexUsers_Id ON PlexUsers (Id);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#region Copyright
|
||||
|
||||
// /************************************************************************
|
||||
// Copyright (c) 2016 Jamie Rees
|
||||
// File: SearchModule.cs
|
||||
|
@ -23,7 +24,9 @@
|
|||
// 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
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
|
@ -54,13 +57,13 @@ using Newtonsoft.Json;
|
|||
using PlexRequests.Api.Models.Sonarr;
|
||||
using PlexRequests.Api.Models.Tv;
|
||||
using PlexRequests.Core.Models;
|
||||
using PlexRequests.Core.Queue;
|
||||
using PlexRequests.Helpers.Analytics;
|
||||
using PlexRequests.Helpers.Permissions;
|
||||
using PlexRequests.Store.Models;
|
||||
using PlexRequests.Store.Repository;
|
||||
|
||||
using TMDbLib.Objects.General;
|
||||
using TMDbLib.Objects.Search;
|
||||
|
||||
using Action = PlexRequests.Helpers.Analytics.Action;
|
||||
using EpisodesModel = PlexRequests.Store.EpisodesModel;
|
||||
|
@ -73,10 +76,13 @@ namespace PlexRequests.UI.Modules
|
|||
ISettingsService<PlexRequestSettings> prSettings, IAvailabilityChecker checker,
|
||||
IRequestService request, ISonarrApi sonarrApi, ISettingsService<SonarrSettings> sonarrSettings,
|
||||
ISettingsService<SickRageSettings> sickRageService, ICouchPotatoApi cpApi, ISickRageApi srApi,
|
||||
INotificationService notify, IMusicBrainzApi mbApi, IHeadphonesApi hpApi, ISettingsService<HeadphonesSettings> hpService,
|
||||
INotificationService notify, IMusicBrainzApi mbApi, IHeadphonesApi hpApi,
|
||||
ISettingsService<HeadphonesSettings> hpService,
|
||||
ICouchPotatoCacher cpCacher, ISonarrCacher sonarrCacher, ISickRageCacher sickRageCacher, IPlexApi plexApi,
|
||||
ISettingsService<PlexSettings> plexService, ISettingsService<AuthenticationSettings> auth, IRepository<UsersToNotify> u, ISettingsService<EmailNotificationSettings> email,
|
||||
IIssueService issue, IAnalytics a, IRepository<RequestLimit> rl) : base("search", prSettings)
|
||||
ISettingsService<PlexSettings> plexService, ISettingsService<AuthenticationSettings> auth,
|
||||
IRepository<UsersToNotify> u, ISettingsService<EmailNotificationSettings> email,
|
||||
IIssueService issue, IAnalytics a, IRepository<RequestLimit> rl, ITransientFaultQueue tfQueue)
|
||||
: base("search", prSettings)
|
||||
{
|
||||
Auth = auth;
|
||||
PlexService = plexService;
|
||||
|
@ -104,6 +110,7 @@ namespace PlexRequests.UI.Modules
|
|||
IssueService = issue;
|
||||
Analytics = a;
|
||||
RequestLimitRepo = rl;
|
||||
FaultQueue = tfQueue;
|
||||
TvApi = new TvMazeApi();
|
||||
|
||||
|
||||
|
@ -118,7 +125,8 @@ namespace PlexRequests.UI.Modules
|
|||
Get["movie/playing", true] = async (x, ct) => await CurrentlyPlayingMovies();
|
||||
|
||||
Post["request/movie", true] = async (x, ct) => await RequestMovie((int)Request.Form.movieId);
|
||||
Post["request/tv", true] = async (x, ct) => await RequestTvShow((int)Request.Form.tvId, (string)Request.Form.seasons);
|
||||
Post["request/tv", true] =
|
||||
async (x, ct) => await RequestTvShow((int)Request.Form.tvId, (string)Request.Form.seasons);
|
||||
Post["request/tvEpisodes", true] = async (x, ct) => await RequestTvShow(0, "episode");
|
||||
Post["request/album", true] = async (x, ct) => await RequestAlbum((string)Request.Form.albumId);
|
||||
|
||||
|
@ -128,6 +136,7 @@ namespace PlexRequests.UI.Modules
|
|||
Get["/seasons"] = x => GetSeasons();
|
||||
Get["/episodes", true] = async (x, ct) => await GetEpisodes();
|
||||
}
|
||||
|
||||
private TvMazeApi TvApi { get; }
|
||||
private IPlexApi PlexApi { get; }
|
||||
private TheMovieDbApi MovieApi { get; }
|
||||
|
@ -154,6 +163,7 @@ namespace PlexRequests.UI.Modules
|
|||
private IRepository<UsersToNotify> UsersToNotifyRepo { get; }
|
||||
private IIssueService IssueService { get; }
|
||||
private IAnalytics Analytics { get; }
|
||||
private ITransientFaultQueue FaultQueue { get; }
|
||||
private IRepository<RequestLimit> RequestLimitRepo { get; }
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
|
@ -167,19 +177,22 @@ namespace PlexRequests.UI.Modules
|
|||
|
||||
private async Task<Response> UpcomingMovies()
|
||||
{
|
||||
Analytics.TrackEventAsync(Category.Search, Action.Movie, "Upcoming", Username, CookieHelper.GetAnalyticClientId(Cookies));
|
||||
Analytics.TrackEventAsync(Category.Search, Action.Movie, "Upcoming", Username,
|
||||
CookieHelper.GetAnalyticClientId(Cookies));
|
||||
return await ProcessMovies(MovieSearchType.Upcoming, string.Empty);
|
||||
}
|
||||
|
||||
private async Task<Response> CurrentlyPlayingMovies()
|
||||
{
|
||||
Analytics.TrackEventAsync(Category.Search, Action.Movie, "CurrentlyPlaying", Username, CookieHelper.GetAnalyticClientId(Cookies));
|
||||
Analytics.TrackEventAsync(Category.Search, Action.Movie, "CurrentlyPlaying", Username,
|
||||
CookieHelper.GetAnalyticClientId(Cookies));
|
||||
return await ProcessMovies(MovieSearchType.CurrentlyPlaying, string.Empty);
|
||||
}
|
||||
|
||||
private async Task<Response> SearchMovie(string searchTerm)
|
||||
{
|
||||
Analytics.TrackEventAsync(Category.Search, Action.Movie, searchTerm, Username, CookieHelper.GetAnalyticClientId(Cookies));
|
||||
Analytics.TrackEventAsync(Category.Search, Action.Movie, searchTerm, Username,
|
||||
CookieHelper.GetAnalyticClientId(Cookies));
|
||||
return await ProcessMovies(MovieSearchType.Search, searchTerm);
|
||||
}
|
||||
|
||||
|
@ -192,24 +205,24 @@ namespace PlexRequests.UI.Modules
|
|||
case MovieSearchType.Search:
|
||||
var movies = await MovieApi.SearchMovie(searchTerm).ConfigureAwait(false);
|
||||
apiMovies = movies.Select(x =>
|
||||
new MovieResult
|
||||
{
|
||||
Adult = x.Adult,
|
||||
BackdropPath = x.BackdropPath,
|
||||
GenreIds = x.GenreIds,
|
||||
Id = x.Id,
|
||||
OriginalLanguage = x.OriginalLanguage,
|
||||
OriginalTitle = x.OriginalTitle,
|
||||
Overview = x.Overview,
|
||||
Popularity = x.Popularity,
|
||||
PosterPath = x.PosterPath,
|
||||
ReleaseDate = x.ReleaseDate,
|
||||
Title = x.Title,
|
||||
Video = x.Video,
|
||||
VoteAverage = x.VoteAverage,
|
||||
VoteCount = x.VoteCount
|
||||
})
|
||||
.ToList();
|
||||
new MovieResult
|
||||
{
|
||||
Adult = x.Adult,
|
||||
BackdropPath = x.BackdropPath,
|
||||
GenreIds = x.GenreIds,
|
||||
Id = x.Id,
|
||||
OriginalLanguage = x.OriginalLanguage,
|
||||
OriginalTitle = x.OriginalTitle,
|
||||
Overview = x.Overview,
|
||||
Popularity = x.Popularity,
|
||||
PosterPath = x.PosterPath,
|
||||
ReleaseDate = x.ReleaseDate,
|
||||
Title = x.Title,
|
||||
Video = x.Video,
|
||||
VoteAverage = x.VoteAverage,
|
||||
VoteCount = x.VoteCount
|
||||
})
|
||||
.ToList();
|
||||
break;
|
||||
case MovieSearchType.CurrentlyPlaying:
|
||||
apiMovies = await MovieApi.GetCurrentPlayingMovies();
|
||||
|
@ -239,8 +252,9 @@ namespace PlexRequests.UI.Modules
|
|||
var imdbId = string.Empty;
|
||||
if (counter <= 5) // Let's only do it for the first 5 items
|
||||
{
|
||||
var movieInfoTask = await MovieApi.GetMovieInformation(movie.Id).ConfigureAwait(false); // TODO needs to be careful about this, it's adding extra time to search...
|
||||
// https://www.themoviedb.org/talk/5807f4cdc3a36812160041f2
|
||||
var movieInfoTask = await MovieApi.GetMovieInformation(movie.Id).ConfigureAwait(false);
|
||||
// TODO needs to be careful about this, it's adding extra time to search...
|
||||
// https://www.themoviedb.org/talk/5807f4cdc3a36812160041f2
|
||||
imdbId = movieInfoTask.ImdbId;
|
||||
counter++;
|
||||
}
|
||||
|
@ -263,7 +277,8 @@ namespace PlexRequests.UI.Modules
|
|||
VoteCount = movie.VoteCount
|
||||
};
|
||||
var canSee = CanUserSeeThisRequest(viewMovie.Id, settings.UsersCanViewOnlyOwnRequests, dbMovies);
|
||||
var plexMovie = Checker.GetMovie(plexMovies.ToArray(), movie.Title, movie.ReleaseDate?.Year.ToString(), imdbId);
|
||||
var plexMovie = Checker.GetMovie(plexMovies.ToArray(), movie.Title, movie.ReleaseDate?.Year.ToString(),
|
||||
imdbId);
|
||||
if (plexMovie != null)
|
||||
{
|
||||
viewMovie.Available = true;
|
||||
|
@ -288,7 +303,8 @@ namespace PlexRequests.UI.Modules
|
|||
return Response.AsJson(viewMovies);
|
||||
}
|
||||
|
||||
private bool CanUserSeeThisRequest(int movieId, bool usersCanViewOnlyOwnRequests, Dictionary<int, RequestedModel> moviesInDb)
|
||||
private bool CanUserSeeThisRequest(int movieId, bool usersCanViewOnlyOwnRequests,
|
||||
Dictionary<int, RequestedModel> moviesInDb)
|
||||
{
|
||||
if (usersCanViewOnlyOwnRequests)
|
||||
{
|
||||
|
@ -302,7 +318,8 @@ namespace PlexRequests.UI.Modules
|
|||
private async Task<Response> SearchTvShow(string searchTerm)
|
||||
{
|
||||
|
||||
Analytics.TrackEventAsync(Category.Search, Action.TvShow, searchTerm, Username, CookieHelper.GetAnalyticClientId(Cookies));
|
||||
Analytics.TrackEventAsync(Category.Search, Action.TvShow, searchTerm, Username,
|
||||
CookieHelper.GetAnalyticClientId(Cookies));
|
||||
var plexSettings = await PlexService.GetSettingsAsync();
|
||||
var prSettings = await PrService.GetSettingsAsync();
|
||||
var providerId = string.Empty;
|
||||
|
@ -360,7 +377,8 @@ namespace PlexRequests.UI.Modules
|
|||
providerId = viewT.Id.ToString();
|
||||
}
|
||||
|
||||
var plexShow = Checker.GetTvShow(plexTvShows.ToArray(), t.show.name, t.show.premiered?.Substring(0, 4), providerId);
|
||||
var plexShow = Checker.GetTvShow(plexTvShows.ToArray(), t.show.name, t.show.premiered?.Substring(0, 4),
|
||||
providerId);
|
||||
if (plexShow != null)
|
||||
{
|
||||
viewT.Available = true;
|
||||
|
@ -377,7 +395,8 @@ namespace PlexRequests.UI.Modules
|
|||
viewT.Episodes = dbt.Episodes.ToList();
|
||||
viewT.Approved = dbt.Approved;
|
||||
}
|
||||
if (sonarrCached.Select(x => x.TvdbId).Contains(tvdbid) || sickRageCache.Contains(tvdbid)) // compare to the sonarr/sickrage db
|
||||
if (sonarrCached.Select(x => x.TvdbId).Contains(tvdbid) || sickRageCache.Contains(tvdbid))
|
||||
// compare to the sonarr/sickrage db
|
||||
{
|
||||
viewT.Requested = true;
|
||||
}
|
||||
|
@ -391,7 +410,8 @@ namespace PlexRequests.UI.Modules
|
|||
|
||||
private async Task<Response> SearchAlbum(string searchTerm)
|
||||
{
|
||||
Analytics.TrackEventAsync(Category.Search, Action.Album, searchTerm, Username, CookieHelper.GetAnalyticClientId(Cookies));
|
||||
Analytics.TrackEventAsync(Category.Search, Action.Album, searchTerm, Username,
|
||||
CookieHelper.GetAnalyticClientId(Cookies));
|
||||
var apiAlbums = new List<Release>();
|
||||
await Task.Run(() => MusicBrainzApi.SearchAlbum(searchTerm)).ContinueWith((t) =>
|
||||
{
|
||||
|
@ -448,7 +468,7 @@ namespace PlexRequests.UI.Modules
|
|||
if (Security.DoesNotHavePermissions(Permissions.ReadOnlyUser, User))
|
||||
{
|
||||
return
|
||||
Response.AsJson(new JsonResponseModel()
|
||||
Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = false,
|
||||
Message = "Sorry, you do not have the correct permissions to request a movie!"
|
||||
|
@ -457,12 +477,19 @@ namespace PlexRequests.UI.Modules
|
|||
var settings = await PrService.GetSettingsAsync();
|
||||
if (!await CheckRequestLimit(settings, RequestType.Movie))
|
||||
{
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = "You have reached your weekly request limit for Movies! Please contact your admin." });
|
||||
return
|
||||
Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = false,
|
||||
Message = "You have reached your weekly request limit for Movies! Please contact your admin."
|
||||
});
|
||||
}
|
||||
|
||||
Analytics.TrackEventAsync(Category.Search, Action.Request, "Movie", Username, CookieHelper.GetAnalyticClientId(Cookies));
|
||||
Analytics.TrackEventAsync(Category.Search, Action.Request, "Movie", Username,
|
||||
CookieHelper.GetAnalyticClientId(Cookies));
|
||||
var movieInfo = await MovieApi.GetMovieInformation(movieId);
|
||||
var fullMovieName = $"{movieInfo.Title}{(movieInfo.ReleaseDate.HasValue ? $" ({movieInfo.ReleaseDate.Value.Year})" : string.Empty)}";
|
||||
var fullMovieName =
|
||||
$"{movieInfo.Title}{(movieInfo.ReleaseDate.HasValue ? $" ({movieInfo.ReleaseDate.Value.Year})" : string.Empty)}";
|
||||
|
||||
var existingRequest = await RequestService.CheckRequestAsync(movieId);
|
||||
if (existingRequest != null)
|
||||
|
@ -474,7 +501,15 @@ namespace PlexRequests.UI.Modules
|
|||
await RequestService.UpdateRequestAsync(existingRequest);
|
||||
}
|
||||
|
||||
return Response.AsJson(new JsonResponseModel { Result = true, Message = settings.UsersCanViewOnlyOwnRequests ? $"{fullMovieName} {Resources.UI.Search_SuccessfullyAdded}" : $"{fullMovieName} {Resources.UI.Search_AlreadyRequested}" });
|
||||
return
|
||||
Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = true,
|
||||
Message =
|
||||
settings.UsersCanViewOnlyOwnRequests
|
||||
? $"{fullMovieName} {Resources.UI.Search_SuccessfullyAdded}"
|
||||
: $"{fullMovieName} {Resources.UI.Search_AlreadyRequested}"
|
||||
});
|
||||
}
|
||||
|
||||
try
|
||||
|
@ -482,13 +517,23 @@ namespace PlexRequests.UI.Modules
|
|||
var movies = Checker.GetPlexMovies();
|
||||
if (Checker.IsMovieAvailable(movies.ToArray(), movieInfo.Title, movieInfo.ReleaseDate?.Year.ToString()))
|
||||
{
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = $"{fullMovieName} is already in Plex!" });
|
||||
return
|
||||
Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = false,
|
||||
Message = $"{fullMovieName} is already in Plex!"
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e);
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = string.Format(Resources.UI.Search_CouldNotCheckPlex, fullMovieName) });
|
||||
return
|
||||
Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = false,
|
||||
Message = string.Format(Resources.UI.Search_CouldNotCheckPlex, fullMovieName)
|
||||
});
|
||||
}
|
||||
//#endif
|
||||
|
||||
|
@ -508,41 +553,58 @@ namespace PlexRequests.UI.Modules
|
|||
Issues = IssueState.None,
|
||||
|
||||
};
|
||||
|
||||
if (ShouldAutoApprove(RequestType.Movie, settings))
|
||||
{
|
||||
var cpSettings = await CpService.GetSettingsAsync();
|
||||
model.Approved = true;
|
||||
if (cpSettings.Enabled)
|
||||
{
|
||||
Log.Info("Adding movie to CP (No approval required)");
|
||||
var result = CouchPotatoApi.AddMovie(model.ImdbId, cpSettings.ApiKey, model.Title,
|
||||
cpSettings.FullUri, cpSettings.ProfileId);
|
||||
Log.Debug("Adding movie to CP result {0}", result);
|
||||
if (result)
|
||||
{
|
||||
return await AddRequest(model, settings, $"{fullMovieName} {Resources.UI.Search_SuccessfullyAdded}");
|
||||
}
|
||||
|
||||
return Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = false,
|
||||
Message = Resources.UI.Search_CouchPotatoError
|
||||
});
|
||||
}
|
||||
model.Approved = true;
|
||||
return await AddRequest(model, settings, $"{fullMovieName} {Resources.UI.Search_SuccessfullyAdded}");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (ShouldAutoApprove(RequestType.Movie, settings))
|
||||
{
|
||||
var cpSettings = await CpService.GetSettingsAsync();
|
||||
model.Approved = true;
|
||||
if (cpSettings.Enabled)
|
||||
{
|
||||
Log.Info("Adding movie to CP (No approval required)");
|
||||
var result = CouchPotatoApi.AddMovie(model.ImdbId, cpSettings.ApiKey, model.Title,
|
||||
cpSettings.FullUri, cpSettings.ProfileId);
|
||||
Log.Debug("Adding movie to CP result {0}", result);
|
||||
if (result)
|
||||
{
|
||||
return
|
||||
await
|
||||
AddRequest(model, settings,
|
||||
$"{fullMovieName} {Resources.UI.Search_SuccessfullyAdded}");
|
||||
}
|
||||
|
||||
return Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = false,
|
||||
Message = Resources.UI.Search_CouchPotatoError
|
||||
});
|
||||
}
|
||||
model.Approved = true;
|
||||
return await AddRequest(model, settings, $"{fullMovieName} {Resources.UI.Search_SuccessfullyAdded}");
|
||||
}
|
||||
|
||||
|
||||
return await AddRequest(model, settings, $"{fullMovieName} {Resources.UI.Search_SuccessfullyAdded}");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Fatal(e);
|
||||
await FaultQueue.QueueItemAsync(model, RequestType.Movie, FaultType.RequestFault);
|
||||
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = Resources.UI.Search_CouchPotatoError });
|
||||
await NotificationService.Publish(new NotificationModel
|
||||
{
|
||||
DateTime = DateTime.Now,
|
||||
User = Username,
|
||||
RequestType = RequestType.Movie,
|
||||
Title = model.Title,
|
||||
NotificationType = NotificationType.ItemAddedToFaultQueue
|
||||
});
|
||||
|
||||
return Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = true,
|
||||
Message = $"{fullMovieName} {Resources.UI.Search_SuccessfullyAdded}"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -576,9 +638,15 @@ namespace PlexRequests.UI.Modules
|
|||
var settings = await PrService.GetSettingsAsync();
|
||||
if (!await CheckRequestLimit(settings, RequestType.TvShow))
|
||||
{
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = Resources.UI.Search_WeeklyRequestLimitTVShow });
|
||||
return
|
||||
Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = false,
|
||||
Message = Resources.UI.Search_WeeklyRequestLimitTVShow
|
||||
});
|
||||
}
|
||||
Analytics.TrackEventAsync(Category.Search, Action.Request, "TvShow", Username, CookieHelper.GetAnalyticClientId(Cookies));
|
||||
Analytics.TrackEventAsync(Category.Search, Action.Request, "TvShow", Username,
|
||||
CookieHelper.GetAnalyticClientId(Cookies));
|
||||
|
||||
var sonarrSettings = SonarrService.GetSettingsAsync();
|
||||
|
||||
|
@ -590,7 +658,13 @@ namespace PlexRequests.UI.Modules
|
|||
var s = await sonarrSettings;
|
||||
if (!s.Enabled)
|
||||
{
|
||||
return Response.AsJson(new JsonResponseModel { Message = "This is currently only supported with Sonarr, Please enable Sonarr for this feature", Result = false });
|
||||
return
|
||||
Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Message =
|
||||
"This is currently only supported with Sonarr, Please enable Sonarr for this feature",
|
||||
Result = false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -599,14 +673,8 @@ namespace PlexRequests.UI.Modules
|
|||
DateTime.TryParse(showInfo.premiered, out firstAir);
|
||||
string fullShowName = $"{showInfo.name} ({firstAir.Year})";
|
||||
|
||||
if (showInfo.externals?.thetvdb == null)
|
||||
{
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Our TV Provider (TVMaze) doesn't have a TheTVDBId for this TV Show :( We cannot add the TV Show automatically sorry! Please report this problem to the server admin so he/she can sort it out!" });
|
||||
}
|
||||
|
||||
var model = new RequestedModel
|
||||
{
|
||||
ProviderId = showInfo.externals?.thetvdb ?? 0,
|
||||
Type = RequestType.TvShow,
|
||||
Overview = showInfo.summary.RemoveHtml(),
|
||||
PosterPath = showInfo.image?.medium,
|
||||
|
@ -622,6 +690,25 @@ namespace PlexRequests.UI.Modules
|
|||
TvDbId = showId.ToString()
|
||||
};
|
||||
|
||||
if (showInfo.externals?.thetvdb == null)
|
||||
{
|
||||
await FaultQueue.QueueItemAsync(model, RequestType.TvShow, FaultType.MissingInformation);
|
||||
await NotificationService.Publish(new NotificationModel
|
||||
{
|
||||
DateTime = DateTime.Now,
|
||||
User = Username,
|
||||
RequestType = RequestType.TvShow,
|
||||
Title = model.Title,
|
||||
NotificationType = NotificationType.ItemAddedToFaultQueue
|
||||
});
|
||||
return Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = true,
|
||||
Message = $"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}"
|
||||
});
|
||||
}
|
||||
|
||||
model.ProviderId = showInfo.externals?.thetvdb ?? 0;
|
||||
|
||||
var seasonsList = new List<int>();
|
||||
switch (seasons)
|
||||
|
@ -642,9 +729,14 @@ namespace PlexRequests.UI.Modules
|
|||
|
||||
foreach (var ep in episodeModel?.Episodes ?? new Models.EpisodesModel[0])
|
||||
{
|
||||
model.Episodes.Add(new EpisodesModel { EpisodeNumber = ep.EpisodeNumber, SeasonNumber = ep.SeasonNumber });
|
||||
model.Episodes.Add(new EpisodesModel
|
||||
{
|
||||
EpisodeNumber = ep.EpisodeNumber,
|
||||
SeasonNumber = ep.SeasonNumber
|
||||
});
|
||||
}
|
||||
Analytics.TrackEventAsync(Category.Requests, Action.TvShow, $"Episode request for {model.Title}", Username, CookieHelper.GetAnalyticClientId(Cookies));
|
||||
Analytics.TrackEventAsync(Category.Requests, Action.TvShow, $"Episode request for {model.Title}",
|
||||
Username, CookieHelper.GetAnalyticClientId(Cookies));
|
||||
break;
|
||||
default:
|
||||
model.SeasonsRequested = seasons;
|
||||
|
@ -691,7 +783,12 @@ namespace PlexRequests.UI.Modules
|
|||
else
|
||||
{
|
||||
// We no episodes to approve
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = $"{fullShowName} {Resources.UI.Search_AlreadyInPlex}" });
|
||||
return
|
||||
Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = false,
|
||||
Message = $"{fullShowName} {Resources.UI.Search_AlreadyInPlex}"
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (model.SeasonList.Except(existingRequest.SeasonList).Any())
|
||||
|
@ -720,9 +817,19 @@ namespace PlexRequests.UI.Modules
|
|||
var cachedEpisodes = cachedEpisodesTask.ToList();
|
||||
foreach (var d in difference) // difference is from an existing request
|
||||
{
|
||||
if (cachedEpisodes.Any(x => x.SeasonNumber == d.SeasonNumber && x.EpisodeNumber == d.EpisodeNumber && x.ProviderId == providerId))
|
||||
if (
|
||||
cachedEpisodes.Any(
|
||||
x =>
|
||||
x.SeasonNumber == d.SeasonNumber && x.EpisodeNumber == d.EpisodeNumber &&
|
||||
x.ProviderId == providerId))
|
||||
{
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = $"{fullShowName} {d.SeasonNumber} - {d.EpisodeNumber} {Resources.UI.Search_AlreadyInPlex}" });
|
||||
return
|
||||
Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = false,
|
||||
Message =
|
||||
$"{fullShowName} {d.SeasonNumber} - {d.EpisodeNumber} {Resources.UI.Search_AlreadyInPlex}"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -738,66 +845,118 @@ namespace PlexRequests.UI.Modules
|
|||
var result = Checker.IsEpisodeAvailable(showId.ToString(), s.SeasonNumber, s.EpisodeNumber);
|
||||
if (result)
|
||||
{
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = $"{fullShowName} {Resources.UI.Search_AlreadyInPlex}" });
|
||||
return
|
||||
Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = false,
|
||||
Message = $"{fullShowName} {Resources.UI.Search_AlreadyInPlex}"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Checker.IsTvShowAvailable(shows.ToArray(), showInfo.name, showInfo.premiered?.Substring(0, 4), providerId, model.SeasonList))
|
||||
else if (Checker.IsTvShowAvailable(shows.ToArray(), showInfo.name, showInfo.premiered?.Substring(0, 4),
|
||||
providerId, model.SeasonList))
|
||||
{
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = $"{fullShowName} {Resources.UI.Search_AlreadyInPlex}" });
|
||||
return
|
||||
Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = false,
|
||||
Message = $"{fullShowName} {Resources.UI.Search_AlreadyInPlex}"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = string.Format(Resources.UI.Search_CouldNotCheckPlex, fullShowName) });
|
||||
return
|
||||
Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = false,
|
||||
Message = string.Format(Resources.UI.Search_CouldNotCheckPlex, fullShowName)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (ShouldAutoApprove(RequestType.TvShow, settings))
|
||||
try
|
||||
{
|
||||
model.Approved = true;
|
||||
var s = await sonarrSettings;
|
||||
var sender = new TvSenderOld(SonarrApi, SickrageApi); // TODO put back
|
||||
if (s.Enabled)
|
||||
if (ShouldAutoApprove(RequestType.TvShow, settings))
|
||||
{
|
||||
var result = await sender.SendToSonarr(s, model);
|
||||
if (!string.IsNullOrEmpty(result?.title))
|
||||
model.Approved = true;
|
||||
var s = await sonarrSettings;
|
||||
var sender = new TvSenderOld(SonarrApi, SickrageApi); // TODO put back
|
||||
if (s.Enabled)
|
||||
{
|
||||
if (existingRequest != null)
|
||||
var result = await sender.SendToSonarr(s, model);
|
||||
if (!string.IsNullOrEmpty(result?.title))
|
||||
{
|
||||
return await UpdateRequest(model, settings,
|
||||
if (existingRequest != null)
|
||||
{
|
||||
return await UpdateRequest(model, settings,
|
||||
$"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}");
|
||||
}
|
||||
return
|
||||
await
|
||||
AddRequest(model, settings,
|
||||
$"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}");
|
||||
}
|
||||
return await AddRequest(model, settings, $"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}");
|
||||
Log.Debug("Error with sending to sonarr.");
|
||||
return
|
||||
Response.AsJson(ValidationHelper.SendSonarrError(result?.ErrorMessages ?? new List<string>()));
|
||||
}
|
||||
Log.Debug("Error with sending to sonarr.");
|
||||
return Response.AsJson(ValidationHelper.SendSonarrError(result?.ErrorMessages ?? new List<string>()));
|
||||
}
|
||||
|
||||
var srSettings = SickRageService.GetSettings();
|
||||
if (srSettings.Enabled)
|
||||
{
|
||||
var result = sender.SendToSickRage(srSettings, model);
|
||||
if (result?.result == "success")
|
||||
var srSettings = SickRageService.GetSettings();
|
||||
if (srSettings.Enabled)
|
||||
{
|
||||
return await AddRequest(model, settings, $"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}");
|
||||
var result = sender.SendToSickRage(srSettings, model);
|
||||
if (result?.result == "success")
|
||||
{
|
||||
return
|
||||
await
|
||||
AddRequest(model, settings,
|
||||
$"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}");
|
||||
}
|
||||
return
|
||||
Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = false,
|
||||
Message = result?.message ?? Resources.UI.Search_SickrageError
|
||||
});
|
||||
}
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = result?.message ?? Resources.UI.Search_SickrageError });
|
||||
|
||||
if (!srSettings.Enabled && !s.Enabled)
|
||||
{
|
||||
return
|
||||
await AddRequest(model, settings, $"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}");
|
||||
}
|
||||
|
||||
return
|
||||
Response.AsJson(new JsonResponseModel { Result = false, Message = Resources.UI.Search_TvNotSetUp });
|
||||
|
||||
}
|
||||
|
||||
if (!srSettings.Enabled && !s.Enabled)
|
||||
{
|
||||
return await AddRequest(model, settings, $"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}");
|
||||
}
|
||||
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = Resources.UI.Search_TvNotSetUp });
|
||||
|
||||
return await AddRequest(model, settings, $"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await FaultQueue.QueueItemAsync(model, RequestType.TvShow, FaultType.RequestFault);
|
||||
await NotificationService.Publish(new NotificationModel
|
||||
{
|
||||
DateTime = DateTime.Now,
|
||||
User = Username,
|
||||
RequestType = RequestType.TvShow,
|
||||
Title = model.Title,
|
||||
NotificationType = NotificationType.ItemAddedToFaultQueue
|
||||
});
|
||||
Log.Error(e);
|
||||
return
|
||||
Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = true,
|
||||
Message = $"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}"
|
||||
});
|
||||
}
|
||||
return await AddRequest(model, settings, $"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}");
|
||||
}
|
||||
|
||||
private async Task<Response> AddUserToRequest(RequestedModel existingRequest, PlexRequestSettings settings, string fullShowName, bool episodeReq = false)
|
||||
private async Task<Response> AddUserToRequest(RequestedModel existingRequest, PlexRequestSettings settings,
|
||||
string fullShowName, bool episodeReq = false)
|
||||
{
|
||||
// check if the current user is already marked as a requester for this show, if not, add them
|
||||
if (!existingRequest.UserHasRequested(Username))
|
||||
|
@ -812,12 +971,15 @@ namespace PlexRequests.UI.Modules
|
|||
$"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}");
|
||||
}
|
||||
|
||||
return await UpdateRequest(existingRequest, settings, $"{fullShowName} {Resources.UI.Search_AlreadyRequested}");
|
||||
return
|
||||
await UpdateRequest(existingRequest, settings, $"{fullShowName} {Resources.UI.Search_AlreadyRequested}");
|
||||
}
|
||||
|
||||
private bool ShouldSendNotification(RequestType type, PlexRequestSettings prSettings)
|
||||
{
|
||||
var sendNotification = ShouldAutoApprove(type, prSettings) ? !prSettings.IgnoreNotifyForAutoApprovedRequests : true;
|
||||
var sendNotification = ShouldAutoApprove(type, prSettings)
|
||||
? !prSettings.IgnoreNotifyForAutoApprovedRequests
|
||||
: true;
|
||||
var claims = Context.CurrentUser?.Claims;
|
||||
if (claims != null)
|
||||
{
|
||||
|
@ -836,9 +998,15 @@ namespace PlexRequests.UI.Modules
|
|||
var settings = await PrService.GetSettingsAsync();
|
||||
if (!await CheckRequestLimit(settings, RequestType.Album))
|
||||
{
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = Resources.UI.Search_WeeklyRequestLimitAlbums });
|
||||
return
|
||||
Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = false,
|
||||
Message = Resources.UI.Search_WeeklyRequestLimitAlbums
|
||||
});
|
||||
}
|
||||
Analytics.TrackEventAsync(Category.Search, Action.Request, "Album", Username, CookieHelper.GetAnalyticClientId(Cookies));
|
||||
Analytics.TrackEventAsync(Category.Search, Action.Request, "Album", Username,
|
||||
CookieHelper.GetAnalyticClientId(Cookies));
|
||||
var existingRequest = await RequestService.CheckRequestAsync(releaseId);
|
||||
|
||||
if (existingRequest != null)
|
||||
|
@ -848,7 +1016,15 @@ namespace PlexRequests.UI.Modules
|
|||
existingRequest.RequestedUsers.Add(Username);
|
||||
await RequestService.UpdateRequestAsync(existingRequest);
|
||||
}
|
||||
return Response.AsJson(new JsonResponseModel { Result = true, Message = settings.UsersCanViewOnlyOwnRequests ? $"{existingRequest.Title} {Resources.UI.Search_SuccessfullyAdded}" : $"{existingRequest.Title} {Resources.UI.Search_AlreadyRequested}" });
|
||||
return
|
||||
Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = true,
|
||||
Message =
|
||||
settings.UsersCanViewOnlyOwnRequests
|
||||
? $"{existingRequest.Title} {Resources.UI.Search_SuccessfullyAdded}"
|
||||
: $"{existingRequest.Title} {Resources.UI.Search_AlreadyRequested}"
|
||||
});
|
||||
}
|
||||
|
||||
var albumInfo = MusicBrainzApi.GetAlbum(releaseId);
|
||||
|
@ -858,11 +1034,17 @@ namespace PlexRequests.UI.Modules
|
|||
var artist = albumInfo.ArtistCredits?.FirstOrDefault()?.artist;
|
||||
if (artist == null)
|
||||
{
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = Resources.UI.Search_MusicBrainzError });
|
||||
return
|
||||
Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = false,
|
||||
Message = Resources.UI.Search_MusicBrainzError
|
||||
});
|
||||
}
|
||||
|
||||
var albums = Checker.GetPlexAlbums();
|
||||
var alreadyInPlex = Checker.IsAlbumAvailable(albums.ToArray(), albumInfo.title, release.ToString("yyyy"), artist.name);
|
||||
var alreadyInPlex = Checker.IsAlbumAvailable(albums.ToArray(), albumInfo.title, release.ToString("yyyy"),
|
||||
artist.name);
|
||||
|
||||
if (alreadyInPlex)
|
||||
{
|
||||
|
@ -892,28 +1074,46 @@ namespace PlexRequests.UI.Modules
|
|||
ArtistId = artist.id
|
||||
};
|
||||
|
||||
if (ShouldAutoApprove(RequestType.Album, settings))
|
||||
try
|
||||
{
|
||||
model.Approved = true;
|
||||
var hpSettings = HeadphonesService.GetSettings();
|
||||
|
||||
if (!hpSettings.Enabled)
|
||||
if (ShouldAutoApprove(RequestType.Album, settings))
|
||||
{
|
||||
await RequestService.AddRequestAsync(model);
|
||||
return
|
||||
Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = true,
|
||||
Message = $"{model.Title} {Resources.UI.Search_SuccessfullyAdded}"
|
||||
});
|
||||
model.Approved = true;
|
||||
var hpSettings = HeadphonesService.GetSettings();
|
||||
|
||||
if (!hpSettings.Enabled)
|
||||
{
|
||||
await RequestService.AddRequestAsync(model);
|
||||
return
|
||||
Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = true,
|
||||
Message = $"{model.Title} {Resources.UI.Search_SuccessfullyAdded}"
|
||||
});
|
||||
}
|
||||
|
||||
var sender = new HeadphonesSender(HeadphonesApi, hpSettings, RequestService);
|
||||
await sender.AddAlbum(model);
|
||||
return await AddRequest(model, settings, $"{model.Title} {Resources.UI.Search_SuccessfullyAdded}");
|
||||
}
|
||||
|
||||
var sender = new HeadphonesSender(HeadphonesApi, hpSettings, RequestService);
|
||||
await sender.AddAlbum(model);
|
||||
return await AddRequest(model, settings, $"{model.Title} {Resources.UI.Search_SuccessfullyAdded}");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e);
|
||||
await FaultQueue.QueueItemAsync(model, RequestType.Movie, FaultType.RequestFault);
|
||||
|
||||
return await AddRequest(model, settings, $"{model.Title} {Resources.UI.Search_SuccessfullyAdded}");
|
||||
await NotificationService.Publish(new NotificationModel
|
||||
{
|
||||
DateTime = DateTime.Now,
|
||||
User = Username,
|
||||
RequestType = RequestType.Album,
|
||||
Title = model.Title,
|
||||
NotificationType = NotificationType.ItemAddedToFaultQueue
|
||||
});
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private string GetMusicBrainzCoverArt(string id)
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
// ************************************************************************/
|
||||
#endregion
|
||||
using Ninject.Modules;
|
||||
|
||||
using PlexRequests.Core.Queue;
|
||||
using PlexRequests.Helpers.Analytics;
|
||||
using PlexRequests.Services.Interfaces;
|
||||
using PlexRequests.Services.Jobs;
|
||||
|
@ -51,6 +51,8 @@ namespace PlexRequests.UI.NinjectModules
|
|||
Bind<IAnalytics>().To<Analytics>();
|
||||
Bind<ISchedulerFactory>().To<StdSchedulerFactory>();
|
||||
Bind<IJobScheduler>().To<Scheduler>();
|
||||
|
||||
Bind<ITransientFaultQueue>().To<TransientFaultQueue>();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue