mirror of
https://github.com/Jackett/Jackett.git
synced 2025-09-13 07:24:08 +02:00
Compare commits
21 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
18a44bc7ab | ||
![]() |
5ea5fad357 | ||
![]() |
cad5c89dc2 | ||
![]() |
a9e2f70017 | ||
![]() |
a6139bfef4 | ||
![]() |
d90eedf2a6 | ||
![]() |
ccd799d85d | ||
![]() |
727ea3505b | ||
![]() |
240e35b23d | ||
![]() |
4735e90488 | ||
![]() |
f338f7dcbb | ||
![]() |
3ef6847fe6 | ||
![]() |
c0aaea065c | ||
![]() |
6bab6e7a13 | ||
![]() |
7db73fb3e4 | ||
![]() |
57c70af07d | ||
![]() |
94284ffd06 | ||
![]() |
aa7ce80cd6 | ||
![]() |
a7e5b2a5b5 | ||
![]() |
3eccab8666 | ||
![]() |
179a02c533 |
@@ -27,6 +27,7 @@ We were previously focused on TV but are working on extending searches to allow
|
||||
* [BeyondHD](https://beyondhd.me/)
|
||||
* [BIT-HDTV](https://www.bit-hdtv.com)
|
||||
* [BitMeTV](http://www.bitmetv.org/)
|
||||
* [BTN](http://broadcasthe.net)
|
||||
* [Demonoid](http://www.demonoid.pw/)
|
||||
* [EuTorrents](https://eutorrents.to/)
|
||||
* [FileList](http://filelist.ro/)
|
||||
@@ -48,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/)
|
||||
@@ -96,8 +98,8 @@ Try running with the "--SSLFix true" if you are on Redhat/Fedora/NNS based libcu
|
||||
You can get additional logging with the switches "-t -l". Please post logs if you are unable to resolve your issue with these switches ensuring to remove your username/password/cookies.
|
||||
|
||||
|
||||
### Additional Trackers
|
||||
Jackett's framework allows our team (and any other volunteering dev) to implement new trackers in an hour or two. If you'd like support for a new tracker then feel free to leave a request on the [issues page](https://github.com/zone117x/Jackett/issues) or contact us on IRC (see below). Pull requests must be made to the develop branch.
|
||||
### Contributing
|
||||
All contributions are welcome just send a pull request. Jackett's framework allows our team (and any other volunteering dev) to implement new trackers in an hour or two. If you'd like support for a new tracker but are not a developer then feel free to leave a request on the [issues page](https://github.com/zone117x/Jackett/issues). It is recommended to use Visual studio 2015 when making code changes in this project.
|
||||
|
||||
### Contact & Support
|
||||
Use the github issues pages or talk to us directly at: [irc.freenode.net#jackett](http://webchat.freenode.net/?channels=#jackett).
|
||||
|
@@ -24,11 +24,12 @@
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 6px;
|
||||
box-shadow: 1px 1px 5px 2px #cdcdcd;
|
||||
padding: 10px;
|
||||
width: 270px;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
margin: 5px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#indexers {
|
||||
@@ -50,7 +51,7 @@
|
||||
}
|
||||
|
||||
.indexer {
|
||||
height: 235px;
|
||||
height: 252px;
|
||||
}
|
||||
|
||||
.add-indexer {
|
||||
@@ -58,12 +59,18 @@
|
||||
}
|
||||
|
||||
.indexer-logo {
|
||||
text-align: center;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.indexer-logo > .hidden-name {
|
||||
position: absolute;
|
||||
color: rgba(255, 255, 255, 0);
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.indexer-logo > img {
|
||||
border: 1px solid #828282;
|
||||
width: 100%;
|
||||
border-bottom: 1px solid #FFF;
|
||||
}
|
||||
|
||||
.indexer-name > h3 {
|
||||
@@ -76,7 +83,7 @@
|
||||
}
|
||||
|
||||
.indexer-buttons > .btn {
|
||||
margin-bottom: 10px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
|
||||
@@ -100,6 +107,10 @@
|
||||
margin-left: -5px;
|
||||
}
|
||||
|
||||
.indexer-host {
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.indexer-host > input {
|
||||
font-size: 12px;
|
||||
@@ -107,7 +118,7 @@
|
||||
}
|
||||
|
||||
.setup-item-inputstring {
|
||||
max-width: 260px;
|
||||
max-width: 255px;
|
||||
}
|
||||
|
||||
.setup-item-inputbool input {
|
||||
|
@@ -50,7 +50,7 @@
|
||||
<li>For <b>URL</b> enter the <b>Torznab Host</b> of one of the indexers.</li>
|
||||
<li>For the <b>API key</b> using the key below.</li>
|
||||
</ol>
|
||||
<h4>Adding a Jackett indexer in Couchpoato</h4>
|
||||
<h4>Adding a Jackett indexer in CouchPotato</h4>
|
||||
<ol>
|
||||
<li>Go to <b>Settings > Searchers</b>.</li>
|
||||
<li>Enable <b>TorrentPotato</b> and in the host field enter the <b>TorrentPotato host</b> of one of the indexers.</li>
|
||||
@@ -146,7 +146,11 @@
|
||||
|
||||
<script id="configured-indexer" type="text/x-handlebars-template">
|
||||
<div class="configured-indexer indexer card">
|
||||
<div class="indexer-logo"><img alt="{{name}}" title="{{name}}" src="/logos/{{id}}.png" /></div>
|
||||
<div class="indexer-logo">
|
||||
<!-- Make section browser searchable -->
|
||||
<span class="hidden-name">{{name}}</span>
|
||||
<img alt="{{name}}" title="{{name}}" src="/logos/{{id}}.png" />
|
||||
</div>
|
||||
<div class="indexer-buttons">
|
||||
<button class="btn btn-primary btn-sm indexer-setup" data-id="{{id}}">
|
||||
<span class="glyphicon glyphicon-wrench" aria-hidden="true"></span>
|
||||
@@ -176,7 +180,11 @@
|
||||
</script>
|
||||
<script id="unconfigured-indexer" type="text/x-handlebars-template">
|
||||
<div class="unconfigured-indexer card">
|
||||
<div class="indexer-logo"><img alt="{{name}}" title="{{name}}" src="/logos/{{id}}.png" /></div>
|
||||
<div class="indexer-logo">
|
||||
<!-- Make section browser searchable -->
|
||||
<span class="hidden-name">{{name}}</span>
|
||||
<img alt="{{name}}" title="{{name}}" src="/logos/{{id}}.png" />
|
||||
</div>
|
||||
<div class="indexer-buttons">
|
||||
<a class="btn btn-info" target="_blank" href="{{site_link}}">Visit <span class="glyphicon glyphicon-new-window" aria-hidden="true"></span></a>
|
||||
<button class="indexer-setup btn btn-success" data-id="{{id}}">Setup <span class="glyphicon glyphicon-ok" aria-hidden="true"></span></button>
|
||||
|
BIN
src/Jackett/Content/logos/tehconnection.png
Normal file
BIN
src/Jackett/Content/logos/tehconnection.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.5 KiB |
@@ -364,7 +364,7 @@ namespace Jackett.Indexers
|
||||
|
||||
if (response.IsRedirect)
|
||||
{
|
||||
await FollowIfRedirect(response, request.Url, null, response.Cookies);
|
||||
await FollowIfRedirect(response, request.Url, redirectUrlOverride, response.Cookies);
|
||||
}
|
||||
|
||||
if (returnCookiesFromFirstCall)
|
||||
|
@@ -21,10 +21,11 @@ namespace Jackett.Indexers
|
||||
{
|
||||
public class BitMeTV : BaseIndexer, IIndexer
|
||||
{
|
||||
//https is poorly implemented on BitMeTV. Site uses http to login, but then redirects to https for search
|
||||
private string LoginUrl { get { return SiteLink + "login.php"; } }
|
||||
private string LoginPost { get { return SiteLink + "takelogin.php"; } }
|
||||
private string CaptchaUrl { get { return SiteLink + "visual.php"; } }
|
||||
private string SearchUrl { get { return SiteLink + "browse.php"; } }
|
||||
private string SearchUrl { get { return "https://www.bitmetv.org/browse.php"; } }
|
||||
|
||||
new ConfigurationDataCaptchaLogin configData
|
||||
{
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using CsQuery;
|
||||
using CsQuery;
|
||||
using Jackett.Indexers;
|
||||
using Jackett.Models;
|
||||
using Jackett.Services;
|
||||
@@ -44,38 +44,48 @@ namespace Jackett.Indexers
|
||||
p: ps,
|
||||
configData: new ConfigurationDataBasicLoginWithRSS())
|
||||
{
|
||||
AddCategoryMapping(47, TorznabCatType.Movies3D);
|
||||
AddCategoryMapping(38, TorznabCatType.MoviesHD);
|
||||
AddCategoryMapping(38, TorznabCatType.MoviesWEBDL);
|
||||
AddCategoryMapping(38, TorznabCatType.MoviesBluRay);
|
||||
AddCategoryMapping(5, TorznabCatType.MoviesSD);
|
||||
AddCategoryMapping(23, TorznabCatType.MoviesForeign);
|
||||
AddCategoryMapping(22, TorznabCatType.MoviesSD);
|
||||
AddCategoryMapping(4, TorznabCatType.TVFOREIGN);
|
||||
AddCategoryMapping(4, TorznabCatType.TVSD);
|
||||
AddCategoryMapping(4, TorznabCatType.TVDocumentary);
|
||||
AddCategoryMapping(4, TorznabCatType.TVSport);
|
||||
AddCategoryMapping(4, TorznabCatType.TV);
|
||||
AddCategoryMapping(31, TorznabCatType.TVHD);
|
||||
AddCategoryMapping(21, TorznabCatType.TVFOREIGN);
|
||||
AddCategoryMapping(46, TorznabCatType.TV);
|
||||
AddCategoryMapping(46, TorznabCatType.TVHD);
|
||||
//AddCategoryMapping(45, TorznabCatType.TV);
|
||||
//AddCategoryMapping(45, TorznabCatType.TVSD);
|
||||
//AddCategoryMapping(24, TorznabCatType.TVFOREIGN);
|
||||
AddCategoryMapping(26, TorznabCatType.TV);
|
||||
AddCategoryMapping(26, TorznabCatType.TVHD);
|
||||
AddCategoryMapping(26, TorznabCatType.TVWEBDL);
|
||||
AddCategoryMapping(33, TorznabCatType.MoviesHD);
|
||||
AddCategoryMapping(33, TorznabCatType.Movies);
|
||||
AddCategoryMapping(17, TorznabCatType.MoviesForeign);
|
||||
AddCategoryMapping(17, TorznabCatType.MoviesDVD);
|
||||
AddCategoryMapping(9, TorznabCatType.MoviesHD);
|
||||
AddCategoryMapping(9, TorznabCatType.Movies);
|
||||
AddCategoryMapping(9, TorznabCatType.MoviesBluRay);
|
||||
AddCategoryMapping(43, TorznabCatType.TV);
|
||||
AddCategoryMapping(43, TorznabCatType.TVHD);
|
||||
AddCategoryMapping(43, TorznabCatType.TVWEBDL);
|
||||
//Movies Mapping
|
||||
AddCategoryMapping(9, TorznabCatType.MoviesHD);
|
||||
AddCategoryMapping(9, TorznabCatType.Movies);
|
||||
AddCategoryMapping(9, TorznabCatType.MoviesBluRay);
|
||||
AddCategoryMapping(47, TorznabCatType.Movies3D);
|
||||
AddCategoryMapping(38, TorznabCatType.MoviesHD);
|
||||
AddCategoryMapping(38, TorznabCatType.MoviesWEBDL);
|
||||
AddCategoryMapping(38, TorznabCatType.MoviesBluRay);
|
||||
AddCategoryMapping(5, TorznabCatType.MoviesSD);
|
||||
AddCategoryMapping(23, TorznabCatType.MoviesForeign);
|
||||
AddCategoryMapping(22, TorznabCatType.MoviesSD);
|
||||
AddCategoryMapping(33, TorznabCatType.MoviesHD);
|
||||
AddCategoryMapping(33, TorznabCatType.Movies);
|
||||
AddCategoryMapping(17, TorznabCatType.MoviesForeign);
|
||||
AddCategoryMapping(17, TorznabCatType.MoviesDVD);
|
||||
|
||||
//TV Mapping
|
||||
//Category 4: TV (Working)
|
||||
AddCategoryMapping(4, TorznabCatType.TVSD);
|
||||
AddCategoryMapping(4, TorznabCatType.TV);
|
||||
AddCategoryMapping(4, TorznabCatType.TVHD);
|
||||
//Category 21: Boxset/SD (Working)
|
||||
AddCategoryMapping(21, TorznabCatType.TVFOREIGN);
|
||||
//Category 24: Boxsets/TV (Working)
|
||||
AddCategoryMapping(24, TorznabCatType.TVFOREIGN);
|
||||
//Category 26: NG Serier WEB-DL (Working)
|
||||
AddCategoryMapping(26, TorznabCatType.TVHD);
|
||||
AddCategoryMapping(26, TorznabCatType.TV);
|
||||
AddCategoryMapping(26, TorznabCatType.TVWEBDL);
|
||||
//Category 31: TVHD (Working)
|
||||
AddCategoryMapping(31, TorznabCatType.TVHD);
|
||||
AddCategoryMapping(31, TorznabCatType.TV);
|
||||
//Category 43: NG WWW HD (Working)
|
||||
AddCategoryMapping(43, TorznabCatType.TVHD);
|
||||
AddCategoryMapping(43, TorznabCatType.TV);
|
||||
AddCategoryMapping(43, TorznabCatType.TVWEBDL);
|
||||
//Category 45: TV-Misc (Working)
|
||||
AddCategoryMapping(45, TorznabCatType.TV);
|
||||
AddCategoryMapping(45, TorznabCatType.TVSD);
|
||||
//Category 46: NG Serier HDTV (Working)
|
||||
AddCategoryMapping(46, TorznabCatType.TVHD);
|
||||
AddCategoryMapping(46, TorznabCatType.TV);
|
||||
}
|
||||
|
||||
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
@@ -146,7 +156,7 @@ namespace Jackett.Indexers
|
||||
var qDesc = qRow.Find("#torrent-udgivelse2-users > p").FirstOrDefault();
|
||||
|
||||
var moviesCats = new[] { 47, 38, 5, 23, 22, 33, 17, 9 };
|
||||
var seriesCats = new[] { 46, 26, 43 };
|
||||
var seriesCats = new[] { 4, 21, 24, 26, 31, 43, 45, 46 };
|
||||
var catUrl = qRow.Find(".torrent-icon > a").Attr("href");
|
||||
var cat = catUrl.Substring(catUrl.LastIndexOf('=') + 1);
|
||||
var catNo = int.Parse(cat);
|
||||
|
@@ -181,7 +181,7 @@ namespace Jackett.Indexers
|
||||
if (hasTorrent)
|
||||
titleIndex++;
|
||||
|
||||
release.Title = row.Cq().Find("td:eq(" + titleIndex + ")").Text().Trim();
|
||||
release.Title = row.Cq().Find("td:eq(1) a:eq(" + titleIndex + ")").Text().Trim();
|
||||
if (configData.StripRussian.Value)
|
||||
{
|
||||
var split = release.Title.IndexOf('/');
|
||||
|
@@ -19,7 +19,7 @@ namespace Jackett.Indexers
|
||||
class SceneAccess : BaseIndexer, IIndexer
|
||||
{
|
||||
private string LoginUrl { get { return SiteLink + "login"; } }
|
||||
private string SearchUrl { get { return SiteLink + "{0}?method=1&c{1}=1&search={2}"; } }
|
||||
private string SearchUrl { get { return SiteLink + "browse?search={0}&method=2&c27=27&c17=17&c11=11"; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
{
|
||||
@@ -67,10 +67,7 @@ namespace Jackett.Indexers
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
var searchSection = string.IsNullOrEmpty(query.Episode) ? "archive" : "browse";
|
||||
var searchCategory = string.IsNullOrEmpty(query.Episode) ? "26" : "27";
|
||||
var searchUrl = string.Format(SearchUrl, searchSection, searchCategory, query.GetQueryString());
|
||||
var results = await RequestStringWithCookiesAndRetry(searchUrl);
|
||||
var results = await RequestStringWithCookiesAndRetry(string.Format(SearchUrl, query.GetQueryString()));
|
||||
|
||||
try
|
||||
{
|
||||
@@ -102,6 +99,17 @@ namespace Jackett.Indexers
|
||||
release.Seeders = ParseUtil.CoerceInt(qRow.Find(".ttr_seeders").Text());
|
||||
release.Peers = ParseUtil.CoerceInt(qRow.Find(".ttr_leechers").Text()) + release.Seeders;
|
||||
|
||||
var cat = qRow.Find(".ttr_type a").Attr("href");
|
||||
|
||||
if (cat == "?cat=27")
|
||||
{
|
||||
release.Category = TorznabCatType.TVHD.ID;
|
||||
}
|
||||
else if (cat == "?cat=17")
|
||||
{
|
||||
release.Category = TorznabCatType.TVSD.ID;
|
||||
}
|
||||
|
||||
releases.Add(release);
|
||||
}
|
||||
}
|
||||
|
@@ -91,114 +91,118 @@ namespace Jackett.Indexers
|
||||
|
||||
WebClientStringResult results = null;
|
||||
|
||||
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "portlet", "true"}
|
||||
};
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(queryString))
|
||||
{
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "search", queryString},
|
||||
{ "portlet", "true"}
|
||||
};
|
||||
|
||||
pairs.Add("search", queryString);
|
||||
results = await PostDataWithCookiesAndRetry(SearchUrl, pairs, null, TorrentsUrl);
|
||||
|
||||
try
|
||||
{
|
||||
CQ dom = results.Content;
|
||||
var rows = dom["#torrent-table tr"];
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(queryString))
|
||||
{
|
||||
rows = dom["table tr"];
|
||||
}
|
||||
|
||||
foreach (var row in rows.Skip(1))
|
||||
{
|
||||
var release = new ReleaseInfo();
|
||||
var qRow = row.Cq();
|
||||
var titleRow = qRow.Find("td:eq(2)").First();
|
||||
titleRow.Children().Remove();
|
||||
release.Title = titleRow.Text().Trim();
|
||||
if (string.IsNullOrWhiteSpace(release.Title))
|
||||
continue;
|
||||
release.Description = release.Title;
|
||||
|
||||
var qLink = row.Cq().Find("td:eq(4) a:eq(0)");
|
||||
release.Link = new Uri(SiteLink + qLink.Attr("href"));
|
||||
release.Guid = release.Link;
|
||||
var qLinkComm = row.Cq().Find("td:eq(4) a:eq(1)");
|
||||
release.Comments = new Uri(SiteLink + qLinkComm.Attr("href"));
|
||||
|
||||
var dateString = qRow.Find(".datetime").Attr("data-timestamp");
|
||||
release.PublishDate = DateTimeUtil.UnixTimestampToDateTime(ParseUtil.CoerceDouble(dateString));
|
||||
var infoString = row.Cq().Find("td:eq(3)").Text();
|
||||
|
||||
release.Size = ParseUtil.CoerceLong(Regex.Match(infoString, "\\((\\d+)\\)").Value.Replace("(", "").Replace(")", ""));
|
||||
|
||||
var infosplit = infoString.Replace("/", string.Empty).Split(":".ToCharArray());
|
||||
release.Seeders = ParseUtil.CoerceInt(infosplit[1]);
|
||||
release.Peers = release.Seeders + ParseUtil.CoerceInt(infosplit[2]);
|
||||
|
||||
// var tags = row.Cq().Find(".label-tag").Text(); These don't see to parse - bad tags?
|
||||
|
||||
releases.Add(release);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(results.Content, ex);
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
{
|
||||
var rssUrl = SiteLink + "rss/recent?passkey=" + configData.RSSKey.Value;
|
||||
|
||||
results = await RequestStringWithCookiesAndRetry(rssUrl);
|
||||
try
|
||||
{
|
||||
var doc = XDocument.Parse(results.Content);
|
||||
foreach (var result in doc.Descendants("item"))
|
||||
{
|
||||
var xTitle = result.Element("title").Value;
|
||||
var xLink = result.Element("link").Value;
|
||||
var xGUID = result.Element("guid").Value;
|
||||
var xDesc = result.Element("description").Value;
|
||||
var xDate = result.Element("pubDate").Value;
|
||||
var release = new ReleaseInfo();
|
||||
release.Guid =release.Link = new Uri(xLink);
|
||||
release.MinimumRatio = 1;
|
||||
release.Seeders = 1; // We are not supplied with peer info so just mark it as one.
|
||||
foreach (var element in xDesc.Split(";".ToCharArray()))
|
||||
{
|
||||
var split = element.IndexOf(':');
|
||||
if (split > -1)
|
||||
{
|
||||
var key = element.Substring(0, split).Trim();
|
||||
var value = element.Substring(split+1).Trim();
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case "Filename":
|
||||
release.Title = release.Description = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//"Thu, 24 Sep 2015 18:07:07 +0000"
|
||||
release.PublishDate = DateTime.ParseExact(xDate, "ddd, dd MMM yyyy HH:mm:ss +0000", CultureInfo.InvariantCulture);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(release.Title))
|
||||
{
|
||||
releases.Add(release);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(results.Content, ex);
|
||||
}
|
||||
results = await PostDataWithCookiesAndRetry(TorrentsUrl, pairs, null, TorrentsUrl);
|
||||
}
|
||||
|
||||
foreach(var release in releases)
|
||||
try
|
||||
{
|
||||
CQ dom = results.Content;
|
||||
var rows = dom["#torrent-table tr"];
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(queryString))
|
||||
{
|
||||
rows = dom["table tr"];
|
||||
}
|
||||
|
||||
foreach (var row in rows.Skip(1))
|
||||
{
|
||||
var release = new ReleaseInfo();
|
||||
var qRow = row.Cq();
|
||||
var titleRow = qRow.Find("td:eq(2)").First();
|
||||
titleRow.Children().Remove();
|
||||
release.Title = titleRow.Text().Trim();
|
||||
if (string.IsNullOrWhiteSpace(release.Title))
|
||||
continue;
|
||||
release.Description = release.Title;
|
||||
|
||||
var qLink = row.Cq().Find("td:eq(4) a:eq(0)");
|
||||
release.Link = new Uri(SiteLink + qLink.Attr("href"));
|
||||
release.Guid = release.Link;
|
||||
var qLinkComm = row.Cq().Find("td:eq(4) a:eq(1)");
|
||||
release.Comments = new Uri(SiteLink + qLinkComm.Attr("href"));
|
||||
|
||||
var dateString = qRow.Find(".datetime").Attr("data-timestamp");
|
||||
release.PublishDate = DateTimeUtil.UnixTimestampToDateTime(ParseUtil.CoerceDouble(dateString));
|
||||
var infoString = row.Cq().Find("td:eq(3)").Text();
|
||||
|
||||
release.Size = ParseUtil.CoerceLong(Regex.Match(infoString, "\\((\\d+)\\)").Value.Replace("(", "").Replace(")", ""));
|
||||
|
||||
var infosplit = infoString.Replace("/", string.Empty).Split(":".ToCharArray());
|
||||
release.Seeders = ParseUtil.CoerceInt(infosplit[1]);
|
||||
release.Peers = release.Seeders + ParseUtil.CoerceInt(infosplit[2]);
|
||||
|
||||
// var tags = row.Cq().Find(".label-tag").Text(); These don't see to parse - bad tags?
|
||||
|
||||
releases.Add(release);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(results.Content, ex);
|
||||
}
|
||||
/* else
|
||||
{
|
||||
var rssUrl = SiteLink + "rss/recent?passkey=" + configData.RSSKey.Value;
|
||||
|
||||
results = await RequestStringWithCookiesAndRetry(rssUrl);
|
||||
try
|
||||
{
|
||||
var doc = XDocument.Parse(results.Content);
|
||||
foreach (var result in doc.Descendants("item"))
|
||||
{
|
||||
var xTitle = result.Element("title").Value;
|
||||
var xLink = result.Element("link").Value;
|
||||
var xGUID = result.Element("guid").Value;
|
||||
var xDesc = result.Element("description").Value;
|
||||
var xDate = result.Element("pubDate").Value;
|
||||
var release = new ReleaseInfo();
|
||||
release.Guid =release.Link = new Uri(xLink);
|
||||
release.MinimumRatio = 1;
|
||||
release.Seeders = 1; // We are not supplied with peer info so just mark it as one.
|
||||
foreach (var element in xDesc.Split(";".ToCharArray()))
|
||||
{
|
||||
var split = element.IndexOf(':');
|
||||
if (split > -1)
|
||||
{
|
||||
var key = element.Substring(0, split).Trim();
|
||||
var value = element.Substring(split+1).Trim();
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case "Filename":
|
||||
release.Title = release.Description = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//"Thu, 24 Sep 2015 18:07:07 +0000"
|
||||
release.PublishDate = DateTime.ParseExact(xDate, "ddd, dd MMM yyyy HH:mm:ss +0000", CultureInfo.InvariantCulture);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(release.Title))
|
||||
{
|
||||
releases.Add(release);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(results.Content, ex);
|
||||
}*/
|
||||
|
||||
|
||||
foreach (var release in releases)
|
||||
{
|
||||
if (release.Title.Contains("1080p") || release.Title.Contains("720p"))
|
||||
{
|
||||
|
184
src/Jackett/Indexers/TehConnection.cs
Normal file
184
src/Jackett/Indexers/TehConnection.cs
Normal file
@@ -0,0 +1,184 @@
|
||||
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());
|
||||
Uri commentsLink = new Uri(movieReleasesLink + "#comments");
|
||||
|
||||
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();
|
||||
var seeders = ParseUtil.CoerceInt(qRow.Find("img[title='Seeders']").First().Parent().Text().Trim());
|
||||
var peers = ParseUtil.CoerceInt(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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -32,13 +32,13 @@ namespace Jackett.Indexers
|
||||
public TorrentLeech(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
|
||||
: base(name: "TorrentLeech",
|
||||
description: "This is what happens when you seed",
|
||||
link: "http://www.torrentleech.org/",
|
||||
link: "https://www.torrentleech.org/",
|
||||
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: wc,
|
||||
logger: l,
|
||||
p: ps,
|
||||
downloadBase: "http://www.torrentleech.org/download/",
|
||||
downloadBase: "https://www.torrentleech.org/download/",
|
||||
configData: new ConfigurationDataBasicLogin())
|
||||
{
|
||||
|
||||
|
@@ -186,6 +186,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" />
|
||||
@@ -196,6 +197,7 @@
|
||||
<Compile Include="Indexers\FileList.cs" />
|
||||
<Compile Include="Indexers\Abstract\AvistazTracker.cs" />
|
||||
<Compile Include="Indexers\AnimeTorrents.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataBasicLoginWithFilter.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataAPIKey.cs" />
|
||||
<Compile Include="Models\ManualSearchResult.cs" />
|
||||
<Compile Include="Indexers\Rarbg.cs" />
|
||||
@@ -491,6 +493,9 @@
|
||||
<Content Include="Content\logos\t411.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\logos\tehconnection.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\logos\torrentbytes.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
@@ -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)" };
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("0.6.7.0")]
|
||||
[assembly: AssemblyFileVersion("0.6.7.0")]
|
||||
[assembly: AssemblyVersion("0.6.8.0")]
|
||||
[assembly: AssemblyFileVersion("0.6.8.0")]
|
||||
|
Reference in New Issue
Block a user