Grabbing show names from Sonarr API, finished with BitMeTV

This commit is contained in:
zone117x
2015-04-18 14:18:14 -06:00
parent aa24c6b966
commit cd2d6949b6
6 changed files with 174 additions and 114 deletions

View File

@@ -133,53 +133,57 @@ namespace Jackett
public async Task<ReleaseInfo[]> PerformQuery(TorznabQuery query)
{
List<ReleaseInfo> releases = new List<ReleaseInfo>();
var searchUrl = string.Format("{0}?search={1}&cat=0", SearchUrl, HttpUtility.UrlEncode("game of thrones s03e09"));
var results = await client.GetStringAsync(searchUrl);
CQ dom = results;
var table = dom["tbody > tr > .latest"].Parent().Parent();
foreach (var row in table.Children().Skip(1))
foreach (var title in query.ShowTitles)
{
var release = new ReleaseInfo();
CQ qRow = row.Cq();
CQ qDetailsCol = row.ChildElements.ElementAt(1).Cq();
CQ qLink = qDetailsCol.Children("a").First();
var searchString = title + " " + query.GetEpisodeSearchString();
var searchUrl = string.Format("{0}?search={1}&cat=0", SearchUrl, HttpUtility.UrlEncode(searchString));
var results = await client.GetStringAsync(searchUrl);
CQ dom = results;
release.MinimumRatio = 1;
release.MinimumSeedTime = 172800;
release.Comments = new Uri(BaseUrl + "/" + qLink.Attr("href"));
release.Guid = release.Comments;
release.Title = qLink.Attr("title");
release.Description = release.Title;
var table = dom["tbody > tr > .latest"].Parent().Parent();
//"Tuesday, June 11th 2013 at 03:52:53 AM" to...
//"Tuesday June 11 2013 03 52 53 AM"
var timestamp = qDetailsCol.Children("font").Text().Trim() + " ";
var groups = new Regex(@"(.*?), (.*?) (.*?)th (.*?) at (.*?):(.*?):(.*?) (.*?) ").Match(timestamp).Groups;
var str = string.Join(" ", groups.Cast<Group>().Skip(1).Select(g => g.Value));
release.PublishDate = DateTime.ParseExact(str, "dddd MMMM d yyyy hh mm ss tt", CultureInfo.InvariantCulture);
release.Link = new Uri(BaseUrl + "/" + row.ChildElements.ElementAt(2).Cq().Children("a.index").Attr("href"));
var sizeCol = row.ChildElements.ElementAt(6);
var sizeVal = float.Parse(sizeCol.ChildNodes[0].NodeValue);
var sizeUnit = sizeCol.ChildNodes[2].NodeValue;
switch (sizeUnit)
foreach (var row in table.Children().Skip(1))
{
case "GB": release.Size = ReleaseInfo.BytesFromGB(sizeVal); break;
case "MB": release.Size = ReleaseInfo.BytesFromMB(sizeVal); break;
case "KB": release.Size = ReleaseInfo.BytesFromKB(sizeVal); break;
}
var release = new ReleaseInfo();
release.Seeders = int.Parse(row.ChildElements.ElementAt(8).Cq().Text());
release.Peers = int.Parse(row.ChildElements.ElementAt(9).Cq().Text()) + release.Seeders;
releases.Add(release);
CQ qRow = row.Cq();
CQ qDetailsCol = row.ChildElements.ElementAt(1).Cq();
CQ qLink = qDetailsCol.Children("a").First();
release.MinimumRatio = 1;
release.MinimumSeedTime = 172800;
release.Comments = new Uri(BaseUrl + "/" + qLink.Attr("href"));
release.Guid = release.Comments;
release.Title = qLink.Attr("title");
release.Description = release.Title;
//"Tuesday, June 11th 2013 at 03:52:53 AM" to...
//"Tuesday June 11 2013 03 52 53 AM"
var timestamp = qDetailsCol.Children("font").Text().Trim() + " ";
var groups = new Regex(@"(.*?), (.*?) (.*?)th (.*?) at (.*?):(.*?):(.*?) (.*?) ").Match(timestamp).Groups;
var str = string.Join(" ", groups.Cast<Group>().Skip(1).Select(g => g.Value));
release.PublishDate = DateTime.ParseExact(str, "dddd MMMM d yyyy hh mm ss tt", CultureInfo.InvariantCulture);
release.Link = new Uri(BaseUrl + "/" + row.ChildElements.ElementAt(2).Cq().Children("a.index").Attr("href"));
var sizeCol = row.ChildElements.ElementAt(6);
var sizeVal = float.Parse(sizeCol.ChildNodes[0].NodeValue);
var sizeUnit = sizeCol.ChildNodes[2].NodeValue;
switch (sizeUnit)
{
case "GB": release.Size = ReleaseInfo.BytesFromGB(sizeVal); break;
case "MB": release.Size = ReleaseInfo.BytesFromMB(sizeVal); break;
case "KB": release.Size = ReleaseInfo.BytesFromKB(sizeVal); break;
}
release.Seeders = int.Parse(row.ChildElements.ElementAt(8).Cq().Text());
release.Peers = int.Parse(row.ChildElements.ElementAt(9).Cq().Text()) + release.Seeders;
releases.Add(release);
}
}
return releases.ToArray();

View File

@@ -120,72 +120,75 @@ namespace Jackett.Indexers
{
List<ReleaseInfo> releases = new List<ReleaseInfo>();
var searchUrl = BaseUrl + string.Format(SearchUrl, HttpUtility.UrlEncode("game of thrones s05e01"));
var message = new HttpRequestMessage
foreach (var title in query.ShowTitles)
{
Method = HttpMethod.Get,
RequestUri = new Uri(BaseUrl + SwitchSingleViewUrl)
};
message.Headers.Referrer = new Uri(searchUrl);
var searchString = title + " " + query.GetEpisodeSearchString();
var searchUrl = BaseUrl + string.Format(SearchUrl, HttpUtility.UrlEncode(searchString));
var response = await client.SendAsync(message);
var results = await response.Content.ReadAsStringAsync();
CQ dom = results;
var rows = dom["#searchResult > tbody > tr"];
foreach (var row in rows)
{
var release = new ReleaseInfo();
CQ qRow = row.Cq();
CQ qLink = row.ChildElements.ElementAt(1).Cq().Children("a").First();
release.MinimumRatio = 1;
release.MinimumSeedTime = 172800;
release.Title = qLink.Text().Trim();
release.Description = release.Title;
release.Comments = new Uri(BaseUrl + qLink.Attr("href").TrimStart('/'));
release.Guid = release.Comments;
var timeString = row.ChildElements.ElementAt(2).Cq().Text();
if (timeString.Contains("mins ago"))
release.PublishDate = (DateTime.Now - TimeSpan.FromMinutes(int.Parse(timeString.Split(' ')[0])));
else if (timeString.Contains("Today"))
release.PublishDate = (DateTime.UtcNow - TimeSpan.FromHours(2) - TimeSpan.Parse(timeString.Split(' ')[1])).ToLocalTime();
else if (timeString.Contains("Y-day"))
release.PublishDate = (DateTime.UtcNow - TimeSpan.FromHours(26) - TimeSpan.Parse(timeString.Split(' ')[1])).ToLocalTime();
else if (timeString.Contains(':'))
var message = new HttpRequestMessage
{
var utc = DateTime.ParseExact(timeString, "MM-dd HH:mm", CultureInfo.InvariantCulture) - TimeSpan.FromHours(2);
release.PublishDate = DateTime.SpecifyKind(utc, DateTimeKind.Utc).ToLocalTime();
}
else
Method = HttpMethod.Get,
RequestUri = new Uri(BaseUrl + SwitchSingleViewUrl)
};
message.Headers.Referrer = new Uri(searchUrl);
var response = await client.SendAsync(message);
var results = await response.Content.ReadAsStringAsync();
CQ dom = results;
var rows = dom["#searchResult > tbody > tr"];
foreach (var row in rows)
{
var utc = DateTime.ParseExact(timeString, "MM-dd yyyy", CultureInfo.InvariantCulture) - TimeSpan.FromHours(2);
release.PublishDate = DateTime.SpecifyKind(utc, DateTimeKind.Utc).ToLocalTime();
var release = new ReleaseInfo();
CQ qRow = row.Cq();
CQ qLink = row.ChildElements.ElementAt(1).Cq().Children("a").First();
release.MinimumRatio = 1;
release.MinimumSeedTime = 172800;
release.Title = qLink.Text().Trim();
release.Description = release.Title;
release.Comments = new Uri(BaseUrl + qLink.Attr("href").TrimStart('/'));
release.Guid = release.Comments;
var timeString = row.ChildElements.ElementAt(2).Cq().Text();
if (timeString.Contains("mins ago"))
release.PublishDate = (DateTime.Now - TimeSpan.FromMinutes(int.Parse(timeString.Split(' ')[0])));
else if (timeString.Contains("Today"))
release.PublishDate = (DateTime.UtcNow - TimeSpan.FromHours(2) - TimeSpan.Parse(timeString.Split(' ')[1])).ToLocalTime();
else if (timeString.Contains("Y-day"))
release.PublishDate = (DateTime.UtcNow - TimeSpan.FromHours(26) - TimeSpan.Parse(timeString.Split(' ')[1])).ToLocalTime();
else if (timeString.Contains(':'))
{
var utc = DateTime.ParseExact(timeString, "MM-dd HH:mm", CultureInfo.InvariantCulture) - TimeSpan.FromHours(2);
release.PublishDate = DateTime.SpecifyKind(utc, DateTimeKind.Utc).ToLocalTime();
}
else
{
var utc = DateTime.ParseExact(timeString, "MM-dd yyyy", CultureInfo.InvariantCulture) - TimeSpan.FromHours(2);
release.PublishDate = DateTime.SpecifyKind(utc, DateTimeKind.Utc).ToLocalTime();
}
var downloadCol = row.ChildElements.ElementAt(3).Cq().Find("a");
release.MagnetUrl = new Uri(downloadCol.Attr("href"));
release.InfoHash = release.MagnetUrl.ToString().Split(':')[3].Split('&')[0];
var sizeString = row.ChildElements.ElementAt(4).Cq().Text().Split(' ');
var sizeVal = float.Parse(sizeString[0]);
var sizeUnit = sizeString[1];
switch (sizeUnit)
{
case "GiB": release.Size = ReleaseInfo.BytesFromGB(sizeVal); break;
case "MiB": release.Size = ReleaseInfo.BytesFromMB(sizeVal); break;
case "KiB": release.Size = ReleaseInfo.BytesFromKB(sizeVal); break;
}
release.Seeders = int.Parse(row.ChildElements.ElementAt(5).Cq().Text());
release.Peers = int.Parse(row.ChildElements.ElementAt(6).Cq().Text()) + release.Seeders;
releases.Add(release);
}
var downloadCol = row.ChildElements.ElementAt(3).Cq().Find("a");
release.MagnetUrl = new Uri(downloadCol.Attr("href"));
release.InfoHash = release.MagnetUrl.ToString().Split(':')[3].Split('&')[0];
var sizeString = row.ChildElements.ElementAt(4).Cq().Text().Split(' ');
var sizeVal = float.Parse(sizeString[0]);
var sizeUnit = sizeString[1];
switch (sizeUnit)
{
case "GiB": release.Size = ReleaseInfo.BytesFromGB(sizeVal); break;
case "MiB": release.Size = ReleaseInfo.BytesFromMB(sizeVal); break;
case "KiB": release.Size = ReleaseInfo.BytesFromKB(sizeVal); break;
}
release.Seeders = int.Parse(row.ChildElements.ElementAt(5).Cq().Text());
release.Peers = int.Parse(row.ChildElements.ElementAt(6).Cq().Text()) + release.Seeders;
releases.Add(release);
}
return releases.ToArray();
}

View File

@@ -99,6 +99,11 @@ namespace Jackett
}
var torznabQuery = TorznabQuery.FromHttpQuery(query);
torznabQuery.ShowTitles = await sonarrApi.GetShowTitle(torznabQuery.RageID);
var releases = await indexer.PerformQuery(torznabQuery);
var severUrl = string.Format("{0}://{1}:{2}/", context.Request.Url.Scheme, context.Request.Url.Host, context.Request.Url.Port);
var resultPage = new ResultPage(new ChannelInfo
@@ -112,8 +117,6 @@ namespace Jackett
ImageDescription = indexer.DisplayName
});
var releases = await indexer.PerformQuery(torznabQuery);
// add Jackett proxy to download links...
foreach (var release in releases)
{

View File

@@ -45,6 +45,8 @@ namespace Jackett
HttpClientHandler handler;
HttpClient client;
Dictionary<int, string[]> IdNameMappings;
public SonarrApi()
{
LoadSettings();
@@ -57,6 +59,28 @@ namespace Jackett
UseCookies = true,
};
client = new HttpClient(handler);
IdNameMappings = new Dictionary<int, string[]>();
}
async Task ReloadNameMappings(string host, int port, string apiKey)
{
Uri hostUri = new Uri(host);
var queryUrl = string.Format("http://{0}:{1}/api/series?apikey={2}", hostUri.Host, port, apiKey);
var response = await client.GetStringAsync(queryUrl);
var json = JArray.Parse(response);
IdNameMappings.Clear();
foreach (var item in json)
{
var titles = new List<string>();
titles.Add((string)item["title"]);
foreach (var t in item["alternateTitles"])
{
titles.Add((string)t["title"]);
}
IdNameMappings.Add((int)item["tvRageId"], titles.ToArray());
}
}
void LoadSettings()
@@ -99,7 +123,7 @@ namespace Jackett
{
var config = new ConfigurationSonarr();
config.LoadValuesFromJson(configJson);
await TestConnection(config.Host.Value, int.Parse(config.Port.Value), config.ApiKey.Value);
await ReloadNameMappings(config.Host.Value, int.Parse(config.Port.Value), config.ApiKey.Value);
Host = "http://" + new Uri(config.Host.Value).Host;
Port = int.Parse(config.Port.Value);
ApiKey = config.ApiKey.Value;
@@ -108,15 +132,24 @@ namespace Jackett
public async Task TestConnection()
{
await TestConnection(Host, Port, ApiKey);
await ReloadNameMappings(Host, Port, ApiKey);
}
async Task TestConnection(string host, int port, string apiKey)
public async Task<string[]> GetShowTitle(int rid)
{
Uri hostUri = new Uri(host);
var queryUrl = string.Format("http://{0}:{1}/api/series?apikey={2}", hostUri.Host, port, apiKey);
var response = await client.GetStringAsync(queryUrl);
var json = JArray.Parse(response);
if (rid == 0)
return null;
int tries = 0;
while (tries < 2)
{
string[] titles;
if (IdNameMappings.TryGetValue(rid, out titles))
return titles;
await ReloadNameMappings(Host, Port, ApiKey);
tries++;
}
return null;
}
}
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -17,7 +18,23 @@ namespace Jackett
public int Offset { get; private set; }
public int RageID { get; private set; }
public int Season { get; private set; }
public int Episode { get; private set; }
public string Episode { get; private set; }
public string[] ShowTitles { get; set; }
public string GetEpisodeSearchString()
{
if (Season == 0)
return string.Empty;
string episodeString;
DateTime showDate;
if (DateTime.TryParseExact(string.Format("{0} {1}", Season, Episode), "yyyy MM/dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out showDate))
episodeString = showDate.ToString("yyyy.MM.dd");
else
episodeString = string.Format("S{0:00}E{1:00}", Season, int.Parse(Episode));
return episodeString;
}
public static TorznabQuery FromHttpQuery(NameValueCollection query)
{
@@ -36,8 +53,8 @@ namespace Jackett
q.RageID = temp;
if (int.TryParse(query["season"], out temp))
q.Season = temp;
if (int.TryParse(query["ep"], out temp))
q.Episode = int.Parse(query["ep"]);
q.Episode = query["ep"];
return q;
}

View File

@@ -308,12 +308,12 @@
<div class="setup-item-value">{{{value_element}}}</div>
</div>
<input class="setup-item-inputstring form-control" type="text" value="{{{value}}}"></input>
<input class="setup-item-inputstring form-control" type="text" value="{{{value}}}" />
<div class="setup-item-checkbox">
{{#if value}}
<input type="checkbox" class="form-control" checked></input>
<input type="checkbox" class="form-control" checked />
{{else}}
<input type="checkbox" class="form-control"></input>
<input type="checkbox" class="form-control" />
{{/if}}
</div>
<img class="setup-item-displayimage" src="{{{value}}}" />