1
0
mirror of https://github.com/Radarr/Radarr.git synced 2026-03-27 17:54:34 -04:00

Compare commits

..

26 Commits

Author SHA1 Message Date
Leonardo Galli
f9049566c1 Fixed: No Physical Release Date causing exception when setting last write time.
Fixes #390
2018-02-06 16:51:19 +01:00
Leonardo Galli
0bc61bea38 Fixed: Movies not getting unmonitored when folder gets deleted.
Fixes #1191, Fixes #1590
2018-02-03 16:44:35 +01:00
Leonardo Galli
032fc68892 Added: Include total space with root folders
Closes #2468
2018-02-02 23:13:26 +01:00
Leonardo Galli
33cc228ac1 Fixed: Rare case of null quality causing issues with manual import.
Fixes #2227
2018-02-02 15:01:02 +01:00
Leonardo Galli
d5832a6a07 Added: Manual Import now adds year after movie title for filtering. This should help finding movies such as IT.
By searching e.g. It 2017, movies with short titles should be easily filterable now. Also displays more results (50 instead of 20)
2018-02-02 14:53:03 +01:00
Leonardo Galli
5f8aeeac17 Fixed: Manual Import not automatically choosing right movie.
Fixes #2458, Fixes #2061
Generally improved Manual Import UI
2018-02-02 14:51:18 +01:00
Leonardo Galli
54e57bf16a Merge remote-tracking branch 'origin/develop' into develop 2018-02-02 13:23:36 +01:00
Leonardo Galli
b1f76082b2 Added: Dynamic paths cleanup old folders now!
Old folder is now only left behind if extra files are also present in new dir and cannot be overwritten. Generally Dynamic Paths should be more stable now. Fixes #2048
2018-02-02 13:23:29 +01:00
Leonardo Galli
73fed04228 Fixed: Rare case of RequiredIndexerFlags failing with old Newznab indexers. 2018-02-01 16:00:55 +01:00
Leonardo Galli
ca3d5c184e Merge branch 'develop' of https://github.com/Radarr/Radarr into develop 2018-02-01 14:20:01 +01:00
Leonardo Galli
861962d06c Added: Option to require indexer flags per indexer. (e.g. only download freeleech torrents from a private tracker) (#2460) 2018-02-01 14:18:52 +01:00
Leonardo Galli
5057fcc40f Fixed: Folder name getting messed up when adding movies via a list.
Fixes #2465
2018-02-01 14:14:45 +01:00
Leonardo Galli
78e5fdf3bc Added: Files downloaded with different quality than grabbed will get rejected.
Fixes #1779, Fixes #2087, Fixes #1321
2018-01-31 20:09:04 +01:00
Leonardo Galli
aab14d02f9 Fixed: Error when adding an already excluded movie to the exclusion list.
Fixes #2462
2018-01-31 15:03:29 +01:00
Leonardo Galli
eb1c3c8b82 Fixed: Last commit still not compiling (whoops squared) 2018-01-30 18:33:30 +01:00
Leonardo Galli
4025af7895 Fixed: Last commit not compiling (whoops) 2018-01-30 18:31:07 +01:00
Leonardo Galli
95ca863697 Fixed: Clean Library being to agressive when lists are having failures.
Fixes #2455
2018-01-30 18:29:07 +01:00
Leonardo Galli
74e0db2829 @cosmetic Fixed all erroring tests. 2018-01-30 15:09:19 +01:00
Leonardo Galli
2459ddb6f4 Fixed: Error when nno quality was associated with a movie file.
Fixes #1991
2018-01-30 13:16:06 +01:00
Leonardo Galli
3e2e085b6b Fixed: Allowing in use Profiles to be Deleted.
Fixes #2030
2018-01-30 13:11:16 +01:00
Leonardo Galli
931cdacf66 Fixed: Error when Movie has no imdbid when searching Rargb
Fixes #2090
2018-01-30 12:59:45 +01:00
Leonardo Galli
18c622de40 Fixed: Rargb failing when imdbid is not found
Fixes #1845, Fixes #2319
2018-01-30 12:56:14 +01:00
Leonardo Galli
53e6fa7cf1 Fixed: {Original Filename} not allowed in Movie Filename
Fixes #1248
2018-01-30 12:42:06 +01:00
Qstick
4afd3f3bfe Fixed: Look for changes to package.json before using old build cache (#2445) 2018-01-26 08:54:59 +01:00
crhammock
da425b04b1 Updated: TMDbSettings.cs to allow pipe for or for genre ids (#2389) 2018-01-11 17:06:26 +01:00
Pieter Janssens
663ac972cd Fixed: HistoryDetailsLayoutTemplate.hbs (#2361) 2017-12-21 13:42:02 +01:00
71 changed files with 4050 additions and 358 deletions

View File

@@ -32,7 +32,7 @@ artifacts:
cache:
- '%USERPROFILE%\.nuget\packages'
- node_modules
- node_modules -> package.json
pull_requests:
do_not_increment_build_number: true

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ContentModelUserStore">
<explicitIncludes />
<explicitExcludes />
</component>
</project>

View File

@@ -1,103 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="RIDER_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$/../../../Logo/1024.png">
<sourceFolder url="file://$MODULE_DIR$/../../../Logo/1024.png" isTestSource="false" />
</content>
<content url="file://$MODULE_DIR$/../../../Logo/64.png">
<sourceFolder url="file://$MODULE_DIR$/../../../Logo/64.png" isTestSource="false" />
</content>
<content url="file://$MODULE_DIR$/../..">
<sourceFolder url="file://$MODULE_DIR$/../../.nuget/NuGet.exe" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../Common/CommonAssemblyInfo.cs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../Common/CommonVersionInfo.cs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../Common/GlobalSuppressions.cs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../ExternalModules/CurlSharp/CurlSharp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../Libraries/MediaInfo/libmediainfo.0.dylib" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../Libraries/MediaInfo/MediaInfo.dll" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../Libraries/Sqlite/libsqlite3.0.dylib" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../Libraries/Sqlite/sqlite3.dll" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../LogentriesCore" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../LogentriesNLog" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../Marr.Data" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../Microsoft.AspNet.SignalR.Core" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../Microsoft.AspNet.SignalR.Owin" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../MonoTorrent" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../NzbDrone" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../NzbDrone.Api" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../NzbDrone.Api.Test" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../NzbDrone.App.Test" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../NzbDrone.Automation.Test" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../NzbDrone.Common" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../NzbDrone.Common.Test" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../NzbDrone.Console" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../NzbDrone.Core" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../NzbDrone.Core.Test" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../NzbDrone.Host" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../NzbDrone.Integration.Test" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../NzbDrone.Libraries.Test" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../NzbDrone.Mono" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../NzbDrone.Mono.Test" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../NzbDrone.SignalR" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../NzbDrone.Test.Common" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../NzbDrone.Test.Dummy" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../NzbDrone.Update" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../NzbDrone.Update.Test" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../NzbDrone.Windows" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../NzbDrone.Windows.Test" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../ServiceHelpers/ServiceInstall" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../ServiceHelpers/ServiceUninstall" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/../../ExternalModules/CurlSharp/CurlSharp/bin" />
<excludeFolder url="file://$MODULE_DIR$/../../ExternalModules/CurlSharp/CurlSharp/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../LogentriesCore/bin" />
<excludeFolder url="file://$MODULE_DIR$/../../LogentriesCore/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../LogentriesNLog/bin" />
<excludeFolder url="file://$MODULE_DIR$/../../LogentriesNLog/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../Marr.Data/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../Microsoft.AspNet.SignalR.Core/bin" />
<excludeFolder url="file://$MODULE_DIR$/../../Microsoft.AspNet.SignalR.Core/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../Microsoft.AspNet.SignalR.Owin/bin" />
<excludeFolder url="file://$MODULE_DIR$/../../Microsoft.AspNet.SignalR.Owin/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../MonoTorrent/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Api.Test/bin" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Api.Test/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Api/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.App.Test/bin" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.App.Test/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Automation.Test/bin" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Automation.Test/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Common.Test/bin" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Common.Test/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Common/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Console/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Core.Test/bin" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Core.Test/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Core/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Host/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Integration.Test/bin" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Integration.Test/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Libraries.Test/bin" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Libraries.Test/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Mono.Test/bin" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Mono.Test/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Mono/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.SignalR/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Test.Common/bin" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Test.Common/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Test.Dummy/bin" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Test.Dummy/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Update.Test/bin" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Update.Test/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Update/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Windows.Test/bin" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Windows.Test/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone.Windows/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../NzbDrone/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../ServiceHelpers/ServiceInstall/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../ServiceHelpers/ServiceUninstall/obj" />
<excludeFolder url="file://$MODULE_DIR$/../../_ReSharper.Caches/ReSharperHost8.NzbDrone.00" />
<excludeFolder url="file://$MODULE_DIR$/../../packages" />
</content>
<content url="file://$MODULE_DIR$/../../../Logo/1024.png" />
<content url="file://$MODULE_DIR$/../../../Logo/64.png" />
<content url="file://$MODULE_DIR$/../.." />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -41,6 +41,16 @@ namespace NzbDrone.Api.ClientSchema
};
var value = propertyInfo.GetValue(model, null);
if (propertyInfo.PropertyType.HasAttribute<FlagsAttribute>())
{
int intVal = (int)value;
value = Enum.GetValues(propertyInfo.PropertyType)
.Cast<int>()
.Where(f=> (f & intVal) == f)
.ToList();
}
if (value != null)
{
field.Value = value;
@@ -131,6 +141,12 @@ namespace NzbDrone.Api.ClientSchema
propertyInfo.SetValue(target, value, null);
}
else if (propertyInfo.PropertyType.HasAttribute<FlagsAttribute>())
{
int value = field.Value.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(s => Convert.ToInt32(s)).Sum();
propertyInfo.SetValue(target, value, null);
}
else
{

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Api.Episodes;
using NzbDrone.Api.Movie;
using NzbDrone.Api.REST;
using NzbDrone.Api.Series;
using NzbDrone.Common.Crypto;
@@ -16,8 +17,9 @@ namespace NzbDrone.Api.ManualImport
public string Name { get; set; }
public long Size { get; set; }
public SeriesResource Series { get; set; }
public MovieResource Movie { get; set; }
public int? SeasonNumber { get; set; }
public List<EpisodeResource> Episodes { get; set; }
public List<Episodes.EpisodeResource> Episodes { get; set; }
public QualityModel Quality { get; set; }
public int QualityWeight { get; set; }
public string DownloadId { get; set; }
@@ -39,6 +41,7 @@ namespace NzbDrone.Api.ManualImport
Name = model.Name,
Size = model.Size,
Series = model.Series.ToResource(),
Movie = model.Movie.ToResource(),
SeasonNumber = model.SeasonNumber,
Episodes = model.Episodes.ToResource(),
Quality = model.Quality,

View File

@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Api.REST;
using NzbDrone.Core.RootFolders;
@@ -9,6 +9,7 @@ namespace NzbDrone.Api.RootFolders
{
public string Path { get; set; }
public long? FreeSpace { get; set; }
public long? TotalSpace { get; set; }
public List<UnmappedFolder> UnmappedFolders { get; set; }
}
@@ -25,6 +26,7 @@ namespace NzbDrone.Api.RootFolders
Path = model.Path,
FreeSpace = model.FreeSpace,
TotalSpace = model.TotalSpace,
UnmappedFolders = model.UnmappedFolders
};
}
@@ -48,4 +50,4 @@ namespace NzbDrone.Api.RootFolders
return models.Select(ToResource).ToList();
}
}
}
}

View File

@@ -245,6 +245,25 @@ namespace NzbDrone.Common.Disk
File.Move(source, destination);
}
public void MoveFolder(string source, string destination, bool overwrite = false)
{
Ensure.That(source, () => source).IsValidPath();
Ensure.That(destination, () => destination).IsValidPath();
if (source.PathEquals(destination))
{
throw new IOException(string.Format("Source and destination can't be the same {0}", source));
}
if (FolderExists(destination) && overwrite)
{
DeleteFolder(destination, true);
}
RemoveReadOnlyFolder(source);
Directory.Move(source, destination);
}
public abstract bool TryCreateHardLink(string source, string destination);
public void DeleteFolder(string path, bool recursive)
@@ -371,6 +390,20 @@ namespace NzbDrone.Common.Disk
}
}
private static void RemoveReadOnlyFolder(string path)
{
if (Directory.Exists(path))
{
var dirInfo = new DirectoryInfo(path);
if (dirInfo.Attributes.HasFlag(FileAttributes.ReadOnly))
{
var newAttributes = dirInfo.Attributes & ~(FileAttributes.ReadOnly);
dirInfo.Attributes = newAttributes;
}
}
}
public FileAttributes GetFileAttributes(string path)
{
return File.GetAttributes(path);

View File

@@ -30,6 +30,7 @@ namespace NzbDrone.Common.Disk
void DeleteFile(string path);
void CopyFile(string source, string destination, bool overwrite = false);
void MoveFile(string source, string destination, bool overwrite = false);
void MoveFolder(string source, string destination, bool overwrite = false);
bool TryCreateHardLink(string source, string destination);
void DeleteFolder(string path, bool recursive);
string ReadAllText(string filePath);

View File

@@ -340,7 +340,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetTests
result.IsLocalhost.Should().BeTrue();
result.OutputRootFolders.Should().NotBeNull();
result.OutputRootFolders.First().Should().Be(@"/remote/mount/tv");
result.OutputRootFolders.First().Should().Be(@"/remote/mount/movie");
}
[Test]

View File

@@ -544,7 +544,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests
public void should_test_failed_if_tv_sorting_contains_category()
{
_config.Misc.enable_tv_sorting = true;
_config.Misc.tv_categories = new[] { "tv" };
_config.Misc.tv_categories = new[] { "movie" };
var result = new NzbDroneValidationResult(Subject.Test());

View File

@@ -328,7 +328,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.UTorrentTests
result.IsLocalhost.Should().BeTrue();
result.OutputRootFolders.Should().NotBeNull();
result.OutputRootFolders.First().Should().Be(@"C:\Downloads\Finished\utorrent\tv".AsOsAgnostic());
result.OutputRootFolders.First().Should().Be(@"C:\Downloads\Finished\utorrent\movie".AsOsAgnostic());
}
[Test]

View File

@@ -47,7 +47,7 @@ namespace NzbDrone.Core.Test.MediaCoverTests
Subject.ConvertToLocalUrls(12, covers);
covers.Single().Url.Should().Be("/MediaCover/12/banner.jpg?lastWrite=1234");
covers.Single().Url.Should().Be("/MediaCover/12/banner.jpg");
}
[Test]

View File

@@ -14,6 +14,7 @@ using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv;
using NzbDrone.Test.Common;
using FluentAssertions;
using NzbDrone.Core.Download;
namespace NzbDrone.Core.Test.MediaFiles
{
@@ -77,7 +78,7 @@ namespace NzbDrone.Core.Test.MediaFiles
Subject.ProcessRootFolder(new DirectoryInfo(_droneFactory));
Mocker.GetMock<IMakeImportDecision>()
.Verify(c => c.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), It.IsAny<ParsedMovieInfo>(), It.IsAny<bool>()),
.Verify(c => c.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>(), It.IsAny<ParsedMovieInfo>(), It.IsAny<bool>()),
Times.Never());
VerifyNoImport();
@@ -128,7 +129,7 @@ namespace NzbDrone.Core.Test.MediaFiles
imported.Add(new ImportDecision(localMovie));
Mocker.GetMock<IMakeImportDecision>()
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), null, true))
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>(), null, true))
.Returns(imported);
Mocker.GetMock<IImportApprovedMovie>()
@@ -154,7 +155,7 @@ namespace NzbDrone.Core.Test.MediaFiles
imported.Add(new ImportDecision(localMovie));
Mocker.GetMock<IMakeImportDecision>()
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), null, true))
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>(), null, true))
.Returns(imported);
Mocker.GetMock<IImportApprovedMovie>()
@@ -226,7 +227,7 @@ namespace NzbDrone.Core.Test.MediaFiles
imported.Add(new ImportDecision(localMovie));
Mocker.GetMock<IMakeImportDecision>()
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), null, true))
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>(), null, true))
.Returns(imported);
Mocker.GetMock<IImportApprovedMovie>()
@@ -280,7 +281,7 @@ namespace NzbDrone.Core.Test.MediaFiles
Subject.ProcessPath(fileName);
Mocker.GetMock<IMakeImportDecision>()
.Verify(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), It.IsAny<ParsedMovieInfo>(), true, false), Times.Once());
.Verify(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>(), It.IsAny<ParsedMovieInfo>(), true, false), Times.Once());
}
[Test]
@@ -304,7 +305,7 @@ namespace NzbDrone.Core.Test.MediaFiles
var result = Subject.ProcessPath(fileName);
Mocker.GetMock<IMakeImportDecision>()
.Verify(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), null, true, false), Times.Once());
.Verify(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>(), null, true, false), Times.Once());
}
[Test]
@@ -337,7 +338,7 @@ namespace NzbDrone.Core.Test.MediaFiles
imported.Add(new ImportDecision(localMovie));
Mocker.GetMock<IMakeImportDecision>()
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), null, true))
.Setup(s => s.GetImportDecisions(It.IsAny<List<string>>(), It.IsAny<Movie>(), It.IsAny<DownloadClientItem>(), null, true))
.Returns(imported);
Mocker.GetMock<IImportApprovedEpisodes>()

View File

@@ -38,8 +38,8 @@ namespace NzbDrone.Core.Test.NetImport
var result = Subject.Fetch();
result.First().Title.Should().Be("Think Like a Man Too");
result.First().ImdbId.Should().Be("tt2239832");
result.Movies.First().Title.Should().Be("Think Like a Man Too");
result.Movies.First().ImdbId.Should().Be("tt2239832");
}
}
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using Marr.Data;
using Marr.Data.Mapping;
@@ -87,7 +87,11 @@ namespace NzbDrone.Core.Datastore
RegisterMappers();
Mapper.Entity<Config>().RegisterModel("Config");
Mapper.Entity<RootFolder>().RegisterModel("RootFolders").Ignore(r => r.FreeSpace);
Mapper.Entity<RootFolder>().RegisterModel("RootFolders")
.Ignore(r => r.FreeSpace)
.Ignore(r => r.TotalSpace);
Mapper.Entity<ScheduledTask>().RegisterModel("ScheduledTasks");
Mapper.Entity<IndexerDefinition>().RegisterDefinition("Indexers")

View File

@@ -0,0 +1,110 @@
using System.Linq;
using NLog;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.DecisionEngine.Specifications.Search
{
public class RequiredIndexerFlagsSpecification : IDecisionEngineSpecification
{
private readonly IIndexerFactory _indexerFactory;
private readonly Logger _logger;
public RequiredIndexerFlagsSpecification(IIndexerFactory indexerFactory, Logger logger)
{
_indexerFactory = indexerFactory;
_logger = logger;
}
//public SpecificationPriority Priority => SpecificationPriority.Default;
public RejectionType Type => RejectionType.Permanent;
public Decision IsSatisfiedBy(RemoteEpisode remoteEpisode, SearchCriteriaBase searchCriteria)
{
var torrentInfo = remoteEpisode.Release as TorrentInfo;
if (torrentInfo == null || torrentInfo.IndexerId == 0)
{
return Decision.Accept();
}
IndexerDefinition indexer;
try
{
indexer = _indexerFactory.Get(torrentInfo.IndexerId);
}
catch (ModelNotFoundException)
{
_logger.Debug("Indexer with id {0} does not exist, skipping seeders check", torrentInfo.IndexerId);
return Decision.Accept();
}
var torrentIndexerSettings = indexer.Settings as ITorrentIndexerSettings;
if (torrentIndexerSettings != null)
{
var minimumSeeders = torrentIndexerSettings.MinimumSeeders;
if (torrentInfo.Seeders.HasValue && torrentInfo.Seeders.Value < minimumSeeders)
{
_logger.Debug("Not enough seeders: {0}. Minimum seeders: {1}", torrentInfo.Seeders, minimumSeeders);
return Decision.Reject("Not enough seeders: {0}. Minimum seeders: {1}", torrentInfo.Seeders, minimumSeeders);
}
}
return Decision.Accept();
}
public Decision IsSatisfiedBy(RemoteMovie remoteEpisode, SearchCriteriaBase searchCriteria)
{
var torrentInfo = remoteEpisode.Release;
if (torrentInfo == null || torrentInfo.IndexerId == 0)
{
return Decision.Accept();
}
IndexerDefinition indexer;
try
{
indexer = _indexerFactory.Get(torrentInfo.IndexerId);
}
catch (ModelNotFoundException)
{
_logger.Debug("Indexer with id {0} does not exist, skipping seeders check", torrentInfo.IndexerId);
return Decision.Accept();
}
var torrentIndexerSettings = indexer.Settings as ITorrentIndexerSettings;
if (torrentIndexerSettings != null)
{
var requiredFlags = torrentIndexerSettings.RequiredFlags;
var requiredFlag = (IndexerFlags) 0;
if (requiredFlags == null || requiredFlags.Count() == 0)
{
return Decision.Accept();
}
foreach (var flag in requiredFlags)
{
if (torrentInfo.IndexerFlags.HasFlag((IndexerFlags)flag))
{
return Decision.Accept();
}
requiredFlag |= (IndexerFlags)flag;
}
_logger.Debug("None of the required indexer flags {0} where found. Found flags: {1}", requiredFlag, torrentInfo.IndexerFlags);
return Decision.Reject("None of the required indexer flags {0} where found. Found flags: {1}", requiredFlag, torrentInfo.IndexerFlags);
}
return Decision.Accept();
}
}
}

View File

@@ -27,19 +27,13 @@ namespace NzbDrone.Core.Indexers.AwesomeHD
private IEnumerable<IndexerRequest> GetRequest(string searchParameters)
{
var onlyInternal = "";
if (Settings.Internal)
{
onlyInternal = "&internal=true";
}
if (searchParameters != null)
{
yield return new IndexerRequest($"{Settings.BaseUrl.Trim().TrimEnd('/')}/searchapi.php?action=imdbsearch&passkey={Settings.Passkey.Trim()}&imdb={searchParameters}", HttpAccept.Rss);
}
else
{
yield return new IndexerRequest($"{Settings.BaseUrl.Trim().TrimEnd('/')}/searchapi.php?action=latestmovies&passkey={Settings.Passkey.Trim()}{onlyInternal}", HttpAccept.Rss);
yield return new IndexerRequest($"{Settings.BaseUrl.Trim().TrimEnd('/')}/searchapi.php?action=latestmovies&passkey={Settings.Passkey.Trim()}", HttpAccept.Rss);
}
}

View File

@@ -1,5 +1,7 @@
using FluentValidation;
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
@@ -30,11 +32,11 @@ namespace NzbDrone.Core.Indexers.AwesomeHD
[FieldDefinition(1, Label = "Passkey")]
public string Passkey { get; set; }
[FieldDefinition(2, Type = FieldType.Checkbox, Label = "Require Internal", HelpText = "Will only include internal releases for RSS Sync.")]
public bool Internal { get; set; }
[FieldDefinition(3, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
[FieldDefinition(2, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
[FieldDefinition(3, Type = FieldType.Tag, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
public NzbDroneValidationResult Validate()
{

View File

@@ -82,15 +82,6 @@ namespace NzbDrone.Core.Indexers.HDBits
});
}
// order by internal
if (_settings.PreferInternal)
{
return
torrentInfos.OrderByDescending(o => o.PublishDate)
.ThenBy(o => ((dynamic)o).Internal ? 0 : 1)
.ToArray();
}
return torrentInfos.ToArray();
}

View File

@@ -63,12 +63,6 @@ namespace NzbDrone.Core.Indexers.HDBits
query.Codec = Settings.Codecs.ToArray();
query.Medium = Settings.Mediums.ToArray();
// Require Internal only if came from RSS sync
if (Settings.RequireInternal && query.ImdbInfo == null)
{
query.Origin = 1;
}
request.SetContent(query.ToJson());
yield return new IndexerRequest(request);

View File

@@ -6,6 +6,7 @@ using NzbDrone.Core.Validation;
using System.Linq.Expressions;
using FluentValidation.Results;
using System.Collections.Generic;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Indexers.HDBits
{
@@ -41,23 +42,20 @@ namespace NzbDrone.Core.Indexers.HDBits
[FieldDefinition(2, Label = "API URL", Advanced = true, HelpText = "Do not change this unless you know what you're doing. Since your API key will be sent to that host.")]
public string BaseUrl { get; set; }
[FieldDefinition(3, Label = "Prefer Internal", Type = FieldType.Checkbox, HelpText = "Favors Internal releases over all other releases.")]
public bool PreferInternal { get; set; }
[FieldDefinition(4, Label = "Require Internal", Type = FieldType.Checkbox, HelpText = "Require Internal releases for release to be accepted.")]
public bool RequireInternal { get; set; }
[FieldDefinition(5, Label = "Categories", Type = FieldType.Tag, SelectOptions = typeof(HdBitsCategory), Advanced = true, HelpText = "Options: Movie, TV, Documentary, Music, Sport, Audio, XXX, MiscDemo. If unspecified, all options are used.")]
[FieldDefinition(3, Label = "Categories", Type = FieldType.Tag, SelectOptions = typeof(HdBitsCategory), Advanced = true, HelpText = "Options: Movie, TV, Documentary, Music, Sport, Audio, XXX, MiscDemo. If unspecified, all options are used.")]
public IEnumerable<int> Categories { get; set; }
[FieldDefinition(6, Label = "Codecs", Type = FieldType.Tag, SelectOptions = typeof(HdBitsCodec), Advanced = true, HelpText = "Options: h264, Mpeg2, VC1, Xvid. If unspecified, all options are used.")]
[FieldDefinition(4, Label = "Codecs", Type = FieldType.Tag, SelectOptions = typeof(HdBitsCodec), Advanced = true, HelpText = "Options: h264, Mpeg2, VC1, Xvid. If unspecified, all options are used.")]
public IEnumerable<int> Codecs { get; set; }
[FieldDefinition(7, Label = "Mediums", Type = FieldType.Tag, SelectOptions = typeof(HdBitsMedium), Advanced = true, HelpText = "Options: BluRay, Encode, Capture, Remux, WebDL. If unspecified, all options are used.")]
[FieldDefinition(5, Label = "Mediums", Type = FieldType.Tag, SelectOptions = typeof(HdBitsMedium), Advanced = true, HelpText = "Options: BluRay, Encode, Capture, Remux, WebDL. If unspecified, all options are used.")]
public IEnumerable<int> Mediums { get; set; }
[FieldDefinition(8, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
[FieldDefinition(6, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
[FieldDefinition(7, Type = FieldType.Tag, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
public NzbDroneValidationResult Validate()
{

View File

@@ -1,7 +1,9 @@
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
@@ -36,6 +38,9 @@ namespace NzbDrone.Core.Indexers.IPTorrents
[FieldDefinition(1, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
[FieldDefinition(2, Type = FieldType.Tag, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
public NzbDroneValidationResult Validate()
{

View File

@@ -1,7 +1,10 @@
namespace NzbDrone.Core.Indexers
using System.Collections.Generic;
namespace NzbDrone.Core.Indexers
{
public interface ITorrentIndexerSettings : IIndexerSettings
{
int MinimumSeeders { get; set; }
IEnumerable<int> RequiredFlags { get; set; }
}
}

View File

@@ -1,7 +1,10 @@
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation;
using System.Text.RegularExpressions;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Indexers.Nyaa
{
public class NyaaSettingsValidator : AbstractValidator<NyaaSettings>
@@ -32,6 +35,9 @@ namespace NzbDrone.Core.Indexers.Nyaa
[FieldDefinition(2, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
[FieldDefinition(3, Type = FieldType.Tag, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
public NzbDroneValidationResult Validate()
{

View File

@@ -73,8 +73,7 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
}
// Only add approved torrents
if (_settings.RequireApproved && torrent.Checked)
{
torrentInfos.Add(new PassThePopcornInfo()
{
Guid = string.Format("PassThePopcorn-{0}", id),
@@ -91,67 +90,10 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
ImdbId = (result.ImdbId.IsNotNullOrWhiteSpace() ? int.Parse(result.ImdbId) : 0),
IndexerFlags = flags
});
}
// Add all torrents
else if (!_settings.RequireApproved)
{
torrentInfos.Add(new PassThePopcornInfo()
{
Guid = string.Format("PassThePopcorn-{0}", id),
Title = title,
Size = long.Parse(torrent.Size),
DownloadUrl = GetDownloadUrl(id, jsonResponse.AuthKey, jsonResponse.PassKey),
InfoUrl = GetInfoUrl(result.GroupId, id),
Seeders = int.Parse(torrent.Seeders),
Peers = int.Parse(torrent.Leechers) + int.Parse(torrent.Seeders),
PublishDate = torrent.UploadTime.ToUniversalTime(),
Golden = torrent.GoldenPopcorn,
Scene = torrent.Scene,
Approved = torrent.Checked,
ImdbId = (result.ImdbId.IsNotNullOrWhiteSpace() ? int.Parse(result.ImdbId) : 0),
IndexerFlags = flags
});
}
// Don't add any torrents
else if (_settings.RequireApproved && !torrent.Checked)
{
continue;
}
}
}
// prefer golden
if (_settings.Golden)
{
if (_settings.Scene)
{
return
torrentInfos.OrderByDescending(o => o.PublishDate)
.ThenBy(o => ((dynamic)o).Golden ? 0 : 1)
.ThenBy(o => ((dynamic)o).Scene ? 0 : 1)
.ToArray();
}
return
torrentInfos.OrderByDescending(o => o.PublishDate)
.ThenBy(o => ((dynamic)o).Golden ? 0 : 1)
.ToArray();
}
// prefer scene
if (_settings.Scene)
{
return
torrentInfos.OrderByDescending(o => o.PublishDate)
.ThenBy(o => ((dynamic)o).Scene ? 0 : 1)
.ToArray();
}
// order by date
return
torrentInfos
.OrderByDescending(o => o.PublishDate)
.ToArray();
torrentInfos;
}

View File

@@ -40,10 +40,8 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
var filter = "";
if (searchParameters == null)
{
if (Settings.RequireGolden)
{
filter = "&scene=2";
}
}
var request =

View File

@@ -1,8 +1,10 @@
using FluentValidation;
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
using System.Text.RegularExpressions;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Indexers.PassThePopcorn
{
@@ -39,20 +41,11 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
[FieldDefinition(3, Label = "Passkey", HelpText = "PTP Passkey")]
public string Passkey { get; set; }
[FieldDefinition(4, Label = "Prefer Golden", Type = FieldType.Checkbox , HelpText = "Favors Golden Popcorn-releases over all other releases.")]
public bool Golden { get; set; }
[FieldDefinition(5, Label = "Prefer Scene", Type = FieldType.Checkbox, HelpText = "Favors scene-releases over non-scene releases.")]
public bool Scene { get; set; }
[FieldDefinition(6, Label = "Require Approved", Type = FieldType.Checkbox, HelpText = "Require staff-approval for releases to be accepted.")]
public bool RequireApproved { get; set; }
[FieldDefinition(7, Label = "Require Golden", Type = FieldType.Checkbox, HelpText = "Require Golden Popcorn-releases for releases to be accepted.")]
public bool RequireGolden { get; set; }
[FieldDefinition(8, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
[FieldDefinition(4, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
[FieldDefinition(5, Type = FieldType.Tag, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
public NzbDroneValidationResult Validate()
{

View File

@@ -29,9 +29,10 @@ namespace NzbDrone.Core.Indexers.Rarbg
if (jsonResponse.Resource.error_code.HasValue)
{
if (jsonResponse.Resource.error_code == 20 || jsonResponse.Resource.error_code == 8)
if (jsonResponse.Resource.error_code == 20 || jsonResponse.Resource.error_code == 8
|| jsonResponse.Resource.error_code == 9 || jsonResponse.Resource.error_code == 10)
{
// No results found
// No results or imdbid not found
return results;
}

View File

@@ -82,7 +82,15 @@ namespace NzbDrone.Core.Indexers.Rarbg
requestBuilder.AddQueryParam("mode", "search");
requestBuilder.AddQueryParam("search_imdb", searchCriteria.Movie.ImdbId);
if (searchCriteria.Movie.ImdbId != null)
{
requestBuilder.AddQueryParam("search_imdb", searchCriteria.Movie.ImdbId);
}
else
{
requestBuilder.AddQueryParam("search_string", $"{searchCriteria.Movie.Title} {searchCriteria.Movie.Year}");
}
if (!Settings.RankedOnly)
{

View File

@@ -1,5 +1,7 @@
using FluentValidation;
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers.Rarbg
@@ -34,6 +36,9 @@ namespace NzbDrone.Core.Indexers.Rarbg
[FieldDefinition(3, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
[FieldDefinition(4, Type = FieldType.Tag, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
public NzbDroneValidationResult Validate()
{

View File

@@ -1,5 +1,7 @@
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
@@ -34,6 +36,9 @@ namespace NzbDrone.Core.Indexers.TorrentPotato
[FieldDefinition(3, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
[FieldDefinition(4, Type = FieldType.Tag, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
public NzbDroneValidationResult Validate()
{

View File

@@ -1,5 +1,7 @@
using FluentValidation;
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers.TorrentRss
@@ -34,6 +36,9 @@ namespace NzbDrone.Core.Indexers.TorrentRss
[FieldDefinition(3, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
[FieldDefinition(4, Type = FieldType.Tag, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
public NzbDroneValidationResult Validate()
{

View File

@@ -1,10 +1,12 @@
using System.Linq;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using FluentValidation;
using FluentValidation.Results;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Indexers.Newznab;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers.Torznab
@@ -58,6 +60,9 @@ namespace NzbDrone.Core.Indexers.Torznab
[FieldDefinition(7, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
[FieldDefinition(8, Type = FieldType.Tag, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
public override NzbDroneValidationResult Validate()
{

View File

@@ -161,15 +161,9 @@ namespace NzbDrone.Core.MediaFiles
if (!_diskProvider.FolderExists(movie.Path))
{
if (_configService.CreateEmptySeriesFolders &&
_diskProvider.FolderExists(rootFolder))
{
_logger.Debug("Creating missing movies folder: {0}", movie.Path);
_diskProvider.CreateFolder(movie.Path);
SetPermissions(movie.Path);
}
else
if (movie.MovieFileId != 0)
{
//Since there is no folder, there can't be any files right?
// Delete Movie from MovieFiles
_movieFileRepository.Delete(movie.MovieFileId);
@@ -179,6 +173,13 @@ namespace NzbDrone.Core.MediaFiles
_logger.Debug("Movies folder doesn't exist: {0}", movie.Path);
}
else if (_configService.CreateEmptySeriesFolders &&
_diskProvider.FolderExists(rootFolder))
{
_logger.Debug("Creating missing movies folder: {0}", movie.Path);
_diskProvider.CreateFolder(movie.Path);
SetPermissions(movie.Path);
}
_eventAggregator.PublishEvent(new MovieScanSkippedEvent(movie, MovieScanSkippedReason.MovieFolderDoesNotExist));
return;

View File

@@ -187,7 +187,7 @@ namespace NzbDrone.Core.MediaFiles
}
}
var decisions = _importDecisionMaker.GetImportDecisions(videoFiles.ToList(), movie, folderInfo, true, false);
var decisions = _importDecisionMaker.GetImportDecisions(videoFiles.ToList(), movie, null, folderInfo, true, false);
var importResults = _importApprovedMovie.Import(decisions, true, downloadClientItem, importMode);
if ((downloadClientItem == null || !downloadClientItem.IsReadOnly) &&
@@ -241,7 +241,7 @@ namespace NzbDrone.Core.MediaFiles
}
}
var decisions = _importDecisionMaker.GetImportDecisions(new List<string>() { fileInfo.FullName }, movie, null, true, false);
var decisions = _importDecisionMaker.GetImportDecisions(new List<string>() { fileInfo.FullName }, movie, null, null, true, false);
return _importApprovedMovie.Import(decisions, true, downloadClientItem, importMode);
}

View File

@@ -1,4 +1,5 @@
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.MediaFiles.EpisodeImport
@@ -7,6 +8,6 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
{
Decision IsSatisfiedBy(LocalEpisode localEpisode);
Decision IsSatisfiedBy(LocalMovie localMovie);
Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem);
}
}

View File

@@ -49,13 +49,16 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
{
_logger.Debug("Decisions: {0}", decisions.Count);
//I added a null op for the rare case that the quality is null. TODO: find out why that would even happen in the first place.
var qualifiedImports = decisions.Where(c => c.Approved)
.GroupBy(c => c.LocalMovie.Movie.Id, (i, s) => s
.OrderByDescending(c => c.LocalMovie.Quality, new QualityModelComparer(s.First().LocalMovie.Movie.Profile))
.OrderByDescending(c => c.LocalMovie.Quality ?? new QualityModel{Quality = Quality.Unknown}, new QualityModelComparer(s.First().LocalMovie.Movie.Profile))
.ThenByDescending(c => c.LocalMovie.Size))
.SelectMany(c => c)
.ToList();
var importResults = new List<ImportResult>();
foreach (var importDecision in qualifiedImports.OrderBy(e => e.LocalMovie.Size)

View File

@@ -6,6 +6,7 @@ using NLog;
using NzbDrone.Common.Disk;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities;
@@ -20,8 +21,8 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
List<ImportDecision> GetImportDecisions(List<string> videoFiles, Series series);
List<ImportDecision> GetImportDecisions(List<string> videoFiles, Movie movie);
List<ImportDecision> GetImportDecisions(List<string> videoFiles, Movie movie, bool shouldCheckQuality);
List<ImportDecision> GetImportDecisions(List<string> videoFiles, Movie movie, ParsedMovieInfo folderInfo, bool sceneSource, bool shouldCheckQuality);
List<ImportDecision> GetImportDecisions(List<string> videoFiles, Movie movie, ParsedMovieInfo folderInfo, bool sceneSource);
List<ImportDecision> GetImportDecisions(List<string> videoFiles, Movie movie, DownloadClientItem downloadClientItem, ParsedMovieInfo folderInfo, bool sceneSource, bool shouldCheckQuality);
List<ImportDecision> GetImportDecisions(List<string> videoFiles, Movie movie, DownloadClientItem downloadClientItem, ParsedMovieInfo folderInfo, bool sceneSource);
List<ImportDecision> GetImportDecisions(List<string> videoFiles, Series series, ParsedEpisodeInfo folderInfo, bool sceneSource);
}
@@ -62,12 +63,12 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
public List<ImportDecision> GetImportDecisions(List<string> videoFiles, Movie movie)
{
return GetImportDecisions(videoFiles, movie, null, true, false);
return GetImportDecisions(videoFiles, movie, null, null, true, false);
}
public List<ImportDecision> GetImportDecisions(List<string> videoFiles, Movie movie, bool shouldCheckQuality = false)
{
return GetImportDecisions(videoFiles, movie, null, true, shouldCheckQuality);
return GetImportDecisions(videoFiles, movie, null, null, true, shouldCheckQuality);
}
public List<ImportDecision> GetImportDecisions(List<string> videoFiles, Series series, ParsedEpisodeInfo folderInfo, bool sceneSource)
@@ -87,7 +88,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
return decisions;
}
public List<ImportDecision> GetImportDecisions(List<string> videoFiles, Movie movie, ParsedMovieInfo folderInfo, bool sceneSource)
public List<ImportDecision> GetImportDecisions(List<string> videoFiles, Movie movie, DownloadClientItem downloadClientItem, ParsedMovieInfo folderInfo, bool sceneSource)
{
var newFiles = _mediaFileService.FilterExistingFiles(videoFiles.ToList(), movie);
@@ -98,13 +99,13 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
foreach (var file in newFiles)
{
decisions.AddIfNotNull(GetDecision(file, movie, folderInfo, sceneSource, shouldUseFolderName));
decisions.AddIfNotNull(GetDecision(file, movie, downloadClientItem, folderInfo, sceneSource, shouldUseFolderName));
}
return decisions;
}
public List<ImportDecision> GetImportDecisions(List<string> videoFiles, Movie movie, ParsedMovieInfo folderInfo, bool sceneSource, bool shouldCheckQuality = false)
public List<ImportDecision> GetImportDecisions(List<string> videoFiles, Movie movie, DownloadClientItem downloadClientItem, ParsedMovieInfo folderInfo, bool sceneSource, bool shouldCheckQuality)
{
var newFiles = _mediaFileService.FilterExistingFiles(videoFiles.ToList(), movie);
@@ -115,13 +116,13 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
foreach (var file in newFiles)
{
decisions.AddIfNotNull(GetDecision(file, movie, folderInfo, sceneSource, shouldUseFolderName, shouldCheckQuality));
decisions.AddIfNotNull(GetDecision(file, movie, downloadClientItem, folderInfo, sceneSource, shouldUseFolderName, shouldCheckQuality));
}
return decisions;
}
private ImportDecision GetDecision(string file, Movie movie, ParsedMovieInfo folderInfo, bool sceneSource, bool shouldUseFolderName, bool shouldCheckQuality = false)
private ImportDecision GetDecision(string file, Movie movie, DownloadClientItem downloadClientItem, ParsedMovieInfo folderInfo, bool sceneSource, bool shouldUseFolderName, bool shouldCheckQuality = false)
{
ImportDecision decision = null;
@@ -283,11 +284,11 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
decision = GetDecision(localMovie);
decision = GetDecision(localMovie, downloadClientItem);
}
else
{
decision = GetDecision(localMovie);
decision = GetDecision(localMovie, downloadClientItem);
}
}
@@ -314,9 +315,9 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
return decision;
}
private ImportDecision GetDecision(LocalMovie localMovie)
private ImportDecision GetDecision(LocalMovie localMovie, DownloadClientItem downloadClientItem)
{
var reasons = _specifications.Select(c => EvaluateSpec(c, localMovie))
var reasons = _specifications.Select(c => EvaluateSpec(c, localMovie, downloadClientItem))
.Where(c => c != null);
return new ImportDecision(localMovie, reasons.ToArray());
@@ -385,11 +386,11 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
return new ImportDecision(localEpisode, reasons.ToArray());
}
private Rejection EvaluateSpec(IImportDecisionEngineSpecification spec, LocalMovie localMovie)
private Rejection EvaluateSpec(IImportDecisionEngineSpecification spec, LocalMovie localMovie, DownloadClientItem downloadClientItem)
{
try
{
var result = spec.IsSatisfiedBy(localMovie);
var result = spec.IsSatisfiedBy(localMovie, downloadClientItem);
if (!result.Accepted)
{

View File

@@ -104,13 +104,19 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
private List<ManualImportItem> ProcessFolder(string folder, string downloadId)
{
DownloadClientItem downloadClientItem = null;
var directoryInfo = new DirectoryInfo(folder);
var series = _parsingService.GetMovie(directoryInfo.Name);
if (series == null && downloadId.IsNotNullOrWhiteSpace())
if (downloadId.IsNotNullOrWhiteSpace())
{
var trackedDownload = _trackedDownloadService.Find(downloadId);
series = trackedDownload.RemoteMovie.Movie;
downloadClientItem = trackedDownload.DownloadItem;
if (series == null)
{
series = trackedDownload.RemoteMovie.Movie;
}
}
if (series == null)
@@ -122,7 +128,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
var folderInfo = Parser.Parser.ParseMovieTitle(directoryInfo.Name, _config.ParsingLeniency > 0);
var seriesFiles = _diskScanService.GetVideoFiles(folder).ToList();
var decisions = _importDecisionMaker.GetImportDecisions(seriesFiles, series, folderInfo, SceneSource(series, folder), false);
var decisions = _importDecisionMaker.GetImportDecisions(seriesFiles, series, downloadClientItem, folderInfo, SceneSource(series, folder), false);
return decisions.Select(decision => MapItem(decision, folder, downloadId)).ToList();
}
@@ -134,6 +140,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
folder = new FileInfo(file).Directory.FullName;
}
DownloadClientItem downloadClientItem = null;
var relativeFile = folder.GetRelativePath(file);
var movie = _parsingService.GetMovie(relativeFile.Split('\\', '/')[0]);
@@ -143,10 +150,15 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
movie = _parsingService.GetMovie(relativeFile);
}
if (movie == null && downloadId.IsNotNullOrWhiteSpace())
if (downloadId.IsNotNullOrWhiteSpace())
{
var trackedDownload = _trackedDownloadService.Find(downloadId);
movie = trackedDownload.RemoteMovie.Movie;
downloadClientItem = trackedDownload.DownloadItem;
if (movie == null)
{
movie = trackedDownload.RemoteMovie.Movie;
}
}
if (movie == null)
@@ -162,7 +174,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
}
var importDecisions = _importDecisionMaker.GetImportDecisions(new List<string> { file },
movie, null, SceneSource(movie, folder), true);
movie, downloadClientItem, null, SceneSource(movie, folder), true);
return importDecisions.Any() ? MapItem(importDecisions.First(), folder, downloadId) : new ManualImportItem
{

View File

@@ -4,6 +4,7 @@ using NLog;
using NzbDrone.Common.Disk;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
@@ -64,7 +65,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
return Decision.Accept();
}
public Decision IsSatisfiedBy(LocalMovie localMovie)
public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem)
{
if (_configService.SkipFreeSpaceCheckWhenImporting)
{

View File

@@ -1,5 +1,6 @@
using NLog;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
@@ -24,7 +25,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
return Decision.Accept();
}
public Decision IsSatisfiedBy(LocalMovie localMovie)
public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem)
{
return Decision.Accept();
}

View File

@@ -0,0 +1,73 @@
using System.Linq;
using NLog;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download;
using NzbDrone.Core.History;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities;
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
{
public class GrabbedReleaseQualitySpecification : IImportDecisionEngineSpecification
{
private readonly Logger _logger;
private readonly IHistoryService _historyService;
public GrabbedReleaseQualitySpecification(Logger logger, IHistoryService historyService)
{
_logger = logger;
_historyService = historyService;
}
public Decision IsSatisfiedBy(LocalEpisode localEpisode)
{
var qualityComparer = new QualityModelComparer(localEpisode.Series.Profile);
if (localEpisode.Episodes.Any(e => e.EpisodeFileId != 0 && qualityComparer.Compare(e.EpisodeFile.Value.Quality, localEpisode.Quality) > 0))
{
_logger.Debug("This file isn't an upgrade for all episodes. Skipping {0}", localEpisode.Path);
return Decision.Reject("Not an upgrade for existing episode file(s)");
}
return Decision.Accept();
}
public Decision IsSatisfiedBy(LocalMovie localEpisode, DownloadClientItem downloadClientItem)
{
if (downloadClientItem == null)
{
_logger.Debug("No download client item provided, skipping.");
return Decision.Accept();
}
var grabbedHistory = _historyService.FindByDownloadId(downloadClientItem.DownloadId)
.Where(h => h.EventType == HistoryEventType.Grabbed)
.ToList();
if (grabbedHistory.Empty())
{
_logger.Debug("No grabbed history for this download client item");
return Decision.Accept();
}
var parsedReleaseName = Parser.Parser.ParseTitle(grabbedHistory.First().SourceTitle);
if (parsedReleaseName != null && parsedReleaseName.FullSeason)
{
_logger.Debug("File is part of a season pack, skipping.");
return Decision.Accept();
}
foreach (var item in grabbedHistory)
{
if (item.Quality.Quality != Quality.Unknown && item.Quality != localEpisode.Quality)
{
_logger.Debug("Quality for grabbed release ({0}) does not match the quality of the file ({1})", item.Quality, localEpisode.Quality);
return Decision.Reject("File quality does not match quality of the grabbed release");
}
}
return Decision.Accept();
}
}
}

View File

@@ -3,6 +3,7 @@ using System.IO;
using System.Linq;
using NLog;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
@@ -16,7 +17,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
_logger = logger;
}
public Decision IsSatisfiedBy(LocalMovie localMovie)
public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem)
{
if (localMovie.ExistingFile)
{

View File

@@ -1,5 +1,6 @@
using NLog;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
@@ -38,7 +39,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
return Decision.Accept();
}
public Decision IsSatisfiedBy(LocalMovie localEpisode)
public Decision IsSatisfiedBy(LocalMovie localEpisode, DownloadClientItem downloadClientItem)
{
var sample = _detectSample.IsSample(localEpisode.Movie,
localEpisode.Quality,

View File

@@ -5,6 +5,7 @@ using NzbDrone.Common.Disk;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
@@ -57,7 +58,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
return Decision.Accept();
}
public Decision IsSatisfiedBy(LocalMovie localEpisode)
public Decision IsSatisfiedBy(LocalMovie localEpisode, DownloadClientItem downloadClientItem)
{
if (localEpisode.ExistingFile)
{

View File

@@ -1,6 +1,7 @@
using System;
using NLog;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
@@ -29,7 +30,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
return Decision.Reject("Episode file on disk contains more episodes than this file contains");
}
public Decision IsSatisfiedBy(LocalMovie localMovie)
public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem)
{
return Decision.Accept();
}

View File

@@ -2,6 +2,7 @@
using System.Linq;
using NLog;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
{
@@ -14,7 +15,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
_logger = logger;
}
public Decision IsSatisfiedBy(LocalMovie localMovie)
public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem)
{
return Decision.Accept();
}

View File

@@ -1,6 +1,7 @@
using System.Linq;
using NLog;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities;
@@ -27,7 +28,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
return Decision.Accept();
}
public Decision IsSatisfiedBy(LocalMovie localEpisode)
public Decision IsSatisfiedBy(LocalMovie localEpisode, DownloadClientItem downloadClientItem)
{
return Decision.Accept();
}

View File

@@ -66,7 +66,7 @@ namespace NzbDrone.Core.MediaFiles
EnsureMovieFolder(movieFile, movie, filePath);
_logger.Debug("Renaming movie file: {0} to {1}", movieFile, filePath);
return TransferFile(movieFile, movie, filePath, TransferMode.Move);
}
@@ -78,7 +78,7 @@ namespace NzbDrone.Core.MediaFiles
EnsureMovieFolder(movieFile, localMovie, filePath);
_logger.Debug("Moving movie file: {0} to {1}", movieFile.Path, filePath);
return TransferFile(movieFile, localMovie.Movie, filePath, TransferMode.Move);
}
@@ -98,7 +98,7 @@ namespace NzbDrone.Core.MediaFiles
_logger.Debug("Copying movie file: {0} to {1}", movieFile.Path, filePath);
return TransferFile(movieFile, localMovie.Movie, filePath, TransferMode.Copy);
}
private MovieFile TransferFile(MovieFile movieFile, Movie movie, string destinationFilePath, TransferMode mode)
{
Ensure.That(movieFile, () => movieFile).IsNotNull();
@@ -122,11 +122,8 @@ namespace NzbDrone.Core.MediaFiles
var oldMoviePath = movie.Path;
var newMoviePath = new OsPath(destinationFilePath).Directory.FullPath.TrimEnd(Path.DirectorySeparatorChar);
movie.Path = newMoviePath;
if (oldMoviePath != newMoviePath)
{
_movieService.UpdateMovie(movie);
}
movie.Path = newMoviePath; //We update it when everything went well!
movieFile.RelativePath = movie.Path.GetRelativePath(destinationFilePath);
@@ -146,12 +143,35 @@ namespace NzbDrone.Core.MediaFiles
if(oldMoviePath != newMoviePath)
{
//Let's move the old files before deleting the old folder. We could just do move folder, but the main file (movie file) is already moved, so eh.
var files = _diskProvider.GetFiles(oldMoviePath, SearchOption.AllDirectories);
foreach (var file in files)
{
try
{
var destFile = Path.Combine(newMoviePath, oldMoviePath.GetRelativePath(file));
_diskProvider.EnsureFolder(Path.GetDirectoryName(destFile));
_diskProvider.MoveFile(file, destFile);
}
catch (Exception e)
{
_logger.Warn(e, "Error while trying to move extra file {0} to new folder. Maybe it already exists? (Manual cleanup necessary!).", oldMoviePath.GetRelativePath(file));
}
}
if (_diskProvider.GetFiles(oldMoviePath, SearchOption.AllDirectories).Count() == 0)
{
_recycleBinProvider.DeleteFolder(oldMoviePath);
}
}
//Only update the movie path if we were successfull!
if (oldMoviePath != newMoviePath)
{
_movieService.UpdateMovie(movie);
}
return movieFile;
}
@@ -163,7 +183,7 @@ namespace NzbDrone.Core.MediaFiles
private void EnsureMovieFolder(MovieFile movieFile, Movie movie, string filePath)
{
var movieFolder = Path.GetDirectoryName(filePath);
movie.Path = movieFolder;
//movie.Path = movieFolder;
var rootFolder = new OsPath(movieFolder).Directory.FullPath;
var fileName = Path.GetFileName(filePath);

View File

@@ -38,7 +38,7 @@ namespace NzbDrone.Core.MediaFiles
private readonly IDiskProvider _diskProvider;
private readonly IRecycleBinProvider _recycleBinProvider;
private readonly Logger _logger;
public RenameMovieFileService(IMovieService movieService,
IMediaFileService mediaFileService,
IMoveMovieFiles movieFileMover,
@@ -91,7 +91,7 @@ namespace NzbDrone.Core.MediaFiles
}
}
}
private void RenameFiles(List<MovieFile> movieFiles, Movie movie, string oldMoviePath = null)
@@ -136,23 +136,25 @@ namespace NzbDrone.Core.MediaFiles
var newFolder = _filenameBuilder.BuildMoviePath(movie);
if (newFolder != movie.Path && movie.PathState == MoviePathState.Dynamic)
{
if (!_configService.AutoRenameFolders)
{
_logger.Info("{0}'s movie should be {1} according to your naming config.", movie, newFolder);
return;
}
_logger.Info("{0}'s movie folder changed to: {1}", movie, newFolder);
var oldFolder = movie.Path;
movie.Path = newFolder;
if (shouldRenameFiles)
_diskProvider.MoveFolder(oldFolder, movie.Path);
if (false)
{
var movieFiles = _mediaFileService.GetFilesByMovie(movie.Id);
_logger.ProgressInfo("Renaming movie files for {0}", movie.Title);
RenameFiles(movieFiles, movie, oldFolder);
_logger.ProgressInfo("All movie files renamed for {0}", movie.Title);
_logger.ProgressInfo("All movie files renamed for {0}", movie.Title);
}
_movieService.UpdateMovie(movie);
@@ -162,7 +164,7 @@ namespace NzbDrone.Core.MediaFiles
_recycleBinProvider.DeleteFolder(oldFolder);
}
}
if (movie.PathState == MoviePathState.StaticOnce)
@@ -194,7 +196,7 @@ namespace NzbDrone.Core.MediaFiles
RenameFiles(movieFiles, movie);
_logger.ProgressInfo("All movie files renamed for {0}", movie.Title);
}
}
public void Execute(RenameMovieFolderCommand message)
@@ -206,7 +208,7 @@ namespace NzbDrone.Core.MediaFiles
foreach(var movie in moviesToRename)
{
var movieFiles = _mediaFileService.GetFilesByMovie(movie.Id);
_logger.ProgressInfo("Renaming movie folder for {0}", movie.Title);
//_logger.ProgressInfo("Renaming movie folder for {0}", movie.Title);
RenameMoviePath(movie);
}
}
@@ -214,7 +216,7 @@ namespace NzbDrone.Core.MediaFiles
{
_logger.Warn(ex, "wtf: {0}, {1}", ex.ResultCode, ex.Data);
}
}
}
}

View File

@@ -53,7 +53,7 @@ namespace NzbDrone.Core.MediaFiles
{
var airDate = movie.PhysicalRelease;
if (airDate == null)
if (airDate.HasValue == false)
{
return false;
}
@@ -65,7 +65,7 @@ namespace NzbDrone.Core.MediaFiles
{
var airDate = movie.InCinemas;
if (airDate == null)
if (airDate.HasValue == false)
{
return false;
}

View File

@@ -88,7 +88,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
public Movie GetMovieInfo(int TmdbId, Profile profile = null, bool hasPreDBEntry = false)
{
var langCode = profile != null ? IsoLanguages.Get(profile.Language).TwoLetterCode : "us";
var langCode = profile != null ? IsoLanguages.Get(profile.Language).TwoLetterCode : "en";
var request = _movieBuilder.Create()
.SetSegment("route", "movie")

View File

@@ -34,19 +34,21 @@ namespace NzbDrone.Core.NetImport
_httpClient = httpClient;
}
public override IList<Movie> Fetch()
public override NetImportFetchResult Fetch()
{
var generator = GetRequestGenerator();
return FetchMovies(generator.GetMovies());
}
protected virtual IList<Movie> FetchMovies(NetImportPageableRequestChain pageableRequestChain, bool isRecent = false)
protected virtual NetImportFetchResult FetchMovies(NetImportPageableRequestChain pageableRequestChain, bool isRecent = false)
{
var movies = new List<Movie>();
var url = string.Empty;
var parser = GetParser();
var anyFailure = false;
try
{
for (int i = 0; i < pageableRequestChain.Tiers; i++)
@@ -73,6 +75,7 @@ namespace NzbDrone.Core.NetImport
}
catch (WebException webException)
{
anyFailure = true;
if (webException.Message.Contains("502") || webException.Message.Contains("503") ||
webException.Message.Contains("timed out"))
{
@@ -85,6 +88,7 @@ namespace NzbDrone.Core.NetImport
}
catch (HttpException httpException)
{
anyFailure = true;
if ((int)httpException.Response.StatusCode == 429)
{
_logger.Warn("API Request Limit reached for {0}", this);
@@ -96,11 +100,12 @@ namespace NzbDrone.Core.NetImport
}
catch (Exception feedEx)
{
anyFailure = true;
feedEx.Data.Add("FeedUrl", url);
_logger.Error(feedEx, "An error occurred while processing feed. " + url);
}
return movies;
return new NetImportFetchResult {Movies = movies, AnyFailure = anyFailure};
}
protected virtual IList<Movie> FetchPage(NetImportRequest request, IParseNetImportResponse parser)

View File

@@ -9,6 +9,6 @@ namespace NzbDrone.Core.NetImport
bool Enabled { get; }
bool EnableAuto { get; }
IList<Movie> Fetch();
NetImportFetchResult Fetch();
}
}

View File

@@ -15,6 +15,7 @@ namespace NzbDrone.Core.NetImport.ImportExclusions
public interface IImportExclusionsRepository : IBasicRepository<ImportExclusion>
{
bool IsMovieExcluded(int tmdbid);
ImportExclusion GetByTmdbid(int tmdbid);
}
public class ImportExclusionsRepository : BasicRepository<ImportExclusion>, IImportExclusionsRepository
@@ -31,5 +32,10 @@ namespace NzbDrone.Core.NetImport.ImportExclusions
{
return Query.Where(ex => ex.TmdbId == tmdbid).Any();
}
public ImportExclusion GetByTmdbid(int tmdbid)
{
return Query.Where(ex => ex.TmdbId == tmdbid).First();
}
}
}

View File

@@ -47,6 +47,10 @@ namespace NzbDrone.Core.NetImport.ImportExclusions
public ImportExclusion AddExclusion(ImportExclusion exclusion)
{
if (_exclusionRepository.IsMovieExcluded(exclusion.TmdbId))
{
return _exclusionRepository.GetByTmdbid(exclusion.TmdbId);
}
return _exclusionRepository.Insert(exclusion);
}

View File

@@ -9,6 +9,12 @@ using NzbDrone.Core.Tv;
namespace NzbDrone.Core.NetImport
{
public class NetImportFetchResult
{
public IList<Movie> Movies { get; set; }
public bool AnyFailure { get; set; }
}
public abstract class NetImportBase<TSettings> : INetImport
where TSettings : IProviderConfig, new()
{
@@ -20,7 +26,7 @@ namespace NzbDrone.Core.NetImport
public abstract bool Enabled { get; }
public abstract bool EnableAuto { get; }
public abstract IList<Movie> Fetch();
public abstract NetImportFetchResult Fetch();
public NetImportBase(IConfigService configService, IParsingService parsingService, Logger logger)
{

View File

@@ -19,7 +19,7 @@ namespace NzbDrone.Core.NetImport
{
public interface IFetchNetImport
{
List<Movie> Fetch(int listId, bool onlyEnableAuto);
NetImportFetchResult Fetch(int listId, bool onlyEnableAuto);
List<Movie> FetchAndFilter(int listId, bool onlyEnableAuto);
}
@@ -54,21 +54,22 @@ namespace NzbDrone.Core.NetImport
}
public List<Movie> Fetch(int listId, bool onlyEnableAuto = false)
public NetImportFetchResult Fetch(int listId, bool onlyEnableAuto = false)
{
return MovieListSearch(listId, onlyEnableAuto);
}
public List<Movie> FetchAndFilter(int listId, bool onlyEnableAuto)
{
var movies = MovieListSearch(listId, onlyEnableAuto);
var movies = MovieListSearch(listId, onlyEnableAuto).Movies;
return _movieService.FilterExistingMovies(movies);
return _movieService.FilterExistingMovies(movies.ToList());
}
public List<Movie> MovieListSearch(int listId, bool onlyEnableAuto = false)
public NetImportFetchResult MovieListSearch(int listId, bool onlyEnableAuto = false)
{
var movies = new List<Movie>();
var anyFailure = false;
var importLists = _netImportFactory.GetAvailableProviders();
@@ -81,24 +82,31 @@ namespace NzbDrone.Core.NetImport
foreach (var list in lists)
{
movies.AddRange(list.Fetch());
var result = list.Fetch();
movies.AddRange(result.Movies);
anyFailure |= result.AnyFailure;
}
_logger.Debug("Found {0} movies from list(s) {1}", movies.Count, string.Join(", ", lists.Select(l => l.Definition.Name)));
return movies.DistinctBy(x => {
if (x.TmdbId != 0)
{
return x.TmdbId.ToString();
}
return new NetImportFetchResult
{
Movies = movies.DistinctBy(x =>
{
if (x.TmdbId != 0)
{
return x.TmdbId.ToString();
}
if (x.ImdbId.IsNotNullOrWhiteSpace())
{
return x.ImdbId;
}
if (x.ImdbId.IsNotNullOrWhiteSpace())
{
return x.ImdbId;
}
return x.Title;
}).ToList();
return x.Title;
}).ToList(),
AnyFailure = anyFailure
};
}
@@ -112,9 +120,13 @@ namespace NzbDrone.Core.NetImport
return;
}
var listedMovies = Fetch(0, true);
var result = Fetch(0, true);
var listedMovies = result.Movies.ToList();
CleanLibrary(listedMovies);
if (!result.AnyFailure)
{
CleanLibrary(listedMovies);
}
listedMovies = listedMovies.Where(x => !_movieService.MovieExists(x)).ToList();
if (listedMovies.Any())

View File

@@ -36,19 +36,19 @@ namespace NzbDrone.Core.NetImport.TMDb
RuleFor(c => c.Ceritification)
.Matches(@"^\bNR\b|\bG\b|\bPG\b|\bPG\-13\b|\bR\b|\bNC\-17\b$", RegexOptions.IgnoreCase)
.When(c => c.Ceritification.IsNotNullOrWhiteSpace())
.WithMessage("Not a valid cerification");
.WithMessage("Not a valid certification");
// CSV of numbers
RuleFor(c => c.IncludeGenreIds)
.Matches(@"^\d+([,]\d+)*$", RegexOptions.IgnoreCase)
.Matches(@"^\d+([,|]\d+)*$", RegexOptions.IgnoreCase)
.When(c => c.IncludeGenreIds.IsNotNullOrWhiteSpace())
.WithMessage("Genre Ids must be comma separated number ids");
.WithMessage("Genre Ids must be comma (,) or pipe (|) separated number ids");
// CSV of numbers
RuleFor(c => c.ExcludeGenreIds)
.Matches(@"^\d+([,]\d+)*$", RegexOptions.IgnoreCase)
.Matches(@"^\d+([,|]\d+)*$", RegexOptions.IgnoreCase)
.When(c => c.ExcludeGenreIds.IsNotNullOrWhiteSpace())
.WithMessage("Genre Ids must be comma separated number ids");
.WithMessage("Genre Ids must be comma (,) or pipe (|) separated number ids");
}
}
@@ -99,4 +99,4 @@ namespace NzbDrone.Core.NetImport.TMDb
}
}
}
}

View File

@@ -127,7 +127,9 @@
<Compile Include="Datastore\Migration\123_create_netimport_table.cs" />
<Compile Include="Datastore\Migration\140_add_alternative_titles_table.cs" />
<Compile Include="Datastore\Migration\141_fix_duplicate_alt_titles.cs" />
<Compile Include="DecisionEngine\Specifications\RequiredIndexerFlagsSpecification.cs" />
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedAlternativeTitles.cs" />
<Compile Include="MediaFiles\EpisodeImport\Specifications\GrabbedReleaseQualitySpecification.cs" />
<Compile Include="MediaFiles\Events\MovieFileUpdatedEvent.cs" />
<Compile Include="Datastore\Migration\134_add_remux_qualities_for_the_wankers.cs" />
<Compile Include="Datastore\Migration\129_add_parsed_movie_info_to_pending_release.cs" />
@@ -1392,4 +1394,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>

View File

@@ -62,7 +62,7 @@ namespace NzbDrone.Core.Organizer
public static readonly Regex SeriesTitleRegex = new Regex(@"(?<token>\{(?:Series)(?<separator>[- ._])(Clean)?Title\})",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
public static readonly Regex MovieTitleRegex = new Regex(@"(?<token>\{((?:(Movie|Original))(?<separator>[- ._])(Clean)?Title(The)?)\})",
public static readonly Regex MovieTitleRegex = new Regex(@"(?<token>\{((?:(Movie|Original))(?<separator>[- ._])(Clean)?(Title|Filename)(The)?)\})",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex FileNameCleanupRegex = new Regex(@"([- ._])(\1)+", RegexOptions.Compiled);
@@ -633,6 +633,15 @@ namespace NzbDrone.Core.Organizer
private void AddQualityTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, Movie movie, MovieFile movieFile)
{
if (movieFile?.Quality?.Quality == null)
{
tokenHandlers["{Quality Full}"] = m => "";
tokenHandlers["{Quality Title}"] = m => "";
tokenHandlers["{Quality Proper}"] = m => "";
tokenHandlers["{Quality Real}"] = m => "";
return;
}
var qualityTitle = _qualityDefinitionService.Get(movieFile.Quality.Quality).Title;
var qualityProper = GetQualityProper(movie, movieFile.Quality);
var qualityReal = GetQualityReal(movie, movieFile.Quality);

View File

@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using NzbDrone.Core.Datastore;
@@ -9,7 +9,8 @@ namespace NzbDrone.Core.RootFolders
public string Path { get; set; }
public long? FreeSpace { get; set; }
public long? TotalSpace { get; set; }
public List<UnmappedFolder> UnmappedFolders { get; set; }
}
}
}

View File

@@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using System;
using System.Collections.Generic;
using System.IO;
@@ -76,14 +76,15 @@ namespace NzbDrone.Core.RootFolders
if (folder.Path.IsPathValid() && _diskProvider.FolderExists(folder.Path))
{
folder.FreeSpace = _diskProvider.GetAvailableSpace(folder.Path);
folder.TotalSpace = _diskProvider.GetTotalSize(folder.Path);
folder.UnmappedFolders = GetUnmappedFolders(folder.Path);
}
}
//We don't want an exception to prevent the root folders from loading in the UI, so they can still be deleted
catch (Exception ex)
{
_logger.Error(ex, "Unable to get free space and unmapped folders for root folder: " + folder.Path);
folder.FreeSpace = 0;
_logger.Error(ex, "Unable to get free space and unmapped folders for root folder {0}", folder.Path);
folder.UnmappedFolders = new List<UnmappedFolder>();
}
});
@@ -211,8 +212,9 @@ namespace NzbDrone.Core.RootFolders
{
var rootFolder = _rootFolderRepository.Get(id);
rootFolder.FreeSpace = _diskProvider.GetAvailableSpace(rootFolder.Path);
rootFolder.TotalSpace = _diskProvider.GetTotalSize(rootFolder.Path);
rootFolder.UnmappedFolders = GetUnmappedFolders(rootFolder.Path);
return rootFolder;
}
}
}
}

View File

@@ -27,9 +27,13 @@
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/FORCE_WHILE_BRACES_STYLE/@EntryValue">ALWAYS_ADD</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_NESTED_FIXED_STMT/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_NESTED_USINGS_STMT/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSOR_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSORHOLDER_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_ACCESSOR_ATTRIBUTE_ON_SAME_LINE/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_ACCESSOR_ON_SINGLE_LINE/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_EMBEDDED_STATEMENT_ON_SAME_LINE/@EntryValue">ALWAYS</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SIMPLE_EMBEDDED_STATEMENT_STYLE/@EntryValue">ON_SINGLE_LINE</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/AllowAlias/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/CanUseGlobalAlias/@EntryValue">False</s:Boolean>
@@ -66,7 +70,12 @@
<s:Boolean x:Key="/Default/Environment/InjectedLayers/InjectedLayerCustomization/=File_003A_003AC_003A_005CDropbox_005CGit_005CNzbDrone_005CNzbDrone_002Esln_002EDotSettings/@KeyIndexDefined">True</s:Boolean>
<s:Double x:Key="/Default/Environment/InjectedLayers/InjectedLayerCustomization/=File_003A_003AC_003A_005CDropbox_005CGit_005CNzbDrone_005CNzbDrone_002Esln_002EDotSettings/RelativePriority/@EntryValue">2</s:Double>
<s:Boolean x:Key="/Default/Environment/MemoryUsageIndicator/IsVisible/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpRenamePlacementToArrangementMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/TextControl/HighlightCurrentLine/@EntryValue">True</s:Boolean>

View File

@@ -1,17 +1,17 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Debug - Chrome" type="JavascriptDebugType" factoryName="JavaScript Debug" singleton="true" engineId="98ca6316-2f89-46d9-a9e5-fa9e2b0625b3" uri="http://localhost:7878">
<mapping url="http://localhost:8989/Wanted" local-file="$PROJECT_DIR$/Wanted" />
<mapping url="http://localhost:8989/Config.js" local-file="$PROJECT_DIR$/Config.js" />
<mapping url="http://localhost:8989" local-file="$PROJECT_DIR$" />
<mapping url="http://localhost:8989/Wanted" local-file="$PROJECT_DIR$/Wanted" />
<mapping url="http://localhost:8989/app.js" local-file="$PROJECT_DIR$/app.js" />
<mapping url="http://localhost:8989/Mixins" local-file="$PROJECT_DIR$/Mixins" />
<mapping url="http://localhost:8989/Quality" local-file="$PROJECT_DIR$/Quality" />
<mapping url="http://localhost:8989/Shared" local-file="$PROJECT_DIR$/Shared" />
<mapping url="http://localhost:8989/Controller.js" local-file="$PROJECT_DIR$/Controller.js" />
<mapping url="http://localhost:8989/Calendar" local-file="$PROJECT_DIR$/Calendar" />
<mapping url="http://localhost:8989/Controller.js" local-file="$PROJECT_DIR$/Controller.js" />
<mapping url="http://localhost:8989/Series" local-file="$PROJECT_DIR$/Series" />
<mapping url="http://localhost:8989/AddSeries" local-file="$PROJECT_DIR$/AddSeries" />
<mapping url="http://localhost:8989/Settings" local-file="$PROJECT_DIR$/Settings" />
<mapping url="http://localhost:8989/Config.js" local-file="$PROJECT_DIR$/Config.js" />
<RunnerSettings RunnerId="JavascriptDebugRunner" />
<ConfigurationWrapper RunnerId="JavascriptDebugRunner" />
<method />

View File

@@ -6,8 +6,8 @@
<h3>
{{#if_eq eventType compare="grabbed"}}Grabbed{{/if_eq}}
{{#if_eq eventType compare="downloadFailed"}}Download Failed{{/if_eq}}
{{#if_eq eventType compare="downloadFolderImported"}}Episode Imported{{/if_eq}}
{{#if_eq eventType compare="episodeFileDeleted"}}Episode File Deleted{{/if_eq}}
{{#if_eq eventType compare="downloadFolderImported"}}Movie Imported{{/if_eq}}
{{#if_eq eventType compare="episodeFileDeleted"}}Movie File Deleted{{/if_eq}}
</h3>
</div>

View File

@@ -36,7 +36,7 @@ var Collection = PageableCollection.extend({
},
sortMappings : {
series : {
movie : {
sortValue : function(model, attr, order) {
var series = model.get(attr);
@@ -71,4 +71,4 @@ var Collection = PageableCollection.extend({
Collection = AsSortedCollection.call(Collection);
module.exports = Collection;
module.exports = Collection;

View File

@@ -22,9 +22,7 @@ module.exports = Backgrid.Row.extend({
},
_setError : function () {
if (this.model.has('series') &&
this.model.has('seasonNumber') &&
(this.model.has('episodes') && this.model.get('episodes').length > 0)&&
if (this.model.has('movie') &&
this.model.has('quality')) {
this.$el.removeClass('manual-import-error');
}
@@ -35,7 +33,7 @@ module.exports = Backgrid.Row.extend({
},
_setClasses : function () {
this.$el.toggleClass('has-series', this.model.has('series'));
this.$el.toggleClass('has-season', this.model.has('seasonNumber'));
this.$el.toggleClass('has-movie', this.model.has('movie'));
//this.$el.toggleClass('has-season', this.model.has('seasonNumber'));
}
});
});

View File

@@ -87,8 +87,8 @@ module.exports = Marionette.Layout.extend({
_filter : function (term) {
this.movieCollection.reset(this.fullMovieCollection.filter(function(model){
return model.get("title").toLowerCase().indexOf(term.toLowerCase()) != -1;
}).slice(0, 20));
return (model.get("title") + " "+model.get("year")+"").toLowerCase().indexOf(term.toLowerCase()) != -1;
}).slice(0, 50));
this._setModelCollection();
//this.movieView.render();

View File

@@ -7,7 +7,7 @@ var EditProfileItemView = require('./EditProfileItemView');
var QualitySortableCollectionView = require('./QualitySortableCollectionView');
var EditProfileView = require('./EditProfileView');
var DeleteView = require('../DeleteProfileView');
var SeriesCollection = require('../../../Series/SeriesCollection');
var FullMovieCollection = require('../../../Movies/FullMovieCollection');
var Config = require('../../../Config');
var AsEditModalView = require('../../../Mixins/AsEditModalView');
@@ -28,7 +28,7 @@ var view = Marionette.Layout.extend({
initialize : function(options) {
this.profileCollection = options.profileCollection;
this.itemsCollection = new Backbone.Collection(_.toArray(this.model.get('items')).reverse());
this.listenTo(SeriesCollection, 'all', this._updateDisableStatus);
this.listenTo(FullMovieCollection, 'all', this._updateDisableStatus);
},
onRender : function() {
@@ -104,14 +104,14 @@ var view = Marionette.Layout.extend({
_updateDisableStatus : function() {
if (this._isQualityInUse()) {
this.ui.deleteButton.addClass('disabled');
this.ui.deleteButton.attr('title', 'Can\'t delete a profile that is attached to a series.');
this.ui.deleteButton.attr('title', 'Can\'t delete a profile that is attached to a movie.');
} else {
this.ui.deleteButton.removeClass('disabled');
}
},
_isQualityInUse : function() {
return SeriesCollection.where({ 'profileId' : this.model.id }).length !== 0;
return FullMovieCollection.where({ 'profileId' : this.model.id }).length !== 0;
}
});
module.exports = AsEditModalView.call(view);