mirror of
https://github.com/Jackett/Jackett.git
synced 2025-09-11 14:19:17 +02:00
Compare commits
58 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
cc3ebbe1ae | ||
![]() |
d88db81207 | ||
![]() |
9a15f1d1a3 | ||
![]() |
4e5f091b6c | ||
![]() |
517f196d73 | ||
![]() |
9461d2470a | ||
![]() |
c9f874dc93 | ||
![]() |
53b6285810 | ||
![]() |
5d4e0c41d6 | ||
![]() |
754337b58f | ||
![]() |
16f79085ad | ||
![]() |
005539d30d | ||
![]() |
2d5a90ae31 | ||
![]() |
fc060d6468 | ||
![]() |
d0937d3561 | ||
![]() |
7b8de5e28d | ||
![]() |
790f5ddfad | ||
![]() |
760231be43 | ||
![]() |
837e74a743 | ||
![]() |
630f613721 | ||
![]() |
aba9e6db47 | ||
![]() |
88858022af | ||
![]() |
852bb27de0 | ||
![]() |
9a071a3457 | ||
![]() |
db11db28e4 | ||
![]() |
79a8ef957f | ||
![]() |
0e0dfe80a7 | ||
![]() |
c112aef644 | ||
![]() |
2e30fe1899 | ||
![]() |
6b3ffa22c9 | ||
![]() |
9e78f46010 | ||
![]() |
50a09189e4 | ||
![]() |
fcda42b9f1 | ||
![]() |
48f72a3096 | ||
![]() |
e4e1ac2c18 | ||
![]() |
a719048f81 | ||
![]() |
8f1f41a4a1 | ||
![]() |
fffd53cc1f | ||
![]() |
ae7c139452 | ||
![]() |
76a3e7cd85 | ||
![]() |
20495ef32b | ||
![]() |
41b91bb0c3 | ||
![]() |
6e59cc4c33 | ||
![]() |
2aaed9b9e4 | ||
![]() |
f7dc404eaf | ||
![]() |
f3b9e70dde | ||
![]() |
d065f0abf4 | ||
![]() |
6e173558db | ||
![]() |
f78434e758 | ||
![]() |
ef5f2ccb89 | ||
![]() |
f05db7f544 | ||
![]() |
12cc25bdb0 | ||
![]() |
5936defc06 | ||
![]() |
3e9006464d | ||
![]() |
f7bf8fba40 | ||
![]() |
6bbb80a54e | ||
![]() |
7889077498 | ||
![]() |
074f0da27f |
18
README.md
18
README.md
@@ -59,7 +59,6 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* Torlock
|
||||
* Torrent Downloads
|
||||
* Torrent9
|
||||
* TorrentKim
|
||||
* Torrentz2
|
||||
* World Wide Torrents
|
||||
* YTS.ag
|
||||
@@ -111,6 +110,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* bB
|
||||
* BeyondHD
|
||||
* BIGTorrent
|
||||
* BigTower
|
||||
* Bit-City Reloaded
|
||||
* BIT-HDTV
|
||||
* Bithorlo
|
||||
@@ -228,6 +228,8 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* Racing4Everyone (R4E)
|
||||
* Redacted (PassTheHeadphones)
|
||||
* Red Star Torrent
|
||||
* Redtopia (RED)
|
||||
* RetroFlix
|
||||
* RevolutionTT
|
||||
* RGU
|
||||
* RoDVD
|
||||
@@ -386,11 +388,10 @@ Example config for nginx:
|
||||
```
|
||||
location /jackett {
|
||||
proxy_pass http://127.0.0.1:9117;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Host $http_host;
|
||||
proxy_redirect off;
|
||||
}
|
||||
```
|
||||
@@ -431,7 +432,8 @@ All contributions are welcome just send a pull request. Jackett's framework all
|
||||
* Install the .NET Core [SDK](https://www.microsoft.com/net/download/windows)
|
||||
* Open the Jackett solution in Visual Studio 2017 (version 15.7 or above)
|
||||
* Right click on the Jackett solution and click 'Rebuild Solution' to restore nuget packages
|
||||
* Select Jackett.Console as startup project
|
||||
* Select Jackett.Server as startup project
|
||||
* In the drop down menu of the run button select "Jackett.Server" instead of "IIS Express"
|
||||
* Build/Start the project
|
||||
|
||||
### OSX
|
||||
@@ -445,9 +447,9 @@ NOTE: msbuild is included in the mono release.
|
||||
|
||||
NOTE: if you get the error "NU1102: Unable to find package Microsoft.AspNetCore with version (>= 2.1.2)" while restoring packages, you'll need to install it manually.https://www.microsoft.com/net/download/thank-you/dotnet-sdk-2.1.302-macos-x64-installer then delete the entire project directory and restart from a new clone
|
||||
|
||||
* msbuild Jackett.Console/Jackett.Console.csproj /t:Build /p:Configuration=Debug
|
||||
* msbuild Jackett.Server/Jackett.Server.csproj /t:Build /p:Configuration=Debug
|
||||
* curl -sS https://curl.haxx.se/ca/cacert.pem | cert-sync --user /dev/stdin
|
||||
* mono Jackett.Console/bin/Debug/JackettConsole.exe
|
||||
* mono Jackett.Server/bin/Debug/JackettServer.exe
|
||||
|
||||
|
||||
### Linux
|
||||
@@ -457,8 +459,8 @@ sudo apt install mono-complete nuget msbuild # install build tools (debian/ubunt
|
||||
git clone https://github.com/Jackett/Jackett.git
|
||||
cd Jackett/src
|
||||
nuget restore Jackett.sln # prepare dependencies
|
||||
msbuild Jackett.Console/Jackett.Console.csproj /t:Build /p:Configuration=Debug # compile
|
||||
mono Jackett.Console/bin/Debug/JackettConsole.exe # run jackett
|
||||
msbuild Jackett.Server/Jackett.Server.csproj /t:Build /p:Configuration=Debug # compile
|
||||
mono Jackett.Server/bin/Debug/JackettServer.exe # run jackett
|
||||
```
|
||||
|
||||
## Screenshots
|
||||
|
161
src/Jackett.Common/Definitions/bigtower.yml
Normal file
161
src/Jackett.Common/Definitions/bigtower.yml
Normal file
@@ -0,0 +1,161 @@
|
||||
---
|
||||
site: bigtower
|
||||
name: BigTower
|
||||
description: "Big Tower is an ITALIAN Private site for TV / MOVIES / GENERAL"
|
||||
language: it-it
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://bigtower.info/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
|
||||
# Movies
|
||||
- {id: 91, cat: Movies/HD, desc: "DSS"}
|
||||
- {id: 92, cat: Movies/HD, desc: "DSS 3D"}
|
||||
- {id: 14, cat: Movies, desc: "Screener"}
|
||||
- {id: 15, cat: Movies/SD, desc: "DVDRip"}
|
||||
- {id: 16, cat: Movies/HD, desc: "BDRip"}
|
||||
- {id: 17, cat: Movies/HD, desc: "HD 720p"}
|
||||
- {id: 18, cat: Movies/HD, desc: "HD 1080p"}
|
||||
- {id: 19, cat: Movies/HD, desc: "HD 3D"}
|
||||
- {id: 83, cat: Movies/HD, desc: "4K (Ultra HD)"}
|
||||
- {id: 89, cat: Movies/DVD, desc: "DVD 5"}
|
||||
- {id: 90, cat: Movies/DVD, desc: "DVD 9"}
|
||||
- {id: 37, cat: Movies, desc: "MP4"}
|
||||
- {id: 61, cat: TV, desc: "TV Show"}
|
||||
- {id: 78, cat: TV, desc: "Serie TV"}
|
||||
- {id: 96, cat: TV/HD, desc: "Serie TV 720p"}
|
||||
- {id: 97, cat: TV/HD, desc: "Serie TV 1080p"}
|
||||
- {id: 98, cat: TV, desc: "Serie TV MP4"}
|
||||
- {id: 24, cat: TV/Anime, desc: "Cartoni"}
|
||||
- {id: 66, cat: TV/Anime, desc: "Anime"}
|
||||
- {id: 71, cat: TV, desc: "SUB iTA"}
|
||||
- {id: 75, cat: TV/Documentary, desc: "Documentari"}
|
||||
- {id: 72, cat: TV/Sport, desc: "Sport"}
|
||||
|
||||
# GAMES
|
||||
- {id: 28, cat: PC/Games, desc: "PC Games"}
|
||||
- {id: 63, cat: Console/Xbox 360, desc: "XBOX 360"}
|
||||
- {id: 64, cat: Console/PS3, desc: "PS3"}
|
||||
- {id: 33, cat: Console/Wii, desc: "WII"}
|
||||
- {id: 76, cat: Console/Other, desc: "PS2"}
|
||||
- {id: 81, cat: Console/Xbox One, desc: "XBOX ONE"}
|
||||
- {id: 84, cat: Console/PS4, desc: "PS4"}
|
||||
|
||||
# MUSIC
|
||||
- {id: 35, cat: Audio, desc: "MP3"}
|
||||
- {id: 67, cat: Audio, desc: "FLAC"}
|
||||
|
||||
# SOFTWARE
|
||||
- {id: 52, cat: PC/ISO, desc: "Windows"}
|
||||
- {id: 54, cat: PC/ISO, desc: "Mac"}
|
||||
- {id: 69, cat: PC/ISO, desc: "Linux"}
|
||||
|
||||
# PHONE
|
||||
- {id: 40, cat: PC/Phone-IOS, desc: "Android"}
|
||||
- {id: 41, cat: PC/Phone-Android, desc: "Iphone"}
|
||||
|
||||
# OTHER
|
||||
- {id: 44, cat: Other, desc: "Varie"}
|
||||
- {id: 82, cat: Other, desc: "Music Video"}
|
||||
- {id: 86, cat: Other, desc: "Navigatori"}
|
||||
- {id: 95, cat: Other, desc: "Immagini"}
|
||||
- {id: 99, cat: Other, desc: "AudioLibri"}
|
||||
|
||||
# EBOOK
|
||||
- {id: 46, cat: Books, desc: "Ebook"}
|
||||
- {id: 73, cat: Books/Comics, desc: "Fumetti"}
|
||||
- {id: 74, cat: Books/Comics, desc: "Manga"}
|
||||
- {id: 87, cat: Books, desc: "Giornali"}
|
||||
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
login:
|
||||
path: index.php?page=login
|
||||
method: post
|
||||
inputs:
|
||||
uid: "{{ .Config.username }}"
|
||||
pwd: "{{ .Config.password }}"
|
||||
error:
|
||||
- selector: span:contains("Nome Utente non corretto")
|
||||
test:
|
||||
path: index.php
|
||||
selector: a[href="logout.php"]
|
||||
|
||||
search:
|
||||
paths:
|
||||
- path: index.php
|
||||
inputs:
|
||||
search: "{{ .Keywords }}"
|
||||
page: "torrents"
|
||||
category: "{{range .Categories}}{{.}};{{end}}"
|
||||
options: "0"
|
||||
active: "0"
|
||||
rows:
|
||||
selector: table > tbody > tr > td > table.lista > tbody > tr:has(a[href^="index.php?page=torrent-details&id="])
|
||||
fields:
|
||||
download:
|
||||
selector: a[href^="index.php?page=torrent-details&id="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["index.php?page=torrent-details&id=", "download.php?id="]
|
||||
title:
|
||||
selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
|
||||
banner:
|
||||
selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
|
||||
attribute: onmouseover
|
||||
filters:
|
||||
- name: regexp
|
||||
args: "src=(.*?) "
|
||||
category:
|
||||
selector: a[href^="index.php?page=torrents&category="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: category
|
||||
details:
|
||||
selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
|
||||
attribute: href
|
||||
size:
|
||||
selector: td:nth-last-child(2)
|
||||
date:
|
||||
selector: td:nth-last-child(7)
|
||||
filters:
|
||||
- name: append
|
||||
args: " +01:00"
|
||||
- name: dateparse
|
||||
args: "02/01/2006 -07:00"
|
||||
grabs:
|
||||
selector: td:nth-last-child(4)
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["---", "0"]
|
||||
seeders:
|
||||
selector: td:nth-last-child(6)
|
||||
leechers:
|
||||
selector: td:nth-last-child(5)
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
img[alt="Gold 100% Free"]: "0"
|
||||
img[alt="Silver 50% Free"]: "0.5"
|
||||
img[alt="Bronze 25% Free"]: "0.75"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
img[alt="2x Upload Multiplier"]: "2"
|
||||
img[alt="3x Upload Multiplier"]: "3"
|
||||
img[alt="4x Upload Multiplier"]: "4"
|
||||
img[alt="5x Upload Multiplier"]: "5"
|
||||
img[alt="6x Upload Multiplier"]: "6"
|
||||
img[alt="7x Upload Multiplier"]: "7"
|
||||
img[alt="8x Upload Multiplier"]: "8"
|
||||
img[alt="9x Upload Multiplier"]: "9"
|
||||
img[alt="10x Upload Multiplier"]: "10"
|
||||
"*": "1"
|
@@ -69,9 +69,18 @@
|
||||
filters:
|
||||
- name: andmatch
|
||||
fields:
|
||||
# download button can be disbled in the profile, use details link instead
|
||||
# download:
|
||||
# selector: a[href^="download.php/"]
|
||||
# attribute: href
|
||||
download:
|
||||
selector: a[href^="download.php/"]
|
||||
selector: a[href^="details.php?id="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["details.php?id=", "download.php/"]
|
||||
- name: append
|
||||
args: "/invalid.torrent"
|
||||
title:
|
||||
selector: a[href^="details.php?id="]
|
||||
title:
|
||||
|
@@ -53,6 +53,10 @@
|
||||
selector: .sbar span:nth-of-type(5) b
|
||||
grabs:
|
||||
selector: .sbar span:nth-of-type(6) b
|
||||
seeders:
|
||||
text: "999"
|
||||
leechers:
|
||||
text: "999"
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
|
@@ -63,9 +63,9 @@
|
||||
grabs:
|
||||
selector: div[class$="info"] span:nth-of-type(4)
|
||||
seeders:
|
||||
text: "999"
|
||||
selector: div[class$="info"] span:nth-of-type(4)
|
||||
leechers:
|
||||
text: "999"
|
||||
selector: div[class$="info"] span:nth-of-type(4)
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
|
@@ -6,11 +6,13 @@
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://www.gktorrent.org/
|
||||
- http://ww2.gktorrent.com/
|
||||
legacylinks:
|
||||
- https://www.gktorrent.org/
|
||||
- http://www.gktorrent.net/
|
||||
- https://www.gktorrent.com/ # they're forcing http
|
||||
- http://www.gktorrent.com/
|
||||
- http://ww1.gktorrent.com/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
|
@@ -1,66 +0,0 @@
|
||||
---
|
||||
site: horriblesubs
|
||||
name: Horrible Subs
|
||||
description: "Anime Sub Group - \"So bad yet so good\""
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://horriblesubs.info/
|
||||
legacylinks:
|
||||
- https://horriblesubs.info/
|
||||
|
||||
caps:
|
||||
categories:
|
||||
1: TV/Anime # Anime
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
settings:
|
||||
- name: prepend-horriblesubs
|
||||
type: checkbox
|
||||
label: Prepend [Horriblesubs] to torrent title
|
||||
|
||||
search:
|
||||
paths:
|
||||
- path: "lib/{{if .Query.Keywords }}search.php{{else}}latest.php{{end}}"
|
||||
inputs:
|
||||
value: "{{ .Query.Keywords }}"
|
||||
rows:
|
||||
selector: "div.release-links"
|
||||
dateheaders:
|
||||
selector: table.release-info
|
||||
filters:
|
||||
- name: split
|
||||
args: [" ", 0 ]
|
||||
- name: replace
|
||||
args: ["(", ""]
|
||||
- name: replace
|
||||
args: [")", ""]
|
||||
- name: replace
|
||||
args: ["/", "-"]
|
||||
- name: dateparse
|
||||
args: "01-02-06"
|
||||
- name: dateparse
|
||||
args: "01-02"
|
||||
fields:
|
||||
category:
|
||||
text: "1"
|
||||
title:
|
||||
selector: table.release-table > tbody > tr > td.dl-label
|
||||
filters:
|
||||
- name: prepend
|
||||
args: "{{if .Config.prepend-horriblesubs}}[Horriblesubs] {{else}}{{end}}"
|
||||
details:
|
||||
attribute: class
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["release-links", ""]
|
||||
- name: re_replace
|
||||
args: [" ?(\\S+?)-((?:s\\d-)?(?:\\d+v?\\d?-){0,2}\\d+p)", "http://horriblesubs.info/shows/$1#$2"]
|
||||
download:
|
||||
selector: table.release-table > tbody > tr > td.hs-magnet-link > span > a
|
||||
attribute: href
|
||||
size:
|
||||
text: "500 MB"
|
@@ -10,6 +10,7 @@
|
||||
certificates:
|
||||
- aa7c40aa360a1cec8a9687312fd50402b912e618 # incomplete CA chain
|
||||
- 83174ec1f92fa13cdef9d51888ea1dfba2166e17 # incomplete CA chain
|
||||
- c414bf4ad6c69841693c147849f4c314aa200bdf # incomplete CA chain
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
|
89
src/Jackett.Common/Definitions/redtopia.yml
Normal file
89
src/Jackett.Common/Definitions/redtopia.yml
Normal file
@@ -0,0 +1,89 @@
|
||||
---
|
||||
site: redtopia
|
||||
name: Redtopia
|
||||
description: "Tracker Music/Podcasts/Audiobooks"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://redtopia.xyz/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 1, cat: Audio, desc: "Studio Album"}
|
||||
- {id: 2, cat: Audio, desc: "Studio Single"}
|
||||
- {id: 3, cat: Audio, desc: "Studio Collection"}
|
||||
- {id: 4, cat: Audio, desc: "Indie Album"}
|
||||
- {id: 5, cat: Audio, desc: "Indie Single"}
|
||||
- {id: 6, cat: Audio, desc: "Indie Collection"}
|
||||
- {id: 7, cat: Audio, desc: "Live Album"}
|
||||
- {id: 8, cat: Audio, desc: "OST"}
|
||||
- {id: 9, cat: Audio, desc: "Podcast"}
|
||||
- {id: 10, cat: Audio, desc: "Audio Book"}
|
||||
- {id: 11, cat: Audio, desc: "Audio Drama"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
music-search: [q]
|
||||
|
||||
login:
|
||||
path: /login
|
||||
method: form
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
error:
|
||||
- selector: table.main:contains("Login Failed!")
|
||||
test:
|
||||
path: /torrents
|
||||
|
||||
search:
|
||||
paths:
|
||||
- path: /filterTorrents
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}categories[]={{.}}&{{end}}"
|
||||
search: "{{ .Keywords }}"
|
||||
uploader: ""
|
||||
sorting: created_at
|
||||
direction: desc
|
||||
qty: 100
|
||||
rows:
|
||||
selector: table > tbody > tr
|
||||
fields:
|
||||
category:
|
||||
selector: a[href*="/categories/"]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: regexp
|
||||
args: "/categories/.*?\\.(\\d+)"
|
||||
title:
|
||||
selector: a.view-torrent
|
||||
download:
|
||||
selector: a[href*="/download/"]
|
||||
attribute: href
|
||||
details:
|
||||
selector: a.view-torrent
|
||||
attribute: href
|
||||
size:
|
||||
selector: td:nth-child(4)
|
||||
seeders:
|
||||
selector: td:nth-child(6)
|
||||
leechers:
|
||||
selector: td:nth-child(7)
|
||||
grabs:
|
||||
selector: td:nth-child(5)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: ([\d\.]+)
|
||||
date:
|
||||
selector: time
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"i[data-original-title=\"100% Free\"]": "0"
|
||||
"i[data-original-title=\"Global FreeLeech\"]": "0"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"i[data-original-title=\"Double Upload\"]": "2" # global flag
|
||||
"i[data-original-title=\"Double upload\"]": "2" # torrent specific flag
|
||||
"*": "1"
|
104
src/Jackett.Common/Definitions/retroflix.yml
Normal file
104
src/Jackett.Common/Definitions/retroflix.yml
Normal file
@@ -0,0 +1,104 @@
|
||||
---
|
||||
site: retroflix
|
||||
name: RetroFlix
|
||||
description: "Private Torrent Tracker for Classic Movies / TV / General Releases."
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://retroflix.club/
|
||||
legacylinks:
|
||||
- https://retroflix.net/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 401, cat: Movies, desc: "Movies"}
|
||||
- {id: 404, cat: TV/Documentary, desc: "Documentaries"}
|
||||
- {id: 405, cat: TV/Anime, desc: "Animations"}
|
||||
- {id: 402, cat: TV, desc: "TV Series"}
|
||||
- {id: 403, cat: TV, desc: "TV Shows"}
|
||||
- {id: 406, cat: Audio/Video, desc: "Music Videos"}
|
||||
- {id: 407, cat: TV/Sport, desc: "Sports"}
|
||||
- {id: 409, cat: Other, desc: "Misc"}
|
||||
- {id: 408, cat: Audio, desc: "HQ Audio"}
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q, imdbid]
|
||||
|
||||
settings:
|
||||
- name: cookie
|
||||
type: text
|
||||
label: Cookie
|
||||
|
||||
login:
|
||||
method: cookie
|
||||
inputs:
|
||||
cookie: "{{ .Config.cookie }}"
|
||||
test:
|
||||
path: torrents.php
|
||||
|
||||
search:
|
||||
paths:
|
||||
- path: torrents.php
|
||||
method: get
|
||||
inputs:
|
||||
search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}"
|
||||
incldead: 1
|
||||
search_area: "{{ if .Query.IMDBID }}4{{else}}0{{end}}"
|
||||
search_mode: 0
|
||||
rows:
|
||||
selector: table.torrents > tbody > tr:has(table.torrentname)
|
||||
fields:
|
||||
release_year:
|
||||
selector: a[href^="/torrents.php?processing="]
|
||||
quality:
|
||||
selector: a[href^="/torrents.php?standard="]
|
||||
title:
|
||||
selector: a[title][href^="details.php?id="]
|
||||
attribute: title
|
||||
filters:
|
||||
- name: append
|
||||
args: " {{ .Result.release_year }}"
|
||||
- name: append
|
||||
args: " {{ .Result.quality }}"
|
||||
category:
|
||||
selector: a[href^="?cat="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
details:
|
||||
selector: a[href^="details.php?id="]
|
||||
attribute: href
|
||||
download:
|
||||
selector: a[href^="download.php?id="]
|
||||
attribute: href
|
||||
size:
|
||||
selector: td:nth-child(5)
|
||||
grabs:
|
||||
selector: td:nth-child(8)
|
||||
seeders:
|
||||
selector: td:nth-child(6)
|
||||
leechers:
|
||||
selector: td:nth-child(7)
|
||||
date:
|
||||
selector: td:nth-child(4) > span[title]
|
||||
attribute: title
|
||||
filters:
|
||||
- name: dateparse
|
||||
args: "02-01-2006 15:04:05"
|
||||
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"
|
@@ -6,7 +6,7 @@
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://ww2.torrent9.blue/
|
||||
- https://www.torrent9.ph/
|
||||
legacylinks:
|
||||
- http://www.torrent9.ec/
|
||||
- http://www.torrent9.red/
|
||||
@@ -16,6 +16,8 @@
|
||||
- http://www.torrent9.pe/
|
||||
- http://www.torrent9.blue/
|
||||
- https://www.torrent9.blue/
|
||||
- https://ww2.torrent9.blue/
|
||||
- https://www.torrent9.rip/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
|
@@ -53,7 +53,7 @@
|
||||
q: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}"
|
||||
incldead: 1
|
||||
rows:
|
||||
selector: table#torrentTable > tbody > tr:has(td.torrentNameInfo)
|
||||
selector: table#torrentsTable > tbody > tr:has(td.torrentNameInfo)
|
||||
fields:
|
||||
download:
|
||||
selector: a[href^="/download.php/"]
|
||||
|
@@ -1,66 +0,0 @@
|
||||
---
|
||||
site: torrentkim
|
||||
name: TorrentKim
|
||||
description: "TorrentKim is a free Korean tracker of pretty much anything Korean."
|
||||
language: ko-KR
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://torrentkim.pro/
|
||||
legacylinks:
|
||||
- https://torrentkim12.com/
|
||||
- https://torrentkim10.net/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: "torrent_variety", cat: TV, desc: "TV - Variety shows"}
|
||||
- {id: "torrent_tv", cat: TV, desc: "TV - Dramas"}
|
||||
- {id: "torrent_mid", cat: TV/FOREIGN, desc: "TV - American Series"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q]
|
||||
movie-search: [q]
|
||||
|
||||
settings: []
|
||||
|
||||
search:
|
||||
paths:
|
||||
- path: "{{ if .Keywords }}/bbs/s-1-{{ .Keywords }}{{else}}/bbs/s-1-미운우리새끼{{end}}"
|
||||
rows:
|
||||
selector: "table.board_list > tbody > tr.bg1:nth-child(n+3)"
|
||||
fields:
|
||||
magnet:
|
||||
selector: td:nth-child(1) a[href^="javascript:"]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["javascript:Mag_dn('", ""]
|
||||
- name: replace
|
||||
args: ["')", ""]
|
||||
- name: prepend
|
||||
args: "magnet:?xt=urn:btih:"
|
||||
seeders:
|
||||
selector: "td:nth-child(2) font:nth-child(2)"
|
||||
leechers:
|
||||
selector: "td:nth-child(2) font:nth-child(1)"
|
||||
category:
|
||||
selector: td:nth-child(3) a[href^="/bbs/bc.php?bo_table="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: bo_table
|
||||
title:
|
||||
selector: td:nth-child(3) a:last-of-type
|
||||
details:
|
||||
selector: td:nth-child(3) a:last-of-type
|
||||
attribute: href
|
||||
date:
|
||||
selector: td:nth-child(3) a:last-of-type
|
||||
filters:
|
||||
- name: split
|
||||
args: ['.', 2]
|
||||
- name: dateparse
|
||||
args: "060102"
|
||||
size:
|
||||
selector: td:nth-child(5)
|
@@ -69,12 +69,11 @@
|
||||
paths:
|
||||
- path: "{{if .Config.filter-verified }}verified{{else}}searchA{{end}}"
|
||||
inputs:
|
||||
f: "{{ .Query.Keywords }}"
|
||||
f: "{{if .Keywords }}title: {{else}}{{end}}{{ .Keywords }}"
|
||||
safe: "{{if .Config.filter-safe }}1{{else}}0{{end}}"
|
||||
rows:
|
||||
selector: "html body #wrap .results dl:has(a)"
|
||||
filters:
|
||||
- name: andmatch
|
||||
# andmatch filter removed, see #3737
|
||||
fields:
|
||||
title:
|
||||
selector: dt a
|
||||
@@ -114,10 +113,9 @@
|
||||
selector: dt
|
||||
remove: a
|
||||
filters:
|
||||
- name: re_replace
|
||||
args: ["[^a-zA-Z\\s]+", ""]
|
||||
- name: trim
|
||||
args: "»"
|
||||
- name: trim
|
||||
args: " "
|
||||
date:
|
||||
selector: dd span:nth-child(2)
|
||||
attribute: title
|
||||
|
@@ -67,6 +67,8 @@
|
||||
selector: div.group_info
|
||||
remove: span, div.tags
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["\t\t\t\t", " "]
|
||||
- name: replace
|
||||
args: [" / Free", ""]
|
||||
- name: replace
|
||||
|
@@ -6,7 +6,7 @@
|
||||
type: semi-private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://ww4.yggtorrent.is/
|
||||
- https://www.yggtorrent.is/
|
||||
legacylinks:
|
||||
- https://yggtorrent.is/
|
||||
- https://yggtorrent.com/
|
||||
@@ -14,11 +14,12 @@
|
||||
- https://ww1.yggtorrent.is/
|
||||
- https://ww2.yggtorrent.is/
|
||||
- https://ww3.yggtorrent.is/
|
||||
- https://ww4.yggtorrent.is/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 2145, cat: TV, desc: "Film/Vidéo"}
|
||||
- {id: 2178, cat: TV/Anime, desc: "Film/Vidéo : Animation"}
|
||||
- {id: 2178, cat: Movies, desc: "Film/Vidéo : Animation"} # changed to movies, see #3553
|
||||
- {id: 2179, cat: TV/Anime, desc: "Film/Vidéo : Animation Série"}
|
||||
- {id: 2180, cat: TV, desc: "Film/Vidéo : Concert"}
|
||||
- {id: 2181, cat: TV, desc: "Film/Vidéo : Documentaire"}
|
||||
@@ -128,8 +129,8 @@
|
||||
|
||||
search:
|
||||
paths:
|
||||
- path: "/engine/search?category={{ .Config.category }}&name={{ .Keywords }}&description=&file=&uploader=&sub_category=&do=search"
|
||||
- path: "/engine/search?category={{ .Config.category }}&name={{ .Keywords }}&description=&file=&uploader=&sub_category=&do=search&page=50"
|
||||
- path: "/engine/search?category={{ .Config.category }}&name={{ .Keywords }}&description=&file=&uploader=&sub_category=&do=search&order=desc&sort=publish_date"
|
||||
- path: "/engine/search?category={{ .Config.category }}&name={{ .Keywords }}&description=&file=&uploader=&sub_category=&do=search&order=desc&sort=publish_date&page=50"
|
||||
|
||||
rows:
|
||||
selector: "table.table > tbody > tr"
|
||||
|
@@ -22,7 +22,7 @@
|
||||
path: /login
|
||||
method: form
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
username_email: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
remember: "on"
|
||||
error:
|
||||
@@ -54,13 +54,13 @@
|
||||
- name: split
|
||||
args: ["|", 0]
|
||||
size:
|
||||
selector: td:nth-child(5)
|
||||
selector: td:nth-child(4)
|
||||
seeders:
|
||||
selector: td:nth-child(6)
|
||||
selector: td:nth-child(5)
|
||||
leechers:
|
||||
selector: td:nth-child(7)
|
||||
selector: td:nth-child(6)
|
||||
grabs:
|
||||
selector: td:nth-child(8)
|
||||
selector: td:nth-child(7)
|
||||
date:
|
||||
selector: td:nth-child(3)
|
||||
filters:
|
||||
|
@@ -63,7 +63,7 @@ namespace Jackett.Common.Indexers.Abstract
|
||||
|
||||
if (!string.IsNullOrEmpty(query.ImdbID))
|
||||
{
|
||||
queryCollection.Add("imdbid", "browse");
|
||||
queryCollection.Add("imdbid", query.ImdbID);
|
||||
}
|
||||
if (searchString != null)
|
||||
{
|
||||
|
@@ -575,6 +575,11 @@ namespace Jackett.Common.Indexers
|
||||
{
|
||||
throw new Exception("Request to " + response.Request.Url + " failed (Error " + response.Status + ") - The tracker seems to be down.");
|
||||
}
|
||||
|
||||
if (response.Status == System.Net.HttpStatusCode.Forbidden && response.Content.Contains("<span data-translate=\"complete_sec_check\">Please complete the security check to access</span>"))
|
||||
{
|
||||
throw new Exception("Request to " + response.Request.Url + " failed (Error " + response.Status + ") - The page is protected by an Cloudflare reCaptcha. The page is in aggressive DDoS mitigation mode or your IP might be blacklisted (e.g. in case of shared VPN IPs). There's no easy way of making it usable with Jackett.");
|
||||
}
|
||||
}
|
||||
|
||||
protected async Task FollowIfRedirect(WebClientStringResult response, string referrer = null, string overrideRedirectUrl = null, string overrideCookies = null, bool accumulateCookies = false)
|
||||
|
@@ -164,7 +164,7 @@ namespace Jackett.Common.Indexers
|
||||
var grabs = qRow.Find("td:nth-child(9) > a").Get(0).FirstChild.ToString();
|
||||
release.Grabs = ParseUtil.CoerceInt(grabs);
|
||||
|
||||
release.DownloadVolumeFactor = 0; // ratioless
|
||||
release.DownloadVolumeFactor = 1;
|
||||
release.UploadVolumeFactor = 1;
|
||||
|
||||
releases.Add(release);
|
||||
|
246
src/Jackett.Common/Indexers/HorribleSubs.cs
Normal file
246
src/Jackett.Common/Indexers/HorribleSubs.cs
Normal file
@@ -0,0 +1,246 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Jackett.Common.Models;
|
||||
using Jackett.Common.Models.IndexerConfig;
|
||||
using Jackett.Common.Services.Interfaces;
|
||||
using Jackett.Common.Utils;
|
||||
using Jackett.Common.Utils.Clients;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
using System.Text.RegularExpressions;
|
||||
using AngleSharp.Parser.Html;
|
||||
|
||||
namespace Jackett.Common.Indexers
|
||||
{
|
||||
class HorribleSubs : BaseWebIndexer
|
||||
{
|
||||
private string ApiEndpoint { get { return SiteLink + "api.php"; } }
|
||||
|
||||
public HorribleSubs(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps)
|
||||
: base(name: "Horrible Subs",
|
||||
description: "HorribleSubs – So bad yet so good",
|
||||
link: "https://horriblesubs.info/",
|
||||
caps: new TorznabCapabilities(),
|
||||
configService: configService,
|
||||
client: wc,
|
||||
logger: l,
|
||||
p: ps,
|
||||
configData: new ConfigurationData())
|
||||
{
|
||||
Encoding = Encoding.UTF8;
|
||||
Language = "en-us";
|
||||
Type = "public";
|
||||
}
|
||||
|
||||
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
var releases = await PerformQuery(new TorznabQuery());
|
||||
|
||||
await ConfigureIfOK(string.Empty, releases.Count() > 0, () =>
|
||||
{
|
||||
throw new Exception("Could not find releases from this URL");
|
||||
});
|
||||
|
||||
return IndexerConfigurationStatus.Completed;
|
||||
}
|
||||
|
||||
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
return await PerformQuery(query, 0);
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<ReleaseInfo>> PerformLatestQuery(TorznabQuery query, int attempts)
|
||||
{
|
||||
var ResultParser = new HtmlParser();
|
||||
var releases = new List<ReleaseInfo>();
|
||||
var searchString = query.GetQueryString();
|
||||
var queryCollection = new NameValueCollection();
|
||||
|
||||
queryCollection.Add("method", "getlatest");
|
||||
|
||||
var searchUrl = ApiEndpoint + "?" + queryCollection.GetQueryString();
|
||||
var response = await RequestStringWithCookiesAndRetry(searchUrl, string.Empty);
|
||||
|
||||
try
|
||||
{
|
||||
if (response.Content.Contains("Nothing was found"))
|
||||
{
|
||||
return releases.ToArray();
|
||||
}
|
||||
|
||||
var dom = ResultParser.Parse(response.Content);
|
||||
var latestresults = dom.QuerySelectorAll("ul > li > a");
|
||||
foreach (var row in latestresults)
|
||||
{
|
||||
var href = SiteLink + row.Attributes["href"].Value.Substring(1);
|
||||
var showrels = await GetRelease(href);
|
||||
releases.AddRange(showrels);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(response.Content, ex);
|
||||
}
|
||||
|
||||
return releases;
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<ReleaseInfo>> GetRelease(string ResultURL)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
var ResultParser = new HtmlParser();
|
||||
try
|
||||
{
|
||||
var episodeno = ResultURL.Substring(ResultURL.LastIndexOf("#") + 1); // = 71
|
||||
ResultURL = ResultURL.Replace("#" + episodeno, ""); // = https://horriblesubs.info/shows/boruto-naruto-next-generations
|
||||
|
||||
var showPageResponse = await RequestStringWithCookiesAndRetry(ResultURL, string.Empty);
|
||||
await FollowIfRedirect(showPageResponse);
|
||||
|
||||
Match match = Regex.Match(showPageResponse.Content, "(var hs_showid = )([0-9]*)(;)", RegexOptions.IgnoreCase);
|
||||
if (match.Success == false)
|
||||
{
|
||||
return releases;
|
||||
}
|
||||
|
||||
int ShowID = int.Parse(match.Groups[2].Value);
|
||||
|
||||
string showAPIURL = ApiEndpoint + "?method=getshows&type=show&showid=" + ShowID; //https://horriblesubs.info/api.php?method=getshows&type=show&showid=869
|
||||
var showAPIResponse = await RequestStringWithCookiesAndRetry(showAPIURL, string.Empty);
|
||||
|
||||
|
||||
var showAPIdom = ResultParser.Parse(showAPIResponse.Content);
|
||||
var releaserows = showAPIdom.QuerySelectorAll("div.rls-info-container");
|
||||
|
||||
foreach (var releaserow in releaserows)
|
||||
{
|
||||
string dateStr = releaserow.QuerySelector(".rls-date").TextContent.Trim();
|
||||
string title = releaserow.FirstChild.TextContent;
|
||||
title = title.Replace("SD720p1080p", "");
|
||||
title = title.Replace(dateStr, "");
|
||||
|
||||
if (title.Contains(episodeno) == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
DateTime releasedate;
|
||||
if (dateStr == "Today")
|
||||
{
|
||||
releasedate = DateTime.Today;
|
||||
}
|
||||
else if (dateStr == "Yesterday")
|
||||
{
|
||||
releasedate = DateTime.Today.AddDays(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
releasedate = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "MM/dd/yy", CultureInfo.InvariantCulture), DateTimeKind.Utc).ToLocalTime();
|
||||
}
|
||||
|
||||
var p480 = releaserow.QuerySelector(".link-480p");
|
||||
|
||||
if (p480 != null)
|
||||
{
|
||||
var release = new ReleaseInfo();
|
||||
release.Title = string.Format("{0} [480p]", title);
|
||||
release.PublishDate = releasedate;
|
||||
release.Link = new Uri(p480.QuerySelector(".hs-torrent-link > a").GetAttribute("href"));
|
||||
release.MagnetUri = new Uri(p480.QuerySelector(".hs-magnet-link > a").GetAttribute("href"));
|
||||
release.Files = 1;
|
||||
releases.Add(release);
|
||||
}
|
||||
|
||||
var p720 = releaserow.QuerySelector(".link-720p");
|
||||
|
||||
if (p720 != null)
|
||||
{
|
||||
var release = new ReleaseInfo();
|
||||
release.Title = string.Format("{0} [720p]", title);
|
||||
release.PublishDate = releasedate;
|
||||
release.Link = new Uri(p720.QuerySelector(".hs-torrent-link > a").GetAttribute("href"));
|
||||
release.MagnetUri = new Uri(p720.QuerySelector(".hs-magnet-link > a").GetAttribute("href"));
|
||||
release.Files = 1;
|
||||
releases.Add(release);
|
||||
}
|
||||
|
||||
var p1080 = releaserow.QuerySelector(".link-1080p");
|
||||
|
||||
if (p1080 != null)
|
||||
{
|
||||
var release = new ReleaseInfo();
|
||||
release.Title = string.Format("{0} [1080p]", title);
|
||||
release.PublishDate = releasedate;
|
||||
release.Link = new Uri(p1080.QuerySelector(".hs-torrent-link > a").GetAttribute("href"));
|
||||
release.MagnetUri = new Uri(p1080.QuerySelector(".hs-magnet-link > a").GetAttribute("href"));
|
||||
release.Files = 1;
|
||||
releases.Add(release);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError("", ex);
|
||||
}
|
||||
return releases;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query, int attempts)
|
||||
{
|
||||
var ResultParser = new HtmlParser();
|
||||
var releases = new List<ReleaseInfo>();
|
||||
var searchString = query.GetQueryString();
|
||||
var queryCollection = new NameValueCollection();
|
||||
|
||||
|
||||
if (string.IsNullOrWhiteSpace(searchString))
|
||||
{
|
||||
return await PerformLatestQuery(query, attempts);
|
||||
}
|
||||
else
|
||||
{
|
||||
queryCollection.Add("method", "search");
|
||||
|
||||
searchString = searchString.Replace("'", ""); // ignore ' (e.g. search for america's Next Top Model)
|
||||
queryCollection.Add("value", searchString);
|
||||
}
|
||||
|
||||
var searchUrl = ApiEndpoint + "?" + queryCollection.GetQueryString();
|
||||
var response = await RequestStringWithCookiesAndRetry(searchUrl, string.Empty);
|
||||
|
||||
try
|
||||
{
|
||||
if (response.Content.Contains("Nothing was found"))
|
||||
{
|
||||
return releases.ToArray();
|
||||
}
|
||||
var dom = ResultParser.Parse(response.Content);
|
||||
var showlinks = dom.QuerySelectorAll("ul > li > a");
|
||||
foreach (var showlink in showlinks)
|
||||
{
|
||||
var href = SiteLink + showlink.Attributes["href"].Value.Substring(1); // = https://horriblesubs.info/shows/boruto-naruto-next-generations#71
|
||||
|
||||
var showrels = await GetRelease(href);
|
||||
releases.AddRange(showrels);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(response.Content, ex);
|
||||
}
|
||||
|
||||
return releases;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -42,30 +42,41 @@ namespace Jackett.Common.Indexers
|
||||
Language = "en-us";
|
||||
Type = "private";
|
||||
|
||||
AddCategoryMapping(32, TorznabCatType.TVAnime);
|
||||
AddCategoryMapping(31, TorznabCatType.TVOTHER);
|
||||
AddCategoryMapping(47, TorznabCatType.TVSD);
|
||||
AddCategoryMapping(8, TorznabCatType.TVHD);
|
||||
AddCategoryMapping(48, TorznabCatType.TVHD);
|
||||
AddCategoryMapping(9, TorznabCatType.TVSD);
|
||||
AddCategoryMapping(4, TorznabCatType.TVHD);
|
||||
AddCategoryMapping(6, TorznabCatType.TVSD);
|
||||
|
||||
AddCategoryMapping(22, TorznabCatType.Books);
|
||||
AddCategoryMapping(41, TorznabCatType.BooksComics);
|
||||
AddCategoryMapping(23, TorznabCatType.PC);
|
||||
|
||||
AddCategoryMapping(16, TorznabCatType.MoviesHD);
|
||||
AddCategoryMapping(17, TorznabCatType.MoviesSD);
|
||||
AddCategoryMapping(14, TorznabCatType.MoviesSD);
|
||||
AddCategoryMapping(34, TorznabCatType.MoviesForeign);
|
||||
AddCategoryMapping(18, TorznabCatType.MoviesForeign);
|
||||
AddCategoryMapping(33, TorznabCatType.MoviesForeign);
|
||||
|
||||
AddCategoryMapping(34, TorznabCatType.Audio);
|
||||
AddCategoryMapping(37, TorznabCatType.AudioLossless);
|
||||
AddCategoryMapping(35, TorznabCatType.AudioAudiobook);
|
||||
AddCategoryMapping(36, TorznabCatType.AudioMP3);
|
||||
AddCategoryMapping(3, TorznabCatType.Other, "Nuked");
|
||||
AddCategoryMapping(32, TorznabCatType.TVAnime, "Anime");
|
||||
AddCategoryMapping(23, TorznabCatType.PC, "Apps");
|
||||
AddCategoryMapping(35, TorznabCatType.AudioAudiobook, "Audiobooks");
|
||||
AddCategoryMapping(31, TorznabCatType.TV, "Childrens/Cartoons");
|
||||
AddCategoryMapping(54, TorznabCatType.TVDocumentary, "Documentary - HD");
|
||||
AddCategoryMapping(41, TorznabCatType.BooksComics, "Comics");
|
||||
AddCategoryMapping(25, TorznabCatType.PCGames, "Games");
|
||||
AddCategoryMapping(29, TorznabCatType.ConsoleXbox, "Games Xbox");
|
||||
AddCategoryMapping(27, TorznabCatType.PCGames, "Games-PC Rips");
|
||||
AddCategoryMapping(28, TorznabCatType.ConsolePS4, "Games-PSx");
|
||||
AddCategoryMapping(49, TorznabCatType.PCPhoneOther, "Mobile");
|
||||
AddCategoryMapping(59, TorznabCatType.MoviesUHD, "Movies-4k");
|
||||
AddCategoryMapping(60, TorznabCatType.MoviesForeign, "Non-English 4k Movies");
|
||||
AddCategoryMapping(16, TorznabCatType.MoviesHD, "Movies HD");
|
||||
AddCategoryMapping(18, TorznabCatType.MoviesForeign, "Movies HD Non-English");
|
||||
AddCategoryMapping(17, TorznabCatType.MoviesSD, "TS/CAM/PPV");
|
||||
AddCategoryMapping(34, TorznabCatType.MoviesForeign, "Movies Low Def Non-English");
|
||||
AddCategoryMapping(14, TorznabCatType.MoviesSD, "Movies-SD");
|
||||
AddCategoryMapping(33, TorznabCatType.MoviesForeign, "Movies SD Non-English");
|
||||
AddCategoryMapping(30, TorznabCatType.AudioOther, "Music");
|
||||
AddCategoryMapping(37, TorznabCatType.AudioLossless, "FLAC");
|
||||
AddCategoryMapping(36, TorznabCatType.AudioMP3, "MP3");
|
||||
AddCategoryMapping(39, TorznabCatType.AudioOther, "Music Other");
|
||||
AddCategoryMapping(38, TorznabCatType.AudioVideo, "Music Video");
|
||||
AddCategoryMapping(45, TorznabCatType.Other, "Other");
|
||||
AddCategoryMapping(7, TorznabCatType.TVSport, "Sports Tv");
|
||||
AddCategoryMapping(44, TorznabCatType.TVSport, "Sports Fitness-Instructional");
|
||||
AddCategoryMapping(58, TorznabCatType.TVSport, "Olympics");
|
||||
AddCategoryMapping(47, TorznabCatType.TVSD, "TV - 480p");
|
||||
AddCategoryMapping(8, TorznabCatType.TVHD, "TV - High Definition");
|
||||
AddCategoryMapping(48, TorznabCatType.TVSD, "TV - Standard Definition - x264");
|
||||
AddCategoryMapping(9, TorznabCatType.TVSD, "TV - Standard Definition - XviD");
|
||||
AddCategoryMapping(4, TorznabCatType.TVHD, "TV Season Packs - HD");
|
||||
AddCategoryMapping(6, TorznabCatType.TVSD, "TV Season Packs - SD");
|
||||
}
|
||||
|
||||
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
|
@@ -69,6 +69,8 @@ namespace Jackett.Common.Indexers
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query, int attempts)
|
||||
{
|
||||
query = query.Clone();
|
||||
|
||||
var originalSearchTerm = query.SearchTerm;
|
||||
if (query.SearchTerm == null)
|
||||
{
|
||||
|
@@ -28,16 +28,36 @@ namespace Jackett.Common.Indexers
|
||||
|
||||
class NewpctRelease : ReleaseInfo
|
||||
{
|
||||
public string SerieName;
|
||||
public ReleaseType NewpctReleaseType;
|
||||
public string SeriesName;
|
||||
public int? Season;
|
||||
public int? Episode;
|
||||
public int? EpisodeTo;
|
||||
|
||||
public NewpctRelease()
|
||||
{
|
||||
}
|
||||
|
||||
public NewpctRelease(NewpctRelease copyFrom):
|
||||
base(copyFrom)
|
||||
{
|
||||
NewpctReleaseType = copyFrom.NewpctReleaseType;
|
||||
SeriesName = copyFrom.SeriesName;
|
||||
Season = copyFrom.Season;
|
||||
Episode = copyFrom.Episode;
|
||||
EpisodeTo = copyFrom.EpisodeTo;
|
||||
}
|
||||
|
||||
public override object Clone()
|
||||
{
|
||||
return new NewpctRelease(this);
|
||||
}
|
||||
}
|
||||
|
||||
private static Uri SiteLinkUri = new Uri("http://www.tvsinpagar.com/");
|
||||
private ReleaseInfo _mostRecentRelease;
|
||||
private NewpctRelease _mostRecentRelease;
|
||||
private Regex _searchStringRegex = new Regex(@"(.+?)S0?(\d+)(E0?(\d+))?$", RegexOptions.IgnoreCase);
|
||||
private Regex _titleListRegex = new Regex(@"Serie(.+?)(Temporada(.+?)(\d+)(.+?))?Capitulos?(.+?)(\d+)((.+?)(\d+))?(.+?)-(.+?)Calidad(.*)", RegexOptions.IgnoreCase);
|
||||
private Regex _titleListRegex = new Regex(@"Serie( *Descargar)?(.+?)(Temporada(.+?)(\d+)(.+?))?Capitulos?(.+?)(\d+)((.+?)(\d+))?(.+?)-(.+?)Calidad(.*)", RegexOptions.IgnoreCase);
|
||||
private Regex _titleClassicRegex = new Regex(@"(\[[^\]]*\])?\[Cap\.(\d{1,2})(\d{2})([_-](\d{1,2})(\d{2}))?\]", RegexOptions.IgnoreCase);
|
||||
private Regex _titleClassicTvQualityRegex = new Regex(@"\[([^\]]*HDTV[^\]]*)", RegexOptions.IgnoreCase);
|
||||
|
||||
@@ -45,6 +65,9 @@ namespace Jackett.Common.Indexers
|
||||
private int _maxEpisodesListPages = 100;
|
||||
private int[] _allTvCategories = TorznabCatType.TV.SubCategories.Select(c => c.ID).ToArray();
|
||||
|
||||
private DateTime _dailyNow;
|
||||
private int _dailyResultIdx;
|
||||
|
||||
private string _dailyUrl = "/ultimas-descargas/pg/{0}";
|
||||
private string[] _seriesLetterUrls = new string[] { "/series/letter/{0}", "/series-hd/letter/{0}" };
|
||||
private string[] _seriesVOLetterUrls = new string[] { "/series-vo/letter/{0}" };
|
||||
@@ -110,6 +133,13 @@ namespace Jackett.Common.Indexers
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
|
||||
lock (cache)
|
||||
{
|
||||
CleanCache();
|
||||
}
|
||||
|
||||
_dailyNow = DateTime.Now;
|
||||
_dailyResultIdx = 0;
|
||||
bool rssMode = string.IsNullOrEmpty(query.SanitizedSearchTerm);
|
||||
|
||||
if (rssMode)
|
||||
@@ -130,7 +160,7 @@ namespace Jackett.Common.Indexers
|
||||
bool recentFound = _mostRecentRelease != null &&
|
||||
items.Any(r => r.Title == _mostRecentRelease.Title && r.Link.AbsoluteUri == _mostRecentRelease.Link.AbsoluteUri);
|
||||
if (pg == 1)
|
||||
_mostRecentRelease = (ReleaseInfo)items.First().Clone();
|
||||
_mostRecentRelease = (NewpctRelease)items.First().Clone();
|
||||
if (recentFound)
|
||||
break;
|
||||
|
||||
@@ -153,7 +183,7 @@ namespace Jackett.Common.Indexers
|
||||
|
||||
private async Task<IEnumerable<ReleaseInfo>> TvSearch(TorznabQuery query)
|
||||
{
|
||||
var newpctReleases = new List<ReleaseInfo>();
|
||||
List<ReleaseInfo> newpctReleases = null;
|
||||
|
||||
string seriesName = query.SanitizedSearchTerm;
|
||||
int? season = query.Season > 0 ? (int?)query.Season : null;
|
||||
@@ -174,22 +204,17 @@ namespace Jackett.Common.Indexers
|
||||
}
|
||||
|
||||
//Try to reuse cache
|
||||
bool cacheFound = false;
|
||||
lock (cache)
|
||||
{
|
||||
CleanCache();
|
||||
var cachedResult = cache.FirstOrDefault(i => i.Query == seriesName.ToLower());
|
||||
if (cachedResult != null && cachedResult.Results != null)
|
||||
{
|
||||
cacheFound = true;
|
||||
newpctReleases = cachedResult.Results.Where(r => (r as NewpctRelease) != null).ToList();
|
||||
if (!newpctReleases.Any() && cachedResult.Results.Any())
|
||||
cacheFound = false;
|
||||
}
|
||||
if (cachedResult != null)
|
||||
newpctReleases = cachedResult.Results.Select(r => (ReleaseInfo)r.Clone()).ToList();
|
||||
}
|
||||
|
||||
if (!cacheFound)
|
||||
if (newpctReleases == null)
|
||||
{
|
||||
newpctReleases = new List<ReleaseInfo>();
|
||||
|
||||
//Search series url
|
||||
foreach (Uri seriesListUrl in SeriesListUris(seriesName))
|
||||
{
|
||||
@@ -288,7 +313,11 @@ namespace Jackett.Common.Indexers
|
||||
foreach (var row in rows)
|
||||
{
|
||||
var anchor = row.QuerySelector("a");
|
||||
var title = anchor.TextContent.Replace("\t", "").Trim();
|
||||
var title = Regex.Replace(anchor.TextContent, @"\s+", " ").Trim();
|
||||
var title2 = Regex.Replace(anchor.GetAttribute("title"), @"\s+", " ").Trim();
|
||||
if (title2.Length >= title.Length)
|
||||
title = title2;
|
||||
|
||||
var detailsUrl = anchor.GetAttribute("href");
|
||||
|
||||
var span = row.QuerySelector("span");
|
||||
@@ -298,16 +327,17 @@ namespace Jackett.Common.Indexers
|
||||
|
||||
var div = row.QuerySelector("div");
|
||||
var language = div.ChildNodes[1].TextContent.Trim();
|
||||
_dailyResultIdx++;
|
||||
|
||||
NewpctRelease newpctRelease;
|
||||
if (releaseType == ReleaseType.TV)
|
||||
newpctRelease = GetReleaseFromData(releaseType,
|
||||
string.Format("Serie {0} - {1} Calidad [{2}]", title, language, quality),
|
||||
detailsUrl, quality, language, ReleaseInfo.GetBytes(sizeText), DateTime.Now);
|
||||
detailsUrl, quality, language, ReleaseInfo.GetBytes(sizeText), _dailyNow - TimeSpan.FromMilliseconds(_dailyResultIdx));
|
||||
else
|
||||
newpctRelease = GetReleaseFromData(releaseType,
|
||||
string.Format("{0} [{1}][{2}]", title, quality, language),
|
||||
detailsUrl, quality, language, ReleaseInfo.GetBytes(sizeText), DateTime.Now);
|
||||
detailsUrl, quality, language, ReleaseInfo.GetBytes(sizeText), _dailyNow - TimeSpan.FromMilliseconds(_dailyResultIdx));
|
||||
|
||||
releases.Add(newpctRelease);
|
||||
}
|
||||
@@ -391,6 +421,7 @@ namespace Jackett.Common.Indexers
|
||||
NewpctRelease GetReleaseFromData(ReleaseType releaseType, string title, string detailsUrl, string quality, string language, long size, DateTime publishDate)
|
||||
{
|
||||
NewpctRelease result = new NewpctRelease();
|
||||
result.NewpctReleaseType = releaseType;
|
||||
|
||||
//Sanitize
|
||||
title = title.Replace("\t", "").Replace("\x2013", "-");
|
||||
@@ -398,30 +429,30 @@ namespace Jackett.Common.Indexers
|
||||
Match match = _titleListRegex.Match(title);
|
||||
if (match.Success)
|
||||
{
|
||||
result.SerieName = match.Groups[1].Value.Trim(' ', '-');
|
||||
result.Season = int.Parse(match.Groups[4].Success ? match.Groups[4].Value.Trim() : "1");
|
||||
result.Episode = int.Parse(match.Groups[7].Value.Trim().PadLeft(2, '0'));
|
||||
result.EpisodeTo = match.Groups[10].Success ? (int?)int.Parse(match.Groups[10].Value.Trim()) : null;
|
||||
string audioQuality = match.Groups[12].Value.Trim(' ', '[', ']');
|
||||
quality = match.Groups[13].Value.Trim(' ', '[', ']');
|
||||
result.SeriesName = match.Groups[2].Value.Trim(' ', '-');
|
||||
result.Season = int.Parse(match.Groups[5].Success ? match.Groups[5].Value.Trim() : "1");
|
||||
result.Episode = int.Parse(match.Groups[8].Value.Trim().PadLeft(2, '0'));
|
||||
result.EpisodeTo = match.Groups[11].Success ? (int?)int.Parse(match.Groups[11].Value.Trim()) : null;
|
||||
string audioQuality = match.Groups[13].Value.Trim(' ', '[', ']');
|
||||
quality = match.Groups[14].Value.Trim(' ', '[', ']');
|
||||
|
||||
string seasonText = result.Season.ToString();
|
||||
string episodeText = seasonText + result.Episode.ToString().PadLeft(2, '0');
|
||||
string episodeToText = result.EpisodeTo.HasValue ? "_" + seasonText + result.EpisodeTo.ToString().PadLeft(2, '0') : "";
|
||||
|
||||
result.Title = string.Format("{0} - Temporada {1} [{2}][Cap.{3}{4}][{5}]",
|
||||
result.SerieName, seasonText, quality, episodeText, episodeToText, audioQuality);
|
||||
result.SeriesName, seasonText, quality, episodeText, episodeToText, audioQuality);
|
||||
}
|
||||
else
|
||||
{
|
||||
Match matchClassic = _titleClassicRegex.Match(title);
|
||||
if (matchClassic.Success)
|
||||
{
|
||||
result.Season = matchClassic.Groups[2].Success ? (int?)int.Parse(matchClassic.Groups[2].Value) : null;
|
||||
result.Episode = matchClassic.Groups[3].Success ? (int?)int.Parse(matchClassic.Groups[3].Value) : null;
|
||||
result.EpisodeTo = matchClassic.Groups[6].Success ? (int?)int.Parse(matchClassic.Groups[6].Value) : null;
|
||||
if (matchClassic.Groups[1].Success)
|
||||
quality = matchClassic.Groups[1].Value;
|
||||
result.Season = matchClassic.Groups[3].Success ? (int?)int.Parse(matchClassic.Groups[3].Value) : null;
|
||||
result.Episode = matchClassic.Groups[4].Success ? (int?)int.Parse(matchClassic.Groups[4].Value) : null;
|
||||
result.EpisodeTo = matchClassic.Groups[7].Success ? (int?)int.Parse(matchClassic.Groups[7].Value) : null;
|
||||
if (matchClassic.Groups[2].Success)
|
||||
quality = matchClassic.Groups[2].Value;
|
||||
}
|
||||
|
||||
result.Title = title;
|
||||
@@ -454,27 +485,30 @@ namespace Jackett.Common.Indexers
|
||||
|
||||
private string FixedTitle(NewpctRelease release, string quality)
|
||||
{
|
||||
if (String.IsNullOrEmpty(release.SerieName))
|
||||
if (String.IsNullOrEmpty(release.SeriesName))
|
||||
{
|
||||
release.SerieName = release.Title;
|
||||
release.SeriesName = release.Title;
|
||||
if (release.Title.Contains("-"))
|
||||
{
|
||||
release.SerieName = release.Title.Substring(0, release.Title.IndexOf('-') - 1);
|
||||
release.SeriesName = release.Title.Substring(0, release.Title.IndexOf('-') - 1);
|
||||
}
|
||||
}
|
||||
if (String.IsNullOrEmpty(quality))
|
||||
{
|
||||
quality = "HDTV";
|
||||
}
|
||||
var seasonAndEpisode = "S" + release.Season.ToString().PadLeft(2, '0');
|
||||
seasonAndEpisode += "E" + release.Episode.ToString().PadLeft(2, '0');
|
||||
if (release.EpisodeTo != release.Episode && release.EpisodeTo != null && release.EpisodeTo != 0)
|
||||
{
|
||||
seasonAndEpisode += "-" + release.EpisodeTo.ToString().PadLeft(2, '0');
|
||||
}
|
||||
var titleParts = new List<string>();
|
||||
titleParts.Add(release.SerieName);
|
||||
titleParts.Add(seasonAndEpisode);
|
||||
titleParts.Add(release.SeriesName);
|
||||
if (release.NewpctReleaseType == ReleaseType.TV)
|
||||
{
|
||||
var seasonAndEpisode = "S" + release.Season.ToString().PadLeft(2, '0');
|
||||
seasonAndEpisode += "E" + release.Episode.ToString().PadLeft(2, '0');
|
||||
if (release.EpisodeTo != release.Episode && release.EpisodeTo != null && release.EpisodeTo != 0)
|
||||
{
|
||||
seasonAndEpisode += "-" + release.EpisodeTo.ToString().PadLeft(2, '0');
|
||||
}
|
||||
titleParts.Add(seasonAndEpisode);
|
||||
}
|
||||
titleParts.Add(quality.Replace("[", "").Replace("]", ""));
|
||||
if (release.Title.ToLower().Contains("esp") || release.Title.ToLower().Contains("cast"))
|
||||
{
|
||||
|
@@ -321,7 +321,7 @@ namespace Jackett.Common.Indexers
|
||||
if (torrentRowList.Count == 0)
|
||||
{
|
||||
// No results found
|
||||
Output("\nNo result found for your query, please try another search term ...\n", "info");
|
||||
Output("\nNo result found for your query, please try another search term or change the theme you're currently using on the site as this is an unsupported solution...\n", "info");
|
||||
|
||||
// No result found for this query
|
||||
break;
|
||||
@@ -678,9 +678,23 @@ namespace Jackett.Common.Indexers
|
||||
/// <returns>JQuery Object</returns>
|
||||
private CQ FindTorrentRows()
|
||||
{
|
||||
// Return all occurencis of torrents found
|
||||
//return _fDom["#content > table > tr"];
|
||||
return _fDom["# base_content > table.mainouter > tbody > tr > td.outer > div.article > table > tbody > tr:not(:first)"];
|
||||
var defaultTheme = new[] { "/templates/1/", "/templates/2/", "/templates/3/", "/templates/4/", "/templates/5/", "/templates/6/", "/templates/11/", "/templates/12/" };
|
||||
var oldV2 = new[] { "/templates/7/", "/templates/8/", "/templates/9/", "/templates/10/", "/templates/14/" };
|
||||
|
||||
if (defaultTheme.Any(_fDom.Document.Body.InnerHTML.Contains))
|
||||
{
|
||||
// Return all occurencis of torrents found
|
||||
// $('#base_content2 > div.article > table > tbody:not(:first) > tr')
|
||||
return _fDom["# base_content2 > div.article > table > tbody:not(:first) > tr"];
|
||||
}
|
||||
|
||||
if (oldV2.Any(_fDom.Document.Body.InnerHTML.Contains))
|
||||
{
|
||||
// Return all occurencis of torrents found
|
||||
// $('#base_content > table.mainouter > tbody > tr > td.outer > div.article > table > tbody')
|
||||
return _fDom["# base_content > table.mainouter > tbody > tr > td.outer > div.article > table > tbody > tr:not(:first)"];
|
||||
}
|
||||
return _fDom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@@ -309,6 +309,13 @@ namespace Jackett.Common.Indexers
|
||||
}
|
||||
|
||||
var results = await RequestStringWithCookiesAndRetry(searchUrl);
|
||||
if (results.IsRedirect)
|
||||
{
|
||||
// re-login
|
||||
await ApplyConfiguration(null);
|
||||
results = await RequestStringWithCookiesAndRetry(searchUrl);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
CQ dom = results.Content;
|
||||
|
@@ -18,7 +18,7 @@ namespace Jackett.Common.Indexers
|
||||
{
|
||||
public class SpeedCD : BaseWebIndexer
|
||||
{
|
||||
private string LoginUrl { get { return SiteLink + "take.login.php"; } }
|
||||
private string LoginUrl { get { return SiteLink + "takelogin.php"; } }
|
||||
private string SearchUrl { get { return SiteLink + "browse.php"; } }
|
||||
|
||||
private new ConfigurationDataBasicLogin configData
|
||||
@@ -147,18 +147,19 @@ namespace Jackett.Common.Indexers
|
||||
CQ torrentData = row.OuterHTML;
|
||||
CQ cells = row.Cq().Find("td");
|
||||
|
||||
string title = torrentData.Find("a[class='torrent']").First().Text().Trim();
|
||||
Uri link = new Uri(SiteLink + torrentData.Find("img[class='icos save']").First().Parent().Attr("href").Trim());
|
||||
Uri guid = new Uri(SiteLink + torrentData.Find("a[class='torrent']").First().Attr("href").Trim().TrimStart('/'));
|
||||
string title = torrentData.Find("td[class='lft'] > div > a").First().Text().Trim();
|
||||
Uri link = new Uri(SiteLink + torrentData.Find("img[title='Download']").First().Parent().Attr("href").Trim());
|
||||
Uri guid = link;
|
||||
long size = ReleaseInfo.GetBytes(cells.Elements.ElementAt(4).Cq().Text());
|
||||
int seeders = ParseUtil.CoerceInt(cells.Elements.ElementAt(5).Cq().Text());
|
||||
int leechers = ParseUtil.CoerceInt(cells.Elements.ElementAt(6).Cq().Text());
|
||||
int grabs = ParseUtil.CoerceInt(cells.Elements.ElementAt(5).Cq().Text());
|
||||
int seeders = ParseUtil.CoerceInt(cells.Elements.ElementAt(6).Cq().Text());
|
||||
int leechers = ParseUtil.CoerceInt(cells.Elements.ElementAt(7).Cq().Text());
|
||||
|
||||
string pubDateStr = torrentData.Find("span[class^='elapsedDate']").First().Attr("title").Trim().Replace(" at", "");
|
||||
DateTime publishDate = DateTime.ParseExact(pubDateStr, "dddd, MMMM d, yyyy h:mmtt", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToLocalTime();
|
||||
|
||||
long category = 0;
|
||||
string cat = torrentData.Find("a[class='cat']").First().Attr("id").Trim();
|
||||
string cat = torrentData.Find("img[class^='Tcat']").First().Parent().Attr("href").Trim().Remove(0, 5);
|
||||
long.TryParse(cat, out category);
|
||||
|
||||
var release = new ReleaseInfo();
|
||||
@@ -168,6 +169,7 @@ namespace Jackett.Common.Indexers
|
||||
release.Link = link;
|
||||
release.PublishDate = publishDate;
|
||||
release.Size = size;
|
||||
release.Grabs = grabs;
|
||||
release.Seeders = seeders;
|
||||
release.Peers = seeders + leechers;
|
||||
release.MinimumRatio = 1;
|
||||
|
@@ -37,6 +37,10 @@ namespace Jackett.Common.Indexers
|
||||
"https://www.torrentday.ru/",
|
||||
"https://www.td.af/",
|
||||
"https://torrentday.it/",
|
||||
"https://td.findnemo.net",
|
||||
"https://td.getcrazy.me",
|
||||
"https://td.venom.global",
|
||||
"https://td.workisboring.net",
|
||||
};
|
||||
|
||||
private new ConfigurationDataRecaptchaLogin configData
|
||||
@@ -54,7 +58,7 @@ namespace Jackett.Common.Indexers
|
||||
client: wc,
|
||||
logger: l,
|
||||
p: ps,
|
||||
configData: new ConfigurationDataRecaptchaLogin())
|
||||
configData: new ConfigurationDataRecaptchaLogin("Make sure you get the cookies from the same torrent day domain as configured above."))
|
||||
{
|
||||
wc.EmulateBrowser = false;
|
||||
Encoding = Encoding.UTF8;
|
||||
@@ -121,7 +125,9 @@ namespace Jackett.Common.Indexers
|
||||
loginPage = await RequestStringWithCookies(loginPage.RedirectingTo, string.Empty);
|
||||
CQ cq = loginPage.Content;
|
||||
var result = this.configData;
|
||||
result.CookieHeader.Value = loginPage.Cookies;
|
||||
|
||||
//result.CookieHeader.Value = loginPage.Cookies;
|
||||
UpdateCookieHeader(loginPage.Cookies); // update cookies instead of replacing them, see #3717
|
||||
result.Captcha.SiteKey = cq.Find(".g-recaptcha").Attr("data-sitekey");
|
||||
result.Captcha.Version = "2";
|
||||
return result;
|
||||
|
@@ -52,40 +52,35 @@ namespace Jackett.Common.Indexers
|
||||
|
||||
AddCategoryMapping(2, TorznabCatType.PC, "Apps / Windows");
|
||||
AddCategoryMapping(13, TorznabCatType.PC, "Apps / Linux");
|
||||
AddCategoryMapping(4, TorznabCatType.PCMac, "Apps / Mac");
|
||||
AddCategoryMapping(4, TorznabCatType.PCMac, "Apps / MacOS");
|
||||
AddCategoryMapping(6, TorznabCatType.PC, "Apps / Misc");
|
||||
|
||||
AddCategoryMapping(12, TorznabCatType.PCGames, "Spiele / PC");
|
||||
AddCategoryMapping(8, TorznabCatType.ConsolePSP, "Spiele / PSX/PSP");
|
||||
AddCategoryMapping(7, TorznabCatType.ConsoleWii, "Spiele / Wii");
|
||||
AddCategoryMapping(32, TorznabCatType.ConsoleXbox, "Spiele / XBOX");
|
||||
AddCategoryMapping(41, TorznabCatType.ConsoleOther, "Spiele / Misc");
|
||||
AddCategoryMapping(50, TorznabCatType.PCGames, "Spiele / Windows");
|
||||
AddCategoryMapping(51, TorznabCatType.PCGames, "Spiele / MacOS");
|
||||
AddCategoryMapping(52, TorznabCatType.PCGames, "Spiele / Linux");
|
||||
AddCategoryMapping(8, TorznabCatType.ConsoleOther, "Spiele / Playstation");
|
||||
AddCategoryMapping(7, TorznabCatType.ConsoleOther, "Spiele / Nintendo");
|
||||
AddCategoryMapping(32, TorznabCatType.ConsoleOther, "Spiele / XBOX");
|
||||
|
||||
AddCategoryMapping(22, TorznabCatType.Movies3D, "Filme / 3D");
|
||||
AddCategoryMapping(3, TorznabCatType.MoviesBluRay, "Filme / BluRay");
|
||||
AddCategoryMapping(11, TorznabCatType.MoviesOther, "Filme / REMUX");
|
||||
AddCategoryMapping(42, TorznabCatType.MoviesUHD, "Filme / 2160p");
|
||||
AddCategoryMapping(9, TorznabCatType.MoviesHD, "Filme / 1080p");
|
||||
AddCategoryMapping(20, TorznabCatType.MoviesHD, "Filme / 720p");
|
||||
AddCategoryMapping(21, TorznabCatType.MoviesDVD, "Filme / DVD");
|
||||
AddCategoryMapping(10, TorznabCatType.MoviesSD, "Filme / SD");
|
||||
AddCategoryMapping(31, TorznabCatType.MoviesOther, "Filme / Anime");
|
||||
|
||||
AddCategoryMapping(43, TorznabCatType.TVUHD, "TV / Serien/UHD");
|
||||
AddCategoryMapping(16, TorznabCatType.TVHD, "TV / Serien/HD");
|
||||
AddCategoryMapping(15, TorznabCatType.TVSD, "TV / Serien/SD");
|
||||
AddCategoryMapping(44, TorznabCatType.TVUHD, "TV / Packs/UHD");
|
||||
AddCategoryMapping(23, TorznabCatType.TVHD, "TV / Packs/HD");
|
||||
AddCategoryMapping(27, TorznabCatType.TVSD, "TV / Packs/SD");
|
||||
AddCategoryMapping(28, TorznabCatType.TVDocumentary, "TV / Dokus/SD");
|
||||
AddCategoryMapping(29, TorznabCatType.TVDocumentary, "TV / Dokus/HD");
|
||||
AddCategoryMapping(30, TorznabCatType.TVSport, "TV / Sport");
|
||||
AddCategoryMapping(40, TorznabCatType.TVAnime, "TV / Anime");
|
||||
AddCategoryMapping(43, TorznabCatType.TVUHD, "Serien / 2160p");
|
||||
AddCategoryMapping(53, TorznabCatType.TVHD, "Serien / 1080p");
|
||||
AddCategoryMapping(54, TorznabCatType.TVHD, "Serien / 720p");
|
||||
AddCategoryMapping(15, TorznabCatType.TVSD, "Serien / SD");
|
||||
AddCategoryMapping(30, TorznabCatType.TVSport, "Serien / Sport");
|
||||
|
||||
AddCategoryMapping(24, TorznabCatType.AudioLossless, "Audio / FLAC");
|
||||
AddCategoryMapping(25, TorznabCatType.AudioMP3, "Audio / MP3");
|
||||
AddCategoryMapping(44, TorznabCatType.TVUHD, "Serienpacks / 2160p");
|
||||
AddCategoryMapping(55, TorznabCatType.TVHD, "Serienpacks / 1080p");
|
||||
AddCategoryMapping(56, TorznabCatType.TVHD, "Serienpacks / 720p");
|
||||
AddCategoryMapping(27, TorznabCatType.TVSD, "Serienpacks / SD");
|
||||
|
||||
AddCategoryMapping(24, TorznabCatType.AudioLossless, "Audio / Musik / FLAC");
|
||||
AddCategoryMapping(25, TorznabCatType.AudioMP3, "Audio / Musik / MP3");
|
||||
AddCategoryMapping(35, TorznabCatType.AudioOther, "Audio / Other");
|
||||
AddCategoryMapping(26, TorznabCatType.Audio, "Audio / Packs");
|
||||
AddCategoryMapping(18, TorznabCatType.AudioAudiobook, "Audio / aBooks");
|
||||
AddCategoryMapping(33, TorznabCatType.AudioVideo, "Audio / Videos");
|
||||
|
||||
@@ -93,7 +88,8 @@ namespace Jackett.Common.Indexers
|
||||
AddCategoryMapping(5, TorznabCatType.PCPhoneOther, "Misc / Mobile");
|
||||
AddCategoryMapping(39, TorznabCatType.Other, "Misc / Bildung");
|
||||
|
||||
AddCategoryMapping(36, TorznabCatType.TVFOREIGN, "Englisch / TV");
|
||||
AddCategoryMapping(36, TorznabCatType.TVFOREIGN, "Englisch / Serien");
|
||||
AddCategoryMapping(57, TorznabCatType.TVFOREIGN, "Englisch / Serienpacks");
|
||||
AddCategoryMapping(37, TorznabCatType.MoviesForeign, "Englisch / Filme");
|
||||
AddCategoryMapping(47, TorznabCatType.Books, "Englisch / eBooks");
|
||||
AddCategoryMapping(48, TorznabCatType.Other, "Englisch / Bildung");
|
||||
|
@@ -1470,7 +1470,7 @@ namespace Jackett.Common.Indexers
|
||||
{
|
||||
{ "login_username", configData.Username.Value },
|
||||
{ "login_password", configData.Password.Value },
|
||||
{ "login", "entry" }
|
||||
{ "login", "Login" }
|
||||
};
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(cap_sid))
|
||||
@@ -1483,9 +1483,10 @@ namespace Jackett.Common.Indexers
|
||||
}
|
||||
|
||||
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, CookieHeader, true, null, LoginUrl, true);
|
||||
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("class=\"logged-in-as-uname\""), () =>
|
||||
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("id=\"logged-in-username\""), () =>
|
||||
{
|
||||
var errorMessage = result.Content;
|
||||
logger.Debug(result.Content);
|
||||
var errorMessage = "Unknown error message, please report";
|
||||
var LoginResultParser = new HtmlParser();
|
||||
var LoginResultDocument = LoginResultParser.Parse(result.Content);
|
||||
var errormsg = LoginResultDocument.QuerySelector("h4[class=\"warnColor1 tCenter mrg_16\"]");
|
||||
@@ -1521,7 +1522,7 @@ namespace Jackett.Common.Indexers
|
||||
|
||||
var searchUrl = SearchUrl + "?" + queryCollection.GetQueryString();
|
||||
var results = await RequestStringWithCookies(searchUrl);
|
||||
if (!results.Content.Contains("class=\"logged-in-as-uname\""))
|
||||
if (!results.Content.Contains("id=\"logged-in-username\""))
|
||||
{
|
||||
// re login
|
||||
await ApplyConfiguration(null);
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0</TargetFrameworks>
|
||||
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
|
||||
<Version>0.0.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
|
||||
<PackageReference Include="MimeMapping" Version="1.0.1.12" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||
<PackageReference Include="NLog" Version="4.5.8" />
|
||||
<PackageReference Include="NLog" Version="4.5.9" />
|
||||
<PackageReference Include="SharpZipLib" Version="1.0.0" />
|
||||
<PackageReference Include="YamlDotNet" Version="5.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Conditionally obtain references for the .NET Full framework target -->
|
||||
<ItemGroup Condition="'$(TargetFramework)' != 'netstandard2.0'">
|
||||
<PackageReference Include="CsQuery" Version="1.3.5-beta5" />
|
||||
<PackageReference Include="SharpZipLib" Version="0.86.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="1.1.2" />
|
||||
<Reference Include="System.ServiceProcess" />
|
||||
</ItemGroup>
|
||||
@@ -31,7 +31,6 @@
|
||||
<!-- Conditionally obtain references for the .NETStandard target -->
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
|
||||
<PackageReference Include="CsQuery.NETStandard" Version="1.3.6.1" />
|
||||
<PackageReference Include="SharpZipLib" Version="1.0.0-alpha2" />
|
||||
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="4.5.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="2.1.1" />
|
||||
<PackageReference Include="System.ServiceProcess.ServiceController" Version="4.5.0" />
|
||||
|
@@ -1,5 +1,4 @@
|
||||
using CommandLine;
|
||||
using Jackett.Common.Utils;
|
||||
using System;
|
||||
|
||||
namespace Jackett.Common.Models.Config
|
||||
@@ -9,55 +8,46 @@ namespace Jackett.Common.Models.Config
|
||||
[Option('i', "Install", HelpText = "Install Jackett windows service (Must be admin)")]
|
||||
public bool Install { get; set; }
|
||||
|
||||
[Option('r', "ReserveUrls", HelpText = "(Re)Register windows port reservations (Required for listening on all interfaces).")]
|
||||
[Option('r', "ReserveUrls", HelpText = "(Re)Register windows port reservations (Required for listening on all interfaces).")]
|
||||
public bool ReserveUrls { get; set; }
|
||||
|
||||
[Option('u', "Uninstall", HelpText = "Uninstall Jackett windows service (Must be admin).")]
|
||||
public bool Uninstall { get; set; }
|
||||
|
||||
[Option('l', "Logging", HelpText = "Log all requests/responses to Jackett")]
|
||||
[Option('l', "Logging", HelpText = "Log all requests/responses to Jackett")]
|
||||
public bool Logging { get; set; }
|
||||
|
||||
[Option('t', "Tracing", HelpText = "Enable tracing")]
|
||||
public bool Tracing { get; set; }
|
||||
|
||||
[Option('c', "UseClient", HelpText = "Override web client selection. [automatic(Default)/libcurl/safecurl/httpclient/httpclient2]")]
|
||||
[Option('c', "UseClient", HelpText = "Override web client selection. [automatic(Default)/httpclient/httpclient2]")]
|
||||
public string Client { get; set; }
|
||||
|
||||
[Option('j', "ProxyConnection", HelpText = "use proxy - e.g. 127.0.0.1:8888")]
|
||||
public string ProxyConnection { get; set; }
|
||||
|
||||
[Option('s', "Start", HelpText = "Start the Jacket Windows service (Must be admin)")]
|
||||
[Option('s', "Start", HelpText = "Start the Jacket Windows service (Must be admin)")]
|
||||
public bool StartService { get; set; }
|
||||
|
||||
[Option('k', "Stop", HelpText = "Stop the Jacket Windows service (Must be admin)")]
|
||||
public bool StopService { get; set; }
|
||||
|
||||
[Option('x', "ListenPublic", HelpText = "Listen publicly")]
|
||||
[Option('x', "ListenPublic", HelpText = "Listen publicly")]
|
||||
public bool ListenPublic { get; set; }
|
||||
|
||||
[Option('z', "ListenPrivate", HelpText = "Only allow local access")]
|
||||
public bool ListenPrivate { get; set; }
|
||||
|
||||
[Option('h', "Help", HelpText = "Show Help")]
|
||||
public bool ShowHelp { get; set; }
|
||||
|
||||
[Option('v', "Version", HelpText = "Show Version")]
|
||||
public bool ShowVersion { get; set; }
|
||||
|
||||
[Option('p', "Port", HelpText = "Web server port")]
|
||||
public int Port { get; set; }
|
||||
|
||||
[Option('m', "MigrateSettings", HelpText = "Migrate settings manually (Must be admin on Windows)")]
|
||||
public bool MigrateSettings { get; set; }
|
||||
|
||||
[Option('f', "SSLFix", HelpText = "[true/false] Linux Libcurl NSS Missing ECC Ciphers workaround (Use if you can't access some trackers) .")]
|
||||
public bool? SSLFix { get; set; }
|
||||
|
||||
[Option('n', "IgnoreSslErrors", HelpText = "[true/false] Ignores invalid SSL certificates")]
|
||||
public bool? IgnoreSslErrors { get; set; }
|
||||
|
||||
[Option('d', "DataFolder", HelpText = "Specify the location of the data folder (Must be admin on Windows) eg. --DataFolder=\"D:\\Your Data\\Jackett\\\". Don't use this on Unix (mono) systems. On Unix just adjust the HOME directory of the user to the datedir or set the XDG_CONFIG_HOME environment variable.")]
|
||||
[Option('d', "DataFolder", HelpText = "Specify the location of the data folder (Must be admin on Windows) eg. --DataFolder=\"D:\\Your Data\\Jackett\\\". Don't use this on Unix (mono) systems. On Unix just adjust the HOME directory of the user to the datadir or set the XDG_CONFIG_HOME environment variable.")]
|
||||
public string DataFolder { get; set; }
|
||||
|
||||
[Option("NoRestart", HelpText = "Don't restart after update")]
|
||||
@@ -87,9 +77,6 @@ namespace Jackett.Common.Models.Config
|
||||
Environment.Exit(1);
|
||||
}
|
||||
|
||||
// SSL Fix
|
||||
runtimeSettings.DoSSLFix = options.SSLFix;
|
||||
|
||||
// Use curl
|
||||
if (options.Client != null)
|
||||
runtimeSettings.ClientOverride = options.Client.ToLowerInvariant();
|
||||
|
@@ -13,8 +13,6 @@ namespace Jackett.Common.Models.Config
|
||||
|
||||
public string ProxyConnection { get; set; }
|
||||
|
||||
public bool? DoSSLFix { get; set; }
|
||||
|
||||
public bool? IgnoreSslErrors { get; set; }
|
||||
|
||||
public string CustomDataFolder { get; set; }
|
||||
|
@@ -104,8 +104,7 @@ namespace Jackett.Common.Models.Config
|
||||
else
|
||||
{
|
||||
return new string[] {
|
||||
"http://127.0.0.1:" + Port + "/",
|
||||
"http://localhost:" + Port + "/",
|
||||
"http://127.0.0.1:" + Port + "/"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -45,33 +45,39 @@ namespace Jackett.Common.Models
|
||||
}
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
public ReleaseInfo()
|
||||
{
|
||||
return new ReleaseInfo()
|
||||
{
|
||||
Title = Title,
|
||||
Guid = Guid,
|
||||
Link = Link,
|
||||
Comments = Comments,
|
||||
PublishDate = PublishDate,
|
||||
Category = Category,
|
||||
Size = Size,
|
||||
Files = Files,
|
||||
Grabs = Grabs,
|
||||
Description = Description,
|
||||
RageID = RageID,
|
||||
Imdb = Imdb,
|
||||
TMDb = TMDb,
|
||||
Seeders = Seeders,
|
||||
Peers = Peers,
|
||||
BannerUrl = BannerUrl,
|
||||
InfoHash = InfoHash,
|
||||
MagnetUri = MagnetUri,
|
||||
MinimumRatio = MinimumRatio,
|
||||
MinimumSeedTime = MinimumSeedTime,
|
||||
DownloadVolumeFactor = DownloadVolumeFactor,
|
||||
UploadVolumeFactor = UploadVolumeFactor
|
||||
};
|
||||
}
|
||||
|
||||
protected ReleaseInfo(ReleaseInfo copyFrom)
|
||||
{
|
||||
Title = copyFrom.Title;
|
||||
Guid = copyFrom.Guid;
|
||||
Link = copyFrom.Link;
|
||||
Comments = copyFrom.Comments;
|
||||
PublishDate = copyFrom.PublishDate;
|
||||
Category = copyFrom.Category;
|
||||
Size = copyFrom.Size;
|
||||
Files = copyFrom.Files;
|
||||
Grabs = copyFrom.Grabs;
|
||||
Description = copyFrom.Description;
|
||||
RageID = copyFrom.RageID;
|
||||
Imdb = copyFrom.Imdb;
|
||||
TMDb = copyFrom.TMDb;
|
||||
Seeders = copyFrom.Seeders;
|
||||
Peers = copyFrom.Peers;
|
||||
BannerUrl = copyFrom.BannerUrl;
|
||||
InfoHash = copyFrom.InfoHash;
|
||||
MagnetUri = copyFrom.MagnetUri;
|
||||
MinimumRatio = copyFrom.MinimumRatio;
|
||||
MinimumSeedTime = copyFrom.MinimumSeedTime;
|
||||
DownloadVolumeFactor = copyFrom.DownloadVolumeFactor;
|
||||
UploadVolumeFactor = copyFrom.UploadVolumeFactor;
|
||||
}
|
||||
|
||||
public virtual object Clone()
|
||||
{
|
||||
return new ReleaseInfo(this);
|
||||
}
|
||||
|
||||
// ex: " 3.5 gb "
|
||||
|
@@ -49,12 +49,12 @@ namespace Jackett.Common.Plumbing
|
||||
return BuildServerConfig(ctx);
|
||||
}).As<ServerConfig>().SingleInstance();
|
||||
builder.RegisterType<HttpWebClient>();
|
||||
|
||||
|
||||
// Register the best web client for the platform or the override
|
||||
switch (_runtimeSettings.ClientOverride)
|
||||
{
|
||||
case "httpclientnetcore":
|
||||
// do nothing, registered by the netcore app
|
||||
RegisterWebClient<HttpWebClientNetCore>(builder);
|
||||
break;
|
||||
case "httpclient":
|
||||
RegisterWebClient<HttpWebClient>(builder);
|
||||
|
@@ -19,12 +19,6 @@ namespace Jackett.Server
|
||||
Environment.Exit(1);
|
||||
}
|
||||
|
||||
if (runtimeSettings.DoSSLFix != null)
|
||||
{
|
||||
logger.Error("SSLFix has been deprecated, please remove it from your start arguments");
|
||||
Environment.Exit(1);
|
||||
}
|
||||
|
||||
if (runtimeSettings.LogRequests)
|
||||
{
|
||||
logger.Info("Logging enabled.");
|
||||
@@ -159,5 +153,32 @@ namespace Jackett.Server
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void CheckEnvironmentalVariables(Logger logger)
|
||||
{
|
||||
//Check the users environmental variables to ensure they aren't using Mono legacy TLS
|
||||
|
||||
var enumerator = Environment.GetEnvironmentVariables().GetEnumerator();
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
if (enumerator.Key.ToString().Equals("MONO_TLS_PROVIDER", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
logger.Info("MONO_TLS_PROVIDER is present with a value of: " + enumerator.Value.ToString());
|
||||
|
||||
if (enumerator.Value.ToString().IndexOf("legacy", StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
{
|
||||
logger.Error("The MONO_TLS_PROVIDER=legacy environment variable is not supported, please remove it.");
|
||||
Environment.Exit(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (enumerator.Key.ToString().IndexOf("MONO_", StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
{
|
||||
logger.Info($"Environment variable {enumerator.Key} is present");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -25,15 +25,15 @@
|
||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.3.0" />
|
||||
<PackageReference Include="AutoMapper" Version="7.0.1" />
|
||||
<PackageReference Include="CommandLineParser" Version="2.3.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore" Version="2.1.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore" Version="2.1.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.1.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.1.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.1.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.ResponseCompression" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Rewrite" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.1" />
|
||||
<PackageReference Include="NLog" Version="4.5.8" />
|
||||
<PackageReference Include="NLog" Version="4.5.9" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="4.6.0" />
|
||||
<PackageReference Include="System.ServiceProcess.ServiceController" Version="4.5.0" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.0" />
|
||||
|
@@ -47,7 +47,6 @@ namespace Jackett.Server
|
||||
{
|
||||
if (string.IsNullOrEmpty(options.Client))
|
||||
{
|
||||
//TODO: Remove libcurl once off owin
|
||||
bool runningOnDotNetCore = RuntimeInformation.FrameworkDescription.IndexOf("Core", StringComparison.OrdinalIgnoreCase) >= 0;
|
||||
|
||||
if (runningOnDotNetCore)
|
||||
@@ -83,6 +82,7 @@ namespace Jackett.Server
|
||||
}
|
||||
}
|
||||
|
||||
Initialisation.CheckEnvironmentalVariables(logger);
|
||||
Initialisation.ProcessSettings(Settings, logger);
|
||||
|
||||
ISerializeService serializeService = new SerializeService();
|
||||
@@ -124,7 +124,7 @@ namespace Jackett.Server
|
||||
|
||||
ServerConfig serverConfig = configurationService.BuildServerConfig(Settings);
|
||||
Int32.TryParse(serverConfig.Port.ToString(), out Int32 configPort);
|
||||
string[] url = serverConfig.GetListenAddresses(serverConfig.AllowExternal).Take(1).ToArray(); //Kestrel doesn't need 127.0.0.1 and localhost to be registered, remove once off OWIN
|
||||
string[] url = serverConfig.GetListenAddresses(serverConfig.AllowExternal);
|
||||
|
||||
isWebHostRestart = false;
|
||||
|
||||
|
@@ -3,7 +3,6 @@ using Autofac.Extensions.DependencyInjection;
|
||||
using Jackett.Common.Models.Config;
|
||||
using Jackett.Common.Plumbing;
|
||||
using Jackett.Common.Services.Interfaces;
|
||||
using Jackett.Common.Utils.Clients;
|
||||
using Jackett.Server.Middleware;
|
||||
using Jackett.Server.Services;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
@@ -84,8 +83,6 @@ namespace Jackett.Server
|
||||
builder.RegisterType<ServerService>().As<IServerService>();
|
||||
builder.RegisterType<ProtectionService>().As<IProtectionService>();
|
||||
builder.RegisterType<ServiceConfigService>().As<IServiceConfigService>();
|
||||
if (runtimeSettings.ClientOverride == "httpclientnetcore")
|
||||
builder.RegisterType<HttpWebClientNetCore>().As<WebClient>();
|
||||
|
||||
IContainer container = builder.Build();
|
||||
Helper.ApplicationContainer = container;
|
||||
|
@@ -22,13 +22,13 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autofac" Version="4.8.1" />
|
||||
<PackageReference Include="FluentAssertions" Version="5.4.1" />
|
||||
<PackageReference Include="FluentAssertions" Version="5.4.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.DataProtection" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="1.3.2" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="1.3.2" />
|
||||
<PackageReference Include="NUnit" Version="3.10.1" />
|
||||
<PackageReference Include="NUnit.ConsoleRunner" Version="3.8.0" />
|
||||
<PackageReference Include="NUnit.ConsoleRunner" Version="3.9.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@@ -87,10 +87,34 @@ namespace Jackett.Updater
|
||||
{
|
||||
var proc = Process.GetProcessById(pid);
|
||||
logger.Info("Killing process " + proc.Id);
|
||||
proc.Kill();
|
||||
var exited = proc.WaitForExit(5000);
|
||||
|
||||
// try to kill gracefully (on unix) first, see #3692
|
||||
var exited = false;
|
||||
if (Environment.OSVersion.Platform == PlatformID.Unix)
|
||||
{
|
||||
try
|
||||
{
|
||||
var startInfo = new ProcessStartInfo();
|
||||
startInfo.Arguments = "-15 " + pid;
|
||||
startInfo.FileName = "kill";
|
||||
Process.Start(startInfo);
|
||||
System.Threading.Thread.Sleep(1000); // just sleep, WaitForExit() doesn't seem to work on mono/linux (returns immediantly), https://bugzilla.xamarin.com/show_bug.cgi?id=51742
|
||||
exited = proc.WaitForExit(2000);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.Error(e, "Error while sending SIGTERM to " + pid.ToString());
|
||||
}
|
||||
if (!exited)
|
||||
logger.Info("Process " + pid.ToString() + " didn't exit within 2 seconds after a SIGTERM");
|
||||
}
|
||||
if (!exited)
|
||||
logger.Info("Process " + pid.ToString() + " didn't exit within 5 seconds");
|
||||
{
|
||||
proc.Kill(); // send SIGKILL
|
||||
}
|
||||
exited = proc.WaitForExit(5000);
|
||||
if (!exited)
|
||||
logger.Info("Process " + pid.ToString() + " didn't exit within 5 seconds after a SIGKILL");
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
@@ -234,7 +258,6 @@ namespace Jackett.Updater
|
||||
"Definitions/eotforum.yml",
|
||||
"Definitions/nexttorrent.yml",
|
||||
"appsettings.Development.json",
|
||||
"appsettings.json",
|
||||
"CurlSharp.dll",
|
||||
"CurlSharp.pdb",
|
||||
"Jackett.dll",
|
||||
@@ -250,6 +273,8 @@ namespace Jackett.Updater
|
||||
"System.Web.Http.dll",
|
||||
"System.Web.Http.Owin.dll",
|
||||
"System.Web.Http.Tracing.dll",
|
||||
"Definitions/torrentkim.yml",
|
||||
"Definitions/horriblesubs.yml",
|
||||
};
|
||||
|
||||
foreach (var oldFile in oldFiles)
|
||||
|
Reference in New Issue
Block a user