mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-08 06:00:50 -07:00
Some error handling and ensure we are an admin to delete requests.
Also started on the approval of everything
This commit is contained in:
parent
2935bee30d
commit
0942bfcbcc
18 changed files with 436 additions and 58 deletions
|
@ -0,0 +1,48 @@
|
|||
#region Copyright
|
||||
// /************************************************************************
|
||||
// Copyright (c) 2016 Jamie Rees
|
||||
// File: ApplicationSettingsException.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
|
||||
using System;
|
||||
|
||||
namespace PlexRequests.Helpers.Exceptions
|
||||
{
|
||||
public class ApplicationSettingsException : Exception
|
||||
{
|
||||
|
||||
public ApplicationSettingsException(string message) : base(message)
|
||||
{
|
||||
|
||||
}
|
||||
public ApplicationSettingsException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ApplicationSettingsException()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -47,6 +47,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AssemblyHelper.cs" />
|
||||
<Compile Include="Exceptions\ApplicationSettingsException.cs" />
|
||||
<Compile Include="ICacheProvider.cs" />
|
||||
<Compile Include="LoggingHelper.cs" />
|
||||
<Compile Include="MemoryCacheProvider.cs" />
|
||||
|
@ -59,6 +60,7 @@
|
|||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
using System;
|
||||
|
||||
using PlexRequests.Helpers.Exceptions;
|
||||
|
||||
namespace PlexRequests.Helpers
|
||||
{
|
||||
public static class UriHelper
|
||||
|
@ -7,6 +9,10 @@ namespace PlexRequests.Helpers
|
|||
|
||||
public static Uri ReturnUri(this string val)
|
||||
{
|
||||
if (val == null)
|
||||
{
|
||||
throw new ApplicationSettingsException("The URI is null, please check your settings to make sure you have configured the applications correctly.");
|
||||
}
|
||||
try
|
||||
{
|
||||
var uri = new UriBuilder();
|
||||
|
@ -53,6 +59,10 @@ namespace PlexRequests.Helpers
|
|||
/// <exception cref="System.Exception"></exception>
|
||||
public static Uri ReturnUri(this string val, int port)
|
||||
{
|
||||
if (val == null)
|
||||
{
|
||||
throw new ApplicationSettingsException("The URI is null, please check your settings to make sure you have configured the applications correctly.");
|
||||
}
|
||||
try
|
||||
{
|
||||
var uri = new UriBuilder();
|
||||
|
@ -65,7 +75,7 @@ namespace PlexRequests.Helpers
|
|||
uri = new UriBuilder(Uri.UriSchemeHttp, split[2], port, "/" + split[3]);
|
||||
}
|
||||
else
|
||||
uri = new UriBuilder(new Uri(string.Format("{0}:{1}", val, port)));
|
||||
uri = new UriBuilder(new Uri($"{val}:{port}"));
|
||||
}
|
||||
else if (val.StartsWith("https://", StringComparison.Ordinal))
|
||||
{
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using NLog;
|
||||
|
||||
using PlexRequests.Api;
|
||||
using PlexRequests.Core;
|
||||
using PlexRequests.Core.SettingModels;
|
||||
|
@ -47,6 +49,7 @@ namespace PlexRequests.Services
|
|||
private ISettingsService<PlexSettings> Plex { get; }
|
||||
private ISettingsService<AuthenticationSettings> Auth { get; }
|
||||
private IRequestService RequestService { get; }
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
|
||||
public void CheckAndUpdateAll(long check)
|
||||
|
@ -54,6 +57,18 @@ namespace PlexRequests.Services
|
|||
var plexSettings = Plex.GetSettings();
|
||||
var authSettings = Auth.GetSettings();
|
||||
var requests = RequestService.GetAll();
|
||||
|
||||
if (plexSettings.Ip == null || authSettings.PlexAuthToken == null || requests == null)
|
||||
{
|
||||
Log.Warn("A setting is null, Ensure Plex is configured correctly, and we have a Plex Auth token.");
|
||||
return;
|
||||
}
|
||||
if (!requests.Any())
|
||||
{
|
||||
Log.Info("We have no requests to check if they are available on Plex.");
|
||||
return;
|
||||
}
|
||||
|
||||
var api = new PlexApi();
|
||||
|
||||
var modifiedModel = new List<RequestedModel>();
|
||||
|
|
|
@ -30,6 +30,10 @@ using System.Linq;
|
|||
|
||||
using Dapper.Contrib.Extensions;
|
||||
|
||||
using NLog;
|
||||
|
||||
using PlexRequests.Helpers;
|
||||
|
||||
namespace PlexRequests.Store
|
||||
{
|
||||
public class GenericRepository<T> : IRepository<T> where T : Entity
|
||||
|
@ -39,6 +43,8 @@ namespace PlexRequests.Store
|
|||
Config = config;
|
||||
}
|
||||
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private ISqliteConfiguration Config { get; set; }
|
||||
public long Insert(T entity)
|
||||
{
|
||||
|
@ -84,6 +90,8 @@ namespace PlexRequests.Store
|
|||
|
||||
public bool Update(T entity)
|
||||
{
|
||||
Log.Trace("Updating entity");
|
||||
Log.Trace(entity.DumpJson());
|
||||
using (var db = Config.DbConnection())
|
||||
{
|
||||
db.Open();
|
||||
|
@ -93,7 +101,9 @@ namespace PlexRequests.Store
|
|||
|
||||
public bool UpdateAll(IEnumerable<T> entity)
|
||||
{
|
||||
Log.Trace("Updating all entities");
|
||||
var result = new HashSet<bool>();
|
||||
|
||||
using (var db = Config.DbConnection())
|
||||
{
|
||||
db.Open();
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
using Dapper.Contrib.Extensions;
|
||||
|
||||
|
@ -20,7 +21,8 @@ namespace PlexRequests.Store
|
|||
public string RequestedBy { get; set; }
|
||||
public DateTime RequestedDate { get; set; }
|
||||
public bool Available { get; set; }
|
||||
|
||||
public IssueState Issues { get; set; }
|
||||
public string OtherMessage { get; set; }
|
||||
}
|
||||
|
||||
public enum RequestType
|
||||
|
@ -28,4 +30,13 @@ namespace PlexRequests.Store
|
|||
Movie,
|
||||
TvShow
|
||||
}
|
||||
|
||||
public enum IssueState
|
||||
{
|
||||
WrongAudio,
|
||||
NoSubtitles,
|
||||
WrongContent,
|
||||
PlaybackIssues,
|
||||
Other
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ CREATE TABLE IF NOT EXISTS Requested
|
|||
Type INTEGER NOT NULL,
|
||||
ProviderId INTEGER NOT NULL,
|
||||
ImdbId varchar(50),
|
||||
Overview varchar(50) NOT NULL,
|
||||
Overview varchar(50),
|
||||
Title varchar(50) NOT NULL,
|
||||
PosterPath varchar(50) NOT NULL,
|
||||
ReleaseDate varchar(50) NOT NULL,
|
||||
|
@ -30,7 +30,9 @@ CREATE TABLE IF NOT EXISTS Requested
|
|||
Approved INTEGER NOT NULL,
|
||||
RequestedBy varchar(50),
|
||||
RequestedDate varchar(50) NOT NULL,
|
||||
Available INTEGER(50)
|
||||
Available INTEGER(50),
|
||||
Issues INTEGER,
|
||||
OtherMessage varchar(50)
|
||||
|
||||
);
|
||||
|
||||
|
|
|
@ -18,3 +18,4 @@
|
|||
background-color: #4e5d6c !important;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,67 @@ var tvimer = 0;
|
|||
movieLoad();
|
||||
tvLoad();
|
||||
|
||||
$('#approveAll').click(function() {
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: '/approval/approveall',
|
||||
dataType: "json",
|
||||
success: function (response) {
|
||||
if (checkJsonResponse(response)) {
|
||||
generateNotify("Success!", "success");
|
||||
}
|
||||
},
|
||||
error: function (e) {
|
||||
console.log(e);
|
||||
generateNotify("Something went wrong!", "danger");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// Report Issue
|
||||
$(document).on("click", ".dropdownIssue", function (e) {
|
||||
var issue = $(this).attr("issue-select");
|
||||
var id = e.target.id;
|
||||
// Other issue so the modal is opening
|
||||
if (issue == 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
type: "post",
|
||||
url: "/requests/reportissue",
|
||||
data: $form.serialize(), // TODO pass in issue enum and Id
|
||||
dataType: "json",
|
||||
success: function (response) {
|
||||
|
||||
if (checkJsonResponse(response)) {
|
||||
generateNotify("Success!", "success");
|
||||
|
||||
$("#" + buttonId + "Template").slideUp();
|
||||
}
|
||||
},
|
||||
error: function (e) {
|
||||
console.log(e);
|
||||
generateNotify("Something went wrong!", "danger");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Modal click
|
||||
$('.theSaveButton').click(function() {
|
||||
|
||||
});
|
||||
|
||||
// Update the modal
|
||||
$('#myModal').on('show.bs.modal', function(event) {
|
||||
var button = $(event.relatedTarget); // Button that triggered the modal
|
||||
var id = button.data('identifier'); // Extract info from data-* attributes
|
||||
|
||||
var modal = $(this);
|
||||
modal.find('.theSaveButton').val(id);
|
||||
});
|
||||
|
||||
$(document).on("click", ".delete", function (e) {
|
||||
e.preventDefault();
|
||||
var buttonId = e.target.id;
|
||||
|
@ -24,13 +85,11 @@ $(document).on("click", ".delete", function (e) {
|
|||
data: $form.serialize(),
|
||||
dataType: "json",
|
||||
success: function (response) {
|
||||
console.log(response);
|
||||
if (response.result === true) {
|
||||
|
||||
if (checkJsonResponse(response)) {
|
||||
generateNotify("Success!", "success");
|
||||
|
||||
$("#" + buttonId + "Template").slideUp();
|
||||
} else {
|
||||
generateNotify(response.message, "warning");
|
||||
}
|
||||
},
|
||||
error: function (e) {
|
||||
|
@ -81,7 +140,8 @@ function buildRequestContext(result, type) {
|
|||
approved: result.approved,
|
||||
requestedBy: result.requestedBy,
|
||||
requestedDate: result.requestedDate,
|
||||
available: result.available
|
||||
available: result.available,
|
||||
admin: result.admin
|
||||
};
|
||||
|
||||
return context;
|
||||
|
|
|
@ -10,14 +10,14 @@ var searchTemplate = Handlebars.compile(searchSource);
|
|||
var movieTimer = 0;
|
||||
var tvimer = 0;
|
||||
|
||||
$("#movieSearchContent").keypress(function (e) {
|
||||
$("#movieSearchContent").keypress(function () {
|
||||
if (movieTimer) {
|
||||
clearTimeout(movieTimer);
|
||||
}
|
||||
movieTimer = setTimeout(movieSearch, 400);
|
||||
});
|
||||
|
||||
$("#tvSearchContent").keypress(function (e) {
|
||||
$("#tvSearchContent").keypress(function () {
|
||||
if (tvimer) {
|
||||
clearTimeout(tvimer);
|
||||
}
|
||||
|
@ -26,12 +26,17 @@ $("#tvSearchContent").keypress(function (e) {
|
|||
|
||||
// Click TV dropdown option
|
||||
$(document).on("click", ".dropdownTv", function (e) {
|
||||
e.preventDefault();
|
||||
var buttonId = e.target.id;
|
||||
$("#" + buttonId).prop("disabled", true);
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
|
||||
var $form = $('#form' + buttonId);
|
||||
var data = $form.serialize();
|
||||
var seasons = $(this).attr("season-select");
|
||||
if (seasons === "1") {
|
||||
// Send over the latest
|
||||
data = data + "&latest=true";
|
||||
}
|
||||
|
||||
|
@ -39,14 +44,16 @@ $(document).on("click", ".dropdownTv", function (e) {
|
|||
var url = $form.prop('action');
|
||||
|
||||
sendRequestAjax(data, type, url, buttonId);
|
||||
$("#" + buttonId).prop("disabled", false);
|
||||
});
|
||||
|
||||
// Click Request for movie
|
||||
$(document).on("click", ".requestMovie", function (e) {
|
||||
$(".requestMovie").prop("disabled", true);
|
||||
var buttonId = e.target.id;
|
||||
$("#" + buttonId).prop("disabled", true);
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
var buttonId = e.target.id;
|
||||
var $form = $('#form' + buttonId);
|
||||
|
||||
var type = $form.prop('method');
|
||||
|
@ -54,6 +61,7 @@ $(document).on("click", ".requestMovie", function (e) {
|
|||
var data = $form.serialize();
|
||||
|
||||
sendRequestAjax(data, type, url, buttonId);
|
||||
$("#" + buttonId).prop("disabled", false);
|
||||
});
|
||||
|
||||
function sendRequestAjax(data, type, url, buttonId) {
|
||||
|
@ -113,3 +121,34 @@ function tvSearch() {
|
|||
});
|
||||
};
|
||||
|
||||
|
||||
function buildMovieContext(result) {
|
||||
var date = new Date(result.releaseDate);
|
||||
var year = date.getFullYear();
|
||||
var context = {
|
||||
posterPath: result.posterPath,
|
||||
id: result.id,
|
||||
title: result.title,
|
||||
overview: result.overview,
|
||||
voteCount: result.voteCount,
|
||||
voteAverage: result.voteAverage,
|
||||
year: year,
|
||||
type: "movie"
|
||||
};
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
function buildTvShowContext(result) {
|
||||
var date = new Date(result.firstAired);
|
||||
var year = date.getFullYear();
|
||||
var context = {
|
||||
posterPath: result.banner,
|
||||
id: result.id,
|
||||
title: result.seriesName,
|
||||
overview: result.overview,
|
||||
year: year,
|
||||
type: "tv"
|
||||
};
|
||||
return context;
|
||||
}
|
||||
|
|
|
@ -9,33 +9,11 @@
|
|||
});
|
||||
}
|
||||
|
||||
function buildMovieContext(result) {
|
||||
var date = new Date(result.releaseDate);
|
||||
var year = date.getFullYear();
|
||||
var context = {
|
||||
posterPath: result.posterPath,
|
||||
id: result.id,
|
||||
title: result.title,
|
||||
overview: result.overview,
|
||||
voteCount: result.voteCount,
|
||||
voteAverage: result.voteAverage,
|
||||
year: year,
|
||||
type: "movie"
|
||||
};
|
||||
|
||||
return context;
|
||||
function checkJsonResponse(response) {
|
||||
if (response.result === true) {
|
||||
return true;
|
||||
} else {
|
||||
generateNotify(response.message, "warning");
|
||||
return false;
|
||||
}
|
||||
|
||||
function buildTvShowContext(result) {
|
||||
var date = new Date(result.firstAired);
|
||||
var year = date.getFullYear();
|
||||
var context = {
|
||||
posterPath: result.banner,
|
||||
id: result.id,
|
||||
title: result.seriesName,
|
||||
overview: result.overview,
|
||||
year: year,
|
||||
type: "tv"
|
||||
};
|
||||
return context;
|
||||
}
|
||||
|
|
34
PlexRequests.UI/Models/JsonResponseModel.cs
Normal file
34
PlexRequests.UI/Models/JsonResponseModel.cs
Normal file
|
@ -0,0 +1,34 @@
|
|||
#region Copyright
|
||||
// /************************************************************************
|
||||
// Copyright (c) 2016 Jamie Rees
|
||||
// File: JsonResponseModel.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 PlexRequests.UI.Models
|
||||
{
|
||||
public class JsonResponseModel
|
||||
{
|
||||
public bool Result { get; set; }
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
|
@ -44,5 +44,6 @@ namespace PlexRequests.UI.Models
|
|||
public string RequestedDate { get; set; }
|
||||
public string ReleaseYear { get; set; }
|
||||
public bool Available { get; set; }
|
||||
public bool Admin { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
120
PlexRequests.UI/Modules/ApprovalModule.cs
Normal file
120
PlexRequests.UI/Modules/ApprovalModule.cs
Normal file
|
@ -0,0 +1,120 @@
|
|||
#region Copyright
|
||||
// /************************************************************************
|
||||
// Copyright (c) 2016 Jamie Rees
|
||||
// File: ApprovalModule.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
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Nancy;
|
||||
using Nancy.Security;
|
||||
|
||||
using NLog;
|
||||
|
||||
using PlexRequests.Store;
|
||||
using PlexRequests.UI.Models;
|
||||
|
||||
namespace PlexRequests.UI.Modules
|
||||
{
|
||||
public class ApprovalModule : BaseModule
|
||||
{
|
||||
|
||||
public ApprovalModule(IRepository<RequestedModel> service) : base("approval")
|
||||
{
|
||||
this.RequiresAuthentication();
|
||||
|
||||
Service = service;
|
||||
|
||||
Post["/approve"] = parameters => Approve((int)Request.Form.requestid);
|
||||
Post["/approveall"] = x => ApproveAll();
|
||||
}
|
||||
|
||||
private IRepository<RequestedModel> Service { get; set; }
|
||||
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
/// <summary>
|
||||
/// Approves the specified request identifier.
|
||||
/// </summary>
|
||||
/// <param name="requestId">The request identifier.</param>
|
||||
/// <returns></returns>
|
||||
private Response Approve(int requestId)
|
||||
{
|
||||
// Get the request from the DB
|
||||
var request = Service.Get(requestId);
|
||||
|
||||
if (request == null)
|
||||
{
|
||||
Log.Warn("Tried approving a request, but the request did not exist in the database, requestId = {0}", requestId);
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = "There are no requests to approve. Please refresh." });
|
||||
}
|
||||
|
||||
// Approve it
|
||||
request.Approved = true;
|
||||
|
||||
// Update the record
|
||||
var result = Service.Update(request);
|
||||
|
||||
return Response.AsJson(result
|
||||
? new JsonResponseModel { Result = true }
|
||||
: new JsonResponseModel { Result = false, Message = "We could not approve this request. Please try again or check the logs." });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Approves all.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private Response ApproveAll()
|
||||
{
|
||||
var requests = Service.GetAll();
|
||||
var requestedModels = requests as RequestedModel[] ?? requests.ToArray();
|
||||
if (!requestedModels.Any())
|
||||
{
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = "There are no requests to approve. Please refresh." });
|
||||
}
|
||||
|
||||
var updatedRequests = new List<RequestedModel>();
|
||||
foreach (var r in requestedModels)
|
||||
{
|
||||
r.Approved = true;
|
||||
updatedRequests.Add(r);
|
||||
}
|
||||
try
|
||||
{
|
||||
|
||||
var result = Service.UpdateAll(updatedRequests); return Response.AsJson(result
|
||||
? new JsonResponseModel { Result = true }
|
||||
: new JsonResponseModel { Result = false, Message = "We could not approve all of the requests. Please try again or check the logs." });
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Fatal(e);
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Something bad happened, please check the logs!" });
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -32,6 +32,8 @@ using Humanizer;
|
|||
|
||||
using Nancy;
|
||||
using Nancy.Responses.Negotiation;
|
||||
using Nancy.Security;
|
||||
|
||||
using PlexRequests.Api;
|
||||
using PlexRequests.Core;
|
||||
using PlexRequests.Core.SettingModels;
|
||||
|
@ -67,11 +69,12 @@ namespace PlexRequests.UI.Modules
|
|||
private Negotiator LoadRequests()
|
||||
{
|
||||
var settings = PrSettings.GetSettings();
|
||||
return View["Requests/Index", settings];
|
||||
return View["Index", settings];
|
||||
}
|
||||
|
||||
private Response GetMovies()
|
||||
{
|
||||
var isAdmin = Context.CurrentUser.IsAuthenticated();
|
||||
var dbMovies = Service.GetAll().Where(x => x.Type == RequestType.Movie);
|
||||
var viewModel = dbMovies.Select(movie => new RequestViewModel
|
||||
{
|
||||
|
@ -88,7 +91,8 @@ namespace PlexRequests.UI.Modules
|
|||
Overview = movie.Overview,
|
||||
RequestedBy = movie.RequestedBy,
|
||||
ReleaseYear = movie.ReleaseDate.Year.ToString(),
|
||||
Available = movie.Available
|
||||
Available = movie.Available,
|
||||
Admin = isAdmin
|
||||
}).ToList();
|
||||
|
||||
return Response.AsJson(viewModel);
|
||||
|
@ -96,6 +100,7 @@ namespace PlexRequests.UI.Modules
|
|||
|
||||
private Response GetTvShows()
|
||||
{
|
||||
var isAdmin = Context.CurrentUser.IsAuthenticated();
|
||||
var dbTv = Service.GetAll().Where(x => x.Type == RequestType.TvShow);
|
||||
var viewModel = dbTv.Select(tv => new RequestViewModel
|
||||
{
|
||||
|
@ -112,17 +117,22 @@ namespace PlexRequests.UI.Modules
|
|||
Overview = tv.Overview,
|
||||
RequestedBy = tv.RequestedBy,
|
||||
ReleaseYear = tv.ReleaseDate.Year.ToString(),
|
||||
Available = tv.Available
|
||||
Available = tv.Available,
|
||||
Admin = isAdmin
|
||||
}).ToList();
|
||||
|
||||
return Response.AsJson(viewModel);
|
||||
}
|
||||
|
||||
private Response DeleteRequest(int providerId, RequestType type)
|
||||
{
|
||||
if (Context.CurrentUser.IsAuthenticated())
|
||||
{
|
||||
var currentEntity = Service.GetAll().FirstOrDefault(x => x.ProviderId == providerId && x.Type == type);
|
||||
Service.Delete(currentEntity);
|
||||
return Response.AsJson(new { Result = true });
|
||||
return Response.AsJson(new JsonResponseModel { Result = true });
|
||||
}
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = "You are not an Admin, so you cannot delete any requests." });
|
||||
}
|
||||
}
|
||||
}
|
|
@ -163,6 +163,7 @@
|
|||
</Content>
|
||||
<Compile Include="Jobs\PlexRegistry.cs" />
|
||||
<Compile Include="Jobs\PlexTaskFactory.cs" />
|
||||
<Compile Include="Models\JsonResponseModel.cs" />
|
||||
<Compile Include="Models\PlexAuth.cs" />
|
||||
<Compile Include="Models\RequestViewModel.cs" />
|
||||
<Compile Include="Models\SearchTvShowViewModel.cs" />
|
||||
|
@ -170,6 +171,7 @@
|
|||
<Compile Include="Modules\AdminModule.cs" />
|
||||
<Compile Include="Modules\BaseModule.cs" />
|
||||
<Compile Include="Modules\IndexModule.cs" />
|
||||
<Compile Include="Modules\ApprovalModule.cs" />
|
||||
<Compile Include="Modules\UserLoginModule.cs" />
|
||||
<Compile Include="Modules\LoginModule.cs" />
|
||||
<Compile Include="Modules\RequestsModule.cs" />
|
||||
|
@ -217,9 +219,6 @@
|
|||
<None Include="sqlite3.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<Content Include="Views\Index.cshtml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="web.config">
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
Home
|
||||
|
|
@ -1,6 +1,11 @@
|
|||
<div>
|
||||
@using Nancy.Security
|
||||
<div>
|
||||
<h1>Requests</h1>
|
||||
<h4>Below you can see yours and all other requests, as well as their download and approval status.</h4>
|
||||
@if (Context.CurrentUser.IsAuthenticated())
|
||||
{
|
||||
<button id="approveAll" class="btn btn-primary" type="submit"><i class="fa fa-plus"></i> Approve All</button>
|
||||
}
|
||||
<!-- Nav tabs -->
|
||||
<ul id="nav-tabs" class="nav nav-tabs" role="tablist">
|
||||
@if (Model.SearchForMovies)
|
||||
|
@ -92,11 +97,29 @@
|
|||
<div class="col-sm-2 col-sm-push-3">
|
||||
<br />
|
||||
<br />
|
||||
{{#if_eq admin true}}
|
||||
<form method="POST" action="/requests/delete" id="form{{id}}">
|
||||
<input name="Id" type="text" value="{{id}}" hidden="hidden" />
|
||||
<input name="Type" type="text" value="{{type}}" hidden="hidden" />
|
||||
<button id="{{id}}" style="text-align: right" class="btn btn-danger delete" type="submit"><i class="fa fa-plus"></i> Remove</button>
|
||||
</form>
|
||||
{{/if_eq}}
|
||||
|
||||
{{#if_eq admin false}}
|
||||
<div class="dropdown">
|
||||
<button id="{{id}}" class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||
<i class="fa fa-plus"></i> Report Issue
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
||||
<li><a id="{{id}}" issue-select="0" class="dropdownIssue" href="#">Wrong Audio</a></li>
|
||||
<li><a id="{{id}}" issue-select="1" class="dropdownIssue" href="#">No Subtitles</a></li>
|
||||
<li><a id="{{id}}" issue-select="2" class="dropdownIssue" href="#">Wrong Content</a></li>
|
||||
<li><a id="{{id}}" issue-select="3" class="dropdownIssue" href="#">Playback Issues</a></li>
|
||||
<li><a id="{{id}}" issue-select="4" class="dropdownIssue" data-identifier="{{id}}" href="#" data-toggle="modal" data-target="#myModal">Other</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
{{/if_eq}}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -104,5 +127,22 @@
|
|||
</div>
|
||||
</script>
|
||||
|
||||
<div class="modal fade" id="myModal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-times"></i></button>
|
||||
<h4 class="modal-title">Modal title</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>One fine body</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
<button type="button" class="btn btn-primary theSaveButton">Save changes</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/Content/requests.js" type="text/javascript"></script>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue