mirror of
https://github.com/Jackett/Jackett.git
synced 2025-09-17 17:34:09 +02:00
Add PTP as a new Indexer (#373)
* Added PassThePopcorn Indexer * Fixed PTP Indexer
This commit is contained in:
@@ -38,6 +38,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
|||||||
* ILoveTorrents
|
* ILoveTorrents
|
||||||
* Immortalseed
|
* Immortalseed
|
||||||
* IPTorrents
|
* IPTorrents
|
||||||
|
* PassThePopcorn
|
||||||
* MoreThanTV
|
* MoreThanTV
|
||||||
* MyAnonamouse
|
* MyAnonamouse
|
||||||
* NCore
|
* NCore
|
||||||
|
BIN
src/Jackett/Content/logos/passthepopcorn.png
Normal file
BIN
src/Jackett/Content/logos/passthepopcorn.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
167
src/Jackett/Indexers/PassThePopcorn.cs
Normal file
167
src/Jackett/Indexers/PassThePopcorn.cs
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
using CsQuery;
|
||||||
|
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 PassThePopcorn : BaseIndexer, IIndexer
|
||||||
|
{
|
||||||
|
private string LoginUrl { get { return "https://tls.passthepopcorn.me/ajax.php?action=login"; } }
|
||||||
|
private string indexUrl { get { return "https://tls.passthepopcorn.me/ajax.php?action=login"; } }
|
||||||
|
private string SearchUrl { get { return "https://tls.passthepopcorn.me/torrents.php"; } }
|
||||||
|
private string DetailURL { get { return "https://tls.passthepopcorn.me/torrents.php?torrentid="; } }
|
||||||
|
private string AuthKey { get; set; }
|
||||||
|
new ConfigurationDataBasicLoginWithFilterAndPasskey configData
|
||||||
|
{
|
||||||
|
get { return (ConfigurationDataBasicLoginWithFilterAndPasskey)base.configData; }
|
||||||
|
set { base.configData = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public PassThePopcorn(IIndexerManagerService i, Logger l, IWebClient c, IProtectionService ps)
|
||||||
|
: base(name: "PassThePopcorn",
|
||||||
|
description: "PassThePopcorn",
|
||||||
|
link: "https://passthepopcorn.me/",
|
||||||
|
caps: new TorznabCapabilities(),
|
||||||
|
manager: i,
|
||||||
|
client: c,
|
||||||
|
logger: l,
|
||||||
|
p: ps,
|
||||||
|
configData: new ConfigurationDataBasicLoginWithFilterAndPasskey(@"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>GoldenPopcorn</code><br><code>Scene</code><br><code>Checked</code>"))
|
||||||
|
{
|
||||||
|
AddCategoryMapping(1, TorznabCatType.Movies);
|
||||||
|
AddCategoryMapping(1, TorznabCatType.MoviesForeign);
|
||||||
|
AddCategoryMapping(1, TorznabCatType.MoviesOther);
|
||||||
|
AddCategoryMapping(1, TorznabCatType.MoviesSD);
|
||||||
|
AddCategoryMapping(1, TorznabCatType.MoviesHD);
|
||||||
|
AddCategoryMapping(1, TorznabCatType.Movies3D);
|
||||||
|
AddCategoryMapping(1, TorznabCatType.MoviesBluRay);
|
||||||
|
AddCategoryMapping(1, TorznabCatType.MoviesDVD);
|
||||||
|
AddCategoryMapping(1, TorznabCatType.MoviesWEBDL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||||
|
{
|
||||||
|
configData.LoadValuesFromJson(configJson);
|
||||||
|
|
||||||
|
await DoLogin();
|
||||||
|
|
||||||
|
return IndexerConfigurationStatus.RequiresTesting;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task DoLogin()
|
||||||
|
{
|
||||||
|
var pairs = new Dictionary<string, string> {
|
||||||
|
{ "username", configData.Username.Value },
|
||||||
|
{ "password", configData.Password.Value },
|
||||||
|
{ "passkey", configData.Passkey.Value },
|
||||||
|
{ "keeplogged", "1" },
|
||||||
|
{ "login", "Log In!" }
|
||||||
|
};
|
||||||
|
|
||||||
|
var response = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, indexUrl, SiteLink);
|
||||||
|
JObject js_response = JObject.Parse(response.Content);
|
||||||
|
await ConfigureIfOK(response.Cookies, response.Content != null && (string)js_response["Result"] != "Error", () =>
|
||||||
|
{
|
||||||
|
// Landing page wil have "Result":"Error" if log in fails
|
||||||
|
string errorMessage = (string)js_response["Message"];
|
||||||
|
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||||
|
{
|
||||||
|
await DoLogin();
|
||||||
|
|
||||||
|
var releases = new List<ReleaseInfo>();
|
||||||
|
bool configGoldenPopcornOnly = configData.FilterString.Value.ToLowerInvariant().Contains("goldenpopcorn");
|
||||||
|
bool configSceneOnly = configData.FilterString.Value.ToLowerInvariant().Contains("scene");
|
||||||
|
bool configCheckedOnly = configData.FilterString.Value.ToLowerInvariant().Contains("checked");
|
||||||
|
string movieListSearchUrl;
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(query.GetQueryString()))
|
||||||
|
movieListSearchUrl = string.Format("{0}?json=noredirect", SearchUrl);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(query.ImdbID))
|
||||||
|
{
|
||||||
|
movieListSearchUrl = string.Format("{0}?json=noredirect&searchstr={1}", SearchUrl, HttpUtility.UrlEncode(query.ImdbID));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
movieListSearchUrl = string.Format("{0}?json=noredirect&searchstr={1}", SearchUrl, HttpUtility.UrlEncode(query.GetQueryString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var results = await RequestStringWithCookiesAndRetry(movieListSearchUrl);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//Iterate over the releases for each movie
|
||||||
|
JObject js_results = JObject.Parse(results.Content);
|
||||||
|
foreach (var movie in js_results["Movies"])
|
||||||
|
{
|
||||||
|
string movie_title = (string) movie["Title"];
|
||||||
|
long movie_imdbid = long.Parse((string)movie["ImdbId"]);
|
||||||
|
string movie_groupid = (string)movie["GroupId"];
|
||||||
|
foreach (var torrent in movie["Torrents"])
|
||||||
|
{
|
||||||
|
var release = new ReleaseInfo();
|
||||||
|
release.Title = movie_title;
|
||||||
|
release.Description = release.Title;
|
||||||
|
release.Imdb = movie_imdbid;
|
||||||
|
release.Comments = new Uri(string.Format("{0}?id={1}", SearchUrl, HttpUtility.UrlEncode(movie_groupid)));
|
||||||
|
release.Guid = release.Comments;
|
||||||
|
release.Size = long.Parse((string)torrent["Size"]);
|
||||||
|
release.Seeders = int.Parse((string)torrent["Seeders"]);
|
||||||
|
release.Peers = int.Parse((string)torrent["Leechers"]);
|
||||||
|
release.PublishDate = DateTime.ParseExact((string)torrent["UploadTime"], "yyyy-MM-dd HH:mm:ss",
|
||||||
|
CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToLocalTime();
|
||||||
|
release.Link = new Uri(string.Format("{0}?action=download&id={1}&authkey={2}&torrent_pass={3}",
|
||||||
|
SearchUrl, HttpUtility.UrlEncode((string)torrent["Id"]), HttpUtility.UrlEncode(AuthKey), HttpUtility.UrlEncode(configData.Passkey.Value)));
|
||||||
|
release.MinimumRatio = 1;
|
||||||
|
release.MinimumSeedTime = 345600;
|
||||||
|
release.Category = 2000;
|
||||||
|
|
||||||
|
bool golden, scene, check;
|
||||||
|
bool.TryParse((string)torrent["GoldenPopcorn"], out golden);
|
||||||
|
bool.TryParse((string)torrent["Scene"], out scene);
|
||||||
|
bool.TryParse((string)torrent["Checked"], out check);
|
||||||
|
|
||||||
|
|
||||||
|
if (configGoldenPopcornOnly && !golden)
|
||||||
|
{
|
||||||
|
continue; //Skip release if user only wants GoldenPopcorn
|
||||||
|
}
|
||||||
|
if (configSceneOnly && !scene)
|
||||||
|
{
|
||||||
|
continue; //Skip release if user only wants Scene
|
||||||
|
}
|
||||||
|
if (configCheckedOnly && !check)
|
||||||
|
{
|
||||||
|
continue; //Skip release if user only wants Checked
|
||||||
|
}
|
||||||
|
releases.Add(release);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
OnParseError(results.Content, ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return releases;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -187,6 +187,7 @@
|
|||||||
<Compile Include="Controllers\DownloadController.cs" />
|
<Compile Include="Controllers\DownloadController.cs" />
|
||||||
<Compile Include="Engine.cs" />
|
<Compile Include="Engine.cs" />
|
||||||
<Compile Include="Indexers\MyAnonamouse.cs" />
|
<Compile Include="Indexers\MyAnonamouse.cs" />
|
||||||
|
<Compile Include="Indexers\PassThePopcorn.cs" />
|
||||||
<Compile Include="Indexers\Xthor.cs" />
|
<Compile Include="Indexers\Xthor.cs" />
|
||||||
<Compile Include="Indexers\PhxBit.cs" />
|
<Compile Include="Indexers\PhxBit.cs" />
|
||||||
<Compile Include="Indexers\AlphaRatio.cs" />
|
<Compile Include="Indexers\AlphaRatio.cs" />
|
||||||
@@ -229,6 +230,7 @@
|
|||||||
<Compile Include="Models\IndexerConfig\Bespoke\ConfigurationDataAbnormal.cs" />
|
<Compile Include="Models\IndexerConfig\Bespoke\ConfigurationDataAbnormal.cs" />
|
||||||
<Compile Include="Models\IndexerConfig\Bespoke\ConfigurationDataFrenchAdn.cs" />
|
<Compile Include="Models\IndexerConfig\Bespoke\ConfigurationDataFrenchAdn.cs" />
|
||||||
<Compile Include="Models\IndexerConfig\Bespoke\ConfigurationDataWiHD.cs" />
|
<Compile Include="Models\IndexerConfig\Bespoke\ConfigurationDataWiHD.cs" />
|
||||||
|
<Compile Include="Models\IndexerConfig\ConfigurationDataBasicLoginWithFilterAndPasskey.cs" />
|
||||||
<Compile Include="Models\IndexerConfig\ConfigurationDataBasicLoginWithFilter.cs" />
|
<Compile Include="Models\IndexerConfig\ConfigurationDataBasicLoginWithFilter.cs" />
|
||||||
<Compile Include="Models\IndexerConfig\ConfigurationDataAPIKey.cs" />
|
<Compile Include="Models\IndexerConfig\ConfigurationDataAPIKey.cs" />
|
||||||
<Compile Include="Models\IndexerConfig\ConfigurationDataBasicLoginWithRSSAndDisplay.cs" />
|
<Compile Include="Models\IndexerConfig\ConfigurationDataBasicLoginWithRSSAndDisplay.cs" />
|
||||||
|
@@ -0,0 +1,32 @@
|
|||||||
|
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 ConfigurationDataBasicLoginWithFilterAndPasskey : ConfigurationData
|
||||||
|
{
|
||||||
|
public StringItem Username { get; private set; }
|
||||||
|
public StringItem Password { get; private set; }
|
||||||
|
public StringItem Passkey { get; private set; }
|
||||||
|
public DisplayItem FilterExample { get; private set; }
|
||||||
|
public StringItem FilterString { get; private set; }
|
||||||
|
|
||||||
|
public ConfigurationDataBasicLoginWithFilterAndPasskey(string FilterInstructions)
|
||||||
|
{
|
||||||
|
Username = new StringItem { Name = "Username" };
|
||||||
|
Password = new StringItem { Name = "Password" };
|
||||||
|
Passkey = new StringItem { Name = "Passkey" };
|
||||||
|
FilterExample = new DisplayItem(FilterInstructions)
|
||||||
|
{
|
||||||
|
Name = ""
|
||||||
|
};
|
||||||
|
FilterString = new StringItem { Name = "Filters (optional)" };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user