mirror of
https://github.com/Jackett/Jackett
synced 2024-12-29 11:17:22 +00:00
* Replace Cardigann Anidex indexer for C# impelementation Add bypass for DDOS Guard * Improve error messages from type conversions * Add missing cookie check * Fix index out of range exception * Change error handling to only warn about DDoS bypass exceptions This is so that searches will still be attempted if there are issues with the DDoS protection (e.g. if it is removed). * Improve error handling and clean up code * pending changes
This commit is contained in:
parent
c12da520a4
commit
e2310ea70b
3 changed files with 427 additions and 215 deletions
|
@ -1,108 +0,0 @@
|
|||
---
|
||||
site: anidex
|
||||
name: Anidex
|
||||
description: "Anidex is a Public torrent tracker and indexer, primarily for English fansub groups of anime"
|
||||
language: en-us
|
||||
encoding: UTF-8
|
||||
type: public
|
||||
links:
|
||||
- https://anidex.info/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 1, cat: TV/Anime, desc: "Anime - Sub"}
|
||||
- {id: 2, cat: TV/Anime, desc: "Anime - Raw"}
|
||||
- {id: 3, cat: TV/Anime, desc: "Anime - Dub"}
|
||||
- {id: 4, cat: TV/Anime, desc: "LA - Sub"}
|
||||
- {id: 5, cat: TV/Anime, desc: "LA - Raw"}
|
||||
- {id: 6, cat: TV/Anime, desc: "Light Novel"}
|
||||
- {id: 7, cat: TV/Anime, desc: "Manga - TLed"}
|
||||
- {id: 8, cat: TV/Anime, desc: "Manga - Raw"}
|
||||
- {id: 9, cat: TV/Anime, desc: "♫ - Lossy"}
|
||||
- {id: 10, cat: TV/Anime, desc: "♫ - Lossless"}
|
||||
- {id: 11, cat: TV/Anime, desc: "♫ - Video"}
|
||||
- {id: 12, cat: TV/Anime, desc: "Games"}
|
||||
- {id: 13, cat: TV/Anime, desc: "Applications"}
|
||||
- {id: 14, cat: TV/Anime, desc: "Pictures"}
|
||||
- {id: 15, cat: TV/Anime, desc: "Adult Video"}
|
||||
- {id: 16, cat: TV/Anime, desc: "Other"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
settings:
|
||||
- name: lang-id
|
||||
type: text
|
||||
label: Language ID
|
||||
- name: info
|
||||
type: info
|
||||
label: Language ID Note
|
||||
default: "You can filter your searches using any of the following language ID (comma delimited):<br>19 :Arabic<br>22 :Bengali<br>14 :Bulgarian<br>21 :Chinese (Simplified)<br>24 :Czech<br>20 :Danish<br>5 :Dutch<br>1 :English<br>11 :Finnish<br>10 :French<br>8 :German<br>13 :Greek<br>9 :Hungarian<br>27 :Indonesian<br>6 :Italian<br>2 :Japanese<br>28 :Korean<br>31 :Malaysian<br>25 :Mongolian<br>30 :Persian<br>3 :Polish<br>16 :Portuguese (Brazil)<br>17 :Portuguese (Portugal)<br>23 :Romanian<br>7 :Russian<br>4 :Serbo-Croatian<br>29 :Spanish (LATAM)<br>15 :Spanish (Spain)<br>18 :Swedish<br>26 :Turkish<br>12 :Vietnamese"
|
||||
- name: sort
|
||||
type: select
|
||||
label: Sort requested from site
|
||||
default: "upload_timestamp"
|
||||
options:
|
||||
"upload_timestamp": "created"
|
||||
"seeders": "seeders"
|
||||
"size": "size"
|
||||
"filename": "title"
|
||||
- name: type
|
||||
type: select
|
||||
label: Order requested from site
|
||||
default: "desc"
|
||||
options:
|
||||
"desc": "desc"
|
||||
"asc": "asc"
|
||||
|
||||
search:
|
||||
paths:
|
||||
# https://anidex.info/?page=search&id=1,2,3&lang_id=5,1,10&group_id=0&q=rinshi
|
||||
- path: "?page=search&id={{ if .Categories }}{{ range .Categories }},{{.}}{{end}}{{else}}0{{end}}{{ if .Config.lang-id }}&lang_id={{ .Config.lang-id }}{{else}}{{end}}&group_id=0&q={{ if .Keywords }}{{ .Keywords }}{{else}}{{end}}&s={{ .Config.sort }}&o={{ .Config.type }}"
|
||||
|
||||
rows:
|
||||
selector: div.table-responsive > table > tbody > tr
|
||||
|
||||
fields:
|
||||
category:
|
||||
selector: a[href^="/?id="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: id
|
||||
title:
|
||||
selector: td:nth-child(3) > a.torrent > span.span-1440
|
||||
filters:
|
||||
- name: re_replace # remove anidb id from return string
|
||||
args: ["(\\[[A-Z0-9]*\\])\\.", "."]
|
||||
details:
|
||||
selector: td:nth-child(3) > a.torrent
|
||||
attribute: href
|
||||
download:
|
||||
selector: td:nth-child(5) > a
|
||||
attribute: href
|
||||
magnet:
|
||||
selector: a[href^="magnet:?"]
|
||||
attribute: href
|
||||
size:
|
||||
selector: td:nth-child(7)
|
||||
date:
|
||||
selector: td:nth-child(8)
|
||||
attribute: title
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["UTC", "+00:00"]
|
||||
- name: dateparse
|
||||
args: "2006-01-02 15:04:05 -07:00"
|
||||
seeders:
|
||||
selector: td:nth-child(9)
|
||||
leechers:
|
||||
selector: td:nth-child(10)
|
||||
grabs:
|
||||
selector: td:nth-child(11)
|
||||
downloadvolumefactor:
|
||||
text: 0
|
||||
uploadvolumefactor:
|
||||
text: 1
|
||||
# engine n/a
|
319
src/Jackett.Common/Indexers/Anidex.cs
Normal file
319
src/Jackett.Common/Indexers/Anidex.cs
Normal file
|
@ -0,0 +1,319 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using AngleSharp.Dom;
|
||||
using AngleSharp.Html.Parser;
|
||||
using Jackett.Common.Models;
|
||||
using Jackett.Common.Models.IndexerConfig;
|
||||
using Jackett.Common.Services.Interfaces;
|
||||
using Jackett.Common.Utils;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
using static Jackett.Common.Models.IndexerConfig.ConfigurationData;
|
||||
|
||||
namespace Jackett.Common.Indexers
|
||||
{
|
||||
public class Anidex : BaseWebIndexer
|
||||
{
|
||||
public Anidex(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, IProtectionService ps)
|
||||
: base(name: "Anidex",
|
||||
description: "Anidex is a Public torrent tracker and indexer, primarily for English fansub groups of anime",
|
||||
link: "https://anidex.info/",
|
||||
caps: new TorznabCapabilities(),
|
||||
configService: configService,
|
||||
client: wc,
|
||||
logger: l,
|
||||
p: ps,
|
||||
configData: new ConfigurationData())
|
||||
{
|
||||
Encoding = Encoding.UTF8;
|
||||
Language = "en-us";
|
||||
Type = "public";
|
||||
|
||||
// Configure the category mappings
|
||||
AddCategoryMapping(1, TorznabCatType.TVAnime, "Anime - Sub");
|
||||
AddCategoryMapping(2, TorznabCatType.TVAnime, "Anime - Raw");
|
||||
AddCategoryMapping(3, TorznabCatType.TVAnime, "Anime - Dub");
|
||||
AddCategoryMapping(4, TorznabCatType.TVAnime, "LA - Sub");
|
||||
AddCategoryMapping(5, TorznabCatType.TVAnime, "LA - Raw");
|
||||
AddCategoryMapping(6, TorznabCatType.TVAnime, "Light Novel");
|
||||
AddCategoryMapping(7, TorznabCatType.TVAnime, "Manga - TLed");
|
||||
AddCategoryMapping(8, TorznabCatType.TVAnime, "Manga - Raw");
|
||||
AddCategoryMapping(9, TorznabCatType.TVAnime, "♫ - Lossy");
|
||||
AddCategoryMapping(10, TorznabCatType.TVAnime, "♫ - Lossless");
|
||||
AddCategoryMapping(11, TorznabCatType.TVAnime, "♫ - Video");
|
||||
AddCategoryMapping(12, TorznabCatType.TVAnime, "Games");
|
||||
AddCategoryMapping(13, TorznabCatType.TVAnime, "Applications");
|
||||
AddCategoryMapping(14, TorznabCatType.TVAnime, "Pictures");
|
||||
AddCategoryMapping(15, TorznabCatType.TVAnime, "Adult Video");
|
||||
AddCategoryMapping(16, TorznabCatType.TVAnime, "Other");
|
||||
|
||||
// Configure the language select option
|
||||
var languageSelect = new SelectItem(new Dictionary<string, string>()
|
||||
{
|
||||
{"1", "English"},
|
||||
{"2", "Japanese"},
|
||||
{"3", "Polish"},
|
||||
{"4", "Serbo-Croatian" },
|
||||
{"5", "Dutch"},
|
||||
{"6", "Italian"},
|
||||
{"7", "Russian"},
|
||||
{"8", "German"},
|
||||
{"9", "Hungarian"},
|
||||
{"10", "French"},
|
||||
{"11", "Finnish"},
|
||||
{"12", "Vietnamese"},
|
||||
{"13", "Greek"},
|
||||
{"14", "Bulgarian"},
|
||||
{"15", "Spanish (Spain)" },
|
||||
{"16", "Portuguese (Brazil)" },
|
||||
{"17", "Portuguese (Portugal)" },
|
||||
{"18", "Swedish"},
|
||||
{"19", "Arabic"},
|
||||
{"20", "Danish"},
|
||||
{"21", "Chinese (Simplified)" },
|
||||
{"22", "Bengali"},
|
||||
{"23", "Romanian"},
|
||||
{"24", "Czech"},
|
||||
{"25", "Mongolian"},
|
||||
{"26", "Turkish"},
|
||||
{"27", "Indonesian"},
|
||||
{"28", "Korean"},
|
||||
{"29", "Spanish (LATAM)" },
|
||||
{"30", "Persian"},
|
||||
{"31", "Malaysian"}
|
||||
}) { Name = "Language", Value = "1" };
|
||||
configData.AddDynamic("languageid", languageSelect);
|
||||
|
||||
// Configure the sort selects
|
||||
var sortBySelect = new SelectItem(new Dictionary<string, string>()
|
||||
{
|
||||
{"upload_timestamp", "created"},
|
||||
{"seeders", "seeders"},
|
||||
{"size", "size"},
|
||||
{"filename", "title"}
|
||||
}) { Name = "Sort by", Value = "upload_timestamp" };
|
||||
configData.AddDynamic("sortrequestedfromsite", sortBySelect);
|
||||
|
||||
var orderSelect = new SelectItem(new Dictionary<string, string>()
|
||||
{
|
||||
{"desc", "Descending"},
|
||||
{"asc", "Ascending"}
|
||||
})
|
||||
{ Name = "Order", Value = "desc" };
|
||||
configData.AddDynamic("orderrequestedfromsite", orderSelect);
|
||||
}
|
||||
|
||||
private string GetSortBy => ((SelectItem)configData.GetDynamic("sortrequestedfromsite")).Value;
|
||||
|
||||
private string GetOrder => ((SelectItem)configData.GetDynamic("orderrequestedfromsite")).Value;
|
||||
|
||||
private Uri GetAbsoluteUrl(string relativeUrl) => new Uri(SiteLink + relativeUrl.TrimStart('/'));
|
||||
|
||||
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
LoadValuesFromJson(configJson);
|
||||
var releases = await PerformQuery(new TorznabQuery());
|
||||
|
||||
await ConfigureIfOK(string.Empty, releases.Any(), () =>
|
||||
throw new Exception("Could not find releases from this URL"));
|
||||
|
||||
return IndexerConfigurationStatus.Completed;
|
||||
}
|
||||
|
||||
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ConfigureDDoSGuardCookie();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Log(LogLevel.Warn, ex, $"Exception while configuring DDoS Guard cookie. Attempting search without. (Exception: {ex})");
|
||||
}
|
||||
|
||||
// Get specified categories. If none were specified, use all available.
|
||||
var searchCategories = MapTorznabCapsToTrackers(query);
|
||||
if (searchCategories.Count == 0)
|
||||
searchCategories = GetAllTrackerCategories();
|
||||
|
||||
// Prepare the search query
|
||||
var queryParameters = new NameValueCollection
|
||||
{
|
||||
{ "page", "search" },
|
||||
{ "id", string.Join(",", searchCategories) },
|
||||
{ "group", "0" }, // No group
|
||||
{ "q", query.SearchTerm ?? string.Empty },
|
||||
{ "s", GetSortBy },
|
||||
{ "o", GetOrder }
|
||||
};
|
||||
|
||||
// Make search request
|
||||
var searchUri = GetAbsoluteUrl("?" + queryParameters.GetQueryString());
|
||||
var response = await RequestStringWithCookiesAndRetry(searchUri.AbsoluteUri);
|
||||
|
||||
// Check for DDOS Guard or other error
|
||||
if (response.Status == System.Net.HttpStatusCode.Forbidden)
|
||||
throw new IOException("Anidex search was forbidden. This was likely caused by DDOS protection.");
|
||||
|
||||
if (response.Status != System.Net.HttpStatusCode.OK)
|
||||
throw new IOException($"Anidex search returned unexpected result. Expected 200 OK but got {response.Status.ToString()}.");
|
||||
|
||||
// Search seems to have been a success so parse it
|
||||
return ParseResult(response.Content);
|
||||
}
|
||||
|
||||
private IEnumerable<ReleaseInfo> ParseResult(string response)
|
||||
{
|
||||
const string rowSelector = "div#content table > tbody > tr";
|
||||
|
||||
try
|
||||
{
|
||||
var resultParser = new HtmlParser();
|
||||
var resultDocument = resultParser.ParseDocument(response);
|
||||
IEnumerable<IElement> rows = resultDocument.QuerySelectorAll(rowSelector);
|
||||
|
||||
var releases = new List<ReleaseInfo>();
|
||||
foreach (var r in rows)
|
||||
try
|
||||
{
|
||||
var release = new ReleaseInfo();
|
||||
|
||||
release.Category = ParseValueFromRow(r, nameof(release.Category), "td:nth-child(1) a", (e) => MapTrackerCatToNewznab(e.Attributes["href"].Value.Substring(5)));
|
||||
release.Title = ParseStringValueFromRow(r, nameof(release.Title), "td:nth-child(3) span");
|
||||
release.Link = ParseValueFromRow(r, nameof(release.Link), "a[href^=\"/dl/\"]", (e) => GetAbsoluteUrl(e.Attributes["href"].Value));
|
||||
release.MagnetUri = ParseValueFromRow(r, nameof(release.MagnetUri), "a[href^=\"magnet:?\"]", (e) => new Uri(e.Attributes["href"].Value));
|
||||
release.Size = ParseValueFromRow(r, nameof(release.Size), "td:nth-child(7)", (e) => ReleaseInfo.GetBytes(e.Text()));
|
||||
release.PublishDate = ParseValueFromRow(r, nameof(release.PublishDate), "td:nth-child(8)", (e) => DateTime.ParseExact(e.Attributes["title"].Value, "yyyy-MM-dd HH:mm:ss UTC", CultureInfo.InvariantCulture));
|
||||
release.Seeders = ParseIntValueFromRow(r, nameof(release.Seeders), "td:nth-child(9)");
|
||||
release.Peers = ParseIntValueFromRow(r, nameof(release.Peers), "td:nth-child(10)") + release.Seeders;
|
||||
release.Grabs = ParseIntValueFromRow(r, nameof(release.Grabs), "td:nth-child(11)");
|
||||
release.Comments = ParseValueFromRow(r, nameof(release.Comments), "td:nth-child(3) a", (e) => GetAbsoluteUrl(e.Attributes["href"].Value));
|
||||
release.Guid = release.Comments;
|
||||
release.MinimumRatio = 1;
|
||||
release.MinimumSeedTime = 172800; // 48 hours
|
||||
release.DownloadVolumeFactor = 0;
|
||||
release.UploadVolumeFactor = 1;
|
||||
|
||||
releases.Add(release);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error($"Anidex: Error parsing search result row '{r.ToHtmlPretty()}':\n\n{ex}");
|
||||
}
|
||||
|
||||
return releases;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new IOException($"Error parsing search result page: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ConfigureDDoSGuardCookie()
|
||||
{
|
||||
const string pathAndQueryBase64Encoded = "Lw=="; // "/"
|
||||
const string baseUriBase64Encoded = "aHR0cHM6Ly9hbmlkZXguaW5mbw=="; // "http://anidex.info"
|
||||
const string ddosPostUrl = "https://ddgu.ddos-guard.net/ddgu/";
|
||||
|
||||
try
|
||||
{
|
||||
// Check if the cookie already exists, if so exit without doing anything
|
||||
if (IsCookiePresent("__ddgu") && IsCookiePresent("__ddg1"))
|
||||
{
|
||||
logger.Debug("DDOS Guard cookies are already present. Skipping bypass.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Make a request to DDoS Guard to get the redirect URL
|
||||
var ddosPostData = new List<KeyValuePair<string, string>>
|
||||
{
|
||||
{ "u", pathAndQueryBase64Encoded },
|
||||
{ "h", baseUriBase64Encoded },
|
||||
{ "p", string.Empty }
|
||||
};
|
||||
|
||||
var result = await PostDataWithCookiesAndRetry(ddosPostUrl, ddosPostData);
|
||||
|
||||
if (!result.IsRedirect)
|
||||
// Success returns a redirect. For anything else, assume a failure.
|
||||
throw new IOException($"Unexpected result from DDOS Guard while attempting to bypass: {result.Content}");
|
||||
|
||||
// Call the redirect URL to retrieve the cookie
|
||||
result = await RequestStringWithCookiesAndRetry(result.RedirectingTo);
|
||||
if (!result.IsRedirect)
|
||||
// Success is another redirect. For anything else, assume a failure.
|
||||
throw new IOException($"Unexpected result when returning from DDOS Guard bypass: {result.Content}");
|
||||
|
||||
// If we got to this point, the bypass should have succeeded and we have stored the necessary cookies to access the site normally.
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new IOException($"Error while configuring DDoS Guard cookie: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsCookiePresent(string name)
|
||||
{
|
||||
var rawCookies = CookieHeader.Split(';');
|
||||
IDictionary<string, string> cookies = rawCookies
|
||||
.Where(e => e.Contains('='))
|
||||
.ToDictionary((e) => e.Split('=')[0].Trim(), (e) => e.Split('=')[1].Trim());
|
||||
|
||||
return cookies.ContainsKey(name);
|
||||
}
|
||||
|
||||
private static TResult ParseValueFromRow<TResult>(IElement row, string propertyName, string selector,
|
||||
Func<IElement, TResult> parseFunction)
|
||||
{
|
||||
try
|
||||
{
|
||||
var selectedElement = row.QuerySelector(selector);
|
||||
if (selectedElement == null)
|
||||
throw new IOException($"Unable to find '{selector}'.");
|
||||
|
||||
return parseFunction(selectedElement);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new IOException($"Error parsing for property '{propertyName}': {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private static string ParseStringValueFromRow(IElement row, string propertyName, string selector)
|
||||
{
|
||||
try
|
||||
{
|
||||
var selectedElement = row.QuerySelector(selector);
|
||||
if (selectedElement == null)
|
||||
throw new IOException($"Unable to find '{selector}'.");
|
||||
|
||||
return selectedElement.Text();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new IOException($"Error parsing for property '{propertyName}': {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private static int ParseIntValueFromRow(IElement row, string propertyName, string selector)
|
||||
{
|
||||
try
|
||||
{
|
||||
var text = ParseStringValueFromRow(row, propertyName, selector);
|
||||
if (!int.TryParse(text, out var value))
|
||||
throw new IOException($"Could not convert '{text}' to int.");
|
||||
return value;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new IOException($"Error parsing for property '{propertyName}': {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -267,49 +267,118 @@ namespace Jackett.Updater
|
|||
|
||||
// delete old files
|
||||
string[] oldFiles = new string[] {
|
||||
"appsettings.Development.json",
|
||||
"Autofac.Integration.WebApi.dll",
|
||||
"Content/congruent_outline.png",
|
||||
"Content/crissXcross.png",
|
||||
"Content/css/jquery.dataTables.css",
|
||||
"Content/css/jquery.dataTables_themeroller.css",
|
||||
"Definitions/tspate.yml",
|
||||
"Definitions/freakstrackingsystem.yml",
|
||||
"Definitions/rarbg.yml",
|
||||
"Definitions/t411.yml",
|
||||
"Definitions/hdbc.yml", // renamed to hdbitscom
|
||||
"Definitions/maniatorrent.yml",
|
||||
"Definitions/nyaa.yml",
|
||||
"Definitions/nachtwerk.yml",
|
||||
"Definitions/leparadisdunet.yml",
|
||||
"Definitions/qctorrent.yml",
|
||||
"Definitions/dragonworld.yml",
|
||||
"Definitions/hdclub.yml",
|
||||
"Definitions/polishtracker.yml",
|
||||
"Definitions/zetorrents.yml",
|
||||
"Definitions/rapidetracker.yml",
|
||||
"Definitions/isohunt.yml",
|
||||
"Definitions/t411v2.yml",
|
||||
"Definitions/bithq.yml",
|
||||
"Definitions/blubits.yml",
|
||||
"Definitions/torrentproject.yml",
|
||||
"Definitions/torrentvault.yml",
|
||||
"Definitions/apollo.yml", // migrated to C# gazelle base tracker
|
||||
"Definitions/secretcinema.yml", // migrated to C# gazelle base tracker
|
||||
"Definitions/utorrents.yml", // same as SzeneFZ now
|
||||
"Definitions/ultrahdclub.yml",
|
||||
"Definitions/infinityt.yml",
|
||||
"Definitions/hachede-c.yml",
|
||||
"Definitions/skytorrents.yml",
|
||||
"Definitions/gormogon.yml",
|
||||
"Definitions/czteam.yml",
|
||||
"Definitions/rockhardlossless.yml",
|
||||
"Definitions/tehconnection.yml",
|
||||
"Definitions/torrentwtf.yml",
|
||||
"Definitions/eotforum.yml",
|
||||
"Definitions/nexttorrent.yml",
|
||||
"Definitions/torrentsmd.yml",
|
||||
"Definitions/scenehd.yml", // migrated to C# (use JSON API)
|
||||
"appsettings.Development.json",
|
||||
"CurlSharp.dll",
|
||||
"CurlSharp.pdb",
|
||||
"Autofac.Integration.WebApi.dll",
|
||||
"Definitions/420files.yml",
|
||||
"Definitions/aox.yml",
|
||||
"Definitions/anidex.yml", // migrated to C#
|
||||
"Definitions/apollo.yml", // migrated to C# gazelle base tracker
|
||||
"Definitions/archetorrent.yml",
|
||||
"Definitions/asiandvdclub.yml",
|
||||
"Definitions/avg.yml",
|
||||
"Definitions/b2s-share.yml",
|
||||
"Definitions/bithq.yml",
|
||||
"Definitions/bitme.yml",
|
||||
"Definitions/blubits.yml",
|
||||
"Definitions/bt-scene.yml",
|
||||
"Definitions/btbit.yml",
|
||||
"Definitions/btkitty.yml",
|
||||
"Definitions/btstornet.yml",
|
||||
"Definitions/btxpress.yml",
|
||||
"Definitions/cinefilhd.yml",
|
||||
"Definitions/czteam.yml",
|
||||
"Definitions/dark-shadow.yml",
|
||||
"Definitions/digbt.yml",
|
||||
"Definitions/dragonworld.yml",
|
||||
"Definitions/dreamteam.yml",
|
||||
"Definitions/elitehd.yml",
|
||||
"Definitions/elittracker.yml",
|
||||
"Definitions/eotforum.yml",
|
||||
"Definitions/evolutionpalace.yml",
|
||||
"Definitions/extratorrent-ag.yml",
|
||||
"Definitions/extratorrentclone.yml",
|
||||
"Definitions/freakstrackingsystem.yml",
|
||||
"Definitions/freedomhd.yml",
|
||||
"Definitions/gdf76.yml",
|
||||
"Definitions/gfxnews.yml",
|
||||
"Definitions/gods.yml",
|
||||
"Definitions/gormogon.yml",
|
||||
"Definitions/hachede-c.yml",
|
||||
"Definitions/hd4free.yml",
|
||||
"Definitions/hdbc.yml", // renamed to hdbitscom
|
||||
"Definitions/hdclub.yml",
|
||||
"Definitions/hdplus.yml",
|
||||
"Definitions/hon3yhd-net.yml",
|
||||
"Definitions/horriblesubs.yml",
|
||||
"Definitions/hyperay.yml",
|
||||
"Definitions/idopeclone.yml",
|
||||
"Definitions/iloveclassics.yml",
|
||||
"Definitions/infinityt.yml",
|
||||
"Definitions/isohunt.yml",
|
||||
"Definitions/katcrs.yml",
|
||||
"Definitions/kikibt.yml",
|
||||
"Definitions/lapausetorrents.yml",
|
||||
"Definitions/lechaudron.yml",
|
||||
"Definitions/lemencili.yml",
|
||||
"Definitions/leparadisdunet.yml",
|
||||
"Definitions/maniatorrent.yml",
|
||||
"Definitions/manicomioshare.yml",
|
||||
"Definitions/megabliz.yml",
|
||||
"Definitions/mkvcage.yml",
|
||||
"Definitions/music-master.yml",
|
||||
"Definitions/nachtwerk.yml",
|
||||
"Definitions/nexttorrent.yml",
|
||||
"Definitions/nyaa.yml",
|
||||
"Definitions/nyoo.yml",
|
||||
"Definitions/passionetorrent.yml",
|
||||
"Definitions/polishtracker.yml",
|
||||
"Definitions/qctorrent.yml",
|
||||
"Definitions/qxr.yml",
|
||||
"Definitions/rapidetracker.yml",
|
||||
"Definitions/rarbg.yml",
|
||||
"Definitions/redtopia.yml",
|
||||
"Definitions/rgu.yml",
|
||||
"Definitions/rockethd.yml",
|
||||
"Definitions/rockhardlossless.yml",
|
||||
"Definitions/scenehd.yml", // migrated to C# (use JSON API)
|
||||
"Definitions/scenereactor.yml",
|
||||
"Definitions/secretcinema.yml", // migrated to C# gazelle base tracker
|
||||
"Definitions/sharingue.yml",
|
||||
"Definitions/skytorrents.yml",
|
||||
"Definitions/solidtorrents.yml", // migrated to C#
|
||||
"Definitions/speed-share.yml",
|
||||
"Definitions/t411.yml",
|
||||
"Definitions/t411v2.yml",
|
||||
"Definitions/tazmaniaden.yml",
|
||||
"Definitions/tbplus.yml",
|
||||
"Definitions/tehconnection.yml",
|
||||
"Definitions/themoviecave.yml",
|
||||
"Definitions/thetorrents.yml",
|
||||
"Definitions/tigers-dl.yml",
|
||||
"Definitions/tntvillage.yml",
|
||||
"Definitions/torrentcouch.yml",
|
||||
"Definitions/torrentkim.yml",
|
||||
"Definitions/torrentproject.yml",
|
||||
"Definitions/torrentsmd.yml",
|
||||
"Definitions/torrentvault.yml",
|
||||
"Definitions/torrentwtf.yml",
|
||||
"Definitions/torrof.yml",
|
||||
"Definitions/torviet.yml",
|
||||
"Definitions/tspate.yml",
|
||||
"Definitions/ultimategamerclub.yml",
|
||||
"Definitions/ultrahdclub.yml",
|
||||
"Definitions/utorrents.yml", // same as SzeneFZ now
|
||||
"Definitions/waffles.yml",
|
||||
"Definitions/worldofp2p.yml",
|
||||
"Definitions/worldwidetorrents.yml",
|
||||
"Definitions/xktorrent.yml",
|
||||
"Definitions/zetorrents.yml",
|
||||
"Microsoft.Owin.dll",
|
||||
"Microsoft.Owin.FileSystems.dll",
|
||||
"Microsoft.Owin.Host.HttpListener.dll",
|
||||
|
@ -319,74 +388,6 @@ namespace Jackett.Updater
|
|||
"System.Web.Http.dll",
|
||||
"System.Web.Http.Owin.dll",
|
||||
"System.Web.Http.Tracing.dll",
|
||||
"Definitions/torrentkim.yml",
|
||||
"Definitions/horriblesubs.yml",
|
||||
"Definitions/bt-scene.yml",
|
||||
"Definitions/extratorrentclone.yml",
|
||||
"Definitions/torrentcouch.yml",
|
||||
"Definitions/idopeclone.yml",
|
||||
"Definitions/torrof.yml",
|
||||
"Definitions/archetorrent.yml",
|
||||
"Definitions/420files.yml",
|
||||
"Definitions/redtopia.yml",
|
||||
"Definitions/btxpress.yml",
|
||||
"Definitions/btstornet.yml",
|
||||
"Definitions/hdplus.yml",
|
||||
"Definitions/gods.yml",
|
||||
"Definitions/freedomhd.yml",
|
||||
"Definitions/sharingue.yml",
|
||||
"Definitions/cinefilhd.yml",
|
||||
"Definitions/tbplus.yml",
|
||||
"Definitions/manicomioshare.yml",
|
||||
"Definitions/speed-share.yml",
|
||||
"Definitions/b2s-share.yml",
|
||||
"Definitions/nyoo.yml",
|
||||
"Definitions/ultimategamerclub.yml",
|
||||
"Definitions/evolutionpalace.yml",
|
||||
"Definitions/qxr.yml",
|
||||
"Definitions/gfxnews.yml",
|
||||
"Definitions/megabliz.yml",
|
||||
"Definitions/tigers-dl.yml",
|
||||
"Definitions/worldwidetorrents.yml",
|
||||
"Definitions/tntvillage.yml",
|
||||
"Definitions/xktorrent.yml",
|
||||
"Definitions/btkitty.yml",
|
||||
"Definitions/kikibt.yml",
|
||||
"Definitions/rockethd.yml",
|
||||
"Definitions/worldofp2p.yml",
|
||||
"Definitions/avg.yml",
|
||||
"Definitions/aox.yml",
|
||||
"Definitions/dreamteam.yml",
|
||||
"Definitions/elitehd.yml",
|
||||
"Definitions/gdf76.yml",
|
||||
"Definitions/hyperay.yml",
|
||||
"Definitions/scenereactor.yml",
|
||||
"Definitions/lapausetorrents.yml",
|
||||
"Definitions/lechaudron.yml",
|
||||
"Definitions/katcrs.yml",
|
||||
"Definitions/iloveclassics.yml",
|
||||
"Definitions/hd4free.yml",
|
||||
"Definitions/lemencili.yml",
|
||||
"Definitions/btbit.yml",
|
||||
"Definitions/digbt.yml",
|
||||
"Definitions/mkvcage.yml",
|
||||
"Content/congruent_outline.png",
|
||||
"Content/crissXcross.png",
|
||||
"Definitions/dark-shadow.yml",
|
||||
"Definitions/bitme.yml",
|
||||
"Definitions/asiandvdclub.yml",
|
||||
"Definitions/music-master.yml",
|
||||
"Definitions/torviet.yml",
|
||||
"Definitions/waffles.yml",
|
||||
"Definitions/rgu.yml",
|
||||
"Definitions/elittracker.yml",
|
||||
"Definitions/hon3yhd-net.yml",
|
||||
"Definitions/solidtorrents.yml",
|
||||
"Definitions/extratorrent-ag.yml",
|
||||
"Definitions/passionetorrent.yml",
|
||||
"Definitions/thetorrents.yml",
|
||||
"Definitions/themoviecave.yml",
|
||||
"Definitions/tazmaniaden.yml",
|
||||
};
|
||||
|
||||
foreach (var oldFile in oldFiles)
|
||||
|
|
Loading…
Reference in a new issue