Added the SickRage API integration

pull/1741/head
Jamie 7 years ago
parent 6e04e2effe
commit f21cd89a74

@ -0,0 +1,17 @@
using System.Threading.Tasks;
using Ombi.Api.SickRage.Models;
namespace Ombi.Api.SickRage
{
public interface ISickRageApi
{
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<SickRageShows> GetShows(string apiKey, string baseUrl);
Task<SickRagePing> Ping(string apiKey, string baseUrl);
Task<SickRageSeasonList> VerifyShowHasLoaded(int tvdbId, string apiKey, string baseUrl);
Task<SickRageEpisodeStatus> SetEpisodeStatus(string apiKey, string baseUrl, int tvdbid, string status,
int season, int episode = -1);
}
}

@ -0,0 +1,10 @@
namespace Ombi.Api.SickRage.Models
{
public abstract class SickRageBase<T>
{
public T data { get; set; }
public string message { get; set; }
public string result { get; set; }
}
}
}

@ -0,0 +1,18 @@
namespace Ombi.Api.SickRage.Models
{
public class SickRageEpisodeStatus
{
public Data[] data { get; set; }
public string message { get; set; }
public string result { get; set; }
}
public class Data
{
public int episode { get; set; }
public string message { get; set; }
public string result { get; set; }
public int season { get; set; }
public string status { get; set; }
}
}

@ -0,0 +1,11 @@
namespace Ombi.Api.SickRage.Models
{
public class SickRagePingData
{
public int pid { get; set; }
}
public class SickRagePing : SickRageBase<SickRagePingData>
{
}
}

@ -0,0 +1,11 @@
using Newtonsoft.Json;
using Ombi.Helpers;
namespace Ombi.Api.SickRage.Models
{
public class SickRageSeasonList : SickRageBase<object>
{
[JsonIgnore]
public int[] Data => JsonConvertHelper.ParseObjectToArray<int>(data);
}
}

@ -0,0 +1,14 @@
using System.Collections.Generic;
namespace Ombi.Api.SickRage.Models
{
public class SickRageShows : SickRageBase<Dictionary<int, Item>>
{
}
public class Item
{
public int tvdbid { get; set; }
}
}

@ -0,0 +1,9 @@
namespace Ombi.Api.SickRage.Models
{
public static class SickRageStatus
{
public const string Wanted = "wanted";
public const string Skipped = "skipped";
public const string Ignored = "Ignored";
}
}

@ -0,0 +1,11 @@
namespace Ombi.Api.SickRage.Models
{
public class SickRageTvAddData
{
public string name { get; set; }
}
public class SickRageTvAdd : SickRageBase<SickRageTvAddData>
{
}
}

@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Ombi.Api\Ombi.Api.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,143 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Ombi.Api.SickRage.Models;
namespace Ombi.Api.SickRage
{
public class SickRageApi : ISickRageApi
{
public SickRageApi(IApi api, ILogger<SickRageApi> log)
{
_api = api;
_log = log;
}
private readonly IApi _api;
private readonly ILogger<SickRageApi> _log;
public async Task<SickRageSeasonList> VerifyShowHasLoaded(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<SickRageSeasonList>(request);
}
public async Task<SickRageTvAdd> AddSeries(int tvdbId, int seasonCount, int[] seasons, string quality, 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);
request.AddQueryString("tvdbid", tvdbId.ToString());
request.AddQueryString("status", status);
request.AddQueryString("future_status", futureStatus);
if (!quality.Equals("default", StringComparison.CurrentCultureIgnoreCase))
{
request.AddQueryString("initial", quality);
}
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;
}
public async Task<SickRageTvAdd> AddSeason(int tvdbId, int season, string apiKey, string baseUrl)
{
var request = new Request($"/api/{apiKey}/?cmd=episode.setstatus", baseUrl, HttpMethod.Get);
request.AddQueryString("tvdbid", tvdbId.ToString());
request.AddQueryString("season", season.ToString());
request.AddQueryString("status", SickRageStatus.Wanted);
return await _api.Request<SickRageTvAdd>(request);
}
public async Task<SickRageShows> GetShows(string apiKey, string baseUrl)
{
var request = new Request($"/api/{apiKey}/?cmd=shows", baseUrl, HttpMethod.Get);
return await _api.Request<SickRageShows>(request);
}
public async Task<SickRagePing> Ping(string apiKey, string baseUrl)
{
var request = new Request($"/api/{apiKey}/?cmd=sb.ping", baseUrl, HttpMethod.Get);
return await _api.Request<SickRagePing>(request);
}
/// <summary>
/// Sets the epsiode status e.g. wanted
/// The episode number is optional, if not supplied it will set the whole season as the status passed in
/// </summary>
/// <returns></returns>
public async Task<SickRageEpisodeStatus> SetEpisodeStatus(string apiKey, string baseUrl, int tvdbid, string status, int season, int episode = -1)
{
var request = new Request($"/api/{apiKey}/?cmd=episode.setstatus", baseUrl, HttpMethod.Get);
request.AddQueryString("tvdbid", tvdbid.ToString());
request.AddQueryString("status", status);
request.AddQueryString("season", season.ToString());
if (episode != -1)
{
request.AddQueryString("episode", episode.ToString());
}
return await _api.Request<SickRageEpisodeStatus>(request);
}
}
}

@ -36,6 +36,7 @@ using Ombi.Api.Mattermost;
using Ombi.Api.Pushbullet;
using Ombi.Api.Pushover;
using Ombi.Api.Service;
using Ombi.Api.SickRage;
using Ombi.Api.Slack;
using Ombi.Core.Rule.Interfaces;
using Ombi.Core.Senders;
@ -102,6 +103,7 @@ namespace Ombi.DependencyInjection
services.AddTransient<IDogNzbApi, DogNzbApi>();
services.AddTransient<ITelegramApi, TelegramApi>();
services.AddTransient<IGithubApi, GithubApi>();
services.AddTransient<ISickRageApi, SickRageApi>();
}
public static void RegisterStore(this IServiceCollection services) {

@ -27,6 +27,7 @@
<ProjectReference Include="..\Ombi.Api.Pushover\Ombi.Api.Pushover.csproj" />
<ProjectReference Include="..\Ombi.Api.Radarr\Ombi.Api.Radarr.csproj" />
<ProjectReference Include="..\Ombi.Api.Service\Ombi.Api.Service.csproj" />
<ProjectReference Include="..\Ombi.Api.SickRage\Ombi.Api.SickRage.csproj" />
<ProjectReference Include="..\Ombi.Api.Slack\Ombi.Api.Slack.csproj" />
<ProjectReference Include="..\Ombi.Api.Sonarr\Ombi.Api.Sonarr.csproj" />
<ProjectReference Include="..\Ombi.Api.Telegram\Ombi.Api.Telegram.csproj" />

@ -0,0 +1,27 @@
using Newtonsoft.Json;
namespace Ombi.Helpers
{
public static class JsonConvertHelper
{
public static T[] ParseObjectToArray<T>(object ambiguousObject)
{
var json = ambiguousObject.ToString();
if (string.IsNullOrWhiteSpace(json))
{
return new T[0]; // Could return null here instead.
}
if (json.TrimStart().StartsWith("["))
{
return JsonConvert.DeserializeObject<T[]>(json);
}
if (json.TrimStart().Equals("{}"))
{
return new T[0];
}
return new T[1] { JsonConvert.DeserializeObject<T>(json) };
}
}
}

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26730.15
VisualStudioVersion = 15.0.27004.2009
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi", "Ombi\Ombi.csproj", "{C987AA67-AFE1-468F-ACD3-EAD5A48E1F6A}"
EndProject
@ -86,9 +86,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.DogNzb", "Ombi.Api
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Tests", "Ombi.Tests\Ombi.Tests.csproj", "{C12F5276-352A-43CF-8E33-400E768E9757}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Telegram", "Ombi.Api.Telegram\Ombi.Api.Telegram.csproj", "{CB9DD209-8E09-4E01-983E-C77C89592D36}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Telegram", "Ombi.Api.Telegram\Ombi.Api.Telegram.csproj", "{CB9DD209-8E09-4E01-983E-C77C89592D36}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Github", "Ombi.Api.Github\Ombi.Api.Github.csproj", "{55866DEE-46D1-4AF7-B1A2-62F6190C8EC7}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Github", "Ombi.Api.Github\Ombi.Api.Github.csproj", "{55866DEE-46D1-4AF7-B1A2-62F6190C8EC7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.SickRage", "Ombi.Api.SickRage\Ombi.Api.SickRage.csproj", "{94C9A366-2595-45EA-AABB-8E4A2E90EC5B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -232,6 +234,10 @@ Global
{55866DEE-46D1-4AF7-B1A2-62F6190C8EC7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{55866DEE-46D1-4AF7-B1A2-62F6190C8EC7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{55866DEE-46D1-4AF7-B1A2-62F6190C8EC7}.Release|Any CPU.Build.0 = Release|Any CPU
{94C9A366-2595-45EA-AABB-8E4A2E90EC5B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{94C9A366-2595-45EA-AABB-8E4A2E90EC5B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{94C9A366-2595-45EA-AABB-8E4A2E90EC5B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{94C9A366-2595-45EA-AABB-8E4A2E90EC5B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -265,6 +271,7 @@ Global
{C12F5276-352A-43CF-8E33-400E768E9757} = {6F42AB98-9196-44C4-B888-D5E409F415A1}
{CB9DD209-8E09-4E01-983E-C77C89592D36} = {9293CA11-360A-4C20-A674-B9E794431BF5}
{55866DEE-46D1-4AF7-B1A2-62F6190C8EC7} = {9293CA11-360A-4C20-A674-B9E794431BF5}
{94C9A366-2595-45EA-AABB-8E4A2E90EC5B} = {9293CA11-360A-4C20-A674-B9E794431BF5}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {192E9BF8-00B4-45E4-BCCC-4C215725C869}

Loading…
Cancel
Save