Compare commits

...

65 Commits

Author SHA1 Message Date
flightlevel
feaf5d4361 Publish Linux ARM builds 2019-03-07 21:11:06 +11:00
flightlevel
f146b3eaa6 Code tidy 2019-03-06 21:25:06 +11:00
flightlevel
d07b6ae863 Enable Linux x64 build 2019-03-06 21:18:28 +11:00
flightlevel
a25f2016dc Make Mono.Posix usage conditional on .NET Core 2019-03-06 21:16:20 +11:00
flightlevel
a5f0e2b5db Code tidy up 2019-03-06 20:20:32 +11:00
flightlevel
6ac9555cb5 Make parameter type HttpRequest
Code tidy
2019-03-06 20:11:50 +11:00
flightlevel
e7d9360b51 Disable Mono.Posix 2019-03-06 19:51:59 +11:00
thetennismaster
5a7091075e Add TotallyKids.tv definition. Resolves #4 (#4825)
* Add TotallyKids.tv definition. Resolves #4
* Add TotallyKids (TK) to the README
2019-03-06 18:10:33 +13:00
flightlevel
2270b13435 Trigger build 2019-03-06 13:05:12 +11:00
flightlevel
80a99ce69f Don't use Path.Combine for Linux paths 2019-03-06 12:59:14 +11:00
flightlevel
c54cbb4cbe Trigger build 2019-03-06 12:32:27 +11:00
flightlevel
de55e6e14e Log paths for debugging 2019-03-06 12:23:03 +11:00
Garfield69
0983540493 Merge branch 'master' of https://github.com/Jackett/Jackett 2019-03-06 13:41:11 +13:00
Garfield69
6cc262a6d3 torrent9: drop apostrophes on keywords. resolves #4822 2019-03-06 13:40:35 +13:00
flightlevel
2484ff16f3 Enable updater on .NET Core 2019-03-06 11:26:38 +11:00
Garfield69
4e1d7ac09b Revert "eztv: fetch magnets from details page. resolves #4813"
This reverts commit a84b1dce4d.
2019-03-06 13:00:28 +13:00
flightlevel
b8aa2a16dd Make execute permission conditional on .NET Core 2019-03-05 22:09:20 +11:00
flightlevel
cf7ca97f9c Make jackett and JackettUpdater executable 2019-03-05 21:25:37 +11:00
Garfield69
cc01b0ca05 add sharingue a Brazilian private tracker. resolves #4817 2019-03-05 19:37:46 +13:00
Garfield69
a84b1dce4d eztv: fetch magnets from details page. resolves #4813 2019-03-05 07:25:56 +13:00
flightlevel
be54f1a532 Fix copy/paste error 2019-03-04 17:52:17 +11:00
flightlevel
064786f379 Disable macOS .NET Core builds for now 2019-03-04 17:44:05 +11:00
Garfield69
9d140b3ab4 beyondhd: set freeleech resolves #4809 2019-03-04 15:40:10 +13:00
Garfield69
a65d855cc4 torrent-turk: fix login form. resolves #4334
switch to new domain .co
also added missing cxategories
fix date processing
add missing volumefactors
2019-03-04 15:34:23 +13:00
Garfield69
2698ac2907 torrentgalaxyorg: new result selectors. resolves #4805 2019-03-04 08:33:41 +13:00
Garfield69
28971c2303 scenerush: add categories. resolves #1775
correct login error meesage detection
upgrade to https
correct date parsing
switch browse post to get
2019-03-04 07:23:30 +13:00
Garfield69
6428a7134b classix: use alternate method of andmatch. for #4788 2019-03-04 06:00:02 +13:00
flightlevel
b33f5764ef Perform Linux build first 2019-03-03 17:42:09 +11:00
flightlevel
ebb855bf45 Release notes for linux 2019-03-03 17:32:47 +11:00
flightlevel
9e90edd397 Linux release notes 2019-03-03 17:22:34 +11:00
flightlevel
ee2743cdc9 Re-enable Windows building 2019-03-03 17:06:14 +11:00
flightlevel
a9731b036c Update file permissions 2019-03-03 16:53:40 +11:00
flightlevel
58ed5421ec Appveyor.yml: Fix casing 2019-03-03 16:35:00 +11:00
flightlevel
dc25480844 Appveyor test casing 2019-03-03 16:31:16 +11:00
flightlevel
789d168648 Build.cake line endings 2019-03-03 16:19:00 +11:00
flightlevel
f6668c9777 Test linux only build 2019-03-03 16:09:55 +11:00
flightlevel
5903e6abdf Enable updater for .NET Core on macOS 2019-03-03 16:09:17 +11:00
flightlevel
0de4c1da43 Push artifacts on Appveyor Linux 2019-03-03 15:51:59 +11:00
flightlevel
53bd7ce0c4 Updater: Add logic for .NET Core 2019-03-03 15:44:18 +11:00
flightlevel
4d4c9fe645 Improve build instructions 2019-03-03 15:32:55 +11:00
flightlevel
caf583a684 Package update 2019-03-03 15:23:33 +11:00
flightlevel
b445072a4d TVStore: Throw exception 2019-03-03 15:09:51 +11:00
flightlevel
82617f961d Force Github update deploy
Trying to avoid downloading artifacts in the second Appveyor job
2019-03-03 15:09:26 +11:00
flightlevel
c28df96332 Build updater for .NET Core macOS 2019-03-03 15:01:07 +11:00
Garfield69
88c6c4af6e classix: add andmatch. resolves #4788 2019-03-02 17:13:22 +13:00
Garfield69
df49bb8578 asiancinema: fix #4798 2019-03-02 13:15:39 +13:00
Garfield69
a968913bc4 add pthome a chinese private tracker. resolves #4795 2019-03-02 09:09:04 +13:00
Jorman
5c9880e410 ilcorsaronero: new domain .live (#4794)
Changed domain
2019-03-01 10:29:48 +13:00
morpheus133
d7af20d4f6 ncore: add offset support (#4792) resolves #4778
* add offset support to ncore indexer
* small correction related to add .hun tag to torrents
* DivideByZeroException  at torrent_per_page
2019-03-01 07:23:00 +13:00
xfouloux
8dc832d64a yggtorrent: tidy up keyword processing (#4791)
trimed stuff on .Keyword in keywordsfilters instead of re_replace in path because it caused having %20%20 in search .Keyword instead of having only one
2019-02-28 22:06:40 +13:00
Garfield69
91b87ee7be 7tor: fix TEST mode for #4784
the getnew search does not appear to be working any longer, so in no keywords are supplied we will use  TEST instead. Not ideal but better than no-results = error.
2019-02-28 13:19:19 +13:00
Garfield69
ee8fc6a78f bigtorrent: fix TEST mode for #1219
and also return a login error message
2019-02-28 10:05:20 +13:00
Garfield69
18f48cb04b icetorrent: attempt to fix for #4783 2019-02-28 09:42:23 +13:00
Garfield69
dd64739af6 torrentbd: attempt to fix login. #1709 #4781 2019-02-28 08:20:13 +13:00
Garfield69
05c4d1e331 polishtracker: display email on login config. resolves #4780 2019-02-28 07:41:53 +13:00
Garfield69
f9ad475aa8 torrent9: add secondary domain 2019-02-27 17:41:54 +13:00
Garfield69
ad17897edd elitetorrent-biz: drop index.php from search path. 2019-02-27 16:10:28 +13:00
SpookyDex
2356ef3837 torrentsectorcrew: new domain .org (#4776) 2019-02-27 07:16:20 +13:00
Garfield69
b63e97fecd torrentscsv: add torznab elements guid and comments for sonarr/radarr. resolves #4774 2019-02-26 13:41:37 +13:00
Garfield69
c025a98cbf skytorrentsclone: update search keyword. resolves #4763 2019-02-26 12:40:40 +13:00
Garfield69
0c84507b51 tp2: add note about categories for Sonarr or Radarr. 2019-02-26 12:30:49 +13:00
Garfield69
875d7a005e EliteTracker: add CA bypass for #4769 2019-02-25 21:50:45 +13:00
Garfield69
b1c25d4c5b gdf76: prevent log errors 2019-02-25 19:04:42 +13:00
Garfield69
5ef6b8601a puntotorrent & unionfansub: handle size 1.018,29 MB 2019-02-25 18:54:31 +13:00
Garfield69
a512a1e6b5 alein: selector adjustments to prevent log errors. 2019-02-25 17:39:11 +13:00
44 changed files with 820 additions and 201 deletions

View File

@@ -271,6 +271,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
* Psytorrents
* PT99
* PTFiles (PTF)
* PThome
* PuntoTorrent
* PWTorrents (PWT)
* Racing4Everyone (R4E)
@@ -292,6 +293,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
* Secret Cinema
* Shareisland
* ShareSpaceDB
* Sharingue
* Shazbat
* Shellife (SL)
* SpaceTorrent
@@ -332,6 +334,7 @@ Developer note: The software implements the [Torznab](https://github.com/Sonarr/
* Torrent-Syndikat
* TOrrent-tuRK (TORK)
* TorViet (HDVNBits)
* TotallyKids (TK)
* ToTheGlory
* TranceTraffic
* Trezzor
@@ -514,6 +517,8 @@ All contributions are welcome just send a pull request.
### Windows
* Install the .NET Core [SDK](https://www.microsoft.com/net/download/windows)
* Clone Jackett
* From the `src` directory, run `dotnet restore`
* Open the Jackett solution in Visual Studio 2017 (version 15.9 or above)
* Right click on the Jackett solution and click 'Rebuild Solution' to restore nuget packages
* Select Jackett.Server as startup project

View File

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

View File

@@ -14,9 +14,11 @@ var configuration = Argument("configuration", "Debug");
// Define directories.
var workingDir = MakeAbsolute(Directory("./"));
var artifactsDirName = "Artifacts";
var testResultsDirName = "TestResults";
var netCoreFramework = "netcoreapp2.2";
string artifactsDirName = "Artifacts";
string testResultsDirName = "TestResults";
string netCoreFramework = "netcoreapp2.2";
string serverProjectPath = "./src/Jackett.Server/Jackett.Server.csproj";
string updaterProjectPath = "./src/Jackett.Updater/Jackett.Updater.csproj";
//////////////////////////////////////////////////////////////////////
// TASKS
@@ -89,7 +91,6 @@ Task("Package-Windows-Full-Framework")
.IsDependentOn("Run-Unit-Tests")
.Does(() =>
{
string serverProjectPath = "./src/Jackett.Server/Jackett.Server.csproj";
string buildOutputPath = "./BuildOutput/net461/win7-x86/Jackett";
DotNetCorePublish(serverProjectPath, "net461", "win7-x86", buildOutputPath);
@@ -119,7 +120,6 @@ Task("Package-Mono-Full-Framework")
.IsDependentOn("Run-Unit-Tests")
.Does(() =>
{
string serverProjectPath = "./src/Jackett.Server/Jackett.Server.csproj";
string buildOutputPath = "./BuildOutput/net461/linux-x64/Jackett";
DotNetCorePublish(serverProjectPath, "net461", "linux-x64", buildOutputPath);
@@ -154,30 +154,38 @@ Task("Package-DotNetCore-macOS")
.Does(() =>
{
string runtimeId = "osx-x64";
string serverProjectPath = "./src/Jackett.Server/Jackett.Server.csproj";
string buildOutputPath = $"./BuildOutput/{netCoreFramework}/{runtimeId}/Jackett";
string updaterOutputPath = buildOutputPath + "/Updater";
DotNetCorePublish(serverProjectPath, netCoreFramework, runtimeId, buildOutputPath);
DotNetCorePublish(updaterProjectPath, netCoreFramework, runtimeId, updaterOutputPath);
CopyFiles(updaterOutputPath + "/JackettUpdater*", buildOutputPath);
DeleteDirectory(updaterOutputPath, recursive:true);
CopyFileToDirectory("./install_service_macos", buildOutputPath);
Gzip($"./BuildOutput/{netCoreFramework}/{runtimeId}", $"./{artifactsDirName}", "Jackett", "Experimental.Jackett.Binaries.macOS.tar.gz");
});
Task("Package-DotNetCore-LinuxAMD64")
Task("Package-DotNetCore-LinuxAMDx64")
.IsDependentOn("Clean")
.Does(() =>
{
string runtimeId = "linux-x64";
string serverProjectPath = "./src/Jackett.Server/Jackett.Server.csproj";
string buildOutputPath = $"./BuildOutput/{netCoreFramework}/{runtimeId}/Jackett";
string updaterOutputPath = buildOutputPath + "/Updater";
DotNetCorePublish(serverProjectPath, netCoreFramework, runtimeId, buildOutputPath);
DotNetCorePublish(updaterProjectPath, netCoreFramework, runtimeId, updaterOutputPath);
CopyFiles(updaterOutputPath + "/JackettUpdater*", buildOutputPath);
DeleteDirectory(updaterOutputPath, recursive:true);
CopyFileToDirectory("./install_service_systemd.sh", buildOutputPath);
CopyFileToDirectory("./Upstart.config", buildOutputPath);
Gzip($"./BuildOutput/{netCoreFramework}/{runtimeId}", $"./{artifactsDirName}", "Jackett", "Experimental.Jackett.Binaries.LinuxAMD64.tar.gz");
Gzip($"./BuildOutput/{netCoreFramework}/{runtimeId}", $"./{artifactsDirName}", "Jackett", "Jackett.Binaries.LinuxAMDx64.tar.gz");
});
Task("Package-DotNetCore-LinuxARM32")
@@ -185,15 +193,19 @@ Task("Package-DotNetCore-LinuxARM32")
.Does(() =>
{
string runtimeId = "linux-arm";
string serverProjectPath = "./src/Jackett.Server/Jackett.Server.csproj";
string buildOutputPath = $"./BuildOutput/{netCoreFramework}/{runtimeId}/Jackett";
string updaterOutputPath = buildOutputPath + "/Updater";
DotNetCorePublish(serverProjectPath, netCoreFramework, runtimeId, buildOutputPath);
DotNetCorePublish(updaterProjectPath, netCoreFramework, runtimeId, updaterOutputPath);
CopyFiles(updaterOutputPath + "/JackettUpdater*", buildOutputPath);
DeleteDirectory(updaterOutputPath, recursive:true);
CopyFileToDirectory("./install_service_systemd.sh", buildOutputPath);
CopyFileToDirectory("./Upstart.config", buildOutputPath);
Gzip($"./BuildOutput/{netCoreFramework}/{runtimeId}", $"./{artifactsDirName}", "Jackett", "Experimental.Jackett.Binaries.LinuxARM32.tar.gz");
Gzip($"./BuildOutput/{netCoreFramework}/{runtimeId}", $"./{artifactsDirName}", "Jackett", "Jackett.Binaries.LinuxARM32.tar.gz");
});
Task("Package-DotNetCore-LinuxARM64")
@@ -201,22 +213,26 @@ Task("Package-DotNetCore-LinuxARM64")
.Does(() =>
{
string runtimeId = "linux-arm64";
string serverProjectPath = "./src/Jackett.Server/Jackett.Server.csproj";
string buildOutputPath = $"./BuildOutput/{netCoreFramework}/{runtimeId}/Jackett";
string updaterOutputPath = buildOutputPath + "/Updater";
DotNetCorePublish(serverProjectPath, netCoreFramework, runtimeId, buildOutputPath);
DotNetCorePublish(updaterProjectPath, netCoreFramework, runtimeId, updaterOutputPath);
CopyFiles(updaterOutputPath + "/JackettUpdater*", buildOutputPath);
DeleteDirectory(updaterOutputPath, recursive:true);
CopyFileToDirectory("./install_service_systemd.sh", buildOutputPath);
CopyFileToDirectory("./Upstart.config", buildOutputPath);
Gzip($"./BuildOutput/{netCoreFramework}/{runtimeId}", $"./{artifactsDirName}", "Jackett", "Experimental.Jackett.Binaries.LinuxARM64.tar.gz");
Gzip($"./BuildOutput/{netCoreFramework}/{runtimeId}", $"./{artifactsDirName}", "Jackett", "Jackett.Binaries.LinuxARM64.tar.gz");
});
Task("Appveyor-Push-Artifacts")
.IsDependentOn("Clean")
.Does(() =>
{
if (AppVeyor.IsRunningOnAppVeyor && IsRunningOnWindows())
if (AppVeyor.IsRunningOnAppVeyor)
{
foreach (var file in GetFiles(workingDir + $"/{artifactsDirName}/*"))
{
@@ -280,10 +296,10 @@ Task("Release-Notes")
Task("Windows-Environment")
.IsDependentOn("Package-Windows-Full-Framework")
.IsDependentOn("Package-Mono-Full-Framework")
.IsDependentOn("Package-DotNetCore-macOS")
.IsDependentOn("Package-DotNetCore-LinuxAMD64")
.IsDependentOn("Package-DotNetCore-LinuxARM32")
.IsDependentOn("Package-DotNetCore-LinuxARM64")
//.IsDependentOn("Package-DotNetCore-macOS")
//.IsDependentOn("Package-DotNetCore-LinuxAMDx64")
//.IsDependentOn("Package-DotNetCore-LinuxARM32")
//.IsDependentOn("Package-DotNetCore-LinuxARM64")
.IsDependentOn("Appveyor-Push-Artifacts")
.IsDependentOn("Release-Notes")
.Does(() =>
@@ -293,7 +309,7 @@ Task("Windows-Environment")
Task("Linux-Environment")
.IsDependentOn("Package-DotNetCore-macOS")
.IsDependentOn("Package-DotNetCore-LinuxAMD64")
.IsDependentOn("Package-DotNetCore-LinuxAMDx64")
.IsDependentOn("Package-DotNetCore-LinuxARM32")
.IsDependentOn("Package-DotNetCore-LinuxARM64")
.IsDependentOn("Appveyor-Push-Artifacts")
@@ -380,7 +396,8 @@ private void Gzip(string sourceFolder, string outputDirectory, string tarCdirect
{
RunLinuxCommand("find", MakeAbsolute(Directory(sourceFolder)) + @" -type d -exec chmod 755 {} \;");
RunLinuxCommand("find", MakeAbsolute(Directory(sourceFolder)) + @" -type f -exec chmod 644 {} \;");
//RunLinuxCommand("chmod", $"755 {MakeAbsolute(Directory(sourceFolder))} /Jackett/jackett");
RunLinuxCommand("chmod", $"755 {MakeAbsolute(Directory(sourceFolder))}/Jackett/jackett");
RunLinuxCommand("chmod", $"755 {MakeAbsolute(Directory(sourceFolder))}/Jackett/JackettUpdater");
RunLinuxCommand("tar", $"-C {sourceFolder} -zcvf {outputDirectory}/{tarFileName}.gz {tarCdirectoryOption}");
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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 = 1;
release.DownloadVolumeFactor = 0;
release.UploadVolumeFactor = 1;
releases.Add(release);

View File

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

View File

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

View File

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

View File

@@ -224,7 +224,9 @@ namespace Jackett.Common.Indexers
series.Add(sd);
}
catch (IndexOutOfRangeException e)
{ }
{
throw (e);
}
}
}
}

View File

@@ -129,6 +129,8 @@ namespace Jackett.Common.Indexers {
"&tr=udp://tracker.justseed.it:1337/announce";
release.MagnetUri = new Uri (magnet_uri);
release.Comments = release.MagnetUri;
release.Guid = release.MagnetUri;
release.InfoHash = torrent.Value<JToken> ("infohash").ToString ();
// convert unix timestamp to human readable date

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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