mirror of https://github.com/Jackett/Jackett
Added RSS feed to RevolutionTT
This commit is contained in:
parent
e4a47927b9
commit
6b1dba2dc3
|
@ -15,6 +15,8 @@ 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;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
namespace Jackett.Indexers
|
namespace Jackett.Indexers
|
||||||
{
|
{
|
||||||
|
@ -22,11 +24,15 @@ namespace Jackett.Indexers
|
||||||
{
|
{
|
||||||
private string LandingPageURL { get { return SiteLink + "login.php"; } }
|
private string LandingPageURL { get { return SiteLink + "login.php"; } }
|
||||||
private string LoginUrl { get { return SiteLink + "takelogin.php"; } }
|
private string LoginUrl { get { return SiteLink + "takelogin.php"; } }
|
||||||
|
private string GetRSSKeyUrl { get { return SiteLink + "getrss.php"; } }
|
||||||
|
private string RSSUrl { get { return SiteLink + "rss.php?feed=dl&passkey="; } }
|
||||||
private string SearchUrl { get { return SiteLink + "browse.php"; } }
|
private string SearchUrl { get { return SiteLink + "browse.php"; } }
|
||||||
|
private string DetailsURL { get { return SiteLink + "details.php?id={0}&hit=1"; } }
|
||||||
|
|
||||||
new ConfigurationDataBasicLogin configData
|
|
||||||
|
new ConfigurationDataBasicLoginWithRSS configData
|
||||||
{
|
{
|
||||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
get { return (ConfigurationDataBasicLoginWithRSS)base.configData; }
|
||||||
set { base.configData = value; }
|
set { base.configData = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +46,7 @@ namespace Jackett.Indexers
|
||||||
logger: l,
|
logger: l,
|
||||||
p: ps,
|
p: ps,
|
||||||
downloadBase: "https://revolutiontt.me/download.php/",
|
downloadBase: "https://revolutiontt.me/download.php/",
|
||||||
configData: new ConfigurationDataBasicLogin())
|
configData: new ConfigurationDataBasicLoginWithRSS())
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Original RevolutionTT Categories -
|
/* Original RevolutionTT Categories -
|
||||||
|
@ -146,6 +152,35 @@ namespace Jackett.Indexers
|
||||||
//AddCategoryMapping("cat_id", TorznabCatType.BooksTechnical);
|
//AddCategoryMapping("cat_id", TorznabCatType.BooksTechnical);
|
||||||
//AddCategoryMapping("cat_id", TorznabCatType.BooksOther);
|
//AddCategoryMapping("cat_id", TorznabCatType.BooksOther);
|
||||||
//AddCategoryMapping("cat_id", TorznabCatType.BooksForeign);
|
//AddCategoryMapping("cat_id", TorznabCatType.BooksForeign);
|
||||||
|
|
||||||
|
// RSS Textual categories
|
||||||
|
AddCategoryMapping("Anime", TorznabCatType.TVAnime);
|
||||||
|
AddCategoryMapping("Appz/Misc", TorznabCatType.PC0day);
|
||||||
|
AddCategoryMapping("Appz/PC-ISO", TorznabCatType.Books);
|
||||||
|
AddCategoryMapping("E-Book", TorznabCatType.BooksEbook);
|
||||||
|
AddCategoryMapping("Games/PC-ISO", TorznabCatType.PCGames);
|
||||||
|
AddCategoryMapping("Games/PC-Rips", TorznabCatType.PCGames);
|
||||||
|
AddCategoryMapping("Games/PS3", TorznabCatType.ConsolePS3);
|
||||||
|
AddCategoryMapping("Games/Wii", TorznabCatType.ConsoleWii);
|
||||||
|
AddCategoryMapping("Games/XBOX360", TorznabCatType.ConsoleXbox360);
|
||||||
|
AddCategoryMapping("Handheld/NDS", TorznabCatType.ConsoleNDS);
|
||||||
|
AddCategoryMapping("Handheld/PSP", TorznabCatType.ConsolePSP);
|
||||||
|
AddCategoryMapping("Mac", TorznabCatType.PCMac);
|
||||||
|
AddCategoryMapping("Movies/BluRay", TorznabCatType.MoviesBluRay);
|
||||||
|
AddCategoryMapping("Movies/DVDR", TorznabCatType.MoviesDVD);
|
||||||
|
AddCategoryMapping("Movies/HDx264", TorznabCatType.MoviesHD);
|
||||||
|
AddCategoryMapping("Movies/Packs", TorznabCatType.Movies);
|
||||||
|
AddCategoryMapping("Movies/SDx264", TorznabCatType.MoviesSD);
|
||||||
|
AddCategoryMapping("Movies/XviD", TorznabCatType.MoviesSD);
|
||||||
|
AddCategoryMapping("Music", TorznabCatType.Audio);
|
||||||
|
AddCategoryMapping("Music/FLAC", TorznabCatType.AudioLossless);
|
||||||
|
AddCategoryMapping("Music/Packs", TorznabCatType.AudioOther);
|
||||||
|
AddCategoryMapping("MusicVideos", TorznabCatType.AudioVideo);
|
||||||
|
AddCategoryMapping("TV/DVDR", TorznabCatType.TV);
|
||||||
|
AddCategoryMapping("TV/HDx264", TorznabCatType.TVHD);
|
||||||
|
AddCategoryMapping("TV/Packs", TorznabCatType.TV);
|
||||||
|
AddCategoryMapping("TV/SDx264", TorznabCatType.TVSD);
|
||||||
|
AddCategoryMapping("TV/XViD", TorznabCatType.TVSD);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||||
|
@ -157,22 +192,38 @@ namespace Jackett.Indexers
|
||||||
{ "password", configData.Password.Value }
|
{ "password", configData.Password.Value }
|
||||||
};
|
};
|
||||||
|
|
||||||
//--need to do an initial request to get PHP session cookie (any better way to do this?)
|
// need to do an initial request to get PHP session cookie (any better way to do this?)
|
||||||
var homePageLoad = await RequestLoginAndFollowRedirect(LandingPageURL, new Dictionary<string, string> { }, null, true, null, SiteLink);
|
var homePageLoad = await RequestLoginAndFollowRedirect(LandingPageURL, new Dictionary<string, string> { }, null, true, null, SiteLink);
|
||||||
|
|
||||||
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, homePageLoad.Cookies, true, null, LoginUrl);
|
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, homePageLoad.Cookies, true, null, LandingPageURL);
|
||||||
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("/logout.php"), () =>
|
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("/logout.php"), () =>
|
||||||
{
|
{
|
||||||
CQ dom = result.Content;
|
CQ dom = result.Content;
|
||||||
var messageEl = dom[".error"];
|
var messageEl = dom[".error"];
|
||||||
var errorMessage = messageEl.Text().Trim();
|
var errorMessage = messageEl.Text().Trim();
|
||||||
//--CloudFlare error?
|
|
||||||
if (errorMessage == "")
|
|
||||||
{
|
|
||||||
errorMessage = result.Content;
|
|
||||||
}
|
|
||||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Store RSS key from feed generator page
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var rssParams = new Dictionary<string, string> {
|
||||||
|
{ "feed", "dl" }
|
||||||
|
};
|
||||||
|
var rssPage = await PostDataWithCookies(GetRSSKeyUrl, rssParams, result.Cookies);
|
||||||
|
var match = Regex.Match(rssPage.Content, "(?<=passkey\\=)([a-zA-z0-9]*)");
|
||||||
|
configData.RSSKey.Value = match.Success ? match.Value : string.Empty;
|
||||||
|
if (string.IsNullOrWhiteSpace(configData.RSSKey.Value))
|
||||||
|
throw new Exception("Failed to get RSS Key");
|
||||||
|
SaveConfig();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
IsConfigured = false;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return IndexerConfigurationStatus.RequiresTesting;
|
return IndexerConfigurationStatus.RequiresTesting;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,10 +233,67 @@ namespace Jackett.Indexers
|
||||||
var searchString = query.GetQueryString();
|
var searchString = query.GetQueryString();
|
||||||
var searchUrl = SearchUrl;
|
var searchUrl = SearchUrl;
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(searchString))
|
// If query is empty, use the RSS Feed
|
||||||
|
if (string.IsNullOrWhiteSpace(searchString))
|
||||||
{
|
{
|
||||||
searchUrl += "?titleonly=1&search=" + HttpUtility.UrlEncode(searchString);
|
var rssPage = await RequestStringWithCookiesAndRetry(RSSUrl + configData.RSSKey.Value);
|
||||||
|
var rssDoc = XDocument.Parse(rssPage.Content);
|
||||||
|
|
||||||
|
foreach (var item in rssDoc.Descendants("item"))
|
||||||
|
{
|
||||||
|
var title = item.Descendants("title").First().Value;
|
||||||
|
var description = item.Descendants("description").First().Value;
|
||||||
|
var link = item.Descendants("link").First().Value;
|
||||||
|
var date = item.Descendants("pubDate").First().Value;
|
||||||
|
|
||||||
|
var torrentIdMatch = Regex.Match(link, "(?<=download\\.php/)([a-zA-z0-9]*)");
|
||||||
|
var torrentId = torrentIdMatch.Success ? torrentIdMatch.Value : string.Empty;
|
||||||
|
if (string.IsNullOrWhiteSpace(torrentId))
|
||||||
|
throw new Exception("Missing torrent id");
|
||||||
|
|
||||||
|
var infoMatch = Regex.Match(description, @"Category:\W(?<cat>.*)\W\n\WSize:\W(?<size>.*)\n\WStatus:\W(?<seeders>.*)\Wseeder(.*)\Wand\W(?<leechers>.*)\Wleecher(.*)\n\WAdded:\W(?<added>.*)\n\WDescription:");
|
||||||
|
if (!infoMatch.Success)
|
||||||
|
throw new Exception("Unable to find info");
|
||||||
|
|
||||||
|
var imdbMatch = Regex.Match(description, "(?<=http://www.imdb.com/title/tt)([0-9]*)");
|
||||||
|
long? imdbID = null;
|
||||||
|
if(imdbMatch.Success)
|
||||||
|
{
|
||||||
|
long l;
|
||||||
|
if(long.TryParse(imdbMatch.Value, out l))
|
||||||
|
{
|
||||||
|
imdbID = l;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var release = new ReleaseInfo()
|
||||||
|
{
|
||||||
|
Title = title,
|
||||||
|
Description = title,
|
||||||
|
Guid = new Uri(string.Format(DetailsURL, torrentId)),
|
||||||
|
Comments = new Uri(string.Format(DetailsURL, torrentId) + "&tocomm=1"),
|
||||||
|
PublishDate = DateTime.ParseExact(infoMatch.Groups["added"].Value, "yyyy-MM-dd H:mm:ss", CultureInfo.InvariantCulture), //2015-08-08 21:20:31
|
||||||
|
Link = new Uri(link),
|
||||||
|
Seeders = ParseUtil.CoerceInt(infoMatch.Groups["seeders"].Value == "no" ? "0" : infoMatch.Groups["seeders"].Value),
|
||||||
|
Peers = ParseUtil.CoerceInt(infoMatch.Groups["leechers"].Value == "no" ? "0" : infoMatch.Groups["leechers"].Value),
|
||||||
|
Size = ReleaseInfo.GetBytes(infoMatch.Groups["size"].Value),
|
||||||
|
Category = MapTrackerCatToNewznab(infoMatch.Groups["cat"].Value),
|
||||||
|
Imdb = imdbID
|
||||||
|
};
|
||||||
|
|
||||||
|
// if unknown category, set to "other"
|
||||||
|
if (release.Category == 0)
|
||||||
|
release.Category = 7000;
|
||||||
|
|
||||||
|
release.Peers += release.Seeders;
|
||||||
|
releases.Add(release);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
searchUrl += "?titleonly=1&search=" + HttpUtility.UrlEncode(searchString);
|
||||||
string.Format(SearchUrl, HttpUtility.UrlEncode(searchString));
|
string.Format(SearchUrl, HttpUtility.UrlEncode(searchString));
|
||||||
|
|
||||||
var cats = MapTorznabCapsToTrackers(query);
|
var cats = MapTorznabCapsToTrackers(query);
|
||||||
|
@ -202,7 +310,7 @@ namespace Jackett.Indexers
|
||||||
{
|
{
|
||||||
CQ dom = results.Content;
|
CQ dom = results.Content;
|
||||||
|
|
||||||
//--table header is the first <tr> in table body, get all rows except this
|
// table header is the first <tr> in table body, get all rows except this
|
||||||
CQ qRows = dom["#torrents-table > tbody > tr:not(:first-child)"];
|
CQ qRows = dom["#torrents-table > tbody > tr:not(:first-child)"];
|
||||||
|
|
||||||
foreach (var row in qRows)
|
foreach (var row in qRows)
|
||||||
|
@ -241,11 +349,11 @@ namespace Jackett.Indexers
|
||||||
releases.Add(release);
|
releases.Add(release);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
OnParseError(results.Content, ex);
|
OnParseError(results.Content, ex);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return releases;
|
return releases;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue