Compare commits

...

9 Commits

Author SHA1 Message Date
Garfield69
26b059a699 xider-torrent: 2mst + add verified/unverified descr 2023-12-11 17:45:05 +13:00
Garfield69
193e338390 cinecalidad: new domain 2023-12-11 17:26:00 +13:00
Garfield69
a0cb8e9b25 asiancinema: support multi-lingual date. resolves #14900 2023-12-11 13:40:55 +13:00
ilike2burnthing
0c54815b22 enthralled: add 2fa indexer 2023-12-10 23:14:32 +00:00
ilike2burnthing
cb7c14e101 Update hellashut.yml 2023-12-10 22:00:08 +00:00
Garfield69
4077c37e7d torrentz2eu: prefix keywords wtth plus. resolves #10959 2023-12-11 07:44:40 +13:00
Garfield69
f11161bfbf Update README.md 2023-12-11 07:43:26 +13:00
Bogdan
5bc872e8be core: migrate Polly to v8 (#14896) 2023-12-10 17:52:12 +02:00
ilike2burnthing
c5088ca09d enthralled: add 3X tracker. resolves #14897 (#14898) 2023-12-10 06:32:15 +00:00
11 changed files with 351 additions and 30 deletions

View File

@@ -330,6 +330,7 @@ A third-party Golang SDK for Jackett is available from [webtor-io/go-jackett](ht
* Drugari
* Ebooks-Shares
* Empornium (EMP) [![(invite needed)][inviteneeded]](#)
* Enthralled
* eShareNet
* eStone (BigTorrent)
* Exitorrent.org [![(invite needed)][inviteneeded]](#)
@@ -506,7 +507,7 @@ A third-party Golang SDK for Jackett is available from [webtor-io/go-jackett](ht
* RedBits
* Red Leaves [![(invite needed)][inviteneeded]](#)
* ReelFlix
* Resurrect The Net
* Resurrect The Net [![(invite needed)][inviteneeded]](#)
* RetroFlix
* RevolutionTT
* Romanian Metal Torrents (RMT)

View File

@@ -127,8 +127,42 @@ search:
date:
selector: time
filters:
- name: append
args: " ago"
# translations for Turkish|Estonian|Danish|Italian|Polish|Norwegian|Portuguese|Czech|Russian|Romanian|Spanish|French|German|Bulgarian|Dutch|Chinese|Japanese|Swedish
- name: re_replace
args: ["(?i)(önce|tagasi|geleden|fa|temu|siden|há|atrás|nazpět|назад|acum|în urmă|hace|il y a|vor|преди|前|sedan)", " ago"]
- name: re_replace
args: ["(?i)(saniye|sekundit|sekunder|secondi|sekund|segundos|sekundami|секунд|secunde|secondes|Sekunden|секунди|seconden|秒前)", "seconds"]
- name: re_replace
args: ["(?i)(minutit|minutter|minuti|minuty|minutos|минуты|минут|Minuten|минути|minuten|minuter)", "minutes"]
- name: re_replace
args: ["(?i)(dakika|minut|minuto|minuta|minutt|минута|Minute|minuut|分钟|分)", " minute"]
- name: re_replace
args: ["(?i)(tundi|timer|ore|godziny|horas|hodiny|hoden|часа|часов|ore|heures|Stunden|timmar)", "hours"]
- name: re_replace
args: ["(?i)(saat|tund|time|ora|godzina|hora|hodina|час|oră|heure|Stunde|uur|小时|時間|timme)", " hour"]
- name: re_replace
args: ["(?i)(päeva|dage|giorni|dni|dias|dny|дня|дней|zile|días|jours|Tagen|дни|dagen|dagar)", "days"]
- name: re_replace
args: ["(?i)(gün|päev|dag|giorno|dzień|dia|den|день|zi|día|jour|Tag|ден|天|日)", " day"]
- name: re_replace
args: ["(?i)(nädalat|uger|settimane|tygodnie|uker|semanas|týdny|недели|недель|săptămâni|semaines|Wochen|седмици|weken|veckor)", "weeks"]
- name: re_replace
args: ["(?i)(hafta|nädal|uge|settimana|tydzień|uke|semana|týden|неделю|săptămână|semaine|Woche|седмица|周|週間|vecka)", " week"]
- name: re_replace
args: ["(?i) (ay)", "month"]
- name: re_replace
args: ["(?i)(kuud|måneder|mesi|miesiące|meses|měsíce|месяца|месяцев|luni|meses|mois|Monaten|месеца|maanden|månader)", "months"]
- name: re_replace
args: ["(?i)(kuu|måned|mese|miesiąc|mês|měsíc|месяц|lună|mes|Monat|месец|maand|个月|ヶ月|månad)", " month"]
- name: re_replace
args: ["(?i)(aastat|anni|lata|anos|roky|года|ani|años|ans|Jahren|години)", " years"]
- name: re_replace
args: ["(?i)(yil|aasta|år|anno|rok|ano|год|año|Jahr|година|jaar|年)", " year"]
- name: re_replace
args: ["(?i) (an)", "year"]
- name: re_replace
args: ["(?i)(För |und)", ""] # Misc removals
- name: timeago
downloadvolumefactor:
case:
i[class*="fa-id-badge text-orange"]: 0 # 24 Hour FreeLeech From BON Store

View File

@@ -0,0 +1,134 @@
---
id: enthralled
name: Enthralled
description: "Enthralled is a Private Torrent Tracker for FETISH 3X"
language: en-US
type: private
encoding: UTF-8
links:
- https://www.enthralled.me/
caps:
categorymappings:
- {id: 1, cat: XXX, desc: "FemDom"}
- {id: 2, cat: XXX, desc: "LezDom"}
- {id: 4, cat: XXX, desc: "POV"}
- {id: 5, cat: XXX, desc: "Scat"}
- {id: 3, cat: XXX, desc: "TransDom"}
modes:
search: [q]
settings:
- name: username
type: text
label: Username
- name: password
type: password
label: Password
- name: freeleech
type: checkbox
label: Search freeleech only
default: false
- name: sort
type: select
label: Sort requested from site
default: time
options:
time: created
seeders: seeders
size: size
- name: type
type: select
label: Order requested from site
default: desc
options:
desc: desc
asc: asc
- name: info_tpp
type: info
label: Results Per Page
default: For best results, change the <b>Torrents per page:</b> setting to <b>100</b> on your account profile.
login:
path: login
method: form
inputs:
username: "{{ .Config.username }}"
password: "{{ .Config.password }}"
cinfo: "2550|1350|24|-60"
keeploggedin: 1
error:
- selector: div.error
test:
path: index.php
selector: "#nav_userinfo"
search:
paths:
- path: torrents.php
inputs:
$raw: "{{ range .Categories }}filter_cat[{{.}}]=1&{{end}}"
title: "{{ .Keywords }}"
order_by: "{{ .Config.sort }}"
order_way: "{{ .Config.type }}"
action: advanced
filter_freeleech: "{{ if .Config.freeleech }}1{{ else }}{{ end }}"
rows:
selector: table#torrent_table > tbody > tr[class^="torrent row"]
fields:
category:
selector: a[href*="filter_cat"]
attribute: href
filters:
- name: regexp
args: "(\\d+)]=1"
title:
selector: a[href^="/torrents.php?id="]
details:
selector: a[href^="/torrents.php?id="]
attribute: href
download:
selector: a[href^="/torrents.php?action=download&id="]
attribute: href
poster:
selector: td:nth-child(2) > script
filters:
- name: regexp
args: "src=\\\\\"(.*?)\\\\\""
- name: re_replace
args: ["\\\\(.)", "$1"]
- name: replace
args: ["/static/common/noartwork/noimage.png", ""]
files:
selector: td:nth-child(3)
date:
selector: td:nth-child(5) > span
attribute: title
# auto adjusted by site account profile
filters:
- name: dateparse
args: "MMM dd yyyy, HH:mm"
size:
selector: td:nth-child(6)
grabs:
selector: td:nth-child(7)
seeders:
selector: td:nth-child(8)
leechers:
selector: td:nth-child(9)
downloadvolumefactor:
case:
span.icon[title*="Freeleech"]: 0
"img[alt=\"Freeleech\"]": 0
"*": 1
uploadvolumefactor:
text: 1
minimumratio:
text: 0.5
description:
optional: true
selector: div.tags
# Luminance

View File

@@ -0,0 +1,129 @@
---
id: enthralled2fa
name: Enthralled2FA
description: "Enthralled is a Private Torrent Tracker for FETISH 3X. Cookie Login for 2FA use."
language: en-US
type: private
encoding: UTF-8
links:
- https://www.enthralled.me/
caps:
categorymappings:
- {id: 1, cat: XXX, desc: "FemDom"}
- {id: 2, cat: XXX, desc: "LezDom"}
- {id: 4, cat: XXX, desc: "POV"}
- {id: 5, cat: XXX, desc: "Scat"}
- {id: 3, cat: XXX, desc: "TransDom"}
modes:
search: [q]
settings:
- name: cookie
type: text
label: Cookie
- name: info_cookie
type: info
label: How to get the Cookie
default: "<ol><li>Login to this tracker with your browser</li><li>Open the <b>DevTools</b> panel by pressing <b>F12</b></li><li>Select the <b>Network</b> tab</li><li>Click on the <b>Doc</b> button (Chrome Browser) or <b>HTML</b> button (FireFox)</li><li>Refresh the page by pressing <b>F5</b></li><li>Click on the first row entry</li><li>Select the <b>Headers</b> tab on the Right panel</li><li>Find <b>'cookie:'</b> in the <b>Request Headers</b> section</li><li><b>Select</b> and <b>Copy</b> the whole cookie string <i>(everything after 'cookie: ')</i> and <b>Paste</b> here.</li></ol>"
- name: freeleech
type: checkbox
label: Search freeleech only
default: false
- name: sort
type: select
label: Sort requested from site
default: time
options:
time: created
seeders: seeders
size: size
- name: type
type: select
label: Order requested from site
default: desc
options:
desc: desc
asc: asc
- name: info_tpp
type: info
label: Results Per Page
default: For best results, change the <b>Torrents per page:</b> setting to <b>100</b> on your account profile.
login:
method: cookie
inputs:
cookie: "{{ .Config.cookie }}"
test:
path: index.php
selector: "#nav_userinfo"
search:
paths:
- path: torrents.php
inputs:
$raw: "{{ range .Categories }}filter_cat[{{.}}]=1&{{end}}"
title: "{{ .Keywords }}"
order_by: "{{ .Config.sort }}"
order_way: "{{ .Config.type }}"
action: advanced
filter_freeleech: "{{ if .Config.freeleech }}1{{ else }}{{ end }}"
rows:
selector: table#torrent_table > tbody > tr[class^="torrent row"]
fields:
category:
selector: a[href*="filter_cat"]
attribute: href
filters:
- name: regexp
args: "(\\d+)]=1"
title:
selector: a[href^="/torrents.php?id="]
details:
selector: a[href^="/torrents.php?id="]
attribute: href
download:
selector: a[href^="/torrents.php?action=download&id="]
attribute: href
poster:
selector: td:nth-child(2) > script
filters:
- name: regexp
args: "src=\\\\\"(.*?)\\\\\""
- name: re_replace
args: ["\\\\(.)", "$1"]
- name: replace
args: ["/static/common/noartwork/noimage.png", ""]
files:
selector: td:nth-child(3)
date:
selector: td:nth-child(5) > span
attribute: title
# auto adjusted by site account profile
filters:
- name: dateparse
args: "MMM dd yyyy, HH:mm"
size:
selector: td:nth-child(6)
grabs:
selector: td:nth-child(7)
seeders:
selector: td:nth-child(8)
leechers:
selector: td:nth-child(9)
downloadvolumefactor:
case:
span.icon[title*="Freeleech"]: 0
"img[alt=\"Freeleech\"]": 0
"*": 1
uploadvolumefactor:
text: 1
minimumratio:
text: 0.5
description:
optional: true
selector: div.tags
# Luminance

View File

@@ -108,10 +108,11 @@ login:
captcha:
type: image
selector: img[src="captcha.php?ext=.gif"]
input: captcha
input: input[name^="captcha"]
inputs:
username: "{{ .Config.username }}"
password: "{{ .Config.password }}"
input[name="username"]: "{{ .Config.username }}"
input[name="password"]: "{{ .Config.password }}"
selectors: true
error:
- selector: td.embedded:contains("Access Denied")
test:

View File

@@ -80,6 +80,9 @@ search:
page: 2
inputs:
q: "{{ if .Keywords }}{{ .Keywords }}{{ else }}+{{ end }}"
keywordsfilters:
- name: re_replace
args: ["(\\w+)", "+$1"] # prepend + to each word
rows:
selector: table.table-responsive > tbody > tr

View File

@@ -150,6 +150,10 @@ search:
selector: td:nth-child(10)
leechers:
selector: td:nth-child(11)
description:
case:
i.fa-check: Verified
i.fa-question: Unverified
downloadvolumefactor:
case:
"span[style^=\"font\"]:contains(\"0x\")": 0
@@ -159,6 +163,6 @@ search:
"span[style^=\"font\"]:last-child:contains(\"2x\")": 2
"*": 1
minimumseedtime:
# 3 days (as seconds = 3 x 24 x 60 x 60)
text: 259200
# 2 days (as seconds = 2 x 24 x 60 x 60)
text: 172800
# Engine n/a

View File

@@ -14,6 +14,7 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;
using Polly;
using Polly.Retry;
using static Jackett.Common.Models.IndexerConfig.ConfigurationData;
namespace Jackett.Common.Indexers
@@ -416,31 +417,41 @@ namespace Jackett.Common.Indexers
}
}
private AsyncPolicy<WebResult> RetryPolicy
private ResiliencePipeline<WebResult> RetryStrategy
{
get
{
// Configure the retry policy
int attemptNumber = 1;
var retryPolicy = Policy
.HandleResult<WebResult>(r => (int)r.Status >= 500)
.Or<Exception>()
.WaitAndRetryAsync(
NumberOfRetryAttempts,
retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt) / 4),
onRetry: (exception, timeSpan, context) =>
var retryPipeline = new ResiliencePipelineBuilder<WebResult>()
.AddRetry(new RetryStrategyOptions<WebResult>
{
ShouldHandle = args => args.Outcome switch
{
if (exception.Result == null)
{ Result: { HasHttpServerError: true } } => PredicateResult.True(),
{ Result: { Status: System.Net.HttpStatusCode.RequestTimeout } } => PredicateResult.True(),
{ Exception: { } } => PredicateResult.True(),
_ => PredicateResult.False()
},
Delay = TimeSpan.FromSeconds(2),
MaxRetryAttempts = NumberOfRetryAttempts,
BackoffType = DelayBackoffType.Exponential,
UseJitter = true,
OnRetry = args =>
{
if (args.Outcome.Exception != null)
{
logger.Warn($"Request to {Name} failed with exception '{exception.Exception.Message}'. Retrying in {timeSpan.TotalSeconds}s... (Attempt {attemptNumber} of {NumberOfRetryAttempts}).");
logger.Warn("Request to {0} failed with exception '{1}'. Retrying in {2}s.", Name, args.Outcome.Exception.Message, args.RetryDelay.TotalSeconds);
}
else
{
logger.Warn($"Request to {Name} failed with status {exception.Result.Status}. Retrying in {timeSpan.TotalSeconds}s... (Attempt {attemptNumber} of {NumberOfRetryAttempts}).");
logger.Warn("Request to {0} failed with status {1}. Retrying in {2}s.", Name, args.Outcome.Result?.Status, args.RetryDelay.TotalSeconds);
}
attemptNumber++;
});
return retryPolicy;
return default;
}
})
.Build();
return retryPipeline;
}
}
@@ -531,9 +542,9 @@ namespace Jackett.Common.Indexers
string referer = null, IEnumerable<KeyValuePair<string, string>> data = null,
Dictionary<string, string> headers = null, string rawbody = null, bool? emulateBrowser = null)
{
return await RetryPolicy.ExecuteAsync(async () =>
await RequestWithCookiesAsync(url, cookieOverride, method, referer, data, headers, rawbody, emulateBrowser)
);
return await RetryStrategy
.ExecuteAsync(async _ => await RequestWithCookiesAsync(url, cookieOverride, method, referer, data, headers, rawbody, emulateBrowser))
.ConfigureAwait(false);
}
protected virtual async Task<WebResult> RequestWithCookiesAsync(

View File

@@ -24,10 +24,9 @@ namespace Jackett.Common.Indexers
public override string Id => "cinecalidad";
public override string Name => "Cinecalidad";
public override string Description => "Películas Full UHD/HD en Latino Dual.";
public override string SiteLink { get; protected set; } = "https://wvvv.cinecalidad.so/";
public override string SiteLink { get; protected set; } = "https://cinecalidad.fi/";
public override string[] LegacySiteLinks => new[]
{
"https://w.cinecalidad.foo/",
"https://wwv.cinecalidad.foo/",
"https://wv.cinecalidad.foo/",
"https://vwv.cinecalidad.foo/",
@@ -42,6 +41,7 @@ namespace Jackett.Common.Indexers
"https://w.cinecalidad.so/",
"https://wv.cinecalidad.so/",
"https://vvvv.cinecalidad.so/",
"https://wvvv.cinecalidad.so/",
};
public override string Language => "es-419";
public override string Type => "public";

View File

@@ -24,7 +24,7 @@
<PackageReference Include="MimeMapping" Version="1.0.1.50" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NLog" Version="5.1.2" />
<PackageReference Include="polly" Version="7.2.3" />
<PackageReference Include="Polly" Version="8.2.0" />
<PackageReference Include="SharpZipLib" Version="1.4.2" />
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="5.0.0" />
<PackageReference Include="System.ServiceProcess.ServiceController" Version="6.0.0" />

View File

@@ -66,6 +66,10 @@ namespace Jackett.Common.Utils.Clients
set => _contentString = value;
}
public bool HasHttpError => (int)Status >= 400;
public bool HasHttpServerError => (int)Status >= 500;
public bool IsRedirect => Status == HttpStatusCode.Redirect ||
Status == HttpStatusCode.RedirectKeepVerb ||
Status == HttpStatusCode.RedirectMethod ||