mirror of
https://github.com/Jackett/Jackett.git
synced 2025-12-25 15:15:09 +01:00
Compare commits
158 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7107bf37d | ||
|
|
c545a49755 | ||
|
|
19ec3e2aff | ||
|
|
4846ea000a | ||
|
|
a29d63e6dc | ||
|
|
bd177cbf26 | ||
|
|
93d5acd355 | ||
|
|
7cc19212f5 | ||
|
|
ba36c9bdff | ||
|
|
734fc31d8e | ||
|
|
6c6d55eb63 | ||
|
|
17cabb2921 | ||
|
|
b0250deee1 | ||
|
|
de8adf382b | ||
|
|
c31b9d84f0 | ||
|
|
2bdf899927 | ||
|
|
2101ebb2de | ||
|
|
a92e0bef37 | ||
|
|
090ee7b093 | ||
|
|
4cd184ae72 | ||
|
|
642f990862 | ||
|
|
829347cba2 | ||
|
|
ca39b85cc2 | ||
|
|
7a57e2d302 | ||
|
|
49de2b0a93 | ||
|
|
a2bd2615c1 | ||
|
|
71d368689c | ||
|
|
e1515b468c | ||
|
|
398f0993f4 | ||
|
|
c846eb4330 | ||
|
|
cae6d4ed73 | ||
|
|
b286dc1c7f | ||
|
|
61a69472c5 | ||
|
|
a04fc6f123 | ||
|
|
86964e1cc6 | ||
|
|
2d7c30dbde | ||
|
|
5b6d1ccc7b | ||
|
|
b9b826c34c | ||
|
|
b33018563b | ||
|
|
033070d9a9 | ||
|
|
8d67d1bf37 | ||
|
|
f9143d14e5 | ||
|
|
a601a25652 | ||
|
|
6451525eb1 | ||
|
|
acd1902734 | ||
|
|
9d68ca86da | ||
|
|
5b9165cd2f | ||
|
|
8a48874b42 | ||
|
|
b0132da030 | ||
|
|
175d7f5379 | ||
|
|
dc8023afe1 | ||
|
|
d956872d95 | ||
|
|
35defc04e0 | ||
|
|
a2f5e5a5aa | ||
|
|
ec5a8e6e33 | ||
|
|
f00aa5faca | ||
|
|
51ece1726c | ||
|
|
579190b4bd | ||
|
|
fd4d8d490a | ||
|
|
e2fe43b3a7 | ||
|
|
bedde1a3db | ||
|
|
da638ad712 | ||
|
|
10ae5e9d5d | ||
|
|
71749ba8db | ||
|
|
4373c38869 | ||
|
|
2a17783a9c | ||
|
|
a184ad4d7c | ||
|
|
acc1e7e65a | ||
|
|
95ffd0caa3 | ||
|
|
b0e788788f | ||
|
|
80f0c1b7da | ||
|
|
7abdd0d817 | ||
|
|
736330bea3 | ||
|
|
accd06d291 | ||
|
|
fed8294ae0 | ||
|
|
1093355e77 | ||
|
|
aae73741e8 | ||
|
|
17002a6ede | ||
|
|
4f96f437ad | ||
|
|
335ea77e9e | ||
|
|
41a4dc2922 | ||
|
|
ee1d7a7625 | ||
|
|
e9aa0edc37 | ||
|
|
e64d7ea947 | ||
|
|
8eb0415aaf | ||
|
|
ef20198a4f | ||
|
|
6c6d379002 | ||
|
|
7c2a343629 | ||
|
|
ea2e88d6bb | ||
|
|
abaf909ef1 | ||
|
|
74054523c5 | ||
|
|
37daacf9fa | ||
|
|
b58dc51f8d | ||
|
|
6c661a4974 | ||
|
|
7a49ddda3a | ||
|
|
5e4cb3581d | ||
|
|
968c2ca3a6 | ||
|
|
af4fb5c6a0 | ||
|
|
fc7d5a0e35 | ||
|
|
2a7c693917 | ||
|
|
838ad77d7f | ||
|
|
3978ba6c04 | ||
|
|
60554c25d9 | ||
|
|
bd03c903d0 | ||
|
|
113e5d658c | ||
|
|
f9b4b5a76c | ||
|
|
2f378210d9 | ||
|
|
e5de468899 | ||
|
|
204d96bcec | ||
|
|
9e37b1429a | ||
|
|
6b61e22f95 | ||
|
|
c3dffe42be | ||
|
|
796947fd6f | ||
|
|
77b1da3089 | ||
|
|
f3c6acf634 | ||
|
|
ab810a20db | ||
|
|
60f1be6f18 | ||
|
|
ab6f7d5218 | ||
|
|
67f50e88a3 | ||
|
|
79a354c6d9 | ||
|
|
ee20b141da | ||
|
|
0c67c6322a | ||
|
|
99ed3fbc2c | ||
|
|
ef92bf5342 | ||
|
|
053d2be3f3 | ||
|
|
c155bf8c8c | ||
|
|
e1232800c6 | ||
|
|
7a2c0bf260 | ||
|
|
203b5d1e37 | ||
|
|
1325fc6391 | ||
|
|
1c3bc3cbf4 | ||
|
|
8509276972 | ||
|
|
e7710489ca | ||
|
|
f6a669ea46 | ||
|
|
68ad01e346 | ||
|
|
ffda2c8269 | ||
|
|
896b2ab954 | ||
|
|
bbcec8103d | ||
|
|
8f0ba9cefe | ||
|
|
cc3ebbe1ae | ||
|
|
d88db81207 | ||
|
|
9a15f1d1a3 | ||
|
|
4e5f091b6c | ||
|
|
517f196d73 | ||
|
|
9461d2470a | ||
|
|
c9f874dc93 | ||
|
|
53b6285810 | ||
|
|
5d4e0c41d6 | ||
|
|
754337b58f | ||
|
|
16f79085ad | ||
|
|
005539d30d | ||
|
|
2d5a90ae31 | ||
|
|
fc060d6468 | ||
|
|
d0937d3561 | ||
|
|
7b8de5e28d | ||
|
|
790f5ddfad | ||
|
|
760231be43 | ||
|
|
837e74a743 |
6
.github/ISSUE_TEMPLATE.md
vendored
6
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,7 +1,11 @@
|
||||
**Please use the search bar** at the top of the page and make sure you are not creating an already submitted issue. Duplicating issues makes it more difficult for everyone to follow. Your issue may have already been solved in the past as well.
|
||||
|
||||
Provide a description of the feature request or bug, the more details the better.
|
||||
If you are experiencing an issue with a tracker, a **full enhanced log must be included**. Instructions for obtaining logs are here: https://github.com/Jackett/Jackett#troubleshooting
|
||||
|
||||
If you are experiencing an issue with a tracker, then:
|
||||
1. Use your browser to check you can access the site directly, and if a login is required, check you can login and that you do not have any outstanding account issues.
|
||||
2. If you haven't already, try upgrading to the latest version of Jackett, your issue may have already been resolved.
|
||||
3. If it is still not working for you, then a **full enhanced log must be included**. Instructions for obtaining logs are here: https://github.com/Jackett/Jackett#troubleshooting
|
||||
|
||||
**Jackett version**:
|
||||
**Mono version** (if not using Windows):
|
||||
|
||||
17
README.md
17
README.md
@@ -24,21 +24,24 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* Anidex
|
||||
* Anime Tosho
|
||||
* AniRena
|
||||
* AudioBookBay
|
||||
* BTstor.net
|
||||
* btbit
|
||||
* BTDB
|
||||
* BT-Scene
|
||||
* cpasbien
|
||||
* ETTV
|
||||
* EliteTorrent.biz
|
||||
* ExtraTorrent.ag
|
||||
* ExtraTorrentClone
|
||||
* EZTV
|
||||
* Frozen Layer
|
||||
* GkTorrent
|
||||
* Horrible Subs
|
||||
* Idope
|
||||
* IdopeClone
|
||||
* Il Corsaro Nero <!-- maintained by bonny1992 -->
|
||||
* Il Corsaro Blu
|
||||
* Isohunt2
|
||||
* KATcrs
|
||||
* KickAssTorrent
|
||||
* KickAssTorrent (thekat.se clone)
|
||||
* LimeTorrents
|
||||
@@ -48,18 +51,21 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* Nyaa.si
|
||||
* Nyaa-Pantsu
|
||||
* Nyoo
|
||||
* ProStyleX
|
||||
* RARBG
|
||||
* RuTor
|
||||
* ShowRSS
|
||||
* SkyTorrentsClone
|
||||
* sukebei.Nyaa.si
|
||||
* sukebei-Pantsu
|
||||
* The Pirate Bay
|
||||
* TNTVillage <!-- maintained by bonny1992 -->
|
||||
* Tokyo Toshokan
|
||||
* Torlock
|
||||
* TorrentCouch
|
||||
* Torrent Downloads
|
||||
* TorrentGalaxy.org
|
||||
* Torrent9
|
||||
* TorrentKim
|
||||
* Torrentz2
|
||||
* World Wide Torrents
|
||||
* YTS.ag
|
||||
@@ -80,6 +86,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* Newstudio
|
||||
* NetHD
|
||||
* NoName Club
|
||||
* RockBox
|
||||
* RuTracker
|
||||
* SkTorrent
|
||||
* Union Fansub
|
||||
@@ -146,6 +153,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* Downloadville
|
||||
* Dragonworld Reloaded
|
||||
* Dream Team
|
||||
* DXDHD
|
||||
* EliteHD [![(invite needed)][inviteneeded]](#)
|
||||
* Elit Tracker
|
||||
* Elite-Tracker
|
||||
@@ -171,6 +179,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* Greek Team
|
||||
* HacheDe
|
||||
* Hardbay
|
||||
* HD4Free (HD4)
|
||||
* HD-Forever
|
||||
* HD-Only
|
||||
* HD-Space
|
||||
@@ -229,10 +238,12 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
|
||||
* Racing4Everyone (R4E)
|
||||
* Redacted (PassTheHeadphones)
|
||||
* Red Star Torrent
|
||||
* Redtopia (RED)
|
||||
* RetroFlix
|
||||
* RevolutionTT
|
||||
* RGU
|
||||
* RoDVD
|
||||
* Romanian Metal Torrent
|
||||
* SceneFZ
|
||||
* SceneReactor
|
||||
* SceneTime
|
||||
|
||||
@@ -731,7 +731,7 @@ function updateReleasesRow(row)
|
||||
labels.empty();
|
||||
|
||||
if (IMDBId) {
|
||||
labels.append('\n<a href="http://www.imdb.com/title/tt' + IMDBId + '/" class="label label-imdb" alt="IMDB" title="IMDB">IMDB</a>');
|
||||
labels.append('\n<a href="http://www.imdb.com/title/tt' + ("000000" + IMDBId).slice(-7) + '/" class="label label-imdb" alt="IMDB" title="IMDB">IMDB</a>');
|
||||
}
|
||||
|
||||
if (!isNaN(DownloadVolumeFactor)) {
|
||||
|
||||
@@ -663,6 +663,6 @@
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="../libs/api.js?changed=2017083001"></script>
|
||||
<script type="text/javascript" src="../custom.js?changed=20180710"></script>
|
||||
<script type="text/javascript" src="../custom.js?changed=20180711"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://www.2f4y.me/
|
||||
legacylinks:
|
||||
- http://www.2f4y.me/
|
||||
|
||||
caps:
|
||||
|
||||
@@ -135,22 +135,22 @@
|
||||
selector: a[href^="/download.php"]
|
||||
attribute: href
|
||||
files:
|
||||
selector: td:nth-child(7)
|
||||
selector: td:nth-child(5)
|
||||
grabs:
|
||||
selector: td:nth-child(6)
|
||||
selector: td:nth-child(4)
|
||||
size:
|
||||
selector: td:nth-child(8)
|
||||
selector: td:nth-child(6)
|
||||
filters:
|
||||
- name: replace
|
||||
args: [".", ""]
|
||||
- name: replace
|
||||
args: [",", "."]
|
||||
seeders:
|
||||
selector: td:nth-child(3) > a
|
||||
selector: td:nth-child(2) > a
|
||||
leechers:
|
||||
selector: td:nth-child(4)
|
||||
selector: td:nth-child(3)
|
||||
date:
|
||||
selector: td:nth-child(9)
|
||||
selector: td:nth-child(10)
|
||||
filters:
|
||||
- name: split
|
||||
args: ["by", 0]
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://www.arabafenice.me/
|
||||
legacylinks:
|
||||
- http://www.arabafenice.me/
|
||||
|
||||
caps:
|
||||
@@ -99,6 +101,13 @@
|
||||
search:
|
||||
paths:
|
||||
- path: index.php
|
||||
keywordsfilters:
|
||||
- name: diacritics
|
||||
args: replace
|
||||
- name: re_replace # S01 to 1
|
||||
args: ["(?i)\\bS0*(\\d+)\\b", "$1"]
|
||||
- name: re_replace # S01E01 to 1 1
|
||||
args: ["(?i)\\bS0*(\\d+)E0*(\\d+)\\b", "$1 $2"]
|
||||
inputs:
|
||||
search: "{{if .Query.IMDBID}}{{ .Query.IMDBIDShort }}{{else}}{{ .Keywords }}{{end}}"
|
||||
page: "torrents"
|
||||
@@ -113,6 +122,21 @@
|
||||
attribute: href
|
||||
title:
|
||||
selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
|
||||
filters:
|
||||
- name: re_replace # S01 E01 to S01E01
|
||||
args: ["(?i)\\bS(\\d+)\\sE(\\d+)\\b", "S$1E$2"]
|
||||
- name: re_replace # 01x01 to S01E01
|
||||
args: ["(?i)(\\d{2})x(\\d+)", "S$1E$2"]
|
||||
- name: re_replace # 1x01 to S01E01
|
||||
args: ["(?i)\\b(\\d{1})x(\\d+)", "S0$1E$2"]
|
||||
- name: re_replace # Stagione X --> S0X
|
||||
args: ["(?i)\\bStagion[ei]\\s?(\\d{1})\\b|\\bSeason'?s?\\s?(\\d{1})\\b", "S0$1$2"]
|
||||
- name: re_replace # Stagione XX --> SXX
|
||||
args: ["(?i)\\bStagion[ei]\\s?(\\d{2,})\\b|\\bSeason'?s?\\s?(\\d{2,})\\b", "S$1$2"]
|
||||
- name: re_replace # Episodio 4 to E4
|
||||
args: ["(?i)\\b(?:[\\/\\|]?Episodio\\s?(\\d+)|Puntata\\s?(\\d+))", "E$1$2"]
|
||||
- name: re_replace # Episodi 4 5 to E04-05
|
||||
args: ["(?i)\\b(?:Puntate\\s*)(\\d+)\\s?(\\d+)", "E0$1-0$2"]
|
||||
banner:
|
||||
selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
|
||||
attribute: onmouseover
|
||||
|
||||
132
src/Jackett.Common/Definitions/audiobookbay.yml
Normal file
132
src/Jackett.Common/Definitions/audiobookbay.yml
Normal file
@@ -0,0 +1,132 @@
|
||||
---
|
||||
site: audiobookbay
|
||||
name: AudioBookBay
|
||||
description: "AudioBook Bay (ABB) is a semi-private Torrent Tracker for AUDIOBOOKS"
|
||||
language: en-us
|
||||
type: semi-private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://audiobookbay.nl/
|
||||
- https://audiobookbay.la/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: Children, cat: Audio/Audiobook, desc: "Children"}
|
||||
- {id: Teen, cat: Audio/Audiobook, desc: "Teen & Young Adult"}
|
||||
- {id: Adults, cat: Audio/Audiobook, desc: "Adults"}
|
||||
- {id: The, cat: Audio/Audiobook, desc: "The Undead"}
|
||||
- {id: Action, cat: Audio/Audiobook, desc: "Action"}
|
||||
- {id: Adventure, cat: Audio/Audiobook, desc: "Adventure"}
|
||||
- {id: Art, cat: Audio/Audiobook, desc: "Art"}
|
||||
- {id: Autobiography, cat: Audio/Audiobook, desc: "Autobiography & Biographies"}
|
||||
- {id: Business, cat: Audio/Audiobook, desc: "Business"}
|
||||
- {id: Computer, cat: Audio/Audiobook, desc: "Computer"}
|
||||
- {id: Contemporary, cat: Audio/Audiobook, desc: "Contemporary"}
|
||||
- {id: Crime, cat: Audio/Audiobook, desc: "Crime"}
|
||||
- {id: Detective, cat: Audio/Audiobook, desc: "Detective"}
|
||||
- {id: Doctor, cat: Audio/Audiobook, desc: "Doctor Who"}
|
||||
- {id: Education, cat: Audio/Audiobook, desc: "Education"}
|
||||
- {id: Fantasy, cat: Audio/Audiobook, desc: "Fantasy"}
|
||||
- {id: General, cat: Audio/Audiobook, desc: "General Fiction"}
|
||||
- {id: Historical, cat: Audio/Audiobook, desc: "Historical Fiction"}
|
||||
- {id: History, cat: Audio/Audiobook, desc: "History"}
|
||||
- {id: Horror, cat: Audio/Audiobook, desc: "Horror"}
|
||||
- {id: Humor, cat: Audio/Audiobook, desc: "Humor"}
|
||||
- {id: Lecture, cat: Audio/Audiobook, desc: "Lecture"}
|
||||
- {id: LGBT, cat: Audio/Audiobook, desc: "LGBT"}
|
||||
- {id: Literature, cat: Audio/Audiobook, desc: "Literature"}
|
||||
- {id: LitRPG, cat: Audio/Audiobook, desc: "LitRPG"}
|
||||
- {id: Misc., cat: Audio/Audiobook, desc: "Misc. Non-fiction"}
|
||||
- {id: Mystery, cat: Audio/Audiobook, desc: "Mystery"}
|
||||
- {id: Myth, cat: Audio/Audiobook, desc: "Myth Hunting"}
|
||||
- {id: Paranormal, cat: Audio/Audiobook, desc: "Paranormal"}
|
||||
- {id: Plays, cat: Audio/Audiobook, desc: "Plays & Theater"}
|
||||
- {id: Poetry, cat: Audio/Audiobook, desc: "Poetry"}
|
||||
- {id: Political, cat: Audio/Audiobook, desc: "Political"}
|
||||
- {id: Postapocalyptic, cat: Audio/Audiobook, desc: "Postapocalyptic"}
|
||||
- {id: Radio, cat: Audio/Audiobook, desc: "Radio Productions"}
|
||||
- {id: Romance, cat: Audio/Audiobook, desc: "Romance"}
|
||||
- {id: Sci-Fi, cat: Audio/Audiobook, desc: "Sci-Fi"}
|
||||
- {id: Science, cat: Audio/Audiobook, desc: "Science"}
|
||||
- {id: Self-help, cat: Audio/Audiobook, desc: "Self-help"}
|
||||
- {id: SHTF, cat: Audio/Audiobook, desc: "SHTF"}
|
||||
- {id: Spiritual, cat: Audio/Audiobook, desc: "Spiritual & Religious"}
|
||||
- {id: Sports, cat: Audio/Audiobook, desc: "Sports"}
|
||||
- {id: Suspense, cat: Audio/Audiobook, desc: "Suspense"}
|
||||
- {id: Thriller, cat: Audio/Audiobook, desc: "Thriller"}
|
||||
- {id: True, cat: Audio/Audiobook, desc: "True Crime"}
|
||||
- {id: Tutorial, cat: Audio/Audiobook, desc: "Tutorial"}
|
||||
- {id: Westerns, cat: Audio/Audiobook, desc: "Westerns"}
|
||||
- {id: Anthology, cat: Audio/Audiobook, desc: "Anthology"}
|
||||
- {id: Bestsellers, cat: Audio/Audiobook, desc: "Bestsellers"}
|
||||
- {id: Classic, cat: Audio/Audiobook, desc: "Classic"}
|
||||
- {id: Documentary, cat: Audio/Audiobook, desc: "Documentary"}
|
||||
- {id: Full, cat: Audio/Audiobook, desc: "Full Cast"}
|
||||
- {id: Libertarian, cat: Audio/Audiobook, desc: "Libertarian"}
|
||||
- {id: Military, cat: Audio/Audiobook, desc: "Military"}
|
||||
- {id: Novel, cat: Audio/Audiobook, desc: "Novel"}
|
||||
- {id: Short, cat: Audio/Audiobook, desc: "Short Story"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
|
||||
login:
|
||||
path: https://audiobookbay.nl/member/login.php
|
||||
form: form[action="https://audiobookbay.nl/member/login.php"]
|
||||
method: post
|
||||
form: form
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
login: "Login"
|
||||
error:
|
||||
- selector: td.embedded:has(h2:contains("Invalid"))
|
||||
test:
|
||||
path: /member/users/
|
||||
|
||||
download:
|
||||
selector: a[href^="/download?"]
|
||||
attribute: href
|
||||
|
||||
search:
|
||||
paths:
|
||||
# with just 7 results per page, try to grab up to 35 results
|
||||
# http://audiobookbay.nl/?s=teeth
|
||||
# http://audiobookbay.nl/page/2/?s=teeth
|
||||
- path: "{{if .Keywords}}/?s={{ .Keywords}}{{else}}/{{end}}"
|
||||
- path: "{{if .Keywords}}/page/2/?s={{ .Keywords}}{{else}}{{end}}"
|
||||
- path: "{{if .Keywords}}/page/3/?s={{ .Keywords}}{{else}}{{end}}"
|
||||
- path: "{{if .Keywords}}/page/4/?s={{ .Keywords}}{{else}}{{end}}"
|
||||
- path: "{{if .Keywords}}/page/5/?s={{ .Keywords}}{{else}}{{end}}"
|
||||
rows:
|
||||
selector: div.post:has(div[class="postTitle"])
|
||||
fields:
|
||||
title:
|
||||
selector: div.postTitle
|
||||
details:
|
||||
selector: div.postTitle h2 a
|
||||
attribute: href
|
||||
download:
|
||||
selector: a[href^="/audio-books/"]
|
||||
attribute: href
|
||||
banner:
|
||||
optional: true
|
||||
selector: img
|
||||
attribute: src
|
||||
category:
|
||||
selector: div.postInfo
|
||||
filters:
|
||||
- name: regexp
|
||||
args: "Category: (.+?)\\s"
|
||||
date:
|
||||
selector: div.postContent p:contains("Posted:")
|
||||
filters:
|
||||
- name: regexp
|
||||
args: "Posted: (.+?)Format:"
|
||||
- name: dateparse
|
||||
args: "2 Jan 2006"
|
||||
size:
|
||||
selector: div.postContent p:contains("File Size:")
|
||||
filters:
|
||||
- name: regexp
|
||||
args: "File Size: (.+?)s"
|
||||
@@ -1,4 +1,4 @@
|
||||
---
|
||||
---
|
||||
site: bigtower
|
||||
name: BigTower
|
||||
description: "Big Tower is an ITALIAN Private site for TV / MOVIES / GENERAL"
|
||||
@@ -108,6 +108,9 @@
|
||||
args: ["index.php?page=torrent-details&id=", "download.php?id="]
|
||||
title:
|
||||
selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
|
||||
filters:
|
||||
- name: re_replace # rimozioni varie
|
||||
args: ["(?i)(\\[Richiesta\\])", ""]
|
||||
banner:
|
||||
selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
|
||||
attribute: onmouseover
|
||||
|
||||
@@ -69,9 +69,18 @@
|
||||
filters:
|
||||
- name: andmatch
|
||||
fields:
|
||||
# download button can be disbled in the profile, use details link instead
|
||||
# download:
|
||||
# selector: a[href^="download.php/"]
|
||||
# attribute: href
|
||||
download:
|
||||
selector: a[href^="download.php/"]
|
||||
selector: a[href^="details.php?id="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["details.php?id=", "download.php/"]
|
||||
- name: append
|
||||
args: "/invalid.torrent"
|
||||
title:
|
||||
selector: a[href^="details.php?id="]
|
||||
title:
|
||||
|
||||
@@ -74,12 +74,37 @@
|
||||
args: ([\d\.]+)
|
||||
date:
|
||||
selector: time
|
||||
filters:
|
||||
# translations for Turkish|Estonian|Danish|Italian|Polish|Norwegian|Portoguese|Czech|Russian|Romanian|Spanish|French|German|Bulgarian|Dutch
|
||||
- name: re_replace
|
||||
args: ["(önce|tagasi|geleden|fa|temu|siden|atrás|nazpět|назад|acum|hace|il y a|vor|преди)", "ago"]
|
||||
- name: re_replace
|
||||
args: ["(dakika|minut|minuto|minuta|minutt|минута|Minute|minuut)", "minute"]
|
||||
- name: re_replace
|
||||
args: ["(dakika|minutit|minutter|minuti|minuty|minutos|минуты|минут|Minuten|минути|minuten)", "minutes"]
|
||||
- name: re_replace
|
||||
args: ["(saat|tund|time|ora|godzina|hora|hodina|час|oră|heure|Stunde|uur)", "hour"]
|
||||
- name: re_replace
|
||||
args: ["(saat|tundi|timer|ore|godziny|horas|hodiny|hoden|часа|часов|ore|heures|Stunden)", "hours"]
|
||||
- name: re_replace
|
||||
args: ["(gün|päev|dag|giorno|dzień|dia|den|день|zi|día|jour|Tag|ден)", "day"]
|
||||
- name: re_replace
|
||||
args: ["(gün|päeva|dage|giorni|dni|dias|dny|дня|дней|zile|días|jours|Tagen|дни|dagen)", "days"]
|
||||
- name: re_replace
|
||||
args: ["(hafta|nädal|uge|settimana|tydzień|uke|semana|týden|неделю|săptămână|semaine|Woche|седмица)", "week"]
|
||||
- name: re_replace
|
||||
args: ["(hafta|nädalat|uger|settimane|tygodnie|uker|semanas|týdny|недели|недель|săptămâni|semaines|Wochen|седмици|weken)", "weeks"]
|
||||
- name: re_replace
|
||||
args: ["(ay|kuu|måned|mese|miesiąc|mês|měsíc|месяц|lună|mes|mois|Monat|месец|maand)", "month"]
|
||||
- name: re_replace
|
||||
args: ["(ay|kuud|måneder|mesi|miesiące|meses|měsíce|месяца|месяцев|luni|meses|mois|Monaten|месеца|maanden)", "months"]
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"i[data-original-title=\"100% Free\"]": "0"
|
||||
"i[data-original-title=\"Global FreeLeech\"]": "0"
|
||||
"i[data-original-title=\"100% Free\"]": "0" # Single Torrent Freeleech
|
||||
"i[data-original-title=\"Global FreeLeech\"]": "0" # Global Freeleech
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"i[data-original-title=\"Double upload\"]": "2"
|
||||
"i[data-original-title=\"Double upload\"]": "2" # Single Torrent Double Upload
|
||||
"i[data-original-title=\"Double Upload\"]": "2" # Global Double Upload
|
||||
"*": "1"
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
---
|
||||
site: bt-scene
|
||||
name: BT-Scene
|
||||
description: "BT-Scene (BTS) is a Public site for MOVIES / TV / GENERAL"
|
||||
language: us-en
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://bt-scene.cc/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 1, cat: Movies, desc: "Movies"}
|
||||
- {id: 2, cat: TV, desc: "Series"}
|
||||
- {id: 3, cat: Audio, desc: "Music"}
|
||||
- {id: 4, cat: PC/Games, desc: "Games"}
|
||||
- {id: 5, cat: PC/0day, desc: "Software"}
|
||||
- {id: 6, cat: TV/Anime, desc: "Anime"}
|
||||
- {id: 7, cat: Books, desc: "Ebooks"}
|
||||
- {id: 8, cat: Other, desc: "Misc"}
|
||||
- {id: 9, cat: XXX, desc: "Porn"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
settings:
|
||||
- name: category
|
||||
type: select
|
||||
label: Category
|
||||
default: "0"
|
||||
options:
|
||||
"0" : "All"
|
||||
"1": "Movies"
|
||||
"2": "Series"
|
||||
"3": "Music"
|
||||
"4": "Games"
|
||||
"5": "Software"
|
||||
"6": "Anime"
|
||||
"7": "Ebooks"
|
||||
"8": "Misc"
|
||||
"9": "Porn"
|
||||
|
||||
search:
|
||||
# https://bt-scene.cc/cat/id/1/
|
||||
# https://bt-scene.cc/results_.php?q=midnight+texas+s01e10&advcat=2
|
||||
keywordsfilters:
|
||||
# replace space between keywords with +
|
||||
- name: re_replace
|
||||
args: [" ", "+"]
|
||||
paths:
|
||||
- path: "{{ if .Keywords }}results_.php?q={{ .Keywords }}&advcat={{ .Config.category }}{{else}}indexfull/{{end}}"
|
||||
rows:
|
||||
selector: table.tor > tbody > tr[id^="_"]
|
||||
filters:
|
||||
- name: andmatch
|
||||
fields:
|
||||
title:
|
||||
selector: td[class^="tname"] > a
|
||||
details:
|
||||
selector: td[class^="tname"] > a
|
||||
attribute: href
|
||||
category:
|
||||
selector: td[class^="tname"] > div.subinfo > a[href^="/cat/id"]
|
||||
optional: true
|
||||
attribute: href
|
||||
filters:
|
||||
- name: re_replace
|
||||
args: ["[^\\d+]", ""]
|
||||
download:
|
||||
# build "/torrentget.php?id=5730447" from "_5730447"
|
||||
selector: tr
|
||||
attribute: id
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["_", ""]
|
||||
- name: prepend
|
||||
args: "/torrentget.php?id="
|
||||
size:
|
||||
selector: td[class^="tsize"]
|
||||
seeders:
|
||||
selector: td[class^="tseeds"]
|
||||
leechers:
|
||||
selector: td[class^="tpeers"]
|
||||
date:
|
||||
selector: td[class^="ttime"]
|
||||
filters:
|
||||
- name: append
|
||||
args: " ago"
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
||||
@@ -54,9 +54,9 @@
|
||||
grabs:
|
||||
selector: .sbar span:nth-of-type(6) b
|
||||
seeders:
|
||||
text: "999"
|
||||
text: "1"
|
||||
leechers:
|
||||
text: "999"
|
||||
text: "1"
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
search:
|
||||
paths:
|
||||
- path: "{{if .Keywords}}q/{{ .Keywords}}/?sort=time{{else}}recent{{end}}"
|
||||
- path: "{{if .Keywords}}q/{{ .Keywords}}/?sort=time{{else}}q/test/{{end}}"
|
||||
- path: "{{if .Keywords}}q/{{ .Keywords}}/2?sort=time{{else}}{{end}}"
|
||||
- path: "{{if .Keywords}}q/{{ .Keywords}}/3?sort=time{{else}}{{end}}"
|
||||
- path: "{{if .Keywords}}q/{{ .Keywords}}/4?sort=time{{else}}{{end}}"
|
||||
@@ -63,9 +63,9 @@
|
||||
grabs:
|
||||
selector: div[class$="info"] span:nth-of-type(4)
|
||||
seeders:
|
||||
text: "999"
|
||||
selector: div[class$="info"] span:nth-of-type(4)
|
||||
leechers:
|
||||
text: "999"
|
||||
selector: div[class$="info"] span:nth-of-type(4)
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
|
||||
78
src/Jackett.Common/Definitions/btstornet.yml
Normal file
78
src/Jackett.Common/Definitions/btstornet.yml
Normal file
@@ -0,0 +1,78 @@
|
||||
---
|
||||
site: btstornet
|
||||
name: BTstor.net
|
||||
description: "BTstor.net is a Public BT-Scene clone for MOVIES / TV / GENERAL"
|
||||
language: us-en
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://btstor.net/
|
||||
|
||||
caps:
|
||||
categories:
|
||||
"anime": TV/Anime
|
||||
"books": Books
|
||||
"games": PC/Games
|
||||
"movies": Movies
|
||||
"music": Audio
|
||||
"other": Other
|
||||
"shows": TV
|
||||
"software": PC
|
||||
"video": Movies
|
||||
"xxx": XXX
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
settings: []
|
||||
|
||||
download:
|
||||
selector: "#dlt_"
|
||||
|
||||
search:
|
||||
# https://btstor.net/
|
||||
# https://btstor.net/q/midnight+texas+s01e10/date/
|
||||
keywordsfilters:
|
||||
# replace space between keywords with +
|
||||
- name: re_replace
|
||||
args: [" ", "+"]
|
||||
paths:
|
||||
- path: "{{ if .Keywords }}q/{{ .Keywords }}/date/{{else}}/{{end}}"
|
||||
rows:
|
||||
selector: table.tor > tbody > tr[class$="_tr"]
|
||||
filters:
|
||||
- name: andmatch
|
||||
fields:
|
||||
title:
|
||||
selector: td.tname_index > a
|
||||
details:
|
||||
selector: td.tname_index > a
|
||||
attribute: href
|
||||
category:
|
||||
# src="https://btstor.net/templates/btscene/images/shows.png"
|
||||
selector: td.tname_index > img
|
||||
attribute: src
|
||||
filters:
|
||||
- name: replace
|
||||
args: [".png", ""]
|
||||
- name: split
|
||||
args: ["/", 6]
|
||||
download:
|
||||
selector: td.tname_index > a
|
||||
attribute: href
|
||||
size:
|
||||
selector: td.tsize_index
|
||||
seeders:
|
||||
selector: td.tseeds_index
|
||||
leechers:
|
||||
selector: td.tpeers_index
|
||||
date:
|
||||
selector: td.tupd_index
|
||||
filters:
|
||||
- name: timeago
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
||||
@@ -73,12 +73,37 @@
|
||||
args: ([\d\.]+)
|
||||
date:
|
||||
selector: time
|
||||
filters:
|
||||
# translations for Turkish|Estonian|Danish|Italian|Polish|Norwegian|Portoguese|Czech|Russian|Romanian|Spanish|French|German|Bulgarian|Dutch
|
||||
- name: re_replace
|
||||
args: ["(önce|tagasi|geleden|fa|temu|siden|atrás|nazpět|назад|acum|hace|il y a|vor|преди)", "ago"]
|
||||
- name: re_replace
|
||||
args: ["(dakika|minut|minuto|minuta|minutt|минута|Minute|minuut)", "minute"]
|
||||
- name: re_replace
|
||||
args: ["(dakika|minutit|minutter|minuti|minuty|minutos|минуты|минут|Minuten|минути|minuten)", "minutes"]
|
||||
- name: re_replace
|
||||
args: ["(saat|tund|time|ora|godzina|hora|hodina|час|oră|heure|Stunde|uur)", "hour"]
|
||||
- name: re_replace
|
||||
args: ["(saat|tundi|timer|ore|godziny|horas|hodiny|hoden|часа|часов|ore|heures|Stunden)", "hours"]
|
||||
- name: re_replace
|
||||
args: ["(gün|päev|dag|giorno|dzień|dia|den|день|zi|día|jour|Tag|ден)", "day"]
|
||||
- name: re_replace
|
||||
args: ["(gün|päeva|dage|giorni|dni|dias|dny|дня|дней|zile|días|jours|Tagen|дни|dagen)", "days"]
|
||||
- name: re_replace
|
||||
args: ["(hafta|nädal|uge|settimana|tydzień|uke|semana|týden|неделю|săptămână|semaine|Woche|седмица)", "week"]
|
||||
- name: re_replace
|
||||
args: ["(hafta|nädalat|uger|settimane|tygodnie|uker|semanas|týdny|недели|недель|săptămâni|semaines|Wochen|седмици|weken)", "weeks"]
|
||||
- name: re_replace
|
||||
args: ["(ay|kuu|måned|mese|miesiąc|mês|měsíc|месяц|lună|mes|mois|Monat|месец|maand)", "month"]
|
||||
- name: re_replace
|
||||
args: ["(ay|kuud|måneder|mesi|miesiące|meses|měsíce|месяца|месяцев|luni|meses|mois|Monaten|месеца|maanden)", "months"]
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"i[data-original-title=\"100% Free\"]": "0"
|
||||
"i[data-original-title=\"Global FreeLeech\"]": "0"
|
||||
"i[data-original-title=\"100% Free\"]": "0" # Single Torrent Freeleech
|
||||
"i[data-original-title=\"Global FreeLeech\"]": "0" # Global Freeleech
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"i[data-original-title=\"Double upload\"]": "2"
|
||||
"i[data-original-title=\"Double upload\"]": "2" # Single Torrent Double Upload
|
||||
"i[data-original-title=\"Double Upload\"]": "2" # Global Double Upload
|
||||
"*": "1"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://www.cpabien.io/
|
||||
- https://www.cpabien.io/
|
||||
legacylinks:
|
||||
- http://www.cpasbiens.cc/
|
||||
- http://www.cpabien.cm/
|
||||
@@ -21,6 +21,8 @@
|
||||
- http://cpabien.co/
|
||||
- http://cpabien.la/
|
||||
- http://cpabien.club/
|
||||
- http://www.cpabien.io/
|
||||
- https://ww1.cpabien.io/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
|
||||
116
src/Jackett.Common/Definitions/dxdhd.yml
Normal file
116
src/Jackett.Common/Definitions/dxdhd.yml
Normal file
@@ -0,0 +1,116 @@
|
||||
---
|
||||
site: dxdhd
|
||||
name: DXDHD
|
||||
description: "General Tracker"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://dxdhd.com/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 1, cat: Movies, desc: "Movies"}
|
||||
- {id: 2, cat: TV, desc: "TV"}
|
||||
- {id: 3, cat: Audio, desc: "Music"}
|
||||
- {id: 4, cat: TV/Anime, desc: "Anime"}
|
||||
- {id: 5, cat: PC/0day, desc: "Apps"}
|
||||
- {id: 6, cat: Books, desc: "Books"}
|
||||
- {id: 7, cat: PC/Games, desc: "Games"}
|
||||
- {id: 8, cat: TV/Sport, desc: "Sports"}
|
||||
- {id: 9, cat: Other, desc: "Other"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep, imdbid]
|
||||
movie-search: [q, imdbid]
|
||||
|
||||
login:
|
||||
path: /login
|
||||
method: form
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
error:
|
||||
- selector: table.main:contains("Login Failed!")
|
||||
test:
|
||||
path: /torrents
|
||||
|
||||
search:
|
||||
paths:
|
||||
- path: /filterTorrents
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}categories[]={{.}}&{{end}}"
|
||||
search: "{{if .Query.IMDBID}}{{else}}{{ .Keywords }}{{end}}"
|
||||
uploader: ""
|
||||
imdb: "{{ .Query.IMDBIDShort }}"
|
||||
tvdb: ""
|
||||
tmdb: ""
|
||||
mal: ""
|
||||
sorting: created_at
|
||||
direction: desc
|
||||
qty: 100
|
||||
rows:
|
||||
selector: table > tbody > tr
|
||||
fields:
|
||||
category:
|
||||
selector: a[href*="/categories/"]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: regexp
|
||||
args: "/categories/.*?\\.(\\d+)"
|
||||
title:
|
||||
selector: a.view-torrent
|
||||
download:
|
||||
selector: a[href*="/download/"]
|
||||
attribute: href
|
||||
details:
|
||||
selector: a.view-torrent
|
||||
attribute: href
|
||||
size:
|
||||
selector: td:nth-child(5)
|
||||
seeders:
|
||||
selector: td:nth-child(7)
|
||||
leechers:
|
||||
selector: td:nth-child(8)
|
||||
grabs:
|
||||
selector: td:nth-child(6)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: ([\d\.]+)
|
||||
date:
|
||||
selector: time
|
||||
filters:
|
||||
# translations for Turkish|Estonian|Danish|Italian|Polish|Norwegian|Portoguese|Czech|Russian|Romanian|Spanish|French|German|Bulgarian|Dutch
|
||||
- name: re_replace
|
||||
args: ["(önce|tagasi|geleden|fa|temu|siden|atrás|nazpět|назад|acum|hace|il y a|vor|преди)", "ago"]
|
||||
- name: re_replace
|
||||
args: ["(dakika|minut|minuto|minuta|minutt|минута|Minute|minuut)", "minute"]
|
||||
- name: re_replace
|
||||
args: ["(dakika|minutit|minutter|minuti|minuty|minutos|минуты|минут|Minuten|минути|minuten)", "minutes"]
|
||||
- name: re_replace
|
||||
args: ["(saat|tund|time|ora|godzina|hora|hodina|час|oră|heure|Stunde|uur)", "hour"]
|
||||
- name: re_replace
|
||||
args: ["(saat|tundi|timer|ore|godziny|horas|hodiny|hoden|часа|часов|ore|heures|Stunden)", "hours"]
|
||||
- name: re_replace
|
||||
args: ["(gün|päev|dag|giorno|dzień|dia|den|день|zi|día|jour|Tag|ден)", "day"]
|
||||
- name: re_replace
|
||||
args: ["(gün|päeva|dage|giorni|dni|dias|dny|дня|дней|zile|días|jours|Tagen|дни|dagen)", "days"]
|
||||
- name: re_replace
|
||||
args: ["(hafta|nädal|uge|settimana|tydzień|uke|semana|týden|неделю|săptămână|semaine|Woche|седмица)", "week"]
|
||||
- name: re_replace
|
||||
args: ["(hafta|nädalat|uger|settimane|tygodnie|uker|semanas|týdny|недели|недель|săptămâni|semaines|Wochen|седмици|weken)", "weeks"]
|
||||
- name: re_replace
|
||||
args: ["(ay|kuu|måned|mese|miesiąc|mês|měsíc|месяц|lună|mes|mois|Monat|месец|maand)", "month"]
|
||||
- name: re_replace
|
||||
args: ["(ay|kuud|måneder|mesi|miesiące|meses|měsíce|месяца|месяцев|luni|meses|mois|Monaten|месеца|maanden)", "months"]
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"i[data-original-title=\"100% Free\"]": "0" # Single Torrent Freeleech
|
||||
"i[data-original-title=\"Global FreeLeech\"]": "0" # Global Freeleech
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"i[data-original-title=\"Double upload\"]": "2" # Single Torrent Double Upload
|
||||
"i[data-original-title=\"Double Upload\"]": "2" # Global Double Upload
|
||||
"*": "1"
|
||||
75
src/Jackett.Common/Definitions/elitetorrent-biz.yml
Normal file
75
src/Jackett.Common/Definitions/elitetorrent-biz.yml
Normal file
@@ -0,0 +1,75 @@
|
||||
---
|
||||
site: elitetorrent-biz
|
||||
name: EliteTorrent.biz
|
||||
description: "EliteTorrent.biz is a Public torrent site for TV, movies and documentaries"
|
||||
language: es-es
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://www.elitetorrent.biz/
|
||||
|
||||
caps:
|
||||
categories:
|
||||
"series": TV
|
||||
"peliculas": Movies
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
settings: []
|
||||
|
||||
download:
|
||||
selector: a[href^="magnet:?"]
|
||||
attribute: href
|
||||
|
||||
search:
|
||||
path: index.php
|
||||
keywordsfilters:
|
||||
# most ES/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:
|
||||
s: "{{ .Keywords }}"
|
||||
$raw: "&x=0&y=0"
|
||||
rows:
|
||||
selector: "#principal .miniboxs-ficha li"
|
||||
fields:
|
||||
title:
|
||||
selector: .meta a
|
||||
# normalize to SXXEYY format
|
||||
filters:
|
||||
- name: re_replace
|
||||
args: ["(\\d{2})×(\\d{2})", "S$1E$2"]
|
||||
- name: re_replace
|
||||
args: ["(\\d{1})×(\\d{2})", "S0$1E$2"]
|
||||
details:
|
||||
selector: .meta a
|
||||
attribute: href
|
||||
download:
|
||||
selector: .meta a
|
||||
attribute: href
|
||||
category:
|
||||
selector: .meta a
|
||||
attribute: href
|
||||
filters:
|
||||
- name: split
|
||||
args: ["/", 3]
|
||||
size:
|
||||
selector: .voto1
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["s", ""]
|
||||
date:
|
||||
text: now
|
||||
seeders:
|
||||
text: "1"
|
||||
leechers:
|
||||
text: "1"
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
||||
@@ -1,4 +1,4 @@
|
||||
---
|
||||
---
|
||||
site: ethor
|
||||
name: Ethor.net (Thor's Land)
|
||||
description: "A French gerneral tracker"
|
||||
@@ -83,6 +83,16 @@
|
||||
args: ["/details.php", "/download.php"]
|
||||
title:
|
||||
selector: a[href^="/details.php"]:has(b)
|
||||
filters:
|
||||
- name: toupper
|
||||
- name: replace
|
||||
args: ["VFQ", "FRENCH"]
|
||||
- name: replace
|
||||
args: ["MULTI", "FRENCH"]
|
||||
- name: re_replace
|
||||
args: ["S(\\d{2}) E(\\d{2})", "S$1E$2"]
|
||||
- name: re_replace
|
||||
args: ["S(\\d{1}) E(\\d{2})", "S0$1E$2"]
|
||||
category:
|
||||
selector: a[href^="/browse.php?cat="]
|
||||
attribute: href
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://eztv.re/
|
||||
legacylinks:
|
||||
- https://eztv.ag/
|
||||
|
||||
caps:
|
||||
|
||||
@@ -162,21 +162,21 @@
|
||||
- name: regexp
|
||||
args: "src=(.+?) "
|
||||
size:
|
||||
selector: td:nth-child(11)
|
||||
selector: td:nth-last-child(3)
|
||||
date:
|
||||
selector: td:nth-child(6)
|
||||
selector: td:nth-last-child(8)
|
||||
filters:
|
||||
- name: dateparse
|
||||
args: "02/01/2006"
|
||||
grabs:
|
||||
selector: td:nth-child(9)
|
||||
selector: td:nth-last-child(5)
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["---", "0"]
|
||||
seeders:
|
||||
selector: td:nth-child(7)
|
||||
selector: td:nth-last-child(7)
|
||||
leechers:
|
||||
selector: td:nth-child(8)
|
||||
selector: td:nth-last-child(6)
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
img[alt="Free Leech"]: "0"
|
||||
|
||||
@@ -6,13 +6,16 @@
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://ww2.gktorrent.com/
|
||||
- https://www.gktorrent.net/
|
||||
legacylinks:
|
||||
- https://www.gktorrent.org/
|
||||
- http://www.gktorrent.net/
|
||||
- https://www.gktorrent.com/ # they're forcing http
|
||||
- https://www.gktorrent.com/
|
||||
- http://www.gktorrent.com/
|
||||
- http://ww1.gktorrent.com/
|
||||
- http://ww2.gktorrent.com/
|
||||
- https://ww2.gktorrent.com/
|
||||
- https://ww3.gktorrent.com/
|
||||
- http://www.gktorrent.net/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
|
||||
115
src/Jackett.Common/Definitions/hd4free.yml
Normal file
115
src/Jackett.Common/Definitions/hd4free.yml
Normal file
@@ -0,0 +1,115 @@
|
||||
---
|
||||
site: hd4free
|
||||
name: hd4free
|
||||
description: "General Tracker Movies/TV/Apps/Games/Music/Books"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://hd4.xyz/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 1, cat: Movies, desc: "Movies"}
|
||||
- {id: 2, cat: TV, desc: "TV"}
|
||||
- {id: 3, cat: Audio, desc: "Music"}
|
||||
- {id: 4, cat: Books, desc: "Books"}
|
||||
- {id: 5, cat: PC/Mac, desc: "Apps"}
|
||||
- {id: 6, cat: Other, desc: "Other"}
|
||||
- {id: 7, cat: PC/Games, desc: "Games"}
|
||||
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep, imdbid]
|
||||
movie-search: [q, imdbid]
|
||||
|
||||
login:
|
||||
path: /login
|
||||
method: form
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
error:
|
||||
- selector: table.main:contains("Login Failed!")
|
||||
test:
|
||||
path: /torrents
|
||||
|
||||
search:
|
||||
paths:
|
||||
- path: /filterTorrents
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}categories[]={{.}}&{{end}}"
|
||||
search: "{{if .Query.IMDBID}}{{else}}{{ .Keywords }}{{end}}"
|
||||
uploader: ""
|
||||
imdb: "{{ .Query.IMDBIDShort }}"
|
||||
tvdb: ""
|
||||
tmdb: ""
|
||||
mal: ""
|
||||
sorting: created_at
|
||||
direction: desc
|
||||
qty: 100
|
||||
rows:
|
||||
selector: table > tbody > tr
|
||||
fields:
|
||||
category:
|
||||
selector: a[href*="/categories/"]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: regexp
|
||||
args: "/categories/.*?\\.(\\d+)"
|
||||
title:
|
||||
selector: a.view-torrent
|
||||
download:
|
||||
selector: a[href*="/download/"]
|
||||
attribute: href
|
||||
details:
|
||||
selector: a.view-torrent
|
||||
attribute: href
|
||||
size:
|
||||
selector: td:nth-child(5)
|
||||
seeders:
|
||||
selector: td:nth-child(7)
|
||||
leechers:
|
||||
selector: td:nth-child(8)
|
||||
grabs:
|
||||
selector: td:nth-child(6)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: ([\d\.]+)
|
||||
date:
|
||||
selector: time
|
||||
filters:
|
||||
# translations for Turkish|Estonian|Danish|Italian|Polish|Norwegian|Portoguese|Czech|Russian|Romanian|Spanish|French|German|Bulgarian|Dutch
|
||||
- name: re_replace
|
||||
args: ["(önce|tagasi|geleden|fa|temu|siden|atrás|nazpět|назад|acum|hace|il y a|vor|преди)", "ago"]
|
||||
- name: re_replace
|
||||
args: ["(dakika|minut|minuto|minuta|minutt|минута|Minute|minuut)", "minute"]
|
||||
- name: re_replace
|
||||
args: ["(dakika|minutit|minutter|minuti|minuty|minutos|минуты|минут|Minuten|минути|minuten)", "minutes"]
|
||||
- name: re_replace
|
||||
args: ["(saat|tund|time|ora|godzina|hora|hodina|час|oră|heure|Stunde|uur)", "hour"]
|
||||
- name: re_replace
|
||||
args: ["(saat|tundi|timer|ore|godziny|horas|hodiny|hoden|часа|часов|ore|heures|Stunden)", "hours"]
|
||||
- name: re_replace
|
||||
args: ["(gün|päev|dag|giorno|dzień|dia|den|день|zi|día|jour|Tag|ден)", "day"]
|
||||
- name: re_replace
|
||||
args: ["(gün|päeva|dage|giorni|dni|dias|dny|дня|дней|zile|días|jours|Tagen|дни|dagen)", "days"]
|
||||
- name: re_replace
|
||||
args: ["(hafta|nädal|uge|settimana|tydzień|uke|semana|týden|неделю|săptămână|semaine|Woche|седмица)", "week"]
|
||||
- name: re_replace
|
||||
args: ["(hafta|nädalat|uger|settimane|tygodnie|uker|semanas|týdny|недели|недель|săptămâni|semaines|Wochen|седмици|weken)", "weeks"]
|
||||
- name: re_replace
|
||||
args: ["(ay|kuu|måned|mese|miesiąc|mês|měsíc|месяц|lună|mes|mois|Monat|месец|maand)", "month"]
|
||||
- name: re_replace
|
||||
args: ["(ay|kuud|måneder|mesi|miesiące|meses|měsíce|месяца|месяцев|luni|meses|mois|Monaten|месеца|maanden)", "months"]
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"i[data-original-title=\"100% Free\"]": "0"
|
||||
"i[data-original-title=\"Global FreeLeech\"]": "0"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"i[data-original-title=\"Double upload\"]": "2"
|
||||
"i[data-original-title=\"Double Upload\"]": "2" # Global Double Upload
|
||||
"*": "1"
|
||||
@@ -6,7 +6,7 @@
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://hdhome.org
|
||||
- https://hdhome.org/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
@@ -70,18 +70,17 @@
|
||||
selector: img[alt="CAPTCHA"]
|
||||
input: imagestring
|
||||
inputs:
|
||||
logintype: "username"
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
error:
|
||||
- selector: td.embedded:has(h2:contains("姿势不正确"))
|
||||
- selector: td.embedded:has(h2:contains("失败"))
|
||||
test:
|
||||
path: /torrents.php
|
||||
path: torrents.php
|
||||
|
||||
search:
|
||||
paths:
|
||||
- path: /torrents.php
|
||||
- path: torrents.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}cat{{.}}=1&{{end}}"
|
||||
search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}"
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://hdtorrents.xyz/
|
||||
legacylinks:
|
||||
- http://hdtorrents.it/
|
||||
|
||||
caps:
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
---
|
||||
site: horriblesubs
|
||||
name: Horrible Subs
|
||||
description: "Anime Sub Group - \"So bad yet so good\""
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://horriblesubs.info/
|
||||
legacylinks:
|
||||
- https://horriblesubs.info/
|
||||
|
||||
caps:
|
||||
categories:
|
||||
1: TV/Anime # Anime
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
settings:
|
||||
- name: prepend-horriblesubs
|
||||
type: checkbox
|
||||
label: Prepend [Horriblesubs] to torrent title
|
||||
|
||||
search:
|
||||
paths:
|
||||
- path: "lib/{{if .Query.Keywords }}search.php{{else}}latest.php{{end}}"
|
||||
inputs:
|
||||
value: "{{ .Query.Keywords }}"
|
||||
rows:
|
||||
selector: "div.release-links"
|
||||
dateheaders:
|
||||
selector: table.release-info
|
||||
filters:
|
||||
- name: split
|
||||
args: [" ", 0 ]
|
||||
- name: replace
|
||||
args: ["(", ""]
|
||||
- name: replace
|
||||
args: [")", ""]
|
||||
- name: replace
|
||||
args: ["/", "-"]
|
||||
- name: dateparse
|
||||
args: "01-02-06"
|
||||
- name: dateparse
|
||||
args: "01-02"
|
||||
fields:
|
||||
category:
|
||||
text: "1"
|
||||
title:
|
||||
selector: table.release-table > tbody > tr > td.dl-label
|
||||
filters:
|
||||
- name: prepend
|
||||
args: "{{if .Config.prepend-horriblesubs}}[Horriblesubs] {{else}}{{end}}"
|
||||
details:
|
||||
attribute: class
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["release-links", ""]
|
||||
- name: re_replace
|
||||
args: [" ?(\\S+?)-((?:s\\d-)?(?:\\d+v?\\d?-){0,2}\\d+p)", "http://horriblesubs.info/shows/$1#$2"]
|
||||
download:
|
||||
selector: table.release-table > tbody > tr > td.hs-magnet-link > span > a
|
||||
attribute: href
|
||||
size:
|
||||
text: "500 MB"
|
||||
@@ -1,104 +0,0 @@
|
||||
---
|
||||
site: idope
|
||||
name: Idope
|
||||
description: "iDope is a Public torrent search engine presenting direct magnet links"
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://idope.cc/
|
||||
legacylinks:
|
||||
- https://idope.se/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 0, cat: Other, desc: "Others"}
|
||||
- {id: 1, cat: Movies, desc: "Movies"}
|
||||
- {id: 2, cat: Other, desc: "Video"}
|
||||
- {id: 3, cat: TV, desc: "TV"}
|
||||
- {id: 4, cat: TV/Anime, desc: "Anime"}
|
||||
- {id: 5, cat: XXX, desc: "XXX"}
|
||||
- {id: 6, cat: Audio, desc: "Music"}
|
||||
- {id: 7, cat: PC/Games, desc: "Games"}
|
||||
- {id: 8, cat: PC, desc: "Apps"}
|
||||
- {id: 9, cat: Books, desc: "Books"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
settings:
|
||||
- name: itorrents-links
|
||||
type: checkbox
|
||||
label: Add download links via itorrents.org
|
||||
- name: info
|
||||
type: info
|
||||
label: ITorrents Note
|
||||
default: Without the itorrents option only magnet links will be provided.
|
||||
|
||||
search:
|
||||
paths:
|
||||
# present trending results if there are no search parms supplied
|
||||
# sort torrent-list by age in descending order
|
||||
- path: "{{if .Keywords}}torrent-list/{{ .Keywords}}?&o=-3&c={{range .Categories }}{{.}}{{end}}{{else}}browse.html{{end}}"
|
||||
rows:
|
||||
selector: div[class="resultdiv"]
|
||||
fields:
|
||||
title:
|
||||
selector: div[class="resultdivtop"] a div[class="resultdivtopname"]
|
||||
category:
|
||||
optional: true
|
||||
selector: div[class="resultdivbotton"] div[class="resultdivbottoncategory"]
|
||||
case:
|
||||
":contains(\"Others\")": 0
|
||||
":contains(\"Movies\")": 1
|
||||
":contains(\"Video\")": 2
|
||||
":contains(\"TV\")": 3
|
||||
":contains(\"Anime\")": 4
|
||||
":contains(\"XXX\")": 5
|
||||
":contains(\"Music\")": 6
|
||||
":contains(\"Games\")": 7
|
||||
":contains(\"Apps\")": 8
|
||||
":contains(\"Books\")": 9
|
||||
details:
|
||||
selector: div[class="resultdivtop"] a
|
||||
attribute: href
|
||||
download-itorrents:
|
||||
selector: div[class="resultdivbotton"] div[id^="hideinfohash"]
|
||||
filters:
|
||||
- name: toupper
|
||||
- name: prepend
|
||||
args: http://itorrents.org/torrent/
|
||||
- name: append
|
||||
args: ".torrent"
|
||||
download:
|
||||
text: "{{if .Config.itorrents-links}}{{ .Result.download-itorrents }}{{else}}{{end}}"
|
||||
magfile:
|
||||
text: "{{ .Result.title }}"
|
||||
filters:
|
||||
- name: validfilename
|
||||
- name: urlencode
|
||||
magnet:
|
||||
selector: div[class="resultdivbotton"] div[id^="hideinfohash"]
|
||||
filters:
|
||||
- name: prepend
|
||||
args: "magnet:?xt=urn:btih:"
|
||||
- name: append
|
||||
args: "&dn={{ .Result.magfile }}.torrent"
|
||||
- name: append
|
||||
args: "&tr=http://182.176.139.129:6969/announce&tr=http://explodie.org:6969/announce&tr=http://tracker.mgtracker.org:2710/announce&tr=udp://tracker.coppersurfer.tk:6969/announce&tr=udp://tracker.leechers-paradise.org:6969/announce&tr=udp://tracker.pirateparty.gr:6969/announce&tr=udp://tracker.sktorrent.net:6969/announce&tr=udp://tracker.zer0day.to:1337/announce"
|
||||
date:
|
||||
selector: div[class="resultdivbotton"] div[class="resulttime"] div[class="resultdivbottontime"]
|
||||
filters:
|
||||
- name: timeago
|
||||
size:
|
||||
selector: div[class="resultdivbotton"] div[class="resultlength"] div[class="resultdivbottonlength"]
|
||||
seeders:
|
||||
selector: div[class="resultdivbotton"] div[class="resultseed"] div[class="resultdivbottonseed"]
|
||||
files:
|
||||
selector: div[class="resultdivbotton"] div[class="resultfile"] div[class="resultdivbottonfiles"]
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
||||
81
src/Jackett.Common/Definitions/idopeclone.yml
Normal file
81
src/Jackett.Common/Definitions/idopeclone.yml
Normal file
@@ -0,0 +1,81 @@
|
||||
---
|
||||
site: idopeclone
|
||||
name: IdopeClone
|
||||
description: "This Clone of iDope is a Public torrent search engine"
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://www.idope.site/
|
||||
legacylinks:
|
||||
- https://idope.top/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: other, cat: Other, desc: "Others"}
|
||||
- {id: movies, cat: Movies, desc: "Movies"}
|
||||
- {id: videos, cat: Other, desc: "Videos"}
|
||||
- {id: tv, cat: TV, desc: "TV"}
|
||||
- {id: anime, cat: TV/Anime, desc: "Anime"}
|
||||
- {id: xxx, cat: XXX, desc: "XXX"}
|
||||
- {id: adult, cat: XXX, desc: "XXX"}
|
||||
- {id: music, cat: Audio, desc: "Music"}
|
||||
- {id: games, cat: PC/Games, desc: "Games"}
|
||||
- {id: apps, cat: PC/0day, desc: "Apps"}
|
||||
- {id: applications, cat: PC/0day, desc: "Apps"}
|
||||
- {id: android, cat: PC/Phone-Android, desc: "Android"}
|
||||
- {id: software, cat: PC/0day, desc: "Apps"}
|
||||
- {id: books, cat: Books, desc: "Books"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
settings: []
|
||||
|
||||
search:
|
||||
paths:
|
||||
- path: "{{if .Keywords}}search/{{ .Keywords}}/{{else}}recent/{{end}}"
|
||||
- path: "{{if .Keywords}}s/{{ .Keywords}}/page/2{{else}}{{end}}"
|
||||
- path: "{{if .Keywords}}s/{{ .Keywords}}/page/3{{else}}{{end}}"
|
||||
- path: "{{if .Keywords}}s/{{ .Keywords}}/page/4{{else}}{{end}}"
|
||||
- path: "{{if .Keywords}}s/{{ .Keywords}}/page/5{{else}}{{end}}"
|
||||
rows:
|
||||
selector: li:has(div.opt-text-w3layouts)
|
||||
filters:
|
||||
- name: andmatch
|
||||
fields:
|
||||
title:
|
||||
selector: div.opt-text-w3layouts a
|
||||
details:
|
||||
selector: div.opt-text-w3layouts a
|
||||
attribute: href
|
||||
category:
|
||||
optional: true
|
||||
selector: a[href^="/browse/"]
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["/browse/", ""]
|
||||
magnet:
|
||||
selector: div.opt-text-w3layouts a
|
||||
attribute: href
|
||||
date:
|
||||
selector: div.seedbar span:nth-child(3)
|
||||
filters:
|
||||
- name: timeago
|
||||
files:
|
||||
selector: div.seedbar span:nth-child(4)
|
||||
size:
|
||||
selector: div.seedbar span:nth-child(2)
|
||||
seeders:
|
||||
selector: div.seedbar span:nth-child(1)
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["Seed: ", ""]
|
||||
leechers:
|
||||
text: "1"
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
||||
@@ -136,26 +136,30 @@
|
||||
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=(.+?) "
|
||||
# banner:
|
||||
# optional: true
|
||||
# selector: td:nth-child(2) > a
|
||||
# attribute: onmouseover
|
||||
# filters:
|
||||
# - name: regexp
|
||||
# args: "src=(.+?) "
|
||||
size:
|
||||
selector: td:nth-child(10)
|
||||
selector: td:nth-last-child(3)
|
||||
date:
|
||||
selector: td:nth-child(6)
|
||||
selector: td:nth-last-child(7)
|
||||
filters:
|
||||
- name: dateparse
|
||||
args: "02/01/2006"
|
||||
grabs:
|
||||
selector: td:nth-child(9)
|
||||
selector: td:nth-last-child(4)
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["---", "0"]
|
||||
seeders:
|
||||
selector: td:nth-child(7)
|
||||
selector: td:nth-last-child(6)
|
||||
leechers:
|
||||
selector: td:nth-child(8)
|
||||
selector: td:nth-last-child(5)
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
||||
|
||||
@@ -6,11 +6,15 @@
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://ilcorsaronero.ch/
|
||||
legacylinks:
|
||||
- https://ilcorsaronero.info/
|
||||
certificates:
|
||||
- 89c12d4a080b5aeec00acbb269dc9b44584b1b3f # incomplete CA chain
|
||||
- aa7c40aa360a1cec8a9687312fd50402b912e618 # incomplete CA chain
|
||||
- 83174ec1f92fa13cdef9d51888ea1dfba2166e17 # incomplete CA chain
|
||||
- c414bf4ad6c69841693c147849f4c314aa200bdf # incomplete CA chain
|
||||
- 3a402766ce22fd1aa24bfc1a4fd47e9309eb8c98 # incomplete CA chain
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
|
||||
77
src/Jackett.Common/Definitions/katcrs.yml
Normal file
77
src/Jackett.Common/Definitions/katcrs.yml
Normal file
@@ -0,0 +1,77 @@
|
||||
---
|
||||
site: katcrs
|
||||
name: KATcrs
|
||||
description: "KATcrs is a Public KickAssTorrent clone for TV / MOVIES / GENERAL"
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://kickassextratorrent.club/
|
||||
legacylinks:
|
||||
- https://kickasskatcr.website/
|
||||
- https://kickasskatcr.stream/
|
||||
- https://kickassextratorrent.xyz/
|
||||
- https://kickassextratorrent.website/
|
||||
|
||||
caps:
|
||||
categories:
|
||||
movies: Movies
|
||||
TV: TV
|
||||
Video: TV/WEB-DL
|
||||
Anime: TV/Anime
|
||||
Music: Audio
|
||||
Books: Books
|
||||
Documentary: TV/Documentary
|
||||
Games: Console
|
||||
Apps: PC
|
||||
Applications: PC
|
||||
Other: Other
|
||||
Othero: XXX
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
settings: []
|
||||
|
||||
search:
|
||||
paths:
|
||||
- path: "{{ if .Keywords }}search/{{ .Keywords }}/{{else}}new/{{end}}"
|
||||
rows:
|
||||
selector: table.data tr.odd
|
||||
filters:
|
||||
- name: andmatch
|
||||
fields:
|
||||
category:
|
||||
selector: span.uploader_block strong a
|
||||
attribute: href
|
||||
filters:
|
||||
- name: trim
|
||||
args: /
|
||||
title:
|
||||
selector: td:nth-child(1) div a.cellMainLink
|
||||
attribute: title
|
||||
details:
|
||||
selector: td:nth-child(1) div a.cellMainLink
|
||||
attribute: href
|
||||
download:
|
||||
selector: td:nth-child(1) div div a[data-download=""]
|
||||
attribute: href
|
||||
magnet:
|
||||
selector: td:nth-child(1) div div a[data-nop=""]
|
||||
attribute: href
|
||||
size:
|
||||
selector: td:nth-child(2)
|
||||
date:
|
||||
selector: td:nth-child(3)
|
||||
filters:
|
||||
- name: timeago
|
||||
seeders:
|
||||
selector: td:nth-child(4)
|
||||
leechers:
|
||||
selector: td:nth-child(5)
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
||||
@@ -11,89 +11,91 @@
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 1, cat: Movies, desc: "Movies"}
|
||||
- {id: 84, cat: Movies, desc: "N ees (2016, 2017)"}
|
||||
- {id: 14, cat: Movies/SD, desc: "DVDRip-BDRip-BRRip (e?? 2015) FREE"}
|
||||
- {id: 16, cat: Movies/SD, desc: "In Avouri (CAM) FREE"}
|
||||
- {id: 17, cat: Movies/BluRay, desc: "B LU-RAY"}
|
||||
- {id: 44, cat: Movies, desc: "E English Movies"}
|
||||
- {id: 76, cat: Movies, desc: "N tokimanter"}
|
||||
- {id: 82, cat: Movies, desc: "I EATP"}
|
||||
- {id: 84, cat: Movies, desc: "Movies New (2017, 2018)"}
|
||||
- {id: 14, cat: Movies/SD, desc: "Movies DVDRip-BDRip-BRRip (up to 2016) FREE"}
|
||||
- {id: 16, cat: Movies/SD, desc: "Movies (CAM) FREE"}
|
||||
- {id: 17, cat: Movies/BluRay, desc: "Movies BLU-RAY"}
|
||||
- {id: 44, cat: Movies, desc: "Movies Greek"}
|
||||
- {id: 76, cat: Movies, desc: "Movies Documentaries"}
|
||||
- {id: 82, cat: Movies, desc: "Movies Theater"}
|
||||
|
||||
- {id: 52, cat: TV, desc: "series"}
|
||||
- {id: 53, cat: TV/SD, desc: ", O Enes"}
|
||||
- {id: 70, cat: TV/HD, desc: "O Enes (720p)"}
|
||||
- {id: 54, cat: TV, desc: "E English"}
|
||||
- {id: 86, cat: TV, desc: "O Enes Complete Seasons"}
|
||||
- {id: 92, cat: TV, desc: "O Enes Complete Seasons (720p)"}
|
||||
- {id: 87, cat: TV, desc: "E English Complete Seasons"}
|
||||
- {id: 63, cat: TV, desc: "Y ychagogikes Emissions"}
|
||||
- {id: 52, cat: TV, desc: "TV Series"}
|
||||
- {id: 53, cat: TV/SD, desc: "TV Series Foreign"}
|
||||
- {id: 70, cat: TV/HD, desc: "TV Series Foreign (720p)"}
|
||||
- {id: 54, cat: TV, desc: "TV Series Greek"}
|
||||
- {id: 86, cat: TV, desc: "TV Series Foreign Complete Seasons"}
|
||||
- {id: 92, cat: TV, desc: "TV Series Foreign Complete Seasons (720p)"}
|
||||
- {id: 87, cat: TV, desc: "TV Series Greek Complete Seasons"}
|
||||
- {id: 63, cat: TV, desc: "TV Series Recreational"}
|
||||
- {id: 83, cat: TV/Sport, desc: "TV Sports"}
|
||||
|
||||
- {id: 55, cat: Movies, desc: "Children"}
|
||||
- {id: 38, cat: Movies, desc: "M etaglotismena (Movies)"}
|
||||
- {id: 39, cat: Movies, desc: "M e Subtitled (Movies)"}
|
||||
- {id: 93, cat: Movies, desc: "M etaglotismena (Series)"}
|
||||
- {id: 94, cat: Movies, desc: "M e Subtitled (Series)"}
|
||||
- {id: 45, cat: Movies, desc: "I absent Anime"}
|
||||
- {id: 98, cat: Movies, desc: "M etaglotismena 3D"}
|
||||
- {id: 64, cat: Movies, desc: "M music for Children"}
|
||||
- {id: 38, cat: Movies, desc: "Children (Movies)"}
|
||||
- {id: 39, cat: Movies, desc: "Children Subtitled (Movies)"}
|
||||
- {id: 93, cat: Movies, desc: "Children (TV Series)"}
|
||||
- {id: 94, cat: Movies, desc: "Children Subtitled (TV Series)"}
|
||||
- {id: 45, cat: Movies, desc: "Children Anime"}
|
||||
- {id: 98, cat: Movies, desc: "Children 3D"}
|
||||
- {id: 64, cat: Movies, desc: "Children Music"}
|
||||
|
||||
- {id: 7, cat: Audio, desc: "Foreign music"}
|
||||
- {id: 21, cat: Audio, desc: "N ees Releases"}
|
||||
- {id: 46, cat: Audio, desc: "P. Alai Releases"}
|
||||
- {id: 32, cat: Audio, desc: "D. iskografies"}
|
||||
- {id: 20, cat: Audio, desc: "In ylloges"}
|
||||
- {id: 102, cat: Audio, desc: "M AGICO Radio"}
|
||||
- {id: 81, cat: Audio, desc: "K araoke"}
|
||||
- {id: 95, cat: Audio, desc: "Soundtrack"}
|
||||
- {id: 7, cat: Audio, desc: "Music Foreign"}
|
||||
- {id: 21, cat: Audio, desc: "Music Foreign New Releases"}
|
||||
- {id: 46, cat: Audio, desc: "Music Foreign Old Releases"}
|
||||
- {id: 32, cat: Audio, desc: "Music Foreign Discographies"}
|
||||
- {id: 20, cat: Audio, desc: "Music Foreign Collections"}
|
||||
- {id: 102, cat: Audio, desc: "Music Foreign MAGICO Radio"}
|
||||
- {id: 81, cat: Audio, desc: "Music Foreign Karaoke"}
|
||||
- {id: 95, cat: Audio, desc: "Music Foreign Soundtrack"}
|
||||
|
||||
- {id: 47, cat: Audio, desc: "Greek music"}
|
||||
- {id: 48, cat: Audio, desc: "N ees Releases"}
|
||||
- {id: 49, cat: Audio, desc: "P. Alai Releases"}
|
||||
- {id: 51, cat: Audio, desc: "D. iskografies"}
|
||||
- {id: 50, cat: Audio, desc: "In ylloges"}
|
||||
- {id: 101, cat: Audio, desc: "M AGICO Radio"}
|
||||
- {id: 97, cat: Audio, desc: "Live Cd 's"}
|
||||
- {id: 57, cat: Audio, desc: "P empetika"}
|
||||
- {id: 58, cat: Audio, desc: "D. imotika"}
|
||||
- {id: 59, cat: Audio, desc: "K exception of preservatives"}
|
||||
- {id: 60, cat: Audio, desc: "N isiotika"}
|
||||
- {id: 62, cat: Audio, desc: "P. ontiaka"}
|
||||
- {id: 80, cat: Audio, desc: "K araoke"}
|
||||
- {id: 96, cat: Audio, desc: "Soundtracks"}
|
||||
- {id: 47, cat: Audio, desc: "Music Greek"}
|
||||
- {id: 48, cat: Audio, desc: "Music Greek New Releases"}
|
||||
- {id: 49, cat: Audio, desc: "Music Greek Old Releases"}
|
||||
- {id: 51, cat: Audio, desc: "Music Greek Discographies"}
|
||||
- {id: 50, cat: Audio, desc: "Music Greek Collections"}
|
||||
- {id: 101, cat: Audio, desc: "Music Greek MAGICO Radio"}
|
||||
- {id: 97, cat: Audio, desc: "Music Greek Live Cd's"}
|
||||
- {id: 57, cat: Audio, desc: "Music Greek Rebetika"}
|
||||
- {id: 58, cat: Audio, desc: "Music Greek Primary"}
|
||||
- {id: 59, cat: Audio, desc: "Music Greek Cretan"}
|
||||
- {id: 60, cat: Audio, desc: "Music Greek Island"}
|
||||
- {id: 62, cat: Audio, desc: "Music Greek Pontian"}
|
||||
- {id: 80, cat: Audio, desc: "Music Greek Karaoke"}
|
||||
- {id: 96, cat: Audio, desc: "Music Greek Soundtracks"}
|
||||
|
||||
- {id: 73, cat: Audio, desc: "seasonal Music"}
|
||||
- {id: 74, cat: Audio, desc: "X ristougenna"}
|
||||
- {id: 79, cat: Audio, desc: "P. ascha"}
|
||||
- {id: 75, cat: Audio, desc: "A pokriatika"}
|
||||
- {id: 78, cat: Audio, desc: "A Tariff Valentine"}
|
||||
- {id: 73, cat: Audio, desc: "Music Seasonal"}
|
||||
- {id: 74, cat: Audio, desc: "Music Seasonal Xmas"}
|
||||
- {id: 79, cat: Audio, desc: "Music Seasonal Easter"}
|
||||
- {id: 75, cat: Audio, desc: "Music Seasonal Halloween"}
|
||||
- {id: 78, cat: Audio, desc: "Music Seasonal Valentines"}
|
||||
|
||||
- {id: 33, cat: Books, desc: "Books"}
|
||||
- {id: 41, cat: Books, desc: "E nglis"}
|
||||
- {id: 65, cat: Books, desc: "K omix"}
|
||||
- {id: 43, cat: Books, desc: "P. periods"}
|
||||
- {id: 72, cat: Books, desc: "P. aidika"}
|
||||
- {id: 66, cat: Books, desc: "L. exika - Educational"}
|
||||
- {id: 42, cat: Books, desc: "O enoglossa"}
|
||||
- {id: 67, cat: Books, desc: "E. Konya-Photos"}
|
||||
- {id: 41, cat: Books, desc: "Books Greek"}
|
||||
- {id: 65, cat: Books, desc: "Books Comics"}
|
||||
- {id: 43, cat: Books, desc: "Books Periodicals"}
|
||||
- {id: 105, cat: Books, desc: "Books Audio"}
|
||||
- {id: 72, cat: Books, desc: "Books Children"}
|
||||
- {id: 66, cat: Books, desc: "Books Educational"}
|
||||
- {id: 42, cat: Books, desc: "Books Foreign"}
|
||||
- {id: 67, cat: Books, desc: "Books Photos"}
|
||||
|
||||
- {id: 6, cat: PC, desc: "programs"}
|
||||
- {id: 18, cat: PC/0day, desc: "PC"}
|
||||
- {id: 40, cat: PC/Phone-Android, desc: "Android"}
|
||||
- {id: 19, cat: PC/Mac, desc: "Mac"}
|
||||
- {id: 6, cat: PC, desc: "Programs"}
|
||||
- {id: 18, cat: PC/0day, desc: "Programs PC"}
|
||||
- {id: 40, cat: PC/Phone-Android, desc: "Programs Android"}
|
||||
- {id: 19, cat: PC/Mac, desc: "Programs Mac"}
|
||||
|
||||
- {id: 2, cat: PC/Games, desc: "Games"}
|
||||
- {id: 27, cat: PC/Games, desc: "PC"}
|
||||
- {id: 68, cat: PC/Phone-Android, desc: "Android"}
|
||||
- {id: 27, cat: PC/Games, desc: "Games PC"}
|
||||
- {id: 68, cat: PC/Phone-Android, desc: "Games Android"}
|
||||
|
||||
- {id: 88, cat: Other, desc: "Design / Tutorials / Accessories"}
|
||||
- {id: 89, cat: Other, desc: "Photoshop Tutorials"}
|
||||
- {id: 91, cat: Other, desc: "Illustrator Tutorials"}
|
||||
- {id: 90, cat: Other, desc: "After Effects Tutorials"}
|
||||
- {id: 88, cat: Other, desc: "Tutorials / Design / Accessories"}
|
||||
- {id: 89, cat: Other, desc: "Tutorials Photoshop"}
|
||||
- {id: 91, cat: Other, desc: "Tutorials Illustrator"}
|
||||
- {id: 90, cat: Other, desc: "Tutorials After Effects"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
login:
|
||||
path: /?p=home&pid=1
|
||||
@@ -135,28 +137,29 @@
|
||||
error:
|
||||
- selector: div#show_error font
|
||||
rows:
|
||||
selector: div#content > div.torrent-box[id^="torrent_"]
|
||||
selector: div#content > div.torrent-box[id^="torrent_"], tr:has(a[href*="?p=torrents"][href*="&action=details"])
|
||||
filters:
|
||||
- name: andmatch
|
||||
fields:
|
||||
title:
|
||||
selector: a[href*="?p=torrents&pid=10&action=details"]
|
||||
selector: a[href*="?p=torrents"][href*="&action=details"]
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["Grey's Anatomy", "Greys Anatomy"]
|
||||
category:
|
||||
selector: div.categoryImage > a
|
||||
selector: a[href*="?p=torrents"][href*="&cid="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cid
|
||||
details:
|
||||
selector: a[href*="?p=torrents&pid=10&action=details"]
|
||||
selector: a[href*="?p=torrents"][href*="&action=details"]
|
||||
attribute: href
|
||||
download:
|
||||
selector: a[href*="?p=torrents&pid=10&action=download"]
|
||||
selector: a[href*="?p=torrents"][href*="&action=download"]
|
||||
attribute: href
|
||||
imdb:
|
||||
optional: true
|
||||
selector: a[href^="http://www.imdb.com/title/tt"]
|
||||
attribute: href
|
||||
size:
|
||||
@@ -172,6 +175,7 @@
|
||||
selector: a[rel="fancybox"]
|
||||
attribute: href
|
||||
description:
|
||||
optional: true
|
||||
selector: div.torrentDetails > div:has(span.floatright)
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
@@ -217,5 +221,17 @@
|
||||
args: ["Κυριακή", "Sunday"]
|
||||
- name: dateparse
|
||||
args: "02-01-2006 15:04"
|
||||
|
||||
|
||||
date:
|
||||
# <br /> Uploaded Saturday at 21:09 by
|
||||
optional: true
|
||||
selector: td.torrent_name
|
||||
remove: div, a, span
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["Uploaded ", ""]
|
||||
- name: replace
|
||||
args: [" by", ""]
|
||||
- name: replace
|
||||
args: ["at ", ""]
|
||||
- name: dateparse
|
||||
args: "02-01-2006 15:04"
|
||||
|
||||
114
src/Jackett.Common/Definitions/metal-iplay-ro.yml
Normal file
114
src/Jackett.Common/Definitions/metal-iplay-ro.yml
Normal file
@@ -0,0 +1,114 @@
|
||||
---
|
||||
site: metaliplayro
|
||||
name: Romanian Metal Torrent
|
||||
description: "Romanian Metal Torrent is a Private site dedicated to METAL MUSIC. This definition is for the English site."
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://metal.iplay.ro/
|
||||
legacylinks:
|
||||
- https://metal.stream.bike/
|
||||
|
||||
caps:
|
||||
categories:
|
||||
"Music": Audio
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
music-search: [q, album, artist, label, year]
|
||||
|
||||
login:
|
||||
path: login.php
|
||||
method: form
|
||||
form: form[action="takelogin.php"]
|
||||
captcha:
|
||||
type: image
|
||||
selector: img
|
||||
input: vImageCodP
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
error:
|
||||
- selector: div.errorSummary
|
||||
message:
|
||||
selector: div.errorSummary ul li
|
||||
test:
|
||||
path: browse.php
|
||||
selector: a[href="logout.php"]
|
||||
|
||||
ratio:
|
||||
path: browse.php
|
||||
selector: img:contains("Ratio =") > img
|
||||
|
||||
download:
|
||||
method: get
|
||||
before:
|
||||
path: "login.php"
|
||||
method: "post"
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
|
||||
search:
|
||||
paths:
|
||||
- path: browse.php
|
||||
method: get
|
||||
inputs:
|
||||
"search": "{{if .Query.Artist}}{{ .Query.Artist }}{{else}}{{ .Keywords }}{{end}}"
|
||||
rows:
|
||||
selector: table.torrents_table tbody tr:has(a[href^="download2.php?id="])
|
||||
fields:
|
||||
title:
|
||||
selector: td a[href^="details.php?id="]
|
||||
details:
|
||||
selector: td a[href^="details.php?id="]
|
||||
attribute: href
|
||||
download:
|
||||
selector: td a[href^="download2.php?id="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["download2.php?id=", "download.php/"]
|
||||
- name: append
|
||||
args: "/{{ .Result.title }}.torrent"
|
||||
banner:
|
||||
optional: true
|
||||
selector: td:nth-child(2) a
|
||||
attribute: onmouseover
|
||||
filters:
|
||||
- name: regexp
|
||||
args: 'img src=(.+?) >'
|
||||
- name: replace
|
||||
args: ["./pic/noposter.jpg", ""]
|
||||
date:
|
||||
selector: td:nth-child(8) > span
|
||||
attribute: title
|
||||
size:
|
||||
selector: td:nth-child(6)
|
||||
seeders:
|
||||
selector: td:nth-child(7)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: '([\d]+) seeders?'
|
||||
leechers:
|
||||
selector: td:nth-child(7)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: '([\d]+) leechers?'
|
||||
grabs:
|
||||
selector: td:nth-child(6)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: '([\d]+) times'
|
||||
category:
|
||||
text: "Music"
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
img[src$="pic/freedownload.gif"]: "0"
|
||||
img[src$="pic/half.gif"]: "0.5"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
img[src$="pic/sticky2.gif"]: "1.5"
|
||||
"*": "1"
|
||||
@@ -124,15 +124,15 @@
|
||||
- name: replace
|
||||
args: ["pic/nopic.jpg", ""]
|
||||
size:
|
||||
selector: td.rowfollow:nth-child(5)
|
||||
selector: td.rowfollow:nth-last-child(6)
|
||||
grabs:
|
||||
selector: td.rowfollow:nth-child(8)
|
||||
selector: td.rowfollow:nth-last-child(3)
|
||||
seeders:
|
||||
selector: td.rowfollow:nth-child(6)
|
||||
selector: td.rowfollow:nth-last-child(5)
|
||||
leechers:
|
||||
selector: td.rowfollow:nth-child(7)
|
||||
selector: td.rowfollow:nth-last-child(4)
|
||||
date:
|
||||
selector: td.rowfollow:nth-child(4):not(:has(span))
|
||||
selector: td.rowfollow:nth-last-child(7):not(:has(span))
|
||||
optional: true
|
||||
filters:
|
||||
- name: append
|
||||
@@ -140,7 +140,7 @@
|
||||
- name: dateparse
|
||||
args: "2006-01-0215:04:05 -07:00"
|
||||
date:
|
||||
selector: td.rowfollow:nth-child(4) > span[title]
|
||||
selector: td.rowfollow:nth-last-child(7) > span[title]
|
||||
optional: true
|
||||
attribute: title
|
||||
filters:
|
||||
|
||||
@@ -9,6 +9,20 @@
|
||||
- https://nnm-club.me/
|
||||
legacylinks:
|
||||
- https://nnm-club.name/
|
||||
certificates:
|
||||
- 7877113458e90f3643dd28424657a29469f5dc55
|
||||
|
||||
settings:
|
||||
- name: username
|
||||
type: text
|
||||
label: Username
|
||||
- name: password
|
||||
type: password
|
||||
label: Password
|
||||
- name: striprussian
|
||||
type: checkbox
|
||||
label: Strip Russian Letters
|
||||
default: true
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
@@ -724,7 +738,7 @@
|
||||
- name: re_replace
|
||||
args: ["(\\([Сс]езон\\s+(\\d+).+[Сс]ери[ия]\\s+(?:(\\d+-*\\d*).*\\d+)*\\))", "(S$2E$3) RUS"]
|
||||
- name: re_replace
|
||||
args: ["(\\([А-Яа-я\\W]+\\))|(^[А-Яа-я\\W\\d]+\\/ )|([а-яА-Я \\-]+,+)|([а-яА-Я]+)", ""]
|
||||
args: ["(\\([А-Яа-я\\W]+\\))|(^[А-Яа-я\\W\\d]+\\/ )|([а-яА-Я \\-]+,+)|([а-яА-Я]+)", "{{ if .Config.striprussian }}{{ else }}$1$2$3$4{{ end }}"]
|
||||
- name: replace
|
||||
args: ["WEBDLRip", "WEBDL"]
|
||||
- name: replace
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://nyaa.si
|
||||
certificates:
|
||||
- 3801e330482d4f9baef71ca4e33ba23ede74f59c # incomplete CA chain
|
||||
|
||||
settings:
|
||||
- name: filter-id
|
||||
|
||||
107
src/Jackett.Common/Definitions/prostylex.yml
Normal file
107
src/Jackett.Common/Definitions/prostylex.yml
Normal file
@@ -0,0 +1,107 @@
|
||||
---
|
||||
site: prostylex
|
||||
name: ProStyleX
|
||||
description: "ProStyleX is a Public torrent site for 0Day and General"
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- http://prostylex.com/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 1, cat: Movies/SD, desc: "Movies - Divx/Xvid"}
|
||||
- {id: 2, cat: Movies/WEBDL, desc: "Movies - h.264/x264"}
|
||||
- {id: 3, cat: Movies/HD, desc: "Movies - HD"}
|
||||
- {id: 4, cat: Movies/DVD, desc: "Movies - DVD"}
|
||||
- {id: 5, cat: Movies/Other, desc: "Movies - Cam/TS"}
|
||||
- {id: 6, cat: Movies/Foreign, desc: "Movies - Non-English"}
|
||||
- {id: 7, cat: Movies/3D, desc: "Movies - 3D"}
|
||||
- {id: 8, cat: Movies/UHD, desc: "Movies - 4K"}
|
||||
- {id: 9, cat: Movies/Other, desc: "Movies - Dubs/Dual Audio"}
|
||||
- {id: 12, cat: TV/WEB-DL, desc: "TV - x264"}
|
||||
- {id: 13, cat: TV/SD, desc: "TV - Xvid"}
|
||||
- {id: 14, cat: TV/HD, desc: "TV - HD"}
|
||||
- {id: 15, cat: TV/OTHER, desc: "TV - Packs"}
|
||||
- {id: 20, cat: Audio/MP3, desc: "Music - Audio"}
|
||||
- {id: 21, cat: Audio/Video, desc: "Music - Video"}
|
||||
- {id: 22, cat: Audio/Other, desc: "Music - Other"}
|
||||
- {id: 40, cat: XXX, desc: "XXX - Video"}
|
||||
- {id: 42, cat: XXX, desc: "XXX - HD Video"}
|
||||
- {id: 43, cat: XXX, desc: "XXX - Movie"}
|
||||
- {id: 44, cat: XXX, desc: "XXX - Anime/Hentai"}
|
||||
- {id: 45, cat: XXX, desc: "XXX - Pics/Comix/Book"}
|
||||
- {id: 46, cat: XXX, desc: "XXX - Games"}
|
||||
- {id: 53, cat: Audio/Audiobook, desc: "Books - Audio books"}
|
||||
- {id: 54, cat: Books/Comics, desc: "Books - Comics"}
|
||||
- {id: 55, cat: Books/Ebook, desc: "Books - Ebooks"}
|
||||
- {id: 56, cat: Books/Magazines, desc: "Books - Magazines"}
|
||||
- {id: 57, cat: Books/Other, desc: "Books - Other"}
|
||||
- {id: 58, cat: Other, desc: "Pictures - Other"}
|
||||
- {id: 59, cat: Other, desc: "Pictures - Wallpapers"}
|
||||
- {id: 65, cat: TV/Anime, desc: "Anime - All"}
|
||||
- {id: 90, cat: PC/ISO, desc: "Games - PC-ISO"}
|
||||
- {id: 91, cat: Console, desc: "Games - PS2"}
|
||||
- {id: 92, cat: Console/PSP, desc: "Games - PSP"}
|
||||
- {id: 93, cat: Console/PS3, desc: "Games - PS3"}
|
||||
- {id: 94, cat: PC/Games, desc: "Games - PC-RIP"}
|
||||
- {id: 95, cat: Console/Xbox 360, desc: "Games - Xbox360"}
|
||||
- {id: 96, cat: Console/Other, desc: "Games - Other"}
|
||||
- {id: 97, cat: Console/Wii, desc: "Games - Wii"}
|
||||
- {id: 98, cat: Console/NDS, desc: "Games - Nintendo DS"}
|
||||
- {id: 99, cat: PC/Phone-Android, desc: "Games - Android"}
|
||||
- {id: 120, cat: PC/0day, desc: "Apps - Windows"}
|
||||
- {id: 121, cat: PC, desc: "Apps - Linux"}
|
||||
- {id: 122, cat: PC/Phone-Android, desc: "Apps - Android"}
|
||||
- {id: 123, cat: PC/Mac, desc: "Apps - Mac"}
|
||||
- {id: 124, cat: PC, desc: "Apps - Other"}
|
||||
- {id: 130, cat: Other, desc: "Other - Other"}
|
||||
- {id: 134, cat: Other, desc: "Other - Tutorials"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
settings: []
|
||||
|
||||
download:
|
||||
selector: a[href^="magnet:?"]
|
||||
|
||||
search:
|
||||
paths:
|
||||
# http://prostylex.com/torrents-search.php?search=
|
||||
# http://prostylex.com/torrents-search.php?c1=1&c2=1&c3=1&search=expanse&cat=0&incldead=0&freeleech=0&inclexternal=0&lang=0
|
||||
- path: "torrents-search.php?{{range .Categories}}c{{.}}=1&{{end}}{{if .Keywords}}&search={{ .Keywords}}&cat=0&incldead=0&freeleech=0&inclexternal=0&lang=0{{else}}search={{end}}"
|
||||
rows:
|
||||
# selector: tr:has(a[href^="/torrent/"])
|
||||
selector: tr.t-row
|
||||
fields:
|
||||
title:
|
||||
selector: td a[href^="torrents-details.php?id="]
|
||||
category:
|
||||
selector: td a[href^="torrents.php?cat="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
details:
|
||||
selector: td a[href^="torrents-details.php?id="]
|
||||
attribute: href
|
||||
download:
|
||||
selector: td a[href^="torrents-details.php?id="]
|
||||
attribute: href
|
||||
date:
|
||||
selector: th:nth-child(5)
|
||||
filters:
|
||||
- name: timeago
|
||||
size:
|
||||
selector: th:nth-child(4)
|
||||
seeders:
|
||||
selector: th:nth-child(6)
|
||||
leechers:
|
||||
selector: th:nth-child(7)
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
||||
@@ -84,12 +84,37 @@
|
||||
args: ([\d\.]+)
|
||||
date:
|
||||
selector: time
|
||||
filters:
|
||||
# translations for Turkish|Estonian|Danish|Italian|Polish|Norwegian|Portoguese|Czech|Russian|Romanian|Spanish|French|German|Bulgarian|Dutch
|
||||
- name: re_replace
|
||||
args: ["(önce|tagasi|geleden|fa|temu|siden|atrás|nazpět|назад|acum|hace|il y a|vor|преди)", "ago"]
|
||||
- name: re_replace
|
||||
args: ["(dakika|minut|minuto|minuta|minutt|минута|Minute|minuut)", "minute"]
|
||||
- name: re_replace
|
||||
args: ["(dakika|minutit|minutter|minuti|minuty|minutos|минуты|минут|Minuten|минути|minuten)", "minutes"]
|
||||
- name: re_replace
|
||||
args: ["(saat|tund|time|ora|godzina|hora|hodina|час|oră|heure|Stunde|uur)", "hour"]
|
||||
- name: re_replace
|
||||
args: ["(saat|tundi|timer|ore|godziny|horas|hodiny|hoden|часа|часов|ore|heures|Stunden)", "hours"]
|
||||
- name: re_replace
|
||||
args: ["(gün|päev|dag|giorno|dzień|dia|den|день|zi|día|jour|Tag|ден)", "day"]
|
||||
- name: re_replace
|
||||
args: ["(gün|päeva|dage|giorni|dni|dias|dny|дня|дней|zile|días|jours|Tagen|дни|dagen)", "days"]
|
||||
- name: re_replace
|
||||
args: ["(hafta|nädal|uge|settimana|tydzień|uke|semana|týden|неделю|săptămână|semaine|Woche|седмица)", "week"]
|
||||
- name: re_replace
|
||||
args: ["(hafta|nädalat|uger|settimane|tygodnie|uker|semanas|týdny|недели|недель|săptămâni|semaines|Wochen|седмици|weken)", "weeks"]
|
||||
- name: re_replace
|
||||
args: ["(ay|kuu|måned|mese|miesiąc|mês|měsíc|месяц|lună|mes|mois|Monat|месец|maand)", "month"]
|
||||
- name: re_replace
|
||||
args: ["(ay|kuud|måneder|mesi|miesiące|meses|měsíce|месяца|месяцев|luni|meses|mois|Monaten|месеца|maanden)", "months"]
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"i[data-original-title=\"100% Free\"]": "0"
|
||||
"i[data-original-title=\"Global FreeLeech\"]": "0"
|
||||
"i[data-original-title=\"100% Free\"]": "0" # Single Torrent Freeleech
|
||||
"i[data-original-title=\"Global FreeLeech\"]": "0" # Global Freeleech
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"i[data-original-title=\"Double upload\"]": "2"
|
||||
"i[data-original-title=\"Double upload\"]": "2" # Single Torrent Double Upload
|
||||
"i[data-original-title=\"Double Upload\"]": "2" # Global Double Upload
|
||||
"*": "1"
|
||||
|
||||
113
src/Jackett.Common/Definitions/redtopia.yml
Normal file
113
src/Jackett.Common/Definitions/redtopia.yml
Normal file
@@ -0,0 +1,113 @@
|
||||
---
|
||||
site: redtopia
|
||||
name: Redtopia
|
||||
description: "Tracker Music/Podcasts/Audiobooks"
|
||||
language: en-us
|
||||
type: private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://redtopia.xyz/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 1, cat: Audio, desc: "Studio Album"}
|
||||
- {id: 2, cat: Audio, desc: "Studio Single"}
|
||||
- {id: 3, cat: Audio, desc: "Studio Collection"}
|
||||
- {id: 4, cat: Audio, desc: "Indie Album"}
|
||||
- {id: 5, cat: Audio, desc: "Indie Single"}
|
||||
- {id: 6, cat: Audio, desc: "Indie Collection"}
|
||||
- {id: 7, cat: Audio, desc: "Live Album"}
|
||||
- {id: 8, cat: Audio, desc: "OST"}
|
||||
- {id: 9, cat: Audio, desc: "Podcast"}
|
||||
- {id: 10, cat: Audio, desc: "Audio Book"}
|
||||
- {id: 11, cat: Audio, desc: "Audio Drama"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
music-search: [q]
|
||||
|
||||
login:
|
||||
path: /login
|
||||
method: form
|
||||
inputs:
|
||||
username: "{{ .Config.username }}"
|
||||
password: "{{ .Config.password }}"
|
||||
error:
|
||||
- selector: table.main:contains("Login Failed!")
|
||||
test:
|
||||
path: /torrents
|
||||
|
||||
search:
|
||||
paths:
|
||||
- path: /filterTorrents
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}categories[]={{.}}&{{end}}"
|
||||
search: "{{ .Keywords }}"
|
||||
uploader: ""
|
||||
sorting: created_at
|
||||
direction: desc
|
||||
qty: 100
|
||||
rows:
|
||||
selector: table > tbody > tr
|
||||
fields:
|
||||
category:
|
||||
selector: a[href*="/categories/"]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: regexp
|
||||
args: "/categories/.*?\\.(\\d+)"
|
||||
title:
|
||||
selector: a.view-torrent
|
||||
download:
|
||||
selector: a[href*="/download/"]
|
||||
attribute: href
|
||||
details:
|
||||
selector: a.view-torrent
|
||||
attribute: href
|
||||
size:
|
||||
selector: td:nth-child(4)
|
||||
seeders:
|
||||
selector: td:nth-child(6)
|
||||
leechers:
|
||||
selector: td:nth-child(7)
|
||||
grabs:
|
||||
selector: td:nth-child(5)
|
||||
filters:
|
||||
- name: regexp
|
||||
args: ([\d\.]+)
|
||||
date:
|
||||
selector: time
|
||||
filters:
|
||||
# translations for Turkish|Estonian|Danish|Italian|Polish|Norwegian|Portoguese|Czech|Russian|Romanian|Spanish|French|German|Bulgarian|Dutch
|
||||
- name: re_replace
|
||||
args: ["(önce|tagasi|geleden|fa|temu|siden|atrás|nazpět|назад|acum|hace|il y a|vor|преди)", "ago"]
|
||||
- name: re_replace
|
||||
args: ["(dakika|minut|minuto|minuta|minutt|минута|Minute|minuut)", "minute"]
|
||||
- name: re_replace
|
||||
args: ["(dakika|minutit|minutter|minuti|minuty|minutos|минуты|минут|Minuten|минути|minuten)", "minutes"]
|
||||
- name: re_replace
|
||||
args: ["(saat|tund|time|ora|godzina|hora|hodina|час|oră|heure|Stunde|uur)", "hour"]
|
||||
- name: re_replace
|
||||
args: ["(saat|tundi|timer|ore|godziny|horas|hodiny|hoden|часа|часов|ore|heures|Stunden)", "hours"]
|
||||
- name: re_replace
|
||||
args: ["(gün|päev|dag|giorno|dzień|dia|den|день|zi|día|jour|Tag|ден)", "day"]
|
||||
- name: re_replace
|
||||
args: ["(gün|päeva|dage|giorni|dni|dias|dny|дня|дней|zile|días|jours|Tagen|дни|dagen)", "days"]
|
||||
- name: re_replace
|
||||
args: ["(hafta|nädal|uge|settimana|tydzień|uke|semana|týden|неделю|săptămână|semaine|Woche|седмица)", "week"]
|
||||
- name: re_replace
|
||||
args: ["(hafta|nädalat|uger|settimane|tygodnie|uker|semanas|týdny|недели|недель|săptămâni|semaines|Wochen|седмици|weken)", "weeks"]
|
||||
- name: re_replace
|
||||
args: ["(ay|kuu|måned|mese|miesiąc|mês|měsíc|месяц|lună|mes|mois|Monat|месец|maand)", "month"]
|
||||
- name: re_replace
|
||||
args: ["(ay|kuud|måneder|mesi|miesiące|meses|měsíce|месяца|месяцев|luni|meses|mois|Monaten|месеца|maanden)", "months"]
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
"i[data-original-title=\"100% Free\"]": "0"
|
||||
"i[data-original-title=\"Global FreeLeech\"]": "0"
|
||||
"*": "1"
|
||||
uploadvolumefactor:
|
||||
case:
|
||||
"i[data-original-title=\"Double Upload\"]": "2" # global flag
|
||||
"i[data-original-title=\"Double upload\"]": "2" # torrent specific flag
|
||||
"*": "1"
|
||||
81
src/Jackett.Common/Definitions/rockbox.yml
Normal file
81
src/Jackett.Common/Definitions/rockbox.yml
Normal file
@@ -0,0 +1,81 @@
|
||||
---
|
||||
site: RockBox
|
||||
name: RockBox Rock/Metal Tracker
|
||||
description: "RockBox Semi-Private site dedicated to HEAVY METAL/ROCK MUSIC. This definition is for the English site."
|
||||
language: en-us
|
||||
type: semi-private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://rawkbawx.rocks/
|
||||
|
||||
caps:
|
||||
categories:
|
||||
"Music": Audio
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
music-search: [q, album, artist, label, year]
|
||||
|
||||
login:
|
||||
path: login.php
|
||||
method: form
|
||||
form: form[action="login.php?returnto=index.php"]
|
||||
inputs:
|
||||
uid: "{{ .Config.username }}"
|
||||
pwd: "{{ .Config.password }}"
|
||||
error:
|
||||
- selector: div.errorSummary
|
||||
message:
|
||||
selector: div.errorSummary ul li
|
||||
test:
|
||||
path: index.php
|
||||
selector: a[href="logout.php"]
|
||||
|
||||
search:
|
||||
paths:
|
||||
- path: torrents.php
|
||||
method: get
|
||||
inputs:
|
||||
search: "{{if .Query.Artist}}{{ .Query.Artist }}{{else}}{{ .Keywords }}{{end}}"
|
||||
rows:
|
||||
selector: body:nth-child(2) tbody tr td:nth-child(2) table.lista tbody tr:nth-child(2) table.lista tbody tr:has(a[href^="download.php?id="])
|
||||
fields:
|
||||
title:
|
||||
selector: td a[href^="details.php?id="]
|
||||
details:
|
||||
selector: td a[href^="details.php?id="]
|
||||
attribute: href
|
||||
comments:
|
||||
selector: td a[href^="details.php?id="]
|
||||
attribute: href
|
||||
download:
|
||||
selector: td a[href^="download.php?id="]
|
||||
attribute: href
|
||||
# dates come in two flavours:
|
||||
date:
|
||||
# 13/10/2018
|
||||
selector: td:nth-child(6):contains("/")
|
||||
optional: true
|
||||
filters:
|
||||
- name: dateparse
|
||||
args: "02/01/2006"
|
||||
date:
|
||||
# 1 hour ago, 2 days ago, 3 weeks ago etc
|
||||
selector: td:nth-child(6):not(:contains("/"))
|
||||
optional: true
|
||||
filters:
|
||||
- name: timeago
|
||||
size:
|
||||
selector: td:nth-child(7)
|
||||
seeders:
|
||||
selector: td:nth-child(9)
|
||||
leechers:
|
||||
selector: td:nth-child(10)
|
||||
grabs:
|
||||
selector: td:nth-child(11)
|
||||
category:
|
||||
text: "Music"
|
||||
downloadvolumefactor:
|
||||
text: "1"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
||||
@@ -71,6 +71,7 @@
|
||||
pwd: "{{ .Config.password }}"
|
||||
error:
|
||||
- selector: div.error
|
||||
- selector: body:has(h1:contains("403 Forbidden")) # for banned IP notices
|
||||
test:
|
||||
path: /index.php
|
||||
selector: a[href="logout.php"]
|
||||
@@ -99,7 +100,7 @@
|
||||
selector: a[href^="download.php?id="]
|
||||
attribute: href
|
||||
title: # shortened title?
|
||||
selector: a[href^="index.php?page=torrent-details"]
|
||||
selector: td:nth-child(2)
|
||||
filters:
|
||||
- name: re_replace # replace special characters with " " (space)
|
||||
args: ["[^a-zA-Z0-9\\s]|\\.", " "]
|
||||
@@ -124,7 +125,7 @@
|
||||
args: ["(?i)(Serie completa|Completat?a?|in pausa)", ""]
|
||||
title: # long titles?
|
||||
optional: true
|
||||
selector: a[title][href^="index.php?page=torrent-details"]
|
||||
selector: td:nth-child(2)
|
||||
attribute: title
|
||||
filters:
|
||||
- name: re_replace # replace special characters with " " (space)
|
||||
@@ -149,7 +150,7 @@
|
||||
- name: re_replace # rimozioni varie
|
||||
args: ["(?i)(Serie completa|Completat?a?|in pausa)", ""]
|
||||
category:
|
||||
selector: a[href^="index.php?page=torrents&category="]
|
||||
selector: td:nth-child(1) a[href^="index.php?page=torrents&category="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
@@ -165,21 +166,21 @@
|
||||
- name: regexp
|
||||
args: "src=(.+?) "
|
||||
size:
|
||||
selector: td:nth-child(10)
|
||||
selector: td:nth-last-child(3)
|
||||
date:
|
||||
selector: td:nth-child(5)
|
||||
selector: td:nth-last-child(7)
|
||||
filters:
|
||||
- name: dateparse
|
||||
args: "02/01/2006"
|
||||
grabs:
|
||||
selector: td:nth-child(8)
|
||||
selector: td:nth-last-child(4)
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["---", "0"]
|
||||
seeders:
|
||||
selector: td:nth-child(6)
|
||||
selector: td:nth-last-child(6)
|
||||
leechers:
|
||||
selector: td:nth-child(7)
|
||||
selector: td:nth-last-child(5)
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
img[alt="Free Leech"]: "0"
|
||||
|
||||
77
src/Jackett.Common/Definitions/skytorrentsclone.yml
Normal file
77
src/Jackett.Common/Definitions/skytorrentsclone.yml
Normal file
@@ -0,0 +1,77 @@
|
||||
---
|
||||
site: skytorrentsclone
|
||||
name: SkyTorrentsClone
|
||||
description: "SkyTorrents.lol is a Public SkyTorrents clone for TV / MOVIES / GENERAL"
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://www.skytorrents.lol/
|
||||
|
||||
caps:
|
||||
categories:
|
||||
# category=
|
||||
"album": Audio
|
||||
"ebook": Books
|
||||
"movie": Movies
|
||||
"show": TV
|
||||
# type=
|
||||
"audio": Audio
|
||||
"doc": Books
|
||||
"games": PC/Games
|
||||
"software": PC
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
settings: []
|
||||
|
||||
search:
|
||||
# https://www.skytorrents.lol/?query=mr+mercedes+s02e05&sort=created
|
||||
# https://www.skytorrents.lol/top100
|
||||
paths:
|
||||
- path: "{{ if .Keywords }}?query={{ .Keywords }}&sort=created{{else}}top100{{end}}"
|
||||
- path: "{{ if .Keywords }}?query={{ .Keywords }}&sort=created&page=2{{else}}{{end}}"
|
||||
- path: "{{ if .Keywords }}?query={{ .Keywords }}&sort=created&page=3{{else}}{{end}}"
|
||||
- path: "{{ if .Keywords }}?query={{ .Keywords }}&sort=created&page=4{{else}}{{end}}"
|
||||
rows:
|
||||
selector: tr.result
|
||||
fields:
|
||||
title:
|
||||
selector: td a
|
||||
category:
|
||||
# try category=
|
||||
optional: true
|
||||
selector: a.label[href*="category="]
|
||||
category:
|
||||
# try type=
|
||||
optional: true
|
||||
selector: a.label[href*="type="]
|
||||
details:
|
||||
selector: td a
|
||||
attribute: href
|
||||
download:
|
||||
selector: a[href^="//itorrents"]
|
||||
attribute: href
|
||||
magnet:
|
||||
selector: a[href^="magnet:?"]
|
||||
attribute: href
|
||||
size:
|
||||
selector: td:nth-child(2)
|
||||
files:
|
||||
selector: td:nth-child(3)
|
||||
date:
|
||||
# 20 Minutes ago
|
||||
selector: td:nth-child(4)
|
||||
filters:
|
||||
- name: timeago
|
||||
seeders:
|
||||
selector: td:nth-child(5)
|
||||
leechers:
|
||||
selector: td:nth-child(6)
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
||||
@@ -302,13 +302,24 @@
|
||||
- name: dateparse
|
||||
args: "02/01/2006 15:04:05"
|
||||
size:
|
||||
selector: td:nth-child(5)
|
||||
# seems size might be floating as the 4th or 5th td so lets try matching the size-unit
|
||||
optional: true
|
||||
selector: td.ttable_col2:contains(" GB")
|
||||
size:
|
||||
optional: true
|
||||
selector: td.ttable_col2:contains(" MB")
|
||||
size:
|
||||
optional: true
|
||||
selector: td.ttable_col2:contains(" kB")
|
||||
size:
|
||||
optional: true
|
||||
selector: td.ttable_col2:contains(" B")
|
||||
grabs:
|
||||
selector: font[color^=orange]
|
||||
selector: td.ttable_col1 > font[color^=orange]
|
||||
seeders:
|
||||
selector: font[color^=green]
|
||||
selector: td.ttable_col1 > b > font[color^=green]
|
||||
leechers:
|
||||
selector: td.ttable_col1 > font[color^=red]
|
||||
selector: td.ttable_col2 > font[color^=red]
|
||||
downloadvolumefactor:
|
||||
case:
|
||||
img[src="images/free.gif"]: "0"
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
- {id: 399, cat: PC, desc: "Other OS", default: true}
|
||||
|
||||
#Games
|
||||
- {id: 401, cat: Console, desc: "Games", default: true}
|
||||
- {id: 400, cat: Console, desc: "Games", default: true}
|
||||
- {id: 401, cat: PC/Games, desc: "PC", default: true}
|
||||
- {id: 402, cat: PC/Mac, desc: "Mac", default: true}
|
||||
- {id: 403, cat: Console/PS4, desc: "PSx", default: true}
|
||||
|
||||
60
src/Jackett.Common/Definitions/torrentcouch.yml
Normal file
60
src/Jackett.Common/Definitions/torrentcouch.yml
Normal file
@@ -0,0 +1,60 @@
|
||||
---
|
||||
site: torrentcouch
|
||||
name: TorrentCouch
|
||||
description: "TorrentCounch is a Public TV tracker"
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://torrentcouch.net/
|
||||
legacylinks:
|
||||
- https://torrentcouch.com/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 1, cat: TV, desc: "TV"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
|
||||
settings: []
|
||||
|
||||
download:
|
||||
selector: tr td a[href*="/files/download/"]
|
||||
|
||||
search:
|
||||
# https://torrentcouch.com/?s=expanse
|
||||
# https://torrentcouch.net/page/3/?s=expanse
|
||||
paths:
|
||||
- path: "{{if .Keywords}}/?s={{ .Keywords}}{{else}}/{{end}}"
|
||||
- path: "{{if .Keywords}}/page/2/?s={{ .Keywords}}{{else}}{{end}}"
|
||||
- path: "{{if .Keywords}}/page/3/?s={{ .Keywords}}{{else}}{{end}}"
|
||||
- path: "{{if .Keywords}}/page/4/?s={{ .Keywords}}{{else}}{{end}}"
|
||||
rows:
|
||||
selector: article
|
||||
fields:
|
||||
title:
|
||||
selector: h2 a
|
||||
category:
|
||||
text: "1"
|
||||
details:
|
||||
selector: h2 a
|
||||
attribute: href
|
||||
description:
|
||||
selector: p
|
||||
download:
|
||||
selector: h2 a
|
||||
attribute: href
|
||||
size:
|
||||
text: "500 MB"
|
||||
seeders:
|
||||
text: "1"
|
||||
leechers:
|
||||
text: "1"
|
||||
date:
|
||||
text: now
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
||||
108
src/Jackett.Common/Definitions/torrentgalaxyorg.yml
Normal file
108
src/Jackett.Common/Definitions/torrentgalaxyorg.yml
Normal file
@@ -0,0 +1,108 @@
|
||||
---
|
||||
site: torrentgalaxyorg
|
||||
name: TorrentGalaxy.org
|
||||
description: "TorrentGalaxy.org (TGx) is a Public site for TV / MOVIES / GENERAL"
|
||||
language: en-us
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://torrentgalaxy.org/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: 28, cat: TV/Anime, desc: "Anime - All"}
|
||||
- {id: 20, cat: PC/Phone-Other, desc: "Apps - Mobile"}
|
||||
- {id: 19, cat: PC/Mac, desc: "Apps - OS"}
|
||||
- {id: 21, cat: PC, desc: "Apps - Other"}
|
||||
- {id: 18, cat: PC/0day, desc: "Apps - Windows"}
|
||||
- {id: 13, cat: Audio/Audiobook, desc: "Books - Audiobooks"}
|
||||
- {id: 12, cat: Books/Ebook, desc: "Books - Ebooks"}
|
||||
- {id: 14, cat: Books/Technical, desc: "Books - Education"}
|
||||
- {id: 15, cat: Books/Magazines, desc: "Books - Magazine"}
|
||||
- {id: 9, cat: TV/Documentary, desc: "Documentaries - All"}
|
||||
- {id: 11, cat: Console, desc: "Games - Console"}
|
||||
- {id: 43, cat: PC/Phone-Other, desc: "Games - Mobile"}
|
||||
- {id: 17, cat: Console/Other, desc: "Games - Other"}
|
||||
- {id: 10, cat: PC/Games , desc: "Games - Windows"}
|
||||
- {id: 3, cat: Movies/UHD, desc: "Movies - 2K/4K UHD"}
|
||||
- {id: 46, cat: Movies/Foreign, desc: "Movies - Bollywood"}
|
||||
- {id: 45, cat: Movies/Other, desc: "Movies - CAM/TS"}
|
||||
- {id: 42, cat: Movies/HD, desc: "Movies - HD"}
|
||||
- {id: 4, cat: Movies, desc: "Movies - Packs"}
|
||||
- {id: 1, cat: Movies/SD, desc: "Movies - SD"}
|
||||
- {id: 22, cat: Audio, desc: "Music - Albums"}
|
||||
- {id: 26, cat: Audio, desc: "Music - Discography"}
|
||||
- {id: 23, cat: Audio/Lossless, desc: "Music - Lossless"}
|
||||
- {id: 25, cat: Audio/Video, desc: "Music - Musicvideo"}
|
||||
- {id: 24, cat: Audio, desc: "Music - Singles"}
|
||||
- {id: 40, cat: Audio/Other, desc: "Other - Other"}
|
||||
- {id: 37, cat: Other, desc: "Other - Pictures"}
|
||||
- {id: 33, cat: Other, desc: "Other - Training"}
|
||||
- {id: 41, cat: TV/HD, desc: "TV - Episodes HD"}
|
||||
- {id: 5, cat: TV/SD, desc: "TV - Episodes SD"}
|
||||
- {id: 6, cat: TV/OTHER, desc: "TV - Packs"}
|
||||
- {id: 7, cat: TV/Sport, desc: "TV - Sports"}
|
||||
- {id: 35, cat: XXX, desc: "XXX - HD"}
|
||||
- {id: 47, cat: XXX, desc: "XXX - Misc"}
|
||||
- {id: 34, cat: XXX, desc: "XXX - SD"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q, season, ep]
|
||||
movie-search: [q]
|
||||
|
||||
settings: []
|
||||
|
||||
search:
|
||||
# https://torrentgalaxy.org/torrents.php?c41=1&search=mercedes+s02e04&lang=0&sort=id&order=desc
|
||||
path: torrents.php
|
||||
inputs:
|
||||
$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
|
||||
search: "{{.Keywords}}"
|
||||
lang: "0"
|
||||
sort: "id"
|
||||
order: "desc"
|
||||
rows:
|
||||
selector: div[class="tgxtablerow clickable-row click"]
|
||||
fields:
|
||||
title:
|
||||
selector: div.tgxtablecell:nth-child(3) div a
|
||||
attribute: title
|
||||
category:
|
||||
selector: div.tgxtablecell a
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: cat
|
||||
details:
|
||||
selector: div.tgxtablecell:nth-child(3) div a
|
||||
attribute: href
|
||||
download:
|
||||
selector: div.tgxtablecell:nth-child(4) a
|
||||
attribute: href
|
||||
magnet:
|
||||
selector: div.tgxtablecell:nth-child(4) a:nth-child(2)
|
||||
attribute: href
|
||||
size:
|
||||
selector: div.tgxtablecell:nth-child(7) span
|
||||
seeders:
|
||||
selector: div.tgxtablecell:nth-child(10) span font b
|
||||
leechers:
|
||||
selector: div.tgxtablecell:nth-child(10) span font:nth-child(2) b
|
||||
date:
|
||||
# 20Mins ago
|
||||
optional: true
|
||||
selector: div.tgxtablecell:nth-child(11) small:contains("ago")
|
||||
filters:
|
||||
- name: timeago
|
||||
date:
|
||||
# 24/12/18 13:55
|
||||
optional: true
|
||||
selector: div.tgxtablecell:nth-child(11) small:contains(":")
|
||||
filters:
|
||||
- name: dateparse
|
||||
args: "02/01/06 15:04"
|
||||
downloadvolumefactor:
|
||||
text: "0"
|
||||
uploadvolumefactor:
|
||||
text: "1"
|
||||
@@ -1,66 +0,0 @@
|
||||
---
|
||||
site: torrentkim
|
||||
name: TorrentKim
|
||||
description: "TorrentKim is a free Korean tracker of pretty much anything Korean."
|
||||
language: ko-KR
|
||||
type: public
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://torrentkim.pro/
|
||||
legacylinks:
|
||||
- https://torrentkim12.com/
|
||||
- https://torrentkim10.net/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
- {id: "torrent_variety", cat: TV, desc: "TV - Variety shows"}
|
||||
- {id: "torrent_tv", cat: TV, desc: "TV - Dramas"}
|
||||
- {id: "torrent_mid", cat: TV/FOREIGN, desc: "TV - American Series"}
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
tv-search: [q]
|
||||
movie-search: [q]
|
||||
|
||||
settings: []
|
||||
|
||||
search:
|
||||
paths:
|
||||
- path: "{{ if .Keywords }}/bbs/s-1-{{ .Keywords }}{{else}}/bbs/s-1-미운우리새끼{{end}}"
|
||||
rows:
|
||||
selector: "table.board_list > tbody > tr.bg1:nth-child(n+3)"
|
||||
fields:
|
||||
magnet:
|
||||
selector: td:nth-child(1) a[href^="javascript:"]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: replace
|
||||
args: ["javascript:Mag_dn('", ""]
|
||||
- name: replace
|
||||
args: ["')", ""]
|
||||
- name: prepend
|
||||
args: "magnet:?xt=urn:btih:"
|
||||
seeders:
|
||||
selector: "td:nth-child(2) font:nth-child(2)"
|
||||
leechers:
|
||||
selector: "td:nth-child(2) font:nth-child(1)"
|
||||
category:
|
||||
selector: td:nth-child(3) a[href^="/bbs/bc.php?bo_table="]
|
||||
attribute: href
|
||||
filters:
|
||||
- name: querystring
|
||||
args: bo_table
|
||||
title:
|
||||
selector: td:nth-child(3) a:last-of-type
|
||||
details:
|
||||
selector: td:nth-child(3) a:last-of-type
|
||||
attribute: href
|
||||
date:
|
||||
selector: td:nth-child(3) a:last-of-type
|
||||
filters:
|
||||
- name: split
|
||||
args: ['.', 2]
|
||||
- name: dateparse
|
||||
args: "060102"
|
||||
size:
|
||||
selector: td:nth-child(5)
|
||||
@@ -69,11 +69,8 @@
|
||||
paths:
|
||||
- path: "{{if .Config.filter-verified }}verified{{else}}searchA{{end}}"
|
||||
inputs:
|
||||
f: "{{ .Keywords }}"
|
||||
f: "{{if .Keywords }}title: {{else}}{{end}}{{ .Keywords }}"
|
||||
safe: "{{if .Config.filter-safe }}1{{else}}0{{end}}"
|
||||
keywordsfilters:
|
||||
- name: prepend
|
||||
args: "title: " # search only in title, https://torrentz2.eu/help
|
||||
rows:
|
||||
selector: "html body #wrap .results dl:has(a)"
|
||||
# andmatch filter removed, see #3737
|
||||
|
||||
@@ -62,6 +62,9 @@
|
||||
search:
|
||||
paths:
|
||||
- path: torrents.php
|
||||
keywordsfilters:
|
||||
- name: re_replace
|
||||
args: ["S(\\d{2})E(\\d{2})", "$1 $2"]
|
||||
inputs:
|
||||
search: "{{ .Keywords }}"
|
||||
category: "0"
|
||||
|
||||
@@ -6,15 +6,18 @@
|
||||
type: semi-private
|
||||
encoding: UTF-8
|
||||
links:
|
||||
- https://www.yggtorrent.is/
|
||||
- https://www6.yggtorrent.to/
|
||||
legacylinks:
|
||||
- https://yggtorrent.is/
|
||||
- https://yggtorrent.com/
|
||||
- https://ww1.yggtorrent.com/
|
||||
- https://www.yggtorrent.is/
|
||||
- https://ww1.yggtorrent.is/
|
||||
- https://ww2.yggtorrent.is/
|
||||
- https://ww3.yggtorrent.is/
|
||||
- https://ww4.yggtorrent.is/
|
||||
- https://yggtorrent.to/
|
||||
- https://www3.yggtorrent.to/
|
||||
|
||||
caps:
|
||||
categorymappings:
|
||||
@@ -113,10 +116,17 @@
|
||||
FRENCH : "FRENCH"
|
||||
MULTI.FRENCH: "MULTI.FRENCH"
|
||||
ENGLISH: "ENGLISH"
|
||||
MULTI.ENGLISH: "MULTI.ENGLISH"
|
||||
VOSTFR: "VOSTFR"
|
||||
MULTI.VOSTFR: "MULTI.VOSTFR"
|
||||
- name: vostfr
|
||||
type: checkbox
|
||||
label: Replace VOSTFR with ENGLISH
|
||||
default: false
|
||||
login:
|
||||
method: form
|
||||
path: /
|
||||
form: form[action$="/user/login"]
|
||||
form: "#user-login"
|
||||
inputs:
|
||||
id: "{{ .Config.username }}"
|
||||
pass: "{{ .Config.password }}"
|
||||
@@ -129,8 +139,8 @@
|
||||
|
||||
search:
|
||||
paths:
|
||||
- path: "/engine/search?category={{ .Config.category }}&name={{ .Keywords }}&description=&file=&uploader=&sub_category=&do=search"
|
||||
- path: "/engine/search?category={{ .Config.category }}&name={{ .Keywords }}&description=&file=&uploader=&sub_category=&do=search&page=50"
|
||||
- path: "/engine/search?category={{ .Config.category }}&name={{ .Keywords }}&description=&file=&uploader=&sub_category=&do=search&order=desc&sort=publish_date"
|
||||
- path: "/engine/search?category={{ .Config.category }}&name={{ .Keywords }}&description=&file=&uploader=&sub_category=&do=search&order=desc&sort=publish_date&page=50"
|
||||
|
||||
rows:
|
||||
selector: "table.table > tbody > tr"
|
||||
@@ -163,8 +173,15 @@
|
||||
filters:
|
||||
- name: re_replace
|
||||
args: ["[\\.\\s\\[\\-][Mm][Uu][Ll][Tt][Ii][\\.\\s\\]\\-]", ".{{ .Config.multilanguage }}."]
|
||||
title:
|
||||
title_phase2:
|
||||
text: "{{if .Config.multilang }}{{ .Result.title_multilang }}{{else}}{{ .Result.title_phase1 }}{{end}}"
|
||||
title_vostfr:
|
||||
text: "{{ .Result.title_phase2 }}"
|
||||
filters:
|
||||
- name: re_replace
|
||||
args: ["[\\.\\s\\[\\-][Vv][Oo][Ss][Tt][Ff][Rr][\\.\\s\\]\\-]", ".ENGLISH."]
|
||||
title:
|
||||
text: "{{if .Config.vostfr }}{{ .Result.title_vostfr }}{{else}}{{ .Result.title_phase2 }}{{end}}"
|
||||
details:
|
||||
selector: ":nth-child(2) > a"
|
||||
attribute: href
|
||||
|
||||
@@ -20,6 +20,11 @@
|
||||
20: Movies/DVD
|
||||
9: XXX
|
||||
49: XXX/Other
|
||||
6: Audio
|
||||
30: Audio/Other
|
||||
29: Audio/Other
|
||||
51: Audio/Other
|
||||
34: Audio/Lossless
|
||||
|
||||
modes:
|
||||
search: [q]
|
||||
|
||||
@@ -13,10 +13,11 @@
|
||||
"anime": TV/Anime
|
||||
"app": PC
|
||||
"book": Books
|
||||
"files": Other/Misc
|
||||
"game": PC/Games
|
||||
"movies": Movies
|
||||
"music": Audio
|
||||
"other": Other/Misc
|
||||
"other": Other
|
||||
"tv": TV
|
||||
|
||||
modes:
|
||||
|
||||
@@ -193,7 +193,7 @@ namespace Jackett.Common.Indexers
|
||||
var DetailsResultDocument = ResultParser.Parse(detailsResult.Content);
|
||||
var qDownloadLink = DetailsResultDocument.QuerySelector("table.table2 > tbody > tr > td > a[href^=\"/download/torrent.php?id\"]");
|
||||
|
||||
release.Link = new Uri(SiteLink + qDownloadLink.GetAttribute("href"));
|
||||
release.Link = new Uri(SiteLink + qDownloadLink.GetAttribute("href").TrimStart('/'));
|
||||
|
||||
release.Seeders = ParseUtil.CoerceInt(Row.QuerySelector("span.seed").TextContent);
|
||||
release.Peers = ParseUtil.CoerceInt(Row.QuerySelector("span.leech").TextContent) + release.Seeders;
|
||||
@@ -214,6 +214,10 @@ namespace Jackett.Common.Indexers
|
||||
size = size.Replace("MiB", "MB");
|
||||
size = size.Replace("KiB", "KB");
|
||||
|
||||
size = size.Replace("ГБ", "GB");
|
||||
size = size.Replace("МБ", "MB");
|
||||
size = size.Replace("КБ", "KB");
|
||||
|
||||
release.Size = ReleaseInfo.GetBytes(size);
|
||||
|
||||
release.DownloadVolumeFactor = 1;
|
||||
|
||||
@@ -10,7 +10,6 @@ using NLog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static Jackett.Common.Models.IndexerConfig.ConfigurationData;
|
||||
@@ -177,10 +176,9 @@ namespace Jackett.Common.Indexers
|
||||
//TODO: Remove this section once users have moved off DPAPI
|
||||
private bool MigratedFromDPAPI(JToken jsonConfig)
|
||||
{
|
||||
bool runningOnDotNetCore = RuntimeInformation.FrameworkDescription.IndexOf("core", StringComparison.OrdinalIgnoreCase) >= 0;
|
||||
bool isWindows = Environment.OSVersion.Platform == PlatformID.Win32NT;
|
||||
|
||||
if (!isWindows && runningOnDotNetCore)
|
||||
if (!isWindows && DotNetCoreUtil.IsRunningOnDotNetCore)
|
||||
{
|
||||
// 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;
|
||||
@@ -575,6 +573,11 @@ namespace Jackett.Common.Indexers
|
||||
{
|
||||
throw new Exception("Request to " + response.Request.Url + " failed (Error " + response.Status + ") - The tracker seems to be down.");
|
||||
}
|
||||
|
||||
if (response.Status == System.Net.HttpStatusCode.Forbidden && response.Content.Contains("<span data-translate=\"complete_sec_check\">Please complete the security check to access</span>"))
|
||||
{
|
||||
throw new Exception("Request to " + response.Request.Url + " failed (Error " + response.Status + ") - The page is protected by an Cloudflare reCaptcha. The page is in aggressive DDoS mitigation mode or your IP might be blacklisted (e.g. in case of shared VPN IPs). There's no easy way of making it usable with Jackett.");
|
||||
}
|
||||
}
|
||||
|
||||
protected async Task FollowIfRedirect(WebClientStringResult response, string referrer = null, string overrideRedirectUrl = null, string overrideCookies = null, bool accumulateCookies = false)
|
||||
|
||||
@@ -164,7 +164,7 @@ namespace Jackett.Common.Indexers
|
||||
var grabs = qRow.Find("td:nth-child(9) > a").Get(0).FirstChild.ToString();
|
||||
release.Grabs = ParseUtil.CoerceInt(grabs);
|
||||
|
||||
release.DownloadVolumeFactor = 0; // ratioless
|
||||
release.DownloadVolumeFactor = 1;
|
||||
release.UploadVolumeFactor = 1;
|
||||
|
||||
releases.Add(release);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
@@ -133,6 +133,18 @@ namespace Jackett.Common.Indexers
|
||||
CQ dom = results.Content;
|
||||
ReleaseInfo release;
|
||||
|
||||
CQ userInfo = dom[".mainmenu > table > tbody > tr:has(td[title=\"Active-Torrents\"])"][0].Cq();
|
||||
string rank = userInfo.Find("td:nth-child(2)").Text().Substring(6);
|
||||
|
||||
HashSet<string> freeleechRanks = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
freeleechRanks.Add("VIP");
|
||||
freeleechRanks.Add("Uploader");
|
||||
freeleechRanks.Add("HD Internal");
|
||||
freeleechRanks.Add("Moderator");
|
||||
freeleechRanks.Add("Administrator");
|
||||
freeleechRanks.Add("Owner");
|
||||
bool hasFreeleech = freeleechRanks.Contains(rank);
|
||||
|
||||
var rows = dom[".mainblockcontenttt > tbody > tr:has(a[href^=\"details.php?id=\"])"];
|
||||
foreach (var row in rows)
|
||||
{
|
||||
@@ -155,19 +167,22 @@ namespace Jackett.Common.Indexers
|
||||
|
||||
release.MinimumRatio = 1;
|
||||
release.MinimumSeedTime = 172800;
|
||||
|
||||
int tdIndex = 0;
|
||||
if(qRow.Find("td:nth-last-child(1)").Text() == "Edit") tdIndex = 1;
|
||||
|
||||
// Sometimes the uploader column is missing
|
||||
int seeders, peers;
|
||||
if (ParseUtil.TryCoerceInt(qRow.Find("td:nth-last-child(3)").Text(), out seeders))
|
||||
if (ParseUtil.TryCoerceInt(qRow.Find($"td:nth-last-child({tdIndex + 3})").Text(), out seeders))
|
||||
{
|
||||
release.Seeders = seeders;
|
||||
if (ParseUtil.TryCoerceInt(qRow.Find("td:nth-last-child(2)").Text(), out peers))
|
||||
if (ParseUtil.TryCoerceInt(qRow.Find($"td:nth-last-child({tdIndex + 2})").Text(), out peers))
|
||||
{
|
||||
release.Peers = peers + release.Seeders;
|
||||
}
|
||||
}
|
||||
|
||||
release.Grabs = ParseUtil.CoerceLong(qRow.Find("td:nth-last-child(1)").Text());
|
||||
release.Grabs = ParseUtil.CoerceLong(qRow.Find($"td:nth-last-child({tdIndex + 1})").Text());
|
||||
|
||||
string fullSize = qRow.Find("td.mainblockcontent").Get(6).InnerText;
|
||||
release.Size = ReleaseInfo.GetBytes(fullSize);
|
||||
@@ -190,6 +205,8 @@ namespace Jackett.Common.Indexers
|
||||
release.DownloadVolumeFactor = 0;
|
||||
release.UploadVolumeFactor = 0;
|
||||
}
|
||||
else if(hasFreeleech)
|
||||
release.DownloadVolumeFactor = 0;
|
||||
else if (qRow.Find("img[alt=\"Silver Torrent\"]").Length >= 1)
|
||||
release.DownloadVolumeFactor = 0.5;
|
||||
else if (qRow.Find("img[alt=\"Bronze Torrent\"]").Length >= 1)
|
||||
|
||||
304
src/Jackett.Common/Indexers/HorribleSubs.cs
Normal file
304
src/Jackett.Common/Indexers/HorribleSubs.cs
Normal file
@@ -0,0 +1,304 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Jackett.Common.Models;
|
||||
using Jackett.Common.Models.IndexerConfig;
|
||||
using Jackett.Common.Services.Interfaces;
|
||||
using Jackett.Common.Utils;
|
||||
using Jackett.Common.Utils.Clients;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
using System.Text.RegularExpressions;
|
||||
using AngleSharp.Parser.Html;
|
||||
|
||||
namespace Jackett.Common.Indexers
|
||||
{
|
||||
class HorribleSubs : BaseWebIndexer
|
||||
{
|
||||
private string ApiEndpoint { get { return SiteLink + "api.php"; } }
|
||||
|
||||
public override string[] LegacySiteLinks { get; protected set; } = new string[] {
|
||||
"http://horriblesubs.info/"
|
||||
};
|
||||
|
||||
public HorribleSubs(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps)
|
||||
: base(name: "Horrible Subs",
|
||||
description: "HorribleSubs - So bad yet so good",
|
||||
link: "https://horriblesubs.info/",
|
||||
caps: new TorznabCapabilities(TorznabCatType.TVAnime),
|
||||
configService: configService,
|
||||
client: wc,
|
||||
logger: l,
|
||||
p: ps,
|
||||
configData: new ConfigurationData())
|
||||
{
|
||||
Encoding = Encoding.UTF8;
|
||||
Language = "en-us";
|
||||
Type = "public";
|
||||
}
|
||||
|
||||
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
var releases = await PerformQuery(new TorznabQuery());
|
||||
|
||||
await ConfigureIfOK(string.Empty, releases.Count() > 0, () =>
|
||||
{
|
||||
throw new Exception("Could not find releases from this URL");
|
||||
});
|
||||
|
||||
return IndexerConfigurationStatus.Completed;
|
||||
}
|
||||
|
||||
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||
{
|
||||
return await PerformQuery(query, 0);
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<ReleaseInfo>> PerformLatestQuery(TorznabQuery query, int attempts)
|
||||
{
|
||||
var ResultParser = new HtmlParser();
|
||||
var releases = new List<ReleaseInfo>();
|
||||
var searchString = query.GetQueryString();
|
||||
var queryCollection = new NameValueCollection();
|
||||
|
||||
queryCollection.Add("method", "getlatest");
|
||||
|
||||
var searchUrl = ApiEndpoint + "?" + queryCollection.GetQueryString();
|
||||
var response = await RequestStringWithCookiesAndRetry(searchUrl, string.Empty);
|
||||
|
||||
try
|
||||
{
|
||||
if (response.Content.Contains("Nothing was found"))
|
||||
{
|
||||
return releases.ToArray();
|
||||
}
|
||||
|
||||
var dom = ResultParser.Parse(response.Content);
|
||||
var latestresults = dom.QuerySelectorAll("ul > li > a");
|
||||
foreach (var row in latestresults)
|
||||
{
|
||||
var href = SiteLink + row.Attributes["href"].Value.Substring(1);
|
||||
var showrels = await GetRelease(href);
|
||||
releases.AddRange(showrels);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(response.Content, ex);
|
||||
}
|
||||
|
||||
return releases;
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<ReleaseInfo>> GetRelease(string ResultURL)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
var ResultParser = new HtmlParser();
|
||||
try
|
||||
{
|
||||
var episodeno = ResultURL.Substring(ResultURL.LastIndexOf("#") + 1); // = 71
|
||||
ResultURL = ResultURL.Replace("#" + episodeno, ""); // = https://horriblesubs.info/shows/boruto-naruto-next-generations
|
||||
|
||||
var showPageResponse = await RequestStringWithCookiesAndRetry(ResultURL, string.Empty);
|
||||
await FollowIfRedirect(showPageResponse);
|
||||
|
||||
Match match = Regex.Match(showPageResponse.Content, "(var hs_showid = )([0-9]*)(;)", RegexOptions.IgnoreCase);
|
||||
if (match.Success == false)
|
||||
{
|
||||
return releases;
|
||||
}
|
||||
|
||||
int ShowID = int.Parse(match.Groups[2].Value);
|
||||
|
||||
string showAPIURL = ApiEndpoint + "?method=getshows&type=show&showid=" + ShowID; //https://horriblesubs.info/api.php?method=getshows&type=show&showid=869
|
||||
var showAPIResponse = await RequestStringWithCookiesAndRetry(showAPIURL, string.Empty);
|
||||
|
||||
|
||||
var showAPIdom = ResultParser.Parse(showAPIResponse.Content);
|
||||
var releaserows = showAPIdom.QuerySelectorAll("div.rls-info-container");
|
||||
|
||||
foreach (var releaserow in releaserows)
|
||||
{
|
||||
string dateStr = releaserow.QuerySelector(".rls-date").TextContent.Trim();
|
||||
string title = releaserow.FirstChild.TextContent;
|
||||
title = title.Replace("SD720p1080p", "");
|
||||
title = title.Replace(dateStr, "");
|
||||
|
||||
if (title.Contains(episodeno) == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ensure fansub group name is present in the title
|
||||
// This is needed for things like configuring tag restrictions in Sonarr
|
||||
if (title.Contains("[HorribleSubs]") == false)
|
||||
{
|
||||
title = "[HorribleSubs] " + title;
|
||||
}
|
||||
|
||||
DateTime releasedate;
|
||||
if (dateStr == "Today")
|
||||
{
|
||||
releasedate = DateTime.Today;
|
||||
}
|
||||
else if (dateStr == "Yesterday")
|
||||
{
|
||||
releasedate = DateTime.Today.AddDays(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
releasedate = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "MM/dd/yy", CultureInfo.InvariantCulture), DateTimeKind.Utc).ToLocalTime();
|
||||
}
|
||||
|
||||
var p480 = releaserow.QuerySelector(".link-480p");
|
||||
|
||||
if (p480 != null)
|
||||
{
|
||||
var release = new ReleaseInfo
|
||||
{
|
||||
PublishDate = releasedate,
|
||||
Files = 1,
|
||||
Category = new List<int> { TorznabCatType.TVAnime.ID },
|
||||
Size = 524288000,
|
||||
Seeders = 1,
|
||||
Peers = 2,
|
||||
DownloadVolumeFactor = 0,
|
||||
UploadVolumeFactor = 1
|
||||
};
|
||||
release.Title = string.Format("{0} [480p]", title);
|
||||
if (p480.QuerySelector(".hs-torrent-link > a") != null)
|
||||
{
|
||||
release.Link = new Uri(p480.QuerySelector(".hs-torrent-link > a").GetAttribute("href"));
|
||||
release.Guid = release.Link;
|
||||
}
|
||||
if (p480.QuerySelector(".hs-magnet-link > a") != null)
|
||||
{
|
||||
release.MagnetUri = new Uri(p480.QuerySelector(".hs-magnet-link > a").GetAttribute("href"));
|
||||
release.Guid = release.MagnetUri;
|
||||
}
|
||||
releases.Add(release);
|
||||
}
|
||||
|
||||
var p720 = releaserow.QuerySelector(".link-720p");
|
||||
|
||||
if (p720 != null)
|
||||
{
|
||||
var release = new ReleaseInfo
|
||||
{
|
||||
PublishDate = releasedate,
|
||||
Files = 1,
|
||||
Category = new List<int> { TorznabCatType.TVAnime.ID },
|
||||
Size = 524288000,
|
||||
Seeders = 1,
|
||||
Peers = 2,
|
||||
DownloadVolumeFactor = 0,
|
||||
UploadVolumeFactor = 1
|
||||
};
|
||||
release.Title = string.Format("{0} [720p]", title);
|
||||
if (p720.QuerySelector(".hs-torrent-link > a") != null)
|
||||
{
|
||||
release.Link = new Uri(p720.QuerySelector(".hs-torrent-link > a").GetAttribute("href"));
|
||||
release.Guid = release.Link;
|
||||
}
|
||||
if (p720.QuerySelector(".hs-magnet-link > a") != null)
|
||||
{
|
||||
release.MagnetUri = new Uri(p720.QuerySelector(".hs-magnet-link > a").GetAttribute("href"));
|
||||
release.Guid = release.MagnetUri;
|
||||
}
|
||||
releases.Add(release);
|
||||
}
|
||||
|
||||
var p1080 = releaserow.QuerySelector(".link-1080p");
|
||||
|
||||
if (p1080 != null)
|
||||
{
|
||||
var release = new ReleaseInfo
|
||||
{
|
||||
PublishDate = releasedate,
|
||||
Files = 1,
|
||||
Category = new List<int> { TorznabCatType.TVAnime.ID },
|
||||
Size = 524288000,
|
||||
Seeders = 1,
|
||||
Peers = 2,
|
||||
DownloadVolumeFactor = 0,
|
||||
UploadVolumeFactor = 1
|
||||
};
|
||||
release.Title = string.Format("{0} [1080p]", title);
|
||||
if (p1080.QuerySelector(".hs-torrent-link > a") != null)
|
||||
{
|
||||
release.Link = new Uri(p1080.QuerySelector(".hs-torrent-link > a").GetAttribute("href"));
|
||||
release.Guid = release.Link;
|
||||
}
|
||||
if (p1080.QuerySelector(".hs-magnet-link > a") != null)
|
||||
{
|
||||
release.MagnetUri = new Uri(p1080.QuerySelector(".hs-magnet-link > a").GetAttribute("href"));
|
||||
release.Guid = release.MagnetUri;
|
||||
}
|
||||
releases.Add(release);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError("", ex);
|
||||
}
|
||||
return releases;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query, int attempts)
|
||||
{
|
||||
var ResultParser = new HtmlParser();
|
||||
var releases = new List<ReleaseInfo>();
|
||||
var searchString = query.GetQueryString();
|
||||
var queryCollection = new NameValueCollection();
|
||||
|
||||
|
||||
if (string.IsNullOrWhiteSpace(searchString))
|
||||
{
|
||||
return await PerformLatestQuery(query, attempts);
|
||||
}
|
||||
else
|
||||
{
|
||||
queryCollection.Add("method", "search");
|
||||
|
||||
searchString = searchString.Replace("'", ""); // ignore ' (e.g. search for america's Next Top Model)
|
||||
queryCollection.Add("value", searchString);
|
||||
}
|
||||
|
||||
var searchUrl = ApiEndpoint + "?" + queryCollection.GetQueryString();
|
||||
var response = await RequestStringWithCookiesAndRetry(searchUrl, string.Empty);
|
||||
|
||||
try
|
||||
{
|
||||
if (response.Content.Contains("Nothing was found"))
|
||||
{
|
||||
return releases.ToArray();
|
||||
}
|
||||
var dom = ResultParser.Parse(response.Content);
|
||||
var showlinks = dom.QuerySelectorAll("ul > li > a");
|
||||
foreach (var showlink in showlinks)
|
||||
{
|
||||
var href = SiteLink + showlink.Attributes["href"].Value.Substring(1); // = https://horriblesubs.info/shows/boruto-naruto-next-generations#71
|
||||
|
||||
var showrels = await GetRelease(href);
|
||||
releases.AddRange(showrels);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(response.Content, ex);
|
||||
}
|
||||
|
||||
return releases;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,13 @@ namespace Jackett.Common.Indexers
|
||||
"http://ghost.cable-modem.org/",
|
||||
"http://logan.unusualperson.com/",
|
||||
"http://baywatch.workisboring.com/",
|
||||
"https://ipt.getcrazy.me",
|
||||
"https://ipt.findnemo.net",
|
||||
"https://ipt.beelyrics.net",
|
||||
"https://ipt.venom.global",
|
||||
"https://ipt.workisboring.net",
|
||||
"https://ipt.lol",
|
||||
|
||||
};
|
||||
|
||||
private new ConfigurationDataRecaptchaLogin configData
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace Jackett.Common.Indexers.Meta
|
||||
public async Task<IEnumerable<TorznabQuery>> FallbackQueries()
|
||||
{
|
||||
if (titles == null)
|
||||
titles = (await resolver.MovieForId(query.ImdbID.ToNonNull())).Title.ToEnumerable();
|
||||
titles = (await resolver.MovieForId(query.ImdbID.ToNonNull())).Title?.ToEnumerable() ?? Enumerable.Empty<string>();
|
||||
return titles.Select(t => query.CreateFallback(t));
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace Jackett.Common.Indexers.Meta
|
||||
|
||||
var remainingResults = results.Except(wrongResults).Except(perfectResults);
|
||||
|
||||
var titles = (await resolver.MovieForId(query.ImdbID.ToNonNull())).Title.ToEnumerable();
|
||||
var titles = (await resolver.MovieForId(query.ImdbID.ToNonNull())).Title?.ToEnumerable() ?? Enumerable.Empty<string>();
|
||||
var strippedTitles = titles.Select(t => RemoveSpecialChars(t));
|
||||
var normalizedTitles = strippedTitles.SelectMany(t => GenerateTitleVariants(t));
|
||||
|
||||
|
||||
@@ -133,7 +133,9 @@ namespace Jackett.Common.Indexers
|
||||
{ "returnto", "/" }
|
||||
};
|
||||
|
||||
var preRequest = await RequestStringWithCookiesAndRetry(LoginUrl, string.Empty);
|
||||
configData.CookieHeader.Cookie = ""; // cookie reset needed in order to relogin
|
||||
|
||||
var preRequest = await RequestStringWithCookiesAndRetry(LoginUrl);
|
||||
|
||||
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, preRequest.Cookies, true, SearchUrl, SiteLink);
|
||||
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("Search Results"), () =>
|
||||
@@ -180,7 +182,7 @@ namespace Jackett.Common.Indexers
|
||||
}
|
||||
|
||||
var response = await RequestStringWithCookiesAndRetry(urlSearch);
|
||||
if (response.Status == System.Net.HttpStatusCode.Forbidden || CookieHeader.Contains("pass=deleted"))
|
||||
if (response.Status == System.Net.HttpStatusCode.Forbidden || CookieHeader.Contains("pass=deleted") || response.Content.Contains("Access limits exceeded."))
|
||||
{
|
||||
// re-login
|
||||
await ApplyConfiguration(null);
|
||||
|
||||
@@ -117,6 +117,118 @@ namespace Jackett.Common.Indexers
|
||||
return IndexerConfigurationStatus.RequiresTesting;
|
||||
}
|
||||
|
||||
List<ReleaseInfo> parseTorrents(WebClientStringResult results, String seasonep, TorznabQuery query, int already_founded, int limit)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
try
|
||||
{
|
||||
CQ dom = results.Content;
|
||||
|
||||
ReleaseInfo release;
|
||||
var rows = dom[".box_torrent_all"].Find(".box_torrent");
|
||||
|
||||
// Check torrents only till we reach the query Limit
|
||||
for(int i=0; (i<rows.Length && ((already_founded + releases.Count) < limit )); i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
CQ qRow = rows[i].Cq();
|
||||
var key = dom["link[rel=alternate]"].First().Attr("href").Split('=').Last();
|
||||
|
||||
release = new ReleaseInfo();
|
||||
var torrentTxt = qRow.Find(".torrent_txt, .torrent_txt2").Find("a").Get(0);
|
||||
//if (torrentTxt == null) continue;
|
||||
release.Title = torrentTxt.GetAttribute("title");
|
||||
release.Description = qRow.Find("span").Get(0).GetAttribute("title") + " " + qRow.Find("a.infolink").Text();
|
||||
|
||||
release.MinimumRatio = 1;
|
||||
release.MinimumSeedTime = 172800;
|
||||
release.DownloadVolumeFactor = 0;
|
||||
release.UploadVolumeFactor = 1;
|
||||
|
||||
string downloadLink = SiteLink + torrentTxt.GetAttribute("href");
|
||||
string downloadId = downloadLink.Substring(downloadLink.IndexOf("&id=") + 4);
|
||||
|
||||
release.Link = new Uri(SiteLink.ToString() + "torrents.php?action=download&id=" + downloadId + "&key=" + key);
|
||||
release.Comments = new Uri(SiteLink.ToString() + "torrents.php?action=details&id=" + downloadId);
|
||||
release.Guid = new Uri(release.Comments.ToString() + "#comments"); ;
|
||||
release.Seeders = ParseUtil.CoerceInt(qRow.Find(".box_s2").Find("a").First().Text());
|
||||
release.Peers = ParseUtil.CoerceInt(qRow.Find(".box_l2").Find("a").First().Text()) + release.Seeders;
|
||||
var imdblink = qRow.Find("a[href*=\".imdb.com/title\"]").Attr("href");
|
||||
release.Imdb = ParseUtil.GetLongFromString(imdblink);
|
||||
var banner = qRow.Find("img.infobar_ico").Attr("onmouseover");
|
||||
if (banner != null)
|
||||
{
|
||||
Regex BannerRegEx = new Regex(@"mutat\('(.*?)', '", RegexOptions.Compiled);
|
||||
var BannerMatch = BannerRegEx.Match(banner);
|
||||
var bannerurl = BannerMatch.Groups[1].Value;
|
||||
release.BannerUrl = new Uri(bannerurl);
|
||||
}
|
||||
release.PublishDate = DateTime.Parse(qRow.Find(".box_feltoltve2").Get(0).InnerHTML.Replace("<br />", " "), CultureInfo.InvariantCulture);
|
||||
string[] sizeSplit = qRow.Find(".box_meret2").Get(0).InnerText.Split(' ');
|
||||
release.Size = ReleaseInfo.GetBytes(sizeSplit[1].ToLower(), ParseUtil.CoerceFloat(sizeSplit[0]));
|
||||
string catlink = qRow.Find("a:has(img[class='categ_link'])").First().Attr("href");
|
||||
string cat = ParseUtil.GetArgumentFromQueryString(catlink, "tipus");
|
||||
release.Category = MapTrackerCatToNewznab(cat);
|
||||
|
||||
/* if the release name not contains the language we add it because it is know from category */
|
||||
if (cat.Contains("hun") && !release.Title.Contains("hun"))
|
||||
release.Title += ".hun";
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (FormatException ex)
|
||||
{
|
||||
logger.Error("Problem of parsing Torrent:" + rows[i].InnerHTML);
|
||||
logger.Error("Exception was the following:" + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnParseError(results.Content, ex);
|
||||
}
|
||||
|
||||
return releases;
|
||||
}
|
||||
|
||||
protected async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query, String seasonep)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
@@ -155,98 +267,37 @@ namespace Jackett.Common.Indexers
|
||||
}
|
||||
|
||||
var results = await PostDataWithCookiesAndRetry(SearchUrl, pairs);
|
||||
|
||||
|
||||
try
|
||||
CQ dom = results.Content;
|
||||
int numVal = 0;
|
||||
|
||||
// find pagelinks in the bottom
|
||||
var pagelinks = dom["div[id=pager_bottom]"].Find("a");
|
||||
if (pagelinks.Length > 0)
|
||||
{
|
||||
CQ dom = results.Content;
|
||||
// If there are several pages find the link for the latest one
|
||||
var last_page_link = (pagelinks[pagelinks.Length - 1].Cq().Attr("href")).Trim();
|
||||
|
||||
ReleaseInfo release;
|
||||
var rows = dom[".box_torrent_all"].Find(".box_torrent");
|
||||
|
||||
foreach (var row in rows)
|
||||
{
|
||||
CQ qRow = row.Cq();
|
||||
|
||||
var key = dom["link[rel=alternate]"].First().Attr("href").Split('=').Last();
|
||||
|
||||
release = new ReleaseInfo();
|
||||
var torrentTxt = qRow.Find(".torrent_txt, .torrent_txt2").Find("a").Get(0);
|
||||
//if (torrentTxt == null) continue;
|
||||
release.Title = torrentTxt.GetAttribute("title");
|
||||
release.Description = qRow.Find("div.siterank").Text();
|
||||
release.MinimumRatio = 1;
|
||||
release.MinimumSeedTime = 172800;
|
||||
release.DownloadVolumeFactor = 0;
|
||||
release.UploadVolumeFactor = 1;
|
||||
|
||||
string downloadLink = SiteLink + torrentTxt.GetAttribute("href");
|
||||
string downloadId = downloadLink.Substring(downloadLink.IndexOf("&id=") + 4);
|
||||
|
||||
release.Link = new Uri(SiteLink.ToString() + "torrents.php?action=download&id=" + downloadId + "&key=" + key);
|
||||
release.Comments = new Uri(SiteLink.ToString() + "torrents.php?action=details&id=" + downloadId);
|
||||
release.Guid = new Uri(release.Comments.ToString() + "#comments"); ;
|
||||
release.Seeders = ParseUtil.CoerceInt(qRow.Find(".box_s2").Find("a").First().Text());
|
||||
release.Peers = ParseUtil.CoerceInt(qRow.Find(".box_l2").Find("a").First().Text()) + release.Seeders;
|
||||
var imdblink = qRow.Find("a[href*=\".imdb.com/title\"]").Attr("href");
|
||||
release.Imdb = ParseUtil.GetLongFromString(imdblink);
|
||||
var banner = qRow.Find("img.infobar_ico").Attr("onmouseover");
|
||||
if (banner != null)
|
||||
{
|
||||
Regex BannerRegEx = new Regex(@"mutat\('(.*?)', '", RegexOptions.Compiled);
|
||||
var BannerMatch = BannerRegEx.Match(banner);
|
||||
var bannerurl = BannerMatch.Groups[1].Value;
|
||||
release.BannerUrl = new Uri(bannerurl);
|
||||
}
|
||||
release.PublishDate = DateTime.Parse(qRow.Find(".box_feltoltve2").Get(0).InnerHTML.Replace("<br />", " "), CultureInfo.InvariantCulture);
|
||||
string[] sizeSplit = qRow.Find(".box_meret2").Get(0).InnerText.Split(' ');
|
||||
release.Size = ReleaseInfo.GetBytes(sizeSplit[1].ToLower(), ParseUtil.CoerceFloat(sizeSplit[0]));
|
||||
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];
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// find out the number of the last page from the link
|
||||
Match match = Regex.Match(last_page_link, @"(?<=[\?,&]oldal=)(\d+)(?=&)");
|
||||
numVal = Int32.Parse(match.Value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
var limit = query.Limit;
|
||||
if (limit == 0)
|
||||
limit = 100;
|
||||
|
||||
releases = parseTorrents(results, seasonep, query, releases.Count, limit);
|
||||
|
||||
// Check all the pages for the torrents.
|
||||
// The starting index is 2. (the first one is the original where we parse out the pages.)
|
||||
for (int i=2; (i<= numVal && releases.Count < limit); i++ )
|
||||
{
|
||||
OnParseError(results.Content, ex);
|
||||
pairs.Add(new KeyValuePair<string, string>("oldal", i.ToString()));
|
||||
results = await PostDataWithCookiesAndRetry(SearchUrl, pairs);
|
||||
releases.AddRange(parseTorrents(results, seasonep, query, releases.Count, limit));
|
||||
pairs.Remove(new KeyValuePair<string, string>("oldal", i.ToString()));
|
||||
}
|
||||
|
||||
return releases;
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Jackett.Common.Indexers
|
||||
{
|
||||
}
|
||||
|
||||
public NewpctRelease(NewpctRelease copyFrom):
|
||||
public NewpctRelease(NewpctRelease copyFrom):
|
||||
base(copyFrom)
|
||||
{
|
||||
NewpctReleaseType = copyFrom.NewpctReleaseType;
|
||||
@@ -65,6 +65,7 @@ namespace Jackett.Common.Indexers
|
||||
private int _maxEpisodesListPages = 100;
|
||||
private int[] _allTvCategories = TorznabCatType.TV.SubCategories.Select(c => c.ID).ToArray();
|
||||
|
||||
private bool _includeVo;
|
||||
private DateTime _dailyNow;
|
||||
private int _dailyResultIdx;
|
||||
|
||||
@@ -72,6 +73,7 @@ namespace Jackett.Common.Indexers
|
||||
private string[] _seriesLetterUrls = new string[] { "/series/letter/{0}", "/series-hd/letter/{0}" };
|
||||
private string[] _seriesVOLetterUrls = new string[] { "/series-vo/letter/{0}" };
|
||||
private string _seriesUrl = "{0}/pg/{1}";
|
||||
private string[] _voUrls = new string[] { "serie-vo", "serievo" };
|
||||
|
||||
public Newpct(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps)
|
||||
: base(name: "Newpct",
|
||||
@@ -138,6 +140,7 @@ namespace Jackett.Common.Indexers
|
||||
CleanCache();
|
||||
}
|
||||
|
||||
_includeVo = ((BoolItem)configData.GetDynamic("IncludeVo")).Value;
|
||||
_dailyNow = DateTime.Now;
|
||||
_dailyResultIdx = 0;
|
||||
bool rssMode = string.IsNullOrEmpty(query.SanitizedSearchTerm);
|
||||
@@ -183,7 +186,7 @@ namespace Jackett.Common.Indexers
|
||||
|
||||
private async Task<IEnumerable<ReleaseInfo>> TvSearch(TorznabQuery query)
|
||||
{
|
||||
List<ReleaseInfo> newpctReleases = null;
|
||||
List<ReleaseInfo> newpctReleases = null;
|
||||
|
||||
string seriesName = query.SanitizedSearchTerm;
|
||||
int? season = query.Season > 0 ? (int?)query.Season : null;
|
||||
@@ -242,7 +245,8 @@ namespace Jackett.Common.Indexers
|
||||
return newpctReleases.Where(r =>
|
||||
{
|
||||
NewpctRelease nr = r as NewpctRelease;
|
||||
return nr.Season.HasValue != season.HasValue || //Can't determine if same season
|
||||
return (
|
||||
nr.Season.HasValue != season.HasValue || //Can't determine if same season
|
||||
nr.Season.HasValue && season.Value == nr.Season.Value && //Same season and ...
|
||||
(
|
||||
nr.Episode.HasValue != episode.HasValue || //Can't determine if same episode
|
||||
@@ -251,7 +255,8 @@ namespace Jackett.Common.Indexers
|
||||
nr.Episode.Value == episode.Value || //Same episode
|
||||
nr.EpisodeTo.HasValue && episode.Value >= nr.Episode.Value && episode.Value <= nr.EpisodeTo.Value //Episode in interval
|
||||
)
|
||||
);
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -285,7 +290,7 @@ namespace Jackett.Common.Indexers
|
||||
private IEnumerable<Uri> SeriesListUris(string seriesName)
|
||||
{
|
||||
IEnumerable<string> lettersUrl;
|
||||
if (!((BoolItem)configData.GetDynamic("IncludeVo")).Value)
|
||||
if (!_includeVo)
|
||||
{
|
||||
lettersUrl = _seriesLetterUrls;
|
||||
}
|
||||
@@ -319,6 +324,8 @@ namespace Jackett.Common.Indexers
|
||||
title = title2;
|
||||
|
||||
var detailsUrl = anchor.GetAttribute("href");
|
||||
if (!_includeVo && _voUrls.Any(vo => detailsUrl.ToLower().Contains(vo.ToLower())))
|
||||
continue;
|
||||
|
||||
var span = row.QuerySelector("span");
|
||||
var quality = span.ChildNodes[0].TextContent.Trim();
|
||||
@@ -331,12 +338,12 @@ namespace Jackett.Common.Indexers
|
||||
|
||||
NewpctRelease newpctRelease;
|
||||
if (releaseType == ReleaseType.TV)
|
||||
newpctRelease = GetReleaseFromData(releaseType,
|
||||
newpctRelease = GetReleaseFromData(releaseType,
|
||||
string.Format("Serie {0} - {1} Calidad [{2}]", title, language, quality),
|
||||
detailsUrl, quality, language, ReleaseInfo.GetBytes(sizeText), _dailyNow - TimeSpan.FromMilliseconds(_dailyResultIdx));
|
||||
else
|
||||
newpctRelease = GetReleaseFromData(releaseType,
|
||||
string.Format("{0} [{1}][{2}]", title, quality, language),
|
||||
string.Format("{0} [{1}][{2}]", title, quality, language),
|
||||
detailsUrl, quality, language, ReleaseInfo.GetBytes(sizeText), _dailyNow - TimeSpan.FromMilliseconds(_dailyResultIdx));
|
||||
|
||||
releases.Add(newpctRelease);
|
||||
@@ -434,6 +441,8 @@ namespace Jackett.Common.Indexers
|
||||
result.Episode = int.Parse(match.Groups[8].Value.Trim().PadLeft(2, '0'));
|
||||
result.EpisodeTo = match.Groups[11].Success ? (int?)int.Parse(match.Groups[11].Value.Trim()) : null;
|
||||
string audioQuality = match.Groups[13].Value.Trim(' ', '[', ']');
|
||||
if (string.IsNullOrEmpty(language))
|
||||
language = audioQuality;
|
||||
quality = match.Groups[14].Value.Trim(' ', '[', ']');
|
||||
|
||||
string seasonText = result.Season.ToString();
|
||||
@@ -448,11 +457,11 @@ namespace Jackett.Common.Indexers
|
||||
Match matchClassic = _titleClassicRegex.Match(title);
|
||||
if (matchClassic.Success)
|
||||
{
|
||||
result.Season = matchClassic.Groups[3].Success ? (int?)int.Parse(matchClassic.Groups[3].Value) : null;
|
||||
result.Episode = matchClassic.Groups[4].Success ? (int?)int.Parse(matchClassic.Groups[4].Value) : null;
|
||||
result.EpisodeTo = matchClassic.Groups[7].Success ? (int?)int.Parse(matchClassic.Groups[7].Value) : null;
|
||||
if (matchClassic.Groups[2].Success)
|
||||
quality = matchClassic.Groups[2].Value;
|
||||
result.Season = matchClassic.Groups[2].Success ? (int?)int.Parse(matchClassic.Groups[2].Value) : null;
|
||||
result.Episode = matchClassic.Groups[3].Success ? (int?)int.Parse(matchClassic.Groups[3].Value) : null;
|
||||
result.EpisodeTo = matchClassic.Groups[6].Success ? (int?)int.Parse(matchClassic.Groups[6].Value) : null;
|
||||
if (matchClassic.Groups[1].Success)
|
||||
quality = matchClassic.Groups[1].Value;
|
||||
}
|
||||
|
||||
result.Title = title;
|
||||
@@ -478,12 +487,12 @@ namespace Jackett.Common.Indexers
|
||||
result.Seeders = 1;
|
||||
result.Peers = 1;
|
||||
|
||||
result.Title = FixedTitle(result, quality);
|
||||
result.Title = FixedTitle(result, quality, language);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private string FixedTitle(NewpctRelease release, string quality)
|
||||
private string FixedTitle(NewpctRelease release, string quality, string language)
|
||||
{
|
||||
if (String.IsNullOrEmpty(release.SeriesName))
|
||||
{
|
||||
@@ -493,12 +502,16 @@ namespace Jackett.Common.Indexers
|
||||
release.SeriesName = release.Title.Substring(0, release.Title.IndexOf('-') - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(quality))
|
||||
{
|
||||
quality = "HDTV";
|
||||
}
|
||||
|
||||
var titleParts = new List<string>();
|
||||
|
||||
titleParts.Add(release.SeriesName);
|
||||
|
||||
if (release.NewpctReleaseType == ReleaseType.TV)
|
||||
{
|
||||
var seasonAndEpisode = "S" + release.Season.ToString().PadLeft(2, '0');
|
||||
@@ -509,12 +522,27 @@ namespace Jackett.Common.Indexers
|
||||
}
|
||||
titleParts.Add(seasonAndEpisode);
|
||||
}
|
||||
titleParts.Add(quality.Replace("[", "").Replace("]", ""));
|
||||
if (release.Title.ToLower().Contains("esp") || release.Title.ToLower().Contains("cast"))
|
||||
|
||||
if (!release.SeriesName.Contains(quality))
|
||||
{
|
||||
titleParts.Add(quality);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(language) && !release.SeriesName.Contains(language))
|
||||
{
|
||||
titleParts.Add(language);
|
||||
}
|
||||
|
||||
if (release.Title.ToLower().Contains("espa\u00F1ol") || release.Title.ToLower().Contains("castellano"))
|
||||
{
|
||||
titleParts.Add("Spanish");
|
||||
}
|
||||
return String.Join(".", titleParts);
|
||||
|
||||
string result = String.Join(".", titleParts);
|
||||
|
||||
result = Regex.Replace(result, @"[\[\]]+", ".");
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,7 +321,7 @@ namespace Jackett.Common.Indexers
|
||||
if (torrentRowList.Count == 0)
|
||||
{
|
||||
// No results found
|
||||
Output("\nNo result found for your query, please try another search term ...\n", "info");
|
||||
Output("\nNo result found for your query, please try another search term or change the theme you're currently using on the site as this is an unsupported solution...\n", "info");
|
||||
|
||||
// No result found for this query
|
||||
break;
|
||||
@@ -678,9 +678,23 @@ namespace Jackett.Common.Indexers
|
||||
/// <returns>JQuery Object</returns>
|
||||
private CQ FindTorrentRows()
|
||||
{
|
||||
// Return all occurencis of torrents found
|
||||
//return _fDom["#content > table > tr"];
|
||||
return _fDom["# base_content > table.mainouter > tbody > tr > td.outer > div.article > table > tbody > tr:not(:first)"];
|
||||
var defaultTheme = new[] { "/templates/1/", "/templates/2/", "/templates/3/", "/templates/4/", "/templates/5/", "/templates/6/", "/templates/11/", "/templates/12/" };
|
||||
var oldV2 = new[] { "/templates/7/", "/templates/8/", "/templates/9/", "/templates/10/", "/templates/14/" };
|
||||
|
||||
if (defaultTheme.Any(_fDom.Document.Body.InnerHTML.Contains))
|
||||
{
|
||||
// Return all occurencis of torrents found
|
||||
// $('#base_content2 > div.article > table > tbody:not(:first) > tr')
|
||||
return _fDom["# base_content2 > div.article > table > tbody:not(:first) > tr"];
|
||||
}
|
||||
|
||||
if (oldV2.Any(_fDom.Document.Body.InnerHTML.Contains))
|
||||
{
|
||||
// Return all occurencis of torrents found
|
||||
// $('#base_content > table.mainouter > tbody > tr > td.outer > div.article > table > tbody')
|
||||
return _fDom["# base_content > table.mainouter > tbody > tr > td.outer > div.article > table > tbody > tr:not(:first)"];
|
||||
}
|
||||
return _fDom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace Jackett.Common.Indexers
|
||||
|
||||
TorznabCaps.SupportsImdbSearch = true;
|
||||
|
||||
webclient.requestDelay = 2.0; // 0.5 requests per second (2 causes problems)
|
||||
webclient.requestDelay = 2.1; // The api has a 1req/2s limit.
|
||||
|
||||
AddCategoryMapping(4, TorznabCatType.XXX, "XXX (18+)");
|
||||
AddCategoryMapping(14, TorznabCatType.MoviesSD, "Movies/XVID");
|
||||
|
||||
@@ -9,10 +9,14 @@ namespace Jackett.Common.Indexers
|
||||
{
|
||||
public class TehConnectionMe : GazelleTracker
|
||||
{
|
||||
public override string[] LegacySiteLinks { get; protected set; } = new string[] {
|
||||
"https://tehconnection.me/",
|
||||
};
|
||||
|
||||
public TehConnectionMe(IIndexerConfigurationService configService, WebClient webClient, Logger logger, IProtectionService protectionService)
|
||||
: base(name: "TehConnection.me",
|
||||
desc: "A movies tracker",
|
||||
link: "https://tehconnection.me/",
|
||||
link: "https://anthelion.me/",
|
||||
configService: configService,
|
||||
logger: logger,
|
||||
protectionService: protectionService,
|
||||
|
||||
@@ -37,6 +37,10 @@ namespace Jackett.Common.Indexers
|
||||
"https://www.torrentday.ru/",
|
||||
"https://www.td.af/",
|
||||
"https://torrentday.it/",
|
||||
"https://td.findnemo.net",
|
||||
"https://td.getcrazy.me",
|
||||
"https://td.venom.global",
|
||||
"https://td.workisboring.net",
|
||||
};
|
||||
|
||||
private new ConfigurationDataRecaptchaLogin configData
|
||||
@@ -48,7 +52,7 @@ namespace Jackett.Common.Indexers
|
||||
public TorrentDay(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps)
|
||||
: base(name: "TorrentDay",
|
||||
description: "TorrentDay (TD) is a Private site for TV / MOVIES / GENERAL",
|
||||
link: "https://www.torrentday.it/",
|
||||
link: "https://td.getcrazy.me/",
|
||||
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
|
||||
configService: configService,
|
||||
client: wc,
|
||||
|
||||
@@ -19,9 +19,15 @@ namespace Jackett.Common.Indexers
|
||||
{
|
||||
public class TorrentHeaven : BaseWebIndexer
|
||||
{
|
||||
public override string[] LegacySiteLinks { get; protected set; } = new string[] {
|
||||
"https://torrentheaven.myfqdn.info/",
|
||||
};
|
||||
private string IndexUrl { get { return SiteLink + "index.php"; } }
|
||||
private string LoginCompleteUrl { get { return SiteLink + "index.php?strWebValue=account&strWebAction=login_complete&ancestry=verify"; } }
|
||||
private static readonly string certificateHash = "6F5CE30D578C2A7AECFB919D0D013976D395055F";
|
||||
private static readonly string[] certificateHashs = new string[] {
|
||||
"6F5CE30D578C2A7AECFB919D0D013976D395055F",
|
||||
"66096DB5FD0107E4FFBAF5EC8378EB235CADA909",
|
||||
};
|
||||
|
||||
private new ConfigurationDataCaptchaLogin configData
|
||||
{
|
||||
@@ -32,7 +38,7 @@ namespace Jackett.Common.Indexers
|
||||
public TorrentHeaven(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps)
|
||||
: base(name: "TorrentHeaven",
|
||||
description: "A German general tracker.",
|
||||
link: "https://torrentheaven.myfqdn.info/",
|
||||
link: "https://newheaven.nl/",
|
||||
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
|
||||
configService: configService,
|
||||
client: wc,
|
||||
@@ -92,7 +98,8 @@ namespace Jackett.Common.Indexers
|
||||
AddCategoryMapping(70, TorznabCatType.PC, "APPLICATIONS/Linux");
|
||||
AddCategoryMapping(71, TorznabCatType.PCMac, "APPLICATIONS/Mac");
|
||||
|
||||
webclient.AddTrustedCertificate(new Uri(SiteLink).Host, certificateHash);
|
||||
foreach (var certificateHash in certificateHashs)
|
||||
webclient.AddTrustedCertificate(new Uri(SiteLink).Host, certificateHash);
|
||||
}
|
||||
|
||||
public override async Task<ConfigurationData> GetConfigurationForSetup()
|
||||
|
||||
@@ -52,40 +52,35 @@ namespace Jackett.Common.Indexers
|
||||
|
||||
AddCategoryMapping(2, TorznabCatType.PC, "Apps / Windows");
|
||||
AddCategoryMapping(13, TorznabCatType.PC, "Apps / Linux");
|
||||
AddCategoryMapping(4, TorznabCatType.PCMac, "Apps / Mac");
|
||||
AddCategoryMapping(4, TorznabCatType.PCMac, "Apps / MacOS");
|
||||
AddCategoryMapping(6, TorznabCatType.PC, "Apps / Misc");
|
||||
|
||||
AddCategoryMapping(12, TorznabCatType.PCGames, "Spiele / PC");
|
||||
AddCategoryMapping(8, TorznabCatType.ConsolePSP, "Spiele / PSX/PSP");
|
||||
AddCategoryMapping(7, TorznabCatType.ConsoleWii, "Spiele / Wii");
|
||||
AddCategoryMapping(32, TorznabCatType.ConsoleXbox, "Spiele / XBOX");
|
||||
AddCategoryMapping(41, TorznabCatType.ConsoleOther, "Spiele / Misc");
|
||||
AddCategoryMapping(50, TorznabCatType.PCGames, "Spiele / Windows");
|
||||
AddCategoryMapping(51, TorznabCatType.PCGames, "Spiele / MacOS");
|
||||
AddCategoryMapping(52, TorznabCatType.PCGames, "Spiele / Linux");
|
||||
AddCategoryMapping(8, TorznabCatType.ConsoleOther, "Spiele / Playstation");
|
||||
AddCategoryMapping(7, TorznabCatType.ConsoleOther, "Spiele / Nintendo");
|
||||
AddCategoryMapping(32, TorznabCatType.ConsoleOther, "Spiele / XBOX");
|
||||
|
||||
AddCategoryMapping(22, TorznabCatType.Movies3D, "Filme / 3D");
|
||||
AddCategoryMapping(3, TorznabCatType.MoviesBluRay, "Filme / BluRay");
|
||||
AddCategoryMapping(11, TorznabCatType.MoviesOther, "Filme / REMUX");
|
||||
AddCategoryMapping(42, TorznabCatType.MoviesUHD, "Filme / 2160p");
|
||||
AddCategoryMapping(9, TorznabCatType.MoviesHD, "Filme / 1080p");
|
||||
AddCategoryMapping(20, TorznabCatType.MoviesHD, "Filme / 720p");
|
||||
AddCategoryMapping(21, TorznabCatType.MoviesDVD, "Filme / DVD");
|
||||
AddCategoryMapping(10, TorznabCatType.MoviesSD, "Filme / SD");
|
||||
AddCategoryMapping(31, TorznabCatType.MoviesOther, "Filme / Anime");
|
||||
|
||||
AddCategoryMapping(43, TorznabCatType.TVUHD, "TV / Serien/UHD");
|
||||
AddCategoryMapping(16, TorznabCatType.TVHD, "TV / Serien/HD");
|
||||
AddCategoryMapping(15, TorznabCatType.TVSD, "TV / Serien/SD");
|
||||
AddCategoryMapping(44, TorznabCatType.TVUHD, "TV / Packs/UHD");
|
||||
AddCategoryMapping(23, TorznabCatType.TVHD, "TV / Packs/HD");
|
||||
AddCategoryMapping(27, TorznabCatType.TVSD, "TV / Packs/SD");
|
||||
AddCategoryMapping(28, TorznabCatType.TVDocumentary, "TV / Dokus/SD");
|
||||
AddCategoryMapping(29, TorznabCatType.TVDocumentary, "TV / Dokus/HD");
|
||||
AddCategoryMapping(30, TorznabCatType.TVSport, "TV / Sport");
|
||||
AddCategoryMapping(40, TorznabCatType.TVAnime, "TV / Anime");
|
||||
AddCategoryMapping(43, TorznabCatType.TVUHD, "Serien / 2160p");
|
||||
AddCategoryMapping(53, TorznabCatType.TVHD, "Serien / 1080p");
|
||||
AddCategoryMapping(54, TorznabCatType.TVHD, "Serien / 720p");
|
||||
AddCategoryMapping(15, TorznabCatType.TVSD, "Serien / SD");
|
||||
AddCategoryMapping(30, TorznabCatType.TVSport, "Serien / Sport");
|
||||
|
||||
AddCategoryMapping(24, TorznabCatType.AudioLossless, "Audio / FLAC");
|
||||
AddCategoryMapping(25, TorznabCatType.AudioMP3, "Audio / MP3");
|
||||
AddCategoryMapping(44, TorznabCatType.TVUHD, "Serienpacks / 2160p");
|
||||
AddCategoryMapping(55, TorznabCatType.TVHD, "Serienpacks / 1080p");
|
||||
AddCategoryMapping(56, TorznabCatType.TVHD, "Serienpacks / 720p");
|
||||
AddCategoryMapping(27, TorznabCatType.TVSD, "Serienpacks / SD");
|
||||
|
||||
AddCategoryMapping(24, TorznabCatType.AudioLossless, "Audio / Musik / FLAC");
|
||||
AddCategoryMapping(25, TorznabCatType.AudioMP3, "Audio / Musik / MP3");
|
||||
AddCategoryMapping(35, TorznabCatType.AudioOther, "Audio / Other");
|
||||
AddCategoryMapping(26, TorznabCatType.Audio, "Audio / Packs");
|
||||
AddCategoryMapping(18, TorznabCatType.AudioAudiobook, "Audio / aBooks");
|
||||
AddCategoryMapping(33, TorznabCatType.AudioVideo, "Audio / Videos");
|
||||
|
||||
@@ -93,7 +88,8 @@ namespace Jackett.Common.Indexers
|
||||
AddCategoryMapping(5, TorznabCatType.PCPhoneOther, "Misc / Mobile");
|
||||
AddCategoryMapping(39, TorznabCatType.Other, "Misc / Bildung");
|
||||
|
||||
AddCategoryMapping(36, TorznabCatType.TVFOREIGN, "Englisch / TV");
|
||||
AddCategoryMapping(36, TorznabCatType.TVFOREIGN, "Englisch / Serien");
|
||||
AddCategoryMapping(57, TorznabCatType.TVFOREIGN, "Englisch / Serienpacks");
|
||||
AddCategoryMapping(37, TorznabCatType.MoviesForeign, "Englisch / Filme");
|
||||
AddCategoryMapping(47, TorznabCatType.Books, "Englisch / eBooks");
|
||||
AddCategoryMapping(48, TorznabCatType.Other, "Englisch / Bildung");
|
||||
@@ -191,7 +187,7 @@ namespace Jackett.Common.Indexers
|
||||
|
||||
var qRow = row.Cq();
|
||||
|
||||
var catStr = row.ChildElements.ElementAt(0).FirstElementChild.GetAttribute("href").Split('=')[1];
|
||||
var catStr = row.ChildElements.ElementAt(0).FirstElementChild.GetAttribute("href").Split('=')[1].Split('&')[0];
|
||||
release.Category = MapTrackerCatToNewznab(catStr);
|
||||
|
||||
var qLink = row.ChildElements.ElementAt(2).FirstElementChild.Cq();
|
||||
@@ -225,8 +221,9 @@ namespace Jackett.Common.Indexers
|
||||
if (imdbLink.Any())
|
||||
release.Imdb = ParseUtil.GetLongFromString(imdbLink.Attr("href"));
|
||||
|
||||
var sizeStr = row.ChildElements.ElementAt(5).Cq().Text();
|
||||
release.Size = ReleaseInfo.GetBytes(sizeStr);
|
||||
var sizeFileCountRowChilds = row.ChildElements.ElementAt(5).ChildElements;
|
||||
release.Size = ReleaseInfo.GetBytes(sizeFileCountRowChilds.ElementAt(0).Cq().Text());
|
||||
release.Files = ParseUtil.CoerceInt(sizeFileCountRowChilds.ElementAt(2).Cq().Text());
|
||||
|
||||
release.Seeders = ParseUtil.CoerceInt(row.ChildElements.ElementAt(7).Cq().Text());
|
||||
release.Peers = ParseUtil.CoerceInt(row.ChildElements.ElementAt(8).Cq().Text()) + release.Seeders;
|
||||
|
||||
@@ -1470,7 +1470,7 @@ namespace Jackett.Common.Indexers
|
||||
{
|
||||
{ "login_username", configData.Username.Value },
|
||||
{ "login_password", configData.Password.Value },
|
||||
{ "login", "entry" }
|
||||
{ "login", "Login" }
|
||||
};
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(cap_sid))
|
||||
@@ -1483,9 +1483,10 @@ namespace Jackett.Common.Indexers
|
||||
}
|
||||
|
||||
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, CookieHeader, true, null, LoginUrl, true);
|
||||
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("class=\"logged-in-as-uname\""), () =>
|
||||
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("id=\"logged-in-username\""), () =>
|
||||
{
|
||||
var errorMessage = result.Content;
|
||||
logger.Debug(result.Content);
|
||||
var errorMessage = "Unknown error message, please report";
|
||||
var LoginResultParser = new HtmlParser();
|
||||
var LoginResultDocument = LoginResultParser.Parse(result.Content);
|
||||
var errormsg = LoginResultDocument.QuerySelector("h4[class=\"warnColor1 tCenter mrg_16\"]");
|
||||
@@ -1521,7 +1522,7 @@ namespace Jackett.Common.Indexers
|
||||
|
||||
var searchUrl = SearchUrl + "?" + queryCollection.GetQueryString();
|
||||
var results = await RequestStringWithCookies(searchUrl);
|
||||
if (!results.Content.Contains("class=\"logged-in-as-uname\""))
|
||||
if (!results.Content.Contains("id=\"logged-in-username\""))
|
||||
{
|
||||
// re login
|
||||
await ApplyConfiguration(null);
|
||||
|
||||
@@ -78,6 +78,10 @@ namespace Jackett.Common.Indexers
|
||||
|
||||
var queryCollection = new NameValueCollection();
|
||||
|
||||
// without this the API sometimes returns nothing
|
||||
queryCollection.Add("sort", "date_added");
|
||||
queryCollection.Add("limit", "50");
|
||||
|
||||
if (query.ImdbID != null)
|
||||
{
|
||||
queryCollection.Add("query_term", query.ImdbID);
|
||||
@@ -131,7 +135,11 @@ namespace Jackett.Common.Indexers
|
||||
return releases.ToArray();
|
||||
}
|
||||
|
||||
foreach (var movie_item in data_items.Value<JToken>("movies"))
|
||||
var movies = data_items.Value<JToken>("movies");
|
||||
if (movies == null)
|
||||
throw new Exception("API error, movies missing");
|
||||
|
||||
foreach (var movie_item in movies)
|
||||
{
|
||||
var torrents = movie_item.Value<JArray>("torrents");
|
||||
if (torrents == null)
|
||||
@@ -142,7 +150,7 @@ namespace Jackett.Common.Indexers
|
||||
|
||||
// Append the quality to the title because thats how radarr seems to be determining the quality?
|
||||
// All releases are BRRips, see issue #2200
|
||||
release.Title = movie_item.Value<string>("title_long") + " " + torrent_info.Value<string>("quality") + " BRRip";
|
||||
release.Title = "[YTS] " + movie_item.Value<string>("title_long") + " " + torrent_info.Value<string>("quality") + " BRRip";
|
||||
var imdb = movie_item.Value<string>("imdb_code");
|
||||
release.Imdb = ParseUtil.GetImdbID(imdb);
|
||||
|
||||
|
||||
@@ -211,4 +211,11 @@
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Save the compiled date so that we know if the user is running an old version of Jackett -->
|
||||
<ItemGroup>
|
||||
<AssemblyAttribute Include="Jackett.Common.Utils.BuildDateAttribute">
|
||||
<_Parameter1>$([System.DateTime]::UtcNow.ToString("yyyyMMddHHmmss"))</_Parameter1>
|
||||
</AssemblyAttribute>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace Jackett.Common.Models
|
||||
getTorznabElement("magneturl", r.MagnetUri),
|
||||
getTorznabElement("rageid", r.RageID),
|
||||
getTorznabElement("thetvdb", r.TVDBId),
|
||||
getTorznabElement("imdb", r.Imdb),
|
||||
getTorznabElement("imdb", r.Imdb == null ? null : ((long)r.Imdb).ToString("D7")),
|
||||
getTorznabElement("seeders", r.Seeders),
|
||||
getTorznabElement("peers", r.Peers),
|
||||
getTorznabElement("infohash", r.InfoHash),
|
||||
|
||||
@@ -11,11 +11,11 @@ namespace Jackett.Common.Utils
|
||||
// When updating these make sure they are not detected by the incapsula bot detection engine (e.g. kickasstorrent indexer)
|
||||
if (System.Environment.OSVersion.Platform == PlatformID.Unix)
|
||||
{
|
||||
return "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36";
|
||||
return "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) 63.0.3239.132 Safari/537.36";
|
||||
return "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
27
src/Jackett.Common/Utils/BuildDate.cs
Normal file
27
src/Jackett.Common/Utils/BuildDate.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Jackett.Common.Utils
|
||||
{
|
||||
public static class BuildDate
|
||||
{
|
||||
public static DateTime GetBuildDateTime()
|
||||
{
|
||||
Assembly commonAssembly = Assembly.GetExecutingAssembly();
|
||||
var attribute = commonAssembly.GetCustomAttribute<BuildDateAttribute>();
|
||||
return attribute?.DateTime ?? default(DateTime);
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Assembly)]
|
||||
public class BuildDateAttribute : Attribute
|
||||
{
|
||||
public BuildDateAttribute(string value)
|
||||
{
|
||||
DateTime = DateTime.ParseExact(value, "yyyyMMddHHmmss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
|
||||
}
|
||||
|
||||
public DateTime DateTime { get; }
|
||||
}
|
||||
}
|
||||
@@ -261,7 +261,10 @@ namespace Jackett.Common.Utils.Clients
|
||||
// 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);
|
||||
if (newRedirectingTo.StartsWith("file:////")) // Location without protocol but with host (only add scheme)
|
||||
newRedirectingTo = newRedirectingTo.Replace("file://", request.RequestUri.Scheme + ":");
|
||||
else
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -281,7 +281,10 @@ namespace Jackett.Common.Utils.Clients
|
||||
// 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);
|
||||
if (newRedirectingTo.StartsWith("file:////")) // Location without protocol but with host (only add scheme)
|
||||
newRedirectingTo = newRedirectingTo.Replace("file://", request.RequestUri.Scheme + ":");
|
||||
else
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -258,7 +258,10 @@ namespace Jackett.Common.Utils.Clients
|
||||
// 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);
|
||||
if (newRedirectingTo.StartsWith("file:////")) // Location without protocol but with host (only add scheme)
|
||||
newRedirectingTo = newRedirectingTo.Replace("file://", request.RequestUri.Scheme + ":");
|
||||
else
|
||||
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;
|
||||
}
|
||||
|
||||
28
src/Jackett.Common/Utils/DotNetCoreUtil.cs
Normal file
28
src/Jackett.Common/Utils/DotNetCoreUtil.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Jackett.Common.Utils
|
||||
{
|
||||
public static class DotNetCoreUtil
|
||||
{
|
||||
public static bool IsRunningOnDotNetCore
|
||||
{
|
||||
get
|
||||
{
|
||||
bool runningOnDotNetCore = false;
|
||||
|
||||
try
|
||||
{
|
||||
runningOnDotNetCore = RuntimeInformation.FrameworkDescription.IndexOf("core", StringComparison.OrdinalIgnoreCase) >= 0;
|
||||
}
|
||||
catch
|
||||
{
|
||||
//Issue only appears to occur for small number of users on Mono
|
||||
runningOnDotNetCore = false;
|
||||
}
|
||||
|
||||
return runningOnDotNetCore;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,6 @@ using Jackett.Common.Utils;
|
||||
using Jackett.Server.Services;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Jackett.Server
|
||||
{
|
||||
@@ -113,8 +111,8 @@ namespace Jackett.Server
|
||||
{
|
||||
logger.Info("Overriding port to " + consoleOptions.Port);
|
||||
serverConfig.Port = consoleOptions.Port;
|
||||
bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||
if (isWindows)
|
||||
|
||||
if (EnvironmentUtil.IsWindows)
|
||||
{
|
||||
if (ServerUtil.IsUserAdministrator())
|
||||
{
|
||||
@@ -137,7 +135,7 @@ namespace Jackett.Server
|
||||
{
|
||||
logger.Info("Overriding external access to " + consoleOptions.ListenPublic);
|
||||
serverConfig.AllowExternal = consoleOptions.ListenPublic;
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
if (EnvironmentUtil.IsWindows)
|
||||
{
|
||||
if (ServerUtil.IsUserAdministrator())
|
||||
{
|
||||
@@ -153,5 +151,32 @@ namespace Jackett.Server
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void CheckEnvironmentalVariables(Logger logger)
|
||||
{
|
||||
//Check the users environmental variables to ensure they aren't using Mono legacy TLS
|
||||
|
||||
var enumerator = Environment.GetEnvironmentVariables().GetEnumerator();
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
if (enumerator.Key.ToString().Equals("MONO_TLS_PROVIDER", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
logger.Info("MONO_TLS_PROVIDER is present with a value of: " + enumerator.Value.ToString());
|
||||
|
||||
if (enumerator.Value.ToString().IndexOf("legacy", StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
{
|
||||
logger.Error("The MONO_TLS_PROVIDER=legacy environment variable is not supported, please remove it.");
|
||||
Environment.Exit(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (enumerator.Key.ToString().IndexOf("MONO_", StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
{
|
||||
logger.Info($"Environment variable {enumerator.Key} is present");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,9 +47,7 @@ namespace Jackett.Server
|
||||
{
|
||||
if (string.IsNullOrEmpty(options.Client))
|
||||
{
|
||||
bool runningOnDotNetCore = RuntimeInformation.FrameworkDescription.IndexOf("Core", StringComparison.OrdinalIgnoreCase) >= 0;
|
||||
|
||||
if (runningOnDotNetCore)
|
||||
if (DotNetCoreUtil.IsRunningOnDotNetCore)
|
||||
{
|
||||
options.Client = "httpclientnetcore";
|
||||
}
|
||||
@@ -82,6 +80,7 @@ namespace Jackett.Server
|
||||
}
|
||||
}
|
||||
|
||||
Initialisation.CheckEnvironmentalVariables(logger);
|
||||
Initialisation.ProcessSettings(Settings, logger);
|
||||
|
||||
ISerializeService serializeService = new SerializeService();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Jackett.Common.Models.Config;
|
||||
using Jackett.Common.Services.Interfaces;
|
||||
using Jackett.Common.Utils;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
using NLog;
|
||||
@@ -121,10 +122,8 @@ namespace Jackett.Server.Services
|
||||
logger.Error(e, "Error while reading the issue file");
|
||||
}
|
||||
|
||||
bool runningOnDotNetCore = RuntimeInformation.FrameworkDescription.IndexOf("Core", StringComparison.OrdinalIgnoreCase) >= 0;
|
||||
|
||||
Type monotype = Type.GetType("Mono.Runtime");
|
||||
if (monotype != null && !runningOnDotNetCore)
|
||||
if (monotype != null && !DotNetCoreUtil.IsRunningOnDotNetCore)
|
||||
{
|
||||
MethodInfo displayName = monotype.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
var monoVersion = "unknown";
|
||||
@@ -259,6 +258,24 @@ namespace Jackett.Server.Services
|
||||
logger.Error(e, "Error while checking the username");
|
||||
}
|
||||
|
||||
//Warn user that they are using an old version of Jackett
|
||||
try
|
||||
{
|
||||
DateTime compiledData = BuildDate.GetBuildDateTime();
|
||||
|
||||
if (compiledData < DateTime.Now.AddMonths(-3))
|
||||
{
|
||||
string version = configService.GetVersion();
|
||||
string notice = $"Your version of Jackett v{version} is very old. Multiple indexers are likely to fail when using an old version. Update to the latest version of Jackett.";
|
||||
_notices.Add(notice);
|
||||
logger.Error(notice);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.Error(e, "Error while checking build date of Jackett.Common");
|
||||
}
|
||||
|
||||
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
|
||||
// Load indexers
|
||||
indexerService.InitIndexers(configService.GetCardigannDefinitionsFolders());
|
||||
|
||||
@@ -79,10 +79,10 @@ namespace Jackett.Server
|
||||
|
||||
builder.Populate(services);
|
||||
builder.RegisterModule(new JackettModule(runtimeSettings));
|
||||
builder.RegisterType<SecuityService>().As<ISecuityService>();
|
||||
builder.RegisterType<ServerService>().As<IServerService>();
|
||||
builder.RegisterType<ProtectionService>().As<IProtectionService>();
|
||||
builder.RegisterType<ServiceConfigService>().As<IServiceConfigService>();
|
||||
builder.RegisterType<SecuityService>().As<ISecuityService>().SingleInstance();
|
||||
builder.RegisterType<ServerService>().As<IServerService>().SingleInstance();
|
||||
builder.RegisterType<ProtectionService>().As<IProtectionService>().SingleInstance();
|
||||
builder.RegisterType<ServiceConfigService>().As<IServiceConfigService>().SingleInstance();
|
||||
|
||||
IContainer container = builder.Build();
|
||||
Helper.ApplicationContainer = container;
|
||||
|
||||
@@ -22,13 +22,13 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autofac" Version="4.8.1" />
|
||||
<PackageReference Include="FluentAssertions" Version="5.4.1" />
|
||||
<PackageReference Include="FluentAssertions" Version="5.4.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.DataProtection" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="1.3.2" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="1.3.2" />
|
||||
<PackageReference Include="NUnit" Version="3.10.1" />
|
||||
<PackageReference Include="NUnit.ConsoleRunner" Version="3.8.0" />
|
||||
<PackageReference Include="NUnit.ConsoleRunner" Version="3.9.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -96,9 +96,9 @@ namespace Jackett.Updater
|
||||
{
|
||||
var startInfo = new ProcessStartInfo();
|
||||
startInfo.Arguments = "-15 " + pid;
|
||||
startInfo.FileName = "/bin/kill";
|
||||
startInfo.FileName = "kill";
|
||||
Process.Start(startInfo);
|
||||
System.Threading.Thread.Sleep(1000); // just sleep, WaitForExit() doesn't seem to work on mono/linux (returns immediantly).
|
||||
System.Threading.Thread.Sleep(1000); // just sleep, WaitForExit() doesn't seem to work on mono/linux (returns immediantly), https://bugzilla.xamarin.com/show_bug.cgi?id=51742
|
||||
exited = proc.WaitForExit(2000);
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -247,7 +247,6 @@ namespace Jackett.Updater
|
||||
"Definitions/ultrahdclub.yml",
|
||||
"Definitions/infinityt.yml",
|
||||
"Definitions/hachede-c.yml",
|
||||
"Definitions/hd4Free.yml",
|
||||
"Definitions/skytorrents.yml",
|
||||
"Definitions/gormogon.yml",
|
||||
"Definitions/czteam.yml",
|
||||
@@ -273,6 +272,10 @@ namespace Jackett.Updater
|
||||
"System.Web.Http.dll",
|
||||
"System.Web.Http.Owin.dll",
|
||||
"System.Web.Http.Tracing.dll",
|
||||
"Definitions/torrentkim.yml",
|
||||
"Definitions/horriblesubs.yml",
|
||||
"Definitions/idope.yml",
|
||||
"Definitions/bt-scene.yml",
|
||||
};
|
||||
|
||||
foreach (var oldFile in oldFiles)
|
||||
|
||||
Reference in New Issue
Block a user