Compare commits

...

54 Commits

Author SHA1 Message Date
Garfield69
14220f169e fix arabicscene id which should have been lowercase 2025-05-20 18:27:50 +12:00
Garfield69
ada12ba547 torrentsir: bump domain 2025-05-20 17:43:08 +12:00
Garfield69
1899df1a84 Update README.md 2025-05-20 16:21:57 +12:00
Garfield69
5f75bdce58 Update README.md 2025-05-20 16:19:50 +12:00
Garfield69
96aeae6f25 add arabicsource a private site. resolves #15996 2025-05-20 14:40:38 +12:00
ilike2burnthing
2dbe6e1f20 tapochek: update cats 2025-05-20 01:06:09 +01:00
Garfield69
8c5be40d26 Update rudub.yml 2025-05-20 06:31:49 +12:00
Garfield69
abc871efeb oldgreektracker: update cats 2025-05-20 06:31:45 +12:00
Garfield69
3f84367e88 coastalcrew: update cats 2025-05-20 06:31:30 +12:00
ilike2burnthing
09c252fc9e btdirectory: add new domain 2025-05-19 18:56:11 +01:00
ilike2burnthing
f4a6c1f494 btdirectory: update domain. resolves #16001 2025-05-19 18:45:18 +01:00
Garfield69
f1ab49f462 hdtorrents: drop posters to avoid multiple flaresolverr hits 2025-05-19 16:15:55 +12:00
ilike2burnthing
e89c6a73aa lat-team-api: bump engine tag 2025-05-19 05:00:08 +01:00
Garfield69
267d6f9160 add bitsexy a private site. resolves #12070 2025-05-19 06:49:42 +12:00
Garfield69
a87f2e8123 Update rudub.yml 2025-05-19 05:56:49 +12:00
Garfield69
ed598f632e pornbay: update date selector. resolves #15997 2025-05-18 05:17:44 +12:00
Garfield69
b5e5d50128 Update rudub.yml 2025-05-18 05:17:21 +12:00
Garfield69
57e5293894 torrentgalaxyclone: lint 2025-05-17 20:18:51 +12:00
Garfield69
695c26fe07 torrentgalaxyclone: lint 2025-05-17 20:11:50 +12:00
Garfield69
c0c229e29d add torrentgalaxyclone a public site. resolves #15992 2025-05-17 20:01:46 +12:00
Garfield69
6e56730d93 dontorrent; new domain 2025-05-17 17:38:12 +12:00
Garfield69
da841b52b0 turkseed: bump engine tag 2025-05-17 17:37:56 +12:00
Garfield69
dd117c73f5 emuwarez: bump engine tag 2025-05-17 05:24:16 +12:00
Garfield69
0b7134eb7d Update rudub.yml 2025-05-17 05:07:09 +12:00
Garfield69
ca7c36735f assorted unit3d: bump engine tag 2025-05-16 19:44:05 +12:00
Garfield69
070ee26017 bithdtv: typo 2025-05-16 18:03:13 +12:00
Garfield69
81e0101cbd bithdtv; add config link to the rate limit forum topic #15993 2025-05-16 15:49:56 +12:00
Garfield69
479392cf4f bithdtv: add request limit detection. #15993 2025-05-16 14:02:58 +12:00
Garfield69
be377ac649 uindex: add c=0 to search. resolves #15912 2025-05-16 05:28:10 +12:00
Garfield69
36d3f19086 Merge branch 'master' of https://github.com/Jackett/Jackett 2025-05-16 05:24:47 +12:00
Garfield69
158d92d336 torrentqq: bump alternate domain 2025-05-16 05:24:38 +12:00
Garfield69
d7ed800d54 siambit: add flaresolverr info 2025-05-16 05:24:23 +12:00
Garfield69
366ce176bb ebook-shares: new cats 2025-05-16 05:24:08 +12:00
Garfield69
e0d3b960ad Update rudub.yml 2025-05-16 05:23:54 +12:00
ilike2burnthing
ae7d6c499b Update Program.cs 2025-05-15 18:03:14 +01:00
ilike2burnthing
1aba79fe13 enthralled2fa: removed. #14897 2025-05-15 18:03:10 +01:00
ilike2burnthing
e4a9019f7f Update README.md 2025-05-15 17:55:41 +01:00
ilike2burnthing
be26c199bf assorted: fix year regex (#15994) 2025-05-15 17:38:44 +01:00
ilike2burnthing
bff8bf3a96 ncore: migrate to yaml (#15991) 2025-05-15 01:36:13 +01:00
Bogdan
4716ea7829 passthepopcorn: download torrent files with API credentials 2025-05-15 01:46:55 +03:00
ilike2burnthing
dcf04e7eac lastfiles: remove unused genre search modes 2025-05-14 17:55:54 +01:00
Garfield69
643bf3283a Update rudub.yml 2025-05-15 04:41:04 +12:00
Garfield69
5b16b9ff65 torrentqq: bump domain 2025-05-14 17:45:04 +12:00
Garfield69
f2f2e63a97 bithorlo: update size selector 2025-05-14 05:48:03 +12:00
Garfield69
4fd1203bef polishtorrent: update inactivity info 2025-05-14 05:47:41 +12:00
Garfield69
10a498308f Update rudub.yml 2025-05-14 05:47:19 +12:00
Garfield69
1fb7c8c346 torrenttip: bump domain 2025-05-13 17:39:31 +12:00
Garfield69
e894496bda torrentsome: bump domain 2025-05-13 17:39:17 +12:00
Garfield69
ca314d3e6a Update rudub.yml 2025-05-13 05:51:57 +12:00
Garfield69
5cba616a31 parabellumhd: tolower 2025-05-12 13:14:28 +12:00
Garfield69
75222975af parabellumhd: fix year input 2025-05-12 07:17:03 +12:00
Garfield69
3d919aa88b Update rudub.yml 2025-05-12 05:50:10 +12:00
Garfield69
030926a549 danishbytes: new cat 2025-05-11 05:31:13 +12:00
Garfield69
90abe2e4d8 Update rudub.yml 2025-05-11 05:30:56 +12:00
47 changed files with 958 additions and 767 deletions

View File

@@ -131,6 +131,7 @@ Prior versions of Jackett are no longer supported.
* Torrent9
* TorrentDosFilmes
* TorrentDownload
* TorrentGalaxyClone
* TorrentKitty
* TorrentProject2
* TorrentQQ (토렌트큐큐)
@@ -256,6 +257,7 @@ Prior versions of Jackett are no longer supported.
* AnimeWorld (AW)
* Anthelion (ANT)
* Araba Fenice (Phoenix) [![(invite needed)][inviteneeded]](#)
* ArabicSource
* ArabP2P
* ArabTorrents [![(invite needed)][inviteneeded]](#)
* AsianCinema
@@ -279,6 +281,7 @@ Prior versions of Jackett are no longer supported.
* BitHUmen [![(invite needed)][inviteneeded]](#)
* Bitpalace
* BitPorn
* BitSexy
* BitTorrentFiles
* BiTTuRK
* BJ-Share (BJ) [![(invite needed)][inviteneeded]](#)
@@ -432,7 +435,7 @@ Prior versions of Jackett are no longer supported.
* Leech24
* LemonHD [![(invite needed)][inviteneeded]](#)
* Lesbians4u
* LetSeed [![(invite needed)][inviteneeded]](#)
* LetSeed
* Libble
* LibraNet (LN)
* LinkoManija
@@ -458,7 +461,7 @@ Prior versions of Jackett are no longer supported.
* MouseBits
* MyAnonamouse (MAM)
* MySpleen [![(invite needed)][inviteneeded]](#)
* NCore [![(invite needed)][inviteneeded]](#)
* NCore
* Nebulance (NBL) (TransmiTheNet)
* NewHeaven (TorrentHeavenResurrection) [![(invite needed)][inviteneeded]](#)
* NicePT
@@ -659,6 +662,8 @@ t=book:
params : q, title, author, publisher, year, genre
```
Note that most indexers will only support a subset of these search modes and parameters, use the t=caps to get a list of the actual modes and parms supported by an indexer.
Examples:
```
@@ -708,7 +713,7 @@ A special "all" indexer is available at `/api/v2.0/indexers/all/results/torznab`
It will query all configured indexers and return the combined results.
If your client supports multiple feeds it's recommended to add each indexer directly instead of using the "all" indexer.
Using the "all" indexer has no advantages (besides reduced management overhead), the only disadvantages:
Using the "all" indexer has no advantages (besides reduced management overhead), and there are many disadvantages:
* you lose control over indexer specific settings (categories, search modes, etc.)
* mixing search modes (IMDB, query, etc.) might cause low-quality results
* indexer specific categories (>= 100000) can't be used.

View File

@@ -152,7 +152,7 @@ search:
keywordsfilters:
# drop the year from searches since site titles do not include year
- name: re_replace
args: ["(19|20[0-9]{2})", ""]
args: ["(\\b((19|20)\\d{2})\\b)", ""]
rows:
selector: "div#fancy-list-group ul.list-group li.list-group-item{{ if .Config.freeleech }}:has(span.badge-success:contains(\"FREE\")){{ else }}{{ end }}"

View File

@@ -145,7 +145,7 @@ search:
- name: dateparse
args: "yyyy-MM-dd HH:mm:ss zzz"
size:
selector: td.fixed-width-size > span
selector: td.fixed-width-size > a
grabs:
selector: td.fixed-width-completed
seeders:

View File

@@ -0,0 +1,178 @@
---
id: bitsexy-api
name: BitSexy (API)
description: "BitSexy is a Private Torrent Tracker for 3X"
language: en-US
type: private
encoding: UTF-8
links:
- https://bitsexy.cc/
caps:
categorymappings:
- {id: 1, cat: XXX/x264, desc: "Movies"}
- {id: 2, cat: XXX/Pack, desc: "Pack"}
- {id: 3, cat: XXX/ImageSet, desc: "Images"}
- {id: 4, cat: Console, desc: "Games"}
- {id: 5, cat: Books, desc: "Books"}
modes:
search: [q]
movie-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://bitsexy.cc/\" target=\"_blank\">BitSexy</a> account <i>My Settings</i> page and clicking on the <b>API Key</b> tab."
- name: freeleech
type: checkbox
label: Search freeleech only
default: false
- name: single_file_release_use_filename
type: checkbox
label: Use filename as title for single file releases
default: true
- 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
- name: info_activity
type: info
label: Account Inactivity
default: "<ul><li>You must log in once every 60 days or seed at least 1 torrent to not get disabled</li><li>Once disabled, you have another 60 days to log back in and have your account re-activated. You may need to contact Helpdesk to do so</li><li>Disabled account will be deleted after 180 days of inactivity</li><ul>"
login:
path: /api/torrents
method: get
error:
- selector: a[href*="/login"]
message:
text: "The API key was not accepted by {{ .Config.sitelink }}."
- selector: :root:contains("Account is Banned")
search:
paths:
# https://github.com/HDInnovations/UNIT3D-Community-Edition/wiki/Torrent-API-(UNIT3D-v8.x.x)
# https://github.com/HDInnovations/UNIT3D-Community-Edition/blob/master/app/Http/Controllers/API/TorrentController.php#L476
- path: api/torrents/filter
response:
type: json
headers:
Authorization: ["Bearer {{ .Config.apikey }}"]
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
$raw: "{{ range .Categories }}&categories[]={{.}}{{end}}"
name: "{{ .Keywords }}"
"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_optional:
selector: name
title_filename:
selector: "files[0].name"
optional: true
files:
selector: num_file
title:
text: "{{ if and (.Config.single_file_release_use_filename) (eq .Result.files \"1\") (.Result.title_filename) }}{{ .Result.title_filename }}{{ else }}{{ .Result.title_optional }}{{ end }}"
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: replace
args: [" & ", "_&_"]
description:
text: "{{ .Result.genre }}"
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
_featured:
selector: featured
case:
False: "{{ .False }}"
True: "{{ .True }}"
downloadvolumefactor_freeleech:
# 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
downloadvolumefactor:
text: "{{ if .Result._featured }}0{{ else }}{{ .Result.downloadvolumefactor_freeleech }}{{ end }}"
uploadvolumefactor_double_upload:
# api returns False, True
selector: double_upload
case:
False: 1 # normal
True: 2 # double
uploadvolumefactor:
text: "{{ if .Result._featured }}2{{ else }}{{ .Result.uploadvolumefactor_double_upload }}{{ end }}"
minimumseedtime:
# 2 days (as seconds = 2 x 24 x 60 x 60)
text: 172800
# json UNIT3D 9.0.8 (custom)

View File

@@ -191,4 +191,4 @@ search:
minimumseedtime:
# 7 days (as seconds = 7 x 24 x 60 x 60)
text: 604800
# json UNIT3D 9.0.7
# json UNIT3D 9.0.8

View File

@@ -7,13 +7,14 @@ type: public
encoding: UTF-8
# current domain at https://cursor.vip/btmulu then follow links to the final search-movie link
links:
- https://btmulu.work/
- https://btmulu.live/
- https://www.btmulu.cyou/
legacylinks:
- https://www.btmulu.asia/
- https://www.btmulu.digital/
- https://www.btmulu.pw/
- https://www.btmulu.one/
- https://btmulu.work/
caps:
categorymappings:

View File

@@ -190,4 +190,4 @@ search:
minimumseedtime:
# 3 days (as seconds = 3 x 24 x 60 x 60)
text: 259200
# json UNIT3D 9.0.7
# json UNIT3D 9.0.8

View File

@@ -29,9 +29,11 @@ caps:
- {id: 92, cat: TV/Documentary, desc: "Doku Avi"}
- {id: 94, cat: TV/Documentary, desc: "Doku Audio"}
- {id: 135, cat: TV/Documentary, desc: "Doku UHD"}
- {id: 13, cat: TV/Documentary, desc: "Doku DVD-R"}
- {id: 14, cat: TV/Documentary, desc: "Doku HD"}
- {id: 15, cat: TV/Documentary, desc: "Doku SD"}
- {id: 136, cat: TV/Documentary, desc: "Doku Pack"}
- {id: 9, cat: PC, desc: "App Linux"}
- {id: 10, cat: PC/Mac, desc: "App Mac"}
@@ -66,6 +68,7 @@ caps:
- {id: 116, cat: TV/Sport, desc: "Sport DVD-R"}
- {id: 117, cat: TV/Sport, desc: "Sport DVD-R"}
- {id: 134, cat: Other, desc: "Sonstiges Pack"}
- {id: 63, cat: Audio/Audiobook, desc: "Sonstiges A-Book"}
- {id: 96, cat: Books/EBook, desc: "Sonstiges E-Book"}
- {id: 69, cat: Other, desc: "Sonstiges Tutorial"}

View File

@@ -106,7 +106,7 @@ search:
text: "{{ if .Result.title_phase1_title }}{{ .Result.title_phase1_title }}{{ else }}{{ .Result.title_phase1_url }}{{ end }}"
filters:
- name: re_replace
args: ["(?i)\\b(FRENCH|MULTI|TRUEFRENCH|VOSTFR|SUBFRENCH)\\b(.+?)(\\b(19|20\\d{2})\\b)$", "$3 $1$2"]
args: ["(?i)\\b(FRENCH|MULTI|TRUEFRENCH|VOSTFR|SUBFRENCH)\\b(.+?)(\\b((19|20)\\d{2})\\b)$", "$3 $1$2"]
title_vostfr:
text: "{{ .Result.title_phase1 }}"
filters:

View File

@@ -93,7 +93,7 @@ search:
selector: a
filters:
- name: re_replace
args: ["(?i)\\b(FRENCH|MULTI|TRUEFRENCH|VOSTFR|SUBFRENCH)\\b(.+?)(\\b(19|20\\d{2})\\b)$", "$3 $1$2"]
args: ["(?i)\\b(FRENCH|MULTI|TRUEFRENCH|VOSTFR|SUBFRENCH)\\b(.+?)(\\b((19|20)\\d{2})\\b)$", "$3 $1$2"]
title_vostfr:
text: "{{ .Result.title_phase1 }}"
filters:

View File

@@ -19,9 +19,10 @@ caps:
- {id: 2, cat: TV, desc: "TV"}
- {id: 5, cat: PC/0day, desc: "Apps"}
- {id: 4, cat: PC/Games, desc: "Games"}
- {id: 3, cat: Audio, desc: "Sound"}
- {id: 3, cat: Audio, desc: "Music"}
- {id: 8, cat: Books, desc: "Books"}
- {id: 17, cat: Audio/Audiobook, desc: "AudioBooks"}
- {id: 19, cat: Audio, desc: "Podcasts"}
modes:
search: [q]

View File

@@ -24,6 +24,12 @@ caps:
- {id: 311, cat: Audio/Audiobook, desc: "Audio:Romance"}
- {id: 317, cat: Audio/Audiobook, desc: "Audio:Urbn Fant/para"}
- {id: 319, cat: Audio/Audiobook, desc: "Audio:V.I.P"}
- {id: 320, cat: Audio/Audiobook, desc: "Audio:Science/engine"}
- {id: 321, cat: Audio/Audiobook, desc: "Audio:History/War"}
- {id: 322, cat: Audio/Audiobook, desc: "Audio:non fiction"}
- {id: 323, cat: Audio/Audiobook, desc: "Audio:Educational"}
- {id: 324, cat: Audio/Audiobook, desc: "Audio:Tutorials"}
- {id: 325, cat: Audio/Audiobook, desc: "Audio:True Crime"}
# Collections
- {id: 305, cat: Books/EBook, desc: "Same Author"}
- {id: 307, cat: Books/EBook, desc: "Collection: Military"}

View File

@@ -183,4 +183,4 @@ search:
minimumseedtime:
# 3 days (as seconds = 3 x 24 x 60 x 60)
text: 259200
# json UNIT3D 8.2.0
# json UNIT3D 9.0.8

View File

@@ -1,134 +0,0 @@
---
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_cookie
- 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:
# using cookie method because login page can present second page for 2FA when enabled
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 shaded_row"]:has(a[href*="action=download"])
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
description_tags:
selector: div.tags
description:
case:
span.icon_okay: "Verified: {{ .Result.description_tags }}"
"*": "Unverified: {{ .Result.description_tags }}"
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:
case:
span.icon[title*="DoubleSeed"]: 2
"img[alt=\"DoubleSeed\"]": 2
"*": 1
minimumratio:
text: 0.5
# Luminance

View File

@@ -193,4 +193,4 @@ search:
minimumseedtime:
# 7 days (as seconds = 7 x 24 x 60 x 60)
text: 604800
# json UNIT3D 9.0.6
# json UNIT3D 9.0.8

View File

@@ -62,10 +62,10 @@ caps:
modes:
search: [q]
tv-search: [q, season, ep, genre]
movie-search: [q, genre]
music-search: [q, genre]
book-search: [q, genre]
tv-search: [q, season, ep]
movie-search: [q]
music-search: [q]
book-search: [q]
settings:
- name: username

View File

@@ -206,4 +206,4 @@ search:
minimumseedtime:
# 3 days (as seconds = 3 x 24 x 60 x 60)
text: 259200
# json UNIT3D 8.3.4 (custom)
# json UNIT3D 9.0.8 (custom)

View File

@@ -0,0 +1,189 @@
---
id: ncore
name: nCore
description: "nCore is a HUNGARIAN Private Torrent Tracker for MOVIES / TV / GENERAL"
language: hu-HU
type: private
encoding: UTF-8
links:
- https://ncore.pro/
legacylinks:
- https://ncore.cc/
caps:
categorymappings:
# E-book
- {id: ebook, cat: Books, desc: "E-book/Eng"}
- {id: ebook_hun, cat: Books, desc: "E-book/Hun"}
# Játék
- {id: console, cat: Console, desc: "Játék/Console"}
- {id: game_iso, cat: PC/Games, desc: "Játék/ISO"}
- {id: game_rip, cat: PC/Games, desc: "Játék/Rip"}
# Filmek
- {id: xvid_hun, cat: Movies/SD, desc: "Film/SD/Hun"}
- {id: xvid, cat: Movies/SD, desc: "Film/SD/Eng"}
- {id: dvd_hun, cat: Movies/DVD, desc: "Film/DVD/Hun"}
- {id: dvd, cat: Movies/DVD, desc: "Film/DVD/Eng"}
- {id: dvd9_hun, cat: Movies/DVD, desc: "Film/Dvd9/Hun"}
- {id: dvd9, cat: Movies/DVD, desc: "Film/Dvd9/Eng"}
- {id: hd_hun, cat: Movies/HD, desc: "Film/HD/Hun"}
- {id: hd, cat: Movies/HD, desc: "Film/HD/Eng"}
# Sorozatok
- {id: xvidser, cat: TV/SD, desc: "Sorozat/SD/Eng"}
- {id: xvidser_hun, cat: TV/SD, desc: "Sorozat/SD/Hun"}
- {id: dvdser, cat: TV/Other, desc: "Sorozat/DVDR/Eng"}
- {id: dvdser_hun, cat: TV/Other, desc: "Sorozat/DVDR/Hun"}
- {id: hdser, cat: TV/HD, desc: "Sorozat/HD/Eng"}
- {id: hdser_hun, cat: TV/HD, desc: "Sorozat/HD/Hun"}
# Zene
- {id: mp3_hun, cat: Audio/MP3, desc: "Zene/MP3/Hun"}
- {id: mp3, cat: Audio/MP3, desc: "Zene/MP3/Eng"}
- {id: lossless_hun, cat: Audio/MP3, desc: "Zene/Lossless/Hun"}
- {id: lossless, cat: Audio/MP3, desc: "Zene/Lossless/Eng"}
- {id: clip, cat: Audio/Video, desc: "Zene/Klip"}
# Program
- {id: iso, cat: PC/ISO, desc: "Win/Program/ISO"}
- {id: misc, cat: PC/0day, desc: "Win/Program/Rip"}
- {id: mobil, cat: PC/Mobile-Other, desc: "Win/Program/Rip"}
# Felnőtt tartalom
- {id: xxx_xvid, cat: XXX/SD, desc: "XXX/Film/SD"}
- {id: xxx_dvd, cat: XXX/DVD, desc: "XXX/DVDR"}
- {id: xxx_hd, cat: XXX/UHD, desc: "XXX/HD"}
- {id: xxx_imageset, cat: XXX/ImageSet, desc: "XXX/Kép"}
modes:
search: [q]
tv-search: [q, season, ep, imdbid, genre]
movie-search: [q, imdbid, genre]
music-search: [q, genre]
book-search: [q, genre]
settings:
- name: username
type: text
label: Username
- name: password
type: password
label: Password
- name: 2facode
type: text
label: 2FA code
- name: info_2fa
type: info
label: "About 2FA code"
default: "Only fill in the <b>2FA code</b> box if you have enabled <b>2FA</b> on the nCore Web Site. Otherwise just leave it empty."
- name: info_tpp
type: info
label: Results Per Page
default: For best results, change the <b>Torrent oldalanként:</b> setting to <b>100</b> on your account profile.
- name: info_activity
type: info
label: Account Inactivity
default: "Anyone who does not access the site for 8 weeks from registration or has been more than 8 weeks since their last stay will be automatically suspended. Anyone who does not log in (stays inactive) for 12 weeks after registration or after their last visit will be removed automatically."
login:
method: post
path: login.php
inputs:
nev: "{{ .Config.username }}"
pass: "{{ .Config.password }}"
2factor: "{{ .Config.2facode }}"
ne_leptessen_ki: "1"
set_lang: "en"
submitted: "1"
error:
- selector: div#hibauzenet table tbody tr
test:
path: index.php
selector: a[href*="profile.php"]
download:
selectors:
- selector: a[href^="torrents.php?action=download&id="]
attribute: href
search:
paths:
- path: torrents.php
inputs:
mire: "{{ if .Query.IMDBID }}{{ .Query.IMDBID }}{{ else }}{{ .Keywords }}{{ end }}"
miben: "{{ if .Query.IMDBID }}imdb{{ else }}name{{ end }}"
tipus: "{{ if .Categories }}kivalasztottak_kozott{{ else }}all_own{{ end }}"
submit.x: 1
submit.y: 1
tags: "{{ .Query.Genre }}"
$raw: "{{ range .Categories }}&kivalasztott_tipus[]={{.}}{{end}}"
rows:
selector: .box_torrent_all .box_torrent
fields:
category:
selector: .box_alap_img > a
attribute: href
filters:
- name: querystring
args: tipus
title:
selector: div[class^="torrent_txt"] > a
attribute: title
details:
selector: div[class^="torrent_txt"] > a
attribute: href
download:
selector: div[class^="torrent_txt"] > a
attribute: href
filters:
- name: replace
args: ["torrents.php?action=details", "ajax.php?action=torrent_drop"]
# image is returned with invalid Content-Type header 'image'
# poster:
# selector: div.infobar > img
# attribute: onmouseover
# filters:
# - name: regexp
# args: "'(.+?)'"
imdbid:
selector: a[href*="imdb.com/title/tt"]
attribute: href
filters:
- name: replace
args: ["https://dereferer.link/?", ""]
size:
selector: div.box_meret2
seeders:
selector: div.box_s2
leechers:
selector: div.box_l2
date:
selector: div.box_feltoltve2
filters:
- name: append
args: " +01:00" # CET
- name: dateparse
args: "yyyy-MM-ddHH:mm:ss zzz"
downloadvolumefactor:
text: 0
uploadvolumefactor:
text: 1
minimumratio:
text: 1.0
# MST is 48 hours + 24 minutes (.4 hours) per GB of downloaded size
# minimumseedtime:
# # 2 days (as seconds = 2 x 24 x 60 x 60)
# text: 172800
description_imdb:
selector: a.infolink
optional: true
description_alt:
selector: div.siterank > span
attribute: title
optional: true
description:
case:
div.torrent_ok: "Verified"
div.torrent_unchecked: "Unverified"
filters:
- name: append
args: "{{ if or .Result.description_alt .Result.description_imdb }}: {{ else }}{{ end }}{{ .Result.description_alt }}{{ if and .Result.description_alt .Result.description_imdb }} {{ else }}{{ end }}{{ .Result.description_imdb }}"
# engine n/a

View File

@@ -120,7 +120,7 @@ search:
selector: td:nth-child(1) a
filters:
- name: re_replace
args: ["(?i)\\b(FRENCH|MULTI|TRUEFRENCH|VOSTFR|SUBFRENCH)\\b(.+?)(\\b(19|20\\d{2})\\b)$", "$3 $1$2"]
args: ["(?i)\\b(FRENCH|MULTI|TRUEFRENCH|VOSTFR|SUBFRENCH)\\b(.+?)(\\b((19|20)\\d{2})\\b)$", "$3 $1$2"]
title_vostfr:
text: "{{ .Result.title_phase1 }}"
filters:

View File

@@ -26,15 +26,25 @@ caps:
- {id: 73, cat: Console, desc: "Games"}
- {id: 74, cat: PC/Games, desc: "Games: PC Games"}
- {id: 15, cat: Movies/SD, desc: "Movies"}
- {id: 132, cat: Movies/SD, desc: "Movies: CAM / TS / TC"}
- {id: 20, cat: Movies/SD, desc: "Movies: Filmographies"}
- {id: 105, cat: Movies, desc: "Movies: Animation"}
- {id: 106, cat: Movies, desc: "Movies: Cartoons"}
- {id: 20, cat: Movies/SD, desc: "Movies: Filmographies"}
- {id: 133, cat: Movies/DVD, desc: "Movies: Foreign DVD5/DVD9"}
- {id: 138, cat: Movies/DVD, desc: "Movies: Foreign DVDRip"}
- {id: 122, cat: Movies/HD, desc: "Movies: Foreign HDRip / BRRip"}
- {id: 16, cat: Movies/SD, desc: "Movies: Foreign Movies Non HD"}
- {id: 130, cat: Movies/SD, desc: "Movies: Foreign VHS"}
- {id: 145, cat: Movies/WEB-DL, desc: "Movies: Foreign WEBRip"}
- {id: 141, cat: Movies, desc: "Movies: Greek Audio Animation"}
- {id: 140, cat: Movies, desc: "Movies: Greek Audio Cartoons"}
- {id: 134, cat: Movies/DVD, desc: "Movies: Greek DVD5/DVD9"}
- {id: 136, cat: Movies/DVD, desc: "Movies: Greek DVDRip"}
- {id: 139, cat: Movies/HD, desc: "Movies: Greek HDRip / BRRip"}
- {id: 119, cat: Movies/SD, desc: "Movies: Greek Movies Non HD"}
- {id: 122, cat: Movies/HD, desc: "Movies: MicroHD"}
- {id: 129, cat: Movies/SD, desc: "Movies: Greek VHS"}
- {id: 146, cat: Movies/WEB-DL, desc: "Movies: Greek WEBRip"}
- {id: 112, cat: Movies/HD, desc: "Movies: Movie Packs"}
- {id: 130, cat: Movies/WEB-DL, desc: "Movies: WEBRip / 1080p"}
- {id: 129, cat: Movies/WEB-DL, desc: "Movies: WEBRip / 720p"}
- {id: 41, cat: Movies/HD, desc: "Movies HD"}
- {id: 50, cat: Movies/HD, desc: "Movies HD: BluRay / 1080p"}
- {id: 51, cat: Movies/UHD, desc: "Movies HD: BluRay / 4K (UHD)"}
@@ -60,12 +70,15 @@ caps:
- {id: 116, cat: Audio/Video, desc: "Music: Greek Music Videos"}
- {id: 92, cat: Audio/Other, desc: "Music: Greek Soundtracks"}
- {id: 28, cat: TV, desc: "TV"}
- {id: 29, cat: TV/Anime, desc: "TV: Animation"}
- {id: 31, cat: TV/Other, desc: "TV: Cartoons"}
- {id: 79, cat: TV/Documentary, desc: "TV: Documentaries"}
- {id: 77, cat: TV, desc: "TV: Foreign TV Packs"}
- {id: 29, cat: TV/Anime, desc: "TV: Foreign Animation"}
- {id: 31, cat: TV/Other, desc: "TV: Foreign Cartoons"}
- {id: 79, cat: TV/Documentary, desc: "TV: Foreign Documentaries"}
- {id: 77, cat: TV, desc: "TV: Foreign TV Episodes"}
- {id: 75, cat: TV, desc: "TV: Foreign TV Series"}
- {id: 76, cat: TV, desc: "TV: Foreign TV Shows"}
- {id: 143, cat: TV/Anime, desc: "TV: Greek Audio Animation"}
- {id: 142, cat: TV/Other, desc: "TV: Greek Audio Cartoons"}
- {id: 144, cat: TV/Documentary, desc: "TV: Greek Audio Documentaries"}
- {id: 36, cat: TV, desc: "TV: Greek TV Packs"}
- {id: 35, cat: TV, desc: "TV: Greek TV Series"}
- {id: 40, cat: TV, desc: "TV: Greek TV Shows"}

View File

@@ -190,4 +190,4 @@ search:
minimumseedtime:
# 2 days (as seconds = 2 x 24 x 60 x 60)
text: 172800
# json UNIT3D 9.0.7
# json UNIT3D 9.0.8

View File

@@ -81,7 +81,7 @@ search:
selector: td:nth-child(1) a
filters:
- name: re_replace
args: ["(?i)\\b(FRENCH|MULTI|TRUEFRENCH|VOSTFR|SUBFRENCH)\\b(.+?)(\\b(19|20\\d{2})\\b)$", "$3 $1$2"]
args: ["(?i)\\b(FRENCH|MULTI|TRUEFRENCH|VOSTFR|SUBFRENCH)\\b(.+?)(\\b((19|20)\\d{2})\\b)$", "$3 $1$2"]
title_vostfr:
text: "{{ .Result.title_phase1 }}"
filters:

View File

@@ -126,7 +126,7 @@ search:
selector: td:nth-child(1) a
filters:
- name: re_replace
args: ["(?i)\\b(FRENCH|MULTI|TRUEFRENCH|VOSTFR|SUBFRENCH)\\b(.+?)(\\b(19|20\\d{2})\\b)$", "$3 $1$2"]
args: ["(?i)\\b(FRENCH|MULTI|TRUEFRENCH|VOSTFR|SUBFRENCH)\\b(.+?)(\\b((19|20)\\d{2})\\b)$", "$3 $1$2"]
title_vostfr:
text: "{{ .Result.title_phase1 }}"
filters:

View File

@@ -60,8 +60,7 @@ search:
view: list
order: "{{ .Config.sort }}"
search: "{{ .Keywords }}"
# if the year is not available in .Query.Year then extract it from .Query.Keywords if found
year: "{{ if .Query.Year }}{{ .Query.Year }}{{ else }}{{ re_replace .Query.Keywords \"(.*\\b((19|20)\\d{2})\\b.*)\" \"$2\" }}{{ end }}"
year: "{{ .Query.Year }}"
keywordsfilters:
- name: re_replace # remove year
args: ["\\b((19|20)\\d{2})\\b", ""]
@@ -69,6 +68,7 @@ search:
args: ["(?i)\\b(S\\d+)\\b", ""]
- name: re_replace # strip El
args: ["(?i)\\b(el)\\b", ""]
- name: tolower
rows:
selector: div.search-results > ul > li

View File

@@ -95,7 +95,7 @@ settings:
- name: info_activity
type: info
label: Account Inactivity
default: "Accounts that are inactive for 3 months will be moved to the 'Disabled' group. Strict restrictions are imposed on this group. If the account is still inactive after being moved to this group, it will be permanently blocked without the possibility of unblocking. Simply logging in and browsing the site does not count as an active account. Required activity: downloading/uploading torrents, possibly activity on the forum."
default: "<ul><li>If a user has not logged in for 30 days, the account will be marked as inactive.</li><li>If the account remains inactive for an additional 120 days, it will be automatically deactivated (soft delete).</li><li>This means the user will lose access to the account, although the data will be retained for a specified period.</li><li>This policy applies to users in the following groups: User, PowerUser, SuperUser, and Leech.</li><li>How can you keep your account active?</li><li>Simply log in at least once every 30 days and stay active in downloads to maintain your status.</li></ul>"
login:
path: /api/torrents
@@ -235,4 +235,4 @@ search:
minimumseedtime:
# 2 days (as seconds = 2 x 24 x 60 x 60)
text: 172800
# json UNIT3D 9.0.6 (custom)
# json UNIT3D 9.0.8 (custom)

View File

@@ -133,7 +133,6 @@ search:
selector: td:nth-child(3)
date:
selector: td:nth-child(5) > span
attribute: title
filters:
- name: append
args: " +00:00" # GMT

View File

@@ -9,28 +9,8 @@ type: semi-private
encoding: windows-1251
followredirect: true
links:
- https://may10.rudub.biz/
- https://may20.rudub.run/
legacylinks:
- http://apr25.rudub.biz/
- https://apr25.rudub.biz/
- http://apr26.rudub.biz/
- https://apr26.rudub.biz/
- http://apr27.rudub.biz/
- https://apr27.rudub.biz/
- http://apr28.rudub.biz/
- https://apr28.rudub.biz/
- http://apr29.rudub.biz/
- https://apr29.rudub.biz/
- http://apr30.rudub.biz/
- https://apr30.rudub.biz/
- http://may01.rudub.biz/
- https://may01.rudub.biz/
- http://may02.rudub.biz/
- https://may02.rudub.biz/
- http://may03.rudub.biz/
- https://may03.rudub.biz/
- http://may04.rudub.biz/
- https://may04.rudub.biz/
- http://may05.rudub.biz/
- https://may05.rudub.biz/
- http://may06.rudub.biz/
@@ -42,6 +22,26 @@ legacylinks:
- http://may09.rudub.biz/
- https://may09.rudub.biz/
- http://may10.rudub.biz/
- https://may10.rudub.biz/
- http://may11.rudub.biz/
- https://may11.rudub.biz/
- http://may12.rudub.run/
- https://may12.rudub.run/
- http://may13.rudub.run/
- https://may13.rudub.run/
- http://may14.rudub.run/
- https://may14.rudub.run/
- http://may15.rudub.run/
- https://may15.rudub.run/
- http://may16.rudub.run/
- https://may16.rudub.run/
- http://may17.rudub.run/
- https://may17.rudub.run/
- http://may18.rudub.run/
- https://may18.rudub.run/
- http://may19.rudub.run/
- https://may19.rudub.run/
- http://may20.rudub.run/
caps:
categorymappings:

View File

@@ -104,6 +104,8 @@ settings:
type: info
label: Account Inactivity
default: "Accounts can use the park system for up to 180 days."
- name: info_flaresolverr
type: info_flaresolverr
login:
path: takelogin.php

View File

@@ -17,25 +17,9 @@ caps:
- {id: 14, cat: PC/Games, desc: "Игры в разработке и демо-версии"}
- {id: 9, cat: PC/Games, desc: "Разное (дополнения, патчи, русификаторы)"}
- {id: 18, cat: PC/Games, desc: "Горячие новинки"}
- {id: 809, cat: PC/Games, desc: "Горячие новинки от R.G. Механики"}
- {id: 810, cat: PC/Games, desc: "Аркады от R.G. Механики"}
- {id: 811, cat: PC/Games, desc: "Приключения и квесты от R.G. Механики"}
- {id: 812, cat: PC/Games, desc: "Стратегии от R.G. Механики"}
- {id: 813, cat: PC/Games, desc: "Симуляторы от R.G. Механики"}
- {id: 814, cat: PC/Games, desc: "Action от R.G. Механики"}
- {id: 815, cat: PC/Games, desc: "RPG от R.G. Механики"}
- {id: 903, cat: PC/Games, desc: "jRPG от R.G. Механики"}
- {id: 935, cat: PC/Games, desc: "Ранний доступ от R.G. GOGFAN"}
- {id: 914, cat: PC/Games, desc: "Аркады от R.G. GOGFAN"}
- {id: 915, cat: PC/Games, desc: "Приключения и квесты от R.G. GOGFAN"}
- {id: 931, cat: PC/Games, desc: "Стратегии от R.G. GOGFAN"}
- {id: 930, cat: PC/Games, desc: "Симуляторы от R.G. GOGFAN"}
- {id: 929, cat: PC/Games, desc: "Action от R.G. GOGFAN"}
- {id: 928, cat: PC/Games, desc: "RPG от R.G. GOGFAN"}
- {id: 24, cat: PC/Games, desc: "Приключения и квесты"}
- {id: 25, cat: PC/Games, desc: "Стратегии"}
- {id: 21, cat: PC/Games, desc: "Аркады (основной)"}
- {id: 23, cat: PC/Games, desc: "Аркады (коллекции, антологии)"}
- {id: 19, cat: PC/Games, desc: "Аркады"}
- {id: 29, cat: PC/Games, desc: "Симуляторы"}
- {id: 35, cat: PC/Games, desc: "Экшены"}
- {id: 40, cat: PC/Games, desc: "Ролевые игры"}
@@ -44,6 +28,7 @@ caps:
- {id: 42, cat: PC/Games, desc: "Хентайные"}
- {id: 968, cat: PC/Games, desc: "Игры для VR"}
- {id: 46, cat: PC/Games, desc: "Для самых маленьких"}
- {id: 978, cat: PC/Games, desc: "Игры для macOS и Linux"}
# Games for Consoles # Игры для Консолей
- {id: 69, cat: Console/XBox, desc: "Xbox"}
- {id: 86, cat: Console/XBox 360, desc: "XBox360 | Игры"}
@@ -53,7 +38,6 @@ caps:
- {id: 612, cat: Console/XBox 360, desc: "XBox360 | Live"}
- {id: 614, cat: Console/XBox 360, desc: "XBox360 | Soft"}
- {id: 88, cat: Console/XBox, desc: "XBox | Игры"}
- {id: 85, cat: Console/XBox, desc: "Прочее | Архив (XBox)"}
- {id: 70, cat: Console/PSP, desc: "PlayStation"}
- {id: 973, cat: Console/PS4, desc: "PS5 | Игры"}
- {id: 910, cat: Console/PS4, desc: "PS4 | Игры"}
@@ -85,82 +69,59 @@ caps:
- {id: 351, cat: Console, desc: "Saturn | Игры"}
- {id: 352, cat: Console, desc: "Игры для старых консолей"}
- {id: 390, cat: Console, desc: "Коллекции (игры для разных платформ)"}
# Games for macOS and Linux # Игры для macOS и Linux
- {id: 129, cat: PC/Games, desc: "Игры для Linux от R.G. GOGFAN"}
- {id: 965, cat: PC/Games, desc: "[Linux] Ранний доступ от R.G. GOGFAN"}
- {id: 874, cat: PC/Games, desc: "[Linux] Аркады от R.G. GOGFAN"}
- {id: 695, cat: PC/Games, desc: "[Linux] Приключения и квесты от R.G. GOGFAN"}
- {id: 873, cat: PC/Games, desc: "[Linux] Стратегии от R.G. GOGFAN"}
- {id: 872, cat: PC/Games, desc: "[Linux] Симуляторы от R.G. GOGFAN"}
- {id: 871, cat: PC/Games, desc: "[Linux] Action от R.G. GOGFAN"}
- {id: 932, cat: PC/Games, desc: "[Linux] RPG от R.G. GOGFAN"}
- {id: 861, cat: PC/Games, desc: "Игры для macOS от R.G. GOGFAN"}
- {id: 966, cat: PC/Games, desc: "[macOS] Ранний доступ от R.G. GOGFAN"}
- {id: 862, cat: PC/Games, desc: "[macOS] Аркады от R.G. GOGFAN"}
- {id: 875, cat: PC/Games, desc: "[macOS] Приключения и квесты от R.G. GOGFAN"}
- {id: 876, cat: PC/Games, desc: "[macOS] Стратегии от R.G. GOGFAN"}
- {id: 877, cat: PC/Games, desc: "[macOS] Симуляторы от R.G. GOGFAN"}
- {id: 878, cat: PC/Games, desc: "[macOS] Action от R.G. GOGFAN"}
- {id: 933, cat: PC/Games, desc: "[macOS] RPG от R.G. GOGFAN"}
# Cinema # Кинематограф
- {id: 429, cat: Movies, desc: "Новинки фильмов и мультфильмов (2024-2025)"}
- {id: 964, cat: Movies/UHD, desc: "Новинки | UHD 4K"}
- {id: 431, cat: Movies/WEB-DL, desc: "Новинки | HD"}
- {id: 430, cat: Movies, desc: "Новинки | Rips"}
- {id: 703, cat: Movies, desc: "Новинки | CAMRip, TS, WEBRip(LQ)"}
- {id: 74, cat: Movies/Foreign, desc: "Зарубежное кино"}
- {id: 963, cat: Movies/UHD, desc: "Зарубежное кино | UHD 4K"}
- {id: 122, cat: Movies/HD, desc: "Зарубежное кино | HD"}
- {id: 124, cat: Movies/Foreign, desc: "Зарубежное кино | Rips"}
- {id: 123, cat: Movies, desc: "Сборники фильмов"}
- {id: 75, cat: Movies, desc: "Отечественное кино"}
- {id: 974, cat: Movies/UHD, desc: "Отечественное кино | UHD 4K"}
- {id: 127, cat: Movies/BluRay, desc: "Отечественное кино | Blu-Ray и BDRemux"}
- {id: 128, cat: Movies/HD, desc: "Отечественное кино | HD Rips"}
- {id: 133, cat: Movies/DVD, desc: "Отечественное кино | DVD"}
- {id: 131, cat: Movies, desc: "Российское и советское кино | Rips"}
- {id: 869, cat: Movies/3D, desc: "3D"}
- {id: 161, cat: TV/Foreign, desc: "Сериалы"}
- {id: 886, cat: Movies, desc: "Новинки зарубежных сериалов (2024-2025)"}
- {id: 135, cat: Movies, desc: "Зарубежные сериалы до 2024г."}
- {id: 160, cat: TV, desc: "Отечественные cериалы"}
- {id: 320, cat: TV, desc: "Мультфильмы"}
- {id: 325, cat: TV/SD, desc: "Мультфильмы | DVD"}
- {id: 325, cat: TV/UHD, desc: "Мультфильмы | UHD 4K"}
- {id: 938, cat: TV/HD, desc: "Мультфильмы | Blu-Ray и BDRemux"}
- {id: 324, cat: TV/HD, desc: "Мультфильмы | HD Rips"}
- {id: 328, cat: TV, desc: "Мультфильмы | Rips"}
- {id: 330, cat: TV, desc: "Сборники мультфильмов"}
- {id: 321, cat: TV, desc: "Мультсериалы"}
- {id: 162, cat: TV/Documentary, desc: "Документальные фильмы и телепередачи"}
- {id: 162, cat: TV/Documentary, desc: "Документальные фильмы и телешоу"}
# Anime # Аниме
- {id: 693, cat: TV/Anime, desc: "Аниме (Основной)"}
- {id: 684, cat: TV/Anime, desc: "Аниме (DVD)"}
- {id: 106, cat: TV/Anime, desc: "Аниме Манга и прочий арт"}
- {id: 678, cat: TV/Anime, desc: "Аниме (HD и Blu-ray)"}
- {id: 660, cat: TV/Anime, desc: "Онгоинги и новинки аниме"}
- {id: 95, cat: TV/Anime, desc: "Аниме (HD)"}
- {id: 660, cat: TV/Anime, desc: "Аниме ?"}
- {id: 684, cat: TV/Anime, desc: "Аниме (Rips | DVD)"}
- {id: 106, cat: TV/Anime, desc: "Манга и прочий арт"}
- {id: 680, cat: TV/Anime, desc: "Аниме (Хентай)"}
- {id: 682, cat: TV/Anime, desc: "Аниме UnCensored"}
- {id: 681, cat: TV/Anime, desc: "Аниме Censored"}
- {id: 697, cat: TV/Anime, desc: "Аниме Манга, обои, артбуки и др."}
- {id: 682, cat: TV/Anime, desc: "UnCensored"}
- {id: 681, cat: TV/Anime, desc: "Censored"}
- {id: 697, cat: TV/Anime, desc: "Манга, обои, артбуки и др."}
# Music and Music Video # Музыка и Музыкальное видео
- {id: 450, cat: Audio, desc: "Общий раздел музыки"}
- {id: 470, cat: Audio, desc: "Классическая музыка"}
- {id: 495, cat: Audio, desc: "New Age, Relax, Meditative & Flamenco"}
- {id: 456, cat: Audio, desc: "Jazz, Blues"}
- {id: 462, cat: Audio, desc: "JReggae, Ska, Dub"}
- {id: 462, cat: Audio, desc: "Reggae, Ska, Dub"}
- {id: 491, cat: Audio, desc: "Фольклор, Народная и Этническая музыка"}
- {id: 468, cat: Audio, desc: "Зарубежный Rock"}
- {id: 469, cat: Audio/Lossless, desc: "Rосk, Mеtаl, Аltеrnаtivе, Рunk, Indереndеnt (lоsslеss)"}
- {id: 472, cat: Audio/MP3, desc: "Rосk, Mеtаl, Аltеrnаtivе, Рunk, Indереndеnt (mp3)"}
- {id: 476, cat: Audio, desc: "Отечественный Rock"}
- {id: 477, cat: Audio/Lossless, desc: "Rосk, Punk, Alternative (losslеss)"}
- {id: 479, cat: Audio/MP3, desc: "Rосk, Punk, Alternative (mр3)"}
- {id: 477, cat: Audio/Lossless, desc: "Rосk, Metal, Punk, Alternative (losslеss)"}
- {id: 479, cat: Audio/MP3, desc: "Rосk, Metal, Punk, Alternative (mр3)"}
- {id: 482, cat: Audio, desc: "Поп-музыка, Eurodance, Disco"}
- {id: 483, cat: Audio, desc: "Зарубежная Поп-музыка"}
- {id: 484, cat: Audio, desc: "Отечественная Поп-музыка"}
- {id: 485, cat: Audio, desc: "Eurodance, Technopop, Disco"}
- {id: 489, cat: Audio/MP3, desc: "Поп-музыка, Eurodance, Disco (официальные сборники) (mp3)"}
- {id: 489, cat: Audio/MP3, desc: "Поп-музыка, Eurodance, Disco (сборники) (mp3)"}
- {id: 503, cat: Audio, desc: "Rap, Hip-Hop, R'n'B"}
- {id: 504, cat: Audio, desc: "Зарубежный Rap, Hip-Hop, R'n'B"}
- {id: 505, cat: Audio, desc: "Отечественный Rap, Hip-Hop, R'n'B"}
@@ -179,32 +140,19 @@ caps:
- {id: 535, cat: Audio, desc: "Музыка других жанров"}
- {id: 539, cat: Audio, desc: "Музыкальное видео"}
# Software # Программное обеспечение
- {id: 202, cat: PC/Mac, desc: "Mac OS (для Apple Macintosh)"}
- {id: 203, cat: PC/Mac, desc: "Mac OS (для РС-Hackintosh)"}
- {id: 208, cat: PC/Mac, desc: "[macOS] Архиваторы и файловые менеджеры"}
- {id: 204, cat: PC/Mac, desc: "[macOS] Проигрыватели и кодеки"}
- {id: 205, cat: PC/Mac, desc: "[macOS] Офисные приложения и редакторы"}
- {id: 206, cat: PC/Mac, desc: "[macOS] Работа с носителями и медиа"}
- {id: 939, cat: PC/Mac, desc: "[macOS] Информационная безопасность"}
- {id: 940, cat: PC/Mac, desc: "[macOS] Интернет-приложения"}
- {id: 207, cat: PC/Mac, desc: "Системные программы для Mac OS"}
- {id: 215, cat: PC, desc: "Операционные системы (Unix и Unix-подобные)"}
- {id: 216, cat: PC, desc: "Программное обеспечение для Unix и Unix-подобных OS"}
- {id: 217, cat: PC, desc: "Другие OS и программное обеспечение под них"}
- {id: 639, cat: TV, desc: "Обучающие видеоматериалы"}
- {id: 202, cat: TV, desc: "macOS и ПО под них"}
- {id: 274, cat: TV, desc: "Веб-разработка и программирование"}
- {id: 303, cat: TV, desc: "Материалы для мультимедиа и дизайна"}
- {id: 969, cat: PC, desc: "Windows 11"}
- {id: 905, cat: PC, desc: "Windows 10"}
- {id: 230, cat: PC, desc: "Windows 7"}
- {id: 879, cat: PC, desc: "Windows 8"}
- {id: 229, cat: PC, desc: "Windows Vista"}
- {id: 228, cat: PC, desc: "Windows XP"}
- {id: 227, cat: PC, desc: "Настольные OS, выпущенные до 2001 года (Microsoft Windows OS.."}
- {id: 970, cat: PC, desc: "Сборки (Microsoft Windows 11)"}
- {id: 906, cat: PC, desc: "Сборки (Microsoft Windows 10)"}
- {id: 701, cat: PC, desc: "Сборки (Microsoft Windows 7)"}
- {id: 880, cat: PC, desc: "Сборки (Microsoft Windows 8)"}
- {id: 698, cat: PC, desc: "Сборки (Microsoft Windows XP)"}
- {id: 231, cat: PC, desc: "Серверные (Microsoft Windows OS)"}
- {id: 232, cat: PC, desc: "Разное (Microsoft Windows OS)"}
- {id: 232, cat: PC, desc: "Разное (Microsoft Windows, WinXP, Vista, 8)"}
- {id: 236, cat: PC, desc: "Работа с жёстким диском"}
- {id: 237, cat: PC, desc: "Резервное копирование"}
- {id: 240, cat: PC, desc: "Архиваторы и файловые менеджеры"}
@@ -234,55 +182,18 @@ caps:
- {id: 263, cat: PC, desc: "Медицинское программное обеспечение"}
- {id: 264, cat: PC, desc: "Справочные системы и карты"}
- {id: 265, cat: PC, desc: "Разное (Пользовательские программы)"}
- {id: 268, cat: PC, desc: "WYSIWYG Редакторы для веб-диза"}
- {id: 269, cat: PC, desc: "Текстовые редакторы с подсветкой"}
- {id: 270, cat: PC, desc: "Среды программирования, компиляторы и вспомогательные програ.."}
- {id: 271, cat: PC, desc: "Компоненты для сред программирования"}
- {id: 272, cat: PC, desc: "Системы управления базами данных (СУБД)"}
- {id: 273, cat: PC, desc: "Скрипты и шаблоны"}
- {id: 274, cat: PC, desc: "Разное (Веб-разработка и программирование)"}
- {id: 278, cat: PC, desc: "Программные комплекты"}
- {id: 279, cat: PC, desc: "Плагины для программ компании Adobe"}
- {id: 280, cat: PC, desc: "Графические редакторы"}
- {id: 281, cat: PC, desc: "Программы для верстки, печати и работы со шрифтами"}
- {id: 282, cat: PC, desc: "3D моделирование, рендеринг и плагины для них"}
- {id: 283, cat: PC, desc: "Анимация"}
- {id: 284, cat: PC, desc: "Создание DVD и BD дисков"}
- {id: 285, cat: PC, desc: "Редакторы видео"}
- {id: 286, cat: PC, desc: "Видео- Аудио- конверторы"}
- {id: 287, cat: PC, desc: "Работа со звуком"}
- {id: 290, cat: PC, desc: "Разное (Программы для работы с мультимедиа и 3D)"}
- {id: 293, cat: PC, desc: "Растровые и Векторные Клипарты"}
- {id: 294, cat: PC, desc: "Заготовки, виньетки, рамки"}
- {id: 295, cat: PC, desc: "Стили, кисти, формы и узоры для Adobe Photoshop"}
- {id: 296, cat: PC, desc: "Текстуры и материалы"}
- {id: 297, cat: PC, desc: "3D графика"}
- {id: 298, cat: PC, desc: "Футажи"}
- {id: 299, cat: PC, desc: "Звуковые эффекты"}
- {id: 300, cat: PC, desc: "Библиотеки сэмплов"}
- {id: 301, cat: PC, desc: "Шрифты"}
- {id: 302, cat: PC, desc: "Photostoсks"}
- {id: 303, cat: PC, desc: "Разное (Материалы для мультимедиа и дизайна)"}
- {id: 597, cat: PC, desc: "Справочно-правовые Системы"}
- {id: 600, cat: PC, desc: "Консультант Плюс"}
- {id: 599, cat: PC, desc: "Гарант"}
- {id: 601, cat: PC, desc: "Кодекс"}
- {id: 623, cat: PC, desc: "Мобильные телефоны"}
- {id: 624, cat: PC, desc: "КПК"}
- {id: 625, cat: PC, desc: "Навигаторы"}
- {id: 626, cat: PC, desc: "Карты для навигаторов"}
- {id: 627, cat: PC, desc: "Плееры"}
- {id: 628, cat: PC, desc: "Разное (Мобильные устройства и КПК)"}
- {id: 622, cat: PC/Mobile-iOS, desc: "Apple Mobile Device Software"}
- {id: 667, cat: PC/Mobile-iOS, desc: "Прошивки (iPhone/iPod Touch/iPad)"}
- {id: 668, cat: PC/Mobile-iOS, desc: "Программы (iPhone/iPod Touch/iPad)"}
- {id: 669, cat: PC/Mobile-iOS, desc: "Игры (iPhone/iPod Touch/iPad)"}
- {id: 670, cat: PC/Mobile-iOS, desc: "Видео (iPhone/iPod Touch/iPad)"}
- {id: 672, cat: PC/Mobile-iOS, desc: "Разное (iPhone/iPod Touch/iPad)"}
- {id: 671, cat: PC/Mobile-iOS, desc: "Музыка (iPhone/iPod Touch/iPad)"}
- {id: 639, cat: PC, desc: "Обучающие видеоматериалы"}
- {id: 640, cat: PC, desc: "Мультимедийные материалы"}
- {id: 642, cat: PC, desc: "Разное"}
# Library # Библиотека
- {id: 717, cat: Books, desc: "Аудиокниги"}
- {id: 738, cat: Books, desc: "Детектив / боевик"}

View File

@@ -144,7 +144,7 @@ search:
text: "{{ if .Result.title_optional }}{{ .Result.title_optional }}{{ else }}{{ .Result.title_default }}{{ end }}"
filters:
- name: re_replace
args: ["(?i)\\b(FRENCH|MULTI|TRUEFRENCH|VOSTFR|SUBFRENCH)\\b(.+?)(\\b(19|20\\d{2})\\b)$", "$3 $1$2"]
args: ["(?i)\\b(FRENCH|MULTI|TRUEFRENCH|VOSTFR|SUBFRENCH)\\b(.+?)(\\b((19|20)\\d{2})\\b)$", "$3 $1$2"]
title_vostfr:
text: "{{ .Result.title_phase1 }}"
filters:

View File

@@ -0,0 +1,82 @@
---
id: torrentgalaxyclone
name: TorrentGalaxyClone
description: "TorrentGalaxyClone is a Public site for MOVIES / TV / GENERAL"
language: en-US
type: public
encoding: UTF-8
# https://proxygalaxy.cc/ for health status and alternate domains
links:
- https://torrentgalaxy.one/
- https://torrentgalaxy.info/
- https://torrentgalaxy.space/
caps:
# dont forget to update the path categories in the search block
categorymappings:
- {id: Anime, cat: TV/Anime, desc: "Anime"}
- {id: Apps, cat: PC, desc: "Apps"}
- {id: Books, cat: Books, desc: "Books"}
- {id: Docus, cat: TV/Documentary, desc: "Documentaries"}
- {id: Games, cat: Console, desc: "Games"}
- {id: Movies, cat: Movies, desc: "Movies"}
- {id: Music, cat: Audio, desc: "Music"}
- {id: Other, cat: Other, desc: "Other"}
- {id: TV, cat: TV, desc: "TV"}
- {id: XXX, cat: XXX, desc: "XXX"}
modes:
search: [q]
tv-search: [q, season, ep, imdbid]
movie-search: [q, imdbid]
music-search: [q]
book-search: [q]
settings: []
download:
selectors:
- selector: a[href^="magnet:?xt="]
attribute: href
search:
# https://torrentgalaxy.one/get-posts/keywords:tt1890725/
# https://torrentgalaxy.one/get-posts/keywords:andor/
# https://torrentgalaxy.one/get-posts/category:Movies:category:TV:keywords:bodies
paths:
- path: "get-posts/{{ if or .Query.IMDBID .Keywords }}keywords:{{ or .Query.IMDBID .Keywords }}{{ else }}{{ end }}{{ range .Categories }}:category:{{.}}{{end}}"
rows:
selector: div.tgxtablerow
fields:
category:
selector: a[href^="/get-posts/category:"]
title:
selector: a[href^="/post-detail/"]
attribute: title
details:
selector: a[href^="/post-detail/"]
attribute: href
download:
selector: a[href^="/post-detail/"]
attribute: href
imdbid:
selector: a[href^="/get-posts/keywords:tt"]
attribute: href
size:
selector: div.tgxtablecell:nth-last-child(5)
seeders:
selector: div.tgxtablecell:nth-last-child(2) span font
leechers:
selector: div.tgxtablecell:nth-last-child(2) span font:nth-of-type(2)
date:
selector: div.tgxtablecell:nth-last-child(1)
remove: div.bighide
filters:
- name: timeago
downloadvolumefactor:
text: 0
uploadvolumefactor:
text: 1
# engine n/a

View File

@@ -7,11 +7,9 @@ type: public
encoding: UTF-8
followredirect: true
links:
- https://torrentqq367.com/
- https://torrentegg59.com/
- https://torrentqq368.com/
- https://torrentegg60.com/
legacylinks:
- https://torrentqq353.com/
- https://torrentegg45.com/
- https://torrentqq354.com/
- https://torrentegg46.com/
- https://torrentqq355.com/
@@ -38,6 +36,8 @@ legacylinks:
- https://torrentegg57.com/
- https://torrentqq366.com/
- https://torrentegg58.com/
- https://torrentqq367.com/
- https://torrentegg59.com/
caps:
categorymappings:

View File

@@ -7,10 +7,8 @@ type: public
encoding: UTF-8
followredirect: true
links:
- https://torrentsir173.com/
- https://torrentsir174.com/
legacylinks:
- http://torrentsir162.com/
- https://torrentsir162.com/
- http://torrentsir163.com/
- https://torrentsir163.com/
- http://torrentsir164.com/
@@ -32,6 +30,8 @@ legacylinks:
- http://torrentsir172.com/
- https://torrentsir172.com/
- http://torrentsir173.com/
- https://torrentsir173.com/
- http://torrentsir174.com/
caps:
categorymappings:

View File

@@ -9,7 +9,7 @@ followredirect: true
requestDelay: 2
# to fetch current domain use https://tzip.top/
links:
- https://torrentsome194.com/
- https://torrentsome195.com/
legacylinks:
- https://torrentsome184.com/
- https://torrentsome185.com/
@@ -21,6 +21,7 @@ legacylinks:
- https://torrentsome191.com/
- https://torrentsome192.com/
- https://torrentsome193.com/
- https://torrentsome194.com/
caps:
categorymappings:

View File

@@ -9,7 +9,7 @@ followredirect: true
requestDelay: 2
# to fetch current domain use https://tzip.top/
links:
- https://torrenttip175.com/
- https://torrenttip176.com/
legacylinks:
- https://Torrenttip165.com/
- https://Torrenttip166.com/
@@ -21,6 +21,7 @@ legacylinks:
- https://torrenttip172.com/
- https://torrenttip173.com/
- https://torrenttip174.com/
- https://torrenttip175.com/
caps:
categorymappings:

View File

@@ -200,4 +200,4 @@ search:
minimumseedtime:
# 2 days (as seconds = 2 x 24 x 60 x 60)
text: 172800
# json UNIT3D 8.3.6
# json UNIT3D 9.0.8

View File

@@ -31,11 +31,12 @@ settings: []
search:
paths:
# https://uindex.org/search.php?search=complete
# https://uindex.org/search.php?search=complete&c=0
- path: search.php
allowEmptyInputs: true
inputs:
search: "{{ .Keywords }}"
c: 0
rows:
selector: table.maintable > tbody > tr:has(a[href^="magnet:?xt="])

View File

@@ -98,7 +98,7 @@ search:
- name: replace
args: ["WEBRIP", "WEBDL"]
- name: re_replace
args: ["(?i)\\b(FRENCH|MULTI|TRUEFRENCH|VOSTFR|SUBFRENCH)\\b(.+?)(\\b(19|20\\d{2})\\b)$", "$3 $1$2"]
args: ["(?i)\\b(FRENCH|MULTI|TRUEFRENCH|VOSTFR|SUBFRENCH)\\b(.+?)(\\b((19|20)\\d{2})\\b)$", "$3 $1$2"]
title_vostfr:
text: "{{ .Result.title_phase1 }}"
filters:

View File

@@ -117,7 +117,7 @@ search:
selector: a
filters:
- name: re_replace
args: ["(?i)\\b(FRENCH|MULTI|TRUEFRENCH|VOSTFR|SUBFRENCH)\\b(.+?)(\\b(19|20\\d{2})\\b)$", "$3 $1$2"]
args: ["(?i)\\b(FRENCH|MULTI|TRUEFRENCH|VOSTFR|SUBFRENCH)\\b(.+?)(\\b((19|20)\\d{2})\\b)$", "$3 $1$2"]
title_vostfr:
text: "{{ .Result.title_phase1 }}"
filters:

View File

@@ -0,0 +1,346 @@
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.RegularExpressions;
using System.Threading.Tasks;
using AngleSharp.Dom;
using AngleSharp.Html.Parser;
using AngleSharp.Io;
using FlareSolverrSharp.Types;
using Jackett.Common.Extensions;
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.Definitions
{
[ExcludeFromCodeCoverage]
public class ArabicSource : IndexerBase
{
public override string Id => "arabicsource";
public override string Name => "ArabicSource";
public override string Description => "ArabicSource is an ARABIC Private Torrent Tracker for MOVIES / TV";
public override string SiteLink { get; protected set; } = "https://arabicsource.net/";
public override string Language => "ar-SA";
public override string Type => "private";
public override TorznabCapabilities TorznabCaps => SetCapabilities();
private string SearchUrl => SiteLink + "browse.php?";
private string SubmitLoginUrl => SiteLink + "takelogin.php";
private string IndexUrl => SiteLink + "index.php";
private string ThankYouUrl => SiteLink + "ts_ajax.php";
private string TakeThanksUrl => SiteLink + "takethanks.php";
private readonly Regex _idRegex = new Regex(@"TSajaxquickcomment\(\'(\d+)\'", RegexOptions.IgnoreCase);
private readonly Regex _lcidRegex = new Regex(@"TSajaxquickcomment\(\'\d+\', \'(\d+)\'", RegexOptions.IgnoreCase);
private new ConfigurationDataBasicLogin configData
{
get => (ConfigurationDataBasicLogin)base.configData;
set => base.configData = value;
}
public ArabicSource(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 ConfigurationDataBasicLogin("For best results, change the <b>Torrents per page:</b> setting to <b>40</b> on your account profile. The Default is <i>15</i>."))
{
configData.AddDynamic("thankyoutext", new StringConfigurationItem("Thank You Text"));
configData.AddDynamic("Thank you comment", new DisplayInfoConfigurationItem("Thank you comment", "This site requires you to leave a Thank You comment before you can download. Enter your personalised plain text comment above."));
configData.AddDynamic("freeleech", new BoolConfigurationItem("Search freeleech only") { Value = false });
// Configure the sort selects
var sortBySelect = new SingleSelectConfigurationItem(
"Sort by",
new Dictionary<string, string>
{
{ "added", "created" },
{ "seeders", "seeders" },
{ "size", "size" },
{ "name", "title" }
})
{ Value = "added" };
configData.AddDynamic("sortrequestedfromsite", sortBySelect);
var orderSelect = new SingleSelectConfigurationItem(
"Order",
new Dictionary<string, string>
{
{ "desc", "descending" },
{ "asc", "ascending" }
})
{ Value = "desc" };
configData.AddDynamic("orderrequestedfromsite", orderSelect);
configData.AddDynamic("includevip", new BoolConfigurationItem(" Include VIP results") { Value = false });
configData.AddDynamic("Account Inactivity", new DisplayInfoConfigurationItem("Account Inactivity", "The maximum number of days you can stay away from the site is 40 days, and only if you suspend the account, you will get a grace period of 180 days, but you must contact the administration in advance so that this is added to your personal account and you are not exposed to expulsion."));
}
private TorznabCapabilities SetCapabilities()
{
var caps = new TorznabCapabilities
{
TvSearchParams = new List<TvSearchParam>
{
TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep, TvSearchParam.ImdbId
},
MovieSearchParams = new List<MovieSearchParam>
{
MovieSearchParam.Q, MovieSearchParam.ImdbId
},
MusicSearchParams = new List<MusicSearchParam>
{
MusicSearchParam.Q
},
BookSearchParams = new List<BookSearchParam>
{
BookSearchParam.Q
}
};
caps.Categories.AddCategoryMapping(52, TorznabCatType.Movies, "(أفلام الرسوم المدبلجة) dubbed animated movies");
caps.Categories.AddCategoryMapping(53, TorznabCatType.MoviesHD, "(أفلام الرسوم المدبلجة) dubbed animated movies 1080p)");
caps.Categories.AddCategoryMapping(55, TorznabCatType.Movies3D, "(أفلام الرسوم المدبلجة) dubbed animated movies 3D");
caps.Categories.AddCategoryMapping(78, TorznabCatType.MoviesUHD, "(أفلام الرسوم المدبلجة) dubbed animated movies 4K");
caps.Categories.AddCategoryMapping(54, TorznabCatType.MoviesHD, "(أفلام الرسوم المدبلجة) dubbed animated movies 720p");
caps.Categories.AddCategoryMapping(56, TorznabCatType.MoviesDVD, "(أفلام الرسوم المدبلجة) dubbed animated movies DVD");
caps.Categories.AddCategoryMapping(58, TorznabCatType.MoviesHD, "(أفلام الرسوم المدبلجة) dubbed animated movies HDTV1080p");
caps.Categories.AddCategoryMapping(57, TorznabCatType.Movies, "(أفلام الرسوم المدبلجة) dubbed animated movies TVRip");
caps.Categories.AddCategoryMapping(72, TorznabCatType.Movies, "(الأفلام العربية) Arabic films");
caps.Categories.AddCategoryMapping(15, TorznabCatType.Other, "(الحصرية) VIP");
caps.Categories.AddCategoryMapping(42, TorznabCatType.Movies, "(الحصرية أفلام) VIP movies");
caps.Categories.AddCategoryMapping(20, TorznabCatType.TVAnime, "(الحصرية رسوم) VIP cartoons ");
caps.Categories.AddCategoryMapping(41, TorznabCatType.AudioVideo, "(الحصرية مسرحيات) VIP plays");
caps.Categories.AddCategoryMapping(21, TorznabCatType.TV, "(الحصرية مسلسلات) VIP series");
caps.Categories.AddCategoryMapping(35, TorznabCatType.AudioVideo, "(المسرحيات العربية) Arabic plays");
caps.Categories.AddCategoryMapping(5, TorznabCatType.TV, "(المسلسلات العربية) Arabic series");
caps.Categories.AddCategoryMapping(81, TorznabCatType.TVForeign, "(المسلسلات العربية الآسيوية) Arabic series Asian");
caps.Categories.AddCategoryMapping(79, TorznabCatType.TVForeign, "(المسلسلات العربية التركية) Arabic series Turkish ");
caps.Categories.AddCategoryMapping(80, TorznabCatType.TVForeign, "(المسلسلات العربية الهندية) Arabic series Hindi");
caps.Categories.AddCategoryMapping(69, TorznabCatType.Movies, "(الوسائط المترجمة) Translated media");
caps.Categories.AddCategoryMapping(70, TorznabCatType.Movies, "(الوسائط المترجمة فلام رسوم) Translated Animated Movies");
caps.Categories.AddCategoryMapping(71, TorznabCatType.Movies, "(الوسائط المترجمة لأفلام الأجنبية) Translated Foreign films");
caps.Categories.AddCategoryMapping(77, TorznabCatType.Movies, "(الوسائط المترجمة الأفلام الهندية) Translated Indian movies");
caps.Categories.AddCategoryMapping(86, TorznabCatType.Movies, "(الوسائط المترجمة مسلسلات الرسوم المترجمة) Translated cartoon series");
caps.Categories.AddCategoryMapping(14, TorznabCatType.TV, "(رمضانيات) Ramadan");
caps.Categories.AddCategoryMapping(7, TorznabCatType.TVAnime, "(مسلسلات الرسوم المدبلجة) Dubbed cartoon series");
caps.Categories.AddCategoryMapping(61, TorznabCatType.TVAnime, "(مسلسلات الرسوم المدبلجة) Dubbed cartoon series1080p");
caps.Categories.AddCategoryMapping(62, TorznabCatType.TVAnime, "(مسلسلات الرسوم المدبلجة) Dubbed cartoon series 720p");
caps.Categories.AddCategoryMapping(63, TorznabCatType.TVAnime, "(مسلسلات الرسوم المدبلجة) Dubbed cartoon series DVD");
caps.Categories.AddCategoryMapping(65, TorznabCatType.TVAnime, "(مسلسلات الرسوم المدبلجة) Dubbed cartoon series HDTV1080p");
caps.Categories.AddCategoryMapping(64, TorznabCatType.TVAnime, "(مسلسلات الرسوم المدبلجة) Dubbed cartoon series TVRip");
caps.Categories.AddCategoryMapping(31, TorznabCatType.Other, "(وسائط منوعات) Miscellaneous media");
caps.Categories.AddCategoryMapping(67, TorznabCatType.Other, "(وسائط منوعات إسلاميات) Miscellaneous media Islamic Studies");
caps.Categories.AddCategoryMapping(32, TorznabCatType.Other, "(وسائط منوعات تربوي) Miscellaneous media Educational");
caps.Categories.AddCategoryMapping(76, TorznabCatType.Audio, "(وسائط منوعات صوتيات) Miscellaneous media Phonetics");
caps.Categories.AddCategoryMapping(68, TorznabCatType.TVAnime, "(وسائط منوعات كرتون كلاسيك) Miscellaneous media Classic Cartoon");
caps.Categories.AddCategoryMapping(66, TorznabCatType.TVDocumentary, "(وسائط منوعات وثائقيات) Miscellaneous media Documentaries");
return caps;
}
private string GetSortBy => ((SingleSelectConfigurationItem)configData.GetDynamic("sortrequestedfromsite")).Value;
private string GetOrder => ((SingleSelectConfigurationItem)configData.GetDynamic("orderrequestedfromsite")).Value;
private string GetThankYouText => ((StringConfigurationItem)configData.GetDynamic("thankyoutext")).Value;
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
LoadValuesFromJson(configJson);
if (GetThankYouText.IsNullOrWhiteSpace())
{
throw new Exception("The Thank You Text in the config is missing. Site requires a thank you comment before download is allowed.");
}
// if we are already logged in, then we need to logout to use login form
var testLoggedin = await RequestWithCookiesAndRetryAsync(IndexUrl);
if (testLoggedin.Status == HttpStatusCode.OK && testLoggedin.ContentString.Contains("/logout.php?logouthash="))
{
var logoutParser = new HtmlParser();
using var document = logoutParser.ParseDocument(testLoggedin.ContentString);
var logoutUrl = document.QuerySelector("a[href*=\"/logout.php?logouthash=\"]").GetAttribute("href");
var logout = await RequestWithCookiesAsync(logoutUrl);
}
// performing login
var pairs = new Dictionary<string, string> {
{ "username", configData.Username.Value },
{ "password", configData.Password.Value },
{ "logout", "" }
};
var response = await RequestLoginAndFollowRedirect(SubmitLoginUrl, pairs, null, true, null, IndexUrl);
await ConfigureIfOK(response.Cookies, response.ContentString.Contains("/logout.php?logouthash="), () =>
{
var htmlParser = new HtmlParser();
using var document = htmlParser.ParseDocument(response.ContentString);
var errorMessage = document.QuerySelector("table:contains(\"ERROR:\")")?.Text().Trim();
throw new ExceptionWithConfigData(errorMessage ?? "Login failed.", configData);
});
return IndexerConfigurationStatus.RequiresTesting;
}
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>();
var searchUrl = SearchUrl;
var queryCollection = new NameValueCollection
{
{ "do", "search" },
{ "keywords", query.ImdbID ?? query.GetQueryString() },
// t_name, t_description, t_both, t_uploader, t_genre
{ "search_type", query.ImdbID.IsNotNullOrWhiteSpace() ? "t_genre" : "t_name" },
// does not support multi category searching so defaulting to all.
{ "category", "0" },
{ "include_dead_torrents", "yes" },
{ "sort", ((BoolConfigurationItem)configData.GetDynamic("freeleech")).Value ? "free" : GetSortBy },
{ "order", ((BoolConfigurationItem)configData.GetDynamic("freeleech")).Value ? "asc" : GetOrder }
};
// add masking to prevent exact matches only and mostly bypass the minimum 4 char word length block
searchUrl += queryCollection.GetQueryString().Replace("+", "%");
var results = await RequestWithCookiesAndRetryAsync(searchUrl);
// Occasionally the cookies become invalid, login again if that happens
if (!results.ContentString.Contains("/logout.php?logouthash="))
{
await ApplyConfiguration(null);
results = await RequestWithCookiesAndRetryAsync(searchUrl);
}
try
{
var parser = new HtmlParser();
using var dom = parser.ParseDocument(results.ContentString);
var rowSelector = "table.sortable tr:has(a[href*=\"download.php?id=\"])";
if (!((BoolConfigurationItem)configData.GetDynamic("includevip")).Value)
{
rowSelector += ":not(:has(a[href$=\"?category=15\"])):not(:has(a[href$=\"?category=20\"])):not(:has(a[href$=\"?category=21\"])):not(:has(a[href$=\"?category=41\"])):not(:has(a[href$=\"?category=42\"]))";
}
var rows = dom.QuerySelectorAll(rowSelector);
foreach (var row in rows)
{
var categoryLink = row.QuerySelector("a[href*=\"?category=\"]").GetAttribute("href");
var cat = ParseUtil.GetArgumentFromQueryString(categoryLink, "category");
var description = string.Empty;
switch (cat)
{
case "15":
case "20":
case "21":
case "41":
case "42":
description = "**VIP**";
break;
default:
break;
}
var qDetailsLink = row.QuerySelector("a[href*=\"details.php?id=\"]");
var title = qDetailsLink.TextContent + description;
var details = new Uri(qDetailsLink.GetAttribute("href"));
var poster = new Uri(row.QuerySelector("img[src*=\"/torrents/images/\"]").GetAttribute("src"));
var size = ParseUtil.GetBytes(row.QuerySelector("td:nth-last-child(5)").TextContent);
var matchDateAdded = Regex.Match(row.QuerySelector(" td:nth-child(2)").TextContent, @"(\d{2}-\d{2}-\d{4} \d{2}:\d{2})", RegexOptions.IgnoreCase);
var publishDate = matchDateAdded.Groups[1].Success && DateTime.TryParseExact(matchDateAdded.Groups[1].Value, "dd-MM-yyyy HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out var parsedDate) ? parsedDate : DateTime.Now;
var grabs = ParseUtil.CoerceInt(row.QuerySelector("td:nth-last-child(4)").TextContent);
var seeders = ParseUtil.CoerceInt(row.QuerySelector("td:nth-last-child(3)").TextContent);
var leechers = ParseUtil.CoerceInt(row.QuerySelector("td:nth-last-child(2)").TextContent) + seeders;
var dlVolumeFactor = 1.0;
var upVolumeFactor = 1.0;
if (row.QuerySelector("img[src$=\"/freedownload.gif\"]") != null)
dlVolumeFactor = 0;
else if (row.QuerySelector("img[src$=\"/silverdownload.gif\"]") != null)
dlVolumeFactor = 0.5;
if (row.QuerySelector("img[src$=\"/x2.gif\"]") != null)
upVolumeFactor = 2;
var release = new ReleaseInfo
{
Title = title,
Details = details,
Guid = details,
Link = details,
PublishDate = publishDate,
Category = MapTrackerCatToNewznab(cat),
Poster = poster,
Size = size,
Grabs = grabs,
Seeders = seeders,
Peers = leechers,
Description = description,
DownloadVolumeFactor = dlVolumeFactor,
UploadVolumeFactor = upVolumeFactor,
MinimumRatio = 1.05
};
releases.Add(release);
}
}
catch (Exception ex)
{
OnParseError(results.ContentString, ex);
}
return releases;
}
public override async Task<byte[]> Download(Uri link)
{
// before downloads are allowed, users must leave a comment on the comments section
// of the details page, and then press the SayThanks button on the info section 8-O
var detailsPage = await RequestWithCookiesAsync(link.ToString());
var htmlParser = new HtmlParser();
using var dom = htmlParser.ParseDocument(detailsPage.ContentString);
// <input type="button" class="button" value="Submit" name="quickcomment" id="quickcomment" onclick="javascript:TSajaxquickcomment('9999', '9');"/>
var quickCommentLink = dom.QuerySelector("#quickcomment").GetAttribute("onclick");
var idMatch = _idRegex.Match(quickCommentLink);
var qcid = idMatch.Success ? idMatch.Groups[1].Value : null;
var lcidMatch = _lcidRegex.Match(quickCommentLink);
var qclcid = lcidMatch.Success ? lcidMatch.Groups[1].Value : null;
if (qcid.IsNullOrWhiteSpace() || qclcid.IsNullOrWhiteSpace())
{
throw new Exception("Unable to extract quickComment data from details page at " + link.ToString());
}
var thankYouPairs = new Dictionary<string, string> {
{ "ajax_quick_comment", "1" },
{ "id", qcid },
{ "lcid", qclcid },
{ "text", GetThankYouText }
};
var thankYouResponse = await RequestLoginAndFollowRedirect(ThankYouUrl, thankYouPairs, null, true, null, ThankYouUrl);
// <input type="button" value="Say thanks!" onclick="javascript:TSajaxquickthanks(9999);"/>
var takeThanksPairs = new Dictionary<string, string> {
{ "torrentid", qcid }
};
var takeThanksResponse = await RequestLoginAndFollowRedirect(TakeThanksUrl, takeThanksPairs, null, true, null, TakeThanksUrl);
var downloadLink = dom.QuerySelector("a[href*=\"download.php?id=\"]")?.GetAttribute("href")?.Trim();
if (downloadLink.IsNullOrWhiteSpace())
{
throw new Exception("Unable to find download link.");
}
var response = await RequestWithCookiesAsync(downloadLink);
return response.ContentBytes;
}
}
}

View File

@@ -47,6 +47,7 @@ namespace Jackett.Common.Indexers.Definitions
{
configData.AddDynamic("freeleech", new BoolConfigurationItem("Search freeleech only") { Value = false });
configData.AddDynamic("Account Inactivity", new DisplayInfoConfigurationItem("Account Inactivity", "Inactive accounts are disabled after 2 months days for User class, after 3 months for Power User, after 4 months for Elite User, after 6 months for Insane User, after 9 months for Veteran User, after 11 months for VIP, after 12 months for Dedicated BHD User & all Staff. Parking your account doubles the maximum inactive time. Only the login and browsing the site is considered activity."));
configData.AddDynamic("Rate Limits", new DisplayInfoConfigurationItem("Rate Limits", "BitHDTV has rate limits, the indexer will fail if you exceed them. Read the post at <a href=\"https://www.bit-hdtv.com/forums/viewtopic.php?id=18657\" target=\"_blank\">forum topic 18657</a>"));
}
private TorznabCapabilities SetCapabilities()
@@ -83,7 +84,9 @@ namespace Jackett.Common.Indexers.Definitions
{
var results = await PerformQuery(new TorznabQuery());
if (!results.Any())
{
throw new Exception("Found 0 results in the tracker");
}
IsConfigured = true;
SaveConfig();
@@ -110,7 +113,9 @@ namespace Jackett.Common.Indexers.Definitions
// free=1 normal: (DL and UL counted as normal.)
// free=0 (any)
if (((BoolConfigurationItem)configData.GetDynamic("freeleech")).Value)
{
qc.Add("free", "2");
}
var results = new List<WebResult>();
var search = new UriBuilder(SearchUrl);
@@ -142,13 +147,20 @@ namespace Jackett.Common.Indexers.Definitions
var parser = new HtmlParser();
foreach (var result in results)
{
try
{
if (result.ContentString.Contains("Request limit per User exceeded! Please try later!"))
{
throw new Exception("Request limit per User exceeded! Please try later!");
}
using var dom = parser.ParseDocument(result.ContentString);
var tableBody = dom.QuerySelector("#torrents-index-table > #torrents-index-table-body");
if (tableBody == null) // No results, so skip this search
{
continue;
}
foreach (var row in tableBody.Children)
{
@@ -160,7 +172,9 @@ namespace Jackett.Common.Indexers.Definitions
var detailsLink = new Uri(qLink.GetAttribute("href"));
//Skip irrelevant and duplicate entries
if (!query.MatchQueryStringAND(release.Title) || releases.Any(r => r.Guid == detailsLink))
{
continue;
}
var genres = row.QuerySelector("font.small")?.TextContent;
if (!string.IsNullOrEmpty(genres))
@@ -214,6 +228,7 @@ namespace Jackett.Common.Indexers.Definitions
{
OnParseError(result.ContentString, ex);
}
}
return releases;
}

View File

@@ -29,10 +29,10 @@ namespace Jackett.Common.Indexers.Definitions
public override string Name => "DonTorrent";
public override string Description => "DonTorrent is a SPANISH Public tracker for MOVIES / TV / GENERAL";
// in the event the redirect is inactive https://t.me/s/dontorrent should have the latest working domain
public override string SiteLink { get; protected set; } = "https://dontorrent.download/";
public override string SiteLink { get; protected set; } = "https://dontorrent.gift/";
public override string[] AlternativeSiteLinks => new[]
{
"https://dontorrent.download/",
"https://dontorrent.gift/",
"https://todotorrents.org/",
"https://tomadivx.net/",
"https://seriesblanco.one/",
@@ -41,7 +41,6 @@ namespace Jackett.Common.Indexers.Definitions
};
public override string[] LegacySiteLinks => new[]
{
"https://dontorrent.gallery/",
"https://dontorrent.yoga/",
"https://dontorrent.foundation/",
"https://dontorrent.co/",
@@ -56,6 +55,7 @@ namespace Jackett.Common.Indexers.Definitions
"https://dontorrent.stream/",
"https://dontorrent.website/",
"https://dontorrent.group/",
"https://dontorrent.download/",
};
public override string Language => "es-ES";
public override string Type => "public";

View File

@@ -196,8 +196,9 @@ namespace Jackett.Common.Indexers.Definitions
var title = mainLink.TextContent;
var details = new Uri(SiteLink + mainLink.GetAttribute("href"));
var posterMatch = _posterRegex.Match(mainLink.GetAttribute("onmouseover"));
var poster = posterMatch.Success ? new Uri(SiteLink + posterMatch.Groups[1].Value.Replace("\\", "/")) : null;
// posters, when fetched on the dashboard search results page, generate cloudflare challenges
// var posterMatch = _posterRegex.Match(mainLink.GetAttribute("onmouseover"));
// var poster = posterMatch.Success ? new Uri(SiteLink + posterMatch.Groups[1].Value.Replace("\\", "/")) : null;
var link = new Uri(SiteLink + row.Children[4].FirstElementChild.GetAttribute("href"));
var description = row.Children[2].QuerySelector("span")?.TextContent.Trim();
@@ -260,7 +261,7 @@ namespace Jackett.Common.Indexers.Definitions
PublishDate = publishDate,
Category = MapTrackerCatToNewznab(cat),
Description = description,
Poster = poster,
// Poster = poster,
Imdb = imdb,
Size = size,
Grabs = grabs,

View File

@@ -1,369 +0,0 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using AngleSharp.Html.Parser;
using Jackett.Common.Models;
using Jackett.Common.Models.IndexerConfig.Bespoke;
using Jackett.Common.Services.Interfaces;
using Jackett.Common.Utils;
using Jackett.Common.Utils.Clients;
using Microsoft.AspNetCore.WebUtilities;
using Newtonsoft.Json.Linq;
using NLog;
namespace Jackett.Common.Indexers.Definitions
{
[ExcludeFromCodeCoverage]
public class NCore : IndexerBase
{
public override string Id => "ncore";
public override string Name => "nCore";
public override string Description => "nCore is a HUNGARIAN Private site.";
public override string SiteLink { get; protected set; } = "https://ncore.pro/";
public override string[] LegacySiteLinks => new[]
{
"https://ncore.cc/"
};
public override string Language => "hu-HU";
public override string Type => "private";
public override TorznabCapabilities TorznabCaps => SetCapabilities();
private string LoginUrl => SiteLink + "login.php";
private string SearchUrl => SiteLink + "torrents.php";
private new ConfigurationDataNCore configData => (ConfigurationDataNCore)base.configData;
private readonly string[] _languageCats =
{
"xvidser",
"dvdser",
"hdser",
"xvid",
"dvd",
"dvd9",
"hd",
"mp3",
"lossless",
"ebook"
};
public NCore(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps,
ICacheService cs)
: base(configService: configService,
client: wc,
logger: l,
p: ps,
cacheService: cs,
configData: new ConfigurationDataNCore())
{
}
private TorznabCapabilities SetCapabilities()
{
var caps = new TorznabCapabilities
{
TvSearchParams = new List<TvSearchParam>
{
TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep, TvSearchParam.ImdbId
},
MovieSearchParams = new List<MovieSearchParam>
{
MovieSearchParam.Q, MovieSearchParam.ImdbId
},
MusicSearchParams = new List<MusicSearchParam>
{
MusicSearchParam.Q
},
BookSearchParams = new List<BookSearchParam>
{
BookSearchParam.Q
}
};
caps.Categories.AddCategoryMapping("xvid_hun", TorznabCatType.MoviesSD, "Film SD/HU");
caps.Categories.AddCategoryMapping("xvid", TorznabCatType.MoviesSD, "Film SD/EN");
caps.Categories.AddCategoryMapping("dvd_hun", TorznabCatType.MoviesDVD, "Film DVDR/HU");
caps.Categories.AddCategoryMapping("dvd", TorznabCatType.MoviesDVD, "Film DVDR/EN");
caps.Categories.AddCategoryMapping("dvd9_hun", TorznabCatType.MoviesDVD, "Film DVD9/HU");
caps.Categories.AddCategoryMapping("dvd9", TorznabCatType.MoviesDVD, "Film DVD9/EN");
caps.Categories.AddCategoryMapping("hd_hun", TorznabCatType.MoviesHD, "Film HD/HU");
caps.Categories.AddCategoryMapping("hd", TorznabCatType.MoviesHD, "Film HD/EN");
caps.Categories.AddCategoryMapping("xvidser_hun", TorznabCatType.TVSD, "Sorozat SD/HU");
caps.Categories.AddCategoryMapping("xvidser", TorznabCatType.TVSD, "Sorozat SD/EN");
caps.Categories.AddCategoryMapping("dvdser_hun", TorznabCatType.TVSD, "Sorozat DVDR/HU");
caps.Categories.AddCategoryMapping("dvdser", TorznabCatType.TVSD, "Sorozat DVDR/EN");
caps.Categories.AddCategoryMapping("hdser_hun", TorznabCatType.TVHD, "Sorozat HD/HU");
caps.Categories.AddCategoryMapping("hdser", TorznabCatType.TVHD, "Sorozat HD/EN");
caps.Categories.AddCategoryMapping("mp3_hun", TorznabCatType.AudioMP3, "Zene MP3/HU");
caps.Categories.AddCategoryMapping("mp3", TorznabCatType.AudioMP3, "Zene MP3/EN");
caps.Categories.AddCategoryMapping("lossless_hun", TorznabCatType.AudioLossless, "Zene Lossless/HU");
caps.Categories.AddCategoryMapping("lossless", TorznabCatType.AudioLossless, "Zene Lossless/EN");
caps.Categories.AddCategoryMapping("clip", TorznabCatType.AudioVideo, "Zene Klip");
caps.Categories.AddCategoryMapping("xxx_xvid", TorznabCatType.XXXXviD, "XXX SD");
caps.Categories.AddCategoryMapping("xxx_dvd", TorznabCatType.XXXDVD, "XXX DVDR");
caps.Categories.AddCategoryMapping("xxx_imageset", TorznabCatType.XXXImageSet, "XXX Imageset");
caps.Categories.AddCategoryMapping("xxx_hd", TorznabCatType.XXX, "XXX HD");
caps.Categories.AddCategoryMapping("game_iso", TorznabCatType.PCGames, "Játék PC/ISO");
caps.Categories.AddCategoryMapping("game_rip", TorznabCatType.PCGames, "Játék PC/RIP");
caps.Categories.AddCategoryMapping("console", TorznabCatType.Console, "Játék Konzol");
caps.Categories.AddCategoryMapping("iso", TorznabCatType.PCISO, "Program Prog/ISO");
caps.Categories.AddCategoryMapping("misc", TorznabCatType.PC0day, "Program Prog/RIP");
caps.Categories.AddCategoryMapping("mobil", TorznabCatType.PCMobileOther, "Program Prog/Mobil");
caps.Categories.AddCategoryMapping("ebook_hun", TorznabCatType.Books, "Könyv eBook/HU");
caps.Categories.AddCategoryMapping("ebook", TorznabCatType.Books, "Könyv eBook/EN");
return caps;
}
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
LoadValuesFromJson(configJson);
if (configData.Hungarian.Value == false && configData.English.Value == false)
throw new ExceptionWithConfigData("Please select at least one language.", configData);
var loginPage = await RequestWithCookiesAsync(LoginUrl, string.Empty);
var pairs = new Dictionary<string, string>
{
{"nev", configData.Username.Value},
{"pass", configData.Password.Value},
{"ne_leptessen_ki", "1"},
{"set_lang", "en"},
{"submitted", "1"},
{"submit", "Access!"}
};
if (!string.IsNullOrEmpty(configData.TwoFactor.Value))
pairs.Add("2factor", configData.TwoFactor.Value);
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, referer: SiteLink);
await ConfigureIfOK(
result.Cookies, result.ContentString?.Contains("profile.php") == true, () =>
{
var parser = new HtmlParser();
using var dom = parser.ParseDocument(result.ContentString);
var msgContainer = dom.QuerySelector("#hibauzenet table tbody tr")?.Children[1];
throw new ExceptionWithConfigData(msgContainer?.TextContent ?? "Error while trying to login.", configData);
});
return IndexerConfigurationStatus.RequiresTesting;
}
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var results = new List<ReleaseInfo>();
if (!(query.IsImdbQuery && query.IsTVSearch))
results = await PerformQueryAsync(query, null);
// if we search for a localized title nCore can't handle any extra S/E information
// search without it and AND filter the results. See #1450
if (query.IsTVSearch && (!results.Any() || query.IsImdbQuery))
results = await PerformQueryAsync(query, query.GetEpisodeSearchString());
return results;
}
private async Task<List<ReleaseInfo>> PerformQueryAsync(TorznabQuery query, string episodeString)
{
var releases = new List<ReleaseInfo>();
var pairs = new NameValueCollection
{
{"nyit_sorozat_resz", "true"},
{"tipus", "kivalasztottak_kozott"},
{"submit.x", "1"},
{"submit.y", "1"},
{"submit", "Ok"}
};
if (query.IsImdbQuery)
{
pairs.Add("miben", "imdb");
pairs.Add("mire", query.ImdbID);
}
else
{
pairs.Add("miben", "name");
pairs.Add("mire", episodeString == null ? query.GetQueryString() : query.SanitizedSearchTerm);
}
var cats = MapTorznabCapsToTrackers(query);
if (cats.Count == 0)
cats = GetAllTrackerCategories();
if (!configData.Hungarian.Value)
cats.RemoveAll(cat => cat.Contains("_hun"));
if (!configData.English.Value)
cats = cats.Except(_languageCats).ToList();
pairs.Add("kivalasztott_tipus[]", string.Join(",", cats));
var results = await RequestWithCookiesAndRetryAsync(
SearchUrl, null, RequestType.POST, null, pairs.ToEnumerable(true));
var parser = new HtmlParser();
using var dom = parser.ParseDocument(results.ContentString);
// find number of torrents / page
var torrentPerPage = dom.QuerySelectorAll(".box_torrent").Length;
if (torrentPerPage == 0)
return releases;
var startPage = (query.Offset / torrentPerPage) + 1;
var previouslyParsedOnPage = query.Offset % torrentPerPage;
// find page links in the bottom
var lastPageLink = dom.QuerySelectorAll("div[id=pager_bottom] a[href*=oldal]")
.LastOrDefault()?.GetAttribute("href");
var pages = int.TryParse(ParseUtil.GetArgumentFromQueryString(lastPageLink, "oldal"), out var lastPage)
? lastPage
: 1;
var limit = query.Limit;
if (limit == 0)
limit = 100;
if (startPage == 1)
{
releases = ParseTorrents(results, episodeString, query, releases.Count, limit, previouslyParsedOnPage);
previouslyParsedOnPage = 0;
startPage++;
}
// Check all the pages for the torrents.
// The starting index is 2. (the first one is the original where we parse out the pages.)
for (var page = startPage; page <= pages && releases.Count < limit; page++)
{
pairs["oldal"] = page.ToString();
results = await RequestWithCookiesAndRetryAsync(
SearchUrl, null, RequestType.POST, null, pairs.ToEnumerable(true));
releases.AddRange(ParseTorrents(results, episodeString, query, releases.Count, limit, previouslyParsedOnPage));
previouslyParsedOnPage = 0;
}
return releases;
}
private List<ReleaseInfo> ParseTorrents(WebResult results, string episodeString, TorznabQuery query,
int alreadyFound, int limit, int previouslyParsedOnPage)
{
var releases = new List<ReleaseInfo>();
try
{
var parser = new HtmlParser();
using var dom = parser.ParseDocument(results.ContentString);
var rows = dom.QuerySelectorAll(".box_torrent").Skip(previouslyParsedOnPage).Take(limit - alreadyFound);
var key = ParseUtil.GetArgumentFromQueryString(
dom.QuerySelector("link[rel=alternate]").GetAttribute("href"), "key");
// Check torrents only till we reach the query Limit
foreach (var row in rows)
try
{
var torrentTxt = row.QuerySelector(".torrent_txt, .torrent_txt2").QuerySelector("a");
//if (torrentTxt == null) continue;
var infoLink = row.QuerySelector("a.infolink");
var imdbId = ParseUtil.GetLongFromString(infoLink?.GetAttribute("href"));
var desc = row.QuerySelector("span")?.GetAttribute("title") + " " +
infoLink?.TextContent;
var torrentLink = SiteLink + torrentTxt.GetAttribute("href");
var downloadId = ParseUtil.GetArgumentFromQueryString(torrentLink, "id");
//Build site links
var details = new Uri(SiteLink + "torrents.php?action=details&id=" + downloadId);
var downloadLink = SiteLink + "torrents.php?action=download&id=" + downloadId;
var linkUri = new Uri(QueryHelpers.AddQueryString(downloadLink, "key", key));
var seeders = ParseUtil.CoerceInt(row.QuerySelector(".box_s2 a").TextContent);
var leechers = ParseUtil.CoerceInt(row.QuerySelector(".box_l2 a").TextContent);
var publishDate = DateTime.Parse(
row.QuerySelector(".box_feltoltve2").InnerHtml.Replace("<br>", " "),
CultureInfo.InvariantCulture);
var sizeSplit = row.QuerySelector(".box_meret2").TextContent.Split(' ');
var size = ParseUtil.GetBytes(sizeSplit[1].ToLower(), ParseUtil.CoerceFloat(sizeSplit[0]));
var catLink = row.QuerySelector("a:has(img[class='categ_link'])").GetAttribute("href");
var cat = ParseUtil.GetArgumentFromQueryString(catLink, "tipus");
var title = torrentTxt.GetAttribute("title");
// if the release name does not contain the language we add from the category
if (cat.Contains("hun") && !title.ToLower().Contains("hun"))
title += ".hun";
// Minimum seed time is 48 hours + 24 minutes (.4 hours) per GB of torrent size if downloaded in full.
// Or a 1.0 ratio on the torrent
var seedTime = TimeSpan.FromHours(48) +
TimeSpan.FromMinutes(24 * ReleaseInfo.GigabytesFromBytes(size).Value);
var release = new ReleaseInfo
{
Title = title,
Description = desc.Trim(),
MinimumRatio = 1,
MinimumSeedTime = (long)seedTime.TotalSeconds,
DownloadVolumeFactor = 0,
UploadVolumeFactor = 1,
Link = linkUri,
Details = details,
Guid = details,
Seeders = seeders,
Peers = leechers + seeders,
Imdb = imdbId,
PublishDate = publishDate,
Size = size,
Category = MapTrackerCatToNewznab(cat)
};
var posterStr = row.QuerySelector("img.infobar_ico")?.GetAttribute("onmouseover");
if (posterStr != null)
{
// static call to Regex.Match caches the pattern, so we aren't recompiling every loop.
var posterMatch = Regex.Match(posterStr, @"mutat\('(.*?)', '", RegexOptions.Compiled);
release.Poster = new Uri(posterMatch.Groups[1].Value);
}
//TODO there is room for improvement here.
if (episodeString != null &&
query.MatchQueryStringAND(release.Title, queryStringOverride: episodeString) &&
!query.IsImdbQuery)
{
// For Sonarr if the search query was english the title must be english also
// The description holds the alternate language name
// so we need to swap title and description names
var tempTitle = release.Title;
// releaseData everything after Name.S0Xe0X
var releaseIndex = tempTitle.IndexOf(episodeString, StringComparison.OrdinalIgnoreCase) +
episodeString.Length;
var releaseData = tempTitle.Substring(releaseIndex).Trim();
// release description contains [imdb: ****] but we only need the data before it for title
var description = new[]
{
release.Description,
""
};
if (release.Description.Contains("[imdb:"))
{
description = release.Description.Split('[');
description[1] = "[" + description[1];
}
var match = Regex.Match(releaseData, @"^E\d\d?");
// if search is done for S0X than we don't want to put . between S0X and E0X
var episodeSeparator = episodeString.Length == 3 && match.Success ? null : ".";
release.Title =
(description[0].Trim() + "." + episodeString.Trim() + episodeSeparator +
releaseData.Trim('.')).Replace(' ', '.');
// add back imdb points to the description [imdb: 8.7]
release.Description = tempTitle + " " + description[1];
release.Description = release.Description.Trim();
}
releases.Add(release);
}
catch (FormatException ex)
{
logger.Error("Problem of parsing Torrent:" + row.InnerHtml);
logger.Error("Exception was the following:" + ex);
}
}
catch (Exception ex)
{
OnParseError(results.ContentString, ex);
}
return releases;
}
}
}

View File

@@ -13,6 +13,7 @@ using Jackett.Common.Models.IndexerConfig;
using Jackett.Common.Serializer;
using Jackett.Common.Services.Interfaces;
using Jackett.Common.Utils;
using Jackett.Common.Utils.Clients;
using Newtonsoft.Json.Linq;
using NLog;
@@ -33,10 +34,6 @@ namespace Jackett.Common.Indexers.Definitions
public override TorznabCapabilities TorznabCaps => SetCapabilities();
private static string SearchUrl => "https://passthepopcorn.me/torrents.php";
private string AuthKey { get; set; }
private string PassKey { get; set; }
// TODO: merge ConfigurationDataAPILoginWithUserAndPasskeyAndFilter class with with ConfigurationDataUserPasskey
private new ConfigurationDataAPILoginWithUserAndPasskeyAndFilter configData
{
@@ -58,7 +55,7 @@ namespace Jackett.Common.Indexers.Definitions
webclient.requestDelay = 4;
}
private TorznabCapabilities SetCapabilities()
private static TorznabCapabilities SetCapabilities()
{
var caps = new TorznabCapabilities
{
@@ -154,7 +151,7 @@ namespace Jackett.Common.Indexers.Definitions
queryCollection.Set("page", page.ToString());
}
var movieListSearchUrl = $"{SearchUrl}?{queryCollection.GetQueryString()}";
var movieListSearchUrl = $"https://passthepopcorn.me/torrents.php?{queryCollection.GetQueryString()}";
var authHeaders = new Dictionary<string, string>
{
@@ -163,10 +160,6 @@ namespace Jackett.Common.Indexers.Definitions
};
var indexerResponse = await RequestWithCookiesAndRetryAsync(movieListSearchUrl, headers: authHeaders);
if (indexerResponse.IsRedirect) // untested
{
indexerResponse = await RequestWithCookiesAndRetryAsync(movieListSearchUrl, headers: authHeaders);
}
var releases = new List<ReleaseInfo>();
@@ -230,7 +223,7 @@ namespace Jackett.Common.Indexers.Definitions
Title = torrent.ReleaseName,
Year = int.Parse(result.Year),
Details = infoUrl,
Link = GetDownloadUrl(id, jsonResponse.AuthKey, jsonResponse.PassKey),
Link = GetDownloadUrl(id),
Category = MapTrackerCatToNewznab(result.CategoryId),
Size = long.Parse(torrent.Size),
Grabs = int.Parse(torrent.Snatched),
@@ -322,14 +315,24 @@ namespace Jackett.Common.Indexers.Definitions
return releases;
}
private Uri GetDownloadUrl(int torrentId, string authKey, string passKey)
public override async Task<byte[]> Download(Uri link)
{
return await Download(
link,
method: RequestType.GET,
headers: new Dictionary<string, string>
{
{ "ApiUser", configData.User.Value },
{ "ApiKey", configData.Key.Value }
}).ConfigureAwait(false);
}
private Uri GetDownloadUrl(int torrentId)
{
var query = new NameValueCollection
{
{ "action", "download" },
{ "id", torrentId.ToString() },
{ "authkey", authKey },
{ "torrent_pass", passKey }
{ "id", torrentId.ToString() }
};
return new UriBuilder(SiteLink)
@@ -371,8 +374,6 @@ namespace Jackett.Common.Indexers.Definitions
{
public string TotalResults { get; set; }
public IReadOnlyCollection<PassThePopcornMovie> Movies { get; set; }
public string AuthKey { get; set; }
public string PassKey { get; set; }
}
public class PassThePopcornMovie

View File

@@ -1,63 +0,0 @@
using System.Diagnostics.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Jackett.Common.Models.IndexerConfig.Bespoke
{
[ExcludeFromCodeCoverage]
internal class ConfigurationDataNCore : ConfigurationData
{
public StringConfigurationItem Username { get; private set; }
public StringConfigurationItem Password { get; private set; }
public StringConfigurationItem TwoFactor { get; private set; }
public BoolConfigurationItem Hungarian { get; set; }
public BoolConfigurationItem English { get; set; }
public ConfigurationDataNCore()
{
Username = new StringConfigurationItem("Username") { Value = "" };
Password = new StringConfigurationItem("Password") { Value = "" };
TwoFactor = new StringConfigurationItem("Twofactor") { Value = "" };
Hungarian = new BoolConfigurationItem("Hungarian") { Value = true };
English = new BoolConfigurationItem("English") { Value = true };
}
public ConfigurationDataNCore(JToken json)
{
var configData = new ConfigurationDataNCore();
dynamic configArray = JsonConvert.DeserializeObject(json.ToString());
foreach (var config in configArray)
{
var propertyName = UppercaseFirst((string)config.id);
switch (propertyName)
{
case "Username":
Username = new StringConfigurationItem(propertyName) { Value = config.value };
break;
case "Password":
Password = new StringConfigurationItem(propertyName) { Value = config.value };
break;
case "Twofactor":
TwoFactor = new StringConfigurationItem(propertyName) { Value = config.value };
break;
case "Hungarian":
Hungarian = new BoolConfigurationItem(propertyName) { Value = config.value };
break;
case "English":
English = new BoolConfigurationItem(propertyName) { Value = config.value };
break;
default:
break;
}
}
}
private static string UppercaseFirst(string s)
{
if (string.IsNullOrEmpty(s))
return string.Empty;
return char.ToUpper(s[0]) + s.Substring(1);
}
}
}

View File

@@ -390,6 +390,7 @@ namespace Jackett.Updater
"Definitions/emmidtracker.yml",
"Definitions/emtrek.yml",
"Definitions/enthralled.yml",
"Definitions/enthralled2fa.yml",
"Definitions/eotforum.yml",
"Definitions/epizod.yml",
"Definitions/erzsebet.yml",