Compare commits

..

8 Commits

Author SHA1 Message Date
Kayomani
49fa67e64e Update version 2015-09-21 20:05:44 +01:00
Kayomani
770fc83ee8 ShowRSS should use raw title #173 2015-09-21 19:58:17 +01:00
Kayomani
e373bb6916 Synology config #182 2015-09-21 19:42:17 +01:00
Kayomani
f4a1f69063 Merge branch 'master' into develop 2015-09-21 19:30:24 +01:00
Kayomani
ae6504dd62 Merge pull request #180 from Kantraz/patch-2
Update NxtGn.cs
2015-09-21 19:28:15 +01:00
Kayomani
df4f1ee69f #183 T411 Category mapping 2015-09-21 19:26:15 +01:00
Kayomani
6b503711fd #181 Fix links are not cleaned before being sent to the webui. Fix failed requests not being forwarded to the caller. Add size display to web ui. 2015-09-21 18:48:53 +01:00
Kantraz
c81bb20684 Update NxtGn.cs 2015-09-18 14:21:22 +02:00
14 changed files with 1781 additions and 1632 deletions

View File

@@ -1,32 +1,33 @@
rmdir /s /q build.windows
rmdir /s /q build.mono
rmdir /s /q Output
cd src
Msbuild Jackett.sln /t:Clean,Build /p:Configuration=Release /verbosity:minimal
cd ..
xcopy src\Jackett.Console\bin\Release build.windows\ /e /y
copy /Y src\Jackett.Service\bin\Release\JackettService.exe build.windows\JackettService.exe
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 LICENSE build.windows\LICENSE
copy /Y README.md build.windows\README.md
cd src
Msbuild Jackett.sln /t:Clean
call "C:\Program Files (x86)\Mono\bin\xbuild.bat" Jackett.sln /t:Build /p:Configuration=Release /verbosity:minimal
cd ..
xcopy src\Jackett.Console\bin\Release build.mono\ /e /y
copy /Y src\Jackett.Service\bin\Release\JackettService.exe build.mono\JackettService.exe
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 LICENSE build.mono\LICENSE
copy /Y README.md build.mono\README.md
iscc Installer.iss
rmdir /s /q build.windows
rmdir /s /q build.mono
rmdir /s /q Output
cd src
Msbuild Jackett.sln /t:Clean,Build /p:Configuration=Release /verbosity:minimal
cd ..
xcopy src\Jackett.Console\bin\Release build.windows\ /e /y
copy /Y src\Jackett.Service\bin\Release\JackettService.exe build.windows\JackettService.exe
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 LICENSE build.windows\LICENSE
copy /Y README.md build.windows\README.md
cd src
Msbuild Jackett.sln /t:Clean
call "C:\Program Files (x86)\Mono\bin\xbuild.bat" Jackett.sln /t:Build /p:Configuration=Release /verbosity:minimal
cd ..
xcopy src\Jackett.Console\bin\Release build.mono\ /e /y
copy /Y src\Jackett.Service\bin\Release\JackettService.exe build.mono\JackettService.exe
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 LICENSE build.mono\LICENSE
copy /Y README.md build.mono\README.md
copy /Y Upstart.config build.mono\Upstart.config
iscc Installer.iss

View File

@@ -55,6 +55,14 @@ We were previously focused on TV but are working on extending searches to allow
* [Torrentz](https://torrentz.eu/)
* [TV Chaos UK](https://tvchaosuk.com/)
#### Installation on Windows
Grab the latest release from the [website](http://jackett.net/Download).
We recommend you install Jackett as a Windows service using the supplied installer. When installed as a service the tray icon acts as a way to open/start/stop Jackett. If you opted to not install it as a service then Jackett will run its web server from the tray tool.
Jackett can also be run from the command line using JackettConsole.exe if you would like to see log messages (Ensure the server isn't already running from the tray/service).
#### Installation on Linux/OSX
1. Install [Mono 4](http://www.mono-project.com/download/) or better
2. Install libcurl:
@@ -63,15 +71,14 @@ We were previously focused on TV but are working on extending searches to allow
* 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 [website](http://jackett.net/Download) and run Jackett using mono with the command "mono JackettConsole.exe".
#### Installation on Windows
Grab the latest release from the [web site](http://jackett.net/Download).
We recommend you install Jackett as a Windows service using the supplied installer. When installed as a service the tray icon acts as a way to open/start/stop Jackett. If you opted to not install it as a service then Jackett will run its web server from the tray tool.
Jackett can also be run from the command line using JackettConsole.exe if you would like to see log messages (Ensure the server isn't already running from the tray/service).
#### 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.
#### Troubleshooting

20
Upstart.config Normal file
View File

@@ -0,0 +1,20 @@
author "sea3pea0"
description "Upstart Script to run NzbDrone as a service on Ubuntu/Debian based systems, as well as others"
#Set username for the process. Should probably be what you use for logging in
setuid {username to run jackett}
setgid users
#This is the install directory. If you installed using a deb package or the NzbDrone Repository you do not need to change this
env DIR=/opt/Jackett
env LD_LIBRARY_PATH=/usr/local/nzbdrone/lib
start on runlevel [2345]
stop on runlevel [016]
respawn
script
chdir $DIR
exec /volume1/@appstore/Mono/usr/bin/mono --debug JackettConsole.exe
end script

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,7 @@
<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>
@@ -202,6 +203,8 @@
<th>First Seen</th>
<th>Tracker</th>
<th>Name</th>
<th>Size</th>
<th>Size</th>
<th>Category</th>
<th>Seeds</th>
<th>Leechers</th>
@@ -217,6 +220,8 @@
<td>{{jacketTimespan FirstSeen}}</td>
<td>{{Tracker}}</td>
<td><a href="{{Comments}}">{{Title}}</a></td>
<td>{{Size}}</td>
<td>{{jacketSize Size}}</td>
<td>{{CategoryDesc}}</td>
<td>{{Seeders}}</td>
<td>{{Peers}}</td>
@@ -296,6 +301,8 @@
<th>Published</th>
<th>Tracker</th>
<th>Name</th>
<th>Size</th>
<th>Size</th>
<th>Category</th>
<th>Seeds</th>
<th>Leechers</th>
@@ -309,6 +316,8 @@
<td>{{jacketTimespan PublishDate}}</td>
<td>{{Tracker}}</td>
<td><a href="{{Comments}}">{{Title}}</a></td>
<td>{{Size}}</td>
<td>{{jacketSize Size}}</td>
<td>{{CategoryDesc}}</td>
<td>{{Seeders}}</td>
<td>{{Peers}}</td>

View File

@@ -0,0 +1,6 @@
/*
2015 Jason Mulligan
@version 3.1.2
*/
"use strict"; !function (a) { var b = /b$/, c = { bits: ["B", "kb", "Mb", "Gb", "Tb", "Pb", "Eb", "Zb", "Yb"], bytes: ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"] }, d = function (a) { var d = void 0 === arguments[1] ? {} : arguments[1], e = [], f = !1, g = 0, h = void 0, i = void 0, j = void 0, k = void 0, l = void 0, m = void 0, n = void 0, o = void 0, p = void 0, q = void 0, r = void 0; if (isNaN(a)) throw new Error("Invalid arguments"); return j = d.bits === !0, p = d.unix === !0, i = void 0 !== d.base ? d.base : 2, o = void 0 !== d.round ? d.round : p ? 1 : 2, q = void 0 !== d.spacer ? d.spacer : p ? "" : " ", r = void 0 !== d.suffixes ? d.suffixes : {}, n = void 0 !== d.output ? d.output : "string", h = void 0 !== d.exponent ? d.exponent : -1, m = Number(a), l = 0 > m, k = i > 2 ? 1e3 : 1024, l && (m = -m), 0 === m ? (e[0] = 0, e[1] = p ? "" : "B") : ((-1 === h || isNaN(h)) && (h = Math.floor(Math.log(m) / Math.log(k))), h > 8 && (g = 1e3 * g * (h - 8), h = 8), g = 2 === i ? m / Math.pow(2, 10 * h) : m / Math.pow(1e3, h), j && (g = 8 * g, g > k && (g /= k, h++)), e[0] = Number(g.toFixed(h > 0 ? o : 0)), e[1] = c[j ? "bits" : "bytes"][h], !f && p && (j && b.test(e[1]) && (e[1] = e[1].toLowerCase()), e[1] = e[1].charAt(0), "B" === e[1] ? (e[0] = Math.floor(e[0]), e[1] = "") : j || "k" !== e[1] || (e[1] = "K"))), l && (e[0] = -e[0]), e[1] = r[e[1]] || e[1], "array" === n ? e : "exponent" === n ? h : "object" === n ? { value: e[0], suffix: e[1] } : e.join(q) }; "undefined" != typeof exports ? module.exports = d : "function" == typeof define ? define(function () { return d }) : a.filesize = d }("undefined" != typeof global ? global : window);
//# sourceMappingURL=filesize.min.js.map

View File

@@ -1,33 +1,37 @@

Handlebars.registerHelper('dateFormat', function (context, block) {
if (window.moment) {
var f = block.hash.format || "MMM DD, YYYY hh:mm:ss A";
return moment(context).format(f); //had to remove Date(context)
} else {
return context; // moment plugin not available. return data as is.
};
});
Handlebars.registerHelper('jacketTimespan', function (context, block) {
var now = moment();
var from = moment(context);
var timeSpan = moment.duration(now.diff(from));
var minutes = timeSpan.asMinutes();
if (minutes < 120) {
return Math.round(minutes) + 'm ago';
}
var hours = timeSpan.asHours();
if (hours < 48) {
return Math.round(hours) + 'h ago';
}
var days = timeSpan.asDays();
if (days < 365) {
return Math.round(days) + 'd ago';
}
var years = timeSpan.asYears();
return Math.round(years) + 'y ago';

Handlebars.registerHelper('dateFormat', function (context, block) {
if (window.moment) {
var f = block.hash.format || "MMM DD, YYYY hh:mm:ss A";
return moment(context).format(f); //had to remove Date(context)
} else {
return context; // moment plugin not available. return data as is.
};
});
Handlebars.registerHelper('jacketTimespan', function (context, block) {
var now = moment();
var from = moment(context);
var timeSpan = moment.duration(now.diff(from));
var minutes = timeSpan.asMinutes();
if (minutes < 120) {
return Math.round(minutes) + 'm ago';
}
var hours = timeSpan.asHours();
if (hours < 48) {
return Math.round(hours) + 'h ago';
}
var days = timeSpan.asDays();
if (days < 365) {
return Math.round(days) + 'd ago';
}
var years = timeSpan.asYears();
return Math.round(years) + 'y ago';
});
Handlebars.registerHelper('jacketSize', function (context, block) {
return filesize(context, { round: 1 });
});

File diff suppressed because it is too large Load Diff

View File

@@ -83,6 +83,11 @@ namespace Jackett.Indexers
public Uri UncleanLink(Uri link)
{
if (link.ToString().StartsWith(downloadUrlBase))
{
return link;
}
return new Uri(downloadUrlBase + link.ToString(), UriKind.RelativeOrAbsolute);
}
@@ -223,6 +228,11 @@ 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)
{
throw new Exception($"Remote server returned {response.Status.ToString()}");
}
return response.Content;
}

View File

@@ -1,135 +1,135 @@
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 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 ConfigurationDataBasicLoginWithRSS configData
{
get { return (ConfigurationDataBasicLoginWithRSS)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.org/",
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
manager: i,
client: c,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLoginWithRSS())
{
AddCategoryMapping(47, TorznabCatType.Movies3D);
AddCategoryMapping(38, TorznabCatType.MoviesHD);
AddCategoryMapping(38, TorznabCatType.MoviesWEBDL);
AddCategoryMapping(38, TorznabCatType.MoviesBluRay);
AddCategoryMapping(5, TorznabCatType.MoviesSD);
AddCategoryMapping(23, TorznabCatType.MoviesForeign);
AddCategoryMapping(22, TorznabCatType.MoviesSD);
//AddCategoryMapping(4, TorznabCatType.TVFOREIGN);
//AddCategoryMapping(4, TorznabCatType.TVSD);
//AddCategoryMapping(4, TorznabCatType.TVDocumentary);
//AddCategoryMapping(4, TorznabCatType.TVSport);
//AddCategoryMapping(4, TorznabCatType.TV);
//AddCategoryMapping(31, TorznabCatType.TVHD);
//AddCategoryMapping(21, TorznabCatType.TVFOREIGN);
AddCategoryMapping(46, TorznabCatType.TV);
AddCategoryMapping(46, TorznabCatType.TVHD);
//AddCategoryMapping(45, TorznabCatType.TV);
//AddCategoryMapping(45, TorznabCatType.TVSD);
//AddCategoryMapping(24, TorznabCatType.TVFOREIGN);
AddCategoryMapping(26, TorznabCatType.TV);
AddCategoryMapping(26, TorznabCatType.TVHD);
AddCategoryMapping(26, TorznabCatType.TVWEBDL);
AddCategoryMapping(33, TorznabCatType.MoviesHD);
AddCategoryMapping(33, TorznabCatType.Movies);
AddCategoryMapping(17, TorznabCatType.MoviesForeign);
AddCategoryMapping(17, TorznabCatType.MoviesDVD);
AddCategoryMapping(9, TorznabCatType.MoviesHD);
AddCategoryMapping(9, TorznabCatType.Movies);
AddCategoryMapping(9, TorznabCatType.MoviesBluRay);
AddCategoryMapping(43, TorznabCatType.TV);
AddCategoryMapping(43, TorznabCatType.TVHD);
AddCategoryMapping(43, TorznabCatType.TVWEBDL);
}
public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
var loginPage = await RequestStringWithCookies(LoginUrl);
CQ loginDom = loginPage.Content;
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 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 ConfigurationDataBasicLoginWithRSS configData
{
get { return (ConfigurationDataBasicLoginWithRSS)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://nxgn.org/",
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
manager: i,
client: c,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLoginWithRSS())
{
AddCategoryMapping(47, TorznabCatType.Movies3D);
AddCategoryMapping(38, TorznabCatType.MoviesHD);
AddCategoryMapping(38, TorznabCatType.MoviesWEBDL);
AddCategoryMapping(38, TorznabCatType.MoviesBluRay);
AddCategoryMapping(5, TorznabCatType.MoviesSD);
AddCategoryMapping(23, TorznabCatType.MoviesForeign);
AddCategoryMapping(22, TorznabCatType.MoviesSD);
AddCategoryMapping(4, TorznabCatType.TVFOREIGN);
AddCategoryMapping(4, TorznabCatType.TVSD);
AddCategoryMapping(4, TorznabCatType.TVDocumentary);
AddCategoryMapping(4, TorznabCatType.TVSport);
AddCategoryMapping(4, TorznabCatType.TV);
AddCategoryMapping(31, TorznabCatType.TVHD);
AddCategoryMapping(21, TorznabCatType.TVFOREIGN);
AddCategoryMapping(46, TorznabCatType.TV);
AddCategoryMapping(46, TorznabCatType.TVHD);
//AddCategoryMapping(45, TorznabCatType.TV);
//AddCategoryMapping(45, TorznabCatType.TVSD);
//AddCategoryMapping(24, TorznabCatType.TVFOREIGN);
AddCategoryMapping(26, TorznabCatType.TV);
AddCategoryMapping(26, TorznabCatType.TVHD);
AddCategoryMapping(26, TorznabCatType.TVWEBDL);
AddCategoryMapping(33, TorznabCatType.MoviesHD);
AddCategoryMapping(33, TorznabCatType.Movies);
AddCategoryMapping(17, TorznabCatType.MoviesForeign);
AddCategoryMapping(17, TorznabCatType.MoviesDVD);
AddCategoryMapping(9, TorznabCatType.MoviesHD);
AddCategoryMapping(9, TorznabCatType.Movies);
AddCategoryMapping(9, TorznabCatType.MoviesBluRay);
AddCategoryMapping(43, TorznabCatType.TV);
AddCategoryMapping(43, TorznabCatType.TVHD);
AddCategoryMapping(43, TorznabCatType.TVWEBDL);
}
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.RequiresTesting;
}
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>();
var breakWhile = false;
var page = 0;
while (page < 3)
{
string episodeSearchUrl;
if (string.IsNullOrEmpty(query.GetQueryString()))
{
episodeSearchUrl = SearchUrl + "?page=" + page;
breakWhile = true;
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.RequiresTesting;
}
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var releases = new List<ReleaseInfo>();
var breakWhile = false;
var page = 0;
while (page < 3)
{
string episodeSearchUrl;
if (string.IsNullOrEmpty(query.GetQueryString()))
{
episodeSearchUrl = SearchUrl + "?page=" + page;
breakWhile = true;
}
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);
}
page++;
}
page++;
var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
try
{
@@ -145,16 +145,16 @@ namespace Jackett.Indexers
var qLink = qRow.Find("#torrent-udgivelse2-users > a").First();
var qDesc = qRow.Find("#torrent-udgivelse2-users > p").FirstOrDefault();
var moviesCats = new[] { 47, 38, 5, 23, 22, 33, 17, 9 };
var seriesCats = new[] { 46, 26, 43 };
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))
var moviesCats = new[] { 47, 38, 5, 23, 22, 33, 17, 9 };
var seriesCats = new[] { 46, 26, 43 };
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
else if (seriesCats.Contains(catNo))
release.Category = TorznabCatType.TV.ID;
else
continue;
releases.Add(release);
@@ -174,27 +174,27 @@ namespace Jackett.Indexers
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.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")
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.TheTvDbId = long.Parse(url.Substring(url.LastIndexOf('=') + 1));
}
release.Imdb = long.Parse(url.Substring(url.LastIndexOf('t') + 1));
}
else if (imgUrl == "/pic/TV.png")
{
release.TheTvDbId = long.Parse(url.Substring(url.LastIndexOf('=') + 1));
}
}
var nextPage = dom["#torrent-table-wrapper + p[align=center]"].Children().Last();
if (!nextPage.Is("a"))
@@ -203,11 +203,11 @@ namespace Jackett.Indexers
catch (Exception ex)
{
OnParseError(results.Content, ex);
}
if (breakWhile)
break;
}
return releases;
}
}
}
}
if (breakWhile)
break;
}
return releases;
}
}
}

View File

@@ -1,132 +1,132 @@
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("title").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;
}
}
}
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,183 +1,249 @@
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.io";
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.io/",
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);
}
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"]);
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();
}
}
}
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.io";
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.io/",
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

@@ -368,6 +368,7 @@
<Content Include="Content\custom.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\libs\filesize.min.js" />
<Content Include="Content\fonts\fontawesome-webfont.svg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

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("0.6.4.0")]
[assembly: AssemblyFileVersion("0.6.4.0")]
[assembly: AssemblyVersion("0.6.5.0")]
[assembly: AssemblyFileVersion("0.6.5.0")]