Indexer searching for special episodes using query string

Added SpecialEpisodeSearchCriteria criteria to handle special episode search queries
Added method NzbSearchService.SearchSpecial() for season0 episodes
Added IIndexer GetSearchUrls() for doing text based queries
This commit is contained in:
Icer Addis 2014-01-07 00:21:05 -08:00
parent 16356b6319
commit d727840fbf
11 changed files with 96 additions and 3 deletions

View File

@ -23,7 +23,7 @@ namespace NzbDrone.Core.IndexerSearch.Definitions
}
}
private static string GetQueryTitle(string title)
public static string GetQueryTitle(string title)
{
Ensure.That(title,() => title).IsNotNullOrWhiteSpace();

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NzbDrone.Core.IndexerSearch.Definitions
{
public class SpecialEpisodeSearchCriteria : SearchCriteriaBase
{
public string[] EpisodeQueryTitles { get; set; }
public override string ToString()
{
var sb = new StringBuilder();
bool delimiter = false;
foreach (var title in EpisodeQueryTitles)
{
if (delimiter)
{
sb.Append(',');
}
sb.Append(title);
delimiter = true;
}
return string.Format("[{0} : {1}]", SceneTitle, sb.ToString());
}
}
}

View File

@ -64,6 +64,12 @@ namespace NzbDrone.Core.IndexerSearch
return SearchDaily(series, episode);
}
if (episode.SeasonNumber == 0)
{
// search for special episodes in season 0
return SearchSpecial(series, new List<Episode>{episode});
}
return SearchSingle(series, episode);
}
@ -103,11 +109,28 @@ namespace NzbDrone.Core.IndexerSearch
return Dispatch(indexer => _feedFetcher.Fetch(indexer, searchSpec), searchSpec);
}
private List<DownloadDecision> SearchSpecial(Series series, List<Episode> episodes)
{
var searchSpec = Get<SpecialEpisodeSearchCriteria>(series, episodes);
// build list of queries for each episode in the form: "<series> <episode-title>"
searchSpec.EpisodeQueryTitles = episodes.Where(e => !String.IsNullOrWhiteSpace(e.Title))
.Select(e => searchSpec.QueryTitle + "+" + SearchCriteriaBase.GetQueryTitle(e.Title))
.ToArray();
return Dispatch(indexer => _feedFetcher.Fetch(indexer, searchSpec), searchSpec);
}
public List<DownloadDecision> SeasonSearch(int seriesId, int seasonNumber)
{
var series = _seriesService.GetSeries(seriesId);
var episodes = _episodeService.GetEpisodesBySeason(seriesId, seasonNumber);
if (seasonNumber == 0)
{
// search for special episodes in season 0
return SearchSpecial(series, episodes);
}
var searchSpec = Get<SeasonSearchCriteria>(series, episodes);
searchSpec.SeasonNumber = seasonNumber;

View File

@ -46,5 +46,10 @@ namespace NzbDrone.Core.Indexers.Eztv
//EZTV doesn't support searching based on actual episode airdate. they only support release date.
return new string[0];
}
public override IEnumerable<string> GetSearchUrls(string query, int offset)
{
return new List<string>();
}
}
}

View File

@ -13,5 +13,6 @@ namespace NzbDrone.Core.Indexers
IEnumerable<string> GetEpisodeSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int episodeNumber);
IEnumerable<string> GetDailyEpisodeSearchUrls(string seriesTitle, int tvRageId, DateTime date);
IEnumerable<string> GetSeasonSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int offset);
IEnumerable<string> GetSearchUrls(string query, int offset = 0);
}
}

View File

@ -48,6 +48,7 @@ namespace NzbDrone.Core.Indexers
public abstract IEnumerable<string> GetEpisodeSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int episodeNumber);
public abstract IEnumerable<string> GetDailyEpisodeSearchUrls(string seriesTitle, int tvRageId, DateTime date);
public abstract IEnumerable<string> GetSeasonSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int offset);
public abstract IEnumerable<string> GetSearchUrls(string query, int offset);
public override string ToString()
{

View File

@ -17,6 +17,7 @@ namespace NzbDrone.Core.Indexers
IList<ReleaseInfo> Fetch(IIndexer indexer, SeasonSearchCriteria searchCriteria);
IList<ReleaseInfo> Fetch(IIndexer indexer, SingleEpisodeSearchCriteria searchCriteria);
IList<ReleaseInfo> Fetch(IIndexer indexer, DailyEpisodeSearchCriteria searchCriteria);
IList<ReleaseInfo> Fetch(IIndexer indexer, SpecialEpisodeSearchCriteria searchCriteria);
}
public class FetchFeedService : IFetchFeedFromIndexers
@ -77,9 +78,8 @@ namespace NzbDrone.Core.Indexers
var searchUrls = indexer.GetEpisodeSearchUrls(searchCriteria.QueryTitle, searchCriteria.Series.TvRageId, searchCriteria.SeasonNumber, searchCriteria.EpisodeNumber);
var result = Fetch(indexer, searchUrls);
_logger.Info("Finished searching {0} for {1}. Found {2}", indexer, searchCriteria, result.Count);
return result;
}
@ -94,6 +94,20 @@ namespace NzbDrone.Core.Indexers
return result;
}
public IList<ReleaseInfo> Fetch(IIndexer indexer, SpecialEpisodeSearchCriteria searchCriteria)
{
var queryUrls = new List<String>();
foreach (var episodeQueryTitle in searchCriteria.EpisodeQueryTitles)
{
_logger.Debug("Performing query of {0} for {1}", indexer, episodeQueryTitle);
queryUrls.AddRange(indexer.GetSearchUrls(episodeQueryTitle));
}
var result = Fetch(indexer, queryUrls);
_logger.Info("Finished searching {0} for {1}. Found {2}", indexer, searchCriteria, result.Count);
return result;
}
private List<ReleaseInfo> Fetch(IIndexer indexer, IEnumerable<string> urls)
{
var result = new List<ReleaseInfo>();

View File

@ -104,6 +104,15 @@ namespace NzbDrone.Core.Indexers.Newznab
return RecentFeed.Select(url => String.Format("{0}&limit=100&q={1}&season={2}&ep={3}", url, NewsnabifyTitle(seriesTitle), seasonNumber, episodeNumber));
}
public override IEnumerable<string> GetSearchUrls(string query, int offset)
{
// encode query (replace the + with spaces first)
query = query.Replace("+", " ");
query = System.Web.HttpUtility.UrlEncode(query);
return RecentFeed.Select(url => String.Format("{0}&offset={1}&limit=100&q={2}", url.Replace("t=tvsearch", "t=search"), offset, query));
}
public override IEnumerable<string> GetDailyEpisodeSearchUrls(string seriesTitle, int tvRageId, DateTime date)
{
if (tvRageId > 0)

View File

@ -66,5 +66,11 @@ namespace NzbDrone.Core.Indexers.Omgwtfnzbs
return searchUrls;
}
public override IEnumerable<string> GetSearchUrls(string query, int offset)
{
return new List<string>();
}
}
}

View File

@ -41,5 +41,10 @@ namespace NzbDrone.Core.Indexers.Wombles
{
return new List<string>();
}
public override IEnumerable<string> GetSearchUrls(string query, int offset)
{
return new List<string>();
}
}
}

View File

@ -259,6 +259,7 @@
<Compile Include="Housekeeping\HousekeepingCommand.cs" />
<Compile Include="Housekeeping\HousekeepingService.cs" />
<Compile Include="Housekeeping\IHousekeepingTask.cs" />
<Compile Include="IndexerSearch\Definitions\SpecialEpisodeSearchCriteria.cs" />
<Compile Include="IndexerSearch\SeriesSearchService.cs" />
<Compile Include="IndexerSearch\SeriesSearchCommand.cs" />
<Compile Include="IndexerSearch\EpisodeSearchService.cs" />