mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-30 11:38:32 -07:00
commit
14d4f6f098
64 changed files with 1863 additions and 233 deletions
|
@ -33,7 +33,8 @@ namespace PlexRequests.Api.Interfaces
|
|||
{
|
||||
public interface ICouchPotatoApi
|
||||
{
|
||||
bool AddMovie(string imdbid, string apiKey, string title, Uri baseUrl);
|
||||
bool AddMovie(string imdbid, string apiKey, string title, Uri baseUrl, string profileID = default(string));
|
||||
CouchPotatoStatus GetStatus(Uri url, string apiKey);
|
||||
CouchPotatoProfiles GetProfiles(Uri url, string apiKey);
|
||||
}
|
||||
}
|
|
@ -37,6 +37,6 @@ namespace PlexRequests.Api.Interfaces
|
|||
PlexFriends GetUsers(string authToken);
|
||||
PlexSearch SearchContent(string authToken, string searchTerm, Uri plexFullHost);
|
||||
PlexStatus GetStatus(string authToken, Uri uri);
|
||||
|
||||
PlexAccount GetAccount(string authToken);
|
||||
}
|
||||
}
|
40
PlexRequests.Api.Interfaces/ISickRageApi.cs
Normal file
40
PlexRequests.Api.Interfaces/ISickRageApi.cs
Normal file
|
@ -0,0 +1,40 @@
|
|||
#region Copyright
|
||||
// /************************************************************************
|
||||
// Copyright (c) 2016 Jamie Rees
|
||||
// File: ISickRageApi.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 PlexRequests.Api.Models.SickRage;
|
||||
|
||||
namespace PlexRequests.Api.Interfaces
|
||||
{
|
||||
public interface ISickRageApi
|
||||
{
|
||||
SickRageTvAdd AddSeries(int tvdbId, bool latest, string quality, string apiKey,
|
||||
Uri baseUrl);
|
||||
|
||||
SickRagePing Ping(string apiKey, Uri baseUrl);
|
||||
}
|
||||
}
|
|
@ -49,6 +49,7 @@
|
|||
<Compile Include="ICouchPotatoApi.cs" />
|
||||
<Compile Include="IPlexApi.cs" />
|
||||
<Compile Include="IPushbulletApi.cs" />
|
||||
<Compile Include="ISickRageApi.cs" />
|
||||
<Compile Include="ISonarrApi.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
|
|
53
PlexRequests.Api.Models/Movie/CouchPotatoProfiles.cs
Normal file
53
PlexRequests.Api.Models/Movie/CouchPotatoProfiles.cs
Normal file
|
@ -0,0 +1,53 @@
|
|||
#region Copyright
|
||||
// /************************************************************************
|
||||
// Copyright (c) 2016 Jamie Rees
|
||||
// File: CouchPotatoProfiles.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.Collections.Generic;
|
||||
|
||||
namespace PlexRequests.Api.Models.Movie
|
||||
{
|
||||
public class ProfileList
|
||||
{
|
||||
public bool core { get; set; }
|
||||
public string _rev { get; set; }
|
||||
public List<bool> finish { get; set; }
|
||||
public List<string> qualities { get; set; }
|
||||
public string _id { get; set; }
|
||||
public string _t { get; set; }
|
||||
public string label { get; set; }
|
||||
public int minimum_score { get; set; }
|
||||
public List<int> stop_after { get; set; }
|
||||
public List<int> wait_for { get; set; }
|
||||
public int order { get; set; }
|
||||
public List<object> __invalid_name__3d { get; set; }
|
||||
}
|
||||
|
||||
public class CouchPotatoProfiles
|
||||
{
|
||||
public List<ProfileList> list { get; set; }
|
||||
public bool success { get; set; }
|
||||
}
|
||||
}
|
22
PlexRequests.Api.Models/Plex/PlexAccount.cs
Normal file
22
PlexRequests.Api.Models/Plex/PlexAccount.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace PlexRequests.Api.Models.Plex
|
||||
{
|
||||
[XmlRoot(ElementName = "user")]
|
||||
public class PlexAccount
|
||||
{
|
||||
[XmlAttribute(AttributeName = "id")]
|
||||
public string Id { get; set; }
|
||||
[XmlAttribute(AttributeName = "username")]
|
||||
public string Username { get; set; }
|
||||
[XmlAttribute(AttributeName = "email")]
|
||||
public string Email { get; set; }
|
||||
[XmlAttribute(AttributeName = "authenticationToken")]
|
||||
public string AuthToken { get; set; }
|
||||
}
|
||||
}
|
|
@ -238,9 +238,79 @@ namespace PlexRequests.Api.Models.Plex
|
|||
public string Type { get; set; }
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "Directory")]
|
||||
public class Directory1
|
||||
{
|
||||
[XmlElement(ElementName = "Genre")]
|
||||
public List<Genre> Genre { get; set; }
|
||||
[XmlElement(ElementName = "Role")]
|
||||
public List<Role> Role { get; set; }
|
||||
[XmlAttribute(AttributeName = "allowSync")]
|
||||
public string AllowSync { get; set; }
|
||||
[XmlAttribute(AttributeName = "librarySectionID")]
|
||||
public string LibrarySectionID { get; set; }
|
||||
[XmlAttribute(AttributeName = "librarySectionTitle")]
|
||||
public string LibrarySectionTitle { get; set; }
|
||||
[XmlAttribute(AttributeName = "librarySectionUUID")]
|
||||
public string LibrarySectionUUID { get; set; }
|
||||
[XmlAttribute(AttributeName = "personal")]
|
||||
public string Personal { get; set; }
|
||||
[XmlAttribute(AttributeName = "sourceTitle")]
|
||||
public string SourceTitle { get; set; }
|
||||
[XmlAttribute(AttributeName = "ratingKey")]
|
||||
public string RatingKey { get; set; }
|
||||
[XmlAttribute(AttributeName = "key")]
|
||||
public string Key { get; set; }
|
||||
[XmlAttribute(AttributeName = "studio")]
|
||||
public string Studio { get; set; }
|
||||
[XmlAttribute(AttributeName = "type")]
|
||||
public string Type { get; set; }
|
||||
[XmlAttribute(AttributeName = "title")]
|
||||
public string Title { get; set; }
|
||||
[XmlAttribute(AttributeName = "contentRating")]
|
||||
public string ContentRating { get; set; }
|
||||
[XmlAttribute(AttributeName = "summary")]
|
||||
public string Summary { get; set; }
|
||||
[XmlAttribute(AttributeName = "index")]
|
||||
public string Index { get; set; }
|
||||
[XmlAttribute(AttributeName = "rating")]
|
||||
public string Rating { get; set; }
|
||||
[XmlAttribute(AttributeName = "viewCount")]
|
||||
public string ViewCount { get; set; }
|
||||
[XmlAttribute(AttributeName = "lastViewedAt")]
|
||||
public string LastViewedAt { get; set; }
|
||||
[XmlAttribute(AttributeName = "year")]
|
||||
public string Year { get; set; }
|
||||
[XmlAttribute(AttributeName = "thumb")]
|
||||
public string Thumb { get; set; }
|
||||
[XmlAttribute(AttributeName = "art")]
|
||||
public string Art { get; set; }
|
||||
[XmlAttribute(AttributeName = "banner")]
|
||||
public string Banner { get; set; }
|
||||
[XmlAttribute(AttributeName = "theme")]
|
||||
public string Theme { get; set; }
|
||||
[XmlAttribute(AttributeName = "duration")]
|
||||
public string Duration { get; set; }
|
||||
[XmlAttribute(AttributeName = "originallyAvailableAt")]
|
||||
public string OriginallyAvailableAt { get; set; }
|
||||
[XmlAttribute(AttributeName = "leafCount")]
|
||||
public string LeafCount { get; set; }
|
||||
[XmlAttribute(AttributeName = "viewedLeafCount")]
|
||||
public string ViewedLeafCount { get; set; }
|
||||
[XmlAttribute(AttributeName = "childCount")]
|
||||
public string ChildCount { get; set; }
|
||||
[XmlAttribute(AttributeName = "addedAt")]
|
||||
public string AddedAt { get; set; }
|
||||
[XmlAttribute(AttributeName = "updatedAt")]
|
||||
public string UpdatedAt { get; set; }
|
||||
}
|
||||
|
||||
|
||||
[XmlRoot(ElementName = "MediaContainer")]
|
||||
public class PlexSearch
|
||||
{
|
||||
[XmlElement(ElementName = "Directory")]
|
||||
public Directory1 Directory { get; set; }
|
||||
[XmlElement(ElementName = "Video")]
|
||||
public List<Video> Video { get; set; }
|
||||
[XmlElement(ElementName = "Provider")]
|
||||
|
|
|
@ -46,9 +46,11 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Movie\CouchPotatoAdd.cs" />
|
||||
<Compile Include="Movie\CouchPotatoProfiles.cs" />
|
||||
<Compile Include="Movie\CouchPotatoStatus.cs" />
|
||||
<Compile Include="Notifications\PushbulletPush.cs" />
|
||||
<Compile Include="Notifications\PushbulletResponse.cs" />
|
||||
<Compile Include="Plex\PlexAccount.cs" />
|
||||
<Compile Include="Plex\PlexAuthentication.cs" />
|
||||
<Compile Include="Plex\PlexError.cs" />
|
||||
<Compile Include="Plex\PlexFriends.cs" />
|
||||
|
@ -56,10 +58,15 @@
|
|||
<Compile Include="Plex\PlexStatus.cs" />
|
||||
<Compile Include="Plex\PlexUserRequest.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SickRage\SickRagePing.cs" />
|
||||
<Compile Include="SickRage\SickRageStatus.cs" />
|
||||
<Compile Include="SickRage\SickRageTvAdd.cs" />
|
||||
<Compile Include="Sonarr\SonarrAddSeries.cs" />
|
||||
<Compile Include="Sonarr\SonarrProfile.cs" />
|
||||
<Compile Include="Sonarr\SystemStatus.cs" />
|
||||
<Compile Include="Tv\Authentication.cs" />
|
||||
<Compile Include="Tv\TvMazeSearch.cs" />
|
||||
<Compile Include="Tv\TVMazeShow.cs" />
|
||||
<Compile Include="Tv\TvSearchResult.cs" />
|
||||
<Compile Include="Tv\TvShow.cs" />
|
||||
<Compile Include="Tv\TvShowImages.cs" />
|
||||
|
|
40
PlexRequests.Api.Models/SickRage/SickRagePing.cs
Normal file
40
PlexRequests.Api.Models/SickRage/SickRagePing.cs
Normal file
|
@ -0,0 +1,40 @@
|
|||
#region Copyright
|
||||
// /************************************************************************
|
||||
// Copyright (c) 2016 Jamie Rees
|
||||
// File: SickRagePing.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.SickRage
|
||||
{
|
||||
public class SickRagePingData
|
||||
{
|
||||
public int pid { get; set; }
|
||||
}
|
||||
|
||||
public class SickRagePing
|
||||
{
|
||||
public SickRagePingData data { get; set; }
|
||||
public string message { get; set; }
|
||||
public string result { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
#region Copyright
|
||||
// /************************************************************************
|
||||
// Copyright (c) 2016 Jamie Rees
|
||||
// File: SettingsModel.cs
|
||||
// File: SickRageStatus.cs
|
||||
// Created By: Jamie Rees
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
|
@ -24,15 +24,12 @@
|
|||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
// ************************************************************************/
|
||||
#endregion
|
||||
using Dapper.Contrib.Extensions;
|
||||
|
||||
namespace PlexRequests.Store
|
||||
namespace PlexRequests.Api.Models.SickRage
|
||||
{
|
||||
[Table("Settings")]
|
||||
public class SettingsModel : Entity
|
||||
public static class SickRageStatus
|
||||
{
|
||||
public int Port { get; set; }
|
||||
public bool UserAuthentication { get; set; }
|
||||
public string PlexAuthToken { get; set; }
|
||||
public const string Wanted = "wanted";
|
||||
public const string Skipped = "skipped";
|
||||
public const string Ignored = "Ignored";
|
||||
}
|
||||
}
|
||||
}
|
41
PlexRequests.Api.Models/SickRage/SickRageTvAdd.cs
Normal file
41
PlexRequests.Api.Models/SickRage/SickRageTvAdd.cs
Normal file
|
@ -0,0 +1,41 @@
|
|||
#region Copyright
|
||||
// /************************************************************************
|
||||
// Copyright (c) 2016 Jamie Rees
|
||||
// File: SickRageTvAdd.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.SickRage
|
||||
{
|
||||
public class SickRageTvAddData
|
||||
{
|
||||
public string name { get; set; }
|
||||
}
|
||||
|
||||
public class SickRageTvAdd
|
||||
{
|
||||
public SickRageTvAddData data { get; set; }
|
||||
public string message { get; set; }
|
||||
public string result { get; set; }
|
||||
}
|
||||
|
||||
}
|
27
PlexRequests.Api.Models/Tv/TVMazeShow.cs
Normal file
27
PlexRequests.Api.Models/Tv/TVMazeShow.cs
Normal file
|
@ -0,0 +1,27 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace PlexRequests.Api.Models.Tv
|
||||
{
|
||||
public class TvMazeShow
|
||||
{
|
||||
public int id { get; set; }
|
||||
public string url { get; set; }
|
||||
public string name { get; set; }
|
||||
public string type { get; set; }
|
||||
public string language { get; set; }
|
||||
public List<string> genres { get; set; }
|
||||
public string status { get; set; }
|
||||
public int runtime { get; set; }
|
||||
public string premiered { get; set; }
|
||||
public Schedule schedule { get; set; }
|
||||
public Rating rating { get; set; }
|
||||
public int weight { get; set; }
|
||||
public Network network { get; set; }
|
||||
public object webChannel { get; set; }
|
||||
public Externals externals { get; set; }
|
||||
public Image image { get; set; }
|
||||
public string summary { get; set; }
|
||||
public int updated { get; set; }
|
||||
public Links _links { get; set; }
|
||||
}
|
||||
}
|
97
PlexRequests.Api.Models/Tv/TvMazeSearch.cs
Normal file
97
PlexRequests.Api.Models/Tv/TvMazeSearch.cs
Normal file
|
@ -0,0 +1,97 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PlexRequests.Api.Models.Tv
|
||||
{
|
||||
public class Schedule
|
||||
{
|
||||
public string time { get; set; }
|
||||
public List<object> days { get; set; }
|
||||
}
|
||||
|
||||
public class Rating
|
||||
{
|
||||
public double? average { get; set; }
|
||||
}
|
||||
|
||||
public class Country
|
||||
{
|
||||
public string name { get; set; }
|
||||
public string code { get; set; }
|
||||
public string timezone { get; set; }
|
||||
}
|
||||
|
||||
public class Network
|
||||
{
|
||||
public int id { get; set; }
|
||||
public string name { get; set; }
|
||||
public Country country { get; set; }
|
||||
}
|
||||
|
||||
public class Externals
|
||||
{
|
||||
public int? tvrage { get; set; }
|
||||
public int? thetvdb { get; set; }
|
||||
public string imdb { get; set; }
|
||||
}
|
||||
|
||||
public class Image
|
||||
{
|
||||
public string medium { get; set; }
|
||||
public string original { get; set; }
|
||||
}
|
||||
|
||||
public class Self
|
||||
{
|
||||
public string href { get; set; }
|
||||
}
|
||||
|
||||
public class Previousepisode
|
||||
{
|
||||
public string href { get; set; }
|
||||
}
|
||||
|
||||
public class Nextepisode
|
||||
{
|
||||
public string href { get; set; }
|
||||
}
|
||||
|
||||
public class Links
|
||||
{
|
||||
public Self self { get; set; }
|
||||
public Previousepisode previousepisode { get; set; }
|
||||
public Nextepisode nextepisode { get; set; }
|
||||
}
|
||||
|
||||
public class Show
|
||||
{
|
||||
public int id { get; set; }
|
||||
public string url { get; set; }
|
||||
public string name { get; set; }
|
||||
public string type { get; set; }
|
||||
public string language { get; set; }
|
||||
public List<object> genres { get; set; }
|
||||
public string status { get; set; }
|
||||
public int? runtime { get; set; }
|
||||
public string premiered { get; set; }
|
||||
public Schedule schedule { get; set; }
|
||||
public Rating rating { get; set; }
|
||||
public int weight { get; set; }
|
||||
public Network network { get; set; }
|
||||
public object webChannel { get; set; }
|
||||
public Externals externals { get; set; }
|
||||
public Image image { get; set; }
|
||||
public string summary { get; set; }
|
||||
public int updated { get; set; }
|
||||
public Links _links { get; set; }
|
||||
}
|
||||
|
||||
public class TvMazeSearch
|
||||
{
|
||||
public double score { get; set; }
|
||||
public Show show { get; set; }
|
||||
}
|
||||
}
|
|
@ -98,13 +98,13 @@ namespace PlexRequests.Api
|
|||
|
||||
try
|
||||
{
|
||||
|
||||
var json = JsonConvert.DeserializeObject<T>(response.Content);
|
||||
return json;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Fatal(e);
|
||||
Log.Info(response.Content);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,9 +45,17 @@ namespace PlexRequests.Api
|
|||
private ApiRequest Api { get; set; }
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public bool AddMovie(string imdbid, string apiKey, string title, Uri baseUrl)
|
||||
public bool AddMovie(string imdbid, string apiKey, string title, Uri baseUrl, string profileId = default(string))
|
||||
{
|
||||
var request = new RestRequest { Resource = "/api/{apikey}/movie.add?title={title}&identifier={imdbid}" };
|
||||
RestRequest request;
|
||||
request = string.IsNullOrEmpty(profileId)
|
||||
? new RestRequest {Resource = "/api/{apikey}/movie.add?title={title}&identifier={imdbid}"}
|
||||
: new RestRequest { Resource = "/api/{apikey}/movie.add?title={title}&identifier={imdbid}&profile_id={profileId}" };
|
||||
|
||||
if (!string.IsNullOrEmpty(profileId))
|
||||
{
|
||||
request.AddUrlSegment("profileId", profileId);
|
||||
}
|
||||
|
||||
request.AddUrlSegment("apikey", apiKey);
|
||||
request.AddUrlSegment("imdbid", imdbid);
|
||||
|
@ -93,5 +101,19 @@ namespace PlexRequests.Api
|
|||
|
||||
return Api.Execute<CouchPotatoStatus>(request,url);
|
||||
}
|
||||
|
||||
public CouchPotatoProfiles GetProfiles(Uri url, string apiKey)
|
||||
{
|
||||
Log.Trace("Getting CP Profiles, ApiKey = {0}", apiKey);
|
||||
var request = new RestRequest
|
||||
{
|
||||
Resource = "api/{apikey}/profile.list/",
|
||||
Method = Method.GET
|
||||
};
|
||||
|
||||
request.AddUrlSegment("apikey", apiKey);
|
||||
|
||||
return Api.Execute<CouchPotatoProfiles>(request, url);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -134,6 +134,25 @@ namespace PlexRequests.Api
|
|||
|
||||
return users;
|
||||
}
|
||||
|
||||
public PlexAccount GetAccount(string authToken)
|
||||
{
|
||||
var request = new RestRequest
|
||||
{
|
||||
Method = Method.GET,
|
||||
};
|
||||
|
||||
request.AddHeader("X-Plex-Client-Identifier", "Test213");
|
||||
request.AddHeader("X-Plex-Product", "Request Plex");
|
||||
request.AddHeader("X-Plex-Version", Version);
|
||||
request.AddHeader("X-Plex-Token", authToken);
|
||||
request.AddHeader("Content-Type", "application/xml");
|
||||
|
||||
var api = new ApiRequest();
|
||||
var account = api.ExecuteXml<PlexAccount>(request, new Uri("https://plex.tv/users/account"));
|
||||
|
||||
return account;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
</Compile>
|
||||
<Compile Include="Mocks\MockSonarrApi.cs" />
|
||||
<Compile Include="PushbulletApi.cs" />
|
||||
<Compile Include="SickrageApi.cs" />
|
||||
<Compile Include="SonarrApi.cs" />
|
||||
<Compile Include="CouchPotatoApi.cs" />
|
||||
<Compile Include="MovieBase.cs" />
|
||||
|
@ -81,6 +82,8 @@
|
|||
<Compile Include="TvBase.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="TheTvDbApi.cs" />
|
||||
<Compile Include="TvMazeApi.cs" />
|
||||
<Compile Include="TvMazeBase.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
|
|
91
PlexRequests.Api/SickrageApi.cs
Normal file
91
PlexRequests.Api/SickrageApi.cs
Normal file
|
@ -0,0 +1,91 @@
|
|||
#region Copyright
|
||||
|
||||
// /************************************************************************
|
||||
// Copyright (c) 2016 Jamie Rees
|
||||
// File: CouchPotatoApi.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 NLog;
|
||||
using PlexRequests.Api.Interfaces;
|
||||
using PlexRequests.Api.Models.SickRage;
|
||||
using RestSharp;
|
||||
|
||||
namespace PlexRequests.Api
|
||||
{
|
||||
public class SickrageApi : ISickRageApi
|
||||
{
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public SickrageApi()
|
||||
{
|
||||
Api = new ApiRequest();
|
||||
}
|
||||
|
||||
private ApiRequest Api { get; }
|
||||
|
||||
|
||||
public SickRageTvAdd AddSeries(int tvdbId, bool latest, string quality, string apiKey,
|
||||
Uri baseUrl)
|
||||
{
|
||||
string status;
|
||||
var futureStatus = SickRageStatus.Wanted;
|
||||
|
||||
status = latest ? SickRageStatus.Skipped : SickRageStatus.Wanted;
|
||||
|
||||
var request = new RestRequest
|
||||
{
|
||||
Resource = "/api/{apiKey}/?cmd=show.addnew",
|
||||
Method = Method.GET
|
||||
};
|
||||
request.AddUrlSegment("apiKey", apiKey);
|
||||
request.AddQueryParameter("tvdbid", tvdbId.ToString());
|
||||
request.AddQueryParameter("status", status);
|
||||
request.AddQueryParameter("future_status", futureStatus);
|
||||
if (!quality.Equals("default", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
request.AddQueryParameter("initial", quality);
|
||||
}
|
||||
|
||||
var obj = Api.Execute<SickRageTvAdd>(request, baseUrl);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
public SickRagePing Ping(string apiKey, Uri baseUrl)
|
||||
{
|
||||
var request = new RestRequest
|
||||
{
|
||||
Resource = "/api/{apiKey}/?cmd=sb.ping",
|
||||
Method = Method.GET
|
||||
};
|
||||
|
||||
request.AddUrlSegment("apiKey", apiKey);
|
||||
var obj = Api.ExecuteJson<SickRagePing>(request, baseUrl);
|
||||
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
}
|
86
PlexRequests.Api/TvMazeApi.cs
Normal file
86
PlexRequests.Api/TvMazeApi.cs
Normal file
|
@ -0,0 +1,86 @@
|
|||
#region Copyright
|
||||
// /************************************************************************
|
||||
// Copyright (c) 2016 Jamie Rees
|
||||
// File: TvMazeApi.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 NLog;
|
||||
|
||||
using PlexRequests.Api.Models.Tv;
|
||||
|
||||
using RestSharp;
|
||||
|
||||
namespace PlexRequests.Api
|
||||
{
|
||||
public class TvMazeApi : TvMazeBase
|
||||
{
|
||||
public TvMazeApi()
|
||||
{
|
||||
Api = new ApiRequest();
|
||||
}
|
||||
private ApiRequest Api { get; }
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
public List<TvMazeSearch> Search(string searchTerm)
|
||||
{
|
||||
var request = new RestRequest
|
||||
{
|
||||
Method = Method.GET,
|
||||
Resource = "search/shows?q={searchTerm}"
|
||||
};
|
||||
request.AddUrlSegment("searchTerm", searchTerm);
|
||||
request.AddHeader("Content-Type", "application/json");
|
||||
|
||||
return Api.Execute<List<TvMazeSearch>>(request, new Uri(Uri));
|
||||
}
|
||||
|
||||
public TvMazeShow ShowLookup(int showId)
|
||||
{
|
||||
var request = new RestRequest
|
||||
{
|
||||
Method = Method.GET,
|
||||
Resource = "shows/{id}"
|
||||
};
|
||||
request.AddUrlSegment("id", showId.ToString());
|
||||
request.AddHeader("Content-Type", "application/json");
|
||||
|
||||
return Api.Execute<TvMazeShow>(request, new Uri(Uri));
|
||||
}
|
||||
|
||||
public TvMazeShow ShowLookupByTheTvDbId(int theTvDbId)
|
||||
{
|
||||
var request = new RestRequest
|
||||
{
|
||||
Method = Method.GET,
|
||||
Resource = "lookup/shows?thetvdb={id}"
|
||||
};
|
||||
request.AddUrlSegment("id", theTvDbId.ToString());
|
||||
request.AddHeader("Content-Type", "application/json");
|
||||
|
||||
return Api.Execute<TvMazeShow>(request, new Uri(Uri));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
33
PlexRequests.Api/TvMazeBase.cs
Normal file
33
PlexRequests.Api/TvMazeBase.cs
Normal file
|
@ -0,0 +1,33 @@
|
|||
#region Copyright
|
||||
// /************************************************************************
|
||||
// Copyright (c) 2016 Jamie Rees
|
||||
// File: TvMazeBase.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
|
||||
{
|
||||
public class TvMazeBase
|
||||
{
|
||||
protected string Uri = "http://api.tvmaze.com";
|
||||
}
|
||||
}
|
|
@ -34,6 +34,7 @@ namespace PlexRequests.Core.Tests
|
|||
public class StatusCheckerTests
|
||||
{
|
||||
[Test]
|
||||
[Ignore("API Limit")]
|
||||
public void CheckStatusTest()
|
||||
{
|
||||
var checker = new StatusChecker();
|
||||
|
@ -42,4 +43,4 @@ namespace PlexRequests.Core.Tests
|
|||
Assert.That(status, Is.Not.Null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,10 +32,10 @@ namespace PlexRequests.Core
|
|||
{
|
||||
public interface IRequestService
|
||||
{
|
||||
long AddRequest(int providerId, RequestedModel model);
|
||||
long AddRequest(RequestedModel model);
|
||||
bool CheckRequest(int providerId);
|
||||
void DeleteRequest(int tmdbId);
|
||||
void UpdateRequest(RequestedModel model);
|
||||
void DeleteRequest(RequestedModel request);
|
||||
bool UpdateRequest(RequestedModel model);
|
||||
RequestedModel Get(int id);
|
||||
IEnumerable<RequestedModel> GetAll();
|
||||
bool BatchUpdate(List<RequestedModel> model);
|
||||
|
|
|
@ -42,11 +42,18 @@ namespace PlexRequests.Core
|
|||
Repo = repo;
|
||||
}
|
||||
private IRequestRepository Repo { get; }
|
||||
public long AddRequest(int providerId, RequestedModel model)
|
||||
public long AddRequest(RequestedModel model)
|
||||
{
|
||||
var entity = new RequestBlobs { Type = model.Type, Content = ReturnBytes(model), ProviderId = model.ProviderId};
|
||||
var entity = new RequestBlobs { Type = model.Type, Content = ReturnBytes(model), ProviderId = model.ProviderId };
|
||||
var id = Repo.Insert(entity);
|
||||
|
||||
return Repo.Insert(entity);
|
||||
// TODO Keep an eye on this, since we are now doing 2 DB update for 1 single request, inserting and then updating
|
||||
model.Id = (int)id;
|
||||
|
||||
entity = new RequestBlobs { Type = model.Type, Content = ReturnBytes(model), ProviderId = model.ProviderId, Id = (int)id };
|
||||
var result = Repo.Update(entity);
|
||||
|
||||
return result ? id : -1;
|
||||
}
|
||||
|
||||
public bool CheckRequest(int providerId)
|
||||
|
@ -55,16 +62,16 @@ namespace PlexRequests.Core
|
|||
return blobs.Any(x => x.ProviderId == providerId);
|
||||
}
|
||||
|
||||
public void DeleteRequest(int tmdbId)
|
||||
public void DeleteRequest(RequestedModel request)
|
||||
{
|
||||
var blob = Repo.GetAll().FirstOrDefault(x => x.ProviderId == tmdbId);
|
||||
var blob = Repo.Get(request.Id);
|
||||
Repo.Delete(blob);
|
||||
}
|
||||
|
||||
public void UpdateRequest(RequestedModel model)
|
||||
public bool UpdateRequest(RequestedModel model)
|
||||
{
|
||||
var entity = new RequestBlobs { Type = model.Type, Content = ReturnBytes(model), ProviderId = model.ProviderId, Id = model.Id};
|
||||
Repo.Update(entity);
|
||||
var entity = new RequestBlobs { Type = model.Type, Content = ReturnBytes(model), ProviderId = model.ProviderId, Id = model.Id };
|
||||
return Repo.Update(entity);
|
||||
}
|
||||
|
||||
public RequestedModel Get(int id)
|
||||
|
@ -85,7 +92,7 @@ namespace PlexRequests.Core
|
|||
|
||||
public bool BatchUpdate(List<RequestedModel> model)
|
||||
{
|
||||
var entities = model.Select(m => new RequestBlobs { Type = m.Type, Content = ReturnBytes(m), ProviderId = m.ProviderId }).ToList();
|
||||
var entities = model.Select(m => new RequestBlobs { Type = m.Type, Content = ReturnBytes(m), ProviderId = m.ProviderId, Id = m.Id }).ToList();
|
||||
return Repo.UpdateAll(entities);
|
||||
}
|
||||
|
||||
|
|
|
@ -94,6 +94,10 @@
|
|||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\PlexRequests.Api.Models\PlexRequests.Api.Models.csproj">
|
||||
<Project>{CB37A5F8-6DFC-4554-99D3-A42B502E4591}</Project>
|
||||
<Name>PlexRequests.Api.Models</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\PlexRequests.Api\PlexRequests.Api.csproj">
|
||||
<Project>{8CB8D235-2674-442D-9C6A-35FCAEEB160D}</Project>
|
||||
<Name>PlexRequests.Api</Name>
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace PlexRequests.Core
|
|||
|
||||
private IRepository<RequestedModel> Repo { get; set; }
|
||||
|
||||
public long AddRequest(int providerId, RequestedModel model)
|
||||
public long AddRequest(RequestedModel model)
|
||||
{
|
||||
return Repo.Insert(model);
|
||||
}
|
||||
|
@ -50,16 +50,15 @@ namespace PlexRequests.Core
|
|||
return Repo.GetAll().Any(x => x.ProviderId == providerId);
|
||||
}
|
||||
|
||||
public void DeleteRequest(int tmdbId)
|
||||
public void DeleteRequest(RequestedModel model)
|
||||
{
|
||||
var entity = Repo.GetAll().FirstOrDefault(x => x.ProviderId == tmdbId);
|
||||
var entity = Repo.Get(model.Id);
|
||||
Repo.Delete(entity);
|
||||
}
|
||||
|
||||
public void UpdateRequest(RequestedModel model)
|
||||
public bool UpdateRequest(RequestedModel model)
|
||||
{
|
||||
|
||||
Repo.Update(model);
|
||||
return Repo.Update(model);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -36,13 +36,15 @@ namespace PlexRequests.Core.SettingModels
|
|||
public string Ip { get; set; }
|
||||
public int Port { get; set; }
|
||||
public string ApiKey { get; set; }
|
||||
public bool Ssl { get; set; }
|
||||
public string ProfileId { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public Uri FullUri
|
||||
{
|
||||
get
|
||||
{
|
||||
var formatted = Ip.ReturnUri(Port);
|
||||
var formatted = Ip.ReturnUri(Port, Ssl);
|
||||
return formatted;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,13 +24,30 @@
|
|||
// 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 SickRageSettings : Settings
|
||||
{
|
||||
public bool Enabled { get; set; }
|
||||
public string Ip { get; set; }
|
||||
public int Port { get; set; }
|
||||
public string ApiKey { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
public string QualityProfile { get; set; }
|
||||
public bool Ssl { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public Uri FullUri
|
||||
{
|
||||
get
|
||||
{
|
||||
var formatted = Ip.ReturnUri(Port, Ssl);
|
||||
return formatted;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -33,19 +33,21 @@ namespace PlexRequests.Core.SettingModels
|
|||
{
|
||||
public class SonarrSettings : Settings
|
||||
{
|
||||
public bool Enabled { get; set; }
|
||||
public string Ip { get; set; }
|
||||
public int Port { get; set; }
|
||||
public string ApiKey { get; set; }
|
||||
public string QualityProfile { get; set; }
|
||||
public bool SeasonFolders { get; set; }
|
||||
public string RootPath { get; set; }
|
||||
public bool Ssl { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public Uri FullUri
|
||||
{
|
||||
get
|
||||
{
|
||||
var formatted = Ip.ReturnUri(Port);
|
||||
var formatted = Ip.ReturnUri(Port, Ssl);
|
||||
return formatted;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,13 @@
|
|||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
// ************************************************************************/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Mono.Data.Sqlite;
|
||||
using PlexRequests.Api;
|
||||
using PlexRequests.Core.SettingModels;
|
||||
using PlexRequests.Helpers;
|
||||
using PlexRequests.Store;
|
||||
|
@ -46,6 +52,7 @@ namespace PlexRequests.Core
|
|||
CreateDefaultSettingsPage();
|
||||
}
|
||||
|
||||
MigrateDb();
|
||||
return Db.DbConnection().ConnectionString;
|
||||
}
|
||||
|
||||
|
@ -63,5 +70,82 @@ namespace PlexRequests.Core
|
|||
var s = new SettingsServiceV2<PlexRequestSettings>(new SettingsJsonRepository(new DbConfiguration(new SqliteFactory()), new MemoryCacheProvider()));
|
||||
s.SaveSettings(defaultSettings);
|
||||
}
|
||||
|
||||
private void MigrateDb() // TODO: Remove when no longer needed
|
||||
{
|
||||
var result = new List<long>();
|
||||
RequestedModel[] requestedModels;
|
||||
var repo = new GenericRepository<RequestedModel>(Db);
|
||||
try
|
||||
{
|
||||
var records = repo.GetAll();
|
||||
requestedModels = records as RequestedModel[] ?? records.ToArray();
|
||||
}
|
||||
catch (SqliteException)
|
||||
{
|
||||
// There is no requested table so they do not have an old version of the DB
|
||||
return;
|
||||
}
|
||||
|
||||
if (!requestedModels.Any())
|
||||
{ return; }
|
||||
|
||||
var jsonRepo = new JsonRequestService(new RequestJsonRepository(Db, new MemoryCacheProvider()));
|
||||
|
||||
var api = new TvMazeApi();
|
||||
|
||||
foreach (var r in requestedModels.Where(x => x.Type == RequestType.TvShow))
|
||||
{
|
||||
var show = api.ShowLookupByTheTvDbId(r.ProviderId);
|
||||
|
||||
var model = new RequestedModel
|
||||
{
|
||||
Title = show.name,
|
||||
PosterPath = show.image?.medium,
|
||||
Type = RequestType.TvShow,
|
||||
ProviderId = show.externals.thetvdb ?? 0,
|
||||
ReleaseDate = r.ReleaseDate,
|
||||
AdminNote = r.AdminNote,
|
||||
Approved = r.Approved,
|
||||
Available = r.Available,
|
||||
ImdbId = show.externals.imdb,
|
||||
Issues = r.Issues,
|
||||
LatestTv = r.LatestTv,
|
||||
OtherMessage = r.OtherMessage,
|
||||
Overview = show.summary.RemoveHtml(),
|
||||
RequestedBy = r.RequestedBy,
|
||||
RequestedDate = r.ReleaseDate,
|
||||
Status = show.status
|
||||
};
|
||||
var id = jsonRepo.AddRequest(model);
|
||||
result.Add(id);
|
||||
}
|
||||
|
||||
foreach (var source in requestedModels.Where(x => x.Type== RequestType.Movie))
|
||||
{
|
||||
var id = jsonRepo.AddRequest(source);
|
||||
result.Add(id);
|
||||
}
|
||||
|
||||
|
||||
if (result.Any(x => x == -1))
|
||||
{
|
||||
throw new SqliteException("Could not migrate the DB!");
|
||||
}
|
||||
|
||||
|
||||
if (result.Count != requestedModels.Length)
|
||||
{
|
||||
throw new SqliteException("Could not migrate the DB! count is different");
|
||||
}
|
||||
|
||||
|
||||
// Now delete the old requests
|
||||
foreach (var oldRequest in requestedModels)
|
||||
{
|
||||
repo.Delete(oldRequest);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
56
PlexRequests.Helpers.Tests/HtmlRemoverTests.cs
Normal file
56
PlexRequests.Helpers.Tests/HtmlRemoverTests.cs
Normal file
|
@ -0,0 +1,56 @@
|
|||
#region Copyright
|
||||
|
||||
// /************************************************************************
|
||||
// Copyright (c) 2016 Jamie Rees
|
||||
// File: HtmlRemoverTests.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 NUnit.Framework;
|
||||
|
||||
namespace PlexRequests.Helpers.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class HtmlRemoverTests
|
||||
{
|
||||
[Test]
|
||||
public void RemoveHtmlBasic()
|
||||
{
|
||||
var html = "this is <b>bold</b> <p>para</p> OK!";
|
||||
var result = html.RemoveHtml();
|
||||
Assert.That(result, Is.Not.Null);
|
||||
Assert.That(result, Is.EqualTo("this is bold para OK!"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RemoveHtmlMoreTags()
|
||||
{
|
||||
// Good 'ol Ali G ;)
|
||||
var html = "<p><strong><em>\"Ali G: Rezurection\"</em></strong> includes every episode of <em>Da Ali G Show</em> with new, original introductions by star, creator/writer Sacha Baron Cohen, along with the BAFTA(R) Award-winning English episodes of <em>Da Ali G Show</em> which have never aired on American television and <em>The Best of Ali G</em>.</p>";
|
||||
var result = html.RemoveHtml();
|
||||
Assert.That(result, Is.Not.Null);
|
||||
Assert.That(result, Is.EqualTo("\"Ali G: Rezurection\" includes every episode of Da Ali G Show with new, original introductions by star, creator/writer Sacha Baron Cohen, along with the BAFTA(R) Award-winning English episodes of Da Ali G Show which have never aired on American television and The Best of Ali G."));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -70,6 +70,7 @@
|
|||
</Otherwise>
|
||||
</Choose>
|
||||
<ItemGroup>
|
||||
<Compile Include="HtmlRemoverTests.cs" />
|
||||
<Compile Include="AssemblyHelperTests.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="UriHelperTests.cs" />
|
||||
|
|
45
PlexRequests.Helpers/HtmlRemover.cs
Normal file
45
PlexRequests.Helpers/HtmlRemover.cs
Normal file
|
@ -0,0 +1,45 @@
|
|||
#region Copyright
|
||||
// /************************************************************************
|
||||
// Copyright (c) 2016 Jamie Rees
|
||||
// File: HtmlRemover.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.Text.RegularExpressions;
|
||||
|
||||
namespace PlexRequests.Helpers
|
||||
{
|
||||
public static class HtmlRemover
|
||||
{
|
||||
public static string RemoveHtml(this string value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
var step1 = Regex.Replace(value, @"<[^>]+>| ", "").Trim();
|
||||
var step2 = Regex.Replace(step1, @"\s{2,}", " ");
|
||||
return step2;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -48,6 +48,7 @@
|
|||
<ItemGroup>
|
||||
<Compile Include="AssemblyHelper.cs" />
|
||||
<Compile Include="Exceptions\ApplicationSettingsException.cs" />
|
||||
<Compile Include="HtmlRemover.cs" />
|
||||
<Compile Include="ICacheProvider.cs" />
|
||||
<Compile Include="LoggingHelper.cs" />
|
||||
<Compile Include="MemoryCacheProvider.cs" />
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace PlexRequests.Services.Tests
|
|||
var plexMock = new Mock<IPlexApi>();
|
||||
Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object);
|
||||
|
||||
Assert.Throws<ApplicationSettingsException>(() => Checker.IsAvailable("title"), "We should be throwing an exception since we cannot talk to the services.");
|
||||
Assert.Throws<ApplicationSettingsException>(() => Checker.IsAvailable("title", "2013"), "We should be throwing an exception since we cannot talk to the services.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -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" } } };
|
||||
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" });
|
||||
|
@ -74,7 +74,28 @@ namespace PlexRequests.Services.Tests
|
|||
|
||||
Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object);
|
||||
|
||||
var result = Checker.IsAvailable("title");
|
||||
var result = Checker.IsAvailable("title", "2011");
|
||||
|
||||
Assert.That(result, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsAvailableDirectoryTitleTest()
|
||||
{
|
||||
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", Year = "2013"} };
|
||||
|
||||
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", "2013");
|
||||
|
||||
Assert.That(result, Is.True);
|
||||
}
|
||||
|
@ -87,7 +108,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 title" } } };
|
||||
var searchResult = new PlexSearch { Video = new List<Video> { new Video { Title = "wrong tistle", Year = "2011"} } };
|
||||
|
||||
settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
||||
authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "abc" });
|
||||
|
@ -95,7 +116,28 @@ namespace PlexRequests.Services.Tests
|
|||
|
||||
Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object);
|
||||
|
||||
var result = Checker.IsAvailable("title");
|
||||
var result = Checker.IsAvailable("title", "2011");
|
||||
|
||||
Assert.That(result, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsYearDoesNotMatchTest()
|
||||
{
|
||||
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 = "title", 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", "2011");
|
||||
|
||||
Assert.That(result, Is.False);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,6 @@ namespace PlexRequests.Services.Interfaces
|
|||
public interface IAvailabilityChecker
|
||||
{
|
||||
void CheckAndUpdateAll(long check);
|
||||
bool IsAvailable(string title);
|
||||
bool IsAvailable(string title, string year);
|
||||
}
|
||||
}
|
|
@ -85,9 +85,10 @@ namespace PlexRequests.Services
|
|||
/// Determines whether the specified search term is available.
|
||||
/// </summary>
|
||||
/// <param name="title">The search term.</param>
|
||||
/// <param name="year">The year.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ApplicationSettingsException">The settings are not configured for Plex or Authentication</exception>
|
||||
public bool IsAvailable(string title)
|
||||
public bool IsAvailable(string title, string year)
|
||||
{
|
||||
var plexSettings = Plex.GetSettings();
|
||||
var authSettings = Auth.GetSettings();
|
||||
|
@ -96,10 +97,21 @@ namespace PlexRequests.Services
|
|||
{
|
||||
throw new ApplicationSettingsException("The settings are not configured for Plex or Authentication");
|
||||
}
|
||||
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 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 directoryTitle = results.Directory?.Title == title;
|
||||
return result?.Title != null || directoryTitle;
|
||||
}
|
||||
|
||||
var results = PlexApi.SearchContent(authSettings.PlexAuthToken, title, plexSettings.FullUri);
|
||||
var result = results.Video.FirstOrDefault(x => x.Title == title);
|
||||
return result?.Title != null;
|
||||
}
|
||||
|
||||
private bool ValidateSettings(PlexSettings plex, AuthenticationSettings auth, IEnumerable<RequestedModel> requests)
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Dapper.Contrib, Version=1.40.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Dapper.Contrib.1.42\lib\net45\Dapper.Contrib.dll</HintPath>
|
||||
<HintPath>..\packages\Dapper.Contrib.1.43\lib\net45\Dapper.Contrib.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Mono.Data.Sqlite">
|
||||
|
@ -68,7 +68,6 @@
|
|||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Repository\SettingsJsonRepository.cs" />
|
||||
<Compile Include="Repository\RequestJsonRepository.cs" />
|
||||
<Compile Include="SettingsModel.cs" />
|
||||
<Compile Include="GenericRepository.cs" />
|
||||
<Compile Include="RequestedModel.cs" />
|
||||
<Compile Include="UserRepository.cs" />
|
||||
|
|
|
@ -53,7 +53,8 @@ namespace PlexRequests.Store.Repository
|
|||
ResetCache();
|
||||
using (var con = Db.DbConnection())
|
||||
{
|
||||
return con.Insert(entity);
|
||||
var id = con.Insert(entity);
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,7 +74,7 @@ namespace PlexRequests.Store.Repository
|
|||
|
||||
public RequestBlobs Get(int id)
|
||||
{
|
||||
var key = TypeName + "Get";
|
||||
var key = TypeName + "Get" + id;
|
||||
var item = Cache.GetOrSet(key, () =>
|
||||
{
|
||||
using (var con = Db.DbConnection())
|
||||
|
@ -111,8 +112,8 @@ namespace PlexRequests.Store.Repository
|
|||
|
||||
public bool UpdateAll(IEnumerable<RequestBlobs> entity)
|
||||
{
|
||||
ResetCache();
|
||||
var result = new HashSet<bool>();
|
||||
|
||||
using (var db = Db.DbConnection())
|
||||
{
|
||||
db.Open();
|
||||
|
|
|
@ -8,36 +8,6 @@ CREATE TABLE IF NOT EXISTS User
|
|||
Password varchar(100) NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Settings
|
||||
(
|
||||
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
Port INTEGER NOT NULL,
|
||||
UserAuthentication INTEGER NOT NULL,
|
||||
PlexAuthToken varchar(50)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Requested
|
||||
(
|
||||
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
Type INTEGER NOT NULL,
|
||||
ProviderId INTEGER NOT NULL,
|
||||
ImdbId varchar(50),
|
||||
Overview varchar(50),
|
||||
Title varchar(50) NOT NULL,
|
||||
PosterPath varchar(50) NOT NULL,
|
||||
ReleaseDate varchar(50) NOT NULL,
|
||||
Status varchar(50) NOT NULL,
|
||||
AdminNote varchar(50),
|
||||
Approved INTEGER NOT NULL,
|
||||
LatestTv INTEGER NOT NULL,
|
||||
RequestedBy varchar(50),
|
||||
RequestedDate varchar(50) NOT NULL,
|
||||
Available INTEGER(50),
|
||||
Issues INTEGER,
|
||||
OtherMessage varchar(50)
|
||||
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS GlobalSettings
|
||||
(
|
||||
|
@ -65,4 +35,4 @@ CREATE TABLE IF NOT EXISTS Log
|
|||
Message varchar(100) NOT NULL,
|
||||
CallSite varchar(100) NOT NULL,
|
||||
Exception varchar(100) NOT NULL
|
||||
);
|
||||
);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Dapper" version="1.42" targetFramework="net452" />
|
||||
<package id="Dapper.Contrib" version="1.42" targetFramework="net452" />
|
||||
<package id="Dapper.Contrib" version="1.43" targetFramework="net46" />
|
||||
<package id="NLog" version="4.2.3" targetFramework="net452" />
|
||||
</packages>
|
|
@ -52,11 +52,13 @@ namespace PlexRequests.UI.Tests
|
|||
private Mock<ISettingsService<AuthenticationSettings>> AuthMock { get; set; }
|
||||
private Mock<ISettingsService<PlexSettings>> PlexSettingsMock { get; set; }
|
||||
private Mock<ISettingsService<SonarrSettings>> SonarrSettingsMock { get; set; }
|
||||
private Mock<ISettingsService<SickRageSettings>> SickRageSettingsMock { get; set; }
|
||||
private Mock<ISettingsService<EmailNotificationSettings>> EmailMock { get; set; }
|
||||
private Mock<ISettingsService<PushbulletNotificationSettings>> PushbulletSettings { get; set; }
|
||||
private Mock<IPlexApi> PlexMock { get; set; }
|
||||
private Mock<ISonarrApi> SonarrApiMock { get; set; }
|
||||
private Mock<IPushbulletApi> PushbulletApi { get; set; }
|
||||
private Mock<ICouchPotatoApi> CpApi { get; set; }
|
||||
|
||||
private ConfigurableBootstrapper Bootstrapper { get; set; }
|
||||
|
||||
|
@ -79,6 +81,8 @@ namespace PlexRequests.UI.Tests
|
|||
EmailMock = new Mock<ISettingsService<EmailNotificationSettings>>();
|
||||
PushbulletApi = new Mock<IPushbulletApi>();
|
||||
PushbulletSettings = new Mock<ISettingsService<PushbulletNotificationSettings>>();
|
||||
CpApi = new Mock<ICouchPotatoApi>();
|
||||
SickRageSettingsMock = new Mock<ISettingsService<SickRageSettings>>();
|
||||
|
||||
Bootstrapper = new ConfigurableBootstrapper(with =>
|
||||
{
|
||||
|
@ -93,6 +97,8 @@ namespace PlexRequests.UI.Tests
|
|||
with.Dependency(EmailMock.Object);
|
||||
with.Dependency(PushbulletApi.Object);
|
||||
with.Dependency(PushbulletSettings.Object);
|
||||
with.Dependency(CpApi.Object);
|
||||
with.Dependency(SickRageSettingsMock.Object);
|
||||
with.RootPathProvider<TestRootPathProvider>();
|
||||
with.RequestStartup((container, pipelines, context) =>
|
||||
{
|
||||
|
|
|
@ -36,7 +36,6 @@ using Newtonsoft.Json;
|
|||
using NUnit.Framework;
|
||||
|
||||
using PlexRequests.Api.Interfaces;
|
||||
using PlexRequests.Api.Models;
|
||||
using PlexRequests.Api.Models.Plex;
|
||||
using PlexRequests.Core;
|
||||
using PlexRequests.Core.SettingModels;
|
||||
|
@ -81,7 +80,7 @@ namespace PlexRequests.UI.Tests
|
|||
with.Header("Accept", "application/json");
|
||||
with.FormValue("Username", "abc");
|
||||
});
|
||||
|
||||
|
||||
Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
|
||||
Assert.That(result.Context.Request.Session[SessionKeys.UsernameKey], Is.EqualTo("abc"));
|
||||
|
||||
|
@ -142,6 +141,7 @@ namespace PlexRequests.UI.Tests
|
|||
|
||||
AuthMock.Setup(x => x.GetSettings()).Returns(expectedSettings);
|
||||
PlexMock.Setup(x => x.GetUsers(It.IsAny<string>())).Returns(plexFriends);
|
||||
PlexMock.Setup(x => x.GetAccount(It.IsAny<string>())).Returns(new PlexAccount());
|
||||
|
||||
var bootstrapper = new ConfigurableBootstrapper(with =>
|
||||
{
|
||||
|
@ -188,6 +188,7 @@ namespace PlexRequests.UI.Tests
|
|||
|
||||
AuthMock.Setup(x => x.GetSettings()).Returns(expectedSettings);
|
||||
PlexMock.Setup(x => x.GetUsers(It.IsAny<string>())).Returns(plexFriends);
|
||||
PlexMock.Setup(x => x.GetAccount(It.IsAny<string>())).Returns(new PlexAccount());
|
||||
|
||||
var bootstrapper = new ConfigurableBootstrapper(with =>
|
||||
{
|
||||
|
@ -245,6 +246,7 @@ namespace PlexRequests.UI.Tests
|
|||
AuthMock.Setup(x => x.GetSettings()).Returns(expectedSettings);
|
||||
PlexMock.Setup(x => x.GetUsers(It.IsAny<string>())).Returns(plexFriends);
|
||||
PlexMock.Setup(x => x.SignIn(It.IsAny<string>(), It.IsAny<string>())).Returns(plexAuth);
|
||||
PlexMock.Setup(x => x.GetAccount(It.IsAny<string>())).Returns(new PlexAccount());
|
||||
|
||||
var bootstrapper = new ConfigurableBootstrapper(with =>
|
||||
{
|
||||
|
@ -376,7 +378,7 @@ namespace PlexRequests.UI.Tests
|
|||
with.RootPathProvider<TestRootPathProvider>();
|
||||
});
|
||||
|
||||
bootstrapper.WithSession(new Dictionary<string, object> { {SessionKeys.UsernameKey, "abc"} });
|
||||
bootstrapper.WithSession(new Dictionary<string, object> { { SessionKeys.UsernameKey, "abc" } });
|
||||
|
||||
var browser = new Browser(bootstrapper);
|
||||
var result = browser.Get("/userlogin/logout", with =>
|
||||
|
@ -388,5 +390,108 @@ namespace PlexRequests.UI.Tests
|
|||
Assert.That(HttpStatusCode.SeeOther, Is.EqualTo(result.StatusCode));
|
||||
Assert.That(result.Context.Request.Session[SessionKeys.UsernameKey], Is.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LoginWithOwnerUsernameSuccessfully()
|
||||
{
|
||||
var expectedSettings = new AuthenticationSettings { UserAuthentication = true, PlexAuthToken = "abc" };
|
||||
var plexFriends = new PlexFriends
|
||||
{
|
||||
User = new[]
|
||||
{
|
||||
new UserFriends()
|
||||
}
|
||||
};
|
||||
|
||||
var account = new PlexAccount { Username = "Jamie" };
|
||||
AuthMock.Setup(x => x.GetSettings()).Returns(expectedSettings);
|
||||
PlexMock.Setup(x => x.GetUsers(It.IsAny<string>())).Returns(plexFriends);
|
||||
PlexMock.Setup(x => x.GetAccount(It.IsAny<string>())).Returns(account);
|
||||
PlexMock.Setup(x => x.SignIn(It.IsAny<string>(), It.IsAny<string>())).Returns(new PlexAuthentication { user = new User { username = "Jamie" } });
|
||||
|
||||
var bootstrapper = new ConfigurableBootstrapper(with =>
|
||||
{
|
||||
with.Module<UserLoginModule>();
|
||||
with.Dependency(AuthMock.Object);
|
||||
with.Dependency(PlexMock.Object);
|
||||
with.RootPathProvider<TestRootPathProvider>();
|
||||
});
|
||||
|
||||
bootstrapper.WithSession(new Dictionary<string, object>());
|
||||
|
||||
var browser = new Browser(bootstrapper);
|
||||
var result = browser.Post("/userlogin", with =>
|
||||
{
|
||||
with.HttpRequest();
|
||||
with.Header("Accept", "application/json");
|
||||
with.FormValue("Username", "Jamie");
|
||||
});
|
||||
|
||||
Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
|
||||
Assert.That(result.Context.Request.Session[SessionKeys.UsernameKey], Is.EqualTo("Jamie"));
|
||||
|
||||
var body = JsonConvert.DeserializeObject<JsonResponseModel>(result.Body.AsString());
|
||||
Assert.That(body.Result, Is.EqualTo(true));
|
||||
AuthMock.Verify(x => x.GetSettings(), Times.Once);
|
||||
PlexMock.Verify(x => x.SignIn(It.IsAny<string>(), It.IsAny<string>()), Times.Never);
|
||||
PlexMock.Verify(x => x.GetUsers(It.IsAny<string>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LoginWithOwnerUsernameAndPasswordSuccessfully()
|
||||
{
|
||||
var expectedSettings = new AuthenticationSettings { UserAuthentication = true, UsePassword = true, PlexAuthToken = "abc" };
|
||||
var plexFriends = new PlexFriends
|
||||
{
|
||||
User = new[]
|
||||
{
|
||||
new UserFriends()
|
||||
}
|
||||
};
|
||||
var plexAuth = new PlexAuthentication
|
||||
{
|
||||
user = new User
|
||||
{
|
||||
authentication_token = "abc",
|
||||
username = "Jamie"
|
||||
}
|
||||
};
|
||||
|
||||
var account = new PlexAccount { Username = "Jamie" };
|
||||
|
||||
AuthMock.Setup(x => x.GetSettings()).Returns(expectedSettings);
|
||||
PlexMock.Setup(x => x.GetUsers(It.IsAny<string>())).Returns(plexFriends);
|
||||
PlexMock.Setup(x => x.SignIn(It.IsAny<string>(), It.IsAny<string>())).Returns(plexAuth);
|
||||
PlexMock.Setup(x => x.GetAccount(It.IsAny<string>())).Returns(account);
|
||||
|
||||
var bootstrapper = new ConfigurableBootstrapper(with =>
|
||||
{
|
||||
with.Module<UserLoginModule>();
|
||||
with.Dependency(AuthMock.Object);
|
||||
with.Dependency(PlexMock.Object);
|
||||
with.RootPathProvider<TestRootPathProvider>();
|
||||
});
|
||||
|
||||
bootstrapper.WithSession(new Dictionary<string, object>());
|
||||
|
||||
var browser = new Browser(bootstrapper);
|
||||
var result = browser.Post("/userlogin", with =>
|
||||
{
|
||||
with.HttpRequest();
|
||||
with.Header("Accept", "application/json");
|
||||
with.FormValue("Username", "jamie");
|
||||
with.FormValue("Password", "abc");
|
||||
});
|
||||
|
||||
|
||||
Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
|
||||
Assert.That(result.Context.Request.Session[SessionKeys.UsernameKey], Is.EqualTo("jamie"));
|
||||
|
||||
var body = JsonConvert.DeserializeObject<JsonResponseModel>(result.Body.AsString());
|
||||
Assert.That(body.Result, Is.EqualTo(true));
|
||||
AuthMock.Verify(x => x.GetSettings(), Times.Once);
|
||||
PlexMock.Verify(x => x.SignIn(It.IsAny<string>(), It.IsAny<string>()), Times.Once);
|
||||
PlexMock.Verify(x => x.GetUsers(It.IsAny<string>()), Times.Never);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -62,33 +62,34 @@ namespace PlexRequests.UI
|
|||
protected override void ConfigureRequestContainer(TinyIoCContainer container, NancyContext context)
|
||||
{
|
||||
container.Register<IUserMapper, UserMapper>();
|
||||
|
||||
container.Register<ISqliteConfiguration, DbConfiguration>(new DbConfiguration(new SqliteFactory()));
|
||||
|
||||
container.Register<ISettingsRepository, SettingsJsonRepository>();
|
||||
container.Register<ICacheProvider, MemoryCacheProvider>();
|
||||
|
||||
// Settings
|
||||
container.Register<ISettingsService<PlexRequestSettings>, SettingsServiceV2<PlexRequestSettings>>();
|
||||
container.Register<ISettingsService<CouchPotatoSettings>, SettingsServiceV2<CouchPotatoSettings>>();
|
||||
container.Register<ISettingsService<AuthenticationSettings>, SettingsServiceV2<AuthenticationSettings>>();
|
||||
container.Register<ISettingsService<PlexSettings>, SettingsServiceV2<PlexSettings>>();
|
||||
container.Register<ISettingsService<SonarrSettings>, SettingsServiceV2<SonarrSettings>>();
|
||||
container.Register<ISettingsService<SickRageSettings>, SettingsServiceV2<SickRageSettings>>();
|
||||
container.Register<ISettingsService<EmailNotificationSettings>, SettingsServiceV2<EmailNotificationSettings>>();
|
||||
container.Register<ISettingsService<PushbulletNotificationSettings>, SettingsServiceV2<PushbulletNotificationSettings>>();
|
||||
container.Register<IRepository<RequestedModel>, GenericRepository<RequestedModel>>();
|
||||
container.Register<IRequestService, RequestService>();
|
||||
|
||||
// Repo's
|
||||
container.Register<IRepository<RequestedModel>, GenericRepository<RequestedModel>>();
|
||||
container.Register<IRequestService, JsonRequestService>();
|
||||
container.Register<ISettingsRepository, SettingsJsonRepository>();
|
||||
|
||||
// Services
|
||||
container.Register<IAvailabilityChecker, PlexAvailabilityChecker>();
|
||||
container.Register<IConfigurationReader, ConfigurationReader>();
|
||||
container.Register<IIntervals, UpdateInterval>();
|
||||
|
||||
// Api's
|
||||
container.Register<ICouchPotatoApi, CouchPotatoApi>();
|
||||
container.Register<IPushbulletApi, PushbulletApi>();
|
||||
|
||||
container.Register<ISickRageApi, SickrageApi>();
|
||||
container.Register<ISonarrApi, SonarrApi>();
|
||||
//container.Register<ISonarrApi, MockSonarrApi>();
|
||||
|
||||
|
||||
container.Register<IPlexApi, PlexApi>();
|
||||
|
||||
SubscribeAllObservers(container);
|
||||
|
@ -101,7 +102,7 @@ namespace PlexRequests.UI
|
|||
TaskManager.Initialize(new PlexRegistry());
|
||||
|
||||
CookieBasedSessions.Enable(pipelines, CryptographyConfiguration.Default);
|
||||
|
||||
|
||||
StaticConfiguration.DisableErrorTraces = false;
|
||||
|
||||
base.ApplicationStartup(container, pipelines);
|
||||
|
|
|
@ -108,7 +108,7 @@ $(".theNoteSaveButton").click(function (e) {
|
|||
if (checkJsonResponse(response)) {
|
||||
generateNotify("Success! Added Note.", "success");
|
||||
$("#myModal").modal("hide");
|
||||
$('#adminNotesArea').html("<div>Note from Admin: " + comment + "</div>");
|
||||
$('#adminNotesArea' + e.target.value).html("<div>Note from Admin: " + comment + "</div>");
|
||||
}
|
||||
},
|
||||
error: function (e) {
|
||||
|
@ -210,7 +210,7 @@ $(document).on("click", ".clear", function (e) {
|
|||
|
||||
if (checkJsonResponse(response)) {
|
||||
generateNotify("Success! Issues Cleared.", "info");
|
||||
$('#issueArea').html("<div>Issue: None</div>");
|
||||
$('#issueArea'+buttonId).html("<div>Issue: None</div>");
|
||||
}
|
||||
},
|
||||
error: function (e) {
|
||||
|
|
77
PlexRequests.UI/Helpers/TvSender.cs
Normal file
77
PlexRequests.UI/Helpers/TvSender.cs
Normal file
|
@ -0,0 +1,77 @@
|
|||
#region Copyright
|
||||
// /************************************************************************
|
||||
// Copyright (c) 2016 Jamie Rees
|
||||
// File: TvSender.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 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
|
||||
{
|
||||
public class TvSender
|
||||
{
|
||||
public TvSender(ISonarrApi sonarrApi, ISickRageApi srApi)
|
||||
{
|
||||
SonarrApi = sonarrApi;
|
||||
SickrageApi = srApi;
|
||||
}
|
||||
private ISonarrApi SonarrApi { get; }
|
||||
private ISickRageApi SickrageApi { get; }
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public SonarrAddSeries SendToSonarr(SonarrSettings sonarrSettings, RequestedModel model)
|
||||
{
|
||||
int qualityProfile;
|
||||
int.TryParse(sonarrSettings.QualityProfile, out qualityProfile);
|
||||
var result = SonarrApi.AddSeries(model.ProviderId, model.Title, qualityProfile,
|
||||
sonarrSettings.SeasonFolders, sonarrSettings.RootPath, model.LatestTv, sonarrSettings.ApiKey,
|
||||
sonarrSettings.FullUri);
|
||||
|
||||
Log.Trace("Sonarr Add Result: ");
|
||||
Log.Trace(result.DumpJson());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public SickRageTvAdd SendToSickRage(SickRageSettings sickRageSettings, RequestedModel model)
|
||||
{
|
||||
var result = SickrageApi.AddSeries(model.ProviderId, model.LatestTv, sickRageSettings.QualityProfile,
|
||||
sickRageSettings.ApiKey, sickRageSettings.FullUri);
|
||||
|
||||
Log.Trace("SickRage Add Result: ");
|
||||
Log.Trace(result.DumpJson());
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -48,8 +48,6 @@ namespace PlexRequests.UI.Models
|
|||
public string AirsTime { get; set; }
|
||||
public string Rating { get; set; }
|
||||
public string ImdbId { get; set; }
|
||||
public string Zap2ItId { get; set; }
|
||||
public string Added { get; set; }
|
||||
public int SiteRating { get; set; }
|
||||
}
|
||||
}
|
|
@ -54,11 +54,13 @@ namespace PlexRequests.UI.Modules
|
|||
private ISettingsService<AuthenticationSettings> AuthService { get; }
|
||||
private ISettingsService<PlexSettings> PlexService { get; }
|
||||
private ISettingsService<SonarrSettings> SonarrService { get; }
|
||||
private ISettingsService<SickRageSettings> SickRageService { get; }
|
||||
private ISettingsService<EmailNotificationSettings> EmailService { get; }
|
||||
private ISettingsService<PushbulletNotificationSettings> PushbulletService { get; }
|
||||
private IPlexApi PlexApi { get; }
|
||||
private ISonarrApi SonarrApi { get; }
|
||||
private PushbulletApi PushbulletApi { get; }
|
||||
private ICouchPotatoApi CpApi { get; }
|
||||
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
public AdminModule(ISettingsService<PlexRequestSettings> rpService,
|
||||
|
@ -66,11 +68,13 @@ namespace PlexRequests.UI.Modules
|
|||
ISettingsService<AuthenticationSettings> auth,
|
||||
ISettingsService<PlexSettings> plex,
|
||||
ISettingsService<SonarrSettings> sonarr,
|
||||
ISettingsService<SickRageSettings> sickrage,
|
||||
ISonarrApi sonarrApi,
|
||||
ISettingsService<EmailNotificationSettings> email,
|
||||
IPlexApi plexApi,
|
||||
ISettingsService<PushbulletNotificationSettings> pbSettings,
|
||||
PushbulletApi pbApi) : base("admin")
|
||||
PushbulletApi pbApi,
|
||||
ICouchPotatoApi cpApi) : base("admin")
|
||||
{
|
||||
RpService = rpService;
|
||||
CpService = cpService;
|
||||
|
@ -82,6 +86,8 @@ namespace PlexRequests.UI.Modules
|
|||
PlexApi = plexApi;
|
||||
PushbulletService = pbSettings;
|
||||
PushbulletApi = pbApi;
|
||||
CpApi = cpApi;
|
||||
SickRageService = sickrage;
|
||||
|
||||
#if !DEBUG
|
||||
this.RequiresAuthentication();
|
||||
|
@ -106,7 +112,11 @@ namespace PlexRequests.UI.Modules
|
|||
Get["/sonarr"] = _ => Sonarr();
|
||||
Post["/sonarr"] = _ => SaveSonarr();
|
||||
|
||||
Get["/sickrage"] = _ => Sickrage();
|
||||
Post["/sickrage"] = _ => SaveSickrage();
|
||||
|
||||
Post["/sonarrprofiles"] = _ => GetSonarrQualityProfiles();
|
||||
Post["/cpprofiles"] = _ => GetCpProfiles();
|
||||
|
||||
Get["/emailnotification"] = _ => EmailNotifications();
|
||||
Post["/emailnotification"] = _ => SaveEmailNotifications();
|
||||
|
@ -279,7 +289,11 @@ namespace PlexRequests.UI.Modules
|
|||
{
|
||||
return Response.AsJson(valid.SendJsonError());
|
||||
}
|
||||
|
||||
var sickRageEnabled = SickRageService.GetSettings().Enabled;
|
||||
if (sickRageEnabled)
|
||||
{
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = "SickRage is enabled, we cannot enable Sonarr and SickRage" });
|
||||
}
|
||||
var result = SonarrService.SaveSettings(sonarrSettings);
|
||||
|
||||
return Response.AsJson(result
|
||||
|
@ -287,6 +301,35 @@ namespace PlexRequests.UI.Modules
|
|||
: new JsonResponseModel { Result = false, Message = "Could not update the settings, take a look at the logs." });
|
||||
}
|
||||
|
||||
private Negotiator Sickrage()
|
||||
{
|
||||
var settings = SickRageService.GetSettings();
|
||||
|
||||
return View["Sickrage", settings];
|
||||
}
|
||||
|
||||
private Response SaveSickrage()
|
||||
{
|
||||
var sickRageSettings = this.Bind<SickRageSettings>();
|
||||
|
||||
var valid = this.Validate(sickRageSettings);
|
||||
if (!valid.IsValid)
|
||||
{
|
||||
return Response.AsJson(valid.SendJsonError());
|
||||
}
|
||||
|
||||
var sonarrEnabled = SonarrService.GetSettings().Enabled;
|
||||
if (sonarrEnabled)
|
||||
{
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Sonarr is enabled, we cannot enable Sonarr and SickRage" });
|
||||
}
|
||||
var result = SickRageService.SaveSettings(sickRageSettings);
|
||||
|
||||
return Response.AsJson(result
|
||||
? new JsonResponseModel { Result = true, Message = "Successfully Updated the Settings for SickRage!" }
|
||||
: new JsonResponseModel { Result = false, Message = "Could not update the settings, take a look at the logs." });
|
||||
}
|
||||
|
||||
private Response GetSonarrQualityProfiles()
|
||||
{
|
||||
var settings = this.Bind<SonarrSettings>();
|
||||
|
@ -354,5 +397,13 @@ namespace PlexRequests.UI.Modules
|
|||
? new JsonResponseModel { Result = true, Message = "Successfully Updated the Settings for Pushbullet Notifications!" }
|
||||
: new JsonResponseModel { Result = false, Message = "Could not update the settings, take a look at the logs." });
|
||||
}
|
||||
|
||||
private Response GetCpProfiles()
|
||||
{
|
||||
var settings = this.Bind<CouchPotatoSettings>();
|
||||
var profiles = CpApi.GetProfiles(settings.FullUri, settings.ApiKey);
|
||||
|
||||
return Response.AsJson(profiles);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -43,7 +43,7 @@ namespace PlexRequests.UI.Modules
|
|||
{
|
||||
|
||||
public ApplicationTesterModule(ICouchPotatoApi cpApi, ISonarrApi sonarrApi, IPlexApi plexApi,
|
||||
ISettingsService<AuthenticationSettings> authSettings) : base("test")
|
||||
ISettingsService<AuthenticationSettings> authSettings, ISickRageApi srApi) : base("test")
|
||||
{
|
||||
this.RequiresAuthentication();
|
||||
|
||||
|
@ -51,10 +51,12 @@ namespace PlexRequests.UI.Modules
|
|||
SonarrApi = sonarrApi;
|
||||
PlexApi = plexApi;
|
||||
AuthSettings = authSettings;
|
||||
SickRageApi = srApi;
|
||||
|
||||
Post["/cp"] = _ => CouchPotatoTest();
|
||||
Post["/sonarr"] = _ => SonarrTest();
|
||||
Post["/plex"] = _ => PlexTest();
|
||||
Post["/sickrage"] = _ => SickRageTest();
|
||||
|
||||
}
|
||||
|
||||
|
@ -62,6 +64,7 @@ namespace PlexRequests.UI.Modules
|
|||
private ISonarrApi SonarrApi { get; }
|
||||
private ICouchPotatoApi CpApi { get; }
|
||||
private IPlexApi PlexApi { get; }
|
||||
private ISickRageApi SickRageApi { get; }
|
||||
private ISettingsService<AuthenticationSettings> AuthSettings { get; }
|
||||
|
||||
private Response CouchPotatoTest()
|
||||
|
@ -99,7 +102,7 @@ namespace PlexRequests.UI.Modules
|
|||
: Response.AsJson(new JsonResponseModel { Result = false, Message = "Could not connect to Sonarr, please check your settings." });
|
||||
|
||||
}
|
||||
catch (ApplicationException e) // Exceptions are expected if we cannot connect so we will just log and swallow them.
|
||||
catch (ApplicationException e) // Exceptions are expected, if we cannot connect so we will just log and swallow them.
|
||||
{
|
||||
Log.Warn("Exception thrown when attempting to get Sonarr's status: ");
|
||||
Log.Warn(e);
|
||||
|
@ -128,7 +131,7 @@ namespace PlexRequests.UI.Modules
|
|||
: Response.AsJson(new JsonResponseModel { Result = false, Message = "Could not connect to Plex, please check your settings." });
|
||||
|
||||
}
|
||||
catch (ApplicationException e) // Exceptions are expected if we cannot connect so we will just log and swallow them.
|
||||
catch (ApplicationException e) // Exceptions are expected, if we cannot connect so we will just log and swallow them.
|
||||
{
|
||||
Log.Warn("Exception thrown when attempting to get Plex's status: ");
|
||||
Log.Warn(e);
|
||||
|
@ -140,5 +143,30 @@ namespace PlexRequests.UI.Modules
|
|||
return Response.AsJson(new JsonResponseModel { Result = false, Message = message });
|
||||
}
|
||||
}
|
||||
|
||||
private Response SickRageTest()
|
||||
{
|
||||
var sickRageSettings = this.Bind<SickRageSettings>();
|
||||
|
||||
try
|
||||
{
|
||||
var status = SickRageApi.Ping(sickRageSettings.ApiKey, sickRageSettings.FullUri);
|
||||
return status?.result == "success"
|
||||
? Response.AsJson(new JsonResponseModel { Result = true, Message = "Connected to SickRage successfully!" })
|
||||
: Response.AsJson(new JsonResponseModel { Result = false, Message = "Could not connect to SickRage, please check your settings." });
|
||||
|
||||
}
|
||||
catch (ApplicationException e) // Exceptions are expected, if we cannot connect so we will just log and swallow them.
|
||||
{
|
||||
Log.Warn("Exception thrown when attempting to get SickRage's status: ");
|
||||
Log.Warn(e);
|
||||
var message = $"Could not connect to SickRage, please check your settings. <strong>Exception Message:</strong> {e.Message}";
|
||||
if (e.InnerException != null)
|
||||
{
|
||||
message = $"Could not connect to SickRage, please check your settings. <strong>Exception Message:</strong> {e.InnerException.Message}";
|
||||
}
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = message });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -27,7 +27,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using System.Linq.Expressions;
|
||||
using Nancy;
|
||||
using Nancy.Security;
|
||||
|
||||
|
@ -36,7 +36,9 @@ using PlexRequests.Api;
|
|||
using PlexRequests.Api.Interfaces;
|
||||
using PlexRequests.Core;
|
||||
using PlexRequests.Core.SettingModels;
|
||||
using PlexRequests.Helpers;
|
||||
using PlexRequests.Store;
|
||||
using PlexRequests.UI.Helpers;
|
||||
using PlexRequests.UI.Models;
|
||||
|
||||
namespace PlexRequests.UI.Modules
|
||||
|
@ -44,8 +46,8 @@ namespace PlexRequests.UI.Modules
|
|||
public class ApprovalModule : BaseModule
|
||||
{
|
||||
|
||||
public ApprovalModule(IRepository<RequestedModel> service, ISettingsService<CouchPotatoSettings> cpService, ICouchPotatoApi cpApi, ISonarrApi sonarrApi,
|
||||
ISettingsService<SonarrSettings> sonarrSettings) : base("approval")
|
||||
public ApprovalModule(IRequestService service, ISettingsService<CouchPotatoSettings> cpService, ICouchPotatoApi cpApi, ISonarrApi sonarrApi,
|
||||
ISettingsService<SonarrSettings> sonarrSettings, ISickRageApi srApi, ISettingsService<SickRageSettings> srSettings) : base("approval")
|
||||
{
|
||||
this.RequiresAuthentication();
|
||||
|
||||
|
@ -54,17 +56,21 @@ namespace PlexRequests.UI.Modules
|
|||
CpApi = cpApi;
|
||||
SonarrApi = sonarrApi;
|
||||
SonarrSettings = sonarrSettings;
|
||||
SickRageApi = srApi;
|
||||
SickRageSettings = srSettings;
|
||||
|
||||
Post["/approve"] = parameters => Approve((int)Request.Form.requestid);
|
||||
Post["/approveall"] = x => ApproveAll();
|
||||
}
|
||||
|
||||
private IRepository<RequestedModel> Service { get; set; }
|
||||
private IRequestService Service { get; }
|
||||
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
private ISettingsService<SonarrSettings> SonarrSettings { get; set; }
|
||||
private ISettingsService<SonarrSettings> SonarrSettings { get; }
|
||||
private ISettingsService<SickRageSettings> SickRageSettings { get; }
|
||||
private ISettingsService<CouchPotatoSettings> CpService { get; }
|
||||
private ISonarrApi SonarrApi { get; set; }
|
||||
private ISonarrApi SonarrApi { get; }
|
||||
private ISickRageApi SickRageApi { get; }
|
||||
private ICouchPotatoApi CpApi { get; }
|
||||
|
||||
/// <summary>
|
||||
|
@ -74,6 +80,7 @@ namespace PlexRequests.UI.Modules
|
|||
/// <returns></returns>
|
||||
private Response Approve(int requestId)
|
||||
{
|
||||
Log.Info("approving request {0}", requestId);
|
||||
if (!Context.CurrentUser.IsAuthenticated())
|
||||
{
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = "You are not an Admin, so you cannot approve any requests." });
|
||||
|
@ -100,20 +107,63 @@ namespace PlexRequests.UI.Modules
|
|||
|
||||
private Response RequestTvAndUpdateStatus(RequestedModel request)
|
||||
{
|
||||
var sonarrSettings = SonarrSettings.GetSettings();
|
||||
int qualityProfile;
|
||||
int.TryParse(sonarrSettings.QualityProfile, out qualityProfile);
|
||||
var result = SonarrApi.AddSeries(request.ProviderId, request.Title, qualityProfile,
|
||||
sonarrSettings.SeasonFolders, sonarrSettings.RootPath, request.LatestTv, sonarrSettings.ApiKey,
|
||||
sonarrSettings.FullUri);
|
||||
var sender = new TvSender(SonarrApi, SickRageApi);
|
||||
|
||||
if (!string.IsNullOrEmpty(result.title))
|
||||
var sonarrSettings = SonarrSettings.GetSettings();
|
||||
if (sonarrSettings.Enabled)
|
||||
{
|
||||
return Response.AsJson(new JsonResponseModel { Result = true });
|
||||
Log.Trace("Sending to Sonarr");
|
||||
var result = sender.SendToSonarr(sonarrSettings, request);
|
||||
Log.Trace("Sonarr Result: ");
|
||||
Log.Trace(result.DumpJson());
|
||||
if (!string.IsNullOrEmpty(result.title))
|
||||
{
|
||||
Log.Info("Sent successfully, Approving request now.");
|
||||
request.Approved = true;
|
||||
var requestResult = Service.UpdateRequest(request);
|
||||
Log.Trace("Approval result: {0}",requestResult);
|
||||
if (requestResult)
|
||||
{
|
||||
return Response.AsJson(new JsonResponseModel { Result = true });
|
||||
}
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Updated Sonarr but could not approve it in PlexRequests :("});
|
||||
}
|
||||
return Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = false,
|
||||
Message = "Could not add the series to Sonarr"
|
||||
});
|
||||
}
|
||||
|
||||
var srSettings = SickRageSettings.GetSettings();
|
||||
if (srSettings.Enabled)
|
||||
{
|
||||
Log.Trace("Sending to SickRage");
|
||||
var result = sender.SendToSickRage(srSettings, request);
|
||||
Log.Trace("SickRage Result: ");
|
||||
Log.Trace(result.DumpJson());
|
||||
if (result?.result == "success")
|
||||
{
|
||||
Log.Info("Sent successfully, Approving request now.");
|
||||
request.Approved = true;
|
||||
var requestResult = Service.UpdateRequest(request);
|
||||
Log.Trace("Approval result: {0}", requestResult);
|
||||
if (requestResult)
|
||||
{
|
||||
return Response.AsJson(new JsonResponseModel { Result = true });
|
||||
}
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Updated SickRage but could not approve it in PlexRequests :(" });
|
||||
}
|
||||
return Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = false,
|
||||
Message = result?.message != null ? "<b>Message From SickRage: </b>" + result.message : "Could not add the series to SickRage"
|
||||
});
|
||||
}
|
||||
return Response.AsJson(new JsonResponseModel
|
||||
{
|
||||
Result = false, Message = "Could not add the series to Sonarr"
|
||||
Result = false,
|
||||
Message = "SickRage or Sonarr are not set up!"
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -127,7 +177,7 @@ namespace PlexRequests.UI.Modules
|
|||
var cpSettings = CpService.GetSettings();
|
||||
var cp = new CouchPotatoApi();
|
||||
Log.Info("Adding movie to CP : {0}", request.Title);
|
||||
var result = cp.AddMovie(request.ImdbId, cpSettings.ApiKey, request.Title, cpSettings.FullUri);
|
||||
var result = cp.AddMovie(request.ImdbId, cpSettings.ApiKey, request.Title, cpSettings.FullUri, cpSettings.ProfileId);
|
||||
Log.Trace("Adding movie to CP result {0}", result);
|
||||
if (result)
|
||||
{
|
||||
|
@ -135,7 +185,7 @@ namespace PlexRequests.UI.Modules
|
|||
request.Approved = true;
|
||||
|
||||
// Update the record
|
||||
var inserted = Service.Update(request);
|
||||
var inserted = Service.UpdateRequest(request);
|
||||
|
||||
return Response.AsJson(inserted
|
||||
? new JsonResponseModel {Result = true}
|
||||
|
@ -184,18 +234,48 @@ namespace PlexRequests.UI.Modules
|
|||
}
|
||||
else
|
||||
{
|
||||
Log.Error("Could not approve send the movie {0} to couch potato!", r.Title);
|
||||
Log.Error("Could not approve and send the movie {0} to couch potato!", r.Title);
|
||||
}
|
||||
}
|
||||
if (r.Type == RequestType.TvShow)
|
||||
{
|
||||
// TODO
|
||||
var sender = new TvSender(SonarrApi,SickRageApi);
|
||||
var sr = SickRageSettings.GetSettings();
|
||||
var sonarr = SonarrSettings.GetSettings();
|
||||
if (sr.Enabled)
|
||||
{
|
||||
var result = sender.SendToSickRage(sr, r);
|
||||
if (result?.result == "success")
|
||||
{
|
||||
r.Approved = true;
|
||||
updatedRequests.Add(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error("Could not approve and send the TV {0} to SickRage!", r.Title);
|
||||
Log.Error("SickRage Message: {0}", result?.message);
|
||||
}
|
||||
}
|
||||
|
||||
if (sonarr.Enabled)
|
||||
{
|
||||
var result = sender.SendToSonarr(sonarr, r);
|
||||
if (result != null)
|
||||
{
|
||||
r.Approved = true;
|
||||
updatedRequests.Add(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error("Could not approve and send the TV {0} to Sonarr!", r.Title);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
|
||||
var result = Service.UpdateAll(updatedRequests); return Response.AsJson(result
|
||||
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." });
|
||||
|
||||
|
@ -208,11 +288,10 @@ namespace PlexRequests.UI.Modules
|
|||
|
||||
}
|
||||
|
||||
|
||||
private bool SendMovie(CouchPotatoSettings settings, RequestedModel r, ICouchPotatoApi cp)
|
||||
{
|
||||
Log.Info("Adding movie to CP : {0}", r.Title);
|
||||
var result = cp.AddMovie(r.ImdbId, settings.ApiKey, r.Title, settings.FullUri);
|
||||
var result = cp.AddMovie(r.ImdbId, settings.ApiKey, r.Title, settings.FullUri, settings.ProfileId);
|
||||
Log.Trace("Adding movie to CP result {0}", result);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace PlexRequests.UI.Modules
|
|||
public class RequestsModule : BaseModule
|
||||
{
|
||||
|
||||
public RequestsModule(IRepository<RequestedModel> service, ISettingsService<PlexRequestSettings> prSettings, ISettingsService<PlexSettings> plex) : base("requests")
|
||||
public RequestsModule(IRequestService service, ISettingsService<PlexRequestSettings> prSettings, ISettingsService<PlexSettings> plex) : base("requests")
|
||||
{
|
||||
Service = service;
|
||||
PrSettings = prSettings;
|
||||
|
@ -64,7 +64,7 @@ namespace PlexRequests.UI.Modules
|
|||
Post["/addnote"] = _ => AddNote((int)Request.Form.requestId, (string)Request.Form.noteArea);
|
||||
}
|
||||
|
||||
private IRepository<RequestedModel> Service { get; }
|
||||
private IRequestService Service { get; }
|
||||
private ISettingsService<PlexRequestSettings> PrSettings { get; }
|
||||
private ISettingsService<PlexSettings> PlexSettings { get; }
|
||||
|
||||
|
@ -114,7 +114,7 @@ namespace PlexRequests.UI.Modules
|
|||
Status = tv.Status,
|
||||
ImdbId = tv.ImdbId,
|
||||
Id = tv.Id,
|
||||
PosterPath = tv.ProviderId.ToString(),
|
||||
PosterPath = tv.PosterPath,
|
||||
ReleaseDate = tv.ReleaseDate.Humanize(),
|
||||
RequestedDate = tv.RequestedDate.Humanize(),
|
||||
Approved = tv.Approved,
|
||||
|
@ -140,7 +140,7 @@ namespace PlexRequests.UI.Modules
|
|||
}
|
||||
|
||||
var currentEntity = Service.Get(requestid);
|
||||
Service.Delete(currentEntity);
|
||||
Service.DeleteRequest(currentEntity);
|
||||
return Response.AsJson(new JsonResponseModel { Result = true });
|
||||
}
|
||||
|
||||
|
@ -165,7 +165,7 @@ namespace PlexRequests.UI.Modules
|
|||
: string.Empty;
|
||||
|
||||
|
||||
var result = Service.Update(originalRequest);
|
||||
var result = Service.UpdateRequest(originalRequest);
|
||||
return Response.AsJson(result
|
||||
? new JsonResponseModel { Result = true }
|
||||
: new JsonResponseModel { Result = false, Message = "Could not add issue, please try again or contact the administrator!" });
|
||||
|
@ -186,7 +186,7 @@ namespace PlexRequests.UI.Modules
|
|||
originalRequest.Issues = IssueState.None;
|
||||
originalRequest.OtherMessage = string.Empty;
|
||||
|
||||
var result = Service.Update(originalRequest);
|
||||
var result = Service.UpdateRequest(originalRequest);
|
||||
return Response.AsJson(result
|
||||
? new JsonResponseModel { Result = true }
|
||||
: new JsonResponseModel { Result = false, Message = "Could not clear issue, please try again or check the logs" });
|
||||
|
@ -202,7 +202,7 @@ namespace PlexRequests.UI.Modules
|
|||
|
||||
originalRequest.Available = available;
|
||||
|
||||
var result = Service.Update(originalRequest);
|
||||
var result = Service.UpdateRequest(originalRequest);
|
||||
return Response.AsJson(result
|
||||
? new { Result = true, Available = available, Message = string.Empty }
|
||||
: new { Result = false, Available = false, Message = "Could not update the availability, please try again or check the logs" });
|
||||
|
@ -218,7 +218,7 @@ namespace PlexRequests.UI.Modules
|
|||
|
||||
originalRequest.AdminNote = noteArea;
|
||||
|
||||
var result = Service.Update(originalRequest);
|
||||
var result = Service.UpdateRequest(originalRequest);
|
||||
return Response.AsJson(result
|
||||
? new JsonResponseModel { Result = true }
|
||||
: new JsonResponseModel { Result = false, Message = "Could not update the notes, please try again or check the logs" });
|
||||
|
|
|
@ -26,6 +26,9 @@
|
|||
#endregion
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
using Nancy;
|
||||
using Nancy.Responses.Negotiation;
|
||||
|
||||
|
@ -39,6 +42,7 @@ using PlexRequests.Helpers;
|
|||
using PlexRequests.Services.Interfaces;
|
||||
using PlexRequests.Services.Notification;
|
||||
using PlexRequests.Store;
|
||||
using PlexRequests.UI.Helpers;
|
||||
using PlexRequests.UI.Models;
|
||||
|
||||
namespace PlexRequests.UI.Modules
|
||||
|
@ -48,7 +52,7 @@ namespace PlexRequests.UI.Modules
|
|||
public SearchModule(ICacheProvider cache, ISettingsService<CouchPotatoSettings> cpSettings,
|
||||
ISettingsService<PlexRequestSettings> prSettings, IAvailabilityChecker checker,
|
||||
IRequestService request, ISonarrApi sonarrApi, ISettingsService<SonarrSettings> sonarrSettings,
|
||||
ICouchPotatoApi cpApi) : base("search")
|
||||
ISettingsService<SickRageSettings> sickRageService, ICouchPotatoApi cpApi, ISickRageApi srApi) : base("search")
|
||||
{
|
||||
CpService = cpSettings;
|
||||
PrService = prSettings;
|
||||
|
@ -60,6 +64,8 @@ namespace PlexRequests.UI.Modules
|
|||
SonarrApi = sonarrApi;
|
||||
SonarrService = sonarrSettings;
|
||||
CouchPotatoApi = cpApi;
|
||||
SickRageService = sickRageService;
|
||||
SickrageApi = srApi;
|
||||
|
||||
Get["/"] = parameters => RequestLoad();
|
||||
|
||||
|
@ -76,11 +82,13 @@ namespace PlexRequests.UI.Modules
|
|||
private ICouchPotatoApi CouchPotatoApi { get; }
|
||||
private ISonarrApi SonarrApi { get; }
|
||||
private TheTvDbApi TvApi { get; }
|
||||
private ISickRageApi SickrageApi { get; }
|
||||
private IRequestService RequestService { get; }
|
||||
private ICacheProvider Cache { get; }
|
||||
private ISettingsService<CouchPotatoSettings> CpService { get; }
|
||||
private ISettingsService<PlexRequestSettings> PrService { get; }
|
||||
private ISettingsService<SonarrSettings> SonarrService { get; }
|
||||
private ISettingsService<SickRageSettings> SickRageService { get; }
|
||||
private IAvailabilityChecker Checker { get; }
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
private string AuthToken => Cache.GetOrSet(CacheKeys.TvDbToken, TvApi.Authenticate, 50);
|
||||
|
@ -104,41 +112,34 @@ namespace PlexRequests.UI.Modules
|
|||
private Response SearchTvShow(string searchTerm)
|
||||
{
|
||||
Log.Trace("Searching for TV Show {0}", searchTerm);
|
||||
var tvShow = TvApi.SearchTv(searchTerm, AuthToken);
|
||||
|
||||
if (tvShow?.data == null)
|
||||
//var tvShow = TvApi.SearchTv(searchTerm, AuthToken);
|
||||
var tvShow = new TvMazeApi().Search(searchTerm);
|
||||
if (!tvShow.Any())
|
||||
{
|
||||
Log.Trace("TV Show data is null");
|
||||
return Response.AsJson("");
|
||||
}
|
||||
var model = new List<SearchTvShowViewModel>();
|
||||
|
||||
foreach (var t in tvShow.data)
|
||||
foreach (var t in tvShow)
|
||||
{
|
||||
model.Add(new SearchTvShowViewModel
|
||||
{
|
||||
Added = t.added,
|
||||
AirsDayOfWeek = t.airsDayOfWeek,
|
||||
AirsTime = t.airsTime,
|
||||
Aliases = t.aliases,
|
||||
// We are constructing the banner with the id:
|
||||
// http://thetvdb.com/banners/_cache/posters/ID-1.jpg
|
||||
Banner = t.id.ToString(),
|
||||
FirstAired = t.firstAired,
|
||||
Genre = t.genre,
|
||||
Id = t.id,
|
||||
ImdbId = t.imdbId,
|
||||
LastUpdated = t.lastUpdated,
|
||||
Network = t.network,
|
||||
NetworkId = t.networkId,
|
||||
Overview = t.overview,
|
||||
Rating = t.rating,
|
||||
Runtime = t.runtime,
|
||||
SeriesId = t.id,
|
||||
SeriesName = t.seriesName,
|
||||
SiteRating = t.siteRating,
|
||||
Status = t.status,
|
||||
Zap2ItId = t.zap2itId
|
||||
Banner = t.show.image?.medium,
|
||||
FirstAired = t.show.premiered,
|
||||
Id = t.show.externals?.thetvdb ?? 0,
|
||||
ImdbId = t.show.externals?.imdb,
|
||||
Network = t.show.network?.name,
|
||||
NetworkId = t.show.network?.id.ToString(),
|
||||
Overview = t.show.summary.RemoveHtml(),
|
||||
Rating = t.score.ToString(CultureInfo.CurrentUICulture),
|
||||
Runtime = t.show.runtime.ToString(),
|
||||
SeriesId = t.show.id,
|
||||
SeriesName = t.show.name,
|
||||
|
||||
Status = t.show.status,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -190,12 +191,12 @@ namespace PlexRequests.UI.Modules
|
|||
Log.Trace("Getting movie info from TheMovieDb");
|
||||
Log.Trace(movieInfo.DumpJson);
|
||||
|
||||
#if !DEBUG
|
||||
if (CheckIfTitleExistsInPlex(movieInfo.Title))
|
||||
//#if !DEBUG
|
||||
if (CheckIfTitleExistsInPlex(movieInfo.Title, movieInfo.ReleaseDate?.Year.ToString()))
|
||||
{
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = $"{movieInfo.Title} is already in Plex!" });
|
||||
}
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
var model = new RequestedModel
|
||||
{
|
||||
|
@ -219,13 +220,13 @@ namespace PlexRequests.UI.Modules
|
|||
if (!settings.RequireApproval)
|
||||
{
|
||||
Log.Info("Adding movie to CP (No approval required)");
|
||||
var result = CouchPotatoApi.AddMovie(model.ImdbId, cpSettings.ApiKey, model.Title, cpSettings.FullUri);
|
||||
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)
|
||||
{
|
||||
model.Approved = true;
|
||||
Log.Debug("Adding movie to database requests (No approval required)");
|
||||
RequestService.AddRequest(movieId, model);
|
||||
RequestService.AddRequest(model);
|
||||
|
||||
return Response.AsJson(new JsonResponseModel { Result = true });
|
||||
}
|
||||
|
@ -235,7 +236,7 @@ namespace PlexRequests.UI.Modules
|
|||
try
|
||||
{
|
||||
Log.Debug("Adding movie to database requests");
|
||||
var id = RequestService.AddRequest(movieId, model);
|
||||
var id = RequestService.AddRequest(model);
|
||||
|
||||
NotificationService.Publish(model.Title, model.RequestedBy);
|
||||
|
||||
|
@ -262,28 +263,27 @@ namespace PlexRequests.UI.Modules
|
|||
return Response.AsJson(new JsonResponseModel { Result = false, Message = "TV Show has already been requested!" });
|
||||
}
|
||||
|
||||
var tvApi = new TheTvDbApi();
|
||||
var token = GetTvDbAuthToken(tvApi);
|
||||
var tvApi = new TvMazeApi();
|
||||
|
||||
var showInfo = tvApi.GetInformation(showId, token).data;
|
||||
var showInfo = tvApi.ShowLookupByTheTvDbId(showId);
|
||||
|
||||
#if !DEBUG
|
||||
if (CheckIfTitleExistsInPlex(showInfo.seriesName))
|
||||
//#if !DEBUG
|
||||
if (CheckIfTitleExistsInPlex(showInfo.name, showInfo.premiered?.Substring(0, 4))) // Take only the year Format = 2014-01-01
|
||||
{
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = $"{showInfo.seriesName} is already in Plex!" });
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = $"{showInfo.name} is already in Plex!" });
|
||||
}
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
DateTime firstAir;
|
||||
DateTime.TryParse(showInfo.firstAired, out firstAir);
|
||||
DateTime.TryParse(showInfo.premiered, out firstAir);
|
||||
|
||||
var model = new RequestedModel
|
||||
{
|
||||
ProviderId = showInfo.id,
|
||||
ProviderId = showInfo.externals?.thetvdb ?? 0,
|
||||
Type = RequestType.TvShow,
|
||||
Overview = showInfo.overview,
|
||||
PosterPath = "http://image.tmdb.org/t/p/w150/" + showInfo.banner, // This is incorrect
|
||||
Title = showInfo.seriesName,
|
||||
Overview = showInfo.summary.RemoveHtml(),
|
||||
PosterPath = showInfo.image?.medium,
|
||||
Title = showInfo.name,
|
||||
ReleaseDate = firstAir,
|
||||
Status = showInfo.status,
|
||||
RequestedDate = DateTime.Now,
|
||||
|
@ -298,36 +298,70 @@ namespace PlexRequests.UI.Modules
|
|||
if (!settings.RequireApproval)
|
||||
{
|
||||
var sonarrSettings = SonarrService.GetSettings();
|
||||
int qualityProfile;
|
||||
int.TryParse(sonarrSettings.QualityProfile, out qualityProfile);
|
||||
var result = SonarrApi.AddSeries(model.ProviderId, model.Title, qualityProfile,
|
||||
sonarrSettings.SeasonFolders, sonarrSettings.RootPath, model.LatestTv, sonarrSettings.ApiKey,
|
||||
sonarrSettings.FullUri);
|
||||
if (result != null)
|
||||
var sender = new TvSender(SonarrApi, SickrageApi);
|
||||
if (sonarrSettings.Enabled)
|
||||
{
|
||||
model.Approved = true;
|
||||
Log.Debug("Adding tv to database requests (No approval required)");
|
||||
RequestService.AddRequest(showId, model);
|
||||
var result = sender.SendToSonarr(sonarrSettings, model);
|
||||
if (result != null)
|
||||
{
|
||||
model.Approved = true;
|
||||
Log.Debug("Adding tv to database requests (No approval required & Sonarr)");
|
||||
RequestService.AddRequest(model);
|
||||
|
||||
return Response.AsJson(new JsonResponseModel { Result = true });
|
||||
}
|
||||
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 });
|
||||
}
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Something went wrong adding the movie to CouchPotato! Please check your settings." });
|
||||
|
||||
var srSettings = SickRageService.GetSettings();
|
||||
if (srSettings.Enabled)
|
||||
{
|
||||
var result = sender.SendToSickRage(srSettings, model);
|
||||
if (result?.result == "success")
|
||||
{
|
||||
model.Approved = true;
|
||||
Log.Debug("Adding tv to database requests (No approval required & SickRage)");
|
||||
RequestService.AddRequest(model);
|
||||
|
||||
return Response.AsJson(new JsonResponseModel { Result = true });
|
||||
}
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = result?.message != null ? "<b>Message From SickRage: </b>" + result.message : "Something went wrong adding the movie to SickRage! Please check your settings." });
|
||||
}
|
||||
|
||||
return Response.AsJson("The request of TV Shows is not correctly set up. Please contact your admin.");
|
||||
|
||||
}
|
||||
|
||||
RequestService.AddRequest(showId, model);
|
||||
RequestService.AddRequest(model);
|
||||
NotificationService.Publish(model.Title, model.RequestedBy);
|
||||
|
||||
return Response.AsJson(new { Result = true });
|
||||
}
|
||||
private string GetTvDbAuthToken(TheTvDbApi api)
|
||||
|
||||
private bool CheckIfTitleExistsInPlex(string title, string year)
|
||||
{
|
||||
return Cache.GetOrSet(CacheKeys.TvDbToken, api.Authenticate, 50);
|
||||
var result = Checker.IsAvailable(title, year);
|
||||
return result;
|
||||
}
|
||||
|
||||
private bool CheckIfTitleExistsInPlex(string title)
|
||||
private Response SendToSickRage(SickRageSettings sickRageSettings, RequestedModel model)
|
||||
{
|
||||
var result = Checker.IsAvailable(title);
|
||||
return result;
|
||||
var result = SickrageApi.AddSeries(model.ProviderId, model.LatestTv, sickRageSettings.QualityProfile,
|
||||
sickRageSettings.ApiKey, sickRageSettings.FullUri);
|
||||
|
||||
Log.Trace("SickRage Result: ");
|
||||
Log.Trace(result.DumpJson());
|
||||
|
||||
if (result?.result == "success")
|
||||
{
|
||||
model.Approved = true;
|
||||
Log.Debug("Adding tv to database requests (No approval required & SickRage)");
|
||||
RequestService.AddRequest(model);
|
||||
|
||||
return Response.AsJson(new JsonResponseModel { Result = true });
|
||||
}
|
||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Something went wrong adding the movie to SickRage! Please check your settings." });
|
||||
}
|
||||
}
|
||||
}
|
|
@ -24,6 +24,9 @@
|
|||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
// ************************************************************************/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Nancy;
|
||||
|
@ -98,15 +101,28 @@ namespace PlexRequests.UI.Modules
|
|||
var signedIn = (PlexAuthentication)Api.SignIn(username, password);
|
||||
if (signedIn.user?.authentication_token != null)
|
||||
{
|
||||
Log.Debug("Correct credentials, checking if the user is in the friends list");
|
||||
authenticated = CheckIfUserIsInPlexFriends(username, settings.PlexAuthToken);
|
||||
Log.Debug("Friends list result = {0}", authenticated);
|
||||
Log.Debug("Correct credentials, checking if the user is account owner or in the friends list");
|
||||
if (CheckIfUserIsOwner(settings.PlexAuthToken, signedIn.user?.username))
|
||||
{
|
||||
Log.Debug("User is the account owner");
|
||||
authenticated = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
authenticated = CheckIfUserIsInPlexFriends(username, settings.PlexAuthToken);
|
||||
Log.Debug("Friends list result = {0}", authenticated);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(settings.UserAuthentication) // Check against the users in Plex
|
||||
{
|
||||
Log.Debug("Need to auth");
|
||||
authenticated = CheckIfUserIsInPlexFriends(username, settings.PlexAuthToken);
|
||||
if (CheckIfUserIsOwner(settings.PlexAuthToken, username))
|
||||
{
|
||||
Log.Debug("User is the account owner");
|
||||
authenticated = true;
|
||||
}
|
||||
Log.Debug("Friends list result = {0}", authenticated);
|
||||
}
|
||||
else if(!settings.UserAuthentication) // No auth, let them pass!
|
||||
|
@ -127,6 +143,8 @@ namespace PlexRequests.UI.Modules
|
|||
: new JsonResponseModel { Result = false, Message = "Incorrect User or Password"});
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Response Logout()
|
||||
{
|
||||
Log.Debug("Logging Out");
|
||||
|
@ -137,12 +155,23 @@ namespace PlexRequests.UI.Modules
|
|||
return Context.GetRedirect("~/userlogin");
|
||||
}
|
||||
|
||||
private bool CheckIfUserIsOwner(string authToken, string userName)
|
||||
{
|
||||
var userAccount = Api.GetAccount(authToken);
|
||||
if (userAccount == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return userAccount.Username != null && userAccount.Username.Equals(userName, StringComparison.CurrentCultureIgnoreCase);
|
||||
}
|
||||
|
||||
private bool CheckIfUserIsInPlexFriends(string username, string authToken)
|
||||
{
|
||||
var users = Api.GetUsers(authToken);
|
||||
Log.Debug("Plex Users: ");
|
||||
Log.Debug(users.DumpJson());
|
||||
return users.User.Any(x => x.Username == username);
|
||||
var allUsers = users.User?.Where(x => !string.IsNullOrEmpty(x.Username));
|
||||
return allUsers != null && allUsers.Any(x => x.Username.Equals(username, StringComparison.CurrentCultureIgnoreCase));
|
||||
}
|
||||
|
||||
private bool IsUserInDeniedList(string username, AuthenticationSettings settings)
|
||||
|
|
|
@ -160,11 +160,13 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Bootstrapper.cs" />
|
||||
<Compile Include="Helpers\TvSender.cs" />
|
||||
<Compile Include="Helpers\ValidationHelper.cs" />
|
||||
<Compile Include="Validators\PushbulletSettingsValidator.cs" />
|
||||
<Compile Include="Validators\EmailNotificationSettingsValidator.cs" />
|
||||
<Compile Include="Validators\CouchPotatoValidator.cs" />
|
||||
<Compile Include="Validators\PlexValidator.cs" />
|
||||
<Compile Include="Validators\SickRageValidator.cs" />
|
||||
<Compile Include="Validators\SonarrValidator.cs" />
|
||||
<Content Include="Content\bootstrap-notify.min.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
|
@ -320,6 +322,9 @@
|
|||
<Content Include="Views\Admin\PushbulletNotifications.cshtml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Views\Admin\Sickrage.cshtml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<None Include="Web.Debug.config">
|
||||
<DependentUpon>web.config</DependentUpon>
|
||||
</None>
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace PlexRequests.UI
|
|||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
static void Main(string[] args)
|
||||
{
|
||||
var uri = string.Empty;
|
||||
var port = -1;
|
||||
if (args.Length > 0)
|
||||
{
|
||||
Log.Info("We are going to use port {0} that was passed in", args[0]);
|
||||
|
@ -59,7 +59,7 @@ namespace PlexRequests.UI
|
|||
Console.ReadLine();
|
||||
Environment.Exit(1);
|
||||
}
|
||||
uri = $"http://*:{portResult}";
|
||||
port = portResult;
|
||||
}
|
||||
|
||||
Log.Trace("Getting product version");
|
||||
|
@ -68,11 +68,10 @@ namespace PlexRequests.UI
|
|||
var s = new Setup();
|
||||
s.SetupDb();
|
||||
|
||||
if (string.IsNullOrEmpty(uri))
|
||||
uri = GetStartupUri();
|
||||
if (port == -1)
|
||||
port = GetStartupPort();
|
||||
|
||||
;
|
||||
var options = new StartOptions(uri)
|
||||
var options = new StartOptions($"http://+:{port}")
|
||||
{
|
||||
ServerFactory = "Microsoft.Owin.Host.HttpListener"
|
||||
};
|
||||
|
@ -81,7 +80,7 @@ namespace PlexRequests.UI
|
|||
|
||||
using (WebApp.Start<Startup>(options))
|
||||
{
|
||||
Console.WriteLine($"Request Plex is running on {uri}");
|
||||
Console.WriteLine($"Request Plex is running on the following port: {port}");
|
||||
Console.WriteLine("Press any key to exit");
|
||||
Console.ReadLine();
|
||||
}
|
||||
|
@ -101,19 +100,19 @@ namespace PlexRequests.UI
|
|||
Console.WriteLine($"Version: {assemblyVer}");
|
||||
}
|
||||
|
||||
private static string GetStartupUri()
|
||||
private static int GetStartupPort()
|
||||
{
|
||||
Log.Trace("Getting startup URI");
|
||||
var uri = "http://*:3579/";
|
||||
Log.Trace("Getting startup Port");
|
||||
var port = 3579;
|
||||
var service = new SettingsServiceV2<PlexRequestSettings>(new SettingsJsonRepository(new DbConfiguration(new SqliteFactory()), new MemoryCacheProvider()));
|
||||
var settings = service.GetSettings();
|
||||
Log.Trace("Port: {0}", settings.Port);
|
||||
if (settings.Port != 0)
|
||||
{
|
||||
uri = $"http://*:{settings.Port}";
|
||||
port = settings.Port;
|
||||
}
|
||||
|
||||
return uri;
|
||||
return port;
|
||||
}
|
||||
|
||||
private static void ConfigureTargets(string connectionString)
|
||||
|
|
43
PlexRequests.UI/Validators/SickRageValidator.cs
Normal file
43
PlexRequests.UI/Validators/SickRageValidator.cs
Normal file
|
@ -0,0 +1,43 @@
|
|||
#region Copyright
|
||||
// /************************************************************************
|
||||
// Copyright (c) 2016 Jamie Rees
|
||||
// File: SonarrValidator.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 FluentValidation;
|
||||
|
||||
using PlexRequests.Core.SettingModels;
|
||||
|
||||
namespace PlexRequests.UI.Validators
|
||||
{
|
||||
public class SickRageValidator : AbstractValidator<SickRageSettings>
|
||||
{
|
||||
public SickRageValidator()
|
||||
{
|
||||
RuleFor(request => request.ApiKey).NotEmpty().WithMessage("You must specify a Api Key.");
|
||||
RuleFor(request => request.Ip).NotEmpty().WithMessage("You must specify a IP/Host name.");
|
||||
RuleFor(request => request.Port).NotEmpty().WithMessage("You must specify a Port.");
|
||||
RuleFor(request => request.QualityProfile).NotEmpty().WithMessage("You must specify a Quality Profile.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -37,8 +37,35 @@
|
|||
<input type="text" class="form-control form-control-custom " id="ApiKey" name="ApiKey" value="@Model.ApiKey">
|
||||
</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">
|
||||
<div>
|
||||
<button type="submit" id="getProfiles" class="btn btn-primary-outline">Get Quality Profiles</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="select" class="control-label">Quality Profiles</label>
|
||||
<div id="profiles">
|
||||
<select class="form-control" id="select"></select>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button id="testCp" type="submit" class="btn btn-primary-outline">Test Connectivity</button>
|
||||
|
@ -62,9 +89,58 @@
|
|||
<script>
|
||||
$(function() {
|
||||
|
||||
@if (!string.IsNullOrEmpty(Model.ProfileId))
|
||||
{
|
||||
<text>
|
||||
var qualitySelected = '@Model.ProfileId';
|
||||
var $form = $("#mainForm");
|
||||
$.ajax({
|
||||
type: $form.prop("method"),
|
||||
data: $form.serialize(),
|
||||
url: "cpprofiles",
|
||||
dataType: "json",
|
||||
success: function(response) {
|
||||
response.list.forEach(function(result) {
|
||||
if (result._id == qualitySelected) {
|
||||
|
||||
$("#select").append("<option selected='selected' value='" + result._id + "'>" + result.label + "</option>");
|
||||
} else {
|
||||
$("#select").append("<option value='" + result._id + "'>" + result.label + "</option>");
|
||||
}
|
||||
});
|
||||
},
|
||||
error: function(e) {
|
||||
console.log(e);
|
||||
generateNotify("Something went wrong!", "danger");
|
||||
}
|
||||
});
|
||||
</text>
|
||||
}
|
||||
|
||||
$('#getProfiles').click(function (e) {
|
||||
e.preventDefault();
|
||||
var $form = $("#mainForm");
|
||||
$.ajax({
|
||||
type: $form.prop("method"),
|
||||
data: $form.serialize(),
|
||||
url: "cpprofiles",
|
||||
dataType: "json",
|
||||
success: function (response) {
|
||||
response.list.forEach(function (result) {
|
||||
$("#select").append("<option value='" + result._id + "'>" + result.label + "</option>");
|
||||
});
|
||||
},
|
||||
error: function (e) {
|
||||
console.log(e);
|
||||
generateNotify("Something went wrong!", "danger");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#testCp').click(function (e) {
|
||||
e.preventDefault();
|
||||
var $form = $("#mainForm");
|
||||
|
||||
$.ajax({
|
||||
type: $form.prop("method"),
|
||||
url: "/test/cp",
|
||||
|
@ -94,9 +170,13 @@
|
|||
return;
|
||||
}
|
||||
var $form = $("#mainForm");
|
||||
var qualityProfile = $("#profiles option:selected").val();
|
||||
var data = $form.serialize();
|
||||
data = data + "&profileId=" + qualityProfile;
|
||||
|
||||
$.ajax({
|
||||
type: $form.prop("method"),
|
||||
data: $form.serialize(),
|
||||
data: data,
|
||||
url: $form.prop("action"),
|
||||
dataType: "json",
|
||||
success: function (response) {
|
||||
|
@ -112,6 +192,6 @@
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
</script>
|
172
PlexRequests.UI/Views/Admin/Sickrage.cshtml
Normal file
172
PlexRequests.UI/Views/Admin/Sickrage.cshtml
Normal file
|
@ -0,0 +1,172 @@
|
|||
@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>SickRage 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">
|
||||
<label for="Ip" class="control-label">SickRage 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">SickRage 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">
|
||||
<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="profiles" class="control-label">Quality Profiles</label>
|
||||
<div id="profiles">
|
||||
<select class="form-control" value="selected">
|
||||
<option id="default" value="default">Use Deafult</option>
|
||||
<option id="sdtv" value="sdtv">SD TV</option>
|
||||
<option id="sddvd" value="sddvd">SD DVD</option>
|
||||
<option id="hdtv" value="hdtv">HD TV</option>
|
||||
<option id="rawhdtv" value="rawhdtv">Raw HD TV</option>
|
||||
<option id="hdwebdl" value="hdwebdl">HD Web DL</option>
|
||||
<option id="fullhdwebdl" value="fullhdwebdl">Full HD Web DL</option>
|
||||
<option id="hdbluray" value="hdbluray">HD Bluray</option>
|
||||
<option id="fullhdbluray" value="fullhdbluray">Full HD Bluray</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button id="testSickRage" 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() {
|
||||
|
||||
@if (!string.IsNullOrEmpty(Model.QualityProfile))
|
||||
{
|
||||
<text>
|
||||
var qualitySelected = '@Model.QualityProfile';
|
||||
$('#' + qualitySelected).prop("selected", "selected");
|
||||
</text>
|
||||
}
|
||||
|
||||
$('#save').click(function (e) {
|
||||
e.preventDefault();
|
||||
var port = $('#portNumber').val();
|
||||
if (isNaN(port)) {
|
||||
generateNotify("You must specify a Port.", "warning");
|
||||
return;
|
||||
}
|
||||
var qualityProfile = $("#profiles option:selected").val();
|
||||
|
||||
var $form = $("#mainForm");
|
||||
|
||||
var data = $form.serialize();
|
||||
data = data + "&qualityProfile=" + qualityProfile;
|
||||
|
||||
$.ajax({
|
||||
type: $form.prop("method"),
|
||||
data: data,
|
||||
url: $form.prop("action"),
|
||||
dataType: "json",
|
||||
success: function (response) {
|
||||
if (response.result === true) {
|
||||
generateNotify("Success!", "success");
|
||||
} else {
|
||||
generateNotify(response.message, "warning");
|
||||
}
|
||||
},
|
||||
error: function (e) {
|
||||
console.log(e);
|
||||
generateNotify("Something went wrong!", "danger");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#testSickRage').click(function (e) {
|
||||
e.preventDefault();
|
||||
var $form = $("#mainForm");
|
||||
$.ajax({
|
||||
type: $form.prop("method"),
|
||||
url: "/test/sickrage",
|
||||
data: $form.serialize(),
|
||||
dataType: "json",
|
||||
success: function (response) {
|
||||
console.log(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>
|
|
@ -14,7 +14,20 @@
|
|||
<form class="form-horizontal" method="POST" id="mainForm">
|
||||
<fieldset>
|
||||
<legend>Sonarr 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">
|
||||
<label for="Ip" class="control-label">Sonarr Hostname or IP</label>
|
||||
<div class="">
|
||||
|
@ -37,7 +50,20 @@
|
|||
<input type="text" class="form-control form-control-custom " id="ApiKey" name="ApiKey" value="@Model.ApiKey">
|
||||
</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">
|
||||
<div>
|
||||
<button type="submit" id="getProfiles" class="btn btn-primary-outline">Get Quality Profiles</button>
|
||||
|
@ -108,7 +134,7 @@
|
|||
success: function(response) {
|
||||
response.forEach(function(result) {
|
||||
if (result.id == qualitySelected) {
|
||||
|
||||
|
||||
$("#select").append("<option selected='selected' value='" + result.id + "'>" + result.name + "</option>");
|
||||
} else {
|
||||
$("#select").append("<option value='" + result.id + "'>" + result.name + "</option>");
|
||||
|
@ -120,11 +146,6 @@
|
|||
generateNotify("Something went wrong!", "danger");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</text>
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,14 @@
|
|||
{
|
||||
<a class="list-group-item" href="/admin/sonarr">Sonarr</a>
|
||||
}
|
||||
@*<a class="list-group-item" href="/admin/sickbeard">Sickbeard Settings</a>*@
|
||||
@if (Context.Request.Path == "/admin/sickrage")
|
||||
{
|
||||
<a class="list-group-item active" href="/admin/sickrage">SickRage</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
<a class="list-group-item" href="/admin/sickrage">SickRage</a>
|
||||
}
|
||||
|
||||
@if (Context.Request.Path == "/admin/emailnotification")
|
||||
{
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
{{/if_eq}}
|
||||
{{#if_eq type "tv"}}
|
||||
{{#if posterPath}}
|
||||
<img class="img-responsive" width="150" src="http://thetvdb.com/banners/_cache/posters/{{posterPath}}-1.jpg" alt="poster">
|
||||
<img class="img-responsive" width="150" src="{{posterPath}}" alt="poster">
|
||||
{{/if}}
|
||||
{{/if_eq}}
|
||||
</div>
|
||||
|
@ -95,14 +95,14 @@
|
|||
</div>
|
||||
<div>Requested By: {{requestedBy}}</div>
|
||||
<div>Requested Date: {{requestedDate}}</div>
|
||||
<div id="issueArea">
|
||||
<div id="issueArea{{requestId}}">
|
||||
{{#if otherMessage}}
|
||||
<div>Message: {{otherMessage}}</div>
|
||||
{{else}}
|
||||
<div>Issue: {{issues}}</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div id="adminNotesArea">
|
||||
<div id="adminNotesArea{{requestId}}">
|
||||
{{#if adminNote}}
|
||||
<div>Note from Admin: {{adminNote}}</div>
|
||||
{{/if}}
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
{{/if_eq}}
|
||||
{{#if_eq type "tv"}}
|
||||
{{#if posterPath}}
|
||||
<img class="img-responsive" width="150" src="http://thetvdb.com/banners/_cache/posters/{{posterPath}}-1.jpg" alt="poster">
|
||||
<img class="img-responsive" width="150" src="{{posterPath}}" alt="poster">
|
||||
{{/if}}
|
||||
{{/if_eq}}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<head>
|
||||
<title>Plex Requests</title>
|
||||
<!-- Styles -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="~/Content/custom.min.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="~/Content/bootstrap.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="~/Content/font-awesome.css" type="text/css"/>
|
||||
|
@ -89,4 +90,4 @@
|
|||
@RenderBody()
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
@ -12,7 +12,8 @@ I wanted to write a similar application in .Net!
|
|||
|
||||
#Features
|
||||
|
||||
* Integration with [TheMovieDB](https://www.themoviedb.org/) for all Movies and TV shows
|
||||
* Integration with [TheMovieDB](https://www.themoviedb.org/) for all Movies
|
||||
* Integration with [TVMaze](www.tvmaze.com) for all TV shows!
|
||||
* Secure authentication
|
||||
* [Sonarr](https://sonarr.tv/) integration (SickRage/Sickbeard TBD)
|
||||
* [CouchPotato](https://couchpota.to/) integration
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
version: 1.3.{build}
|
||||
version: 1.4.{build}
|
||||
configuration: Release
|
||||
assembly_info:
|
||||
patch: true
|
||||
file: '**\AssemblyInfo.*'
|
||||
assembly_version: '1.3.0'
|
||||
assembly_version: '1.4.0'
|
||||
assembly_file_version: '{version}'
|
||||
assembly_informational_version: '1.3.0'
|
||||
assembly_informational_version: '1.4.0'
|
||||
before_build:
|
||||
- cmd: appveyor-retry nuget restore
|
||||
build:
|
||||
|
@ -18,7 +18,7 @@ after_build:
|
|||
|
||||
deploy:
|
||||
- provider: GitHub
|
||||
release: PlexRequests $(appveyor_build_version)
|
||||
release: PlexRequests v$(appveyor_build_version)
|
||||
auth_token:
|
||||
secure: jDpp1/WUQl3uN41fNI3VeZoRZbDiDfs3GPQ1v+C5ZNE3cWdnUvuJfCCfUbYUV1Rp
|
||||
draft: true
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue