Skip to content

Commit

Permalink
Merge pull request #202 from flightlevel/feature/irc
Browse files Browse the repository at this point in the history
Add TehConnection Indexer & Fix Url Redirect
  • Loading branch information
KZ authored and KZ committed Oct 4, 2015
2 parents f65dbc7 + 5d09f60 commit 1f41542
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ We were previously focused on TV but are working on extending searches to allow
* [ShowRSS](https://showrss.info/)
* [Strike](https://getstrike.net/)
* [T411](http://www.t411.io/)
* [TehConnection](https://tehconnection.eu/)
* [The Pirate Bay](https://thepiratebay.se/)
* [TorrentBytes](https://www.torrentbytes.net/)
* [TorrentDay](https://torrentday.eu/)
Expand Down
Binary file added src/Jackett/Content/logos/tehconnection.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/Jackett/Indexers/BaseIndexer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ protected async Task<WebClientStringResult> RequestLoginAndFollowRedirect(string

if (response.IsRedirect)
{
await FollowIfRedirect(response, request.Url, null, response.Cookies);
await FollowIfRedirect(response, request.Url, redirectUrlOverride, response.Cookies);
}

if (returnCookiesFromFirstCall)
Expand Down
183 changes: 183 additions & 0 deletions src/Jackett/Indexers/TehConnection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
using CsQuery;
using Jackett.Indexers;
using Jackett.Models;
using Jackett.Services;
using Jackett.Utils;
using Jackett.Utils.Clients;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using Jackett.Models.IndexerConfig;

namespace Jackett.Indexers
{
public class TehConnection : BaseIndexer, IIndexer
{
private string LoginUrl { get { return SiteLink + "login.php"; } }
private string indexUrl { get { return SiteLink + "index.php"; } }
private string SearchUrl { get { return SiteLink + "torrents.php"; } }

new ConfigurationDataBasicLoginWithFilter configData
{
get { return (ConfigurationDataBasicLoginWithFilter)base.configData; }
set { base.configData = value; }
}

public TehConnection(IIndexerManagerService i, Logger l, IWebClient c, IProtectionService ps)
: base(name: "TehConnection",
description: "Working towards providing a well-seeded archive of all available digital forms of cinema and film in their highest possible quality",
link: "https://tehconnection.eu/",
caps: new TorznabCapabilities(),
manager: i,
client: c,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLoginWithFilter(@"Enter filter options below to restrict search results.
Separate options with a space if using more than one option.<br>Filter options available:
<br><code>QualityEncodeOnly</code><br><code>FreeLeechOnly</code>"))
{
AddCategoryMapping(7, TorznabCatType.Movies);
AddCategoryMapping(7, TorznabCatType.MoviesForeign);
AddCategoryMapping(7, TorznabCatType.MoviesOther);
AddCategoryMapping(7, TorznabCatType.MoviesSD);
AddCategoryMapping(7, TorznabCatType.MoviesHD);
AddCategoryMapping(7, TorznabCatType.Movies3D);
AddCategoryMapping(7, TorznabCatType.MoviesBluRay);
AddCategoryMapping(7, TorznabCatType.MoviesDVD);
AddCategoryMapping(7, TorznabCatType.MoviesWEBDL);
}

public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
configData.LoadValuesFromJson(configJson);
var pairs = new Dictionary<string, string> {
{ "username", configData.Username.Value },
{ "password", configData.Password.Value },
{ "keeplogged", "1" },
{ "login", "Log In!" }
};

var response = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, indexUrl, SiteLink);

await ConfigureIfOK(response.Cookies, response.Content != null && response.Content.Contains("/logout.php"), () =>
{
CQ dom = response.Content;
string errorMessage = "Unable to login to TehConnection";
throw new ExceptionWithConfigData(errorMessage, configData);
});
return IndexerConfigurationStatus.RequiresTesting;
}

public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>();
bool configFreeLeechOnly = configData.FilterString.Value.ToLowerInvariant().Contains("freeleechonly");
bool configQualityEncodeOnly = configData.FilterString.Value.ToLowerInvariant().Contains("qualityencodeonly");
string movieListSearchUrl;

if (string.IsNullOrEmpty(query.GetQueryString()))
movieListSearchUrl = SearchUrl;
else
{
movieListSearchUrl = string.Format("{0}?action=basic&searchstr={1}", SearchUrl, HttpUtility.UrlEncode(query.GetQueryString()));
}

var results = await RequestStringWithCookiesAndRetry(movieListSearchUrl);
try
{
CQ mdom = results.Content;

var mrows = mdom[".torrent_title_box"];
foreach (var mrow in mrows.Take(5))
{
var mqRow = mrow.Cq();

Uri movieReleasesLink = new Uri(SiteLink.TrimEnd('/') + mqRow.Find("a[title='View Torrent']").First().Attr("href").Trim());
bool commentsPresent = !mqRow.Find("font[class='tags'] > strong > a:contains('Comment')").First().Text().Trim().Contains("0 Comments");
Uri commentsLink = new Uri(SiteLink.TrimEnd('/') + mqRow.Find("font[class='tags'] > strong > a:contains('Comment')").First().Attr("href").Trim());

string imdblink = mqRow.Find("span[class='imdb-number-rating']").Length > 0 ? mqRow.Find("span[class='imdb-number-rating'] > a").First().Attr("href").Trim() : "";
long imdb_id = 0;
try
{
if (!string.IsNullOrWhiteSpace(imdblink) && imdblink.ToLowerInvariant().Contains("tt"))
{
imdb_id = long.Parse(imdblink.Substring(imdblink.LastIndexOf('t') + 1).Replace("/", ""));
}
}
catch { imdb_id = 0; }

var release_results = await RequestStringWithCookiesAndRetry(movieReleasesLink.ToString());

//Iterate over the releases for each movie

CQ dom = release_results.Content;

var rows = dom[".torrent_widget.box.pad"];
foreach (var row in rows)
{
var qRow = row.Cq();

string title = qRow.Find("[id^=desc_] > h2 > strong").First().Text().Trim();
Uri link = new Uri(SiteLink.TrimEnd('/') + qRow.Find("a[title='Download']").First().Attr("href").Trim());
Uri guid = new Uri(SiteLink.TrimEnd('/') + qRow.Find("a[title='Permalink']").First().Attr("href").Trim());
string pubDateStr = qRow.Find("div[class='box pad'] > p:contains('Uploaded by') > span").First().Attr("title").Trim();
DateTime pubDate = DateTime.ParseExact(pubDateStr, "MMM dd yyyy, HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToLocalTime();
string sizeStr = qRow.Find("[id^=desc_] > div > table > tbody > tr > td > strong:contains('Size:')").First().Parent().Parent().Find("td").Last().Text().Trim();
Int32 seeders = Convert.ToInt32(qRow.Find("img[title='Seeders']").First().Parent().Text().Trim());
Int32 peers = Convert.ToInt32(qRow.Find("img[title='Leechers']").First().Parent().Text().Trim()) + seeders;
Uri CoverUrl = new Uri(SiteLink.TrimEnd('/') + dom.Find("div[id='poster'] > a > img").First().Attr("src").Trim());
bool freeleech = qRow.Find("span[class='freeleech']").Length == 1 ? true : false;
bool qualityEncode = qRow.Find("img[class='approved']").Length == 1 ? true : false;
string grabs = qRow.Find("img[title='Snatches']").First().Parent().Text().Trim();
if (String.IsNullOrWhiteSpace(sizeStr))
{
string secondSizeStr = qRow.Find("div[class='details_title'] > strong:contains('(')").Last().Text().Trim();
if (secondSizeStr.Length > 3 && secondSizeStr.Contains("(") && secondSizeStr.Contains(")"))
{ sizeStr = secondSizeStr.Replace("(", "").Replace(")", "").Trim(); }
}

var release = new ReleaseInfo();

release.Title = title;
release.Guid = guid;
release.Link = link;
release.PublishDate = pubDate;
release.Size = ReleaseInfo.GetBytes(sizeStr);
release.Description = release.Title;
release.Seeders = seeders;
release.Peers = peers;
release.MinimumRatio = 1;
release.MinimumSeedTime = 345600;
release.Category = 2000;
if (commentsPresent) { release.Comments = commentsLink; }
if (imdb_id > 0) { release.Imdb = imdb_id; }

if (configFreeLeechOnly && !freeleech)
{
continue; //Skip release if user only wants FreeLeech
}
if (configQualityEncodeOnly && !qualityEncode)
{
continue; //Skip release if user only wants Quality Encode
}

releases.Add(release);
}

}
}
catch (Exception ex)
{
OnParseError(results.Content, ex);
}

return releases;
}
}
}
2 changes: 2 additions & 0 deletions src/Jackett/Jackett.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@
<Compile Include="Indexers\Demonoid.cs" />
<Compile Include="Indexers\FrenchTorrentDb.cs" />
<Compile Include="Indexers\BroadcastTheNet.cs" />
<Compile Include="Indexers\TehConnection.cs" />
<Compile Include="Indexers\Shazbat.cs" />
<Compile Include="Indexers\NxtGn.cs" />
<Compile Include="Indexers\Freshon.cs" />
Expand Down Expand Up @@ -300,6 +301,7 @@
<Compile Include="Models\DTO\ChannelDTO.cs" />
<Compile Include="Models\DTO\IRCommandDTO.cs" />
<Compile Include="Models\DTO\NetworkDTO.cs" />
<Compile Include="Models\IndexerConfig\ConfigurationDataBasicLoginWithFilter.cs" />
<Compile Include="Models\Irc\Channel.cs" />
<Compile Include="Models\Irc\ChannelInfoResult.cs" />
<Compile Include="Models\Irc\DTO\ChannelInfo.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Jackett.Models.IndexerConfig
{
public class ConfigurationDataBasicLoginWithFilter : ConfigurationData
{
public StringItem Username { get; private set; }
public StringItem Password { get; private set; }
public DisplayItem FilterExample { get; private set; }
public StringItem FilterString { get; private set; }

public ConfigurationDataBasicLoginWithFilter(string FilterInstructions)
{
Username = new StringItem { Name = "Username" };
Password = new StringItem { Name = "Password" };
FilterExample = new DisplayItem(FilterInstructions)
{
Name = ""
};
FilterString = new StringItem { Name = "Filters (optional)" };
}


}
}

0 comments on commit 1f41542

Please sign in to comment.