Add category mapping to torrentday, make logs viewable from web ui and change log messages to report new/old release count.

This commit is contained in:
KZ
2015-08-06 20:07:58 +01:00
parent 1160a609ca
commit 2b198ef688
13 changed files with 262 additions and 14 deletions

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Jackett
{
class AuthenticationException : Exception
{
}
}

View File

@@ -223,4 +223,12 @@ hr {
.indexer-caps table { .indexer-caps table {
border-bottom: 1px solid #ddd; border-bottom: 1px solid #ddd;
}
.jackettlogWarn {
background-color: #FFFF8E !important;
}
.jackettlogError {
background-color: #FF6060 !important;
} }

View File

@@ -63,6 +63,20 @@ $("#jackett-show-releases").click(function () {
}); });
$("#view-jackett-logs").click(function () {
var jqxhr = $.get("/admin/GetLogs", function (data) {
var releaseTemplate = Handlebars.compile($("#jackett-logs").html());
var item = { logs: data };
var releaseDialog = $(releaseTemplate(item));
$("#modals").append(releaseDialog);
releaseDialog.modal("show");
}).fail(function () {
doNotify("Request to Jackett server failed", "danger", "glyphicon glyphicon-alert");
});
});
$("#change-jackett-port").click(function () { $("#change-jackett-port").click(function () {
var jackett_port = $("#jackett-port").val(); var jackett_port = $("#jackett-port").val();
var jackett_external = $("#jackett-allowext").is(':checked'); var jackett_external = $("#jackett-allowext").is(':checked');

View File

@@ -71,6 +71,42 @@
</div> </div>
</script> </script>
<script id="jackett-logs" type="text/x-handlebars-template">
<div id="select-indexer-modal" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-lg modal-fillwidth">
<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">Server Logs</h4>
</div>
<div class="modal-body">
<table class="dataTable compact cell-border hover stripe">
<thead>
<tr>
<th style="width: 200px">When</th>
<th style="width: 80px">Level</th>
<th>Message</th>
</tr>
</thead>
<tbody>
{{#each logs}}
<tr class="jackettlog{{Level}}">
<td>{{dateFormat When}}</td>
<td>{{Level}}</td>
<td>{{Message}}</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</script>
<script id="jackett-config-setup-modal" type="text/x-handlebars-template"> <script id="jackett-config-setup-modal" type="text/x-handlebars-template">
<div class="config-setup-modal modal fade" tabindex="-1" role="dialog" aria-hidden="true"> <div class="config-setup-modal modal fade" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog"> <div class="modal-dialog">
@@ -156,6 +192,9 @@
<button id="change-jackett-port" class="btn btn-primary btn-sm"> <button id="change-jackett-port" class="btn btn-primary btn-sm">
Apply server settings <span class="glyphicon glyphicon-ok-wrench" aria-hidden="true"></span> Apply server settings <span class="glyphicon glyphicon-ok-wrench" aria-hidden="true"></span>
</button> </button>
<button id="view-jackett-logs" class="btn btn-danger btn-sm">
View logs <span class="glyphicon glyphicon-ok-wrench" aria-hidden="true"></span>
</button>
</div> </div>
<div class="input-area"> <div class="input-area">
<span class="input-header">External access: </span> <span class="input-header">External access: </span>

View File

@@ -37,8 +37,9 @@ namespace Jackett.Controllers
private IProcessService processService; private IProcessService processService;
private ICacheService cacheService; private ICacheService cacheService;
private Logger logger; private Logger logger;
private ILogCacheService logCache;
public AdminController(IConfigurationService config, IIndexerManagerService i, IServerService ss, ISecuityService s, IProcessService p, ICacheService c, Logger l) public AdminController(IConfigurationService config, IIndexerManagerService i, IServerService ss, ISecuityService s, IProcessService p, ICacheService c, Logger l, ILogCacheService lc)
{ {
this.config = config; this.config = config;
indexerService = i; indexerService = i;
@@ -47,6 +48,7 @@ namespace Jackett.Controllers
processService = p; processService = p;
cacheService = c; cacheService = c;
logger = l; logger = l;
logCache = lc;
} }
private async Task<JToken> ReadPostDataJson() private async Task<JToken> ReadPostDataJson()
@@ -379,6 +381,13 @@ namespace Jackett.Controllers
var severUrl = string.Format("{0}://{1}:{2}/", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port); var severUrl = string.Format("{0}://{1}:{2}/", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port);
return cacheService.GetCachedResults(severUrl); return cacheService.GetCachedResults(severUrl);
} }
[Route("GetLogs")]
[HttpGet]
public List<CachedLog> GetLogs()
{
return logCache.Logs;
}
} }
} }

View File

@@ -64,24 +64,36 @@ namespace Jackett.Controllers
var releases = await indexer.PerformQuery(torznabQuery); var releases = await indexer.PerformQuery(torznabQuery);
int? newItemCount = null;
// Cache non query results // Cache non query results
if (string.IsNullOrEmpty(torznabQuery.SanitizedSearchTerm)) if (string.IsNullOrEmpty(torznabQuery.SanitizedSearchTerm))
{ {
cacheService.CacheRssResults(indexer, releases); newItemCount = cacheService.CacheRssResults(indexer, releases);
} }
var releaseCount = releases.Count();
releases = indexer.FilterResults(torznabQuery, releases); releases = indexer.FilterResults(torznabQuery, releases);
var removedInFilterCount = releaseCount - releases.Count();
if (newItemCount.HasValue)
newItemCount -= removedInFilterCount;
// Log info // Log info
if (string.IsNullOrWhiteSpace(torznabQuery.SanitizedSearchTerm)) var logBuilder = new StringBuilder();
{ if (newItemCount != null) {
logger.Info(string.Format("Found {0} releases from {1}", releases.Count(), indexer.DisplayName)); logBuilder.AppendFormat(string.Format("Found {0} ({1} new) releases from {2}", releases.Count(), newItemCount, indexer.DisplayName));
} }
else else {
{ logBuilder.AppendFormat(string.Format("Found {0} releases from {1}", releases.Count(), indexer.DisplayName));
logger.Info(string.Format("Found {0} releases from {1} for: {2} {3}", releases.Count(), indexer.DisplayName, torznabQuery.SanitizedSearchTerm, torznabQuery.GetEpisodeSearchString()));
} }
if (!string.IsNullOrWhiteSpace(torznabQuery.SanitizedSearchTerm)) {
logBuilder.AppendFormat(" for: {2} {3}", torznabQuery.SanitizedSearchTerm, torznabQuery.GetEpisodeSearchString());
}
logger.Info(logBuilder.ToString());
var severUrl = string.Format("{0}://{1}:{2}/", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port); var severUrl = string.Format("{0}://{1}:{2}/", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port);
var resultPage = new ResultPage(new ChannelInfo var resultPage = new ResultPage(new ChannelInfo
{ {

View File

@@ -34,6 +34,7 @@ namespace Jackett
secondaryBuilder.RegisterInstance<IContainer>(container).SingleInstance(); secondaryBuilder.RegisterInstance<IContainer>(container).SingleInstance();
SetupLogging(secondaryBuilder); SetupLogging(secondaryBuilder);
secondaryBuilder.Update(container); secondaryBuilder.Update(container);
} }
public static IContainer GetContainer() public static IContainer GetContainer()
@@ -132,6 +133,11 @@ namespace Jackett
var logConsoleRule = new LoggingRule("*", logLevel, logConsole); var logConsoleRule = new LoggingRule("*", logLevel, logConsole);
logConfig.LoggingRules.Add(logConsoleRule); 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; LogManager.Configuration = logConfig;
builder.RegisterInstance<Logger>(LogManager.GetCurrentClassLogger()).SingleInstance(); builder.RegisterInstance<Logger>(LogManager.GetCurrentClassLogger()).SingleInstance();
} }

View File

@@ -15,6 +15,7 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Web; using System.Web;
using Jackett.Models.IndexerConfig; using Jackett.Models.IndexerConfig;
using System.Collections.Specialized;
namespace Jackett.Indexers namespace Jackett.Indexers
{ {
@@ -22,7 +23,7 @@ namespace Jackett.Indexers
{ {
private string StartPageUrl { get { return SiteLink + "login.php"; } } private string StartPageUrl { get { return SiteLink + "login.php"; } }
private string LoginUrl { get { return SiteLink + "tak3login.php"; } } private string LoginUrl { get { return SiteLink + "tak3login.php"; } }
private string SearchUrl { get { return SiteLink + "browse.php?search={0}&cata=yes&c2=1&c7=1&c14=1&c24=1&c26=1&c31=1&c32=1&c33=1"; } } private string SearchUrl { get { return SiteLink + "browse.php"; } }
new ConfigurationDataBasicLogin configData new ConfigurationDataBasicLogin configData
{ {
@@ -40,6 +41,46 @@ namespace Jackett.Indexers
logger: l, logger: l,
configData: new ConfigurationDataBasicLogin()) configData: new ConfigurationDataBasicLogin())
{ {
AddCategoryMapping(29, TorznabCatType.Anime);
AddCategoryMapping(28, TorznabCatType.Apps);
AddCategoryMapping(28, TorznabCatType.AudioBooks);
AddCategoryMapping(20, TorznabCatType.Books);
AddCategoryMapping(30, TorznabCatType.TVDocs);
//Freelech
//Mac
AddCategoryMapping(25, TorznabCatType.MoviesSD);
AddCategoryMapping(11, TorznabCatType.MoviesHD);
AddCategoryMapping(5, TorznabCatType.MoviesHD);
AddCategoryMapping(3, TorznabCatType.MoviesSD);
AddCategoryMapping(21, TorznabCatType.MoviesSD);
AddCategoryMapping(22, TorznabCatType.MoviesForeign);
// Movie packs
AddCategoryMapping(44, TorznabCatType.MoviesSD);
AddCategoryMapping(1, TorznabCatType.MoviesSD);
// Music foreign
// Music packs
// Music videos
AddCategoryMapping(4, TorznabCatType.PCGames);
// ps3
// psp
// wii
// 360
AddCategoryMapping(24, TorznabCatType.TVSD);
AddCategoryMapping(32, TorznabCatType.TVHD);
AddCategoryMapping(31, TorznabCatType.TVSD);
AddCategoryMapping(33, TorznabCatType.TVSD);
AddCategoryMapping(14, TorznabCatType.TVHD);
AddCategoryMapping(26, TorznabCatType.TVSD);
AddCategoryMapping(7, TorznabCatType.TVHD);
AddCategoryMapping(2, TorznabCatType.TVSD);
AddCategoryMapping(6, TorznabCatType.XXX);
AddCategoryMapping(15, TorznabCatType.XXX);
} }
public async Task ApplyConfiguration(JToken configJson) public async Task ApplyConfiguration(JToken configJson)
@@ -69,8 +110,23 @@ namespace Jackett.Indexers
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString();
var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString)); var queryUrl = SearchUrl;
var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl); var queryCollection = new NameValueCollection();
if (!string.IsNullOrWhiteSpace(searchString))
queryCollection.Add("search", searchString);
foreach (var cat in MapTorznabCapsToTrackers(query))
queryCollection.Add("c"+cat,"1");
if (queryCollection.Count > 0)
queryUrl += "?" + queryCollection.GetQueryString();
var results = await RequestStringWithCookiesAndRetry(queryUrl);
// Check for being logged out
if (results.IsRedirect)
throw new AuthenticationException();
try try
{ {
@@ -103,6 +159,9 @@ namespace Jackett.Indexers
release.Seeders = ParseUtil.CoerceInt(qRow.Find(".seedersInfo").Text()); release.Seeders = ParseUtil.CoerceInt(qRow.Find(".seedersInfo").Text());
release.Peers = ParseUtil.CoerceInt(qRow.Find(".leechersInfo").Text()) + release.Seeders; release.Peers = ParseUtil.CoerceInt(qRow.Find(".leechersInfo").Text()) + release.Seeders;
var cat = qRow.Find("td:eq(0) a").First().Attr("href").Substring(15);//browse.php?cat=24
release.Category = MapTrackerCatToNewznab(cat);
releases.Add(release); releases.Add(release);
} }
} }

View File

@@ -170,6 +170,7 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="AuthenticationException.cs" />
<Compile Include="Controllers\PotatoController.cs" /> <Compile Include="Controllers\PotatoController.cs" />
<Compile Include="Controllers\TorznabController.cs" /> <Compile Include="Controllers\TorznabController.cs" />
<Compile Include="Controllers\DownloadController.cs" /> <Compile Include="Controllers\DownloadController.cs" />
@@ -205,6 +206,7 @@
<Compile Include="Indexers\TorrentLeech.cs" /> <Compile Include="Indexers\TorrentLeech.cs" />
<Compile Include="Indexers\TorrentShack.cs" /> <Compile Include="Indexers\TorrentShack.cs" />
<Compile Include="Indexers\Torrentz.cs" /> <Compile Include="Indexers\Torrentz.cs" />
<Compile Include="Models\CachedLog.cs" />
<Compile Include="Models\CachedResult.cs" /> <Compile Include="Models\CachedResult.cs" />
<Compile Include="Models\CategoryMapping.cs" /> <Compile Include="Models\CategoryMapping.cs" />
<Compile Include="Models\IndexerConfig\ConfigurationDataLoginTokin.cs" /> <Compile Include="Models\IndexerConfig\ConfigurationDataLoginTokin.cs" />
@@ -223,6 +225,7 @@
<Compile Include="Models\TrackerCache.cs" /> <Compile Include="Models\TrackerCache.cs" />
<Compile Include="Models\TrackerCacheResult.cs" /> <Compile Include="Models\TrackerCacheResult.cs" />
<Compile Include="Services\CacheService.cs" /> <Compile Include="Services\CacheService.cs" />
<Compile Include="Services\LogCacheService.cs" />
<Compile Include="Utils\Clients\BaseWebResult.cs" /> <Compile Include="Utils\Clients\BaseWebResult.cs" />
<Compile Include="Utils\Clients\UnixLibCurlWebClient.cs" /> <Compile Include="Utils\Clients\UnixLibCurlWebClient.cs" />
<Compile Include="Utils\Clients\WebByteResult.cs" /> <Compile Include="Utils\Clients\WebByteResult.cs" />

View File

@@ -0,0 +1,16 @@
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Jackett.Models
{
public class CachedLog
{
public string Level { set; get; }
public string Message { set; get; }
public DateTime When { set; get; }
}
}

View File

@@ -16,9 +16,11 @@ namespace Jackett.Models
cats.Add(5030, "TV/SD"); cats.Add(5030, "TV/SD");
cats.Add(5040, "TV/HD"); cats.Add(5040, "TV/HD");
cats.Add(5070, "TV/Anime"); cats.Add(5070, "TV/Anime");
cats.Add(5080, "TV/Documentary");
cats.Add(8000, "Books"); cats.Add(8000, "Books");
cats.Add(8020, "Books/Comics"); cats.Add(8020, "Books/Comics");
cats.Add(4000, "PC"); cats.Add(4000, "PC");
cats.Add(4050, "PC/Games");
cats.Add(3030, "Audio/Audiobook"); cats.Add(3030, "Audio/Audiobook");
cats.Add(2000, "Movies"); cats.Add(2000, "Movies");
cats.Add(2040, "Movies/HD"); cats.Add(2040, "Movies/HD");
@@ -82,6 +84,11 @@ namespace Jackett.Models
get { return GetCat(5000); } get { return GetCat(5000); }
} }
public static TorznabCategory TVDocs
{
get { return GetCat(5080); }
}
public static TorznabCategory TVSD public static TorznabCategory TVSD
{ {
get { return GetCat(5030); } get { return GetCat(5030); }
@@ -107,6 +114,11 @@ namespace Jackett.Models
get { return GetCat(4000); } get { return GetCat(4000); }
} }
public static TorznabCategory PCGames
{
get { return GetCat(4050); }
}
public static TorznabCategory AudioBooks public static TorznabCategory AudioBooks
{ {
get { return GetCat(3030); } get { return GetCat(3030); }

View File

@@ -11,7 +11,7 @@ namespace Jackett.Services
{ {
public interface ICacheService public interface ICacheService
{ {
void CacheRssResults(IIndexer indexer, IEnumerable<ReleaseInfo> releases); int CacheRssResults(IIndexer indexer, IEnumerable<ReleaseInfo> releases);
List<TrackerCacheResult> GetCachedResults(string serverUrl); List<TrackerCacheResult> GetCachedResults(string serverUrl);
} }
@@ -19,12 +19,13 @@ namespace Jackett.Services
{ {
private readonly List<TrackerCache> cache = new List<TrackerCache>(); private readonly List<TrackerCache> cache = new List<TrackerCache>();
private readonly int MAX_RESULTS_PER_TRACKER = 250; private readonly int MAX_RESULTS_PER_TRACKER = 250;
private readonly TimeSpan AGE_LIMIT = new TimeSpan(2, 0, 0, 0); private readonly TimeSpan AGE_LIMIT = new TimeSpan(7, 0, 0, 0);
public void CacheRssResults(IIndexer indexer, IEnumerable<ReleaseInfo> releases) public int CacheRssResults(IIndexer indexer, IEnumerable<ReleaseInfo> releases)
{ {
lock (cache) lock (cache)
{ {
int newItemCount = 0;
var trackerCache = cache.Where(c => c.TrackerId == indexer.ID).FirstOrDefault(); var trackerCache = cache.Where(c => c.TrackerId == indexer.ID).FirstOrDefault();
if (trackerCache == null) if (trackerCache == null)
{ {
@@ -48,6 +49,7 @@ namespace Jackett.Services
existingItem = new CachedResult(); existingItem = new CachedResult();
existingItem.Created = DateTime.Now; existingItem.Created = DateTime.Now;
trackerCache.Results.Add(existingItem); trackerCache.Results.Add(existingItem);
newItemCount++;
} }
existingItem.Result = release; existingItem.Result = release;
@@ -58,6 +60,8 @@ namespace Jackett.Services
{ {
tracker.Results = tracker.Results.OrderByDescending(i => i.Created).Take(MAX_RESULTS_PER_TRACKER).ToList(); tracker.Results = tracker.Results.OrderByDescending(i => i.Created).Take(MAX_RESULTS_PER_TRACKER).ToList();
} }
return newItemCount;
} }
} }

View File

@@ -0,0 +1,54 @@
using Jackett.Models;
using NLog;
using NLog.Targets;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Jackett.Services
{
public interface ILogCacheService
{
// void AddLog(LogEventInfo l);
List<CachedLog> Logs { get; }
}
[Target("LogService")]
class LogCacheService: TargetWithLayout, ILogCacheService
{
private static List<CachedLog> logs = new List<CachedLog>();
public void AddLog(LogEventInfo l)
{
lock (logs)
{
logs.Insert(0, new CachedLog()
{
Level = l.Level.Name,
Message = l.Message,
When = l.TimeStamp
});
logs = logs.Take(100).ToList();
}
}
public List<CachedLog> Logs
{
get
{
lock (logs)
{
return logs.ToList();
}
}
}
protected override void Write(LogEventInfo logEvent)
{
AddLog(logEvent);
}
}
}