Metasearch , fix for empty queries being converted to a single space, parent categories are now autoexpanded.

This commit is contained in:
KZ
2015-08-14 22:20:51 +01:00
parent c45929fe43
commit 98446222c9
39 changed files with 465 additions and 119 deletions

View File

@@ -214,6 +214,7 @@ hr {
.modal-fillwidth { .modal-fillwidth {
width: 1200px; width: 1200px;
min-width:80%;
} }
.indexer-caps { .indexer-caps {

View File

@@ -114,6 +114,132 @@ $("#jackett-show-releases").click(function () {
}); });
$("#jackett-show-search").click(function () {
$('#select-indexer-modal').remove();
var jqxhr = $.get("/admin/get_indexers", function (data) {
var scope = {
items: data.items
};
var indexers = [];
indexers.push({ id: '', name: '-- All --' });
for (var i = 0; i < data.items.length; i++) {
if (data.items[i].configured === true) {
indexers.push(data.items[i]);
}
}
var releaseTemplate = Handlebars.compile($("#jackett-search").html());
var releaseDialog = $(releaseTemplate({ indexers: indexers }));
$("#modals").append(releaseDialog);
releaseDialog.modal("show");
var setCategories = function (tracker, items) {
var cats = {};
for (var i = 0; i < items.length; i++) {
if (items[i].configured === true && (items[i].id === tracker || tracker ==='')) {
indexers["'" + items[i].id + "'"] = items[i].name;
for (var prop in items[i].caps) {
cats[prop] = items[i].caps[prop];
}
}
}
var select = $('#searchCategory');
select.html("<option value=''>-- All --</option>");
$.each(cats, function (value, key) {
select.append($("<option></option>")
.attr("value", value).text(key + ' (' + value + ')'));
});
};
setCategories('', data.items);
$('#searchTracker').change(jQuery.proxy(function () {
var trackerId = $('#searchTracker').val();
setCategories(trackerId, this.items);
}, scope));
$('#jackett-search-perform').click(function () {
if ($('#jackett-search-perform').text().trim() !== 'Search trackers') {
// We are searchin already
return;
}
var queryObj = {
Query: releaseDialog.find('#searchquery').val(),
Category: releaseDialog.find('#searchCategory').val(),
Tracker: releaseDialog.find('#searchTracker').val().replace("'", "").replace("'", ""),
};
$('#searchResults').empty();
$('#jackett-search-perform').html($('#spinner').html());
var jqxhr = $.post("/admin/search", queryObj, function (data) {
$('#jackett-search-perform').html('Search trackers');
var resultsTemplate = Handlebars.compile($("#jackett-search-results").html());
var results = $('#searchResults');
results.html($(resultsTemplate(data)));
results.find('table').DataTable(
{
"pageLength": 20,
"lengthMenu": [[10, 20, 50, -1], [10, 20, 50, "All"]],
"order": [[0, "desc"]],
"columnDefs": [
{
"targets": 0,
"visible": false,
"searchable": false,
"type": 'date'
},
{
"targets": 1,
"visible": true,
"searchable": false,
"iDataSort": 0
},
],
initComplete: function () {
var count = 0;
this.api().columns().every(function () {
count++;
if (count === 3 || count === 5) {
var column = this;
var select = $('<select><option value=""></option></select>')
.appendTo($(column.footer()).empty())
.on('change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
column
.search(val ? '^' + val + '$' : '', true, false)
.draw();
});
column.data().unique().sort().each(function (d, j) {
select.append('<option value="' + d + '">' + d + '</option>')
});
}
});
}
});
}).fail(function () {
$('#jackett-search-perform').html('Search trackers');
doNotify("Request to Jackett server failed", "danger", "glyphicon glyphicon-alert");
});
});
}).fail(function () {
doNotify("Error loading indexers, request to Jackett server failed", "danger", "glyphicon glyphicon-alert");
});
});
$("#view-jackett-logs").click(function () { $("#view-jackett-logs").click(function () {
var jqxhr = $.get("/admin/GetLogs", function (data) { var jqxhr = $.get("/admin/GetLogs", function (data) {
var releaseTemplate = Handlebars.compile($("#jackett-logs").html()); var releaseTemplate = Handlebars.compile($("#jackett-logs").html());

View File

@@ -108,6 +108,7 @@
</div> </div>
</div> </div>
</script> </script>
<script id="jackett-releases" type="text/x-handlebars-template"> <script id="jackett-releases" type="text/x-handlebars-template">
<div id="select-indexer-modal" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true"> <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-dialog modal-lg modal-fillwidth">
@@ -117,7 +118,7 @@
<h4 class="modal-title">Releases</h4> <h4 class="modal-title">Releases</h4>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<p>This screen shows releases which have been recently returned from Jackett. Only the last 100 releases in the last 2 days are kept in memory for each tracker.</p> <p>This screen shows releases which have been recently returned from Jackett. Only the last 300 releases for each tracker are returned.</p>
<table class="dataTable compact cell-border hover stripe"> <table class="dataTable compact cell-border hover stripe">
<thead> <thead>
<tr> <tr>
@@ -178,6 +179,89 @@
</div> </div>
</script> </script>
<script id="jackett-search" 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">Metasearch</h4>
</div>
<div class="modal-body">
<p>You can search all configured indexers from this screen.</p>
<label>Query</label>
<input type="text" name="query" id="searchquery" style="width:400px" />
<label>Category</label>
<select name="category" id="searchCategory"></select>
<label>Tracker</label>
<select name="tracker" id="searchTracker">
{{#each indexers}}
<option value="{{id}}">{{name}}</option>
{{/each}}
</select>
<button id="jackett-search-perform" class="btn btn-success btn-sm">
Search trackers<span class="glyphicon glyphicon-ok-wrench" aria-hidden="true"></span>
</button>
<div id="searchResults"></div>
</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-search-results" type="text/x-handlebars-template">
<hr/>
<p>Your search contains results from: {{#each Indexers}}{{this}}, {{/each}}</p>
<table class="dataTable compact cell-border hover stripe">
<thead>
<tr>
<th>Published</th>
<th>Published</th>
<th>Tracker</th>
<th>Name</th>
<th>Category</th>
<th>Seeds</th>
<th>Leechers</th>
<th>Download</th>
</tr>
</thead>
<tbody>
{{#each Results}}
<tr>
<td>{{PublishDate}}</td>
<td>{{jacketTimespan PublishDate}}</td>
<td>{{Tracker}}</td>
<td><a href="{{Comments}}">{{Title}}</a></td>
<td>{{CategoryDesc}}</td>
<td>{{Seeders}}</td>
<td>{{Peers}}</td>
<td class="downloadcolumn">
<a class="downloadlink" title="Download locally" href="{{Link}}"><i class="fa fa-download"></i></a>
{{#if BlackholeLink}}
<a class="downloadlink jacketdownloadserver" title="Save to server blackhole directory" href="{{BlackholeLink}}"><i class="fa fa-upload"></i></a>
{{/if}}
</td>
</tr>
{{/each}}
</tbody>
<tfoot>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tfoot>
</table>
</script>
<script id="jackett-logs" type="text/x-handlebars-template"> <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 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-dialog modal-lg modal-fillwidth">
@@ -286,6 +370,9 @@
<hr /> <hr />
<div class="pull-right"> <div class="pull-right">
<button id="jackett-show-search" class="btn btn-success btn-sm">
Metasearch <span class="glyphicon glyphicon-ok-wrench" aria-hidden="true"></span>
</button>
<button id="jackett-show-releases" class="btn btn-primary btn-sm"> <button id="jackett-show-releases" class="btn btn-primary btn-sm">
View cached releases <span class="glyphicon glyphicon-ok-wrench" aria-hidden="true"></span> View cached releases <span class="glyphicon glyphicon-ok-wrench" aria-hidden="true"></span>
</button> </button>

View File

@@ -221,6 +221,11 @@ namespace Jackett.Controllers
item["configured"] = indexer.IsConfigured; item["configured"] = indexer.IsConfigured;
item["site_link"] = indexer.SiteLink; item["site_link"] = indexer.SiteLink;
item["potatoenabled"] = indexer.TorznabCaps.Categories.Select(c => c.ID).Any(i => PotatoController.MOVIE_CATS.Contains(i)); item["potatoenabled"] = indexer.TorznabCaps.Categories.Select(c => c.ID).Any(i => PotatoController.MOVIE_CATS.Contains(i));
var caps = new JObject();
foreach (var cap in indexer.TorznabCaps.Categories)
caps[cap.ID.ToString()] = cap.Name;
item["caps"] = caps;
items.Add(item); items.Add(item);
} }
jsonReply["items"] = items; jsonReply["items"] = items;
@@ -396,9 +401,15 @@ namespace Jackett.Controllers
[HttpGet] [HttpGet]
public List<TrackerCacheResult> GetCache() public List<TrackerCacheResult> GetCache()
{ {
var serverUrl = string.Format("{0}://{1}:{2}/", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port);
var results = cacheService.GetCachedResults(); var results = cacheService.GetCachedResults();
ConfigureCacheResults(results);
return results;
}
private void ConfigureCacheResults(List<TrackerCacheResult> results)
{
var serverUrl = string.Format("{0}://{1}:{2}/", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port);
foreach (var result in results) foreach (var result in results)
{ {
var link = result.Link; var link = result.Link;
@@ -407,8 +418,6 @@ namespace Jackett.Controllers
result.BlackholeLink = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "bh", string.Empty); result.BlackholeLink = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "bh", string.Empty);
} }
return results;
} }
[Route("GetLogs")] [Route("GetLogs")]
@@ -417,6 +426,73 @@ namespace Jackett.Controllers
{ {
return logCache.Logs; return logCache.Logs;
} }
[Route("Search")]
[HttpPost]
public ManualSearchResult Search([FromBody]AdminSearch value)
{
var results = new List<TrackerCacheResult>();
var query = new TorznabQuery()
{
SearchTerm = value.Query,
Categories = value.Category ==0?new int[0]: new int[1] { value.Category }
};
query.ExpandCatsToSubCats();
var trackers = indexerService.GetAllIndexers().Where(t=>t.IsConfigured).ToList();
if (!string.IsNullOrWhiteSpace(value.Tracker))
{
trackers = trackers.Where(t => t.ID == value.Tracker).ToList();
}
if (value.Category != 0)
{
trackers = trackers.Where(t => t.TorznabCaps.Categories.Select(c => c.ID).Contains(value.Category)).ToList();
}
Parallel.ForEach(trackers.ToList(), indexer =>
{
var searchResults = indexer.PerformQuery(query).Result;
cacheService.CacheRssResults(indexer, searchResults);
searchResults = indexer.FilterResults(query, searchResults);
lock (results)
{
if (searchResults.Count() == 0)
trackers.Remove(indexer);
foreach (var result in searchResults)
{
var item = Mapper.Map<TrackerCacheResult>(result);
item.Tracker = indexer.DisplayName;
item.TrackerId = indexer.ID;
item.Peers = item.Peers - item.Seeders; // Use peers as leechers
results.Add(item);
}
}
});
ConfigureCacheResults(results);
if (trackers.Count > 1)
{
results = results.OrderByDescending(d => d.PublishDate).ToList();
}
var manualResult = new ManualSearchResult()
{
Results = results,
Indexers = trackers.Select(t=>t.DisplayName).ToList()
};
if (manualResult.Indexers.Count == 0)
manualResult.Indexers = new List<string>() { "None" };
logger.Info(string.Format("Manual search for \"{0}\" on {1} with {2} results.", query.GetQueryString(), string.Join(", ", manualResult.Indexers), manualResult.Results.Count));
return manualResult;
}
} }
} }

View File

@@ -28,7 +28,19 @@ namespace Jackett.Controllers
private ICacheService cacheService; private ICacheService cacheService;
private IWebClient webClient; private IWebClient webClient;
public static readonly int[] MOVIE_CATS = new int[] {2000, 2040, 2030, 2010}; public static int[] MOVIE_CATS
{
get
{
var torznabQuery = new TorznabQuery()
{
Categories = new int[1] { TorznabCatType.Movies.ID },
};
torznabQuery.ExpandCatsToSubCats();
return torznabQuery.Categories;
}
}
public PotatoController(IIndexerManagerService i, Logger l, IServerService s, ICacheService c, IWebClient w) public PotatoController(IIndexerManagerService i, Logger l, IServerService s, ICacheService c, IWebClient w)
{ {
@@ -137,7 +149,7 @@ namespace Jackett.Controllers
} }
else else
{ {
logger.Info(string.Format("Found {0} torrentpotato releases from {1} for: {2} {3}", releases.Count(), indexer.DisplayName, torznabQuery.SanitizedSearchTerm, torznabQuery.GetEpisodeSearchString())); logger.Info(string.Format("Found {0} torrentpotato releases from {1} for: {2}", releases.Count(), indexer.DisplayName, torznabQuery.GetQueryString()));
} }
// Force the return as Json // Force the return as Json

View File

@@ -46,6 +46,7 @@ namespace Jackett.Controllers
}; };
} }
torznabQuery.ExpandCatsToSubCats();
var allowBadApiDueToDebug = false; var allowBadApiDueToDebug = false;
#if DEBUG #if DEBUG
allowBadApiDueToDebug = Debugger.IsAttached; allowBadApiDueToDebug = Debugger.IsAttached;
@@ -77,7 +78,6 @@ namespace Jackett.Controllers
var filteredReleases = releases = indexer.FilterResults(torznabQuery, releases); var filteredReleases = releases = indexer.FilterResults(torznabQuery, releases);
int? newItemCount = null; int? newItemCount = null;
// Cache non query results // Cache non query results
if (string.IsNullOrEmpty(torznabQuery.SanitizedSearchTerm)) if (string.IsNullOrEmpty(torznabQuery.SanitizedSearchTerm))
{ {
@@ -95,7 +95,7 @@ namespace Jackett.Controllers
} }
if (!string.IsNullOrWhiteSpace(torznabQuery.SanitizedSearchTerm)) { if (!string.IsNullOrWhiteSpace(torznabQuery.SanitizedSearchTerm)) {
logBuilder.AppendFormat(" for: {0} {1}", torznabQuery.SanitizedSearchTerm, torznabQuery.GetEpisodeSearchString()); logBuilder.AppendFormat(" for: {0}", torznabQuery.GetQueryString());
} }
logger.Info(logBuilder.ToString()); logger.Info(logBuilder.ToString());

View File

@@ -92,7 +92,7 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var searchString = query.GetQueryString();
var searchUrl = SearchUrl; var searchUrl = SearchUrl;
var queryCollection = new NameValueCollection(); var queryCollection = new NameValueCollection();

View File

@@ -88,7 +88,7 @@ namespace Jackett.Indexers
{ {
List<ReleaseInfo> releases = new List<ReleaseInfo>(); List<ReleaseInfo> releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var searchString = query.GetQueryString();
var searchUrl = SearchUrl; var searchUrl = SearchUrl;
var queryCollection = new NameValueCollection(); var queryCollection = new NameValueCollection();

View File

@@ -83,7 +83,7 @@ namespace Jackett.Indexers
{ {
List<ReleaseInfo> releases = new List<ReleaseInfo>(); List<ReleaseInfo> releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var searchString = query.GetQueryString();
var searchUrl = SearchUrl; var searchUrl = SearchUrl;
var queryCollection = new NameValueCollection(); var queryCollection = new NameValueCollection();

View File

@@ -67,8 +67,7 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode(query.GetQueryString());
var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode(searchString);
var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl); var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
try try
{ {

View File

@@ -85,8 +85,7 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = string.Format("{0}?search={1}&cat=0", SearchUrl, HttpUtility.UrlEncode(query.GetQueryString()));
var episodeSearchUrl = string.Format("{0}?search={1}&cat=0", SearchUrl, HttpUtility.UrlEncode(searchString));
var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl); var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
try try
{ {

View File

@@ -63,8 +63,7 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(query.GetQueryString()));
var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString));
var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl); var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
if (results.Content.Contains("No torrents found")) if (results.Content.Contains("No torrents found"))

View File

@@ -86,11 +86,20 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString();
var searchUrl = BrowseUrl; var searchUrl = BrowseUrl;
var searchString = query.GetQueryString();
var cats = MapTorznabCapsToTrackers(query);
string cat = "0";
if (cats.Count == 1)
{
cat = cats[0];
}
if (!string.IsNullOrWhiteSpace(searchString) || cat != "0")
searchUrl += string.Format("?search={0}&cat={1}&searchin=0&sort=0", HttpUtility.UrlEncode(searchString), cat);
if (!string.IsNullOrWhiteSpace(searchString))
searchUrl += string.Format("?search={0}&cat=0&searchin=0&sort=0", HttpUtility.UrlEncode(searchString));
var response = await RequestStringWithCookiesAndRetry(searchUrl, null, BrowseUrl); var response = await RequestStringWithCookiesAndRetry(searchUrl, null, BrowseUrl);
var results = response.Content; var results = response.Content;
@@ -121,8 +130,8 @@ namespace Jackett.Indexers
release.Seeders = ParseUtil.CoerceInt(qRow.Find(".torrenttable:eq(8)").Text().Trim()); release.Seeders = ParseUtil.CoerceInt(qRow.Find(".torrenttable:eq(8)").Text().Trim());
release.Peers = ParseUtil.CoerceInt(qRow.Find(".torrenttable:eq(9)").Text().Trim()) + release.Seeders; release.Peers = ParseUtil.CoerceInt(qRow.Find(".torrenttable:eq(9)").Text().Trim()) + release.Seeders;
var cat = qRow.Find(".torrenttable:eq(0) a").First().Attr("href").Substring(15); var catId = qRow.Find(".torrenttable:eq(0) a").First().Attr("href").Substring(15);
release.Category = MapTrackerCatToNewznab(cat); release.Category = MapTrackerCatToNewznab(catId);
// Skip other // Skip other
if (release.Category != 0) if (release.Category != 0)

View File

@@ -55,10 +55,8 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
List<ReleaseInfo> releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(query.GetQueryString()));
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString();
var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString));
var response = await RequestStringWithCookiesAndRetry(episodeSearchUrl); var response = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
try try
{ {

View File

@@ -72,12 +72,11 @@ namespace Jackett.Indexers
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
string episodeSearchUrl; string episodeSearchUrl;
if (string.IsNullOrEmpty(query.SanitizedSearchTerm)) if (string.IsNullOrEmpty(query.GetQueryString()))
episodeSearchUrl = SearchUrl; episodeSearchUrl = SearchUrl;
else else
{ {
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); episodeSearchUrl = string.Format("{0}?search={1}&cat=0", SearchUrl, HttpUtility.UrlEncode(query.GetQueryString()));
episodeSearchUrl = string.Format("{0}?search={1}&cat=0", SearchUrl, HttpUtility.UrlEncode(searchString));
} }
var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl); var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl);

View File

@@ -68,8 +68,7 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(query.GetQueryString()));
var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString));
var response = await RequestStringWithCookiesAndRetry(episodeSearchUrl); var response = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
var results = response.Content; var results = response.Content;

View File

@@ -66,8 +66,7 @@ namespace Jackett.Indexers
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchurls = new List<string>(); var searchurls = new List<string>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var searchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(query.GetQueryString()));
var searchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString.Trim()));
var results = await RequestStringWithCookiesAndRetry(searchUrl); var results = await RequestStringWithCookiesAndRetry(searchUrl);
try try
{ {

View File

@@ -114,7 +114,7 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var searchString = query.GetQueryString();
var searchUrl = BrowseUrl; var searchUrl = BrowseUrl;
var queryCollection = new NameValueCollection(); var queryCollection = new NameValueCollection();

View File

@@ -98,12 +98,11 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString();
var searchUrl = BrowsePage; var searchUrl = BrowsePage;
if (!string.IsNullOrWhiteSpace(searchString)) if (!string.IsNullOrWhiteSpace(query.GetQueryString()))
{ {
searchUrl += string.Format(QueryString, HttpUtility.UrlEncode(searchString)); searchUrl += string.Format(QueryString, HttpUtility.UrlEncode(query.GetQueryString()));
} }
var results = await RequestStringWithCookiesAndRetry(searchUrl); var results = await RequestStringWithCookiesAndRetry(searchUrl);

View File

@@ -0,0 +1,15 @@
using Jackett.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Jackett.Indexers
{
public class ManualSearchResult
{
public List<TrackerCacheResult> Results { get; set; }
public List<string> Indexers { get; set; }
}
}

View File

@@ -89,8 +89,7 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode(query.GetQueryString());
var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode(searchString);
WebClientStringResult response = null; WebClientStringResult response = null;
response = await RequestStringWithCookiesAndRetry(episodeSearchUrl); response = await RequestStringWithCookiesAndRetry(episodeSearchUrl);

View File

@@ -74,9 +74,7 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(query.GetQueryString()));
var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString));
var response = await RequestStringWithCookiesAndRetry(episodeSearchUrl); var response = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
try try

View File

@@ -73,7 +73,6 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString();
var categoryMapping = MapTorznabCapsToTrackers(query).Distinct(); var categoryMapping = MapTorznabCapsToTrackers(query).Distinct();
string category = "0"; // Aka all string category = "0"; // Aka all
@@ -83,7 +82,7 @@ namespace Jackett.Indexers
} }
var episodeSearchUrl = string.Format(SearchUrl, category, HttpUtility.UrlEncode(searchString)); var episodeSearchUrl = string.Format(SearchUrl, category, HttpUtility.UrlEncode(query.GetQueryString()));
var response = await RequestStringWithCookiesAndRetry(episodeSearchUrl); var response = await RequestStringWithCookiesAndRetry(episodeSearchUrl);

View File

@@ -96,7 +96,7 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var searchString = query.GetQueryString();
var searchCategory = CAT_ANY; var searchCategory = CAT_ANY;
if (query.Categories.Contains(TorznabCatType.TV.ID) || if (query.Categories.Contains(TorznabCatType.TV.ID) ||

View File

@@ -65,10 +65,9 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString();
var searchSection = string.IsNullOrEmpty(query.Episode) ? "archive" : "browse"; var searchSection = string.IsNullOrEmpty(query.Episode) ? "archive" : "browse";
var searchCategory = string.IsNullOrEmpty(query.Episode) ? "26" : "27"; var searchCategory = string.IsNullOrEmpty(query.Episode) ? "26" : "27";
var searchUrl = string.Format(SearchUrl, searchSection, searchCategory, searchString); var searchUrl = string.Format(SearchUrl, searchSection, searchCategory, query.GetQueryString());
var results = await RequestStringWithCookiesAndRetry(searchUrl); var results = await RequestStringWithCookiesAndRetry(searchUrl);
try try

View File

@@ -72,8 +72,7 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var results = await PostDataWithCookiesAndRetry(SearchUrl, GetSearchFormData(query.GetQueryString()));
var results = await PostDataWithCookiesAndRetry(SearchUrl, GetSearchFormData(searchString));
try try
{ {

View File

@@ -82,7 +82,6 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString();
var episodeSearchUrl = string.Format(SearchAllUrl); var episodeSearchUrl = string.Format(SearchAllUrl);
var result = await RequestStringWithCookiesAndRetry(episodeSearchUrl, string.Empty); var result = await RequestStringWithCookiesAndRetry(episodeSearchUrl, string.Empty);
var xmlDoc = new XmlDocument(); var xmlDoc = new XmlDocument();

View File

@@ -80,9 +80,7 @@ namespace Jackett.Indexers
List<ReleaseInfo> releases = new List<ReleaseInfo>(); List<ReleaseInfo> releases = new List<ReleaseInfo>();
var searchTerm = string.IsNullOrEmpty(query.SanitizedSearchTerm) ? "2015" : query.SanitizedSearchTerm; var searchTerm = string.IsNullOrEmpty(query.SanitizedSearchTerm) ? "2015" : query.SanitizedSearchTerm;
var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(query.GetQueryString()));
var searchString = searchTerm + " " + query.GetEpisodeSearchString();
var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString.Trim()));
var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl, string.Empty); var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl, string.Empty);
try try
{ {

View File

@@ -137,7 +137,7 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var searchString = query.GetQueryString();
// If we have no query use the RSS Page as their server is slow enough at times! // If we have no query use the RSS Page as their server is slow enough at times!
if (string.IsNullOrWhiteSpace(searchString)) if (string.IsNullOrWhiteSpace(searchString))

View File

@@ -78,8 +78,7 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var queryStr = HttpUtility.UrlEncode(query.GetQueryString());
var queryStr = HttpUtility.UrlEncode(searchString);
var episodeSearchUrl = string.Format(SearchUrl, queryStr); var episodeSearchUrl = string.Format(SearchUrl, queryStr);
var response = await RequestStringWithCookiesAndRetry(episodeSearchUrl, string.Empty); var response = await RequestStringWithCookiesAndRetry(episodeSearchUrl, string.Empty);

View File

@@ -96,7 +96,7 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var searchString = query.GetQueryString();
var searchUrl = BrowseUrl; var searchUrl = BrowseUrl;
var trackerCats = MapTorznabCapsToTrackers(query); var trackerCats = MapTorznabCapsToTrackers(query);
var queryCollection = new NameValueCollection(); var queryCollection = new NameValueCollection();

View File

@@ -145,7 +145,7 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var searchString = query.GetQueryString();
var queryUrl = SearchUrl; var queryUrl = SearchUrl;
var queryCollection = new NameValueCollection(); var queryCollection = new NameValueCollection();

View File

@@ -102,7 +102,7 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var searchString = query.GetQueryString();
var searchUrl = SearchUrl; var searchUrl = SearchUrl;
if (!string.IsNullOrWhiteSpace(searchString)) if (!string.IsNullOrWhiteSpace(searchString))

View File

@@ -67,7 +67,7 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var searchString = query.GetQueryString();
var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString)); var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString));
var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl); var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
try try

View File

@@ -78,7 +78,7 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
var releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var searchString = query.GetQueryString();
var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString.Trim())); var episodeSearchUrl = string.Format(SearchUrl, HttpUtility.UrlEncode(searchString.Trim()));
var xmlDoc = new XmlDocument(); var xmlDoc = new XmlDocument();
string xml = string.Empty; string xml = string.Empty;

View File

@@ -116,10 +116,8 @@ namespace Jackett.Indexers
public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query) public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{ {
List<ReleaseInfo> releases = new List<ReleaseInfo>(); var releases = new List<ReleaseInfo>();
var results = await PostDataWithCookiesAndRetry(SearchUrl, GetSearchFormData(query.GetQueryString()));
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString();
var results = await PostDataWithCookiesAndRetry(SearchUrl, GetSearchFormData(searchString));
try try
{ {

View File

@@ -189,6 +189,7 @@
<Compile Include="Indexers\IIndexer.cs" /> <Compile Include="Indexers\IIndexer.cs" />
<Compile Include="Indexers\ImmortalSeed.cs" /> <Compile Include="Indexers\ImmortalSeed.cs" />
<Compile Include="Indexers\FileList.cs" /> <Compile Include="Indexers\FileList.cs" />
<Compile Include="Indexers\ManualSearchResult.cs" />
<Compile Include="Indexers\TVChaosUK.cs" /> <Compile Include="Indexers\TVChaosUK.cs" />
<Compile Include="Indexers\NCore.cs" /> <Compile Include="Indexers\NCore.cs" />
<Compile Include="Indexers\RuTor.cs" /> <Compile Include="Indexers\RuTor.cs" />
@@ -212,6 +213,7 @@
<Compile Include="Models\CachedLog.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\AdminSearch.cs" />
<Compile Include="Models\IndexerConfig\ConfigurationDataFileList.cs" /> <Compile Include="Models\IndexerConfig\ConfigurationDataFileList.cs" />
<Compile Include="Models\IndexerConfig\ConfigurationDataBasicLoginWithRSS.cs" /> <Compile Include="Models\IndexerConfig\ConfigurationDataBasicLoginWithRSS.cs" />
<Compile Include="Models\IndexerConfig\ConfigurationDataRecaptchaLogin.cs" /> <Compile Include="Models\IndexerConfig\ConfigurationDataRecaptchaLogin.cs" />

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Jackett.Models
{
public class AdminSearch
{
public string Query { get; set; }
public string Tracker { get; set; }
public int Category { get; set; }
}
}

View File

@@ -47,6 +47,11 @@ namespace Jackett.Models
Categories = new int[0]; Categories = new int[0];
} }
public string GetQueryString()
{
return (SanitizedSearchTerm + " " + GetEpisodeSearchString()).Trim();
}
public string GetEpisodeSearchString() public string GetEpisodeSearchString()
{ {
if (Season == 0) if (Season == 0)
@@ -118,5 +123,24 @@ namespace Jackett.Models
return q; return q;
} }
public void ExpandCatsToSubCats()
{
if (Categories.Count() == 0)
return;
var newCatList = new List<int>();
newCatList.AddRange(Categories);
foreach (var cat in Categories)
{
var majorCat = TorznabCatType.AllCats.Where(c => c.ID == cat).FirstOrDefault();
// If we search for TV we should also search for all sub cats
if (majorCat != null)
{
newCatList.AddRange(majorCat.SubCategories.Select(s => s.ID));
}
}
Categories = newCatList.Distinct().ToArray();
}
} }
} }