Merge branch 'develop'

This commit is contained in:
Mark McDowall 2013-12-31 14:21:45 -08:00
commit e063af635a
29 changed files with 171 additions and 54 deletions

View File

@ -74,6 +74,12 @@ Function PackageMono()
Write-Host Removing Update Client
Remove-Item -Recurse -Force "$outputFolderMono\NzbDrone.Update"
Write-Host Creating MDBs
get-childitem $outputFolderMono -File -Include @("*.exe", "*.dll") -Exclude @("MediaInfo.dll", "sqlite3.dll") -Recurse | foreach ($_) {
Write-Host "Creating .mdb for $_"
& "tools\pdb2mdb\pdb2mdb.exe" $_.fullname
}
Write-Host Removing PDBs
get-childitem $outputFolderMono -File -Filter *.pdb -Recurse | foreach ($_) {remove-item $_.fullname}
@ -89,8 +95,15 @@ Function PackageMono()
Copy-Item "$sourceFolder\MediaInfoDotNet.dll.config" $outputFolderMono
Write-Host Renaming NzbDrone.Console.exe to NzbDrone.exe
get-childitem $outputFolderMono -File -Filter NzbDrone.exe -Recurse | foreach ($_) {remove-item $_.fullname}
Rename-Item "$outputFolderMono\NzbDrone.Console.exe" "NzbDrone.exe"
Get-ChildItem $outputFolderMono -File -Filter "NzbDrone.exe*" -Recurse | foreach ($_) {remove-item $_.fullname}
Get-ChildItem $outputFolderMono -File -Filter "NzbDrone.Console.exe*" -Recurse | foreach ($_) {
$newName = $_.fullname -Replace ".Console",""
Rename-Item $_.fullname $newName
}
Remove-Item "$outputFolderMono\NzbDrone.Console.vshost.exe"
Write-Host "##teamcity[progressFinish 'Creating Mono Package']"
}

View File

@ -16,13 +16,11 @@ namespace NzbDrone.Api.Authentication
private readonly IConfigFileProvider _configFileProvider;
private static readonly NzbDroneUser AnonymousUser = new NzbDroneUser { UserName = "Anonymous" };
public AuthenticationService(IConfigFileProvider configFileProvider)
{
_configFileProvider = configFileProvider;
}
public IUserIdentity Validate(string username, string password)
{
if (!Enabled)

View File

@ -7,7 +7,7 @@ namespace NzbDrone.Api.Extensions
{
public static bool IsApiRequest(this Request request)
{
return request.Path.StartsWith("/api/", StringComparison.InvariantCultureIgnoreCase);
return request.Path.StartsWith("/api/", StringComparison.InvariantCultureIgnoreCase) || request.IsLogFileRequest();
}
public static bool IsSignalRRequest(this Request request)
@ -21,5 +21,11 @@ namespace NzbDrone.Api.Extensions
request.UserHostAddress.Equals("127.0.0.1") ||
request.UserHostAddress.Equals("::1"));
}
private static bool IsLogFileRequest(this Request request)
{
return request.Path.StartsWith("/log/", StringComparison.InvariantCultureIgnoreCase) &&
request.Path.EndsWith(".txt", StringComparison.InvariantCultureIgnoreCase);
}
}
}

View File

@ -25,7 +25,7 @@ namespace NzbDrone.Api.Frontend.Mappers
public override bool CanHandle(string resourceUrl)
{
return resourceUrl.StartsWith("/log") && resourceUrl.EndsWith(".txt");
return resourceUrl.StartsWith("/log/") && resourceUrl.EndsWith(".txt");
}
}
}

View File

@ -1,27 +1,18 @@
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using NLog;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Instrumentation;
namespace NzbDrone.Common.Security
{
public static class IgnoreCertErrorPolicy
{
private static readonly Logger Logger = NzbDroneLogger.GetLogger();
public static void Register()
{
if (OsInfo.IsLinux)
{
ServicePointManager.ServerCertificateValidationCallback = ValidationCallback;
}
}
private static bool ValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslpolicyerrors)
{
Logger.Warn("[{0}] {1}", sender.GetType(), sslpolicyerrors);
return true;
}
}

View File

@ -0,0 +1,48 @@
using FizzWare.NBuilder;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.MediaFiles.EpisodeImport.Specifications;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv;
using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications
{
[TestFixture]
public class FullSeasonSpecificationFixture : CoreTest<FullSeasonSpecification>
{
private LocalEpisode _localEpisode;
[SetUp]
public void Setup()
{
_localEpisode = new LocalEpisode
{
Path = @"C:\Test\30 Rock\30.rock.s01e01.avi".AsOsAgnostic(),
Size = 100,
Series = Builder<Series>.CreateNew().Build(),
ParsedEpisodeInfo = new ParsedEpisodeInfo
{
FullSeason = false
}
};
}
[Test]
public void should_return_false_when_file_contains_the_full_season()
{
_localEpisode.ParsedEpisodeInfo.FullSeason = true;
Subject.IsSatisfiedBy(_localEpisode).Should().BeFalse();
}
[Test]
public void should_return_true_when_file_does_not_contain_the_full_season()
{
Subject.IsSatisfiedBy(_localEpisode).Should().BeTrue();
}
}
}

View File

@ -146,6 +146,7 @@
<Compile Include="MediaCoverTests\CoverExistsSpecificationFixture.cs" />
<Compile Include="MediaCoverTests\MediaCoverServiceFixture.cs" />
<Compile Include="MediaFiles\EpisodeFileMovingServiceTests\MoveEpisodeFileFixture.cs" />
<Compile Include="MediaFiles\EpisodeImport\Specifications\FullSeasonSpecificationFixture.cs" />
<Compile Include="MediaFiles\EpisodeImport\Specifications\FreeSpaceSpecificationFixture.cs" />
<Compile Include="MediaFiles\EpisodeImport\ImportDecisionMakerFixture.cs" />
<Compile Include="MediaFiles\EpisodeImport\Specifications\NotInUseSpecificationFixture.cs" />

View File

@ -106,6 +106,7 @@ namespace NzbDrone.Core.Test.ParserTests
result.EpisodeNumbers.First().Should().Be(episodeNumber);
result.SeriesTitle.Should().Be(title.CleanSeriesTitle());
result.AbsoluteEpisodeNumbers.Should().BeEmpty();
result.FullSeason.Should().BeFalse();
}
[TestCase(@"z:\tv shows\battlestar galactica (2003)\Season 3\S03E05 - Collaborators.mkv", 3, 5)]
@ -129,6 +130,8 @@ namespace NzbDrone.Core.Test.ParserTests
result.EpisodeNumbers.Should().HaveCount(1);
result.SeasonNumber.Should().Be(season);
result.EpisodeNumbers[0].Should().Be(episode);
result.AbsoluteEpisodeNumbers.Should().BeEmpty();
result.FullSeason.Should().BeFalse();
ExceptionVerification.IgnoreWarns();
}
@ -169,6 +172,8 @@ namespace NzbDrone.Core.Test.ParserTests
result.SeasonNumber.Should().Be(season);
result.EpisodeNumbers.Should().BeEquivalentTo(episodes);
result.SeriesTitle.Should().Be(title.CleanSeriesTitle());
result.AbsoluteEpisodeNumbers.Should().BeEmpty();
result.FullSeason.Should().BeFalse();
}
@ -190,6 +195,8 @@ namespace NzbDrone.Core.Test.ParserTests
result.SeriesTitle.Should().Be(title.CleanSeriesTitle());
result.AirDate.Should().Be(airDate.ToString(Episode.AIR_DATE_FORMAT));
result.EpisodeNumbers.Should().BeEmpty();
result.AbsoluteEpisodeNumbers.Should().BeEmpty();
result.FullSeason.Should().BeFalse();
}
[TestCase("[SubDESU]_High_School_DxD_07_(1280x720_x264-AAC)_[6B7FD717]", "High School DxD", 7, 0, 0)]
@ -222,9 +229,9 @@ namespace NzbDrone.Core.Test.ParserTests
result.SeasonNumber.Should().Be(seasonNumber);
result.EpisodeNumbers.FirstOrDefault().Should().Be(episodeNumber);
result.SeriesTitle.Should().Be(title.CleanSeriesTitle());
result.FullSeason.Should().BeFalse();
}
[TestCase("Conan {year} {month} {day} Emma Roberts HDTV XviD BFF")]
[TestCase("The Tonight Show With Jay Leno {year} {month} {day} 1080i HDTV DD5 1 MPEG2 TrollHD")]
[TestCase("The.Daily.Show.{year}.{month}.{day}.Johnny.Knoxville.iTouch-MW")]
@ -238,7 +245,6 @@ namespace NzbDrone.Core.Test.ParserTests
Parser.Parser.ParseTitle(yearTooLow).Should().BeNull();
}
[TestCase("Conan {year} {month} {day} Emma Roberts HDTV XviD BFF")]
[TestCase("The Tonight Show With Jay Leno {year} {month} {day} 1080i HDTV DD5 1 MPEG2 TrollHD")]
[TestCase("The.Daily.Show.{year}.{month}.{day}.Johnny.Knoxville.iTouch-MW")]
@ -268,12 +274,14 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("The.Office.US.S03.720p.x264-DIMENSION", "The.Office.US", 3)]
[TestCase(@"Sons.of.Anarchy.S03.720p.BluRay-CLUE\REWARD", "Sons.of.Anarchy", 3)]
[TestCase("Adventure Time S02 720p HDTV x264 CRON", "Adventure Time", 2)]
[TestCase("Sealab.2021.S04.iNTERNAL.DVDRip.XviD-VCDVaULT", "Sealab 2021", 4)]
public void full_season_release_parse(string postTitle, string title, int season)
{
var result = Parser.Parser.ParseTitle(postTitle);
result.SeasonNumber.Should().Be(season);
result.SeriesTitle.Should().Be(title.CleanSeriesTitle());
result.EpisodeNumbers.Length.Should().Be(0);
result.EpisodeNumbers.Should().BeEmpty();
result.AbsoluteEpisodeNumbers.Should().BeEmpty();
result.FullSeason.Should().BeTrue();
}
@ -466,5 +474,13 @@ namespace NzbDrone.Core.Test.ParserTests
{
Parser.Parser.ParseReleaseGroup(title).Should().Be(expected);
}
[Test]
public void should_not_include_extension_in_releaseGroup()
{
const string path = @"C:\Test\Doctor.Who.2005.s01e01.internal.bdrip.x264-archivist.mkv";
Parser.Parser.ParsePath(path).ReleaseGroup.Should().Be("archivist");
}
}
}

View File

@ -46,6 +46,14 @@ namespace NzbDrone.Core.Indexers.Newznab
Settings = GetSettings("https://dognzb.cr", new List<Int32>())
});
list.Add(new IndexerDefinition
{
Enable = false,
Name = "OZnzb.com",
Implementation = GetType().Name,
Settings = GetSettings("https://www.oznzb.com", new List<Int32>())
});
return list;
}

View File

@ -0,0 +1,31 @@
using System;
using System.IO;
using NLog;
using NzbDrone.Common;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
{
public class FullSeasonSpecification : IImportDecisionEngineSpecification
{
private readonly Logger _logger;
public FullSeasonSpecification(Logger logger)
{
_logger = logger;
}
public string RejectionReason { get { return "Full season file"; } }
public bool IsSatisfiedBy(LocalEpisode localEpisode)
{
if (localEpisode.ParsedEpisodeInfo.FullSeason)
{
_logger.Trace("Single episode file detected as containing all episodes in the season");
return false;
}
return true;
}
}
}

View File

@ -284,6 +284,7 @@
<Compile Include="Instrumentation\DeleteLogFilesService.cs" />
<Compile Include="MediaFiles\Commands\RenameFilesCommand.cs" />
<Compile Include="MediaFiles\EpisodeFileMoveResult.cs" />
<Compile Include="MediaFiles\EpisodeImport\Specifications\FullSeasonSpecification.cs" />
<Compile Include="MediaFiles\MediaFileExtensions.cs" />
<Compile Include="MediaFiles\MediaInfo\VideoFileInfoReader.cs" />
<Compile Include="MediaFiles\RenameEpisodeFilePreview.cs" />

View File

@ -74,10 +74,6 @@ namespace NzbDrone.Core.Parser
new Regex(@"^(?<title>.+?)(?:\W+(?:(?:Part\W?|(?<!\d+\W+)e)(?<episode>\d{1,2}(?!\d+)))+)",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
//Supports 1103/1113 naming
new Regex(@"^(?<title>.+?)?(?:\W?(?<season>(?<!\d+|\(|\[|e|x)\d{2})(?<episode>(?<!e|x)\d{2}(?!p|i|\d+|\)|\]|\W\d+)))+(\W+|_|$)(?!\\)",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
//Supports Season 01 Episode 03
new Regex(@"(?:.*(?:\""|^))(?<title>.*?)(?:\W?Season\W?)(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:\W|_)(?:Episode\W)(?<episode>(?<!\d+)\d{1,2}(?!\d+))",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
@ -86,6 +82,10 @@ namespace NzbDrone.Core.Parser
new Regex(@"^(?<title>.+?)\W(?:S|Season)\W?(?<season>\d{1,2}(?!\d+))(\W+|_|$)(?<extras>EXTRAS|SUBPACK)?(?!\\)",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
//Supports 1103/1113 naming
new Regex(@"^(?<title>.+?)?(?:\W?(?<season>(?<!\d+|\(|\[|e|x)\d{2})(?<episode>(?<!e|x)\d{2}(?!p|i|\d+|\)|\]|\W\d+)))+(\W+|_|$)(?!\\)",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
//4-digit episode number
//Episodes without a title, Single (S01E05, 1x05) AND Multi (S01E04E05, 1x04x05, etc)
new Regex(@"^(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]|_){1,2}(?<episode>\d{4}(?!\d+|i|p)))+)(\W+|_|$)(?!\\)",
@ -129,8 +129,11 @@ namespace NzbDrone.Core.Parser
if (result == null)
{
Logger.Warn("Unable to parse episode info from path {0}", path);
return null;
}
result.ReleaseGroup = ParseReleaseGroup(fileInfo.Name.Replace(fileInfo.Extension, ""));
return result;
}
@ -336,7 +339,8 @@ namespace NzbDrone.Core.Parser
var count = last - first + 1;
result.AbsoluteEpisodeNumbers = Enumerable.Range(first, count).ToArray();
}
else
if (!episodeCaptures.Any() && !absoluteEpisodeCaptures.Any())
{
//Check to see if this is an "Extras" or "SUBPACK" release, if it is, return NULL
//Todo: Set a "Extras" flag in EpisodeParseResult if we want to download them ever

View File

@ -112,6 +112,11 @@ namespace NzbDrone.Core.Parser
{
var result = new List<Episode>();
if (parsedEpisodeInfo.FullSeason)
{
return _episodeService.GetEpisodesBySeason(series.Id, parsedEpisodeInfo.SeasonNumber);
}
if (parsedEpisodeInfo.IsDaily())
{
if (series.SeriesType == SeriesTypes.Standard)

View File

@ -15,18 +15,15 @@ namespace NzbDrone.Host
private static IContainer _container;
private static readonly Logger Logger = NzbDroneLogger.GetLogger();
public static void Start(StartupContext startupContext, IUserAlert userAlert, Action<IContainer> startCallback = null)
{
try
{
GlobalExceptionHandlers.Register();
IgnoreCertErrorPolicy.Register();
Logger.Info("Starting NzbDrone Console. Version {0}", Assembly.GetExecutingAssembly().GetName().Version);
if (!PlatformValidation.IsValidate(userAlert))
{
throw new TerminateApplicationException("Missing system requirements");
@ -92,8 +89,6 @@ namespace NzbDrone.Host
}
}
private static ApplicationModes GetApplicationMode(StartupContext startupContext)
{
if (startupContext.Flags.Contains(StartupContext.HELP))
@ -119,8 +114,6 @@ namespace NzbDrone.Host
return ApplicationModes.Interactive;
}
private static bool IsInUtilityMode(ApplicationModes applicationMode)
{
switch (applicationMode)
@ -137,6 +130,5 @@ namespace NzbDrone.Host
}
}
}
}
}

View File

@ -38,7 +38,7 @@ namespace NzbDrone.Host
}
else
{
_logger.Debug("none-interactive runtime. Won't attempt to open browser.");
_logger.Debug("non-interactive runtime. Won't attempt to open browser.");
}
}
catch (Exception e)

View File

@ -23,7 +23,6 @@ namespace NzbDrone.Host
{
_processPriorityCheckTimer = new Timer(EnsurePriority);
_processPriorityCheckTimer.Change(TimeSpan.FromSeconds(15), TimeSpan.FromMinutes(30));
}
public virtual void EnsurePriority(object sender)

View File

@ -38,7 +38,7 @@ namespace NzbDrone.SysTray
_trayIcon.ContextMenu = _trayMenu;
_trayIcon.Visible = true;
_trayIcon.DoubleClick += LaunchBrowser;
Application.Run(this);
}

View File

@ -147,12 +147,11 @@ define(
this.model.set('seasonFolder', seasonFolder);
var self = this;
SeriesCollection.add(this.model);
var promise = this.model.save();
promise.done(function () {
SeriesCollection.add(self.model);
self.close();
icon.removeClass('icon-spin icon-spinner disabled').addClass('icon-search');

View File

@ -31,7 +31,7 @@ define(
var hasAired = Moment(this.model.get('airDateUtc')).isBefore(Moment());
var hasFile = this.model.get('hasFile');
if (hasFile) {
if (hasFile && reqres.hasHandler(reqres.Requests.GetEpisodeFileById)) {
var episodeFile = reqres.request(reqres.Requests.GetEpisodeFileById, this.model.get('episodeFileId'));
this.listenTo(episodeFile, 'change', this._refresh);

View File

@ -22,28 +22,28 @@
</a>
</li>
<li>
<a href="history">
<a href="/history">
<i class="icon-time"></i>
<br>
History
</a>
</li>
<li>
<a href="missing">
<a href="/missing">
<i class="icon-warning-sign"></i>
<br>
Missing
</a>
</li>
<li>
<a href="settings">
<a href="/settings">
<i class="icon-cogs"></i>
<br>
Settings
</a>
</li>
<li>
<a href="system">
<a href="/system">
<i class="icon-laptop"></i>
<br>
System

View File

@ -186,6 +186,10 @@ define(
this.episodeCollection = new EpisodeCollection({ seriesId: this.model.id }).bindSignalR();
this.episodeFileCollection = new EpisodeFileCollection({ seriesId: this.model.id }).bindSignalR();
reqres.setHandler(reqres.Requests.GetEpisodeFileById, function (episodeFileId) {
return self.episodeFileCollection.get(episodeFileId);
});
$.when(this.episodeCollection.fetch(), this.episodeFileCollection.fetch()).done(function () {
var seasonCollectionView = new SeasonCollectionView({
collection : self.seasonCollection,
@ -193,10 +197,6 @@ define(
series : self.model
});
reqres.setHandler(reqres.Requests.GetEpisodeFileById, function (episodeFileId) {
return self.episodeFileCollection.get(episodeFileId);
});
self.seasons.show(seasonCollectionView);
});
},

View File

@ -224,6 +224,10 @@
}
}
.season-actions {
width: 70px;
}
.season-actions, .series-actions {
div {

View File

@ -184,7 +184,7 @@ define(
},
_navigate:function(route){
Backbone.history.navigate(route, {trigger:true});
Backbone.history.navigate(route, { trigger: true, replace: true });
},
_save: function () {

View File

@ -52,7 +52,7 @@ define(
},
_navigate:function(route){
Backbone.history.navigate(route);
Backbone.history.navigate(route, { trigger: true, replace: true });
},
_showInfo: function (e) {

View File

@ -16,17 +16,18 @@ define(
initialize: function () {
this.updateCollection = new UpdateCollection();
this.listenTo(this.updateCollection, 'sync', this._showUpdates);
},
onRender: function () {
this.updates.show(new LoadingView());
var self = this;
var promise = this.updateCollection.fetch();
this.updateCollection.fetch();
},
promise.done(function (){
self.updates.show(new UpdateCollectionView({ collection: self.updateCollection }));
});
_showUpdates: function () {
this.updates.show(new UpdateCollectionView({ collection: this.updateCollection }));
}
});
});

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
tools/pdb2mdb/pdb2mdb.exe Normal file

Binary file not shown.