mirror of
https://github.com/Jackett/Jackett.git
synced 2025-09-15 08:24:14 +02:00
Compare commits
36 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
81c9828e4c | ||
![]() |
23b0378d2a | ||
![]() |
dd029db392 | ||
![]() |
40978fbce1 | ||
![]() |
2cc451ebef | ||
![]() |
2f6e1e29b1 | ||
![]() |
99c0de285e | ||
![]() |
d9afee215d | ||
![]() |
dc8f85d33d | ||
![]() |
1134ef71da | ||
![]() |
c9e5f14687 | ||
![]() |
dbe7561642 | ||
![]() |
9fcb16e535 | ||
![]() |
1215548b31 | ||
![]() |
ecf295873f | ||
![]() |
8dcc2aedc9 | ||
![]() |
08b3ba0f02 | ||
![]() |
f587ae3084 | ||
![]() |
58206b0d33 | ||
![]() |
8e5538a11e | ||
![]() |
175bea9269 | ||
![]() |
33cbc71817 | ||
![]() |
f7014f4ca2 | ||
![]() |
874e14018e | ||
![]() |
922c08da19 | ||
![]() |
5fe89a85e9 | ||
![]() |
0bcf922f37 | ||
![]() |
eb485bfa60 | ||
![]() |
74d0e022ae | ||
![]() |
0a8675ea7c | ||
![]() |
eed8cb70a3 | ||
![]() |
e476233f07 | ||
![]() |
b8d40b5259 | ||
![]() |
a399e8d0a5 | ||
![]() |
db049b2478 | ||
![]() |
03ab411d68 |
11
README.md
11
README.md
@@ -14,6 +14,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
|
||||
|
||||
#### Supported Private Trackers
|
||||
* 7tor
|
||||
* Abnormal
|
||||
* AlphaRatio
|
||||
* AlphaReign
|
||||
@@ -29,6 +30,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* Bit-City Reloaded
|
||||
* BIT-HDTV
|
||||
* BitHQ
|
||||
* BitHUmen
|
||||
* BitMeTV
|
||||
* BitSoup
|
||||
* Blu-bits
|
||||
@@ -43,9 +45,9 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* Ethor.net (Thor's Land)
|
||||
* FANO.IN
|
||||
* FileList
|
||||
* Freaks Tracking System
|
||||
* Freshon
|
||||
* FunFile
|
||||
* FunkyTorrents
|
||||
* Fuzer
|
||||
* Ghost City
|
||||
* Gormogon
|
||||
@@ -53,6 +55,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* HD-Space
|
||||
* HD-Torrents
|
||||
* HDClub
|
||||
* HDSky
|
||||
* Hebits
|
||||
* New Real World
|
||||
* Hounddawgs
|
||||
@@ -61,6 +64,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* ILoveTorrents
|
||||
* Immortalseed
|
||||
* IPTorrents
|
||||
* M-Team - TP
|
||||
* MoreThanTV
|
||||
* MyAnonamouse
|
||||
* myAmity
|
||||
@@ -79,14 +83,17 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* QcTorrent
|
||||
* RapideTracker
|
||||
* RevolutionTT
|
||||
* RuTracker
|
||||
* SceneAccess
|
||||
* SceneFZ
|
||||
* SceneTime
|
||||
* SDBits
|
||||
* Secret Cinema
|
||||
* Shareisland
|
||||
* ShareSpaceDB
|
||||
* Shazbat
|
||||
* SpeedCD
|
||||
* Superbits
|
||||
* The Horror Charnel
|
||||
* The New Retro
|
||||
* The Shinning
|
||||
@@ -98,6 +105,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* TorrentBytes
|
||||
* TorrentDay
|
||||
* TorrentHeaven
|
||||
* Torrenting
|
||||
* TorrentLeech
|
||||
* Torrents.Md
|
||||
* TorrentShack
|
||||
@@ -105,7 +113,6 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* ToTheGlory
|
||||
* TranceTraffic
|
||||
* TransmitheNet
|
||||
* Tspate
|
||||
* TV Chaos UK
|
||||
* TV-Vault
|
||||
* u-Torrent
|
||||
|
@@ -165,7 +165,7 @@
|
||||
</div>
|
||||
</script>
|
||||
<script id="setup-item-displayimage" type="text/x-handlebars-template">
|
||||
<img class="setup-item-displayimage" src="{{{value}}}" />
|
||||
<img class="setup-item-displayimage" src="{{{value}}}" alt="No image available" />
|
||||
</script>
|
||||
<script id="setup-item-displayinfo" type="text/x-handlebars-template">
|
||||
<div class="setup-item-displayinfo alert alert-info" role="alert">{{{value}}}</div>
|
||||
|
132
src/Jackett/Definitions/bithumen.yml
Normal file
132
src/Jackett/Definitions/bithumen.yml
Normal file
@@ -0,0 +1,132 @@
|
||||
---
|
||||
site: bithumen
|
||||
name: BitHUmen
|
||||
language: hu-hu
|
||||
encoding: ISO-8859-2
|
||||
links:
|
||||
- https://bithumen.be/
|
||||
|
||||
caps:
|
||||
categories:
|
||||
23: Movies/SD # Film/Hun/SD
|
||||
24: Movies/DVD # Film/Hun/DVD-R
|
||||
25: Movies/HD # Film/Hun/720p
|
||||
37: Movies/HD # Film/Hun/1080p
|
||||
33: Movies/BluRay # Film/Hun/Blu-ray
|
||||
30: XXX # XXX/SD
|
||||
19: Movies/SD # Film/Eng/SD
|
||||
20: Movies/DVD # Film/Eng/DVD-R
|
||||
5: Movies/HD # Film/Eng/720p
|
||||
39: Movies/HD # Film/Eng/1080p
|
||||
40: Movies/BluRay # Film/Eng/Blu-ray
|
||||
34: XXX # XXX/HD
|
||||
7: TV/SD # Sorozat/Hun/SD
|
||||
41: TV/HD # Sorozat/Hun/HD
|
||||
26: TV/SD # Sorozat/Eng/SD
|
||||
42: TV/HD # Sorozat/Eng/HD
|
||||
28: Books # eBook/Hun
|
||||
29: Books # eBook/Eng
|
||||
9: Audio/MP3 # Mp3/Hun
|
||||
35: Audio/Lossless # Lossless/Hun
|
||||
1: PC/0day # Programok/ISO
|
||||
4: PC/Games # Játékok/ISO
|
||||
31: Console/PS4 # Játékok/PS
|
||||
36: Console/Wii # Játékok/Wii
|
||||
6: Audio/MP3 # Mp3/Eng
|
||||
38: Audio/Lossless # Lossless/Eng
|
||||
22: PC # Programok/egyéb
|
||||
21: PC # Játékok/Rip/Dox
|
||||
32: Console/Xbox360 # Játékok/Xbox360
|
||||
27: Other # Klipek
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
login:
|
||||
path: takelogin.php
|
||||
method: post
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
error:
|
||||
- selector: td.embedded:has(h2:contains("bejelentkezés"))
|
||||
test:
|
||||
path: browse.php
|
||||
|
||||
search:
|
||||
path: browse.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
incldead: 1
|
||||
rows:
|
||||
selector: table#torrenttable > tbody > tr:has(a[href^="details.php?id="])
|
||||
filters:
|
||||
- name: andmatch
|
||||
fields:
|
||||
download:
|
||||
selector: a[href^="download.php/"]
|
||||
attribute: href
|
||||
title:
|
||||
selector: a[href^="details.php?id="]
|
||||
title|optional:
|
||||
selector: a[href^="details.php?id="]
|
||||
attribute: title
|
||||
details:
|
||||
selector: a[href^="details.php?id="]
|
||||
attribute: href
|
||||
imdb:
|
||||
selector: a[href^="http://anonym.to/?http://www.imdb.com/title/"]
|
||||
attribute: href
|
||||
banner:
|
||||
selector: a[onmouseover^="bithumen.UI.images.coverShow"]
|
||||
attribute: onmouseover
|
||||
filters:
|
||||
- name: regexp
|
||||
args: "\"(.*?)\""
|
||||
category:
|
||||
selector: a[href^="?cat="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
seeders:
|
||||
selector: td:nth-child(8)
|
||||
leechers:
|
||||
selector: td:nth-child(9)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: /\s*([\d,]+)
|
||||
grabs:
|
||||
selector: td:nth-child(7)
|
||||
files:
|
||||
selector: td:nth-child(3)
|
||||
size:
|
||||
selector: td:nth-child(6) > u
|
||||
downloadvolumefactor:
|
||||
text: "1"
|
||||
downloadvolumefactor|optional:
|
||||
selector: td:nth-child(6) > nobr > font:contains(" × ")
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["×", ""]
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
||||
uploadvolumefactor|optional:
|
||||
selector: td:nth-child(5) > nobr > font:contains(" × ")
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["×", ""]
|
||||
date:
|
||||
selector: td:nth-child(5)
|
||||
remove: font
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["ma", "today"]
|
||||
- name: replace
|
||||
args: ["tegnap", "yesterday"]
|
||||
|
||||
description:
|
||||
selector: td:nth-child(2) > div
|
||||
|
@@ -1,101 +0,0 @@
|
||||
---
|
||||
site: freakstrackingsystem
|
||||
name: Freaks Tracking System
|
||||
description: "A German gerneral tracker"
|
||||
language: de-de
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://fts.to
|
||||
|
||||
caps:
|
||||
categories:
|
||||
1: Movies
|
||||
2: TV
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
login:
|
||||
path: /index.php?form=UserLogin
|
||||
method: form
|
||||
inputs:
|
||||
loginUsername: "{{ .Config.username }}"
|
||||
loginPassword: "{{ .Config.password }}"
|
||||
error:
|
||||
- selector: p.innerError
|
||||
test:
|
||||
path: index.php?page=FTSAttachmentList
|
||||
selector: "span:contains(\"Freaks-Punkte:\") > span"
|
||||
|
||||
ratio:
|
||||
path: index.php?page=FTSAttachmentList
|
||||
selector: "span:contains(\"Freaks-Punkte:\") > span"
|
||||
|
||||
search:
|
||||
path: index.php
|
||||
inputs:
|
||||
page: "FTSAttachmentList"
|
||||
sortField: "uploadTime"
|
||||
sortOrder: "DESC"
|
||||
filename: "{{ .Query.Keywords }}"
|
||||
rows:
|
||||
selector: table.tableList > tbody > tr[class^="container-"]:has(td:nth-child(5) > a, td:nth-child(6) > a) # has makes sure that we can build a download link
|
||||
fields:
|
||||
download:
|
||||
selector: td:nth-child(5) > a, td:nth-child(6) > a
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["page=FTSPeerList&torrentID=", "page=Attachment&attachmentID="]
|
||||
title:
|
||||
selector: td:nth-child(4) > a
|
||||
category:
|
||||
text: 2
|
||||
details:
|
||||
selector: td:nth-child(4) > a
|
||||
attribute: href
|
||||
size:
|
||||
selector: td:nth-child(8)
|
||||
filters:
|
||||
- name: replace
|
||||
args: [".", ""]
|
||||
- name: replace
|
||||
args: [",", "."]
|
||||
grabs:
|
||||
selector: td:nth-child(7)
|
||||
seeders:
|
||||
selector: td:nth-child(5)
|
||||
leechers:
|
||||
selector: td:nth-child(6)
|
||||
date:
|
||||
selector: td:nth-child(3)
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["Heute", "Today"]
|
||||
- name: replace
|
||||
args: ["Gestern", "Yesterday"]
|
||||
- name: replace
|
||||
args: ["Januar", "January"]
|
||||
- name: replace
|
||||
args: ["Februar", "February"]
|
||||
- name: replace
|
||||
args: ["März", "March"]
|
||||
- name: replace
|
||||
args: ["Mai", "May"]
|
||||
- name: replace
|
||||
args: ["Juni", "June"]
|
||||
- name: replace
|
||||
args: ["Juli", "July"]
|
||||
- name: replace
|
||||
args: ["Oktober", "October"]
|
||||
- name: replace
|
||||
args: ["Dezember", "December"]
|
||||
- name: dateparse
|
||||
args: "2. January 2006, 15:04"
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
112
src/Jackett/Definitions/funkytorrents.yml
Normal file
112
src/Jackett/Definitions/funkytorrents.yml
Normal file
@@ -0,0 +1,112 @@
|
||||
---
|
||||
site: funkytorrents
|
||||
name: FunkyTorrents
|
||||
language: en-us
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://funkytorrents.com
|
||||
|
||||
caps:
|
||||
categories:
|
||||
1: PC # (Apps)
|
||||
2: Books # (eBooks)
|
||||
3: Movies # (Movie)
|
||||
33: Audio # (Music DVDs)
|
||||
5: Audio/Video # (Music Vids)
|
||||
4: Audio # (OST)
|
||||
19: Audio # Alternative
|
||||
28: Audio # Ambient
|
||||
12: Audio # Classical
|
||||
17: Audio # Dance
|
||||
16: Audio # Drum 'n' Bass
|
||||
20: Audio # Electronic
|
||||
14: Audio # Emo
|
||||
23: Audio # Experimental
|
||||
34: Audio # Funk
|
||||
18: Audio # Hardcore
|
||||
13: Audio # House
|
||||
31: Audio # IDM
|
||||
21: Audio # Indie
|
||||
26: Audio # Industrial
|
||||
25: Audio # Jazz/Blues/Soul
|
||||
37: Audio # Lo-Fi
|
||||
6: Audio # Metal
|
||||
22: Audio # Misc
|
||||
7: Audio # Pop/RnB
|
||||
29: Audio # Post-Rock
|
||||
30: Audio # Psychedelic
|
||||
8: Audio # Punk
|
||||
9: Audio # Rap/Hip-Hop
|
||||
35: Audio # Reggae
|
||||
10: Audio # Rock
|
||||
15: Audio # Ska
|
||||
32: Audio # Techno
|
||||
11: Audio # Trance
|
||||
36: Audio # Trip-Hop
|
||||
24: Audio # World/Ethnic
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
login:
|
||||
path: takelogin.php
|
||||
method: post
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
error:
|
||||
- selector: td.embedded:has(h2:contains("failed"))
|
||||
test:
|
||||
path: browse.php
|
||||
|
||||
search:
|
||||
path: /browse.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
incldead: 1
|
||||
rows:
|
||||
selector: table.mainouter > tbody > tr > td.outer > table > tbody > tr.mouse_out
|
||||
fields:
|
||||
description|optional:
|
||||
selector: td:nth-child(2) > font
|
||||
title:
|
||||
selector: td:nth-child(2)
|
||||
remove: font
|
||||
category:
|
||||
selector: a[href^="browse.php?cat="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
details:
|
||||
selector: a[href^="details.php?id="]
|
||||
attribute: href
|
||||
download:
|
||||
selector: a[href^="download.php"]
|
||||
attribute: href
|
||||
files:
|
||||
selector: td:nth-child(5)
|
||||
size:
|
||||
selector: td:nth-child(8)
|
||||
seeders:
|
||||
selector: td:nth-child(10)
|
||||
leechers:
|
||||
selector: td:nth-child(11)
|
||||
date:
|
||||
selector: td:nth-child(7)
|
||||
filters:
|
||||
- name: append
|
||||
args: " +0000"
|
||||
- name: dateparse
|
||||
args: "2006-01-0215:04:05 -0700"
|
||||
grabs:
|
||||
selector: td:nth-child(9)
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
img[alt="Free Leech"]: "0"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
117
src/Jackett/Definitions/hdsky.yml
Normal file
117
src/Jackett/Definitions/hdsky.yml
Normal file
@@ -0,0 +1,117 @@
|
||||
---
|
||||
site: hdsky
|
||||
name: HDSky
|
||||
description: "A chinese tracker"
|
||||
language: zh-cn
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://hdsky.me
|
||||
|
||||
caps:
|
||||
categories:
|
||||
401: Movies # Movies/电影
|
||||
404: TV/Documentary # Documentaries/纪录片
|
||||
410: Movies # iPad/iPad影视
|
||||
405: TV/Anime # Animations/动漫
|
||||
402: TV # TV Series/剧集
|
||||
403: TV # TV Shows/综艺
|
||||
406: Audio/Video # Music Videos/音乐MV
|
||||
407: TV/Sport # Sports/体育
|
||||
408: Audio # HQ Audio/无损音乐
|
||||
409: Other # Misc/其他
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
login:
|
||||
path: login.php
|
||||
method: form
|
||||
form: form[action="takelogin.php"]
|
||||
captcha:
|
||||
type: image
|
||||
image: img[alt="CAPTCHA"]
|
||||
input: imagestring
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
error:
|
||||
- selector: td.embedded:has(h2:contains("failed"))
|
||||
test:
|
||||
path: /torrents.php
|
||||
|
||||
ratio:
|
||||
path: /torrents.php
|
||||
selector: table#info_block
|
||||
filters:
|
||||
- name: regexp
|
||||
args: "Ratio:\\s(.*?)\\s\\s"
|
||||
|
||||
download:
|
||||
method: post
|
||||
|
||||
search:
|
||||
path: /torrents.php
|
||||
method: post
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}cat{{.}}=1&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
incldead: "1"
|
||||
spstate: "0"
|
||||
inclbookmarked: "0"
|
||||
search_area: "0"
|
||||
search_mode: "0"
|
||||
rows:
|
||||
selector: table.torrents > tbody > tr:has(table.torrentname)
|
||||
fields:
|
||||
title:
|
||||
selector: a[title][href^="details.php?id="]
|
||||
attribute: title
|
||||
category:
|
||||
selector: a[href^="?cat="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
details:
|
||||
selector: a[title][href^="details.php?id="]
|
||||
attribute: href
|
||||
download:
|
||||
selector: form[action^="download.php?id="]
|
||||
attribute: action
|
||||
imdb:
|
||||
selector: a[href^="http://www.imdb.com/title/tt"]
|
||||
attribute: href
|
||||
size:
|
||||
selector: td.rowfollow:nth-child(5)
|
||||
grabs:
|
||||
selector: td.rowfollow:nth-child(8)
|
||||
seeders:
|
||||
selector: td.rowfollow:nth-child(6)
|
||||
leechers:
|
||||
selector: td.rowfollow:nth-child(7)
|
||||
date:
|
||||
selector: td.rowfollow:nth-child(4) > span[title]
|
||||
attribute: title
|
||||
filters:
|
||||
- name: append
|
||||
args: " +08:00"
|
||||
- name: dateparse
|
||||
args: "2006-01-02 15:04:05 -07:00"
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
img.pro_free: "0"
|
||||
img.pro_free2up: "0"
|
||||
img.pro_50pctdown: "0.5"
|
||||
img.pro_50pctdown2up: "0.5"
|
||||
img.pro_30pctdown: "0.3"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
img.pro_50pctdown2up: "2"
|
||||
img.pro_free2up: "2"
|
||||
img.pro_2up: "2"
|
||||
"*": "1"
|
||||
description:
|
||||
selector: td:nth-child(2)
|
||||
remove: a, img
|
121
src/Jackett/Definitions/mteamtp.yml
Normal file
121
src/Jackett/Definitions/mteamtp.yml
Normal file
@@ -0,0 +1,121 @@
|
||||
---
|
||||
site: mteamtp
|
||||
name: M-Team - TP
|
||||
description: "A chinese tracker"
|
||||
language: zh-cn
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://tp.m-team.cc
|
||||
|
||||
caps:
|
||||
categories:
|
||||
401: Movies/SD # Movie(電影)/SD
|
||||
419: Movies/HD # Movie(電影)/HD
|
||||
420: Movies/DVD # Movie(電影)/DVDiSo
|
||||
421: Movies/BluRay # Movie(電影)/Blu-Ray
|
||||
439: Movies/Other # Movie(電影)/Remux
|
||||
403: TV/SD # TV Series(影劇/綜藝)/SD
|
||||
402: TV/HD # TV Series(影劇/綜藝)/HD
|
||||
435: TV/SD # TV Series(影劇/綜藝)/DVDiSo
|
||||
438: TV/HD # TV Series(影劇/綜藝)/BD
|
||||
404: TV/Documentary # 紀錄教育
|
||||
405: TV/Anime # Anime(動畫)
|
||||
406: Audio/Video # MV(演唱)
|
||||
408: Audio/Other # Music(AAC/ALAC)
|
||||
434: Audio # Music(無損)
|
||||
407: TV/Sport # Sports(運動)
|
||||
422: PC/0day # Software(軟體)
|
||||
423: PC/Games # PCGame(PC遊戲)
|
||||
427: Books # eBook(電子書)
|
||||
409: Other # Misc(其他)
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
login:
|
||||
path: takelogin.php
|
||||
method: post
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
error:
|
||||
- selector: td.embedded:has(h2:contains("failed"))
|
||||
test:
|
||||
path: /torrents.php
|
||||
|
||||
ratio:
|
||||
path: /torrents.php
|
||||
selector: table#info_block
|
||||
filters:
|
||||
- name: regexp
|
||||
args: "Ratio:\\s(.*?)\\s\\s"
|
||||
|
||||
search:
|
||||
path: /torrents.php
|
||||
method: post
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}cat{{.}}=1&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
incldead: "1"
|
||||
spstate: "0"
|
||||
inclbookmarked: "0"
|
||||
search_area: "0"
|
||||
search_mode: "0"
|
||||
rows:
|
||||
selector: table.torrents > tbody > tr:has(table.torrentname)
|
||||
fields:
|
||||
title:
|
||||
selector: a[title][href^="details.php?id="]
|
||||
attribute: title
|
||||
category:
|
||||
selector: a[href^="?cat="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
details:
|
||||
selector: a[title][href^="details.php?id="]
|
||||
attribute: href
|
||||
download:
|
||||
selector: a[href^="download.php?id="]
|
||||
attribute: href
|
||||
banner:
|
||||
selector: img[alt="torrent thumbnail"]
|
||||
attribute: src
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["pic/nopic.jpg", ""]
|
||||
size:
|
||||
selector: td.rowfollow:nth-child(5)
|
||||
grabs:
|
||||
selector: td.rowfollow:nth-child(8)
|
||||
seeders:
|
||||
selector: td.rowfollow:nth-child(6)
|
||||
leechers:
|
||||
selector: td.rowfollow:nth-child(7)
|
||||
date:
|
||||
selector: td.rowfollow:nth-child(4) > span[title]
|
||||
attribute: title
|
||||
filters:
|
||||
- name: append
|
||||
args: " +08:00"
|
||||
- name: dateparse
|
||||
args: "2006-01-02 15:04:05 -07:00"
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
img.pro_free: "0"
|
||||
img.pro_free2up: "0"
|
||||
img.pro_50pctdown: "0.5"
|
||||
img.pro_50pctdown2up: "0.5"
|
||||
img.pro_30pctdown: "0.3"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
img.pro_50pctdown2up: "2"
|
||||
img.pro_free2up: "2"
|
||||
img.pro_2up: "2"
|
||||
"*": "1"
|
||||
description:
|
||||
selector: td:nth-child(2)
|
||||
remove: a, img
|
@@ -74,8 +74,8 @@
|
||||
inputs:
|
||||
p: "torrents"
|
||||
pid: "32"
|
||||
$raw: "{{range .Categories}}cid[]:{{.}}&{{end}}"
|
||||
keywords: "{{ re_replace .Query.Keywords \"[^a-zA-Z0-9]+\" \"%\" }}"
|
||||
$raw: "{{range .Categories}}cid[]={{.}}&{{end}}"
|
||||
keywords: "{{ re_replace .Query.Keywords \"[^a-zA-Z0-9]+\" \"%25\" }}"
|
||||
search_type: "name"
|
||||
searchin: "title"
|
||||
|
||||
|
@@ -1,11 +1,11 @@
|
||||
---
|
||||
site: tspate
|
||||
name: Tspate
|
||||
site: sharespacedb
|
||||
name: ShareSpaceDB
|
||||
description: "A French gerneral tracker"
|
||||
language: fr-fr
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://www.tspate.me/
|
||||
- https://www.sharespacedb.me/
|
||||
|
||||
caps:
|
||||
categories:
|
||||
@@ -117,9 +117,18 @@
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
details:
|
||||
selector: a[href^="torrents-details.php?id="]
|
||||
attribute: href
|
||||
comments:
|
||||
selector: a[href^="comments.php"]
|
||||
attribute: href
|
||||
banner:
|
||||
selector: a[onmouseover][href^="torrents-details.php?id="]
|
||||
attribute: onmouseover
|
||||
filters:
|
||||
- name: regexp
|
||||
args: <td align=left><img src=(.*?) width
|
||||
size:
|
||||
selector: td:nth-child(7)
|
||||
grabs:
|
@@ -12,6 +12,7 @@
|
||||
1: TV # Sports
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
login:
|
||||
path: members.php?action=takelogin
|
||||
@@ -19,12 +20,16 @@
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
error:
|
||||
- selector: div:contains("Login Failed")
|
||||
test:
|
||||
path: my.php
|
||||
#error:
|
||||
#- path: members.php?action=takelogin
|
||||
test:
|
||||
path: my.php
|
||||
#selector: a[href="members.php?action=logout"]
|
||||
|
||||
|
||||
ratio:
|
||||
path: browse.php
|
||||
selector: #status_bar
|
||||
@@ -37,6 +42,8 @@
|
||||
rows:
|
||||
selector: table[border="1"] tr:not(:first-child)
|
||||
fields:
|
||||
category:
|
||||
text: 1
|
||||
title:
|
||||
selector: td:nth-child(2)
|
||||
download:
|
||||
|
86
src/Jackett/Definitions/torrenting.yml
Normal file
86
src/Jackett/Definitions/torrenting.yml
Normal file
@@ -0,0 +1,86 @@
|
||||
---
|
||||
site: torrenting
|
||||
name: Torrenting
|
||||
language: en-us
|
||||
encoding: windows-1252
|
||||
links:
|
||||
- https://torrenting.com
|
||||
|
||||
caps:
|
||||
categories:
|
||||
1: Movies # Movies
|
||||
2: Movies/DVD # Movies/DVD-R
|
||||
3: Movies/BluRay # BluRay Movies
|
||||
4: TV/SD # TV/SD-x264
|
||||
5: TV/HD # TV/X264 HD
|
||||
11: Movies/HD # Movies/HD
|
||||
18: TV # TV/Packs
|
||||
21: Console # Games/Consoles
|
||||
26: Audio/Video # Music/Videos
|
||||
27: Audio # Music/Audio
|
||||
29: TV/Anime # Anime/Toons
|
||||
30: Books # Books
|
||||
34: PC/0day # Applications/0-day
|
||||
35: PC/Games # Games/PC
|
||||
40: XXX # XXX
|
||||
47: Movies # Movies/Packs
|
||||
49: Movies/HD # x265 (HEVC)
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
login:
|
||||
path: login.php
|
||||
method: form
|
||||
form: form[action="secure.php"]
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
error:
|
||||
- selector: td.embedded:has(h2:contains("failed"))
|
||||
test:
|
||||
path: browse.php
|
||||
|
||||
search:
|
||||
path: browse.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
incldead: 1
|
||||
rows:
|
||||
selector: table#torrentsTable > tbody > tr.torrentsTableTR
|
||||
fields:
|
||||
download:
|
||||
selector: a[href^="download.php/"]
|
||||
attribute: href
|
||||
title:
|
||||
selector: a.nameLink
|
||||
details:
|
||||
selector: a.nameLink
|
||||
attribute: href
|
||||
category:
|
||||
selector: a[href^="browse.php?cat="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
date:
|
||||
selector: div.uploaded
|
||||
seeders:
|
||||
selector: td:nth-child(7)
|
||||
leechers:
|
||||
selector: td:nth-child(8)
|
||||
size:
|
||||
selector: td:nth-child(6)
|
||||
downloadvolumefactor:
|
||||
text: "1"
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"span:contains(\"Freeleech\")": "0"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
||||
|
||||
|
1728
src/Jackett/Indexers/7tor.cs
Normal file
1728
src/Jackett/Indexers/7tor.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -161,7 +161,7 @@ namespace Jackett.Indexers
|
||||
IsConfigured = false;
|
||||
}
|
||||
|
||||
protected virtual void SaveConfig()
|
||||
public virtual void SaveConfig()
|
||||
{
|
||||
indexerService.SaveConfig(this as IIndexer, configData.ToJson(protectionService, forDisplay: false));
|
||||
}
|
||||
@@ -334,13 +334,18 @@ namespace Jackett.Indexers
|
||||
}
|
||||
|
||||
public async virtual Task<byte[]> Download(Uri link)
|
||||
{
|
||||
return await Download(link, RequestType.GET);
|
||||
}
|
||||
|
||||
public async virtual Task<byte[]> Download(Uri link, RequestType method = RequestType.GET)
|
||||
{
|
||||
// do some extra escaping, needed for HD-Torrents
|
||||
var requestLink = link.ToString()
|
||||
.Replace("(", "%28")
|
||||
.Replace(")", "%29")
|
||||
.Replace("'", "%27");
|
||||
var response = await RequestBytesWithCookiesAndRetry(requestLink);
|
||||
var response = await RequestBytesWithCookiesAndRetry(requestLink, null, method);
|
||||
if (response.Status != System.Net.HttpStatusCode.OK && response.Status != System.Net.HttpStatusCode.Continue && response.Status != System.Net.HttpStatusCode.PartialContent)
|
||||
{
|
||||
logger.Error("Failed download cookies: " + this.CookieHeader);
|
||||
@@ -352,14 +357,14 @@ namespace Jackett.Indexers
|
||||
return response.Content;
|
||||
}
|
||||
|
||||
protected async Task<WebClientByteResult> RequestBytesWithCookiesAndRetry(string url, string cookieOverride = null)
|
||||
protected async Task<WebClientByteResult> RequestBytesWithCookiesAndRetry(string url, string cookieOverride = null, RequestType method = RequestType.GET)
|
||||
{
|
||||
Exception lastException = null;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await RequestBytesWithCookies(url, cookieOverride);
|
||||
return await RequestBytesWithCookies(url, cookieOverride, method);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -411,12 +416,12 @@ namespace Jackett.Indexers
|
||||
throw lastException;
|
||||
}
|
||||
|
||||
protected async Task<WebClientByteResult> RequestBytesWithCookies(string url, string cookieOverride = null)
|
||||
protected async Task<WebClientByteResult> RequestBytesWithCookies(string url, string cookieOverride = null, RequestType method = RequestType.GET)
|
||||
{
|
||||
var request = new Utils.Clients.WebRequest()
|
||||
{
|
||||
Url = url,
|
||||
Type = RequestType.GET,
|
||||
Type = method,
|
||||
Cookies = cookieOverride ?? CookieHeader,
|
||||
Encoding = Encoding
|
||||
};
|
||||
|
File diff suppressed because one or more lines are too long
@@ -136,6 +136,7 @@ namespace Jackett.Indexers
|
||||
public class downloadBlock
|
||||
{
|
||||
public string Selector { get; set; }
|
||||
public string Method { get; set; }
|
||||
}
|
||||
|
||||
protected readonly string[] OptionalFileds = new string[] { "imdb", "rageid", "tvdbid", "banner" };
|
||||
@@ -367,7 +368,7 @@ namespace Jackett.Indexers
|
||||
pairs.Add(Input.Key, value);
|
||||
}
|
||||
|
||||
var LoginUrl = SiteLink + Login.Path;
|
||||
var LoginUrl = resolvePath(Login.Path).ToString();
|
||||
configData.CookieHeader.Value = null;
|
||||
var loginResult = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, SiteLink, true);
|
||||
configData.CookieHeader.Value = loginResult.Cookies;
|
||||
@@ -376,7 +377,7 @@ namespace Jackett.Indexers
|
||||
}
|
||||
else if (Login.Method == "form")
|
||||
{
|
||||
var LoginUrl = SiteLink + Login.Path;
|
||||
var LoginUrl = resolvePath(Login.Path).ToString();
|
||||
|
||||
var pairs = new Dictionary<string, string>();
|
||||
|
||||
@@ -524,6 +525,22 @@ namespace Jackett.Indexers
|
||||
{
|
||||
configData.CookieHeader.Value = ((StringItem)configData.GetDynamic("cookie")).Value;
|
||||
}
|
||||
else if (Login.Method == "get")
|
||||
{
|
||||
var queryCollection = new NameValueCollection();
|
||||
foreach (var Input in Definition.Login.Inputs)
|
||||
{
|
||||
var value = applyGoTemplateText(Input.Value);
|
||||
queryCollection.Add(Input.Key, value);
|
||||
}
|
||||
|
||||
var LoginUrl = resolvePath(Login.Path + "?" + queryCollection.GetQueryString()).ToString();
|
||||
configData.CookieHeader.Value = null;
|
||||
var loginResult = await RequestStringWithCookies(LoginUrl, null, SiteLink);
|
||||
configData.CookieHeader.Value = loginResult.Cookies;
|
||||
|
||||
checkForLoginError(loginResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException("Login method " + Definition.Login.Method + " not implemented");
|
||||
@@ -539,7 +556,7 @@ namespace Jackett.Indexers
|
||||
return false;
|
||||
|
||||
// test if login was successful
|
||||
var LoginTestUrl = SiteLink + Login.Test.Path;
|
||||
var LoginTestUrl = resolvePath(Login.Test.Path).ToString();
|
||||
var testResult = await RequestStringWithCookies(LoginTestUrl);
|
||||
|
||||
if (testResult.IsRedirect)
|
||||
@@ -588,7 +605,7 @@ namespace Jackett.Indexers
|
||||
if (Login == null || Login.Method != "form")
|
||||
return configData;
|
||||
|
||||
var LoginUrl = SiteLink + Login.Path;
|
||||
var LoginUrl = resolvePath(Login.Path).ToString();
|
||||
|
||||
configData.CookieHeader.Value = null;
|
||||
landingResult = await RequestStringWithCookies(LoginUrl, null, SiteLink);
|
||||
@@ -781,6 +798,8 @@ namespace Jackett.Indexers
|
||||
else if (Selector.Attribute != null)
|
||||
{
|
||||
value = selection.GetAttribute(Selector.Attribute);
|
||||
if (value == null)
|
||||
throw new Exception(string.Format("Attribute \"{0}\" is not set for element {1}", Selector.Attribute, selection.OuterHtml));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -796,6 +815,11 @@ namespace Jackett.Indexers
|
||||
{
|
||||
return new Uri(path);
|
||||
}
|
||||
else if (path.StartsWith("//"))
|
||||
{
|
||||
var basepath = new Uri(SiteLink);
|
||||
return new Uri(basepath.Scheme + ":" + path);
|
||||
}
|
||||
else if(path.StartsWith("/"))
|
||||
{
|
||||
var basepath = new Uri(SiteLink);
|
||||
@@ -805,7 +829,6 @@ namespace Jackett.Indexers
|
||||
{
|
||||
return new Uri(SiteLink + path);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
@@ -853,7 +876,7 @@ namespace Jackett.Indexers
|
||||
variables[".Keywords"] = variables[".Query.Keywords"];
|
||||
|
||||
// build search URL
|
||||
var searchUrl = SiteLink + applyGoTemplateText(Search.Path, variables) + "?";
|
||||
var searchUrl = resolvePath(applyGoTemplateText(Search.Path, variables) + "?").ToString();
|
||||
var queryCollection = new NameValueCollection();
|
||||
if (Search.Inputs != null)
|
||||
{
|
||||
@@ -928,12 +951,18 @@ namespace Jackett.Indexers
|
||||
// Parse fields
|
||||
foreach (var Field in Search.Fields)
|
||||
{
|
||||
var FieldParts = Field.Key.Split('|');
|
||||
var FieldName = FieldParts[0];
|
||||
var FieldModifier = "";
|
||||
if (FieldParts.Length >= 2)
|
||||
FieldModifier = FieldParts[1];
|
||||
|
||||
string value = null;
|
||||
try
|
||||
{
|
||||
value = handleSelector(Field.Value, Row);
|
||||
value = ParseUtil.NormalizeSpace(value);
|
||||
switch (Field.Key)
|
||||
switch (FieldName)
|
||||
{
|
||||
case "download":
|
||||
if (value.StartsWith("magnet:"))
|
||||
@@ -1036,7 +1065,7 @@ namespace Jackett.Indexers
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (OptionalFileds.Contains(Field.Key))
|
||||
if (OptionalFileds.Contains(Field.Key) || FieldModifier == "optional")
|
||||
continue;
|
||||
throw new Exception(string.Format("Error while parsing field={0}, selector={1}, value={2}: {3}", Field.Key, Field.Value.Selector, value, ex.Message));
|
||||
}
|
||||
@@ -1115,9 +1144,15 @@ namespace Jackett.Indexers
|
||||
|
||||
public override async Task<byte[]> Download(Uri link)
|
||||
{
|
||||
if(Definition.Download != null)
|
||||
var method = RequestType.GET;
|
||||
if (Definition.Download != null)
|
||||
{
|
||||
var Download = Definition.Download;
|
||||
if (Download.Method != null)
|
||||
{
|
||||
if (Download.Method == "post")
|
||||
method = RequestType.POST;
|
||||
}
|
||||
if (Download.Selector != null)
|
||||
{
|
||||
var response = await RequestStringWithCookies(link.ToString());
|
||||
@@ -1138,7 +1173,7 @@ namespace Jackett.Indexers
|
||||
}
|
||||
}
|
||||
}
|
||||
return await base.Download(link);
|
||||
return await base.Download(link, method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -130,6 +130,16 @@ namespace Jackett.Indexers
|
||||
release.Title = qLink.Text().Trim();
|
||||
release.Description = rowB.ChildElements.ElementAt(0).Cq().Text();
|
||||
|
||||
if (release.Category == TorznabCatType.Audio.ID)
|
||||
{
|
||||
if (release.Description.Contains("Lossless"))
|
||||
release.Category = TorznabCatType.AudioLossless.ID;
|
||||
else if (release.Description.Contains("MP3"))
|
||||
release.Category = TorznabCatType.AudioMP3.ID;
|
||||
else
|
||||
release.Category = TorznabCatType.AudioOther.ID;
|
||||
}
|
||||
|
||||
release.Comments = new Uri(SiteLink + qLink.Attr("href"));
|
||||
release.Guid = release.Comments;
|
||||
|
||||
|
264
src/Jackett/Indexers/EliteTracker.cs
Normal file
264
src/Jackett/Indexers/EliteTracker.cs
Normal file
@@ -0,0 +1,264 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using AngleSharp.Parser.Html;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
|
||||
using Jackett.Models;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
using Jackett.Services;
|
||||
using Jackett.Utils;
|
||||
using Jackett.Utils.Clients;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
class EliteTracker : BaseIndexer, IIndexer
|
||||
{
|
||||
string LoginUrl { get { return SiteLink + "takelogin.php"; } }
|
||||
string BrowseUrl { get { return SiteLink + "browse.php"; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
{
|
||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public EliteTracker(IIndexerManagerService indexerManager, IWebClient webClient, Logger logger, IProtectionService protectionService)
|
||||
: base(name: "Elite-Tracker",
|
||||
description: "French Torrent Tracker",
|
||||
link: "https://elite-tracker.net/",
|
||||
manager: indexerManager,
|
||||
logger: logger,
|
||||
p: protectionService,
|
||||
client: webClient,
|
||||
configData: new ConfigurationDataBasicLogin()
|
||||
)
|
||||
{
|
||||
Encoding = Encoding.GetEncoding("UTF-8");
|
||||
Language = "fr-fr";
|
||||
|
||||
AddCategoryMapping(27, TorznabCatType.TVAnime, "Animation/Animes");
|
||||
AddCategoryMapping(63, TorznabCatType.TVAnime, "Animes DVD");
|
||||
AddCategoryMapping(56, TorznabCatType.TVAnime, "Animes HD");
|
||||
AddCategoryMapping(59, TorznabCatType.TVAnime, "Animes Serie");
|
||||
|
||||
AddCategoryMapping(3, TorznabCatType.PC0day, "APPLICATION");
|
||||
AddCategoryMapping(74, TorznabCatType.PCPhoneAndroid, "ANDROID");
|
||||
AddCategoryMapping(57, TorznabCatType.PCPhoneIOS, "IPHONE");
|
||||
AddCategoryMapping(6, TorznabCatType.PC0day, "LINUX");
|
||||
AddCategoryMapping(5, TorznabCatType.PCMac, "MAC");
|
||||
AddCategoryMapping(4, TorznabCatType.PC0day, "WINDOWS");
|
||||
|
||||
AddCategoryMapping(38, TorznabCatType.TVDocumentary, "DOCUMENTAIRES");
|
||||
|
||||
AddCategoryMapping(34, TorznabCatType.Books, "EBOOKS");
|
||||
|
||||
AddCategoryMapping(7, TorznabCatType.Movies, "FILMS");
|
||||
AddCategoryMapping(11, TorznabCatType.MoviesDVD, "DVD");
|
||||
AddCategoryMapping(10, TorznabCatType.MoviesSD, "DVD-RIP/BD-RIP");
|
||||
AddCategoryMapping(53, TorznabCatType.MoviesSD, "DVD-SCREENER");
|
||||
AddCategoryMapping(9, TorznabCatType.MoviesDVD, "R5");
|
||||
AddCategoryMapping(8, TorznabCatType.MoviesSD, "SCREENER");
|
||||
AddCategoryMapping(40, TorznabCatType.Movies, "VO");
|
||||
AddCategoryMapping(39, TorznabCatType.Movies, "VOSTFR");
|
||||
AddCategoryMapping(48, TorznabCatType.MoviesHD, "HD");
|
||||
AddCategoryMapping(51, TorznabCatType.MoviesHD, "1080P");
|
||||
AddCategoryMapping(70, TorznabCatType.Movies3D, "3D");
|
||||
AddCategoryMapping(50, TorznabCatType.MoviesHD, "720P");
|
||||
AddCategoryMapping(49, TorznabCatType.MoviesBluRay, "BluRay");
|
||||
AddCategoryMapping(78, TorznabCatType.MoviesHD, "M - HD");
|
||||
|
||||
AddCategoryMapping(15, TorznabCatType.Console, "JEUX VIDEO");
|
||||
AddCategoryMapping(76, TorznabCatType.Console3DS, "3DS");
|
||||
AddCategoryMapping(18, TorznabCatType.ConsoleNDS, "DS");
|
||||
AddCategoryMapping(55, TorznabCatType.PCPhoneIOS, "IPHONE");
|
||||
AddCategoryMapping(80, TorznabCatType.PCGames, "LINUX");
|
||||
AddCategoryMapping(79, TorznabCatType.PCMac, "OSX");
|
||||
AddCategoryMapping(22, TorznabCatType.PCGames, "PC");
|
||||
AddCategoryMapping(66, TorznabCatType.ConsolePS3, "PS2");
|
||||
AddCategoryMapping(58, TorznabCatType.ConsolePS3, "PS3");
|
||||
AddCategoryMapping(81, TorznabCatType.ConsolePS4, "PS4");
|
||||
AddCategoryMapping(20, TorznabCatType.ConsolePSP, "PSP");
|
||||
AddCategoryMapping(75, TorznabCatType.ConsolePS3, "PSX");
|
||||
AddCategoryMapping(19, TorznabCatType.ConsoleWii, "WII");
|
||||
AddCategoryMapping(83, TorznabCatType.ConsoleWiiU, "WiiU");
|
||||
AddCategoryMapping(16, TorznabCatType.ConsoleXbox, "XBOX");
|
||||
AddCategoryMapping(82, TorznabCatType.ConsoleXboxOne, "XBOX ONE");
|
||||
AddCategoryMapping(17, TorznabCatType.ConsoleXbox360, "XBOX360");
|
||||
AddCategoryMapping(44, TorznabCatType.ConsoleXbox360, "XBOX360.E");
|
||||
AddCategoryMapping(54, TorznabCatType.ConsoleXbox360, "XBOX360.JTAG");
|
||||
AddCategoryMapping(43, TorznabCatType.ConsoleXbox360, "XBOX360.NTSC");
|
||||
|
||||
AddCategoryMapping(23, TorznabCatType.Audio, "MUSIQUES");
|
||||
AddCategoryMapping(26, TorznabCatType.Audio, "CLIP/CONCERT");
|
||||
AddCategoryMapping(61, TorznabCatType.AudioLossless, "FLAC");
|
||||
AddCategoryMapping(60, TorznabCatType.AudioMP3, "MP3");
|
||||
|
||||
AddCategoryMapping(30, TorznabCatType.TV, "SERIES");
|
||||
AddCategoryMapping(73, TorznabCatType.TV, "Pack TV");
|
||||
AddCategoryMapping(31, TorznabCatType.TV, "Series FR");
|
||||
AddCategoryMapping(32, TorznabCatType.TV, "Series VO");
|
||||
AddCategoryMapping(33, TorznabCatType.TV, "Series VO-STFR");
|
||||
AddCategoryMapping(77, TorznabCatType.TVSD, "Series.DVD");
|
||||
AddCategoryMapping(67, TorznabCatType.TVHD, "Series.FR.HD");
|
||||
AddCategoryMapping(68, TorznabCatType.TVHD, "Series.VO.HD");
|
||||
AddCategoryMapping(69, TorznabCatType.TVHD, "Series.VOSTFR.HD");
|
||||
|
||||
AddCategoryMapping(47, TorznabCatType.TV, "SPECTACLES/EMISSIONS");
|
||||
AddCategoryMapping(71, TorznabCatType.TV, "Emissions");
|
||||
AddCategoryMapping(72, TorznabCatType.TV, "Spectacles");
|
||||
|
||||
AddCategoryMapping(35, TorznabCatType.TVSport, "SPORT");
|
||||
AddCategoryMapping(36, TorznabCatType.TVSport, "CATCH");
|
||||
AddCategoryMapping(65, TorznabCatType.TVSport, "UFC");
|
||||
|
||||
AddCategoryMapping(37, TorznabCatType.XXX, "XXX");
|
||||
}
|
||||
|
||||
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
|
||||
var pairs = new Dictionary<string, string>
|
||||
{
|
||||
{ "username", configData.Username.Value },
|
||||
{ "password", configData.Password.Value }
|
||||
};
|
||||
|
||||
var result = await PostDataWithCookies(LoginUrl, pairs);
|
||||
|
||||
await ConfigureIfOK(result.Cookies, result.Cookies != null, () =>
|
||||
{
|
||||
var errorMessage = result.Content;
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
|
||||
return IndexerConfigurationStatus.RequiresTesting;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
var searchString = query.GetQueryString();
|
||||
|
||||
var queryCollection = new Dictionary<string, string>();
|
||||
queryCollection.Add("search_type", "t_name");
|
||||
queryCollection.Add("do", "search");
|
||||
queryCollection.Add("keywords", searchString);
|
||||
queryCollection.Add("category", "0"); // multi cat search not supported
|
||||
|
||||
var results = await PostDataWithCookies(BrowseUrl, queryCollection);
|
||||
|
||||
try
|
||||
{
|
||||
var RowsSelector = "table[id='sortabletable'] > tbody > tr";
|
||||
var SearchResultParser = new HtmlParser();
|
||||
var SearchResultDocument = SearchResultParser.Parse(results.Content);
|
||||
var Rows = SearchResultDocument.QuerySelectorAll(RowsSelector);
|
||||
var lastDate = DateTime.Now;
|
||||
|
||||
foreach (var Row in Rows.Skip(1))
|
||||
{
|
||||
var release = new ReleaseInfo();
|
||||
release.MinimumRatio = 1;
|
||||
release.MinimumSeedTime = 0;
|
||||
|
||||
var category = Row.QuerySelector("td:nth-child(1) > a");
|
||||
var title = Row.QuerySelector("td:nth-child(2) a");
|
||||
var added = Row.QuerySelector("td:nth-child(2) > div:has(span[style=\"float: right;\"])");
|
||||
var pretime = added.QuerySelector("font.mkprettytime");
|
||||
var tooltip = Row.QuerySelector("td:nth-child(2) > div.tooltip-content");
|
||||
|
||||
var link = Row.QuerySelector("td:nth-child(3)").QuerySelector("a");
|
||||
var comments = Row.QuerySelector("td:nth-child(2)").QuerySelector("a");
|
||||
var Size = Row.QuerySelector("td:nth-child(5)");
|
||||
var Grabs = Row.QuerySelector("td:nth-child(6)").QuerySelector("a");
|
||||
var Seeders = Row.QuerySelector("td:nth-child(7)").QuerySelector("a");
|
||||
var Leechers = Row.QuerySelector("td:nth-child(8)").QuerySelector("a");
|
||||
|
||||
var categoryIdparts = category.GetAttribute("href").Split('-');
|
||||
var categoryId = categoryIdparts[categoryIdparts.Length-1].Replace(".ts", "");
|
||||
|
||||
release.Title = title.TextContent;
|
||||
release.Category = MapTrackerCatToNewznab(categoryId);
|
||||
release.Link = new Uri(link.GetAttribute("href"));
|
||||
release.Comments = new Uri(comments.GetAttribute("href"));
|
||||
release.Guid = release.Link;
|
||||
release.Size = ReleaseInfo.GetBytes(Size.TextContent);
|
||||
release.Seeders = ParseUtil.CoerceInt(Seeders.TextContent);
|
||||
release.Peers = ParseUtil.CoerceInt(Leechers.TextContent) + release.Seeders;
|
||||
release.Grabs = ParseUtil.CoerceLong(Grabs.TextContent);
|
||||
|
||||
if (added.QuerySelector("img[alt^=\"TORRENT GRATUIT\"]") != null)
|
||||
release.DownloadVolumeFactor = 0;
|
||||
else if (added.QuerySelector("img[alt^=\"TORRENT SILVER\"]") != null)
|
||||
release.DownloadVolumeFactor = 0.5;
|
||||
else
|
||||
release.DownloadVolumeFactor = 1;
|
||||
|
||||
if (added.QuerySelector("img[alt^=\"TORRENT X2\"]") != null)
|
||||
release.UploadVolumeFactor = 2;
|
||||
else
|
||||
release.UploadVolumeFactor = 1;
|
||||
|
||||
if (tooltip != null)
|
||||
{
|
||||
var banner = tooltip.QuerySelector("img");
|
||||
if (banner != null)
|
||||
{
|
||||
release.BannerUrl = new Uri(banner.GetAttribute("src"));
|
||||
banner.Remove();
|
||||
}
|
||||
|
||||
tooltip.QuerySelector("div:contains(\"Total Hits: \")").Remove();
|
||||
|
||||
var longtitle = tooltip.QuerySelectorAll("div").First();
|
||||
release.Title = longtitle.TextContent;
|
||||
longtitle.Remove();
|
||||
|
||||
var desc = tooltip.TextContent.Trim();
|
||||
if (!string.IsNullOrWhiteSpace(desc))
|
||||
release.Description = desc;
|
||||
}
|
||||
|
||||
// if even the tooltip title is shortened we use the URL
|
||||
if (release.Title.EndsWith("..."))
|
||||
{
|
||||
var tregex = new Regex(@"/([^/]+)-s-\d+\.ts");
|
||||
var tmatch = tregex.Match(release.Comments.ToString());
|
||||
release.Title = tmatch.Groups[1].Value;
|
||||
}
|
||||
|
||||
if (pretime != null)
|
||||
{
|
||||
if (release.Description == null)
|
||||
release.Description = pretime.TextContent;
|
||||
else
|
||||
release.Description += "<br>\n" + pretime.TextContent;
|
||||
release.PublishDate = lastDate;
|
||||
}
|
||||
else
|
||||
{
|
||||
release.PublishDate = DateTime.ParseExact(added.TextContent.Trim(), "dd.M.yyyy HH:mm", CultureInfo.InvariantCulture);
|
||||
lastDate = release.PublishDate;
|
||||
}
|
||||
|
||||
releases.Add(release);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(results.Content, ex);
|
||||
}
|
||||
|
||||
return releases;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -48,18 +48,37 @@ namespace Jackett.Indexers
|
||||
Encoding = Encoding.UTF8;
|
||||
Language = "en-us";
|
||||
|
||||
AddCategoryMapping(4, TorznabCatType.TV); // TV/XVID
|
||||
AddCategoryMapping(17, TorznabCatType.TVHD); // TV/X264
|
||||
AddCategoryMapping(19, TorznabCatType.TV); // TV/DVDRIP
|
||||
AddCategoryMapping(26, TorznabCatType.TVHD); // TV/BLURAY
|
||||
AddCategoryMapping(37, TorznabCatType.TV); // TV/DVDR
|
||||
AddCategoryMapping(47, TorznabCatType.TV); // TV/SD
|
||||
|
||||
AddCategoryMapping(7, TorznabCatType.Movies); // Movies/XVID
|
||||
AddCategoryMapping(8, TorznabCatType.MoviesDVD); // Movies/DVDR
|
||||
AddCategoryMapping(12, TorznabCatType.MoviesBluRay); // Movies/BLURAY
|
||||
AddCategoryMapping(18, TorznabCatType.MoviesHD); // Movies/X264-HD
|
||||
AddCategoryMapping(49, TorznabCatType.MoviesSD); // Movies/X264-SD
|
||||
AddCategoryMapping(2, TorznabCatType.PC0day, "0DAY");
|
||||
AddCategoryMapping(16, TorznabCatType.TVAnime, "Anime");
|
||||
AddCategoryMapping(1, TorznabCatType.PC0day, "APPS");
|
||||
AddCategoryMapping(9, TorznabCatType.Other, "E-Learning");
|
||||
AddCategoryMapping(35, TorznabCatType.TVFOREIGN, "Foreign");
|
||||
AddCategoryMapping(32, TorznabCatType.ConsoleNDS, "Games/NDS");
|
||||
AddCategoryMapping(6, TorznabCatType.PCGames, "Games/PC");
|
||||
AddCategoryMapping(36, TorznabCatType.ConsolePS4, "Games/Playstation");
|
||||
AddCategoryMapping(29, TorznabCatType.ConsolePSP, "Games/PSP");
|
||||
AddCategoryMapping(23, TorznabCatType.ConsoleWii, "Games/WII");
|
||||
AddCategoryMapping(12, TorznabCatType.ConsoleXbox, "Games/XBOX");
|
||||
AddCategoryMapping(11, TorznabCatType.Other, "Misc");
|
||||
AddCategoryMapping(48, TorznabCatType.MoviesBluRay, "Movies/BLURAY");
|
||||
AddCategoryMapping(8, TorznabCatType.MoviesDVD, "Movies/DVDR");
|
||||
AddCategoryMapping(18, TorznabCatType.MoviesHD, "Movies/X264-HD");
|
||||
AddCategoryMapping(49, TorznabCatType.MoviesSD, "Movies/X264-SD");
|
||||
AddCategoryMapping(7, TorznabCatType.MoviesSD, "Movies/XVID");
|
||||
AddCategoryMapping(38, TorznabCatType.AudioOther, "Music/DVDR");
|
||||
AddCategoryMapping(46, TorznabCatType.AudioLossless, "Music/FLAC");
|
||||
AddCategoryMapping(5, TorznabCatType.AudioMP3, "Music/MP3");
|
||||
AddCategoryMapping(13, TorznabCatType.AudioVideo, "Music/Vids");
|
||||
AddCategoryMapping(26, TorznabCatType.TVHD, "TV/BLURAY");
|
||||
AddCategoryMapping(37, TorznabCatType.TVSD, "TV/DVDR");
|
||||
AddCategoryMapping(19, TorznabCatType.TVSD, "TV/DVDRIP");
|
||||
AddCategoryMapping(47, TorznabCatType.TVSD, "TV/SD");
|
||||
AddCategoryMapping(17, TorznabCatType.TVHD, "TV/X264");
|
||||
AddCategoryMapping(4, TorznabCatType.TVSD, "TV/XVID");
|
||||
AddCategoryMapping(22, TorznabCatType.XXX, "XXX/0DAY");
|
||||
AddCategoryMapping(25, TorznabCatType.XXXDVD, "XXX/DVDR");
|
||||
AddCategoryMapping(20, TorznabCatType.XXX, "XXX/HD");
|
||||
AddCategoryMapping(3, TorznabCatType.XXXXviD, "XXX/XVID");
|
||||
}
|
||||
|
||||
public override async Task<ConfigurationData> GetConfigurationForSetup()
|
||||
@@ -116,18 +135,17 @@ namespace Jackett.Indexers
|
||||
}
|
||||
}
|
||||
|
||||
var cookieJar = configData.CookieHeader.Value;
|
||||
var response = await RequestLoginAndFollowRedirect(LoginUrl, pairs, configData.CookieHeader.Value, true, null, StartPageUrl);
|
||||
cookieJar += response.Cookies.ToString();
|
||||
response = await RequestStringWithCookiesAndRetry(SearchUrl, cookieJar);
|
||||
var response = await RequestLoginAndFollowRedirect(LoginUrl, pairs, configData.CookieHeader.Value, true, SearchUrl, StartPageUrl);
|
||||
UpdateCookieHeader(response.Cookies);
|
||||
|
||||
await ConfigureIfOK(cookieJar, response.Content != null && response.Content.Contains("logout.php"), () =>
|
||||
await ConfigureIfOK(configData.CookieHeader.Value, response.Content != null && response.Content.Contains("logout.php"), () =>
|
||||
{
|
||||
CQ dom = response.Content;
|
||||
var messageEl = dom["h2"].Last();
|
||||
var messageEl = dom["div:has(h2)"].Last();
|
||||
messageEl.Children("a").Remove();
|
||||
messageEl.Children("style").Remove();
|
||||
var errorMessage = messageEl.Text().Trim();
|
||||
IsConfigured = false;
|
||||
throw new ExceptionWithConfigData(errorMessage, configData);
|
||||
});
|
||||
return IndexerConfigurationStatus.RequiresTesting;
|
||||
@@ -140,6 +158,8 @@ namespace Jackett.Indexers
|
||||
var queryCollection = new NameValueCollection();
|
||||
|
||||
queryCollection.Add("view", "0");
|
||||
queryCollection.Add("searchtype", "1");
|
||||
queryCollection.Add("incldead", "1");
|
||||
if (!string.IsNullOrWhiteSpace(searchString))
|
||||
{
|
||||
queryCollection.Add("search", searchString);
|
||||
@@ -152,7 +172,14 @@ namespace Jackett.Indexers
|
||||
|
||||
var searchUrl = SearchUrl + "?" + queryCollection.GetQueryString();
|
||||
|
||||
var results = await RequestStringWithCookiesAndRetry(searchUrl, CookieHeader);
|
||||
var results = await RequestStringWithCookiesAndRetry(searchUrl);
|
||||
if (results.IsRedirect)
|
||||
{
|
||||
// re-login
|
||||
await ApplyConfiguration(null);
|
||||
results = await RequestStringWithCookiesAndRetry(searchUrl);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
CQ dom = results.Content;
|
||||
@@ -162,19 +189,11 @@ namespace Jackett.Indexers
|
||||
var release = new ReleaseInfo();
|
||||
CQ qRow = row.Cq();
|
||||
|
||||
//CQ qLink = qRow.Children().ElementAt(1).Cq().Children("a").ElementAt(1).Cq();
|
||||
CQ qLink;
|
||||
CQ qTmp = qRow.Children().ElementAt(1).Cq().Find("a");
|
||||
if (qTmp.Length < 2) {
|
||||
qLink = qRow.Children().ElementAt(1).Cq().Find("a").ElementAt(0).Cq();
|
||||
} else {
|
||||
qLink = qRow.Children().ElementAt(1).Cq().Find("a").ElementAt(1).Cq();
|
||||
}
|
||||
release.MinimumRatio = 0;
|
||||
release.MinimumSeedTime = 2 * 24 * 60 * 60;
|
||||
|
||||
release.MinimumRatio = 1;
|
||||
release.MinimumSeedTime = 172800;
|
||||
var qLink = qRow.Find("a[title][href^=\"details.php?id=\"]");
|
||||
release.Title = qLink.Attr("title");
|
||||
release.Description = release.Title;
|
||||
release.Guid = new Uri(SiteLink + qLink.Attr("href").TrimStart('/'));
|
||||
release.Comments = release.Guid;
|
||||
|
||||
@@ -186,14 +205,22 @@ namespace Jackett.Indexers
|
||||
release.Category = MapTrackerCatToNewznab(catNum);
|
||||
|
||||
var dateString = qRow.Children().ElementAt(6).Cq().Text().Trim();
|
||||
//var pubDate = DateTime.ParseExact(dateString, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
|
||||
release.PublishDate = Jackett.Utils.DateTimeUtil.FromTimeAgo(dateString);
|
||||
release.PublishDate = DateTime.ParseExact(dateString, "yyyy-MM-ddHH:mm:ss", CultureInfo.InvariantCulture);
|
||||
|
||||
var sizeStr = qRow.Children().ElementAt(7).Cq().Text().Split(new char[] { '/' })[0];
|
||||
release.Size = ReleaseInfo.GetBytes(sizeStr);
|
||||
|
||||
release.Seeders = ParseUtil.CoerceInt(qRow.Children().ElementAt(8).Cq().Text().Split(new char[] { '/' })[0].Trim());
|
||||
release.Peers = ParseUtil.CoerceInt(qRow.Children().ElementAt(8).Cq().Text().Split(new char[] { '/' })[1].Trim()) + release.Seeders;
|
||||
release.Files = ParseUtil.CoerceLong(qRow.Find("td:nth-child(5)").Text());
|
||||
release.Grabs = ParseUtil.CoerceLong(qRow.Find("a[href^=\"snatches.php?id=\"]").Text().Split(' ')[0]);
|
||||
|
||||
release.DownloadVolumeFactor = 0;
|
||||
release.UploadVolumeFactor = 1;
|
||||
|
||||
var desc = qRow.Find("td:nth-child(2)");
|
||||
desc.Find("a").Remove();
|
||||
release.Description = desc.Text();
|
||||
|
||||
releases.Add(release);
|
||||
}
|
||||
|
@@ -34,6 +34,7 @@ namespace Jackett.Indexers
|
||||
|
||||
// Called on startup when initializing indexers from saved configuration
|
||||
void LoadFromSavedConfiguration(JToken jsonConfig);
|
||||
void SaveConfig();
|
||||
|
||||
Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query);
|
||||
|
||||
|
@@ -194,6 +194,8 @@ namespace Jackett.Indexers
|
||||
release.Description = release.Title;
|
||||
release.MinimumRatio = 1;
|
||||
release.MinimumSeedTime = 172800;
|
||||
release.DownloadVolumeFactor = 0;
|
||||
release.UploadVolumeFactor = 1;
|
||||
|
||||
string downloadLink = SiteLink + torrentTxt.GetAttribute("href");
|
||||
string downloadId = downloadLink.Substring(downloadLink.IndexOf("&id=") + 4);
|
||||
|
194
src/Jackett/Indexers/Superbits.cs
Normal file
194
src/Jackett/Indexers/Superbits.cs
Normal file
@@ -0,0 +1,194 @@
|
||||
using Jackett.Models;
|
||||
using Jackett.Services;
|
||||
using Jackett.Utils;
|
||||
using Jackett.Utils.Clients;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Jackett.Models.IndexerConfig;
|
||||
using System.Collections.Specialized;
|
||||
using Newtonsoft.Json;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
public class Superbits : BaseIndexer, IIndexer
|
||||
{
|
||||
private string SearchUrl { get { return SiteLink + "api/v1/torrents"; } }
|
||||
private string LoginUrl { get { return SiteLink + "api/v1/auth"; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
{
|
||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public Superbits(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps)
|
||||
: base(name: "Superbits",
|
||||
description: null,
|
||||
link: "https://superbits.org/",
|
||||
caps: new TorznabCapabilities(),
|
||||
manager: i,
|
||||
client: w,
|
||||
logger: l,
|
||||
p: ps,
|
||||
configData: new ConfigurationDataBasicLogin())
|
||||
{
|
||||
Encoding = Encoding.GetEncoding("UTF-8");
|
||||
Language = "sv-sw";
|
||||
|
||||
AddCategoryMapping(1, TorznabCatType.MoviesDVD, "DVD-R Swesub");
|
||||
AddCategoryMapping(2, TorznabCatType.TV, "DVD-R TV");
|
||||
AddCategoryMapping(3, TorznabCatType.BooksEbook, "eBok");
|
||||
AddCategoryMapping(4, TorznabCatType.MoviesHD, "Film 1080");
|
||||
AddCategoryMapping(5, TorznabCatType.Movies3D, "Film 3D");
|
||||
AddCategoryMapping(6, TorznabCatType.MoviesHD, "Film 720");
|
||||
AddCategoryMapping(7, TorznabCatType.MoviesBluRay, "Film Bluray");
|
||||
AddCategoryMapping(8, TorznabCatType.TV, "Svensk TV");
|
||||
AddCategoryMapping(9, TorznabCatType.AudioAudiobook, "Ljudböcker");
|
||||
AddCategoryMapping(10, TorznabCatType.AudioVideo, "Musikvideos");
|
||||
AddCategoryMapping(11, TorznabCatType.BooksMagazines, "E-tidningar");
|
||||
AddCategoryMapping(12, TorznabCatType.Audio, "Musik");
|
||||
AddCategoryMapping(13, TorznabCatType.Other, "Omslag");
|
||||
AddCategoryMapping(14, TorznabCatType.Other, "Övrigt");
|
||||
AddCategoryMapping(15, TorznabCatType.PCGames, "PC-Spel");
|
||||
AddCategoryMapping(16, TorznabCatType.PC0day, "Program");
|
||||
AddCategoryMapping(17, TorznabCatType.ConsolePS3, "PS3");
|
||||
AddCategoryMapping(18, TorznabCatType.TV, "TV");
|
||||
AddCategoryMapping(19, TorznabCatType.ConsoleWii, "Wii");
|
||||
AddCategoryMapping(20, TorznabCatType.ConsoleXbox, "Xbox");
|
||||
AddCategoryMapping(21, TorznabCatType.MoviesOther, "Xvid");
|
||||
AddCategoryMapping(22, TorznabCatType.XXX, "XXX");
|
||||
}
|
||||
|
||||
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
LoadValuesFromJson(configJson);
|
||||
var queryCollection = new NameValueCollection();
|
||||
|
||||
queryCollection.Add("username", configData.Username.Value);
|
||||
queryCollection.Add("password", configData.Password.Value);
|
||||
|
||||
var loginUrl = LoginUrl + "?" + queryCollection.GetQueryString();
|
||||
var loginResult = await RequestStringWithCookies(loginUrl, null, SiteLink);
|
||||
|
||||
await ConfigureIfOK(loginResult.Cookies, loginResult.Content.Contains("\"user\""), () =>
|
||||
{
|
||||
throw new ExceptionWithConfigData(loginResult.Content, configData);
|
||||
});
|
||||
return IndexerConfigurationStatus.RequiresTesting;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
List<ReleaseInfo> releases = new List<ReleaseInfo>();
|
||||
var queryCollection = new NameValueCollection();
|
||||
var searchString = query.GetQueryString();
|
||||
var searchUrl = SearchUrl;
|
||||
|
||||
queryCollection.Add("extendedSearch", "false");
|
||||
queryCollection.Add("freeleech", "false");
|
||||
queryCollection.Add("index", "0");
|
||||
queryCollection.Add("limit", "100");
|
||||
queryCollection.Add("order", "desc");
|
||||
queryCollection.Add("page", "search");
|
||||
queryCollection.Add("searchText", searchString);
|
||||
queryCollection.Add("section", "all");
|
||||
queryCollection.Add("sort", "d");
|
||||
queryCollection.Add("section", "all");
|
||||
queryCollection.Add("stereoscopic", "false");
|
||||
queryCollection.Add("sweaudio", "false");
|
||||
queryCollection.Add("swesub", "false");
|
||||
queryCollection.Add("watchview", "false");
|
||||
|
||||
foreach (var cat in MapTorznabCapsToTrackers(query))
|
||||
queryCollection.Add("categories[]", cat);
|
||||
|
||||
searchUrl += "?" + queryCollection.GetQueryString();
|
||||
var results = await RequestStringWithCookies(searchUrl, null, SiteLink);
|
||||
|
||||
try
|
||||
{
|
||||
//var json = JArray.Parse(results.Content);
|
||||
dynamic json = JsonConvert.DeserializeObject<dynamic>(results.Content);
|
||||
foreach (var row in json)
|
||||
{
|
||||
var release = new ReleaseInfo();
|
||||
var descriptions = new List<string>();
|
||||
var tags = new List<string>();
|
||||
|
||||
release.MinimumRatio = 1.1;
|
||||
release.MinimumSeedTime = 48 * 60 * 60;
|
||||
release.Title = row.name;
|
||||
release.Category = MapTrackerCatToNewznab(row.category.ToString());
|
||||
release.Size = row.size;
|
||||
release.Seeders = row.seeders;
|
||||
release.Peers = row.leechers + release.Seeders;
|
||||
release.PublishDate = DateTime.ParseExact(row.added.ToString() + " +01:00", "yyyy-MM-dd HH:mm:ss zzz", CultureInfo.InvariantCulture);
|
||||
release.Files = row.numfiles;
|
||||
release.Grabs = row.times_completed;
|
||||
|
||||
release.Comments = new Uri(SiteLink + "torrent/" + row.id.ToString() + "/");
|
||||
release.Link = new Uri(SiteLink + "api/v1/torrents/download/" + row.id.ToString());
|
||||
|
||||
if (row.frileech == 1)
|
||||
release.DownloadVolumeFactor = 0;
|
||||
else
|
||||
release.DownloadVolumeFactor = 1;
|
||||
release.UploadVolumeFactor = 1;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(row.customcover.ToString()))
|
||||
release.BannerUrl = new Uri(SiteLink + row.customcover);
|
||||
|
||||
if (row.imdbid2 != null && row.imdbid2.ToString().StartsWith("tt"))
|
||||
{
|
||||
https://superbits.org/img/imdb/tt5288312.jpg
|
||||
release.Imdb = ParseUtil.CoerceLong(row.imdbid2.ToString().Substring(2));
|
||||
descriptions.Add("Title: " + row.title);
|
||||
descriptions.Add("Year: " + row.year);
|
||||
descriptions.Add("Genres: " + row.genres);
|
||||
descriptions.Add("Tagline: " + row.tagline);
|
||||
descriptions.Add("Cast: " + row.cast);
|
||||
descriptions.Add("Rating: " + row.rating);
|
||||
descriptions.Add("Plot: " + row.plot);
|
||||
|
||||
release.BannerUrl = new Uri(SiteLink + "img/imdb/" + row.imdbid2 + ".jpg");
|
||||
}
|
||||
|
||||
if ((int)row.p2p == 1)
|
||||
tags.Add("P2P");
|
||||
if ((int)row.pack == 1)
|
||||
tags.Add("Pack");
|
||||
if ((int)row.reqid != 0)
|
||||
tags.Add("Request");
|
||||
if ((int)row.sweaudio != 0)
|
||||
tags.Add("Swedish audio");
|
||||
if ((int)row.swesub != 0)
|
||||
tags.Add("Swedish subtitles");
|
||||
|
||||
if (tags.Count > 0)
|
||||
descriptions.Add("Tags: " + string.Join(", ", tags));
|
||||
|
||||
var preDate = row.preDate.ToString();
|
||||
if (!string.IsNullOrWhiteSpace(preDate) && preDate != "1970-01-01 01:00:00")
|
||||
descriptions.Add("PRE: " + preDate);
|
||||
|
||||
descriptions.Add("Section: " + row.section);
|
||||
|
||||
release.Description = string.Join("<br>\n", descriptions);
|
||||
|
||||
releases.Add(release);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(results.Content, ex);
|
||||
}
|
||||
|
||||
return releases;
|
||||
}
|
||||
}
|
||||
}
|
1584
src/Jackett/Indexers/rutracker.cs
Normal file
1584
src/Jackett/Indexers/rutracker.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -165,8 +165,12 @@
|
||||
<Compile Include="Controllers\TorznabController.cs" />
|
||||
<Compile Include="Controllers\DownloadController.cs" />
|
||||
<Compile Include="Engine.cs" />
|
||||
<Compile Include="Indexers\Superbits.cs" />
|
||||
<Compile Include="Indexers\rutracker.cs" />
|
||||
<Compile Include="Indexers\Abstract\GazelleTracker.cs" />
|
||||
<Compile Include="Indexers\AnimeTorrents.cs" />
|
||||
<Compile Include="Indexers\7tor.cs" />
|
||||
<Compile Include="Indexers\EliteTracker.cs" />
|
||||
<Compile Include="Indexers\Torrentech.cs" />
|
||||
<Compile Include="Indexers\nostream.cs" />
|
||||
<Compile Include="Indexers\notwhatcd.cs" />
|
||||
@@ -401,7 +405,7 @@
|
||||
<Content Include="Definitions\thehorrorcharnel.yml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Definitions\tspate.yml">
|
||||
<Content Include="Definitions\sharespacedb.yml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Definitions\eotforum.yml">
|
||||
@@ -419,9 +423,6 @@
|
||||
<Content Include="Definitions\blubits.yml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Definitions\freakstrackingsystem.yml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Definitions\theshinning.yml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
@@ -488,6 +489,21 @@
|
||||
<Content Include="Definitions\chdbits.yml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Definitions\hdsky.yml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Definitions\mteamtp.yml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Definitions\bithumen.yml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Definitions\torrenting.yml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Definitions\funkytorrents.yml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<None Include="packages.config">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
|
@@ -28,6 +28,8 @@ namespace Jackett.Services
|
||||
|
||||
public class IndexerManagerService : IIndexerManagerService
|
||||
{
|
||||
private static readonly object configWriteLock = new object();
|
||||
|
||||
private IContainer container;
|
||||
private IConfigurationService configService;
|
||||
private Logger logger;
|
||||
@@ -55,7 +57,27 @@ namespace Jackett.Services
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex, "Failed loading configuration for {0}, you must reconfigure this indexer", idx.DisplayName);
|
||||
logger.Error(ex, "Failed loading configuration for {0}, trying backup", idx.DisplayName);
|
||||
var configFilePathBak = configFilePath + ".bak";
|
||||
if (File.Exists(configFilePathBak))
|
||||
{
|
||||
try
|
||||
{
|
||||
var fileStrBak = File.ReadAllText(configFilePathBak);
|
||||
var jsonStringBak = JToken.Parse(fileStrBak);
|
||||
idx.LoadFromSavedConfiguration(jsonStringBak);
|
||||
logger.Info("Successfully loaded backup config for {0}", idx.DisplayName);
|
||||
idx.SaveConfig();
|
||||
}
|
||||
catch (Exception exbak)
|
||||
{
|
||||
logger.Error(exbak, "Failed loading backup configuration for {0}, you must reconfigure this indexer", idx.DisplayName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error(ex, "Failed loading backup configuration for {0} (no backup available), you must reconfigure this indexer", idx.DisplayName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -157,59 +179,62 @@ namespace Jackett.Services
|
||||
|
||||
public void SaveConfig(IIndexer indexer, JToken obj)
|
||||
{
|
||||
var uID = Guid.NewGuid().ToString("N");
|
||||
var configFilePath = GetIndexerConfigFilePath(indexer);
|
||||
var configFilePathBak = configFilePath + ".bak";
|
||||
var configFilePathTmp = configFilePath + "." + uID + ".tmp";
|
||||
var content = obj.ToString();
|
||||
lock (configWriteLock)
|
||||
{
|
||||
var uID = Guid.NewGuid().ToString("N");
|
||||
var configFilePath = GetIndexerConfigFilePath(indexer);
|
||||
var configFilePathBak = configFilePath + ".bak";
|
||||
var configFilePathTmp = configFilePath + "." + uID + ".tmp";
|
||||
var content = obj.ToString();
|
||||
|
||||
logger.Debug(string.Format("Saving new config file: {0}", configFilePathTmp));
|
||||
logger.Debug(string.Format("Saving new config file: {0}", configFilePathTmp));
|
||||
|
||||
if (string.IsNullOrWhiteSpace(content))
|
||||
{
|
||||
throw new Exception(string.Format("New config content for {0} is empty, please report this bug.", indexer.ID));
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(content))
|
||||
{
|
||||
throw new Exception(string.Format("New config content for {0} is empty, please report this bug.", indexer.ID));
|
||||
}
|
||||
|
||||
if (content.Contains("\x00"))
|
||||
{
|
||||
throw new Exception(string.Format("New config content for {0} contains 0x00, please report this bug. Content: {1}", indexer.ID, content));
|
||||
}
|
||||
if (content.Contains("\x00"))
|
||||
{
|
||||
throw new Exception(string.Format("New config content for {0} contains 0x00, please report this bug. Content: {1}", indexer.ID, content));
|
||||
}
|
||||
|
||||
// make sure the config directory exists
|
||||
if (!Directory.Exists(configService.GetIndexerConfigDir()))
|
||||
Directory.CreateDirectory(configService.GetIndexerConfigDir());
|
||||
// make sure the config directory exists
|
||||
if (!Directory.Exists(configService.GetIndexerConfigDir()))
|
||||
Directory.CreateDirectory(configService.GetIndexerConfigDir());
|
||||
|
||||
// create new temporary config file
|
||||
File.WriteAllText(configFilePathTmp, content);
|
||||
var fileInfo = new FileInfo(configFilePathTmp);
|
||||
if (fileInfo.Length == 0)
|
||||
{
|
||||
throw new Exception(string.Format("New config file {0} is empty, please report this bug.", configFilePathTmp));
|
||||
}
|
||||
// create new temporary config file
|
||||
File.WriteAllText(configFilePathTmp, content);
|
||||
var fileInfo = new FileInfo(configFilePathTmp);
|
||||
if (fileInfo.Length == 0)
|
||||
{
|
||||
throw new Exception(string.Format("New config file {0} is empty, please report this bug.", configFilePathTmp));
|
||||
}
|
||||
|
||||
// create backup file
|
||||
File.Delete(configFilePathBak);
|
||||
if (File.Exists(configFilePath))
|
||||
{
|
||||
// create backup file
|
||||
File.Delete(configFilePathBak);
|
||||
if (File.Exists(configFilePath))
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Move(configFilePath, configFilePathBak);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
logger.Error(string.Format("Error while moving {0} to {1}: {2}", configFilePath, configFilePathBak, ex.ToString()));
|
||||
}
|
||||
}
|
||||
|
||||
// replace the actual config file
|
||||
File.Delete(configFilePath);
|
||||
try
|
||||
{
|
||||
File.Move(configFilePath, configFilePathBak);
|
||||
File.Move(configFilePathTmp, configFilePath);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
logger.Error(string.Format("Error while moving {0} to {1}: {2}", configFilePath, configFilePathBak, ex.ToString()));
|
||||
logger.Error(string.Format("Error while moving {0} to {1}: {2}", configFilePathTmp, configFilePath, ex.ToString()));
|
||||
}
|
||||
}
|
||||
|
||||
// replace the actual config file
|
||||
File.Delete(configFilePath);
|
||||
try
|
||||
{
|
||||
File.Move(configFilePathTmp, configFilePath);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
logger.Error(string.Format("Error while moving {0} to {1}: {2}", configFilePathTmp, configFilePath, ex.ToString()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -17,10 +17,10 @@ namespace Jackett.Utils.Clients
|
||||
public class HttpWebClient : IWebClient
|
||||
{
|
||||
public HttpWebClient(IProcessService p, Logger l, IConfigurationService c)
|
||||
: base(p: p,
|
||||
l: l,
|
||||
: base(p: p,
|
||||
l: l,
|
||||
c: c)
|
||||
{
|
||||
{
|
||||
}
|
||||
|
||||
override public void Init()
|
||||
@@ -67,7 +67,8 @@ namespace Jackett.Utils.Clients
|
||||
AllowAutoRedirect = false, // Do not use this - Bugs ahoy! Lost cookies and more.
|
||||
UseCookies = true,
|
||||
Proxy = proxyServer,
|
||||
UseProxy = useProxy
|
||||
UseProxy = useProxy,
|
||||
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
|
||||
};
|
||||
|
||||
clearanceHandlr.InnerHandler = clientHandlr;
|
||||
@@ -94,6 +95,9 @@ namespace Jackett.Utils.Clients
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(webRequest.Referer))
|
||||
request.Headers.Referrer = new Uri(webRequest.Referer);
|
||||
|
||||
if (!string.IsNullOrEmpty(webRequest.RawBody))
|
||||
{
|
||||
var type = webRequest.Headers.Where(h => h.Key == "Content-Type").Cast<KeyValuePair<string,string>?>().FirstOrDefault();
|
||||
|
@@ -18,6 +18,8 @@ namespace Jackett.Utils
|
||||
|
||||
public static string BytesToDataUrl(byte[] bytes, string mimeType = "image/jpg")
|
||||
{
|
||||
if (bytes == null)
|
||||
return null;
|
||||
return "data:" + mimeType + ";base64," + Convert.ToBase64String(bytes);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user