using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Jackett.Common.Models;
using Jackett.Common.Models.IndexerConfig;
using Jackett.Common.Services.Interfaces;
using Jackett.Common.Utils;
using Newtonsoft.Json.Linq;
using NLog;
namespace Jackett.Common.Indexers
{
public class PassThePopcorn : BaseWebIndexer
{
private string LoginUrl { get { return "https://passthepopcorn.me/ajax.php?action=login"; } }
private string indexUrl { get { return "https://passthepopcorn.me/ajax.php?action=login"; } }
private string SearchUrl { get { return "https://passthepopcorn.me/torrents.php"; } }
private string DetailURL { get { return "https://passthepopcorn.me/torrents.php?torrentid="; } }
private string AuthKey { get; set; }
private new ConfigurationDataAPILoginWithUserAndPasskeyAndFilter configData
{
get { return (ConfigurationDataAPILoginWithUserAndPasskeyAndFilter)base.configData; }
set { base.configData = value; }
}
public PassThePopcorn(IIndexerConfigurationService configService, Utils.Clients.WebClient c, Logger l, IProtectionService ps)
: base(name: "PassThePopcorn",
description: "PassThePopcorn is a Private site for MOVIES / TV",
link: "https://passthepopcorn.me/",
caps: new TorznabCapabilities(),
configService: configService,
client: c,
logger: l,
p: ps,
configData: new ConfigurationDataAPILoginWithUserAndPasskeyAndFilter(@"Enter filter options below to restrict search results.
Separate options with a space if using more than one option.
Filter options available:
GoldenPopcorn
Scene
Checked
Free
"))
{
Encoding = Encoding.UTF8;
Language = "en-us";
Type = "private";
TorznabCaps.SupportsImdbMovieSearch = true;
webclient.requestDelay = 2; // 0.5 requests per second
AddCategoryMapping(1, TorznabCatType.Movies, "Feature Film");
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);
AddCategoryMapping(2, TorznabCatType.Movies, "Short Film");
AddCategoryMapping(3, TorznabCatType.TV, "Miniseries");
AddCategoryMapping(4, TorznabCatType.TV, "Stand-up Comedy");
AddCategoryMapping(5, TorznabCatType.TV, "Live Performance");
}
public override async Task ApplyConfiguration(JToken configJson)
{
LoadValuesFromJson(configJson);
IsConfigured = false;
try
{
var results = await PerformQuery(new TorznabQuery());
if (results.Count() == 0)
throw new Exception("Testing returned no results!");
IsConfigured = true;
SaveConfig();
}
catch (Exception e)
{
throw new ExceptionWithConfigData(e.Message, configData);
}
return IndexerConfigurationStatus.Completed;
}
protected override async Task> PerformQuery(TorznabQuery query)
{
var releases = new List();
bool configGoldenPopcornOnly = configData.FilterString.Value.ToLowerInvariant().Contains("goldenpopcorn");
bool configSceneOnly = configData.FilterString.Value.ToLowerInvariant().Contains("scene");
bool configCheckedOnly = configData.FilterString.Value.ToLowerInvariant().Contains("checked");
bool configFreeOnly = configData.FilterString.Value.ToLowerInvariant().Contains("free");
string movieListSearchUrl = SearchUrl;
var queryCollection = new NameValueCollection();
queryCollection.Add("json", "noredirect");
if (!string.IsNullOrEmpty(query.ImdbID))
{
queryCollection.Add("searchstr", query.ImdbID);
}
else if (!string.IsNullOrEmpty(query.GetQueryString()))
{
queryCollection.Add("searchstr", query.GetQueryString());
}
if(configFreeOnly)
queryCollection.Add("freetorrent", "1");
if (queryCollection.Count > 0)
{
movieListSearchUrl += "?" + queryCollection.GetQueryString();
}
var authHeaders = new Dictionary()
{
{ "ApiUser", configData.User.Value },
{ "ApiKey", configData.Key.Value }
};
var results = await RequestStringWithCookiesAndRetry(movieListSearchUrl, null, null, authHeaders);
if (results.IsRedirect) // untested
{
results = await RequestStringWithCookiesAndRetry(movieListSearchUrl, null, null, authHeaders);
}
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"];
string Year = (string)movie["Year"];
var movie_imdbid_str = (string)movie["ImdbId"];
var coverStr = (string)movie["Cover"];
Uri coverUri = null;
if (!string.IsNullOrEmpty(coverStr))
coverUri = new Uri(coverStr);
long? movie_imdbid = null;
if (!string.IsNullOrEmpty(movie_imdbid_str))
movie_imdbid = long.Parse(movie_imdbid_str);
string movie_groupid = (string)movie["GroupId"];
foreach (var torrent in movie["Torrents"])
{
var release = new ReleaseInfo();
string release_name = (string)torrent["ReleaseName"];
release.Title = release_name;
release.Description = string.Format("Title: {0}", movie_title);
release.BannerUrl = coverUri;
release.Imdb = movie_imdbid;
release.Comments = new Uri(string.Format("{0}?id={1}", SearchUrl, WebUtility.UrlEncode(movie_groupid)));
release.Size = long.Parse((string)torrent["Size"]);
release.Grabs = long.Parse((string)torrent["Snatched"]);
release.Seeders = int.Parse((string)torrent["Seeders"]);
release.Peers = release.Seeders + 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, WebUtility.UrlEncode((string)torrent["Id"]), WebUtility.UrlEncode(AuthKey), WebUtility.UrlEncode(configData.Passkey.Value)));
release.Guid = release.Link;
release.MinimumRatio = 1;
release.MinimumSeedTime = 345600;
release.DownloadVolumeFactor = 1;
release.UploadVolumeFactor = 1;
release.Category = new List { 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
}
var titletags = new List();
string Quality = (string)torrent["Quality"];
string Container = (string)torrent["Container"];
string Codec = (string)torrent["Codec"];
string Resolution = (string)torrent["Resolution"];
string Source = (string)torrent["Source"];
if (Year != null)
{
release.Description += string.Format("
\nYear: {0}", Year);
}
if (Quality != null)
{
release.Description += string.Format("
\nQuality: {0}", Quality);
}
if (Resolution != null)
{
titletags.Add(Resolution);
release.Description += string.Format("
\nResolution: {0}", Resolution);
}
if (Source != null)
{
titletags.Add(Source);
release.Description += string.Format("
\nSource: {0}", Source);
}
if (Codec != null)
{
titletags.Add(Codec);
release.Description += string.Format("
\nCodec: {0}", Codec);
}
if (Container != null)
{
titletags.Add(Container);
release.Description += string.Format("
\nContainer: {0}", Container);
}
if (scene)
{
titletags.Add("Scene");
release.Description += "
\nScene";
}
if (check)
{
titletags.Add("Checked");
release.Description += "
\nChecked";
}
if (golden)
{
titletags.Add("Golden Popcorn");
release.Description += "
\nGolden Popcorn";
}
if (titletags.Count() > 0)
release.Title += " [" + string.Join(" / ", titletags) + "]";
bool freeleech;
bool.TryParse((string)torrent["FreeleechType"], out freeleech);
if (freeleech)
release.DownloadVolumeFactor = 0;
releases.Add(release);
}
}
}
catch (Exception ex)
{
OnParseError(results.Content, ex);
}
return releases;
}
}
}