mirror of
https://github.com/Sonarr/Sonarr.git
synced 2026-04-18 21:35:27 -04:00
Compare commits
1 Commits
v2.0.0.530
...
sqlite-on-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c886a02388 |
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
@@ -91,11 +91,9 @@ namespace Marr.Data.Mapping
|
|||||||
Type entType = ent.GetType();
|
Type entType = ent.GetType();
|
||||||
if (_repos.Relationships.ContainsKey(entType))
|
if (_repos.Relationships.ContainsKey(entType))
|
||||||
{
|
{
|
||||||
var provider = _db.ProviderFactory;
|
|
||||||
var connectionString = _db.ConnectionString;
|
|
||||||
Func<IDataMapper> dbCreate = () =>
|
Func<IDataMapper> dbCreate = () =>
|
||||||
{
|
{
|
||||||
var db = new DataMapper(provider, connectionString);
|
var db = new DataMapper(_db.ProviderFactory, _db.ConnectionString);
|
||||||
db.SqlMode = SqlModes.Text;
|
db.SqlMode = SqlModes.Text;
|
||||||
return db;
|
return db;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ namespace NzbDrone.Api.EpisodeFiles
|
|||||||
public string SceneName { get; set; }
|
public string SceneName { get; set; }
|
||||||
public QualityModel Quality { get; set; }
|
public QualityModel Quality { get; set; }
|
||||||
public MediaInfoResource MediaInfo { get; set; }
|
public MediaInfoResource MediaInfo { get; set; }
|
||||||
public string OriginalFilePath { get; set; }
|
|
||||||
|
|
||||||
public bool QualityCutoffNotMet { get; set; }
|
public bool QualityCutoffNotMet { get; set; }
|
||||||
}
|
}
|
||||||
@@ -39,8 +38,8 @@ namespace NzbDrone.Api.EpisodeFiles
|
|||||||
DateAdded = model.DateAdded,
|
DateAdded = model.DateAdded,
|
||||||
SceneName = model.SceneName,
|
SceneName = model.SceneName,
|
||||||
Quality = model.Quality,
|
Quality = model.Quality,
|
||||||
MediaInfo = model.MediaInfo.ToResource(model.SceneName),
|
MediaInfo = model.MediaInfo.ToResource(model.SceneName)
|
||||||
OriginalFilePath = model.OriginalFilePath
|
//QualityCutoffNotMet
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +61,6 @@ namespace NzbDrone.Api.EpisodeFiles
|
|||||||
Quality = model.Quality,
|
Quality = model.Quality,
|
||||||
QualityCutoffNotMet = qualityUpgradableSpecification.CutoffNotMet(series.Profile.Value, model.Quality),
|
QualityCutoffNotMet = qualityUpgradableSpecification.CutoffNotMet(series.Profile.Value, model.Quality),
|
||||||
MediaInfo = model.MediaInfo.ToResource(model.SceneName),
|
MediaInfo = model.MediaInfo.ToResource(model.SceneName),
|
||||||
OriginalFilePath = model.OriginalFilePath
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
@@ -30,7 +30,6 @@ namespace NzbDrone.Api.Episodes
|
|||||||
public bool UnverifiedSceneNumbering { get; set; }
|
public bool UnverifiedSceneNumbering { get; set; }
|
||||||
public string SeriesTitle { get; set; }
|
public string SeriesTitle { get; set; }
|
||||||
public SeriesResource Series { get; set; }
|
public SeriesResource Series { get; set; }
|
||||||
public DateTime? LastSearchTime { get; set; }
|
|
||||||
|
|
||||||
//Hiding this so people don't think its usable (only used to set the initial state)
|
//Hiding this so people don't think its usable (only used to set the initial state)
|
||||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
||||||
@@ -66,7 +65,6 @@ namespace NzbDrone.Api.Episodes
|
|||||||
UnverifiedSceneNumbering = model.UnverifiedSceneNumbering,
|
UnverifiedSceneNumbering = model.UnverifiedSceneNumbering,
|
||||||
SeriesTitle = model.SeriesTitle,
|
SeriesTitle = model.SeriesTitle,
|
||||||
//Series = model.Series.MapToResource(),
|
//Series = model.Series.MapToResource(),
|
||||||
LastSearchTime = model.LastSearchTime
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ using System.Linq;
|
|||||||
using Nancy;
|
using Nancy;
|
||||||
using Nancy.Bootstrapper;
|
using Nancy.Bootstrapper;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Extensions.Pipelines
|
namespace NzbDrone.Api.Extensions.Pipelines
|
||||||
@@ -16,14 +15,9 @@ namespace NzbDrone.Api.Extensions.Pipelines
|
|||||||
|
|
||||||
public int Order => 0;
|
public int Order => 0;
|
||||||
|
|
||||||
private readonly Action<Action<Stream>, Stream> _writeGZipStream;
|
|
||||||
|
|
||||||
public GzipCompressionPipeline(Logger logger)
|
public GzipCompressionPipeline(Logger logger)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
// On Mono GZipStream/DeflateStream leaks memory if an exception is thrown, use an intermediate buffer in that case.
|
|
||||||
_writeGZipStream = PlatformInfo.IsMono ? WriteGZipStreamMono : (Action<Action<Stream>, Stream>)WriteGZipStream;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Register(IPipelines pipelines)
|
public void Register(IPipelines pipelines)
|
||||||
@@ -49,7 +43,14 @@ namespace NzbDrone.Api.Extensions.Pipelines
|
|||||||
var contents = response.Contents;
|
var contents = response.Contents;
|
||||||
|
|
||||||
response.Headers["Content-Encoding"] = "gzip";
|
response.Headers["Content-Encoding"] = "gzip";
|
||||||
response.Contents = responseStream => _writeGZipStream(contents, responseStream);
|
response.Contents = responseStream =>
|
||||||
|
{
|
||||||
|
using (var gzip = new GZipStream(responseStream, CompressionMode.Compress, true))
|
||||||
|
using (var buffered = new BufferedStream(gzip, 8192))
|
||||||
|
{
|
||||||
|
contents.Invoke(buffered);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,25 +61,6 @@ namespace NzbDrone.Api.Extensions.Pipelines
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteGZipStreamMono(Action<Stream> innerContent, Stream targetStream)
|
|
||||||
{
|
|
||||||
using (var membuffer = new MemoryStream())
|
|
||||||
{
|
|
||||||
WriteGZipStream(innerContent, membuffer);
|
|
||||||
membuffer.Position = 0;
|
|
||||||
membuffer.CopyTo(targetStream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void WriteGZipStream(Action<Stream> innerContent, Stream targetStream)
|
|
||||||
{
|
|
||||||
using (var gzip = new GZipStream(targetStream, CompressionMode.Compress, true))
|
|
||||||
using (var buffered = new BufferedStream(gzip, 8192))
|
|
||||||
{
|
|
||||||
innerContent.Invoke(buffered);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool ContentLengthIsTooSmall(Response response)
|
private static bool ContentLengthIsTooSmall(Response response)
|
||||||
{
|
{
|
||||||
var contentLength = response.Headers.GetValueOrDefault("Content-Length");
|
var contentLength = response.Headers.GetValueOrDefault("Content-Length");
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace NzbDrone.Common.EnvironmentInfo
|
namespace NzbDrone.Common.EnvironmentInfo
|
||||||
{
|
{
|
||||||
public interface IRuntimeInfo
|
public interface IRuntimeInfo
|
||||||
{
|
{
|
||||||
DateTime StartTime { get; }
|
|
||||||
bool IsUserInteractive { get; }
|
bool IsUserInteractive { get; }
|
||||||
bool IsAdmin { get; }
|
bool IsAdmin { get; }
|
||||||
bool IsWindowsService { get; }
|
bool IsWindowsService { get; }
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ namespace NzbDrone.Common.EnvironmentInfo
|
|||||||
public class RuntimeInfo : IRuntimeInfo
|
public class RuntimeInfo : IRuntimeInfo
|
||||||
{
|
{
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
private readonly DateTime _startTime = DateTime.UtcNow;
|
|
||||||
|
|
||||||
public RuntimeInfo(IServiceProvider serviceProvider, Logger logger)
|
public RuntimeInfo(IServiceProvider serviceProvider, Logger logger)
|
||||||
{
|
{
|
||||||
@@ -38,14 +37,6 @@ namespace NzbDrone.Common.EnvironmentInfo
|
|||||||
IsProduction = InternalIsProduction();
|
IsProduction = InternalIsProduction();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DateTime StartTime
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _startTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsUserInteractive => Environment.UserInteractive;
|
public static bool IsUserInteractive => Environment.UserInteractive;
|
||||||
|
|
||||||
bool IRuntimeInfo.IsUserInteractive => IsUserInteractive;
|
bool IRuntimeInfo.IsUserInteractive => IsUserInteractive;
|
||||||
|
|||||||
@@ -191,24 +191,6 @@ namespace NzbDrone.Common.Extensions
|
|||||||
return directories;
|
return directories;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetAncestorPath(this string path, string ancestorName)
|
|
||||||
{
|
|
||||||
var parent = Path.GetDirectoryName(path);
|
|
||||||
|
|
||||||
while (parent != null)
|
|
||||||
{
|
|
||||||
var currentPath = parent;
|
|
||||||
parent = Path.GetDirectoryName(parent);
|
|
||||||
|
|
||||||
if (Path.GetFileName(currentPath) == ancestorName)
|
|
||||||
{
|
|
||||||
return currentPath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetAppDataPath(this IAppFolderInfo appFolderInfo)
|
public static string GetAppDataPath(this IAppFolderInfo appFolderInfo)
|
||||||
{
|
{
|
||||||
return appFolderInfo.AppDataFolder;
|
return appFolderInfo.AppDataFolder;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Compression;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
@@ -26,20 +25,11 @@ namespace NzbDrone.Common.Http.Dispatchers
|
|||||||
{
|
{
|
||||||
var webRequest = (HttpWebRequest)WebRequest.Create((Uri)request.Url);
|
var webRequest = (HttpWebRequest)WebRequest.Create((Uri)request.Url);
|
||||||
|
|
||||||
if (PlatformInfo.IsMono)
|
// Deflate is not a standard and could break depending on implementation.
|
||||||
{
|
// we should just stick with the more compatible Gzip
|
||||||
// On Mono GZipStream/DeflateStream leaks memory if an exception is thrown, use an intermediate buffer in that case.
|
//http://stackoverflow.com/questions/8490718/how-to-decompress-stream-deflated-with-java-util-zip-deflater-in-net
|
||||||
webRequest.AutomaticDecompression = DecompressionMethods.None;
|
webRequest.AutomaticDecompression = DecompressionMethods.GZip;
|
||||||
webRequest.Headers.Add("Accept-Encoding", "gzip");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Deflate is not a standard and could break depending on implementation.
|
|
||||||
// we should just stick with the more compatible Gzip
|
|
||||||
//http://stackoverflow.com/questions/8490718/how-to-decompress-stream-deflated-with-java-util-zip-deflater-in-net
|
|
||||||
webRequest.AutomaticDecompression = DecompressionMethods.GZip;
|
|
||||||
}
|
|
||||||
|
|
||||||
webRequest.Method = request.Method.ToString();
|
webRequest.Method = request.Method.ToString();
|
||||||
webRequest.UserAgent = _userAgentBuilder.GetUserAgent(request.UseSimplifiedUserAgent);
|
webRequest.UserAgent = _userAgentBuilder.GetUserAgent(request.UseSimplifiedUserAgent);
|
||||||
webRequest.KeepAlive = request.ConnectionKeepAlive;
|
webRequest.KeepAlive = request.ConnectionKeepAlive;
|
||||||
@@ -117,19 +107,6 @@ namespace NzbDrone.Common.Http.Dispatchers
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
data = responseStream.ToBytes();
|
data = responseStream.ToBytes();
|
||||||
|
|
||||||
if (PlatformInfo.IsMono && httpWebResponse.ContentEncoding == "gzip")
|
|
||||||
{
|
|
||||||
using (var compressedStream = new MemoryStream(data))
|
|
||||||
using (var gzip = new GZipStream(compressedStream, CompressionMode.Decompress))
|
|
||||||
using (var decompressedStream = new MemoryStream())
|
|
||||||
{
|
|
||||||
gzip.CopyTo(decompressedStream);
|
|
||||||
data = decompressedStream.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
httpWebResponse.Headers.Remove("Content-Encoding");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
|
||||||
using NzbDrone.Core.Download;
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
@@ -17,10 +16,6 @@ namespace NzbDrone.Core.Test.Download
|
|||||||
public void SetUp()
|
public void SetUp()
|
||||||
{
|
{
|
||||||
_epoch = DateTime.UtcNow;
|
_epoch = DateTime.UtcNow;
|
||||||
|
|
||||||
Mocker.GetMock<IRuntimeInfo>()
|
|
||||||
.SetupGet(v => v.StartTime)
|
|
||||||
.Returns(_epoch - TimeSpan.FromHours(1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private DownloadClientStatus WithStatus(DownloadClientStatus status)
|
private DownloadClientStatus WithStatus(DownloadClientStatus status)
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
@@ -17,10 +16,6 @@ namespace NzbDrone.Core.Test.IndexerTests
|
|||||||
public void SetUp()
|
public void SetUp()
|
||||||
{
|
{
|
||||||
_epoch = DateTime.UtcNow;
|
_epoch = DateTime.UtcNow;
|
||||||
|
|
||||||
Mocker.GetMock<IRuntimeInfo>()
|
|
||||||
.SetupGet(v => v.StartTime)
|
|
||||||
.Returns(_epoch - TimeSpan.FromHours(1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WithStatus(IndexerStatus status)
|
private void WithStatus(IndexerStatus status)
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ using FizzWare.NBuilder;
|
|||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Common.Disk;
|
|
||||||
using NzbDrone.Core.DecisionEngine;
|
using NzbDrone.Core.DecisionEngine;
|
||||||
using NzbDrone.Core.Download;
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
@@ -35,8 +34,6 @@ namespace NzbDrone.Core.Test.MediaFiles
|
|||||||
_rejectedDecisions = new List<ImportDecision>();
|
_rejectedDecisions = new List<ImportDecision>();
|
||||||
_approvedDecisions = new List<ImportDecision>();
|
_approvedDecisions = new List<ImportDecision>();
|
||||||
|
|
||||||
var outputPath = @"C:\Test\Unsorted\TV\30.Rock.S01E01".AsOsAgnostic();
|
|
||||||
|
|
||||||
var series = Builder<Series>.CreateNew()
|
var series = Builder<Series>.CreateNew()
|
||||||
.With(e => e.Profile = new Profile { Items = Qualities.QualityFixture.GetDefaultQualities() })
|
.With(e => e.Profile = new Profile { Items = Qualities.QualityFixture.GetDefaultQualities() })
|
||||||
.With(s => s.Path = @"C:\Test\TV\30 Rock".AsOsAgnostic())
|
.With(s => s.Path = @"C:\Test\TV\30 Rock".AsOsAgnostic())
|
||||||
@@ -69,14 +66,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
|||||||
.Setup(s => s.UpgradeEpisodeFile(It.IsAny<EpisodeFile>(), It.IsAny<LocalEpisode>(), It.IsAny<bool>()))
|
.Setup(s => s.UpgradeEpisodeFile(It.IsAny<EpisodeFile>(), It.IsAny<LocalEpisode>(), It.IsAny<bool>()))
|
||||||
.Returns(new EpisodeFileMoveResult());
|
.Returns(new EpisodeFileMoveResult());
|
||||||
|
|
||||||
_downloadClientItem = Builder<DownloadClientItem>.CreateNew()
|
_downloadClientItem = Builder<DownloadClientItem>.CreateNew().Build();
|
||||||
.With(d => d.OutputPath = new OsPath(outputPath))
|
|
||||||
.Build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenNewDownload()
|
|
||||||
{
|
|
||||||
_approvedDecisions.ForEach(a => a.LocalEpisode.Path = Path.Combine(_downloadClientItem.OutputPath.ToString(), Path.GetFileName(a.LocalEpisode.Path)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -150,7 +140,6 @@ namespace NzbDrone.Core.Test.MediaFiles
|
|||||||
[Test]
|
[Test]
|
||||||
public void should_use_nzb_title_as_scene_name()
|
public void should_use_nzb_title_as_scene_name()
|
||||||
{
|
{
|
||||||
GivenNewDownload();
|
|
||||||
_downloadClientItem.Title = "malcolm.in.the.middle.s02e05.dvdrip.xvid-ingot";
|
_downloadClientItem.Title = "malcolm.in.the.middle.s02e05.dvdrip.xvid-ingot";
|
||||||
|
|
||||||
Subject.Import(new List<ImportDecision> { _approvedDecisions.First() }, true, _downloadClientItem);
|
Subject.Import(new List<ImportDecision> { _approvedDecisions.First() }, true, _downloadClientItem);
|
||||||
@@ -163,7 +152,6 @@ namespace NzbDrone.Core.Test.MediaFiles
|
|||||||
[TestCase(".nzb")]
|
[TestCase(".nzb")]
|
||||||
public void should_remove_extension_from_nzb_title_for_scene_name(string extension)
|
public void should_remove_extension_from_nzb_title_for_scene_name(string extension)
|
||||||
{
|
{
|
||||||
GivenNewDownload();
|
|
||||||
var title = "malcolm.in.the.middle.s02e05.dvdrip.xvid-ingot";
|
var title = "malcolm.in.the.middle.s02e05.dvdrip.xvid-ingot";
|
||||||
|
|
||||||
_downloadClientItem.Title = title + extension;
|
_downloadClientItem.Title = title + extension;
|
||||||
@@ -176,8 +164,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
|||||||
[Test]
|
[Test]
|
||||||
public void should_not_use_nzb_title_as_scene_name_if_full_season()
|
public void should_not_use_nzb_title_as_scene_name_if_full_season()
|
||||||
{
|
{
|
||||||
GivenNewDownload();
|
_approvedDecisions.First().LocalEpisode.Path = "c:\\tv\\season1\\malcolm.in.the.middle.s02e23.dvdrip.xvid-ingot.mkv".AsOsAgnostic();
|
||||||
_approvedDecisions.First().LocalEpisode.Path = Path.Combine(_downloadClientItem.OutputPath.ToString(), "malcolm.in.the.middle.s02e23.dvdrip.xvid-ingot.mkv");
|
|
||||||
_downloadClientItem.Title = "malcolm.in.the.middle.s02.dvdrip.xvid-ingot";
|
_downloadClientItem.Title = "malcolm.in.the.middle.s02.dvdrip.xvid-ingot";
|
||||||
|
|
||||||
Subject.Import(new List<ImportDecision> { _approvedDecisions.First() }, true, _downloadClientItem);
|
Subject.Import(new List<ImportDecision> { _approvedDecisions.First() }, true, _downloadClientItem);
|
||||||
@@ -188,8 +175,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
|||||||
[Test]
|
[Test]
|
||||||
public void should_use_file_name_as_scenename_only_if_it_looks_like_scenename()
|
public void should_use_file_name_as_scenename_only_if_it_looks_like_scenename()
|
||||||
{
|
{
|
||||||
GivenNewDownload();
|
_approvedDecisions.First().LocalEpisode.Path = "c:\\tv\\malcolm.in.the.middle.s02e23.dvdrip.xvid-ingot.mkv".AsOsAgnostic();
|
||||||
_approvedDecisions.First().LocalEpisode.Path = Path.Combine(_downloadClientItem.OutputPath.ToString(), "malcolm.in.the.middle.s02e23.dvdrip.xvid-ingot.mkv");
|
|
||||||
|
|
||||||
Subject.Import(new List<ImportDecision> { _approvedDecisions.First() }, true);
|
Subject.Import(new List<ImportDecision> { _approvedDecisions.First() }, true);
|
||||||
|
|
||||||
@@ -199,8 +185,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
|||||||
[Test]
|
[Test]
|
||||||
public void should_not_use_file_name_as_scenename_if_it_doesnt_looks_like_scenename()
|
public void should_not_use_file_name_as_scenename_if_it_doesnt_looks_like_scenename()
|
||||||
{
|
{
|
||||||
GivenNewDownload();
|
_approvedDecisions.First().LocalEpisode.Path = "c:\\tv\\aaaaa.mkv".AsOsAgnostic();
|
||||||
_approvedDecisions.First().LocalEpisode.Path = Path.Combine(_downloadClientItem.OutputPath.ToString(), "aaaaa.mkv");
|
|
||||||
|
|
||||||
Subject.Import(new List<ImportDecision> { _approvedDecisions.First() }, true);
|
Subject.Import(new List<ImportDecision> { _approvedDecisions.First() }, true);
|
||||||
|
|
||||||
@@ -238,11 +223,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
|||||||
[Test]
|
[Test]
|
||||||
public void should_copy_when_cannot_move_files_downloads()
|
public void should_copy_when_cannot_move_files_downloads()
|
||||||
{
|
{
|
||||||
GivenNewDownload();
|
Subject.Import(new List<ImportDecision> { _approvedDecisions.First() }, true, new DownloadClientItem { Title = "30.Rock.S01E01", CanMoveFiles = false});
|
||||||
_downloadClientItem.Title = "30.Rock.S01E01";
|
|
||||||
_downloadClientItem.CanMoveFiles = false;
|
|
||||||
|
|
||||||
Subject.Import(new List<ImportDecision> { _approvedDecisions.First() }, true, _downloadClientItem);
|
|
||||||
|
|
||||||
Mocker.GetMock<IUpgradeMediaFiles>()
|
Mocker.GetMock<IUpgradeMediaFiles>()
|
||||||
.Verify(v => v.UpgradeEpisodeFile(It.IsAny<EpisodeFile>(), _approvedDecisions.First().LocalEpisode, true), Times.Once());
|
.Verify(v => v.UpgradeEpisodeFile(It.IsAny<EpisodeFile>(), _approvedDecisions.First().LocalEpisode, true), Times.Once());
|
||||||
@@ -251,71 +232,10 @@ namespace NzbDrone.Core.Test.MediaFiles
|
|||||||
[Test]
|
[Test]
|
||||||
public void should_use_override_importmode()
|
public void should_use_override_importmode()
|
||||||
{
|
{
|
||||||
GivenNewDownload();
|
Subject.Import(new List<ImportDecision> { _approvedDecisions.First() }, true, new DownloadClientItem { Title = "30.Rock.S01E01", CanMoveFiles = false }, ImportMode.Move);
|
||||||
_downloadClientItem.Title = "30.Rock.S01E01";
|
|
||||||
_downloadClientItem.CanMoveFiles = false;
|
|
||||||
|
|
||||||
Subject.Import(new List<ImportDecision> { _approvedDecisions.First() }, true, _downloadClientItem, ImportMode.Move);
|
|
||||||
|
|
||||||
Mocker.GetMock<IUpgradeMediaFiles>()
|
Mocker.GetMock<IUpgradeMediaFiles>()
|
||||||
.Verify(v => v.UpgradeEpisodeFile(It.IsAny<EpisodeFile>(), _approvedDecisions.First().LocalEpisode, false), Times.Once());
|
.Verify(v => v.UpgradeEpisodeFile(It.IsAny<EpisodeFile>(), _approvedDecisions.First().LocalEpisode, false), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_use_file_name_only_for_download_client_item_without_a_job_folder()
|
|
||||||
{
|
|
||||||
var fileName = "Series.Title.S01E01.720p.HDTV.x264-Sonarr.mkv";
|
|
||||||
var path = Path.Combine(@"C:\Test\Unsorted\TV\".AsOsAgnostic(), fileName);
|
|
||||||
|
|
||||||
_downloadClientItem.OutputPath = new OsPath(path);
|
|
||||||
_approvedDecisions.First().LocalEpisode.Path = path;
|
|
||||||
|
|
||||||
Subject.Import(new List<ImportDecision> { _approvedDecisions.First() }, true, _downloadClientItem);
|
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileService>().Verify(v => v.Add(It.Is<EpisodeFile>(c => c.OriginalFilePath == fileName)));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_use_folder_and_file_name_only_for_download_client_item_with_a_job_folder()
|
|
||||||
{
|
|
||||||
var name = "Series.Title.S01E01.720p.HDTV.x264-Sonarr";
|
|
||||||
var outputPath = Path.Combine(@"C:\Test\Unsorted\TV\".AsOsAgnostic(), name);
|
|
||||||
|
|
||||||
_downloadClientItem.OutputPath = new OsPath(outputPath);
|
|
||||||
_approvedDecisions.First().LocalEpisode.Path = Path.Combine(outputPath, name + ".mkv");
|
|
||||||
|
|
||||||
Subject.Import(new List<ImportDecision> { _approvedDecisions.First() }, true, _downloadClientItem);
|
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileService>().Verify(v => v.Add(It.Is<EpisodeFile>(c => c.OriginalFilePath == $"{name}\\{name}.mkv".AsOsAgnostic())));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_include_intermediate_folders_for_download_client_item_with_a_job_folder()
|
|
||||||
{
|
|
||||||
var name = "Series.Title.S01E01.720p.HDTV.x264-Sonarr";
|
|
||||||
var outputPath = Path.Combine(@"C:\Test\Unsorted\TV\".AsOsAgnostic(), name);
|
|
||||||
|
|
||||||
_downloadClientItem.OutputPath = new OsPath(outputPath);
|
|
||||||
_approvedDecisions.First().LocalEpisode.Path = Path.Combine(outputPath, "subfolder", name + ".mkv");
|
|
||||||
|
|
||||||
Subject.Import(new List<ImportDecision> { _approvedDecisions.First() }, true, _downloadClientItem);
|
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileService>().Verify(v => v.Add(It.Is<EpisodeFile>(c => c.OriginalFilePath == $"{name}\\subfolder\\{name}.mkv".AsOsAgnostic())));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_use_folder_info_release_title_to_find_relative_path()
|
|
||||||
{
|
|
||||||
var name = "Series.Title.S01E01.720p.HDTV.x264-Sonarr";
|
|
||||||
var outputPath = Path.Combine(@"C:\Test\Unsorted\TV\".AsOsAgnostic(), name);
|
|
||||||
var localEpisode = _approvedDecisions.First().LocalEpisode;
|
|
||||||
|
|
||||||
localEpisode.FolderEpisodeInfo = new ParsedEpisodeInfo { ReleaseTitle = name };
|
|
||||||
localEpisode.Path = Path.Combine(outputPath, "subfolder", name + ".mkv");
|
|
||||||
|
|
||||||
Subject.Import(new List<ImportDecision> { _approvedDecisions.First() }, true, null);
|
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileService>().Verify(v => v.Add(It.Is<EpisodeFile>(c => c.OriginalFilePath == $"{name}\\subfolder\\{name}.mkv".AsOsAgnostic())));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,12 +44,12 @@ namespace NzbDrone.Core.Test.MetadataSource.SkyHook
|
|||||||
[TestCase("tvdbid: 0")]
|
[TestCase("tvdbid: 0")]
|
||||||
[TestCase("tvdbid: -12")]
|
[TestCase("tvdbid: -12")]
|
||||||
[TestCase("tvdbid:289578")]
|
[TestCase("tvdbid:289578")]
|
||||||
[TestCase("adjalkwdjkalwdjklawjdlKAJD")]
|
[TestCase("adjalkwdjkalwdjklawjdlKAJD;EF")]
|
||||||
public void no_search_result(string term)
|
public void no_search_result(string term)
|
||||||
{
|
{
|
||||||
var result = Subject.SearchForNewSeries(term);
|
var result = Subject.SearchForNewSeries(term);
|
||||||
result.Should().BeEmpty();
|
result.Should().BeEmpty();
|
||||||
|
|
||||||
ExceptionVerification.IgnoreWarns();
|
ExceptionVerification.IgnoreWarns();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,29 +136,5 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||||||
result.SeriesTitle.Should().Be(title);
|
result.SeriesTitle.Should().Be(title);
|
||||||
result.FullSeason.Should().BeFalse();
|
result.FullSeason.Should().BeFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("[Vivid] Living Sky Saga S01 [Web][MKV][h264 10-bit][1080p][AAC 2.0]", "Living Sky Saga", 1)]
|
|
||||||
public void should_parse_anime_season_packs(string postTitle, string title, int seasonNumber)
|
|
||||||
{
|
|
||||||
var result = Parser.Parser.ParseTitle(postTitle);
|
|
||||||
result.Should().NotBeNull();
|
|
||||||
result.AbsoluteEpisodeNumbers.Should().BeEmpty();
|
|
||||||
result.SeriesTitle.Should().Be(title);
|
|
||||||
result.FullSeason.Should().BeTrue();
|
|
||||||
result.SeasonNumber.Should().Be(seasonNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase("[HorribleSubs] Goblin Slayer - 10.5 [1080p].mkv", "Goblin Slayer", 10.5)]
|
|
||||||
public void should_handle_anime_recap_numbering(string postTitle, string title, double specialEpisodeNumber)
|
|
||||||
{
|
|
||||||
var result = Parser.Parser.ParseTitle(postTitle);
|
|
||||||
result.Should().NotBeNull();
|
|
||||||
result.SeriesTitle.Should().Be(title);
|
|
||||||
result.AbsoluteEpisodeNumbers.Should().BeEmpty();
|
|
||||||
result.SpecialAbsoluteEpisodeNumbers.Should().NotBeEmpty();
|
|
||||||
result.SpecialAbsoluteEpisodeNumbers.Should().BeEquivalentTo(new[] { (decimal)specialEpisodeNumber });
|
|
||||||
result.FullSeason.Should().BeFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,13 +87,6 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||||||
"Fargo",
|
"Fargo",
|
||||||
Quality.WEBDL1080p,
|
Quality.WEBDL1080p,
|
||||||
"RARBG"
|
"RARBG"
|
||||||
},
|
|
||||||
new object[]
|
|
||||||
{
|
|
||||||
@"C:\Test\XxQVHK4GJMP3n2dLpmhW\XxQVHK4GJMP3n2dLpmhW\MKV\010E70S.yhcranA.fo.snoS.mkv".AsOsAgnostic(),
|
|
||||||
"Sons of Anarchy",
|
|
||||||
Quality.HDTV720p,
|
|
||||||
null
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Moq;
|
using Moq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
@@ -26,8 +25,8 @@ namespace NzbDrone.Core.Test.ThingiProviderTests
|
|||||||
|
|
||||||
public class MockProviderStatusService : ProviderStatusServiceBase<IMockProvider, MockProviderStatus>
|
public class MockProviderStatusService : ProviderStatusServiceBase<IMockProvider, MockProviderStatus>
|
||||||
{
|
{
|
||||||
public MockProviderStatusService(IMockProviderStatusRepository providerStatusRepository, IEventAggregator eventAggregator, IRuntimeInfo runtimeInfo, Logger logger)
|
public MockProviderStatusService(IMockProviderStatusRepository providerStatusRepository, IEventAggregator eventAggregator, Logger logger)
|
||||||
: base(providerStatusRepository, eventAggregator, runtimeInfo, logger)
|
: base(providerStatusRepository, eventAggregator, logger)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -41,20 +40,9 @@ namespace NzbDrone.Core.Test.ThingiProviderTests
|
|||||||
public void SetUp()
|
public void SetUp()
|
||||||
{
|
{
|
||||||
_epoch = DateTime.UtcNow;
|
_epoch = DateTime.UtcNow;
|
||||||
|
|
||||||
Mocker.GetMock<IRuntimeInfo>()
|
|
||||||
.SetupGet(v => v.StartTime)
|
|
||||||
.Returns(_epoch - TimeSpan.FromHours(1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenRecentStartup()
|
private void WithStatus(MockProviderStatus status)
|
||||||
{
|
|
||||||
Mocker.GetMock<IRuntimeInfo>()
|
|
||||||
.SetupGet(v => v.StartTime)
|
|
||||||
.Returns(_epoch - TimeSpan.FromMinutes(12));
|
|
||||||
}
|
|
||||||
|
|
||||||
private MockProviderStatus WithStatus(MockProviderStatus status)
|
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IMockProviderStatusRepository>()
|
Mocker.GetMock<IMockProviderStatusRepository>()
|
||||||
.Setup(v => v.FindByProviderId(1))
|
.Setup(v => v.FindByProviderId(1))
|
||||||
@@ -63,8 +51,6 @@ namespace NzbDrone.Core.Test.ThingiProviderTests
|
|||||||
Mocker.GetMock<IMockProviderStatusRepository>()
|
Mocker.GetMock<IMockProviderStatusRepository>()
|
||||||
.Setup(v => v.All())
|
.Setup(v => v.All())
|
||||||
.Returns(new[] { status });
|
.Returns(new[] { status });
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void VerifyUpdate()
|
private void VerifyUpdate()
|
||||||
@@ -136,32 +122,5 @@ namespace NzbDrone.Core.Test.ThingiProviderTests
|
|||||||
status.DisabledTill.Should().HaveValue();
|
status.DisabledTill.Should().HaveValue();
|
||||||
status.DisabledTill.Value.Should().BeCloseTo(_epoch + TimeSpan.FromMinutes(15), 500);
|
status.DisabledTill.Value.Should().BeCloseTo(_epoch + TimeSpan.FromMinutes(15), 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_not_escalate_further_till_after_5_minutes_since_startup()
|
|
||||||
{
|
|
||||||
GivenRecentStartup();
|
|
||||||
|
|
||||||
var origStatus = WithStatus(new MockProviderStatus
|
|
||||||
{
|
|
||||||
InitialFailure = _epoch - TimeSpan.FromMinutes(6),
|
|
||||||
MostRecentFailure = _epoch - TimeSpan.FromSeconds(120),
|
|
||||||
EscalationLevel = 3
|
|
||||||
});
|
|
||||||
|
|
||||||
Subject.RecordFailure(1);
|
|
||||||
Subject.RecordFailure(1);
|
|
||||||
Subject.RecordFailure(1);
|
|
||||||
Subject.RecordFailure(1);
|
|
||||||
Subject.RecordFailure(1);
|
|
||||||
Subject.RecordFailure(1);
|
|
||||||
Subject.RecordFailure(1);
|
|
||||||
|
|
||||||
var status = Subject.GetBlockedProviders().FirstOrDefault();
|
|
||||||
status.Should().NotBeNull();
|
|
||||||
|
|
||||||
origStatus.EscalationLevel.Should().Be(3);
|
|
||||||
status.DisabledTill.Should().BeCloseTo(_epoch + TimeSpan.FromMinutes(5), 500);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Data.SQLite;
|
using System.Data.SQLite;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Common.Instrumentation;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Datastore
|
namespace NzbDrone.Core.Datastore
|
||||||
{
|
{
|
||||||
@@ -14,10 +17,20 @@ namespace NzbDrone.Core.Datastore
|
|||||||
|
|
||||||
public class ConnectionStringFactory : IConnectionStringFactory
|
public class ConnectionStringFactory : IConnectionStringFactory
|
||||||
{
|
{
|
||||||
public ConnectionStringFactory(IAppFolderInfo appFolderInfo)
|
private static readonly Logger Logger = NzbDroneLogger.GetLogger(typeof(ConnectionStringFactory));
|
||||||
|
|
||||||
|
public ConnectionStringFactory(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider)
|
||||||
{
|
{
|
||||||
MainDbConnectionString = GetConnectionString(appFolderInfo.GetNzbDroneDatabase());
|
var mount = diskProvider.GetMount(appFolderInfo.AppDataFolder);
|
||||||
LogDbConnectionString = GetConnectionString(appFolderInfo.GetLogDatabase());
|
var isNetworkDrive = mount.DriveType == System.IO.DriveType.Network;
|
||||||
|
if (isNetworkDrive)
|
||||||
|
{
|
||||||
|
Logger.Warn("AppData folder {0} is located on the network drive {1} using a {2} filesystem. Is highly discouraged to use a SQLite database on network drives and may lead to database corruption.",
|
||||||
|
appFolderInfo.AppDataFolder, mount.RootDirectory, mount.DriveFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
MainDbConnectionString = GetConnectionString(appFolderInfo.GetNzbDroneDatabase(), isNetworkDrive);
|
||||||
|
LogDbConnectionString = GetConnectionString(appFolderInfo.GetLogDatabase(), isNetworkDrive);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string MainDbConnectionString { get; private set; }
|
public string MainDbConnectionString { get; private set; }
|
||||||
@@ -30,14 +43,14 @@ namespace NzbDrone.Core.Datastore
|
|||||||
return connectionBuilder.DataSource;
|
return connectionBuilder.DataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetConnectionString(string dbPath)
|
private static string GetConnectionString(string dbPath, bool isNetworkDrive)
|
||||||
{
|
{
|
||||||
var connectionBuilder = new SQLiteConnectionStringBuilder();
|
var connectionBuilder = new SQLiteConnectionStringBuilder();
|
||||||
|
|
||||||
connectionBuilder.DataSource = dbPath;
|
connectionBuilder.DataSource = dbPath;
|
||||||
connectionBuilder.CacheSize = (int)-10000;
|
connectionBuilder.CacheSize = (int)-10.Megabytes();
|
||||||
connectionBuilder.DateTimeKind = DateTimeKind.Utc;
|
connectionBuilder.DateTimeKind = DateTimeKind.Utc;
|
||||||
connectionBuilder.JournalMode = OsInfo.IsOsx ? SQLiteJournalModeEnum.Truncate : SQLiteJournalModeEnum.Wal;
|
connectionBuilder.JournalMode = OsInfo.IsOsx || isNetworkDrive ? SQLiteJournalModeEnum.Truncate : SQLiteJournalModeEnum.Wal;
|
||||||
connectionBuilder.Pooling = true;
|
connectionBuilder.Pooling = true;
|
||||||
connectionBuilder.Version = 3;
|
connectionBuilder.Version = 3;
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
using FluentMigrator;
|
|
||||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Datastore.Migration
|
|
||||||
{
|
|
||||||
[Migration(129)]
|
|
||||||
public class add_relative_original_path_to_episode_file : NzbDroneMigrationBase
|
|
||||||
{
|
|
||||||
protected override void MainDbUpgrade()
|
|
||||||
{
|
|
||||||
Alter.Table("EpisodeFiles").AddColumn("OriginalFilePath").AsString().Nullable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
using FluentMigrator;
|
|
||||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Datastore.Migration
|
|
||||||
{
|
|
||||||
[Migration(130)]
|
|
||||||
public class episode_last_searched_time : NzbDroneMigrationBase
|
|
||||||
{
|
|
||||||
protected override void MainDbUpgrade()
|
|
||||||
{
|
|
||||||
Alter.Table("Episodes").AddColumn("LastSearchTime").AsDateTime().Nullable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
using NzbDrone.Core.ThingiProvider.Status;
|
using NzbDrone.Core.ThingiProvider.Status;
|
||||||
|
|
||||||
@@ -13,8 +12,8 @@ namespace NzbDrone.Core.Download
|
|||||||
|
|
||||||
public class DownloadClientStatusService : ProviderStatusServiceBase<IDownloadClient, DownloadClientStatus>, IDownloadClientStatusService
|
public class DownloadClientStatusService : ProviderStatusServiceBase<IDownloadClient, DownloadClientStatus>, IDownloadClientStatusService
|
||||||
{
|
{
|
||||||
public DownloadClientStatusService(IDownloadClientStatusRepository providerStatusRepository, IEventAggregator eventAggregator, IRuntimeInfo runtimeInfo, Logger logger)
|
public DownloadClientStatusService(IDownloadClientStatusRepository providerStatusRepository, IEventAggregator eventAggregator, Logger logger)
|
||||||
: base(providerStatusRepository, eventAggregator, runtimeInfo, logger)
|
: base(providerStatusRepository, eventAggregator, logger)
|
||||||
{
|
{
|
||||||
MinimumTimeSinceInitialFailure = TimeSpan.FromMinutes(5);
|
MinimumTimeSinceInitialFailure = TimeSpan.FromMinutes(5);
|
||||||
MaximumEscalationLevel = 5;
|
MaximumEscalationLevel = 5;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -314,16 +314,6 @@ namespace NzbDrone.Core.IndexerSearch
|
|||||||
|
|
||||||
_logger.Debug("Total of {0} reports were found for {1} from {2} indexers", reports.Count, criteriaBase, indexers.Count);
|
_logger.Debug("Total of {0} reports were found for {1} from {2} indexers", reports.Count, criteriaBase, indexers.Count);
|
||||||
|
|
||||||
// Update the last search time for all episodes if at least 1 indexer was searched.
|
|
||||||
if (indexers.Any())
|
|
||||||
{
|
|
||||||
var lastSearchTime = DateTime.UtcNow;
|
|
||||||
_logger.Debug("Setting last search time to: {0}", lastSearchTime);
|
|
||||||
|
|
||||||
criteriaBase.Episodes.ForEach(e => e.LastSearchTime = lastSearchTime);
|
|
||||||
_episodeService.UpdateEpisodes(criteriaBase.Episodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _makeDownloadDecision.GetSearchDecision(reports, criteriaBase).ToList();
|
return _makeDownloadDecision.GetSearchDecision(reports, criteriaBase).ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.ThingiProvider.Status;
|
using NzbDrone.Core.ThingiProvider.Status;
|
||||||
@@ -15,8 +14,8 @@ namespace NzbDrone.Core.Indexers
|
|||||||
|
|
||||||
public class IndexerStatusService : ProviderStatusServiceBase<IIndexer, IndexerStatus>, IIndexerStatusService
|
public class IndexerStatusService : ProviderStatusServiceBase<IIndexer, IndexerStatus>, IIndexerStatusService
|
||||||
{
|
{
|
||||||
public IndexerStatusService(IIndexerStatusRepository providerStatusRepository, IEventAggregator eventAggregator, IRuntimeInfo runtimeInfo, Logger logger)
|
public IndexerStatusService(IIndexerStatusRepository providerStatusRepository, IEventAggregator eventAggregator, Logger logger)
|
||||||
: base(providerStatusRepository, eventAggregator, runtimeInfo, logger)
|
: base(providerStatusRepository, eventAggregator, logger)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Marr.Data;
|
using Marr.Data;
|
||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
@@ -17,7 +17,6 @@ namespace NzbDrone.Core.MediaFiles
|
|||||||
public string Path { get; set; }
|
public string Path { get; set; }
|
||||||
public long Size { get; set; }
|
public long Size { get; set; }
|
||||||
public DateTime DateAdded { get; set; }
|
public DateTime DateAdded { get; set; }
|
||||||
public string OriginalFilePath { get; set; }
|
|
||||||
public string SceneName { get; set; }
|
public string SceneName { get; set; }
|
||||||
public string ReleaseGroup { get; set; }
|
public string ReleaseGroup { get; set; }
|
||||||
public QualityModel Quality { get; set; }
|
public QualityModel Quality { get; set; }
|
||||||
|
|||||||
@@ -102,7 +102,6 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
|||||||
|
|
||||||
if (newDownload)
|
if (newDownload)
|
||||||
{
|
{
|
||||||
episodeFile.OriginalFilePath = GetOriginalFilePath(downloadClientItem, localEpisode);
|
|
||||||
episodeFile.SceneName = GetSceneName(downloadClientItem, localEpisode);
|
episodeFile.SceneName = GetSceneName(downloadClientItem, localEpisode);
|
||||||
|
|
||||||
var moveResult = _episodeFileUpgrader.UpgradeEpisodeFile(episodeFile, localEpisode, copyOnly);
|
var moveResult = _episodeFileUpgrader.UpgradeEpisodeFile(episodeFile, localEpisode, copyOnly);
|
||||||
@@ -149,37 +148,6 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
|||||||
return importResults;
|
return importResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetOriginalFilePath(DownloadClientItem downloadClientItem, LocalEpisode localEpisode)
|
|
||||||
{
|
|
||||||
if (downloadClientItem != null)
|
|
||||||
{
|
|
||||||
return downloadClientItem.OutputPath.Directory.ToString().GetRelativePath(localEpisode.Path);
|
|
||||||
}
|
|
||||||
|
|
||||||
var path = localEpisode.Path;
|
|
||||||
var folderEpisodeInfo = localEpisode.FolderEpisodeInfo;
|
|
||||||
|
|
||||||
if (folderEpisodeInfo != null)
|
|
||||||
{
|
|
||||||
var folderPath = path.GetAncestorPath(folderEpisodeInfo.ReleaseTitle);
|
|
||||||
|
|
||||||
if (folderPath != null)
|
|
||||||
{
|
|
||||||
return folderPath.GetParentPath().GetRelativePath(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var parentPath = path.GetParentPath();
|
|
||||||
var grandparentPath = parentPath.GetParentPath();
|
|
||||||
|
|
||||||
if (grandparentPath != null)
|
|
||||||
{
|
|
||||||
return grandparentPath.GetRelativePath(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Path.Combine(Path.GetFileName(parentPath), Path.GetFileName(path));
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetSceneName(DownloadClientItem downloadClientItem, LocalEpisode localEpisode)
|
private string GetSceneName(DownloadClientItem downloadClientItem, LocalEpisode localEpisode)
|
||||||
{
|
{
|
||||||
if (downloadClientItem != null)
|
if (downloadClientItem != null)
|
||||||
|
|||||||
@@ -143,8 +143,6 @@
|
|||||||
<Compile Include="Configuration\IConfigService.cs" />
|
<Compile Include="Configuration\IConfigService.cs" />
|
||||||
<Compile Include="Configuration\InvalidConfigFileException.cs" />
|
<Compile Include="Configuration\InvalidConfigFileException.cs" />
|
||||||
<Compile Include="Configuration\ResetApiKeyCommand.cs" />
|
<Compile Include="Configuration\ResetApiKeyCommand.cs" />
|
||||||
<Compile Include="Datastore\Migration\130_episode_last_searched_time.cs" />
|
|
||||||
<Compile Include="Datastore\Migration\129_add_relative_original_path_to_episode_file.cs" />
|
|
||||||
<Compile Include="DecisionEngine\Specifications\AlreadyImportedSpecification.cs" />
|
<Compile Include="DecisionEngine\Specifications\AlreadyImportedSpecification.cs" />
|
||||||
<Compile Include="Indexers\SeedConfigProvider.cs" />
|
<Compile Include="Indexers\SeedConfigProvider.cs" />
|
||||||
<Compile Include="DataAugmentation\DailySeries\DailySeries.cs" />
|
<Compile Include="DataAugmentation\DailySeries\DailySeries.cs" />
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ namespace NzbDrone.Core.Parser.Model
|
|||||||
public int SeasonNumber { get; set; }
|
public int SeasonNumber { get; set; }
|
||||||
public int[] EpisodeNumbers { get; set; }
|
public int[] EpisodeNumbers { get; set; }
|
||||||
public int[] AbsoluteEpisodeNumbers { get; set; }
|
public int[] AbsoluteEpisodeNumbers { get; set; }
|
||||||
public decimal[] SpecialAbsoluteEpisodeNumbers { get; set; }
|
|
||||||
public string AirDate { get; set; }
|
public string AirDate { get; set; }
|
||||||
public Language Language { get; set; }
|
public Language Language { get; set; }
|
||||||
public bool FullSeason { get; set; }
|
public bool FullSeason { get; set; }
|
||||||
@@ -28,7 +27,6 @@ namespace NzbDrone.Core.Parser.Model
|
|||||||
{
|
{
|
||||||
EpisodeNumbers = new int[0];
|
EpisodeNumbers = new int[0];
|
||||||
AbsoluteEpisodeNumbers = new int[0];
|
AbsoluteEpisodeNumbers = new int[0];
|
||||||
SpecialAbsoluteEpisodeNumbers = new decimal[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsDaily
|
public bool IsDaily
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
@@ -40,15 +39,15 @@ namespace NzbDrone.Core.Parser
|
|||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
//Anime - [SubGroup] Title Episode Absolute Episode Number ([SubGroup] Series Title Episode 01)
|
//Anime - [SubGroup] Title Episode Absolute Episode Number ([SubGroup] Series Title Episode 01)
|
||||||
new Regex(@"^(?:\[(?<subgroup>.+?)\][-_. ]?)(?<title>.+?)[-_. ](?:Episode)(?:[-_. ]+(?<absoluteepisode>(?<!\d+)\d{2,3}(\.\d{1,2})?(?!\d+)))+(?:_|-|\s|\.)*?(?<hash>\[.{8}\])?(?:$|\.)?",
|
new Regex(@"^(?:\[(?<subgroup>.+?)\][-_. ]?)(?<title>.+?)[-_. ](?:Episode)(?:[-_. ]+(?<absoluteepisode>(?<!\d+)\d{2,3}(?!\d+)))+(?:_|-|\s|\.)*?(?<hash>\[.{8}\])?(?:$|\.)?",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
//Anime - [SubGroup] Title Absolute Episode Number + Season+Episode
|
//Anime - [SubGroup] Title Absolute Episode Number + Season+Episode
|
||||||
new Regex(@"^(?:\[(?<subgroup>.+?)\](?:_|-|\s|\.)?)(?<title>.+?)(?:(?:[-_\W](?<![()\[!]))+(?<absoluteepisode>\d{2,3}(\.\d{1,2})?))+(?:_|-|\s|\.)+(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]){1,2}(?<episode>\d{2}(?!\d+)))+).*?(?<hash>[(\[]\w{8}[)\]])?(?:$|\.)",
|
new Regex(@"^(?:\[(?<subgroup>.+?)\](?:_|-|\s|\.)?)(?<title>.+?)(?:(?:[-_\W](?<![()\[!]))+(?<absoluteepisode>\d{2,3}))+(?:_|-|\s|\.)+(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]){1,2}(?<episode>\d{2}(?!\d+)))+).*?(?<hash>[(\[]\w{8}[)\]])?(?:$|\.)",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
//Anime - [SubGroup] Title Season+Episode + Absolute Episode Number
|
//Anime - [SubGroup] Title Season+Episode + Absolute Episode Number
|
||||||
new Regex(@"^(?:\[(?<subgroup>.+?)\](?:_|-|\s|\.)?)(?<title>.+?)(?:[-_\W](?<![()\[!]))+(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]){1,2}(?<episode>\d{2}(?!\d+)))+)(?:(?:_|-|\s|\.)+(?<absoluteepisode>(?<!\d+)\d{2,3}(\.\d{1,2})?(?!\d+)))+.*?(?<hash>\[\w{8}\])?(?:$|\.)",
|
new Regex(@"^(?:\[(?<subgroup>.+?)\](?:_|-|\s|\.)?)(?<title>.+?)(?:[-_\W](?<![()\[!]))+(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]){1,2}(?<episode>\d{2}(?!\d+)))+)(?:(?:_|-|\s|\.)+(?<absoluteepisode>(?<!\d+)\d{2,3}(?!\d+)))+.*?(?<hash>\[\w{8}\])?(?:$|\.)",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
//Anime - [SubGroup] Title Season+Episode
|
//Anime - [SubGroup] Title Season+Episode
|
||||||
@@ -56,15 +55,15 @@ namespace NzbDrone.Core.Parser
|
|||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
//Anime - [SubGroup] Title with trailing number Absolute Episode Number
|
//Anime - [SubGroup] Title with trailing number Absolute Episode Number
|
||||||
new Regex(@"^\[(?<subgroup>.+?)\][-_. ]?(?<title>[^-]+?\d+?)[-_. ]+(?:[-_. ]?(?<absoluteepisode>\d{3}(\.\d{1,2})?(?!\d+)))+(?:[-_. ]+(?<special>special|ova|ovd))?.*?(?<hash>\[\w{8}\])?(?:$|\.mkv)",
|
new Regex(@"^\[(?<subgroup>.+?)\][-_. ]?(?<title>[^-]+?\d+?)[-_. ]+(?:[-_. ]?(?<absoluteepisode>\d{3}(?!\d+)))+(?:[-_. ]+(?<special>special|ova|ovd))?.*?(?<hash>\[\w{8}\])?(?:$|\.mkv)",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
//Anime - [SubGroup] Title - Absolute Episode Number
|
//Anime - [SubGroup] Title - Absolute Episode Number
|
||||||
new Regex(@"^\[(?<subgroup>.+?)\][-_. ]?(?<title>.+?)(?:[. ]-[. ](?<absoluteepisode>\d{2,3}(\.\d{1,2})?(?!\d+|[-])))+(?:[-_. ]+(?<special>special|ova|ovd))?.*?(?<hash>\[\w{8}\])?(?:$|\.mkv)",
|
new Regex(@"^\[(?<subgroup>.+?)\][-_. ]?(?<title>.+?)(?:[. ]-[. ](?<absoluteepisode>\d{2,3}(?!\d+|[-])))+(?:[-_. ]+(?<special>special|ova|ovd))?.*?(?<hash>\[\w{8}\])?(?:$|\.mkv)",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
//Anime - [SubGroup] Title Absolute Episode Number
|
//Anime - [SubGroup] Title Absolute Episode Number
|
||||||
new Regex(@"^\[(?<subgroup>.+?)\][-_. ]?(?<title>.+?)[-_. ]+\(?(?:[-_. ]?#?(?<absoluteepisode>\d{2,3}(\.\d{1,2})?(?!\d+)))+\)?(?:[-_. ]+(?<special>special|ova|ovd))?.*?(?<hash>\[\w{8}\])?(?:$|\.mkv)",
|
new Regex(@"^\[(?<subgroup>.+?)\][-_. ]?(?<title>.+?)[-_. ]+\(?(?:[-_. ]?#?(?<absoluteepisode>\d{2,3}(?!\d+)))+\)?(?:[-_. ]+(?<special>special|ova|ovd))?.*?(?<hash>\[\w{8}\])?(?:$|\.mkv)",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
//Multi-episode Repeated (S01E05 - S01E06, 1x05 - 1x06, etc)
|
//Multi-episode Repeated (S01E05 - S01E06, 1x05 - 1x06, etc)
|
||||||
@@ -76,7 +75,7 @@ namespace NzbDrone.Core.Parser
|
|||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
//Anime - Title Season EpisodeNumber + Absolute Episode Number [SubGroup]
|
//Anime - Title Season EpisodeNumber + Absolute Episode Number [SubGroup]
|
||||||
new Regex(@"^(?<title>.+?)(?:[-_\W](?<![()\[!]))+(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:[ex]|\W[ex]){1,2}(?<episode>(?<!\d+)\d{2}(?!\d+)))).+?(?:[-_. ]?(?<absoluteepisode>(?<!\d+)\d{3}(\.\d{1,2})?(?!\d+)))+.+?\[(?<subgroup>.+?)\](?:$|\.mkv)",
|
new Regex(@"^(?<title>.+?)(?:[-_\W](?<![()\[!]))+(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:[ex]|\W[ex]){1,2}(?<episode>(?<!\d+)\d{2}(?!\d+)))).+?(?:[-_. ]?(?<absoluteepisode>(?<!\d+)\d{3}(?!\d+)))+.+?\[(?<subgroup>.+?)\](?:$|\.mkv)",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
//Multi-Episode with a title (S01E05E06, S01E05-06, S01E05 E06, etc) and trailing info in slashes
|
//Multi-Episode with a title (S01E05E06, S01E05-06, S01E05 E06, etc) and trailing info in slashes
|
||||||
@@ -84,11 +83,11 @@ namespace NzbDrone.Core.Parser
|
|||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
//Anime - Title Absolute Episode Number [SubGroup]
|
//Anime - Title Absolute Episode Number [SubGroup]
|
||||||
new Regex(@"^(?<title>.+?)(?:(?:_|-|\s|\.)+(?<absoluteepisode>\d{3}(\.\d{1,2})?(?!\d+)))+(?:.+?)\[(?<subgroup>.+?)\].*?(?<hash>\[\w{8}\])?(?:$|\.)",
|
new Regex(@"^(?<title>.+?)(?:(?:_|-|\s|\.)+(?<absoluteepisode>\d{3}(?!\d+)))+(?:.+?)\[(?<subgroup>.+?)\].*?(?<hash>\[\w{8}\])?(?:$|\.)",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
//Anime - Title Absolute Episode Number [Hash]
|
//Anime - Title Absolute Episode Number [Hash]
|
||||||
new Regex(@"^(?<title>.+?)(?:(?:_|-|\s|\.)+(?<absoluteepisode>\d{2,3}(\.\d{1,2})?(?!\d+)))+(?:[-_. ]+(?<special>special|ova|ovd))?[-_. ]+.*?(?<hash>\[\w{8}\])(?:$|\.)",
|
new Regex(@"^(?<title>.+?)(?:(?:_|-|\s|\.)+(?<absoluteepisode>\d{2,3}(?!\d+)))+(?:[-_. ]+(?<special>special|ova|ovd))?[-_. ]+.*?(?<hash>\[\w{8}\])(?:$|\.)",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
//Episodes with airdate AND season/episode number, capture season/epsiode only
|
//Episodes with airdate AND season/episode number, capture season/epsiode only
|
||||||
@@ -172,11 +171,11 @@ namespace NzbDrone.Core.Parser
|
|||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
// Anime - Title with season number - Absolute Episode Number (Title S01 - EP14)
|
// Anime - Title with season number - Absolute Episode Number (Title S01 - EP14)
|
||||||
new Regex(@"^(?<title>.+?S\d{1,2})[-_. ]{3,}(?:EP)?(?<absoluteepisode>\d{2,3}(\.\d{1,2})?(?!\d+|[-]))",
|
new Regex(@"^(?<title>.+?S\d{1,2})[-_. ]{3,}(?:EP)?(?<absoluteepisode>\d{2,3}(?!\d+|[-]))",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
// Anime - French titles with single episode numbers, with or without leading sub group ([RlsGroup] Title - Episode 1)
|
// Anime - French titles with single episode numbers, with or without leading sub group ([RlsGroup] Title - Episode 1)
|
||||||
new Regex(@"^(?:\[(?<subgroup>.+?)\][-_. ]?)?(?<title>.+?)[-_. ]+?(?:Episode[-_. ]+?)(?<absoluteepisode>\d{1}(\.\d{1,2})?(?!\d+))",
|
new Regex(@"^(?:\[(?<subgroup>.+?)\][-_. ]?)?(?<title>.+?)[-_. ]+?(?:Episode[-_. ]+?)(?<absoluteepisode>\d{1}(?!\d+))",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
//Season only releases
|
//Season only releases
|
||||||
@@ -231,19 +230,19 @@ namespace NzbDrone.Core.Parser
|
|||||||
|
|
||||||
// TODO: THIS ONE
|
// TODO: THIS ONE
|
||||||
//Anime - Title Absolute Episode Number (e66)
|
//Anime - Title Absolute Episode Number (e66)
|
||||||
new Regex(@"^(?:\[(?<subgroup>.+?)\][-_. ]?)?(?<title>.+?)(?:(?:_|-|\s|\.)+(?:e|ep)(?<absoluteepisode>\d{2,3}(\.\d{1,2})?))+.*?(?<hash>\[\w{8}\])?(?:$|\.)",
|
new Regex(@"^(?:\[(?<subgroup>.+?)\][-_. ]?)?(?<title>.+?)(?:(?:_|-|\s|\.)+(?:e|ep)(?<absoluteepisode>\d{2,3}))+.*?(?<hash>\[\w{8}\])?(?:$|\.)",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
//Anime - Title Episode Absolute Episode Number (Series Title Episode 01)
|
//Anime - Title Episode Absolute Episode Number (Series Title Episode 01)
|
||||||
new Regex(@"^(?<title>.+?)[-_. ](?:Episode)(?:[-_. ]+(?<absoluteepisode>(?<!\d+)\d{2,3}(\.\d{1,2})?(?!\d+)))+(?:_|-|\s|\.)*?(?<hash>\[.{8}\])?(?:$|\.)?",
|
new Regex(@"^(?<title>.+?)[-_. ](?:Episode)(?:[-_. ]+(?<absoluteepisode>(?<!\d+)\d{2,3}(?!\d+)))+(?:_|-|\s|\.)*?(?<hash>\[.{8}\])?(?:$|\.)?",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
//Anime - Title Absolute Episode Number
|
//Anime - Title Absolute Episode Number
|
||||||
new Regex(@"^(?:\[(?<subgroup>.+?)\][-_. ]?)?(?<title>.+?)(?:[-_. ]+(?<absoluteepisode>(?<!\d+)\d{2,3}(\.\d{1,2})?(?!\d+)))+(?:_|-|\s|\.)*?(?<hash>\[.{8}\])?(?:$|\.)?",
|
new Regex(@"^(?:\[(?<subgroup>.+?)\][-_. ]?)?(?<title>.+?)(?:[-_. ]+(?<absoluteepisode>(?<!\d+)\d{2,3}(?!\d+)))+(?:_|-|\s|\.)*?(?<hash>\[.{8}\])?(?:$|\.)?",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
//Anime - Title {Absolute Episode Number}
|
//Anime - Title {Absolute Episode Number}
|
||||||
new Regex(@"^(?:\[(?<subgroup>.+?)\][-_. ]?)?(?<title>.+?)(?:(?:[-_\W](?<![()\[!]))+(?<absoluteepisode>(?<!\d+)\d{2,3}(\.\d{1,2})?(?!\d+)))+(?:_|-|\s|\.)*?(?<hash>\[.{8}\])?(?:$|\.)?",
|
new Regex(@"^(?:\[(?<subgroup>.+?)\][-_. ]?)?(?<title>.+?)(?:(?:[-_\W](?<![()\[!]))+(?<absoluteepisode>(?<!\d+)\d{2,3}(?!\d+)))+(?:_|-|\s|\.)*?(?<hash>\[.{8}\])?(?:$|\.)?",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
//Extant, terrible multi-episode naming (extant.10708.hdtv-lol.mp4)
|
//Extant, terrible multi-episode naming (extant.10708.hdtv-lol.mp4)
|
||||||
@@ -291,7 +290,7 @@ namespace NzbDrone.Core.Parser
|
|||||||
};
|
};
|
||||||
|
|
||||||
//Regex to detect whether the title was reversed.
|
//Regex to detect whether the title was reversed.
|
||||||
private static readonly Regex ReversedTitleRegex = new Regex(@"[-._ ](p027|p0801|\d{2,3}E\d{2}S)[-._ ]", RegexOptions.Compiled);
|
private static readonly Regex ReversedTitleRegex = new Regex(@"[-._ ](p027|p0801|\d{2}E\d{2}S)[-._ ]", RegexOptions.Compiled);
|
||||||
|
|
||||||
private static readonly Regex NormalizeRegex = new Regex(@"((?:\b|_)(?<!^)(a(?!$)|an|the|and|or|of)(?:\b|_))|\W|_",
|
private static readonly Regex NormalizeRegex = new Regex(@"((?:\b|_)(?<!^)(a(?!$)|an|the|and|or|of)(?:\b|_))|\W|_",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||||
@@ -299,7 +298,7 @@ namespace NzbDrone.Core.Parser
|
|||||||
private static readonly Regex FileExtensionRegex = new Regex(@"\.[a-z0-9]{2,4}$",
|
private static readonly Regex FileExtensionRegex = new Regex(@"\.[a-z0-9]{2,4}$",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||||
|
|
||||||
private static readonly Regex SimpleTitleRegex = new Regex(@"(?:(480|720|1080|2160)[ip]|[xh][\W_]?26[45]|DD\W?5\W1|[<>?*:|]|848x480|1280x720|1920x1080|3840x2160|4096x2160|(8|10)b(it)?|10-bit)\s*?",
|
private static readonly Regex SimpleTitleRegex = new Regex(@"(?:(480|720|1080|2160)[ip]|[xh][\W_]?26[45]|DD\W?5\W1|[<>?*:|]|848x480|1280x720|1920x1080|3840x2160|4096x2160|(8|10)b(it)?)\s*?",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||||
|
|
||||||
private static readonly Regex WebsitePrefixRegex = new Regex(@"^\[\s*[a-z]+(\.[a-z]+)+\s*\][- ]*|^www\.[a-z]+\.(?:com|net)[ -]*",
|
private static readonly Regex WebsitePrefixRegex = new Regex(@"^\[\s*[a-z]+(\.[a-z]+)+\s*\][- ]*|^www\.[a-z]+\.(?:com|net)[ -]*",
|
||||||
@@ -654,32 +653,21 @@ namespace NzbDrone.Core.Parser
|
|||||||
|
|
||||||
if (absoluteEpisodeCaptures.Any())
|
if (absoluteEpisodeCaptures.Any())
|
||||||
{
|
{
|
||||||
var first = Convert.ToDecimal(absoluteEpisodeCaptures.First().Value, CultureInfo.InvariantCulture);
|
var first = Convert.ToInt32(absoluteEpisodeCaptures.First().Value);
|
||||||
var last = Convert.ToDecimal(absoluteEpisodeCaptures.Last().Value, CultureInfo.InvariantCulture);
|
var last = Convert.ToInt32(absoluteEpisodeCaptures.Last().Value);
|
||||||
|
|
||||||
if (first > last)
|
if (first > last)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((first % 1) != 0 || (last % 1) != 0)
|
var count = last - first + 1;
|
||||||
{
|
result.AbsoluteEpisodeNumbers = Enumerable.Range(first, count).ToArray();
|
||||||
if (absoluteEpisodeCaptures.Count != 1)
|
|
||||||
return null; // Multiple matches not allowed for specials
|
|
||||||
|
|
||||||
result.SpecialAbsoluteEpisodeNumbers = new decimal[] { first };
|
if (matchGroup.Groups["special"].Success)
|
||||||
|
{
|
||||||
result.Special = true;
|
result.Special = true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
var count = last - first + 1;
|
|
||||||
result.AbsoluteEpisodeNumbers = Enumerable.Range((int)first, (int)count).ToArray();
|
|
||||||
|
|
||||||
if (matchGroup.Groups["special"].Success)
|
|
||||||
{
|
|
||||||
result.Special = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!episodeCaptures.Any() && !absoluteEpisodeCaptures.Any())
|
if (!episodeCaptures.Any() && !absoluteEpisodeCaptures.Any())
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
using NzbDrone.Core.ThingiProvider.Events;
|
using NzbDrone.Core.ThingiProvider.Events;
|
||||||
|
|
||||||
@@ -25,18 +24,15 @@ namespace NzbDrone.Core.ThingiProvider.Status
|
|||||||
|
|
||||||
protected readonly IProviderStatusRepository<TModel> _providerStatusRepository;
|
protected readonly IProviderStatusRepository<TModel> _providerStatusRepository;
|
||||||
protected readonly IEventAggregator _eventAggregator;
|
protected readonly IEventAggregator _eventAggregator;
|
||||||
protected readonly IRuntimeInfo _runtimeInfo;
|
|
||||||
protected readonly Logger _logger;
|
protected readonly Logger _logger;
|
||||||
|
|
||||||
protected int MaximumEscalationLevel { get; set; } = EscalationBackOff.Periods.Length - 1;
|
protected int MaximumEscalationLevel { get; set; } = EscalationBackOff.Periods.Length - 1;
|
||||||
protected TimeSpan MinimumTimeSinceInitialFailure { get; set; } = TimeSpan.Zero;
|
protected TimeSpan MinimumTimeSinceInitialFailure { get; set; } = TimeSpan.Zero;
|
||||||
protected TimeSpan MinimumTimeSinceStartup { get; set; } = TimeSpan.FromMinutes(15);
|
|
||||||
|
|
||||||
public ProviderStatusServiceBase(IProviderStatusRepository<TModel> providerStatusRepository, IEventAggregator eventAggregator, IRuntimeInfo runtimeInfo, Logger logger)
|
public ProviderStatusServiceBase(IProviderStatusRepository<TModel> providerStatusRepository, IEventAggregator eventAggregator, Logger logger)
|
||||||
{
|
{
|
||||||
_providerStatusRepository = providerStatusRepository;
|
_providerStatusRepository = providerStatusRepository;
|
||||||
_eventAggregator = eventAggregator;
|
_eventAggregator = eventAggregator;
|
||||||
_runtimeInfo = runtimeInfo;
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,10 +89,9 @@ namespace NzbDrone.Core.ThingiProvider.Status
|
|||||||
escalate = false;
|
escalate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var inStartupGracePeriod = (_runtimeInfo.StartTime + MinimumTimeSinceStartup) > now;
|
|
||||||
var inGracePeriod = (status.InitialFailure.Value + MinimumTimeSinceInitialFailure) > now;
|
var inGracePeriod = (status.InitialFailure.Value + MinimumTimeSinceInitialFailure) > now;
|
||||||
|
|
||||||
if (escalate && !inGracePeriod && !inStartupGracePeriod)
|
if (escalate && !inGracePeriod)
|
||||||
{
|
{
|
||||||
status.EscalationLevel = Math.Min(MaximumEscalationLevel, status.EscalationLevel + 1);
|
status.EscalationLevel = Math.Min(MaximumEscalationLevel, status.EscalationLevel + 1);
|
||||||
}
|
}
|
||||||
@@ -114,15 +109,6 @@ namespace NzbDrone.Core.ThingiProvider.Status
|
|||||||
status.DisabledTill = now + CalculateBackOffPeriod(status);
|
status.DisabledTill = now + CalculateBackOffPeriod(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inStartupGracePeriod && minimumBackOff == TimeSpan.Zero && status.DisabledTill.HasValue)
|
|
||||||
{
|
|
||||||
var maximumDisabledTill = now + TimeSpan.FromSeconds(EscalationBackOff.Periods[1]);
|
|
||||||
if (maximumDisabledTill < status.DisabledTill)
|
|
||||||
{
|
|
||||||
status.DisabledTill = maximumDisabledTill;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_providerStatusRepository.Upsert(status);
|
_providerStatusRepository.Upsert(status);
|
||||||
|
|
||||||
_eventAggregator.PublishEvent(new ProviderStatusChangedEvent<TProvider>(providerId, status));
|
_eventAggregator.PublishEvent(new ProviderStatusChangedEvent<TProvider>(providerId, status));
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Marr.Data;
|
using Marr.Data;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
@@ -32,7 +32,6 @@ namespace NzbDrone.Core.Tv
|
|||||||
public bool UnverifiedSceneNumbering { get; set; }
|
public bool UnverifiedSceneNumbering { get; set; }
|
||||||
public Ratings Ratings { get; set; }
|
public Ratings Ratings { get; set; }
|
||||||
public List<MediaCover.MediaCover> Images { get; set; }
|
public List<MediaCover.MediaCover> Images { get; set; }
|
||||||
public DateTime? LastSearchTime { get; set; }
|
|
||||||
|
|
||||||
public string SeriesTitle { get; private set; }
|
public string SeriesTitle { get; private set; }
|
||||||
|
|
||||||
@@ -47,4 +46,4 @@ namespace NzbDrone.Core.Tv
|
|||||||
return string.Format("[{0}]{1}", Id, Title.NullSafe());
|
return string.Format("[{0}]{1}", Id, Title.NullSafe());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user