Compare commits

...

84 Commits

Author SHA1 Message Date
kaso17
3538fdfaf7 Synthesiz3r: removed (dead) 2018-06-15 11:58:29 +02:00
kaso17
3468e7d404 improve BEncode error handling 2018-06-15 11:12:03 +02:00
kaso17
ec4afda184 Audiobook Torrents: improve compatibility 2018-06-15 10:44:26 +02:00
kaso17
67b1835264 Bit-City Reloaded: fix login 2018-06-15 10:30:43 +02:00
kaso17
aee64aa589 Shareisland: update URL 2018-06-14 19:28:51 +02:00
kaso17
687e6e237f TorrentWTF: removed (dead) 2018-06-14 19:28:36 +02:00
kaso17
b48dd5e930 cpasbien: URL update 2018-06-14 18:38:07 +02:00
kaso17
5ee6833610 NCore: fix else 2018-06-14 17:53:46 +02:00
morpheus133
c998ba3762 Additional fix for #1450 (#3227)
* Additional fix for #1450
Sonarr is search for a tilte if the result title is different it reject it.
So it is not enough that Jackett give the result it must give with the same language.

Workaround create a new title from the original one and from the title.
It also make some fine tunning:
if title not contains the language we add it from category

* Make decision safer
2018-06-14 17:44:22 +02:00
kaso17
2d4f7ab0e9 Waffles: fix category parsing 2018-06-14 17:39:16 +02:00
kaso17
676d03eb88 mono: redirect workaround 2018-06-14 17:28:57 +02:00
garfield69
6f7ecbfb7b Yggtorrent: domain changed, fixes #3228 2018-06-13 13:01:32 +12:00
Raphael Barreiros
c4aa49eb32 Update BJ-Share to new domain name (#3225)
* Update BJ-Share to new domain name

BJ-Share changed its domain from bj-share.me to bj-share.info

* Added LegacySiteLinks method
2018-06-13 07:44:42 +12:00
garfield69
32aae44ffc Btbit: fix slash in wrong place #3902 2018-06-13 07:04:35 +12:00
garfield69
7883534c5e Btbit: apply sort for all results #3209 2018-06-13 06:49:10 +12:00
kaso17
b58c9fb718 HDHome: try to fix search 2018-06-11 18:31:27 +02:00
kaso17
99d8f63f9e HDChina: try to fix search 2018-06-11 18:31:10 +02:00
la55u
635e8240d2 RevTT: added files count (#3213) 2018-06-11 17:36:29 +02:00
R91g
117a670aa3 Update readme (add HD-Spain tracker) (#3223)
Add new private tracker HD-Spain
2018-06-11 17:33:49 +02:00
R91g
f49c58a1fa HD-Spain: add indexer (#3222)
Add Spanish Private HD tracker https://www.hd-spain.com/
Based on Albvadi's code from HD-Spain forum all credit to him, I only added some changes for better search, ISO correct and spain flag detection
2018-06-11 17:33:26 +02:00
kaso17
2492f1b797 NCore: add comment 2018-06-11 17:31:46 +02:00
kaso17
d6781f67b2 NCore: improve search fix 2018-06-11 17:28:24 +02:00
morpheus133
2e0c22eb6d NCore: fix for #1450 (#3220)
Some workoround to "Ncore - not forward all search results to Sonarr, Radarr"
In case of TV shows if nothing is founded, retry the search without SxxExx after the show name.
This will list all torrent also if their title or description are changed.
Than add the result only if it contains the skipped SxxExx
2018-06-11 17:15:21 +02:00
flightlevel
f7bf4060ea Don't publish experimental artifacts 2018-06-11 17:21:34 +10:00
flightlevel
8c953bbf01 Avoid Engine for AspNetCore 2018-06-11 17:17:56 +10:00
aurelien
4e91761fdf Elite Tracker: Add HTTPS tracker option (#3217)
* Add option for Elite Tracker (FR) for download torrent using https for tracker URL.

* change return type.
clean code.

* use the SiteLink variable instead of hard coding
2018-06-11 06:42:21 +02:00
kaso17
53f8465e67 Demonoid: change to public 2018-06-10 15:55:51 +02:00
flightlevel
e8bc2816ef Update migration logging 2018-06-10 12:51:34 +10:00
flightlevel
28ed7cc8a5 BJShare: Remove unused variable
Remove warning in build
2018-06-10 12:40:02 +10:00
flightlevel
089d9f2e3d Ignore launchSettings.json 2018-06-10 12:38:32 +10:00
garfield69
b4eda2ed54 Ettv: sort by created for rss, test and no-keyword search #3209 2018-06-09 08:01:24 +12:00
garfield69
4d8d21a815 Btbit: sort by created for rss, test, and no-keyword searches #3209 2018-06-09 07:39:08 +12:00
kaso17
f3290800d8 bloackhole: fix magnet links 2018-06-08 16:04:54 +02:00
kaso17
22a858c076 SceneTime: fix search 2018-06-07 18:33:44 +02:00
kaso17
823419c032 Shareisland: fix legacylinks 2018-06-07 18:19:57 +02:00
Jorman
908d3f64f4 Added Audiobook category (#3203) 2018-06-06 12:44:49 +12:00
flightlevel
4b599f391c Mono 5.8 is the minimum supported runtime
#3181 fix. Can get away without using RuntimeInformation and didn't
consider public trackers without a password
2018-06-05 21:47:20 +10:00
kaso17
6d8239caab Demonoid: improve download debugging 2018-06-05 13:34:54 +02:00
Jorman
dae37f273a ilcorsaroblu: Update url (#3202) 2018-06-05 13:21:37 +02:00
kaso17
1615bff2d0 handle RuntimeInformation exception 2018-06-05 13:14:32 +02:00
kaso17
b303befbb9 SceneTime: fix indexer 2018-06-05 13:09:07 +02:00
kaso17
e243c11cc0 update mono reference 2018-06-05 07:24:05 +02:00
Travis Boss
c860bca320 changed log button from btn-danger to btn-success, less scary (#3196) 2018-06-04 14:59:16 +12:00
flightlevel
a60c1fca36 .NET 4.6.1 or Mono 5.4 is now the minimum supported runtime 2018-06-03 21:27:47 +10:00
la55u
5ad2c7a371 RevTT: Minor fixes (#3193)
* fixed RevTT pc/iso category

* added grabs count to RevTT
2018-06-03 01:11:42 +02:00
Jorman
3df0218347 Changed link after site fix (#3188) 2018-06-02 17:43:46 +10:00
flightlevel
601783aef6 .NET Core preparation 2 2018-06-02 17:42:01 +10:00
flightlevel
ac5af81344 .NET Core preparation (#3177)
The DPAPI won't be present, will be using AspNetCore DataProtection
instead
2018-05-30 21:28:20 +10:00
Celedhrim
823563c84f downloadville: fix typo (#3175)
Fix typo if MULTI replacement is check
2018-05-29 22:07:31 +02:00
Celedhrim
47410c5eb6 yggtorrent: fix typo (#3174)
Fix typo if multi language replacement is activate
2018-05-29 22:07:05 +02:00
kaso17
af135f4ae9 Torrent9: update links 2018-05-29 14:41:08 +02:00
kaso17
3eeced3a04 Racing4Everyone: update links 2018-05-29 14:40:56 +02:00
kaso17
8ea99b548d PolishSource: add login detection 2018-05-29 14:09:47 +02:00
kaso17
ae73e8188d Torrent.LT: update categories
fixes #2279
2018-05-29 13:48:07 +02:00
kaso17
9c5cda72da Demonoid: fix download handling 2018-05-29 13:26:35 +02:00
Jonas Stendahl
fb1e24799d TorrentBytes: Don't use truncated release names (#3168) 2018-05-29 12:24:13 +02:00
bpikap
5721948434 torrent-turk: add indexer (#3161)
* Add tracker torrent-turk

* Add torrent-turk to readme
2018-05-29 12:23:39 +02:00
Jorman
d7b6f413be README: Update for Girotorrent (#3159)
Added new girotorrent
2018-05-29 12:23:01 +02:00
Jorman
959ec4667d Girotorrent:_ add indexer (#3158)
Italian Private Tracker
2018-05-29 12:22:45 +02:00
kaso17
20433db169 RevolutionTT: remove debug output 2018-05-24 16:28:14 +02:00
kaso17
54465798e9 GazelleGames: add relogin detection 2018-05-24 16:13:13 +02:00
kaso17
313147d224 Demonoid: add redirect error detection 2018-05-24 16:05:45 +02:00
kaso17
84bd947eca ICE Torrent: update definition 2018-05-24 16:05:23 +02:00
kaso17
366abc4431 Mega-Bliz: fix and improve definition 2018-05-24 15:45:23 +02:00
DarkSupremo
2f7fa2f063 Bjshare: fix broken regex (#3137) 2018-05-23 15:40:23 +02:00
Celedhrim
205f6cac12 Yggtorrent and downloadville: Better MULTI replace (#3135) 2018-05-23 14:11:22 +02:00
Jorman
f602b3db24 README: add Il Corsaro Blu (#3132)
Update file to adding new traker file
2018-05-23 14:10:34 +02:00
Jorman
0d72f1f228 add tracker Il Corsaro Blu (#3131) 2018-05-23 14:10:13 +02:00
kaso17
508125e68f RGU: fix AND search 2018-05-22 18:52:47 +02:00
kaso17
cfb714e13c TorrentSeeds: add andmatch 2018-05-22 18:30:49 +02:00
kaso17
b9dcfd1b02 Torlock: add andmatch 2018-05-22 18:30:29 +02:00
kaso17
a1b2dc67b8 Elit Tracker: add andmatch 2018-05-22 18:30:10 +02:00
Celedhrim
2207c5a961 yggtorrents and downloadville: support multi to french title rewriting (#3130) 2018-05-22 18:07:15 +02:00
kaso17
2caa09bb1e fix bee 2018-05-21 15:51:07 +02:00
kaso17
68906f6e40 readme: fix link 2018-05-21 12:26:02 +02:00
kaso17
2cf3cf15e3 README: add Roslyn note 2018-05-21 12:24:39 +02:00
Jorman
88202c1f7f Isohunt2: fix size parsing (#3127)
Sometimes when parsing, the size of the rel was not enough to have Gb instead Mb or Kb to Mb or whatever
So the size in row is for example 1.015.22 Mb (less than 1024)
So in this case the parser return error

I searched a way to replace this, I found a solution, hope that works in a log way
2018-05-20 21:08:22 +02:00
DarkSupremo
6293c787e7 Bj share: improve search results (#3126)
* Improved anime search and speed-share resolution detection

* - Code Refactored to new standards
- Removed publish date from search mode, since the tracker does not provide that information, it was based on the serie year (but it does provide it on last 24h page, that's still prssent)
- Code clean
- Added season to all animes but One Piece (every anime that i searched in this tracker have the correct season and episode numbering, except One Piece that have an incorrect season set and episode is in absolute format, its added automatically on every new release, so must be the source from where they get that info that is wrong, since its an popular show, added it as an workaround and explained on code as comment)
2018-05-20 21:07:00 +02:00
flightlevel
f67fda3bf4 Add detail to build steps and remove Bountysource 2018-05-20 21:56:50 +10:00
kaso17
c81dd24fe7 RevolutionTT: add time debug output 2018-05-20 10:10:30 +02:00
kaso17
af94dd2757 TVChaosUK: fix parse error 2018-05-20 09:51:18 +02:00
kaso17
0a07738c5b HDME: fix passkey 2018-05-19 06:33:11 +02:00
kaso17
e05783a25a Cardigann: add support for .Config.sitelink 2018-05-19 06:32:16 +02:00
kaso17
27d4ab3967 TorrentBytes: support hidden userbars 2018-05-18 18:10:32 +02:00
61 changed files with 1295 additions and 438 deletions

1
.gitignore vendored
View File

@@ -200,3 +200,4 @@ FakesAssemblies/
/TestResults
*.DS_Store
.idea/
launchSettings.json

View File

@@ -2,7 +2,6 @@
[![GitHub issues](https://img.shields.io/github/issues/Jackett/Jackett.svg?maxAge=60&style=flat-square)](https://github.com/Jackett/Jackett/issues)
[![GitHub pull requests](https://img.shields.io/github/issues-pr/Jackett/Jackett.svg?maxAge=60&style=flat-square)](https://github.com/Jackett/Jackett/pulls)
[![Bountysource](https://img.shields.io/bountysource/team/jackett/activity.svg?style=flat-square)](https://www.bountysource.com/teams/jackett)
[![Build status](https://ci.appveyor.com/api/projects/status/gaybh5mvyx418nsp/branch/master?svg=true)](https://ci.appveyor.com/project/Jackett/jackett)
[![Github Releases](https://img.shields.io/github/downloads/Jackett/Jackett/total.svg?maxAge=60&style=flat-square)](https://github.com/Jackett/Jackett/releases/latest)
[![Docker Pulls](https://img.shields.io/docker/pulls/linuxserver/jackett.svg?maxAge=60&style=flat-square)](https://hub.docker.com/r/linuxserver/jackett/)
@@ -17,8 +16,8 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
#### Supported Systems
* Windows using .NET 4.5.2 [Download here](https://www.microsoft.com/net/framework/versions/net452).
* Linux and macOS using Mono 4.6.0 and above. [Download here](http://www.mono-project.com/download/). Earlier versions of mono may work but some trackers may fail to negotiate SSL correctly, and others may cause Jackett to crash when used.
* 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/). Earlier versions of mono may work, but some trackers may fail to negotiate SSL correctly, and others may cause Jackett to crash when used.
### Supported Public Trackers
* 1337x
@@ -37,6 +36,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
* Horrible Subs
* Idope
* Il Corsaro Nero <!-- maintained by bonny1992 -->
* Il Corsaro Blu
* Isohunt2
* KickAssTorrent
* KickAssTorrent (thekat.se clone)
@@ -163,6 +163,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
* GFXPeers
* GigaTorrents
* GimmePeers <!-- maintained by jamesb2147 -->
* Girotottent
* GODS [![(invite needed)][inviteneeded]](#)
* Greek Team
* HacheDe
@@ -170,6 +171,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
* HD-Forever
* HD-Only
* HD-Space
* HD-Spain
* HD-Torrents
* HD-Bits.com
* HDBits
@@ -239,7 +241,6 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
* SportsCult
* SportHD
* Superbits
* Synthesiz3r
* Tasmanit
* TBPlus
* TenYardTracker
@@ -269,7 +270,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
* Torrents.Md
* TorrentSeeds
* Torrent-Syndikat
* TorrentWTF
* TOrrent-tuRK (TORK)
* TorViet
* ToTheGlory
* TranceTraffic
@@ -317,7 +318,7 @@ 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
1. Install [Mono 4.6](http://www.mono-project.com/download/#download-lin) or better (using the latest stable release for your distribution is recommended)
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.
2. Install libcurl:
@@ -330,6 +331,8 @@ Detailed instructions for [Ubuntu 14.x](http://www.htpcguides.com/install-jacket
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).
## Installation on macOS
### Prerequisites
@@ -399,7 +402,8 @@ All contributions are welcome just send a pull request. Jackett's framework all
## Building from source
### Windows
* Open the Jackett solution in Visual Studio 2017
* Open the Jackett solution in Visual Studio 2017 (version 15.7 or above)
* Right click on the Jackett solution and click 'Rebuild Solution' to restore nuget packages
* Select Jackett.Console as startup project
* Build/Start the project
@@ -418,4 +422,4 @@ mono Jackett.Console/bin/Debug/JackettConsole.exe # run jackett
![screenshot](https://i.imgur.com/0d1nl7g.png "screenshot")
[inviteneeded]: https://raw.githubusercontent.com/Jackett/Jackett/master/.github/label-inviteneeded.png
[inviteneeded]: https://raw.githubusercontent.com/Jackett/Jackett/master/.github/label-inviteneeded.png

View File

@@ -27,6 +27,7 @@ deploy:
description: $(release_description)
auth_token:
secure: hOg+16YTIbq4kO9u4D1YVOTbWDqgCX6mAQYMbnmBBSw2CiUsZh7OKbupoUb3FtWa
artifact: /^(?:(?![Ee]xperimental).)*$/
draft: true
on:
branch: master

View File

@@ -98,7 +98,7 @@
<button id="change-jackett-port" class="btn btn-primary btn-sm">
<i class="fa fa-wrench"></i> Apply server settings <span class="glyphicon glyphicon-ok-wrench" aria-hidden="true"></span>
</button>
<button id="view-jackett-logs" class="btn btn-danger btn-sm">
<button id="view-jackett-logs" class="btn btn-success btn-sm">
<i class="fa fa-rss"></i> View logs <span class="glyphicon glyphicon-ok-wrench" aria-hidden="true"></span>
</button>
<button id="trigger-updater" class="btn btn-warning btn-sm">

View File

@@ -72,7 +72,7 @@
rows:
selector: tr.browse_color, tr.freeleech_color, tr[id^="kdescr"]
after: 1
fields:
fields: # some users (rank specific?) have an extra column (td:nth-child(4)) with bookmark features
banner:
selector: a[href^="details.php?id="][onmouseover]
attribute: onmouseover
@@ -98,20 +98,20 @@
selector: a[href^="download.php"]
attribute: href
files:
selector: td:nth-child(4)
selector: a[href^="filelist.php"]
size:
selector: td:nth-child(7)
selector: td:nth-last-child(6)
grabs:
selector: td:nth-child(8)
selector: td:nth-last-child(5)
filters:
- name: regexp
args: ([\d,]+)
seeders:
selector: td:nth-child(9)
selector: td:nth-last-child(4)
leechers:
selector: td:nth-child(10)
selector: td:nth-last-child(3)
date:
selector: td:nth-child(6)
selector: td:nth-last-child(7)
downloadvolumefactor:
case:
"a.info > b:contains(\"[FREE]\")": "0"

View File

@@ -28,7 +28,7 @@
search:
paths:
- path: "list/{{if .Keywords}}{{.Keywords}}{{else}}movie{{end}}.html"
- path: "list/{{if .Keywords}}{{.Keywords}}{{else}}movie{{end}}/1-1-0.html"
rows:
selector: .rs
fields:

View File

@@ -6,8 +6,9 @@
type: public
encoding: UTF-8
links:
- http://www.cpabien.cm/
- http://www.cpasbiens.cc/
legacylinks:
- http://www.cpabien.cm/
- http://cpabien.cm/
- http://cpasbiens1.com/
- http://cpabien.mx/

View File

@@ -128,7 +128,18 @@
"2" : "Argent (Silver)"
"3" : "Or (Gold)"
"4" : "Argent & Or (Both)"
- name: multilang
type: checkbox
label: Replace MULTI by another language in release name
default: false
- name: multilanguage
type: select
label: Replace MULTI by this language
default: FRENCH
options:
FRENCH : "FRENCH"
MULTI.FRENCH : "MULTI.FRENCH"
ENGLISH: "ENGLISH"
login:
path: tracker/index.php?page=login
method: post
@@ -168,8 +179,15 @@
rows:
selector: table > tbody > tr > td > table.lista > tbody > tr:has(td[onmouseover="this.className='post'"])
fields:
title:
title_phase1:
selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
title_multilang:
text: "{{ .Result.title_phase1 }}"
filters:
- name: re_replace
args: ["[\\.\\s\\[\\-][Mm][Uu][Ll][Tt][Ii][\\.\\s\\]\\-]", ".{{ .Config.multilanguage }}."]
title:
text: "{{if .Config.multilang }}{{ .Result.title_multilang }}{{else}}{{ .Result.title_phase1 }}{{end}}"
details:
selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
attribute: href

View File

@@ -115,6 +115,8 @@
rows:
selector: table > tbody > tr:has(img[src*="/pic/categories/"])
filters:
- name: andmatch
fields:
title:
# using attribute title from td(3) because the text from td(2) a(2) can be abbreviated

View File

@@ -69,6 +69,8 @@
inputs:
$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
search: "{{ .Keywords }}"
sort: "id"
order: "desc"
incldead: "1"
keywordsfilters:
- name: replace
@@ -110,4 +112,4 @@
downloadvolumefactor:
text: "0"
uploadvolumefactor:
text: "1"
text: "1"

View File

@@ -0,0 +1,225 @@
---
site: girotorrent
name: Girotorrent
description: "Girotorrent is an ITALIAN Private site for TV / MOVIES / GENERAL"
language: it-it
type: private
encoding: UTF-8
links:
- http://girotorrent.org/
caps:
categorymappings:
# LIBREDICOLA
- {id: 13, cat: Books, desc: "Giornali e Riviste"}
- {id: 15, cat: Books, desc: "Ebook"}
- {id: 16, cat: Books, desc: "Fumetti"}
- {id: 70, cat: Books, desc: "Manuali e Guide"}
- {id: 72, cat: Audio/Audiobook, desc: "Audiolibri"}
# CINEMA
- {id: 17, cat: Movies/Other, desc: "Movie Cam-Ts"}
- {id: 18, cat: Movies/Other, desc: "Movie Screener"}
- {id: 61, cat: Movies/Other, desc: "Movie R5-R6"}
- {id: 19, cat: Movies/Other, desc: "Movie DVDRip"}
- {id: 20, cat: Movies/Other, desc: "Movie BDRip"}
- {id: 60, cat: Movies/Other, desc: "Movie BluRay"}
- {id: 63, cat: Movies/Other, desc: "Movie WEBDLRip"}
# VIDEOTECA
- {id: 22, cat: Movies/SD, desc: "Movie BDRip"}
- {id: 23, cat: Movies/SD, desc: "Movie DvdRip"}
- {id: 23, cat: Movies/SD, desc: "Movie WEBRip"}
- {id: 24, cat: Movies/DVD, desc: "Movie DVD-R 5"}
- {id: 25, cat: Movies/DVD, desc: "Movie DVD-R 9"}
- {id: 26, cat: Movies/HD, desc: "Movie Blu-Ray HD"}
- {id: 27, cat: Movies/3D, desc: "Movie 3D-SBS"}
- {id: 96, cat: Movies/HD, desc: "Movie x265 HEVC"}
- {id: 28, cat: Movies/Foreign, desc: "Movie Subbet-ita"}
- {id: 73, cat: Movies/SD, desc: "Movie MP4"}
- {id: 29, cat: Movies/Foreign, desc: "Movie Ligua Originale"}
# ANIMAZIONE
- {id: 32, cat: TV/Anime, desc: "Anime Disney"}
- {id: 33, cat: TV/Anime, desc: "Anime"}
- {id: 34, cat: TV/Anime, desc: "Anime Altri Cartoni"}
# TELEVISIONE
- {id: 36, cat: TV, desc: "TV Serie TV"}
- {id: 77, cat: TV, desc: "TV Reality"}
- {id: 37, cat: TV, desc: "TV Film TV"}
- {id: 59, cat: TV, desc: "TV Sport"}
- {id: 38, cat: TV, desc: "TV Concerti-Spettacoli"}
- {id: 39, cat: TV, desc: "TV Teatro-Cabaret"}
- {id: 40, cat: TV/Documentary, desc: "Tv Documentario"}
# MUSICA
- {id: 42, cat: Audio, desc: "Musica CD Singoli"}
- {id: 43, cat: Audio, desc: "Musica Italiana"}
- {id: 44, cat: Audio, desc: "Musica Straniera"}
- {id: 45, cat: Audio, desc: "Musica Compilation"}
- {id: 46, cat: Audio, desc: "Musica Video Clip"}
- {id: 58, cat: Audio, desc: "Musica Discografie"}
# SALA GIOCHI
- {id: 47, cat: PC/Games, desc: "PC Games"}
- {id: 48, cat: PC/Games, desc: "PC Giochi PS2-PS3"}
- {id: 49, cat: PC/Games, desc: "PC Giochi Nintendo Wii"}
- {id: 50, cat: PC/Games, desc: "PC Giochi Xbox"}
- {id: 52, cat: PC/Games, desc: "PC Giochi DS-DS3"}
# SOFTWARE
- {id: 54, cat: PC, desc: "PC Programmi Windows"}
- {id: 55, cat: PC/Mac, desc: "PC Mac"}
- {id: 69, cat: PC, desc: "PC Portable"}
- {id: 56, cat: PC, desc: "PC Linux"}
# CELLULARI-PALMARI
- {id: 71, cat: PC/Phone-Android, desc: "Android APP"}
- {id: 74, cat: Other, desc: "Varie"}
- {id: 75, cat: Other, desc: "Immagini Wallpaper"}
modes:
search: [q]
tv-search: [q, season, ep]
movie-search: [q]
login:
path: /index.php?page=login
method: post
inputs:
uid: "{{ .Config.username }}"
pwd: "{{ .Config.password }}"
error:
- selector: div.error
test:
path: /index.php
selector: a[href="logout.php"]
download:
before:
path: "thanks.php"
method: "post"
inputs:
infohash: "{{ .DownloadUri.Query.id }}"
thanks: "1"
rndval: "1487013827343"
selector: a[href^="download.php?id="]
search:
paths:
- path: /index.php
keywordsfilters:
- name: re_replace
args: ["S[0-9]{2}([^E]|$)", ""] # remove season tag without episode (search doesn't support it)
- name: diacritics
args: replace
# most ITA TV torrents are in XXxYY format, so we search without S/E prefixes and filter later
- name: re_replace
args: ["S0?(\\d{1,2})", " $1 "]
- name: re_replace
args: ["E(\\d{2,3})", " $1 "]
inputs:
search: "{{ .Keywords }}"
category: "{{range .Categories}}{{.}};{{end}}"
page: "torrents"
active: 0
rows:
selector: div.b-content > table > tbody > tr > td > table.lista > tbody > tr:has(a[href^="index.php?page=torrent-details&id="])
#http://girotorrent.org/index.php?page=torrent-details&id=73d93dccf84ea3a8b614a3113acfd9eea186d730
fields:
download:
selector: a[href^="index.php?page=downloadcheck&id="]
attribute: href
title: # shortened title?
selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
# normalize to SXXEYY format
filters:
- name: re_replace # replace special characters with " " (space)
args: ["[^a-zA-Z0-9]|\\.", " "]
# normalize to SXXEYY format
- name: re_replace
args: ["(\\d{2})x(\\d{2})", "S$1E$2"]
- name: re_replace
args: ["(\\d{1})x(\\d{2})", "S0$1E$2"]
- name: re_replace #Stagione X --> S0X
args: ["Stagione (\\d{0,1}\\s)", "S0$1"]
- name: re_replace #Stagione XX --> SXX
args: ["Stagione (\\d{2}\\s)", "S$1"]
- name: re_replace #/ Episodio [YY-YY --> EYY-YY
args: ["(\\s\\/\\sEpisodio|\\s\\/\\sEpisodi|\\sEpisodio|\\s\\|\\sEpisodio|\\sEpisodi)\\s\\[", "E"]
- name: re_replace #/ Completa [episodi YY-YY --> EYY-YY
args: ["(\\s\\/\\sCompleta\\s\\[episodi\\s)", "E"]
- name: re_replace #remove di YY] | remove /YY]
args: ["(\\sdi\\s\\d{1,2}|\\/\\d{1,2})\\]", " "]
- name: re_replace #remove various
args: ["(Serie completa|Completa|\\[in pausa\\])", ""]
# fine prova
title: # long titles?
optional: true
selector: a[title][href^="index.php?page=torrent-details"]
attribute: title
filters:
- name: replace
args: ["Vedi Dettagli: ", ""]
# inizio prova
- name: re_replace # replace special characters with " " (space)
args: ["[^a-zA-Z0-9]|\\.", " "]
# normalize to SXXEYY format
- name: re_replace
args: ["(\\d{2})x(\\d{2})", "S$1E$2"]
- name: re_replace
args: ["(\\d{1})x(\\d{2})", "S0$1E$2"]
- name: re_replace #Stagione X --> S0X
args: ["Stagione (\\d{0,1}\\s)", "S0$1"]
- name: re_replace #Stagione XX --> SXX
args: ["Stagione (\\d{2}\\s)", "S$1"]
- name: re_replace #/ Episodio [YY-YY --> EYY-YY
args: ["(\\s\\/\\sEpisodio|\\s\\/\\sEpisodi|\\sEpisodio|\\s\\|\\sEpisodio|\\sEpisodi)\\s\\[", "E"]
- name: re_replace #/ Completa [episodi YY-YY --> EYY-YY
args: ["(\\s\\/\\sCompleta\\s\\[episodi\\s)", "E"]
- name: re_replace #remove di YY] | remove /YY]
args: ["(\\sdi\\s\\d{1,2}|\\/\\d{1,2})\\]", " "]
- name: re_replace #remove various
args: ["(Serie completa|Completa|\\[in pausa\\])", ""]
# fine prova
category:
selector: a[href^="index.php?page=torrents&category="]
attribute: href
filters:
- name: querystring
args: category
details:
selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
attribute: href
banner:
optional: true
selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
attribute: onmouseover
filters:
- name: regexp
args: "src=(.+?) "
size:
selector: td:nth-child(11)
date:
selector: td:nth-child(6)
filters:
- name: dateparse
args: "02/01/2006"
grabs:
selector: td:nth-child(9)
filters:
- name: replace
args: ["---", "0"]
seeders:
selector: td:nth-child(7)
leechers:
selector: td:nth-child(8)
downloadvolumefactor:
case:
img[alt="Free Leech"]: "0"
img[alt="Gold 100% Free"]: "0"
img[alt="Silver 50% Free"]: "0.5"
img[alt="Bronze 25% Free"]: "0.75"
"*": "1"
uploadvolumefactor:
text: "1"
uploadvolumefactor:
optional: true
selector: img[alt$="x Upload Multiplier"]
attribute: alt
filters:
- name: replace
args: ["x Upload Multiplier", ""]

View File

@@ -61,7 +61,6 @@
search:
paths:
- path: /torrents.php
method: post
inputs:
$raw: "{{range .Categories}}cat{{.}}=1&{{end}}"
search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}"

View File

@@ -82,7 +82,6 @@
search:
paths:
- path: /torrents.php
method: post
inputs:
$raw: "{{range .Categories}}cat{{.}}=1&{{end}}"
search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}"

View File

@@ -91,6 +91,11 @@
download:
selector: td:nth-child(11) > a
attribute: href
filters:
- name: prepend
args: "{{ .Config.sitelink }}"
- name: replace # https download links are redirected to http causing invalid cookies => invalid passkeys
args: ["https", "http"]
size:
selector: td:nth-child(6)
remove: br
@@ -103,3 +108,9 @@
selector: td:nth-child(8)
leechers:
selector: td:nth-child(9)
downloadvolumefactor:
case:
"font:contains(\"(FreeLeech)\")": "0"
"*": "1"
uploadvolumefactor:
text: "1"

View File

@@ -0,0 +1,142 @@
---
site: hdspain
name: HD-Spain
description: "HD-Spain is a SPANISH site for HD content"
language: es-es
type: private
encoding: ISO-8859-1
links:
- https://www.hd-spain.com/
caps:
categorymappings:
- {id: 1 , cat: Movies/HD, desc: "Películas"}
- {id: 5 , cat: Movies/HD, desc: "Pelíc. Anim."}
- {id: 4 , cat: TV/HD, desc: "Series"}
- {id: 3 , cat: TV/HD, desc: "Series Anim."}
- {id: 6 , cat: TV/Documentary, desc: "Documentales"}
- {id: 11, cat: TV/Sport, desc: "Deportes"}
- {id: 7 , cat: Audio/Video, desc: "Música/Espec."}
- {id: 9 , cat: TV/OTHER, desc: "Programas TV"}
- {id: 8 , cat: Audio/Lossless, desc: "Audios"}
- {id: 10, cat: XXX/x264, desc: "XXX"}
modes:
search: [q]
login:
path: index.php
method: form
inputs:
usuario: "{{ .Config.username }}"
contrasena: "{{ .Config.password }}"
error:
- selector: p.error
test:
path: index.php
selector: .tcabecera
search:
path: index.php
keywordsfilters:
- name: re_replace
args: ["S0?(\\d{1,2})E(\\d{1,2})", "$1x$2"]
inputs:
sec: listado
ord: 9
b: "{{ .Keywords }}"
ver: "0"
relanz: "0"
$raw: "{{range .Categories}}&cat[]={{.}}{{end}}"
rows:
selector: "table.listatorrents tr:not(:first-child)"
fields:
category:
selector: td.categorias a
attribute: href
filters:
- name: querystring
args: cat
title:
selector: td.titulo a[id]
filters:
- name: append
args: " [spanish]"
details:
selector: td.titulo a
attribute: href
size:
selector: td.tamano
seeders:
selector: td.usuarios.seeds a
leechers:
selector: td.usuarios.leechers a
grabs:
selector: td.usuarios.completados
date:
optional: true
selector: td.fecha
attribute: title
filters:
- name: replace
args: ["Lunes", "Monday"]
- name: replace
args: ["Martes", "Tuesday"]
- name: re_replace
args: ["Miércoles", "Wednesday"]
- name: replace
args: ["Jueves", "Thursday"]
- name: replace
args: ["Viernes", "Friday"]
- name: re_replace
args: ["Sábado", "Saturday"]
- name: replace
args: ["Domingo", "Sunday"]
- name: replace
args: ["Enero", "January"]
- name: replace
args: ["Febrero", "February"]
- name: replace
args: ["Marzo", "March"]
- name: replace
args: ["Abril", "April"]
- name: replace
args: ["Mayo", "May"]
- name: replace
args: ["Junio", "June"]
- name: replace
args: ["Julio", "July"]
- name: replace
args: ["Agosto", "August"]
- name: replace
args: ["Septiembre", "September"]
- name: replace
args: ["Octubre", "October"]
- name: replace
args: ["Noviembre", "November"]
- name: replace
args: ["Diciembre", "December"]
- name: dateparse
args: "Monday 2 January 2006, 15:04"
download:
selector: td.descargar a
attribute: href
downloadvolumefactor:
text: "1"
downloadvolumefactor:
optional: true
selector: td.descargar a b strong
filters:
- name: replace
args: [" X2", ""]
- name: replace
args: ["Freeleech", "0"]
uploadvolumefactor:
text: "1"
uploadvolumefactor:
optional: true
selector: td.descargar a b strong
filters:
- name: replace
args: ["Freeleech X2", "2"]

View File

@@ -114,7 +114,7 @@
selector: td:has(a[href$="filelist=1#filelist"])
remove: a
date:
selector: td > font:contains("Added on")
selector: td > font:has(i.fa-clock-o)
remove: b
filters:
- name: replace

View File

@@ -0,0 +1,160 @@
---
site: ilcorsaroblu
name: Il Corsaro Blu
description: "Il Corsaro Blu is an ITALIAN Public site for TV / MOVIES / GENERAL"
language: it-it
type: public
encoding: UTF-8
links:
- https://www.ilcorsaroblu.info/
legacylinks:
- http://ilcorsaroblu.org/
- https://www.ilcorsaroblu.org/
caps:
categorymappings:
# Adult
- {id: 12, cat: XXX, desc: "Adult"}
# Applicazioni
- {id: 5, cat: PC/Phone-Android, desc: "Android"}
# Books
- {id: 6, cat: Books, desc: "Books"}
# Games
- {id: 3, cat: Other, desc: "Games"}
# Music
- {id: 2, cat: Audio, desc: "Music"}
# Movies
- {id: 17, cat: Movies/SD, desc: "Movie BDRip"}
- {id: 21, cat: Movies/Other, desc: "Movies - Films"}
- {id: 11, cat: Movies/DVD, desc: "DVD-R"}
- {id: 14, cat: Movies/HD, desc: "Movie 720p"}
- {id: 13, cat: Movies/HD, desc: "Movie 1080p"}
- {id: 15, cat: Movies/3D, desc: "Movie 3D"}
- {id: 24, cat: TV/OTHER, desc: "TV Show Standard"}
- {id: 19, cat: TV/HD, desc: "Tv Show 1080p"}
- {id: 20, cat: TV/HD, desc: "Tv Show 720"}
# Various
- {id: 4, cat: Other, desc: "Other"}
- {id: 7, cat: PC, desc: "Windows"}
- {id: 8, cat: Other, desc: "Linux"}
- {id: 9, cat: PC/Mac, desc: "Mac"}
- {id: 23, cat: Other, desc: "Archive"}
modes:
search: [q]
tv-search: [q, season, ep]
movie-search: [q]
settings: []
search:
paths:
- path: /index.php
keywordsfilters:
- name: re_replace
args: ["S[0-9]{2}([^E]|$)", ""] # remove season tag without episode (search doesn't support it)
- name: diacritics
args: replace
# most ITA TV torrents are in XXxYY format, so we search without S/E prefixes and filter later
- name: re_replace
args: ["S0?(\\d{1,2})", " $1 "]
- name: re_replace
args: ["E(\\d{2,3})", " $1 "]
inputs:
search: "{{ .Keywords }}"
category: "{{range .Categories}}{{.}};{{end}}"
page: torrents
active: 0
rows:
selector: div.b-content > table > tbody > tr > td > table.lista > tbody > tr:has(a[href^="index.php?page=torrents&category="])
fields:
title:
selector: td:nth-child(2) > a
# normalize to SXXEYY format
filters:
- name: re_replace # replace special characters with " " (space)
args: ["[^a-zA-Z0-9]|\\.", " "]
# normalize to SXXEYY format
- name: re_replace
args: ["(\\d{2})x(\\d{2})", "S$1E$2"]
- name: re_replace
args: ["(\\d{1})x(\\d{2})", "S0$1E$2"]
- name: re_replace #Stagione X --> S0X
args: ["Stagione (\\d{0,1}\\s)", "S0$1"]
- name: re_replace #Stagione XX --> SXX
args: ["Stagione (\\d{2}\\s)", "S$1"]
- name: re_replace #/ Episodio [YY-YY --> EYY-YY
args: ["(\\s\\/\\sEpisodio|\\s\\/\\sEpisodi|\\sEpisodio|\\s\\|\\sEpisodio|\\sEpisodi)\\s\\[", "E"]
- name: re_replace #/ Completa [episodi YY-YY --> EYY-YY
args: ["(\\s\\/\\sCompleta\\s\\[episodi\\s)", "E"]
- name: re_replace #remove di YY] | remove /YY]
args: ["(\\sdi\\s\\d{1,2}|\\/\\d{1,2})\\]", " "]
- name: re_replace #remove various
args: ["(Serie completa|Completa|\\[in pausa\\])", ""]
# fine prova
download: # handle torrents with normal torrent file download
optional: true
selector: a[href^="download.php?id="]
attribute: href
filters:
- name: querystring
args: id
- name: toupper
- name: prepend
args: http://itorrents.org/torrent/
- name: append
args: ".torrent"
_magnetfilename: # convert title to valid magnet filename
text: "{{ .Result.title }}"
filters:
- name: validfilename
- name: urlencode
magnet: # generate magnet link from download link
optional: true
selector: a[href^="download.php?id="]
attribute: href
filters:
- name: querystring
args: id
- name: prepend
args: "magnet:?xt=urn:btih:"
- name: append
args: "&dn={{ .Result._magnetfilename }}.torrent"
- name: append # add some well known public trackers
args: "&tr=udp://tracker.openbittorrent.com:80/announce&tr=udp://tracker.opentrackr.org:1337/announce"
magnet: # in case a direct magnet link is provided use it
optional: true
selector: a[href^="magnet:?xt="]
attribute: href
category:
selector: a[href^="index.php?page=torrents&category="]
attribute: href
filters:
- name: querystring
args: category
details:
selector: td:nth-child(2) a
attribute: href
banner:
optional: true
selector: td:nth-child(2) > a
attribute: onmouseover
filters:
- name: regexp
args: "src=(.+?) "
size:
selector: td:nth-child(9)
date:
selector: td:nth-child(5)
filters:
- name: dateparse
args: "02/01/2006"
grabs:
selector: td:nth-child(8)
filters:
- name: replace
args: ["---", "0"]
seeders:
selector: td:nth-child(6)
leechers:
selector: td:nth-child(7)

View File

@@ -77,6 +77,9 @@
attribute: href
size:
selector: td.size-row
filters:
- name: re_replace
args: ["(\\d+).(?=\\d{3}(\\D|$))", "$1"]
seeders:
selector: td.sn
date:
@@ -96,4 +99,4 @@
downloadvolumefactor:
text: "0"
uploadvolumefactor:
text: "1"
text: "1"

View File

@@ -10,53 +10,20 @@
caps:
categorymappings:
# TV
- {id: 23, cat: TV, desc: "TV/HD"}
- {id: 47, cat: TV, desc: "TV/PACKS"}
- {id: 28, cat: TV, desc: "TV/eps"}
- {id: 25, cat: TV, desc: "TV/HDRIP"}
- {id: 24, cat: TV, desc: "TV/TV-packs"}
- {id: 26, cat: TV/HD, desc: "TV/X264-HD"}
- {id: 27, cat: TV/SD, desc: "TV/X264-SD"}
# Movies
- {id: 10, cat: Movies, desc: "Movies/0DAY"}
- {id: 56, cat: Movies/3D, desc: "Movies/3D"}
- {id: 16, cat: TV/Anime, desc: "Movies/ANIME"}
- {id: 44, cat: Movies, desc: "Movies/CAM"}
- {id: 18, cat: Movies/DVD, desc: "Movies/DVDR"}
- {id: 49, cat: Movies/HD, desc: "Movies/hd 1080p"}
- {id: 48, cat: Movies/HD, desc: "Movies/hd 720p"}
- {id: 55, cat: Movies, desc: "Movies/Box Sets"}
- {id: 53, cat: Movies, desc: "Movies/Sports"}
- {id: 17, cat: Movies, desc: "Movies/X264"}
- {id: 57, cat: Movies, desc: "Movies/xmas"}
- {id: 15, cat: Movies/SD, desc: "Movies/XVID"}
# Music
- {id: 54, cat: Audio/Audiobook, desc: "Music/Audio Book"}
- {id: 19, cat: Audio/Lossless, desc: "Music/FLAC"}
- {id: 20, cat: Audio, desc: "Music/DVDR"}
- {id: 21, cat: Audio/MP3, desc: "Music/MP3"}
- {id: 42, cat: Audio, desc: "Music/0DAY"}
- {id: 22, cat: Audio/Video, desc: "Music/VID"}
# Apps
- {id: 9, cat: PC/0day, desc: "Apps/APPS"}
- {id: 11, cat: Books/Ebook, desc: "Apps/EBOOKS"}
- {id: 46, cat: PC/Phone-Other, desc: "Apps/IPHONE/ANDROID"}
- {id: 51, cat: PC, desc: "Apps/Linux"}
- {id: 52, cat: PC/Mac, desc: "Apps/MAC"}
# Games
- {id: 58, cat: Console/Other, desc: "Games/Android"}
- {id: 45, cat: PC/Games, desc: "Games/GAMES"}
- {id: 59, cat: Console/NDS, desc: "Games/NDS"}
- {id: 50, cat: Console, desc: "Games/PS2"}
- {id: 14, cat: Console/PS3, desc: "Games/PS3"}
- {id: 12, cat: Console/Wii, desc: "Games/WII"}
- {id: 13, cat: Console/Xbox 360, desc: "Games/XBOX360"}
# XXX
- {id: 38, cat: XXX, desc: "XXX"}
- {id: 39, cat: XXX, desc: "XXX/0DAY"}
- {id: 40, cat: XXX/Imageset, desc: "XXX/IMAGESET"}
- {id: 41, cat: XXX/Other, desc: "XXX/SITERIPS"}
- {id: 9, cat: TV/Anime, desc: "Anime"}
- {id: 1, cat: PC/0day, desc: "Apps"}
- {id: 13, cat: PC/0day, desc: "Apps"}
- {id: 5, cat: TV, desc: "Episodes"}
- {id: 2, cat: PC/Games, desc: "Games"}
- {id: 12, cat: PC/Games, desc: "Games/PC Rips"}
- {id: 8, cat: Console/Other, desc: "Games/PS2"}
- {id: 7, cat: Console/PSP, desc: "Games/PSP"}
- {id: 3, cat: Movies, desc: "Movies"}
- {id: 11, cat: Movies/SD, desc: "Movies/HDTV"}
- {id: 10, cat: Movies/SD, desc: "Movies/XviD"}
- {id: 4, cat: Audio, desc: "Music"}
- {id: 14, cat: Audio, desc: "Music"}
- {id: 6, cat: XXX, desc: "XXX"}
modes:
search: [q]
@@ -101,13 +68,13 @@
selector: table tr td.text
test:
path: browse.php
selector: li a[href^="logout.php?hash_please="]
selector: a[href*="logout.php?hash_please="]
search:
paths:
- path: browse.php
inputs:
#$raw: "{{range .Categories}}c{{.}}=1&{{end}}" # this should work, untested
$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
search: "{{ .Keywords }}"
searchin: "title"
incldead: "{{ .Config.incldead }}"
@@ -137,11 +104,7 @@
selector: td:nth-of-type(3) a
attribute: href
files:
optional: true
selector: td:nth-of-type(5) a
files:
optional: true
selector: td:nth-of-type(5):not(:has(a))
selector: td:nth-of-type(5)
date:
selector: td:nth-of-type(7)
filters:
@@ -155,12 +118,13 @@
- name: regexp
args: "([\\d]+)"
seeders:
selector: td:nth-of-type(10) a font
selector: td:nth-of-type(10)
leechers:
selector: td:nth-of-type(11)
downloadvolumefactor:
case:
"span:contains(\"Unlimited\")": "0"
"img[title=\"Free Torrent\"]": "0" # torrent specific free leech (icon)?
"a.info:contains(\"Free\")": "0" # global freeleech note?
"*": "1"
uploadvolumefactor:
text: "1"

View File

@@ -44,6 +44,7 @@
- selector: td.embedded:has(h2:contains("failed"))
- selector: td.embedded:has(h2:contains("Error"))
test:
selector: a[href^="logout.php"]
path: /browse.php
search:

View File

@@ -6,6 +6,8 @@
type: private
encoding: UTF-8
links:
- https://racing4everyone.eu/
legacylinks:
- https://racing4everyone.jp/
caps:

View File

@@ -83,7 +83,9 @@
searchin: "title"
incldead: "{{ .Config.incldead }}"
"only_free": "{{ if .Config.onlyfree }}1{{else}}0{{end}}"
keywordsfilters:
- name: re_replace
args: ["(\\w+)", " +$1"] # prepend + to each word
rows:
selector: tr.browse_color, tr[id^="kdescr"]
after: 1
@@ -141,7 +143,10 @@
args: ["\n", "<br>\n"]
downloadvolumefactor:
case:
"b:contains(\"[Free and Double]\")": "0"
"img[alt=\"Free Torrent\"]": "0"
"*": "1"
uploadvolumefactor:
text: "1"
case:
"b:contains(\"[Free and Double]\")": "2"
"*": "1"

View File

@@ -6,10 +6,10 @@
type: private
encoding: UTF-8
links:
- http://www.shareisland.org/
legacylinks:
- https://shareisland.org/
- http://shareisland.org/
legacylinks:
- http://shareisland.org/
- http://www.shareisland.org/
caps:
categorymappings:
@@ -28,6 +28,7 @@
- {id: 41, cat: Books, desc: "Quotidiani"}
- {id: 59, cat: Books, desc: "Fumetti"}
- {id: 60, cat: Books, desc: "Riviste"}
- {id: 61, cat: Books, desc: "Audiolibri"}
# Games
- {id: 47, cat: PC/Games, desc: "Games PC"}
- {id: 22, cat: Console/Other, desc: "Nintendo"}

View File

@@ -60,6 +60,8 @@
args: ["[^a-zA-Z0-9]+", "-"]
rows:
selector: table > tbody > tr:has(td:has(div:has(a[href^="/torrent/"])))
filters:
- name: andmatch
fields:
title:
selector: td:nth-child(1) > div > a

View File

@@ -0,0 +1,111 @@
---
site: torrent-turk
name: TOrrent-tuRK
description: "TOrrent-tuRK (TORK) is a Turkish Private Torrent Tracker for HD MOVIES / TV / GENERAL"
language: tr-TR
type: private
encoding: UTF-8
links:
- https://torrent-turk.org/
caps:
categorymappings:
- {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: 156, cat: Movies, desc: "Movies/Foreign"}
- {id: 157, cat: Movies/UHD, desc: "Movies/Foreign/4K"}
- {id: 159, cat: Movies/HD, desc: "Movies/Foreign/1080p"}
- {id: 160, cat: Movies/HD, desc: "Movies/Foreign/720p"}
- {id: 164, cat: TV, desc: "TV"}
- {id: 165, cat: TV, desc: "TV/Turkish"}
- {id: 166, cat: TV, desc: "TV/Foreign"}
- {id: 171, cat: Audio, desc: "Music"}
- {id: 172, cat: Audio, desc: "Music/Turkish"}
- {id: 173, cat: Audio, desc: "Music/Foreign"}
modes:
search: [q]
tv-search: [q]
movie-search: [q]
login:
path: /?p=home&pid=1
method: form
form: form#loginbox_form
submitpath: /ajax/login.php
inputs:
action: "login"
loginbox_membername: "{{ .Config.username }}"
loginbox_password: "{{ .Config.password }}"
loginbox_remember: "true"
selectorinputs:
securitytoken:
selector: "script:contains(\"stKey: \")"
filters:
- name: regexp
args: "stKey: \"(.+?)\","
error:
- selector: ":contains(\"-ERROR-\")"
test:
path: /?p=torrents&type=bookmarks&pid=508
selector: a#logout
search:
paths:
- path: /
keywordsfilters:
- name: re_replace
args: ["[^a-zA-Z0-9]+", "%25"]
inputs:
p: "torrents"
pid: "32"
$raw: "{{range .Categories}}cid[]={{.}}&{{end}}"
keywords: "{{ .Keywords }}"
search_type: "name"
searchin: "title"
error:
- selector: div.error:not(:contains("Hiçbir sonuç bulunamadı."))
rows:
selector: table#torrents_table_classic > tbody > tr:has(td.torrent_name)
fields:
title:
selector: a[href*="?p=torrents&pid=10&action=details"]
category:
selector: div.category_image > a
attribute: href
filters:
- name: querystring
args: cid
details:
selector: a[href*="?p=torrents&pid=10&action=details"]
attribute: href
download:
selector: a[href*="?p=torrents&pid=10&action=download"]
attribute: href
size:
selector: a[rel="torrent_size"]
seeders:
selector: a[rel="torrent_seeders"]
leechers:
selector: a[rel="torrent_leechers"]
grabs:
selector: a[rel="times_completed"]
banner:
selector: a[rel="fancybox"]
optional: true
attribute: href
downloadvolumefactor:
case:
"img[title=\"FREE!\"]": "0"
"*": "1"
uploadvolumefactor:
case:
"*": "1"
date:
selector: td.torrent_name > abbr.timeago
optional: true
attribute: data-time

View File

@@ -6,8 +6,9 @@
type: public
encoding: UTF-8
links:
- http://www.torrent9.red/
- http://www.torrent9.ec/
legacylinks:
- http://www.torrent9.red/
- http://www.torrent9.bz/
- http://www.torrents9.pe/
- http://www.torrent9.cc/

View File

@@ -55,6 +55,7 @@
- {id: 71, cat: XXX/Packs, desc: "pr0n / pack"}
- {id: 30, cat: Other, desc: "Kita"}
- {id: 41, cat: Books, desc: "E-Books"}
- {id: 76, cat: TV, desc: "Animacija / LT"}
modes:
search: [q]

View File

@@ -115,6 +115,8 @@
rows:
selector: tr.browse_color, tr[id^="kdescr"]
after: 1
filters:
- name: andmatch
fields:
category:
selector: td:nth-of-type(1) a

View File

@@ -1,111 +0,0 @@
---
site: torrentwtf
name: Torrentwtf
description: "Torrentwtf is a Czech Private site for TV / MOVIES / GENERAL"
language: cs-cz
type: private
encoding: UTF-8
links:
- https://torrent.wtf/
caps:
categorymappings:
- {id: 1, cat: Movies, desc: "Filmy"}
- {id: 2, cat: TV, desc: "Seriály"}
- {id: 3, cat: Audio, desc: "Hudba"}
- {id: 5, cat: PC/Games, desc: "Hry"}
- {id: 6, cat: Books, desc: "Knihy"}
- {id: 8, cat: PC, desc: "Software"}
- {id: 9, cat: XXX, desc: "xXx"}
- {id: 10, cat: Other, desc: "Ostatní"}
modes:
search: [q]
tv-search: [q, season, ep, imdbid]
movie-search: [q, imdbid]
login:
path: /login
method: form
inputs:
username: "{{ .Config.username }}"
password: "{{ .Config.password }}"
error:
- selector: table.main:contains("Tieto poverenia sa nezhodujú s našimi záznamami.")
test:
path: /torrents
search:
paths:
- path: /filter
inputs:
$raw: "{{range .Categories}}categories[]={{.}}&{{end}}"
search: "{{if .Query.IMDBID}}{{else}}{{ .Keywords }}{{end}}"
imdb: "{{ .Query.IMDBIDShort }}"
tvdb: ""
tmdb: ""
sorting: created_at
direction: desc
qty: 100
preprocessingfilters:
- name: jsonjoinarray
args: ["$.result", ""]
- name: prepend
args: "<table>"
- name: append
args: "</table>"
rows:
selector: tr
fields:
category:
selector: a[href*="/categories/"]
attribute: href
filters:
- name: regexp
args: "/categories/.*?\\.(\\d+)"
title:
selector: a.view-torrent
filters:
- name: re_replace
args: [".*? / ", ""]
download:
selector: a[href*="/download_check/"]
attribute: href
filters:
- name: replace
args: ["/download_check/", "/download/"]
details:
selector: a.view-torrent
attribute: href
imdb:
optional: true
selector: a[href*="://www.imdb.com/title/"]
attribute: href
size:
selector: td:nth-child(5)
seeders:
selector: td:nth-child(7)
leechers:
selector: td:nth-child(8)
grabs:
selector: td:nth-child(6)
filters:
- name: regexp
args: ([\d\.]+)
date:
selector: time
attribute: datetime
filters:
- name: append
args: " +00:00"
- name: dateparse
args: "2006-01-02 15:04:05 -07:00"
downloadvolumefactor:
case:
"i[data-original-title=\"100% Free\"]": "0"
"i[data-original-title=\"Global FreeLeech\"]": "0"
"*": "1"
uploadvolumefactor:
case:
"i[data-original-title=\"Double upload\"]": "2"
"*": "1"

View File

@@ -120,7 +120,7 @@
selector: table#browsetable > tbody > tr:has(a[href^="/details.php?id="])
fields:
category:
selector: a[href^="/browse.php?q="]
selector: a[href^="/browse.php"]
attribute: href
filters:
- name: querystring

View File

@@ -6,8 +6,9 @@
type: semi-private
encoding: UTF-8
links:
- https://yggtorrent.is/
- https://ww1.yggtorrent.is/
legacylinks:
- https://yggtorrent.is/
- https://yggtorrent.com/
- https://ww1.yggtorrent.com/
@@ -96,7 +97,18 @@
type: checkbox
label: Try to normalize releases names by moving year after the title
default: false
- name: multilang
type: checkbox
label: Replace MULTI by another language in release name
default: false
- name: multilanguage
type: select
label: Replace MULTI by this language
default: FRENCH
options:
FRENCH : "FRENCH"
MULTI.FRENCH: "MULTI.FRENCH"
ENGLISH: "ENGLISH"
login:
method: form
path: /
@@ -140,8 +152,15 @@
- name: re_replace
args: ["(\\s{2,5})", " "]
- name: trim
title:
title_phase1:
text: "{{if .Config.filter_title }}{{ .Result.title_filtered }}{{else}}{{ .Result.title_normal }}{{end}}"
title_multilang:
text: "{{ .Result.title_phase1 }}"
filters:
- name: re_replace
args: ["[\\.\\s\\[\\-][Mm][Uu][Ll][Tt][Ii][\\.\\s\\]\\-]", ".{{ .Config.multilanguage }}."]
title:
text: "{{if .Config.multilang }}{{ .Result.title_multilang }}{{else}}{{ .Result.title_phase1 }}{{end}}"
details:
selector: ":nth-child(2) > a"
attribute: href
@@ -238,4 +257,4 @@
downloadvolumefactor:
text: "1"
uploadvolumefactor:
text: "1"
text: "1"

View File

@@ -20,21 +20,29 @@ namespace Jackett.Common.Indexers
{
public class BJShare : BaseWebIndexer
{
private string LoginUrl { get { return SiteLink + "login.php"; } }
private string BrowseUrl { get { return SiteLink + "torrents.php"; } }
private string TodayUrl { get { return SiteLink + "torrents.php?action=today"; } }
private char[] digits = new[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
private new ConfigurationDataBasicLoginWithRSSAndDisplay configData
private string LoginUrl => SiteLink + "login.php";
private string BrowseUrl => SiteLink + "torrents.php";
private string TodayUrl => SiteLink + "torrents.php?action=today";
private readonly char[] _digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
private readonly Dictionary<string, string> _commonSearchTerms = new Dictionary<string, string>
{
get { return (ConfigurationDataBasicLoginWithRSSAndDisplay)base.configData; }
set { base.configData = value; }
{ "agents of shield", "Agents of S.H.I.E.L.D."}
};
public override string[] LegacySiteLinks { get; protected set; } = new string[] {
"https://bj-share.me/"
};
private ConfigurationDataBasicLoginWithRSSAndDisplay ConfigData
{
get => (ConfigurationDataBasicLoginWithRSSAndDisplay)configData;
set => configData = value;
}
public BJShare(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps)
: base(name: "BJ-Share",
: base("BJ-Share",
description: "A brazilian tracker.",
link: "https://bj-share.me/",
link: "https://bj-share.info/",
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
configService: configService,
client: wc,
@@ -76,8 +84,8 @@ namespace Jackett.Common.Indexers
var pairs = new Dictionary<string, string>
{
{ "username", configData.Username.Value },
{ "password", configData.Password.Value },
{ "username", ConfigData.Username.Value },
{ "password", ConfigData.Password.Value },
{ "keeplogged", "1" }
};
@@ -85,7 +93,7 @@ namespace Jackett.Common.Indexers
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
{
var errorMessage = result.Content;
throw new ExceptionWithConfigData(errorMessage, configData);
throw new ExceptionWithConfigData(errorMessage, ConfigData);
});
return IndexerConfigurationStatus.RequiresTesting;
}
@@ -94,13 +102,24 @@ namespace Jackett.Common.Indexers
{
// Search does not support searching with episode numbers so strip it if we have one
// Ww AND filter the result later to archive the proper result
if (isAnime)
{
return term.TrimEnd(digits);
}
var ret = Regex.Replace(term, @"[S|E]\d\d", string.Empty).Trim();
return ret.Replace("Agents of SHIELD", "Agents of S.H.I.E.L.D.");
return isAnime ? term.TrimEnd(_digits) : Regex.Replace(term, @"[S|E]\d\d", string.Empty).Trim();
}
private static string FixAbsoluteNumbering(string title)
{
// if result is One piece, convert title from SXXEXX to EXX
// One piece is the only anime that i'm aware that is in "absolute" numbering, the problem is that they include
// the season (wrong season) and episode as absolute, eg: One Piece - S08E836
// 836 is the latest episode in absolute numbering, that is correct, but S08 is not the current season...
// So for this show, i don't see a other way to make it work...
//
// All others animes that i tested is with correct season and episode set, so i can't remove the season from all
// or will break everything else
//
// In this indexer, it looks that it is added "automatically", so all current and new releases will be broken
// until they or the source from where they get that info fix it...
return title.Contains("One Piece") ? Regex.Replace(title, @"(Ep[\.]?[ ]?)|([S]\d\d[Ee])", "E") : title;
}
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
@@ -113,51 +132,53 @@ namespace Jackett.Common.Indexers
var results = await RequestStringWithCookies(TodayUrl);
try
{
string RowsSelector = "table.torrent_table > tbody > tr:not(tr.colhead)";
const string rowsSelector = "table.torrent_table > tbody > tr:not(tr.colhead)";
var SearchResultParser = new HtmlParser();
var SearchResultDocument = SearchResultParser.Parse(results.Content);
var Rows = SearchResultDocument.QuerySelectorAll(RowsSelector);
foreach (var Row in Rows)
var searchResultParser = new HtmlParser();
var searchResultDocument = searchResultParser.Parse(results.Content);
var rows = searchResultDocument.QuerySelectorAll(rowsSelector);
foreach (var row in rows)
{
try
{
var release = new ReleaseInfo();
var release = new ReleaseInfo
{
MinimumRatio = 1,
MinimumSeedTime = 0
};
release.MinimumRatio = 1;
release.MinimumSeedTime = 0;
var qDetailsLink = Row.QuerySelector("a.BJinfoBox");
var qTitle = qDetailsLink.QuerySelector("font");
release.Title = qTitle.TextContent;
var qDetailsLink = row.QuerySelector("a.BJinfoBox");
var qBJinfoBox = qDetailsLink.QuerySelector("span");
var qCatLink = Row.QuerySelector("a[href^=\"/torrents.php?filter_cat\"]");
var qDLLink = Row.QuerySelector("a[href^=\"torrents.php?action=download\"]");
var qSeeders = Row.QuerySelector("td:nth-child(4)");
var qLeechers = Row.QuerySelector("td:nth-child(5)");
var qQuality = Row.QuerySelector("font[color=\"red\"]");
var qFreeLeech = Row.QuerySelector("font[color=\"green\"]:contains(Free)");
var qCatLink = row.QuerySelector("a[href^=\"/torrents.php?filter_cat\"]");
var qDlLink = row.QuerySelector("a[href^=\"torrents.php?action=download\"]");
var qSeeders = row.QuerySelector("td:nth-child(4)");
var qLeechers = row.QuerySelector("td:nth-child(5)");
var qQuality = row.QuerySelector("font[color=\"red\"]");
var qFreeLeech = row.QuerySelector("font[color=\"green\"]:contains(Free)");
var qTitle = qDetailsLink.QuerySelector("font");
// Get international title if available, or use the full title if not
release.Title = Regex.Replace(qTitle.TextContent, @".* \[(.*?)\](.*)", "$1$2");
release.Description = "";
foreach (var Child in qBJinfoBox.ChildNodes)
foreach (var child in qBJinfoBox.ChildNodes)
{
var type = Child.NodeType;
var type = child.NodeType;
if (type != NodeType.Text)
continue;
var line = Child.TextContent;
var line = child.TextContent;
if (line.StartsWith("Tamanho:"))
{
string Size = line.Substring("Tamanho: ".Length); ;
release.Size = ReleaseInfo.GetBytes(Size);
var size = line.Substring("Tamanho: ".Length); ;
release.Size = ReleaseInfo.GetBytes(size);
}
else if (line.StartsWith("Lançado em: "))
{
string PublishDateStr = line.Substring("Lançado em: ".Length).Replace("às ", "");
PublishDateStr += " +0";
var PublishDate = DateTime.SpecifyKind(DateTime.ParseExact(PublishDateStr, "dd/MM/yyyy HH:mm z", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
release.PublishDate = PublishDate.ToLocalTime();
var publishDateStr = line.Substring("Lançado em: ".Length).Replace("às ", "");
publishDateStr += " +0";
var publishDate = DateTime.SpecifyKind(DateTime.ParseExact(publishDateStr, "dd/MM/yyyy HH:mm z", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
release.PublishDate = publishDate.ToLocalTime();
}
else
{
@@ -166,39 +187,36 @@ namespace Jackett.Common.Indexers
}
var catStr = qCatLink.GetAttribute("href").Split('=')[1];
// if result is an anime, convert title from SXXEXX to EXX
if (catStr == "14")
release.Title = FixAbsoluteNumbering(release.Title);
var quality = qQuality.TextContent;
switch (quality)
{
release.Title = Regex.Replace(release.Title, @"(Ep[\.]?[ ]?)|([S]\d\d[Ee])", "E");
case "Full HD":
release.Title += " 1080p";
break;
case "HD":
release.Title += " 720p";
break;
default:
release.Title += " 480p";
break;
}
var Quality = qQuality.TextContent;
if (Quality == "Full HD")
release.Title += " 1080p";
else if(Quality == "HD")
release.Title += " 720p";
release.Category = MapTrackerCatToNewznab(catStr);
release.Link = new Uri(SiteLink + qDLLink.GetAttribute("href"));
release.Link = new Uri(SiteLink + qDlLink.GetAttribute("href"));
release.Comments = new Uri(SiteLink + qDetailsLink.GetAttribute("href"));
release.Guid = release.Link;
release.Seeders = ParseUtil.CoerceInt(qSeeders.TextContent);
release.Peers = ParseUtil.CoerceInt(qLeechers.TextContent) + release.Seeders;
if (qFreeLeech != null)
release.DownloadVolumeFactor = 0;
else
release.DownloadVolumeFactor = 1;
release.DownloadVolumeFactor = qFreeLeech != null ? 0 : 1;
release.UploadVolumeFactor = 1;
releases.Add(release);
}
catch (Exception ex)
{
logger.Error(string.Format("{0}: Error while parsing row '{1}': {2}", ID, Row.OuterHtml, ex.Message));
logger.Error($"{ID}: Error while parsing row '{row.OuterHtml}': {ex.Message}");
}
}
}
@@ -211,10 +229,13 @@ namespace Jackett.Common.Indexers
{
var searchUrl = BrowseUrl;
var isSearchAnime = query.Categories.Any(s => s == TorznabCatType.TVAnime.ID);
query.SearchTerm = query.SearchTerm.Replace("Agents of SHIELD", "Agents of S.H.I.E.L.D.");
var searchString = query.GetQueryString();
foreach (var searchTerm in _commonSearchTerms)
{
query.SearchTerm = query.SearchTerm.ToLower().Replace(searchTerm.Key.ToLower(), searchTerm.Value);
}
var searchString = query.GetQueryString();
var queryCollection = new NameValueCollection
{
{"searchstr", StripSearchString(searchString, isSearchAnime)},
@@ -235,132 +256,134 @@ namespace Jackett.Common.Indexers
var results = await RequestStringWithCookies(searchUrl);
try
{
string RowsSelector = "table.torrent_table > tbody > tr:not(tr.colhead)";
const string rowsSelector = "table.torrent_table > tbody > tr:not(tr.colhead)";
var SearchResultParser = new HtmlParser();
var SearchResultDocument = SearchResultParser.Parse(results.Content);
var Rows = SearchResultDocument.QuerySelectorAll(RowsSelector);
var searchResultParser = new HtmlParser();
var searchResultDocument = searchResultParser.Parse(results.Content);
var rows = searchResultDocument.QuerySelectorAll(rowsSelector);
ICollection<int> GroupCategory = null;
string GroupTitle = null;
string GroupYearStr = null;
Nullable<DateTime> GroupPublishDate = null;
ICollection<int> groupCategory = null;
string groupTitle = null;
string groupYearStr = null;
var categoryStr = "";
foreach (var Row in Rows)
foreach (var row in rows)
{
try
{
var qDetailsLink = Row.QuerySelector("a[href^=\"torrents.php?id=\"]");
string Title = qDetailsLink.TextContent;
ICollection<int> Category = null;
string YearStr = null;
Nullable<DateTime> YearPublishDate = null;
string CategoryStr = "";
var qDetailsLink = row.QuerySelector("a[href^=\"torrents.php?id=\"]");
var title = qDetailsLink.TextContent;
ICollection<int> category = null;
string yearStr = null;
if (Row.ClassList.Contains("group") || Row.ClassList.Contains("torrent")) // group/ungrouped headers
if (row.ClassList.Contains("group") || row.ClassList.Contains("torrent")) // group/ungrouped headers
{
var qCatLink = Row.QuerySelector("a[href^=\"/torrents.php?filter_cat\"]");
CategoryStr = qCatLink.GetAttribute("href").Split('=')[1].Split('&')[0];
Category = MapTrackerCatToNewznab(CategoryStr);
var qCatLink = row.QuerySelector("a[href^=\"/torrents.php?filter_cat\"]");
categoryStr = qCatLink.GetAttribute("href").Split('=')[1].Split('&')[0];
category = MapTrackerCatToNewznab(categoryStr);
YearStr = qDetailsLink.NextSibling.TextContent.Trim().TrimStart('[').TrimEnd(']');
YearPublishDate = DateTime.SpecifyKind(DateTime.ParseExact(YearStr, "yyyy", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
yearStr = qDetailsLink.NextSibling.TextContent.Trim().TrimStart('[').TrimEnd(']');
// if result is an anime, convert title from SXXEXX to EXX
if (CategoryStr == "14")
{
Title = Regex.Replace(Title, @"(Ep[\.]?[ ]?)|([S]\d\d[Ee])", "E");
}
title = FixAbsoluteNumbering(title);
if (Row.ClassList.Contains("group")) // group headers
if (row.ClassList.Contains("group")) // group headers
{
GroupCategory = Category;
GroupTitle = Title;
GroupYearStr = YearStr;
GroupPublishDate = YearPublishDate;
groupCategory = category;
groupTitle = title;
groupYearStr = yearStr;
continue;
}
}
var release = new ReleaseInfo();
release.MinimumRatio = 1;
release.MinimumSeedTime = 0;
var qDLLink = Row.QuerySelector("a[href^=\"torrents.php?action=download\"]");
var qSize = Row.QuerySelector("td:nth-last-child(4)");
var qGrabs = Row.QuerySelector("td:nth-last-child(3)");
var qSeeders = Row.QuerySelector("td:nth-last-child(2)");
var qLeechers = Row.QuerySelector("td:nth-last-child(1)");
var qFreeLeech = Row.QuerySelector("strong[title=\"Free\"]");
if (Row.ClassList.Contains("group_torrent")) // torrents belonging to a group
var release = new ReleaseInfo
{
release.Description = qDetailsLink.TextContent;
MinimumRatio = 1,
MinimumSeedTime = 0
};
string cleanTitle = Regex.Replace(GroupTitle, @" - S?(?<season>\d{1,2})?E?(?<episode>\d{1,4})?", "");
string seasonEp = Regex.Replace(GroupTitle, @"^(.*?) - (S?(\d{1,2})?E?(\d{1,4})?)?", "$2");
release.Title = CategoryStr == "14" ? GroupTitle : cleanTitle + " " + GroupYearStr + " " + seasonEp;
var qDlLink = row.QuerySelector("a[href^=\"torrents.php?action=download\"]");
var qSize = row.QuerySelector("td:nth-last-child(4)");
var qGrabs = row.QuerySelector("td:nth-last-child(3)");
var qSeeders = row.QuerySelector("td:nth-last-child(2)");
var qLeechers = row.QuerySelector("td:nth-last-child(1)");
var qFreeLeech = row.QuerySelector("strong[title=\"Free\"]");
release.PublishDate = GroupPublishDate.Value;
release.Category = GroupCategory;
if (row.ClassList.Contains("group_torrent")) // torrents belonging to a group
{
var description = Regex.Replace(qDetailsLink.TextContent.Trim(), @"\s+", " ");
description = Regex.Replace(description, @"((S\d{2})(E\d{2,4})?) (.*)", "$4");
release.Description = description;
var cleanTitle = Regex.Replace(groupTitle, @" - ((S(\d{2}))?E(\d{1,4}))", "");
title = Regex.Replace(title.Trim(), @"\s+", " ");
var seasonEp = Regex.Replace(title, @"((S\d{2})?(E\d{2,4})?) .*", "$1");
// do not include year to animes
if (categoryStr == "14")
{
release.Title = cleanTitle + " " + seasonEp;
}
else
{
release.Title = cleanTitle + " " + groupYearStr + " " + seasonEp;
}
release.Category = groupCategory;
}
else if (Row.ClassList.Contains("torrent")) // standalone/un grouped torrents
else if (row.ClassList.Contains("torrent")) // standalone/un grouped torrents
{
var qDescription = Row.QuerySelector("div.torrent_info");
var qDescription = row.QuerySelector("div.torrent_info");
release.Description = qDescription.TextContent;
string cleanTitle = Regex.Replace(Title, @" - ((S(\d{1,2}))?E(\d{1,4}))", "");
string seasonEp = Regex.Replace(Title, @"^(.*?) - ((S(\d{1,2}))?E(\d{1,4}))", "$2");
release.Title = CategoryStr == "14" ? Title : cleanTitle + " " + YearStr + " " + seasonEp;
var cleanTitle = Regex.Replace(title, @" - ((S\d{2})?(E\d{2,4})?)", "");
var seasonEp = Regex.Replace(title, @"^(.*?) - ((S\d{2})?(E\d{2,4})?)", "$2");
release.PublishDate = YearPublishDate.Value;
release.Category = Category;
// do not include year to animes
if (categoryStr == "14")
{
release.Title = cleanTitle + " " + seasonEp;
}
else
{
release.Title = cleanTitle + " " + yearStr + " " + seasonEp;
}
release.Category = category;
}
release.Description = release.Description.Replace(" / Free", ""); // Remove Free Tag
release.Description = release.Description.Replace("Full HD", "1080p");
release.Description = release.Description.Replace("/ HD / ", "/ 720p /");
release.Description = release.Description.Replace(" / HD]", " / 720p]");
release.Description = release.Description.Replace("4K", "2160p");
int nBarra = release.Title.IndexOf("[");
if (nBarra != -1)
{
release.Title = release.Title.Substring(nBarra + 1);
release.Title = release.Title.Replace("]", "");
}
// Get international title if available, or use the full title if not
release.Title = Regex.Replace(release.Title, @".* \[(.*?)\](.*)", "$1$2");
release.Title += " " + release.Description; // add year and Description to the release Title to add some meaning to it
// This tracker does not provide an publish date to search terms (only on last 24h page)
release.PublishDate = DateTime.Today;
// check for previously stripped search terms
if (!query.MatchQueryStringAND(release.Title))
continue;
var Size = qSize.TextContent;
release.Size = ReleaseInfo.GetBytes(Size);
release.Link = new Uri(SiteLink + qDLLink.GetAttribute("href"));
var size = qSize.TextContent;
release.Size = ReleaseInfo.GetBytes(size);
release.Link = new Uri(SiteLink + qDlLink.GetAttribute("href"));
release.Comments = new Uri(SiteLink + qDetailsLink.GetAttribute("href"));
release.Guid = release.Link;
release.Grabs = ParseUtil.CoerceLong(qGrabs.TextContent);
release.Seeders = ParseUtil.CoerceInt(qSeeders.TextContent);
release.Peers = ParseUtil.CoerceInt(qLeechers.TextContent) + release.Seeders;
if (qFreeLeech != null)
release.DownloadVolumeFactor = 0;
else
release.DownloadVolumeFactor = 1;
release.DownloadVolumeFactor = qFreeLeech != null ? 0 : 1;
release.UploadVolumeFactor = 1;
releases.Add(release);
}
catch (Exception ex)
{
logger.Error(string.Format("{0}: Error while parsing row '{1}': {2}", ID, Row.OuterHtml, ex.Message));
logger.Error($"{ID}: Error while parsing row '{row.OuterHtml}': {ex.Message}");
}
}
}

View File

@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using AutoMapper;
@@ -32,6 +34,9 @@ namespace Jackett.Common.Indexers
public string Type { get; protected set; }
public virtual string ID { get { return GetIndexerID(GetType()); } }
[JsonConverter(typeof(EncodingJsonConverter))]
public Encoding Encoding { get; protected set; }
public virtual bool IsConfigured { get; protected set; }
protected Logger logger;
protected IIndexerConfigurationService configurationService;
@@ -154,8 +159,11 @@ namespace Jackett.Common.Indexers
{
if (jsonConfig is JArray)
{
LoadValuesFromJson(jsonConfig, true);
IsConfigured = true;
if (!MigratedFromDPAPI(jsonConfig))
{
LoadValuesFromJson(jsonConfig, true);
IsConfigured = true;
}
}
// read and upgrade old settings file format
else if (jsonConfig is Object)
@@ -166,6 +174,81 @@ namespace Jackett.Common.Indexers
}
}
//TODO: Remove this section once users have moved off DPAPI
private bool MigratedFromDPAPI(JToken jsonConfig)
{
if (EnvironmentUtil.IsRunningLegacyOwin)
{
//Still running legacy Owin and using the DPAPI, we don't want to migrate
logger.Debug(ID + " - Running Owin, no need to migrate from DPAPI");
return false;
}
Version dotNetVersion = Microsoft.Extensions.PlatformAbstractions.PlatformServices.Default.Application.RuntimeFramework.Version;
bool isWindows = Environment.OSVersion.Platform == PlatformID.Win32NT;
if (!isWindows && dotNetVersion.Major < 4)
{
// User isn't running Windows, but is running on .NET Core framework, no access to the DPAPI, so don't bother trying to migrate
return false;
}
LoadValuesFromJson(jsonConfig, false);
object passwordPropertyValue = null;
string passwordValue = "";
try
{
passwordPropertyValue = configData.GetType().GetProperty("Password").GetValue(configData, null);
passwordValue = passwordPropertyValue.GetType().GetProperty("Value").GetValue(passwordPropertyValue, null).ToString();
}
catch (Exception)
{
logger.Debug($"Unable to source password for [{ID}] while attempting migration, likely a public tracker");
return false;
}
if (!string.IsNullOrEmpty(passwordValue))
{
try
{
protectionService.UnProtect(passwordValue);
//Password successfully unprotected using Microsoft.AspNetCore.DataProtection, no further action needed as we've already converted the password previously
return false;
}
catch (Exception ex)
{
if (ex.Message != "The provided payload cannot be decrypted because it was not protected with this protection provider.")
{
logger.Info($"Password could not be unprotected using Microsoft.AspNetCore.DataProtection - {ID} : " + ex);
}
logger.Info($"Attempting legacy Unprotect - {ID} : ");
try
{
string unprotectedPassword = protectionService.LegacyUnProtect(passwordValue);
//Password successfully unprotected using Windows/Mono DPAPI
passwordPropertyValue.GetType().GetProperty("Value").SetValue(passwordPropertyValue, unprotectedPassword);
SaveConfig();
IsConfigured = true;
logger.Info($"Password successfully migrated for {ID}");
return true;
}
catch (Exception exception)
{
logger.Info($"Password could not be unprotected using legacy DPAPI - {ID} : " + exception);
}
}
}
return false;
}
protected async Task ConfigureIfOK(string cookies, bool isLoggedin, Func<Task> onError)
{
if (isLoggedin)
@@ -755,8 +838,6 @@ namespace Jackett.Common.Indexers
public override TorznabCapabilities TorznabCaps { get; protected set; }
[JsonConverter(typeof(EncodingJsonConverter))]
public Encoding Encoding { get; protected set; }
private List<CategoryMapping> categoryMapping = new List<CategoryMapping>();
protected WebClient webclient;

View File

@@ -17,7 +17,7 @@ namespace Jackett.Common.Indexers
{
public class BitCityReloaded : BaseWebIndexer
{
private string LoginUrl { get { return SiteLink + "login.php"; } }
private string LoginUrl { get { return SiteLink + "login/index.php"; } }
private string BrowseUrl { get { return SiteLink + "uebersicht.php"; } }
private TimeZoneInfo germanyTz = TimeZoneInfo.CreateCustomTimeZone("W. Europe Standard Time", new TimeSpan(1, 0, 0), "W. Europe Standard Time", "W. Europe Standard Time");

View File

@@ -197,6 +197,7 @@ namespace Jackett.Common.Indexers
{
Dictionary<string, object> variables = new Dictionary<string, object>();
variables[".Config.sitelink"] = SiteLink;
foreach (settingsField Setting in Definition.Settings)
{
string value;

View File

@@ -40,7 +40,7 @@ namespace Jackett.Common.Indexers
{
Encoding = Encoding.UTF8;
Language = "en-us";
Type = "private";
Type = "public";
AddCategoryMapping(5, TorznabCatType.PC0day, "Applications");
AddCategoryMapping(17, TorznabCatType.AudioAudiobook, "Audio Books");
@@ -135,6 +135,11 @@ namespace Jackett.Common.Indexers
var episodeSearchUrl = string.Format(SearchUrl, cat, WebUtility.UrlEncode(query.GetQueryString()));
var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
if (results.IsRedirect)
{
throw new ExceptionWithConfigData("Unexpected redirect to " + results.RedirectingTo + ". Check your credentials.", configData);
}
if (results.Content.Contains("No torrents found"))
{
return releases;
@@ -199,17 +204,15 @@ namespace Jackett.Common.Indexers
release.Comments = new Uri(new Uri(SiteLink), qLink.Attr("href"));
release.Guid = release.Comments;
release.Link = release.Comments; // indirect download see Download() method
var qDownload = rowB.ChildElements.ElementAt(2).ChildElements.ElementAt(0).Cq();
release.Link = new Uri(qDownload.Attr("href"));
var sizeStr = rowB.ChildElements.ElementAt(3).Cq().Text();
var sizeStr = rowB.ChildElements.ElementAt(2).Cq().Text();
release.Size = ReleaseInfo.GetBytes(sizeStr);
release.Seeders = ParseUtil.CoerceInt(rowB.ChildElements.ElementAt(6).Cq().Text());
release.Seeders = ParseUtil.CoerceInt(rowB.ChildElements.ElementAt(5).Cq().Text());
release.Peers = ParseUtil.CoerceInt(rowB.ChildElements.ElementAt(6).Cq().Text()) + release.Seeders;
var grabs = rowB.Cq().Find("td:nth-child(6)").Text();
var grabs = rowB.Cq().Find("td:nth-child(5)").Text();
release.Grabs = ParseUtil.CoerceInt(grabs);
release.DownloadVolumeFactor = 0; // ratioless
@@ -224,5 +227,19 @@ namespace Jackett.Common.Indexers
}
return releases;
}
public override async Task<byte[]> Download(Uri link)
{
var results = await RequestStringWithCookies(link.AbsoluteUri);
//await FollowIfRedirect(results); // manual follow for better debugging (string)
if (results.IsRedirect)
results = await RequestStringWithCookies(results.RedirectingTo);
CQ dom = results.Content;
var dl = dom.Find("a:has(font:contains(\"Download torrent file\"))");
link = new Uri(dl.Attr("href"));
return await base.Download(link);
}
}
}

View File

@@ -6,6 +6,7 @@ using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using AngleSharp.Parser.Html;
using Jackett.Common.Models.IndexerConfig.Bespoke;
using Jackett.Common.Models;
using Jackett.Common.Models.IndexerConfig;
using Jackett.Common.Services.Interfaces;
@@ -22,10 +23,11 @@ namespace Jackett.Common.Indexers
{ get { return SiteLink + "takelogin.php"; } }
private string BrowseUrl
{ get { return SiteLink + "browse.php"; } }
private bool TorrentHTTPSMode => configData.TorrentHTTPSMode.Value;
private new ConfigurationDataBasicLogin configData
private new ConfigurationDataEliteTracker configData
{
get { return (ConfigurationDataBasicLogin)base.configData; }
get { return (ConfigurationDataEliteTracker)base.configData; }
set { base.configData = value; }
}
@@ -37,10 +39,10 @@ namespace Jackett.Common.Indexers
logger: logger,
p: protectionService,
client: webClient,
configData: new ConfigurationDataBasicLogin()
configData: new ConfigurationDataEliteTracker()
)
{
Encoding = Encoding.UTF8;
Encoding = Encoding.UTF8;
Language = "fr-fr";
Type = "private";
@@ -206,6 +208,13 @@ Encoding = Encoding.UTF8;
release.Peers = ParseUtil.CoerceInt(Leechers.TextContent) + release.Seeders;
release.Grabs = ParseUtil.CoerceLong(Grabs.TextContent);
if (TorrentHTTPSMode)
{
var linkHttps = Row.QuerySelector("td:nth-child(4)").QuerySelector("a").GetAttribute("href");
var idTorrent = ParseUtil.GetArgumentFromQueryString(linkHttps, "id");
release.Link = new Uri($"{SiteLink}download.php?id={idTorrent}&type=ssl");
}
if (added.QuerySelector("img[alt^=\"TORRENT GRATUIT\"]") != null)
release.DownloadVolumeFactor = 0;
else if (added.QuerySelector("img[alt^=\"TORRENT SILVER\"]") != null)

View File

@@ -219,6 +219,11 @@ namespace Jackett.Common.Indexers
searchUrl += "?" + queryCollection.GetQueryString();
var results = await RequestStringWithCookies(searchUrl);
if (results.IsRedirect && results.RedirectingTo.EndsWith("login.php"))
{
throw new Exception("relogin needed, please update your cookie");
}
try
{
string RowsSelector = ".torrent_table > tbody > tr";

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Jackett.Common.Models;
using Jackett.Common.Models.IndexerConfig;
@@ -30,6 +31,7 @@ namespace Jackett.Common.Indexers
string Language { get; }
string LastError { get; set; }
string ID { get; }
Encoding Encoding { get; }
TorznabCapabilities TorznabCaps { get; }

View File

@@ -117,12 +117,17 @@ namespace Jackett.Common.Indexers
return IndexerConfigurationStatus.RequiresTesting;
}
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
protected async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query, String seasonep)
{
var releases = new List<ReleaseInfo>();
var searchString = query.GetQueryString();
var pairs = new List<KeyValuePair<string, string>>();
if (seasonep != null)
{
searchString = query.SanitizedSearchTerm;
}
pairs.Add(new KeyValuePair<string, string>("nyit_sorozat_resz", "true"));
pairs.Add(new KeyValuePair<string, string>("miben", "name"));
pairs.Add(new KeyValuePair<string, string>("tipus", "kivalasztottak_kozott"));
@@ -198,8 +203,46 @@ namespace Jackett.Common.Indexers
string catlink = qRow.Find("a:has(img[class='categ_link'])").First().Attr("href");
string cat = ParseUtil.GetArgumentFromQueryString(catlink, "tipus");
release.Category = MapTrackerCatToNewznab(cat);
if (seasonep == null)
releases.Add(release);
else
{
if (query.MatchQueryStringAND(release.Title, null, seasonep))
{
/* For sonnar if the search querry was english the title must be english also so we need to change the Description and Title */
var temp = release.Title;
// releasedata everithing after Name.S0Xe0X
String releasedata =release.Title.Split(new[] { seasonep }, StringSplitOptions.None)[1].Trim();
/* if the release name not contains the language we add it because it is know from category */
if (cat.Contains("hun") && !releasedata.Contains("hun"))
releasedata += ".hun";
// release description contains [imdb: ****] but we only need the data before it for title
String[] description = {release.Description, ""};
if (release.Description.Contains("[imdb:"))
{
description = release.Description.Split('[');
description[1] = "[" + description[1];
}
else
release.Title = (description[0].Trim() + "." + seasonep.Trim() + "." + releasedata.Trim('.')).Replace(' ', '.');
// if search is done for S0X than we dont want to put . between S0X and E0X
Match match = Regex.Match(releasedata, @"^E\d\d?");
if (seasonep.Length==3 && match.Success)
release.Title = (description[0].Trim() + "." + seasonep.Trim() + releasedata.Trim('.')).Replace(' ', '.');
// add back imdb points to the description [imdb: 8.7]
release.Description = temp+" "+ description[1];
release.Description = release.Description.Trim();
releases.Add(release);
}
}
releases.Add(release);
}
}
catch (Exception ex)
@@ -209,5 +252,16 @@ namespace Jackett.Common.Indexers
return releases;
}
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var results = await PerformQuery(query, null);
if (results.Count()==0 && query.IsTVSearch) // if we search for a localized title ncore can't handle any extra S/E information, search without it and AND filter the results. See #1450
{
results = await PerformQuery(query,query.GetEpisodeSearchString());
}
return results;
}
}
}

View File

@@ -116,7 +116,7 @@ namespace Jackett.Common.Indexers
//AddCategoryMapping("cat_id", TorznabCatType.AudioForeign);
AddCategoryMapping("21", TorznabCatType.PC);
AddCategoryMapping("22", TorznabCatType.PC0day);
AddCategoryMapping("4", TorznabCatType.PCISO);
AddCategoryMapping("1", TorznabCatType.PCISO);
AddCategoryMapping("2", TorznabCatType.PCMac);
//AddCategoryMapping("cat_id", TorznabCatType.PCPhoneOther);
//Games/PC-ISO, Games/PC-Rips
@@ -155,7 +155,7 @@ namespace Jackett.Common.Indexers
// RSS Textual categories
AddCategoryMapping("Anime", TorznabCatType.TVAnime);
AddCategoryMapping("Appz/Misc", TorznabCatType.PC0day);
AddCategoryMapping("Appz/PC-ISO", TorznabCatType.Books);
AddCategoryMapping("Appz/PC-ISO", TorznabCatType.PCISO);
AddCategoryMapping("E-Book", TorznabCatType.BooksEbook);
AddCategoryMapping("Games/PC-ISO", TorznabCatType.PCGames);
AddCategoryMapping("Games/PC-Rips", TorznabCatType.PCGames);
@@ -265,6 +265,10 @@ namespace Jackett.Common.Indexers
imdbID = l;
}
}
var Now = DateTime.Now;
var PublishDate = DateTime.ParseExact(date, "ddd, dd MMM yyyy HH:mm:ss zz00", CultureInfo.InvariantCulture);
var PublishDateLocal = PublishDate.ToLocalTime();
var diff = Now - PublishDateLocal;
var release = new ReleaseInfo()
{
@@ -273,7 +277,7 @@ namespace Jackett.Common.Indexers
Guid = new Uri(string.Format(DetailsURL, torrentId)),
Comments = new Uri(string.Format(DetailsURL, torrentId)),
//PublishDate = DateTime.ParseExact(infoMatch.Groups["added"].Value, "yyyy-MM-dd H:mm:ss", CultureInfo.InvariantCulture), //2015-08-08 21:20:31 TODO: correct timezone (always -4)
PublishDate = DateTime.ParseExact(date, "ddd, dd MMM yyyy HH:mm:ss zz00", CultureInfo.InvariantCulture).ToLocalTime(),
PublishDate = PublishDateLocal,
Link = new Uri(link),
Seeders = ParseUtil.CoerceInt(infoMatch.Groups["seeders"].Value == "no" ? "0" : infoMatch.Groups["seeders"].Value),
Peers = ParseUtil.CoerceInt(infoMatch.Groups["leechers"].Value == "no" ? "0" : infoMatch.Groups["leechers"].Value),
@@ -345,6 +349,12 @@ namespace Jackett.Common.Indexers
release.Seeders = ParseUtil.CoerceInt(qRow.Find("td:nth-child(9)").Text());
release.Peers = release.Seeders + ParseUtil.CoerceInt(qRow.Find("td:nth-child(10)").Text());
var grabsStr = qRow.Find("td:nth-child(8)").Text();
release.Grabs = ParseUtil.GetLongFromString(grabsStr);
var filesStr = qRow.Find("td:nth-child(7) > a").Text();
release.Files = ParseUtil.GetLongFromString(filesStr);
var category = qRow.Find(".br_type > a").Attr("href").Replace("browse.php?cat=", string.Empty);
release.Category = MapTrackerCatToNewznab(category);
}
@@ -360,4 +370,4 @@ namespace Jackett.Common.Indexers
return releases;
}
}
}
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
@@ -19,7 +20,7 @@ namespace Jackett.Common.Indexers
{
private string StartPageUrl { get { return SiteLink + "login.php"; } }
private string LoginUrl { get { return SiteLink + "takelogin.php"; } }
private string SearchUrl { get { return SiteLink + "browse_API.php"; } }
private string SearchUrl { get { return SiteLink + "browse.php"; } }
private string DownloadUrl { get { return SiteLink + "download.php/{0}/download.torrent"; } }
private new ConfigurationDataRecaptchaLogin configData
@@ -53,25 +54,27 @@ namespace Jackett.Common.Indexers
AddCategoryMapping(59, TorznabCatType.MoviesHD, "Movies/HD");
AddCategoryMapping(61, TorznabCatType.Movies, "Movies/Classic");
AddCategoryMapping(64, TorznabCatType.Movies3D, "Movies/3D");
AddCategoryMapping(78, TorznabCatType.XXX, "0day/XxX");
AddCategoryMapping(80, TorznabCatType.MoviesForeign, "Movies/Non-English");
AddCategoryMapping(81, TorznabCatType.MoviesBluRay, "Movies/BluRay");
AddCategoryMapping(82, TorznabCatType.MoviesOther, "Movies/CAM-TS");
AddCategoryMapping(102, TorznabCatType.MoviesOther, "Movies/Remux");
AddCategoryMapping(103, TorznabCatType.MoviesWEBDL, "Movies/Web-Rip");
AddCategoryMapping(105, TorznabCatType.Movies, "Movies/Kids");
AddCategoryMapping(16, TorznabCatType.MoviesUHD, "Movies/4K");
AddCategoryMapping(17, TorznabCatType.MoviesBluRay, "Movies/4K bluray");
//TV
AddCategoryMapping(2, TorznabCatType.TVSD, "TV/XviD");
AddCategoryMapping(43, TorznabCatType.TV, "TV/Packs");
AddCategoryMapping(9, TorznabCatType.TVHD, "TV-HD");
AddCategoryMapping(19, TorznabCatType.TVHD, "TV-HD HEVC/x265");
AddCategoryMapping(63, TorznabCatType.TV, "TV/Classic");
AddCategoryMapping(77, TorznabCatType.TVSD, "TV/SD");
AddCategoryMapping(79, TorznabCatType.TVSport, "Sports");
AddCategoryMapping(100, TorznabCatType.TVFOREIGN, "TV/Non-English");
AddCategoryMapping(83, TorznabCatType.TVWEBDL, "TV/Web-Rip");
AddCategoryMapping(8, TorznabCatType.TVOTHER, "TV-Mobile");
AddCategoryMapping(18, TorznabCatType.TVAnime, "TV/Anime");
AddCategoryMapping(19, TorznabCatType.TVHD, "TV-x265");
// Games
AddCategoryMapping(6, TorznabCatType.PCGames, "Games/PC ISO");
@@ -165,7 +168,7 @@ namespace Jackett.Common.Indexers
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
Dictionary<string, string> qParams = new Dictionary<string, string>();
var qParams = new NameValueCollection();
qParams.Add("cata", "yes");
qParams.Add("sec", "jax");
@@ -180,7 +183,9 @@ namespace Jackett.Common.Indexers
qParams.Add("search", query.GetQueryString());
}
var results = await PostDataWithCookiesAndRetry(SearchUrl, qParams);
var searchUrl = SearchUrl + "?" + qParams.GetQueryString();
var results = await RequestStringWithCookies(searchUrl);
List<ReleaseInfo> releases = ParseResponse(query, results.Content);
return releases;

View File

@@ -1,36 +0,0 @@
using System.Collections.Generic;
using Jackett.Common.Indexers.Abstract;
using Jackett.Common.Models;
using Jackett.Common.Services.Interfaces;
using Jackett.Common.Utils.Clients;
using NLog;
namespace Jackett.Common.Indexers
{
public class Synthesiz3r : GazelleTracker
{
public Synthesiz3r(IIndexerConfigurationService configService, WebClient webClient, Logger logger, IProtectionService protectionService)
: base(name: "Synthesiz3r",
desc: "Synthesiz3r (ST3) is a Private Torrent Tracker for ELECTRONIC MUSIC",
link: "https://synthesiz3r.com/",
configService: configService,
logger: logger,
protectionService: protectionService,
webClient: webClient,
supportsFreeleechTokens: true
)
{
Language = "en-us";
Type = "private";
TorznabCaps.SupportedMusicSearchParamsList = new List<string>() { "q", "album", "artist", "label", "year" };
AddCategoryMapping(1, TorznabCatType.Audio, "Music");
AddCategoryMapping(2, TorznabCatType.PC, "Applications");
AddCategoryMapping(3, TorznabCatType.Books, "E-Books");
AddCategoryMapping(4, TorznabCatType.AudioAudiobook, "Audiobooks");
AddCategoryMapping(5, TorznabCatType.Movies, "E-Learning Videos");
AddCategoryMapping(6, TorznabCatType.TV, "Comedy");
AddCategoryMapping(7, TorznabCatType.Books, "Comics");
}
}
}

View File

@@ -12,6 +12,7 @@ using Jackett.Common.Models.IndexerConfig;
using Jackett.Common.Services.Interfaces;
using Jackett.Common.Utils;
using Jackett.Common.Utils.Clients;
using static Jackett.Common.Utils.ParseUtil;
using Newtonsoft.Json.Linq;
using NLog;
@@ -195,6 +196,7 @@ namespace Jackett.Common.Indexers
if (query.IsTest || string.IsNullOrWhiteSpace(searchString))
{
var rssPage = await RequestStringWithCookiesAndRetry(string.Format(RSSUrl, configData.RSSKey.Value));
rssPage.Content = RemoveInvalidXmlChars(rssPage.Content);
var rssDoc = XDocument.Parse(rssPage.Content);
foreach (var item in rssDoc.Descendants("item"))

View File

@@ -90,7 +90,7 @@ namespace Jackett.Common.Indexers
var loginPage = await RequestStringWithCookies(SiteLink, string.Empty);
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, SiteLink, SiteLink);
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("my.php"), () =>
{
CQ dom = result.Content;
var messageEl = dom["td.embedded"].First();
@@ -156,7 +156,14 @@ namespace Jackett.Common.Indexers
var link = row.Cq().Find("td:eq(1) a:eq(1)").First();
release.Guid = new Uri(SiteLink + link.Attr("href"));
release.Comments = release.Guid;
release.Title = link.Get(0).FirstChild.ToString();
release.Title = link.Attr("title");
// There isn't a title attribute if the release name isn't truncated.
if (string.IsNullOrWhiteSpace(release.Title))
{
release.Title = link.Get(0).FirstChild.ToString();
}
release.Description = release.Title;
// If we search an get no results, we still get a table just with no info.

View File

@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net452</TargetFrameworks>
@@ -114,16 +114,17 @@
<ItemGroup>
<PackageReference Include="AngleSharp" Version="0.9.9.2" />
<PackageReference Include="Autofac" Version="4.6.2" />
<PackageReference Include="Autofac" Version="4.8.1" />
<PackageReference Include="AutoMapper" Version="6.2.2" />
<PackageReference Include="BencodeNET" Version="2.2.24" />
<PackageReference Include="CloudFlareUtilities" Version="1.2.0" />
<PackageReference Include="CommandLineParser" Version="2.2.1" />
<PackageReference Include="DotNet4.SocksProxy" Version="1.4.0.1" />
<PackageReference Include="Microsoft.CSharp" Version="4.4.1" />
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
<PackageReference Include="Microsoft.Extensions.PlatformAbstractions" Version="1.1.0" />
<PackageReference Include="MimeMapping" Version="1.0.1.12" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.1" />
<PackageReference Include="NLog" Version="4.5.0-rc07" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="NLog" Version="4.5.6" />
<PackageReference Include="YamlDotNet" Version="4.3.2-pre0473" />
</ItemGroup>

View File

@@ -1,4 +1,5 @@
using CommandLine;
using Jackett.Common.Utils;
using System;
namespace Jackett.Common.Models.Config
@@ -83,7 +84,16 @@ namespace Jackett.Common.Models.Config
if (options.ListenPublic && options.ListenPrivate)
{
Console.WriteLine("You can only use listen private OR listen publicly.");
Engine.Exit(1);
//TODO: Remove once off Owin
if (EnvironmentUtil.IsRunningLegacyOwin)
{
Engine.Exit(1);
}
else
{
Environment.Exit(1);
}
}
// SSL Fix

View File

@@ -0,0 +1,13 @@
namespace Jackett.Common.Models.IndexerConfig.Bespoke
{
class ConfigurationDataEliteTracker : ConfigurationDataBasicLogin
{
public BoolItem TorrentHTTPSMode { get; private set; }
public ConfigurationDataEliteTracker()
: base()
{
TorrentHTTPSMode = new BoolItem { Name = "Use https for tracker URL (Experimental)", Value = false };
}
}
}

View File

@@ -83,7 +83,11 @@ namespace Jackett.Common.Plumbing
private void RegisterWebClient<WebClientType>(ContainerBuilder builder)
{
Engine.WebClientType = typeof(WebClientType);
//TODO: Remove once off Owin
if (EnvironmentUtil.IsRunningLegacyOwin)
{
Engine.WebClientType = typeof(WebClientType);
}
builder.RegisterType<WebClientType>().As<WebClient>();
}

View File

@@ -4,5 +4,7 @@
{
string Protect(string plainText);
string UnProtect(string plainText);
string LegacyProtect(string plainText);
string LegacyUnProtect(string plainText);
}
}

View File

@@ -12,8 +12,10 @@ using System.Threading.Tasks;
using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.Tar;
using ICSharpCode.SharpZipLib.Zip;
using Jackett.Common.Models.Config;
using Jackett.Common.Models.GitHub;
using Jackett.Common.Services.Interfaces;
using Jackett.Common.Utils;
using Jackett.Common.Utils.Clients;
using Newtonsoft.Json;
using NLog;
@@ -28,14 +30,16 @@ namespace Jackett.Common.Services
IConfigurationService configService;
ManualResetEvent locker = new ManualResetEvent(false);
ITrayLockService lockService;
private ServerConfig serverConfig;
bool forceupdatecheck = false;
public UpdateService(Logger l, WebClient c, IConfigurationService cfg, ITrayLockService ls)
public UpdateService(Logger l, WebClient c, IConfigurationService cfg, ITrayLockService ls, ServerConfig sc)
{
logger = l;
client = c;
configService = cfg;
lockService = ls;
serverConfig = sc;
}
private string ExePath()
@@ -74,13 +78,12 @@ namespace Jackett.Common.Services
private async Task CheckForUpdates()
{
var config = Engine.ServerConfig;
if (config.RuntimeSettings.NoUpdates)
if (serverConfig.RuntimeSettings.NoUpdates)
{
logger.Info($"Updates are disabled via --NoUpdates.");
return;
}
if (config.UpdateDisabled && !forceupdatecheck)
if (serverConfig.UpdateDisabled && !forceupdatecheck)
{
logger.Info($"Skipping update check as it is disabled.");
return;
@@ -112,7 +115,7 @@ namespace Jackett.Common.Services
var releases = JsonConvert.DeserializeObject<List<Release>>(response.Content);
if (!config.UpdatePrerelease)
if (!serverConfig.UpdatePrerelease)
{
releases = releases.Where(r => !r.Prerelease).ToList();
}
@@ -132,7 +135,7 @@ namespace Jackett.Common.Services
var installDir = Path.GetDirectoryName(ExePath());
var updaterPath = Path.Combine(tempDir, "Jackett", "JackettUpdater.exe");
if (updaterPath != null)
StartUpdate(updaterPath, installDir, isWindows, config.RuntimeSettings.NoRestart);
StartUpdate(updaterPath, installDir, isWindows, serverConfig.RuntimeSettings.NoRestart);
}
catch (Exception e)
{
@@ -304,7 +307,15 @@ namespace Jackett.Common.Services
{
logger.Info("Exiting Jackett..");
lockService.Signal();
Engine.Exit(0);
//TODO: Remove once off Owin
if (EnvironmentUtil.IsRunningLegacyOwin)
{
Engine.Exit(0);
}
else
{
Environment.Exit(0);
}
}
}
}

View File

@@ -13,6 +13,7 @@ using CloudFlareUtilities;
using Jackett.Common.Models.Config;
using Jackett.Common.Services.Interfaces;
using NLog;
using Jackett.Common.Helpers;
namespace Jackett.Common.Utils.Clients
{
@@ -257,7 +258,10 @@ namespace Jackett.Common.Utils.Clients
// See issue #1200
if (result.RedirectingTo != null && result.RedirectingTo.StartsWith("file://"))
{
var newRedirectingTo = result.RedirectingTo.Replace("file://", request.RequestUri.Scheme + "://" + request.RequestUri.Host);
// URL decoding apparently is needed to, without it e.g. Demonoid download is broken
// TODO: is it always needed (not just for relative redirects)?
var newRedirectingTo = WebUtilityHelpers.UrlDecode(result.RedirectingTo, webRequest.Encoding);
newRedirectingTo = newRedirectingTo.Replace("file://", request.RequestUri.Scheme + "://" + request.RequestUri.Host);
logger.Debug("[MONO relative redirect bug] Rewriting relative redirect URL from " + result.RedirectingTo + " to " + newRedirectingTo);
result.RedirectingTo = newRedirectingTo;
}

View File

@@ -13,6 +13,7 @@ using CloudFlareUtilities;
using Jackett.Common.Models.Config;
using Jackett.Common.Services.Interfaces;
using NLog;
using Jackett.Common.Helpers;
namespace Jackett.Common.Utils.Clients
{
@@ -277,7 +278,10 @@ namespace Jackett.Common.Utils.Clients
// See issue #1200
if (result.RedirectingTo != null && result.RedirectingTo.StartsWith("file://"))
{
var newRedirectingTo = result.RedirectingTo.Replace("file://", request.RequestUri.Scheme + "://" + request.RequestUri.Host);
// URL decoding apparently is needed to, without it e.g. Demonoid download is broken
// TODO: is it always needed (not just for relative redirects)?
var newRedirectingTo = WebUtilityHelpers.UrlDecode(result.RedirectingTo, webRequest.Encoding);
newRedirectingTo = newRedirectingTo.Replace("file://", request.RequestUri.Scheme + "://" + request.RequestUri.Host);
logger.Debug("[MONO relative redirect bug] Rewriting relative redirect URL from " + result.RedirectingTo + " to " + newRedirectingTo);
result.RedirectingTo = newRedirectingTo;
}

View File

@@ -1,4 +1,6 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
namespace Jackett.Common.Utils
@@ -22,6 +24,33 @@ namespace Jackett.Common.Utils
}
}
public static bool IsRunningLegacyOwin
{
get
{
bool runningOwin;
try
{
var currentAssembly = Assembly.GetExecutingAssembly();
bool aspNetCorePresent = new StackTrace().GetFrames()
.Select(x => x.GetMethod().ReflectedType.Assembly).Distinct()
.Where(x => x.GetReferencedAssemblies().Any(y => y.FullName == currentAssembly.FullName))
.Where(x => x.ManifestModule.Name == "JackettConsole.exe").Select(x => x.CustomAttributes)
.FirstOrDefault()
.Where(x => x.AttributeType.Assembly.FullName.StartsWith("Microsoft.AspNetCore", StringComparison.OrdinalIgnoreCase))
.Any();
runningOwin = !aspNetCorePresent;
}
catch
{
runningOwin = true;
}
return runningOwin;
}
}
}
}

View File

@@ -118,4 +118,4 @@ namespace Jackett.Common.Utils
return "tt" + ((int)imdbid).ToString("D7");
}
}
}
}

View File

@@ -15,7 +15,7 @@
<EmbeddedResource Include="Util\Invalid-RSS.xml" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="4.6.2" />
<PackageReference Include="Autofac" Version="4.8.1" />
<PackageReference Include="FluentAssertions" Version="5.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.6.0" />
<PackageReference Include="MSTest.TestAdapter" Version="1.2.0" />

View File

@@ -206,6 +206,7 @@ namespace Jackett.Updater
"Definitions/rockhardlossless.yml",
"Definitions/oxtorrent.yml",
"Definitions/tehconnection.yml",
"Definitions/torrentwtf.yml",
};
foreach (var oldFIle in oldFiles)

View File

@@ -71,9 +71,19 @@ namespace Jackett.Controllers
}
// This will fix torrents where the keys are not sorted, and thereby not supported by Sonarr.
var parser = new BencodeParser();
var torrentDictionary = parser.Parse(downloadBytes);
byte[] sortedDownloadBytes = torrentDictionary.EncodeAsBytes();
byte[] sortedDownloadBytes = null;
try
{
var parser = new BencodeParser();
var torrentDictionary = parser.Parse(downloadBytes);
sortedDownloadBytes = torrentDictionary.EncodeAsBytes();
}
catch (Exception e)
{
var content = indexer.Encoding.GetString(downloadBytes);
logger.Error(content);
throw new Exception("BencodeParser failed", e);
}
var result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new ByteArrayContent(sortedDownloadBytes);

View File

@@ -467,8 +467,13 @@ namespace Jackett.Controllers
var link = result.Link;
var file = StringUtil.MakeValidFileName(result.Title, '_', false);
result.Link = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "dl", file);
if (result.Link != null && result.Link.Scheme != "magnet" && !string.IsNullOrWhiteSpace(Engine.ServerConfig.BlackholeDir))
result.BlackholeLink = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "bh", file);
if (!string.IsNullOrWhiteSpace(Engine.ServerConfig.BlackholeDir))
{
if (result.Link != null)
result.BlackholeLink = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "bh", file);
else if (result.MagnetUri != null)
result.BlackholeLink = serverService.ConvertToProxyLink(result.MagnetUri, serverUrl, result.TrackerId, "bh", file);
}
}
}

View File

@@ -57,6 +57,16 @@ namespace Jackett.Services
}
}
public string LegacyProtect(string plainText)
{
return Protect(plainText);
}
public string LegacyUnProtect(string plainText)
{
return UnProtect(plainText);
}
private string ProtectDefaultMethod(string plainText)
{
if (string.IsNullOrEmpty(plainText))

View File

@@ -61,7 +61,7 @@ namespace Jackett.Services
public Uri ConvertToProxyLink(Uri link, string serverUrl, string indexerId, string action = "dl", string file = "t")
{
if (link == null || (link.IsAbsoluteUri && link.Scheme == "magnet"))
if (link == null || (link.IsAbsoluteUri && link.Scheme == "magnet" && action != "bh")) // no need to convert a magnet link to a proxy link unless it's a blackhole link
return link;
var encryptedLink = _protectionService.Protect(link.ToString());
@@ -153,6 +153,13 @@ namespace Jackett.Services
logger.Error(notice);
}
if (monoVersionO.Major < 5 || (monoVersionO.Major == 5 && monoVersionO.Minor < 8))
{
string notice = "A minimum Mono version of 5.8 is required. Please update to the latest version from http://www.mono-project.com/download/";
_notices.Add(notice);
logger.Error(notice);
}
try
{
// Check for mono-devel