mirror of
https://github.com/Jackett/Jackett.git
synced 2025-09-17 17:34:09 +02:00
Category mapping on TorrentLeech and AnimeBytes. Fix sparadic issue where downloads fail due to the url being too long.
This commit is contained in:
@@ -17,7 +17,7 @@
|
|||||||
<TargetFrameworkProfile />
|
<TargetFrameworkProfile />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<Optimize>false</Optimize>
|
<Optimize>false</Optimize>
|
||||||
|
@@ -53,7 +53,7 @@ $("#jackett-show-releases").click(function () {
|
|||||||
{
|
{
|
||||||
"pageLength": 20,
|
"pageLength": 20,
|
||||||
"lengthMenu": [[10, 20, 50, -1], [10, 20, 50, "All"]],
|
"lengthMenu": [[10, 20, 50, -1], [10, 20, 50, "All"]],
|
||||||
"order": [[2, "desc"]],
|
"order": [[0, "desc"]],
|
||||||
"columnDefs": [
|
"columnDefs": [
|
||||||
{
|
{
|
||||||
"targets": 0,
|
"targets": 0,
|
||||||
|
@@ -396,8 +396,19 @@ namespace Jackett.Controllers
|
|||||||
[HttpGet]
|
[HttpGet]
|
||||||
public List<TrackerCacheResult> GetCache()
|
public List<TrackerCacheResult> GetCache()
|
||||||
{
|
{
|
||||||
var severUrl = string.Format("{0}://{1}:{2}/", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port);
|
var serverUrl = string.Format("{0}://{1}:{2}/", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port);
|
||||||
return cacheService.GetCachedResults(severUrl);
|
var results = cacheService.GetCachedResults();
|
||||||
|
|
||||||
|
foreach (var result in results)
|
||||||
|
{
|
||||||
|
var link = result.Link;
|
||||||
|
result.Link = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId);
|
||||||
|
if (result.Link != null && result.Link.Scheme != "magnet" && !string.IsNullOrWhiteSpace(Engine.Server.Config.BlackholeDir))
|
||||||
|
result.BlackholeLink = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "bh", string.Empty);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("GetLogs")]
|
[Route("GetLogs")]
|
||||||
|
@@ -21,15 +21,17 @@ namespace Jackett.Controllers
|
|||||||
{
|
{
|
||||||
private Logger logger;
|
private Logger logger;
|
||||||
private IIndexerManagerService indexerService;
|
private IIndexerManagerService indexerService;
|
||||||
|
IServerService serverService;
|
||||||
|
|
||||||
public BlackholeController(IIndexerManagerService i, Logger l)
|
public BlackholeController(IIndexerManagerService i, Logger l, IServerService s)
|
||||||
{
|
{
|
||||||
logger = l;
|
logger = l;
|
||||||
indexerService = i;
|
indexerService = i;
|
||||||
|
serverService = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<IHttpActionResult> Blackhole(string indexerID, string path)
|
public async Task<IHttpActionResult> Blackhole(string indexerID, string path, string apikey)
|
||||||
{
|
{
|
||||||
|
|
||||||
var jsonReply = new JObject();
|
var jsonReply = new JObject();
|
||||||
@@ -42,8 +44,13 @@ namespace Jackett.Controllers
|
|||||||
throw new Exception("This indexer is not configured.");
|
throw new Exception("This indexer is not configured.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var remoteFile = Encoding.UTF8.GetString(HttpServerUtility.UrlTokenDecode(path));
|
if (serverService.Config.APIKey != apikey)
|
||||||
var downloadBytes = await indexer.Download(new Uri(remoteFile, UriKind.RelativeOrAbsolute));
|
throw new Exception("Incorrect API key");
|
||||||
|
|
||||||
|
var remoteFile = new Uri(Encoding.UTF8.GetString(HttpServerUtility.UrlTokenDecode(path)), UriKind.RelativeOrAbsolute);
|
||||||
|
remoteFile = indexer.UncleanLink(remoteFile);
|
||||||
|
|
||||||
|
var downloadBytes = await indexer.Download(remoteFile);
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(Engine.Server.Config.BlackholeDir))
|
if (string.IsNullOrWhiteSpace(Engine.Server.Config.BlackholeDir))
|
||||||
{
|
{
|
||||||
|
@@ -17,17 +17,19 @@ namespace Jackett.Controllers
|
|||||||
[JackettAPINoCache]
|
[JackettAPINoCache]
|
||||||
public class DownloadController : ApiController
|
public class DownloadController : ApiController
|
||||||
{
|
{
|
||||||
private Logger logger;
|
Logger logger;
|
||||||
private IIndexerManagerService indexerService;
|
IIndexerManagerService indexerService;
|
||||||
|
IServerService serverService;
|
||||||
|
|
||||||
public DownloadController(IIndexerManagerService i, Logger l)
|
public DownloadController(IIndexerManagerService i, Logger l, IServerService s)
|
||||||
{
|
{
|
||||||
logger = l;
|
logger = l;
|
||||||
indexerService = i;
|
indexerService = i;
|
||||||
|
serverService = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<HttpResponseMessage> Download(string indexerID, string path)
|
public async Task<HttpResponseMessage> Download(string indexerID, string path, string apikey)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -39,8 +41,15 @@ namespace Jackett.Controllers
|
|||||||
return Request.CreateResponse(HttpStatusCode.Forbidden, "This indexer is not configured.");
|
return Request.CreateResponse(HttpStatusCode.Forbidden, "This indexer is not configured.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var remoteFile = Encoding.UTF8.GetString(HttpServerUtility.UrlTokenDecode(path));
|
path = Encoding.UTF8.GetString(HttpServerUtility.UrlTokenDecode(path));
|
||||||
var downloadBytes = await indexer.Download(new Uri(remoteFile, UriKind.RelativeOrAbsolute));
|
|
||||||
|
if (serverService.Config.APIKey != apikey)
|
||||||
|
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||||
|
|
||||||
|
var target = new Uri(path, UriKind.RelativeOrAbsolute);
|
||||||
|
target = indexer.UncleanLink(target);
|
||||||
|
|
||||||
|
var downloadBytes = await indexer.Download(target);
|
||||||
|
|
||||||
var result = new HttpResponseMessage(HttpStatusCode.OK);
|
var result = new HttpResponseMessage(HttpStatusCode.OK);
|
||||||
result.Content = new ByteArrayContent(downloadBytes);
|
result.Content = new ByteArrayContent(downloadBytes);
|
||||||
|
@@ -95,6 +95,7 @@ namespace Jackett.Controllers
|
|||||||
if (!string.IsNullOrWhiteSpace(torznabQuery.SanitizedSearchTerm))
|
if (!string.IsNullOrWhiteSpace(torznabQuery.SanitizedSearchTerm))
|
||||||
{
|
{
|
||||||
releases = await indexer.PerformQuery(torznabQuery);
|
releases = await indexer.PerformQuery(torznabQuery);
|
||||||
|
releases = indexer.CleanLinks(releases);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache non query results
|
// Cache non query results
|
||||||
@@ -112,7 +113,7 @@ namespace Jackett.Controllers
|
|||||||
foreach (var r in releases)
|
foreach (var r in releases)
|
||||||
{
|
{
|
||||||
var release = Mapper.Map<ReleaseInfo>(r);
|
var release = Mapper.Map<ReleaseInfo>(r);
|
||||||
release.Link = release.ConvertToProxyLink(serverUrl, indexerID);
|
release.Link = serverService.ConvertToProxyLink(release.Link, serverUrl, indexerID);
|
||||||
|
|
||||||
potatoResponse.results.Add(new TorrentPotatoResponseItem()
|
potatoResponse.results.Add(new TorrentPotatoResponseItem()
|
||||||
{
|
{
|
||||||
|
@@ -64,6 +64,7 @@ namespace Jackett.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
var releases = await indexer.PerformQuery(torznabQuery);
|
var releases = await indexer.PerformQuery(torznabQuery);
|
||||||
|
releases = indexer.CleanLinks(releases);
|
||||||
|
|
||||||
// Some trackers do not keep their clocks up to date and can be ~20 minutes out!
|
// Some trackers do not keep their clocks up to date and can be ~20 minutes out!
|
||||||
foreach (var release in releases)
|
foreach (var release in releases)
|
||||||
@@ -115,7 +116,7 @@ namespace Jackett.Controllers
|
|||||||
foreach(var result in releases)
|
foreach(var result in releases)
|
||||||
{
|
{
|
||||||
var clone = Mapper.Map<ReleaseInfo>(result);
|
var clone = Mapper.Map<ReleaseInfo>(result);
|
||||||
clone.Link = clone.ConvertToProxyLink(serverUrl, indexerID);
|
clone.Link = serverService.ConvertToProxyLink(clone.Link, serverUrl, indexerID);
|
||||||
resultPage.Releases.Add(clone);
|
resultPage.Releases.Add(clone);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -35,6 +35,7 @@ namespace Jackett.Indexers
|
|||||||
client: w,
|
client: w,
|
||||||
logger: l,
|
logger: l,
|
||||||
p: ps,
|
p: ps,
|
||||||
|
downloadBase: "https://alpharatio.cc/torrents.php?action=download&id=",
|
||||||
configData: new ConfigurationDataBasicLogin())
|
configData: new ConfigurationDataBasicLogin())
|
||||||
{
|
{
|
||||||
AddCategoryMapping(1, TorznabCatType.TVSD);
|
AddCategoryMapping(1, TorznabCatType.TVSD);
|
||||||
|
@@ -24,7 +24,7 @@ namespace Jackett.Indexers
|
|||||||
public class AnimeBytes : BaseIndexer, IIndexer
|
public class AnimeBytes : BaseIndexer, IIndexer
|
||||||
{
|
{
|
||||||
private string LoginUrl { get { return SiteLink + "user/login"; } }
|
private string LoginUrl { get { return SiteLink + "user/login"; } }
|
||||||
private string SearchUrl { get { return SiteLink + "torrents.php?filter_cat[1]=1"; } }
|
private string SearchUrl { get { return SiteLink + "torrents.php?"; } }
|
||||||
public bool AllowRaws { get { return configData.IncludeRaw.Value; } }
|
public bool AllowRaws { get { return configData.IncludeRaw.Value; } }
|
||||||
|
|
||||||
new ConfigurationDataAnimeBytes configData
|
new ConfigurationDataAnimeBytes configData
|
||||||
@@ -39,11 +39,17 @@ namespace Jackett.Indexers
|
|||||||
description: "Powered by Tentacles",
|
description: "Powered by Tentacles",
|
||||||
manager: i,
|
manager: i,
|
||||||
client: client,
|
client: client,
|
||||||
caps: new TorznabCapabilities(TorznabCatType.TVAnime),
|
caps: new TorznabCapabilities(TorznabCatType.TVAnime,
|
||||||
|
TorznabCatType.Movies,
|
||||||
|
TorznabCatType.BooksComics,
|
||||||
|
TorznabCatType.ConsolePSP,
|
||||||
|
TorznabCatType.ConsoleOther,
|
||||||
|
TorznabCatType.PCGames),
|
||||||
logger: l,
|
logger: l,
|
||||||
p: ps,
|
p: ps,
|
||||||
configData: new ConfigurationDataAnimeBytes())
|
configData: new ConfigurationDataAnimeBytes())
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ApplyConfiguration(JToken configJson)
|
public async Task ApplyConfiguration(JToken configJson)
|
||||||
@@ -125,6 +131,8 @@ namespace Jackett.Indexers
|
|||||||
|
|
||||||
public async Task<IEnumerable<ReleaseInfo>> GetResults(string searchTerm)
|
public async Task<IEnumerable<ReleaseInfo>> GetResults(string searchTerm)
|
||||||
{
|
{
|
||||||
|
var cleanSearchTerm = HttpUtility.UrlEncode(searchTerm);
|
||||||
|
|
||||||
// This tracker only deals with full seasons so chop off the episode/season number if we have it D:
|
// This tracker only deals with full seasons so chop off the episode/season number if we have it D:
|
||||||
if (!string.IsNullOrWhiteSpace(searchTerm))
|
if (!string.IsNullOrWhiteSpace(searchTerm))
|
||||||
{
|
{
|
||||||
@@ -151,7 +159,7 @@ namespace Jackett.Indexers
|
|||||||
// Only include the query bit if its required as hopefully the site caches the non query page
|
// Only include the query bit if its required as hopefully the site caches the non query page
|
||||||
if (!string.IsNullOrWhiteSpace(searchTerm))
|
if (!string.IsNullOrWhiteSpace(searchTerm))
|
||||||
{
|
{
|
||||||
queryUrl += "&action=advanced&search_type=title&sort=time_added&way=desc&anime%5Btv_series%5D=1&searchstr=" + WebUtility.UrlEncode(searchTerm);
|
queryUrl += string.Format("searchstr={0}&action=advanced&search_type=title&year=&year2=&tags=&tags_type=0&sort=time_added&way=desc&hentai=2&releasegroup=&epcount=&epcount2=&artbooktitle=", cleanSearchTerm);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the content from the tracker
|
// Get the content from the tracker
|
||||||
@@ -162,7 +170,7 @@ namespace Jackett.Indexers
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var releaseInfo = "S01";
|
var releaseInfo = "S01";
|
||||||
var root = dom.Find(".anime");
|
var root = dom.Find(".group_cont");
|
||||||
// We may have got redirected to the series page if we have none of these
|
// We may have got redirected to the series page if we have none of these
|
||||||
if (root.Count() == 0)
|
if (root.Count() == 0)
|
||||||
root = dom.Find(".torrent_table");
|
root = dom.Find(".torrent_table");
|
||||||
@@ -215,7 +223,7 @@ namespace Jackett.Indexers
|
|||||||
var releaseRows = seriesCq.Find(".torrent_group tr");
|
var releaseRows = seriesCq.Find(".torrent_group tr");
|
||||||
|
|
||||||
// Skip the first two info rows
|
// Skip the first two info rows
|
||||||
for (int r = 2; r < releaseRows.Count(); r++)
|
for (int r = 1; r < releaseRows.Count(); r++)
|
||||||
{
|
{
|
||||||
var row = releaseRows.Get(r);
|
var row = releaseRows.Get(r);
|
||||||
var rowCq = row.Cq();
|
var rowCq = row.Cq();
|
||||||
@@ -257,6 +265,37 @@ namespace Jackett.Indexers
|
|||||||
release.Guid = new Uri(SiteLink + infoLink.Attributes.GetAttribute("href") + "&nh=" + StringUtil.Hash(title)); // Sonarr should dedupe on this url - allow a url per name.
|
release.Guid = new Uri(SiteLink + infoLink.Attributes.GetAttribute("href") + "&nh=" + StringUtil.Hash(title)); // Sonarr should dedupe on this url - allow a url per name.
|
||||||
release.Link = new Uri(downloadLink.Attributes.GetAttribute("href"), UriKind.Relative);
|
release.Link = new Uri(downloadLink.Attributes.GetAttribute("href"), UriKind.Relative);
|
||||||
|
|
||||||
|
var category = seriesCq.Find("a[title=\"View Torrent\"]").Text().Trim();
|
||||||
|
if (category == "TV Series")
|
||||||
|
release.Category = TorznabCatType.TVAnime.ID;
|
||||||
|
|
||||||
|
// Ignore these categories as they'll cause hell with the matcher
|
||||||
|
// TV Special, OVA, ONA, DVD Special, BD Special
|
||||||
|
|
||||||
|
if (category == "Movie")
|
||||||
|
release.Category = TorznabCatType.Movies.ID;
|
||||||
|
|
||||||
|
if (category == "Manga" || category == "Oneshot" || category == "Anthology" || category == "Manhwa" || category == "Manhua" || category == "Light Novel")
|
||||||
|
release.Category = TorznabCatType.BooksComics.ID;
|
||||||
|
|
||||||
|
if (category == "Novel" || category == "Artbook")
|
||||||
|
release.Category = TorznabCatType.BooksComics.ID;
|
||||||
|
|
||||||
|
if (category == "Game" || category == "Visual Novel")
|
||||||
|
{
|
||||||
|
var description = rowCq.Find(".torrent_properties a:eq(1)").Text();
|
||||||
|
if (description.Contains(" PSP "))
|
||||||
|
release.Category = TorznabCatType.ConsolePSP.ID;
|
||||||
|
if (description.Contains("PSX"))
|
||||||
|
release.Category = TorznabCatType.ConsoleOther.ID;
|
||||||
|
if (description.Contains(" NES "))
|
||||||
|
release.Category = TorznabCatType.ConsoleOther.ID;
|
||||||
|
if (description.Contains(" PC "))
|
||||||
|
release.Category = TorznabCatType.PCGames.ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// We dont actually have a release name >.> so try to create one
|
// We dont actually have a release name >.> so try to create one
|
||||||
var releaseTags = infoLink.InnerText.Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).ToList();
|
var releaseTags = infoLink.InnerText.Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||||
for (int i = releaseTags.Count - 1; i >= 0; i--)
|
for (int i = releaseTags.Count - 1; i >= 0; i--)
|
||||||
@@ -287,10 +326,19 @@ namespace Jackett.Indexers
|
|||||||
|
|
||||||
for (int i = 0; i + 1 < releaseTags.Count(); i++)
|
for (int i = 0; i + 1 < releaseTags.Count(); i++)
|
||||||
{
|
{
|
||||||
|
if (releaseTags[i] == "Raw" && !AllowRaws)
|
||||||
|
continue;
|
||||||
infoString += "[" + releaseTags[i] + "]";
|
infoString += "[" + releaseTags[i] + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (category == "Movie")
|
||||||
|
{
|
||||||
|
release.Title = string.Format("{0} {1} {2}{3}", title, year, group, infoString);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
release.Title = string.Format("{0}{1} {2} {3}", group, title, releaseInfo, infoString);
|
release.Title = string.Format("{0}{1} {2} {3}", group, title, releaseInfo, infoString);
|
||||||
|
}
|
||||||
release.Description = title;
|
release.Description = title;
|
||||||
|
|
||||||
var size = rowCq.Find(".torrent_size");
|
var size = rowCq.Find(".torrent_size");
|
||||||
@@ -306,6 +354,7 @@ namespace Jackett.Indexers
|
|||||||
release.Seeders = ParseUtil.CoerceInt(rowCq.Find(".torrent_seeders").Text());
|
release.Seeders = ParseUtil.CoerceInt(rowCq.Find(".torrent_seeders").Text());
|
||||||
release.Peers = release.Seeders + ParseUtil.CoerceInt(rowCq.Find(".torrent_leechers").Text());
|
release.Peers = release.Seeders + ParseUtil.CoerceInt(rowCq.Find(".torrent_leechers").Text());
|
||||||
|
|
||||||
|
if (release.Category != 0)
|
||||||
releases.Add(release);
|
releases.Add(release);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -147,7 +147,7 @@ namespace Jackett.Indexers
|
|||||||
release.Size = ReleaseInfo.GetBytes(size);
|
release.Size = ReleaseInfo.GetBytes(size);
|
||||||
|
|
||||||
//22 Jul 15
|
//22 Jul 15
|
||||||
var dateStr = qRow.Find(".added . datetime").First().Text().Replace("'", string.Empty);
|
var dateStr = qRow.Find(".added").First().Text().Replace("'", string.Empty);
|
||||||
if (dateStr.Split(' ')[0].Length == 1)
|
if (dateStr.Split(' ')[0].Length == 1)
|
||||||
dateStr = "0" + dateStr;
|
dateStr = "0" + dateStr;
|
||||||
|
|
||||||
|
@@ -30,6 +30,7 @@ namespace Jackett.Indexers
|
|||||||
protected static readonly TimeSpan cacheTime = new TimeSpan(0, 9, 0);
|
protected static readonly TimeSpan cacheTime = new TimeSpan(0, 9, 0);
|
||||||
protected IWebClient webclient;
|
protected IWebClient webclient;
|
||||||
protected IProtectionService protectionService;
|
protected IProtectionService protectionService;
|
||||||
|
protected readonly string downloadUrlBase = "";
|
||||||
|
|
||||||
protected string CookieHeader
|
protected string CookieHeader
|
||||||
{
|
{
|
||||||
@@ -37,11 +38,13 @@ namespace Jackett.Indexers
|
|||||||
set { configData.CookieHeader.Value = value; }
|
set { configData.CookieHeader.Value = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected ConfigurationData configData;
|
protected ConfigurationData configData;
|
||||||
|
|
||||||
private List<CategoryMapping> categoryMapping = new List<CategoryMapping>();
|
private List<CategoryMapping> categoryMapping = new List<CategoryMapping>();
|
||||||
|
|
||||||
public BaseIndexer(string name, string link, string description, IIndexerManagerService manager, IWebClient client, Logger logger, ConfigurationData configData, IProtectionService p, TorznabCapabilities caps = null)
|
public BaseIndexer(string name, string link, string description, IIndexerManagerService manager, IWebClient client, Logger logger, ConfigurationData configData, IProtectionService p, TorznabCapabilities caps = null, string downloadBase = null)
|
||||||
{
|
{
|
||||||
if (!link.EndsWith("/"))
|
if (!link.EndsWith("/"))
|
||||||
throw new Exception("Site link must end with a slash.");
|
throw new Exception("Site link must end with a slash.");
|
||||||
@@ -53,6 +56,7 @@ namespace Jackett.Indexers
|
|||||||
indexerService = manager;
|
indexerService = manager;
|
||||||
webclient = client;
|
webclient = client;
|
||||||
protectionService = p;
|
protectionService = p;
|
||||||
|
this.downloadUrlBase = downloadBase;
|
||||||
|
|
||||||
this.configData = configData;
|
this.configData = configData;
|
||||||
|
|
||||||
@@ -62,6 +66,26 @@ namespace Jackett.Indexers
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerable<ReleaseInfo> CleanLinks(IEnumerable<ReleaseInfo> releases)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(downloadUrlBase))
|
||||||
|
return releases;
|
||||||
|
foreach(var release in releases)
|
||||||
|
{
|
||||||
|
if (release.Link.ToString().StartsWith(downloadUrlBase))
|
||||||
|
{
|
||||||
|
release.Link = new Uri(release.Link.ToString().Substring(downloadUrlBase.Length), UriKind.Relative);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return releases;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uri UncleanLink(Uri link)
|
||||||
|
{
|
||||||
|
return new Uri(downloadUrlBase + link.ToString(), UriKind.RelativeOrAbsolute);
|
||||||
|
}
|
||||||
|
|
||||||
protected int MapTrackerCatToNewznab(string input)
|
protected int MapTrackerCatToNewznab(string input)
|
||||||
{
|
{
|
||||||
if (null != input)
|
if (null != input)
|
||||||
|
@@ -110,7 +110,7 @@ namespace Jackett.Indexers
|
|||||||
|
|
||||||
//22:05:3716/02/2013
|
//22:05:3716/02/2013
|
||||||
var dateStr = qRow.Find(".torrenttable:eq(5)").Text().Trim();
|
var dateStr = qRow.Find(".torrenttable:eq(5)").Text().Trim();
|
||||||
release.PublishDate = DateTime.ParseExact(dateStr, "H:mm:ssdd/MM/yyyy", CultureInfo.InvariantCulture);
|
release.PublishDate = DateTime.ParseExact(dateStr, "H:mm:ssdd/MM/yyyy", CultureInfo.InvariantCulture).AddHours(-2);
|
||||||
|
|
||||||
var qLink = qRow.Find(".torrenttable:eq(2) a").First();
|
var qLink = qRow.Find(".torrenttable:eq(2) a").First();
|
||||||
release.Link = new Uri(SiteLink + qLink.Attr("href"));
|
release.Link = new Uri(SiteLink + qLink.Attr("href"));
|
||||||
|
@@ -37,5 +37,8 @@ namespace Jackett.Indexers
|
|||||||
IEnumerable<ReleaseInfo> FilterResults(TorznabQuery query, IEnumerable<ReleaseInfo> input);
|
IEnumerable<ReleaseInfo> FilterResults(TorznabQuery query, IEnumerable<ReleaseInfo> input);
|
||||||
|
|
||||||
Task<byte[]> Download(Uri link);
|
Task<byte[]> Download(Uri link);
|
||||||
|
|
||||||
|
IEnumerable<ReleaseInfo> CleanLinks(IEnumerable<ReleaseInfo> releases);
|
||||||
|
Uri UncleanLink(Uri link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -21,7 +21,7 @@ namespace Jackett.Indexers
|
|||||||
public class TorrentLeech : BaseIndexer, IIndexer
|
public class TorrentLeech : BaseIndexer, IIndexer
|
||||||
{
|
{
|
||||||
private string LoginUrl { get { return SiteLink + "user/account/login/"; } }
|
private string LoginUrl { get { return SiteLink + "user/account/login/"; } }
|
||||||
private string SearchUrl { get { return SiteLink + "torrents/browse/index/query/{0}/categories/2%2C26%2C27%2C32/orderby/added?"; } }
|
private string SearchUrl { get { return SiteLink + "torrents/browse/index/"; } }
|
||||||
|
|
||||||
new ConfigurationDataBasicLogin configData
|
new ConfigurationDataBasicLogin configData
|
||||||
{
|
{
|
||||||
@@ -38,8 +38,45 @@ namespace Jackett.Indexers
|
|||||||
client: wc,
|
client: wc,
|
||||||
logger: l,
|
logger: l,
|
||||||
p: ps,
|
p: ps,
|
||||||
|
downloadBase: "http://www.torrentleech.org/download/",
|
||||||
configData: new ConfigurationDataBasicLogin())
|
configData: new ConfigurationDataBasicLogin())
|
||||||
{
|
{
|
||||||
|
|
||||||
|
AddCategoryMapping(8, TorznabCatType.MoviesSD); // cam
|
||||||
|
AddCategoryMapping(9, TorznabCatType.MoviesSD); //ts
|
||||||
|
AddCategoryMapping(10, TorznabCatType.MoviesSD); // Sceener
|
||||||
|
AddCategoryMapping(11, TorznabCatType.MoviesSD);
|
||||||
|
AddCategoryMapping(12, TorznabCatType.MoviesSD);
|
||||||
|
AddCategoryMapping(13, TorznabCatType.MoviesHD);
|
||||||
|
AddCategoryMapping(14, TorznabCatType.MoviesHD);
|
||||||
|
AddCategoryMapping(15, TorznabCatType.Movies); // Boxsets
|
||||||
|
AddCategoryMapping(29, TorznabCatType.TVDocumentary);
|
||||||
|
|
||||||
|
AddCategoryMapping(26, TorznabCatType.TVSD);
|
||||||
|
AddCategoryMapping(27, TorznabCatType.TV); // Boxsets
|
||||||
|
AddCategoryMapping(32, TorznabCatType.TVHD);
|
||||||
|
|
||||||
|
AddCategoryMapping(17, TorznabCatType.PCGames);
|
||||||
|
AddCategoryMapping(18, TorznabCatType.ConsoleXbox);
|
||||||
|
AddCategoryMapping(19, TorznabCatType.ConsoleXbox360);
|
||||||
|
// 20 PS2
|
||||||
|
AddCategoryMapping(21, TorznabCatType.ConsolePS3);
|
||||||
|
AddCategoryMapping(22, TorznabCatType.ConsolePSP);
|
||||||
|
AddCategoryMapping(28, TorznabCatType.ConsoleWii);
|
||||||
|
AddCategoryMapping(30, TorznabCatType.ConsoleNDS);
|
||||||
|
|
||||||
|
AddCategoryMapping(16, TorznabCatType.AudioVideo);
|
||||||
|
AddCategoryMapping(31, TorznabCatType.Audio);
|
||||||
|
|
||||||
|
AddCategoryMapping(34, TorznabCatType.TVAnime);
|
||||||
|
AddCategoryMapping(35, TorznabCatType.TV); // Cartoons
|
||||||
|
|
||||||
|
AddCategoryMapping(5, TorznabCatType.Books);
|
||||||
|
|
||||||
|
AddCategoryMapping(23, TorznabCatType.PCISO);
|
||||||
|
AddCategoryMapping(24, TorznabCatType.PCMac);
|
||||||
|
AddCategoryMapping(25, TorznabCatType.PCPhoneOther);
|
||||||
|
AddCategoryMapping(33, TorznabCatType.PC0day);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ApplyConfiguration(JToken configJson)
|
public async Task ApplyConfiguration(JToken configJson)
|
||||||
@@ -66,8 +103,27 @@ namespace Jackett.Indexers
|
|||||||
{
|
{
|
||||||
var releases = new List<ReleaseInfo>();
|
var releases = new List<ReleaseInfo>();
|
||||||
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString();
|
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString();
|
||||||
var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString));
|
var searchUrl = SearchUrl;
|
||||||
var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(searchString))
|
||||||
|
{
|
||||||
|
searchUrl += "query/" + HttpUtility.UrlEncode(searchString) + "/";
|
||||||
|
}
|
||||||
|
string.Format(SearchUrl, HttpUtility.UrlEncode(searchString));
|
||||||
|
|
||||||
|
var cats = MapTorznabCapsToTrackers(query);
|
||||||
|
if (cats.Count > 0)
|
||||||
|
{
|
||||||
|
searchUrl += "categories/";
|
||||||
|
foreach (var cat in cats)
|
||||||
|
{
|
||||||
|
if (!searchUrl.EndsWith("/"))
|
||||||
|
searchUrl += ",";
|
||||||
|
searchUrl += cat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var results = await RequestStringWithCookiesAndRetry(searchUrl);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
CQ dom = results.Content;
|
CQ dom = results.Content;
|
||||||
@@ -86,12 +142,12 @@ namespace Jackett.Indexers
|
|||||||
release.MinimumSeedTime = 172800;
|
release.MinimumSeedTime = 172800;
|
||||||
|
|
||||||
CQ qLink = qRow.Find(".title > a").First();
|
CQ qLink = qRow.Find(".title > a").First();
|
||||||
release.Guid = new Uri(SiteLink + qLink.Attr("href"));
|
release.Guid = new Uri(SiteLink + qLink.Attr("href").Substring(1));
|
||||||
release.Comments = release.Guid;
|
release.Comments = release.Guid;
|
||||||
release.Title = qLink.Text();
|
release.Title = qLink.Text();
|
||||||
release.Description = release.Title;
|
release.Description = release.Title;
|
||||||
|
|
||||||
release.Link = new Uri(SiteLink + qRow.Find(".quickdownload > a").Attr("href"));
|
release.Link = new Uri(SiteLink + qRow.Find(".quickdownload > a").Attr("href").Substring(1));
|
||||||
|
|
||||||
var dateString = qRow.Find(".name")[0].InnerText.Trim().Replace(" ", string.Empty).Replace("Addedinon", string.Empty);
|
var dateString = qRow.Find(".name")[0].InnerText.Trim().Replace(" ", string.Empty).Replace("Addedinon", string.Empty);
|
||||||
//"2015-04-25 23:38:12"
|
//"2015-04-25 23:38:12"
|
||||||
@@ -104,6 +160,9 @@ namespace Jackett.Indexers
|
|||||||
release.Seeders = ParseUtil.CoerceInt(qRow.Find(".seeders").Text());
|
release.Seeders = ParseUtil.CoerceInt(qRow.Find(".seeders").Text());
|
||||||
release.Peers = release.Seeders + ParseUtil.CoerceInt(qRow.Find(".leechers").Text());
|
release.Peers = release.Seeders + ParseUtil.CoerceInt(qRow.Find(".leechers").Text());
|
||||||
|
|
||||||
|
var category = qRow.Find(".category a").Attr("href").Replace("/torrents/browse/index/categories/",string.Empty);
|
||||||
|
release.Category = MapTrackerCatToNewznab(category);
|
||||||
|
|
||||||
releases.Add(release);
|
releases.Add(release);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -91,15 +91,5 @@ namespace Jackett.Models
|
|||||||
{
|
{
|
||||||
return (long)(kb * 1024f);
|
return (long)(kb * 1024f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uri ConvertToProxyLink(string serverUrl, string indexerId, string action = "download")
|
|
||||||
{
|
|
||||||
if (Link == null || (Link.IsAbsoluteUri && Link.Scheme == "magnet"))
|
|
||||||
return Link;
|
|
||||||
var originalLink = Link;
|
|
||||||
var encodedLink = HttpServerUtility.UrlTokenEncode(Encoding.UTF8.GetBytes(originalLink.ToString())) + "/t.torrent";
|
|
||||||
var proxyLink = string.Format("{0}api/{1}/{2}/{3}", serverUrl, indexerId, action, encodedLink);
|
|
||||||
return new Uri(proxyLink);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -10,6 +10,7 @@ namespace Jackett.Models
|
|||||||
{
|
{
|
||||||
public DateTime FirstSeen { get; set; }
|
public DateTime FirstSeen { get; set; }
|
||||||
public string Tracker { get; set; }
|
public string Tracker { get; set; }
|
||||||
|
public string TrackerId { get; set; }
|
||||||
public string CategoryDesc { get; set; }
|
public string CategoryDesc { get; set; }
|
||||||
public Uri BlackholeLink { get; set; }
|
public Uri BlackholeLink { get; set; }
|
||||||
}
|
}
|
||||||
|
@@ -12,7 +12,7 @@ namespace Jackett.Services
|
|||||||
public interface ICacheService
|
public interface ICacheService
|
||||||
{
|
{
|
||||||
void CacheRssResults(IIndexer indexer, IEnumerable<ReleaseInfo> releases);
|
void CacheRssResults(IIndexer indexer, IEnumerable<ReleaseInfo> releases);
|
||||||
List<TrackerCacheResult> GetCachedResults(string serverUrl);
|
List<TrackerCacheResult> GetCachedResults();
|
||||||
int GetNewItemCount(IIndexer indexer, IEnumerable<ReleaseInfo> releases);
|
int GetNewItemCount(IIndexer indexer, IEnumerable<ReleaseInfo> releases);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,12 +37,6 @@ namespace Jackett.Services
|
|||||||
|
|
||||||
foreach(var release in releases.OrderByDescending(i=>i.PublishDate))
|
foreach(var release in releases.OrderByDescending(i=>i.PublishDate))
|
||||||
{
|
{
|
||||||
// Skip old releases
|
|
||||||
if(release.PublishDate-DateTime.Now> AGE_LIMIT)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var existingItem = trackerCache.Results.Where(i => i.Result.Guid == release.Guid).FirstOrDefault();
|
var existingItem = trackerCache.Results.Where(i => i.Result.Guid == release.Guid).FirstOrDefault();
|
||||||
if (existingItem == null)
|
if (existingItem == null)
|
||||||
{
|
{
|
||||||
@@ -86,7 +80,7 @@ namespace Jackett.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<TrackerCacheResult> GetCachedResults(string serverUrl)
|
public List<TrackerCacheResult> GetCachedResults()
|
||||||
{
|
{
|
||||||
lock (cache)
|
lock (cache)
|
||||||
{
|
{
|
||||||
@@ -94,16 +88,13 @@ namespace Jackett.Services
|
|||||||
|
|
||||||
foreach(var tracker in cache)
|
foreach(var tracker in cache)
|
||||||
{
|
{
|
||||||
foreach(var release in tracker.Results)
|
foreach(var release in tracker.Results.OrderByDescending(i => i.Result.PublishDate).Take(300))
|
||||||
{
|
{
|
||||||
var item = Mapper.Map<TrackerCacheResult>(release.Result);
|
var item = Mapper.Map<TrackerCacheResult>(release.Result);
|
||||||
item.FirstSeen = release.Created;
|
item.FirstSeen = release.Created;
|
||||||
item.Tracker = tracker.TrackerName;
|
item.Tracker = tracker.TrackerName;
|
||||||
|
item.TrackerId = tracker.TrackerId;
|
||||||
item.Peers = item.Peers - item.Seeders; // Use peers as leechers
|
item.Peers = item.Peers - item.Seeders; // Use peers as leechers
|
||||||
item.Link = item.ConvertToProxyLink(serverUrl, tracker.TrackerId);
|
|
||||||
if(item.Link!=null && item.Link.Scheme != "magnet" && !string.IsNullOrWhiteSpace(Engine.Server.Config.BlackholeDir))
|
|
||||||
item.BlackholeLink = item.ConvertToProxyLink(serverUrl, tracker.TrackerId, "blackhole");
|
|
||||||
|
|
||||||
results.Add(item);
|
results.Add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -87,6 +87,7 @@ namespace Jackett.Services
|
|||||||
var indexer = GetIndexer(name);
|
var indexer = GetIndexer(name);
|
||||||
var browseQuery = new TorznabQuery();
|
var browseQuery = new TorznabQuery();
|
||||||
var results = await indexer.PerformQuery(browseQuery);
|
var results = await indexer.PerformQuery(browseQuery);
|
||||||
|
results = indexer.CleanLinks(results);
|
||||||
logger.Info(string.Format("Found {0} releases from {1}", results.Count(), indexer.DisplayName));
|
logger.Info(string.Format("Found {0} releases from {1}", results.Count(), indexer.DisplayName));
|
||||||
if (results.Count() == 0)
|
if (results.Count() == 0)
|
||||||
throw new Exception("Found no results while trying to browse this tracker");
|
throw new Exception("Found no results while trying to browse this tracker");
|
||||||
|
@@ -20,6 +20,7 @@ using System.Net.NetworkInformation;
|
|||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Web;
|
||||||
|
|
||||||
namespace Jackett.Services
|
namespace Jackett.Services
|
||||||
{
|
{
|
||||||
@@ -31,6 +32,7 @@ namespace Jackett.Services
|
|||||||
void ReserveUrls(bool doInstall = true);
|
void ReserveUrls(bool doInstall = true);
|
||||||
ServerConfig Config { get; }
|
ServerConfig Config { get; }
|
||||||
void SaveConfig();
|
void SaveConfig();
|
||||||
|
Uri ConvertToProxyLink(Uri link, string serverUrl, string indexerId, string action = "dl", string file = "/t.torrent");
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ServerService : IServerService
|
public class ServerService : IServerService
|
||||||
@@ -63,6 +65,16 @@ namespace Jackett.Services
|
|||||||
get { return config; }
|
get { return config; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Uri ConvertToProxyLink(Uri link, string serverUrl, string indexerId, string action = "dl", string file = "/t.torrent")
|
||||||
|
{
|
||||||
|
if (link == null || (link.IsAbsoluteUri && link.Scheme == "magnet"))
|
||||||
|
return link;
|
||||||
|
|
||||||
|
var encodedLink = HttpServerUtility.UrlTokenEncode(Encoding.UTF8.GetBytes(link.ToString())) + file;
|
||||||
|
var proxyLink = string.Format("{0}{1}/{2}/{3}/{4}", serverUrl, action, indexerId, config.APIKey, encodedLink);
|
||||||
|
return new Uri(proxyLink);
|
||||||
|
}
|
||||||
|
|
||||||
private void LoadConfig()
|
private void LoadConfig()
|
||||||
{
|
{
|
||||||
// Load config
|
// Load config
|
||||||
|
@@ -111,16 +111,19 @@ namespace Jackett
|
|||||||
|
|
||||||
config.Routes.MapHttpRoute(
|
config.Routes.MapHttpRoute(
|
||||||
name: "download",
|
name: "download",
|
||||||
routeTemplate: "api/{indexerID}/download/{path}/t.torrent",
|
routeTemplate: "dl/{indexerID}/{apikey}/{path}/t.torrent",
|
||||||
defaults: new { controller = "Download", action = "Download" }
|
defaults: new { controller = "Download", action = "Download" }
|
||||||
);
|
);
|
||||||
|
|
||||||
config.Routes.MapHttpRoute(
|
config.Routes.MapHttpRoute(
|
||||||
name: "blackhole",
|
name: "blackhole",
|
||||||
routeTemplate: "api/{indexerID}/blackhole/{path}/t.torrent",
|
routeTemplate: "bh/{indexerID}/{apikey}/{path}",
|
||||||
defaults: new { controller = "Blackhole", action = "Blackhole" }
|
defaults: new { controller = "Blackhole", action = "Blackhole" }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
appBuilder.UseWebApi(config);
|
||||||
|
|
||||||
|
|
||||||
appBuilder.UseFileServer(new FileServerOptions
|
appBuilder.UseFileServer(new FileServerOptions
|
||||||
{
|
{
|
||||||
RequestPath = new PathString(string.Empty),
|
RequestPath = new PathString(string.Empty),
|
||||||
@@ -129,7 +132,6 @@ namespace Jackett
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
appBuilder.UseWebApi(config);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user