commit
2ecacecbfd
|
@ -0,0 +1,22 @@
|
||||||
|
# Auto detect text files and perform LF normalization
|
||||||
|
*text eol=lf
|
||||||
|
|
||||||
|
# Custom for Visual Studio
|
||||||
|
*.cs diff=csharp
|
||||||
|
*.sln merge=union
|
||||||
|
*.csproj merge=union
|
||||||
|
*.vbproj merge=union
|
||||||
|
*.fsproj merge=union
|
||||||
|
*.dbproj merge=union
|
||||||
|
|
||||||
|
# Standard to msysgit
|
||||||
|
*.doc diff=astextplain
|
||||||
|
*.DOC diff=astextplain
|
||||||
|
*.docx diff=astextplain
|
||||||
|
*.DOCX diff=astextplain
|
||||||
|
*.dot diff=astextplain
|
||||||
|
*.DOT diff=astextplain
|
||||||
|
*.pdf diff=astextplain
|
||||||
|
*.PDF diff=astextplain
|
||||||
|
*.rtf diff=astextplain
|
||||||
|
*.RTF diff=astextplain
|
20
Gruntfile.js
20
Gruntfile.js
|
@ -155,6 +155,25 @@ module.exports = function (grunt) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
requirejs: {
|
||||||
|
compile:{
|
||||||
|
options: {
|
||||||
|
mainConfigFile: "_output/UI/app.js",
|
||||||
|
fileExclusionRegExp: /^.*\.(?!js$)[^.]+$/,
|
||||||
|
preserveLicenseComments: true,
|
||||||
|
dir: "rjs/",
|
||||||
|
optimize: 'none',
|
||||||
|
removeCombined: true,
|
||||||
|
inlineText: false,
|
||||||
|
modules: [{
|
||||||
|
name: 'app',
|
||||||
|
exclude: ['JsLibraries/jquery']
|
||||||
|
}],
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
options: {
|
options: {
|
||||||
nospawn: false,
|
nospawn: false,
|
||||||
|
@ -213,6 +232,7 @@ module.exports = function (grunt) {
|
||||||
grunt.loadNpmTasks('grunt-contrib-clean');
|
grunt.loadNpmTasks('grunt-contrib-clean');
|
||||||
grunt.loadNpmTasks('grunt-notify');
|
grunt.loadNpmTasks('grunt-notify');
|
||||||
grunt.loadNpmTasks('grunt-curl');
|
grunt.loadNpmTasks('grunt-curl');
|
||||||
|
grunt.loadNpmTasks('grunt-contrib-requirejs');
|
||||||
|
|
||||||
grunt.registerTask('package', ['clean:output', 'copy', 'less', 'handlebars']);
|
grunt.registerTask('package', ['clean:output', 'copy', 'less', 'handlebars']);
|
||||||
grunt.registerTask('default', ['package', 'watch']);
|
grunt.registerTask('default', ['package', 'watch']);
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
"grunt-contrib-copy": "*",
|
"grunt-contrib-copy": "*",
|
||||||
"grunt-curl": "*",
|
"grunt-curl": "*",
|
||||||
"grunt-notify": "*",
|
"grunt-notify": "*",
|
||||||
"grunt-contrib-clean": "*"
|
"grunt-contrib-clean": "*",
|
||||||
|
"grunt-contrib-requirejs": "*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Core.DiskSpace;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.DiskSpace
|
||||||
|
{
|
||||||
|
public class DiskSpaceModule :NzbDroneRestModule<DiskSpaceResource>
|
||||||
|
{
|
||||||
|
private readonly IDiskSpaceService _diskSpaceService;
|
||||||
|
|
||||||
|
public DiskSpaceModule(IDiskSpaceService diskSpaceService)
|
||||||
|
:base("diskspace")
|
||||||
|
{
|
||||||
|
_diskSpaceService = diskSpaceService;
|
||||||
|
GetResourceAll = GetFreeSpace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DiskSpaceResource> GetFreeSpace()
|
||||||
|
{
|
||||||
|
return ToListResource(_diskSpaceService.GetFreeSpace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using NzbDrone.Api.REST;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.DiskSpace
|
||||||
|
{
|
||||||
|
public class DiskSpaceResource : RestResource
|
||||||
|
{
|
||||||
|
public string Path { get; set; }
|
||||||
|
public string Label { get; set; }
|
||||||
|
public Int64 FreeSpace { get; set; }
|
||||||
|
public Int64 TotalSpace { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,11 +2,17 @@
|
||||||
|
|
||||||
namespace NzbDrone.Api.Indexers
|
namespace NzbDrone.Api.Indexers
|
||||||
{
|
{
|
||||||
public class IndexerModule : ProviderModuleBase<ProviderResource, IIndexer, IndexerDefinition>
|
public class IndexerModule : ProviderModuleBase<IndexerResource, IIndexer, IndexerDefinition>
|
||||||
{
|
{
|
||||||
public IndexerModule(IndexerFactory indexerFactory)
|
public IndexerModule(IndexerFactory indexerFactory)
|
||||||
: base(indexerFactory, "indexer")
|
: base(indexerFactory, "indexer")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void Validate(IndexerDefinition definition)
|
||||||
|
{
|
||||||
|
if (!definition.Enable) return;
|
||||||
|
base.Validate(definition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,16 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using NzbDrone.Api.ClientSchema;
|
|
||||||
using NzbDrone.Api.REST;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Indexers
|
namespace NzbDrone.Api.Indexers
|
||||||
{
|
{
|
||||||
public class IndexerResource : RestResource
|
public class IndexerResource : ProviderResource
|
||||||
{
|
{
|
||||||
public Boolean Enable { get; set; }
|
public Boolean Enable { get; set; }
|
||||||
public String Name { get; set; }
|
|
||||||
public List<Field> Fields { get; set; }
|
|
||||||
public String Implementation { get; set; }
|
|
||||||
public String ConfigContract { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,10 +19,8 @@ namespace NzbDrone.Api.Indexers
|
||||||
|
|
||||||
private List<IndexerResource> GetSchema()
|
private List<IndexerResource> GetSchema()
|
||||||
{
|
{
|
||||||
|
|
||||||
var indexers = _indexerFactory.Templates().Where(c => c.Implementation =="Newznab");
|
var indexers = _indexerFactory.Templates().Where(c => c.Implementation =="Newznab");
|
||||||
|
|
||||||
|
|
||||||
var result = new List<IndexerResource>(indexers.Count());
|
var result = new List<IndexerResource>(indexers.Count());
|
||||||
|
|
||||||
foreach (var indexer in indexers)
|
foreach (var indexer in indexers)
|
||||||
|
|
|
@ -10,82 +10,17 @@ using Omu.ValueInjecter;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Notifications
|
namespace NzbDrone.Api.Notifications
|
||||||
{
|
{
|
||||||
public class NotificationModule : NzbDroneRestModule<NotificationResource>
|
public class IndexerModule : ProviderModuleBase<NotificationResource, INotification, NotificationDefinition>
|
||||||
{
|
{
|
||||||
private readonly INotificationService _notificationService;
|
public IndexerModule(NotificationFactory notificationrFactory)
|
||||||
|
: base(notificationrFactory, "notification")
|
||||||
public NotificationModule(INotificationService notificationService)
|
|
||||||
{
|
{
|
||||||
_notificationService = notificationService;
|
|
||||||
|
|
||||||
GetResourceAll = GetAll;
|
|
||||||
GetResourceById = GetNotification;
|
|
||||||
CreateResource = Create;
|
|
||||||
UpdateResource = Update;
|
|
||||||
DeleteResource = DeleteNotification;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private NotificationResource GetNotification(int id)
|
protected override void Validate(NotificationDefinition definition)
|
||||||
{
|
{
|
||||||
return _notificationService.Get(id).InjectTo<NotificationResource>();
|
if (!definition.OnGrab && !definition.OnDownload) return;
|
||||||
}
|
base.Validate(definition);
|
||||||
|
|
||||||
private List<NotificationResource> GetAll()
|
|
||||||
{
|
|
||||||
var notifications = _notificationService.All();
|
|
||||||
|
|
||||||
var result = new List<NotificationResource>(notifications.Count);
|
|
||||||
|
|
||||||
foreach (var notification in notifications)
|
|
||||||
{
|
|
||||||
var notificationResource = new NotificationResource();
|
|
||||||
notificationResource.InjectFrom(notification);
|
|
||||||
notificationResource.Fields = SchemaBuilder.ToSchema(notification.Settings);
|
|
||||||
notificationResource.TestCommand = String.Format("test{0}", notification.Implementation.ToLowerInvariant());
|
|
||||||
|
|
||||||
result.Add(notificationResource);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int Create(NotificationResource notificationResource)
|
|
||||||
{
|
|
||||||
var notification = ConvertToNotification(notificationResource);
|
|
||||||
return _notificationService.Create(notification).Id;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Update(NotificationResource notificationResource)
|
|
||||||
{
|
|
||||||
var notification = ConvertToNotification(notificationResource);
|
|
||||||
notification.Id = notificationResource.Id;
|
|
||||||
_notificationService.Update(notification);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DeleteNotification(int id)
|
|
||||||
{
|
|
||||||
_notificationService.Delete(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Notification ConvertToNotification(NotificationResource notificationResource)
|
|
||||||
{
|
|
||||||
var notification = _notificationService.Schema()
|
|
||||||
.SingleOrDefault(i =>
|
|
||||||
i.Implementation.Equals(notificationResource.Implementation,
|
|
||||||
StringComparison.InvariantCultureIgnoreCase));
|
|
||||||
|
|
||||||
if (notification == null)
|
|
||||||
{
|
|
||||||
throw new BadRequestException("Invalid Notification Implementation");
|
|
||||||
}
|
|
||||||
|
|
||||||
notification.InjectFrom(notificationResource);
|
|
||||||
|
|
||||||
//var configType = ReflectionExtensions.CoreAssembly.FindTypeByName(notification)
|
|
||||||
|
|
||||||
//notification.Settings = SchemaBuilder.ReadFormSchema(notification.Settings, notificationResource.Fields);
|
|
||||||
|
|
||||||
return notification;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,19 +1,12 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using NzbDrone.Api.ClientSchema;
|
|
||||||
using NzbDrone.Api.REST;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Notifications
|
namespace NzbDrone.Api.Notifications
|
||||||
{
|
{
|
||||||
public class NotificationResource : RestResource
|
public class NotificationResource : ProviderResource
|
||||||
{
|
{
|
||||||
public String Name { get; set; }
|
|
||||||
public String ImplementationName { get; set; }
|
|
||||||
public String Link { get; set; }
|
public String Link { get; set; }
|
||||||
public Boolean OnGrab { get; set; }
|
public Boolean OnGrab { get; set; }
|
||||||
public Boolean OnDownload { get; set; }
|
public Boolean OnDownload { get; set; }
|
||||||
public List<Field> Fields { get; set; }
|
|
||||||
public String Implementation { get; set; }
|
|
||||||
public String TestCommand { get; set; }
|
public String TestCommand { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,20 +7,19 @@ using Omu.ValueInjecter;
|
||||||
namespace NzbDrone.Api.Notifications
|
namespace NzbDrone.Api.Notifications
|
||||||
{
|
{
|
||||||
public class NotificationSchemaModule : NzbDroneRestModule<NotificationResource>
|
public class NotificationSchemaModule : NzbDroneRestModule<NotificationResource>
|
||||||
{
|
{
|
||||||
private readonly INotificationService _notificationService;
|
private readonly INotificationFactory _notificationFactory;
|
||||||
|
|
||||||
public NotificationSchemaModule(INotificationService notificationService)
|
public NotificationSchemaModule(INotificationFactory notificationFactory)
|
||||||
: base("notification/schema")
|
: base("notification/schema")
|
||||||
{
|
{
|
||||||
_notificationService = notificationService;
|
_notificationFactory = notificationFactory;
|
||||||
|
|
||||||
GetResourceAll = GetSchema;
|
GetResourceAll = GetSchema;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<NotificationResource> GetSchema()
|
private List<NotificationResource> GetSchema()
|
||||||
{
|
{
|
||||||
var notifications = _notificationService.Schema();
|
var notifications = _notificationFactory.Templates();
|
||||||
|
|
||||||
var result = new List<NotificationResource>(notifications.Count);
|
var result = new List<NotificationResource>(notifications.Count);
|
||||||
|
|
||||||
|
@ -29,7 +28,6 @@ namespace NzbDrone.Api.Notifications
|
||||||
var notificationResource = new NotificationResource();
|
var notificationResource = new NotificationResource();
|
||||||
notificationResource.InjectFrom(notification);
|
notificationResource.InjectFrom(notification);
|
||||||
notificationResource.Fields = SchemaBuilder.ToSchema(notification.Settings);
|
notificationResource.Fields = SchemaBuilder.ToSchema(notification.Settings);
|
||||||
notificationResource.TestCommand = String.Format("test{0}", notification.Implementation.ToLowerInvariant());
|
|
||||||
|
|
||||||
result.Add(notificationResource);
|
result.Add(notificationResource);
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,6 +87,8 @@
|
||||||
<Compile Include="Commands\CommandResource.cs" />
|
<Compile Include="Commands\CommandResource.cs" />
|
||||||
<Compile Include="Config\NamingConfigResource.cs" />
|
<Compile Include="Config\NamingConfigResource.cs" />
|
||||||
<Compile Include="Config\NamingModule.cs" />
|
<Compile Include="Config\NamingModule.cs" />
|
||||||
|
<Compile Include="DiskSpace\DiskSpaceModule.cs" />
|
||||||
|
<Compile Include="DiskSpace\DiskSpaceResource.cs" />
|
||||||
<Compile Include="EpisodeFiles\EpisodeFileModule.cs" />
|
<Compile Include="EpisodeFiles\EpisodeFileModule.cs" />
|
||||||
<Compile Include="EpisodeFiles\EpisodeFileResource.cs" />
|
<Compile Include="EpisodeFiles\EpisodeFileResource.cs" />
|
||||||
<Compile Include="Directories\DirectoryLookupService.cs" />
|
<Compile Include="Directories\DirectoryLookupService.cs" />
|
||||||
|
@ -109,7 +111,7 @@
|
||||||
<Compile Include="Frontend\StaticResourceModule.cs" />
|
<Compile Include="Frontend\StaticResourceModule.cs" />
|
||||||
<Compile Include="History\HistoryResource.cs" />
|
<Compile Include="History\HistoryResource.cs" />
|
||||||
<Compile Include="History\HistoryModule.cs" />
|
<Compile Include="History\HistoryModule.cs" />
|
||||||
<Compile Include="IndexerResource.cs" />
|
<Compile Include="ProviderResource.cs" />
|
||||||
<Compile Include="ProviderModuleBase.cs" />
|
<Compile Include="ProviderModuleBase.cs" />
|
||||||
<Compile Include="Indexers\IndexerSchemaModule.cs" />
|
<Compile Include="Indexers\IndexerSchemaModule.cs" />
|
||||||
<Compile Include="Indexers\IndexerModule.cs" />
|
<Compile Include="Indexers\IndexerModule.cs" />
|
||||||
|
|
|
@ -4,7 +4,6 @@ using FluentValidation;
|
||||||
using Nancy;
|
using Nancy;
|
||||||
using NzbDrone.Api.ClientSchema;
|
using NzbDrone.Api.ClientSchema;
|
||||||
using NzbDrone.Api.Extensions;
|
using NzbDrone.Api.Extensions;
|
||||||
using NzbDrone.Api.Indexers;
|
|
||||||
using NzbDrone.Api.Mapping;
|
using NzbDrone.Api.Mapping;
|
||||||
using NzbDrone.Common.Reflection;
|
using NzbDrone.Common.Reflection;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
@ -30,8 +29,6 @@ namespace NzbDrone.Api
|
||||||
UpdateResource = UpdateProvider;
|
UpdateResource = UpdateProvider;
|
||||||
DeleteResource = DeleteProvider;
|
DeleteResource = DeleteProvider;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SharedValidator.RuleFor(c => c.Name).NotEmpty();
|
SharedValidator.RuleFor(c => c.Name).NotEmpty();
|
||||||
SharedValidator.RuleFor(c => c.Implementation).NotEmpty();
|
SharedValidator.RuleFor(c => c.Implementation).NotEmpty();
|
||||||
SharedValidator.RuleFor(c => c.ConfigContract).NotEmpty();
|
SharedValidator.RuleFor(c => c.ConfigContract).NotEmpty();
|
||||||
|
@ -69,39 +66,25 @@ namespace NzbDrone.Api
|
||||||
return indexer.Id;
|
return indexer.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateProvider(TProviderResource indexerResource)
|
private void UpdateProvider(TProviderResource providerResource)
|
||||||
{
|
{
|
||||||
var indexer = GetDefinition(indexerResource);
|
var providerDefinition = GetDefinition(providerResource);
|
||||||
|
|
||||||
ValidateIndexer(indexer);
|
Validate(providerDefinition);
|
||||||
|
|
||||||
_providerFactory.Update(indexer);
|
_providerFactory.Update(providerDefinition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TProviderDefinition GetDefinition(TProviderResource providerResource)
|
||||||
private static void ValidateIndexer(ProviderDefinition definition)
|
|
||||||
{
|
{
|
||||||
if (!definition.Enable) return;
|
|
||||||
|
|
||||||
var validationResult = definition.Settings.Validate();
|
|
||||||
|
|
||||||
if (!validationResult.IsValid)
|
|
||||||
{
|
|
||||||
throw new ValidationException(validationResult.Errors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private TProviderDefinition GetDefinition(TProviderResource indexerResource)
|
|
||||||
{
|
|
||||||
|
|
||||||
var definition = new TProviderDefinition();
|
var definition = new TProviderDefinition();
|
||||||
|
|
||||||
definition.InjectFrom(indexerResource);
|
definition.InjectFrom(providerResource);
|
||||||
|
|
||||||
var configContract = ReflectionExtensions.CoreAssembly.FindTypeByName(definition.ConfigContract);
|
var configContract = ReflectionExtensions.CoreAssembly.FindTypeByName(definition.ConfigContract);
|
||||||
definition.Settings = (IProviderConfig)SchemaBuilder.ReadFormSchema(indexerResource.Fields, configContract);
|
definition.Settings = (IProviderConfig)SchemaBuilder.ReadFormSchema(providerResource.Fields, configContract);
|
||||||
|
|
||||||
ValidateIndexer(definition);
|
Validate(definition);
|
||||||
|
|
||||||
return definition;
|
return definition;
|
||||||
}
|
}
|
||||||
|
@ -113,22 +96,30 @@ namespace NzbDrone.Api
|
||||||
|
|
||||||
private Response GetTemplates()
|
private Response GetTemplates()
|
||||||
{
|
{
|
||||||
|
var templates = _providerFactory.Templates();
|
||||||
|
|
||||||
var indexers = _providerFactory.Templates();
|
var result = new List<TProviderResource>(templates.Count());
|
||||||
|
|
||||||
|
foreach (var providerDefinition in templates)
|
||||||
var result = new List<IndexerResource>(indexers.Count());
|
|
||||||
|
|
||||||
foreach (var indexer in indexers)
|
|
||||||
{
|
{
|
||||||
var indexerResource = new IndexerResource();
|
var providerResource = new TProviderResource();
|
||||||
indexerResource.InjectFrom(indexer);
|
providerResource.InjectFrom(providerDefinition);
|
||||||
indexerResource.Fields = SchemaBuilder.ToSchema(indexer.Settings);
|
providerResource.Fields = SchemaBuilder.ToSchema(providerDefinition.Settings);
|
||||||
|
|
||||||
result.Add(indexerResource);
|
result.Add(providerResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.AsResponse();
|
return result.AsResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void Validate(TProviderDefinition definition)
|
||||||
|
{
|
||||||
|
var validationResult = definition.Settings.Validate();
|
||||||
|
|
||||||
|
if (!validationResult.IsValid)
|
||||||
|
{
|
||||||
|
throw new ValidationException(validationResult.Errors);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,7 +7,6 @@ namespace NzbDrone.Api
|
||||||
{
|
{
|
||||||
public class ProviderResource : RestResource
|
public class ProviderResource : RestResource
|
||||||
{
|
{
|
||||||
public Boolean Enable { get; set; }
|
|
||||||
public String Name { get; set; }
|
public String Name { get; set; }
|
||||||
public List<Field> Fields { get; set; }
|
public List<Field> Fields { get; set; }
|
||||||
public String Implementation { get; set; }
|
public String Implementation { get; set; }
|
|
@ -42,6 +42,9 @@ namespace NzbDrone.Common
|
||||||
void SetFolderWriteTime(string path, DateTime time);
|
void SetFolderWriteTime(string path, DateTime time);
|
||||||
FileAttributes GetFileAttributes(string path);
|
FileAttributes GetFileAttributes(string path);
|
||||||
void EmptyFolder(string path);
|
void EmptyFolder(string path);
|
||||||
|
string[] GetFixedDrives();
|
||||||
|
long? GetTotalSize(string path);
|
||||||
|
string GetVolumeLabel(string path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DiskProvider : IDiskProvider
|
public class DiskProvider : IDiskProvider
|
||||||
|
@ -322,30 +325,6 @@ namespace NzbDrone.Common
|
||||||
return DriveFreeSpaceEx(root);
|
return DriveFreeSpaceEx(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static long DriveFreeSpaceEx(string folderName)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(folderName))
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("folderName");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!folderName.EndsWith("\\"))
|
|
||||||
{
|
|
||||||
folderName += '\\';
|
|
||||||
}
|
|
||||||
|
|
||||||
ulong free = 0;
|
|
||||||
ulong dummy1 = 0;
|
|
||||||
ulong dummy2 = 0;
|
|
||||||
|
|
||||||
if (GetDiskFreeSpaceEx(folderName, out free, out dummy1, out dummy2))
|
|
||||||
{
|
|
||||||
return (long)free;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string ReadAllText(string filePath)
|
public string ReadAllText(string filePath)
|
||||||
{
|
{
|
||||||
Ensure.That(() => filePath).IsValidPath();
|
Ensure.That(() => filePath).IsValidPath();
|
||||||
|
@ -475,5 +454,105 @@ namespace NzbDrone.Common
|
||||||
DeleteFolder(directory, true);
|
DeleteFolder(directory, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string[] GetFixedDrives()
|
||||||
|
{
|
||||||
|
return (DriveInfo.GetDrives().Where(x => x.DriveType == DriveType.Fixed).Select(x => x.Name)).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long? GetTotalSize(string path)
|
||||||
|
{
|
||||||
|
Ensure.That(() => path).IsValidPath();
|
||||||
|
|
||||||
|
var root = GetPathRoot(path);
|
||||||
|
|
||||||
|
if (!FolderExists(root))
|
||||||
|
throw new DirectoryNotFoundException(root);
|
||||||
|
|
||||||
|
if (OsInfo.IsLinux)
|
||||||
|
{
|
||||||
|
var drives = DriveInfo.GetDrives();
|
||||||
|
|
||||||
|
foreach (var drive in drives)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (drive.IsReady && path.StartsWith(drive.Name, StringComparison.CurrentCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
return drive.TotalSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException e)
|
||||||
|
{
|
||||||
|
Logger.ErrorException("Couldn't get total space for " + path, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return DriveTotalSizeEx(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetVolumeLabel(string path)
|
||||||
|
{
|
||||||
|
var driveInfo = DriveInfo.GetDrives().SingleOrDefault(d => d.Name == path);
|
||||||
|
|
||||||
|
if (driveInfo == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return driveInfo.VolumeLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long DriveFreeSpaceEx(string folderName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(folderName))
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("folderName");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!folderName.EndsWith("\\"))
|
||||||
|
{
|
||||||
|
folderName += '\\';
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong free = 0;
|
||||||
|
ulong dummy1 = 0;
|
||||||
|
ulong dummy2 = 0;
|
||||||
|
|
||||||
|
if (GetDiskFreeSpaceEx(folderName, out free, out dummy1, out dummy2))
|
||||||
|
{
|
||||||
|
return (long)free;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long DriveTotalSizeEx(string folderName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(folderName))
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("folderName");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!folderName.EndsWith("\\"))
|
||||||
|
{
|
||||||
|
folderName += '\\';
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong total = 0;
|
||||||
|
ulong dummy1 = 0;
|
||||||
|
ulong dummy2 = 0;
|
||||||
|
|
||||||
|
if (GetDiskFreeSpaceEx(folderName, out dummy1, out total, out dummy2))
|
||||||
|
{
|
||||||
|
return (long)total;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,242 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class NotInQueueSpecificationFixture : CoreTest<NotInQueueSpecification>
|
||||||
|
{
|
||||||
|
private Series _series;
|
||||||
|
private Episode _episode;
|
||||||
|
private RemoteEpisode _remoteEpisode;
|
||||||
|
private Mock<IDownloadClient> _downloadClient;
|
||||||
|
|
||||||
|
private Series _otherSeries;
|
||||||
|
private Episode _otherEpisode;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_series = Builder<Series>.CreateNew().Build();
|
||||||
|
|
||||||
|
_episode = Builder<Episode>.CreateNew()
|
||||||
|
.With(e => e.SeriesId = _series.Id)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_otherSeries = Builder<Series>.CreateNew()
|
||||||
|
.With(s => s.Id = 2)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_otherEpisode = Builder<Episode>.CreateNew()
|
||||||
|
.With(e => e.SeriesId = _otherSeries.Id)
|
||||||
|
.With(e => e.Id = 2)
|
||||||
|
.With(e => e.SeasonNumber = 2)
|
||||||
|
.With(e => e.EpisodeNumber = 2)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_remoteEpisode = Builder<RemoteEpisode>.CreateNew()
|
||||||
|
.With(r => r.Series = _series)
|
||||||
|
.With(r => r.Episodes = new List<Episode> { _episode })
|
||||||
|
.With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.DVD)})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_downloadClient = Mocker.GetMock<IDownloadClient>();
|
||||||
|
|
||||||
|
Mocker.GetMock<IProvideDownloadClient>()
|
||||||
|
.Setup(s => s.GetDownloadClient())
|
||||||
|
.Returns(_downloadClient.Object);
|
||||||
|
|
||||||
|
_downloadClient.SetupGet(s => s.IsConfigured)
|
||||||
|
.Returns(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenEmptyQueue()
|
||||||
|
{
|
||||||
|
_downloadClient.Setup(s => s.GetQueue())
|
||||||
|
.Returns(new List<QueueItem>());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenQueue(IEnumerable<RemoteEpisode> remoteEpisodes)
|
||||||
|
{
|
||||||
|
var queue = new List<QueueItem>();
|
||||||
|
|
||||||
|
foreach (var remoteEpisode in remoteEpisodes)
|
||||||
|
{
|
||||||
|
queue.Add(new QueueItem
|
||||||
|
{
|
||||||
|
RemoteEpisode = remoteEpisode
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_downloadClient.Setup(s => s.GetQueue())
|
||||||
|
.Returns(queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_true_when_queue_is_empty()
|
||||||
|
{
|
||||||
|
GivenEmptyQueue();
|
||||||
|
Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_true_when_series_doesnt_match()
|
||||||
|
{
|
||||||
|
var remoteEpisode = Builder<RemoteEpisode>.CreateNew()
|
||||||
|
.With(r => r.Series = _otherSeries)
|
||||||
|
.With(r => r.Episodes = new List<Episode> { _episode })
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
GivenQueue(new List<RemoteEpisode> { remoteEpisode });
|
||||||
|
Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_true_when_quality_in_queue_is_lower()
|
||||||
|
{
|
||||||
|
var remoteEpisode = Builder<RemoteEpisode>.CreateNew()
|
||||||
|
.With(r => r.Series = _series)
|
||||||
|
.With(r => r.Episodes = new List<Episode> { _episode })
|
||||||
|
.With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo
|
||||||
|
{
|
||||||
|
Quality = new QualityModel(Quality.SDTV)
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
GivenQueue(new List<RemoteEpisode> { remoteEpisode });
|
||||||
|
Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_true_when_episode_doesnt_match()
|
||||||
|
{
|
||||||
|
var remoteEpisode = Builder<RemoteEpisode>.CreateNew()
|
||||||
|
.With(r => r.Series = _series)
|
||||||
|
.With(r => r.Episodes = new List<Episode> { _otherEpisode })
|
||||||
|
.With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo
|
||||||
|
{
|
||||||
|
Quality = new QualityModel(Quality.DVD)
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
GivenQueue(new List<RemoteEpisode> { remoteEpisode });
|
||||||
|
Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_false_when_qualities_are_the_same()
|
||||||
|
{
|
||||||
|
var remoteEpisode = Builder<RemoteEpisode>.CreateNew()
|
||||||
|
.With(r => r.Series = _series)
|
||||||
|
.With(r => r.Episodes = new List<Episode> { _episode })
|
||||||
|
.With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo
|
||||||
|
{
|
||||||
|
Quality = new QualityModel(Quality.DVD)
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
GivenQueue(new List<RemoteEpisode> { remoteEpisode });
|
||||||
|
Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_false_when_quality_in_queue_is_better()
|
||||||
|
{
|
||||||
|
var remoteEpisode = Builder<RemoteEpisode>.CreateNew()
|
||||||
|
.With(r => r.Series = _series)
|
||||||
|
.With(r => r.Episodes = new List<Episode> { _episode })
|
||||||
|
.With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo
|
||||||
|
{
|
||||||
|
Quality = new QualityModel(Quality.HDTV720p)
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
GivenQueue(new List<RemoteEpisode> { remoteEpisode });
|
||||||
|
Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_false_if_matching_multi_episode_is_in_queue()
|
||||||
|
{
|
||||||
|
var remoteEpisode = Builder<RemoteEpisode>.CreateNew()
|
||||||
|
.With(r => r.Series = _series)
|
||||||
|
.With(r => r.Episodes = new List<Episode> { _episode, _otherEpisode })
|
||||||
|
.With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo
|
||||||
|
{
|
||||||
|
Quality = new QualityModel(Quality.HDTV720p)
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
GivenQueue(new List<RemoteEpisode> { remoteEpisode });
|
||||||
|
Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_false_if_multi_episode_has_one_episode_in_queue()
|
||||||
|
{
|
||||||
|
var remoteEpisode = Builder<RemoteEpisode>.CreateNew()
|
||||||
|
.With(r => r.Series = _series)
|
||||||
|
.With(r => r.Episodes = new List<Episode> { _episode })
|
||||||
|
.With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo
|
||||||
|
{
|
||||||
|
Quality = new QualityModel(Quality.HDTV720p)
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_remoteEpisode.Episodes.Add(_otherEpisode);
|
||||||
|
|
||||||
|
GivenQueue(new List<RemoteEpisode> { remoteEpisode });
|
||||||
|
Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_false_if_multi_part_episode_is_already_in_queue()
|
||||||
|
{
|
||||||
|
var remoteEpisode = Builder<RemoteEpisode>.CreateNew()
|
||||||
|
.With(r => r.Series = _series)
|
||||||
|
.With(r => r.Episodes = new List<Episode> { _episode, _otherEpisode })
|
||||||
|
.With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo
|
||||||
|
{
|
||||||
|
Quality = new QualityModel(Quality.HDTV720p)
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_remoteEpisode.Episodes.Add(_otherEpisode);
|
||||||
|
|
||||||
|
GivenQueue(new List<RemoteEpisode> { remoteEpisode });
|
||||||
|
Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_false_if_multi_part_episode_has_two_episodes_in_queue()
|
||||||
|
{
|
||||||
|
var remoteEpisodes = Builder<RemoteEpisode>.CreateListOfSize(2)
|
||||||
|
.All()
|
||||||
|
.With(r => r.Series = _series)
|
||||||
|
.With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo
|
||||||
|
{
|
||||||
|
Quality =
|
||||||
|
new QualityModel(
|
||||||
|
Quality.HDTV720p)
|
||||||
|
})
|
||||||
|
.TheFirst(1)
|
||||||
|
.With(r => r.Episodes = new List<Episode> {_episode})
|
||||||
|
.TheNext(1)
|
||||||
|
.With(r => r.Episodes = new List<Episode> {_otherEpisode})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_remoteEpisode.Episodes.Add(_otherEpisode);
|
||||||
|
GivenQueue(remoteEpisodes);
|
||||||
|
Subject.IsSatisfiedBy(_remoteEpisode, null ).Should().BeFalse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,11 +5,14 @@ using NUnit.Framework;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Download.Clients.Nzbget;
|
using NzbDrone.Core.Download.Clients.Nzbget;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetProviderTests
|
namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetProviderTests
|
||||||
{
|
{
|
||||||
public class QueueFixture : CoreTest
|
public class QueueFixture : CoreTest<NzbgetClient>
|
||||||
{
|
{
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
|
@ -49,10 +52,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetProviderTests
|
||||||
{
|
{
|
||||||
WithEmptyQueue();
|
WithEmptyQueue();
|
||||||
|
|
||||||
Mocker.Resolve<NzbgetClient>()
|
Subject.GetQueue()
|
||||||
.GetQueue()
|
.Should()
|
||||||
.Should()
|
.BeEmpty();
|
||||||
.BeEmpty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -60,10 +62,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetProviderTests
|
||||||
{
|
{
|
||||||
WithFullQueue();
|
WithFullQueue();
|
||||||
|
|
||||||
Mocker.Resolve<NzbgetClient>()
|
Mocker.GetMock<IParsingService>()
|
||||||
.GetQueue()
|
.Setup(s => s.Map(It.IsAny<ParsedEpisodeInfo>(), 0, null))
|
||||||
.Should()
|
.Returns(new RemoteEpisode {Series = new Series()});
|
||||||
.HaveCount(1);
|
|
||||||
|
Subject.GetQueue()
|
||||||
|
.Should()
|
||||||
|
.HaveCount(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
using System.Linq;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Housekeeping.Housekeepers;
|
||||||
|
using NzbDrone.Core.MediaFiles;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class CleanupOrphanedEpisodeFilesFixture : DbTest<CleanupOrphanedEpisodeFiles, EpisodeFile>
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void should_delete_orphaned_episode_files()
|
||||||
|
{
|
||||||
|
var episodeFile = Builder<EpisodeFile>.CreateNew()
|
||||||
|
.BuildNew();
|
||||||
|
|
||||||
|
Db.Insert(episodeFile);
|
||||||
|
Subject.Clean();
|
||||||
|
AllStoredModels.Should().BeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_delete_unorphaned_episode_files()
|
||||||
|
{
|
||||||
|
var episodeFiles = Builder<EpisodeFile>.CreateListOfSize(2)
|
||||||
|
.BuildListOfNew();
|
||||||
|
|
||||||
|
Db.InsertMany(episodeFiles);
|
||||||
|
|
||||||
|
var episode = Builder<Episode>.CreateNew()
|
||||||
|
.With(e => e.EpisodeFileId = episodeFiles.First().Id)
|
||||||
|
.BuildNew();
|
||||||
|
|
||||||
|
Db.Insert(episode);
|
||||||
|
|
||||||
|
Subject.Clean();
|
||||||
|
AllStoredModels.Should().HaveCount(1);
|
||||||
|
Db.All<Episode>().Should().Contain(e => e.EpisodeFileId == AllStoredModels.First().Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -48,7 +48,6 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
Episodes = new List<Episode> {episode},
|
Episodes = new List<Episode> {episode},
|
||||||
Path = @"C:\Test\TV\30 Rock\30 Rock - S01E01 - Pilit.avi".AsOsAgnostic(),
|
Path = @"C:\Test\TV\30 Rock\30 Rock - S01E01 - Pilit.avi".AsOsAgnostic(),
|
||||||
Quality = new QualityModel(Quality.Bluray720p)
|
Quality = new QualityModel(Quality.Bluray720p)
|
||||||
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,5 +124,32 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||||
Mocker.GetMock<IEventAggregator>()
|
Mocker.GetMock<IEventAggregator>()
|
||||||
.Verify(v => v.PublishEvent(It.IsAny<EpisodeImportedEvent>()), Times.Never());
|
.Verify(v => v.PublishEvent(It.IsAny<EpisodeImportedEvent>()), Times.Never());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_import_larger_files_first()
|
||||||
|
{
|
||||||
|
var fileDecision = _approvedDecisions.First();
|
||||||
|
fileDecision.LocalEpisode.Size = 1.Gigabytes();
|
||||||
|
|
||||||
|
var sampleDecision = new ImportDecision
|
||||||
|
(new LocalEpisode
|
||||||
|
{
|
||||||
|
Series = fileDecision.LocalEpisode.Series,
|
||||||
|
Episodes = new List<Episode> {fileDecision.LocalEpisode.Episodes.First()},
|
||||||
|
Path = @"C:\Test\TV\30 Rock\30 Rock - S01E01 - Pilit.avi".AsOsAgnostic(),
|
||||||
|
Quality = new QualityModel(Quality.Bluray720p),
|
||||||
|
Size = 80.Megabytes()
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
var all = new List<ImportDecision>();
|
||||||
|
all.Add(fileDecision);
|
||||||
|
all.Add(sampleDecision);
|
||||||
|
|
||||||
|
var results = Subject.Import(all);
|
||||||
|
|
||||||
|
results.Should().HaveCount(1);
|
||||||
|
results.Should().ContainSingle(d => d.LocalEpisode.Size == fileDecision.LocalEpisode.Size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -80,8 +80,6 @@ namespace NzbDrone.Core.Test.MetadataSourceTests
|
||||||
episodes.GroupBy(e => e.SeasonNumber.ToString("000") + e.EpisodeNumber.ToString("000"))
|
episodes.GroupBy(e => e.SeasonNumber.ToString("000") + e.EpisodeNumber.ToString("000"))
|
||||||
.Max(e => e.Count()).Should().Be(1);
|
.Max(e => e.Count()).Should().Be(1);
|
||||||
|
|
||||||
episodes.Select(c => c.TvDbEpisodeId).Should().OnlyHaveUniqueItems();
|
|
||||||
|
|
||||||
episodes.Should().Contain(c => c.SeasonNumber > 0);
|
episodes.Should().Contain(c => c.SeasonNumber > 0);
|
||||||
episodes.Should().Contain(c => !string.IsNullOrWhiteSpace(c.Overview));
|
episodes.Should().Contain(c => !string.IsNullOrWhiteSpace(c.Overview));
|
||||||
|
|
||||||
|
@ -98,7 +96,6 @@ namespace NzbDrone.Core.Test.MetadataSourceTests
|
||||||
{
|
{
|
||||||
episode.Should().NotBeNull();
|
episode.Should().NotBeNull();
|
||||||
episode.EpisodeNumber.Should().NotBe(0);
|
episode.EpisodeNumber.Should().NotBe(0);
|
||||||
episode.TvDbEpisodeId.Should().BeGreaterThan(0);
|
|
||||||
|
|
||||||
episode.Should().NotBeNull();
|
episode.Should().NotBeNull();
|
||||||
|
|
||||||
|
|
|
@ -1,130 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Sockets;
|
|
||||||
using FizzWare.NBuilder;
|
|
||||||
using FluentAssertions;
|
|
||||||
using Moq;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using NzbDrone.Common.Composition;
|
|
||||||
using NzbDrone.Core.MediaFiles.Events;
|
|
||||||
using NzbDrone.Core.Notifications;
|
|
||||||
using NzbDrone.Core.Notifications.Email;
|
|
||||||
using NzbDrone.Core.Notifications.Growl;
|
|
||||||
using NzbDrone.Core.Notifications.Plex;
|
|
||||||
using NzbDrone.Core.Notifications.Prowl;
|
|
||||||
using NzbDrone.Core.Parser.Model;
|
|
||||||
using NzbDrone.Core.Test.Framework;
|
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.NotificationTests
|
|
||||||
{
|
|
||||||
public class NotificationServiceFixture : DbTest<NotificationService, NotificationDefinition>
|
|
||||||
{
|
|
||||||
private List<INotification> _notifications;
|
|
||||||
|
|
||||||
[SetUp]
|
|
||||||
public void Setup()
|
|
||||||
{
|
|
||||||
_notifications = new List<INotification>();
|
|
||||||
|
|
||||||
_notifications.Add(new Notifications.Xbmc.Xbmc(null));
|
|
||||||
_notifications.Add(new PlexClient(null));
|
|
||||||
_notifications.Add(new PlexServer(null));
|
|
||||||
_notifications.Add(new Email(null));
|
|
||||||
_notifications.Add(new Growl(null));
|
|
||||||
_notifications.Add(new Prowl(null));
|
|
||||||
|
|
||||||
Mocker.SetConstant<IEnumerable<INotification>>(_notifications);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void getting_list_of_indexers_should_be_empty_by_default()
|
|
||||||
{
|
|
||||||
Mocker.SetConstant<INotificationRepository>(Mocker.Resolve<NotificationRepository>());
|
|
||||||
|
|
||||||
var notifications = Subject.All().ToList();
|
|
||||||
notifications.Should().BeEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_be_able_to_get_schema_for_all_notifications()
|
|
||||||
{
|
|
||||||
Mocker.SetConstant<INotificationRepository>(Mocker.Resolve<NotificationRepository>());
|
|
||||||
|
|
||||||
Mocker.GetMock<IContainer>().Setup(s => s.Resolve(typeof(Notifications.Xbmc.Xbmc)))
|
|
||||||
.Returns(new Notifications.Xbmc.Xbmc(null));
|
|
||||||
|
|
||||||
Mocker.GetMock<IContainer>().Setup(s => s.Resolve(typeof(PlexClient)))
|
|
||||||
.Returns(new PlexClient(null));
|
|
||||||
|
|
||||||
Mocker.GetMock<IContainer>().Setup(s => s.Resolve(typeof(PlexServer)))
|
|
||||||
.Returns(new PlexServer(null));
|
|
||||||
|
|
||||||
Mocker.GetMock<IContainer>().Setup(s => s.Resolve(typeof(Email)))
|
|
||||||
.Returns(new Email(null));
|
|
||||||
|
|
||||||
Mocker.GetMock<IContainer>().Setup(s => s.Resolve(typeof(Growl)))
|
|
||||||
.Returns(new Growl(null));
|
|
||||||
|
|
||||||
Mocker.GetMock<IContainer>().Setup(s => s.Resolve(typeof(Prowl)))
|
|
||||||
.Returns(new Prowl(null));
|
|
||||||
|
|
||||||
var notifications = Subject.Schema().ToList();
|
|
||||||
notifications.Should().NotBeEmpty();
|
|
||||||
notifications.Should().NotContain(c => c.Settings == null);
|
|
||||||
notifications.Should().NotContain(c => c.Instance == null);
|
|
||||||
notifications.Should().NotContain(c => c.ImplementationName == null);
|
|
||||||
notifications.Select(c => c.ImplementationName).Should().OnlyHaveUniqueItems();
|
|
||||||
notifications.Select(c => c.Instance).Should().OnlyHaveUniqueItems();
|
|
||||||
notifications.Select(c => c.Id).Should().OnlyHaveUniqueItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
[Explicit]
|
|
||||||
public void should_try_other_notifiers_when_one_fails()
|
|
||||||
{
|
|
||||||
var notifications = Builder<NotificationDefinition>.CreateListOfSize(2)
|
|
||||||
.All()
|
|
||||||
.With(n => n.OnGrab = true)
|
|
||||||
.With(n => n.OnDownload = true)
|
|
||||||
.TheFirst(1)
|
|
||||||
.With(n => n.Implementation = "Xbmc")
|
|
||||||
.TheLast(1)
|
|
||||||
.With(n => n.Implementation = "Email")
|
|
||||||
.Build()
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
var series = Builder<Series>.CreateNew()
|
|
||||||
.With(s => s.SeriesType = SeriesTypes.Standard)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var parsedEpisodeInfo = Builder<ParsedEpisodeInfo>.CreateNew()
|
|
||||||
.With(p => p.EpisodeNumbers = new int[] {1})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var localEpisode = Builder<LocalEpisode>.CreateNew()
|
|
||||||
.With(e => e.Series = series)
|
|
||||||
.With(e => e.ParsedEpisodeInfo = parsedEpisodeInfo)
|
|
||||||
.With(e => e.Episodes = Builder<Episode>.CreateListOfSize(1)
|
|
||||||
.Build().ToList())
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
Mocker.GetMock<INotificationRepository>()
|
|
||||||
.Setup(s => s.All())
|
|
||||||
.Returns(notifications);
|
|
||||||
|
|
||||||
//Todo: How can we test this, right now without an empty constructor it won't work
|
|
||||||
Mocker.GetMock<Notifications.Xbmc.Xbmc>()
|
|
||||||
.Setup(s => s.OnDownload(It.IsAny<string>(), series))
|
|
||||||
.Throws(new SocketException());
|
|
||||||
|
|
||||||
Subject.Handle(new EpisodeDownloadedEvent(localEpisode));
|
|
||||||
|
|
||||||
Mocker.GetMock<Notifications.Xbmc.Xbmc>()
|
|
||||||
.Verify(v => v.OnDownload(It.IsAny<string>(), series), Times.Once());
|
|
||||||
|
|
||||||
Mocker.GetMock<Email>()
|
|
||||||
.Verify(v => v.OnDownload(It.IsAny<string>(), series), Times.Once());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -111,6 +111,7 @@
|
||||||
<Compile Include="Datastore\ReflectionStrategyFixture\Benchmarks.cs" />
|
<Compile Include="Datastore\ReflectionStrategyFixture\Benchmarks.cs" />
|
||||||
<Compile Include="Datastore\SQLiteMigrationHelperTests\AlterFixture.cs" />
|
<Compile Include="Datastore\SQLiteMigrationHelperTests\AlterFixture.cs" />
|
||||||
<Compile Include="Datastore\SQLiteMigrationHelperTests\DuplicateFixture.cs" />
|
<Compile Include="Datastore\SQLiteMigrationHelperTests\DuplicateFixture.cs" />
|
||||||
|
<Compile Include="DecisionEngineTests\NotInQueueSpecificationFixture.cs" />
|
||||||
<Compile Include="DecisionEngineTests\CutoffSpecificationFixture.cs" />
|
<Compile Include="DecisionEngineTests\CutoffSpecificationFixture.cs" />
|
||||||
<Compile Include="DecisionEngineTests\NotRestrictedReleaseSpecificationFixture.cs" />
|
<Compile Include="DecisionEngineTests\NotRestrictedReleaseSpecificationFixture.cs" />
|
||||||
<Compile Include="DecisionEngineTests\RssSync\ProperSpecificationFixture.cs" />
|
<Compile Include="DecisionEngineTests\RssSync\ProperSpecificationFixture.cs" />
|
||||||
|
@ -127,6 +128,7 @@
|
||||||
<Compile Include="Framework\DbTest.cs" />
|
<Compile Include="Framework\DbTest.cs" />
|
||||||
<Compile Include="Framework\NBuilderExtensions.cs" />
|
<Compile Include="Framework\NBuilderExtensions.cs" />
|
||||||
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedHistoryItemsFixture.cs" />
|
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedHistoryItemsFixture.cs" />
|
||||||
|
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedEpisodeFilesFixture.cs" />
|
||||||
<Compile Include="IndexerSearchTests\SearchDefinitionFixture.cs" />
|
<Compile Include="IndexerSearchTests\SearchDefinitionFixture.cs" />
|
||||||
<Compile Include="IndexerTests\BasicRssParserFixture.cs" />
|
<Compile Include="IndexerTests\BasicRssParserFixture.cs" />
|
||||||
<Compile Include="IndexerTests\IndexerServiceFixture.cs" />
|
<Compile Include="IndexerTests\IndexerServiceFixture.cs" />
|
||||||
|
@ -154,7 +156,6 @@
|
||||||
<Compile Include="Messaging\Commands\CommandFixture.cs" />
|
<Compile Include="Messaging\Commands\CommandFixture.cs" />
|
||||||
<Compile Include="Messaging\Events\EventAggregatorFixture.cs" />
|
<Compile Include="Messaging\Events\EventAggregatorFixture.cs" />
|
||||||
<Compile Include="MetadataSourceTests\TraktProxyFixture.cs" />
|
<Compile Include="MetadataSourceTests\TraktProxyFixture.cs" />
|
||||||
<Compile Include="NotificationTests\NotificationServiceFixture.cs" />
|
|
||||||
<Compile Include="NotificationTests\Xbmc\GetJsonVersionFixture.cs" />
|
<Compile Include="NotificationTests\Xbmc\GetJsonVersionFixture.cs" />
|
||||||
<Compile Include="NotificationTests\Xbmc\Http\ActivePlayersFixture.cs" />
|
<Compile Include="NotificationTests\Xbmc\Http\ActivePlayersFixture.cs" />
|
||||||
<Compile Include="NotificationTests\Xbmc\Http\CheckForErrorFixture.cs" />
|
<Compile Include="NotificationTests\Xbmc\Http\CheckForErrorFixture.cs" />
|
||||||
|
|
|
@ -48,7 +48,6 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeRepositoryTests
|
||||||
var monitoredSeriesEpisodes = Builder<Episode>.CreateListOfSize(3)
|
var monitoredSeriesEpisodes = Builder<Episode>.CreateListOfSize(3)
|
||||||
.All()
|
.All()
|
||||||
.With(e => e.Id = 0)
|
.With(e => e.Id = 0)
|
||||||
.With(e => e.TvDbEpisodeId = RandomNumber)
|
|
||||||
.With(e => e.SeriesId = _monitoredSeries.Id)
|
.With(e => e.SeriesId = _monitoredSeries.Id)
|
||||||
.With(e => e.EpisodeFileId = 0)
|
.With(e => e.EpisodeFileId = 0)
|
||||||
.With(e => e.AirDateUtc = DateTime.Now.AddDays(-5))
|
.With(e => e.AirDateUtc = DateTime.Now.AddDays(-5))
|
||||||
|
@ -62,7 +61,6 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeRepositoryTests
|
||||||
var unmonitoredSeriesEpisodes = Builder<Episode>.CreateListOfSize(3)
|
var unmonitoredSeriesEpisodes = Builder<Episode>.CreateListOfSize(3)
|
||||||
.All()
|
.All()
|
||||||
.With(e => e.Id = 0)
|
.With(e => e.Id = 0)
|
||||||
.With(e => e.TvDbEpisodeId = RandomNumber)
|
|
||||||
.With(e => e.SeriesId = _unmonitoredSeries.Id)
|
.With(e => e.SeriesId = _unmonitoredSeries.Id)
|
||||||
.With(e => e.EpisodeFileId = 0)
|
.With(e => e.EpisodeFileId = 0)
|
||||||
.With(e => e.AirDateUtc = DateTime.Now.AddDays(-5))
|
.With(e => e.AirDateUtc = DateTime.Now.AddDays(-5))
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,18 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Common.Serializer;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(22)]
|
||||||
|
public class move_indexer_to_generic_provider : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Alter.Table("Indexers").AddColumn("ConfigContract").AsString().Nullable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,68 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Data;
|
|
||||||
using FluentMigrator;
|
|
||||||
using NzbDrone.Common.Serializer;
|
|
||||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Datastore.Migration
|
|
||||||
{
|
|
||||||
[Migration(22)]
|
|
||||||
public class move_indexer_to_generic_provider : NzbDroneMigrationBase
|
|
||||||
{
|
|
||||||
protected override void MainDbUpgrade()
|
|
||||||
{
|
|
||||||
Alter.Table("Indexers").AddColumn("ConfigContract").AsString().Nullable();
|
|
||||||
|
|
||||||
//Execute.WithConnection(ConvertSeasons);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ConvertSeasons(IDbConnection conn, IDbTransaction tran)
|
|
||||||
{
|
|
||||||
using (IDbCommand allSeriesCmd = conn.CreateCommand())
|
|
||||||
{
|
|
||||||
allSeriesCmd.Transaction = tran;
|
|
||||||
allSeriesCmd.CommandText = @"SELECT Id FROM Series";
|
|
||||||
using (IDataReader allSeriesReader = allSeriesCmd.ExecuteReader())
|
|
||||||
{
|
|
||||||
while (allSeriesReader.Read())
|
|
||||||
{
|
|
||||||
int seriesId = allSeriesReader.GetInt32(0);
|
|
||||||
var seasons = new List<dynamic>();
|
|
||||||
|
|
||||||
using (IDbCommand seasonsCmd = conn.CreateCommand())
|
|
||||||
{
|
|
||||||
seasonsCmd.Transaction = tran;
|
|
||||||
seasonsCmd.CommandText = String.Format(@"SELECT SeasonNumber, Monitored FROM Seasons WHERE SeriesId = {0}", seriesId);
|
|
||||||
|
|
||||||
using (IDataReader seasonReader = seasonsCmd.ExecuteReader())
|
|
||||||
{
|
|
||||||
while (seasonReader.Read())
|
|
||||||
{
|
|
||||||
int seasonNumber = seasonReader.GetInt32(0);
|
|
||||||
bool monitored = seasonReader.GetBoolean(1);
|
|
||||||
|
|
||||||
if (seasonNumber == 0)
|
|
||||||
{
|
|
||||||
monitored = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
seasons.Add(new { seasonNumber, monitored });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
using (IDbCommand updateCmd = conn.CreateCommand())
|
|
||||||
{
|
|
||||||
var text = String.Format("UPDATE Series SET Seasons = '{0}' WHERE Id = {1}", seasons.ToJson(), seriesId);
|
|
||||||
|
|
||||||
updateCmd.Transaction = tran;
|
|
||||||
updateCmd.CommandText = text;
|
|
||||||
updateCmd.ExecuteNonQuery();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(24)]
|
||||||
|
public class drop_tvdb_episodeid : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
SqLiteAlter.DropColumns("Episodes", new[] { "TvDbEpisodeId" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(25)]
|
||||||
|
public class move_notification_to_generic_provider : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Alter.Table("Notifications").AddColumn("ConfigContract").AsString().Nullable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(26)]
|
||||||
|
public class add_config_contract_to_notifications : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Update.Table("Notifications").Set(new { ConfigContract = "EmailSettings" }).Where(new { Implementation = "Email" });
|
||||||
|
Update.Table("Notifications").Set(new { ConfigContract = "GrowlSettings" }).Where(new { Implementation = "Growl" });
|
||||||
|
Update.Table("Notifications").Set(new { ConfigContract = "NotifyMyAndroidSettings" }).Where(new { Implementation = "NotifyMyAndroid" });
|
||||||
|
Update.Table("Notifications").Set(new { ConfigContract = "PlexClientSettings" }).Where(new { Implementation = "PlexClient" });
|
||||||
|
Update.Table("Notifications").Set(new { ConfigContract = "PlexServerSettings" }).Where(new { Implementation = "PlexServer" });
|
||||||
|
Update.Table("Notifications").Set(new { ConfigContract = "ProwlSettings" }).Where(new { Implementation = "Prowl" });
|
||||||
|
Update.Table("Notifications").Set(new { ConfigContract = "PushBulletSettings" }).Where(new { Implementation = "PushBullet" });
|
||||||
|
Update.Table("Notifications").Set(new { ConfigContract = "PushoverSettings" }).Where(new { Implementation = "Pushover" });
|
||||||
|
Update.Table("Notifications").Set(new { ConfigContract = "XbmcSettings" }).Where(new { Implementation = "Xbmc" });
|
||||||
|
|
||||||
|
Delete.FromTable("Notifications").IsNull("ConfigContract");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(27)]
|
||||||
|
public class fix_omgwtfnzbs : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Update.Table("Indexers")
|
||||||
|
.Set(new {ConfigContract = "OmgwtfnzbsSettings"})
|
||||||
|
.Where(new {Implementation = "Omgwtfnzbs"});
|
||||||
|
|
||||||
|
Update.Table("Indexers")
|
||||||
|
.Set(new {Settings = "{}"})
|
||||||
|
.Where(new {Implementation = "Omgwtfnzbs", Settings = (string) null});
|
||||||
|
|
||||||
|
Update.Table("Indexers")
|
||||||
|
.Set(new { Settings = "{}" })
|
||||||
|
.Where(new { Implementation = "Omgwtfnzbs", Settings = "" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,12 +35,13 @@ namespace NzbDrone.Core.Datastore
|
||||||
|
|
||||||
Mapper.Entity<IndexerDefinition>().RegisterModel("Indexers");
|
Mapper.Entity<IndexerDefinition>().RegisterModel("Indexers");
|
||||||
Mapper.Entity<ScheduledTask>().RegisterModel("ScheduledTasks");
|
Mapper.Entity<ScheduledTask>().RegisterModel("ScheduledTasks");
|
||||||
Mapper.Entity<NotificationDefinition>().RegisterModel("Notifications");
|
Mapper.Entity<NotificationDefinition>()
|
||||||
|
.RegisterModel("Notifications");
|
||||||
|
|
||||||
Mapper.Entity<SceneMapping>().RegisterModel("SceneMappings");
|
Mapper.Entity<SceneMapping>().RegisterModel("SceneMappings");
|
||||||
|
|
||||||
Mapper.Entity<History.History>().RegisterModel("History")
|
Mapper.Entity<History.History>().RegisterModel("History")
|
||||||
.AutoMapChildModels();
|
.AutoMapChildModels();
|
||||||
|
|
||||||
Mapper.Entity<Series>().RegisterModel("Series")
|
Mapper.Entity<Series>().RegisterModel("Series")
|
||||||
.Ignore(s => s.RootFolderPath)
|
.Ignore(s => s.RootFolderPath)
|
||||||
|
@ -96,7 +97,6 @@ namespace NzbDrone.Core.Datastore
|
||||||
{
|
{
|
||||||
var embeddedTypes = typeof(IEmbeddedDocument).Assembly.ImplementationsOf<IEmbeddedDocument>();
|
var embeddedTypes = typeof(IEmbeddedDocument).Assembly.ImplementationsOf<IEmbeddedDocument>();
|
||||||
|
|
||||||
|
|
||||||
var embeddedConvertor = new EmbeddedDocumentConverter();
|
var embeddedConvertor = new EmbeddedDocumentConverter();
|
||||||
var genericListDefinition = typeof(List<>).GetGenericTypeDefinition();
|
var genericListDefinition = typeof(List<>).GetGenericTypeDefinition();
|
||||||
foreach (var embeddedType in embeddedTypes)
|
foreach (var embeddedType in embeddedTypes)
|
||||||
|
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Core.Download;
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
|
@ -38,31 +39,17 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var queue = downloadClient.GetQueue().Select(queueItem => Parser.Parser.ParseTitle(queueItem.Title)).Where(episodeInfo => episodeInfo != null);
|
var queue = downloadClient.GetQueue().Select(q => q.RemoteEpisode);
|
||||||
|
|
||||||
return !IsInQueue(subject, queue);
|
return !IsInQueue(subject, queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsInQueue(RemoteEpisode newEpisode, IEnumerable<ParsedEpisodeInfo> queue)
|
private bool IsInQueue(RemoteEpisode newEpisode, IEnumerable<RemoteEpisode> queue)
|
||||||
{
|
{
|
||||||
var matchingTitle = queue.Where(q => String.Equals(q.SeriesTitle, newEpisode.Series.CleanTitle, StringComparison.InvariantCultureIgnoreCase));
|
var matchingSeries = queue.Where(q => q.Series.Id == newEpisode.Series.Id);
|
||||||
|
var matchingSeriesAndQuality = matchingSeries.Where(q => q.ParsedEpisodeInfo.Quality >= newEpisode.ParsedEpisodeInfo.Quality);
|
||||||
|
|
||||||
var matchingTitleWithQuality = matchingTitle.Where(q => q.Quality >= newEpisode.ParsedEpisodeInfo.Quality);
|
return matchingSeriesAndQuality.Any(q => q.Episodes.Select(e => e.Id).Intersect(newEpisode.Episodes.Select(e => e.Id)).Any());
|
||||||
|
|
||||||
if (newEpisode.Series.SeriesType == SeriesTypes.Daily)
|
|
||||||
{
|
|
||||||
return matchingTitleWithQuality.Any(q => q.AirDate.Value.Date == newEpisode.ParsedEpisodeInfo.AirDate.Value.Date);
|
|
||||||
}
|
|
||||||
|
|
||||||
var matchingSeason = matchingTitleWithQuality.Where(q => q.SeasonNumber == newEpisode.ParsedEpisodeInfo.SeasonNumber);
|
|
||||||
|
|
||||||
if (newEpisode.ParsedEpisodeInfo.FullSeason)
|
|
||||||
{
|
|
||||||
return matchingSeason.Any();
|
|
||||||
}
|
|
||||||
|
|
||||||
return matchingSeason.Any(q => q.EpisodeNumbers != null && q.EpisodeNumbers.Any(e => newEpisode.ParsedEpisodeInfo.EpisodeNumbers.Contains(e)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.DiskSpace
|
||||||
|
{
|
||||||
|
public class DiskSpace
|
||||||
|
{
|
||||||
|
public String Path { get; set; }
|
||||||
|
public String Label { get; set; }
|
||||||
|
public long FreeSpace { get; set; }
|
||||||
|
public long TotalSpace { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.DiskSpace
|
||||||
|
{
|
||||||
|
public interface IDiskSpaceService
|
||||||
|
{
|
||||||
|
List<DiskSpace> GetFreeSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DiskSpaceService : IDiskSpaceService
|
||||||
|
{
|
||||||
|
private readonly ISeriesService _seriesService;
|
||||||
|
private readonly IConfigService _configService;
|
||||||
|
private readonly IDiskProvider _diskProvider;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
public DiskSpaceService(ISeriesService seriesService, IConfigService configService, IDiskProvider diskProvider, Logger logger)
|
||||||
|
{
|
||||||
|
_seriesService = seriesService;
|
||||||
|
_configService = configService;
|
||||||
|
_diskProvider = diskProvider;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DiskSpace> GetFreeSpace()
|
||||||
|
{
|
||||||
|
var diskSpace = new List<DiskSpace>();
|
||||||
|
diskSpace.AddRange(GetSeriesFreeSpace());
|
||||||
|
diskSpace.AddRange(GetDroneFactoryFreeSpace());
|
||||||
|
diskSpace.AddRange(GetFixedDisksFreeSpace());
|
||||||
|
|
||||||
|
return diskSpace.DistinctBy(d => d.Path).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<DiskSpace> GetSeriesFreeSpace()
|
||||||
|
{
|
||||||
|
var seriesRootPaths = _seriesService.GetAllSeries().Select(s => _diskProvider.GetPathRoot(s.Path)).Distinct();
|
||||||
|
|
||||||
|
return GetDiskSpace(seriesRootPaths);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<DiskSpace> GetDroneFactoryFreeSpace()
|
||||||
|
{
|
||||||
|
if (!String.IsNullOrWhiteSpace(_configService.DownloadedEpisodesFolder))
|
||||||
|
{
|
||||||
|
return GetDiskSpace(new[] { _diskProvider.GetPathRoot(_configService.DownloadedEpisodesFolder) });
|
||||||
|
}
|
||||||
|
|
||||||
|
return new List<DiskSpace>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<DiskSpace> GetFixedDisksFreeSpace()
|
||||||
|
{
|
||||||
|
return GetDiskSpace(_diskProvider.GetFixedDrives());
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<DiskSpace> GetDiskSpace(IEnumerable<String> paths)
|
||||||
|
{
|
||||||
|
foreach (var path in paths)
|
||||||
|
{
|
||||||
|
DiskSpace diskSpace = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var freeSpace = _diskProvider.GetAvailableSpace(path).Value;
|
||||||
|
var totalSpace = _diskProvider.GetTotalSize(path).Value;
|
||||||
|
|
||||||
|
diskSpace = new DiskSpace
|
||||||
|
{
|
||||||
|
Path = path,
|
||||||
|
FreeSpace = freeSpace,
|
||||||
|
TotalSpace = totalSpace
|
||||||
|
};
|
||||||
|
|
||||||
|
diskSpace.Label = _diskProvider.GetVolumeLabel(path);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.WarnException("Unable to get free space for: " + path, ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (diskSpace != null)
|
||||||
|
{
|
||||||
|
yield return diskSpace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ using NLog;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Common.Serializer;
|
using NzbDrone.Common.Serializer;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download.Clients.Nzbget
|
namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||||
|
@ -12,12 +13,14 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||||
{
|
{
|
||||||
private readonly IConfigService _configService;
|
private readonly IConfigService _configService;
|
||||||
private readonly IHttpProvider _httpProvider;
|
private readonly IHttpProvider _httpProvider;
|
||||||
|
private readonly IParsingService _parsingService;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public NzbgetClient(IConfigService configService, IHttpProvider httpProvider, Logger logger)
|
public NzbgetClient(IConfigService configService, IHttpProvider httpProvider, IParsingService parsingService, Logger logger)
|
||||||
{
|
{
|
||||||
_configService = configService;
|
_configService = configService;
|
||||||
_httpProvider = httpProvider;
|
_httpProvider = httpProvider;
|
||||||
|
_parsingService = parsingService;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +78,14 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||||
queueItem.Size = nzbGetQueueItem.FileSizeMb;
|
queueItem.Size = nzbGetQueueItem.FileSizeMb;
|
||||||
queueItem.Sizeleft = nzbGetQueueItem.RemainingSizeMb;
|
queueItem.Sizeleft = nzbGetQueueItem.RemainingSizeMb;
|
||||||
|
|
||||||
|
var parsedEpisodeInfo = Parser.Parser.ParseTitle(queueItem.Title);
|
||||||
|
if (parsedEpisodeInfo == null) continue;
|
||||||
|
|
||||||
|
var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0);
|
||||||
|
if (remoteEpisode.Series == null) continue;
|
||||||
|
|
||||||
|
queueItem.RemoteEpisode = remoteEpisode;
|
||||||
|
|
||||||
yield return queueItem;
|
yield return queueItem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ using NzbDrone.Common;
|
||||||
using NzbDrone.Common.Cache;
|
using NzbDrone.Common.Cache;
|
||||||
using NzbDrone.Common.Serializer;
|
using NzbDrone.Common.Serializer;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using RestSharp;
|
using RestSharp;
|
||||||
|
|
||||||
|
@ -53,13 +54,19 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||||
{
|
{
|
||||||
private readonly IConfigService _configService;
|
private readonly IConfigService _configService;
|
||||||
private readonly IHttpProvider _httpProvider;
|
private readonly IHttpProvider _httpProvider;
|
||||||
|
private readonly IParsingService _parsingService;
|
||||||
private readonly ICached<IEnumerable<QueueItem>> _queueCache;
|
private readonly ICached<IEnumerable<QueueItem>> _queueCache;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public SabnzbdClient(IConfigService configService, IHttpProvider httpProvider, ICacheManger cacheManger, Logger logger)
|
public SabnzbdClient(IConfigService configService,
|
||||||
|
IHttpProvider httpProvider,
|
||||||
|
ICacheManger cacheManger,
|
||||||
|
IParsingService parsingService,
|
||||||
|
Logger logger)
|
||||||
{
|
{
|
||||||
_configService = configService;
|
_configService = configService;
|
||||||
_httpProvider = httpProvider;
|
_httpProvider = httpProvider;
|
||||||
|
_parsingService = parsingService;
|
||||||
_queueCache = cacheManger.GetCache<IEnumerable<QueueItem>>(GetType(), "queue");
|
_queueCache = cacheManger.GetCache<IEnumerable<QueueItem>>(GetType(), "queue");
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
@ -121,6 +128,14 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||||
queueItem.Timeleft = sabQueueItem.Timeleft;
|
queueItem.Timeleft = sabQueueItem.Timeleft;
|
||||||
queueItem.Status = sabQueueItem.Status;
|
queueItem.Status = sabQueueItem.Status;
|
||||||
|
|
||||||
|
var parsedEpisodeInfo = Parser.Parser.ParseTitle(queueItem.Title);
|
||||||
|
if (parsedEpisodeInfo == null) continue;
|
||||||
|
|
||||||
|
var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0);
|
||||||
|
if (remoteEpisode.Series == null) continue;
|
||||||
|
|
||||||
|
queueItem.RemoteEpisode = remoteEpisode;
|
||||||
|
|
||||||
queueItems.Add(queueItem);
|
queueItems.Add(queueItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,5 +9,4 @@ namespace NzbDrone.Core.Download
|
||||||
bool IsConfigured { get; }
|
bool IsConfigured { get; }
|
||||||
IEnumerable<QueueItem> GetQueue();
|
IEnumerable<QueueItem> GetQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Download
|
namespace NzbDrone.Core.Download
|
||||||
{
|
{
|
||||||
|
@ -10,5 +11,6 @@ namespace NzbDrone.Core.Download
|
||||||
public decimal Sizeleft { get; set; }
|
public decimal Sizeleft { get; set; }
|
||||||
public TimeSpan Timeleft { get; set; }
|
public TimeSpan Timeleft { get; set; }
|
||||||
public String Status { get; set; }
|
public String Status { get; set; }
|
||||||
|
public RemoteEpisode RemoteEpisode { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Core.Datastore;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Housekeeping.Housekeepers
|
||||||
|
{
|
||||||
|
public class CleanupOrphanedEpisodeFiles : IHousekeepingTask
|
||||||
|
{
|
||||||
|
private readonly IDatabase _database;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
public CleanupOrphanedEpisodeFiles(IDatabase database, Logger logger)
|
||||||
|
{
|
||||||
|
_database = database;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clean()
|
||||||
|
{
|
||||||
|
_logger.Trace("Running orphaned episode files cleanup");
|
||||||
|
|
||||||
|
var mapper = _database.GetDataMapper();
|
||||||
|
|
||||||
|
mapper.ExecuteNonQuery(@"DELETE FROM EpisodeFiles
|
||||||
|
WHERE Id IN (
|
||||||
|
SELECT EpisodeFiles.Id FROM EpisodeFiles
|
||||||
|
LEFT OUTER JOIN Episodes
|
||||||
|
ON EpisodeFiles.Id = Episodes.EpisodeFileId
|
||||||
|
WHERE Episodes.Id IS NULL)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,13 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using NzbDrone.Core.Lifecycle;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Housekeeping
|
namespace NzbDrone.Core.Housekeeping
|
||||||
{
|
{
|
||||||
public class HousekeepingService : IExecute<HousekeepingCommand>
|
public class HousekeepingService : IExecute<HousekeepingCommand>, IHandleAsync<ApplicationStartedEvent>
|
||||||
{
|
{
|
||||||
private readonly IEnumerable<IHousekeepingTask> _housekeepers;
|
private readonly IEnumerable<IHousekeepingTask> _housekeepers;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
@ -16,7 +18,7 @@ namespace NzbDrone.Core.Housekeeping
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Execute(HousekeepingCommand message)
|
private void Clean()
|
||||||
{
|
{
|
||||||
_logger.Info("Running housecleaning tasks");
|
_logger.Info("Running housecleaning tasks");
|
||||||
|
|
||||||
|
@ -32,5 +34,15 @@ namespace NzbDrone.Core.Housekeeping
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Execute(HousekeepingCommand message)
|
||||||
|
{
|
||||||
|
Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void HandleAsync(ApplicationStartedEvent message)
|
||||||
|
{
|
||||||
|
Clean();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,6 @@ namespace NzbDrone.Core.Indexers
|
||||||
|
|
||||||
_logger.Debug("Available indexers {0}", indexers.Count);
|
_logger.Debug("Available indexers {0}", indexers.Count);
|
||||||
|
|
||||||
|
|
||||||
var taskList = new List<Task>();
|
var taskList = new List<Task>();
|
||||||
var taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.None);
|
var taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.None);
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace NzbDrone.Core.Indexers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProviderDefinition Definition { get; set; }
|
public virtual ProviderDefinition Definition { get; set; }
|
||||||
|
|
||||||
public abstract DownloadProtocol Protocol { get; }
|
public abstract DownloadProtocol Protocol { get; }
|
||||||
|
|
||||||
|
@ -49,7 +49,6 @@ namespace NzbDrone.Core.Indexers
|
||||||
public abstract IEnumerable<string> GetDailyEpisodeSearchUrls(string seriesTitle, int tvRageId, DateTime date);
|
public abstract IEnumerable<string> GetDailyEpisodeSearchUrls(string seriesTitle, int tvRageId, DateTime date);
|
||||||
public abstract IEnumerable<string> GetSeasonSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int offset);
|
public abstract IEnumerable<string> GetSeasonSearchUrls(string seriesTitle, int tvRageId, int seasonNumber, int offset);
|
||||||
|
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return GetType().Name;
|
return GetType().Name;
|
||||||
|
|
|
@ -4,5 +4,6 @@ namespace NzbDrone.Core.Indexers
|
||||||
{
|
{
|
||||||
public class IndexerDefinition : ProviderDefinition
|
public class IndexerDefinition : ProviderDefinition
|
||||||
{
|
{
|
||||||
|
public bool Enable { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,8 @@
|
||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using NzbDrone.Common.Composition;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Indexers
|
namespace NzbDrone.Core.Indexers
|
||||||
|
@ -14,12 +16,14 @@ namespace NzbDrone.Core.Indexers
|
||||||
{
|
{
|
||||||
private readonly IIndexerRepository _providerRepository;
|
private readonly IIndexerRepository _providerRepository;
|
||||||
private readonly IEnumerable<IIndexer> _providers;
|
private readonly IEnumerable<IIndexer> _providers;
|
||||||
|
private readonly INewznabTestService _newznabTestService;
|
||||||
|
|
||||||
public IndexerFactory(IIndexerRepository providerRepository, IEnumerable<IIndexer> providers, Logger logger)
|
public IndexerFactory(IIndexerRepository providerRepository, IEnumerable<IIndexer> providers, IContainer container, INewznabTestService newznabTestService, Logger logger)
|
||||||
: base(providerRepository, providers, logger)
|
: base(providerRepository, providers, container, logger)
|
||||||
{
|
{
|
||||||
_providerRepository = providerRepository;
|
_providerRepository = providerRepository;
|
||||||
_providers = providers;
|
_providers = providers;
|
||||||
|
_newznabTestService = newznabTestService;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void InitializeProviders()
|
protected override void InitializeProviders()
|
||||||
|
@ -31,11 +35,26 @@ namespace NzbDrone.Core.Indexers
|
||||||
|
|
||||||
var newProviders = definitions.Where(def => currentProviders.All(c => c.Implementation != def.Implementation)).ToList();
|
var newProviders = definitions.Where(def => currentProviders.All(c => c.Implementation != def.Implementation)).ToList();
|
||||||
|
|
||||||
|
|
||||||
if (newProviders.Any())
|
if (newProviders.Any())
|
||||||
{
|
{
|
||||||
_providerRepository.InsertMany(newProviders.Cast<IndexerDefinition>().ToList());
|
_providerRepository.InsertMany(newProviders.Cast<IndexerDefinition>().ToList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override List<IndexerDefinition> Active()
|
||||||
|
{
|
||||||
|
return base.Active().Where(c => c.Enable).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IndexerDefinition Create(IndexerDefinition definition)
|
||||||
|
{
|
||||||
|
if (definition.Implementation == typeof(Newznab.Newznab).Name)
|
||||||
|
{
|
||||||
|
var indexer = GetInstance(definition);
|
||||||
|
_newznabTestService.Test(indexer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.Create(definition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -52,6 +52,8 @@ namespace NzbDrone.Core.Indexers.Newznab
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override ProviderDefinition Definition { get; set; }
|
||||||
|
|
||||||
private NewznabSettings GetSettings(string url, List<int> categories)
|
private NewznabSettings GetSettings(string url, List<int> categories)
|
||||||
{
|
{
|
||||||
var settings = new NewznabSettings { Url = url };
|
var settings = new NewznabSettings { Url = url };
|
||||||
|
|
|
@ -16,7 +16,6 @@ namespace NzbDrone.Core.Indexers.Newznab
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class NewznabSettings : IProviderConfig
|
public class NewznabSettings : IProviderConfig
|
||||||
{
|
{
|
||||||
private static readonly NewznabSettingsValidator Validator = new NewznabSettingsValidator();
|
private static readonly NewznabSettingsValidator Validator = new NewznabSettingsValidator();
|
||||||
|
|
|
@ -94,6 +94,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
{
|
{
|
||||||
return decisions.Where(c => c.Approved)
|
return decisions.Where(c => c.Approved)
|
||||||
.OrderByDescending(c => c.LocalEpisode.Quality)
|
.OrderByDescending(c => c.LocalEpisode.Quality)
|
||||||
|
.ThenByDescending(c => c.LocalEpisode.Size)
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,7 +119,6 @@ namespace NzbDrone.Core.MetadataSource
|
||||||
episode.SeasonNumber = traktEpisode.season;
|
episode.SeasonNumber = traktEpisode.season;
|
||||||
episode.EpisodeNumber = traktEpisode.episode;
|
episode.EpisodeNumber = traktEpisode.episode;
|
||||||
episode.EpisodeNumber = traktEpisode.number;
|
episode.EpisodeNumber = traktEpisode.number;
|
||||||
episode.TvDbEpisodeId = traktEpisode.tvdb_id;
|
|
||||||
episode.Title = traktEpisode.title;
|
episode.Title = traktEpisode.title;
|
||||||
episode.AirDate = FromIsoToString(traktEpisode.first_aired_iso);
|
episode.AirDate = FromIsoToString(traktEpisode.first_aired_iso);
|
||||||
episode.AirDateUtc = FromIso(traktEpisode.first_aired_iso);
|
episode.AirDateUtc = FromIso(traktEpisode.first_aired_iso);
|
||||||
|
|
|
@ -12,16 +12,6 @@ namespace NzbDrone.Core.Notifications.Email
|
||||||
_smtpProvider = smtpProvider;
|
_smtpProvider = smtpProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Name
|
|
||||||
{
|
|
||||||
get { return "Email"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ImplementationName
|
|
||||||
{
|
|
||||||
get { return "Email"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string Link
|
public override string Link
|
||||||
{
|
{
|
||||||
get { return null; }
|
get { return null; }
|
||||||
|
|
|
@ -1,12 +1,26 @@
|
||||||
using System;
|
using System;
|
||||||
|
using FluentValidation;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NzbDrone.Core.Annotations;
|
using NzbDrone.Core.Annotations;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Email
|
namespace NzbDrone.Core.Notifications.Email
|
||||||
{
|
{
|
||||||
|
public class EmailSettingsValidator : AbstractValidator<EmailSettings>
|
||||||
|
{
|
||||||
|
public EmailSettingsValidator()
|
||||||
|
{
|
||||||
|
RuleFor(c => c.Server).NotEmpty();
|
||||||
|
RuleFor(c => c.Port).GreaterThan(0);
|
||||||
|
RuleFor(c => c.From).NotEmpty();
|
||||||
|
RuleFor(c => c.To).NotEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class EmailSettings : IProviderConfig
|
public class EmailSettings : IProviderConfig
|
||||||
{
|
{
|
||||||
|
private static readonly EmailSettingsValidator Validator = new EmailSettingsValidator();
|
||||||
|
|
||||||
public EmailSettings()
|
public EmailSettings()
|
||||||
{
|
{
|
||||||
Port = 25;
|
Port = 25;
|
||||||
|
@ -43,7 +57,7 @@ namespace NzbDrone.Core.Notifications.Email
|
||||||
|
|
||||||
public ValidationResult Validate()
|
public ValidationResult Validate()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return Validator.Validate(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,16 +11,6 @@ namespace NzbDrone.Core.Notifications.Growl
|
||||||
_growlProvider = growlProvider;
|
_growlProvider = growlProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Name
|
|
||||||
{
|
|
||||||
get { return "Growl"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ImplementationName
|
|
||||||
{
|
|
||||||
get { return "Growl"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string Link
|
public override string Link
|
||||||
{
|
{
|
||||||
get { return "http://growl.info/"; }
|
get { return "http://growl.info/"; }
|
||||||
|
|
|
@ -1,12 +1,24 @@
|
||||||
using System;
|
using System;
|
||||||
|
using FluentValidation;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NzbDrone.Core.Annotations;
|
using NzbDrone.Core.Annotations;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Growl
|
namespace NzbDrone.Core.Notifications.Growl
|
||||||
{
|
{
|
||||||
|
public class GrowlSettingsValidator : AbstractValidator<GrowlSettings>
|
||||||
|
{
|
||||||
|
public GrowlSettingsValidator()
|
||||||
|
{
|
||||||
|
RuleFor(c => c.Host).NotEmpty();
|
||||||
|
RuleFor(c => c.Port).GreaterThan(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class GrowlSettings : IProviderConfig
|
public class GrowlSettings : IProviderConfig
|
||||||
{
|
{
|
||||||
|
private static readonly GrowlSettingsValidator Validator = new GrowlSettingsValidator();
|
||||||
|
|
||||||
public GrowlSettings()
|
public GrowlSettings()
|
||||||
{
|
{
|
||||||
Port = 23053;
|
Port = 23053;
|
||||||
|
@ -31,7 +43,7 @@ namespace NzbDrone.Core.Notifications.Growl
|
||||||
|
|
||||||
public ValidationResult Validate()
|
public ValidationResult Validate()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return Validator.Validate(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications
|
namespace NzbDrone.Core.Notifications
|
||||||
{
|
{
|
||||||
public interface INotification
|
public interface INotification : IProvider
|
||||||
{
|
{
|
||||||
string Name { get; }
|
|
||||||
string ImplementationName { get; }
|
|
||||||
string Link { get; }
|
string Link { get; }
|
||||||
|
|
||||||
NotificationDefinition InstanceDefinition { get; set; }
|
|
||||||
|
|
||||||
void OnGrab(string message);
|
void OnGrab(string message);
|
||||||
void OnDownload(string message, Series series);
|
void OnDownload(string message, Series series);
|
||||||
void AfterRename(Series series);
|
void AfterRename(Series series);
|
||||||
|
|
|
@ -1,28 +1,47 @@
|
||||||
using NzbDrone.Common.Serializer;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications
|
namespace NzbDrone.Core.Notifications
|
||||||
{
|
{
|
||||||
public abstract class NotificationBase<TSetting> : INotification where TSetting : class, IProviderConfig, new()
|
public abstract class NotificationBase<TSettings> : INotification where TSettings : IProviderConfig, new()
|
||||||
{
|
{
|
||||||
public abstract string Name { get; }
|
public Type ConfigContract
|
||||||
public abstract string ImplementationName { get; }
|
{
|
||||||
public abstract string Link { get; }
|
get
|
||||||
|
{
|
||||||
|
return typeof(TSettings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public NotificationDefinition InstanceDefinition { get; set; }
|
public IEnumerable<ProviderDefinition> DefaultDefinitions
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new List<ProviderDefinition>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProviderDefinition Definition { get; set; }
|
||||||
|
|
||||||
|
public abstract string Link { get; }
|
||||||
|
|
||||||
public abstract void OnGrab(string message);
|
public abstract void OnGrab(string message);
|
||||||
public abstract void OnDownload(string message, Series series);
|
public abstract void OnDownload(string message, Series series);
|
||||||
public abstract void AfterRename(Series series);
|
public abstract void AfterRename(Series series);
|
||||||
|
|
||||||
public TSetting Settings { get; private set; }
|
protected TSettings Settings
|
||||||
|
|
||||||
public TSetting ImportSettingsFromJson(string json)
|
|
||||||
{
|
{
|
||||||
Settings = Json.Deserialize<TSetting>(json) ?? new TSetting();
|
get
|
||||||
|
{
|
||||||
|
return (TSettings)Definition.Settings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Settings;
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return GetType().Name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using NzbDrone.Core.Datastore;
|
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications
|
namespace NzbDrone.Core.Notifications
|
||||||
{
|
{
|
||||||
public class NotificationDefinition : ModelBase
|
public class NotificationDefinition : ProviderDefinition
|
||||||
{
|
|
||||||
public String Name { get; set; }
|
|
||||||
public Boolean OnGrab { get; set; }
|
|
||||||
public Boolean OnDownload { get; set; }
|
|
||||||
public String Settings { get; set; }
|
|
||||||
public String Implementation { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public class NotificationProviderModel : ProviderDefinition
|
|
||||||
{
|
{
|
||||||
public Boolean OnGrab { get; set; }
|
public Boolean OnGrab { get; set; }
|
||||||
public Boolean OnDownload { get; set; }
|
public Boolean OnDownload { get; set; }
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common.Composition;
|
||||||
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Notifications
|
||||||
|
{
|
||||||
|
public interface INotificationFactory : IProviderFactory<INotification, NotificationDefinition>
|
||||||
|
{
|
||||||
|
List<INotification> OnGrabEnabled();
|
||||||
|
List<INotification> OnDownloadEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NotificationFactory : ProviderFactory<INotification, NotificationDefinition>, INotificationFactory
|
||||||
|
{
|
||||||
|
private IEnumerable<INotification> _providers;
|
||||||
|
|
||||||
|
public NotificationFactory(INotificationRepository providerRepository, IEnumerable<INotification> providers, IContainer container, Logger logger)
|
||||||
|
: base(providerRepository, providers, container, logger)
|
||||||
|
{
|
||||||
|
_providers = providers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<INotification> OnGrabEnabled()
|
||||||
|
{
|
||||||
|
return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnGrab).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<INotification> OnDownloadEnabled()
|
||||||
|
{
|
||||||
|
return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnDownload).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,32 +1,20 @@
|
||||||
using System;
|
using NzbDrone.Core.Datastore;
|
||||||
using System.Linq;
|
|
||||||
using NzbDrone.Core.Datastore;
|
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications
|
namespace NzbDrone.Core.Notifications
|
||||||
{
|
{
|
||||||
public interface INotificationRepository : IBasicRepository<NotificationDefinition>
|
public interface INotificationRepository : IProviderRepository<NotificationDefinition>
|
||||||
{
|
{
|
||||||
NotificationDefinition Get(string name);
|
|
||||||
NotificationDefinition Find(string name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NotificationRepository : BasicRepository<NotificationDefinition>, INotificationRepository
|
public class NotificationRepository : ProviderRepository<NotificationDefinition>, INotificationRepository
|
||||||
{
|
{
|
||||||
public NotificationRepository(IDatabase database, IEventAggregator eventAggregator)
|
public NotificationRepository(IDatabase database, IEventAggregator eventAggregator)
|
||||||
: base(database, eventAggregator)
|
: base(database, eventAggregator)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public NotificationDefinition Get(string name)
|
|
||||||
{
|
|
||||||
return Query.Single(i => i.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase));
|
|
||||||
}
|
|
||||||
|
|
||||||
public NotificationDefinition Find(string name)
|
|
||||||
{
|
|
||||||
return Query.SingleOrDefault(i => i.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -13,126 +13,20 @@ using Omu.ValueInjecter;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications
|
namespace NzbDrone.Core.Notifications
|
||||||
{
|
{
|
||||||
public interface INotificationService
|
|
||||||
{
|
|
||||||
List<Notification> All();
|
|
||||||
Notification Get(int id);
|
|
||||||
List<Notification> Schema();
|
|
||||||
Notification Create(Notification notification);
|
|
||||||
void Update(Notification notification);
|
|
||||||
void Delete(int id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class NotificationService
|
public class NotificationService
|
||||||
: INotificationService,
|
: IHandle<EpisodeGrabbedEvent>,
|
||||||
IHandle<EpisodeGrabbedEvent>,
|
|
||||||
IHandle<EpisodeDownloadedEvent>,
|
IHandle<EpisodeDownloadedEvent>,
|
||||||
IHandle<SeriesRenamedEvent>
|
IHandle<SeriesRenamedEvent>
|
||||||
{
|
{
|
||||||
private readonly INotificationRepository _notificationRepository;
|
private readonly INotificationFactory _notificationFactory;
|
||||||
private readonly IContainer _container;
|
|
||||||
private readonly List<INotification> _notifications;
|
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public NotificationService(INotificationRepository notificationRepository,
|
public NotificationService(INotificationFactory notificationFactory, Logger logger)
|
||||||
IEnumerable<INotification> notifications,
|
|
||||||
IContainer container,
|
|
||||||
Logger logger)
|
|
||||||
{
|
{
|
||||||
_notificationRepository = notificationRepository;
|
_notificationFactory = notificationFactory;
|
||||||
_container = container;
|
|
||||||
_notifications = notifications.ToList();
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Notification> All()
|
|
||||||
{
|
|
||||||
return _notificationRepository.All().Select(ToNotification).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Notification Get(int id)
|
|
||||||
{
|
|
||||||
return ToNotification(_notificationRepository.Get(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Notification> Schema()
|
|
||||||
{
|
|
||||||
var notifications = new List<Notification>();
|
|
||||||
|
|
||||||
int i = 1;
|
|
||||||
foreach (var notification in _notifications)
|
|
||||||
{
|
|
||||||
var type = notification.GetType();
|
|
||||||
|
|
||||||
var newNotification = new Notification();
|
|
||||||
newNotification.Instance = (INotification)_container.Resolve(type);
|
|
||||||
newNotification.Id = i;
|
|
||||||
newNotification.ImplementationName = notification.ImplementationName;
|
|
||||||
newNotification.Link = notification.Link;
|
|
||||||
|
|
||||||
var instanceType = newNotification.Instance.GetType();
|
|
||||||
var baseGenArgs = instanceType.BaseType.GetGenericArguments();
|
|
||||||
newNotification.Settings = (IProviderConfig)Activator.CreateInstance(baseGenArgs[0]);
|
|
||||||
newNotification.Implementation = type.Name;
|
|
||||||
|
|
||||||
notifications.Add(newNotification);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return notifications.OrderBy(n => n.Name).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Notification Create(Notification notification)
|
|
||||||
{
|
|
||||||
var definition = new NotificationDefinition();
|
|
||||||
definition.InjectFrom(notification);
|
|
||||||
definition.Settings = notification.Settings.ToJson();
|
|
||||||
|
|
||||||
definition = _notificationRepository.Insert(definition);
|
|
||||||
notification.Id = definition.Id;
|
|
||||||
|
|
||||||
return notification;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Update(Notification notification)
|
|
||||||
{
|
|
||||||
var definition = _notificationRepository.Get(notification.Id);
|
|
||||||
definition.InjectFrom(notification);
|
|
||||||
definition.Settings = notification.Settings.ToJson();
|
|
||||||
|
|
||||||
_notificationRepository.Update(definition);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Delete(int id)
|
|
||||||
{
|
|
||||||
_notificationRepository.Delete(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Notification ToNotification(NotificationDefinition definition)
|
|
||||||
{
|
|
||||||
var notification = new Notification();
|
|
||||||
notification.Id = definition.Id;
|
|
||||||
notification.OnGrab = definition.OnGrab;
|
|
||||||
notification.OnDownload = definition.OnDownload;
|
|
||||||
notification.Instance = GetInstance(definition);
|
|
||||||
notification.Name = definition.Name;
|
|
||||||
notification.Implementation = definition.Implementation;
|
|
||||||
notification.ImplementationName = notification.Instance.ImplementationName;
|
|
||||||
notification.Settings = ((dynamic)notification.Instance).ImportSettingsFromJson(definition.Settings);
|
|
||||||
|
|
||||||
return notification;
|
|
||||||
}
|
|
||||||
|
|
||||||
private INotification GetInstance(NotificationDefinition indexerDefinition)
|
|
||||||
{
|
|
||||||
var type = _notifications.Single(c => c.GetType().Name.Equals(indexerDefinition.Implementation, StringComparison.InvariantCultureIgnoreCase)).GetType();
|
|
||||||
|
|
||||||
var instance = (INotification)_container.Resolve(type);
|
|
||||||
|
|
||||||
instance.InstanceDefinition = indexerDefinition;
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetMessage(Series series, List<Episode> episodes, QualityModel quality)
|
private string GetMessage(Series series, List<Episode> episodes, QualityModel quality)
|
||||||
{
|
{
|
||||||
if (series.SeriesType == SeriesTypes.Daily)
|
if (series.SeriesType == SeriesTypes.Daily)
|
||||||
|
@ -163,16 +57,16 @@ namespace NzbDrone.Core.Notifications
|
||||||
{
|
{
|
||||||
var messageBody = GetMessage(message.Episode.Series, message.Episode.Episodes, message.Episode.ParsedEpisodeInfo.Quality);
|
var messageBody = GetMessage(message.Episode.Series, message.Episode.Episodes, message.Episode.ParsedEpisodeInfo.Quality);
|
||||||
|
|
||||||
foreach (var notification in All().Where(n => n.OnGrab))
|
foreach (var notification in _notificationFactory.OnGrabEnabled())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
notification.Instance.OnGrab(messageBody);
|
notification.OnGrab(messageBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Unable to send OnGrab notification to: " + notification.Name, ex);
|
_logger.ErrorException("Unable to send OnGrab notification to: " + notification.Definition.Name, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,32 +75,32 @@ namespace NzbDrone.Core.Notifications
|
||||||
{
|
{
|
||||||
var messageBody = GetMessage(message.Episode.Series, message.Episode.Episodes, message.Episode.ParsedEpisodeInfo.Quality);
|
var messageBody = GetMessage(message.Episode.Series, message.Episode.Episodes, message.Episode.ParsedEpisodeInfo.Quality);
|
||||||
|
|
||||||
foreach (var notification in All().Where(n => n.OnDownload))
|
foreach (var notification in _notificationFactory.OnDownloadEnabled())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
notification.Instance.OnDownload(messageBody, message.Episode.Series);
|
notification.OnDownload(messageBody, message.Episode.Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.WarnException("Unable to send OnDownload notification to: " + notification.Name, ex);
|
_logger.WarnException("Unable to send OnDownload notification to: " + notification.Definition.Name, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Handle(SeriesRenamedEvent message)
|
public void Handle(SeriesRenamedEvent message)
|
||||||
{
|
{
|
||||||
foreach (var notification in All().Where(n => n.OnDownload))
|
foreach (var notification in _notificationFactory.OnDownloadEnabled())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
notification.Instance.AfterRename(message.Series);
|
notification.AfterRename(message.Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.WarnException("Unable to send AfterRename notification to: " + notification.Name, ex);
|
_logger.WarnException("Unable to send AfterRename notification to: " + notification.Definition.Name, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
using NzbDrone.Common.Serializer;
|
|
||||||
using NzbDrone.Core.ThingiProvider;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications
|
|
||||||
{
|
|
||||||
public interface INotificationSettingsProvider
|
|
||||||
{
|
|
||||||
TSetting Get<TSetting>(INotification indexer) where TSetting : IProviderConfig, new();
|
|
||||||
}
|
|
||||||
|
|
||||||
public class NotificationSettingsProvider : INotificationSettingsProvider
|
|
||||||
{
|
|
||||||
private readonly INotificationRepository _notificationRepository;
|
|
||||||
|
|
||||||
public NotificationSettingsProvider(INotificationRepository notificationRepository)
|
|
||||||
{
|
|
||||||
_notificationRepository = notificationRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TSetting Get<TSetting>(INotification indexer) where TSetting : IProviderConfig, new()
|
|
||||||
{
|
|
||||||
var indexerDef = _notificationRepository.Find(indexer.Name);
|
|
||||||
|
|
||||||
if (indexerDef == null || string.IsNullOrWhiteSpace(indexerDef.Settings))
|
|
||||||
{
|
|
||||||
return new TSetting();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Json.Deserialize<TSetting>(indexerDef.Settings);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -11,16 +11,6 @@ namespace NzbDrone.Core.Notifications.NotifyMyAndroid
|
||||||
_notifyMyAndroidProxy = notifyMyAndroidProxy;
|
_notifyMyAndroidProxy = notifyMyAndroidProxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Name
|
|
||||||
{
|
|
||||||
get { return "NotifyMyAndroid"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ImplementationName
|
|
||||||
{
|
|
||||||
get { return "NotifyMyAndroid"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string Link
|
public override string Link
|
||||||
{
|
{
|
||||||
get { return "http://www.notifymyandroid.com/"; }
|
get { return "http://www.notifymyandroid.com/"; }
|
||||||
|
|
|
@ -1,12 +1,23 @@
|
||||||
using System;
|
using System;
|
||||||
|
using FluentValidation;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NzbDrone.Core.Annotations;
|
using NzbDrone.Core.Annotations;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.NotifyMyAndroid
|
namespace NzbDrone.Core.Notifications.NotifyMyAndroid
|
||||||
{
|
{
|
||||||
|
public class NotifyMyAndroidSettingsValidator : AbstractValidator<NotifyMyAndroidSettings>
|
||||||
|
{
|
||||||
|
public NotifyMyAndroidSettingsValidator()
|
||||||
|
{
|
||||||
|
RuleFor(c => c.ApiKey).NotEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class NotifyMyAndroidSettings : IProviderConfig
|
public class NotifyMyAndroidSettings : IProviderConfig
|
||||||
{
|
{
|
||||||
|
private static readonly NotifyMyAndroidSettingsValidator Validator = new NotifyMyAndroidSettingsValidator();
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "API Key", HelpLink = "http://www.notifymyandroid.com/")]
|
[FieldDefinition(0, Label = "API Key", HelpLink = "http://www.notifymyandroid.com/")]
|
||||||
public String ApiKey { get; set; }
|
public String ApiKey { get; set; }
|
||||||
|
|
||||||
|
@ -23,7 +34,7 @@ namespace NzbDrone.Core.Notifications.NotifyMyAndroid
|
||||||
|
|
||||||
public ValidationResult Validate()
|
public ValidationResult Validate()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return Validator.Validate(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,16 +11,6 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||||
_plexProvider = plexProvider;
|
_plexProvider = plexProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Name
|
|
||||||
{
|
|
||||||
get { return "Plex Client"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ImplementationName
|
|
||||||
{
|
|
||||||
get { return "Plex Client"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string Link
|
public override string Link
|
||||||
{
|
{
|
||||||
get { return "http://www.plexapp.com/"; }
|
get { return "http://www.plexapp.com/"; }
|
||||||
|
|
|
@ -1,12 +1,24 @@
|
||||||
using System;
|
using System;
|
||||||
|
using FluentValidation;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NzbDrone.Core.Annotations;
|
using NzbDrone.Core.Annotations;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Plex
|
namespace NzbDrone.Core.Notifications.Plex
|
||||||
{
|
{
|
||||||
|
public class PlexClientSettingsValidator : AbstractValidator<PlexClientSettings>
|
||||||
|
{
|
||||||
|
public PlexClientSettingsValidator()
|
||||||
|
{
|
||||||
|
RuleFor(c => c.Host).NotEmpty();
|
||||||
|
RuleFor(c => c.Port).GreaterThan(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class PlexClientSettings : IProviderConfig
|
public class PlexClientSettings : IProviderConfig
|
||||||
{
|
{
|
||||||
|
private static readonly PlexClientSettingsValidator Validator = new PlexClientSettingsValidator();
|
||||||
|
|
||||||
public PlexClientSettings()
|
public PlexClientSettings()
|
||||||
{
|
{
|
||||||
Port = 3000;
|
Port = 3000;
|
||||||
|
@ -34,7 +46,7 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||||
|
|
||||||
public ValidationResult Validate()
|
public ValidationResult Validate()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return Validator.Validate(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,16 +11,6 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||||
_plexProvider = plexProvider;
|
_plexProvider = plexProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Name
|
|
||||||
{
|
|
||||||
get { return "Plex Server"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ImplementationName
|
|
||||||
{
|
|
||||||
get { return "Plex Server"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string Link
|
public override string Link
|
||||||
{
|
{
|
||||||
get { return "http://www.plexapp.com/"; }
|
get { return "http://www.plexapp.com/"; }
|
||||||
|
|
|
@ -1,12 +1,24 @@
|
||||||
using System;
|
using System;
|
||||||
|
using FluentValidation;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NzbDrone.Core.Annotations;
|
using NzbDrone.Core.Annotations;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Plex
|
namespace NzbDrone.Core.Notifications.Plex
|
||||||
{
|
{
|
||||||
|
public class PlexServerSettingsValidator : AbstractValidator<PlexServerSettings>
|
||||||
|
{
|
||||||
|
public PlexServerSettingsValidator()
|
||||||
|
{
|
||||||
|
RuleFor(c => c.Host).NotEmpty();
|
||||||
|
RuleFor(c => c.Port).GreaterThan(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class PlexServerSettings : IProviderConfig
|
public class PlexServerSettings : IProviderConfig
|
||||||
{
|
{
|
||||||
|
private static readonly PlexServerSettingsValidator Validator = new PlexServerSettingsValidator();
|
||||||
|
|
||||||
public PlexServerSettings()
|
public PlexServerSettings()
|
||||||
{
|
{
|
||||||
Port = 32400;
|
Port = 32400;
|
||||||
|
@ -31,7 +43,7 @@ namespace NzbDrone.Core.Notifications.Plex
|
||||||
|
|
||||||
public ValidationResult Validate()
|
public ValidationResult Validate()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return Validator.Validate(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,16 +12,6 @@ namespace NzbDrone.Core.Notifications.Prowl
|
||||||
_prowlProvider = prowlProvider;
|
_prowlProvider = prowlProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Name
|
|
||||||
{
|
|
||||||
get { return "Prowl"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ImplementationName
|
|
||||||
{
|
|
||||||
get { return "Prowl"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string Link
|
public override string Link
|
||||||
{
|
{
|
||||||
get { return "http://www.prowlapp.com/"; }
|
get { return "http://www.prowlapp.com/"; }
|
||||||
|
|
|
@ -1,12 +1,23 @@
|
||||||
using System;
|
using System;
|
||||||
|
using FluentValidation;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NzbDrone.Core.Annotations;
|
using NzbDrone.Core.Annotations;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Prowl
|
namespace NzbDrone.Core.Notifications.Prowl
|
||||||
{
|
{
|
||||||
|
public class ProwlSettingsValidator : AbstractValidator<ProwlSettings>
|
||||||
|
{
|
||||||
|
public ProwlSettingsValidator()
|
||||||
|
{
|
||||||
|
RuleFor(c => c.ApiKey).NotEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class ProwlSettings : IProviderConfig
|
public class ProwlSettings : IProviderConfig
|
||||||
{
|
{
|
||||||
|
private static readonly ProwlSettingsValidator Validator = new ProwlSettingsValidator();
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "API Key", HelpLink = "https://www.prowlapp.com/api_settings.php")]
|
[FieldDefinition(0, Label = "API Key", HelpLink = "https://www.prowlapp.com/api_settings.php")]
|
||||||
public String ApiKey { get; set; }
|
public String ApiKey { get; set; }
|
||||||
|
|
||||||
|
@ -23,7 +34,7 @@ namespace NzbDrone.Core.Notifications.Prowl
|
||||||
|
|
||||||
public ValidationResult Validate()
|
public ValidationResult Validate()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return Validator.Validate(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,16 +11,6 @@ namespace NzbDrone.Core.Notifications.PushBullet
|
||||||
_pushBulletProxy = pushBulletProxy;
|
_pushBulletProxy = pushBulletProxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Name
|
|
||||||
{
|
|
||||||
get { return "PushBullet"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ImplementationName
|
|
||||||
{
|
|
||||||
get { return "PushBullet"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string Link
|
public override string Link
|
||||||
{
|
{
|
||||||
get { return "https://www.pushbullet.com/"; }
|
get { return "https://www.pushbullet.com/"; }
|
||||||
|
|
|
@ -1,12 +1,24 @@
|
||||||
using System;
|
using System;
|
||||||
|
using FluentValidation;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NzbDrone.Core.Annotations;
|
using NzbDrone.Core.Annotations;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.PushBullet
|
namespace NzbDrone.Core.Notifications.PushBullet
|
||||||
{
|
{
|
||||||
|
public class PushBulletSettingsValidator : AbstractValidator<PushBulletSettings>
|
||||||
|
{
|
||||||
|
public PushBulletSettingsValidator()
|
||||||
|
{
|
||||||
|
RuleFor(c => c.ApiKey).NotEmpty();
|
||||||
|
RuleFor(c => c.DeviceId).GreaterThan(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class PushBulletSettings : IProviderConfig
|
public class PushBulletSettings : IProviderConfig
|
||||||
{
|
{
|
||||||
|
private static readonly PushBulletSettingsValidator Validator = new PushBulletSettingsValidator();
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "API Key", HelpLink = "https://www.pushbullet.com/")]
|
[FieldDefinition(0, Label = "API Key", HelpLink = "https://www.pushbullet.com/")]
|
||||||
public String ApiKey { get; set; }
|
public String ApiKey { get; set; }
|
||||||
|
|
||||||
|
@ -23,7 +35,7 @@ namespace NzbDrone.Core.Notifications.PushBullet
|
||||||
|
|
||||||
public ValidationResult Validate()
|
public ValidationResult Validate()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return Validator.Validate(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,16 +11,6 @@ namespace NzbDrone.Core.Notifications.Pushover
|
||||||
_pushoverProxy = pushoverProxy;
|
_pushoverProxy = pushoverProxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Name
|
|
||||||
{
|
|
||||||
get { return "Pushover"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ImplementationName
|
|
||||||
{
|
|
||||||
get { return "Pushover"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string Link
|
public override string Link
|
||||||
{
|
{
|
||||||
get { return "https://pushover.net/"; }
|
get { return "https://pushover.net/"; }
|
||||||
|
|
|
@ -1,12 +1,23 @@
|
||||||
using System;
|
using System;
|
||||||
|
using FluentValidation;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using NzbDrone.Core.Annotations;
|
using NzbDrone.Core.Annotations;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Pushover
|
namespace NzbDrone.Core.Notifications.Pushover
|
||||||
{
|
{
|
||||||
|
public class PushoverSettingsValidator : AbstractValidator<PushoverSettings>
|
||||||
|
{
|
||||||
|
public PushoverSettingsValidator()
|
||||||
|
{
|
||||||
|
RuleFor(c => c.UserKey).NotEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class PushoverSettings : IProviderConfig
|
public class PushoverSettings : IProviderConfig
|
||||||
{
|
{
|
||||||
|
private static readonly PushoverSettingsValidator Validator = new PushoverSettingsValidator();
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "User Key", HelpLink = "https://pushover.net/")]
|
[FieldDefinition(0, Label = "User Key", HelpLink = "https://pushover.net/")]
|
||||||
public String UserKey { get; set; }
|
public String UserKey { get; set; }
|
||||||
|
|
||||||
|
@ -23,7 +34,7 @@ namespace NzbDrone.Core.Notifications.Pushover
|
||||||
|
|
||||||
public ValidationResult Validate()
|
public ValidationResult Validate()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return Validator.Validate(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,16 +11,6 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
||||||
_xbmcProvider = xbmcProvider;
|
_xbmcProvider = xbmcProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Name
|
|
||||||
{
|
|
||||||
get { return "XBMC"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ImplementationName
|
|
||||||
{
|
|
||||||
get { return "XBMC"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string Link
|
public override string Link
|
||||||
{
|
{
|
||||||
get { return "http://xbmc.org/"; }
|
get { return "http://xbmc.org/"; }
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using FluentValidation;
|
||||||
using FluentValidation.Results;
|
using FluentValidation.Results;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using NzbDrone.Core.Annotations;
|
using NzbDrone.Core.Annotations;
|
||||||
|
@ -7,8 +8,19 @@ using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Notifications.Xbmc
|
namespace NzbDrone.Core.Notifications.Xbmc
|
||||||
{
|
{
|
||||||
|
public class XbmcSettingsValidator : AbstractValidator<XbmcSettings>
|
||||||
|
{
|
||||||
|
public XbmcSettingsValidator()
|
||||||
|
{
|
||||||
|
RuleFor(c => c.Host).NotEmpty();
|
||||||
|
RuleFor(c => c.DisplayTime).GreaterThan(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class XbmcSettings : IProviderConfig
|
public class XbmcSettings : IProviderConfig
|
||||||
{
|
{
|
||||||
|
private static readonly XbmcSettingsValidator Validator = new XbmcSettingsValidator();
|
||||||
|
|
||||||
public XbmcSettings()
|
public XbmcSettings()
|
||||||
{
|
{
|
||||||
DisplayTime = 5;
|
DisplayTime = 5;
|
||||||
|
@ -56,7 +68,7 @@ namespace NzbDrone.Core.Notifications.Xbmc
|
||||||
|
|
||||||
public ValidationResult Validate()
|
public ValidationResult Validate()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return Validator.Validate(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,8 +173,14 @@
|
||||||
<Compile Include="Datastore\Migration\019_restore_unique_constraints.cs" />
|
<Compile Include="Datastore\Migration\019_restore_unique_constraints.cs" />
|
||||||
<Compile Include="Datastore\Migration\020_add_year_and_seasons_to_series.cs" />
|
<Compile Include="Datastore\Migration\020_add_year_and_seasons_to_series.cs" />
|
||||||
<Compile Include="Datastore\Migration\021_drop_seasons_table.cs" />
|
<Compile Include="Datastore\Migration\021_drop_seasons_table.cs" />
|
||||||
<Compile Include="Datastore\Migration\022_move_notification_to_generic_provider.cs" />
|
<Compile Include="Datastore\Migration\022_move_indexer_to_generic_provider.cs" />
|
||||||
<Compile Include="Datastore\Migration\023_add_config_contract_to_indexers.cs" />
|
<Compile Include="Datastore\Migration\023_add_config_contract_to_indexers.cs" />
|
||||||
|
<Compile Include="Datastore\Migration\024_drop_tvdb_episodeid.cs" />
|
||||||
|
<Compile Include="Datastore\Migration\026_add_config_contract_to_notifications.cs" />
|
||||||
|
<Compile Include="Datastore\Migration\025_move_notification_to_generic_provider.cs" />
|
||||||
|
<Compile Include="Datastore\Migration\027_fix_omgwtfnzbs.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Datastore\Migration\Framework\MigrationContext.cs" />
|
<Compile Include="Datastore\Migration\Framework\MigrationContext.cs" />
|
||||||
<Compile Include="Datastore\Migration\Framework\MigrationController.cs" />
|
<Compile Include="Datastore\Migration\Framework\MigrationController.cs" />
|
||||||
<Compile Include="Datastore\Migration\Framework\MigrationExtension.cs" />
|
<Compile Include="Datastore\Migration\Framework\MigrationExtension.cs" />
|
||||||
|
@ -213,6 +219,8 @@
|
||||||
<Compile Include="DecisionEngine\Specifications\Search\SingleEpisodeSearchMatchSpecification.cs" />
|
<Compile Include="DecisionEngine\Specifications\Search\SingleEpisodeSearchMatchSpecification.cs" />
|
||||||
<Compile Include="DecisionEngine\Specifications\UpgradeDiskSpecification.cs" />
|
<Compile Include="DecisionEngine\Specifications\UpgradeDiskSpecification.cs" />
|
||||||
<Compile Include="DecisionEngine\Specifications\RssSync\UpgradeHistorySpecification.cs" />
|
<Compile Include="DecisionEngine\Specifications\RssSync\UpgradeHistorySpecification.cs" />
|
||||||
|
<Compile Include="DiskSpace\DiskSpace.cs" />
|
||||||
|
<Compile Include="DiskSpace\DiskSpaceService.cs" />
|
||||||
<Compile Include="Download\Clients\Sabnzbd\ConnectionInfoModel.cs" />
|
<Compile Include="Download\Clients\Sabnzbd\ConnectionInfoModel.cs" />
|
||||||
<Compile Include="Download\Clients\Sabnzbd\JsonConverters\SabnzbdPriorityTypeConverter.cs" />
|
<Compile Include="Download\Clients\Sabnzbd\JsonConverters\SabnzbdPriorityTypeConverter.cs" />
|
||||||
<Compile Include="Download\Clients\Sabnzbd\JsonConverters\SabnzbdQueueTimeConverter.cs" />
|
<Compile Include="Download\Clients\Sabnzbd\JsonConverters\SabnzbdQueueTimeConverter.cs" />
|
||||||
|
@ -227,6 +235,7 @@
|
||||||
<Compile Include="Exceptions\StatusCodeToExceptions.cs" />
|
<Compile Include="Exceptions\StatusCodeToExceptions.cs" />
|
||||||
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedEpisodes.cs" />
|
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedEpisodes.cs" />
|
||||||
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedHistoryItems.cs" />
|
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedHistoryItems.cs" />
|
||||||
|
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedEpisodeFiles.cs" />
|
||||||
<Compile Include="Housekeeping\HousekeepingCommand.cs" />
|
<Compile Include="Housekeeping\HousekeepingCommand.cs" />
|
||||||
<Compile Include="Housekeeping\HousekeepingService.cs" />
|
<Compile Include="Housekeeping\HousekeepingService.cs" />
|
||||||
<Compile Include="Housekeeping\IHousekeepingTask.cs" />
|
<Compile Include="Housekeeping\IHousekeepingTask.cs" />
|
||||||
|
@ -267,6 +276,8 @@
|
||||||
<Compile Include="Messaging\Events\IEventAggregator.cs" />
|
<Compile Include="Messaging\Events\IEventAggregator.cs" />
|
||||||
<Compile Include="Messaging\Events\IHandle.cs" />
|
<Compile Include="Messaging\Events\IHandle.cs" />
|
||||||
<Compile Include="MetadataSource\Trakt\TraktException.cs" />
|
<Compile Include="MetadataSource\Trakt\TraktException.cs" />
|
||||||
|
<Compile Include="Notifications\NotificationFactory.cs" />
|
||||||
|
<Compile Include="Notifications\NotificationService.cs" />
|
||||||
<Compile Include="Notifications\PushBullet\PushBullet.cs" />
|
<Compile Include="Notifications\PushBullet\PushBullet.cs" />
|
||||||
<Compile Include="Notifications\PushBullet\PushBulletProxy.cs" />
|
<Compile Include="Notifications\PushBullet\PushBulletProxy.cs" />
|
||||||
<Compile Include="Notifications\PushBullet\PushBulletSettings.cs" />
|
<Compile Include="Notifications\PushBullet\PushBulletSettings.cs" />
|
||||||
|
@ -326,10 +337,8 @@
|
||||||
<Compile Include="Notifications\Email\TestEmailCommand.cs" />
|
<Compile Include="Notifications\Email\TestEmailCommand.cs" />
|
||||||
<Compile Include="Notifications\Growl\GrowlSettings.cs" />
|
<Compile Include="Notifications\Growl\GrowlSettings.cs" />
|
||||||
<Compile Include="Notifications\Growl\TestGrowlCommand.cs" />
|
<Compile Include="Notifications\Growl\TestGrowlCommand.cs" />
|
||||||
<Compile Include="Notifications\NotificationSettingsProvider.cs" />
|
|
||||||
<Compile Include="Notifications\INotification.cs" />
|
<Compile Include="Notifications\INotification.cs" />
|
||||||
<Compile Include="Notifications\Notification.cs" />
|
<Compile Include="Notifications\Notification.cs" />
|
||||||
<Compile Include="Notifications\NotificationService.cs" />
|
|
||||||
<Compile Include="Notifications\NotificationRepository.cs" />
|
<Compile Include="Notifications\NotificationRepository.cs" />
|
||||||
<Compile Include="Fluent.cs" />
|
<Compile Include="Fluent.cs" />
|
||||||
<Compile Include="History\HistoryRepository.cs" />
|
<Compile Include="History\HistoryRepository.cs" />
|
||||||
|
|
|
@ -15,13 +15,11 @@ namespace NzbDrone.Core.Queue
|
||||||
public class QueueService : IQueueService
|
public class QueueService : IQueueService
|
||||||
{
|
{
|
||||||
private readonly IProvideDownloadClient _downloadClientProvider;
|
private readonly IProvideDownloadClient _downloadClientProvider;
|
||||||
private readonly IParsingService _parsingService;
|
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public QueueService(IProvideDownloadClient downloadClientProvider, IParsingService parsingService, Logger logger)
|
public QueueService(IProvideDownloadClient downloadClientProvider, Logger logger)
|
||||||
{
|
{
|
||||||
_downloadClientProvider = downloadClientProvider;
|
_downloadClientProvider = downloadClientProvider;
|
||||||
_parsingService = parsingService;
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,31 +37,19 @@ namespace NzbDrone.Core.Queue
|
||||||
|
|
||||||
foreach (var queueItem in queueItems)
|
foreach (var queueItem in queueItems)
|
||||||
{
|
{
|
||||||
var parsedEpisodeInfo = Parser.Parser.ParseTitle(queueItem.Title);
|
foreach (var episode in queueItem.RemoteEpisode.Episodes)
|
||||||
|
|
||||||
if (parsedEpisodeInfo != null && !string.IsNullOrWhiteSpace(parsedEpisodeInfo.SeriesTitle))
|
|
||||||
{
|
{
|
||||||
var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0);
|
var queue = new Queue();
|
||||||
|
queue.Id = queueItem.Id.GetHashCode();
|
||||||
if (remoteEpisode.Series == null)
|
queue.Series = queueItem.RemoteEpisode.Series;
|
||||||
{
|
queue.Episode = episode;
|
||||||
continue;
|
queue.Quality = queueItem.RemoteEpisode.ParsedEpisodeInfo.Quality;
|
||||||
}
|
queue.Title = queueItem.Title;
|
||||||
|
queue.Size = queueItem.Size;
|
||||||
foreach (var episode in remoteEpisode.Episodes)
|
queue.Sizeleft = queueItem.Sizeleft;
|
||||||
{
|
queue.Timeleft = queueItem.Timeleft;
|
||||||
var queue = new Queue();
|
queue.Status = queueItem.Status;
|
||||||
queue.Id = queueItem.Id.GetHashCode();
|
queued.Add(queue);
|
||||||
queue.Series = remoteEpisode.Series;
|
|
||||||
queue.Episode = episode;
|
|
||||||
queue.Quality = remoteEpisode.ParsedEpisodeInfo.Quality;
|
|
||||||
queue.Title = queueItem.Title;
|
|
||||||
queue.Size = queueItem.Size;
|
|
||||||
queue.Sizeleft = queueItem.Sizeleft;
|
|
||||||
queue.Timeleft = queueItem.Timeleft;
|
|
||||||
queue.Status = queueItem.Status;
|
|
||||||
queued.Add(queue);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ namespace NzbDrone.Core.ThingiProvider
|
||||||
private IProviderConfig _settings;
|
private IProviderConfig _settings;
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string Implementation { get; set; }
|
public string Implementation { get; set; }
|
||||||
public bool Enable { get; set; }
|
|
||||||
|
|
||||||
public string ConfigContract { get; set; }
|
public string ConfigContract { get; set; }
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using NzbDrone.Common.Composition;
|
||||||
using NzbDrone.Core.Lifecycle;
|
using NzbDrone.Core.Lifecycle;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
|
||||||
|
@ -12,13 +13,18 @@ namespace NzbDrone.Core.ThingiProvider
|
||||||
where TProvider : IProvider
|
where TProvider : IProvider
|
||||||
{
|
{
|
||||||
private readonly IProviderRepository<TProviderDefinition> _providerRepository;
|
private readonly IProviderRepository<TProviderDefinition> _providerRepository;
|
||||||
|
private readonly IContainer _container;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
private readonly List<TProvider> _providers;
|
private readonly List<TProvider> _providers;
|
||||||
|
|
||||||
protected ProviderFactory(IProviderRepository<TProviderDefinition> providerRepository, IEnumerable<TProvider> providers, Logger logger)
|
protected ProviderFactory(IProviderRepository<TProviderDefinition> providerRepository,
|
||||||
|
IEnumerable<TProvider> providers,
|
||||||
|
IContainer container,
|
||||||
|
Logger logger)
|
||||||
{
|
{
|
||||||
_providerRepository = providerRepository;
|
_providerRepository = providerRepository;
|
||||||
|
_container = container;
|
||||||
_providers = providers.ToList();
|
_providers = providers.ToList();
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
@ -40,8 +46,7 @@ namespace NzbDrone.Core.ThingiProvider
|
||||||
|
|
||||||
public List<TProvider> GetAvailableProviders()
|
public List<TProvider> GetAvailableProviders()
|
||||||
{
|
{
|
||||||
return All().Where(c => c.Enable && c.Settings.Validate().IsValid)
|
return Active().Select(GetInstance).ToList();
|
||||||
.Select(GetInstance).ToList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TProviderDefinition Get(int id)
|
public TProviderDefinition Get(int id)
|
||||||
|
@ -49,12 +54,12 @@ namespace NzbDrone.Core.ThingiProvider
|
||||||
return _providerRepository.Get(id);
|
return _providerRepository.Get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TProviderDefinition Create(TProviderDefinition provider)
|
public virtual TProviderDefinition Create(TProviderDefinition definition)
|
||||||
{
|
{
|
||||||
return _providerRepository.Insert(provider);
|
return _providerRepository.Insert(definition);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update(TProviderDefinition definition)
|
public virtual void Update(TProviderDefinition definition)
|
||||||
{
|
{
|
||||||
_providerRepository.Update(definition);
|
_providerRepository.Update(definition);
|
||||||
}
|
}
|
||||||
|
@ -64,10 +69,10 @@ namespace NzbDrone.Core.ThingiProvider
|
||||||
_providerRepository.Delete(id);
|
_providerRepository.Delete(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TProvider GetInstance(TProviderDefinition definition)
|
protected TProvider GetInstance(TProviderDefinition definition)
|
||||||
{
|
{
|
||||||
var type = GetImplementation(definition);
|
var type = GetImplementation(definition);
|
||||||
var instance = (TProvider)Activator.CreateInstance(type);
|
var instance = (TProvider)_container.Resolve(type);
|
||||||
instance.Definition = definition;
|
instance.Definition = definition;
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
@ -90,6 +95,11 @@ namespace NzbDrone.Core.ThingiProvider
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual List<TProviderDefinition> Active()
|
||||||
|
{
|
||||||
|
return All().Where(c => c.Settings.Validate().IsValid).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
private void RemoveMissingImplementations()
|
private void RemoveMissingImplementations()
|
||||||
{
|
{
|
||||||
var storedProvider = _providerRepository.All();
|
var storedProvider = _providerRepository.All();
|
||||||
|
|
|
@ -11,7 +11,6 @@ namespace NzbDrone.Core.Tv
|
||||||
{
|
{
|
||||||
public const string AIR_DATE_FORMAT = "yyyy-MM-dd";
|
public const string AIR_DATE_FORMAT = "yyyy-MM-dd";
|
||||||
|
|
||||||
public int TvDbEpisodeId { get; set; }
|
|
||||||
public int SeriesId { get; set; }
|
public int SeriesId { get; set; }
|
||||||
public int EpisodeFileId { get; set; }
|
public int EpisodeFileId { get; set; }
|
||||||
public int SeasonNumber { get; set; }
|
public int SeasonNumber { get; set; }
|
||||||
|
@ -39,7 +38,7 @@ namespace NzbDrone.Core.Tv
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return string.Format("[{0}]{1}", TvDbEpisodeId, Title.NullSafe());
|
return string.Format("[{0}]{1}", Id, Title.NullSafe());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -58,7 +58,6 @@ namespace NzbDrone.Core.Tv
|
||||||
}
|
}
|
||||||
|
|
||||||
episodeToUpdate.SeriesId = series.Id;
|
episodeToUpdate.SeriesId = series.Id;
|
||||||
episodeToUpdate.TvDbEpisodeId = episode.TvDbEpisodeId;
|
|
||||||
episodeToUpdate.EpisodeNumber = episode.EpisodeNumber;
|
episodeToUpdate.EpisodeNumber = episode.EpisodeNumber;
|
||||||
episodeToUpdate.SeasonNumber = episode.SeasonNumber;
|
episodeToUpdate.SeasonNumber = episode.SeasonNumber;
|
||||||
episodeToUpdate.Title = episode.Title;
|
episodeToUpdate.Title = episode.Title;
|
||||||
|
|
|
@ -75,7 +75,10 @@
|
||||||
<inspection_tool class="JSUnnecessarySemicolon" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="JSUnnecessarySemicolon" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
<inspection_tool class="JSUnresolvedFunction" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="JSUnresolvedFunction" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="JSUnresolvedVariable" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="JSUnresolvedVariable" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="JSUnusedGlobalSymbols" enabled="false" level="INFO" enabled_by_default="false" />
|
<inspection_tool class="JSUnusedGlobalSymbols" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="myReportUnusedDefinitions" value="true" />
|
||||||
|
<option name="myReportUnusedProperties" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
<inspection_tool class="LabeledStatementJS" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="LabeledStatementJS" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
<inspection_tool class="LocalVariableNamingConventionJS" enabled="true" level="WARNING" enabled_by_default="true">
|
<inspection_tool class="LocalVariableNamingConventionJS" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
<option name="m_regex" value="[a-z][A-Za-z]*" />
|
<option name="m_regex" value="[a-z][A-Za-z]*" />
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
<option camelcase="true" />
|
<option camelcase="true" />
|
||||||
<option curly="true" />
|
<option curly="true" />
|
||||||
<option eqeqeq="true" />
|
<option eqeqeq="true" />
|
||||||
|
<option es3="false" />
|
||||||
<option forin="true" />
|
<option forin="true" />
|
||||||
<option immed="true" />
|
<option immed="true" />
|
||||||
<option latedef="true" />
|
<option latedef="true" />
|
||||||
|
@ -15,7 +16,7 @@
|
||||||
<option plusplus="false" />
|
<option plusplus="false" />
|
||||||
<option regexp="false" />
|
<option regexp="false" />
|
||||||
<option undef="true" />
|
<option undef="true" />
|
||||||
<option unused="false" />
|
<option unused="true" />
|
||||||
<option strict="true" />
|
<option strict="true" />
|
||||||
<option trailing="false" />
|
<option trailing="false" />
|
||||||
<option quotmark="single" />
|
<option quotmark="single" />
|
||||||
|
@ -49,7 +50,7 @@
|
||||||
<option couch="false" />
|
<option couch="false" />
|
||||||
<option devel="true" />
|
<option devel="true" />
|
||||||
<option dojo="false" />
|
<option dojo="false" />
|
||||||
<option jquery="true" />
|
<option jquery="false" />
|
||||||
<option mootools="false" />
|
<option mootools="false" />
|
||||||
<option node="false" />
|
<option node="false" />
|
||||||
<option nonstandard="false" />
|
<option nonstandard="false" />
|
||||||
|
@ -63,7 +64,7 @@
|
||||||
<option passfail="false" />
|
<option passfail="false" />
|
||||||
<option white="false" />
|
<option white="false" />
|
||||||
<option maxerr="50" />
|
<option maxerr="50" />
|
||||||
<option predef="window, define, require ,$" />
|
<option predef="window, define, require" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
define(
|
define(
|
||||||
[
|
[
|
||||||
'backbone',
|
'backbone',
|
||||||
'Series/SeriesModel'
|
'Series/SeriesModel',
|
||||||
], function (Backbone, SeriesModel) {
|
'underscore'
|
||||||
|
], function (Backbone, SeriesModel, _) {
|
||||||
return Backbone.Collection.extend({
|
return Backbone.Collection.extend({
|
||||||
url : window.NzbDrone.ApiRoot + '/series/lookup',
|
url : window.NzbDrone.ApiRoot + '/series/lookup',
|
||||||
model: SeriesModel,
|
model: SeriesModel,
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
define(
|
define(
|
||||||
[
|
[
|
||||||
'app',
|
'vent',
|
||||||
|
'AppLayout',
|
||||||
'marionette',
|
'marionette',
|
||||||
'AddSeries/RootFolders/Layout',
|
'AddSeries/RootFolders/Layout',
|
||||||
'AddSeries/Existing/AddExistingSeriesCollectionView',
|
'AddSeries/Existing/AddExistingSeriesCollectionView',
|
||||||
|
@ -9,7 +10,8 @@ define(
|
||||||
'Quality/QualityProfileCollection',
|
'Quality/QualityProfileCollection',
|
||||||
'AddSeries/RootFolders/Collection',
|
'AddSeries/RootFolders/Collection',
|
||||||
'Series/SeriesCollection'
|
'Series/SeriesCollection'
|
||||||
], function (App,
|
], function (vent,
|
||||||
|
AppLayout,
|
||||||
Marionette,
|
Marionette,
|
||||||
RootFolderLayout,
|
RootFolderLayout,
|
||||||
ExistingSeriesCollectionView,
|
ExistingSeriesCollectionView,
|
||||||
|
@ -43,7 +45,7 @@ define(
|
||||||
},
|
},
|
||||||
|
|
||||||
_folderSelected: function (options) {
|
_folderSelected: function (options) {
|
||||||
App.vent.trigger(App.Commands.CloseModalCommand);
|
vent.trigger(vent.Commands.CloseModalCommand);
|
||||||
|
|
||||||
this.workspace.show(new ExistingSeriesCollectionView({model: options.model}));
|
this.workspace.show(new ExistingSeriesCollectionView({model: options.model}));
|
||||||
},
|
},
|
||||||
|
@ -51,7 +53,7 @@ define(
|
||||||
_importSeries: function () {
|
_importSeries: function () {
|
||||||
this.rootFolderLayout = new RootFolderLayout();
|
this.rootFolderLayout = new RootFolderLayout();
|
||||||
this.rootFolderLayout.on('folderSelected', this._folderSelected, this);
|
this.rootFolderLayout.on('folderSelected', this._folderSelected, this);
|
||||||
App.modalRegion.show(this.rootFolderLayout);
|
AppLayout.modalRegion.show(this.rootFolderLayout);
|
||||||
},
|
},
|
||||||
|
|
||||||
_addSeries: function () {
|
_addSeries: function () {
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
define(
|
define(
|
||||||
[
|
[
|
||||||
'app',
|
'vent',
|
||||||
'marionette',
|
'marionette',
|
||||||
'AddSeries/AddSeriesCollection',
|
'AddSeries/AddSeriesCollection',
|
||||||
'AddSeries/SearchResultCollectionView',
|
'AddSeries/SearchResultCollectionView',
|
||||||
'AddSeries/NotFoundView',
|
'AddSeries/NotFoundView',
|
||||||
'Shared/LoadingView',
|
'Shared/LoadingView',
|
||||||
'underscore'
|
'underscore'
|
||||||
], function (App, Marionette, AddSeriesCollection, SearchResultCollectionView, NotFoundView, LoadingView, _) {
|
], function (vent, Marionette, AddSeriesCollection, SearchResultCollectionView, NotFoundView, LoadingView, _) {
|
||||||
return Marionette.Layout.extend({
|
return Marionette.Layout.extend({
|
||||||
template: 'AddSeries/AddSeriesViewTemplate',
|
template: 'AddSeries/AddSeriesViewTemplate',
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ define(
|
||||||
this.className = 'new-series';
|
this.className = 'new-series';
|
||||||
}
|
}
|
||||||
|
|
||||||
this.listenTo(App.vent, App.Events.SeriesAdded, this._onSeriesAdded);
|
this.listenTo(vent, vent.Events.SeriesAdded, this._onSeriesAdded);
|
||||||
this.listenTo(this.collection, 'sync', this._showResults);
|
this.listenTo(this.collection, 'sync', this._showResults);
|
||||||
|
|
||||||
this.resultCollectionView = new SearchResultCollectionView({
|
this.resultCollectionView = new SearchResultCollectionView({
|
||||||
|
|
|
@ -20,4 +20,4 @@
|
||||||
<div class="btn btn-block text-center new-series-loadmore x-load-more" style="display: none;">
|
<div class="btn btn-block text-center new-series-loadmore x-load-more" style="display: none;">
|
||||||
<i class="icon-angle-down"/>
|
<i class="icon-angle-down"/>
|
||||||
more
|
more
|
||||||
</div>{{debug}}
|
</div>
|
||||||
|
|
|
@ -5,4 +5,3 @@
|
||||||
<a href="https://github.com/NzbDrone/NzbDrone/wiki/FAQ#why-cant-i-add-a-new-show-to-nzbdrone-its-on-thetvdb">Why can't I find my show?</a>
|
<a href="https://github.com/NzbDrone/NzbDrone/wiki/FAQ#why-cant-i-add-a-new-show-to-nzbdrone-its-on-thetvdb">Why can't I find my show?</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{{debug}}
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
define(
|
define(
|
||||||
[
|
[
|
||||||
'app',
|
'vent',
|
||||||
|
'AppLayout',
|
||||||
'underscore',
|
'underscore',
|
||||||
'marionette',
|
'marionette',
|
||||||
'Quality/QualityProfileCollection',
|
'Quality/QualityProfileCollection',
|
||||||
|
@ -12,7 +13,7 @@ define(
|
||||||
'Shared/Messenger',
|
'Shared/Messenger',
|
||||||
'Mixins/AsValidatedView',
|
'Mixins/AsValidatedView',
|
||||||
'jquery.dotdotdot'
|
'jquery.dotdotdot'
|
||||||
], function (App, _, Marionette, QualityProfiles, RootFolders, RootFolderLayout, SeriesCollection, Config, Messenger, AsValidatedView) {
|
], function (vent, AppLayout, _, Marionette, QualityProfiles, RootFolders, RootFolderLayout, SeriesCollection, Config, Messenger, AsValidatedView) {
|
||||||
|
|
||||||
var view = Marionette.ItemView.extend({
|
var view = Marionette.ItemView.extend({
|
||||||
|
|
||||||
|
@ -41,12 +42,9 @@ define(
|
||||||
this.templateHelpers = {};
|
this.templateHelpers = {};
|
||||||
this._configureTemplateHelpers();
|
this._configureTemplateHelpers();
|
||||||
|
|
||||||
this.listenTo(App.vent, Config.Events.ConfigUpdatedEvent, this._onConfigUpdated);
|
this.listenTo(vent, Config.Events.ConfigUpdatedEvent, this._onConfigUpdated);
|
||||||
this.listenTo(this.model, 'change', this.render);
|
this.listenTo(this.model, 'change', this.render);
|
||||||
this.listenTo(RootFolders, 'all', this.render);
|
this.listenTo(RootFolders, 'all', this._rootFoldersUpdated);
|
||||||
|
|
||||||
this.rootFolderLayout = new RootFolderLayout();
|
|
||||||
this.listenTo(this.rootFolderLayout, 'folderSelected', this._setRootFolder);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onRender: function () {
|
onRender: function () {
|
||||||
|
@ -105,7 +103,9 @@ define(
|
||||||
_rootFolderChanged: function () {
|
_rootFolderChanged: function () {
|
||||||
var rootFolderValue = this.ui.rootFolder.val();
|
var rootFolderValue = this.ui.rootFolder.val();
|
||||||
if (rootFolderValue === 'addNew') {
|
if (rootFolderValue === 'addNew') {
|
||||||
App.modalRegion.show(this.rootFolderLayout);
|
var rootFolderLayout = new RootFolderLayout();
|
||||||
|
this.listenToOnce(rootFolderLayout, 'folderSelected', this._setRootFolder);
|
||||||
|
AppLayout.modalRegion.show(rootFolderLayout);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Config.setValue(Config.Keys.DefaultRootFolderId, rootFolderValue);
|
Config.setValue(Config.Keys.DefaultRootFolderId, rootFolderValue);
|
||||||
|
@ -113,7 +113,7 @@ define(
|
||||||
},
|
},
|
||||||
|
|
||||||
_setRootFolder: function (options) {
|
_setRootFolder: function (options) {
|
||||||
App.vent.trigger(App.Commands.CloseModalCommand);
|
vent.trigger(vent.Commands.CloseModalCommand);
|
||||||
this.ui.rootFolder.val(options.model.id);
|
this.ui.rootFolder.val(options.model.id);
|
||||||
this._rootFolderChanged();
|
this._rootFolderChanged();
|
||||||
},
|
},
|
||||||
|
@ -145,12 +145,17 @@ define(
|
||||||
message: 'Added: ' + self.model.get('title')
|
message: 'Added: ' + self.model.get('title')
|
||||||
});
|
});
|
||||||
|
|
||||||
App.vent.trigger(App.Events.SeriesAdded, { series: self.model });
|
vent.trigger(vent.Events.SeriesAdded, { series: self.model });
|
||||||
});
|
});
|
||||||
|
|
||||||
promise.fail(function () {
|
promise.fail(function () {
|
||||||
icon.removeClass('icon-spin icon-spinner disabled').addClass('icon-search');
|
icon.removeClass('icon-spin icon-spinner disabled').addClass('icon-search');
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_rootFoldersUpdated: function () {
|
||||||
|
this._configureTemplateHelpers();
|
||||||
|
this.render();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
define(
|
||||||
|
[
|
||||||
|
'marionette',
|
||||||
|
'Shared/Modal/ModalRegion'
|
||||||
|
], function (Marionette, ModalRegion) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var Layout = Marionette.Layout.extend({
|
||||||
|
|
||||||
|
regions: {
|
||||||
|
navbarRegion: '#nav-region',
|
||||||
|
mainRegion : '#main-region'
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize: function () {
|
||||||
|
this.addRegions({
|
||||||
|
modalRegion: ModalRegion
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return new Layout({el: 'body'});
|
||||||
|
});
|
|
@ -2,12 +2,12 @@
|
||||||
|
|
||||||
define(
|
define(
|
||||||
[
|
[
|
||||||
'app',
|
'vent',
|
||||||
'marionette',
|
'marionette',
|
||||||
'moment',
|
'moment',
|
||||||
'Calendar/Collection',
|
'Calendar/Collection',
|
||||||
'fullcalendar'
|
'fullcalendar'
|
||||||
], function (App, Marionette, Moment, CalendarCollection) {
|
], function (vent, Marionette, Moment, CalendarCollection) {
|
||||||
|
|
||||||
var _instance;
|
var _instance;
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ define(
|
||||||
$(element).children('.fc-event-inner').addClass(event.statusLevel);
|
$(element).children('.fc-event-inner').addClass(event.statusLevel);
|
||||||
},
|
},
|
||||||
eventClick : function (event) {
|
eventClick : function (event) {
|
||||||
App.vent.trigger(App.Commands.ShowEpisodeDetails, {episode: event.model});
|
vent.trigger(vent.Commands.ShowEpisodeDetails, {episode: event.model});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ define(
|
||||||
var test = currentTime.startOf('day').format('LLLL');
|
var test = currentTime.startOf('day').format('LLLL');
|
||||||
|
|
||||||
if (end.isBefore(currentTime.startOf('day'))) {
|
if (end.isBefore(currentTime.startOf('day'))) {
|
||||||
statusLevel += ' past'
|
statusLevel += ' past';
|
||||||
}
|
}
|
||||||
|
|
||||||
return statusLevel;
|
return statusLevel;
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
|
|
||||||
define(
|
define(
|
||||||
[
|
[
|
||||||
'app',
|
'vent',
|
||||||
'marionette',
|
'marionette',
|
||||||
'moment'
|
'moment'
|
||||||
], function (App, Marionette, Moment) {
|
], function (vent, Marionette, Moment) {
|
||||||
return Marionette.ItemView.extend({
|
return Marionette.ItemView.extend({
|
||||||
template: 'Calendar/UpcomingItemViewTemplate',
|
template: 'Calendar/UpcomingItemViewTemplate',
|
||||||
tagName : 'div',
|
tagName : 'div',
|
||||||
|
@ -21,11 +21,11 @@ define(
|
||||||
|
|
||||||
this.model.set({
|
this.model.set({
|
||||||
end: end.toISOString()
|
end: end.toISOString()
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_showEpisodeDetails: function () {
|
_showEpisodeDetails: function () {
|
||||||
App.vent.trigger(App.Commands.ShowEpisodeDetails, {episode: this.model});
|
vent.trigger(vent.Commands.ShowEpisodeDetails, {episode: this.model});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
define(
|
define(
|
||||||
[
|
[
|
||||||
'backgrid',
|
'backgrid',
|
||||||
|
'marionette',
|
||||||
|
'underscore',
|
||||||
'Settings/Quality/Profile/QualityProfileSchemaCollection',
|
'Settings/Quality/Profile/QualityProfileSchemaCollection',
|
||||||
'Series/EpisodeFileModel'
|
], function (Backgrid, Marionette, _, QualityProfileSchemaCollection) {
|
||||||
], function (Backgrid, QualityProfileSchemaCollection, EpisodeFileModel) {
|
|
||||||
return Backgrid.CellEditor.extend({
|
return Backgrid.CellEditor.extend({
|
||||||
|
|
||||||
className: 'quality-cell-editor',
|
className: 'quality-cell-editor',
|
||||||
|
@ -12,8 +13,8 @@ define(
|
||||||
tagName : 'select',
|
tagName : 'select',
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
'change': 'save',
|
'change' : 'save',
|
||||||
'blur': 'close',
|
'blur' : 'close',
|
||||||
'keydown': 'close'
|
'keydown': 'close'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -27,7 +28,7 @@ define(
|
||||||
var templateName = self.template;
|
var templateName = self.template;
|
||||||
self.schema = qualityProfileSchemaCollection.first();
|
self.schema = qualityProfileSchemaCollection.first();
|
||||||
|
|
||||||
var selected = _.find(self.schema.get('available'), { 'id': self.model.get(self.column.get("name")).quality.id });
|
var selected = _.find(self.schema.get('available'), { 'id': self.model.get(self.column.get('name')).quality.id });
|
||||||
|
|
||||||
if (selected) {
|
if (selected) {
|
||||||
selected.selected = true;
|
selected.selected = true;
|
||||||
|
@ -45,18 +46,18 @@ define(
|
||||||
save: function (e) {
|
save: function (e) {
|
||||||
var model = this.model;
|
var model = this.model;
|
||||||
var column = this.column;
|
var column = this.column;
|
||||||
var selected = parseInt(this.$el.val());
|
var selected = parseInt(this.$el.val(), 10);
|
||||||
|
|
||||||
var quality = _.find(this.schema.get('available'), { 'id': selected });
|
var quality = _.find(this.schema.get('available'), { 'id': selected });
|
||||||
|
|
||||||
var newQuality = {
|
var newQuality = {
|
||||||
proper: false,
|
proper : false,
|
||||||
quality: quality
|
quality: quality
|
||||||
};
|
};
|
||||||
|
|
||||||
model.set(column.get("name"), newQuality);
|
model.set(column.get('name'), newQuality);
|
||||||
model.save();
|
model.save();
|
||||||
model.trigger("backgrid:edited", model, column, new Backgrid.Command(e));
|
model.trigger('backgrid:edited', model, column, new Backgrid.Command(e));
|
||||||
},
|
},
|
||||||
|
|
||||||
close: function (e) {
|
close: function (e) {
|
||||||
|
@ -64,7 +65,7 @@ define(
|
||||||
var column = this.column;
|
var column = this.column;
|
||||||
var command = new Backgrid.Command(e);
|
var command = new Backgrid.Command(e);
|
||||||
|
|
||||||
model.trigger("backgrid:edited", model, column, command);
|
model.trigger('backgrid:edited', model, column, command);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,10 +2,11 @@
|
||||||
|
|
||||||
define(
|
define(
|
||||||
[
|
[
|
||||||
'app',
|
'vent',
|
||||||
|
'marionette',
|
||||||
'Cells/NzbDroneCell',
|
'Cells/NzbDroneCell',
|
||||||
'Commands/CommandController'
|
'Commands/CommandController'
|
||||||
], function (App, NzbDroneCell, CommandController) {
|
], function (vent, Marionette, NzbDroneCell, CommandController) {
|
||||||
return NzbDroneCell.extend({
|
return NzbDroneCell.extend({
|
||||||
|
|
||||||
className: 'episode-actions-cell',
|
className: 'episode-actions-cell',
|
||||||
|
@ -48,7 +49,7 @@ define(
|
||||||
},
|
},
|
||||||
|
|
||||||
_manualSearch: function () {
|
_manualSearch: function () {
|
||||||
App.vent.trigger(App.Commands.ShowEpisodeDetails, { episode: this.cellValue, hideSeriesLink: true, openingTab: 'search' });
|
vent.trigger(vent.Commands.ShowEpisodeDetails, { episode: this.cellValue, hideSeriesLink: true, openingTab: 'search' });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
define(
|
define(
|
||||||
[
|
[
|
||||||
'app',
|
'reqres',
|
||||||
'underscore',
|
'underscore',
|
||||||
'Cells/NzbDroneCell',
|
'Cells/NzbDroneCell',
|
||||||
'History/Queue/QueueCollection',
|
'History/Queue/QueueCollection',
|
||||||
'moment',
|
'moment',
|
||||||
'Shared/FormatHelpers'
|
'Shared/FormatHelpers'
|
||||||
], function (App, _, NzbDroneCell, QueueCollection, Moment, FormatHelpers) {
|
], function (reqres, _, NzbDroneCell, QueueCollection, Moment, FormatHelpers) {
|
||||||
return NzbDroneCell.extend({
|
return NzbDroneCell.extend({
|
||||||
|
|
||||||
className: 'episode-status-cell',
|
className: 'episode-status-cell',
|
||||||
|
@ -33,7 +33,7 @@ define(
|
||||||
var hasFile = this.model.get('hasFile');
|
var hasFile = this.model.get('hasFile');
|
||||||
|
|
||||||
if (hasFile) {
|
if (hasFile) {
|
||||||
var episodeFile = App.request(App.Reqres.GetEpisodeFileById, this.model.get('episodeFileId'));
|
var episodeFile = reqres.request(reqres.Requests.GetEpisodeFileById, this.model.get('episodeFileId'));
|
||||||
|
|
||||||
this.listenTo(episodeFile, 'change', this._refresh);
|
this.listenTo(episodeFile, 'change', this._refresh);
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
define(
|
define(
|
||||||
[
|
[
|
||||||
'app',
|
'vent',
|
||||||
'Cells/NzbDroneCell'
|
'Cells/NzbDroneCell'
|
||||||
], function (App, NzbDroneCell) {
|
], function (vent, NzbDroneCell) {
|
||||||
return NzbDroneCell.extend({
|
return NzbDroneCell.extend({
|
||||||
|
|
||||||
className: 'episode-title-cell',
|
className: 'episode-title-cell',
|
||||||
|
@ -27,7 +27,7 @@ define(
|
||||||
_showDetails: function () {
|
_showDetails: function () {
|
||||||
var hideSeriesLink = this.column.get('hideSeriesLink');
|
var hideSeriesLink = this.column.get('hideSeriesLink');
|
||||||
|
|
||||||
App.vent.trigger(App.Commands.ShowEpisodeDetails, { episode: this.cellValue, hideSeriesLink: hideSeriesLink });
|
vent.trigger(vent.Commands.ShowEpisodeDetails, { episode: this.cellValue, hideSeriesLink: hideSeriesLink });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
define(
|
define(
|
||||||
[
|
[
|
||||||
'app',
|
'vent',
|
||||||
'Cells/NzbDroneCell'
|
'Cells/NzbDroneCell'
|
||||||
], function (App, NzbDroneCell) {
|
], function (vent, NzbDroneCell) {
|
||||||
return NzbDroneCell.extend({
|
return NzbDroneCell.extend({
|
||||||
|
|
||||||
className: 'series-actions-cell',
|
className: 'series-actions-cell',
|
||||||
|
@ -27,11 +27,11 @@ define(
|
||||||
},
|
},
|
||||||
|
|
||||||
_editSeries: function () {
|
_editSeries: function () {
|
||||||
App.vent.trigger(App.Commands.EditSeriesCommand, {series:this.model});
|
vent.trigger(vent.Commands.EditSeriesCommand, {series:this.model});
|
||||||
},
|
},
|
||||||
|
|
||||||
_removeSeries: function () {
|
_removeSeries: function () {
|
||||||
App.vent.trigger(App.Commands.DeleteSeriesCommand, {series:this.model});
|
vent.trigger(vent.Commands.DeleteSeriesCommand, {series:this.model});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
define(
|
define(
|
||||||
[
|
[
|
||||||
'app',
|
'vent',
|
||||||
'Commands/CommandModel',
|
'Commands/CommandModel',
|
||||||
'Commands/CommandCollection',
|
'Commands/CommandCollection',
|
||||||
|
'Commands/CommandMessengerCollectionView',
|
||||||
'underscore',
|
'underscore',
|
||||||
'jQuery/jquery.spin'
|
'jQuery/jquery.spin'
|
||||||
], function (App, CommandModel, CommandCollection, _) {
|
], function (vent, CommandModel, CommandCollection, CommandMessengerCollectionView, _) {
|
||||||
|
|
||||||
|
|
||||||
|
CommandMessengerCollectionView.render();
|
||||||
|
|
||||||
var singleton = function () {
|
var singleton = function () {
|
||||||
|
|
||||||
|
@ -33,11 +37,18 @@ define(
|
||||||
this._bindToCommandModel.call(this, existingCommand, options);
|
this._bindToCommandModel.call(this, existingCommand, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandCollection.bind('add sync', function (model) {
|
CommandCollection.bind('add', function (model) {
|
||||||
if (model.isSameCommand(options.command)) {
|
if (model.isSameCommand(options.command)) {
|
||||||
self._bindToCommandModel.call(self, model, options);
|
self._bindToCommandModel.call(self, model, options);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
CommandCollection.bind('add sync', function () {
|
||||||
|
var command = CommandCollection.findCommand(options.command);
|
||||||
|
if (command) {
|
||||||
|
self._bindToCommandModel.call(self, command, options);
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_bindToCommandModel: function bindToCommand(model, options) {
|
_bindToCommandModel: function bindToCommand(model, options) {
|
||||||
|
@ -52,7 +63,7 @@ define(
|
||||||
options.element.stopSpin();
|
options.element.stopSpin();
|
||||||
|
|
||||||
if (model.isComplete()) {
|
if (model.isComplete()) {
|
||||||
App.vent.trigger(App.Events.CommandComplete, { command: model, model: options.model });
|
vent.trigger(vent.Events.CommandComplete, { command: model, model: options.model });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
define(
|
define(
|
||||||
[
|
[
|
||||||
'app',
|
|
||||||
'marionette',
|
'marionette',
|
||||||
'Commands/CommandCollection',
|
'Commands/CommandCollection',
|
||||||
'Commands/CommandMessengerItemView'
|
'Commands/CommandMessengerItemView'
|
||||||
], function (App, Marionette, commandCollection, CommandMessengerItemView) {
|
], function (Marionette, commandCollection, CommandMessengerItemView) {
|
||||||
|
|
||||||
var CollectionView = Marionette.CollectionView.extend({
|
var CollectionView = Marionette.CollectionView.extend({
|
||||||
itemView : CommandMessengerItemView
|
itemView: CommandMessengerItemView
|
||||||
});
|
});
|
||||||
|
|
||||||
new CollectionView({collection: commandCollection});
|
return new CollectionView({collection: commandCollection});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
define(
|
define(
|
||||||
[
|
[
|
||||||
'app',
|
|
||||||
'marionette',
|
'marionette',
|
||||||
'Shared/Messenger'
|
'Shared/Messenger'
|
||||||
], function (App, Marionette, Messenger) {
|
], function ( Marionette, Messenger) {
|
||||||
|
|
||||||
return Marionette.ItemView.extend({
|
return Marionette.ItemView.extend({
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
define(
|
define(
|
||||||
[
|
[
|
||||||
'app'
|
'vent'
|
||||||
], function (App) {
|
], function (vent) {
|
||||||
return {
|
return {
|
||||||
Events: {
|
Events: {
|
||||||
ConfigUpdatedEvent: 'ConfigUpdatedEvent'
|
ConfigUpdatedEvent: 'ConfigUpdatedEvent'
|
||||||
|
@ -36,7 +36,7 @@ define(
|
||||||
}
|
}
|
||||||
|
|
||||||
localStorage.setItem(key, value);
|
localStorage.setItem(key, value);
|
||||||
App.vent.trigger(this.Events.ConfigUpdatedEvent, {key: key, value: value});
|
vent.trigger(this.Events.ConfigUpdatedEvent, {key: key, value: value});
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,118 +1,77 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
define(
|
define(
|
||||||
[
|
[
|
||||||
'app',
|
'Shared/NzbDroneController',
|
||||||
|
'AppLayout',
|
||||||
'marionette',
|
'marionette',
|
||||||
'History/HistoryLayout',
|
'History/HistoryLayout',
|
||||||
'Settings/SettingsLayout',
|
'Settings/SettingsLayout',
|
||||||
'AddSeries/AddSeriesLayout',
|
'AddSeries/AddSeriesLayout',
|
||||||
'Series/Index/SeriesIndexLayout',
|
|
||||||
'Series/Details/SeriesDetailsLayout',
|
|
||||||
'Series/SeriesCollection',
|
|
||||||
'Missing/MissingLayout',
|
'Missing/MissingLayout',
|
||||||
'Calendar/CalendarLayout',
|
'Calendar/CalendarLayout',
|
||||||
'Release/Layout',
|
'Release/Layout',
|
||||||
'System/SystemLayout',
|
'System/SystemLayout',
|
||||||
'SeasonPass/SeasonPassLayout',
|
'SeasonPass/SeasonPassLayout',
|
||||||
'System/Update/UpdateLayout',
|
'System/Update/UpdateLayout'
|
||||||
'Shared/NotFoundView',
|
], function (NzbDroneController,
|
||||||
'Shared/Modal/Region'
|
AppLayout,
|
||||||
], function (App,
|
|
||||||
Marionette,
|
Marionette,
|
||||||
HistoryLayout,
|
HistoryLayout,
|
||||||
SettingsLayout,
|
SettingsLayout,
|
||||||
AddSeriesLayout,
|
AddSeriesLayout,
|
||||||
SeriesIndexLayout,
|
|
||||||
SeriesDetailsLayout,
|
|
||||||
SeriesCollection,
|
|
||||||
MissingLayout,
|
MissingLayout,
|
||||||
CalendarLayout,
|
CalendarLayout,
|
||||||
ReleaseLayout,
|
ReleaseLayout,
|
||||||
SystemLayout,
|
SystemLayout,
|
||||||
SeasonPassLayout,
|
SeasonPassLayout,
|
||||||
UpdateLayout,
|
UpdateLayout) {
|
||||||
NotFoundView) {
|
return NzbDroneController.extend({
|
||||||
return Marionette.Controller.extend({
|
|
||||||
|
|
||||||
series: function () {
|
|
||||||
this._setTitle('NzbDrone');
|
|
||||||
App.mainRegion.show(new SeriesIndexLayout());
|
|
||||||
},
|
|
||||||
|
|
||||||
seriesDetails: function (query) {
|
|
||||||
var series = SeriesCollection.where({titleSlug: query});
|
|
||||||
|
|
||||||
if (series.length !== 0) {
|
|
||||||
var targetSeries = series[0];
|
|
||||||
this._setTitle(targetSeries.get('title'));
|
|
||||||
App.mainRegion.show(new SeriesDetailsLayout({ model: targetSeries }));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.notFound();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
addSeries: function (action) {
|
addSeries: function (action) {
|
||||||
this._setTitle('Add Series');
|
this.setTitle('Add Series');
|
||||||
App.mainRegion.show(new AddSeriesLayout({action: action}));
|
AppLayout.mainRegion.show(new AddSeriesLayout({action: action}));
|
||||||
},
|
},
|
||||||
|
|
||||||
calendar: function () {
|
calendar: function () {
|
||||||
this._setTitle('Calendar');
|
this.setTitle('Calendar');
|
||||||
App.mainRegion.show(new CalendarLayout());
|
AppLayout.mainRegion.show(new CalendarLayout());
|
||||||
},
|
},
|
||||||
|
|
||||||
settings: function (action) {
|
settings: function (action) {
|
||||||
this._setTitle('Settings');
|
this.setTitle('Settings');
|
||||||
App.mainRegion.show(new SettingsLayout({ action: action }));
|
AppLayout.mainRegion.show(new SettingsLayout({ action: action }));
|
||||||
},
|
},
|
||||||
|
|
||||||
missing: function () {
|
missing: function () {
|
||||||
this._setTitle('Missing');
|
this.setTitle('Missing');
|
||||||
|
|
||||||
App.mainRegion.show(new MissingLayout());
|
AppLayout.mainRegion.show(new MissingLayout());
|
||||||
},
|
},
|
||||||
|
|
||||||
history: function (action) {
|
history: function (action) {
|
||||||
this._setTitle('History');
|
this.setTitle('History');
|
||||||
|
|
||||||
App.mainRegion.show(new HistoryLayout({ action: action }));
|
AppLayout.mainRegion.show(new HistoryLayout({ action: action }));
|
||||||
},
|
},
|
||||||
|
|
||||||
rss: function () {
|
rss: function () {
|
||||||
this._setTitle('RSS');
|
this.setTitle('RSS');
|
||||||
App.mainRegion.show(new ReleaseLayout());
|
AppLayout.mainRegion.show(new ReleaseLayout());
|
||||||
},
|
},
|
||||||
|
|
||||||
system: function (action) {
|
system: function (action) {
|
||||||
this._setTitle('System');
|
this.setTitle('System');
|
||||||
App.mainRegion.show(new SystemLayout({ action: action }));
|
AppLayout.mainRegion.show(new SystemLayout({ action: action }));
|
||||||
},
|
},
|
||||||
|
|
||||||
seasonPass: function () {
|
seasonPass: function () {
|
||||||
this._setTitle('Season Pass');
|
this.setTitle('Season Pass');
|
||||||
App.mainRegion.show(new SeasonPassLayout());
|
AppLayout.mainRegion.show(new SeasonPassLayout());
|
||||||
},
|
},
|
||||||
|
|
||||||
update: function () {
|
update: function () {
|
||||||
this._setTitle('Updates');
|
this.setTitle('Updates');
|
||||||
App.mainRegion.show(new UpdateLayout());
|
AppLayout.mainRegion.show(new UpdateLayout());
|
||||||
},
|
|
||||||
|
|
||||||
notFound: function () {
|
|
||||||
this._setTitle('Not Found');
|
|
||||||
App.mainRegion.show(new NotFoundView(this));
|
|
||||||
},
|
|
||||||
|
|
||||||
_setTitle: function (title) {
|
|
||||||
//$('#title-region').html(title);
|
|
||||||
|
|
||||||
if (title.toLocaleLowerCase() === 'nzbdrone') {
|
|
||||||
window.document.title = 'NzbDrone';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
window.document.title = title + ' - NzbDrone';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue