Compare commits

...

48 Commits

Author SHA1 Message Date
Garfield69
c0a5e24186 Update ptchina.yml 2023-06-06 16:05:10 +12:00
Garfield69
0e043a5792 assorted nexusphp: update engine tag 2023-06-06 16:01:49 +12:00
Bogdan
98f7e720e7 cardigann: allow empty inputs for login.method get (#14430) 2023-06-06 05:56:14 +03:00
Bogdan
8154acb47b cardigann: allow empty inputs for login.method get 2023-06-06 01:02:45 +03:00
Garfield69
df94aaf930 cinecalidad: new domain 2023-06-06 09:23:56 +12:00
Bogdan
d8dc0d221a torrentleech: use login form (#14428) resolves #14410 2023-06-06 09:11:58 +12:00
Garfield69
3ba502a378 YTS: correct sort
the default is date_added so using sort=date_added instead of sort_by=date_added did not make any difference but at least now we are in line with the api docs ;-)
2023-06-06 07:33:07 +12:00
Bogdan
b9655f1302 digitalcore: add search P2P releases only option 2023-06-05 19:46:34 +03:00
Garfield69
422eff86f4 hdtorrentsit: removed. resolves #14411 2023-06-05 17:21:55 +12:00
Garfield69
e66d88bbcf hd-unit3d: update engine tag 2023-06-05 15:47:08 +12:00
Garfield69
669ddae0b0 theoldschool: drop page 2023-06-05 15:46:44 +12:00
Garfield69
0b0d08dd7c bwtorrents: new cat 2023-06-05 07:39:54 +12:00
Garfield69
bf5b24a5a7 ccfbits: removed. resolves #14306 2023-06-04 20:08:56 +12:00
Garfield69
228089b35b torrenteros: new cat 2023-06-04 15:32:55 +12:00
Bogdan
f334cc89d6 indexers: improve test indexer message on failure (#14421) 2023-06-04 06:11:35 +03:00
Bogdan
3a9360add9 hdtorrents: add error message selector 2023-06-04 02:53:15 +03:00
Bogdan
207dd1d51a torrentdownloads: add raw search support
Fixes #14420
2023-06-04 02:00:33 +03:00
Garfield69
47e78fc70c torrenteros: amend MR MST based on OP #11925 2023-06-03 20:04:09 +12:00
Garfield69
36d3f67fdc add torrenteros a Spanish private site. resolves #11925
Early stages, still setting up by the looks of it, has just some movies, so cannot tell what the series filename season structure will be like.
No Rules or FAQ ATM so defaulting to MR 1.0
Expect changes.
2023-06-03 19:48:01 +12:00
Bogdan
41a5d3165e torrentleech: add login page form as error selector (#14414) 2023-06-03 02:44:59 +03:00
Bogdan
2b9d950f39 speedapptracker: add freeleech only (#14415) 2023-06-02 23:42:00 +03:00
Garfield69
7be7d6770f cinefilhd: new preferred domain 2023-06-02 19:09:02 +12:00
Garfield69
ff36eecfae xxxclub: new layout 2023-06-02 07:47:03 +12:00
Garfield69
0438ffdfc0 torrentqq: bump domain 2023-06-02 07:46:51 +12:00
Bogdan
b614a8dc42 torrentz2eu: fix dateparse and check for TV Show in title 2023-06-01 19:42:21 +03:00
ilike2burnthing
1eae091ab8 core: update magnet trackers 2023-06-01 06:01:15 +01:00
Garfield69
17d08d3f8c cinecalidad: new domain 2023-06-01 11:44:16 +12:00
Garfield69
d70bdbb26d dontorrent: new domain 2023-06-01 11:31:19 +12:00
ilike2burnthing
8d0edcdfb8 rarbg: removed, dead. resolves #14406 (#14407) 2023-05-31 15:07:17 +01:00
Garfield69
34193e11df thegeeks: new cat 2023-05-31 06:46:27 +12:00
Garfield69
57b8cbd407 bitbazis: new cat 2023-05-31 06:32:54 +12:00
Garfield69
c2dbf6a80d cinecalidad: new domain 2023-05-30 06:50:44 +12:00
ilike2burnthing
ff5586c4fa lostfilm: restore domains. #14398 2023-05-29 16:13:36 +01:00
Bogdan
48ff6821e6 cardigann: use MissingAttributeEqualsNoResults for Search.Rows.Attribute
Fixes #14400
2023-05-29 17:33:02 +03:00
Bogdan
e282ff76a5 core: show app version in exceptions 2023-05-29 16:56:45 +03:00
Garfield69
8affee4b2d lostfilm: domain fixes. resolves #14398 2023-05-29 18:41:17 +12:00
Garfield69
dc352744c7 assorted: follow up ef5276da64 2023-05-29 16:01:59 +12:00
Garfield69
ef5276da64 assorted: simplify future path category maintenance
in the event new cats get added or removed  there is now fewer places we have to remember to cross check
2023-05-29 15:32:15 +12:00
Garfield69
32360070ad metalguru: add new cats 2023-05-29 13:12:52 +12:00
ilike2burnthing
633d1631c2 vstorrent: add public VST site. resolves #14385 (#14397) 2023-05-28 23:57:15 +01:00
ilike2burnthing
d4fc8ab071 vsttorrents: change cat to PC, add date 2023-05-28 23:53:23 +01:00
ilike2burnthing
08713ae7b8 vsthouse: remove unused mode 2023-05-28 23:52:26 +01:00
ilike2burnthing
836f5372b3 vsthouse: change cat to PC 2023-05-28 23:51:15 +01:00
Bogdan
7e7ace05be cardigann: respect the categories from search paths (#14395) 2023-05-29 00:53:42 +03:00
ilike2burnthing
12da8b6131 bitbazis: update for 3x search 2023-05-28 22:20:35 +01:00
Bogdan
abc2f43f9c mteamtp: increase request delay to 4s 2023-05-28 20:19:13 +03:00
Bogdan
1a49430b45 rutracker: use supported 200 categories per search request 2023-05-28 19:52:14 +03:00
Aleksei
147549cbf8 rutracker: update cats (#14394)
Co-authored-by: ilike2burnthing <59480337+ilike2burnthing@users.noreply.github.com>
2023-05-28 17:41:35 +01:00
63 changed files with 567 additions and 833 deletions

View File

@@ -106,7 +106,6 @@ A third-party Golang SDK for Jackett is available from [webtor-io/go-jackett](ht
* PornoTorrent
* ProPorn
* Rapidzona
* RARBG
* RinTorNeT
* RuTor
* RuTracker.RU
@@ -144,7 +143,8 @@ A third-party Golang SDK for Jackett is available from [webtor-io/go-jackett](ht
* truPornolabs
* UnionDHT
* VSTHouse
* VST Torrents
* VST Torrentz
* VSTorrent
* xxxAdultTorrent
* XXXClub
* xxxtor
@@ -300,7 +300,6 @@ A third-party Golang SDK for Jackett is available from [webtor-io/go-jackett](ht
* CarPT
* CartoonChaos (CC)
* Cathode-Ray.Tube (CRT)
* CCFBits [![(invite needed)][inviteneeded]](#)
* Central Torrent
* CeskeForum
* CGPeers [![(invite needed)][inviteneeded]](#)
@@ -383,7 +382,6 @@ A third-party Golang SDK for Jackett is available from [webtor-io/go-jackett](ht
* HDRoute [![(invite needed)][inviteneeded]](#)
* HDSky [![(invite needed)][inviteneeded]](#)
* HDTime
* HDTorrents.it [![(invite needed)][inviteneeded]](#)
* HDTurk
* HDU
* HDVIDEO
@@ -565,6 +563,7 @@ A third-party Golang SDK for Jackett is available from [webtor-io/go-jackett](ht
* TorrentBytes (TBy)
* TorrentCCF (TCCF)
* TorrentDay (TD)
* Torrenteros (TTR)
* TorrentHeaven [![(invite needed)][inviteneeded]](#)
* TorrentHR [![(invite needed)][inviteneeded]](#)
* Torrenting (TT)

View File

@@ -189,4 +189,4 @@ search:
description:
selector: td:nth-child(2)
remove: a, b, font, img, span
# NexusPHP v1.8.2 2023-05-08
# NexusPHP v1.8.3 2023-05-14

View File

@@ -30,13 +30,13 @@ caps:
- {id: 423, cat: XXX, desc: "IV(写真影片)", default: true}
- {id: 424, cat: XXX, desc: "IV(写真图集)", default: true}
# special
- {id: 526, cat: Movies, desc: "VRMovies(3D/VR电影)", default: true}
- {id: 527, cat: TV, desc: "VRSeries(3D/VR剧集)", default: true}
- {id: 528, cat: Audio/Video, desc: "AV(VR无码)", default: true}
- {id: 529, cat: Audio/Video, desc: "AV(VR有码)", default: true}
- {id: 530, cat: Console, desc: "VRGame(VR一体机游戏)", default: true}
- {id: 531, cat: PC/Games, desc: "PCVRGame(PCVR游戏)", default: true}
- {id: 532, cat: Other, desc: "VRTools(VR工具软件)", default: true}
- {id: 526, cat: Movies, desc: "VRMovies(3D/VR电影)", default: false}
- {id: 527, cat: TV, desc: "VRSeries(3D/VR剧集)", default: false}
- {id: 528, cat: Audio/Video, desc: "AV(VR无码)", default: false}
- {id: 529, cat: Audio/Video, desc: "AV(VR有码)", default: false}
- {id: 530, cat: Console, desc: "VRGame(VR一体机游戏)", default: false}
- {id: 531, cat: PC/Games, desc: "PCVRGame(PCVR游戏)", default: false}
- {id: 532, cat: Other, desc: "VRTools(VR工具软件)", default: false}
modes:
search: [q]
@@ -110,7 +110,7 @@ login:
search:
paths:
- path: torrents.php
categories: [401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 413, 420, 421, 422, 423, 424]
categories: ["!", 526, 527, 528, 529, 530, 531, 532]
- path: special.php
categories: [526, 527, 528, 529, 530, 531, 532]
inputs:

View File

@@ -23,10 +23,16 @@ caps:
- {id: 95, cat: Movies/HD, desc: "Film/FHD/Eng", default: true}
- {id: 92, cat: Movies/UHD, desc: "Film/UHD/Hun", default: true}
- {id: 93, cat: Movies/UHD, desc: "Film/UHD/Eng", default: true}
- {id: 64, cat: Movies, desc: "Film/Pack", default: true}
- {id: 24, cat: Audio/Video, desc: "Videóklip", default: true}
- {id: 22, cat: TV, desc: "Sorozat/Hun", default: true}
- {id: 58, cat: TV, desc: "Sorozat/Eng", default: true}
- {id: 64, cat: Movies, desc: "Film/Pack", default: true}
- {id: 66, cat: XXX/ImageSet, desc: "Képek/XXX", default: false}
- {id: 33, cat: XXX/SD, desc: "SD/XXX", default: false}
- {id: 89, cat: XXX/x264, desc: "HD/XXX", default: false}
- {id: 24, cat: Audio/Video, desc: "Videóklip", default: true}
- {id: 70, cat: Audio/Audiobook, desc: "Hangoskönyv", default: true}
- {id: 27, cat: Books/EBook, desc: "Könyv/Hun", default: true}
- {id: 50, cat: Books/EBook, desc: "Könyv/Eng", default: true}
- {id: 69, cat: TV/Anime, desc: "Mese/SD", default: true}
- {id: 68, cat: TV/Anime, desc: "Mese/DVD", default: true}
- {id: 91, cat: TV/Anime, desc: "Mese/HD", default: true}
@@ -35,19 +41,13 @@ caps:
- {id: 84, cat: Audio/Lossless, desc: "Lossless/Hun", default: true}
- {id: 71, cat: Audio/Lossless, desc: "Lossless/Eng", default: true}
- {id: 31, cat: PC/Games, desc: "Játék/PC", default: true}
- {id: 54, cat: Console, desc: "Játék/Konzol", default: true}
- {id: 81, cat: PC/0day, desc: "Program/PC", default: true}
- {id: 67, cat: PC/Mobile-Android, desc: "Program/Mobil", default: true}
- {id: 49, cat: PC/0day, desc: "Program/Rip", default: true}
- {id: 27, cat: Books/EBook, desc: "Könyv/Hun", default: true}
- {id: 50, cat: Books/EBook, desc: "Könyv/Eng", default: true}
- {id: 14, cat: PC, desc: "Program/Egyéb", default: true}
- {id: 65, cat: Other, desc: "Egyéb", default: true}
- {id: 33, cat: XXX/SD, desc: "SD/XXX", default: false}
- {id: 89, cat: XXX/x264, desc: "HD/XXX", default: false}
- {id: 66, cat: XXX/ImageSet, desc: "Képek/XXX", default: false}
# the following are no longer in the cat list in the search page, but are still in the profile cat list
- {id: 54, cat: Console, desc: "Játék/Konzol", default: true}
- {id: 67, cat: PC/Mobile-Android, desc: "Program/Mobil", default: true}
- {id: 70, cat: Audio/Audiobook, desc: "Hangoskönyv", default: true}
- {id: 97, cat: TV/Anime, desc: "Sorozat/Mese", default: true}
modes:
search: [q]
@@ -99,7 +99,7 @@ login:
search:
paths:
- path: browse.php
categories: [85, 86, 15, 16, 17, 19, 83, 82, 94, 95, 92, 93, 64, 24, 22, 58, 69, 68, 91, 25, 26, 84, 71, 31, 81, 49, 27, 50, 14, 65, 54, 67, 70]
categories: ["!", 33, 66, 89]
inputs:
# 0 all, 1 active, 2 deadonly, 3 myuploads, 4 zeroseed, 6 re-seeded
incldead: 0
@@ -117,22 +117,26 @@ search:
# can support genre searching but you need to know the id, eg &genre23=1 for Comedy (id is 23)
rows:
selector: "tr[class^=\"toriadatok_\"]{{ if .Config.freeleech }}:has(i:contains(\"(Free)\")){{ else }}{{ end }}"
selector: "tr[class^=\"toriadatok\"]{{ if .Config.freeleech }}:has(i:contains(\"(Free)\")){{ else }}{{ end }}"
fields:
categorydesc:
selector: img[src^="pic/kategoria/"]
attribute: title
title:
selector: a.preview
selector: font[class="tori"], a.preview
_id:
selector: td.tori_infok
attribute: id
optional: true
filters:
- name: regexp
args: (\d+)
details:
text: "details.php?id={{ .Result._id }}#adatlap"
selector: a[href^="details.php?id="]
attribute: href
optional: true
default: "details.php?id={{ .Result._id }}#adatlap"
download:
text: "download.php?torrent={{ .Result._id }}"
poster:
@@ -142,14 +146,14 @@ search:
selector: a[href*="imdb.com/title/tt"]
attribute: href
size:
selector: td[id^="tsize_"]
selector: td[id^="tsize"]
date:
# 36 perce
# 13 órája és 59 perce
# 2 napja és 10 órája
# 1 hete és 1 napja
# 1 éve és 30 hete
selector: td[id^="t_added_"] > span
selector: td[id^="t_added"] > span
filters:
- name: replace
args: ["és ", " "]

View File

@@ -123,6 +123,7 @@ caps:
- {id: 217, cat: Movies, desc: "Tamil-Movies | Remuxes BluRay"}
- {id: 218, cat: TV, desc: "TV-Ishara TV"}
- {id: 219, cat: TV, desc: "TV-Bengali Tv"}
- {id: 220, cat: TV, desc: "TV-Shemaroo Umang"}
modes:
search: [q]

View File

@@ -89,7 +89,7 @@ login:
search:
paths:
- path: browse.php
categories: [1, 2, 8, 7, 16, 15, 14, 13, 4, 3, 18, 17, 23, 19, 20, 24, 21, 22, 35, 36, 25, 30, 31, 33, 32, 29, 28, 27, 26]
categories: ["!", 34, 39]
- path: browse.php
categories: [34, 39]
inputs:

View File

@@ -189,4 +189,4 @@ search:
description:
selector: td.rowfollow:nth-child(2)
remove: a, b, font, img, span
# NexusPHP v1.7.37 2023-05-08
# NexusPHP v1.7.38 2023-05-14

View File

@@ -1,152 +0,0 @@
---
id: ccfbits
name: CCFBits
description: "CCFBits is a CHINESE Private Torrent Tracker for HD MOVIES / TV"
language: zh-CN
type: private
encoding: UTF-8
links:
- https://ccfbits.org/
caps:
categorymappings:
# 高清电影
- {id: 39, cat: Movies/HD, desc: "HD-DVD原盘"}
- {id: 40, cat: Movies/BluRay, desc: "Blu-ray原盘"}
- {id: 30, cat: Movies/HD, desc: "高清电影1080p"}
- {id: 2, cat: Movies/HD, desc: "高清电影720p"}
# 高清电视剧
- {id: 7, cat: TV/HD, desc: "高清欧美剧"}
- {id: 32, cat: TV/HD, desc: "高清国产剧"}
- {id: 34, cat: TV/HD, desc: "高清港台剧"}
- {id: 36, cat: TV/HD, desc: "高清日韩剧"}
# 其他高清视频
- {id: 12, cat: TV/Documentary, desc: "高清纪录片"}
- {id: 11, cat: TV/Sport, desc: "高清体育"}
- {id: 23, cat: TV/Anime, desc: "高清动漫"}
- {id: 4, cat: Audio/Video, desc: "高清MV/综艺"}
# 电视剧集包
- {id: 38, cat: TV/HD, desc: "欧美剧包"}
- {id: 33, cat: TV/HD, desc: "国产剧包"}
- {id: 35, cat: TV/HD, desc: "港台剧包"}
- {id: 37, cat: TV/HD, desc: "日韩剧包"}
# 非高清和其他
- {id: 43, cat: TV/SD, desc: "HR_HDTV"}
- {id: 20, cat: Movies/DVD, desc: "DVD"}
- {id: 42, cat: Movies/SD, desc: "XviD"}
- {id: 3, cat: Audio, desc: "无损音乐"}
- {id: 22, cat: Other, desc: "杂项"}
modes:
search: [q]
tv-search: [q, season, ep, imdbid]
movie-search: [q, imdbid]
music-search: [q]
settings:
- name: username
type: text
label: Username
- name: password
type: password
label: Password
- name: sort
type: select
label: Sort requested from site
default: added
options:
added: created
seeders: seeders
size: size
name: title
- name: type
type: select
label: Order requested from site
default: DESC
options:
DESC: desc
ASC: asc
login:
path: takelogin.php
method: post
inputs:
username: "{{ .Config.username }}"
password: "{{ .Config.password }}"
error:
- selector: td.embedded:has(h2:contains("登录失败"))
test:
path: browse.php
search:
paths:
- path: browse.php
inputs:
$raw: "{{ range .Categories }}c{{.}}=1&{{end}}"
search: "{{ if .Query.IMDBID }}{{ .Query.IMDBID }}{{ else }}{{ .Keywords }}{{ end }}"
# 0 active 1 incldead 2 deadonly
incldead: 1
fullsearch: "{{ if .Query.IMDBID }}1{{ else }}{{ end }}"
sort: "{{ .Config.sort }}"
d: "{{ .Config.sort }}"
rows:
selector: table[border="1"][cellpadding="5"] > tbody > tr:has(a[href^="details.php?id="])
fields:
title:
selector: a[title][href^="details.php?id="]
attribute: title
filters:
- name: split
args: ["\n", 0]
category:
selector: a[href^="browse.php?cat="]
attribute: href
filters:
- name: querystring
args: cat
details:
selector: a[href^="details.php?id="]
attribute: href
download:
selector: a[href^="download.php/"]
attribute: href
imdbid:
selector: a[href*="imdb.com/title/tt"]
attribute: href
files:
selector: a[href$="&filelist=1"]
grabs:
selector: a[href^="snatches.php?id"]
filters:
- name: replace
args: ["次", ""]
size:
selector: td:nth-child(7)
remove: a
seeders:
selector: td:nth-child(8)
leechers:
selector: td:nth-child(9)
date:
selector: td:nth-child(5)
filters:
- name: append
args: " +08:00" # CST
- name: dateparse
args: "yyyy-MM-ddHH:mm:ss zzz"
downloadvolumefactor:
case:
"font[color=\"#C20603\"]:contains(\"免费\")": 0
"font:has([src=\"/pic/arrowdown1.gif\"]):contains(\"0.5x\")": 0.5
"*": 1
uploadvolumefactor:
case:
"font:has([src=\"/pic/arrowup1.gif\"]):contains(\"1.5x\")": 1.5
"font:has([src=\"/pic/arrowup1.gif\"]):contains(\"2x\")": 2
"*": 1
description:
selector: td:nth-child(2) > table > tbody > tr:nth-child(2)
remove: a, img
# Discuz! 7.2

View File

@@ -6,6 +6,7 @@ language: en-US
type: private
encoding: UTF-8
links:
- http://cinefilhd.xyz/
- http://cinefilhd.sytes.net/
legacylinks:
- http://www.cinefilhd.org/

View File

@@ -71,6 +71,10 @@ settings:
type: checkbox
label: Search freeleech only
default: false
- name: p2p_releases_only
type: checkbox
label: Search P2P releases only
default: false
- name: sort
type: select
label: Sort requested from site
@@ -109,6 +113,7 @@ search:
index: 0
limit: 100
order: "{{ .Config.type }}"
p2p: "{{ if .Config.p2p_releases_only }}true{{ else }}{{ end }}"
page: search
searchText: "{{ if .Query.IMDBID }}{{ .Query.IMDBID }} {{ else }}{{ end }}{{ .Keywords }}"
section: all

View File

@@ -77,7 +77,7 @@ login:
search:
paths:
- path: torrents.php
categories: [1, 4091, 4097, 4098, 4099, 4101, 4104, 4105]
categories: ["!", 4103]
- path: live.php
categories: [4103]
inputs:

View File

@@ -148,4 +148,4 @@ search:
minimumseedtime:
# 3 days (as seconds = 3 x 24 x 60 x 60)
text: 259200
# json UNIT3D 6.3.0
# json UNIT3D 6.4.1

View File

@@ -146,4 +146,4 @@ search:
img.pro_free2up: 2
img.pro_2up: 2
"*": 1
# NexusPHP 2c858e7 (Customised)
# NexusPHP 4e16128 (Customised)

View File

@@ -195,4 +195,4 @@ search:
description:
selector: td:nth-child(2)
remove: a, b, font, img, span
# NexusPHP v1.8.2 2023-05-06
# NexusPHP v1.8.4 2023-05-27

View File

@@ -171,4 +171,4 @@ search:
description:
selector: td.rowfollow:nth-child(2)
remove: a, b, font, img, span
# NexusPHP v1.7.29 2022-10-12
# NexusPHP v1.8.3 2023-05-13

View File

@@ -188,4 +188,4 @@ search:
description:
selector: td.rowfollow:nth-child(2)
remove: a, b, font, img, span
# NexusPHP v1.7.37 2023-05-08
# NexusPHP v1.8.4 2023-06-04

View File

@@ -1,161 +0,0 @@
---
id: hdtorrentsit
name: HDTorrents.it
description: "HDTorrents.it is an ITALIAN Private site for TV / MOVIES"
language: it-IT
type: private
encoding: UTF-8
links:
- https://hdtorrents.xyz/ # Italian IP address filtering
legacylinks:
- http://hdtorrents.it/
- http://hdtorrents.xyz/
caps:
categorymappings:
- {id: 2040, cat: Movies/HD}
- {id: 5040, cat: TV/HD}
modes:
search: [q]
tv-search: [q, season, ep]
movie-search: [q]
settings:
- name: username
type: text
label: Username
- name: password
type: password
label: Password
- name: ip_filtering
type: info
label: "IP Filtering"
default: "The <b>404 Not Found</b> error means your IP was not accepted. Check the <a href=\"https://check-host.net/check-report/e5b649bkfa\" target=\"_blank\">Locations report</a>, only those with a Status of <b>OK</b> will be accepted."
login:
path: takelogin.php
method: post
inputs:
username: "{{ .Config.username }}"
password: "{{ .Config.password }}"
error:
- selector: div.error
- selector: h1:contains("404 Not Found")
test:
path: browse.php
search:
paths:
- path: browse.php
method: post
allowEmptyInputs: true
keywordsfilters:
- name: re_replace
args: ["[^a-zA-Z0-9]+", "%"]
- name: diacritics
args: replace
- name: re_replace # remove SXXEYY from research
args: ["(?i)(S\\d{1,2}E\\d{1,2})", ""]
- name: re_replace # remove SXX from research
args: ["(?i)(S\\d{1,2})", ""]
inputs:
ajax: false
search: "{{ .Keywords }}"
# 0 active 1 incldead 2 onlydead 3 gold 4 no seeders
incldead: 0
rows:
selector: tbody#highlighted tr
fields:
year:
selector: td:nth-child(2) a:nth-child(1)
filters:
- name: regexp # find torrent year
args: (\d{4})
_quality: # (BDRip 1080, BDRip 720p etc)
selector: td:nth-child(1) a:nth-child(1) img
attribute: alt
_audio: # ita audio TAG
selector: a[href^="download.php?id="]
attribute: href
filters:
- name: querystring
args: name
- name: regexp
args: (DTS AC3 ITA|DTS ITA|AC3 ITA)
- name: re_replace
args: ["ITA", ""]
title:
selector: td:nth-child(2) a:nth-child(1)
filters:
- name: re_replace # separate title
args: ["(\\s+\\/\\s+|\\/\\s+|\\s+\\/|\\/)(.*)\\s\\(", " ("]
- name: re_replace # remove (yyyy) from the title
args: ["(\\(\\d{4}\\)?\\s?)", ""]
- name: re_replace # remove |
args: ["(\\s\\||\\s\\/)", ""]
- name: re_replace # Stagione X --> S0X
args: ["(?i)\\bStagion[ei]\\s?(\\d{1})\\b|\\bSeason'?s?\\s?(\\d{1})\\b", "S0$1$2"]
- name: re_replace # Stagione XX --> SXX
args: ["(?i)\\bStagion[ei]\\s?(\\d{2,})\\b|\\bSeason'?s?\\s?(\\d{2,})\\b", "S$1$2"]
- name: re_replace # / Episodio [YY-YY --> EYY-YY
args: ["(?i)(\\s\\/?\\s?Episodi[o]?)\\s\\[", "E"]
- name: re_replace # Episodio 4 to E4
args: ["(?i)\\b(?:[\\s\\/\\|]?Episodi[o]?\\s?(\\d+)|Puntata\\s?(\\d+))", "E$1$2"]
- name: re_replace # / Completa [episodi YY-YY --> EYY-YY
args: ["(?i)(\\s\\/\\sCompleta\\s\\[episodi\\s)", "E"]
- name: re_replace # remove di YY] | remove /YY]
args: ["(?i)(\\sdi\\s\\d{1,2}|\\/\\d{1,2})\\]", " "]
- name: re_replace # remove various
args: ["(?i)(Serie completa|Completa|\\[in pausa\\])", ""]
- name: append
args: " ({{ .Result.year }}) [{{ .Result._quality }} - {{ .Result._audio }} ITA]"
- name: re_replace # replace multiple spaces
args: ["[ ]{2,}", " "]
details:
selector: td:nth-child(2) a:nth-child(1)
attribute: href
poster:
selector: td:nth-child(2)[onmousemove]
attribute: onmousemove
filters:
- name: regexp
args: ".*\\(.*,.*,.*,'(.*?)'\\)"
download:
selector: a[href^="download.php?id="]
attribute: href
size:
selector: td:nth-child(3)
seeders:
selector: td:nth-child(4)
optional: true
default: 1
filters:
- name: re_replace
args: ["(\\d*) \\(\\+\\d*\\)\n? \\| (\\d*) \\(\\+\\d*\\)", "$1"]
leechers:
selector: td:nth-child(4)
optional: true
default: 1
filters:
- name: re_replace
args: ["(\\d*) \\(\\+\\d*\\)\n? \\| (\\d*) \\(\\+\\d*\\)", "$2"]
date:
selector: td:nth-child(2) i
filters:
- name: append
args: " +02:00" # EET
- name: dateparse
args: "yyyy-MM-dd HH:mm:ss zzz"
category:
case:
"a[href^=\"details.php\"]:contains(\"Stagione\")": 5040 # TV/HD
"*": 2040 # default to Movies/HD
downloadvolumefactor:
case:
img[src="pic/freedownload.gif"]: 0
"*": 1
uploadvolumefactor:
text: 1
# engine tbd

View File

@@ -169,4 +169,4 @@ search:
description:
selector: td.rowfollow:nth-child(2)
remove: a, b, font, img, span
# NexusPHP v1.7.34 2023-01-16
# NexusPHP v1.7.39 2023-05-15

View File

@@ -21,9 +21,9 @@ caps:
- {id: 409, cat: Other, desc: "Misc/其他", default: true}
- {id: 408, cat: Audio, desc: "Music/音乐", default: true}
# special
- {id: 410, cat: Movies, desc: "Video/视频资料", default: true}
- {id: 411, cat: Audio, desc: "Audio/音频资料", default: true}
- {id: 412, cat: Other, desc: "Other/其他资料", default: true}
- {id: 410, cat: Movies, desc: "Video/视频资料", default: false}
- {id: 411, cat: Audio, desc: "Audio/音频资料", default: false}
- {id: 412, cat: Other, desc: "Other/其他资料", default: false}
modes:
search: [q]
@@ -96,7 +96,7 @@ login:
search:
paths:
- path: torrents.php
categories: [401, 402, 403, 404, 405, 406, 407, 408, 409]
categories: ["!", 410, 411, 412]
- path: special.php
categories: [410, 411, 412]
inputs:

View File

@@ -179,4 +179,4 @@ search:
description:
selector: td.rowfollow:nth-child(2)
remove: a, b, font, img, span
# NexusPHP v1.7.26 2022-09-15
# NexusPHP v1.8.2 2023-05-08

View File

@@ -121,7 +121,7 @@ search:
# https://www.last-torrents.org/externalid?searchex=tt5834760&search_by=imdbid
# cannot support imdbid or tmdbid searches while using path category filters
- path: browse.php
categories: [1, 2, 5, 6, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 30, 31, 32, 33, 42, 43, 44, 49, 51, 54, 55, 56, 57, 58, 59, 60, 61, 62, 81, 82]
categories: ["!", 27, 60]
- path: browseadult.php
categories: [27, 60]

View File

@@ -82,11 +82,11 @@ login:
search:
paths:
- path: letoltes.php
categories: [4, 5, 48, 50, 75, 76, 26, 25, 58, 59, 42, 51, 38, 24, 85, 87, 47, 36, 6, 7, 56, 33, 44, 28, 32, 30, 53, 74, 40, 41, 34, 35, 46]
categories: ["!", 70, 39, 57]
inputs:
tipus: 1
- path: letoltes.php
categories: [4, 5, 48, 50, 75, 76, 26, 25, 58, 59, 42, 51, 38, 24, 85, 87, 47, 36, 6, 7, 56, 33, 44, 28, 32, 30, 53, 74, 40, 41, 34, 35, 46]
categories: ["!", 70, 39, 57]
inputs:
tipus: 2
- path: xxx.php

View File

@@ -16,6 +16,8 @@ caps:
- {id: 1, cat: PC, desc: "Applications"}
- {id: 2, cat: Books, desc: "Books Ebooks & mags"}
- {id: 59, cat: Movies/SD, desc: "Cams"}
- {id: 52, cat: Audio, desc: "DJ"}
- {id: 53, cat: Audio, desc: "DJ PACKS"}
- {id: 46, cat: Books, desc: "Documents"}
- {id: 47, cat: Audio/Lossless, desc: "Flac/HD Audio"}
- {id: 61, cat: Console, desc: "Games"}

View File

@@ -5,7 +5,7 @@ description: "M-Team TP (MTTP) is a CHINESE Private Torrent Tracker for HD MOVIE
language: zh-CN
type: private
encoding: UTF-8
requestDelay: 3
requestDelay: 4
links:
- https://kp.m-team.cc/
legacylinks:

View File

@@ -5,7 +5,7 @@ description: "This indexer uses a cookie login for M-Team TP (MTTP) for those th
language: zh-CN
type: private
encoding: UTF-8
requestDelay: 3
requestDelay: 4
links:
- https://kp.m-team.cc/
legacylinks:

View File

@@ -178,4 +178,4 @@ search:
filters:
- name: replace
args: [" 剩余时间:", ""]
# NexusPHP v1.7.29 2022-10-13
# NexusPHP v1.8.2 2023-05-08

View File

@@ -192,4 +192,4 @@ search:
remove: a, img, span
description:
text: "{{ .Result.genre }}"
# NexusPHP v1.7.33 2022-12-19
# NexusPHP v1.8.0 2023-04-16

View File

@@ -188,4 +188,4 @@ search:
description:
selector: td:nth-child(2)
remove: a, b, font, img, span
# NexusPHP v1.8.2 2023-05-08
# NexusPHP v1.8.3 2023-05-14

View File

@@ -172,4 +172,4 @@ search:
filters:
- name: replace
args: [" 剩余时间:", ""]
# Ourbits 1.1.0 (Based on NexusPHP Standard v1.5 Beta 4) 4691022 2023-05-04
# Ourbits 1.1.0 (Based on NexusPHP Standard v1.5 Beta 4) 3feac18 2023-05-30

View File

@@ -21,10 +21,10 @@ caps:
- {id: 409, cat: Other, desc: "Misc/其他", default: true}
- {id: 408, cat: Audio, desc: "Music/音乐", default: true}
# kids zone
- {id: 908, cat: TV, desc: "TV Series/剧集", default: true}
- {id: 909, cat: Movies, desc: "Movies/电影", default: true}
- {id: 905, cat: Audio/Video, desc: "MusicVideo/MV", default: true}
- {id: 907, cat: Audio, desc: "Music/音乐", default: true}
- {id: 908, cat: TV, desc: "TV Series/剧集", default: false}
- {id: 909, cat: Movies, desc: "Movies/电影", default: false}
- {id: 905, cat: Audio/Video, desc: "MusicVideo/MV", default: false}
- {id: 907, cat: Audio, desc: "Music/音乐", default: false}
modes:
search: [q]
@@ -79,7 +79,7 @@ login:
search:
paths:
- path: torrents.php
categories: [401, 402, 403, 404, 405, 406, 407, 408, 409]
categories: ["!", 905, 907, 908, 909]
- path: special.php
categories: [905, 907, 908, 909]
inputs:

View File

@@ -185,4 +185,4 @@ search:
description:
selector: td.rowfollow:nth-child(2)
remove: a, b, font, img, span
# NexusPHP v1.8.2 2023-04-29
# NexusPHP v1.8.4 2023-05-27

View File

@@ -95,7 +95,7 @@ login:
search:
paths:
- path: torrents.php
categories: [401, 402, 403, 404, 405, 406, 408, 409, 411, 412, 413, 420, 430, 431, 432, 450, 451, 490]
categories: ["!", 440, 441, 442, 443, 444, 445, 446, 447]
- path: adults.php
categories: [440, 441, 442, 443, 444, 445, 446, 447]
inputs:

View File

@@ -120,7 +120,7 @@ download:
search:
paths:
- path: viewno18sb.php
categories: [1, 75, 10, 9, 110, 7, 40, 16, 3, 70, 100, 85, 105, 8, 56, 19, 20, 55, 21, 2, 130, 60, 90, 91, 92, 89, 93, 4, 50, 18, 17, 11, 5, 54, 51, 52, 57, 53]
categories: ["!", 901, 902, 903, 904, 905, 906, 907, 908, 910, 911, 912]
- path: viewbrsb.php
categories: [901, 902, 903, 904, 905, 906, 907, 908, 910, 911, 912]
inputs:

View File

@@ -144,7 +144,7 @@ login:
search:
paths:
- path: torrents.php
categories: [409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453]
categories: ["!", 435]
- path: special.php
categories: [435]
inputs:

View File

@@ -89,6 +89,7 @@ caps:
- {id: 208, cat: Other, desc: "Business : Marketing"}
- {id: 25, cat: Other, desc: "Exam Prep / Education"}
- {id: 204, cat: Other, desc: "Parapsychology"}
- {id: 215, cat: Other, desc: "Sexuality/Seductn/Body Img"}
modes:
search: [q]

View File

@@ -112,7 +112,6 @@ search:
sortField: "{{ .Config.sort }}"
sortDirection: "{{ .Config.type }}"
perPage: 100
page: 1
keywordsfilters:
- name: re_replace
@@ -211,4 +210,4 @@ search:
minimumseedtime:
# 2 days (as seconds = 2 x 24 x 60 x 60)
text: 172800
# json UNIT3D custom edition 1.0.2 (based on 6.5.0)
# json UNIT3D custom edition 1.0.1 (based on 6.5.0)

View File

@@ -56,6 +56,7 @@ caps:
movie-search: [q]
music-search: [q]
book-search: [q]
allowrawsearch: true
settings:
- name: downloadlink
@@ -92,6 +93,11 @@ search:
$raw: "{{ range .Categories }}s_cat={{.}}&{{end}}"
search: "{{ .Keywords }}"
keywordsfilters:
- name: re_replace
args: ["\\W+", " "]
- name: trim
rows:
selector: div.inner_container > div:has(p:has(a[href^="/torrent/"])):not(:has(span.__cf_email__))

View File

@@ -0,0 +1,168 @@
---
id: torrenteros-api
name: Torrenteros (API)
description: "Torrenteros (TTR) is a SPANISH site for MOVIES / TV / GENERAL"
language: es-ES
type: private
encoding: UTF-8
links:
- https://torrenteros.org/
caps:
categorymappings:
- {id: 1, cat: Movies, desc: "Movies"}
- {id: 2, cat: TV, desc: "TV"}
- {id: 3, cat: Audio, desc: "Music"}
- {id: 4, cat: Console, desc: "Game"}
- {id: 5, cat: PC, desc: "Application"}
- {id: 6, cat: Books, desc: "Libros"}
modes:
search: [q]
tv-search: [q, season, ep, imdbid, tvdbid, tmdbid]
movie-search: [q, imdbid, tmdbid]
music-search: [q]
book-search: [q]
settings:
- name: apikey
type: text
label: APIKey
- name: info_key
type: info
label: About your API key
default: "Find or Generate a new API Token by accessing your <a href=\"https://torrenteros.org/\" target=\"_blank\">TTR</a> account <i>My Security</i> page and clicking on the <b>API Token</b> tab."
- name: freeleech
type: checkbox
label: Search freeleech only
default: false
- name: sort
type: select
label: Sort requested from site
default: created_at
options:
created_at: created
seeders: seeders
size: size
name: title
- name: type
type: select
label: Order requested from site
default: desc
options:
desc: desc
asc: asc
login:
path: /api/torrents
method: get
inputs:
api_token: "{{ .Config.apikey }}"
error:
- selector: a[href*="/login"]
message:
text: "The API key was not accepted by {{ .Config.sitelink }}."
search:
paths:
# https://hdinnovations.github.io/UNIT3D-Community-Edition-Docs/api_endpoints.html
# https://github.com/HDInnovations/UNIT3D-Community-Edition/blob/master/app/Http/Controllers/API/TorrentController.php
- path: "/api/torrents/filter"
response:
type: json
inputs:
# if we have an id based search, add Season and Episode as query in name for UNIT3D < v6. Else pass S/E Params for UNIT3D >= v6
api_token: "{{ .Config.apikey }}"
$raw: "{{ range .Categories }}&categories[]={{.}}{{end}}"
name: "{{ .Keywords }}"
seasonNumber: "{{ .Query.Season }}"
episodeNumber: "{{ .Query.Ep }}"
imdbId: "{{ .Query.IMDBIDShort }}"
tmdbId: "{{ .Query.TMDBID }}"
tvdbId: "{{ .Query.TVDBID }}"
"free[]": "{{ if .Config.freeleech }}100{{ else }}{{ end }}"
sortField: "{{ .Config.sort }}"
sortDirection: "{{ .Config.type }}"
perPage: 100
keywordsfilters:
- name: re_replace
args: ["\\.", " "]
rows:
selector: data
attribute: attributes
fields:
category:
selector: category_id
title:
selector: name
details:
selector: details_link
download:
selector: download_link
infohash:
selector: info_hash
poster:
selector: meta.poster
filters:
- name: replace
args: ["https://via.placeholder.com/90x135", ""]
imdbid:
selector: imdb_id
tmdbid:
selector: tmdb_id
tvdbid:
selector: tvdb_id
genre:
selector: meta.genres
filters:
- name: re_replace
args: ["(?i)(Ciencia ficción)", "Ciencia_ficción"]
- name: replace
args: [" & ", "_&_"]
description:
text: "{{ .Result.genre }}"
files:
selector: num_file
seeders:
selector: seeders
leechers:
selector: leechers
grabs:
selector: times_completed
date:
# "created_at": "2021-10-18T00:34:50.000000Z" is returned by Newtonsoft.Json.Linq as 18/10/2021 00:34:50
selector: created_at
filters:
- name: append
args: " +00:00" # GMT
- name: dateparse
args: "MM/dd/yyyy HH:mm:ss zzz"
size:
selector: size
downloadvolumefactor:
# api returns 0%, 25%, 50%, 75%, 100%
selector: freeleech
case:
0%: 1 # not free
25%: 0.75
50%: 0.5
75%: 0.25
100%: 0 # freeleech
"*": 0 # catch errors
uploadvolumefactor:
# api returns 0=false, 1=true
selector: double_upload
case:
0: 1 # normal
1: 2 # double
# global MR is 0.4 but torrents must be seeded for 7 days regardless of ratio
# minimumratio:
# text: 0.4
minimumseedtime:
# 7 days (as seconds = 7 x 24 x 60 x 60)
text: 604800
# json UNIT3D 6.5.0

View File

@@ -122,7 +122,8 @@ settings:
login:
path: user/account/login/
method: post
method: form
form: form[name="login-form"]
inputs:
username: "{{ .Config.username }}"
password: "{{ .Config.password }}"
@@ -132,6 +133,9 @@ login:
- selector: .login-container h2:contains("One Time Password")
message:
text: "Your TorrentLeech account has 2FA enabled. Please recheck your indexer settings."
- selector: form[name="login-form"]
message:
text: "Login page detected at {{ .Config.sitelink }}."
test:
path: /
selector: a[href="/user/account/logout"]

View File

@@ -7,9 +7,8 @@ type: public
encoding: UTF-8
followredirect: true
links:
- https://torrentqq258.com/
- https://torrentqq259.com/
legacylinks:
- https://torrentqq243.com/
- https://torrentqq244.com/
- https://torrentqq245.com/. # typo
- https://torrentqq245.com/
@@ -25,6 +24,7 @@ legacylinks:
- https://torrentqq255.com/
- https://torrentqq256.com/
- https://torrentqq257.com/
- https://torrentqq258.com/
caps:
categorymappings:

View File

@@ -5,6 +5,7 @@ description: "Torrentz2eu is a Public torrent meta-search engine"
language: en-US
type: public
encoding: UTF-8
requestDelay: 2
followredirect: true
links:
- https://2torrentz2eu.in/
@@ -44,16 +45,24 @@ search:
paths:
# https://2torrentz2eu.in/beta2/search.php?torrent-query=2023
- path: beta2/search.php
- path: beta2/search.php
inputs:
page: 2
inputs:
torrent-query: "{{ if .Keywords }}{{ .Keywords }}{{ else }}{{ .Today.Year }}{{ end }}"
rows:
selector: table#torrent-table > tbody > tr
fields:
category:
text: 3
title:
selector: td:nth-child(1)
category_is_tv_show:
text: "{{ .Result.title }}"
filters:
- name: regexp
args: "\\b(S\\d+(?:E\\d+)?)\\b"
category:
text: "{{ if .Result.category_is_tv_show }}2{{ else }}3{{ end }}"
details:
# https://torrentz2.pics/beta2/page.php?url=9999999%2FThe-Torrent-file-name-goes-here%2F
selector: td:nth-child(6) button
@@ -77,7 +86,7 @@ search:
- name: re_replace
args: ["(?i)(st|nd|rd|th|'|\\.)", ""]
- name: dateparse
args: "MMM. dd yy"
args: "MMM dd yy"
downloadvolumefactor:
text: 0
uploadvolumefactor:

View File

@@ -181,4 +181,4 @@ search:
description:
selector: td:nth-child(2)
remove: a, b, font, img, span
# NexusPHP v1.8.2 2023-05-08
# NexusPHP v1.8.4 2023-05-27

View File

@@ -162,4 +162,4 @@ search:
description:
selector: td:nth-child(2)
remove: a, b, font, img, span
# NexusPHP v1.8.2 2023-04-30
# NexusPHP v1.8.4 2023-06-05

View File

@@ -10,11 +10,10 @@ links:
caps:
categories:
Audio: Audio
PC: PC
modes:
search: [q]
music-search: [q]
settings: []
@@ -39,7 +38,7 @@ search:
fields:
category:
text: Audio
text: PC
title:
selector: div.eTitle a
details:

View File

@@ -0,0 +1,61 @@
---
id: vstorrent
name: VSTorrent
description: "VSTorrent is a Public site for AUDIO apps, plugins and samples"
language: en-US
type: public
encoding: UTF-8
links:
- https://vstorrent.org/
caps:
categories:
PC: PC
modes:
search: [q]
settings: []
download:
selectors:
- selector: a[href^="magnet:?xt"]
attribute: href
search:
paths:
- path: /
inputs:
s: "{{ .Keywords }}"
rows:
selector: article:has(.entry-title)
filters:
- name: andmatch
fields:
category:
text: PC
title:
selector: .entry-title
details:
selector: .entry-title > a
attribute: href
download:
selector: .entry-title > a
attribute: href
description:
selector: .entry-summary
date:
selector: span.date
size:
text: "512 MB"
seeders:
text: 1
leechers:
text: 1
downloadvolumefactor:
text: 0
uploadvolumefactor:
text: 1
# wordpress 6.2.2

View File

@@ -1,7 +1,7 @@
---
id: vsttorrents
name: VST Torrents
description: "VST Torrents is a Public site for AUDIO apps, plugins and samples"
name: VST Torrentz
description: "VST Torrentz is a Public site for AUDIO apps, plugins and samples"
language: en-US
type: public
encoding: UTF-8
@@ -13,11 +13,10 @@ legacylinks:
caps:
categories:
Audio: Audio
PC: PC
modes:
search: [q]
music-search: [q]
settings: []
@@ -39,7 +38,7 @@ search:
fields:
category:
text: Audio
text: PC
title:
selector: .entry-title
details:
@@ -51,7 +50,8 @@ search:
description:
selector: .entry-excerpt
date:
text: now
selector: time
attribute: datetime
size:
text: "512 MB"
seeders:
@@ -62,4 +62,4 @@ search:
text: 0
uploadvolumefactor:
text: 1
# wordpress 6.0.3
# wordpress 6.2.2

View File

@@ -31,6 +31,11 @@ settings:
desc: desc
asc: asc
download:
selectors:
- selector: a[href^="/torrents/download/"]
attribute: href
search:
paths:
# https://xxxclub.to/torrents/browse/all/tushyraw%20grays?sort=size&order=asc
@@ -43,30 +48,30 @@ search:
category:
text: XXX
title:
selector: td:nth-child(2)
selector: a[href^="/torrents/details/"]
details:
selector: td:nth-child(2) a
selector: a[href^="/torrents/details/"]
attribute: href
download:
selector: td:nth-child(3) a
selector: a[href^="/torrents/details/"]
attribute: href
poster:
selector: td:nth-child(2) a
selector: a[href^="/torrents/details/"]
attribute: title
filters:
- name: regexp
args: src='(.+?)'
date:
selector: td:nth-child(4)
selector: td:nth-child(3)
filters:
- name: dateparse
args: "dd MMM yyyy HH:mm:ss"
size:
selector: td:nth-child(5)
selector: td:nth-child(4)
seeders:
selector: td:nth-child(6)
selector: td:nth-child(5)
leechers:
selector: td:nth-child(7)
selector: td:nth-child(6)
downloadvolumefactor:
text: 0
uploadvolumefactor:

View File

@@ -61,12 +61,13 @@ search:
type: json
inputs:
# ignore ' (e.g. search for america's Next Top Model)
query_term: "{{ if .Query.IMDBID }}{{ .Query.IMDBID }}{{ else }}{{ .Keywords }}{{ end }}"
# without this the API sometimes returns nothing
limit: 50
sort: date_added
sort_by: date_added
order_by: desc
keywordsfilters:
# ignore ' (e.g. search for america's Next Top Model)
- name: re_replace
args: ["[^\\w]+", " "]

View File

@@ -186,4 +186,4 @@ search:
description:
selector: td.rowfollow:nth-child(2)
remove: a, b, font, img, span
# NexusPHP v1.8.2 2023-05-08
# NexusPHP v1.8.4 2023-05-27

View File

@@ -0,0 +1,12 @@
using System.Collections.Generic;
using System.Linq;
namespace Jackett.Common.Extensions
{
public static class ListExtensions
{
public static List<List<T>> ChunkBy<T>(this List<T> source, int chunkSize) => source
.Select((x, i) => new { Index = i, Value = x }).GroupBy(x => x.Index / chunkSize)
.Select(x => x.Select(v => v.Value).ToList()).ToList();
}
}

View File

@@ -6,7 +6,7 @@ using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Jackett.Common.Models;
using Jackett.Common.Models.IndexerConfig;
using Jackett.Common.Models.IndexerConfig.Bespoke;
using Jackett.Common.Services.Interfaces;
using Jackett.Common.Utils;
using Jackett.Common.Utils.Clients;
@@ -35,7 +35,7 @@ namespace Jackett.Common.Indexers.Abstract
private string SearchUrl => SiteLink + "api/torrent";
private string _token;
private new ConfigurationDataBasicLoginWithEmail configData => (ConfigurationDataBasicLoginWithEmail)base.configData;
private new ConfigurationDataSpeedAppTracker configData => (ConfigurationDataSpeedAppTracker)base.configData;
protected SpeedAppTracker(IIndexerConfigurationService configService, WebClient client, Logger logger, IProtectionService p, ICacheService cs)
: base(configService: configService,
@@ -43,7 +43,7 @@ namespace Jackett.Common.Indexers.Abstract
logger: logger,
p: p,
cacheService: cs,
configData: new ConfigurationDataBasicLoginWithEmail())
configData: new ConfigurationDataSpeedAppTracker())
{
}
@@ -120,8 +120,17 @@ namespace Jackett.Common.Indexers.Abstract
try
{
var rows = JArray.Parse(response.ContentString);
foreach (var row in rows)
{
var dlVolumeFactor = row.Value<double>("download_volume_factor");
// skip non-freeleech results when freeleech only is set
if (configData.FreeleechOnly.Value && dlVolumeFactor != 0)
{
continue;
}
var id = row.Value<string>("id");
var link = new Uri($"{SiteLink}api/torrent/{id}/download");
var urlStr = row.Value<string>("url");
@@ -141,9 +150,6 @@ namespace Jackett.Common.Indexers.Abstract
var posterStr = row.Value<string>("poster");
var poster = Uri.TryCreate(posterStr, UriKind.Absolute, out var posterUri) ? posterUri : null;
var dlVolumeFactor = row.Value<double>("download_volume_factor");
var ulVolumeFactor = row.Value<double>("upload_volume_factor");
var title = row.Value<string>("name");
// fix for #10883
if (UseP2PReleaseName && !string.IsNullOrWhiteSpace(row.Value<string>("p2p_release_name")))
@@ -167,7 +173,7 @@ namespace Jackett.Common.Indexers.Abstract
Seeders = row.Value<int>("seeders"),
Peers = row.Value<int>("leechers") + row.Value<int>("seeders"),
DownloadVolumeFactor = dlVolumeFactor,
UploadVolumeFactor = ulVolumeFactor,
UploadVolumeFactor = row.Value<double>("upload_volume_factor"),
MinimumRatio = 1,
MinimumSeedTime = minimumSeedTime
};

View File

@@ -555,10 +555,14 @@ namespace Jackett.Common.Indexers
if (Login.Method == "post")
{
var pairs = new Dictionary<string, string>();
foreach (var Input in Definition.Login.Inputs)
if (Login.Inputs != null && Login.Inputs.Any())
{
var value = applyGoTemplateText(Input.Value);
pairs.Add(Input.Key, value);
foreach (var input in Login.Inputs)
{
var value = applyGoTemplateText(input.Value);
pairs.Add(input.Key, value);
}
}
var LoginUrl = resolvePath(Login.Path).ToString();
@@ -628,18 +632,27 @@ namespace Jackett.Common.Indexers
pairs[name] = value;
}
foreach (var Input in Definition.Login.Inputs)
if (Login.Inputs != null && Login.Inputs.Any())
{
var value = applyGoTemplateText(Input.Value);
var input = Input.Key;
if (Login.Selectors)
foreach (var Input in Login.Inputs)
{
var inputElement = landingResultDocument.QuerySelector(Input.Key);
if (inputElement == null)
throw new ExceptionWithConfigData(string.Format("Login failed: No input found using selector {0}", Input.Key), configData);
input = inputElement.GetAttribute("name");
var value = applyGoTemplateText(Input.Value);
var input = Input.Key;
if (Login.Selectors)
{
var inputElement = landingResultDocument.QuerySelector(Input.Key);
if (inputElement == null)
{
throw new ExceptionWithConfigData($"Login failed: No input found using selector {Input.Key}", configData);
}
input = inputElement.GetAttribute("name");
}
pairs[input] = value;
}
pairs[input] = value;
}
// selector inputs
@@ -772,18 +785,22 @@ namespace Jackett.Common.Indexers
else if (Login.Method == "get")
{
var queryCollection = new NameValueCollection();
foreach (var Input in Definition.Login.Inputs)
if (Login.Inputs != null && Login.Inputs.Any())
{
var value = applyGoTemplateText(Input.Value);
queryCollection.Add(Input.Key, value);
foreach (var input in Login.Inputs)
{
var value = applyGoTemplateText(input.Value);
queryCollection.Add(input.Key, value);
}
}
var LoginUrl = resolvePath(Login.Path + "?" + queryCollection.GetQueryString()).ToString();
var loginUrl = resolvePath(Login.Path + "?" + queryCollection.GetQueryString()).ToString();
configData.CookieHeader.Value = null;
var loginResult = await RequestWithCookiesAsync(LoginUrl, referer: SiteLink, headers: headers);
var loginResult = await RequestWithCookiesAsync(loginUrl, referer: SiteLink, headers: headers);
configData.CookieHeader.Value = loginResult.Cookies;
checkForError(loginResult, Definition.Login.Error);
checkForError(loginResult, Login.Error);
}
else if (Login.Method == "oneurl")
{
@@ -793,11 +810,11 @@ namespace Jackett.Common.Indexers
var loginResult = await RequestWithCookiesAsync(LoginUrl, referer: SiteLink, headers: headers);
configData.CookieHeader.Value = loginResult.Cookies;
checkForError(loginResult, Definition.Login.Error);
checkForError(loginResult, Login.Error);
}
else
{
throw new NotImplementedException("Login method " + Definition.Login.Method + " not implemented");
throw new NotImplementedException($"Login method {Login.Method} not implemented");
}
logger.Debug($"CardigannIndexer ({Id}): Cookies after login: {CookieHeader}");
@@ -1349,8 +1366,6 @@ namespace Jackett.Common.Indexers
mappedCategories = DefaultCategories;
}
variables[".Categories"] = mappedCategories;
var KeywordTokens = new List<string>();
var KeywordTokenKeys = new List<string> { "Q", "Series", "Movie", "Year" };
foreach (var key in KeywordTokenKeys)
@@ -1369,15 +1384,26 @@ namespace Jackett.Common.Indexers
var SearchPaths = Search.Paths;
foreach (var SearchPath in SearchPaths)
{
variables[".Categories"] = mappedCategories;
// skip path if categories don't match
if (SearchPath.Categories.Count > 0)
{
var invertMatch = (SearchPath.Categories[0] == "!");
var hasIntersect = mappedCategories.Intersect(SearchPath.Categories).Any();
if (invertMatch)
if (SearchPath.Categories[0] == "!")
{
hasIntersect = !hasIntersect;
}
if (!hasIntersect)
{
variables[".Categories"] = mappedCategories.Except(SearchPath.Categories).ToList();
continue;
}
variables[".Categories"] = mappedCategories.Intersect(SearchPath.Categories).ToList();
}
// build search URL
@@ -1448,18 +1474,24 @@ namespace Jackett.Common.Indexers
if (SearchPath.Response != null && SearchPath.Response.Type.Equals("json"))
{
if (response.Status != HttpStatusCode.OK)
{
throw new Exception($"Error Parsing Json Response: Status={response.Status} Response={results}");
}
if (response.Status == HttpStatusCode.OK
&& SearchPath.Response != null
&& SearchPath.Response.NoResultsMessage != null
&& (SearchPath.Response.NoResultsMessage != string.Empty && results.Contains(SearchPath.Response.NoResultsMessage) || (SearchPath.Response.NoResultsMessage == string.Empty && results == string.Empty)))
{
continue;
}
var parsedJson = JToken.Parse(results);
if (parsedJson == null)
{
throw new Exception("Error Parsing Json Response");
}
if (Search.Rows.Count != null)
{
@@ -1483,7 +1515,9 @@ namespace Jackett.Common.Indexers
if (rowsArray == null)
{
if (Search.Rows.MissingAttributeEqualsNoResults)
{
continue;
}
throw new Exception("Error Parsing Rows Selector. There are 0 rows.");
}
@@ -1495,7 +1529,18 @@ namespace Jackett.Common.Indexers
foreach (var Row in rowsArray)
{
var selObj = Search.Rows.Attribute != null ? Row.SelectToken(Search.Rows.Attribute).Value<JToken>() : Row;
var selObj = Row;
if (Search.Rows.Attribute != null)
{
selObj = Row.SelectToken(Search.Rows.Attribute)?.Value<JToken>();
if (selObj == null && Search.Rows.MissingAttributeEqualsNoResults)
{
continue;
}
}
var mulRows = Search.Rows.Multiple ? selObj.Values<JObject>() : new List<JObject> { selObj.Value<JObject>() };
foreach (var mulRow in mulRows)

View File

@@ -13,6 +13,7 @@ using Jackett.Common.Services.Interfaces;
using Jackett.Common.Utils.Clients;
using Newtonsoft.Json.Linq;
using NLog;
using static System.Net.WebRequestMethods;
using WebClient = Jackett.Common.Utils.Clients.WebClient;
namespace Jackett.Common.Indexers
@@ -23,7 +24,7 @@ namespace Jackett.Common.Indexers
public override string Id => "cinecalidad";
public override string Name => "Cinecalidad";
public override string Description => "Películas Full HD en Latino Dual.";
public override string SiteLink { get; protected set; } = "https://www3.cinecalidad.ms/";
public override string SiteLink { get; protected set; } = "https://www.cinecalidad.tf/";
public override string[] LegacySiteLinks => new[]
{
"https://cinecalidad.website/",
@@ -41,7 +42,10 @@ namespace Jackett.Common.Indexers
"https://www.cine-calidad.com/",
"https://www.cinecalidad.lat/",
"https://cinecalidad.dev/",
"https://cinecalidad.ms/"
"https://cinecalidad.ms/",
"https://www3.cinecalidad.ms/",
"https://ww1.cinecalidad.ms/",
"https://www.cinecalidad.gs/"
};
public override string Language => "es-419";
public override string Type => "public";

View File

@@ -25,10 +25,10 @@ namespace Jackett.Common.Indexers
public override string Id => "dontorrent";
public override string Name => "DonTorrent";
public override string Description => "DonTorrent is a SPANISH public tracker for MOVIES / TV / GENERAL";
public override string SiteLink { get; protected set; } = "https://dontorrent.dad/";
public override string SiteLink { get; protected set; } = "https://dontorrent.zip/";
public override string[] AlternativeSiteLinks => new[]
{
"https://dontorrent.dad/",
"https://dontorrent.zip/",
"https://todotorrents.net/",
"https://tomadivx.net/",
"https://seriesblanco.one/",
@@ -52,6 +52,7 @@ namespace Jackett.Common.Indexers
"https://dontorrent.observer/",
"https://dontorrent.company/",
"https://dontorrent.discount/",
"https://dontorrent.dad/",
};
public override string Language => "es-ES";
public override string Type => "public";

View File

@@ -133,27 +133,37 @@ namespace Jackett.Common.Indexers
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, null, LoginUrl);
await ConfigureIfOK(
result.Cookies, result.ContentString?.Contains("If your browser doesn't have javascript enabled") == true,
() => throw new ExceptionWithConfigData("Couldn't login", configData));
result.Cookies, result.ContentString?.Contains("If your browser doesn't have javascript enabled") == true, () =>
{
var parser = new HtmlParser();
var dom = parser.ParseDocument(result.ContentString);
var errorMessage = dom.QuerySelector("div > font[color=\"#FF0000\"]")?.TextContent.Trim();
throw new ExceptionWithConfigData(errorMessage ?? "Couldn't login", configData);
});
return IndexerConfigurationStatus.RequiresTesting;
}
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>();
var searchUrl = SearchUrl + string.Join(
string.Empty, MapTorznabCapsToTrackers(query).Select(cat => $"category[]={cat}&"));
var searchUrl = SearchUrl + string.Join(string.Empty, MapTorznabCapsToTrackers(query).Select(cat => $"category[]={cat}&"));
var queryCollection = new NameValueCollection
{
{"search", query.ImdbID ?? query.GetQueryString()},
{"active", ((BoolConfigurationItem)configData.GetDynamic("freeleech")).Value ? "5" : "0"},
{"options", "0"}
{ "search", query.ImdbID ?? query.GetQueryString() },
{ "active", ((BoolConfigurationItem)configData.GetDynamic("freeleech")).Value ? "5" : "0" },
{ "options", "0" }
};
// manually url encode parenthesis to prevent "hacking" detection, remove . as not used in titles
searchUrl += queryCollection.GetQueryString().Replace("(", "%28").Replace(")", "%29").Replace(".", " ");
var results = await RequestWithCookiesAndRetryAsync(searchUrl);
try
{
var parser = new HtmlParser();
@@ -167,7 +177,10 @@ namespace Jackett.Common.Indexers
foreach (var row in rows.Skip(1))
{
if (row.Children.Length == 2)
continue; // fix bug with search: cohen
{
// fix bug with search: cohen
continue;
}
var mainLink = row.Children[2].QuerySelector("a");
var title = mainLink.TextContent;

View File

@@ -24,9 +24,10 @@ namespace Jackett.Common.Indexers
public override string Id => "lostfilm";
public override string Name => "LostFilm.tv";
public override string Description => "Unique portal about foreign series";
public override string SiteLink { get; protected set; } = "https://www.lostfilm.run/";
public override string SiteLink { get; protected set; } = "https://www.lostfilm.life/";
public override string[] AlternativeSiteLinks => new[]
{
"https://www.lostfilm.life/",
"https://www.lostfilm.run/",
"https://www.lostfilmtv.site/",
"https://www.lostfilm.tv/",
@@ -40,7 +41,7 @@ namespace Jackett.Common.Indexers
public override string[] LegacySiteLinks => new[]
{
"https://lostfilm.site",
"https://lostfilm.tw/",
"https://lostfilm.tw/"
};
public override string Language => "ru-RU";
public override string Type => "semi-private";

View File

@@ -1,336 +0,0 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Jackett.Common.Exceptions;
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
{
[ExcludeFromCodeCoverage]
public class RarBG : IndexerBase
{
public override string Id => "rarbg";
public override string Name => "RARBG";
public override string Description => "RARBG is a Public torrent site for MOVIES / TV / GENERAL";
public override string SiteLink { get; protected set; } = "https://rarbg.to/";
public override Encoding Encoding => Encoding.GetEncoding("windows-1252");
public override string Language => "en-US";
public override string Type => "public";
public override TorznabCapabilities TorznabCaps => SetCapabilities();
// API doc: https://torrentapi.org/apidocs_v2.txt?app_id=Jackett
private string ApiEndpoint => ((StringConfigurationItem)configData.GetDynamic("apiEndpoint")).Value;
private readonly TimeSpan TokenDuration = TimeSpan.FromMinutes(14); // 15 minutes expiration
private readonly string _appId;
private string _token;
private DateTime _lastTokenFetch;
private string _sort;
private new ConfigurationData configData => base.configData;
public RarBG(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l,
IProtectionService ps, ICacheService cs)
: base(configService: configService,
client: wc,
logger: l,
p: ps,
cacheService: cs,
configData: new ConfigurationData())
{
webclient.requestDelay = 5; // The api has a 1req/2s limit
var ConfigApiEndpoint = new StringConfigurationItem("API URL") { Value = "https://torrentapi.org/pubapi_v2.php" };
configData.AddDynamic("apiEndpoint", ConfigApiEndpoint);
var sort = new SingleSelectConfigurationItem("Sort requested from site", new Dictionary<string, string>
{
{"last", "created"},
{"seeders", "seeders"},
{"leechers", "leechers"}
})
{ Value = "last" };
configData.AddDynamic("sort", sort);
_appId = "ttekcaJ_" + EnvironmentUtil.JackettVersion();
}
private TorznabCapabilities SetCapabilities()
{
var caps = new TorznabCapabilities
{
TvSearchParams = new List<TvSearchParam>
{
TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep, TvSearchParam.ImdbId, TvSearchParam.TmdbId, TvSearchParam.TvdbId
},
MovieSearchParams = new List<MovieSearchParam>
{
MovieSearchParam.Q, MovieSearchParam.ImdbId, MovieSearchParam.TmdbId
},
MusicSearchParams = new List<MusicSearchParam>
{
MusicSearchParam.Q
},
TvSearchImdbAvailable = true
};
//caps.Categories.AddCategoryMapping(4, TorznabCatType.XXX, "XXX (18+)"); // 3x is not supported by API #11848
caps.Categories.AddCategoryMapping(14, TorznabCatType.MoviesSD, "Movies/XVID");
caps.Categories.AddCategoryMapping(17, TorznabCatType.MoviesSD, "Movies/x264");
caps.Categories.AddCategoryMapping(18, TorznabCatType.TVSD, "TV Episodes");
caps.Categories.AddCategoryMapping(23, TorznabCatType.AudioMP3, "Music/MP3");
caps.Categories.AddCategoryMapping(25, TorznabCatType.AudioLossless, "Music/FLAC");
caps.Categories.AddCategoryMapping(27, TorznabCatType.PCGames, "Games/PC ISO");
caps.Categories.AddCategoryMapping(28, TorznabCatType.PCGames, "Games/PC RIP");
caps.Categories.AddCategoryMapping(32, TorznabCatType.ConsoleXBox360, "Games/XBOX-360");
caps.Categories.AddCategoryMapping(33, TorznabCatType.PCISO, "Software/PC ISO");
caps.Categories.AddCategoryMapping(40, TorznabCatType.ConsolePS3, "Games/PS3");
caps.Categories.AddCategoryMapping(41, TorznabCatType.TVHD, "TV HD Episodes");
caps.Categories.AddCategoryMapping(42, TorznabCatType.MoviesBluRay, "Movies/Full BD");
caps.Categories.AddCategoryMapping(44, TorznabCatType.MoviesHD, "Movies/x264/1080");
caps.Categories.AddCategoryMapping(45, TorznabCatType.MoviesHD, "Movies/x264/720");
caps.Categories.AddCategoryMapping(46, TorznabCatType.MoviesBluRay, "Movies/BD Remux");
caps.Categories.AddCategoryMapping(47, TorznabCatType.Movies3D, "Movies/x264/3D");
caps.Categories.AddCategoryMapping(48, TorznabCatType.MoviesHD, "Movies/XVID/720");
caps.Categories.AddCategoryMapping(49, TorznabCatType.TVUHD, "TV UHD Episodes");
// torrentapi.org returns "Movies/TV-UHD-episodes" for some reason
// possibly because thats what the category is called on the /top100.php page
caps.Categories.AddCategoryMapping(49, TorznabCatType.TVUHD, "Movies/TV-UHD-episodes");
caps.Categories.AddCategoryMapping(50, TorznabCatType.MoviesUHD, "Movies/x264/4k");
caps.Categories.AddCategoryMapping(51, TorznabCatType.MoviesUHD, "Movies/x265/4k");
caps.Categories.AddCategoryMapping(52, TorznabCatType.MoviesUHD, "Movs/x265/4k/HDR");
caps.Categories.AddCategoryMapping(53, TorznabCatType.ConsolePS4, "Games/PS4");
caps.Categories.AddCategoryMapping(54, TorznabCatType.MoviesHD, "Movies/x265/1080");
return caps;
}
public override void LoadValuesFromJson(JToken jsonConfig, bool useProtectionService = false)
{
base.LoadValuesFromJson(jsonConfig, useProtectionService);
var sort = (SingleSelectConfigurationItem)configData.GetDynamic("sort");
_sort = sort != null ? sort.Value : "last";
}
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)
=> await PerformQueryWithRetry(query, true);
private async Task<IEnumerable<ReleaseInfo>> PerformQueryWithRetry(TorznabQuery query, bool retry)
{
var releases = new List<ReleaseInfo>();
// check the token and renewal if necessary
await RenewalTokenAsync();
var response = await RequestWithCookiesAsync(BuildSearchUrl(query));
var responseCode = (int)response.Status;
switch (responseCode)
{
case 429:
throw new TooManyRequestsException($"Rate limited with StatusCode {responseCode}, retry in 2 minutes", TimeSpan.FromMinutes(2));
case 520:
throw new TooManyRequestsException($"Rate limited with StatusCode {responseCode}, retry in 3 minutes", TimeSpan.FromMinutes(3));
case (int)HttpStatusCode.OK:
break;
default:
throw new Exception($"Indexer API call returned an unexpected StatusCode [{responseCode}]");
}
var jsonContent = JObject.Parse(response.ContentString);
var errorCode = jsonContent.Value<int>("error_code");
switch (errorCode)
{
case 0: // valid response with results
break;
case 2:
case 4: // invalid token
await RenewalTokenAsync(true); // force renewal token
response = await RequestWithCookiesAsync(BuildSearchUrl(query));
jsonContent = JObject.Parse(response.ContentString);
break;
case 5: // Too many requests per second. Maximum requests allowed are 1req/2sec Please try again later!
if (retry)
{
logger.Warn("torrentapi.org returned code 5 Too many requests per second, retrying after 5 secs");
return await PerformQueryWithRetry(query, false);
}
throw new TooManyRequestsException("Rate limited, retry in 2 minutes", TimeSpan.FromMinutes(2));
case 8: // search_imdb not found, see issue #12466 (no longer used, has been replaced with error 10)
case 9: // invalid imdb, see Radarr #1845
case 13: // invalid tmdb, invalid tvdb
return releases;
case 10: // imdb not found, see issue #1486
case 14: // tmdb not found (see Radarr #7625), thetvdb not found
case 20: // no results found
if (jsonContent.Value<int>("rate_limit") is 1 && jsonContent.Value<JArray>("torrent_results") == null)
throw new TooManyRequestsException("Rate limited, retry in 5 minutes", TimeSpan.FromMinutes(5));
// the api returns "no results" in some valid queries. we do one retry on this case but we can't do more
// because we can't distinguish between search without results and api malfunction
return retry ? await PerformQueryWithRetry(query, false) : releases;
default:
throw new Exception($"Unknown error code: {errorCode}. Response: {response.ContentString}");
}
if (jsonContent.Value<JArray>("torrent_results") == null)
return releases;
try
{
foreach (var item in jsonContent.Value<JArray>("torrent_results"))
{
var magnetStr = item.Value<string>("download");
var magnetUri = new Uri(magnetStr);
// #11021 we can't use the magnet link as guid because they are using random ports
var infoHash = magnetStr.Split(':')[3].Split('&')[0];
var guid = new Uri(SiteLink + "infohash/" + infoHash);
// append app_id to prevent api server returning 403 forbidden
var details = new Uri(item.Value<string>("info_page") + "&app_id=" + _appId);
var seeders = item.Value<int>("seeders");
var leechers = item.Value<int>("leechers");
var release = new ReleaseInfo
{
Guid = guid,
Details = details,
MagnetUri = magnetUri,
Title = WebUtility.HtmlDecode(item.Value<string>("title")).Trim(),
Category = MapTrackerCatDescToNewznab(item.Value<string>("category")),
InfoHash = infoHash,
PublishDate = DateTime.Parse(item.Value<string>("pubdate"), CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal),
Seeders = seeders,
Peers = leechers + seeders,
Size = item.Value<long>("size"),
DownloadVolumeFactor = 0,
UploadVolumeFactor = 1
};
var episodeInfo = item.Value<JToken>("episode_info");
if (episodeInfo.HasValues)
{
release.Imdb = ParseUtil.GetImdbId(episodeInfo.Value<string>("imdb"));
release.TVDBId = episodeInfo.Value<long?>("tvdb");
release.RageID = episodeInfo.Value<long?>("tvrage");
release.TMDb = episodeInfo.Value<long?>("themoviedb");
}
releases.Add(release);
}
}
catch (Exception ex)
{
OnParseError(response.ContentString, ex);
}
return releases;
}
private string BuildSearchUrl(TorznabQuery query)
{
var searchString = query.GetQueryString();
var episodeSearchString = query.GetEpisodeSearchString();
var qc = new NameValueCollection
{
{ "token", _token },
{ "format", "json_extended" },
{ "app_id", _appId },
{ "limit", "100" },
{ "ranked", "0" },
{ "sort", _sort }
};
if (query.IsTVSearch && !string.IsNullOrWhiteSpace(episodeSearchString) && query.ImdbID != null)
{
qc.Add("mode", "search");
qc.Add("search_imdb", query.ImdbID);
qc.Add("search_string", episodeSearchString);
}
else if (query.ImdbID != null)
{
qc.Add("mode", "search");
qc.Add("search_imdb", query.ImdbID);
}
else if (query.TmdbID != null)
{
qc.Add("mode", "search");
qc.Add("search_themoviedb", query.TmdbID.ToString());
}
else if (query.IsTVSearch && query.TvdbID != null)
{
qc.Add("mode", "search");
qc.Add("search_tvdb", query.TvdbID.ToString());
}
else if (!string.IsNullOrWhiteSpace(searchString))
{
// ignore ' (e.g. search for america's Next Top Model)
searchString = searchString.Replace("'", "");
qc.Add("mode", "search");
qc.Add("search_string", searchString);
}
else
{
qc.Add("mode", "list");
qc.Remove("sort");
}
var querycats = MapTorznabCapsToTrackers(query);
if (querycats.Count == 0)
// default to all, without specifying it some categories are missing (e.g. games), see #4146
querycats = GetAllTrackerCategories();
var cats = string.Join(";", querycats);
qc.Add("category", cats);
webclient.requestDelay = qc.Get("mode") == "list" ? 31 : 5;
return ApiEndpoint + "?" + qc.GetQueryString();
}
private async Task RenewalTokenAsync(bool force = false)
{
if (!HasValidToken || force)
{
var qc = new NameValueCollection
{
{ "get_token", "get_token" },
{ "app_id", _appId }
};
var tokenUrl = ApiEndpoint + "?" + qc.GetQueryString();
var result = await RequestWithCookiesAndRetryAsync(tokenUrl);
var json = JObject.Parse(result.ContentString);
_token = json.Value<string>("token");
_lastTokenFetch = DateTime.Now;
}
}
private bool HasValidToken => !string.IsNullOrEmpty(_token) && _lastTokenFetch > DateTime.Now - TokenDuration;
}
}

View File

@@ -8,6 +8,7 @@ using System.Text.RegularExpressions;
using System.Threading.Tasks;
using AngleSharp.Dom;
using AngleSharp.Html.Parser;
using Jackett.Common.Extensions;
using Jackett.Common.Models;
using Jackett.Common.Models.IndexerConfig;
using Jackett.Common.Models.IndexerConfig.Bespoke;
@@ -119,7 +120,6 @@ namespace Jackett.Common.Indexers
caps.Categories.AddCategoryMapping(2220, TorznabCatType.MoviesDVD, "|- Индийское кино (DVD Video)");
caps.Categories.AddCategoryMapping(1670, TorznabCatType.MoviesDVD, "|- Грайндхаус (DVD Video)");
caps.Categories.AddCategoryMapping(2198, TorznabCatType.MoviesHD, "HD Video");
caps.Categories.AddCategoryMapping(1457, TorznabCatType.MoviesUHD, "|- UHD Video");
caps.Categories.AddCategoryMapping(2199, TorznabCatType.MoviesHD, "|- Классика мирового кинематографа (HD Video)");
caps.Categories.AddCategoryMapping(313, TorznabCatType.MoviesHD, "|- Зарубежное кино (HD Video)");
caps.Categories.AddCategoryMapping(312, TorznabCatType.MoviesHD, "|- Наше кино (HD Video)");
@@ -128,6 +128,12 @@ namespace Jackett.Common.Indexers
caps.Categories.AddCategoryMapping(2339, TorznabCatType.MoviesHD, "|- Арт-хаус и авторское кино (HD Video)");
caps.Categories.AddCategoryMapping(140, TorznabCatType.MoviesHD, "|- Индийское кино (HD Video)");
caps.Categories.AddCategoryMapping(194, TorznabCatType.MoviesHD, "|- Грайндхаус (HD Video)");
caps.Categories.AddCategoryMapping(718, TorznabCatType.MoviesUHD, "UHD Video");
caps.Categories.AddCategoryMapping(775, TorznabCatType.MoviesUHD, "|- Классика мирового кинематографа (UHD Video)");
caps.Categories.AddCategoryMapping(1457, TorznabCatType.MoviesUHD, "|- Зарубежное кино (UHD Video)");
caps.Categories.AddCategoryMapping(1940, TorznabCatType.MoviesUHD, "|- Наше кино (UHD Video)");
caps.Categories.AddCategoryMapping(272, TorznabCatType.MoviesUHD, "|- Азиатские фильмы (UHD Video)");
caps.Categories.AddCategoryMapping(271, TorznabCatType.MoviesUHD, "|- Арт-хаус и авторское кино (UHD Video)");
caps.Categories.AddCategoryMapping(352, TorznabCatType.Movies3D, "3D/Стерео Кино, Видео, TV и Спорт");
caps.Categories.AddCategoryMapping(549, TorznabCatType.Movies3D, "|- 3D Кинофильмы");
caps.Categories.AddCategoryMapping(1213, TorznabCatType.Movies3D, "|- 3D Мультфильмы");
@@ -152,6 +158,7 @@ namespace Jackett.Common.Indexers
caps.Categories.AddCategoryMapping(815, TorznabCatType.TVSD, "|- Мультсериалы (SD Video)");
caps.Categories.AddCategoryMapping(816, TorznabCatType.TVHD, "|- Мультсериалы (DVD Video)");
caps.Categories.AddCategoryMapping(1460, TorznabCatType.TVHD, "|- Мультсериалы (HD Video)");
caps.Categories.AddCategoryMapping(498, TorznabCatType.TVUHD, "|- Мультсериалы (UHD Video)");
caps.Categories.AddCategoryMapping(33, TorznabCatType.TVAnime, "Аниме");
caps.Categories.AddCategoryMapping(1106, TorznabCatType.TVAnime, "|- Онгоинги (HD Video)");
caps.Categories.AddCategoryMapping(1105, TorznabCatType.TVAnime, "|- Аниме (HD Video)");
@@ -231,7 +238,6 @@ namespace Jackett.Common.Indexers
caps.Categories.AddCategoryMapping(1949, TorznabCatType.TVHD, "|- Черное зеркало / Black Mirror (HD Video)");
caps.Categories.AddCategoryMapping(1498, TorznabCatType.TVHD, "|- Для некондиционных раздач (HD Video)");
caps.Categories.AddCategoryMapping(911, TorznabCatType.TVForeign, "Сериалы Латинской Америки, Турции и Индии");
caps.Categories.AddCategoryMapping(1493, TorznabCatType.TVForeign, "|- Актёры и актрисы латиноамериканских сериалов");
caps.Categories.AddCategoryMapping(325, TorznabCatType.TVForeign, "|- Сериалы Аргентины");
caps.Categories.AddCategoryMapping(534, TorznabCatType.TVForeign, "|- Сериалы Бразилии");
caps.Categories.AddCategoryMapping(594, TorznabCatType.TVForeign, "|- Сериалы Венесуэлы");
@@ -239,11 +245,8 @@ namespace Jackett.Common.Indexers
caps.Categories.AddCategoryMapping(607, TorznabCatType.TVForeign, "|- Сериалы Колумбии");
caps.Categories.AddCategoryMapping(1574, TorznabCatType.TVForeign, "|- Сериалы Латинской Америки с озвучкой (раздачи папками)");
caps.Categories.AddCategoryMapping(1539, TorznabCatType.TVForeign, "|- Сериалы Латинской Америки с субтитрами");
caps.Categories.AddCategoryMapping(1940, TorznabCatType.TVForeign, "|- Официальные краткие версии сериалов Латинской Америки");
caps.Categories.AddCategoryMapping(694, TorznabCatType.TVForeign, "|- Сериалы Мексики");
caps.Categories.AddCategoryMapping(775, TorznabCatType.TVForeign, "|- Сериалы Перу, Сальвадора, Чили и других стран");
caps.Categories.AddCategoryMapping(781, TorznabCatType.TVForeign, "|- Сериалы совместного производства");
caps.Categories.AddCategoryMapping(718, TorznabCatType.TVForeign, "|- Сериалы США (латиноамериканские)");
caps.Categories.AddCategoryMapping(704, TorznabCatType.TVForeign, "|- Сериалы Турции");
caps.Categories.AddCategoryMapping(1537, TorznabCatType.TVForeign, "|- Для некондиционных раздач");
caps.Categories.AddCategoryMapping(2100, TorznabCatType.TVForeign, "Азиатские сериалы");
@@ -381,7 +384,7 @@ namespace Jackett.Common.Indexers
caps.Categories.AddCategoryMapping(1229, TorznabCatType.TVSport, "|- Чемпионат Мира 2022 (финальный турнир)");
caps.Categories.AddCategoryMapping(1693, TorznabCatType.TVSport, "|- Чемпионат Мира 2022 (отбор)");
caps.Categories.AddCategoryMapping(2532, TorznabCatType.TVSport, "|- Чемпионат Европы 2020 [2021] (финальный турнир)");
caps.Categories.AddCategoryMapping(136, TorznabCatType.TVSport, "|- Чемпионат Европы 2020 [2021] (отбор)");
caps.Categories.AddCategoryMapping(136, TorznabCatType.TVSport, "|- Чемпионат Европы 2024 (отбор)");
caps.Categories.AddCategoryMapping(592, TorznabCatType.TVSport, "|- Лига Наций");
caps.Categories.AddCategoryMapping(2533, TorznabCatType.TVSport, "|- Чемпионат Мира 2018 (игры)");
caps.Categories.AddCategoryMapping(1952, TorznabCatType.TVSport, "|- Чемпионат Мира 2018 (обзорные передачи, документалистика)");
@@ -427,8 +430,7 @@ namespace Jackett.Common.Indexers
caps.Categories.AddCategoryMapping(1527, TorznabCatType.TVSport, "|- International Wrestling");
caps.Categories.AddCategoryMapping(2069, TorznabCatType.TVSport, "|- Oldschool Wrestling");
caps.Categories.AddCategoryMapping(1323, TorznabCatType.TVSport, "|- Documentary Wrestling");
caps.Categories.AddCategoryMapping(1346, TorznabCatType.TVSport, "Для дооформления раздач");
caps.Categories.AddCategoryMapping(1411, TorznabCatType.TVSport, "|- Сканирование, обработка сканов");
caps.Categories.AddCategoryMapping(1411, TorznabCatType.Books, "|- Сканирование, обработка сканов");
caps.Categories.AddCategoryMapping(21, TorznabCatType.Books, "Книги и журналы (общий раздел)");
caps.Categories.AddCategoryMapping(2157, TorznabCatType.Books, "|- Кино, театр, ТВ, мультипликация, цирк");
caps.Categories.AddCategoryMapping(765, TorznabCatType.Books, "|- Рисунок, графический дизайн");
@@ -1452,36 +1454,41 @@ namespace Jackett.Common.Indexers
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var searchUrl = CreateSearchUrlForQuery(query);
var results = await RequestWithCookiesAsync(searchUrl);
if (!results.ContentString.Contains("id=\"logged-in-username\""))
{
// re login
await ApplyConfiguration(null);
results = await RequestWithCookiesAsync(searchUrl);
}
var searchUrls = CreateSearchUrlsForQuery(query);
var releases = new List<ReleaseInfo>();
try
foreach (var searchUrl in searchUrls)
{
var rows = GetReleaseRows(results);
foreach (var row in rows)
Console.WriteLine(searchUrl);
var results = await RequestWithCookiesAsync(searchUrl);
if (!results.ContentString.Contains("id=\"logged-in-username\""))
{
var release = ParseReleaseRow(row);
if (release != null)
// re login
await ApplyConfiguration(null);
results = await RequestWithCookiesAsync(searchUrl);
}
try
{
var rows = GetReleaseRows(results);
foreach (var row in rows)
{
releases.Add(release);
var release = ParseReleaseRow(row);
if (release != null)
{
releases.Add(release);
}
}
}
}
catch (Exception ex)
{
OnParseError(results.ContentString, ex);
catch (Exception ex)
{
OnParseError(results.ContentString, ex);
}
}
return releases;
return releases.OrderByDescending(o => o.PublishDate).ToArray();
}
public override async Task<byte[]> Download(Uri link)
@@ -1503,20 +1510,21 @@ namespace Jackett.Common.Indexers
return await base.Download(link);
}
private string CreateSearchUrlForQuery(in TorznabQuery query)
private IEnumerable<string> CreateSearchUrlsForQuery(TorznabQuery query)
{
var queryCollection = new NameValueCollection();
var searchString = query.SearchTerm;
// replace any space, special char, etc. with % (wildcard)
var ReplaceRegex = new Regex("[^a-zA-Zа-яА-Я0-9]+");
if (!string.IsNullOrWhiteSpace(searchString))
searchString = ReplaceRegex.Replace(searchString, "%");
{
searchString = new Regex("[^a-zA-Zа-яА-Я0-9]+").Replace(searchString, "%");
}
// if the search string is empty use the getnew view
if (string.IsNullOrWhiteSpace(searchString))
{
queryCollection.Add("nm", searchString);
queryCollection.Set("nm", searchString);
}
else // use the normal search
{
@@ -1529,15 +1537,24 @@ namespace Jackett.Common.Indexers
{
searchString += " Серии: " + query.Episode;
}
queryCollection.Add("nm", searchString);
queryCollection.Set("nm", searchString);
}
if (query.HasSpecifiedCategories)
queryCollection.Add("f", string.Join(",", MapTorznabCapsToTrackers(query)));
{
var trackerCategories = MapTorznabCapsToTrackers(query).Distinct().ToList();
var searchUrl = SearchUrl + "?" + queryCollection.GetQueryString();
foreach (var trackerCategoriesChunk in trackerCategories.ChunkBy(200))
{
queryCollection.Set("f", string.Join(",", trackerCategoriesChunk));
return searchUrl;
yield return SearchUrl + "?" + queryCollection.GetQueryString();
}
}
else
{
yield return SearchUrl + "?" + queryCollection.GetQueryString();
}
}
private IHtmlCollection<IElement> GetReleaseRows(WebResult results)

View File

@@ -0,0 +1,15 @@
using System.Diagnostics.CodeAnalysis;
namespace Jackett.Common.Models.IndexerConfig.Bespoke
{
[ExcludeFromCodeCoverage]
internal class ConfigurationDataSpeedAppTracker : ConfigurationDataBasicLoginWithEmail
{
public BoolConfigurationItem FreeleechOnly { get; private set; }
public ConfigurationDataSpeedAppTracker()
{
FreeleechOnly = new BoolConfigurationItem("Show freeleech only") { Value = false };
}
}
}

View File

@@ -319,7 +319,9 @@ namespace Jackett.Common.Services
_logger.Info($"Test search in {indexer.Name} => Found {result.Releases.Count()} releases [{stopwatch.ElapsedMilliseconds:0}ms]");
if (!result.Releases.Any())
throw new Exception($"Test search in {indexer.Name} => Found no results while trying to browse this tracker");
{
throw new Exception($"Test search in {indexer.Name} => Found no results while trying to browse this tracker. This may be an issue with the indexer, or other indexer settings such as search freeleech only etc.");
}
}
public void DeleteIndexer(string name)

View File

@@ -23,7 +23,7 @@ namespace Jackett.Common.Utils
var logFile = new FileTarget
{
Layout = "${longdate} ${level} ${message} ${exception:format=ToString}",
Layout = "${longdate} ${level} ${message} ${onexception:inner=${newline}${newline}[v${assembly-version}] ${exception:format=ToString}${newline}${exception:format=Data}${newline}}",
FileName = Path.Combine(settings.DataFolder, logFileName),
ArchiveFileName = Path.Combine(settings.DataFolder, logFileName + ".{#####}.txt"),
ArchiveAboveSize = 2097152, // 2 MB
@@ -60,7 +60,7 @@ namespace Jackett.Common.Utils
{
var logConsole = new ColoredConsoleTarget
{
Layout = "${simpledatetime} ${level} ${message} ${exception:format=ToString}"
Layout = "${simpledatetime} ${level} ${message} ${onexception:inner=${newline}${newline}[v${assembly-version}] ${exception:format=ToString}${newline}${exception:format=Data}${newline}}"
};
logConfig.AddTarget("console", logConsole);

View File

@@ -12,15 +12,15 @@ namespace Jackett.Common.Utils
private static readonly NameValueCollection _Trackers = new NameValueCollection
{
{"tr", "udp://tracker.opentrackr.org:1337/announce"},
{"tr", "udp://open.tracker.cl:1337/announce"},
{"tr", "udp://9.rarbg.com:2810/announce"},
{"tr", "udp://tracker.openbittorrent.com:6969/announce"},
{"tr", "http://tracker.openbittorrent.com:80/announce"},
{"tr", "udp://opentracker.i2p.rocks:6969/announce"},
{"tr", "https://opentracker.i2p.rocks:443/announce"},
{"tr", "udp://tracker.torrent.eu.org:451/announce"},
{"tr", "http://tracker.openbittorrent.com:80/announce"},
{"tr", "udp://tracker.openbittorrent.com:6969/announce"},
{"tr", "udp://open.demonii.com:1337/announce"},
{"tr", "udp://open.stealth.si:80/announce"},
{"tr", "udp://exodus.desync.com:6969/announce"},
{"tr", "udp://tracker.tiny-vps.com:6969/announce"},
{"tr", "udp://tracker.torrent.eu.org:451/announce"},
{"tr", "udp://tracker.moeking.me:6969/announce"},
};
private static readonly string _TrackersEncoded = _Trackers.GetQueryString(null, true);

View File

@@ -314,6 +314,7 @@ namespace Jackett.Updater
"Definitions/btxpress.yml",
"Definitions/casatorrent.yml", // renamed to teamctgame
"Definitions/casstudiotv.yml",
"Definitions/ccfbits.yml",
"Definitions/channelx.yml",
"Definitions/cili180.yml", // renamed to liaorencili
"Definitions/cilipro.yml",
@@ -401,6 +402,7 @@ namespace Jackett.Updater
"Definitions/hdreactor.yml", // renamed to hdhouse
"Definitions/hdspain.yml",
"Definitions/hdstreet.yml",
"Definitions/hdtorrentsit.yml",
"Definitions/hellashut.yml",
"Definitions/hellastz.yml",
"Definitions/hidden-palace.yml",