mirror of
https://github.com/Radarr/Radarr.git
synced 2024-09-11 12:02:35 +02:00
Added sabtitle method
Added custom parse option to Indexrbase
This commit is contained in:
parent
9028e498ca
commit
10ad7d1ed5
@ -1,10 +1,13 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Linq.Expressions;
|
||||||
using AutoMoq;
|
using AutoMoq;
|
||||||
using FizzWare.NBuilder;
|
using FizzWare.NBuilder;
|
||||||
using MbUnit.Framework;
|
using MbUnit.Framework;
|
||||||
using Moq;
|
using Moq;
|
||||||
|
using NzbDrone.Core.Model;
|
||||||
using NzbDrone.Core.Providers;
|
using NzbDrone.Core.Providers;
|
||||||
using NzbDrone.Core.Repository;
|
using NzbDrone.Core.Repository;
|
||||||
using NzbDrone.Core.Repository.Quality;
|
using NzbDrone.Core.Repository.Quality;
|
||||||
@ -54,42 +57,142 @@ public void RefreshEpisodeInfo()
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void IsNeededTrue()
|
|
||||||
|
//Should Download
|
||||||
|
[Row(QualityTypes.TV, true, QualityTypes.TV, false, true)]
|
||||||
|
[Row(QualityTypes.DVD, true, QualityTypes.TV, true, true)]
|
||||||
|
[Row(QualityTypes.DVD, true, QualityTypes.TV, true, true)]
|
||||||
|
//Should Skip
|
||||||
|
[Row(QualityTypes.Bluray720, true, QualityTypes.Bluray1080, false, false)]
|
||||||
|
[Row(QualityTypes.TV, true, QualityTypes.HDTV, true, false)]
|
||||||
|
public void Is_Needed_Tv_Dvd_BluRay_BluRay720_Is_Cutoff(QualityTypes reportQuality, Boolean isReportProper, QualityTypes fileQuality, Boolean isFileProper, bool excpected)
|
||||||
{
|
{
|
||||||
//Setup
|
//Setup
|
||||||
var season = new Mock<SeasonProvider>();
|
var parseResult = new EpisodeParseResult
|
||||||
var series = new Mock<SeriesProvider>();
|
{
|
||||||
//var history = new Mock<IHistoryProvider>();
|
SeriesId = 12,
|
||||||
//var quality = new Mock<IQualityProvider>();
|
SeasonNumber = 2,
|
||||||
var repo = new Mock<IRepository>();
|
Episodes = new List<int> { 3 },
|
||||||
|
Quality = reportQuality,
|
||||||
|
Proper = isReportProper
|
||||||
|
};
|
||||||
|
|
||||||
var epInDb = new Episode
|
var epFile = new EpisodeFile()
|
||||||
{
|
{
|
||||||
AirDate = DateTime.Today,
|
Proper = isFileProper,
|
||||||
EpisodeId = 55555,
|
Quality = fileQuality
|
||||||
EpisodeNumber = 5,
|
};
|
||||||
Language = "en",
|
|
||||||
SeasonId = 4444,
|
|
||||||
SeasonNumber = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
season.Setup(s => s.IsIgnored(12345, 1)).Returns(false);
|
var episodeInfo = new Episode
|
||||||
series.Setup(s => s.QualityWanted(12345, QualityTypes.TV)).Returns(true);
|
{
|
||||||
repo.Setup(s => s.Single<Episode>(c => c.SeriesId == 12345 && c.SeasonNumber == 1 && c.EpisodeNumber == 5)).
|
SeriesId = 12,
|
||||||
Returns(epInDb);
|
SeasonNumber = 2,
|
||||||
|
EpisodeNumber = 3,
|
||||||
|
Series = new Series() { QualityProfileId = 1 },
|
||||||
|
EpisodeFile = epFile
|
||||||
|
|
||||||
//repo.Setup(s => s.All<EpisodeFile>()).Returns();
|
};
|
||||||
//repo.All<EpisodeFile>().Where(c => c.EpisodeId == episode.EpisodeId);
|
|
||||||
|
|
||||||
|
var seriesQualityProfile = new QualityProfile()
|
||||||
|
{
|
||||||
|
Allowed = new List<QualityTypes> { QualityTypes.TV, QualityTypes.DVD, QualityTypes.Bluray720, QualityTypes.Bluray1080 },
|
||||||
|
Cutoff = QualityTypes.Bluray720,
|
||||||
|
Name = "TV/DVD",
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var mocker = new AutoMoqer();
|
||||||
|
mocker.GetMock<IRepository>()
|
||||||
|
.Setup(r => r.Single(It.IsAny<Expression<Func<Episode, Boolean>>>()))
|
||||||
|
.Returns(episodeInfo);
|
||||||
|
|
||||||
|
mocker.GetMock<QualityProvider>()
|
||||||
|
.Setup(q => q.Find(1))
|
||||||
|
.Returns(seriesQualityProfile);
|
||||||
|
|
||||||
|
var result = mocker.Resolve<EpisodeProvider>().IsNeeded(parseResult);
|
||||||
|
|
||||||
|
Assert.AreEqual(excpected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Missing_episode_should_be_added()
|
||||||
|
{
|
||||||
|
//Setup
|
||||||
|
var parseResult1 = new EpisodeParseResult
|
||||||
|
{
|
||||||
|
SeriesId = 12,
|
||||||
|
SeasonNumber = 2,
|
||||||
|
Episodes = new List<int> { 3 },
|
||||||
|
Quality = QualityTypes.DVD
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
var parseResult2 = new EpisodeParseResult
|
||||||
|
{
|
||||||
|
SeriesId = 12,
|
||||||
|
SeasonNumber = 3,
|
||||||
|
Episodes = new List<int> { 3 },
|
||||||
|
Quality = QualityTypes.DVD
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
var mocker = new AutoMoqer();
|
||||||
|
mocker.SetConstant(MockLib.GetEmptyRepository());
|
||||||
|
|
||||||
|
var episodeProvider = mocker.Resolve<EpisodeProvider>();
|
||||||
|
var result1 = episodeProvider.IsNeeded(parseResult1);
|
||||||
|
var result2 = episodeProvider.IsNeeded(parseResult2);
|
||||||
|
var episodes = episodeProvider.GetEpisodeBySeries(12);
|
||||||
|
Assert.IsTrue(result1);
|
||||||
|
Assert.IsTrue(result2);
|
||||||
|
Assert.IsNotEmpty(episodes);
|
||||||
|
Assert.Count(2, episodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
[Row(1, new[] { 2 }, "My Episode Title", QualityTypes.DVD, false, "My Series Name - 1x2 - My Episode Title DVD")]
|
||||||
|
[Row(1, new[] { 2 }, "My Episode Title", QualityTypes.DVD, true, "My Series Name - 1x2 - My Episode Title DVD [Proper]")]
|
||||||
|
[Row(1, new[] { 2 }, "", QualityTypes.DVD, true, "My Series Name - 1x2 - DVD [Proper]")]
|
||||||
|
[Row(1, new[] { 2, 4 }, "My Episode Title", QualityTypes.HDTV, false, "My Series Name - 1x2-1x4 - My Episode Title HDTV")]
|
||||||
|
[Row(1, new[] { 2, 4 }, "My Episode Title", QualityTypes.HDTV, true, "My Series Name - 1x2-1x4 - My Episode Title HDTV [Proper]")]
|
||||||
|
[Row(1, new[] { 2, 4 }, "", QualityTypes.HDTV, true, "My Series Name - 1x2-1x4 - HDTV [Proper]")]
|
||||||
|
public void sab_title(int seasons, int[] episodes, string title, QualityTypes quality, bool proper, string excpected)
|
||||||
|
{
|
||||||
|
//Arrange
|
||||||
|
var fakeSeries = new Series()
|
||||||
|
{
|
||||||
|
SeriesId = 12,
|
||||||
|
Path = "C:\\TV Shows\\My Series Name"
|
||||||
|
};
|
||||||
|
|
||||||
|
var mocker = new AutoMoqer();
|
||||||
|
mocker.GetMock<SeriesProvider>(MockBehavior.Strict)
|
||||||
|
.Setup(c => c.GetSeries(12))
|
||||||
|
.Returns(fakeSeries);
|
||||||
|
|
||||||
|
var parsResult = new EpisodeParseResult()
|
||||||
|
{
|
||||||
|
SeriesId = 12,
|
||||||
|
AirDate = DateTime.Now,
|
||||||
|
Episodes = episodes.ToList(),
|
||||||
|
Proper = proper,
|
||||||
|
Quality = quality,
|
||||||
|
SeasonNumber = seasons,
|
||||||
|
EpisodeTitle = title
|
||||||
|
};
|
||||||
|
|
||||||
//Act
|
//Act
|
||||||
|
var actual = mocker.Resolve<EpisodeProvider>().GetSabTitle(parsResult);
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
|
Assert.AreEqual(excpected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
[Explicit]
|
||||||
public void Add_daily_show_episodes()
|
public void Add_daily_show_episodes()
|
||||||
{
|
{
|
||||||
var mocker = new AutoMoqer();
|
var mocker = new AutoMoqer();
|
||||||
|
@ -62,7 +62,7 @@ public MockIndexerProvider(SeriesProvider seriesProvider, SeasonProvider seasonP
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string[] Url
|
protected override string[] Urls
|
||||||
{
|
{
|
||||||
get { return new[] { "www.google.com" }; }
|
get { return new[] { "www.google.com" }; }
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,27 @@ public void can_run_job_again()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
//This test will confirm that the concurrency checks are rest
|
||||||
|
//after execution so the job can successfully run.
|
||||||
|
public void can_run_broken_job_again()
|
||||||
|
{
|
||||||
|
IEnumerable<IJob> fakeTimers = new List<IJob> { new BrokenJob() };
|
||||||
|
var mocker = new AutoMoqer();
|
||||||
|
|
||||||
|
mocker.SetConstant(MockLib.GetEmptyRepository());
|
||||||
|
mocker.SetConstant(fakeTimers);
|
||||||
|
|
||||||
|
var timerProvider = mocker.Resolve<JobProvider>();
|
||||||
|
timerProvider.Initialize();
|
||||||
|
var firstRun = timerProvider.RunScheduled();
|
||||||
|
var secondRun = timerProvider.RunScheduled();
|
||||||
|
|
||||||
|
Assert.IsTrue(firstRun);
|
||||||
|
Assert.IsTrue(secondRun);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
//This test will confirm that the concurrency checks are rest
|
//This test will confirm that the concurrency checks are rest
|
||||||
//after execution so the job can successfully run.
|
//after execution so the job can successfully run.
|
||||||
@ -73,6 +94,28 @@ public void can_run_async_job_again()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
//This test will confirm that the concurrency checks are rest
|
||||||
|
//after execution so the job can successfully run.
|
||||||
|
public void can_run_broken_async_job_again()
|
||||||
|
{
|
||||||
|
IEnumerable<IJob> fakeTimers = new List<IJob> { new BrokenJob() };
|
||||||
|
var mocker = new AutoMoqer();
|
||||||
|
|
||||||
|
mocker.SetConstant(MockLib.GetEmptyRepository());
|
||||||
|
mocker.SetConstant(fakeTimers);
|
||||||
|
|
||||||
|
var timerProvider = mocker.Resolve<JobProvider>();
|
||||||
|
timerProvider.Initialize();
|
||||||
|
var firstRun = timerProvider.BeginExecute(typeof(FakeJob));
|
||||||
|
Thread.Sleep(2000);
|
||||||
|
var secondRun = timerProvider.BeginExecute(typeof(FakeJob));
|
||||||
|
|
||||||
|
Assert.IsTrue(firstRun);
|
||||||
|
Assert.IsTrue(secondRun);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
//This test will confirm that the concurrency checks are rest
|
//This test will confirm that the concurrency checks are rest
|
||||||
//after execution so the job can successfully run.
|
//after execution so the job can successfully run.
|
||||||
@ -183,6 +226,24 @@ public void Start(ProgressNotification notification, int targetId)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class BrokenJob : IJob
|
||||||
|
{
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return "FakeJob"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int DefaultInterval
|
||||||
|
{
|
||||||
|
get { return 15; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Start(ProgressNotification notification, int targetId)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class SlowJob : IJob
|
public class SlowJob : IJob
|
||||||
{
|
{
|
||||||
public string Name
|
public string Name
|
||||||
@ -197,7 +258,7 @@ public int DefaultInterval
|
|||||||
|
|
||||||
public void Start(ProgressNotification notification, int targetId)
|
public void Start(ProgressNotification notification, int targetId)
|
||||||
{
|
{
|
||||||
Thread.Sleep(10000);
|
Thread.Sleep(5000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -13,6 +13,8 @@ public class EpisodeParseResult
|
|||||||
internal List<int> Episodes { get; set; }
|
internal List<int> Episodes { get; set; }
|
||||||
internal int Year { get; set; }
|
internal int Year { get; set; }
|
||||||
|
|
||||||
|
internal string EpisodeTitle { get; set; }
|
||||||
|
|
||||||
internal DateTime AirDate { get; set; }
|
internal DateTime AirDate { get; set; }
|
||||||
|
|
||||||
public bool Proper { get; set; }
|
public bool Proper { get; set; }
|
||||||
|
@ -139,7 +139,6 @@
|
|||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>Libraries\NLog.Extended.dll</HintPath>
|
<HintPath>Libraries\NLog.Extended.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NzbDrone.Core, Version=0.2.0.35870, Culture=neutral, processorArchitecture=MSIL" />
|
|
||||||
<Reference Include="SubSonic.Core, Version=3.0.0.3, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="SubSonic.Core, Version=3.0.0.3, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>Libraries\SubSonic.Core.dll</HintPath>
|
<HintPath>Libraries\SubSonic.Core.dll</HintPath>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Core.Model;
|
using NzbDrone.Core.Model;
|
||||||
@ -58,13 +59,29 @@ public virtual IList<Episode> GetEpisodeBySeason(long seasonId)
|
|||||||
return _sonicRepo.Find<Episode>(e => e.SeasonId == seasonId);
|
return _sonicRepo.Find<Episode>(e => e.SeasonId == seasonId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual String GetSabTitle(Episode episode)
|
public virtual String GetSabTitle(EpisodeParseResult parseResult)
|
||||||
{
|
{
|
||||||
var series = _series.GetSeries(episode.SeriesId);
|
//Show Name - 1x01-1x02 - Episode Name
|
||||||
if (series == null) throw new ArgumentException("Unknown series. ID: " + episode.SeriesId);
|
//Show Name - 1x01 - Episode Name
|
||||||
|
var episodeString = new List<String>();
|
||||||
|
|
||||||
//TODO: This method should return a standard title for the sab episode.
|
foreach (var episode in parseResult.Episodes)
|
||||||
throw new NotImplementedException();
|
{
|
||||||
|
episodeString.Add(String.Format("{0}x{1}", parseResult.SeasonNumber, episode));
|
||||||
|
}
|
||||||
|
|
||||||
|
var epNumberString = String.Join("-", episodeString);
|
||||||
|
var series = _series.GetSeries(parseResult.SeriesId);
|
||||||
|
var folderName = new DirectoryInfo(series.Path).Name;
|
||||||
|
|
||||||
|
var result = String.Format("{0} - {1} - {2} {3}", folderName, epNumberString, parseResult.EpisodeTitle, parseResult.Quality);
|
||||||
|
|
||||||
|
if (parseResult.Proper)
|
||||||
|
{
|
||||||
|
result += " [Proper]";
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -80,10 +97,23 @@ public virtual bool IsNeeded(EpisodeParseResult parsedReport)
|
|||||||
|
|
||||||
if (episodeInfo == null)
|
if (episodeInfo == null)
|
||||||
{
|
{
|
||||||
|
|
||||||
//Todo: How do we want to handle this really? Episode could be released before information is on TheTvDB
|
//Todo: How do we want to handle this really? Episode could be released before information is on TheTvDB
|
||||||
//(Parks and Rec did this a lot in the first season, from experience)
|
//(Parks and Rec did this a lot in the first season, from experience)
|
||||||
//Keivan: Should automatically add the episode to db with minimal information. then update the description/title when avilable.
|
//Keivan: Should automatically add the episode to db with minimal information. then update the description/title when available.
|
||||||
throw new NotImplementedException("Episode was not found in the database");
|
episodeInfo = new Episode()
|
||||||
|
{
|
||||||
|
SeriesId = parsedReport.SeriesId,
|
||||||
|
AirDate = DateTime.Now.Date,
|
||||||
|
EpisodeNumber = episode,
|
||||||
|
SeasonNumber = parsedReport.SeasonNumber,
|
||||||
|
Title = String.Empty,
|
||||||
|
Overview = String.Empty,
|
||||||
|
Language = "en"
|
||||||
|
};
|
||||||
|
|
||||||
|
_sonicRepo.Add(episodeInfo);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var file = episodeInfo.EpisodeFile;
|
var file = episodeInfo.EpisodeFile;
|
||||||
@ -221,6 +251,8 @@ public virtual void RefreshEpisodeInfo(Season season)
|
|||||||
Title = episode.EpisodeName
|
Title = episode.EpisodeName
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: Replace this db check with a local check. Should make things even faster
|
||||||
if (_sonicRepo.Exists<Episode>(e => e.EpisodeId == newEpisode.EpisodeId))
|
if (_sonicRepo.Exists<Episode>(e => e.EpisodeId == newEpisode.EpisodeId))
|
||||||
{
|
{
|
||||||
updateList.Add(newEpisode);
|
updateList.Add(newEpisode);
|
||||||
|
@ -32,49 +32,25 @@ public IndexerProviderBase(SeriesProvider seriesProvider, SeasonProvider seasonP
|
|||||||
_indexerProvider = indexerProvider;
|
_indexerProvider = indexerProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the source URL for the feed
|
|
||||||
/// </summary>
|
|
||||||
protected abstract string[] Url { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the name for the feed
|
/// Gets the name for the feed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract string Name { get; }
|
public abstract string Name { get; }
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates direct link to download an NZB
|
/// Gets the source URL for the feed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name = "item">RSS Feed item to generate the link for</param>
|
protected abstract string[] Urls { get; }
|
||||||
/// <returns>Download link URL</returns>
|
|
||||||
protected abstract string NzbDownloadUrl(SyndicationItem item);
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
protected IndexerSetting Settings
|
||||||
/// Parses the RSS feed item and.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name = "item">RSS feed item to parse</param>
|
|
||||||
/// <returns>Detailed episode info</returns>
|
|
||||||
protected EpisodeParseResult ParseFeed(SyndicationItem item)
|
|
||||||
{
|
{
|
||||||
var episodeParseResult = Parser.ParseEpisodeInfo(item.Title.Text);
|
get
|
||||||
if (episodeParseResult == null) return null;
|
|
||||||
|
|
||||||
var seriesInfo = _seriesProvider.FindSeries(episodeParseResult.SeriesTitle);
|
|
||||||
|
|
||||||
if (seriesInfo != null)
|
|
||||||
{
|
{
|
||||||
episodeParseResult.SeriesId = seriesInfo.SeriesId;
|
return _indexerProvider.GetSettings(GetType());
|
||||||
episodeParseResult.SeriesTitle = seriesInfo.Title;
|
|
||||||
return episodeParseResult;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Debug("Unable to map {0} to any of series in database", episodeParseResult.SeriesTitle);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Fetches RSS feed and process each news item.
|
/// Fetches RSS feed and process each news item.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -82,7 +58,7 @@ public void Fetch()
|
|||||||
{
|
{
|
||||||
Logger.Info("Fetching feeds from " + Settings.Name);
|
Logger.Info("Fetching feeds from " + Settings.Name);
|
||||||
|
|
||||||
foreach (var url in Url)
|
foreach (var url in Urls)
|
||||||
{
|
{
|
||||||
Logger.Debug("Downloading RSS " + url);
|
Logger.Debug("Downloading RSS " + url);
|
||||||
var feed = SyndicationFeed.Load(_httpProvider.DownloadXml(url)).Items;
|
var feed = SyndicationFeed.Load(_httpProvider.DownloadXml(url)).Items;
|
||||||
@ -132,16 +108,45 @@ private void ProcessItem(SyndicationItem feedItem)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IndexerSetting Settings
|
/// <summary>
|
||||||
|
/// Parses the RSS feed item and.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name = "item">RSS feed item to parse</param>
|
||||||
|
/// <returns>Detailed episode info</returns>
|
||||||
|
protected EpisodeParseResult ParseFeed(SyndicationItem item)
|
||||||
{
|
{
|
||||||
get
|
var episodeParseResult = Parser.ParseEpisodeInfo(item.Title.Text);
|
||||||
|
if (episodeParseResult == null) return CustomParser(item, null);
|
||||||
|
|
||||||
|
var seriesInfo = _seriesProvider.FindSeries(episodeParseResult.SeriesTitle);
|
||||||
|
|
||||||
|
if (seriesInfo != null)
|
||||||
{
|
{
|
||||||
return _indexerProvider.GetSettings(GetType());
|
episodeParseResult.SeriesId = seriesInfo.SeriesId;
|
||||||
|
episodeParseResult.SeriesTitle = seriesInfo.Title;
|
||||||
|
return CustomParser(item, episodeParseResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger.Debug("Unable to map {0} to any of series in database", episodeParseResult.SeriesTitle);
|
||||||
|
return CustomParser(item, episodeParseResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This method can be overwritten to provide indexer specific info parsing
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item">RSS item that needs to be parsed</param>
|
||||||
|
/// <param name="currentResult">Result of the built in parse function.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected virtual EpisodeParseResult CustomParser(SyndicationItem item, EpisodeParseResult currentResult)
|
||||||
|
{
|
||||||
|
return currentResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates direct link to download an NZB
|
||||||
|
/// </summary>
|
||||||
|
/// <param name = "item">RSS Feed item to generate the link for</param>
|
||||||
|
/// <returns>Download link URL</returns>
|
||||||
|
protected abstract string NzbDownloadUrl(SyndicationItem item);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -11,7 +11,7 @@ public NewzbinProvider(SeriesProvider seriesProvider, SeasonProvider seasonProvi
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string[] Url
|
protected override string[] Urls
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -11,7 +11,7 @@ public NzbMatrixProvider(SeriesProvider seriesProvider, SeasonProvider seasonPro
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string[] Url
|
protected override string[] Urls
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -11,7 +11,7 @@ public NzbsOrgProvider(SeriesProvider seriesProvider, SeasonProvider seasonProvi
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string[] Url
|
protected override string[] Urls
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -11,7 +11,7 @@ public NzbsRUsProvider(SeriesProvider seriesProvider, SeasonProvider seasonProvi
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string[] Url
|
protected override string[] Urls
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -127,7 +127,18 @@ public bool BeginExecute(Type jobType, int targetId = 0)
|
|||||||
{
|
{
|
||||||
Logger.Debug("Initializing background thread");
|
Logger.Debug("Initializing background thread");
|
||||||
|
|
||||||
ThreadStart starter = () => Execute(jobType, targetId);
|
ThreadStart starter = () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Execute(jobType, targetId);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_isRunning = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
_jobThread = new Thread(starter) { Name = "TimerThread", Priority = ThreadPriority.BelowNormal };
|
_jobThread = new Thread(starter) { Name = "TimerThread", Priority = ThreadPriority.BelowNormal };
|
||||||
_jobThread.Start();
|
_jobThread.Start();
|
||||||
|
|
||||||
@ -169,14 +180,7 @@ private void Execute(Type jobType, int targetId = 0)
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logger.ErrorException("An error has occurred while executing timer job" + timerClass.Name, e);
|
Logger.ErrorException("An error has occurred while executing timer job " + timerClass.Name, e);
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (_jobThread == Thread.CurrentThread)
|
|
||||||
{
|
|
||||||
_isRunning = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,14 +198,13 @@ public virtual void Initialize()
|
|||||||
var timerProviderLocal = timer;
|
var timerProviderLocal = timer;
|
||||||
if (!currentTimer.Exists(c => c.TypeName == timerProviderLocal.GetType().ToString()))
|
if (!currentTimer.Exists(c => c.TypeName == timerProviderLocal.GetType().ToString()))
|
||||||
{
|
{
|
||||||
var settings = new JobSetting()
|
var settings = new JobSetting
|
||||||
{
|
{
|
||||||
Enable = true,
|
Enable = true,
|
||||||
TypeName = timer.GetType().ToString(),
|
TypeName = timer.GetType().ToString(),
|
||||||
Name = timerProviderLocal.Name,
|
Name = timerProviderLocal.Name,
|
||||||
Interval = timerProviderLocal.DefaultInterval,
|
Interval = timerProviderLocal.DefaultInterval,
|
||||||
LastExecution = DateTime.MinValue
|
LastExecution = DateTime.MinValue
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
SaveSettings(settings);
|
SaveSettings(settings);
|
||||||
|
@ -32,10 +32,10 @@ public class Episode
|
|||||||
public virtual Season Season { get; set; }
|
public virtual Season Season { get; set; }
|
||||||
|
|
||||||
[SubSonicToOneRelation(ThisClassContainsJoinKey = true)]
|
[SubSonicToOneRelation(ThisClassContainsJoinKey = true)]
|
||||||
public virtual Series Series { get; private set; }
|
public virtual Series Series { get; set; }
|
||||||
|
|
||||||
[SubSonicToOneRelation(ThisClassContainsJoinKey = true)]
|
[SubSonicToOneRelation(ThisClassContainsJoinKey = true)]
|
||||||
public virtual EpisodeFile EpisodeFile { get; private set; }
|
public virtual EpisodeFile EpisodeFile { get; set; }
|
||||||
|
|
||||||
[SubSonicToManyRelation]
|
[SubSonicToManyRelation]
|
||||||
public virtual List<History> Histories { get; private set; }
|
public virtual List<History> Histories { get; private set; }
|
||||||
|
Loading…
Reference in New Issue
Block a user