mirror of
https://github.com/Jackett/Jackett.git
synced 2025-09-09 21:24:42 +02:00
Compare commits
54 Commits
84abb69984
...
v0.22.1930
Author | SHA1 | Date | |
---|---|---|---|
![]() |
14220f169e | ||
![]() |
ada12ba547 | ||
![]() |
1899df1a84 | ||
![]() |
5f75bdce58 | ||
![]() |
96aeae6f25 | ||
![]() |
2dbe6e1f20 | ||
![]() |
8c5be40d26 | ||
![]() |
abc871efeb | ||
![]() |
3f84367e88 | ||
![]() |
09c252fc9e | ||
![]() |
f4a6c1f494 | ||
![]() |
f1ab49f462 | ||
![]() |
e89c6a73aa | ||
![]() |
267d6f9160 | ||
![]() |
a87f2e8123 | ||
![]() |
ed598f632e | ||
![]() |
b5e5d50128 | ||
![]() |
57e5293894 | ||
![]() |
695c26fe07 | ||
![]() |
c0c229e29d | ||
![]() |
6e56730d93 | ||
![]() |
da841b52b0 | ||
![]() |
dd117c73f5 | ||
![]() |
0b7134eb7d | ||
![]() |
ca7c36735f | ||
![]() |
070ee26017 | ||
![]() |
81e0101cbd | ||
![]() |
479392cf4f | ||
![]() |
be377ac649 | ||
![]() |
36d3f19086 | ||
![]() |
158d92d336 | ||
![]() |
d7ed800d54 | ||
![]() |
366ce176bb | ||
![]() |
e0d3b960ad | ||
![]() |
ae7d6c499b | ||
![]() |
1aba79fe13 | ||
![]() |
e4a9019f7f | ||
![]() |
be26c199bf | ||
![]() |
bff8bf3a96 | ||
![]() |
4716ea7829 | ||
![]() |
dcf04e7eac | ||
![]() |
643bf3283a | ||
![]() |
5b16b9ff65 | ||
![]() |
f2f2e63a97 | ||
![]() |
4fd1203bef | ||
![]() |
10a498308f | ||
![]() |
1fb7c8c346 | ||
![]() |
e894496bda | ||
![]() |
ca314d3e6a | ||
![]() |
5cba616a31 | ||
![]() |
75222975af | ||
![]() |
3d919aa88b | ||
![]() |
030926a549 | ||
![]() |
90abe2e4d8 |
11
README.md
11
README.md
@@ -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.
|
||||
|
@@ -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 }}"
|
||||
|
@@ -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:
|
||||
|
178
src/Jackett.Common/Definitions/bitsexy-api.yml
Normal file
178
src/Jackett.Common/Definitions/bitsexy-api.yml
Normal 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)
|
@@ -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
|
||||
|
@@ -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:
|
||||
|
@@ -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
|
||||
|
@@ -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"}
|
||||
|
@@ -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:
|
||||
|
@@ -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:
|
||||
|
@@ -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]
|
||||
|
@@ -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"}
|
||||
|
@@ -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
|
||||
|
@@ -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
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
189
src/Jackett.Common/Definitions/ncore.yml
Normal file
189
src/Jackett.Common/Definitions/ncore.yml
Normal 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
|
@@ -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:
|
||||
|
@@ -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"}
|
||||
|
@@ -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
|
||||
|
@@ -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:
|
||||
|
@@ -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:
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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:
|
||||
|
@@ -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
|
||||
|
@@ -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: "Детектив / боевик"}
|
||||
|
@@ -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:
|
||||
|
82
src/Jackett.Common/Definitions/torrentgalaxyclone.yml
Normal file
82
src/Jackett.Common/Definitions/torrentgalaxyclone.yml
Normal 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
|
@@ -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:
|
||||
|
@@ -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:
|
||||
|
@@ -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:
|
||||
|
@@ -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:
|
||||
|
@@ -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
|
||||
|
@@ -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="])
|
||||
|
@@ -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:
|
||||
|
@@ -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:
|
||||
|
346
src/Jackett.Common/Indexers/Definitions/ArabicSource.cs
Normal file
346
src/Jackett.Common/Indexers/Definitions/ArabicSource.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
|
@@ -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";
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -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",
|
||||
|
Reference in New Issue
Block a user