mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-14 17:22:54 -07:00
merge in tidusjar's dev changes, remove approve all, fix alignment on approve all category buttons
This commit is contained in:
commit
dce5983720
26 changed files with 592 additions and 109 deletions
|
@ -64,6 +64,7 @@
|
|||
<Compile Include="SickRage\SickRageStatus.cs" />
|
||||
<Compile Include="SickRage\SickRageTvAdd.cs" />
|
||||
<Compile Include="Sonarr\SonarrAddSeries.cs" />
|
||||
<Compile Include="Sonarr\SonarrError.cs" />
|
||||
<Compile Include="Sonarr\SonarrProfile.cs" />
|
||||
<Compile Include="Sonarr\SystemStatus.cs" />
|
||||
<Compile Include="Tv\Authentication.cs" />
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PlexRequests.Api.Models.Sonarr
|
||||
{
|
||||
public class Season
|
||||
|
@ -23,6 +25,8 @@ namespace PlexRequests.Api.Models.Sonarr
|
|||
public string imdbId { get; set; }
|
||||
public string titleSlug { get; set; }
|
||||
public int id { get; set; }
|
||||
[JsonIgnore]
|
||||
public string ErrorMessage { get; set; }
|
||||
}
|
||||
|
||||
public class AddOptions
|
||||
|
|
36
PlexRequests.Api.Models/Sonarr/SonarrError.cs
Normal file
36
PlexRequests.Api.Models/Sonarr/SonarrError.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
#region Copyright
|
||||
// /************************************************************************
|
||||
// Copyright (c) 2016 Jamie Rees
|
||||
// File: SonarrError.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.Api.Models.Sonarr
|
||||
{
|
||||
public class SonarrError
|
||||
{
|
||||
public string propertyName { get; set; }
|
||||
public string errorMessage { get; set; }
|
||||
public string attemptedValue { get; set; }
|
||||
public string[] formattedMessageArguments { get; set; }
|
||||
}
|
||||
}
|
|
@ -26,13 +26,9 @@
|
|||
#endregion
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using NLog;
|
||||
|
||||
|
@ -96,20 +92,13 @@ namespace PlexRequests.Api
|
|||
throw new ApplicationException(message, response.ErrorException);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
var json = JsonConvert.DeserializeObject<T>(response.Content);
|
||||
|
||||
return json;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Fatal(e);
|
||||
Log.Info(response.Content);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public T DeserializeXml<T>(string input)
|
||||
private T DeserializeXml<T>(string input)
|
||||
where T : class
|
||||
{
|
||||
var ser = new XmlSerializer(typeof(T));
|
||||
|
|
|
@ -27,9 +27,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using NLog;
|
||||
using PlexRequests.Api.Interfaces;
|
||||
using PlexRequests.Api.Models.Sonarr;
|
||||
using PlexRequests.Helpers;
|
||||
|
||||
using RestSharp;
|
||||
|
||||
namespace PlexRequests.Api
|
||||
|
@ -56,7 +61,8 @@ namespace PlexRequests.Api
|
|||
|
||||
public SonarrAddSeries AddSeries(int tvdbId, string title, int qualityId, bool seasonFolders, string rootPath, int seasonCount, int[] seasons, string apiKey, Uri baseUrl)
|
||||
{
|
||||
|
||||
Log.Debug("Adding series {0}", title);
|
||||
Log.Debug("Seasons = {0}, out of {1} seasons", seasons.DumpJson(), seasonCount);
|
||||
var request = new RestRequest
|
||||
{
|
||||
Resource = "/api/Series?",
|
||||
|
@ -74,7 +80,6 @@ namespace PlexRequests.Api
|
|||
rootFolderPath = rootPath
|
||||
};
|
||||
|
||||
|
||||
for (var i = 1; i <= seasonCount; i++)
|
||||
{
|
||||
var season = new Season
|
||||
|
@ -85,12 +90,25 @@ namespace PlexRequests.Api
|
|||
options.seasons.Add(season);
|
||||
}
|
||||
|
||||
Log.Debug("Sonarr API Options:");
|
||||
Log.Debug(options.DumpJson());
|
||||
|
||||
request.AddHeader("X-Api-Key", apiKey);
|
||||
request.AddJsonBody(options);
|
||||
|
||||
var obj = Api.ExecuteJson<SonarrAddSeries>(request, baseUrl);
|
||||
SonarrAddSeries result;
|
||||
try
|
||||
{
|
||||
result = Api.ExecuteJson<SonarrAddSeries>(request, baseUrl);
|
||||
}
|
||||
catch (JsonSerializationException jse)
|
||||
{
|
||||
Log.Error(jse);
|
||||
var error = Api.ExecuteJson<SonarrError>(request, baseUrl);
|
||||
result = new SonarrAddSeries { ErrorMessage = error.errorMessage };
|
||||
}
|
||||
|
||||
return obj;
|
||||
return result;
|
||||
}
|
||||
|
||||
public SystemStatus SystemStatus(string apiKey, Uri baseUrl)
|
||||
|
|
|
@ -79,6 +79,10 @@ namespace PlexRequests.Core
|
|||
public RequestedModel Get(int id)
|
||||
{
|
||||
var blob = Repo.Get(id);
|
||||
if (blob == null)
|
||||
{
|
||||
return new RequestedModel();
|
||||
}
|
||||
var model = ByteConverterHelper.ReturnObject<RequestedModel>(blob.Content);
|
||||
return model;
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
<Compile Include="Models\StatusModel.cs" />
|
||||
<Compile Include="Models\UserProperties.cs" />
|
||||
<Compile Include="SettingModels\AuthenticationSettings.cs" />
|
||||
<Compile Include="SettingModels\HeadphonesSettings.cs" />
|
||||
<Compile Include="SettingModels\PushoverNotificationSettings.cs" />
|
||||
<Compile Include="SettingModels\PushBulletNotificationSettings.cs" />
|
||||
<Compile Include="SettingModels\EmailNotificationSettings.cs" />
|
||||
|
|
58
PlexRequests.Core/SettingModels/HeadphonesSettings.cs
Normal file
58
PlexRequests.Core/SettingModels/HeadphonesSettings.cs
Normal file
|
@ -0,0 +1,58 @@
|
|||
#region Copyright
|
||||
// /************************************************************************
|
||||
// Copyright (c) 2016 Jamie Rees
|
||||
// File: CouchPotatoSettings.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 Newtonsoft.Json;
|
||||
using PlexRequests.Helpers;
|
||||
|
||||
namespace PlexRequests.Core.SettingModels
|
||||
{
|
||||
public class HeadphonesSettings : Settings
|
||||
{
|
||||
public string Enabled { get; set; }
|
||||
public string Ip { get; set; }
|
||||
public int Port { get; set; }
|
||||
public int ApiKey { get; set; }
|
||||
public bool Ssl { get; set; }
|
||||
public string SubDir { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public Uri FullUri
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(SubDir))
|
||||
{
|
||||
var formattedSubDir = Ip.ReturnUriWithSubDir(Port, Ssl, SubDir);
|
||||
return formattedSubDir;
|
||||
}
|
||||
var formatted = Ip.ReturnUri(Port, Ssl);
|
||||
return formatted;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -32,12 +32,12 @@ using Moq;
|
|||
using NUnit.Framework;
|
||||
|
||||
using PlexRequests.Api.Interfaces;
|
||||
using PlexRequests.Api.Models;
|
||||
using PlexRequests.Api.Models.Plex;
|
||||
using PlexRequests.Core;
|
||||
using PlexRequests.Core.SettingModels;
|
||||
using PlexRequests.Helpers.Exceptions;
|
||||
using PlexRequests.Services.Interfaces;
|
||||
using PlexRequests.Store;
|
||||
|
||||
namespace PlexRequests.Services.Tests
|
||||
{
|
||||
|
@ -66,7 +66,7 @@ namespace PlexRequests.Services.Tests
|
|||
var requestMock = new Mock<IRequestService>();
|
||||
var plexMock = new Mock<IPlexApi>();
|
||||
|
||||
var searchResult = new PlexSearch {Video = new List<Video> {new Video {Title = "title", Year = "2011"} } };
|
||||
var searchResult = new PlexSearch { Video = new List<Video> { new Video { Title = "title", Year = "2011" } } };
|
||||
|
||||
settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
||||
authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "abc" });
|
||||
|
@ -87,7 +87,7 @@ namespace PlexRequests.Services.Tests
|
|||
var requestMock = new Mock<IRequestService>();
|
||||
var plexMock = new Mock<IPlexApi>();
|
||||
|
||||
var searchResult = new PlexSearch { Directory = new Directory1 {Title = "title", Year = "2013"} };
|
||||
var searchResult = new PlexSearch { Directory = new Directory1 { Title = "title", Year = "2013" } };
|
||||
|
||||
settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
||||
authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "abc" });
|
||||
|
@ -100,6 +100,27 @@ namespace PlexRequests.Services.Tests
|
|||
Assert.That(result, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsAvailableDirectoryTitleWithoutYearTest()
|
||||
{
|
||||
var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
||||
var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
||||
var requestMock = new Mock<IRequestService>();
|
||||
var plexMock = new Mock<IPlexApi>();
|
||||
|
||||
var searchResult = new PlexSearch { Directory = new Directory1 { Title = "title", } };
|
||||
|
||||
settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
||||
authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "abc" });
|
||||
plexMock.Setup(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>())).Returns(searchResult);
|
||||
|
||||
Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object);
|
||||
|
||||
var result = Checker.IsAvailable("title", null);
|
||||
|
||||
Assert.That(result, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsNotAvailableTest()
|
||||
{
|
||||
|
@ -108,7 +129,7 @@ namespace PlexRequests.Services.Tests
|
|||
var requestMock = new Mock<IRequestService>();
|
||||
var plexMock = new Mock<IPlexApi>();
|
||||
|
||||
var searchResult = new PlexSearch { Video = new List<Video> { new Video { Title = "wrong tistle", Year = "2011"} } };
|
||||
var searchResult = new PlexSearch { Video = new List<Video> { new Video { Title = "wrong title", Year = "2011" } } };
|
||||
|
||||
settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
||||
authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "abc" });
|
||||
|
@ -121,6 +142,27 @@ namespace PlexRequests.Services.Tests
|
|||
Assert.That(result, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsNotAvailableTestWihtoutYear()
|
||||
{
|
||||
var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
||||
var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
||||
var requestMock = new Mock<IRequestService>();
|
||||
var plexMock = new Mock<IPlexApi>();
|
||||
|
||||
var searchResult = new PlexSearch { Video = new List<Video> { new Video { Title = "wrong title" } } };
|
||||
|
||||
settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
||||
authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "abc" });
|
||||
plexMock.Setup(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>())).Returns(searchResult);
|
||||
|
||||
Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object);
|
||||
|
||||
var result = Checker.IsAvailable("title", null);
|
||||
|
||||
Assert.That(result, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsYearDoesNotMatchTest()
|
||||
{
|
||||
|
@ -141,5 +183,155 @@ namespace PlexRequests.Services.Tests
|
|||
|
||||
Assert.That(result, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TitleDoesNotMatchTest()
|
||||
{
|
||||
var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
||||
var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
||||
var requestMock = new Mock<IRequestService>();
|
||||
var plexMock = new Mock<IPlexApi>();
|
||||
|
||||
var searchResult = new PlexSearch { Video = new List<Video> { new Video { Title = "title23", Year = "2019" } } };
|
||||
|
||||
settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
||||
authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "abc" });
|
||||
plexMock.Setup(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>())).Returns(searchResult);
|
||||
|
||||
Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object);
|
||||
|
||||
var result = Checker.IsAvailable("title", "2019");
|
||||
|
||||
Assert.That(result, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TitleDoesNotMatchWithoutYearTest()
|
||||
{
|
||||
var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
||||
var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
||||
var requestMock = new Mock<IRequestService>();
|
||||
var plexMock = new Mock<IPlexApi>();
|
||||
|
||||
var searchResult = new PlexSearch { Video = new List<Video> { new Video { Title = "title23" } } };
|
||||
|
||||
settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
||||
authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "abc" });
|
||||
plexMock.Setup(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>())).Returns(searchResult);
|
||||
|
||||
Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object);
|
||||
|
||||
var result = Checker.IsAvailable("title", null);
|
||||
|
||||
Assert.That(result, Is.False);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void CheckAndUpdateNoPlexSettingsTest()
|
||||
{
|
||||
var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
||||
var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
||||
var requestMock = new Mock<IRequestService>();
|
||||
var plexMock = new Mock<IPlexApi>();
|
||||
authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "abc" });
|
||||
Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object);
|
||||
|
||||
Checker.CheckAndUpdateAll(1);
|
||||
|
||||
requestMock.Verify(x => x.BatchUpdate(It.IsAny<List<RequestedModel>>()), Times.Never);
|
||||
requestMock.Verify(x => x.Get(It.IsAny<int>()), Times.Never);
|
||||
plexMock.Verify(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CheckAndUpdateNoAuthSettingsTest()
|
||||
{
|
||||
var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
||||
var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
||||
var requestMock = new Mock<IRequestService>();
|
||||
var plexMock = new Mock<IPlexApi>();
|
||||
settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "123" });
|
||||
|
||||
Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object);
|
||||
|
||||
Checker.CheckAndUpdateAll(1);
|
||||
|
||||
requestMock.Verify(x => x.BatchUpdate(It.IsAny<List<RequestedModel>>()), Times.Never);
|
||||
requestMock.Verify(x => x.Get(It.IsAny<int>()), Times.Never);
|
||||
plexMock.Verify(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CheckAndUpdateNoRequestsTest()
|
||||
{
|
||||
var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
||||
var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
||||
var requestMock = new Mock<IRequestService>();
|
||||
var plexMock = new Mock<IPlexApi>();
|
||||
settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "192.168.1.1" });
|
||||
authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "abc" });
|
||||
requestMock.Setup(x => x.GetAll()).Returns(new List<RequestedModel>());
|
||||
|
||||
Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object);
|
||||
|
||||
Checker.CheckAndUpdateAll(1);
|
||||
|
||||
requestMock.Verify(x => x.BatchUpdate(It.IsAny<List<RequestedModel>>()), Times.Never);
|
||||
requestMock.Verify(x => x.Get(It.IsAny<int>()), Times.Never);
|
||||
plexMock.Verify(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>()), Times.Never);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
[Ignore("Need to work out Plex Directory vs Video objects")]
|
||||
public void CheckAndUpdateRequestsTest()
|
||||
{
|
||||
|
||||
var requests = new List<RequestedModel> {
|
||||
new RequestedModel
|
||||
{
|
||||
Id = 123,
|
||||
Title = "title1",
|
||||
Available = false,
|
||||
},
|
||||
new RequestedModel
|
||||
{
|
||||
Id=222,
|
||||
Title = "title3",
|
||||
Available = false
|
||||
},
|
||||
new RequestedModel
|
||||
{
|
||||
Id = 333,
|
||||
Title= "missingTitle",
|
||||
Available = false
|
||||
},
|
||||
new RequestedModel
|
||||
{
|
||||
Id= 444,
|
||||
Title = "already found",
|
||||
Available = true
|
||||
}
|
||||
};
|
||||
|
||||
var search = new PlexSearch { };
|
||||
|
||||
var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
||||
var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
||||
var requestMock = new Mock<IRequestService>();
|
||||
var plexMock = new Mock<IPlexApi>();
|
||||
settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "192.168.1.1" });
|
||||
authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "abc" });
|
||||
requestMock.Setup(x => x.GetAll()).Returns(requests);
|
||||
|
||||
Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object);
|
||||
|
||||
Checker.CheckAndUpdateAll(1);
|
||||
|
||||
requestMock.Verify(x => x.BatchUpdate(It.IsAny<List<RequestedModel>>()), Times.Never);
|
||||
requestMock.Verify(x => x.Get(It.IsAny<int>()), Times.Never);
|
||||
plexMock.Verify(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>()), Times.Never);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -84,6 +84,10 @@
|
|||
<Project>{566EFA49-68F8-4716-9693-A6B3F2624DEA}</Project>
|
||||
<Name>PlexRequests.Services</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\PlexRequests.Store\PlexRequests.Store.csproj">
|
||||
<Project>{92433867-2B7B-477B-A566-96C382427525}</Project>
|
||||
<Name>PlexRequests.Store</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Choose>
|
||||
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
// ************************************************************************/
|
||||
#endregion
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
|
@ -52,7 +53,7 @@ namespace PlexRequests.Services
|
|||
private ISettingsService<AuthenticationSettings> Auth { get; }
|
||||
private IRequestService RequestService { get; }
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
private IPlexApi PlexApi { get; set; }
|
||||
private IPlexApi PlexApi { get; }
|
||||
|
||||
|
||||
public void CheckAndUpdateAll(long check)
|
||||
|
@ -62,7 +63,7 @@ namespace PlexRequests.Services
|
|||
var requests = RequestService.GetAll();
|
||||
|
||||
var requestedModels = requests as RequestedModel[] ?? requests.ToArray();
|
||||
if (!ValidateSettings(plexSettings, authSettings, requestedModels))
|
||||
if (!ValidateSettings(plexSettings, authSettings) || !requestedModels.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -97,38 +98,22 @@ namespace PlexRequests.Services
|
|||
{
|
||||
throw new ApplicationSettingsException("The settings are not configured for Plex or Authentication");
|
||||
}
|
||||
var results = PlexApi.SearchContent(authSettings.PlexAuthToken, title, plexSettings.FullUri);
|
||||
if (!string.IsNullOrEmpty(year))
|
||||
{
|
||||
var results = PlexApi.SearchContent(authSettings.PlexAuthToken, title, plexSettings.FullUri);
|
||||
var result = results.Video?.FirstOrDefault(x => x.Title.Contains(title) && x.Year == year);
|
||||
var result = results.Video?.FirstOrDefault(x => x.Title.Equals(title, StringComparison.InvariantCultureIgnoreCase) && x.Year == year);
|
||||
var directoryTitle = results.Directory?.Title == title && results.Directory?.Year == year;
|
||||
return result?.Title != null || directoryTitle;
|
||||
}
|
||||
else
|
||||
{
|
||||
var results = PlexApi.SearchContent(authSettings.PlexAuthToken, title, plexSettings.FullUri);
|
||||
var result = results.Video?.FirstOrDefault(x => x.Title.Contains(title));
|
||||
var result = results.Video?.FirstOrDefault(x => x.Title.Equals(title, StringComparison.InvariantCultureIgnoreCase));
|
||||
var directoryTitle = results.Directory?.Title == title;
|
||||
return result?.Title != null || directoryTitle;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private bool ValidateSettings(PlexSettings plex, AuthenticationSettings auth, IEnumerable<RequestedModel> requests)
|
||||
{
|
||||
if (plex.Ip == null || auth.PlexAuthToken == null || requests == null)
|
||||
{
|
||||
Log.Warn("A setting is null, Ensure Plex is configured correctly, and we have a Plex Auth token.");
|
||||
return false;
|
||||
}
|
||||
if (!requests.Any())
|
||||
{
|
||||
Log.Info("We have no requests to check if they are available on Plex.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ValidateSettings(PlexSettings plex, AuthenticationSettings auth)
|
||||
{
|
||||
if (plex?.Ip == null || auth?.PlexAuthToken == null)
|
||||
|
|
|
@ -27,12 +27,11 @@
|
|||
using System;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using Mono.Data.Sqlite;
|
||||
|
||||
using NLog;
|
||||
using PlexRequests.Helpers;
|
||||
using PlexRequests.Store.Repository;
|
||||
|
||||
namespace PlexRequests.Store
|
||||
{
|
||||
|
@ -44,12 +43,14 @@ namespace PlexRequests.Store
|
|||
Factory = provider;
|
||||
}
|
||||
|
||||
private SqliteFactory Factory { get; set; }
|
||||
private SqliteFactory Factory { get; }
|
||||
private string CurrentPath =>Path.Combine(Path.GetDirectoryName(Application.ExecutablePath) ?? string.Empty, DbFile);
|
||||
|
||||
public virtual bool CheckDb()
|
||||
{
|
||||
Log.Trace("Checking DB");
|
||||
if (!File.Exists(DbFile))
|
||||
Console.WriteLine(CurrentPath);
|
||||
if (!File.Exists(CurrentPath))
|
||||
{
|
||||
Log.Trace("DB doesn't exist, creating a new one");
|
||||
CreateDatabase();
|
||||
|
@ -72,7 +73,7 @@ namespace PlexRequests.Store
|
|||
{
|
||||
throw new SqliteException("Factory returned null");
|
||||
}
|
||||
fact.ConnectionString = "Data Source=" + DbFile;
|
||||
fact.ConnectionString = "Data Source=" + CurrentPath;
|
||||
return fact;
|
||||
}
|
||||
|
||||
|
@ -83,7 +84,7 @@ namespace PlexRequests.Store
|
|||
{
|
||||
try
|
||||
{
|
||||
using (File.Create(DbFile))
|
||||
using (File.Create(CurrentPath))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
|
|
|
@ -59,6 +59,7 @@ namespace PlexRequests.UI.Tests
|
|||
private Mock<ISettingsService<EmailNotificationSettings>> EmailMock { get; set; }
|
||||
private Mock<ISettingsService<PushbulletNotificationSettings>> PushbulletSettings { get; set; }
|
||||
private Mock<ISettingsService<PushoverNotificationSettings>> PushoverSettings { get; set; }
|
||||
private Mock<ISettingsService<HeadphonesSettings>> HeadphonesSettings { get; set; }
|
||||
private Mock<IPlexApi> PlexMock { get; set; }
|
||||
private Mock<ISonarrApi> SonarrApiMock { get; set; }
|
||||
private Mock<IPushbulletApi> PushbulletApi { get; set; }
|
||||
|
@ -94,6 +95,7 @@ namespace PlexRequests.UI.Tests
|
|||
PushoverSettings = new Mock<ISettingsService<PushoverNotificationSettings>>();
|
||||
PushoverApi = new Mock<IPushoverApi>();
|
||||
NotificationService = new Mock<INotificationService>();
|
||||
HeadphonesSettings = new Mock<ISettingsService<HeadphonesSettings>>();
|
||||
|
||||
Bootstrapper = new ConfigurableBootstrapper(with =>
|
||||
{
|
||||
|
@ -114,6 +116,7 @@ namespace PlexRequests.UI.Tests
|
|||
with.Dependency(PushoverSettings.Object);
|
||||
with.Dependency(PushoverApi.Object);
|
||||
with.Dependency(NotificationService.Object);
|
||||
with.Dependency(HeadphonesSettings.Object);
|
||||
with.RootPathProvider<TestRootPathProvider>();
|
||||
with.RequestStartup((container, pipelines, context) =>
|
||||
{
|
||||
|
|
|
@ -76,9 +76,9 @@ namespace PlexRequests.UI
|
|||
container.Register<ISettingsService<EmailNotificationSettings>, SettingsServiceV2<EmailNotificationSettings>>();
|
||||
container.Register<ISettingsService<PushbulletNotificationSettings>, SettingsServiceV2<PushbulletNotificationSettings>>();
|
||||
container.Register<ISettingsService<PushoverNotificationSettings>, SettingsServiceV2<PushoverNotificationSettings>>();
|
||||
container.Register<ISettingsService<HeadphonesSettings>, SettingsServiceV2<HeadphonesSettings>>();
|
||||
|
||||
// Repo's
|
||||
container.Register<IRepository<RequestedModel>, GenericRepository<RequestedModel>>();
|
||||
container.Register<IRepository<LogEntity>, GenericRepository<LogEntity>>();
|
||||
container.Register<IRequestService, JsonRequestService>();
|
||||
container.Register<ISettingsRepository, SettingsJsonRepository>();
|
||||
|
@ -101,13 +101,13 @@ namespace PlexRequests.UI
|
|||
|
||||
SubscribeAllObservers(container);
|
||||
base.ConfigureRequestContainer(container, context);
|
||||
|
||||
TaskManager.TaskFactory = new PlexTaskFactory();
|
||||
TaskManager.Initialize(new PlexRegistry());
|
||||
}
|
||||
|
||||
protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
|
||||
{
|
||||
TaskManager.TaskFactory = new PlexTaskFactory();
|
||||
TaskManager.Initialize(new PlexRegistry());
|
||||
|
||||
CookieBasedSessions.Enable(pipelines, CryptographyConfiguration.Default);
|
||||
|
||||
StaticConfiguration.DisableErrorTraces = false;
|
||||
|
@ -123,6 +123,7 @@ namespace PlexRequests.UI
|
|||
|
||||
FormsAuthentication.Enable(pipelines, formsAuthConfiguration);
|
||||
|
||||
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
|
||||
ServicePointManager.ServerCertificateValidationCallback +=
|
||||
(sender, certificate, chain, sslPolicyErrors) => true;
|
||||
|
||||
|
|
|
@ -58,36 +58,6 @@ $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
|||
});
|
||||
|
||||
// Approve all
|
||||
$('#approveAll').click(function (e) {
|
||||
e.preventDefault();
|
||||
var buttonId = e.target.id;
|
||||
var origHtml = $(this).html();
|
||||
|
||||
if ($('#' + buttonId).text() === " Loading...") {
|
||||
return;
|
||||
}
|
||||
|
||||
loadingButton(buttonId, "success");
|
||||
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: '/approval/approveall',
|
||||
dataType: "json",
|
||||
success: function (response) {
|
||||
if (checkJsonResponse(response)) {
|
||||
generateNotify("Success! All requests approved!", "success");
|
||||
initLoad();
|
||||
}
|
||||
},
|
||||
error: function (e) {
|
||||
console.log(e);
|
||||
generateNotify("Something went wrong!", "danger");
|
||||
},
|
||||
complete: function (e) {
|
||||
finishLoading(buttonId, "success", origHtml)
|
||||
}
|
||||
});
|
||||
});
|
||||
$('#approveMovies').click(function (e) {
|
||||
e.preventDefault();
|
||||
var buttonId = e.target.id;
|
||||
|
|
|
@ -24,17 +24,13 @@
|
|||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
// ************************************************************************/
|
||||
#endregion
|
||||
|
||||
using Nancy;
|
||||
using NLog;
|
||||
using PlexRequests.Api.Interfaces;
|
||||
using PlexRequests.Api.Models.SickRage;
|
||||
using PlexRequests.Api.Models.Sonarr;
|
||||
using PlexRequests.Core;
|
||||
using PlexRequests.Core.SettingModels;
|
||||
using PlexRequests.Helpers;
|
||||
using PlexRequests.Store;
|
||||
using PlexRequests.UI.Models;
|
||||
|
||||
namespace PlexRequests.UI.Helpers
|
||||
{
|
||||
|
|
|
@ -12,12 +12,12 @@ namespace PlexRequests.UI.Jobs
|
|||
//typeof(AvailabilityUpdateService);
|
||||
var container = TinyIoCContainer.Current;
|
||||
|
||||
var a= container.ResolveAll(typeof(T));
|
||||
var a= container.Resolve(typeof(T));
|
||||
|
||||
object outT;
|
||||
container.TryResolve(typeof(T), out outT);
|
||||
|
||||
return (T)outT;
|
||||
return (T)a;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -28,6 +28,8 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
using System.Linq;
|
||||
using System.Web.UI.HtmlControls;
|
||||
|
||||
using Humanizer;
|
||||
using MarkdownSharp;
|
||||
|
||||
|
@ -66,6 +68,7 @@ namespace PlexRequests.UI.Modules
|
|||
private ISettingsService<EmailNotificationSettings> EmailService { get; }
|
||||
private ISettingsService<PushbulletNotificationSettings> PushbulletService { get; }
|
||||
private ISettingsService<PushoverNotificationSettings> PushoverService { get; }
|
||||
private ISettingsService<HeadphonesSettings> HeadphonesService { get; }
|
||||
private IPlexApi PlexApi { get; }
|
||||
private ISonarrApi SonarrApi { get; }
|
||||
private IPushbulletApi PushbulletApi { get; }
|
||||
|
@ -90,7 +93,8 @@ namespace PlexRequests.UI.Modules
|
|||
ISettingsService<PushoverNotificationSettings> pushoverSettings,
|
||||
IPushoverApi pushoverApi,
|
||||
IRepository<LogEntity> logsRepo,
|
||||
INotificationService notify) : base("admin")
|
||||
INotificationService notify,
|
||||
ISettingsService<HeadphonesSettings> headphones) : base("admin")
|
||||
{
|
||||
RpService = rpService;
|
||||
CpService = cpService;
|
||||
|
@ -108,6 +112,7 @@ namespace PlexRequests.UI.Modules
|
|||
PushoverService = pushoverSettings;
|
||||
PushoverApi = pushoverApi;
|
||||
NotificationService = notify;
|
||||
HeadphonesService = headphones;
|
||||
|
||||
#if !DEBUG
|
||||
this.RequiresAuthentication();
|
||||
|
@ -155,6 +160,9 @@ namespace PlexRequests.UI.Modules
|
|||
Get["/loglevel"] = _ => GetLogLevels();
|
||||
Post["/loglevel"] = _ => UpdateLogLevels(Request.Form.level);
|
||||
Get["/loadlogs"] = _ => LoadLogs();
|
||||
|
||||
Get["/headphones"] = _ => Headphones();
|
||||
Post["/headphones"] = _ => SaveHeadphones();
|
||||
}
|
||||
|
||||
private Negotiator Authentication()
|
||||
|
@ -567,5 +575,32 @@ namespace PlexRequests.UI.Modules
|
|||
LoggingHelper.ReconfigureLogLevel(newLevel);
|
||||
return Response.AsJson(new JsonResponseModel { Result = true, Message = $"The new log level is now {newLevel}"});
|
||||
}
|
||||
|
||||
private Negotiator Headphones()
|
||||
{
|
||||
var settings = HeadphonesService.GetSettings();
|
||||
return View["Headphones", settings];
|
||||
}
|
||||
|
||||
private Response SaveHeadphones()
|
||||
{
|
||||
var settings = this.Bind<HeadphonesSettings>();
|
||||
|
||||
var valid = this.Validate(settings);
|
||||
if (!valid.IsValid)
|
||||
{
|
||||
var error = valid.SendJsonError();
|
||||
Log.Info("Error validating Headphones settings, message: {0}", error.Message);
|
||||
return Response.AsJson(error);
|
||||
}
|
||||
Log.Trace(settings.DumpJson());
|
||||
|
||||
var result = HeadphonesService.SaveSettings(settings);
|
||||
|
||||
Log.Info("Saved headphones settings, result: {0}", result);
|
||||
return Response.AsJson(result
|
||||
? new JsonResponseModel { Result = true, Message = "Successfully Updated the Settings for Headphones!" }
|
||||
: new JsonResponseModel { Result = false, Message = "Could not update the settings, take a look at the logs." });
|
||||
}
|
||||
}
|
||||
}
|
|
@ -57,6 +57,7 @@ namespace PlexRequests.UI.Modules
|
|||
Post["/sonarr"] = _ => SonarrTest();
|
||||
Post["/plex"] = _ => PlexTest();
|
||||
Post["/sickrage"] = _ => SickRageTest();
|
||||
Post["/headphones"] = _ => HeadphonesTest();
|
||||
|
||||
}
|
||||
|
||||
|
@ -168,5 +169,10 @@ namespace PlexRequests.UI.Modules
|
|||
return Response.AsJson(new JsonResponseModel { Result = false, Message = message });
|
||||
}
|
||||
}
|
||||
|
||||
private Response HeadphonesTest()
|
||||
{
|
||||
throw new NotImplementedException(); //TODO
|
||||
}
|
||||
}
|
||||
}
|
|
@ -133,7 +133,7 @@ namespace PlexRequests.UI.Modules
|
|||
return Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = false,
|
||||
Message = "Could not add the series to Sonarr"
|
||||
Message = result.ErrorMessage ?? "Could not add the series to Sonarr"
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -340,7 +340,7 @@ namespace PlexRequests.UI.Modules
|
|||
if (sonarr.Enabled)
|
||||
{
|
||||
var res = sender.SendToSonarr(sonarr, r);
|
||||
if (res != null)
|
||||
if (!string.IsNullOrEmpty(res?.title))
|
||||
{
|
||||
r.Approved = true;
|
||||
updatedRequests.Add(r);
|
||||
|
@ -348,15 +348,25 @@ namespace PlexRequests.UI.Modules
|
|||
else
|
||||
{
|
||||
Log.Error("Could not approve and send the TV {0} to Sonarr!", r.Title);
|
||||
Log.Error("Error message: {0}", res?.ErrorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
|
||||
var result = Service.BatchUpdate(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!" });
|
||||
}
|
||||
}
|
||||
|
||||
private bool SendMovie(CouchPotatoSettings settings, RequestedModel r, ICouchPotatoApi cp)
|
||||
{
|
||||
|
|
|
@ -371,18 +371,19 @@ namespace PlexRequests.UI.Modules
|
|||
if (sonarrSettings.Enabled)
|
||||
{
|
||||
var result = sender.SendToSonarr(sonarrSettings, model);
|
||||
if (result != null)
|
||||
if (result != null && !string.IsNullOrEmpty(result.title))
|
||||
{
|
||||
model.Approved = true;
|
||||
Log.Debug("Adding tv to database requests (No approval required & Sonarr)");
|
||||
RequestService.AddRequest(model);
|
||||
|
||||
return Response.AsJson(new JsonResponseModel { Result = true, Message = $"{fullShowName} was successfully added!" });
|
||||
}
|
||||
var notify1 = new NotificationModel { Title = model.Title, User = model.RequestedBy, DateTime = DateTime.Now, NotificationType = NotificationType.NewRequest };
|
||||
NotificationService.Publish(notify1);
|
||||
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Something went wrong adding the movie to Sonarr! Please check your settings." });
|
||||
return Response.AsJson(new JsonResponseModel { Result = true, Message = $"{fullShowName} was successfully added!" });
|
||||
}
|
||||
|
||||
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = result?.ErrorMessage ?? "Something went wrong adding the movie to Sonarr! Please check your settings." });
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -371,6 +371,9 @@
|
|||
<Content Include="Views\Admin\PushoverNotifications.cshtml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Views\Admin\Headphones.cshtml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<None Include="Web.Debug.config">
|
||||
<DependentUpon>web.config</DependentUpon>
|
||||
</None>
|
||||
|
|
162
PlexRequests.UI/Views/Admin/Headphones.cshtml
Normal file
162
PlexRequests.UI/Views/Admin/Headphones.cshtml
Normal file
|
@ -0,0 +1,162 @@
|
|||
@Html.Partial("_Sidebar")
|
||||
@{
|
||||
int port;
|
||||
if (Model.Port == 0)
|
||||
{
|
||||
port = 8081;
|
||||
}
|
||||
else
|
||||
{
|
||||
port = Model.Port;
|
||||
}
|
||||
}
|
||||
<div class="col-sm-8 col-sm-push-1">
|
||||
<form class="form-horizontal" method="POST" id="mainForm">
|
||||
<fieldset>
|
||||
<legend>Headphones Settings</legend>
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
@if (Model.Enabled)
|
||||
{
|
||||
<input type="checkbox" id="Enabled" name="Enabled" checked="checked"><text>Enabled</text>
|
||||
}
|
||||
else
|
||||
{
|
||||
<input type="checkbox" id="Enabled" name="Enabled"><text>Enabled</text>
|
||||
}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
@if (Model.Ssl)
|
||||
{
|
||||
<input type="checkbox" id="Ssl" name="Ssl" checked="checked"><text>SSL</text>
|
||||
}
|
||||
else
|
||||
{
|
||||
<input type="checkbox" id="Ssl" name="Ssl"><text>SSL</text>
|
||||
}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="Ip" class="control-label">Headphones Hostname or IP</label>
|
||||
<div class="">
|
||||
<input type="text" class="form-control form-control-custom " id="Ip" name="Ip" placeholder="localhost" value="@Model.Ip">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="portNumber" class="control-label">Port</label>
|
||||
|
||||
<div class="">
|
||||
<input type="text" class="form-control form-control-custom " id="portNumber" name="Port" placeholder="Port Number" value="@port">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label for="ApiKey" class="control-label">Headphones API Key</label>
|
||||
<div>
|
||||
<input type="text" class="form-control form-control-custom " id="ApiKey" name="ApiKey" value="@Model.ApiKey">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="SubDir" class="control-label">Headphones SubDirectory</label>
|
||||
<div>
|
||||
<input type="text" class="form-control form-control-custom " id="SubDir" name="SubDir" value="@Model.SubDir">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button type="submit" id="getProfiles" class="btn btn-primary-outline">Get Quality Profiles</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button id="testHeadphones" type="submit" class="btn btn-primary-outline">Test Connectivity</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button id="save" type="submit" class="btn btn-primary-outline">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
$(function() {
|
||||
|
||||
$('#testHeadphones').click(function (e) {
|
||||
e.preventDefault();
|
||||
var $form = $("#mainForm");
|
||||
|
||||
$.ajax({
|
||||
type: $form.prop("method"),
|
||||
url: "/test/headphones",
|
||||
data: $form.serialize(),
|
||||
dataType: "json",
|
||||
success: function (response) {
|
||||
console.log(response);
|
||||
if (response.result === true) {
|
||||
generateNotify(response.message, "success");
|
||||
$('#authToken').val(response.authToken);
|
||||
} else {
|
||||
generateNotify(response.message, "warning");
|
||||
}
|
||||
},
|
||||
error: function (e) {
|
||||
console.log(e);
|
||||
generateNotify("Something went wrong!", "danger");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#save').click(function (e) {
|
||||
e.preventDefault();
|
||||
var port = $('#portNumber').val();
|
||||
if (isNaN(port)) {
|
||||
generateNotify("You must specify a Port.", "warning");
|
||||
return;
|
||||
}
|
||||
var $form = $("#mainForm");
|
||||
var qualityProfile = $("#profiles option:selected").val();
|
||||
var data = $form.serialize();
|
||||
data = data + "&profileId=" + qualityProfile;
|
||||
|
||||
$.ajax({
|
||||
type: $form.prop("method"),
|
||||
data: data,
|
||||
url: $form.prop("action"),
|
||||
dataType: "json",
|
||||
success: function (response) {
|
||||
if (response.result === true) {
|
||||
generateNotify(response.message, "success");
|
||||
} else {
|
||||
generateNotify(response.message, "warning");
|
||||
}
|
||||
},
|
||||
error: function (e) {
|
||||
console.log(e);
|
||||
generateNotify("Something went wrong!", "danger");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
|
@ -52,6 +52,14 @@
|
|||
{
|
||||
<a class="list-group-item" href="/admin/sickrage">SickRage</a>
|
||||
}
|
||||
@if (Context.Request.Path == "/admin/headphones")
|
||||
{
|
||||
<a class="list-group-item active" href="/admin/headphones">Headphones</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
<a class="list-group-item" href="/admin/headphones">Headphones</a>
|
||||
}
|
||||
|
||||
@if (Context.Request.Path == "/admin/emailnotification")
|
||||
{
|
||||
|
|
|
@ -2,13 +2,8 @@
|
|||
<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-success-outline" type="submit"><i class="fa fa-plus"></i> Approve All</button>
|
||||
<br />
|
||||
|
||||
<br />
|
||||
<br />
|
||||
}
|
||||
<!-- Nav tabs -->
|
||||
<ul id="nav-tabs" class="nav nav-tabs" role="tablist">
|
||||
@if (Model.SearchForMovies)
|
||||
|
@ -23,10 +18,9 @@
|
|||
</ul>
|
||||
<br />
|
||||
|
||||
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content contentList">
|
||||
<div class="btn-group col-sm-2">
|
||||
<div class="btn-group col-sm-push-8">
|
||||
@if (Context.CurrentUser.IsAuthenticated())
|
||||
{
|
||||
@if (Model.SearchForMovies)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue