mirror of
https://github.com/Jackett/Jackett.git
synced 2025-09-15 00:14:10 +02:00
Compare commits
84 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3538fdfaf7 | ||
![]() |
3468e7d404 | ||
![]() |
ec4afda184 | ||
![]() |
67b1835264 | ||
![]() |
aee64aa589 | ||
![]() |
687e6e237f | ||
![]() |
b48dd5e930 | ||
![]() |
5ee6833610 | ||
![]() |
c998ba3762 | ||
![]() |
2d4f7ab0e9 | ||
![]() |
676d03eb88 | ||
![]() |
6f7ecbfb7b | ||
![]() |
c4aa49eb32 | ||
![]() |
32aae44ffc | ||
![]() |
7883534c5e | ||
![]() |
b58c9fb718 | ||
![]() |
99d8f63f9e | ||
![]() |
635e8240d2 | ||
![]() |
117a670aa3 | ||
![]() |
f49c58a1fa | ||
![]() |
2492f1b797 | ||
![]() |
d6781f67b2 | ||
![]() |
2e0c22eb6d | ||
![]() |
f7bf4060ea | ||
![]() |
8c953bbf01 | ||
![]() |
4e91761fdf | ||
![]() |
53f8465e67 | ||
![]() |
e8bc2816ef | ||
![]() |
28ed7cc8a5 | ||
![]() |
089d9f2e3d | ||
![]() |
b4eda2ed54 | ||
![]() |
4d8d21a815 | ||
![]() |
f3290800d8 | ||
![]() |
22a858c076 | ||
![]() |
823419c032 | ||
![]() |
908d3f64f4 | ||
![]() |
4b599f391c | ||
![]() |
6d8239caab | ||
![]() |
dae37f273a | ||
![]() |
1615bff2d0 | ||
![]() |
b303befbb9 | ||
![]() |
e243c11cc0 | ||
![]() |
c860bca320 | ||
![]() |
a60c1fca36 | ||
![]() |
5ad2c7a371 | ||
![]() |
3df0218347 | ||
![]() |
601783aef6 | ||
![]() |
ac5af81344 | ||
![]() |
823563c84f | ||
![]() |
47410c5eb6 | ||
![]() |
af135f4ae9 | ||
![]() |
3eeced3a04 | ||
![]() |
8ea99b548d | ||
![]() |
ae73e8188d | ||
![]() |
9c5cda72da | ||
![]() |
fb1e24799d | ||
![]() |
5721948434 | ||
![]() |
d7b6f413be | ||
![]() |
959ec4667d | ||
![]() |
20433db169 | ||
![]() |
54465798e9 | ||
![]() |
313147d224 | ||
![]() |
84bd947eca | ||
![]() |
366abc4431 | ||
![]() |
2f7fa2f063 | ||
![]() |
205f6cac12 | ||
![]() |
f602b3db24 | ||
![]() |
0d72f1f228 | ||
![]() |
508125e68f | ||
![]() |
cfb714e13c | ||
![]() |
b9dcfd1b02 | ||
![]() |
a1b2dc67b8 | ||
![]() |
2207c5a961 | ||
![]() |
2caa09bb1e | ||
![]() |
68906f6e40 | ||
![]() |
2cf3cf15e3 | ||
![]() |
88202c1f7f | ||
![]() |
6293c787e7 | ||
![]() |
f67fda3bf4 | ||
![]() |
c81dd24fe7 | ||
![]() |
af94dd2757 | ||
![]() |
0a07738c5b | ||
![]() |
e05783a25a | ||
![]() |
27d4ab3967 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -200,3 +200,4 @@ FakesAssemblies/
|
||||
/TestResults
|
||||
*.DS_Store
|
||||
.idea/
|
||||
launchSettings.json
|
||||
|
20
README.md
20
README.md
@@ -2,7 +2,6 @@
|
||||
|
||||
[](https://github.com/Jackett/Jackett/issues)
|
||||
[](https://github.com/Jackett/Jackett/pulls)
|
||||
[](https://www.bountysource.com/teams/jackett)
|
||||
[](https://ci.appveyor.com/project/Jackett/jackett)
|
||||
[](https://github.com/Jackett/Jackett/releases/latest)
|
||||
[](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
|
||||
|
||||

|
||||
|
||||
[inviteneeded]: https://raw.githubusercontent.com/Jackett/Jackett/master/.github/label-inviteneeded.png
|
||||
[inviteneeded]: https://raw.githubusercontent.com/Jackett/Jackett/master/.github/label-inviteneeded.png
|
||||
|
@@ -27,6 +27,7 @@ deploy:
|
||||
description: $(release_description)
|
||||
auth_token:
|
||||
secure: hOg+16YTIbq4kO9u4D1YVOTbWDqgCX6mAQYMbnmBBSw2CiUsZh7OKbupoUb3FtWa
|
||||
artifact: /^(?:(?![Ee]xperimental).)*$/
|
||||
draft: true
|
||||
on:
|
||||
branch: master
|
||||
|
@@ -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">
|
||||
|
@@ -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"
|
||||
|
@@ -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:
|
||||
|
@@ -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/
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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"
|
||||
|
225
src/Jackett.Common/Definitions/girotorrent.yml
Normal file
225
src/Jackett.Common/Definitions/girotorrent.yml
Normal 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", ""]
|
@@ -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}}"
|
||||
|
@@ -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}}"
|
||||
|
@@ -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"
|
||||
|
142
src/Jackett.Common/Definitions/hdspain.yml
Normal file
142
src/Jackett.Common/Definitions/hdspain.yml
Normal 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"]
|
@@ -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
|
||||
|
160
src/Jackett.Common/Definitions/ilcorsaroblu.yml
Normal file
160
src/Jackett.Common/Definitions/ilcorsaroblu.yml
Normal 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)
|
@@ -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"
|
||||
|
@@ -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"
|
||||
|
@@ -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:
|
||||
|
@@ -6,6 +6,8 @@
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://racing4everyone.eu/
|
||||
legacylinks:
|
||||
- https://racing4everyone.jp/
|
||||
|
||||
caps:
|
||||
|
@@ -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"
|
||||
|
@@ -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"}
|
||||
|
@@ -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
|
||||
|
111
src/Jackett.Common/Definitions/torrent-turk.yml
Normal file
111
src/Jackett.Common/Definitions/torrent-turk.yml
Normal 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
|
@@ -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/
|
||||
|
@@ -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]
|
||||
|
@@ -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
|
||||
|
@@ -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"
|
@@ -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
|
||||
|
@@ -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"
|
||||
|
@@ -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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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");
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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)
|
||||
|
@@ -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";
|
||||
|
@@ -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; }
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
@@ -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"))
|
||||
|
@@ -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.
|
||||
|
@@ -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>
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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 };
|
||||
}
|
||||
}
|
||||
}
|
@@ -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>();
|
||||
}
|
||||
|
||||
|
@@ -4,5 +4,7 @@
|
||||
{
|
||||
string Protect(string plainText);
|
||||
string UnProtect(string plainText);
|
||||
string LegacyProtect(string plainText);
|
||||
string LegacyUnProtect(string plainText);
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -118,4 +118,4 @@ namespace Jackett.Common.Utils
|
||||
return "tt" + ((int)imdbid).ToString("D7");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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" />
|
||||
|
@@ -206,6 +206,7 @@ namespace Jackett.Updater
|
||||
"Definitions/rockhardlossless.yml",
|
||||
"Definitions/oxtorrent.yml",
|
||||
"Definitions/tehconnection.yml",
|
||||
"Definitions/torrentwtf.yml",
|
||||
};
|
||||
|
||||
foreach (var oldFIle in oldFiles)
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -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))
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user