Compare commits

...

157 Commits

Author SHA1 Message Date
Azerelat
2901cceea9 Fix cache items not expiring and change redirect to a temp one as we can now change the base path 2016-01-17 13:19:18 +00:00
Azerelat
ea4d0fe701 AnimeBytes Sonarr Fix (Will only fix season 1 but we don't have season info). 2016-01-16 22:36:56 +00:00
Azerelat
02a57533f9 Merge pull request #193 from raspdealer/patch-4
Change below to above inside steps
2016-01-16 21:07:24 +00:00
Azerelat
99f0e9c9f6 Merge pull request #192 from raspdealer/patch-3
Enable SSL on Bluetigers
2016-01-16 21:07:13 +00:00
Raspdealer
d1225c17b2 Change below to above inside steps 2016-01-16 11:47:01 +01:00
Raspdealer
2adecae9bf Enable SSL on Bluetigers 2016-01-16 11:41:51 +01:00
Azerelat
c7aa0d7b0f Fix better reverse proxy support 2016-01-14 20:15:10 +00:00
Azerelat
a69ecf3e06 Merge pull request #179 from tehjojo/master
Better reverse proxy support
2016-01-14 19:29:57 +00:00
Azerelat
9414e7a4b8 Merge pull request #188 from JigSawFr/providers/fnt-remove
Removed FNT provider
2016-01-14 19:20:25 +00:00
Azerelat
d9473781d3 Merge pull request #189 from JigSawFr/providers/bluetigers-ssl-removed
Fixed Disabled SSL on tracker side with BlueTigers Provider
2016-01-14 19:19:57 +00:00
JigSawFr
4952199e68 Fixed Disabled SSL on tracker side with BlueTigers Provider 2016-01-14 16:55:09 +01:00
JigSawFr
388460993d Removed FNT provider 2016-01-14 14:57:00 +01:00
flightlevel
f21c1f0400 Merge pull request #183 from flightlevel/FixNcoreFileNameCase
Fix NCore File Name Casing
2016-01-13 22:56:11 +11:00
flightlevel
4db62bbf63 Fix NCore File Name Casing 2016-01-12 22:49:01 +11:00
Michael Robinson
42ec634cd3 Better reverse proxy support
Added "base path override" config option that makes all links and
redirects work with your reverse proxy.
Fixed post config update reload to work properly.
Make redirects and ajax calls use relative pathing.
2016-01-10 19:59:40 -07:00
Azerelat
a07de4d1e9 Merge pull request #175 from twistedroutes/master
demonoid to support torrentPotato
2016-01-10 20:12:18 +00:00
Azerelat
0361a88856 Merge branch 'master' of https://github.com/Jackett/Jackett.git 2016-01-10 20:06:12 +00:00
Azerelat
a88f248b75 Add logging to updater 2016-01-10 20:06:09 +00:00
twistedpear
82f06d0b46 Added movies category to demonoid - simple version, no subcats - all qualities 2016-01-09 15:11:22 -05:00
Azerelat
10e019a1dd Merge pull request #174 from JigSawFr/providers/abn
Abnormal Provider
2016-01-09 18:46:38 +00:00
Azerelat
173e26c054 SCC queries not uri encoded #170 2016-01-09 18:45:02 +00:00
JigSawFr
24f8d26b2d Updated README 2016-01-09 03:08:39 +01:00
JigSawFr
8ceb8ebbe7 ABN Provider 2016-01-09 03:06:21 +01:00
Azerelat
71c583d359 AnimeBytes Fix stripping of episode number from search term 2016-01-07 00:12:56 +00:00
Azerelat
9d4e8f4bda Merge pull request #160 from twistedroutes/bitsoup
Put GUID back into release
2016-01-06 23:02:34 +00:00
twistedpear
65d2a88591 Put GUID back into release 2016-01-06 16:56:46 -05:00
Azerelat
a04d296b55 Make Un-configured list smaller 2016-01-06 19:53:13 +00:00
Azerelat
79452053ee Merge pull request #153 from JigSawFr/providers/fadn
French-ADN Provider
2016-01-06 18:37:48 +00:00
Azerelat
7ad5fac9c0 Merge pull request #156 from JigSawFr/providers/fnt-hotfix-dl
FNT Provider ~ Download HOTFIX & SSL
2016-01-06 18:36:35 +00:00
JigSawFr
2456a42608 SSL enabled 2016-01-05 20:26:47 +01:00
JigSawFr
3c396ba880 Fix Torrent Files Downloading 2016-01-05 20:25:00 +01:00
JigSawFr
65e4d1e068 Rebase on upstream 2016-01-05 15:41:54 +01:00
JigSawFr
e643134f09 Updated README 2016-01-05 15:33:13 +01:00
JigSawFr
19bc3c7b36 FADN Provider 2016-01-05 15:30:50 +01:00
Azerelat
a50e31ec3f Merge pull request #151 from tehjojo/master
Changed resource paths to be relative
2016-01-04 20:51:51 +00:00
Azerelat
ff96389864 Merge pull request #149 from JigSawFr/providers/fnt
FNT Provider
2016-01-04 20:50:42 +00:00
Azerelat
efd5a8cc98 Merge pull request #150 from JigSawFr/providers/wihd
WiHD Provider ~ Improved
2016-01-04 20:41:15 +00:00
Michael Robinson
d5c59109b1 Changed resource paths to be relative 2016-01-03 20:14:44 -07:00
JigSawFr
4a9fcdbc9b Fixed some typo & removed unecessary comment 2016-01-04 00:47:42 +01:00
JigSawFr
6bea0b009a Upgraded with new functions and improvements,
Empty search return now from all (fixed term before),
Fix Browser XHR request not removed if no result,
Fix some typo
2016-01-04 00:09:32 +01:00
JigSawFr
ff86a15ddd Rebase on upstream 2016-01-03 22:15:04 +01:00
Azerelat
d204ce6f39 Fix TVChaosUK and missing logos 2016-01-03 20:40:59 +00:00
JigSawFr
6bc011f678 FNT Provider 2016-01-03 19:39:53 +01:00
Azerelat
acdf198b05 Merge pull request #137 from JigSawFr/providers/wihd
WiHD Provider
2016-01-03 14:38:18 +00:00
JigSawFr
5f2dfcf499 Updated README 2015-12-29 12:07:34 +01:00
JigSawFr
aa69d1a3b9 Debug logging only if debug level is true 2015-12-29 11:51:52 +01:00
JigSawFr
29bde68337 Cache only used in case of search term 2015-12-29 11:30:55 +01:00
Sébastien Robert
e9ae2d4cd8 WiHD Provider 2015-12-29 11:17:18 +01:00
Azerelat
0ba6188e4b Merge pull request #132 from twistedroutes/master
XSpeeds
2015-12-29 01:31:38 +00:00
twistedpear
283a003aef remember xspeeds cookies if they have changed. This makes future queries much quicker 2015-12-28 12:15:09 -05:00
twistedpear
a50ab9c49b Improved cookie accumulation to reduce roundtrips to the server. 2015-12-28 11:16:53 -05:00
twistedpear
b4e42b4180 Improved the category search - can now use mutli categories 2015-12-28 10:27:02 -05:00
twistedpear
f7efd83e09 Put ProxyConnection back into Startup.cs 2015-12-28 09:53:59 -05:00
twistedpear
f67381d0ac Merge remote-tracking branch 'upstream/master' 2015-12-28 09:46:38 -05:00
garreth.jeremiah@gmail.com
af0c15be2c added notice in log when proxying is used
bitsoup multi category searches look for all cats instead of making multiple queries
2015-12-28 08:42:11 -05:00
Azerelat
4ce6f6b048 Update README.md 2015-12-28 11:50:33 +00:00
Azerelat
828091128e Respect pre-release flag 2015-12-27 22:55:18 +00:00
Azerelat
f8c0b9a80f Merge pull request #133 from some-guy-23/indexer-RevolutionTT
Added new tracker/indexer class for RevolutionTT.me
2015-12-27 21:39:48 +00:00
Azerelat
d598017a03 Fix blackhole downloads #135 2015-12-27 21:25:54 +00:00
Azerelat
aadf25e3b6 Fix update cross platform issues 2015-12-27 21:11:04 +00:00
garreth.jeremiah@gmail.com
f4129dc4a0 Added simple (non-auth) proxy support including processing the second set of headers (server) vs first (proxy). New command line option (-j 127.0.0.1:8888) to set the proxy and port. unfortunatly both -p and -x were already taken
extended refresh header handling to libcurl and safecurl
also some minor tweaks needed to have Curl 'behave' with certain servers by adding accept-language header to Curl
Added ability/template to allow the user to select their own SiteURL (see BitSoup implementation) with a minor update to ConfigurationData class to prevent the "display text" from disappearing on errors.
XSpeeds indexer - updated to handle a case where the returned XML occasionally is null terminated resulting in XML parsing exceptions
BitSoup indexer - added user customizable url selection, including some url validation
BaseIndexer - cleaned up some of my earlier implementation for accumulating cookies.
2015-12-24 22:26:39 -05:00
twistedroutes
f6f27e604a Fixed grabbing the wrong download link. Also updated the comment link 2015-12-22 12:17:49 -05:00
twistedroutes
bc1dd0e9e8 Added Bitsoup tracker. For multi-category searches will perform multiple searches as the tracker search didn't support multiple categories. Recommend to the user to search for "all" instead. Consider changing this approach later. 2015-12-21 22:12:43 -05:00
some-guy-23
6b1dba2dc3 Added RSS feed to RevolutionTT 2015-12-21 20:03:50 -05:00
some-guy-23
e4a47927b9 Fixed RevolutionTT so that login can use username/password (instead of cookie) 2015-12-21 18:18:07 -05:00
some-guy-23
226c27f903 Added new tracker/indexer class for RevolutionTT.me 2015-12-21 16:10:39 -05:00
flightlevel
a69ee65176 Merge pull request #129 from Kantraz/patch-2
Attempt to keep hounddawgs logged in
2015-12-20 11:27:22 +11:00
garreth.jeremiah@gmail.com
5acaf9dbb8 performQuery did not handle the situation where the credentials had timed out or the cloudflare DDoS was re-requested. Added a temporary solution by re-doing the log-in process. It is a little slow, so users of this indexer will see a 20s delay. I will find a way to improve that in a subsequent fix. 2015-12-19 10:40:01 -05:00
garreth.jeremiah@gmail.com
a856aba953 XSpeeds.cs - updated configuration data to give notification to use about the initial delay for handling the CloudFlare DDOS Redirection using a new ConfigurationData class that exploits the seemingly unused DisplayInfo
ConfigurationDataBaseicLoginWithRSSAndDisplay - a ConfigData class that provides a display item member.  I am new to c# so I haven't figured out if I coud have avoided this by added it to the object after instantiation.  Looks possible with expandoobject but I felt that would be changing too much
2015-12-18 13:02:07 -05:00
garreth.jeremiah@gmail.com
ce351dd3aa Corrected typo in response.statusCode to response.StatusCode 2015-12-18 12:08:36 -05:00
garreth.jeremiah@gmail.com
99125386f0 XSpeeds - based on TVCHaosUK. Because f clourflare redirection, needs to hit the site twice. Once for cloudflare DDoS redirection (to obtain all necessary cookies) and second to login. 2015-12-18 12:06:51 -05:00
garreth.jeremiah@gmail.com
44d6ac2f04 Run - added parsing of the http response headers to examine the Refresh header if the response is a 503 (service unavailable). Extract the redirect and redirect delay from the header and follow it. This is to avoid the alternative of trying to calculate the cloudflare challenge/response. 2015-12-18 12:03:38 -05:00
garreth.jeremiah@gmail.com
b5ff430e2d RequestLoginAndFollowRedirect - added "accumulateCookies" which adds cookies from redirection responses. This was needed for xspeeds processing of cloudflare redirection
FollowIfRedirect - during redirects this can keep the cookies
2015-12-18 11:55:53 -05:00
Kantraz
8fcda318ca Attempt to keep hounddawgs logged in 2015-12-16 20:19:59 +01:00
WhatFox
73171c3e45 Remove closed tracker NextGen 2015-12-15 23:35:24 +00:00
WhatFox
c2ec9827cd Fix webui on mono 3.x. Please don't use 3.x :( 2015-12-15 23:27:13 +00:00
flightlevel
03a42af594 Merge pull request #126 from flightlevel/IpTorrentsUrl
IPTorrents: Fix Url
2015-12-14 10:26:01 +11:00
flightlevel
95e3615bfa IPTorrents: Fix Url
IPTorrents: Fix Url
2015-12-14 10:20:40 +11:00
flightlevel
82b69667cb Merge pull request #123 from flightlevel/ftdb
FTDB: Remove tracker
2015-12-09 20:24:56 +11:00
flightlevel
6a831c2884 Merge pull request #122 from flightlevel/speedcdcats
Speed.Cd: Add categories
2015-12-09 20:01:43 +11:00
flightlevel
3e19ca2b85 FTDB: Remove tracker
FTDB: Remove tracker
2015-12-09 19:50:25 +11:00
flightlevel
e1c29b7723 Speed.Cd: Add categories
Speed.Cd: Add categories
2015-12-09 19:45:44 +11:00
flightlevel
1d5498e93e Merge pull request #118 from Kantraz/master
Hounddawgs working againg
2015-12-08 21:59:33 +11:00
flightlevel
a9d4bbdf1d Merge pull request #117 from Diaoul/patch-1
Jackett is available at SynoCommunity
2015-12-08 21:58:51 +11:00
Kantraz
89bfdca5c0 Hounddawgs working againg
Run with "--IgnoreSslErrors true"
2015-12-06 21:43:39 +01:00
Antoine Bertin
0652e9b42d Jackett is available at SynoCommunity 2015-12-06 20:48:10 +01:00
flightlevel
97a5c10017 Merge pull request #114 from OriginalFool/master
Add movie support to Speed.cd
2015-12-06 22:36:35 +11:00
Nic Carroll
a547e4805e Merge remote-tracking branch 'upstream/master' 2015-12-04 17:44:00 -07:00
Nic Carroll
ff71257a0d Merge pull request #1 from OriginalFool/OriginalFool-patch-speed
Speed.cd Patch
2015-12-04 13:03:40 -07:00
Nic Carroll
ccbe704ef3 Add Movie Support to Speed.cd 2015-12-04 13:01:36 -07:00
flightlevel
4e5d3bf538 Merge pull request #112 from BramRoets/master
Speed.cd - login url fix
2015-12-04 22:54:16 +11:00
Bram Roets
a2872fdf77 Speed.cd - login url fix 2015-12-04 10:55:54 +01:00
flightlevel
655b5894e9 Merge pull request #109 from flightlevel/speedcd
SpeedCD- Change login URL
2015-12-02 21:51:48 +11:00
flightlevel
c3642ffcbb SpeedCD- Change login URL
SpeedCD- Change login URL
2015-12-02 21:48:17 +11:00
flightlevel
1978d35b5f Merge pull request #108 from flightlevel/ignoresslerror
Linux: Ignore SSL certificate errors option added
2015-12-02 21:27:41 +11:00
flightlevel
18a2db5af2 Linux: Ignore SSL certificate errors option added
Linux: Ignore SSL certificate errors option added
2015-12-02 21:19:51 +11:00
Nic Carroll
4f800f3f34 Update SpeedCD.cs
Change login url
2015-11-26 00:28:00 -07:00
flightlevel
6262d937d4 Merge pull request #92 from flightlevel/danishbitsaddbacklogo
Add Danishbits logo
2015-11-23 23:42:50 +11:00
flightlevel
41a6ac17c6 Merge pull request #90 from flightlevel/danishbitsfixlogo
Remove Danish Bits Logo
2015-11-23 23:37:07 +11:00
flightlevel
2adfa6a184 Add Danishbits logo
Made extension lowercase for linux
2015-11-23 23:36:32 +11:00
flightlevel
8dfc86b041 Remove Danish Bits Logo
Works on Windows, but not Linux due to uppercase extension
2015-11-23 23:26:15 +11:00
flightlevel
9e52dec2d7 Merge pull request #84 from flightlevel/freshoncategoryandtime
FreshOn: Add Tv Categories and Fix Time
2015-11-21 23:43:27 +11:00
flightlevel
85e7b34a71 Merge pull request #83 from flightlevel/tvcategoryparser
Tv Category Parser
2015-11-21 23:37:34 +11:00
flightlevel
43845c4be2 FreshOn: Add Tv Categories and Fix Time
-Add Tv Categories
-Incorrect time was being returned
2015-11-21 23:32:31 +11:00
flightlevel
7a0264051d Tv Category Parser
Can Determine Torznab TV show category from title if tracker doesn't
supply a category
2015-11-21 22:56:06 +11:00
WhatFox
05b99801f7 Fix enhanced logging not disabling properly 2015-11-21 02:03:57 +00:00
WhatFox
5116330180 #80 Enable logging from the UI. #31 Missing SCC results 2015-11-21 01:22:38 +00:00
flightlevel
cfe6ace07a Update README.md 2015-11-20 21:50:33 +11:00
flightlevel
2eb4356288 Update README.md 2015-11-20 21:37:46 +11:00
flightlevel
1ceff06def Merge pull request #77 from flightlevel/monoautoupdater
Autoupdater: Mono fix
2015-11-20 21:04:27 +11:00
flightlevel
57c4765fab Autoupdater: Mono fix
Autoupdater: Mono fix
2015-11-20 20:58:13 +11:00
flightlevel
f1188d548a Merge pull request #76 from Jackett/revert-71-monodebug
Revert "Debug Mono AutoUpdater"
2015-11-20 20:46:19 +11:00
flightlevel
327100ae6a Revert "Debug Mono AutoUpdater" 2015-11-20 20:46:07 +11:00
flightlevel
3ed887d926 Merge pull request #75 from Jackett/revert-72-monodebug2
Revert "MonoDebug2"
2015-11-20 20:45:41 +11:00
flightlevel
95f96662bf Revert "MonoDebug2" 2015-11-20 20:44:29 +11:00
flightlevel
f8b6b17c29 Merge pull request #72 from flightlevel/monodebug2
MonoDebug2
2015-11-19 22:20:23 +11:00
flightlevel
e6afe4d432 MonoDebug2
MonoDebug2
2015-11-19 22:15:50 +11:00
flightlevel
961f84f74d Merge pull request #71 from flightlevel/monodebug
Debug Mono AutoUpdater
2015-11-19 21:51:18 +11:00
flightlevel
934d5034e2 Debug Mono AutoUpdater
Debug Mono AutoUpdater
2015-11-19 21:47:22 +11:00
WhatFox
2310d08f99 Fix build 2015-11-18 20:03:55 +00:00
WhatFox
61a8585e43 Only allow private trackers 2015-11-18 20:00:26 +00:00
WhatFox
44aa33a7e0 Close tray app when updating 2015-11-18 19:39:40 +00:00
flightlevel
0b74f762a3 Merge pull request #68 from flightlevel/mtvseason
MoreThanTV: Fix season search
2015-11-18 23:00:14 +11:00
flightlevel
89460f1c73 MoreThanTV: Fix season search
MoreThanTV: Fix season search
2015-11-18 22:55:00 +11:00
flightlevel
6fbffb587b Merge pull request #55 from fuffenz/master
Basic support for GFT
2015-11-12 21:55:33 +11:00
Fuffenz
9342496a12 gft 2015-11-11 21:05:40 +01:00
Fuffenz
eb5d6d62f5 Merge remote-tracking branch 'refs/remotes/origin/GFTracker'
Conflicts:
	src/Jackett/Jackett.csproj
2015-11-11 20:58:35 +01:00
WhatFox
a134a77b9f Fix tray blocking updates 2015-11-10 22:18:58 +00:00
WhatFox
ee8464219f Fix windows installer 2015-11-10 22:02:02 +00:00
WhatFox
f8120363f4 Non-change to test updates 2015-11-10 21:27:37 +00:00
WhatFox
716be92693 Merge branch 'master' of https://github.com/Jackett/Jackett 2015-11-10 21:25:44 +00:00
WhatFox
73ea3d899d Fix migration breaking the install 2015-11-10 21:25:01 +00:00
What Fox
376888cd8f Merge pull request #54 from raspdealer/patch-3
Update README.md
2015-11-10 21:01:14 +00:00
WhatFox
bd672a36df Change auto update to use tokens for auth 2015-11-10 20:58:09 +00:00
Raspdealer
d5d0027843 Update README.md 2015-11-10 19:08:28 +01:00
flightlevel
e782456c99 Merge pull request #52 from flightlevel/BlueTigersFixCatParameter
Blue Tigers: Fix Category URL Parameter
2015-11-10 21:11:54 +11:00
flightlevel
d0596febac Blue Tigers: Fix Category URL Parameter
Blue Tigers: Fix Category URL Parameter
2015-11-10 21:10:52 +11:00
WhatFox
a9e14cc4af Auto update #8 2015-11-09 21:59:16 +00:00
flightlevel
35580224c7 Merge pull request #46 from flightlevel/BlueTigersTime
BlueTigers: GMT Time
2015-11-09 22:00:21 +11:00
flightlevel
b8bfa809e8 BlueTigers: GMT Time
BlueTigers: GMT Time
2015-11-09 21:58:38 +11:00
flightlevel
bf508d1700 Merge pull request #45 from flightlevel/BlueTigersCatMap
BlueTigers Category Mapping
2015-11-09 19:59:11 +11:00
flightlevel
601da8c51a BlueTigers Category Mapping
BlueTigers Category Mapping
2015-11-09 19:55:53 +11:00
flightlevel
714748e892 Merge pull request #43 from flightlevel/AssemblyVersion
Update Assembly Versions
2015-11-09 19:45:02 +11:00
flightlevel
6d07008e1f Merge pull request #42 from flightlevel/BeyondHdReCaptcha
BeyondHD: Add ReCaptcha
2015-11-09 19:37:44 +11:00
flightlevel
95abf9bb6a Update Assembly Versions
Update Assembly Versions: Now using AppVeyor for versioning, so not
required
2015-11-09 19:37:09 +11:00
flightlevel
9e7d2a2bee BeyondHD: Add ReCaptcha
BeyondHD: Add ReCaptcha to fix issue
https://github.com/Jackett/Jackett/issues/35
2015-11-09 19:30:09 +11:00
flightlevel
bfe453b4de Merge pull request #40 from flightlevel/bluetigers
Add BlueTigers Indexer
2015-11-08 12:55:37 +11:00
flightlevel
f999e6657b Add BlueTigers Indexer
Adds BlueTigers Indexer. Torznab Category mapping still to come.
2015-11-08 12:48:49 +11:00
flightlevel
02d0f9c5a1 Merge pull request #39 from flightlevel/nuget-update
Update NUGET Packages
2015-11-07 15:36:11 +11:00
flightlevel
4341136ddb Update NUGET Packages
Update NUGET Packages
2015-11-07 15:30:57 +11:00
flightlevel
afd5994d8b Merge pull request #37 from flightlevel/MissingViews
Comment Out Missing Views
2015-11-07 15:02:23 +11:00
flightlevel
a6dbd08dd0 Merge pull request #36 from flightlevel/master
Installer Config: Update AppURL
2015-11-07 14:56:32 +11:00
flightlevel
168aebb0fd Merge pull request #1 from flightlevel/update-installer
Installer Config: Update AppURL
2015-11-07 14:51:41 +11:00
flightlevel
2aa0dc7f4f Installer Config: Update AppURL
Update AppURL to https://github.com/Jackett/Jackett
2015-11-07 14:50:49 +11:00
flightlevel
0d9e687e66 Comment Out Missing Views
Fix errors found by Resharper
2015-11-07 12:20:49 +11:00
Fuffenz
a87cdc3443 copy gftracker logo on release build 2015-10-23 13:43:37 +02:00
Fuffenz
b65ab8b435 Basic GFTracker support 2015-10-23 00:31:59 +02:00
222 changed files with 8191 additions and 39051 deletions

1
.gitignore vendored
View File

@@ -196,3 +196,4 @@ FakesAssemblies/
*.opt
/Build.mono
/Build.windows
/Output

View File

@@ -11,6 +11,8 @@ copy /Y src\Jackett.Service\bin\Release\JackettService.exe build.windows\Jackett
copy /Y src\Jackett.Service\bin\Release\JackettService.exe.config build.windows\JackettService.exe.config
copy /Y src\Jackett.Tray\bin\Release\JackettTray.exe build.windows\JackettTray.exe
copy /Y src\Jackett.Tray\bin\Release\JackettTray.exe.config build.windows\JackettTray.exe.config
copy /Y src\Jackett.Updater\bin\Release\JackettUpdater.exe build.windows\JackettUpdater.exe
copy /Y src\Jackett.Updater\bin\Release\JackettUpdater.exe.config build.windows\JackettUpdater.exe.config
copy /Y LICENSE build.windows\LICENSE
copy /Y README.md build.windows\README.md
@@ -25,6 +27,8 @@ copy /Y src\Jackett.Service\bin\Release\JackettService.exe build.mono\JackettSer
copy /Y src\Jackett.Service\bin\Release\JackettService.exe.config build.mono\JackettService.exe.config
copy /Y src\Jackett.Tray\bin\Release\JackettTray.exe build.mono\JackettTray.exe
copy /Y src\Jackett.Tray\bin\Release\JackettTray.exe.config build.mono\JackettTray.exe.config
copy /Y src\Jackett.Updater\bin\Release\JackettUpdater.exe build.mono\JackettUpdater.exe
copy /Y src\Jackett.Updater\bin\Release\JackettUpdater.exe.config build.mono\JackettUpdater.exe.config
copy /Y LICENSE build.mono\LICENSE
copy /Y README.md build.mono\README.md
copy /Y Upstart.config build.mono\Upstart.config

View File

@@ -4,7 +4,7 @@
#define MyAppName "Jackett"
#define MyAppVersion GetFileVersion("build.windows/Jackett.dll")
#define MyAppPublisher "Jackett Inc."
#define MyAppURL "https://github.com/zone117x/Jackett"
#define MyAppURL "https://github.com/Jackett/Jackett"
#define MyAppExeName "JackettTray.exe"
[Setup]
@@ -24,9 +24,10 @@ DefaultGroupName={#MyAppName}
DisableProgramGroupPage=yes
OutputBaseFilename=setup
SetupIconFile=src\Jackett.Console\jackett.ico
UninstallDisplayIcon={app}\JackettConsole.exe
UninstallDisplayIcon={commonappdata}\Jackett\JackettConsole.exe
Compression=lzma
SolidCompression=yes
DisableDirPage=yes
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
@@ -36,26 +37,27 @@ Name: "windowsService"; Description: "Install as a Windows Service"
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
[Files]
Source: "build.windows\JackettTray.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "build.windows\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "build.windows\JackettTray.exe"; DestDir: "{commonappdata}\Jackett"; Flags: ignoreversion
Source: "build.windows\JackettUpdater.exe"; DestDir: "{commonappdata}\Jackett"; Flags: ignoreversion
Source: "build.windows\*"; DestDir: "{commonappdata}\Jackett"; Flags: ignoreversion recursesubdirs createallsubdirs
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{group}\{#MyAppName}"; Filename: "{commonappdata}\Jackett\{#MyAppExeName}"
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
Name: "{commondesktop}\{#MyAppName}"; Filename: "{commonappdata}\Jackett\{#MyAppExeName}"; Tasks: desktopicon
[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
Filename: "{commonappdata}\Jackett\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
[Run]
Filename: "{app}\JackettConsole.exe"; Parameters: "--Uninstall"; Flags: waituntilterminated;
Filename: "{app}\JackettConsole.exe"; Parameters: "--ReserveUrls"; Flags: waituntilterminated;
Filename: "{app}\JackettConsole.exe"; Parameters: "--MigrateSettings"; Flags: waituntilterminated;
Filename: "{app}\JackettConsole.exe"; Parameters: "--Install"; Flags: waituntilterminated; Tasks: windowsService
Filename: "{app}\JackettConsole.exe"; Parameters: "--Start"; Flags: waituntilterminated; Tasks: windowsService
Filename: "{commonappdata}\Jackett\JackettConsole.exe"; Parameters: "--Uninstall"; Flags: waituntilterminated;
Filename: "{commonappdata}\Jackett\JackettConsole.exe"; Parameters: "--ReserveUrls"; Flags: waituntilterminated;
Filename: "{commonappdata}\Jackett\JackettConsole.exe"; Parameters: "--MigrateSettings"; Flags: waituntilterminated;
Filename: "{commonappdata}\Jackett\JackettConsole.exe"; Parameters: "--Install"; Flags: waituntilterminated; Tasks: windowsService
Filename: "{commonappdata}\Jackett\JackettConsole.exe"; Parameters: "--Start"; Flags: waituntilterminated; Tasks: windowsService
[UninstallRun]
Filename: "{app}\JackettConsole.exe"; Parameters: "--Uninstall"; Flags: waituntilterminated skipifdoesntexist
Filename: "{commonappdata}\Jackett\JackettConsole.exe"; Parameters: "--Uninstall"; Flags: waituntilterminated skipifdoesntexist

105
README.md
View File

@@ -2,12 +2,10 @@
This project is a new fork and is recruiting development help. If you are able to help out please contact us.
#### Overview
This software creates a [Torznab](https://github.com/Sonarr/Sonarr/wiki/Implementing-a-Torznab-indexer) (with [nZEDb](https://github.com/nZEDb/nZEDb/blob/master/docs/newznab_api_specification.txt) category numbering) and [TorrentPotato](https://github.com/RuudBurger/CouchPotatoServer/wiki/Couchpotato-torrent-provider) API server on your machine. Torznab enables software such as [Sonarr](https://sonarr.tv) to access data from your favorite indexers in a similar fashion to rss but with added features such as searching. TorrentPotato is an interface accessible to [CouchPotato](https://couchpota.to/).
Jackett works as a proxy server: it translates queries from apps (Sonarr, SickRage, CouchPotato, Mylar, etc) into tracker-site-specific http queries, parses the html response, then sends results back to the requesting software. This allows for getting recent uploads (like RSS) and performing searches. Jackett is a single repository of maintained indexer scraping & translation logic - removing the burden from other apps.
We were previously focused on TV but are working on extending searches to allow for searching other items such as movies, comics, and music.
Developer note: The software implements the [Torznab](https://github.com/Sonarr/Sonarr/wiki/Implementing-a-Torznab-indexer) (with [nZEDb](https://github.com/nZEDb/nZEDb/blob/master/docs/newznab_api_specification.txt) category numbering) and [TorrentPotato](https://github.com/RuudBurger/CouchPotatoServer/wiki/Couchpotato-torrent-provider) APIs.
#### Supported Systems
@@ -15,46 +13,48 @@ We were previously focused on TV but are working on extending searches to allow
* Linux and OSX using Mono 4 (v3 should work but you may experience crashes).
#### Supported Trackers
* [AlphaRatio](https://alpharatio.cc/)
* [AnimeBytes](https://animebytes.tv/)
* [AnimeTorrents](http://animetorrents.me/)
* [Avistaz](https://avistaz.to/)
* [BakaBT](http://bakabt.me/)
* [bB](http://reddit.com/r/baconbits)
* [BeyondHD](https://beyondhd.me/)
* [BIT-HDTV](https://www.bit-hdtv.com)
* [BitMeTV](http://www.bitmetv.org/)
* [BTN](http://broadcasthe.net)
* [Demonoid](http://www.demonoid.pw/)
* [EuTorrents](https://eutorrents.to/)
* [FileList](http://filelist.ro/)
* [FrenchTorrentDb](http://www.frenchtorrentdb.com/)
* [Freshon](https://freshon.tv/)
* [HD-Space](https://hd-space.org/)
* [HD-Torrents.org](https://hd-torrents.org/)
* [Immortalseed.me](http://immortalseed.me)
* [IPTorrents](https://iptorrents.com/)
* [MoreThan.tv](https://morethan.tv/)
* [NextGen](https://nxtgn.org/)
* [pretome](https://pretome.info)
* [PrivateHD](https://privatehd.to/)
* [RARBG](https://rarbg.to/)
* [RuTor](http://rutor.org/)
* [SceneAccess](https://sceneaccess.eu/login)
* [SceneTime](https://www.scenetime.com/)
* [Shazbat](www.shazbat.tv/login)
* [ShowRSS](https://showrss.info/)
* [Strike](https://getstrike.net/)
* [T411](http://www.t411.io/)
* [TehConnection](https://tehconnection.eu/)
* [The Pirate Bay](https://thepiratebay.se/)
* [TorrentBytes](https://www.torrentbytes.net/)
* [TorrentDay](https://torrentday.eu/)
* [TorrentLeech](http://www.torrentleech.org/)
* [TorrentShack](http://torrentshack.me/)
* [Torrentz](https://torrentz.eu/)
* [TV Chaos UK](https://tvchaosuk.com/)
#### Supported Private Trackers
* Abnormal
* AlphaRatio
* AnimeBytes
* Avistaz
* bB
* BeyondHD
* BIT-HDTV
* BitMeTV
* BitSoup
* BlueTigers
* BTN
* DanishBits
* Demonoid
* EuTorrents
* FileList
* Fnt
* French-ADN
* Freshon
* HD-Space
* HD-Torrents
* Hounddawgs
* Immortalseed
* IPTorrents
* MoreThanTV
* NCore
* NextGen
* Pretome
* PrivateHD
* RevolutionTT
* SceneAccess
* SceneTime
* Shazbat
* SpeedCD
* TehConnection
* TorrentBytes
* TorrentDay
* TorrentLeech
* TorrentShack
* TV Chaos UK
* World-In-HD
* XSpeeds
#### Installation on Windows
@@ -68,18 +68,12 @@ Jackett can also be run from the command line using JackettConsole.exe if you wo
* Debian/Ubunutu: apt-get install libcurl-dev
* Redhat/Fedora: yum install libcurl-devel
* For other distros see the [Curl docs](http://curl.haxx.se/dlwiz/?type=devel).
3. Download and extract the latest ```.tar.bz2``` release from the [releases page](https://github.com/Jackett/Jackett/releases) and run Jackett using mono with the command "mono JackettConsole.exe".
3. Download and extract the latest ```.tar.gz``` release from the [releases page](https://github.com/Jackett/Jackett/releases) and run Jackett using mono with the command "mono JackettConsole.exe".
Detailed instructions for [Ubuntu 14.x](http://www.htpcguides.com/install-jackett-on-ubuntu-14-x-for-custom-torrents-in-sonarr/) and [Ubuntu 15.x](http://www.htpcguides.com/install-jackett-ubuntu-15-x-for-custom-torrents-in-sonarr/)
#### Installation on Synology
1. Install Sonarr & Mono 3.10 from synocommunity.
2. Install Mono beta 3.12 from the main Synology repo (Or newer if available).
3. Download jackett and place it in /opt/Jackett
4. cd /opt
5. chown -R {user who will run jackett} Jackett
6. Copy Upstart.config to /etc/init/jackett.conf and replace the braces {} in the script with the username that you wish to run Jackett with.
9. From anywhere on command line type "start jackett" . You should see output telling you that Jackett is running and you should be able to browse to {IP Address}:9117 . If not you should check /var/log/upstart/jackett.log and see what that says.
Jackett is available as beta package from [SynoCommuniy](https://synocommunity.com/)
#### Troubleshooting
@@ -89,14 +83,17 @@ You can pass various options when running via the command line, see --help for d
* Unable to connect to certain trackers on Linux
Try running with the "--SSLFix true" if you are on Redhat/Fedora/NNS based libcurl. If the tracker is currently configured try removing it and adding it again. Alternatively try running with a different client via --UseClient (Warning: safecurl just executes curl and your details may be seen from the process list).
Try running with the "--SSLFix true" if you are on Redhat/Fedora/NNS based libcurl. If the tracker is currently configured try removing it and adding it again. Alternatively try running with a different client via --UseClient (Warning: safecurl just executes curl and your details may be seen from the process list). You can also try running with the "--IgnoreSslErrors true" option which is useful if the site has an invalid SSL certificate.
* Enable logging
You can get additional logging with the switches "-t -l". Please post logs if you are unable to resolve your issue with these switches ensuring to remove your username/password/cookies.
#### Creating an issue
Please supply as much information about the problem you are experiencing as possible. Your issue has a much greater chance of being resolved if logs are supplied so that we can see what is going on. Creating an issue with '### isn't working' doesn't help anyone to fix the problem.
### Contributing
All contributions are welcome just send a pull request. Jackett's framework allows our team (and any other volunteering dev) to implement new trackers in an hour or two. If you'd like support for a new tracker but are not a developer then feel free to leave a request on the [issues page](https://github.com/zone117x/Jackett/issues). It is recommended to use Visual studio 2015 when making code changes in this project.
All contributions are welcome just send a pull request. Jackett's framework allows our team (and any other volunteering dev) to implement new trackers in an hour or two. If you'd like support for a new tracker but are not a developer then feel free to leave a request on the [issues page](https://github.com/zone117x/Jackett/issues). It is recommended to use Visual studio 2015 when making code changes in this project. We currently only support private trackers.
### Screenshots

View File

@@ -1,38 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.5.0.0" newVersion="3.5.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="AutoMapper" publicKeyToken="be96cd2c38ef1005" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.4.0" newVersion="4.0.4.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.5.0.0" newVersion="3.5.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="AutoMapper" publicKeyToken="be96cd2c38ef1005" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.4.0" newVersion="4.0.4.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -27,6 +27,9 @@ namespace Jackett.Console
[Option('c', "UseClient", HelpText = "Override web client selection. [automatic(Default)/libcurl/safecurl/httpclient]")]
public string Client { get; set; }
[Option('j', "ProxyConnection", HelpText = "use proxy - e.g. 127.0.0.1:8888")]
public string ProxyConnection { get; set; }
[Option('s', "Start", HelpText = "Start the Jacket Windows service (Must be admin)")]
public bool StartService { get; set; }
@@ -54,6 +57,9 @@ namespace Jackett.Console
[Option('f', "SSLFix", HelpText = "[true/false] Linux Libcurl NSS Missing ECC Ciphers workaround (Use if you can't access some trackers) .")]
public bool? SSLFix { get; set; }
[Option('n', "IgnoreSslErrors", HelpText = "[true/false] Linux Libcurl - Ignores invalid SSL certificates")]
public bool? IgnoreSslErrors { get; set; }
[ParserState]
public IParserState LastParserState { get; set; }
}

View File

@@ -1,180 +1,180 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{4E2A81DA-E235-4A88-AD20-38AABBFBF33C}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Jackett.Console</RootNamespace>
<AssemblyName>JackettConsole</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>jackett.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<StartupObject>JackettConsole.Program</StartupObject>
</PropertyGroup>
<ItemGroup>
<Reference Include="Autofac, Version=3.5.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.3.5.2\lib\net40\Autofac.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Autofac.Integration.Owin, Version=3.1.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.Owin.3.1.0\lib\net45\Autofac.Integration.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Autofac.Integration.WebApi, Version=3.4.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.WebApi2.3.4.0\lib\net45\Autofac.Integration.WebApi.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Autofac.Integration.WebApi.Owin, Version=3.2.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.WebApi2.Owin.3.2.0\lib\net45\Autofac.Integration.WebApi.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="AutoMapper, Version=4.0.4.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.4.0.4\lib\net45\AutoMapper.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="CommandLine, Version=1.9.71.2, Culture=neutral, PublicKeyToken=de6f01bd326f8c32, processorArchitecture=MSIL">
<HintPath>..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.AspNet.Identity.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.FileSystems, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.FileSystems.3.0.1\lib\net45\Microsoft.Owin.FileSystems.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.Host.HttpListener, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Host.HttpListener.3.0.1\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.Host.SystemWeb, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Host.SystemWeb.3.0.1\lib\net45\Microsoft.Owin.Host.SystemWeb.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.Hosting, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Hosting.3.0.1\lib\net45\Microsoft.Owin.Hosting.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.StaticFiles, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.StaticFiles.3.0.1\lib\net45\Microsoft.Owin.StaticFiles.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.0.1\lib\net45\NLog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Net.Http.Extensions, Version=2.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.Primitives, Version=4.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Http.Owin, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Http.Tracing, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Tracing.5.2.3\lib\net45\System.Web.Http.Tracing.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ConsoleOptions.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CurlSharp\CurlSharp.csproj">
<Project>{74420a79-cc16-442c-8b1e-7c1b913844f0}</Project>
<Name>CurlSharp</Name>
</ProjectReference>
<ProjectReference Include="..\Jackett\Jackett.csproj">
<Project>{e636d5f8-68b4-4903-b4ed-ccfd9c9e899f}</Project>
<Name>Jackett</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="jackett.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{4E2A81DA-E235-4A88-AD20-38AABBFBF33C}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Jackett.Console</RootNamespace>
<AssemblyName>JackettConsole</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>jackett.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<StartupObject>JackettConsole.Program</StartupObject>
</PropertyGroup>
<ItemGroup>
<Reference Include="Autofac, Version=3.5.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.3.5.2\lib\net40\Autofac.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Autofac.Integration.Owin, Version=3.1.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.Owin.3.1.0\lib\net45\Autofac.Integration.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Autofac.Integration.WebApi, Version=3.4.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.WebApi2.3.4.0\lib\net45\Autofac.Integration.WebApi.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Autofac.Integration.WebApi.Owin, Version=3.3.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.WebApi2.Owin.3.3.0\lib\net45\Autofac.Integration.WebApi.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="AutoMapper, Version=4.1.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.4.1.1\lib\net45\AutoMapper.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="CommandLine, Version=1.9.71.2, Culture=neutral, PublicKeyToken=de6f01bd326f8c32, processorArchitecture=MSIL">
<HintPath>..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.AspNet.Identity.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.FileSystems, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.FileSystems.3.0.1\lib\net45\Microsoft.Owin.FileSystems.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.Host.HttpListener, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Host.HttpListener.3.0.1\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.Host.SystemWeb, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Host.SystemWeb.3.0.1\lib\net45\Microsoft.Owin.Host.SystemWeb.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.Hosting, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Hosting.3.0.1\lib\net45\Microsoft.Owin.Hosting.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.StaticFiles, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.StaticFiles.3.0.1\lib\net45\Microsoft.Owin.StaticFiles.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.2.3\lib\net45\NLog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Net.Http.Extensions, Version=2.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.Primitives, Version=4.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Http.Owin, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Http.Tracing, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Tracing.5.2.3\lib\net45\System.Web.Http.Tracing.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ConsoleOptions.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CurlSharp\CurlSharp.csproj">
<Project>{74420a79-cc16-442c-8b1e-7c1b913844f0}</Project>
<Name>CurlSharp</Name>
</ProjectReference>
<ProjectReference Include="..\Jackett\Jackett.csproj">
<Project>{e636d5f8-68b4-4903-b4ed-ccfd9c9e899f}</Project>
<Name>Jackett</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="jackett.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -1,212 +1,226 @@
using CommandLine;
using CommandLine.Text;
using Jackett;
using Jackett.Console;
using Jackett.Indexers;
using Jackett.Utils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
namespace JackettConsole
{
public class Program
{
static void Main(string[] args)
{
try
{
var options = new ConsoleOptions();
if (!Parser.Default.ParseArguments(args, options) || options.ShowHelp == true)
{
if (options.LastParserState != null && options.LastParserState.Errors.Count > 0)
{
var help = new HelpText();
var errors = help.RenderParsingErrorsText(options, 2); // indent with two spaces
Console.WriteLine("Jackett v" + Engine.ConfigService.GetVersion());
Console.WriteLine("Switch error: " + errors);
Console.WriteLine("See --help for further details on switches.");
Environment.ExitCode = 1;
return;
}
else
{
var text = HelpText.AutoBuild(options, (HelpText current) => HelpText.DefaultParsingErrorsHandler(options, current));
text.Copyright = " ";
text.Heading = "Jackett v" + Engine.ConfigService.GetVersion() + " options:";
Console.WriteLine(text);
Environment.ExitCode = 1;
return;
}
}
else
{
if (options.ListenPublic && options.ListenPrivate)
{
Console.WriteLine("You can only use listen private OR listen publicly.");
Environment.ExitCode = 1;
return;
}
/* ====== Options ===== */
// SSL Fix
Startup.DoSSLFix = options.SSLFix;
// Use curl
if (options.Client != null)
Startup.ClientOverride = options.Client.ToLowerInvariant();
// Logging
if (options.Logging)
Startup.LogRequests = true;
// Tracing
if (options.Tracing)
Startup.TracingEnabled = true;
// Log after the fact as using the logger will cause the options above to be used
if (options.Logging)
Engine.Logger.Info("Logging enabled.");
if (options.Tracing)
Engine.Logger.Info("Tracing enabled.");
if (options.SSLFix == true)
Engine.Logger.Info("SSL ECC workaround enabled.");
else if (options.SSLFix == false)
Engine.Logger.Info("SSL ECC workaround has been disabled.");
/* ====== Actions ===== */
// Install service
if (options.Install)
{
Engine.ServiceConfig.Install();
return;
}
// Uninstall service
if (options.Uninstall)
{
Engine.Server.ReserveUrls(doInstall: false);
Engine.ServiceConfig.Uninstall();
return;
}
// Reserve urls
if (options.ReserveUrls)
{
Engine.Server.ReserveUrls(doInstall: true);
return;
}
// Start Service
if (options.StartService)
{
if (!Engine.ServiceConfig.ServiceRunning())
{
Engine.ServiceConfig.Start();
}
return;
}
// Stop Service
if (options.StopService)
{
if (Engine.ServiceConfig.ServiceRunning())
{
Engine.ServiceConfig.Stop();
}
return;
}
// Migrate settings
if (options.MigrateSettings)
{
Engine.ConfigService.PerformMigration();
return;
}
// Show Version
if (options.ShowVersion)
{
Console.WriteLine("Jackett v" + Engine.ConfigService.GetVersion());
return;
}
/* ====== Overrides ===== */
// Override listen public
if (options.ListenPublic || options.ListenPrivate)
{
if (Engine.Server.Config.AllowExternal != options.ListenPublic)
{
Engine.Logger.Info("Overriding external access to " + options.ListenPublic);
Engine.Server.Config.AllowExternal = options.ListenPublic;
if (System.Environment.OSVersion.Platform != PlatformID.Unix)
{
if (ServerUtil.IsUserAdministrator())
{
Engine.Server.ReserveUrls(doInstall: true);
}
else
{
Engine.Logger.Error("Unable to switch to public listening without admin rights.");
Environment.ExitCode = 1;
return;
}
}
Engine.Server.SaveConfig();
}
}
// Override port
if (options.Port != 0)
{
if (Engine.Server.Config.Port != options.Port)
{
Engine.Logger.Info("Overriding port to " + options.Port);
Engine.Server.Config.Port = options.Port;
if (System.Environment.OSVersion.Platform != PlatformID.Unix)
{
if (ServerUtil.IsUserAdministrator())
{
Engine.Server.ReserveUrls(doInstall: true);
}
else
{
Engine.Logger.Error("Unable to switch ports when not running as administrator");
Environment.ExitCode = 1;
return;
}
}
Engine.Server.SaveConfig();
}
}
}
Engine.Server.Initalize();
Engine.Server.Start();
Engine.RunTime.Spin();
Engine.Logger.Info("Server thread exit");
}
catch (Exception e)
{
Engine.Logger.Error(e, "Top level exception");
}
}
}
}
using CommandLine;
using CommandLine.Text;
using Jackett;
using Jackett.Console;
using Jackett.Indexers;
using Jackett.Utils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
namespace JackettConsole
{
public class Program
{
static void Main(string[] args)
{
try
{
var options = new ConsoleOptions();
if (!Parser.Default.ParseArguments(args, options) || options.ShowHelp == true)
{
if (options.LastParserState != null && options.LastParserState.Errors.Count > 0)
{
var help = new HelpText();
var errors = help.RenderParsingErrorsText(options, 2); // indent with two spaces
Console.WriteLine("Jackett v" + Engine.ConfigService.GetVersion());
Console.WriteLine("Switch error: " + errors);
Console.WriteLine("See --help for further details on switches.");
Environment.ExitCode = 1;
return;
}
else
{
var text = HelpText.AutoBuild(options, (HelpText current) => HelpText.DefaultParsingErrorsHandler(options, current));
text.Copyright = " ";
text.Heading = "Jackett v" + Engine.ConfigService.GetVersion() + " options:";
Console.WriteLine(text);
Environment.ExitCode = 1;
return;
}
}
else
{
if (options.ListenPublic && options.ListenPrivate)
{
Console.WriteLine("You can only use listen private OR listen publicly.");
Environment.ExitCode = 1;
return;
}
/* ====== Options ===== */
// SSL Fix
Startup.DoSSLFix = options.SSLFix;
// Use curl
if (options.Client != null)
Startup.ClientOverride = options.Client.ToLowerInvariant();
// Use Proxy
if (options.ProxyConnection != null)
{
Startup.ProxyConnection = options.ProxyConnection.ToLowerInvariant();
Engine.Logger.Info("Proxy enabled. " + Startup.ProxyConnection);
}
// Logging
if (options.Logging)
Startup.LogRequests = true;
// Tracing
if (options.Tracing)
Startup.TracingEnabled = true;
// Log after the fact as using the logger will cause the options above to be used
if (options.Logging)
Engine.Logger.Info("Logging enabled.");
if (options.Tracing)
Engine.Logger.Info("Tracing enabled.");
if (options.SSLFix == true)
Engine.Logger.Info("SSL ECC workaround enabled.");
else if (options.SSLFix == false)
Engine.Logger.Info("SSL ECC workaround has been disabled.");
// Ignore SSL errors on Curl
Startup.IgnoreSslErrors = options.IgnoreSslErrors;
if (options.IgnoreSslErrors == true)
{
Engine.Logger.Info("Curl will ignore SSL certificate errors.");
}
/* ====== Actions ===== */
// Install service
if (options.Install)
{
Engine.ServiceConfig.Install();
return;
}
// Uninstall service
if (options.Uninstall)
{
Engine.Server.ReserveUrls(doInstall: false);
Engine.ServiceConfig.Uninstall();
return;
}
// Reserve urls
if (options.ReserveUrls)
{
Engine.Server.ReserveUrls(doInstall: true);
return;
}
// Start Service
if (options.StartService)
{
if (!Engine.ServiceConfig.ServiceRunning())
{
Engine.ServiceConfig.Start();
}
return;
}
// Stop Service
if (options.StopService)
{
if (Engine.ServiceConfig.ServiceRunning())
{
Engine.ServiceConfig.Stop();
}
return;
}
// Migrate settings
if (options.MigrateSettings)
{
Engine.ConfigService.PerformMigration();
return;
}
// Show Version
if (options.ShowVersion)
{
Console.WriteLine("Jackett v" + Engine.ConfigService.GetVersion());
return;
}
/* ====== Overrides ===== */
// Override listen public
if (options.ListenPublic || options.ListenPrivate)
{
if (Engine.Server.Config.AllowExternal != options.ListenPublic)
{
Engine.Logger.Info("Overriding external access to " + options.ListenPublic);
Engine.Server.Config.AllowExternal = options.ListenPublic;
if (System.Environment.OSVersion.Platform != PlatformID.Unix)
{
if (ServerUtil.IsUserAdministrator())
{
Engine.Server.ReserveUrls(doInstall: true);
}
else
{
Engine.Logger.Error("Unable to switch to public listening without admin rights.");
Environment.ExitCode = 1;
return;
}
}
Engine.Server.SaveConfig();
}
}
// Override port
if (options.Port != 0)
{
if (Engine.Server.Config.Port != options.Port)
{
Engine.Logger.Info("Overriding port to " + options.Port);
Engine.Server.Config.Port = options.Port;
if (System.Environment.OSVersion.Platform != PlatformID.Unix)
{
if (ServerUtil.IsUserAdministrator())
{
Engine.Server.ReserveUrls(doInstall: true);
}
else
{
Engine.Logger.Error("Unable to switch ports when not running as administrator");
Environment.ExitCode = 1;
return;
}
}
Engine.Server.SaveConfig();
}
}
}
Engine.Server.Initalize();
Engine.Server.Start();
Engine.RunTime.Spin();
Engine.Logger.Info("Server thread exit");
}
catch (Exception e)
{
Engine.Logger.Error(e, "Top level exception");
}
}
}
}

View File

@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("0.0.0.0")]
[assembly: AssemblyFileVersion("0.0.0.0")]

View File

@@ -1,27 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Autofac" version="3.5.2" targetFramework="net45" />
<package id="Autofac.Owin" version="3.1.0" targetFramework="net45" />
<package id="Autofac.WebApi2" version="3.4.0" targetFramework="net45" />
<package id="Autofac.WebApi2.Owin" version="3.2.0" targetFramework="net45" />
<package id="AutoMapper" version="4.0.4" targetFramework="net45" />
<package id="CommandLineParser" version="1.9.71" targetFramework="net45" />
<package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.OwinSelfHost" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Tracing" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net45" />
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net45" />
<package id="Microsoft.Net.Http" version="2.2.29" targetFramework="net45" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.FileSystems" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Host.HttpListener" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Host.SystemWeb" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Hosting" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.StaticFiles" version="3.0.1" targetFramework="net45" />
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
<package id="NLog" version="4.0.1" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Autofac" version="3.5.2" targetFramework="net45" />
<package id="Autofac.Owin" version="3.1.0" targetFramework="net45" />
<package id="Autofac.WebApi2" version="3.4.0" targetFramework="net45" />
<package id="Autofac.WebApi2.Owin" version="3.3.0" targetFramework="net45" />
<package id="AutoMapper" version="4.1.1" targetFramework="net45" />
<package id="CommandLineParser" version="1.9.71" targetFramework="net45" />
<package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.OwinSelfHost" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Tracing" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net45" />
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net45" />
<package id="Microsoft.Net.Http" version="2.2.29" targetFramework="net45" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.FileSystems" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Host.HttpListener" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Host.SystemWeb" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Hosting" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.StaticFiles" version="3.0.1" targetFramework="net45" />
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
<package id="NLog" version="4.2.3" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
</packages>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
</startup>
</configuration>

View File

@@ -1,67 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{99D893EC-1A8A-42A9-AC6B-FE047AFC32F0}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Jackett.Distribution</RootNamespace>
<AssemblyName>JackettDistribution</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Octokit, Version=0.14.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Octokit.0.14.0\lib\net45\Octokit.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -1,127 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.IO.Compression;
using Octokit;
using Octokit.Internal;
namespace Jackett.Distribution
{
class Program
{
static readonly string repoOwner = "zone117x";
static readonly string repoName = "Jackett";
static readonly string jackettLibPath = Path.Combine("build.windows", "Jackett.dll");
static readonly string buildZipFileWindows = "JackettBuildWindows.zip";
static readonly string buildZipFileMono = "JackettBuildMono.zip";
static readonly string installFile = Path.Combine("Output", "setup.exe");
static GitHubClient github;
static Version localVersion;
static void Main(string[] args)
{
if (args.Length == 0)
{
throw new Exception("Missing github API token argument");
}
var token = args[0];
github = new GitHubClient(new ProductHeaderValue("Jackett"));
github.Credentials = new Credentials(token);
localVersion = GetJackettVersion();
/*var latestReleaseVersion = LatestGithubRelease().Result;
if (localVersion <= latestReleaseVersion)
{
Console.WriteLine("Latest Github release is {0}, will not upload local version {1}", latestReleaseVersion, localVersion);
return;
}*/
Console.WriteLine("Zipping release build for Windows " + localVersion);
ZippingReleaseBuildWindows();
Console.WriteLine("Zipping release build for Mono " + localVersion);
ZippingReleaseBuildMono();
UploadRelease().Wait();
}
static Version GetJackettVersion()
{
var assemblyVersion = AssemblyName.GetAssemblyName(jackettLibPath).Version;
return new Version(assemblyVersion.Major, assemblyVersion.Minor, assemblyVersion.Build);
}
static async Task<Version> LatestGithubRelease()
{
var releases = await github.Release.GetAll(repoOwner, repoName);
var latest = releases.Where(t => t.PublishedAt != null).OrderByDescending(t => t.TagName).FirstOrDefault();
var version = Version.Parse(latest.TagName.Replace("v", ""));
return version;
}
static void ZippingReleaseBuildWindows()
{
if (File.Exists(buildZipFileWindows))
File.Delete(buildZipFileWindows);
ZipFile.CreateFromDirectory("build.windows", buildZipFileWindows);
}
static void ZippingReleaseBuildMono()
{
if (File.Exists(buildZipFileMono))
File.Delete(buildZipFileMono);
ZipFile.CreateFromDirectory("build.mono", buildZipFileMono);
}
static async Task UploadRelease()
{
// get last master commit to tag
/*var masterBranch = await github.Repository.GetBranch(repoOwner, repoName, "master");
var lastCommit = masterBranch.Commit.Sha;
// create tag
var tagName = "v" + localVersion.ToString();
var tag = new NewTag
{
Message = "Tagging a new release of Jackett",
Tag = tagName,
Object = lastCommit,
Type = TaggedType.Commit,
Tagger = new SignatureResponse("DistributionBot", "zone117x@gmail.com", DateTime.UtcNow)
};
var tagResult = await github.GitDatabase.Tag.Create(repoOwner, repoName, tag);*/
// create release entry
var newRelease = new NewRelease("v" + localVersion.ToString());
newRelease.Name = "Beta Release";
newRelease.Body = "";
newRelease.Draft = true;
newRelease.Prerelease = false;
var releaseResult = await github.Release.Create(repoOwner, repoName, newRelease);
Console.WriteLine("Uploading Windows build");
await UploadFileToGithub(releaseResult, buildZipFileWindows, string.Format("Jackett.Windows.v{0}.zip", localVersion), "application/zip");
Console.WriteLine("Uploading Mono build");
await UploadFileToGithub(releaseResult, buildZipFileMono, string.Format("Jackett.Mono.v{0}.zip", localVersion), "application/zip");
Console.WriteLine("Uploading Windows installer");
await UploadFileToGithub(releaseResult, installFile, string.Format("Jackett.v{0}.Windows.Installer.exe", localVersion), "application/octet-stream");
}
static Task UploadFileToGithub(Release githubRelease, string filePath, string filePublishName, string contentType)
{
var buildZipAssetWindows = new ReleaseAssetUpload()
{
FileName = filePublishName,
ContentType = contentType,
RawData = File.OpenRead(filePath)
};
return github.Release.UploadAsset(githubRelease, buildZipAssetWindows);
}
}
}

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Octokit" version="0.14.0" targetFramework="net45" />
</packages>

View File

@@ -1,30 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -1,167 +1,167 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{BF611F7B-4658-4CB8-AA9E-0736FADAA3BA}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Jackett.Service</RootNamespace>
<AssemblyName>JackettService</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>jackett.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="Autofac, Version=3.5.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.3.5.2\lib\net40\Autofac.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Autofac.Integration.Owin, Version=3.1.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.Owin.3.1.0\lib\net45\Autofac.Integration.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Autofac.Integration.WebApi, Version=3.4.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.WebApi2.3.4.0\lib\net45\Autofac.Integration.WebApi.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Autofac.Integration.WebApi.Owin, Version=3.2.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.WebApi2.Owin.3.2.0\lib\net45\Autofac.Integration.WebApi.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.FileSystems, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.FileSystems.3.0.1\lib\net45\Microsoft.Owin.FileSystems.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.Host.HttpListener, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Host.HttpListener.3.0.1\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.Hosting, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Hosting.3.0.1\lib\net45\Microsoft.Owin.Hosting.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.StaticFiles, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.StaticFiles.3.0.1\lib\net45\Microsoft.Owin.StaticFiles.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.0.1\lib\net45\NLog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Net.Http.Extensions, Version=2.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.Primitives, Version=4.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Http.Owin, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Http.Tracing, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Tracing.5.2.3\lib\net45\System.Web.Http.Tracing.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Service.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Service.Designer.cs">
<DependentUpon>Service.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Content Include="jackett.ico" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CurlSharp\CurlSharp.csproj">
<Project>{74420a79-cc16-442c-8b1e-7c1b913844f0}</Project>
<Name>CurlSharp</Name>
</ProjectReference>
<ProjectReference Include="..\Jackett\Jackett.csproj">
<Project>{e636d5f8-68b4-4903-b4ed-ccfd9c9e899f}</Project>
<Name>Jackett</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{BF611F7B-4658-4CB8-AA9E-0736FADAA3BA}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Jackett.Service</RootNamespace>
<AssemblyName>JackettService</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>jackett.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="Autofac, Version=3.5.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.3.5.2\lib\net40\Autofac.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Autofac.Integration.Owin, Version=3.1.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.Owin.3.1.0\lib\net45\Autofac.Integration.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Autofac.Integration.WebApi, Version=3.4.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.WebApi2.3.4.0\lib\net45\Autofac.Integration.WebApi.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Autofac.Integration.WebApi.Owin, Version=3.3.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.WebApi2.Owin.3.3.0\lib\net45\Autofac.Integration.WebApi.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.FileSystems, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.FileSystems.3.0.1\lib\net45\Microsoft.Owin.FileSystems.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.Host.HttpListener, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Host.HttpListener.3.0.1\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.Hosting, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Hosting.3.0.1\lib\net45\Microsoft.Owin.Hosting.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.StaticFiles, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.StaticFiles.3.0.1\lib\net45\Microsoft.Owin.StaticFiles.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.2.3\lib\net45\NLog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Net.Http.Extensions, Version=2.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.Primitives, Version=4.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Http.Owin, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Http.Tracing, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Tracing.5.2.3\lib\net45\System.Web.Http.Tracing.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Service.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Service.Designer.cs">
<DependentUpon>Service.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Content Include="jackett.ico" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CurlSharp\CurlSharp.csproj">
<Project>{74420a79-cc16-442c-8b1e-7c1b913844f0}</Project>
<Name>CurlSharp</Name>
</ProjectReference>
<ProjectReference Include="..\Jackett\Jackett.csproj">
<Project>{e636d5f8-68b4-4903-b4ed-ccfd9c9e899f}</Project>
<Name>Jackett</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("0.0.0.0")]
[assembly: AssemblyFileVersion("0.0.0.0")]

View File

@@ -1,23 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Autofac" version="3.5.2" targetFramework="net45" />
<package id="Autofac.Owin" version="3.1.0" targetFramework="net45" />
<package id="Autofac.WebApi2" version="3.4.0" targetFramework="net45" />
<package id="Autofac.WebApi2.Owin" version="3.2.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.OwinSelfHost" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Tracing" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net45" />
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net45" />
<package id="Microsoft.Net.Http" version="2.2.29" targetFramework="net45" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.FileSystems" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Host.HttpListener" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Hosting" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.StaticFiles" version="3.0.1" targetFramework="net45" />
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
<package id="NLog" version="4.0.1" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Autofac" version="3.5.2" targetFramework="net45" />
<package id="Autofac.Owin" version="3.1.0" targetFramework="net45" />
<package id="Autofac.WebApi2" version="3.4.0" targetFramework="net45" />
<package id="Autofac.WebApi2.Owin" version="3.3.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.OwinSelfHost" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Tracing" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net45" />
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net45" />
<package id="Microsoft.Net.Http" version="2.2.29" targetFramework="net45" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.FileSystems" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Host.HttpListener" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Hosting" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.StaticFiles" version="3.0.1" targetFramework="net45" />
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
<package id="NLog" version="4.2.3" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
</packages>

View File

@@ -1,177 +0,0 @@
using Jackett.Utils.Clients;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autofac;
using Jackett.Indexers;
using FluentAssertions;
using Newtonsoft.Json.Linq;
using Jackett;
using Newtonsoft.Json;
namespace JackettTest.Indexers
{
[TestFixture]
class BakaBTTests : TestBase
{
[Test]
public async void should_return_be_able_to_login_successfully()
{
// Do Login
TestUtil.RegisterStringCall(new WebRequest()
{
Url = "http://bakabt.me/login.php",
Cookies = "bbtid=b",
Type = RequestType.POST,
Referer = "http://bakabt.me/",
PostData = new Dictionary<string, string>()
{
{"username", "user" },
{"password", "pwd" },
{"returnto", "/index.php" }
}
}, (req) => {
return new WebClientStringResult()
{
Status = System.Net.HttpStatusCode.Found,
Cookies = "bbtid=c",
};
});
// Get login form
TestUtil.RegisterStringCall(new WebRequest()
{
Url = "http://bakabt.me/login.php",
Type = RequestType.GET
}, (req) => {
return new WebClientStringResult()
{
Cookies = "bbtid=b",
Status = System.Net.HttpStatusCode.Found
};
});
// Get logged in page
TestUtil.RegisterStringCall(new WebRequest()
{
Cookies = "bbtid=c",
Type = RequestType.GET,
Url = "http://bakabt.me/browse.php?only=0&hentai=1&incomplete=1&lossless=1&hd=1&multiaudio=1&bonus=1&c1=1&reorder=1&q="
}, (req) => {
return new WebClientStringResult()
{
Content = TestUtil.GetResource("Indexers/BakaBTTestsSearchPage.html"),
Status = System.Net.HttpStatusCode.OK
};
});
var indexer = TestUtil.Container.ResolveNamed<IIndexer>(BakaBT.GetIndexerID(typeof(BakaBT))) as BakaBT;
indexer.DisplayName.Should().Be("BakaBT");
indexer.DisplayDescription.Should().Be("Anime Community");
indexer.ID.Should().Be("bakabt");
indexer.LoginUrl.Should().Be("http://bakabt.me/login.php");
var token = JObject.Parse("{\"username\":\"user\",\"password\":\"pwd\"}");
await indexer.ApplyConfiguration(token);
indexer.IsConfigured.Should().Be(true);
((string)TestUtil.IndexManager.LastSavedConfig["cookies"]).Should().Be("bbtid=c");
}
[Test]
public async void should_return_be_able_to_login_unsuccessfully()
{
// Do Login
TestUtil.RegisterStringCall(new WebRequest()
{
Url = "http://bakabt.me/login.php",
Cookies = "bbtid=b",
Type = RequestType.POST,
Referer = "http://bakabt.me/",
PostData = new Dictionary<string, string>()
{
{"username", "user" },
{"password", "pwd" },
{"returnto", "/index.php" }
}
}, (req) => {
return new WebClientStringResult()
{
Status = System.Net.HttpStatusCode.OK,
Cookies = "bbtid=c",
Content = TestUtil.GetResource("Indexers/BakaBTTestsLoginError.html"),
};
});
// Get login form
TestUtil.RegisterStringCall(new WebRequest()
{
Url = "http://bakabt.me/login.php",
Type = RequestType.GET
}, (req) => {
return new WebClientStringResult()
{
Cookies = "bbtid=b",
Status = System.Net.HttpStatusCode.Found
};
});
var indexer = TestUtil.Container.ResolveNamed<IIndexer>(BakaBT.GetIndexerID(typeof(BakaBT))) as BakaBT;
var token = JObject.Parse("{\"username\":\"user\",\"password\":\"pwd\"}");
try {
await indexer.ApplyConfiguration(token);
}
catch(ExceptionWithConfigData e)
{
e.Message.Should().Be("Username or password is incorrect");
}
indexer.IsConfigured.Should().Be(false);
}
[Test]
public async void should_return_be_able_to_scrape_the_search_page()
{
// Do Search
TestUtil.RegisterStringCall(new WebRequest()
{
Url = "http://bakabt.me/browse.php?only=0&hentai=1&incomplete=1&lossless=1&hd=1&multiaudio=1&bonus=1&c1=1&reorder=1&q=Series",
Cookies = "bbtid=c",
Type = RequestType.GET
}, (req) => {
return new WebClientStringResult()
{
Status = System.Net.HttpStatusCode.OK,
Cookies = "bbtid=c",
Content = TestUtil.GetResource("Indexers/BakaBTTestsSearchPage.html"),
};
});
var indexer = TestUtil.Container.ResolveNamed<IIndexer>(BakaBT.GetIndexerID(typeof(BakaBT))) as BakaBT;
indexer.LoadFromSavedConfiguration(JObject.Parse("{\"cookies\":\"bbtid=c\"}"));
var results = await indexer.PerformQuery(new Jackett.Models.TorznabQuery() { SearchTerm = "Series S1", Season = 1 });
results.Count().Should().Be(44);
results.First().Title.Should().Be("Golden Time Season 1 (BD 720p) [FFF]");
results.First().Guid.Should().Be("http://bakabt.me/torrent/180302/golden-time-bd-720p-fff");
results.First().Comments.Should().Be("http://bakabt.me/torrent/180302/golden-time-bd-720p-fff");
results.First().Size.Should().Be(10307921920);
results.First().Description.Should().Be("Golden Time Season 1 (BD 720p) [FFF]");
results.First().Link.Should().Be("http://bakabt.me/torrent/180302/golden-time-bd-720p-fff");
results.First().Peers.Should().Be(161);
results.First().Seeders.Should().Be(151);
results.First().MinimumRatio.Should().Be(1);
results.ElementAt(1).Title.Should().Be("Yowamushi Pedal Season 1 (BD 720p) [Commie]");
results.ElementAt(4).Title.Should().Be("Dungeon ni Deai o Motomeru no wa Machigatte Iru Darouka: Familia Myth Season 1 (480p) [HorribleSubs]");
results.ElementAt(5).Title.Should().Be("Is It Wrong to Try to Pick Up Girls in a Dungeon? Season 1 (480p) [HorribleSubs]");
}
}
}

View File

@@ -1,59 +0,0 @@
<html class="">
<head>
<meta charset="utf-8">
<title>Login - BakaBT</title>
<link rel="shortcut icon" href="/resources/img/favicon.png">
<base href="/">
<script type="text/javascript" async="" src="http://www.google-analytics.com/ga.js"></script>
<script type="text/javascript" src="resources/61ccf6a181efcd89748c30755b9c6541.js"></script>
<link rel="stylesheet" type="text/css" href="resources/61ccf6a181efcd89748c30755b9c6541.css">
<script type="text/javascript">var user = create_user({"id":0,"class":0,"avatars":false});</script>
<style type="text/css">
.fancybox-margin {
margin-right: 15px;
}
</style>
<style type="text/css">
@media print {
.lpiframeoverlay {
display: none;
}
}
</style>
</head>
<body>
<div class="dango"></div><div class="heart" style="transform: rotate(0deg); bottom: 50px; right: 55px;"></div><div class="main">
<div class="banner" style="background-image:url(images/banners/Grimmjow.jpg);"><a href="" class="home"></a><a href="rss.php?uid=0&amp;pass=" class="icon rss" title="RSS Feed"></a></div><div class="headerbar"><ul><li><a href="">News</a></li><li><a href="browse.php">Browse</a></li><li><a href="http://forums.bakabt.me">Forums</a></li><li><a href="http://bakashots.me">BakaSHOTS</a><ul><li><a href="http://compare.bakashots.me">BakaCOMPARE</a></li></ul></li><li><a href="http://wiki.bakabt.me">Wiki</a><ul><li><a href="http://wiki.bakabt.me/index.php/Rules">Rules</a></li><li><a href="http://wiki.bakabt.me/index.php/FAQ">FAQ</a></li></ul></li><li><a href="http://wiki.bakabt.me/index.php/IRC" title="#bakabt@irc.rizon.net">IRC</a><ul><li><a href="webirc.php">Web IRC</a></li></ul></li><li><a href="http://www.cafepress.com/bakabt">Store</a></li><li><a href="donate.php">Donate</a></li><li><a href="#" onclick="return false;">More…</a><ul><li><a href="http://blog.bakabt.me">Blog</a></li><li><a href="topten.php">Top 10</a></li><li><a href="banners.php">Banners</a></li><li><a href="random" title="Go to a random torrent">Random</a></li><li><a href="keywords.php">Keywords</a></li></ul></li><li><form method="get" action="browse.php"><input type="text" maxlength="128" name="q"></form></li><li class="welcomeback">Welcome, <strong>Guest</strong>. <a href="login.php">Login</a> or <a href="signup.php">Signup</a></li></ul></div>
<div class="content">
<div class="login">
<h1>Login</h1>
<p class="error">Username or password is incorrect</p>
<form method="post" action="login.php" name="login">
<input type="text" name="username" placeholder="Username" autocomplete="off" style="cursor: auto; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAASCAYAAABSO15qAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QsPDiIBl+zfqgAAAdJJREFUOMvNkj9oU2EUxX/3e4+X2AYtgoIotAUVlZSiVQKCOFgwQ50cKhUcg4qbEITwvfyTjEKnCqUgbqJooQgFRXAROoiiKFWHOsdiSw0UXvK4DkloGl+wOHm2c7ice++5F/47ZLPZQ9baM21urU1Za0d61ZtOYq29FY/Hl0VkDhBARGRGRN75vl+JMnC7eCAi/cCItXZSVRsichJAVb9FGUg3933/tYicA76qaigix4FXxWLxQk+DXC43aIzZXa/XN13XHTLGLIqI0+ocApdVtSoiiUaj8aNSqbzftoLruneA67FY7M8OTaN5keawruvOApnuEM2/Xk1a6Y+p6j5VXReR/Y7jPANMu+tfDTqRz+dfAOOq+tEY07q/x1j6EqeG9rLx/QPPF5eo9fiDK8B4i5bb+pGJDBOpJH3EOJZKk5kcjX4k4CjQUNVPpVLpSVNKMHjAY315nun7D1gJoS8WjzYol8ulIAhGwzC8CWhTrfFy9h7Tj1yy+dsMO7BarfbOoBOFQkHB40TqLLt+fubL6h4uXp0iObDCzN2HVCNeOQL9nE6fZzg4yMbcG3Caan3n91/j6eMlfnmHmbpxjeTAJm8XFljb+Qpb8BIeQS3YVvMbj7WWjTVB6I8AAAAASUVORK5CYII=); background-attachment: scroll; background-position: 100% 50%; background-repeat: no-repeat;">
<input type="password" name="password" onfocus="formInUse = true;" placeholder="Password" autocomplete="off" style="cursor: auto; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAASCAYAAABSO15qAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QsPDiIBl+zfqgAAAdJJREFUOMvNkj9oU2EUxX/3e4+X2AYtgoIotAUVlZSiVQKCOFgwQ50cKhUcg4qbEITwvfyTjEKnCqUgbqJooQgFRXAROoiiKFWHOsdiSw0UXvK4DkloGl+wOHm2c7ice++5F/47ZLPZQ9baM21urU1Za0d61ZtOYq29FY/Hl0VkDhBARGRGRN75vl+JMnC7eCAi/cCItXZSVRsichJAVb9FGUg3933/tYicA76qaigix4FXxWLxQk+DXC43aIzZXa/XN13XHTLGLIqI0+ocApdVtSoiiUaj8aNSqbzftoLruneA67FY7M8OTaN5keawruvOApnuEM2/Xk1a6Y+p6j5VXReR/Y7jPANMu+tfDTqRz+dfAOOq+tEY07q/x1j6EqeG9rLx/QPPF5eo9fiDK8B4i5bb+pGJDBOpJH3EOJZKk5kcjX4k4CjQUNVPpVLpSVNKMHjAY315nun7D1gJoS8WjzYol8ulIAhGwzC8CWhTrfFy9h7Tj1yy+dsMO7BarfbOoBOFQkHB40TqLLt+fubL6h4uXp0iObDCzN2HVCNeOQL9nE6fZzg4yMbcG3Caan3n91/j6eMlfnmHmbpxjeTAJm8XFljb+Qpb8BIeQS3YVvMbj7WWjTVB6I8AAAAASUVORK5CYII=); background-attachment: scroll; background-position: 100% 50%; background-repeat: no-repeat;">
<input type="submit" value="Log in" class="border button">
<input type="hidden" name="returnto" value="/index.php">
</form>
<p><a href="recover.php">Recover Password </a></p>
<p><a href="signup.php">Sign up</a></p>
<script type="text/javascript">
var formInUse = false;
$(document).ready(function() {
if(!formInUse)
document.login.username.focus();
});
</script>
</div>
<div class="clear"></div>
</div>
</div>
<script>try{function lpshowmenudiv(id){ closelpmenus(id); var div = document.getElementById('lppopup'+id); var btn = document.getElementById('lp'+id); if(btn && div){ var btnstyle = window.getComputedStyle(btn, null); var divstyle = window.getComputedStyle(div, null); var posx = btn.offsetLeft; posx -= 80; var divwidth = parseInt(divstyle.getPropertyValue('width')); if(posx + divwidth > window.innerWidth - 25){ posx -= ((posx + divwidth) - window.innerWidth + 25); } div.style.left = posx + "px"; div.style.top = (btn.offsetTop + parseInt(btnstyle.getPropertyValue('height'))) + "px"; if(div.style.display=='block'){div.style.display = 'none'; if(typeof(slideup)=='function'){slideup();} } else div.style.display = 'block'; } }function closelpmenus(id){ if(typeof(lpgblmenus)!='undefined'){ for(var i=0; i < lpgblmenus.length; i++){ if((id==null || lpgblmenus[i]!='lppopup'+id) && document.getElementById(lpgblmenus[i])) document.getElementById(lpgblmenus[i]).style.display = 'none'; } }} var lpcustomEvent = document.createEvent('Event'); lpcustomEvent.initEvent('lpCustomEventMenu', true, true); }catch(e){}</script>
<script>try{if(typeof(lpgblmenus)=='undefined'){ lpgblmenus = new Array(); } lpgblmenus[lpgblmenus.length] = 'lppopupnever'; }catch(e){}</script>
<script>try{document.addEventListener('mouseup', function(e){ if(typeof(closelpmenus)=='function'){closelpmenus();}}, false)}catch(e){}</script><div style="position: absolute; z-index: -10000; top: 0px; left: 0px; right: 0px; height: 592px;"></div>
<script id="hiddenlpsubmitdiv" style="display: none;"></script>
<script>try{for(var lastpass_iter=0; lastpass_iter < document.forms.length; lastpass_iter++){ var lastpass_f = document.forms[lastpass_iter]; if(typeof(lastpass_f.lpsubmitorig2)=="undefined"){ lastpass_f.lpsubmitorig2 = lastpass_f.submit; if (typeof(lastpass_f.lpsubmitorig2)=='object'){ continue;}lastpass_f.submit = function(){ var form=this; var customEvent = document.createEvent("Event"); customEvent.initEvent("lpCustomEvent", true, true); var d = document.getElementById("hiddenlpsubmitdiv"); if (d) {for(var i = 0; i < document.forms.length; i++){ if(document.forms[i]==form){ if (typeof(d.innerText) != 'undefined') { d.innerText=i.toString(); } else { d.textContent=i.toString(); } } } d.dispatchEvent(customEvent); }form.lpsubmitorig2(); } } }}catch(e){}</script>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@@ -1,222 +1,219 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{E75D4F15-5DA3-4332-ADB1-28FB673DAE56}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>JackettTest</RootNamespace>
<AssemblyName>JackettTest</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
<IsCodedUITest>False</IsCodedUITest>
<TestProjectType>UnitTest</TestProjectType>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Autofac, Version=3.5.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.3.5.2\lib\net40\Autofac.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Autofac.Integration.Owin, Version=3.1.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.Owin.3.1.0\lib\net45\Autofac.Integration.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Autofac.Integration.WebApi, Version=3.4.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.WebApi2.3.4.0\lib\net45\Autofac.Integration.WebApi.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Autofac.Integration.WebApi.Owin, Version=3.2.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.WebApi2.Owin.3.2.0\lib\net45\Autofac.Integration.WebApi.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="AutoMapper, Version=4.0.4.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.4.0.4\lib\net45\AutoMapper.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="CsQuery, Version=1.3.3.249, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\CsQuery.1.3.4\lib\net40\CsQuery.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="FluentAssertions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.3.5.0\lib\net45\FluentAssertions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="FluentAssertions.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.3.5.0\lib\net45\FluentAssertions.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.AspNet.Identity.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.Host.HttpListener, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Host.HttpListener.3.0.1\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.Hosting, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Hosting.3.0.1\lib\net45\Microsoft.Owin.Hosting.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.0.1\lib\net45\NLog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nunit.core, Version=2.6.4.14350, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
<HintPath>..\packages\NUnitTestAdapter.2.0.0\lib\nunit.core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nunit.core.interfaces, Version=2.6.4.14350, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
<HintPath>..\packages\NUnitTestAdapter.2.0.0\lib\nunit.core.interfaces.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nunit.framework, Version=2.6.4.14350, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nunit.util, Version=2.6.4.14350, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
<HintPath>..\packages\NUnitTestAdapter.2.0.0\lib\nunit.util.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NUnit.VisualStudio.TestAdapter, Version=2.0.0.0, Culture=neutral, PublicKeyToken=4cb40d35494691ac, processorArchitecture=MSIL">
<HintPath>..\packages\NUnitTestAdapter.2.0.0\lib\NUnit.VisualStudio.TestAdapter.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.Extensions, Version=2.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.Primitives, Version=4.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Http.Owin, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<Choose>
<When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'">
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework" />
</ItemGroup>
</Otherwise>
</Choose>
<ItemGroup>
<Compile Include="Indexers\BakaBTTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\ProtectionServiceTests.cs" />
<Compile Include="TestBase.cs" />
<Compile Include="TestIIndexerManagerServiceHelper.cs" />
<Compile Include="TestUtil.cs" />
<Compile Include="TestWebClient.cs" />
<Compile Include="Util\ServerUtilTests.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config">
<SubType>Designer</SubType>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Jackett\Jackett.csproj">
<Project>{e636d5f8-68b4-4903-b4ed-ccfd9c9e899f}</Project>
<Name>Jackett</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Indexers\BakaBTTestsSearchPage.html" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Indexers\BakaBTTestsLoginError.html" />
</ItemGroup>
<Choose>
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Extension, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITesting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
</ItemGroup>
</When>
</Choose>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{E75D4F15-5DA3-4332-ADB1-28FB673DAE56}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>JackettTest</RootNamespace>
<AssemblyName>JackettTest</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
<IsCodedUITest>False</IsCodedUITest>
<TestProjectType>UnitTest</TestProjectType>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Autofac, Version=3.5.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.3.5.2\lib\net40\Autofac.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Autofac.Integration.Owin, Version=3.1.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.Owin.3.1.0\lib\net45\Autofac.Integration.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Autofac.Integration.WebApi, Version=3.4.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.WebApi2.3.4.0\lib\net45\Autofac.Integration.WebApi.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Autofac.Integration.WebApi.Owin, Version=3.3.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.WebApi2.Owin.3.3.0\lib\net45\Autofac.Integration.WebApi.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="AutoMapper, Version=4.1.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.4.1.1\lib\net45\AutoMapper.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="CsQuery, Version=1.3.3.249, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\CsQuery.1.3.4\lib\net40\CsQuery.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="FluentAssertions, Version=4.1.1.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.4.1.1\lib\net45\FluentAssertions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="FluentAssertions.Core, Version=4.1.1.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.4.1.1\lib\net45\FluentAssertions.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.AspNet.Identity.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.Host.HttpListener, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Host.HttpListener.3.0.1\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.Hosting, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Hosting.3.0.1\lib\net45\Microsoft.Owin.Hosting.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.2.3\lib\net45\NLog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nunit.core, Version=2.6.4.14350, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
<HintPath>..\packages\NUnitTestAdapter.2.0.0\lib\nunit.core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nunit.core.interfaces, Version=2.6.4.14350, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
<HintPath>..\packages\NUnitTestAdapter.2.0.0\lib\nunit.core.interfaces.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nunit.framework, Version=3.0.5813.39031, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.3.0.1\lib\net45\nunit.framework.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nunit.util, Version=2.6.4.14350, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
<HintPath>..\packages\NUnitTestAdapter.2.0.0\lib\nunit.util.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NUnit.VisualStudio.TestAdapter, Version=2.0.0.0, Culture=neutral, PublicKeyToken=4cb40d35494691ac, processorArchitecture=MSIL">
<HintPath>..\packages\NUnitTestAdapter.2.0.0\lib\NUnit.VisualStudio.TestAdapter.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.Extensions, Version=2.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.Primitives, Version=4.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Http.Owin, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<Choose>
<When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'">
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework" />
</ItemGroup>
</Otherwise>
</Choose>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\ProtectionServiceTests.cs" />
<Compile Include="TestBase.cs" />
<Compile Include="TestIIndexerManagerServiceHelper.cs" />
<Compile Include="TestUtil.cs" />
<Compile Include="TestWebClient.cs" />
<Compile Include="Util\ServerUtilTests.cs" />
<Compile Include="Util\TvCategoryParserTests.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config">
<SubType>Designer</SubType>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Jackett\Jackett.csproj">
<Project>{e636d5f8-68b4-4903-b4ed-ccfd9c9e899f}</Project>
<Name>Jackett</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="Indexers\" />
</ItemGroup>
<Choose>
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Extension, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITesting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
</ItemGroup>
</When>
</Choose>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("0.0.0.0")]
[assembly: AssemblyFileVersion("0.0.0.0")]

View File

@@ -0,0 +1,27 @@
using NUnit.Framework;
using Jackett.Utils;
namespace JackettTest.Util
{
[TestFixture]
internal class ParseTvShowQualityTest : TestBase
{
[TestCase("Chuck.S04E05.HDTV.XviD-LOL", 5030)]
[TestCase("Gold.Rush.S04E05.Garnets.or.Gold.REAL.REAL.PROPER.HDTV.x264-W4F", 5030)]
[TestCase("Chuck.S03E17.REAL.PROPER.720p.HDTV.x264-ORENJI-RP", 5040)]
[TestCase("Covert.Affairs.S05E09.REAL.PROPER.HDTV.x264-KILLERS", 5030)]
[TestCase("Mythbusters.S14E01.REAL.PROPER.720p.HDTV.x264-KILLERS", 5040)]
[TestCase("Orange.Is.the.New.Black.s02e06.real.proper.720p.webrip.x264-2hd", 5040)]
[TestCase("Top.Gear.S21E07.Super.Duper.Real.Proper.HDTV.x264-FTP", 5030)]
[TestCase("Top.Gear.S21E07.PROPER.HDTV.x264-RiVER-RP", 5030)]
[TestCase("House.S07E11.PROPER.REAL.RERIP.1080p.BluRay.x264-TENEIGHTY", 5040)]
[TestCase("The.Blacklist.S02E05", 5000)]
[TestCase("The.IT.Crowd.S01.DVD.REMUX.DD2.0.MPEG2-DTG", 5030)]
public void should_parse_quality_from_title(string title, int quality)
{
Assert.That(TvCategoryParser.ParseTvShowQuality(title), Is.EqualTo(quality));
}
}
}

View File

@@ -1,31 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="AutoMapper" publicKeyToken="be96cd2c38ef1005" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.4.0" newVersion="4.0.4.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /></startup></configuration>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="AutoMapper" publicKeyToken="be96cd2c38ef1005" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.4.0" newVersion="4.0.4.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /></startup></configuration>

View File

@@ -1,26 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Autofac" version="3.5.2" targetFramework="net45" />
<package id="Autofac.Owin" version="3.1.0" targetFramework="net45" />
<package id="Autofac.WebApi2" version="3.4.0" targetFramework="net45" />
<package id="Autofac.WebApi2.Owin" version="3.2.0" targetFramework="net45" />
<package id="AutoMapper" version="4.0.4" targetFramework="net45" />
<package id="CsQuery" version="1.3.4" targetFramework="net45" />
<package id="FluentAssertions" version="3.5.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.OwinSelfHost" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net45" />
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net45" />
<package id="Microsoft.Net.Http" version="2.2.29" targetFramework="net45" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Host.HttpListener" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Hosting" version="3.0.1" targetFramework="net45" />
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
<package id="NLog" version="4.0.1" targetFramework="net45" />
<package id="NUnit" version="2.6.4" targetFramework="net45" />
<package id="NUnitTestAdapter" version="2.0.0" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Autofac" version="3.5.2" targetFramework="net45" />
<package id="Autofac.Owin" version="3.1.0" targetFramework="net45" />
<package id="Autofac.WebApi2" version="3.4.0" targetFramework="net45" />
<package id="Autofac.WebApi2.Owin" version="3.3.0" targetFramework="net45" />
<package id="AutoMapper" version="4.1.1" targetFramework="net45" />
<package id="CsQuery" version="1.3.4" targetFramework="net45" />
<package id="FluentAssertions" version="4.1.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.OwinSelfHost" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net45" />
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net45" />
<package id="Microsoft.Net.Http" version="2.2.29" targetFramework="net45" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Host.HttpListener" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Hosting" version="3.0.1" targetFramework="net45" />
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
<package id="NLog" version="4.2.3" targetFramework="net45" />
<package id="NUnit" version="3.0.1" targetFramework="net45" />
<package id="NUnitTestAdapter" version="2.0.0" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
</packages>

View File

@@ -1,34 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="AutoMapper" publicKeyToken="be96cd2c38ef1005" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.4.0" newVersion="4.0.4.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="AutoMapper" publicKeyToken="be96cd2c38ef1005" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.4.0" newVersion="4.0.4.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -1,204 +1,204 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{FF9025B1-EC14-4AA9-8081-9F69C5E35B63}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Jackett.Tray</RootNamespace>
<AssemblyName>JackettTray</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>jackett.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="Autofac, Version=3.5.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.3.5.2\lib\net40\Autofac.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Autofac.Integration.Owin, Version=3.1.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.Owin.3.1.0\lib\net45\Autofac.Integration.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Autofac.Integration.WebApi, Version=3.4.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.WebApi2.3.4.0\lib\net45\Autofac.Integration.WebApi.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Autofac.Integration.WebApi.Owin, Version=3.2.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.WebApi2.Owin.3.2.0\lib\net45\Autofac.Integration.WebApi.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="AutoMapper, Version=4.0.4.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.4.0.4\lib\net45\AutoMapper.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.FileSystems, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.FileSystems.3.0.1\lib\net45\Microsoft.Owin.FileSystems.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.Host.HttpListener, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Host.HttpListener.3.0.1\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.Hosting, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Hosting.3.0.1\lib\net45\Microsoft.Owin.Hosting.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.StaticFiles, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.StaticFiles.3.0.1\lib\net45\Microsoft.Owin.StaticFiles.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.0.1\lib\net45\NLog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Net.Http.Extensions, Version=2.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.Primitives, Version=4.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Http.Owin, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Http.Tracing, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Tracing.5.2.3\lib\net45\System.Web.Http.Tracing.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Main.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Main.Designer.cs">
<DependentUpon>Main.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Main.resx">
<DependentUpon>Main.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<Content Include="jackett.ico" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Jackett\Jackett.csproj">
<Project>{e636d5f8-68b4-4903-b4ed-ccfd9c9e899f}</Project>
<Name>Jackett</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<COMReference Include="IWshRuntimeLibrary">
<Guid>{F935DC20-1CF0-11D0-ADB9-00C04FD58A0B}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{FF9025B1-EC14-4AA9-8081-9F69C5E35B63}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Jackett.Tray</RootNamespace>
<AssemblyName>JackettTray</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>jackett.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="Autofac, Version=3.5.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.3.5.2\lib\net40\Autofac.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Autofac.Integration.Owin, Version=3.1.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.Owin.3.1.0\lib\net45\Autofac.Integration.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Autofac.Integration.WebApi, Version=3.4.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.WebApi2.3.4.0\lib\net45\Autofac.Integration.WebApi.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Autofac.Integration.WebApi.Owin, Version=3.3.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.WebApi2.Owin.3.3.0\lib\net45\Autofac.Integration.WebApi.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="AutoMapper, Version=4.1.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.4.1.1\lib\net45\AutoMapper.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.FileSystems, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.FileSystems.3.0.1\lib\net45\Microsoft.Owin.FileSystems.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.Host.HttpListener, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Host.HttpListener.3.0.1\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.Hosting, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Hosting.3.0.1\lib\net45\Microsoft.Owin.Hosting.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.StaticFiles, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.StaticFiles.3.0.1\lib\net45\Microsoft.Owin.StaticFiles.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.2.3\lib\net45\NLog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Net.Http.Extensions, Version=2.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.Primitives, Version=4.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Http.Owin, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Http.Tracing, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Tracing.5.2.3\lib\net45\System.Web.Http.Tracing.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Main.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Main.Designer.cs">
<DependentUpon>Main.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Main.resx">
<DependentUpon>Main.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<Content Include="jackett.ico" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Jackett\Jackett.csproj">
<Project>{e636d5f8-68b4-4903-b4ed-ccfd9c9e899f}</Project>
<Name>Jackett</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<COMReference Include="IWshRuntimeLibrary">
<Guid>{F935DC20-1CF0-11D0-ADB9-00C04FD58A0B}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -42,6 +42,14 @@ namespace JackettTray
Engine.Logger.Info("Starting server from tray");
Engine.Server.Start();
}
Task.Factory.StartNew(WaitForEvent);
}
private void WaitForEvent()
{
Engine.LockService.WaitForSignal();
Application.Exit();
}
void toolStripMenuItemWebUI_Click(object sender, EventArgs e)

View File

@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("0.0.0.0")]
[assembly: AssemblyFileVersion("0.0.0.0")]

View File

@@ -1,24 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Autofac" version="3.5.2" targetFramework="net45" />
<package id="Autofac.Owin" version="3.1.0" targetFramework="net45" />
<package id="Autofac.WebApi2" version="3.4.0" targetFramework="net45" />
<package id="Autofac.WebApi2.Owin" version="3.2.0" targetFramework="net45" />
<package id="AutoMapper" version="4.0.4" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.OwinSelfHost" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Tracing" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net45" />
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net45" />
<package id="Microsoft.Net.Http" version="2.2.29" targetFramework="net45" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.FileSystems" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Host.HttpListener" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Hosting" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.StaticFiles" version="3.0.1" targetFramework="net45" />
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
<package id="NLog" version="4.0.1" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Autofac" version="3.5.2" targetFramework="net45" />
<package id="Autofac.Owin" version="3.1.0" targetFramework="net45" />
<package id="Autofac.WebApi2" version="3.4.0" targetFramework="net45" />
<package id="Autofac.WebApi2.Owin" version="3.3.0" targetFramework="net45" />
<package id="AutoMapper" version="4.1.1" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.OwinSelfHost" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Tracing" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net45" />
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net45" />
<package id="Microsoft.Net.Http" version="2.2.29" targetFramework="net45" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.FileSystems" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Host.HttpListener" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Hosting" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.StaticFiles" version="3.0.1" targetFramework="net45" />
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
<package id="NLog" version="4.2.3" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
</packages>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -0,0 +1,105 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{A61E311A-6F8B-4497-B5E4-2EA8994C7BD8}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Jackett.Updater</RootNamespace>
<AssemblyName>JackettUpdater</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFrameworkProfile />
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>jackett.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="Autofac, Version=3.5.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.3.5.2\lib\net40\Autofac.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="CommandLine, Version=1.9.71.2, Culture=neutral, PublicKeyToken=de6f01bd326f8c32, processorArchitecture=MSIL">
<HintPath>..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.2.3\lib\net45\NLog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Net.Http.Extensions, Version=2.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.Primitives, Version=4.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="UpdaterConsoleOptions.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Jackett\Jackett.csproj">
<Project>{e636d5f8-68b4-4903-b4ed-ccfd9c9e899f}</Project>
<Name>Jackett</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="jackett.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,150 @@
using CommandLine;
using Jackett.Services;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Jackett.Updater
{
class Program
{
static void Main(string[] args)
{
new Program().Run(args);
}
private void Run(string[] args)
{
Engine.SetupLogging(null, "updater.txt");
Engine.Logger.Info("Jackett Updater v" + GetCurrentVersion());
Engine.Logger.Info("Options " + string.Join(" ", args));
try {
var options = new UpdaterConsoleOptions();
if (Parser.Default.ParseArguments(args, options))
{
ProcessUpdate(options);
}
else
{
Engine.Logger.Error("Failed to process update arguments!: " + string.Join(" ", args));
Console.ReadKey();
}
}
catch (Exception e)
{
Engine.Logger.Error(e, "Exception applying update!");
}
}
private string GetCurrentVersion()
{
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
var fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
return fvi.FileVersion;
}
private void ProcessUpdate(UpdaterConsoleOptions options)
{
var updateLocation = GetUpdateLocation();
if(!(updateLocation.EndsWith("\\") || updateLocation.EndsWith("/")))
{
updateLocation += Path.DirectorySeparatorChar;
}
var isWindows = System.Environment.OSVersion.Platform != PlatformID.Unix;
var trayRunning = false;
var trayProcesses = Process.GetProcessesByName("JackettTray");
if (isWindows)
{
if (trayProcesses.Count() > 0)
{
foreach (var proc in trayProcesses)
{
try
{
Engine.Logger.Info("Killing tray process " + proc.Id);
proc.Kill();
trayRunning = true;
}
catch { }
}
}
}
Engine.Logger.Info("Waiting for Jackett to close..");
Thread.Sleep(2000);
Engine.Logger.Info("Finding files in: " + updateLocation);
var files = Directory.GetFiles(updateLocation, "*.*", SearchOption.AllDirectories);
foreach(var file in files)
{
var fileName = Path.GetFileName(file).ToLowerInvariant();
if (fileName.EndsWith(".zip") ||
fileName.EndsWith(".tar") ||
fileName.EndsWith(".gz"))
{
continue;
}
try {
Engine.Logger.Info("Copying " + fileName);
var dest = Path.Combine(options.Path, file.Substring(updateLocation.Length));
File.Copy(file, dest, true);
}
catch(Exception e)
{
Engine.Logger.Error(e);
}
}
if (trayRunning)
{
var startInfo = new ProcessStartInfo()
{
Arguments = options.Args,
FileName = Path.Combine(options.Path, "JackettTray.exe"),
UseShellExecute = true
};
Process.Start(startInfo);
}
if(string.Equals(options.Type, "JackettService.exe", StringComparison.InvariantCultureIgnoreCase))
{
var serviceHelper = new ServiceConfigService(null, null);
if (serviceHelper.ServiceExists())
{
serviceHelper.Start();
}
} else
{
var startInfo = new ProcessStartInfo()
{
Arguments = options.Args,
FileName = Path.Combine(options.Path, "JackettConsole.exe"),
UseShellExecute = true
};
if (!isWindows)
{
startInfo.Arguments = startInfo.FileName + " " + startInfo.Arguments;
startInfo.FileName = "mono";
}
Engine.Logger.Info("Starting Jackett: " + startInfo.FileName + " " + startInfo.Arguments);
Process.Start(startInfo);
}
}
private string GetUpdateLocation()
{
var location = new Uri(Assembly.GetEntryAssembly().GetName().CodeBase);
return new FileInfo(location.AbsolutePath).DirectoryName;
}
}
}

View File

@@ -5,11 +5,11 @@ using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("JackettDistribution")]
[assembly: AssemblyTitle("Jackett.Updater")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("JackettDistribution")]
[assembly: AssemblyProduct("Jackett.Updater")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -20,7 +20,7 @@ using System.Runtime.InteropServices;
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("99d893ec-1a8a-42a9-ac6b-fe047afc32f0")]
[assembly: Guid("a61e311a-6f8b-4497-b5e4-2ea8994c7bd8")]
// Version information for an assembly consists of the following four values:
//
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("0.0.0.0")]
[assembly: AssemblyFileVersion("0.0.0.0")]

View File

@@ -0,0 +1,21 @@
using CommandLine;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Jackett.Updater
{
public class UpdaterConsoleOptions
{
[Option('p', "Path", HelpText = "Install location")]
public string Path { get; set; }
[Option('t', "Type", HelpText = "Install type")]
public string Type { get; set; }
[Option('a', "Args", HelpText = "Launch arguments")]
public string Args { get; set; }
}
}

View File

Before

Width:  |  Height:  |  Size: 361 KiB

After

Width:  |  Height:  |  Size: 361 KiB

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Autofac" version="3.5.2" targetFramework="net45" />
<package id="CommandLineParser" version="1.9.71" targetFramework="net45" />
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net45" />
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net45" />
<package id="Microsoft.Net.Http" version="2.2.29" targetFramework="net45" />
<package id="NLog" version="4.2.3" targetFramework="net45" />
</packages>

View File

@@ -1,107 +1,101 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jackett", "Jackett\Jackett.csproj", "{E636D5F8-68B4-4903-B4ED-CCFD9C9E899F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CurlSharp", "CurlSharp\CurlSharp.csproj", "{74420A79-CC16-442C-8B1E-7C1B913844F0}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{BE7B0C8A-6144-47CD-821E-B09BA1B7BADE}"
ProjectSection(SolutionItems) = preProject
..\Build.bat = ..\Build.bat
..\Installer.iss = ..\Installer.iss
..\LICENSE = ..\LICENSE
..\README.md = ..\README.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jackett.Console", "Jackett.Console\Jackett.Console.csproj", "{4E2A81DA-E235-4A88-AD20-38AABBFBF33C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jackett.Service", "Jackett.Service\Jackett.Service.csproj", "{BF611F7B-4658-4CB8-AA9E-0736FADAA3BA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jackett.Tray", "Jackett.Tray\Jackett.Tray.csproj", "{FF9025B1-EC14-4AA9-8081-9F69C5E35B63}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jackett.Test", "Jackett.Test\Jackett.Test.csproj", "{E75D4F15-5DA3-4332-ADB1-28FB673DAE56}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jackett.Distribution", "Jackett.Distribution\Jackett.Distribution.csproj", "{99D893EC-1A8A-42A9-AC6B-FE047AFC32F0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Website", "Website\Website.csproj", "{6B6AB1B0-5ABD-4696-A3D2-70E991174625}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E636D5F8-68B4-4903-B4ED-CCFD9C9E899F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E636D5F8-68B4-4903-B4ED-CCFD9C9E899F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E636D5F8-68B4-4903-B4ED-CCFD9C9E899F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E636D5F8-68B4-4903-B4ED-CCFD9C9E899F}.Release|Any CPU.Build.0 = Release|Any CPU
{74420A79-CC16-442C-8B1E-7C1B913844F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{74420A79-CC16-442C-8B1E-7C1B913844F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{74420A79-CC16-442C-8B1E-7C1B913844F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{74420A79-CC16-442C-8B1E-7C1B913844F0}.Release|Any CPU.Build.0 = Release|Any CPU
{4E2A81DA-E235-4A88-AD20-38AABBFBF33C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4E2A81DA-E235-4A88-AD20-38AABBFBF33C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4E2A81DA-E235-4A88-AD20-38AABBFBF33C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4E2A81DA-E235-4A88-AD20-38AABBFBF33C}.Release|Any CPU.Build.0 = Release|Any CPU
{BF611F7B-4658-4CB8-AA9E-0736FADAA3BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BF611F7B-4658-4CB8-AA9E-0736FADAA3BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BF611F7B-4658-4CB8-AA9E-0736FADAA3BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BF611F7B-4658-4CB8-AA9E-0736FADAA3BA}.Release|Any CPU.Build.0 = Release|Any CPU
{FF9025B1-EC14-4AA9-8081-9F69C5E35B63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FF9025B1-EC14-4AA9-8081-9F69C5E35B63}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FF9025B1-EC14-4AA9-8081-9F69C5E35B63}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FF9025B1-EC14-4AA9-8081-9F69C5E35B63}.Release|Any CPU.Build.0 = Release|Any CPU
{E75D4F15-5DA3-4332-ADB1-28FB673DAE56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E75D4F15-5DA3-4332-ADB1-28FB673DAE56}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E75D4F15-5DA3-4332-ADB1-28FB673DAE56}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E75D4F15-5DA3-4332-ADB1-28FB673DAE56}.Release|Any CPU.Build.0 = Release|Any CPU
{99D893EC-1A8A-42A9-AC6B-FE047AFC32F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{99D893EC-1A8A-42A9-AC6B-FE047AFC32F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{99D893EC-1A8A-42A9-AC6B-FE047AFC32F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{99D893EC-1A8A-42A9-AC6B-FE047AFC32F0}.Release|Any CPU.Build.0 = Release|Any CPU
{6B6AB1B0-5ABD-4696-A3D2-70E991174625}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6B6AB1B0-5ABD-4696-A3D2-70E991174625}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6B6AB1B0-5ABD-4696-A3D2-70E991174625}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6B6AB1B0-5ABD-4696-A3D2-70E991174625}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
Policies = $0
$0.TextStylePolicy = $1
$1.inheritsSet = VisualStudio
$1.inheritsScope = text/plain
$1.scope = text/x-csharp
$0.CSharpFormattingPolicy = $2
$2.IndentSwitchBody = True
$2.IndentBlocksInsideExpressions = True
$2.AnonymousMethodBraceStyle = NextLine
$2.PropertyBraceStyle = NextLine
$2.PropertyGetBraceStyle = NextLine
$2.PropertySetBraceStyle = NextLine
$2.EventBraceStyle = NextLine
$2.EventAddBraceStyle = NextLine
$2.EventRemoveBraceStyle = NextLine
$2.StatementBraceStyle = NextLine
$2.ElseNewLinePlacement = NewLine
$2.CatchNewLinePlacement = NewLine
$2.FinallyNewLinePlacement = NewLine
$2.WhileNewLinePlacement = DoNotCare
$2.ArrayInitializerWrapping = DoNotChange
$2.ArrayInitializerBraceStyle = NextLine
$2.BeforeMethodDeclarationParentheses = False
$2.BeforeMethodCallParentheses = False
$2.BeforeConstructorDeclarationParentheses = False
$2.NewLineBeforeConstructorInitializerColon = NewLine
$2.NewLineAfterConstructorInitializerColon = SameLine
$2.BeforeDelegateDeclarationParentheses = False
$2.NewParentheses = False
$2.SpacesBeforeBrackets = False
$2.inheritsSet = Mono
$2.inheritsScope = text/x-csharp
$2.scope = text/x-csharp
EndGlobalSection
EndGlobal

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jackett", "Jackett\Jackett.csproj", "{E636D5F8-68B4-4903-B4ED-CCFD9C9E899F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CurlSharp", "CurlSharp\CurlSharp.csproj", "{74420A79-CC16-442C-8B1E-7C1B913844F0}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{BE7B0C8A-6144-47CD-821E-B09BA1B7BADE}"
ProjectSection(SolutionItems) = preProject
..\Build.bat = ..\Build.bat
..\Installer.iss = ..\Installer.iss
..\LICENSE = ..\LICENSE
..\README.md = ..\README.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jackett.Console", "Jackett.Console\Jackett.Console.csproj", "{4E2A81DA-E235-4A88-AD20-38AABBFBF33C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jackett.Service", "Jackett.Service\Jackett.Service.csproj", "{BF611F7B-4658-4CB8-AA9E-0736FADAA3BA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jackett.Tray", "Jackett.Tray\Jackett.Tray.csproj", "{FF9025B1-EC14-4AA9-8081-9F69C5E35B63}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jackett.Test", "Jackett.Test\Jackett.Test.csproj", "{E75D4F15-5DA3-4332-ADB1-28FB673DAE56}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jackett.Updater", "Jackett.Updater\Jackett.Updater.csproj", "{A61E311A-6F8B-4497-B5E4-2EA8994C7BD8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E636D5F8-68B4-4903-B4ED-CCFD9C9E899F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E636D5F8-68B4-4903-B4ED-CCFD9C9E899F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E636D5F8-68B4-4903-B4ED-CCFD9C9E899F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E636D5F8-68B4-4903-B4ED-CCFD9C9E899F}.Release|Any CPU.Build.0 = Release|Any CPU
{74420A79-CC16-442C-8B1E-7C1B913844F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{74420A79-CC16-442C-8B1E-7C1B913844F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{74420A79-CC16-442C-8B1E-7C1B913844F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{74420A79-CC16-442C-8B1E-7C1B913844F0}.Release|Any CPU.Build.0 = Release|Any CPU
{4E2A81DA-E235-4A88-AD20-38AABBFBF33C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4E2A81DA-E235-4A88-AD20-38AABBFBF33C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4E2A81DA-E235-4A88-AD20-38AABBFBF33C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4E2A81DA-E235-4A88-AD20-38AABBFBF33C}.Release|Any CPU.Build.0 = Release|Any CPU
{BF611F7B-4658-4CB8-AA9E-0736FADAA3BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BF611F7B-4658-4CB8-AA9E-0736FADAA3BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BF611F7B-4658-4CB8-AA9E-0736FADAA3BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BF611F7B-4658-4CB8-AA9E-0736FADAA3BA}.Release|Any CPU.Build.0 = Release|Any CPU
{FF9025B1-EC14-4AA9-8081-9F69C5E35B63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FF9025B1-EC14-4AA9-8081-9F69C5E35B63}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FF9025B1-EC14-4AA9-8081-9F69C5E35B63}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FF9025B1-EC14-4AA9-8081-9F69C5E35B63}.Release|Any CPU.Build.0 = Release|Any CPU
{E75D4F15-5DA3-4332-ADB1-28FB673DAE56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E75D4F15-5DA3-4332-ADB1-28FB673DAE56}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E75D4F15-5DA3-4332-ADB1-28FB673DAE56}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E75D4F15-5DA3-4332-ADB1-28FB673DAE56}.Release|Any CPU.Build.0 = Release|Any CPU
{A61E311A-6F8B-4497-B5E4-2EA8994C7BD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A61E311A-6F8B-4497-B5E4-2EA8994C7BD8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A61E311A-6F8B-4497-B5E4-2EA8994C7BD8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A61E311A-6F8B-4497-B5E4-2EA8994C7BD8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
Policies = $0
$0.TextStylePolicy = $1
$1.inheritsSet = VisualStudio
$1.inheritsScope = text/plain
$1.scope = text/x-csharp
$0.CSharpFormattingPolicy = $2
$2.IndentSwitchBody = True
$2.IndentBlocksInsideExpressions = True
$2.AnonymousMethodBraceStyle = NextLine
$2.PropertyBraceStyle = NextLine
$2.PropertyGetBraceStyle = NextLine
$2.PropertySetBraceStyle = NextLine
$2.EventBraceStyle = NextLine
$2.EventAddBraceStyle = NextLine
$2.EventRemoveBraceStyle = NextLine
$2.StatementBraceStyle = NextLine
$2.ElseNewLinePlacement = NewLine
$2.CatchNewLinePlacement = NewLine
$2.FinallyNewLinePlacement = NewLine
$2.WhileNewLinePlacement = DoNotCare
$2.ArrayInitializerWrapping = DoNotChange
$2.ArrayInitializerBraceStyle = NextLine
$2.BeforeMethodDeclarationParentheses = False
$2.BeforeMethodCallParentheses = False
$2.BeforeConstructorDeclarationParentheses = False
$2.NewLineBeforeConstructorInitializerColon = NewLine
$2.NewLineAfterConstructorInitializerColon = SameLine
$2.BeforeDelegateDeclarationParentheses = False
$2.NewParentheses = False
$2.SpacesBeforeBrackets = False
$2.inheritsSet = Mono
$2.inheritsScope = text/x-csharp
$2.scope = text/x-csharp
EndGlobalSection
EndGlobal

View File

@@ -1,36 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.5.0.0" newVersion="3.5.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.5.0.0" newVersion="3.5.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -11,6 +11,9 @@ namespace Jackett
{
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
if(null!= actionExecutedContext &&
null!= actionExecutedContext.Response &&
null!= actionExecutedContext.Response.Headers)
actionExecutedContext.Response.Headers.CacheControl = new System.Net.Http.Headers.CacheControlHeaderValue()
{
NoStore = true,

View File

@@ -1,289 +1,295 @@
body {
background-image: url("binding_dark.png");
background-repeat: repeat;
}
#page {
border-radius: 6px;
background-color: white;
max-width: 900px;
margin: 0 auto;
margin-top: 30px;
padding: 20px;
margin-bottom: 100px;
}
.container-fluid {
}
#templates {
display: none;
}
.card {
background-color: #f9f9f9;
border-radius: 6px;
box-shadow: 1px 1px 5px 2px #cdcdcd;
width: 270px;
display: inline-block;
vertical-align: top;
margin: 5px;
overflow: hidden;
position: relative;
}
#indexers {
text-align: center;
margin-top: 30px;
}
#unconfigured-indexers{
text-align: center;
}
#unconfigured-indexers .card {
width: 200px;
}
.unconfigured-indexer {
height: 120px;
}
.indexer {
height: 252px;
}
.add-indexer {
border: 0;
}
.indexer-logo {
padding-bottom: 5px;
}
.indexer-logo > .hidden-name {
position: absolute;
color: rgba(255, 255, 255, 0);
left: 0;
}
.indexer-logo > img {
width: 100%;
border-bottom: 1px solid #FFF;
}
.indexer-name > h3 {
margin-top: 13px;
text-align: center;
}
.indexer-buttons {
text-align: center;
}
.indexer-buttons > .btn {
margin-bottom: 2px;
}
.indexer-button-test {
width: 60px;
}
.indexer-add-content {
color: gray;
text-align: center;
}
.indexer-add-content > .glyphicon {
font-size: 50px;
vertical-align: bottom;
}
.indexer-add-content > .light-text {
margin-top: 11px;
font-size: 18px;
margin-left: -5px;
}
.indexer-host {
padding-left: 5px;
padding-right: 5px;
}
.indexer-host > input {
font-size: 12px;
padding: 2px;
}
.setup-item-inputstring {
max-width: 255px;
}
.setup-item-inputbool input {
max-width: 100px;
height: 20px;
}
[data-type=hiddendata]{
display: none;
}
.spinner {
-webkit-animation: spin 2s infinite linear;
-moz-animation: spin 2s infinite linear;
-o-animation: spin 2s infinite linear;
animation: spin 2s infinite linear;
}
@-moz-keyframes spin {
from {
-moz-transform: rotate(0deg);
}
to {
-moz-transform: rotate(360deg);
}
}
@-webkit-keyframes spin {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
}
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
#setup-indexer-go {
width: 70px;
}
hr {
border-top-color: #cdcdcd;
}
.input-area {
margin: 4px 0px;
}
.input-area > * {
vertical-align: middle;
}
.input-area > p {
margin-top: 10px;
}
.input-header {
font-size: 18px;
width: 160px;
display: inline-block;
}
.input-right {
width: 300px;
display: inline-block;
font-family: monospace;
}
#sonarr-warning {
display: none;
}
#logo {
max-width: 50px;
}
#header-title {
font-size: 34px;
vertical-align: middle;
padding-left: 15px;
}
#footer {
color: #444444;
margin: 0 auto;
margin-top: 10px;
text-align: center;
}
#jackett-allowext {
width: 25px;
}
.modal-fillwidth {
width: 1200px;
min-width:80%;
}
.indexer-caps {
padding: 0px 15px 15px 15px;
border-top: 1px solid #e5e5e5;
}
.indexer-caps table {
border-bottom: 1px solid #ddd;
}
.jackettlogWarn {
background-color: #FFFF8E !important;
}
.jackettlogError {
background-color: #FF6060 !important;
}
.jackettdownloaded {
color: blueviolet;
}
.jacketdownloadlocal {
padding-left: 10px;
}
.downloadcolumn {
text-align:center;
}
pre {
display: block;
padding: 3px;
margin: 0 0 0px;
font-size: 13px;
line-height: 1.42857143;
color: #333;
word-break: break-all;
word-wrap: break-word;
background-color: transparent;
border: 0px;
border-radius: 0px;
}
.modal-open .modal {
overflow-x: auto; /* Model can be bigger than the screen on mobiles */
}
#unconfigured-indexers-template {
display: none;
}
.jackett-apikey{
margin-top: 10px;
}
.jackett-apikey .input-header{
width: 80px;
}
body {
background-image: url("binding_dark.png");
background-repeat: repeat;
}
#page {
border-radius: 6px;
background-color: white;
max-width: 900px;
margin: 0 auto;
margin-top: 30px;
padding: 20px;
margin-bottom: 100px;
}
.container-fluid {
}
#templates {
display: none;
}
.card {
background-color: #f9f9f9;
border-radius: 6px;
box-shadow: 1px 1px 5px 2px #cdcdcd;
width: 270px;
display: inline-block;
vertical-align: top;
margin: 5px;
overflow: hidden;
position: relative;
}
#indexers {
text-align: center;
margin-top: 30px;
}
#unconfigured-indexers{
text-align: center;
}
#unconfigured-indexers .card {
width: 200px;
position: relative;
}
.unconfigured-indexer {
height: 70px;
}
.indexer {
height: 252px;
}
.add-indexer {
border: 0;
}
.indexer-logo {
padding-bottom: 5px;
}
.indexer-logo > .hidden-name {
position: absolute;
color: rgba(255, 255, 255, 0);
left: 0;
}
.indexer-logo img {
width: 100%;
border-bottom: 1px solid #FFF;
}
#unconfigured-indexers .indexer-logo img {
cursor: pointer;
}
.indexer-name > h3 {
margin-top: 13px;
text-align: center;
}
.indexer-buttons {
text-align: center;
}
.indexer-buttons > .btn {
margin-bottom: 2px;
}
.indexer-button-test {
width: 60px;
}
.indexer-add-content {
color: gray;
text-align: center;
}
.indexer-add-content > .glyphicon {
font-size: 50px;
vertical-align: bottom;
}
.indexer-add-content > .light-text {
margin-top: 11px;
font-size: 18px;
margin-left: -5px;
}
.indexer-host {
padding-left: 5px;
padding-right: 5px;
}
.indexer-host > input {
font-size: 12px;
padding: 2px;
}
.setup-item-inputstring {
max-width: 255px;
}
.setup-item-inputbool input {
max-width: 100px;
height: 20px;
}
[data-type=hiddendata]{
display: none;
}
.spinner {
-webkit-animation: spin 2s infinite linear;
-moz-animation: spin 2s infinite linear;
-o-animation: spin 2s infinite linear;
animation: spin 2s infinite linear;
}
@-moz-keyframes spin {
from {
-moz-transform: rotate(0deg);
}
to {
-moz-transform: rotate(360deg);
}
}
@-webkit-keyframes spin {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
}
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
#setup-indexer-go {
width: 70px;
}
hr {
border-top-color: #cdcdcd;
}
.input-area {
margin: 4px 0px;
}
.input-area > * {
vertical-align: middle;
}
.input-area > p {
margin-top: 10px;
}
.input-header {
font-size: 18px;
width: 160px;
display: inline-block;
}
.input-right {
width: 300px;
display: inline-block;
font-family: monospace;
}
#sonarr-warning {
display: none;
}
#logo {
max-width: 50px;
}
#header-title {
font-size: 34px;
vertical-align: middle;
padding-left: 15px;
}
#footer {
color: #444444;
margin: 0 auto;
margin-top: 10px;
text-align: center;
}
#jackett-allowext, #jackett-allowupdate, #jackett-logging, #jackett-prerelease {
width: 25px;
}
.modal-fillwidth {
width: 1200px;
min-width:80%;
}
.indexer-caps {
padding: 0px 15px 15px 15px;
border-top: 1px solid #e5e5e5;
}
.indexer-caps table {
border-bottom: 1px solid #ddd;
}
.jackettlogWarn {
background-color: #FFFF8E !important;
}
.jackettlogError {
background-color: #FF6060 !important;
}
.jackettdownloaded {
color: blueviolet;
}
.jacketdownloadlocal {
padding-left: 10px;
}
.downloadcolumn {
text-align:center;
}
pre {
display: block;
padding: 3px;
margin: 0 0 0px;
font-size: 13px;
line-height: 1.42857143;
color: #333;
word-break: break-all;
word-wrap: break-word;
background-color: transparent;
border: 0px;
border-radius: 0px;
}
.modal-open .modal {
overflow-x: auto; /* Model can be bigger than the screen on mobiles */
}
#unconfigured-indexers-template {
display: none;
}
.jackett-apikey{
margin-top: 10px;
}
.jackett-apikey .input-header{
width: 80px;
}

View File

@@ -1,15 +1,17 @@
$(document).ready(function () {
var basePath = '';
$(document).ready(function () {
$.ajaxSetup({ cache: false });
window.jackettIsLocal = window.location.hostname === 'localhost' ||
window.location.hostname === '127.0.0.1';
bindUIButtons();
reloadIndexers();
loadJackettSettings();
});
function getJackettConfig(callback) {
var jqxhr = $.get("/admin/get_jackett_config", function (data) {
var jqxhr = $.get("get_jackett_config", function (data) {
callback(data);
}).fail(function () {
@@ -22,13 +24,24 @@ function loadJackettSettings() {
$("#api-key-input").val(data.config.api_key);
$("#app-version").html(data.app_version);
$("#jackett-port").val(data.config.port);
$("#jackett-basepathoverride").val(data.config.basepathoverride);
basePath = data.config.basepathoverride;
if (basePath === null || basePath === undefined) {
basePath = '';
}
$("#jackett-savedir").val(data.config.blackholedir);
$("#jackett-allowext").attr('checked', data.config.external);
$("#jackett-allowupdate").attr('checked', data.config.updatedisabled);
$("#jackett-prerelease").attr('checked', data.config.prerelease);
$("#jackett-logging").attr('checked', data.config.logging);
var password = data.config.password;
$("#jackett-adminpwd").val(password);
if (password != null && password != '') {
$("#logoutBtn").show();
}
reloadIndexers();
});
}
@@ -36,7 +49,7 @@ function reloadIndexers() {
$('#indexers').hide();
$('#indexers > .indexer').remove();
$('#unconfigured-indexers').empty();
var jqxhr = $.get("/admin/get_indexers", function (data) {
var jqxhr = $.get("get_indexers", function (data) {
displayIndexers(data.items);
}).fail(function () {
doNotify("Error loading indexers, request to Jackett server failed", "danger", "glyphicon glyphicon-alert");
@@ -49,8 +62,8 @@ function displayIndexers(items) {
$('#unconfigured-indexers-template').empty();
for (var i = 0; i < items.length; i++) {
var item = items[i];
item.torznab_host = resolveUrl("/torznab/" + item.id);
item.potato_host = resolveUrl("/potato/" + item.id);
item.torznab_host = resolveUrl(basePath + "/torznab/" + item.id);
item.potato_host = resolveUrl(basePath + "/potato/" + item.id);
if (item.configured)
$('#indexers').append(indexerTemplate(item));
else
@@ -69,9 +82,10 @@ function displayIndexers(items) {
$('.indexer-setup').each(function (i, btn) {
var $btn = $(btn);
var id = $btn.data("id");
var link = $btn.data("link");
$btn.click(function () {
$('#select-indexer-modal').modal('hide').on('hidden.bs.modal', function (e) {
displayIndexerSetup(id);
displayIndexerSetup(id, link);
});
});
});
@@ -88,7 +102,7 @@ function prepareDeleteButtons() {
var $btn = $(btn);
var id = $btn.data("id");
$btn.click(function () {
var jqxhr = $.post("/admin/delete_indexer", JSON.stringify({ indexer: id }), function (data) {
var jqxhr = $.post("delete_indexer", JSON.stringify({ indexer: id }), function (data) {
if (data.result == "error") {
doNotify("Delete error for " + id + "\n" + data.error, "danger", "glyphicon glyphicon-alert");
}
@@ -108,8 +122,9 @@ function prepareSetupButtons() {
$('.indexer-setup').each(function (i, btn) {
var $btn = $(btn);
var id = $btn.data("id");
var link = $btn.data("link");
$btn.click(function () {
displayIndexerSetup(id);
displayIndexerSetup(id, link);
});
});
}
@@ -120,7 +135,7 @@ function prepareTestButtons() {
var id = $btn.data("id");
$btn.click(function () {
doNotify("Test started for " + id, "info", "glyphicon glyphicon-transfer");
var jqxhr = $.post("/admin/test_indexer", JSON.stringify({ indexer: id }), function (data) {
var jqxhr = $.post("test_indexer", JSON.stringify({ indexer: id }), function (data) {
if (data.result == "error") {
doNotify("Test failed for " + id + ": \n" + data.error, "danger", "glyphicon glyphicon-alert");
}
@@ -134,15 +149,15 @@ function prepareTestButtons() {
});
}
function displayIndexerSetup(id) {
function displayIndexerSetup(id, link) {
var jqxhr = $.post("/admin/get_config_form", JSON.stringify({ indexer: id }), function (data) {
var jqxhr = $.post("get_config_form", JSON.stringify({ indexer: id }), function (data) {
if (data.result == "error") {
doNotify("Error: " + data.error, "danger", "glyphicon glyphicon-alert");
return;
}
populateSetupForm(id, data.name, data.config, data.caps);
populateSetupForm(id, data.name, data.config, data.caps, link);
}).fail(function () {
doNotify("Request to Jackett server failed", "danger", "glyphicon glyphicon-alert");
@@ -193,9 +208,9 @@ function populateConfigItems(configForm, config) {
}
}
function newConfigModal(title, config, caps) {
function newConfigModal(title, config, caps, link) {
var configTemplate = Handlebars.compile($("#jackett-config-setup-modal").html());
var configForm = $(configTemplate({ title: title, caps: caps }));
var configForm = $(configTemplate({ title: title, caps: caps, link:link }));
$("#modals").append(configForm);
populateConfigItems(configForm, config);
return configForm;
@@ -231,8 +246,8 @@ function getConfigModalJson(configForm) {
return configJson;
}
function populateSetupForm(indexerId, name, config, caps) {
var configForm = newConfigModal(name, config, caps);
function populateSetupForm(indexerId, name, config, caps, link) {
var configForm = newConfigModal(name, config, caps, link);
var $goButton = configForm.find(".setup-indexer-go");
$goButton.click(function () {
var data = { indexer: indexerId, name: name };
@@ -242,7 +257,7 @@ function populateSetupForm(indexerId, name, config, caps) {
$goButton.prop('disabled', true);
$goButton.html($('#spinner').html());
var jqxhr = $.post("/admin/configure_indexer", JSON.stringify(data), function (data) {
var jqxhr = $.post("configure_indexer", JSON.stringify(data), function (data) {
if (data.result == "error") {
if (data.config) {
populateConfigItems(configForm, data.config);
@@ -316,7 +331,7 @@ function bindUIButtons() {
});
$("#jackett-show-releases").click(function () {
var jqxhr = $.get("/admin/GetCache", function (data) {
var jqxhr = $.get("GetCache", function (data) {
var releaseTemplate = Handlebars.compile($("#jackett-releases").html());
var item = { releases: data, Title: 'Releases' };
var releaseDialog = $(releaseTemplate(item));
@@ -398,7 +413,7 @@ function bindUIButtons() {
$("#jackett-show-search").click(function () {
$('#select-indexer-modal').remove();
var jqxhr = $.get("/admin/get_indexers", function (data) {
var jqxhr = $.get("get_indexers", function (data) {
var scope = {
items: data.items
};
@@ -454,7 +469,7 @@ function bindUIButtons() {
$('#searchResults').empty();
$('#jackett-search-perform').html($('#spinner').html());
var jqxhr = $.post("/admin/search", queryObj, function (data) {
var jqxhr = $.post("search", queryObj, function (data) {
$('#jackett-search-perform').html('Search trackers');
var resultsTemplate = Handlebars.compile($("#jackett-search-results").html());
var results = $('#searchResults');
@@ -529,7 +544,7 @@ function bindUIButtons() {
});
$("#view-jackett-logs").click(function () {
var jqxhr = $.get("/admin/GetLogs", function (data) {
var jqxhr = $.get("GetLogs", function (data) {
var releaseTemplate = Handlebars.compile($("#jackett-logs").html());
var item = { logs: data };
var releaseDialog = $(releaseTemplate(item));
@@ -543,25 +558,28 @@ function bindUIButtons() {
$("#change-jackett-port").click(function () {
var jackett_port = $("#jackett-port").val();
var jackett_basepathoverride = $("#jackett-basepathoverride").val();
var jackett_external = $("#jackett-allowext").is(':checked');
var jackett_update = $("#jackett-allowupdate").is(':checked');
var jackett_prerelease = $("#jackett-prerelease").is(':checked');
var jackett_logging = $("#jackett-logging").is(':checked');
var jsonObject = {
port: jackett_port,
external: jackett_external,
blackholedir: $("#jackett-savedir").val()
updatedisabled: jackett_update,
prerelease: jackett_prerelease,
blackholedir: $("#jackett-savedir").val(),
logging: jackett_logging,
basepathoverride: jackett_basepathoverride
};
var jqxhr = $.post("/admin/set_config", JSON.stringify(jsonObject), function (data) {
var jqxhr = $.post("set_config", JSON.stringify(jsonObject), function (data) {
if (data.result == "error") {
doNotify("Error: " + data.error, "danger", "glyphicon glyphicon-alert");
return;
} else {
doNotify("Redirecting you to complete configuration update..", "success", "glyphicon glyphicon-ok");
window.setTimeout(function () {
url = window.location.href;
if (data.external) {
window.location.href = url.substr(0, url.lastIndexOf(":") + 1) + data.port;
} else {
window.location.href = 'http://127.0.0.1:' + data.port;
}
window.location.reload(true);
}, 3000);
}
@@ -570,11 +588,24 @@ function bindUIButtons() {
});
});
$("#trigger-updater").click(function () {
var jqxhr = $.get("trigger_update", function (data) {
if (data.result == "error") {
doNotify("Error: " + data.error, "danger", "glyphicon glyphicon-alert");
return;
} else {
doNotify("Updater triggered see log for details..", "success", "glyphicon glyphicon-ok");
}
}).fail(function () {
doNotify("Request to Jackett server failed", "danger", "glyphicon glyphicon-alert");
});
});
$("#change-jackett-password").click(function () {
var password = $("#jackett-adminpwd").val();
var jsonObject = { password: password };
var jqxhr = $.post("/admin/set_admin_password", JSON.stringify(jsonObject), function (data) {
var jqxhr = $.post("set_admin_password", JSON.stringify(jsonObject), function (data) {
if (data.result == "error") {
doNotify("Error: " + data.error, "danger", "glyphicon glyphicon-alert");

View File

@@ -4,27 +4,27 @@
<head>
<meta charset="utf-8" />
<link rel='shortcut icon' type='image/x-icon' href='/favicon.ico' />
<script src="/libs/filesize.min.js"></script>
<script src="/libs/jquery.min.js"></script>
<script src="/libs/jquery.dataTables.min.js"></script>
<script src="/libs/handlebars.min.js"></script>
<script src="/libs/moment.min.js"></script>
<script src="/libs/handlebarsmoment.js"></script>
<script src="/bootstrap/bootstrap.min.js"></script>
<script src="/libs/bootstrap-notify.js"></script>
<script src="../libs/filesize.min.js"></script>
<script src="../libs/jquery.min.js"></script>
<script src="../libs/jquery.dataTables.min.js"></script>
<script src="../libs/handlebars.min.js"></script>
<script src="../libs/moment.min.js"></script>
<script src="../libs/handlebarsmoment.js"></script>
<script src="../bootstrap/bootstrap.min.js"></script>
<script src="../libs/bootstrap-notify.js"></script>
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>
<link href="/bootstrap/bootstrap.min.css" rel="stylesheet">
<link href="/animate.css" rel="stylesheet">
<link href="/custom.css" rel="stylesheet">
<link href="/css/jquery.dataTables.css" rel="stylesheet">
<link rel="stylesheet" href="/css/font-awesome.min.css">
<link href="../bootstrap/bootstrap.min.css" rel="stylesheet">
<link href="../animate.css" rel="stylesheet">
<link href="../custom.css" rel="stylesheet">
<link href="../css/jquery.dataTables.css" rel="stylesheet">
<link rel="stylesheet" href="../css/font-awesome.min.css">
<title>Jackett</title>
</head>
<body>
<div id="page">
<img id="logo" src="/jacket_medium.png" alt="Logo" /><span id="header-title">Jackett</span>
<img id="logo" src="../jacket_medium.png" alt="Logo" /><span id="header-title">Jackett</span>
<div class="pull-right jackett-apikey">
<span class="input-header">API Key: </span>
@@ -48,7 +48,7 @@
<ol>
<li>Go to <b>Settings > Indexers > Add > Torznab > Custom</b>.</li>
<li>For <b>URL</b> enter the <b>Torznab Host</b> of one of the indexers.</li>
<li>For the <b>API key</b> using the key below.</li>
<li>For the <b>API key</b> using the key above.</li>
</ol>
<h4>Adding a Jackett indexer in CouchPotato</h4>
<ol>
@@ -60,8 +60,22 @@
</div>
<hr />
<h3>Jackett Configuration</h3>
<div class="text-center">
<div class="btn-group">
<button id="change-jackett-port" class="btn btn-primary btn-sm">
<i class="fa fa-wrench"></i> Apply server settings <span class="glyphicon glyphicon-ok-wrench" aria-hidden="true"></span>
</button>
<button id="view-jackett-logs" class="btn btn-danger btn-sm">
<i class="fa fa-rss"></i> View logs <span class="glyphicon glyphicon-ok-wrench" aria-hidden="true"></span>
</button>
<button id="trigger-updater" class="btn btn-warning btn-sm">
<i class="fa fa-wrench"></i> Check for updates <span class="glyphicon glyphicon-ok-wrench" aria-hidden="true"></span>
</button>
</div>
</div>
<br />
<div class="input-area">
<span class="input-header">Admin Password: </span>
<span class="input-header">Admin password: </span>
<input id="jackett-adminpwd" class="form-control input-right" type="password" value="" placeholder="Blank to disable" />
<button id="change-jackett-password" class="btn btn-primary btn-sm">
<i class="fa fa-user-secret"></i> Set Password <span class="glyphicon glyphicon-ok-wrench" aria-hidden="true"></span>
@@ -70,15 +84,13 @@
Logout
</a>
</div>
<div class="input-area">
<span class="input-header">Base Path Override: </span>
<input id="jackett-basepathoverride" class="form-control input-right" type="text" value="" placeholder="/jackett/">
</div>
<div class="input-area">
<span class="input-header">Server port: </span>
<input id="jackett-port" class="form-control input-right" type="text" value="" placeholder="9117">
<button id="change-jackett-port" class="btn btn-primary btn-sm">
<i class="fa fa-wrench"></i> Apply server settings <span class="glyphicon glyphicon-ok-wrench" aria-hidden="true"></span>
</button>
<button id="view-jackett-logs" class="btn btn-danger btn-sm">
<i class="fa fa-rss"></i> View logs <span class="glyphicon glyphicon-ok-wrench" aria-hidden="true"></span>
</button>
</div>
<div class="input-area">
<span class="input-header">Manual download blackhole directory: </span>
@@ -88,6 +100,20 @@
<span class="input-header">External access: </span>
<input id="jackett-allowext" class="form-control input-right" type="checkbox" />
</div>
<div class="input-area">
<span class="input-header">Disable auto update: </span>
<input id="jackett-allowupdate" class="form-control input-right" type="checkbox" />
</div>
<div class="input-area">
<span class="input-header">Update to pre-release: </span>
<input id="jackett-prerelease" class="form-control input-right" type="checkbox" />
</div>
<div class="input-area">
<span class="input-header">Enhanced logging: </span>
<input id="jackett-logging" class="form-control input-right" type="checkbox" />
</div>
<hr />
<div id="footer">
Jackett Version <span id="app-version"></span>
@@ -149,10 +175,10 @@
<div class="indexer-logo">
<!-- Make section browser searchable -->
<span class="hidden-name">{{name}}</span>
<img alt="{{name}}" title="{{name}}" src="/logos/{{id}}.png" />
<img alt="{{name}}" title="{{name}}" src="../logos/{{id}}.png" />
</div>
<div class="indexer-buttons">
<button class="btn btn-primary btn-sm indexer-setup" data-id="{{id}}">
<button class="btn btn-primary btn-sm indexer-setup" data-id="{{id}}" data-link="{{site_link}}">
<span class="glyphicon glyphicon-wrench" aria-hidden="true"></span>
</button>
<button class="btn btn-danger btn-sm indexer-button-delete" data-id="{{id}}">
@@ -180,14 +206,11 @@
</script>
<script id="unconfigured-indexer" type="text/x-handlebars-template">
<div class="unconfigured-indexer card">
<div class="indexer-logo">
<div class="indexer-logo indexer-setup" data-id="{{id}}" data-link="{{site_link}}">
<!-- Make section browser searchable -->
<span class="hidden-name">{{name}}</span>
<img alt="{{name}}" title="{{name}}" src="/logos/{{id}}.png" />
</div>
<div class="indexer-buttons">
<a class="btn btn-info" target="_blank" href="{{site_link}}">Visit <span class="glyphicon glyphicon-new-window" aria-hidden="true"></span></a>
<button class="indexer-setup btn btn-success" data-id="{{id}}">Setup <span class="glyphicon glyphicon-ok" aria-hidden="true"></span></button>
<img alt="{{name}}" title="{{name}}" src="../logos/{{id}}.png" />
</div>
</div>
</script>
@@ -414,7 +437,7 @@
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">{{title}}</h4>
<h4 class="modal-title">{{title}} - <a target="_blank" href="{{link}}">{{link}}</a></h4>
</div>
<div class="modal-body">
<form class="config-setup-form"></form>
@@ -458,6 +481,6 @@
<span class="spinner glyphicon glyphicon-refresh"></span>
</script>
<script src="/custom.js"></script>
<script src="../custom.js"></script>
</body>
</html>

View File

@@ -6,28 +6,28 @@
<link rel='shortcut icon' type='image/x-icon' href='/favicon.ico' />
<script src="/libs/jquery.min.js"></script>
<script src="/libs/jquery.dataTables.min.js"></script>
<script src="/libs/handlebars.min.js"></script>
<script src="/libs/moment.min.js"></script>
<script src="/libs/handlebarsmoment.js"></script>
<script src="/bootstrap/bootstrap.min.js"></script>
<script src="/libs/bootstrap-notify.js"></script>
<script src="../libs/jquery.min.js"></script>
<script src="../libs/jquery.dataTables.min.js"></script>
<script src="../libs/handlebars.min.js"></script>
<script src="../libs/moment.min.js"></script>
<script src="../libs/handlebarsmoment.js"></script>
<script src="../bootstrap/bootstrap.min.js"></script>
<script src="../libs/bootstrap-notify.js"></script>
<link href="/bootstrap/bootstrap.min.css" rel="stylesheet">
<link href="/animate.css" rel="stylesheet">
<link href="/custom.css" rel="stylesheet">
<link href="../bootstrap/bootstrap.min.css" rel="stylesheet">
<link href="../animate.css" rel="stylesheet">
<link href="../custom.css" rel="stylesheet">
<title>Jackett</title>
</head>
<body>
<div id="page">
<img id="logo" src="/jacket_medium.png" /><span id="header-title">Jackett</span>
<img id="logo" src="../jacket_medium.png" /><span id="header-title">Jackett</span>
<hr />
<h1>Login</h1>
<form action="/Admin/Dashboard" method="post">
<form action="Dashboard" method="post">
<div class="input-area">
<span class="input-header">Admin password</span>
<input id="password" name="password" class="form-control input-right" type="password">

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -39,8 +39,9 @@ namespace Jackett.Controllers
private ICacheService cacheService;
private Logger logger;
private ILogCacheService logCache;
private IUpdateService updater;
public AdminController(IConfigurationService config, IIndexerManagerService i, IServerService ss, ISecuityService s, IProcessService p, ICacheService c, Logger l, ILogCacheService lc)
public AdminController(IConfigurationService config, IIndexerManagerService i, IServerService ss, ISecuityService s, IProcessService p, ICacheService c, Logger l, ILogCacheService lc, IUpdateService u)
{
this.config = config;
indexerService = i;
@@ -50,6 +51,7 @@ namespace Jackett.Controllers
cacheService = c;
logger = l;
logCache = lc;
updater = u;
}
private async Task<JToken> ReadPostDataJson()
@@ -78,7 +80,7 @@ namespace Jackett.Controllers
var ctx = Request.GetOwinContext();
var authManager = ctx.Authentication;
authManager.SignOut("ApplicationCookie");
return Redirect("/Admin/Dashboard");
return Redirect("Admin/Dashboard");
}
[HttpGet]
@@ -291,6 +293,15 @@ namespace Jackett.Controllers
return Json(jsonReply);
}
[Route("trigger_update")]
[HttpGet]
public IHttpActionResult TriggerUpdates()
{
var jsonReply = new JObject();
updater.CheckForUpdatesNow();
return Json(jsonReply);
}
[Route("get_jackett_config")]
[HttpGet]
public IHttpActionResult GetConfig()
@@ -303,7 +314,12 @@ namespace Jackett.Controllers
cfg["external"] = serverService.Config.AllowExternal;
cfg["api_key"] = serverService.Config.APIKey;
cfg["blackholedir"] = serverService.Config.BlackholeDir;
cfg["updatedisabled"] = serverService.Config.UpdateDisabled;
cfg["prerelease"] = serverService.Config.UpdatePrerelease;
cfg["password"] = string.IsNullOrEmpty(serverService.Config.AdminPassword) ? string.Empty : serverService.Config.AdminPassword.Substring(0, 10);
cfg["logging"] = Startup.TracingEnabled;
cfg["basepathoverride"] = serverService.Config.BasePathOverride;
jsonReply["config"] = cfg;
jsonReply["app_version"] = config.GetVersion();
@@ -331,9 +347,23 @@ namespace Jackett.Controllers
int port = (int)postData["port"];
bool external = (bool)postData["external"];
string saveDir = (string)postData["blackholedir"];
bool updateDisabled = (bool)postData["updatedisabled"];
bool preRelease = (bool)postData["prerelease"];
bool logging = (bool)postData["logging"];
string basePathOverride = (string)postData["basepathoverride"];
Engine.Server.Config.UpdateDisabled = updateDisabled;
Engine.Server.Config.UpdatePrerelease = preRelease;
Engine.Server.Config.BasePathOverride = basePathOverride;
Startup.BasePath = Engine.Server.BasePath();
Engine.Server.SaveConfig();
Engine.SetLogLevel(logging ? LogLevel.Debug : LogLevel.Info);
Startup.TracingEnabled = logging;
if (port != Engine.Server.Config.Port || external != Engine.Server.Config.AllowExternal)
{
if (ServerUtil.RestrictedPorts.Contains(port))
{
jsonReply["result"] = "error";
@@ -371,17 +401,16 @@ namespace Jackett.Controllers
}
}
(new Thread(() =>
{
Thread.Sleep(500);
serverService.Stop();
Engine.BuildContainer();
Engine.Server.Initalize();
Engine.Server.Start();
})).Start();
(new Thread(() =>
{
Thread.Sleep(500);
serverService.Stop();
Engine.BuildContainer();
Engine.Server.Initalize();
Engine.Server.Start();
})).Start();
}
if (saveDir != Engine.Server.Config.BlackholeDir)
{
if (!string.IsNullOrEmpty(saveDir))
@@ -421,7 +450,7 @@ namespace Jackett.Controllers
private void ConfigureCacheResults(List<TrackerCacheResult> results)
{
var serverUrl = string.Format("{0}://{1}:{2}/", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port);
var serverUrl = string.Format("{0}://{1}:{2}{3}", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port, serverService.BasePath());
foreach (var result in results)
{
var link = result.Link;

View File

@@ -117,7 +117,7 @@ namespace Jackett.Controllers
}
releases = indexer.FilterResults(torznabQuery, releases);
var serverUrl = string.Format("{0}://{1}:{2}/", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port);
var serverUrl = string.Format("{0}://{1}:{2}{3}", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port, serverService.BasePath());
var potatoResponse = new TorrentPotatoResponse();
releases = TorznabUtil.FilterResultsToTitle(releases, torznabQuery.SanitizedSearchTerm, year);

View File

@@ -100,7 +100,7 @@ namespace Jackett.Controllers
logger.Info(logBuilder.ToString());
var serverUrl = string.Format("{0}://{1}:{2}/", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port);
var serverUrl = string.Format("{0}://{1}:{2}{3}", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port, serverService.BasePath());
var resultPage = new ResultPage(new ChannelInfo
{
Title = indexer.DisplayName,

View File

@@ -85,6 +85,7 @@ namespace Jackett
using (var easy = new CurlEasy())
{
easy.Url = curlRequest.Url;
easy.BufferSize = 64 * 1024;
easy.UserAgent = BrowserUtil.ChromeUserAgent;
@@ -135,6 +136,17 @@ namespace Jackett
easy.ForbidReuse = true;
}
if (Startup.IgnoreSslErrors == true)
{
easy.SetOpt(CurlOption.SslVerifyhost, false);
easy.SetOpt(CurlOption.SslVerifyPeer, false);
}
if (Startup.ProxyConnection != null)
{
easy.SetOpt(CurlOption.Proxy, Startup.ProxyConnection);
}
easy.Perform();
if (easy.LastErrorCode != CurlCode.Ok)
@@ -149,6 +161,15 @@ namespace Jackett
var headerBytes = Combine(headerBuffers.ToArray());
var headerString = Encoding.UTF8.GetString(headerBytes);
if (Startup.ProxyConnection != null)
{
var firstcrlf = headerString.IndexOf("\r\n\r\n");
var secondcrlf = headerString.IndexOf("\r\n\r\n", firstcrlf + 1);
if (secondcrlf > 0)
{
headerString = headerString.Substring(firstcrlf + 4, secondcrlf - (firstcrlf));
}
}
var headerParts = headerString.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
var headers = new List<string[]>();
var headerCount = 0;

View File

@@ -1,154 +1,191 @@
using Autofac;
using Jackett.Services;
using NLog;
using NLog.Config;
using NLog.LayoutRenderers;
using NLog.Targets;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Jackett
{
public class Engine
{
private static IContainer container = null;
static Engine()
{
BuildContainer();
}
public static void BuildContainer()
{
var builder = new ContainerBuilder();
builder.RegisterModule<JackettModule>();
container = builder.Build();
// Register the container in itself to allow for late resolves
var secondaryBuilder = new ContainerBuilder();
secondaryBuilder.RegisterInstance<IContainer>(container).SingleInstance();
SetupLogging(secondaryBuilder);
secondaryBuilder.Update(container);
}
public static IContainer GetContainer()
{
return container;
}
public static bool IsWindows
{
get
{
return Environment.OSVersion.Platform == PlatformID.Win32NT;
}
}
public static IConfigurationService ConfigService
{
get
{
return container.Resolve<IConfigurationService>();
}
}
public static IProcessService ProcessService
{
get
{
return container.Resolve<IProcessService>();
}
}
public static IServiceConfigService ServiceConfig
{
get
{
return container.Resolve<IServiceConfigService>();
}
}
public static IServerService Server
{
get
{
return container.Resolve<IServerService>();
}
}
public static IRunTimeService RunTime
{
get
{
return container.Resolve<IRunTimeService>();
}
}
public static Logger Logger
{
get
{
return container.Resolve<Logger>();
}
}
public static ISecuityService SecurityService
{
get
{
return container.Resolve<ISecuityService>();
}
}
private static void SetupLogging(ContainerBuilder builder)
{
var logLevel = Startup.TracingEnabled ? LogLevel.Debug : LogLevel.Info;
// Add custom date time format renderer as the default is too long
ConfigurationItemFactory.Default.LayoutRenderers.RegisterDefinition("simpledatetime", typeof(SimpleDateTimeRenderer));
var logConfig = new LoggingConfiguration();
var logFile = new FileTarget();
logConfig.AddTarget("file", logFile);
logFile.Layout = "${longdate} ${level} ${message} ${exception:format=ToString}";
logFile.FileName = Path.Combine(ConfigurationService.GetAppDataFolderStatic(), "log.txt");
logFile.ArchiveFileName = "log.{#####}.txt";
logFile.ArchiveAboveSize = 500000;
logFile.MaxArchiveFiles = 5;
logFile.KeepFileOpen = false;
logFile.ArchiveNumbering = ArchiveNumberingMode.DateAndSequence;
var logFileRule = new LoggingRule("*", logLevel, logFile);
logConfig.LoggingRules.Add(logFileRule);
var logConsole = new ColoredConsoleTarget();
logConfig.AddTarget("console", logConsole);
logConsole.Layout = "${simpledatetime} ${level} ${message} ${exception:format=ToString}";
var logConsoleRule = new LoggingRule("*", logLevel, logConsole);
logConfig.LoggingRules.Add(logConsoleRule);
var logService = new LogCacheService();
logConfig.AddTarget("service", logService);
var serviceRule = new LoggingRule("*", logLevel,logService);
logConfig.LoggingRules.Add(serviceRule);
LogManager.Configuration = logConfig;
builder.RegisterInstance<Logger>(LogManager.GetCurrentClassLogger()).SingleInstance();
}
}
[LayoutRenderer("simpledatetime")]
public class SimpleDateTimeRenderer : LayoutRenderer
{
protected override void Append(StringBuilder builder, LogEventInfo logEvent)
{
builder.Append(DateTime.Now.ToString("MM-dd HH:mm:ss"));
}
}
}
using Autofac;
using Jackett.Services;
using NLog;
using NLog.Config;
using NLog.LayoutRenderers;
using NLog.Targets;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Jackett
{
public class Engine
{
private static IContainer container = null;
static Engine()
{
BuildContainer();
}
public static void BuildContainer()
{
var builder = new ContainerBuilder();
builder.RegisterModule<JackettModule>();
container = builder.Build();
// Register the container in itself to allow for late resolves
var secondaryBuilder = new ContainerBuilder();
secondaryBuilder.RegisterInstance<IContainer>(container).SingleInstance();
SetupLogging(secondaryBuilder);
secondaryBuilder.Update(container);
}
public static IContainer GetContainer()
{
return container;
}
public static bool IsWindows
{
get
{
return Environment.OSVersion.Platform == PlatformID.Win32NT;
}
}
public static IConfigurationService ConfigService
{
get
{
return container.Resolve<IConfigurationService>();
}
}
public static IProcessService ProcessService
{
get
{
return container.Resolve<IProcessService>();
}
}
public static IServiceConfigService ServiceConfig
{
get
{
return container.Resolve<IServiceConfigService>();
}
}
public static ITrayLockService LockService
{
get
{
return container.Resolve<ITrayLockService>();
}
}
public static IServerService Server
{
get
{
return container.Resolve<IServerService>();
}
}
public static IRunTimeService RunTime
{
get
{
return container.Resolve<IRunTimeService>();
}
}
public static Logger Logger
{
get
{
return container.Resolve<Logger>();
}
}
public static ISecuityService SecurityService
{
get
{
return container.Resolve<ISecuityService>();
}
}
public static void SetupLogging(ContainerBuilder builder = null, string logfile = "log.txt")
{
var logLevel = Startup.TracingEnabled ? LogLevel.Debug : LogLevel.Info;
// Add custom date time format renderer as the default is too long
ConfigurationItemFactory.Default.LayoutRenderers.RegisterDefinition("simpledatetime", typeof(SimpleDateTimeRenderer));
var logConfig = new LoggingConfiguration();
var logFile = new FileTarget();
logConfig.AddTarget("file", logFile);
logFile.Layout = "${longdate} ${level} ${message} ${exception:format=ToString}";
logFile.FileName = Path.Combine(ConfigurationService.GetAppDataFolderStatic(), logfile);
logFile.ArchiveFileName = "log.{#####}.txt";
logFile.ArchiveAboveSize = 500000;
logFile.MaxArchiveFiles = 5;
logFile.KeepFileOpen = false;
logFile.ArchiveNumbering = ArchiveNumberingMode.DateAndSequence;
var logFileRule = new LoggingRule("*", logLevel, logFile);
logConfig.LoggingRules.Add(logFileRule);
var logConsole = new ColoredConsoleTarget();
logConfig.AddTarget("console", logConsole);
logConsole.Layout = "${simpledatetime} ${level} ${message} ${exception:format=ToString}";
var logConsoleRule = new LoggingRule("*", logLevel, logConsole);
logConfig.LoggingRules.Add(logConsoleRule);
var logService = new LogCacheService();
logConfig.AddTarget("service", logService);
var serviceRule = new LoggingRule("*", logLevel, logService);
logConfig.LoggingRules.Add(serviceRule);
LogManager.Configuration = logConfig;
if (builder != null)
{
builder.RegisterInstance<Logger>(LogManager.GetCurrentClassLogger()).SingleInstance();
}
}
public static void SetLogLevel(LogLevel level)
{
foreach (var rule in LogManager.Configuration.LoggingRules)
{
if (level == LogLevel.Debug)
{
if (!rule.Levels.Contains(LogLevel.Debug))
{
rule.EnableLoggingForLevel(LogLevel.Debug);
}
}
else
{
if (rule.Levels.Contains(LogLevel.Debug))
{
rule.DisableLoggingForLevel(LogLevel.Debug);
}
}
}
LogManager.ReconfigExistingLoggers();
}
}
[LayoutRenderer("simpledatetime")]
public class SimpleDateTimeRenderer : LayoutRenderer
{
protected override void Append(StringBuilder builder, LogEventInfo logEvent)
{
builder.Append(DateTime.Now.ToString("MM-dd HH:mm:ss"));
}
}
}

View File

@@ -0,0 +1,870 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
using CsQuery;
using Jackett.Models;
using Jackett.Models.IndexerConfig.Bespoke;
using Jackett.Services;
using Jackett.Utils;
using Jackett.Utils.Clients;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;
namespace Jackett.Indexers
{
/// <summary>
/// Provider for Abnormal Private French Tracker
/// </summary>
public class Abnormal : BaseIndexer, IIndexer
{
private string LoginUrl { get { return SiteLink + "login.php"; } }
private string SearchUrl { get { return SiteLink + "torrents.php"; } }
private string TorrentCommentUrl { get { return TorrentDescriptionUrl; } }
private string TorrentDescriptionUrl { get { return SiteLink + "torrents.php?id="; } }
private string TorrentDownloadUrl { get { return SiteLink + "torrents.php?action=download&id={id}&authkey={auth_key}&torrent_pass={torrent_pass}"; } }
private bool Latency { get { return ConfigData.Latency.Value; } }
private bool DevMode { get { return ConfigData.DevMode.Value; } }
private bool CacheMode { get { return ConfigData.HardDriveCache.Value; } }
private string directory { get { return System.IO.Path.GetTempPath() + "Jackett\\" + MethodBase.GetCurrentMethod().DeclaringType.Name + "\\"; } }
private Dictionary<string, string> emulatedBrowserHeaders = new Dictionary<string, string>();
private CQ fDom = null;
private ConfigurationDataAbnormal ConfigData
{
get { return (ConfigurationDataAbnormal)configData; }
set { base.configData = value; }
}
public Abnormal(IIndexerManagerService i, IWebClient w, Logger l, IProtectionService ps)
: base(
name: "Abnormal",
description: "General French Private Tracker",
link: "https://abnormal.ws/",
caps: new TorznabCapabilities(),
manager: i,
client: w,
logger: l,
p: ps,
downloadBase: "https://abnormal.ws/torrents.php?action=download&id=",
configData: new ConfigurationDataAbnormal())
{
// Clean capabilities
TorznabCaps.Categories.Clear();
// Movies
AddCategoryMapping("MOVIE|DVDR", TorznabCatType.MoviesDVD); // DVDR
AddCategoryMapping("MOVIE|DVDRIP", TorznabCatType.MoviesSD); // DVDRIP
AddCategoryMapping("MOVIE|BDRIP", TorznabCatType.MoviesSD); // BDRIP
AddCategoryMapping("MOVIE|VOSTFR", TorznabCatType.MoviesOther); // VOSTFR
AddCategoryMapping("MOVIE|HD|720p", TorznabCatType.MoviesHD); // HD 720P
AddCategoryMapping("MOVIE|HD|1080p", TorznabCatType.MoviesHD); // HD 1080P
AddCategoryMapping("MOVIE|REMUXBR", TorznabCatType.MoviesBluRay); // REMUX BLURAY
AddCategoryMapping("MOVIE|FULLBR", TorznabCatType.MoviesBluRay); // FULL BLURAY
// Series
AddCategoryMapping("TV|SD|VOSTFR", TorznabCatType.TV); // SD VOSTFR
AddCategoryMapping("TV|HD|VOSTFR", TorznabCatType.TVHD); // HD VOSTFR
AddCategoryMapping("TV|SD|VF", TorznabCatType.TVSD); // SD VF
AddCategoryMapping("TV|HD|VF", TorznabCatType.TVHD); // HD VF
AddCategoryMapping("TV|PACK|FR", TorznabCatType.TVOTHER); // PACK FR
AddCategoryMapping("TV|PACK|VOSTFR", TorznabCatType.TVOTHER); // PACK VOSTFR
AddCategoryMapping("TV|EMISSIONS", TorznabCatType.TVOTHER); // EMISSIONS
// Anime
AddCategoryMapping("ANIME", TorznabCatType.TVAnime); // ANIME
// Documentaries
AddCategoryMapping("DOCS", TorznabCatType.TVDocumentary); // DOCS
// Music
AddCategoryMapping("MUSIC|FLAC", TorznabCatType.AudioLossless); // FLAC
AddCategoryMapping("MUSIC|MP3", TorznabCatType.AudioMP3); // MP3
AddCategoryMapping("MUSIC|CONCERT", TorznabCatType.AudioVideo); // CONCERT
// Other
AddCategoryMapping("PC|APP", TorznabCatType.PC); // PC
AddCategoryMapping("PC|GAMES", TorznabCatType.PCGames); // GAMES
AddCategoryMapping("EBOOKS", TorznabCatType.BooksEbook); // EBOOKS
}
/// <summary>
/// Configure our WiHD Provider
/// </summary>
/// <param name="configJson">Our params in Json</param>
/// <returns>Configuration state</returns>
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
// Retrieve config values set by Jackett's user
ConfigData.LoadValuesFromJson(configJson);
// Check & Validate Config
validateConfig();
// Setting our data for a better emulated browser (maximum security)
// TODO: Encoded Content not supported by Jackett at this time
// emulatedBrowserHeaders.Add("Accept-Encoding", "gzip, deflate");
// If we want to simulate a browser
if (ConfigData.Browser.Value) {
// Clean headers
emulatedBrowserHeaders.Clear();
// Inject headers
emulatedBrowserHeaders.Add("Accept", ConfigData.HeaderAccept.Value);
emulatedBrowserHeaders.Add("Accept-Language", ConfigData.HeaderAcceptLang.Value);
emulatedBrowserHeaders.Add("DNT", Convert.ToInt32(ConfigData.HeaderDNT.Value).ToString());
emulatedBrowserHeaders.Add("Upgrade-Insecure-Requests", Convert.ToInt32(ConfigData.HeaderUpgradeInsecure.Value).ToString());
emulatedBrowserHeaders.Add("User-Agent", ConfigData.HeaderUserAgent.Value);
}
// Getting login form to retrieve CSRF token
var myRequest = new Utils.Clients.WebRequest()
{
Url = LoginUrl
};
// Add our headers to request
myRequest.Headers = emulatedBrowserHeaders;
// Building login form data
var pairs = new Dictionary<string, string> {
{ "username", ConfigData.Username.Value },
{ "password", ConfigData.Password.Value },
{ "keeplogged", "1" },
{ "login", "Connexion" }
};
// Do the login
var request = new Utils.Clients.WebRequest(){
PostData = pairs,
Referer = LoginUrl,
Type = RequestType.POST,
Url = LoginUrl,
Headers = emulatedBrowserHeaders
};
// Perform loggin
latencyNow();
output("\nPerform loggin.. with " + LoginUrl);
var response = await webclient.GetString(request);
// Test if we are logged in
await ConfigureIfOK(response.Cookies, response.Cookies.Contains("session="), () =>
{
// Parse error page
CQ dom = response.Content;
string message = dom[".warning"].Text().Split('.').Reverse().Skip(1).First();
// Try left
string left = dom[".info"].Text().Trim();
// Oops, unable to login
output("-> Login failed: \"" + message + "\" and " + left + " tries left before being banned for 6 hours !", "error");
throw new ExceptionWithConfigData("Login failed: " + message, configData);
});
output("-> Login Success");
return IndexerConfigurationStatus.RequiresTesting;
}
/// <summary>
/// Execute our search query
/// </summary>
/// <param name="query">Query</param>
/// <returns>Releases</returns>
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>();
var torrentRowList = new List<CQ>();
var searchTerm = query.GetQueryString();
var searchUrl = SearchUrl;
int nbResults = 0;
int pageLinkCount = 0;
// Check cache first so we don't query the server (if search term used or not in dev mode)
if(!DevMode && !string.IsNullOrEmpty(searchTerm))
{
lock (cache)
{
// Remove old cache items
CleanCache();
// Search in cache
var cachedResult = cache.Where(i => i.Query == searchTerm).FirstOrDefault();
if (cachedResult != null)
return cachedResult.Results.Select(s => (ReleaseInfo)s.Clone()).ToArray();
}
}
// Build our query
var request = buildQuery(searchTerm, query, searchUrl);
// Getting results & Store content
WebClientStringResult results = await queryExec(request);
fDom = results.Content;
try
{
// Find torrent rows
var firstPageRows = findTorrentRows();
// Add them to torrents list
torrentRowList.AddRange(firstPageRows.Select(fRow => fRow.Cq()));
// Check if there are pagination links at bottom
Boolean pagination = (fDom[".linkbox > a"].Length != 0);
// If pagination available
if (pagination) {
// Calculate numbers of pages available for this search query (Based on number results and number of torrents on first page)
pageLinkCount = ParseUtil.CoerceInt(Regex.Match(fDom[".linkbox > a"].Last().Attr("href").ToString(), @"\d+").Value);
// Calculate average number of results (based on torrents rows lenght on first page)
nbResults = firstPageRows.Count() * pageLinkCount;
}
else {
// Check if we have a minimum of one result
if (firstPageRows.Length >= 1)
{
// Retrieve total count on our alone page
nbResults = firstPageRows.Count();
pageLinkCount = 1;
}
else
{
output("\nNo result found for your query, please try another search term ...\n", "info");
// No result found for this query
return releases;
}
}
output("\nFound " + nbResults + " result(s) (+/- " + firstPageRows.Length + ") in " + pageLinkCount + " page(s) for this query !");
output("\nThere are " + firstPageRows.Length + " results on the first page !");
// If we have a term used for search and pagination result superior to one
if (!string.IsNullOrWhiteSpace(query.GetQueryString()) && pageLinkCount > 1)
{
// Starting with page #2
for (int i = 2; i <= Math.Min(Int32.Parse(ConfigData.Pages.Value), pageLinkCount); i++)
{
output("\nProcessing page #" + i);
// Request our page
latencyNow();
// Build our query
var pageRequest = buildQuery(searchTerm, query, searchUrl, i);
// Getting results & Store content
WebClientStringResult pageResults = await queryExec(pageRequest);
// Assign response
fDom = pageResults.Content;
// Process page results
var additionalPageRows = findTorrentRows();
// Add them to torrents list
torrentRowList.AddRange(additionalPageRows.Select(fRow => fRow.Cq()));
}
}
else
{
// No search term, maybe testing... so registring autkey and torrentpass for future uses
string infosData = firstPageRows.First().Find("td:eq(3) > a").Attr("href");
IList<string> infosList = infosData.Split('&').Select(s => s.Trim()).Where(s => s != String.Empty).ToList();
IList<string> infosTracker = infosList.Select(s => s.Split(new[] { '=' }, 2)[1].Trim()).ToList();
output("\nStoring Authkey for future uses...");
ConfigData.AuthKey.Value = infosTracker[2];
output("\nStoring TorrentPass for future uses...");
ConfigData.TorrentPass.Value = infosTracker[3];
}
// Loop on results
foreach (CQ tRow in torrentRowList)
{
output("\n=>> Torrent #" + (releases.Count + 1));
// ID
int id = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(1) > a").Attr("href").ToString(), @"\d+").Value);
output("ID: " + id);
// Release Name
string name = tRow.Find("td:eq(1) > a").Text().ToString();
output("Release: " + name);
// Category
string categoryID = tRow.Find("td:eq(0) > a").Attr("href").Replace("torrents.php?cat[]=", String.Empty);
output("Category: " + MapTrackerCatToNewznab(categoryID) + " (" + categoryID + ")");
// Seeders
int seeders = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(6)").Text(), @"\d+").Value);
output("Seeders: " + seeders);
// Leechers
int leechers = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(7)").Text(), @"\d+").Value);
output("Leechers: " + leechers);
// Completed
int completed = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(5)").Text(), @"\d+").Value);
output("Completed: " + completed);
// Size
string sizeStr = tRow.Find("td:eq(4)").Text().Replace("Go", "gb").Replace("Mo", "mb").Replace("Ko", "kb");
long size = ReleaseInfo.GetBytes(sizeStr);
output("Size: " + sizeStr + " (" + size + " bytes)");
// Publish DateToString
IList<string> clockList = tRow.Find("td:eq(2) > span").Text().Replace("Il y a", "").Split(',').Select(s => s.Trim()).Where(s => s != String.Empty).ToList();
var date = agoToDate(clockList);
output("Released on: " + date.ToLocalTime());
// Torrent Details URL
Uri detailsLink = new Uri(TorrentDescriptionUrl + id);
output("Details: " + detailsLink.AbsoluteUri);
// Torrent Comments URL
Uri commentsLink = new Uri(TorrentCommentUrl + id);
output("Comments Link: " + commentsLink.AbsoluteUri);
// Torrent Download URL
Uri downloadLink = new Uri(TorrentDownloadUrl.Replace("{id}", id.ToString()).Replace("{auth_key}", ConfigData.AuthKey.Value).Replace("{torrent_pass}", ConfigData.TorrentPass.Value));
output("Download Link: " + downloadLink.AbsoluteUri);
// Building release infos
var release = new ReleaseInfo();
release.Category = MapTrackerCatToNewznab(categoryID.ToString());
release.Title = name;
release.Seeders = seeders;
release.Peers = seeders + leechers;
release.MinimumRatio = 1;
release.MinimumSeedTime = 172800;
release.PublishDate = date;
release.Size = size;
release.Guid = detailsLink;
release.Comments = commentsLink;
release.Link = downloadLink;
releases.Add(release);
}
}
catch (Exception ex)
{
OnParseError("Error, unable to parse result \n" + ex.StackTrace, ex);
}
// Return found releases
return releases;
}
/// <summary>
/// Build query to process
/// </summary>
/// <param name="term">Term to search</param>
/// <param name="query">Torznab Query for categories mapping</param>
/// <param name="url">Search url for provider</param>
/// <param name="page">Page number to request</param>
/// <returns>URL to query for parsing and processing results</returns>
private string buildQuery(string term, TorznabQuery query, string url, int page = 0)
{
var parameters = new NameValueCollection();
List<string> categoriesList = MapTorznabCapsToTrackers(query);
string categories = null;
// Check if we are processing a new page
if (page > 0)
{
// Adding page number to query
parameters.Add("page", page.ToString());
}
// Loop on Categories needed
foreach (string category in categoriesList)
{
// If last, build !
if (categoriesList.Last() == category)
{
// Adding previous categories to URL with latest category
parameters.Add(Uri.EscapeDataString("cat[]"), HttpUtility.UrlEncode(category) + categories);
}
else
{
// Build categories parameter
categories += "&" + Uri.EscapeDataString("cat[]") + "=" + HttpUtility.UrlEncode(category);
}
}
// If search term provided
if (!string.IsNullOrWhiteSpace(term))
{
// Add search term
parameters.Add("search", HttpUtility.UrlEncode(term));
}
else
{
parameters.Add("search", HttpUtility.UrlEncode("%"));
// Showing all torrents (just for output function)
term = "all";
}
// Building our query -- Cannot use GetQueryString due to UrlEncode (generating wrong cat[] param)
url += "?" + string.Join("&", parameters.AllKeys.Select(a => a + "=" + parameters[a]));
output("\nBuilded query for \"" + term + "\"... " + url);
// Return our search url
return url;
}
/// <summary>
/// Switch Method for Querying
/// </summary>
/// <param name="request">URL created by Query Builder</param>
/// <returns>Results from query</returns>
private async Task<WebClientStringResult> queryExec(string request)
{
WebClientStringResult results = null;
// Switch in we are in DEV mode with Hard Drive Cache or not
if (DevMode && CacheMode)
{
// Check Cache before querying and load previous results if available
results = await queryCache(request);
}
else
{
// Querying tracker directly
results = await queryTracker(request);
}
return results;
}
/// <summary>
/// Get Torrents Page from Cache by Query Provided
/// </summary>
/// <param name="request">URL created by Query Builder</param>
/// <returns>Results from query</returns>
private async Task<WebClientStringResult> queryCache(string request)
{
WebClientStringResult results = null;
// Create Directory if not exist
System.IO.Directory.CreateDirectory(directory);
// Clean Storage Provider Directory from outdated cached queries
cleanCacheStorage();
// Create fingerprint for request
string file = directory + request.GetHashCode() + ".json";
// Checking modes states
if (System.IO.File.Exists(file))
{
// File exist... loading it right now !
output("Loading results from hard drive cache ..." + request.GetHashCode() + ".json");
results = JsonConvert.DeserializeObject<WebClientStringResult>(System.IO.File.ReadAllText(file));
}
else
{
// No cached file found, querying tracker directly
results = await queryTracker(request);
// Cached file didn't exist for our query, writing it right now !
output("Writing results to hard drive cache ..." + request.GetHashCode() + ".json");
System.IO.File.WriteAllText(file, JsonConvert.SerializeObject(results));
}
return results;
}
/// <summary>
/// Get Torrents Page from Tracker by Query Provided
/// </summary>
/// <param name="request">URL created by Query Builder</param>
/// <returns>Results from query</returns>
private async Task<WebClientStringResult> queryTracker(string request)
{
WebClientStringResult results = null;
// Cache mode not enabled or cached file didn't exist for our query
output("\nQuerying tracker for results....");
// Request our first page
latencyNow();
results = await RequestStringWithCookiesAndRetry(request, null, null, emulatedBrowserHeaders);
// Return results from tracker
return results;
}
/// <summary>
/// Clean Hard Drive Cache Storage
/// </summary>
/// <param name="force">Force Provider Folder deletion</param>
private void cleanCacheStorage(Boolean force = false)
{
// Check cleaning method
if(force)
{
// Deleting Provider Storage folder and all files recursively
output("\nDeleting Provider Storage folder and all files recursively ...");
// Check if directory exist
if(System.IO.Directory.Exists(directory))
{
// Delete storage directory of provider
System.IO.Directory.Delete(directory, true);
output("-> Storage folder deleted successfully.");
}
else
{
// No directory, so nothing to do
output("-> No Storage folder found for this provider !");
}
}
else
{
int i = 0;
// Check if there is file older than ... and delete them
output("\nCleaning Provider Storage folder... in progress.");
System.IO.Directory.GetFiles(directory)
.Select(f => new System.IO.FileInfo(f))
.Where(f => f.LastAccessTime < DateTime.Now.AddMilliseconds(-Convert.ToInt32(ConfigData.HardDriveCacheKeepTime.Value)))
.ToList()
.ForEach(f => {
output("Deleting cached file << " + f.Name + " >> ... done.");
f.Delete();
i++;
});
// Inform on what was cleaned during process
if(i > 0) {
output("-> Deleted " + i + " cached files during cleaning.");
}
else {
output("-> Nothing deleted during cleaning.");
}
}
}
/// <summary>
/// Generate a random fake latency to avoid detection on tracker side
/// </summary>
private void latencyNow()
{
// Need latency ?
if(Latency)
{
// Generate a random value in our range
var random = new Random(DateTime.Now.Millisecond);
int waiting = random.Next(Convert.ToInt32(ConfigData.LatencyStart.Value), Convert.ToInt32(ConfigData.LatencyEnd.Value));
output("\nLatency Faker => Sleeping for " + waiting + " ms...");
// Sleep now...
System.Threading.Thread.Sleep(waiting);
}
}
/// <summary>
/// Find torrent rows in search pages
/// </summary>
/// <returns>JQuery Object</returns>
private CQ findTorrentRows()
{
// Return all occurencis of torrents found
return fDom[".torrent_table > tbody > tr"].Not(".colhead");
}
/// <summary>
/// Convert Ago date to DateTime
/// </summary>
/// <param name="clockList"></param>
/// <returns>A DateTime</returns>
private DateTime agoToDate(IList<string> clockList)
{
DateTime release = DateTime.Now;
foreach (var ago in clockList)
{
// Check for years
if (ago.Contains("années") || ago.Contains("année"))
{
// Number of years to remove
int years = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
// Removing
release = release.AddYears(-years);
continue;
}
// Check for months
else if (ago.Contains("mois"))
{
// Number of months to remove
int months = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
// Removing
release = release.AddMonths(-months);
continue;
}
// Check for weeks
else if (ago.Contains("semaines") || ago.Contains("semaine"))
{
// Number of weeks to remove
int weeks = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
// Removing
release = release.AddDays(-(7 * weeks));
continue;
}
// Check for days
else if (ago.Contains("jours") || ago.Contains("jour"))
{
// Number of days to remove
int days = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
// Removing
release = release.AddDays(-days);
continue;
}
// Check for hours
else if (ago.Contains("heures") || ago.Contains("heure"))
{
// Number of hours to remove
int hours = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
// Removing
release = release.AddHours(-hours);
continue;
}
// Check for minutes
else if (ago.Contains("mins") || ago.Contains("min"))
{
// Number of minutes to remove
int minutes = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
// Removing
release = release.AddMinutes(-minutes);
continue;
}
// Check for seconds
else if (ago.Contains("secondes") || ago.Contains("seconde"))
{
// Number of seconds to remove
int seconds = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
// Removing
release = release.AddSeconds(-seconds);
continue;
}
else
{
output("Unable to detect release date of torrent", "error");
//throw new Exception("Unable to detect release date of torrent");
}
}
return release;
}
/// <summary>
/// Output message for logging or developpment (console)
/// </summary>
/// <param name="message">Message to output</param>
/// <param name="level">Level for Logger</param>
private void output(string message, string level = "debug")
{
// Check if we are in dev mode
if(DevMode)
{
// Output message to console
Console.WriteLine(message);
}
else
{
// Send message to logger with level
switch (level)
{
default:
goto case "debug";
case "debug":
// Only if Debug Level Enabled on Jackett
if (Engine.Logger.IsDebugEnabled)
{
logger.Debug(message);
}
break;
case "info":
logger.Info(message);
break;
case "error":
logger.Error(message);
break;
}
}
}
/// <summary>
/// Validate Config entered by user on Jackett
/// </summary>
private void validateConfig()
{
output("\nValidating Settings ... \n");
// Check Username Setting
if (string.IsNullOrEmpty(ConfigData.Username.Value))
{
throw new ExceptionWithConfigData("You must provide a username for this tracker to login !", ConfigData);
}
else
{
output("Validated Setting -- Username (auth) => " + ConfigData.Username.Value.ToString());
}
// Check Password Setting
if (string.IsNullOrEmpty(ConfigData.Password.Value))
{
throw new ExceptionWithConfigData("You must provide a password with your username for this tracker to login !", ConfigData);
}
else
{
output("Validated Setting -- Password (auth) => " + ConfigData.Password.Value.ToString());
}
// Check Max Page Setting
if (!string.IsNullOrEmpty(ConfigData.Pages.Value))
{
try
{
output("Validated Setting -- Max Pages => " + Convert.ToInt32(ConfigData.Pages.Value));
}
catch (Exception)
{
throw new ExceptionWithConfigData("Please enter a numeric maximum number of pages to crawl !", ConfigData);
}
}
else
{
throw new ExceptionWithConfigData("Please enter a maximum number of pages to crawl !", ConfigData);
}
// Check Latency Setting
if (ConfigData.Latency.Value)
{
output("\nValidated Setting -- Latency Simulation enabled");
// Check Latency Start Setting
if (!string.IsNullOrEmpty(ConfigData.LatencyStart.Value))
{
try
{
output("Validated Setting -- Latency Start => " + Convert.ToInt32(ConfigData.LatencyStart.Value));
}
catch (Exception)
{
throw new ExceptionWithConfigData("Please enter a numeric latency start in ms !", ConfigData);
}
}
else
{
throw new ExceptionWithConfigData("Latency Simulation enabled, Please enter a start latency !", ConfigData);
}
// Check Latency End Setting
if (!string.IsNullOrEmpty(ConfigData.LatencyEnd.Value))
{
try
{
output("Validated Setting -- Latency End => " + Convert.ToInt32(ConfigData.LatencyEnd.Value));
}
catch (Exception)
{
throw new ExceptionWithConfigData("Please enter a numeric latency end in ms !", ConfigData);
}
}
else
{
throw new ExceptionWithConfigData("Latency Simulation enabled, Please enter a end latency !", ConfigData);
}
}
// Check Browser Setting
if (ConfigData.Browser.Value)
{
output("\nValidated Setting -- Browser Simulation enabled");
// Check ACCEPT header Setting
if (string.IsNullOrEmpty(ConfigData.HeaderAccept.Value))
{
throw new ExceptionWithConfigData("Browser Simulation enabled, Please enter an ACCEPT header !", ConfigData);
}
else
{
output("Validated Setting -- ACCEPT (header) => " + ConfigData.HeaderAccept.Value.ToString());
}
// Check ACCEPT-LANG header Setting
if (string.IsNullOrEmpty(ConfigData.HeaderAcceptLang.Value))
{
throw new ExceptionWithConfigData("Browser Simulation enabled, Please enter an ACCEPT-LANG header !", ConfigData);
}
else
{
output("Validated Setting -- ACCEPT-LANG (header) => " + ConfigData.HeaderAcceptLang.Value.ToString());
}
// Check USER-AGENT header Setting
if (string.IsNullOrEmpty(ConfigData.HeaderUserAgent.Value))
{
throw new ExceptionWithConfigData("Browser Simulation enabled, Please enter an USER-AGENT header !", ConfigData);
}
else
{
output("Validated Setting -- USER-AGENT (header) => " + ConfigData.HeaderUserAgent.Value.ToString());
}
}
// Check Dev Cache Settings
if (ConfigData.HardDriveCache.Value == true)
{
output("\nValidated Setting -- DEV Hard Drive Cache enabled");
// Check if Dev Mode enabled !
if (!ConfigData.DevMode.Value)
{
throw new ExceptionWithConfigData("Hard Drive is enabled but not in DEV MODE, Please enable DEV MODE !", ConfigData);
}
// Check Cache Keep Time Setting
if (!string.IsNullOrEmpty(ConfigData.HardDriveCacheKeepTime.Value))
{
try
{
output("Validated Setting -- Cache Keep Time (ms) => " + Convert.ToInt32(ConfigData.HardDriveCacheKeepTime.Value));
}
catch (Exception)
{
throw new ExceptionWithConfigData("Please enter a numeric hard drive keep time in ms !", ConfigData);
}
}
else
{
throw new ExceptionWithConfigData("Hard Drive Cache enabled, Please enter a maximum keep time for cache !", ConfigData);
}
}
else
{
// Delete cache if previously existed
cleanCacheStorage(true);
}
}
}
}

View File

@@ -27,6 +27,7 @@ namespace Jackett.Indexers
private string LoginUrl { get { return SiteLink + "user/login"; } }
private string SearchUrl { get { return SiteLink + "torrents.php?"; } }
public bool AllowRaws { get { return configData.IncludeRaw.Value; } }
public bool InsertSeason { get { return configData.InsertSeason!=null && configData.InsertSeason.Value; } }
new ConfigurationDataAnimeBytes configData
{
@@ -53,6 +54,13 @@ namespace Jackett.Indexers
}
public IEnumerable<ReleaseInfo> FilterResults(TorznabQuery query, IEnumerable<ReleaseInfo> input)
{
// Prevent filtering
return input;
}
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
configData.LoadValuesFromJson(configJson);
@@ -119,12 +127,20 @@ namespace Jackett.Indexers
base.LoadFromSavedConfiguration(jsonConfig);
}
private string StripEpisodeNumber(string term)
{
// Tracer does not support searching with episode number so strip it if we have one
term = Regex.Replace(term, @"\W(\dx)?\d?\d$", string.Empty);
term = Regex.Replace(term, @"\W(S\d\d?E)?\d?\d$", string.Empty);
return term;
}
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
// The result list
var releases = new List<ReleaseInfo>();
foreach (var result in await GetResults(query.SanitizedSearchTerm))
foreach (var result in await GetResults(StripEpisodeNumber(query.SanitizedSearchTerm)))
{
releases.Add(result);
}
@@ -136,14 +152,6 @@ namespace Jackett.Indexers
{
var cleanSearchTerm = HttpUtility.UrlEncode(searchTerm);
// This tracker only deals with full seasons so chop off the episode/season number if we have it D:
if (!string.IsNullOrWhiteSpace(searchTerm))
{
var splitindex = searchTerm.LastIndexOf(' ');
if (splitindex > -1)
searchTerm = searchTerm.Substring(0, splitindex);
}
// The result list
var releases = new List<ReleaseInfo>();
@@ -244,6 +252,12 @@ namespace Jackett.Indexers
releaseInfo = releaseInfo.Replace("Episode ", "");
releaseInfo = releaseInfo.Replace("Season ", "S");
releaseInfo = releaseInfo.Trim();
int test = 0;
if (InsertSeason && int.TryParse(releaseInfo, out test) && releaseInfo.Length==1)
{
releaseInfo = "S01E0" + releaseInfo;
}
}
else if (rowCq.HasClass("torrent"))
{

View File

@@ -1,176 +0,0 @@
using CsQuery;
using Jackett.Models;
using Jackett.Services;
using Jackett.Utils;
using Jackett.Utils.Clients;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using Jackett.Models.IndexerConfig;
using System.Collections.Specialized;
using System.Globalization;
namespace Jackett.Indexers
{
public class AnimeTorrents : BaseIndexer, IIndexer
{
private string LoginUrl { get { return SiteLink + "login.php"; } }
private string SearchUrl { get { return SiteLink + "ajax/torrents_data.php"; } }
private string SearchUrlReferer { get { return SiteLink + "torrents.php?cat=0&searchin=filename&search="; } }
new ConfigurationDataBasicLogin configData
{
get { return (ConfigurationDataBasicLogin)base.configData; }
set { base.configData = value; }
}
public AnimeTorrents(IIndexerManagerService i, HttpWebClient c, Logger l, IProtectionService ps)
: base(name: "AnimeTorrents",
description: "Definitive source for anime and manga",
link: "http://animetorrents.me/",
caps: new TorznabCapabilities(),
manager: i,
client: c, // Forced HTTP client for custom headers
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
{
AddCategoryMapping(1, TorznabCatType.MoviesSD); // Anime Movie
AddCategoryMapping(6, TorznabCatType.MoviesHD); // Anime Movie HD
AddCategoryMapping(2, TorznabCatType.TVAnime); // Anime Series
AddCategoryMapping(7, TorznabCatType.TVAnime); // Anime Series HD
AddCategoryMapping(5, TorznabCatType.XXXDVD); // Hentai (censored)
AddCategoryMapping(9, TorznabCatType.XXXDVD); // Hentai (censored) HD
AddCategoryMapping(4, TorznabCatType.XXXDVD); // Hentai (un-censored)
AddCategoryMapping(8, TorznabCatType.XXXDVD); // Hentai (un-censored) HD
AddCategoryMapping(13, TorznabCatType.BooksForeign); // Light Novel
AddCategoryMapping(3, TorznabCatType.BooksComics); // Manga
AddCategoryMapping(10, TorznabCatType.BooksComics); // Manga 18+
AddCategoryMapping(11, TorznabCatType.TVAnime); // OVA
AddCategoryMapping(12, TorznabCatType.TVAnime); // OVA HD
AddCategoryMapping(14, TorznabCatType.BooksComics); // Doujin Anime
AddCategoryMapping(15, TorznabCatType.XXXDVD); // Doujin Anime 18+
AddCategoryMapping(16, TorznabCatType.AudioForeign); // Doujin Music
AddCategoryMapping(17, TorznabCatType.BooksComics); // Doujinshi
AddCategoryMapping(18, TorznabCatType.BooksComics); // Doujinshi 18+
AddCategoryMapping(19, TorznabCatType.Audio); // OST
}
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
configData.LoadValuesFromJson(configJson);
var pairs = new Dictionary<string, string> {
{ "username", configData.Username.Value },
{ "password", configData.Password.Value },
{ "form", "login" },
{ "rememberme[]", "1" }
};
var loginPage = await RequestStringWithCookiesAndRetry(LoginUrl, null, null);
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, SearchUrl, SiteLink);
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
{
CQ dom = result.Content;
var errorMessage = dom[".ui-state-error"].Text().Trim();
throw new ExceptionWithConfigData(errorMessage, configData);
});
return IndexerConfigurationStatus.RequiresTesting;
}
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>();
var searchString = query.GetQueryString();
var searchUrl = SearchUrl;
var queryCollection = new NameValueCollection();
queryCollection.Add("total", "146"); // Not sure what this is about but its required!
var cat = "0";
var queryCats = MapTorznabCapsToTrackers(query);
if (queryCats.Count == 1)
{
cat = queryCats.First().ToString();
}
queryCollection.Add("cat", cat);
queryCollection.Add("searchin", "filename");
queryCollection.Add("search", searchString);
queryCollection.Add("page", "1");
searchUrl += "?" + queryCollection.GetQueryString();
var extraHeaders = new Dictionary<string, string>()
{
{ "X-Requested-With", "XMLHttpRequest" }
};
var response = await RequestStringWithCookiesAndRetry(searchUrl, null, SearchUrlReferer, extraHeaders);
var results = response.Content;
try
{
CQ dom = results;
var rows = dom["tr"];
foreach (var row in rows.Skip(1))
{
var release = new ReleaseInfo();
var qRow = row.Cq();
var qTitleLink = qRow.Find("td:eq(1) a:eq(0)").First();
release.Title = qTitleLink.Find("strong").Text().Trim();
// If we search an get no results, we still get a table just with no info.
if (string.IsNullOrWhiteSpace(release.Title))
{
break;
}
release.Description = release.Title;
release.Guid = new Uri(qTitleLink.Attr("href"));
release.Comments = release.Guid;
var dateString = qRow.Find("td:eq(4)").Text();
release.PublishDate = DateTime.ParseExact(dateString, "dd MMM yy", CultureInfo.InvariantCulture);
var qLink = qRow.Find("td:eq(2) a");
release.Link = new Uri(qLink.Attr("href"));
var sizeStr = qRow.Find("td:eq(5)").Text();
release.Size = ReleaseInfo.GetBytes(sizeStr);
var connections = qRow.Find("td:eq(7)").Text().Trim().Split("/".ToCharArray(),StringSplitOptions.RemoveEmptyEntries);
release.Seeders = ParseUtil.CoerceInt(connections[0].Trim());
release.Peers = ParseUtil.CoerceInt(connections[1].Trim()) + release.Seeders;
var rCat = row.Cq().Find("td:eq(0) a").First().Attr("href");
var rCatIdx = rCat.IndexOf("cat=");
if (rCatIdx > -1)
{
rCat = rCat.Substring(rCatIdx + 4);
}
release.Category = MapTrackerCatToNewznab(rCat);
releases.Add(release);
}
}
catch (Exception ex)
{
OnParseError(results, ex);
}
return releases;
}
}
}

View File

@@ -1,196 +0,0 @@
using CsQuery;
using Jackett.Models;
using Jackett.Services;
using Jackett.Utils;
using Jackett.Utils.Clients;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using Jackett.Models.IndexerConfig;
namespace Jackett.Indexers
{
public class BakaBT : BaseIndexer, IIndexer
{
public string SearchUrl { get { return SiteLink + "browse.php?only=0&hentai=1&incomplete=1&lossless=1&hd=1&multiaudio=1&bonus=1&c1=1&reorder=1&q="; } }
public string LoginUrl { get { return SiteLink + "login.php"; } }
new ConfigurationDataBasicLogin configData
{
get { return (ConfigurationDataBasicLogin)base.configData; }
set { base.configData = value; }
}
public BakaBT(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
: base(name: "BakaBT",
description: "Anime Community",
link: "http://bakabt.me/",
caps: new TorznabCapabilities(TorznabCatType.TVAnime),
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
{
}
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
configData.LoadValuesFromJson(configJson);
var loginForm = await webclient.GetString(new Utils.Clients.WebRequest()
{
Url = LoginUrl,
Type = RequestType.GET
});
var pairs = new Dictionary<string, string> {
{ "username", configData.Username.Value },
{ "password", configData.Password.Value },
{ "returnto", "/index.php" }
};
var response = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginForm.Cookies, true, null, SiteLink);
var responseContent = response.Content;
await ConfigureIfOK(response.Cookies, responseContent.Contains("<a href=\"logout.php\">Logout</a>"), () =>
{
CQ dom = responseContent;
var messageEl = dom[".error"].First();
var errorMessage = messageEl.Text().Trim();
throw new ExceptionWithConfigData(errorMessage, configData);
});
return IndexerConfigurationStatus.RequiresTesting;
}
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
// This tracker only deals with full seasons so chop off the episode/season number if we have it D:
if (!string.IsNullOrWhiteSpace(query.SearchTerm))
{
var splitindex = query.SearchTerm.LastIndexOf(' ');
if (splitindex > -1)
query.SearchTerm = query.SearchTerm.Substring(0, splitindex);
}
var releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm;
var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode(searchString);
var response = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
try
{
CQ dom = response.Content;
var rows = dom[".torrents tr.torrent"];
foreach (var row in rows)
{
var qRow = row.Cq();
var qTitleLink = qRow.Find("a.title").First();
var title = qTitleLink.Text().Trim();
// Insert before the release info
var taidx = title.IndexOf('(');
var tbidx = title.IndexOf('[');
if (taidx == -1)
taidx = title.Length;
if (tbidx == -1)
tbidx = title.Length;
var titleSplit = Math.Min(taidx, tbidx);
var titleSeries = title.Substring(0, titleSplit);
var releaseInfo = title.Substring(titleSplit);
// For each over each pipe deliminated name
foreach (var name in titleSeries.Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
{
var release = new ReleaseInfo();
release.Title = (name + releaseInfo).Trim();
// Ensure the season is defined as this tracker only deals with full seasons
if (release.Title.IndexOf("Season") == -1)
{
// Insert before the release info
var aidx = release.Title.IndexOf('(');
var bidx = release.Title.IndexOf('[');
if (aidx == -1)
aidx = release.Title.Length;
if (bidx == -1)
bidx = release.Title.Length;
var insertPoint = Math.Min(aidx, bidx);
release.Title = release.Title.Substring(0, insertPoint) + "Season 1 " + release.Title.Substring(insertPoint);
}
release.Description = release.Title;
release.Guid = new Uri(SiteLink + qTitleLink.Attr("href"));
release.Comments = release.Guid;
release.Link = new Uri(SiteLink + qRow.Find(".peers a").First().Attr("href"));
release.Seeders = int.Parse(qRow.Find(".peers a").Get(0).InnerText);
release.Peers = release.Seeders + int.Parse(qRow.Find(".peers a").Get(1).InnerText);
release.MinimumRatio = 1;
var size = qRow.Find(".size").First().Text();
release.Size = ReleaseInfo.GetBytes(size);
//22 Jul 15
var dateStr = qRow.Find(".added").First().Text().Replace("'", string.Empty);
if (dateStr.Split(' ')[0].Length == 1)
dateStr = "0" + dateStr;
if (string.Equals(dateStr, "yesterday", StringComparison.InvariantCultureIgnoreCase))
{
release.PublishDate = DateTime.Now.AddDays(-1);
}
else if (string.Equals(dateStr, "today", StringComparison.InvariantCultureIgnoreCase))
{
release.PublishDate = DateTime.Now;
}
else
{
release.PublishDate = DateTime.ParseExact(dateStr, "dd MMM yy", CultureInfo.InvariantCulture);
}
releases.Add(release);
}
}
}
catch (Exception ex)
{
OnParseError(response.Content, ex);
}
return releases;
}
public override async Task<byte[]> Download(Uri link)
{
var downloadPage = await RequestStringWithCookies(link.ToString());
CQ dom = downloadPage.Content;
var downloadLink = dom.Find(".download_link").First().Attr("href");
if (string.IsNullOrWhiteSpace(downloadLink))
{
throw new Exception("Unable to find download link.");
}
var response = await RequestBytesWithCookies(SiteLink + downloadLink);
return response.Content;
}
}
}

View File

@@ -141,43 +141,75 @@ namespace Jackett.Indexers
protected void CleanCache()
{
foreach (var expired in cache.Where(i => i.Created - DateTime.Now > cacheTime).ToList())
foreach (var expired in cache.Where(i => DateTime.Now - i.Created > cacheTime).ToList())
{
cache.Remove(expired);
}
}
protected async Task FollowIfRedirect(WebClientStringResult response, string referrer = null, string overrideRedirectUrl = null, string overrideCookies = null)
protected async Task FollowIfRedirect(WebClientStringResult response, string referrer = null, string overrideRedirectUrl = null, string overrideCookies = null, bool accumulateCookies = false)
{
var byteResult = new WebClientByteResult();
// Map to byte
Mapper.Map(response, byteResult);
await FollowIfRedirect(byteResult, referrer, overrideRedirectUrl, overrideCookies);
await FollowIfRedirect(byteResult, referrer, overrideRedirectUrl, overrideCookies, accumulateCookies);
// Map to string
Mapper.Map(byteResult, response);
}
protected async Task FollowIfRedirect(WebClientByteResult response, string referrer = null, string overrideRedirectUrl = null, string overrideCookies = null)
protected async Task FollowIfRedirect(WebClientByteResult response, string referrer = null, string overrideRedirectUrl = null, string overrideCookies = null, bool accumulateCookies = false)
{
// Follow up to 5 redirects
for (int i = 0; i < 5; i++)
{
if (!response.IsRedirect)
break;
await DoFollowIfRedirect(response, referrer, overrideRedirectUrl, overrideCookies);
await DoFollowIfRedirect(response, referrer, overrideRedirectUrl, overrideCookies, accumulateCookies);
if (accumulateCookies)
{
CookieHeader = ResolveCookies((CookieHeader != null && CookieHeader != ""? CookieHeader + " " : "") + (overrideCookies != null && overrideCookies != "" ? overrideCookies + " " : "") + response.Cookies);
overrideCookies = response.Cookies = CookieHeader;
}
if (overrideCookies != null && response.Cookies == null)
{
response.Cookies = overrideCookies;
}
}
}
private async Task DoFollowIfRedirect(WebClientByteResult incomingResponse, string referrer = null, string overrideRedirectUrl = null, string overrideCookies = null)
private String ResolveCookies(String incomingCookies = "")
{
var redirRequestCookies = (CookieHeader != "" ? CookieHeader + " " : "") + incomingCookies;
System.Text.RegularExpressions.Regex expression = new System.Text.RegularExpressions.Regex(@"([^\s]+)=([^=]+)(?:\s|$)");
Dictionary<string, string> cookieDIctionary = new Dictionary<string, string>();
var matches = expression.Match(redirRequestCookies);
while (matches.Success)
{
if (matches.Groups.Count > 2) cookieDIctionary[matches.Groups[1].Value] = matches.Groups[2].Value;
matches = matches.NextMatch();
}
return string.Join(" ", cookieDIctionary.Select(kv => kv.Key.ToString() + "=" + kv.Value.ToString()).ToArray());
}
private async Task DoFollowIfRedirect(WebClientByteResult incomingResponse, string referrer = null, string overrideRedirectUrl = null, string overrideCookies = null, bool accumulateCookies = false)
{
if (incomingResponse.IsRedirect)
{
var redirRequestCookies = "";
if (accumulateCookies)
{
redirRequestCookies = ResolveCookies((CookieHeader != "" ? CookieHeader + " " : "") + (overrideCookies != null ? overrideCookies : ""));
} else
{
redirRequestCookies = (overrideCookies != null ? overrideCookies : "");
}
// Do redirect
var redirectedResponse = await webclient.GetBytes(new WebRequest()
{
Url = overrideRedirectUrl ?? incomingResponse.RedirectingTo,
Referer = referrer,
Cookies = overrideCookies ?? CookieHeader
Cookies = redirRequestCookies
});
Mapper.Map(redirectedResponse, incomingResponse);
}
@@ -233,7 +265,7 @@ namespace Jackett.Indexers
public async virtual Task<byte[]> Download(Uri link)
{
var response = await RequestBytesWithCookiesAndRetry(link.ToString());
if(response.Status != System.Net.HttpStatusCode.OK && response.Status != System.Net.HttpStatusCode.Continue && response.Status != System.Net.HttpStatusCode.PartialContent)
if (response.Status != System.Net.HttpStatusCode.OK && response.Status != System.Net.HttpStatusCode.Continue && response.Status != System.Net.HttpStatusCode.PartialContent)
{
throw new Exception($"Remote server returned {response.Status.ToString()}");
}
@@ -269,7 +301,7 @@ namespace Jackett.Indexers
Type = RequestType.GET,
Cookies = CookieHeader,
Referer = referer,
Headers = headers
Headers = headers
};
if (cookieOverride != null)
@@ -277,7 +309,7 @@ namespace Jackett.Indexers
return await webclient.GetString(request);
}
protected async Task<WebClientStringResult> RequestStringWithCookiesAndRetry(string url, string cookieOverride = null, string referer = null, Dictionary<string,string> headers = null)
protected async Task<WebClientStringResult> RequestStringWithCookiesAndRetry(string url, string cookieOverride = null, string referer = null, Dictionary<string, string> headers = null)
{
Exception lastException = null;
for (int i = 0; i < 3; i++)
@@ -349,7 +381,7 @@ namespace Jackett.Indexers
throw lastException;
}
protected async Task<WebClientStringResult> RequestLoginAndFollowRedirect(string url, IEnumerable<KeyValuePair<string, string>> data, string cookies, bool returnCookiesFromFirstCall, string redirectUrlOverride = null, string referer = null)
protected async Task<WebClientStringResult> RequestLoginAndFollowRedirect(string url, IEnumerable<KeyValuePair<string, string>> data, string cookies, bool returnCookiesFromFirstCall, string redirectUrlOverride = null, string referer = null, bool accumulateCookies = false)
{
var request = new Utils.Clients.WebRequest()
{
@@ -360,18 +392,22 @@ namespace Jackett.Indexers
PostData = data
};
var response = await webclient.GetString(request);
if (accumulateCookies)
{
response.Cookies = ResolveCookies((request.Cookies == null ? "" : request.Cookies + " ") + response.Cookies);
}
var firstCallCookies = response.Cookies;
if (response.IsRedirect)
{
await FollowIfRedirect(response, request.Url, redirectUrlOverride, response.Cookies);
await FollowIfRedirect(response, request.Url, redirectUrlOverride, response.Cookies, accumulateCookies);
}
if (returnCookiesFromFirstCall)
{
response.Cookies = firstCallCookies;
response.Cookies = ResolveCookies(firstCallCookies + (accumulateCookies ? " " + response.Cookies : ""));
}
return response;
}

View File

@@ -8,24 +8,22 @@ using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using Jackett.Models.IndexerConfig;
using System.Collections.Specialized;
using System.Text.RegularExpressions;
namespace Jackett.Indexers
{
public class BeyondHD : BaseIndexer, IIndexer
{
private string SearchUrl { get { return SiteLink + "browse.php?searchin=title&incldead=0&"; } }
private string DownloadUrl { get { return SiteLink + "download.php?torrent={0}"; } }
private string LoginUrl { get { return SiteLink + "login.php?returnto=%2F"; } }
private string AjaxLoginUrl { get { return SiteLink + "ajax/takelogin.php"; } }
new ConfigurationDataCookie configData
new ConfigurationDataRecaptchaLogin configData
{
get { return (ConfigurationDataCookie)base.configData; }
get { return (ConfigurationDataRecaptchaLogin)base.configData; }
set { base.configData = value; }
}
@@ -38,7 +36,7 @@ namespace Jackett.Indexers
client: w,
logger: l,
p: ps,
configData: new ConfigurationDataCookie())
configData: new ConfigurationDataRecaptchaLogin())
{
AddCategoryMapping(37, TorznabCatType.MoviesBluRay); // Movie / Blu-ray
AddMultiCategoryMapping(TorznabCatType.Movies3D,
@@ -78,20 +76,55 @@ namespace Jackett.Indexers
}
public override async Task<ConfigurationData> GetConfigurationForSetup()
{
var loginPage = await RequestStringWithCookies(LoginUrl, string.Empty);
string recaptchaSiteKey = new Regex(@"loginwidget', \{[\s]{4,30}'sitekey' : '([0-9A-Za-z]{5,60})',[\s]{4,30}'theme'").Match(loginPage.Content).Groups[1].ToString().Trim();
var result = new ConfigurationDataRecaptchaLogin();
result.CookieHeader.Value = loginPage.Cookies;
result.Captcha.SiteKey = recaptchaSiteKey;
return result;
}
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
configData.LoadValuesFromJson(configJson);
var pairs = new Dictionary<string, string> {
{ "username", configData.Username.Value },
{ "password", configData.Password.Value },
{ "g-recaptcha-response", configData.Captcha.Value }
};
var response = await webclient.GetString(new Utils.Clients.WebRequest()
if (!string.IsNullOrWhiteSpace(configData.Captcha.Cookie))
{
Url = SiteLink,
Cookies = configData.Cookie.Value
});
// Cookie was manually supplied
CookieHeader = configData.Captcha.Cookie;
try
{
var results = await PerformQuery(new TorznabQuery());
if (!results.Any())
{
throw new Exception("Your cookie did not work");
}
await ConfigureIfOK(configData.Cookie.Value, response.Content.Contains("logout.php"), () =>
SaveConfig();
IsConfigured = true;
return IndexerConfigurationStatus.Completed;
}
catch (Exception e)
{
IsConfigured = false;
throw new Exception("Your cookie did not work: " + e.Message);
}
}
var result = await RequestLoginAndFollowRedirect(AjaxLoginUrl, pairs, configData.CookieHeader.Value, true, SiteLink, LoginUrl);
JToken token = JObject.Parse(result.Content);
bool success = token.Value<bool?>("success") ?? false;
await ConfigureIfOK(result.Cookies, success, () =>
{
CQ dom = response.Content;
throw new ExceptionWithConfigData("Invalid cookie header", configData);
var errorMessage = result.Content;
throw new ExceptionWithConfigData(errorMessage, configData);
});
return IndexerConfigurationStatus.RequiresTesting;
}
@@ -135,7 +168,7 @@ namespace Jackett.Indexers
var qLink = row.ChildElements.ElementAt(2).FirstChild.Cq();
release.Link = new Uri(SiteLink + "/" + qLink.Attr("href"));
var torrentID = qLink.Attr("href").Split('=').Last();
var torrentId = qLink.Attr("href").Split('=').Last();
var descCol = row.ChildElements.ElementAt(3);
var qCommentLink = descCol.FirstChild.Cq();
@@ -143,6 +176,7 @@ namespace Jackett.Indexers
release.Description = release.Title;
release.Comments = new Uri(SiteLink + "/" + qCommentLink.Attr("href"));
release.Guid = release.Comments;
release.Link = new Uri($"{SiteLink}download.php?torrent={torrentId}");
var dateStr = descCol.ChildElements.Last().Cq().Text().Split('|').Last().ToLowerInvariant().Replace("ago.", "").Trim();
release.PublishDate = DateTimeUtil.FromTimeAgo(dateStr);

View File

@@ -0,0 +1,264 @@
using CsQuery;
using Jackett.Models;
using Jackett.Services;
using Jackett.Utils;
using Jackett.Utils.Clients;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using Jackett.Models.IndexerConfig;
using System.Collections.Specialized;
using System.Text.RegularExpressions;
namespace Jackett.Indexers
{
public class BitSoup : BaseIndexer, IIndexer
{
private string UseLink { get { return (this.configData.AlternateLink.Value != null && this.configData.AlternateLink.Value != "" ? this.configData.AlternateLink.Value : SiteLink); } }
private string BrowseUrl { get { return UseLink + "browse.php"; } }
private string LoginUrl { get { return UseLink + "takelogin.php"; } }
private string LoginReferer { get { return UseLink + "login.php"; } }
private List<String> KnownURLs = new List<String>{ "https://www.bitsoup.me/","https://www.bitsoup.org/"};
new NxtGnConfigurationData configData
{
get { return (NxtGnConfigurationData)base.configData; }
set { base.configData = value; }
}
public BitSoup(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
: base(name: "BitSoup",
description: "SoupieBits",
link: "https://www.bitsoup.me/",
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
manager: i,
client: wc,
logger: l,
p: ps,
configData: new NxtGnConfigurationData())
{
this.configData.DisplayText.Value = this.DisplayName + " has multiple URLs. The default (" + this.SiteLink + ") can be changed by entering a new value in the box below.";
this.configData.DisplayText.Value += "The following are some known URLs for " + this.DisplayName;
this.configData.DisplayText.Value += "<ul><li>" + String.Join("</li><li>", this.KnownURLs.ToArray()) + "</li></ul>";
//AddCategoryMapping("624", TorznabCatType.Console);
//AddCategoryMapping("307", TorznabCatType.ConsoleNDS);
//AddCategoryMapping("308", TorznabCatType.ConsolePSP);
AddCategoryMapping("35", TorznabCatType.ConsoleWii);
//AddCategoryMapping("309", TorznabCatType.ConsoleXbox);
AddCategoryMapping("12", TorznabCatType.ConsoleXbox360);
//AddCategoryMapping("305", TorznabCatType.ConsoleWiiwareVC);
//AddCategoryMapping("309", TorznabCatType.ConsoleXBOX360DLC);
AddCategoryMapping("38", TorznabCatType.ConsolePS3);
//AddCategoryMapping("239", TorznabCatType.ConsoleOther);
//AddCategoryMapping("245", TorznabCatType.ConsoleOther);
//AddCategoryMapping("246", TorznabCatType.ConsoleOther);
//AddCategoryMapping("626", TorznabCatType.ConsoleOther);
//AddCategoryMapping("628", TorznabCatType.ConsoleOther);
//AddCategoryMapping("630", TorznabCatType.ConsoleOther);
//AddCategoryMapping("307", TorznabCatType.Console3DS);
//AddCategoryMapping("308", TorznabCatType.ConsolePSVita);
//AddCategoryMapping("307", TorznabCatType.ConsoleWiiU);
//AddCategoryMapping("309", TorznabCatType.ConsoleXboxOne);
//AddCategoryMapping("308", TorznabCatType.ConsolePS4);
//AddCategoryMapping("631", TorznabCatType.Movies);
//AddCategoryMapping("631", TorznabCatType.MoviesForeign);
//AddCategoryMapping("455", TorznabCatType.MoviesOther);
//AddCategoryMapping("633", TorznabCatType.MoviesOther);
AddCategoryMapping("19", TorznabCatType.MoviesSD);
AddCategoryMapping("41", TorznabCatType.MoviesHD);
AddCategoryMapping("17", TorznabCatType.Movies3D);
AddCategoryMapping("80", TorznabCatType.MoviesBluRay);
AddCategoryMapping("20", TorznabCatType.MoviesDVD);
//AddCategoryMapping("631", TorznabCatType.MoviesWEBDL);
AddCategoryMapping("6", TorznabCatType.Audio);
//AddCategoryMapping("623", TorznabCatType.AudioMP3);
AddCategoryMapping("29", TorznabCatType.AudioVideo);
//AddCategoryMapping("402", TorznabCatType.AudioVideo);
AddCategoryMapping("5", TorznabCatType.AudioAudiobook);
//AddCategoryMapping("1", TorznabCatType.AudioLossless);
//AddCategoryMapping("403", TorznabCatType.AudioOther);
//AddCategoryMapping("642", TorznabCatType.AudioOther);
//AddCategoryMapping("1", TorznabCatType.AudioForeign);
//AddCategoryMapping("233", TorznabCatType.PC);
//AddCategoryMapping("236", TorznabCatType.PC);
//AddCategoryMapping("1", TorznabCatType.PC0day);
AddCategoryMapping("1", TorznabCatType.PCISO);
//AddCategoryMapping("235", TorznabCatType.PCMac);
//AddCategoryMapping("627", TorznabCatType.PCPhoneOther);
AddCategoryMapping("21", TorznabCatType.PCGames);
AddCategoryMapping("4", TorznabCatType.PCGames);
//AddCategoryMapping("625", TorznabCatType.PCPhoneIOS);
//AddCategoryMapping("625", TorznabCatType.PCPhoneAndroid);
AddCategoryMapping("45", TorznabCatType.TV);
//AddCategoryMapping("433", TorznabCatType.TV);
//AddCategoryMapping("639", TorznabCatType.TVWEBDL);
//AddCategoryMapping("433", TorznabCatType.TVWEBDL);
//AddCategoryMapping("639", TorznabCatType.TVFOREIGN);
//AddCategoryMapping("433", TorznabCatType.TVFOREIGN);
AddCategoryMapping("7", TorznabCatType.TVSD);
AddCategoryMapping("49", TorznabCatType.TVSD);
AddCategoryMapping("42", TorznabCatType.TVHD);
//AddCategoryMapping("433", TorznabCatType.TVHD);
//AddCategoryMapping("635", TorznabCatType.TVOTHER);
//AddCategoryMapping("636", TorznabCatType.TVSport);
AddCategoryMapping("23", TorznabCatType.TVAnime);
//AddCategoryMapping("634", TorznabCatType.TVDocumentary);
AddCategoryMapping("9", TorznabCatType.XXX);
//AddCategoryMapping("1", TorznabCatType.XXXDVD);
//AddCategoryMapping("1", TorznabCatType.XXXWMV);
//AddCategoryMapping("1", TorznabCatType.XXXXviD);
//AddCategoryMapping("1", TorznabCatType.XXXx264);
//AddCategoryMapping("1", TorznabCatType.XXXOther);
//AddCategoryMapping("1", TorznabCatType.XXXImageset);
//AddCategoryMapping("1", TorznabCatType.XXXPacks);
//AddCategoryMapping("340", TorznabCatType.Other);
//AddCategoryMapping("342", TorznabCatType.Other);
//AddCategoryMapping("344", TorznabCatType.Other);
//AddCategoryMapping("391", TorznabCatType.Other);
//AddCategoryMapping("392", TorznabCatType.Other);
//AddCategoryMapping("393", TorznabCatType.Other);
//AddCategoryMapping("394", TorznabCatType.Other);
//AddCategoryMapping("234", TorznabCatType.Other);
//AddCategoryMapping("638", TorznabCatType.Other);
//AddCategoryMapping("629", TorznabCatType.Other);
//AddCategoryMapping("1", TorznabCatType.OtherMisc);
//AddCategoryMapping("1", TorznabCatType.OtherHashed);
//AddCategoryMapping("408", TorznabCatType.Books);
AddCategoryMapping("24", TorznabCatType.BooksEbook);
//AddCategoryMapping("406", TorznabCatType.BooksComics);
//AddCategoryMapping("407", TorznabCatType.BooksComics);
//AddCategoryMapping("409", TorznabCatType.BooksComics);
//AddCategoryMapping("410", TorznabCatType.BooksMagazines);
//AddCategoryMapping("1", TorznabCatType.BooksTechnical);
//AddCategoryMapping("1", TorznabCatType.BooksOther);
//AddCategoryMapping("1", TorznabCatType.BooksForeign);
}
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
configData.LoadValuesFromJson(configJson);
if (configData.AlternateLink.Value != null && configData.AlternateLink.Value != "")
{
if (!configData.AlternateLink.Value.EndsWith("/"))
{
configData.AlternateLink.Value = null;
throw new Exception("AlternateLink must end with a slash.");
}
var match = Regex.Match(configData.AlternateLink.Value, "^https?:\\/\\/(?:[\\w]+\\.)+(?:[a-zA-Z]+)\\/$");
if (!match.Success)
{
configData.AlternateLink.Value = null;
throw new Exception("AlternateLink must be a valid url.");
}
}
var pairs = new Dictionary<string, string> {
{ "username", configData.Username.Value },
{ "password", configData.Password.Value },
};
var loginPage = await RequestStringWithCookies(UseLink, string.Empty);
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, null, LoginReferer, true);
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
{
CQ dom = result.Content;
var messageEl = dom["body > table.statusbar1 > tbody > tr > td > table > tbody > tr > td > table > tbody > tr > td"].First();
var errorMessage = messageEl.Text().Trim();
throw new ExceptionWithConfigData(errorMessage, configData);
});
return IndexerConfigurationStatus.RequiresTesting;
}
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>();
var searchString = query.GetQueryString();
var searchUrl = BrowseUrl;
var trackerCats = MapTorznabCapsToTrackers(query);
var queryCollection = new NameValueCollection();
queryCollection.Add("search", string.IsNullOrWhiteSpace(searchString)? "" : searchString);
if (trackerCats.Count > 1)
{
for (var ct = 0; ct < trackerCats.Count; ct++) queryCollection.Add("cat" + (ct+1), trackerCats.ElementAt(ct));
} else
{
queryCollection.Add("cat", (trackerCats.Count == 1 ? trackerCats.ElementAt(0) : "0"));
}
//queryCollection.Add("cat", (trackerCats.Count == 1 ? trackerCats.ElementAt(0) : "0"));
searchUrl += "?" + queryCollection.GetQueryString();
await ProcessPage(releases, searchUrl);
return releases;
}
private async Task ProcessPage(List<ReleaseInfo> releases, string searchUrl)
{
var response = await RequestStringWithCookiesAndRetry(searchUrl, null, BrowseUrl);
var results = response.Content;
try
{
CQ dom = results;
var rows = dom["table.koptekst tr"];
foreach (var row in rows.Skip(1))
{
var release = new ReleaseInfo();
release.Title = row.Cq().Find("td:eq(1) a").First().Text().Trim();
release.Comments = new Uri(UseLink + row.Cq().Find("td:eq(1) a").First().Attr("href"));
release.Link = new Uri(UseLink + row.Cq().Find("td:eq(2) a").First().Attr("href"));
release.Guid = release.Link;
release.Description = release.Title;
var cat = row.Cq().Find("td:eq(0) a").First().Attr("href").Substring(15);
release.Category = MapTrackerCatToNewznab(cat);
var added = row.Cq().Find("td:eq(7)").First().Text().Trim();
release.PublishDate = DateTime.ParseExact(added, "yyyy-MM-ddH:mm:ss", CultureInfo.InvariantCulture);
var sizeStr = row.Cq().Find("td:eq(8)").First().Text().Trim();
release.Size = ReleaseInfo.GetBytes(sizeStr);
release.Seeders = ParseUtil.CoerceInt(row.Cq().Find("td:eq(10)").First().Text().Trim());
release.Peers = ParseUtil.CoerceInt(row.Cq().Find("td:eq(11)").First().Text().Trim()) + release.Seeders;
releases.Add(release);
}
}
catch (Exception ex)
{
OnParseError(results, ex);
}
}
public class NxtGnConfigurationData : ConfigurationData
{
public StringItem Username { get; private set; }
public StringItem Password { get; private set; }
public DisplayItem DisplayText { get; private set; }
public StringItem AlternateLink { get; set; }
public NxtGnConfigurationData()
{
Username = new StringItem { Name = "Username" };
Password = new StringItem { Name = "Password" };
DisplayText = new DisplayItem("") { Name = "" };
AlternateLink = new StringItem { Name = "AlternateLinks" };
}
}
}
}

View File

@@ -0,0 +1,257 @@
using CsQuery;
using Jackett.Models;
using Jackett.Services;
using Jackett.Utils;
using Jackett.Utils.Clients;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Jackett.Models.IndexerConfig.Bespoke;
namespace Jackett.Indexers
{
public class BlueTigers : BaseIndexer, IIndexer
{
private string LoginUrl => SiteLink + "account-login.php";
private string TorrentSearchUrl => SiteLink + "torrents-search.php";
private string IndexUrl => SiteLink + "index.php";
private ConfigurationDataBlueTigers ConfigData
{
get { return (ConfigurationDataBlueTigers)configData; }
set { base.configData = value; }
}
public BlueTigers(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
: base(name: "BlueTigers",
description: "BlueTigers - No Ratio - Private",
link: "https://www.bluetigers.ca/",
caps: new TorznabCapabilities(),
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataBlueTigers(@"BlueTigers can search for one or all languages.
If you select 2 languages below, results will contain all 3 languages.
<br> For best results change the torrents per page setting to 50 in your BlueTigers profile."))
{
AddCategoryMapping("14", TorznabCatType.ConsolePSP);
AddCategoryMapping("150", TorznabCatType.ConsoleWii);
AddCategoryMapping("150", TorznabCatType.ConsoleWiiwareVC);
AddCategoryMapping("150", TorznabCatType.ConsoleWiiU);
AddCategoryMapping("52", TorznabCatType.ConsoleXbox);
AddCategoryMapping("52", TorznabCatType.ConsoleXbox360);
AddCategoryMapping("52", TorznabCatType.ConsoleXBOX360DLC);
AddCategoryMapping("52", TorznabCatType.ConsoleXboxOne);
AddCategoryMapping("11", TorznabCatType.PCGames);
AddCategoryMapping("13", TorznabCatType.ConsolePS4);
AddCategoryMapping("13", TorznabCatType.ConsolePS3);
AddCategoryMapping("13", TorznabCatType.ConsolePSVita);
AddCategoryMapping("12", TorznabCatType.Console3DS);
AddCategoryMapping("160", TorznabCatType.PCPhoneIOS);
AddCategoryMapping("160", TorznabCatType.PCPhoneAndroid);
AddCategoryMapping("1", TorznabCatType.PCPhoneAndroid);
AddCategoryMapping("29", TorznabCatType.PCMac);
AddCategoryMapping("27", TorznabCatType.PC);
AddCategoryMapping("41", TorznabCatType.PC);
AddCategoryMapping("50", TorznabCatType.PC);
AddCategoryMapping("333", TorznabCatType.BooksMagazines);
AddCategoryMapping("38", TorznabCatType.TVDocumentary);
AddCategoryMapping("37", TorznabCatType.BooksEbook);
AddCategoryMapping("61", TorznabCatType.Movies3D);
AddCategoryMapping("45", TorznabCatType.XXX);
AddCategoryMapping("59", TorznabCatType.MoviesHD);
AddCategoryMapping("222", TorznabCatType.MoviesHD);
AddCategoryMapping("22", TorznabCatType.MoviesHD);
AddCategoryMapping("60", TorznabCatType.MoviesHD);
AddCategoryMapping("56", TorznabCatType.MoviesBluRay);
AddCategoryMapping("23", TorznabCatType.MoviesOther);
AddCategoryMapping("15", TorznabCatType.MoviesOther);
AddCategoryMapping("43", TorznabCatType.MoviesDVD);
AddCategoryMapping("24", TorznabCatType.MoviesDVD);
AddCategoryMapping("25", TorznabCatType.MoviesOther);
AddCategoryMapping("21", TorznabCatType.MoviesOther);
AddCategoryMapping("20", TorznabCatType.MoviesDVD);
AddCategoryMapping("9", TorznabCatType.TVAnime);
AddCategoryMapping("34", TorznabCatType.Other);
AddCategoryMapping("35", TorznabCatType.Audio);
AddCategoryMapping("36", TorznabCatType.AudioVideo);
AddCategoryMapping("31", TorznabCatType.AudioVideo);
AddCategoryMapping("2", TorznabCatType.TVOTHER);
AddCategoryMapping("16", TorznabCatType.TVHD);
AddCategoryMapping("130", TorznabCatType.TVHD);
AddCategoryMapping("10", TorznabCatType.TVSD);
AddCategoryMapping("131", TorznabCatType.TV);
AddCategoryMapping("17", TorznabCatType.TV);
AddCategoryMapping("18", TorznabCatType.TV);
AddCategoryMapping("19", TorznabCatType.TV);
AddCategoryMapping("58", TorznabCatType.TVSport);
AddCategoryMapping("33", TorznabCatType.TVOTHER);
AddCategoryMapping("34", TorznabCatType.Other);
}
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
ConfigData.LoadValuesFromJson(configJson);
if (ConfigData.French.Value == false && ConfigData.English.Value == false && ConfigData.Spanish.Value == false)
throw new ExceptionWithConfigData("Please select at least one language.", ConfigData);
await RequestStringWithCookies(LoginUrl, string.Empty);
var pairs = new Dictionary<string, string> {
{ "username", ConfigData.Username.Value },
{ "password", ConfigData.Password.Value },
{ "take_login", "1" }
};
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, IndexUrl, SiteLink);
Regex rgx = new Regex(@"uid=[0-9]{1,10}; pass=[a-z0-9]{1,40};");
await ConfigureIfOK(result.Cookies, rgx.IsMatch(result.Cookies), () =>
{
var errorMessage = "Error while trying to login.";
throw new ExceptionWithConfigData(errorMessage, ConfigData);
});
return IndexerConfigurationStatus.RequiresTesting;
}
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
List<ReleaseInfo> releases = new List<ReleaseInfo>();
NameValueCollection qParams = new NameValueCollection();
if (ConfigData.French.Value && !ConfigData.English.Value && !ConfigData.Spanish.Value)
{
qParams.Add("lang", "1");
}
else
{
if (!ConfigData.French.Value && ConfigData.English.Value && !ConfigData.Spanish.Value)
{
qParams.Add("lang", "2");
}
else
{
if (!ConfigData.French.Value && !ConfigData.English.Value && ConfigData.Spanish.Value)
{
qParams.Add("lang", "3");
}
else
{
qParams.Add("lang", "0");
}
}
}
List<string> catList = MapTorznabCapsToTrackers(query);
foreach (string cat in catList)
{
qParams.Add("c" + cat, "1");
}
if (!string.IsNullOrEmpty(query.SanitizedSearchTerm))
{
qParams.Add("search", query.GetQueryString());
}
string queryStr = qParams.GetQueryString();
string searchUrl = $"{TorrentSearchUrl}?incldead=0&freeleech=0&sort=id&order=ascdesc&{queryStr}";
List<CQ> torrentRowList = new List<CQ>();
var results = await RequestStringWithCookiesAndRetry(searchUrl);
try
{
CQ fDom = results.Content;
var firstPageRows = fDom["table[class='ttable_headinner'] > tbody > tr:not(:First-child)"];
torrentRowList.AddRange(firstPageRows.Select(fRow => fRow.Cq()));
//If a search term is used, follow upto the first 4 pages (initial plus 3 more)
if (!string.IsNullOrWhiteSpace(query.GetQueryString()) && fDom["a[class='boutons']"].Filter("a[href*=&page=]").Length > 0)
{
int pageLinkCount;
int.TryParse(fDom["a[class='boutons']"].Filter("a[href*=&page=]").Last().Attr("href").Split(new[] { "&page=" }, StringSplitOptions.None).LastOrDefault(), out pageLinkCount);
for (int i = 1; i < Math.Min(4, pageLinkCount + 1); i++)
{
var sResults = await RequestStringWithCookiesAndRetry($"{searchUrl}&page={i}");
CQ sDom = sResults.Content;
var additionalPageRows = sDom["table[class='ttable_headinner'] > tbody > tr:not(:First-child)"];
torrentRowList.AddRange(additionalPageRows.Select(sRow => sRow.Cq()));
}
}
foreach (CQ tRow in torrentRowList)
{
long torrentId = 0;
string idTarget = "bookmarks.php?torrent=";
string id = tRow.Find("a[href*=" + idTarget + "]").First().Attr("href").Trim();
if (!string.IsNullOrEmpty(id) && id.Contains(idTarget))
{
long.TryParse(id.Substring(id.LastIndexOf(idTarget, StringComparison.Ordinal) + idTarget.Length), out torrentId);
}
if (torrentId <= 0) continue;
long category = 0;
string catTarget = "torrents.php?cat=";
string cat = tRow.Find("a[href*=" + catTarget + "]").First().Attr("href").Trim();
if (!string.IsNullOrEmpty(cat) && cat.Contains(catTarget))
{
long.TryParse(cat.Substring(cat.LastIndexOf(catTarget, StringComparison.Ordinal) + catTarget.Length), out category);
}
Uri guid = new Uri($"{SiteLink}torrents-details.php?hit=1&id={torrentId}");
Uri link = new Uri($"{SiteLink}download.php?hit=1&id={torrentId}");
Uri comments = new Uri($"{SiteLink}comments.php?type=torrent&id={torrentId}");
string title = tRow.Find("a[href*=torrents-details.php?id=]").First().Text().Trim();
string stats = tRow.Find("div[id=kt" + torrentId.ToString() + "]").First().Text();
string sizeStr = new Regex("Taille:(.*)Vitesse:").Match(stats).Groups[1].ToString().Trim();
string pubDateStr = new Regex("Ajout.:(.*)Compl.t.s").Match(stats).Groups[1].ToString().Trim();
DateTime pubDate = DateTime.ParseExact(pubDateStr, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToLocalTime();
string statistics = tRow.Find("a[href*=torrents-details.php?id=]").First().RenderSelection().Trim();
string startTag = "<table ";
string endTag = "</table>";
CQ statsCq = startTag + new Regex(startTag + "(.*)" + endTag).Match(statistics).Groups[1].ToString().Trim() + endTag;
int seeders;
int leechers;
int.TryParse(statsCq.Find("font[color=#05FC09]").First().Text(), out seeders);
int.TryParse(statsCq.Find("font[color=red]").First().Text(), out leechers);
var release = new ReleaseInfo();
release.Title = title;
release.Guid = guid;
release.Link = link;
release.PublishDate = pubDate;
release.Size = ReleaseInfo.GetBytes(sizeStr);
release.Description = title;
release.Seeders = seeders;
release.Peers = leechers + seeders;
release.MinimumRatio = 1;
release.MinimumSeedTime = 172800;
release.Category = MapTrackerCatToNewznab(category.ToString());
release.Comments = comments;
releases.Add(release);
}
}
catch (Exception ex)
{
OnParseError(results.Content, ex);
}
return releases;
}
}
}

View File

@@ -19,7 +19,7 @@ namespace Jackett.Indexers
public class Demonoid : BaseIndexer, IIndexer
{
private string LoginUrl { get { return SiteLink + "account_handler.php"; } }
private string SearchUrl { get { return SiteLink + "files/?category=3&subcategory=All&quality=All&seeded=0&to=1&query={0}"; } }
private string SearchUrl { get { return SiteLink + "files/?category={0}&subcategory=All&quality=All&seeded=0&to=1&query={1}"; } }
new ConfigurationDataBasicLogin configData
{
@@ -38,6 +38,10 @@ namespace Jackett.Indexers
p: ps,
configData: new ConfigurationDataBasicLogin())
{
AddCategoryMapping(3, TorznabCatType.TV);
AddCategoryMapping(3, TorznabCatType.TVSD);
AddCategoryMapping(3, TorznabCatType.TVHD);
AddCategoryMapping(1, TorznabCatType.Movies);
}
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
@@ -64,9 +68,12 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>();
var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(query.GetQueryString()));
var trackerCats = MapTorznabCapsToTrackers(query);
var cat = (trackerCats.Count == 1 ? trackerCats.ElementAt(0) : "0");
var episodeSearchUrl = string.Format(SearchUrl, cat, HttpUtility.UrlEncode(query.GetQueryString()));
var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
if (results.Content.Contains("No torrents found"))
{
return releases;

View File

@@ -0,0 +1,966 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using CsQuery;
using Jackett.Models;
using Jackett.Models.IndexerConfig.Bespoke;
using Jackett.Services;
using Jackett.Utils;
using Jackett.Utils.Clients;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;
namespace Jackett.Indexers
{
/// <summary>
/// Provider for French-ADN Private Tracker
/// </summary>
public class FrenchADN : BaseIndexer, IIndexer
{
private string LoginUrl { get { return SiteLink + "login.php?"; } }
private string LoginCheckUrl { get { return SiteLink + "takelogin.php"; } }
private string SearchUrl { get { return SiteLink + "browse.php"; } }
private string TorrentCommentUrl { get { return SiteLink + "details.php?id={id}#comments"; } }
private string TorrentDescriptionUrl { get { return SiteLink + "details.php?id={id}"; } }
private string TorrentDownloadUrl { get { return SiteLink + "download.php?id={id}"; } }
private string TorrentThanksUrl { get { return SiteLink + "takethanks.php"; } }
private bool Latency { get { return ConfigData.Latency.Value; } }
private bool DevMode { get { return ConfigData.DevMode.Value; } }
private bool CacheMode { get { return ConfigData.HardDriveCache.Value; } }
private string directory { get { return System.IO.Path.GetTempPath() + "Jackett\\" + MethodBase.GetCurrentMethod().DeclaringType.Name + "\\"; } }
private Dictionary<string, string> emulatedBrowserHeaders = new Dictionary<string, string>();
private CQ fDom = null;
private ConfigurationDataFrenchADN ConfigData
{
get { return (ConfigurationDataFrenchADN)configData; }
set { base.configData = value; }
}
public FrenchADN(IIndexerManagerService i, IWebClient w, Logger l, IProtectionService ps)
: base(
name: "French-ADN",
description: "Your French Family Provider",
link: "https://french-adn.com/",
caps: new TorznabCapabilities(),
manager: i,
client: w,
logger: l,
p: ps,
downloadBase: "https://french-adn.com/download.php?id=",
configData: new ConfigurationDataFrenchADN())
{
// Clean capabilities
TorznabCaps.Categories.Clear();
// Movies
AddCategoryMapping("15", TorznabCatType.Movies); // ALL
AddCategoryMapping("108", TorznabCatType.MoviesSD); // TS CAM
AddCategoryMapping("25", TorznabCatType.MoviesSD); // BDRIP
AddCategoryMapping("56", TorznabCatType.MoviesSD); // BRRIP
AddCategoryMapping("16", TorznabCatType.MoviesSD); // DVDRIP
AddCategoryMapping("49", TorznabCatType.MoviesDVD); // TVRIP
AddCategoryMapping("102", TorznabCatType.MoviesWEBDL); // WEBRIP
AddCategoryMapping("105", TorznabCatType.MoviesHD); // 1080P
AddCategoryMapping("104", TorznabCatType.MoviesHD); // 720P
AddCategoryMapping("17", TorznabCatType.MoviesDVD); // DVD R
AddCategoryMapping("21", TorznabCatType.MoviesDVD); // DVD R5
AddCategoryMapping("112", TorznabCatType.MoviesDVD); // DVD REMUX
AddCategoryMapping("107", TorznabCatType.Movies3D); // 3D
AddCategoryMapping("113", TorznabCatType.MoviesBluRay); // BLURAY
AddCategoryMapping("118", TorznabCatType.MoviesHD); // MHD
// Series
AddCategoryMapping("41", TorznabCatType.TV); // ALL
AddCategoryMapping("43", TorznabCatType.TV); // VF
AddCategoryMapping("44", TorznabCatType.TV); // VOSTFR
AddCategoryMapping("42", TorznabCatType.TV); // PACK
// TV
AddCategoryMapping("110", TorznabCatType.TV); // SHOWS
// Anime
AddCategoryMapping("109", TorznabCatType.TVAnime); // ANIME
// Manga
AddCategoryMapping("119", TorznabCatType.TVAnime); // MANGA
// Documentaries
AddCategoryMapping("114", TorznabCatType.TVDocumentary); // DOCUMENTARY
// Music
AddCategoryMapping("22", TorznabCatType.Audio); // ALL
AddCategoryMapping("24", TorznabCatType.AudioLossless); // FLAC
AddCategoryMapping("23", TorznabCatType.AudioMP3); // MP3
// Games
AddCategoryMapping("33", TorznabCatType.PCGames); // ALL
AddCategoryMapping("45", TorznabCatType.PCGames); // PC GAMES
AddCategoryMapping("93", TorznabCatType.Console3DS); // 3DS
AddCategoryMapping("94", TorznabCatType.Console); // PS2
AddCategoryMapping("93", TorznabCatType.ConsolePS3); // PS3
AddCategoryMapping("95", TorznabCatType.ConsolePSP); // PSP
AddCategoryMapping("35", TorznabCatType.ConsolePS3); // WII
// Applications
AddCategoryMapping("11", TorznabCatType.PC); // ALL
AddCategoryMapping("12", TorznabCatType.PC); // APPS WINDOWS
AddCategoryMapping("97", TorznabCatType.PCMac); // APPS MAC
AddCategoryMapping("98", TorznabCatType.PC); // APPS LINUX
// Books
AddCategoryMapping("115", TorznabCatType.BooksEbook); // EBOOK
AddCategoryMapping("114", TorznabCatType.BooksComics); // COMICS
// Other
AddCategoryMapping("103", TorznabCatType.Other); // STAFF
}
/// <summary>
/// Configure our FADN Provider
/// </summary>
/// <param name="configJson">Our params in Json</param>
/// <returns>Configuration state</returns>
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
// Retrieve config values set by Jackett's user
ConfigData.LoadValuesFromJson(configJson);
// Check & Validate Config
validateConfig();
// Setting our data for a better emulated browser (maximum security)
// TODO: Encoded Content not supported by Jackett at this time
// emulatedBrowserHeaders.Add("Accept-Encoding", "gzip, deflate");
// If we want to simulate a browser
if (ConfigData.Browser.Value)
{
// Clean headers
emulatedBrowserHeaders.Clear();
// Inject headers
emulatedBrowserHeaders.Add("Accept", ConfigData.HeaderAccept.Value);
emulatedBrowserHeaders.Add("Accept-Language", ConfigData.HeaderAcceptLang.Value);
emulatedBrowserHeaders.Add("DNT", Convert.ToInt32(ConfigData.HeaderDNT.Value).ToString());
emulatedBrowserHeaders.Add("Upgrade-Insecure-Requests", Convert.ToInt32(ConfigData.HeaderUpgradeInsecure.Value).ToString());
emulatedBrowserHeaders.Add("User-Agent", ConfigData.HeaderUserAgent.Value);
}
// Build WebRequest for index
var myIndexRequest = new WebRequest()
{
Type = RequestType.GET,
Url = SiteLink,
Headers = emulatedBrowserHeaders
};
// Get index page for cookies
output("\nGetting index page (for cookies).. with " + SiteLink);
var indexPage = await webclient.GetString(myIndexRequest);
// Building login form data
var pairs = new Dictionary<string, string> {
{ "username", ConfigData.Username.Value },
{ "password", ConfigData.Password.Value }
};
// Build WebRequest for login
var myRequestLogin = new WebRequest()
{
Type = RequestType.GET,
Url = LoginUrl,
Headers = emulatedBrowserHeaders,
Cookies = indexPage.Cookies,
Referer = SiteLink
};
// Get login page -- (not used, but simulation needed by tracker security's checks)
latencyNow();
output("\nGetting login page (user simulation).. with " + LoginUrl);
var loginPage = await webclient.GetString(myRequestLogin);
// Build WebRequest for submitting authentification
var request = new WebRequest()
{
PostData = pairs,
Referer = LoginUrl,
Type = RequestType.POST,
Url = LoginCheckUrl,
Headers = emulatedBrowserHeaders,
Cookies = indexPage.Cookies,
};
// Perform loggin
latencyNow();
output("\nPerform loggin.. with " + LoginCheckUrl);
var response = await webclient.GetString(request);
// Test if we are logged in
await ConfigureIfOK(response.Cookies, !string.IsNullOrEmpty(response.Cookies) && !response.IsRedirect, () =>
{
// Default error message
string message = "Error during attempt !";
// Parse redirect header
string redirectTo = response.RedirectingTo;
// Analyzer error code
if(redirectTo.Contains("login.php?error=4"))
{
// Set message
message = "Wrong username or password !";
}
// Oops, unable to login
output("-> Login failed: " + message, "error");
throw new ExceptionWithConfigData("Login failed: " + message, configData);
});
output("\nCookies saved for future uses...");
ConfigData.CookieHeader.Value = indexPage.Cookies + " " + response.Cookies + " ts_username=" + ConfigData.Username.Value;
output("\n-> Login Success\n");
return IndexerConfigurationStatus.RequiresTesting;
}
/// <summary>
/// Execute our search query
/// </summary>
/// <param name="query">Query</param>
/// <returns>Releases</returns>
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>();
var torrentRowList = new List<CQ>();
var searchTerm = query.GetQueryString();
var searchUrl = SearchUrl;
int nbResults = 0;
int pageLinkCount = 0;
// Check cache first so we don't query the server (if search term used or not in dev mode)
if (!DevMode && !string.IsNullOrEmpty(searchTerm))
{
lock (cache)
{
// Remove old cache items
CleanCache();
// Search in cache
var cachedResult = cache.Where(i => i.Query == searchTerm).FirstOrDefault();
if (cachedResult != null)
return cachedResult.Results.Select(s => (ReleaseInfo)s.Clone()).ToArray();
}
}
// Build our query
var request = buildQuery(searchTerm, query, searchUrl);
// Getting results & Store content
WebClientStringResult results = await queryExec(request);
fDom = results.Content;
try
{
// Find torrent rows
var firstPageRows = findTorrentRows();
// Add them to torrents list
torrentRowList.AddRange(firstPageRows.Select(fRow => fRow.Cq()));
// Check if there are pagination links at bottom
Boolean pagination = (fDom["#quicknavpage_menu"].Length != 0);
// If pagination available
if (pagination)
{
// Retrieve available pages (3 pages shown max)
pageLinkCount = fDom["#navcontainer_f:first > ul"].Find("a").Not(".smalltext").Not("#quicknavpage").Length;
// Last button ? (So more than 3 page are available)
Boolean more = (fDom["#navcontainer_f:first > ul"].Find("a.smalltext").Length > 1); ;
// More page than 3 pages ?
if (more)
{
// Get total page count from last link
pageLinkCount = ParseUtil.CoerceInt(Regex.Match(fDom["#navcontainer_f:first > ul"].Find("a:eq(4)").Attr("href").ToString(), @"\d+").Value);
}
// Calculate average number of results (based on torrents rows lenght on first page)
nbResults = firstPageRows.Count() * pageLinkCount;
}
else {
nbResults = 1;
pageLinkCount = 1;
// Check if we have a minimum of one result
if (firstPageRows.Length > 1)
{
// Retrieve total count on our alone page
nbResults = firstPageRows.Count();
}
else
{
// Check if no result
if(torrentRowList.First().Find("td").Length == 1)
{
// No results found
output("\nNo result found for your query, please try another search term ...\n", "info");
// No result found for this query
return releases;
}
}
}
output("\nFound " + nbResults + " result(s) (+/- " + firstPageRows.Length + ") in " + pageLinkCount + " page(s) for this query !");
output("\nThere are " + firstPageRows.Length + " results on the first page !");
// If we have a term used for search and pagination result superior to one
if (!string.IsNullOrWhiteSpace(query.GetQueryString()) && pageLinkCount > 1)
{
// Starting with page #2
for (int i = 2; i <= Math.Min(Int32.Parse(ConfigData.Pages.Value), pageLinkCount); i++)
{
output("\nProcessing page #" + i);
// Request our page
latencyNow();
// Build our query -- Minus 1 to page due to strange pagination number on tracker side, starting with page 0...
var pageRequest = buildQuery(searchTerm, query, searchUrl, i);
// Getting results & Store content
WebClientStringResult pageResults = await queryExec(pageRequest);
// Assign response
fDom = pageResults.Content;
// Process page results
var additionalPageRows = findTorrentRows();
// Add them to torrents list
torrentRowList.AddRange(additionalPageRows.Select(fRow => fRow.Cq()));
}
}
// Loop on results
foreach (CQ tRow in torrentRowList)
{
output("\n=>> Torrent #" + (releases.Count + 1));
// ID
int id = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(1) > div:first > a").Attr("name").ToString(), @"\d+").Value);
output("ID: " + id);
// Check if torrent is not nuked by tracker or rulez, can't download it
if (tRow.Find("td:eq(2) > a").Length == 0)
{
// Next item
output("Torrent is nuked, we can't download it, going to next torrent...");
continue;
}
// Release Name
string name = tRow.Find("td:eq(2) > a").Attr("title").ToString().Substring(24).Trim();
output("Release: " + name);
// Category
int categoryID = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(0) > a").Attr("href").ToString(), @"\d+").Value);
string categoryName = tRow.Find("td:eq(0) > a > img").Attr("title").Split(new[] { ':' }, 2)[1].Trim().ToString();
output("Category: " + MapTrackerCatToNewznab(categoryID.ToString()) + " (" + categoryID + " - " + categoryName + ")");
// Seeders
int seeders = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(5) > div > font").Select(s => Regex.Replace(s.ToString(), "<.*?>", String.Empty)).ToString(), @"\d+").Value);
output("Seeders: " + seeders);
// Leechers
int leechers = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(6) > div > font").Text().ToString(), @"\d+").Value);
output("Leechers: " + leechers);
// Completed
int completed = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(4)").Text().ToString(), @"\d+").Value);
output("Completed: " + completed);
// Files
int files = 1;
if (tRow.Find("td:eq(3) > a").Length == 1)
{
files = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(3) > a").Text().ToString(), @"\d+").Value);
}
output("Files: " + files);
// Health
int percent = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(7) > img").Attr("src").ToString(), @"\d+").Value) * 10;
output("Health: " + percent + "%");
// Size
string humanSize = tRow.Find("td:eq(8)").Text().ToString().ToLowerInvariant();
long size = ReleaseInfo.GetBytes(humanSize);
output("Size: " + humanSize + " (" + size + " bytes)");
// Date & IMDB & Genre
string infosData = tRow.Find("td:eq(1) > div:last").Text().ToString();
IList<string> infosList = Regex.Split(infosData, "\\|").ToList();
IList<string> infosTorrent = infosList.Select(s => s.Split(new[] { ':' }, 2)[1].Trim()).ToList();
// --> Date
DateTime date = formatDate(infosTorrent.First());
output("Released on: " + date.ToLocalTime().ToString());
// --> Genre
string genre = infosTorrent.Last();
output("Genre: " + genre);
// Torrent Details URL
Uri detailsLink = new Uri(TorrentDescriptionUrl.Replace("{id}", id.ToString()));
output("Details: " + detailsLink.AbsoluteUri);
// Torrent Comments URL
Uri commentsLink = new Uri(TorrentCommentUrl.Replace("{id}", id.ToString()));
output("Comments Link: " + commentsLink.AbsoluteUri);
// Torrent Download URL
Uri downloadLink = new Uri(TorrentDownloadUrl.Replace("{id}", id.ToString()));
output("Download Link: " + downloadLink.AbsoluteUri);
// Building release infos
var release = new ReleaseInfo();
release.Category = MapTrackerCatToNewznab(categoryID.ToString());
release.Title = name;
release.Seeders = seeders;
release.Peers = seeders + leechers;
release.MinimumRatio = 1;
release.MinimumSeedTime = 172800;
release.PublishDate = date;
release.Size = size;
release.Guid = detailsLink;
release.Comments = commentsLink;
release.Link = downloadLink;
releases.Add(release);
}
}
catch (Exception ex)
{
OnParseError("Error, unable to parse result \n" + ex.StackTrace, ex);
}
// Return found releases
return releases;
}
/// <summary>
/// Build query to process
/// </summary>
/// <param name="term">Term to search</param>
/// <param name="query">Torznab Query for categories mapping</param>
/// <param name="url">Search url for provider</param>
/// <param name="page">Page number to request</param>
/// <returns>URL to query for parsing and processing results</returns>
private string buildQuery(string term, TorznabQuery query, string url, int page = 0)
{
var parameters = new NameValueCollection();
List<string> categoriesList = MapTorznabCapsToTrackers(query);
// Building our tracker query
parameters.Add("do", "search");
// If search term provided
if (!string.IsNullOrWhiteSpace(term))
{
// Add search term ~~ Strange search engine, need to replace space with dot for results !
parameters.Add("keywords", term.Replace(' ', '.'));
}
else
{
// Showing all torrents (just for output function)
parameters.Add("keywords", "");
term = "all";
}
// Adding requested categories
if(categoriesList.Count > 0)
{
// Add categories
parameters.Add("category", String.Join(",", categoriesList));
}
else
{
// Add empty category parameter
parameters.Add("category", "");
}
// Building our tracker query
parameters.Add("search_type", "t_name");
// Check if we are processing a new page
if (page > 1)
{
// Adding page number to query
parameters.Add("page", page.ToString());
}
// Building our query
url += "?" + parameters.GetQueryString();
output("\nBuilded query for \"" + term + "\"... " + url);
// Return our search url
return url;
}
/// <summary>
/// Switch Method for Querying
/// </summary>
/// <param name="request">URL created by Query Builder</param>
/// <returns>Results from query</returns>
private async Task<WebClientStringResult> queryExec(string request)
{
WebClientStringResult results = null;
// Switch in we are in DEV mode with Hard Drive Cache or not
if (DevMode && CacheMode)
{
// Check Cache before querying and load previous results if available
results = await queryCache(request);
}
else
{
// Querying tracker directly
results = await queryTracker(request);
}
return results;
}
/// <summary>
/// Get Torrents Page from Cache by Query Provided
/// </summary>
/// <param name="request">URL created by Query Builder</param>
/// <returns>Results from query</returns>
private async Task<WebClientStringResult> queryCache(string request)
{
WebClientStringResult results = null;
// Create Directory if not exist
System.IO.Directory.CreateDirectory(directory);
// Clean Storage Provider Directory from outdated cached queries
cleanCacheStorage();
// Create fingerprint for request
string file = directory + request.GetHashCode() + ".json";
// Checking modes states
if (System.IO.File.Exists(file))
{
// File exist... loading it right now !
output("Loading results from hard drive cache ..." + request.GetHashCode() + ".json");
results = JsonConvert.DeserializeObject<WebClientStringResult>(System.IO.File.ReadAllText(file));
}
else
{
// No cached file found, querying tracker directly
results = await queryTracker(request);
// Cached file didn't exist for our query, writing it right now !
output("Writing results to hard drive cache ..." + request.GetHashCode() + ".json");
System.IO.File.WriteAllText(file, JsonConvert.SerializeObject(results));
}
return results;
}
/// <summary>
/// Get Torrents Page from Tracker by Query Provided
/// </summary>
/// <param name="request">URL created by Query Builder</param>
/// <returns>Results from query</returns>
private async Task<WebClientStringResult> queryTracker(string request)
{
WebClientStringResult results = null;
// Cache mode not enabled or cached file didn't exist for our query
output("\nQuerying tracker for results....");
// Request our first page
latencyNow();
results = await RequestStringWithCookiesAndRetry(request, ConfigData.CookieHeader.Value, SearchUrl, emulatedBrowserHeaders);
// Return results from tracker
return results;
}
/// <summary>
/// Clean Hard Drive Cache Storage
/// </summary>
/// <param name="force">Force Provider Folder deletion</param>
private void cleanCacheStorage(Boolean force = false)
{
// Check cleaning method
if (force)
{
// Deleting Provider Storage folder and all files recursively
output("\nDeleting Provider Storage folder and all files recursively ...");
// Check if directory exist
if (System.IO.Directory.Exists(directory))
{
// Delete storage directory of provider
System.IO.Directory.Delete(directory, true);
output("-> Storage folder deleted successfully.");
}
else
{
// No directory, so nothing to do
output("-> No Storage folder found for this provider !");
}
}
else
{
int i = 0;
// Check if there is file older than ... and delete them
output("\nCleaning Provider Storage folder... in progress.");
System.IO.Directory.GetFiles(directory)
.Select(f => new System.IO.FileInfo(f))
.Where(f => f.LastAccessTime < DateTime.Now.AddMilliseconds(-Convert.ToInt32(ConfigData.HardDriveCacheKeepTime.Value)))
.ToList()
.ForEach(f => {
output("Deleting cached file << " + f.Name + " >> ... done.");
f.Delete();
i++;
});
// Inform on what was cleaned during process
if (i > 0)
{
output("-> Deleted " + i + " cached files during cleaning.");
}
else {
output("-> Nothing deleted during cleaning.");
}
}
}
/// <summary>
/// Generate a random fake latency to avoid detection on tracker side
/// </summary>
private void latencyNow()
{
// Need latency ?
if (Latency)
{
// Generate a random value in our range
var random = new Random(DateTime.Now.Millisecond);
int waiting = random.Next(Convert.ToInt32(ConfigData.LatencyStart.Value), Convert.ToInt32(ConfigData.LatencyEnd.Value));
output("\nLatency Faker => Sleeping for " + waiting + " ms...");
// Sleep now...
System.Threading.Thread.Sleep(waiting);
}
}
/// <summary>
/// Find torrent rows in search pages
/// </summary>
/// <returns>JQuery Object</returns>
private CQ findTorrentRows()
{
// Return all occurencis of torrents found
return fDom["#showcontents > table > tbody > tr:not(:first)"];
}
/// <summary>
/// Format Date to DateTime
/// </summary>
/// <param name="clock"></param>
/// <returns>A DateTime</returns>
private DateTime formatDate(string clock)
{
DateTime date;
// Switch from date format
if(clock.Contains("Aujourd'hui") || clock.Contains("Hier"))
{
// Get hours & minutes
IList<int> infosClock = clock.Split(':').Select(s => ParseUtil.CoerceInt(Regex.Match(s, @"\d+").Value)).ToList();
// Ago date with today
date = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, Convert.ToInt32(infosClock[0]), Convert.ToInt32(infosClock[1]), DateTime.Now.Second);
// Set yesterday if necessary
if (clock.Contains("Hier"))
{
// Remove one day from date
date.AddDays(-1);
}
}
else
{
// Parse Date if full
date = DateTime.ParseExact(clock, "MM-dd-yyyy HH:mm", CultureInfo.GetCultureInfo("fr-FR"), DateTimeStyles.AssumeLocal);
}
return date.ToUniversalTime();
}
/// <summary>
/// Download torrent file from tracker
/// </summary>
/// <param name="link">URL string</param>
/// <returns></returns>
public async override Task<byte[]> Download(Uri link)
{
var dl = link.AbsoluteUri;
// This tracker need to thanks Uploader before getting torrent file...
output("\nThis tracker needs you to thank uploader before downloading torrent!");
// Retrieving ID from link provided
int id = ParseUtil.CoerceInt(Regex.Match(link.AbsoluteUri, @"\d+").Value);
output("Torrent Requested ID: " + id);
// Building login form data
var pairs = new Dictionary<string, string> {
{ "torrentid", id.ToString() },
{ "_", string.Empty } // ~~ Strange, blank param...
};
// Add emulated XHR request
emulatedBrowserHeaders.Add("X-Prototype-Version", "1.6.0.3");
emulatedBrowserHeaders.Add("X-Requested-With", "XMLHttpRequest");
// Build WebRequest for thanks
var myRequestThanks = new WebRequest()
{
Type = RequestType.POST,
PostData = pairs,
Url = TorrentThanksUrl,
Headers = emulatedBrowserHeaders,
Cookies = ConfigData.CookieHeader.Value,
Referer = TorrentDescriptionUrl.Replace("{id}", id.ToString())
};
// Get thanks page -- (not used, just for doing a request)
latencyNow();
output("Thanks user, to get download link for our torrent.. with " + TorrentThanksUrl);
var thanksPage = await webclient.GetString(myRequestThanks);
// Get torrent file now
output("Getting torrent file now....");
var response = await base.Download(link);
// Remove our XHR request header
emulatedBrowserHeaders.Remove("X-Prototype-Version");
emulatedBrowserHeaders.Remove("X-Requested-With");
// Return content
return response;
}
/// <summary>
/// Output message for logging or developpment (console)
/// </summary>
/// <param name="message">Message to output</param>
/// <param name="level">Level for Logger</param>
private void output(string message, string level = "debug")
{
// Check if we are in dev mode
if (DevMode)
{
// Output message to console
Console.WriteLine(message);
}
else
{
// Send message to logger with level
switch (level)
{
default:
goto case "debug";
case "debug":
// Only if Debug Level Enabled on Jackett
if (Engine.Logger.IsDebugEnabled)
{
logger.Debug(message);
}
break;
case "info":
logger.Info(message);
break;
case "error":
logger.Error(message);
break;
}
}
}
/// <summary>
/// Validate Config entered by user on Jackett
/// </summary>
private void validateConfig()
{
output("\nValidating Settings ... \n");
// Check Username Setting
if (string.IsNullOrEmpty(ConfigData.Username.Value))
{
throw new ExceptionWithConfigData("You must provide a username for this tracker to login !", ConfigData);
}
else
{
output("Validated Setting -- Username (auth) => " + ConfigData.Username.Value.ToString());
}
// Check Password Setting
if (string.IsNullOrEmpty(ConfigData.Password.Value))
{
throw new ExceptionWithConfigData("You must provide a password with your username for this tracker to login !", ConfigData);
}
else
{
output("Validated Setting -- Password (auth) => " + ConfigData.Password.Value.ToString());
}
// Check Max Page Setting
if (!string.IsNullOrEmpty(ConfigData.Pages.Value))
{
try
{
output("Validated Setting -- Max Pages => " + Convert.ToInt32(ConfigData.Pages.Value));
}
catch (Exception)
{
throw new ExceptionWithConfigData("Please enter a numeric maximum number of pages to crawl !", ConfigData);
}
}
else
{
throw new ExceptionWithConfigData("Please enter a maximum number of pages to crawl !", ConfigData);
}
// Check Latency Setting
if (ConfigData.Latency.Value)
{
output("\nValidated Setting -- Latency Simulation enabled");
// Check Latency Start Setting
if (!string.IsNullOrEmpty(ConfigData.LatencyStart.Value))
{
try
{
output("Validated Setting -- Latency Start => " + Convert.ToInt32(ConfigData.LatencyStart.Value));
}
catch (Exception)
{
throw new ExceptionWithConfigData("Please enter a numeric latency start in ms !", ConfigData);
}
}
else
{
throw new ExceptionWithConfigData("Latency Simulation enabled, Please enter a start latency !", ConfigData);
}
// Check Latency End Setting
if (!string.IsNullOrEmpty(ConfigData.LatencyEnd.Value))
{
try
{
output("Validated Setting -- Latency End => " + Convert.ToInt32(ConfigData.LatencyEnd.Value));
}
catch (Exception)
{
throw new ExceptionWithConfigData("Please enter a numeric latency end in ms !", ConfigData);
}
}
else
{
throw new ExceptionWithConfigData("Latency Simulation enabled, Please enter a end latency !", ConfigData);
}
}
// Check Browser Setting
if (ConfigData.Browser.Value == true)
{
output("\nValidated Setting -- Browser Simulation enabled");
// Check ACCEPT header Setting
if (string.IsNullOrEmpty(ConfigData.HeaderAccept.Value))
{
throw new ExceptionWithConfigData("Browser Simulation enabled, Please enter an ACCEPT header !", ConfigData);
}
else
{
output("Validated Setting -- ACCEPT (header) => " + ConfigData.HeaderAccept.Value.ToString());
}
// Check ACCEPT-LANG header Setting
if (string.IsNullOrEmpty(ConfigData.HeaderAcceptLang.Value))
{
throw new ExceptionWithConfigData("Browser Simulation enabled, Please enter an ACCEPT-LANG header !", ConfigData);
}
else
{
output("Validated Setting -- ACCEPT-LANG (header) => " + ConfigData.HeaderAcceptLang.Value.ToString());
}
// Check USER-AGENT header Setting
if (string.IsNullOrEmpty(ConfigData.HeaderUserAgent.Value))
{
throw new ExceptionWithConfigData("Browser Simulation enabled, Please enter an USER-AGENT header !", ConfigData);
}
else
{
output("Validated Setting -- USER-AGENT (header) => " + ConfigData.HeaderUserAgent.Value.ToString());
}
}
else
{
// Browser simulation must be enabled (otherwhise, this provider will not work due to tracker's security)
throw new ExceptionWithConfigData("Browser Simulation must be enabled for this provider to work, please enable it !", ConfigData);
}
// Check Dev Cache Settings
if (ConfigData.HardDriveCache.Value == true)
{
output("\nValidated Setting -- DEV Hard Drive Cache enabled");
// Check if Dev Mode enabled !
if (!ConfigData.DevMode.Value)
{
throw new ExceptionWithConfigData("Hard Drive is enabled but not in DEV MODE, Please enable DEV MODE !", ConfigData);
}
// Check Cache Keep Time Setting
if (!string.IsNullOrEmpty(ConfigData.HardDriveCacheKeepTime.Value))
{
try
{
output("Validated Setting -- Cache Keep Time (ms) => " + Convert.ToInt32(ConfigData.HardDriveCacheKeepTime.Value));
}
catch (Exception)
{
throw new ExceptionWithConfigData("Please enter a numeric hard drive keep time in ms !", ConfigData);
}
}
else
{
throw new ExceptionWithConfigData("Hard Drive Cache enabled, Please enter a maximum keep time for cache !", ConfigData);
}
}
else
{
// Delete cache if previously existed
cleanCacheStorage(true);
}
}
}
}

View File

@@ -1,97 +0,0 @@
using CsQuery;
using Jackett.Models;
using Jackett.Models.IndexerConfig;
using Jackett.Services;
using Jackett.Utils;
using Jackett.Utils.Clients;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Web;
namespace Jackett.Indexers
{
class FrenchTorrentDb : BaseIndexer, IIndexer
{
private string MainUrl { get { return SiteLink + "?section=INDEX"; } }
private string SearchUrl { get { return SiteLink + "?section=TORRENTS&exact=1&name={0}&submit=GO"; } }
new ConfigurationDataCookie configData
{
get { return (ConfigurationDataCookie)base.configData; }
set { base.configData = value; }
}
public FrenchTorrentDb(IIndexerManagerService i, Logger l, IWebClient c, IProtectionService ps)
: base(name: "FrenchTorrentDb",
description: "One the biggest French Torrent Tracker",
link: "http://www.frenchtorrentdb.com/",
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
manager: i,
client: c,
logger: l,
p: ps,
configData: new ConfigurationDataCookie())
{
}
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
configData.LoadValuesFromJson(configJson);
var response = await webclient.GetString(new Utils.Clients.WebRequest()
{
Url = MainUrl,
Type = RequestType.GET,
Cookies = configData.Cookie.Value
});
await ConfigureIfOK(configData.Cookie.Value, response.Content.Contains("/?section=LOGOUT"), () =>
{
throw new ExceptionWithConfigData("Failed to login", configData);
});
return IndexerConfigurationStatus.RequiresTesting;
}
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>();
var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(query.GetQueryString()));
var response = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
try
{
CQ dom = response.Cookies;
var rows = dom[".results_index ul"];
foreach (var row in rows)
{
var release = new ReleaseInfo();
CQ qRow = row.Cq();
CQ qLink = qRow.Find("li.torrents_name > .torrents_name_link").First();
CQ qDlLink = qRow.Find("li.torrents_download > a").First();
release.MinimumRatio = 1;
release.MinimumSeedTime = 172800;
release.Title = qLink.Text().Trim();
release.Description = release.Title;
release.Comments = new Uri(SiteLink + "/" + qLink.Attr("href").TrimStart('/'));
release.Guid = release.Comments;
release.Link = new Uri(SiteLink + "/" + qDlLink.Attr("href").TrimStart('/'));
release.PublishDate = DateTime.Now;
release.Seeders = ParseUtil.CoerceInt(qRow.Find("li.torrents_seeders").Text());
release.Peers = ParseUtil.CoerceInt(qRow.Find("li.torrents_leechers").Text()) + release.Seeders;
var sizeParts = qRow.Find("li.torrents_size").Text();
release.Size = ReleaseInfo.GetBytes(sizeParts);
releases.Add(release);
}
}
catch (Exception ex)
{
OnParseError(response.Content, ex);
}
return releases;
}
}
}

View File

@@ -70,6 +70,13 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0), 3, 5, DayOfWeek.Sunday);
TimeZoneInfo.TransitionTime endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0), 10, 5, DayOfWeek.Sunday);
TimeSpan delta = new TimeSpan(1, 0, 0);
TimeZoneInfo.AdjustmentRule adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition);
TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment };
TimeZoneInfo romaniaTz = TimeZoneInfo.CreateCustomTimeZone("Romania Time", new TimeSpan(2, 0, 0), "(GMT+02:00) Romania Time", "Romania Time", "Romania Daylight Time", adjustments);
var releases = new List<ReleaseInfo>();
string episodeSearchUrl;
@@ -77,7 +84,7 @@ namespace Jackett.Indexers
episodeSearchUrl = SearchUrl;
else
{
episodeSearchUrl = string.Format("{0}?search={1}&cat=0", SearchUrl, HttpUtility.UrlEncode(query.GetQueryString()));
episodeSearchUrl = $"{SearchUrl}?search={HttpUtility.UrlEncode(query.GetQueryString())}&cat=0";
}
var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
@@ -101,16 +108,7 @@ namespace Jackett.Indexers
release.Guid = new Uri(SiteLink + qLink.Attr("href"));
release.Comments = release.Guid;
release.Link = new Uri(SiteLink + qRow.Find("td.table_links > a").First().Attr("href"));
DateTime pubDate;
var dateString = qRow.Find("td.table_added").Text().Trim();
if (dateString.StartsWith("Today "))
pubDate = (DateTime.UtcNow + TimeSpan.Parse(dateString.Split(' ')[1])).ToLocalTime();
else if (dateString.StartsWith("Yesterday "))
pubDate = (DateTime.UtcNow + TimeSpan.Parse(dateString.Split(' ')[1]) - TimeSpan.FromDays(1)).ToLocalTime();
else
pubDate = DateTime.ParseExact(dateString, "d-MMM-yyyy HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToLocalTime();
release.PublishDate = pubDate;
release.Category = TvCategoryParser.ParseTvShowQuality(release.Title);
release.Seeders = ParseUtil.CoerceInt(qRow.Find("td.table_seeders").Text().Trim());
release.Peers = ParseUtil.CoerceInt(qRow.Find("td.table_leechers").Text().Trim()) + release.Seeders;
@@ -118,6 +116,18 @@ namespace Jackett.Indexers
var sizeStr = qRow.Find("td.table_size")[0].Cq().Text();
release.Size = ReleaseInfo.GetBytes(sizeStr);
DateTime pubDateRomania;
var dateString = qRow.Find("td.table_added").Text().Trim();
if (dateString.StartsWith("Today "))
{ pubDateRomania = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + TimeSpan.Parse(dateString.Split(' ')[1]); }
else if (dateString.StartsWith("Yesterday "))
{ pubDateRomania = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + TimeSpan.Parse(dateString.Split(' ')[1]) - TimeSpan.FromDays(1); }
else
{ pubDateRomania = DateTime.SpecifyKind(DateTime.ParseExact(dateString, "d-MMM-yyyy HH:mm:ss", CultureInfo.InvariantCulture), DateTimeKind.Unspecified); }
DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(pubDateRomania, romaniaTz);
release.PublishDate = pubDateUtc.ToLocalTime();
releases.Add(release);
}
}

View File

@@ -0,0 +1,202 @@
using CsQuery;
using Jackett.Models;
using Jackett.Services;
using Jackett.Utils;
using Jackett.Utils.Clients;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using Jackett.Models.IndexerConfig;
using System.Collections.Specialized;
namespace Jackett.Indexers
{
//
// Quick and dirty indexer for GFTracker.
//
public class GFTracker : BaseIndexer, IIndexer
{
private string StartPageUrl { get { return SiteLink + "login.php?returnto=%2F"; } }
private string LoginUrl { get { return SiteLink + "loginsite.php"; } }
private string SearchUrl { get { return SiteLink + "browse.php"; } }
new ConfigurationDataRecaptchaLogin configData
{
get { return (ConfigurationDataRecaptchaLogin)base.configData; }
set { base.configData = value; }
}
public GFTracker(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps)
: base(name: "GFTracker",
description: "Home of user happiness",
link: "https://www.thegft.org/",
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
manager: i,
client: w,
logger: l,
p: ps,
configData: new ConfigurationDataRecaptchaLogin())
{
AddCategoryMapping(4, TorznabCatType.TV); // TV/XVID
AddCategoryMapping(17, TorznabCatType.TVHD); // TV/X264
AddCategoryMapping(19, TorznabCatType.TV); // TV/DVDRIP
AddCategoryMapping(26, TorznabCatType.TVHD); // TV/BLURAY
AddCategoryMapping(37, TorznabCatType.TV); // TV/DVDR
AddCategoryMapping(47, TorznabCatType.TV); // TV/SD
AddCategoryMapping(7, TorznabCatType.Movies); // Movies/XVID
AddCategoryMapping(8, TorznabCatType.MoviesDVD); // Movies/DVDR
AddCategoryMapping(12, TorznabCatType.MoviesBluRay); // Movies/BLURAY
AddCategoryMapping(18, TorznabCatType.MoviesHD); // Movies/X264-HD
AddCategoryMapping(49, TorznabCatType.MoviesSD); // Movies/X264-SD
}
public override async Task<ConfigurationData> GetConfigurationForSetup()
{
var loginPage = await RequestStringWithCookies(StartPageUrl, string.Empty);
CQ cq = loginPage.Content;
var result = new ConfigurationDataRecaptchaLogin();
CQ recaptcha = cq.Find(".g-recaptcha").Attr("data-sitekey");
if(recaptcha.Length != 0) // recaptcha not always present in login form, perhaps based on cloudflare uid or just phase of the moon
{
result.CookieHeader.Value = loginPage.Cookies;
result.Captcha.SiteKey = cq.Find(".g-recaptcha").Attr("data-sitekey");
return result;
} else
{
var stdResult = new ConfigurationDataBasicLogin();
stdResult.CookieHeader.Value = loginPage.Cookies;
return stdResult;
}
}
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
configData.LoadValuesFromJson(configJson);
var pairs = new Dictionary<string, string> {
{ "username", configData.Username.Value },
{ "password", configData.Password.Value },
{ "g-recaptcha-response", configData.Captcha.Value }
};
if (!string.IsNullOrWhiteSpace(configData.Captcha.Cookie))
{
CookieHeader = configData.Captcha.Cookie;
try
{
var results = await PerformQuery(new TorznabQuery());
if (results.Count() == 0)
{
throw new Exception("Your cookie did not work");
}
SaveConfig();
IsConfigured = true;
return IndexerConfigurationStatus.Completed;
}
catch (Exception e)
{
IsConfigured = false;
throw new Exception("Your cookie did not work: " + e.Message);
}
}
var cookieJar = configData.CookieHeader.Value;
var response = await RequestLoginAndFollowRedirect(LoginUrl, pairs, configData.CookieHeader.Value, true, null, StartPageUrl);
cookieJar += response.Cookies.ToString();
response = await RequestStringWithCookiesAndRetry(SearchUrl, cookieJar);
await ConfigureIfOK(cookieJar, response.Content != null && response.Content.Contains("logout.php"), () =>
{
CQ dom = response.Content;
var messageEl = dom["h2"].Last();
messageEl.Children("a").Remove();
messageEl.Children("style").Remove();
var errorMessage = messageEl.Text().Trim();
throw new ExceptionWithConfigData(errorMessage, configData);
});
return IndexerConfigurationStatus.RequiresTesting;
}
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>();
var searchString = query.GetQueryString();
var queryCollection = new NameValueCollection();
queryCollection.Add("view", "0");
if (!string.IsNullOrWhiteSpace(searchString))
{
queryCollection.Add("search", searchString);
}
foreach (var cat in MapTorznabCapsToTrackers(query))
{
queryCollection.Add(string.Format("c{0}", cat), "1");
}
var searchUrl = SearchUrl + "?" + queryCollection.GetQueryString();
var results = await RequestStringWithCookiesAndRetry(searchUrl, CookieHeader);
try
{
CQ dom = results.Content;
var rows = dom["#torrentBrowse > table > tbody > tr"];
foreach (var row in rows.Skip(1))
{
var release = new ReleaseInfo();
CQ qRow = row.Cq();
//CQ qLink = qRow.Children().ElementAt(1).Cq().Children("a").ElementAt(1).Cq();
CQ qLink;
CQ qTmp = qRow.Children().ElementAt(1).Cq().Find("a");
if (qTmp.Length < 2) {
qLink = qRow.Children().ElementAt(1).Cq().Find("a").ElementAt(0).Cq();
} else {
qLink = qRow.Children().ElementAt(1).Cq().Find("a").ElementAt(1).Cq();
}
release.MinimumRatio = 1;
release.MinimumSeedTime = 172800;
release.Title = qLink.Attr("title");
release.Description = release.Title;
release.Guid = new Uri(SiteLink + qLink.Attr("href").TrimStart('/'));
release.Comments = release.Guid;
qLink = qRow.Children().ElementAt(3).Cq().Children("a").First();
release.Link = new Uri(string.Format("{0}{1}", SiteLink, qLink.Attr("href")));
var catUrl = qRow.Children().ElementAt(0).FirstElementChild.Cq().Attr("href");
var catNum = catUrl.Split(new char[] { '=', '&' })[2].Replace("c", "");
release.Category = MapTrackerCatToNewznab(catNum);
var dateString = qRow.Children().ElementAt(6).Cq().Text().Trim();
//var pubDate = DateTime.ParseExact(dateString, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
release.PublishDate = Jackett.Utils.DateTimeUtil.FromTimeAgo(dateString);
var sizeStr = qRow.Children().ElementAt(7).Cq().Text().Split(new char[] { '/' })[0];
release.Size = ReleaseInfo.GetBytes(sizeStr);
release.Seeders = ParseUtil.CoerceInt(qRow.Children().ElementAt(8).Cq().Text().Split(new char[] { '/' })[0].Trim());
release.Peers = ParseUtil.CoerceInt(qRow.Children().ElementAt(8).Cq().Text().Split(new char[] { '/' })[1].Trim()) + release.Seeders;
releases.Add(release);
}
}
catch (Exception ex)
{
OnParseError(results.Content, ex);
}
return releases;
}
}
}

View File

@@ -1,4 +1,4 @@
using CsQuery;
using CsQuery;
using Jackett.Indexers;
using Jackett.Models;
using Jackett.Services;
@@ -26,9 +26,9 @@ namespace Jackett.Indexers
private string LoginUrl { get { return SiteLink + "login.php"; } }
private string SearchUrl { get { return SiteLink + "torrents.php"; } }
new ConfigurationDataBasicLogin configData
new NxtGnConfigurationData configData
{
get { return (ConfigurationDataBasicLogin)base.configData; }
get { return (NxtGnConfigurationData)base.configData; }
set { base.configData = value; }
}
@@ -41,7 +41,7 @@ namespace Jackett.Indexers
client: c,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
configData: new NxtGnConfigurationData())
{
AddCategoryMapping(92, TorznabCatType.TV);
AddCategoryMapping(92, TorznabCatType.TVHD);
@@ -65,13 +65,14 @@ namespace Jackett.Indexers
var pairs = new Dictionary<string, string> {
{ "username", configData.Username.Value },
{ "password", configData.Password.Value },
{ "Submit", "Submit" }
{ "keeplogged", "1" },
{ "login", "Login" }
};
// Get inital cookies
var response = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, LoginUrl);
var response = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, "https://hounddawgs.org/");
await ConfigureIfOK(response.Cookies, response.Content != null && response.Content.Contains("Velkommen til vores seneste bruger"), () =>
await ConfigureIfOK(response.Cookies, response.Content != null && response.Content.Contains("Velkommen til"), () =>
{
CQ dom = response.Content;
var messageEl = dom["inputs"];
@@ -142,5 +143,15 @@ namespace Jackett.Indexers
return releases;
}
public class NxtGnConfigurationData : ConfigurationData
{
public NxtGnConfigurationData()
{
Username = new StringItem { Name = "Username" };
Password = new StringItem { Name = "Password" };
}
public StringItem Username { get; private set; }
public StringItem Password { get; private set; }
}
}
}

View File

@@ -33,7 +33,7 @@ namespace Jackett.Indexers
: base(name: "IPTorrents",
description: "Always a step ahead.",
link: "https://iptorrents.com/",
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
caps: new TorznabCapabilities(),
manager: i,
client: wc,
logger: l,
@@ -165,7 +165,7 @@ namespace Jackett.Indexers
release.PublishDate = DateTimeUtil.FromTimeAgo(dateString);
var qLink = row.ChildElements.ElementAt(3).Cq().Children("a");
release.Link = new Uri(SiteLink + qLink.Attr("href"));
release.Link = new Uri(SiteLink + qLink.Attr("href").TrimStart('/'));
var sizeStr = row.ChildElements.ElementAt(5).Cq().Text();
release.Size = ReleaseInfo.GetBytes(sizeStr);

View File

@@ -12,6 +12,7 @@ using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
using Jackett.Models.IndexerConfig;
@@ -93,10 +94,17 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>();
var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode(query.GetQueryString());
WebClientStringResult response = null;
string qryString = query.GetQueryString();
response = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
Match matchQry = new Regex(@".*\s[Ss]{1}\d{2}$").Match(qryString);
if (matchQry.Success)
{
//If search string ends in S## eg. S03 (season search) add an asterix to search term
qryString += "*";
}
var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode(qryString);
WebClientStringResult response = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
try
{
@@ -112,16 +120,18 @@ namespace Jackett.Indexers
pubDate = DateTime.SpecifyKind(pubDate, DateTimeKind.Utc).ToLocalTime();
}
var groupName = (string)r["groupName"];
string groupName = (string)r["groupName"];
if (r["torrents"] is JArray)
{
string showName = (string) r["artist"];
foreach (JObject t in r["torrents"])
{
var release = new ReleaseInfo();
release.PublishDate = pubDate;
release.Title = groupName;
release.Description = groupName;
release.Title = $"{showName} {groupName}";
release.Description = $"{showName} {groupName}";
FillReleaseInfoFromJson(release, t);
releases.Add(release);
}

View File

@@ -1,251 +0,0 @@
using CsQuery;
using Jackett.Indexers;
using Jackett.Models;
using Jackett.Services;
using Jackett.Utils;
using Jackett.Utils.Clients;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.UI.WebControls;
using CsQuery.ExtensionMethods;
using Jackett.Models.IndexerConfig;
namespace Jackett.Indexers
{
public class NxtGn : BaseIndexer, IIndexer
{
private string LoginUrl { get { return SiteLink + "login.php"; } }
private string SearchUrl { get { return SiteLink + "browse.php"; } }
private string ProfileUrl { get { return SiteLink + "my.php"; } }
new NxtGnConfigurationData configData
{
get { return (NxtGnConfigurationData)base.configData; }
set { base.configData = value; }
}
public NxtGn(IIndexerManagerService i, Logger l, IWebClient c, IProtectionService ps)
: base(name: "NextGen",
description: "A danish closed torrent tracker",
link: "https://nxtgn.biz/",
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
manager: i,
client: c,
logger: l,
p: ps,
configData: new NxtGnConfigurationData())
{
//Movies Mapping
AddCategoryMapping(38, TorznabCatType.MoviesHD);
AddCategoryMapping(38, TorznabCatType.MoviesWEBDL);
AddCategoryMapping(38, TorznabCatType.MoviesBluRay);
AddCategoryMapping(23, TorznabCatType.MoviesForeign);
AddCategoryMapping(22, TorznabCatType.MoviesSD);
AddCategoryMapping(33, TorznabCatType.MoviesHD);
AddCategoryMapping(33, TorznabCatType.Movies);
AddCategoryMapping(17, TorznabCatType.MoviesForeign);
AddCategoryMapping(17, TorznabCatType.MoviesDVD);
if (!configData.OnlyDanishCategories.Value)
{
AddCategoryMapping(9, TorznabCatType.MoviesHD);
AddCategoryMapping(9, TorznabCatType.Movies);
AddCategoryMapping(9, TorznabCatType.MoviesBluRay);
AddCategoryMapping(47, TorznabCatType.Movies3D);
AddCategoryMapping(5, TorznabCatType.MoviesSD);
}
//TV Mapping
//Category 26: NG Serier WEB-DL (Working)
AddCategoryMapping(26, TorznabCatType.TVHD);
AddCategoryMapping(26, TorznabCatType.TV);
AddCategoryMapping(26, TorznabCatType.TVWEBDL);
//Category 43: NG WWW HD (Working)
AddCategoryMapping(43, TorznabCatType.TVHD);
AddCategoryMapping(43, TorznabCatType.TV);
AddCategoryMapping(43, TorznabCatType.TVWEBDL);
//Category 46: NG Serier HDTV (Working)
AddCategoryMapping(46, TorznabCatType.TVHD);
AddCategoryMapping(46, TorznabCatType.TV);
if (!configData.OnlyDanishCategories.Value)
{
//Category 4: TV (Working)
AddCategoryMapping(4, TorznabCatType.TVSD);
AddCategoryMapping(4, TorznabCatType.TV);
AddCategoryMapping(4, TorznabCatType.TVHD);
//Category 21: Boxset/SD (Working)
AddCategoryMapping(21, TorznabCatType.TVFOREIGN);
//Category 24: Boxsets/TV (Working)
AddCategoryMapping(24, TorznabCatType.TVFOREIGN);
//Category 31: TVHD (Working)
AddCategoryMapping(31, TorznabCatType.TVHD);
AddCategoryMapping(31, TorznabCatType.TV);
//Category 45: TV-Misc (Working)
AddCategoryMapping(45, TorznabCatType.TV);
AddCategoryMapping(45, TorznabCatType.TVSD);
}
// Audio Books
AddCategoryMapping(37, TorznabCatType.AudioAudiobook);
// Books
AddCategoryMapping(8, TorznabCatType.BooksEbook);
}
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
var loginPage = await RequestStringWithCookies(LoginUrl);
CQ loginDom = loginPage.Content;
var loginPostUrl = loginDom["#login"].Attr("action");
configData.LoadValuesFromJson(configJson);
var pairs = new Dictionary<string, string> {
{ "username", configData.Username.Value },
{ "password", configData.Password.Value }
};
// Get inital cookies
CookieHeader = string.Empty;
var response = await RequestLoginAndFollowRedirect(SiteLink + loginPostUrl, pairs, CookieHeader, true, null, LoginUrl);
await ConfigureIfOK(response.Cookies, response.Content != null && response.Content.Contains("Velkommen tilbage"), () =>
{
CQ dom = response.Content;
var messageEl = dom["inputs"];
var errorMessage = messageEl.Text().Trim();
throw new ExceptionWithConfigData(errorMessage, configData);
});
var profilePage = await RequestStringWithCookies(ProfileUrl, response.Cookies);
CQ profileDom = profilePage.Content;
var passKey = profileDom["input[name=resetkey]"].Parent().Text();
passKey = passKey.Substring(0, passKey.IndexOf(' '));
configData.RSSKey.Value = passKey;
SaveConfig();
return IndexerConfigurationStatus.Completed;
}
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releasesPerPage = 100;
var releases = new List<ReleaseInfo>();
var page = (query.Offset / releasesPerPage);
string episodeSearchUrl;
if (string.IsNullOrEmpty(query.GetQueryString()))
{
episodeSearchUrl = SearchUrl + "?page=" + page;
}
else
{
var cats = MapTorznabCapsToTrackers(query);
var catsUrlPart = string.Join("&", cats.Select(c => $"c{c}=1"));
episodeSearchUrl = string.Format("{0}?search={1}&cat=0&incldead=0&{2}&page={3}", SearchUrl, HttpUtility.UrlEncode(query.GetQueryString()), catsUrlPart, page);
}
var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
try
{
CQ dom = results.Content;
var rows = dom["#torrent-table-wrapper > div"];
foreach (var row in rows.Skip(1))
{
var release = new ReleaseInfo();
var qRow = row.Cq();
var qLink = qRow.Find("#torrent-udgivelse2-users > a").First();
var qDesc = qRow.Find("#torrent-udgivelse2-users > p").FirstOrDefault();
var moviesCatsDanish = new[] { 38, 23, 22, 33, 17 };
var moviesCatsIntl = new[] { 47, 5, 9 };
var moviesCats = configData.OnlyDanishCategories.Value
? moviesCatsDanish
: moviesCatsDanish.Concat(moviesCatsIntl);
var seriesCatsDanish = new[] { 26, 43, 46 };
var seriesCatsIntl = new[] { 4, 21, 24, 31, 45 };
var seriesCats = configData.OnlyDanishCategories.Value
? seriesCatsDanish
: seriesCatsDanish.Concat(seriesCatsIntl);
var catUrl = qRow.Find(".torrent-icon > a").Attr("href");
var cat = catUrl.Substring(catUrl.LastIndexOf('=') + 1);
var catNo = int.Parse(cat);
if (moviesCats.Contains(catNo))
release.Category = TorznabCatType.Movies.ID;
else if (seriesCats.Contains(catNo))
release.Category = TorznabCatType.TV.ID;
else
continue;
releases.Add(release);
var torrentUrl = qLink.Attr("href");
var torrentId = torrentUrl.Substring(torrentUrl.LastIndexOf('=') + 1);
release.MinimumRatio = 1;
release.MinimumSeedTime = 172800;
release.Title = qLink.Attr("title");
release.Description = qDesc != null ? qDesc.InnerText : release.Title;
release.Guid = new Uri(SiteLink + torrentUrl);
release.Comments = new Uri(release.Guid + "#startcomments");
var downloadUrl = $"{SiteLink}download.php?id={torrentId}&rss&passkey={configData.RSSKey.Value}";
release.Link = new Uri(downloadUrl);
var qAdded = qRow.Find("#torrent-added").First();
var addedStr = qAdded.Text().Trim();
release.PublishDate = DateTime.ParseExact(addedStr, "dd-MM-yyyyHH:mm:ss", CultureInfo.InvariantCulture);
release.Seeders = ParseUtil.CoerceInt(qRow.Find("#torrent-seeders").Text().Trim());
release.Peers = ParseUtil.CoerceInt(qRow.Find("#torrent-leechers").Text().Trim()) + release.Seeders;
var sizeStr = qRow.Find("#torrent-size").First().Text();
release.Size = ReleaseInfo.GetBytes(sizeStr);
var infoLink = qRow.Find("#infolink");
var linkContainer = infoLink.Children().First().Children().First();
var url = linkContainer.Attr("href");
var img = linkContainer.Children().First();
var imgUrl = img.Attr("src");
if (imgUrl == "/pic/imdb.png")
{
release.Imdb = long.Parse(url.Substring(url.LastIndexOf('t') + 1));
}
else if (imgUrl == "/pic/TV.png")
{
release.TVDBId = long.Parse(url.Substring(url.LastIndexOf('=') + 1));
}
}
}
catch (Exception ex)
{
OnParseError(results.Content, ex);
}
return releases;
}
public class NxtGnConfigurationData : ConfigurationData
{
public NxtGnConfigurationData()
{
Username = new StringItem { Name = "Username" };
Password = new StringItem { Name = "Password" };
RSSKey = new HiddenItem { Name = "RSSKey" };
OnlyDanishCategories = new BoolItem { Name = "Only Danish Categories" };
}
public StringItem Username { get; private set; }
public StringItem Password { get; private set; }
public HiddenItem RSSKey { get; private set; }
public BoolItem OnlyDanishCategories { get; private set; }
}
}
}

View File

@@ -1,233 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Jackett.Models;
using Newtonsoft.Json.Linq;
using NLog;
using Jackett.Utils;
using System.Net;
using System.Net.Http;
using CsQuery;
using System.Web;
using Jackett.Services;
using Jackett.Utils.Clients;
using System.Text.RegularExpressions;
using Jackett.Models.IndexerConfig;
using System.Globalization;
using Newtonsoft.Json;
using Jackett.Models.IndexerConfig.Bespoke;
namespace Jackett.Indexers
{
public class RuTor : BaseIndexer, IIndexer
{
private string SearchUrl { get { return SiteLink + "search/0/{0}/000/0/{1}"; } }
private string BrowseUrl { get { return SiteLink + "browse/0/{0}/0/0"; } }
readonly static string defaultSiteLink = "http://rutor.org/";
new ConfigurationDataRuTor configData
{
get { return (ConfigurationDataRuTor)base.configData; }
set { base.configData = value; }
}
public RuTor(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
: base(name: "RUTor",
description: "Свободный торрент трекер",
link: "http://rutor.org/",
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataRuTor(defaultSiteLink))
{
TorznabCaps.Categories.Add(TorznabCatType.TVAnime);
TorznabCaps.Categories.Add(TorznabCatType.Movies);
TorznabCaps.Categories.Add(TorznabCatType.Audio);
TorznabCaps.Categories.Add(TorznabCatType.Books);
}
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
configData.LoadValuesFromJson(configJson);
var oldConfig = configData;
var releases = await PerformQuery(new TorznabQuery());
await ConfigureIfOK(string.Empty, releases.Count() > 0, () =>
{
configData = oldConfig;
throw new Exception("Could not find releases from this URL");
});
return IndexerConfigurationStatus.RequiresTesting;
}
protected override void SaveConfig()
{
indexerService.SaveConfig(this as IIndexer, JsonConvert.SerializeObject(configData));
}
// Override to load legacy config format
public override void LoadFromSavedConfiguration(JToken jsonConfig)
{
var json = jsonConfig.ToString();
configData = JsonConvert.DeserializeObject<ConfigurationDataRuTor>(json);
IsConfigured = true;
}
private readonly int CAT_ANY = 0;
private readonly int CAT_FOREIGN_MOVIE = 1;
// private readonly int CAT_OUR_MOVIES = 5;
// private readonly int CAT_POP_SCIFI_MOVIES = 12;
private readonly int CAT_TV_SERIES = 4;
// private readonly int CAT_TV = 6;
// private readonly int CAT_ANIMATION = 7;
private readonly int CAT_ANIME = 10;
private readonly int CAT_MUSIC = 2;
// private readonly int CAT_GAMES = 8;
// private readonly int CAT_SOFTWARE = 9;
// private readonly int CAT_SPORTS_HEALTH = 13;
// private readonly int CAT_HUMOR = 15;
// private readonly int CAT_ECONOMY_LIFE = 14;
private readonly int CAT_BOOKS = 11;
// private readonly int CAT_OTHER = 3;
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>();
var searchString = query.GetQueryString();
var searchCategory = CAT_ANY;
if (query.Categories.Contains(TorznabCatType.TV.ID) ||
query.Categories.Contains(TorznabCatType.TVHD.ID) ||
query.Categories.Contains(TorznabCatType.TVSD.ID))
{
searchCategory = CAT_TV_SERIES;
}
if ((searchCategory == CAT_ANY) &&
(query.Categories.Contains(TorznabCatType.Movies.ID) ||
query.Categories.Contains(TorznabCatType.MoviesForeign.ID) ||
query.Categories.Contains(TorznabCatType.MoviesHD.ID) ||
query.Categories.Contains(TorznabCatType.MoviesSD.ID)))
{
searchCategory = CAT_FOREIGN_MOVIE;
}
if ((searchCategory == CAT_ANY) &&
(query.Categories.Contains(TorznabCatType.TVAnime.ID)))
{
searchCategory = CAT_ANIME;
}
if ((searchCategory == CAT_ANY) &&
(query.Categories.Contains(TorznabCatType.Books.ID)))
{
searchCategory = CAT_BOOKS;
}
if ((searchCategory == CAT_ANY) &&
(query.Categories.Contains(TorznabCatType.Audio.ID) ||
query.Categories.Contains(TorznabCatType.AudioLossless.ID) ||
query.Categories.Contains(TorznabCatType.AudioMP3.ID)))
{
searchCategory = CAT_MUSIC;
}
string queryUrl = string.Empty;
if (string.IsNullOrWhiteSpace(searchString))
{
queryUrl = string.Format(BrowseUrl, searchCategory);
}
else
{
queryUrl = string.Format(SearchUrl, searchCategory, HttpUtility.UrlEncode(searchString.Trim()));
}
var results = await RequestStringWithCookiesAndRetry(queryUrl, string.Empty);
try
{
CQ dom = results.Content;
var rows = dom["#index table tr"];
foreach (var row in rows.Skip(1))
{
var release = new ReleaseInfo();
release.MinimumRatio = 1;
release.MinimumSeedTime = 172800;
var date = StringUtil.StripNonAlphaNumeric(row.Cq().Find("td:eq(0)").Text().Trim()
.Replace("Янв", "01")
.Replace("Фев", "02")
.Replace("Мар", "03")
.Replace("Апр", "04")
.Replace("Май", "05")
.Replace("Июн", "06")
.Replace("Июл", "07")
.Replace("Авг", "08")
.Replace("Сен", "09")
.Replace("Окт", "10")
.Replace("Ноя", "11")
.Replace("Дек", "12"));
release.PublishDate = DateTime.ParseExact(date, "ddMMyy", CultureInfo.InvariantCulture);
var hasTorrent = row.Cq().Find("td:eq(1) a").Length == 3;
var titleIndex = 1;
if (hasTorrent)
titleIndex++;
release.Title = row.Cq().Find("td:eq(1) a:eq(" + titleIndex + ")").Text().Trim();
if (configData.StripRussian.Value)
{
var split = release.Title.IndexOf('/');
if (split > -1)
{
release.Title = release.Title.Substring(split + 1).Trim();
}
}
release.Description = release.Title;
var hasComments = row.Cq().Find("td:eq(2) img").Length > 0;
var sizeCol = 2;
if (hasComments)
sizeCol++;
var sizeStr = StringUtil.StripRegex(row.Cq().Find("td:eq(" + sizeCol + ")").Text(), "[^a-zA-Z0-9\\. -]", " ").Trim();
string[] sizeSplit = sizeStr.Split(' ');
release.Size = ReleaseInfo.GetBytes(sizeSplit[1].ToLower(), ParseUtil.CoerceFloat(sizeSplit[0]));
release.Seeders = ParseUtil.CoerceInt(row.Cq().Find(".green").Text().Trim());
release.Peers = ParseUtil.CoerceInt(row.Cq().Find(".red").Text().Trim()) + release.Seeders;
release.Guid = new Uri(configData.Url.Value + row.Cq().Find("td:eq(1) a:eq(" + titleIndex + ")").Attr("href").Substring(1));
release.Comments = release.Guid;
if (hasTorrent)
{
release.Link = new Uri(row.Cq().Find("td:eq(1) a:eq(0)").Attr("href"));
release.MagnetUri = new Uri(row.Cq().Find("td:eq(1) a:eq(1)").Attr("href"));
}
else
{
release.MagnetUri = new Uri(row.Cq().Find("td:eq(1) a:eq(0)").Attr("href"));
}
releases.Add(release);
}
}
catch (Exception ex)
{
OnParseError(results.Content, ex);
}
return releases;
}
}
}

View File

@@ -1,187 +0,0 @@
using Jackett.Models;
using Jackett.Models.IndexerConfig;
using Jackett.Services;
using Jackett.Utils.Clients;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
namespace Jackett.Indexers
{
public class Rarbg : BaseIndexer, IIndexer
{
readonly static string defaultSiteLink = "https://torrentapi.org/";
private Uri BaseUri
{
get { return new Uri(configData.Url.Value); }
set { configData.Url.Value = value.ToString(); }
}
private string ApiEndpoint { get { return BaseUri + "pubapi_v2.php"; } }
private string TokenUrl { get { return ApiEndpoint + "?get_token=get_token"; } }
private string SearchUrl { get { return ApiEndpoint + "?app_id=jackett_v{0}&mode={1}&format=json_extended&search_string={2}&token={3}"; } }
new ConfigurationDataUrl configData
{
get { return (ConfigurationDataUrl)base.configData; }
set { base.configData = value; }
}
private DateTime lastTokenFetch;
private string token;
readonly TimeSpan TOKEN_DURATION = TimeSpan.FromMinutes(10);
private bool HasValidToken { get { return !string.IsNullOrEmpty(token) && lastTokenFetch > DateTime.Now - TOKEN_DURATION; } }
Dictionary<string, int> categoryLabels;
public Rarbg(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
: base(name: "RARBG",
description: "RARBG",
link: defaultSiteLink,
caps: new TorznabCapabilities(),
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataUrl(defaultSiteLink))
{
categoryLabels = new Dictionary<string, int>();
AddCat(4, TorznabCatType.XXX, "XXX (18+)");
AddCat(14, TorznabCatType.MoviesSD, "Movies/XVID");
AddCat(48, TorznabCatType.MoviesHD, "Movies/XVID/720");
AddCat(17, TorznabCatType.MoviesSD, "Movies/x264");
AddCat(44, TorznabCatType.MoviesHD, "Movies/x264/1080");
AddCat(45, TorznabCatType.MoviesHD, "Movies/x264/720");
AddCat(47, TorznabCatType.Movies3D, "Movies/x264/3D");
AddCat(42, TorznabCatType.MoviesBluRay, "Movies/Full BD");
AddCat(46, TorznabCatType.MoviesBluRay, "Movies/BD Remux");
AddCat(18, TorznabCatType.TVSD, "TV Episodes");
AddCat(41, TorznabCatType.TVHD, "TV HD Episodes");
AddCat(23, TorznabCatType.AudioMP3, "Music/MP3");
AddCat(25, TorznabCatType.AudioLossless, "Music/FLAC");
AddCat(27, TorznabCatType.PCGames, "Games/PC ISO");
AddCat(28, TorznabCatType.PCGames, "Games/PC RIP");
AddCat(40, TorznabCatType.ConsolePS3, "Games/PS3");
AddCat(32, TorznabCatType.ConsoleXbox360, "Games/XBOX-360");
AddCat(33, TorznabCatType.PCISO, "Software/PC ISO");
AddCat(35, TorznabCatType.BooksEbook, "e-Books");
}
void AddCat(int cat, TorznabCategory catType, string label)
{
AddCategoryMapping(cat, catType);
categoryLabels.Add(label, cat);
}
async Task CheckToken()
{
if (!HasValidToken)
{
var result = await RequestStringWithCookiesAndRetry(TokenUrl);
var json = JObject.Parse(result.Content);
token = json.Value<string>("token");
lastTokenFetch = DateTime.Now;
}
}
public 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;
}
public Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
return PerformQuery(query, 0);
}
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query, int attempts = 0)
{
await CheckToken();
var releases = new List<ReleaseInfo>();
var queryStr = HttpUtility.UrlEncode(query.GetQueryString());
var mode = string.IsNullOrEmpty(queryStr) ? "list" : "search";
var episodeSearchUrl = string.Format(SearchUrl, Engine.ConfigService.GetVersion(), mode, queryStr, token);
var cats = string.Join(";", MapTorznabCapsToTrackers(query));
if (!string.IsNullOrEmpty(cats))
{
episodeSearchUrl += "&category=" + cats;
}
var response = await RequestStringWithCookiesAndRetry(episodeSearchUrl, string.Empty);
try
{
var jsonContent = JObject.Parse(response.Content);
int errorCode = jsonContent.Value<int>("error_code");
if (errorCode == 20) // no results found
{
return releases.ToArray();
}
if (errorCode > 0) // too many requests per second
{
if (attempts < 3)
{
await Task.Delay(TimeSpan.FromSeconds(2));
return await PerformQuery(query, ++attempts);
}
else
{
throw new Exception(jsonContent.Value<string>("error"));
}
}
foreach (var item in jsonContent.Value<JArray>("torrent_results"))
{
var release = new ReleaseInfo();
release.Title = item.Value<string>("title");
release.Description = release.Title;
release.Category = MapTrackerCatToNewznab(categoryLabels[item.Value<string>("category")].ToString());
release.MagnetUri = new Uri(item.Value<string>("download"));
release.InfoHash = release.MagnetUri.ToString().Split(':')[3].Split('&')[0];
release.Comments = new Uri(item.Value<string>("info_page"));
release.Guid = release.Comments;
// ex: 2015-08-16 21:25:08 +0000
var dateStr = item.Value<string>("pubdate").Replace(" +0000", "");
var dateTime = DateTime.ParseExact(dateStr, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
release.PublishDate = DateTime.SpecifyKind(dateTime, DateTimeKind.Utc).ToLocalTime();
release.Seeders = item.Value<int>("seeders");
release.Peers = item.Value<int>("leechers") + release.Seeders;
release.Size = item.Value<long>("size");
releases.Add(release);
}
}
catch (Exception ex)
{
OnParseError(response.Content, ex);
}
return releases.ToArray();
}
}
}

View File

@@ -0,0 +1,361 @@
using CsQuery;
using Jackett.Models;
using Jackett.Services;
using Jackett.Utils;
using Jackett.Utils.Clients;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using Jackett.Models.IndexerConfig;
using System.Text.RegularExpressions;
using System.Xml.Linq;
namespace Jackett.Indexers
{
public class RevolutionTT : BaseIndexer, IIndexer
{
private string LandingPageURL { get { return SiteLink + "login.php"; } }
private string LoginUrl { get { return SiteLink + "takelogin.php"; } }
private string GetRSSKeyUrl { get { return SiteLink + "getrss.php"; } }
private string RSSUrl { get { return SiteLink + "rss.php?feed=dl&passkey="; } }
private string SearchUrl { get { return SiteLink + "browse.php"; } }
private string DetailsURL { get { return SiteLink + "details.php?id={0}&hit=1"; } }
new ConfigurationDataBasicLoginWithRSS configData
{
get { return (ConfigurationDataBasicLoginWithRSS)base.configData; }
set { base.configData = value; }
}
public RevolutionTT(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
: base(name: "RevolutionTT",
description: "The Revolution has begun",
link: "https://revolutiontt.me/",
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
manager: i,
client: wc,
logger: l,
p: ps,
downloadBase: "https://revolutiontt.me/download.php/",
configData: new ConfigurationDataBasicLoginWithRSS())
{
/* Original RevolutionTT Categories -
Anime - 23
Appz/Misc - 22
Appz/PC-ISO - 1
E-Book - 36
Games/PC-ISO - 4
Games/PC-Rips - 21
Games/PS3 - 16
Games/Wii - 40
Games/XBOX360 - 39
Handheld/NDS - 35
Handheld/PSP - 34
Mac - 2
Movies/BluRay - 10
Movies/DVDR - 20
Movies/HDx264 - 12
Movies/Packs - 44
Movies/SDx264 - 11
Movies/XviD - 19
Music - 6
Music/FLAC - 8
Music/Packs - 46
MusicVideos - 29
TV/DVDR - 43
TV/HDx264 - 42
TV/Packs - 45
TV/SDx264 - 41
TV/XViD - 7
*/
//AddCategoryMapping("cat_id", TorznabCatType.Console);
AddCategoryMapping("35", TorznabCatType.ConsoleNDS);
AddCategoryMapping("34", TorznabCatType.ConsolePSP);
AddCategoryMapping("40", TorznabCatType.ConsoleWii);
//AddCategoryMapping("cat_id", TorznabCatType.ConsoleXbox);
AddCategoryMapping("39", TorznabCatType.ConsoleXbox360);
//AddCategoryMapping("cat_id", TorznabCatType.ConsoleWiiwareVC);
//AddCategoryMapping("cat_id", TorznabCatType.ConsoleXBOX360DLC);
AddCategoryMapping("16", TorznabCatType.ConsolePS3);
//AddCategoryMapping("cat_id", TorznabCatType.ConsoleOther);
//AddCategoryMapping("cat_id", TorznabCatType.Console3DS);
//AddCategoryMapping("cat_id", TorznabCatType.ConsolePSVita);
AddCategoryMapping("40", TorznabCatType.ConsoleWiiU);
//AddCategoryMapping("cat_id", TorznabCatType.ConsoleXboxOne);
//AddCategoryMapping("cat_id", TorznabCatType.ConsolePS4);
AddCategoryMapping("44", TorznabCatType.Movies);
//AddCategoryMapping("cat_id", TorznabCatType.MoviesForeign);
//AddCategoryMapping("cat_id", TorznabCatType.MoviesOther);
//Movies/DVDR, Movies/SDx264, Movies/XviD
AddMultiCategoryMapping(TorznabCatType.MoviesSD, 20, 11, 19);
//Movies/BluRay, Movies/HDx264
AddMultiCategoryMapping(TorznabCatType.MoviesHD, 10, 12);
//AddCategoryMapping("cat_id", TorznabCatType.Movies3D);
AddCategoryMapping("10", TorznabCatType.MoviesBluRay);
AddCategoryMapping("20", TorznabCatType.MoviesDVD);
//AddCategoryMapping("cat_id", TorznabCatType.MoviesWEBDL);
//Music, Music/Packs
AddMultiCategoryMapping(TorznabCatType.Audio, 6, 46);
//AddCategoryMapping("cat_id", TorznabCatType.AudioMP3);
AddCategoryMapping("29", TorznabCatType.AudioVideo);
//AddCategoryMapping("cat_id", TorznabCatType.AudioAudiobook);
AddCategoryMapping("8", TorznabCatType.AudioLossless);
//AddCategoryMapping("cat_id", TorznabCatType.AudioOther);
//AddCategoryMapping("cat_id", TorznabCatType.AudioForeign);
AddCategoryMapping("21", TorznabCatType.PC);
AddCategoryMapping("22", TorznabCatType.PC0day);
AddCategoryMapping("4", TorznabCatType.PCISO);
AddCategoryMapping("2", TorznabCatType.PCMac);
//AddCategoryMapping("cat_id", TorznabCatType.PCPhoneOther);
//Games/PC-ISO, Games/PC-Rips
AddMultiCategoryMapping(TorznabCatType.PCGames, 4, 21);
//AddCategoryMapping("cat_id", TorznabCatType.PCPhoneIOS);
//AddCategoryMapping("cat_id", TorznabCatType.PCPhoneAndroid);
AddCategoryMapping("45", TorznabCatType.TV);
//AddCategoryMapping("cat_id", TorznabCatType.TVWEBDL);
//AddCategoryMapping("cat_id", TorznabCatType.TVFOREIGN);
//TV/DVDR, TV/SDx264, TV/XViD
AddMultiCategoryMapping(TorznabCatType.TVSD, 43, 41, 7);
AddCategoryMapping("42", TorznabCatType.TVHD);
//AddCategoryMapping("cat_id", TorznabCatType.TVOTHER);
//AddCategoryMapping("cat_id", TorznabCatType.TVSport);
AddCategoryMapping("23", TorznabCatType.TVAnime);
//AddCategoryMapping("cat_id", TorznabCatType.TVDocumentary);
//AddCategoryMapping("cat_id", TorznabCatType.XXX);
//AddCategoryMapping("cat_id", TorznabCatType.XXXDVD);
//AddCategoryMapping("cat_id", TorznabCatType.XXXWMV);
//AddCategoryMapping("cat_id", TorznabCatType.XXXXviD);
//AddCategoryMapping("cat_id", TorznabCatType.XXXx264);
//AddCategoryMapping("cat_id", TorznabCatType.XXXOther);
//AddCategoryMapping("cat_id", TorznabCatType.XXXImageset);
//AddCategoryMapping("cat_id", TorznabCatType.XXXPacks);
//AddCategoryMapping("cat_id", TorznabCatType.Other);
//AddCategoryMapping("cat_id", TorznabCatType.OtherMisc);
//AddCategoryMapping("cat_id", TorznabCatType.OtherHashed);
AddCategoryMapping("36", TorznabCatType.Books);
AddCategoryMapping("36", TorznabCatType.BooksEbook);
//AddCategoryMapping("cat_id", TorznabCatType.BooksComics);
//AddCategoryMapping("cat_id", TorznabCatType.BooksMagazines);
//AddCategoryMapping("cat_id", TorznabCatType.BooksTechnical);
//AddCategoryMapping("cat_id", TorznabCatType.BooksOther);
//AddCategoryMapping("cat_id", TorznabCatType.BooksForeign);
// RSS Textual categories
AddCategoryMapping("Anime", TorznabCatType.TVAnime);
AddCategoryMapping("Appz/Misc", TorznabCatType.PC0day);
AddCategoryMapping("Appz/PC-ISO", TorznabCatType.Books);
AddCategoryMapping("E-Book", TorznabCatType.BooksEbook);
AddCategoryMapping("Games/PC-ISO", TorznabCatType.PCGames);
AddCategoryMapping("Games/PC-Rips", TorznabCatType.PCGames);
AddCategoryMapping("Games/PS3", TorznabCatType.ConsolePS3);
AddCategoryMapping("Games/Wii", TorznabCatType.ConsoleWii);
AddCategoryMapping("Games/XBOX360", TorznabCatType.ConsoleXbox360);
AddCategoryMapping("Handheld/NDS", TorznabCatType.ConsoleNDS);
AddCategoryMapping("Handheld/PSP", TorznabCatType.ConsolePSP);
AddCategoryMapping("Mac", TorznabCatType.PCMac);
AddCategoryMapping("Movies/BluRay", TorznabCatType.MoviesBluRay);
AddCategoryMapping("Movies/DVDR", TorznabCatType.MoviesDVD);
AddCategoryMapping("Movies/HDx264", TorznabCatType.MoviesHD);
AddCategoryMapping("Movies/Packs", TorznabCatType.Movies);
AddCategoryMapping("Movies/SDx264", TorznabCatType.MoviesSD);
AddCategoryMapping("Movies/XviD", TorznabCatType.MoviesSD);
AddCategoryMapping("Music", TorznabCatType.Audio);
AddCategoryMapping("Music/FLAC", TorznabCatType.AudioLossless);
AddCategoryMapping("Music/Packs", TorznabCatType.AudioOther);
AddCategoryMapping("MusicVideos", TorznabCatType.AudioVideo);
AddCategoryMapping("TV/DVDR", TorznabCatType.TV);
AddCategoryMapping("TV/HDx264", TorznabCatType.TVHD);
AddCategoryMapping("TV/Packs", TorznabCatType.TV);
AddCategoryMapping("TV/SDx264", TorznabCatType.TVSD);
AddCategoryMapping("TV/XViD", TorznabCatType.TVSD);
}
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
configData.LoadValuesFromJson(configJson);
var pairs = new Dictionary<string, string> {
{ "username", configData.Username.Value },
{ "password", configData.Password.Value }
};
// need to do an initial request to get PHP session cookie (any better way to do this?)
var homePageLoad = await RequestLoginAndFollowRedirect(LandingPageURL, new Dictionary<string, string> { }, null, true, null, SiteLink);
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, homePageLoad.Cookies, true, null, LandingPageURL);
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("/logout.php"), () =>
{
CQ dom = result.Content;
var messageEl = dom[".error"];
var errorMessage = messageEl.Text().Trim();
throw new ExceptionWithConfigData(errorMessage, configData);
});
// Store RSS key from feed generator page
try
{
var rssParams = new Dictionary<string, string> {
{ "feed", "dl" }
};
var rssPage = await PostDataWithCookies(GetRSSKeyUrl, rssParams, result.Cookies);
var match = Regex.Match(rssPage.Content, "(?<=passkey\\=)([a-zA-z0-9]*)");
configData.RSSKey.Value = match.Success ? match.Value : string.Empty;
if (string.IsNullOrWhiteSpace(configData.RSSKey.Value))
throw new Exception("Failed to get RSS Key");
SaveConfig();
}
catch (Exception e)
{
IsConfigured = false;
throw e;
}
return IndexerConfigurationStatus.RequiresTesting;
}
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>();
var searchString = query.GetQueryString();
var searchUrl = SearchUrl;
// If query is empty, use the RSS Feed
if (string.IsNullOrWhiteSpace(searchString))
{
var rssPage = await RequestStringWithCookiesAndRetry(RSSUrl + configData.RSSKey.Value);
var rssDoc = XDocument.Parse(rssPage.Content);
foreach (var item in rssDoc.Descendants("item"))
{
var title = item.Descendants("title").First().Value;
var description = item.Descendants("description").First().Value;
var link = item.Descendants("link").First().Value;
var date = item.Descendants("pubDate").First().Value;
var torrentIdMatch = Regex.Match(link, "(?<=download\\.php/)([a-zA-z0-9]*)");
var torrentId = torrentIdMatch.Success ? torrentIdMatch.Value : string.Empty;
if (string.IsNullOrWhiteSpace(torrentId))
throw new Exception("Missing torrent id");
var infoMatch = Regex.Match(description, @"Category:\W(?<cat>.*)\W\n\WSize:\W(?<size>.*)\n\WStatus:\W(?<seeders>.*)\Wseeder(.*)\Wand\W(?<leechers>.*)\Wleecher(.*)\n\WAdded:\W(?<added>.*)\n\WDescription:");
if (!infoMatch.Success)
throw new Exception("Unable to find info");
var imdbMatch = Regex.Match(description, "(?<=http://www.imdb.com/title/tt)([0-9]*)");
long? imdbID = null;
if(imdbMatch.Success)
{
long l;
if(long.TryParse(imdbMatch.Value, out l))
{
imdbID = l;
}
}
var release = new ReleaseInfo()
{
Title = title,
Description = title,
Guid = new Uri(string.Format(DetailsURL, torrentId)),
Comments = new Uri(string.Format(DetailsURL, torrentId) + "&tocomm=1"),
PublishDate = DateTime.ParseExact(infoMatch.Groups["added"].Value, "yyyy-MM-dd H:mm:ss", CultureInfo.InvariantCulture), //2015-08-08 21:20:31
Link = new Uri(link),
Seeders = ParseUtil.CoerceInt(infoMatch.Groups["seeders"].Value == "no" ? "0" : infoMatch.Groups["seeders"].Value),
Peers = ParseUtil.CoerceInt(infoMatch.Groups["leechers"].Value == "no" ? "0" : infoMatch.Groups["leechers"].Value),
Size = ReleaseInfo.GetBytes(infoMatch.Groups["size"].Value),
Category = MapTrackerCatToNewznab(infoMatch.Groups["cat"].Value),
Imdb = imdbID
};
// if unknown category, set to "other"
if (release.Category == 0)
release.Category = 7000;
release.Peers += release.Seeders;
releases.Add(release);
}
}
else
{
searchUrl += "?titleonly=1&search=" + HttpUtility.UrlEncode(searchString);
string.Format(SearchUrl, HttpUtility.UrlEncode(searchString));
var cats = MapTorznabCapsToTrackers(query);
if (cats.Count > 0)
{
foreach (var cat in cats)
{
searchUrl += "&c" + cat + "=1";
}
}
var results = await RequestStringWithCookiesAndRetry(searchUrl);
try
{
CQ dom = results.Content;
// table header is the first <tr> in table body, get all rows except this
CQ qRows = dom["#torrents-table > tbody > tr:not(:first-child)"];
foreach (var row in qRows)
{
var release = new ReleaseInfo();
var qRow = row.Cq();
var debug = qRow.Html();
release.MinimumRatio = 1;
release.MinimumSeedTime = 172800;
CQ qLink = qRow.Find(".br_right > a").First();
release.Guid = new Uri(SiteLink + qLink.Attr("href"));
release.Comments = new Uri(SiteLink + qLink.Attr("href") + "&tocomm=1");
release.Title = qLink.Find("b").Text();
release.Description = release.Title;
release.Link = new Uri(SiteLink + qRow.Find("td:nth-child(4) > a").Attr("href"));
var dateString = qRow.Find("td:nth-child(6) nobr")[0].InnerText.Trim();
//"2015-04-25 23:38:12"
//"yyyy-MMM-dd hh:mm:ss"
release.PublishDate = DateTime.ParseExact(dateString, "yyyy-MM-ddHH:mm:ss", CultureInfo.InvariantCulture);
var sizeStr = qRow.Children().ElementAt(6).InnerText.Trim();
release.Size = ReleaseInfo.GetBytes(sizeStr);
release.Seeders = ParseUtil.CoerceInt(qRow.Find("td:nth-child(9)").Text());
release.Peers = release.Seeders + ParseUtil.CoerceInt(qRow.Find("td:nth-child(10)").Text());
var category = qRow.Find(".br_type > a").Attr("href").Replace("browse.php?cat=", string.Empty);
release.Category = MapTrackerCatToNewznab(category);
releases.Add(release);
}
}
catch (Exception ex)
{
OnParseError(results.Content, ex);
}
}
return releases;
}
}
}

View File

@@ -1,124 +1,165 @@
using CsQuery;
using Jackett.Models;
using Jackett.Services;
using Jackett.Utils;
using Jackett.Utils.Clients;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Jackett.Models.IndexerConfig;
namespace Jackett.Indexers
{
class SceneAccess : BaseIndexer, IIndexer
{
private string LoginUrl { get { return SiteLink + "login"; } }
private string SearchUrl { get { return SiteLink + "browse?search={0}&method=2&c27=27&c17=17&c11=11"; } }
new ConfigurationDataBasicLogin configData
{
get { return (ConfigurationDataBasicLogin)base.configData; }
set { base.configData = value; }
}
public SceneAccess(IIndexerManagerService i, IWebClient c, Logger l, IProtectionService ps)
: base(name: "SceneAccess",
description: "Your gateway to the scene",
link: "https://sceneaccess.eu/",
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
manager: i,
client: c,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
{
}
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
configData.LoadValuesFromJson(configJson);
var pairs = new Dictionary<string, string> {
{ "username", configData.Username.Value },
{ "password", configData.Password.Value },
{ "submit", "come on in" }
};
var loginPage = await RequestStringWithCookies(LoginUrl, string.Empty);
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, SiteLink, LoginUrl);
await ConfigureIfOK(result.Cookies + " " + loginPage.Cookies, result.Content != null && result.Content.Contains("nav_profile"), () =>
{
CQ dom = result.Content;
var messageEl = dom["#login_box_desc"];
var errorMessage = messageEl.Text().Trim();
throw new ExceptionWithConfigData(errorMessage, configData);
});
return IndexerConfigurationStatus.RequiresTesting;
}
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>();
var results = await RequestStringWithCookiesAndRetry(string.Format(SearchUrl, query.GetQueryString()));
try
{
CQ dom = results.Content;
var rows = dom["#torrents-table > tbody > tr.tt_row"];
foreach (var row in rows)
{
CQ qRow = row.Cq();
var release = new ReleaseInfo();
release.MinimumRatio = 1;
release.MinimumSeedTime = 129600;
release.Title = qRow.Find(".ttr_name > a").Text();
release.Description = release.Title;
release.Guid = new Uri(SiteLink + "/" + qRow.Find(".ttr_name > a").Attr("href"));
release.Comments = release.Guid;
release.Link = new Uri(SiteLink + "/" + qRow.Find(".td_dl > a").Attr("href"));
var sizeStr = qRow.Find(".ttr_size").Contents()[0].NodeValue;
release.Size = ReleaseInfo.GetBytes(sizeStr);
var timeStr = qRow.Find(".ttr_added").Text();
DateTime time;
if (DateTime.TryParseExact(timeStr, "yyyy-MM-ddHH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out time))
{
release.PublishDate = time;
}
release.Seeders = ParseUtil.CoerceInt(qRow.Find(".ttr_seeders").Text());
release.Peers = ParseUtil.CoerceInt(qRow.Find(".ttr_leechers").Text()) + release.Seeders;
var cat = qRow.Find(".ttr_type a").Attr("href");
if (cat == "?cat=27")
{
release.Category = TorznabCatType.TVHD.ID;
}
else if (cat == "?cat=17")
{
release.Category = TorznabCatType.TVSD.ID;
}
releases.Add(release);
}
}
catch (Exception ex)
{
OnParseError(results.Content, ex);
}
return releases;
}
}
}
using CsQuery;
using Jackett.Models;
using Jackett.Services;
using Jackett.Utils;
using Jackett.Utils.Clients;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Jackett.Models.IndexerConfig;
using System.Web;
namespace Jackett.Indexers
{
class SceneAccess : BaseIndexer, IIndexer
{
private string LoginUrl { get { return SiteLink + "login"; } }
private string SearchUrl { get { return SiteLink + "all?search={0}&method=2"; } }
new ConfigurationDataBasicLogin configData
{
get { return (ConfigurationDataBasicLogin)base.configData; }
set { base.configData = value; }
}
public SceneAccess(IIndexerManagerService i, IWebClient c, Logger l, IProtectionService ps)
: base(name: "SceneAccess",
description: "Your gateway to the scene",
link: "https://sceneaccess.eu/",
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
manager: i,
client: c,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
{
AddCategoryMapping(8, TorznabCatType.MoviesSD);
AddCategoryMapping(22, TorznabCatType.MoviesHD);
AddCategoryMapping(7, TorznabCatType.MoviesSD);
AddCategoryMapping(4, TorznabCatType.Movies);
AddCategoryMapping(27, TorznabCatType.TVHD);
AddCategoryMapping(17, TorznabCatType.TVSD);
AddCategoryMapping(11, TorznabCatType.MoviesSD);
AddCategoryMapping(26, TorznabCatType.TV);
AddCategoryMapping(3, TorznabCatType.PCGames);
AddCategoryMapping(5, TorznabCatType.ConsolePS3);
AddCategoryMapping(20, TorznabCatType.ConsolePSP);
AddCategoryMapping(28, TorznabCatType.TV);
AddCategoryMapping(23, TorznabCatType.Console);
AddCategoryMapping(29, TorznabCatType.Console);
AddCategoryMapping(40, TorznabCatType.AudioLossless);
AddCategoryMapping(13, TorznabCatType.AudioMP3);
AddCategoryMapping(15, TorznabCatType.AudioVideo);
AddCategoryMapping(1, TorznabCatType.PCISO);
AddCategoryMapping(2, TorznabCatType.PCISO);
AddCategoryMapping(14, TorznabCatType.PCISO);
AddCategoryMapping(21, TorznabCatType.Other);
AddCategoryMapping(41, TorznabCatType.MoviesHD);
AddCategoryMapping(42, TorznabCatType.MoviesSD);
AddCategoryMapping(43, TorznabCatType.MoviesSD);
AddCategoryMapping(44, TorznabCatType.TVHD);
AddCategoryMapping(45, TorznabCatType.TVSD);
AddCategoryMapping(12, TorznabCatType.XXXXviD);
AddCategoryMapping(35, TorznabCatType.XXXx264);
AddCategoryMapping(36, TorznabCatType.XXX);
AddCategoryMapping(30, TorznabCatType.MoviesForeign);
AddCategoryMapping(31, TorznabCatType.MoviesForeign);
AddCategoryMapping(32, TorznabCatType.MoviesForeign);
AddCategoryMapping(33, TorznabCatType.TVFOREIGN);
AddCategoryMapping(34, TorznabCatType.TVFOREIGN);
AddCategoryMapping(4, TorznabCatType.Movies);
AddCategoryMapping(37, TorznabCatType.XXX);
AddCategoryMapping(38, TorznabCatType.Audio);
}
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
configData.LoadValuesFromJson(configJson);
var pairs = new Dictionary<string, string> {
{ "username", configData.Username.Value },
{ "password", configData.Password.Value },
{ "submit", "come on in" }
};
var loginPage = await RequestStringWithCookies(LoginUrl, string.Empty);
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, SiteLink, LoginUrl);
await ConfigureIfOK(result.Cookies + " " + loginPage.Cookies, result.Content != null && result.Content.Contains("nav_profile"), () =>
{
CQ dom = result.Content;
var messageEl = dom["#login_box_desc"];
var errorMessage = messageEl.Text().Trim();
throw new ExceptionWithConfigData(errorMessage, configData);
});
return IndexerConfigurationStatus.RequiresTesting;
}
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>();
var results = await RequestStringWithCookiesAndRetry(string.Format(SearchUrl, HttpUtility.UrlEncode(query.GetQueryString())));
try
{
CQ dom = results.Content;
var rows = dom["#torrents-table > tbody > tr.tt_row"];
foreach (var row in rows)
{
CQ qRow = row.Cq();
var release = new ReleaseInfo();
release.MinimumRatio = 1;
release.MinimumSeedTime = 129600;
release.Title = qRow.Find(".ttr_name > a").Text();
release.Description = release.Title;
release.Guid = new Uri(SiteLink + qRow.Find(".ttr_name > a").Attr("href"));
release.Comments = release.Guid;
release.Link = new Uri(SiteLink + qRow.Find(".td_dl > a").Attr("href"));
var sizeStr = qRow.Find(".ttr_size").Contents()[0].NodeValue;
release.Size = ReleaseInfo.GetBytes(sizeStr);
var timeStr = qRow.Find(".ttr_added").Text();
DateTime time;
if (DateTime.TryParseExact(timeStr, "yyyy-MM-ddHH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out time))
{
release.PublishDate = time;
}
release.Seeders = ParseUtil.CoerceInt(qRow.Find(".ttr_seeders").Text());
release.Peers = ParseUtil.CoerceInt(qRow.Find(".ttr_leechers").Text()) + release.Seeders;
var cat = qRow.Find(".ttr_type a").Attr("href").Replace("?cat=",string.Empty);
release.Category = MapTrackerCatToNewznab(cat);
releases.Add(release);
}
}
catch (Exception ex)
{
OnParseError(results.Content, ex);
}
return releases;
}
}
}

View File

@@ -1,132 +0,0 @@
using Jackett.Models;
using Jackett.Services;
using Jackett.Utils;
using Jackett.Utils.Clients;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Xml;
using Jackett.Models.IndexerConfig;
namespace Jackett.Indexers
{
public class ShowRSS : BaseIndexer, IIndexer
{
readonly static string defaultSiteLink = "http://showrss.info/";
private Uri BaseUri
{
get { return new Uri(configData.Url.Value); }
set { configData.Url.Value = value.ToString(); }
}
private string SearchAllUrl { get { return BaseUri + "feeds/all.rss"; } }
new ConfigurationDataUrl configData
{
get { return (ConfigurationDataUrl)base.configData; }
set { base.configData = value; }
}
public ShowRSS(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
: base(name: "ShowRSS",
description: "showRSS is a service that allows you to keep track of your favorite TV shows",
link: defaultSiteLink,
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataUrl(defaultSiteLink))
{
}
public 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.RequiresTesting;
}
// Override to load legacy config format
public override void LoadFromSavedConfiguration(JToken jsonConfig)
{
if (jsonConfig is JObject)
{
BaseUri = new Uri(jsonConfig.Value<string>("base_url"));
SaveConfig();
IsConfigured = true;
return;
}
base.LoadFromSavedConfiguration(jsonConfig);
}
public override Task<byte[]> Download(Uri link)
{
throw new NotImplementedException();
}
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>();
var episodeSearchUrl = string.Format(SearchAllUrl);
var result = await RequestStringWithCookiesAndRetry(episodeSearchUrl, string.Empty);
var xmlDoc = new XmlDocument();
try
{
xmlDoc.LoadXml(result.Content);
ReleaseInfo release;
string serie_title;
foreach (XmlNode node in xmlDoc.GetElementsByTagName("item"))
{
release = new ReleaseInfo();
release.MinimumRatio = 1;
release.MinimumSeedTime = 172800;
serie_title = node.SelectSingleNode(".//*[local-name()='rawtitle']").InnerText;
release.Title = serie_title;
release.Comments = new Uri(node.SelectSingleNode("link").InnerText);
int category = 0;
int.TryParse(node.SelectSingleNode("title").InnerText, out category);
release.Category = category;
var test = node.SelectSingleNode("enclosure");
release.Guid = new Uri(test.Attributes["url"].Value);
release.PublishDate = DateTime.Parse(node.SelectSingleNode("pubDate").InnerText, CultureInfo.InvariantCulture);
release.Description = node.SelectSingleNode("description").InnerText;
release.InfoHash = node.SelectSingleNode("description").InnerText;
release.Size = 0;
release.Seeders = 1;
release.Peers = 1;
release.MagnetUri = new Uri(node.SelectSingleNode("link").InnerText);
releases.Add(release);
}
}
catch (Exception ex)
{
OnParseError(result.Content, ex);
}
return releases;
}
}
}

View File

@@ -1,4 +1,4 @@
using CsQuery;
using CsQuery;
using Jackett.Models;
using Jackett.Services;
using Jackett.Utils;
@@ -8,22 +8,16 @@ using NLog;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
using Jackett.Models.IndexerConfig;
namespace Jackett.Indexers
{
public class SpeedCD : BaseIndexer, IIndexer
{
private string LoginUrl { get { return SiteLink + "take_login.php"; } }
private string LoginUrl { get { return SiteLink + "take.login.php"; } }
private string SearchUrl { get { return SiteLink + "V3/API/API.php"; } }
private string SearchFormData { get { return "c53=1&c49=1&c2=1&c52=1&c41=1&c50=1&c30=1&jxt=4&jxw=b"; } }
private string CommentsUrl { get { return SiteLink + "t/{0}"; } }
private string DownloadUrl { get { return SiteLink + "download.php?torrent={0}"; } }
@@ -37,13 +31,41 @@ namespace Jackett.Indexers
: base(name: "Speed.cd",
description: "Your home now!",
link: "http://speed.cd/",
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
caps: new TorznabCapabilities(),
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
{
AddCategoryMapping("1", TorznabCatType.MoviesOther);
AddCategoryMapping("42", TorznabCatType.Movies);
AddCategoryMapping("32", TorznabCatType.Movies);
AddCategoryMapping("43", TorznabCatType.MoviesHD);
AddCategoryMapping("47", TorznabCatType.Movies);
AddCategoryMapping("28", TorznabCatType.MoviesBluRay);
AddCategoryMapping("48", TorznabCatType.Movies3D);
AddCategoryMapping("40", TorznabCatType.MoviesDVD);
AddCategoryMapping("49", TorznabCatType.TVHD);
AddCategoryMapping("50", TorznabCatType.TVSport);
AddCategoryMapping("52", TorznabCatType.TVHD);
AddCategoryMapping("53", TorznabCatType.TVSD);
AddCategoryMapping("41", TorznabCatType.TV);
AddCategoryMapping("55", TorznabCatType.TV);
AddCategoryMapping("2", TorznabCatType.TV);
AddCategoryMapping("30", TorznabCatType.TVAnime);
AddCategoryMapping("25", TorznabCatType.PCISO);
AddCategoryMapping("39", TorznabCatType.ConsoleWii);
AddCategoryMapping("45", TorznabCatType.ConsolePS3);
AddCategoryMapping("35", TorznabCatType.Console);
AddCategoryMapping("33", TorznabCatType.ConsoleXbox360);
AddCategoryMapping("46", TorznabCatType.PCPhoneOther);
AddCategoryMapping("24", TorznabCatType.PC0day);
AddCategoryMapping("51", TorznabCatType.PCMac);
AddCategoryMapping("27", TorznabCatType.Books);
AddCategoryMapping("26", TorznabCatType.Audio);
AddCategoryMapping("44", TorznabCatType.Audio);
AddCategoryMapping("29", TorznabCatType.AudioVideo);
}
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
@@ -68,10 +90,23 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>();
var formData = HttpUtility.ParseQueryString(SearchFormData);
var formDict = formData.AllKeys.ToDictionary(t => t, t => formData[t]);
formDict.Add("search", query.SanitizedSearchTerm);
var response = await PostDataWithCookiesAndRetry(SearchUrl, formDict);
Dictionary<string, string> qParams = new Dictionary<string, string>();
qParams.Add("jxt", "4");
qParams.Add("jxw", "b");
if (!string.IsNullOrEmpty(query.SanitizedSearchTerm))
{
qParams.Add("search", query.SanitizedSearchTerm);
}
List<string> catList = MapTorznabCapsToTrackers(query);
foreach (string cat in catList)
{
qParams.Add("c" + cat, "1");
}
var response = await PostDataWithCookiesAndRetry(SearchUrl, qParams);
try
{
var jsonResult = JObject.Parse(response.Content);
@@ -90,14 +125,17 @@ namespace Jackett.Indexers
var SizeStr = ((string)jobj["size"]);
release.Size = ReleaseInfo.GetBytes(SizeStr);
var cat = (int)jobj["cat"];
release.Category = MapTrackerCatToNewznab(cat.ToString());
release.Seeders = ParseUtil.CoerceInt((string)jobj["seed"]);
release.Peers = ParseUtil.CoerceInt((string)jobj["leech"]) + release.Seeders;
// ex: Tuesday, May 26, 2015 at 6:00pm
var dateStr = new Regex("title=\"(.*?)\"").Match((string)jobj["added"]).Groups[1].ToString();
dateStr = dateStr.Replace(" at", "");
var dateTime = DateTime.ParseExact(dateStr, "dddd, MMMM d, yyyy h:mmtt", CultureInfo.InvariantCulture);
release.PublishDate = dateTime;
var dateTime = DateTime.ParseExact(dateStr, "dddd, MMMM d, yyyy h:mmtt", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
release.PublishDate = dateTime.ToLocalTime();
releases.Add(release);
}

View File

@@ -1,173 +0,0 @@
using Jackett.Models;
using Jackett.Services;
using Jackett.Utils;
using Jackett.Utils.Clients;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using Jackett.Models.IndexerConfig;
using System.Collections.Specialized;
using Jackett.Models.IndexerConfig.Bespoke;
namespace Jackett.Indexers
{
public class Strike : BaseIndexer, IIndexer
{
readonly static string defaultSiteLink = "https://getstrike.net/";
private Uri BaseUri
{
get { return new Uri(configData.Url.Value); }
set { configData.Url.Value = value.ToString(); }
}
private string SearchUrl { get { return BaseUri + "api/v2/torrents/search/?phrase={0}"; } }
private string DownloadUrl { get { return BaseUri + "torrents/api/download/{0}.torrent"; } }
new ConfigurationDataStrike configData
{
get { return (ConfigurationDataStrike)base.configData; }
set { base.configData = value; }
}
public Strike(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
: base(name: "Strike",
description: "Torrent search engine",
link: defaultSiteLink,
caps: new TorznabCapabilities(),
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataStrike(defaultSiteLink))
{
AddCategoryMapping("Anime", TorznabCatType.TVAnime);
AddCategoryMapping("Applications", TorznabCatType.PC);
AddCategoryMapping("Books", TorznabCatType.Books);
AddCategoryMapping("Games", TorznabCatType.PCGames);
AddCategoryMapping("Movies", TorznabCatType.Movies);
AddCategoryMapping("TV", TorznabCatType.TV);
AddCategoryMapping("XXX", TorznabCatType.XXX);
AddCategoryMapping("Music", TorznabCatType.Audio);
/*AddCategoryMapping("Movies:Highres Movies", TorznabCatType.MoviesHD);
AddCategoryMapping("Movies:3D Movies", TorznabCatType.Movies3D);
AddCategoryMapping("Books:Ebooks", TorznabCatType.BooksEbook);
AddCategoryMapping("Books:Comics", TorznabCatType.BooksComics);
AddCategoryMapping("Books:Audio Books", TorznabCatType.AudioAudiobook);
AddCategoryMapping("Games:XBOX360", TorznabCatType.ConsoleXbox360);
AddCategoryMapping("Games:Wii", TorznabCatType.ConsoleWii);
AddCategoryMapping("Games:PSP", TorznabCatType.ConsolePSP);
AddCategoryMapping("Games:PS3", TorznabCatType.ConsolePS3);
AddCategoryMapping("Games:PC", TorznabCatType.PCGames);
AddCategoryMapping("Games:Android", TorznabCatType.PCPhoneAndroid);
AddCategoryMapping("Music:Mp3", TorznabCatType.AudioMP3);*/
}
public 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;
}
// Override to load legacy config format
public override void LoadFromSavedConfiguration(JToken jsonConfig)
{
if (jsonConfig is JObject)
{
BaseUri = new Uri(jsonConfig.Value<string>("base_url"));
SaveConfig();
IsConfigured = true;
return;
}
base.LoadFromSavedConfiguration(jsonConfig);
}
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
List<ReleaseInfo> releases = new List<ReleaseInfo>();
var queryString = query.GetQueryString();
var searchTerm = string.IsNullOrEmpty(queryString) ? DateTime.Now.Year.ToString() : queryString;
var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchTerm));
var trackerCategories = MapTorznabCapsToTrackers(query, mapChildrenCatsToParent: true);
// This tracker can only search one cat at a time, otherwise search all and filter results
if (trackerCategories.Count == 1)
{
episodeSearchUrl += "&category=" + trackerCategories[0];
}
var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl, string.Empty);
try
{
var jResults = JObject.Parse(results.Content);
foreach (JObject result in (JArray)jResults["torrents"])
{
var release = new ReleaseInfo();
release.MinimumRatio = 1;
release.MinimumSeedTime = 172800;
if (trackerCategories.Count > 0 && !trackerCategories.Contains((string)result["torrent_category"]))
{
continue;
}
release.Category = MapTrackerCatToNewznab((string)result["torrent_category"]);
release.Title = (string)result["torrent_title"];
release.Description = release.Title;
release.Seeders = (int)result["seeds"];
release.Peers = (int)result["leeches"] + release.Seeders;
release.Size = (long)result["size"];
// "Apr 2, 2015", "Apr 12, 2015" (note the spacing)
// some are unix timestamps, some are not.. :/
var dateString = string.Join(" ", ((string)result["upload_date"]).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
float dateVal;
if (ParseUtil.TryCoerceFloat(dateString, out dateVal))
release.PublishDate = DateTimeUtil.UnixTimestampToDateTime(dateVal);
else
release.PublishDate = DateTime.ParseExact(dateString, "MMM d, yyyy", CultureInfo.InvariantCulture);
release.Guid = new Uri((string)result["page"]);
release.Comments = release.Guid;
release.InfoHash = (string)result["torrent_hash"];
release.MagnetUri = new Uri((string)result["magnet_uri"]);
release.Link = new Uri(string.Format(DownloadUrl, release.InfoHash));
releases.Add(release);
}
}
catch (Exception ex)
{
OnParseError(results.Content, ex);
}
return releases;
}
public override Task<byte[]> Download(Uri link)
{
throw new NotImplementedException();
}
}
}

View File

@@ -1,249 +0,0 @@
using Jackett.Models;
using Jackett.Services;
using Jackett.Utils;
using Jackett.Utils.Clients;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using Jackett.Models.IndexerConfig;
namespace Jackett.Indexers
{
public class T411 : BaseIndexer, IIndexer
{
private readonly string CommentsUrl = "";
const string ApiUrl = "http://api.t411.in";
const string AuthUrl = ApiUrl + "/auth";
const string SearchUrl = ApiUrl + "/torrents/search/{0}";
const string DownloadUrl = ApiUrl + "/torrents/download/{0}";
HttpClientHandler handler;
HttpClient client;
new ConfigurationDataLoginTokin configData
{
get { return (ConfigurationDataLoginTokin)base.configData; }
set { base.configData = value; }
}
public T411(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
: base(name: "T411",
description: "French Torrent Tracker",
link: "http://www.t411.in/",
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataLoginTokin())
{
CommentsUrl = SiteLink + "/torrents/{0}";
IsConfigured = false;
handler = new HttpClientHandler
{
AllowAutoRedirect = true
};
client = new HttpClient(handler);
AddCategoryMapping("Film\\/Vidéo", TorznabCatType.Movies);
AddCategoryMapping("Vidéo-clips", TorznabCatType.Other);
AddCategoryMapping("Série TV", TorznabCatType.TV);
AddCategoryMapping("Animation", TorznabCatType.TVAnime);
AddCategoryMapping("Film", TorznabCatType.Movies);
AddCategoryMapping("Concert", TorznabCatType.AudioVideo);
AddCategoryMapping("Documentaire", TorznabCatType.Audio);
AddCategoryMapping("Spectacle", TorznabCatType.TV);
AddCategoryMapping("Sport", TorznabCatType.TVSport);
AddCategoryMapping("Animation Série", TorznabCatType.TVAnime);
AddCategoryMapping("Emission TV", TorznabCatType.TV);
AddCategoryMapping("Application", TorznabCatType.PC0day);
AddCategoryMapping("Linux", TorznabCatType.PC);
AddCategoryMapping("MacOS", TorznabCatType.PCMac);
AddCategoryMapping("Windows", TorznabCatType.PC);
AddCategoryMapping("Smartphone", TorznabCatType.PCPhoneOther);
AddCategoryMapping("Tablette", TorznabCatType.PCPhoneOther);
AddCategoryMapping("Autre", TorznabCatType.PC);
AddCategoryMapping("Formation", TorznabCatType.PC);
AddCategoryMapping("Emulation", TorznabCatType.PC);
AddCategoryMapping("Emulateurs", TorznabCatType.PC);
AddCategoryMapping("Roms", TorznabCatType.PC);
AddCategoryMapping("GPS", TorznabCatType.Other);
AddCategoryMapping("Applications", TorznabCatType.Other);
AddCategoryMapping("Cartes", TorznabCatType.Other);
AddCategoryMapping("Divers", TorznabCatType.Other);
AddCategoryMapping("Audio", TorznabCatType.Audio);
AddCategoryMapping("Karaoke", TorznabCatType.Audio);
AddCategoryMapping("Samples", TorznabCatType.Audio);
AddCategoryMapping("Musique", TorznabCatType.Audio);
AddCategoryMapping("Podcast Radio", TorznabCatType.Audio);
AddCategoryMapping("eBook", TorznabCatType.BooksEbook);
AddCategoryMapping("Audio", TorznabCatType.AudioAudiobook);
AddCategoryMapping("Bds", TorznabCatType.AudioVideo);
AddCategoryMapping("Comics", TorznabCatType.BooksComics);
AddCategoryMapping("Livres", TorznabCatType.Books);
AddCategoryMapping("Mangas", TorznabCatType.BooksForeign);
AddCategoryMapping("Presse", TorznabCatType.BooksMagazines);
AddCategoryMapping("xXx", TorznabCatType.XXX);
AddCategoryMapping("eBooks", TorznabCatType.XXXImageset);
AddCategoryMapping("Jeux vidéo", TorznabCatType.XXX);
AddCategoryMapping("Video", TorznabCatType.XXXDVD);
//AddCategoryMapping("Animation", TorznabCatType.XXX); Used above :/
AddCategoryMapping("Jeu vidéo", TorznabCatType.PCGames);
AddCategoryMapping("Linux", TorznabCatType.PCGames);
AddCategoryMapping("MacOS", TorznabCatType.PCGames);
// AddCategoryMapping("Windows", TorznabCatType.PCGames); Used above :/
AddCategoryMapping("Nintendo", TorznabCatType.Console);
AddCategoryMapping("Sony", TorznabCatType.Console);
AddCategoryMapping("Microsoft", TorznabCatType.PCGames);
AddCategoryMapping("Smartphone", TorznabCatType.PCPhoneOther);
AddCategoryMapping("Tablette", TorznabCatType.PCPhoneOther);
AddCategoryMapping("Autre", TorznabCatType.Other);
AddCategoryMapping("Jeux vidéo", TorznabCatType.Other);
}
async Task<string> GetAuthToken(bool forceFetch = false)
{
if (!forceFetch && configData.LastTokenFetchDateTime > DateTime.Now - TimeSpan.FromHours(48))
{
return configData.ApiToken.Value;
}
var pairs = new Dictionary<string, string> {
{ "username", configData.Username.Value },
{ "password", configData.Password.Value }
};
var content = new FormUrlEncodedContent(pairs);
var response = await client.PostAsync(AuthUrl, content);
var responseContent = await response.Content.ReadAsStringAsync();
var jsonResponse = JObject.Parse(responseContent);
if (jsonResponse["error"] != null)
{
throw new ApplicationException((string)jsonResponse["error"]);
}
configData.ApiToken.Value = (string)jsonResponse["token"];
configData.LastTokenFetchDateTime = DateTime.Now;
return configData.ApiToken.Value;
}
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
configData.LoadValuesFromJson(configJson);
Exception tokenFetchEx = null;
try
{
await GetAuthToken(true);
}
catch (Exception ex)
{
tokenFetchEx = new ExceptionWithConfigData(ex.Message, configData);
}
await ConfigureIfOK(string.Empty, tokenFetchEx == null, () =>
{
throw tokenFetchEx;
});
return IndexerConfigurationStatus.RequiresTesting;
}
// Override to load legacy config format
public override void LoadFromSavedConfiguration(JToken jsonConfig)
{
if (jsonConfig is JObject)
{
configData.ApiToken.Value = jsonConfig.Value<string>("token"); ;
configData.Username.Value = jsonConfig.Value<string>("username");
configData.Password.Value = jsonConfig.Value<string>("password");
SaveConfig();
IsConfigured = true;
return;
}
base.LoadFromSavedConfiguration(jsonConfig);
}
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>();
var searchTerm = string.IsNullOrEmpty(query.SanitizedSearchTerm) ? "%20" : query.SanitizedSearchTerm;
var searchString = searchTerm + " " + query.GetEpisodeSearchString();
var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString));
var message = new HttpRequestMessage();
message.Method = HttpMethod.Get;
message.RequestUri = new Uri(episodeSearchUrl);
message.Headers.TryAddWithoutValidation("Authorization", await GetAuthToken());
var response = await client.SendAsync(message);
var results = await response.Content.ReadAsStringAsync();
var jsonResult = JObject.Parse(results);
try
{
var items = (JArray)jsonResult["torrents"];
foreach (var item in items)
{
var release = new ReleaseInfo();
release.MinimumRatio = 1;
release.MinimumSeedTime = 172800;
var torrentId = (string)item["id"];
release.Link = new Uri(string.Format(DownloadUrl, torrentId));
release.Title = (string)item["name"];
release.Description = release.Title;
release.Comments = new Uri(string.Format(CommentsUrl, (string)item["rewritename"]));
release.Guid = release.Comments;
var dateUtc = DateTime.ParseExact((string)item["added"], "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
release.PublishDate = DateTime.SpecifyKind(dateUtc, DateTimeKind.Utc).ToLocalTime();
release.Seeders = ParseUtil.CoerceInt((string)item["seeders"]);
release.Peers = ParseUtil.CoerceInt((string)item["leechers"]) + release.Seeders;
release.Size = ParseUtil.CoerceLong((string)item["size"]);
release.Category = MapTrackerCatToNewznab((string)item["categoryname"]);
releases.Add(release);
}
}
catch (Exception ex)
{
OnParseError(results, ex);
}
return releases;
}
public override async Task<byte[]> Download(Uri link)
{
var message = new HttpRequestMessage();
message.Method = HttpMethod.Get;
message.RequestUri = link;
message.Headers.TryAddWithoutValidation("Authorization", await GetAuthToken());
var response = await client.SendAsync(message);
return await response.Content.ReadAsByteArrayAsync();
}
}
}

View File

@@ -39,7 +39,7 @@ namespace Jackett.Indexers
public TVChaosUK(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
: base(name: "TV Chaos",
description: "Total Chaos",
link: "https://tvchaosuk.com/",
link: "https://www.tvchaosuk.com/",
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
manager: i,
client: wc,

View File

@@ -1,161 +0,0 @@
using CsQuery;
using Jackett.Models;
using Jackett.Services;
using Jackett.Utils;
using Jackett.Utils.Clients;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
using Jackett.Models.IndexerConfig;
namespace Jackett.Indexers
{
public class ThePirateBay : BaseIndexer, IIndexer
{
readonly static string defaultSiteLink = "https://thepiratebay.mn/";
private Uri BaseUri
{
get { return new Uri(configData.Url.Value); }
set { configData.Url.Value = value.ToString(); }
}
private string SearchUrl { get { return BaseUri + "search/{0}/0/99/208,205"; } }
private string RecentUrl { get { return BaseUri + "recent"; } }
new ConfigurationDataUrl configData
{
get { return (ConfigurationDataUrl)base.configData; }
set { base.configData = value; }
}
public ThePirateBay(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
: base(name: "The Pirate Bay",
description: "The worlds largest bittorrent indexer",
link: defaultSiteLink,
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataUrl(defaultSiteLink))
{
}
public 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;
}
// Override to load legacy config format
public override void LoadFromSavedConfiguration(JToken jsonConfig)
{
if (jsonConfig is JObject)
{
BaseUri = new Uri(jsonConfig.Value<string>("base_url"));
SaveConfig();
IsConfigured = true;
return;
}
base.LoadFromSavedConfiguration(jsonConfig);
}
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>();
var queryStr = HttpUtility.UrlEncode(query.GetQueryString());
var episodeSearchUrl = string.IsNullOrWhiteSpace(queryStr) ? RecentUrl : string.Format(SearchUrl, queryStr);
var response = await RequestStringWithCookiesAndRetry(episodeSearchUrl, string.Empty);
try
{
CQ dom = response.Content;
var rows = dom["#searchResult > tbody > tr"];
foreach (var row in rows)
{
if (row.ChildElements.Count() < 2)
continue;
var release = new ReleaseInfo();
CQ qRow = row.Cq();
CQ qLink = qRow.Find(".detName > .detLink").First();
release.MinimumRatio = 1;
release.MinimumSeedTime = 172800;
release.Title = qLink.Text().Trim();
release.Description = release.Title;
release.Comments = new Uri(BaseUri + qLink.Attr("href").TrimStart('/'));
release.Guid = release.Comments;
var downloadCol = row.ChildElements.ElementAt(1).Cq().Children("a");
release.MagnetUri = new Uri(downloadCol.Attr("href"));
release.InfoHash = release.MagnetUri.ToString().Split(':')[3].Split('&')[0];
var descString = qRow.Find(".detDesc").Text().Trim();
var descParts = descString.Split(',');
var timeString = descParts[0].Split(' ')[1];
if (timeString.Contains(" ago"))
{
release.PublishDate = (DateTime.Now - TimeSpan.FromMinutes(ParseUtil.CoerceInt(timeString.Split(' ')[0])));
}
else if (timeString.Contains("Today"))
{
release.PublishDate = (DateTime.UtcNow - TimeSpan.FromHours(2) - TimeSpan.Parse(timeString.Split(' ')[1])).ToLocalTime();
}
else if (timeString.Contains("Y-day"))
{
release.PublishDate = (DateTime.UtcNow - TimeSpan.FromHours(26) - TimeSpan.Parse(timeString.Split(' ')[1])).ToLocalTime();
}
else if (timeString.Contains(':'))
{
var utc = DateTime.ParseExact(timeString, "MM-dd HH:mm", CultureInfo.InvariantCulture) - TimeSpan.FromHours(2);
release.PublishDate = DateTime.SpecifyKind(utc, DateTimeKind.Utc).ToLocalTime();
}
else
{
var utc = DateTime.ParseExact(timeString, "MM-dd yyyy", CultureInfo.InvariantCulture) - TimeSpan.FromHours(2);
release.PublishDate = DateTime.SpecifyKind(utc, DateTimeKind.Utc).ToLocalTime();
}
release.Size = ReleaseInfo.GetBytes(descParts[1]);
release.Seeders = ParseUtil.CoerceInt(row.ChildElements.ElementAt(2).Cq().Text());
release.Peers = ParseUtil.CoerceInt(row.ChildElements.ElementAt(3).Cq().Text()) + release.Seeders;
releases.Add(release);
}
}
catch (Exception ex)
{
OnParseError(response.Content, ex);
}
return releases.ToArray();
}
public override Task<byte[]> Download(Uri link)
{
throw new NotImplementedException();
}
}
}

View File

@@ -1,212 +0,0 @@
using Jackett.Models;
using Jackett.Services;
using Jackett.Utils;
using Jackett.Utils.Clients;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
using System.Windows.Forms;
using System.Xml;
using System.Linq;
using Jackett.Models.IndexerConfig;
namespace Jackett.Indexers
{
public class Torrentz : BaseIndexer, IIndexer
{
readonly static string defaultSiteLink = "https://torrentz.eu/";
private Uri BaseUri
{
get { return new Uri(configData.Url.Value); }
set { configData.Url.Value = value.ToString(); }
}
private string SearchUrl { get { return BaseUri + "feed_verifiedP?f={0}"; } }
new ConfigurationDataUrl configData
{
get { return (ConfigurationDataUrl)base.configData; }
set { base.configData = value; }
}
public Torrentz(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
: base(name: "Torrentz",
description: "Torrentz is a meta-search engine and a Multisearch. This means we just search other search engines.",
link: defaultSiteLink,
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataUrl(defaultSiteLink))
{
}
public 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;
}
// Override to load legacy config format
public override void LoadFromSavedConfiguration(JToken jsonConfig)
{
if (jsonConfig is JObject)
{
BaseUri = new Uri(jsonConfig.Value<string>("base_url"));
SaveConfig();
IsConfigured = true;
return;
}
base.LoadFromSavedConfiguration(jsonConfig);
}
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>();
var searchString = query.GetQueryString();
var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString.Trim()));
var xmlDoc = new XmlDocument();
string xml = string.Empty;
var result = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
try
{
xmlDoc.LoadXml(result.Content);
ReleaseInfo release;
TorrentzHelper td;
string serie_title;
foreach (XmlNode node in xmlDoc.GetElementsByTagName("item"))
{
release = new ReleaseInfo();
release.MinimumRatio = 1;
release.MinimumSeedTime = 172800;
serie_title = node.SelectSingleNode("title").InnerText;
release.Title = serie_title;
release.Comments = new Uri(node.SelectSingleNode("link").InnerText);
int category = 0;
int.TryParse(node.SelectSingleNode("category").InnerText, out category);
release.Category = category;
release.Guid = new Uri(node.SelectSingleNode("guid").InnerText);
release.PublishDate = DateTime.Parse(node.SelectSingleNode("pubDate").InnerText, CultureInfo.InvariantCulture);
td = new TorrentzHelper(node.SelectSingleNode("description").InnerText);
release.Description = td.Description;
release.InfoHash = td.hash;
release.Size = td.Size;
release.Seeders = td.Seeders;
release.Peers = td.Peers + release.Seeders;
release.MagnetUri = TorrentzHelper.createMagnetLink(td.hash, serie_title);
releases.Add(release);
}
}
catch (Exception ex)
{
OnParseError(xml, ex);
}
return releases;
}
public override Task<byte[]> Download(Uri link)
{
throw new NotImplementedException();
}
}
public class TorrentzHelper
{
public TorrentzHelper(string description)
{
this.Description = description;
if (null == description)
{
this.Description = "";
this.Size = 0;
this.Peers = 0;
this.Seeders = 0;
this.hash = "";
}
else
FillProperties();
}
public static Uri createMagnetLink(string hash, string title)
{
string MagnetLink = "magnet:?xt=urn:btih:{0}&dn={1}&tr={2}";
string Trackers = WebUtility.UrlEncode("udp://tracker.publicbt.com:80&tr=udp://tracker.openbittorrent.com:80&tr=udp://tracker.ccc.de:80&tr=udp://tracker.istole.it:80");
title = WebUtility.UrlEncode(title);
return new Uri(string.Format(MagnetLink, hash, title, Trackers));
}
private void FillProperties()
{
string description = this.Description;
int counter = 0;
while (description.Contains(" "))
{
int nextSpace = description.IndexOf(": ") + 1;
int secondSpace;
if (counter != 0)
secondSpace = description.IndexOf(" ", nextSpace + 1);
else
secondSpace = description.IndexOf(": ", nextSpace + 2) - description.IndexOf(" ", nextSpace);
string val;
if (secondSpace == -1)
{
val = description.Substring(nextSpace).Trim();
description = string.Empty;
}
else
{
val = description.Substring(nextSpace, secondSpace - nextSpace).Trim();
description = description.Substring(secondSpace);
}
switch (counter)
{
case 0:
this.Size = ReleaseInfo.GetBytes(val);
break;
case 1:
this.Seeders = ParseUtil.CoerceInt(val.Contains(",") ? val.Remove(val.IndexOf(","), 1) : val);
break;
case 2:
this.Peers = ParseUtil.CoerceInt(val.Contains(",") ? val.Remove(val.IndexOf(","), 1) : val);
break;
case 3:
this.hash = val;
break;
}
counter++;
}
}
public string Description { get; set; }
public long Size { get; set; }
public int Seeders { get; set; }
public int Peers { get; set; }
public string hash { get; set; }
}
}

View File

@@ -0,0 +1,945 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using CsQuery;
using Jackett.Models;
using Jackett.Models.IndexerConfig.Bespoke;
using Jackett.Services;
using Jackett.Utils;
using Jackett.Utils.Clients;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;
namespace Jackett.Indexers
{
/// <summary>
/// Provider for WiHD Private French Tracker
/// </summary>
public class WiHD : BaseIndexer, IIndexer
{
private string LoginUrl { get { return SiteLink + "login"; } }
private string LoginCheckUrl { get { return SiteLink + "login_check"; } }
private string SearchUrl { get { return SiteLink + "torrent/ajaxfiltertorrent/"; } }
private bool Latency { get { return ConfigData.Latency.Value; } }
private bool DevMode { get { return ConfigData.DevMode.Value; } }
private bool CacheMode { get { return ConfigData.HardDriveCache.Value; } }
private string directory { get { return System.IO.Path.GetTempPath() + "Jackett\\" + MethodBase.GetCurrentMethod().DeclaringType.Name + "\\"; } }
private Dictionary<string, string> emulatedBrowserHeaders = new Dictionary<string, string>();
private CQ fDom = null;
private ConfigurationDataWiHD ConfigData
{
get { return (ConfigurationDataWiHD)configData; }
set { base.configData = value; }
}
public WiHD(IIndexerManagerService i, IWebClient w, Logger l, IProtectionService ps)
: base(
name: "WiHD",
description: "Your World in High Definition",
link: "http://world-in-hd.net/",
caps: new TorznabCapabilities(),
manager: i,
client: w,
logger: l,
p: ps,
downloadBase: "http://world-in-hd.net/torrents/download/",
configData: new ConfigurationDataWiHD())
{
// Clean capabilities
TorznabCaps.Categories.Clear();
// Movies
AddCategoryMapping("565af82b1fd35761568b4572", TorznabCatType.MoviesHD); // 1080P
AddCategoryMapping("565af82b1fd35761568b4574", TorznabCatType.MoviesHD); // 720P
AddCategoryMapping("565af82b1fd35761568b4576", TorznabCatType.MoviesHD); // HDTV
AddCategoryMapping("565af82b1fd35761568b4578", TorznabCatType.MoviesBluRay); // Bluray
AddCategoryMapping("565af82b1fd35761568b457a", TorznabCatType.MoviesBluRay); // Bluray Remux
AddCategoryMapping("565af82b1fd35761568b457c", TorznabCatType.Movies3D); // Bluray 3D
// TV
AddCategoryMapping("565af82d1fd35761568b4587", TorznabCatType.TVHD); // 1080P
AddCategoryMapping("565af82d1fd35761568b4589", TorznabCatType.TVHD); // 720P
AddCategoryMapping("565af82d1fd35761568b458b", TorznabCatType.TVHD); // HDTV
AddCategoryMapping("565af82d1fd35761568b458d", TorznabCatType.TVHD); // Bluray
AddCategoryMapping("565af82d1fd35761568b458f", TorznabCatType.TVHD); // Bluray Remux
AddCategoryMapping("565af82d1fd35761568b4591", TorznabCatType.TVHD); // Bluray 3D
// Anime
AddCategoryMapping("565af82d1fd35761568b459c", TorznabCatType.TVAnime); // 1080P
AddCategoryMapping("565af82d1fd35761568b459e", TorznabCatType.TVAnime); // 720P
AddCategoryMapping("565af82d1fd35761568b45a0", TorznabCatType.TVAnime); // HDTV
AddCategoryMapping("565af82d1fd35761568b45a2", TorznabCatType.TVAnime); // Bluray
AddCategoryMapping("565af82d1fd35761568b45a4", TorznabCatType.TVAnime); // Bluray Remux
AddCategoryMapping("565af82d1fd35761568b45a6", TorznabCatType.TVAnime); // Bluray 3D
// Other
AddCategoryMapping("565af82d1fd35761568b45af", TorznabCatType.PC); // Apps
AddCategoryMapping("565af82d1fd35761568b45b1", TorznabCatType.AudioVideo); // Clips
AddCategoryMapping("565af82d1fd35761568b45b3", TorznabCatType.AudioOther); // Audios Tracks of Movies/TV/Anime
AddCategoryMapping("565af82d1fd35761568b45b5", TorznabCatType.TVDocumentary); // Documentary
AddCategoryMapping("565af82d1fd35761568b45b7", TorznabCatType.MoviesBluRay); // Bluray (ALL)
}
/// <summary>
/// Configure our WiHD Provider
/// </summary>
/// <param name="configJson">Our params in Json</param>
/// <returns>Configuration state</returns>
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
// Retrieve config values set by Jackett's user
ConfigData.LoadValuesFromJson(configJson);
// Check & Validate Config
validateConfig();
// Setting our data for a better emulated browser (maximum security)
// TODO: Encoded Content not supported by Jackett at this time
// emulatedBrowserHeaders.Add("Accept-Encoding", "gzip, deflate");
// If we want to simulate a browser
if (ConfigData.Browser.Value) {
// Clean headers
emulatedBrowserHeaders.Clear();
// Inject headers
emulatedBrowserHeaders.Add("Accept", ConfigData.HeaderAccept.Value);
emulatedBrowserHeaders.Add("Accept-Language", ConfigData.HeaderAcceptLang.Value);
emulatedBrowserHeaders.Add("DNT", Convert.ToInt32(ConfigData.HeaderDNT.Value).ToString());
emulatedBrowserHeaders.Add("Upgrade-Insecure-Requests", Convert.ToInt32(ConfigData.HeaderUpgradeInsecure.Value).ToString());
emulatedBrowserHeaders.Add("User-Agent", ConfigData.HeaderUserAgent.Value);
}
// Getting login form to retrieve CSRF token
var myRequest = new Utils.Clients.WebRequest()
{
Url = LoginUrl
};
// Add our headers to request
myRequest.Headers = emulatedBrowserHeaders;
// Get login page
var loginPage = await webclient.GetString(myRequest);
// Retrieving our CSRF token
CQ loginPageDom = loginPage.Content;
var csrfToken = loginPageDom["input[name=\"_csrf_token\"]"].Last();
// Building login form data
var pairs = new Dictionary<string, string> {
{ "_csrf_token", csrfToken.Attr("value") },
{ "_username", ConfigData.Username.Value },
{ "_password", ConfigData.Password.Value },
{ "_remember_me", "on" },
{ "_submit", "" }
};
// Do the login
var request = new Utils.Clients.WebRequest(){
Cookies = loginPage.Cookies,
PostData = pairs,
Referer = LoginUrl,
Type = RequestType.POST,
Url = LoginUrl,
Headers = emulatedBrowserHeaders
};
// Perform loggin
latencyNow();
output("\nPerform loggin.. with " + LoginCheckUrl);
var response = await RequestLoginAndFollowRedirect(LoginCheckUrl, pairs, loginPage.Cookies, true, null, null);
// Test if we are logged in
await ConfigureIfOK(response.Cookies, response.Content != null && response.Content.Contains("/logout"), () =>
{
// Oops, unable to login
output("-> Login failed", "error");
throw new ExceptionWithConfigData("Failed to login", configData);
});
output("-> Login Success");
return IndexerConfigurationStatus.RequiresTesting;
}
/// <summary>
/// Execute our search query
/// </summary>
/// <param name="query">Query</param>
/// <returns>Releases</returns>
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>();
var torrentRowList = new List<CQ>();
var searchTerm = query.GetQueryString();
var searchUrl = SearchUrl;
int nbResults = 0;
int pageLinkCount = 0;
// Check cache first so we don't query the server (if search term used or not in dev mode)
if (!DevMode && !string.IsNullOrEmpty(searchTerm))
{
lock (cache)
{
// Remove old cache items
CleanCache();
// Search in cache
var cachedResult = cache.Where(i => i.Query == searchTerm).FirstOrDefault();
if (cachedResult != null)
return cachedResult.Results.Select(s => (ReleaseInfo)s.Clone()).ToArray();
}
}
// Add emulated XHR request
emulatedBrowserHeaders.Add("X-Requested-With", "XMLHttpRequest");
// Build our query
var request = buildQuery(searchTerm, query, searchUrl);
// Getting results & Store content
WebClientStringResult results = await queryExec(request);
fDom = results.Content;
try
{
// Find number of results
nbResults = ParseUtil.CoerceInt(Regex.Match(fDom["div.ajaxtotaltorrentcount"].Text(), @"\d+").Value);
// Find torrent rows
var firstPageRows = findTorrentRows();
// Add them to torrents list
torrentRowList.AddRange(firstPageRows.Select(fRow => fRow.Cq()));
// Check if there are pagination links at bottom
Boolean pagination = (nbResults != 0);
// If pagination available
if (pagination)
{
// Calculate numbers of pages available for this search query (Based on number results and number of torrents on first page)
pageLinkCount = (int)Math.Ceiling((double)nbResults / firstPageRows.Length);
}
else {
// Check if we have a minimum of one result
if (firstPageRows.Length >= 1)
{
// Set page count arbitrary to one
pageLinkCount = 1;
}
else
{
output("\nNo result found for your query, please try another search term ...\n", "info");
// No result found for this query
return releases;
}
}
output("\nFound " + nbResults + " result(s) in " + pageLinkCount + " page(s) for this query !");
output("\nThere are " + firstPageRows.Length + " results on the first page !");
// If we have a term used for search and pagination result superior to one
if (!string.IsNullOrWhiteSpace(query.GetQueryString()) && pageLinkCount > 1)
{
// Starting with page #2
for (int i = 2; i <= Math.Min(Int32.Parse(ConfigData.Pages.Value), pageLinkCount); i++)
{
output("\nProcessing page #" + i);
// Request our page
latencyNow();
// Build our query
var pageRequest = buildQuery(searchTerm, query, searchUrl, i);
// Getting results & Store content
WebClientStringResult pageResults = await queryExec(pageRequest);
// Assign response
fDom = pageResults.Content;
// Process page results
var additionalPageRows = findTorrentRows();
// Add them to torrents list
torrentRowList.AddRange(additionalPageRows.Select(fRow => fRow.Cq()));
}
}
// Loop on results
foreach (CQ tRow in torrentRowList)
{
output("\n=>> Torrent #" + (releases.Count + 1));
// Release Name
string name = tRow.Find(".torrent-h3 > h3 > a").Attr("title").ToString();
output("Release: " + name);
// Category
string categoryID = tRow.Find(".category > img").Attr("src").Split('/').Last().ToString();
string categoryName = tRow.Find(".category > img").Attr("title").ToString();
output("Category: " + MapTrackerCatToNewznab(mediaToCategory(categoryID, categoryName)) + " (" + categoryName + ")");
// Uploader
string uploader = tRow.Find(".uploader > span > a").Attr("title").ToString();
output("Uploader: " + uploader);
// Seeders
int seeders = ParseUtil.CoerceInt(Regex.Match(tRow.Find(".seeders")[0].LastChild.ToString(), @"\d+").Value);
output("Seeders: " + seeders);
// Leechers
int leechers = ParseUtil.CoerceInt(Regex.Match(tRow.Find(".leechers")[0].LastChild.ToString(), @"\d+").Value);
output("Leechers: " + leechers);
// Completed
int completed = ParseUtil.CoerceInt(Regex.Match(tRow.Find(".completed")[0].LastChild.ToString(), @"\d+").Value);
output("Completed: " + completed);
// Comments
int comments = ParseUtil.CoerceInt(Regex.Match(tRow.Find(".comments")[0].LastChild.ToString(), @"\d+").Value);
output("Comments: " + comments);
// Size & Publish Date
string infosData = tRow.Find(".torrent-h3 > span")[0].LastChild.ToString().Trim();
IList<string> infosList = infosData.Split('-').Select(s => s.Trim()).Where(s => s != String.Empty).ToList();
// --> Size
var size = ReleaseInfo.GetBytes(infosList[1].Replace("Go", "gb").Replace("Mo", "mb").Replace("Ko", "kb"));
output("Size: " + infosList[1] + " (" + size + " bytes)");
// --> Publish Date
IList<string> clockList = infosList[0].Replace("Il y a", "").Split(',').Select(s => s.Trim()).Where(s => s != String.Empty).ToList();
var clock = agoToDate(clockList);
output("Released on: " + clock.ToString());
// Torrent Details URL
string details = tRow.Find(".torrent-h3 > h3 > a").Attr("href").ToString().TrimStart('/');
Uri detailsLink = new Uri(SiteLink + details);
output("Details: " + detailsLink.AbsoluteUri);
// Torrent Comments URL
Uri commentsLink = new Uri(SiteLink + details + "#tab_2");
output("Comments Link: " + commentsLink.AbsoluteUri);
// Torrent Download URL
string download = tRow.Find(".download-item > a").Attr("href").ToString().TrimStart('/');
Uri downloadLink = new Uri(SiteLink + download);
output("Download Link: " + downloadLink.AbsoluteUri);
// Building release infos
var release = new ReleaseInfo();
release.Category = MapTrackerCatToNewznab(mediaToCategory(categoryID, categoryName));
release.Title = name;
release.Seeders = seeders;
release.Peers = seeders + leechers;
release.MinimumRatio = 1;
release.MinimumSeedTime = 345600;
release.PublishDate = clock;
release.Size = size;
release.Guid = detailsLink;
release.Comments = commentsLink;
release.Link = downloadLink;
releases.Add(release);
}
}
catch (Exception ex)
{
OnParseError("Error, unable to parse result \n" + ex.StackTrace, ex);
}
finally
{
// Remove our XHR request header
emulatedBrowserHeaders.Remove("X-Requested-With");
}
// Return found releases
return releases;
}
/// <summary>
/// Build query to process
/// </summary>
/// <param name="term">Term to search</param>
/// <param name="query">Torznab Query for categories mapping</param>
/// <param name="url">Search url for provider</param>
/// <param name="page">Page number to request</param>
/// <returns>URL to query for parsing and processing results</returns>
private string buildQuery(string term, TorznabQuery query, string url, int page = 1)
{
var parameters = new NameValueCollection();
List<string> categoriesList = MapTorznabCapsToTrackers(query);
string categories = null;
// If search term not provided
if (string.IsNullOrWhiteSpace(term))
{
// Showing all torrents (just for output function)
term = "null";
}
// Encode & Add search term to URL
url += Uri.EscapeDataString(term);
// Check if we are processing a new page
if (page > 1)
{
// Adding page number to query
url += "/" + page.ToString();
}
// Adding interrogation point
url += "?";
// Building our tracker query
parameters.Add("exclu", Convert.ToInt32(ConfigData.Exclusive.Value).ToString());
parameters.Add("freeleech", Convert.ToInt32(ConfigData.Freeleech.Value).ToString());
parameters.Add("reseed", Convert.ToInt32(ConfigData.Reseed.Value).ToString());
// Loop on Categories needed
foreach (string category in categoriesList)
{
// If last, build !
if(categoriesList.Last() == category)
{
// Adding previous categories to URL with latest category
parameters.Add(Uri.EscapeDataString("subcat[]"), category + categories);
}
else
{
// Build categories parameter
categories += "&" + Uri.EscapeDataString("subcat[]") + "=" + category;
}
}
// Add timestamp as a query param (for no caching)
parameters.Add("_", UnixTimeNow().ToString());
// Building our query -- Cannot use GetQueryString due to UrlEncode (generating wrong subcat[] param)
url += string.Join("&", parameters.AllKeys.Select(a => a + "=" + parameters[a]));
output("\nBuilded query for \"" + term + "\"... " + url);
// Return our search url
return url;
}
/// <summary>
/// Switch Method for Querying
/// </summary>
/// <param name="request">URL created by Query Builder</param>
/// <returns>Results from query</returns>
private async Task<WebClientStringResult> queryExec(string request)
{
WebClientStringResult results = null;
// Switch in we are in DEV mode with Hard Drive Cache or not
if (DevMode && CacheMode)
{
// Check Cache before querying and load previous results if available
results = await queryCache(request);
}
else
{
// Querying tracker directly
results = await queryTracker(request);
}
return results;
}
/// <summary>
/// Get Torrents Page from Cache by Query Provided
/// </summary>
/// <param name="request">URL created by Query Builder</param>
/// <returns>Results from query</returns>
private async Task<WebClientStringResult> queryCache(string request)
{
WebClientStringResult results = null;
// Create Directory if not exist
System.IO.Directory.CreateDirectory(directory);
// Clean Storage Provider Directory from outdated cached queries
cleanCacheStorage();
// Remove timestamp from query
string file = string.Join("&", Regex.Split(request, "&").Where(s => !Regex.IsMatch(s, @"_=\d")).ToList());
// Create fingerprint for request
file = directory + file.GetHashCode() + ".json";
// Checking modes states
if (System.IO.File.Exists(file))
{
// File exist... loading it right now !
output("Loading results from hard drive cache ..." + request.GetHashCode() + ".json");
results = JsonConvert.DeserializeObject<WebClientStringResult>(System.IO.File.ReadAllText(file));
}
else
{
// No cached file found, querying tracker directly
results = await queryTracker(request);
// Cached file didn't exist for our query, writing it right now !
output("Writing results to hard drive cache ..." + request.GetHashCode() + ".json");
System.IO.File.WriteAllText(file, JsonConvert.SerializeObject(results));
}
return results;
}
/// <summary>
/// Get Torrents Page from Tracker by Query Provided
/// </summary>
/// <param name="request">URL created by Query Builder</param>
/// <returns>Results from query</returns>
private async Task<WebClientStringResult> queryTracker(string request)
{
WebClientStringResult results = null;
// Cache mode not enabled or cached file didn't exist for our query
output("\nQuerying tracker for results....");
// Request our first page
latencyNow();
results = await RequestStringWithCookiesAndRetry(request, null, null, emulatedBrowserHeaders);
// Return results from tracker
return results;
}
/// <summary>
/// Clean Hard Drive Cache Storage
/// </summary>
/// <param name="force">Force Provider Folder deletion</param>
private void cleanCacheStorage(Boolean force = false)
{
// Check cleaning method
if (force)
{
// Deleting Provider Storage folder and all files recursively
output("\nDeleting Provider Storage folder and all files recursively ...");
// Check if directory exist
if (System.IO.Directory.Exists(directory))
{
// Delete storage directory of provider
System.IO.Directory.Delete(directory, true);
output("-> Storage folder deleted successfully.");
}
else
{
// No directory, so nothing to do
output("-> No Storage folder found for this provider !");
}
}
else
{
int i = 0;
// Check if there is file older than ... and delete them
output("\nCleaning Provider Storage folder... in progress.");
System.IO.Directory.GetFiles(directory)
.Select(f => new System.IO.FileInfo(f))
.Where(f => f.LastAccessTime < DateTime.Now.AddMilliseconds(-Convert.ToInt32(ConfigData.HardDriveCacheKeepTime.Value)))
.ToList()
.ForEach(f => {
output("Deleting cached file << " + f.Name + " >> ... done.");
f.Delete();
i++;
});
// Inform on what was cleaned during process
if (i > 0)
{
output("-> Deleted " + i + " cached files during cleaning.");
}
else {
output("-> Nothing deleted during cleaning.");
}
}
}
/// <summary>
/// Generate a random fake latency to avoid detection on tracker side
/// </summary>
private void latencyNow()
{
// Need latency ?
if(Latency)
{
// Generate a random value in our range
var random = new Random(DateTime.Now.Millisecond);
int waiting = random.Next(Convert.ToInt32(ConfigData.LatencyStart.Value), Convert.ToInt32(ConfigData.LatencyEnd.Value));
output("\nLatency Faker => Sleeping for " + waiting + " ms...");
// Sleep now...
System.Threading.Thread.Sleep(waiting);
}
}
/// <summary>
/// Generate an UTC Unix TimeStamp
/// </summary>
/// <returns>Unix TimeStamp</returns>
private long UnixTimeNow()
{
var timeSpan = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0));
return (long)timeSpan.TotalSeconds;
}
/// <summary>
/// Find torrent rows in search pages
/// </summary>
/// <returns>JQuery Object</returns>
private CQ findTorrentRows()
{
// Return all occurencis of torrents found
return fDom[".torrent-item"];
}
/// <summary>
/// Convert Ago date to DateTime
/// </summary>
/// <param name="clockList"></param>
/// <returns>A DateTime</returns>
private DateTime agoToDate(IList<string> clockList)
{
DateTime release = DateTime.Now;
foreach(var ago in clockList)
{
// Check for years
if(ago.Contains("Années") || ago.Contains("Année"))
{
// Number of years to remove
int years = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
// Removing
release = release.AddYears(-years);
continue;
}
// Check for months
else if (ago.Contains("Mois"))
{
// Number of months to remove
int months = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
// Removing
release = release.AddMonths(-months);
continue;
}
// Check for days
else if (ago.Contains("Jours") || ago.Contains("Jour"))
{
// Number of days to remove
int days = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
// Removing
release = release.AddDays(-days);
continue;
}
// Check for hours
else if (ago.Contains("Heures") || ago.Contains("Heure"))
{
// Number of hours to remove
int hours = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
// Removing
release = release.AddHours(-hours);
continue;
}
// Check for minutes
else if (ago.Contains("Minutes") || ago.Contains("Minute"))
{
// Number of minutes to remove
int minutes = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
// Removing
release = release.AddMinutes(-minutes);
continue;
}
// Check for seconds
else if (ago.Contains("Secondes") || ago.Contains("Seconde"))
{
// Number of seconds to remove
int seconds = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
// Removing
release = release.AddSeconds(-seconds);
continue;
}
else
{
output("Unable to detect release date of torrent", "error");
//throw new Exception("Unable to detect release date of torrent");
}
}
return release;
}
/// <summary>
/// Retrieve category ID from media ID
/// </summary>
/// <param name="media">Media ID</param>
/// <returns>Category ID</returns>
private string mediaToCategory(string media, string name)
{
// Declare our Dictionnary -- Media ID (key) <-> Category ID (value)
Dictionary<string, string> dictionary = new Dictionary<string, string>();
// Movies
dictionary.Add("565af82b1fd35761568b4573", "565af82b1fd35761568b4572"); // 1080P
dictionary.Add("565af82b1fd35761568b4575", "565af82b1fd35761568b4574"); // 720P
dictionary.Add("565af82b1fd35761568b4577", "565af82b1fd35761568b4576"); // HDTV
dictionary.Add("565af82b1fd35761568b4579", "565af82b1fd35761568b4578"); // Bluray
dictionary.Add("565af82b1fd35761568b457b", "565af82b1fd35761568b457a"); // Bluray Remux
dictionary.Add("565af82b1fd35761568b457d", "565af82b1fd35761568b457c"); // Bluray 3D
// TV
dictionary.Add("565af82d1fd35761568b4588", "565af82d1fd35761568b4587"); // 1080P
dictionary.Add("565af82d1fd35761568b458a", "565af82d1fd35761568b4589"); // 720P
dictionary.Add("565af82d1fd35761568b458c", "565af82d1fd35761568b458b"); // HDTV
dictionary.Add("565af82d1fd35761568b458e", "565af82d1fd35761568b458d"); // Bluray
dictionary.Add("565af82d1fd35761568b4590", "565af82d1fd35761568b458f"); // Bluray Remux
dictionary.Add("565af82d1fd35761568b4592", "565af82d1fd35761568b4591"); // Bluray 3D
// Anime
dictionary.Add("565af82d1fd35761568b459d", "565af82d1fd35761568b459c"); // 1080P
dictionary.Add("565af82d1fd35761568b459f", "565af82d1fd35761568b459e"); // 720P
dictionary.Add("565af82d1fd35761568b45a1", "565af82d1fd35761568b45a0"); // HDTV
dictionary.Add("565af82d1fd35761568b45a3", "565af82d1fd35761568b45a2"); // Bluray
dictionary.Add("565af82d1fd35761568b45a5", "565af82d1fd35761568b45a4"); // Bluray Remux
// BUG ~~ Media ID for Anime BR 3D is same as TV BR 3D ~~
//dictionary.Add("565af82d1fd35761568b4592", "565af82d1fd35761568b45a6"); // Bluray 3D
// Other
dictionary.Add("565af82d1fd35761568b45b0", "565af82d1fd35761568b45af"); // Apps
dictionary.Add("565af82d1fd35761568b45b2", "565af82d1fd35761568b45b1"); // Clips
dictionary.Add("565af82d1fd35761568b45b4", "565af82d1fd35761568b45b3"); // Audios Tracks of Movies/TV/Anime
dictionary.Add("565af82d1fd35761568b45b6", "565af82d1fd35761568b45b5"); // Documentary
dictionary.Add("565af82d1fd35761568b45b8", "565af82d1fd35761568b45b7"); // Bluray (ALL)
// Check if we know this media ID
if (dictionary.ContainsKey(media))
{
// Due to a bug on tracker side, check for a specific id/name as image is same for TV/Anime BR 3D
if(media == "565af82d1fd35761568b4592" && name == "Animations - Bluray 3D")
{
// If it's an Anime BR 3D
return "565af82d1fd35761568b45a6";
}
else
{
// Return category ID for media ID
return dictionary[media];
}
}
else
{
// Media ID unknown
throw new Exception("Media ID Unknow !");
}
}
/// <summary>
/// Output message for logging or developpment (console)
/// </summary>
/// <param name="message">Message to output</param>
/// <param name="level">Level for Logger</param>
private void output(string message, string level = "debug")
{
// Check if we are in dev mode
if(DevMode)
{
// Output message to console
Console.WriteLine(message);
}
else
{
// Send message to logger with level
switch (level)
{
default:
goto case "debug";
case "debug":
// Only if Debug Level Enabled on Jackett
if(Engine.Logger.IsDebugEnabled)
{
logger.Debug(message);
}
break;
case "info":
logger.Info(message);
break;
case "error":
logger.Error(message);
break;
}
}
}
/// <summary>
/// Validate Config entered by user on Jackett
/// </summary>
private void validateConfig()
{
output("\nValidating Settings ... \n");
// Check Username Setting
if (string.IsNullOrEmpty(ConfigData.Username.Value))
{
throw new ExceptionWithConfigData("You must provide a username for this tracker to login !", ConfigData);
}
else
{
output("Validated Setting -- Username (auth) => " + ConfigData.Username.Value.ToString());
}
// Check Password Setting
if (string.IsNullOrEmpty(ConfigData.Password.Value))
{
throw new ExceptionWithConfigData("You must provide a password with your username for this tracker to login !", ConfigData);
}
else
{
output("Validated Setting -- Password (auth) => " + ConfigData.Password.Value.ToString());
}
// Check Max Page Setting
if (!string.IsNullOrEmpty(ConfigData.Pages.Value))
{
try
{
output("Validated Setting -- Max Pages => " + Convert.ToInt32(ConfigData.Pages.Value));
}
catch (Exception)
{
throw new ExceptionWithConfigData("Please enter a numeric maximum number of pages to crawl !", ConfigData);
}
}
else
{
throw new ExceptionWithConfigData("Please enter a maximum number of pages to crawl !", ConfigData);
}
// Check Latency Setting
if (ConfigData.Latency.Value)
{
output("\nValidated Setting -- Latency Simulation enabled");
// Check Latency Start Setting
if (!string.IsNullOrEmpty(ConfigData.LatencyStart.Value))
{
try
{
output("Validated Setting -- Latency Start => " + Convert.ToInt32(ConfigData.LatencyStart.Value));
}
catch (Exception)
{
throw new ExceptionWithConfigData("Please enter a numeric latency start in ms !", ConfigData);
}
}
else
{
throw new ExceptionWithConfigData("Latency Simulation enabled, Please enter a start latency !", ConfigData);
}
// Check Latency End Setting
if (!string.IsNullOrEmpty(ConfigData.LatencyEnd.Value))
{
try
{
output("Validated Setting -- Latency End => " + Convert.ToInt32(ConfigData.LatencyEnd.Value));
}
catch (Exception)
{
throw new ExceptionWithConfigData("Please enter a numeric latency end in ms !", ConfigData);
}
}
else
{
throw new ExceptionWithConfigData("Latency Simulation enabled, Please enter a end latency !", ConfigData);
}
}
// Check Browser Setting
if (ConfigData.Browser.Value)
{
output("\nValidated Setting -- Browser Simulation enabled");
// Check ACCEPT header Setting
if (string.IsNullOrEmpty(ConfigData.HeaderAccept.Value))
{
throw new ExceptionWithConfigData("Browser Simulation enabled, Please enter an ACCEPT header !", ConfigData);
}
else
{
output("Validated Setting -- ACCEPT (header) => " + ConfigData.HeaderAccept.Value.ToString());
}
// Check ACCEPT-LANG header Setting
if (string.IsNullOrEmpty(ConfigData.HeaderAcceptLang.Value))
{
throw new ExceptionWithConfigData("Browser Simulation enabled, Please enter an ACCEPT-LANG header !", ConfigData);
}
else
{
output("Validated Setting -- ACCEPT-LANG (header) => " + ConfigData.HeaderAcceptLang.Value.ToString());
}
// Check USER-AGENT header Setting
if (string.IsNullOrEmpty(ConfigData.HeaderUserAgent.Value))
{
throw new ExceptionWithConfigData("Browser Simulation enabled, Please enter an USER-AGENT header !", ConfigData);
}
else
{
output("Validated Setting -- USER-AGENT (header) => " + ConfigData.HeaderUserAgent.Value.ToString());
}
}
// Check Dev Cache Settings
if (ConfigData.HardDriveCache.Value == true)
{
output("\nValidated Setting -- DEV Hard Drive Cache enabled");
// Check if Dev Mode enabled !
if (!ConfigData.DevMode.Value)
{
throw new ExceptionWithConfigData("Hard Drive is enabled but not in DEV MODE, Please enable DEV MODE !", ConfigData);
}
// Check Cache Keep Time Setting
if (!string.IsNullOrEmpty(ConfigData.HardDriveCacheKeepTime.Value))
{
try
{
output("Validated Setting -- Cache Keep Time (ms) => " + Convert.ToInt32(ConfigData.HardDriveCacheKeepTime.Value));
}
catch (Exception)
{
throw new ExceptionWithConfigData("Please enter a numeric hard drive keep time in ms !", ConfigData);
}
}
else
{
throw new ExceptionWithConfigData("Hard Drive Cache enabled, Please enter a maximum keep time for cache !", ConfigData);
}
}
else
{
// Delete cache if previously existed
cleanCacheStorage(true);
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More