mirror of
https://github.com/Jackett/Jackett.git
synced 2025-09-17 17:34:09 +02:00
Complete Shazbat, fix category picker on web ui and start btn
This commit is contained in:
@@ -40,7 +40,7 @@ We were previously focused on TV but are working on extending searches to allow
|
||||
* [NextGen](https://nxtgn.org/)
|
||||
* [pretome](https://pretome.info)
|
||||
* [PrivateHD](https://privatehd.to/)
|
||||
* [RARGB](https://rarbg.to/)
|
||||
* [RARBG](https://rarbg.to/)
|
||||
* [RuTor](http://rutor.org/)
|
||||
* [SceneAccess](https://sceneaccess.eu/login)
|
||||
* [SceneTime](https://www.scenetime.com/)
|
||||
|
@@ -367,7 +367,7 @@ function bindUIButtons() {
|
||||
var count = 0;
|
||||
this.api().columns().every(function () {
|
||||
count++;
|
||||
if (count === 5 || count === 7) {
|
||||
if (count === 5 || count === 9) {
|
||||
var column = this;
|
||||
var select = $('<select><option value=""></option></select>')
|
||||
.appendTo($(column.footer()).empty())
|
||||
@@ -495,7 +495,7 @@ function bindUIButtons() {
|
||||
var count = 0;
|
||||
this.api().columns().every(function () {
|
||||
count++;
|
||||
if (count === 3 || count === 5) {
|
||||
if (count === 3 || count === 7) {
|
||||
var column = this;
|
||||
var select = $('<select><option value=""></option></select>')
|
||||
.appendTo($(column.footer()).empty())
|
||||
|
BIN
src/Jackett/Content/logos/broadcastthenet.png
Normal file
BIN
src/Jackett/Content/logos/broadcastthenet.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
@@ -1,393 +1,394 @@
|
||||
using CsQuery;
|
||||
using Jackett.Models;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
using Jackett.Services;
|
||||
using Jackett.Utils;
|
||||
using Jackett.Utils.Clients;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
public class AnimeBytes : BaseIndexer, IIndexer
|
||||
{
|
||||
private string LoginUrl { get { return SiteLink + "user/login"; } }
|
||||
private string SearchUrl { get { return SiteLink + "torrents.php?"; } }
|
||||
public bool AllowRaws { get { return configData.IncludeRaw.Value; } }
|
||||
|
||||
new ConfigurationDataAnimeBytes configData
|
||||
{
|
||||
get { return (ConfigurationDataAnimeBytes)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public AnimeBytes(IIndexerManagerService i, IWebClient client, Logger l, IProtectionService ps)
|
||||
: base(name: "AnimeBytes",
|
||||
link: "https://animebytes.tv/",
|
||||
description: "Powered by Tentacles",
|
||||
manager: i,
|
||||
client: client,
|
||||
caps: new TorznabCapabilities(TorznabCatType.TVAnime,
|
||||
TorznabCatType.Movies,
|
||||
TorznabCatType.BooksComics,
|
||||
TorznabCatType.ConsolePSP,
|
||||
TorznabCatType.ConsoleOther,
|
||||
TorznabCatType.PCGames),
|
||||
logger: l,
|
||||
p: ps,
|
||||
configData: new ConfigurationDataAnimeBytes())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
|
||||
lock (cache)
|
||||
{
|
||||
cache.Clear();
|
||||
}
|
||||
|
||||
// Get the login form as we need the CSRF Token
|
||||
var loginPage = await webclient.GetString(new Utils.Clients.WebRequest()
|
||||
{
|
||||
Url = LoginUrl
|
||||
});
|
||||
|
||||
CQ loginPageDom = loginPage.Content;
|
||||
var csrfToken = loginPageDom["input[name=\"csrf_token\"]"].Last();
|
||||
|
||||
// Build login form
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "csrf_token", csrfToken.Attr("value") },
|
||||
{ "username", configData.Username.Value },
|
||||
{ "password", configData.Password.Value },
|
||||
{ "keeplogged_sent", "true" },
|
||||
{ "keeplogged", "on" },
|
||||
{ "login", "Log In!" }
|
||||
};
|
||||
|
||||
// Do the login
|
||||
var request = new Utils.Clients.WebRequest()
|
||||
{
|
||||
Cookies = loginPage.Cookies,
|
||||
PostData = pairs,
|
||||
Referer = LoginUrl,
|
||||
Type = RequestType.POST,
|
||||
Url = LoginUrl
|
||||
};
|
||||
var response = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, null);
|
||||
|
||||
// Follow the redirect
|
||||
await FollowIfRedirect(response, request.Url, SearchUrl);
|
||||
|
||||
await ConfigureIfOK(response.Cookies, response.Content != null && response.Content.Contains("/user/logout"), () =>
|
||||
{
|
||||
// Their login page appears to be broken and just gives a 500 error.
|
||||
throw new ExceptionWithConfigData("Failed to login, 6 failed attempts will get you banned for 6 hours.", configData);
|
||||
});
|
||||
|
||||
return IndexerConfigurationStatus.RequiresTesting;
|
||||
}
|
||||
|
||||
// Override to load legacy config format
|
||||
public override void LoadFromSavedConfiguration(JToken jsonConfig)
|
||||
{
|
||||
if (jsonConfig is JObject)
|
||||
{
|
||||
configData.CookieHeader.Value = jsonConfig.Value<string>("cookies");
|
||||
configData.IncludeRaw.Value = jsonConfig.Value<bool>("raws");
|
||||
SaveConfig();
|
||||
IsConfigured = true;
|
||||
return;
|
||||
}
|
||||
|
||||
base.LoadFromSavedConfiguration(jsonConfig);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
// The result list
|
||||
var releases = new List<ReleaseInfo>();
|
||||
|
||||
foreach (var result in await GetResults(query.SanitizedSearchTerm))
|
||||
{
|
||||
releases.Add(result);
|
||||
}
|
||||
|
||||
return releases.ToArray();
|
||||
}
|
||||
|
||||
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:
|
||||
if (!string.IsNullOrWhiteSpace(searchTerm))
|
||||
{
|
||||
var splitindex = searchTerm.LastIndexOf(' ');
|
||||
if (splitindex > -1)
|
||||
searchTerm = searchTerm.Substring(0, splitindex);
|
||||
}
|
||||
|
||||
// The result list
|
||||
var releases = new List<ReleaseInfo>();
|
||||
|
||||
// Check cache first so we don't query the server for each episode when searching for each episode in a series.
|
||||
lock (cache)
|
||||
{
|
||||
// Remove old cache items
|
||||
CleanCache();
|
||||
|
||||
var cachedResult = cache.Where(i => i.Query == searchTerm).FirstOrDefault();
|
||||
if (cachedResult != null)
|
||||
return cachedResult.Results.Select(s => (ReleaseInfo)s.Clone()).ToArray();
|
||||
}
|
||||
|
||||
var queryUrl = SearchUrl;
|
||||
// Only include the query bit if its required as hopefully the site caches the non query page
|
||||
if (!string.IsNullOrWhiteSpace(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
|
||||
var response = await RequestStringWithCookiesAndRetry(queryUrl);
|
||||
CQ dom = response.Content;
|
||||
|
||||
// Parse
|
||||
try
|
||||
{
|
||||
var releaseInfo = "S01";
|
||||
var root = dom.Find(".group_cont");
|
||||
// We may have got redirected to the series page if we have none of these
|
||||
if (root.Count() == 0)
|
||||
root = dom.Find(".torrent_table");
|
||||
|
||||
foreach (var series in root)
|
||||
{
|
||||
var seriesCq = series.Cq();
|
||||
|
||||
var synonyms = new List<string>();
|
||||
var mainTitle = seriesCq.Find(".group_title strong a").First().Text().Trim();
|
||||
|
||||
var yearStr = seriesCq.Find(".group_title strong").First().Text().Trim().Replace("]", "").Trim();
|
||||
int yearIndex = yearStr.LastIndexOf("[");
|
||||
if (yearIndex > -1)
|
||||
yearStr = yearStr.Substring(yearIndex + 1);
|
||||
|
||||
int year = 0;
|
||||
if (!int.TryParse(yearStr, out year))
|
||||
year = DateTime.Now.Year;
|
||||
|
||||
synonyms.Add(mainTitle);
|
||||
|
||||
// If the title contains a comma then we can't use the synonyms as they are comma seperated
|
||||
if (!mainTitle.Contains(","))
|
||||
{
|
||||
var symnomnNames = string.Empty;
|
||||
foreach (var e in seriesCq.Find(".group_statbox li"))
|
||||
{
|
||||
if (e.FirstChild.InnerText == "Synonyms:")
|
||||
{
|
||||
symnomnNames = e.InnerText;
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(symnomnNames))
|
||||
{
|
||||
foreach (var name in symnomnNames.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
var theName = name.Trim();
|
||||
if (!theName.Contains("&#") && !string.IsNullOrWhiteSpace(theName))
|
||||
{
|
||||
synonyms.Add(theName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var title in synonyms)
|
||||
{
|
||||
var releaseRows = seriesCq.Find(".torrent_group tr");
|
||||
|
||||
// Skip the first two info rows
|
||||
for (int r = 1; r < releaseRows.Count(); r++)
|
||||
{
|
||||
var row = releaseRows.Get(r);
|
||||
var rowCq = row.Cq();
|
||||
if (rowCq.HasClass("edition_info"))
|
||||
{
|
||||
releaseInfo = rowCq.Find("td").Text();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(releaseInfo))
|
||||
{
|
||||
// Single episodes alpha - Reported that this info is missing.
|
||||
// It should self correct when availible
|
||||
break;
|
||||
}
|
||||
|
||||
releaseInfo = releaseInfo.Replace("Episode ", "");
|
||||
releaseInfo = releaseInfo.Replace("Season ", "S");
|
||||
releaseInfo = releaseInfo.Trim();
|
||||
}
|
||||
else if (rowCq.HasClass("torrent"))
|
||||
{
|
||||
var links = rowCq.Find("a");
|
||||
// Protect against format changes
|
||||
if (links.Count() != 2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var release = new ReleaseInfo();
|
||||
release.MinimumRatio = 1;
|
||||
release.MinimumSeedTime = 259200;
|
||||
var downloadLink = links.Get(0);
|
||||
|
||||
// We dont know this so try to fake based on the release year
|
||||
release.PublishDate = new DateTime(year, 1, 1);
|
||||
release.PublishDate = release.PublishDate.AddDays(Math.Min(DateTime.Now.DayOfYear, 365) - 1);
|
||||
|
||||
var infoLink = links.Get(1);
|
||||
release.Comments = new Uri(SiteLink + infoLink.Attributes.GetAttribute("href"));
|
||||
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);
|
||||
|
||||
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
|
||||
var releaseTags = infoLink.InnerText.Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||
for (int i = releaseTags.Count - 1; i >= 0; i--)
|
||||
{
|
||||
releaseTags[i] = releaseTags[i].Trim();
|
||||
if (string.IsNullOrWhiteSpace(releaseTags[i]))
|
||||
releaseTags.RemoveAt(i);
|
||||
}
|
||||
|
||||
var group = releaseTags.Last();
|
||||
if (group.Contains("(") && group.Contains(")"))
|
||||
{
|
||||
// Skip raws if set
|
||||
if (group.ToLowerInvariant().StartsWith("raw") && !AllowRaws)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var start = group.IndexOf("(");
|
||||
group = "[" + group.Substring(start + 1, (group.IndexOf(")") - 1) - start) + "] ";
|
||||
}
|
||||
else
|
||||
{
|
||||
group = string.Empty;
|
||||
}
|
||||
|
||||
var infoString = "";
|
||||
|
||||
for (int i = 0; i + 1 < releaseTags.Count(); i++)
|
||||
{
|
||||
if (releaseTags[i] == "Raw" && !AllowRaws)
|
||||
continue;
|
||||
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.Description = title;
|
||||
|
||||
var size = rowCq.Find(".torrent_size");
|
||||
if (size.Count() > 0)
|
||||
{
|
||||
release.Size = ReleaseInfo.GetBytes(size.First().Text());
|
||||
}
|
||||
|
||||
// Additional 5 hours per GB
|
||||
release.MinimumSeedTime += (release.Size / 1000000000) * 18000;
|
||||
|
||||
// Peer info
|
||||
release.Seeders = ParseUtil.CoerceInt(rowCq.Find(".torrent_seeders").Text());
|
||||
release.Peers = release.Seeders + ParseUtil.CoerceInt(rowCq.Find(".torrent_leechers").Text());
|
||||
|
||||
if (release.Category != 0)
|
||||
releases.Add(release);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(response.Content, ex);
|
||||
}
|
||||
|
||||
// Add to the cache
|
||||
lock (cache)
|
||||
{
|
||||
cache.Add(new CachedQueryResult(searchTerm, releases));
|
||||
}
|
||||
|
||||
return releases.Select(s => (ReleaseInfo)s.Clone());
|
||||
}
|
||||
|
||||
|
||||
public async override Task<byte[]> Download(Uri link)
|
||||
{
|
||||
// The urls for this tracker are quite long so append the domain after the incoming request.
|
||||
var response = await webclient.GetBytes(new Utils.Clients.WebRequest()
|
||||
{
|
||||
Url = SiteLink + link.ToString(),
|
||||
Cookies = CookieHeader
|
||||
});
|
||||
|
||||
return response.Content;
|
||||
}
|
||||
}
|
||||
}
|
||||
using CsQuery;
|
||||
using Jackett.Models;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
using Jackett.Models.IndexerConfig.Bespoke;
|
||||
using Jackett.Services;
|
||||
using Jackett.Utils;
|
||||
using Jackett.Utils.Clients;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
public class AnimeBytes : BaseIndexer, IIndexer
|
||||
{
|
||||
private string LoginUrl { get { return SiteLink + "user/login"; } }
|
||||
private string SearchUrl { get { return SiteLink + "torrents.php?"; } }
|
||||
public bool AllowRaws { get { return configData.IncludeRaw.Value; } }
|
||||
|
||||
new ConfigurationDataAnimeBytes configData
|
||||
{
|
||||
get { return (ConfigurationDataAnimeBytes)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public AnimeBytes(IIndexerManagerService i, IWebClient client, Logger l, IProtectionService ps)
|
||||
: base(name: "AnimeBytes",
|
||||
link: "https://animebytes.tv/",
|
||||
description: "Powered by Tentacles",
|
||||
manager: i,
|
||||
client: client,
|
||||
caps: new TorznabCapabilities(TorznabCatType.TVAnime,
|
||||
TorznabCatType.Movies,
|
||||
TorznabCatType.BooksComics,
|
||||
TorznabCatType.ConsolePSP,
|
||||
TorznabCatType.ConsoleOther,
|
||||
TorznabCatType.PCGames),
|
||||
logger: l,
|
||||
p: ps,
|
||||
configData: new ConfigurationDataAnimeBytes())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
|
||||
lock (cache)
|
||||
{
|
||||
cache.Clear();
|
||||
}
|
||||
|
||||
// Get the login form as we need the CSRF Token
|
||||
var loginPage = await webclient.GetString(new Utils.Clients.WebRequest()
|
||||
{
|
||||
Url = LoginUrl
|
||||
});
|
||||
|
||||
CQ loginPageDom = loginPage.Content;
|
||||
var csrfToken = loginPageDom["input[name=\"csrf_token\"]"].Last();
|
||||
|
||||
// Build login form
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "csrf_token", csrfToken.Attr("value") },
|
||||
{ "username", configData.Username.Value },
|
||||
{ "password", configData.Password.Value },
|
||||
{ "keeplogged_sent", "true" },
|
||||
{ "keeplogged", "on" },
|
||||
{ "login", "Log In!" }
|
||||
};
|
||||
|
||||
// Do the login
|
||||
var request = new Utils.Clients.WebRequest()
|
||||
{
|
||||
Cookies = loginPage.Cookies,
|
||||
PostData = pairs,
|
||||
Referer = LoginUrl,
|
||||
Type = RequestType.POST,
|
||||
Url = LoginUrl
|
||||
};
|
||||
var response = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, null);
|
||||
|
||||
// Follow the redirect
|
||||
await FollowIfRedirect(response, request.Url, SearchUrl);
|
||||
|
||||
await ConfigureIfOK(response.Cookies, response.Content != null && response.Content.Contains("/user/logout"), () =>
|
||||
{
|
||||
// Their login page appears to be broken and just gives a 500 error.
|
||||
throw new ExceptionWithConfigData("Failed to login, 6 failed attempts will get you banned for 6 hours.", configData);
|
||||
});
|
||||
|
||||
return IndexerConfigurationStatus.RequiresTesting;
|
||||
}
|
||||
|
||||
// Override to load legacy config format
|
||||
public override void LoadFromSavedConfiguration(JToken jsonConfig)
|
||||
{
|
||||
if (jsonConfig is JObject)
|
||||
{
|
||||
configData.CookieHeader.Value = jsonConfig.Value<string>("cookies");
|
||||
configData.IncludeRaw.Value = jsonConfig.Value<bool>("raws");
|
||||
SaveConfig();
|
||||
IsConfigured = true;
|
||||
return;
|
||||
}
|
||||
|
||||
base.LoadFromSavedConfiguration(jsonConfig);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
// The result list
|
||||
var releases = new List<ReleaseInfo>();
|
||||
|
||||
foreach (var result in await GetResults(query.SanitizedSearchTerm))
|
||||
{
|
||||
releases.Add(result);
|
||||
}
|
||||
|
||||
return releases.ToArray();
|
||||
}
|
||||
|
||||
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:
|
||||
if (!string.IsNullOrWhiteSpace(searchTerm))
|
||||
{
|
||||
var splitindex = searchTerm.LastIndexOf(' ');
|
||||
if (splitindex > -1)
|
||||
searchTerm = searchTerm.Substring(0, splitindex);
|
||||
}
|
||||
|
||||
// The result list
|
||||
var releases = new List<ReleaseInfo>();
|
||||
|
||||
// Check cache first so we don't query the server for each episode when searching for each episode in a series.
|
||||
lock (cache)
|
||||
{
|
||||
// Remove old cache items
|
||||
CleanCache();
|
||||
|
||||
var cachedResult = cache.Where(i => i.Query == searchTerm).FirstOrDefault();
|
||||
if (cachedResult != null)
|
||||
return cachedResult.Results.Select(s => (ReleaseInfo)s.Clone()).ToArray();
|
||||
}
|
||||
|
||||
var queryUrl = SearchUrl;
|
||||
// Only include the query bit if its required as hopefully the site caches the non query page
|
||||
if (!string.IsNullOrWhiteSpace(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
|
||||
var response = await RequestStringWithCookiesAndRetry(queryUrl);
|
||||
CQ dom = response.Content;
|
||||
|
||||
// Parse
|
||||
try
|
||||
{
|
||||
var releaseInfo = "S01";
|
||||
var root = dom.Find(".group_cont");
|
||||
// We may have got redirected to the series page if we have none of these
|
||||
if (root.Count() == 0)
|
||||
root = dom.Find(".torrent_table");
|
||||
|
||||
foreach (var series in root)
|
||||
{
|
||||
var seriesCq = series.Cq();
|
||||
|
||||
var synonyms = new List<string>();
|
||||
var mainTitle = seriesCq.Find(".group_title strong a").First().Text().Trim();
|
||||
|
||||
var yearStr = seriesCq.Find(".group_title strong").First().Text().Trim().Replace("]", "").Trim();
|
||||
int yearIndex = yearStr.LastIndexOf("[");
|
||||
if (yearIndex > -1)
|
||||
yearStr = yearStr.Substring(yearIndex + 1);
|
||||
|
||||
int year = 0;
|
||||
if (!int.TryParse(yearStr, out year))
|
||||
year = DateTime.Now.Year;
|
||||
|
||||
synonyms.Add(mainTitle);
|
||||
|
||||
// If the title contains a comma then we can't use the synonyms as they are comma seperated
|
||||
if (!mainTitle.Contains(","))
|
||||
{
|
||||
var symnomnNames = string.Empty;
|
||||
foreach (var e in seriesCq.Find(".group_statbox li"))
|
||||
{
|
||||
if (e.FirstChild.InnerText == "Synonyms:")
|
||||
{
|
||||
symnomnNames = e.InnerText;
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(symnomnNames))
|
||||
{
|
||||
foreach (var name in symnomnNames.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
var theName = name.Trim();
|
||||
if (!theName.Contains("&#") && !string.IsNullOrWhiteSpace(theName))
|
||||
{
|
||||
synonyms.Add(theName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var title in synonyms)
|
||||
{
|
||||
var releaseRows = seriesCq.Find(".torrent_group tr");
|
||||
|
||||
// Skip the first two info rows
|
||||
for (int r = 1; r < releaseRows.Count(); r++)
|
||||
{
|
||||
var row = releaseRows.Get(r);
|
||||
var rowCq = row.Cq();
|
||||
if (rowCq.HasClass("edition_info"))
|
||||
{
|
||||
releaseInfo = rowCq.Find("td").Text();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(releaseInfo))
|
||||
{
|
||||
// Single episodes alpha - Reported that this info is missing.
|
||||
// It should self correct when availible
|
||||
break;
|
||||
}
|
||||
|
||||
releaseInfo = releaseInfo.Replace("Episode ", "");
|
||||
releaseInfo = releaseInfo.Replace("Season ", "S");
|
||||
releaseInfo = releaseInfo.Trim();
|
||||
}
|
||||
else if (rowCq.HasClass("torrent"))
|
||||
{
|
||||
var links = rowCq.Find("a");
|
||||
// Protect against format changes
|
||||
if (links.Count() != 2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var release = new ReleaseInfo();
|
||||
release.MinimumRatio = 1;
|
||||
release.MinimumSeedTime = 259200;
|
||||
var downloadLink = links.Get(0);
|
||||
|
||||
// We dont know this so try to fake based on the release year
|
||||
release.PublishDate = new DateTime(year, 1, 1);
|
||||
release.PublishDate = release.PublishDate.AddDays(Math.Min(DateTime.Now.DayOfYear, 365) - 1);
|
||||
|
||||
var infoLink = links.Get(1);
|
||||
release.Comments = new Uri(SiteLink + infoLink.Attributes.GetAttribute("href"));
|
||||
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);
|
||||
|
||||
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
|
||||
var releaseTags = infoLink.InnerText.Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||
for (int i = releaseTags.Count - 1; i >= 0; i--)
|
||||
{
|
||||
releaseTags[i] = releaseTags[i].Trim();
|
||||
if (string.IsNullOrWhiteSpace(releaseTags[i]))
|
||||
releaseTags.RemoveAt(i);
|
||||
}
|
||||
|
||||
var group = releaseTags.Last();
|
||||
if (group.Contains("(") && group.Contains(")"))
|
||||
{
|
||||
// Skip raws if set
|
||||
if (group.ToLowerInvariant().StartsWith("raw") && !AllowRaws)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var start = group.IndexOf("(");
|
||||
group = "[" + group.Substring(start + 1, (group.IndexOf(")") - 1) - start) + "] ";
|
||||
}
|
||||
else
|
||||
{
|
||||
group = string.Empty;
|
||||
}
|
||||
|
||||
var infoString = "";
|
||||
|
||||
for (int i = 0; i + 1 < releaseTags.Count(); i++)
|
||||
{
|
||||
if (releaseTags[i] == "Raw" && !AllowRaws)
|
||||
continue;
|
||||
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.Description = title;
|
||||
|
||||
var size = rowCq.Find(".torrent_size");
|
||||
if (size.Count() > 0)
|
||||
{
|
||||
release.Size = ReleaseInfo.GetBytes(size.First().Text());
|
||||
}
|
||||
|
||||
// Additional 5 hours per GB
|
||||
release.MinimumSeedTime += (release.Size / 1000000000) * 18000;
|
||||
|
||||
// Peer info
|
||||
release.Seeders = ParseUtil.CoerceInt(rowCq.Find(".torrent_seeders").Text());
|
||||
release.Peers = release.Seeders + ParseUtil.CoerceInt(rowCq.Find(".torrent_leechers").Text());
|
||||
|
||||
if (release.Category != 0)
|
||||
releases.Add(release);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(response.Content, ex);
|
||||
}
|
||||
|
||||
// Add to the cache
|
||||
lock (cache)
|
||||
{
|
||||
cache.Add(new CachedQueryResult(searchTerm, releases));
|
||||
}
|
||||
|
||||
return releases.Select(s => (ReleaseInfo)s.Clone());
|
||||
}
|
||||
|
||||
|
||||
public async override Task<byte[]> Download(Uri link)
|
||||
{
|
||||
// The urls for this tracker are quite long so append the domain after the incoming request.
|
||||
var response = await webclient.GetBytes(new Utils.Clients.WebRequest()
|
||||
{
|
||||
Url = SiteLink + link.ToString(),
|
||||
Cookies = CookieHeader
|
||||
});
|
||||
|
||||
return response.Content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -311,7 +311,7 @@ namespace Jackett.Indexers
|
||||
return await webclient.GetBytes(request);
|
||||
}
|
||||
|
||||
protected async Task<WebClientStringResult> PostDataWithCookies(string url, IEnumerable<KeyValuePair<string, string>> data, string cookieOverride = null, string referer = null)
|
||||
protected async Task<WebClientStringResult> PostDataWithCookies(string url, IEnumerable<KeyValuePair<string, string>> data, string cookieOverride = null, string referer = null, Dictionary<string, string> headers = null, string rawbody = null)
|
||||
{
|
||||
var request = new Utils.Clients.WebRequest()
|
||||
{
|
||||
@@ -319,19 +319,20 @@ namespace Jackett.Indexers
|
||||
Type = RequestType.POST,
|
||||
Cookies = cookieOverride ?? CookieHeader,
|
||||
PostData = data,
|
||||
Referer = referer
|
||||
Referer = referer,
|
||||
Headers = headers
|
||||
};
|
||||
return await webclient.GetString(request);
|
||||
}
|
||||
|
||||
protected async Task<WebClientStringResult> PostDataWithCookiesAndRetry(string url, IEnumerable<KeyValuePair<string, string>> data, string cookieOverride = null, string referer = null)
|
||||
protected async Task<WebClientStringResult> PostDataWithCookiesAndRetry(string url, IEnumerable<KeyValuePair<string, string>> data, string cookieOverride = null, string referer = null, Dictionary<string, string> headers = null, string rawbody = null)
|
||||
{
|
||||
Exception lastException = null;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await PostDataWithCookies(url, data, cookieOverride, referer);
|
||||
return await PostDataWithCookies(url, data, cookieOverride, referer, headers, rawbody);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
151
src/Jackett/Indexers/BroadcastTheNet.cs
Normal file
151
src/Jackett/Indexers/BroadcastTheNet.cs
Normal file
@@ -0,0 +1,151 @@
|
||||
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.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
using System.Dynamic;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
public class BroadcastTheNet : BaseIndexer, IIndexer
|
||||
{
|
||||
string APIBASE = "http://api.btnapps.net/";
|
||||
|
||||
new ConfigurationDataAPIKey configData
|
||||
{
|
||||
get { return (ConfigurationDataAPIKey)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public BroadcastTheNet(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
|
||||
: base(name: "BroadcastTheNet",
|
||||
description: "Needs no description..",
|
||||
link: "https://broadcasthe.net/",
|
||||
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: wc,
|
||||
logger: l,
|
||||
p: ps,
|
||||
configData: new ConfigurationDataAPIKey())
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
configData.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;
|
||||
}
|
||||
|
||||
|
||||
private string JsonRPCRequest(string method, dynamic parameters)
|
||||
{
|
||||
dynamic request = new ExpandoObject();
|
||||
request["jsonrpc"] = "2.0";
|
||||
request["method"] = method;
|
||||
request["params"] = parameters;
|
||||
request["id"] = Guid.NewGuid().ToString().Substring(0, 8);
|
||||
return request.ToString();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
|
||||
|
||||
var response = await PostDataWithCookiesAndRetry(APIBASE, null, null, null, new Dictionary<string, string>()
|
||||
{
|
||||
{ "Accept", "application/json-rpc, application/json"},
|
||||
{"ContentType", "application/json-rpc"}
|
||||
}, JsonRPCRequest("getTorrents", new Object[]
|
||||
{
|
||||
configData.Key.Value
|
||||
}));
|
||||
|
||||
/*
|
||||
var searchUrl = BrowsePage;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(query.GetQueryString()))
|
||||
{
|
||||
searchUrl += string.Format(QueryString, HttpUtility.UrlEncode(query.GetQueryString()));
|
||||
}
|
||||
|
||||
var results = await RequestStringWithCookiesAndRetry(searchUrl);
|
||||
|
||||
try
|
||||
{
|
||||
CQ dom = results.Content;
|
||||
|
||||
var rows = dom["#sortabletable tr"];
|
||||
foreach (var row in rows.Skip(1))
|
||||
{
|
||||
var release = new ReleaseInfo();
|
||||
var qRow = row.Cq();
|
||||
release.Title = qRow.Find(".tooltip-content div").First().Text();
|
||||
if (string.IsNullOrWhiteSpace(release.Title))
|
||||
continue;
|
||||
release.Description = qRow.Find(".tooltip-content div").Get(1).InnerText.Trim();
|
||||
|
||||
var qLink = row.Cq().Find("td:eq(2) a:eq(1)");
|
||||
release.Link = new Uri(qLink.Attr("href"));
|
||||
release.Guid = release.Link;
|
||||
release.Comments = new Uri(qRow.Find(".tooltip-target a").First().Attr("href"));
|
||||
|
||||
// 07-22-2015 11:08 AM
|
||||
var dateString = qRow.Find("td:eq(1) div").Last().Children().Remove().End().Text().Trim();
|
||||
release.PublishDate = DateTime.ParseExact(dateString, "MM-dd-yyyy hh:mm tt", CultureInfo.InvariantCulture);
|
||||
|
||||
var sizeStr = qRow.Find("td:eq(4)").Text().Trim();
|
||||
release.Size = ReleaseInfo.GetBytes(sizeStr);
|
||||
|
||||
release.Seeders = ParseUtil.CoerceInt(qRow.Find("td:eq(6)").Text().Trim());
|
||||
release.Peers = ParseUtil.CoerceInt(qRow.Find("td:eq(7)").Text().Trim()) + release.Seeders;
|
||||
|
||||
var catLink = row.Cq().Find("td:eq(0) a").First().Attr("href");
|
||||
var catSplit = catLink.IndexOf("category=");
|
||||
if (catSplit > -1)
|
||||
{
|
||||
catLink = catLink.Substring(catSplit + 9);
|
||||
}
|
||||
|
||||
release.Category = MapTrackerCatToNewznab(catLink);
|
||||
releases.Add(release);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(results.Content, ex);
|
||||
}*/
|
||||
|
||||
return releases;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@@ -1,156 +1,157 @@
|
||||
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.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
public class FileList : BaseIndexer, IIndexer
|
||||
{
|
||||
string LoginUrl { get { return SiteLink + "takelogin.php"; } }
|
||||
string BrowseUrl { get { return SiteLink + "browse.php"; } }
|
||||
|
||||
new ConfigurationDataFileList configData
|
||||
{
|
||||
get { return (ConfigurationDataFileList)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public FileList(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
|
||||
: base(name: "FileList",
|
||||
description: "The best Romanian site.",
|
||||
link: "http://filelist.ro/",
|
||||
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: wc,
|
||||
logger: l,
|
||||
p: ps,
|
||||
configData: new ConfigurationDataFileList())
|
||||
{
|
||||
AddCategoryMapping(24, TorznabCatType.TVAnime);
|
||||
AddCategoryMapping(11, TorznabCatType.Audio);
|
||||
AddCategoryMapping(15, TorznabCatType.TV);
|
||||
//AddCategoryMapping(18, TorznabCatType.); Other
|
||||
AddCategoryMapping(16, TorznabCatType.TVDocumentary);
|
||||
AddCategoryMapping(25, TorznabCatType.Movies3D);
|
||||
AddCategoryMapping(20, TorznabCatType.MoviesBluRay);
|
||||
AddCategoryMapping(2, TorznabCatType.MoviesSD);
|
||||
AddCategoryMapping(3, TorznabCatType.MoviesForeign); //RO
|
||||
AddCategoryMapping(4, TorznabCatType.MoviesHD);
|
||||
AddCategoryMapping(19, TorznabCatType.MoviesForeign); // RO
|
||||
AddCategoryMapping(1, TorznabCatType.MoviesSD);
|
||||
AddCategoryMapping(10, TorznabCatType.Console);
|
||||
AddCategoryMapping(9, TorznabCatType.PCGames);
|
||||
//AddCategoryMapping(17, TorznabCatType); Linux No cat
|
||||
AddCategoryMapping(22, TorznabCatType.PCPhoneOther); //Apps/mobile
|
||||
AddCategoryMapping(8, TorznabCatType.PC);
|
||||
AddCategoryMapping(21, TorznabCatType.TVHD);
|
||||
AddCategoryMapping(23, TorznabCatType.TVSD);
|
||||
AddCategoryMapping(13, TorznabCatType.TVSport);
|
||||
AddCategoryMapping(14, TorznabCatType.TV);
|
||||
AddCategoryMapping(12, TorznabCatType.AudioVideo);
|
||||
AddCategoryMapping(7, TorznabCatType.XXX);
|
||||
}
|
||||
|
||||
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "username", configData.Username.Value },
|
||||
{ "password", configData.Password.Value }
|
||||
};
|
||||
|
||||
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, LoginUrl);
|
||||
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
|
||||
{
|
||||
CQ dom = result.Content;
|
||||
var errorMessage = dom[".main"].Text().Trim();
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
return IndexerConfigurationStatus.RequiresTesting;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
var searchUrl = BrowseUrl;
|
||||
var searchString = query.GetQueryString();
|
||||
|
||||
var cats = MapTorznabCapsToTrackers(query);
|
||||
string cat = "0";
|
||||
if (cats.Count == 1)
|
||||
{
|
||||
cat = cats[0];
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(searchString) || cat != "0")
|
||||
searchUrl += string.Format("?search={0}&cat={1}&searchin=0&sort=0", HttpUtility.UrlEncode(searchString), cat);
|
||||
|
||||
|
||||
|
||||
var response = await RequestStringWithCookiesAndRetry(searchUrl, null, BrowseUrl);
|
||||
var results = response.Content;
|
||||
try
|
||||
{
|
||||
CQ dom = results;
|
||||
var rows = dom[".torrentrow"];
|
||||
foreach (var row in rows)
|
||||
{
|
||||
var release = new ReleaseInfo();
|
||||
var qRow = row.Cq();
|
||||
var qTitleLink = qRow.Find(".torrenttable:eq(1) a").First();
|
||||
release.Title = qRow.Find(".torrenttable:eq(1) a b").Text().Trim();
|
||||
release.Description = release.Title;
|
||||
release.Guid = new Uri(SiteLink + qTitleLink.Attr("href"));
|
||||
release.Comments = release.Guid;
|
||||
|
||||
//22:05:3716/02/2013
|
||||
var dateStr = qRow.Find(".torrenttable:eq(5)").Text().Trim();
|
||||
release.PublishDate = DateTime.ParseExact(dateStr, "H:mm:ssdd/MM/yyyy", CultureInfo.InvariantCulture).AddHours(-2);
|
||||
|
||||
var qLink = qRow.Find(".torrenttable:eq(2) a").First();
|
||||
release.Link = new Uri(SiteLink + qLink.Attr("href"));
|
||||
|
||||
var sizeStr = qRow.Find(".torrenttable:eq(6)").Text().Trim();
|
||||
release.Size = ReleaseInfo.GetBytes(sizeStr);
|
||||
|
||||
release.Seeders = ParseUtil.CoerceInt(qRow.Find(".torrenttable:eq(8)").Text().Trim());
|
||||
release.Peers = ParseUtil.CoerceInt(qRow.Find(".torrenttable:eq(9)").Text().Trim()) + release.Seeders;
|
||||
|
||||
var catId = qRow.Find(".torrenttable:eq(0) a").First().Attr("href").Substring(15);
|
||||
release.Category = MapTrackerCatToNewznab(catId);
|
||||
|
||||
// Skip other
|
||||
if (release.Category != 0)
|
||||
{
|
||||
// Skip Romanian releases
|
||||
if (release.Category == TorznabCatType.MoviesForeign.ID && !configData.IncludeRomanianReleases.Value)
|
||||
continue;
|
||||
|
||||
releases.Add(release);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(results, ex);
|
||||
}
|
||||
|
||||
return releases;
|
||||
}
|
||||
}
|
||||
}
|
||||
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.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
using Jackett.Models.IndexerConfig.Bespoke;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
public class FileList : BaseIndexer, IIndexer
|
||||
{
|
||||
string LoginUrl { get { return SiteLink + "takelogin.php"; } }
|
||||
string BrowseUrl { get { return SiteLink + "browse.php"; } }
|
||||
|
||||
new ConfigurationDataFileList configData
|
||||
{
|
||||
get { return (ConfigurationDataFileList)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public FileList(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
|
||||
: base(name: "FileList",
|
||||
description: "The best Romanian site.",
|
||||
link: "http://filelist.ro/",
|
||||
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: wc,
|
||||
logger: l,
|
||||
p: ps,
|
||||
configData: new ConfigurationDataFileList())
|
||||
{
|
||||
AddCategoryMapping(24, TorznabCatType.TVAnime);
|
||||
AddCategoryMapping(11, TorznabCatType.Audio);
|
||||
AddCategoryMapping(15, TorznabCatType.TV);
|
||||
//AddCategoryMapping(18, TorznabCatType.); Other
|
||||
AddCategoryMapping(16, TorznabCatType.TVDocumentary);
|
||||
AddCategoryMapping(25, TorznabCatType.Movies3D);
|
||||
AddCategoryMapping(20, TorznabCatType.MoviesBluRay);
|
||||
AddCategoryMapping(2, TorznabCatType.MoviesSD);
|
||||
AddCategoryMapping(3, TorznabCatType.MoviesForeign); //RO
|
||||
AddCategoryMapping(4, TorznabCatType.MoviesHD);
|
||||
AddCategoryMapping(19, TorznabCatType.MoviesForeign); // RO
|
||||
AddCategoryMapping(1, TorznabCatType.MoviesSD);
|
||||
AddCategoryMapping(10, TorznabCatType.Console);
|
||||
AddCategoryMapping(9, TorznabCatType.PCGames);
|
||||
//AddCategoryMapping(17, TorznabCatType); Linux No cat
|
||||
AddCategoryMapping(22, TorznabCatType.PCPhoneOther); //Apps/mobile
|
||||
AddCategoryMapping(8, TorznabCatType.PC);
|
||||
AddCategoryMapping(21, TorznabCatType.TVHD);
|
||||
AddCategoryMapping(23, TorznabCatType.TVSD);
|
||||
AddCategoryMapping(13, TorznabCatType.TVSport);
|
||||
AddCategoryMapping(14, TorznabCatType.TV);
|
||||
AddCategoryMapping(12, TorznabCatType.AudioVideo);
|
||||
AddCategoryMapping(7, TorznabCatType.XXX);
|
||||
}
|
||||
|
||||
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "username", configData.Username.Value },
|
||||
{ "password", configData.Password.Value }
|
||||
};
|
||||
|
||||
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, LoginUrl);
|
||||
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
|
||||
{
|
||||
CQ dom = result.Content;
|
||||
var errorMessage = dom[".main"].Text().Trim();
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
return IndexerConfigurationStatus.RequiresTesting;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
var searchUrl = BrowseUrl;
|
||||
var searchString = query.GetQueryString();
|
||||
|
||||
var cats = MapTorznabCapsToTrackers(query);
|
||||
string cat = "0";
|
||||
if (cats.Count == 1)
|
||||
{
|
||||
cat = cats[0];
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(searchString) || cat != "0")
|
||||
searchUrl += string.Format("?search={0}&cat={1}&searchin=0&sort=0", HttpUtility.UrlEncode(searchString), cat);
|
||||
|
||||
|
||||
|
||||
var response = await RequestStringWithCookiesAndRetry(searchUrl, null, BrowseUrl);
|
||||
var results = response.Content;
|
||||
try
|
||||
{
|
||||
CQ dom = results;
|
||||
var rows = dom[".torrentrow"];
|
||||
foreach (var row in rows)
|
||||
{
|
||||
var release = new ReleaseInfo();
|
||||
var qRow = row.Cq();
|
||||
var qTitleLink = qRow.Find(".torrenttable:eq(1) a").First();
|
||||
release.Title = qRow.Find(".torrenttable:eq(1) a b").Text().Trim();
|
||||
release.Description = release.Title;
|
||||
release.Guid = new Uri(SiteLink + qTitleLink.Attr("href"));
|
||||
release.Comments = release.Guid;
|
||||
|
||||
//22:05:3716/02/2013
|
||||
var dateStr = qRow.Find(".torrenttable:eq(5)").Text().Trim();
|
||||
release.PublishDate = DateTime.ParseExact(dateStr, "H:mm:ssdd/MM/yyyy", CultureInfo.InvariantCulture).AddHours(-2);
|
||||
|
||||
var qLink = qRow.Find(".torrenttable:eq(2) a").First();
|
||||
release.Link = new Uri(SiteLink + qLink.Attr("href"));
|
||||
|
||||
var sizeStr = qRow.Find(".torrenttable:eq(6)").Text().Trim();
|
||||
release.Size = ReleaseInfo.GetBytes(sizeStr);
|
||||
|
||||
release.Seeders = ParseUtil.CoerceInt(qRow.Find(".torrenttable:eq(8)").Text().Trim());
|
||||
release.Peers = ParseUtil.CoerceInt(qRow.Find(".torrenttable:eq(9)").Text().Trim()) + release.Seeders;
|
||||
|
||||
var catId = qRow.Find(".torrenttable:eq(0) a").First().Attr("href").Substring(15);
|
||||
release.Category = MapTrackerCatToNewznab(catId);
|
||||
|
||||
// Skip other
|
||||
if (release.Category != 0)
|
||||
{
|
||||
// Skip Romanian releases
|
||||
if (release.Category == TorznabCatType.MoviesForeign.ID && !configData.IncludeRomanianReleases.Value)
|
||||
continue;
|
||||
|
||||
releases.Add(release);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(results, ex);
|
||||
}
|
||||
|
||||
return releases;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,232 +1,233 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Jackett.Models;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
using Jackett.Utils;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using CsQuery;
|
||||
using System.Web;
|
||||
using Jackett.Services;
|
||||
using Jackett.Utils.Clients;
|
||||
using System.Text.RegularExpressions;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
using System.Globalization;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
public class RuTor : BaseIndexer, IIndexer
|
||||
{
|
||||
private string SearchUrl { get { return SiteLink + "search/0/{0}/000/0/{1}"; } }
|
||||
private string BrowseUrl { get { return SiteLink + "browse/0/{0}/0/0"; } }
|
||||
readonly static string defaultSiteLink = "http://rutor.org/";
|
||||
|
||||
new ConfigurationDataRuTor configData
|
||||
{
|
||||
get { return (ConfigurationDataRuTor)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public RuTor(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
|
||||
: base(name: "RUTor",
|
||||
description: "Свободный торрент трекер",
|
||||
link: "http://rutor.org/",
|
||||
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: wc,
|
||||
logger: l,
|
||||
p: ps,
|
||||
configData: new ConfigurationDataRuTor(defaultSiteLink))
|
||||
{
|
||||
TorznabCaps.Categories.Add(TorznabCatType.TVAnime);
|
||||
TorznabCaps.Categories.Add(TorznabCatType.Movies);
|
||||
TorznabCaps.Categories.Add(TorznabCatType.Audio);
|
||||
TorznabCaps.Categories.Add(TorznabCatType.Books);
|
||||
}
|
||||
|
||||
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
var oldConfig = configData;
|
||||
var releases = await PerformQuery(new TorznabQuery());
|
||||
|
||||
await ConfigureIfOK(string.Empty, releases.Count() > 0, () =>
|
||||
{
|
||||
configData = oldConfig;
|
||||
throw new Exception("Could not find releases from this URL");
|
||||
});
|
||||
|
||||
return IndexerConfigurationStatus.RequiresTesting;
|
||||
}
|
||||
|
||||
|
||||
protected override void SaveConfig()
|
||||
{
|
||||
indexerService.SaveConfig(this as IIndexer, JsonConvert.SerializeObject(configData));
|
||||
}
|
||||
|
||||
// Override to load legacy config format
|
||||
public override void LoadFromSavedConfiguration(JToken jsonConfig)
|
||||
{
|
||||
var json = jsonConfig.ToString();
|
||||
configData = JsonConvert.DeserializeObject<ConfigurationDataRuTor>(json);
|
||||
IsConfigured = true;
|
||||
}
|
||||
|
||||
private readonly int CAT_ANY = 0;
|
||||
private readonly int CAT_FOREIGN_MOVIE = 1;
|
||||
// private readonly int CAT_OUR_MOVIES = 5;
|
||||
// private readonly int CAT_POP_SCIFI_MOVIES = 12;
|
||||
private readonly int CAT_TV_SERIES = 4;
|
||||
// private readonly int CAT_TV = 6;
|
||||
// private readonly int CAT_ANIMATION = 7;
|
||||
private readonly int CAT_ANIME = 10;
|
||||
private readonly int CAT_MUSIC = 2;
|
||||
// private readonly int CAT_GAMES = 8;
|
||||
// private readonly int CAT_SOFTWARE = 9;
|
||||
// private readonly int CAT_SPORTS_HEALTH = 13;
|
||||
// private readonly int CAT_HUMOR = 15;
|
||||
// private readonly int CAT_ECONOMY_LIFE = 14;
|
||||
private readonly int CAT_BOOKS = 11;
|
||||
// private readonly int CAT_OTHER = 3;
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
var searchString = query.GetQueryString();
|
||||
var searchCategory = CAT_ANY;
|
||||
|
||||
if (query.Categories.Contains(TorznabCatType.TV.ID) ||
|
||||
query.Categories.Contains(TorznabCatType.TVHD.ID) ||
|
||||
query.Categories.Contains(TorznabCatType.TVSD.ID))
|
||||
{
|
||||
searchCategory = CAT_TV_SERIES;
|
||||
}
|
||||
|
||||
if ((searchCategory == CAT_ANY) &&
|
||||
(query.Categories.Contains(TorznabCatType.Movies.ID) ||
|
||||
query.Categories.Contains(TorznabCatType.MoviesForeign.ID) ||
|
||||
query.Categories.Contains(TorznabCatType.MoviesHD.ID) ||
|
||||
query.Categories.Contains(TorznabCatType.MoviesSD.ID)))
|
||||
{
|
||||
searchCategory = CAT_FOREIGN_MOVIE;
|
||||
}
|
||||
|
||||
if ((searchCategory == CAT_ANY) &&
|
||||
(query.Categories.Contains(TorznabCatType.TVAnime.ID)))
|
||||
{
|
||||
searchCategory = CAT_ANIME;
|
||||
}
|
||||
|
||||
if ((searchCategory == CAT_ANY) &&
|
||||
(query.Categories.Contains(TorznabCatType.Books.ID)))
|
||||
{
|
||||
searchCategory = CAT_BOOKS;
|
||||
}
|
||||
|
||||
if ((searchCategory == CAT_ANY) &&
|
||||
(query.Categories.Contains(TorznabCatType.Audio.ID) ||
|
||||
query.Categories.Contains(TorznabCatType.AudioLossless.ID) ||
|
||||
query.Categories.Contains(TorznabCatType.AudioMP3.ID)))
|
||||
{
|
||||
searchCategory = CAT_MUSIC;
|
||||
}
|
||||
|
||||
string queryUrl = string.Empty;
|
||||
if (string.IsNullOrWhiteSpace(searchString))
|
||||
{
|
||||
queryUrl = string.Format(BrowseUrl, searchCategory);
|
||||
}
|
||||
else
|
||||
{
|
||||
queryUrl = string.Format(SearchUrl, searchCategory, HttpUtility.UrlEncode(searchString.Trim()));
|
||||
}
|
||||
|
||||
var results = await RequestStringWithCookiesAndRetry(queryUrl, string.Empty);
|
||||
try
|
||||
{
|
||||
CQ dom = results.Content;
|
||||
var rows = dom["#index table tr"];
|
||||
foreach (var row in rows.Skip(1))
|
||||
{
|
||||
var release = new ReleaseInfo();
|
||||
|
||||
release.MinimumRatio = 1;
|
||||
release.MinimumSeedTime = 172800;
|
||||
|
||||
var date = StringUtil.StripNonAlphaNumeric(row.Cq().Find("td:eq(0)").Text().Trim()
|
||||
.Replace("Янв", "01")
|
||||
.Replace("Фев", "02")
|
||||
.Replace("Мар", "03")
|
||||
.Replace("Апр", "04")
|
||||
.Replace("Май", "05")
|
||||
.Replace("Июн", "06")
|
||||
.Replace("Июл", "07")
|
||||
.Replace("Авг", "08")
|
||||
.Replace("Сен", "09")
|
||||
.Replace("Окт", "10")
|
||||
.Replace("Ноя", "11")
|
||||
.Replace("Дек", "12"));
|
||||
|
||||
release.PublishDate = DateTime.ParseExact(date, "ddMMyy", CultureInfo.InvariantCulture);
|
||||
|
||||
var hasTorrent = row.Cq().Find("td:eq(1) a").Length == 3;
|
||||
var titleIndex = 1;
|
||||
if (hasTorrent)
|
||||
titleIndex++;
|
||||
|
||||
release.Title = row.Cq().Find("td:eq(" + titleIndex + ")").Text().Trim();
|
||||
if (configData.StripRussian.Value)
|
||||
{
|
||||
var split = release.Title.IndexOf('/');
|
||||
if (split > -1)
|
||||
{
|
||||
release.Title = release.Title.Substring(split + 1).Trim();
|
||||
}
|
||||
}
|
||||
|
||||
release.Description = release.Title;
|
||||
|
||||
var hasComments = row.Cq().Find("td:eq(2) img").Length > 0;
|
||||
var sizeCol = 2;
|
||||
|
||||
if (hasComments)
|
||||
sizeCol++;
|
||||
|
||||
var sizeStr = StringUtil.StripRegex(row.Cq().Find("td:eq(" + sizeCol + ")").Text(), "[^a-zA-Z0-9\\. -]", " ").Trim();
|
||||
string[] sizeSplit = sizeStr.Split(' ');
|
||||
release.Size = ReleaseInfo.GetBytes(sizeSplit[1].ToLower(), ParseUtil.CoerceFloat(sizeSplit[0]));
|
||||
|
||||
release.Seeders = ParseUtil.CoerceInt(row.Cq().Find(".green").Text().Trim());
|
||||
release.Peers = ParseUtil.CoerceInt(row.Cq().Find(".red").Text().Trim()) + release.Seeders;
|
||||
|
||||
release.Guid = new Uri(configData.Url.Value + row.Cq().Find("td:eq(1) a:eq(" + titleIndex + ")").Attr("href").Substring(1));
|
||||
release.Comments = release.Guid;
|
||||
|
||||
if (hasTorrent)
|
||||
{
|
||||
release.Link = new Uri(row.Cq().Find("td:eq(1) a:eq(0)").Attr("href"));
|
||||
release.MagnetUri = new Uri(row.Cq().Find("td:eq(1) a:eq(1)").Attr("href"));
|
||||
}
|
||||
else
|
||||
{
|
||||
release.MagnetUri = new Uri(row.Cq().Find("td:eq(1) a:eq(0)").Attr("href"));
|
||||
}
|
||||
|
||||
releases.Add(release);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(results.Content, ex);
|
||||
}
|
||||
|
||||
return releases;
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Jackett.Models;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
using Jackett.Utils;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using CsQuery;
|
||||
using System.Web;
|
||||
using Jackett.Services;
|
||||
using Jackett.Utils.Clients;
|
||||
using System.Text.RegularExpressions;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
using System.Globalization;
|
||||
using Newtonsoft.Json;
|
||||
using Jackett.Models.IndexerConfig.Bespoke;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
public class RuTor : BaseIndexer, IIndexer
|
||||
{
|
||||
private string SearchUrl { get { return SiteLink + "search/0/{0}/000/0/{1}"; } }
|
||||
private string BrowseUrl { get { return SiteLink + "browse/0/{0}/0/0"; } }
|
||||
readonly static string defaultSiteLink = "http://rutor.org/";
|
||||
|
||||
new ConfigurationDataRuTor configData
|
||||
{
|
||||
get { return (ConfigurationDataRuTor)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public RuTor(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
|
||||
: base(name: "RUTor",
|
||||
description: "Свободный торрент трекер",
|
||||
link: "http://rutor.org/",
|
||||
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: wc,
|
||||
logger: l,
|
||||
p: ps,
|
||||
configData: new ConfigurationDataRuTor(defaultSiteLink))
|
||||
{
|
||||
TorznabCaps.Categories.Add(TorznabCatType.TVAnime);
|
||||
TorznabCaps.Categories.Add(TorznabCatType.Movies);
|
||||
TorznabCaps.Categories.Add(TorznabCatType.Audio);
|
||||
TorznabCaps.Categories.Add(TorznabCatType.Books);
|
||||
}
|
||||
|
||||
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
var oldConfig = configData;
|
||||
var releases = await PerformQuery(new TorznabQuery());
|
||||
|
||||
await ConfigureIfOK(string.Empty, releases.Count() > 0, () =>
|
||||
{
|
||||
configData = oldConfig;
|
||||
throw new Exception("Could not find releases from this URL");
|
||||
});
|
||||
|
||||
return IndexerConfigurationStatus.RequiresTesting;
|
||||
}
|
||||
|
||||
|
||||
protected override void SaveConfig()
|
||||
{
|
||||
indexerService.SaveConfig(this as IIndexer, JsonConvert.SerializeObject(configData));
|
||||
}
|
||||
|
||||
// Override to load legacy config format
|
||||
public override void LoadFromSavedConfiguration(JToken jsonConfig)
|
||||
{
|
||||
var json = jsonConfig.ToString();
|
||||
configData = JsonConvert.DeserializeObject<ConfigurationDataRuTor>(json);
|
||||
IsConfigured = true;
|
||||
}
|
||||
|
||||
private readonly int CAT_ANY = 0;
|
||||
private readonly int CAT_FOREIGN_MOVIE = 1;
|
||||
// private readonly int CAT_OUR_MOVIES = 5;
|
||||
// private readonly int CAT_POP_SCIFI_MOVIES = 12;
|
||||
private readonly int CAT_TV_SERIES = 4;
|
||||
// private readonly int CAT_TV = 6;
|
||||
// private readonly int CAT_ANIMATION = 7;
|
||||
private readonly int CAT_ANIME = 10;
|
||||
private readonly int CAT_MUSIC = 2;
|
||||
// private readonly int CAT_GAMES = 8;
|
||||
// private readonly int CAT_SOFTWARE = 9;
|
||||
// private readonly int CAT_SPORTS_HEALTH = 13;
|
||||
// private readonly int CAT_HUMOR = 15;
|
||||
// private readonly int CAT_ECONOMY_LIFE = 14;
|
||||
private readonly int CAT_BOOKS = 11;
|
||||
// private readonly int CAT_OTHER = 3;
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
var searchString = query.GetQueryString();
|
||||
var searchCategory = CAT_ANY;
|
||||
|
||||
if (query.Categories.Contains(TorznabCatType.TV.ID) ||
|
||||
query.Categories.Contains(TorznabCatType.TVHD.ID) ||
|
||||
query.Categories.Contains(TorznabCatType.TVSD.ID))
|
||||
{
|
||||
searchCategory = CAT_TV_SERIES;
|
||||
}
|
||||
|
||||
if ((searchCategory == CAT_ANY) &&
|
||||
(query.Categories.Contains(TorznabCatType.Movies.ID) ||
|
||||
query.Categories.Contains(TorznabCatType.MoviesForeign.ID) ||
|
||||
query.Categories.Contains(TorznabCatType.MoviesHD.ID) ||
|
||||
query.Categories.Contains(TorznabCatType.MoviesSD.ID)))
|
||||
{
|
||||
searchCategory = CAT_FOREIGN_MOVIE;
|
||||
}
|
||||
|
||||
if ((searchCategory == CAT_ANY) &&
|
||||
(query.Categories.Contains(TorznabCatType.TVAnime.ID)))
|
||||
{
|
||||
searchCategory = CAT_ANIME;
|
||||
}
|
||||
|
||||
if ((searchCategory == CAT_ANY) &&
|
||||
(query.Categories.Contains(TorznabCatType.Books.ID)))
|
||||
{
|
||||
searchCategory = CAT_BOOKS;
|
||||
}
|
||||
|
||||
if ((searchCategory == CAT_ANY) &&
|
||||
(query.Categories.Contains(TorznabCatType.Audio.ID) ||
|
||||
query.Categories.Contains(TorznabCatType.AudioLossless.ID) ||
|
||||
query.Categories.Contains(TorznabCatType.AudioMP3.ID)))
|
||||
{
|
||||
searchCategory = CAT_MUSIC;
|
||||
}
|
||||
|
||||
string queryUrl = string.Empty;
|
||||
if (string.IsNullOrWhiteSpace(searchString))
|
||||
{
|
||||
queryUrl = string.Format(BrowseUrl, searchCategory);
|
||||
}
|
||||
else
|
||||
{
|
||||
queryUrl = string.Format(SearchUrl, searchCategory, HttpUtility.UrlEncode(searchString.Trim()));
|
||||
}
|
||||
|
||||
var results = await RequestStringWithCookiesAndRetry(queryUrl, string.Empty);
|
||||
try
|
||||
{
|
||||
CQ dom = results.Content;
|
||||
var rows = dom["#index table tr"];
|
||||
foreach (var row in rows.Skip(1))
|
||||
{
|
||||
var release = new ReleaseInfo();
|
||||
|
||||
release.MinimumRatio = 1;
|
||||
release.MinimumSeedTime = 172800;
|
||||
|
||||
var date = StringUtil.StripNonAlphaNumeric(row.Cq().Find("td:eq(0)").Text().Trim()
|
||||
.Replace("Янв", "01")
|
||||
.Replace("Фев", "02")
|
||||
.Replace("Мар", "03")
|
||||
.Replace("Апр", "04")
|
||||
.Replace("Май", "05")
|
||||
.Replace("Июн", "06")
|
||||
.Replace("Июл", "07")
|
||||
.Replace("Авг", "08")
|
||||
.Replace("Сен", "09")
|
||||
.Replace("Окт", "10")
|
||||
.Replace("Ноя", "11")
|
||||
.Replace("Дек", "12"));
|
||||
|
||||
release.PublishDate = DateTime.ParseExact(date, "ddMMyy", CultureInfo.InvariantCulture);
|
||||
|
||||
var hasTorrent = row.Cq().Find("td:eq(1) a").Length == 3;
|
||||
var titleIndex = 1;
|
||||
if (hasTorrent)
|
||||
titleIndex++;
|
||||
|
||||
release.Title = row.Cq().Find("td:eq(" + titleIndex + ")").Text().Trim();
|
||||
if (configData.StripRussian.Value)
|
||||
{
|
||||
var split = release.Title.IndexOf('/');
|
||||
if (split > -1)
|
||||
{
|
||||
release.Title = release.Title.Substring(split + 1).Trim();
|
||||
}
|
||||
}
|
||||
|
||||
release.Description = release.Title;
|
||||
|
||||
var hasComments = row.Cq().Find("td:eq(2) img").Length > 0;
|
||||
var sizeCol = 2;
|
||||
|
||||
if (hasComments)
|
||||
sizeCol++;
|
||||
|
||||
var sizeStr = StringUtil.StripRegex(row.Cq().Find("td:eq(" + sizeCol + ")").Text(), "[^a-zA-Z0-9\\. -]", " ").Trim();
|
||||
string[] sizeSplit = sizeStr.Split(' ');
|
||||
release.Size = ReleaseInfo.GetBytes(sizeSplit[1].ToLower(), ParseUtil.CoerceFloat(sizeSplit[0]));
|
||||
|
||||
release.Seeders = ParseUtil.CoerceInt(row.Cq().Find(".green").Text().Trim());
|
||||
release.Peers = ParseUtil.CoerceInt(row.Cq().Find(".red").Text().Trim()) + release.Seeders;
|
||||
|
||||
release.Guid = new Uri(configData.Url.Value + row.Cq().Find("td:eq(1) a:eq(" + titleIndex + ")").Attr("href").Substring(1));
|
||||
release.Comments = release.Guid;
|
||||
|
||||
if (hasTorrent)
|
||||
{
|
||||
release.Link = new Uri(row.Cq().Find("td:eq(1) a:eq(0)").Attr("href"));
|
||||
release.MagnetUri = new Uri(row.Cq().Find("td:eq(1) a:eq(1)").Attr("href"));
|
||||
}
|
||||
else
|
||||
{
|
||||
release.MagnetUri = new Uri(row.Cq().Find("td:eq(1) a:eq(0)").Attr("href"));
|
||||
}
|
||||
|
||||
releases.Add(release);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(results.Content, ex);
|
||||
}
|
||||
|
||||
return releases;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -17,6 +17,8 @@ using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.XPath;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
@@ -25,10 +27,11 @@ namespace Jackett.Indexers
|
||||
private string LoginUrl { get { return SiteLink + "login"; } }
|
||||
private string SearchUrl { get { return SiteLink + "search"; } }
|
||||
private string TorrentsUrl { get { return SiteLink + "torrents"; } }
|
||||
private string RSSProfile { get { return SiteLink + "rss_feeds"; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
new ConfigurationDataBasicLoginWithRSS configData
|
||||
{
|
||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
||||
get { return (ConfigurationDataBasicLoginWithRSS)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
@@ -43,7 +46,7 @@ namespace Jackett.Indexers
|
||||
client: c,
|
||||
logger: l,
|
||||
p: ps,
|
||||
configData: new ConfigurationDataBasicLogin())
|
||||
configData: new ConfigurationDataBasicLoginWithRSS())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -67,6 +70,15 @@ namespace Jackett.Indexers
|
||||
throw new ExceptionWithConfigData("The username and password entered do not match.", configData);
|
||||
});
|
||||
|
||||
var rssProfile = await RequestStringWithCookiesAndRetry(RSSProfile);
|
||||
CQ rssDom = rssProfile.Content;
|
||||
configData.RSSKey.Value = rssDom.Find(".col-sm-9:eq(0)").Text().Trim();
|
||||
if (string.IsNullOrWhiteSpace(configData.RSSKey.Value))
|
||||
{
|
||||
throw new ExceptionWithConfigData("Failed to find RSS key.", configData);
|
||||
}
|
||||
|
||||
SaveConfig();
|
||||
return IndexerConfigurationStatus.RequiresTesting;
|
||||
}
|
||||
|
||||
@@ -87,64 +99,115 @@ namespace Jackett.Indexers
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "portlet", "true"}
|
||||
};
|
||||
var rssUrl = SiteLink + "rss/recent?passkey=" + configData.RSSKey.Value;
|
||||
|
||||
results = await PostDataWithCookiesAndRetry(TorrentsUrl, pairs, null, TorrentsUrl);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
CQ dom = results.Content;
|
||||
var rows = dom["#torrent-table tr"];
|
||||
foreach (var row in rows.Skip(1))
|
||||
results = await RequestStringWithCookiesAndRetry(rssUrl);
|
||||
try
|
||||
{
|
||||
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"));
|
||||
|
||||
// 07-22-2015 11:08 AM
|
||||
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?
|
||||
|
||||
if(release.Title.Contains("1080p") || release.Title.Contains("720p"))
|
||||
var doc = XDocument.Parse(results.Content);
|
||||
foreach (var result in doc.Descendants("item"))
|
||||
{
|
||||
release.Category = TorznabCatType.TVHD.ID;
|
||||
} else
|
||||
{
|
||||
release.Category = TorznabCatType.TVSD.ID;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
releases.Add(release);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(results.Content, ex);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
foreach(var release in releases)
|
||||
{
|
||||
OnParseError(results.Content, ex);
|
||||
if (release.Title.Contains("1080p") || release.Title.Contains("720p"))
|
||||
{
|
||||
release.Category = TorznabCatType.TVHD.ID;
|
||||
}
|
||||
else
|
||||
{
|
||||
release.Category = TorznabCatType.TVSD.ID;
|
||||
}
|
||||
}
|
||||
|
||||
return releases;
|
||||
|
@@ -1,172 +1,173 @@
|
||||
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.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
using System.Collections.Specialized;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
public class Strike : BaseIndexer, IIndexer
|
||||
{
|
||||
readonly static string defaultSiteLink = "https://getstrike.net/";
|
||||
|
||||
private Uri BaseUri
|
||||
{
|
||||
get { return new Uri(configData.Url.Value); }
|
||||
set { configData.Url.Value = value.ToString(); }
|
||||
}
|
||||
|
||||
private string SearchUrl { get { return BaseUri + "api/v2/torrents/search/?phrase={0}"; } }
|
||||
private string DownloadUrl { get { return BaseUri + "torrents/api/download/{0}.torrent"; } }
|
||||
|
||||
new ConfigurationDataStrike configData
|
||||
{
|
||||
get { return (ConfigurationDataStrike)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
|
||||
public Strike(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
|
||||
: base(name: "Strike",
|
||||
description: "Torrent search engine",
|
||||
link: defaultSiteLink,
|
||||
caps: new TorznabCapabilities(),
|
||||
manager: i,
|
||||
client: wc,
|
||||
logger: l,
|
||||
p: ps,
|
||||
configData: new ConfigurationDataStrike(defaultSiteLink))
|
||||
{
|
||||
AddCategoryMapping("Anime", TorznabCatType.TVAnime);
|
||||
AddCategoryMapping("Applications", TorznabCatType.PC);
|
||||
AddCategoryMapping("Books", TorznabCatType.Books);
|
||||
AddCategoryMapping("Games", TorznabCatType.PCGames);
|
||||
AddCategoryMapping("Movies", TorznabCatType.Movies);
|
||||
AddCategoryMapping("TV", TorznabCatType.TV);
|
||||
AddCategoryMapping("XXX", TorznabCatType.XXX);
|
||||
AddCategoryMapping("Music", TorznabCatType.Audio);
|
||||
|
||||
/*AddCategoryMapping("Movies:Highres Movies", TorznabCatType.MoviesHD);
|
||||
AddCategoryMapping("Movies:3D Movies", TorznabCatType.Movies3D);
|
||||
AddCategoryMapping("Books:Ebooks", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("Books:Comics", TorznabCatType.BooksComics);
|
||||
AddCategoryMapping("Books:Audio Books", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("Games:XBOX360", TorznabCatType.ConsoleXbox360);
|
||||
AddCategoryMapping("Games:Wii", TorznabCatType.ConsoleWii);
|
||||
AddCategoryMapping("Games:PSP", TorznabCatType.ConsolePSP);
|
||||
AddCategoryMapping("Games:PS3", TorznabCatType.ConsolePS3);
|
||||
AddCategoryMapping("Games:PC", TorznabCatType.PCGames);
|
||||
AddCategoryMapping("Games:Android", TorznabCatType.PCPhoneAndroid);
|
||||
AddCategoryMapping("Music:Mp3", TorznabCatType.AudioMP3);*/
|
||||
}
|
||||
|
||||
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
var releases = await PerformQuery(new TorznabQuery());
|
||||
|
||||
await ConfigureIfOK(string.Empty, releases.Count() > 0, () =>
|
||||
{
|
||||
throw new Exception("Could not find releases from this URL");
|
||||
});
|
||||
|
||||
return IndexerConfigurationStatus.Completed;
|
||||
}
|
||||
|
||||
// Override to load legacy config format
|
||||
public override void LoadFromSavedConfiguration(JToken jsonConfig)
|
||||
{
|
||||
if (jsonConfig is JObject)
|
||||
{
|
||||
BaseUri = new Uri(jsonConfig.Value<string>("base_url"));
|
||||
SaveConfig();
|
||||
IsConfigured = true;
|
||||
return;
|
||||
}
|
||||
|
||||
base.LoadFromSavedConfiguration(jsonConfig);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
List<ReleaseInfo> releases = new List<ReleaseInfo>();
|
||||
var queryString = query.GetQueryString();
|
||||
var searchTerm = string.IsNullOrEmpty(queryString) ? DateTime.Now.Year.ToString() : queryString;
|
||||
var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchTerm));
|
||||
|
||||
var trackerCategories = MapTorznabCapsToTrackers(query, mapChildrenCatsToParent: true);
|
||||
|
||||
// This tracker can only search one cat at a time, otherwise search all and filter results
|
||||
if (trackerCategories.Count == 1)
|
||||
{
|
||||
episodeSearchUrl += "&category=" + trackerCategories[0];
|
||||
}
|
||||
|
||||
var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl, string.Empty);
|
||||
try
|
||||
{
|
||||
var jResults = JObject.Parse(results.Content);
|
||||
foreach (JObject result in (JArray)jResults["torrents"])
|
||||
{
|
||||
var release = new ReleaseInfo();
|
||||
|
||||
release.MinimumRatio = 1;
|
||||
release.MinimumSeedTime = 172800;
|
||||
|
||||
if (trackerCategories.Count > 0 && !trackerCategories.Contains((string)result["torrent_category"]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
release.Category = MapTrackerCatToNewznab((string)result["torrent_category"]);
|
||||
|
||||
release.Title = (string)result["torrent_title"];
|
||||
release.Description = release.Title;
|
||||
release.Seeders = (int)result["seeds"];
|
||||
release.Peers = (int)result["leeches"] + release.Seeders;
|
||||
release.Size = (long)result["size"];
|
||||
|
||||
// "Apr 2, 2015", "Apr 12, 2015" (note the spacing)
|
||||
// some are unix timestamps, some are not.. :/
|
||||
var dateString = string.Join(" ", ((string)result["upload_date"]).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
|
||||
float dateVal;
|
||||
if (ParseUtil.TryCoerceFloat(dateString, out dateVal))
|
||||
release.PublishDate = DateTimeUtil.UnixTimestampToDateTime(dateVal);
|
||||
else
|
||||
release.PublishDate = DateTime.ParseExact(dateString, "MMM d, yyyy", CultureInfo.InvariantCulture);
|
||||
|
||||
release.Guid = new Uri((string)result["page"]);
|
||||
release.Comments = release.Guid;
|
||||
|
||||
release.InfoHash = (string)result["torrent_hash"];
|
||||
release.MagnetUri = new Uri((string)result["magnet_uri"]);
|
||||
release.Link = new Uri(string.Format(DownloadUrl, release.InfoHash));
|
||||
|
||||
releases.Add(release);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(results.Content, ex);
|
||||
}
|
||||
|
||||
return releases;
|
||||
}
|
||||
|
||||
public override Task<byte[]> Download(Uri link)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
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.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
using System.Collections.Specialized;
|
||||
using Jackett.Models.IndexerConfig.Bespoke;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
public class Strike : BaseIndexer, IIndexer
|
||||
{
|
||||
readonly static string defaultSiteLink = "https://getstrike.net/";
|
||||
|
||||
private Uri BaseUri
|
||||
{
|
||||
get { return new Uri(configData.Url.Value); }
|
||||
set { configData.Url.Value = value.ToString(); }
|
||||
}
|
||||
|
||||
private string SearchUrl { get { return BaseUri + "api/v2/torrents/search/?phrase={0}"; } }
|
||||
private string DownloadUrl { get { return BaseUri + "torrents/api/download/{0}.torrent"; } }
|
||||
|
||||
new ConfigurationDataStrike configData
|
||||
{
|
||||
get { return (ConfigurationDataStrike)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
|
||||
public Strike(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
|
||||
: base(name: "Strike",
|
||||
description: "Torrent search engine",
|
||||
link: defaultSiteLink,
|
||||
caps: new TorznabCapabilities(),
|
||||
manager: i,
|
||||
client: wc,
|
||||
logger: l,
|
||||
p: ps,
|
||||
configData: new ConfigurationDataStrike(defaultSiteLink))
|
||||
{
|
||||
AddCategoryMapping("Anime", TorznabCatType.TVAnime);
|
||||
AddCategoryMapping("Applications", TorznabCatType.PC);
|
||||
AddCategoryMapping("Books", TorznabCatType.Books);
|
||||
AddCategoryMapping("Games", TorznabCatType.PCGames);
|
||||
AddCategoryMapping("Movies", TorznabCatType.Movies);
|
||||
AddCategoryMapping("TV", TorznabCatType.TV);
|
||||
AddCategoryMapping("XXX", TorznabCatType.XXX);
|
||||
AddCategoryMapping("Music", TorznabCatType.Audio);
|
||||
|
||||
/*AddCategoryMapping("Movies:Highres Movies", TorznabCatType.MoviesHD);
|
||||
AddCategoryMapping("Movies:3D Movies", TorznabCatType.Movies3D);
|
||||
AddCategoryMapping("Books:Ebooks", TorznabCatType.BooksEbook);
|
||||
AddCategoryMapping("Books:Comics", TorznabCatType.BooksComics);
|
||||
AddCategoryMapping("Books:Audio Books", TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping("Games:XBOX360", TorznabCatType.ConsoleXbox360);
|
||||
AddCategoryMapping("Games:Wii", TorznabCatType.ConsoleWii);
|
||||
AddCategoryMapping("Games:PSP", TorznabCatType.ConsolePSP);
|
||||
AddCategoryMapping("Games:PS3", TorznabCatType.ConsolePS3);
|
||||
AddCategoryMapping("Games:PC", TorznabCatType.PCGames);
|
||||
AddCategoryMapping("Games:Android", TorznabCatType.PCPhoneAndroid);
|
||||
AddCategoryMapping("Music:Mp3", TorznabCatType.AudioMP3);*/
|
||||
}
|
||||
|
||||
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
var releases = await PerformQuery(new TorznabQuery());
|
||||
|
||||
await ConfigureIfOK(string.Empty, releases.Count() > 0, () =>
|
||||
{
|
||||
throw new Exception("Could not find releases from this URL");
|
||||
});
|
||||
|
||||
return IndexerConfigurationStatus.Completed;
|
||||
}
|
||||
|
||||
// Override to load legacy config format
|
||||
public override void LoadFromSavedConfiguration(JToken jsonConfig)
|
||||
{
|
||||
if (jsonConfig is JObject)
|
||||
{
|
||||
BaseUri = new Uri(jsonConfig.Value<string>("base_url"));
|
||||
SaveConfig();
|
||||
IsConfigured = true;
|
||||
return;
|
||||
}
|
||||
|
||||
base.LoadFromSavedConfiguration(jsonConfig);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
List<ReleaseInfo> releases = new List<ReleaseInfo>();
|
||||
var queryString = query.GetQueryString();
|
||||
var searchTerm = string.IsNullOrEmpty(queryString) ? DateTime.Now.Year.ToString() : queryString;
|
||||
var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchTerm));
|
||||
|
||||
var trackerCategories = MapTorznabCapsToTrackers(query, mapChildrenCatsToParent: true);
|
||||
|
||||
// This tracker can only search one cat at a time, otherwise search all and filter results
|
||||
if (trackerCategories.Count == 1)
|
||||
{
|
||||
episodeSearchUrl += "&category=" + trackerCategories[0];
|
||||
}
|
||||
|
||||
var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl, string.Empty);
|
||||
try
|
||||
{
|
||||
var jResults = JObject.Parse(results.Content);
|
||||
foreach (JObject result in (JArray)jResults["torrents"])
|
||||
{
|
||||
var release = new ReleaseInfo();
|
||||
|
||||
release.MinimumRatio = 1;
|
||||
release.MinimumSeedTime = 172800;
|
||||
|
||||
if (trackerCategories.Count > 0 && !trackerCategories.Contains((string)result["torrent_category"]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
release.Category = MapTrackerCatToNewznab((string)result["torrent_category"]);
|
||||
|
||||
release.Title = (string)result["torrent_title"];
|
||||
release.Description = release.Title;
|
||||
release.Seeders = (int)result["seeds"];
|
||||
release.Peers = (int)result["leeches"] + release.Seeders;
|
||||
release.Size = (long)result["size"];
|
||||
|
||||
// "Apr 2, 2015", "Apr 12, 2015" (note the spacing)
|
||||
// some are unix timestamps, some are not.. :/
|
||||
var dateString = string.Join(" ", ((string)result["upload_date"]).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
|
||||
float dateVal;
|
||||
if (ParseUtil.TryCoerceFloat(dateString, out dateVal))
|
||||
release.PublishDate = DateTimeUtil.UnixTimestampToDateTime(dateVal);
|
||||
else
|
||||
release.PublishDate = DateTime.ParseExact(dateString, "MMM d, yyyy", CultureInfo.InvariantCulture);
|
||||
|
||||
release.Guid = new Uri((string)result["page"]);
|
||||
release.Comments = release.Guid;
|
||||
|
||||
release.InfoHash = (string)result["torrent_hash"];
|
||||
release.MagnetUri = new Uri((string)result["magnet_uri"]);
|
||||
release.Link = new Uri(string.Format(DownloadUrl, release.InfoHash));
|
||||
|
||||
releases.Add(release);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(results.Content, ex);
|
||||
}
|
||||
|
||||
return releases;
|
||||
}
|
||||
|
||||
public override Task<byte[]> Download(Uri link)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,168 +1,169 @@
|
||||
using CsQuery;
|
||||
using Jackett.Models;
|
||||
using Jackett.Services;
|
||||
using Jackett.Utils;
|
||||
using Jackett.Utils.Clients;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
public class NCore : BaseIndexer, IIndexer
|
||||
{
|
||||
private string LoginUrl { get { return SiteLink + "login.php"; } }
|
||||
private string SearchUrl { get { return SiteLink + "torrents.php"; } }
|
||||
|
||||
new ConfigurationDataNCore configData
|
||||
{
|
||||
get { return (ConfigurationDataNCore)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public NCore(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
|
||||
: base(name: "nCore",
|
||||
description: "A Hungarian private torrent site.",
|
||||
link: "https://ncore.cc/",
|
||||
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: wc,
|
||||
logger: l,
|
||||
p: ps,
|
||||
configData: new ConfigurationDataNCore())
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
|
||||
if (configData.Hungarian.Value == false && configData.English.Value == false)
|
||||
throw new ExceptionWithConfigData("Please select atleast one language.", configData);
|
||||
|
||||
var loginPage = await RequestStringWithCookies(LoginUrl, string.Empty);
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "nev", configData.Username.Value },
|
||||
{ "pass", configData.Password.Value },
|
||||
{ "ne_leptessen_ki", "1"},
|
||||
{ "set_lang", "en" },
|
||||
{ "submitted", "1" },
|
||||
{ "submit", "Access!" }
|
||||
};
|
||||
|
||||
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, referer: SiteLink);
|
||||
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("profile.php"), () =>
|
||||
{
|
||||
CQ dom = result.Content;
|
||||
var messageEl = dom["#hibauzenet table tbody tr"];
|
||||
var msgContainer = messageEl.Get(0).ChildElements.ElementAt(1);
|
||||
var errorMessage = msgContainer != null ? msgContainer.InnerText : "Error while trying to login.";
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
|
||||
return IndexerConfigurationStatus.RequiresTesting;
|
||||
}
|
||||
|
||||
List<KeyValuePair<string, string>> CreateKeyValueList(params string[][] keyValues)
|
||||
{
|
||||
var list = new List<KeyValuePair<string, string>>();
|
||||
foreach (var d in keyValues)
|
||||
{
|
||||
list.Add(new KeyValuePair<string, string>(d[0], d[1]));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private IEnumerable<KeyValuePair<string, string>> GetSearchFormData(string searchString)
|
||||
{
|
||||
const string searchTypeKey = "kivalasztott_tipus[]";
|
||||
var baseList = CreateKeyValueList(
|
||||
new[] { "nyit_sorozat_resz", "true" },
|
||||
new[] { "miben", "name" },
|
||||
new[] { "tipus", "kivalasztottak_kozott" },
|
||||
new[] { "submit.x", "1" },
|
||||
new[] { "submit.y", "1" },
|
||||
new[] { "submit", "Ok" },
|
||||
new[] { "mire", searchString }
|
||||
);
|
||||
|
||||
if (configData.English.Value)
|
||||
{
|
||||
baseList.AddRange(CreateKeyValueList(
|
||||
new[] { searchTypeKey, "xvidser" },
|
||||
new[] { searchTypeKey, "dvdser" },
|
||||
new[] { searchTypeKey, "hdser" }
|
||||
));
|
||||
}
|
||||
|
||||
if (configData.Hungarian.Value)
|
||||
{
|
||||
baseList.AddRange(CreateKeyValueList(
|
||||
new[] { searchTypeKey, "xvidser_hun" },
|
||||
new[] { searchTypeKey, "dvdser_hun" },
|
||||
new[] { searchTypeKey, "hdser_hun" }
|
||||
));
|
||||
}
|
||||
return baseList;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
var results = await PostDataWithCookiesAndRetry(SearchUrl, GetSearchFormData(query.GetQueryString()));
|
||||
|
||||
try
|
||||
{
|
||||
CQ dom = results.Content;
|
||||
|
||||
ReleaseInfo release;
|
||||
var rows = dom[".box_torrent_all"].Find(".box_torrent");
|
||||
|
||||
foreach (var row in rows)
|
||||
{
|
||||
CQ qRow = row.Cq();
|
||||
|
||||
release = new ReleaseInfo();
|
||||
var torrentTxt = qRow.Find(".torrent_txt").Find("a").Get(0);
|
||||
if (torrentTxt == null) continue;
|
||||
release.Title = torrentTxt.GetAttribute("title");
|
||||
release.Description = release.Title;
|
||||
release.MinimumRatio = 1;
|
||||
release.MinimumSeedTime = 172800;
|
||||
|
||||
string downloadLink = SiteLink + torrentTxt.GetAttribute("href");
|
||||
string downloadId = downloadLink.Substring(downloadLink.IndexOf("&id=") + 4);
|
||||
|
||||
release.Link = new Uri(SiteLink.ToString() + "torrents.php?action=download&id=" + downloadId);
|
||||
release.Comments = new Uri(SiteLink.ToString() + "torrents.php?action=details&id=" + downloadId);
|
||||
release.Guid = new Uri(release.Comments.ToString() + "#comments"); ;
|
||||
release.Seeders = ParseUtil.CoerceInt(qRow.Find(".box_s2").Find("a").First().Text());
|
||||
release.Peers = ParseUtil.CoerceInt(qRow.Find(".box_l2").Find("a").First().Text()) + release.Seeders;
|
||||
release.PublishDate = DateTime.Parse(qRow.Find(".box_feltoltve2").Get(0).InnerHTML.Replace("<br />", " "), CultureInfo.InvariantCulture);
|
||||
string[] sizeSplit = qRow.Find(".box_meret2").Get(0).InnerText.Split(' ');
|
||||
release.Size = ReleaseInfo.GetBytes(sizeSplit[1].ToLower(), ParseUtil.CoerceFloat(sizeSplit[0]));
|
||||
|
||||
releases.Add(release);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(results.Content, ex);
|
||||
}
|
||||
|
||||
|
||||
return releases.ToArray();
|
||||
}
|
||||
|
||||
}
|
||||
using CsQuery;
|
||||
using Jackett.Models;
|
||||
using Jackett.Services;
|
||||
using Jackett.Utils;
|
||||
using Jackett.Utils.Clients;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
using Jackett.Models.IndexerConfig.Bespoke;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
public class NCore : BaseIndexer, IIndexer
|
||||
{
|
||||
private string LoginUrl { get { return SiteLink + "login.php"; } }
|
||||
private string SearchUrl { get { return SiteLink + "torrents.php"; } }
|
||||
|
||||
new ConfigurationDataNCore configData
|
||||
{
|
||||
get { return (ConfigurationDataNCore)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public NCore(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
|
||||
: base(name: "nCore",
|
||||
description: "A Hungarian private torrent site.",
|
||||
link: "https://ncore.cc/",
|
||||
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
client: wc,
|
||||
logger: l,
|
||||
p: ps,
|
||||
configData: new ConfigurationDataNCore())
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
|
||||
if (configData.Hungarian.Value == false && configData.English.Value == false)
|
||||
throw new ExceptionWithConfigData("Please select atleast one language.", configData);
|
||||
|
||||
var loginPage = await RequestStringWithCookies(LoginUrl, string.Empty);
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "nev", configData.Username.Value },
|
||||
{ "pass", configData.Password.Value },
|
||||
{ "ne_leptessen_ki", "1"},
|
||||
{ "set_lang", "en" },
|
||||
{ "submitted", "1" },
|
||||
{ "submit", "Access!" }
|
||||
};
|
||||
|
||||
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, referer: SiteLink);
|
||||
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("profile.php"), () =>
|
||||
{
|
||||
CQ dom = result.Content;
|
||||
var messageEl = dom["#hibauzenet table tbody tr"];
|
||||
var msgContainer = messageEl.Get(0).ChildElements.ElementAt(1);
|
||||
var errorMessage = msgContainer != null ? msgContainer.InnerText : "Error while trying to login.";
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
|
||||
return IndexerConfigurationStatus.RequiresTesting;
|
||||
}
|
||||
|
||||
List<KeyValuePair<string, string>> CreateKeyValueList(params string[][] keyValues)
|
||||
{
|
||||
var list = new List<KeyValuePair<string, string>>();
|
||||
foreach (var d in keyValues)
|
||||
{
|
||||
list.Add(new KeyValuePair<string, string>(d[0], d[1]));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private IEnumerable<KeyValuePair<string, string>> GetSearchFormData(string searchString)
|
||||
{
|
||||
const string searchTypeKey = "kivalasztott_tipus[]";
|
||||
var baseList = CreateKeyValueList(
|
||||
new[] { "nyit_sorozat_resz", "true" },
|
||||
new[] { "miben", "name" },
|
||||
new[] { "tipus", "kivalasztottak_kozott" },
|
||||
new[] { "submit.x", "1" },
|
||||
new[] { "submit.y", "1" },
|
||||
new[] { "submit", "Ok" },
|
||||
new[] { "mire", searchString }
|
||||
);
|
||||
|
||||
if (configData.English.Value)
|
||||
{
|
||||
baseList.AddRange(CreateKeyValueList(
|
||||
new[] { searchTypeKey, "xvidser" },
|
||||
new[] { searchTypeKey, "dvdser" },
|
||||
new[] { searchTypeKey, "hdser" }
|
||||
));
|
||||
}
|
||||
|
||||
if (configData.Hungarian.Value)
|
||||
{
|
||||
baseList.AddRange(CreateKeyValueList(
|
||||
new[] { searchTypeKey, "xvidser_hun" },
|
||||
new[] { searchTypeKey, "dvdser_hun" },
|
||||
new[] { searchTypeKey, "hdser_hun" }
|
||||
));
|
||||
}
|
||||
return baseList;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
var results = await PostDataWithCookiesAndRetry(SearchUrl, GetSearchFormData(query.GetQueryString()));
|
||||
|
||||
try
|
||||
{
|
||||
CQ dom = results.Content;
|
||||
|
||||
ReleaseInfo release;
|
||||
var rows = dom[".box_torrent_all"].Find(".box_torrent");
|
||||
|
||||
foreach (var row in rows)
|
||||
{
|
||||
CQ qRow = row.Cq();
|
||||
|
||||
release = new ReleaseInfo();
|
||||
var torrentTxt = qRow.Find(".torrent_txt").Find("a").Get(0);
|
||||
if (torrentTxt == null) continue;
|
||||
release.Title = torrentTxt.GetAttribute("title");
|
||||
release.Description = release.Title;
|
||||
release.MinimumRatio = 1;
|
||||
release.MinimumSeedTime = 172800;
|
||||
|
||||
string downloadLink = SiteLink + torrentTxt.GetAttribute("href");
|
||||
string downloadId = downloadLink.Substring(downloadLink.IndexOf("&id=") + 4);
|
||||
|
||||
release.Link = new Uri(SiteLink.ToString() + "torrents.php?action=download&id=" + downloadId);
|
||||
release.Comments = new Uri(SiteLink.ToString() + "torrents.php?action=details&id=" + downloadId);
|
||||
release.Guid = new Uri(release.Comments.ToString() + "#comments"); ;
|
||||
release.Seeders = ParseUtil.CoerceInt(qRow.Find(".box_s2").Find("a").First().Text());
|
||||
release.Peers = ParseUtil.CoerceInt(qRow.Find(".box_l2").Find("a").First().Text()) + release.Seeders;
|
||||
release.PublishDate = DateTime.Parse(qRow.Find(".box_feltoltve2").Get(0).InnerHTML.Replace("<br />", " "), CultureInfo.InvariantCulture);
|
||||
string[] sizeSplit = qRow.Find(".box_meret2").Get(0).InnerText.Split(' ');
|
||||
release.Size = ReleaseInfo.GetBytes(sizeSplit[1].ToLower(), ParseUtil.CoerceFloat(sizeSplit[0]));
|
||||
|
||||
releases.Add(release);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(results.Content, ex);
|
||||
}
|
||||
|
||||
|
||||
return releases.ToArray();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -185,6 +185,7 @@
|
||||
<Compile Include="Indexers\BitMeTV.cs" />
|
||||
<Compile Include="Indexers\Demonoid.cs" />
|
||||
<Compile Include="Indexers\FrenchTorrentDb.cs" />
|
||||
<Compile Include="Indexers\BroadcastTheNet.cs" />
|
||||
<Compile Include="Indexers\Shazbat.cs" />
|
||||
<Compile Include="Indexers\NxtGn.cs" />
|
||||
<Compile Include="Indexers\Freshon.cs" />
|
||||
@@ -195,6 +196,7 @@
|
||||
<Compile Include="Indexers\FileList.cs" />
|
||||
<Compile Include="Indexers\Abstract\AvistazTracker.cs" />
|
||||
<Compile Include="Indexers\AnimeTorrents.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataAPIKey.cs" />
|
||||
<Compile Include="Models\ManualSearchResult.cs" />
|
||||
<Compile Include="Indexers\Rarbg.cs" />
|
||||
<Compile Include="Indexers\TVChaosUK.cs" />
|
||||
@@ -222,14 +224,14 @@
|
||||
<Compile Include="Models\CategoryMapping.cs" />
|
||||
<Compile Include="Models\AdminSearch.cs" />
|
||||
<Compile Include="Models\IndexerConfigurationStatus.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataFileList.cs" />
|
||||
<Compile Include="Models\IndexerConfig\Bespoke\ConfigurationDataFileList.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataBasicLoginWithRSS.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataRecaptchaLogin.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataLoginTokin.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataNCore.cs" />
|
||||
<Compile Include="Models\IndexerConfig\Bespoke\ConfigurationDataNCore.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataCaptchaLogin.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataAnimeBytes.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataStrike.cs" />
|
||||
<Compile Include="Models\IndexerConfig\Bespoke\ConfigurationDataAnimeBytes.cs" />
|
||||
<Compile Include="Models\IndexerConfig\Bespoke\ConfigurationDataStrike.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataUrl.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ISerializableConfig.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataPinNumber.cs" />
|
||||
@@ -265,7 +267,7 @@
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationData.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataBasicLogin.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataCookie.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataRuTor.cs" />
|
||||
<Compile Include="Models\IndexerConfig\Bespoke\ConfigurationDataRuTor.cs" />
|
||||
<Compile Include="Controllers\AdminController.cs" />
|
||||
<Compile Include="CookieContainerExtensions.cs" />
|
||||
<Compile Include="Utils\Clients\WebRequest.cs" />
|
||||
@@ -429,6 +431,9 @@
|
||||
<Content Include="Content\logos\beyondhd.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\logos\broadcastthenet.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\logos\demonoid.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
@@ -1,22 +1,22 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.Models.IndexerConfig
|
||||
{
|
||||
class ConfigurationDataAnimeBytes : ConfigurationDataBasicLogin
|
||||
{
|
||||
public BoolItem IncludeRaw { get; private set; }
|
||||
public DisplayItem DateWarning { get; private set; }
|
||||
|
||||
public ConfigurationDataAnimeBytes()
|
||||
: base()
|
||||
{
|
||||
IncludeRaw = new BoolItem() { Name = "IncludeRaw", Value = false };
|
||||
DateWarning = new DisplayItem("This tracker does not supply upload dates so they are based off year of release.") { Name = "DateWarning" };
|
||||
}
|
||||
}
|
||||
}
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.Models.IndexerConfig.Bespoke
|
||||
{
|
||||
class ConfigurationDataAnimeBytes : ConfigurationDataBasicLogin
|
||||
{
|
||||
public BoolItem IncludeRaw { get; private set; }
|
||||
public DisplayItem DateWarning { get; private set; }
|
||||
|
||||
public ConfigurationDataAnimeBytes()
|
||||
: base()
|
||||
{
|
||||
IncludeRaw = new BoolItem() { Name = "IncludeRaw", Value = false };
|
||||
DateWarning = new DisplayItem("This tracker does not supply upload dates so they are based off year of release.") { Name = "DateWarning" };
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,22 +1,22 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.Models.IndexerConfig
|
||||
{
|
||||
class ConfigurationDataFileList : ConfigurationDataBasicLogin
|
||||
{
|
||||
public BoolItem IncludeRomanianReleases { get; private set; }
|
||||
public DisplayItem CatWarning { get; private set; }
|
||||
|
||||
public ConfigurationDataFileList()
|
||||
: base()
|
||||
{
|
||||
IncludeRomanianReleases = new BoolItem() { Name = "IncludeRomanianReleases", Value = false };
|
||||
CatWarning = new DisplayItem("When mapping TV ensure you add category 5000 in addition to 5030,5040.") { Name = "CatWarning" };
|
||||
}
|
||||
}
|
||||
}
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.Models.IndexerConfig.Bespoke
|
||||
{
|
||||
class ConfigurationDataFileList : ConfigurationDataBasicLogin
|
||||
{
|
||||
public BoolItem IncludeRomanianReleases { get; private set; }
|
||||
public DisplayItem CatWarning { get; private set; }
|
||||
|
||||
public ConfigurationDataFileList()
|
||||
: base()
|
||||
{
|
||||
IncludeRomanianReleases = new BoolItem() { Name = "IncludeRomanianReleases", Value = false };
|
||||
CatWarning = new DisplayItem("When mapping TV ensure you add category 5000 in addition to 5030,5040.") { Name = "CatWarning" };
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,62 +1,62 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.Models.IndexerConfig
|
||||
{
|
||||
public class ConfigurationDataNCore : ConfigurationData
|
||||
{
|
||||
public StringItem Username { get; private set; }
|
||||
public StringItem Password { get; private set; }
|
||||
public BoolItem Hungarian { get; set; }
|
||||
public BoolItem English { get; set; }
|
||||
|
||||
public ConfigurationDataNCore()
|
||||
{
|
||||
Username = new StringItem { Name = "Username", Value = "" };
|
||||
Password = new StringItem { Name = "Password", Value = "" };
|
||||
Hungarian = new BoolItem { Name = "Hungarian", Value = true };
|
||||
English = new BoolItem { Name = "English", Value = true };
|
||||
}
|
||||
|
||||
public ConfigurationDataNCore(JToken json)
|
||||
{
|
||||
ConfigurationDataNCore configData = new ConfigurationDataNCore();
|
||||
|
||||
dynamic configArray = JsonConvert.DeserializeObject(json.ToString());
|
||||
foreach (var config in configArray)
|
||||
{
|
||||
string propertyName = UppercaseFirst((string)config.id);
|
||||
switch (propertyName)
|
||||
{
|
||||
case "Username":
|
||||
Username = new StringItem { Name = propertyName, Value = config.value };
|
||||
break;
|
||||
case "Password":
|
||||
Password = new StringItem { Name = propertyName, Value = config.value };
|
||||
break;
|
||||
case "Hungarian":
|
||||
Hungarian = new BoolItem { Name = propertyName, Value = config.value };
|
||||
break;
|
||||
case "English":
|
||||
English = new BoolItem { Name = propertyName, Value = config.value };
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static string UppercaseFirst(string s)
|
||||
{
|
||||
if (string.IsNullOrEmpty(s))
|
||||
return string.Empty;
|
||||
return char.ToUpper(s[0]) + s.Substring(1);
|
||||
}
|
||||
}
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.Models.IndexerConfig.Bespoke
|
||||
{
|
||||
public class ConfigurationDataNCore : ConfigurationData
|
||||
{
|
||||
public StringItem Username { get; private set; }
|
||||
public StringItem Password { get; private set; }
|
||||
public BoolItem Hungarian { get; set; }
|
||||
public BoolItem English { get; set; }
|
||||
|
||||
public ConfigurationDataNCore()
|
||||
{
|
||||
Username = new StringItem { Name = "Username", Value = "" };
|
||||
Password = new StringItem { Name = "Password", Value = "" };
|
||||
Hungarian = new BoolItem { Name = "Hungarian", Value = true };
|
||||
English = new BoolItem { Name = "English", Value = true };
|
||||
}
|
||||
|
||||
public ConfigurationDataNCore(JToken json)
|
||||
{
|
||||
ConfigurationDataNCore configData = new ConfigurationDataNCore();
|
||||
|
||||
dynamic configArray = JsonConvert.DeserializeObject(json.ToString());
|
||||
foreach (var config in configArray)
|
||||
{
|
||||
string propertyName = UppercaseFirst((string)config.id);
|
||||
switch (propertyName)
|
||||
{
|
||||
case "Username":
|
||||
Username = new StringItem { Name = propertyName, Value = config.value };
|
||||
break;
|
||||
case "Password":
|
||||
Password = new StringItem { Name = propertyName, Value = config.value };
|
||||
break;
|
||||
case "Hungarian":
|
||||
Hungarian = new BoolItem { Name = propertyName, Value = config.value };
|
||||
break;
|
||||
case "English":
|
||||
English = new BoolItem { Name = propertyName, Value = config.value };
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static string UppercaseFirst(string s)
|
||||
{
|
||||
if (string.IsNullOrEmpty(s))
|
||||
return string.Empty;
|
||||
return char.ToUpper(s[0]) + s.Substring(1);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,27 +1,27 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.Models.IndexerConfig
|
||||
{
|
||||
public class ConfigurationDataRuTor : ConfigurationData
|
||||
{
|
||||
[JsonProperty]
|
||||
public StringItem Url { get; private set; }
|
||||
[JsonProperty]
|
||||
public BoolItem StripRussian { get; private set; }
|
||||
|
||||
public ConfigurationDataRuTor()
|
||||
{
|
||||
}
|
||||
|
||||
public ConfigurationDataRuTor(string defaultUrl)
|
||||
{
|
||||
Url = new StringItem { Name = "Url", Value = defaultUrl };
|
||||
StripRussian = new BoolItem() { Name = "StripRusNamePrefix", Value = true };
|
||||
}
|
||||
}
|
||||
}
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.Models.IndexerConfig.Bespoke
|
||||
{
|
||||
public class ConfigurationDataRuTor : ConfigurationData
|
||||
{
|
||||
[JsonProperty]
|
||||
public StringItem Url { get; private set; }
|
||||
[JsonProperty]
|
||||
public BoolItem StripRussian { get; private set; }
|
||||
|
||||
public ConfigurationDataRuTor()
|
||||
{
|
||||
}
|
||||
|
||||
public ConfigurationDataRuTor(string defaultUrl)
|
||||
{
|
||||
Url = new StringItem { Name = "Url", Value = defaultUrl };
|
||||
StripRussian = new BoolItem() { Name = "StripRusNamePrefix", Value = true };
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,18 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.Models.IndexerConfig
|
||||
{
|
||||
public class ConfigurationDataStrike : ConfigurationDataUrl
|
||||
{
|
||||
public DisplayItem StrikeWarning { get; private set; }
|
||||
|
||||
public ConfigurationDataStrike(string url) : base(url)
|
||||
{
|
||||
StrikeWarning = new DisplayItem("This indexer does not support RSS Sync, only Search") { Name = "Warning" };
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.Models.IndexerConfig.Bespoke
|
||||
{
|
||||
public class ConfigurationDataStrike : ConfigurationDataUrl
|
||||
{
|
||||
public DisplayItem StrikeWarning { get; private set; }
|
||||
|
||||
public ConfigurationDataStrike(string url) : base(url)
|
||||
{
|
||||
StrikeWarning = new DisplayItem("This indexer does not support RSS Sync, only Search") { Name = "Warning" };
|
||||
}
|
||||
}
|
||||
}
|
18
src/Jackett/Models/IndexerConfig/ConfigurationDataAPIKey.cs
Normal file
18
src/Jackett/Models/IndexerConfig/ConfigurationDataAPIKey.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.Models.IndexerConfig
|
||||
{
|
||||
public class ConfigurationDataAPIKey : ConfigurationData
|
||||
{
|
||||
public ConfigurationData.StringItem Key { get; private set; }
|
||||
|
||||
public ConfigurationDataAPIKey()
|
||||
{
|
||||
Key = new ConfigurationData.StringItem { Name = "APIKey", Value = string.Empty };
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user