Adds Anime-specific searching and Fanzub support
Splits searching in the same way as a Daily search, each indexer has a method to search specifically for anime. Fanzub support was also added, with its own indexer and parser classes.
This commit is contained in:
parent
a75ce9ab87
commit
828dd5f5ad
|
@ -0,0 +1,14 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.IndexerSearch.Definitions
|
||||||
|
{
|
||||||
|
public class AnimeEpisodeSearchCriteria : SearchCriteriaBase
|
||||||
|
{
|
||||||
|
public int AbsoluteEpisodeNumber { get; set; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return string.Format("[{0} : {1:00}]", SceneTitle, AbsoluteEpisodeNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -70,6 +70,10 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
|
|
||||||
return SearchDaily(series, episode);
|
return SearchDaily(series, episode);
|
||||||
}
|
}
|
||||||
|
if (series.SeriesType == SeriesTypes.Anime)
|
||||||
|
{
|
||||||
|
return SearchAnime(series, episode);
|
||||||
|
}
|
||||||
|
|
||||||
if (episode.SeasonNumber == 0)
|
if (episode.SeasonNumber == 0)
|
||||||
{
|
{
|
||||||
|
@ -116,6 +120,17 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
return Dispatch(indexer => _feedFetcher.Fetch(indexer, searchSpec), searchSpec);
|
return Dispatch(indexer => _feedFetcher.Fetch(indexer, searchSpec), searchSpec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<DownloadDecision> SearchAnime(Series series, Episode episode)
|
||||||
|
{
|
||||||
|
var searchSpec = Get<AnimeEpisodeSearchCriteria>(series, new List<Episode> { episode });
|
||||||
|
// TODO: Get the scene title from TheXEM
|
||||||
|
searchSpec.SceneTitle = series.Title;
|
||||||
|
// TODO: Calculate the Absolute Episode Number on the fly (if I have to)
|
||||||
|
searchSpec.AbsoluteEpisodeNumber = episode.AbsoluteEpisodeNumber.GetValueOrDefault(0);
|
||||||
|
|
||||||
|
return Dispatch(indexer => _feedFetcher.Fetch(indexer, searchSpec), searchSpec);
|
||||||
|
}
|
||||||
|
|
||||||
private List<DownloadDecision> SearchSpecial(Series series, List<Episode> episodes)
|
private List<DownloadDecision> SearchSpecial(Series series, List<Episode> episodes)
|
||||||
{
|
{
|
||||||
var searchSpec = Get<SpecialEpisodeSearchCriteria>(series, episodes);
|
var searchSpec = Get<SpecialEpisodeSearchCriteria>(series, episodes);
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Indexers.Fanzub
|
||||||
|
{
|
||||||
|
public class Fanzub : IndexerBase<NullConfig>
|
||||||
|
{
|
||||||
|
public override DownloadProtocol Protocol
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return DownloadProtocol.Usenet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool SupportsPaging
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool SupportsSearching
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IParseFeed Parser
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new FanzubParser();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<string> RecentFeed
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
yield return "http://fanzub.com/rss/?cat=anime";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<string> GetEpisodeSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int episodeNumber)
|
||||||
|
{
|
||||||
|
return new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<string> GetSeasonSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int offset)
|
||||||
|
{
|
||||||
|
return new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<string> GetDailyEpisodeSearchUrls(string seriesTitle, int tvRageId, DateTime date)
|
||||||
|
{
|
||||||
|
return new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<string> GetAnimeEpisodeSearchUrls(string seriesTitle, int tvRageId, int absoluteEpisodeNumber)
|
||||||
|
{
|
||||||
|
return RecentFeed.Select(url => String.Format("{0}&q={1}%20{2}", url, seriesTitle, absoluteEpisodeNumber));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<string> GetSearchUrls(string query, int offset)
|
||||||
|
{
|
||||||
|
return new List<string>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Indexers.Fanzub
|
||||||
|
{
|
||||||
|
public class FanzubParser : RssParserBase
|
||||||
|
{
|
||||||
|
protected override string GetNzbInfoUrl(XElement item)
|
||||||
|
{
|
||||||
|
IEnumerable<XElement> matches = item.DescendantsAndSelf("link");
|
||||||
|
if (matches.Any())
|
||||||
|
{
|
||||||
|
return matches.First().Value;
|
||||||
|
}
|
||||||
|
return String.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override long GetSize(XElement item)
|
||||||
|
{
|
||||||
|
IEnumerable<XElement> matches = item.DescendantsAndSelf("enclosure");
|
||||||
|
if (matches.Any())
|
||||||
|
{
|
||||||
|
XElement enclosureElement = matches.First();
|
||||||
|
return Convert.ToInt64(enclosureElement.Attribute("length").Value);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,6 +15,7 @@ namespace NzbDrone.Core.Indexers
|
||||||
IEnumerable<string> RecentFeed { get; }
|
IEnumerable<string> RecentFeed { get; }
|
||||||
IEnumerable<string> GetEpisodeSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int episodeNumber);
|
IEnumerable<string> GetEpisodeSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int episodeNumber);
|
||||||
IEnumerable<string> GetDailyEpisodeSearchUrls(string seriesTitle, int tvRageId, DateTime date);
|
IEnumerable<string> GetDailyEpisodeSearchUrls(string seriesTitle, int tvRageId, DateTime date);
|
||||||
|
IEnumerable<string> GetAnimeEpisodeSearchUrls(string seriesTitle, int tvRageId, int absoluteEpisodeNumber);
|
||||||
IEnumerable<string> GetSeasonSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int offset);
|
IEnumerable<string> GetSeasonSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int offset);
|
||||||
IEnumerable<string> GetSearchUrls(string query, int offset = 0);
|
IEnumerable<string> GetSearchUrls(string query, int offset = 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ namespace NzbDrone.Core.Indexers
|
||||||
public abstract IEnumerable<string> RecentFeed { get; }
|
public abstract IEnumerable<string> RecentFeed { get; }
|
||||||
public abstract IEnumerable<string> GetEpisodeSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int episodeNumber);
|
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> GetDailyEpisodeSearchUrls(string seriesTitle, int tvRageId, DateTime date);
|
||||||
|
public abstract IEnumerable<string> GetAnimeEpisodeSearchUrls(string seriesTitle, int tvRageId, int absoluteEpisodeNumber);
|
||||||
public abstract IEnumerable<string> GetSeasonSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int offset);
|
public abstract IEnumerable<string> GetSeasonSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int offset);
|
||||||
public abstract IEnumerable<string> GetSearchUrls(string query, int offset);
|
public abstract IEnumerable<string> GetSearchUrls(string query, int offset);
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ namespace NzbDrone.Core.Indexers
|
||||||
IList<ReleaseInfo> Fetch(IIndexer indexer, SeasonSearchCriteria searchCriteria);
|
IList<ReleaseInfo> Fetch(IIndexer indexer, SeasonSearchCriteria searchCriteria);
|
||||||
IList<ReleaseInfo> Fetch(IIndexer indexer, SingleEpisodeSearchCriteria searchCriteria);
|
IList<ReleaseInfo> Fetch(IIndexer indexer, SingleEpisodeSearchCriteria searchCriteria);
|
||||||
IList<ReleaseInfo> Fetch(IIndexer indexer, DailyEpisodeSearchCriteria searchCriteria);
|
IList<ReleaseInfo> Fetch(IIndexer indexer, DailyEpisodeSearchCriteria searchCriteria);
|
||||||
|
IList<ReleaseInfo> Fetch(IIndexer indexer, AnimeEpisodeSearchCriteria searchCriteria);
|
||||||
IList<ReleaseInfo> Fetch(IIndexer indexer, SpecialEpisodeSearchCriteria searchCriteria);
|
IList<ReleaseInfo> Fetch(IIndexer indexer, SpecialEpisodeSearchCriteria searchCriteria);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,6 +94,17 @@ namespace NzbDrone.Core.Indexers
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IList<ReleaseInfo> Fetch(IIndexer indexer, AnimeEpisodeSearchCriteria searchCriteria)
|
||||||
|
{
|
||||||
|
_logger.Debug("Searching for {0}", searchCriteria);
|
||||||
|
|
||||||
|
var searchUrls = indexer.GetAnimeEpisodeSearchUrls(searchCriteria.QueryTitle, searchCriteria.Series.TvRageId, searchCriteria.AbsoluteEpisodeNumber);
|
||||||
|
var result = Fetch(indexer, searchUrls);
|
||||||
|
_logger.Info("Finished searching {0} for {1}. Found {2}", indexer, searchCriteria, result.Count);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public IList<ReleaseInfo> Fetch(IIndexer indexer, SpecialEpisodeSearchCriteria searchCriteria)
|
public IList<ReleaseInfo> Fetch(IIndexer indexer, SpecialEpisodeSearchCriteria searchCriteria)
|
||||||
{
|
{
|
||||||
var queryUrls = new List<String>();
|
var queryUrls = new List<String>();
|
||||||
|
|
|
@ -125,6 +125,12 @@ namespace NzbDrone.Core.Indexers.Newznab
|
||||||
return RecentFeed.Select(url => String.Format("{0}&limit=100&q={1}&season={2:yyyy}&ep={2:MM}/{2:dd}", url, NewsnabifyTitle(seriesTitle), date)).ToList();
|
return RecentFeed.Select(url => String.Format("{0}&limit=100&q={1}&season={2:yyyy}&ep={2:MM}/{2:dd}", url, NewsnabifyTitle(seriesTitle), date)).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<string> GetAnimeEpisodeSearchUrls(string seriesTitle, int tvRageId, int absoluteEpisodeNumber)
|
||||||
|
{
|
||||||
|
// TODO: Implement
|
||||||
|
return new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
public override IEnumerable<string> GetSeasonSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int offset)
|
public override IEnumerable<string> GetSeasonSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int offset)
|
||||||
{
|
{
|
||||||
if (tvRageId > 0)
|
if (tvRageId > 0)
|
||||||
|
|
|
@ -48,6 +48,12 @@ namespace NzbDrone.Core.Indexers.Omgwtfnzbs
|
||||||
return searchUrls;
|
return searchUrls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<string> GetAnimeEpisodeSearchUrls(string seriesTitle, int tvRageId, int absoluteEpisodeNumber)
|
||||||
|
{
|
||||||
|
// TODO: Implement
|
||||||
|
return new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
public override IEnumerable<string> GetSeasonSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int offset)
|
public override IEnumerable<string> GetSeasonSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int offset)
|
||||||
{
|
{
|
||||||
var searchUrls = new List<String>();
|
var searchUrls = new List<String>();
|
||||||
|
|
|
@ -37,6 +37,11 @@ namespace NzbDrone.Core.Indexers.Wombles
|
||||||
return new List<string>();
|
return new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<string> GetAnimeEpisodeSearchUrls(string seriesTitle, int tvRageId, int absoluteEpisodeNumber)
|
||||||
|
{
|
||||||
|
return new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
public override IEnumerable<string> GetSearchUrls(string query, int offset)
|
public override IEnumerable<string> GetSearchUrls(string query, int offset)
|
||||||
{
|
{
|
||||||
return new List<string>();
|
return new List<string>();
|
||||||
|
|
|
@ -311,6 +311,7 @@
|
||||||
<Compile Include="Housekeeping\HousekeepingCommand.cs" />
|
<Compile Include="Housekeeping\HousekeepingCommand.cs" />
|
||||||
<Compile Include="Housekeeping\HousekeepingService.cs" />
|
<Compile Include="Housekeeping\HousekeepingService.cs" />
|
||||||
<Compile Include="Housekeeping\IHousekeepingTask.cs" />
|
<Compile Include="Housekeeping\IHousekeepingTask.cs" />
|
||||||
|
<Compile Include="IndexerSearch\Definitions\AnimeEpisodeSearchCriteria.cs" />
|
||||||
<Compile Include="IndexerSearch\MissingEpisodeSearchCommand.cs" />
|
<Compile Include="IndexerSearch\MissingEpisodeSearchCommand.cs" />
|
||||||
<Compile Include="IndexerSearch\Definitions\SpecialEpisodeSearchCriteria.cs" />
|
<Compile Include="IndexerSearch\Definitions\SpecialEpisodeSearchCriteria.cs" />
|
||||||
<Compile Include="IndexerSearch\SeriesSearchService.cs" />
|
<Compile Include="IndexerSearch\SeriesSearchService.cs" />
|
||||||
|
@ -323,6 +324,9 @@
|
||||||
<Compile Include="Indexers\DownloadProtocol.cs" />
|
<Compile Include="Indexers\DownloadProtocol.cs" />
|
||||||
<Compile Include="Indexers\Exceptions\ApiKeyException.cs" />
|
<Compile Include="Indexers\Exceptions\ApiKeyException.cs" />
|
||||||
<Compile Include="Indexers\Exceptions\RequestLimitReachedException.cs" />
|
<Compile Include="Indexers\Exceptions\RequestLimitReachedException.cs" />
|
||||||
|
<Compile Include="Indexers\Eztv\Eztv.cs" />
|
||||||
|
<Compile Include="Indexers\Fanzub\Fanzub.cs" />
|
||||||
|
<Compile Include="Indexers\Fanzub\FanzubParser.cs" />
|
||||||
<Compile Include="Indexers\FetchAndParseRssService.cs" />
|
<Compile Include="Indexers\FetchAndParseRssService.cs" />
|
||||||
<Compile Include="Indexers\IIndexer.cs" />
|
<Compile Include="Indexers\IIndexer.cs" />
|
||||||
<Compile Include="Indexers\IndexerSettingUpdatedEvent.cs" />
|
<Compile Include="Indexers\IndexerSettingUpdatedEvent.cs" />
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
<TargetFrameworkProfile>
|
<TargetFrameworkProfile>
|
||||||
</TargetFrameworkProfile>
|
</TargetFrameworkProfile>
|
||||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||||
|
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
|
||||||
|
<RestorePackages>true</RestorePackages>
|
||||||
<PublishUrl>publish\</PublishUrl>
|
<PublishUrl>publish\</PublishUrl>
|
||||||
<Install>true</Install>
|
<Install>true</Install>
|
||||||
<InstallFrom>Disk</InstallFrom>
|
<InstallFrom>Disk</InstallFrom>
|
||||||
|
@ -29,8 +31,6 @@
|
||||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||||
<UseApplicationTrust>false</UseApplicationTrust>
|
<UseApplicationTrust>false</UseApplicationTrust>
|
||||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
|
|
||||||
<RestorePackages>true</RestorePackages>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
|
Loading…
Reference in New Issue