mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-16 02:02:55 -07:00
commit
69fee0a24a
33 changed files with 1026 additions and 13 deletions
15
Ombi.Api.Interfaces/IRadarrApi.cs
Normal file
15
Ombi.Api.Interfaces/IRadarrApi.cs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Ombi.Api.Models.Radarr;
|
||||||
|
using Ombi.Api.Models.Sonarr;
|
||||||
|
|
||||||
|
namespace Ombi.Api.Interfaces
|
||||||
|
{
|
||||||
|
public interface IRadarrApi
|
||||||
|
{
|
||||||
|
RadarrAddMovie AddMovie(int tmdbId, string title, int qualityId, string rootPath, string apiKey, Uri baseUrl, bool searchNow = false);
|
||||||
|
List<RadarrMovieResponse> GetMovies(string apiKey, Uri baseUrl);
|
||||||
|
List<SonarrProfile> GetProfiles(string apiKey, Uri baseUrl);
|
||||||
|
SystemStatus SystemStatus(string apiKey, Uri baseUrl);
|
||||||
|
}
|
||||||
|
}
|
|
@ -53,6 +53,7 @@
|
||||||
<Compile Include="INetflixApi.cs" />
|
<Compile Include="INetflixApi.cs" />
|
||||||
<Compile Include="IPlexApi.cs" />
|
<Compile Include="IPlexApi.cs" />
|
||||||
<Compile Include="IPushbulletApi.cs" />
|
<Compile Include="IPushbulletApi.cs" />
|
||||||
|
<Compile Include="IRadarrApi.cs" />
|
||||||
<Compile Include="ISlackApi.cs" />
|
<Compile Include="ISlackApi.cs" />
|
||||||
<Compile Include="IPushoverApi.cs" />
|
<Compile Include="IPushoverApi.cs" />
|
||||||
<Compile Include="ISickRageApi.cs" />
|
<Compile Include="ISickRageApi.cs" />
|
||||||
|
|
|
@ -82,6 +82,10 @@
|
||||||
<Compile Include="Plex\PlexUserRequest.cs" />
|
<Compile Include="Plex\PlexUserRequest.cs" />
|
||||||
<Compile Include="Plex\RecentlyAddedModelOld.cs" />
|
<Compile Include="Plex\RecentlyAddedModelOld.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Radarr\RadarrAddMovie.cs" />
|
||||||
|
<Compile Include="Radarr\RadarrAddOptions.cs" />
|
||||||
|
<Compile Include="Radarr\RadarrError.cs" />
|
||||||
|
<Compile Include="Radarr\RadarrMovieResponse.cs" />
|
||||||
<Compile Include="SickRage\SickRageBase.cs" />
|
<Compile Include="SickRage\SickRageBase.cs" />
|
||||||
<Compile Include="SickRage\SickrageShows.cs" />
|
<Compile Include="SickRage\SickrageShows.cs" />
|
||||||
<Compile Include="SickRage\SickRagePing.cs" />
|
<Compile Include="SickRage\SickRagePing.cs" />
|
||||||
|
|
55
Ombi.Api.Models/Radarr/RadarrAddMovie.cs
Normal file
55
Ombi.Api.Models/Radarr/RadarrAddMovie.cs
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2017 Jamie Rees
|
||||||
|
// File: RadarrAddMovie.cs
|
||||||
|
// Created By: Jamie Rees
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
// a copy of this software and associated documentation files (the
|
||||||
|
// "Software"), to deal in the Software without restriction, including
|
||||||
|
// without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
// permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
// the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be
|
||||||
|
// included in all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
// ************************************************************************/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Ombi.Api.Models.Sonarr;
|
||||||
|
|
||||||
|
namespace Ombi.Api.Models.Radarr
|
||||||
|
{
|
||||||
|
public class RadarrAddMovie
|
||||||
|
{
|
||||||
|
|
||||||
|
public RadarrAddMovie()
|
||||||
|
{
|
||||||
|
images = new List<string>();
|
||||||
|
}
|
||||||
|
public RadarrError Error { get; set; }
|
||||||
|
public RadarrAddOptions addOptions { get; set; }
|
||||||
|
public string title { get; set; }
|
||||||
|
public string rootFolderPath { get; set; }
|
||||||
|
public int qualityProfileId { get; set; }
|
||||||
|
public bool monitored { get; set; }
|
||||||
|
public int tmdbId { get; set; }
|
||||||
|
public List<string> images { get; set; }
|
||||||
|
public string cleanTitle { get; set; }
|
||||||
|
public string imdbId { get; set; }
|
||||||
|
public string titleSlug { get; set; }
|
||||||
|
public int id { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
35
Ombi.Api.Models/Radarr/RadarrAddOptions.cs
Normal file
35
Ombi.Api.Models/Radarr/RadarrAddOptions.cs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2017 Jamie Rees
|
||||||
|
// File: RadarrAddOptions.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 Ombi.Api.Models.Radarr
|
||||||
|
{
|
||||||
|
public class RadarrAddOptions
|
||||||
|
{
|
||||||
|
public bool ignoreEpisodesWithFiles { get; set; }
|
||||||
|
public bool ignoreEpisodesWithoutFiles { get; set; }
|
||||||
|
public bool searchForMovie { get; set; }
|
||||||
|
}
|
||||||
|
}
|
34
Ombi.Api.Models/Radarr/RadarrError.cs
Normal file
34
Ombi.Api.Models/Radarr/RadarrError.cs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2017 Jamie Rees
|
||||||
|
// File: RadarrError.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 Ombi.Api.Models.Radarr
|
||||||
|
{
|
||||||
|
public class RadarrError
|
||||||
|
{
|
||||||
|
public string message { get; set; }
|
||||||
|
public string description { get; set; }
|
||||||
|
}
|
||||||
|
}
|
80
Ombi.Api.Models/Radarr/RadarrMovieResponse.cs
Normal file
80
Ombi.Api.Models/Radarr/RadarrMovieResponse.cs
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2017 Jamie Rees
|
||||||
|
// File: RadarrMovieResponse.cs
|
||||||
|
// Created By: Jamie Rees
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
// a copy of this software and associated documentation files (the
|
||||||
|
// "Software"), to deal in the Software without restriction, including
|
||||||
|
// without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
// permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
// the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be
|
||||||
|
// included in all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
// ************************************************************************/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Ombi.Api.Models.Radarr
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public class Image
|
||||||
|
{
|
||||||
|
public string coverType { get; set; }
|
||||||
|
public string url { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Ratings
|
||||||
|
{
|
||||||
|
public int votes { get; set; }
|
||||||
|
public double value { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RadarrMovieResponse
|
||||||
|
{
|
||||||
|
public string title { get; set; }
|
||||||
|
public string sortTitle { get; set; }
|
||||||
|
public int sizeOnDisk { get; set; }
|
||||||
|
public string status { get; set; }
|
||||||
|
public string overview { get; set; }
|
||||||
|
public string inCinemas { get; set; }
|
||||||
|
public string physicalRelease { get; set; }
|
||||||
|
public List<Image> images { get; set; }
|
||||||
|
public string website { get; set; }
|
||||||
|
public bool downloaded { get; set; }
|
||||||
|
public int year { get; set; }
|
||||||
|
public bool hasFile { get; set; }
|
||||||
|
public string youTubeTrailerId { get; set; }
|
||||||
|
public string studio { get; set; }
|
||||||
|
public string path { get; set; }
|
||||||
|
public int profileId { get; set; }
|
||||||
|
public bool monitored { get; set; }
|
||||||
|
public int runtime { get; set; }
|
||||||
|
public string lastInfoSync { get; set; }
|
||||||
|
public string cleanTitle { get; set; }
|
||||||
|
public string imdbId { get; set; }
|
||||||
|
public int tmdbId { get; set; }
|
||||||
|
public string titleSlug { get; set; }
|
||||||
|
public List<string> genres { get; set; }
|
||||||
|
public List<object> tags { get; set; }
|
||||||
|
public string added { get; set; }
|
||||||
|
public Ratings ratings { get; set; }
|
||||||
|
public List<string> alternativeTitles { get; set; }
|
||||||
|
public int qualityProfileId { get; set; }
|
||||||
|
public int id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -71,6 +71,7 @@
|
||||||
<Compile Include="ApiRequest.cs" />
|
<Compile Include="ApiRequest.cs" />
|
||||||
<Compile Include="DiscordApi.cs" />
|
<Compile Include="DiscordApi.cs" />
|
||||||
<Compile Include="NetflixRouletteApi.cs" />
|
<Compile Include="NetflixRouletteApi.cs" />
|
||||||
|
<Compile Include="RadarrApi.cs" />
|
||||||
<Compile Include="WatcherApi.cs" />
|
<Compile Include="WatcherApi.cs" />
|
||||||
<Compile Include="MusicBrainzApi.cs" />
|
<Compile Include="MusicBrainzApi.cs" />
|
||||||
<Compile Include="SlackApi.cs" />
|
<Compile Include="SlackApi.cs" />
|
||||||
|
|
152
Ombi.Api/RadarrApi.cs
Normal file
152
Ombi.Api/RadarrApi.cs
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: CouchPotatoApi.cs
|
||||||
|
// Created By: Jamie Rees
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
// a copy of this software and associated documentation files (the
|
||||||
|
// "Software"), to deal in the Software without restriction, including
|
||||||
|
// without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
// permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
// the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be
|
||||||
|
// included in all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
// ************************************************************************/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using NLog;
|
||||||
|
using Ombi.Api.Interfaces;
|
||||||
|
using Ombi.Api.Models.Radarr;
|
||||||
|
using Ombi.Api.Models.Sonarr;
|
||||||
|
using Ombi.Helpers;
|
||||||
|
using RestSharp;
|
||||||
|
|
||||||
|
namespace Ombi.Api
|
||||||
|
{
|
||||||
|
public class RadarrApi : IRadarrApi
|
||||||
|
{
|
||||||
|
public RadarrApi()
|
||||||
|
{
|
||||||
|
Api = new ApiRequest();
|
||||||
|
}
|
||||||
|
private ApiRequest Api { get; set; }
|
||||||
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
public List<SonarrProfile> GetProfiles(string apiKey, Uri baseUrl)
|
||||||
|
{
|
||||||
|
var request = new RestRequest { Resource = "/api/profile", Method = Method.GET };
|
||||||
|
|
||||||
|
request.AddHeader("X-Api-Key", apiKey);
|
||||||
|
var policy = RetryHandler.RetryAndWaitPolicy((exception, timespan) => Log.Error(exception, "Exception when calling GetProfiles for Sonarr, Retrying {0}", timespan), new TimeSpan[] {
|
||||||
|
TimeSpan.FromSeconds (2),
|
||||||
|
TimeSpan.FromSeconds(5),
|
||||||
|
TimeSpan.FromSeconds(10)
|
||||||
|
});
|
||||||
|
|
||||||
|
var obj = policy.Execute(() => Api.ExecuteJson<List<SonarrProfile>>(request, baseUrl));
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RadarrAddMovie AddMovie(int tmdbId, string title, int qualityId, string rootPath, string apiKey, Uri baseUrl, bool searchNow = false)
|
||||||
|
{
|
||||||
|
var request = new RestRequest
|
||||||
|
{
|
||||||
|
Resource = "/api/movie",
|
||||||
|
Method = Method.POST
|
||||||
|
};
|
||||||
|
|
||||||
|
var options = new RadarrAddMovie
|
||||||
|
{
|
||||||
|
title = title,
|
||||||
|
tmdbId = tmdbId,
|
||||||
|
qualityProfileId = qualityId,
|
||||||
|
rootFolderPath = rootPath,
|
||||||
|
titleSlug = title,
|
||||||
|
monitored = true
|
||||||
|
};
|
||||||
|
|
||||||
|
if (searchNow)
|
||||||
|
{
|
||||||
|
options.addOptions = new RadarrAddOptions
|
||||||
|
{
|
||||||
|
searchForMovie = true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
request.AddHeader("X-Api-Key", apiKey);
|
||||||
|
request.AddJsonBody(options);
|
||||||
|
|
||||||
|
RadarrAddMovie result;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var policy = RetryHandler.RetryAndWaitPolicy((exception, timespan) => Log.Error(exception, "Exception when calling AddSeries for Sonarr, Retrying {0}", timespan), new TimeSpan[] {
|
||||||
|
TimeSpan.FromSeconds (2)
|
||||||
|
});
|
||||||
|
|
||||||
|
var response = policy.Execute(() => Api.Execute(request, baseUrl));
|
||||||
|
if (response.Content.Contains("\"message\":"))
|
||||||
|
{
|
||||||
|
var error = JsonConvert.DeserializeObject < RadarrError>(response.Content);
|
||||||
|
return new RadarrAddMovie {Error = error};
|
||||||
|
}
|
||||||
|
return JsonConvert.DeserializeObject < RadarrAddMovie>(response.Content);
|
||||||
|
}
|
||||||
|
catch (JsonSerializationException jse)
|
||||||
|
{
|
||||||
|
Log.Error(jse);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public SystemStatus SystemStatus(string apiKey, Uri baseUrl)
|
||||||
|
{
|
||||||
|
var request = new RestRequest { Resource = "/api/system/status", Method = Method.GET };
|
||||||
|
request.AddHeader("X-Api-Key", apiKey);
|
||||||
|
|
||||||
|
var policy = RetryHandler.RetryAndWaitPolicy((exception, timespan) => Log.Error(exception, "Exception when calling SystemStatus for Sonarr, Retrying {0}", timespan), new TimeSpan[] {
|
||||||
|
TimeSpan.FromSeconds (2),
|
||||||
|
TimeSpan.FromSeconds(5),
|
||||||
|
TimeSpan.FromSeconds(10)
|
||||||
|
});
|
||||||
|
|
||||||
|
var obj = policy.Execute(() => Api.ExecuteJson<SystemStatus>(request, baseUrl));
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<RadarrMovieResponse> GetMovies(string apiKey, Uri baseUrl)
|
||||||
|
{
|
||||||
|
var request = new RestRequest { Resource = "/api/movie", Method = Method.GET };
|
||||||
|
request.AddHeader("X-Api-Key", apiKey);
|
||||||
|
|
||||||
|
var policy = RetryHandler.RetryAndWaitPolicy((exception, timespan) => Log.Error(exception, "Exception when calling SystemStatus for Sonarr, Retrying {0}", timespan), new TimeSpan[] {
|
||||||
|
TimeSpan.FromSeconds (2),
|
||||||
|
TimeSpan.FromSeconds(5),
|
||||||
|
TimeSpan.FromSeconds(10)
|
||||||
|
});
|
||||||
|
|
||||||
|
var obj = policy.Execute(() => Api.Execute(request, baseUrl));
|
||||||
|
|
||||||
|
return JsonConvert.DeserializeObject<List<RadarrMovieResponse>>(obj.Content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,7 +37,9 @@ namespace Ombi.Core
|
||||||
public const string PlexEpisodes = nameof(PlexEpisodes);
|
public const string PlexEpisodes = nameof(PlexEpisodes);
|
||||||
public const string TvDbToken = nameof(TvDbToken);
|
public const string TvDbToken = nameof(TvDbToken);
|
||||||
public const string SonarrQualityProfiles = nameof(SonarrQualityProfiles);
|
public const string SonarrQualityProfiles = nameof(SonarrQualityProfiles);
|
||||||
|
public const string RadarrQualityProfiles = nameof(RadarrQualityProfiles);
|
||||||
public const string SonarrQueued = nameof(SonarrQueued);
|
public const string SonarrQueued = nameof(SonarrQueued);
|
||||||
|
public const string RadarrMovies = nameof(RadarrMovies);
|
||||||
public const string SickRageQualityProfiles = nameof(SickRageQualityProfiles);
|
public const string SickRageQualityProfiles = nameof(SickRageQualityProfiles);
|
||||||
public const string SickRageQueued = nameof(SickRageQueued);
|
public const string SickRageQueued = nameof(SickRageQueued);
|
||||||
public const string CouchPotatoQualityProfiles = nameof(CouchPotatoQualityProfiles);
|
public const string CouchPotatoQualityProfiles = nameof(CouchPotatoQualityProfiles);
|
||||||
|
|
|
@ -37,16 +37,20 @@ namespace Ombi.Core
|
||||||
public class MovieSender : IMovieSender
|
public class MovieSender : IMovieSender
|
||||||
{
|
{
|
||||||
public MovieSender(ISettingsService<CouchPotatoSettings> cp, ISettingsService<WatcherSettings> watcher,
|
public MovieSender(ISettingsService<CouchPotatoSettings> cp, ISettingsService<WatcherSettings> watcher,
|
||||||
ICouchPotatoApi cpApi, IWatcherApi watcherApi)
|
ICouchPotatoApi cpApi, IWatcherApi watcherApi, IRadarrApi radarrApi, ISettingsService<RadarrSettings> radarrSettings)
|
||||||
{
|
{
|
||||||
CouchPotatoSettings = cp;
|
CouchPotatoSettings = cp;
|
||||||
WatcherSettings = watcher;
|
WatcherSettings = watcher;
|
||||||
CpApi = cpApi;
|
CpApi = cpApi;
|
||||||
WatcherApi = watcherApi;
|
WatcherApi = watcherApi;
|
||||||
|
RadarrSettings = radarrSettings;
|
||||||
|
RadarrApi = radarrApi;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ISettingsService<CouchPotatoSettings> CouchPotatoSettings { get; }
|
private ISettingsService<CouchPotatoSettings> CouchPotatoSettings { get; }
|
||||||
private ISettingsService<WatcherSettings> WatcherSettings { get; }
|
private ISettingsService<WatcherSettings> WatcherSettings { get; }
|
||||||
|
private ISettingsService<RadarrSettings> RadarrSettings { get; }
|
||||||
|
private IRadarrApi RadarrApi { get; }
|
||||||
private ICouchPotatoApi CpApi { get; }
|
private ICouchPotatoApi CpApi { get; }
|
||||||
private IWatcherApi WatcherApi { get; }
|
private IWatcherApi WatcherApi { get; }
|
||||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
@ -55,6 +59,7 @@ namespace Ombi.Core
|
||||||
{
|
{
|
||||||
var cpSettings = await CouchPotatoSettings.GetSettingsAsync();
|
var cpSettings = await CouchPotatoSettings.GetSettingsAsync();
|
||||||
var watcherSettings = await WatcherSettings.GetSettingsAsync();
|
var watcherSettings = await WatcherSettings.GetSettingsAsync();
|
||||||
|
var radarrSettings = await RadarrSettings.GetSettingsAsync();
|
||||||
|
|
||||||
if (cpSettings.Enabled)
|
if (cpSettings.Enabled)
|
||||||
{
|
{
|
||||||
|
@ -66,6 +71,11 @@ namespace Ombi.Core
|
||||||
return SendToWatcher(model, watcherSettings);
|
return SendToWatcher(model, watcherSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (radarrSettings.Enabled)
|
||||||
|
{
|
||||||
|
return SendToRadarr(model, radarrSettings);
|
||||||
|
}
|
||||||
|
|
||||||
return new MovieSenderResult { Result = false, MovieSendingEnabled = false };
|
return new MovieSenderResult { Result = false, MovieSendingEnabled = false };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,5 +101,23 @@ namespace Ombi.Core
|
||||||
var result = CpApi.AddMovie(model.ImdbId, settings.ApiKey, model.Title, settings.FullUri, qualityId);
|
var result = CpApi.AddMovie(model.ImdbId, settings.ApiKey, model.Title, settings.FullUri, qualityId);
|
||||||
return new MovieSenderResult { Result = result, MovieSendingEnabled = true };
|
return new MovieSenderResult { Result = result, MovieSendingEnabled = true };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private MovieSenderResult SendToRadarr(RequestedModel model, RadarrSettings settings)
|
||||||
|
{
|
||||||
|
var qualityProfile = 0;
|
||||||
|
int.TryParse(settings.QualityProfile, out qualityProfile);
|
||||||
|
var result = RadarrApi.AddMovie(model.ProviderId, model.Title, qualityProfile, settings.RootPath, settings.ApiKey, settings.FullUri, true);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(result.Error?.message))
|
||||||
|
{
|
||||||
|
Log.Error(result.Error.message);
|
||||||
|
return new MovieSenderResult { Result = false };
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrEmpty(result.title))
|
||||||
|
{
|
||||||
|
return new MovieSenderResult { Result = true, MovieSendingEnabled = true };
|
||||||
|
}
|
||||||
|
return new MovieSenderResult { Result = false, MovieSendingEnabled = true };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -123,6 +123,7 @@
|
||||||
<Compile Include="SecurityExtensions.cs" />
|
<Compile Include="SecurityExtensions.cs" />
|
||||||
<Compile Include="SettingModels\AuthenticationSettings.cs" />
|
<Compile Include="SettingModels\AuthenticationSettings.cs" />
|
||||||
<Compile Include="SettingModels\DiscordNotificationSettings.cs" />
|
<Compile Include="SettingModels\DiscordNotificationSettings.cs" />
|
||||||
|
<Compile Include="SettingModels\RadarrSettings.cs" />
|
||||||
<Compile Include="SettingModels\WatcherSettings.cs" />
|
<Compile Include="SettingModels\WatcherSettings.cs" />
|
||||||
<Compile Include="SettingModels\ExternalSettings.cs" />
|
<Compile Include="SettingModels\ExternalSettings.cs" />
|
||||||
<Compile Include="SettingModels\HeadphonesSettings.cs" />
|
<Compile Include="SettingModels\HeadphonesSettings.cs" />
|
||||||
|
|
37
Ombi.Core/SettingModels/RadarrSettings.cs
Normal file
37
Ombi.Core/SettingModels/RadarrSettings.cs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: SonarrSettings.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 Ombi.Core.SettingModels
|
||||||
|
{
|
||||||
|
public sealed class RadarrSettings : ExternalSettings
|
||||||
|
{
|
||||||
|
public bool Enabled { get; set; }
|
||||||
|
public string ApiKey { get; set; }
|
||||||
|
public string QualityProfile { get; set; }
|
||||||
|
public string RootPath { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -46,5 +46,6 @@ namespace Ombi.Core.SettingModels
|
||||||
public int FaultQueueHandler { get; set; }
|
public int FaultQueueHandler { get; set; }
|
||||||
public int PlexContentCacher { get; set; }
|
public int PlexContentCacher { get; set; }
|
||||||
public int PlexUserChecker { get; set; }
|
public int PlexUserChecker { get; set; }
|
||||||
|
public int RadarrCacher { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
11
Ombi.Services/Interfaces/IRadarrCacher.cs
Normal file
11
Ombi.Services/Interfaces/IRadarrCacher.cs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Ombi.Services.Models;
|
||||||
|
|
||||||
|
namespace Ombi.Services.Interfaces
|
||||||
|
{
|
||||||
|
public interface IRadarrCacher
|
||||||
|
{
|
||||||
|
void Queued();
|
||||||
|
int[] QueuedIds();
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,6 +32,7 @@ namespace Ombi.Services.Jobs
|
||||||
public const string CpCacher = "CouchPotato Cacher";
|
public const string CpCacher = "CouchPotato Cacher";
|
||||||
public const string WatcherCacher = "Watcher Cacher";
|
public const string WatcherCacher = "Watcher Cacher";
|
||||||
public const string SonarrCacher = "Sonarr Cacher";
|
public const string SonarrCacher = "Sonarr Cacher";
|
||||||
|
public const string RadarrCacher = "Radarr Cacher";
|
||||||
public const string SrCacher = "SickRage Cacher";
|
public const string SrCacher = "SickRage Cacher";
|
||||||
public const string PlexChecker = "Plex Availability Cacher";
|
public const string PlexChecker = "Plex Availability Cacher";
|
||||||
public const string PlexCacher = "Plex Cacher";
|
public const string PlexCacher = "Plex Cacher";
|
||||||
|
|
102
Ombi.Services/Jobs/RadarrCacher.cs
Normal file
102
Ombi.Services/Jobs/RadarrCacher.cs
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
#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.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using NLog;
|
||||||
|
using Ombi.Api.Interfaces;
|
||||||
|
using Ombi.Api.Models.Radarr;
|
||||||
|
using Ombi.Core;
|
||||||
|
using Ombi.Core.SettingModels;
|
||||||
|
using Ombi.Helpers;
|
||||||
|
using Ombi.Services.Interfaces;
|
||||||
|
using Quartz;
|
||||||
|
|
||||||
|
namespace Ombi.Services.Jobs
|
||||||
|
{
|
||||||
|
public class RadarrCacher : IJob, IRadarrCacher
|
||||||
|
{
|
||||||
|
public RadarrCacher(ISettingsService<RadarrSettings> radarrService, IRadarrApi radarrApi, ICacheProvider cache, IJobRecord rec)
|
||||||
|
{
|
||||||
|
RadarrSettings = radarrService;
|
||||||
|
RadarrApi = radarrApi;
|
||||||
|
Job = rec;
|
||||||
|
Cache = cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ISettingsService<RadarrSettings> RadarrSettings { get; }
|
||||||
|
private ICacheProvider Cache { get; }
|
||||||
|
private IRadarrApi RadarrApi { get; }
|
||||||
|
private IJobRecord Job { get; }
|
||||||
|
|
||||||
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
public void Queued()
|
||||||
|
{
|
||||||
|
var settings = RadarrSettings.GetSettings();
|
||||||
|
if (settings.Enabled)
|
||||||
|
{
|
||||||
|
Job.SetRunning(true, JobNames.RadarrCacher);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var movies = RadarrApi.GetMovies(settings.ApiKey, settings.FullUri);
|
||||||
|
if (movies != null)
|
||||||
|
{
|
||||||
|
var movieIds = movies.Select(x => x.tmdbId).ToList();
|
||||||
|
Cache.Set(CacheKeys.RadarrMovies, movieIds, CacheKeys.TimeFrameMinutes.SchedulerCaching);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (System.Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Failed caching queued items from Radarr");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Job.Record(JobNames.RadarrCacher);
|
||||||
|
Job.SetRunning(false, JobNames.RadarrCacher);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we do not want to set here...
|
||||||
|
public int[] QueuedIds()
|
||||||
|
{
|
||||||
|
var retVal = new List<int>();
|
||||||
|
var movies = Cache.Get<List<int>>(CacheKeys.RadarrMovies);
|
||||||
|
if (movies != null)
|
||||||
|
{
|
||||||
|
retVal.AddRange(movies);
|
||||||
|
}
|
||||||
|
return retVal.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Execute(IJobExecutionContext context)
|
||||||
|
{
|
||||||
|
Queued();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -86,9 +86,11 @@
|
||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Interfaces\IRadarrCacher.cs" />
|
||||||
<Compile Include="Interfaces\IWatcherCacher.cs" />
|
<Compile Include="Interfaces\IWatcherCacher.cs" />
|
||||||
<Compile Include="Interfaces\IJobRecord.cs" />
|
<Compile Include="Interfaces\IJobRecord.cs" />
|
||||||
<Compile Include="Interfaces\INotificationEngine.cs" />
|
<Compile Include="Interfaces\INotificationEngine.cs" />
|
||||||
|
<Compile Include="Jobs\RadarrCacher.cs" />
|
||||||
<Compile Include="Jobs\WatcherCacher.cs" />
|
<Compile Include="Jobs\WatcherCacher.cs" />
|
||||||
<Compile Include="Jobs\HtmlTemplateGenerator.cs" />
|
<Compile Include="Jobs\HtmlTemplateGenerator.cs" />
|
||||||
<Compile Include="Jobs\IPlexContentCacher.cs" />
|
<Compile Include="Jobs\IPlexContentCacher.cs" />
|
||||||
|
|
|
@ -355,7 +355,7 @@ $(function () {
|
||||||
if (results.result) {
|
if (results.result) {
|
||||||
// It's on Netflix
|
// It's on Netflix
|
||||||
$('#' + id + 'netflixTab')
|
$('#' + id + 'netflixTab')
|
||||||
.html("<span class='label label-success'>Avaialble on Netflix</span>");
|
.html("<a href='https://www.netflix.com/watch/"+results.netflixId+"' target='_blank'><span class='label label-success'>Avaialble on Netflix</span></a>");
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -75,6 +75,7 @@ namespace Ombi.UI.Jobs
|
||||||
JobBuilder.Create<UserRequestLimitResetter>().WithIdentity("UserRequestLimiter", "Request").Build(),
|
JobBuilder.Create<UserRequestLimitResetter>().WithIdentity("UserRequestLimiter", "Request").Build(),
|
||||||
JobBuilder.Create<RecentlyAdded>().WithIdentity("RecentlyAddedModel", "Email").Build(),
|
JobBuilder.Create<RecentlyAdded>().WithIdentity("RecentlyAddedModel", "Email").Build(),
|
||||||
JobBuilder.Create<FaultQueueHandler>().WithIdentity("FaultQueueHandler", "Fault").Build(),
|
JobBuilder.Create<FaultQueueHandler>().WithIdentity("FaultQueueHandler", "Fault").Build(),
|
||||||
|
JobBuilder.Create<RadarrCacher>().WithIdentity("RadarrCacher", "Cache").Build(),
|
||||||
};
|
};
|
||||||
|
|
||||||
jobs.AddRange(jobList);
|
jobs.AddRange(jobList);
|
||||||
|
@ -170,6 +171,10 @@ namespace Ombi.UI.Jobs
|
||||||
{
|
{
|
||||||
s.PlexUserChecker = 24;
|
s.PlexUserChecker = 24;
|
||||||
}
|
}
|
||||||
|
if (s.RadarrCacher == 0)
|
||||||
|
{
|
||||||
|
s.RadarrCacher = 60;
|
||||||
|
}
|
||||||
|
|
||||||
var triggers = new List<ITrigger>();
|
var triggers = new List<ITrigger>();
|
||||||
|
|
||||||
|
@ -222,6 +227,14 @@ namespace Ombi.UI.Jobs
|
||||||
.WithSimpleSchedule(x => x.WithIntervalInMinutes(s.WatcherCacher).RepeatForever())
|
.WithSimpleSchedule(x => x.WithIntervalInMinutes(s.WatcherCacher).RepeatForever())
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
|
var radarrCacher =
|
||||||
|
TriggerBuilder.Create()
|
||||||
|
.WithIdentity("RadarrCacher", "Cache")
|
||||||
|
.StartNow()
|
||||||
|
//.StartAt(DateBuilder.FutureDate(2, IntervalUnit.Minute))
|
||||||
|
.WithSimpleSchedule(x => x.WithIntervalInMinutes(s.RadarrCacher).RepeatForever())
|
||||||
|
.Build();
|
||||||
|
|
||||||
var storeBackup =
|
var storeBackup =
|
||||||
TriggerBuilder.Create()
|
TriggerBuilder.Create()
|
||||||
.WithIdentity("StoreBackup", "Database")
|
.WithIdentity("StoreBackup", "Database")
|
||||||
|
@ -280,6 +293,7 @@ namespace Ombi.UI.Jobs
|
||||||
triggers.Add(fault);
|
triggers.Add(fault);
|
||||||
triggers.Add(plexCacher);
|
triggers.Add(plexCacher);
|
||||||
triggers.Add(plexUserChecker);
|
triggers.Add(plexUserChecker);
|
||||||
|
triggers.Add(radarrCacher);
|
||||||
|
|
||||||
return triggers;
|
return triggers;
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,6 +95,8 @@ namespace Ombi.UI.Modules.Admin
|
||||||
private ISettingsService<NotificationSettingsV2> NotifySettings { get; }
|
private ISettingsService<NotificationSettingsV2> NotifySettings { get; }
|
||||||
private ISettingsService<DiscordNotificationSettings> DiscordSettings { get; }
|
private ISettingsService<DiscordNotificationSettings> DiscordSettings { get; }
|
||||||
private IDiscordApi DiscordApi { get; }
|
private IDiscordApi DiscordApi { get; }
|
||||||
|
private ISettingsService<RadarrSettings> RadarrSettings { get; }
|
||||||
|
private IRadarrApi RadarrApi { get; }
|
||||||
|
|
||||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
public AdminModule(ISettingsService<PlexRequestSettings> prService,
|
public AdminModule(ISettingsService<PlexRequestSettings> prService,
|
||||||
|
@ -122,7 +124,7 @@ namespace Ombi.UI.Modules.Admin
|
||||||
ISettingsService<NotificationSettingsV2> notifyService, IRecentlyAdded recentlyAdded,
|
ISettingsService<NotificationSettingsV2> notifyService, IRecentlyAdded recentlyAdded,
|
||||||
ISettingsService<WatcherSettings> watcherSettings ,
|
ISettingsService<WatcherSettings> watcherSettings ,
|
||||||
ISettingsService<DiscordNotificationSettings> discord,
|
ISettingsService<DiscordNotificationSettings> discord,
|
||||||
IDiscordApi discordapi
|
IDiscordApi discordapi, ISettingsService<RadarrSettings> settings, IRadarrApi radarrApi
|
||||||
, ISecurityExtensions security) : base("admin", prService, security)
|
, ISecurityExtensions security) : base("admin", prService, security)
|
||||||
{
|
{
|
||||||
PrService = prService;
|
PrService = prService;
|
||||||
|
@ -156,6 +158,8 @@ namespace Ombi.UI.Modules.Admin
|
||||||
WatcherSettings = watcherSettings;
|
WatcherSettings = watcherSettings;
|
||||||
DiscordSettings = discord;
|
DiscordSettings = discord;
|
||||||
DiscordApi = discordapi;
|
DiscordApi = discordapi;
|
||||||
|
RadarrSettings = settings;
|
||||||
|
RadarrApi = radarrApi;
|
||||||
|
|
||||||
Before += (ctx) => Security.AdminLoginRedirect(Permissions.Administrator, ctx);
|
Before += (ctx) => Security.AdminLoginRedirect(Permissions.Administrator, ctx);
|
||||||
|
|
||||||
|
@ -171,18 +175,22 @@ namespace Ombi.UI.Modules.Admin
|
||||||
Get["/getusers"] = _ => GetUsers();
|
Get["/getusers"] = _ => GetUsers();
|
||||||
|
|
||||||
Get["/couchpotato"] = _ => CouchPotato();
|
Get["/couchpotato"] = _ => CouchPotato();
|
||||||
Post["/couchpotato"] = _ => SaveCouchPotato();
|
Post["/couchpotato", true] = async (x, ct) => await SaveCouchPotato();
|
||||||
|
|
||||||
Get["/plex"] = _ => Plex();
|
Get["/plex"] = _ => Plex();
|
||||||
Post["/plex", true] = async (x, ct) => await SavePlex();
|
Post["/plex", true] = async (x, ct) => await SavePlex();
|
||||||
|
|
||||||
Get["/sonarr"] = _ => Sonarr();
|
Get["/sonarr"] = _ => Sonarr();
|
||||||
Post["/sonarr"] = _ => SaveSonarr();
|
Post["/sonarr"] = _ => SaveSonarr();
|
||||||
|
Post["/sonarrprofiles"] = _ => GetSonarrQualityProfiles();
|
||||||
|
|
||||||
|
Get["/radarr", true] = async (x, ct) => await Radarr();
|
||||||
|
Post["/radarr", true] = async (x, ct) => await SaveRadarr();
|
||||||
|
Post["/radarrprofiles"] = _ => GetRadarrQualityProfiles();
|
||||||
|
|
||||||
Get["/sickrage"] = _ => Sickrage();
|
Get["/sickrage"] = _ => Sickrage();
|
||||||
Post["/sickrage"] = _ => SaveSickrage();
|
Post["/sickrage"] = _ => SaveSickrage();
|
||||||
|
|
||||||
Post["/sonarrprofiles"] = _ => GetSonarrQualityProfiles();
|
|
||||||
Post["/cpprofiles", true] = async (x, ct) => await GetCpProfiles();
|
Post["/cpprofiles", true] = async (x, ct) => await GetCpProfiles();
|
||||||
Post["/cpapikey"] = x => GetCpApiKey();
|
Post["/cpapikey"] = x => GetCpApiKey();
|
||||||
|
|
||||||
|
@ -377,7 +385,7 @@ namespace Ombi.UI.Modules.Admin
|
||||||
return View["CouchPotato", settings];
|
return View["CouchPotato", settings];
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response SaveCouchPotato()
|
private async Task<Response> SaveCouchPotato()
|
||||||
{
|
{
|
||||||
var couchPotatoSettings = this.Bind<CouchPotatoSettings>();
|
var couchPotatoSettings = this.Bind<CouchPotatoSettings>();
|
||||||
var valid = this.Validate(couchPotatoSettings);
|
var valid = this.Validate(couchPotatoSettings);
|
||||||
|
@ -386,7 +394,7 @@ namespace Ombi.UI.Modules.Admin
|
||||||
return Response.AsJson(valid.SendJsonError());
|
return Response.AsJson(valid.SendJsonError());
|
||||||
}
|
}
|
||||||
|
|
||||||
var watcherSettings = WatcherSettings.GetSettings();
|
var watcherSettings = await WatcherSettings.GetSettingsAsync();
|
||||||
|
|
||||||
if (watcherSettings.Enabled)
|
if (watcherSettings.Enabled)
|
||||||
{
|
{
|
||||||
|
@ -398,8 +406,20 @@ namespace Ombi.UI.Modules.Admin
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var radarrSettings = await RadarrSettings.GetSettingsAsync();
|
||||||
|
|
||||||
|
if (radarrSettings.Enabled)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
Response.AsJson(new JsonResponseModel
|
||||||
|
{
|
||||||
|
Result = false,
|
||||||
|
Message = "Cannot have Radarr and CouchPotato both enabled."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
couchPotatoSettings.ApiKey = couchPotatoSettings.ApiKey.Trim();
|
couchPotatoSettings.ApiKey = couchPotatoSettings.ApiKey.Trim();
|
||||||
var result = CpService.SaveSettings(couchPotatoSettings);
|
var result = await CpService.SaveSettingsAsync(couchPotatoSettings);
|
||||||
return Response.AsJson(result
|
return Response.AsJson(result
|
||||||
? new JsonResponseModel { Result = true, Message = "Successfully Updated the Settings for CouchPotato!" }
|
? new JsonResponseModel { Result = true, Message = "Successfully Updated the Settings for CouchPotato!" }
|
||||||
: new JsonResponseModel { Result = false, Message = "Could not update the settings, take a look at the logs." });
|
: new JsonResponseModel { Result = false, Message = "Could not update the settings, take a look at the logs." });
|
||||||
|
@ -457,6 +477,7 @@ namespace Ombi.UI.Modules.Admin
|
||||||
{
|
{
|
||||||
return Response.AsJson(new JsonResponseModel { Result = false, Message = "SickRage is enabled, we cannot enable Sonarr and SickRage" });
|
return Response.AsJson(new JsonResponseModel { Result = false, Message = "SickRage is enabled, we cannot enable Sonarr and SickRage" });
|
||||||
}
|
}
|
||||||
|
|
||||||
sonarrSettings.ApiKey = sonarrSettings.ApiKey.Trim();
|
sonarrSettings.ApiKey = sonarrSettings.ApiKey.Trim();
|
||||||
var result = SonarrService.SaveSettings(sonarrSettings);
|
var result = SonarrService.SaveSettings(sonarrSettings);
|
||||||
|
|
||||||
|
@ -465,6 +486,58 @@ namespace Ombi.UI.Modules.Admin
|
||||||
: new JsonResponseModel { Result = false, Message = "Could not update the settings, take a look at the logs." });
|
: new JsonResponseModel { Result = false, Message = "Could not update the settings, take a look at the logs." });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<Negotiator> Radarr()
|
||||||
|
{
|
||||||
|
var settings = await RadarrSettings.GetSettingsAsync();
|
||||||
|
|
||||||
|
return View["Radarr", settings];
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<Response> SaveRadarr()
|
||||||
|
{
|
||||||
|
var radarrSettings = this.Bind<RadarrSettings>();
|
||||||
|
|
||||||
|
//Check Watcher and CP make sure they are not enabled
|
||||||
|
var watcher = await WatcherSettings.GetSettingsAsync();
|
||||||
|
if (watcher.Enabled)
|
||||||
|
{
|
||||||
|
return Response.AsJson(new JsonResponseModel { Result = false, Message = "Watcher is enabled, we cannot enable Watcher and Radarr" });
|
||||||
|
}
|
||||||
|
|
||||||
|
var cp = await CpService.GetSettingsAsync();
|
||||||
|
if (cp.Enabled)
|
||||||
|
{
|
||||||
|
return Response.AsJson(new JsonResponseModel { Result = false, Message = "CouchPotato is enabled, we cannot enable Watcher and CouchPotato" });
|
||||||
|
}
|
||||||
|
|
||||||
|
var valid = this.Validate(radarrSettings);
|
||||||
|
if (!valid.IsValid)
|
||||||
|
{
|
||||||
|
return Response.AsJson(valid.SendJsonError());
|
||||||
|
}
|
||||||
|
|
||||||
|
radarrSettings.ApiKey = radarrSettings.ApiKey.Trim();
|
||||||
|
var result = await RadarrSettings.SaveSettingsAsync(radarrSettings);
|
||||||
|
|
||||||
|
return Response.AsJson(result
|
||||||
|
? new JsonResponseModel { Result = true, Message = "Successfully Updated the Settings for Radarr!" }
|
||||||
|
: new JsonResponseModel { Result = false, Message = "Could not update the settings, take a look at the logs." });
|
||||||
|
}
|
||||||
|
|
||||||
|
private Response GetRadarrQualityProfiles()
|
||||||
|
{
|
||||||
|
var settings = this.Bind<RadarrSettings>();
|
||||||
|
var profiles = RadarrApi.GetProfiles(settings.ApiKey, settings.FullUri);
|
||||||
|
|
||||||
|
// set the cache
|
||||||
|
if (profiles != null)
|
||||||
|
{
|
||||||
|
Cache.Set(CacheKeys.RadarrQualityProfiles, profiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response.AsJson(profiles);
|
||||||
|
}
|
||||||
|
|
||||||
private Negotiator Sickrage()
|
private Negotiator Sickrage()
|
||||||
{
|
{
|
||||||
var settings = SickRageService.GetSettings();
|
var settings = SickRageService.GetSettings();
|
||||||
|
|
|
@ -97,6 +97,18 @@ namespace Ombi.UI.Modules.Admin
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var watcherSettings = await WatcherSettings.GetSettingsAsync();
|
||||||
|
|
||||||
|
if (watcherSettings.Enabled)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
Response.AsJson(new JsonResponseModel
|
||||||
|
{
|
||||||
|
Result = false,
|
||||||
|
Message = "Cannot have Watcher and CouchPotato both enabled."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
settings.ApiKey = settings.ApiKey.Trim();
|
settings.ApiKey = settings.ApiKey.Trim();
|
||||||
var result = await WatcherSettings.SaveSettingsAsync(settings);
|
var result = await WatcherSettings.SaveSettingsAsync(settings);
|
||||||
return Response.AsJson(result
|
return Response.AsJson(result
|
||||||
|
|
|
@ -46,7 +46,7 @@ namespace Ombi.UI.Modules
|
||||||
|
|
||||||
public ApplicationTesterModule(ICouchPotatoApi cpApi, ISonarrApi sonarrApi, IPlexApi plexApi,
|
public ApplicationTesterModule(ICouchPotatoApi cpApi, ISonarrApi sonarrApi, IPlexApi plexApi,
|
||||||
ISickRageApi srApi, IHeadphonesApi hpApi, ISettingsService<PlexRequestSettings> pr, ISecurityExtensions security,
|
ISickRageApi srApi, IHeadphonesApi hpApi, ISettingsService<PlexRequestSettings> pr, ISecurityExtensions security,
|
||||||
IWatcherApi watcherApi) : base("test", pr, security)
|
IWatcherApi watcherApi, IRadarrApi radarrApi) : base("test", pr, security)
|
||||||
{
|
{
|
||||||
this.RequiresAuthentication();
|
this.RequiresAuthentication();
|
||||||
|
|
||||||
|
@ -56,9 +56,11 @@ namespace Ombi.UI.Modules
|
||||||
SickRageApi = srApi;
|
SickRageApi = srApi;
|
||||||
HeadphonesApi = hpApi;
|
HeadphonesApi = hpApi;
|
||||||
WatcherApi = watcherApi;
|
WatcherApi = watcherApi;
|
||||||
|
RadarrApi = radarrApi;
|
||||||
|
|
||||||
Post["/cp"] = _ => CouchPotatoTest();
|
Post["/cp"] = _ => CouchPotatoTest();
|
||||||
Post["/sonarr"] = _ => SonarrTest();
|
Post["/sonarr"] = _ => SonarrTest();
|
||||||
|
Post["/radarr"] = _ => RadarrTest();
|
||||||
Post["/plex"] = _ => PlexTest();
|
Post["/plex"] = _ => PlexTest();
|
||||||
Post["/sickrage"] = _ => SickRageTest();
|
Post["/sickrage"] = _ => SickRageTest();
|
||||||
Post["/headphones"] = _ => HeadphonesTest();
|
Post["/headphones"] = _ => HeadphonesTest();
|
||||||
|
@ -73,6 +75,7 @@ namespace Ombi.UI.Modules
|
||||||
private ISickRageApi SickRageApi { get; }
|
private ISickRageApi SickRageApi { get; }
|
||||||
private IHeadphonesApi HeadphonesApi { get; }
|
private IHeadphonesApi HeadphonesApi { get; }
|
||||||
private IWatcherApi WatcherApi { get; }
|
private IWatcherApi WatcherApi { get; }
|
||||||
|
private IRadarrApi RadarrApi { get; }
|
||||||
|
|
||||||
private Response CouchPotatoTest()
|
private Response CouchPotatoTest()
|
||||||
{
|
{
|
||||||
|
@ -148,7 +151,7 @@ namespace Ombi.UI.Modules
|
||||||
: 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." });
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e) // Exceptions are expected, if we cannot connect so we will just log and swallow them.
|
catch (Exception e) // Exceptions are expected, if we cannot connect so we will just log and swallow them.
|
||||||
{
|
{
|
||||||
Log.Warn("Exception thrown when attempting to get Sonarr's status: ");
|
Log.Warn("Exception thrown when attempting to get Sonarr's status: ");
|
||||||
Log.Warn(e);
|
Log.Warn(e);
|
||||||
|
@ -161,6 +164,35 @@ namespace Ombi.UI.Modules
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Response RadarrTest()
|
||||||
|
{
|
||||||
|
var radarrSettings = this.Bind<RadarrSettings>();
|
||||||
|
var valid = this.Validate(radarrSettings);
|
||||||
|
if (!valid.IsValid)
|
||||||
|
{
|
||||||
|
return Response.AsJson(valid.SendJsonError());
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var status = RadarrApi.SystemStatus(radarrSettings.ApiKey, radarrSettings.FullUri);
|
||||||
|
return status?.version != null
|
||||||
|
? Response.AsJson(new JsonResponseModel { Result = true, Message = "Connected to Radarr successfully!" })
|
||||||
|
: Response.AsJson(new JsonResponseModel { Result = false, Message = "Could not connect to Radarr, please check your settings." });
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e) // Exceptions are expected, if we cannot connect so we will just log and swallow them.
|
||||||
|
{
|
||||||
|
Log.Warn("Exception thrown when attempting to get Radarr's status: ");
|
||||||
|
Log.Warn(e);
|
||||||
|
var message = $"Could not connect to Radarr, please check your settings. <strong>Exception Message:</strong> {e.Message}";
|
||||||
|
if (e.InnerException != null)
|
||||||
|
{
|
||||||
|
message = $"Could not connect to Radarr, please check your settings. <strong>Exception Message:</strong> {e.InnerException.Message}";
|
||||||
|
}
|
||||||
|
return Response.AsJson(new JsonResponseModel { Result = false, Message = message });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Response PlexTest()
|
private Response PlexTest()
|
||||||
{
|
{
|
||||||
var plexSettings = this.Bind<PlexSettings>();
|
var plexSettings = this.Bind<PlexSettings>();
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace Ombi.UI.Modules
|
||||||
return Response.AsJson(new { Result = false });
|
return Response.AsJson(new { Result = false });
|
||||||
}
|
}
|
||||||
|
|
||||||
return Response.AsJson(new { Result = true });
|
return Response.AsJson(new { Result = true, NetflixId = result.ShowId });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ namespace Ombi.UI.Modules
|
||||||
ISettingsService<PlexSettings> plexService, ISettingsService<AuthenticationSettings> auth,
|
ISettingsService<PlexSettings> plexService, ISettingsService<AuthenticationSettings> auth,
|
||||||
IRepository<UsersToNotify> u, ISettingsService<EmailNotificationSettings> email,
|
IRepository<UsersToNotify> u, ISettingsService<EmailNotificationSettings> email,
|
||||||
IIssueService issue, IAnalytics a, IRepository<RequestLimit> rl, ITransientFaultQueue tfQueue, IRepository<PlexContent> content,
|
IIssueService issue, IAnalytics a, IRepository<RequestLimit> rl, ITransientFaultQueue tfQueue, IRepository<PlexContent> content,
|
||||||
ISecurityExtensions security, IMovieSender movieSender)
|
ISecurityExtensions security, IMovieSender movieSender, IRadarrCacher radarrCacher)
|
||||||
: base("search", prSettings, security)
|
: base("search", prSettings, security)
|
||||||
{
|
{
|
||||||
Auth = auth;
|
Auth = auth;
|
||||||
|
@ -108,6 +108,7 @@ namespace Ombi.UI.Modules
|
||||||
PlexContentRepository = content;
|
PlexContentRepository = content;
|
||||||
MovieSender = movieSender;
|
MovieSender = movieSender;
|
||||||
WatcherCacher = watcherCacher;
|
WatcherCacher = watcherCacher;
|
||||||
|
RadarrCacher = radarrCacher;
|
||||||
|
|
||||||
Get["SearchIndex", "/", true] = async (x, ct) => await RequestLoad();
|
Get["SearchIndex", "/", true] = async (x, ct) => await RequestLoad();
|
||||||
|
|
||||||
|
@ -157,6 +158,7 @@ namespace Ombi.UI.Modules
|
||||||
private IAnalytics Analytics { get; }
|
private IAnalytics Analytics { get; }
|
||||||
private ITransientFaultQueue FaultQueue { get; }
|
private ITransientFaultQueue FaultQueue { get; }
|
||||||
private IRepository<RequestLimit> RequestLimitRepo { get; }
|
private IRepository<RequestLimit> RequestLimitRepo { get; }
|
||||||
|
private IRadarrCacher RadarrCacher { get; }
|
||||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
private async Task<Negotiator> RequestLoad()
|
private async Task<Negotiator> RequestLoad()
|
||||||
|
@ -236,6 +238,7 @@ namespace Ombi.UI.Modules
|
||||||
|
|
||||||
var cpCached = CpCacher.QueuedIds();
|
var cpCached = CpCacher.QueuedIds();
|
||||||
var watcherCached = WatcherCacher.QueuedIds();
|
var watcherCached = WatcherCacher.QueuedIds();
|
||||||
|
var radarrCached = RadarrCacher.QueuedIds();
|
||||||
var content = PlexContentRepository.GetAll();
|
var content = PlexContentRepository.GetAll();
|
||||||
var plexMovies = Checker.GetPlexMovies(content);
|
var plexMovies = Checker.GetPlexMovies(content);
|
||||||
var viewMovies = new List<SearchMovieViewModel>();
|
var viewMovies = new List<SearchMovieViewModel>();
|
||||||
|
@ -246,6 +249,7 @@ namespace Ombi.UI.Modules
|
||||||
if (counter <= 5) // Let's only do it for the first 5 items
|
if (counter <= 5) // Let's only do it for the first 5 items
|
||||||
{
|
{
|
||||||
var movieInfoTask = await MovieApi.GetMovieInformation(movie.Id).ConfigureAwait(false);
|
var movieInfoTask = await MovieApi.GetMovieInformation(movie.Id).ConfigureAwait(false);
|
||||||
|
|
||||||
// TODO needs to be careful about this, it's adding extra time to search...
|
// TODO needs to be careful about this, it's adding extra time to search...
|
||||||
// https://www.themoviedb.org/talk/5807f4cdc3a36812160041f2
|
// https://www.themoviedb.org/talk/5807f4cdc3a36812160041f2
|
||||||
imdbId = movieInfoTask?.ImdbId;
|
imdbId = movieInfoTask?.ImdbId;
|
||||||
|
@ -287,13 +291,19 @@ namespace Ombi.UI.Modules
|
||||||
}
|
}
|
||||||
else if (cpCached.Contains(movie.Id) && canSee) // compare to the couchpotato db
|
else if (cpCached.Contains(movie.Id) && canSee) // compare to the couchpotato db
|
||||||
{
|
{
|
||||||
|
viewMovie.Approved = true;
|
||||||
viewMovie.Requested = true;
|
viewMovie.Requested = true;
|
||||||
}
|
}
|
||||||
else if(watcherCached.Contains(imdbId) && canSee) // compare to the watcher db
|
else if(watcherCached.Contains(imdbId) && canSee) // compare to the watcher db
|
||||||
{
|
{
|
||||||
|
viewMovie.Approved = true;
|
||||||
|
viewMovie.Requested = true;
|
||||||
|
}
|
||||||
|
else if (radarrCached.Contains(movie.Id) && canSee)
|
||||||
|
{
|
||||||
|
viewMovie.Approved = true;
|
||||||
viewMovie.Requested = true;
|
viewMovie.Requested = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
viewMovies.Add(viewMovie);
|
viewMovies.Add(viewMovie);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,6 +355,10 @@ namespace Ombi.UI.Modules
|
||||||
var viewTv = new List<SearchTvShowViewModel>();
|
var viewTv = new List<SearchTvShowViewModel>();
|
||||||
foreach (var t in apiTv)
|
foreach (var t in apiTv)
|
||||||
{
|
{
|
||||||
|
if (!(t.show.externals?.thetvdb.HasValue) ?? false)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
var banner = t.show.image?.medium;
|
var banner = t.show.image?.medium;
|
||||||
if (!string.IsNullOrEmpty(banner))
|
if (!string.IsNullOrEmpty(banner))
|
||||||
{
|
{
|
||||||
|
|
|
@ -48,6 +48,7 @@ namespace Ombi.UI.NinjectModules
|
||||||
Bind<IWatcherApi>().To<WatcherApi>();
|
Bind<IWatcherApi>().To<WatcherApi>();
|
||||||
Bind<INetflixApi>().To<NetflixRouletteApi>();
|
Bind<INetflixApi>().To<NetflixRouletteApi>();
|
||||||
Bind<IDiscordApi>().To<DiscordApi>();
|
Bind<IDiscordApi>().To<DiscordApi>();
|
||||||
|
Bind<IRadarrApi>().To<RadarrApi>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -48,6 +48,7 @@ namespace Ombi.UI.NinjectModules
|
||||||
Bind<ISonarrCacher>().To<SonarrCacher>();
|
Bind<ISonarrCacher>().To<SonarrCacher>();
|
||||||
Bind<ISickRageCacher>().To<SickRageCacher>();
|
Bind<ISickRageCacher>().To<SickRageCacher>();
|
||||||
Bind<IRecentlyAdded>().To<RecentlyAdded>();
|
Bind<IRecentlyAdded>().To<RecentlyAdded>();
|
||||||
|
Bind<IRadarrCacher>().To<RadarrCacher>();
|
||||||
Bind<IPlexContentCacher>().To<PlexContentCacher>();
|
Bind<IPlexContentCacher>().To<PlexContentCacher>();
|
||||||
Bind<IJobFactory>().To<CustomJobFactory>();
|
Bind<IJobFactory>().To<CustomJobFactory>();
|
||||||
Bind<IMovieSender>().To<MovieSender>();
|
Bind<IMovieSender>().To<MovieSender>();
|
||||||
|
|
|
@ -288,6 +288,7 @@
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Start\StartupOptions.cs" />
|
<Compile Include="Start\StartupOptions.cs" />
|
||||||
<Compile Include="Start\UpdateValue.cs" />
|
<Compile Include="Start\UpdateValue.cs" />
|
||||||
|
<Compile Include="Validators\RadarrValidator.cs" />
|
||||||
<Compile Include="Validators\WatcherValidator.cs" />
|
<Compile Include="Validators\WatcherValidator.cs" />
|
||||||
<Compile Include="Validators\SlackSettingsValidator.cs" />
|
<Compile Include="Validators\SlackSettingsValidator.cs" />
|
||||||
<Compile Include="Validators\UserViewModelValidator.cs" />
|
<Compile Include="Validators\UserViewModelValidator.cs" />
|
||||||
|
@ -792,6 +793,9 @@
|
||||||
<Content Include="Views\Admin\DiscordNotification.cshtml">
|
<Content Include="Views\Admin\DiscordNotification.cshtml">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="Views\Admin\Radarr.cshtml">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
<None Include="Web.Debug.config">
|
<None Include="Web.Debug.config">
|
||||||
<DependentUpon>web.config</DependentUpon>
|
<DependentUpon>web.config</DependentUpon>
|
||||||
</None>
|
</None>
|
||||||
|
|
|
@ -124,6 +124,10 @@ namespace Ombi.UI
|
||||||
var slackService = container.Get<ISettingsService<SlackNotificationSettings>>();
|
var slackService = container.Get<ISettingsService<SlackNotificationSettings>>();
|
||||||
var slackSettings = slackService.GetSettings();
|
var slackSettings = slackService.GetSettings();
|
||||||
SubScribeOvserver(slackSettings, notificationService, new SlackNotification(container.Get<ISlackApi>(), slackService));
|
SubScribeOvserver(slackSettings, notificationService, new SlackNotification(container.Get<ISlackApi>(), slackService));
|
||||||
|
|
||||||
|
var discordSettings = container.Get<ISettingsService<DiscordNotificationSettings>>();
|
||||||
|
var discordService = discordSettings.GetSettings();
|
||||||
|
SubScribeOvserver(discordService, notificationService, new DiscordNotification(container.Get<IDiscordApi>(), discordSettings));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SubScribeOvserver<T>(T settings, INotificationService notificationService, INotification notification)
|
private void SubScribeOvserver<T>(T settings, INotificationService notificationService, INotification notification)
|
||||||
|
|
43
Ombi.UI/Validators/RadarrValidator.cs
Normal file
43
Ombi.UI/Validators/RadarrValidator.cs
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: SonarrValidator.cs
|
||||||
|
// Created By: Jamie Rees
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
// a copy of this software and associated documentation files (the
|
||||||
|
// "Software"), to deal in the Software without restriction, including
|
||||||
|
// without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
// permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
// the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be
|
||||||
|
// included in all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
// ************************************************************************/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using FluentValidation;
|
||||||
|
using Ombi.Core.SettingModels;
|
||||||
|
|
||||||
|
namespace Ombi.UI.Validators
|
||||||
|
{
|
||||||
|
public class RadarrValidator : AbstractValidator<RadarrSettings>
|
||||||
|
{
|
||||||
|
public RadarrValidator()
|
||||||
|
{
|
||||||
|
RuleFor(request => request.ApiKey).NotEmpty().WithMessage("You must specify a Api Key.");
|
||||||
|
RuleFor(request => request.Ip).NotEmpty().WithMessage("You must specify a IP/Host name.");
|
||||||
|
RuleFor(request => request.Port).NotEmpty().WithMessage("You must specify a Port.");
|
||||||
|
RuleFor(request => request.QualityProfile).NotEmpty().WithMessage("You must specify a Quality Profile.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
244
Ombi.UI/Views/Admin/Radarr.cshtml
Normal file
244
Ombi.UI/Views/Admin/Radarr.cshtml
Normal file
|
@ -0,0 +1,244 @@
|
||||||
|
@using Ombi.UI.Helpers
|
||||||
|
@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase<Ombi.Core.SettingModels.RadarrSettings>
|
||||||
|
@Html.Partial("Shared/Partial/_Sidebar")
|
||||||
|
@{
|
||||||
|
int port;
|
||||||
|
if (Model.Port == 0)
|
||||||
|
{
|
||||||
|
port = 7878;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
port = Model.Port;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<div class="col-sm-8 col-sm-push-1">
|
||||||
|
<form class="form-horizontal" method="POST" id="mainForm">
|
||||||
|
<fieldset>
|
||||||
|
<legend>Radarr Settings</legend>
|
||||||
|
@Html.Checkbox(Model.Enabled, "Enabled", "Enabled")
|
||||||
|
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Ip" class="control-label">Radarr Hostname or IP</label>
|
||||||
|
<div class="">
|
||||||
|
<input type="text" class="form-control form-control-custom " id="Ip" name="Ip" placeholder="localhost" value="@Model.Ip">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="portNumber" class="control-label">Port</label>
|
||||||
|
|
||||||
|
<div class="">
|
||||||
|
<input type="text" class="form-control form-control-custom " id="portNumber" name="Port" placeholder="Port Number" value="@port">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="ApiKey" class="control-label">Radarr API Key</label>
|
||||||
|
<div>
|
||||||
|
<input type="text" class="form-control form-control-custom " id="ApiKey" name="ApiKey" value="@Model.ApiKey">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@Html.Checkbox(Model.Ssl, "Ssl", "Ssl")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="SubDir" class="control-label">Radarr Base Url</label>
|
||||||
|
<div>
|
||||||
|
<input type="text" class="form-control form-control-custom " id="SubDir" name="SubDir" value="@Model.SubDir">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div>
|
||||||
|
<button type="submit" id="getProfiles" class="btn btn-primary-outline">Get Quality Profiles <div id="getSpinner"/></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="select" class="control-label">Quality Profiles</label>
|
||||||
|
<div id="profiles">
|
||||||
|
<select class="form-control form-control-custom" id="select"></select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="RootPath" class="control-label">Root save directory for TV shows</label>
|
||||||
|
<div>
|
||||||
|
<input type="text" class="form-control form-control-custom " placeholder="C:\Media\Tv" id="RootPath" name="RootPath" value="@Model.RootPath">
|
||||||
|
<label>Enter the root folder where movies are saved. For example <strong>C:\Media\TV</strong>.</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div>
|
||||||
|
<button id="testRadarr" type="button" class="btn btn-primary-outline">Test Connectivity <div id="spinner"/></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div>
|
||||||
|
<button id="save" type="submit" class="btn btn-primary-outline ">Submit</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(function () {
|
||||||
|
|
||||||
|
@if (!string.IsNullOrEmpty(Model.QualityProfile))
|
||||||
|
{
|
||||||
|
|
||||||
|
<text>
|
||||||
|
|
||||||
|
preLoad();
|
||||||
|
|
||||||
|
function preLoad() {
|
||||||
|
var qualitySelected = @Model.QualityProfile;
|
||||||
|
if (!qualitySelected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var $form = $("#mainForm");
|
||||||
|
$.ajax({
|
||||||
|
type: $form.prop("method"),
|
||||||
|
data: $form.serialize(),
|
||||||
|
url: "radarrprofiles",
|
||||||
|
dataType: "json",
|
||||||
|
success: function(response) {
|
||||||
|
response.forEach(function(result) {
|
||||||
|
if (result.id == qualitySelected) {
|
||||||
|
|
||||||
|
$("#select").append("<option selected='selected' value='" + result.id + "'>" + result.name + "</option>");
|
||||||
|
} else {
|
||||||
|
$("#select").append("<option value='" + result.id + "'>" + result.name + "</option>");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error: function(e) {
|
||||||
|
console.log(e);
|
||||||
|
generateNotify("Something went wrong!", "danger");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</text>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$('#save').click(function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var port = $('#portNumber').val();
|
||||||
|
if (isNaN(port)) {
|
||||||
|
generateNotify("You must specify a Port.", "warning");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var qualityProfile = $("#profiles option:selected").val();
|
||||||
|
|
||||||
|
var $form = $("#mainForm");
|
||||||
|
|
||||||
|
var data = $form.serialize();
|
||||||
|
data = data + "&qualityProfile=" + qualityProfile;
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: $form.prop("method"),
|
||||||
|
data: data,
|
||||||
|
url: $form.prop("action"),
|
||||||
|
dataType: "json",
|
||||||
|
success: function (response) {
|
||||||
|
if (response.result === true) {
|
||||||
|
generateNotify("Success!", "success");
|
||||||
|
} else {
|
||||||
|
generateNotify(response.message, "warning");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function (e) {
|
||||||
|
console.log(e);
|
||||||
|
generateNotify("Something went wrong!", "danger");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#getProfiles').click(function (e) {
|
||||||
|
|
||||||
|
$('#getSpinner').attr("class", "fa fa-spinner fa-spin");
|
||||||
|
e.preventDefault();
|
||||||
|
if (!$('#Ip').val()) {
|
||||||
|
generateNotify("Please enter a valid IP/Hostname.", "warning");
|
||||||
|
$('#getSpinner').attr("class", "fa fa-times");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!$('#portNumber').val()) {
|
||||||
|
generateNotify("Please enter a valid Port Number.", "warning");
|
||||||
|
$('#getSpinner').attr("class", "fa fa-times");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!$('#ApiKey').val()) {
|
||||||
|
generateNotify("Please enter a valid ApiKey.", "warning");
|
||||||
|
$('#getSpinner').attr("class", "fa fa-times");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var $form = $("#mainForm");
|
||||||
|
$.ajax({
|
||||||
|
type: $form.prop("method"),
|
||||||
|
data: $form.serialize(),
|
||||||
|
url: "radarrprofiles",
|
||||||
|
dataType: "json",
|
||||||
|
success: function (response) {
|
||||||
|
response.forEach(function (result) {
|
||||||
|
$('#getSpinner').attr("class", "fa fa-check");
|
||||||
|
$("#select").append("<option value='" + result.id + "'>" + result.name + "</option>");
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error: function (e) {
|
||||||
|
console.log(e);
|
||||||
|
$('#getSpinner').attr("class", "fa fa-times");
|
||||||
|
generateNotify("Something went wrong!", "danger");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
var base = '@Html.GetBaseUrl()';
|
||||||
|
$('#testRadarr').click(function (e) {
|
||||||
|
|
||||||
|
$('#spinner').attr("class", "fa fa-spinner fa-spin");
|
||||||
|
e.preventDefault();
|
||||||
|
var qualityProfile = $("#profiles option:selected").val();
|
||||||
|
|
||||||
|
var $form = $("#mainForm");
|
||||||
|
|
||||||
|
var data = $form.serialize();
|
||||||
|
data = data + "&qualityProfile=" + qualityProfile;
|
||||||
|
|
||||||
|
var url = createBaseUrl(base, '/test/radarr');
|
||||||
|
$.ajax({
|
||||||
|
type: $form.prop("method"),
|
||||||
|
url: url,
|
||||||
|
data: data,
|
||||||
|
dataType: "json",
|
||||||
|
success: function (response) {
|
||||||
|
console.log(response);
|
||||||
|
if (response.result === true) {
|
||||||
|
generateNotify(response.message, "success");
|
||||||
|
$('#spinner').attr("class", "fa fa-check");
|
||||||
|
} else {
|
||||||
|
generateNotify(response.message, "warning");
|
||||||
|
$('#spinner').attr("class", "fa fa-times");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function (e) {
|
||||||
|
console.log(e);
|
||||||
|
generateNotify("Something went wrong!", "danger");
|
||||||
|
$('#spinner').attr("class", "fa fa-times");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
</script>
|
|
@ -45,6 +45,14 @@
|
||||||
<label for="CouchPotatoCacher" class="control-label">Couch Potato Cacher (min)</label>
|
<label for="CouchPotatoCacher" class="control-label">Couch Potato Cacher (min)</label>
|
||||||
<input type="text" class="form-control form-control-custom " id="CouchPotatoCacher" name="CouchPotatoCacher" value="@Model.CouchPotatoCacher">
|
<input type="text" class="form-control form-control-custom " id="CouchPotatoCacher" name="CouchPotatoCacher" value="@Model.CouchPotatoCacher">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="WatcherCacher" class="control-label">Wactcher Cacher (min)</label>
|
||||||
|
<input type="text" class="form-control form-control-custom " id="WatcherCacher" name="WatcherCacher" value="@Model.WatcherCacher">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="RadarrCacher" class="control-label">Radarr Cacher (min)</label>
|
||||||
|
<input type="text" class="form-control form-control-custom " id="RadarrCacher" name="RadarrCacher" value="@Model.RadarrCacher">
|
||||||
|
</div>
|
||||||
|
|
||||||
<small>Please note, the minimum time for this to run is 11 hours, if set below 11 then we will ignore that value. This is a very resource intensive job, the less we run it the better.</small>
|
<small>Please note, the minimum time for this to run is 11 hours, if set below 11 then we will ignore that value. This is a very resource intensive job, the less we run it the better.</small>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
@Html.GetSidebarUrl(Context, "/admin/plex", "Plex")
|
@Html.GetSidebarUrl(Context, "/admin/plex", "Plex")
|
||||||
@Html.GetSidebarUrl(Context, "/admin/couchpotato", "CouchPotato")
|
@Html.GetSidebarUrl(Context, "/admin/couchpotato", "CouchPotato")
|
||||||
@Html.GetSidebarUrl(Context, "/admin/watcher", "Watcher (beta)")
|
@Html.GetSidebarUrl(Context, "/admin/watcher", "Watcher (beta)")
|
||||||
|
@Html.GetSidebarUrl(Context, "/admin/radarr", "Radarr (beta)")
|
||||||
@Html.GetSidebarUrl(Context, "/admin/sonarr", "Sonarr")
|
@Html.GetSidebarUrl(Context, "/admin/sonarr", "Sonarr")
|
||||||
@Html.GetSidebarUrl(Context, "/admin/sickrage", "SickRage")
|
@Html.GetSidebarUrl(Context, "/admin/sickrage", "SickRage")
|
||||||
@Html.GetSidebarUrl(Context, "/admin/headphones", "Headphones (beta)")
|
@Html.GetSidebarUrl(Context, "/admin/headphones", "Headphones (beta)")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue