#183 T411 Category mapping

This commit is contained in:
KZ 2015-09-21 19:26:15 +01:00
parent e8bb1680f3
commit 06266e2cc5
1 changed files with 249 additions and 183 deletions

View File

@ -1,183 +1,249 @@
using Jackett.Models; using Jackett.Models;
using Jackett.Services; using Jackett.Services;
using Jackett.Utils; using Jackett.Utils;
using Jackett.Utils.Clients; using Jackett.Utils.Clients;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using NLog; using NLog;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Net.Http.Headers; using System.Net.Http.Headers;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Web; using System.Web;
using Jackett.Models.IndexerConfig; using Jackett.Models.IndexerConfig;
namespace Jackett.Indexers namespace Jackett.Indexers
{ {
public class T411 : BaseIndexer, IIndexer public class T411 : BaseIndexer, IIndexer
{ {
private readonly string CommentsUrl = ""; private readonly string CommentsUrl = "";
const string ApiUrl = "http://api.t411.io"; const string ApiUrl = "http://api.t411.io";
const string AuthUrl = ApiUrl + "/auth"; const string AuthUrl = ApiUrl + "/auth";
const string SearchUrl = ApiUrl + "/torrents/search/{0}"; const string SearchUrl = ApiUrl + "/torrents/search/{0}";
const string DownloadUrl = ApiUrl + "/torrents/download/{0}"; const string DownloadUrl = ApiUrl + "/torrents/download/{0}";
HttpClientHandler handler; HttpClientHandler handler;
HttpClient client; HttpClient client;
new ConfigurationDataLoginTokin configData new ConfigurationDataLoginTokin configData
{ {
get { return (ConfigurationDataLoginTokin)base.configData; } get { return (ConfigurationDataLoginTokin)base.configData; }
set { base.configData = value; } set { base.configData = value; }
} }
public T411(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps) public T411(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
: base(name: "T411", : base(name: "T411",
description: "French Torrent Tracker", description: "French Torrent Tracker",
link: "http://www.t411.io/", link: "http://www.t411.io/",
caps: TorznabUtil.CreateDefaultTorznabTVCaps(), caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
manager: i, manager: i,
client: wc, client: wc,
logger: l, logger: l,
p: ps, p: ps,
configData: new ConfigurationDataLoginTokin()) configData: new ConfigurationDataLoginTokin())
{ {
CommentsUrl = SiteLink + "/torrents/{0}"; CommentsUrl = SiteLink + "/torrents/{0}";
IsConfigured = false; IsConfigured = false;
handler = new HttpClientHandler handler = new HttpClientHandler
{ {
AllowAutoRedirect = true AllowAutoRedirect = true
}; };
client = new HttpClient(handler); client = new HttpClient(handler);
}
async Task<string> GetAuthToken(bool forceFetch = false)
{ AddCategoryMapping("Film\\/Vidéo", TorznabCatType.Movies);
if (!forceFetch && configData.LastTokenFetchDateTime > DateTime.Now - TimeSpan.FromHours(48)) AddCategoryMapping("Vidéo-clips", TorznabCatType.Other);
{ AddCategoryMapping("Série TV", TorznabCatType.TV);
return configData.ApiToken.Value; AddCategoryMapping("Animation", TorznabCatType.TVAnime);
} AddCategoryMapping("Film", TorznabCatType.Movies);
AddCategoryMapping("Concert", TorznabCatType.AudioVideo);
var pairs = new Dictionary<string, string> { AddCategoryMapping("Documentaire", TorznabCatType.Audio);
{ "username", configData.Username.Value }, AddCategoryMapping("Spectacle", TorznabCatType.TV);
{ "password", configData.Password.Value } AddCategoryMapping("Sport", TorznabCatType.TVSport);
}; AddCategoryMapping("Animation Série", TorznabCatType.TVAnime);
AddCategoryMapping("Emission TV", TorznabCatType.TV);
var content = new FormUrlEncodedContent(pairs);
var response = await client.PostAsync(AuthUrl, content); AddCategoryMapping("Application", TorznabCatType.PC0day);
var responseContent = await response.Content.ReadAsStringAsync(); AddCategoryMapping("Linux", TorznabCatType.PC);
var jsonResponse = JObject.Parse(responseContent); AddCategoryMapping("MacOS", TorznabCatType.PCMac);
if (jsonResponse["error"] != null) AddCategoryMapping("Windows", TorznabCatType.PC);
{ AddCategoryMapping("Smartphone", TorznabCatType.PCPhoneOther);
throw new ApplicationException((string)jsonResponse["error"]); AddCategoryMapping("Tablette", TorznabCatType.PCPhoneOther);
} AddCategoryMapping("Autre", TorznabCatType.PC);
configData.ApiToken.Value = (string)jsonResponse["token"]; AddCategoryMapping("Formation", TorznabCatType.PC);
configData.LastTokenFetchDateTime = DateTime.Now;
return configData.ApiToken.Value; AddCategoryMapping("Emulation", TorznabCatType.PC);
} AddCategoryMapping("Emulateurs", TorznabCatType.PC);
AddCategoryMapping("Roms", TorznabCatType.PC);
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{ AddCategoryMapping("GPS", TorznabCatType.Other);
configData.LoadValuesFromJson(configJson); AddCategoryMapping("Applications", TorznabCatType.Other);
AddCategoryMapping("Cartes", TorznabCatType.Other);
Exception tokenFetchEx = null; AddCategoryMapping("Divers", TorznabCatType.Other);
try
{ AddCategoryMapping("Audio", TorznabCatType.Audio);
await GetAuthToken(true); AddCategoryMapping("Karaoke", TorznabCatType.Audio);
} AddCategoryMapping("Samples", TorznabCatType.Audio);
catch (Exception ex) AddCategoryMapping("Musique", TorznabCatType.Audio);
{ AddCategoryMapping("Podcast Radio", TorznabCatType.Audio);
tokenFetchEx = new ExceptionWithConfigData(ex.Message, configData);
} AddCategoryMapping("eBook", TorznabCatType.BooksEbook);
AddCategoryMapping("Audio", TorznabCatType.AudioAudiobook);
await ConfigureIfOK(string.Empty, tokenFetchEx == null, () => AddCategoryMapping("Bds", TorznabCatType.AudioVideo);
{ AddCategoryMapping("Comics", TorznabCatType.BooksComics);
throw tokenFetchEx; AddCategoryMapping("Livres", TorznabCatType.Books);
}); AddCategoryMapping("Mangas", TorznabCatType.BooksForeign);
AddCategoryMapping("Presse", TorznabCatType.BooksMagazines);
return IndexerConfigurationStatus.RequiresTesting;
} AddCategoryMapping("xXx", TorznabCatType.XXX);
AddCategoryMapping("eBooks", TorznabCatType.XXXImageset);
// Override to load legacy config format AddCategoryMapping("Jeux vidéo", TorznabCatType.XXX);
public override void LoadFromSavedConfiguration(JToken jsonConfig) AddCategoryMapping("Video", TorznabCatType.XXXDVD);
{ //AddCategoryMapping("Animation", TorznabCatType.XXX); Used above :/
if (jsonConfig is JObject)
{ AddCategoryMapping("Jeu vidéo", TorznabCatType.PCGames);
configData.ApiToken.Value = jsonConfig.Value<string>("token"); ; AddCategoryMapping("Linux", TorznabCatType.PCGames);
configData.Username.Value = jsonConfig.Value<string>("username"); AddCategoryMapping("MacOS", TorznabCatType.PCGames);
configData.Password.Value = jsonConfig.Value<string>("password"); // AddCategoryMapping("Windows", TorznabCatType.PCGames); Used above :/
SaveConfig(); AddCategoryMapping("Nintendo", TorznabCatType.Console);
IsConfigured = true; AddCategoryMapping("Sony", TorznabCatType.Console);
return; AddCategoryMapping("Microsoft", TorznabCatType.PCGames);
} AddCategoryMapping("Smartphone", TorznabCatType.PCPhoneOther);
AddCategoryMapping("Tablette", TorznabCatType.PCPhoneOther);
base.LoadFromSavedConfiguration(jsonConfig); AddCategoryMapping("Autre", TorznabCatType.Other);
}
AddCategoryMapping("Jeux vidéo", TorznabCatType.Other);
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) }
{
var releases = new List<ReleaseInfo>(); async Task<string> GetAuthToken(bool forceFetch = false)
var searchTerm = string.IsNullOrEmpty(query.SanitizedSearchTerm) ? "%20" : query.SanitizedSearchTerm; {
var searchString = searchTerm + " " + query.GetEpisodeSearchString(); if (!forceFetch && configData.LastTokenFetchDateTime > DateTime.Now - TimeSpan.FromHours(48))
var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString)); {
return configData.ApiToken.Value;
var message = new HttpRequestMessage(); }
message.Method = HttpMethod.Get;
message.RequestUri = new Uri(episodeSearchUrl); var pairs = new Dictionary<string, string> {
message.Headers.TryAddWithoutValidation("Authorization", await GetAuthToken()); { "username", configData.Username.Value },
{ "password", configData.Password.Value }
var response = await client.SendAsync(message); };
var results = await response.Content.ReadAsStringAsync();
var content = new FormUrlEncodedContent(pairs);
var jsonResult = JObject.Parse(results);
try var response = await client.PostAsync(AuthUrl, content);
{ var responseContent = await response.Content.ReadAsStringAsync();
var items = (JArray)jsonResult["torrents"]; var jsonResponse = JObject.Parse(responseContent);
foreach (var item in items) if (jsonResponse["error"] != null)
{ {
var release = new ReleaseInfo(); throw new ApplicationException((string)jsonResponse["error"]);
}
release.MinimumRatio = 1; configData.ApiToken.Value = (string)jsonResponse["token"];
release.MinimumSeedTime = 172800; configData.LastTokenFetchDateTime = DateTime.Now;
var torrentId = (string)item["id"]; return configData.ApiToken.Value;
release.Link = new Uri(string.Format(DownloadUrl, torrentId)); }
release.Title = (string)item["name"];
release.Description = release.Title; public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
release.Comments = new Uri(string.Format(CommentsUrl, (string)item["rewritename"])); {
release.Guid = release.Comments; configData.LoadValuesFromJson(configJson);
var dateUtc = DateTime.ParseExact((string)item["added"], "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); Exception tokenFetchEx = null;
release.PublishDate = DateTime.SpecifyKind(dateUtc, DateTimeKind.Utc).ToLocalTime(); try
{
release.Seeders = ParseUtil.CoerceInt((string)item["seeders"]); await GetAuthToken(true);
release.Peers = ParseUtil.CoerceInt((string)item["leechers"]) + release.Seeders; }
catch (Exception ex)
release.Size = ParseUtil.CoerceLong((string)item["size"]); {
tokenFetchEx = new ExceptionWithConfigData(ex.Message, configData);
releases.Add(release); }
}
} await ConfigureIfOK(string.Empty, tokenFetchEx == null, () =>
catch (Exception ex) {
{ throw tokenFetchEx;
OnParseError(results, ex); });
}
return releases; return IndexerConfigurationStatus.RequiresTesting;
} }
public override async Task<byte[]> Download(Uri link) // Override to load legacy config format
{ public override void LoadFromSavedConfiguration(JToken jsonConfig)
var message = new HttpRequestMessage(); {
message.Method = HttpMethod.Get; if (jsonConfig is JObject)
message.RequestUri = link; {
message.Headers.TryAddWithoutValidation("Authorization", await GetAuthToken()); configData.ApiToken.Value = jsonConfig.Value<string>("token"); ;
configData.Username.Value = jsonConfig.Value<string>("username");
var response = await client.SendAsync(message); configData.Password.Value = jsonConfig.Value<string>("password");
return await response.Content.ReadAsByteArrayAsync(); SaveConfig();
} IsConfigured = true;
} return;
} }
base.LoadFromSavedConfiguration(jsonConfig);
}
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>();
var searchTerm = string.IsNullOrEmpty(query.SanitizedSearchTerm) ? "%20" : query.SanitizedSearchTerm;
var searchString = searchTerm + " " + query.GetEpisodeSearchString();
var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString));
var message = new HttpRequestMessage();
message.Method = HttpMethod.Get;
message.RequestUri = new Uri(episodeSearchUrl);
message.Headers.TryAddWithoutValidation("Authorization", await GetAuthToken());
var response = await client.SendAsync(message);
var results = await response.Content.ReadAsStringAsync();
var jsonResult = JObject.Parse(results);
try
{
var items = (JArray)jsonResult["torrents"];
foreach (var item in items)
{
var release = new ReleaseInfo();
release.MinimumRatio = 1;
release.MinimumSeedTime = 172800;
var torrentId = (string)item["id"];
release.Link = new Uri(string.Format(DownloadUrl, torrentId));
release.Title = (string)item["name"];
release.Description = release.Title;
release.Comments = new Uri(string.Format(CommentsUrl, (string)item["rewritename"]));
release.Guid = release.Comments;
var dateUtc = DateTime.ParseExact((string)item["added"], "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
release.PublishDate = DateTime.SpecifyKind(dateUtc, DateTimeKind.Utc).ToLocalTime();
release.Seeders = ParseUtil.CoerceInt((string)item["seeders"]);
release.Peers = ParseUtil.CoerceInt((string)item["leechers"]) + release.Seeders;
release.Size = ParseUtil.CoerceLong((string)item["size"]);
release.Category = MapTrackerCatToNewznab((string)item["categoryname"]);
releases.Add(release);
}
}
catch (Exception ex)
{
OnParseError(results, ex);
}
return releases;
}
public override async Task<byte[]> Download(Uri link)
{
var message = new HttpRequestMessage();
message.Method = HttpMethod.Get;
message.RequestUri = link;
message.Headers.TryAddWithoutValidation("Authorization", await GetAuthToken());
var response = await client.SendAsync(message);
return await response.Content.ReadAsByteArrayAsync();
}
}
}