mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-31 12:00:06 -07:00
commit
0f3b010ad8
110 changed files with 2973 additions and 1208 deletions
|
@ -36,5 +36,6 @@ namespace PlexRequests.Api.Interfaces
|
||||||
bool AddMovie(string imdbid, string apiKey, string title, Uri baseUrl, string profileID = default(string));
|
bool AddMovie(string imdbid, string apiKey, string title, Uri baseUrl, string profileID = default(string));
|
||||||
CouchPotatoStatus GetStatus(Uri url, string apiKey);
|
CouchPotatoStatus GetStatus(Uri url, string apiKey);
|
||||||
CouchPotatoProfiles GetProfiles(Uri url, string apiKey);
|
CouchPotatoProfiles GetProfiles(Uri url, string apiKey);
|
||||||
|
CouchPotatoMovies GetMovies(Uri baseUrl, string apiKey, string[] status);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -38,5 +38,7 @@ namespace PlexRequests.Api.Interfaces
|
||||||
PlexSearch SearchContent(string authToken, string searchTerm, Uri plexFullHost);
|
PlexSearch SearchContent(string authToken, string searchTerm, Uri plexFullHost);
|
||||||
PlexStatus GetStatus(string authToken, Uri uri);
|
PlexStatus GetStatus(string authToken, Uri uri);
|
||||||
PlexAccount GetAccount(string authToken);
|
PlexAccount GetAccount(string authToken);
|
||||||
|
PlexLibraries GetLibrarySections(string authToken, Uri plexFullHost);
|
||||||
|
PlexSearch GetLibrary(string authToken, Uri plexFullHost, string libraryId);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -39,5 +39,7 @@ namespace PlexRequests.Api.Interfaces
|
||||||
SickRagePing Ping(string apiKey, Uri baseUrl);
|
SickRagePing Ping(string apiKey, Uri baseUrl);
|
||||||
|
|
||||||
Task<SickRageTvAdd> AddSeason(int tvdbId, int season, string apiKey, Uri baseUrl);
|
Task<SickRageTvAdd> AddSeason(int tvdbId, int season, string apiKey, Uri baseUrl);
|
||||||
|
|
||||||
|
Task<SickrageShows> GetShows(string apiKey, Uri baseUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -39,5 +39,7 @@ namespace PlexRequests.Api.Interfaces
|
||||||
int seasonCount, int[] seasons, string apiKey, Uri baseUrl);
|
int seasonCount, int[] seasons, string apiKey, Uri baseUrl);
|
||||||
|
|
||||||
SystemStatus SystemStatus(string apiKey, Uri baseUrl);
|
SystemStatus SystemStatus(string apiKey, Uri baseUrl);
|
||||||
|
|
||||||
|
List<Series> GetSeries(string apiKey, Uri baseUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,7 +9,7 @@
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>PlexRequests.Api.Interfaces</RootNamespace>
|
<RootNamespace>PlexRequests.Api.Interfaces</RootNamespace>
|
||||||
<AssemblyName>PlexRequests.Api.Interfaces</AssemblyName>
|
<AssemblyName>PlexRequests.Api.Interfaces</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<TargetFrameworkProfile />
|
<TargetFrameworkProfile />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="RestSharp" version="105.2.3" targetFramework="net452" requireReinstallation="true" />
|
<package id="RestSharp" version="105.2.3" targetFramework="net452" />
|
||||||
</packages>
|
</packages>
|
|
@ -14,7 +14,7 @@ namespace PlexRequests.Api.Models.Movie
|
||||||
}
|
}
|
||||||
public class Rating
|
public class Rating
|
||||||
{
|
{
|
||||||
public List<double> imdb { get; set; }
|
public List<string> imdb { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,15 +23,15 @@ namespace PlexRequests.Api.Models.Movie
|
||||||
{
|
{
|
||||||
public List<object> disc_art { get; set; }
|
public List<object> disc_art { get; set; }
|
||||||
public List<string> poster { get; set; }
|
public List<string> poster { get; set; }
|
||||||
|
public List<string> backdrop { get; set; }
|
||||||
public List<object> extra_thumbs { get; set; }
|
public List<object> extra_thumbs { get; set; }
|
||||||
public List<string> poster_original { get; set; }
|
public List<string> poster_original { get; set; }
|
||||||
public List<object> landscape { get; set; }
|
public List<string> actors { get; set; }
|
||||||
public string[] actors { get; set; }
|
|
||||||
public List<string> backdrop_original { get; set; }
|
public List<string> backdrop_original { get; set; }
|
||||||
public List<object> clear_art { get; set; }
|
public List<object> clear_art { get; set; }
|
||||||
public List<object> logo { get; set; }
|
public List<object> logo { get; set; }
|
||||||
public List<object> banner { get; set; }
|
public List<object> banner { get; set; }
|
||||||
public List<string> backdrop { get; set; }
|
public List<object> landscape { get; set; }
|
||||||
public List<object> extra_fanart { get; set; }
|
public List<object> extra_fanart { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,16 +42,17 @@ namespace PlexRequests.Api.Models.Movie
|
||||||
public int tmdb_id { get; set; }
|
public int tmdb_id { get; set; }
|
||||||
public string plot { get; set; }
|
public string plot { get; set; }
|
||||||
public string tagline { get; set; }
|
public string tagline { get; set; }
|
||||||
|
public Release_Date release_date { get; set; }
|
||||||
|
public int year { get; set; }
|
||||||
public string original_title { get; set; }
|
public string original_title { get; set; }
|
||||||
public string[] actor_roles { get; set; }
|
public List<string> actor_roles { get; set; }
|
||||||
public bool via_imdb { get; set; }
|
public bool via_imdb { get; set; }
|
||||||
public string mpaa { get; set; }
|
public Images images { get; set; }
|
||||||
public bool via_tmdb { get; set; }
|
|
||||||
public List<string> directors { get; set; }
|
public List<string> directors { get; set; }
|
||||||
public List<string> titles { get; set; }
|
public List<string> titles { get; set; }
|
||||||
public string imdb { get; set; }
|
public string imdb { get; set; }
|
||||||
public int year { get; set; }
|
public string mpaa { get; set; }
|
||||||
public Images images { get; set; }
|
public bool via_tmdb { get; set; }
|
||||||
public List<string> actors { get; set; }
|
public List<string> actors { get; set; }
|
||||||
public List<string> writers { get; set; }
|
public List<string> writers { get; set; }
|
||||||
public int runtime { get; set; }
|
public int runtime { get; set; }
|
||||||
|
@ -59,6 +60,19 @@ namespace PlexRequests.Api.Models.Movie
|
||||||
public string released { get; set; }
|
public string released { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class Release_Date
|
||||||
|
{
|
||||||
|
public int dvd { get; set; }
|
||||||
|
public int expires { get; set; }
|
||||||
|
public int theater { get; set; }
|
||||||
|
public bool bluray { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Files
|
||||||
|
{
|
||||||
|
public List<string> image_poster { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class Identifiers
|
public class Identifiers
|
||||||
{
|
{
|
||||||
public string imdb { get; set; }
|
public string imdb { get; set; }
|
||||||
|
@ -74,8 +88,11 @@ namespace PlexRequests.Api.Models.Movie
|
||||||
public string _rev { get; set; }
|
public string _rev { get; set; }
|
||||||
public string profile_id { get; set; }
|
public string profile_id { get; set; }
|
||||||
public string _id { get; set; }
|
public string _id { get; set; }
|
||||||
|
public List<object> tags { get; set; }
|
||||||
|
public int last_edit { get; set; }
|
||||||
public object category_id { get; set; }
|
public object category_id { get; set; }
|
||||||
public string type { get; set; }
|
public string type { get; set; }
|
||||||
|
public Files files { get; set; }
|
||||||
public Identifiers identifiers { get; set; }
|
public Identifiers identifiers { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
PlexRequests.Api.Models/Movie/CouchPotatoMovies.cs
Normal file
12
PlexRequests.Api.Models/Movie/CouchPotatoMovies.cs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace PlexRequests.Api.Models.Movie
|
||||||
|
{
|
||||||
|
public class CouchPotatoMovies
|
||||||
|
{
|
||||||
|
public List<Movie> movies { get; set; }
|
||||||
|
public int total { get; set; }
|
||||||
|
public bool success { get; set; }
|
||||||
|
public bool empty { get; set; }
|
||||||
|
}
|
||||||
|
}
|
22
PlexRequests.Api.Models/Plex/PlexLibraries.cs
Normal file
22
PlexRequests.Api.Models/Plex/PlexLibraries.cs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace PlexRequests.Api.Models.Plex
|
||||||
|
{
|
||||||
|
[XmlRoot(ElementName = "MediaContainer")]
|
||||||
|
public class PlexLibraries
|
||||||
|
{
|
||||||
|
[XmlElement(ElementName = "Directory")]
|
||||||
|
public List<Directory> Directories { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlRoot(ElementName = "Location")]
|
||||||
|
public partial class Location
|
||||||
|
{
|
||||||
|
[XmlElement(ElementName = "id")]
|
||||||
|
public int id { get; set; }
|
||||||
|
[XmlElement(ElementName = "path")]
|
||||||
|
public string path { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
35
PlexRequests.Api.Models/Plex/PlexMediaType.cs
Normal file
35
PlexRequests.Api.Models/Plex/PlexMediaType.cs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: PlexType.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.Services
|
||||||
|
{
|
||||||
|
public enum PlexMediaType
|
||||||
|
{
|
||||||
|
Movie,
|
||||||
|
Show,
|
||||||
|
Music // double check this one
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,8 @@ namespace PlexRequests.Api.Models.Plex
|
||||||
public string Key { get; set; }
|
public string Key { get; set; }
|
||||||
[XmlAttribute(AttributeName = "title")]
|
[XmlAttribute(AttributeName = "title")]
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
|
[XmlAttribute(AttributeName = "type")]
|
||||||
|
public string type { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[XmlRoot(ElementName = "MediaContainer")]
|
[XmlRoot(ElementName = "MediaContainer")]
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>PlexRequests.Api.Models</RootNamespace>
|
<RootNamespace>PlexRequests.Api.Models</RootNamespace>
|
||||||
<AssemblyName>PlexRequests.Api.Models</AssemblyName>
|
<AssemblyName>PlexRequests.Api.Models</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<TargetFrameworkProfile />
|
<TargetFrameworkProfile />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@ -46,6 +46,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Movie\CouchPotatoAdd.cs" />
|
<Compile Include="Movie\CouchPotatoAdd.cs" />
|
||||||
|
<Compile Include="Movie\CouchPotatoMovies.cs" />
|
||||||
<Compile Include="Movie\CouchPotatoProfiles.cs" />
|
<Compile Include="Movie\CouchPotatoProfiles.cs" />
|
||||||
<Compile Include="Movie\CouchPotatoStatus.cs" />
|
<Compile Include="Movie\CouchPotatoStatus.cs" />
|
||||||
<Compile Include="Music\HeadphonesAlbumSearchResult.cs" />
|
<Compile Include="Music\HeadphonesAlbumSearchResult.cs" />
|
||||||
|
@ -62,17 +63,21 @@
|
||||||
<Compile Include="Plex\PlexAuthentication.cs" />
|
<Compile Include="Plex\PlexAuthentication.cs" />
|
||||||
<Compile Include="Plex\PlexError.cs" />
|
<Compile Include="Plex\PlexError.cs" />
|
||||||
<Compile Include="Plex\PlexFriends.cs" />
|
<Compile Include="Plex\PlexFriends.cs" />
|
||||||
|
<Compile Include="Plex\PlexLibraries.cs" />
|
||||||
<Compile Include="Plex\PlexSearch.cs" />
|
<Compile Include="Plex\PlexSearch.cs" />
|
||||||
<Compile Include="Plex\PlexStatus.cs" />
|
<Compile Include="Plex\PlexStatus.cs" />
|
||||||
|
<Compile Include="Plex\PlexMediaType.cs" />
|
||||||
<Compile Include="Plex\PlexUserRequest.cs" />
|
<Compile Include="Plex\PlexUserRequest.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="SickRage\SickRageBase.cs" />
|
<Compile Include="SickRage\SickRageBase.cs" />
|
||||||
|
<Compile Include="SickRage\SickrageShows.cs" />
|
||||||
<Compile Include="SickRage\SickRagePing.cs" />
|
<Compile Include="SickRage\SickRagePing.cs" />
|
||||||
<Compile Include="SickRage\SickRageSeasonList.cs" />
|
<Compile Include="SickRage\SickRageSeasonList.cs" />
|
||||||
<Compile Include="SickRage\SickRageShowInformation.cs" />
|
<Compile Include="SickRage\SickRageShowInformation.cs" />
|
||||||
<Compile Include="SickRage\SickRageStatus.cs" />
|
<Compile Include="SickRage\SickRageStatus.cs" />
|
||||||
<Compile Include="SickRage\SickRageTvAdd.cs" />
|
<Compile Include="SickRage\SickRageTvAdd.cs" />
|
||||||
<Compile Include="Sonarr\SonarrAddSeries.cs" />
|
<Compile Include="Sonarr\SonarrAddSeries.cs" />
|
||||||
|
<Compile Include="Sonarr\SonarrAllSeries.cs" />
|
||||||
<Compile Include="Sonarr\SonarrError.cs" />
|
<Compile Include="Sonarr\SonarrError.cs" />
|
||||||
<Compile Include="Sonarr\SonarrProfile.cs" />
|
<Compile Include="Sonarr\SonarrProfile.cs" />
|
||||||
<Compile Include="Sonarr\SystemStatus.cs" />
|
<Compile Include="Sonarr\SystemStatus.cs" />
|
||||||
|
@ -87,6 +92,12 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\PlexRequests.Helpers\PlexRequests.Helpers.csproj">
|
||||||
|
<Project>{1252336D-42A3-482A-804C-836E60173DFA}</Project>
|
||||||
|
<Name>PlexRequests.Helpers</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
namespace PlexRequests.Api.Models.SickRage
|
namespace PlexRequests.Api.Models.SickRage
|
||||||
{
|
{
|
||||||
public class SickRageBase<T>
|
public abstract class SickRageBase<T>
|
||||||
{
|
{
|
||||||
public T data { get; set; }
|
public T data { get; set; }
|
||||||
public string message { get; set; }
|
public string message { get; set; }
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
namespace PlexRequests.Api.Models.SickRage
|
using Newtonsoft.Json;
|
||||||
|
using PlexRequests.Helpers;
|
||||||
|
|
||||||
|
namespace PlexRequests.Api.Models.SickRage
|
||||||
{
|
{
|
||||||
public class SickRageSeasonList : SickRageBase<int[]>
|
public class SickRageSeasonList : SickRageBase<object>
|
||||||
{
|
{
|
||||||
|
[JsonIgnore]
|
||||||
|
public int[] Data => JsonConvertHelper.ParseObjectToArray<int>(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
42
PlexRequests.Api.Models/SickRage/SickrageShows.cs
Normal file
42
PlexRequests.Api.Models/SickRage/SickrageShows.cs
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: SickrageShows.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;
|
||||||
|
|
||||||
|
namespace PlexRequests.Api.Models.SickRage
|
||||||
|
{
|
||||||
|
public class SickrageShows : SickRageBase<Dictionary<int, Item>>
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Item
|
||||||
|
{
|
||||||
|
public int tvdbid { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace PlexRequests.Api.Models.Sonarr
|
namespace PlexRequests.Api.Models.Sonarr
|
||||||
{
|
{
|
||||||
|
@ -8,6 +9,17 @@ namespace PlexRequests.Api.Models.Sonarr
|
||||||
{
|
{
|
||||||
public int seasonNumber { get; set; }
|
public int seasonNumber { get; set; }
|
||||||
public bool monitored { get; set; }
|
public bool monitored { get; set; }
|
||||||
|
public Statistics statistics { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Statistics
|
||||||
|
{
|
||||||
|
public int episodeFileCount { get; set; }
|
||||||
|
public int episodeCount { get; set; }
|
||||||
|
public int totalEpisodeCount { get; set; }
|
||||||
|
public long sizeOnDisk { get; set; }
|
||||||
|
public float percentOfEpisodes { get; set; }
|
||||||
|
public DateTime previousAiring { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SonarrAddSeries
|
public class SonarrAddSeries
|
||||||
|
@ -26,7 +38,7 @@ namespace PlexRequests.Api.Models.Sonarr
|
||||||
public string titleSlug { get; set; }
|
public string titleSlug { get; set; }
|
||||||
public int id { get; set; }
|
public int id { get; set; }
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public string ErrorMessage { get; set; }
|
public List<string> ErrorMessages { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AddOptions
|
public class AddOptions
|
||||||
|
@ -35,7 +47,4 @@ namespace PlexRequests.Api.Models.Sonarr
|
||||||
public bool ignoreEpisodesWithoutFiles { get; set; }
|
public bool ignoreEpisodesWithoutFiles { get; set; }
|
||||||
public bool searchForMissingEpisodes { get; set; }
|
public bool searchForMissingEpisodes { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
69
PlexRequests.Api.Models/Sonarr/SonarrAllSeries.cs
Normal file
69
PlexRequests.Api.Models/Sonarr/SonarrAllSeries.cs
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace PlexRequests.Api.Models.Sonarr
|
||||||
|
{
|
||||||
|
public class SonarrAllSeries
|
||||||
|
{
|
||||||
|
public List<Series> list { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Series
|
||||||
|
{
|
||||||
|
public string title { get; set; }
|
||||||
|
public List<Alternatetitle> alternateTitles { get; set; }
|
||||||
|
public string sortTitle { get; set; }
|
||||||
|
public int seasonCount { get; set; }
|
||||||
|
public int totalEpisodeCount { get; set; }
|
||||||
|
public int episodeCount { get; set; }
|
||||||
|
public int episodeFileCount { get; set; }
|
||||||
|
public long sizeOnDisk { get; set; }
|
||||||
|
public string status { get; set; }
|
||||||
|
public string overview { get; set; }
|
||||||
|
public DateTime previousAiring { get; set; }
|
||||||
|
public string network { get; set; }
|
||||||
|
public List<Image> images { get; set; }
|
||||||
|
public List<Season> seasons { get; set; }
|
||||||
|
public int year { get; set; }
|
||||||
|
public string path { get; set; }
|
||||||
|
public int profileId { get; set; }
|
||||||
|
public bool seasonFolder { get; set; }
|
||||||
|
public bool monitored { get; set; }
|
||||||
|
public bool useSceneNumbering { get; set; }
|
||||||
|
public int runtime { get; set; }
|
||||||
|
public int tvdbId { get; set; }
|
||||||
|
public int tvRageId { get; set; }
|
||||||
|
public int tvMazeId { get; set; }
|
||||||
|
public DateTime firstAired { get; set; }
|
||||||
|
public DateTime lastInfoSync { get; set; }
|
||||||
|
public string seriesType { get; set; }
|
||||||
|
public string cleanTitle { get; set; }
|
||||||
|
public string imdbId { get; set; }
|
||||||
|
public string titleSlug { get; set; }
|
||||||
|
public string certification { get; set; }
|
||||||
|
public List<string> genres { get; set; }
|
||||||
|
public List<object> tags { get; set; }
|
||||||
|
public DateTime added { get; set; }
|
||||||
|
public Ratings ratings { get; set; }
|
||||||
|
public int qualityProfileId { get; set; }
|
||||||
|
public int id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Ratings
|
||||||
|
{
|
||||||
|
public int votes { get; set; }
|
||||||
|
public float value { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Alternatetitle
|
||||||
|
{
|
||||||
|
public string title { get; set; }
|
||||||
|
public int seasonNumber { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Image
|
||||||
|
{
|
||||||
|
public string coverType { get; set; }
|
||||||
|
public string url { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,13 +24,22 @@
|
||||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
// ************************************************************************/
|
// ************************************************************************/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace PlexRequests.Api.Models.Sonarr
|
namespace PlexRequests.Api.Models.Sonarr
|
||||||
{
|
{
|
||||||
public class SonarrError
|
public class SonarrError
|
||||||
{
|
{
|
||||||
public string propertyName { get; set; }
|
public string propertyName { get; set; }
|
||||||
public string errorMessage { get; set; }
|
public string errorMessage { get; set; }
|
||||||
public string attemptedValue { get; set; }
|
public object attemptedValue { get; set; }
|
||||||
public string[] formattedMessageArguments { get; set; }
|
public FormattedMessagePlaceholderValues formattedMessagePlaceholderValues { get; set; }
|
||||||
|
}
|
||||||
|
public class FormattedMessagePlaceholderValues
|
||||||
|
{
|
||||||
|
public string propertyName { get; set; }
|
||||||
|
public object propertyValue { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -25,6 +25,7 @@
|
||||||
// ************************************************************************/
|
// ************************************************************************/
|
||||||
#endregion
|
#endregion
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Xml.Serialization;
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
@ -33,13 +34,19 @@ using Newtonsoft.Json;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
|
||||||
using PlexRequests.Api.Interfaces;
|
using PlexRequests.Api.Interfaces;
|
||||||
|
using PlexRequests.Helpers;
|
||||||
using RestSharp;
|
using RestSharp;
|
||||||
|
|
||||||
namespace PlexRequests.Api
|
namespace PlexRequests.Api
|
||||||
{
|
{
|
||||||
public class ApiRequest : IApiRequest
|
public class ApiRequest : IApiRequest
|
||||||
{
|
{
|
||||||
|
private JsonSerializerSettings Settings = new JsonSerializerSettings
|
||||||
|
{
|
||||||
|
NullValueHandling = NullValueHandling.Ignore,
|
||||||
|
MissingMemberHandling = MissingMemberHandling.Ignore
|
||||||
|
};
|
||||||
|
|
||||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An API request handler
|
/// An API request handler
|
||||||
|
@ -53,6 +60,8 @@ namespace PlexRequests.Api
|
||||||
var client = new RestClient { BaseUrl = baseUri };
|
var client = new RestClient { BaseUrl = baseUri };
|
||||||
|
|
||||||
var response = client.Execute<T>(request);
|
var response = client.Execute<T>(request);
|
||||||
|
Log.Trace("Api Content Response:");
|
||||||
|
Log.Trace(response.Content);
|
||||||
|
|
||||||
if (response.ErrorException != null)
|
if (response.ErrorException != null)
|
||||||
{
|
{
|
||||||
|
@ -61,7 +70,6 @@ namespace PlexRequests.Api
|
||||||
}
|
}
|
||||||
|
|
||||||
return response.Data;
|
return response.Data;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IRestResponse Execute(IRestRequest request, Uri baseUri)
|
public IRestResponse Execute(IRestRequest request, Uri baseUri)
|
||||||
|
@ -100,15 +108,17 @@ namespace PlexRequests.Api
|
||||||
var client = new RestClient { BaseUrl = baseUri };
|
var client = new RestClient { BaseUrl = baseUri };
|
||||||
|
|
||||||
var response = client.Execute(request);
|
var response = client.Execute(request);
|
||||||
|
Log.Trace("Api Content Response:");
|
||||||
|
Log.Trace(response.Content);
|
||||||
if (response.ErrorException != null)
|
if (response.ErrorException != null)
|
||||||
{
|
{
|
||||||
var message = "Error retrieving response. Check inner details for more info.";
|
var message = "Error retrieving response. Check inner details for more info.";
|
||||||
throw new ApplicationException(message, response.ErrorException);
|
throw new ApplicationException(message, response.ErrorException);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.Trace("Deserialzing Object");
|
||||||
var json = JsonConvert.DeserializeObject<T>(response.Content);
|
var json = JsonConvert.DeserializeObject<T>(response.Content, Settings);
|
||||||
|
Log.Trace("Finished Deserialzing Object");
|
||||||
|
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
@ -129,4 +139,6 @@ namespace PlexRequests.Api
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,5 +115,16 @@ namespace PlexRequests.Api
|
||||||
|
|
||||||
return Api.Execute<CouchPotatoProfiles>(request, url);
|
return Api.Execute<CouchPotatoProfiles>(request, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CouchPotatoMovies GetMovies(Uri baseUrl, string apiKey, string[] status)
|
||||||
|
{
|
||||||
|
RestRequest request;
|
||||||
|
request = new RestRequest { Resource = "/api/{apikey}/movie.list?status={status}" };
|
||||||
|
|
||||||
|
request.AddUrlSegment("apikey", apiKey);
|
||||||
|
request.AddUrlSegment("status", string.Join(",", status));
|
||||||
|
|
||||||
|
return Api.Execute<CouchPotatoMovies>(request, baseUrl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -55,5 +55,10 @@ namespace PlexRequests.Api.Mocks
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Series> GetSeries(string apiKey, Uri baseUrl)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -32,6 +32,8 @@ using PlexRequests.Api.Models.Plex;
|
||||||
using PlexRequests.Helpers;
|
using PlexRequests.Helpers;
|
||||||
|
|
||||||
using RestSharp;
|
using RestSharp;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace PlexRequests.Api
|
namespace PlexRequests.Api
|
||||||
{
|
{
|
||||||
|
@ -58,10 +60,7 @@ namespace PlexRequests.Api
|
||||||
Method = Method.POST
|
Method = Method.POST
|
||||||
};
|
};
|
||||||
|
|
||||||
request.AddHeader("X-Plex-Client-Identifier", "Test213"); // TODO need something unique to the users version/installation
|
AddHeaders(ref request);
|
||||||
request.AddHeader("X-Plex-Product", "Request Plex");
|
|
||||||
request.AddHeader("X-Plex-Version", Version);
|
|
||||||
request.AddHeader("Content-Type", "application/json");
|
|
||||||
|
|
||||||
request.AddJsonBody(userModel);
|
request.AddJsonBody(userModel);
|
||||||
|
|
||||||
|
@ -76,11 +75,7 @@ namespace PlexRequests.Api
|
||||||
Method = Method.GET,
|
Method = Method.GET,
|
||||||
};
|
};
|
||||||
|
|
||||||
request.AddHeader("X-Plex-Client-Identifier", "Test213");
|
AddHeaders(ref request, authToken);
|
||||||
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 api = new ApiRequest();
|
||||||
var users = api.ExecuteXml<PlexFriends>(request, new Uri("https://plex.tv/pms/friends/all"));
|
var users = api.ExecuteXml<PlexFriends>(request, new Uri("https://plex.tv/pms/friends/all"));
|
||||||
|
@ -104,11 +99,7 @@ namespace PlexRequests.Api
|
||||||
};
|
};
|
||||||
|
|
||||||
request.AddUrlSegment("searchTerm", searchTerm);
|
request.AddUrlSegment("searchTerm", searchTerm);
|
||||||
request.AddHeader("X-Plex-Client-Identifier", "Test213");
|
AddHeaders(ref request, authToken);
|
||||||
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 api = new ApiRequest();
|
||||||
var search = api.ExecuteXml<PlexSearch>(request, plexFullHost);
|
var search = api.ExecuteXml<PlexSearch>(request, plexFullHost);
|
||||||
|
@ -123,11 +114,7 @@ namespace PlexRequests.Api
|
||||||
Method = Method.GET,
|
Method = Method.GET,
|
||||||
};
|
};
|
||||||
|
|
||||||
request.AddHeader("X-Plex-Client-Identifier", "Test213");
|
AddHeaders(ref request, authToken);
|
||||||
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 api = new ApiRequest();
|
||||||
var users = api.ExecuteXml<PlexStatus>(request, uri);
|
var users = api.ExecuteXml<PlexStatus>(request, uri);
|
||||||
|
@ -142,17 +129,60 @@ namespace PlexRequests.Api
|
||||||
Method = Method.GET,
|
Method = Method.GET,
|
||||||
};
|
};
|
||||||
|
|
||||||
request.AddHeader("X-Plex-Client-Identifier", "Test213");
|
AddHeaders(ref request, authToken);
|
||||||
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 api = new ApiRequest();
|
||||||
var account = api.ExecuteXml<PlexAccount>(request, new Uri("https://plex.tv/users/account"));
|
var account = api.ExecuteXml<PlexAccount>(request, new Uri("https://plex.tv/users/account"));
|
||||||
|
|
||||||
return account;
|
return account;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PlexLibraries GetLibrarySections(string authToken, Uri plexFullHost)
|
||||||
|
{
|
||||||
|
var request = new RestRequest
|
||||||
|
{
|
||||||
|
Method = Method.GET,
|
||||||
|
Resource = "library/sections"
|
||||||
|
};
|
||||||
|
|
||||||
|
AddHeaders(ref request, authToken);
|
||||||
|
|
||||||
|
var api = new ApiRequest();
|
||||||
|
var sections = api.ExecuteXml<PlexLibraries>(request, plexFullHost);
|
||||||
|
|
||||||
|
return sections;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlexSearch GetLibrary(string authToken, Uri plexFullHost, string libraryId)
|
||||||
|
{
|
||||||
|
var request = new RestRequest
|
||||||
|
{
|
||||||
|
Method = Method.GET,
|
||||||
|
Resource = "library/sections/{libraryId}/all"
|
||||||
|
};
|
||||||
|
|
||||||
|
request.AddUrlSegment("libraryId", libraryId.ToString());
|
||||||
|
AddHeaders(ref request, authToken);
|
||||||
|
|
||||||
|
var api = new ApiRequest();
|
||||||
|
var search = api.ExecuteXml<PlexSearch>(request, plexFullHost);
|
||||||
|
|
||||||
|
return search;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddHeaders(ref RestRequest request, string authToken)
|
||||||
|
{
|
||||||
|
request.AddHeader("X-Plex-Token", authToken);
|
||||||
|
AddHeaders(ref request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddHeaders(ref RestRequest request)
|
||||||
|
{
|
||||||
|
request.AddHeader("X-Plex-Client-Identifier", "Test213");
|
||||||
|
request.AddHeader("X-Plex-Product", "Request Plex");
|
||||||
|
request.AddHeader("X-Plex-Version", Version);
|
||||||
|
request.AddHeader("Content-Type", "application/xml");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>PlexRequests.Api</RootNamespace>
|
<RootNamespace>PlexRequests.Api</RootNamespace>
|
||||||
<AssemblyName>PlexRequests.Api</AssemblyName>
|
<AssemblyName>PlexRequests.Api</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<TargetFrameworkProfile />
|
<TargetFrameworkProfile />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
|
@ -28,15 +28,18 @@
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using NLog;
|
using NLog;
|
||||||
using PlexRequests.Api.Interfaces;
|
using PlexRequests.Api.Interfaces;
|
||||||
using PlexRequests.Api.Models.SickRage;
|
using PlexRequests.Api.Models.SickRage;
|
||||||
using PlexRequests.Helpers;
|
using PlexRequests.Helpers;
|
||||||
using RestSharp;
|
using RestSharp;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace PlexRequests.Api
|
namespace PlexRequests.Api
|
||||||
{
|
{
|
||||||
|
@ -55,9 +58,13 @@ namespace PlexRequests.Api
|
||||||
public async Task<SickRageTvAdd> AddSeries(int tvdbId, int seasonCount, int[] seasons, string quality, string apiKey,
|
public async Task<SickRageTvAdd> AddSeries(int tvdbId, int seasonCount, int[] seasons, string quality, string apiKey,
|
||||||
Uri baseUrl)
|
Uri baseUrl)
|
||||||
{
|
{
|
||||||
|
|
||||||
var futureStatus = seasons.Length > 0 && !seasons.Any(x => x == seasonCount) ? SickRageStatus.Skipped : SickRageStatus.Wanted;
|
var futureStatus = seasons.Length > 0 && !seasons.Any(x => x == seasonCount) ? SickRageStatus.Skipped : SickRageStatus.Wanted;
|
||||||
var status = seasons.Length > 0 ? SickRageStatus.Skipped : SickRageStatus.Wanted;
|
var status = seasons.Length > 0 ? SickRageStatus.Skipped : SickRageStatus.Wanted;
|
||||||
|
|
||||||
|
Log.Trace("Future Status: {0}", futureStatus);
|
||||||
|
Log.Trace("Current Status: {0}", status);
|
||||||
|
|
||||||
var request = new RestRequest
|
var request = new RestRequest
|
||||||
{
|
{
|
||||||
Resource = "/api/{apiKey}/?cmd=show.addnew",
|
Resource = "/api/{apiKey}/?cmd=show.addnew",
|
||||||
|
@ -69,10 +76,15 @@ namespace PlexRequests.Api
|
||||||
request.AddQueryParameter("future_status", futureStatus);
|
request.AddQueryParameter("future_status", futureStatus);
|
||||||
if (!quality.Equals("default", StringComparison.CurrentCultureIgnoreCase))
|
if (!quality.Equals("default", StringComparison.CurrentCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
|
Log.Trace("Settings quality to {0}", quality);
|
||||||
request.AddQueryParameter("initial", quality);
|
request.AddQueryParameter("initial", quality);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.Trace("Entering `Execute<SickRageTvAdd>`");
|
||||||
var obj = Api.Execute<SickRageTvAdd>(request, baseUrl);
|
var obj = Api.Execute<SickRageTvAdd>(request, baseUrl);
|
||||||
|
Log.Trace("Exiting `Execute<SickRageTvAdd>`");
|
||||||
|
Log.Trace("obj Result:");
|
||||||
|
Log.Trace(obj.DumpJson());
|
||||||
|
|
||||||
if (obj.result != "failure")
|
if (obj.result != "failure")
|
||||||
{
|
{
|
||||||
|
@ -81,10 +93,19 @@ namespace PlexRequests.Api
|
||||||
|
|
||||||
var seasonIncrement = 0;
|
var seasonIncrement = 0;
|
||||||
var seasonList = new SickRageSeasonList();
|
var seasonList = new SickRageSeasonList();
|
||||||
|
Log.Trace("while (seasonIncrement < seasonCount) where seasonCount = {0}", seasonCount);
|
||||||
|
try
|
||||||
|
{
|
||||||
while (seasonIncrement < seasonCount)
|
while (seasonIncrement < seasonCount)
|
||||||
{
|
{
|
||||||
seasonList = VerifyShowHasLoaded(tvdbId, apiKey, baseUrl);
|
seasonList = VerifyShowHasLoaded(tvdbId, apiKey, baseUrl);
|
||||||
seasonIncrement = seasonList.data?.Length ?? 0;
|
if (seasonList.result.Equals("failure"))
|
||||||
|
{
|
||||||
|
Thread.Sleep(3000);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
seasonIncrement = seasonList.Data?.Length ?? 0;
|
||||||
|
Log.Trace("New seasonIncrement -> {0}", seasonIncrement);
|
||||||
|
|
||||||
if (sw.ElapsedMilliseconds > 30000) // Break out after 30 seconds, it's not going to get added
|
if (sw.ElapsedMilliseconds > 30000) // Break out after 30 seconds, it's not going to get added
|
||||||
{
|
{
|
||||||
|
@ -94,17 +115,35 @@ namespace PlexRequests.Api
|
||||||
}
|
}
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Error("Exception thrown when getting the seasonList");
|
||||||
|
Log.Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.Trace("seasons.Length > 0 where seasons.Len -> {0}", seasons.Length);
|
||||||
|
try
|
||||||
|
{
|
||||||
if (seasons.Length > 0)
|
if (seasons.Length > 0)
|
||||||
{
|
{
|
||||||
//handle the seasons requested
|
//handle the seasons requested
|
||||||
foreach (var s in seasons)
|
foreach (var s in seasons)
|
||||||
{
|
{
|
||||||
|
Log.Trace("Adding season {0}", s);
|
||||||
var result = await AddSeason(tvdbId, s, apiKey, baseUrl);
|
var result = await AddSeason(tvdbId, s, apiKey, baseUrl);
|
||||||
Log.Trace("SickRage adding season results: ");
|
Log.Trace("SickRage adding season results: ");
|
||||||
Log.Trace(result.DumpJson());
|
Log.Trace(result.DumpJson());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Trace("Exception when adding seasons:");
|
||||||
|
Log.Error(e);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.Trace("Finished with the API, returning the obj");
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,6 +163,7 @@ namespace PlexRequests.Api
|
||||||
|
|
||||||
public SickRageSeasonList VerifyShowHasLoaded(int tvdbId, string apiKey, Uri baseUrl)
|
public SickRageSeasonList VerifyShowHasLoaded(int tvdbId, string apiKey, Uri baseUrl)
|
||||||
{
|
{
|
||||||
|
Log.Trace("Entered `VerifyShowHasLoaded({0} <- id)`", tvdbId);
|
||||||
var request = new RestRequest
|
var request = new RestRequest
|
||||||
{
|
{
|
||||||
Resource = "/api/{apiKey}/?cmd=show.seasonlist",
|
Resource = "/api/{apiKey}/?cmd=show.seasonlist",
|
||||||
|
@ -134,7 +174,9 @@ namespace PlexRequests.Api
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
Log.Trace("Entering `ExecuteJson<SickRageSeasonList>`");
|
||||||
var obj = Api.ExecuteJson<SickRageSeasonList>(request, baseUrl);
|
var obj = Api.ExecuteJson<SickRageSeasonList>(request, baseUrl);
|
||||||
|
Log.Trace("Exited `ExecuteJson<SickRageSeasonList>`");
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -157,7 +199,26 @@ namespace PlexRequests.Api
|
||||||
request.AddQueryParameter("status", SickRageStatus.Wanted);
|
request.AddQueryParameter("status", SickRageStatus.Wanted);
|
||||||
|
|
||||||
await Task.Run(() => Thread.Sleep(2000));
|
await Task.Run(() => Thread.Sleep(2000));
|
||||||
return await Task.Run(() => Api.Execute<SickRageTvAdd>(request, baseUrl)).ConfigureAwait(false);
|
return await Task.Run(() =>
|
||||||
|
{
|
||||||
|
Log.Trace("Entering `Execute<SickRageTvAdd>` in a new `Task<T>`");
|
||||||
|
var result = Api.Execute<SickRageTvAdd>(request, baseUrl);
|
||||||
|
|
||||||
|
Log.Trace("Exiting `Execute<SickRageTvAdd>` and yeilding `Task<T>` result");
|
||||||
|
return result;
|
||||||
|
}).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<SickrageShows> GetShows(string apiKey, Uri baseUrl)
|
||||||
|
{
|
||||||
|
var request = new RestRequest
|
||||||
|
{
|
||||||
|
Resource = "/api/{apiKey}/?cmd=shows",
|
||||||
|
Method = Method.GET
|
||||||
|
};
|
||||||
|
request.AddUrlSegment("apiKey", apiKey);
|
||||||
|
|
||||||
|
return await Task.Run(() => Api.Execute<SickrageShows>(request, baseUrl)).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -36,6 +36,7 @@ using PlexRequests.Api.Models.Sonarr;
|
||||||
using PlexRequests.Helpers;
|
using PlexRequests.Helpers;
|
||||||
|
|
||||||
using RestSharp;
|
using RestSharp;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace PlexRequests.Api
|
namespace PlexRequests.Api
|
||||||
{
|
{
|
||||||
|
@ -104,8 +105,10 @@ namespace PlexRequests.Api
|
||||||
catch (JsonSerializationException jse)
|
catch (JsonSerializationException jse)
|
||||||
{
|
{
|
||||||
Log.Error(jse);
|
Log.Error(jse);
|
||||||
var error = Api.ExecuteJson<SonarrError>(request, baseUrl);
|
var error = Api.ExecuteJson<List<SonarrError>>(request, baseUrl);
|
||||||
result = new SonarrAddSeries { ErrorMessage = error.errorMessage };
|
var messages = error?.Select(x => x.errorMessage).ToList();
|
||||||
|
messages?.ForEach(x => Log.Error(x));
|
||||||
|
result = new SonarrAddSeries { ErrorMessages = messages };
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -120,5 +123,13 @@ namespace PlexRequests.Api
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Series> GetSeries(string apiKey, Uri baseUrl)
|
||||||
|
{
|
||||||
|
var request = new RestRequest { Resource = "/api/series", Method = Method.GET };
|
||||||
|
request.AddHeader("X-Api-Key", apiKey);
|
||||||
|
|
||||||
|
return Api.Execute<List<Series>>(request, baseUrl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<runtime>
|
<runtime>
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
|
@ -8,4 +8,4 @@
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
</assemblyBinding>
|
</assemblyBinding>
|
||||||
</runtime>
|
</runtime>
|
||||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" /></startup></configuration>
|
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/></startup></configuration>
|
||||||
|
|
|
@ -4,6 +4,6 @@
|
||||||
<package id="Nancy" version="1.4.3" targetFramework="net452" />
|
<package id="Nancy" version="1.4.3" targetFramework="net452" />
|
||||||
<package id="Newtonsoft.Json" version="8.0.2" targetFramework="net452" />
|
<package id="Newtonsoft.Json" version="8.0.2" targetFramework="net452" />
|
||||||
<package id="NLog" version="4.2.3" targetFramework="net452" />
|
<package id="NLog" version="4.2.3" targetFramework="net452" />
|
||||||
<package id="RestSharp" version="105.2.3" targetFramework="net452" requireReinstallation="true" />
|
<package id="RestSharp" version="105.2.3" targetFramework="net452" />
|
||||||
<package id="TMDbLib" version="0.9.0.0-alpha" targetFramework="net452" />
|
<package id="TMDbLib" version="0.9.0.0-alpha" targetFramework="net452" />
|
||||||
</packages>
|
</packages>
|
|
@ -8,7 +8,7 @@
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>PlexRequests.Core.Tests</RootNamespace>
|
<RootNamespace>PlexRequests.Core.Tests</RootNamespace>
|
||||||
<AssemblyName>PlexRequests.Core.Tests</AssemblyName>
|
<AssemblyName>PlexRequests.Core.Tests</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<runtime>
|
<runtime>
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
|
@ -8,4 +8,4 @@
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
</assemblyBinding>
|
</assemblyBinding>
|
||||||
</runtime>
|
</runtime>
|
||||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" /></startup></configuration>
|
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/></startup></configuration>
|
||||||
|
|
|
@ -28,9 +28,19 @@ namespace PlexRequests.Core
|
||||||
{
|
{
|
||||||
public class CacheKeys
|
public class CacheKeys
|
||||||
{
|
{
|
||||||
|
public const string PlexLibaries = "PlexLibaries";
|
||||||
|
|
||||||
public const string TvDbToken = "TheTvDbApiToken";
|
public const string TvDbToken = "TheTvDbApiToken";
|
||||||
|
|
||||||
public const string SonarrQualityProfiles = "SonarrQualityProfiles";
|
public const string SonarrQualityProfiles = "SonarrQualityProfiles";
|
||||||
|
public const string SonarrQueued = "SonarrQueued";
|
||||||
|
|
||||||
public const string SickRageQualityProfiles = "SickRageQualityProfiles";
|
public const string SickRageQualityProfiles = "SickRageQualityProfiles";
|
||||||
|
public const string SickRageQueued = "SickRageQueued";
|
||||||
|
|
||||||
public const string CouchPotatoQualityProfiles = "CouchPotatoQualityProfiles";
|
public const string CouchPotatoQualityProfiles = "CouchPotatoQualityProfiles";
|
||||||
|
public const string CouchPotatoQueued = "CouchPotatoQueued";
|
||||||
|
|
||||||
|
public const string GetBaseUrl = "GetBaseUrl";
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,7 +9,7 @@
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>PlexRequests.Core</RootNamespace>
|
<RootNamespace>PlexRequests.Core</RootNamespace>
|
||||||
<AssemblyName>PlexRequests.Core</AssemblyName>
|
<AssemblyName>PlexRequests.Core</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<TargetFrameworkProfile />
|
<TargetFrameworkProfile />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace PlexRequests.Core.SettingModels
|
||||||
public class PlexRequestSettings : Settings
|
public class PlexRequestSettings : Settings
|
||||||
{
|
{
|
||||||
public int Port { get; set; }
|
public int Port { get; set; }
|
||||||
|
public string BaseUrl { get; set; }
|
||||||
public bool SearchForMovies { get; set; }
|
public bool SearchForMovies { get; set; }
|
||||||
public bool SearchForTvShows { get; set; }
|
public bool SearchForTvShows { get; set; }
|
||||||
public bool SearchForMusic { get; set; }
|
public bool SearchForMusic { get; set; }
|
||||||
|
|
|
@ -44,7 +44,7 @@ namespace PlexRequests.Core
|
||||||
{
|
{
|
||||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
private static DbConfiguration Db { get; set; }
|
private static DbConfiguration Db { get; set; }
|
||||||
public string SetupDb()
|
public string SetupDb(string urlBase)
|
||||||
{
|
{
|
||||||
Db = new DbConfiguration(new SqliteFactory());
|
Db = new DbConfiguration(new SqliteFactory());
|
||||||
var created = Db.CheckDb();
|
var created = Db.CheckDb();
|
||||||
|
@ -52,7 +52,7 @@ namespace PlexRequests.Core
|
||||||
|
|
||||||
if (created)
|
if (created)
|
||||||
{
|
{
|
||||||
CreateDefaultSettingsPage();
|
CreateDefaultSettingsPage(urlBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
var version = CheckSchema();
|
var version = CheckSchema();
|
||||||
|
@ -89,7 +89,7 @@ namespace PlexRequests.Core
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateDefaultSettingsPage()
|
private void CreateDefaultSettingsPage(string baseUrl)
|
||||||
{
|
{
|
||||||
var defaultSettings = new PlexRequestSettings
|
var defaultSettings = new PlexRequestSettings
|
||||||
{
|
{
|
||||||
|
@ -97,7 +97,8 @@ namespace PlexRequests.Core
|
||||||
RequireMovieApproval = true,
|
RequireMovieApproval = true,
|
||||||
SearchForMovies = true,
|
SearchForMovies = true,
|
||||||
SearchForTvShows = true,
|
SearchForTvShows = true,
|
||||||
WeeklyRequestLimit = 0
|
WeeklyRequestLimit = 0,
|
||||||
|
BaseUrl = baseUrl ?? string.Empty
|
||||||
};
|
};
|
||||||
var s = new SettingsServiceV2<PlexRequestSettings>(new SettingsJsonRepository(new DbConfiguration(new SqliteFactory()), new MemoryCacheProvider()));
|
var s = new SettingsServiceV2<PlexRequestSettings>(new SettingsJsonRepository(new DbConfiguration(new SqliteFactory()), new MemoryCacheProvider()));
|
||||||
s.SaveSettings(defaultSettings);
|
s.SaveSettings(defaultSettings);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<runtime>
|
<runtime>
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
|
@ -8,4 +8,4 @@
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
</assemblyBinding>
|
</assemblyBinding>
|
||||||
</runtime>
|
</runtime>
|
||||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" /></startup></configuration>
|
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/></startup></configuration>
|
||||||
|
|
54
PlexRequests.Helpers/JsonConvertHelper.cs
Normal file
54
PlexRequests.Helpers/JsonConvertHelper.cs
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: JsonConvertHelper.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 Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PlexRequests.Helpers
|
||||||
|
{
|
||||||
|
public static class JsonConvertHelper
|
||||||
|
{
|
||||||
|
public static T[] ParseObjectToArray<T>(object ambiguousObject)
|
||||||
|
{
|
||||||
|
var json = ambiguousObject.ToString();
|
||||||
|
if (string.IsNullOrWhiteSpace(json))
|
||||||
|
{
|
||||||
|
return new T[0]; // Could return null here instead.
|
||||||
|
}
|
||||||
|
if (json.TrimStart().StartsWith("["))
|
||||||
|
{
|
||||||
|
return JsonConvert.DeserializeObject<T[]>(json);
|
||||||
|
}
|
||||||
|
if (json.TrimStart().Equals("{}"))
|
||||||
|
{
|
||||||
|
return new T[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return new T[1] { JsonConvert.DeserializeObject<T>(json) };
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -106,7 +106,7 @@ namespace PlexRequests.Helpers
|
||||||
CreateDirs = true
|
CreateDirs = true
|
||||||
};
|
};
|
||||||
config.AddTarget(fileTarget);
|
config.AddTarget(fileTarget);
|
||||||
var rule2 = new LoggingRule("*", LogLevel.Trace, fileTarget);
|
var rule2 = new LoggingRule("*", LogLevel.Info, fileTarget);
|
||||||
config.LoggingRules.Add(rule2);
|
config.LoggingRules.Add(rule2);
|
||||||
|
|
||||||
// Step 5. Activate the configuration
|
// Step 5. Activate the configuration
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>PlexRequests.Helpers</RootNamespace>
|
<RootNamespace>PlexRequests.Helpers</RootNamespace>
|
||||||
<AssemblyName>PlexRequests.Helpers</AssemblyName>
|
<AssemblyName>PlexRequests.Helpers</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<TargetFrameworkProfile />
|
<TargetFrameworkProfile />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@ -56,6 +56,7 @@
|
||||||
<Compile Include="Exceptions\ApplicationSettingsException.cs" />
|
<Compile Include="Exceptions\ApplicationSettingsException.cs" />
|
||||||
<Compile Include="HtmlRemover.cs" />
|
<Compile Include="HtmlRemover.cs" />
|
||||||
<Compile Include="ICacheProvider.cs" />
|
<Compile Include="ICacheProvider.cs" />
|
||||||
|
<Compile Include="JsonConvertHelper.cs" />
|
||||||
<Compile Include="LoggingHelper.cs" />
|
<Compile Include="LoggingHelper.cs" />
|
||||||
<Compile Include="MemoryCacheProvider.cs" />
|
<Compile Include="MemoryCacheProvider.cs" />
|
||||||
<Compile Include="ObjectCopier.cs" />
|
<Compile Include="ObjectCopier.cs" />
|
||||||
|
|
|
@ -38,6 +38,7 @@ using PlexRequests.Core.SettingModels;
|
||||||
using PlexRequests.Helpers.Exceptions;
|
using PlexRequests.Helpers.Exceptions;
|
||||||
using PlexRequests.Services.Interfaces;
|
using PlexRequests.Services.Interfaces;
|
||||||
using PlexRequests.Store;
|
using PlexRequests.Store;
|
||||||
|
using PlexRequests.Helpers;
|
||||||
|
|
||||||
namespace PlexRequests.Services.Tests
|
namespace PlexRequests.Services.Tests
|
||||||
{
|
{
|
||||||
|
@ -46,502 +47,524 @@ namespace PlexRequests.Services.Tests
|
||||||
{
|
{
|
||||||
public IAvailabilityChecker Checker { get; set; }
|
public IAvailabilityChecker Checker { get; set; }
|
||||||
|
|
||||||
[Test]
|
//[Test]
|
||||||
public void IsAvailableWithEmptySettingsTest()
|
//public void IsAvailableWithEmptySettingsTest()
|
||||||
{
|
//{
|
||||||
var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
// var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
||||||
var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
// var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
||||||
var requestMock = new Mock<IRequestService>();
|
// var requestMock = new Mock<IRequestService>();
|
||||||
var plexMock = new Mock<IPlexApi>();
|
// var plexMock = new Mock<IPlexApi>();
|
||||||
Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object);
|
// var cacheMock = new Mock<ICacheProvider>();
|
||||||
|
// Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object, cacheMock.Object);
|
||||||
|
|
||||||
Assert.Throws<ApplicationSettingsException>(() => Checker.IsAvailable("title", "2013", null, PlexType.TvShow), "We should be throwing an exception since we cannot talk to the services.");
|
// Assert.Throws<ApplicationSettingsException>(() => Checker.IsAvailable("title", "2013", null, PlexType.TvShow), "We should be throwing an exception since we cannot talk to the services.");
|
||||||
}
|
//}
|
||||||
|
|
||||||
[Test]
|
//[Test]
|
||||||
public void IsAvailableTest()
|
//public void IsAvailableTest()
|
||||||
{
|
//{
|
||||||
var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
// var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
||||||
var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
// var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
||||||
var requestMock = new Mock<IRequestService>();
|
// var requestMock = new Mock<IRequestService>();
|
||||||
var plexMock = new Mock<IPlexApi>();
|
// var plexMock = new Mock<IPlexApi>();
|
||||||
|
// var cacheMock = new Mock<ICacheProvider>();
|
||||||
|
|
||||||
var searchResult = new PlexSearch { Video = new List<Video> { new Video { Title = "title", Year = "2011" } } };
|
// var searchResult = new PlexSearch { Video = new List<Video> { new Video { Title = "title", Year = "2011" } } };
|
||||||
|
|
||||||
settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
// settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
||||||
authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "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);
|
// 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);
|
// Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object, cacheMock.Object);
|
||||||
|
|
||||||
var result = Checker.IsAvailable("title", "2011", null, PlexType.Movie);
|
// var result = Checker.IsAvailable("title", "2011", null, PlexType.Movie);
|
||||||
|
|
||||||
Assert.That(result, Is.True);
|
// Assert.That(result, Is.True);
|
||||||
}
|
//}
|
||||||
|
|
||||||
[Test]
|
//[Test]
|
||||||
public void IsAvailableMusicDirectoryTitleTest()
|
//public void IsAvailableMusicDirectoryTitleTest()
|
||||||
{
|
//{
|
||||||
var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
// var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
||||||
var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
// var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
||||||
var requestMock = new Mock<IRequestService>();
|
// var requestMock = new Mock<IRequestService>();
|
||||||
var plexMock = new Mock<IPlexApi>();
|
// var plexMock = new Mock<IPlexApi>();
|
||||||
|
// var cacheMock = new Mock<ICacheProvider>();
|
||||||
|
|
||||||
var searchResult = new PlexSearch { Directory = new List<Directory1> { new Directory1 { Title = "title", Year = "2013", ParentTitle = "dIzZy"} } };
|
// var searchResult = new PlexSearch { Directory = new List<Directory1> { new Directory1 { Title = "title", Year = "2013", ParentTitle = "dIzZy"} } };
|
||||||
|
|
||||||
settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
// settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
||||||
authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "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);
|
// 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);
|
// Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object, cacheMock.Object);
|
||||||
|
|
||||||
var result = Checker.IsAvailable("title", "2013", "dIzZy", PlexType.Music);
|
// var result = Checker.IsAvailable("title", "2013", "dIzZy", PlexType.Music);
|
||||||
|
|
||||||
Assert.That(result, Is.True);
|
// Assert.That(result, Is.True);
|
||||||
}
|
//}
|
||||||
|
|
||||||
[Test]
|
//[Test]
|
||||||
public void IsNotAvailableMusicDirectoryTitleTest()
|
//public void IsNotAvailableMusicDirectoryTitleTest()
|
||||||
{
|
//{
|
||||||
var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
// var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
||||||
var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
// var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
||||||
var requestMock = new Mock<IRequestService>();
|
// var requestMock = new Mock<IRequestService>();
|
||||||
var plexMock = new Mock<IPlexApi>();
|
// var plexMock = new Mock<IPlexApi>();
|
||||||
|
// var cacheMock = new Mock<ICacheProvider>();
|
||||||
|
|
||||||
var searchResult = new PlexSearch { Directory = new List<Directory1> { new Directory1 { Title = "titale2", Year = "1992", ParentTitle = "dIzZy" } } };
|
// var searchResult = new PlexSearch { Directory = new List<Directory1> { new Directory1 { Title = "titale2", Year = "1992", ParentTitle = "dIzZy" } } };
|
||||||
|
|
||||||
settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
// settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
||||||
authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "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);
|
// 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);
|
// Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object, cacheMock.Object);
|
||||||
|
|
||||||
var result = Checker.IsAvailable("title", "2013", "dIzZy", PlexType.Music);
|
// var result = Checker.IsAvailable("title", "2013", "dIzZy", PlexType.Music);
|
||||||
|
|
||||||
Assert.That(result, Is.False);
|
// Assert.That(result, Is.False);
|
||||||
}
|
//}
|
||||||
|
|
||||||
[Test]
|
//[Test]
|
||||||
public void IsAvailableDirectoryTitleWithoutYearTest()
|
//public void IsAvailableDirectoryTitleWithoutYearTest()
|
||||||
{
|
//{
|
||||||
var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
// var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
||||||
var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
// var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
||||||
var requestMock = new Mock<IRequestService>();
|
// var requestMock = new Mock<IRequestService>();
|
||||||
var plexMock = new Mock<IPlexApi>();
|
// var plexMock = new Mock<IPlexApi>();
|
||||||
|
// var cacheMock = new Mock<ICacheProvider>();
|
||||||
|
|
||||||
var searchResult = new PlexSearch { Directory = new List<Directory1> { new Directory1 { Title = "title", } } };
|
// var searchResult = new PlexSearch { Directory = new List<Directory1> { new Directory1 { Title = "title", } } };
|
||||||
|
|
||||||
settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
// settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
||||||
authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "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);
|
// 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);
|
// Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object, cacheMock.Object);
|
||||||
|
|
||||||
var result = Checker.IsAvailable("title", null, null, PlexType.Movie);
|
// var result = Checker.IsAvailable("title", null, null, PlexType.Movie);
|
||||||
|
|
||||||
Assert.That(result, Is.True);
|
// Assert.That(result, Is.True);
|
||||||
}
|
//}
|
||||||
|
|
||||||
[Test]
|
//[Test]
|
||||||
public void IsNotAvailableTest()
|
//public void IsNotAvailableTest()
|
||||||
{
|
//{
|
||||||
var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
// var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
||||||
var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
// var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
||||||
var requestMock = new Mock<IRequestService>();
|
// var requestMock = new Mock<IRequestService>();
|
||||||
var plexMock = new Mock<IPlexApi>();
|
// var plexMock = new Mock<IPlexApi>();
|
||||||
|
// var cacheMock = new Mock<ICacheProvider>();
|
||||||
|
|
||||||
var searchResult = new PlexSearch { Video = new List<Video> { new Video { Title = "wrong title", Year = "2011" } } };
|
// var searchResult = new PlexSearch { Video = new List<Video> { new Video { Title = "wrong title", Year = "2011" } } };
|
||||||
|
|
||||||
settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
// settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
||||||
authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "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);
|
// 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);
|
// Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object, cacheMock.Object);
|
||||||
|
|
||||||
var result = Checker.IsAvailable("title", "2011", null, PlexType.Movie);
|
// var result = Checker.IsAvailable("title", "2011", null, PlexType.Movie);
|
||||||
|
|
||||||
Assert.That(result, Is.False);
|
// Assert.That(result, Is.False);
|
||||||
}
|
//}
|
||||||
|
|
||||||
[Test]
|
//[Test]
|
||||||
public void IsNotAvailableTestWihtoutYear()
|
//public void IsNotAvailableTestWihtoutYear()
|
||||||
{
|
//{
|
||||||
var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
// var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
||||||
var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
// var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
||||||
var requestMock = new Mock<IRequestService>();
|
// var requestMock = new Mock<IRequestService>();
|
||||||
var plexMock = new Mock<IPlexApi>();
|
// var plexMock = new Mock<IPlexApi>();
|
||||||
|
// var cacheMock = new Mock<ICacheProvider>();
|
||||||
|
|
||||||
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 title" } } };
|
||||||
|
|
||||||
settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
// settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
||||||
authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "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);
|
// 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);
|
// Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object, cacheMock.Object);
|
||||||
|
|
||||||
var result = Checker.IsAvailable("title", null, null, PlexType.Movie);
|
// var result = Checker.IsAvailable("title", null, null, PlexType.Movie);
|
||||||
|
|
||||||
Assert.That(result, Is.False);
|
// Assert.That(result, Is.False);
|
||||||
}
|
//}
|
||||||
|
|
||||||
[Test]
|
//[Test]
|
||||||
public void IsYearDoesNotMatchTest()
|
//public void IsYearDoesNotMatchTest()
|
||||||
{
|
//{
|
||||||
var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
// var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
||||||
var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
// var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
||||||
var requestMock = new Mock<IRequestService>();
|
// var requestMock = new Mock<IRequestService>();
|
||||||
var plexMock = new Mock<IPlexApi>();
|
// var plexMock = new Mock<IPlexApi>();
|
||||||
|
// var cacheMock = new Mock<ICacheProvider>();
|
||||||
|
|
||||||
var searchResult = new PlexSearch { Video = new List<Video> { new Video { Title = "title", Year = "2019" } } };
|
// var searchResult = new PlexSearch { Video = new List<Video> { new Video { Title = "title", Year = "2019" } } };
|
||||||
|
|
||||||
settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
// settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
||||||
authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "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);
|
// 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);
|
// Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object, cacheMock.Object);
|
||||||
|
|
||||||
var result = Checker.IsAvailable("title", "2011", null, PlexType.Movie);
|
// var result = Checker.IsAvailable("title", "2011", null, PlexType.Movie);
|
||||||
|
|
||||||
Assert.That(result, Is.False);
|
// Assert.That(result, Is.False);
|
||||||
}
|
//}
|
||||||
|
|
||||||
[Test]
|
//[Test]
|
||||||
public void TitleDoesNotMatchTest()
|
//public void TitleDoesNotMatchTest()
|
||||||
{
|
//{
|
||||||
var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
// var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
||||||
var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
// var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
||||||
var requestMock = new Mock<IRequestService>();
|
// var requestMock = new Mock<IRequestService>();
|
||||||
var plexMock = new Mock<IPlexApi>();
|
// var plexMock = new Mock<IPlexApi>();
|
||||||
|
// var cacheMock = new Mock<ICacheProvider>();
|
||||||
|
|
||||||
var searchResult = new PlexSearch { Video = new List<Video> { new Video { Title = "title23", Year = "2019" } } };
|
// var searchResult = new PlexSearch { Video = new List<Video> { new Video { Title = "title23", Year = "2019" } } };
|
||||||
|
|
||||||
settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
// settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
||||||
authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "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);
|
// 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);
|
// Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object, cacheMock.Object);
|
||||||
|
|
||||||
var result = Checker.IsAvailable("title", "2019", null, PlexType.Movie);
|
// var result = Checker.IsAvailable("title", "2019", null, PlexType.Movie);
|
||||||
|
|
||||||
Assert.That(result, Is.False);
|
// Assert.That(result, Is.False);
|
||||||
}
|
//}
|
||||||
|
|
||||||
[Test]
|
//[Test]
|
||||||
public void TitleDoesNotMatchWithoutYearTest()
|
//public void TitleDoesNotMatchWithoutYearTest()
|
||||||
{
|
//{
|
||||||
var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
// var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
||||||
var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
// var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
||||||
var requestMock = new Mock<IRequestService>();
|
// var requestMock = new Mock<IRequestService>();
|
||||||
var plexMock = new Mock<IPlexApi>();
|
// var plexMock = new Mock<IPlexApi>();
|
||||||
|
// var cacheMock = new Mock<ICacheProvider>();
|
||||||
var searchResult = new PlexSearch { Video = new List<Video> { new Video { Title = "title23" } } };
|
|
||||||
|
// var searchResult = new PlexSearch { Video = new List<Video> { new Video { Title = "title23" } } };
|
||||||
settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
|
||||||
authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "abc" });
|
// settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "abc" });
|
||||||
plexMock.Setup(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>())).Returns(searchResult);
|
// 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);
|
|
||||||
|
// Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object, cacheMock.Object);
|
||||||
var result = Checker.IsAvailable("title", null, null, PlexType.Movie);
|
|
||||||
|
// var result = Checker.IsAvailable("title", null, null, PlexType.Movie);
|
||||||
Assert.That(result, Is.False);
|
|
||||||
}
|
// Assert.That(result, Is.False);
|
||||||
|
//}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void CheckAndUpdateNoPlexSettingsTest()
|
//[Test]
|
||||||
{
|
//public void CheckAndUpdateNoPlexSettingsTest()
|
||||||
var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
//{
|
||||||
var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
// var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
||||||
var requestMock = new Mock<IRequestService>();
|
// var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
||||||
var plexMock = new Mock<IPlexApi>();
|
// var requestMock = new Mock<IRequestService>();
|
||||||
authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "abc" });
|
// var plexMock = new Mock<IPlexApi>();
|
||||||
Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object);
|
// var cacheMock = new Mock<ICacheProvider>();
|
||||||
|
|
||||||
Checker.CheckAndUpdateAll(1);
|
// authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "abc" });
|
||||||
|
// Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object, cacheMock.Object);
|
||||||
requestMock.Verify(x => x.BatchUpdate(It.IsAny<List<RequestedModel>>()), Times.Never);
|
|
||||||
requestMock.Verify(x => x.Get(It.IsAny<int>()), Times.Never);
|
// Checker.CheckAndUpdateAll(1);
|
||||||
plexMock.Verify(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>()), Times.Never);
|
|
||||||
}
|
// requestMock.Verify(x => x.BatchUpdate(It.IsAny<List<RequestedModel>>()), Times.Never);
|
||||||
|
// requestMock.Verify(x => x.Get(It.IsAny<int>()), Times.Never);
|
||||||
[Test]
|
// plexMock.Verify(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>()), Times.Never);
|
||||||
public void CheckAndUpdateNoAuthSettingsTest()
|
//}
|
||||||
{
|
|
||||||
var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
//[Test]
|
||||||
var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
//public void CheckAndUpdateNoAuthSettingsTest()
|
||||||
var requestMock = new Mock<IRequestService>();
|
//{
|
||||||
var plexMock = new Mock<IPlexApi>();
|
// var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
||||||
settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "123" });
|
// var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
||||||
|
// var requestMock = new Mock<IRequestService>();
|
||||||
Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object);
|
// var plexMock = new Mock<IPlexApi>();
|
||||||
|
// var cacheMock = new Mock<ICacheProvider>();
|
||||||
Checker.CheckAndUpdateAll(1);
|
|
||||||
|
// settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "123" });
|
||||||
requestMock.Verify(x => x.BatchUpdate(It.IsAny<List<RequestedModel>>()), Times.Never);
|
|
||||||
requestMock.Verify(x => x.Get(It.IsAny<int>()), Times.Never);
|
// Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object, cacheMock.Object);
|
||||||
plexMock.Verify(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>()), Times.Never);
|
|
||||||
}
|
// Checker.CheckAndUpdateAll(1);
|
||||||
|
|
||||||
[Test]
|
// requestMock.Verify(x => x.BatchUpdate(It.IsAny<List<RequestedModel>>()), Times.Never);
|
||||||
public void CheckAndUpdateNoRequestsTest()
|
// requestMock.Verify(x => x.Get(It.IsAny<int>()), Times.Never);
|
||||||
{
|
// plexMock.Verify(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>()), Times.Never);
|
||||||
var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
//}
|
||||||
var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
|
||||||
var requestMock = new Mock<IRequestService>();
|
//[Test]
|
||||||
var plexMock = new Mock<IPlexApi>();
|
//public void CheckAndUpdateNoRequestsTest()
|
||||||
settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "192.168.1.1" });
|
//{
|
||||||
authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "abc" });
|
// var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
||||||
requestMock.Setup(x => x.GetAll()).Returns(new List<RequestedModel>());
|
// var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
||||||
|
// var requestMock = new Mock<IRequestService>();
|
||||||
Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object);
|
// var plexMock = new Mock<IPlexApi>();
|
||||||
|
// var cacheMock = new Mock<ICacheProvider>();
|
||||||
Checker.CheckAndUpdateAll(1);
|
|
||||||
|
// settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "192.168.1.1" });
|
||||||
requestMock.Verify(x => x.BatchUpdate(It.IsAny<List<RequestedModel>>()), Times.Never);
|
// authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "abc" });
|
||||||
requestMock.Verify(x => x.Get(It.IsAny<int>()), Times.Never);
|
// requestMock.Setup(x => x.GetAll()).Returns(new List<RequestedModel>());
|
||||||
plexMock.Verify(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>()), Times.Never);
|
|
||||||
}
|
// Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object, cacheMock.Object);
|
||||||
|
|
||||||
|
// Checker.CheckAndUpdateAll(1);
|
||||||
[Test]
|
|
||||||
public void CheckAndUpdateRequestsThatDoNotExistInPlexTest()
|
// requestMock.Verify(x => x.BatchUpdate(It.IsAny<List<RequestedModel>>()), Times.Never);
|
||||||
{
|
// requestMock.Verify(x => x.Get(It.IsAny<int>()), Times.Never);
|
||||||
|
// plexMock.Verify(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>()), Times.Never);
|
||||||
var requests = new List<RequestedModel> {
|
//}
|
||||||
new RequestedModel
|
|
||||||
{
|
|
||||||
Id = 123,
|
//[Test]
|
||||||
Title = "title1",
|
//public void CheckAndUpdateRequestsThatDoNotExistInPlexTest()
|
||||||
Available = false,
|
//{
|
||||||
},
|
|
||||||
new RequestedModel
|
// var requests = new List<RequestedModel> {
|
||||||
{
|
// new RequestedModel
|
||||||
Id=222,
|
// {
|
||||||
Title = "title3",
|
// Id = 123,
|
||||||
Available = false
|
// Title = "title1",
|
||||||
},
|
// Available = false,
|
||||||
new RequestedModel
|
// },
|
||||||
{
|
// new RequestedModel
|
||||||
Id = 333,
|
// {
|
||||||
Title= "missingTitle",
|
// Id=222,
|
||||||
Available = false
|
// Title = "title3",
|
||||||
},
|
// Available = false
|
||||||
new RequestedModel
|
// },
|
||||||
{
|
// new RequestedModel
|
||||||
Id= 444,
|
// {
|
||||||
Title = "already found",
|
// Id = 333,
|
||||||
Available = true
|
// Title= "missingTitle",
|
||||||
}
|
// Available = false
|
||||||
};
|
// },
|
||||||
|
// new RequestedModel
|
||||||
var search = new PlexSearch
|
// {
|
||||||
{
|
// Id= 444,
|
||||||
Video = new List<Video>
|
// Title = "already found",
|
||||||
{
|
// Available = true
|
||||||
new Video
|
// }
|
||||||
{
|
// };
|
||||||
Title = "Title4",
|
|
||||||
Year = "2012"
|
// var search = new PlexSearch
|
||||||
},
|
// {
|
||||||
new Video
|
// Video = new List<Video>
|
||||||
{
|
// {
|
||||||
Title = "Title2",
|
// new Video
|
||||||
}
|
// {
|
||||||
},
|
// Title = "Title4",
|
||||||
Directory = new List<Directory1> { new Directory1
|
// Year = "2012"
|
||||||
{
|
// },
|
||||||
Title = "Title9",
|
// new Video
|
||||||
Year = "1978"
|
// {
|
||||||
}}
|
// Title = "Title2",
|
||||||
};
|
// }
|
||||||
|
// },
|
||||||
var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
// Directory = new List<Directory1> { new Directory1
|
||||||
var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
// {
|
||||||
var requestMock = new Mock<IRequestService>();
|
// Title = "Title9",
|
||||||
var plexMock = new Mock<IPlexApi>();
|
// Year = "1978"
|
||||||
settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "192.168.1.1" });
|
// }}
|
||||||
authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "abc" });
|
// };
|
||||||
requestMock.Setup(x => x.GetAll()).Returns(requests);
|
|
||||||
plexMock.Setup(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>())).Returns(search);
|
// var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
||||||
Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object);
|
// var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
||||||
|
// var requestMock = new Mock<IRequestService>();
|
||||||
Checker.CheckAndUpdateAll(1);
|
// var plexMock = new Mock<IPlexApi>();
|
||||||
|
// var cacheMock = new Mock<ICacheProvider>();
|
||||||
requestMock.Verify(x => x.BatchUpdate(It.IsAny<List<RequestedModel>>()), Times.Never);
|
|
||||||
requestMock.Verify(x => x.Get(It.IsAny<int>()), Times.Never);
|
// settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "192.168.1.1" });
|
||||||
plexMock.Verify(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>()), Times.Exactly(3));
|
// authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "abc" });
|
||||||
}
|
// requestMock.Setup(x => x.GetAll()).Returns(requests);
|
||||||
|
// plexMock.Setup(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>())).Returns(search);
|
||||||
[Test]
|
// Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object, cacheMock.Object);
|
||||||
public void CheckAndUpdateRequestsAllRequestsTest()
|
|
||||||
{
|
// Checker.CheckAndUpdateAll(1);
|
||||||
|
|
||||||
var requests = new List<RequestedModel> {
|
// requestMock.Verify(x => x.BatchUpdate(It.IsAny<List<RequestedModel>>()), Times.Never);
|
||||||
new RequestedModel
|
// requestMock.Verify(x => x.Get(It.IsAny<int>()), Times.Never);
|
||||||
{
|
// plexMock.Verify(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>()), Times.Exactly(3));
|
||||||
Id = 123,
|
//}
|
||||||
Title = "title1",
|
|
||||||
Available = false,
|
//[Test]
|
||||||
},
|
//public void CheckAndUpdateRequestsAllRequestsTest()
|
||||||
new RequestedModel
|
//{
|
||||||
{
|
|
||||||
Id=222,
|
// var requests = new List<RequestedModel> {
|
||||||
Title = "title3",
|
// new RequestedModel
|
||||||
Available = false
|
// {
|
||||||
},
|
// Id = 123,
|
||||||
new RequestedModel
|
// Title = "title1",
|
||||||
{
|
// Available = false,
|
||||||
Id = 333,
|
// },
|
||||||
Title= "missingTitle",
|
// new RequestedModel
|
||||||
Available = false
|
// {
|
||||||
},
|
// Id=222,
|
||||||
new RequestedModel
|
// Title = "title3",
|
||||||
{
|
// Available = false
|
||||||
Id= 444,
|
// },
|
||||||
Title = "Hi",
|
// new RequestedModel
|
||||||
Available = false
|
// {
|
||||||
}
|
// Id = 333,
|
||||||
};
|
// Title= "missingTitle",
|
||||||
|
// Available = false
|
||||||
var search = new PlexSearch
|
// },
|
||||||
{
|
// new RequestedModel
|
||||||
Video = new List<Video>
|
// {
|
||||||
{
|
// Id= 444,
|
||||||
new Video
|
// Title = "Hi",
|
||||||
{
|
// Available = false
|
||||||
Title = "title1",
|
// }
|
||||||
Year = "2012"
|
// };
|
||||||
},
|
|
||||||
new Video
|
// var search = new PlexSearch
|
||||||
{
|
// {
|
||||||
Title = "Title3",
|
// Video = new List<Video>
|
||||||
}
|
// {
|
||||||
,
|
// new Video
|
||||||
new Video
|
// {
|
||||||
{
|
// Title = "title1",
|
||||||
Title = "Hi",
|
// Year = "2012"
|
||||||
}
|
// },
|
||||||
},
|
// new Video
|
||||||
Directory = new List<Directory1> { new Directory1
|
// {
|
||||||
{
|
// Title = "Title3",
|
||||||
Title = "missingTitle",
|
// }
|
||||||
Year = "1978"
|
// ,
|
||||||
}}
|
// new Video
|
||||||
};
|
// {
|
||||||
|
// Title = "Hi",
|
||||||
var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
// }
|
||||||
var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
// },
|
||||||
var requestMock = new Mock<IRequestService>();
|
// Directory = new List<Directory1> { new Directory1
|
||||||
var plexMock = new Mock<IPlexApi>();
|
// {
|
||||||
settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "192.168.1.1" });
|
// Title = "missingTitle",
|
||||||
authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "abc" });
|
// Year = "1978"
|
||||||
requestMock.Setup(x => x.GetAll()).Returns(requests);
|
// }}
|
||||||
plexMock.Setup(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>())).Returns(search);
|
// };
|
||||||
Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object);
|
|
||||||
|
// var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
||||||
Checker.CheckAndUpdateAll(1);
|
// var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
||||||
|
// var requestMock = new Mock<IRequestService>();
|
||||||
requestMock.Verify(x => x.BatchUpdate(It.IsAny<List<RequestedModel>>()), Times.Once);
|
// var plexMock = new Mock<IPlexApi>();
|
||||||
requestMock.Verify(x => x.Get(It.IsAny<int>()), Times.Never);
|
// var cacheMock = new Mock<ICacheProvider>();
|
||||||
plexMock.Verify(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>()), Times.Exactly(4));
|
|
||||||
}
|
// settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "192.168.1.1" });
|
||||||
|
// authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "abc" });
|
||||||
|
// requestMock.Setup(x => x.GetAll()).Returns(requests);
|
||||||
[Test]
|
// plexMock.Setup(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>())).Returns(search);
|
||||||
public void CheckAndUpdateAllMusicRequestsTest()
|
// Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object, cacheMock.Object);
|
||||||
{
|
|
||||||
|
// Checker.CheckAndUpdateAll(1);
|
||||||
var requests = new List<RequestedModel> {
|
|
||||||
new RequestedModel
|
// requestMock.Verify(x => x.BatchUpdate(It.IsAny<List<RequestedModel>>()), Times.Once);
|
||||||
{
|
// requestMock.Verify(x => x.Get(It.IsAny<int>()), Times.Never);
|
||||||
Id = 123,
|
// plexMock.Verify(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>()), Times.Exactly(4));
|
||||||
Title = "title1",
|
//}
|
||||||
Available = false,
|
|
||||||
ArtistName = "dizzy",
|
|
||||||
Type = RequestType.Album,
|
//[Test]
|
||||||
ReleaseDate = new DateTime(2010,1,1)
|
//public void CheckAndUpdateAllMusicRequestsTest()
|
||||||
},
|
//{
|
||||||
new RequestedModel
|
|
||||||
{
|
// var requests = new List<RequestedModel> {
|
||||||
Id=222,
|
// new RequestedModel
|
||||||
Title = "title3",
|
// {
|
||||||
Available = false,
|
// Id = 123,
|
||||||
ArtistName = "a",
|
// Title = "title1",
|
||||||
Type = RequestType.Album,
|
// Available = false,
|
||||||
ReleaseDate = new DateTime(2006,1,1)
|
// ArtistName = "dizzy",
|
||||||
},
|
// Type = RequestType.Album,
|
||||||
new RequestedModel
|
// ReleaseDate = new DateTime(2010,1,1)
|
||||||
{
|
// },
|
||||||
Id = 333,
|
// new RequestedModel
|
||||||
Title= "missingTitle",
|
// {
|
||||||
Available = false,
|
// Id=222,
|
||||||
ArtistName = "b",
|
// Title = "title3",
|
||||||
Type = RequestType.Album,
|
// Available = false,
|
||||||
ReleaseDate = new DateTime(1992,1,1)
|
// ArtistName = "a",
|
||||||
},
|
// Type = RequestType.Album,
|
||||||
new RequestedModel
|
// ReleaseDate = new DateTime(2006,1,1)
|
||||||
{
|
// },
|
||||||
Id= 444,
|
// new RequestedModel
|
||||||
Title = "Hi",
|
// {
|
||||||
Available = false,
|
// Id = 333,
|
||||||
ArtistName = "c",
|
// Title= "missingTitle",
|
||||||
Type = RequestType.Album,
|
// Available = false,
|
||||||
ReleaseDate = new DateTime(2017,1,1)
|
// ArtistName = "b",
|
||||||
}
|
// Type = RequestType.Album,
|
||||||
};
|
// ReleaseDate = new DateTime(1992,1,1)
|
||||||
|
// },
|
||||||
var search = new PlexSearch
|
// new RequestedModel
|
||||||
{
|
// {
|
||||||
Directory = new List<Directory1> {
|
// Id= 444,
|
||||||
new Directory1
|
// Title = "Hi",
|
||||||
{
|
// Available = false,
|
||||||
Title = "missingTitle",
|
// ArtistName = "c",
|
||||||
Year = "1978",
|
// Type = RequestType.Album,
|
||||||
ParentTitle = "c"
|
// ReleaseDate = new DateTime(2017,1,1)
|
||||||
},
|
// }
|
||||||
new Directory1
|
// };
|
||||||
{
|
|
||||||
Title = "Hi",
|
// var search = new PlexSearch
|
||||||
Year = "1978",
|
// {
|
||||||
ParentTitle = "c"
|
// Directory = new List<Directory1> {
|
||||||
},
|
// new Directory1
|
||||||
new Directory1
|
// {
|
||||||
{
|
// Title = "missingTitle",
|
||||||
Title = "Hi",
|
// Year = "1978",
|
||||||
Year = "2017",
|
// ParentTitle = "c"
|
||||||
ParentTitle = "c"
|
// },
|
||||||
},
|
// new Directory1
|
||||||
new Directory1
|
// {
|
||||||
{
|
// Title = "Hi",
|
||||||
Title = "missingTitle",
|
// Year = "1978",
|
||||||
Year = "1992",
|
// ParentTitle = "c"
|
||||||
ParentTitle = "b"
|
// },
|
||||||
},
|
// new Directory1
|
||||||
new Directory1
|
// {
|
||||||
{
|
// Title = "Hi",
|
||||||
Title = "title1",
|
// Year = "2017",
|
||||||
Year = "2010",
|
// ParentTitle = "c"
|
||||||
ParentTitle = "DiZzY"
|
// },
|
||||||
},
|
// new Directory1
|
||||||
}
|
// {
|
||||||
};
|
// Title = "missingTitle",
|
||||||
|
// Year = "1992",
|
||||||
var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
// ParentTitle = "b"
|
||||||
var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
// },
|
||||||
var requestMock = new Mock<IRequestService>();
|
// new Directory1
|
||||||
var plexMock = new Mock<IPlexApi>();
|
// {
|
||||||
settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "192.168.1.1" });
|
// Title = "title1",
|
||||||
authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "abc" });
|
// Year = "2010",
|
||||||
requestMock.Setup(x => x.GetAll()).Returns(requests);
|
// ParentTitle = "DiZzY"
|
||||||
plexMock.Setup(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>())).Returns(search);
|
// },
|
||||||
Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object);
|
// }
|
||||||
|
// };
|
||||||
Checker.CheckAndUpdateAll(1);
|
|
||||||
|
// var settingsMock = new Mock<ISettingsService<PlexSettings>>();
|
||||||
requestMock.Verify(x => x.BatchUpdate(It.IsAny<List<RequestedModel>>()), Times.Once);
|
// var authMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
||||||
requestMock.Verify(x => x.Get(It.IsAny<int>()), Times.Never);
|
// var requestMock = new Mock<IRequestService>();
|
||||||
plexMock.Verify(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>()), Times.Exactly(4));
|
// var plexMock = new Mock<IPlexApi>();
|
||||||
}
|
// var cacheMock = new Mock<ICacheProvider>();
|
||||||
|
|
||||||
|
// settingsMock.Setup(x => x.GetSettings()).Returns(new PlexSettings { Ip = "192.168.1.1" });
|
||||||
|
// authMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings { PlexAuthToken = "abc" });
|
||||||
|
// requestMock.Setup(x => x.GetAll()).Returns(requests);
|
||||||
|
// plexMock.Setup(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>())).Returns(search);
|
||||||
|
// Checker = new PlexAvailabilityChecker(settingsMock.Object, authMock.Object, requestMock.Object, plexMock.Object, cacheMock.Object);
|
||||||
|
|
||||||
|
// Checker.CheckAndUpdateAll(1);
|
||||||
|
|
||||||
|
// requestMock.Verify(x => x.BatchUpdate(It.IsAny<List<RequestedModel>>()), Times.Once);
|
||||||
|
// requestMock.Verify(x => x.Get(It.IsAny<int>()), Times.Never);
|
||||||
|
// plexMock.Verify(x => x.SearchContent(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Uri>()), Times.Exactly(4));
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -8,7 +8,7 @@
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>PlexRequests.Services.Tests</RootNamespace>
|
<RootNamespace>PlexRequests.Services.Tests</RootNamespace>
|
||||||
<AssemblyName>PlexRequests.Services.Tests</AssemblyName>
|
<AssemblyName>PlexRequests.Services.Tests</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||||
|
@ -60,7 +60,9 @@
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="app.config" />
|
<None Include="app.config">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</None>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<runtime>
|
<runtime>
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
|
@ -8,4 +8,4 @@
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
</assemblyBinding>
|
</assemblyBinding>
|
||||||
</runtime>
|
</runtime>
|
||||||
</configuration>
|
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/></startup></configuration>
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
// ************************************************************************/
|
// ************************************************************************/
|
||||||
#endregion
|
#endregion
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Reactive.Linq;
|
using System.Reactive.Linq;
|
||||||
using System.Web.Hosting;
|
using System.Web.Hosting;
|
||||||
|
|
||||||
|
@ -41,19 +43,22 @@ using PlexRequests.Helpers;
|
||||||
using PlexRequests.Services.Interfaces;
|
using PlexRequests.Services.Interfaces;
|
||||||
using PlexRequests.Store;
|
using PlexRequests.Store;
|
||||||
using PlexRequests.Store.Repository;
|
using PlexRequests.Store.Repository;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace PlexRequests.Services
|
namespace PlexRequests.Services
|
||||||
{
|
{
|
||||||
public class AvailabilityUpdateService : ITask, IRegisteredObject, IAvailabilityUpdateService
|
public class AvailabilityUpdateService : ITask, IRegisteredObject, IAvailabilityUpdateService
|
||||||
{
|
{
|
||||||
|
|
||||||
public AvailabilityUpdateService()
|
public AvailabilityUpdateService()
|
||||||
{
|
{
|
||||||
|
|
||||||
var memCache = new MemoryCacheProvider();
|
var memCache = new MemoryCacheProvider();
|
||||||
var dbConfig = new DbConfiguration(new SqliteFactory());
|
var dbConfig = new DbConfiguration(new SqliteFactory());
|
||||||
var repo = new SettingsJsonRepository(dbConfig, memCache);
|
var repo = new SettingsJsonRepository(dbConfig, memCache);
|
||||||
|
|
||||||
ConfigurationReader = new ConfigurationReader();
|
ConfigurationReader = new ConfigurationReader();
|
||||||
Checker = new PlexAvailabilityChecker(new SettingsServiceV2<PlexSettings>(repo), new SettingsServiceV2<AuthenticationSettings>(repo), new JsonRequestService(new RequestJsonRepository(dbConfig, memCache)), new PlexApi());
|
Checker = new PlexAvailabilityChecker(new SettingsServiceV2<PlexSettings>(repo), new SettingsServiceV2<AuthenticationSettings>(repo), new JsonRequestService(new RequestJsonRepository(dbConfig, memCache)), new PlexApi(), memCache);
|
||||||
HostingEnvironment.RegisterObject(this);
|
HostingEnvironment.RegisterObject(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +71,7 @@ namespace PlexRequests.Services
|
||||||
public void Start(Configuration c)
|
public void Start(Configuration c)
|
||||||
{
|
{
|
||||||
UpdateSubscription?.Dispose();
|
UpdateSubscription?.Dispose();
|
||||||
|
Task.Factory.StartNew(() => Checker.CheckAndUpdateAll(-1)); // cache the libraries and run the availability checks
|
||||||
UpdateSubscription = Observable.Interval(c.Intervals.Notification).Subscribe(Checker.CheckAndUpdateAll);
|
UpdateSubscription = Observable.Interval(c.Intervals.Notification).Subscribe(Checker.CheckAndUpdateAll);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
77
PlexRequests.Services/CouchPotatoCacher.cs
Normal file
77
PlexRequests.Services/CouchPotatoCacher.cs
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: PlexAvailabilityChecker.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.Core;
|
||||||
|
using PlexRequests.Core.SettingModels;
|
||||||
|
using PlexRequests.Helpers;
|
||||||
|
using PlexRequests.Services.Interfaces;
|
||||||
|
using PlexRequests.Api.Models.Movie;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace PlexRequests.Services
|
||||||
|
{
|
||||||
|
public class CouchPotatoCacher : ICouchPotatoCacher
|
||||||
|
{
|
||||||
|
public CouchPotatoCacher(ISettingsService<CouchPotatoSettings> cpSettings, ICouchPotatoApi cpApi, ICacheProvider cache)
|
||||||
|
{
|
||||||
|
CpSettings = cpSettings;
|
||||||
|
CpApi = cpApi;
|
||||||
|
Cache = cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ISettingsService<CouchPotatoSettings> CpSettings { get; }
|
||||||
|
private ICacheProvider Cache { get; }
|
||||||
|
private ICouchPotatoApi CpApi { get; }
|
||||||
|
|
||||||
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
public void Queued(long check)
|
||||||
|
{
|
||||||
|
Log.Trace("This is check no. {0}", check);
|
||||||
|
Log.Trace("Getting the settings");
|
||||||
|
|
||||||
|
var settings = CpSettings.GetSettings();
|
||||||
|
if (settings.Enabled)
|
||||||
|
{
|
||||||
|
Log.Trace("Getting all movies from CouchPotato");
|
||||||
|
var movies = CpApi.GetMovies(settings.FullUri, settings.ApiKey, new[] { "active" });
|
||||||
|
Cache.Set(CacheKeys.CouchPotatoQueued, movies, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we do not want to set here...
|
||||||
|
public int[] QueuedIds()
|
||||||
|
{
|
||||||
|
var movies = Cache.Get<CouchPotatoMovies>(CacheKeys.CouchPotatoQueued);
|
||||||
|
return movies != null ? movies.movies.Select(x => x.info.tmdb_id).ToArray() : new int[] { };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,11 +24,19 @@
|
||||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
// ************************************************************************/
|
// ************************************************************************/
|
||||||
#endregion
|
#endregion
|
||||||
|
using PlexRequests.Services.Models;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace PlexRequests.Services.Interfaces
|
namespace PlexRequests.Services.Interfaces
|
||||||
{
|
{
|
||||||
public interface IAvailabilityChecker
|
public interface IAvailabilityChecker
|
||||||
{
|
{
|
||||||
void CheckAndUpdateAll(long check);
|
void CheckAndUpdateAll(long check);
|
||||||
bool IsAvailable(string title, string year, string artist, PlexType type);
|
List<PlexMovie> GetPlexMovies();
|
||||||
|
bool IsMovieAvailable(PlexMovie[] plexMovies, string title, string year);
|
||||||
|
List<PlexTvShow> GetPlexTvShows();
|
||||||
|
bool IsTvShowAvailable(PlexTvShow[] plexShows, string title, string year);
|
||||||
|
List<PlexAlbum> GetPlexAlbums();
|
||||||
|
bool IsAlbumAvailable(PlexAlbum[] plexAlbums, string title, string year, string artist);
|
||||||
}
|
}
|
||||||
}
|
}
|
8
PlexRequests.Services/Interfaces/ICouchPotatoCacher.cs
Normal file
8
PlexRequests.Services/Interfaces/ICouchPotatoCacher.cs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
namespace PlexRequests.Services.Interfaces
|
||||||
|
{
|
||||||
|
public interface ICouchPotatoCacher
|
||||||
|
{
|
||||||
|
void Queued(long check);
|
||||||
|
int[] QueuedIds();
|
||||||
|
}
|
||||||
|
}
|
8
PlexRequests.Services/Interfaces/ISonarrCacher.cs
Normal file
8
PlexRequests.Services/Interfaces/ISonarrCacher.cs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
namespace PlexRequests.Services.Interfaces
|
||||||
|
{
|
||||||
|
public interface ISonarrCacher
|
||||||
|
{
|
||||||
|
void Queued(long check);
|
||||||
|
int[] QueuedIds();
|
||||||
|
}
|
||||||
|
}
|
8
PlexRequests.Services/Interfaces/ITvCacher.cs
Normal file
8
PlexRequests.Services/Interfaces/ITvCacher.cs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
namespace PlexRequests.Services.Interfaces
|
||||||
|
{
|
||||||
|
public interface ISickRageCacher
|
||||||
|
{
|
||||||
|
void Queued(long check);
|
||||||
|
int[] QueuedIds();
|
||||||
|
}
|
||||||
|
}
|
102
PlexRequests.Services/MediaCacheService.cs
Normal file
102
PlexRequests.Services/MediaCacheService.cs
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: AvailabilityUpdateService.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.Reactive.Linq;
|
||||||
|
using System.Web.Hosting;
|
||||||
|
|
||||||
|
using FluentScheduler;
|
||||||
|
|
||||||
|
using Mono.Data.Sqlite;
|
||||||
|
|
||||||
|
using NLog;
|
||||||
|
|
||||||
|
using PlexRequests.Api;
|
||||||
|
using PlexRequests.Core;
|
||||||
|
using PlexRequests.Core.SettingModels;
|
||||||
|
using PlexRequests.Helpers;
|
||||||
|
using PlexRequests.Services.Interfaces;
|
||||||
|
using PlexRequests.Store;
|
||||||
|
using PlexRequests.Store.Repository;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace PlexRequests.Services
|
||||||
|
{
|
||||||
|
public class MediaCacheService : ITask, IRegisteredObject, IAvailabilityUpdateService
|
||||||
|
{
|
||||||
|
public MediaCacheService()
|
||||||
|
{
|
||||||
|
var memCache = new MemoryCacheProvider();
|
||||||
|
var dbConfig = new DbConfiguration(new SqliteFactory());
|
||||||
|
var repo = new SettingsJsonRepository(dbConfig, memCache);
|
||||||
|
|
||||||
|
ConfigurationReader = new ConfigurationReader();
|
||||||
|
CpCacher = new CouchPotatoCacher(new SettingsServiceV2<CouchPotatoSettings>(repo), new CouchPotatoApi(), memCache);
|
||||||
|
SonarrCacher = new SonarrCacher(new SettingsServiceV2<SonarrSettings>(repo), new SonarrApi(), memCache);
|
||||||
|
SickRageCacher = new SickRageCacher(new SettingsServiceV2<SickRageSettings>(repo), new SickrageApi(), memCache);
|
||||||
|
HostingEnvironment.RegisterObject(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
private IConfigurationReader ConfigurationReader { get; }
|
||||||
|
private ICouchPotatoCacher CpCacher { get; }
|
||||||
|
private ISonarrCacher SonarrCacher { get; }
|
||||||
|
private ISickRageCacher SickRageCacher { get; }
|
||||||
|
private IDisposable CpSubscription { get; set; }
|
||||||
|
private IDisposable SonarrSubscription { get; set; }
|
||||||
|
private IDisposable SickRageSubscription { get; set; }
|
||||||
|
|
||||||
|
public void Start(Configuration c)
|
||||||
|
{
|
||||||
|
CpSubscription?.Dispose();
|
||||||
|
SonarrSubscription?.Dispose();
|
||||||
|
SickRageSubscription?.Dispose();
|
||||||
|
|
||||||
|
Task.Factory.StartNew(() => CpCacher.Queued(-1));
|
||||||
|
Task.Factory.StartNew(() => SonarrCacher.Queued(-1));
|
||||||
|
Task.Factory.StartNew(() => SickRageCacher.Queued(-1));
|
||||||
|
CpSubscription = Observable.Interval(c.Intervals.Notification).Subscribe(CpCacher.Queued);
|
||||||
|
SonarrSubscription = Observable.Interval(c.Intervals.Notification).Subscribe(SonarrCacher.Queued);
|
||||||
|
SickRageSubscription = Observable.Interval(c.Intervals.Notification).Subscribe(SickRageCacher.Queued);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Execute()
|
||||||
|
{
|
||||||
|
Start(ConfigurationReader.Read());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop(bool immediate)
|
||||||
|
{
|
||||||
|
HostingEnvironment.UnregisterObject(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ICouchPotatoCacheService
|
||||||
|
{
|
||||||
|
void Start(Configuration c);
|
||||||
|
}
|
||||||
|
}
|
9
PlexRequests.Services/Models/PlexAlbum.cs
Normal file
9
PlexRequests.Services/Models/PlexAlbum.cs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
namespace PlexRequests.Services.Models
|
||||||
|
{
|
||||||
|
public class PlexAlbum
|
||||||
|
{
|
||||||
|
public string Title { get; set; }
|
||||||
|
public string Artist { get; set; }
|
||||||
|
public string ReleaseYear { get; set; }
|
||||||
|
}
|
||||||
|
}
|
8
PlexRequests.Services/Models/PlexMovie.cs
Normal file
8
PlexRequests.Services/Models/PlexMovie.cs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
namespace PlexRequests.Services.Models
|
||||||
|
{
|
||||||
|
public class PlexMovie
|
||||||
|
{
|
||||||
|
public string Title { get; set; }
|
||||||
|
public string ReleaseYear { get; set; }
|
||||||
|
}
|
||||||
|
}
|
8
PlexRequests.Services/Models/PlexTvShow.cs
Normal file
8
PlexRequests.Services/Models/PlexTvShow.cs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
namespace PlexRequests.Services.Models
|
||||||
|
{
|
||||||
|
public class PlexTvShow
|
||||||
|
{
|
||||||
|
public string Title { get; set; }
|
||||||
|
public string ReleaseYear { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,20 +35,21 @@ using PlexRequests.Api.Models.Plex;
|
||||||
using PlexRequests.Core;
|
using PlexRequests.Core;
|
||||||
using PlexRequests.Core.SettingModels;
|
using PlexRequests.Core.SettingModels;
|
||||||
using PlexRequests.Helpers;
|
using PlexRequests.Helpers;
|
||||||
using PlexRequests.Helpers.Exceptions;
|
|
||||||
using PlexRequests.Services.Interfaces;
|
using PlexRequests.Services.Interfaces;
|
||||||
using PlexRequests.Store;
|
using PlexRequests.Store;
|
||||||
|
using PlexRequests.Services.Models;
|
||||||
|
|
||||||
namespace PlexRequests.Services
|
namespace PlexRequests.Services
|
||||||
{
|
{
|
||||||
public class PlexAvailabilityChecker : IAvailabilityChecker
|
public class PlexAvailabilityChecker : IAvailabilityChecker
|
||||||
{
|
{
|
||||||
public PlexAvailabilityChecker(ISettingsService<PlexSettings> plexSettings, ISettingsService<AuthenticationSettings> auth, IRequestService request, IPlexApi plex)
|
public PlexAvailabilityChecker(ISettingsService<PlexSettings> plexSettings, ISettingsService<AuthenticationSettings> auth, IRequestService request, IPlexApi plex, ICacheProvider cache)
|
||||||
{
|
{
|
||||||
Plex = plexSettings;
|
Plex = plexSettings;
|
||||||
Auth = auth;
|
Auth = auth;
|
||||||
RequestService = request;
|
RequestService = request;
|
||||||
PlexApi = plex;
|
PlexApi = plex;
|
||||||
|
Cache = cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ISettingsService<PlexSettings> Plex { get; }
|
private ISettingsService<PlexSettings> Plex { get; }
|
||||||
|
@ -56,7 +57,7 @@ namespace PlexRequests.Services
|
||||||
private IRequestService RequestService { get; }
|
private IRequestService RequestService { get; }
|
||||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
private IPlexApi PlexApi { get; }
|
private IPlexApi PlexApi { get; }
|
||||||
|
private ICacheProvider Cache { get; }
|
||||||
|
|
||||||
public void CheckAndUpdateAll(long check)
|
public void CheckAndUpdateAll(long check)
|
||||||
{
|
{
|
||||||
|
@ -65,14 +66,25 @@ namespace PlexRequests.Services
|
||||||
var plexSettings = Plex.GetSettings();
|
var plexSettings = Plex.GetSettings();
|
||||||
var authSettings = Auth.GetSettings();
|
var authSettings = Auth.GetSettings();
|
||||||
Log.Trace("Getting all the requests");
|
Log.Trace("Getting all the requests");
|
||||||
var requests = RequestService.GetAll();
|
|
||||||
|
|
||||||
|
if (!ValidateSettings(plexSettings, authSettings))
|
||||||
|
{
|
||||||
|
Log.Info("Validation of the plex settings failed.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var libraries = CachedLibraries(authSettings, plexSettings, true); //force setting the cache (10 min intervals via scheduler)
|
||||||
|
var movies = GetPlexMovies().ToArray();
|
||||||
|
var shows = GetPlexTvShows().ToArray();
|
||||||
|
var albums = GetPlexAlbums().ToArray();
|
||||||
|
|
||||||
|
var requests = RequestService.GetAll();
|
||||||
var requestedModels = requests as RequestedModel[] ?? requests.Where(x => !x.Available).ToArray();
|
var requestedModels = requests as RequestedModel[] ?? requests.Where(x => !x.Available).ToArray();
|
||||||
Log.Trace("Requests Count {0}", requestedModels.Length);
|
Log.Trace("Requests Count {0}", requestedModels.Length);
|
||||||
|
|
||||||
if (!ValidateSettings(plexSettings, authSettings) || !requestedModels.Any())
|
if (!requestedModels.Any())
|
||||||
{
|
{
|
||||||
Log.Info("Validation of the settings failed or there is no requests.");
|
Log.Info("There are no requests to check.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,39 +92,33 @@ namespace PlexRequests.Services
|
||||||
foreach (var r in requestedModels)
|
foreach (var r in requestedModels)
|
||||||
{
|
{
|
||||||
Log.Trace("We are going to see if Plex has the following title: {0}", r.Title);
|
Log.Trace("We are going to see if Plex has the following title: {0}", r.Title);
|
||||||
PlexSearch results;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
results = PlexApi.SearchContent(authSettings.PlexAuthToken, r.Title, plexSettings.FullUri);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Log.Error("We failed to search Plex for the following request:");
|
|
||||||
Log.Error(r.DumpJson());
|
|
||||||
Log.Error(e);
|
|
||||||
break; // Let's finish processing and not crash the process, there is a reason why we cannot connect.
|
|
||||||
}
|
|
||||||
|
|
||||||
if (results == null)
|
if (libraries == null)
|
||||||
|
{
|
||||||
|
libraries = new List<PlexSearch>() { PlexApi.SearchContent(authSettings.PlexAuthToken, r.Title, plexSettings.FullUri) };
|
||||||
|
if (libraries == null)
|
||||||
{
|
{
|
||||||
Log.Trace("Could not find any matching result for this title.");
|
Log.Trace("Could not find any matching result for this title.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Log.Trace("Search results from Plex for the following request: {0}", r.Title);
|
Log.Trace("Search results from Plex for the following request: {0}", r.Title);
|
||||||
Log.Trace(results.DumpJson());
|
//Log.Trace(results.DumpJson());
|
||||||
bool matchResult;
|
|
||||||
var releaseDate = r.ReleaseDate == DateTime.MinValue ? string.Empty : r.ReleaseDate.ToString("yyyy");
|
var releaseDate = r.ReleaseDate == DateTime.MinValue ? string.Empty : r.ReleaseDate.ToString("yyyy");
|
||||||
|
|
||||||
|
bool matchResult;
|
||||||
switch (r.Type)
|
switch (r.Type)
|
||||||
{
|
{
|
||||||
case RequestType.Movie:
|
case RequestType.Movie:
|
||||||
matchResult = MovieTvSearch(results, r.Title, releaseDate);
|
matchResult = IsMovieAvailable(movies, r.Title, releaseDate);
|
||||||
break;
|
break;
|
||||||
case RequestType.TvShow:
|
case RequestType.TvShow:
|
||||||
matchResult = MovieTvSearch(results, r.Title, releaseDate);
|
matchResult = IsTvShowAvailable(shows, r.Title, releaseDate);
|
||||||
break;
|
break;
|
||||||
case RequestType.Album:
|
case RequestType.Album:
|
||||||
matchResult = AlbumSearch(results, r.Title, r.ArtistName);
|
matchResult = IsAlbumAvailable(albums, r.Title, r.ReleaseDate.Year.ToString(), r.ArtistName);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException();
|
||||||
|
@ -138,117 +144,144 @@ namespace PlexRequests.Services
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public List<PlexMovie> GetPlexMovies()
|
||||||
/// Determines whether the specified title is available.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="title">The title.</param>
|
|
||||||
/// <param name="year">The year.</param>
|
|
||||||
/// <param name="artist">The artist.</param>
|
|
||||||
/// <param name="type">The type.</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
/// <exception cref="ApplicationSettingsException">The settings are not configured for Plex or Authentication</exception>
|
|
||||||
/// <exception cref="System.ArgumentOutOfRangeException">null</exception>
|
|
||||||
public bool IsAvailable(string title, string year, string artist, PlexType type)
|
|
||||||
{
|
{
|
||||||
Log.Trace("Checking if the following {0} {1} is available in Plex", title, year);
|
var movies = new List<PlexMovie>();
|
||||||
var plexSettings = Plex.GetSettings();
|
var libs = Cache.Get<List<PlexSearch>>(CacheKeys.PlexLibaries);
|
||||||
var authSettings = Auth.GetSettings();
|
if (libs != null)
|
||||||
|
{
|
||||||
|
var movieLibs = libs.Where(x =>
|
||||||
|
x.Video.Any(y =>
|
||||||
|
y.Type.Equals(PlexMediaType.Movie.ToString(), StringComparison.CurrentCultureIgnoreCase)
|
||||||
|
)
|
||||||
|
).ToArray();
|
||||||
|
|
||||||
|
foreach (var lib in movieLibs)
|
||||||
|
{
|
||||||
|
movies.AddRange(lib.Video.Select(x => new PlexMovie() // movies are in the Video list
|
||||||
|
{
|
||||||
|
Title = x.Title,
|
||||||
|
ReleaseYear = x.Year
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return movies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsMovieAvailable(PlexMovie[] plexMovies, string title, string year)
|
||||||
|
{
|
||||||
|
return plexMovies.Any(x => x.Title.Equals(title, StringComparison.CurrentCultureIgnoreCase) && x.ReleaseYear.Equals(year, StringComparison.CurrentCultureIgnoreCase));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<PlexTvShow> GetPlexTvShows()
|
||||||
|
{
|
||||||
|
var shows = new List<PlexTvShow>();
|
||||||
|
var libs = Cache.Get<List<PlexSearch>>(CacheKeys.PlexLibaries);
|
||||||
|
if (libs != null)
|
||||||
|
{
|
||||||
|
var tvLibs = libs.Where(x =>
|
||||||
|
x.Directory.Any(y =>
|
||||||
|
y.Type.Equals(PlexMediaType.Show.ToString(), StringComparison.CurrentCultureIgnoreCase)
|
||||||
|
)
|
||||||
|
).ToArray();
|
||||||
|
|
||||||
|
foreach (var lib in tvLibs)
|
||||||
|
{
|
||||||
|
shows.AddRange(lib.Directory.Select(x => new PlexTvShow() // shows are in the directory list
|
||||||
|
{
|
||||||
|
Title = x.Title,
|
||||||
|
ReleaseYear = x.Year
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return shows;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsTvShowAvailable(PlexTvShow[] plexShows, string title, string year)
|
||||||
|
{
|
||||||
|
return plexShows.Any(x =>
|
||||||
|
(x.Title.Equals(title, StringComparison.CurrentCultureIgnoreCase) || x.Title.StartsWith(title, StringComparison.CurrentCultureIgnoreCase)) &&
|
||||||
|
x.ReleaseYear.Equals(year, StringComparison.CurrentCultureIgnoreCase));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<PlexAlbum> GetPlexAlbums()
|
||||||
|
{
|
||||||
|
var albums = new List<PlexAlbum>();
|
||||||
|
var libs = Cache.Get<List<PlexSearch>>(CacheKeys.PlexLibaries);
|
||||||
|
if (libs != null)
|
||||||
|
{
|
||||||
|
var albumLibs = libs.Where(x =>
|
||||||
|
x.Directory.Any(y =>
|
||||||
|
y.Type.Equals(PlexMediaType.Show.ToString(), StringComparison.CurrentCultureIgnoreCase)
|
||||||
|
)
|
||||||
|
).ToArray();
|
||||||
|
|
||||||
|
foreach (var lib in albumLibs)
|
||||||
|
{
|
||||||
|
albums.AddRange(lib.Directory.Select(x => new PlexAlbum()
|
||||||
|
{
|
||||||
|
Title = x.Title,
|
||||||
|
ReleaseYear = x.Year,
|
||||||
|
Artist = x.ParentTitle
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return albums;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsAlbumAvailable(PlexAlbum[] plexAlbums, string title, string year, string artist)
|
||||||
|
{
|
||||||
|
return plexAlbums.Any(x =>
|
||||||
|
x.Title.Contains(title) &&
|
||||||
|
//x.ReleaseYear.Equals(year, StringComparison.CurrentCultureIgnoreCase) &&
|
||||||
|
x.Artist.Equals(artist, StringComparison.CurrentCultureIgnoreCase));
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<PlexSearch> CachedLibraries(AuthenticationSettings authSettings, PlexSettings plexSettings, bool setCache)
|
||||||
|
{
|
||||||
|
Log.Trace("Obtaining library sections from Plex for the following request");
|
||||||
|
|
||||||
|
List<PlexSearch> results = new List<PlexSearch>();
|
||||||
|
|
||||||
if (!ValidateSettings(plexSettings, authSettings))
|
if (!ValidateSettings(plexSettings, authSettings))
|
||||||
{
|
{
|
||||||
Log.Warn("The settings are not configured");
|
Log.Warn("The settings are not configured");
|
||||||
throw new ApplicationSettingsException("The settings are not configured for Plex or Authentication");
|
return results; // don't error out here, just let it go!
|
||||||
}
|
|
||||||
var results = PlexApi.SearchContent(authSettings.PlexAuthToken, title, plexSettings.FullUri);
|
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case PlexType.Movie:
|
|
||||||
return MovieTvSearch(results, title, year);
|
|
||||||
case PlexType.TvShow:
|
|
||||||
return MovieTvSearch(results, title, year);
|
|
||||||
case PlexType.Music:
|
|
||||||
return AlbumSearch(results, title, artist);
|
|
||||||
default:
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(type), type, null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
if (setCache)
|
||||||
/// Searches the movies and TV shows on Plex.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="results">The results.</param>
|
|
||||||
/// <param name="title">The title.</param>
|
|
||||||
/// <param name="year">The year.</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private bool MovieTvSearch(PlexSearch results, string title, string year)
|
|
||||||
{
|
{
|
||||||
try
|
results = GetLibraries(authSettings, plexSettings);
|
||||||
{
|
Cache.Set(CacheKeys.PlexLibaries, results, 10);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(year))
|
|
||||||
{
|
|
||||||
var result = results.Video?.FirstOrDefault(x => x.Title.Equals(title, StringComparison.InvariantCultureIgnoreCase) && x.Year == year);
|
|
||||||
|
|
||||||
var directoryResult = false;
|
|
||||||
if (results.Directory != null)
|
|
||||||
{
|
|
||||||
if (results.Directory.Any(d => d.Title.Equals(title, StringComparison.CurrentCultureIgnoreCase) && d.Year == year))
|
|
||||||
{
|
|
||||||
directoryResult = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result?.Title != null || directoryResult;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var result = results.Video?.FirstOrDefault(x => x.Title.Equals(title, StringComparison.InvariantCultureIgnoreCase));
|
results = Cache.GetOrSet(CacheKeys.PlexLibaries, () => {
|
||||||
var directoryResult = false;
|
return GetLibraries(authSettings, plexSettings);
|
||||||
if (results.Directory != null)
|
}, 10);
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<PlexSearch> GetLibraries(AuthenticationSettings authSettings, PlexSettings plexSettings)
|
||||||
{
|
{
|
||||||
if (results.Directory.Any(d => d.Title.Equals(title, StringComparison.CurrentCultureIgnoreCase)))
|
var sections = PlexApi.GetLibrarySections(authSettings.PlexAuthToken, plexSettings.FullUri);
|
||||||
|
|
||||||
|
List<PlexSearch> libs = new List<PlexSearch>();
|
||||||
|
if (sections != null)
|
||||||
{
|
{
|
||||||
directoryResult = true;
|
foreach (var dir in sections.Directories)
|
||||||
}
|
|
||||||
}
|
|
||||||
return result?.Title != null || directoryResult;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
{
|
||||||
Log.Error("Could not finish the Movie/TV check in Plex because of an exception:");
|
Log.Trace("Obtaining results from Plex for the following library section: {0}", dir.Title);
|
||||||
Log.Error(e);
|
var lib = PlexApi.GetLibrary(authSettings.PlexAuthToken, plexSettings.FullUri, dir.Key);
|
||||||
return false;
|
if (lib != null)
|
||||||
|
{
|
||||||
|
libs.Add(lib);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
return libs;
|
||||||
/// Searches the music on Plex.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="results">The results.</param>
|
|
||||||
/// <param name="title">The title.</param>
|
|
||||||
/// <param name="artist">The artist.</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private bool AlbumSearch(PlexSearch results, string title, string artist)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
foreach (var r in results.Directory)
|
|
||||||
{
|
|
||||||
var titleMatch = r.Title.Contains(title);
|
|
||||||
var artistMatch = r.ParentTitle.Equals(artist, StringComparison.CurrentCultureIgnoreCase);
|
|
||||||
if (titleMatch && artistMatch)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Log.Error("Could not finish the Album check in Plex because of an exception:");
|
|
||||||
Log.Error(e);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ValidateSettings(PlexSettings plex, AuthenticationSettings auth)
|
private bool ValidateSettings(PlexSettings plex, AuthenticationSettings auth)
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>PlexRequests.Services</RootNamespace>
|
<RootNamespace>PlexRequests.Services</RootNamespace>
|
||||||
<AssemblyName>PlexRequests.Services</AssemblyName>
|
<AssemblyName>PlexRequests.Services</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<TargetFrameworkProfile />
|
<TargetFrameworkProfile />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@ -31,11 +31,23 @@
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Reference Include="BouncyCastle, Version=1.8.1.0, Culture=neutral, PublicKeyToken=0e99375e54769942, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\MimeKit.1.2.22\lib\net45\BouncyCastle.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
<Reference Include="FluentScheduler, Version=3.1.46.0, Culture=neutral, PublicKeyToken=b76503528a14ebd1, processorArchitecture=MSIL">
|
<Reference Include="FluentScheduler, Version=3.1.46.0, Culture=neutral, PublicKeyToken=b76503528a14ebd1, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\FluentScheduler.3.1.46\lib\net40\FluentScheduler.dll</HintPath>
|
<HintPath>..\packages\FluentScheduler.3.1.46\lib\net40\FluentScheduler.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="MailKit, Version=1.2.0.0, Culture=neutral, PublicKeyToken=4e064fe7c44a8f1b, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\MailKit.1.2.21\lib\net451\MailKit.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Microsoft.Build.Framework" />
|
<Reference Include="Microsoft.Build.Framework" />
|
||||||
|
<Reference Include="MimeKit, Version=1.2.0.0, Culture=neutral, PublicKeyToken=bede1c8a46c66814, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\MimeKit.1.2.22\lib\net45\MimeKit.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Mono.Data.Sqlite, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
|
<Reference Include="Mono.Data.Sqlite, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\Assemblies\Mono.Data.Sqlite.dll</HintPath>
|
<HintPath>..\Assemblies\Mono.Data.Sqlite.dll</HintPath>
|
||||||
|
@ -62,6 +74,7 @@
|
||||||
<HintPath>..\packages\Rx-PlatformServices.2.2.5\lib\net45\System.Reactive.PlatformServices.dll</HintPath>
|
<HintPath>..\packages\Rx-PlatformServices.2.2.5\lib\net45\System.Reactive.PlatformServices.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="System.Security" />
|
||||||
<Reference Include="System.Web" />
|
<Reference Include="System.Web" />
|
||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
<Reference Include="System.Data.DataSetExtensions" />
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
@ -71,9 +84,18 @@
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Models\PlexAlbum.cs" />
|
||||||
|
<Compile Include="Models\PlexMovie.cs" />
|
||||||
|
<Compile Include="Models\PlexTvShow.cs" />
|
||||||
|
<Compile Include="SickRageCacher.cs" />
|
||||||
|
<Compile Include="Interfaces\ITvCacher.cs" />
|
||||||
|
<Compile Include="SonarrCacher.cs" />
|
||||||
|
<Compile Include="Interfaces\ISonarrCacher.cs" />
|
||||||
|
<Compile Include="MediaCacheService.cs" />
|
||||||
<Compile Include="AvailabilityUpdateService.cs" />
|
<Compile Include="AvailabilityUpdateService.cs" />
|
||||||
<Compile Include="Configuration.cs" />
|
<Compile Include="Configuration.cs" />
|
||||||
<Compile Include="ConfigurationReader.cs" />
|
<Compile Include="ConfigurationReader.cs" />
|
||||||
|
<Compile Include="Interfaces\ICouchPotatoCacher.cs" />
|
||||||
<Compile Include="Interfaces\IAvailabilityChecker.cs" />
|
<Compile Include="Interfaces\IAvailabilityChecker.cs" />
|
||||||
<Compile Include="Interfaces\IConfigurationReader.cs" />
|
<Compile Include="Interfaces\IConfigurationReader.cs" />
|
||||||
<Compile Include="Interfaces\IIntervals.cs" />
|
<Compile Include="Interfaces\IIntervals.cs" />
|
||||||
|
@ -85,6 +107,7 @@
|
||||||
<Compile Include="Notification\NotificationType.cs" />
|
<Compile Include="Notification\NotificationType.cs" />
|
||||||
<Compile Include="Notification\PushoverNotification.cs" />
|
<Compile Include="Notification\PushoverNotification.cs" />
|
||||||
<Compile Include="Notification\PushbulletNotification.cs" />
|
<Compile Include="Notification\PushbulletNotification.cs" />
|
||||||
|
<Compile Include="CouchPotatoCacher.cs" />
|
||||||
<Compile Include="PlexAvailabilityChecker.cs" />
|
<Compile Include="PlexAvailabilityChecker.cs" />
|
||||||
<Compile Include="PlexType.cs" />
|
<Compile Include="PlexType.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
|
78
PlexRequests.Services/SickRageCacher.cs
Normal file
78
PlexRequests.Services/SickRageCacher.cs
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: PlexAvailabilityChecker.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.Core;
|
||||||
|
using PlexRequests.Core.SettingModels;
|
||||||
|
using PlexRequests.Helpers;
|
||||||
|
using PlexRequests.Services.Interfaces;
|
||||||
|
using PlexRequests.Api.Models.Movie;
|
||||||
|
using System.Linq;
|
||||||
|
using PlexRequests.Api.Models.SickRage;
|
||||||
|
|
||||||
|
namespace PlexRequests.Services
|
||||||
|
{
|
||||||
|
public class SickRageCacher : ISickRageCacher
|
||||||
|
{
|
||||||
|
public SickRageCacher(ISettingsService<SickRageSettings> srSettings, ISickRageApi srApi, ICacheProvider cache)
|
||||||
|
{
|
||||||
|
SrSettings = srSettings;
|
||||||
|
SrApi = srApi;
|
||||||
|
Cache = cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ISettingsService<SickRageSettings> SrSettings { get; }
|
||||||
|
private ICacheProvider Cache { get; }
|
||||||
|
private ISickRageApi SrApi { get; }
|
||||||
|
|
||||||
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
public void Queued(long check)
|
||||||
|
{
|
||||||
|
Log.Trace("This is check no. {0}", check);
|
||||||
|
Log.Trace("Getting the settings");
|
||||||
|
|
||||||
|
var settings = SrSettings.GetSettings();
|
||||||
|
if (settings.Enabled)
|
||||||
|
{
|
||||||
|
Log.Trace("Getting all shows from SickRage");
|
||||||
|
var movies = SrApi.GetShows(settings.ApiKey, settings.FullUri);
|
||||||
|
Cache.Set(CacheKeys.SickRageQueued, movies.Result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we do not want to set here...
|
||||||
|
public int[] QueuedIds()
|
||||||
|
{
|
||||||
|
var tv = Cache.Get<SickrageShows>(CacheKeys.SickRageQueued);
|
||||||
|
return tv?.data.Values.Select(x => x.tvdbid).ToArray() ?? new int[] { };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
77
PlexRequests.Services/SonarrCacher.cs
Normal file
77
PlexRequests.Services/SonarrCacher.cs
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: PlexAvailabilityChecker.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 NLog;
|
||||||
|
|
||||||
|
using PlexRequests.Api.Interfaces;
|
||||||
|
using PlexRequests.Core;
|
||||||
|
using PlexRequests.Core.SettingModels;
|
||||||
|
using PlexRequests.Helpers;
|
||||||
|
using PlexRequests.Services.Interfaces;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using PlexRequests.Api.Models.Sonarr;
|
||||||
|
|
||||||
|
namespace PlexRequests.Services
|
||||||
|
{
|
||||||
|
public class SonarrCacher : ISonarrCacher
|
||||||
|
{
|
||||||
|
public SonarrCacher(ISettingsService<SonarrSettings> sonarrSettings, ISonarrApi sonarrApi, ICacheProvider cache)
|
||||||
|
{
|
||||||
|
SonarrSettings = sonarrSettings;
|
||||||
|
SonarrApi = sonarrApi;
|
||||||
|
Cache = cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ISettingsService<SonarrSettings> SonarrSettings { get; }
|
||||||
|
private ICacheProvider Cache { get; }
|
||||||
|
private ISonarrApi SonarrApi { get; }
|
||||||
|
|
||||||
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
public void Queued(long check)
|
||||||
|
{
|
||||||
|
Log.Trace("This is check no. {0}", check);
|
||||||
|
Log.Trace("Getting the settings");
|
||||||
|
|
||||||
|
var settings = SonarrSettings.GetSettings();
|
||||||
|
if (settings.Enabled)
|
||||||
|
{
|
||||||
|
Log.Trace("Getting all tv series from Sonarr");
|
||||||
|
var series = SonarrApi.GetSeries(settings.ApiKey, settings.FullUri);
|
||||||
|
Cache.Set(CacheKeys.SonarrQueued, series, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we do not want to set here...
|
||||||
|
public int[] QueuedIds()
|
||||||
|
{
|
||||||
|
var series = Cache.Get<List<Series>>(CacheKeys.SonarrQueued);
|
||||||
|
return series?.Select(x => x.tvdbId).ToArray() ?? new int[] { };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<runtime>
|
<runtime>
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
|
@ -8,4 +8,4 @@
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
</assemblyBinding>
|
</assemblyBinding>
|
||||||
</runtime>
|
</runtime>
|
||||||
</configuration>
|
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/></startup></configuration>
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="FluentScheduler" version="3.1.46" targetFramework="net452" />
|
<package id="FluentScheduler" version="3.1.46" targetFramework="net452" />
|
||||||
|
<package id="MailKit" version="1.2.21" targetFramework="net46" />
|
||||||
|
<package id="MimeKit" version="1.2.22" targetFramework="net46" />
|
||||||
<package id="NLog" version="4.2.3" targetFramework="net452" />
|
<package id="NLog" version="4.2.3" targetFramework="net452" />
|
||||||
<package id="Rx-Core" version="2.2.5" targetFramework="net452" />
|
<package id="Rx-Core" version="2.2.5" targetFramework="net452" />
|
||||||
<package id="Rx-Interfaces" version="2.2.5" targetFramework="net452" />
|
<package id="Rx-Interfaces" version="2.2.5" targetFramework="net452" />
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>PlexRequests.Store</RootNamespace>
|
<RootNamespace>PlexRequests.Store</RootNamespace>
|
||||||
<AssemblyName>PlexRequests.Store</AssemblyName>
|
<AssemblyName>PlexRequests.Store</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<TargetFrameworkProfile />
|
<TargetFrameworkProfile />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
|
@ -49,6 +49,7 @@ using PlexRequests.Helpers;
|
||||||
namespace PlexRequests.UI.Tests
|
namespace PlexRequests.UI.Tests
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
|
[Ignore("Needs rework")]
|
||||||
public class AdminModuleTests
|
public class AdminModuleTests
|
||||||
{
|
{
|
||||||
private Mock<ISettingsService<PlexRequestSettings>> PlexRequestMock { get; set; }
|
private Mock<ISettingsService<PlexRequestSettings>> PlexRequestMock { get; set; }
|
||||||
|
|
|
@ -30,6 +30,7 @@ using Moq;
|
||||||
|
|
||||||
using Nancy;
|
using Nancy;
|
||||||
using Nancy.Testing;
|
using Nancy.Testing;
|
||||||
|
using Nancy.TinyIoc;
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
@ -39,15 +40,18 @@ using PlexRequests.Api.Interfaces;
|
||||||
using PlexRequests.Api.Models.Plex;
|
using PlexRequests.Api.Models.Plex;
|
||||||
using PlexRequests.Core;
|
using PlexRequests.Core;
|
||||||
using PlexRequests.Core.SettingModels;
|
using PlexRequests.Core.SettingModels;
|
||||||
|
using PlexRequests.UI.Helpers;
|
||||||
using PlexRequests.UI.Models;
|
using PlexRequests.UI.Models;
|
||||||
using PlexRequests.UI.Modules;
|
using PlexRequests.UI.Modules;
|
||||||
|
|
||||||
namespace PlexRequests.UI.Tests
|
namespace PlexRequests.UI.Tests
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
|
[Ignore("Needs some work")]
|
||||||
public class UserLoginModuleTests
|
public class UserLoginModuleTests
|
||||||
{
|
{
|
||||||
private Mock<ISettingsService<AuthenticationSettings>> AuthMock { get; set; }
|
private Mock<ISettingsService<AuthenticationSettings>> AuthMock { get; set; }
|
||||||
|
private Mock<ISettingsService<PlexRequestSettings>> PlexRequestMock { get; set; }
|
||||||
private Mock<IPlexApi> PlexMock { get; set; }
|
private Mock<IPlexApi> PlexMock { get; set; }
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
|
@ -55,6 +59,7 @@ namespace PlexRequests.UI.Tests
|
||||||
{
|
{
|
||||||
AuthMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
AuthMock = new Mock<ISettingsService<AuthenticationSettings>>();
|
||||||
PlexMock = new Mock<IPlexApi>();
|
PlexMock = new Mock<IPlexApi>();
|
||||||
|
PlexRequestMock = new Mock<ISettingsService<PlexRequestSettings>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -68,6 +73,7 @@ namespace PlexRequests.UI.Tests
|
||||||
with.Module<UserLoginModule>();
|
with.Module<UserLoginModule>();
|
||||||
with.Dependency(AuthMock.Object);
|
with.Dependency(AuthMock.Object);
|
||||||
with.Dependency(PlexMock.Object);
|
with.Dependency(PlexMock.Object);
|
||||||
|
with.Dependency(PlexRequestMock.Object);
|
||||||
with.RootPathProvider<TestRootPathProvider>();
|
with.RootPathProvider<TestRootPathProvider>();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -26,12 +26,13 @@
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using FluentScheduler;
|
|
||||||
using Mono.Data.Sqlite;
|
using Mono.Data.Sqlite;
|
||||||
|
|
||||||
using Nancy;
|
using Nancy;
|
||||||
using Nancy.Authentication.Forms;
|
using Nancy.Authentication.Forms;
|
||||||
using Nancy.Bootstrapper;
|
using Nancy.Bootstrapper;
|
||||||
|
using Nancy.Conventions;
|
||||||
using Nancy.Cryptography;
|
using Nancy.Cryptography;
|
||||||
using Nancy.Diagnostics;
|
using Nancy.Diagnostics;
|
||||||
using Nancy.Session;
|
using Nancy.Session;
|
||||||
|
@ -39,7 +40,6 @@ using Nancy.TinyIoc;
|
||||||
|
|
||||||
using PlexRequests.Api;
|
using PlexRequests.Api;
|
||||||
using PlexRequests.Api.Interfaces;
|
using PlexRequests.Api.Interfaces;
|
||||||
using PlexRequests.Api.Mocks;
|
|
||||||
using PlexRequests.Core;
|
using PlexRequests.Core;
|
||||||
using PlexRequests.Core.SettingModels;
|
using PlexRequests.Core.SettingModels;
|
||||||
using PlexRequests.Helpers;
|
using PlexRequests.Helpers;
|
||||||
|
@ -49,8 +49,7 @@ using PlexRequests.Services.Notification;
|
||||||
using PlexRequests.Store;
|
using PlexRequests.Store;
|
||||||
using PlexRequests.Store.Models;
|
using PlexRequests.Store.Models;
|
||||||
using PlexRequests.Store.Repository;
|
using PlexRequests.Store.Repository;
|
||||||
using PlexRequests.UI.Jobs;
|
using PlexRequests.UI.Helpers;
|
||||||
using TaskFactory = FluentScheduler.TaskFactory;
|
|
||||||
|
|
||||||
namespace PlexRequests.UI
|
namespace PlexRequests.UI
|
||||||
{
|
{
|
||||||
|
@ -60,11 +59,12 @@ namespace PlexRequests.UI
|
||||||
// by overriding the various methods and properties.
|
// by overriding the various methods and properties.
|
||||||
// For more information https://github.com/NancyFx/Nancy/wiki/Bootstrapper
|
// For more information https://github.com/NancyFx/Nancy/wiki/Bootstrapper
|
||||||
|
|
||||||
|
|
||||||
protected override void ConfigureRequestContainer(TinyIoCContainer container, NancyContext context)
|
protected override void ConfigureRequestContainer(TinyIoCContainer container, NancyContext context)
|
||||||
{
|
{
|
||||||
container.Register<IUserMapper, UserMapper>();
|
container.Register<IUserMapper, UserMapper>();
|
||||||
container.Register<ISqliteConfiguration, DbConfiguration>(new DbConfiguration(new SqliteFactory()));
|
container.Register<ISqliteConfiguration, DbConfiguration>(new DbConfiguration(new SqliteFactory()));
|
||||||
container.Register<ICacheProvider, MemoryCacheProvider>();
|
container.Register<ICacheProvider, MemoryCacheProvider>().AsSingleton();
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
container.Register<ISettingsService<PlexRequestSettings>, SettingsServiceV2<PlexRequestSettings>>();
|
container.Register<ISettingsService<PlexRequestSettings>, SettingsServiceV2<PlexRequestSettings>>();
|
||||||
|
@ -85,6 +85,9 @@ namespace PlexRequests.UI
|
||||||
|
|
||||||
// Services
|
// Services
|
||||||
container.Register<IAvailabilityChecker, PlexAvailabilityChecker>();
|
container.Register<IAvailabilityChecker, PlexAvailabilityChecker>();
|
||||||
|
container.Register<ICouchPotatoCacher, CouchPotatoCacher>();
|
||||||
|
container.Register<ISonarrCacher, SonarrCacher>();
|
||||||
|
container.Register<ISickRageCacher, SickRageCacher>();
|
||||||
container.Register<IConfigurationReader, ConfigurationReader>();
|
container.Register<IConfigurationReader, ConfigurationReader>();
|
||||||
container.Register<IIntervals, UpdateInterval>();
|
container.Register<IIntervals, UpdateInterval>();
|
||||||
|
|
||||||
|
@ -103,9 +106,8 @@ namespace PlexRequests.UI
|
||||||
|
|
||||||
SubscribeAllObservers(container);
|
SubscribeAllObservers(container);
|
||||||
base.ConfigureRequestContainer(container, context);
|
base.ConfigureRequestContainer(container, context);
|
||||||
|
var loc = ServiceLocator.Instance;
|
||||||
TaskManager.TaskFactory = new PlexTaskFactory();
|
loc.SetContainer(container);
|
||||||
TaskManager.Initialize(new PlexRegistry());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
|
protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
|
||||||
|
@ -116,10 +118,14 @@ namespace PlexRequests.UI
|
||||||
|
|
||||||
base.ApplicationStartup(container, pipelines);
|
base.ApplicationStartup(container, pipelines);
|
||||||
|
|
||||||
|
var settings = new SettingsServiceV2<PlexRequestSettings>(new SettingsJsonRepository(new DbConfiguration(new SqliteFactory()), new MemoryCacheProvider()));
|
||||||
|
var baseUrl = settings.GetSettings().BaseUrl;
|
||||||
|
var redirect = string.IsNullOrEmpty(baseUrl) ? "~/login" : $"~/{baseUrl}/login";
|
||||||
|
|
||||||
// Enable forms auth
|
// Enable forms auth
|
||||||
var formsAuthConfiguration = new FormsAuthenticationConfiguration
|
var formsAuthConfiguration = new FormsAuthenticationConfiguration
|
||||||
{
|
{
|
||||||
RedirectUrl = "~/login",
|
RedirectUrl = redirect,
|
||||||
UserMapper = container.Resolve<IUserMapper>()
|
UserMapper = container.Resolve<IUserMapper>()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -131,6 +137,16 @@ namespace PlexRequests.UI
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void ConfigureConventions(NancyConventions nancyConventions)
|
||||||
|
{
|
||||||
|
base.ConfigureConventions(nancyConventions);
|
||||||
|
|
||||||
|
var settings = new SettingsServiceV2<PlexRequestSettings>(new SettingsJsonRepository(new DbConfiguration(new SqliteFactory()),new MemoryCacheProvider()));
|
||||||
|
var assetLocation = settings.GetSettings().BaseUrl;
|
||||||
|
nancyConventions.StaticContentsConventions.Add(
|
||||||
|
StaticContentConventionBuilder.AddDirectory($"{assetLocation}/Content", "Content")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
protected override DiagnosticsConfiguration DiagnosticsConfiguration => new DiagnosticsConfiguration { Password = @"password" };
|
protected override DiagnosticsConfiguration DiagnosticsConfiguration => new DiagnosticsConfiguration { Password = @"password" };
|
||||||
|
|
||||||
|
|
|
@ -192,7 +192,8 @@ label {
|
||||||
color: #ccc; }
|
color: #ccc; }
|
||||||
|
|
||||||
.form-control-search {
|
.form-control-search {
|
||||||
padding: 25px 105px 25px 16px; }
|
padding: 13px 105px 13px 16px;
|
||||||
|
height: 100%; }
|
||||||
|
|
||||||
.form-control-withbuttons {
|
.form-control-withbuttons {
|
||||||
padding-right: 105px; }
|
padding-right: 105px; }
|
||||||
|
|
2
PlexRequests.UI/Content/custom.min.css
vendored
2
PlexRequests.UI/Content/custom.min.css
vendored
|
@ -1 +1 @@
|
||||||
@media(min-width:768px){.row{position:relative;}.bottom-align-text{position:absolute;bottom:0;right:0;}}@media(max-width:48em){.home{padding-top:1rem;}}@media(min-width:48em){.home{padding-top:4rem;}}.btn{border-radius:.25rem !important;}.multiSelect{background-color:#4e5d6c;}.form-control-custom{background-color:#4e5d6c !important;color:#fff !important;border-radius:0;box-shadow:0 0 0 !important;}h1{font-size:3.5rem !important;font-weight:600 !important;}.request-title{margin-top:0 !important;font-size:1.9rem !important;}p{font-size:1.1rem !important;}label{display:inline-block !important;margin-bottom:.5rem !important;font-size:16px !important;}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{background:#4e5d6c;}.navbar .nav a .fa,.dropdown-menu a .fa{font-size:130%;top:1px;position:relative;display:inline-block;margin-right:5px;}.dropdown-menu a .fa{top:2px;}.btn-danger-outline{color:#d9534f !important;background-color:transparent;background-image:none;border-color:#d9534f !important;}.btn-danger-outline:focus,.btn-danger-outline.focus,.btn-danger-outline:active,.btn-danger-outline.active,.btn-danger-outline:hover,.open>.btn-danger-outline.dropdown-toggle{color:#fff !important;background-color:#d9534f !important;border-color:#d9534f !important;}.btn-primary-outline{color:#ff761b !important;background-color:transparent;background-image:none;border-color:#ff761b !important;}.btn-primary-outline:focus,.btn-primary-outline.focus,.btn-primary-outline:active,.btn-primary-outline.active,.btn-primary-outline:hover,.open>.btn-primary-outline.dropdown-toggle{color:#fff !important;background-color:#df691a !important;border-color:#df691a !important;}.btn-info-outline{color:#5bc0de !important;background-color:transparent;background-image:none;border-color:#5bc0de !important;}.btn-info-outline:focus,.btn-info-outline.focus,.btn-info-outline:active,.btn-info-outline.active,.btn-info-outline:hover,.open>.btn-info-outline.dropdown-toggle{color:#fff !important;background-color:#5bc0de !important;border-color:#5bc0de !important;}.btn-warning-outline{color:#f0ad4e !important;background-color:transparent;background-image:none;border-color:#f0ad4e !important;}.btn-warning-outline:focus,.btn-warning-outline.focus,.btn-warning-outline:active,.btn-warning-outline.active,.btn-warning-outline:hover,.open>.btn-warning-outline.dropdown-toggle{color:#fff !important;background-color:#f0ad4e !important;border-color:#f0ad4e !important;}.btn-success-outline{color:#5cb85c !important;background-color:transparent;background-image:none;border-color:#5cb85c !important;}.btn-success-outline:focus,.btn-success-outline.focus,.btn-success-outline:active,.btn-success-outline.active,.btn-success-outline:hover,.open>.btn-success-outline.dropdown-toggle{color:#fff !important;background-color:#5cb85c !important;border-color:#5cb85c !important;}#movieList .mix{display:none;}#tvList .mix{display:none;}.scroll-top-wrapper{position:fixed;opacity:0;visibility:hidden;overflow:hidden;text-align:center;z-index:99999999;background-color:#4e5d6c;color:#eee;width:50px;height:48px;line-height:48px;right:30px;bottom:30px;padding-top:2px;border-top-left-radius:10px;border-top-right-radius:10px;border-bottom-right-radius:10px;border-bottom-left-radius:10px;-webkit-transition:all .5s ease-in-out;-moz-transition:all .5s ease-in-out;-ms-transition:all .5s ease-in-out;-o-transition:all .5s ease-in-out;transition:all .5s ease-in-out;}.scroll-top-wrapper:hover{background-color:#637689;}.scroll-top-wrapper.show{visibility:visible;cursor:pointer;opacity:1;}.scroll-top-wrapper i.fa{line-height:inherit;}.no-search-results{text-align:center;}.no-search-results .no-search-results-icon{font-size:10em;color:#4e5d6c;}.no-search-results .no-search-results-text{margin:20px 0;color:#ccc;}.form-control-search{padding:25px 105px 25px 16px;}.form-control-withbuttons{padding-right:105px;}.input-group-addon .btn-group{position:absolute;right:45px;z-index:3;top:13px;box-shadow:0 0 0;}.input-group-addon .btn-group .btn{border:1px solid rgba(255,255,255,.7) !important;padding:3px 12px;color:rgba(255,255,255,.7) !important;}.btn-split .btn{border-radius:0 !important;}.btn-split .btn:not(.dropdown-toggle){border-radius:.25rem 0 0 .25rem !important;}.btn-split .btn.dropdown-toggle{border-radius:0 .25rem .25rem 0 !important;padding:12px 8px;}
|
@media(min-width:768px){.row{position:relative;}.bottom-align-text{position:absolute;bottom:0;right:0;}}@media(max-width:48em){.home{padding-top:1rem;}}@media(min-width:48em){.home{padding-top:4rem;}}.btn{border-radius:.25rem !important;}.multiSelect{background-color:#4e5d6c;}.form-control-custom{background-color:#4e5d6c !important;color:#fff !important;border-radius:0;box-shadow:0 0 0 !important;}h1{font-size:3.5rem !important;font-weight:600 !important;}.request-title{margin-top:0 !important;font-size:1.9rem !important;}p{font-size:1.1rem !important;}label{display:inline-block !important;margin-bottom:.5rem !important;font-size:16px !important;}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{background:#4e5d6c;}.navbar .nav a .fa,.dropdown-menu a .fa{font-size:130%;top:1px;position:relative;display:inline-block;margin-right:5px;}.dropdown-menu a .fa{top:2px;}.btn-danger-outline{color:#d9534f !important;background-color:transparent;background-image:none;border-color:#d9534f !important;}.btn-danger-outline:focus,.btn-danger-outline.focus,.btn-danger-outline:active,.btn-danger-outline.active,.btn-danger-outline:hover,.open>.btn-danger-outline.dropdown-toggle{color:#fff !important;background-color:#d9534f !important;border-color:#d9534f !important;}.btn-primary-outline{color:#ff761b !important;background-color:transparent;background-image:none;border-color:#ff761b !important;}.btn-primary-outline:focus,.btn-primary-outline.focus,.btn-primary-outline:active,.btn-primary-outline.active,.btn-primary-outline:hover,.open>.btn-primary-outline.dropdown-toggle{color:#fff !important;background-color:#df691a !important;border-color:#df691a !important;}.btn-info-outline{color:#5bc0de !important;background-color:transparent;background-image:none;border-color:#5bc0de !important;}.btn-info-outline:focus,.btn-info-outline.focus,.btn-info-outline:active,.btn-info-outline.active,.btn-info-outline:hover,.open>.btn-info-outline.dropdown-toggle{color:#fff !important;background-color:#5bc0de !important;border-color:#5bc0de !important;}.btn-warning-outline{color:#f0ad4e !important;background-color:transparent;background-image:none;border-color:#f0ad4e !important;}.btn-warning-outline:focus,.btn-warning-outline.focus,.btn-warning-outline:active,.btn-warning-outline.active,.btn-warning-outline:hover,.open>.btn-warning-outline.dropdown-toggle{color:#fff !important;background-color:#f0ad4e !important;border-color:#f0ad4e !important;}.btn-success-outline{color:#5cb85c !important;background-color:transparent;background-image:none;border-color:#5cb85c !important;}.btn-success-outline:focus,.btn-success-outline.focus,.btn-success-outline:active,.btn-success-outline.active,.btn-success-outline:hover,.open>.btn-success-outline.dropdown-toggle{color:#fff !important;background-color:#5cb85c !important;border-color:#5cb85c !important;}#movieList .mix{display:none;}#tvList .mix{display:none;}.scroll-top-wrapper{position:fixed;opacity:0;visibility:hidden;overflow:hidden;text-align:center;z-index:99999999;background-color:#4e5d6c;color:#eee;width:50px;height:48px;line-height:48px;right:30px;bottom:30px;padding-top:2px;border-top-left-radius:10px;border-top-right-radius:10px;border-bottom-right-radius:10px;border-bottom-left-radius:10px;-webkit-transition:all .5s ease-in-out;-moz-transition:all .5s ease-in-out;-ms-transition:all .5s ease-in-out;-o-transition:all .5s ease-in-out;transition:all .5s ease-in-out;}.scroll-top-wrapper:hover{background-color:#637689;}.scroll-top-wrapper.show{visibility:visible;cursor:pointer;opacity:1;}.scroll-top-wrapper i.fa{line-height:inherit;}.no-search-results{text-align:center;}.no-search-results .no-search-results-icon{font-size:10em;color:#4e5d6c;}.no-search-results .no-search-results-text{margin:20px 0;color:#ccc;}.form-control-search{padding:13px 105px 13px 16px;height:100%;}.form-control-withbuttons{padding-right:105px;}.input-group-addon .btn-group{position:absolute;right:45px;z-index:3;top:13px;box-shadow:0 0 0;}.input-group-addon .btn-group .btn{border:1px solid rgba(255,255,255,.7) !important;padding:3px 12px;color:rgba(255,255,255,.7) !important;}.btn-split .btn{border-radius:0 !important;}.btn-split .btn:not(.dropdown-toggle){border-radius:.25rem 0 0 .25rem !important;}.btn-split .btn.dropdown-toggle{border-radius:0 .25rem .25rem 0 !important;padding:12px 8px;}
|
|
@ -246,7 +246,8 @@ $border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-control-search {
|
.form-control-search {
|
||||||
padding: 25px 105px 25px 16px;
|
padding: 13px 105px 13px 16px;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-control-withbuttons {
|
.form-control-withbuttons {
|
||||||
|
|
|
@ -11,6 +11,7 @@ var searchTemplate = Handlebars.compile(searchSource);
|
||||||
var albumTemplate = Handlebars.compile(albumSource);
|
var albumTemplate = Handlebars.compile(albumSource);
|
||||||
var movieTimer = 0;
|
var movieTimer = 0;
|
||||||
var tvimer = 0;
|
var tvimer = 0;
|
||||||
|
var base = $('#baseUrl').text();
|
||||||
|
|
||||||
var mixItUpDefault = {
|
var mixItUpDefault = {
|
||||||
animation: { enable: true },
|
animation: { enable: true },
|
||||||
|
@ -94,9 +95,10 @@ $('#approveMovies').click(function (e) {
|
||||||
|
|
||||||
loadingButton(buttonId, "success");
|
loadingButton(buttonId, "success");
|
||||||
|
|
||||||
|
var url = createBaseUrl(base, '/approval/approveallmovies');
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'post',
|
type: 'post',
|
||||||
url: '/approval/approveallmovies',
|
url: url,
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (response) {
|
success: function (response) {
|
||||||
if (checkJsonResponse(response)) {
|
if (checkJsonResponse(response)) {
|
||||||
|
@ -123,10 +125,10 @@ $('#approveTVShows').click(function (e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
loadingButton(buttonId, "success");
|
loadingButton(buttonId, "success");
|
||||||
|
var url = createBaseUrl(base, '/approval/approvealltvshows');
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'post',
|
type: 'post',
|
||||||
url: '/approval/approvealltvshows',
|
url: url,
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (response) {
|
success: function (response) {
|
||||||
if (checkJsonResponse(response)) {
|
if (checkJsonResponse(response)) {
|
||||||
|
@ -379,16 +381,20 @@ $(document).on("click", ".change", function (e) {
|
||||||
generateNotify("Success! Availibility changed.", "info");
|
generateNotify("Success! Availibility changed.", "info");
|
||||||
var button = $("button[custom-availibility='" + buttonId + "']");
|
var button = $("button[custom-availibility='" + buttonId + "']");
|
||||||
var icon = $('#availableIcon' + buttonId);
|
var icon = $('#availableIcon' + buttonId);
|
||||||
|
var approvedIcon = $("#"+buttonId + "notapproved");
|
||||||
|
|
||||||
if (response.available) {
|
if (response.available) {
|
||||||
button.text("Mark Unavailable");
|
button.text("Mark Unavailable");
|
||||||
button.val("false");
|
button.val("false");
|
||||||
button.prop("class", "btn btn-sm btn-info-outline change");
|
button.prop("class", "btn btn-sm btn-info-outline change");
|
||||||
icon.prop("class", "fa fa-check");
|
icon.prop("class", "fa fa-check");
|
||||||
|
approvedIcon.prop("class", "fa fa-check");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
button.text("Mark Available");
|
button.text("Mark Available");
|
||||||
button.prop("class", "btn btn-sm btn-success-outline change");
|
button.prop("class", "btn btn-sm btn-success-outline change");
|
||||||
icon.prop("class", "fa fa-times");
|
icon.prop("class", "fa fa-times");
|
||||||
|
approvedIcon.prop("class", "fa fa-times");
|
||||||
button.val("true");
|
button.val("true");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -456,7 +462,8 @@ function movieLoad() {
|
||||||
}
|
}
|
||||||
$ml.html("");
|
$ml.html("");
|
||||||
|
|
||||||
$.ajax("/requests/movies/").success(function (results) {
|
var url = createBaseUrl(base, '/requests/movies');
|
||||||
|
$.ajax(url).success(function (results) {
|
||||||
if (results.length > 0) {
|
if (results.length > 0) {
|
||||||
results.forEach(function (result) {
|
results.forEach(function (result) {
|
||||||
var context = buildRequestContext(result, "movie");
|
var context = buildRequestContext(result, "movie");
|
||||||
|
@ -478,8 +485,8 @@ function tvLoad() {
|
||||||
$tvl.mixItUp('destroy');
|
$tvl.mixItUp('destroy');
|
||||||
}
|
}
|
||||||
$tvl.html("");
|
$tvl.html("");
|
||||||
|
var url = createBaseUrl(base, '/requests/tvshows');
|
||||||
$.ajax("/requests/tvshows/").success(function (results) {
|
$.ajax(url).success(function (results) {
|
||||||
if (results.length > 0) {
|
if (results.length > 0) {
|
||||||
results.forEach(function (result) {
|
results.forEach(function (result) {
|
||||||
var context = buildRequestContext(result, "tv");
|
var context = buildRequestContext(result, "tv");
|
||||||
|
@ -501,8 +508,8 @@ function albumLoad() {
|
||||||
$albumL.mixItUp('destroy');
|
$albumL.mixItUp('destroy');
|
||||||
}
|
}
|
||||||
$albumL.html("");
|
$albumL.html("");
|
||||||
|
var url = createBaseUrl(base, '/requests/albums');
|
||||||
$.ajax("/requests/albums/").success(function (results) {
|
$.ajax(url).success(function (results) {
|
||||||
if (results.length > 0) {
|
if (results.length > 0) {
|
||||||
results.forEach(function (result) {
|
results.forEach(function (result) {
|
||||||
var context = buildRequestContext(result, "album");
|
var context = buildRequestContext(result, "album");
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
return opts.inverse(this);
|
return opts.inverse(this);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$(function () {
|
$(function () {
|
||||||
|
|
||||||
var searchSource = $("#search-template").html();
|
var searchSource = $("#search-template").html();
|
||||||
|
@ -12,6 +14,8 @@ $(function () {
|
||||||
var searchTemplate = Handlebars.compile(searchSource);
|
var searchTemplate = Handlebars.compile(searchSource);
|
||||||
var musicTemplate = Handlebars.compile(musicSource);
|
var musicTemplate = Handlebars.compile(musicSource);
|
||||||
|
|
||||||
|
var base = $('#baseUrl').text();
|
||||||
|
|
||||||
var searchTimer = 0;
|
var searchTimer = 0;
|
||||||
|
|
||||||
// fix for selecting a default tab
|
// fix for selecting a default tab
|
||||||
|
@ -21,7 +25,7 @@ $(function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
||||||
focusSearch($($(e.target).attr('href')))
|
focusSearch($($(e.target).attr('href')));
|
||||||
});
|
});
|
||||||
focusSearch($('li.active a', '#nav-tabs').first().attr('href'));
|
focusSearch($('li.active a', '#nav-tabs').first().attr('href'));
|
||||||
|
|
||||||
|
@ -30,7 +34,6 @@ $(function () {
|
||||||
if (searchTimer) {
|
if (searchTimer) {
|
||||||
clearTimeout(searchTimer);
|
clearTimeout(searchTimer);
|
||||||
}
|
}
|
||||||
$('#movieSearchButton').attr("class", "fa fa-spinner fa-spin");
|
|
||||||
searchTimer = setTimeout(movieSearch, 400);
|
searchTimer = setTimeout(movieSearch, 400);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -50,7 +53,6 @@ $(function () {
|
||||||
if (searchTimer) {
|
if (searchTimer) {
|
||||||
clearTimeout(searchTimer);
|
clearTimeout(searchTimer);
|
||||||
}
|
}
|
||||||
$('#tvSearchButton').attr("class", "fa fa-spinner fa-spin");
|
|
||||||
searchTimer = setTimeout(tvSearch, 400);
|
searchTimer = setTimeout(tvSearch, 400);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -90,7 +92,6 @@ $(function () {
|
||||||
if (searchTimer) {
|
if (searchTimer) {
|
||||||
clearTimeout(searchTimer);
|
clearTimeout(searchTimer);
|
||||||
}
|
}
|
||||||
$('#musicSearchButton').attr("class", "fa fa-spinner fa-spin");
|
|
||||||
searchTimer = setTimeout(musicSearch, 400);
|
searchTimer = setTimeout(musicSearch, 400);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -175,21 +176,24 @@ $(function () {
|
||||||
|
|
||||||
function movieSearch() {
|
function movieSearch() {
|
||||||
var query = $("#movieSearchContent").val();
|
var query = $("#movieSearchContent").val();
|
||||||
getMovies("/search/movie/" + query);
|
var url = createBaseUrl(base, '/search/movie/');
|
||||||
|
query ? getMovies(url + query) : resetMovies();
|
||||||
}
|
}
|
||||||
|
|
||||||
function moviesComingSoon() {
|
function moviesComingSoon() {
|
||||||
getMovies("/search/movie/upcoming");
|
var url = createBaseUrl(base, '/search/movie/upcoming');
|
||||||
|
getMovies(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
function moviesInTheaters() {
|
function moviesInTheaters() {
|
||||||
getMovies("/search/movie/playing");
|
var url = createBaseUrl(base, '/search/movie/playing');
|
||||||
|
getMovies(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMovies(url) {
|
function getMovies(url) {
|
||||||
$("#movieList").html("");
|
resetMovies();
|
||||||
|
|
||||||
|
|
||||||
|
$('#movieSearchButton').attr("class", "fa fa-spinner fa-spin");
|
||||||
$.ajax(url).success(function (results) {
|
$.ajax(url).success(function (results) {
|
||||||
if (results.length > 0) {
|
if (results.length > 0) {
|
||||||
results.forEach(function (result) {
|
results.forEach(function (result) {
|
||||||
|
@ -206,14 +210,21 @@ $(function () {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function resetMovies() {
|
||||||
|
$("#movieList").html("");
|
||||||
|
}
|
||||||
|
|
||||||
function tvSearch() {
|
function tvSearch() {
|
||||||
var query = $("#tvSearchContent").val();
|
var query = $("#tvSearchContent").val();
|
||||||
getTvShows("/search/tv/" + query);
|
|
||||||
|
var url = createBaseUrl(base, '/search/tv/');
|
||||||
|
query ? getTvShows(url + query) : resetTvShows();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTvShows(url) {
|
function getTvShows(url) {
|
||||||
$("#tvList").html("");
|
resetTvShows();
|
||||||
|
|
||||||
|
$('#tvSearchButton').attr("class", "fa fa-spinner fa-spin");
|
||||||
$.ajax(url).success(function (results) {
|
$.ajax(url).success(function (results) {
|
||||||
if (results.length > 0) {
|
if (results.length > 0) {
|
||||||
results.forEach(function (result) {
|
results.forEach(function (result) {
|
||||||
|
@ -229,14 +240,20 @@ $(function () {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function resetTvShows() {
|
||||||
|
$("#tvList").html("");
|
||||||
|
}
|
||||||
|
|
||||||
function musicSearch() {
|
function musicSearch() {
|
||||||
|
var url = createBaseUrl(base, '/search/music/');
|
||||||
var query = $("#musicSearchContent").val();
|
var query = $("#musicSearchContent").val();
|
||||||
getMusic("/search/music/" + query);
|
query ? getMusic(url + query) : resetMusic();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMusic(url) {
|
function getMusic(url) {
|
||||||
$("#musicList").html("");
|
resetMusic();
|
||||||
|
|
||||||
|
$('#musicSearchButton').attr("class", "fa fa-spinner fa-spin");
|
||||||
$.ajax(url).success(function (results) {
|
$.ajax(url).success(function (results) {
|
||||||
if (results.length > 0) {
|
if (results.length > 0) {
|
||||||
results.forEach(function (result) {
|
results.forEach(function (result) {
|
||||||
|
@ -254,8 +271,14 @@ $(function () {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function resetMusic() {
|
||||||
|
$("#musicList").html("");
|
||||||
|
}
|
||||||
|
|
||||||
function getCoverArt(artistId) {
|
function getCoverArt(artistId) {
|
||||||
$.ajax("/search/music/coverart/" + artistId).success(function (result) {
|
|
||||||
|
var url = createBaseUrl(base, '/search/music/coverart/');
|
||||||
|
$.ajax(url + artistId).success(function (result) {
|
||||||
if (result) {
|
if (result) {
|
||||||
$('#' + artistId + "imageDiv").html(" <img class='img-responsive' src='" + result + "' width='150' alt='poster'>");
|
$('#' + artistId + "imageDiv").html(" <img class='img-responsive' src='" + result + "' width='150' alt='poster'>");
|
||||||
}
|
}
|
||||||
|
@ -274,7 +297,10 @@ $(function () {
|
||||||
voteAverage: result.voteAverage,
|
voteAverage: result.voteAverage,
|
||||||
year: year,
|
year: year,
|
||||||
type: "movie",
|
type: "movie",
|
||||||
imdb: result.imdbId
|
imdb: result.imdbId,
|
||||||
|
requested: result.requested,
|
||||||
|
approved: result.approved,
|
||||||
|
available: result.available
|
||||||
};
|
};
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
|
@ -290,7 +316,10 @@ $(function () {
|
||||||
overview: result.overview,
|
overview: result.overview,
|
||||||
year: year,
|
year: year,
|
||||||
type: "tv",
|
type: "tv",
|
||||||
imdb: result.imdbId
|
imdb: result.imdbId,
|
||||||
|
requested: result.requested,
|
||||||
|
approved: result.approved,
|
||||||
|
available: result.available
|
||||||
};
|
};
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
@ -307,7 +336,10 @@ $(function () {
|
||||||
coverArtUrl: result.coverArtUrl,
|
coverArtUrl: result.coverArtUrl,
|
||||||
artist: result.artist,
|
artist: result.artist,
|
||||||
releaseType: result.releaseType,
|
releaseType: result.releaseType,
|
||||||
country: result.country
|
country: result.country,
|
||||||
|
requested: result.requested,
|
||||||
|
approved: result.approved,
|
||||||
|
available: result.available
|
||||||
};
|
};
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
|
|
|
@ -62,6 +62,17 @@ function finishLoading(elementId, originalCss, html) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createBaseUrl(base, url) {
|
||||||
|
if (base) {
|
||||||
|
if (url.charAt(0) === "/") {
|
||||||
|
url = "/" + base + url;
|
||||||
|
} else {
|
||||||
|
url = "/" + base + "/" + url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
var noResultsHtml = "<div class='no-search-results'>" +
|
var noResultsHtml = "<div class='no-search-results'>" +
|
||||||
"<i class='fa fa-film no-search-results-icon'></i><div class='no-search-results-text'>Sorry, we didn't find any results!</div></div>";
|
"<i class='fa fa-film no-search-results-icon'></i><div class='no-search-results-text'>Sorry, we didn't find any results!</div></div>";
|
||||||
var noResultsMusic = "<div class='no-search-results'>" +
|
var noResultsMusic = "<div class='no-search-results'>" +
|
||||||
|
|
176
PlexRequests.UI/Helpers/BaseUrlHelper.cs
Normal file
176
PlexRequests.UI/Helpers/BaseUrlHelper.cs
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: BaseUrlHelper.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.IO;
|
||||||
|
using System.Text;
|
||||||
|
using Nancy;
|
||||||
|
using Nancy.ViewEngines.Razor;
|
||||||
|
|
||||||
|
using PlexRequests.Core;
|
||||||
|
using PlexRequests.Core.SettingModels;
|
||||||
|
using PlexRequests.Helpers;
|
||||||
|
|
||||||
|
namespace PlexRequests.UI.Helpers
|
||||||
|
{
|
||||||
|
public static class BaseUrlHelper
|
||||||
|
{
|
||||||
|
static BaseUrlHelper()
|
||||||
|
{
|
||||||
|
Locator = ServiceLocator.Instance;
|
||||||
|
Cache = Locator.Resolve<ICacheProvider>();
|
||||||
|
}
|
||||||
|
private static ICacheProvider Cache { get; }
|
||||||
|
private static ServiceLocator Locator { get; }
|
||||||
|
|
||||||
|
public static IHtmlString LoadAssets(this HtmlHelpers helper)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
var assetLocation = GetBaseUrl();
|
||||||
|
|
||||||
|
var content = GetContentUrl(assetLocation);
|
||||||
|
|
||||||
|
sb.AppendLine($"<link rel=\"stylesheet\" href=\"{content}/Content/bootstrap.css\" type=\"text/css\"/>");
|
||||||
|
sb.AppendLine($"<link rel=\"stylesheet\" href=\"{content}/Content/custom.min.css\" type=\"text/css\" />");
|
||||||
|
sb.AppendLine($"<link rel=\"stylesheet\" href=\"{content}/Content/font-awesome.css\" type=\"text/css\"/>");
|
||||||
|
sb.AppendLine($"<link rel=\"stylesheet\" href=\"{content}/Content/pace.min.css\" type=\"text/css\"/>");
|
||||||
|
|
||||||
|
sb.AppendLine($"<script src=\"{content}/Content/jquery-2.2.1.min.js\"></script>");
|
||||||
|
sb.AppendLine($"<script src=\"{content}/Content/handlebars.min.js\"></script>");
|
||||||
|
sb.AppendLine($"<script src=\"{content}/Content/bootstrap.min.js\"></script>");
|
||||||
|
sb.AppendLine($"<script src=\"{content}/Content/bootstrap-notify.min.js\"></script>");
|
||||||
|
sb.AppendLine($"<script src=\"{content}/Content/site.js\"></script>");
|
||||||
|
sb.AppendLine($"<script src=\"{content}/Content/pace.min.js\"></script>");
|
||||||
|
sb.AppendLine($"<script src=\"{content}/Content/jquery.mixitup.js\"></script>");
|
||||||
|
sb.AppendLine($"<script src=\"{content}/Content/moment.min.js\"></script>");
|
||||||
|
|
||||||
|
|
||||||
|
return helper.Raw(sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IHtmlString LoadSearchAssets(this HtmlHelpers helper)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
var assetLocation = GetBaseUrl();
|
||||||
|
|
||||||
|
var content = GetContentUrl(assetLocation);
|
||||||
|
|
||||||
|
sb.AppendLine($"<script src=\"{content}/Content/search.js\" type=\"text/javascript\"></script>");
|
||||||
|
|
||||||
|
return helper.Raw(sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IHtmlString LoadRequestAssets(this HtmlHelpers helper)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
var assetLocation = GetBaseUrl();
|
||||||
|
|
||||||
|
var content = GetContentUrl(assetLocation);
|
||||||
|
|
||||||
|
sb.AppendLine($"<script src=\"{content}/Content/requests.js\" type=\"text/javascript\"></script>");
|
||||||
|
|
||||||
|
return helper.Raw(sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IHtmlString LoadLogsAssets(this HtmlHelpers helper)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
var assetLocation = GetBaseUrl();
|
||||||
|
|
||||||
|
var content = GetContentUrl(assetLocation);
|
||||||
|
|
||||||
|
sb.AppendLine($"<script src=\"{content}/Content/datatables.min.js\" type=\"text/javascript\"></script>");
|
||||||
|
sb.AppendLine($"<link rel=\"stylesheet\" type=\"text/css\" href=\"{content}/Content/dataTables.bootstrap.css\" />");
|
||||||
|
|
||||||
|
return helper.Raw(sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IHtmlString GetSidebarUrl(this HtmlHelpers helper, NancyContext context, string url, string title)
|
||||||
|
{
|
||||||
|
var returnString = string.Empty;
|
||||||
|
var content = GetLinkUrl(GetBaseUrl());
|
||||||
|
if (!string.IsNullOrEmpty(content))
|
||||||
|
{
|
||||||
|
url = $"/{content}{url}";
|
||||||
|
}
|
||||||
|
if (context.Request.Path == url)
|
||||||
|
{
|
||||||
|
returnString = $"<a class=\"list-group-item active\" href=\"{url}\">{title}</a>";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
returnString = $"<a class=\"list-group-item\" href=\"{url}\">{title}</a>";
|
||||||
|
}
|
||||||
|
|
||||||
|
return helper.Raw(returnString);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IHtmlString GetNavbarUrl(this HtmlHelpers helper, NancyContext context, string url, string title, string fontIcon)
|
||||||
|
{
|
||||||
|
var returnString = string.Empty;
|
||||||
|
var content = GetLinkUrl(GetBaseUrl());
|
||||||
|
if (!string.IsNullOrEmpty(content))
|
||||||
|
{
|
||||||
|
url = $"/{content}{url}";
|
||||||
|
}
|
||||||
|
if (context.Request.Path == url)
|
||||||
|
{
|
||||||
|
returnString = $"<li class=\"active\"><a href=\"{url}\"><i class=\"fa fa-{fontIcon}\"></i> {title}</a></li>";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
returnString = $"<li><a href=\"{url}\"><i class=\"fa fa-{fontIcon}\"></i> {title}</a></li>";
|
||||||
|
}
|
||||||
|
|
||||||
|
return helper.Raw(returnString);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IHtmlString GetBaseUrl(this HtmlHelpers helper)
|
||||||
|
{
|
||||||
|
return helper.Raw(GetBaseUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetBaseUrl()
|
||||||
|
{
|
||||||
|
var returnValue = Cache.GetOrSet(CacheKeys.GetBaseUrl, () =>
|
||||||
|
{
|
||||||
|
var settings = Locator.Resolve<ISettingsService<PlexRequestSettings>>().GetSettings();
|
||||||
|
var assetLocation = settings.BaseUrl;
|
||||||
|
return assetLocation;
|
||||||
|
});
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetLinkUrl(string assetLocation)
|
||||||
|
{
|
||||||
|
return string.IsNullOrEmpty(assetLocation) ? string.Empty : $"{assetLocation}";
|
||||||
|
}
|
||||||
|
private static string GetContentUrl(string assetLocation)
|
||||||
|
{
|
||||||
|
return string.IsNullOrEmpty(assetLocation) ? string.Empty : $"/{assetLocation}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
50
PlexRequests.UI/Helpers/ServiceLocator.cs
Normal file
50
PlexRequests.UI/Helpers/ServiceLocator.cs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: ServiceLocator.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.TinyIoc;
|
||||||
|
|
||||||
|
namespace PlexRequests.UI.Helpers
|
||||||
|
{
|
||||||
|
public class ServiceLocator
|
||||||
|
{
|
||||||
|
static ServiceLocator()
|
||||||
|
{
|
||||||
|
Singleton = new ServiceLocator();
|
||||||
|
}
|
||||||
|
private static ServiceLocator Singleton { get; }
|
||||||
|
private TinyIoCContainer Container { get; set; }
|
||||||
|
public static ServiceLocator Instance => Singleton;
|
||||||
|
|
||||||
|
public void SetContainer(TinyIoCContainer con)
|
||||||
|
{
|
||||||
|
Container = con;
|
||||||
|
}
|
||||||
|
public T Resolve<T>() where T : class
|
||||||
|
{
|
||||||
|
return Container?.Resolve<T>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -77,11 +77,16 @@ namespace PlexRequests.UI.Helpers
|
||||||
|
|
||||||
public SickRageTvAdd SendToSickRage(SickRageSettings sickRageSettings, RequestedModel model, string qualityId)
|
public SickRageTvAdd SendToSickRage(SickRageSettings sickRageSettings, RequestedModel model, string qualityId)
|
||||||
{
|
{
|
||||||
|
Log.Info("Sending to SickRage {0}", model.Title);
|
||||||
if (!sickRageSettings.Qualities.Any(x => x.Key == qualityId))
|
if (!sickRageSettings.Qualities.Any(x => x.Key == qualityId))
|
||||||
{
|
{
|
||||||
qualityId = sickRageSettings.QualityProfile;
|
qualityId = sickRageSettings.QualityProfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.Trace("Calling `AddSeries` with the following settings:");
|
||||||
|
Log.Trace(sickRageSettings.DumpJson());
|
||||||
|
Log.Trace("And the following `model`:");
|
||||||
|
Log.Trace(model.DumpJson());
|
||||||
var apiResult = SickrageApi.AddSeries(model.ProviderId, model.SeasonCount, model.SeasonList, qualityId,
|
var apiResult = SickrageApi.AddSeries(model.ProviderId, model.SeasonCount, model.SeasonList, qualityId,
|
||||||
sickRageSettings.ApiKey, sickRageSettings.FullUri);
|
sickRageSettings.ApiKey, sickRageSettings.FullUri);
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,10 @@
|
||||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
// ************************************************************************/
|
// ************************************************************************/
|
||||||
#endregion
|
#endregion
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
using Nancy.Validation;
|
using Nancy.Validation;
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,5 +57,31 @@ namespace PlexRequests.UI.Helpers
|
||||||
})
|
})
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static JsonResponseModel SendSonarrError(List<string> result)
|
||||||
|
{
|
||||||
|
var model = new JsonResponseModel {Result = false};
|
||||||
|
if (!result.Any())
|
||||||
|
{
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
sb.AppendLine("Errors from Sonarr: ");
|
||||||
|
for (var i = 0; i < result.Count; i++)
|
||||||
|
{
|
||||||
|
if (i != result.Count - 1)
|
||||||
|
{
|
||||||
|
sb.AppendLine(result[i] + ",");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.AppendLine(result[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
model.Message = sb.ToString();
|
||||||
|
|
||||||
|
return model;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
41
PlexRequests.UI/Jobs/MediaCacheRegistry.cs
Normal file
41
PlexRequests.UI/Jobs/MediaCacheRegistry.cs
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: PlexRegistry.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 FluentScheduler;
|
||||||
|
|
||||||
|
using PlexRequests.Services;
|
||||||
|
|
||||||
|
namespace PlexRequests.UI.Jobs
|
||||||
|
{
|
||||||
|
public class MediaCacheRegistry : Registry
|
||||||
|
{
|
||||||
|
public MediaCacheRegistry()
|
||||||
|
{
|
||||||
|
Schedule<MediaCacheService>().ToRunNow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,5 +30,7 @@ namespace PlexRequests.UI.Models
|
||||||
{
|
{
|
||||||
public bool Result { get; set; }
|
public bool Result { get; set; }
|
||||||
public string Message { get; set; }
|
public string Message { get; set; }
|
||||||
|
public string BaseUrl { get; set; }
|
||||||
|
public bool HasBase => !string.IsNullOrEmpty(BaseUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
35
PlexRequests.UI/Models/MovieSearchType.cs
Normal file
35
PlexRequests.UI/Models/MovieSearchType.cs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: PlexType.cs
|
||||||
|
// Created By: Jamie Rees
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
// a copy of this software and associated documentation files (the
|
||||||
|
// "Software"), to deal in the Software without restriction, including
|
||||||
|
// without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
// permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
// the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be
|
||||||
|
// included in all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
// ************************************************************************/
|
||||||
|
#endregion
|
||||||
|
namespace PlexRequests.UI.Models
|
||||||
|
{
|
||||||
|
public enum MovieSearchType
|
||||||
|
{
|
||||||
|
Upcoming,
|
||||||
|
CurrentlyPlaying,
|
||||||
|
Search
|
||||||
|
}
|
||||||
|
}
|
50
PlexRequests.UI/Models/SearchMovieViewModel.cs
Normal file
50
PlexRequests.UI/Models/SearchMovieViewModel.cs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: SearchTvShowViewModel.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;
|
||||||
|
|
||||||
|
namespace PlexRequests.UI.Models
|
||||||
|
{
|
||||||
|
public class SearchMovieViewModel : SearchViewModel
|
||||||
|
{
|
||||||
|
public bool Adult { get; set; }
|
||||||
|
public string BackdropPath { get; set; }
|
||||||
|
public List<int> GenreIds { get; set; }
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string OriginalLanguage { get; set; }
|
||||||
|
public string OriginalTitle { get; set; }
|
||||||
|
public string Overview { get; set; }
|
||||||
|
public double Popularity { get; set; }
|
||||||
|
public string PosterPath { get; set; }
|
||||||
|
public DateTime? ReleaseDate { get; set; }
|
||||||
|
public string Title { get; set; }
|
||||||
|
public bool Video { get; set; }
|
||||||
|
public double VoteAverage { get; set; }
|
||||||
|
public int VoteCount { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,7 +26,7 @@
|
||||||
#endregion
|
#endregion
|
||||||
namespace PlexRequests.UI.Models
|
namespace PlexRequests.UI.Models
|
||||||
{
|
{
|
||||||
public class SearchMusicViewModel
|
public class SearchMusicViewModel : SearchViewModel
|
||||||
{
|
{
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
public string Overview { get; set; }
|
public string Overview { get; set; }
|
||||||
|
|
|
@ -29,7 +29,7 @@ using System.Collections.Generic;
|
||||||
|
|
||||||
namespace PlexRequests.UI.Models
|
namespace PlexRequests.UI.Models
|
||||||
{
|
{
|
||||||
public class SearchTvShowViewModel
|
public class SearchTvShowViewModel : SearchViewModel
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
public string SeriesName { get; set; }
|
public string SeriesName { get; set; }
|
||||||
|
|
37
PlexRequests.UI/Models/SearchViewModel.cs
Normal file
37
PlexRequests.UI/Models/SearchViewModel.cs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: SearchTvShowViewModel.cs
|
||||||
|
// Created By: Jamie Rees
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
// a copy of this software and associated documentation files (the
|
||||||
|
// "Software"), to deal in the Software without restriction, including
|
||||||
|
// without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
// permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
// the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be
|
||||||
|
// included in all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
// ************************************************************************/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
namespace PlexRequests.UI.Models
|
||||||
|
{
|
||||||
|
public class SearchViewModel
|
||||||
|
{
|
||||||
|
public bool Approved { get; set; }
|
||||||
|
public bool Requested { get; set; }
|
||||||
|
public bool Available { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -56,7 +56,7 @@ using Nancy.Security;
|
||||||
|
|
||||||
namespace PlexRequests.UI.Modules
|
namespace PlexRequests.UI.Modules
|
||||||
{
|
{
|
||||||
public class AdminModule : NancyModule
|
public class AdminModule : BaseModule
|
||||||
{
|
{
|
||||||
private ISettingsService<PlexRequestSettings> PrService { get; }
|
private ISettingsService<PlexRequestSettings> PrService { get; }
|
||||||
private ISettingsService<CouchPotatoSettings> CpService { get; }
|
private ISettingsService<CouchPotatoSettings> CpService { get; }
|
||||||
|
@ -181,8 +181,16 @@ namespace PlexRequests.UI.Modules
|
||||||
var result = AuthService.SaveSettings(model);
|
var result = AuthService.SaveSettings(model);
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
|
if (!string.IsNullOrEmpty(BaseUrl))
|
||||||
|
{
|
||||||
|
return Context.GetRedirect($"~/{BaseUrl}/admin/authentication");
|
||||||
|
}
|
||||||
return Context.GetRedirect("~/admin/authentication");
|
return Context.GetRedirect("~/admin/authentication");
|
||||||
}
|
}
|
||||||
|
if (!string.IsNullOrEmpty(BaseUrl))
|
||||||
|
{
|
||||||
|
return Context.GetRedirect($"~/{BaseUrl}/error"); //TODO create error page
|
||||||
|
}
|
||||||
return Context.GetRedirect("~/error"); //TODO create error page
|
return Context.GetRedirect("~/error"); //TODO create error page
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,8 +209,7 @@ namespace PlexRequests.UI.Modules
|
||||||
|
|
||||||
PrService.SaveSettings(model);
|
PrService.SaveSettings(model);
|
||||||
|
|
||||||
|
return Context.GetRedirect(!string.IsNullOrEmpty(BaseUrl) ? $"~/{BaseUrl}/admin" : "~/admin");
|
||||||
return Context.GetRedirect("~/admin");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response RequestAuthToken()
|
private Response RequestAuthToken()
|
||||||
|
@ -588,6 +595,11 @@ namespace PlexRequests.UI.Modules
|
||||||
private Response GetCpProfiles()
|
private Response GetCpProfiles()
|
||||||
{
|
{
|
||||||
var settings = this.Bind<CouchPotatoSettings>();
|
var settings = this.Bind<CouchPotatoSettings>();
|
||||||
|
var valid = this.Validate(settings);
|
||||||
|
if (!valid.IsValid)
|
||||||
|
{
|
||||||
|
return Response.AsJson(valid.SendJsonError());
|
||||||
|
}
|
||||||
var profiles = CpApi.GetProfiles(settings.FullUri, settings.ApiKey);
|
var profiles = CpApi.GetProfiles(settings.FullUri, settings.ApiKey);
|
||||||
|
|
||||||
// set the cache
|
// set the cache
|
||||||
|
|
|
@ -29,17 +29,18 @@ using System;
|
||||||
using Nancy;
|
using Nancy;
|
||||||
using Nancy.ModelBinding;
|
using Nancy.ModelBinding;
|
||||||
using Nancy.Security;
|
using Nancy.Security;
|
||||||
|
using Nancy.Validation;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
|
||||||
using PlexRequests.Api.Interfaces;
|
using PlexRequests.Api.Interfaces;
|
||||||
using PlexRequests.Core;
|
using PlexRequests.Core;
|
||||||
using PlexRequests.Core.SettingModels;
|
using PlexRequests.Core.SettingModels;
|
||||||
|
using PlexRequests.UI.Helpers;
|
||||||
using PlexRequests.UI.Models;
|
using PlexRequests.UI.Models;
|
||||||
|
|
||||||
namespace PlexRequests.UI.Modules
|
namespace PlexRequests.UI.Modules
|
||||||
{
|
{
|
||||||
public class ApplicationTesterModule : BaseModule
|
public class ApplicationTesterModule : BaseAuthModule
|
||||||
{
|
{
|
||||||
|
|
||||||
public ApplicationTesterModule(ICouchPotatoApi cpApi, ISonarrApi sonarrApi, IPlexApi plexApi,
|
public ApplicationTesterModule(ICouchPotatoApi cpApi, ISonarrApi sonarrApi, IPlexApi plexApi,
|
||||||
|
@ -73,6 +74,11 @@ namespace PlexRequests.UI.Modules
|
||||||
private Response CouchPotatoTest()
|
private Response CouchPotatoTest()
|
||||||
{
|
{
|
||||||
var couchPotatoSettings = this.Bind<CouchPotatoSettings>();
|
var couchPotatoSettings = this.Bind<CouchPotatoSettings>();
|
||||||
|
var valid = this.Validate(couchPotatoSettings);
|
||||||
|
if (!valid.IsValid)
|
||||||
|
{
|
||||||
|
return Response.AsJson(valid.SendJsonError());
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var status = CpApi.GetStatus(couchPotatoSettings.FullUri, couchPotatoSettings.ApiKey);
|
var status = CpApi.GetStatus(couchPotatoSettings.FullUri, couchPotatoSettings.ApiKey);
|
||||||
|
@ -97,10 +103,15 @@ namespace PlexRequests.UI.Modules
|
||||||
private Response SonarrTest()
|
private Response SonarrTest()
|
||||||
{
|
{
|
||||||
var sonarrSettings = this.Bind<SonarrSettings>();
|
var sonarrSettings = this.Bind<SonarrSettings>();
|
||||||
|
var valid = this.Validate(sonarrSettings);
|
||||||
|
if (!valid.IsValid)
|
||||||
|
{
|
||||||
|
return Response.AsJson(valid.SendJsonError());
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var status = SonarrApi.SystemStatus(sonarrSettings.ApiKey, sonarrSettings.FullUri);
|
var status = SonarrApi.SystemStatus(sonarrSettings.ApiKey, sonarrSettings.FullUri);
|
||||||
return status != null
|
return status?.version != null
|
||||||
? Response.AsJson(new JsonResponseModel { Result = true, Message = "Connected to Sonarr successfully!" })
|
? Response.AsJson(new JsonResponseModel { Result = true, Message = "Connected to Sonarr successfully!" })
|
||||||
: Response.AsJson(new JsonResponseModel { Result = false, Message = "Could not connect to Sonarr, please check your settings." });
|
: Response.AsJson(new JsonResponseModel { Result = false, Message = "Could not connect to Sonarr, please check your settings." });
|
||||||
|
|
||||||
|
@ -121,6 +132,11 @@ namespace PlexRequests.UI.Modules
|
||||||
private Response PlexTest()
|
private Response PlexTest()
|
||||||
{
|
{
|
||||||
var plexSettings = this.Bind<PlexSettings>();
|
var plexSettings = this.Bind<PlexSettings>();
|
||||||
|
var valid = this.Validate(plexSettings);
|
||||||
|
if (!valid.IsValid)
|
||||||
|
{
|
||||||
|
return Response.AsJson(valid.SendJsonError());
|
||||||
|
}
|
||||||
var settings = AuthSettings.GetSettings();
|
var settings = AuthSettings.GetSettings();
|
||||||
if (settings?.PlexAuthToken == null)
|
if (settings?.PlexAuthToken == null)
|
||||||
{
|
{
|
||||||
|
@ -150,7 +166,11 @@ namespace PlexRequests.UI.Modules
|
||||||
private Response SickRageTest()
|
private Response SickRageTest()
|
||||||
{
|
{
|
||||||
var sickRageSettings = this.Bind<SickRageSettings>();
|
var sickRageSettings = this.Bind<SickRageSettings>();
|
||||||
|
var valid = this.Validate(sickRageSettings);
|
||||||
|
if (!valid.IsValid)
|
||||||
|
{
|
||||||
|
return Response.AsJson(valid.SendJsonError());
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var status = SickRageApi.Ping(sickRageSettings.ApiKey, sickRageSettings.FullUri);
|
var status = SickRageApi.Ping(sickRageSettings.ApiKey, sickRageSettings.FullUri);
|
||||||
|
@ -175,6 +195,11 @@ namespace PlexRequests.UI.Modules
|
||||||
private Response HeadphonesTest()
|
private Response HeadphonesTest()
|
||||||
{
|
{
|
||||||
var settings = this.Bind<HeadphonesSettings>();
|
var settings = this.Bind<HeadphonesSettings>();
|
||||||
|
var valid = this.Validate(settings);
|
||||||
|
if (!valid.IsValid)
|
||||||
|
{
|
||||||
|
return Response.AsJson(valid.SendJsonError());
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var result = HeadphonesApi.GetVersion(settings.ApiKey, settings.FullUri);
|
var result = HeadphonesApi.GetVersion(settings.ApiKey, settings.FullUri);
|
||||||
|
|
|
@ -43,7 +43,7 @@ using PlexRequests.UI.Models;
|
||||||
|
|
||||||
namespace PlexRequests.UI.Modules
|
namespace PlexRequests.UI.Modules
|
||||||
{
|
{
|
||||||
public class ApprovalModule : BaseModule
|
public class ApprovalModule : BaseAuthModule
|
||||||
{
|
{
|
||||||
|
|
||||||
public ApprovalModule(IRequestService service, ISettingsService<CouchPotatoSettings> cpService, ICouchPotatoApi cpApi, ISonarrApi sonarrApi,
|
public ApprovalModule(IRequestService service, ISettingsService<CouchPotatoSettings> cpService, ICouchPotatoApi cpApi, ISonarrApi sonarrApi,
|
||||||
|
@ -135,14 +135,16 @@ namespace PlexRequests.UI.Modules
|
||||||
{
|
{
|
||||||
return Response.AsJson(new JsonResponseModel {Result = true});
|
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
|
||||||
return Response.AsJson(new JsonResponseModel
|
|
||||||
{
|
{
|
||||||
Result = false,
|
Result = false,
|
||||||
Message = result.ErrorMessage ?? "Could not add the series to Sonarr"
|
Message = "Updated Sonarr but could not approve it in PlexRequests :("
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
return Response.AsJson(ValidationHelper.SendSonarrError(result.ErrorMessages));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
var srSettings = SickRageSettings.GetSettings();
|
var srSettings = SickRageSettings.GetSettings();
|
||||||
if (srSettings.Enabled)
|
if (srSettings.Enabled)
|
||||||
|
@ -384,7 +386,7 @@ namespace PlexRequests.UI.Modules
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log.Error("Could not approve and send the TV {0} to Sonarr!", r.Title);
|
Log.Error("Could not approve and send the TV {0} to Sonarr!", r.Title);
|
||||||
Log.Error("Error message: {0}", res?.ErrorMessage);
|
res?.ErrorMessages.ForEach(x => Log.Error("Error messages: {0}", x));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
91
PlexRequests.UI/Modules/BaseAuthModule.cs
Normal file
91
PlexRequests.UI/Modules/BaseAuthModule.cs
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: BaseAuthModule.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 Nancy.Extensions;
|
||||||
|
using PlexRequests.UI.Models;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using PlexRequests.Core;
|
||||||
|
using PlexRequests.Core.SettingModels;
|
||||||
|
|
||||||
|
namespace PlexRequests.UI.Modules
|
||||||
|
{
|
||||||
|
public class BaseAuthModule : BaseModule
|
||||||
|
{
|
||||||
|
private string _username;
|
||||||
|
private int _dateTimeOffset = -1;
|
||||||
|
|
||||||
|
protected string Username
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(_username))
|
||||||
|
{
|
||||||
|
_username = Session[SessionKeys.UsernameKey].ToString();
|
||||||
|
}
|
||||||
|
return _username;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int DateTimeOffset
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_dateTimeOffset == -1)
|
||||||
|
{
|
||||||
|
_dateTimeOffset = (int?)Session[SessionKeys.ClientDateTimeOffsetKey] ?? new DateTimeOffset().Offset.Minutes;
|
||||||
|
}
|
||||||
|
return _dateTimeOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseAuthModule()
|
||||||
|
{
|
||||||
|
Before += (ctx) => CheckAuth();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseAuthModule(string modulePath) : base(modulePath)
|
||||||
|
{
|
||||||
|
Before += (ctx) => CheckAuth();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Response CheckAuth()
|
||||||
|
{
|
||||||
|
var settings = Locator.Resolve<ISettingsService<PlexRequestSettings>>().GetSettings();
|
||||||
|
var baseUrl = settings.BaseUrl;
|
||||||
|
|
||||||
|
var redirectPath = string.IsNullOrEmpty(baseUrl) ? "~/userlogin" : $"~/{baseUrl}/userlogin";
|
||||||
|
|
||||||
|
return Session[SessionKeys.UsernameKey] == null
|
||||||
|
? Context.GetRedirect(redirectPath)
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,63 +24,38 @@
|
||||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
// ************************************************************************/
|
// ************************************************************************/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using Nancy;
|
using Nancy;
|
||||||
using Nancy.Extensions;
|
|
||||||
using PlexRequests.UI.Models;
|
using PlexRequests.Core;
|
||||||
using System;
|
using PlexRequests.Core.SettingModels;
|
||||||
|
using PlexRequests.UI.Helpers;
|
||||||
|
|
||||||
namespace PlexRequests.UI.Modules
|
namespace PlexRequests.UI.Modules
|
||||||
{
|
{
|
||||||
public class BaseModule : NancyModule
|
public class BaseModule : NancyModule
|
||||||
{
|
{
|
||||||
private string _username;
|
protected ServiceLocator Locator => ServiceLocator.Instance;
|
||||||
private int _dateTimeOffset = -1;
|
protected string BaseUrl { get; set; }
|
||||||
|
|
||||||
protected string Username
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(_username))
|
|
||||||
{
|
|
||||||
_username = Session[SessionKeys.UsernameKey].ToString();
|
|
||||||
}
|
|
||||||
return _username;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected int DateTimeOffset
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_dateTimeOffset == -1)
|
|
||||||
{
|
|
||||||
_dateTimeOffset = Session[SessionKeys.ClientDateTimeOffsetKey] != null ?
|
|
||||||
(int)Session[SessionKeys.ClientDateTimeOffsetKey] : (new DateTimeOffset().Offset).Minutes;
|
|
||||||
}
|
|
||||||
return _dateTimeOffset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public BaseModule()
|
public BaseModule()
|
||||||
{
|
{
|
||||||
Before += (ctx) => CheckAuth();
|
var settings = Locator.Resolve<ISettingsService<PlexRequestSettings>>().GetSettings();
|
||||||
|
var baseUrl = settings.BaseUrl;
|
||||||
|
BaseUrl = baseUrl;
|
||||||
|
|
||||||
|
var modulePath = string.IsNullOrEmpty(baseUrl) ? string.Empty : baseUrl;
|
||||||
|
|
||||||
|
ModulePath = modulePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BaseModule(string modulePath) : base(modulePath)
|
public BaseModule(string modulePath)
|
||||||
{
|
{
|
||||||
Before += (ctx) => CheckAuth();
|
var settings = Locator.Resolve<ISettingsService<PlexRequestSettings>>().GetSettings();
|
||||||
}
|
var baseUrl = settings.BaseUrl;
|
||||||
|
BaseUrl = baseUrl;
|
||||||
|
|
||||||
|
var settingModulePath = string.IsNullOrEmpty(baseUrl) ? modulePath : $"{baseUrl}/{modulePath}";
|
||||||
|
|
||||||
private Response CheckAuth()
|
ModulePath = settingModulePath;
|
||||||
{
|
}
|
||||||
if (Session[SessionKeys.UsernameKey] == null)
|
|
||||||
{
|
|
||||||
return Context.GetRedirect("~/userlogin");
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -29,12 +29,13 @@ using Nancy.Extensions;
|
||||||
|
|
||||||
namespace PlexRequests.UI.Modules
|
namespace PlexRequests.UI.Modules
|
||||||
{
|
{
|
||||||
public class IndexModule : BaseModule
|
public class IndexModule : BaseAuthModule
|
||||||
{
|
{
|
||||||
public IndexModule()
|
public IndexModule()
|
||||||
{
|
{
|
||||||
Get["/"] = parameters => Context.GetRedirect("~/search");
|
Get["/"] = parameters => Context.GetRedirect(!string.IsNullOrEmpty(BaseUrl) ? $"~/{BaseUrl}/search" : "~/search");
|
||||||
Get["/Index"] = parameters => Context.GetRedirect("~/search");
|
|
||||||
|
Get["/Index"] = parameters => Context.GetRedirect(!string.IsNullOrEmpty(BaseUrl) ? $"~/{BaseUrl}/search" : "~/search");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -38,7 +38,7 @@ using PlexRequests.UI.Models;
|
||||||
|
|
||||||
namespace PlexRequests.UI.Modules
|
namespace PlexRequests.UI.Modules
|
||||||
{
|
{
|
||||||
public class LoginModule : NancyModule
|
public class LoginModule : BaseModule
|
||||||
{
|
{
|
||||||
public LoginModule()
|
public LoginModule()
|
||||||
{
|
{
|
||||||
|
@ -54,7 +54,7 @@ namespace PlexRequests.UI.Modules
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Get["/logout"] = x => this.LogoutAndRedirect("~/");
|
Get["/logout"] = x => this.LogoutAndRedirect(!string.IsNullOrEmpty(BaseUrl) ? $"~/{BaseUrl}/" : "~/");
|
||||||
|
|
||||||
Post["/login"] = x =>
|
Post["/login"] = x =>
|
||||||
{
|
{
|
||||||
|
@ -66,7 +66,7 @@ namespace PlexRequests.UI.Modules
|
||||||
|
|
||||||
if (userId == null)
|
if (userId == null)
|
||||||
{
|
{
|
||||||
return Context.GetRedirect("~/login?error=true&username=" + username);
|
return Context.GetRedirect(!string.IsNullOrEmpty(BaseUrl) ? $"~/{BaseUrl}/login?error=true&username=" + username : "~/login?error=true&username=" + username);
|
||||||
}
|
}
|
||||||
DateTime? expiry = null;
|
DateTime? expiry = null;
|
||||||
if (Request.Form.RememberMe.HasValue)
|
if (Request.Form.RememberMe.HasValue)
|
||||||
|
@ -75,6 +75,11 @@ namespace PlexRequests.UI.Modules
|
||||||
}
|
}
|
||||||
Session[SessionKeys.UsernameKey] = username;
|
Session[SessionKeys.UsernameKey] = username;
|
||||||
Session[SessionKeys.ClientDateTimeOffsetKey] = dtOffset;
|
Session[SessionKeys.ClientDateTimeOffsetKey] = dtOffset;
|
||||||
|
if (!string.IsNullOrEmpty(BaseUrl))
|
||||||
|
{
|
||||||
|
|
||||||
|
return this.LoginAndRedirect(userId.Value, expiry, $"/{BaseUrl}");
|
||||||
|
}
|
||||||
return this.LoginAndRedirect(userId.Value, expiry);
|
return this.LoginAndRedirect(userId.Value, expiry);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -94,7 +99,7 @@ namespace PlexRequests.UI.Modules
|
||||||
var exists = UserMapper.DoUsersExist();
|
var exists = UserMapper.DoUsersExist();
|
||||||
if (exists)
|
if (exists)
|
||||||
{
|
{
|
||||||
return Context.GetRedirect("~/register?error=true");
|
return Context.GetRedirect(!string.IsNullOrEmpty(BaseUrl) ? $"~/{BaseUrl}/register?error=true" : "~/register?error=true");
|
||||||
}
|
}
|
||||||
var userId = UserMapper.CreateUser(username, Request.Form.Password, new[] { "Admin" });
|
var userId = UserMapper.CreateUser(username, Request.Form.Password, new[] { "Admin" });
|
||||||
Session[SessionKeys.UsernameKey] = username;
|
Session[SessionKeys.UsernameKey] = username;
|
||||||
|
|
|
@ -46,7 +46,7 @@ using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace PlexRequests.UI.Modules
|
namespace PlexRequests.UI.Modules
|
||||||
{
|
{
|
||||||
public class RequestsModule : BaseModule
|
public class RequestsModule : BaseAuthModule
|
||||||
{
|
{
|
||||||
public RequestsModule(
|
public RequestsModule(
|
||||||
IRequestService service,
|
IRequestService service,
|
||||||
|
|
|
@ -48,23 +48,35 @@ using PlexRequests.Services.Notification;
|
||||||
using PlexRequests.Store;
|
using PlexRequests.Store;
|
||||||
using PlexRequests.UI.Helpers;
|
using PlexRequests.UI.Helpers;
|
||||||
using PlexRequests.UI.Models;
|
using PlexRequests.UI.Models;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using TMDbLib.Objects.Search;
|
||||||
|
using PlexRequests.Api.Models.Tv;
|
||||||
|
using TMDbLib.Objects.General;
|
||||||
|
|
||||||
namespace PlexRequests.UI.Modules
|
namespace PlexRequests.UI.Modules
|
||||||
{
|
{
|
||||||
public class SearchModule : BaseModule
|
public class SearchModule : BaseAuthModule
|
||||||
{
|
{
|
||||||
public SearchModule(ICacheProvider cache, ISettingsService<CouchPotatoSettings> cpSettings,
|
public SearchModule(ICacheProvider cache, ISettingsService<CouchPotatoSettings> cpSettings,
|
||||||
ISettingsService<PlexRequestSettings> prSettings, IAvailabilityChecker checker,
|
ISettingsService<PlexRequestSettings> prSettings, IAvailabilityChecker checker,
|
||||||
IRequestService request, ISonarrApi sonarrApi, ISettingsService<SonarrSettings> sonarrSettings,
|
IRequestService request, ISonarrApi sonarrApi, ISettingsService<SonarrSettings> sonarrSettings,
|
||||||
ISettingsService<SickRageSettings> sickRageService, ICouchPotatoApi cpApi, ISickRageApi srApi,
|
ISettingsService<SickRageSettings> sickRageService, ICouchPotatoApi cpApi, ISickRageApi srApi,
|
||||||
INotificationService notify, IMusicBrainzApi mbApi, IHeadphonesApi hpApi, ISettingsService<HeadphonesSettings> hpService) : base("search")
|
INotificationService notify, IMusicBrainzApi mbApi, IHeadphonesApi hpApi, ISettingsService<HeadphonesSettings> hpService,
|
||||||
|
ICouchPotatoCacher cpCacher, ISonarrCacher sonarrCacher, ISickRageCacher sickRageCacher, IPlexApi plexApi,
|
||||||
|
ISettingsService<PlexSettings> plexService, ISettingsService<AuthenticationSettings> auth) : base("search")
|
||||||
{
|
{
|
||||||
|
Auth = auth;
|
||||||
|
PlexService = plexService;
|
||||||
|
PlexApi = plexApi;
|
||||||
CpService = cpSettings;
|
CpService = cpSettings;
|
||||||
PrService = prSettings;
|
PrService = prSettings;
|
||||||
MovieApi = new TheMovieDbApi();
|
MovieApi = new TheMovieDbApi();
|
||||||
TvApi = new TheTvDbApi();
|
TvApi = new TheTvDbApi();
|
||||||
Cache = cache;
|
Cache = cache;
|
||||||
Checker = checker;
|
Checker = checker;
|
||||||
|
CpCacher = cpCacher;
|
||||||
|
SonarrCacher = sonarrCacher;
|
||||||
|
SickRageCacher = sickRageCacher;
|
||||||
RequestService = request;
|
RequestService = request;
|
||||||
SonarrApi = sonarrApi;
|
SonarrApi = sonarrApi;
|
||||||
SonarrService = sonarrSettings;
|
SonarrService = sonarrSettings;
|
||||||
|
@ -91,6 +103,7 @@ namespace PlexRequests.UI.Modules
|
||||||
Post["request/tv"] = parameters => RequestTvShow((int)Request.Form.tvId, (string)Request.Form.seasons);
|
Post["request/tv"] = parameters => RequestTvShow((int)Request.Form.tvId, (string)Request.Form.seasons);
|
||||||
Post["request/album"] = parameters => RequestAlbum((string)Request.Form.albumId);
|
Post["request/album"] = parameters => RequestAlbum((string)Request.Form.albumId);
|
||||||
}
|
}
|
||||||
|
private IPlexApi PlexApi { get; }
|
||||||
private TheMovieDbApi MovieApi { get; }
|
private TheMovieDbApi MovieApi { get; }
|
||||||
private INotificationService NotificationService { get; }
|
private INotificationService NotificationService { get; }
|
||||||
private ICouchPotatoApi CouchPotatoApi { get; }
|
private ICouchPotatoApi CouchPotatoApi { get; }
|
||||||
|
@ -99,17 +112,23 @@ namespace PlexRequests.UI.Modules
|
||||||
private ISickRageApi SickrageApi { get; }
|
private ISickRageApi SickrageApi { get; }
|
||||||
private IRequestService RequestService { get; }
|
private IRequestService RequestService { get; }
|
||||||
private ICacheProvider Cache { get; }
|
private ICacheProvider Cache { get; }
|
||||||
|
private ISettingsService<AuthenticationSettings> Auth { get; }
|
||||||
|
private ISettingsService<PlexSettings> PlexService { get; }
|
||||||
private ISettingsService<CouchPotatoSettings> CpService { get; }
|
private ISettingsService<CouchPotatoSettings> CpService { get; }
|
||||||
private ISettingsService<PlexRequestSettings> PrService { get; }
|
private ISettingsService<PlexRequestSettings> PrService { get; }
|
||||||
private ISettingsService<SonarrSettings> SonarrService { get; }
|
private ISettingsService<SonarrSettings> SonarrService { get; }
|
||||||
private ISettingsService<SickRageSettings> SickRageService { get; }
|
private ISettingsService<SickRageSettings> SickRageService { get; }
|
||||||
private ISettingsService<HeadphonesSettings> HeadphonesService { get; }
|
private ISettingsService<HeadphonesSettings> HeadphonesService { get; }
|
||||||
private IAvailabilityChecker Checker { get; }
|
private IAvailabilityChecker Checker { get; }
|
||||||
|
private ICouchPotatoCacher CpCacher { get; }
|
||||||
|
private ISonarrCacher SonarrCacher { get; }
|
||||||
|
private ISickRageCacher SickRageCacher { get; }
|
||||||
private IMusicBrainzApi MusicBrainzApi { get; }
|
private IMusicBrainzApi MusicBrainzApi { get; }
|
||||||
private IHeadphonesApi HeadphonesApi { get; }
|
private IHeadphonesApi HeadphonesApi { get; }
|
||||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
private bool IsAdmin {
|
private bool IsAdmin
|
||||||
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Context.CurrentUser.IsAuthenticated();
|
return Context.CurrentUser.IsAuthenticated();
|
||||||
|
@ -124,29 +143,165 @@ namespace PlexRequests.UI.Modules
|
||||||
return View["Search/Index", settings];
|
return View["Search/Index", settings];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Response UpcomingMovies()
|
||||||
|
{
|
||||||
|
Log.Trace("Loading upcoming movies");
|
||||||
|
return ProcessMovies(MovieSearchType.Upcoming, string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Response CurrentlyPlayingMovies()
|
||||||
|
{
|
||||||
|
Log.Trace("Loading currently playing movies");
|
||||||
|
return ProcessMovies(MovieSearchType.CurrentlyPlaying, string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
private Response SearchMovie(string searchTerm)
|
private Response SearchMovie(string searchTerm)
|
||||||
{
|
{
|
||||||
Log.Trace("Searching for Movie {0}", searchTerm);
|
Log.Trace("Searching for Movie {0}", searchTerm);
|
||||||
var movies = MovieApi.SearchMovie(searchTerm);
|
return ProcessMovies(MovieSearchType.Search, searchTerm);
|
||||||
var result = movies.Result;
|
}
|
||||||
return Response.AsJson(result);
|
|
||||||
|
private Response ProcessMovies(MovieSearchType searchType, string searchTerm)
|
||||||
|
{
|
||||||
|
List<Task> taskList = new List<Task>();
|
||||||
|
var cpSettings = CpService.GetSettings();
|
||||||
|
|
||||||
|
List<MovieResult> apiMovies = new List<MovieResult>();
|
||||||
|
taskList.Add(Task.Factory.StartNew<List<MovieResult>>(() =>
|
||||||
|
{
|
||||||
|
switch(searchType)
|
||||||
|
{
|
||||||
|
case MovieSearchType.Search:
|
||||||
|
return MovieApi.SearchMovie(searchTerm).Result.Select(x => new MovieResult()
|
||||||
|
{
|
||||||
|
Adult = x.Adult,
|
||||||
|
BackdropPath = x.BackdropPath,
|
||||||
|
GenreIds = x.GenreIds,
|
||||||
|
Id = x.Id,
|
||||||
|
OriginalLanguage = x.OriginalLanguage,
|
||||||
|
OriginalTitle = x.OriginalTitle,
|
||||||
|
Overview = x.Overview,
|
||||||
|
Popularity = x.Popularity,
|
||||||
|
PosterPath = x.PosterPath,
|
||||||
|
ReleaseDate = x.ReleaseDate,
|
||||||
|
Title = x.Title,
|
||||||
|
Video = x.Video,
|
||||||
|
VoteAverage = x.VoteAverage,
|
||||||
|
VoteCount = x.VoteCount
|
||||||
|
}).ToList();
|
||||||
|
case MovieSearchType.CurrentlyPlaying:
|
||||||
|
return MovieApi.GetCurrentPlayingMovies().Result.ToList();
|
||||||
|
case MovieSearchType.Upcoming:
|
||||||
|
return MovieApi.GetUpcomingMovies().Result.ToList();
|
||||||
|
default:
|
||||||
|
return new List<MovieResult>();
|
||||||
|
}
|
||||||
|
}).ContinueWith((t) =>
|
||||||
|
{
|
||||||
|
apiMovies = t.Result;
|
||||||
|
}));
|
||||||
|
|
||||||
|
Dictionary<int, RequestedModel> dbMovies = new Dictionary<int, RequestedModel>();
|
||||||
|
taskList.Add(Task.Factory.StartNew(() =>
|
||||||
|
{
|
||||||
|
return RequestService.GetAll().Where(x => x.Type == RequestType.Movie);
|
||||||
|
|
||||||
|
}).ContinueWith((t) =>
|
||||||
|
{
|
||||||
|
dbMovies = t.Result.ToDictionary(x => x.ProviderId);
|
||||||
|
}));
|
||||||
|
|
||||||
|
Task.WaitAll(taskList.ToArray());
|
||||||
|
|
||||||
|
int[] cpCached = CpCacher.QueuedIds();
|
||||||
|
var plexMovies = Checker.GetPlexMovies();
|
||||||
|
|
||||||
|
List<SearchMovieViewModel> viewMovies = new List<SearchMovieViewModel>();
|
||||||
|
foreach (MovieResult movie in apiMovies)
|
||||||
|
{
|
||||||
|
var viewMovie = new SearchMovieViewModel()
|
||||||
|
{
|
||||||
|
Adult = movie.Adult,
|
||||||
|
BackdropPath = movie.BackdropPath,
|
||||||
|
GenreIds = movie.GenreIds,
|
||||||
|
Id = movie.Id,
|
||||||
|
OriginalLanguage = movie.OriginalLanguage,
|
||||||
|
OriginalTitle = movie.OriginalTitle,
|
||||||
|
Overview = movie.Overview,
|
||||||
|
Popularity = movie.Popularity,
|
||||||
|
PosterPath = movie.PosterPath,
|
||||||
|
ReleaseDate = movie.ReleaseDate,
|
||||||
|
Title = movie.Title,
|
||||||
|
Video = movie.Video,
|
||||||
|
VoteAverage = movie.VoteAverage,
|
||||||
|
VoteCount = movie.VoteCount
|
||||||
|
};
|
||||||
|
|
||||||
|
if (Checker.IsMovieAvailable(plexMovies.ToArray(), movie.Title, movie.ReleaseDate?.Year.ToString()))
|
||||||
|
{
|
||||||
|
viewMovie.Available = true;
|
||||||
|
}
|
||||||
|
else if (dbMovies.ContainsKey(movie.Id)) // compare to the requests db
|
||||||
|
{
|
||||||
|
var dbm = dbMovies[movie.Id];
|
||||||
|
|
||||||
|
viewMovie.Requested = true;
|
||||||
|
viewMovie.Approved = dbm.Approved;
|
||||||
|
viewMovie.Available = dbm.Available;
|
||||||
|
}
|
||||||
|
else if (cpCached.Contains(movie.Id)) // compare to the couchpotato db
|
||||||
|
{
|
||||||
|
viewMovie.Requested = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
viewMovies.Add(viewMovie);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response.AsJson(viewMovies);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response SearchTvShow(string searchTerm)
|
private Response SearchTvShow(string searchTerm)
|
||||||
{
|
{
|
||||||
Log.Trace("Searching for TV Show {0}", searchTerm);
|
Log.Trace("Searching for TV Show {0}", searchTerm);
|
||||||
//var tvShow = TvApi.SearchTv(searchTerm, AuthToken);
|
|
||||||
var tvShow = new TvMazeApi().Search(searchTerm);
|
List<Task> taskList = new List<Task>();
|
||||||
if (!tvShow.Any())
|
|
||||||
|
List<TvMazeSearch> apiTv = new List<TvMazeSearch>();
|
||||||
|
taskList.Add(Task.Factory.StartNew(() =>
|
||||||
|
{
|
||||||
|
return new TvMazeApi().Search(searchTerm);
|
||||||
|
|
||||||
|
}).ContinueWith((t) =>
|
||||||
|
{
|
||||||
|
apiTv = t.Result;
|
||||||
|
}));
|
||||||
|
|
||||||
|
Dictionary<int, RequestedModel> dbTv = new Dictionary<int, RequestedModel>();
|
||||||
|
taskList.Add(Task.Factory.StartNew(() =>
|
||||||
|
{
|
||||||
|
return RequestService.GetAll().Where(x => x.Type == RequestType.TvShow);
|
||||||
|
|
||||||
|
}).ContinueWith((t) =>
|
||||||
|
{
|
||||||
|
dbTv = t.Result.ToDictionary(x => x.ProviderId);
|
||||||
|
}));
|
||||||
|
|
||||||
|
Task.WaitAll(taskList.ToArray());
|
||||||
|
|
||||||
|
if (!apiTv.Any())
|
||||||
{
|
{
|
||||||
Log.Trace("TV Show data is null");
|
Log.Trace("TV Show data is null");
|
||||||
return Response.AsJson("");
|
return Response.AsJson("");
|
||||||
}
|
}
|
||||||
var model = new List<SearchTvShowViewModel>();
|
|
||||||
|
|
||||||
foreach (var t in tvShow)
|
int[] sonarrCached = SonarrCacher.QueuedIds();
|
||||||
|
int[] sickRageCache = SickRageCacher.QueuedIds(); // consider just merging sonarr/sickrage arrays
|
||||||
|
var plexTvShows = Checker.GetPlexTvShows();
|
||||||
|
|
||||||
|
var viewTv = new List<SearchTvShowViewModel>();
|
||||||
|
foreach (var t in apiTv)
|
||||||
{
|
{
|
||||||
model.Add(new SearchTvShowViewModel
|
var viewT = new SearchTvShowViewModel
|
||||||
{
|
{
|
||||||
// We are constructing the banner with the id:
|
// We are constructing the banner with the id:
|
||||||
// http://thetvdb.com/banners/_cache/posters/ID-1.jpg
|
// http://thetvdb.com/banners/_cache/posters/ID-1.jpg
|
||||||
|
@ -161,24 +316,71 @@ namespace PlexRequests.UI.Modules
|
||||||
Runtime = t.show.runtime.ToString(),
|
Runtime = t.show.runtime.ToString(),
|
||||||
SeriesId = t.show.id,
|
SeriesId = t.show.id,
|
||||||
SeriesName = t.show.name,
|
SeriesName = t.show.name,
|
||||||
|
Status = t.show.status
|
||||||
|
};
|
||||||
|
|
||||||
Status = t.show.status,
|
if (Checker.IsTvShowAvailable(plexTvShows.ToArray(), t.show.name, t.show.premiered?.Substring(0, 4)))
|
||||||
});
|
{
|
||||||
|
viewT.Available = true;
|
||||||
|
}
|
||||||
|
else if (t.show.externals.thetvdb != null)
|
||||||
|
{
|
||||||
|
int tvdbid = (int)t.show.externals.thetvdb;
|
||||||
|
|
||||||
|
if (dbTv.ContainsKey(tvdbid))
|
||||||
|
{
|
||||||
|
var dbt = dbTv[tvdbid];
|
||||||
|
|
||||||
|
viewT.Requested = true;
|
||||||
|
viewT.Approved = dbt.Approved;
|
||||||
|
viewT.Available = dbt.Available;
|
||||||
|
}
|
||||||
|
else if (sonarrCached.Contains(tvdbid) || sickRageCache.Contains(tvdbid)) // compare to the sonarr/sickrage db
|
||||||
|
{
|
||||||
|
viewT.Requested = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
viewTv.Add(viewT);
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.Trace("Returning TV Show results: ");
|
Log.Trace("Returning TV Show results: ");
|
||||||
Log.Trace(model.DumpJson());
|
Log.Trace(viewTv.DumpJson());
|
||||||
return Response.AsJson(model);
|
return Response.AsJson(viewTv);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response SearchMusic(string searchTerm)
|
private Response SearchMusic(string searchTerm)
|
||||||
{
|
{
|
||||||
var albums = MusicBrainzApi.SearchAlbum(searchTerm);
|
List<Task> taskList = new List<Task>();
|
||||||
var releases = albums.releases ?? new List<Release>();
|
|
||||||
var model = new List<SearchMusicViewModel>();
|
List<Release> apiAlbums = new List<Release>();
|
||||||
foreach (var a in releases)
|
taskList.Add(Task.Factory.StartNew(() =>
|
||||||
{
|
{
|
||||||
model.Add(new SearchMusicViewModel
|
return MusicBrainzApi.SearchAlbum(searchTerm);
|
||||||
|
|
||||||
|
}).ContinueWith((t) =>
|
||||||
|
{
|
||||||
|
apiAlbums = t.Result.releases ?? new List<Release>();
|
||||||
|
}));
|
||||||
|
|
||||||
|
Dictionary<string, RequestedModel> dbAlbum = new Dictionary<string, RequestedModel>();
|
||||||
|
taskList.Add(Task.Factory.StartNew(() =>
|
||||||
|
{
|
||||||
|
return RequestService.GetAll().Where(x => x.Type == RequestType.Album);
|
||||||
|
|
||||||
|
}).ContinueWith((t) =>
|
||||||
|
{
|
||||||
|
dbAlbum = t.Result.ToDictionary(x => x.MusicBrainzId);
|
||||||
|
}));
|
||||||
|
|
||||||
|
Task.WaitAll(taskList.ToArray());
|
||||||
|
|
||||||
|
var plexAlbums = Checker.GetPlexAlbums();
|
||||||
|
|
||||||
|
var viewAlbum = new List<SearchMusicViewModel>();
|
||||||
|
foreach (var a in apiAlbums)
|
||||||
|
{
|
||||||
|
var viewA = new SearchMusicViewModel
|
||||||
{
|
{
|
||||||
Title = a.title,
|
Title = a.title,
|
||||||
Id = a.id,
|
Id = a.id,
|
||||||
|
@ -188,27 +390,27 @@ namespace PlexRequests.UI.Modules
|
||||||
TrackCount = a.TrackCount,
|
TrackCount = a.TrackCount,
|
||||||
ReleaseType = a.status,
|
ReleaseType = a.status,
|
||||||
Country = a.country
|
Country = a.country
|
||||||
});
|
};
|
||||||
|
|
||||||
|
DateTime release;
|
||||||
|
DateTimeHelper.CustomParse(a.ReleaseEvents?.FirstOrDefault()?.date, out release);
|
||||||
|
var artist = a.ArtistCredit?.FirstOrDefault()?.artist;
|
||||||
|
if (Checker.IsAlbumAvailable(plexAlbums.ToArray(), a.title, release.ToString("yyyy"), artist.name))
|
||||||
|
{
|
||||||
|
viewA.Available = true;
|
||||||
}
|
}
|
||||||
return Response.AsJson(model);
|
if (!string.IsNullOrEmpty(a.id) && dbAlbum.ContainsKey(a.id))
|
||||||
|
{
|
||||||
|
var dba = dbAlbum[a.id];
|
||||||
|
|
||||||
|
viewA.Requested = true;
|
||||||
|
viewA.Approved = dba.Approved;
|
||||||
|
viewA.Available = dba.Available;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response UpcomingMovies() // TODO : Not used
|
viewAlbum.Add(viewA);
|
||||||
{
|
|
||||||
var movies = MovieApi.GetUpcomingMovies();
|
|
||||||
var result = movies.Result;
|
|
||||||
Log.Trace("Movie Upcoming Results: ");
|
|
||||||
Log.Trace(result.DumpJson());
|
|
||||||
return Response.AsJson(result);
|
|
||||||
}
|
}
|
||||||
|
return Response.AsJson(viewAlbum);
|
||||||
private Response CurrentlyPlayingMovies() // TODO : Not used
|
|
||||||
{
|
|
||||||
var movies = MovieApi.GetCurrentPlayingMovies();
|
|
||||||
var result = movies.Result;
|
|
||||||
Log.Trace("Movie Currently Playing Results: ");
|
|
||||||
Log.Trace(result.DumpJson());
|
|
||||||
return Response.AsJson(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response RequestMovie(int movieId)
|
private Response RequestMovie(int movieId)
|
||||||
|
@ -241,7 +443,8 @@ namespace PlexRequests.UI.Modules
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (CheckIfTitleExistsInPlex(movieInfo.Title, movieInfo.ReleaseDate?.Year.ToString(),null, PlexType.Movie))
|
var movies = Checker.GetPlexMovies();
|
||||||
|
if (Checker.IsMovieAvailable(movies.ToArray(), movieInfo.Title, movieInfo.ReleaseDate?.Year.ToString()))
|
||||||
{
|
{
|
||||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = $"{fullMovieName} is already in Plex!" });
|
return Response.AsJson(new JsonResponseModel { Result = false, Message = $"{fullMovieName} is already in Plex!" });
|
||||||
}
|
}
|
||||||
|
@ -377,7 +580,8 @@ namespace PlexRequests.UI.Modules
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (CheckIfTitleExistsInPlex(showInfo.name, showInfo.premiered?.Substring(0, 4), null, PlexType.TvShow)) // Take only the year Format = 2014-01-01
|
var shows = Checker.GetPlexTvShows();
|
||||||
|
if (Checker.IsTvShowAvailable(shows.ToArray(), showInfo.name, showInfo.premiered?.Substring(0, 4)))
|
||||||
{
|
{
|
||||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = $"{fullShowName} is already in Plex!" });
|
return Response.AsJson(new JsonResponseModel { Result = false, Message = $"{fullShowName} is already in Plex!" });
|
||||||
}
|
}
|
||||||
|
@ -442,7 +646,7 @@ namespace PlexRequests.UI.Modules
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = result?.ErrorMessage ?? "Something went wrong adding the movie to Sonarr! Please check your settings." });
|
return Response.AsJson(ValidationHelper.SendSonarrError(result?.ErrorMessages));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,12 +680,6 @@ namespace PlexRequests.UI.Modules
|
||||||
return Response.AsJson(new JsonResponseModel { Result = true, Message = $"{fullShowName} was successfully added!" });
|
return Response.AsJson(new JsonResponseModel { Result = true, Message = $"{fullShowName} was successfully added!" });
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CheckIfTitleExistsInPlex(string title, string year, string artist, PlexType type)
|
|
||||||
{
|
|
||||||
var result = Checker.IsAvailable(title, year, artist, type);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Response RequestAlbum(string releaseId)
|
private Response RequestAlbum(string releaseId)
|
||||||
{
|
{
|
||||||
var settings = PrService.GetSettings();
|
var settings = PrService.GetSettings();
|
||||||
|
@ -513,7 +711,8 @@ namespace PlexRequests.UI.Modules
|
||||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = "We could not find the artist on MusicBrainz. Please try again later or contact your admin" });
|
return Response.AsJson(new JsonResponseModel { Result = false, Message = "We could not find the artist on MusicBrainz. Please try again later or contact your admin" });
|
||||||
}
|
}
|
||||||
|
|
||||||
var alreadyInPlex = CheckIfTitleExistsInPlex(albumInfo.title, release.ToString("yyyy"), artist.name, PlexType.Music);
|
var albums = Checker.GetPlexAlbums();
|
||||||
|
var alreadyInPlex = Checker.IsAlbumAvailable(albums.ToArray(), albumInfo.title, release.ToString("yyyy"), artist.name);
|
||||||
|
|
||||||
if (alreadyInPlex)
|
if (alreadyInPlex)
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,7 +44,7 @@ using PlexRequests.UI.Models;
|
||||||
|
|
||||||
namespace PlexRequests.UI.Modules
|
namespace PlexRequests.UI.Modules
|
||||||
{
|
{
|
||||||
public class UserLoginModule : NancyModule
|
public class UserLoginModule : BaseModule
|
||||||
{
|
{
|
||||||
public UserLoginModule(ISettingsService<AuthenticationSettings> auth, IPlexApi api) : base("userlogin")
|
public UserLoginModule(ISettingsService<AuthenticationSettings> auth, IPlexApi api) : base("userlogin")
|
||||||
{
|
{
|
||||||
|
@ -142,7 +142,7 @@ namespace PlexRequests.UI.Modules
|
||||||
Session[SessionKeys.ClientDateTimeOffsetKey] = (int)dateTimeOffset;
|
Session[SessionKeys.ClientDateTimeOffsetKey] = (int)dateTimeOffset;
|
||||||
|
|
||||||
return Response.AsJson(authenticated
|
return Response.AsJson(authenticated
|
||||||
? new JsonResponseModel { Result = true }
|
? new JsonResponseModel { Result = true, BaseUrl = BaseUrl}
|
||||||
: new JsonResponseModel { Result = false, Message = "Incorrect User or Password"});
|
: new JsonResponseModel { Result = false, Message = "Incorrect User or Password"});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +155,9 @@ namespace PlexRequests.UI.Modules
|
||||||
{
|
{
|
||||||
Session.Delete(SessionKeys.UsernameKey);
|
Session.Delete(SessionKeys.UsernameKey);
|
||||||
}
|
}
|
||||||
return Context.GetRedirect("~/userlogin");
|
return Context.GetRedirect(!string.IsNullOrEmpty(BaseUrl)
|
||||||
|
? $"~/{BaseUrl}/userlogin"
|
||||||
|
: "~/userlogin");
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CheckIfUserIsOwner(string authToken, string userName)
|
private bool CheckIfUserIsOwner(string authToken, string userName)
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>PlexRequests.UI</RootNamespace>
|
<RootNamespace>PlexRequests.UI</RootNamespace>
|
||||||
<AssemblyName>PlexRequests</AssemblyName>
|
<AssemblyName>PlexRequests</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
|
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
|
||||||
<RestorePackages>true</RestorePackages>
|
<RestorePackages>true</RestorePackages>
|
||||||
|
@ -164,13 +164,21 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Bootstrapper.cs" />
|
<Compile Include="Bootstrapper.cs" />
|
||||||
|
<Compile Include="Helpers\BaseUrlHelper.cs" />
|
||||||
<Compile Include="Helpers\HeadphonesSender.cs" />
|
<Compile Include="Helpers\HeadphonesSender.cs" />
|
||||||
|
<Compile Include="Helpers\ServiceLocator.cs" />
|
||||||
<Compile Include="Helpers\StringHelper.cs" />
|
<Compile Include="Helpers\StringHelper.cs" />
|
||||||
<Compile Include="Helpers\TvSender.cs" />
|
<Compile Include="Helpers\TvSender.cs" />
|
||||||
<Compile Include="Helpers\ValidationHelper.cs" />
|
<Compile Include="Helpers\ValidationHelper.cs" />
|
||||||
|
<Compile Include="Jobs\MediaCacheRegistry.cs" />
|
||||||
<Compile Include="Models\DatatablesModel.cs" />
|
<Compile Include="Models\DatatablesModel.cs" />
|
||||||
|
<Compile Include="Models\MovieSearchType.cs" />
|
||||||
<Compile Include="Models\QualityModel.cs" />
|
<Compile Include="Models\QualityModel.cs" />
|
||||||
|
<Compile Include="Models\SearchViewModel.cs" />
|
||||||
<Compile Include="Models\SearchMusicViewModel.cs" />
|
<Compile Include="Models\SearchMusicViewModel.cs" />
|
||||||
|
<Compile Include="Models\SearchMovieViewModel.cs" />
|
||||||
|
<Compile Include="Modules\BaseModule.cs" />
|
||||||
|
<Compile Include="Validators\HeadphonesValidator.cs" />
|
||||||
<Compile Include="Validators\PushoverSettingsValidator.cs" />
|
<Compile Include="Validators\PushoverSettingsValidator.cs" />
|
||||||
<Compile Include="Validators\PushbulletSettingsValidator.cs" />
|
<Compile Include="Validators\PushbulletSettingsValidator.cs" />
|
||||||
<Compile Include="Validators\EmailNotificationSettingsValidator.cs" />
|
<Compile Include="Validators\EmailNotificationSettingsValidator.cs" />
|
||||||
|
@ -193,7 +201,7 @@
|
||||||
<Compile Include="Models\SessionKeys.cs" />
|
<Compile Include="Models\SessionKeys.cs" />
|
||||||
<Compile Include="Modules\AdminModule.cs" />
|
<Compile Include="Modules\AdminModule.cs" />
|
||||||
<Compile Include="Modules\ApplicationTesterModule.cs" />
|
<Compile Include="Modules\ApplicationTesterModule.cs" />
|
||||||
<Compile Include="Modules\BaseModule.cs" />
|
<Compile Include="Modules\BaseAuthModule.cs" />
|
||||||
<Compile Include="Modules\IndexModule.cs" />
|
<Compile Include="Modules\IndexModule.cs" />
|
||||||
<Compile Include="Modules\ApprovalModule.cs" />
|
<Compile Include="Modules\ApprovalModule.cs" />
|
||||||
<Compile Include="Modules\UserLoginModule.cs" />
|
<Compile Include="Modules\UserLoginModule.cs" />
|
||||||
|
@ -458,6 +466,10 @@
|
||||||
<ReferenceCopyLocalPaths Remove="@(ReferenceSatellitePaths)" />
|
<ReferenceCopyLocalPaths Remove="@(ReferenceSatellitePaths)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Target>
|
</Target>
|
||||||
|
<PropertyGroup>
|
||||||
|
<PreBuildEvent>
|
||||||
|
</PreBuildEvent>
|
||||||
|
</PropertyGroup>
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
<Target Name="BeforeBuild">
|
<Target Name="BeforeBuild">
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
// ************************************************************************/
|
// ************************************************************************/
|
||||||
#endregion
|
#endregion
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using Microsoft.Owin.Hosting;
|
using Microsoft.Owin.Hosting;
|
||||||
|
|
||||||
using Mono.Data.Sqlite;
|
using Mono.Data.Sqlite;
|
||||||
|
@ -39,6 +41,11 @@ using PlexRequests.Store;
|
||||||
using PlexRequests.Store.Repository;
|
using PlexRequests.Store.Repository;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
using FluentScheduler;
|
||||||
|
|
||||||
|
using PlexRequests.Services;
|
||||||
|
using PlexRequests.UI.Jobs;
|
||||||
|
|
||||||
namespace PlexRequests.UI
|
namespace PlexRequests.UI
|
||||||
{
|
{
|
||||||
class Program
|
class Program
|
||||||
|
@ -46,28 +53,45 @@ namespace PlexRequests.UI
|
||||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
|
var baseUrl = string.Empty;
|
||||||
var port = -1;
|
var port = -1;
|
||||||
if (args.Length > 0)
|
if (args.Length > 0)
|
||||||
{
|
{
|
||||||
Log.Info("We are going to use port {0} that was passed in", args[0]);
|
for (int i = 0; i < args.Length; i++)
|
||||||
int portResult;
|
|
||||||
if (!int.TryParse(args[0], out portResult))
|
|
||||||
{
|
{
|
||||||
Console.WriteLine("Incorrect Port format. Press any key.");
|
var arg = args[i].ToLowerInvariant().Substring(1);
|
||||||
|
switch (arg)
|
||||||
|
{
|
||||||
|
case "base":
|
||||||
|
i++;
|
||||||
|
var value = args[i];
|
||||||
|
Console.WriteLine($"Using a Base URL {args[i]}");
|
||||||
|
baseUrl = value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
int portResult;
|
||||||
|
if (!int.TryParse(args[i], out portResult))
|
||||||
|
{
|
||||||
|
Console.WriteLine("Didn't pass in a valid port");
|
||||||
Console.ReadLine();
|
Console.ReadLine();
|
||||||
Environment.Exit(1);
|
Environment.Exit(1);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
port = portResult;
|
port = portResult;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Log.Trace("Getting product version");
|
Log.Trace("Getting product version");
|
||||||
WriteOutVersion();
|
WriteOutVersion();
|
||||||
|
|
||||||
var s = new Setup();
|
var s = new Setup();
|
||||||
var cn = s.SetupDb();
|
var cn = s.SetupDb(baseUrl);
|
||||||
s.CacheQualityProfiles();
|
s.CacheQualityProfiles();
|
||||||
ConfigureTargets(cn);
|
ConfigureTargets(cn);
|
||||||
|
|
||||||
|
|
||||||
if (port == -1)
|
if (port == -1)
|
||||||
port = GetStartupPort();
|
port = GetStartupPort();
|
||||||
|
|
||||||
|
@ -79,6 +103,8 @@ namespace PlexRequests.UI
|
||||||
{
|
{
|
||||||
using (WebApp.Start<Startup>(options))
|
using (WebApp.Start<Startup>(options))
|
||||||
{
|
{
|
||||||
|
SetupSchedulers();
|
||||||
|
|
||||||
Console.WriteLine($"Request Plex is running on the following: http://+:{port}/");
|
Console.WriteLine($"Request Plex is running on the following: http://+:{port}/");
|
||||||
|
|
||||||
if (Type.GetType("Mono.Runtime") != null)
|
if (Type.GetType("Mono.Runtime") != null)
|
||||||
|
@ -130,5 +156,12 @@ namespace PlexRequests.UI
|
||||||
{
|
{
|
||||||
LoggingHelper.ConfigureLogging(connectionString);
|
LoggingHelper.ConfigureLogging(connectionString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void SetupSchedulers()
|
||||||
|
{
|
||||||
|
TaskManager.TaskFactory = new PlexTaskFactory();
|
||||||
|
TaskManager.Initialize(new PlexRegistry());
|
||||||
|
TaskManager.Initialize(new MediaCacheRegistry());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
42
PlexRequests.UI/Validators/HeadphonesValidator.cs
Normal file
42
PlexRequests.UI/Validators/HeadphonesValidator.cs
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#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 HeadphonesValidator : AbstractValidator<HeadphonesSettings>
|
||||||
|
{
|
||||||
|
public HeadphonesValidator()
|
||||||
|
{
|
||||||
|
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.ApiKey).NotEmpty().WithMessage("You must specify a Api Key.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,16 @@
|
||||||
@Html.Partial("_Sidebar")
|
@using PlexRequests.UI.Helpers
|
||||||
|
@Html.Partial("_Sidebar")
|
||||||
|
|
||||||
|
@{
|
||||||
|
var baseUrl = Html.GetBaseUrl();
|
||||||
|
var formAction = "/admin/authentication";
|
||||||
|
if (!string.IsNullOrEmpty(baseUrl.ToHtmlString()))
|
||||||
|
{
|
||||||
|
formAction = "/" + baseUrl.ToHtmlString() + formAction;
|
||||||
|
}
|
||||||
|
}
|
||||||
<div class="col-sm-8 col-sm-push-1">
|
<div class="col-sm-8 col-sm-push-1">
|
||||||
<form class="form-horizontal" method="POST" action="/admin/authentication" id="mainForm">
|
<form class="form-horizontal" method="POST" action="@formAction" id="mainForm">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Authentication Settings</legend>
|
<legend>Authentication Settings</legend>
|
||||||
|
|
||||||
|
@ -100,17 +109,20 @@
|
||||||
<script>
|
<script>
|
||||||
$(function () {
|
$(function () {
|
||||||
|
|
||||||
|
var base = '@Html.GetBaseUrl()';
|
||||||
|
|
||||||
if ($('#PlexAuthToken')) {
|
if ($('#PlexAuthToken')) {
|
||||||
loadUserList();
|
loadUserList();
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#refreshUsers').click(function () {
|
$('#refreshUsers').click(function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
loadUserList();
|
loadUserList();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#requestToken').click(function (e) {
|
$('#requestToken').click(function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
var url = createBaseUrl(base, "requestauth");
|
||||||
var $form = $("#mainForm");
|
var $form = $("#mainForm");
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: $form.prop("method"),
|
type: $form.prop("method"),
|
||||||
|
@ -136,6 +148,9 @@
|
||||||
|
|
||||||
|
|
||||||
function loadUserList() {
|
function loadUserList() {
|
||||||
|
$('#users').html("");
|
||||||
|
var url = "getusers";
|
||||||
|
url = createBaseUrl(base, url);
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "Get",
|
type: "Get",
|
||||||
url: "getusers",
|
url: "getusers",
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
@Html.Partial("_Sidebar")
|
@using PlexRequests.UI.Helpers
|
||||||
|
@Html.Partial("_Sidebar")
|
||||||
@{
|
@{
|
||||||
int port;
|
int port;
|
||||||
if (Model.Port == 0)
|
if (Model.Port == 0)
|
||||||
|
@ -108,15 +109,19 @@
|
||||||
<script>
|
<script>
|
||||||
$(function() {
|
$(function() {
|
||||||
|
|
||||||
|
var baseUrl = '@Html.GetBaseUrl()';
|
||||||
|
|
||||||
@if (!string.IsNullOrEmpty(Model.ProfileId))
|
@if (!string.IsNullOrEmpty(Model.ProfileId))
|
||||||
{
|
{
|
||||||
<text>
|
<text>
|
||||||
var qualitySelected = '@Model.ProfileId';
|
var qualitySelected = '@Model.ProfileId';
|
||||||
var $form = $("#mainForm");
|
var $form = $("#mainForm");
|
||||||
|
var url = '/admin/cpprofiles';
|
||||||
|
url = createBaseUrl(baseUrl, url);
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: $form.prop("method"),
|
type: $form.prop("method"),
|
||||||
data: $form.serialize(),
|
data: $form.serialize(),
|
||||||
url: "cpprofiles",
|
url: url,
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function(response) {
|
success: function(response) {
|
||||||
response.list.forEach(function(result) {
|
response.list.forEach(function(result) {
|
||||||
|
@ -139,12 +144,17 @@
|
||||||
$('#getProfiles').click(function (e) {
|
$('#getProfiles').click(function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var $form = $("#mainForm");
|
var $form = $("#mainForm");
|
||||||
|
var url = createBaseUrl(baseUrl, "/admin/cpprofiles");
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: $form.prop("method"),
|
type: $form.prop("method"),
|
||||||
data: $form.serialize(),
|
data: $form.serialize(),
|
||||||
url: "cpprofiles",
|
url: url,
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (response) {
|
success: function (response) {
|
||||||
|
if (response.message) {
|
||||||
|
generateNotify(response.message, "warning");
|
||||||
|
return;
|
||||||
|
}
|
||||||
response.list.forEach(function (result) {
|
response.list.forEach(function (result) {
|
||||||
$("#select").append("<option value='" + result._id + "'>" + result.label + "</option>");
|
$("#select").append("<option value='" + result._id + "'>" + result.label + "</option>");
|
||||||
});
|
});
|
||||||
|
@ -159,10 +169,10 @@
|
||||||
$('#testCp').click(function (e) {
|
$('#testCp').click(function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var $form = $("#mainForm");
|
var $form = $("#mainForm");
|
||||||
|
var url = createBaseUrl(baseUrl,"/test/cp");
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: $form.prop("method"),
|
type: $form.prop("method"),
|
||||||
url: "/test/cp",
|
url: url,
|
||||||
data: $form.serialize(),
|
data: $form.serialize(),
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (response) {
|
success: function (response) {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
@Html.Partial("_Sidebar")
|
@using PlexRequests.UI.Helpers
|
||||||
|
@Html.Partial("_Sidebar")
|
||||||
@{
|
@{
|
||||||
int port;
|
int port;
|
||||||
if (Model.EmailPort == 0)
|
if (Model.EmailPort == 0)
|
||||||
|
@ -106,6 +107,7 @@
|
||||||
<script>
|
<script>
|
||||||
$(function () {
|
$(function () {
|
||||||
|
|
||||||
|
var base = '@Html.GetBaseUrl()';
|
||||||
$('#save').click(function (e) {
|
$('#save').click(function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var port = $('#EmailPort').val();
|
var port = $('#EmailPort').val();
|
||||||
|
@ -134,6 +136,8 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#testEmail').click(function (e) {
|
$('#testEmail').click(function (e) {
|
||||||
|
|
||||||
|
var url = createBaseUrl(base, '/admin/testemailnotification');
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var port = $('#EmailPort').val();
|
var port = $('#EmailPort').val();
|
||||||
if (isNaN(port)) {
|
if (isNaN(port)) {
|
||||||
|
@ -144,7 +148,7 @@
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: $form.prop("method"),
|
type: $form.prop("method"),
|
||||||
data: $form.serialize(),
|
data: $form.serialize(),
|
||||||
url: '/admin/testemailnotification',
|
url: url,
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (response) {
|
success: function (response) {
|
||||||
if (response.result === true) {
|
if (response.result === true) {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
@Html.Partial("_Sidebar")
|
@using PlexRequests.UI.Helpers
|
||||||
|
@Html.Partial("_Sidebar")
|
||||||
@{
|
@{
|
||||||
int port;
|
int port;
|
||||||
if (Model.Port == 0)
|
if (Model.Port == 0)
|
||||||
|
@ -93,13 +94,14 @@
|
||||||
<script>
|
<script>
|
||||||
$(function() {
|
$(function() {
|
||||||
|
|
||||||
|
var base = '@Html.GetBaseUrl()';
|
||||||
$('#testHeadphones').click(function (e) {
|
$('#testHeadphones').click(function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var $form = $("#mainForm");
|
var $form = $("#mainForm");
|
||||||
|
var url = createBaseUrl(base, '/test/headphones');
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: $form.prop("method"),
|
type: $form.prop("method"),
|
||||||
url: "/test/headphones",
|
url: url,
|
||||||
data: $form.serialize(),
|
data: $form.serialize(),
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (response) {
|
success: function (response) {
|
||||||
|
|
|
@ -1,13 +1,20 @@
|
||||||
@Html.Partial("_Sidebar")
|
@using PlexRequests.UI.Helpers
|
||||||
<link rel="stylesheet" type="text/css" href="~/Content/dataTables.bootstrap.css" />
|
@Html.Partial("_Sidebar")
|
||||||
|
@Html.LoadLogsAssets()
|
||||||
|
|
||||||
<script type="text/javascript" src="~/Content/datatables.min.js"></script>
|
@{
|
||||||
|
var baseUrl = Html.GetBaseUrl();
|
||||||
|
var formAction = "/admin/loglevel";
|
||||||
|
if (!string.IsNullOrEmpty(baseUrl.ToHtmlString()))
|
||||||
|
{
|
||||||
|
formAction = "/" + baseUrl.ToHtmlString() + formAction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
<div class="col-sm-8 col-sm-push-1">
|
<div class="col-sm-8 col-sm-push-1">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Logs</legend>
|
<legend>Logs</legend>
|
||||||
|
<form method="post" id="mainForm" action="@formAction">
|
||||||
<form method="post" id="mainForm" action="/admin/loglevel">
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="logLevel" class="control-label">Log Level</label>
|
<label for="logLevel" class="control-label">Log Level</label>
|
||||||
<div id="logLevel">
|
<div id="logLevel">
|
||||||
|
@ -46,9 +53,12 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(function () {
|
$(function () {
|
||||||
|
var baseUrl = '@Html.GetBaseUrl()';
|
||||||
|
|
||||||
|
var logsUrl = "/admin/loadlogs";
|
||||||
|
var url = createBaseUrl(baseUrl, logsUrl);
|
||||||
$('#example').DataTable({
|
$('#example').DataTable({
|
||||||
"ajax": "/admin/loadlogs",
|
"ajax": url,
|
||||||
"columns": [
|
"columns": [
|
||||||
{ "data": "message" },
|
{ "data": "message" },
|
||||||
{ "data": "logger" },
|
{ "data": "logger" },
|
||||||
|
@ -59,9 +69,11 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
var logUrl = "/admin/loglevel";
|
||||||
|
logUrl = createBaseUrl(baseUrl, logUrl);
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "get",
|
type: "get",
|
||||||
url: "/admin/loglevel",
|
url: logUrl,
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (response) {
|
success: function (response) {
|
||||||
$("#select > option").each(function (level) {
|
$("#select > option").each(function (level) {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
@Html.Partial("_Sidebar")
|
@using PlexRequests.UI.Helpers
|
||||||
|
@Html.Partial("_Sidebar")
|
||||||
@{
|
@{
|
||||||
int port;
|
int port;
|
||||||
if (Model.Port == 0)
|
if (Model.Port == 0)
|
||||||
|
@ -67,13 +68,14 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(function () {
|
$(function () {
|
||||||
|
var base = '@Html.GetBaseUrl()';
|
||||||
$('#testPlex').click(function (e) {
|
$('#testPlex').click(function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
var url = createBaseUrl(base, '/test/plex');
|
||||||
var $form = $("#mainForm");
|
var $form = $("#mainForm");
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: $form.prop("method"),
|
type: $form.prop("method"),
|
||||||
url: "/test/plex",
|
url: url,
|
||||||
data: $form.serialize(),
|
data: $form.serialize(),
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (response) {
|
success: function (response) {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
@Html.Partial("_Sidebar")
|
@using PlexRequests.UI.Helpers
|
||||||
|
@Html.Partial("_Sidebar")
|
||||||
|
|
||||||
<div class="col-sm-8 col-sm-push-1">
|
<div class="col-sm-8 col-sm-push-1">
|
||||||
<form class="form-horizontal" method="POST" id="mainForm">
|
<form class="form-horizontal" method="POST" id="mainForm">
|
||||||
|
@ -53,7 +54,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(function () {
|
$(function () {
|
||||||
|
var base = '@Html.GetBaseUrl()';
|
||||||
$('#save').click(function (e) {
|
$('#save').click(function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
|
@ -80,11 +81,12 @@
|
||||||
$('#testPushbullet').click(function (e) {
|
$('#testPushbullet').click(function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
|
var url = createBaseUrl(base, '/admin/testpushbulletnotification');
|
||||||
var $form = $("#mainForm");
|
var $form = $("#mainForm");
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: $form.prop("method"),
|
type: $form.prop("method"),
|
||||||
data: $form.serialize(),
|
data: $form.serialize(),
|
||||||
url: '/admin/testpushbulletnotification',
|
url: url,
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (response) {
|
success: function (response) {
|
||||||
if (response.result === true) {
|
if (response.result === true) {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
@Html.Partial("_Sidebar")
|
@using PlexRequests.UI.Helpers
|
||||||
|
@Html.Partial("_Sidebar")
|
||||||
|
|
||||||
<div class="col-sm-8 col-sm-push-1">
|
<div class="col-sm-8 col-sm-push-1">
|
||||||
<form class="form-horizontal" method="POST" id="mainForm">
|
<form class="form-horizontal" method="POST" id="mainForm">
|
||||||
|
@ -54,6 +55,7 @@
|
||||||
<script>
|
<script>
|
||||||
$(function () {
|
$(function () {
|
||||||
|
|
||||||
|
var base = '@Html.GetBaseUrl()';
|
||||||
$('#save').click(function (e) {
|
$('#save').click(function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
|
@ -80,11 +82,12 @@
|
||||||
$('#testPushover').click(function (e) {
|
$('#testPushover').click(function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
|
var url = createBaseUrl(base, '/admin/testpushovernotification');
|
||||||
var $form = $("#mainForm");
|
var $form = $("#mainForm");
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: $form.prop("method"),
|
type: $form.prop("method"),
|
||||||
data: $form.serialize(),
|
data: $form.serialize(),
|
||||||
url: '/admin/testpushovernotification',
|
url: url,
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (response) {
|
success: function (response) {
|
||||||
if (response.result === true) {
|
if (response.result === true) {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
@Html.Partial("_Sidebar")
|
@using PlexRequests.UI.Helpers
|
||||||
|
@Html.Partial("_Sidebar")
|
||||||
@{
|
@{
|
||||||
int port;
|
int port;
|
||||||
if (Model.Port == 0)
|
if (Model.Port == 0)
|
||||||
|
@ -10,9 +11,17 @@
|
||||||
port = Model.Port;
|
port = Model.Port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var baseUrl = Html.GetBaseUrl();
|
||||||
|
var formAction = "/admin";
|
||||||
|
if (!string.IsNullOrEmpty(baseUrl.ToHtmlString()))
|
||||||
|
{
|
||||||
|
formAction = "/" + baseUrl.ToHtmlString() + formAction;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
<div class="col-sm-8 col-sm-push-1">
|
<div class="col-sm-8 col-sm-push-1">
|
||||||
<form class="form-horizontal" method="POST" action="/admin" id="mainForm">
|
<form class="form-horizontal" method="POST" action="@formAction" id="mainForm">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Request Plex Settings</legend>
|
<legend>Request Plex Settings</legend>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
@ -23,6 +32,16 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<small class="control-label">You will have to restart after changing the port.</small>
|
<small class="control-label">You will have to restart after changing the port.</small>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="BaseUrl" class="control-label">Base Url</label>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<input type="text" class="form-control form-control-custom " id="BaseUrl" name="BaseUrl" placeholder="Base Url" value="@Model.BaseUrl">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<small class="control-label">You will have to restart after changing the url base.</small>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label>
|
<label>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
@Html.Partial("_Sidebar")
|
@using PlexRequests.UI.Helpers
|
||||||
|
@Html.Partial("_Sidebar")
|
||||||
@{
|
@{
|
||||||
int port;
|
int port;
|
||||||
if (Model.Port == 0)
|
if (Model.Port == 0)
|
||||||
|
@ -103,7 +104,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(function() {
|
$(function() {
|
||||||
|
var base = '@Html.GetBaseUrl()';
|
||||||
@if (!string.IsNullOrEmpty(Model.QualityProfile))
|
@if (!string.IsNullOrEmpty(Model.QualityProfile))
|
||||||
{
|
{
|
||||||
<text>
|
<text>
|
||||||
|
@ -147,11 +148,18 @@
|
||||||
|
|
||||||
$('#testSickRage').click(function (e) {
|
$('#testSickRage').click(function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
var qualityProfile = $("#profiles option:selected").val();
|
||||||
|
|
||||||
var $form = $("#mainForm");
|
var $form = $("#mainForm");
|
||||||
|
|
||||||
|
var data = $form.serialize();
|
||||||
|
data = data + "&qualityProfile=" + qualityProfile;
|
||||||
|
|
||||||
|
var url = createBaseUrl(base, '/test/sickrage');
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: $form.prop("method"),
|
type: $form.prop("method"),
|
||||||
url: "/test/sickrage",
|
url: url,
|
||||||
data: $form.serialize(),
|
data: data,
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (response) {
|
success: function (response) {
|
||||||
console.log(response);
|
console.log(response);
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue