Compare commits

...

115 Commits

Author SHA1 Message Date
Garfield69
266568e4ce add dark-shadow a Private German site. resolves #4573 2019-03-11 11:59:15 +13:00
Garfield69
3378895b4c dragonworldreloaded: fix date parsing 2019-03-11 11:58:05 +13:00
Garfield69
d847b93418 gods: update cats for uhd 2019-03-11 09:47:22 +13:00
Garfield69
e32f02a003 nethd: fix date parsing. resolves #4855 2019-03-11 08:10:04 +13:00
Garfield69
8b0cede8ee torrentseeds: update categories, fix date processing 2019-03-10 20:53:04 +13:00
Garfield69
9f77de381b add hdplus a private tracker. resolves #4843 2019-03-10 19:52:50 +13:00
Garfield69
e060c82cd3 beyondhd: add imdbid support (torznab and dashboard search) resolves #4850 2019-03-10 17:13:32 +13:00
flightlevel
43f0f03b05 Version bump for .NET core support 2019-03-10 12:31:28 +11:00
flightlevel
25c7d84f95 Update install instructions for Linux 2019-03-10 12:21:06 +11:00
flightlevel
37ccf7a7a9 Update build script for different systemd scripts 2019-03-10 12:11:53 +11:00
flightlevel
a2e92da5f6 Add systemd script for .NET Core version of Jackett 2019-03-10 12:06:18 +11:00
flightlevel
d1e57c25d6 Rename systemd to include Mono 2019-03-10 11:59:32 +11:00
Garfield69
db2ba3ba0b digitalcore: update music categories 2019-03-10 13:40:32 +13:00
Joachim Bergstrøm
902961dc5a add digitalcore a Private tracker. (#4847) resolves #4808
Add support for digitalcore.club private tracker
Update README.md
2019-03-10 12:45:03 +13:00
Garfield69
689568d147 beyondhd: add andmatch #4828 2019-03-10 08:08:42 +13:00
Garfield69
1cd05963df beyondhd: now searching using searchin=descr&incldead=1 #4828 2019-03-09 19:53:47 +13:00
Garfield69
fbb3c1bdfc xtremezone is no longer semi-private, invites are needed for registration. 2019-03-09 17:00:34 +13:00
Garfield69
de5b26032e nyaa-pantsu: add alternate domain 2019-03-09 16:12:37 +13:00
Garfield69
0761ad7aee delete idopeclone: no longer suitable for cardigann processing
needs to be rewritten in c# see #4841
2019-03-09 15:53:48 +13:00
Garfield69
6cce59126b btkitty: new domain .pet 2019-03-09 15:06:00 +13:00
Garfield69
347191ab6a readme: note that the omdb is used for the aggregate Indexer. 2019-03-08 20:20:24 +13:00
Garfield69
afac5ad1cf tvstore: prevent index-out-of-range-exception 2019-03-08 20:00:04 +13:00
Garfield69
fa10c625dd delete torrentcouch
no longer suppliying .torrent or magnet
2019-03-08 18:19:28 +13:00
Garfield69
c546fd7ac8 gktorrent: back to .tv domain. 2019-03-08 17:41:01 +13:00
Garfield69
fc96965e54 awesome-hd: correct modes. (untested) 2019-03-08 16:05:34 +13:00
flightlevel
feaf5d4361 Publish Linux ARM builds 2019-03-07 21:11:06 +11:00
flightlevel
f146b3eaa6 Code tidy 2019-03-06 21:25:06 +11:00
flightlevel
d07b6ae863 Enable Linux x64 build 2019-03-06 21:18:28 +11:00
flightlevel
a25f2016dc Make Mono.Posix usage conditional on .NET Core 2019-03-06 21:16:20 +11:00
flightlevel
a5f0e2b5db Code tidy up 2019-03-06 20:20:32 +11:00
flightlevel
6ac9555cb5 Make parameter type HttpRequest
Code tidy
2019-03-06 20:11:50 +11:00
flightlevel
e7d9360b51 Disable Mono.Posix 2019-03-06 19:51:59 +11:00
thetennismaster
5a7091075e Add TotallyKids.tv definition. Resolves #4 (#4825)
* Add TotallyKids.tv definition. Resolves #4
* Add TotallyKids (TK) to the README
2019-03-06 18:10:33 +13:00
flightlevel
2270b13435 Trigger build 2019-03-06 13:05:12 +11:00
flightlevel
80a99ce69f Don't use Path.Combine for Linux paths 2019-03-06 12:59:14 +11:00
flightlevel
c54cbb4cbe Trigger build 2019-03-06 12:32:27 +11:00
flightlevel
de55e6e14e Log paths for debugging 2019-03-06 12:23:03 +11:00
Garfield69
0983540493 Merge branch 'master' of https://github.com/Jackett/Jackett 2019-03-06 13:41:11 +13:00
Garfield69
6cc262a6d3 torrent9: drop apostrophes on keywords. resolves #4822 2019-03-06 13:40:35 +13:00
flightlevel
2484ff16f3 Enable updater on .NET Core 2019-03-06 11:26:38 +11:00
Garfield69
4e1d7ac09b Revert "eztv: fetch magnets from details page. resolves #4813"
This reverts commit a84b1dce4d.
2019-03-06 13:00:28 +13:00
flightlevel
b8aa2a16dd Make execute permission conditional on .NET Core 2019-03-05 22:09:20 +11:00
flightlevel
cf7ca97f9c Make jackett and JackettUpdater executable 2019-03-05 21:25:37 +11:00
Garfield69
cc01b0ca05 add sharingue a Brazilian private tracker. resolves #4817 2019-03-05 19:37:46 +13:00
Garfield69
a84b1dce4d eztv: fetch magnets from details page. resolves #4813 2019-03-05 07:25:56 +13:00
flightlevel
be54f1a532 Fix copy/paste error 2019-03-04 17:52:17 +11:00
flightlevel
064786f379 Disable macOS .NET Core builds for now 2019-03-04 17:44:05 +11:00
Garfield69
9d140b3ab4 beyondhd: set freeleech resolves #4809 2019-03-04 15:40:10 +13:00
Garfield69
a65d855cc4 torrent-turk: fix login form. resolves #4334
switch to new domain .co
also added missing cxategories
fix date processing
add missing volumefactors
2019-03-04 15:34:23 +13:00
Garfield69
2698ac2907 torrentgalaxyorg: new result selectors. resolves #4805 2019-03-04 08:33:41 +13:00
Garfield69
28971c2303 scenerush: add categories. resolves #1775
correct login error meesage detection
upgrade to https
correct date parsing
switch browse post to get
2019-03-04 07:23:30 +13:00
Garfield69
6428a7134b classix: use alternate method of andmatch. for #4788 2019-03-04 06:00:02 +13:00
flightlevel
b33f5764ef Perform Linux build first 2019-03-03 17:42:09 +11:00
flightlevel
ebb855bf45 Release notes for linux 2019-03-03 17:32:47 +11:00
flightlevel
9e90edd397 Linux release notes 2019-03-03 17:22:34 +11:00
flightlevel
ee2743cdc9 Re-enable Windows building 2019-03-03 17:06:14 +11:00
flightlevel
a9731b036c Update file permissions 2019-03-03 16:53:40 +11:00
flightlevel
58ed5421ec Appveyor.yml: Fix casing 2019-03-03 16:35:00 +11:00
flightlevel
dc25480844 Appveyor test casing 2019-03-03 16:31:16 +11:00
flightlevel
789d168648 Build.cake line endings 2019-03-03 16:19:00 +11:00
flightlevel
f6668c9777 Test linux only build 2019-03-03 16:09:55 +11:00
flightlevel
5903e6abdf Enable updater for .NET Core on macOS 2019-03-03 16:09:17 +11:00
flightlevel
0de4c1da43 Push artifacts on Appveyor Linux 2019-03-03 15:51:59 +11:00
flightlevel
53bd7ce0c4 Updater: Add logic for .NET Core 2019-03-03 15:44:18 +11:00
flightlevel
4d4c9fe645 Improve build instructions 2019-03-03 15:32:55 +11:00
flightlevel
caf583a684 Package update 2019-03-03 15:23:33 +11:00
flightlevel
b445072a4d TVStore: Throw exception 2019-03-03 15:09:51 +11:00
flightlevel
82617f961d Force Github update deploy
Trying to avoid downloading artifacts in the second Appveyor job
2019-03-03 15:09:26 +11:00
flightlevel
c28df96332 Build updater for .NET Core macOS 2019-03-03 15:01:07 +11:00
Garfield69
88c6c4af6e classix: add andmatch. resolves #4788 2019-03-02 17:13:22 +13:00
Garfield69
df49bb8578 asiancinema: fix #4798 2019-03-02 13:15:39 +13:00
Garfield69
a968913bc4 add pthome a chinese private tracker. resolves #4795 2019-03-02 09:09:04 +13:00
Jorman
5c9880e410 ilcorsaronero: new domain .live (#4794)
Changed domain
2019-03-01 10:29:48 +13:00
morpheus133
d7af20d4f6 ncore: add offset support (#4792) resolves #4778
* add offset support to ncore indexer
* small correction related to add .hun tag to torrents
* DivideByZeroException  at torrent_per_page
2019-03-01 07:23:00 +13:00
xfouloux
8dc832d64a yggtorrent: tidy up keyword processing (#4791)
trimed stuff on .Keyword in keywordsfilters instead of re_replace in path because it caused having %20%20 in search .Keyword instead of having only one
2019-02-28 22:06:40 +13:00
Garfield69
91b87ee7be 7tor: fix TEST mode for #4784
the getnew search does not appear to be working any longer, so in no keywords are supplied we will use  TEST instead. Not ideal but better than no-results = error.
2019-02-28 13:19:19 +13:00
Garfield69
ee8fc6a78f bigtorrent: fix TEST mode for #1219
and also return a login error message
2019-02-28 10:05:20 +13:00
Garfield69
18f48cb04b icetorrent: attempt to fix for #4783 2019-02-28 09:42:23 +13:00
Garfield69
dd64739af6 torrentbd: attempt to fix login. #1709 #4781 2019-02-28 08:20:13 +13:00
Garfield69
05c4d1e331 polishtracker: display email on login config. resolves #4780 2019-02-28 07:41:53 +13:00
Garfield69
f9ad475aa8 torrent9: add secondary domain 2019-02-27 17:41:54 +13:00
Garfield69
ad17897edd elitetorrent-biz: drop index.php from search path. 2019-02-27 16:10:28 +13:00
SpookyDex
2356ef3837 torrentsectorcrew: new domain .org (#4776) 2019-02-27 07:16:20 +13:00
Garfield69
b63e97fecd torrentscsv: add torznab elements guid and comments for sonarr/radarr. resolves #4774 2019-02-26 13:41:37 +13:00
Garfield69
c025a98cbf skytorrentsclone: update search keyword. resolves #4763 2019-02-26 12:40:40 +13:00
Garfield69
0c84507b51 tp2: add note about categories for Sonarr or Radarr. 2019-02-26 12:30:49 +13:00
Garfield69
875d7a005e EliteTracker: add CA bypass for #4769 2019-02-25 21:50:45 +13:00
Garfield69
b1c25d4c5b gdf76: prevent log errors 2019-02-25 19:04:42 +13:00
Garfield69
5ef6b8601a puntotorrent & unionfansub: handle size 1.018,29 MB 2019-02-25 18:54:31 +13:00
Garfield69
a512a1e6b5 alein: selector adjustments to prevent log errors. 2019-02-25 17:39:11 +13:00
Garfield69
5ba93dd9c2 add racingforme a Private tracker for racing. resolves #1351 2019-02-25 08:28:51 +13:00
snamds
5216b6ece7 Newpct: changed Download link format (#4758) resolves #4757 2019-02-24 11:52:31 +13:00
Garfield69
eb5c8f4dcd solidtorrents: fix cat database 2019-02-24 08:32:56 +13:00
Garfield69
8a6ba04688 TVstore: handle dashboard SnnEnn searching
and if no query supplied, then its a test so juest fetcch 20 entries to shorten response time to 30s (previously set to 100 would cause timeout failure on sonarr indexer test).
2019-02-23 22:01:49 +13:00
Garfield69
287ad3a995 nnm-club: new CA bypass 2019-02-23 19:51:54 +13:00
Garfield69
00494bdac1 add solidtorrents: a Public meta-search engine. resolves #4751 2019-02-23 16:06:42 +13:00
Garfield69
4189aeac0e TVstore: add cats tvhd and tvsd
to match the returned categories processed via the call of TvCategoryParser.ParseTvShowQuality
2019-02-23 08:14:53 +13:00
kaso17
5f66b1a297 RARBG: fix title decoding 2019-02-22 18:33:19 +01:00
kaso17
ad77068a7b RARBG: make torrent download link optional 2019-02-22 18:28:42 +01:00
kaso17
75d53b4026 improve certificate validation error handling 2019-02-22 17:42:42 +01:00
kaso17
a4cd5e0047 The Shinning: fix legacy urls 2019-02-22 17:10:47 +01:00
kaso17
eccafdf4af XSpeeds: update categories
fixes #4519
2019-02-22 17:02:30 +01:00
kaso17
a7fab04e42 add imdbid to tv-search 2019-02-22 16:03:29 +01:00
kaso17
95e17d1741 TorrentCCF: update URL 2019-02-22 15:53:30 +01:00
morpheus133
a6c821762a TVstore: Correct Sonar Test (#4745) 2019-02-22 21:06:27 +13:00
morpheus133
e66a839fb3 add TVstore a Hungarian Private tracker for TV #2590 (#4738)
* Initial version for TvStore.me (#2590)
Only freeleech and upload/download factor handling is needed.
2019-02-22 20:12:15 +13:00
Garfield69
1a8b48f4dc karagarga: update date parsing 2019-02-22 18:52:17 +13:00
Garfield69
e32baf18a4 spacetorrent: they have simplyfied categories and dropped seelders and leechers from main result page 2019-02-22 16:16:25 +13:00
Garfield69
486a5313e4 gktorrent: new domain .cx 2019-02-22 15:40:20 +13:00
Garfield69
79b262569f cpabien: new domain .bz 2019-02-22 15:38:40 +13:00
buckmelanoma
9a2a019ff5 torrents.csv: Fixed categories, updated tracker list (#4744) 2019-02-22 13:42:39 +13:00
Garfield69
2dc4582830 2fast4you: update categories, as per #4743 2019-02-22 07:39:03 +13:00
Garfield69
48d7ce271b 3evils: updates resolves #4737 2019-02-21 20:30:11 +13:00
Garfield69
11acfddd64 theshinning: update for unit3d server. resolves #4735 2019-02-21 15:40:10 +13:00
Garfield69
23f36bb0f8 nostalgic: drop debug logging 2019-02-21 08:02:57 +13:00
79 changed files with 2534 additions and 686 deletions

View File

@@ -17,7 +17,8 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
#### Supported Systems
* Windows using .NET 4.6.1 or above [Download here](https://www.microsoft.com/net/framework/versions/net461).
* Linux and macOS using Mono 5.8 or above. [Download here](http://www.mono-project.com/download/).
* Linux
* macOS using Mono 5.8 or above. [Download here](http://www.mono-project.com/download/).
### Supported Public Trackers
* 1337x
@@ -39,7 +40,6 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
* Frozen Layer
* GkTorrent
* Horrible Subs
* IdopeClone
* Il Corsaro Nero <!-- maintained by bonny1992 -->
* Il Corsaro Blu
* Isohunt2
@@ -61,13 +61,13 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
* shokweb
* ShowRSS
* SkyTorrentsClone
* SolidTorrents
* sukebei.Nyaa.si
* sukebei-Pantsu
* The Pirate Bay (TPB)
* TNTVillage <!-- maintained by bonny1992 -->
* Tokyo Tosho
* Torlock
* TorrentCouch
* Torrent Downloads (TD)
* TorrentFunk
* TorrentGalaxy.org (TGx)
@@ -171,9 +171,11 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
* Classix
* CrnaBerza
* DanishBits (DB)
* Dark-Shadow
* DataScene (DS)
* DesiTorrents
* Diablo Torrent
* DigitalCore
* DigitalHive
* DivTeam
* DocumentaryTorrents (DT)
@@ -220,6 +222,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
* HDCity
* HDHome (HDBigger)
* HDME
* HDplus
* HDSky
* HDTorrents.it
* Hebits
@@ -270,9 +273,11 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
* Psytorrents
* PT99
* PTFiles (PTF)
* PThome
* PuntoTorrent
* PWTorrents (PWT)
* Racing4Everyone (R4E)
* RacingForMe (RFM)
* Redacted (PassTheHeadphones)
* Red Star Torrent (RST)
* Redtopia (RED)
@@ -290,6 +295,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
* Secret Cinema
* Shareisland
* ShareSpaceDB
* Sharingue
* Shazbat
* Shellife (SL)
* SpaceTorrent
@@ -330,12 +336,14 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
* Torrent-Syndikat
* TOrrent-tuRK (TORK)
* TorViet (HDVNBits)
* TotallyKids (TK)
* ToTheGlory
* TranceTraffic
* Trezzor
* TurkTorrent (TT)
* TV Chaos UK (TVCUK)
* TV-Vault
* TVstore
* u-torrents (SceneFZ)
* UHDBits
* Ultimate Gamer Club (UGC)
@@ -386,7 +394,24 @@ When installed as a service the tray icon acts as a way to open/start/stop Jacke
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
### Install on Linux (AMDx64)
1. Download and extract the latest `Jackett.Binaries.LinuxAMDx64.tar.gz` release from the [releases page](https://github.com/Jackett/Jackett/releases) and run Jackett with the command `./jackett`
2. (Optional) To install Jackett as a service, open the Terminal and run `sudo ./install_service_systemd.sh` You need root permissions to install the service. The service will start on each logon. You can always stop it by running `systemctl stop jackett.service` from Terminal. You can start it again it using `systemctl start jackett.service`. Logs are stored as usual under `~/.config/Jackett/log.txt` and also in `journalctl -u jackett.service`.
On most operating systems all the required dependencies will already be present. In case they are not, you can refer to this page https://docs.microsoft.com/en-us/dotnet/core/linux-prerequisites?tabs=netcore2x#linux-distribution-dependencies
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.
### Install on Linux (ARMv7 or above)
1. Download and extract the latest `Jackett.Binaries.LinuxARM32.tar.gz` or `Jackett.Binaries.LinuxARM64.tar.gz` (32 bit is the most common on ARM) release from the [releases page](https://github.com/Jackett/Jackett/releases) and run Jackett with the command `./jackett`
2. (Optional) To install Jackett as a service, open the Terminal and run `sudo ./install_service_systemd.sh` You need root permissions to install the service. The service will start on each logon. You can always stop it by running `systemctl stop jackett.service` from Terminal. You can start it again it using `systemctl start jackett.service`. Logs are stored as usual under `~/.config/Jackett/log.txt` and also in `journalctl -u jackett.service`.
On most operating systems all the required dependencies will already be present. In case they are not, you can refer to this page https://docs.microsoft.com/en-us/dotnet/core/linux-prerequisites?tabs=netcore2x#linux-distribution-dependencies
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 Linux (ARMv6 or below)
1. Install [Mono 5.8](http://www.mono-project.com/download/#download-lin) or better (using the latest stable release is recommended)
* Follow the instructions on the mono website and install the `mono-devel` and the `ca-certificates-mono` packages.
* On Red Hat/CentOS/openSUSE/Fedora the `mono-locale-extras` package is also required.
@@ -395,21 +420,12 @@ Jackett can also be run from the command line if you would like to see log messa
* Redhat/Fedora: `yum install libcurl-devel`
* For other distros see the [Curl docs](http://curl.haxx.se/dlwiz/?type=devel).
3. Download and extract the latest `Jackett.Binaries.Mono.tar.gz` release from the [releases page](https://github.com/Jackett/Jackett/releases) and run Jackett using mono with the command `mono --debug JackettConsole.exe`.
Detailed instructions for [Ubuntu 14.x](http://www.htpcguides.com/install-jackett-on-ubuntu-14-x-for-custom-torrents-in-sonarr/) and [Ubuntu 15.x](http://www.htpcguides.com/install-jackett-ubuntu-15-x-for-custom-torrents-in-sonarr/)
4. (Optional) To install Jackett as a service, open the Terminal and run `sudo ./install_service_systemd_mono.sh` You need root permissions to install the service. The service will start on each logon. You can always stop it by running `systemctl stop jackett.service` from Terminal. You can start it again it using `systemctl start jackett.service`. Logs are stored as usual under `~/.config/Jackett/log.txt` and also in `journalctl -u jackett.service`.
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.
Mono must be compiled with the Roslyn compiler (default), using MCS will cause "An error has occurred." errors (See https://github.com/Jackett/Jackett/issues/2704).
### Install as service
1. Install Jackett with the steps from above.
2. Open the Terminal and run `sudo ./install_service_systemd.sh` You need root permissions to install the service.
2. 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 `systemctl stop jackett.service` from Terminal. You can start it again it using `systemctl start jackett.service`.
Logs are stored as usual under `~/.config/Jackett/log.txt` and also in `journalctl -u jackett.service`.
### Installation on Linux via Ansible
On a RHEL/Centos 7 system: [linuxhq.jackett](https://galaxy.ansible.com/linuxhq/jackett)
@@ -484,7 +500,7 @@ location /jackett {
The logfiles (log.txt/updater.txt) are stored in `%ProgramData%\Jackett` on Windows and `~/.config/Jackett/` on Linux/macOS.
## Configuring OMDb
This feature is used as a fallback to get the movie/series title if only the IMDB ID is provided in the request.
This feature is used as a fallback (when using the aggregate Indexer) to get the movie/series title if only the IMDB ID is provided in the request.
To use it, please just request a free API key on [OMDb](http://www.omdbapi.com/apikey.aspx) (1,000 daily requests limit) and paste the key in Jackett
## Creating an issue
@@ -511,6 +527,8 @@ All contributions are welcome just send a pull request.
### Windows
* Install the .NET Core [SDK](https://www.microsoft.com/net/download/windows)
* Clone Jackett
* From the `src` directory, run `dotnet restore`
* Open the Jackett solution in Visual Studio 2017 (version 15.9 or above)
* Right click on the Jackett solution and click 'Rebuild Solution' to restore nuget packages
* Select Jackett.Server as startup project

View File

@@ -1,8 +1,8 @@
version: 0.10.{build}
version: 0.11.{build}
skip_tags: true
image:
- Visual Studio 2017
image:
- Ubuntu
- Visual Studio 2017
environment:
APPVEYOR_YML_DISABLE_PS_LINUX: true
configuration: Release
@@ -28,12 +28,13 @@ before_deploy:
- ps: ${env:release_description} = ( Get-Content -LiteralPath BuildOutput/ReleaseNotes.txt -Encoding UTF8 ) -join "`n";
deploy:
- provider: GitHub
tag: v$(appveyor_build_version)
tag: v$(APPVEYOR_BUILD_VERSION)
description: $(release_description)
auth_token:
secure: hOg+16YTIbq4kO9u4D1YVOTbWDqgCX6mAQYMbnmBBSw2CiUsZh7OKbupoUb3FtWa
artifact: /^(?:(?![Ee]xperimental).)*$/
draft: true
force_update: true
on:
branch: master
notifications:

View File

@@ -14,9 +14,11 @@ var configuration = Argument("configuration", "Debug");
// Define directories.
var workingDir = MakeAbsolute(Directory("./"));
var artifactsDirName = "Artifacts";
var testResultsDirName = "TestResults";
var netCoreFramework = "netcoreapp2.2";
string artifactsDirName = "Artifacts";
string testResultsDirName = "TestResults";
string netCoreFramework = "netcoreapp2.2";
string serverProjectPath = "./src/Jackett.Server/Jackett.Server.csproj";
string updaterProjectPath = "./src/Jackett.Updater/Jackett.Updater.csproj";
//////////////////////////////////////////////////////////////////////
// TASKS
@@ -89,7 +91,6 @@ Task("Package-Windows-Full-Framework")
.IsDependentOn("Run-Unit-Tests")
.Does(() =>
{
string serverProjectPath = "./src/Jackett.Server/Jackett.Server.csproj";
string buildOutputPath = "./BuildOutput/net461/win7-x86/Jackett";
DotNetCorePublish(serverProjectPath, "net461", "win7-x86", buildOutputPath);
@@ -119,7 +120,6 @@ Task("Package-Mono-Full-Framework")
.IsDependentOn("Run-Unit-Tests")
.Does(() =>
{
string serverProjectPath = "./src/Jackett.Server/Jackett.Server.csproj";
string buildOutputPath = "./BuildOutput/net461/linux-x64/Jackett";
DotNetCorePublish(serverProjectPath, "net461", "linux-x64", buildOutputPath);
@@ -127,7 +127,7 @@ Task("Package-Mono-Full-Framework")
CopyFiles("./src/Jackett.Updater/bin/" + configuration + "/net461" + "/JackettUpdater.*", buildOutputPath); //builds against multiple frameworks
CopyFileToDirectory("./install_service_macos", buildOutputPath);
CopyFileToDirectory("./install_service_systemd.sh", buildOutputPath);
CopyFileToDirectory("./install_service_systemd_mono.sh", buildOutputPath);
CopyFileToDirectory("./Upstart.config", buildOutputPath);
//There is an issue with Mono 5.8 (fixed in Mono 5.12) where its expecting to use its own patched version of System.Net.Http.dll, instead of the version supplied in folder
@@ -154,30 +154,37 @@ Task("Package-DotNetCore-macOS")
.Does(() =>
{
string runtimeId = "osx-x64";
string serverProjectPath = "./src/Jackett.Server/Jackett.Server.csproj";
string buildOutputPath = $"./BuildOutput/{netCoreFramework}/{runtimeId}/Jackett";
string updaterOutputPath = buildOutputPath + "/Updater";
DotNetCorePublish(serverProjectPath, netCoreFramework, runtimeId, buildOutputPath);
DotNetCorePublish(updaterProjectPath, netCoreFramework, runtimeId, updaterOutputPath);
CopyFiles(updaterOutputPath + "/JackettUpdater*", buildOutputPath);
DeleteDirectory(updaterOutputPath, new DeleteDirectorySettings {Recursive = true, Force = true});
CopyFileToDirectory("./install_service_macos", buildOutputPath);
Gzip($"./BuildOutput/{netCoreFramework}/{runtimeId}", $"./{artifactsDirName}", "Jackett", "Experimental.Jackett.Binaries.macOS.tar.gz");
});
Task("Package-DotNetCore-LinuxAMD64")
Task("Package-DotNetCore-LinuxAMDx64")
.IsDependentOn("Clean")
.Does(() =>
{
string runtimeId = "linux-x64";
string serverProjectPath = "./src/Jackett.Server/Jackett.Server.csproj";
string buildOutputPath = $"./BuildOutput/{netCoreFramework}/{runtimeId}/Jackett";
string updaterOutputPath = buildOutputPath + "/Updater";
DotNetCorePublish(serverProjectPath, netCoreFramework, runtimeId, buildOutputPath);
CopyFileToDirectory("./install_service_systemd.sh", buildOutputPath);
CopyFileToDirectory("./Upstart.config", buildOutputPath);
DotNetCorePublish(updaterProjectPath, netCoreFramework, runtimeId, updaterOutputPath);
CopyFiles(updaterOutputPath + "/JackettUpdater*", buildOutputPath);
DeleteDirectory(updaterOutputPath, new DeleteDirectorySettings {Recursive = true, Force = true});
Gzip($"./BuildOutput/{netCoreFramework}/{runtimeId}", $"./{artifactsDirName}", "Jackett", "Experimental.Jackett.Binaries.LinuxAMD64.tar.gz");
CopyFileToDirectory("./install_service_systemd.sh", buildOutputPath);
Gzip($"./BuildOutput/{netCoreFramework}/{runtimeId}", $"./{artifactsDirName}", "Jackett", "Jackett.Binaries.LinuxAMDx64.tar.gz");
});
Task("Package-DotNetCore-LinuxARM32")
@@ -185,15 +192,18 @@ Task("Package-DotNetCore-LinuxARM32")
.Does(() =>
{
string runtimeId = "linux-arm";
string serverProjectPath = "./src/Jackett.Server/Jackett.Server.csproj";
string buildOutputPath = $"./BuildOutput/{netCoreFramework}/{runtimeId}/Jackett";
string updaterOutputPath = buildOutputPath + "/Updater";
DotNetCorePublish(serverProjectPath, netCoreFramework, runtimeId, buildOutputPath);
CopyFileToDirectory("./install_service_systemd.sh", buildOutputPath);
CopyFileToDirectory("./Upstart.config", buildOutputPath);
DotNetCorePublish(updaterProjectPath, netCoreFramework, runtimeId, updaterOutputPath);
CopyFiles(updaterOutputPath + "/JackettUpdater*", buildOutputPath);
DeleteDirectory(updaterOutputPath, new DeleteDirectorySettings {Recursive = true, Force = true});
Gzip($"./BuildOutput/{netCoreFramework}/{runtimeId}", $"./{artifactsDirName}", "Jackett", "Experimental.Jackett.Binaries.LinuxARM32.tar.gz");
CopyFileToDirectory("./install_service_systemd.sh", buildOutputPath);
Gzip($"./BuildOutput/{netCoreFramework}/{runtimeId}", $"./{artifactsDirName}", "Jackett", "Jackett.Binaries.LinuxARM32.tar.gz");
});
Task("Package-DotNetCore-LinuxARM64")
@@ -201,22 +211,25 @@ Task("Package-DotNetCore-LinuxARM64")
.Does(() =>
{
string runtimeId = "linux-arm64";
string serverProjectPath = "./src/Jackett.Server/Jackett.Server.csproj";
string buildOutputPath = $"./BuildOutput/{netCoreFramework}/{runtimeId}/Jackett";
string updaterOutputPath = buildOutputPath + "/Updater";
DotNetCorePublish(serverProjectPath, netCoreFramework, runtimeId, buildOutputPath);
CopyFileToDirectory("./install_service_systemd.sh", buildOutputPath);
CopyFileToDirectory("./Upstart.config", buildOutputPath);
Gzip($"./BuildOutput/{netCoreFramework}/{runtimeId}", $"./{artifactsDirName}", "Jackett", "Experimental.Jackett.Binaries.LinuxARM64.tar.gz");
DotNetCorePublish(updaterProjectPath, netCoreFramework, runtimeId, updaterOutputPath);
CopyFiles(updaterOutputPath + "/JackettUpdater*", buildOutputPath);
DeleteDirectory(updaterOutputPath, new DeleteDirectorySettings {Recursive = true, Force = true});
CopyFileToDirectory("./install_service_systemd.sh", buildOutputPath);
Gzip($"./BuildOutput/{netCoreFramework}/{runtimeId}", $"./{artifactsDirName}", "Jackett", "Jackett.Binaries.LinuxARM64.tar.gz");
});
Task("Appveyor-Push-Artifacts")
.IsDependentOn("Clean")
.Does(() =>
{
if (AppVeyor.IsRunningOnAppVeyor && IsRunningOnWindows())
if (AppVeyor.IsRunningOnAppVeyor)
{
foreach (var file in GetFiles(workingDir + $"/{artifactsDirName}/*"))
{
@@ -280,10 +293,10 @@ Task("Release-Notes")
Task("Windows-Environment")
.IsDependentOn("Package-Windows-Full-Framework")
.IsDependentOn("Package-Mono-Full-Framework")
.IsDependentOn("Package-DotNetCore-macOS")
.IsDependentOn("Package-DotNetCore-LinuxAMD64")
.IsDependentOn("Package-DotNetCore-LinuxARM32")
.IsDependentOn("Package-DotNetCore-LinuxARM64")
//.IsDependentOn("Package-DotNetCore-macOS")
//.IsDependentOn("Package-DotNetCore-LinuxAMDx64")
//.IsDependentOn("Package-DotNetCore-LinuxARM32")
//.IsDependentOn("Package-DotNetCore-LinuxARM64")
.IsDependentOn("Appveyor-Push-Artifacts")
.IsDependentOn("Release-Notes")
.Does(() =>
@@ -293,7 +306,7 @@ Task("Windows-Environment")
Task("Linux-Environment")
.IsDependentOn("Package-DotNetCore-macOS")
.IsDependentOn("Package-DotNetCore-LinuxAMD64")
.IsDependentOn("Package-DotNetCore-LinuxAMDx64")
.IsDependentOn("Package-DotNetCore-LinuxARM32")
.IsDependentOn("Package-DotNetCore-LinuxARM64")
.IsDependentOn("Appveyor-Push-Artifacts")
@@ -380,7 +393,8 @@ private void Gzip(string sourceFolder, string outputDirectory, string tarCdirect
{
RunLinuxCommand("find", MakeAbsolute(Directory(sourceFolder)) + @" -type d -exec chmod 755 {} \;");
RunLinuxCommand("find", MakeAbsolute(Directory(sourceFolder)) + @" -type f -exec chmod 644 {} \;");
//RunLinuxCommand("chmod", $"755 {MakeAbsolute(Directory(sourceFolder))} /Jackett/jackett");
RunLinuxCommand("chmod", $"755 {MakeAbsolute(Directory(sourceFolder))}/Jackett/jackett");
RunLinuxCommand("chmod", $"755 {MakeAbsolute(Directory(sourceFolder))}/Jackett/JackettUpdater");
RunLinuxCommand("tar", $"-C {sourceFolder} -zcvf {outputDirectory}/{tarFileName}.gz {tarCdirectoryOption}");
}
}

12
install_service_systemd.sh Executable file → Normal file
View File

@@ -13,23 +13,19 @@ systemctl stop ${jackettservice}
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?"
if [ ! -f ./jackett ]; then
echo "${BOLDRED}ERROR${NC}: Couldn't locate jackett. Is the script in the right directory?"
exit 1
fi
jackettdir="$(pwd)"
# Check if Jackett's owner is root
jackettuser="$(stat -c "%U" ./JackettConsole.exe)"
jackettuser="$(stat -c "%U" ./jackett)"
if [ "${jackettuser}" == "root" ]; then
echo "${BOLDRED}ERROR${NC}: Jackett shouldn't run as root. Please, change the owner of the Jackett directory."
exit 1
fi
# 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 [[ $(systemctl status ${jackettservice} | grep "active (running)") ]]; then
echo "${BOLDRED}ERROR${NC}: Jackett already seems to be running as a service. Please stop it before running this script again."
@@ -50,7 +46,7 @@ Type=simple
User=${jackettuser}
Group=${jackettuser}
WorkingDirectory=${jackettdir}
ExecStart=${monodir}/mono --debug ${jackettdir}/JackettConsole.exe --NoRestart
ExecStart=${jackettdir}/jackett --NoRestart
TimeoutStopSec=20
[Install]

View File

@@ -0,0 +1,82 @@
#!/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
jackettservice="jackett.service"
systemctl stop ${jackettservice}
# 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 Jackett's owner is root
jackettuser="$(stat -c "%U" ./JackettConsole.exe)"
if [ "${jackettuser}" == "root" ]; then
echo "${BOLDRED}ERROR${NC}: Jackett shouldn't run as root. Please, change the owner of the Jackett directory."
exit 1
fi
# 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 [[ $(systemctl status ${jackettservice} | grep "active (running)") ]]; 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 systemd service descriptor
cat >"/etc/systemd/system/${jackettservice}" <<EOL
[Unit]
Description=Jackett Daemon
After=network.target
[Service]
SyslogIdentifier=jackett
Restart=always
RestartSec=5
Type=simple
User=${jackettuser}
Group=${jackettuser}
WorkingDirectory=${jackettdir}
ExecStart=${monodir}/mono --debug ${jackettdir}/JackettConsole.exe --NoRestart
TimeoutStopSec=20
[Install]
WantedBy=multi-user.target
EOL
# Reload systemd daemon
systemctl daemon-reload
# Enable the service for following restarts
systemctl enable ${jackettservice}
# Run the service
systemctl start ${jackettservice}
# Check that it's running
if [[ $(systemctl status ${jackettservice} | grep "active (running)") ]]; then
echo "${BOLDGREEN}Agent successfully installed and launched!${NC}"
else
cat << EOL
${BOLDRED}ERROR${NC}: Could not launch service. 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}\`
Jackett user: \`${jackettuser}\`
EOL
fi

View File

@@ -15,11 +15,9 @@
- {id: 10, cat: TV/Anime, desc: "Animation: HD720P"}
- {id: 11, cat: TV/Anime, desc: "Animation: HD1080P"}
- {id: 56, cat: TV/Anime, desc: "Animation: DVDRip"}
- {id: 13, cat: TV/Anime, desc: "Animation: DVD"}
- {id: 18, cat: PC/0day, desc: "Applications: PC"}
- {id: 16, cat: PC/Games, desc: "Applications: Jeux"}
- {id: 19, cat: PC/Phone-Android, desc: "Applications: Android"}
- {id: 38, cat: PC/Phone-IOS, desc: "Applications: Mobile Phone"}
- {id: 17, cat: PC/0day, desc: "Applications: Autres"}
- {id: 67, cat: TV, desc: "Autres: Emission TV"}
- {id: 68, cat: TV/Sport, desc: "Autres: Sport"}
@@ -34,6 +32,7 @@
- {id: 53, cat: Books, desc: "E-Books: Livre Anglais"}
- {id: 52, cat: Books, desc: "E-Books: Revue - Journaux"}
- {id: 51, cat: Books, desc: "E-Books: BD"}
- {id: 95, cat: Movies, desc: "Films: Film Divx XviD"}
- {id: 66, cat: Movies, desc: "Films: VOSTFR"}
- {id: 71, cat: Movies/WEBDL, desc: "Films: WEB-DL"}
- {id: 65, cat: Movies, desc: "Films: VO"}
@@ -49,19 +48,13 @@
- {id: 92, cat: Movies/HD, desc: "Films: 4K"}
- {id: 69, cat: Movies/3D, desc: "Films: Film 3D"}
- {id: 3, cat: Movies/DVD, desc: "Films: DVDRIP"}
- {id: 4, cat: Movies/DVD, desc: "Films: DVD5"}
- {id: 5, cat: Movies/DVD, desc: "Films: DVD9"}
- {id: 91, cat: Movies/HD, desc: "Films: RemuX"}
- {id: 89, cat: Movies/HD, desc: "Films: BD/BR Rip"}
- {id: 88, cat: Movies/BluRay, desc: "Films: Full BD/BR"}
- {id: 77, cat: Other, desc: "GPS: Cartes"}
- {id: 78, cat: Other, desc: "GPS: Radars"}
- {id: 97, cat: Movies, desc: "Films: Cours Métrage"}
- {id: 79, cat: TV/Anime, desc: "Mangas: HD"}
- {id: 80, cat: TV/Anime, desc: "Mangas: HD VO"}
- {id: 81, cat: TV/Anime, desc: "Mangas: HD VOSTFR"}
- {id: 82, cat: TV/Anime, desc: "Mangas: DVDRIP"}
- {id: 83, cat: TV/Anime, desc: "Mangas: DVDRIP VO"}
- {id: 84, cat: TV/Anime, desc: "Mangas: DVDRIP VOSTFR"}
- {id: 85, cat: TV/Anime, desc: "Mangas: Web-DL"}
- {id: 86, cat: TV/Anime, desc: "Mangas: TV-RIP"}
- {id: 75, cat: Audio, desc: "Musique: Concert TVRip"}
@@ -70,6 +63,7 @@
- {id: 22, cat: Audio/MP3, desc: "Musique: Album MP3"}
- {id: 23, cat: Audio/Lossless, desc: "Musique: Album Flac"}
- {id: 64, cat: Audio, desc: "Musique: Mégamix Maison"}
- {id: 96, cat: Audio/MP3, desc: "Musique: PlayList MP3"}
- {id: 94, cat: Audio, desc: "Musique: Podcast"}
- {id: 58, cat: Audio, desc: "Musique: Concert"}
- {id: 93, cat: TV, desc: "Serie TV: Saison VOSTFR"}
@@ -80,6 +74,7 @@
- {id: 73, cat: TV/WEB-DL, desc: "Serie TV: WEB-DL"}
- {id: 7, cat: TV, desc: "Serie TV: Episode FR"}
- {id: 6, cat: TV, desc: "Serie TV: Saison FR"}
- {id: 98, cat: TV/Anime, desc: "Serie TV: Manga VOSTFR"}
modes:
search: [q]

View File

@@ -10,12 +10,24 @@
caps:
categorymappings:
- {id: 2, cat: Console, desc: "Games"}
- {id: 3, cat: Movies, desc: "Movies"}
- {id: 4, cat: Audio, desc: "Music"}
- {id: 9, cat: TV/Anime, desc: " Anime"}
- {id: 17, cat: TV, desc: " TV"}
- {id: 18, cat: PC, desc: "Appz"}
- {id: 65, cat: Books, desc: "Books"}
- {id: 27, cat: Console/NDS, desc: "Games/Nintendo-DS"}
- {id: 28, cat: Console/Other, desc: "Games/Switch"}
- {id: 42, cat: PC/Phone-Android, desc: "Mobile/Android"}
- {id: 44, cat: Movies/UHD, desc: "Movies/4K"}
- {id: 13, cat: Movies/BluRay, desc: "Movies/Bluray"}
- {id: 12, cat: Movies/DVD, desc: "Movies/DVD-R"}
- {id: 14, cat: Movies, desc: "Movies/Packs"}
- {id: 67, cat: Movies/HD, desc: "Movies/x264"}
- {id: 55, cat: Movies/HD, desc: "Movies/X265"}
- {id: 45, cat: Movies, desc: "Movies/Remux"}
- {id: 62, cat: Audio, desc: "Music/Audio"}
- {id: 32, cat: Audio, desc: "Music/Packs"}
- {id: 6, cat: TV, desc: "TV/Packs"}
- {id: 3, cat: TV/HD, desc: "TV/x264"}
- {id: 4, cat: TV/HD, desc: "TV/x265"}
- {id: 8, cat: TV/SD, desc: "TV/Xvid"}
- {id: 63, cat: PC/0day, desc: "Windows/Applications"}
modes:
search: [q]
@@ -80,31 +92,35 @@
size:
selector: td:nth-last-child(6)
files:
selector: td:nth-last-child(9)
selector: a[href^="filelist.php?id="]
grabs:
selector: td:nth-last-child(5)
selector: a[href^="snatches.php?id="]
filters:
- name: replace
args: ["Times", ""]
- name: regexp
args: "(\\d+)"
# 2 flavours of dates
date:
# Today<br />10:20 AM
# Yesterday<br />08:03 PM
# Today<br /> 10:20 AM
# Yesterday<br /> 08:03 PM
optional: true
selector: td:nth-last-child(7):contains("day")
date:
# Feb 14 2019<br />10:20 AM
# Feb 14 2019<br /> 10:20 AM
optional: true
selector: td:nth-last-child(7):not(:contains("day"))
filters:
- name: regex # drop break in between date and time
args: ["(.+?)<[^>]*>(.+?)","$1 $2"]
- name: dateparse
args: "Jan 2 2006 03:04 pm"
seeders:
selector: td:nth-last-child(4)
text: "0"
seeders:
optional: true
selector: a[href$="#seeders"]
leechers:
selector: td:nth-last-child(3)
text: "0"
leechers:
optional: true
selector: a[href$="#leechers"]
downloadvolumefactor:
case:
"b:contains(\"[FREE]\")": "0"

View File

@@ -67,9 +67,6 @@
path: /
selector: :has(a[href="logout.php"])
download:
selector: a[href^="download.php?id="]
search:
paths:
# http://alein.org/index.php?page=torrents&category=1%3B15%3B41%3B14%3B48%3B39%3B20%3B16%3B5%3B21%3B22%3B11&search=venom&active=1
@@ -81,22 +78,35 @@
active: "1"
rows:
selector: tr.trclass
selector: tr.trclass:not(:has(td.lista-cat-rec))
fields:
title:
selector: td.lista-list a
selector: td a[href*="id="]
details:
selector: td.lista-list a
selector: td a[href*="id="]
attribute: href
category:
selector: td.lista-cat a
selector: td a[href*="category="]
attribute: href
filters:
- name: querystring
args: category
download:
selector: td.lista-list a
selector: td a[href*="id="]
attribute: href
filters:
- name: querystring
args: id
- name: prepend
args: "download.php?id="
- name: append
args: "&f={{.Result.title}}.torrent"
banner:
selector: td a[href*="id="]
attribute: onmouseover
filters:
- name: regexp
args: "src=(.+?) width="
size:
selector: td:nth-child(6)
seeders:

View File

@@ -48,11 +48,11 @@
selector: table > tbody > tr
fields:
category:
selector: a[href*="/categories/"]
selector: a[href*="/category/"]
attribute: href
filters:
- name: regexp
args: "/categories/.*?\\.(\\d+)"
args: "/category/.*?\\.(\\d+)"
title:
selector: a.view-torrent
download:

View File

@@ -14,7 +14,9 @@
- {id: 2, cat: TV/HD, desc: "TV-Shows"}
modes:
searchstr: [q]
search: [q]
tv-search: [q, season, ep]
movie-search: [q]
settings:
- name: cookie

View File

@@ -49,7 +49,7 @@
sent: "yes"
returnto: "/"
error:
- selector: table:contains("Login failed!")
- selector: div.error
test:
path: index.php
@@ -61,7 +61,7 @@
- path: browse.php
inputs:
$raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
search: "{{ .Query.Keywords }}"
search: "{{if .Keywords}}{{ .Keywords }}{{else}} {{end}}"
rows:
selector: table#torrent_table > tbody > tr:has(a[href^="browse.php?cat="])
fields:

View File

@@ -5,8 +5,9 @@
language: en-us
type: public
encoding: UTF-8
followredirect: true
links:
- http://cnbtkitty.ws/
- http://btkitty.pet/
legacylinks:
- https://cnbtkitty.org/
- http://cnbtkitty.org/
@@ -14,6 +15,7 @@
- http://cnbtkitty.com/
- https://cnbtkitty.me/
- http://cnbtkitty.me/
- http://cnbtkitty.ws/
caps:
categorymappings:

View File

@@ -34,7 +34,7 @@
- path: torrents-search.php
inputs:
$raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
search: "{{ .Query.Keywords }}"
search: "{{if .Keywords}}\"{{.Keywords}}\"{{else}}{{end}}"
rows:
selector: table > tbody > tr:has(a[href^="torrents.php?cat="])
fields:

View File

@@ -7,7 +7,7 @@
encoding: UTF-8
followredirect: true
links:
- https://www.cpasbiens.cz/
- https://www.cpasbiens.bz/
legacylinks:
- http://www.cpasbiens.cc/
- http://www.cpabien.cm/
@@ -33,6 +33,7 @@
- http://www.cpasbien.io/
- https://www.cpabien.bz/
- https://www.cpabien.link/
- https://www.cpasbiens.cz/
caps:
categorymappings:

View File

@@ -0,0 +1,237 @@
---
site: dark-shadow
name: Dark-Shadow
description: "Dark-Shadow is a German Private site for TV / MOVIES / GENERAL"
language: de-de
type: private
encoding: UTF-8
links:
- https://dark-shadow.ml/
caps:
categorymappings:
# Film
- {id: 32, cat: Movies/HD, desc: "Film HD"}
- {id: 28, cat: Movies/SD, desc: "Film SD"}
- {id: 119, cat: Movies/DVD, desc: "Film DVD"}
- {id: 114, cat: Movies/UHD, desc: "Film 4K/2160p"}
- {id: 26, cat: Movies/3D, desc: "Film 3D"}
# Serien
- {id: 57, cat: TV/HD, desc: "Serien HD"}
- {id: 60, cat: TV/SD, desc: "Serien SD"}
- {id: 59, cat: TV, desc: "Serien Pack"}
- {id: 122, cat: TV, desc: "Serien Show"}
- {id: 123, cat: TV/Documentary, desc: "Serien Doku"}
# Doku
- {id: 14, cat: TV/Documentary, desc: "Doku HD"}
- {id: 15, cat: TV/Documentary, desc: "Doku SD"}
# Spiele
- {id: 17, cat: PC/Games, desc: "Spiele PC"}
- {id: 24, cat: Console, desc: "Spiele Konsole"}
- {id: 121, cat: Console, desc: "Spiele Wimmelbild"}
- {id: 126, cat: Console/Other, desc: "Spiele Mobil"}
# Musik
- {id: 110, cat: Audio/MP3, desc: "Musik MP3"}
- {id: 52, cat: Audio, desc: "Musik Pack"}
- {id: 48, cat: Audio/Lossless, desc: "Musik Flac"}
- {id: 120, cat: Audio/Video, desc: "Musik Video"}
# App
- {id: 12, cat: PC/0day, desc: "App PC"}
- {id: 125, cat: PC/Mac, desc: "App MacOS"}
- {id: 11, cat: PC/Phone-Other, desc: "App Mobil"}
# Sport
- {id: 61, cat: TV/Sport, desc: "Sport HD"}
- {id: 62, cat: TV/Sport, desc: "Sport SD"}
# Internal
- {id: 128, cat: Movies/HD, desc: "Internal Film HD"}
- {id: 129, cat: Movies/SD, desc: "Internal Film SD"}
- {id: 130, cat: TV/HD, desc: "Internal Serien HD"}
- {id: 131, cat: TV/SD, desc: "Internal Serien SD"}
- {id: 132, cat: Other, desc: "Internal Sonstiges"}
# Sonstiges
- {id: 64, cat: TV/Anime, desc: "Anime"}
- {id: 96, cat: Books/Ebook, desc: "e-Book"}
- {id: 63, cat: Audio/Audiobook, desc: "Hörbuch"}
- {id: 71, cat: Other, desc: "Anderes"}
# XXX
- {id: 73, cat: XXX/x264, desc: "XXX HD"}
- {id: 75, cat: XXX/Packs, desc: "XXX Pack"}
- {id: 76, cat: XXX/XviD, desc: "XXX SD"}
- {id: 124, cat: XXX/Other, desc: "XXX Clips"}
modes:
search: [q]
tv-search: [q, season, ep]
movie-search: [q]
settings:
- name: username
type: text
label: Username
- name: password
type: password
label: Password
- name: pin
type: text
label: Pin
login:
path: login.php
method: form
form: form[action="/login.php"]
cookies: ["JAVA=OK"] # avoid jscheck redirect
inputs:
username: "{{ .Config.username }}"
password: "{{ .Config.password }}"
pin: "{{ .Config.pin }}"
error:
- selector: div#login_error
test:
path: selection.php
download:
before:
path: ajax_det_poll.php
method: "post"
inputs:
set_thanks: "thanks"
det_id: "{{ .DownloadUri.Query.torrent }}"
ajax: "yes"
search:
paths:
- path: selection.php
inputs:
$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
search: "{{ .Keywords }}"
blah: "0"
orderby: "added"
sort: "desc"
rows:
selector: div.selection_wrap
fields:
download:
selector: a.selection_a
attribute: href
filters:
- name: replace
args: ["details.php?id=", "download.php?torrent="]
title:
selector: a.selection_a
details:
selector: a.selection_a
attribute: href
category:
selector: div.kat_cat_pic
case:
# Movies
":has(div.kat_cat_pic_name:contains(\"Movie\")):has(div.kat_cat_pic_name_b:contains(\"4K/2160p\"))": "114"
":has(div.kat_cat_pic_name:contains(\"Movie\")):has(div.kat_cat_pic_name_b:contains(\"DVD\"))": "119"
":has(div.kat_cat_pic_name:contains(\"Movie\")):has(div.kat_cat_pic_name_b:contains(\"HD\"))": "32"
":has(div.kat_cat_pic_name:contains(\"Movie\")):has(div.kat_cat_pic_name_b:contains(\"SD\"))": "28"
":has(div.kat_cat_pic_name:contains(\"Movie\")):has(div.kat_cat_pic_name_b:contains(\"3D\"))": "26"
# Serien
":has(div.kat_cat_pic_name:contains(\"Serien\")):has(div.kat_cat_pic_name_b:contains(\"SD\"))": "60"
":has(div.kat_cat_pic_name:contains(\"Serien\")):has(div.kat_cat_pic_name_b:contains(\"HD\"))": "57"
":has(div.kat_cat_pic_name:contains(\"Serien\")):has(div.kat_cat_pic_name_b:contains(\"Pack\"))": "59"
":has(div.kat_cat_pic_name:contains(\"Serien\")):has(div.kat_cat_pic_name_b:contains(\"Show\"))": "122"
":has(div.kat_cat_pic_name:contains(\"Serien\")):has(div.kat_cat_pic_name_b:contains(\"Doku\"))": "123"
# Musik
":has(div.kat_cat_pic_name:contains(\"Music\")):has(div.kat_cat_pic_name_b:contains(\"Flac\"))": "48"
":has(div.kat_cat_pic_name:contains(\"Music\")):has(div.kat_cat_pic_name_b:contains(\"MP3\"))": "110"
":has(div.kat_cat_pic_name:contains(\"Music\")):has(div.kat_cat_pic_name_b:contains(\"Pack\"))": "52"
":has(div.kat_cat_pic_name:contains(\"Music\")):has(div.kat_cat_pic_name_b:contains(\"Videos\"))": "120"
# Doku
":has(div.kat_cat_pic_name:contains(\"Doku\")):has(div.kat_cat_pic_name_b:contains(\"SD\"))": "15"
":has(div.kat_cat_pic_name:contains(\"Doku\")):has(div.kat_cat_pic_name_b:contains(\"HD\"))": "14"
# Games
":has(div.kat_cat_pic_name:contains(\"Game\")):has(div.kat_cat_pic_name_b:contains(\"PC\"))": "17"
":has(div.kat_cat_pic_name:contains(\"Game\")):has(div.kat_cat_pic_name_b:contains(\"Wimmelbild\"))": "121"
":has(div.kat_cat_pic_name:contains(\"Game\")):has(div.kat_cat_pic_name_b:contains(\"Konsole\"))": "24"
":has(div.kat_cat_pic_name:contains(\"Game\")):has(div.kat_cat_pic_name_b:contains(\"Mobil\"))": "126"
# App
":has(div.kat_cat_pic_name:contains(\"App\")):has(div.kat_cat_pic_name_b:contains(\"PC\"))": "12"
":has(div.kat_cat_pic_name:contains(\"App\")):has(div.kat_cat_pic_name_b:contains(\"MacOS\"))": "125"
":has(div.kat_cat_pic_name:contains(\"App\")):has(div.kat_cat_pic_name_b:contains(\"Mobil\"))": "11"
# Sport
":has(div.kat_cat_pic_name:contains(\"Sport\")):has(div.kat_cat_pic_name_b:contains(\"SD\"))": "62"
":has(div.kat_cat_pic_name:contains(\"Sport\")):has(div.kat_cat_pic_name_b:contains(\"HD\"))": "61"
# Sonstiges
":has(div.kat_cat_pic_name:contains(\"Sonstiges\")):has(div.kat_cat_pic_name_b:contains(\"Anime\"))": "64"
":has(div.kat_cat_pic_name:contains(\"Sonstiges\")):has(div.kat_cat_pic_name_b:contains(\"E-Book\"))": "96"
":has(div.kat_cat_pic_name:contains(\"Sonstiges\")):has(div.kat_cat_pic_name_b:contains(\"Hörbuch\"))": "63"
":has(div.kat_cat_pic_name:contains(\"Sonstiges\")):has(div.kat_cat_pic_name_b:contains(\"Other\"))": "71"
# XXX
":has(div.kat_cat_pic_name:contains(\"XXX\")):has(div.kat_cat_pic_name_b:contains(\"SD\"))": "76"
":has(div.kat_cat_pic_name:contains(\"XXX\")):has(div.kat_cat_pic_name_b:contains(\"HD\"))": "73"
":has(div.kat_cat_pic_name:contains(\"XXX\")):has(div.kat_cat_pic_name_b:contains(\"Pack\"))": "75"
":has(div.kat_cat_pic_name:contains(\"XXX\")):has(div.kat_cat_pic_name_b:contains(\"Clips\"))": "124"
# Internal
":has(div.kat_cat_pic_name:contains(\"Internal\")):has(div.kat_cat_pic_name_b:contains(\"Film HD\"))": "128"
":has(div.kat_cat_pic_name:contains(\"Internal\")):has(div.kat_cat_pic_name_b:contains(\"Film SD\"))": "129"
":has(div.kat_cat_pic_name:contains(\"Internal\")):has(div.kat_cat_pic_name_b:contains(\"Serien HD\"))": "130"
":has(div.kat_cat_pic_name:contains(\"Internal\")):has(div.kat_cat_pic_name_b:contains(\"Serien SD\"))": "131"
":has(div.kat_cat_pic_name:contains(\"Internal\")):has(div.kat_cat_pic_name_b:contains(\"Sonstiges\"))": "132"
banner:
selector: div[id^="details"] img
attribute: src
size:
selector: div.selection_unter_ad
filters:
- name: replace
args: [".", ""]
- name: replace
args: [",", "."]
grabs:
selector: div.selection_unter_ae
filters:
- name: trim
args: "x"
- name: replace
args: [".", ""]
- name: replace
args: [",", "."]
seeders:
selector: div.selection_unter_aa
filters:
- name: replace
args: [".", ""]
- name: replace
args: [",", "."]
leechers:
selector: div.selection_unter_aaa
filters:
- name: replace
args: [".", ""]
- name: replace
args: [",", "."]
downloadvolumefactor:
case:
":root:has(div.onlyup)": "0"
"*": "1"
uploadvolumefactor:
case:
"*": "1"
# 2 flavours of dates
date:
# Heute 13:30:04
# Gestern 09:10:10
selector: div.selection_unter_ab:not(:contains("."))
optional: true
filters:
- name: replace
args: ["Heute", "Today"]
- name: replace
args: ["Gestern", "Yesterday"]
date:
# 30.02.2018 um 23:12:50
selector: div.selection_unter_ab:contains(".")
optional: true
filters:
- name: replace
args: [" um", ""]
- name: dateparse
args: "02.01.2006 15:04:05"
description:
selector: selection_unter_af
optional: true

View File

@@ -236,13 +236,22 @@
uploadvolumefactor:
case:
"*": "1"
# 2 flavours of dates
date:
selector: div.selection_unter_ab
# Heute 13:30:04
# Gestern 09:10:10
selector: div.selection_unter_ab:not(:contains("."))
optional: true
filters:
- name: replace
args: ["Heute", "Today"]
- name: replace
args: ["Gestern", "Yesterday"]
date:
# 30.02.2018 um 23:12:50
selector: div.selection_unter_ab:contains(".")
optional: true
filters:
- name: replace
args: [" um", ""]
- name: dateparse

View File

@@ -27,9 +27,9 @@
search:
# site returns just 30 results, attempt to fetch upto 90
paths:
- path: index.php
- path: index.php/page/2/
- path: index.php/page/3/
- path: /
- path: /page/2/
- path: /page/3/
keywordsfilters:
# most ES/ITA TV torrents are in XXxYY format, so we search without S/E prefixes and filter later
- name: re_replace

View File

@@ -50,7 +50,7 @@
active: 0
rows:
selector: tr:has(a[href^="index.php?page=torrent-details"])
selector: tr > td > table > tbody tr:has(a[href^="index.php?page=torrent-details"])
fields:
title:
selector: td a[href^="index.php?page=torrent-details"]

View File

@@ -24,6 +24,7 @@
- https://www.gktorrent.me/
- https://www.rantop.org/
- https://www.gktorrent.net/
- https://www.gktorrent.cx/
caps:
categorymappings:
- {id: movies, cat: Movies, desc: "Movies"}

View File

@@ -13,7 +13,7 @@
# Movie
- {id: 132, cat: Movies/BluRay, desc: "BluRay"}
- {id: 146, cat: Movies/HD, desc: "Remux"}
- {id: 186, cat: Movies/HD, desc: "UHD"}
- {id: 186, cat: Movies/UHD, desc: "UHD"}
- {id: 189, cat: Movies/HD, desc: "HD"}
- {id: 190, cat: Movies/SD, desc: "SD"}
- {id: 20, cat: Movies/DVD, desc: "DVD"}
@@ -21,10 +21,10 @@
- {id: 16, cat: Movies, desc: "Packs"}
# Serien
- {id: 187, cat: TV/HD, desc: "Staffeln UHD"}
- {id: 187, cat: TV/UHD, desc: "Staffeln UHD"}
- {id: 173, cat: TV/HD, desc: "Staffeln HD"}
- {id: 133, cat: TV/SD, desc: "Staffeln SD"}
- {id: 188, cat: TV/HD, desc: "Folgen UHD"}
- {id: 188, cat: TV/UHD, desc: "Folgen UHD"}
- {id: 174, cat: TV/HD, desc: "Folgen HD"}
- {id: 7, cat: TV/SD, desc: "Folgen SD"}
@@ -76,6 +76,7 @@
modes:
search: [q]
tv-search: [q, season, ep]
movie-search: [q]
settings:
- name: pin

View File

@@ -0,0 +1,122 @@
---
site: hdplus
name: HDplus
description: "HDplus is Private Torrent Tracker for MOVIES / TV / MUSIC"
language: en-us
type: private
encoding: UTF-8
links:
- https://hdplus.xyz/
caps:
categorymappings:
- {id: 1, cat: Movies, desc: "Movies"}
- {id: 2, cat: TV, desc: "TV"}
- {id: 3, cat: Audio, desc: "Music"}
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 }}"
remember: 1
selectorinputs:
_token:
selector: meta[name="csrf-token"]
attribute: content
error:
- selector: form[action$="/login"] .text-red
test:
path: /
selector: a[href$="/logout"]
ratio:
path: /
selector: span:has(i.fa-sync-alt)
filters:
- name: regexp
args: "Ratio : (\\d+)"
search:
paths:
- path: filterTorrents
inputs:
$raw: "{{range .Categories}}categories[]={{.}}&{{end}}"
search: "{{if .Query.IMDBID}}{{else}}{{ .Keywords }}{{end}}"
uploader: ""
imdb: "{{ .Query.IMDBIDShort }}"
tvdb: ""
tmdb: ""
sort: created_at
direction: desc
qty: 100
rows:
selector: table > tbody > tr
fields:
category:
selector: a[href*="/categories/"]
attribute: href
filters:
- name: regexp
args: "/categories/.*?\\.(\\d+)"
title:
selector: a.view-torrent
download:
selector: a[href*="/download/"]
attribute: href
details:
selector: a.view-torrent
attribute: href
size:
selector: td:nth-child(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
filters:
# translations for Turkish|Estonian|Danish|Italian|Polish|Norwegian|Portoguese|Czech|Russian|Romanian|Spanish|French|German|Bulgarian|Dutch
- name: re_replace
args: ["(önce|tagasi|geleden|fa|temu|siden|atrás|nazpět|назад|acum|hace|il y a|vor|преди)", "ago"]
- name: re_replace
args: ["(dakika|minut|minuto|minuta|minutt|минута|Minute|minuut)", "minute"]
- name: re_replace
args: ["(dakika|minutit|minutter|minuti|minuty|minutos|минуты|минут|Minuten|минути|minuten)", "minutes"]
- name: re_replace
args: ["(saat|tund|time|ora|godzina|hora|hodina|час|oră|heure|Stunde|uur)", "hour"]
- name: re_replace
args: ["(saat|tundi|timer|ore|godziny|horas|hodiny|hoden|часа|часов|ore|heures|Stunden)", "hours"]
- name: re_replace
args: ["(gün|päev|dag|giorno|dzień|dia|den|день|zi|día|jour|Tag|ден)", "day"]
- name: re_replace
args: ["(gün|päeva|dage|giorni|dni|dias|dny|дня|дней|zile|días|jours|Tagen|дни|dagen)", "days"]
- name: re_replace
args: ["(hafta|nädal|uge|settimana|tydzień|uke|semana|týden|неделю|săptămână|semaine|Woche|седмица)", "week"]
- name: re_replace
args: ["(hafta|nädalat|uger|settimane|tygodnie|uker|semanas|týdny|недели|недель|săptămâni|semaines|Wochen|седмици|weken)", "weeks"]
- name: re_replace
args: [" (ay|kuu|måned|mese|miesiąc|mês|měsíc|месяц|lună|mes|mois|Monat|месец|maand)", "month"]
- name: re_replace
args: [" (ay|kuud|måneder|mesi|miesiące|meses|měsíce|месяца|месяцев|luni|meses|mois|Monaten|месеца|maanden)", "months"]
downloadvolumefactor:
case:
"i[data-original-title=\"100% Free\"]": "0" # Single Torrent Freeleech
"i[data-original-title=\"Global freeleech\"]": "0" # Global Freeleech
"*": "1"
uploadvolumefactor:
case:
"i[data-original-title=\"Double upload\"]": "2" # Single Torrent Double Upload
"i[data-original-title=\"Double Upload\"]": "2" # Global Double Upload
"*": "1"

View File

@@ -26,7 +26,7 @@
- {id: 26, cat: PC/Games, desc: "Games/PC"}
- {id: 38, cat: PC/Phone-Other, desc: "Mobile"}
- {id: 59, cat: Movies/3D, desc: "Movies/3D"}
- {id: 92, cat: Movies/HD, desc: "Movies/4K-UHD"}
- {id: 92, cat: Movies/UHD, desc: "Movies/4K-UHD"}
- {id: 32, cat: Movies/BluRay, desc: "Movies/Blu-Ray"}
- {id: 28, cat: Movies/DVD, desc: "Movies/DVD"}
- {id: 42, cat: Movies/HD, desc: "Movies/HD-x264"}
@@ -79,7 +79,7 @@
incldead: 1
search_by: "{{ if .Query.IMDBID }}imdb{{else}}name{{end}}"
rows:
selector: table.torrenttable > tbody > tr:has(a[title][href^="details.php?id="])
selector: table.table-striped > tbody > tr:has(a[title][href^="details.php?id="])
fields:
title:
selector: a[title][href^="details.php?id="]
@@ -93,13 +93,10 @@
filters:
- name: querystring
args: cat
imdb:
selector: a[title="IMDB"]
attribute: href
banner:
attribute: rel
imdb:
selector: a[href^="http://www.imdb.com/title/"]
selector: a[href*="https://www.imdb.com/title/"]
optional: true
attribute: href
download:
@@ -114,13 +111,10 @@
selector: td:has(a[href$="filelist=1#filelist"])
remove: a
date:
selector: td > span:has(i.fa-clock)
remove: b
selector: td > small:has(i.fa-clock)
filters:
- name: replace
args: ["\xA0", " "]
- name: replace
args: ["Added on ", ""]
- name: replace
args: ["st ", " "]
- name: replace
@@ -129,8 +123,8 @@
args: ["rd ", " "]
- name: replace
args: ["th ", " "]
- name: replace
args: [" by", ""]
- name: regexp
args: "(.+?) by"
- name: append
args: " +02:00"
- name: dateparse
@@ -145,6 +139,3 @@
uploadvolumefactor:
case:
"*": "1"
description:
selector: td:has(a[title][href^="details.php?id="])
remove: a[title][href^="details.php?id="], div, font:contains("Added on")

View File

@@ -1,92 +0,0 @@
---
site: idopeclone
name: IdopeClone
description: "This Clone of iDope is a Public torrent search engine"
language: en-us
type: public
encoding: UTF-8
links:
- https://www.idope.site/
legacylinks:
- https://idope.top/
caps:
categorymappings:
- {id: other, cat: Other, desc: "Others"}
- {id: movies, cat: Movies, desc: "Movies"}
- {id: videos, cat: Other, desc: "Videos"}
- {id: tv, cat: TV, desc: "TV"}
- {id: anime, cat: TV/Anime, desc: "Anime"}
- {id: xxx, cat: XXX, desc: "XXX"}
- {id: adult, cat: XXX, desc: "XXX"}
- {id: music, cat: Audio, desc: "Music"}
- {id: games, cat: PC/Games, desc: "Games"}
- {id: apps, cat: PC/0day, desc: "Apps"}
- {id: applications, cat: PC/0day, desc: "Apps"}
- {id: android, cat: PC/Phone-Android, desc: "Android"}
- {id: software, cat: PC/0day, desc: "Apps"}
- {id: books, cat: Books, desc: "Books"}
modes:
search: [q]
tv-search: [q, season, ep]
movie-search: [q]
settings: []
search:
paths:
- path: "{{if .Keywords}}search/{{ .Keywords}}/{{else}}recent/{{end}}"
- path: "{{if .Keywords}}s/{{ .Keywords}}/page/2{{else}}recent/2{{end}}"
- path: "{{if .Keywords}}s/{{ .Keywords}}/page/3{{else}}recent/3{{end}}"
- path: "{{if .Keywords}}s/{{ .Keywords}}/page/4{{else}}recent/4{{end}}"
- path: "{{if .Keywords}}s/{{ .Keywords}}/page/5{{else}}recent/5{{end}}"
rows:
selector: li:has(div.opt-text-w3layouts)
filters:
- name: andmatch
fields:
title:
selector: div.opt-text-w3layouts a
details:
selector: div.opt-text-w3layouts a
attribute: href
category:
optional: true
selector: a[href^="/browse/"]
filters:
- name: replace
args: ["/browse/", ""]
magnet:
selector: a[href^="magnet:?"]
attribute: href
date:
selector: div.seedbar span:nth-child(4)
filters:
- name: replace
args: ["Age: ", ""]
- name: timeago
files:
selector: div.seedbar span:nth-child(5)
filters:
- name: replace
args: ["Files: ", ""]
size:
selector: div.seedbar span:nth-child(3)
filters:
- name: replace
args: ["Size: ", ""]
seeders:
selector: div.seedbar span:nth-child(1)
filters:
- name: replace
args: ["Seed: ", ""]
leechers:
selector: div.seedbar span:nth-child(2)
filters:
- name: replace
args: ["Leech: ", ""]
downloadvolumefactor:
text: "0"
uploadvolumefactor:
text: "1"

View File

@@ -6,8 +6,9 @@
type: public
encoding: UTF-8
links:
- https://ilcorsaronero.vip/
- https://ilcorsaronero.live/
legacylinks:
- https://ilcorsaronero.vip/
- https://ilcorsaronero.info/
- https://ilcorsaronero.ch/
- https://ilcorsaronero.cc/

View File

@@ -142,7 +142,7 @@
- name: re_replace
args: ["([a-zA-Z]+)\\s+(\\d{1,2})\\s+'(\\d{2})", "$2 $1 $3"]
- name: dateparse
args: "02 Jan 06"
args: "2 Jan 06"
downloadvolumefactor:
case:
"*": 1

View File

@@ -87,10 +87,7 @@
date:
selector: td:nth-child(4)
filters:
- name: append
args: " +0700"
- name: dateparse
args: "2006-01-0215:04:05 -0700"
- name: timeago
downloadvolumefactor:
case:
"span.label:contains(\"Free\")": "0"

View File

@@ -11,6 +11,7 @@
- https://nnm-club.name/
certificates:
- 7877113458e90f3643dd28424657a29469f5dc55
- 0edfdcc8cf9f69dbe5473878145cae92504275b0
settings:
- name: username

View File

@@ -76,8 +76,6 @@
autocomplete_toggle: 1
rows:
selector: table#torrent_table tr:not(:first-child)
# filters:
# - name: andmatch
fields:
title:
selector: a[href^="/torrents.php?id="]
@@ -85,10 +83,8 @@
selector: td.cats_col div a
attribute: href
filters:
- name: strdump
- name: regexp
args: "(\\d+)]=1"
- name: strdump
details:
selector: a[href^="/torrents.php?id="]
attribute: href

View File

@@ -12,6 +12,7 @@
encoding: UTF-8
links:
- https://nyaa.pantsu.cat/
- https://nyaa.pt/
settings:
- name: cat-id

View File

@@ -0,0 +1,123 @@
---
site: pthome
name: PThome
description: "PThome is a CHINESE Private Torrent Tracker for 0DAY / GENERAL"
language: zh-CN
type: private
encoding: UTF-8
followredirect: true
links:
- https://www.pthome.net/
caps:
categorymappings:
- {id: 401, cat: Movies, desc: "Movies(电影)"}
- {id: 404, cat: TV/Documentary, desc: "Documentaries(记录片)"}
- {id: 405, cat: TV/Anime, desc: "Animations(动漫)"}
- {id: 402, cat: TV, desc: "TV Series(电视剧)"}
- {id: 403, cat: TV/OTHER, desc: "TV Shows(综艺)"}
- {id: 406, cat: Audio/Video, desc: "Music Videos(MV)"}
- {id: 407, cat: TV/Sport, desc: "Sports(体育)"}
- {id: 408, cat: Audio/Lossless, desc: "HQ Audio(音乐)"}
- {id: 410, cat: Console, desc: "Games(游戏)"}
- {id: 411, cat: PC, desc: "Software(软件)"}
- {id: 412, cat: Books, desc: "Study(学习)"}
- {id: 409, cat: Other, desc: "Misc(其他)"}
modes:
search: [q]
tv-search: [q, season, ep, imdbid]
movie-search: [q, imdbid]
settings:
- name: cookie
type: text
label: Cookie
- name: info
type: info
label: How to get the Cookie
default: "<ol><li>Login to this tracker in your browser<li>Open the <b>DevTools</b> panel by pressing <b>F12</b><li>Select the <b>Network</b> tab<li>Click on the <b>Doc</b> button<li>Refresh the page by pressing <b>F5</b><li>Select the <b>Headers</b> tab<li>Find 'cookie:' in the <b>Request Headers</b> section<li>Copy & paste the whole cookie string to here</ol>"
login:
method: cookie
inputs:
cookie: "{{ .Config.cookie }}"
test:
path: index.php
ratio:
path: index.php
selector: table tr td.bottom
filters:
- name: replace
args: ["分享率:","Ratio:"] # for simplified chinese language setting
- name: regexp
args: "Ratio:\\s(.*?)\\s\\s"
search:
paths:
- path: torrents.php
inputs:
$raw: "{{range .Categories}}cat{{.}}=1&{{end}}"
incldead: "0"
spstate: "0"
inclbookmarked: "0"
search: "{{if .Query.IMDBID}}{{.Query.IMDBID}}{{else}}{{.Keywords}}{{end}}"
search_area: "{{if .Query.IMDBID}}4{{else}}0{{end}}"
search_mode: "0"
rows:
selector: table.torrents tr:has(a[href^="?cat="])
filters:
- name: andmatch
fields:
title:
selector: td.torrents-box a
attribute: title
category:
selector: a[href^="?cat="]
attribute: href
filters:
- name: querystring
args: cat
details:
selector: a[href^="details.php?id="]
attribute: href
download:
selector: a[href^="details.php?id="]
attribute: href
filters:
- name: replace
args: ["details.php", "download.php"]
imdb:
selector: a[href^="http://www.imdb.com/title/tt"]
attribute: href
size:
selector: td:nth-child(5)
grabs:
selector: td:nth-child(8)
seeders:
selector: td:nth-child(6)
leechers:
selector: td:nth-child(7)
date:
selector: td:nth-child(4) span
attribute: title
filters:
- name: dateparse
args: "2006-01-02 15:04:05"
downloadvolumefactor:
case:
img.pro_free: "0"
img.pro_free2up: "0"
img.pro_50pctdown: "0.5"
img.pro_50pctdown2up: "0.5"
img.pro_30pctdown: "0.3"
"*": "1"
uploadvolumefactor:
case:
img.pro_50pctdown2up: "2"
img.pro_free2up: "2"
img.pro_2up: "2"
"*": "1"

View File

@@ -132,8 +132,13 @@
selector: td:nth-child(3) a
attribute: href
size:
# 1,36 GB
# 296,98 MB
# 1.018,29 MB
selector: td:nth-child(6)
filters:
- name: replace
args: [".", ""]
- name: replace
args: [",", "."]
seeders:

View File

@@ -0,0 +1,223 @@
---
site: racingforme
name: RacingForMe
description: "Racing For Me (RFM) is a Private Torrent Tracker for RACING"
language: en-us
type: private
encoding: UTF-8
links:
- https://www.racingfor.me/
caps:
categorymappings:
- {id: 1000, cat: TV/Sport, desc: "Formula 1 - Full races"}
- {id: 1010, cat: TV/Sport, desc: "F1 Full Seasons"}
- {id: 1020, cat: TV/Sport, desc: "F1 Full Season 1950-1980"}
- {id: 1030, cat: TV/Sport, desc: "F1 Full Season 1981-1990"}
- {id: 1040, cat: TV/Sport, desc: "F1 Full Season 1991-2000"}
- {id: 1050, cat: TV/Sport, desc: "F1 Full Season 2001-2010"}
- {id: 1060, cat: TV/Sport, desc: "F1 Full Season 2011-2017"}
- {id: 1070, cat: TV/Sport, desc: "F1 Full Season 2011-2017 (HD)"}
- {id: 2000, cat: TV/Sport, desc: "Formula 1 - Highlights"}
- {id: 2010, cat: TV/Sport, desc: "F1 Highlights 1950-1980"}
- {id: 2020, cat: TV/Sport, desc: "F1 Highlights 1981-1990"}
- {id: 2030, cat: TV/Sport, desc: "F1 Highlights 1991-2000"}
- {id: 2040, cat: TV/Sport, desc: "F1 Highlights 2001-2010"}
- {id: 2050, cat: TV/Sport, desc: "F1 Highlights 2011-2017"}
- {id: 2060, cat: TV/Sport, desc: "F1 Highlights 2011-2017 (HD)"}
- {id: 3000, cat: TV/Sport, desc: "Formula 1 - FP and quali"}
- {id: 3010, cat: TV/Sport, desc: "F1 FP and quali 1950-1980"}
- {id: 3020, cat: TV/Sport, desc: "F1 FP and quali 1981-1990"}
- {id: 3030, cat: TV/Sport, desc: "F1 FP and quali 1991-2000"}
- {id: 3040, cat: TV/Sport, desc: "F1 FP and quali 2001-2010"}
- {id: 3050, cat: TV/Sport, desc: "F1 FP and quali 2011-2017"}
- {id: 3060, cat: TV/Sport, desc: "F1 FP and quali 2011-2017 (HD)"}
- {id: 4000, cat: TV/Sport, desc: "Formula 1 - Onboard"}
- {id: 4010, cat: TV/Sport, desc: "F1 Onboard 1950-1980"}
- {id: 4020, cat: TV/Sport, desc: "F1 Onboard 1981-1990"}
- {id: 4030, cat: TV/Sport, desc: "F1 Onboard 1991-2000"}
- {id: 4040, cat: TV/Sport, desc: "F1 Onboard 2001-2010"}
- {id: 4050, cat: TV/Sport, desc: "F1 Onboard 2011-2017"}
- {id: 5000, cat: TV/Sport, desc: "Formula 1 - Miscellaneous"}
- {id: 5010, cat: TV/Sport, desc: "F1 Misc Documentaries"}
- {id: 5020, cat: TV/Sport, desc: "F1 Misc Driver/team specials"}
- {id: 5030, cat: TV/Sport, desc: "F1 Misc Event specials"}
- {id: 5040, cat: TV/Sport, desc: "F1 Misc Other"}
- {id: 6000, cat: TV/Sport, desc: "Formula 1 - 2018"}
- {id: 6010, cat: TV/Sport, desc: "F1 2018 Free practices"}
- {id: 6020, cat: TV/Sport, desc: "F1 2018 Qualifications"}
- {id: 6030, cat: TV/Sport, desc: "F1 2018 Races"}
- {id: 6040, cat: TV/Sport, desc: "F1 2018 Highlights"}
- {id: 6050, cat: TV/Sport, desc: "F1 2018 Onboards"}
- {id: 6060, cat: TV/Sport, desc: "F1 2018 Other"}
- {id: 7000, cat: TV/Sport, desc: "Formula 1 - 2018 (HD)"}
- {id: 7010, cat: TV/Sport, desc: "F1 2018 (HD) Free practices"}
- {id: 7020, cat: TV/Sport, desc: "F1 2018 (HD) Qualifications"}
- {id: 7030, cat: TV/Sport, desc: "F1 2018 (HD) Races"}
- {id: 7040, cat: TV/Sport, desc: "F1 2018 (HD) Highlights"}
- {id: 7050, cat: TV/Sport, desc: "F1 2018 (HD) Other"}
- {id: 8000, cat: TV/Sport, desc: "Moto3 / Moto2 / MotoGP"}
- {id: 8010, cat: TV/Sport, desc: "Moto 125cc"}
- {id: 8020, cat: TV/Sport, desc: "Moto 250cc"}
- {id: 8030, cat: TV/Sport, desc: "Moto Moto3"}
- {id: 8040, cat: TV/Sport, desc: "Moto Moto2"}
- {id: 8050, cat: TV/Sport, desc: "Moto MotoGP"}
- {id: 9000, cat: TV/Sport, desc: "Motorbikes"}
- {id: 9010, cat: TV/Sport, desc: "Motorbikes AMA"}
- {id: 9020, cat: TV/Sport, desc: "Motorbikes World Supersport"}
- {id: 9030, cat: TV/Sport, desc: "Motorbikes World Superstock"}
- {id: 9040, cat: TV/Sport, desc: "Motorbikes WSBK"}
- {id: 9050, cat: TV/Sport, desc: "Motorbikes BSB"}
- {id: 9060, cat: TV/Sport, desc: "Motorbikes Other"}
- {id: 9070, cat: TV/Sport, desc: "Motorbikes MotoAmerica"}
- {id: 10000, cat: TV/Sport, desc: "Touring cars"}
- {id: 10010, cat: TV/Sport, desc: "Touring cars WTCC"}
- {id: 10020, cat: TV/Sport, desc: "Touring cars DTM"}
- {id: 10030, cat: TV/Sport, desc: "Touring cars V8 Supercars"}
- {id: 10040, cat: TV/Sport, desc: "Touring cars BTCC"}
- {id: 10050, cat: TV/Sport, desc: "Touring cars Porsche Supercup"}
- {id: 10060, cat: TV/Sport, desc: "Touring cars Other"}
- {id: 11000, cat: TV/Sport, desc: "Sports cars"}
- {id: 11010, cat: TV/Sport, desc: "Sports cars BSS"}
- {id: 11020, cat: TV/Sport, desc: "Sports cars Le Mans 24H"}
- {id: 11030, cat: TV/Sport, desc: "Sports cars WSC/WEC"}
- {id: 11040, cat: TV/Sport, desc: "Sports cars IMSA"}
- {id: 11050, cat: TV/Sport, desc: "Sports cars USC"}
- {id: 11070, cat: TV/Sport, desc: "Sports cars BES"}
- {id: 11080, cat: TV/Sport, desc: "Sports cars Super GT"}
- {id: 11090, cat: TV/Sport, desc: "Sports cars IMSA Pilot Challenge"}
- {id: 11060, cat: TV/Sport, desc: "Sports cars Other"}
- {id: 12000, cat: TV/Sport, desc: "American open-wheelers"}
- {id: 12010, cat: TV/Sport, desc: "American open-wheelers CCWS"}
- {id: 12020, cat: TV/Sport, desc: "American open-wheelers IRL"}
- {id: 12030, cat: TV/Sport, desc: "American open-wheelers CART"}
- {id: 12040, cat: TV/Sport, desc: "American open-wheelers Indycar Series"}
- {id: 12050, cat: TV/Sport, desc: "American open-wheelers Indy Lights"}
- {id: 12060, cat: TV/Sport, desc: "American open-wheelers Other"}
- {id: 13000, cat: TV/Sport, desc: "Rally"}
- {id: 13010, cat: TV/Sport, desc: "Rally WRC"}
- {id: 13020, cat: TV/Sport, desc: "Rally ERC"}
- {id: 13030, cat: TV/Sport, desc: "Rally BRC"}
- {id: 13040, cat: TV/Sport, desc: "Rally National series"}
- {id: 13050, cat: TV/Sport, desc: "Rally Enduro-rally"}
- {id: 13060, cat: TV/Sport, desc: "Rally Rally cross"}
- {id: 13070, cat: TV/Sport, desc: "Rally Other"}
- {id: 14000, cat: TV/Sport, desc: "NASCAR / Stockcars"}
- {id: 14010, cat: TV/Sport, desc: "NASCAR Sprint Cup"}
- {id: 14020, cat: TV/Sport, desc: "NASCAR XFINITY Series"}
- {id: 14030, cat: TV/Sport, desc: "NASCAR CW Trucks"}
- {id: 14040, cat: TV/Sport, desc: "NASCAR ARCA"}
- {id: 14050, cat: TV/Sport, desc: "NASCAR Other"}
- {id: 15000, cat: TV/Sport, desc: "F3000 / GP2 / Formula 2"}
- {id: 15010, cat: TV/Sport, desc: "F2 1985-1990"}
- {id: 15020, cat: TV/Sport, desc: "F2 1991-2000"}
- {id: 15030, cat: TV/Sport, desc: "F2 2001-2011"}
- {id: 15040, cat: TV/Sport, desc: "F2 2012-2017"}
- {id: 15050, cat: TV/Sport, desc: "F2 GP2 Asia"}
- {id: 16000, cat: TV/Sport, desc: "Single seaters"}
- {id: 16010, cat: TV/Sport, desc: "Single seaters Formula 2"}
- {id: 16020, cat: TV/Sport, desc: "Single seaters FIA F3"}
- {id: 16030, cat: TV/Sport, desc: "Single seaters GP3"}
- {id: 16040, cat: TV/Sport, desc: "Single seaters WSBR 2.0"}
- {id: 16050, cat: TV/Sport, desc: "Single seaters WSBR 3.5"}
- {id: 16060, cat: TV/Sport, desc: "Single seaters British F3"}
- {id: 16070, cat: TV/Sport, desc: "Single seaters Formula E"}
- {id: 16080, cat: TV/Sport, desc: "Single seaters Other"}
- {id: 17000, cat: TV/Sport, desc: "Other Photographs"}
- {id: 17010, cat: TV/Sport, desc: "Other Formula 1"}
- {id: 17020, cat: TV/Sport, desc: "Other Motorbikes"}
- {id: 17030, cat: TV/Sport, desc: "Other Touring cars"}
- {id: 17040, cat: TV/Sport, desc: "Other Rally"}
- {id: 17050, cat: TV/Sport, desc: "Other Sports cars"}
- {id: 17060, cat: TV/Sport, desc: "Other"}
- {id: 18000, cat: TV/Sport, desc: "Miscellaneous"}
- {id: 18010, cat: TV/Sport, desc: "Documentaries"}
- {id: 18020, cat: TV/Sport, desc: "TV shows"}
- {id: 18030, cat: TV/Sport, desc: "DVD covers"}
- {id: 18040, cat: TV/Sport, desc: "E-books"}
- {id: 18050, cat: TV/Sport, desc: "Other"}
- {id: 19000, cat: TV/Sport, desc: "Other"}
- {id: 19010, cat: TV/Sport, desc: "Drag racing"}
- {id: 19020, cat: TV/Sport, desc: "Truck racing"}
- {id: 19030, cat: TV/Sport, desc: "Off-road"}
- {id: 19040, cat: TV/Sport, desc: "Drifting"}
- {id: 19050, cat: TV/Sport, desc: "Other"}
modes:
search: [q]
login:
path: login
method: post
inputs:
username: "{{ .Config.username }}"
password: "{{ .Config.password }}"
rememberme: 1
error:
- selector: div#Error
test:
path: /
selector: a[href="/logout"]
search:
paths:
# only 20 results per page so attempt to fetch 5 pages
# https://www.racingfor.me/search/australia%20f1%202018?c=7000&ob=&offset=20#results
- path: "search/{{if .Keywords}}{{.Keywords}}{{else}}*{{end}}"
- path: "search/{{if .Keywords}}{{.Keywords}}&offset=20{{else}}*?offset=20{{end}}"
- path: "search/{{if .Keywords}}{{.Keywords}}&offset=40{{else}}*?offset=40{{end}}"
- path: "search/{{if .Keywords}}{{.Keywords}}&offset=60{{else}}*?offset=60{{end}}"
- path: "search/{{if .Keywords}}{{.Keywords}}&offset=80{{else}}*?offset=80{{end}}"
rows:
selector: div#torrentBorder
fields:
category:
selector: span.catIcon a
attribute: href
filters:
- name: querystring
args: c
title:
selector: span.browseTitle a
download:
selector: span.browseTitle a
attribute: href
filters:
- name: replace
args: ["/details/", "/download/"]
details:
selector: span.browseTitle a
attribute: href
size:
selector: span.torrentData span.torrentFiles
filters:
- name: regexp
args: "(.+?) in"
files:
selector: span.torrentData span.torrentFiles
filters:
- name: replace
args: [" in > 100", " in 100 file"]
- name: regexp
args: " in (\\d+) file"
seeders:
selector: span.torrentData span.torrentPeers
filters:
- name: regexp
args: "(\\d+) seeder"
leechers:
selector: span.torrentData span.torrentPeers
filters:
- name: regexp
args: "and (\\d+) leecher"
grabs:
selector: span.torrentData span.torrentSnatched
filters:
- name: regexp
args: "(\\d+)"
date:
text: now
downloadvolumefactor:
text: "1"
uploadvolumefactor:
text: "1"

View File

@@ -1,40 +1,54 @@
---
site: scenerush
name: SceneRush
description: "SceneRush is a Portuguese general tracker."
description: "SceneRush is a PORTUGUESE Private Torrent Tracker for 0DAY / GENERAL"
language: pt-PT
type: private
encoding: UTF-8
links:
- https://www.scene-rush.pt/
legacylinks:
- http://www.scene-rush.pt/
caps:
categorymappings:
- {id: 1, cat: PC, desc: "Apps"}
- {id: 2, cat: Movies, desc: "XVID"}
- {id: 3, cat: Movies/DVD, desc: "DVD"}
- {id: 4, cat: TV, desc: "TV XVID"}
- {id: 5, cat: PC/Games, desc: "PC Games"}
- {id: 6, cat: Movies/HD, desc: "HD"}
- {id: 7, cat: XXX, desc: "XXX"}
- {id: 8, cat: TV/Anime, desc: "ANIME"}
- {id: 8, cat: TV/Anime, desc: "Anime"}
- {id: 9, cat: Audio, desc: "Audio"}
- {id: 10, cat: Other, desc: "Other"}
- {id: 11, cat: Console/Xbox 360, desc: "XBOX 360"}
- {id: 12, cat: Console/PSP, desc: "PSP"}
- {id: 13, cat: TV/Documentary, desc: "DOC"}
- {id: 17, cat: TV/HD, desc: "TV-X264"}
- {id: 13, cat: TV/Documentary, desc: "Doc"}
- {id: 14, cat: Movies/DVD, desc: "Movies DVD"}
- {id: 15, cat: Console, desc: "PS2"}
- {id: 16, cat: TV/Sport, desc: "TV WWE"}
- {id: 17, cat: TV/HD, desc: "TV X264"}
- {id: 18, cat: TV, desc: "TV DVD"}
- {id: 19, cat: XXX/DVD, desc: "XXX DVD"}
- {id: 20, cat: Movies/DVD, desc: "A.DVD"}
- {id: 21, cat: PC/Mac, desc: "MAC"}
- {id: 20, cat: TV/Anime, desc: "Anime DVD"}
- {id: 21, cat: PC/Mac, desc: "Mac"}
- {id: 23, cat: Movies, desc: "Boxset"}
- {id: 31, cat: Other, desc: "OFF"}
- {id: 32, cat: Movies/BluRay, desc: "BluRay"}
- {id: 33, cat: Console/Wii, desc: "WII"}
- {id: 34, cat: Console/PS3, desc: "PS3"}
- {id: 35, cat: Movies/HD, desc: "A.HD"}
- {id: 35, cat: TV/Anime, desc: "Anime HD"}
- {id: 36, cat: PC/Phone-Android, desc: "Android"}
- {id: 37, cat: Movies/DVD, desc: "C.DVDR"}
- {id: 37, cat: Movies/DVD, desc: "Custom DVDR"}
- {id: 38, cat: Movies/Other, desc: "CAM TS"}
- {id: 39, cat: Other, desc: "GPS"}
- {id: 40, cat: Console/PS4, desc: "PS4"}
- {id: 41, cat: Movies/SD, desc: "BDRIP"}
- {id: 41, cat: Movies/BluRay, desc: "BDRIP"}
- {id: 42, cat: Movies/WEBDL, desc: "WEB DL"}
- {id: 43, cat: Books, desc: "EBOOK"}
- {id: 44, cat: TV/Sport, desc: "SPORTS"}
- {id: 43, cat: Books, desc: "Ebook"}
- {id: 44, cat: TV/Sport, desc: "Sports"}
- {id: 46, cat: Movies/UHD, desc: "4K"}
modes:
search: [q]
tv-search: [q]
@@ -45,18 +59,23 @@
username: "{{ .Config.username }}"
password: "{{ .Config.password }}"
error:
- selector: td.embedded:has(h2:contains("failed")+table)
- selector: h2:contains("Falhou")
message:
selector: table tr td.text
test:
path: browse.php
path: index.php
selector: a[href="logout.php"]
ratio:
path: browse.php
selector: td[width='60'][style=['text-align:center;'] > span > font
selector: td.text:contains("Ratio")
filters:
- name: regexp
args: "Ratio actual (.*?) ]"
search:
paths:
- path: browse.php
method: post
inputs:
$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
search: "{{ .Query.Keywords }}"
@@ -93,7 +112,7 @@
- name: re_replace
args: ["(\\d{4}-\\d{2}-\\d{2})(\\d{2}:\\d{2}:\\d{2})","$1 $2"]
- name: dateparse
args: "2018-12-30 22:30:31"
args: "2006-01-02 15:04:05"
downloadvolumefactor:
case:
"i.fg-gold": "0"

View File

@@ -0,0 +1,124 @@
---
site: sharingue
name: Sharingue
description: "Sharingue is a BRAZILIAN Private Tracker for TV / MOVIES / ANIME / MUSIC"
language: pt-br
type: private
encoding: UTF-8
links:
- https://www.sharingue.live/
caps:
categorymappings:
- {id: 1, cat: Movies, desc: "Movies (Filmes)"}
- {id: 3, cat: Audio, desc: "Music (Músicas)"}
- {id: 4, cat: TV, desc: "TV (Séries)"}
- {id: 5, cat: TV/Anime, desc: "Anime (Animes)"}
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 }}"
remember: 1
selectorinputs:
_token:
selector: meta[name="csrf-token"]
attribute: content
error:
- selector: form[action$="/login"] .text-red
test:
path: /
selector: a[href$="/logout"]
ratio:
path: /
selector: span:has(i.fa-sync-alt)
filters:
- name: regexp
args: "Ratio : (\\d+)"
search:
paths:
- path: filterTorrents
inputs:
$raw: "{{range .Categories}}categories[]={{.}}&{{end}}"
search: "{{if .Query.IMDBID}}{{else}}{{ .Keywords }}{{end}}"
uploader: ""
imdb: "{{ .Query.IMDBIDShort }}"
tvdb: ""
tmdb: ""
mal: ""
sort: created_at
direction: desc
qty: 100
rows:
selector: table > tbody > tr
fields:
category:
selector: a[href*="/categories/"]
attribute: href
filters:
- name: regexp
args: "/categories/.*?\\.(\\d+)"
title:
selector: a.view-torrent
download:
selector: a[href*="/download/"]
attribute: href
details:
selector: a.view-torrent
attribute: href
size:
selector: td:nth-child(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
filters:
# translations for Turkish|Estonian|Danish|Italian|Polish|Norwegian|Portoguese|Czech|Russian|Romanian|Spanish|French|German|Bulgarian|Dutch
- name: re_replace
args: ["(önce|tagasi|geleden|fa|temu|siden|atrás|nazpět|назад|acum|hace|il y a|vor|преди)", "ago"]
- name: re_replace
args: ["(dakika|minut|minuto|minuta|minutt|минута|Minute|minuut)", "minute"]
- name: re_replace
args: ["(dakika|minutit|minutter|minuti|minuty|minutos|минуты|минут|Minuten|минути|minuten)", "minutes"]
- name: re_replace
args: ["(saat|tund|time|ora|godzina|hora|hodina|час|oră|heure|Stunde|uur)", "hour"]
- name: re_replace
args: ["(saat|tundi|timer|ore|godziny|horas|hodiny|hoden|часа|часов|ore|heures|Stunden)", "hours"]
- name: re_replace
args: ["(gün|päev|dag|giorno|dzień|dia|den|день|zi|día|jour|Tag|ден)", "day"]
- name: re_replace
args: ["(gün|päeva|dage|giorni|dni|dias|dny|дня|дней|zile|días|jours|Tagen|дни|dagen)", "days"]
- name: re_replace
args: ["(hafta|nädal|uge|settimana|tydzień|uke|semana|týden|неделю|săptămână|semaine|Woche|седмица)", "week"]
- name: re_replace
args: ["(hafta|nädalat|uger|settimane|tygodnie|uker|semanas|týdny|недели|недель|săptămâni|semaines|Wochen|седмици|weken)", "weeks"]
- name: re_replace
args: [" (ay|kuu|måned|mese|miesiąc|mês|měsíc|месяц|lună|mes|mois|Monat|месец|maand)", "month"]
- name: re_replace
args: [" (ay|kuud|måneder|mesi|miesiące|meses|měsíce|месяца|месяцев|luni|meses|mois|Monaten|месеца|maanden)", "months"]
downloadvolumefactor:
case:
"i[data-original-title=\"100% Free\"]": "0" # Single Torrent Freeleech
"i[data-original-title=\"Global freeleech\"]": "0" # Global Freeleech
"*": "1"
uploadvolumefactor:
case:
"i[data-original-title=\"Double upload\"]": "2" # Single Torrent Double Upload
"i[data-original-title=\"Double Upload\"]": "2" # Global Double Upload
"*": "1"

View File

@@ -39,13 +39,13 @@
default: Without the itorrents option only magnet links will be provided.
search:
# https://www.skytorrents.lol/?query=mr+mercedes+s02e05&sort=created
# https://www.skytorrents.lol/?search=mr+mercedes+s02e05&sort=created
# https://www.skytorrents.lol/top100
paths:
- path: "{{ if .Keywords }}?query={{ .Keywords }}&sort=created{{else}}top100{{end}}"
- path: "{{ if .Keywords }}?query={{ .Keywords }}&sort=created&page=2{{else}}{{end}}"
- path: "{{ if .Keywords }}?query={{ .Keywords }}&sort=created&page=3{{else}}{{end}}"
- path: "{{ if .Keywords }}?query={{ .Keywords }}&sort=created&page=4{{else}}{{end}}"
- path: "{{ if .Keywords }}?search={{ .Keywords }}&sort=created{{else}}top100{{end}}"
- path: "{{ if .Keywords }}?search={{ .Keywords }}&sort=created&page=2{{else}}{{end}}"
- path: "{{ if .Keywords }}?search={{ .Keywords }}&sort=created&page=3{{else}}{{end}}"
- path: "{{ if .Keywords }}?search={{ .Keywords }}&sort=created&page=4{{else}}{{end}}"
rows:
selector: tr.result
fields:

View File

@@ -0,0 +1,74 @@
---
site: solidtorrents
name: SolidTorrents
description: "SolidTorrents is a Public torrent meta-search engine"
language: en-us
type: public
encoding: UTF-8
links:
- https://solidtorrents.net/
caps:
categories:
"Audio": Audio
"Video": Movies
"Image": Other/Misc
"Document": Books/Comics
"eBook": Books/Ebook
"Program": PC/0day
"Android": PC/Phone-Android
"Archive": Other
"Diskimage": PC/ISO
"Sourcecode": Movies/Other
"Database": Movies/DVD
"Unknown": Other
modes:
search: [q]
tv-search: [q, season, ep]
movie-search: [q]
settings: []
search:
paths:
# https://solidtorrents.net/search?q=gotham%20s05e02&sort=date&category=all
- path: "search?q={{.Keywords}}&sort=date&category=all"
rows:
selector: div[role="listitem"]:has(a[href^="magnet:?xt="])
fields:
title:
selector: div[class$="__title"] h3
details:
selector: div[class$="__title"] a
attribute: href
download:
selector: a[href^="magnet:?xt="]
attribute: href
category:
selector: div.v-list__tile__content div:nth-of-type(2)
filters:
- name: regexp
args: "(.+?) \\|"
date:
selector: div.v-list__tile__content div:nth-of-type(2)
filters:
- name: replace
args: ["a few", "1"]
- name: replace
args: ["an ", "1 "]
- name: replace
args: ["a ", "1 "]
- name: regexp
args: "(\\d+ \\w+ \\w+)"
seeders:
selector: div.v-list__tile__content div:nth-of-type(3) span:nth-child(1)
leechers:
selector: div.v-list__tile__content div:nth-of-type(3) span:nth-child(2)
size:
selector: div.v-list__tile__content div:nth-of-type(3)
remove: span
downloadvolumefactor:
text: "0"
uploadvolumefactor:
text: "1"

View File

@@ -10,67 +10,13 @@
caps:
categorymappings:
- {id: 41, cat: PC/Phone-Android, desc: "Applications / Android"}
- {id: 42, cat: PC/Phone-IOS, desc: "Applications / iOS"}
- {id: 57, cat: Books/Comics, desc: "Ebooks / Bandes dessinées"}
- {id: 58, cat: XXX, desc: "Ebooks / Bandes dessinées X"}
- {id: 31, cat: Books/Magazines, desc: "Ebooks / Journaux"}
- {id: 32, cat: Books/Ebook, desc: "Ebooks / Livres"}
- {id: 59, cat: Books/Comics, desc: "Ebooks / Manga"}
- {id: 77, cat: Movies/UHD, desc: "Films / 4K rip"}
- {id: 23, cat: Movies, desc: "Films / Animés"}
- {id: 49, cat: Movies/BluRay, desc: "Films / BDrip"}
- {id: 51, cat: Movies/BluRay, desc: "Films / BluRay 1080"}
- {id: 52, cat: Movies/BluRay, desc: "Films / BluRay 4K"}
- {id: 50, cat: Movies/BluRay, desc: "Films / BluRay 720"}
- {id: 19, cat: Movies/BluRay, desc: "Films / BRrip"}
- {id: 74, cat: TV/Documentary, desc: "Films / Documentaires"}
- {id: 20, cat: Movies/DVD, desc: "Films / DVD-R 5"}
- {id: 48, cat: Movies/DVD, desc: "Films / DVD-R 9"}
- {id: 53, cat: Movies/DVD, desc: "Films / DVDrip"}
- {id: 64, cat: Movies/HD, desc: "Films / HDLight 1080"}
- {id: 63, cat: Movies/HD, desc: "Films / HDLight 720"}
- {id: 55, cat: Movies/HD, desc: "Films / HDrip 1080"}
- {id: 54, cat: Movies/HD, desc: "Films / HDrip 720"}
- {id: 60, cat: Movies/HD, desc: "Films / HDTV"}
- {id: 62, cat: Movies/HD, desc: "Films / HDTV 1080"}
- {id: 61, cat: Movies/HD, desc: "Films / HDTV 720"}
- {id: 75, cat: Movies/SD, desc: "Films / VHSrip"}
- {id: 65, cat: Movies/WEBDL, desc: "Films / Web-DL"}
- {id: 67, cat: Movies/WEBDL, desc: "Films / Web-DL 1080"}
- {id: 68, cat: Movies/WEBDL, desc: "Films / Web-DL 4K"}
- {id: 69, cat: Movies/WEBDL, desc: "Films / Web-DL 4K"}
- {id: 66, cat: Movies/WEBDL, desc: "Films / Web-DL 720"}
- {id: 70, cat: Movies/WEBDL, desc: "Films / WEBrip"}
- {id: 72, cat: Movies/WEBDL, desc: "Films / WEBrip 1080"}
- {id: 73, cat: Movies/WEBDL, desc: "Films / WEBrip 4K"}
- {id: 71, cat: Movies/WEBDL, desc: "Films / WEBrip 720"}
- {id: 9, cat: XXX, desc: "Films X"}
- {id: 76, cat: Console/3DS, desc: "Jeux / 3DS"}
- {id: 29, cat: PC/Phone-Android, desc: "Jeux / Android"}
- {id: 12, cat: Console, desc: "Jeux / GameBoy"}
- {id: 45, cat: Console, desc: "Jeux / GameBoy Advance"}
- {id: 30, cat: PC/Phone-IOS, desc: "Jeux / iOS"}
- {id: 46, cat: PC/Mac, desc: "Jeux / Mac"}
- {id: 4, cat: PC/Games, desc: "Jeux / PC "}
- {id: 36, cat: Console/PSP, desc: "Jeux / PS1"}
- {id: 37, cat: Console/PSP, desc: "Jeux / PS2"}
- {id: 33, cat: Console/PS3, desc: "Jeux / PS3"}
- {id: 34, cat: Console/PS4, desc: "Jeux / PS4"}
- {id: 78, cat: Console/Wii, desc: "Jeux / Wii"}
- {id: 38, cat: Console/Xbox, desc: "Jeux / Xbox"}
- {id: 40, cat: Console/Xbox, desc: "Jeux / Xbox One"}
- {id: 39, cat: Console/Xbox 360, desc: "Jeux / Xbox360"}
- {id: 28, cat: PC/Mac, desc: "Logiciels / Apple"}
- {id: 26, cat: PC, desc: "Logiciels / Linux"}
- {id: 27, cat: PC/0day, desc: "Logiciels / Windows"}
- {id: 56, cat: Audio/Lossless, desc: "Musiques / FLAC"}
- {id: 6, cat: Audio/MP3, desc: "Musiques / MP3"}
- {id: 7, cat: TV, desc: "Séries"}
- {id: 44, cat: XXX, desc: "Séries X"}
- {id: 47, cat: TV, desc: "Séries animées"}
- {id: 43, cat: TV/HD, desc: "Séries HD"}
- {id: 0, cat: Other, desc: "Other"}
- {id: 1, cat: Audio, desc: "Musique"}
- {id: 2, cat: Movies, desc: "Film"}
- {id: 3, cat: TV, desc: "Série"}
- {id: 4, cat: Console, desc: "Jeux"}
- {id: 5, cat: Books, desc: "Ebook"}
- {id: 6, cat: PC, desc: "Logiciels"}
- {id: 7, cat: XXX, desc: "Contenu Adulte"}
modes:
search: [q]
@@ -144,8 +90,14 @@
size:
selector: td:nth-child(5)
seeders:
text: "0"
seeders:
optional: true
selector: td:nth-child(6)
leechers:
text: "0"
leechers:
optional: true
selector: td:nth-child(7)
downloadvolumefactor:
case:

View File

@@ -1,161 +1,130 @@
---
---
site: theshinning
name: The Shinning
description: "The Shinning (TsH) is a GERMAN Private Torrent Tracker for MOVIES / TV / GENERAL"
language: de-de
type: private
encoding: windows-1252
encoding: UTF-8
links:
- https://theshinning.me/
legacylinks:
- https://theshinning.org
- https://theshinning.org/
caps:
categorymappings:
# Filme
- {id: 28, cat: Movies/SD, desc: "HORROR"}
- {id: 25, cat: Movies/DVD, desc: "SD|DVD"}
- {id: 99, cat: Movies/SD, desc: "SD|SPORT"}
- {id: 24, cat: Movies/SD, desc: "SD|x264"}
- {id: 22, cat: Movies/SD, desc: "SD|XVID"}
- {id: 26, cat: XXX, desc: "SD|XxX"}
# High Definition
- {id: 29, cat: Movies/BluRay, desc: "BLURAY"}
- {id: 19, cat: Movies/HD, desc: "HD|1080p"}
- {id: 21, cat: Movies/3D, desc: "HD|3D"}
- {id: 107, cat: Movies/HD, desc: "HD|4K"}
- {id: 20, cat: Movies/HD, desc: "HD|720p"}
- {id: 101, cat: Movies/HD, desc: "HD|REMUX"}
- {id: 100, cat: Movies/HD, desc: "HD|SPORT"}
- {id: 27, cat: XXX, desc: "HD|XxX"}
- {id: 102, cat: Movies/HD, desc: "SMALL|HD"}
# Musik
- {id: 13, cat: Audio, desc: "CHARTS"}
- {id: 31, cat: Audio/Lossless, desc: "FLAC"}
- {id: 97, cat: Audio/Audiobook, desc: "HOERSPIELE"}
- {id: 30, cat: Audio/MP3, desc: "MP3"}
- {id: 106, cat: Audio, desc: "SAMPLER"}
# Releaser
- {id: 18, cat: Movies, desc: "CR3WHD"}
- {id: 16, cat: Movies, desc: "ONKEL JENS"}
- {id: 17, cat: Movies, desc: "xTM|XviD"}
# Serie
- {id: 11, cat: TV/SD, desc: "DVD|SERIEN"}
- {id: 9, cat: TV/HD, desc: "HD|SERIEN"}
- {id: 32, cat: TV, desc: "MIXED|SERIEN"}
- {id: 10, cat: TV, desc: "PACK|SERIEN"}
- {id: 8, cat: TV/SD, desc: "SD|SERIEN"}
- {id: 105, cat: TV, desc: "SMALL|SERIE"}
- {id: 12, cat: TV, desc: "US|SERIEN"}
# Sonstige
- {id: 98, cat: PC, desc: "APPS"}
- {id: 90, cat: TV/Documentary, desc: "DOKUS"}
- {id: 91, cat: Books, desc: "EBOOKS"}
- {id: 14, cat: Movies, desc: "KINOHITS"}
- {id: 15, cat: Other, desc: "REQUEST"}
- {id: 23, cat: Other , desc: "SONSTIGES"}
- {id: 104, cat: XXX/Imageset, desc: "XXX|IMAGE"}
# Spiele
- {id: 96, cat: Console/NDS, desc: "GAMES|NDS"}
- {id: 92, cat: PC/Games, desc: "GAMES|PC"}
- {id: 94, cat: Console/PS4, desc: "GAMES|PS"}
- {id: 95, cat: Console/Wii, desc: "GAMES|WII"}
- {id: 93, cat: Console/Xbox, desc: "GAMES|XBOX"}
# Wrestling
- {id: 3, cat: TV/Sport, desc: "HD|RAW"}
- {id: 1, cat: TV/Sport, desc: "HD|SMACKD"}
- {id: 6, cat: TV/Sport, desc: "NXT"}
- {id: 7, cat: TV/Sport, desc: "PPV"}
- {id: 4, cat: TV/Sport, desc: "SD|RAW"}
- {id: 2, cat: TV/Sport, desc: "SD|SMACKD"}
- {id: 5, cat: TV/Sport, desc: "TNA"}
- {id: 1, cat: Movies, desc: "Movies"}
- {id: 2, cat: TV, desc: "TV"}
- {id: 3, cat: Audio, desc: "Music"}
- {id: 4, cat: Console, desc: "Games"}
- {id: 5, cat: PC, desc: "Apps"}
- {id: 6, cat: Other, desc: "Misc"}
- {id: 7, cat: XXX, desc: "XXX"}
modes:
search: [q]
tv-search: [q, season, ep]
tv-search: [q, season, ep, imdbid]
movie-search: [q, imdbid]
login:
path: login.php
path: login
method: form
inputs:
username: "{{ .Config.username }}"
password: "{{ .Config.password }}"
remember: 1
selectorinputs:
_token:
selector: meta[name="csrf-token"]
attribute: content
error:
- selector: div.stderr_info_wrap
- selector: form[action$="/login"] .text-red
test:
path: browse.php
selector: img[title="Ratio"] + i
path: /
selector: a[href$="/logout"]
ratio:
path: browse.php
selector: img[title="Ratio"] + i
path: /
selector: span:has(i.fa-sync-alt)
filters:
- name: regexp
args: "Ratio : (\\d+)"
search:
paths:
- path: browse.php
- path: filterTorrents
inputs:
$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
search: "{{ .Query.Keywords }}"
showsearch: "1"
incldead: "1"
orderby: "added"
sort: "desc"
$raw: "{{range .Categories}}categories[]={{.}}&{{end}}"
search: "{{if .Query.IMDBID}}{{else}}{{ .Keywords }}{{end}}"
uploader: ""
imdb: "{{ .Query.IMDBIDShort }}"
tvdb: ""
tmdb: ""
mal: ""
sorting: created_at
direction: desc
qty: 100
rows:
# correct selector depends on the "Empfohlene Torrents in der Liste anzeigen" profile option
selector: table.main > tbody > tr:contains("Alle Torrents") + tr > td > table.tableinborder > tbody > tr, div.bro_torr_wrap:not(:contains("Alle Torrents")) > table.tableinborder > tbody > tr
filters:
- name: andmatch
selector: table > tbody > tr
fields:
download:
selector: a[href^="download-ssl.php?torrent="]
attribute: href
title:
selector: div.title_wrap
attribute: title
filters:
- name: replace
args: ["[TsH]", ""]
category:
selector: a[href^="browse.php?cat="]
selector: a[href*="/categories/"]
attribute: href
filters:
- name: querystring
args: cat
- name: regexp
args: "/categories/.*?\\.(\\d+)"
title:
selector: a.view-torrent
download:
selector: a[href*="/download/"]
attribute: href
details:
selector: div.title_wrap > a
selector: a.view-torrent
attribute: href
size:
selector: div.bro_right_ad > b
filters:
- name: replace
args: [".", ""]
- name: replace
args: [",", "."]
grabs:
selector: div.bro_right_ae > b
selector: td:nth-child(5)
seeders:
selector: div.bro_box1_aa > b
selector: td:nth-child(7)
leechers:
selector: div.bro_box_aaa > b
date:
selector: div.bro_box_date > span
selector: td:nth-child(8)
grabs:
selector: td:nth-child(6)
filters:
- name: replace
args: ["\u00a0", " "]
- name: dateparse
args: "02.01.2006 15:04:05"
- name: regexp
args: ([\d\.]+)
date:
selector: time
filters:
# translations for Turkish|Estonian|Danish|Italian|Polish|Norwegian|Portoguese|Czech|Russian|Romanian|Spanish|French|German|Bulgarian|Dutch
- name: re_replace
args: ["(önce|tagasi|geleden|fa|temu|siden|atrás|nazpět|назад|acum|hace|il y a|vor|преди)", "ago"]
- name: re_replace
args: ["(dakika|minut|minuto|minuta|minutt|минута|Minute|minuut)", "minute"]
- name: re_replace
args: ["(dakika|minutit|minutter|minuti|minuty|minutos|минуты|минут|Minuten|минути|minuten)", "minutes"]
- name: re_replace
args: ["(saat|tund|time|ora|godzina|hora|hodina|час|oră|heure|Stunde|uur)", "hour"]
- name: re_replace
args: ["(saat|tundi|timer|ore|godziny|horas|hodiny|hoden|часа|часов|ore|heures|Stunden)", "hours"]
- name: re_replace
args: ["(gün|päev|dag|giorno|dzień|dia|den|день|zi|día|jour|Tag|ден)", "day"]
- name: re_replace
args: ["(gün|päeva|dage|giorni|dni|dias|dny|дня|дней|zile|días|jours|Tagen|дни|dagen)", "days"]
- name: re_replace
args: ["(hafta|nädal|uge|settimana|tydzień|uke|semana|týden|неделю|săptămână|semaine|Woche|седмица)", "week"]
- name: re_replace
args: ["(hafta|nädalat|uger|settimane|tygodnie|uker|semanas|týdny|недели|недель|săptămâni|semaines|Wochen|седмици|weken)", "weeks"]
- name: re_replace
args: [" (ay|kuu|måned|mese|miesiąc|mês|měsíc|месяц|lună|mes|mois|Monat|месец|maand)", "month"]
- name: re_replace
args: [" (ay|kuud|måneder|mesi|miesiące|meses|měsíce|месяца|месяцев|luni|meses|mois|Monaten|месеца|maanden)", "months"]
downloadvolumefactor:
case:
span[title="OnlyUp"]: "0"
"i[data-original-title=\"100% Free\"]": "0" # Single Torrent Freeleech
"i[data-original-title=\"Global freeleech\"]": "0" # Global Freeleech
"*": "1"
uploadvolumefactor:
case:
"i[data-original-title=\"Double upload\"]": "2" # Single Torrent Double Upload
"i[data-original-title=\"Double Upload\"]": "2" # Global Double Upload
"*": "1"

View File

@@ -6,6 +6,8 @@
type: private
encoding: UTF-8
links:
- https://torrent-turk.co/
legacylinks:
- https://torrent-turk.org/
caps:
@@ -13,23 +15,43 @@
- {id: 149, cat: Movies, desc: "Movies/Turkish"}
- {id: 151, cat: Movies/HD, desc: "Movies/Turkish/1080p"}
- {id: 152, cat: Movies/HD, desc: "Movies/Turkish/720p"}
- {id: 153, cat: Movies/DVD, desc: "Movies/Turkish/DVD5-DVD9"}
- {id: 154, cat: Movies/WEBDL, desc: "Movies/Turkish/BRRip-HDRip-DVDRip-WebDL"}
- {id: 155, cat: Movies/Other, desc: "Movies/Turkish/Boxset"}
- {id: 156, cat: Movies, desc: "Movies/Foreign"}
- {id: 157, cat: Movies/UHD, desc: "Movies/Foreign/4K"}
- {id: 157, cat: Movies/UHD, desc: "Movies/Foreign/4K / 3D"}
- {id: 159, cat: Movies/HD, desc: "Movies/Foreign/1080p"}
- {id: 160, cat: Movies/HD, desc: "Movies/Foreign/720p"}
- {id: 161, cat: Movies/DVD, desc: "Movies/Foreign/DVD5-DVD9"}
- {id: 162, cat: Movies/WEBDL, desc: "Movies/Foreign/BRRip-HDRip-DVDRip-WebDL"}
- {id: 163, cat: Movies/Other, desc: "Movies/Foreign/Boxset"}
- {id: 164, cat: TV, desc: "TV"}
- {id: 165, cat: TV, desc: "TV/Turkish"}
- {id: 166, cat: TV, desc: "TV/Foreign"}
- {id: 167, cat: TV/Other, desc: "TV Programs"}
- {id: 185, cat: TV/Documentary, desc: "TV/Documentary"}
- {id: 168, cat: TV/Other, desc: "TV/Other"}
- {id: 171, cat: Audio, desc: "Music"}
- {id: 172, cat: Audio, desc: "Music/Turkish"}
- {id: 173, cat: Audio, desc: "Music/Foreign"}
- {id: 184, cat: Audio, desc: "Music/Discography"}
- {id: 174, cat: Audio/Video, desc: "Music/Video"}
- {id: 175, cat: PC, desc: "Apps / Game / Graphics"}
- {id: 176, cat: PC, desc: "Apps"}
- {id: 177, cat: Other, desc: "Pictures"}
- {id: 183, cat: Books/Ebook, desc: "EBook"}
- {id: 178, cat: Books/Technical, desc: "Training Sets"}
- {id: 179, cat: PC, desc: "OS"}
- {id: 180, cat: PC/Games, desc: "PC/Games"}
- {id: 181, cat: Console, desc: "Playstation"}
modes:
search: [q]
tv-search: [q]
tv-search: [q, season, ep]
movie-search: [q]
settings:
@@ -42,18 +64,18 @@
- name: info
type: info
label: Layout
default: Only the classic profile is supported. Make sure to set the "Torrent listesi" option in your profile to "Klasik".
default: "<ol><li>Only the English Classic profile is supported.<li>Make sure to set the <b>Torrent Listing (Listeleme Biçimi)</b> option in your profile to <b>Classic (Klasik)</b><li>And set the <b>Language (Dil)</b> to <b>English</b><li>Using the <i>Modern</i> theme will prevent results, and using <i>Turkish</i> will prevent upload dates.</ol>"
login:
path: ?p=home&pid=1
method: form
form: form#loginbox_form
form: form#sls_form
submitpath: ajax/login.php
inputs:
action: "login"
loginbox_membername: "{{ .Config.username }}"
loginbox_password: "{{ .Config.password }}"
loginbox_remember: "true"
loginbox_remember: 1
selectorinputs:
securitytoken:
selector: "script:contains(\"stKey: \")"
@@ -98,6 +120,26 @@
download:
selector: a[href*="?p=torrents&pid=10&action=download"]
attribute: href
date:
optional: true
# Uploaded 30-01-2019 15:02 by
selector: td.torrent_name:not(:contains(" at "))
filters:
- name: regexp
args: "Uploaded (.+?) by"
- name: dateparse
args: "02-01-2006 15:04"
date:
optional: true
# Uploaded Friday at 05:11 by
# Uploaded Today at 00:48 by
# Uploaded Yesterday at 23:57 by
selector: td.torrent_name:contains(" at ")
filters:
- name: regexp
args: "Uploaded (.+?) by"
- name: replace
args: [" at ", " "]
size:
selector: a[rel="torrent_size"]
seeders:
@@ -113,11 +155,9 @@
downloadvolumefactor:
case:
"img[title=\"FREE!\"]": "0"
"img[title=\"Download Multiplier: 0.5\"]": "0.5"
"*": "1"
uploadvolumefactor:
case:
"img[title=\"Upload Multiplier: 2\"]": "2"
"*": "1"
date:
selector: td.torrent_name > abbr.timeago
optional: true
attribute: data-time

View File

@@ -8,6 +8,7 @@
followredirect: true
links:
- https://wvw.torrent9.uno/
- https://wvw.t9.pe/
legacylinks:
- http://www.torrent9.ec/
- http://www.torrent9.red/
@@ -43,7 +44,7 @@
search:
paths:
- path: "{{ if .Keywords }}/search_torrent/{{ .Keywords }}/page-0{{else}}/top_torrent.php{{end}}"
- path: "{{ if .Keywords }}/search_torrent/{{ re_replace .Keywords \"[']+\" \"\" }}/page-0{{else}}/top_torrent.php{{end}}"
rows:
selector: div.table-responsive > table tbody tr
fields:

View File

@@ -84,8 +84,7 @@
login:
path: torrent/account-login.php
method: form
form: form[action="account-login.php"]
method: post
inputs:
username: "{{ .Config.username }}"
password: "{{ .Config.password }}"
@@ -93,7 +92,7 @@
- selector: div.row p.red-text
test:
path: torrent/torrents-search.php
selector: a[href*="logout"]
selector: div.myB-content:contains("Ratio:")
ratio:
path: torrent/torrents-search.php

View File

@@ -6,9 +6,9 @@
type: private
encoding: UTF-8
links:
- https://et8.org/
legacylinks:
- http://et8.org/
legacylinks:
- https://et8.org/
caps:
categorymappings:

View File

@@ -1,63 +0,0 @@
---
site: torrentcouch
name: TorrentCouch
description: "TorrentCounch is a Public TV tracker"
language: en-us
type: public
encoding: UTF-8
links:
- https://torrentcouch.net/
legacylinks:
- https://torrentcouch.com/
caps:
categorymappings:
- {id: 1, cat: TV, desc: "TV"}
modes:
search: [q]
tv-search: [q, season, ep]
settings: []
download:
selector: tr td a[href*="/files/download/"]
search:
# https://torrentcouch.com/?s=expanse
# https://torrentcouch.net/page/3/?s=expanse
paths:
- path: "{{if .Keywords}}/?s={{ .Keywords}}{{else}}/{{end}}"
- path: "{{if .Keywords}}/page/2/?s={{ .Keywords}}{{else}}{{end}}"
- path: "{{if .Keywords}}/page/3/?s={{ .Keywords}}{{else}}{{end}}"
- path: "{{if .Keywords}}/page/4/?s={{ .Keywords}}{{else}}{{end}}"
rows:
selector: article
fields:
title:
selector: h1.entry-title a
category:
text: "1"
details:
selector: h1.entry-title a
attribute: href
description:
selector: p
download:
selector: h1.entry-title a
attribute: href
size:
text: "500 MB"
seeders:
text: "1"
leechers:
text: "1"
date:
selector: span.posted-on a time
filters:
- name: dateparse
args: "January 2, 2006"
downloadvolumefactor:
text: "0"
uploadvolumefactor:
text: "1"

View File

@@ -66,39 +66,39 @@
selector: div[class="tgxtablerow clickable-row click"]
fields:
title:
selector: div.tgxtablecell:nth-child(3) div a
selector: div a[href^="/torrent/"]
attribute: title
category:
selector: div.tgxtablecell a
selector: div a[href^="/torrents.php?cat="]
attribute: href
filters:
- name: querystring
args: cat
details:
selector: div.tgxtablecell:nth-child(3) div a
selector: div a[href^="/torrent/"]
attribute: href
download:
selector: div.tgxtablecell:nth-child(4) a
selector: div a[href*="/get/"]
attribute: href
magnet:
selector: div.tgxtablecell:nth-child(4) a:nth-child(2)
selector: div a[href^="magnet:?"]
attribute: href
size:
selector: div.tgxtablecell:nth-child(7) span
selector: div span[style^="border-radius"]
seeders:
selector: div.tgxtablecell:nth-child(10) span font b
selector: div span[title="Seeders/Leechers"] font b
leechers:
selector: div.tgxtablecell:nth-child(10) span font:nth-child(2) b
selector: div span[title="Seeders/Leechers"] font:nth-child(2) b
date:
# 20Mins ago
optional: true
selector: div.tgxtablecell:nth-child(11) small:contains("ago")
selector: div.tgxtablecell:last-of-type:contains("ago")
filters:
- name: timeago
date:
# 24/12/18 13:55
optional: true
selector: div.tgxtablecell:nth-child(11) small:contains(":")
selector: div.tgxtablecell:last-of-type small:contains(":")
filters:
- name: dateparse
args: "02/01/06 15:04"

View File

@@ -43,6 +43,10 @@
type: checkbox
label: "Only include verifed content in results"
default: false
- name: info
type: info
label: A note about TP2
default: TP2 does not display categories in its search results page. To add to Sonarr or Radarr replace all categories with 7000.
download:
selector: "#download > div:nth-child(2) > div:nth-child(1) > a"

View File

@@ -6,6 +6,8 @@
type: private
encoding: windows-1252
links:
- https://tsctracker.org/
legacylinks:
- https://tsctracker.net/
caps:
@@ -175,4 +177,4 @@
"*": "1"
uploadvolumefactor:
case:
"*": "1"
"*": "1"

View File

@@ -15,19 +15,22 @@
- {id: 9, cat: TV/Anime, desc: "Anime/SD"}
- {id: 1, cat: PC/0day, desc: "Apps"}
- {id: 27, cat: Books, desc: "Bookware"}
- {id: 32, cat: Books/EBook, desc: "EBOOK"}
- {id: 32, cat: Books/Ebook, desc: "EBOOK"}
- {id: 47, cat: Console/Other, desc: "GAMES/NSW"}
- {id: 60, cat: Console/Other, desc: "GAMES/ATARI"}
- {id: 63, cat: Console/Other, desc: "GAMES/UPDATES"}
- {id: 2, cat: PC/Games, desc: "Games/PC"}
- {id: 8, cat: Console/PS3, desc: "Games/PS3"}
- {id: 30, cat: Console/PS4, desc: "GAMES/PS4"}
- {id: 7, cat: Console/PSP, desc: "Games/PSP"}
- {id: 16, cat: Console/Wii, desc: "GAMES/WII"}
- {id: 29, cat: Console/WiiU, desc: "GAMES/WIIU"}
- {id: 17, cat: Console/XBox360, desc: "GAMES/XBOX360"}
- {id: 17, cat: Console/XBox 360, desc: "GAMES/XBOX360"}
- {id: 50, cat: Movies/BluRay, desc: "Movies/Bluray-UHD"}
- {id: 31, cat: Movies/BluRay, desc: "MOVIES/COMPLETE-BLURAY"}
- {id: 3, cat: Movies/DVD, desc: "MOVIES/DVDR"}
- {id: 39, cat: Movies/Foreign, desc: "MOVIES/HD-Foreign"}
- {id: 62, cat: Movies/Foreign, desc: "MOVIES/SD-Foreign"}
- {id: 19, cat: Movies/HD, desc: "MOVIES/X264"}
- {id: 49, cat: Movies/HD, desc: "Movies/X265"}
- {id: 25, cat: Movies/SD, desc: "MOVIES/XVID"}
@@ -56,6 +59,8 @@
- {id: 24, cat: TV/SD, desc: "TV/DVDRIP"}
- {id: 18, cat: TV/SD, desc: "TV/SD"}
- {id: 26, cat: TV/HD, desc: "TV/X264"}
- {id: 61, cat: TV/UHD, desc: "TV/2160P"}
- {id: 64, cat: TV/FOREIGN, desc: "TV/X264-FOREIGN"}
modes:
@@ -85,7 +90,7 @@
- name: info
type: info
label: Results Per Page
default: For best results, change the 'Torrents per page' setting to 100 on your 'Personal Options' from the 'Personal' menu on the Mega-Blitz webpage.
default: For best results, change the 'Torrents per page' setting to 100 on your 'Torrent Options' from the 'Pers Tools > UserCP' menu on the TorrentSeeds webpage.
login:
path: login.php
@@ -94,7 +99,6 @@
inputs:
username: "{{ .Config.username }}"
password: "{{ .Config.password }}"
submitme: "X"
error:
- selector: h2:contains("Login failed!")
message:
@@ -148,11 +152,19 @@
attribute: href
files:
selector: td:nth-of-type(5)
# 2 flavours of dates
date:
selector: td:nth-of-type(7)
# Today<br /> 10:20 AM
# Yesterday<br /> 08:03 PM
optional: true
selector: td:nth-child(7):contains("day")
date:
# Feb 14 2019<br /> 10:20 AM
optional: true
selector: td:nth-child(7):not(:contains("day"))
filters:
- name: dateparse
args: "Jan 02 2006 03:04 PM"
args: "Jan 2 2006 03:04 pm"
size:
selector: td:nth-of-type(8)
grabs:

View File

@@ -0,0 +1,125 @@
---
site: totallykids
name: TotallyKids
description: "TotallyKids (TK) is a Private Torrent Tracker for CHILDRENS MOVIES / TV / GENERAL"
language: en-us
type: private
encoding: UTF-8
links:
- http://www.totallykids.tv/
settings:
- name: username
type: text
label: Username
- name: password
type: password
label: Password
- name: info_results
type: info
label: "Search results"
default: "For best results, increase the torrents number in your profile to 100.<br />Default is 15."
caps:
categorymappings:
- {id: 5, cat: Audio, desc: "Music"}
- {id: 6, cat: Audio/Audiobook, desc: "Audiobooks"}
- {id: 4, cat: Books/Comics, desc: "Comics"}
- {id: 7, cat: Books/EBook, desc: "E-Books"}
- {id: 16, cat: Movies, desc: "Family Movies"}
- {id: 23, cat: Movies, desc: "Teen Movies"}
- {id: 8, cat: PC/Games, desc: "Games"}
- {id: 1, cat: TV, desc: "Kids"}
- {id: 2, cat: TV, desc: "Family"}
- {id: 15, cat: TV, desc: "Educational"}
- {id: 24, cat: TV, desc: "Teens"}
modes:
search: [q]
tv-search: [q, season, ep]
movie-search: [q]
music-search: [q]
login:
path: index.php?page=login
method: form
form: form[action^="index.php?page=login"]
inputs:
uid: "{{ .Config.username }}"
pwd: "{{ .Config.password }}"
error:
- selector: tr td span[style="color:#FF0000;"]
test:
path: index.php
selector: a[href="logout.php"]
search:
paths:
# http://www.totallykids.tv/index.php?page=torrents&search=scooby&category=1;2;5;6;4;7;8;15;24;16;23&options=0&active=0
- path: index.php
inputs:
page: torrents
search: "{{ if .Keywords }}{{ .Keywords }}{{else}}{{end}}"
category: "{{if .Categories}}{{range .Categories}}{{.}};{{end}}{{else}}0{{end}}"
options: 0
active: 0
rows:
selector: table.lista tr td table.lista tr:has(a[href^="index.php?page=torrent-details"])
fields:
title:
selector: td a[href^="index.php?page=torrent-details"]
details:
selector: td a[href^="index.php?page=torrent-details"]
attribute: href
category:
selector: td a[href^="index.php?page=torrents&category="]
attribute: href
filters:
- name: querystring
args: category
download:
selector: td a[href^="download.php"]
attribute: href
imdb:
optional: true
selector: a[href*="http://www.imdb.com/title/"]
attribute: href
filters:
# http://anonym.to?javascript:popdetails('http://www.imdb.com/title/tt0086817');
- name: replace
args: [" http://anonym.to?javascript:popdetails('", ""]
- name: replace
args: ["');", ""]
size:
selector: td:nth-child(10)
# two flavours of dates
date:
# Yesterday at 10:03:30 PM
selector: td:nth-child(5):contains("day")
optional: true
filters:
- name: re_replace
args: ["[ ]at|[\\s+]|[//\xa0],\\/g", " "]
date:
# February 09, 2019, 06:35:08 AM
selector: td:nth-child(5):not(:contains("day"))
optional: true
filters:
- name: re_replace
args: ["[,]|[\\s+]|[//\xa0],\\/g", " "]
- name: dateparse
args: "January 02 2006 03:04:05 PM"
seeders:
selector: td:nth-child(6)
leechers:
selector: td:nth-child(7)
grabs:
selector: td:nth-child(8)
downloadvolumefactor:
case:
img[src="gold/gold.gif"]: "0"
"*": "1"
uploadvolumefactor:
text: "1"

View File

@@ -78,8 +78,13 @@
files:
selector: td:nth-last-child(8)
size:
# 1,36 GB
# 296,98 MB
# 1.018,29 MB
selector: td:nth-last-child(5)
filters:
- name: replace
args: [".", ""]
- name: replace
args: [",", "."]
grabs:

View File

@@ -3,7 +3,7 @@
name: Xtreme Zone
description: "XtreMeZone (MYXZ) is a ROMANIAN Private Torrent Tracker for MOVIES / TV / GENERAL"
language: ro-ro
type: semi-private
type: private
encoding: UTF-8
links:
- https://www.myxz.eu/

View File

@@ -160,9 +160,10 @@
args: ["(.*)[sS](\\d{1,4})$", "$1"]
- name: replace
args: ["\"", ""]
- name: trim
paths:
- path: "https://{{ .Config.searchanddlurl }}/engine/search?category={{ .Config.category }}&name={{if .Config.enhancedAnime}}{{ re_replace .Keywords \"([\\.\\s\\[\\-])(\\d+)$\" \"$1e$2\" }}{{else}}{{ re_replace .Keywords \"\\s\" \"\"\"\" }}{{end}}&description=&file=&uploader=&sub_category=&do=search&order=desc&sort=publish_date"
- path: "https://{{ .Config.searchanddlurl }}/engine/search?category={{ .Config.category }}&name={{if .Config.enhancedAnime}}{{ re_replace .Keywords \"([\\.\\s\\[\\-])(\\d+)$\" \"$1e$2\" }}{{else}}{{ re_replace .Keywords \"\\s\" \"\"\"\" }}{{end}}&description=&file=&uploader=&sub_category=&do=search&order=desc&sort=publish_date&page=50"
- path: "https://{{ .Config.searchanddlurl }}/engine/search?category={{ .Config.category }}&name={{if .Config.enhancedAnime}}{{ re_replace .Keywords \"([\\.\\s\\[\\-])(\\d+)$\" \"$1e$2\" }}{{else}}{{ .Keywords }}{{end}}&description=&file=&uploader=&sub_category=&do=search&order=desc&sort=publish_date"
- path: "https://{{ .Config.searchanddlurl }}/engine/search?category={{ .Config.category }}&name={{if .Config.enhancedAnime}}{{ re_replace .Keywords \"([\\.\\s\\[\\-])(\\d+)$\" \"$1e$2\" }}{{else}}{{ .Keywords }}{{end}}&description=&file=&uploader=&sub_category=&do=search&order=desc&sort=publish_date&page=50"
rows:
selector: "table.table > tbody > tr"
fields:

View File

@@ -1617,23 +1617,22 @@ namespace Jackett.Common.Indexers
queryCollection.Add("t", "0");
queryCollection.Add("submit", "Search");
queryCollection.Add("sr", "topics");
//queryCollection.Add("sr", "posts");
//queryCollection.Add("ch", "99999");
// if the search string is empty use the getnew view
if (string.IsNullOrWhiteSpace(searchString))
{
queryCollection.Add("search_id", "newposts");
//queryCollection.Add("search_id", "newposts");
searchString = "test";
}
else // use the normal search
{
//else // use the normal search
//{
searchString = searchString.Replace("-", " ");
queryCollection.Add("terms", "all");
queryCollection.Add("keywords", searchString);
queryCollection.Add("author", "");
queryCollection.Add("sc", "1");
queryCollection.Add("sf", "titleonly");
}
//}
var searchUrl = SearchUrl + "?" + queryCollection.GetQueryString();
results = await RequestStringWithCookies(searchUrl);

View File

@@ -18,7 +18,7 @@ namespace Jackett.Common.Indexers
{
public class BeyondHD : BaseWebIndexer
{
private string SearchUrl { get { return SiteLink + "browse.php?searchin=title&incldead=0&"; } }
private string SearchUrl { get { return SiteLink + "browse.php?searchin=descr&incldead=1&"; } }
private new ConfigurationDataLoginLink configData
{
@@ -43,6 +43,8 @@ namespace Jackett.Common.Indexers
configData.DisplayText.Value = "Go to the general tab of your BeyondHD user profile and create/copy the Login Link.";
TorznabCaps.SupportsImdbSearch = true;
AddCategoryMapping(37, TorznabCatType.MoviesBluRay, "Movie / Blu-ray");
AddCategoryMapping(71, TorznabCatType.Movies3D, "Movie / 3D");
AddCategoryMapping(83, TorznabCatType.Movies3D, "FraMeSToR 3D");
@@ -101,12 +103,22 @@ namespace Jackett.Common.Indexers
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
List<ReleaseInfo> releases = new List<ReleaseInfo>();
Regex IMDBRegEx = new Regex(@"tt(\d+)", RegexOptions.Compiled);
var searchString = query.GetQueryString();
var searchUrl = SearchUrl;
var queryCollection = new NameValueCollection();
var searchStringIsImdbQuery = (ParseUtil.GetImdbID(searchString) != null);
if (!string.IsNullOrWhiteSpace(searchString))
if (query.IsImdbQuery)
{
queryCollection.Add("search", query.ImdbID);
}
else if (searchStringIsImdbQuery)
{
queryCollection.Add("search", searchString);
}
else if (!string.IsNullOrWhiteSpace(searchString))
{
Regex ReplaceRegex = new Regex("[^a-zA-Z0-9]+");
searchString = "%" + ReplaceRegex.Replace(searchString, "%") + "%";
@@ -139,13 +151,15 @@ namespace Jackett.Common.Indexers
release.Category = MapTrackerCatToNewznab(catStr);
var qLink = row.ChildElements.ElementAt(2).FirstChild.Cq();
release.Link = new Uri(SiteLink + "/" + qLink.Attr("href"));
release.Link = new Uri(SiteLink + qLink.Attr("href"));
var torrentId = qLink.Attr("href").Split('=').Last();
var descCol = row.ChildElements.ElementAt(3);
var qCommentLink = descCol.FirstChild.Cq();
release.Title = qCommentLink.Text();
release.Comments = new Uri(SiteLink + "/" + qCommentLink.Attr("href"));
if (!query.IsImdbQuery && !query.MatchQueryStringAND(release.Title))
continue;
release.Comments = new Uri(SiteLink + qCommentLink.Attr("href"));
release.Guid = release.Comments;
release.Link = new Uri($"{SiteLink}download.php?torrent={torrentId}");
@@ -164,7 +178,14 @@ namespace Jackett.Common.Indexers
var grabs = qRow.Find("td:nth-child(9) > a").Get(0).FirstChild.ToString();
release.Grabs = ParseUtil.CoerceInt(grabs);
release.DownloadVolumeFactor = 1;
var imdbLink = qRow.Find("a[href*=\"imdb.com/title/\"]").Attr("href");
if (imdbLink != null)
{
var IMDBMatch = IMDBRegEx.Match(imdbLink);
release.Imdb = ParseUtil.CoerceLong(IMDBMatch.Groups[1].Value);
}
release.DownloadVolumeFactor = 0;
release.UploadVolumeFactor = 1;
releases.Add(release);

View File

@@ -25,6 +25,10 @@ namespace Jackett.Common.Indexers
{ get { return SiteLink + "browse.php"; } }
private bool TorrentHTTPSMode => configData.TorrentHTTPSMode.Value;
private static readonly string[] certificateHashs = new string[] {
"4482711D19A95CDE01D7958E5F1295E05BCA335D", // Let's Encrypt Authority X3
};
private new ConfigurationDataEliteTracker configData
{
get { return (ConfigurationDataEliteTracker)base.configData; }
@@ -124,6 +128,10 @@ namespace Jackett.Common.Indexers
AddCategoryMapping(65, TorznabCatType.TVSport, "UFC");
AddCategoryMapping(37, TorznabCatType.XXX, "XXX");
foreach (var certificateHash in certificateHashs)
webclient.AddTrustedCertificate(new Uri(SiteLink).Host, certificateHash);
}
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)

View File

@@ -117,7 +117,7 @@ namespace Jackett.Common.Indexers
return IndexerConfigurationStatus.RequiresTesting;
}
List<ReleaseInfo> parseTorrents(WebClientStringResult results, String seasonep, TorznabQuery query, int already_founded, int limit)
List<ReleaseInfo> parseTorrents(WebClientStringResult results, String seasonep, TorznabQuery query, int already_founded, int limit, int previously_parsed_on_page)
{
var releases = new List<ReleaseInfo>();
try
@@ -128,7 +128,7 @@ namespace Jackett.Common.Indexers
var rows = dom[".box_torrent_all"].Find(".box_torrent");
// Check torrents only till we reach the query Limit
for(int i=0; (i<rows.Length && ((already_founded + releases.Count) < limit )); i++)
for(int i= previously_parsed_on_page; (i<rows.Length && ((already_founded + releases.Count) < limit )); i++)
{
try
{
@@ -172,7 +172,7 @@ namespace Jackett.Common.Indexers
release.Category = MapTrackerCatToNewznab(cat);
/* if the release name not contains the language we add it because it is know from category */
if (cat.Contains("hun") && !release.Title.Contains("hun"))
if (cat.Contains("hun") && !release.Title.ToLower().Contains("hun"))
release.Title += ".hun";
if (seasonep == null)
@@ -272,6 +272,15 @@ namespace Jackett.Common.Indexers
CQ dom = results.Content;
int numVal = 0;
// find number of torrents / page
int torrent_per_page = dom[".box_torrent_all"].Find(".box_torrent").Length;
if (torrent_per_page==0)
return releases;
int start_page = (query.Offset / torrent_per_page)+1;
int previously_parsed_on_page = query.Offset - (start_page * torrent_per_page) + 1; //+1 because indexing start from 0
if (previously_parsed_on_page < 0)
previously_parsed_on_page = query.Offset;
// find pagelinks in the bottom
var pagelinks = dom["div[id=pager_bottom]"].Find("a");
if (pagelinks.Length > 0)
@@ -293,15 +302,22 @@ namespace Jackett.Common.Indexers
if (limit == 0)
limit = 100;
releases = parseTorrents(results, seasonep, query, releases.Count, limit);
if (start_page == 1)
{
releases = parseTorrents(results, seasonep, query, releases.Count, limit, previously_parsed_on_page);
previously_parsed_on_page = 0;
start_page++;
}
// Check all the pages for the torrents.
// The starting index is 2. (the first one is the original where we parse out the pages.)
for (int i=2; (i<= numVal && releases.Count < limit); i++ )
for (int i= start_page; (i<= numVal && releases.Count < limit); i++ )
{
pairs.Add(new KeyValuePair<string, string>("oldal", i.ToString()));
results = await PostDataWithCookiesAndRetry(SearchUrl, pairs);
releases.AddRange(parseTorrents(results, seasonep, query, releases.Count, limit));
releases.AddRange(parseTorrents(results, seasonep, query, releases.Count, limit, previously_parsed_on_page));
previously_parsed_on_page = 0;
pairs.Remove(new KeyValuePair<string, string>("oldal", i.ToString()));
}

View File

@@ -62,9 +62,9 @@ namespace Jackett.Common.Indexers
private static Uri[] ExtraSiteLinkUris = new Uri[]
{
new Uri("http://torrentrapid.com/"),
new Uri("http://torrentlocura.com/"),
new Uri("http://tumejortorrent.com/"),
new Uri("http://pctnew.com/"),
new Uri("http://torrentlocura.com/"),
};
private static Uri[] LegacySiteLinkUris = new Uri[]
@@ -157,7 +157,7 @@ namespace Jackett.Common.Indexers
links.Add(linkParam.AbsoluteUri);
IEnumerable<Uri> knownUris = (new Uri[] { DefaultSiteLinkUri }).
Concat(ExtraSiteLinkUris).Concat(LegacySiteLinkUris);
Concat(ExtraSiteLinkUris);
foreach (Uri extraSiteUri in knownUris)
{
@@ -178,9 +178,15 @@ namespace Jackett.Common.Indexers
await FollowIfRedirect(results);
var content = results.Content;
Match match = _downloadMatchRegex.Match(content);
if (match.Success)
result = await base.Download(new Uri(match.Groups[0].Value));
if (content != null)
{
Match match = _downloadMatchRegex.Match(content);
if (match.Success)
{
Uri uriLink = new Uri(new Uri(link), match.Groups[0].Value);
result = await base.Download(uriLink);
}
}
}
catch
{

View File

@@ -23,9 +23,9 @@ namespace Jackett.Common.Indexers
"https://polishtracker.net/",
};
private new ConfigurationDataBasicLoginWithRSSAndDisplay configData
private new ConfigurationDataBasicLoginWithEmail configData
{
get { return (ConfigurationDataBasicLoginWithRSSAndDisplay)base.configData; }
get { return (ConfigurationDataBasicLoginWithEmail)base.configData; }
set { base.configData = value; }
}
@@ -38,7 +38,7 @@ namespace Jackett.Common.Indexers
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLoginWithRSSAndDisplay())
configData: new ConfigurationDataBasicLoginWithEmail())
{
Encoding = Encoding.UTF8;
Language = "pl-pl";
@@ -64,7 +64,7 @@ Encoding = Encoding.UTF8;
var pairs = new Dictionary<string, string>
{
{ "email", configData.Username.Value },
{ "email", configData.Email.Value },
{ "pass", configData.Password.Value }
};
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, SiteLink);
@@ -72,6 +72,8 @@ Encoding = Encoding.UTF8;
await ConfigureIfOK(result.Cookies, result.Cookies != null && result.Cookies.Contains("id="), () =>
{
var errorMessage = result.Content;
if (errorMessage.Contains("Error!"))
errorMessage = "E-mail or password is incorrect";
throw new ExceptionWithConfigData(errorMessage, configData);
});
return IndexerConfigurationStatus.RequiresTesting;

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Jackett.Common.Models;
@@ -37,12 +38,13 @@ namespace Jackett.Common.Indexers
private DateTime lastTokenFetch;
private string token;
private string app_id;
private bool provideTorrentLink = false;
private readonly TimeSpan TOKEN_DURATION = TimeSpan.FromMinutes(10);
private bool HasValidToken { get { return !string.IsNullOrEmpty(token) && lastTokenFetch > DateTime.Now - TOKEN_DURATION; } }
public Rarbg(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps)
public Rarbg(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, IProtectionService ps)
: base(name: "RARBG",
description: "RARBG is a Public torrent site for MOVIES / TV / GENERAL",
link: "https://rarbg.to/",
@@ -57,6 +59,10 @@ namespace Jackett.Common.Indexers
Language = "en-us";
Type = "public";
var provideTorrentLinkItem = new ConfigurationData.BoolItem { Value = false };
provideTorrentLinkItem.Name = "Generate torrent download link additionally to magnet (not recommended due to DDoS protection).";
configData.AddDynamic("providetorrentlink", provideTorrentLinkItem);
TorznabCaps.SupportsImdbSearch = true;
webclient.requestDelay = 2.1; // The api has a 1req/2s limit.
@@ -89,6 +95,17 @@ namespace Jackett.Common.Indexers
app_id = "jackett_v" + EnvironmentUtil.JackettVersion;
}
public override void LoadValuesFromJson(JToken jsonConfig, bool useProtectionService = false)
{
base.LoadValuesFromJson(jsonConfig, useProtectionService);
var provideTorrentLinkItem = (ConfigurationData.BoolItem)configData.GetDynamic("providetorrentlink");
if (provideTorrentLinkItem != null)
{
provideTorrentLink = provideTorrentLinkItem.Value;
}
}
private async Task CheckToken()
{
if (!HasValidToken)
@@ -109,7 +126,7 @@ namespace Jackett.Common.Indexers
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
configData.LoadValuesFromJson(configJson);
LoadValuesFromJson(configJson);
var releases = await PerformQuery(new TorznabQuery());
await ConfigureIfOK(string.Empty, releases.Count() > 0, () =>
@@ -210,14 +227,15 @@ namespace Jackett.Common.Indexers
foreach (var item in jsonContent.Value<JArray>("torrent_results"))
{
var release = new ReleaseInfo();
release.Title = item.Value<string>("title");
release.Title = WebUtility.HtmlDecode(item.Value<string>("title"));
release.Category = MapTrackerCatDescToNewznab(item.Value<string>("category"));
release.MagnetUri = new Uri(item.Value<string>("download"));
release.InfoHash = release.MagnetUri.ToString().Split(':')[3].Split('&')[0];
release.Comments = new Uri(item.Value<string>("info_page"));
release.Link = release.Comments; // in case of a torrent download we grab the link from the details page in Download()
if (provideTorrentLink)
release.Link = release.Comments; // in case of a torrent download we grab the link from the details page in Download()
release.Guid = release.MagnetUri;
var episode_info = item.Value<JToken>("episode_info");

View File

@@ -0,0 +1,321 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using CsQuery;
using Jackett.Common.Models;
using Jackett.Common.Models.IndexerConfig.Bespoke;
using Jackett.Common.Services.Interfaces;
using Jackett.Common.Utils;
using Jackett.Common.Utils.Clients;
using Newtonsoft.Json.Linq;
using NLog;
namespace Jackett.Common.Indexers
{
public class TVstore : BaseWebIndexer
{
private string LoginUrl { get { return SiteLink + "takelogin.php"; } }
private string LoginPageUrl { get { return SiteLink + "login.php?returnto=%2F"; } }
private string SearchUrl { get { return SiteLink + "torrent/br_process.php"; } }
private string DownloadUrl { get { return SiteLink + "torrent/download.php"; } }
private string BrowseUrl { get { return SiteLink + "torrent/browse.php"; } }
private List<SeriesDetail> series = new List<SeriesDetail>();
private Regex _searchStringRegex = new Regex(@"(.+?)S0?(\d+)(E0?(\d+))?$", RegexOptions.IgnoreCase);
private new ConfigurationDataTVstore configData
{
get { return (ConfigurationDataTVstore)base.configData; }
set { base.configData = value; }
}
public TVstore(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, IProtectionService ps)
: base(name: "TVstore",
description: "TV Store is a HUNGARIAN Private Torrent Tracker for TV",
link: "https://tvstore.me/",
caps: new TorznabCapabilities(),
configService: configService,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataTVstore())
{
Encoding = Encoding.UTF8;
Language = "hu-hu";
Type = "private";
AddCategoryMapping(1, TorznabCatType.TV);
AddCategoryMapping(2, TorznabCatType.TVHD);
AddCategoryMapping(3, TorznabCatType.TVSD);
}
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
LoadValuesFromJson(configJson);
var loginPage = await RequestStringWithCookies(LoginPageUrl, string.Empty);
var pairs = new Dictionary<string, string> {
{ "username", configData.Username.Value },
{ "password", configData.Password.Value },
{ "back", "%2F" },
{ "logout", "1"}
};
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, referer: SiteLink);
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("Főoldal"), () =>
{
throw new ExceptionWithConfigData("Error while trying to login with: Username: " + configData.Username.Value +
" Password: " + configData.Password.Value, configData);
});
return IndexerConfigurationStatus.RequiresTesting;
}
/// <summary>
/// Parses the torrents from the content
/// </summary>
/// <returns>The parsed torrents.</returns>
/// <param name="results">The result of the query</param>
/// <param name="query">Query.</param>
/// <param name="already_found">Number of the already found torrents.(used for limit)</param>
/// <param name="limit">The limit to the number of torrents to download </param>
async Task<List<ReleaseInfo>> ParseTorrents(WebClientStringResult results, TorznabQuery query, int already_found, int limit)
{
var releases = new List<ReleaseInfo>();
try
{
String content = results.Content;
/* Content Looks like this
* 2\15\2\1\1727\207244\1x08 \[WebDL-720p - Eng - AJP69]\gb\2018-03-09 08:11:53\akció, kaland, sci-fi \0\0\1\191170047\1\0\Anonymous\50\0\0\\0\4\0\174\0\
* 1\ 0\0\1\1727\207243\1x08 \[WebDL-1080p - Eng - AJP69]\gb\2018-03-09 08:11:49\akció, kaland, sci-fi \0\0\1\305729738\1\0\Anonymous\50\0\0\\0\8\0\102\0\0\0\0\1\\\
*/
var splits = content.Split('\\');
int i = 0;
ReleaseInfo release = new ReleaseInfo();
/* Split the releases by '\' and go through them.
* 26 element belongs to one torrent
*/
foreach (var s in splits)
{
switch (i)
{
case 4:
//ID of the series
//Get IMDB id form site series database
SeriesDetail seriesinfo = series.Find(x => x.id.Contains(s));
if (seriesinfo != null && !s.Equals(""))
release.Imdb = long.Parse(seriesinfo.imdbid);
goto default;
case 5:
//ID of the torrent
Int32 unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
string fileinfoURL = SearchUrl + "?func=getToggle&id=" + s + "&w=F&pg=0&now=" + unixTimestamp;
string fileinfo = (await RequestStringWithCookiesAndRetry(fileinfoURL)).Content;
release.Link = new Uri(DownloadUrl + "?id=" + s);
release.Guid = release.Link;
release.Comments = release.Link;
string[] fileinf = fileinfo.Split(new string[] { "\\\\" }, StringSplitOptions.None);
if (fileinf.Length > 1)
release.Title = fileinf[1];
goto default;
/*case 6:
Console.WriteLine("Series season/ep =" + s); --> 9x10
goto default;*/
/*case 7:
Console.WriteLine("Releaseinfo =" + s); --->Releaseinfo =[HDTV - Rip - Eng - SVA]
goto default;*/
case 9:
release.PublishDate = DateTime.Parse(s, CultureInfo.InvariantCulture);
goto default;
case 13:
release.Files = int.Parse(s);
goto default;
case 14:
release.Size = long.Parse(s);
goto default;
case 23:
release.Seeders = int.Parse(s);
goto default;
case 24:
release.Peers = (int.Parse(s) + release.Seeders);
goto default;
case 25:
release.Grabs = int.Parse(s);
goto default;
case 26:
/* This is the last element for the torrent. So add it to releases and start parsing to new torrent */
i = 0;
release.Category = new List<int> { TvCategoryParser.ParseTvShowQuality(release.Title) };
//todo Added some basic configuration need to improve it
release.MinimumRatio = 1;
release.MinimumSeedTime = 172800;
release.DownloadVolumeFactor = 1;
release.UploadVolumeFactor = 1;
if ((already_found + releases.Count) < limit)
{
releases.Add(release);
}
else
{
return releases;
}
release = new ReleaseInfo();
break;
default:
i++;
break;
}
}
}
catch (Exception ex)
{
OnParseError(results.Content, ex);
}
return releases;
}
/* Search is possible only based by Series ID.
* All known series ID is on main page, with their attributes. (ID, EngName, HunName, imdbid)
*/
/// <summary>
/// Get all series info known by site
/// These are:
/// - Series ID
/// - Hungarian name
/// - English name
/// - IMDB ID
/// </summary>
/// <returns>The series info.</returns>
protected async Task<Boolean> GetSeriesInfo()
{
var result = (await RequestStringWithCookiesAndRetry(BrowseUrl)).Content;
CQ dom = result;
var scripts = dom["script"];
foreach (var script in scripts)
{
if (script.TextContent.Contains("catsh=Array"))
{
string[] seriesknowbysite = Regex.Split(script.TextContent, "catl");
for (int i = 1; i < seriesknowbysite.Length; i++)
{
try
{
var id = seriesknowbysite[i];
string[] serieselement = WebUtility.HtmlDecode(id).Split(';');
SeriesDetail sd = new SeriesDetail();
sd.HunName = serieselement[1].Split('=')[1].Trim('\'').ToLower();
sd.EngName = serieselement[2].Split('=')[1].Trim('\'').ToLower();
sd.id = serieselement[0].Split('=')[1].Trim('\'');
sd.imdbid = serieselement[7].Split('=')[1].Trim('\'');
series.Add(sd);
}
catch (IndexOutOfRangeException e)
{
throw (e);
}
}
}
}
return true;
}
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>();
/* If series from sites are indexed than we dont need to reindex them. */
if (series == null || series.IsEmpty())
{
await GetSeriesInfo();
}
Int32 unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
WebClientStringResult results;
string searchString = "";
var limit = query.Limit;
if (limit == 0)
limit = 100;
/* SearchString format is the following: Seriesname 1X09 */
if (query.SearchTerm != null && !query.SearchTerm.Equals(""))
{
searchString += query.SanitizedSearchTerm;
// convert SnnEnn to nnxnn for dashboard searches
if (query.Season == 0 && (query.Episode == null || query.Episode.Equals("")))
{
Match searchMatch = _searchStringRegex.Match(searchString);
if (searchMatch.Success)
{
query.Season = int.Parse(searchMatch.Groups[2].Value);
query.Episode = searchMatch.Groups[4].Success ? string.Format("{0:00}", (int?)int.Parse(searchMatch.Groups[4].Value)) : null;
searchString = searchMatch.Groups[1].Value; // strip SnnEnn
}
}
if (query.Season != 0)
searchString += " " + query.Season.ToString();
if (query.Episode != null && !query.Episode.Equals(""))
searchString += string.Format("x{0:00}", int.Parse(query.Episode));
} else
{
// if searchquery is empty this is a test, so shorten the response time
limit = 20;
}
/* Search string must be converted to Base64 */
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(searchString);
var base64coded = System.Convert.ToBase64String(plainTextBytes);
/*Start search*/
int page = 1;
string exactSearchURL = SearchUrl + "?gyors=" + base64coded +"&p="+ page +"&now=" + unixTimestamp.ToString();
results = await RequestStringWithCookiesAndRetry(exactSearchURL);
/* Parse page Information from result */
string content = results.Content;
var splits = content.Split('\\');
int maxfounded = int.Parse(splits[0]);
int perpage = int.Parse(splits[1]);
//int incurrentpage = int.Parse(splits[2]);
double pages = Math.Ceiling((double)maxfounded / (double)perpage);
/* First page content is already ready */
releases.AddRange(await ParseTorrents(results, query, releases.Count, limit));
for (page =2;(page<=pages && releases.Count<limit);page++)
{
exactSearchURL = SearchUrl + "?gyors=" + base64coded + "&p=" + page + "&now=" + unixTimestamp.ToString();
results = await RequestStringWithCookiesAndRetry(exactSearchURL);
releases.AddRange(await ParseTorrents(results, query, releases.Count, limit));
}
return releases;
}
}
public class SeriesDetail
{
public string id;
public string HunName;
public string EngName;
public string imdbid;
}
}

View File

@@ -37,19 +37,19 @@ namespace Jackett.Common.Indexers {
Language = "en-us";
Type = "public";
// Dummy mappings for sonarr, radarr, etc
AddCategoryMapping (1, TorznabCatType.TV);
AddCategoryMapping (2, TorznabCatType.Movies);
AddCategoryMapping (3, TorznabCatType.Console);
AddCategoryMapping (4, TorznabCatType.Audio);
AddCategoryMapping (5, TorznabCatType.PC);
AddCategoryMapping (6, TorznabCatType.XXX);
AddCategoryMapping (7, TorznabCatType.Other);
AddCategoryMapping (8, TorznabCatType.Books);
// dummy mappings for sonarr, radarr, etc since torrents.csv doesnt return categories
AddCategoryMapping (1000, TorznabCatType.Console);
AddCategoryMapping (2000, TorznabCatType.Movies);
AddCategoryMapping (3000, TorznabCatType.Audio);
AddCategoryMapping (4000, TorznabCatType.PC);
AddCategoryMapping (5000, TorznabCatType.TV);
AddCategoryMapping (6000, TorznabCatType.XXX);
AddCategoryMapping (7000, TorznabCatType.Other);
AddCategoryMapping (8000, TorznabCatType.Books);
TorznabCaps.SupportsImdbSearch = false;
webclient.requestDelay = 1;
webclient.requestDelay = 0;
}
public override async Task<IndexerConfigurationStatus> ApplyConfiguration (JToken configJson) {
@@ -94,31 +94,50 @@ namespace Jackett.Common.Indexers {
// construct magnet link from infohash with all public trackers known to man
string magnet_uri = "magnet:?xt=urn:btih:" + torrent.Value<JToken> ("infohash") +
"&tr=udp://tracker.opentrackr.org:1337/announce" +
"&tr=udp://tracker.leechers-paradise.org:6969" +
"&tr=udp://tracker.coppersurfer.tk:6969/announce" +
"&tr=udp://tracker1.itzmx.com:8080/announce" +
"&tr=udp://explodie.org:6969/announce" +
"&tr=udp://tracker.leechers-paradise.org:6969/announce" +
"&tr=udp://tracker.internetwarriors.net:1337/announce" +
"&tr=udp://tracker.opentrackr.org:1337/announce" +
"&tr=udp://9.rarbg.to:2710/announce" +
"&tr=udp://exodus.desync.com:6969/announce" +
"&tr=udp://tracker.openbittorrent.com:80" +
"&tr=udp://torrent.gresille.org:80/announce" +
"&tr=udp://glotorrents.pw:6969/announce" +
"&tr=http://tracker3.itzmx.com:6961/announce" +
"&tr=udp://tracker.internetwarriors.net:1337/announce" +
"&tr=udp://open.demonii.com:1337/announce" +
"&tr=udp://p4p.arenabg.com:1337";
"&tr=udp://explodie.org:6969/announce" +
"&tr=udp://tracker2.itzmx.com:6961/announce" +
"&tr=udp://tracker1.itzmx.com:8080/announce" +
"&tr=udp://tracker.torrent.eu.org:451/announce" +
"&tr=udp://tracker.tiny-vps.com:6969/announce" +
"&tr=udp://tracker.port443.xyz:6969/announce" +
"&tr=udp://thetracker.org:80/announce" +
"&tr=udp://open.stealth.si:80/announce" +
"&tr=udp://open.demonii.si:1337/announce" +
"&tr=udp://ipv4.tracker.harry.lu:80/announce" +
"&tr=udp://denis.stalker.upeer.me:6969/announce" +
"&tr=udp://tracker1.wasabii.com.tw:6969/announce" +
"&tr=udp://tracker.dler.org:6969/announce" +
"&tr=udp://tracker.cyberia.is:6969/announce" +
"&tr=udp://tracker4.itzmx.com:2710/announce" +
"&tr=udp://tracker.uw0.xyz:6969/announce" +
"&tr=udp://tracker.moeking.me:6969/announce" +
"&tr=udp://retracker.lanta-net.ru:2710/announce" +
"&tr=udp://tracker.nyaa.uk:6969/announce" +
"&tr=udp://tracker.novg.net:6969/announce" +
"&tr=udp://tracker.iamhansen.xyz:2000/announce" +
"&tr=udp://tracker.filepit.to:6969/announce" +
"&tr=udp://tracker.dyn.im:6969/announce" +
"&tr=udp://torrentclub.tech:6969/announce" +
"&tr=udp://tracker.tvunderground.org.ru:3218/announce" +
"&tr=udp://tracker.open-tracker.org:1337/announce" +
"&tr=udp://tracker.justseed.it:1337/announce";
release.MagnetUri = new Uri (magnet_uri);
release.Comments = release.MagnetUri;
release.Guid = release.MagnetUri;
release.InfoHash = torrent.Value<JToken> ("infohash").ToString ();
// convert unix timestamp to human readable date
double createdunix = torrent.Value<int> ("created_unix");
System.DateTime dateTime = new System.DateTime (1970, 1, 1, 0, 0, 0, 0);
dateTime = dateTime.AddSeconds (createdunix);
release.PublishDate = dateTime;
release.Category = new List<int> { TorznabCatType.Other.ID };
release.Seeders = torrent.Value<int> ("seeders");
release.Peers = torrent.Value<int> ("leechers") + release.Seeders;
release.Size = torrent.Value<long> ("size_bytes");
@@ -128,13 +147,43 @@ namespace Jackett.Common.Indexers {
release.DownloadVolumeFactor = 0;
release.UploadVolumeFactor = 1;
// dummy mappings for sonarr, radarr, etc
string categories = string.Join (";", MapTorznabCapsToTrackers (query));
if (!string.IsNullOrEmpty (categories)) {
if (categories.Contains ("1000")) {
release.Category = new List<int> { TorznabCatType.Console.ID };
}
if (categories.Contains ("2000")) {
release.Category = new List<int> { TorznabCatType.Movies.ID };
}
if (categories.Contains ("3000")) {
release.Category = new List<int> { TorznabCatType.Audio.ID };
}
if (categories.Contains ("4000")) {
release.Category = new List<int> { TorznabCatType.PC.ID };
}
if (categories.Contains ("5000")) {
release.Category = new List<int> { TorznabCatType.TV.ID };
}
if (categories.Contains ("6000")) {
release.Category = new List<int> { TorznabCatType.XXX.ID };
}
if (categories.Contains ("7000")) {
release.Category = new List<int> { TorznabCatType.Other.ID };
}
if (categories.Contains ("8000")) {
release.Category = new List<int> { TorznabCatType.Books.ID };
}
}
// for null category
if (string.IsNullOrEmpty (categories)) {
release.Category = new List<int> { TorznabCatType.Other.ID };
}
releases.Add (release);
}
} catch (Exception ex) {
OnParseError (response.Content, ex);
}
return releases;
}
}

View File

@@ -53,43 +53,49 @@ namespace Jackett.Common.Indexers
configData.DisplayText.Value = "Expect an initial delay (often around 10 seconds) due to XSpeeds CloudFlare DDoS protection";
configData.DisplayText.Name = "Notice";
AddCategoryMapping(70, TorznabCatType.TVAnime); // Anime
AddCategoryMapping(4, TorznabCatType.PC); // Apps
AddCategoryMapping(82, TorznabCatType.PCMac); // Mac
AddCategoryMapping(80, TorznabCatType.AudioAudiobook); // Audiobooks
AddCategoryMapping(66, TorznabCatType.MoviesBluRay); // Blu-Ray
AddCategoryMapping(48, TorznabCatType.Books); // Books Magazines
AddCategoryMapping(68, TorznabCatType.MoviesOther); // Cams/TS
AddCategoryMapping(65, TorznabCatType.TVDocumentary); // Documentaries
AddCategoryMapping(10, TorznabCatType.MoviesDVD); // DVDR
AddCategoryMapping(72, TorznabCatType.MoviesForeign); // Foreign
AddCategoryMapping(74, TorznabCatType.TVOTHER); // Kids
AddCategoryMapping(44, TorznabCatType.TVSport); // MMA
AddCategoryMapping(11, TorznabCatType.Movies); // Movie Boxsets
AddCategoryMapping(12, TorznabCatType.Movies); // Movies
AddCategoryMapping(13, TorznabCatType.Audio); // Music
AddCategoryMapping(15, TorznabCatType.AudioVideo); // Music Videos
AddCategoryMapping(32, TorznabCatType.ConsoleNDS); // NDS Games
AddCategoryMapping(9, TorznabCatType.Other); // Other
AddCategoryMapping(6, TorznabCatType.PCGames); // PC Games
AddCategoryMapping(45, TorznabCatType.Other); // Pictures
AddCategoryMapping(31, TorznabCatType.ConsolePS4); // Playstation
AddCategoryMapping(71, TorznabCatType.TV); // PPV
AddCategoryMapping(54, TorznabCatType.TV); // Soaps
AddCategoryMapping(20, TorznabCatType.TVSport); // Sports
AddCategoryMapping(86, TorznabCatType.TVSport); // MotorSports
AddCategoryMapping(89, TorznabCatType.TVSport); // Olympics 2016
AddCategoryMapping(88, TorznabCatType.TVSport); // World Cup
AddCategoryMapping(83, TorznabCatType.Movies); // TOTM
AddCategoryMapping(21, TorznabCatType.TVSD); // TV Boxsets
AddCategoryMapping(76, TorznabCatType.TVHD); // HD Boxsets
AddCategoryMapping(47, TorznabCatType.TVHD); // TV-HD
AddCategoryMapping(16, TorznabCatType.TVSD); // TV-SD
AddCategoryMapping(7, TorznabCatType.ConsoleWii); // Wii Games
AddCategoryMapping(43, TorznabCatType.TVSport); // Wrestling
AddCategoryMapping(8, TorznabCatType.ConsoleXbox); // Xbox Games
AddCategoryMapping(92, TorznabCatType.MoviesUHD, "4K Movies");
AddCategoryMapping(91, TorznabCatType.TVUHD, "4K TV");
AddCategoryMapping(94, TorznabCatType.TVUHD, "4K TV Boxsets");
AddCategoryMapping(70, TorznabCatType.TVAnime, "Anime");
AddCategoryMapping(4, TorznabCatType.PC, "Apps");
AddCategoryMapping(82, TorznabCatType.PCMac, "Mac");
AddCategoryMapping(80, TorznabCatType.AudioAudiobook, "Audiobooks");
AddCategoryMapping(66, TorznabCatType.MoviesBluRay, "Blu-Ray");
AddCategoryMapping(48, TorznabCatType.Books, "Books Magazines");
AddCategoryMapping(68, TorznabCatType.MoviesOther, "Cams/TS");
AddCategoryMapping(65, TorznabCatType.TVDocumentary, "Documentaries");
AddCategoryMapping(10, TorznabCatType.MoviesDVD, "DVDR");
AddCategoryMapping(72, TorznabCatType.MoviesForeign, "Foreign");
AddCategoryMapping(74, TorznabCatType.TVOTHER, "Kids");
AddCategoryMapping(44, TorznabCatType.TVSport, "MMA");
AddCategoryMapping(11, TorznabCatType.Movies, "Movie Boxsets");
AddCategoryMapping(12, TorznabCatType.Movies, "Movies");
AddCategoryMapping(13, TorznabCatType.Audio, "Music");
AddCategoryMapping(15, TorznabCatType.AudioVideo, "Music Videos");
AddCategoryMapping(32, TorznabCatType.ConsoleNDS, "NDS Games");
AddCategoryMapping(9, TorznabCatType.Other, "Other");
AddCategoryMapping(6, TorznabCatType.PCGames, "PC Games");
AddCategoryMapping(45, TorznabCatType.Other, "Pictures");
AddCategoryMapping(31, TorznabCatType.ConsolePS4, "Playstation");
AddCategoryMapping(71, TorznabCatType.TV, "PPV");
AddCategoryMapping(54, TorznabCatType.TV, "Soaps");
AddCategoryMapping(20, TorznabCatType.TVSport, "Sports");
AddCategoryMapping(86, TorznabCatType.TVSport, "MotorSports");
AddCategoryMapping(89, TorznabCatType.TVSport, "Olympics 2016");
AddCategoryMapping(88, TorznabCatType.TVSport, "World Cup");
AddCategoryMapping(83, TorznabCatType.Movies, "TOTM");
AddCategoryMapping(21, TorznabCatType.TVSD, "TV Boxsets");
AddCategoryMapping(76, TorznabCatType.TVHD, "HD Boxsets");
AddCategoryMapping(47, TorznabCatType.TVHD, "TV-HD");
AddCategoryMapping(16, TorznabCatType.TVSD, "TV-SD");
AddCategoryMapping(7, TorznabCatType.ConsoleWii, "Wii Games");
AddCategoryMapping(43, TorznabCatType.TVSport, "Wrestling");
AddCategoryMapping(8, TorznabCatType.ConsoleXbox, "Xbox Games");
// RSS Textual categories
AddCategoryMapping("4K Movies", TorznabCatType.MoviesUHD);
AddCategoryMapping("4K TV", TorznabCatType.TVUHD);
AddCategoryMapping("4K TV Boxsets", TorznabCatType.TVUHD);
AddCategoryMapping("Anime", TorznabCatType.TVAnime);
AddCategoryMapping("Apps", TorznabCatType.PC);
AddCategoryMapping("Mac", TorznabCatType.PCMac);

View File

@@ -0,0 +1,200 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.Text;
using System.Threading.Tasks;
using Jackett.Common.Models;
using Jackett.Common.Models.IndexerConfig;
using Jackett.Common.Services.Interfaces;
using Jackett.Common.Utils;
using Jackett.Common.Utils.Clients;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;
namespace Jackett.Common.Indexers
{
public class Digitalcore : BaseWebIndexer
{
private string SearchUrl { get { return SiteLink + "api/v1/torrents"; } }
private string LoginUrl { get { return SiteLink + "api/v1/auth"; } }
private new ConfigurationDataBasicLogin configData
{
get { return (ConfigurationDataBasicLogin)base.configData; }
set { base.configData = value; }
}
public Digitalcore(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps)
: base(name: "DigitalCore",
description: "DigitalCore is a Private Torrent Tracker for MOVIES / TV / GENERAL",
link: "https://digitalcore.club/",
caps: new TorznabCapabilities(),
configService: configService,
client: w,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
{
Encoding = Encoding.UTF8;
Language = "en-us";
Type = "private";
TorznabCaps.SupportsImdbSearch = true;
AddCategoryMapping(1, TorznabCatType.MoviesDVD, "Movies/DVDR");
AddCategoryMapping(2, TorznabCatType.MoviesSD, "Movies/XviD");
AddCategoryMapping(3, TorznabCatType.MoviesBluRay, "Movies/BluRay");
AddCategoryMapping(4, TorznabCatType.MoviesUHD, "Movies/4K");
AddCategoryMapping(5, TorznabCatType.MoviesHD, "Movies/720p");
AddCategoryMapping(6, TorznabCatType.MoviesHD, "Movies/1080p");
AddCategoryMapping(8, TorznabCatType.TVHD, "Tv/720p");
AddCategoryMapping(9, TorznabCatType.TVHD, "Tv/1080p");
AddCategoryMapping(10, TorznabCatType.TVSD, "Tv/XVID");
AddCategoryMapping(11, TorznabCatType.TVSD, "Tv/DVDR");
AddCategoryMapping(12, TorznabCatType.TVHD, "Tv/PACKS");
AddCategoryMapping(13, TorznabCatType.TVUHD, "Tv/4K");
AddCategoryMapping(14, TorznabCatType.TVHD, "Tv/BluRay");
AddCategoryMapping(17, TorznabCatType.Other, "Unknown");
AddCategoryMapping(18, TorznabCatType.PC0day, "Apps/0day");
AddCategoryMapping(19, TorznabCatType.PCGames, "Games/PC");
AddCategoryMapping(20, TorznabCatType.PCISO, "Apps/PC");
AddCategoryMapping(22, TorznabCatType.AudioMP3, "Music/MP3");
AddCategoryMapping(23, TorznabCatType.AudioLossless, "Music/FLAC");
AddCategoryMapping(24, TorznabCatType.Audio, "Music/MTV");
AddCategoryMapping(30, TorznabCatType.XXX, "XXX/SD");
AddCategoryMapping(31, TorznabCatType.XXX, "XXX/HD");
AddCategoryMapping(32, TorznabCatType.XXX, "XXX/4K");
}
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
LoadValuesFromJson(configJson);
var queryCollection = new NameValueCollection();
queryCollection.Add("username", configData.Username.Value);
queryCollection.Add("password", configData.Password.Value);
var loginUrl = LoginUrl + "?" + queryCollection.GetQueryString();
var loginResult = await RequestStringWithCookies(loginUrl, null, SiteLink);
await ConfigureIfOK(loginResult.Cookies, loginResult.Content.Contains("\"user\""), () =>
{
throw new ExceptionWithConfigData(loginResult.Content, configData);
});
return IndexerConfigurationStatus.RequiresTesting;
}
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
List<ReleaseInfo> releases = new List<ReleaseInfo>();
var queryCollection = new NameValueCollection();
var searchString = query.GetQueryString();
var searchUrl = SearchUrl;
queryCollection.Add("extendedSearch", "false");
queryCollection.Add("freeleech", "false");
queryCollection.Add("index", "0");
queryCollection.Add("limit", "100");
queryCollection.Add("order", "desc");
queryCollection.Add("page", "search");
if (query.ImdbID != null)
queryCollection.Add("searchText", query.ImdbID);
else
queryCollection.Add("searchText", searchString);
queryCollection.Add("sort", "d");
queryCollection.Add("section", "all");
queryCollection.Add("stereoscopic", "false");
queryCollection.Add("watchview", "false");
searchUrl += "?" + queryCollection.GetQueryString();
foreach (var cat in MapTorznabCapsToTrackers(query))
searchUrl += "&categories[]=" + cat;
var results = await RequestStringWithCookies(searchUrl, null, SiteLink);
try
{
//var json = JArray.Parse(results.Content);
dynamic json = JsonConvert.DeserializeObject<dynamic>(results.Content);
foreach (var row in json ?? System.Linq.Enumerable.Empty<dynamic>())
{
var release = new ReleaseInfo();
var descriptions = new List<string>();
var tags = new List<string>();
release.MinimumRatio = 1.1;
release.MinimumSeedTime = 48 * 60 * 60;
release.Title = row.name;
release.Category = MapTrackerCatToNewznab(row.category.ToString());
release.Size = row.size;
release.Seeders = row.seeders;
release.Peers = row.leechers + release.Seeders;
release.PublishDate = DateTime.ParseExact(row.added.ToString() + " +01:00", "yyyy-MM-dd HH:mm:ss zzz", CultureInfo.InvariantCulture);
release.Files = row.numfiles;
release.Grabs = row.times_completed;
release.Comments = new Uri(SiteLink + "torrent/" + row.id.ToString() + "/");
release.Guid = release.Comments;
release.Link = new Uri(SiteLink + "api/v1/torrents/download/" + row.id.ToString());
if (row.frileech == 1)
release.DownloadVolumeFactor = 0;
else
release.DownloadVolumeFactor = 1;
release.UploadVolumeFactor = 1;
// if (!string.IsNullOrWhiteSpace(row.customcover.ToString()))
// {
// release.BannerUrl = new Uri(SiteLink + row.customcover);
//}
if (row.imdbid2 != null && row.imdbid2.ToString().StartsWith("tt"))
{
release.Imdb = ParseUtil.CoerceLong(row.imdbid2.ToString().Substring(2));
descriptions.Add("Title: " + row.title);
descriptions.Add("Year: " + row.year);
descriptions.Add("Genres: " + row.genres);
descriptions.Add("Tagline: " + row.tagline);
descriptions.Add("Cast: " + row.cast);
descriptions.Add("Rating: " + row.rating);
//descriptions.Add("Plot: " + row.plot);
release.BannerUrl = new Uri(SiteLink + "img/imdb/" + row.imdbid2 + ".jpg");
}
if ((int)row.p2p == 1)
tags.Add("P2P");
if ((int)row.pack == 1)
tags.Add("Pack");
if ((int)row.reqid != 0)
tags.Add("Request");
if (tags.Count > 0)
descriptions.Add("Tags: " + string.Join(", ", tags));
// var preDate = row.preDate.ToString();
// if (!string.IsNullOrWhiteSpace(preDate) && preDate != "1970-01-01 01:00:00")
// descriptions.Add("PRE: " + preDate);
descriptions.Add("Section: " + row.section);
release.Description = string.Join("<br>\n", descriptions);
releases.Add(release);
}
}
catch (Exception ex)
{
OnParseError(results.Content, ex);
}
return releases;
}
}
}

View File

@@ -7,14 +7,15 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AngleSharp" Version="0.10.1" />
<PackageReference Include="Autofac" Version="4.8.1" />
<PackageReference Include="AngleSharp" Version="0.11.0" />
<PackageReference Include="Autofac" Version="4.9.1" />
<PackageReference Include="AutoMapper" Version="8.0.0" />
<PackageReference Include="BencodeNET" Version="2.2.24" />
<PackageReference Include="BencodeNET" Version="2.3.0" />
<PackageReference Include="CloudFlareUtilities" Version="1.2.0" />
<PackageReference Include="CommandLineParser" Version="2.4.3" />
<PackageReference Include="CsQuery.NETStandard" Version="1.3.6.1" />
<PackageReference Include="DotNet4.SocksProxy" Version="1.4.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="2.2.0" />
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
<PackageReference Include="MimeMapping" Version="1.0.1.12" />
@@ -23,7 +24,7 @@
<PackageReference Include="SharpZipLib" Version="1.1.0" />
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="4.5.0" />
<PackageReference Include="System.ServiceProcess.ServiceController" Version="4.5.0" />
<PackageReference Include="YamlDotNet" Version="5.3.0" />
<PackageReference Include="YamlDotNet" Version="5.4.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -0,0 +1,46 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Jackett.Common.Models.IndexerConfig.Bespoke
{
public class ConfigurationDataTVstore : ConfigurationData
{
public StringItem Username { get; private set; }
public StringItem Password { get; private set; }
public ConfigurationDataTVstore()
{
Username = new StringItem { Name = "Username", Value = "" };
Password = new StringItem { Name = "Password", Value = "" };
}
public ConfigurationDataTVstore(JToken json)
{
ConfigurationDataTVstore configData = new ConfigurationDataTVstore();
dynamic configArray = JsonConvert.DeserializeObject(json.ToString());
foreach (var config in configArray)
{
string propertyName = UppercaseFirst((string)config.id);
switch (propertyName)
{
case "Username":
Username = new StringItem { Name = propertyName, Value = config.value };
break;
case "Password":
Password = new StringItem { Name = propertyName, Value = config.value };
break;
default:
break;
}
}
}
static string UppercaseFirst(string s)
{
if (string.IsNullOrEmpty(s))
return string.Empty;
return char.ToUpper(s[0]) + s.Substring(1);
}
}
}

View File

@@ -0,0 +1,18 @@
namespace Jackett.Common.Models.IndexerConfig
{
public class ConfigurationDataBasicLoginWithEmail : ConfigurationData
{
public StringItem Email { get; private set; }
public StringItem Password { get; private set; }
public DisplayItem Instructions { get; private set; }
public ConfigurationDataBasicLoginWithEmail(string instructionMessageOptional = null)
{
Email = new StringItem { Name = "Email" };
Password = new StringItem { Name = "Password" };
Instructions = new DisplayItem(instructionMessageOptional) { Name = "" };
}
}
}

View File

@@ -62,6 +62,8 @@ namespace Jackett.Common.Models
var parameters = new List<string>() { "q", "season", "ep" };
if (SupportsTVRageSearch)
parameters.Add("rid");
if (SupportsImdbSearch)
parameters.Add("imdbid");
return string.Join(",", parameters);
}
}

View File

@@ -0,0 +1,7 @@
namespace Jackett.Common.Services.Interfaces
{
public interface IFilePermissionService
{
void MakeFileExecutable(string path);
}
}

View File

@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using Microsoft.AspNetCore.Http;
namespace Jackett.Common.Services.Interfaces
{
@@ -12,7 +12,7 @@ namespace Jackett.Common.Services.Interfaces
void ReserveUrls(bool doInstall = true);
Uri ConvertToProxyLink(Uri link, string serverUrl, string indexerId, string action = "dl", string file = "t");
string BasePath();
string GetServerUrl(object Request); //TODO: Once Mono is removed, change type to HttpRequest
string GetServerUrl(HttpRequest Request);
List<string> notices { get; }
string GetBlackholeDirectory();
string GetApiKey();

View File

@@ -30,17 +30,23 @@ namespace Jackett.Common.Services
IConfigurationService configService;
ManualResetEvent locker = new ManualResetEvent(false);
ITrayLockService lockService;
IProcessService processService;
IServiceConfigService windowsService;
IFilePermissionService filePermissionService;
private ServerConfig serverConfig;
bool forceupdatecheck = false;
Variants.JackettVariant variant = Variants.JackettVariant.NotFound;
public UpdateService(Logger l, WebClient c, IConfigurationService cfg, ITrayLockService ls, ServerConfig sc)
public UpdateService(Logger l, WebClient c, IConfigurationService cfg, ITrayLockService ls, IProcessService ps, IServiceConfigService ws, IFilePermissionService fps, ServerConfig sc)
{
logger = l;
client = c;
configService = cfg;
lockService = ls;
processService = ps;
windowsService = ws;
serverConfig = sc;
filePermissionService = fps;
}
private string ExePath()
@@ -94,12 +100,6 @@ namespace Jackett.Common.Services
variant = variants.GetVariant();
logger.Info("Jackett variant: " + variant.ToString());
if (DotNetCoreUtil.IsRunningOnDotNetCore)
{
logger.Info($"Skipping update check as running Jackett on .NET Core is still in preview. Updates must be performed manually at this time.");
return;
}
forceupdatecheck = true;
var isWindows = System.Environment.OSVersion.Platform != PlatformID.Unix;
@@ -117,7 +117,6 @@ namespace Jackett.Common.Services
try
{
var response = await client.GetString(new WebRequest()
{
Url = "https://api.github.com/repos/Jackett/Jackett/releases",
@@ -147,12 +146,14 @@ namespace Jackett.Common.Services
logger.Info($"New release found. Current: {currentVersion} New: {latestRelease.Name}");
try
{
var tempDir = await DownloadRelease(latestRelease.Assets, isWindows, latestRelease.Name);
var tempDir = await DownloadRelease(latestRelease.Assets, isWindows, latestRelease.Name);
// Copy updater
var installDir = Path.GetDirectoryName(ExePath());
var updaterPath = Path.Combine(tempDir, "Jackett", "JackettUpdater.exe");
var updaterPath = GetUpdaterPath(tempDir);
if (updaterPath != null)
{
StartUpdate(updaterPath, installDir, isWindows, serverConfig.RuntimeSettings.NoRestart, trayIsRunning);
}
}
catch (Exception e)
{
@@ -178,6 +179,19 @@ namespace Jackett.Common.Services
}
}
private string GetUpdaterPath(string tempDirectory)
{
if (variant == Variants.JackettVariant.CoreMacOs || variant == Variants.JackettVariant.CoreLinuxAmdx64 ||
variant == Variants.JackettVariant.CoreLinuxArm32 || variant == Variants.JackettVariant.CoreLinuxArm64)
{
return Path.Combine(tempDirectory, "Jackett", "JackettUpdater");
}
else
{
return Path.Combine(tempDirectory, "Jackett", "JackettUpdater.exe");
}
}
private string GetCurrentVersion()
{
var assembly = Assembly.GetExecutingAssembly();
@@ -204,8 +218,8 @@ namespace Jackett.Common.Services
logger.Error("Temp dir doesn't exist: " + tempDir.ToString());
return;
}
try {
try {
DirectoryInfo d = new DirectoryInfo(tempDir);
foreach (var dir in d.GetDirectories("JackettUpdate-*"))
{
@@ -276,6 +290,21 @@ namespace Jackett.Common.Services
tarArchive.Close();
gzipStream.Close();
inStream.Close();
if (variant == Variants.JackettVariant.CoreMacOs || variant == Variants.JackettVariant.CoreLinuxAmdx64
|| variant == Variants.JackettVariant.CoreLinuxArm32 || variant == Variants.JackettVariant.CoreLinuxArm64)
{
//Calling the file permission service to limit usage to netcoreapp. The Mono.Posix.NETStandard library causes issues outside of .NET Core
//https://github.com/xamarin/XamarinComponents/issues/282
// When the files get extracted, the execute permission for jackett and JackettUpdater don't get carried across
string jackettPath = tempDir + "/Jackett/jackett";
filePermissionService.MakeFileExecutable(jackettPath);
string jackettUpdaterPath = tempDir + "/Jackett/JackettUpdater";
filePermissionService.MakeFileExecutable(jackettUpdaterPath);
}
}
return tempDir;
@@ -284,9 +313,6 @@ namespace Jackett.Common.Services
private void StartUpdate(string updaterExePath, string installLocation, bool isWindows, bool NoRestart, bool trayIsRunning)
{
string appType = "Console";
//DI once off Owin
IProcessService processService = new ProcessService(logger);
IServiceConfigService windowsService = new WindowsServiceConfigService(processService, logger);
if (isWindows && windowsService.ServiceExists() && windowsService.ServiceRunning())
{
@@ -294,19 +320,14 @@ namespace Jackett.Common.Services
}
var exe = Path.GetFileName(ExePath());
var args = string.Join(" ", Environment.GetCommandLineArgs().Skip(1).Select(a => a.Contains(" ") ? "\"" +a + "\"" : a )).Replace("\"", "\\\"");
var args = string.Join(" ", Environment.GetCommandLineArgs().Skip(1).Select(a => a.Contains(" ") ? "\"" + a + "\"" : a )).Replace("\"", "\\\"");
var startInfo = new ProcessStartInfo();
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
// Note: add a leading space to the --Args argument to avoid parsing as arguments
if (isWindows)
{
startInfo.Arguments = $"--Path \"{installLocation}\" --Type \"{appType}\" --Args \" {args}\"";
startInfo.FileName = Path.Combine(updaterExePath);
}
else
if (variant == Variants.JackettVariant.Mono)
{
// Wrap mono
args = exe + " " + args;
@@ -315,6 +336,11 @@ namespace Jackett.Common.Services
startInfo.Arguments = $"{Path.Combine(updaterExePath)} --Path \"{installLocation}\" --Type \"{appType}\" --Args \" {args}\"";
startInfo.FileName = "mono";
}
else
{
startInfo.Arguments = $"--Path \"{installLocation}\" --Type \"{appType}\" --Args \" {args}\"";
startInfo.FileName = Path.Combine(updaterExePath);
}
try
{

View File

@@ -116,6 +116,12 @@ namespace Jackett.Common.Utils.Clients
if (hosts.Contains(request.Host))
return true;
}
if (sslPolicyErrors != SslPolicyErrors.None)
{
throw new Exception("certificate validation failed: " + certificate.ToString());
}
return sslPolicyErrors == SslPolicyErrors.None;
};
}

View File

@@ -150,6 +150,12 @@ namespace Jackett.Common.Utils.Clients
if (hosts.Contains(request.Host))
return true;
}
if (sslPolicyErrors != SslPolicyErrors.None)
{
throw new Exception("certificate validation failed: " + certificate.ToString());
}
return sslPolicyErrors == SslPolicyErrors.None;
};
}

View File

@@ -149,6 +149,12 @@ namespace Jackett.Common.Utils.Clients
if (hosts.Contains(request.RequestUri.Host))
return true;
}
if (sslPolicyErrors != SslPolicyErrors.None)
{
throw new Exception("certificate validation failed: " + certificate.ToString());
}
return sslPolicyErrors == SslPolicyErrors.None;
};

View File

@@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace Jackett.Common.Utils
{
@@ -14,7 +12,7 @@ namespace Jackett.Common.Utils
Mono,
CoreWindows,
CoreMacOs,
CoreLinuxAmd64,
CoreLinuxAmdx64,
CoreLinuxArm32,
CoreLinuxArm64
}
@@ -37,7 +35,7 @@ namespace Jackett.Common.Utils
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.X64)
{
return JackettVariant.CoreLinuxAmd64;
return JackettVariant.CoreLinuxAmdx64;
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.Arm)
@@ -67,7 +65,6 @@ namespace Jackett.Common.Utils
return JackettVariant.NotFound;
}
public string GetArtifactFileName(JackettVariant variant)
{
switch (variant)
@@ -88,9 +85,9 @@ namespace Jackett.Common.Utils
{
return "Jackett.Binaries.macOS.tar.gz";
}
case JackettVariant.CoreLinuxAmd64:
case JackettVariant.CoreLinuxAmdx64:
{
return "Jackett.Binaries.LinuxAMD64.tar.gz";
return "Jackett.Binaries.LinuxAMDx64.tar.gz";
}
case JackettVariant.CoreLinuxArm32:
{

View File

@@ -22,12 +22,13 @@
<!-- Conditionally obtain references for the .NET Core App 2.2 target -->
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.2' ">
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="4.5.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="4.8.1" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.3.1" />
<PackageReference Include="Autofac" Version="4.9.1" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.4.0" />
<PackageReference Include="AutoMapper" Version="8.0.0" />
<PackageReference Include="CommandLineParser" Version="2.4.3" />
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
@@ -39,7 +40,7 @@
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.2.0" />
<PackageReference Include="NLog" Version="4.5.11" />
<PackageReference Include="NLog.Web.AspNetCore" Version="4.7.1" />
<PackageReference Include="NLog.Web.AspNetCore" Version="4.8.0" />
<PackageReference Include="System.ServiceProcess.ServiceController" Version="4.5.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.1" />
</ItemGroup>

View File

@@ -0,0 +1,41 @@
using Jackett.Common.Services.Interfaces;
using NLog;
using System;
#if NETCOREAPP2_2
using Mono.Unix;
#endif
namespace Jackett.Server.Services
{
public class FilePermissionService : IFilePermissionService
{
private Logger logger;
public FilePermissionService(Logger l)
{
logger = l;
}
public void MakeFileExecutable(string path)
{
#if NETCOREAPP2_2
//Calling the file permission service to limit usage to netcoreapp. The Mono.Posix.NETStandard library causes issues outside of .NET Core
//https://github.com/xamarin/XamarinComponents/issues/282
logger.Debug($"Attempting to give execute permission to: {path}");
try
{
UnixFileInfo jackettUpdaterFI = new UnixFileInfo(path)
{
FileAccessPermissions = FileAccessPermissions.UserReadWriteExecute | FileAccessPermissions.GroupRead | FileAccessPermissions.OtherRead
};
}
catch (Exception ex)
{
logger.Error(ex);
}
#endif
}
}
}

View File

@@ -314,36 +314,33 @@ namespace Jackett.Server.Services
// Only needed for Owin
}
public string GetServerUrl(Object obj)
public string GetServerUrl(HttpRequest request)
{
string serverUrl = "";
if (obj is HttpRequest request)
var scheme = request.Scheme;
var port = request.HttpContext.Request.Host.Port;
// Check for protocol headers added by reverse proxys
// X-Forwarded-Proto: A de facto standard for identifying the originating protocol of an HTTP request
var X_Forwarded_Proto = request.Headers.Where(x => x.Key == "X-Forwarded-Proto").Select(x => x.Value).FirstOrDefault();
if (X_Forwarded_Proto.Count > 0)
{
var scheme = request.Scheme;
var port = request.HttpContext.Request.Host.Port;
// Check for protocol headers added by reverse proxys
// X-Forwarded-Proto: A de facto standard for identifying the originating protocol of an HTTP request
var X_Forwarded_Proto = request.Headers.Where(x => x.Key == "X-Forwarded-Proto").Select(x => x.Value).FirstOrDefault();
if (X_Forwarded_Proto.Count > 0)
{
scheme = X_Forwarded_Proto.First();
}
// Front-End-Https: Non-standard header field used by Microsoft applications and load-balancers
else if (request.Headers.Where(x => x.Key == "Front-End-Https" && x.Value.FirstOrDefault() == "on").Any())
{
scheme = "https";
}
//default to 443 if the Host header doesn't contain the port (needed for reverse proxy setups)
if (scheme == "https" && !request.HttpContext.Request.Host.Value.Contains(":"))
{
port = 443;
}
serverUrl = string.Format("{0}://{1}:{2}{3}/", scheme, request.HttpContext.Request.Host.Host, port, BasePath());
scheme = X_Forwarded_Proto.First();
}
// Front-End-Https: Non-standard header field used by Microsoft applications and load-balancers
else if (request.Headers.Where(x => x.Key == "Front-End-Https" && x.Value.FirstOrDefault() == "on").Any())
{
scheme = "https";
}
//default to 443 if the Host header doesn't contain the port (needed for reverse proxy setups)
if (scheme == "https" && !request.HttpContext.Request.Host.Value.Contains(":"))
{
port = 443;
}
serverUrl = string.Format("{0}://{1}:{2}{3}/", scheme, request.HttpContext.Request.Host.Host, port, BasePath());
return serverUrl;
}

View File

@@ -83,6 +83,7 @@ namespace Jackett.Server
builder.RegisterType<ServerService>().As<IServerService>().SingleInstance();
builder.RegisterType<ProtectionService>().As<IProtectionService>().SingleInstance();
builder.RegisterType<ServiceConfigService>().As<IServiceConfigService>().SingleInstance();
builder.RegisterType<FilePermissionService>().As<IFilePermissionService>().SingleInstance();
IContainer container = builder.Build();
Helper.ApplicationContainer = container;

View File

@@ -21,15 +21,15 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="4.8.1" />
<PackageReference Include="FluentAssertions" Version="5.5.3" />
<PackageReference Include="Autofac" Version="4.9.1" />
<PackageReference Include="FluentAssertions" Version="5.6.0" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection" Version="2.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.0" />
<PackageReference Include="MSTest.TestAdapter" Version="1.4.0" />
<PackageReference Include="MSTest.TestFramework" Version="1.4.0" />
<PackageReference Include="NUnit" Version="3.11.0" />
<PackageReference Include="NUnit.ConsoleRunner" Version="3.9.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -19,6 +19,7 @@ namespace Jackett.Updater
private IProcessService processService;
private IServiceConfigService windowsService;
private Logger logger;
private Variants.JackettVariant variant = Variants.JackettVariant.NotFound;
public static void Main(string[] args)
{
@@ -38,6 +39,10 @@ namespace Jackett.Updater
logger.Info("Jackett Updater v" + GetCurrentVersion());
logger.Info("Options \"" + string.Join("\" \"", args) + "\"");
Variants variants = new Variants();
variant = variants.GetVariant();
logger.Info("Jackett variant: " + variant.ToString());
bool isWindows = Environment.OSVersion.Platform == PlatformID.Win32NT;
if (isWindows)
{
@@ -45,7 +50,7 @@ namespace Jackett.Updater
logger.Info("Pausing for 3 seconds to give Jackett & tray time to shutdown");
System.Threading.Thread.Sleep(3000);
}
processService = new ProcessService(logger);
windowsService = new WindowsServiceConfigService(processService, logger);
@@ -63,6 +68,7 @@ namespace Jackett.Updater
{
logger.Error(HelpText.AutoBuild(optionsResult));
logger.Error("Failed to process update arguments!");
logger.Error(errors.ToString());
Console.ReadKey();
});
}
@@ -94,9 +100,11 @@ namespace Jackett.Updater
{
try
{
var startInfo = new ProcessStartInfo();
startInfo.Arguments = "-15 " + pid;
startInfo.FileName = "kill";
var startInfo = new ProcessStartInfo
{
Arguments = "-15 " + pid,
FileName = "kill"
};
Process.Start(startInfo);
System.Threading.Thread.Sleep(1000); // just sleep, WaitForExit() doesn't seem to work on mono/linux (returns immediantly), https://bugzilla.xamarin.com/show_bug.cgi?id=51742
exited = proc.WaitForExit(2000);
@@ -148,7 +156,7 @@ namespace Jackett.Updater
var trayProcesses = Process.GetProcessesByName("JackettTray");
if (isWindows)
{
if (trayProcesses.Count() > 0)
if (trayProcesses.Length > 0)
{
foreach (var proc in trayProcesses)
{
@@ -172,9 +180,9 @@ namespace Jackett.Updater
{
var fileName = Path.GetFileName(file).ToLowerInvariant();
if (fileName.EndsWith(".zip") ||
fileName.EndsWith(".tar") ||
fileName.EndsWith(".gz"))
if (fileName.EndsWith(".zip")
|| fileName.EndsWith(".tar")
|| fileName.EndsWith(".gz"))
{
continue;
}
@@ -280,6 +288,8 @@ namespace Jackett.Updater
"Definitions/bt-scene.yml",
"Definitions/extratorrentclone.yml",
"Definitions/btdb.yml",
"Definitions/torrentcouch.yml",
"Definitions/idopeclone.yml",
};
foreach (var oldFile in oldFiles)
@@ -303,7 +313,7 @@ namespace Jackett.Updater
if (!isWindows)
KillPids(pids);
if (options.NoRestart == false)
if (!options.NoRestart)
{
if (isWindows && (trayRunning || options.StartTray) && !string.Equals(options.Type, "WindowsService", StringComparison.OrdinalIgnoreCase))
{
@@ -344,14 +354,13 @@ namespace Jackett.Updater
logger.Error("Failed to get admin rights to start the service.");
}
}
}
else
{
var startInfo = new ProcessStartInfo()
{
Arguments = options.Args,
FileName = Path.Combine(options.Path, "JackettConsole.exe"),
FileName = GetJackettConsolePath(options.Path),
UseShellExecute = true
};
@@ -363,12 +372,20 @@ namespace Jackett.Updater
startInfo.CreateNoWindow = false;
startInfo.WindowStyle = ProcessWindowStyle.Normal;
}
else
if (variant == Variants.JackettVariant.Mono)
{
startInfo.Arguments = startInfo.FileName + " " + startInfo.Arguments;
startInfo.FileName = "mono";
}
if (variant == Variants.JackettVariant.CoreMacOs || variant == Variants.JackettVariant.CoreLinuxAmdx64
|| variant == Variants.JackettVariant.CoreLinuxArm32 || variant == Variants.JackettVariant.CoreLinuxArm64)
{
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
}
logger.Info("Starting Jackett: " + startInfo.FileName + " " + startInfo.Arguments);
Process.Start(startInfo);
}
@@ -380,5 +397,18 @@ namespace Jackett.Updater
var location = new Uri(Assembly.GetEntryAssembly().GetName().CodeBase);
return new FileInfo(WebUtility.UrlDecode(location.AbsolutePath)).DirectoryName;
}
private string GetJackettConsolePath(string directoryPath)
{
if (variant == Variants.JackettVariant.CoreMacOs || variant == Variants.JackettVariant.CoreLinuxAmdx64
|| variant == Variants.JackettVariant.CoreLinuxArm32 || variant == Variants.JackettVariant.CoreLinuxArm64)
{
return Path.Combine(directoryPath, "jackett");
}
else
{
return Path.Combine(directoryPath, "JackettConsole.exe");
}
}
}
}