mirror of
https://github.com/Jackett/Jackett.git
synced 2025-09-12 15:04:13 +02:00
Compare commits
312 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
141f3e57e5 | ||
![]() |
00027a41c1 | ||
![]() |
e754d3da9f | ||
![]() |
bf54a2f171 | ||
![]() |
7b7d0082b6 | ||
![]() |
3614b1b3da | ||
![]() |
39b0670a29 | ||
![]() |
1689c46c91 | ||
![]() |
0143bdfe14 | ||
![]() |
93a9568a77 | ||
![]() |
40079b0365 | ||
![]() |
168f04e786 | ||
![]() |
861a33f4af | ||
![]() |
57c52d9eb2 | ||
![]() |
f574dedbe8 | ||
![]() |
a6d2ecffbb | ||
![]() |
300354ef13 | ||
![]() |
4a519226f5 | ||
![]() |
6a4f6e3638 | ||
![]() |
157b042c0a | ||
![]() |
9385218c9d | ||
![]() |
7482e8d9c4 | ||
![]() |
5501d282de | ||
![]() |
123bb4af5f | ||
![]() |
4d36dae634 | ||
![]() |
eac11ab807 | ||
![]() |
b6892f1dc6 | ||
![]() |
0695b8f84e | ||
![]() |
04995f1a10 | ||
![]() |
44d9b3ecc8 | ||
![]() |
a311509b7c | ||
![]() |
0db4229bd4 | ||
![]() |
441aad5a18 | ||
![]() |
d8d911abf8 | ||
![]() |
7423e3f5bc | ||
![]() |
48fea35645 | ||
![]() |
cef72f11d0 | ||
![]() |
ad3039b70f | ||
![]() |
73d590cebd | ||
![]() |
1d0790471f | ||
![]() |
3b3048aa01 | ||
![]() |
183fb56b0a | ||
![]() |
466be31e6f | ||
![]() |
db42bc944b | ||
![]() |
102e7338f9 | ||
![]() |
01b30b0743 | ||
![]() |
947dbac485 | ||
![]() |
0d29e85c80 | ||
![]() |
89a28e2e95 | ||
![]() |
66b2c20b42 | ||
![]() |
e6035bcaa5 | ||
![]() |
68aac78360 | ||
![]() |
4b02141250 | ||
![]() |
8e1d321817 | ||
![]() |
3354d37aa3 | ||
![]() |
7675214092 | ||
![]() |
7af8e1916e | ||
![]() |
6d4720e58f | ||
![]() |
9928815777 | ||
![]() |
a7d65fedfb | ||
![]() |
464b142130 | ||
![]() |
e1bcdce019 | ||
![]() |
ced9bad4f8 | ||
![]() |
c6140d7eef | ||
![]() |
97f4a9de5d | ||
![]() |
be1f6a43a7 | ||
![]() |
c8d96990d5 | ||
![]() |
e9db6edce8 | ||
![]() |
eee7f2999f | ||
![]() |
01e5ad792e | ||
![]() |
aa02644e05 | ||
![]() |
26dd740a53 | ||
![]() |
952b6d7f95 | ||
![]() |
e8742554c2 | ||
![]() |
7229da2fbb | ||
![]() |
39db77eb7c | ||
![]() |
d866758a0d | ||
![]() |
4d72d08e26 | ||
![]() |
2e169a8c3a | ||
![]() |
978ce0827f | ||
![]() |
fe94e4833d | ||
![]() |
592f04389f | ||
![]() |
5992e6d701 | ||
![]() |
d44ebb7d43 | ||
![]() |
852142e9ae | ||
![]() |
3ba52f15dd | ||
![]() |
502a4dc763 | ||
![]() |
d336a761a7 | ||
![]() |
9240f9d72b | ||
![]() |
cab91ff346 | ||
![]() |
2a327549f5 | ||
![]() |
5748881a29 | ||
![]() |
69aa38c1ff | ||
![]() |
aa157cfcb9 | ||
![]() |
f963f8d173 | ||
![]() |
1d75164aaf | ||
![]() |
f503f0543e | ||
![]() |
333f7297fa | ||
![]() |
3fdfc4a142 | ||
![]() |
0ac58224f9 | ||
![]() |
3d08fcb4b9 | ||
![]() |
c2f11306b1 | ||
![]() |
07a0c2c828 | ||
![]() |
28eaa637df | ||
![]() |
8707e6b2e9 | ||
![]() |
7a8d83b693 | ||
![]() |
403c0ef7e4 | ||
![]() |
3374c14311 | ||
![]() |
9eade51d89 | ||
![]() |
bc9e4a30cb | ||
![]() |
0103c48c97 | ||
![]() |
29ecf8a584 | ||
![]() |
eec07bc5b8 | ||
![]() |
bf23878477 | ||
![]() |
043085e8f3 | ||
![]() |
39e612d60c | ||
![]() |
6f8b1b749d | ||
![]() |
439e9296f9 | ||
![]() |
1332b49370 | ||
![]() |
33a7db5ec4 | ||
![]() |
2075e914eb | ||
![]() |
758ad91a55 | ||
![]() |
e9b604d3c4 | ||
![]() |
51aa4f35bd | ||
![]() |
fc55882f16 | ||
![]() |
d03cbefa57 | ||
![]() |
e079c90535 | ||
![]() |
8591add0bf | ||
![]() |
fbbe4f9c45 | ||
![]() |
289c5cd24f | ||
![]() |
84a45737d3 | ||
![]() |
d083cf774a | ||
![]() |
f2ce167bbf | ||
![]() |
4e04bbbcf4 | ||
![]() |
7f5d00e89f | ||
![]() |
f777114644 | ||
![]() |
7c63a6b8f2 | ||
![]() |
f0140999bf | ||
![]() |
6f0a249503 | ||
![]() |
2e79500f50 | ||
![]() |
720b5971d3 | ||
![]() |
dba63857e4 | ||
![]() |
b05ee653d3 | ||
![]() |
84df60368c | ||
![]() |
76102ac171 | ||
![]() |
3c6e77a2ca | ||
![]() |
f6272032a6 | ||
![]() |
41fb5e89b4 | ||
![]() |
42c9967844 | ||
![]() |
e740e2434d | ||
![]() |
057df28d1b | ||
![]() |
6fbc4b6904 | ||
![]() |
cab608f0ec | ||
![]() |
f5592d04e2 | ||
![]() |
5138496436 | ||
![]() |
bcc1e5ff6c | ||
![]() |
7eb57d8e9a | ||
![]() |
929c12ccc6 | ||
![]() |
1ba1b91b8e | ||
![]() |
d90a2613fc | ||
![]() |
0d25ed2921 | ||
![]() |
a07bffa773 | ||
![]() |
f0da6ce247 | ||
![]() |
32d0a8d703 | ||
![]() |
6e2087d5dc | ||
![]() |
82f330f4af | ||
![]() |
14f86107e1 | ||
![]() |
845faf9066 | ||
![]() |
7c2b801ee9 | ||
![]() |
f96dca5653 | ||
![]() |
0e4e9f4253 | ||
![]() |
dc38f8c041 | ||
![]() |
17f544be36 | ||
![]() |
fb59e84def | ||
![]() |
de8e33e647 | ||
![]() |
cf1bbc603e | ||
![]() |
ecc60e59d8 | ||
![]() |
e7be6faf2f | ||
![]() |
9e3076dde6 | ||
![]() |
35103206cf | ||
![]() |
29cf00560f | ||
![]() |
9ef9302808 | ||
![]() |
616b436648 | ||
![]() |
702e975d57 | ||
![]() |
6c90016c0c | ||
![]() |
90152a7eed | ||
![]() |
dabd95655b | ||
![]() |
4f938e3ea8 | ||
![]() |
f21a721ddb | ||
![]() |
7d65e60750 | ||
![]() |
c87f1b3949 | ||
![]() |
08b471fd1e | ||
![]() |
4a0d2dcc57 | ||
![]() |
91eae526f9 | ||
![]() |
11fd2db5a5 | ||
![]() |
75e7ce81c2 | ||
![]() |
345602926e | ||
![]() |
780ea4c631 | ||
![]() |
cf9d87a7d8 | ||
![]() |
3f2d6f0cee | ||
![]() |
22cf450d07 | ||
![]() |
8bd7233756 | ||
![]() |
2807a71e0e | ||
![]() |
b60bcda109 | ||
![]() |
4d36165cdf | ||
![]() |
44de6e5459 | ||
![]() |
d31c593d4b | ||
![]() |
0473029277 | ||
![]() |
3bef19cbfe | ||
![]() |
79fc4850ed | ||
![]() |
7cf24e906a | ||
![]() |
9870d38cbb | ||
![]() |
994604271b | ||
![]() |
81f2c7e91c | ||
![]() |
b0788e491e | ||
![]() |
0faed4e6b0 | ||
![]() |
73a3a9aca9 | ||
![]() |
1dfe9db7da | ||
![]() |
fa56b1d15f | ||
![]() |
b31c5d41ca | ||
![]() |
df22e39b4e | ||
![]() |
08d1e2cc07 | ||
![]() |
569558aea5 | ||
![]() |
2ceb41324d | ||
![]() |
d95e55137a | ||
![]() |
57b7173237 | ||
![]() |
ce8570c656 | ||
![]() |
d8e6f0ec57 | ||
![]() |
b4948c924d | ||
![]() |
7c36d3a892 | ||
![]() |
9aedd68f1c | ||
![]() |
0afd9c638a | ||
![]() |
3b4eceed87 | ||
![]() |
7c7c27847f | ||
![]() |
95398b4f06 | ||
![]() |
6857d0ad24 | ||
![]() |
2cfef12289 | ||
![]() |
a3c443e69b | ||
![]() |
31ce2ca545 | ||
![]() |
12d8340114 | ||
![]() |
a4d5c98e12 | ||
![]() |
12b60b5a9e | ||
![]() |
213f8114ba | ||
![]() |
c8a2482fc1 | ||
![]() |
8478fb7580 | ||
![]() |
cc10d9f233 | ||
![]() |
805f0f4e0d | ||
![]() |
c5eb78602a | ||
![]() |
d7b5ab8595 | ||
![]() |
562cfd57a6 | ||
![]() |
3d84d12c96 | ||
![]() |
2a71dafb0e | ||
![]() |
02e2bcdbc2 | ||
![]() |
19b496b5c8 | ||
![]() |
5c03cab5a2 | ||
![]() |
183f9f5649 | ||
![]() |
a46b75bef7 | ||
![]() |
f6e0d7d239 | ||
![]() |
6d893a1ac3 | ||
![]() |
175509abc8 | ||
![]() |
8900ece8ab | ||
![]() |
37dc039de4 | ||
![]() |
15b6afb11e | ||
![]() |
753913ccc7 | ||
![]() |
27d4f2108e | ||
![]() |
2fb045e94a | ||
![]() |
7756e8da41 | ||
![]() |
823e06b84e | ||
![]() |
f12571d767 | ||
![]() |
bf1e3a1a53 | ||
![]() |
6276789738 | ||
![]() |
4b66273c19 | ||
![]() |
0fad901ecb | ||
![]() |
3426e66b3b | ||
![]() |
b85721e584 | ||
![]() |
16c2e5521a | ||
![]() |
42d8c30147 | ||
![]() |
338a4cbf6e | ||
![]() |
813c449065 | ||
![]() |
03549b97aa | ||
![]() |
7ee03a9e03 | ||
![]() |
8c6ae89204 | ||
![]() |
d5c902eb82 | ||
![]() |
8a037295d0 | ||
![]() |
c4caa62f8b | ||
![]() |
d3ea4135b9 | ||
![]() |
d0d62eeae9 | ||
![]() |
aa6e7b148b | ||
![]() |
251a631523 | ||
![]() |
4dd49985c3 | ||
![]() |
c24368f8f9 | ||
![]() |
6b35da8ad0 | ||
![]() |
026fa22a37 | ||
![]() |
9d6d5265e2 | ||
![]() |
a86c30fdd4 | ||
![]() |
378b63a658 | ||
![]() |
e09092bbaf | ||
![]() |
ffdce26639 | ||
![]() |
797eff5200 | ||
![]() |
b942689dad | ||
![]() |
9479eb20b7 | ||
![]() |
79d87f4809 | ||
![]() |
3a0d99acbe | ||
![]() |
6b3f42a667 | ||
![]() |
a2d9954a1d | ||
![]() |
f5fa7b5217 | ||
![]() |
bab4620c04 | ||
![]() |
c0b665062e | ||
![]() |
117022151b | ||
![]() |
a96b7cfca9 | ||
![]() |
d8b83c6b07 | ||
![]() |
0594e1c52d |
100
.github/appveyor.yml
vendored
Normal file
100
.github/appveyor.yml
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
version: 0.7.{build}
|
||||
skip_tags: true
|
||||
image: Visual Studio 2015
|
||||
configuration: Release
|
||||
assembly_info:
|
||||
patch: true
|
||||
file: '**\AssemblyInfo.*'
|
||||
assembly_version: '{version}'
|
||||
assembly_file_version: '{version}'
|
||||
assembly_informational_version: '{version}'
|
||||
install:
|
||||
- cmd: choco install InnoSetup
|
||||
before_build:
|
||||
- cmd: nuget restore src\Jackett.sln
|
||||
build:
|
||||
verbosity: minimal
|
||||
after_build:
|
||||
- cmd: >-
|
||||
xcopy src\Jackett.Console\bin\Release build.windows\ /e /y
|
||||
|
||||
copy /Y src\Jackett.Service\bin\Release\JackettService.exe* %APPVEYOR_BUILD_FOLDER%\build.windows\
|
||||
|
||||
copy /Y src\Jackett.Tray\bin\Release\JackettTray.exe* %APPVEYOR_BUILD_FOLDER%\build.windows\
|
||||
|
||||
copy /Y src\Jackett.Updater\bin\Release\JackettUpdater.exe* %APPVEYOR_BUILD_FOLDER%\build.windows\
|
||||
|
||||
copy /Y LICENSE build.windows\LICENSE
|
||||
|
||||
copy /Y README.md build.windows\README.md
|
||||
|
||||
|
||||
xcopy build.windows WindowsBuild\Jackett\ /e /y
|
||||
|
||||
|
||||
msbuild src\Jackett.sln /t:Clean /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
||||
|
||||
"C:\Program Files (x86)\Mono\bin\xbuild.bat" src\Jackett.sln /t:Build /p:Configuration=Release /verbosity:minimal /tv:12.0
|
||||
|
||||
|
||||
xcopy src\Jackett.Console\bin\Release build.mono\ /e /y
|
||||
|
||||
copy /Y src\Jackett.Service\bin\Release\JackettService.exe* %APPVEYOR_BUILD_FOLDER%\build.mono\
|
||||
|
||||
copy /Y src\Jackett.Tray\bin\Release\JackettTray.exe* %APPVEYOR_BUILD_FOLDER%\build.mono\
|
||||
|
||||
copy /Y src\Jackett.Updater\bin\Release\JackettUpdater.exe* %APPVEYOR_BUILD_FOLDER%\build.mono\
|
||||
|
||||
copy /Y LICENSE build.mono\LICENSE
|
||||
|
||||
copy /Y README.md build.mono\README.md
|
||||
|
||||
copy /Y Upstart.config build.mono\Upstart.config
|
||||
|
||||
|
||||
xcopy build.mono MonoBuild\Jackett\ /e /y
|
||||
|
||||
|
||||
"C:\Program Files (x86)\Inno Setup 5\ISCC.exe" Installer.iss
|
||||
|
||||
RENAME Output\setup.exe Jackett.Installer.Windows.exe
|
||||
|
||||
MOVE Output\Jackett.Installer.Windows.exe %APPVEYOR_BUILD_FOLDER%
|
||||
|
||||
|
||||
cd WindowsBuild
|
||||
|
||||
7z a -tzip -r "%APPVEYOR_BUILD_FOLDER%\Jackett.Binaries.Windows.zip" "Jackett\"
|
||||
|
||||
|
||||
cd %APPVEYOR_BUILD_FOLDER%
|
||||
|
||||
cd MonoBuild
|
||||
|
||||
7z a -ttar "%APPVEYOR_BUILD_FOLDER%\Jackett.Binaries.Mono.tar" "Jackett\"
|
||||
|
||||
cd %APPVEYOR_BUILD_FOLDER%
|
||||
|
||||
7z a -tgzip "Jackett.Binaries.Mono.tar.gz" "Jackett.Binaries.Mono.tar"
|
||||
|
||||
|
||||
appveyor PushArtifact Jackett.Installer.Windows.exe
|
||||
|
||||
appveyor PushArtifact Jackett.Binaries.Windows.zip
|
||||
|
||||
appveyor PushArtifact Jackett.Binaries.Mono.tar.gz
|
||||
deploy:
|
||||
- provider: GitHub
|
||||
tag: v$(appveyor_build_version)
|
||||
auth_token:
|
||||
secure: hOg+16YTIbq4kO9u4D1YVOTbWDqgCX6mAQYMbnmBBSw2CiUsZh7OKbupoUb3FtWa
|
||||
draft: true
|
||||
on:
|
||||
branch: master
|
||||
notifications:
|
||||
- provider: GitHubPullRequest
|
||||
auth_token:
|
||||
secure: k6ZZACPbKcvAFiXe/uOmY6Ofs4aw2rgKEWMNA8EilQpdJ6o7ef31we4DPn3SXZzx
|
||||
on_build_success: true
|
||||
on_build_failure: true
|
||||
on_build_status_changed: true
|
618
README.md
618
README.md
@@ -1,278 +1,340 @@
|
||||
# Jackett
|
||||
|
||||
[](https://github.com/Jackett/Jackett/issues)
|
||||
[](https://github.com/Jackett/Jackett/pulls)
|
||||
[](https://github.com/Jackett/Jackett/releases/latest)
|
||||
[](https://hub.docker.com/r/linuxserver/jackett/)
|
||||
|
||||
This project is a new fork and is recruiting development help. If you are able to help out please contact us.
|
||||
|
||||
Jackett works as a proxy server: it translates queries from apps ([Sonarr](https://github.com/Sonarr/Sonarr), [Radarr](https://github.com/Radarr/Radarr), [SickRage](https://sickrage.github.io/), [CouchPotato](https://couchpota.to/), [Mylar](https://github.com/evilhero/mylar), etc) into tracker-site-specific http queries, parses the html response, then sends results back to the requesting software. This allows for getting recent uploads (like RSS) and performing searches. Jackett is a single repository of maintained indexer scraping & translation logic - removing the burden from other apps.
|
||||
|
||||
Developer note: The software implements the [Torznab](https://github.com/Sonarr/Sonarr/wiki/Implementing-a-Torznab-indexer) (with [nZEDb](https://github.com/nZEDb/nZEDb/blob/dev/docs/newznab_api_specification.txt) category numbering) and [TorrentPotato](https://github.com/RuudBurger/CouchPotatoServer/wiki/Couchpotato-torrent-provider) APIs.
|
||||
|
||||
|
||||
|
||||
#### Supported Systems
|
||||
* Windows using .NET 4.5
|
||||
* Linux and OSX using Mono 4 (mono 3 is no longer supported).
|
||||
|
||||
### Supported Public Trackers
|
||||
* EZTV
|
||||
* Il Corsaro Nero <!-- maintained by bonny1992 -->
|
||||
* Isohunt
|
||||
* KickAssTorrent
|
||||
* KickAssTorrent (kat.how clone)
|
||||
* LimeTorrents
|
||||
* Nyaa <!-- maintained by bonny1992 -->
|
||||
* RARBG
|
||||
* ShowRSS
|
||||
* Sky torrents
|
||||
* The Pirate Bay
|
||||
* TNTVillage <!-- maintained by bonny1992 -->
|
||||
* TorrentProject
|
||||
* Torrentz2
|
||||
|
||||
### Supported Private Trackers
|
||||
* 2 Fast 4 You
|
||||
* 3D Torrents
|
||||
* 7tor
|
||||
* Abnormal
|
||||
* Acid-Lounge
|
||||
* AlphaRatio
|
||||
* Andraste
|
||||
* AnimeBytes
|
||||
* AnimeTorrents
|
||||
* AOX
|
||||
* Apollo (XANAX)
|
||||
* ArabaFenice
|
||||
* AsianDVDClub
|
||||
* Audiobook Torrents
|
||||
* Avistaz
|
||||
* BakaBT [![(invite needed)][inviteneeded]](#)
|
||||
* bB
|
||||
* Best Friends
|
||||
* BeyondHD
|
||||
* BIGTorrent
|
||||
* Bit-City Reloaded
|
||||
* BIT-HDTV
|
||||
* BitHQ
|
||||
* BitHUmen
|
||||
* BitMeTV
|
||||
* BitSoup [![(invite needed)][inviteneeded]](#)
|
||||
* Bitspyder
|
||||
* Blu-bits
|
||||
* BlueBird
|
||||
* BroadcastTheNet [![(invite needed)][inviteneeded]](#)
|
||||
* BTN
|
||||
* BTNext
|
||||
* Carpathians
|
||||
* CHDBits
|
||||
* Cinematik
|
||||
* Cinemageddon
|
||||
* CinemaZ
|
||||
* Classix
|
||||
* CZTeam
|
||||
* DanishBits
|
||||
* DataScene
|
||||
* Demonoid
|
||||
* Diablo Torrent
|
||||
* DigitalHive
|
||||
* Dragon World (DTW)
|
||||
* Dragonworld Reloaded
|
||||
* Dream Team
|
||||
* EoT-Forum
|
||||
* eStone
|
||||
* Ethor.net (Thor's Land)
|
||||
* FANO.IN
|
||||
* FileList
|
||||
* Freedom-HD
|
||||
* Freshon
|
||||
* FullMixMusic
|
||||
* FunFile
|
||||
* FunkyTorrents
|
||||
* Fuzer
|
||||
* GFXPeers
|
||||
* Ghost City
|
||||
* GigaTorrents [![(invite needed)][inviteneeded]](#)
|
||||
* GimmePeers <!-- maintained by jamesb2147 -->
|
||||
* GODS [![(invite needed)][inviteneeded]](#)
|
||||
* Gormogon
|
||||
* Greek Team
|
||||
* Hardbay
|
||||
* HD4Free
|
||||
* HD-Space
|
||||
* HD-Torrents
|
||||
* HD-Bits.com
|
||||
* HDBits
|
||||
* HDChina
|
||||
* HDClub
|
||||
* HDHome
|
||||
* HDSky
|
||||
* HDTorrents.it
|
||||
* Hebits
|
||||
* Hon3y HD
|
||||
* Hounddawgs
|
||||
* House-of-Torrents
|
||||
* Hyperay
|
||||
* ICE Torrent
|
||||
* I Love Classics
|
||||
* Immortalseed
|
||||
* Infinity-T
|
||||
* inPeril
|
||||
* Insane Tracker
|
||||
* IPTorrents
|
||||
* JPopsuki
|
||||
* Kapaki
|
||||
* Karagarga
|
||||
* Le Paradis Du Net
|
||||
* LinkoManija
|
||||
* LosslessClub
|
||||
* M-Team - TP
|
||||
* Magico
|
||||
* Majomparádé
|
||||
* Mononoké-BT
|
||||
* MoreThanTV
|
||||
* MyAnonamouse
|
||||
* myAmity
|
||||
* MySpleen
|
||||
* Nachtwerk
|
||||
* NCore
|
||||
* NetHD
|
||||
* New Real World
|
||||
* NextGen
|
||||
* Norbits [![(invite needed)][inviteneeded]](#) <!-- added by DiseaseNO but no longer maintained? -->
|
||||
* notwhat.cd
|
||||
* Ourbits
|
||||
* Passione Torrent <!-- maintained by bonny1992 -->
|
||||
* PassThePopcorn [![(invite needed)][inviteneeded]](#)
|
||||
* PirateTheNet
|
||||
* PiXELHD
|
||||
* PolishSource
|
||||
* PolishTracker
|
||||
* Pretome
|
||||
* PrivateHD
|
||||
* Psytorrents
|
||||
* PTFiles
|
||||
* QcTorrent
|
||||
* Redacted (PassTheHeadphones)
|
||||
* RevolutionTT
|
||||
* Rockhard Lossless
|
||||
* RoDVD
|
||||
* RuTracker
|
||||
* SceneAccess
|
||||
* SceneFZ
|
||||
* SceneTime
|
||||
* SDBits
|
||||
* Secret Cinema
|
||||
* Shareisland
|
||||
* ShareSpaceDB
|
||||
* Shazbat
|
||||
* Shellife
|
||||
* SpeedCD
|
||||
* Superbits
|
||||
* Tasmanit
|
||||
* The Empire
|
||||
* The Horror Charnel
|
||||
* The New Retro
|
||||
* The Shinning
|
||||
* The-Torrents
|
||||
* TehConnection
|
||||
* TenYardTracker
|
||||
* Torrent Network
|
||||
* Torrent Sector Crew
|
||||
* Torrent411
|
||||
* Torrent9
|
||||
* TorrentBD
|
||||
* TorrentBytes
|
||||
* TorrentCCF [![(invite needed)][inviteneeded]](#)
|
||||
* TorrentDay
|
||||
* TorrentHeaven
|
||||
* TorrentHR
|
||||
* Torrenting
|
||||
* TorrentLeech
|
||||
* Torrents.Md
|
||||
* Torrent-Syndikat
|
||||
* ToTheGlory
|
||||
* TranceTraffic
|
||||
* TransmitheNet
|
||||
* TV Chaos UK
|
||||
* TV-Vault
|
||||
* u-Torrent
|
||||
* UHDBits
|
||||
* Ultimate Gamer Club
|
||||
* ULTRAHDCLUB
|
||||
* Waffles
|
||||
* World-In-HD [![(invite needed)][inviteneeded]](#)
|
||||
* WorldOfP2P
|
||||
* x264
|
||||
* XSpeeds
|
||||
* Xthor
|
||||
* Xtreme Zone
|
||||
* Ztracker
|
||||
|
||||
Trackers marked with [![(invite needed)][inviteneeded]](#) have no active maintainer and are missing features or are broken. If you have an invite for them please send it to kaso1717 -at- gmail.com to get them fixed/improved.
|
||||
|
||||
## Installation on Windows
|
||||
|
||||
We recommend you install Jackett as a Windows service using the supplied installer. You may also download the zipped version if you would like to configure everything manually.
|
||||
|
||||
To get started with using the installer for Jackett, follow the steps below:
|
||||
|
||||
1. Download the latest version of the Windows installer, "Jackett.Installer.Windows.exe" from the [releases](https://github.com/Jackett/Jackett/releases/latest) page.
|
||||
2. When prompted if you would like this app to make changes to your computer, select "yes".
|
||||
3. If you would like to install Jackett as a Windows Service, make sure the "Install as Windows Service" checkbox is filled.
|
||||
4. Once the installation has finished, check the "Launch Jackett" box to get started.
|
||||
5. Navigate your web browser to: http://127.0.0.1:9117
|
||||
6. You're now ready to begin adding your trackers and using Jackett.
|
||||
|
||||
When installed as a service the tray icon acts as a way to open/start/stop Jackett. If you opted to not install it as a service then Jackett will run its web server from the tray tool.
|
||||
|
||||
Jackett can also be run from the command line if you would like to see log messages (Ensure the server isn't already running from the tray/service). This can be done by using "JackettConsole.exe" (for Command Prompt), found in the Jackett data folder: "%ProgramData%\Jackett".
|
||||
|
||||
## Installation on Linux/OSX
|
||||
1. Install [Mono 4](http://www.mono-project.com/download/#download-lin) or better (version 4.8 is recommended)
|
||||
* Follow the instructions on the mono website and install the `mono-devel` and the `ca-certificates-mono` packages.
|
||||
* On Red Hat/CentOS/openSUSE/Fedora the `mono-locale-extras` package is also required.
|
||||
2. Install libcurl:
|
||||
* Debian/Ubunutu: `apt-get install libcurl4-openssl-dev`
|
||||
* Redhat/Fedora: `yum install libcurl-devel`
|
||||
* For other distros see the [Curl docs](http://curl.haxx.se/dlwiz/?type=devel).
|
||||
3. Download and extract the latest `Jackett.Binaries.Mono.tar.gz` release from the [releases page](https://github.com/Jackett/Jackett/releases) and run Jackett using mono with the command `mono --debug JackettConsole.exe`.
|
||||
|
||||
Detailed instructions for [Ubuntu 14.x](http://www.htpcguides.com/install-jackett-on-ubuntu-14-x-for-custom-torrents-in-sonarr/) and [Ubuntu 15.x](http://www.htpcguides.com/install-jackett-ubuntu-15-x-for-custom-torrents-in-sonarr/)
|
||||
|
||||
## Installation using Docker
|
||||
Detailed instructions are available at [LinuxServer.io Jackett Docker](https://hub.docker.com/r/linuxserver/jackett/). The Jackett Docker is highly recommended, especially if you are having Mono stability issues or having issues running Mono on your system eg. QNAP, Synology. Thanks to [LinuxServer.io](https://linuxserver.io)
|
||||
|
||||
## Installation on Synology
|
||||
Jackett is available as beta package from [SynoCommuniy](https://synocommunity.com/)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
* __Command line switches__
|
||||
|
||||
You can pass various options when running via the command line, see --help for details.
|
||||
|
||||
* __Unable to connect to trackers with invalid SSL certificates__
|
||||
|
||||
You can disable certificate validation using the `--IgnoreSslErrors true` option but it's not recommended to use it as it enables Man-in-the-middle attacks on your connections.
|
||||
|
||||
* __Enable logging__
|
||||
|
||||
You can get additional logging with the command line switches `-t -l` or by enabeling `Enhanced logging` via the web interface.
|
||||
Please post logs if you are unable to resolve your issue with these switches ensuring to remove your username/password/cookies.
|
||||
The logfiles (log.txt/updater.txt) are stored in `%ProgramData%\Jackett` on Windows and `~/.config/Jackett/` on Linux/OSX.
|
||||
|
||||
## Creating an issue
|
||||
Please supply as much information about the problem you are experiencing as possible. Your issue has a much greater chance of being resolved if logs are supplied so that we can see what is going on. Creating an issue with '### isn't working' doesn't help anyone to fix the problem.
|
||||
|
||||
## Contributing
|
||||
All contributions are welcome just send a pull request. Jackett's framework allows our team (and any other volunteering dev) to implement new trackers in an hour or two. If you'd like support for a new tracker but are not a developer then feel free to leave a request on the [issues page](https://github.com/Jackett/Jackett/issues). It is recommended to use Visual studio 2015 when making code changes in this project.
|
||||
|
||||
|
||||
## Screenshots
|
||||
|
||||

|
||||
|
||||
[inviteneeded]: https://raw.githubusercontent.com/Jackett/Jackett/master/.github/label-inviteneeded.png
|
||||
# Jackett
|
||||
|
||||
[](https://github.com/Jackett/Jackett/issues)
|
||||
[](https://github.com/Jackett/Jackett/pulls)
|
||||
[](https://www.bountysource.com/teams/jackett)
|
||||
[](https://ci.appveyor.com/project/camjac251/jackett)
|
||||
[](https://github.com/Jackett/Jackett/releases/latest)
|
||||
[](https://hub.docker.com/r/linuxserver/jackett/)
|
||||
[](https://discord.gg/J865QuA)
|
||||
|
||||
This project is a new fork and is recruiting development help. If you are able to help out please contact us.
|
||||
|
||||
Jackett works as a proxy server: it translates queries from apps ([Sonarr](https://github.com/Sonarr/Sonarr), [Radarr](https://github.com/Radarr/Radarr), [SickRage](https://sickrage.github.io/), [CouchPotato](https://couchpota.to/), [Mylar](https://github.com/evilhero/mylar), etc) into tracker-site-specific http queries, parses the html response, then sends results back to the requesting software. This allows for getting recent uploads (like RSS) and performing searches. Jackett is a single repository of maintained indexer scraping & translation logic - removing the burden from other apps.
|
||||
|
||||
Developer note: The software implements the [Torznab](https://github.com/Sonarr/Sonarr/wiki/Implementing-a-Torznab-indexer) (with [nZEDb](https://github.com/nZEDb/nZEDb/blob/dev/docs/newznab_api_specification.txt) category numbering) and [TorrentPotato](https://github.com/RuudBurger/CouchPotatoServer/wiki/Couchpotato-torrent-provider) APIs.
|
||||
|
||||
|
||||
|
||||
#### Supported Systems
|
||||
* Windows using .NET 4.5
|
||||
* Linux and macOS using Mono 4 (mono 3 is no longer supported).
|
||||
|
||||
### Supported Public Trackers
|
||||
* Anidex
|
||||
* Anime Tosho
|
||||
* AniRena
|
||||
* cpasbien
|
||||
* EZTV
|
||||
* Horrible Subs
|
||||
* Il Corsaro Nero <!-- maintained by bonny1992 -->
|
||||
* Isohunt
|
||||
* KickAssTorrent
|
||||
* KickAssTorrent (thekat.se clone)
|
||||
* LimeTorrents
|
||||
* NextTorrent
|
||||
* Nyaa.si
|
||||
* Nyaa-Pantsu
|
||||
* Nyoo
|
||||
* RARBG
|
||||
* ShowRSS
|
||||
* Sky torrents
|
||||
* T411 v2
|
||||
* The Pirate Bay
|
||||
* TNTVillage <!-- maintained by bonny1992 -->
|
||||
* Tokyo Toshokan
|
||||
* Torlock
|
||||
* Torrent Downloads
|
||||
* Torrent9
|
||||
* TorrentProject
|
||||
* Torrentz2
|
||||
* YTS.ag
|
||||
* zetorrents
|
||||
|
||||
### Supported Semi-Private Trackers
|
||||
* 7tor
|
||||
* CzTorrent
|
||||
* Deildu
|
||||
* Gay-Torrents.net
|
||||
* NetHD
|
||||
* RuTracker
|
||||
* TorrentBytes
|
||||
* Xtreme Zone
|
||||
* YggTorrent
|
||||
* Ztracker
|
||||
|
||||
### Supported Private Trackers
|
||||
* 2 Fast 4 You
|
||||
* 3D Torrents
|
||||
* Abnormal
|
||||
* Acid-Lounge
|
||||
* AlphaRatio
|
||||
* Andraste
|
||||
* AnimeBytes
|
||||
* AnimeTorrents
|
||||
* AOX
|
||||
* Apollo (XANAX)
|
||||
* ArabaFenice
|
||||
* Arche Torrent
|
||||
* AsianDVDClub
|
||||
* Audiobook Torrents
|
||||
* Awesome-HD
|
||||
* Avistaz
|
||||
* B2S-Share
|
||||
* BakaBT [![(invite needed)][inviteneeded]](#)
|
||||
* bB
|
||||
* BeyondHD
|
||||
* BIGTorrent
|
||||
* Bit-City Reloaded
|
||||
* BIT-HDTV
|
||||
* BitHQ
|
||||
* BitHUmen
|
||||
* BitMeTV
|
||||
* BitSoup [![(invite needed)][inviteneeded]](#)
|
||||
* Bitspyder
|
||||
* BJ-Share
|
||||
* Blu-bits
|
||||
* BlueBird
|
||||
* Blutopia
|
||||
* BroadcastTheNet
|
||||
* BrokenStones
|
||||
* BTNext
|
||||
* Carpathians
|
||||
* CGPeers
|
||||
* CHDBits
|
||||
* Cinematik
|
||||
* Cinemageddon
|
||||
* CinemaZ
|
||||
* Classix
|
||||
* CZTeam
|
||||
* DanishBits
|
||||
* DataScene
|
||||
* Demonoid
|
||||
* Diablo Torrent
|
||||
* DigitalHive
|
||||
* Dragonworld Reloaded
|
||||
* Dream Team
|
||||
* Elite-Tracker
|
||||
* EoT-Forum
|
||||
* eStone
|
||||
* Ethor.net (Thor's Land)
|
||||
* FANO.IN
|
||||
* FileList
|
||||
* Freedom-HD
|
||||
* FullMixMusic
|
||||
* FunFile
|
||||
* FunkyTorrents
|
||||
* Fuzer
|
||||
* GayTorrent.ru
|
||||
* GFTracker
|
||||
* GFXPeers
|
||||
* Ghost City
|
||||
* GigaTorrents [![(invite needed)][inviteneeded]](#)
|
||||
* GimmePeers <!-- maintained by jamesb2147 -->
|
||||
* GODS [![(invite needed)][inviteneeded]](#)
|
||||
* Gormogon
|
||||
* Greek Team
|
||||
* Hardbay
|
||||
* HD-Forever
|
||||
* HD-Only
|
||||
* HD-Space
|
||||
* HD-Torrents
|
||||
* HD-Bits.com
|
||||
* HD4Free
|
||||
* HDBits
|
||||
* HDChina
|
||||
* HDClub
|
||||
* HDHome
|
||||
* HDME
|
||||
* HDSky
|
||||
* HDTorrents.it
|
||||
* Hebits
|
||||
* Hon3y HD
|
||||
* Hounddawgs
|
||||
* House-of-Torrents
|
||||
* Hyperay
|
||||
* ICE Torrent
|
||||
* I Love Classics
|
||||
* Immortalseed
|
||||
* Infinity-T
|
||||
* inPeril
|
||||
* Insane Tracker
|
||||
* IPTorrents
|
||||
* JPopsuki
|
||||
* Kapaki
|
||||
* Karagarga
|
||||
* LinkoManija
|
||||
* LosslessClub
|
||||
* M-Team - TP
|
||||
* Magico
|
||||
* Majomparádé
|
||||
* Manicomio Share
|
||||
* Mononoké-BT
|
||||
* MoreThanTV
|
||||
* MyAnonamouse
|
||||
* myAmity
|
||||
* MySpleen
|
||||
* NCore
|
||||
* Nebulance
|
||||
* New Real World
|
||||
* Norbits [![(invite needed)][inviteneeded]](#) <!-- added by DiseaseNO but no longer maintained? -->
|
||||
* notwhat.cd
|
||||
* Ourbits
|
||||
* Passione Torrent <!-- maintained by bonny1992 -->
|
||||
* PassThePopcorn [![(invite needed)][inviteneeded]](#)
|
||||
* PirateTheNet
|
||||
* PiXELHD
|
||||
* PolishSource
|
||||
* PolishTracker
|
||||
* Pretome
|
||||
* PrivateHD
|
||||
* Psytorrents
|
||||
* PTFiles
|
||||
* Redacted (PassTheHeadphones)
|
||||
* RevolutionTT
|
||||
* Rockhard Lossless
|
||||
* RoDVD
|
||||
* SceneAccess
|
||||
* SceneFZ
|
||||
* SceneTime
|
||||
* SDBits
|
||||
* Secret Cinema
|
||||
* Shareisland
|
||||
* ShareSpaceDB
|
||||
* Shazbat
|
||||
* Shellife
|
||||
* SpeedCD
|
||||
* SpeedTorrent Reloaded
|
||||
* SportsCult
|
||||
* SportHD
|
||||
* Superbits
|
||||
* Tasmanit
|
||||
* The Empire
|
||||
* The Geeks
|
||||
* The Horror Charnel
|
||||
* The Occult
|
||||
* The New Retro
|
||||
* The Place
|
||||
* The Shinning
|
||||
* The Show
|
||||
* The Vault
|
||||
* The-Torrents
|
||||
* TehConnection
|
||||
* TenYardTracker
|
||||
* Torrent Network
|
||||
* Torrent Sector Crew
|
||||
* TorrentBD
|
||||
* TorrentCCF [![(invite needed)][inviteneeded]](#)
|
||||
* TorrentDay
|
||||
* Torrentech
|
||||
* TorrentHeaven
|
||||
* TorrentHR
|
||||
* Torrenting
|
||||
* TorrentLeech
|
||||
* Torrents.Md
|
||||
* Torrent-Syndikat
|
||||
* TorViet
|
||||
* ToTheGlory
|
||||
* TranceTraffic
|
||||
* Trezzor
|
||||
* TV Chaos UK
|
||||
* TV-Vault
|
||||
* u-Torrent
|
||||
* UHDBits
|
||||
* Ultimate Gamer Club
|
||||
* ULTRAHDCLUB
|
||||
* Waffles
|
||||
* World-In-HD
|
||||
* WorldOfP2P
|
||||
* x264
|
||||
* XSpeeds
|
||||
* Xthor
|
||||
* Zamunda.net
|
||||
* Zelka.org
|
||||
|
||||
Trackers marked with [![(invite needed)][inviteneeded]](#) have no active maintainer and are missing features or are broken. If you have an invite for them please send it to kaso1717 -at- gmail.com to get them fixed/improved.
|
||||
|
||||
## Installation on Windows
|
||||
|
||||
We recommend you install Jackett as a Windows service using the supplied installer. You may also download the zipped version if you would like to configure everything manually.
|
||||
|
||||
To get started with using the installer for Jackett, follow the steps below:
|
||||
|
||||
1. Download the latest version of the Windows installer, "Jackett.Installer.Windows.exe" from the [releases](https://github.com/Jackett/Jackett/releases/latest) page.
|
||||
2. When prompted if you would like this app to make changes to your computer, select "yes".
|
||||
3. If you would like to install Jackett as a Windows Service, make sure the "Install as Windows Service" checkbox is filled.
|
||||
4. Once the installation has finished, check the "Launch Jackett" box to get started.
|
||||
5. Navigate your web browser to: http://127.0.0.1:9117
|
||||
6. You're now ready to begin adding your trackers and using Jackett.
|
||||
|
||||
When installed as a service the tray icon acts as a way to open/start/stop Jackett. If you opted to not install it as a service then Jackett will run its web server from the tray tool.
|
||||
|
||||
Jackett can also be run from the command line if you would like to see log messages (Ensure the server isn't already running from the tray/service). This can be done by using "JackettConsole.exe" (for Command Prompt), found in the Jackett data folder: "%ProgramData%\Jackett".
|
||||
|
||||
## Installation on Linux
|
||||
1. Install [Mono 4](http://www.mono-project.com/download/#download-lin) or better (version 4.8 is recommended)
|
||||
* Follow the instructions on the mono website and install the `mono-devel` and the `ca-certificates-mono` packages.
|
||||
* On Red Hat/CentOS/openSUSE/Fedora the `mono-locale-extras` package is also required.
|
||||
2. Install libcurl:
|
||||
* Debian/Ubunutu: `apt-get install libcurl4-openssl-dev`
|
||||
* Redhat/Fedora: `yum install libcurl-devel`
|
||||
* For other distros see the [Curl docs](http://curl.haxx.se/dlwiz/?type=devel).
|
||||
3. Download and extract the latest `Jackett.Binaries.Mono.tar.gz` release from the [releases page](https://github.com/Jackett/Jackett/releases) and run Jackett using mono with the command `mono --debug JackettConsole.exe`.
|
||||
|
||||
Detailed instructions for [Ubuntu 14.x](http://www.htpcguides.com/install-jackett-on-ubuntu-14-x-for-custom-torrents-in-sonarr/) and [Ubuntu 15.x](http://www.htpcguides.com/install-jackett-ubuntu-15-x-for-custom-torrents-in-sonarr/)
|
||||
|
||||
## Installation on macOS
|
||||
|
||||
### Prerequisites
|
||||
Install [Mono 4](http://www.mono-project.com/download/#download-mac) or better (version 4.8 is recommended).
|
||||
* Setup ssl support by running `curl -sS https://curl.haxx.se/ca/cacert.pem | cert-sync --user /dev/stdin`
|
||||
|
||||
### Install as service
|
||||
1. Download and extract the latest `Jackett.Binaries.Mono.tar.gz` release from the [releases page](https://github.com/Jackett/Jackett/releases).
|
||||
2. In Terminal, run the install script from the extracted directory using `./install_service_macos.sh`
|
||||
|
||||
The service will start on each logon. You can always stop it by running `launchctl unload ~/Library/LaunchAgents/org.user.Jackett.plist` from Terminal. You can start it again it using `launchctl load ~/Library/LaunchAgents/org.user.Jackett.plist`.
|
||||
Logs are stored as usual under `~/.config/Jackett/log.txt`.
|
||||
|
||||
### Run without installing as a service
|
||||
Download and extract the latest `Jackett.Binaries.Mono.tar.gz` release from the [releases page](https://github.com/Jackett/Jackett/releases) and run Jackett using mono with the command `mono --debug JackettConsole.exe`.
|
||||
|
||||
## Installation using Docker
|
||||
Detailed instructions are available at [LinuxServer.io Jackett Docker](https://hub.docker.com/r/linuxserver/jackett/). The Jackett Docker is highly recommended, especially if you are having Mono stability issues or having issues running Mono on your system eg. QNAP, Synology. Thanks to [LinuxServer.io](https://linuxserver.io)
|
||||
|
||||
## Installation on Synology
|
||||
Jackett is available as beta package from [SynoCommunity](https://synocommunity.com/)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
* __Command line switches__
|
||||
|
||||
You can pass various options when running via the command line, see --help for details.
|
||||
|
||||
* __Unable to connect to trackers with invalid SSL certificates__
|
||||
|
||||
If you're using mono this is often caused by missing ca-certificates.
|
||||
Try reimporting the certificates in this case:
|
||||
- On Linux: `wget -O - https://curl.haxx.se/ca/cacert.pem | cert-sync /dev/stdin`
|
||||
- On macOS: `curl -sS https://curl.haxx.se/ca/cacert.pem | cert-sync --user /dev/stdin`
|
||||
|
||||
As a option of last resort you can disable certificate validation using the `--IgnoreSslErrors true` option but it's not recommended to use it as it enables Man-in-the-middle attacks on your connections.
|
||||
|
||||
* __Enable logging__
|
||||
|
||||
You can get additional logging with the command line switches `-t -l` or by enabling `Enhanced logging` via the web interface.
|
||||
Please post logs if you are unable to resolve your issue with these switches ensuring to remove your username/password/cookies.
|
||||
The logfiles (log.txt/updater.txt) are stored in `%ProgramData%\Jackett` on Windows and `~/.config/Jackett/` on Linux/macOS.
|
||||
|
||||
## Creating an issue
|
||||
Please supply as much information about the problem you are experiencing as possible. Your issue has a much greater chance of being resolved if logs are supplied so that we can see what is going on. Creating an issue with '### isn't working' doesn't help anyone to fix the problem.
|
||||
|
||||
## Contributing
|
||||
All contributions are welcome just send a pull request. Jackett's framework allows our team (and any other volunteering dev) to implement new trackers in an hour or two. If you'd like support for a new tracker but are not a developer then feel free to leave a request on the [issues page](https://github.com/Jackett/Jackett/issues). It is recommended to use Visual studio 2015 when making code changes in this project.
|
||||
|
||||
|
||||
## Screenshots
|
||||
|
||||

|
||||
|
||||
[inviteneeded]: https://raw.githubusercontent.com/Jackett/Jackett/master/.github/label-inviteneeded.png
|
||||
|
@@ -94,8 +94,14 @@
|
||||
<MonoDevelop>
|
||||
<Properties>
|
||||
<Policies>
|
||||
<TextStylePolicy inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/x-csharp" />
|
||||
<CSharpFormattingPolicy IndentSwitchBody="True" IndentBlocksInsideExpressions="True" AnonymousMethodBraceStyle="NextLine" PropertyBraceStyle="NextLine" PropertyGetBraceStyle="NextLine" PropertySetBraceStyle="NextLine" EventBraceStyle="NextLine" EventAddBraceStyle="NextLine" EventRemoveBraceStyle="NextLine" StatementBraceStyle="NextLine" ElseNewLinePlacement="NewLine" CatchNewLinePlacement="NewLine" FinallyNewLinePlacement="NewLine" WhileNewLinePlacement="DoNotCare" ArrayInitializerWrapping="DoNotChange" ArrayInitializerBraceStyle="NextLine" BeforeMethodDeclarationParentheses="False" BeforeMethodCallParentheses="False" BeforeConstructorDeclarationParentheses="False" NewLineBeforeConstructorInitializerColon="NewLine" NewLineAfterConstructorInitializerColon="SameLine" BeforeDelegateDeclarationParentheses="False" NewParentheses="False" SpacesBeforeBrackets="False" inheritsSet="Mono" inheritsScope="text/x-csharp" scope="text/x-csharp" />
|
||||
<TextStylePolicy TabWidth="4" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" EolMarker="Native" FileWidth="80" TabsToSpaces="True" scope="text/x-csharp">
|
||||
<inheritsSet />
|
||||
<inheritsScope />
|
||||
</TextStylePolicy>
|
||||
<CSharpFormattingPolicy IndentBlock="True" IndentBraces="False" IndentSwitchSection="False" IndentSwitchCaseSection="True" LabelPositioning="OneLess" NewLinesForBracesInTypes="True" NewLinesForBracesInMethods="True" NewLinesForBracesInProperties="False" NewLinesForBracesInAccessors="False" NewLinesForBracesInAnonymousMethods="False" NewLinesForBracesInControlBlocks="False" NewLinesForBracesInAnonymousTypes="False" NewLinesForBracesInObjectCollectionArrayInitializers="False" NewLinesForBracesInLambdaExpressionBody="False" NewLineForElse="False" NewLineForCatch="False" NewLineForFinally="False" NewLineForMembersInObjectInit="False" NewLineForMembersInAnonymousTypes="False" NewLineForClausesInQuery="False" SpacingAfterMethodDeclarationName="True" SpaceWithinMethodDeclarationParenthesis="False" SpaceBetweenEmptyMethodDeclarationParentheses="False" SpaceAfterMethodCallName="True" SpaceWithinMethodCallParentheses="False" SpaceBetweenEmptyMethodCallParentheses="False" SpaceAfterControlFlowStatementKeyword="True" SpaceWithinExpressionParentheses="False" SpaceWithinCastParentheses="False" SpaceWithinOtherParentheses="False" SpaceAfterCast="False" SpacesIgnoreAroundVariableDeclaration="False" SpaceBeforeOpenSquareBracket="True" SpaceBetweenEmptySquareBrackets="False" SpaceWithinSquareBrackets="False" SpaceAfterColonInBaseTypeDeclaration="True" SpaceAfterComma="True" SpaceAfterDot="False" SpaceAfterSemicolonsInForStatement="True" SpaceBeforeColonInBaseTypeDeclaration="True" SpaceBeforeComma="False" SpaceBeforeDot="False" SpaceBeforeSemicolonsInForStatement="False" SpacingAroundBinaryOperator="Single" WrappingPreserveSingleLine="True" WrappingKeepStatementsOnSingleLine="True" PlaceSystemDirectiveFirst="True" scope="text/x-csharp">
|
||||
<inheritsSet />
|
||||
<inheritsScope />
|
||||
</CSharpFormattingPolicy>
|
||||
</Policies>
|
||||
</Properties>
|
||||
</MonoDevelop>
|
||||
|
@@ -60,7 +60,7 @@ namespace Jackett.Console
|
||||
[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\\\"")]
|
||||
[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.")]
|
||||
public string DataFolder { get; set; }
|
||||
|
||||
[Option(HelpText = "Don't restart after update")]
|
||||
|
@@ -153,6 +153,9 @@
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
<None Include="packages.config" />
|
||||
<Content Include="install_service_macos.sh">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CurlSharp\CurlSharp.csproj">
|
||||
@@ -182,4 +185,4 @@
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
||||
|
67
src/Jackett.Console/install_service_macos.sh
Executable file
67
src/Jackett.Console/install_service_macos.sh
Executable file
@@ -0,0 +1,67 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Stop and unload the service if it's running
|
||||
launchctl remove org.user.Jackett
|
||||
|
||||
# Check if we're running from Jackett's directory
|
||||
if [ ! -f ./JackettConsole.exe ]; then
|
||||
echo "Couldn't locate JackettConsole.exe. Are you running from the right directory?"
|
||||
exit 1
|
||||
fi
|
||||
jackettdir="$(pwd)"
|
||||
|
||||
# Check if mono is installed
|
||||
command -v mono >/dev/null 2>&1 || { echo >&2 "Jackett requires Mono but it's not installed. Aborting."; exit 1; }
|
||||
monodir="$(dirname $(command -v mono))"
|
||||
|
||||
# Check that no other service called Jackett is already running
|
||||
if [[ $(launchctl list | grep org.user.Jackett) ]]; then
|
||||
echo "Jackett already seems to be running as a service. Please stop it before running this script again."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Write the plist to LaunchAgents
|
||||
cat >~/Library/LaunchAgents/org.user.Jackett.plist <<EOL
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>EnvironmentVariables</key>
|
||||
<dict>
|
||||
<key>PATH</key>
|
||||
<string>/usr/bin:/bin:/usr/sbin:/sbin:${monodir}</string>
|
||||
</dict>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>Label</key>
|
||||
<string>org.user.Jackett</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>${monodir}/mono</string>
|
||||
<string>--debug</string>
|
||||
<string>JackettConsole.exe</string>
|
||||
<string>--NoRestart</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>WorkingDirectory</key>
|
||||
<string>${jackettdir}</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
EOL
|
||||
|
||||
# Run the agent
|
||||
launchctl load ~/Library/LaunchAgents/org.user.Jackett.plist
|
||||
|
||||
# Check that it's running
|
||||
if [[ $(launchctl list | grep org.user.Jackett) ]]; then
|
||||
echo "Agent successfully installed and launched!"
|
||||
else
|
||||
cat << EOL
|
||||
Could not launch agent. The installation might have failed.
|
||||
Please open an issue on https://github.com/Jackett/Jackett/issues and paste following information:
|
||||
Mono directory: \`${monodir}\`
|
||||
Jackett directory: \`${jackettdir}\`
|
||||
EOL
|
||||
fi
|
@@ -28,7 +28,12 @@ namespace JackettTest
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void InitIndexers()
|
||||
public IWebIndexer GetWebIndexer(string name)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void InitIndexers(IEnumerable<string> path)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
@@ -43,12 +48,7 @@ namespace JackettTest
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void InitCardigannIndexers(string path)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SortIndexers()
|
||||
public void InitAggregateIndexer()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
@@ -76,7 +76,7 @@ namespace Jackett.Updater
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
catch (ArgumentException e)
|
||||
catch (ArgumentException)
|
||||
{
|
||||
Engine.Logger.Info("Process " + pid.ToString() + " is already dead");
|
||||
}
|
||||
@@ -185,6 +185,12 @@ namespace Jackett.Updater
|
||||
"Definitions/rarbg.yml",
|
||||
"Definitions/t411.yml",
|
||||
"Definitions/hdbc.yml", // renamed to hdbitscom
|
||||
"Definitions/maniatorrent.yml",
|
||||
"Definitions/nyaa.yml",
|
||||
"Definitions/nachtwerk.yml",
|
||||
"Definitions/leparadisdunet.yml",
|
||||
"Definitions/qctorrent.yml",
|
||||
"Definitions/dragonworld.yml",
|
||||
};
|
||||
|
||||
foreach (var oldFIle in oldFiles)
|
||||
|
@@ -66,9 +66,9 @@ Global
|
||||
GlobalSection(MonoDevelopProperties) = preSolution
|
||||
Policies = $0
|
||||
$0.TextStylePolicy = $1
|
||||
$1.inheritsSet = VisualStudio
|
||||
$1.inheritsScope = text/plain
|
||||
$1.scope = text/x-csharp
|
||||
$1.TabsToSpaces = True
|
||||
$1.EolMarker = Unix
|
||||
$0.CSharpFormattingPolicy = $2
|
||||
$2.IndentSwitchBody = True
|
||||
$2.IndentBlocksInsideExpressions = True
|
||||
@@ -94,8 +94,27 @@ Global
|
||||
$2.BeforeDelegateDeclarationParentheses = False
|
||||
$2.NewParentheses = False
|
||||
$2.SpacesBeforeBrackets = False
|
||||
$2.inheritsSet = Mono
|
||||
$2.inheritsScope = text/x-csharp
|
||||
$2.scope = text/x-csharp
|
||||
$2.IndentSwitchSection = True
|
||||
$2.NewLinesForBracesInProperties = True
|
||||
$2.NewLinesForBracesInAccessors = True
|
||||
$2.NewLinesForBracesInAnonymousMethods = True
|
||||
$2.NewLinesForBracesInControlBlocks = True
|
||||
$2.NewLinesForBracesInAnonymousTypes = True
|
||||
$2.NewLinesForBracesInObjectCollectionArrayInitializers = True
|
||||
$2.NewLinesForBracesInLambdaExpressionBody = True
|
||||
$2.NewLineForElse = True
|
||||
$2.NewLineForCatch = True
|
||||
$2.NewLineForFinally = True
|
||||
$2.NewLineForMembersInObjectInit = True
|
||||
$2.NewLineForMembersInAnonymousTypes = True
|
||||
$2.NewLineForClausesInQuery = True
|
||||
$2.SpacingAfterMethodDeclarationName = False
|
||||
$2.SpaceAfterMethodCallName = False
|
||||
$2.SpaceBeforeOpenSquareBracket = False
|
||||
$0.TextStylePolicy = $3
|
||||
$3.FileWidth = 80
|
||||
$3.TabsToSpaces = True
|
||||
$3.scope = text/plain
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
1
src/Jackett/Content/css/bootstrap-multiselect.css
vendored
Normal file
1
src/Jackett/Content/css/bootstrap-multiselect.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
span.multiselect-native-select{position:relative}span.multiselect-native-select select{border:0!important;clip:rect(0 0 0 0)!important;height:1px!important;margin:-1px -1px -1px -3px!important;overflow:hidden!important;padding:0!important;position:absolute!important;width:1px!important;left:50%;top:30px}.multiselect-container{position:absolute;list-style-type:none;margin:0;padding:0}.multiselect-container .input-group{margin:5px}.multiselect-container>li{padding:0}.multiselect-container>li>a.multiselect-all label{font-weight:700}.multiselect-container>li.multiselect-group label{margin:0;padding:3px 20px 3px 20px;height:100%;font-weight:700}.multiselect-container>li.multiselect-group-clickable label{cursor:pointer}.multiselect-container>li>a{padding:0}.multiselect-container>li>a>label{margin:0;height:100%;cursor:pointer;font-weight:400;padding:3px 20px 3px 40px}.multiselect-container>li>a>label.radio,.multiselect-container>li>a>label.checkbox{margin:0}.multiselect-container>li>a>label>input[type=checkbox]{margin-bottom:5px}.btn-group>.btn-group:nth-child(2)>.multiselect.btn{border-top-left-radius:4px;border-bottom-left-radius:4px}.form-inline .multiselect-container label.checkbox,.form-inline .multiselect-container label.radio{padding:3px 20px 3px 40px}.form-inline .multiselect-container li a label.checkbox input[type=checkbox],.form-inline .multiselect-container li a label.radio input[type=radio]{margin-left:-20px;margin-right:0}
|
@@ -62,6 +62,10 @@ body {
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.setup-item-inputselect {
|
||||
max-width: 255px;
|
||||
}
|
||||
|
||||
[data-type=hiddendata]{
|
||||
display: none;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -62,6 +62,10 @@ body {
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.setup-item-inputselect {
|
||||
max-width: 255px;
|
||||
}
|
||||
|
||||
[data-type=hiddendata]{
|
||||
display: none;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
89
src/Jackett/Content/libs/api.js
Normal file
89
src/Jackett/Content/libs/api.js
Normal file
@@ -0,0 +1,89 @@
|
||||
var api = {
|
||||
version: "2.0",
|
||||
root: "/api",
|
||||
key: "",
|
||||
|
||||
getApiPath: function(category, action) {
|
||||
var path = this.root + "/v" + this.version + "/" + category;
|
||||
if (action !== undefined)
|
||||
path = path + "/" + action
|
||||
return path;
|
||||
},
|
||||
|
||||
getAllIndexers: function(callback) {
|
||||
return $.get(this.getApiPath("indexers"), callback);
|
||||
},
|
||||
|
||||
getServerConfig: function(callback) {
|
||||
return $.get(this.getApiPath("server", "config"), callback);
|
||||
},
|
||||
|
||||
getIndexerConfig: function(indexerId, callback) {
|
||||
return $.get(this.getApiPath("indexers", indexerId + "/config"), callback);
|
||||
},
|
||||
|
||||
updateIndexerConfig: function(indexerId, config, callback) {
|
||||
return $.ajax({
|
||||
url: this.getApiPath("indexers", indexerId + "/config"),
|
||||
type: 'POST',
|
||||
data: JSON.stringify(config),
|
||||
dataType: 'json',
|
||||
contentType: 'application/json',
|
||||
cache: false,
|
||||
success: callback
|
||||
});
|
||||
},
|
||||
|
||||
deleteIndexer: function(indexerId, callback) {
|
||||
return $.ajax({
|
||||
url: this.getApiPath("indexers", indexerId),
|
||||
type: 'DELETE',
|
||||
cache: false,
|
||||
success: callback
|
||||
});
|
||||
},
|
||||
|
||||
testIndexer: function(indexerId, callback) {
|
||||
return $.post(this.getApiPath("indexers", indexerId + "/test"), callback);
|
||||
},
|
||||
|
||||
resultsForIndexer: function(indexerId, query, callback) {
|
||||
return $.get(this.getApiPath("indexers", indexerId + "/results?apikey=" + this.key), query, callback);
|
||||
},
|
||||
|
||||
getServerCache: function(callback) {
|
||||
return $.get(this.getApiPath("indexers", "cache"), callback);
|
||||
},
|
||||
|
||||
getServerLogs: function(callback) {
|
||||
return $.get(this.getApiPath("server", "logs"), callback);
|
||||
},
|
||||
|
||||
updateServerConfig: function(serverConfig, callback) {
|
||||
return $.ajax({
|
||||
url: this.getApiPath("server", "config"),
|
||||
type: 'POST',
|
||||
data: JSON.stringify(serverConfig),
|
||||
dataType: 'json',
|
||||
contentType: 'application/json',
|
||||
cache: false,
|
||||
success: callback
|
||||
});
|
||||
},
|
||||
|
||||
updateServer: function(callback) {
|
||||
return $.post(this.getApiPath("server", "update"), callback);
|
||||
},
|
||||
|
||||
updateAdminPassword: function(password, callback) {
|
||||
return $.ajax({
|
||||
url: this.getApiPath("server", "adminpassword"),
|
||||
type: 'POST',
|
||||
data: JSON.stringify(password),
|
||||
dataType: 'json',
|
||||
contentType: 'application/json',
|
||||
cache: false,
|
||||
success: callback
|
||||
});
|
||||
}
|
||||
}
|
1716
src/Jackett/Content/libs/bootstrap-multiselect.js
vendored
Normal file
1716
src/Jackett/Content/libs/bootstrap-multiselect.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
src/Jackett/Content/libs/handlebarsextend.js
Normal file
6
src/Jackett/Content/libs/handlebarsextend.js
Normal file
@@ -0,0 +1,6 @@
|
||||
Handlebars.registerHelper('ifCond', function (v1, v2, options) {
|
||||
if(v1 === v2) {
|
||||
return options.fn(this);
|
||||
}
|
||||
return options.inverse(this);
|
||||
});
|
@@ -1,117 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<script src="jquery-2.1.3.min.js"></script>
|
||||
<script src="common.js"></script>
|
||||
<style>
|
||||
#formItemTemplateContainer {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
$(function () {
|
||||
|
||||
var urlParams = getUrlParams();
|
||||
|
||||
var jqxhr = $.post("get_config_form", JSON.stringify({ indexer: urlParams.indexer }), function (data) {
|
||||
populateForm(data.config);
|
||||
})
|
||||
.fail(function () {
|
||||
alert("error");
|
||||
});
|
||||
|
||||
$("#loginButton").click(function () {
|
||||
var data = { indexer: urlParams.indexer, config: {} };
|
||||
$("#formItems").children().each(function (i, item) {
|
||||
var $item = $(item);
|
||||
var type = $item.data("type");
|
||||
var id = $item.data("id");
|
||||
var $valEl = $item.find(".formItemValue").children().first();
|
||||
switch (type) {
|
||||
case "inputstring":
|
||||
data.config[id] = $valEl.val();
|
||||
break;
|
||||
case "inputbool":
|
||||
data.config[id] = $valEl.val();
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
var jqxhr = $.post("configure_indexer", JSON.stringify(data), function (data) {
|
||||
if (data.result == "error") {
|
||||
if (data.config) {
|
||||
populateForm(data.config);
|
||||
}
|
||||
alert(data.error);
|
||||
|
||||
}
|
||||
})
|
||||
.fail(function () {
|
||||
alert("error");
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function populateForm(data) {
|
||||
$("#formItems").empty();
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
$("#formItems").append(createFormItem(data[i]));
|
||||
}
|
||||
}
|
||||
|
||||
function createFormItem(itemData) {
|
||||
var $template = $("#formItemTemplate").clone();
|
||||
$template.attr("id", "item" + itemData.id);
|
||||
$template.data("id", itemData.id);
|
||||
$template.data("type", itemData.type);
|
||||
$template.attr("data-type", itemData.type);
|
||||
$template.data("value", itemData.value);
|
||||
$template.find(".formItemName").text(itemData.name);
|
||||
|
||||
$valueElement = $template.find(".formItemValue");
|
||||
|
||||
switch (itemData.type) {
|
||||
case "inputstring":
|
||||
$valueElement.append($("<input type='text'></input>").val(itemData.value));
|
||||
break;
|
||||
case "inputbool":
|
||||
$valueElement.append($("<input type='checkbox'></input>").prop("checked", itemData.value));
|
||||
break;
|
||||
case "displayimage":
|
||||
$valueElement.append($("<img src='" + itemData.value + "'>"));
|
||||
break;
|
||||
case "displayinfo":
|
||||
$valueElement.append($("<span></span>").text(itemData.value));
|
||||
break;
|
||||
}
|
||||
|
||||
return $template;
|
||||
}
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<div id="formItems">
|
||||
|
||||
</div>
|
||||
|
||||
<button id="loginButton">Login</button>
|
||||
|
||||
<div id="formItemTemplateContainer">
|
||||
<div id="formItemTemplate">
|
||||
<div class="formItemName"></div>
|
||||
<div class="formItemValue"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
@@ -1,595 +0,0 @@
|
||||
using Autofac;
|
||||
using AutoMapper;
|
||||
using Jackett.Indexers;
|
||||
using Jackett.Models;
|
||||
using Jackett.Services;
|
||||
using Jackett.Utils;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
using System.Web.Http.Results;
|
||||
using System.Web.Security;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Jackett.Controllers
|
||||
{
|
||||
[RoutePrefix("admin")]
|
||||
[JackettAuthorized]
|
||||
[JackettAPINoCache]
|
||||
public class AdminController : ApiController
|
||||
{
|
||||
private IConfigurationService config;
|
||||
private IIndexerManagerService indexerService;
|
||||
private IServerService serverService;
|
||||
private ISecuityService securityService;
|
||||
private IProcessService processService;
|
||||
private ICacheService cacheService;
|
||||
private Logger logger;
|
||||
private ILogCacheService logCache;
|
||||
private IUpdateService updater;
|
||||
|
||||
public AdminController(IConfigurationService config, IIndexerManagerService i, IServerService ss, ISecuityService s, IProcessService p, ICacheService c, Logger l, ILogCacheService lc, IUpdateService u)
|
||||
{
|
||||
this.config = config;
|
||||
indexerService = i;
|
||||
serverService = ss;
|
||||
securityService = s;
|
||||
processService = p;
|
||||
cacheService = c;
|
||||
logger = l;
|
||||
logCache = lc;
|
||||
updater = u;
|
||||
}
|
||||
|
||||
private async Task<JToken> ReadPostDataJson()
|
||||
{
|
||||
var content = await Request.Content.ReadAsStringAsync();
|
||||
return JObject.Parse(content);
|
||||
}
|
||||
|
||||
|
||||
private HttpResponseMessage GetFile(string path)
|
||||
{
|
||||
var result = new HttpResponseMessage(HttpStatusCode.OK);
|
||||
var mappedPath = Path.Combine(config.GetContentFolder(), path);
|
||||
var stream = new FileStream(mappedPath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
result.Content = new StreamContent(stream);
|
||||
result.Content.Headers.ContentType = new MediaTypeHeaderValue(MimeMapping.GetMimeMapping(mappedPath));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[AllowAnonymous]
|
||||
public RedirectResult Logout()
|
||||
{
|
||||
var ctx = Request.GetOwinContext();
|
||||
var authManager = ctx.Authentication;
|
||||
authManager.SignOut("ApplicationCookie");
|
||||
return Redirect("Admin/Dashboard");
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[HttpPost]
|
||||
[AllowAnonymous]
|
||||
public async Task<HttpResponseMessage> Dashboard()
|
||||
{
|
||||
if (Request.RequestUri.Query != null && Request.RequestUri.Query.Contains("logout"))
|
||||
{
|
||||
var file = GetFile("login.html");
|
||||
securityService.Logout(file);
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
if (securityService.CheckAuthorised(Request))
|
||||
{
|
||||
return GetFile("index.html");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
var formData = await Request.Content.ReadAsFormDataAsync();
|
||||
|
||||
if (formData != null && securityService.HashPassword(formData["password"]) == serverService.Config.AdminPassword)
|
||||
{
|
||||
var file = GetFile("index.html");
|
||||
securityService.Login(file);
|
||||
return file;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetFile("login.html");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Route("set_admin_password")]
|
||||
[HttpPost]
|
||||
public async Task<IHttpActionResult> SetAdminPassword()
|
||||
{
|
||||
var jsonReply = new JObject();
|
||||
try
|
||||
{
|
||||
var postData = await ReadPostDataJson();
|
||||
var password = (string)postData["password"];
|
||||
if (string.IsNullOrEmpty(password))
|
||||
{
|
||||
serverService.Config.AdminPassword = string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
serverService.Config.AdminPassword = securityService.HashPassword(password);
|
||||
}
|
||||
|
||||
serverService.SaveConfig();
|
||||
jsonReply["result"] = "success";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex, "Exception in SetAdminPassword");
|
||||
jsonReply["result"] = "error";
|
||||
jsonReply["error"] = ex.Message;
|
||||
}
|
||||
return Json(jsonReply);
|
||||
}
|
||||
|
||||
[Route("get_config_form")]
|
||||
[HttpPost]
|
||||
public async Task<IHttpActionResult> GetConfigForm()
|
||||
{
|
||||
var jsonReply = new JObject();
|
||||
try
|
||||
{
|
||||
var postData = await ReadPostDataJson();
|
||||
var indexer = indexerService.GetIndexer((string)postData["indexer"]);
|
||||
var config = await indexer.GetConfigurationForSetup();
|
||||
jsonReply["config"] = config.ToJson(null);
|
||||
jsonReply["caps"] = indexer.TorznabCaps.CapsToJson();
|
||||
jsonReply["name"] = indexer.DisplayName;
|
||||
jsonReply["alternativesitelinks"] = JToken.FromObject(indexer.AlternativeSiteLinks);
|
||||
jsonReply["result"] = "success";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex, "Exception in GetConfigForm");
|
||||
jsonReply["result"] = "error";
|
||||
jsonReply["error"] = ex.Message;
|
||||
}
|
||||
return Json(jsonReply);
|
||||
}
|
||||
|
||||
[Route("configure_indexer")]
|
||||
[HttpPost]
|
||||
public async Task<IHttpActionResult> Configure()
|
||||
{
|
||||
var jsonReply = new JObject();
|
||||
IIndexer indexer = null;
|
||||
try
|
||||
{
|
||||
var postData = await ReadPostDataJson();
|
||||
string indexerString = (string)postData["indexer"];
|
||||
indexer = indexerService.GetIndexer((string)postData["indexer"]);
|
||||
jsonReply["name"] = indexer.DisplayName;
|
||||
var configurationResult = await indexer.ApplyConfiguration(postData["config"]);
|
||||
if (configurationResult == IndexerConfigurationStatus.RequiresTesting)
|
||||
{
|
||||
await indexerService.TestIndexer((string)postData["indexer"]);
|
||||
}
|
||||
else if (configurationResult == IndexerConfigurationStatus.Failed)
|
||||
{
|
||||
throw new Exception("Configuration Failed");
|
||||
}
|
||||
jsonReply["result"] = "success";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
jsonReply["result"] = "error";
|
||||
jsonReply["error"] = ex.Message;
|
||||
var baseIndexer = indexer as BaseIndexer;
|
||||
if (null != baseIndexer)
|
||||
baseIndexer.ResetBaseConfig();
|
||||
if (ex is ExceptionWithConfigData)
|
||||
{
|
||||
jsonReply["config"] = ((ExceptionWithConfigData)ex).ConfigData.ToJson(null,false);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error(ex, "Exception in Configure");
|
||||
}
|
||||
}
|
||||
return Json(jsonReply);
|
||||
}
|
||||
|
||||
[Route("get_indexers")]
|
||||
[HttpGet]
|
||||
public IHttpActionResult Indexers()
|
||||
{
|
||||
var jsonReply = new JObject();
|
||||
try
|
||||
{
|
||||
jsonReply["result"] = "success";
|
||||
JArray items = new JArray();
|
||||
|
||||
foreach (var indexer in indexerService.GetAllIndexers())
|
||||
{
|
||||
var item = new JObject();
|
||||
item["id"] = indexer.ID;
|
||||
item["name"] = indexer.DisplayName;
|
||||
item["description"] = indexer.DisplayDescription;
|
||||
item["type"] = indexer.Type;
|
||||
item["configured"] = indexer.IsConfigured;
|
||||
item["site_link"] = indexer.SiteLink;
|
||||
item["language"] = indexer.Language;
|
||||
item["last_error"] = indexer.LastError;
|
||||
item["potatoenabled"] = indexer.TorznabCaps.Categories.Select(c => c.ID).Any(i => PotatoController.MOVIE_CATS.Contains(i));
|
||||
|
||||
var caps = new JObject();
|
||||
foreach (var cap in indexer.TorznabCaps.Categories)
|
||||
caps[cap.ID.ToString()] = cap.Name;
|
||||
item["caps"] = caps;
|
||||
items.Add(item);
|
||||
}
|
||||
jsonReply["items"] = items;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex, "Exception in get_indexers");
|
||||
jsonReply["result"] = "error";
|
||||
jsonReply["error"] = ex.Message;
|
||||
}
|
||||
return Json(jsonReply);
|
||||
}
|
||||
|
||||
[Route("test_indexer")]
|
||||
[HttpPost]
|
||||
public async Task<IHttpActionResult> Test()
|
||||
{
|
||||
JToken jsonReply = new JObject();
|
||||
IIndexer indexer = null;
|
||||
try
|
||||
{
|
||||
var postData = await ReadPostDataJson();
|
||||
string indexerString = (string)postData["indexer"];
|
||||
indexer = indexerService.GetIndexer(indexerString);
|
||||
await indexerService.TestIndexer(indexerString);
|
||||
jsonReply["name"] = indexer.DisplayName;
|
||||
jsonReply["result"] = "success";
|
||||
indexer.LastError = null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var msg = ex.Message;
|
||||
if (ex.InnerException != null)
|
||||
msg += ": " + ex.InnerException.Message;
|
||||
logger.Error(ex, "Exception in test_indexer");
|
||||
jsonReply["result"] = "error";
|
||||
jsonReply["error"] = msg;
|
||||
if (indexer != null)
|
||||
indexer.LastError = msg;
|
||||
}
|
||||
return Json(jsonReply);
|
||||
}
|
||||
|
||||
[Route("delete_indexer")]
|
||||
[HttpPost]
|
||||
public async Task<IHttpActionResult> Delete()
|
||||
{
|
||||
var jsonReply = new JObject();
|
||||
try
|
||||
{
|
||||
var postData = await ReadPostDataJson();
|
||||
string indexerString = (string)postData["indexer"];
|
||||
indexerService.DeleteIndexer(indexerString);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex, "Exception in delete_indexer");
|
||||
jsonReply["result"] = "error";
|
||||
jsonReply["error"] = ex.Message;
|
||||
}
|
||||
return Json(jsonReply);
|
||||
}
|
||||
|
||||
[Route("trigger_update")]
|
||||
[HttpGet]
|
||||
public IHttpActionResult TriggerUpdates()
|
||||
{
|
||||
var jsonReply = new JObject();
|
||||
updater.CheckForUpdatesNow();
|
||||
return Json(jsonReply);
|
||||
}
|
||||
|
||||
[Route("get_jackett_config")]
|
||||
[HttpGet]
|
||||
public IHttpActionResult GetConfig()
|
||||
{
|
||||
var jsonReply = new JObject();
|
||||
try
|
||||
{
|
||||
var cfg = new JObject();
|
||||
cfg["notices"] = JToken.FromObject(serverService.notices);
|
||||
cfg["port"] = serverService.Config.Port;
|
||||
cfg["external"] = serverService.Config.AllowExternal;
|
||||
cfg["api_key"] = serverService.Config.APIKey;
|
||||
cfg["blackholedir"] = serverService.Config.BlackholeDir;
|
||||
cfg["updatedisabled"] = serverService.Config.UpdateDisabled;
|
||||
cfg["prerelease"] = serverService.Config.UpdatePrerelease;
|
||||
cfg["password"] = string.IsNullOrEmpty(serverService.Config.AdminPassword) ? string.Empty : serverService.Config.AdminPassword.Substring(0, 10);
|
||||
cfg["logging"] = Startup.TracingEnabled;
|
||||
cfg["basepathoverride"] = serverService.Config.BasePathOverride;
|
||||
|
||||
|
||||
jsonReply["config"] = cfg;
|
||||
jsonReply["app_version"] = config.GetVersion();
|
||||
jsonReply["result"] = "success";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex, "Exception in get_jackett_config");
|
||||
jsonReply["result"] = "error";
|
||||
jsonReply["error"] = ex.Message;
|
||||
}
|
||||
return Json(jsonReply);
|
||||
}
|
||||
|
||||
[Route("set_config")]
|
||||
[HttpPost]
|
||||
public async Task<IHttpActionResult> SetConfig()
|
||||
{
|
||||
var originalPort = Engine.Server.Config.Port;
|
||||
var originalAllowExternal = Engine.Server.Config.AllowExternal;
|
||||
var jsonReply = new JObject();
|
||||
try
|
||||
{
|
||||
var postData = await ReadPostDataJson();
|
||||
int port = (int)postData["port"];
|
||||
bool external = (bool)postData["external"];
|
||||
string saveDir = (string)postData["blackholedir"];
|
||||
bool updateDisabled = (bool)postData["updatedisabled"];
|
||||
bool preRelease = (bool)postData["prerelease"];
|
||||
bool logging = (bool)postData["logging"];
|
||||
string basePathOverride = (string)postData["basepathoverride"];
|
||||
|
||||
Engine.Server.Config.UpdateDisabled = updateDisabled;
|
||||
Engine.Server.Config.UpdatePrerelease = preRelease;
|
||||
Engine.Server.Config.BasePathOverride = basePathOverride;
|
||||
Startup.BasePath = Engine.Server.BasePath();
|
||||
Engine.Server.SaveConfig();
|
||||
|
||||
Engine.SetLogLevel(logging ? LogLevel.Debug : LogLevel.Info);
|
||||
Startup.TracingEnabled = logging;
|
||||
|
||||
if (port != Engine.Server.Config.Port || external != Engine.Server.Config.AllowExternal)
|
||||
{
|
||||
|
||||
if (ServerUtil.RestrictedPorts.Contains(port))
|
||||
{
|
||||
jsonReply["result"] = "error";
|
||||
jsonReply["error"] = "The port you have selected is restricted, try a different one.";
|
||||
return Json(jsonReply);
|
||||
}
|
||||
|
||||
// Save port to the config so it can be picked up by the if needed when running as admin below.
|
||||
Engine.Server.Config.AllowExternal = external;
|
||||
Engine.Server.Config.Port = port;
|
||||
Engine.Server.SaveConfig();
|
||||
|
||||
// On Windows change the url reservations
|
||||
if (System.Environment.OSVersion.Platform != PlatformID.Unix)
|
||||
{
|
||||
if (!ServerUtil.IsUserAdministrator())
|
||||
{
|
||||
try
|
||||
{
|
||||
processService.StartProcessAndLog(Application.ExecutablePath, "--ReserveUrls", true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Engine.Server.Config.Port = originalPort;
|
||||
Engine.Server.Config.AllowExternal = originalAllowExternal;
|
||||
Engine.Server.SaveConfig();
|
||||
jsonReply["result"] = "error";
|
||||
jsonReply["error"] = "Failed to acquire admin permissions to reserve the new port.";
|
||||
return Json(jsonReply);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
serverService.ReserveUrls(true);
|
||||
}
|
||||
}
|
||||
|
||||
(new Thread(() =>
|
||||
{
|
||||
Thread.Sleep(500);
|
||||
serverService.Stop();
|
||||
Engine.BuildContainer();
|
||||
Engine.Server.Initalize();
|
||||
Engine.Server.Start();
|
||||
})).Start();
|
||||
}
|
||||
|
||||
if (saveDir != Engine.Server.Config.BlackholeDir)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(saveDir))
|
||||
{
|
||||
if (!Directory.Exists(saveDir))
|
||||
{
|
||||
throw new Exception("Blackhole directory does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
Engine.Server.Config.BlackholeDir = saveDir;
|
||||
Engine.Server.SaveConfig();
|
||||
}
|
||||
|
||||
jsonReply["result"] = "success";
|
||||
jsonReply["port"] = port;
|
||||
jsonReply["external"] = external;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex, "Exception in set_port");
|
||||
jsonReply["result"] = "error";
|
||||
jsonReply["error"] = ex.Message;
|
||||
}
|
||||
return Json(jsonReply);
|
||||
}
|
||||
|
||||
[Route("GetCache")]
|
||||
[HttpGet]
|
||||
public List<TrackerCacheResult> GetCache()
|
||||
{
|
||||
var results = cacheService.GetCachedResults();
|
||||
ConfigureCacheResults(results);
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
private void ConfigureCacheResults(List<TrackerCacheResult> results)
|
||||
{
|
||||
var serverUrl = string.Format("{0}://{1}:{2}{3}", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port, serverService.BasePath());
|
||||
foreach (var result in results)
|
||||
{
|
||||
var link = result.Link;
|
||||
result.Link = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "dl", result.Title + ".torrent");
|
||||
if (result.Link != null && result.Link.Scheme != "magnet" && !string.IsNullOrWhiteSpace(Engine.Server.Config.BlackholeDir))
|
||||
result.BlackholeLink = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "bh", string.Empty);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
[Route("GetLogs")]
|
||||
[HttpGet]
|
||||
public List<CachedLog> GetLogs()
|
||||
{
|
||||
return logCache.Logs;
|
||||
}
|
||||
|
||||
[Route("Search")]
|
||||
[HttpPost]
|
||||
public ManualSearchResult Search([FromBody]AdminSearch value)
|
||||
{
|
||||
var results = new List<TrackerCacheResult>();
|
||||
var stringQuery = new TorznabQuery();
|
||||
|
||||
var queryStr = value.Query;
|
||||
if (queryStr != null)
|
||||
{
|
||||
var seasonMatch = Regex.Match(queryStr, @"S(\d{2,4})");
|
||||
if (seasonMatch.Success)
|
||||
{
|
||||
stringQuery.Season = int.Parse(seasonMatch.Groups[1].Value);
|
||||
queryStr = queryStr.Remove(seasonMatch.Index, seasonMatch.Length);
|
||||
}
|
||||
|
||||
var episodeMatch = Regex.Match(queryStr, @"E(\d{2,4})");
|
||||
if (episodeMatch.Success)
|
||||
{
|
||||
stringQuery.Episode = episodeMatch.Groups[1].Value;
|
||||
queryStr = queryStr.Remove(episodeMatch.Index, episodeMatch.Length);
|
||||
}
|
||||
queryStr = queryStr.Trim();
|
||||
}
|
||||
|
||||
|
||||
stringQuery.SearchTerm = queryStr;
|
||||
stringQuery.Categories = value.Category == 0 ? new int[0] : new int[1] { value.Category };
|
||||
stringQuery.ExpandCatsToSubCats();
|
||||
|
||||
// try to build an IMDB Query
|
||||
var imdbID = ParseUtil.GetFullImdbID(stringQuery.SanitizedSearchTerm);
|
||||
TorznabQuery imdbQuery = null;
|
||||
if (imdbID != null)
|
||||
{
|
||||
imdbQuery = new TorznabQuery()
|
||||
{
|
||||
ImdbID = imdbID,
|
||||
Categories = stringQuery.Categories,
|
||||
Season = stringQuery.Season,
|
||||
Episode = stringQuery.Episode,
|
||||
};
|
||||
imdbQuery.ExpandCatsToSubCats();
|
||||
}
|
||||
|
||||
var trackers = indexerService.GetAllIndexers().Where(t => t.IsConfigured).ToList();
|
||||
if (!string.IsNullOrWhiteSpace(value.Tracker))
|
||||
{
|
||||
trackers = trackers.Where(t => t.ID == value.Tracker).ToList();
|
||||
}
|
||||
|
||||
if (value.Category != 0)
|
||||
{
|
||||
trackers = trackers.Where(t => t.TorznabCaps.Categories.Select(c => c.ID).Contains(value.Category)).ToList();
|
||||
}
|
||||
|
||||
Parallel.ForEach(trackers.ToList(), new ParallelOptions { MaxDegreeOfParallelism = 1000 }, indexer =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var query = stringQuery;
|
||||
// use imdb Query for trackers which support it
|
||||
if (imdbQuery != null && indexer.TorznabCaps.SupportsImdbSearch)
|
||||
query = imdbQuery;
|
||||
|
||||
var searchResults = indexer.PerformQuery(query).Result;
|
||||
searchResults = indexer.CleanLinks(searchResults);
|
||||
cacheService.CacheRssResults(indexer, searchResults);
|
||||
searchResults = indexer.FilterResults(query, searchResults);
|
||||
|
||||
foreach (var result in searchResults)
|
||||
{
|
||||
var item = Mapper.Map<TrackerCacheResult>(result);
|
||||
item.Tracker = indexer.DisplayName;
|
||||
item.TrackerId = indexer.ID;
|
||||
item.Peers = item.Peers - item.Seeders; // Use peers as leechers
|
||||
lock (results)
|
||||
{
|
||||
results.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.Error(e, "An error occured during manual search on " + indexer.DisplayName + ": " + e.Message);
|
||||
}
|
||||
});
|
||||
|
||||
ConfigureCacheResults(results);
|
||||
|
||||
if (trackers.Count > 1)
|
||||
{
|
||||
results = results.OrderByDescending(d => d.PublishDate).ToList();
|
||||
}
|
||||
|
||||
var manualResult = new ManualSearchResult()
|
||||
{
|
||||
Results = results,
|
||||
Indexers = trackers.Select(t => t.DisplayName).ToList()
|
||||
};
|
||||
|
||||
|
||||
if (manualResult.Indexers.Count == 0)
|
||||
manualResult.Indexers = new List<string>() { "None" };
|
||||
|
||||
logger.Info(string.Format("Manual search for \"{0}\" on {1} with {2} results.", stringQuery.GetQueryString(), string.Join(", ", manualResult.Indexers), manualResult.Results.Count));
|
||||
return manualResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using Jackett.Services;
|
||||
using Jackett.Utils;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
using System;
|
||||
@@ -22,34 +23,36 @@ namespace Jackett.Controllers
|
||||
private Logger logger;
|
||||
private IIndexerManagerService indexerService;
|
||||
IServerService serverService;
|
||||
IProtectionService protectionService;
|
||||
|
||||
public BlackholeController(IIndexerManagerService i, Logger l, IServerService s)
|
||||
public BlackholeController(IIndexerManagerService i, Logger l, IServerService s, IProtectionService ps)
|
||||
{
|
||||
logger = l;
|
||||
indexerService = i;
|
||||
serverService = s;
|
||||
protectionService = ps;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IHttpActionResult> Blackhole(string indexerID, string path, string apikey)
|
||||
public async Task<IHttpActionResult> Blackhole(string indexerID, string path, string jackett_apikey, string file)
|
||||
{
|
||||
|
||||
var jsonReply = new JObject();
|
||||
try
|
||||
{
|
||||
var indexer = indexerService.GetIndexer(indexerID);
|
||||
var indexer = indexerService.GetWebIndexer(indexerID);
|
||||
if (!indexer.IsConfigured)
|
||||
{
|
||||
logger.Warn(string.Format("Rejected a request to {0} which is unconfigured.", indexer.DisplayName));
|
||||
throw new Exception("This indexer is not configured.");
|
||||
}
|
||||
|
||||
if (serverService.Config.APIKey != apikey)
|
||||
if (serverService.Config.APIKey != jackett_apikey)
|
||||
throw new Exception("Incorrect API key");
|
||||
|
||||
var remoteFile = new Uri(Encoding.UTF8.GetString(HttpServerUtility.UrlTokenDecode(path)), UriKind.RelativeOrAbsolute);
|
||||
remoteFile = indexer.UncleanLink(remoteFile);
|
||||
|
||||
path = Encoding.UTF8.GetString(HttpServerUtility.UrlTokenDecode(path));
|
||||
path = protectionService.UnProtect(path);
|
||||
var remoteFile = new Uri(path, UriKind.RelativeOrAbsolute);
|
||||
var downloadBytes = await indexer.Download(remoteFile);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(Engine.Server.Config.BlackholeDir))
|
||||
@@ -62,7 +65,12 @@ namespace Jackett.Controllers
|
||||
throw new Exception("Blackhole directory does not exist: " + Engine.Server.Config.BlackholeDir);
|
||||
}
|
||||
|
||||
var fileName = DateTime.Now.Ticks + ".torrent";
|
||||
var fileName = DateTime.Now.Ticks.ToString() + "-" + StringUtil.MakeValidFileName(indexer.DisplayName, '_', false);
|
||||
if (string.IsNullOrWhiteSpace(file))
|
||||
fileName += ".torrent";
|
||||
else
|
||||
fileName += "-"+StringUtil.MakeValidFileName(file, '_', false); // call MakeValidFileName() again to avoid any possibility of path traversal attacks
|
||||
|
||||
File.WriteAllBytes(Path.Combine(Engine.Server.Config.BlackholeDir, fileName), downloadBytes);
|
||||
jsonReply["result"] = "success";
|
||||
}
|
||||
|
@@ -11,6 +11,7 @@ using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
using MonoTorrent.BEncoding;
|
||||
using Jackett.Utils;
|
||||
|
||||
namespace Jackett.Controllers
|
||||
{
|
||||
@@ -21,20 +22,22 @@ namespace Jackett.Controllers
|
||||
Logger logger;
|
||||
IIndexerManagerService indexerService;
|
||||
IServerService serverService;
|
||||
IProtectionService protectionService;
|
||||
|
||||
public DownloadController(IIndexerManagerService i, Logger l, IServerService s)
|
||||
public DownloadController(IIndexerManagerService i, Logger l, IServerService s, IProtectionService ps)
|
||||
{
|
||||
logger = l;
|
||||
indexerService = i;
|
||||
serverService = s;
|
||||
protectionService = ps;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<HttpResponseMessage> Download(string indexerID, string path, string apikey, string file)
|
||||
public async Task<HttpResponseMessage> Download(string indexerID, string path, string jackett_apikey, string file)
|
||||
{
|
||||
try
|
||||
{
|
||||
var indexer = indexerService.GetIndexer(indexerID);
|
||||
var indexer = indexerService.GetWebIndexer(indexerID);
|
||||
|
||||
if (!indexer.IsConfigured)
|
||||
{
|
||||
@@ -43,31 +46,24 @@ namespace Jackett.Controllers
|
||||
}
|
||||
|
||||
path = Encoding.UTF8.GetString(HttpServerUtility.UrlTokenDecode(path));
|
||||
path = protectionService.UnProtect(path);
|
||||
|
||||
if (serverService.Config.APIKey != apikey)
|
||||
if (serverService.Config.APIKey != jackett_apikey)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
var target = new Uri(path, UriKind.RelativeOrAbsolute);
|
||||
target = indexer.UncleanLink(target);
|
||||
|
||||
var downloadBytes = await indexer.Download(target);
|
||||
|
||||
// This will fix torrents where the keys are not sorted, and thereby not supported by Sonarr.
|
||||
var torrentDictionary = BEncodedDictionary.DecodeTorrent(downloadBytes);
|
||||
downloadBytes = torrentDictionary.Encode();
|
||||
|
||||
char[] invalidChars = System.IO.Path.GetInvalidFileNameChars();
|
||||
for(int i=0;i<file.Count();i++)
|
||||
if(invalidChars.Contains(file[i])) {
|
||||
file = file.Remove(i, 1).Insert(i, " ");
|
||||
}
|
||||
|
||||
var result = new HttpResponseMessage(HttpStatusCode.OK);
|
||||
result.Content = new ByteArrayContent(downloadBytes);
|
||||
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-bittorrent");
|
||||
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
|
||||
{
|
||||
FileName = file
|
||||
FileName = StringUtil.MakeValidFileName(file, '_', false) // call MakeValidFileName again to avoid any kind of injection attack
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
173
src/Jackett/Controllers/IndexerApiController.cs
Normal file
173
src/Jackett/Controllers/IndexerApiController.cs
Normal file
@@ -0,0 +1,173 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Http;
|
||||
using System.Web.Http.Controllers;
|
||||
using System.Web.Http.Filters;
|
||||
using AutoMapper;
|
||||
using Jackett.Indexers;
|
||||
using Jackett.Models;
|
||||
using Jackett.Services;
|
||||
using Jackett.Utils;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
|
||||
namespace Jackett.Controllers.V20
|
||||
{
|
||||
public interface IIndexerController
|
||||
{
|
||||
IIndexerManagerService IndexerService { get; }
|
||||
IIndexer CurrentIndexer { get; set; }
|
||||
}
|
||||
|
||||
public class RequiresIndexerAttribute : ActionFilterAttribute
|
||||
{
|
||||
public override void OnActionExecuting(HttpActionContext actionContext)
|
||||
{
|
||||
base.OnActionExecuting(actionContext);
|
||||
|
||||
var controller = actionContext.ControllerContext.Controller;
|
||||
if (!(controller is IIndexerController))
|
||||
return;
|
||||
|
||||
var indexerController = controller as IIndexerController;
|
||||
|
||||
var parameters = actionContext.RequestContext.RouteData.Values;
|
||||
|
||||
if (!parameters.ContainsKey("indexerId"))
|
||||
{
|
||||
indexerController.CurrentIndexer = null;
|
||||
return;
|
||||
}
|
||||
|
||||
var indexerId = parameters["indexerId"] as string;
|
||||
if (indexerId.IsNullOrEmptyOrWhitespace())
|
||||
return;
|
||||
|
||||
var indexerService = indexerController.IndexerService;
|
||||
var indexer = indexerService.GetIndexer(indexerId);
|
||||
indexerController.CurrentIndexer = indexer;
|
||||
}
|
||||
}
|
||||
|
||||
[RoutePrefix("api/v2.0/indexers")]
|
||||
[JackettAuthorized]
|
||||
[JackettAPINoCache]
|
||||
public class IndexerApiController : ApiController, IIndexerController
|
||||
{
|
||||
public IIndexerManagerService IndexerService { get; private set; }
|
||||
public IIndexer CurrentIndexer { get; set; }
|
||||
|
||||
public IndexerApiController(IIndexerManagerService indexerManagerService, IServerService ss, ICacheService c, Logger logger)
|
||||
{
|
||||
IndexerService = indexerManagerService;
|
||||
serverService = ss;
|
||||
cacheService = c;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[RequiresIndexer]
|
||||
public async Task<IHttpActionResult> Config()
|
||||
{
|
||||
var config = await CurrentIndexer.GetConfigurationForSetup();
|
||||
return Ok(config.ToJson(null));
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ActionName("Config")]
|
||||
[RequiresIndexer]
|
||||
public async Task UpdateConfig([FromBody]Models.DTO.ConfigItem[] config)
|
||||
{
|
||||
try
|
||||
{
|
||||
// HACK
|
||||
var jsonString = JsonConvert.SerializeObject(config);
|
||||
var json = JToken.Parse(jsonString);
|
||||
|
||||
var configurationResult = await CurrentIndexer.ApplyConfiguration(json);
|
||||
|
||||
if (configurationResult == IndexerConfigurationStatus.RequiresTesting)
|
||||
await IndexerService.TestIndexer(CurrentIndexer.ID);
|
||||
}
|
||||
catch
|
||||
{
|
||||
var baseIndexer = CurrentIndexer as BaseIndexer;
|
||||
if (null != baseIndexer)
|
||||
baseIndexer.ResetBaseConfig();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("")]
|
||||
public IEnumerable<Models.DTO.Indexer> Indexers()
|
||||
{
|
||||
var dto = IndexerService.GetAllIndexers().Select(i => new Models.DTO.Indexer(i));
|
||||
return dto;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[RequiresIndexer]
|
||||
public async Task Test()
|
||||
{
|
||||
JToken jsonReply = new JObject();
|
||||
try
|
||||
{
|
||||
await IndexerService.TestIndexer(CurrentIndexer.ID);
|
||||
CurrentIndexer.LastError = null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var msg = ex.Message;
|
||||
if (ex.InnerException != null)
|
||||
msg += ": " + ex.InnerException.Message;
|
||||
|
||||
if (CurrentIndexer != null)
|
||||
CurrentIndexer.LastError = msg;
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
[RequiresIndexer]
|
||||
[Route("{indexerId}")]
|
||||
public void Delete()
|
||||
{
|
||||
IndexerService.DeleteIndexer(CurrentIndexer.ID);
|
||||
}
|
||||
|
||||
// TODO
|
||||
// This should go to ServerConfigurationController
|
||||
[Route("Cache")]
|
||||
[HttpGet]
|
||||
public List<TrackerCacheResult> Cache()
|
||||
{
|
||||
var results = cacheService.GetCachedResults();
|
||||
ConfigureCacheResults(results);
|
||||
return results;
|
||||
}
|
||||
|
||||
private void ConfigureCacheResults(IEnumerable<TrackerCacheResult> results)
|
||||
{
|
||||
var serverUrl = string.Format("{0}://{1}:{2}{3}", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port, serverService.BasePath());
|
||||
foreach (var result in results)
|
||||
{
|
||||
var link = result.Link;
|
||||
var file = StringUtil.MakeValidFileName(result.Title, '_', false) + ".torrent";
|
||||
result.Link = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "dl", file);
|
||||
if (result.Link != null && result.Link.Scheme != "magnet" && !string.IsNullOrWhiteSpace(Engine.Server.Config.BlackholeDir))
|
||||
result.BlackholeLink = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "bh", file);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private Logger logger;
|
||||
private IServerService serverService;
|
||||
private ICacheService cacheService;
|
||||
}
|
||||
}
|
@@ -1,173 +0,0 @@
|
||||
using AutoMapper;
|
||||
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.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
|
||||
namespace Jackett.Controllers
|
||||
{
|
||||
[AllowAnonymous]
|
||||
[JackettAPINoCache]
|
||||
public class PotatoController : ApiController
|
||||
{
|
||||
private IIndexerManagerService indexerService;
|
||||
private Logger logger;
|
||||
private IServerService serverService;
|
||||
private ICacheService cacheService;
|
||||
private IWebClient webClient;
|
||||
|
||||
public static int[] MOVIE_CATS
|
||||
{
|
||||
get
|
||||
{
|
||||
var torznabQuery = new TorznabQuery()
|
||||
{
|
||||
Categories = new int[1] { TorznabCatType.Movies.ID },
|
||||
};
|
||||
|
||||
torznabQuery.ExpandCatsToSubCats();
|
||||
return torznabQuery.Categories;
|
||||
}
|
||||
}
|
||||
|
||||
public PotatoController(IIndexerManagerService i, Logger l, IServerService s, ICacheService c, IWebClient w)
|
||||
{
|
||||
indexerService = i;
|
||||
logger = l;
|
||||
serverService = s;
|
||||
cacheService = c;
|
||||
webClient = w;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<HttpResponseMessage> Call(string indexerID, [FromUri]TorrentPotatoRequest request)
|
||||
{
|
||||
var indexer = indexerService.GetIndexer(indexerID);
|
||||
|
||||
var allowBadApiDueToDebug = false;
|
||||
#if DEBUG
|
||||
allowBadApiDueToDebug = Debugger.IsAttached;
|
||||
#endif
|
||||
|
||||
if (!allowBadApiDueToDebug && !string.Equals(request.passkey, serverService.Config.APIKey, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
logger.Warn(string.Format("A request from {0} was made with an incorrect API key.", Request.GetOwinContext().Request.RemoteIpAddress));
|
||||
return Request.CreateResponse(HttpStatusCode.Forbidden, "Incorrect API key");
|
||||
}
|
||||
|
||||
if (!indexer.IsConfigured)
|
||||
{
|
||||
logger.Warn(string.Format("Rejected a request to {0} which is unconfigured.", indexer.DisplayName));
|
||||
return Request.CreateResponse(HttpStatusCode.Forbidden, "This indexer is not configured.");
|
||||
}
|
||||
|
||||
if (!indexer.TorznabCaps.Categories.Select(c => c.ID).Any(i => MOVIE_CATS.Contains(i))){
|
||||
logger.Warn(string.Format("Rejected a request to {0} which does not support searching for movies.", indexer.DisplayName));
|
||||
return Request.CreateResponse(HttpStatusCode.Forbidden, "This indexer does not support movies.");
|
||||
}
|
||||
|
||||
var year = 0;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(request.search))
|
||||
{
|
||||
// We are searching by IMDB id so look up the name
|
||||
var omdbapiRequest = new Utils.Clients.WebRequest("http://www.omdbapi.com/?type=movie&i=" + request.imdbid);
|
||||
omdbapiRequest.Encoding = Encoding.UTF8;
|
||||
var response = await webClient.GetString(omdbapiRequest);
|
||||
if (response.Status == HttpStatusCode.OK)
|
||||
{
|
||||
JObject result = JObject.Parse(response.Content);
|
||||
if (result["Title"] != null)
|
||||
{
|
||||
request.search = result["Title"].ToString();
|
||||
year = ParseUtil.CoerceInt(result["Year"].ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var torznabQuery = new TorznabQuery()
|
||||
{
|
||||
ApiKey = request.passkey,
|
||||
Categories = MOVIE_CATS,
|
||||
SearchTerm = request.search,
|
||||
ImdbID = request.imdbid,
|
||||
QueryType = "TorrentPotato"
|
||||
};
|
||||
|
||||
IEnumerable<ReleaseInfo> releases = new List<ReleaseInfo>();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(torznabQuery.SanitizedSearchTerm))
|
||||
{
|
||||
releases = await indexer.PerformQuery(torznabQuery);
|
||||
releases = indexer.CleanLinks(releases);
|
||||
}
|
||||
|
||||
// Cache non query results
|
||||
if (string.IsNullOrEmpty(torznabQuery.SanitizedSearchTerm))
|
||||
{
|
||||
cacheService.CacheRssResults(indexer, releases);
|
||||
}
|
||||
|
||||
releases = indexer.FilterResults(torznabQuery, releases);
|
||||
var serverUrl = string.Format("{0}://{1}:{2}{3}", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port, serverService.BasePath());
|
||||
var potatoResponse = new TorrentPotatoResponse();
|
||||
|
||||
releases = TorznabUtil.FilterResultsToTitle(releases, torznabQuery.SanitizedSearchTerm, year);
|
||||
releases = TorznabUtil.FilterResultsToImdb(releases, request.imdbid);
|
||||
|
||||
foreach (var r in releases)
|
||||
{
|
||||
var release = Mapper.Map<ReleaseInfo>(r);
|
||||
release.Link = serverService.ConvertToProxyLink(release.Link, serverUrl, indexerID, "dl", release.Title + ".torrent");
|
||||
|
||||
// Only accept torrent links, magnet is not supported
|
||||
// This seems to be no longer the case, allowing magnet URIs for now
|
||||
if (release.Link != null || release.MagnetUri != null)
|
||||
{
|
||||
potatoResponse.results.Add(new TorrentPotatoResponseItem()
|
||||
{
|
||||
release_name = release.Title + "[" + indexer.DisplayName + "]", // Suffix the indexer so we can see which tracker we are using in CPS as it just says torrentpotato >.>
|
||||
torrent_id = release.Guid.ToString(),
|
||||
details_url = release.Comments.ToString(),
|
||||
download_url = (release.Link != null ? release.Link.ToString() : release.MagnetUri.ToString()),
|
||||
imdb_id = release.Imdb.HasValue ? "tt" + release.Imdb : null,
|
||||
freeleech = (release.DownloadVolumeFactor == 0 ? true : false),
|
||||
type = "movie",
|
||||
size = (long)release.Size / (1024 * 1024), // This is in MB
|
||||
leechers = (int)release.Peers - (int)release.Seeders,
|
||||
seeders = (int)release.Seeders,
|
||||
publish_date = r.PublishDate == DateTime.MinValue ? null : release.PublishDate.ToUniversalTime().ToString("s")
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Log info
|
||||
if (string.IsNullOrWhiteSpace(torznabQuery.SanitizedSearchTerm))
|
||||
{
|
||||
logger.Info(string.Format("Found {0} torrentpotato releases from {1}", releases.Count(), indexer.DisplayName));
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Info(string.Format("Found {0} torrentpotato releases from {1} for: {2}", releases.Count(), indexer.DisplayName, torznabQuery.GetQueryString()));
|
||||
}
|
||||
|
||||
// Force the return as Json
|
||||
return new HttpResponseMessage()
|
||||
{
|
||||
Content = new JsonContent(potatoResponse)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
419
src/Jackett/Controllers/ResultsController.cs
Normal file
419
src/Jackett/Controllers/ResultsController.cs
Normal file
@@ -0,0 +1,419 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
using System.Web.Http.Controllers;
|
||||
using System.Web.Http.Filters;
|
||||
using System.Xml.Linq;
|
||||
using Jackett.Indexers;
|
||||
using Jackett.Models;
|
||||
using Jackett.Services;
|
||||
using Jackett.Utils;
|
||||
using Jackett.Utils.Clients;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using Jackett.Models.DTO;
|
||||
|
||||
namespace Jackett.Controllers.V20
|
||||
{
|
||||
public class RequiresApiKeyAttribute : AuthorizationFilterAttribute
|
||||
{
|
||||
public override void OnAuthorization(HttpActionContext actionContext)
|
||||
{
|
||||
var validApiKey = Engine.Server.Config.APIKey;
|
||||
var queryParams = actionContext.Request.GetQueryNameValuePairs();
|
||||
var queryApiKey = queryParams.Where(x => x.Key == "apikey" || x.Key == "passkey").Select(x => x.Value).FirstOrDefault();
|
||||
|
||||
#if DEBUG
|
||||
if (Debugger.IsAttached)
|
||||
return;
|
||||
#endif
|
||||
if (queryApiKey != validApiKey)
|
||||
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
|
||||
}
|
||||
}
|
||||
|
||||
public class RequiresConfiguredIndexerAttribute : ActionFilterAttribute
|
||||
{
|
||||
public override void OnActionExecuting(HttpActionContext actionContext)
|
||||
{
|
||||
var controller = actionContext.ControllerContext.Controller;
|
||||
if (!(controller is IIndexerController))
|
||||
return;
|
||||
|
||||
var indexerController = controller as IIndexerController;
|
||||
|
||||
var parameters = actionContext.RequestContext.RouteData.Values;
|
||||
|
||||
if (!parameters.ContainsKey("indexerId"))
|
||||
{
|
||||
indexerController.CurrentIndexer = null;
|
||||
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Invalid parameter");
|
||||
return;
|
||||
}
|
||||
|
||||
var indexerId = parameters["indexerId"] as string;
|
||||
if (indexerId.IsNullOrEmptyOrWhitespace())
|
||||
{
|
||||
indexerController.CurrentIndexer = null;
|
||||
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Invalid parameter");
|
||||
return;
|
||||
}
|
||||
|
||||
var indexerService = indexerController.IndexerService;
|
||||
var indexer = indexerService.GetIndexer(indexerId);
|
||||
|
||||
if (indexer == null)
|
||||
{
|
||||
indexerController.CurrentIndexer = null;
|
||||
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Invalid parameter");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!indexer.IsConfigured)
|
||||
{
|
||||
indexerController.CurrentIndexer = null;
|
||||
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Indexer is not configured");
|
||||
return;
|
||||
}
|
||||
|
||||
indexerController.CurrentIndexer = indexer;
|
||||
}
|
||||
}
|
||||
|
||||
public class RequiresValidQueryAttribute : RequiresConfiguredIndexerAttribute
|
||||
{
|
||||
public override void OnActionExecuting(HttpActionContext actionContext)
|
||||
{
|
||||
base.OnActionExecuting(actionContext);
|
||||
if (actionContext.Response != null)
|
||||
return;
|
||||
|
||||
var controller = actionContext.ControllerContext.Controller;
|
||||
if (!(controller is IResultController))
|
||||
return;
|
||||
|
||||
var resultController = controller as IResultController;
|
||||
|
||||
var query = actionContext.ActionArguments.First().Value;
|
||||
var queryType = query.GetType();
|
||||
var converter = queryType.GetMethod("ToTorznabQuery", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
|
||||
if (converter == null)
|
||||
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, "");
|
||||
var converted = converter.Invoke(null, new object[] { query });
|
||||
var torznabQuery = converted as TorznabQuery;
|
||||
resultController.CurrentQuery = torznabQuery;
|
||||
|
||||
if (queryType == typeof(ApiSearch)) // Skip CanHandleQuery() check for manual search (CurrentIndexer isn't used during manul search)
|
||||
return;
|
||||
|
||||
if (!resultController.CurrentIndexer.CanHandleQuery(resultController.CurrentQuery))
|
||||
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, $"{resultController.CurrentIndexer.ID} does not support the requested query.");
|
||||
}
|
||||
}
|
||||
|
||||
public class JsonResponseAttribute : ActionFilterAttribute
|
||||
{
|
||||
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
|
||||
{
|
||||
base.OnActionExecuted(actionExecutedContext);
|
||||
|
||||
var content = actionExecutedContext.Response.Content as ObjectContent;
|
||||
actionExecutedContext.Response.Content = new JsonContent(content.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public interface IResultController : IIndexerController
|
||||
{
|
||||
TorznabQuery CurrentQuery { get; set; }
|
||||
}
|
||||
|
||||
[AllowAnonymous]
|
||||
[JackettAPINoCache]
|
||||
[RoutePrefix("api/v2.0/indexers")]
|
||||
[RequiresApiKey]
|
||||
[RequiresValidQuery]
|
||||
public class ResultsController : ApiController, IResultController
|
||||
{
|
||||
public IIndexerManagerService IndexerService { get; private set; }
|
||||
public IIndexer CurrentIndexer { get; set; }
|
||||
public TorznabQuery CurrentQuery { get; set; }
|
||||
|
||||
public ResultsController(IIndexerManagerService indexerManagerService, IServerService ss, ICacheService c, Logger logger)
|
||||
{
|
||||
IndexerService = indexerManagerService;
|
||||
serverService = ss;
|
||||
cacheService = c;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<Models.DTO.ManualSearchResult> Results([FromUri]Models.DTO.ApiSearch request)
|
||||
{
|
||||
var manualResult = new ManualSearchResult();
|
||||
var trackers = IndexerService.GetAllIndexers().Where(t => t.IsConfigured);
|
||||
if (request.Tracker != null)
|
||||
trackers = trackers.Where(t => request.Tracker.Contains(t.ID));
|
||||
trackers = trackers.Where(t => t.CanHandleQuery(CurrentQuery));
|
||||
|
||||
var tasks = trackers.ToList().Select(t => t.ResultsForQuery(CurrentQuery)).ToList();
|
||||
try
|
||||
{
|
||||
var aggregateTask = Task.WhenAll(tasks);
|
||||
await aggregateTask;
|
||||
}
|
||||
catch (AggregateException aex)
|
||||
{
|
||||
foreach (var ex in aex.InnerExceptions)
|
||||
{
|
||||
logger.Error(ex);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex);
|
||||
}
|
||||
|
||||
manualResult.Indexers = tasks.Select(t =>
|
||||
{
|
||||
var resultIndexer = new ManualSearchResultIndexer();
|
||||
IIndexer indexer = null;
|
||||
if (t.Status == TaskStatus.RanToCompletion)
|
||||
{
|
||||
resultIndexer.Status = ManualSearchResultIndexerStatus.OK;
|
||||
resultIndexer.Results = t.Result.Releases.Count();
|
||||
resultIndexer.Error = null;
|
||||
indexer = t.Result.Indexer;
|
||||
}
|
||||
else if (t.Exception.InnerException is IndexerException)
|
||||
{
|
||||
resultIndexer.Status = ManualSearchResultIndexerStatus.Error;
|
||||
resultIndexer.Results = 0;
|
||||
resultIndexer.Error = ((IndexerException)t.Exception.InnerException).ToString();
|
||||
indexer = ((IndexerException)t.Exception.InnerException).Indexer;
|
||||
}
|
||||
else
|
||||
{
|
||||
resultIndexer.Status = ManualSearchResultIndexerStatus.Unknown;
|
||||
resultIndexer.Results = 0;
|
||||
resultIndexer.Error = null;
|
||||
}
|
||||
|
||||
if (indexer != null)
|
||||
{
|
||||
resultIndexer.ID = indexer.ID;
|
||||
resultIndexer.Name = indexer.DisplayName;
|
||||
}
|
||||
return resultIndexer;
|
||||
}).ToList();
|
||||
|
||||
manualResult.Results = tasks.Where(t => t.Status == TaskStatus.RanToCompletion).Where(t => t.Result.Releases.Count() > 0).SelectMany(t =>
|
||||
{
|
||||
var searchResults = t.Result.Releases;
|
||||
var indexer = t.Result.Indexer;
|
||||
cacheService.CacheRssResults(indexer, searchResults);
|
||||
|
||||
return searchResults.Select(result =>
|
||||
{
|
||||
var item = AutoMapper.Mapper.Map<TrackerCacheResult>(result);
|
||||
item.Tracker = indexer.DisplayName;
|
||||
item.TrackerId = indexer.ID;
|
||||
item.Peers = item.Peers - item.Seeders; // Use peers as leechers
|
||||
|
||||
return item;
|
||||
});
|
||||
}).OrderByDescending(d => d.PublishDate).ToList();
|
||||
|
||||
ConfigureCacheResults(manualResult.Results);
|
||||
|
||||
logger.Info(string.Format("Manual search for \"{0}\" on {1} with {2} results.", CurrentQuery.SanitizedSearchTerm, string.Join(", ", manualResult.Indexers.Select(i => i.ID)), manualResult.Results.Count()));
|
||||
return manualResult;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IHttpActionResult> Torznab([FromUri]Models.DTO.TorznabRequest request)
|
||||
{
|
||||
if (string.Equals(CurrentQuery.QueryType, "caps", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return ResponseMessage(new HttpResponseMessage()
|
||||
{
|
||||
Content = new StringContent(CurrentIndexer.TorznabCaps.ToXml(), Encoding.UTF8, "application/xml")
|
||||
});
|
||||
}
|
||||
|
||||
if (CurrentQuery.ImdbID != null)
|
||||
{
|
||||
if (CurrentQuery.QueryType != "movie")
|
||||
{
|
||||
logger.Warn($"A non movie request with an imdbid was made from {Request.GetOwinContext().Request.RemoteIpAddress}.");
|
||||
return GetErrorXML(201, "Incorrect parameter: only movie-search supports the imdbid parameter");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(CurrentQuery.SearchTerm))
|
||||
{
|
||||
logger.Warn($"A movie-search request from {Request.GetOwinContext().Request.RemoteIpAddress} was made contining q and imdbid.");
|
||||
return GetErrorXML(201, "Incorrect parameter: please specify either imdbid or q");
|
||||
}
|
||||
|
||||
CurrentQuery.ImdbID = ParseUtil.GetFullImdbID(CurrentQuery.ImdbID); // normalize ImdbID
|
||||
if (CurrentQuery.ImdbID == null)
|
||||
{
|
||||
logger.Warn($"A movie-search request from {Request.GetOwinContext().Request.RemoteIpAddress} was made with an invalid imdbid.");
|
||||
return GetErrorXML(201, "Incorrect parameter: invalid imdbid format");
|
||||
}
|
||||
|
||||
if (!CurrentIndexer.TorznabCaps.SupportsImdbSearch)
|
||||
{
|
||||
logger.Warn($"A movie-search request with imdbid from {Request.GetOwinContext().Request.RemoteIpAddress} was made but the indexer {CurrentIndexer.DisplayName} doesn't support it.");
|
||||
return GetErrorXML(203, "Function Not Available: imdbid is not supported by this indexer");
|
||||
}
|
||||
}
|
||||
|
||||
var result = await CurrentIndexer.ResultsForQuery(CurrentQuery);
|
||||
|
||||
// Some trackers do not support multiple category filtering so filter the releases that match manually.
|
||||
int? newItemCount = null;
|
||||
|
||||
// Cache non query results
|
||||
if (string.IsNullOrEmpty(CurrentQuery.SanitizedSearchTerm))
|
||||
{
|
||||
newItemCount = cacheService.GetNewItemCount(CurrentIndexer, result.Releases);
|
||||
cacheService.CacheRssResults(CurrentIndexer, result.Releases);
|
||||
}
|
||||
|
||||
// Log info
|
||||
var logBuilder = new StringBuilder();
|
||||
if (newItemCount != null)
|
||||
{
|
||||
logBuilder.AppendFormat("Found {0} ({1} new) releases from {2}", result.Releases.Count(), newItemCount, CurrentIndexer.DisplayName);
|
||||
}
|
||||
else
|
||||
{
|
||||
logBuilder.AppendFormat("Found {0} releases from {1}", result.Releases.Count(), CurrentIndexer.DisplayName);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(CurrentQuery.SanitizedSearchTerm))
|
||||
{
|
||||
logBuilder.AppendFormat(" for: {0}", CurrentQuery.GetQueryString());
|
||||
}
|
||||
|
||||
logger.Info(logBuilder.ToString());
|
||||
|
||||
var serverUrl = string.Format("{0}://{1}:{2}{3}", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port, serverService.BasePath());
|
||||
var resultPage = new ResultPage(new ChannelInfo
|
||||
{
|
||||
Title = CurrentIndexer.DisplayName,
|
||||
Description = CurrentIndexer.DisplayDescription,
|
||||
Link = new Uri(CurrentIndexer.SiteLink),
|
||||
ImageUrl = new Uri(serverUrl + "logos/" + CurrentIndexer.ID + ".png"),
|
||||
ImageTitle = CurrentIndexer.DisplayName,
|
||||
ImageLink = new Uri(CurrentIndexer.SiteLink),
|
||||
ImageDescription = CurrentIndexer.DisplayName
|
||||
});
|
||||
|
||||
var proxiedReleases = result.Releases.Select(r => AutoMapper.Mapper.Map<ReleaseInfo>(r)).Select(r =>
|
||||
{
|
||||
r.Link = serverService.ConvertToProxyLink(r.Link, serverUrl, r.Origin.ID, "dl", r.Title + ".torrent");
|
||||
return r;
|
||||
});
|
||||
|
||||
resultPage.Releases = proxiedReleases.ToList();
|
||||
|
||||
var xml = resultPage.ToXml(new Uri(serverUrl));
|
||||
// Force the return as XML
|
||||
return ResponseMessage(new HttpResponseMessage()
|
||||
{
|
||||
Content = new StringContent(xml, Encoding.UTF8, "application/rss+xml")
|
||||
});
|
||||
}
|
||||
|
||||
public IHttpActionResult GetErrorXML(int code, string description)
|
||||
{
|
||||
var xdoc = new XDocument(
|
||||
new XDeclaration("1.0", "UTF-8", null),
|
||||
new XElement("error",
|
||||
new XAttribute("code", code.ToString()),
|
||||
new XAttribute("description", description)
|
||||
)
|
||||
);
|
||||
|
||||
var xml = xdoc.Declaration.ToString() + Environment.NewLine + xdoc.ToString();
|
||||
|
||||
return ResponseMessage(new HttpResponseMessage()
|
||||
{
|
||||
Content = new StringContent(xml, Encoding.UTF8, "application/xml")
|
||||
});
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[JsonResponse]
|
||||
public async Task<Models.DTO.TorrentPotatoResponse> Potato([FromUri]Models.DTO.TorrentPotatoRequest request)
|
||||
{
|
||||
var result = await CurrentIndexer.ResultsForQuery(CurrentQuery);
|
||||
|
||||
// Cache non query results
|
||||
if (string.IsNullOrEmpty(CurrentQuery.SanitizedSearchTerm))
|
||||
cacheService.CacheRssResults(CurrentIndexer, result.Releases);
|
||||
|
||||
// Log info
|
||||
if (string.IsNullOrWhiteSpace(CurrentQuery.SanitizedSearchTerm))
|
||||
logger.Info($"Found {result.Releases.Count()} torrentpotato releases from {CurrentIndexer.DisplayName}");
|
||||
else
|
||||
logger.Info($"Found {result.Releases.Count()} torrentpotato releases from {CurrentIndexer.DisplayName} for: {CurrentQuery.GetQueryString()}");
|
||||
|
||||
var serverUrl = string.Format("{0}://{1}:{2}{3}", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port, serverService.BasePath());
|
||||
var potatoReleases = result.Releases.Where(r => r.Link != null || r.MagnetUri != null).Select(r =>
|
||||
{
|
||||
var release = AutoMapper.Mapper.Map<ReleaseInfo>(r);
|
||||
release.Link = serverService.ConvertToProxyLink(release.Link, serverUrl, CurrentIndexer.ID, "dl", release.Title + ".torrent");
|
||||
var item = new Models.DTO.TorrentPotatoResponseItem()
|
||||
{
|
||||
release_name = release.Title + "[" + CurrentIndexer.DisplayName + "]", // Suffix the indexer so we can see which tracker we are using in CPS as it just says torrentpotato >.>
|
||||
torrent_id = release.Guid.ToString(),
|
||||
details_url = release.Comments.ToString(),
|
||||
download_url = (release.Link != null ? release.Link.ToString() : release.MagnetUri.ToString()),
|
||||
imdb_id = release.Imdb.HasValue ? "tt" + release.Imdb : null,
|
||||
freeleech = (release.DownloadVolumeFactor == 0 ? true : false),
|
||||
type = "movie",
|
||||
size = (long)release.Size / (1024 * 1024), // This is in MB
|
||||
leechers = (int)release.Peers - (int)release.Seeders,
|
||||
seeders = (int)release.Seeders,
|
||||
publish_date = r.PublishDate == DateTime.MinValue ? null : release.PublishDate.ToUniversalTime().ToString("s")
|
||||
};
|
||||
return item;
|
||||
});
|
||||
|
||||
var potatoResponse = new Models.DTO.TorrentPotatoResponse()
|
||||
{
|
||||
results = potatoReleases.ToList()
|
||||
};
|
||||
|
||||
return potatoResponse;
|
||||
}
|
||||
|
||||
private void ConfigureCacheResults(IEnumerable<TrackerCacheResult> results)
|
||||
{
|
||||
var serverUrl = string.Format("{0}://{1}:{2}{3}", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port, serverService.BasePath());
|
||||
foreach (var result in results)
|
||||
{
|
||||
var link = result.Link;
|
||||
var file = StringUtil.MakeValidFileName(result.Title, '_', false) + ".torrent";
|
||||
result.Link = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "dl", file);
|
||||
if (result.Link != null && result.Link.Scheme != "magnet" && !string.IsNullOrWhiteSpace(Engine.Server.Config.BlackholeDir))
|
||||
result.BlackholeLink = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "bh", file);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private Logger logger;
|
||||
private IServerService serverService;
|
||||
private ICacheService cacheService;
|
||||
}
|
||||
}
|
176
src/Jackett/Controllers/ServerConfigurationController.cs
Normal file
176
src/Jackett/Controllers/ServerConfigurationController.cs
Normal file
@@ -0,0 +1,176 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Web.Http;
|
||||
using Jackett.Models;
|
||||
using Jackett.Services;
|
||||
using Jackett.Utils;
|
||||
using NLog;
|
||||
|
||||
namespace Jackett.Controllers.V20
|
||||
{
|
||||
[RoutePrefix("api/v2.0/server")]
|
||||
[JackettAuthorized]
|
||||
[JackettAPINoCache]
|
||||
public class ServerConfigurationController : ApiController
|
||||
{
|
||||
public ServerConfigurationController(IConfigurationService c, IServerService s, IProcessService p, IIndexerManagerService i, ISecuityService ss, IUpdateService u, ILogCacheService lc, Logger l)
|
||||
{
|
||||
config = c;
|
||||
serverService = s;
|
||||
processService = p;
|
||||
indexerService = i;
|
||||
securityService = ss;
|
||||
updater = u;
|
||||
logCache = lc;
|
||||
logger = l;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void AdminPassword([FromBody]string password)
|
||||
{
|
||||
var oldPassword = serverService.Config.AdminPassword;
|
||||
if (string.IsNullOrEmpty(password))
|
||||
password = string.Empty;
|
||||
|
||||
if (oldPassword != password)
|
||||
{
|
||||
serverService.Config.AdminPassword = securityService.HashPassword(password);
|
||||
serverService.SaveConfig();
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void Update()
|
||||
{
|
||||
updater.CheckForUpdatesNow();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public Models.DTO.ServerConfig Config()
|
||||
{
|
||||
|
||||
var dto = new Models.DTO.ServerConfig(serverService.notices, serverService.Config, config.GetVersion());
|
||||
return dto;
|
||||
}
|
||||
|
||||
[ActionName("Config")]
|
||||
[HttpPost]
|
||||
public void UpdateConfig([FromBody]Models.DTO.ServerConfig config)
|
||||
{
|
||||
var originalPort = Engine.Server.Config.Port;
|
||||
var originalAllowExternal = Engine.Server.Config.AllowExternal;
|
||||
int port = config.port;
|
||||
bool external = config.external;
|
||||
string saveDir = config.blackholedir;
|
||||
bool updateDisabled = config.updatedisabled;
|
||||
bool preRelease = config.prerelease;
|
||||
bool logging = config.logging;
|
||||
string basePathOverride = config.basepathoverride;
|
||||
if (basePathOverride != null)
|
||||
{
|
||||
basePathOverride = basePathOverride.TrimEnd('/');
|
||||
if (!string.IsNullOrWhiteSpace(basePathOverride) && !basePathOverride.StartsWith("/"))
|
||||
throw new Exception("The Base Path Override must start with a /");
|
||||
}
|
||||
|
||||
string omdbApiKey = config.omdbkey;
|
||||
|
||||
Engine.Server.Config.UpdateDisabled = updateDisabled;
|
||||
Engine.Server.Config.UpdatePrerelease = preRelease;
|
||||
Engine.Server.Config.BasePathOverride = basePathOverride;
|
||||
Startup.BasePath = Engine.Server.BasePath();
|
||||
Engine.Server.SaveConfig();
|
||||
|
||||
Engine.SetLogLevel(logging ? LogLevel.Debug : LogLevel.Info);
|
||||
Startup.TracingEnabled = logging;
|
||||
|
||||
if (omdbApiKey != Engine.Server.Config.OmdbApiKey)
|
||||
{
|
||||
Engine.Server.Config.OmdbApiKey = omdbApiKey;
|
||||
Engine.Server.SaveConfig();
|
||||
// HACK
|
||||
indexerService.InitAggregateIndexer();
|
||||
}
|
||||
|
||||
if (port != Engine.Server.Config.Port || external != Engine.Server.Config.AllowExternal)
|
||||
{
|
||||
|
||||
if (ServerUtil.RestrictedPorts.Contains(port))
|
||||
throw new Exception("The port you have selected is restricted, try a different one.");
|
||||
|
||||
if (port < 1 || port > 65535)
|
||||
throw new Exception("The port you have selected is invalid, it must be below 65535.");
|
||||
|
||||
// Save port to the config so it can be picked up by the if needed when running as admin below.
|
||||
Engine.Server.Config.AllowExternal = external;
|
||||
Engine.Server.Config.Port = port;
|
||||
Engine.Server.SaveConfig();
|
||||
|
||||
// On Windows change the url reservations
|
||||
if (System.Environment.OSVersion.Platform != PlatformID.Unix)
|
||||
{
|
||||
if (!ServerUtil.IsUserAdministrator())
|
||||
{
|
||||
try
|
||||
{
|
||||
processService.StartProcessAndLog(System.Windows.Forms.Application.ExecutablePath, "--ReserveUrls", true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Engine.Server.Config.Port = originalPort;
|
||||
Engine.Server.Config.AllowExternal = originalAllowExternal;
|
||||
Engine.Server.SaveConfig();
|
||||
|
||||
throw new Exception("Failed to acquire admin permissions to reserve the new port.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
serverService.ReserveUrls(true);
|
||||
}
|
||||
}
|
||||
|
||||
(new Thread(() =>
|
||||
{
|
||||
Thread.Sleep(500);
|
||||
serverService.Stop();
|
||||
Engine.BuildContainer();
|
||||
Engine.Server.Initalize();
|
||||
Engine.Server.Start();
|
||||
})).Start();
|
||||
}
|
||||
|
||||
if (saveDir != Engine.Server.Config.BlackholeDir)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(saveDir))
|
||||
{
|
||||
if (!Directory.Exists(saveDir))
|
||||
{
|
||||
throw new Exception("Blackhole directory does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
Engine.Server.Config.BlackholeDir = saveDir;
|
||||
Engine.Server.SaveConfig();
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public List<CachedLog> Logs()
|
||||
{
|
||||
return logCache.Logs;
|
||||
}
|
||||
|
||||
private IConfigurationService config;
|
||||
private IServerService serverService;
|
||||
private IProcessService processService;
|
||||
private IIndexerManagerService indexerService;
|
||||
private ISecuityService securityService;
|
||||
private IUpdateService updater;
|
||||
private ILogCacheService logCache;
|
||||
private Logger logger;
|
||||
}
|
||||
}
|
@@ -1,181 +0,0 @@
|
||||
using AutoMapper;
|
||||
using Jackett.Models;
|
||||
using Jackett.Services;
|
||||
using Jackett.Utils;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Jackett.Controllers
|
||||
{
|
||||
[AllowAnonymous]
|
||||
[JackettAPINoCache]
|
||||
public class TorznabController : ApiController
|
||||
{
|
||||
private IIndexerManagerService indexerService;
|
||||
private Logger logger;
|
||||
private IServerService serverService;
|
||||
private ICacheService cacheService;
|
||||
|
||||
public TorznabController(IIndexerManagerService i, Logger l, IServerService s, ICacheService c)
|
||||
{
|
||||
indexerService = i;
|
||||
logger = l;
|
||||
serverService = s;
|
||||
cacheService = c;
|
||||
}
|
||||
|
||||
public HttpResponseMessage GetErrorXML(int code, string description)
|
||||
{
|
||||
var xdoc = new XDocument(
|
||||
new XDeclaration("1.0", "UTF-8", null),
|
||||
new XElement("error",
|
||||
new XAttribute("code", code.ToString()),
|
||||
new XAttribute("description", description)
|
||||
)
|
||||
);
|
||||
|
||||
var xml = xdoc.Declaration.ToString() + Environment.NewLine + xdoc.ToString();
|
||||
|
||||
return new HttpResponseMessage()
|
||||
{
|
||||
Content = new StringContent(xml, Encoding.UTF8, "application/xml")
|
||||
};
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<HttpResponseMessage> Call(string indexerID)
|
||||
{
|
||||
var indexer = indexerService.GetIndexer(indexerID);
|
||||
var torznabQuery = TorznabQuery.FromHttpQuery(HttpUtility.ParseQueryString(Request.RequestUri.Query));
|
||||
|
||||
if (string.Equals(torznabQuery.QueryType, "caps", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return new HttpResponseMessage()
|
||||
{
|
||||
Content = new StringContent(indexer.TorznabCaps.ToXml(), Encoding.UTF8, "application/xml")
|
||||
};
|
||||
}
|
||||
|
||||
torznabQuery.ExpandCatsToSubCats();
|
||||
var allowBadApiDueToDebug = false;
|
||||
#if DEBUG
|
||||
allowBadApiDueToDebug = Debugger.IsAttached;
|
||||
#endif
|
||||
|
||||
if (!allowBadApiDueToDebug && !string.Equals(torznabQuery.ApiKey, serverService.Config.APIKey, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
logger.Warn(string.Format("A request from {0} was made with an incorrect API key.", Request.GetOwinContext().Request.RemoteIpAddress));
|
||||
return Request.CreateResponse(HttpStatusCode.Forbidden, "Incorrect API key");
|
||||
}
|
||||
|
||||
if (!indexer.IsConfigured)
|
||||
{
|
||||
logger.Warn(string.Format("Rejected a request to {0} which is unconfigured.", indexer.DisplayName));
|
||||
return Request.CreateResponse(HttpStatusCode.Forbidden, "This indexer is not configured.");
|
||||
}
|
||||
|
||||
if (torznabQuery.ImdbID != null)
|
||||
{
|
||||
if (torznabQuery.QueryType != "movie")
|
||||
{
|
||||
logger.Warn(string.Format("A non movie request with an imdbid was made from {0}.", Request.GetOwinContext().Request.RemoteIpAddress));
|
||||
return GetErrorXML(201, "Incorrect parameter: only movie-search supports the imdbid parameter");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(torznabQuery.SearchTerm))
|
||||
{
|
||||
logger.Warn(string.Format("A movie-search request from {0} was made contining q and imdbid.", Request.GetOwinContext().Request.RemoteIpAddress));
|
||||
return GetErrorXML(201, "Incorrect parameter: please specify either imdbid or q");
|
||||
}
|
||||
|
||||
torznabQuery.ImdbID = ParseUtil.GetFullImdbID(torznabQuery.ImdbID); // normalize ImdbID
|
||||
if (torznabQuery.ImdbID == null)
|
||||
{
|
||||
logger.Warn(string.Format("A movie-search request from {0} was made with an invalid imdbid.", Request.GetOwinContext().Request.RemoteIpAddress));
|
||||
return GetErrorXML(201, "Incorrect parameter: invalid imdbid format");
|
||||
}
|
||||
|
||||
if (!indexer.TorznabCaps.SupportsImdbSearch)
|
||||
{
|
||||
logger.Warn(string.Format("A movie-search request with imdbid from {0} was made but the indexer {1} doesn't support it.", Request.GetOwinContext().Request.RemoteIpAddress, indexer.DisplayName));
|
||||
return GetErrorXML(203, "Function Not Available: imdbid is not supported by this indexer");
|
||||
}
|
||||
}
|
||||
|
||||
var releases = await indexer.PerformQuery(torznabQuery);
|
||||
releases = indexer.CleanLinks(releases);
|
||||
|
||||
// Some trackers do not keep their clocks up to date and can be ~20 minutes out!
|
||||
foreach (var release in releases)
|
||||
{
|
||||
if (release.PublishDate > DateTime.Now)
|
||||
release.PublishDate = DateTime.Now;
|
||||
}
|
||||
|
||||
// Some trackers do not support multiple category filtering so filter the releases that match manually.
|
||||
var filteredReleases = releases = indexer.FilterResults(torznabQuery, releases);
|
||||
int? newItemCount = null;
|
||||
|
||||
// Cache non query results
|
||||
if (string.IsNullOrEmpty(torznabQuery.SanitizedSearchTerm))
|
||||
{
|
||||
newItemCount = cacheService.GetNewItemCount(indexer, filteredReleases);
|
||||
cacheService.CacheRssResults(indexer, releases);
|
||||
}
|
||||
|
||||
// Log info
|
||||
var logBuilder = new StringBuilder();
|
||||
if (newItemCount != null) {
|
||||
logBuilder.AppendFormat(string.Format("Found {0} ({1} new) releases from {2}", releases.Count(), newItemCount, indexer.DisplayName));
|
||||
}
|
||||
else {
|
||||
logBuilder.AppendFormat(string.Format("Found {0} releases from {1}", releases.Count(), indexer.DisplayName));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(torznabQuery.SanitizedSearchTerm)) {
|
||||
logBuilder.AppendFormat(" for: {0}", torznabQuery.GetQueryString());
|
||||
}
|
||||
|
||||
logger.Info(logBuilder.ToString());
|
||||
|
||||
var serverUrl = string.Format("{0}://{1}:{2}{3}", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port, serverService.BasePath());
|
||||
var resultPage = new ResultPage(new ChannelInfo
|
||||
{
|
||||
Title = indexer.DisplayName,
|
||||
Description = indexer.DisplayDescription,
|
||||
Link = new Uri(indexer.SiteLink),
|
||||
ImageUrl = new Uri(serverUrl + "logos/" + indexer.ID + ".png"),
|
||||
ImageTitle = indexer.DisplayName,
|
||||
ImageLink = new Uri(indexer.SiteLink),
|
||||
ImageDescription = indexer.DisplayName
|
||||
});
|
||||
|
||||
|
||||
foreach(var result in releases)
|
||||
{
|
||||
var clone = Mapper.Map<ReleaseInfo>(result);
|
||||
clone.Link = serverService.ConvertToProxyLink(clone.Link, serverUrl, indexerID, "dl", result.Title + ".torrent");
|
||||
resultPage.Releases.Add(clone);
|
||||
}
|
||||
|
||||
var xml = resultPage.ToXml(new Uri(serverUrl));
|
||||
// Force the return as XML
|
||||
return new HttpResponseMessage()
|
||||
{
|
||||
Content = new StringContent(xml, Encoding.UTF8, "application/rss+xml")
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
89
src/Jackett/Controllers/UIController.cs
Normal file
89
src/Jackett/Controllers/UIController.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
using Jackett.Services;
|
||||
using Jackett.Utils;
|
||||
using NLog;
|
||||
|
||||
namespace Jackett.Controllers
|
||||
{
|
||||
[RoutePrefix("UI")]
|
||||
[JackettAuthorized]
|
||||
[JackettAPINoCache]
|
||||
public class WebUIController : ApiController
|
||||
{
|
||||
public WebUIController(IConfigurationService config, IServerService ss, ISecuityService s, Logger l)
|
||||
{
|
||||
this.config = config;
|
||||
serverService = ss;
|
||||
securityService = s;
|
||||
logger = l;
|
||||
}
|
||||
|
||||
private HttpResponseMessage GetFile(string path)
|
||||
{
|
||||
var result = new HttpResponseMessage(HttpStatusCode.OK);
|
||||
var mappedPath = Path.Combine(config.GetContentFolder(), path);
|
||||
var stream = new FileStream(mappedPath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
result.Content = new StreamContent(stream);
|
||||
result.Content.Headers.ContentType = new MediaTypeHeaderValue(MimeMapping.GetMimeMapping(mappedPath));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[AllowAnonymous]
|
||||
public IHttpActionResult Logout()
|
||||
{
|
||||
var ctx = Request.GetOwinContext();
|
||||
var authManager = ctx.Authentication;
|
||||
authManager.SignOut("ApplicationCookie");
|
||||
return Redirect("UI/Dashboard");
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[HttpPost]
|
||||
[AllowAnonymous]
|
||||
public async Task<HttpResponseMessage> Dashboard()
|
||||
{
|
||||
if (Request.RequestUri.Query != null && Request.RequestUri.Query.Contains("logout"))
|
||||
{
|
||||
var file = GetFile("login.html");
|
||||
securityService.Logout(file);
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
if (securityService.CheckAuthorised(Request))
|
||||
{
|
||||
return GetFile("index.html");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
var formData = await Request.Content.ReadAsFormDataAsync();
|
||||
|
||||
if (formData != null && securityService.HashPassword(formData["password"]) == serverService.Config.AdminPassword)
|
||||
{
|
||||
var file = GetFile("index.html");
|
||||
securityService.Login(file);
|
||||
return file;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetFile("login.html");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IConfigurationService config;
|
||||
private IServerService serverService;
|
||||
private ISecuityService securityService;
|
||||
private Logger logger;
|
||||
}
|
||||
}
|
@@ -112,6 +112,9 @@
|
||||
args: ["torrents-details.php", "download.php"]
|
||||
title:
|
||||
selector: a[href^="torrents-details.php?id="]
|
||||
filters:
|
||||
- name: replace
|
||||
args: [" - (Nouveau!)", ""]
|
||||
category:
|
||||
selector: a[href^="torrents.php?cat="]
|
||||
attribute: href
|
||||
|
94
src/Jackett/Definitions/anidex.yml
Normal file
94
src/Jackett/Definitions/anidex.yml
Normal file
@@ -0,0 +1,94 @@
|
||||
---
|
||||
site: anidex
|
||||
name: Anidex
|
||||
description: "Anidex is a torrent tracker and indexer, primarily for English fansub groups of anime"
|
||||
language: en-us
|
||||
encoding: UTF-8
|
||||
type: public
|
||||
links:
|
||||
- https://anidex.info/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 1, cat: TV/Anime, desc: "Anime - Sub"}
|
||||
- {id: 2, cat: TV/Anime, desc: "Anime - Raw"}
|
||||
- {id: 3, cat: TV/Anime, desc: "Anime - Dub"}
|
||||
- {id: 4, cat: TV/Anime, desc: "LA - Sub"}
|
||||
- {id: 5, cat: TV/Anime, desc: "LA - Raw"}
|
||||
- {id: 6, cat: TV/Anime, desc: "Light Novel"}
|
||||
- {id: 7, cat: TV/Anime, desc: "Manga - TLed"}
|
||||
- {id: 8, cat: TV/Anime, desc: "Manga - Raw"}
|
||||
- {id: 9, cat: TV/Anime, desc: "♫ - Lossy"}
|
||||
- {id: 10, cat: TV/Anime, desc: "♫ - Lossless"}
|
||||
- {id: 11, cat: TV/Anime, desc: "♫ - Video"}
|
||||
- {id: 12, cat: TV/Anime, desc: "Games"}
|
||||
- {id: 13, cat: TV/Anime, desc: "Applications"}
|
||||
- {id: 14, cat: TV/Anime, desc: "Pictures"}
|
||||
- {id: 15, cat: TV/Anime, desc: "Adult Video"}
|
||||
- {id: 16, cat: TV/Anime, desc: "Other"}
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
settings:
|
||||
- name: cat-id
|
||||
type: text
|
||||
label: Category Id
|
||||
- name: lang-id
|
||||
type: text
|
||||
label: Language Id
|
||||
|
||||
search:
|
||||
path: "ajax/page.ajax.php"
|
||||
headers:
|
||||
x-requested-with: ["XMLHttpRequest"]
|
||||
inputs:
|
||||
page: "torrents"
|
||||
filename: "{{ .Query.Keywords }}"
|
||||
category: "{{ .Config.cat-id }}"
|
||||
lang_id: "{{ .Config.lang-id }}"
|
||||
rows:
|
||||
selector: div.table-responsive > table > tbody > tr
|
||||
fields:
|
||||
category:
|
||||
selector: td:nth-child(1) > div
|
||||
case:
|
||||
":contains(\"Anime - Sub\")": 1
|
||||
":contains(\"Anime - Raw\")": 2
|
||||
":contains(\"Anime - Dub\")": 3
|
||||
":contains(\"LA - Sub\")": 4
|
||||
":contains(\"LA - Raw\")": 5
|
||||
":contains(\"Light Novel\")": 6
|
||||
":contains(\"Manga - TLed\")": 7
|
||||
":contains(\"Manga - Raw\")": 8
|
||||
":contains(\"♫ - Lossy\")": 9
|
||||
":contains(\"♫ - Lossless\")": 10
|
||||
":contains(\"♫ - Video\")": 11
|
||||
":contains(\"Games\")": 12
|
||||
":contains(\"Applications\")": 13
|
||||
":contains(\"Pictures\")": 14
|
||||
":contains(\"Adult Video\")": 15
|
||||
":contains(\"Other\")": 16
|
||||
"*": 0 # some old torrents don't have a category
|
||||
title:
|
||||
selector: td:nth-child(3) > a.torrent > span.span-1440
|
||||
details:
|
||||
selector: td:nth-child(3) > a.torrent
|
||||
attribute: href
|
||||
download:
|
||||
selector: td:nth-child(5) > a
|
||||
attribute: href
|
||||
size:
|
||||
selector: td:nth-child(7)
|
||||
date:
|
||||
selector: td:nth-child(8)
|
||||
attribute: title
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["UTC", "+00:00"]
|
||||
- name: dateparse
|
||||
args: "2006-01-02 15:04:05 -07:00"
|
||||
seeders:
|
||||
selector: td:nth-child(9)
|
||||
leechers:
|
||||
selector: td:nth-child(10)
|
53
src/Jackett/Definitions/anirena.yml
Normal file
53
src/Jackett/Definitions/anirena.yml
Normal file
@@ -0,0 +1,53 @@
|
||||
---
|
||||
site: aniRena
|
||||
name: AniRena
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://www.anirena.com/
|
||||
|
||||
settings: []
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
# Anime
|
||||
- {id: 2, cat: TV/Anime, desc: "Anime"}
|
||||
- {id: 9, cat: TV/Anime, desc: "Anime Music Videos"}
|
||||
- {id: 10, cat: TV/Anime, desc: "Non-English"}
|
||||
- {id: 1, cat: TV/Anime, desc: "Raw Animes"}
|
||||
# Audio
|
||||
- {id: 8, cat: Audio, desc: "Audio"}
|
||||
# Literature
|
||||
- {id: 7, cat: Books, desc: "Manga"}
|
||||
# Software
|
||||
- {id: 5, cat: PC/ISO, desc: "DVD/ISO"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
|
||||
search:
|
||||
path: "/"
|
||||
inputs:
|
||||
s: "{{ .Query.Keywords }}"
|
||||
rows:
|
||||
selector: table tbody tr
|
||||
fields:
|
||||
title:
|
||||
selector: .torrents_small_info_data1 div
|
||||
download:
|
||||
selector: .torrents_small_info_data2 a[title="Download Torrent"]
|
||||
attribute: href
|
||||
magnet:
|
||||
selector: .torrents_small_info_data2 a[title="Magnet Link"]
|
||||
attribute: href
|
||||
size:
|
||||
selector: .torrents_small_size_data1
|
||||
seeders:
|
||||
selector: .torrents_small_seeders_data1 b big
|
||||
leechers:
|
||||
selector: .torrents_small_leechers_data1 b big
|
||||
grabs:
|
||||
selector: .torrents_small_downloads_data1
|
68
src/Jackett/Definitions/awesomehd.yml
Executable file
68
src/Jackett/Definitions/awesomehd.yml
Executable file
@@ -0,0 +1,68 @@
|
||||
---
|
||||
site: awesomehd
|
||||
name: Awesome-HD
|
||||
description: "An HD tracker"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://awesome-hd.me
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 1, cat: Movies/HD, desc: "Movies"}
|
||||
- {id: 2, cat: TV/HD, desc: "TV-Shows"}
|
||||
|
||||
modes:
|
||||
searchstr: [q]
|
||||
|
||||
settings:
|
||||
- name: cookie
|
||||
type: text
|
||||
label: Cookie
|
||||
|
||||
login:
|
||||
method: cookie
|
||||
inputs:
|
||||
cookie: "{{ .Config.cookie }}"
|
||||
test:
|
||||
path: index.php
|
||||
|
||||
search:
|
||||
path: torrents.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
|
||||
searchstr: "{{ .Query.Keywords }}"
|
||||
page: torrents
|
||||
rows:
|
||||
selector: table#torrent_table > tbody > tr.group, tr.torrent, tr.group_torrent:not(.edition_info)
|
||||
fields:
|
||||
download:
|
||||
selector: a[href^="torrents.php?action=download&id="]
|
||||
attribute: href
|
||||
optional: true
|
||||
details:
|
||||
selector: a[href^="torrents.php?id="]
|
||||
attribute: href
|
||||
title:
|
||||
selector: td:nth-child(3) > a
|
||||
category:
|
||||
selector: td:nth-child(2)
|
||||
# files:
|
||||
# selector: td:nth-child(4)
|
||||
date:
|
||||
selector: td:nth-last-child(5)
|
||||
size:
|
||||
selector: td:nth-last-child(4)
|
||||
grabs:
|
||||
selector: td:nth-last-child(3)
|
||||
seeders:
|
||||
selector: td:nth-last-child(2)
|
||||
leechers:
|
||||
selector: td:nth-last-child(1)
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
264
src/Jackett/Definitions/b2s-share.yml
Normal file
264
src/Jackett/Definitions/b2s-share.yml
Normal file
@@ -0,0 +1,264 @@
|
||||
---
|
||||
site: b2s-share
|
||||
name: B2S-Share
|
||||
language: pt-br
|
||||
type: private
|
||||
encoding: iso-8859-1
|
||||
links:
|
||||
- http://www.b2s-share.com/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
#3D
|
||||
- {id: 141, cat: Movies/3D, desc: "3D Ação"}
|
||||
- {id: 142, cat: Movies/3D, desc: "3D Animação"}
|
||||
- {id: 143, cat: Movies/3D, desc: "3D Aventura"}
|
||||
- {id: 144, cat: Movies/3D, desc: "3D Clássico"}
|
||||
- {id: 145, cat: Movies/3D, desc: "3D Comédia"}
|
||||
- {id: 146, cat: Movies/3D, desc: "3D Documentário"}
|
||||
- {id: 147, cat: Movies/3D, desc: "3D Drama"}
|
||||
- {id: 149, cat: Movies/3D, desc: "3D Ficção"}
|
||||
- {id: 150, cat: Movies/3D, desc: "3D Guerra"}
|
||||
- {id: 151, cat: Movies/3D, desc: "3D Infantil"}
|
||||
- {id: 152, cat: Movies/3D, desc: "3D Musical"}
|
||||
- {id: 154, cat: Movies/3D, desc: "3D Outros"}
|
||||
- {id: 155, cat: Movies/3D, desc: "3D Policial"}
|
||||
- {id: 156, cat: Movies/3D, desc: "3D Religioso"}
|
||||
- {id: 157, cat: Movies/3D, desc: "3D Romance"}
|
||||
- {id: 158, cat: Movies/3D, desc: "3D Shows"}
|
||||
- {id: 159, cat: Movies/3D, desc: "3D Suspense"}
|
||||
- {id: 160, cat: Movies/3D, desc: "3D Terror"}
|
||||
- {id: 161, cat: Movies/3D, desc: "3D Thriller"}
|
||||
- {id: 162, cat: Movies/3D, desc: "3D Western"}
|
||||
|
||||
#4K
|
||||
- {id: 173, cat: Movies, desc: "4K Ação"}
|
||||
- {id: 191, cat: Movies, desc: "4K Animação"}
|
||||
- {id: 190, cat: Movies, desc: "4K Aventura"}
|
||||
- {id: 188, cat: Movies, desc: "4K Clássico"}
|
||||
- {id: 175, cat: Movies, desc: "4K Comédia"}
|
||||
- {id: 186, cat: Movies, desc: "4K Documentário"}
|
||||
- {id: 185, cat: Movies, desc: "4K Drama"}
|
||||
- {id: 177, cat: Movies, desc: "4K Ficção"}
|
||||
- {id: 178, cat: Movies, desc: "4K Guerra"}
|
||||
- {id: 179, cat: Movies, desc: "4K Infantil"}
|
||||
- {id: 180, cat: Movies, desc: "4K Musical"}
|
||||
- {id: 184, cat: Movies, desc: "4K Outros"}
|
||||
- {id: 176, cat: Movies, desc: "4K Policial"}
|
||||
- {id: 187, cat: Movies, desc: "4K Religioso"}
|
||||
- {id: 174, cat: Movies, desc: "4K Romance"}
|
||||
- {id: 181, cat: Movies, desc: "4K Shows"}
|
||||
- {id: 182, cat: Movies, desc: "4K Suspense"}
|
||||
- {id: 189, cat: Movies, desc: "4K Terror"}
|
||||
- {id: 183, cat: Movies, desc: "4K Thriller"}
|
||||
|
||||
#ANIME
|
||||
- {id: 11, cat: TV/Anime, desc: "Anime"}
|
||||
|
||||
#PC-APPS
|
||||
- {id: 2, cat: PC, desc: "PC APPS - Linux"}
|
||||
- {id: 3, cat: PC, desc: "PC APPS - Mac"}
|
||||
- {id: 33, cat: PC, desc: "PC APPS - Portateis"}
|
||||
- {id: 1, cat: PC, desc: "PC APPS - Windows"}
|
||||
|
||||
#BD-R
|
||||
- {id: 140, cat: Movies, desc: "BD-R Autorado"}
|
||||
- {id: 119, cat: Movies, desc: "BD-R"}
|
||||
|
||||
#MOBILE
|
||||
- {id: 163, cat: Other, desc: "Mobile App/Jogos-Android"}
|
||||
- {id: 164, cat: Other, desc: "Mobile App/Jogos-iPhone"}
|
||||
- {id: 93, cat: Other, desc: "Mobile App/Jogos-Java"}
|
||||
- {id: 169, cat: Other, desc: "Mobile App/Jogos-Outros"}
|
||||
- {id: 168, cat: Other, desc: "Mobile App/Jogos-Win"}
|
||||
- {id: 92, cat: Other, desc: "Mobile Filmes"}
|
||||
- {id: 118, cat: Other, desc: "Mobile Séries"}
|
||||
- {id: 94, cat: Other, desc: "Mobile Wallpapers"}
|
||||
|
||||
#CARTOON
|
||||
- {id: 172, cat: TV/Other, desc: "Desenho Animado"}
|
||||
|
||||
#OTHER
|
||||
- {id: 4, cat: Other, desc: "Apostilas/Cursos"}
|
||||
- {id: 12, cat: Books, desc: "Diversos"}
|
||||
- {id: 167, cat: Books, desc: "E-book/Livros"}
|
||||
- {id: 7, cat: PC/Games, desc: "Emuladores / Roms"}
|
||||
- {id: 166, cat: Books/Comics, desc: "HQ"}
|
||||
- {id: 165, cat: Books, desc: "Revistas"}
|
||||
|
||||
#DVD-R
|
||||
- {id: 41, cat: Movies/SD, desc: "DVD-R Autorado"}
|
||||
- {id: 32, cat: Movies/SD, desc: "DVD-R"}
|
||||
|
||||
#MOVIES
|
||||
- {id: 14, cat: Movies, desc: "Filmes Ação"}
|
||||
- {id: 99, cat: Movies, desc: "Filmes Animação"}
|
||||
- {id: 15, cat: Movies, desc: "Filmes Aventura"}
|
||||
- {id: 16, cat: Movies, desc: "Filmes Clássico"}
|
||||
- {id: 17, cat: Movies, desc: "Filmes Comédia"}
|
||||
- {id: 31, cat: Movies, desc: "Filmes Documentário"}
|
||||
- {id: 18, cat: Movies, desc: "Filmes Drama"}
|
||||
- {id: 19, cat: Movies, desc: "Filmes Ficção"}
|
||||
- {id: 20, cat: Movies, desc: "Filmes Guerra"}
|
||||
- {id: 126, cat: Movies, desc: "Filmes Infantil"}
|
||||
- {id: 96, cat: Movies, desc: "Filmes Musical"}
|
||||
- {id: 24, cat: Movies, desc: "Filmes Outros"}
|
||||
- {id: 40, cat: Movies, desc: "Filmes Policial"}
|
||||
- {id: 39, cat: Movies, desc: "Filmes Religioso"}
|
||||
- {id: 30, cat: Movies, desc: "Filmes Romance"}
|
||||
- {id: 22, cat: Movies, desc: "Filmes Suspense"}
|
||||
- {id: 23, cat: Movies, desc: "Filmes Terror"}
|
||||
- {id: 130, cat: Movies, desc: "Filmes Thriller"}
|
||||
- {id: 131, cat: Movies, desc: "Filmes Western"}
|
||||
- {id: 34, cat: Movies, desc: "Filmes x264"}
|
||||
|
||||
#HD-1080p
|
||||
- {id: 73, cat: Movies/HD, desc: "Filmes 1080p Ação"}
|
||||
- {id: 87, cat: Movies/HD, desc: "Filmes 1080p Animação"}
|
||||
- {id: 74, cat: Movies/HD, desc: "Filmes 1080p Aventura"}
|
||||
- {id: 75, cat: Movies/HD, desc: "Filmes 1080p Clássico"}
|
||||
- {id: 76, cat: Movies/HD, desc: "Filmes 1080p Comédia"}
|
||||
- {id: 77, cat: Movies/HD, desc: "Filmes 1080p Documentário"}
|
||||
- {id: 78, cat: Movies/HD, desc: "Filmes 1080p Drama"}
|
||||
- {id: 79, cat: Movies/HD, desc: "Filmes 1080p Ficção"}
|
||||
- {id: 80, cat: Movies/HD, desc: "Filmes 1080p Guerra"}
|
||||
- {id: 127, cat: Movies/HD, desc: "Filmes 1080p Infantil"}
|
||||
- {id: 97, cat: Movies/HD, desc: "Filmes 1080p Musical"}
|
||||
- {id: 63, cat: Movies/HD, desc: "Filmes 1080p Outros"}
|
||||
- {id: 82, cat: Movies/HD, desc: "Filmes 1080p Policial"}
|
||||
- {id: 83, cat: Movies/HD, desc: "Filmes 1080p Religioso"}
|
||||
- {id: 84, cat: Movies/HD, desc: "Filmes 1080p Romance"}
|
||||
- {id: 88, cat: Movies/HD, desc: "Filmes 1080p Shows"}
|
||||
- {id: 85, cat: Movies/HD, desc: "Filmes 1080p Suspense"}
|
||||
- {id: 86, cat: Movies/HD, desc: "Filmes 1080p Terror"}
|
||||
- {id: 132, cat: Movies/HD, desc: "Filmes 1080p Thriller"}
|
||||
- {id: 135, cat: Movies/HD, desc: "Filmes 1080p Western"}
|
||||
|
||||
#HD-720p
|
||||
- {id: 58, cat: Movies/HD, desc: "Filmes 720p Ação"}
|
||||
- {id: 89, cat: Movies/HD, desc: "Filmes 720p Animação"}
|
||||
- {id: 60, cat: Movies/HD, desc: "Filmes 720p Aventura"}
|
||||
- {id: 61, cat: Movies/HD, desc: "Filmes 720p Clássico"}
|
||||
- {id: 62, cat: Movies/HD, desc: "Filmes 720p Comédia"}
|
||||
- {id: 72, cat: Movies/HD, desc: "Filmes 720p Documentário"}
|
||||
- {id: 64, cat: Movies/HD, desc: "Filmes 720p Drama"}
|
||||
- {id: 65, cat: Movies/HD, desc: "Filmes 720p Ficção"}
|
||||
- {id: 66, cat: Movies/HD, desc: "Filmes 720p Guerra"}
|
||||
- {id: 129, cat: Movies/HD, desc: "Filmes 720p Infantil"}
|
||||
- {id: 98, cat: Movies/HD, desc: "Filmes 720p Musical"}
|
||||
- {id: 59, cat: Movies/HD, desc: "Filmes 720p Outros"}
|
||||
- {id: 70, cat: Movies/HD, desc: "Filmes 720p Policial"}
|
||||
- {id: 57, cat: Movies/HD, desc: "Filmes 720p Religioso"}
|
||||
- {id: 71, cat: Movies/HD, desc: "Filmes 720p Romance"}
|
||||
- {id: 90, cat: Movies/HD, desc: "Filmes 720p Shows"}
|
||||
- {id: 68, cat: Movies/HD, desc: "Filmes 720p Suspense"}
|
||||
- {id: 69, cat: Movies/HD, desc: "Filmes 720p Terror"}
|
||||
- {id: 134, cat: Movies/HD, desc: "Filmes 720p Thriller"}
|
||||
- {id: 137, cat: Movies/HD, desc: "Filmes 720p Western"}
|
||||
|
||||
#GAMES
|
||||
- {id: 6, cat: Console, desc: "Jogos Console"}
|
||||
- {id: 51, cat: PC/Games, desc: "Jogos Emuladores"}
|
||||
- {id: 44, cat: Console, desc: "Jogos Gamecube"}
|
||||
- {id: 43, cat: Console/NDS, desc: "Jogos Nintendo DS"}
|
||||
- {id: 52, cat: Console, desc: "Jogos Outros"}
|
||||
- {id: 5, cat: PC/Games, desc: "Jogos PC"}
|
||||
- {id: 47, cat: Console, desc: "Jogos PS2"}
|
||||
- {id: 48, cat: Console, desc: "Jogos PS3"}
|
||||
- {id: 170, cat: Console, desc: "Jogos PS4"}
|
||||
- {id: 46, cat: Console, desc: "Jogos PSP"}
|
||||
- {id: 45, cat: Console/Wii, desc: "Jogos Wii"}
|
||||
- {id: 49, cat: Console/Xbox, desc: "Jogos XBOX"}
|
||||
- {id: 50, cat: Console/Xbox 360, desc: "Jogos XBOX360"}
|
||||
- {id: 171, cat: Console, desc: "Jogos XBOXONE"}
|
||||
|
||||
#MUSIC
|
||||
- {id: 29, cat: Audio, desc: "Musica Discografia"}
|
||||
- {id: 28, cat: Audio, desc: "Musica Gospel"}
|
||||
- {id: 139, cat: Audio, desc: "Musica Infantil"}
|
||||
- {id: 27, cat: Audio, desc: "Musica Internacionais"}
|
||||
- {id: 26, cat: Audio, desc: "Musica Nacionais"}
|
||||
- {id: 91, cat: Audio, desc: "Musica Outros"}
|
||||
|
||||
#TV-SERIES
|
||||
- {id: 35, cat: TV/HD, desc: "Séries HD"}
|
||||
- {id: 8, cat: TV, desc: "Séries"}
|
||||
|
||||
#SHOWS
|
||||
- {id: 13, cat: Audio/Video, desc: "Show"}
|
||||
- {id: 56, cat: Audio/Video, desc: "Video Clipes"}
|
||||
|
||||
#TV
|
||||
- {id: 53, cat: TV, desc: "Entretenimento"}
|
||||
- {id: 54, cat: TV/Sport, desc: "Esportes"}
|
||||
- {id: 138, cat: TV, desc: "Infantil"}
|
||||
- {id: 55, cat: TV, desc: "Jornalismo"}
|
||||
|
||||
#XXX
|
||||
- {id: 36, cat: XXX/Other, desc: "Anime Hentai"}
|
||||
- {id: 10, cat: XXX, desc: "Filmes Adultos"}
|
||||
- {id: 37, cat: XXX/Other, desc: "XXX Fotos"}
|
||||
- {id: 95, cat: XXX/Other, desc: "XXX Revistas"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
|
||||
login:
|
||||
path: account-login.php
|
||||
method: post
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
test:
|
||||
path: torrents.php
|
||||
|
||||
search:
|
||||
path: torrents-search.php
|
||||
keywordsfilters:
|
||||
- name: re_replace
|
||||
args: ["[^a-zA-Z0-9]+", "%"]
|
||||
inputs:
|
||||
search: "{{ .Keywords }}"
|
||||
rows:
|
||||
selector: table[class^="ttable_headinner"] > tbody > tr:has(a[href^="torrents-details.php?id="])
|
||||
fields:
|
||||
details:
|
||||
selector: a[href^="torrents-details.php?id="]
|
||||
attribute: href
|
||||
title:
|
||||
selector: a[href^="torrents-details.php?id="]
|
||||
download:
|
||||
selector: a[href^="torrents-details.php?id="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["torrents-details.php", "download.php"]
|
||||
category:
|
||||
selector: a[href^="torrents.php?cat="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
date:
|
||||
selector: td:nth-child(2) > span
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["(", ""]
|
||||
- name: replace
|
||||
args: [")", ""]
|
||||
size:
|
||||
selector: td:nth-child(3)
|
||||
grabs:
|
||||
selector: td:nth-child(4) > font > b
|
||||
seeders:
|
||||
selector: td:nth-child(5) > b > font
|
||||
leechers:
|
||||
selector: td:nth-child(6) > font > b
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"img[alt=\"[free]\"]": "0"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"img[alt=\"[+UP x2]\"]": "2"
|
||||
"*": "1"
|
83
src/Jackett/Definitions/blutopia.yml
Normal file
83
src/Jackett/Definitions/blutopia.yml
Normal file
@@ -0,0 +1,83 @@
|
||||
---
|
||||
site: blutopia
|
||||
name: Blutopia
|
||||
description: "HD Movie tracker"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://blutopia.xyz/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 1, cat: Movies, desc: "Movies"}
|
||||
- {id: 2, cat: TV, desc: "TV"}
|
||||
- {id: 3, cat: Movies, desc: "FANRES"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
|
||||
login:
|
||||
path: /login
|
||||
method: form
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
error:
|
||||
- selector: table.main:contains("Login Failed!")
|
||||
test:
|
||||
path: /torrents
|
||||
|
||||
download:
|
||||
selector: a[href^="/download.php/"]
|
||||
|
||||
search:
|
||||
path: /torrents/search
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
|
||||
name: "{{ .Query.Keywords }}"
|
||||
category_id: 1
|
||||
type: BD50
|
||||
order: created_at:desc
|
||||
rows:
|
||||
selector: table.table > tbody > tr
|
||||
fields:
|
||||
# category:
|
||||
# selector: a[href^="categories"]
|
||||
# attribute: href
|
||||
title:
|
||||
remove: ul
|
||||
selector: td:nth-child(2)
|
||||
download:
|
||||
selector: a.view-torrent
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["/torrents/", "/download/"]
|
||||
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: td:nth-child(3)
|
||||
filters:
|
||||
- name: append
|
||||
args: " ago"
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
#"i[data-original-title=\"100% Free\"]": "0"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
#"i[data-original-title=\"Double upload\"]": "2"
|
||||
"*": "1"
|
@@ -120,7 +120,7 @@
|
||||
search_type: "name"
|
||||
searchin: "title"
|
||||
error:
|
||||
- selector: div.error
|
||||
- selector: div.error:not(:contains("Não existem resultados encontrados."))
|
||||
rows:
|
||||
selector: table#torrents_table_classic > tbody > tr:has(td.torrent_name)
|
||||
fields:
|
||||
|
88
src/Jackett/Definitions/cpabien.yml
Normal file
88
src/Jackett/Definitions/cpabien.yml
Normal file
@@ -0,0 +1,88 @@
|
||||
---
|
||||
site: cpasbien
|
||||
name: cpasbien
|
||||
language: fr-fr
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://cpabien.cc/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: films, cat: Movies, desc: "Movies"}
|
||||
- {id: series, cat: TV, desc: "TV"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
settings: []
|
||||
|
||||
download:
|
||||
selector: "#telecharger"
|
||||
|
||||
search:
|
||||
path: "/search.php?t={{ .Query.Keywords }}"
|
||||
rows:
|
||||
selector: div[class^='ligne']
|
||||
fields:
|
||||
site_date:
|
||||
selector: a
|
||||
filters:
|
||||
# date is at the end of the title, so we get it and name it site_date
|
||||
- name: regexp
|
||||
args: "(\\w+)$"
|
||||
title:
|
||||
selector: a
|
||||
filters:
|
||||
# now we put the date at the right place according scene naming rules using .Result.site_date
|
||||
- name: replace
|
||||
args: ["FRENCH", "{{ .Result.site_date }} FRENCH"]
|
||||
- name: replace
|
||||
args: ["TRUEFRENCH", "{{ .Result.site_date }} TRUEFRENCH"]
|
||||
- name: replace
|
||||
args: ["VOSTFR", "{{ .Result.site_date }} VOSTFR"]
|
||||
# and we delete it at the end
|
||||
- name: re_replace
|
||||
args: ["(\\w+)$", ""]
|
||||
details:
|
||||
selector: a
|
||||
attribute: href
|
||||
download:
|
||||
selector: a
|
||||
attribute: href
|
||||
size:
|
||||
selector: div.poid
|
||||
filters:
|
||||
- name: re_replace
|
||||
args: [ "\\.(\\d) Ko", "$1X00"]
|
||||
- name: re_replace
|
||||
args: [ " Ko", "000"]
|
||||
- name: re_replace
|
||||
args: [ "\\.(\\d) Mo", "$1X00000"]
|
||||
- name: re_replace
|
||||
args: [ " Mo", "000000"]
|
||||
- name: re_replace
|
||||
args: [ "\\.(\\d) Go", "$1X00000000"]
|
||||
- name: re_replace
|
||||
args: [ " Go", "000000000"]
|
||||
- name: re_replace
|
||||
args: [ "\\.(\\d) To", "$1X00000000000"]
|
||||
- name: re_replace
|
||||
args: [ " To", "000000000000"]
|
||||
- name: replace
|
||||
args: [ "X", "" ]
|
||||
seeders:
|
||||
text: 0
|
||||
seeders:
|
||||
selector: div.up
|
||||
optional: true
|
||||
leechers:
|
||||
text: 0
|
||||
leechers:
|
||||
selector: div.down
|
||||
optional: true
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
125
src/Jackett/Definitions/cztorrent.yml
Normal file
125
src/Jackett/Definitions/cztorrent.yml
Normal file
@@ -0,0 +1,125 @@
|
||||
---
|
||||
site: cztorrent
|
||||
name: CzTorrent
|
||||
language: cs-cz
|
||||
type: semi-private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://tracker.cztorrent.net/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 1, cat: Movies, desc: "Filmy"}
|
||||
- {id: 25, cat: TV, desc: "Seriály"}
|
||||
- {id: 23, cat: TV/Documentary, desc: "Filmy - dokument"}
|
||||
- {id: 22, cat: PC, desc: "Aplikace"}
|
||||
- {id: 36, cat: Movies/3D, desc: "Filmy - 3D"}
|
||||
- {id: 35, cat: Movies/Other, desc: "Filmy - anime"}
|
||||
- {id: 37, cat: Movies/BluRay, desc: "Filmy - Blu-ray"}
|
||||
- {id: 11, cat: Movies/DVD, desc: "Filmy - DVD"}
|
||||
- {id: 30, cat: Movies/DVD, desc: "Filmy - DVD full"}
|
||||
- {id: 5, cat: Movies, desc: "Filmy - kreslené"}
|
||||
- {id: 31, cat: Movies/HD, desc: "HD"}
|
||||
- {id: 38, cat: Movies/HD, desc: "HD-LQ"}
|
||||
- {id: 3, cat: PC/Games, desc: "Hry"}
|
||||
- {id: 2, cat: Audio, desc: "Hudba"}
|
||||
- {id: 34, cat: Audio/Video, desc: "Hudba DVD/HD"}
|
||||
- {id: 6, cat: Books, desc: "Knihy"}
|
||||
- {id: 13, cat: Console, desc: "Konzole"}
|
||||
- {id: 32, cat: Audio, desc: "Mluvené slovo"}
|
||||
- {id: 16, cat: PC/Phone-Other, desc: "Mobil, PDA"}
|
||||
- {id: 4, cat: Other, desc: "Ostatní"}
|
||||
- {id: 29, cat: Audio, desc: "Soundtrack"}
|
||||
- {id: 19, cat: Audio/Video, desc: "Videoklipy"}
|
||||
- {id: 24, cat: XXX, desc: "xXx"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
login:
|
||||
path: /login-page
|
||||
method: form
|
||||
form: form[action^="/login"]
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
persistent_login: "1"
|
||||
error:
|
||||
- selector: div.error
|
||||
test:
|
||||
path: /torrents
|
||||
|
||||
search:
|
||||
path: /torrents
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
|
||||
s: "{{ .Keywords }}"
|
||||
t: "1"
|
||||
rows:
|
||||
selector: tr.torr_hover
|
||||
fields:
|
||||
title:
|
||||
selector: td.detaily a
|
||||
filters:
|
||||
- name: re_replace
|
||||
args: [".*? / ", ""]
|
||||
category:
|
||||
selector: td:nth-child(2)
|
||||
case:
|
||||
":contains(\"Filmy\")": 1
|
||||
":contains(\"Seriály\")": 25
|
||||
":contains(\"Filmy - dokument\")": 23
|
||||
":contains(\"Aplikace\")": 22
|
||||
":contains(\"Filmy - 3D\")": 36
|
||||
":contains(\"Filmy - anime\")": 35
|
||||
":contains(\"Filmy - Blu-ray\")": 37
|
||||
":contains(\"Filmy - DVD\")": 11
|
||||
":contains(\"Filmy - DVD full\")": 30
|
||||
":contains(\"Filmy - kreslené\")": 5
|
||||
":contains(\"HD\")": 31
|
||||
":contains(\"HD-LQ\")": 38
|
||||
":contains(\"Hry\")": 3
|
||||
":contains(\"Hudba\")": 2
|
||||
":contains(\"Hudba DVD/HD\")": 34
|
||||
":contains(\"Knihy\")": 6
|
||||
":contains(\"Konzole\")": 13
|
||||
":contains(\"Mluvené slovo\")": 32
|
||||
":contains(\"Mobil, PDA\")": 16
|
||||
":contains(\"Ostatní\")": 4
|
||||
":contains(\"Soundtrack\")": 29
|
||||
":contains(\"Videoklipy\")": 19
|
||||
":contains(\"xXx\")": 24
|
||||
details:
|
||||
selector: td.detaily a
|
||||
attribute: href
|
||||
download:
|
||||
selector: td.download a
|
||||
attribute: href
|
||||
size:
|
||||
selector: td.detaily
|
||||
filters:
|
||||
- name: split
|
||||
args: [ "|", 0 ]
|
||||
- name: regexp
|
||||
args: "Velikost: (.+?) ?$"
|
||||
date:
|
||||
selector: td:nth-child(4)
|
||||
filters:
|
||||
- name: split
|
||||
args: [ "|", 1 ]
|
||||
- name: regexp
|
||||
args: "Přidán: (.+?) ?$"
|
||||
- name: append
|
||||
args: " +02:00"
|
||||
seeders:
|
||||
selector: td:nth-child(7) span
|
||||
leechers:
|
||||
selector: td:nth-child(8) span
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
@@ -67,11 +67,15 @@
|
||||
search: "{{ .Query.Keywords }}"
|
||||
incldead: 1
|
||||
rows:
|
||||
selector: tr:has(a.tname)
|
||||
selector: div.ncls > table > tbody > tr:has(a.tname)
|
||||
fields:
|
||||
title:
|
||||
title-attribute:
|
||||
selector: a.tname
|
||||
attribute: title
|
||||
title-text:
|
||||
selector: a.tname
|
||||
title:
|
||||
text: "{{if .Result.title-attribute }}{{ .Result.title-attribute }}{{else}}{{ .Result.title-text }}{{end}}"
|
||||
details:
|
||||
selector: a.tname
|
||||
attribute: href
|
||||
@@ -82,34 +86,37 @@
|
||||
- name: querystring
|
||||
args: cat
|
||||
download:
|
||||
selector: a[href^="/download.php/"]
|
||||
selector: a[href^="/download.php/"], a[href^="/downloadd.php/"] # some releases use a download link with two d's
|
||||
attribute: href
|
||||
grabs:
|
||||
selector: td:nth-child(7)
|
||||
selector: td:nth-child(8)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: (\d+)
|
||||
size:
|
||||
selector: td:nth-child(6)
|
||||
selector: td:nth-child(7)
|
||||
date:
|
||||
selector: td:nth-child(2) > right > div:has(font:contains("Uploaded"))
|
||||
remove: div > font
|
||||
filters:
|
||||
- name: trim
|
||||
args: ":"
|
||||
- name: replace
|
||||
args: ["Uploaded: ", ""]
|
||||
seeders:
|
||||
selector: td:nth-child(8)
|
||||
leechers:
|
||||
selector: td:nth-child(9)
|
||||
leechers:
|
||||
selector: td:nth-child(10)
|
||||
banner:
|
||||
selector: a.tname
|
||||
attribute: onmouseover
|
||||
filters:
|
||||
- name: regexp
|
||||
args: src=([^\s]+)
|
||||
imdb:
|
||||
selector: a[href^="http://www.imdb.com/title/"]
|
||||
optional: true
|
||||
attribute: href
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"img[src=\"pic/free.gif\"]": "0"
|
||||
"img[src=\"pic/free.png\"]": "0"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
|
92
src/Jackett/Definitions/deildu.yml
Normal file
92
src/Jackett/Definitions/deildu.yml
Normal file
@@ -0,0 +1,92 @@
|
||||
---
|
||||
site: deildu
|
||||
name: Deildu
|
||||
language: is-is
|
||||
type: semi-private
|
||||
encoding: iso-8859-1
|
||||
links:
|
||||
- https://deildu.net/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 11, cat: Audio, desc: "Music"}
|
||||
- {id: 6, cat: Movies, desc: "Movies"}
|
||||
- {id: 5, cat: Movies/DVD, desc: "Movies DVDR"}
|
||||
- {id: 8, cat: TV, desc: "TV shows"}
|
||||
- {id: 12, cat: Movies/HD, desc: "HD Movies"}
|
||||
- {id: 12, cat: TV/HD, desc: "HD TV"}
|
||||
- {id: 9, cat: TV/Documentary, desc: "TV - Documentaries"}
|
||||
- {id: 9, cat: Movies/Other, desc: "Movie - Documentaries"}
|
||||
- {id: 2, cat: TV/Sport, desc: "Sports"}
|
||||
- {id: 7, cat: Movies/Other, desc: "Cartoons"}
|
||||
- {id: 14, cat: PC, desc: "Windows"}
|
||||
- {id: 3, cat: PC/Mac, desc: "Mac"}
|
||||
- {id: 10, cat: PC/Games, desc: "Games"}
|
||||
- {id: 4, cat: XXX, desc: "XXX"}
|
||||
- {id: 1, cat: Other, desc: "Other"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
login:
|
||||
path: takelogin.php
|
||||
method: post
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
keeplogged: 1
|
||||
|
||||
test:
|
||||
path: my.php
|
||||
|
||||
search:
|
||||
path: browse.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
incldead: "1"
|
||||
rows:
|
||||
selector: table[class="torrentlist"] > tbody > tr:has(a[href*="details.php?id="])
|
||||
filters:
|
||||
- name: andmatch
|
||||
args: 55
|
||||
fields:
|
||||
download:
|
||||
selector: a[href^="download.php"]
|
||||
attribute: href
|
||||
title:
|
||||
selector: td:nth-child(2)
|
||||
# category:
|
||||
# selector: a[href^="browse.php?cat="]
|
||||
# attribute: href
|
||||
# filters:
|
||||
# - name: querystring
|
||||
# args: cat
|
||||
details:
|
||||
selector: a[href^="details.php?id="]
|
||||
attribute: href
|
||||
size:
|
||||
selector: td:nth-child(7)
|
||||
files:
|
||||
selector: td:nth-child(4)
|
||||
grabs:
|
||||
selector: td:nth-child(8)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: ([\d,]+)
|
||||
seeders:
|
||||
selector: td:nth-child(9)
|
||||
leechers:
|
||||
selector: td:nth-child(10)
|
||||
date:
|
||||
selector: td:nth-child(6)
|
||||
filters:
|
||||
- name: dateparse
|
||||
args: "2006-01-0215:04:05"
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
@@ -58,32 +58,25 @@
|
||||
movie-search: [q]
|
||||
|
||||
login:
|
||||
path: login.php
|
||||
submitpath: login.php
|
||||
path: login
|
||||
submitpath: login/run
|
||||
method: form
|
||||
inputs:
|
||||
referer: ""
|
||||
nev: "{{ .Config.username }}"
|
||||
jelszo: "{{ .Config.password }}"
|
||||
fsv: "-1"
|
||||
ssl: "1"
|
||||
fsv: "0"
|
||||
login: "1"
|
||||
belepes: "1"
|
||||
getselectorinputs:
|
||||
c:
|
||||
selector: "script:contains(\"login.php\")"
|
||||
filters:
|
||||
- name: regexp
|
||||
args: "login.php\\?c=(.*?)&rhash="
|
||||
rhash:
|
||||
text: "123"
|
||||
rhash: "123"
|
||||
test:
|
||||
path: browse.php
|
||||
path: browse
|
||||
|
||||
search:
|
||||
path: browse.php
|
||||
path: browse
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}category[]={{.}}&{{end}}"
|
||||
cim: "{{ .Keywords }}"
|
||||
search: "{{ .Keywords }}"
|
||||
s_alapjan: "7"
|
||||
s_sorrend: "desc"
|
||||
rows:
|
||||
@@ -93,10 +86,8 @@
|
||||
download:
|
||||
selector: div.box_download > a
|
||||
attribute: href
|
||||
#title: # shortened
|
||||
# selector: a.box_name_a
|
||||
title:
|
||||
selector: div.torrent_details_po + h2
|
||||
selector: a.box_name_a > span
|
||||
details:
|
||||
selector: a.box_name_a
|
||||
attribute: href
|
||||
|
@@ -1,154 +0,0 @@
|
||||
---
|
||||
site: dragonworld
|
||||
name: Dragon World (DTW)
|
||||
language: de-de
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://dtw.sytes.net/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
# Dokumentation
|
||||
- {id: 46, cat: TV/Documentary, desc: "Dokumentation"}
|
||||
- {id: 55, cat: TV/Documentary, desc: "Dokumentation/HD"}
|
||||
- {id: 56, cat: TV/Documentary, desc: "Dokumentation/SD"}
|
||||
# Ebooks
|
||||
- {id: 36, cat: Books, desc: "Ebooks"}
|
||||
- {id: 37, cat: Books, desc: "Ebooks"}
|
||||
- {id: 38, cat: Books, desc: "Ebooks/Hoerspiele/Hoerbuecher"}
|
||||
# Games
|
||||
- {id: 21, cat: Console, desc: "Games"}
|
||||
- {id: 24, cat: Console/Other, desc: "Games/Nintendo"}
|
||||
- {id: 22, cat: PC/Games, desc: "Games/PC"}
|
||||
- {id: 23, cat: Console/PS4, desc: "Games/Playstation"}
|
||||
- {id: 25, cat: Console/Xbox, desc: "Games/Xbox"}
|
||||
# Kinder
|
||||
- {id: 10, cat: Other, desc: "Kinder"}
|
||||
- {id: 14, cat: Other, desc: "Kinder/Diverses"}
|
||||
- {id: 12, cat: Movies, desc: "Kinder/Filme"}
|
||||
- {id: 11, cat: PC/Games, desc: "Kinder/Games"}
|
||||
- {id: 13, cat: Audio, desc: "Kinder/Musik"}
|
||||
# Movies
|
||||
- {id: 15, cat: Movies, desc: "Movies"}
|
||||
- {id: 50, cat: Movies/3D, desc: "Movies/3D"}
|
||||
- {id: 48, cat: Movies/HD, desc: "Movies/HD"}
|
||||
- {id: 53, cat: Movies/HD, desc: "Movies/HD Pack"}
|
||||
- {id: 45, cat: Movies/HD, desc: "Movies/Remuxe"}
|
||||
- {id: 17, cat: Movies/SD, desc: "Movies/SD"}
|
||||
- {id: 54, cat: Movies/SD, desc: "Movies/SD Pack"}
|
||||
# Musik
|
||||
- {id: 4, cat: Audio, desc: "Musik"}
|
||||
- {id: 57, cat: Audio, desc: "Musik/Album"}
|
||||
- {id: 8, cat: Audio/Lossless, desc: "Musik/Flac"}
|
||||
- {id: 7, cat: Audio/MP3, desc: "Musik/Mp3"}
|
||||
- {id: 9, cat: Audio/Video, desc: "Musik/Video"}
|
||||
# Serien
|
||||
- {id: 26, cat: TV, desc: "Serien"}
|
||||
- {id: 27, cat: TV/HD, desc: "Serien/HD"}
|
||||
- {id: 28, cat: TV/SD, desc: "Serien/SD"}
|
||||
# Software
|
||||
- {id: 29, cat: PC/0day, desc: "Software"}
|
||||
- {id: 32, cat: PC/0day, desc: "Software/Diverses"}
|
||||
- {id: 31, cat: PC/Mac, desc: "Software/Mac"}
|
||||
- {id: 30, cat: PC/0day, desc: "Software/Windows"}
|
||||
# Sport
|
||||
- {id: 39, cat: TV/Sport, desc: "Sport"}
|
||||
- {id: 40, cat: TV/Sport, desc: "Sport HD"}
|
||||
- {id: 58, cat: TV/Sport, desc: "Sport SD"}
|
||||
# XXX
|
||||
- {id: 33, cat: XXX, desc: "XXX"}
|
||||
- {id: 34, cat: XXX, desc: "XXX/HD"}
|
||||
- {id: 35, cat: XXX, desc: "XXX/SD"}
|
||||
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
login:
|
||||
path: takelogin.php
|
||||
method: post
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
error:
|
||||
- selector: table:has(td:contains("Ein Fehler ist aufgetreten"))
|
||||
test:
|
||||
path: browse.php
|
||||
selector: a[href*="/logout.php"]
|
||||
|
||||
download:
|
||||
before:
|
||||
path: "takethanks.php"
|
||||
method: "post"
|
||||
inputs:
|
||||
torrentid: "{{ .DownloadUri.Query.id }}"
|
||||
|
||||
search:
|
||||
path: browse.php
|
||||
keywordsfilters:
|
||||
- name: re_replace
|
||||
args: ["[^a-zA-Z0-9]+", "%"]
|
||||
inputs:
|
||||
do: "search"
|
||||
keywords: "{{ .Keywords }}"
|
||||
search_type: "t_name"
|
||||
category: "0" # multi cat search not supported
|
||||
include_dead_torrents: "yes"
|
||||
rows:
|
||||
selector: table#sortabletable > tbody > tr:has(a[href*="/details.php?id="])
|
||||
filters:
|
||||
- name: andmatch
|
||||
args: 66
|
||||
fields:
|
||||
download:
|
||||
selector: a[href*="/download.php?id="]
|
||||
attribute: href
|
||||
magnet:
|
||||
selector: a[href^="magnet:"]
|
||||
attribute: href
|
||||
title:
|
||||
selector: a[href*="/details.php?id="]
|
||||
title:
|
||||
selector: div.tooltip-content > div
|
||||
optional: true
|
||||
details:
|
||||
selector: a[href*="/details.php?id="]
|
||||
attribute: href
|
||||
category:
|
||||
selector: a[href*="/browse.php?category="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: category
|
||||
banner:
|
||||
selector: div.tooltip-content > img
|
||||
attribute: src
|
||||
optional: true
|
||||
size:
|
||||
selector: td:nth-child(5)
|
||||
grabs:
|
||||
selector: td:nth-child(6)
|
||||
seeders:
|
||||
selector: td:nth-child(7)
|
||||
leechers:
|
||||
selector: td:nth-child(8)
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
img[alt^="OnlyUp Torrent"]: "0"
|
||||
img[alt^="50% "]: "0.5"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
img[alt^="multi2 Torrent"]: "2"
|
||||
"*": "1"
|
||||
date:
|
||||
selector: "td:nth-child(2) > div:has(span[style=\"float: right;\"])"
|
||||
remove: span
|
||||
filters:
|
||||
- name: append
|
||||
args: " +01:00"
|
||||
- name: dateparse
|
||||
args: "02-01-2006 15:04 -07:00"
|
@@ -6,7 +6,7 @@
|
||||
type: private
|
||||
encoding: windows-1252
|
||||
links:
|
||||
- http://eot-forum.net
|
||||
- https://eot-forum.net
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
|
@@ -7,6 +7,16 @@
|
||||
links:
|
||||
- http://freedom-paradise.eu/
|
||||
|
||||
download:
|
||||
before:
|
||||
path: "list_thanks.php"
|
||||
method: "get"
|
||||
inputs:
|
||||
id: "{{ .DownloadUri.Query.id }}"
|
||||
to: "give"
|
||||
torrent: "{{ .DownloadUri.Query.id }}"
|
||||
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
# ANIMES
|
||||
|
114
src/Jackett/Definitions/gay-torrents.yml
Normal file
114
src/Jackett/Definitions/gay-torrents.yml
Normal file
@@ -0,0 +1,114 @@
|
||||
site: gay-torrents
|
||||
name: Gay-Torrents.net
|
||||
description: "Gay Torrents Live Free!"
|
||||
language: en-us
|
||||
type: semi-private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://www.gay-torrents.net/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: porn , cat: XXX , desc: "Porn"}
|
||||
- {id: porn/Amateur , cat: XXX , desc: "Amateur"}
|
||||
- {id: porn/Anal , cat: XXX , desc: "Anal"}
|
||||
- {id: porn/Asian , cat: XXX , desc: "Asian"}
|
||||
- {id: porn/Bareback , cat: XXX , desc: "Bareback"}
|
||||
- {id: porn/Bears , cat: XXX , desc: "Bears"}
|
||||
- {id: porn/Bisexual , cat: XXX , desc: "Bisexual"}
|
||||
- {id: porn/Black-Men , cat: XXX , desc: "Black-Men"}
|
||||
- {id: porn/Chubs , cat: XXX , desc: "Chubs"}
|
||||
- {id: porn/Clips , cat: XXX/Packs , desc: "Clips"}
|
||||
- {id: porn/Cross-Generation , cat: XXX , desc: "Cross-Generation"}
|
||||
- {id: porn/DVD-R , cat: XXX/DVD , desc: "DVD-R"}
|
||||
- {id: porn/Fetish , cat: XXX , desc: "Fetish"}
|
||||
- {id: porn/Group-Sex , cat: XXX , desc: "Group-Sex"}
|
||||
- {id: porn/HD-Movies , cat: XXX , desc: "HD-Movies"}
|
||||
- {id: porn/Hunks , cat: XXX , desc: "Hunks"}
|
||||
- {id: porn/Images , cat: XXX/Imageset , desc: "Images"}
|
||||
- {id: porn/Interracial , cat: XXX , desc: "Interracial"}
|
||||
- {id: porn/Jocks , cat: XXX , desc: "Jocks"}
|
||||
- {id: porn/Latino , cat: XXX , desc: "Latino"}
|
||||
- {id: porn/Mature , cat: XXX , desc: "Mature"}
|
||||
- {id: porn/Member , cat: XXX , desc: "Member"}
|
||||
- {id: porn/MiddleEast , cat: XXX , desc: "MiddleEast"}
|
||||
- {id: porn/Military , cat: XXX , desc: "Military"}
|
||||
- {id: porn/Muscle , cat: XXX , desc: "Muscle"}
|
||||
- {id: porn/Oral-Sex , cat: XXX , desc: "Oral-Sex"}
|
||||
- {id: porn/Solo , cat: XXX , desc: "Solo"}
|
||||
- {id: porn/Transsexual , cat: XXX , desc: "Transsexual"}
|
||||
- {id: porn/Twinks , cat: XXX , desc: "Twinks"}
|
||||
- {id: porn/Vintage , cat: XXX , desc: "Vintage"}
|
||||
- {id: porn/Wrestling , cat: XXX , desc: "Wrestling"}
|
||||
- {id: nonporn , cat: Other , desc: "NonPorn"}
|
||||
- {id: nonporn/Anime , cat: TV/Anime , desc: "Anime"}
|
||||
- {id: nonporn/Applications , cat: PC , desc: "Applications"}
|
||||
- {id: nonporn/Comedy , cat: Movies , desc: "Comedy"}
|
||||
- {id: nonporn/Comics , cat: Books/Comics , desc: "Comics"}
|
||||
- {id: nonporn/Coming-Out , cat: Movies , desc: "Coming-Out"}
|
||||
- {id: nonporn/Documentary , cat: Movies , desc: "Documentary"}
|
||||
- {id: nonporn/Drama , cat: Movies , desc: "Drama"}
|
||||
- {id: nonporn/DVD-R , cat: Movies/DVD , desc: "DVD-R"}
|
||||
- {id: nonporn/Gay-Movies , cat: Movies , desc: "Gay-Movies"}
|
||||
- {id: nonporn/Misc , cat: Other/Misc , desc: "Misc"}
|
||||
- {id: nonporn/Short-Film , cat: Movies , desc: "Short-Film"}
|
||||
- {id: nonporn/Softcore , cat: Movies , desc: "Softcore"}
|
||||
- {id: nonporn/Thriller , cat: Movies , desc: "Thriller"}
|
||||
- {id: nonporn/TV-Episode , cat: TV , desc: "TV-Episode"}
|
||||
modes:
|
||||
search: [q]
|
||||
|
||||
login:
|
||||
path: login.php
|
||||
method: post
|
||||
inputs:
|
||||
vb_login_username: "{{ .Config.username }}"
|
||||
vb_login_password: "{{ .Config.password }}"
|
||||
cookieuser: "1"
|
||||
do: "login"
|
||||
test:
|
||||
path: torrentslist.php
|
||||
selector: ul.isuser
|
||||
|
||||
search:
|
||||
path: "{{if .Query.Keywords}}search.php{{else}}torrentslist.php{{end}}"
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}type={{.}}&{{end}}"
|
||||
textsearch: "{{ .Query.Keywords }}"
|
||||
rows:
|
||||
selector: ul.TorrentList
|
||||
fields:
|
||||
category:
|
||||
selector: .TorrentList1 > a
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: type
|
||||
title:
|
||||
selector: .TorrentList2 > a
|
||||
download:
|
||||
selector: .TorrentList2 > a
|
||||
attribute: href
|
||||
filters:
|
||||
- name: append
|
||||
args: "&do=download"
|
||||
details:
|
||||
selector: .TorrentList2 > a
|
||||
attribute: href
|
||||
size:
|
||||
selector: .TorrentList3
|
||||
seeders:
|
||||
selector: .TorrentList6
|
||||
leechers:
|
||||
selector: .TorrentList7
|
||||
date:
|
||||
selector: li.TorrentList8
|
||||
filters:
|
||||
- name: dateparse
|
||||
args: "02 Jan 06, 15:04"
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
".TorrentList2 > a:contains(\"[FFL]\")": "0"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
113
src/Jackett/Definitions/gaytorrentru.yml
Normal file
113
src/Jackett/Definitions/gaytorrentru.yml
Normal file
@@ -0,0 +1,113 @@
|
||||
site: gaytorrentru
|
||||
name: GayTorrent.ru
|
||||
description: "World largest gay porn library for free with a stunning forum and 24/7 Chat"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://www.gaytorrent.ru/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 62 , cat: XXX , desc: "Amateur"}
|
||||
- {id: 29 , cat: XXX , desc: "Anal"}
|
||||
- {id: 46 , cat: XXX , desc: "Anime Games"}
|
||||
- {id: 30 , cat: XXX , desc: "Asian"}
|
||||
- {id: 43 , cat: XXX , desc: "Bareback"}
|
||||
- {id: 19 , cat: XXX , desc: "BDSM"}
|
||||
- {id: 17 , cat: XXX , desc: "Bears"}
|
||||
- {id: 44 , cat: XXX , desc: "Black"}
|
||||
- {id: 50 , cat: Books , desc: "Books & Magazines"}
|
||||
- {id: 9 , cat: XXX , desc: "Chubbies"}
|
||||
- {id: 7 , cat: XXX , desc: "Clips"}
|
||||
- {id: 48 , cat: Books/Comics , desc: "Comic & Yaoi"}
|
||||
- {id: 5 , cat: XXX , desc: "Daddies / Sons"}
|
||||
- {id: 34 , cat: XXX , desc: "Fetish"}
|
||||
- {id: 27 , cat: XXX , desc: "Grey / Older"}
|
||||
- {id: 32 , cat: XXX , desc: "Group-Sex"}
|
||||
- {id: 63 , cat: XXX , desc: "Homemade"}
|
||||
- {id: 12 , cat: XXX , desc: "Hunks"}
|
||||
- {id: 33 , cat: XXX , desc: "Images"}
|
||||
- {id: 53 , cat: XXX , desc: "Interracial"}
|
||||
- {id: 57 , cat: XXX , desc: "Jocks"}
|
||||
- {id: 35 , cat: XXX , desc: "Latino"}
|
||||
- {id: 36 , cat: XXX , desc: "Mature"}
|
||||
- {id: 58 , cat: PC , desc: "Media Programs"}
|
||||
- {id: 37 , cat: XXX , desc: "Member"}
|
||||
- {id: 54 , cat: XXX , desc: "Middle Eastern"}
|
||||
- {id: 38 , cat: XXX , desc: "Military"}
|
||||
- {id: 39 , cat: XXX , desc: "Oral-Sex"}
|
||||
- {id: 47 , cat: XXX , desc: "Shemale"}
|
||||
- {id: 56 , cat: XXX , desc: "Softcore"}
|
||||
- {id: 40 , cat: XXX , desc: "Solo"}
|
||||
- {id: 45 , cat: Movies , desc: "Themed Movie"}
|
||||
- {id: 1 , cat: TV , desc: "TV / Episodes"}
|
||||
- {id: 41 , cat: XXX , desc: "Twinks"}
|
||||
- {id: 42 , cat: XXX , desc: "Vintage"}
|
||||
- {id: 51 , cat: XXX , desc: "Voyeur"}
|
||||
- {id: 65 , cat: XXX , desc: "Wrestling and Sports"}
|
||||
- {id: 28 , cat: XXX , desc: "Youngblood"}
|
||||
modes:
|
||||
search: [q]
|
||||
|
||||
login:
|
||||
path: takelogin.php
|
||||
method: post
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
test:
|
||||
path: browse.php
|
||||
|
||||
search:
|
||||
path: browse.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
incldead: "0" # Searches only for alive torrents
|
||||
rows:
|
||||
selector: table.browse_result > tbody > tr:has(a[href^="details.php?id="])
|
||||
fields:
|
||||
category:
|
||||
selector: a[href^="browse.php?cat="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
title:
|
||||
selector: .browsedesc > a
|
||||
download:
|
||||
selector: a[href^="download.php/"]
|
||||
attribute: href
|
||||
details:
|
||||
selector: a[href^="details.php?id="]
|
||||
attribute: href
|
||||
grabs:
|
||||
selector: .tsnatch
|
||||
files:
|
||||
selector: .tfiles
|
||||
filters:
|
||||
- name: regexp
|
||||
args: ([\d]+)
|
||||
size:
|
||||
selector: .tsize
|
||||
seeders:
|
||||
optional: true
|
||||
selector: a[href$="&toseeders=1"]
|
||||
leechers:
|
||||
optional: true
|
||||
selector: a[href$="&todlers=1"]
|
||||
date:
|
||||
selector: .tadded
|
||||
filters:
|
||||
- name: re_replace
|
||||
args: ["(\\d{4}-\\d{2}-\\d{2})(\\d{2}:\\d{2}:\\d{2})(.*)","$1 $2"]
|
||||
- name: dateparse
|
||||
args: "2006-01-02 15:04:05"
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"td:nth-child(3) > div > nobr > font[color=\"yellow\"]": "0"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
@@ -70,6 +70,8 @@
|
||||
blah: "0"
|
||||
rows:
|
||||
selector: table#torrenttable > tbody > tr:has()
|
||||
error:
|
||||
- selector: div.content:contains("Meg van vonva a letöltési jogod")
|
||||
fields:
|
||||
download:
|
||||
selector: a[href^="/details.php?id="]
|
||||
|
@@ -119,9 +119,9 @@
|
||||
download:
|
||||
text: "download2.php?torrent={{ .Result._id }}"
|
||||
size:
|
||||
selector: td:nth-last-child(3)
|
||||
selector: td:nth-last-child(4)
|
||||
date:
|
||||
selector: td:nth-last-child(5)
|
||||
selector: td:nth-last-child(6) > nobr
|
||||
filters:
|
||||
- name: append
|
||||
args: " +02:00"
|
||||
@@ -130,9 +130,9 @@
|
||||
files:
|
||||
selector: td:nth-last-child(7)
|
||||
seeders:
|
||||
selector: td:nth-last-child(2)
|
||||
selector: td:nth-last-child(3)
|
||||
leechers:
|
||||
selector: td:nth-last-child(1)
|
||||
selector: td:nth-last-child(2)
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"img[src=\"pic/free.png\"]": "0"
|
||||
|
63
src/Jackett/Definitions/horriblesubs.yml
Normal file
63
src/Jackett/Definitions/horriblesubs.yml
Normal file
@@ -0,0 +1,63 @@
|
||||
---
|
||||
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/
|
||||
|
||||
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:
|
||||
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"
|
@@ -6,6 +6,8 @@
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://ilcorsaronero.info/
|
||||
certificates:
|
||||
- FFB230323B987B07C24DCC13BC892CF30536F015 # incomplete CA chain
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
|
@@ -76,7 +76,8 @@
|
||||
keywords: "{{ .Keywords }}"
|
||||
search_type: "name"
|
||||
searchin: "title"
|
||||
|
||||
error:
|
||||
- selector: div#show_error:not(:contains("Ουπς! Λάθος!Δεν βρέθηκαν αποτελέσματα."))
|
||||
rows:
|
||||
selector: div#content > div.torrent-box[id^="torrent_"]
|
||||
filters:
|
||||
|
@@ -30,9 +30,6 @@
|
||||
test:
|
||||
path: index.php
|
||||
|
||||
download:
|
||||
selector: a[href^="download.php?id="]
|
||||
|
||||
search:
|
||||
path: browse.php
|
||||
inputs:
|
||||
@@ -47,11 +44,8 @@
|
||||
title:
|
||||
selector: td:nth-child(2) span
|
||||
download:
|
||||
selector: a[href^="details.php?id="]
|
||||
selector: a[href^="down.php"]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["details.php?id=", "download.php?id="]
|
||||
details:
|
||||
selector: a[href^="details.php?id="]
|
||||
attribute: href
|
||||
|
4
src/Jackett/Definitions/kickasstorrent-kathow.yml
Normal file → Executable file
4
src/Jackett/Definitions/kickasstorrent-kathow.yml
Normal file → Executable file
@@ -1,11 +1,11 @@
|
||||
---
|
||||
site: kickasstorrent-kathow
|
||||
name: KickAssTorrent (kat.how)
|
||||
name: KickAssTorrent (thekat.se)
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://kat.how
|
||||
- https://thekat.se
|
||||
|
||||
caps:
|
||||
categories:
|
||||
|
9
src/Jackett/Definitions/kickasstorrent.yml
Normal file → Executable file
9
src/Jackett/Definitions/kickasstorrent.yml
Normal file → Executable file
@@ -68,7 +68,7 @@
|
||||
- {id: 153, cat: Other, desc: "Other - Wordpress"}
|
||||
- {id: 6, cat: TV/HD, desc: "TV - Blu-Ray Disc"}
|
||||
- {id: 7, cat: TV/Documentary, desc: "TV - Documentary"}
|
||||
- {id: 5, cat: TV/SD, desc: "TV - DVD Disc"}
|
||||
- {id: 5, cat: TV/SD, desc: "TV - DVD ISO"}
|
||||
- {id: 41, cat: TV/HD, desc: "TV - HD"}
|
||||
- {id: 151, cat: TV/Other, desc: "TV - Other"}
|
||||
- {id: 146, cat: TV/Sport, desc: "TV - Sport"}
|
||||
@@ -88,7 +88,7 @@
|
||||
settings: []
|
||||
|
||||
search:
|
||||
path: "/new/torrents-search.php"
|
||||
path: "/new/{{if .Query.Keywords}}search-torrents.php{{else}}index.php{{end}}"
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
|
||||
search: "\"{{ .Query.Keywords }}\""
|
||||
@@ -164,7 +164,7 @@
|
||||
":has(a:contains(\"Other\")):contains(\"Wordpress\")": 153
|
||||
":has(a:contains(\"TV\")):contains(\"Blu-Ray Disc\")": 6
|
||||
":has(a:contains(\"TV\")):contains(\"Documentary\")": 7
|
||||
":has(a:contains(\"TV\")):contains(\"DVD Disc\")": 5
|
||||
":has(a:contains(\"TV\")):contains(\"DVD ISO\")": 5
|
||||
":has(a:contains(\"TV\")):contains(\"HD\")": 41
|
||||
":has(a:contains(\"TV\")):contains(\"Other\")": 151
|
||||
":has(a:contains(\"TV\")):contains(\"Sport\")": 146
|
||||
@@ -176,6 +176,7 @@
|
||||
":has(a:contains(\"XXX\")):contains(\"UltraHD\")": 121
|
||||
":has(a:contains(\"XXX\")):contains(\"Videos\")": 119
|
||||
":has(a:contains(\"XXX\")):contains(\"XXX Games\")": 126
|
||||
"*": 0 # some older torrents's don't have a category
|
||||
details:
|
||||
selector: a.cellMainLink
|
||||
attribute: href
|
||||
@@ -184,8 +185,6 @@
|
||||
date:
|
||||
selector: td:nth-child(3)
|
||||
filters:
|
||||
- name: append
|
||||
args: " +00:00"
|
||||
- name: dateparse
|
||||
args: "02-01-2006 15:04:05 -07:00"
|
||||
seeders:
|
||||
|
@@ -1,163 +0,0 @@
|
||||
---
|
||||
site: leparadisdunet
|
||||
name: Le Paradis Du Net
|
||||
language: fr-fr
|
||||
type: semi-private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://le-paradis-du-net.com/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 10, cat: Movies/3D, desc: "3D"}
|
||||
- {id: 9, cat: XXX, desc: "Adultes"}
|
||||
- {id: 1, cat: PC, desc: "APPLICATION"}
|
||||
- {id: 33, cat: PC/Phone-Other, desc: " Iphone/Ipod/Android"}
|
||||
- {id: 3, cat: PC/0day, desc: " Linux"}
|
||||
- {id: 32, cat: PC/Mac, desc: " Mac"}
|
||||
- {id: 4, cat: PC/0day, desc: " Windows"}
|
||||
- {id: 70, cat: Movies/HD, desc: "BDRIP"}
|
||||
- {id: 69, cat: Movies/BluRay, desc: "Blueray"}
|
||||
- {id: 73, cat: Movies/HD, desc: "BRRIP"}
|
||||
- {id: 22, cat: Movies/SD, desc: "CAM TS SCREENER"}
|
||||
- {id: 39, cat: Movies/DVD, desc: " R5"}
|
||||
- {id: 13, cat: TV/Anime, desc: "DESSINS ANIMES"}
|
||||
- {id: 48, cat: TV/Anime, desc: " Animations"}
|
||||
- {id: 47, cat: TV/Anime, desc: " Mangas"}
|
||||
- {id: 14, cat: TV/Documentary, desc: "DOCUMENTAIRE"}
|
||||
- {id: 52, cat: TV/Documentary, desc: " EmissionsTV"}
|
||||
- {id: 49, cat: TV/Documentary, desc: " Tv docs"}
|
||||
- {id: 15, cat: Movies/DVD, desc: "DVDR"}
|
||||
- {id: 16, cat: Movies/SD, desc: "DVDRIP"}
|
||||
- {id: 35, cat: Movies, desc: " Action"}
|
||||
- {id: 64, cat: Movies, desc: " Autres"}
|
||||
- {id: 36, cat: Movies, desc: " Aventure"}
|
||||
- {id: 55, cat: Movies, desc: " Comédie"}
|
||||
- {id: 37, cat: Movies, desc: " Drame"}
|
||||
- {id: 38, cat: Movies, desc: " Fantastique"}
|
||||
- {id: 63, cat: Movies, desc: " Guerre"}
|
||||
- {id: 72, cat: Movies, desc: " Historique/Biopic"}
|
||||
- {id: 67, cat: Movies, desc: " Horreur"}
|
||||
- {id: 65, cat: Movies, desc: " Thriller"}
|
||||
- {id: 71, cat: Movies, desc: " Werstern"}
|
||||
- {id: 17, cat: Movies/SD, desc: "DVDRIP VOSTFR"}
|
||||
- {id: 19, cat: Books, desc: "EBOOK"}
|
||||
- {id: 54, cat: Books, desc: " Journaux"}
|
||||
- {id: 81, cat: Books, desc: " Magazines"}
|
||||
- {id: 82, cat: Books, desc: " People"}
|
||||
- {id: 40, cat: Movies/HD, desc: "HD"}
|
||||
- {id: 41, cat: Movies/HD, desc: " 1080p"}
|
||||
- {id: 42, cat: Movies/HD, desc: " 720P"}
|
||||
- {id: 77, cat: Movies/HD, desc: " HD LIGHT"}
|
||||
- {id: 86, cat: TV/SD, desc: " HDTV"}
|
||||
- {id: 20, cat: Console/Other, desc: "JEUX"}
|
||||
- {id: 56, cat: Console/NDS, desc: " DS"}
|
||||
- {id: 57, cat: PC/Games, desc: " Pc"}
|
||||
- {id: 26, cat: Console/PS3, desc: " PS3"}
|
||||
- {id: 58, cat: Console/PSP, desc: " PSP"}
|
||||
- {id: 25, cat: Console/Wii, desc: " Wii"}
|
||||
- {id: 24, cat: Console/Xbox360, desc: " Xbox360"}
|
||||
- {id: 21, cat: Audio, desc: "MUSIQUES"}
|
||||
- {id: 29, cat: Audio/Video, desc: " Clip"}
|
||||
- {id: 68, cat: Audio/Video, desc: " Concert"}
|
||||
- {id: 31, cat: Audio/Lossless, desc: " FLAC"}
|
||||
- {id: 30, cat: Audio/MP3, desc: " mp3"}
|
||||
- {id: 28, cat: Audio/Lossless, desc: " wave"}
|
||||
- {id: 27, cat: Audio/Other, desc: " wma"}
|
||||
- {id: 5, cat: TV, desc: "SERIES"}
|
||||
- {id: 79, cat: TV/HD, desc: " SERIES HD 1080P"}
|
||||
- {id: 80, cat: TV/HD, desc: " SERIES HD 720p"}
|
||||
- {id: 75, cat: TV, desc: " TV pack"}
|
||||
- {id: 8, cat: TV, desc: " vf"}
|
||||
- {id: 6, cat: TV, desc: " vo"}
|
||||
- {id: 7, cat: TV, desc: " vost"}
|
||||
- {id: 12, cat: TV/Sport, desc: "SPORTS"}
|
||||
- {id: 61, cat: TV/Sport, desc: " Autres "}
|
||||
- {id: 45, cat: TV/Sport, desc: " Catch VF"}
|
||||
- {id: 59, cat: TV/Sport, desc: " Catch VO"}
|
||||
- {id: 44, cat: TV/Sport, desc: " Football"}
|
||||
- {id: 60, cat: TV/Sport, desc: " UFC/MMA"}
|
||||
- {id: 76, cat: TV, desc: "Télévision"}
|
||||
- {id: 78, cat: Movies/WEBDL, desc: "WEBRIP"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
login:
|
||||
path: /takelogin.php
|
||||
method: post
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
error:
|
||||
- selector: table:has(td:contains("Une erreur est survenue"))
|
||||
test:
|
||||
path: browse.php
|
||||
|
||||
download:
|
||||
before:
|
||||
path: "/takethanks.php"
|
||||
method: "post"
|
||||
inputs:
|
||||
torrentid: "{{ re_replace .DownloadUri.AbsolutePath \"^.*download-torrent-(\\d+)/.*$\" \"$1\" }}"
|
||||
|
||||
search:
|
||||
path: browse.php
|
||||
inputs:
|
||||
do: "chercher"
|
||||
keywords: "{{ .Query.Keywords }}"
|
||||
search_type: "t_name"
|
||||
category: "0" # multi cat search not supported
|
||||
include_dead_torrents: "yes"
|
||||
rows:
|
||||
selector: table#sortabletable > tbody > tr:has(a[href*="/torrent-details-"])
|
||||
fields:
|
||||
download:
|
||||
selector: a[href*="/torrent-details-"]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["torrent-details-", "download-torrent-"]
|
||||
title:
|
||||
selector: a[href*="/torrent-details-"]
|
||||
details:
|
||||
selector: a[href*="/torrent-details-"]
|
||||
attribute: href
|
||||
category:
|
||||
selector: a[href*="/torrent-category-"]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: regexp
|
||||
args: torrent-category-(\d+)
|
||||
size:
|
||||
selector: td:nth-child(4)
|
||||
date:
|
||||
selector: td:nth-child(2) > div > font[color="white"]
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["le ", ""]
|
||||
- name: replace
|
||||
args: [" à ", " "]
|
||||
- name: trim
|
||||
args: "\t"
|
||||
- name: trim
|
||||
args: "\n"
|
||||
- name: append
|
||||
args: " +01:00"
|
||||
- name: dateparse
|
||||
args: "02-01-2006 15:04 -07:00"
|
||||
grabs:
|
||||
selector: td:nth-child(5)
|
||||
seeders:
|
||||
selector: td:nth-child(6)
|
||||
leechers:
|
||||
selector: td:nth-child(7)
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
img[alt^="Free Torrent "]: "0"
|
||||
img[alt^="Silver Torrent "]: "0.5"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
257
src/Jackett/Definitions/manicomioshare.yml
Normal file
257
src/Jackett/Definitions/manicomioshare.yml
Normal file
@@ -0,0 +1,257 @@
|
||||
---
|
||||
site: manicomioshare
|
||||
name: Manicomio Share
|
||||
language: pt-br
|
||||
type: private
|
||||
encoding: iso-8859-1
|
||||
links:
|
||||
- https://www.manicomio-share.com
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
#XXX
|
||||
- {id: 80, cat: XXX, desc: "Adulto: [XXX] - Filmes"}
|
||||
- {id: 157, cat: XXX, desc: "Adulto: [XXX] - Blu-Ray"}
|
||||
- {id: 159, cat: XXX, desc: "Adulto: [XXX] - DVD-R"}
|
||||
- {id: 160, cat: XXX, desc: "Adulto: [XXX] - DVD-R 9"}
|
||||
- {id: 161, cat: XXX, desc: "Adulto: [XXX] - Eróticos"}
|
||||
- {id: 162, cat: XXX, desc: "Adulto: [XXX] - HD"}
|
||||
- {id: 188, cat: XXX, desc: "Adulto: [XXX] - 4K"}
|
||||
- {id: 112, cat: XXX/Other, desc: "Adulto: [XXX] - Fotos"}
|
||||
- {id: 113, cat: XXX/Other, desc: "Adulto: [XXX] - Hentai"}
|
||||
- {id: 131, cat: XXX/Other, desc: "Adulto: [XXX] - Jogos"}
|
||||
|
||||
#ANIME
|
||||
- {id: 21, cat: TV/Anime, desc: "Anime: Anime"}
|
||||
- {id: 155, cat: TV/Anime, desc: "Anime: Anime DVD-R"}
|
||||
- {id: 156, cat: TV/Anime, desc: "Anime: Anime HD"}
|
||||
|
||||
#PC APPS
|
||||
- {id: 22, cat: PC, desc: "Aplicativos: Linux"}
|
||||
- {id: 23, cat: PC, desc: "Aplicativos: Mac OS"}
|
||||
- {id: 24, cat: PC, desc: "Aplicativos: Windows"}
|
||||
|
||||
#BOOKLET
|
||||
- {id: 25, cat: Other, desc: "Apostila: Apostila e Textos"}
|
||||
- {id: 169, cat: Other, desc: "Apostila: Cursos e Video Aula"}
|
||||
|
||||
#MOBILE
|
||||
- {id: 26, cat: Other, desc: "Celular: Aplicativos"}
|
||||
- {id: 184, cat: Other, desc: "Celular: Jogos"}
|
||||
|
||||
#TV-CHILD
|
||||
- {id: 88, cat: TV/Other, desc: "Desenhos: Desenhos"}
|
||||
- {id: 165, cat: TV/Other, desc: "Desenhos: Desenhos DVD-R"}
|
||||
- {id: 166, cat: TV/Other, desc: "Desenhos: Desenhos HD"}
|
||||
- {id: 83, cat: TV/Other, desc: "Diversos: Diversos"}
|
||||
- {id: 84, cat: TV/Other, desc: "Educativos: Infantil"}
|
||||
|
||||
#TV-SPORTS
|
||||
- {id: 105, cat: TV/Sport, desc: "Eventos: Esportivos"}
|
||||
- {id: 153, cat: TV/Sport, desc: "Eventos: Esportivos DVD-R"}
|
||||
- {id: 154, cat: TV/Sport, desc: "Eventos: Esportivos HD"}
|
||||
|
||||
#MOVIES
|
||||
- {id: 189, cat: Movies, desc: "Filmes: 4K"}
|
||||
- {id: 132, cat: Movies/BluRay, desc: "Filmes: Blu-Ray"}
|
||||
- {id: 152, cat: Movies/BluRay, desc: "Filmes: Blu-Ray Nacionais"}
|
||||
- {id: 141, cat: Movies/BluRay, desc: "Filmes: Blu-Ray 3D"}
|
||||
- {id: 142, cat: Movies/BluRay, desc: "Filmes: Blu-Ray BD25"}
|
||||
- {id: 182, cat: Movies/BluRay, desc: "Filmes: Blu-Ray BD25 Nacionais"}
|
||||
- {id: 183, cat: Movies/BluRay, desc: "Filmes: Blu-Ray BD25 3D"}
|
||||
- {id: 143, cat: Movies/BluRay, desc: "Filmes: Blu-Ray Remux"}
|
||||
- {id: 34, cat: Movies/SD, desc: "Filmes: DVD-R"}
|
||||
- {id: 134, cat: Movies/SD, desc: "Filmes: DVD-R Nacionais"}
|
||||
- {id: 144, cat: Movies/SD, desc: "Filmes: DVD-R 9"}
|
||||
- {id: 145, cat: Movies/Other, desc: "Filmes: Documentarios DVD-R"}
|
||||
- {id: 151, cat: Movies/Other, desc: "Filmes: Documentarios HD"}
|
||||
- {id: 127, cat: Movies/HD, desc: "Filmes: HD"}
|
||||
- {id: 148, cat: Movies/Foreign, desc: "Filmes: HD Nacionais"}
|
||||
- {id: 147, cat: Movies/3D, desc: "Filmes: HD 3D"}
|
||||
- {id: 128, cat: Movies/Foreign, desc: "Filmes: Nacionais"}
|
||||
- {id: 27, cat: Movies, desc: "Filmes: Ação"}
|
||||
- {id: 95, cat: Movies, desc: "Filmes: Animação"}
|
||||
- {id: 28, cat: Movies, desc: "Filmes: Aventura"}
|
||||
- {id: 29, cat: Movies, desc: "Filmes: Biografia"}
|
||||
- {id: 30, cat: Movies, desc: "Filmes: Classicos"}
|
||||
- {id: 31, cat: Movies, desc: "Filmes: Comédia"}
|
||||
- {id: 32, cat: Movies, desc: "Filmes: Documentarios"}
|
||||
- {id: 33, cat: Movies, desc: "Filmes: Drama"}
|
||||
- {id: 35, cat: Movies, desc: "Filmes: Esportes"}
|
||||
- {id: 185, cat: Movies, desc: "Filmes: Fantasia"}
|
||||
- {id: 36, cat: Movies, desc: "Filmes: Ficção"}
|
||||
- {id: 85, cat: Movies, desc: "Filmes: Guerra"}
|
||||
- {id: 37, cat: Movies, desc: "Filmes: Infantil"}
|
||||
- {id: 118, cat: Movies, desc: "Filmes: Musicais"}
|
||||
- {id: 104, cat: Movies, desc: "Filmes: Policial"}
|
||||
- {id: 40, cat: Movies, desc: "Filmes: Suspense"}
|
||||
- {id: 38, cat: Movies, desc: "Filmes: Religiosos"}
|
||||
- {id: 39, cat: Movies, desc: "Filmes: Romance"}
|
||||
- {id: 41, cat: Movies, desc: "Filmes: Terror"}
|
||||
- {id: 107, cat: Movies, desc: "Filmes: Western"}
|
||||
|
||||
#GAMES
|
||||
- {id: 97, cat: Console, desc: "Jogos: Dreamcast"}
|
||||
- {id: 44, cat: PC/Games, desc: "Jogos: Emuladores e Rom"}
|
||||
- {id: 101, cat: Console, desc: "Jogos: Game Cube"}
|
||||
- {id: 140, cat: PC/Mac, desc: "Jogos: Mac OS"}
|
||||
- {id: 119, cat: Console/NDS, desc: "Jogos: Nintendo DS"}
|
||||
- {id: 45, cat: PC/Games, desc: "Jogos: Pc"}
|
||||
- {id: 87, cat: Console, desc: "Jogos: PS1"}
|
||||
- {id: 46, cat: Console, desc: "Jogos: PS2"}
|
||||
- {id: 120, cat: Console, desc: "Jogos: PS3"}
|
||||
- {id: 82, cat: Console/PSP, desc: "Jogos: PSP"}
|
||||
- {id: 191, cat: Console, desc: "Jogos: PSVita"}
|
||||
- {id: 47, cat: Console/XBox, desc: "Jogos: Xbox"}
|
||||
- {id: 48, cat: Console/XBox 360, desc: "Jogos: Xbox 360"}
|
||||
- {id: 100, cat: Console/Wii, desc: "Jogos: Wii"}
|
||||
- {id: 187, cat: Console/Wii, desc: "Jogos: Wii-U"}
|
||||
|
||||
#EBOOKS
|
||||
- {id: 49, cat: Books/EBook, desc: "Livros: E-books"}
|
||||
|
||||
#MUSIC
|
||||
- {id: 50, cat: Audio, desc: "Músicas: Axé"}
|
||||
- {id: 51, cat: Audio, desc: "Músicas: Blues"}
|
||||
- {id: 52, cat: Audio, desc: "Músicas: Classica"}
|
||||
- {id: 53, cat: Audio, desc: "Músicas: Coletânea"}
|
||||
- {id: 103, cat: Audio, desc: "Músicas: Country"}
|
||||
- {id: 102, cat: Audio, desc: "Músicas: Discografia"}
|
||||
- {id: 54, cat: Audio, desc: "Músicas: Dance"}
|
||||
- {id: 55, cat: Audio, desc: "Músicas: Eletronica"}
|
||||
- {id: 135, cat: Audio, desc: "Músicas: Enka e Japonesa"}
|
||||
- {id: 56, cat: Audio, desc: "Músicas: Forró"}
|
||||
- {id: 57, cat: Audio, desc: "Músicas: Funk"}
|
||||
- {id: 58, cat: Audio, desc: "Músicas: Gospel"}
|
||||
- {id: 117, cat: Audio, desc: "Músicas: Hard Core"}
|
||||
- {id: 59, cat: Audio, desc: "Músicas: Hard Rock"}
|
||||
- {id: 61, cat: Audio, desc: "Músicas: Hip Hop"}
|
||||
- {id: 90, cat: Audio, desc: "Músicas: House"}
|
||||
- {id: 62, cat: Audio, desc: "Músicas: Infantil"}
|
||||
- {id: 175, cat: Audio, desc: "Músicas: Instrumental"}
|
||||
- {id: 86, cat: Audio, desc: "Músicas: Jazz"}
|
||||
- {id: 60, cat: Audio, desc: "Músicas: Metal"}
|
||||
- {id: 63, cat: Audio, desc: "Músicas: MPB"}
|
||||
- {id: 64, cat: Audio, desc: "Músicas: New Age"}
|
||||
- {id: 94, cat: Audio, desc: "Músicas: Oldies"}
|
||||
- {id: 65, cat: Audio, desc: "Músicas: Pagode"}
|
||||
- {id: 66, cat: Audio, desc: "Músicas: Pop"}
|
||||
- {id: 109, cat: Audio, desc: "Músicas: Psychedelic"}
|
||||
- {id: 67, cat: Audio, desc: "Músicas: Punk Rock"}
|
||||
- {id: 89, cat: Audio, desc: "Músicas: Raízes"}
|
||||
- {id: 68, cat: Audio, desc: "Músicas: Rap"}
|
||||
- {id: 69, cat: Audio, desc: "Músicas: Reggae"}
|
||||
- {id: 70, cat: Audio, desc: "Músicas: Regionais"}
|
||||
- {id: 71, cat: Audio, desc: "Músicas: Religiosas"}
|
||||
- {id: 72, cat: Audio, desc: "Músicas: Rock"}
|
||||
- {id: 73, cat: Audio, desc: "Músicas: Samba"}
|
||||
- {id: 74, cat: Audio, desc: "Músicas: Sertanejo"}
|
||||
- {id: 98, cat: Audio, desc: "Músicas: Soul R&B"}
|
||||
- {id: 110, cat: Audio, desc: "Músicas: Surf Music"}
|
||||
- {id: 92, cat: Audio, desc: "Músicas: Techno"}
|
||||
- {id: 91, cat: Audio, desc: "Músicas: Trance"}
|
||||
- {id: 75, cat: Audio, desc: "Músicas: Trilha Sonora"}
|
||||
- {id: 93, cat: Audio, desc: "Músicas: Vocal"}
|
||||
- {id: 111, cat: Audio, desc: "Músicas: World Music"}
|
||||
|
||||
#TV-FOREIGN
|
||||
- {id: 170, cat: TV/Foreign, desc: "Novelas: Novela"}
|
||||
- {id: 171, cat: TV/Foreign, desc: "Novelas: Novela DVD-R"}
|
||||
- {id: 172, cat: TV/Foreign, desc: "Novelas: Novela HD"}
|
||||
- {id: 179, cat: TV/Other, desc: "Religião: Religião Diversos"}
|
||||
- {id: 178, cat: TV/Other, desc: "Religião: Religião DVD-R"}
|
||||
|
||||
#BOOKS
|
||||
- {id: 96, cat: Books, desc: "Revistas: Revistas"}
|
||||
- {id: 99, cat: Books/Comics, desc: "Revistas: HQ"}
|
||||
- {id: 192, cat: Books/Comics, desc: "Revistas: Mangá"}
|
||||
|
||||
#TV-SERIES
|
||||
- {id: 76, cat: TV, desc: "Séries: Seriados"}
|
||||
- {id: 122, cat: TV/HD, desc: "Séries: HD"}
|
||||
- {id: 190, cat: TV, desc: "Séries: 4K"}
|
||||
- {id: 186, cat: TV, desc: "Séries: Blu-Ray"}
|
||||
- {id: 124, cat: TV/SD, desc: "Séries: DVD-R"}
|
||||
- {id: 181, cat: TV/SD, desc: "Séries: DVD-R 9"}
|
||||
- {id: 125, cat: TV/SD, desc: "Séries: DVDRip"}
|
||||
- {id: 123, cat: TV/Other, desc: "Séries: Cartoon"}
|
||||
- {id: 164, cat: TV/Other, desc: "Séries: Cartoon DVD-R"}
|
||||
- {id: 163, cat: TV/Other, desc: "Séries: Cartoon HD"}
|
||||
|
||||
#MUSIC SHOWS
|
||||
- {id: 77, cat: Audio/Video, desc: "Shows: Shows"}
|
||||
- {id: 133, cat: Audio/Video, desc: "Shows: Shows Blu-Ray"}
|
||||
- {id: 130, cat: Audio/Video, desc: "Shows: Shows DVD-R"}
|
||||
- {id: 180, cat: Audio/Video, desc: "Shows: Shows DVD-R 9"}
|
||||
- {id: 129, cat: Audio/Video, desc: "Shows: Shows HD"}
|
||||
|
||||
#TV-OTHER
|
||||
- {id: 78, cat: TV, desc: "Televisão: Televisão"}
|
||||
- {id: 136, cat: TV, desc: "Televisão: Televisão HDTV"}
|
||||
- {id: 137, cat: TV, desc: "Televisão: Televisão HD"}
|
||||
- {id: 139, cat: TV, desc: "Televisão: Televisão SDTV"}
|
||||
|
||||
#MUSIC CLIPS
|
||||
- {id: 79, cat: Audio/Video, desc: "Video: Video Clipes"}
|
||||
- {id: 167, cat: Audio/Video, desc: "Video: Video Clipes DVD-R"}
|
||||
- {id: 168, cat: Audio/Video, desc: "Video: Video Clipes HD"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
|
||||
login:
|
||||
path: index.php
|
||||
method: post
|
||||
inputs:
|
||||
dados: "ok"
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
test:
|
||||
path: torrents.php
|
||||
|
||||
search:
|
||||
path: pesquisa.php
|
||||
keywordsfilters:
|
||||
# workaroud to remove year in search keywords
|
||||
- name: re_replace
|
||||
args: ["([1-2]\\d{3})", ""]
|
||||
- name: re_replace
|
||||
args: ["[^a-zA-Z0-9]+", "%"]
|
||||
inputs:
|
||||
busca: "{{ .Keywords }}"
|
||||
rows:
|
||||
selector: table#tbltorrent > tbody > tr[data-id]
|
||||
fields:
|
||||
download:
|
||||
selector: a[href*="/download.php?id="]
|
||||
attribute: href
|
||||
details:
|
||||
selector: a[href*="/item/"]
|
||||
attribute: href
|
||||
category:
|
||||
selector: a[href*="/torrents.php?cat="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
title:
|
||||
selector: a[href*="/item/"]
|
||||
remove: font[color^=green]
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["|", ""]
|
||||
size:
|
||||
selector: td:nth-child(4)
|
||||
grabs:
|
||||
selector: td:nth-child(6)
|
||||
seeders:
|
||||
selector: td:nth-child(5) > span:nth-child(1)
|
||||
leechers:
|
||||
selector: td:nth-child(5) > span:nth-child(2)
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"span.h3t:contains(\"[livre]\")": "0"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
@@ -1,152 +0,0 @@
|
||||
---
|
||||
site: nachtwerk
|
||||
name: Nachtwerk
|
||||
language: de-de
|
||||
type: private
|
||||
encoding: ISO-8859-15
|
||||
links:
|
||||
- https://nwtracker.com/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 75, cat: Movies/3D, desc: "Filme - 3D"}
|
||||
- {id: 34, cat: Movies, desc: "Filme - Xvid / x264"}
|
||||
- {id: 55, cat: Movies/BluRay, desc: "Filme - Blu-Ray"}
|
||||
- {id: 20, cat: Movies/DVD, desc: "Filme - DVD-R"}
|
||||
- {id: 71, cat: Movies/HD, desc: "Filme - HD 1080p"}
|
||||
- {id: 70, cat: Movies/HD, desc: "Filme - HD 720p"}
|
||||
- {id: 35, cat: Movies/Foreign, desc: "Filme - Inter"}
|
||||
- {id: 104, cat: Movies/HD, desc: "Filme - UHD"}
|
||||
- {id: 107, cat: Movies/Other, desc: "Filme - Remux"}
|
||||
- {id: 7, cat: TV/SD, desc: "Serien - Xvid / x264"}
|
||||
- {id: 72, cat: TV/HD, desc: "Serien - HD"}
|
||||
- {id: 82, cat: TV/Foreign, desc: "Serien - Inter"}
|
||||
- {id: 69, cat: TV, desc: "Serien - Pack's"}
|
||||
- {id: 42, cat: TV, desc: "Serien - TV Show"}
|
||||
- {id: 105, cat: TV/HD, desc: "Serien - UHD"}
|
||||
- {id: 51, cat: XXX, desc: "XXX - Xvid / x264"}
|
||||
- {id: 73, cat: XXX, desc: "XXX - HD"}
|
||||
- {id: 84, cat: XXX, desc: "XXX - Pack's"}
|
||||
- {id: 85, cat: XXX, desc: "XXX - Sonstiges"}
|
||||
- {id: 102, cat: XXX, desc: "XXX - Hentai"}
|
||||
- {id: 103, cat: XXX, desc: "XXX - UHD"}
|
||||
- {id: 6, cat: Audio/MP3, desc: "Audio - MP3"}
|
||||
- {id: 74, cat: Audio/Lossless, desc: "Audio - Flac"}
|
||||
- {id: 86, cat: Audio/Video, desc: "Audio - Videos"}
|
||||
- {id: 24, cat: Audio/Audiobook, desc: "Audio - Hörspiel/Hörbuch"}
|
||||
- {id: 93, cat: PC/Mac, desc: "Appz - Mac"}
|
||||
- {id: 67, cat: PC/0day, desc: "Appz - Windows"}
|
||||
- {id: 31, cat: PC/Phone-Other, desc: "Appz - Handy"}
|
||||
- {id: 81, cat: PC, desc: "Appz - Sonstiges"}
|
||||
- {id: 25, cat: TV/Documentary, desc: "Dokus - Xvid / x264"}
|
||||
- {id: 76, cat: TV/Documentary, desc: "Dokus - HD"}
|
||||
- {id: 99, cat: TV/Documentary, desc: "Dokus - Pack's"}
|
||||
- {id: 100, cat: TV/Documentary, desc: "Dokus - 3D"}
|
||||
- {id: 106, cat: TV/Documentary, desc: "Dokus - UHD"}
|
||||
- {id: 90, cat: Console/PS3, desc: "Games - PSX"}
|
||||
- {id: 56, cat: Console/Wii, desc: "Games - WII"}
|
||||
- {id: 43, cat: Console/Xbox, desc: "Games - XboX"}
|
||||
- {id: 4, cat: PC/Games, desc: "Games - PC"}
|
||||
- {id: 88, cat: Console/NDS, desc: "Games - xDS"}
|
||||
- {id: 91, cat: PC/Mac, desc: "Games - Mac"}
|
||||
- {id: 92, cat: Console, desc: "Games - Sonstiges"}
|
||||
- {id: 23, cat: TV/Anime, desc: "Anime - Xvid / x264"}
|
||||
- {id: 80, cat: TV/Anime, desc: "Anime - HD"}
|
||||
- {id: 98, cat: TV/Anime, desc: "Anime - Serien"}
|
||||
- {id: 94, cat: Books/Magazines, desc: "eBooks - Magazine/Zeitungen"}
|
||||
- {id: 95, cat: Books/Comics, desc: "eBooks - Comics"}
|
||||
- {id: 30, cat: Books, desc: "eBooks - Bücher"}
|
||||
- {id: 96, cat: TV/Sport, desc: "Sport - Wrestling"}
|
||||
- {id: 97, cat: TV/Sport, desc: "Sport - Fussball"}
|
||||
- {id: 45, cat: TV/Sport, desc: "Sport - Sonstiges"}
|
||||
- {id: 9, cat: Other, desc: "Diverses - Sonstiges"}
|
||||
|
||||
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
|
||||
|
||||
download:
|
||||
selector: a[href^="download.php?torrent="]
|
||||
|
||||
search:
|
||||
path: /browse.php
|
||||
method: post
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
incldead: "1"
|
||||
spstate: "0"
|
||||
inclbookmarked: "0"
|
||||
search_area: "0"
|
||||
search_mode: "0"
|
||||
rows:
|
||||
selector: table.tableinborder[cellspacing="1"][cellpadding="0"] > tbody > tr
|
||||
fields:
|
||||
title:
|
||||
selector: a[href^="details.php?id="]
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["[NW] ", ""]
|
||||
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^="details.php?id="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["details.php?id=", "thanks1.php?torrentid="]
|
||||
banner:
|
||||
selector: a[onmouseover][href^="details.php?id="]
|
||||
attribute: onmouseover
|
||||
filters:
|
||||
- name: regexp
|
||||
args: "src=.*'\\);"
|
||||
size:
|
||||
selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(1) > b:nth-child(1)
|
||||
filters:
|
||||
- name: replace
|
||||
args: [".", ""]
|
||||
- name: replace
|
||||
args: [",", "."]
|
||||
files:
|
||||
selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(1) > b:nth-child(2)
|
||||
grabs:
|
||||
selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(3) > b:nth-child(1)
|
||||
seeders:
|
||||
selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(2) > b:nth-child(1)
|
||||
leechers:
|
||||
selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(2) > b:nth-child(3)
|
||||
date:
|
||||
selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(5)
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["\xA0", " "]
|
||||
- name: append
|
||||
args: " +01:00"
|
||||
- name: dateparse
|
||||
args: "02.01.2006 15:04:05 -07:00"
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
img[src="pic/onlyuploadd.gif"]: "0"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
@@ -6,7 +6,7 @@
|
||||
type: private
|
||||
encoding: windows-1252
|
||||
links:
|
||||
- http://new-retro.eu/
|
||||
- https://new-retro.eu/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
@@ -46,8 +46,9 @@
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
login:
|
||||
path: /takelogin.php
|
||||
method: post
|
||||
path: /login.php
|
||||
method: form
|
||||
cookies: ["JAVA=OK"] # avoid jscheck redirect
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
|
88
src/Jackett/Definitions/nexttorrent.yml
Executable file
88
src/Jackett/Definitions/nexttorrent.yml
Executable file
@@ -0,0 +1,88 @@
|
||||
---
|
||||
site: nexttorrent
|
||||
name: NextTorrent
|
||||
language: fr-fr
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://www.nextorrent.org/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: films, cat: Movies, desc: "Movies"}
|
||||
- {id: series, cat: TV, desc: "TV"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
settings: []
|
||||
|
||||
download:
|
||||
selector: a[href^="/get_torrent/"]
|
||||
|
||||
search:
|
||||
path: "recherche/{{ .Query.Keywords }}"
|
||||
rows:
|
||||
selector: div.listing-torrent > table tbody tr:has(a)
|
||||
fields:
|
||||
site_date:
|
||||
selector: td:nth-child(1) a
|
||||
filters:
|
||||
# date is at the end of the title, so we get it and name it site_date
|
||||
- name: regexp
|
||||
args: "(\\w+)$"
|
||||
title:
|
||||
selector: td:nth-child(1) a
|
||||
filters:
|
||||
# now we put the date at the right place according scene naming rules using .Result.site_date
|
||||
- name: replace
|
||||
args: ["FRENCH", "{{ .Result.site_date }} FRENCH"]
|
||||
- name: replace
|
||||
args: ["TRUEFRENCH", "{{ .Result.site_date }} TRUEFRENCH"]
|
||||
- name: replace
|
||||
args: ["VOSTFR", "{{ .Result.site_date }} VOSTFR"]
|
||||
# and we delete it at the end
|
||||
- name: re_replace
|
||||
args: ["(\\w+)$", ""]
|
||||
details:
|
||||
selector: td:nth-child(1) a
|
||||
attribute: href
|
||||
download:
|
||||
selector: td:nth-child(1) a
|
||||
attribute: href
|
||||
size:
|
||||
selector: td:nth-child(2)
|
||||
filters:
|
||||
- name: re_replace
|
||||
args: [ "\\.(\\d) Ko", "$1X00"]
|
||||
- name: re_replace
|
||||
args: [ " Ko", "000"]
|
||||
- name: re_replace
|
||||
args: [ "\\.(\\d) Mo", "$1X00000"]
|
||||
- name: re_replace
|
||||
args: [ " Mo", "000000"]
|
||||
- name: re_replace
|
||||
args: [ "\\.(\\d) Go", "$1X00000000"]
|
||||
- name: re_replace
|
||||
args: [ " Go", "000000000"]
|
||||
- name: re_replace
|
||||
args: [ "\\.(\\d) To", "$1X00000000000"]
|
||||
- name: re_replace
|
||||
args: [ " To", "000000000000"]
|
||||
- name: replace
|
||||
args: [ "X", "" ]
|
||||
seeders:
|
||||
text: 0
|
||||
seeders:
|
||||
selector: td:nth-child(3)
|
||||
optional: true
|
||||
leechers:
|
||||
text: 0
|
||||
leechers:
|
||||
selector: td:nth-child(4)
|
||||
optional: true
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
113
src/Jackett/Definitions/nyaa-pantsu.yml
Normal file
113
src/Jackett/Definitions/nyaa-pantsu.yml
Normal file
@@ -0,0 +1,113 @@
|
||||
#,==========,
|
||||
#| | | |
|
||||
#`-./ \.-' - Config'd by Quatroking (05-05-2017), updated by AeonLucid (26-05-2017) -
|
||||
# `.__.'
|
||||
|
||||
---
|
||||
site: nyaa-pantsu
|
||||
name: Nyaa-pantsu
|
||||
language: en-en
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://nyaa.pantsu.cat/
|
||||
|
||||
settings:
|
||||
- name: cat-id
|
||||
type: select
|
||||
label: Category
|
||||
default: "_"
|
||||
options:
|
||||
_: "All categories"
|
||||
3_: "Anime"
|
||||
3_12: "Anime - Anime Music Video"
|
||||
3_5: "Anime - English-translated"
|
||||
3_13: "Anime - Non-English-translated"
|
||||
3_6: "Anime - Raw"
|
||||
2_: "Audio"
|
||||
2_3: "Audio - Lossless"
|
||||
2_4: "Audio - Lossy"
|
||||
4_: "Literature"
|
||||
4_7: "Literature - English-translated"
|
||||
4_14: "Literature - Non-English-translated"
|
||||
4_14: "Literature - Raw"
|
||||
1_: "Software"
|
||||
1_1: "Software - Applications"
|
||||
1_2: "Software - Games"
|
||||
- name: filter-id
|
||||
type: select
|
||||
label: Filter
|
||||
default: "0"
|
||||
options:
|
||||
0: "Show all"
|
||||
1: "Filter Remakes"
|
||||
2: "Trusted"
|
||||
3: "A+"
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
# Anime
|
||||
- {id: 3_, cat: TV/Anime, desc: "Anime"}
|
||||
- {id: 3_12, cat: TV/Anime, desc: "Anime music videos"}
|
||||
- {id: 3_5, cat: TV/Anime, desc: "English subtitled animes"}
|
||||
- {id: 3_13, cat: TV/Anime, desc: "Non-english subtitled animes"}
|
||||
- {id: 3_6, cat: TV/Anime, desc: "Raw animes"}
|
||||
# Audio
|
||||
- {id: 2_, cat: Audio, desc: "Audio"}
|
||||
- {id: 2_3, cat: Audio, desc: "Lossless audio"}
|
||||
- {id: 2_4, cat: Audio, desc: "Lossy audio"}
|
||||
# Literature
|
||||
- {id: 4_, cat: Books, desc: "Literature"}
|
||||
- {id: 4_7, cat: Books, desc: "Literature english translated"}
|
||||
- {id: 4_14, cat: Books, desc: "Literature non-english translated"}
|
||||
- {id: 4_8, cat: Books, desc: "Raw literature"}
|
||||
# Software
|
||||
- {id: 1_, cat: PC, desc: "Software"}
|
||||
- {id: 1_1, cat: PC/ISO, desc: "Applications"}
|
||||
- {id: 1_2, cat: PC/Games, desc: "Games"}
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q]
|
||||
|
||||
search:
|
||||
path: /search
|
||||
inputs:
|
||||
q: "{{ .Query.Keywords }}"
|
||||
c: "{{ .Config.cat-id }}"
|
||||
s: "{{ .Config.filter-id }}"
|
||||
rows:
|
||||
selector: tr.torrent-info
|
||||
fields:
|
||||
title:
|
||||
selector: td.tr-name a
|
||||
category:
|
||||
selector: td:nth-child(1) a
|
||||
attribute: href
|
||||
filters:
|
||||
- name: split
|
||||
args: [ "=", -1 ]
|
||||
details:
|
||||
selector: td.tr-name a
|
||||
attribute: href
|
||||
download:
|
||||
selector: a[title="Magnet Link"]
|
||||
attribute: href
|
||||
seeders:
|
||||
selector: td.tr-se
|
||||
optional: true
|
||||
leechers:
|
||||
selector: td.tr-le
|
||||
optional: true
|
||||
grabs:
|
||||
selector: td.tr-dl
|
||||
optional: true
|
||||
date:
|
||||
selector: td.date-short
|
||||
filters:
|
||||
- name: dateparse
|
||||
args: "2006-01-02T15:04:05Z"
|
||||
size:
|
||||
selector: td.tr-size
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["Unknown", "0"]
|
@@ -1,74 +0,0 @@
|
||||
---
|
||||
site: nyaa
|
||||
name: Nyaa
|
||||
language: en-en
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://www.nyaa.se/
|
||||
|
||||
settings: []
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
# Anime
|
||||
- {id: 1_32, cat: TV/Anime, desc: "Anime music videos"}
|
||||
- {id: 1_37, cat: TV/Anime, desc: "English subtitled animes"}
|
||||
- {id: 1_38, cat: TV/Anime, desc: "Non-english subtitled animes"}
|
||||
- {id: 1_11, cat: TV/Anime, desc: "Raw animes"}
|
||||
# Audio
|
||||
- {id: 3_14, cat: Audio, desc: "Lossless audio"}
|
||||
- {id: 3_15, cat: Audio, desc: "Lossy audio"}
|
||||
# Literature
|
||||
- {id: 2_12, cat: Books, desc: "Literature english translated"}
|
||||
- {id: 2_39, cat: Books, desc: "Literature non-english translated"}
|
||||
- {id: 2_13, cat: Books, desc: "Raw literature"}
|
||||
# Software
|
||||
- {id: 6_23, cat: PC/ISO, desc: "Applications"}
|
||||
- {id: 6_24, cat: PC/Games, desc: "Games"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
|
||||
search:
|
||||
path: /
|
||||
inputs:
|
||||
page: "search"
|
||||
term: "{{ .Query.Keywords}}"
|
||||
rows:
|
||||
selector: tr.tlistrow
|
||||
fields:
|
||||
title:
|
||||
selector: td.tlistname a
|
||||
category:
|
||||
selector: td.tlisticon a
|
||||
attribute: href
|
||||
filters:
|
||||
- name: split
|
||||
args: [ "=", -1 ]
|
||||
details:
|
||||
selector: td.tlistname a
|
||||
attribute: href
|
||||
download:
|
||||
selector: a[title="Download"]
|
||||
attribute: href
|
||||
size:
|
||||
selector: td.tlistsize
|
||||
seeders:
|
||||
text: 0
|
||||
seeders:
|
||||
selector: td.tlistsn
|
||||
optional: true
|
||||
leechers:
|
||||
text: 0
|
||||
leechers:
|
||||
selector: td.tlistln
|
||||
optional: true
|
||||
grabs:
|
||||
selector: td.tlistdn
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
106
src/Jackett/Definitions/nyaasi.yml
Normal file
106
src/Jackett/Definitions/nyaasi.yml
Normal file
@@ -0,0 +1,106 @@
|
||||
---
|
||||
site: nyaasi
|
||||
name: Nyaa.si
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://nyaa.si
|
||||
|
||||
settings:
|
||||
- name: filter-id
|
||||
type: select
|
||||
label: Filter
|
||||
default: "0"
|
||||
options:
|
||||
0: No filter
|
||||
1: No remakes
|
||||
2: Trusted only
|
||||
- name: cat-id
|
||||
type: select
|
||||
label: Category
|
||||
default: "0_0"
|
||||
options:
|
||||
0_0: "All categories"
|
||||
1_0: "Anime"
|
||||
1_1: "Anime - Anime Music Video"
|
||||
1_2: "Anime - English-translated"
|
||||
1_3: "Anime - Non-English-translated"
|
||||
1_4: "Anime - Raw"
|
||||
2_0: "Audio"
|
||||
2_1: "Audio - Lossless"
|
||||
2_2: "Audio - Lossy"
|
||||
3_0: "Literature"
|
||||
3_1: "Literature - English-translated"
|
||||
3_2: "Literature - Non-English-translated"
|
||||
3_3: "Literature - Lossy"
|
||||
6_0: "Software"
|
||||
6_1: "Software - Applications"
|
||||
6_2: "Software - Games"
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
# Anime
|
||||
- {id: 1_0, cat: TV/Anime, desc: "Anime"}
|
||||
- {id: 1_1, cat: TV/Anime, desc: "Anime music videos"}
|
||||
- {id: 1_2, cat: TV/Anime, desc: "English subtitled animes"}
|
||||
- {id: 1_3, cat: TV/Anime, desc: "Non-english subtitled animes"}
|
||||
- {id: 1_4, cat: TV/Anime, desc: "Raw animes"}
|
||||
# Audio
|
||||
- {id: 2_0, cat: Audio, desc: "Audio"}
|
||||
- {id: 2_1, cat: Audio, desc: "Lossless audio"}
|
||||
- {id: 2_2, cat: Audio, desc: "Lossy audio"}
|
||||
# Literature
|
||||
- {id: 3_0, cat: Books, desc: "Literature"}
|
||||
- {id: 3_1, cat: Books, desc: "Literature english translated"}
|
||||
- {id: 3_2, cat: Books, desc: "Literature non-english translated"}
|
||||
- {id: 3_3, cat: Books, desc: "Raw literature"}
|
||||
# Software
|
||||
- {id: 6_0, cat: PC, desc: "Software"}
|
||||
- {id: 6_1, cat: PC/ISO, desc: "Applications"}
|
||||
- {id: 6_2, cat: PC/Games, desc: "Games"}
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q]
|
||||
|
||||
search:
|
||||
path: /
|
||||
inputs:
|
||||
q: "{{ .Query.Keywords}}"
|
||||
f: "{{ .Config.filter-id }}"
|
||||
c: "{{ .Config.cat-id }}"
|
||||
rows:
|
||||
selector: tr.default,tr.danger,tr.success
|
||||
fields:
|
||||
category:
|
||||
selector: td:nth-child(1) a
|
||||
attribute: href
|
||||
filters:
|
||||
- name: split
|
||||
args: [ "=", -1 ]
|
||||
title:
|
||||
selector: td:nth-child(2) a:last-of-type
|
||||
details:
|
||||
selector: td:nth-child(2) a:last-of-type
|
||||
attribute: href
|
||||
download:
|
||||
selector: td:nth-child(3) a[href$=".torrent"]
|
||||
attribute: href
|
||||
magnet:
|
||||
selector: td:nth-child(3) a[href^="magnet:?"]
|
||||
attribute: href
|
||||
size:
|
||||
selector: td:nth-child(4)
|
||||
date:
|
||||
selector: td:nth-child(5)
|
||||
filters:
|
||||
- name: append
|
||||
args: " -00"
|
||||
- name: dateparse
|
||||
args: "2006-01-02 15:04 -07"
|
||||
seeders:
|
||||
selector: td:nth-child(6)
|
||||
leechers:
|
||||
selector: td:nth-child(7)
|
||||
grabs:
|
||||
selector: td:nth-child(8)
|
75
src/Jackett/Definitions/nyoo.yml
Normal file
75
src/Jackett/Definitions/nyoo.yml
Normal file
@@ -0,0 +1,75 @@
|
||||
# Config'd by Quatroking, 07-05-2017
|
||||
---
|
||||
site: nyoo
|
||||
name: Nyoo
|
||||
language: en-en
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://nyoo.moe
|
||||
|
||||
settings: []
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
# Anime
|
||||
- {id: 3_12, cat: TV/Anime, desc: "Anime music videos"}
|
||||
- {id: 3_5, cat: TV/Anime, desc: "English subtitled animes"}
|
||||
- {id: 3_13, cat: TV/Anime, desc: "Non-english subtitled animes"}
|
||||
- {id: 3_6, cat: TV/Anime, desc: "Raw animes"}
|
||||
# Audio
|
||||
- {id: 2_3, cat: Audio, desc: "Lossless audio"}
|
||||
- {id: 2_4, cat: Audio, desc: "Lossy audio"}
|
||||
# Literature
|
||||
- {id: 4_7, cat: Books, desc: "Literature english translated"}
|
||||
- {id: 4_14, cat: Books, desc: "Literature non-english translated"}
|
||||
- {id: 4_8, cat: Books, desc: "Raw literature"}
|
||||
# Software
|
||||
- {id: 1_1, cat: PC/ISO, desc: "Applications"}
|
||||
- {id: 1_2, cat: PC/Games, desc: "Games"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
|
||||
search:
|
||||
path: /search
|
||||
inputs:
|
||||
page: "search"
|
||||
q: "{{ .Query.Keywords}}"
|
||||
rows:
|
||||
selector: tr.torrent-info
|
||||
fields:
|
||||
title:
|
||||
selector: td.tr-name a
|
||||
category:
|
||||
selector: td.tr-cat div.nyaa-cat a
|
||||
attribute: href
|
||||
filters:
|
||||
- name: split
|
||||
args: [ "=", -1 ]
|
||||
details:
|
||||
selector: td.tr-name a
|
||||
attribute: href
|
||||
download:
|
||||
selector: a[title="Magnet Link"]
|
||||
attribute: href
|
||||
size:
|
||||
selector: td.tr-size
|
||||
# seeders:
|
||||
# text: 0
|
||||
# seeders:
|
||||
# selector: td.tlistsn
|
||||
# optional: true
|
||||
# leechers:
|
||||
# text: 0
|
||||
# leechers:
|
||||
# selector: td.tlistln
|
||||
# optional: true
|
||||
# grabs:
|
||||
# selector: td.tlistdn
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
@@ -6,6 +6,8 @@
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://polishtracker.net/
|
||||
certificates:
|
||||
- 95EAB2795D8E35A14A9B35619C2568F974AE4D95 # expired
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
@@ -57,6 +59,8 @@
|
||||
search: "{{ .Query.Keywords }}"
|
||||
rows:
|
||||
selector: div#bro1 > table.shad1 > tbody > tr[class^="rowfx"]
|
||||
error:
|
||||
- selector: table.textfx2 td:contains("In order to use PolishTracker we require users to familiarize with FAQ, Rules and any News from Home Page.")
|
||||
fields:
|
||||
download:
|
||||
selector: a[href^="/download.php/"]
|
||||
|
@@ -1,107 +0,0 @@
|
||||
---
|
||||
site: qctorrent
|
||||
name: QcTorrent
|
||||
description: "A French gerneral tracker"
|
||||
language: fr-fr
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://www.qctorrent.net/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 30, cat: PC, desc: "++ Applications"}
|
||||
- {id: 1, cat: PC, desc: "Applications/Divers"}
|
||||
- {id: 2, cat: PC, desc: "Applications/PC ISO"}
|
||||
- {id: 3, cat: PC, desc: "Applications/Portable"}
|
||||
- {id: 31, cat: Movies, desc: "++ Films"}
|
||||
- {id: 4, cat: Movies/BluRay, desc: "Films/Bluray"}
|
||||
- {id: 5, cat: Movies/DVD, desc: "Films/DVDr"}
|
||||
- {id: 6, cat: Movies/HD, desc: "Films/HD Rip"}
|
||||
- {id: 7, cat: Movies/SD, desc: "Films/SD Rip"}
|
||||
- {id: 8, cat: Movies/SD, desc: "Films/VCD"}
|
||||
- {id: 32, cat: Console, desc: "++ Jeux"}
|
||||
- {id: 9, cat: PC/Games, desc: "Jeux/PC"}
|
||||
- {id: 10, cat: Console, desc: "Jeux/Portable"}
|
||||
- {id: 11, cat: Console/PS4, desc: "Jeux/PS"}
|
||||
- {id: 12, cat: Console/Wii, desc: "Jeux/Wii"}
|
||||
- {id: 13, cat: Console/Xbox, desc: "Jeux/Xbox"}
|
||||
- {id: 33, cat: Audio, desc: "++ Musique"}
|
||||
- {id: 14, cat: Audio, desc: "Musique"}
|
||||
- {id: 15, cat: Audio/Video, desc: "Musique/Video"}
|
||||
- {id: 34, cat: TV, desc: "++ Série-Télé"}
|
||||
- {id: 16, cat: TV/HD, desc: "Série-Télé/Bluray"}
|
||||
- {id: 17, cat: TV/SD, desc: "Série-Télé/DVDr"}
|
||||
- {id: 18, cat: TV/HD, desc: "Série-Télé/HD Rip"}
|
||||
- {id: 19, cat: TV/SD, desc: "Série-Télé/SD Rip"}
|
||||
- {id: 20, cat: Books, desc: "E-Books"}
|
||||
- {id: 21, cat: XXX, desc: "XXX"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
login:
|
||||
path: login.php
|
||||
method: post
|
||||
inputs:
|
||||
login-username: "{{ .Config.username }}"
|
||||
login-password: "{{ .Config.password }}"
|
||||
login-remember-me: "on"
|
||||
login: ""
|
||||
error:
|
||||
- selector: "script[type=\"text/javascript\"]:contains(\"$.ambiance({message: \")"
|
||||
test:
|
||||
path: search.php
|
||||
selector: div.top-bar > div.container > div.textleft > div.hidden-sm > font:contains("Ratio:") > font
|
||||
|
||||
ratio:
|
||||
path: search.php
|
||||
selector: div.top-bar > div.container > div.textleft > div.hidden-sm > font:contains("Ratio:") > font
|
||||
|
||||
search:
|
||||
path: search.php
|
||||
inputs:
|
||||
category: "{{range .Categories}}{{.}};{{end}}"
|
||||
title: "{{ .Query.Keywords }}"
|
||||
search: "Recherche"
|
||||
rows:
|
||||
selector: tr[data-snatches]
|
||||
fields:
|
||||
download:
|
||||
selector: td.name > a
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["/torrent/", "/dl/"]
|
||||
title:
|
||||
selector: td.name > a
|
||||
category:
|
||||
selector: td.coll-0 > a
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: category
|
||||
details:
|
||||
selector: td.name > a
|
||||
attribute: href
|
||||
grabs:
|
||||
attribute: data-snatches
|
||||
seeders:
|
||||
selector: td.seeds
|
||||
leechers:
|
||||
selector: td.leeches
|
||||
date:
|
||||
selector: td[data-date]
|
||||
attribute: data-date
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
span[title^="Freeleech:"]: "0"
|
||||
span[title^="Half Freeleech:"]: "0.5"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
||||
size:
|
||||
selector: td.size
|
||||
remove: span
|
@@ -1,103 +0,0 @@
|
||||
---
|
||||
site: redacted-scrape
|
||||
name: Redacted (scrape)
|
||||
description: "A music tracker"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://redacted.ch/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 1, cat: Audio, desc: "Music"}
|
||||
- {id: 2, cat: PC, desc: "Applications"}
|
||||
- {id: 3, cat: Books, desc: "E-Books"}
|
||||
- {id: 4, cat: Audio/Audiobook, desc: "Audiobooks"}
|
||||
- {id: 5, cat: Movies, desc: "E-Learning Videos"}
|
||||
- {id: 6, cat: TV, desc: "Comedy"}
|
||||
- {id: 7, cat: Books/Comics, desc: "Comics"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
login:
|
||||
path: login.php
|
||||
method: post
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
keeplogged: 1
|
||||
login: "Log in"
|
||||
error:
|
||||
- selector: form#loginform > span.warning
|
||||
test:
|
||||
path: torrents.php
|
||||
|
||||
ratio:
|
||||
path: torrents.php
|
||||
selector: li#stats_ratio > span
|
||||
|
||||
search:
|
||||
path: torrents.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
|
||||
searchstr: "{{ .Query.Keywords }}"
|
||||
order_by: time
|
||||
order_way: desc
|
||||
action: basic
|
||||
searchsubmit: 1
|
||||
rows:
|
||||
selector: table#torrent_table > tbody > tr.torrent
|
||||
fields:
|
||||
download:
|
||||
selector: a[href^="torrents.php?action=download&id="]
|
||||
attribute: href
|
||||
description:
|
||||
selector: div.group_info
|
||||
remove: span
|
||||
title:
|
||||
selector: div.group_info
|
||||
remove: span, div.tags
|
||||
filters:
|
||||
- name: replace
|
||||
args: [" / Neutral Leech!", ""]
|
||||
- name: replace
|
||||
args: [" / Freeleech!", ""]
|
||||
category:
|
||||
selector: td.cats_col
|
||||
case:
|
||||
div.cats_music: 1
|
||||
div.cats_applications: 2
|
||||
div.cats_ebooks: 3
|
||||
div.cats_audiobooks: 4
|
||||
div.cats_elearningvideos: 5
|
||||
div.cats_comedy: 6
|
||||
div.cats_comics: 7
|
||||
comments:
|
||||
selector: a[href^="torrents.php?id="]
|
||||
attribute: href
|
||||
files:
|
||||
selector: td:nth-child(3)
|
||||
date:
|
||||
selector: td:nth-child(4)
|
||||
size:
|
||||
selector: td:nth-child(5)
|
||||
grabs:
|
||||
selector: td:nth-child(6)
|
||||
seeders:
|
||||
selector: td:nth-child(7)
|
||||
leechers:
|
||||
selector: td:nth-child(8)
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"strong.tl_free": "0"
|
||||
"strong.tl_neutral": "0"
|
||||
":root div.alertbar:contains(\"freeleech\")": "0"
|
||||
":root div.alertbar:contains(\"FREELEECH\")": "0"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"strong.tl_neutral": "0"
|
||||
"*": "1"
|
@@ -54,20 +54,20 @@
|
||||
selector: td:nth-child(2) > img
|
||||
attribute: src
|
||||
size:
|
||||
selector: td:nth-child(8)
|
||||
files:
|
||||
selector: td:nth-child(5)
|
||||
grabs:
|
||||
selector: td:nth-child(9)
|
||||
files:
|
||||
selector: td:nth-child(6)
|
||||
grabs:
|
||||
selector: td:nth-child(10)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: ([\d\.]+)
|
||||
seeders:
|
||||
selector: td:nth-child(10)
|
||||
leechers:
|
||||
selector: td:nth-child(11)
|
||||
leechers:
|
||||
selector: td:nth-child(12)
|
||||
date:
|
||||
selector: td:nth-child(7)
|
||||
selector: td:nth-child(8)
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"a.info > b:contains(\"Free\")": "0"
|
||||
|
@@ -6,7 +6,7 @@
|
||||
type: private
|
||||
encoding: "UTF-8"
|
||||
links:
|
||||
- http://www.secret-cinema.net
|
||||
- https://secret-cinema.pw
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
|
@@ -50,9 +50,9 @@
|
||||
- name: dateparse
|
||||
args: "01-02-2006"
|
||||
download:
|
||||
selector: td > a[href^="/file"]
|
||||
selector: td > a[href^="magnet"]
|
||||
attribute: href
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
||||
text: "1"
|
||||
|
122
src/Jackett/Definitions/speedtorrentreloaded.yml
Normal file
122
src/Jackett/Definitions/speedtorrentreloaded.yml
Normal file
@@ -0,0 +1,122 @@
|
||||
---
|
||||
site: speedtorrentreloaded
|
||||
name: SpeedTorrent Reloaded
|
||||
language: de-de
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://speedtorrent-tracker.mine.nu/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 201, cat: Movies/HD, desc: "Filme: HD 720P / 1080P"}
|
||||
- {id: 103, cat: Movies/DVD, desc: "Filme: DVD"}
|
||||
- {id: 104, cat: Movies/DVD, desc: "Filme: HD2DVD"}
|
||||
- {id: 137, cat: Audio/Video, desc: "Musik: Video"}
|
||||
- {id: 106, cat: Movies/SD, desc: "Filme: DVDRip"}
|
||||
- {id: 107, cat: Movies/SD, desc: "Filme: BDRip "}
|
||||
- {id: 108, cat: Movies/3D, desc: "Filme: 3D"}
|
||||
- {id: 109, cat: Movies/BluRay, desc: "Filme: Blue Ray"}
|
||||
- {id: 111, cat: Movies/SD, desc: "Filme: SD"}
|
||||
- {id: 112, cat: Movies/Other, desc: "Filme: TV/HDTV"}
|
||||
- {id: 203, cat: XXX, desc: "Erotik: XXX PDF"}
|
||||
- {id: 116, cat: Console, desc: "Spiele: Konsolen"}
|
||||
- {id: 117, cat: PC/Games, desc: "Spiele: Windows / Mac"}
|
||||
- {id: 126, cat: PC/0day, desc: "Software: Mac / Linux"}
|
||||
- {id: 120, cat: Audio/Other, desc: "Musik: Alben/Sampler "}
|
||||
- {id: 121, cat: TV/SD, desc: "Serien: SD"}
|
||||
- {id: 123, cat: TV/Documentary, desc: "Doku: sonstige"}
|
||||
- {id: 124, cat: Console/Other, desc: "Spiele: sonstige"}
|
||||
- {id: 125, cat: PC/0day, desc: "Software: Windows"}
|
||||
- {id: 129, cat: PC/Phone-Other, desc: "Software: Handy / Navi / Sonst"}
|
||||
- {id: 131, cat: TV/HD, desc: "Serien: HD"}
|
||||
- {id: 132, cat: TV, desc: "Serien: Packs"}
|
||||
- {id: 135, cat: Audio, desc: "Musik: Discographie"}
|
||||
- {id: 138, cat: TV/Documentary, desc: "Doku: HD"}
|
||||
- {id: 139, cat: TV/Documentary, desc: "Doku: x264"}
|
||||
- {id: 141, cat: Audio/Audiobook, desc: "A/Ebook: Hoerbook"}
|
||||
- {id: 142, cat: Books, desc: "A/Ebook: EBooks"}
|
||||
- {id: 143, cat: Books, desc: "sonstige:PDF"}
|
||||
- {id: 144, cat: XXX, desc: "Erotik: XXX Pics"}
|
||||
- {id: 202, cat: TV/Sport, desc: "Sport"}
|
||||
- {id: 204, cat: XXX, desc: "XXX-Games"}
|
||||
- {id: 205, cat: Movies/SD, desc: "International-SD"}
|
||||
- {id: 206, cat: movies/HD, desc: "International-HD"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
login:
|
||||
path: takelogin.php
|
||||
method: post
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
test:
|
||||
path: browse.php
|
||||
|
||||
search:
|
||||
path: browse.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
incldead: "1"
|
||||
orderby: "added"
|
||||
sort: desc
|
||||
rows:
|
||||
selector: table.tableinborder > tbody > tr > td > table.tableinborder > tbody > tr:has(a[href^="details.php"])
|
||||
fields:
|
||||
title:
|
||||
selector: a[href^="details.php"]
|
||||
banner:
|
||||
selector: a[href^="details.php"][onmouseover]
|
||||
attribute: onmouseover
|
||||
filters:
|
||||
- name: regexp
|
||||
args: "<img src=(.*)>')"
|
||||
category:
|
||||
selector: a[href^="browse.php?cat="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
details:
|
||||
selector: a[href^="details.php"]
|
||||
attribute: href
|
||||
comments:
|
||||
selector: a[href*="&tocomm="]
|
||||
attribute: href
|
||||
download:
|
||||
selector: a[href^="download.php"]
|
||||
attribute: href
|
||||
files:
|
||||
selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(1) > b:nth-child(2)
|
||||
grabs:
|
||||
selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(3) > b:nth-child(1)
|
||||
size:
|
||||
selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(1) > b:nth-child(1)
|
||||
filters:
|
||||
- name: replace
|
||||
args: [".", ""]
|
||||
- name: replace
|
||||
args: [",", "."]
|
||||
seeders:
|
||||
selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(2) > b:nth-child(1)
|
||||
leechers:
|
||||
selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(2) > b:nth-child(3)
|
||||
date:
|
||||
selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(5)
|
||||
filters:
|
||||
- name: append
|
||||
args: " +2:00"
|
||||
- name: dateparse
|
||||
args: "02.01.2006 15:04:05 -07:00"
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
img[title="OnlyUp"]: "0"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
143
src/Jackett/Definitions/sporthd.yml
Normal file
143
src/Jackett/Definitions/sporthd.yml
Normal file
@@ -0,0 +1,143 @@
|
||||
---
|
||||
site: sporthd
|
||||
name: SportHD
|
||||
description: "Sports tracker"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://sporthd.org/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 50, cat: Movies, desc: "Australian Open"}
|
||||
- {id: 32, cat: Movies, desc: "Basketball"}
|
||||
- {id: 22, cat: Movies, desc: "Boxing"}
|
||||
- {id: 23, cat: Movies, desc: "Brasilareo Seria A"}
|
||||
- {id: 54, cat: Movies, desc: "Brazil League"}
|
||||
- {id: 11, cat: Movies, desc: "BundesLiga"}
|
||||
- {id: 45, cat: Movies, desc: "CAF"}
|
||||
- {id: 37, cat: Movies, desc: "Champions Hockey League"}
|
||||
- {id: 46, cat: Movies, desc: "Copa Americana"}
|
||||
- {id: 41, cat: Movies, desc: "Copa Del Rey"}
|
||||
- {id: 42, cat: Movies, desc: "Copa do Brasil"}
|
||||
- {id: 43, cat: Movies, desc: "Copa Libertadores"}
|
||||
- {id: 40, cat: Movies, desc: "Coppa Italia"}
|
||||
- {id: 51, cat: Movies, desc: "Coupe de France"}
|
||||
- {id: 39, cat: Movies, desc: "DFB Pokal"}
|
||||
- {id: 49, cat: Movies, desc: "English League Cup"}
|
||||
- {id: 8, cat: Movies, desc: "EPL"}
|
||||
- {id: 13, cat: Movies, desc: "Eredivisie"}
|
||||
- {id: 2, cat: Movies, desc: "EURO Cup"}
|
||||
- {id: 6, cat: Movies, desc: "EURO Cup Qualification"}
|
||||
- {id: 66, cat: Movies, desc: "Eurobasket"}
|
||||
- {id: 53, cat: Movies, desc: "Euroleague ULEB"}
|
||||
- {id: 38, cat: Movies, desc: "FA Cup"}
|
||||
- {id: 59, cat: Movies, desc: "FIFA U-20 World Cup"}
|
||||
- {id: 69, cat: Movies, desc: "FIFA World Clup Cup"}
|
||||
- {id: 19, cat: Movies, desc: "Football League Championship"}
|
||||
- {id: 18, cat: Movies, desc: "Formula 1"}
|
||||
- {id: 7, cat: Movies, desc: "Friendly matches"}
|
||||
- {id: 30, cat: Movies, desc: "Handball"}
|
||||
- {id: 31, cat: Movies, desc: "IIHF"}
|
||||
- {id: 15, cat: Movies, desc: "IndyCar"}
|
||||
- {id: 20, cat: Movies, desc: "KHL"}
|
||||
- {id: 10, cat: Movies, desc: "La Liga"}
|
||||
- {id: 12, cat: Movies, desc: "Ligue 1"}
|
||||
- {id: 21, cat: Movies, desc: "Major League Soccer"}
|
||||
- {id: 67, cat: Movies, desc: "MLB"}
|
||||
- {id: 63, cat: Movies, desc: "MMA"}
|
||||
- {id: 58, cat: Movies, desc: "MotoGP"}
|
||||
- {id: 16, cat: Movies, desc: "NBA"}
|
||||
- {id: 57, cat: Movies, desc: "NBA Playoffs"}
|
||||
- {id: 14, cat: Movies, desc: "NCAA"}
|
||||
- {id: 34, cat: Movies, desc: "NFL"}
|
||||
- {id: 17, cat: Movies, desc: "NHL"}
|
||||
- {id: 36, cat: Movies, desc: "Old classic games"}
|
||||
- {id: 68, cat: Movies, desc: "Olympic Games 2016"}
|
||||
- {id: 28, cat: Movies, desc: "Other domestic leagues"}
|
||||
- {id: 55, cat: Movies, desc: "Paulista A1"}
|
||||
- {id: 26, cat: Movies, desc: "Portuguese League"}
|
||||
- {id: 65, cat: Movies, desc: "ROH"}
|
||||
- {id: 61, cat: Movies, desc: "Rollan Garros"}
|
||||
- {id: 29, cat: Movies, desc: "Rugby"}
|
||||
- {id: 9, cat: Movies, desc: "Serie A"}
|
||||
- {id: 33, cat: Movies, desc: "SHL"}
|
||||
- {id: 47, cat: Movies, desc: "Ski Jumping"}
|
||||
- {id: 25, cat: Movies, desc: "Sport video"}
|
||||
- {id: 44, cat: Movies, desc: "Sudamericana"}
|
||||
- {id: 52, cat: Movies, desc: "Taca Da Liga"}
|
||||
- {id: 24, cat: Movies, desc: "Tennis"}
|
||||
- {id: 64, cat: Movies, desc: "TNA"}
|
||||
- {id: 56, cat: Movies, desc: "Torneo Premiera A"}
|
||||
- {id: 3, cat: Movies, desc: "UCL"}
|
||||
- {id: 4, cat: Movies, desc: "UEL"}
|
||||
- {id: 60, cat: Movies, desc: "UFC"}
|
||||
- {id: 35, cat: Movies, desc: "Volleyball"}
|
||||
- {id: 5, cat: Movies, desc: "WC Qualification"}
|
||||
- {id: 1, cat: Movies, desc: "World Cup"}
|
||||
- {id: 27, cat: Movies, desc: "World Cup 2014"}
|
||||
- {id: 48, cat: Movies, desc: "WWE"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
|
||||
settings:
|
||||
- name: cookie
|
||||
type: text
|
||||
label: Cookie
|
||||
|
||||
login:
|
||||
method: cookie
|
||||
inputs:
|
||||
cookie: "{{ .Config.cookie }}"
|
||||
test:
|
||||
path: index.php
|
||||
|
||||
download:
|
||||
selector: a[href^="download.php?id="]
|
||||
|
||||
search:
|
||||
path: browse.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
rows:
|
||||
selector: table.embedded > tbody > tr:has(a[href^="browse.php?cat="])
|
||||
fields:
|
||||
category:
|
||||
selector: a[href^="browse.php?cat="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
title:
|
||||
selector: td:nth-child(2)
|
||||
download:
|
||||
selector: a[href^="details.php?id="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["details.php?id=", "download.php?id="]
|
||||
details:
|
||||
selector: a[href^="details.php?id="]
|
||||
attribute: href
|
||||
# files:
|
||||
# selector: td:nth-child(3)
|
||||
# size:
|
||||
# selector: td:nth-child(4)
|
||||
#seeders:
|
||||
# selector: td:nth-child(5)
|
||||
#leechers:
|
||||
# selector: td:nth-child(5)
|
||||
# date:
|
||||
# selector: td:nth-child(7)
|
||||
# filters:
|
||||
# - name: append
|
||||
# args: " ago"
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
124
src/Jackett/Definitions/sportscult.yml
Normal file
124
src/Jackett/Definitions/sportscult.yml
Normal file
@@ -0,0 +1,124 @@
|
||||
---
|
||||
site: sportscult
|
||||
name: SportsCult
|
||||
description: "Sports tracker"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://sportscult.org
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 47, cat: TV/Sport, desc: "EPL"}
|
||||
- {id: 41, cat: TV/Sport, desc: "American Football"}
|
||||
- {id: 17, cat: TV/Sport, desc: "Athletics"}
|
||||
- {id: 34, cat: TV/Sport, desc: "Bodybuilding/Fitness"}
|
||||
- {id: 29, cat: TV/Sport, desc: "Boxing"}
|
||||
- {id: 19, cat: TV/Sport, desc: "BrainGames"}
|
||||
- {id: 36, cat: TV/Sport, desc: "BreakDance"}
|
||||
- {id: 40, cat: TV/Sport, desc: "Cricet/Golf/Baseball"}
|
||||
- {id: 23, cat: TV/Sport, desc: "Cycling"}
|
||||
- {id: 31, cat: TV/Sport, desc: "Documentary"}
|
||||
- {id: 1, cat: TV/Sport, desc: "European Basketball"}
|
||||
- {id: 6, cat: TV/Sport, desc: "European Soccer"}
|
||||
- {id: 37, cat: TV/Sport, desc: "Extreme Sports"}
|
||||
- {id: 9, cat: TV/Sport, desc: "Fight Sports"}
|
||||
- {id: 32, cat: TV/Sport, desc: "Formula1"}
|
||||
- {id: 45, cat: TV/Sport, desc: "GAA (Gaelic)"}
|
||||
- {id: 8, cat: TV/Sport, desc: "Golf"}
|
||||
- {id: 22, cat: TV/Sport, desc: "Gymnastics"}
|
||||
- {id: 39, cat: TV/Sport, desc: "Handball"}
|
||||
- {id: 2, cat: TV/Sport, desc: "International Basket"}
|
||||
- {id: 25, cat: TV/Sport, desc: "IceHockey"}
|
||||
- {id: 4, cat: TV/Sport, desc: "International Soccer"}
|
||||
- {id: 42, cat: TV/Sport, desc: "KHL"}
|
||||
- {id: 35, cat: TV/Sport, desc: "KickBoxing/Muay Thai"}
|
||||
- {id: 43, cat: TV/Sport, desc: "La Liga"}
|
||||
- {id: 15, cat: TV/Sport, desc: "MotorSport"}
|
||||
- {id: 24, cat: TV/Sport, desc: "MLB/Baseball"}
|
||||
- {id: 28, cat: TV/Sport, desc: "MMA"}
|
||||
- {id: 11, cat: TV/Sport, desc: "NBA/WNBA"}
|
||||
- {id: 3, cat: TV/Sport, desc: "NCAA Basket/Football"}
|
||||
- {id: 5, cat: TV/Sport, desc: "NFL"}
|
||||
- {id: 27, cat: TV/Sport, desc: "NHL"}
|
||||
- {id: 26, cat: TV/Sport, desc: "Olympic games"}
|
||||
- {id: 7, cat: TV/Sport, desc: "Rugby"}
|
||||
- {id: 44, cat: TV/Sport, desc: "Serie A"}
|
||||
- {id: 38, cat: TV/Sport, desc: "Snooker/Pool"}
|
||||
- {id: 30, cat: TV/Sport, desc: "Streetball"}
|
||||
- {id: 18, cat: TV/Sport, desc: "Swimming/Aquatics"}
|
||||
- {id: 46, cat: TV/Sport, desc: "AFL(AustralianFB)"}
|
||||
- {id: 12, cat: TV/Sport, desc: "Tennis"}
|
||||
- {id: 20, cat: TV/Sport, desc: "Volleyball/Beach"}
|
||||
- {id: 21, cat: TV/Sport, desc: "Weightlifting"}
|
||||
- {id: 16, cat: TV/Sport, desc: "WinterSport"}
|
||||
- {id: 33, cat: TV/Sport, desc: "Wrestling/Grapling"}
|
||||
- {id: 48, cat: TV/Sport, desc: "Uncategorised"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
|
||||
login:
|
||||
path: /?page=login
|
||||
method: form
|
||||
form: form
|
||||
inputs:
|
||||
uid: "{{ .Config.username }}"
|
||||
pwd: "{{ .Config.password }}"
|
||||
error:
|
||||
- selector: span:contains("Password Incorrect")
|
||||
test:
|
||||
path: index.php
|
||||
|
||||
download:
|
||||
selector: a[href^="download.php?id="]
|
||||
|
||||
search:
|
||||
path: index.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
page: torrents
|
||||
category: 0
|
||||
active: 1
|
||||
rows:
|
||||
selector: table[cellspacing!="1"].lista > tbody > tr:has(a[href^="index.php?page=torrents&category="])
|
||||
fields:
|
||||
category:
|
||||
selector: a[href^="index.php?page=torrents&category="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: category
|
||||
title:
|
||||
remove: span
|
||||
selector: td:nth-child(2)
|
||||
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="]
|
||||
details:
|
||||
selector: a[href^="index.php?page=torrent-details&id="]
|
||||
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(8)
|
||||
# date:
|
||||
# selector: td:nth-child(5)
|
||||
# filters:
|
||||
# - name: dateparse
|
||||
# args: "02/05/2017"
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
117
src/Jackett/Definitions/t411v2.yml
Executable file
117
src/Jackett/Definitions/t411v2.yml
Executable file
@@ -0,0 +1,117 @@
|
||||
---
|
||||
site: t411v2
|
||||
name: t411 v2
|
||||
language: fr-fr
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://t411.si
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 1, cat: Movies, desc: Films}
|
||||
- {id: 2, cat: TV, desc: Séries}
|
||||
- {id: 3, cat: TV/Anime, desc: Animes}
|
||||
- {id: 4, cat: Audio, desc: Musique}
|
||||
- {id: 5, cat: Books, desc: Ebooks}
|
||||
- {id: 6, cat: PC/0day, desc: Logiciels}
|
||||
- {id: 7, cat: PC/Games, desc: Jeux}
|
||||
- {id: 8, cat: TV/Documentary, desc: Documentaires}
|
||||
- {id: 9, cat: XXX, desc: XXX}
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
settings: []
|
||||
|
||||
download:
|
||||
selector: a[href^="/telecharger-torrent/"]
|
||||
|
||||
search:
|
||||
path: /torrents/search/?search={{ .Keywords}}
|
||||
rows:
|
||||
selector: tr.isItem.isItemDesk
|
||||
fields:
|
||||
category:
|
||||
selector: td.m-cat > a
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: category
|
||||
site_date:
|
||||
selector: td.m-name > a
|
||||
filters:
|
||||
# date is at the end of the title, so we get it and name it
|
||||
# site_date
|
||||
- name: regexp
|
||||
args: "(\\w+)$"
|
||||
title:
|
||||
selector: td.m-name > a
|
||||
filters:
|
||||
# now we put the date at the right place according scene
|
||||
# naming rules using .Result.site_date
|
||||
- name: replace
|
||||
args: ["FRENCH", "{{ .Result.site_date }} FRENCH"]
|
||||
- name: replace
|
||||
args: ["TRUEFRENCH", "{{ .Result.site_date }} TRUEFRENCH"]
|
||||
- name: replace
|
||||
args: ["VOSTFR", "{{ .Result.site_date }} VOSTFR"]
|
||||
# and we delete it at the end
|
||||
- name: re_replace
|
||||
args: ["(\\w+)$", ""]
|
||||
details:
|
||||
selector: td.m-name > a
|
||||
attribute: href
|
||||
download:
|
||||
selector: td.m-name > a
|
||||
attribute: href
|
||||
size:
|
||||
selector: td.m-taille > span
|
||||
filters:
|
||||
- name: re_replace
|
||||
args: [ "\\.(\\w+) K", "$1X00"]
|
||||
- name: re_replace
|
||||
args: [ " K", "000"]
|
||||
- name: re_replace
|
||||
args: [ "\\.(\\w+) M", "$1X0000"]
|
||||
- name: re_replace
|
||||
args: [ " M", "000000"]
|
||||
- name: re_replace
|
||||
args: [ "\\.(\\w+) G", "$1X0000000"]
|
||||
- name: re_replace
|
||||
args: [ " G", "000000000"]
|
||||
seeders:
|
||||
text: 0
|
||||
seeders:
|
||||
selector: td.m-seeders > span
|
||||
optional: true
|
||||
leechers:
|
||||
text: 0
|
||||
leechers:
|
||||
selector: td.m-leechers > span
|
||||
optional: true
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
||||
date:
|
||||
selector: td.m-age > span
|
||||
filters:
|
||||
- name: replace
|
||||
args: [ " jours", " days"]
|
||||
- name: replace
|
||||
args: [ " jour", " day"]
|
||||
- name: replace
|
||||
args: [ " heures", " hours"]
|
||||
- name: replace
|
||||
args: [ " heure", " hour"]
|
||||
- name: replace
|
||||
args: [ " semaines", " weeks"]
|
||||
- name: replace
|
||||
args: [ " semaine", " week"]
|
||||
- name: replace
|
||||
args: [ " mois", " month"]
|
||||
- name: replace
|
||||
args: [ " ans", " years"]
|
||||
- name: replace
|
||||
args: [ " an", " year"]
|
||||
- name: append
|
||||
args: " ago"
|
@@ -71,6 +71,9 @@
|
||||
keywords: "{{ .Keywords }}"
|
||||
search_type: "t_name"
|
||||
include_dead_torrents: "yes"
|
||||
keywordsfilters:
|
||||
- name: re_replace
|
||||
args: ["[^a-zA-Z0-9]+", "%"]
|
||||
rows:
|
||||
selector: table#sortabletable > tbody > tr:has(a[href])
|
||||
fields:
|
||||
|
@@ -6,7 +6,7 @@
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://www.theempire.bz/
|
||||
- http://theempire.click/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
|
157
src/Jackett/Definitions/thegeeks.yml
Normal file
157
src/Jackett/Definitions/thegeeks.yml
Normal file
@@ -0,0 +1,157 @@
|
||||
---
|
||||
site: thegeeks
|
||||
name: The Geeks
|
||||
description: "Technology E-Learning"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://thegeeks.click/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 71, cat: Other, desc: "Antiques / Collecting"}
|
||||
- {id: 46, cat: Other, desc: "Comp: Security/Encryption"}
|
||||
- {id: 37, cat: Other, desc: "Game Shows / Quiz Shows"}
|
||||
- {id: 16, cat: Other, desc: "Magic & Illusion"}
|
||||
- {id: 79, cat: Other, desc: "Reality: Competitions"}
|
||||
- {id: 68, cat: Other, desc: "Arts & Crafts / Jewelry"}
|
||||
- {id: 52, cat: Other, desc: "Comp: Software Training"}
|
||||
- {id: 2, cat: Other, desc: "Games: Cards / Gambling"}
|
||||
- {id: 12, cat: Other, desc: "Math & Statistics"}
|
||||
- {id: 53, cat: Other, desc: "Reality: Social Experiment"}
|
||||
- {id: 72, cat: Other, desc: "Astronomy / Space"}
|
||||
- {id: 41, cat: Other, desc: "Comp: Theory/Ref/Mags"}
|
||||
- {id: 63, cat: Other, desc: "Games: Tabletop / Roleplay"}
|
||||
- {id: 10, cat: Other, desc: "Medicine & Health"}
|
||||
- {id: 61, cat: Other, desc: "Sci: Biology"}
|
||||
- {id: 28, cat: Other, desc: "Business / Finance"}
|
||||
- {id: 47, cat: Other, desc: "Comp: Web Development"}
|
||||
- {id: 36, cat: Other, desc: "Gardening / Agriculture"}
|
||||
- {id: 26, cat: Other, desc: "Music: History / Theory"}
|
||||
- {id: 77, cat: Other, desc: "Sci: Chemistry"}
|
||||
- {id: 38, cat: Other, desc: "Crime & Investigation"}
|
||||
- {id: 21, cat: Other, desc: "DIY / Workshop"}
|
||||
- {id: 55, cat: Other, desc: "History of Civilization"}
|
||||
- {id: 15, cat: Other, desc: "Music: Learning / Courses"}
|
||||
- {id: 76, cat: Other, desc: "Sci: Physics"}
|
||||
- {id: 45, cat: Other, desc: "Photography"}
|
||||
- {id: 82, cat: Other, desc: "Docu: Architecture / Building"}
|
||||
- {id: 56, cat: Other, desc: "History of War & Politics"}
|
||||
- {id: 75, cat: Other, desc: "Nature"}
|
||||
- {id: 80, cat: Other, desc: "Sports - Live/Highlights"}
|
||||
- {id: 85, cat: Other, desc: "Childrens Educational"}
|
||||
- {id: 39, cat: Other, desc: "Docu: Fly on The Wall"}
|
||||
- {id: 58, cat: Other, desc: "History: Biographies"}
|
||||
- {id: 54, cat: Other, desc: "News / World Reports"}
|
||||
- {id: 22, cat: Other, desc: "Sports/Exercise/Outdoors"}
|
||||
- {id: 40, cat: Other, desc: "Comp: Certification Courses"}
|
||||
- {id: 69, cat: Other, desc: "Documentaries: Misc"}
|
||||
- {id: 31, cat: Other, desc: "History: Misc"}
|
||||
- {id: 83, cat: Other, desc: "Nova"}
|
||||
- {id: 24, cat: Other, desc: "Stock Media"}
|
||||
- {id: 44, cat: Other, desc: "Comp: Digital Audio/Video"}
|
||||
- {id: 59, cat: Other, desc: "Earth / Environment"}
|
||||
- {id: 23, cat: Other, desc: "Hobbies: Misc"}
|
||||
- {id: 27, cat: Other, desc: "Paleontology"}
|
||||
- {id: 33, cat: Other, desc: "Style & Fashion"}
|
||||
- {id: 48, cat: Other, desc: "Comp: Games Dev/Guides"}
|
||||
- {id: 18, cat: Other, desc: "Engineering"}
|
||||
- {id: 35, cat: Other, desc: "Home / Property"}
|
||||
- {id: 60, cat: Other, desc: "Performing Arts"}
|
||||
- {id: 73, cat: Other, desc: "Survivalism"}
|
||||
- {id: 3, cat: Other, desc: "Comp: Graphics "}
|
||||
- {id: 25, cat: Other, desc: "Exam Prep / Education"}
|
||||
- {id: 78, cat: Other, desc: "Horizon"}
|
||||
- {id: 67, cat: Other, desc: "Pets / Animal Keeping"}
|
||||
- {id: 86, cat: Other, desc: "Tattoos/Body Art"}
|
||||
- {id: 42, cat: Other, desc: "Comp: Lang/DBs"}
|
||||
- {id: 4, cat: Other, desc: "Fine & Visual Arts"}
|
||||
- {id: 1, cat: Other, desc: "Languages / Linguistics"}
|
||||
- {id: 29, cat: Other, desc: "Philosophy"}
|
||||
- {id: 32, cat: Other, desc: "Travel / Culture"}
|
||||
- {id: 49, cat: Other, desc: "Comp: Network/Hardware"}
|
||||
- {id: 9, cat: Other, desc: "Food / Cooking / Nutrition"}
|
||||
- {id: 20, cat: Other, desc: "Law & Justice"}
|
||||
- {id: 11, cat: Other, desc: "Political Studies"}
|
||||
- {id: 34, cat: Other, desc: "Vehicles & Transport"}
|
||||
- {id: 43, cat: Other, desc: "Comp: Operating Systems"}
|
||||
- {id: 84, cat: Other, desc: "FrontLine"}
|
||||
- {id: 30, cat: Other, desc: "Literature"}
|
||||
- {id: 14, cat: Other, desc: "Psychology/Sociology"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
|
||||
login:
|
||||
path: /login.php
|
||||
method: form
|
||||
form: form
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
captcha:
|
||||
type: image
|
||||
image: img#freecap
|
||||
input: word
|
||||
error:
|
||||
- selector: table:contains("Login failed!")
|
||||
test:
|
||||
path: main.php
|
||||
|
||||
download:
|
||||
selector: a[href^="download.php"]
|
||||
|
||||
search:
|
||||
path: browse.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
rows:
|
||||
selector: table[border="0"] > tbody > tr.ttable:has(a[href^="browse.php?cat="])
|
||||
fields:
|
||||
category:
|
||||
selector: a[href^="browse.php?cat="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
title:
|
||||
filters:
|
||||
selector: td:nth-child(2) b
|
||||
download:
|
||||
selector: a[href^="details.php?id="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["details.php?id=", "download.php?id="]
|
||||
details:
|
||||
selector: a[href^="details.php?id="]
|
||||
attribute: href
|
||||
grabs:
|
||||
selector: td:nth-child(8)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: ([\d,]+)
|
||||
files:
|
||||
selector: td:nth-child(4)
|
||||
size:
|
||||
selector: td:nth-child(7)
|
||||
seeders:
|
||||
selector: td:nth-child(9)
|
||||
leechers:
|
||||
selector: td:nth-child(10)
|
||||
date:
|
||||
selector: td:nth-child(6)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: (\d{4}-\d{2}-\d{2})
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"font[color=\"green\"]": "0"
|
||||
"font[color=\"blue\"]": "0"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"font[color=\"green\"]": "0"
|
||||
"*": "1"
|
139
src/Jackett/Definitions/theoccult.yml
Normal file
139
src/Jackett/Definitions/theoccult.yml
Normal file
@@ -0,0 +1,139 @@
|
||||
---
|
||||
site: theoccult
|
||||
name: The Occult
|
||||
description: "Cult E-Learning"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://theoccult.click/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 63, cat: Other, desc: "Academic / Reference"}
|
||||
- {id: 21, cat: Other, desc: "Everything Else"}
|
||||
- {id: 68, cat: Other, desc: "Mythology and Folklore"}
|
||||
- {id: 61, cat: Other, desc: "Rajneesh"}
|
||||
- {id: 1, cat: Other, desc: "Thelema / Crowley"}
|
||||
- {id: 51, cat: Other, desc: "African/African Diaspora Relig"}
|
||||
- {id: 30, cat: Other, desc: "Fourth Way"}
|
||||
- {id: 17, cat: Other, desc: "Native American"}
|
||||
- {id: 57, cat: Other, desc: "Ritual Magic"}
|
||||
- {id: 74, cat: Other, desc: "Theosophy / Anthroposophy"}
|
||||
- {id: 10, cat: Other, desc: "Alchemy"}
|
||||
- {id: 7, cat: Other, desc: "Freemasonry"}
|
||||
- {id: 54, cat: Other, desc: "New Age"}
|
||||
- {id: 34, cat: Other, desc: "Rosicrucian"}
|
||||
- {id: 73, cat: Other, desc: "Traditional Left-Hand Path"}
|
||||
- {id: 69, cat: Other, desc: "Ancient Languages"}
|
||||
- {id: 6, cat: Other, desc: "Golden Dawn"}
|
||||
- {id: 76, cat: Other, desc: "Non-Dualism"}
|
||||
- {id: 75, cat: Other, desc: "Sacred Geometry"}
|
||||
- {id: 71, cat: Other, desc: "Traditional Witchcraft"}
|
||||
- {id: 9, cat: Other, desc: "Astrology"}
|
||||
- {id: 35, cat: Other, desc: "Grimoires"}
|
||||
- {id: 52, cat: Other, desc: "Northern European Paganism"}
|
||||
- {id: 31, cat: Other, desc: "Satanism"}
|
||||
- {id: 77, cat: Other, desc: "Transpersonal Psychology"}
|
||||
- {id: 25, cat: Other, desc: "Buddhism "}
|
||||
- {id: 26, cat: Other, desc: "Hinduism"}
|
||||
- {id: 70, cat: Other, desc: "Other Divination"}
|
||||
- {id: 28, cat: Other, desc: "Shamanism"}
|
||||
- {id: 19, cat: Other, desc: "Wicca / NeoWicca / Eclectic"}
|
||||
- {id: 32, cat: Other, desc: "Chaos Magic "}
|
||||
- {id: 64, cat: Other, desc: "Lovecraft Mythos"}
|
||||
- {id: 67, cat: Other, desc: "Other Eastern Traditions"}
|
||||
- {id: 56, cat: Other, desc: "Southern European Paganism"}
|
||||
- {id: 20, cat: Other, desc: "Yoga / Tantra"}
|
||||
- {id: 66, cat: Other, desc: "Energy Healing"}
|
||||
- {id: 13, cat: Other, desc: "Lucid Dreams/Astral Projection"}
|
||||
- {id: 49, cat: Other, desc: "Paranormal"}
|
||||
- {id: 72, cat: Other, desc: "Specialty Presses"}
|
||||
- {id: 4, cat: Other, desc: "Enochian"}
|
||||
- {id: 14, cat: Other, desc: "Meditation"}
|
||||
- {id: 33, cat: Other, desc: "Parapsychology"}
|
||||
- {id: 58, cat: Other, desc: "Sufism"}
|
||||
- {id: 11, cat: Other, desc: "Entheogens"}
|
||||
- {id: 53, cat: Other, desc: "Middle Eastern Magic"}
|
||||
- {id: 15, cat: Other, desc: "Philosophy"}
|
||||
- {id: 55, cat: Other, desc: "Taoism / Daoism"}
|
||||
- {id: 29, cat: Other, desc: "Esoteric Christianity"}
|
||||
- {id: 65, cat: Other, desc: "Modern Grimoires"}
|
||||
- {id: 12, cat: Other, desc: "Qabalah / Kabbalah / Cabala"}
|
||||
- {id: 18, cat: Other, desc: "Tarot / Oracle Cards"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
|
||||
login:
|
||||
path: /login.php
|
||||
method: form
|
||||
form: form
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
captcha:
|
||||
type: image
|
||||
image: img#freecap
|
||||
input: word
|
||||
error:
|
||||
- selector: table:contains("Login failed!")
|
||||
test:
|
||||
path: main.php
|
||||
|
||||
download:
|
||||
selector: a[href^="download.php"]
|
||||
|
||||
search:
|
||||
path: browse.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
rows:
|
||||
selector: table[border="0"] > tbody > tr.ttable:has(a[href^="browse.php?cat="])
|
||||
fields:
|
||||
category:
|
||||
selector: a[href^="browse.php?cat="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
title:
|
||||
filters:
|
||||
selector: td:nth-child(2) b
|
||||
download:
|
||||
selector: a[href^="details.php?id="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["details.php?id=", "download.php?id="]
|
||||
details:
|
||||
selector: a[href^="details.php?id="]
|
||||
attribute: href
|
||||
grabs:
|
||||
selector: td:nth-child(8)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: ([\d,]+)
|
||||
files:
|
||||
selector: td:nth-child(4)
|
||||
size:
|
||||
selector: td:nth-child(7)
|
||||
seeders:
|
||||
selector: td:nth-child(9)
|
||||
leechers:
|
||||
selector: td:nth-child(10)
|
||||
date:
|
||||
selector: td:nth-child(6)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: (\d{4}-\d{2}-\d{2})
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"font[color=\"green\"]": "0"
|
||||
"font[color=\"blue\"]": "0"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"font[color=\"green\"]": "0"
|
||||
"*": "1"
|
@@ -73,7 +73,12 @@
|
||||
settings: []
|
||||
|
||||
search:
|
||||
path: "{{if .Query.Keywords}}/search/{{ .Query.Keywords}}/0/99/{{range .Categories }}{{.}}{{end}}{{else}}/recent{{end}}"
|
||||
path: "{{if .Query.Keywords}}/search/{{ .Keywords}}/0/99/{{range .Categories }}{{.}}{{end}}{{else}}/recent{{end}}"
|
||||
keywordsfilters:
|
||||
# currently, the only uploader for General Hospital puts a space between season and episode
|
||||
# this filter searches both formats, so "General Hospital S01E02" becomes "General Hospital S01E02 | (S01 E02)"
|
||||
- name: re_replace
|
||||
args: ["General Hospital S(\\d{2,3})E(\\d{2,3})", "$0 | \\(S$1 E$2\\)"]
|
||||
rows:
|
||||
selector: "#searchResult tbody tr:has(td.vertTh)"
|
||||
fields:
|
||||
@@ -85,6 +90,9 @@
|
||||
args: [ "/", -1 ]
|
||||
title:
|
||||
selector: .detLink
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["\u000f", ""] # get rid of unwanted character (Example: at the end of https://thepiratebay.org/torrent/18316540/Game.of.Thrones.S07E04.iNTERNAL.1080p.WEBRip.x264-MOROSE_)
|
||||
details:
|
||||
selector: .detLink
|
||||
attribute: href
|
||||
|
120
src/Jackett/Definitions/theplace.yml
Normal file
120
src/Jackett/Definitions/theplace.yml
Normal file
@@ -0,0 +1,120 @@
|
||||
---
|
||||
site: theplace
|
||||
name: The Place
|
||||
description: "Self-improvement E-Learning"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://theplace.click/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 46, cat: Other, desc: "Alpha Male Example Clips"}
|
||||
- {id: 68, cat: Other, desc: "Author: Juggler"}
|
||||
- {id: 69, cat: Other, desc: "Author: Sean Messenger"}
|
||||
- {id: 42, cat: Other, desc: "Food / Drink / Cooking"}
|
||||
- {id: 22, cat: Other, desc: "Seduction: Other"}
|
||||
- {id: 60, cat: Other, desc: "Author: AMP"}
|
||||
- {id: 70, cat: Other, desc: "Author: Michael Hall (NLP)"}
|
||||
- {id: 61, cat: Other, desc: "Author: Style (Neil Strauss)"}
|
||||
- {id: 47, cat: Other, desc: "Health / Fitness / Massage"}
|
||||
- {id: 39, cat: Other, desc: "Seduction: Video"}
|
||||
- {id: 51, cat: Other, desc: "Author: Anthony Robbins"}
|
||||
- {id: 49, cat: Other, desc: "Author: Mystery"}
|
||||
- {id: 66, cat: Other, desc: "Author: Vince Kelvin"}
|
||||
- {id: 43, cat: Other, desc: "Hypnotism / NLP"}
|
||||
- {id: 14, cat: Other, desc: "Seduction: Written"}
|
||||
- {id: 50, cat: Other, desc: "Author: Carlos Xuma"}
|
||||
- {id: 53, cat: Other, desc: "Author: Pickup101"}
|
||||
- {id: 41, cat: Other, desc: "Dance / Singing / Voice"}
|
||||
- {id: 44, cat: Other, desc: "Languages / Accents"}
|
||||
- {id: 40, cat: Other, desc: "Sex"}
|
||||
- {id: 48, cat: Other, desc: "Author: David DeAngelo"}
|
||||
- {id: 65, cat: Other, desc: "Author: Richard Bandler (NLP)"}
|
||||
- {id: 57, cat: Other, desc: "Everything Else"}
|
||||
- {id: 45, cat: Other, desc: "Magic / Illusions / Tricks"}
|
||||
- {id: 54, cat: Other, desc: "Author: David Shade"}
|
||||
- {id: 52, cat: Other, desc: "Author: Ross Jeffries"}
|
||||
- {id: 58, cat: Other, desc: "Fashion / Clothing / Grooming"}
|
||||
- {id: 59, cat: Other, desc: "Psychology / Body Language"}
|
||||
- {id: 71, cat: Other, desc: "Author: Jerry Stocking"}
|
||||
- {id: 67, cat: Other, desc: "Author: RSD"}
|
||||
- {id: 64, cat: Other, desc: "Fighting / Martial Arts"}
|
||||
- {id: 38, cat: Other, desc: "Seduction: Audio"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
|
||||
login:
|
||||
path: /login.php
|
||||
method: form
|
||||
form: form
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
captcha:
|
||||
type: image
|
||||
image: img#freecap
|
||||
input: word
|
||||
error:
|
||||
- selector: table:contains("Login failed!")
|
||||
test:
|
||||
path: main.php
|
||||
|
||||
download:
|
||||
selector: a[href^="download.php"]
|
||||
|
||||
search:
|
||||
path: browse.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
rows:
|
||||
selector: table[border="0"] > tbody > tr.ttable:has(a[href^="browse.php?cat="])
|
||||
fields:
|
||||
category:
|
||||
selector: a[href^="browse.php?cat="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
title:
|
||||
filters:
|
||||
selector: td:nth-child(2) b
|
||||
download:
|
||||
selector: a[href^="details.php?id="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["details.php?id=", "download.php?id="]
|
||||
details:
|
||||
selector: a[href^="details.php?id="]
|
||||
attribute: href
|
||||
grabs:
|
||||
selector: td:nth-child(8)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: ([\d,]+)
|
||||
files:
|
||||
selector: td:nth-child(4)
|
||||
size:
|
||||
selector: td:nth-child(7)
|
||||
seeders:
|
||||
selector: td:nth-child(9)
|
||||
leechers:
|
||||
selector: td:nth-child(10)
|
||||
date:
|
||||
selector: td:nth-child(6)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: (\d{4}-\d{2}-\d{2})
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"font[color=\"green\"]": "0"
|
||||
"font[color=\"blue\"]": "0"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"font[color=\"green\"]": "0"
|
||||
"*": "1"
|
137
src/Jackett/Definitions/theshow.yml
Normal file
137
src/Jackett/Definitions/theshow.yml
Normal file
@@ -0,0 +1,137 @@
|
||||
---
|
||||
site: theshow
|
||||
name: The Show
|
||||
description: "Entertainment E-Learning"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://theshow.click/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 64, cat: Other, desc: "Graphics / Photo Editing"}
|
||||
- {id: 51, cat: Other, desc: "Performing Craft: Acting"}
|
||||
- {id: 85, cat: Other, desc: "Scripts: Theatre"}
|
||||
- {id: 90, cat: Other, desc: "Visual Craft: Handcraft/Sculpt"}
|
||||
- {id: 32, cat: Other, desc: "Magazines / Trade Journals"}
|
||||
- {id: 4, cat: Other, desc: "Performing Craft: Dance"}
|
||||
- {id: 49, cat: Other, desc: "Software / Tutorials"}
|
||||
- {id: 93, cat: Other, desc: "Visual Craft: Jewelry Making"}
|
||||
- {id: 17, cat: Other, desc: "A-V: Film/Video Editing"}
|
||||
- {id: 66, cat: Other, desc: "Mindset / Creativity"}
|
||||
- {id: 10, cat: Other, desc: "Production: Cinematography"}
|
||||
- {id: 26, cat: Other, desc: "Stock: Film / Video"}
|
||||
- {id: 11, cat: Other, desc: "Visual Craft: Needlework"}
|
||||
- {id: 30, cat: Other, desc: "A-V: Sound Recording/Design"}
|
||||
- {id: 67, cat: Other, desc: "Music Business / Promotion"}
|
||||
- {id: 1, cat: Other, desc: "Production: Directing (Film)"}
|
||||
- {id: 54, cat: Other, desc: "Stock: Music / Sound FX"}
|
||||
- {id: 52, cat: Other, desc: "Visual Craft: Photography"}
|
||||
- {id: 6, cat: Other, desc: "A-V: Videography"}
|
||||
- {id: 73, cat: Other, desc: "Music: Shows/Special Events"}
|
||||
- {id: 7, cat: Other, desc: "Production: Directing(Theatre)"}
|
||||
- {id: 13, cat: Other, desc: "Stock: Photos / Illustrations"}
|
||||
- {id: 89, cat: Other, desc: "Visual Craft: Scrapbooking"}
|
||||
- {id: 9, cat: Other, desc: "A-V: Visual FX"}
|
||||
- {id: 70, cat: Other, desc: "Performances: Competitions"}
|
||||
- {id: 53, cat: Other, desc: "Production: Visuals"}
|
||||
- {id: 69, cat: Other, desc: "TV Shows: Action/Drama/Mystery"}
|
||||
- {id: 88, cat: Other, desc: "Visual Craft: Tattoos/Body Art"}
|
||||
- {id: 29, cat: Other, desc: "Business / Distribution"}
|
||||
- {id: 94, cat: Other, desc: "Performances: Dance/Ballet"}
|
||||
- {id: 77, cat: Other, desc: "Radio: Comedy/Drama/Mystery"}
|
||||
- {id: 68, cat: Other, desc: "TV Shows: Comedy"}
|
||||
- {id: 21, cat: Other, desc: "Writing Craft: Screenwriting"}
|
||||
- {id: 56, cat: Other, desc: "Creative Writing"}
|
||||
- {id: 82, cat: Other, desc: "Performances: Drama/Art"}
|
||||
- {id: 79, cat: Other, desc: "Radio: Entertain/Arts/Narrativ"}
|
||||
- {id: 71, cat: Other, desc: "TV Shows: Entertain/Chat/Goss"}
|
||||
- {id: 25, cat: Other, desc: "Digital Craft: 3D Modeling"}
|
||||
- {id: 76, cat: Other, desc: "Performances: Sketch/Improv"}
|
||||
- {id: 80, cat: Other, desc: "Radio: Music Performances"}
|
||||
- {id: 92, cat: Other, desc: "Visual Craft: Design Theory"}
|
||||
- {id: 63, cat: Other, desc: "Everything Else"}
|
||||
- {id: 75, cat: Other, desc: "Performances: Spoken Word"}
|
||||
- {id: 83, cat: Other, desc: "Scripts: Radio"}
|
||||
- {id: 91, cat: Other, desc: "Visual Craft: Drawing/Drafting"}
|
||||
- {id: 65, cat: Other, desc: "Film History / Theory "}
|
||||
- {id: 78, cat: Other, desc: "Performances: Standup Comedy"}
|
||||
- {id: 84, cat: Other, desc: "Scripts: Television"}
|
||||
- {id: 87, cat: Other, desc: "Visual Craft: Fashion/Makeup"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
|
||||
login:
|
||||
path: /login.php
|
||||
method: form
|
||||
form: form
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
captcha:
|
||||
type: image
|
||||
image: img#freecap
|
||||
input: word
|
||||
error:
|
||||
- selector: table:contains("Login failed!")
|
||||
test:
|
||||
path: main.php
|
||||
|
||||
download:
|
||||
selector: a[href^="download.php"]
|
||||
|
||||
search:
|
||||
path: browse.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
rows:
|
||||
selector: table[border="0"] > tbody > tr.ttable:has(a[href^="browse.php?cat="])
|
||||
fields:
|
||||
category:
|
||||
selector: a[href^="browse.php?cat="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
title:
|
||||
filters:
|
||||
selector: td:nth-child(2) b
|
||||
download:
|
||||
selector: a[href^="details.php?id="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["details.php?id=", "download.php?id="]
|
||||
details:
|
||||
selector: a[href^="details.php?id="]
|
||||
attribute: href
|
||||
grabs:
|
||||
selector: td:nth-child(8)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: ([\d,]+)
|
||||
files:
|
||||
selector: td:nth-child(4)
|
||||
size:
|
||||
selector: td:nth-child(7)
|
||||
seeders:
|
||||
selector: td:nth-child(9)
|
||||
leechers:
|
||||
selector: td:nth-child(10)
|
||||
date:
|
||||
selector: td:nth-child(6)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: (\d{4}-\d{2}-\d{2})
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"font[color=\"green\"]": "0"
|
||||
"font[color=\"blue\"]": "0"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"font[color=\"green\"]": "0"
|
||||
"*": "1"
|
@@ -65,8 +65,9 @@
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
login:
|
||||
path: /takelogin.php
|
||||
method: post
|
||||
path: /login.php
|
||||
method: form
|
||||
form: form[action="takelogin.php"]
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
@@ -102,7 +103,7 @@
|
||||
- name: querystring
|
||||
args: cat
|
||||
download:
|
||||
selector: a[href^="/download.php/"]
|
||||
selector: a[href^="/download.php"]
|
||||
attribute: href
|
||||
description:
|
||||
selector: td:nth-child(2) > small
|
||||
|
138
src/Jackett/Definitions/thevault.yml
Normal file
138
src/Jackett/Definitions/thevault.yml
Normal file
@@ -0,0 +1,138 @@
|
||||
---
|
||||
site: thevault
|
||||
name: The Vault
|
||||
description: "Business/Marketing E-Learning"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://thevault.click/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 87, cat: Other, desc: "Author: Brian Tracy"}
|
||||
- {id: 106, cat: Other, desc: "Autobiographies / Biographies"}
|
||||
- {id: 67, cat: Other, desc: "Investing / Trading / Stocks"}
|
||||
- {id: 93, cat: Other, desc: "Negotiation / Contracts"}
|
||||
- {id: 99, cat: Other, desc: "Net: Traffic Generation"}
|
||||
- {id: 107, cat: Other, desc: "Author: Dan Kennedy"}
|
||||
- {id: 118, cat: Other, desc: "Ayn Rand / Objectivism"}
|
||||
- {id: 75, cat: Other, desc: "Magazines"}
|
||||
- {id: 97, cat: Other, desc: "Net: Affiliate Schemes"}
|
||||
- {id: 102, cat: Other, desc: "Net: Web Site/Blog Templates"}
|
||||
- {id: 110, cat: Other, desc: "Author: Dan Pena"}
|
||||
- {id: 112, cat: Other, desc: "Consulting"}
|
||||
- {id: 70, cat: Other, desc: "Management / Leadership"}
|
||||
- {id: 105, cat: Other, desc: "Net: Blogging"}
|
||||
- {id: 114, cat: Other, desc: "Network Marketing (MLM)"}
|
||||
- {id: 117, cat: Other, desc: "Author: Eben Pagan"}
|
||||
- {id: 94, cat: Other, desc: "Copywriting"}
|
||||
- {id: 85, cat: Other, desc: "Mindset / Achievement"}
|
||||
- {id: 76, cat: Other, desc: "Net: E-Commerce"}
|
||||
- {id: 111, cat: Other, desc: "Offshore / Tax Avoidance"}
|
||||
- {id: 92, cat: Other, desc: "Author: Jay Abraham"}
|
||||
- {id: 103, cat: Other, desc: "Corporate Design / Branding"}
|
||||
- {id: 80, cat: Other, desc: "Misc: Audio"}
|
||||
- {id: 100, cat: Other, desc: "Net: eBay / Online Auctions"}
|
||||
- {id: 116, cat: Other, desc: "Private Label Rights (PLR)"}
|
||||
- {id: 89, cat: Other, desc: "Author: Jim Rohn"}
|
||||
- {id: 84, cat: Other, desc: "Customer Service"}
|
||||
- {id: 90, cat: Other, desc: "Misc: Other"}
|
||||
- {id: 115, cat: Other, desc: "Net: Email Marketing"}
|
||||
- {id: 68, cat: Other, desc: "Real Estate / Property Develop"}
|
||||
- {id: 96, cat: Other, desc: "Author: John Reese"}
|
||||
- {id: 65, cat: Other, desc: "Economics / Finance"}
|
||||
- {id: 83, cat: Other, desc: "Misc: Software"}
|
||||
- {id: 95, cat: Other, desc: "Net: Marketing"}
|
||||
- {id: 104, cat: Other, desc: "Recruitment / Interviewing"}
|
||||
- {id: 63, cat: Other, desc: "Author: Robert Kiyosaki"}
|
||||
- {id: 113, cat: Other, desc: "Entertainment Business"}
|
||||
- {id: 81, cat: Other, desc: "Misc: Video"}
|
||||
- {id: 101, cat: Other, desc: "Net: Misc"}
|
||||
- {id: 71, cat: Other, desc: "Sales / Marketing"}
|
||||
- {id: 86, cat: Other, desc: "Author: T Harv Eker"}
|
||||
- {id: 109, cat: Other, desc: "Gambling / Betting"}
|
||||
- {id: 82, cat: Other, desc: "Misc: Written / E-Books"}
|
||||
- {id: 98, cat: Other, desc: "Net: Pay-Per-Click Advertising"}
|
||||
- {id: 72, cat: Other, desc: "Small Business / Entrepreneurs"}
|
||||
- {id: 88, cat: Other, desc: "Author: Zig Ziglar"}
|
||||
- {id: 73, cat: Other, desc: "Hypnosis / NLP"}
|
||||
- {id: 62, cat: Other, desc: "Money Management / Taxes"}
|
||||
- {id: 108, cat: Other, desc: "Net: Search Engine Optimizing"}
|
||||
- {id: 91, cat: Other, desc: "TTC Lectures"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
|
||||
login:
|
||||
path: /login.php
|
||||
method: form
|
||||
form: form
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
captcha:
|
||||
type: image
|
||||
image: img#freecap
|
||||
input: word
|
||||
error:
|
||||
- selector: table:contains("Login failed!")
|
||||
test:
|
||||
path: main.php
|
||||
|
||||
download:
|
||||
selector: a[href^="download.php"]
|
||||
|
||||
search:
|
||||
path: browse.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
rows:
|
||||
selector: table[border="0"] > tbody > tr.ttable:has(a[href^="browse.php?cat="])
|
||||
fields:
|
||||
category:
|
||||
selector: a[href^="browse.php?cat="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
title:
|
||||
filters:
|
||||
selector: td:nth-child(2) b
|
||||
download:
|
||||
selector: a[href^="details.php?id="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["details.php?id=", "download.php?id="]
|
||||
details:
|
||||
selector: a[href^="details.php?id="]
|
||||
attribute: href
|
||||
grabs:
|
||||
selector: td:nth-child(8)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: ([\d,]+)
|
||||
files:
|
||||
selector: td:nth-child(4)
|
||||
size:
|
||||
selector: td:nth-child(7)
|
||||
seeders:
|
||||
selector: td:nth-child(9)
|
||||
leechers:
|
||||
selector: td:nth-child(10)
|
||||
date:
|
||||
selector: td:nth-child(6)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: (\d{4}-\d{2}-\d{2})
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"font[color=\"green\"]": "0"
|
||||
"font[color=\"blue\"]": "0"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"font[color=\"green\"]": "0"
|
||||
"*": "1"
|
81
src/Jackett/Definitions/tokyotosho.yml
Normal file
81
src/Jackett/Definitions/tokyotosho.yml
Normal file
@@ -0,0 +1,81 @@
|
||||
---
|
||||
site: tokyotosho
|
||||
name: Tokyo Toshokan
|
||||
description: "A BitTorrent Library for Japanese Media"
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://www.tokyotosho.info/
|
||||
|
||||
settings:
|
||||
- name: type-id
|
||||
type: text
|
||||
label: Type Id
|
||||
|
||||
caps:
|
||||
categories:
|
||||
1: TV/Anime # Anime
|
||||
10: TV/Anime # Non-English Anime
|
||||
3: Books # Manga
|
||||
8: TV/Anime # Drama
|
||||
2: Audio # Anime Music
|
||||
9: TV/Anime # Anime Music Videos
|
||||
7: TV/Anime # Raw Anime
|
||||
4: XXX # Hentai
|
||||
12: XXX # Hentai (Anime)
|
||||
13: XXX # Hentai (Manga)
|
||||
14: XXX # Hentai (Games)
|
||||
11: TV/Anime # Batch
|
||||
15: XXX # JAV
|
||||
5: Other # Other
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
search:
|
||||
path: "{{if .Query.Keywords }}search.php{{else}}index.php{{end}}"
|
||||
inputs:
|
||||
terms: "{{ .Query.Keywords }}"
|
||||
type: "{{ .Config.type-id }}"
|
||||
cat: "{{ .Config.type-id }}"
|
||||
rows:
|
||||
selector: "table.listing tr.category_0"
|
||||
after: 1
|
||||
fields:
|
||||
category:
|
||||
selector: td:nth-child(1) > a
|
||||
attribute: href
|
||||
filters:
|
||||
- name: regexp
|
||||
args: "(\\d+)"
|
||||
title:
|
||||
selector: td:nth-child(2) > a:nth-child(2)
|
||||
details:
|
||||
selector: td:nth-child(3) > a
|
||||
attribute: href
|
||||
download:
|
||||
selector: td:nth-child(2) > a:nth-child(2)
|
||||
attribute: href
|
||||
size:
|
||||
selector: td:nth-child(4)
|
||||
filters:
|
||||
- name: split
|
||||
args: [ "|", 1 ]
|
||||
- name: regexp
|
||||
args: "Size: (.+?) ?$"
|
||||
date:
|
||||
selector: td:nth-child(4)
|
||||
filters:
|
||||
- name: split
|
||||
args: [ "|", 2 ]
|
||||
- name: regexp
|
||||
args: "Date: (.+?) ?$"
|
||||
- name: replace
|
||||
args: ["UTC","-00"]
|
||||
- name: dateparse
|
||||
args: "2006-01-02 15:04 -07"
|
||||
seeders:
|
||||
selector: td:nth-child(5) > span:nth-child(1)
|
||||
leechers:
|
||||
selector: td:nth-child(5) > span:nth-child(2)
|
79
src/Jackett/Definitions/torlock.yml
Normal file
79
src/Jackett/Definitions/torlock.yml
Normal file
@@ -0,0 +1,79 @@
|
||||
---
|
||||
site: torlock
|
||||
name: Torlock
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://www.torlock.com/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: TELEVISION, cat: TV, desc: "TV Shows"}
|
||||
- {id: MOVIES, cat: Movies, desc: "Movies"}
|
||||
- {id: MUSIC, cat: Audio, desc: "Music"}
|
||||
- {id: GAMES, cat: PC/Games, desc: "Games"}
|
||||
- {id: SOFTWARE, cat: PC, desc: "Software"}
|
||||
- {id: ANIME, cat: TV/Anime, desc: "Anime"}
|
||||
- {id: EBOOKS, cat: Books/Ebook, desc: "Books"}
|
||||
- {id: OTHER, cat: Other, desc: "Other"}
|
||||
- {id: ADULT, cat: XXX, desc: "Adult"}
|
||||
- {id: AUDIOBOOK, cat: Audio/Audiobook, desc: "Audiobook"}
|
||||
- {id: IMAGES, cat: Other/Misc, desc: "Images"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
|
||||
settings: []
|
||||
|
||||
search:
|
||||
path: "{{if .Keywords}}/all/torrents/{{ .Keywords }}.html{{else}}/fresh.html{{end}}"
|
||||
keywordsfilters:
|
||||
- name: tolower
|
||||
- name: re_replace
|
||||
args: ["[^a-zA-Z0-9]+", "-"]
|
||||
rows:
|
||||
selector: table > tbody > tr:has(td:has(div:has(a[href^="/torrent/"])))
|
||||
fields:
|
||||
title:
|
||||
selector: td:nth-child(1) > div > a
|
||||
details:
|
||||
selector: td:nth-child(1) > div > a[href^="/torrent/"]
|
||||
attribute: href
|
||||
download:
|
||||
selector: td:nth-child(1) > div > a[href^="/torrent/"]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["/torrent/", "/tor/"]
|
||||
- name: regexp
|
||||
args: (^/tor/\d*)
|
||||
- name: append
|
||||
args: ".torrent"
|
||||
date:
|
||||
selector: td:nth-child(2)
|
||||
size:
|
||||
selector: td:nth-child(3)
|
||||
seeders:
|
||||
selector: td:nth-child(4)
|
||||
leechers:
|
||||
selector: td:nth-child(5)
|
||||
category:
|
||||
selector: span[class^="tv"]
|
||||
attribute: class
|
||||
case:
|
||||
span.tv0: OTHER
|
||||
span.tv1: MOVIES
|
||||
span.tv2: MUSIC
|
||||
span.tv3: TELEVISION
|
||||
span.tv4: GAMES
|
||||
span.tv5: SOFTWARE
|
||||
span.tv6: ANIME
|
||||
span.tv7: ADULT
|
||||
span.tv8: EBOOKS
|
||||
span.tv9: IMAGES
|
||||
span.tv12: AUDIOBOOK
|
||||
downloadvolumefactor:
|
||||
text: "1"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
@@ -5,7 +5,7 @@
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://www.torrent9.biz/
|
||||
- http://www.torrent9.cc/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
@@ -28,8 +28,25 @@
|
||||
rows:
|
||||
selector: div.table-responsive > table tbody tr
|
||||
fields:
|
||||
site_date:
|
||||
selector: td:nth-child(1) a
|
||||
filters:
|
||||
# date is at the end of the title, so we get it and name it site_date
|
||||
- name: regexp
|
||||
args: "(\\w+)$"
|
||||
title:
|
||||
selector: td:nth-child(1) a
|
||||
filters:
|
||||
# now we put the date at the right place according scene naming rules using .Result.site_date
|
||||
- name: replace
|
||||
args: ["FRENCH", "{{ .Result.site_date }} FRENCH"]
|
||||
- name: replace
|
||||
args: ["TRUEFRENCH", "{{ .Result.site_date }} TRUEFRENCH"]
|
||||
- name: replace
|
||||
args: ["VOSTFR", "{{ .Result.site_date }} VOSTFR"]
|
||||
# and we delete it at the end
|
||||
- name: re_replace
|
||||
args: ["(\\w+)$", ""]
|
||||
details:
|
||||
selector: td:nth-child(1) a
|
||||
attribute: href
|
||||
@@ -75,4 +92,4 @@
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
||||
text: "1"
|
||||
|
61
src/Jackett/Definitions/torrentdownloads.yml
Normal file
61
src/Jackett/Definitions/torrentdownloads.yml
Normal file
@@ -0,0 +1,61 @@
|
||||
---
|
||||
site: torrentdownloads
|
||||
name: Torrent Downloads
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://www.torrentdownloads.me/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 8, cat: TV, desc: "TV Shows"}
|
||||
- {id: 4, cat: Movies, desc: "Movies"}
|
||||
- {id: 5, cat: Audio, desc: "Music"}
|
||||
- {id: 3, cat: PC/Games, desc: "Games"}
|
||||
- {id: 7, cat: PC, desc: "Software"}
|
||||
- {id: 1, cat: TV/Anime, desc: "Anime"}
|
||||
- {id: 2, cat: Books, desc: "Books"}
|
||||
- {id: 9, cat: Other, desc: "Other"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
|
||||
settings: []
|
||||
|
||||
search:
|
||||
path: "{{if .Keywords}}/search/{{else}}/today/{{end}}"
|
||||
inputs:
|
||||
$raw: "new=1&{{range .Categories}}s_cat={{.}}&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
rows:
|
||||
selector: div.inner_container > div:has(p:has(a[href^="/torrent/"]))
|
||||
fields:
|
||||
title:
|
||||
selector: p:nth-child(1) > a
|
||||
details:
|
||||
selector: p:nth-child(1) > a[href^="/torrent/"]
|
||||
attribute: href
|
||||
download:
|
||||
selector: p:nth-child(1) > a[href^="/torrent/"]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["/torrent/", "/download/"]
|
||||
size:
|
||||
selector: span:nth-child(5)
|
||||
seeders:
|
||||
selector: span:nth-child(4)
|
||||
leechers:
|
||||
selector: span:nth-child(3)
|
||||
category:
|
||||
selector: img[src^="/templates/new/images/icons/menu_icon"]
|
||||
attribute: src
|
||||
filters:
|
||||
- name: regexp
|
||||
args: ([\d,]+)
|
||||
- name: strdump
|
||||
downloadvolumefactor:
|
||||
text: "1"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
@@ -52,9 +52,23 @@
|
||||
details:
|
||||
selector: span > a
|
||||
attribute: href
|
||||
download:
|
||||
magfile:
|
||||
text: "{{ .Result.title }}"
|
||||
filters:
|
||||
- name: validfilename
|
||||
- name: urlencode
|
||||
magnet:
|
||||
selector: span > a
|
||||
attribute: href
|
||||
filters:
|
||||
- name: regexp
|
||||
args: "/(\\w+)/"
|
||||
- name: prepend
|
||||
args: "magnet:?xt=urn:btih:"
|
||||
- name: append
|
||||
args: "&dn={{ .Result.magfile }}.torrent"
|
||||
- name: append
|
||||
args: "&tr=http://182.176.139.129:6969/announce&tr=http://explodie.org:6969/announce&tr=http://tracker.mgtracker.org:2710/announce&tr=udp://tracker.coppersurfer.tk:6969/announce&tr=udp://tracker.leechers-paradise.org:6969/announce&tr=udp://tracker.pirateparty.gr:6969/announce&tr=udp://tracker.sktorrent.net:6969/announce&tr=udp://tracker.zer0day.to:1337/announce"
|
||||
category|optional:
|
||||
selector: div > span:nth-child(1) > span
|
||||
date:
|
||||
|
@@ -7,7 +7,7 @@
|
||||
links:
|
||||
- https://www.trancetraffic.com
|
||||
certificates:
|
||||
- D40789207A75EA36B02E255BF7162C8DF9637750 # expired 13.03.2017
|
||||
- 117B89D7C086F3E051F0A5A3576504667402AE52
|
||||
|
||||
caps:
|
||||
categories:
|
||||
|
@@ -110,9 +110,6 @@
|
||||
test:
|
||||
path: index.php
|
||||
|
||||
download:
|
||||
selector: a[href^="download.php?id="]
|
||||
|
||||
search:
|
||||
path: browse.php
|
||||
inputs:
|
||||
@@ -130,11 +127,8 @@
|
||||
title:
|
||||
selector: td:nth-child(2)
|
||||
download:
|
||||
selector: a[href^="/details.php?id="]
|
||||
selector: a[href^="/download.php/"]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["/details.php?id=", "/download.php?id="]
|
||||
details:
|
||||
selector: a[href^="/details.php?id="]
|
||||
attribute: href
|
||||
|
@@ -93,7 +93,7 @@
|
||||
searchin: "title"
|
||||
|
||||
rows:
|
||||
selector: table.browsewidth100 > tbody > tr:has(a[href^="download.php?torrent="])
|
||||
selector: table > tbody > tr:has(a[href^="download.php?torrent="])
|
||||
filters:
|
||||
- name: andmatch
|
||||
fields:
|
||||
|
@@ -86,18 +86,23 @@
|
||||
selector: a[href^="dwn.php"]
|
||||
attribute: href
|
||||
size:
|
||||
selector: td:nth-child(6)
|
||||
selector: td:nth-child(7)
|
||||
date:
|
||||
selector: td:nth-child(5)
|
||||
selector: td:nth-child(6)
|
||||
filters:
|
||||
- name: append
|
||||
args: " +00:00"
|
||||
- name: dateparse
|
||||
args: "02-01-200615:04:05 -07:00"
|
||||
seeders:
|
||||
selector: td:nth-child(7)
|
||||
leechers:
|
||||
grabs:
|
||||
selector: td:nth-child(8)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: ([\d\.]+)
|
||||
seeders:
|
||||
selector: td:nth-child(9)
|
||||
leechers:
|
||||
selector: td:nth-child(10)
|
||||
banner:
|
||||
selector: a[onmouseover][href^="details.php?id="]
|
||||
attribute: onmouseover
|
||||
|
165
src/Jackett/Definitions/yggtorrent.yml
Executable file
165
src/Jackett/Definitions/yggtorrent.yml
Executable file
@@ -0,0 +1,165 @@
|
||||
---
|
||||
site: yggtorrent
|
||||
name: YGGtorrent
|
||||
language: fr-fr
|
||||
type: semi-private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://yggtorrent.com
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
# Film/Video for search results
|
||||
- {id: 2145, cat: Other, desc: "Movies & TV"}
|
||||
- {id: 2178, cat: Movies, desc: "Anim Movies"}
|
||||
- {id: 2179, cat: TV/Anime, desc: "Anim TV"}
|
||||
- {id: 2180, cat: Other, desc: "Concerts"}
|
||||
- {id: 2181, cat: TV/Documentary, desc: "Documentary"}
|
||||
- {id: 2182, cat: TV, desc: "TV Shows"}
|
||||
- {id: 2183, cat: Movies, desc: "Movies"}
|
||||
- {id: 2184, cat: TV, desc: "TV"}
|
||||
- {id: 2185, cat: TV/Other, desc: "Shows"}
|
||||
- {id: 2186, cat: TV/Sport, desc: "Sport"}
|
||||
- {id: 2187, cat: TV/Other, desc: "Clips"}
|
||||
# Film/Video for blank search
|
||||
- {id: "Tous les torrents", cat: Other, desc: "Movies & TV"}
|
||||
- {id: "Animation", cat: Movies, desc: "Anim Movies"}
|
||||
- {id: "Animation Série", cat: TV/Anime, desc: "Anim TV"}
|
||||
- {id: "Concert", cat: Other, desc: "Concerts"}
|
||||
- {id: "Documentaire", cat: TV/Documentary, desc: "Documentary"}
|
||||
- {id: "Emission TV", cat: TV, desc: "TV Shows"}
|
||||
- {id: "Film", cat: Movies, desc: "Movies"}
|
||||
- {id: "Série TV", cat: TV, desc: "TV"}
|
||||
- {id: "Spectacle", cat: TV/Other, desc: "Shows"}
|
||||
- {id: "Sport", cat: TV/Sport, desc: "Sport"}
|
||||
- {id: "Vidéo-clips", cat: TV/Other, desc: "Clips"}
|
||||
modes:
|
||||
search: [q]
|
||||
#tv-search: [q, season, ep]
|
||||
settings:
|
||||
- name: username
|
||||
type: text
|
||||
label: Username (email or username)
|
||||
- name: password
|
||||
type: password
|
||||
label: Password
|
||||
- name: filter_title
|
||||
type: checkbox
|
||||
label: Try to normalize releases names by moving year after the title
|
||||
default: false
|
||||
login:
|
||||
path: "/user/login"
|
||||
method: post
|
||||
inputs:
|
||||
id: "{{ .Config.username }}"
|
||||
pass: "{{ .Config.password }}"
|
||||
submit: ""
|
||||
headers:
|
||||
"[:authority]": "yggtorrent.com"
|
||||
"[:method]": "post"
|
||||
"[:path]": "/"
|
||||
"[:scheme]": "https"
|
||||
error:
|
||||
- selector: "body > div.page-content > div > div.col-md-10 > div > div > div > div > div.content-box-large.box-with-header > form > center > table > tbody > tr:nth-child(3) > td:nth-child(2) > button.text:contains('Se connecter')"
|
||||
test:
|
||||
path: "/"
|
||||
selector: "a[href=\"https://yggtorrent.com/user/logout\"]"
|
||||
search:
|
||||
paths:
|
||||
- path: "{{if .Keywords}}/engine/search?q={{ .Keywords}}{{else}}/torrents/2145-filmvideo{{end}}"
|
||||
- path: "{{if .Keywords}}/engine/search?q={{ .Keywords}}&page=15{{else}}/torrents/2145-filmvideo?page=25{{end}}"
|
||||
- path: "{{if .Keywords}}/engine/search?q={{ .Keywords}}&page=30{{else}}/torrents/2145-filmvideo?page=50{{end}}"
|
||||
rows:
|
||||
selector: "table.table.table-striped > tbody > tr"
|
||||
fields:
|
||||
site_date:
|
||||
selector: "td:nth-child(3)"
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["il y a ", ""]
|
||||
- name: replace
|
||||
args: [ " jours", " days"]
|
||||
- name: replace
|
||||
args: [ " jour", " day"]
|
||||
- name: replace
|
||||
args: [ " heures", " hours"]
|
||||
- name: replace
|
||||
args: [ " heure", " hour"]
|
||||
- name: replace
|
||||
args: [ " semaines", " weeks"]
|
||||
- name: replace
|
||||
args: [ " semaine", " week"]
|
||||
- name: replace
|
||||
args: [ " mois", " month"]
|
||||
- name: replace
|
||||
args: [ " ans", " years"]
|
||||
- name: replace
|
||||
args: [ " an", " year"]
|
||||
- name: append
|
||||
args: " ago"
|
||||
title_normal:
|
||||
selector: "a.torrent-name"
|
||||
title_filtered:
|
||||
selector: "a.torrent-name"
|
||||
filters:
|
||||
- name: re_replace
|
||||
args: ["(?i)^(?:(.+?)((?:[\\.\\-\\s_\\[]+(?:imax|(?:dvd|bd|tv)(?:rip|scr)|bluray(?:\\-?rip)?|720\\s*p?|1080\\s*p?|vof?|vost(?:fr)?|multi|vf(?:f|q)?[1-3]?|(?:true)?french|eng?)[\\.\\-\\s_\\]]*)*)([\\(\\[]?(?:20|1[7-9])\\d{2}[\\)\\]]?)(.*)$|(.*))$", "$1 $3 $2 $4 $5"]
|
||||
- name: replace
|
||||
args: [".", " "]
|
||||
- name: trim
|
||||
- name: re_replace
|
||||
args: ["(?i)\\s(mkv|avi|divx|xvid|mp4)$", ""]
|
||||
- name: re_replace
|
||||
args: ["(\\s{2,5})", " "]
|
||||
- name: trim
|
||||
title:
|
||||
text: "{{if .Config.filter_title }}{{ .Result.title_filtered }}{{else}}{{ .Result.title_normal }}{{end}}"
|
||||
details:
|
||||
selector: "a.torrent-name"
|
||||
attribute: href
|
||||
category:
|
||||
selector: "td:nth-child(1) > span > i:last-child > a"
|
||||
comments:
|
||||
optional: true
|
||||
selector: "td:nth-child(1) > a[href$=\"#comments\"]"
|
||||
attribute: href
|
||||
download:
|
||||
selector: "td:nth-child(1) > a[href^=\"https://yggtorrent.com/engine/download_torrent?id=\"]"
|
||||
attribute: href
|
||||
size:
|
||||
selector: "td:nth-child(4)"
|
||||
filters:
|
||||
- name: re_replace
|
||||
args: [ "\\.(\\d) KB", "$1X00"]
|
||||
- name: re_replace
|
||||
args: [ " KB", "000"]
|
||||
- name: re_replace
|
||||
args: [ "\\.(\\d) MB", "$1X00000"]
|
||||
- name: re_replace
|
||||
args: [ " MB", "000000"]
|
||||
- name: re_replace
|
||||
args: [ "\\.(\\d) GB", "$1X00000000"]
|
||||
- name: re_replace
|
||||
args: [ " GB", "000000000"]
|
||||
- name: re_replace
|
||||
args: [ "\\.(\\d) TB", "$1X00000000000"]
|
||||
- name: re_replace
|
||||
args: [ " TB", "000000000000"]
|
||||
- name: replace
|
||||
args: [ "X", "" ]
|
||||
seeders:
|
||||
text: 0
|
||||
seeders:
|
||||
selector: "td:nth-child(5)"
|
||||
optional: true
|
||||
leechers:
|
||||
text: 0
|
||||
leechers:
|
||||
selector: "td:nth-child(6)"
|
||||
optional: true
|
||||
date:
|
||||
text: "{{ .Result.site_date }}"
|
||||
downloadvolumefactor:
|
||||
text: "1"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
87
src/Jackett/Definitions/zamundanet.yml
Normal file
87
src/Jackett/Definitions/zamundanet.yml
Normal file
@@ -0,0 +1,87 @@
|
||||
---
|
||||
site: zamundanet
|
||||
name: Zamunda.net
|
||||
language: bg-bg
|
||||
type: private
|
||||
encoding: windows-1251
|
||||
links:
|
||||
- http://zamunda.net/
|
||||
|
||||
caps:
|
||||
categories:
|
||||
7: TV/SD
|
||||
33: TV/HD
|
||||
25: TV/Other
|
||||
5: Movies/HD
|
||||
19: Movies/SD
|
||||
46: Movies/3D
|
||||
42: Movies/BluRay
|
||||
20: Movies/DVD
|
||||
9: XXX
|
||||
49: XXX/Other
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
login:
|
||||
path: /takelogin.php
|
||||
method: post
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
error:
|
||||
- selector: td.embedded:has(h2:contains("failed"))
|
||||
test:
|
||||
path: /bananas
|
||||
|
||||
search:
|
||||
path: /bananas
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
incldead: 1
|
||||
rows:
|
||||
selector: .responsetop > tbody > tr:has(td.td_newborder)
|
||||
fields:
|
||||
title:
|
||||
selector: td:nth-child(2) > a:nth-child(1)
|
||||
details:
|
||||
selector: td:nth-child(2) > a:nth-child(1)
|
||||
attribute: href
|
||||
category:
|
||||
selector: td:nth-child(1) > a
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
download:
|
||||
selector: a:has(i.fa-download)
|
||||
attribute: href
|
||||
grabs:
|
||||
selector: td:nth-child(7)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: (\d+)
|
||||
size:
|
||||
selector: td:nth-child(6)
|
||||
date:
|
||||
selector: td:nth-child(5)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: ([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))
|
||||
seeders:
|
||||
selector: td:nth-child(8)
|
||||
leechers:
|
||||
selector: td:nth-child(9)
|
||||
banner:
|
||||
selector: td:nth-child(2) > a:nth-child(1)
|
||||
attribute: onmouseover
|
||||
filters:
|
||||
- name: regexp
|
||||
args: src=\\'([^\s\\]+)
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
93
src/Jackett/Definitions/zelkaorg.yml
Normal file
93
src/Jackett/Definitions/zelkaorg.yml
Normal file
@@ -0,0 +1,93 @@
|
||||
---
|
||||
site: zelkaorg
|
||||
name: Zelka.org
|
||||
language: bg-bg
|
||||
type: private
|
||||
encoding: windows-1251
|
||||
links:
|
||||
- http://zelka.org/
|
||||
- http://zamunda.se/
|
||||
|
||||
caps:
|
||||
categories:
|
||||
7: TV/SD
|
||||
33: TV/HD
|
||||
25: TV/Other
|
||||
5: Movies/HD
|
||||
53: Movies/HD
|
||||
35: Movies/WEBDL
|
||||
19: Movies/SD
|
||||
46: Movies/3D
|
||||
42: Movies/BluRay
|
||||
20: Movies/DVD
|
||||
9: XXX
|
||||
49: XXX/Other
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
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}}cat{{.}}=1&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
incldead: 1
|
||||
rows:
|
||||
selector: .test > tbody > tr:has(a[href^="browse.php"])
|
||||
fields:
|
||||
title:
|
||||
selector: td:nth-child(2) > a:nth-child(1)
|
||||
details:
|
||||
selector: td:nth-child(2) > a:nth-child(1)
|
||||
attribute: href
|
||||
category:
|
||||
selector: td:nth-child(1) > a
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
download:
|
||||
selector: a:has(img[src^="http://img.zamunda.se/pic/download.gif"])
|
||||
attribute: href
|
||||
magnet:
|
||||
selector: a:has(img[src^="http://img.zamunda.se/pic/magnet-icon-12w-12h.gif"])
|
||||
attribute: href
|
||||
grabs:
|
||||
selector: td:nth-child(7)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: (\d+)
|
||||
size:
|
||||
selector: td:nth-child(6)
|
||||
date:
|
||||
selector: td:nth-child(5)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: ([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))
|
||||
seeders:
|
||||
selector: td:nth-child(8)
|
||||
leechers:
|
||||
selector: td:nth-child(9)
|
||||
banner:
|
||||
selector: td:nth-child(2) > a:nth-child(1)
|
||||
attribute: onmouseover
|
||||
filters:
|
||||
- name: regexp
|
||||
args: src=([^\s]+)
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
88
src/Jackett/Definitions/zetorrents.yml
Executable file
88
src/Jackett/Definitions/zetorrents.yml
Executable file
@@ -0,0 +1,88 @@
|
||||
---
|
||||
site: zetorrents
|
||||
name: zetorrents
|
||||
language: fr-fr
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://www.zetorrents.cc/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: films, cat: Movies, desc: "Movies"}
|
||||
- {id: series, cat: TV, desc: "TV"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
settings: []
|
||||
|
||||
download:
|
||||
selector: a[href^="/get_torrent/"]
|
||||
|
||||
search:
|
||||
path: "/recherche/{{ .Query.Keywords }}"
|
||||
rows:
|
||||
selector: div.content-list-torrent > table tbody tr:has(a)
|
||||
fields:
|
||||
site_date:
|
||||
selector: td:nth-child(1) a
|
||||
filters:
|
||||
# date is at the end of the title, so we get it and name it site_date
|
||||
- name: regexp
|
||||
args: "(\\w+)$"
|
||||
title:
|
||||
selector: td:nth-child(1) a
|
||||
filters:
|
||||
# now we put the date at the right place according scene naming rules using .Result.site_date
|
||||
- name: replace
|
||||
args: ["FRENCH", "{{ .Result.site_date }} FRENCH"]
|
||||
- name: replace
|
||||
args: ["TRUEFRENCH", "{{ .Result.site_date }} TRUEFRENCH"]
|
||||
- name: replace
|
||||
args: ["VOSTFR", "{{ .Result.site_date }} VOSTFR"]
|
||||
# and we delete it at the end
|
||||
- name: re_replace
|
||||
args: ["(\\w+)$", ""]
|
||||
details:
|
||||
selector: td:nth-child(1) a
|
||||
attribute: href
|
||||
download:
|
||||
selector: td:nth-child(1) a
|
||||
attribute: href
|
||||
size:
|
||||
selector: td:nth-child(2)
|
||||
filters:
|
||||
- name: re_replace
|
||||
args: [ "\\.(\\d) Ko", "$1X00"]
|
||||
- name: re_replace
|
||||
args: [ " Ko", "000"]
|
||||
- name: re_replace
|
||||
args: [ "\\.(\\d) Mo", "$1X00000"]
|
||||
- name: re_replace
|
||||
args: [ " Mo", "000000"]
|
||||
- name: re_replace
|
||||
args: [ "\\.(\\d) Go", "$1X00000000"]
|
||||
- name: re_replace
|
||||
args: [ " Go", "000000000"]
|
||||
- name: re_replace
|
||||
args: [ "\\.(\\d) To", "$1X00000000000"]
|
||||
- name: re_replace
|
||||
args: [ " To", "000000000000"]
|
||||
- name: replace
|
||||
args: [ "X", "" ]
|
||||
seeders:
|
||||
text: 0
|
||||
seeders:
|
||||
selector: td:nth-child(3)
|
||||
optional: true
|
||||
leechers:
|
||||
text: 0
|
||||
leechers:
|
||||
selector: td:nth-child(4)
|
||||
optional: true
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
@@ -10,6 +10,8 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Http.Dependencies;
|
||||
using Autofac.Integration.WebApi;
|
||||
|
||||
namespace Jackett
|
||||
{
|
||||
@@ -37,9 +39,9 @@ namespace Jackett
|
||||
|
||||
}
|
||||
|
||||
public static IContainer GetContainer()
|
||||
public static IDependencyResolver DependencyResolver()
|
||||
{
|
||||
return container;
|
||||
return new AutofacWebApiDependencyResolver(container);
|
||||
}
|
||||
|
||||
public static bool IsWindows
|
||||
|
30
src/Jackett/IndexerException.cs
Normal file
30
src/Jackett/IndexerException.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using Jackett.Indexers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett
|
||||
{
|
||||
class IndexerException : Exception
|
||||
{
|
||||
public IIndexer Indexer { get; protected set; }
|
||||
|
||||
public IndexerException(IIndexer Indexer, string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
this.Indexer = Indexer;
|
||||
}
|
||||
|
||||
public IndexerException(IIndexer Indexer, string message)
|
||||
: this(Indexer, message, null)
|
||||
{
|
||||
}
|
||||
|
||||
public IndexerException(IIndexer Indexer, Exception innerException)
|
||||
: this(Indexer, "Exception (" + Indexer.ID + "): " + innerException.Message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@@ -18,7 +18,7 @@ using System.Web;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
public class SevenTor : BaseIndexer, IIndexer
|
||||
public class SevenTor : BaseWebIndexer
|
||||
{
|
||||
string LoginUrl { get { return SiteLink + "ucp.php?mode=login"; } }
|
||||
string SearchUrl { get { return SiteLink + "search.php"; } }
|
||||
@@ -29,12 +29,12 @@ namespace Jackett.Indexers
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public SevenTor(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
|
||||
public SevenTor(IIndexerConfigurationService configService, IWebClient wc, Logger l, IProtectionService ps)
|
||||
: base(name: "7tor",
|
||||
description: null,
|
||||
link: "https://7tor.org/",
|
||||
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: i,
|
||||
configService: configService,
|
||||
client: wc,
|
||||
logger: l,
|
||||
p: ps,
|
||||
@@ -1584,7 +1584,7 @@ namespace Jackett.Indexers
|
||||
AddCategoryMapping(1569, TorznabCatType.Other, " Amateur videos");
|
||||
}
|
||||
|
||||
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
LoadValuesFromJson(configJson);
|
||||
|
||||
@@ -1606,7 +1606,7 @@ namespace Jackett.Indexers
|
||||
return IndexerConfigurationStatus.RequiresTesting;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
var searchString = query.GetQueryString();
|
||||
|
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
@@ -22,7 +23,7 @@ namespace Jackett.Indexers
|
||||
/// <summary>
|
||||
/// Provider for Abnormal Private French Tracker
|
||||
/// </summary>
|
||||
public class Abnormal : BaseIndexer, IIndexer
|
||||
public class Abnormal : BaseCachingWebIndexer
|
||||
{
|
||||
private string LoginUrl { get { return SiteLink + "login.php"; } }
|
||||
private string SearchUrl { get { return SiteLink + "torrents.php"; } }
|
||||
@@ -32,7 +33,7 @@ namespace Jackett.Indexers
|
||||
private bool Latency { get { return ConfigData.Latency.Value; } }
|
||||
private bool DevMode { get { return ConfigData.DevMode.Value; } }
|
||||
private bool CacheMode { get { return ConfigData.HardDriveCache.Value; } }
|
||||
private string directory { get { return System.IO.Path.GetTempPath() + "Jackett\\" + MethodBase.GetCurrentMethod().DeclaringType.Name + "\\"; } }
|
||||
private static string Directory => Path.Combine(Path.GetTempPath(), Assembly.GetExecutingAssembly().GetName().Name.ToLower(), MethodBase.GetCurrentMethod().DeclaringType?.Name.ToLower());
|
||||
|
||||
private Dictionary<string, string> emulatedBrowserHeaders = new Dictionary<string, string>();
|
||||
private CQ fDom = null;
|
||||
@@ -43,13 +44,13 @@ namespace Jackett.Indexers
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public Abnormal(IIndexerManagerService i, IWebClient w, Logger l, IProtectionService ps)
|
||||
public Abnormal(IIndexerConfigurationService configService, IWebClient w, Logger l, IProtectionService ps)
|
||||
: base(
|
||||
name: "Abnormal",
|
||||
description: "General French Private Tracker",
|
||||
link: "https://abnormal.ws/",
|
||||
caps: new TorznabCapabilities(),
|
||||
manager: i,
|
||||
configService: configService,
|
||||
client: w,
|
||||
logger: l,
|
||||
p: ps,
|
||||
@@ -104,7 +105,7 @@ namespace Jackett.Indexers
|
||||
/// </summary>
|
||||
/// <param name="configJson">Our params in Json</param>
|
||||
/// <returns>Configuration state</returns>
|
||||
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
// Retrieve config values set by Jackett's user
|
||||
LoadValuesFromJson(configJson);
|
||||
@@ -117,7 +118,8 @@ namespace Jackett.Indexers
|
||||
// emulatedBrowserHeaders.Add("Accept-Encoding", "gzip, deflate");
|
||||
|
||||
// If we want to simulate a browser
|
||||
if (ConfigData.Browser.Value) {
|
||||
if (ConfigData.Browser.Value)
|
||||
{
|
||||
|
||||
// Clean headers
|
||||
emulatedBrowserHeaders.Clear();
|
||||
@@ -149,7 +151,8 @@ namespace Jackett.Indexers
|
||||
};
|
||||
|
||||
// Do the login
|
||||
var request = new Utils.Clients.WebRequest(){
|
||||
var request = new Utils.Clients.WebRequest()
|
||||
{
|
||||
PostData = pairs,
|
||||
Referer = LoginUrl,
|
||||
Type = RequestType.POST,
|
||||
@@ -187,7 +190,7 @@ namespace Jackett.Indexers
|
||||
/// </summary>
|
||||
/// <param name="query">Query</param>
|
||||
/// <returns>Releases</returns>
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
var torrentRowList = new List<CQ>();
|
||||
@@ -197,7 +200,7 @@ namespace Jackett.Indexers
|
||||
int pageLinkCount = 0;
|
||||
|
||||
// Check cache first so we don't query the server (if search term used or not in dev mode)
|
||||
if(!DevMode && !string.IsNullOrEmpty(searchTerm))
|
||||
if (!DevMode && !string.IsNullOrEmpty(searchTerm))
|
||||
{
|
||||
lock (cache)
|
||||
{
|
||||
@@ -215,8 +218,7 @@ namespace Jackett.Indexers
|
||||
var request = buildQuery(searchTerm, query, searchUrl);
|
||||
|
||||
// Getting results & Store content
|
||||
WebClientStringResult results = await queryExec(request);
|
||||
fDom = results.Content;
|
||||
fDom = await queryExec(request);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -230,14 +232,16 @@ namespace Jackett.Indexers
|
||||
Boolean pagination = (fDom[".linkbox > a"].Length != 0);
|
||||
|
||||
// If pagination available
|
||||
if (pagination) {
|
||||
if (pagination)
|
||||
{
|
||||
// Calculate numbers of pages available for this search query (Based on number results and number of torrents on first page)
|
||||
pageLinkCount = ParseUtil.CoerceInt(Regex.Match(fDom[".linkbox > a"].Last().Attr("href").ToString(), @"\d+").Value);
|
||||
|
||||
// Calculate average number of results (based on torrents rows lenght on first page)
|
||||
nbResults = firstPageRows.Count() * pageLinkCount;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
// Check if we have a minimum of one result
|
||||
if (firstPageRows.Length >= 1)
|
||||
{
|
||||
@@ -270,10 +274,7 @@ namespace Jackett.Indexers
|
||||
var pageRequest = buildQuery(searchTerm, query, searchUrl, i);
|
||||
|
||||
// Getting results & Store content
|
||||
WebClientStringResult pageResults = await queryExec(pageRequest);
|
||||
|
||||
// Assign response
|
||||
fDom = pageResults.Content;
|
||||
fDom = await queryExec(pageRequest);
|
||||
|
||||
// Process page results
|
||||
var additionalPageRows = findTorrentRows();
|
||||
@@ -282,20 +283,6 @@ namespace Jackett.Indexers
|
||||
torrentRowList.AddRange(additionalPageRows.Select(fRow => fRow.Cq()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No search term, maybe testing... so registring autkey and torrentpass for future uses
|
||||
string infosData = firstPageRows.First().Find("td:eq(3) > a").Attr("href");
|
||||
IList<string> infosList = infosData.Split('&').Select(s => s.Trim()).Where(s => s != String.Empty).ToList();
|
||||
IList<string> infosTracker = infosList.Select(s => s.Split(new[] { '=' }, 2)[1].Trim()).ToList();
|
||||
|
||||
output("\nStoring Authkey for future uses...");
|
||||
ConfigData.AuthKey.Value = infosTracker[2];
|
||||
|
||||
output("\nStoring TorrentPass for future uses...");
|
||||
ConfigData.TorrentPass.Value = infosTracker[3];
|
||||
|
||||
}
|
||||
|
||||
// Loop on results
|
||||
foreach (CQ tRow in torrentRowList)
|
||||
@@ -307,12 +294,13 @@ namespace Jackett.Indexers
|
||||
output("ID: " + id);
|
||||
|
||||
// Release Name
|
||||
string name = tRow.Find("td:eq(1) > a").Text().ToString();
|
||||
string name = tRow.Find("td:eq(1) > a").Text();
|
||||
output("Release: " + name);
|
||||
|
||||
// Category
|
||||
string categoryID = tRow.Find("td:eq(0) > a").Attr("href").Replace("torrents.php?cat[]=", String.Empty);
|
||||
output("Category: " + MapTrackerCatToNewznab(categoryID) + " (" + categoryID + ")");
|
||||
var newznab = MapTrackerCatToNewznab(categoryID);
|
||||
output("Category: " + MapTrackerCatToNewznab(categoryID).First().ToString() + " (" + categoryID + ")");
|
||||
|
||||
// Seeders
|
||||
int seeders = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(5)").Text(), @"\d+").Value);
|
||||
@@ -345,30 +333,46 @@ namespace Jackett.Indexers
|
||||
output("Comments Link: " + commentsLink.AbsoluteUri);
|
||||
|
||||
// Torrent Download URL
|
||||
Uri downloadLink = new Uri(TorrentDownloadUrl.Replace("{id}", id.ToString()).Replace("{auth_key}", ConfigData.AuthKey.Value).Replace("{torrent_pass}", ConfigData.TorrentPass.Value));
|
||||
output("Download Link: " + downloadLink.AbsoluteUri);
|
||||
Uri downloadLink = null;
|
||||
string link = tRow.Find("td:eq(3) > a").Attr("href");
|
||||
if (!String.IsNullOrEmpty(link))
|
||||
{
|
||||
// Download link available
|
||||
downloadLink = new Uri(SiteLink + link);
|
||||
output("Download Link: " + downloadLink.AbsoluteUri);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No download link available -- Must be on pending ( can't be downloaded now...)
|
||||
output("Download Link: Not available, torrent pending ? Skipping ...");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Freeleech
|
||||
int downloadVolumeFactor = 1;
|
||||
if (tRow.Find("img[alt=\"Freeleech\"]").Length >= 1)
|
||||
{
|
||||
downloadVolumeFactor = 0;
|
||||
output("FreeLeech =)");
|
||||
}
|
||||
|
||||
// Building release infos
|
||||
var release = new ReleaseInfo();
|
||||
release.Category = MapTrackerCatToNewznab(categoryID.ToString());
|
||||
release.Title = name;
|
||||
release.Seeders = seeders;
|
||||
release.Peers = seeders + leechers;
|
||||
release.MinimumRatio = 1;
|
||||
release.MinimumSeedTime = 172800;
|
||||
release.PublishDate = date;
|
||||
release.Size = size;
|
||||
release.Guid = detailsLink;
|
||||
release.Comments = commentsLink;
|
||||
release.Link = downloadLink;
|
||||
|
||||
// freeleech
|
||||
if (tRow.Find("img[alt=\"Freeleech\"]").Length >= 1)
|
||||
release.DownloadVolumeFactor = 0;
|
||||
else
|
||||
release.DownloadVolumeFactor = 1;
|
||||
release.UploadVolumeFactor = 1;
|
||||
|
||||
var release = new ReleaseInfo()
|
||||
{
|
||||
Category = MapTrackerCatToNewznab(categoryID.ToString()),
|
||||
Title = name,
|
||||
Seeders = seeders,
|
||||
Peers = seeders + leechers,
|
||||
MinimumRatio = 1,
|
||||
MinimumSeedTime = 172800,
|
||||
PublishDate = date,
|
||||
Size = size,
|
||||
Guid = detailsLink,
|
||||
Comments = commentsLink,
|
||||
Link = downloadLink,
|
||||
UploadVolumeFactor = 1,
|
||||
DownloadVolumeFactor = downloadVolumeFactor
|
||||
};
|
||||
releases.Add(release);
|
||||
}
|
||||
|
||||
@@ -446,9 +450,9 @@ namespace Jackett.Indexers
|
||||
/// </summary>
|
||||
/// <param name="request">URL created by Query Builder</param>
|
||||
/// <returns>Results from query</returns>
|
||||
private async Task<WebClientStringResult> queryExec(string request)
|
||||
private async Task<String> queryExec(string request)
|
||||
{
|
||||
WebClientStringResult results = null;
|
||||
String results = null;
|
||||
|
||||
// Switch in we are in DEV mode with Hard Drive Cache or not
|
||||
if (DevMode && CacheMode)
|
||||
@@ -469,25 +473,40 @@ namespace Jackett.Indexers
|
||||
/// </summary>
|
||||
/// <param name="request">URL created by Query Builder</param>
|
||||
/// <returns>Results from query</returns>
|
||||
private async Task<WebClientStringResult> queryCache(string request)
|
||||
private async Task<String> queryCache(string request)
|
||||
{
|
||||
WebClientStringResult results = null;
|
||||
String results;
|
||||
|
||||
// Create Directory if not exist
|
||||
System.IO.Directory.CreateDirectory(directory);
|
||||
System.IO.Directory.CreateDirectory(Directory);
|
||||
|
||||
// Clean Storage Provider Directory from outdated cached queries
|
||||
cleanCacheStorage();
|
||||
|
||||
// File Name
|
||||
string fileName = StringUtil.HashSHA1(request) + ".json";
|
||||
|
||||
// Create fingerprint for request
|
||||
string file = directory + request.GetHashCode() + ".json";
|
||||
string file = Path.Combine(Directory, fileName);
|
||||
|
||||
// Checking modes states
|
||||
if (System.IO.File.Exists(file))
|
||||
if (File.Exists(file))
|
||||
{
|
||||
// File exist... loading it right now !
|
||||
output("Loading results from hard drive cache ..." + request.GetHashCode() + ".json");
|
||||
results = JsonConvert.DeserializeObject<WebClientStringResult>(System.IO.File.ReadAllText(file));
|
||||
output("Loading results from hard drive cache ..." + fileName);
|
||||
try
|
||||
{
|
||||
using (StreamReader fileReader = File.OpenText(file))
|
||||
{
|
||||
JsonSerializer serializer = new JsonSerializer();
|
||||
results = (String)serializer.Deserialize(fileReader, typeof(String));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
output("Error loading cached results ! " + e.Message, "error");
|
||||
results = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -495,8 +514,12 @@ namespace Jackett.Indexers
|
||||
results = await queryTracker(request);
|
||||
|
||||
// Cached file didn't exist for our query, writing it right now !
|
||||
output("Writing results to hard drive cache ..." + request.GetHashCode() + ".json");
|
||||
System.IO.File.WriteAllText(file, JsonConvert.SerializeObject(results));
|
||||
output("Writing results to hard drive cache ..." + fileName);
|
||||
using (StreamWriter fileWriter = File.CreateText(file))
|
||||
{
|
||||
JsonSerializer serializer = new JsonSerializer();
|
||||
serializer.Serialize(fileWriter, results);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
@@ -506,7 +529,7 @@ namespace Jackett.Indexers
|
||||
/// </summary>
|
||||
/// <param name="request">URL created by Query Builder</param>
|
||||
/// <returns>Results from query</returns>
|
||||
private async Task<WebClientStringResult> queryTracker(string request)
|
||||
private async Task<String> queryTracker(string request)
|
||||
{
|
||||
WebClientStringResult results = null;
|
||||
|
||||
@@ -518,26 +541,26 @@ namespace Jackett.Indexers
|
||||
results = await RequestStringWithCookiesAndRetry(request, null, null, emulatedBrowserHeaders);
|
||||
|
||||
// Return results from tracker
|
||||
return results;
|
||||
return results.Content;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clean Hard Drive Cache Storage
|
||||
/// </summary>
|
||||
/// <param name="force">Force Provider Folder deletion</param>
|
||||
private void cleanCacheStorage(Boolean force = false)
|
||||
private void cleanCacheStorage(bool force = false)
|
||||
{
|
||||
// Check cleaning method
|
||||
if(force)
|
||||
if (force)
|
||||
{
|
||||
// Deleting Provider Storage folder and all files recursively
|
||||
output("\nDeleting Provider Storage folder and all files recursively ...");
|
||||
|
||||
|
||||
// Check if directory exist
|
||||
if(System.IO.Directory.Exists(directory))
|
||||
if (System.IO.Directory.Exists(Directory))
|
||||
{
|
||||
// Delete storage directory of provider
|
||||
System.IO.Directory.Delete(directory, true);
|
||||
System.IO.Directory.Delete(Directory, true);
|
||||
output("-> Storage folder deleted successfully.");
|
||||
}
|
||||
else
|
||||
@@ -548,24 +571,27 @@ namespace Jackett.Indexers
|
||||
}
|
||||
else
|
||||
{
|
||||
int i = 0;
|
||||
var i = 0;
|
||||
// Check if there is file older than ... and delete them
|
||||
output("\nCleaning Provider Storage folder... in progress.");
|
||||
System.IO.Directory.GetFiles(directory)
|
||||
.Select(f => new System.IO.FileInfo(f))
|
||||
System.IO.Directory.GetFiles(Directory)
|
||||
.Select(f => new FileInfo(f))
|
||||
.Where(f => f.LastAccessTime < DateTime.Now.AddMilliseconds(-Convert.ToInt32(ConfigData.HardDriveCacheKeepTime.Value)))
|
||||
.ToList()
|
||||
.ForEach(f => {
|
||||
.ForEach(f =>
|
||||
{
|
||||
output("Deleting cached file << " + f.Name + " >> ... done.");
|
||||
f.Delete();
|
||||
i++;
|
||||
});
|
||||
});
|
||||
|
||||
// Inform on what was cleaned during process
|
||||
if(i > 0) {
|
||||
if (i > 0)
|
||||
{
|
||||
output("-> Deleted " + i + " cached files during cleaning.");
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
output("-> Nothing deleted during cleaning.");
|
||||
}
|
||||
}
|
||||
@@ -577,7 +603,7 @@ namespace Jackett.Indexers
|
||||
private void latencyNow()
|
||||
{
|
||||
// Need latency ?
|
||||
if(Latency)
|
||||
if (Latency)
|
||||
{
|
||||
// Generate a random value in our range
|
||||
var random = new Random(DateTime.Now.Millisecond);
|
||||
@@ -696,7 +722,7 @@ namespace Jackett.Indexers
|
||||
private void output(string message, string level = "debug")
|
||||
{
|
||||
// Check if we are in dev mode
|
||||
if(DevMode)
|
||||
if (DevMode)
|
||||
{
|
||||
// Output message to console
|
||||
Console.WriteLine(message);
|
||||
|
@@ -18,7 +18,7 @@ using Jackett.Models.IndexerConfig;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
public abstract class AvistazTracker : BaseIndexer
|
||||
public abstract class AvistazTracker : BaseWebIndexer
|
||||
{
|
||||
private string LoginUrl { get { return SiteLink + "auth/login"; } }
|
||||
private string SearchUrl { get { return SiteLink + "torrents?in=1&type={0}&search={1}"; } }
|
||||
@@ -29,12 +29,12 @@ namespace Jackett.Indexers
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public AvistazTracker(IIndexerManagerService indexerManager, IWebClient webClient, Logger logger, IProtectionService protectionService, string name, string desc, string link)
|
||||
public AvistazTracker(IIndexerConfigurationService configService, IWebClient webClient, Logger logger, IProtectionService protectionService, string name, string desc, string link)
|
||||
: base(name: name,
|
||||
description: desc,
|
||||
link: link,
|
||||
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
|
||||
manager: indexerManager,
|
||||
configService: configService,
|
||||
client: webClient,
|
||||
logger: logger,
|
||||
p: protectionService,
|
||||
@@ -51,7 +51,7 @@ namespace Jackett.Indexers
|
||||
AddCategoryMapping(3, TorznabCatType.Audio);
|
||||
}
|
||||
|
||||
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
LoadValuesFromJson(configJson);
|
||||
var loginPage = await RequestStringWithCookies(LoginUrl, string.Empty);
|
||||
@@ -75,7 +75,7 @@ namespace Jackett.Indexers
|
||||
return IndexerConfigurationStatus.RequiresTesting;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
|
||||
|
@@ -17,7 +17,7 @@ using System.Web;
|
||||
|
||||
namespace Jackett.Indexers.Abstract
|
||||
{
|
||||
public abstract class GazelleTracker : BaseIndexer
|
||||
public abstract class GazelleTracker : BaseWebIndexer
|
||||
{
|
||||
protected string LoginUrl { get { return SiteLink + "login.php"; } }
|
||||
protected string APIUrl { get { return SiteLink + "ajax.php"; } }
|
||||
@@ -30,12 +30,12 @@ namespace Jackett.Indexers.Abstract
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public GazelleTracker(IIndexerManagerService indexerManager, IWebClient webClient, Logger logger, IProtectionService protectionService, string name, string desc, string link)
|
||||
public GazelleTracker(IIndexerConfigurationService configService, IWebClient webClient, Logger logger, IProtectionService protectionService, string name, string desc, string link)
|
||||
: base(name: name,
|
||||
description: desc,
|
||||
link: link,
|
||||
caps: new TorznabCapabilities(),
|
||||
manager: indexerManager,
|
||||
configService: configService,
|
||||
client: webClient,
|
||||
logger: logger,
|
||||
p: protectionService,
|
||||
@@ -44,7 +44,7 @@ namespace Jackett.Indexers.Abstract
|
||||
Encoding = Encoding.GetEncoding("UTF-8");
|
||||
}
|
||||
|
||||
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
LoadValuesFromJson(configJson);
|
||||
var pairs = new Dictionary<string, string> {
|
||||
@@ -68,7 +68,7 @@ namespace Jackett.Indexers.Abstract
|
||||
return IndexerConfigurationStatus.RequiresTesting;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
var searchString = query.GetQueryString();
|
||||
@@ -126,9 +126,9 @@ namespace Jackett.Indexers.Abstract
|
||||
if (!string.IsNullOrEmpty(artist))
|
||||
release.Title += artist + " - ";
|
||||
release.Title += groupName;
|
||||
if (!string.IsNullOrEmpty(groupYear))
|
||||
if (!string.IsNullOrEmpty(groupYear) && groupYear != "0")
|
||||
release.Title += " [" + groupYear + "]";
|
||||
if (!string.IsNullOrEmpty(releaseType))
|
||||
if (!string.IsNullOrEmpty(releaseType) && releaseType != "Unknown")
|
||||
release.Title += " [" + releaseType + "]";
|
||||
|
||||
release.Description = "";
|
||||
@@ -180,7 +180,7 @@ namespace Jackett.Indexers.Abstract
|
||||
|
||||
var format = (string)torrent["format"];
|
||||
if (!string.IsNullOrEmpty(format))
|
||||
flags.Add(format);
|
||||
flags.Add(HttpUtility.HtmlDecode(format));
|
||||
|
||||
var encoding = (string)torrent["encoding"];
|
||||
if (!string.IsNullOrEmpty(encoding))
|
||||
@@ -228,7 +228,8 @@ namespace Jackett.Indexers.Abstract
|
||||
{
|
||||
release.DownloadVolumeFactor = 0;
|
||||
}
|
||||
if ((bool)torrent["isPersonalFreeleech"])
|
||||
var isPersonalFreeleech = (bool?)torrent["isPersonalFreeleech"];
|
||||
if (isPersonalFreeleech != null && isPersonalFreeleech == true)
|
||||
{
|
||||
release.DownloadVolumeFactor = 0;
|
||||
}
|
||||
|
@@ -19,19 +19,19 @@ using System.Collections.Specialized;
|
||||
|
||||
namespace Jackett.Indexers
|
||||
{
|
||||
public class AlphaRatio : BaseIndexer, IIndexer
|
||||
public class AlphaRatio : BaseWebIndexer
|
||||
{
|
||||
private string LoginUrl { get { return SiteLink + "login.php"; } }
|
||||
private string SearchUrl { get { return SiteLink + "ajax.php?action=browse&order_by=time&order_way=desc&"; } }
|
||||
private string DownloadUrl { get { return SiteLink + "torrents.php?action=download&id="; } }
|
||||
private string GuidUrl { get { return SiteLink + "torrents.php?torrentid="; } }
|
||||
|
||||
public AlphaRatio(IIndexerManagerService i, IWebClient w, Logger l, IProtectionService ps)
|
||||
public AlphaRatio(IIndexerConfigurationService configService, IWebClient w, Logger l, IProtectionService ps)
|
||||
: base(name: "AlphaRatio",
|
||||
description: "Legendary",
|
||||
link: "https://alpharatio.cc/",
|
||||
caps: new TorznabCapabilities(),
|
||||
manager: i,
|
||||
configService: configService,
|
||||
client: w,
|
||||
logger: l,
|
||||
p: ps,
|
||||
@@ -71,7 +71,7 @@ namespace Jackett.Indexers
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
LoadValuesFromJson(configJson);
|
||||
var pairs = new Dictionary<string, string> {
|
||||
@@ -123,7 +123,7 @@ namespace Jackett.Indexers
|
||||
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
var searchString = query.GetQueryString();
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user