Sickrage done. Ish... So i've written all the code by looking at the API. the key there is i've looked at the api. I have not tested anything so expect this to fail.

pull/1741/head
Jamie 7 years ago
parent 62a3ed924b
commit a1ee52daef

@ -6,12 +6,14 @@ namespace Ombi.Api.SickRage
public interface ISickRageApi public interface ISickRageApi
{ {
Task<SickRageTvAdd> AddSeason(int tvdbId, int season, string apiKey, string baseUrl); Task<SickRageTvAdd> AddSeason(int tvdbId, int season, string apiKey, string baseUrl);
Task<SickRageTvAdd> AddSeries(int tvdbId, int seasonCount, int[] seasons, string quality, string apiKey, string baseUrl); Task<SickRageTvAdd> AddSeries(int tvdbId, string quality, string status, string apiKey, string baseUrl);
Task<SickRageShows> GetShows(string apiKey, string baseUrl); Task<SickRageShows> GetShows(string apiKey, string baseUrl);
Task<SickRagePing> Ping(string apiKey, string baseUrl); Task<SickRagePing> Ping(string apiKey, string baseUrl);
Task<SickRageSeasonList> VerifyShowHasLoaded(int tvdbId, string apiKey, string baseUrl); Task<SickRageSeasonList> VerifyShowHasLoaded(int tvdbId, string apiKey, string baseUrl);
Task<SickRageShowInformation> GetShow(int tvdbid, string apikey, string baseUrl);
Task<SickRageEpisodeStatus> SetEpisodeStatus(string apiKey, string baseUrl, int tvdbid, string status, Task<SickRageEpisodeStatus> SetEpisodeStatus(string apiKey, string baseUrl, int tvdbid, string status,
int season, int episode = -1); int season, int episode = -1);
Task<SickRageEpisodes> GetEpisodesForSeason(int tvdbid, int season, string apikey, string baseUrl);
Task<SeasonList> GetSeasonList(int tvdbId, string apikey, string baseurl);
} }
} }

@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace Ombi.Api.SickRage.Models
{
public class SeasonList : SickRageBase<List<int>>
{
}
}

@ -0,0 +1,18 @@
using System.Collections.Generic;
namespace Ombi.Api.SickRage.Models
{
public class SickRageEpisodes : SickRageBase<Dictionary<int, SickRageEpisodesData>>
{
}
public class SickRageEpisodesData
{
public string airdate { get; set; }
public string name { get; set; }
public string quality { get; set; }
public string status { get; set; }
}
}

@ -0,0 +1,41 @@
namespace Ombi.Api.SickRage.Models
{
public class SickRageShowInformation : SickRageBase<SickRageShowInformationData>
{
}
public class SickRageShowInformationData
{
public int air_by_date { get; set; }
public string airs { get; set; }
public Cache cache { get; set; }
public int flatten_folders { get; set; }
public string[] genre { get; set; }
public string language { get; set; }
public string location { get; set; }
public string network { get; set; }
public string next_ep_airdate { get; set; }
public int paused { get; set; }
public string quality { get; set; }
public Quality_Details quality_details { get; set; }
public int[] season_list { get; set; }
public string show_name { get; set; }
public string status { get; set; }
public int tvrage_id { get; set; }
public string tvrage_name { get; set; }
}
public class Cache
{
public int banner { get; set; }
public int poster { get; set; }
}
public class Quality_Details
{
public object[] archive { get; set; }
public string[] initial { get; set; }
}
}

@ -1,6 +1,4 @@
using System; using System;
using System.Diagnostics;
using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -27,15 +25,12 @@ namespace Ombi.Api.SickRage
return await _api.Request<SickRageSeasonList>(request); return await _api.Request<SickRageSeasonList>(request);
} }
public async Task<SickRageTvAdd> AddSeries(int tvdbId, int seasonCount, int[] seasons, string quality, string apiKey, string baseUrl) public async Task<SickRageTvAdd> AddSeries(int tvdbId, string quality, string status, string apiKey, string baseUrl)
{ {
var futureStatus = seasons.Length > 0 && seasons.All(x => x != seasonCount) ? SickRageStatus.Skipped : SickRageStatus.Wanted;
var status = seasons.Length > 0 ? SickRageStatus.Skipped : SickRageStatus.Wanted;
var request = new Request($"/api/{apiKey}/?cmd=show.addnew", baseUrl, HttpMethod.Get); var request = new Request($"/api/{apiKey}/?cmd=show.addnew", baseUrl, HttpMethod.Get);
request.AddQueryString("tvdbid", tvdbId.ToString()); request.AddQueryString("tvdbid", tvdbId.ToString());
request.AddQueryString("status", status); request.AddQueryString("status", status);
request.AddQueryString("future_status", futureStatus);
if (!quality.Equals("default", StringComparison.CurrentCultureIgnoreCase)) if (!quality.Equals("default", StringComparison.CurrentCultureIgnoreCase))
{ {
@ -44,55 +39,6 @@ namespace Ombi.Api.SickRage
var obj = await _api.Request<SickRageTvAdd>(request); var obj = await _api.Request<SickRageTvAdd>(request);
if (obj.result != "failure")
{
var sw = new Stopwatch();
sw.Start();
var seasonIncrement = 0;
try
{
while (seasonIncrement < seasonCount)
{
var seasonList = await VerifyShowHasLoaded(tvdbId, apiKey, baseUrl);
if (seasonList.result.Equals("failure"))
{
await Task.Delay(3000);
continue;
}
seasonIncrement = seasonList.Data?.Length ?? 0;
if (sw.ElapsedMilliseconds > 30000) // Break out after 30 seconds, it's not going to get added
{
_log.LogWarning("Couldn't find out if the show had been added after 10 seconds. I doubt we can change the status to wanted.");
break;
}
}
sw.Stop();
}
catch (Exception e)
{
_log.LogCritical(e, "Exception thrown when getting the seasonList");
}
}
try
{
if (seasons.Length > 0)
{
//handle the seasons requested
foreach (var s in seasons)
{
var result = await AddSeason(tvdbId, s, apiKey, baseUrl);
}
}
}
catch (Exception e)
{
_log.LogCritical(e, "Exception when adding seasons:");
throw;
}
return obj; return obj;
} }
@ -113,6 +59,23 @@ namespace Ombi.Api.SickRage
return await _api.Request<SickRageShows>(request); return await _api.Request<SickRageShows>(request);
} }
public async Task<SickRageShowInformation> GetShow(int tvdbid, string apikey, string baseUrl)
{
var request = new Request($"/api/{apikey}/?cmd=show", baseUrl, HttpMethod.Get);
request.AddQueryString("tvdbid", tvdbid.ToString());
return await _api.Request<SickRageShowInformation>(request);
}
public async Task<SickRageEpisodes> GetEpisodesForSeason(int tvdbid, int season, string apikey, string baseUrl)
{
var request = new Request($"/api/{apikey}/?cmd=show.seasons", baseUrl, HttpMethod.Get);
request.AddQueryString("tvdbid", tvdbid.ToString());
request.AddQueryString("season", season.ToString());
return await _api.Request<SickRageEpisodes>(request);
}
public async Task<SickRagePing> Ping(string apiKey, string baseUrl) public async Task<SickRagePing> Ping(string apiKey, string baseUrl)
{ {
var request = new Request($"/api/{apiKey}/?cmd=sb.ping", baseUrl, HttpMethod.Get); var request = new Request($"/api/{apiKey}/?cmd=sb.ping", baseUrl, HttpMethod.Get);
@ -139,5 +102,13 @@ namespace Ombi.Api.SickRage
return await _api.Request<SickRageEpisodeStatus>(request); return await _api.Request<SickRageEpisodeStatus>(request);
} }
public async Task<SeasonList> GetSeasonList(int tvdbId, string apikey, string baseurl)
{
var request = new Request($"/api/{apikey}/?cmd=show.seasonlist", baseurl, HttpMethod.Get);
request.AddQueryString("tvdbid", tvdbId.ToString());
return await _api.Request<SeasonList>(request);
}
} }
} }

@ -6,6 +6,7 @@ using Microsoft.Extensions.Logging;
using Ombi.Api.DogNzb; using Ombi.Api.DogNzb;
using Ombi.Api.DogNzb.Models; using Ombi.Api.DogNzb.Models;
using Ombi.Api.SickRage; using Ombi.Api.SickRage;
using Ombi.Api.SickRage.Models;
using Ombi.Api.Sonarr; using Ombi.Api.Sonarr;
using Ombi.Api.Sonarr.Models; using Ombi.Api.Sonarr.Models;
using Ombi.Core.Settings; using Ombi.Core.Settings;
@ -70,6 +71,20 @@ namespace Ombi.Core.Senders
Message = result.ErrorMessage Message = result.ErrorMessage
}; };
} }
var sr = await SickRageSettings.GetSettingsAsync();
if (sr.Enabled)
{
var result = await SendToSickRage(model, sr);
if (result)
{
return new SenderResult
{
Sent = true,
Success = true
};
}
return new SenderResult();
}
return new SenderResult return new SenderResult
{ {
Success = true Success = true
@ -246,24 +261,64 @@ namespace Ombi.Core.Senders
} }
} }
public async Task SendToSickRage(ChildRequests model, string qualityId = null) private async Task<bool> SendToSickRage(ChildRequests model, SickRageSettings settings, string qualityId = null)
{ {
var settings = await SickRageSettings.GetSettingsAsync(); var tvdbid = model.ParentRequest.TvDbId;
if (qualityId.HasValue()) if (qualityId.HasValue()) { var id = qualityId; if (settings.Qualities.All(x => x.Value != id)) { qualityId = settings.QualityProfile; } }
// Check if the show exists
var existingShow = await SickRageApi.GetShow(tvdbid, settings.ApiKey, settings.FullUri);
if (existingShow == null)
{ {
if (settings.Qualities.All(x => x.Key != qualityId)) var addResult = await SickRageApi.AddSeries(model.ParentRequest.TvDbId, SickRageStatus.Wanted,
qualityId,
settings.ApiKey, settings.FullUri);
Logger.LogDebug("Added the show (tvdbid) {0}. The result is '{2}' : '{3}'", tvdbid, addResult.result, addResult.message);
if (addResult.result.Equals("failure"))
{ {
qualityId = settings.QualityProfile; // Do something
return false;
} }
} }
//var apiResult = SickRageApi.AddSeries(model.ParentRequest.TvDbId, model.SeasonCount, model.SeasonList, qualityId, foreach (var seasonRequests in model.SeasonRequests)
// sickRageSettings.ApiKey, sickRageSettings.FullUri); {
var srEpisodes = await SickRageApi.GetEpisodesForSeason(tvdbid, seasonRequests.SeasonNumber, settings.ApiKey, settings.FullUri);
var totalSrEpisodes = srEpisodes.data.Count;
//var result = apiResult.Result; if (totalSrEpisodes == seasonRequests.Episodes.Count)
{
// This is a request for the whole season
var wholeSeasonResult = await SickRageApi.SetEpisodeStatus(settings.ApiKey, settings.FullUri, tvdbid, SickRageStatus.Wanted,
seasonRequests.SeasonNumber);
Logger.LogDebug("Set the status to Wanted for season {0}. The result is '{1}' : '{2}'", seasonRequests.SeasonNumber, wholeSeasonResult.result, wholeSeasonResult.message);
continue;
}
foreach (var srEp in srEpisodes.data)
{
var epNumber = srEp.Key;
var epData = srEp.Value;
//return result; var epRequest = seasonRequests.Episodes.FirstOrDefault(x => x.EpisodeNumber == epNumber);
if (epRequest != null)
{
// We want to monior this episode since we have a request for it
// Let's check to see if it's wanted first, save an api call
if (epData.status.Equals(SickRageStatus.Wanted, StringComparison.CurrentCultureIgnoreCase))
{
continue;
}
var epResult = await SickRageApi.SetEpisodeStatus(settings.ApiKey, settings.FullUri, tvdbid,
SickRageStatus.Wanted, seasonRequests.SeasonNumber, epNumber);
Logger.LogDebug("Set the status to Wanted for Episode {0} in season {1}. The result is '{2}' : '{3}'", seasonRequests.SeasonNumber, epNumber, epResult.result, epResult.message);
}
}
}
return true;
} }
private async Task SearchForRequest(ChildRequests model, IEnumerable<Episode> sonarrEpList, SonarrSeries existingSeries, SonarrSettings s, private async Task SearchForRequest(ChildRequests model, IEnumerable<Episode> sonarrEpList, SonarrSeries existingSeries, SonarrSettings s,

@ -19,6 +19,7 @@ namespace Ombi.Helpers
public static EventId SonarrCacher => new EventId(2006); public static EventId SonarrCacher => new EventId(2006);
public static EventId CouchPotatoCacher => new EventId(2007); public static EventId CouchPotatoCacher => new EventId(2007);
public static EventId PlexContentCacher => new EventId(2008); public static EventId PlexContentCacher => new EventId(2008);
public static EventId SickRageCacher => new EventId(2009);
public static EventId MovieSender => new EventId(3000); public static EventId MovieSender => new EventId(3000);

@ -6,6 +6,7 @@ using Ombi.Schedule.Jobs.Emby;
using Ombi.Schedule.Jobs.Ombi; using Ombi.Schedule.Jobs.Ombi;
using Ombi.Schedule.Jobs.Plex; using Ombi.Schedule.Jobs.Plex;
using Ombi.Schedule.Jobs.Radarr; using Ombi.Schedule.Jobs.Radarr;
using Ombi.Schedule.Jobs.SickRage;
using Ombi.Schedule.Jobs.Sonarr; using Ombi.Schedule.Jobs.Sonarr;
using Ombi.Settings.Settings.Models; using Ombi.Settings.Settings.Models;
@ -16,7 +17,7 @@ namespace Ombi.Schedule
public JobSetup(IPlexContentSync plexContentSync, IRadarrSync radarrSync, public JobSetup(IPlexContentSync plexContentSync, IRadarrSync radarrSync,
IOmbiAutomaticUpdater updater, IEmbyContentSync embySync, IPlexUserImporter userImporter, IOmbiAutomaticUpdater updater, IEmbyContentSync embySync, IPlexUserImporter userImporter,
IEmbyUserImporter embyUserImporter, ISonarrSync cache, ICouchPotatoSync cpCache, IEmbyUserImporter embyUserImporter, ISonarrSync cache, ICouchPotatoSync cpCache,
ISettingsService<JobSettings> jobsettings) ISettingsService<JobSettings> jobsettings, ISickRageSync srSync)
{ {
PlexContentSync = plexContentSync; PlexContentSync = plexContentSync;
RadarrSync = radarrSync; RadarrSync = radarrSync;
@ -37,6 +38,7 @@ namespace Ombi.Schedule
private IEmbyUserImporter EmbyUserImporter { get; } private IEmbyUserImporter EmbyUserImporter { get; }
private ISonarrSync SonarrSync { get; } private ISonarrSync SonarrSync { get; }
private ICouchPotatoSync CpCache { get; } private ICouchPotatoSync CpCache { get; }
private ISickRageSync SrSync { get; }
private ISettingsService<JobSettings> JobSettings { get; set; } private ISettingsService<JobSettings> JobSettings { get; set; }
public void Setup() public void Setup()
@ -48,6 +50,7 @@ namespace Ombi.Schedule
RecurringJob.AddOrUpdate(() => RadarrSync.CacheContent(), JobSettingsHelper.Radarr(s)); RecurringJob.AddOrUpdate(() => RadarrSync.CacheContent(), JobSettingsHelper.Radarr(s));
RecurringJob.AddOrUpdate(() => PlexContentSync.CacheContent(), JobSettingsHelper.PlexContent(s)); RecurringJob.AddOrUpdate(() => PlexContentSync.CacheContent(), JobSettingsHelper.PlexContent(s));
RecurringJob.AddOrUpdate(() => CpCache.Start(), JobSettingsHelper.CouchPotato(s)); RecurringJob.AddOrUpdate(() => CpCache.Start(), JobSettingsHelper.CouchPotato(s));
RecurringJob.AddOrUpdate(() => SrSync.Start(), JobSettingsHelper.SickRageSync(s));
RecurringJob.AddOrUpdate(() => Updater.Update(null), JobSettingsHelper.Updater(s)); RecurringJob.AddOrUpdate(() => Updater.Update(null), JobSettingsHelper.Updater(s));

@ -0,0 +1,9 @@
using System.Threading.Tasks;
namespace Ombi.Schedule.Jobs.SickRage
{
public interface ISickRageSync
{
Task Start();
}
}

@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Ombi.Api.SickRage;
using Ombi.Api.SickRage.Models;
using Ombi.Core.Settings;
using Ombi.Helpers;
using Ombi.Settings.Settings.Models.External;
using Ombi.Store.Context;
using Ombi.Store.Entities;
namespace Ombi.Schedule.Jobs.SickRage
{
public class SickRageSync : ISickRageSync
{
public SickRageSync(ISettingsService<SickRageSettings> s, ISickRageApi api, ILogger<SickRageSync> l, IOmbiContext ctx)
{
_settings = s;
_api = api;
_log = l;
_ctx = ctx;
_settings.ClearCache();
}
private readonly ISettingsService<SickRageSettings> _settings;
private readonly ISickRageApi _api;
private readonly ILogger<SickRageSync> _log;
private readonly IOmbiContext _ctx;
private static readonly SemaphoreSlim SemaphoreSlim = new SemaphoreSlim(1, 1);
public async Task Start()
{
await SemaphoreSlim.WaitAsync();
try
{
var settings = await _settings.GetSettingsAsync();
if (!settings.Enabled)
{
return;
}
var shows = await _api.GetShows(settings.ApiKey, settings.FullUri);
if (shows != null)
{
var srShows = shows.data.Values;
var ids = srShows.Select(x => x.tvdbid);
await _ctx.Database.ExecuteSqlCommandAsync("DELETE FROM SickRageCache");
var entites = ids.Select(id => new SickRageCache { TvDbId = id }).ToList();
await _ctx.SickRageCache.AddRangeAsync(entites);
var episodesToAdd = new List<SickRageEpisodeCache>();
await _ctx.Database.ExecuteSqlCommandAsync("DELETE FROM SickRageEpisodeCache");
foreach (var s in srShows)
{
var seasons = await _api.GetSeasonList(s.tvdbid, settings.ApiKey, settings.FullUri);
foreach (var season in seasons.data)
{
var episodes =
await _api.GetEpisodesForSeason(s.tvdbid, season, settings.ApiKey, settings.FullUri);
var monitoredEpisodes = episodes.data.Where(x => x.Value.status.Equals(SickRageStatus.Wanted));
episodesToAdd.AddRange(monitoredEpisodes.Select(episode => new SickRageEpisodeCache
{
EpisodeNumber = episode.Key,
SeasonNumber = season,
TvDbId = s.tvdbid
}));
}
}
await _ctx.SickRageEpisodeCache.AddRangeAsync(episodesToAdd);
await _ctx.SaveChangesAsync();
}
}
catch (Exception e)
{
_log.LogError(LoggingEvents.SickRageCacher, e, "Exception when trying to cache SickRage");
}
finally
{
SemaphoreSlim.Release();
}
}
}
}

@ -27,6 +27,7 @@
<ProjectReference Include="..\Ombi.Api.Plex\Ombi.Api.Plex.csproj" /> <ProjectReference Include="..\Ombi.Api.Plex\Ombi.Api.Plex.csproj" />
<ProjectReference Include="..\Ombi.Api.Radarr\Ombi.Api.Radarr.csproj" /> <ProjectReference Include="..\Ombi.Api.Radarr\Ombi.Api.Radarr.csproj" />
<ProjectReference Include="..\Ombi.Api.Service\Ombi.Api.Service.csproj" /> <ProjectReference Include="..\Ombi.Api.Service\Ombi.Api.Service.csproj" />
<ProjectReference Include="..\Ombi.Api.SickRage\Ombi.Api.SickRage.csproj" />
<ProjectReference Include="..\Ombi.Api.Sonarr\Ombi.Api.Sonarr.csproj" /> <ProjectReference Include="..\Ombi.Api.Sonarr\Ombi.Api.Sonarr.csproj" />
<ProjectReference Include="..\Ombi.Notifications\Ombi.Notifications.csproj" /> <ProjectReference Include="..\Ombi.Notifications\Ombi.Notifications.csproj" />
<ProjectReference Include="..\Ombi.Settings\Ombi.Settings.csproj" /> <ProjectReference Include="..\Ombi.Settings\Ombi.Settings.csproj" />

@ -1,5 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
using Newtonsoft.Json;
namespace Ombi.Settings.Settings.Models.External namespace Ombi.Settings.Settings.Models.External
{ {
@ -9,18 +8,33 @@ namespace Ombi.Settings.Settings.Models.External
public string ApiKey { get; set; } public string ApiKey { get; set; }
public string QualityProfile { get; set; } public string QualityProfile { get; set; }
[JsonIgnore] public List<DropDownModel> Qualities => new List<DropDownModel>
public Dictionary<string, string> Qualities => new Dictionary<string, string>
{ {
{ "default", "Use Default" }, new DropDownModel("default", "Use Default"),
{ "sdtv", "SD TV" }, new DropDownModel("sdtv", "SD TV"),
{ "sddvd", "SD DVD" }, new DropDownModel("sddvd", "SD DVD"),
{ "hdtv", "HD TV" }, new DropDownModel("hdtv", "HD TV"),
{ "rawhdtv", "Raw HD TV" }, new DropDownModel("rawhdtv", "Raw HD TV"),
{ "hdwebdl", "HD Web DL" }, new DropDownModel("hdwebdl", "HD Web DL"),
{ "fullhdwebdl", "Full HD Web DL" }, new DropDownModel("fullhdwebdl", "Full HD Web DL"),
{ "hdbluray", "HD Bluray" }, new DropDownModel("hdbluray", "HD Bluray"),
{ "fullhdbluray", "Full HD Bluray" } new DropDownModel("fullhdbluray", "Full HD Bluray"),
}; };
} }
public class DropDownModel
{
public DropDownModel(string val, string display)
{
Value = val;
Display = display;
}
public DropDownModel()
{
}
public string Value { get; set; }
public string Display { get; set; }
}
} }

@ -9,5 +9,6 @@
public string CouchPotatoSync { get; set; } public string CouchPotatoSync { get; set; }
public string AutomaticUpdater { get; set; } public string AutomaticUpdater { get; set; }
public string UserImporter { get; set; } public string UserImporter { get; set; }
public string SickRageSync { get; set; }
} }
} }

@ -35,6 +35,10 @@ namespace Ombi.Settings.Settings.Models
{ {
return Get(s.UserImporter, Cron.Daily()); return Get(s.UserImporter, Cron.Daily());
} }
public static string SickRageSync(JobSettings s)
{
return Get(s.SickRageSync, Cron.Hourly(35));
}
private static string Get(string settings, string defaultCron) private static string Get(string settings, string defaultCron)

@ -38,5 +38,7 @@ namespace Ombi.Store.Context
EntityEntry Update(object entity); EntityEntry Update(object entity);
EntityEntry<TEntity> Update<TEntity>(TEntity entity) where TEntity : class; EntityEntry<TEntity> Update<TEntity>(TEntity entity) where TEntity : class;
DbSet<CouchPotatoCache> CouchPotatoCache { get; set; } DbSet<CouchPotatoCache> CouchPotatoCache { get; set; }
DbSet<SickRageCache> SickRageCache { get; set; }
DbSet<SickRageEpisodeCache> SickRageEpisodeCache { get; set; }
} }
} }

@ -40,6 +40,8 @@ namespace Ombi.Store.Context
public DbSet<Tokens> Tokens { get; set; } public DbSet<Tokens> Tokens { get; set; }
public DbSet<SonarrCache> SonarrCache { get; set; } public DbSet<SonarrCache> SonarrCache { get; set; }
public DbSet<SonarrEpisodeCache> SonarrEpisodeCache { get; set; } public DbSet<SonarrEpisodeCache> SonarrEpisodeCache { get; set; }
public DbSet<SickRageCache> SickRageCache { get; set; }
public DbSet<SickRageEpisodeCache> SickRageEpisodeCache { get; set; }
public DbSet<ApplicationConfiguration> ApplicationConfigurations { get; set; } public DbSet<ApplicationConfiguration> ApplicationConfigurations { get; set; }

@ -0,0 +1,10 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace Ombi.Store.Entities
{
[Table("SickRageCache")]
public class SickRageCache : Entity
{
public int TvDbId { get; set; }
}
}

@ -0,0 +1,12 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace Ombi.Store.Entities
{
[Table("SickRageEpisodeCache")]
public class SickRageEpisodeCache : Entity
{
public int SeasonNumber { get; set; }
public int EpisodeNumber { get; set; }
public int TvDbId { get; set; }
}
}

@ -26,7 +26,3 @@ export interface IUsersModel {
id: string; id: string;
username: string; username: string;
} }
export interface IDictionary<T> {
[Key: string]: T;
}

@ -1,4 +1,4 @@
import { IDictionary, ISettings } from "./ICommon"; import { ISettings } from "./ICommon";
export interface IExternalSettings extends ISettings { export interface IExternalSettings extends ISettings {
ssl: boolean; ssl: boolean;
@ -115,6 +115,7 @@ export interface IJobSettings {
couchPotatoSync: string; couchPotatoSync: string;
automaticUpdater: string; automaticUpdater: string;
userImporter: string; userImporter: string;
sickRageSync: string;
} }
export interface IAuthenticationSettings extends ISettings { export interface IAuthenticationSettings extends ISettings {
@ -158,7 +159,12 @@ export interface ISickRageSettings extends IExternalSettings {
enabled: boolean; enabled: boolean;
apiKey: string; apiKey: string;
qualityProfile: string; qualityProfile: string;
qualities: IDictionary<string>; qualities: IDropDownModel[];
}
export interface IDropDownModel {
value: string;
display: string;
} }
export interface IDogNzbSettings extends ISettings { export interface IDogNzbSettings extends ISettings {

@ -13,6 +13,11 @@
<input type="text" class="form-control form-control-custom" [ngClass]="{'form-error': form.get('sonarrSync').hasError('required')}" id="sonarrSync" name="sonarrSync" formControlName="sonarrSync"> <input type="text" class="form-control form-control-custom" [ngClass]="{'form-error': form.get('sonarrSync').hasError('required')}" id="sonarrSync" name="sonarrSync" formControlName="sonarrSync">
<small *ngIf="form.get('sonarrSync').hasError('required')" class="error-text">The Sonarr Sync is required</small> <small *ngIf="form.get('sonarrSync').hasError('required')" class="error-text">The Sonarr Sync is required</small>
</div> </div>
<div class="form-group">
<label for="sickRageSync" class="control-label">SickRage Sync</label>
<input type="text" class="form-control form-control-custom" [ngClass]="{'form-error': form.get('sonarrSync').hasError('required')}" id="sickRageSync" name="sickRageSync" formControlName="sickRageSync">
<small *ngIf="form.get('sickRageSync').hasError('required')" class="error-text">The SickRage Sync is required</small>
</div>
<div class="form-group"> <div class="form-group">
<label for="radarrSync" class="control-label">Radarr Sync</label> <label for="radarrSync" class="control-label">Radarr Sync</label>

@ -23,8 +23,9 @@ export class JobsComponent implements OnInit {
embyContentSync: [x.embyContentSync, Validators.required], embyContentSync: [x.embyContentSync, Validators.required],
plexContentSync: [x.plexContentSync, Validators.required], plexContentSync: [x.plexContentSync, Validators.required],
userImporter: [x.userImporter, Validators.required], userImporter: [x.userImporter, Validators.required],
sonarrSync: [x.radarrSync, Validators.required], sonarrSync: [x.radarrSync, Validators.required],
radarrSync: [x.sonarrSync, Validators.required], radarrSync: [x.sonarrSync, Validators.required],
sickRageSync: [x.sickRageSync, Validators.required],
}); });
}); });
} }

@ -30,8 +30,7 @@
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Sonarr']">Sonarr</a></li> <li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Sonarr']">Sonarr</a></li>
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/DogNzb']">DogNzb</a></li> <li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/DogNzb']">DogNzb</a></li>
<li [routerLinkActive]="['active']"><a>More Coming Soon...</a></li> <li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/SickRage']">SickRage</a></li>
<!--<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/SickRage']">SickRage</a></li>-->
</ul> </ul>
</li> </li>
@ -44,7 +43,6 @@
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/DogNzb']">DogNzb</a></li> <li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/DogNzb']">DogNzb</a></li>
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Radarr']">Radarr</a></li> <li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Radarr']">Radarr</a></li>
<!--<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Watcher']">Watcher</a></li>--> <!--<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Watcher']">Watcher</a></li>-->
<li [routerLinkActive]="['active']"><a>More Coming Soon...</a></li>
</ul> </ul>
</li> </li>

@ -53,7 +53,7 @@
<label for="select" class="control-label">Quality Profiles</label> <label for="select" class="control-label">Quality Profiles</label>
<div id="profiles"> <div id="profiles">
<select class="form-control form-control-custom" [ngClass]="{'form-error': form.get('qualityProfile').hasError('required')}" id="select" formControlName="qualityProfile"> <select class="form-control form-control-custom" [ngClass]="{'form-error': form.get('qualityProfile').hasError('required')}" id="select" formControlName="qualityProfile">
<option *ngFor="let quality of qualities" value="{{quality.id}}" >{{quality.name}}</option> <option *ngFor="let quality of qualities" value="{{quality.value}}" >{{quality.display}}</option>
</select> </select>
</div> </div>
<small *ngIf="form.get('qualityProfile').hasError('required')" class="error-text">A Default Quality Profile is required</small> <small *ngIf="form.get('qualityProfile').hasError('required')" class="error-text">A Default Quality Profile is required</small>

@ -1,9 +1,7 @@
import { Component, OnInit } from "@angular/core"; import { Component, OnInit } from "@angular/core";
import { FormBuilder, FormGroup, Validators } from "@angular/forms"; import { FormBuilder, FormGroup, Validators } from "@angular/forms";
import { ISonarrProfile, ISonarrRootFolder } from "../../interfaces"; import { IDropDownModel, ISickRageSettings } from "../../interfaces";
import { ISickRageSettings } from "../../interfaces";
import { TesterService } from "../../services"; import { TesterService } from "../../services";
import { NotificationService } from "../../services"; import { NotificationService } from "../../services";
import { SettingsService } from "../../services"; import { SettingsService } from "../../services";
@ -13,14 +11,8 @@ import { SettingsService } from "../../services";
}) })
export class SickRageComponent implements OnInit { export class SickRageComponent implements OnInit {
public qualities: ISonarrProfile[]; public qualities: IDropDownModel[];
public rootFolders: ISonarrRootFolder[];
public selectedRootFolder: ISonarrRootFolder;
public selectedQuality: ISonarrProfile;
public profilesRunning: boolean;
public rootFoldersRunning: boolean;
public form: FormGroup; public form: FormGroup;
public advanced = false;
constructor(private settingsService: SettingsService, constructor(private settingsService: SettingsService,
private notificationService: NotificationService, private notificationService: NotificationService,
@ -34,13 +26,12 @@ export class SickRageComponent implements OnInit {
enabled: [x.enabled], enabled: [x.enabled],
apiKey: [x.apiKey, [Validators.required]], apiKey: [x.apiKey, [Validators.required]],
qualityProfile: [x.qualityProfile, [Validators.required]], qualityProfile: [x.qualityProfile, [Validators.required]],
qualities: [x.qualities],
ssl: [x.ssl], ssl: [x.ssl],
subDir: [x.subDir], subDir: [x.subDir],
ip: [x.ip, [Validators.required]], ip: [x.ip, [Validators.required]],
port: [x.port, [Validators.required]], port: [x.port, [Validators.required]],
}); });
this.qualities = x.qualities;
}); });
} }

@ -1,7 +1,6 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Hangfire;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Ombi.Api.CouchPotato; using Ombi.Api.CouchPotato;
@ -10,7 +9,6 @@ using Ombi.Api.Plex;
using Ombi.Api.Radarr; using Ombi.Api.Radarr;
using Ombi.Api.SickRage; using Ombi.Api.SickRage;
using Ombi.Api.Sonarr; using Ombi.Api.Sonarr;
using Ombi.Api.Telegram;
using Ombi.Attributes; using Ombi.Attributes;
using Ombi.Core.Notifications; using Ombi.Core.Notifications;
using Ombi.Core.Settings.Models.External; using Ombi.Core.Settings.Models.External;
@ -18,7 +16,6 @@ using Ombi.Helpers;
using Ombi.Notifications; using Ombi.Notifications;
using Ombi.Notifications.Agents; using Ombi.Notifications.Agents;
using Ombi.Notifications.Models; using Ombi.Notifications.Models;
using Ombi.Notifications.Templates;
using Ombi.Settings.Settings.Models.External; using Ombi.Settings.Settings.Models.External;
using Ombi.Settings.Settings.Models.Notifications; using Ombi.Settings.Settings.Models.Notifications;
@ -84,11 +81,19 @@ namespace Ombi.Controllers.External
[HttpPost("discord")] [HttpPost("discord")]
public bool Discord([FromBody] DiscordNotificationSettings settings) public bool Discord([FromBody] DiscordNotificationSettings settings)
{ {
settings.Enabled = true; try
DiscordNotification.NotifyAsync( {
new NotificationOptions { NotificationType = NotificationType.Test, RequestId = -1 }, settings); settings.Enabled = true;
DiscordNotification.NotifyAsync(
new NotificationOptions { NotificationType = NotificationType.Test, RequestId = -1 }, settings);
return true; return true;
}
catch (Exception e)
{
Log.LogError(LoggingEvents.Api, e, "Could not test Discord");
return false;
}
} }
/// <summary> /// <summary>
@ -99,11 +104,20 @@ namespace Ombi.Controllers.External
[HttpPost("pushbullet")] [HttpPost("pushbullet")]
public bool Pushbullet([FromBody] PushbulletSettings settings) public bool Pushbullet([FromBody] PushbulletSettings settings)
{ {
settings.Enabled = true; try
PushbulletNotification.NotifyAsync( {
new NotificationOptions { NotificationType = NotificationType.Test, RequestId = -1 }, settings);
return true; settings.Enabled = true;
PushbulletNotification.NotifyAsync(
new NotificationOptions { NotificationType = NotificationType.Test, RequestId = -1 }, settings);
return true;
}
catch (Exception e)
{
Log.LogError(LoggingEvents.Api, e, "Could not test Pushbullet");
return false;
}
} }
/// <summary> /// <summary>
@ -114,11 +128,20 @@ namespace Ombi.Controllers.External
[HttpPost("pushover")] [HttpPost("pushover")]
public bool Pushover([FromBody] PushoverSettings settings) public bool Pushover([FromBody] PushoverSettings settings)
{ {
settings.Enabled = true; try
PushoverNotification.NotifyAsync( {
new NotificationOptions { NotificationType = NotificationType.Test, RequestId = -1 }, settings); settings.Enabled = true;
PushoverNotification.NotifyAsync(
new NotificationOptions { NotificationType = NotificationType.Test, RequestId = -1 }, settings);
return true;
}
catch (Exception e)
{
Log.LogError(LoggingEvents.Api, e, "Could not test Pushover");
return false;
}
return true;
} }
/// <summary> /// <summary>
@ -129,11 +152,21 @@ namespace Ombi.Controllers.External
[HttpPost("mattermost")] [HttpPost("mattermost")]
public bool Mattermost([FromBody] MattermostNotificationSettings settings) public bool Mattermost([FromBody] MattermostNotificationSettings settings)
{ {
settings.Enabled = true; try
MattermostNotification.NotifyAsync( {
new NotificationOptions { NotificationType = NotificationType.Test, RequestId = -1 }, settings); settings.Enabled = true;
MattermostNotification.NotifyAsync(
new NotificationOptions { NotificationType = NotificationType.Test, RequestId = -1 }, settings);
return true;
}
catch (Exception e)
{
Log.LogError(LoggingEvents.Api, e, "Could not test Mattermost");
return false;
}
return true;
} }
@ -145,11 +178,19 @@ namespace Ombi.Controllers.External
[HttpPost("slack")] [HttpPost("slack")]
public bool Slack([FromBody] SlackNotificationSettings settings) public bool Slack([FromBody] SlackNotificationSettings settings)
{ {
settings.Enabled = true; try
SlackNotification.NotifyAsync( {
new NotificationOptions { NotificationType = NotificationType.Test, RequestId = -1 }, settings); settings.Enabled = true;
SlackNotification.NotifyAsync(
new NotificationOptions { NotificationType = NotificationType.Test, RequestId = -1 }, settings);
return true; return true;
}
catch (Exception e)
{
Log.LogError(LoggingEvents.Api, e, "Could not test Slack");
return false;
}
} }
/// <summary> /// <summary>
@ -293,10 +334,18 @@ namespace Ombi.Controllers.External
[HttpPost("telegram")] [HttpPost("telegram")]
public async Task<bool> Telegram([FromBody] TelegramSettings settings) public async Task<bool> Telegram([FromBody] TelegramSettings settings)
{ {
settings.Enabled = true; try
await TelegramNotification.NotifyAsync(new NotificationOptions { NotificationType = NotificationType.Test, RequestId = -1 }, settings); {
settings.Enabled = true;
await TelegramNotification.NotifyAsync(new NotificationOptions { NotificationType = NotificationType.Test, RequestId = -1 }, settings);
return true; return true;
}
catch (Exception e)
{
Log.LogError(LoggingEvents.Api, e, "Could not test Telegram");
return false;
}
} }
/// <summary> /// <summary>
@ -307,9 +356,17 @@ namespace Ombi.Controllers.External
[HttpPost("sickrage")] [HttpPost("sickrage")]
public async Task<bool> SickRage([FromBody] SickRageSettings settings) public async Task<bool> SickRage([FromBody] SickRageSettings settings)
{ {
settings.Enabled = true; try
var result = await SickRageApi.Ping(settings.ApiKey, settings.FullUri); {
return result?.data?.pid != null; settings.Enabled = true;
var result = await SickRageApi.Ping(settings.ApiKey, settings.FullUri);
return result?.data?.pid != null;
}
catch (Exception e)
{
Log.LogError(LoggingEvents.Api, e, "Could not test SickRage");
return false;
}
} }
} }
} }
Loading…
Cancel
Save