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 {
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 () {
var jackett_port = $("#jackett-port").val();
var jackett_external = $("#jackett-allowext").is(':checked');

View File

@ -71,6 +71,42 @@
</div>
</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">
<div class="config-setup-modal modal fade" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
@ -156,6 +192,9 @@
<button id="change-jackett-port" class="btn btn-primary btn-sm">
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">
View logs <span class="glyphicon glyphicon-ok-wrench" aria-hidden="true"></span>
</button>
</div>
<div class="input-area">
<span class="input-header">External access: </span>

View File

@ -37,8 +37,9 @@ namespace Jackett.Controllers
private IProcessService processService;
private ICacheService cacheService;
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;
indexerService = i;
@ -47,6 +48,7 @@ namespace Jackett.Controllers
processService = p;
cacheService = c;
logger = l;
logCache = lc;
}
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);
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);
int? newItemCount = null;
// Cache non query results
if (string.IsNullOrEmpty(torznabQuery.SanitizedSearchTerm))
{
cacheService.CacheRssResults(indexer, releases);
newItemCount = cacheService.CacheRssResults(indexer, releases);
}
var releaseCount = releases.Count();
releases = indexer.FilterResults(torznabQuery, releases);
var removedInFilterCount = releaseCount - releases.Count();
if (newItemCount.HasValue)
newItemCount -= removedInFilterCount;
// Log info
if (string.IsNullOrWhiteSpace(torznabQuery.SanitizedSearchTerm))
{
logger.Info(string.Format("Found {0} releases from {1}", releases.Count(), indexer.DisplayName));
var logBuilder = new StringBuilder();
if (newItemCount != null) {
logBuilder.AppendFormat(string.Format("Found {0} ({1} new) releases from {2}", releases.Count(), newItemCount, indexer.DisplayName));
}
else
{
logger.Info(string.Format("Found {0} releases from {1} for: {2} {3}", releases.Count(), indexer.DisplayName, torznabQuery.SanitizedSearchTerm, torznabQuery.GetEpisodeSearchString()));
else {
logBuilder.AppendFormat(string.Format("Found {0} releases from {1}", releases.Count(), indexer.DisplayName));
}
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 resultPage = new ResultPage(new ChannelInfo
{

View File

@ -34,6 +34,7 @@ namespace Jackett
secondaryBuilder.RegisterInstance<IContainer>(container).SingleInstance();
SetupLogging(secondaryBuilder);
secondaryBuilder.Update(container);
}
public static IContainer GetContainer()
@ -132,6 +133,11 @@ namespace Jackett
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();
}

View File

@ -15,6 +15,7 @@ using System.Text;
using System.Threading.Tasks;
using System.Web;
using Jackett.Models.IndexerConfig;
using System.Collections.Specialized;
namespace Jackett.Indexers
{
@ -22,7 +23,7 @@ namespace Jackett.Indexers
{
private string StartPageUrl { get { return SiteLink + "login.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
{
@ -40,6 +41,46 @@ namespace Jackett.Indexers
logger: l,
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)
@ -69,8 +110,23 @@ namespace Jackett.Indexers
{
var releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString();
var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString));
var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
var queryUrl = SearchUrl;
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
{
@ -103,6 +159,9 @@ namespace Jackett.Indexers
release.Seeders = ParseUtil.CoerceInt(qRow.Find(".seedersInfo").Text());
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);
}
}

View File

@ -170,6 +170,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AuthenticationException.cs" />
<Compile Include="Controllers\PotatoController.cs" />
<Compile Include="Controllers\TorznabController.cs" />
<Compile Include="Controllers\DownloadController.cs" />
@ -205,6 +206,7 @@
<Compile Include="Indexers\TorrentLeech.cs" />
<Compile Include="Indexers\TorrentShack.cs" />
<Compile Include="Indexers\Torrentz.cs" />
<Compile Include="Models\CachedLog.cs" />
<Compile Include="Models\CachedResult.cs" />
<Compile Include="Models\CategoryMapping.cs" />
<Compile Include="Models\IndexerConfig\ConfigurationDataLoginTokin.cs" />
@ -223,6 +225,7 @@
<Compile Include="Models\TrackerCache.cs" />
<Compile Include="Models\TrackerCacheResult.cs" />
<Compile Include="Services\CacheService.cs" />
<Compile Include="Services\LogCacheService.cs" />
<Compile Include="Utils\Clients\BaseWebResult.cs" />
<Compile Include="Utils\Clients\UnixLibCurlWebClient.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(5040, "TV/HD");
cats.Add(5070, "TV/Anime");
cats.Add(5080, "TV/Documentary");
cats.Add(8000, "Books");
cats.Add(8020, "Books/Comics");
cats.Add(4000, "PC");
cats.Add(4050, "PC/Games");
cats.Add(3030, "Audio/Audiobook");
cats.Add(2000, "Movies");
cats.Add(2040, "Movies/HD");
@ -82,6 +84,11 @@ namespace Jackett.Models
get { return GetCat(5000); }
}
public static TorznabCategory TVDocs
{
get { return GetCat(5080); }
}
public static TorznabCategory TVSD
{
get { return GetCat(5030); }
@ -107,6 +114,11 @@ namespace Jackett.Models
get { return GetCat(4000); }
}
public static TorznabCategory PCGames
{
get { return GetCat(4050); }
}
public static TorznabCategory AudioBooks
{
get { return GetCat(3030); }

View File

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