mirror of
https://github.com/Jackett/Jackett.git
synced 2025-09-10 13:48:02 +02:00
Compare commits
392 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e6a2646a98 | ||
![]() |
6dc12f0d3c | ||
![]() |
0846ca40cd | ||
![]() |
dae55ad500 | ||
![]() |
5e361c2087 | ||
![]() |
3d7ecd197b | ||
![]() |
c0524db98d | ||
![]() |
fa8021c048 | ||
![]() |
246a761eb7 | ||
![]() |
28260afdd9 | ||
![]() |
4c42995ebc | ||
![]() |
bdc2843b40 | ||
![]() |
6e61f38644 | ||
![]() |
8ff186d716 | ||
![]() |
c58b9d58a9 | ||
![]() |
1603516666 | ||
![]() |
46e841fc13 | ||
![]() |
d4ff5d3022 | ||
![]() |
935416cf0d | ||
![]() |
7ca75f51e3 | ||
![]() |
9b592259aa | ||
![]() |
281678892d | ||
![]() |
9aace8ae16 | ||
![]() |
adcfade7f2 | ||
![]() |
d0d51a907e | ||
![]() |
0a4e003bde | ||
![]() |
7230507f5a | ||
![]() |
07744ab88f | ||
![]() |
a8f80ca60e | ||
![]() |
3011f22101 | ||
![]() |
f3098bd6d9 | ||
![]() |
b9d3592f3a | ||
![]() |
f299cf3ac3 | ||
![]() |
48118d5691 | ||
![]() |
5d6b71b7a7 | ||
![]() |
e5982b49a2 | ||
![]() |
bb80da9b19 | ||
![]() |
d027901257 | ||
![]() |
8b8629ef19 | ||
![]() |
3cdab54f5c | ||
![]() |
d0342019bc | ||
![]() |
3c61cb6f06 | ||
![]() |
3863008846 | ||
![]() |
22ca2d9552 | ||
![]() |
e6029c41a7 | ||
![]() |
63cf687f02 | ||
![]() |
d30bde715c | ||
![]() |
12b9d6ca7d | ||
![]() |
0933d913dc | ||
![]() |
8aa82a22f4 | ||
![]() |
91817a10ff | ||
![]() |
8f10d27d0f | ||
![]() |
49a7c8df7a | ||
![]() |
34780f91be | ||
![]() |
851a4d30e1 | ||
![]() |
2ab6d13493 | ||
![]() |
fd79b317ea | ||
![]() |
0e0d53fa00 | ||
![]() |
034edbd32a | ||
![]() |
ecc438b21e | ||
![]() |
d2d3dfbe77 | ||
![]() |
addd6ae226 | ||
![]() |
5818548dbf | ||
![]() |
38e039ac34 | ||
![]() |
4c3f45fd8c | ||
![]() |
1b7e8a9edf | ||
![]() |
af4df90832 | ||
![]() |
c99fdfe641 | ||
![]() |
211e80cb17 | ||
![]() |
d687dfc3e1 | ||
![]() |
1ea5b21956 | ||
![]() |
aff3af0214 | ||
![]() |
f9b2875470 | ||
![]() |
606c82921b | ||
![]() |
4463fc0550 | ||
![]() |
2bdb1ee0ff | ||
![]() |
2af27c0a87 | ||
![]() |
db9fb73b4d | ||
![]() |
aee64183fc | ||
![]() |
9cabf72829 | ||
![]() |
ec7a2d049c | ||
![]() |
11ebe34f55 | ||
![]() |
db476951fe | ||
![]() |
a49e0d5667 | ||
![]() |
605c6bcada | ||
![]() |
9c2e5b4219 | ||
![]() |
2e1ce6f202 | ||
![]() |
650435aaef | ||
![]() |
f2248200af | ||
![]() |
6a9777895c | ||
![]() |
47a8c977d9 | ||
![]() |
b138e243ee | ||
![]() |
fbab796e76 | ||
![]() |
8126fc3c85 | ||
![]() |
27a7b2d711 | ||
![]() |
86ecacffcb | ||
![]() |
8b5d3d0170 | ||
![]() |
4c3cb9f295 | ||
![]() |
c9f945a08e | ||
![]() |
46c6bd74a2 | ||
![]() |
61e2add89a | ||
![]() |
24fe395cf0 | ||
![]() |
aab8968a14 | ||
![]() |
de98438102 | ||
![]() |
108213f098 | ||
![]() |
861271ac04 | ||
![]() |
b378f74202 | ||
![]() |
866e1df174 | ||
![]() |
0bb231eeca | ||
![]() |
fb5c82ff85 | ||
![]() |
d9f57b4e13 | ||
![]() |
4676972493 | ||
![]() |
1d3ac34011 | ||
![]() |
634a860f5c | ||
![]() |
eb00665df1 | ||
![]() |
5e77d27021 | ||
![]() |
8fec3ede4e | ||
![]() |
ae6d5ccfc6 | ||
![]() |
e309d96c51 | ||
![]() |
2a3b42f83a | ||
![]() |
4819a3c8ed | ||
![]() |
34d091942a | ||
![]() |
ee2abe6751 | ||
![]() |
27f0448caf | ||
![]() |
6493037251 | ||
![]() |
0cd11e1882 | ||
![]() |
cfdafa01c9 | ||
![]() |
e3852bcb1b | ||
![]() |
e33e95c1b2 | ||
![]() |
3d0e777d22 | ||
![]() |
aeb3d49c06 | ||
![]() |
c2cf5adeb2 | ||
![]() |
40ab7280ca | ||
![]() |
0c37a191fd | ||
![]() |
19547bc58f | ||
![]() |
bcbe18214b | ||
![]() |
eb60a6854c | ||
![]() |
11406697be | ||
![]() |
b2b576a72d | ||
![]() |
e537e4976e | ||
![]() |
490254d16b | ||
![]() |
a5cc7d973f | ||
![]() |
3e000453a5 | ||
![]() |
8f090fabef | ||
![]() |
91eb4c37cb | ||
![]() |
da43f17558 | ||
![]() |
3b3c3b0947 | ||
![]() |
06e386c253 | ||
![]() |
a2ae2d3384 | ||
![]() |
3532a73d59 | ||
![]() |
b7daffea87 | ||
![]() |
e7b9f8c5ec | ||
![]() |
9ada58a6e3 | ||
![]() |
c8d974cf52 | ||
![]() |
c544de8fed | ||
![]() |
93ec102a86 | ||
![]() |
92bda2b09b | ||
![]() |
1cd0358531 | ||
![]() |
222fec2fd0 | ||
![]() |
3790cbb894 | ||
![]() |
05d5798046 | ||
![]() |
9e9deb17c7 | ||
![]() |
2aedc4f335 | ||
![]() |
dfa708e355 | ||
![]() |
6d1997ef96 | ||
![]() |
db479d8de8 | ||
![]() |
741e6407ce | ||
![]() |
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 |
136
README.md
136
README.md
@@ -1,14 +1,16 @@
|
||||
# Jackett
|
||||
# Jackett
|
||||
|
||||
[](https://github.com/Jackett/Jackett/issues)
|
||||
[](https://github.com/Jackett/Jackett/pulls)
|
||||
[](https://ci.appveyor.com/project/camjac251/jackett)
|
||||
[](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.
|
||||
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), [DuckieTV](https://github.com/SchizoDuckie/DuckieTV), 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.
|
||||
|
||||
@@ -16,33 +18,63 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
|
||||
#### Supported Systems
|
||||
* Windows using .NET 4.5
|
||||
* Linux and OSX using Mono 4 (mono 3 is no longer supported).
|
||||
* Linux and macOS using Mono 4 (mono 3 is no longer supported).
|
||||
|
||||
### Supported Public Trackers
|
||||
* 1337x
|
||||
* Anidex
|
||||
* Anime Tosho
|
||||
* AniRena
|
||||
* btbit
|
||||
* BTDB
|
||||
* cpasbien
|
||||
* EZTV
|
||||
* GkTorrent
|
||||
* Horrible Subs
|
||||
* Idope
|
||||
* Il Corsaro Nero <!-- maintained by bonny1992 -->
|
||||
* Isohunt
|
||||
* KickAssTorrent
|
||||
* KickAssTorrent (kat.how clone)
|
||||
* KickAssTorrent (thekat.se clone)
|
||||
* LimeTorrents
|
||||
* MagnetDL
|
||||
* 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
|
||||
* World Wide Torrents
|
||||
* YTS.ag
|
||||
* Zooqle
|
||||
|
||||
### Supported Semi-Private Trackers
|
||||
* 7tor
|
||||
* CzTorrent
|
||||
* Deildu
|
||||
* Gay-Torrents.net
|
||||
* LostFilm.tv
|
||||
* Metal Tracker
|
||||
* NetHD
|
||||
* RuTracker
|
||||
* SkTorrent
|
||||
* TorrentBytes
|
||||
* Xtreme Zone
|
||||
* YggTorrent
|
||||
* Ztracker
|
||||
|
||||
### Supported Private Trackers
|
||||
* 2 Fast 4 You
|
||||
* 3D Torrents
|
||||
* 7tor
|
||||
* Abnormal
|
||||
* Acid-Lounge
|
||||
* AlphaRatio
|
||||
@@ -54,12 +86,14 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* ArabaFenice
|
||||
* Arche Torrent
|
||||
* AsianDVDClub
|
||||
* AST4u
|
||||
* Audiobook Torrents
|
||||
* Awesome-HD
|
||||
* Avistaz
|
||||
* B2S-Share
|
||||
* Back-ups
|
||||
* BakaBT [![(invite needed)][inviteneeded]](#)
|
||||
* bB
|
||||
* Best Friends
|
||||
* BeyondHD
|
||||
* BIGTorrent
|
||||
* Bit-City Reloaded
|
||||
@@ -69,12 +103,15 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* BitMeTV
|
||||
* BitSoup [![(invite needed)][inviteneeded]](#)
|
||||
* Bitspyder
|
||||
* BJ-Share
|
||||
* Blu-bits
|
||||
* BlueBird
|
||||
* BroadcastTheNet [![(invite needed)][inviteneeded]](#)
|
||||
* Blutopia
|
||||
* BroadcastTheNet
|
||||
* BrokenStones
|
||||
* BTNext
|
||||
* Carpathians
|
||||
* CGPeers
|
||||
* CHDBits
|
||||
* Cinematik
|
||||
* Cinemageddon
|
||||
@@ -83,13 +120,13 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* CZTeam
|
||||
* DanishBits
|
||||
* DataScene
|
||||
* Deildu
|
||||
* Demonoid
|
||||
* Diablo Torrent
|
||||
* DigitalHive
|
||||
* Dragon World (DTW)
|
||||
* Dragonworld Reloaded
|
||||
* Dream Team
|
||||
* EliteHD [![(invite needed)][inviteneeded]](#)
|
||||
* Elite-Tracker
|
||||
* EoT-Forum
|
||||
* eStone
|
||||
* Ethor.net (Thor's Land)
|
||||
@@ -100,23 +137,26 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* FunFile
|
||||
* FunkyTorrents
|
||||
* Fuzer
|
||||
* GayTorrent.ru
|
||||
* GFTracker
|
||||
* GFXPeers
|
||||
* Ghost City
|
||||
* GigaTorrents [![(invite needed)][inviteneeded]](#)
|
||||
* GigaTorrents
|
||||
* 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
|
||||
@@ -134,23 +174,20 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* JPopsuki
|
||||
* Kapaki
|
||||
* Karagarga
|
||||
* Le Paradis Du Net
|
||||
* LinkoManija
|
||||
* LosslessClub
|
||||
* M-Team - TP
|
||||
* Magico
|
||||
* Majomparádé
|
||||
* Majomparádé
|
||||
* Manicomio Share
|
||||
* Mononoké-BT
|
||||
* MoreThanTV
|
||||
* MyAnonamouse
|
||||
* myAmity
|
||||
* MySpleen
|
||||
* Nachtwerk
|
||||
* NCore
|
||||
* Nebulance
|
||||
* NetHD
|
||||
* New Real World
|
||||
* NextGen
|
||||
* Norbits [![(invite needed)][inviteneeded]](#) <!-- added by DiseaseNO but no longer maintained? -->
|
||||
* notwhat.cd
|
||||
* Ourbits
|
||||
@@ -164,13 +201,10 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* PrivateHD
|
||||
* Psytorrents
|
||||
* PTFiles
|
||||
* QcTorrent
|
||||
* Redacted (PassTheHeadphones)
|
||||
* RevolutionTT
|
||||
* Rockhard Lossless
|
||||
* RoDVD
|
||||
* RuTracker
|
||||
* SceneAccess
|
||||
* SceneFZ
|
||||
* SceneTime
|
||||
* SDBits
|
||||
@@ -180,9 +214,11 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* Shazbat
|
||||
* Shellife
|
||||
* SpeedCD
|
||||
* SpeedTorrent Reloaded
|
||||
* SportsCult
|
||||
* SportHD
|
||||
* Superbits
|
||||
* Synthesiz3r
|
||||
* Tasmanit
|
||||
* The Empire
|
||||
* The Geeks
|
||||
@@ -198,18 +234,18 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* TenYardTracker
|
||||
* Torrent Network
|
||||
* Torrent Sector Crew
|
||||
* Torrent411
|
||||
* Torrent9
|
||||
* TorrentBD
|
||||
* TorrentBytes
|
||||
* TorrentCCF [![(invite needed)][inviteneeded]](#)
|
||||
* TorrentDay
|
||||
* Torrentech
|
||||
* TorrentHeaven
|
||||
* TorrentHR
|
||||
* Torrenting
|
||||
* TorrentLeech
|
||||
* Torrents.Md
|
||||
* TorrentVault
|
||||
* Torrent-Syndikat
|
||||
* TorViet
|
||||
* ToTheGlory
|
||||
* TranceTraffic
|
||||
* Trezzor
|
||||
@@ -220,16 +256,16 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* Ultimate Gamer Club
|
||||
* ULTRAHDCLUB
|
||||
* Waffles
|
||||
* World-In-HD [![(invite needed)][inviteneeded]](#)
|
||||
* World-In-HD
|
||||
* WorldOfP2P
|
||||
* x264
|
||||
* XSpeeds
|
||||
* Xthor
|
||||
* Xtreme Zone
|
||||
* Ztracker
|
||||
* 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.
|
||||
@@ -245,7 +281,7 @@ To get started with using the installer for Jackett, follow the steps below:
|
||||
|
||||
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".
|
||||
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)
|
||||
@@ -259,20 +295,30 @@ Jackett can also be run from the command line if you would like to see log messa
|
||||
|
||||
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 OSX
|
||||
1. Install [Mono 4](http://www.mono-project.com/download/#download-mac) or better (version 4.8 is recommended)
|
||||
* Setup ssl support by running
|
||||
```
|
||||
https://curl.haxx.se/ca/cacert.pem
|
||||
cert-sync --user ~/Downloads/cacert.pem
|
||||
```
|
||||
1. 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`.
|
||||
If you want to run it with a user without a /home directory you need to add `Environment=XDG_CONFIG_HOME=/path/to/folder` to your systemd file, this folder will be used to store your config files.
|
||||
|
||||
## 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. Open the extracted folder and double-click on `install_service_macos`.
|
||||
3. If the installation was a success, you can close the Terminal window.
|
||||
|
||||
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 [SynoCommuniy](https://synocommunity.com/)
|
||||
Jackett is available as beta package from [SynoCommunity](https://synocommunity.com/)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
@@ -280,20 +326,18 @@ Jackett is available as beta package from [SynoCommuniy](https://synocommunity.c
|
||||
|
||||
You can pass various options when running via the command line, see --help for details.
|
||||
|
||||
* __Unable to connect to trackers with invalid SSL certificates__
|
||||
* __Error "The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel."__
|
||||
|
||||
If you're using mono this is often caused by missing ca-certificates.
|
||||
This is often caused by missing CA certificates.
|
||||
Try reimporting the certificates in this case:
|
||||
|
||||
`wget -O - https://curl.haxx.se/ca/cacert.pem | cert-sync /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.
|
||||
- On Linux (as user root): `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`
|
||||
|
||||
* __Enable logging__
|
||||
|
||||
You can get additional logging with the command line switches `-t -l` or by enabeling `Enhanced logging` via the web interface.
|
||||
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/OSX.
|
||||
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.
|
||||
|
@@ -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">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CurlSharp\CurlSharp.csproj">
|
||||
@@ -182,4 +185,4 @@
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
||||
|
76
src/Jackett.Console/install_service_macos
Executable file
76
src/Jackett.Console/install_service_macos
Executable file
@@ -0,0 +1,76 @@
|
||||
#!/bin/bash
|
||||
|
||||
#Setting up colors
|
||||
BOLDRED="$(printf '\033[1;31m')"
|
||||
BOLDGREEN="$(printf '\033[1;32m')"
|
||||
NC="$(printf '\033[0m')" # No Color
|
||||
|
||||
# Stop and unload the service if it's running
|
||||
launchctl remove org.user.Jackett
|
||||
|
||||
# Move working directory to Jackett's
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
# Check if we're running from Jackett's directory
|
||||
if [ ! -f ./JackettConsole.exe ]; then
|
||||
echo "${BOLDRED}ERROR${NC}: Couldn't locate JackettConsole.exe. Is the script in the right directory?"
|
||||
exit 1
|
||||
fi
|
||||
jackettdir="$(pwd)"
|
||||
|
||||
# Check if mono is installed
|
||||
command -v mono >/dev/null 2>&1 || { echo >&2 "${BOLDRED}ERROR${NC}: 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 "${BOLDRED}ERROR${NC}: 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 "${BOLDGREEN}Agent successfully installed and launched!${NC}"
|
||||
else
|
||||
cat << EOL
|
||||
${BOLDRED}ERROR${NC}: 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,16 +48,6 @@ namespace JackettTest
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void InitCardigannIndexers(string path)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SortIndexers()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
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,7 +185,17 @@ 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",
|
||||
"Definitions/hdclub.yml",
|
||||
"Definitions/polishtracker.yml",
|
||||
"Definitions/zetorrents.yml",
|
||||
"Definitions/rapidetracker.yml",
|
||||
"Definitions/isohunt.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}
|
File diff suppressed because it is too large
Load Diff
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
@@ -1,120 +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;
|
||||
case "inputselect":
|
||||
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 = serverService.GetServerUrl(Request);
|
||||
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)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
422
src/Jackett/Controllers/ResultsController.cs
Normal file
422
src/Jackett/Controllers/ResultsController.cs
Normal file
@@ -0,0 +1,422 @@
|
||||
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);
|
||||
|
||||
if (actionExecutedContext.Exception != null)
|
||||
throw new Exception("Error while executing request", actionExecutedContext.Exception);
|
||||
|
||||
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 = serverService.GetServerUrl(Request);
|
||||
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 = serverService.GetServerUrl(Request);
|
||||
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 = serverService.GetServerUrl(Request);
|
||||
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,180 +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.Where(r => r.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;
|
||||
}
|
||||
}
|
182
src/Jackett/Definitions/1337x.yml
Normal file
182
src/Jackett/Definitions/1337x.yml
Normal file
@@ -0,0 +1,182 @@
|
||||
---
|
||||
site: 1337x
|
||||
name: 1337x
|
||||
description: "1337X is a Public torrent site that offers verified torrent downloads"
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://1337x.to
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
#Audio
|
||||
- {id: 22, cat: Audio/MP3, desc: "Music/MP3"}
|
||||
- {id: 23, cat: Audio/Lossless, desc: "Music/Lossless"}
|
||||
- {id: 24, cat: Audio, desc: "Music/DVD"}
|
||||
- {id: 25, cat: Audio/Video, desc: "Music/Video"}
|
||||
- {id: 26, cat: Audio, desc: "Music/Radio"}
|
||||
- {id: 27, cat: Audio/Other, desc: "Music/Other"}
|
||||
- {id: 52, cat: Audio/Audiobook, desc: "Other/Audiobook"}
|
||||
- {id: 53, cat: Audio, desc: "Music/Album"}
|
||||
- {id: 58, cat: Audio, desc: "Music/Box set"}
|
||||
- {id: 59, cat: Audio, desc: "Music/Discography"}
|
||||
- {id: 60, cat: Audio, desc: "Music/Single"}
|
||||
- {id: 68, cat: Audio, desc: "Music/Concerts"}
|
||||
- {id: 69, cat: Audio, desc: "Music/AAC"}
|
||||
|
||||
#Movies
|
||||
- {id: 1, cat: Movies/DVD, desc: "Movies/DVD"}
|
||||
- {id: 2, cat: Movies/SD, desc: "Movies/Divx/Xvid"}
|
||||
- {id: 3, cat: Movies, desc: "Movies/SVCD/VCD"}
|
||||
- {id: 4, cat: Movies/Foreign, desc: "Movies/Dubs/Dual Audio"}
|
||||
- {id: 9, cat: Movies, desc: "Documentaries/Documentary"}
|
||||
- {id: 42, cat: Movies/HD, desc: "Movies/HD"}
|
||||
- {id: 54, cat: Movies, desc: "Movies/h.264/x264"}
|
||||
- {id: 55, cat: Movies, desc: "Movies/Mp4"}
|
||||
- {id: 66, cat: Movies/3D, desc: "Movies/3D"}
|
||||
- {id: 70, cat: Movies, desc: "Movies/HEVC/x265"}
|
||||
- {id: 73, cat: Movies, desc: "Movies/Bollywood"}
|
||||
|
||||
#TV
|
||||
- {id: 5, cat: TV, desc: "TV/DVD"}
|
||||
- {id: 6, cat: TV/SD, desc: "TV/Divx/Xvid"}
|
||||
- {id: 7, cat: TV, desc: "TV/SVCD/VCD"}
|
||||
- {id: 28, cat: TV/Anime, desc: "Anime/Anime"}
|
||||
- {id: 41, cat: TV/HD, desc: "TV/HD"}
|
||||
- {id: 71, cat: TV, desc: "TV/HEVC/x265"}
|
||||
|
||||
#Apps
|
||||
- {id: 18, cat: PC, desc: "Apps/PC Software"}
|
||||
- {id: 19, cat: PC/Mac, desc: "Apps/Mac"}
|
||||
- {id: 20, cat: PC, desc: "Apps/Linux"}
|
||||
- {id: 21, cat: PC, desc: "Apps/Other"}
|
||||
- {id: 56, cat: PC/Phone-Android, desc: "Apps/Android"}
|
||||
- {id: 57, cat: PC/Phone-IOS, desc: "Apps/iOS"}
|
||||
|
||||
#Games
|
||||
- {id: 10, cat: PC/Games, desc: "Games/PC Game"}
|
||||
- {id: 11, cat: Console, desc: "Games/PS2"}
|
||||
- {id: 12, cat: Console/PSP, desc: "Games/PSP"}
|
||||
- {id: 13, cat: Console/Xbox, desc: "Games/Xbox"}
|
||||
- {id: 14, cat: Console/Xbox 360, desc: "Games/Xbox360"}
|
||||
- {id: 15, cat: Console, desc: "Games/PS1"}
|
||||
- {id: 16, cat: Console/Other, desc: "Games/Dreamcast"}
|
||||
- {id: 17, cat: PC/Phone-Other, desc: "Games/Other"}
|
||||
- {id: 43, cat: Console/PS3, desc: "Games/PS3"}
|
||||
- {id: 44, cat: Console/Wii, desc: "Games/Wii"}
|
||||
- {id: 45, cat: Console/NDS, desc: "Games/DS"}
|
||||
- {id: 46, cat: Console, desc: "Games/GameCube"}
|
||||
- {id: 72, cat: Console/3DS, desc: "Games/3DS"}
|
||||
|
||||
#XXX
|
||||
- {id: 48, cat: XXX/DVD, desc: "XXX/Video"}
|
||||
- {id: 49, cat: XXX/Imageset, desc: "XXX/Picture"}
|
||||
- {id: 50, cat: XXX, desc: "XXX/Magazine"}
|
||||
- {id: 51, cat: XXX, desc: "XXX/Hentai"}
|
||||
- {id: 67, cat: XXX, desc: "XXX/Games"}
|
||||
|
||||
#Other
|
||||
- {id: 33, cat: Other, desc: "Other/Emulation"}
|
||||
- {id: 34, cat: Books, desc: "Other/Tutorial"}
|
||||
- {id: 35, cat: Other, desc: "Other/Sounds"}
|
||||
- {id: 36, cat: Books/Ebook, desc: "Other/E-books"}
|
||||
- {id: 37, cat: Other, desc: "Other/Images"}
|
||||
- {id: 38, cat: Other, desc: "Other/Mobile Phone"}
|
||||
- {id: 39, cat: Books/Comics, desc: "Other/Comics"}
|
||||
- {id: 40, cat: Other/Misc, desc: "Other/Other"}
|
||||
- {id: 47, cat: Other, desc: "Other/Nulled Script"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
settings: []
|
||||
|
||||
download:
|
||||
# the .torrent url is on the on the details page
|
||||
selector: ul li a[href^="http://itorrents.org/"]
|
||||
|
||||
# it appears that Jackett Definitions do not currently support fetching magnets from the details page :-(
|
||||
# magnet:
|
||||
# the magnet url is on the on the details page
|
||||
# selector: ul li a[href^="magnet:?"]
|
||||
|
||||
search:
|
||||
# present trending results if there are no search parms supplied
|
||||
path: "{{if .Keywords}}/search/{{ .Keywords}}/1/{{else}}/trending{{end}}"
|
||||
rows:
|
||||
selector: tr:has(a[href^="/torrent/"])
|
||||
fields:
|
||||
title:
|
||||
selector: td[class^="coll-1"] a[href^="/torrent/"]
|
||||
category:
|
||||
optional: true
|
||||
selector: td[class^="coll-1"] a[href^="/sub/"]
|
||||
attribute: href
|
||||
filters:
|
||||
# extract the third part
|
||||
- name: split
|
||||
args: ["/", 2]
|
||||
details:
|
||||
selector: td[class^="coll-1"] a[href^="/torrent/"]
|
||||
attribute: href
|
||||
download:
|
||||
# .torrent link is on the details page
|
||||
selector: td[class^="coll-1"] a[href^="/torrent/"]
|
||||
attribute: href
|
||||
# magnet:
|
||||
# magnet URI is on the details page
|
||||
# selector: td[class^="coll-1"] a[href^="/torrent/"]
|
||||
# attribute: href
|
||||
# dates come in three flavours:
|
||||
date:
|
||||
# (within this year) 7am Sep. 14th
|
||||
optional: true
|
||||
selector: td[class^="coll-date"]:not(:contains(":")):not(:contains("'"))
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["st", ""]
|
||||
- name: replace
|
||||
args: ["nd", ""]
|
||||
- name: replace
|
||||
args: ["rd", ""]
|
||||
- name: replace
|
||||
args: ["th", ""]
|
||||
- name: dateparse
|
||||
args: "3pm Jan. 2"
|
||||
date:
|
||||
# (more than a year ago) Apr. 18th '11
|
||||
optional: true
|
||||
selector: td[class^="coll-date"]:contains("'")
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["'", ""]
|
||||
- name: replace
|
||||
args: ["st", ""]
|
||||
- name: replace
|
||||
args: ["nd", ""]
|
||||
- name: replace
|
||||
args: ["rd", ""]
|
||||
- name: replace
|
||||
args: ["th", ""]
|
||||
- name: dateparse
|
||||
args: "Jan. 2 06"
|
||||
date:
|
||||
# # (today) 12:25am
|
||||
optional: true
|
||||
selector: td[class^="coll-date"]:contains(":")
|
||||
filters:
|
||||
- name: dateparse
|
||||
args: "3:04pm"
|
||||
size:
|
||||
selector: td[class^="coll-4"]
|
||||
seeders:
|
||||
selector: td[class^="coll-2"]
|
||||
leechers:
|
||||
selector: td[class^="coll-3"]
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: 2fast4you
|
||||
name: 2 Fast 4 You
|
||||
description: "2 Fast 4 You is a FRENCH Private site for TV / MOVIES / GENERAL"
|
||||
language: fr-fr
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
@@ -112,6 +113,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
|
||||
@@ -136,4 +140,4 @@
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
||||
"*": "1"
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: acidlounge
|
||||
name: Acid-Lounge
|
||||
description: "Acid Lounge (A-L) is a Private Torrent Tracker for 0DAY / GENERAL"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
|
@@ -1,7 +1,7 @@
|
||||
---
|
||||
---
|
||||
site: anidex
|
||||
name: Anidex
|
||||
description: "Anidex is a torrent tracker and indexer, primarily for English fansub groups of anime"
|
||||
description: "Anidex is a Public torrent tracker and indexer, primarily for English fansub groups of anime"
|
||||
language: en-us
|
||||
encoding: UTF-8
|
||||
type: public
|
||||
@@ -9,8 +9,23 @@
|
||||
- https://anidex.info/
|
||||
|
||||
caps:
|
||||
categories:
|
||||
1: TV/Anime # Anime
|
||||
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]
|
||||
@@ -19,24 +34,22 @@
|
||||
- name: cat-id
|
||||
type: text
|
||||
label: Category Id
|
||||
- name: lang-id
|
||||
type: text
|
||||
label: Language Id
|
||||
- name: info
|
||||
type: info
|
||||
label: Category Id Note
|
||||
default: "You can filter your searches by using any of the following category numbers (comma delimited):<br>1 :Anime - Sub<br>2 :Anime - Raw<br>3 :Anime - Dub<br>4 :LA - Sub<br>5 :LA - Raw<br>6 :Light Novel<br>7 :Manga - TLed<br>8 :Manga - Raw<br>9 :♫ - Lossy<br>10 :♫ - Lossless<br>11 :♫ - Video<br>12 :Games<br>13 :Applications<br>14 :Pictures<br>15 :Adult Video<br>16 :Other"
|
||||
|
||||
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 }}"
|
||||
path: "?{{if .Config.cat-id}}id={{.Config.cat-id }}&{{else}}{{end}}q={{if .Keywords}}{{.Keywords}}{{else}}{{end}}"
|
||||
rows:
|
||||
selector: div.table-responsive > table > tbody > tr
|
||||
fields:
|
||||
category:
|
||||
text: "1"
|
||||
selector: a[href^="/?id="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: id
|
||||
title:
|
||||
selector: td:nth-child(3) > a.torrent > span.span-1440
|
||||
details:
|
||||
@@ -45,6 +58,9 @@
|
||||
download:
|
||||
selector: td:nth-child(5) > a
|
||||
attribute: href
|
||||
magnet:
|
||||
selector: a[href^="magnet:?"]
|
||||
attribute: href
|
||||
size:
|
||||
selector: td:nth-child(7)
|
||||
date:
|
||||
@@ -59,3 +75,9 @@
|
||||
selector: td:nth-child(9)
|
||||
leechers:
|
||||
selector: td:nth-child(10)
|
||||
grabs:
|
||||
selector: td:nth-child(11)
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: aniRena
|
||||
name: AniRena
|
||||
description: "AniRena is a Public torrent tracker for the latest anime and Japanese related torrents"
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
@@ -12,34 +13,41 @@
|
||||
caps:
|
||||
categorymappings:
|
||||
# Anime
|
||||
- {id: 1, cat: TV/Anime, desc: "Raw Animes"}
|
||||
- {id: 2, cat: TV/Anime, desc: "Anime"}
|
||||
- {id: 3, cat: TV/Anime, desc: "Hentai"}
|
||||
- {id: 4, cat: TV/Anime, desc: "Drama"}
|
||||
- {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"}
|
||||
- {id: 6, cat: PC, desc: "Hentai-Game"}
|
||||
# Literature
|
||||
- {id: 7, cat: Books, desc: "Manga"}
|
||||
# Audio
|
||||
- {id: 8, cat: Audio, desc: "Audio"}
|
||||
# Other
|
||||
- {id: 11, cat: Other, desc: "Other"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
|
||||
search:
|
||||
path: "/"
|
||||
inputs:
|
||||
s: "{{ .Query.Keywords }}"
|
||||
path: "/{{if .Keywords}}?s={{ .Keywords}}{{else}}{{end}}"
|
||||
rows:
|
||||
selector: table tbody tr
|
||||
selector: table tbody tr:has(td.torrents_small_type_data1)
|
||||
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
|
||||
date:
|
||||
text: now
|
||||
size:
|
||||
selector: .torrents_small_size_data1
|
||||
seeders:
|
||||
@@ -48,3 +56,22 @@
|
||||
selector: .torrents_small_leechers_data1 b big
|
||||
grabs:
|
||||
selector: .torrents_small_downloads_data1
|
||||
category:
|
||||
selector: .torrents_small_type_data1 img
|
||||
attribute: src
|
||||
case:
|
||||
"[src=\"./styles/tracker/imageset/cat_raw_small.png\"]": "1"
|
||||
"[src=\"./styles/tracker/imageset/cat_anime_small.png\"]": "2"
|
||||
"[src=\"./styles/tracker/imageset/cat_hentai_small.png\"]": "3"
|
||||
"[src=\"./styles/tracker/imageset/cat_drama_small.png\"]": "4"
|
||||
"[src=\"./styles/tracker/imageset/cat_dvd_small.png\"]": "5"
|
||||
"[src=\"./styles/tracker/imageset/cat_hgame2_small.png\"]": "6"
|
||||
"[src=\"./styles/tracker/imageset/cat_manga_small.png\"]": "7"
|
||||
"[src=\"./styles/tracker/imageset/cat_music_small.png\"]": "8"
|
||||
"[src=\"./styles/tracker/imageset/cat_musicvid_small.png\"]": "9"
|
||||
"[src=\"./styles/tracker/imageset/cat_noneng_small.png\"]": "10"
|
||||
"[src=\"./styles/tracker/imageset/cat_other_small.png\"]": "11"
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: aox
|
||||
name: AOX
|
||||
description: "AOX (Chippu) is a Private Torrent Tracker for ASIAN MOVIES / TV"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
@@ -121,4 +122,4 @@
|
||||
- name: prepend
|
||||
args: "<br>Language: "
|
||||
|
||||
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: arabafenice
|
||||
name: ArabaFenice
|
||||
description: "Araba Fenice (Phoenix) is an ITALIAN Private site for TV / MOVIES / GENERAL"
|
||||
language: it-it
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
|
135
src/Jackett/Definitions/archetorrent.yml
Normal file
135
src/Jackett/Definitions/archetorrent.yml
Normal file
@@ -0,0 +1,135 @@
|
||||
---
|
||||
site: archetorrent
|
||||
name: ArcheTorrent
|
||||
description: "ArcheTorrent is a FRENCH Private Torrent Tracker"
|
||||
language: fr-fr
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://archetorrent.com
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 18, cat: PC, desc: "Applications: PC"}
|
||||
- {id: 19, cat: PC/Mac, desc: "Applications: Mac"}
|
||||
- {id: 54, cat: PC, desc: "Applications: linux"}
|
||||
- {id: 56, cat: XXX/Other, desc: "Autres: ebook xxx"}
|
||||
- {id: 36, cat: Books, desc: "Autres: E-Books"}
|
||||
- {id: 37, cat: Other, desc: "Autres: Images"}
|
||||
- {id: 38, cat: PC/Phone-Other, desc: "Autres: Telephone-mobile"}
|
||||
- {id: 47, cat: Movies, desc: "Films: Animé"}
|
||||
- {id: 1, cat: Movies/DVD, desc: "Films: DVD"}
|
||||
- {id: 2, cat: Movies/SD, desc: "Films: Dvdrip"}
|
||||
- {id: 68, cat: Movies, desc: "Films: TAT Releases"}
|
||||
- {id: 70, cat: Movies/HD, desc: "Films: UHD 4K"}
|
||||
- {id: 69, cat: Movies, desc: "Films: Retro"}
|
||||
- {id: 3, cat: Movies/HD, desc: "Films: HD1080"}
|
||||
- {id: 42, cat: Movies/HD, desc: "Films: HD720"}
|
||||
- {id: 4, cat: Movies, desc: "Films: Cam/Ts"}
|
||||
- {id: 22, cat: Movies/BluRay, desc: "Films: bluray"}
|
||||
- {id: 23, cat: Movies/3D, desc: "Films: 3D"}
|
||||
- {id: 24, cat: Movies/Foreign, desc: "Films: VOSTFR"}
|
||||
- {id: 25, cat: XXX, desc: "Films: Adulte"}
|
||||
- {id: 48, cat: TV/Documentary, desc: "Films: Documentaire"}
|
||||
- {id: 49, cat: Movies/Other, desc: "Films: Spectacle"}
|
||||
- {id: 51, cat: Movies/SD, desc: "Films: R5"}
|
||||
- {id: 52, cat: Movies/SD, desc: "Films: bdrip"}
|
||||
- {id: 53, cat: Movies/SD, desc: "Films: brrip"}
|
||||
- {id: 55, cat: Movies/DVD, desc: "Films: dvd-pack"}
|
||||
- {id: 57, cat: Movies, desc: "Films: manga"}
|
||||
- {id: 59, cat: Movies/WEBDL, desc: "Films: Webrip"}
|
||||
- {id: 63, cat: Movies/SD, desc: "Films: M-HD"}
|
||||
- {id: 10, cat: PC/Games, desc: "Jeux: PC"}
|
||||
- {id: 11, cat: Console/Other, desc: "Jeux: PS2"}
|
||||
- {id: 43, cat: Console/PS3, desc: "Jeux: PS3"}
|
||||
- {id: 12, cat: Console/PSP, desc: "Jeux: PSP"}
|
||||
- {id: 14, cat: Console/Xbox 360, desc: "Jeux: Xbox360"}
|
||||
- {id: 44, cat: Console/Wii, desc: "Jeux: Wii"}
|
||||
- {id: 45, cat: Console/NDS, desc: "Jeux: DS"}
|
||||
- {id: 27, cat: Audio/Video, desc: "Musique: Clip Video"}
|
||||
- {id: 62, cat: TV/SD, desc: "Serie tv: TV BDRip"}
|
||||
- {id: 5, cat: TV/SD, desc: "Serie tv: Dvdrip"}
|
||||
- {id: 41, cat: TV/HD, desc: "Serie tv: Hd"}
|
||||
- {id: 60, cat: TV/SD, desc: "Serie tv: pack série tv"}
|
||||
- {id: 64, cat: TV/FOREIGN, desc: "Serie tv: vostfr"}
|
||||
- {id: 65, cat: TV/HD, desc: "Serie tv: Série tv 720P"}
|
||||
- {id: 66, cat: TV/HD, desc: "Serie tv: Série tv 1080P"}
|
||||
- {id: 67, cat: TV/HD, desc: "Serie tv: Série tv PackHD"}
|
||||
- {id: 73, cat: TV/Anime, desc: "Serie tv: Anime "}
|
||||
- {id: 72, cat: TV/Sport, desc: "Sport: sport"}
|
||||
- {id: 61, cat: TV/SD, desc: "Tv: DVDRip"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
login:
|
||||
path: account-login.php
|
||||
method: post
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
error:
|
||||
- selector: form:contains("Erreur")
|
||||
message:
|
||||
selector: form
|
||||
remove: table
|
||||
test:
|
||||
path: torrents-search.php
|
||||
|
||||
search:
|
||||
path: torrents-search.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
incldead: "1"
|
||||
|
||||
rows:
|
||||
selector: table.ttable_headinner > tbody > tr[class^="t-row"]
|
||||
fields:
|
||||
download:
|
||||
selector: a[href^="torrents-details.php?id="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["torrents-details.php", "download.php"]
|
||||
date:
|
||||
selector: td:nth-child(2) a
|
||||
attribute: onmouseover
|
||||
filters:
|
||||
- name: regexp
|
||||
args: "Poster le: </b>(.*?)<br />"
|
||||
- name: dateparse
|
||||
args: "02-01-2006"
|
||||
title:
|
||||
selector: a[href^="torrents-details.php?id="]
|
||||
filters:
|
||||
- name: replace
|
||||
args: [" - (Nouveau!)", ""]
|
||||
category:
|
||||
selector: a[href^="torrents.php?cat="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
details:
|
||||
selector: a[href^="torrents-details.php?id="]
|
||||
attribute: href
|
||||
banner:
|
||||
selector: img.rounded-img
|
||||
attribute: src
|
||||
size:
|
||||
selector: td:nth-child(5)
|
||||
grabs:
|
||||
selector: td:nth-child(8) font b
|
||||
seeders:
|
||||
selector: td:nth-child(6) font b
|
||||
leechers:
|
||||
selector: td:nth-child(7) font b
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
img[title="freeleech"]: "0"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: asiandvdclub
|
||||
name: AsianDVDClub
|
||||
description: "AsianDVDClub is an ASIAN Private Torrent Tracker for HD MOVIES / TV"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
|
110
src/Jackett/Definitions/ast4u.yml
Normal file
110
src/Jackett/Definitions/ast4u.yml
Normal file
@@ -0,0 +1,110 @@
|
||||
---
|
||||
site: ast4u
|
||||
name: AST4u
|
||||
description: "AST4u is a GERMAN Private site for TV / MOVIES / ANIME / HENTAI"
|
||||
language: de-de
|
||||
type: private
|
||||
encoding: iso-8859-1
|
||||
links:
|
||||
- https://www.ast4u.me/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 35, cat: TV/Anime, desc: "Anime Movie"}
|
||||
- {id: 36, cat: TV/Anime, desc: "Anime Serie"}
|
||||
- {id: 37, cat: Audio/Foreign, desc: "Anime Musik"}
|
||||
- {id: 41, cat: Books, desc: "Anime Pic & Manga"}
|
||||
- {id: 42, cat: XXX, desc: "Hentai Movie & OVA"}
|
||||
- {id: 43, cat: XXX, desc: "Hentai Serie"}
|
||||
- {id: 44, cat: PC, desc: "Hentai Game"}
|
||||
- {id: 45, cat: Movies, desc: "Cartoon Movie"}
|
||||
- {id: 46, cat: TV, desc: "Cartoon Serie"}
|
||||
- {id: 47, cat: TV, desc: "TV-Serie"}
|
||||
- {id: 49, cat: TV/Documentary, desc: "Sonstiges Doku"}
|
||||
- {id: 50, cat: Audio, desc: "Sonstiges Soundtrack"}
|
||||
- {id: 52, cat: Movies/HD, desc: "Movie HD"}
|
||||
- {id: 53, cat: Other, desc: "Sonstiges"}
|
||||
- {id: 55, cat: Movies/Foreign, desc: "Movie Asia & MartialArts"}
|
||||
- {id: 56, cat: TV/Anime, desc: "Anime OVA"}
|
||||
- {id: 58, cat: Movies, desc: "Movie"}
|
||||
- {id: 59, cat: Audio/Audiobook, desc: "Sonstiges Hoerspiele"}
|
||||
- {id: 62, cat: Console, desc: "Sonstiges Game"}
|
||||
- {id: 65, cat: Movies/BluRay, desc: "Movie BluRay"}
|
||||
- {id: 66, cat: TV, desc: "TV-Serie BluRay"}
|
||||
- {id: 67, cat: TV/HD, desc: "TV-Serie HD"}
|
||||
- {id: 68, cat: TV/Anime, desc: "Anime Movie HD & BD"}
|
||||
- {id: 69, cat: TV/Anime, desc: "Anime OVA HD & BD"}
|
||||
- {id: 70, cat: TV/Anime, desc: "Anime Serie HD & BD"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
login:
|
||||
path: takelogin.php
|
||||
method: post
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
returnto: "/index.php"
|
||||
test:
|
||||
path: browse.php
|
||||
|
||||
search:
|
||||
path: browse.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
incldead: "0"
|
||||
orderby: "added"
|
||||
sort: "desc"
|
||||
|
||||
rows:
|
||||
selector: table.tableinborder > tbody > tr:has(a[href^="details.php"])
|
||||
fields:
|
||||
title:
|
||||
selector: a[href^="details.php"]
|
||||
category:
|
||||
selector: a[href^="browse.php?cat="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
details:
|
||||
selector: a[href^="details.php"]
|
||||
attribute: href
|
||||
download:
|
||||
selector: a[href^=" /gettorrent/ssl/"]
|
||||
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: replace
|
||||
args: ["\xA0", " "]
|
||||
- name: dateparse
|
||||
args: "02.01.2006 15:04:05 -07:00"
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
img[src="/pic/free.gif"]: "0"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: audiobooktorrents
|
||||
name: Audiobook Torrents
|
||||
description: "Audiobook Torrents (ABT) is a Private Torrent Tracker for AUDIOBOOKS"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
@@ -133,4 +134,4 @@
|
||||
selector: td[colspan=13]
|
||||
filters:
|
||||
- name: prepend
|
||||
args: "{{ .Result.description }}<br>\n"
|
||||
args: "{{ .Result.description }}<br>\n"
|
||||
|
265
src/Jackett/Definitions/b2s-share.yml
Normal file
265
src/Jackett/Definitions/b2s-share.yml
Normal file
@@ -0,0 +1,265 @@
|
||||
---
|
||||
site: b2s-share
|
||||
name: B2S-Share
|
||||
description: "B2S-Share is a Brazilian Private site for TV / MOVIES / GENERAL"
|
||||
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"
|
122
src/Jackett/Definitions/backups.yml
Normal file
122
src/Jackett/Definitions/backups.yml
Normal file
@@ -0,0 +1,122 @@
|
||||
site: backups
|
||||
name: Back-ups
|
||||
description: "Back-Ups is a Private Torrent Tracker for MOVIES / TV / GENERAL"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://back-ups.me/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 12, cat: Console, desc: "XBOX360"}
|
||||
- {id: 9, cat: TV, desc: "TV-Boxsets"}
|
||||
- {id: 3, cat: PC, desc: "Apps"}
|
||||
- {id: 24, cat: PC, desc: "Apple"}
|
||||
- {id: 11, cat: TV, desc: "TV/x264"}
|
||||
- {id: 23, cat: Console, desc: "Visionary"}
|
||||
- {id: 14, cat: TV/Sport, desc: "WWE"}
|
||||
- {id: 26, cat: Console, desc: "Xbox"}
|
||||
- {id: 13, cat: Console, desc: "XBOX-JTAG"}
|
||||
- {id: 35, cat: Movies/Other, desc: "Anime"}
|
||||
- {id: 4, cat: Movies/BluRay, desc: "Blu-Ray"}
|
||||
- {id: 6, cat: Movies, desc: "Movies/XVID"}
|
||||
- {id: 10, cat: TV, desc: "TV/Xvid"}
|
||||
- {id: 29, cat: TV/Sport, desc: "Sport"}
|
||||
- {id: 40, cat: TV, desc: "Soaps"}
|
||||
- {id: 27, cat: Console, desc: "Roms and Emulators"}
|
||||
- {id: 30, cat: Console, desc: "Playstation"}
|
||||
- {id: 7, cat: Audio, desc: "Music"}
|
||||
- {id: 16, cat: TV/Documentary, desc: "Docu"}
|
||||
- {id: 5, cat: Books, desc: "EBooks"}
|
||||
- {id: 38, cat: Console, desc: "Hyperspin Bolt-on Edition"}
|
||||
- {id: 34, cat: TV, desc: "Kids"}
|
||||
- {id: 8, cat: PC/Games, desc: "PC Games"}
|
||||
- {id: 22, cat: PC/Games, desc: "CoinOPS"}
|
||||
- {id: 33, cat: TV/Sport, desc: "MMA/Boxing"}
|
||||
- {id: 32, cat: Movies, desc: "Movie Pack"}
|
||||
- {id: 31, cat: Console, desc: "Nintendo"}
|
||||
|
||||
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:contains("remaining tries")
|
||||
test:
|
||||
path: browse.php
|
||||
selector: a[href*="/logout.php"]
|
||||
|
||||
search:
|
||||
path: browse.php
|
||||
keywordsfilters:
|
||||
# remove words <= 3 characters and surrounding special characters
|
||||
- name: re_replace
|
||||
args: ["(?:^|\\s)[_\\+\\/\\.\\-\\(\\)]*[\\S]{0,3}[_\\+\\/\\.\\-\\(\\)]*(?:\\s|$)", " "]
|
||||
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:
|
||||
title:
|
||||
selector: a[href*="/details.php?id="]
|
||||
title:
|
||||
optional: true
|
||||
selector: div.tooltip-content > div
|
||||
details:
|
||||
selector: a[href*="/details.php?id="]
|
||||
attribute: href
|
||||
download:
|
||||
selector: a[href*="/download.php?id="]
|
||||
attribute: href
|
||||
magnet:
|
||||
selector: a[href^="magnet:?xt="]
|
||||
attribute: href
|
||||
category:
|
||||
selector: a[href*="/browse.php?category="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: category
|
||||
size:
|
||||
selector: td:nth-child(5)
|
||||
grabs:
|
||||
selector: td:nth-child(6)
|
||||
seeders:
|
||||
selector: td:nth-child(7)
|
||||
leechers:
|
||||
selector: td:nth-child(8)
|
||||
date:
|
||||
selector: "td:nth-child(2) > div:has(span[style=\"float: right;\"])"
|
||||
remove: span
|
||||
filters:
|
||||
- name: append
|
||||
args: " +00:00"
|
||||
- name: dateparse
|
||||
args: "02-01-2006 15:04 -07:00"
|
||||
banner:
|
||||
optional: true
|
||||
selector: div.tooltip-content > img
|
||||
attribute: src
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
img[alt^="Free Torrent "]: "0"
|
||||
img[alt^="Silver Torrent "]: "0.5"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: bithq
|
||||
name: BitHQ
|
||||
description: "BitHQ is a Private Torrent Tracker for DVD-R / BLURAY MOVIES / TV"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: windows-1252
|
||||
@@ -90,4 +91,4 @@
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
||||
"*": "1"
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
---
|
||||
site: bithumen
|
||||
name: BitHUmen
|
||||
description: "BitHUmen is a Hungarian Private site for TV / MOVIES / GENERAL"
|
||||
language: hu-hu
|
||||
type: private
|
||||
encoding: ISO-8859-2
|
||||
@@ -72,7 +73,8 @@
|
||||
attribute: href
|
||||
title:
|
||||
selector: a[href^="details.php?id="]
|
||||
title|optional:
|
||||
title:
|
||||
optional: true
|
||||
selector: a[href^="details.php?id="]
|
||||
attribute: title
|
||||
details:
|
||||
@@ -108,14 +110,16 @@
|
||||
selector: td:nth-child(6) > u
|
||||
downloadvolumefactor:
|
||||
text: "1"
|
||||
downloadvolumefactor|optional:
|
||||
downloadvolumefactor:
|
||||
optional: true
|
||||
selector: td:nth-child(6) > nobr > font:contains(" × ")
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["×", ""]
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
||||
uploadvolumefactor|optional:
|
||||
uploadvolumefactor:
|
||||
optional: true
|
||||
selector: td:nth-child(5) > nobr > font:contains(" × ")
|
||||
filters:
|
||||
- name: replace
|
||||
@@ -131,4 +135,3 @@
|
||||
|
||||
description:
|
||||
selector: td:nth-child(2) > div
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
---
|
||||
site: bitspyder
|
||||
name: Bitspyder
|
||||
description: "Bitspyder is a Private site for Educational BOOKS / AUDIO"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: windows-1252
|
||||
@@ -94,7 +95,7 @@
|
||||
files:
|
||||
selector: a[href*="&filelist=1"]
|
||||
grabs:
|
||||
selector: td.rowcol:nth-child(7):has(br)
|
||||
selector: td.rowcol:nth-child(7):has(br), td.clear:nth-child(4)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: ([\d,]+)
|
||||
@@ -102,7 +103,8 @@
|
||||
selector: td.rowcol:nth-last-child(3)
|
||||
leechers:
|
||||
selector: td.rowcol:nth-last-child(2)
|
||||
date|optional|1:
|
||||
date:
|
||||
optional: true
|
||||
selector: font[color="5F5F5F"]
|
||||
filters:
|
||||
- name: split
|
||||
@@ -113,7 +115,8 @@
|
||||
args: " +00:00"
|
||||
- name: dateparse
|
||||
args: "2006-01-02 15:04:05 -07:00"
|
||||
date|optional|2:
|
||||
date:
|
||||
optional: true
|
||||
selector: a[title^="Upploaded at"]
|
||||
attribute: title
|
||||
filters:
|
||||
@@ -129,5 +132,6 @@
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
||||
description|optional:
|
||||
description:
|
||||
optional: true
|
||||
selector: font[color="#990000"]
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: bluebirdhd
|
||||
name: BlueBird
|
||||
description: "BlueBird is a RUSSIAN Private Torrent Tracker for HD MOVIES"
|
||||
language: ru-ru
|
||||
type: private
|
||||
encoding: windows-1251
|
||||
|
103
src/Jackett/Definitions/blutopia.yml
Normal file
103
src/Jackett/Definitions/blutopia.yml
Normal file
@@ -0,0 +1,103 @@
|
||||
---
|
||||
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]
|
||||
tv-search: [q, season, ep, imdbid]
|
||||
movie-search: [q, imdbid]
|
||||
|
||||
login:
|
||||
path: /login
|
||||
method: form
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
error:
|
||||
- selector: table.main:contains("Login Failed!")
|
||||
test:
|
||||
path: /torrents
|
||||
|
||||
search:
|
||||
path: /filter
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}categories[]={{.}}&{{end}}"
|
||||
search: "{{if .Query.IMDBID}}{{else}}{{ .Keywords }}{{end}}"
|
||||
imdb: "{{ .Query.IMDBIDShort }}"
|
||||
tvdb: ""
|
||||
tmdb: ""
|
||||
sorting: created_at
|
||||
direction: desc
|
||||
qty: 100
|
||||
preprocessingfilters:
|
||||
- name: jsonjoinarray
|
||||
args: ["$.result", ""]
|
||||
- name: prepend
|
||||
args: "<table>"
|
||||
- name: append
|
||||
args: "</table>"
|
||||
rows:
|
||||
selector: tr
|
||||
fields:
|
||||
category:
|
||||
selector: a[href*="/categories/"]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: strdump
|
||||
- name: regexp
|
||||
args: "/categories/.*?\\.(\\d+)"
|
||||
- name: strdump
|
||||
title:
|
||||
selector: a.view-torrent
|
||||
download:
|
||||
selector: a[href*="/download_check/"]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["/download_check/", "/download/"]
|
||||
details:
|
||||
selector: a.view-torrent
|
||||
attribute: href
|
||||
imdb:
|
||||
optional: true
|
||||
selector: a[href*="://www.imdb.com/title/"]
|
||||
attribute: href
|
||||
size:
|
||||
selector: td:nth-child(5)
|
||||
seeders:
|
||||
selector: td:nth-child(7)
|
||||
leechers:
|
||||
selector: td:nth-child(8)
|
||||
grabs:
|
||||
selector: td:nth-child(6)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: ([\d\.]+)
|
||||
date:
|
||||
selector: time
|
||||
attribute: datetime
|
||||
filters:
|
||||
- name: append
|
||||
args: " +00:00"
|
||||
- name: dateparse
|
||||
args: "2006-01-02 15:04:05 -07:00"
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"i[data-original-title=\"100% Free\"]": "0"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"i[data-original-title=\"Double upload\"]": "2"
|
||||
"*": "1"
|
58
src/Jackett/Definitions/btbit.yml
Normal file
58
src/Jackett/Definitions/btbit.yml
Normal file
@@ -0,0 +1,58 @@
|
||||
---
|
||||
site: btbit
|
||||
name: btbit
|
||||
description: "btbit is a public magnet search engine for MOVIES / GENERAL. This definition is for the English site."
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://en.btbit.org/
|
||||
|
||||
caps:
|
||||
categories:
|
||||
"Movie": Movies
|
||||
"Package": PC/0day
|
||||
"Other": Other
|
||||
"Software": PC
|
||||
"Mirror": PC/ISO
|
||||
"Music": Audio
|
||||
"Picture": Other/Misc
|
||||
"Document": Books
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
settings: []
|
||||
|
||||
search:
|
||||
path: "list/{{if .Keywords}}{{.Keywords}}{{else}}movie{{end}}.html"
|
||||
rows:
|
||||
selector: .rs
|
||||
fields:
|
||||
title:
|
||||
selector: .title
|
||||
category:
|
||||
selector: .sbar span[class^="cpill"]
|
||||
details:
|
||||
selector: .title h3 a
|
||||
attribute: href
|
||||
download:
|
||||
selector: .sbar a[href^="magnet:?xt"]
|
||||
attribute: href
|
||||
date:
|
||||
selector: .sbar span:nth-of-type(3) b
|
||||
filters:
|
||||
- name: dateparse
|
||||
args: "2006-01-02"
|
||||
size:
|
||||
selector: .sbar span:nth-of-type(4) b
|
||||
files:
|
||||
selector: .sbar span:nth-of-type(5) b
|
||||
grabs:
|
||||
selector: .sbar span:nth-of-type(6) b
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
77
src/Jackett/Definitions/btdb.yml
Normal file
77
src/Jackett/Definitions/btdb.yml
Normal file
@@ -0,0 +1,77 @@
|
||||
---
|
||||
site: btdb
|
||||
name: BTDB
|
||||
description: "BTDB is a Public BitTorrent DHT search engine. Torrents can be downloaded via magnet links"
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://btdb.to/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 1, cat: Other, desc: "Other"}
|
||||
- {id: 2, cat: TV, desc: "TV"}
|
||||
- {id: 3, cat: Movies, desc: ""}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
settings:
|
||||
- name: info
|
||||
type: info
|
||||
label: Category for Sonarr and Radarr
|
||||
default: BTDB does not use categories. In your Sonarr or Radarr Torznab Indexer settings, set the category to 100001.
|
||||
|
||||
search:
|
||||
path: "{{if .Keywords}}q/{{ .Keywords}}/?sort=time{{else}}recent{{end}}"
|
||||
rows:
|
||||
selector: li[class$="item"]
|
||||
fields:
|
||||
title:
|
||||
selector: h2[class$="title"] a[href^="/torrent/"]
|
||||
attribute: title
|
||||
category:
|
||||
text: "1"
|
||||
details:
|
||||
selector: h2[class$="title"] a[href^="/torrent/"]
|
||||
attribute: href
|
||||
magnet:
|
||||
selector: div[class$="info"] a[href^="magnet:"]
|
||||
attribute: href
|
||||
date:
|
||||
selector: div[class$="info"]
|
||||
filters:
|
||||
- name: split
|
||||
args: ["\n", 3]
|
||||
- name: replace
|
||||
args: ["AddTime: ", ""]
|
||||
- name: dateparse
|
||||
args: "2006-01-02 15:04:05"
|
||||
size:
|
||||
selector: div[class$="info"]
|
||||
filters:
|
||||
- name: split
|
||||
args: ["\n", 1]
|
||||
- name: replace
|
||||
args: ["Size: ", ""]
|
||||
files:
|
||||
selector: div[class$="info"]
|
||||
filters:
|
||||
- name: split
|
||||
args: ["\n", 2]
|
||||
- name: replace
|
||||
args: ["Files: ", ""]
|
||||
grabs:
|
||||
selector: div[class$="info"]
|
||||
filters:
|
||||
- name: split
|
||||
args: ["\n", 4]
|
||||
- name: replace
|
||||
args: ["Popularity: ", ""]
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: btnext
|
||||
name: BTNext
|
||||
description: "BTNext (BTNT) is a PORTUGUESE Private Torrent Tracker for 0DAY / GENERAL"
|
||||
language: pt-pt
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
@@ -120,7 +121,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:
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: carpathians
|
||||
name: Carpathians
|
||||
description: "Carpathians is a HUNGARIAN Private Torrent Tracker for 0DAY / GENERAL"
|
||||
language: hu-hu
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
|
@@ -1,4 +1,4 @@
|
||||
---
|
||||
---
|
||||
site: chdbits
|
||||
name: CHDBits
|
||||
description: "A general tracker"
|
||||
@@ -54,7 +54,8 @@
|
||||
fields:
|
||||
title:
|
||||
selector: a[href^="details.php?id="]
|
||||
title|optional:
|
||||
title:
|
||||
optional: true
|
||||
selector: a[title][href^="details.php?id="]
|
||||
attribute: title
|
||||
category:
|
||||
|
95
src/Jackett/Definitions/cpabien.yml
Normal file
95
src/Jackett/Definitions/cpabien.yml
Normal file
@@ -0,0 +1,95 @@
|
||||
---
|
||||
site: cpasbien
|
||||
name: cpasbien
|
||||
description: "cpasbien is a FRENCH Public site for TV / MOVIES / GENERAL"
|
||||
language: fr-fr
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://cpabien.la/
|
||||
legacylinks:
|
||||
- http://cpabien.org/
|
||||
- http://cpabien.cc/
|
||||
- http://cpabien.co/
|
||||
|
||||
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", "" ]
|
||||
date:
|
||||
text: "now"
|
||||
seeders:
|
||||
text: 0
|
||||
seeders:
|
||||
selector: div.up
|
||||
optional: true
|
||||
leechers:
|
||||
text: 0
|
||||
leechers:
|
||||
selector: div.down
|
||||
optional: true
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: czteam
|
||||
name: CZTeam
|
||||
description: "CZTeam (CZT) is a ROMANIAN Private Torrent Tracker for MOVIES / TV / GENERAL"
|
||||
language: cs-cz
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
@@ -91,4 +92,4 @@
|
||||
"*": "1"
|
||||
description:
|
||||
selector: div.torrent_info
|
||||
remove: strong
|
||||
remove: strong
|
||||
|
137
src/Jackett/Definitions/cztorrent.yml
Normal file
137
src/Jackett/Definitions/cztorrent.yml
Normal file
@@ -0,0 +1,137 @@
|
||||
site: cztorrent
|
||||
name: CzTorrent
|
||||
description: "CzTorrent is a Czech Semi-Private site for TV / MOVIES / GENERAL"
|
||||
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: [".*? / ", ""]
|
||||
- name: diacritics
|
||||
args: replace
|
||||
- name: replace
|
||||
args: ["serie", ""]
|
||||
- name: replace
|
||||
args: ["Serie", ""]
|
||||
- name: re_replace
|
||||
args: ["(\\d{2})\\.", "S$1"]
|
||||
- name: re_replace
|
||||
args: ["(\\d{1})\\.", "S0$1"]
|
||||
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"
|
||||
- name: dateparse
|
||||
args: "2.1.2006 15:04 -07:00"
|
||||
seeders:
|
||||
selector: td:nth-child(7) span
|
||||
leechers:
|
||||
selector: td:nth-child(8) span
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: datascene
|
||||
name: DataScene
|
||||
description: "DataScene (DS) is a ROMANIAN Private Torrent Tracker for MOVIES / TV / GENERAL"
|
||||
language: ro-ro
|
||||
type: private
|
||||
encoding: windows-1252
|
||||
@@ -67,11 +68,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,38 +87,41 @@
|
||||
- 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:
|
||||
"*": "1"
|
||||
description:
|
||||
selector: td:nth-child(2) > right
|
||||
remove: div
|
||||
remove: div
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: deildu
|
||||
name: Deildu
|
||||
description: "Deildu is an Icelandic Semi-Private site for TV / MOVIES / GENERAL"
|
||||
language: is-is
|
||||
type: semi-private
|
||||
encoding: iso-8859-1
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
---
|
||||
site: diablotorrent
|
||||
name: Diablo Torrent
|
||||
description: " Diablo Torrent is a Hungarian Private site for TV / MOVIES / GENERAL"
|
||||
language: hu-hu
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
@@ -58,32 +59,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 +87,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
|
||||
@@ -123,13 +115,15 @@
|
||||
args: "2006-01-0215:04:05 -07:00"
|
||||
size:
|
||||
selector: div.box_size
|
||||
banner|optional:
|
||||
banner:
|
||||
optional: true
|
||||
selector: a.cover_a
|
||||
attribute: title
|
||||
filters:
|
||||
- name: regexp
|
||||
args: src='(.*?)'
|
||||
imdb|optional:
|
||||
imdb:
|
||||
optional: true
|
||||
selector: a[href^="http://www.imdb.com/title/"]
|
||||
attribute: href
|
||||
description:
|
||||
|
@@ -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"
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: dragonworldreloaded
|
||||
name: Dragonworld Reloaded
|
||||
description: "Dragonworld Reloaded is a GERMAN Private Torrent Tracker for MOVIES / TV / GENERAL"
|
||||
language: de-de
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
|
@@ -1,10 +1,13 @@
|
||||
---
|
||||
site: dreamteam
|
||||
name: Dream Team
|
||||
description: "Dream Team is a GREEK Private Torrent Tracker for MOVIES / TV / GENERAL"
|
||||
language: el-gr
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://dream-team.ga/
|
||||
legacylinks:
|
||||
- http://dream-team.ml/
|
||||
|
||||
caps:
|
||||
@@ -249,7 +252,7 @@
|
||||
- selector: td:contains("remaining tries")
|
||||
test:
|
||||
path: browse.php
|
||||
selector: a[href^="http://dream-team.ml/logout.php"]
|
||||
selector: a[href*="/logout.php"]
|
||||
|
||||
download:
|
||||
before:
|
||||
@@ -271,29 +274,32 @@
|
||||
category: "0" # multi cat search not supported
|
||||
include_dead_torrents: "yes"
|
||||
rows:
|
||||
selector: table#sortabletable > tbody > tr:has(a[href^="http://dream-team.ml/details.php?id="])
|
||||
selector: table#sortabletable > tbody > tr:has(a[href*="/details.php?id="])
|
||||
filters:
|
||||
- name: andmatch
|
||||
args: 66
|
||||
fields:
|
||||
download:
|
||||
selector: a[href^="http://dream-team.ml/download.php?id="]
|
||||
selector: a[href*="/download.php?id="]
|
||||
attribute: href
|
||||
title:
|
||||
selector: a[href^="http://dream-team.ml/details.php?id="]
|
||||
title|optional:
|
||||
selector: a[href*="/details.php?id="]
|
||||
title:
|
||||
optional: true
|
||||
selector: div.tooltip-content > div
|
||||
details:
|
||||
selector: a[href^="http://dream-team.ml/details.php?id="]
|
||||
selector: a[href*="/details.php?id="]
|
||||
attribute: href
|
||||
category:
|
||||
selector: a[href^="http://dream-team.ml/browse.php?category="]
|
||||
selector: a[href*="/browse.php?category="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: category
|
||||
banner|optional:
|
||||
banner:
|
||||
optional: true
|
||||
selector: div.tooltip-content > img
|
||||
attribute: src
|
||||
size:
|
||||
selector: td:nth-child(5)
|
||||
grabs:
|
||||
|
@@ -1,11 +1,12 @@
|
||||
---
|
||||
site: hdclub
|
||||
name: HDClub
|
||||
---
|
||||
site: elitehd
|
||||
name: EliteHD
|
||||
description: "EliteHD (HDClub) is a RUSSIAN Private Torrent Tracker for HD MOVIES / TV / GENERAL"
|
||||
language: ru-ru
|
||||
type: private
|
||||
encoding: windows-1251
|
||||
links:
|
||||
- http://hdclub.org
|
||||
- https://elitehd.org/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
@@ -95,4 +96,4 @@
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
||||
"*": "1"
|
@@ -6,7 +6,7 @@
|
||||
type: private
|
||||
encoding: windows-1252
|
||||
links:
|
||||
- http://eot-forum.net
|
||||
- https://eot-forum.net
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: estone
|
||||
name: eStone
|
||||
description: "eStone (XiDER, BeLoad) is a HUNGARIAN Private Torrent Tracker for 0DAY / GENERAL"
|
||||
language: hu-hu
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
|
@@ -52,6 +52,8 @@
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
secure_cookie: "0"
|
||||
error:
|
||||
- selector: :contains("\"status\":\"error\"")
|
||||
test:
|
||||
path: browse.php
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: eztv
|
||||
name: EZTV
|
||||
description: "EZTV is a Public torrent site for TV shows"
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
@@ -43,7 +44,8 @@
|
||||
download:
|
||||
selector: td:nth-child(3) a.magnet, td:nth-child(3) a
|
||||
attribute: href
|
||||
size|optional:
|
||||
size:
|
||||
optional: true
|
||||
selector: td:nth-child(4)
|
||||
date:
|
||||
selector: td:nth-child(5)
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: fanoin
|
||||
name: FANO.IN
|
||||
description: "Fano.in is a LATVIAN Private Torrent Tracker for 0DAY / GENERAL"
|
||||
language: lv-lv
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
|
@@ -1,12 +1,23 @@
|
||||
---
|
||||
site: freedomhd
|
||||
name: Freedom-HD
|
||||
description: "Freedom-HD (Freedom Paradise) is a ratioless FRENCH Private Torrent Tracker for HD MOVIES / GENERAL"
|
||||
language: fr-fr
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
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
|
||||
@@ -127,4 +138,4 @@
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
||||
"*": "1"
|
||||
|
@@ -1,10 +1,13 @@
|
||||
---
|
||||
site: fullmixmusic
|
||||
name: FullMixMusic
|
||||
description: "FullMixMusic is a HUNGARIAN Private Torrent Tracker for MUSIC"
|
||||
language: hu-hu
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://fullmixmusic.org/
|
||||
legacylinks:
|
||||
- http://fullmixmusic.org/
|
||||
|
||||
caps:
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
---
|
||||
site: funkytorrents
|
||||
name: FunkyTorrents
|
||||
description: "FunkyTorrents (FT) is a Private Torrent Tracker for MUSIC"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
@@ -72,7 +73,8 @@
|
||||
rows:
|
||||
selector: table.mainouter > tbody > tr > td.outer > table > tbody > tr.mouse_out
|
||||
fields:
|
||||
description|optional:
|
||||
description:
|
||||
optional: true
|
||||
selector: td:nth-child(2) > font
|
||||
title:
|
||||
selector: td:nth-child(2)
|
||||
@@ -83,7 +85,8 @@
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
category|optional:
|
||||
category:
|
||||
optional: true
|
||||
case:
|
||||
a[href="/browse.php?ext=1&bitrate=Lossless"]: "3040"
|
||||
a[href="/browse.php?ext=1&format=MP3"]: "3010"
|
||||
@@ -116,4 +119,4 @@
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
||||
"*": "1"
|
||||
|
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"
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: gfxpeers
|
||||
name: GFXPeers
|
||||
description: "GFXPeers is a ratio-based torrent tracker for all things graphic design and visual effects"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: gigatorrents
|
||||
name: GigaTorrents
|
||||
description: "Giga Torrents is a Hungarian Private site for TV / MOVIES / GENERAL"
|
||||
language: hu-hu
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
@@ -70,6 +71,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="]
|
||||
@@ -138,4 +141,4 @@
|
||||
size:
|
||||
selector: td:nth-child(6)
|
||||
remove: span
|
||||
|
||||
|
||||
|
82
src/Jackett/Definitions/gktorrent.yml
Normal file
82
src/Jackett/Definitions/gktorrent.yml
Normal file
@@ -0,0 +1,82 @@
|
||||
---
|
||||
site: gktorrent
|
||||
name: GkTorrent
|
||||
description: "GkTorrent is a French Public site for TV / MOVIES / GENERAL"
|
||||
language: fr-fr
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://www.gktorrent.com
|
||||
legacylinks:
|
||||
- https://www.gktorrent.com # they're forcing http
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: movies, cat: Movies, desc: "Movies"}
|
||||
- {id: tvshows, cat: TV, desc: "TV Shows"}
|
||||
- {id: softwares, cat: PC, desc: "Softwares"}
|
||||
- {id: music, cat: Audio, desc: "Music"}
|
||||
- {id: games, cat: Console, desc: "Games"}
|
||||
- {id: books, cat: Books, desc: "Books"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
settings: []
|
||||
|
||||
download:
|
||||
selector: a[href^="/get_torrent/"]
|
||||
|
||||
search:
|
||||
path: "{{if .Keywords}}/recherche/{{.Keywords}}{{else}}{{end}}"
|
||||
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)
|
||||
seeders:
|
||||
selector: td:nth-child(3)
|
||||
leechers:
|
||||
selector: td:nth-child(4)
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
||||
category:
|
||||
selector: td:nth-child(1) > i
|
||||
case:
|
||||
.Films: "movies"
|
||||
.Séries: "tvshows"
|
||||
.Logiciels: "softwares"
|
||||
.Musiques: "music"
|
||||
.Jeux: "games"
|
||||
.Ebooks: "books"
|
||||
date:
|
||||
text: "now"
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: gods
|
||||
name: GODS
|
||||
description: "GODS is a German Private site for TV / MOVIES / GENERAL"
|
||||
language: de-de
|
||||
type: private
|
||||
encoding: windows-1252
|
||||
@@ -159,4 +160,4 @@
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
||||
"*": "1"
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: gormogon
|
||||
name: Gormogon
|
||||
description: "Gormogon is a Private Torrent Tracker for CLASSIC MOVIES / TV / GENERAL"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
@@ -190,4 +191,4 @@
|
||||
img[alt="8x Upload Multiplier"]: "8"
|
||||
img[alt="9x Upload Multiplier"]: "9"
|
||||
img[alt="10x Upload Multiplier"]: "10"
|
||||
"*": "1"
|
||||
"*": "1"
|
||||
|
@@ -2,6 +2,7 @@
|
||||
site: greekteam
|
||||
name: Greek Team
|
||||
language: el-gr
|
||||
description: "Greek Team is a GREEK Private site for TV / MOVIES / GENERAL"
|
||||
type: private
|
||||
encoding: windows-1253
|
||||
links:
|
||||
@@ -119,9 +120,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 +131,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"
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: hdhome
|
||||
name: HDHome
|
||||
description: "HDHome (HDBiger) is a CHINESE Private Torrent Tracker for HD MOVIES / TV"
|
||||
language: zh-cn
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
@@ -139,4 +140,4 @@
|
||||
"*": "1"
|
||||
description:
|
||||
selector: td:nth-child(2)
|
||||
remove: a, img
|
||||
remove: a, img
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: hdme
|
||||
name: HDME
|
||||
description: "HDME is a Private Torrent Tracker for HD MOVIES / TV / GENERAL"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: windows-1252
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: hdtorrentsit
|
||||
name: HDTorrents.it
|
||||
description: "HDTorrents.it is an ITALIAN Private site for TV / MOVIES"
|
||||
language: it-it
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
@@ -31,34 +32,71 @@
|
||||
paths:
|
||||
- path: browse.php
|
||||
method: post
|
||||
keywordsfilters:
|
||||
- name: re_replace
|
||||
args: ["[^a-zA-Z0-9]+", "%"]
|
||||
- name: diacritics
|
||||
args: replace
|
||||
- name: re_replace #remove SXXEYY from research
|
||||
args: ["(S\\d{1,2}E\\d{1,2})", ""]
|
||||
- name: re_replace #remove SXX from research
|
||||
args: ["(S\\d{1,2})", ""]
|
||||
inputs:
|
||||
ajax: false
|
||||
search: "{{ .Query.Keywords }}"
|
||||
search: "{{ .Keywords }}"
|
||||
incldead: 0
|
||||
rows:
|
||||
selector: tbody#highlighted tr
|
||||
fields:
|
||||
title-no-filters:
|
||||
selector: td:nth-child(2) a:nth-child(1)
|
||||
title:
|
||||
selector: td:nth-child(2) a:nth-child(1)
|
||||
filters:
|
||||
- name: re_replace #separate title
|
||||
args: ["(\\s+\\/\\s+|\\/\\s+|\\s+\\/|\\/)(.*)\\s\\(", " ("]
|
||||
- name: re_replace #remove (yyyy) from the title
|
||||
args: ["(\\(\\d{4}\\))|(\\(\\d{4})", ""]
|
||||
- name: re_replace #remove |
|
||||
args: ["(\\s\\|\\s)", " "]
|
||||
- name: re_replace #Stagione X --> S0X
|
||||
args: ["Stagione (\\d{0,1}\\s)", "S0$1"]
|
||||
- name: re_replace #Stagione XX --> SXX
|
||||
args: ["Stagione (\\d{2}\\s)", "S$1"]
|
||||
- name: re_replace #/ Episodio [YY-YY --> EYY-YY
|
||||
args: ["(\\s\\/\\sEpisodio|\\s\\/\\sEpisodi|\\sEpisodio|\\s\\|\\sEpisodio|\\sEpisodi)\\s\\[", "E"]
|
||||
- name: re_replace #/ Completa [episodi YY-YY --> EYY-YY
|
||||
args: ["(\\s\\/\\sCompleta\\s\\[episodi\\s)", "E"]
|
||||
- name: re_replace #remove di YY] | remove /YY]
|
||||
args: ["(\\sdi\\s\\d{1,2}|\\/\\d{1,2})\\]", " "]
|
||||
- name: re_replace #remove various
|
||||
args: ["(Serie completa|Completa|\\[in pausa\\])", ""]
|
||||
title|append: #start year
|
||||
text: "("
|
||||
title|append: #add year
|
||||
selector: td:nth-child(2) a:nth-child(1)
|
||||
filters:
|
||||
- name: regexp #find torrent year
|
||||
args: (\d{4})
|
||||
title|append: #end year
|
||||
text: ") "
|
||||
title|append: #start quality TAG
|
||||
text: "["
|
||||
title|append: #quality TAG (BDRip 1080, BDRip 720p etc)
|
||||
selector: td:nth-child(1) a:nth-child(1) img
|
||||
attribute: alt
|
||||
title|append: #separator
|
||||
text: " - "
|
||||
title|append: #ita audio TAG
|
||||
selector: a[href^="download.php?id="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: name
|
||||
- name: regexp
|
||||
args: (DTS AC3 ITA|DTS ITA|AC3 ITA)
|
||||
- name: re_replace
|
||||
args: ["Stagione (\\d{0,1})", "S0$1"]
|
||||
- name: re_replace
|
||||
args: ["Stagione (\\d{2})", "S$1"]
|
||||
- name: re_replace
|
||||
args: ["Episodio{0,1} \\[(\\d{0,1})", "E0$1"]
|
||||
- name: re_replace
|
||||
args: ["Episodio{0,1} \\[(\\d{2})", "E$1"]
|
||||
- name: re_replace
|
||||
args: ["-(\\d{0,1}) ", "-0$1 "]
|
||||
- name: re_replace
|
||||
args: ["-(\\d{2}) ", "-$1 "]
|
||||
- name: re_replace
|
||||
args: ["(\\d) *\\/ *(E)", "$1$2"]
|
||||
- name: replace
|
||||
args: ["]", ""]
|
||||
args: ["ITA", ""]
|
||||
title|append: #end TAG
|
||||
text: "ITA]"
|
||||
details:
|
||||
selector: td:nth-child(2) a:nth-child(1)
|
||||
attribute: href
|
||||
@@ -86,8 +124,10 @@
|
||||
date:
|
||||
selector: td:nth-child(2) i
|
||||
filters:
|
||||
- name: append
|
||||
args: " +02:00"
|
||||
- name: dateparse
|
||||
args: "2006-02-01 15:04:05"
|
||||
args: "2006-01-02 15:04:05 -07:00"
|
||||
category:
|
||||
case:
|
||||
"a[href^=\"details.php\"]:contains(\"Stagione\")": 5040 # TV/HD
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
---
|
||||
site: hon3yhd
|
||||
name: Hon3y HD
|
||||
description: "Hon3yHD is an INDIAN Private Torrent Tracker for MOVIES / TV / GENERAL"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
@@ -68,9 +69,15 @@
|
||||
path: /browse.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
|
||||
search: "{{ .Query.Keywords }}"
|
||||
search: "{{ .Keywords }}"
|
||||
searchin: "title"
|
||||
incldead: "1"
|
||||
keywordsfilters:
|
||||
# by default the search returns unordered resuts of an OR query making the results useless in many cases, adding + to the keywords improves the situration (Issue #1859)
|
||||
- name: re_replace # replace special characters with " +"
|
||||
args: ["[^\\w\\d]+", " +"]
|
||||
- name: prepend
|
||||
args: "+"
|
||||
rows:
|
||||
selector: table > tbody > tr.tt
|
||||
fields:
|
||||
@@ -88,7 +95,8 @@
|
||||
download:
|
||||
selector: a[href^="download.php?torrent="]
|
||||
attribute: href
|
||||
banner|optional:
|
||||
banner:
|
||||
optional: true
|
||||
selector: a[href^="details.php?id="]
|
||||
attribute: onmouseover
|
||||
filters:
|
||||
|
@@ -1,10 +1,13 @@
|
||||
---
|
||||
site: hyperay
|
||||
name: Hyperay
|
||||
description: "Hyperay is a CHINESE Private Torrent Tracker for HD MOVIES / TV"
|
||||
language: zh-cn
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://www.hyperay.org
|
||||
legacylinks:
|
||||
- https://www.hyperay.cc
|
||||
|
||||
caps:
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: icetorrent
|
||||
name: ICE Torrent
|
||||
description: "ICE Torrent is a ratioless ROMANIAN Private Torrent Tracker for 0DAY / GENERAL"
|
||||
language: ro-ro
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
|
101
src/Jackett/Definitions/idope.yml
Normal file
101
src/Jackett/Definitions/idope.yml
Normal file
@@ -0,0 +1,101 @@
|
||||
---
|
||||
site: idope
|
||||
name: Idope
|
||||
description: "iDope is a Public torrent search engine presenting direct magnet links"
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://idope.se/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 0, cat: Other, desc: "Others"}
|
||||
- {id: 1, cat: Movies, desc: "Movies"}
|
||||
- {id: 2, cat: Other, desc: "Video"}
|
||||
- {id: 3, cat: TV, desc: "TV"}
|
||||
- {id: 4, cat: TV/Anime, desc: "Anime"}
|
||||
- {id: 5, cat: XXX, desc: "XXX"}
|
||||
- {id: 6, cat: Audio, desc: "Music"}
|
||||
- {id: 7, cat: PC/Games, desc: "Games"}
|
||||
- {id: 8, cat: PC, desc: "Apps"}
|
||||
- {id: 9, cat: Books, desc: "Books"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
settings:
|
||||
- name: itorrents-links
|
||||
type: checkbox
|
||||
label: Add download links via itorrents.org
|
||||
- name: info
|
||||
type: info
|
||||
label: ITorrents Note
|
||||
default: Without the itorrents option only magnet links will be provided.
|
||||
|
||||
search:
|
||||
# present trending results if there are no search parms supplied
|
||||
# sort torrent-list by age in descending order
|
||||
path: "{{if .Keywords}}torrent-list/{{ .Keywords}}?&o=-3&c={{range .Categories }}{{.}}{{end}}{{else}}browse.html{{end}}"
|
||||
rows:
|
||||
selector: div[class="resultdiv"]
|
||||
fields:
|
||||
title:
|
||||
selector: div[class="resultdivtop"] a div[class="resultdivtopname"]
|
||||
category:
|
||||
optional: true
|
||||
selector: div[class="resultdivbotton"] div[class="resultdivbottoncategory"]
|
||||
case:
|
||||
":contains(\"Others\")": 0
|
||||
":contains(\"Movies\")": 1
|
||||
":contains(\"Video\")": 2
|
||||
":contains(\"TV\")": 3
|
||||
":contains(\"Anime\")": 4
|
||||
":contains(\"XXX\")": 5
|
||||
":contains(\"Music\")": 6
|
||||
":contains(\"Games\")": 7
|
||||
":contains(\"Apps\")": 8
|
||||
":contains(\"Books\")": 9
|
||||
details:
|
||||
selector: div[class="resultdivtop"] a
|
||||
attribute: href
|
||||
download-itorrents:
|
||||
selector: div[class="resultdivbotton"] div[id^="hideinfohash"]
|
||||
filters:
|
||||
- name: toupper
|
||||
- name: prepend
|
||||
args: http://itorrents.org/torrent/
|
||||
- name: append
|
||||
args: ".torrent"
|
||||
download:
|
||||
text: "{{if .Config.itorrents-links}}{{ .Result.download-itorrents }}{{else}}{{end}}"
|
||||
magfile:
|
||||
text: "{{ .Result.title }}"
|
||||
filters:
|
||||
- name: validfilename
|
||||
- name: urlencode
|
||||
magnet:
|
||||
selector: div[class="resultdivbotton"] div[id^="hideinfohash"]
|
||||
filters:
|
||||
- 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"
|
||||
date:
|
||||
selector: div[class="resultdivbotton"] div[class="resulttime"] div[class="resultdivbottontime"]
|
||||
filters:
|
||||
- name: timeago
|
||||
size:
|
||||
selector: div[class="resultdivbotton"] div[class="resultlength"] div[class="resultdivbottonlength"]
|
||||
seeders:
|
||||
selector: div[class="resultdivbotton"] div[class="resultseed"] div[class="resultdivbottonseed"]
|
||||
files:
|
||||
selector: div[class="resultdivbotton"] div[class="resultfile"] div[class="resultdivbottonfiles"]
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
@@ -1,11 +1,14 @@
|
||||
---
|
||||
site: ilcorsaronero
|
||||
name: Il Corsaro Nero
|
||||
description: "Il Corsaro Nero is an ITALIAN Public site for TV / MOVIES / GENERAL"
|
||||
language: it-it
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://ilcorsaronero.info/
|
||||
certificates:
|
||||
- 8D4B5B12D12693F29271C6A0A65ACB3DF6029202 # incomplete CA chain
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: infinityt
|
||||
name: Infinity-T
|
||||
description: "Infinity-T is a DANISH Private Torrent Tracker for 0DAY / GENERAL"
|
||||
language: da-dk
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
@@ -103,4 +104,4 @@
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
||||
"*": "1"
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: inperil
|
||||
name: inPeril
|
||||
description: "InPeril is a LATVIAN Private Torrent Tracker for 0DAY / GENERAL"
|
||||
type: private
|
||||
language: lv-lv
|
||||
type: private
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
---
|
||||
site: insanetracker
|
||||
name: Insane Tracker
|
||||
description: "Insane Tracker is a HUNGARIAN Private Torrent Tracker for 0DAY / GENERAL"
|
||||
language: hu-hu
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
@@ -80,13 +81,16 @@
|
||||
download:
|
||||
selector: a[href^="download.php/"]
|
||||
attribute: href
|
||||
imdb|optional:
|
||||
imdb:
|
||||
optional: true
|
||||
selector: a[title="IMDb link"]
|
||||
attribute: href
|
||||
banner|optional|1:
|
||||
banner:
|
||||
optional: true
|
||||
selector: img[alt="offer"]
|
||||
attribute: src
|
||||
banner|optional|2:
|
||||
banner:
|
||||
optional: true
|
||||
selector: a.cover
|
||||
attribute: href
|
||||
files:
|
||||
|
@@ -1,61 +0,0 @@
|
||||
---
|
||||
site: isohunt
|
||||
name: Isohunt
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://isohunt.to/
|
||||
|
||||
caps:
|
||||
categories:
|
||||
"series+&+tv": TV
|
||||
"movies": Movies
|
||||
"other": Other/Misc
|
||||
"music": Audio
|
||||
"games": PC/Games
|
||||
"software": PC/0day
|
||||
"anime": TV/Anime
|
||||
"adult": XXX
|
||||
"books": Other
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
settings: []
|
||||
|
||||
download:
|
||||
selector: a.btn-download
|
||||
|
||||
search:
|
||||
path: "{{if .Query.Keywords}}torrents/{{else}}latest.php{{end}}"
|
||||
inputs:
|
||||
ihq: "{{ .Keywords }}"
|
||||
rows:
|
||||
selector: "#serps > table > tbody > tr:has(td.title-row)"
|
||||
fields:
|
||||
title:
|
||||
selector: td.title-row > a[href^="/"] > span
|
||||
details:
|
||||
selector: td.title-row > a[href^="/"]
|
||||
attribute: href
|
||||
download:
|
||||
selector: td.title-row > a[href^="/"]
|
||||
attribute: href
|
||||
size:
|
||||
selector: td.size-row
|
||||
seeders:
|
||||
selector: td.sy, td.sn
|
||||
date:
|
||||
selector: td.date-row
|
||||
filters:
|
||||
- name: append
|
||||
args: " ago"
|
||||
category:
|
||||
selector: td.category-row > span
|
||||
attribute: title
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: jpopsuki
|
||||
name: JPopsuki
|
||||
description: "JPopSuki is a Private Torrent Tracker for ASIAN MUSIC"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
@@ -102,4 +103,4 @@
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
||||
"*": "1"
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
---
|
||||
site: kapaki
|
||||
name: Kapaki
|
||||
description: "Kapaki is a GREEK Private Torrent Tracker for MOVIES / TV / GENERAL"
|
||||
language: el-gr
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
@@ -76,7 +77,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:
|
||||
@@ -107,7 +109,8 @@
|
||||
selector: a[rel="torrent_leechers"]
|
||||
grabs:
|
||||
selector: a[rel="times_completed"]
|
||||
banner|optional:
|
||||
banner:
|
||||
optional: true
|
||||
selector: a[rel="fancybox"]
|
||||
attribute: href
|
||||
description:
|
||||
@@ -119,10 +122,12 @@
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
||||
date|optional|1:
|
||||
date:
|
||||
optional: true
|
||||
selector: div.torrentOwner > abbr.timeago
|
||||
attribute: data-time
|
||||
date|optional|2:
|
||||
date:
|
||||
optional: true
|
||||
selector: div.torrentOwner:not(:has(abbr.timeago))
|
||||
remove: span
|
||||
filters:
|
||||
@@ -155,4 +160,4 @@
|
||||
- name: dateparse
|
||||
args: "02-01-2006 15:04"
|
||||
|
||||
|
||||
|
||||
|
@@ -29,9 +29,6 @@
|
||||
- selector: table:contains("Login failed!")
|
||||
test:
|
||||
path: index.php
|
||||
|
||||
download:
|
||||
selector: a[href^="download.php?id="]
|
||||
|
||||
search:
|
||||
path: browse.php
|
||||
|
5
src/Jackett/Definitions/kickasstorrent-kathow.yml
Normal file → Executable file
5
src/Jackett/Definitions/kickasstorrent-kathow.yml
Normal file → Executable file
@@ -1,11 +1,12 @@
|
||||
---
|
||||
site: kickasstorrent-kathow
|
||||
name: KickAssTorrent (kat.how)
|
||||
name: KickAssTorrent (thekat.se)
|
||||
description: "thekat.se is a Public KickAssTorrent clone for TV / MOVIES / GENERAL"
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://kat.how
|
||||
- https://thekat.se
|
||||
|
||||
caps:
|
||||
categories:
|
||||
|
28
src/Jackett/Definitions/kickasstorrent.yml
Normal file → Executable file
28
src/Jackett/Definitions/kickasstorrent.yml
Normal file → Executable file
@@ -1,8 +1,9 @@
|
||||
---
|
||||
site: kickasstorrent
|
||||
name: KickAssTorrent
|
||||
description: "Kickass Torrents (KATcr) is a well-know Public torrent site indexing thousands of torrents verified and commented by a large file-sharing community"
|
||||
language: en-us
|
||||
type: semi-private
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://katcr.co/
|
||||
@@ -84,29 +85,12 @@
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
settings:
|
||||
- name: username
|
||||
type: text
|
||||
label: Username
|
||||
- name: passkey
|
||||
type: text
|
||||
label: Passkey
|
||||
|
||||
login:
|
||||
method: post
|
||||
path: "new/account-login.php"
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
passkey: "{{ .Config.passkey }}"
|
||||
test:
|
||||
path: index.php
|
||||
settings: []
|
||||
|
||||
search:
|
||||
path: "/new/torrents-search.php"
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
|
||||
search: "\"{{ .Query.Keywords }}\""
|
||||
path: "/new/{{if .Keywords}}search-torrents.php?{{range .Categories }}c{{.}}=1&{{end}}search={{.Keywords}}{{else}}{{end}}"
|
||||
rows:
|
||||
selector: table.ttable_headinner > tbody > tr[class^="t-row"]
|
||||
filters:
|
||||
@@ -200,8 +184,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"
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: limetorrents
|
||||
name: LimeTorrents
|
||||
description: "LimeTorrents is a Public general torrent index with mostly verified torrents"
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
@@ -57,7 +58,8 @@
|
||||
download:
|
||||
selector: div.tt-name > a[href^="/"]
|
||||
attribute: href
|
||||
category|optional:
|
||||
category:
|
||||
optional: true
|
||||
selector: td:nth-child(2)
|
||||
filters:
|
||||
- name: split
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
---
|
||||
site: linkomanija
|
||||
name: LinkoManija
|
||||
description: "LinkoManija is an ITALIAN Private site for TV / MOVIES / GENERAL"
|
||||
language: lt-lt
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
@@ -72,7 +73,8 @@
|
||||
attribute: href
|
||||
title:
|
||||
selector: a[href^="details?"]
|
||||
description|optional:
|
||||
description:
|
||||
optional: true
|
||||
selector: td:nth-child(2) > span
|
||||
details:
|
||||
selector: a[href^="details?"]
|
||||
@@ -108,4 +110,4 @@
|
||||
- name: dateparse
|
||||
args: "2006-01-0215:04:05 -07:00"
|
||||
|
||||
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
---
|
||||
site: losslessclub
|
||||
name: LosslessClub
|
||||
description: "LosslessClub is a Romanian Private site for High Quality Music"
|
||||
language: ru-ru
|
||||
type: private
|
||||
encoding: windows-1251
|
||||
@@ -45,12 +46,14 @@
|
||||
download:
|
||||
selector: a[href^="download.php?id="]
|
||||
attribute: href
|
||||
banner|optional:
|
||||
banner:
|
||||
optional: true
|
||||
selector: img.thumbnail
|
||||
attribute: src
|
||||
size:
|
||||
selector: td:nth-child(5)
|
||||
grabs|optional:
|
||||
grabs:
|
||||
optional: true
|
||||
selector: td:nth-child(6) br + span
|
||||
seeders:
|
||||
selector: td:nth-child(6)
|
||||
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
---
|
||||
site: magico
|
||||
name: Magico
|
||||
description: "Magico (Trellas) is a GREEK Private Torrent Tracker for MOVIES / TV / GENERAL"
|
||||
language: el-gr
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
@@ -165,7 +166,8 @@
|
||||
selector: a[rel="torrent_leechers"]
|
||||
grabs:
|
||||
selector: a[rel="times_completed"]
|
||||
banner|optional:
|
||||
banner:
|
||||
optional: true
|
||||
selector: a[rel="fancybox"]
|
||||
attribute: href
|
||||
description:
|
||||
@@ -177,10 +179,12 @@
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"*": "1"
|
||||
date|optional|1:
|
||||
date:
|
||||
optional: true
|
||||
selector: div.torrentOwner > abbr.timeago
|
||||
attribute: data-time
|
||||
date|optional|2:
|
||||
date:
|
||||
optional: true
|
||||
selector: div.torrentOwner:not(:has(abbr.timeago))
|
||||
remove: span
|
||||
filters:
|
||||
@@ -213,4 +217,4 @@
|
||||
- name: dateparse
|
||||
args: "02-01-2006 15:04"
|
||||
|
||||
|
||||
|
||||
|
68
src/Jackett/Definitions/magnetdl.yml
Normal file
68
src/Jackett/Definitions/magnetdl.yml
Normal file
@@ -0,0 +1,68 @@
|
||||
---
|
||||
site: magnetdl
|
||||
name: MagnetDL
|
||||
description: "MagnetDL is a Public torrent Magnet Links search engine"
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://www.magnetdl.com/
|
||||
|
||||
caps:
|
||||
categories:
|
||||
"TV": TV
|
||||
"Movie": Movies
|
||||
"Music": Audio
|
||||
"E-Book": Books/Ebook
|
||||
"Game": PC/Games
|
||||
"Software": PC
|
||||
"Other": Other
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
settings: []
|
||||
|
||||
search:
|
||||
headers:
|
||||
# prevent redirect
|
||||
Accept: ["text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"]
|
||||
keywordsfilters:
|
||||
# replace space between keywords with - to prevent 404 Not Found
|
||||
- name: re_replace
|
||||
args: [" ", "-"]
|
||||
- name: tolower
|
||||
# return movie results if there are no search parms supplied (for use with the TEST button)
|
||||
# http://www.magnetdl.com/m/midnight-texas-s01e10/
|
||||
path: "{{if .Keywords}}/{{ re_replace .Keywords \"(.).*\" \"$1\" }}/{{ .Keywords }}/{{else}}download/movies/{{end}}"
|
||||
rows:
|
||||
selector: tr:has(td[class="m"])
|
||||
fields:
|
||||
title:
|
||||
selector: td[class="n"] a
|
||||
attribute: title
|
||||
category:
|
||||
optional: true
|
||||
selector: td[class^="t"]
|
||||
details:
|
||||
selector: td[class="n"] a
|
||||
attribute: href
|
||||
magnet:
|
||||
selector: td[class="m"] a
|
||||
attribute: href
|
||||
date:
|
||||
selector: td:nth-child(3)
|
||||
filters:
|
||||
- name: timeago
|
||||
size:
|
||||
selector: td:nth-child(6)
|
||||
seeders:
|
||||
selector: td[class="s"]
|
||||
files:
|
||||
selector: td[class="l"]
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
---
|
||||
site: majomparade
|
||||
name: Majomparádé
|
||||
description: "Majomparádé (TurkDepo) is a HUNGARIAN Private Torrent Tracker for 0DAY / GENERAL"
|
||||
language: hu-hu
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
@@ -115,10 +116,12 @@
|
||||
details:
|
||||
selector: a[href^="details.php?id="]
|
||||
attribute: href
|
||||
imdb|optional:
|
||||
imdb:
|
||||
optional: true
|
||||
selector: a[href^="https://www.imdb.com/title/"]
|
||||
attribute: href
|
||||
banner|optional:
|
||||
banner:
|
||||
optional: true
|
||||
selector: img[src="pic/borito.png"]
|
||||
attribute: title
|
||||
filters:
|
||||
|
260
src/Jackett/Definitions/manicomioshare.yml
Normal file
260
src/Jackett/Definitions/manicomioshare.yml
Normal file
@@ -0,0 +1,260 @@
|
||||
---
|
||||
site: manicomioshare
|
||||
name: Manicomio Share
|
||||
description: "Manicomio Share is a Brazilian Private site for TV / MOVIES / GENERAL"
|
||||
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: ["|", ""]
|
||||
- name: replace
|
||||
args: ["Ep. ","E"]
|
||||
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"
|
78
src/Jackett/Definitions/metaltracker.yml
Normal file
78
src/Jackett/Definitions/metaltracker.yml
Normal file
@@ -0,0 +1,78 @@
|
||||
---
|
||||
site: metaltracker
|
||||
name: Metal Tracker
|
||||
description: "Metal Tracker is a Semi-Private site dedicated to HEAVY METAL MUSIC. This definition is for the English site."
|
||||
language: en-us
|
||||
type: semi-private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://en.metal-tracker.com/
|
||||
|
||||
caps:
|
||||
categories:
|
||||
"Books": Audio/Audiobook
|
||||
"Video": Audio/Video
|
||||
"Music": Audio/MP3
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
music-search: [q, album, artist, label, year]
|
||||
|
||||
login:
|
||||
path: /user/login.html
|
||||
method: form
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
go: "Enter"
|
||||
error:
|
||||
- selector: div.errorSummary
|
||||
message:
|
||||
selector: div.errorSummary ul li
|
||||
test:
|
||||
path: /torrents/search.html
|
||||
selector: li li:has(a[href="/user/logout.html"])
|
||||
|
||||
search:
|
||||
paths:
|
||||
- path: /torrents/search.html
|
||||
method: post
|
||||
inputs:
|
||||
"SearchTorrentsForm[nameTorrent]": "{{ .Keywords }}"
|
||||
go-search: "Search"
|
||||
rows:
|
||||
selector: .smallalbum
|
||||
fields:
|
||||
title:
|
||||
selector: a h3
|
||||
banner:
|
||||
selector: .thumb a img
|
||||
attribute: src
|
||||
details:
|
||||
selector: .thumb a
|
||||
attribute: href
|
||||
download:
|
||||
selector: .center a[href^="/torrents/download/id/"]
|
||||
attribute: href
|
||||
date:
|
||||
text: "now"
|
||||
seeders:
|
||||
selector: .center font:nth-of-type(1)
|
||||
leechers:
|
||||
selector: .center font:nth-of-type(2)
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
||||
category:
|
||||
selector: .smallalbum
|
||||
remove: div.thumb, div.center, a
|
||||
case:
|
||||
":contains(\"Type: Music\")": "Music"
|
||||
":contains(\"Type: Video\")": "Video"
|
||||
":contains(\"Type: Books\")": "Books"
|
||||
size:
|
||||
selector: .smallalbum
|
||||
filters:
|
||||
- name: regexp
|
||||
args: "Size:\\s+([\\w\\d\\.,]+ \\w\\w)"
|
@@ -1,6 +1,7 @@
|
||||
---
|
||||
site: mononokebt
|
||||
name: Mononoké-BT
|
||||
description: "Mononoke-BT is a FRENCH Private Torrent Tracker for ANIME"
|
||||
language: fr-fr
|
||||
type: private
|
||||
encoding: ISO-8859-15
|
||||
@@ -77,4 +78,4 @@
|
||||
- name: dateparse
|
||||
args: "2006-01-0215:04:05 -07:00"
|
||||
|
||||
|
||||
|
||||
|
@@ -29,12 +29,40 @@
|
||||
- {id: 423, cat: PC/Games, desc: "PCGame(PC遊戲)"}
|
||||
- {id: 427, cat: Books, desc: "eBook(電子書)"}
|
||||
- {id: 409, cat: Other, desc: "Misc(其他)"}
|
||||
# adult
|
||||
- {id: 410, cat: XXX, desc: "AV(有碼)/HD Censored"}
|
||||
- {id: 429, cat: XXX, desc: "AV(無碼)/HD Uncensored"}
|
||||
- {id: 424, cat: XXX, desc: "AV(有碼)/SD Censored"}
|
||||
- {id: 430, cat: XXX, desc: "AV(無碼)/SD Uncensored"}
|
||||
- {id: 426, cat: XXX, desc: "AV(無碼)/DVDiSo Uncensored"}
|
||||
- {id: 437, cat: XXX, desc: "AV(有碼)/DVDiSo Censored"}
|
||||
- {id: 431, cat: XXX, desc: "AV(有碼)/Blu-Ray Censored"}
|
||||
- {id: 432, cat: XXX, desc: "AV(無碼)/Blu-Ray Uncensored"}
|
||||
- {id: 436, cat: XXX, desc: "AV(網站)/0Day"}
|
||||
- {id: 425, cat: XXX, desc: "IV(寫真影集)/Video Collection"}
|
||||
- {id: 433, cat: XXX, desc: "IV(寫真圖集)/Picture Collection"}
|
||||
- {id: 411, cat: XXX, desc: "H-Game(遊戲)"}
|
||||
- {id: 412, cat: XXX, desc: "H-Anime(動畫)"}
|
||||
- {id: 413, cat: XXX, desc: "H-Comic(漫畫)"}
|
||||
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep, imdbid]
|
||||
movie-search: [q, imdbid]
|
||||
|
||||
settings:
|
||||
- name: username
|
||||
type: text
|
||||
label: Username
|
||||
- name: password
|
||||
type: password
|
||||
label: Password
|
||||
- name: info
|
||||
type: info
|
||||
label: ""
|
||||
default: For best results disable the torrent name tooltip (User CP/Tracker Settings/Torrents Page). Otherwise long release names will be cut off.
|
||||
|
||||
login:
|
||||
path: takelogin.php
|
||||
method: post
|
||||
@@ -54,7 +82,11 @@
|
||||
args: "Ratio:\\s(.*?)\\s\\s"
|
||||
|
||||
search:
|
||||
path: /torrents.php
|
||||
paths:
|
||||
- path: torrents.php
|
||||
categorymappings: ["!", 410, 429, 424, 430, 426, 437, 431, 432, 436, 425, 433, 411, 412, 413]
|
||||
- path: adult.php
|
||||
categorymappings: [410, 429, 424, 430, 426, 437, 431, 432, 436, 425, 433, 411, 412, 413]
|
||||
method: post
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}cat{{.}}=1&{{end}}"
|
||||
@@ -67,7 +99,10 @@
|
||||
rows:
|
||||
selector: table.torrents > tbody > tr:has(table.torrentname)
|
||||
fields:
|
||||
title: # shortened for long release names
|
||||
selector: a[href^="details.php?id="] > b
|
||||
title:
|
||||
optional: true # not available if IMDB tooltips are turned on
|
||||
selector: a[title][href^="details.php?id="]
|
||||
attribute: title
|
||||
category:
|
||||
@@ -77,7 +112,7 @@
|
||||
- name: querystring
|
||||
args: cat
|
||||
details:
|
||||
selector: a[title][href^="details.php?id="]
|
||||
selector: a[href^="details.php?id="]
|
||||
attribute: href
|
||||
download:
|
||||
selector: a[href^="download.php?id="]
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user