Merge branch 'develop'
This commit is contained in:
commit
bbfd09ca84
|
@ -3,19 +3,12 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NzbDrone.Api.Episodes;
|
using NzbDrone.Api.Episodes;
|
||||||
using NzbDrone.Api.Extensions;
|
using NzbDrone.Api.Extensions;
|
||||||
using NzbDrone.Api.Mapping;
|
|
||||||
using NzbDrone.Core.Datastore.Events;
|
|
||||||
using NzbDrone.Core.Download;
|
|
||||||
using NzbDrone.Core.MediaFiles.Events;
|
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Calendar
|
namespace NzbDrone.Api.Calendar
|
||||||
{
|
{
|
||||||
public class CalendarModule : NzbDroneRestModuleWithSignalR<EpisodeResource, Episode>,
|
public class CalendarModule : EpisodeModuleWithSignalR
|
||||||
IHandle<EpisodeGrabbedEvent>,
|
|
||||||
IHandle<EpisodeDownloadedEvent>
|
|
||||||
{
|
{
|
||||||
private readonly IEpisodeService _episodeService;
|
private readonly IEpisodeService _episodeService;
|
||||||
private readonly SeriesRepository _seriesRepository;
|
private readonly SeriesRepository _seriesRepository;
|
||||||
|
@ -23,18 +16,12 @@ namespace NzbDrone.Api.Calendar
|
||||||
public CalendarModule(ICommandExecutor commandExecutor,
|
public CalendarModule(ICommandExecutor commandExecutor,
|
||||||
IEpisodeService episodeService,
|
IEpisodeService episodeService,
|
||||||
SeriesRepository seriesRepository)
|
SeriesRepository seriesRepository)
|
||||||
: base(commandExecutor, "calendar")
|
: base(episodeService, commandExecutor, "calendar")
|
||||||
{
|
{
|
||||||
_episodeService = episodeService;
|
_episodeService = episodeService;
|
||||||
_seriesRepository = seriesRepository;
|
_seriesRepository = seriesRepository;
|
||||||
|
|
||||||
GetResourceAll = GetCalendar;
|
GetResourceAll = GetCalendar;
|
||||||
GetResourceById = GetEpisode;
|
|
||||||
}
|
|
||||||
|
|
||||||
private EpisodeResource GetEpisode(int id)
|
|
||||||
{
|
|
||||||
return _episodeService.GetEpisode(id).InjectTo<EpisodeResource>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<EpisodeResource> GetCalendar()
|
private List<EpisodeResource> GetCalendar()
|
||||||
|
@ -53,24 +40,5 @@ namespace NzbDrone.Api.Calendar
|
||||||
|
|
||||||
return resources.OrderBy(e => e.AirDateUtc).ToList();
|
return resources.OrderBy(e => e.AirDateUtc).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Handle(EpisodeGrabbedEvent message)
|
|
||||||
{
|
|
||||||
foreach (var episode in message.Episode.Episodes)
|
|
||||||
{
|
|
||||||
var resource = episode.InjectTo<EpisodeResource>();
|
|
||||||
resource.Grabbed = true;
|
|
||||||
|
|
||||||
BroadcastResourceChange(ModelAction.Updated, resource);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(EpisodeDownloadedEvent message)
|
|
||||||
{
|
|
||||||
foreach (var episode in message.Episode.Episodes)
|
|
||||||
{
|
|
||||||
BroadcastResourceChange(ModelAction.Updated, episode.Id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,16 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NzbDrone.Api.Mapping;
|
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.Datastore.Events;
|
|
||||||
using NzbDrone.Core.Download;
|
|
||||||
using NzbDrone.Core.MediaFiles.Events;
|
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Episodes
|
namespace NzbDrone.Api.Episodes
|
||||||
{
|
{
|
||||||
public class EpisodeModule : NzbDroneRestModuleWithSignalR<EpisodeResource, Episode>,
|
public class EpisodeModule : EpisodeModuleWithSignalR
|
||||||
IHandle<EpisodeGrabbedEvent>,
|
|
||||||
IHandle<EpisodeDownloadedEvent>
|
|
||||||
|
|
||||||
{
|
{
|
||||||
private readonly IEpisodeService _episodeService;
|
private readonly IEpisodeService _episodeService;
|
||||||
|
|
||||||
public EpisodeModule(ICommandExecutor commandExecutor, IEpisodeService episodeService)
|
public EpisodeModule(ICommandExecutor commandExecutor, IEpisodeService episodeService)
|
||||||
: base(commandExecutor)
|
: base(episodeService, commandExecutor)
|
||||||
{
|
{
|
||||||
_episodeService = episodeService;
|
_episodeService = episodeService;
|
||||||
|
|
||||||
|
@ -43,29 +35,5 @@ namespace NzbDrone.Api.Episodes
|
||||||
{
|
{
|
||||||
_episodeService.SetEpisodeMonitored(episodeResource.Id, episodeResource.Monitored);
|
_episodeService.SetEpisodeMonitored(episodeResource.Id, episodeResource.Monitored);
|
||||||
}
|
}
|
||||||
|
|
||||||
private EpisodeResource GetEpisode(int id)
|
|
||||||
{
|
|
||||||
return _episodeService.GetEpisode(id).InjectTo<EpisodeResource>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(EpisodeGrabbedEvent message)
|
|
||||||
{
|
|
||||||
foreach (var episode in message.Episode.Episodes)
|
|
||||||
{
|
|
||||||
var resource = episode.InjectTo<EpisodeResource>();
|
|
||||||
resource.Grabbed = true;
|
|
||||||
|
|
||||||
BroadcastResourceChange(ModelAction.Updated, resource);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(EpisodeDownloadedEvent message)
|
|
||||||
{
|
|
||||||
foreach (var episode in message.Episode.Episodes)
|
|
||||||
{
|
|
||||||
BroadcastResourceChange(ModelAction.Updated, episode.Id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
using NzbDrone.Api.Mapping;
|
||||||
|
using NzbDrone.Core.Datastore.Events;
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
|
using NzbDrone.Core.MediaFiles.Events;
|
||||||
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Episodes
|
||||||
|
{
|
||||||
|
public abstract class EpisodeModuleWithSignalR : NzbDroneRestModuleWithSignalR<EpisodeResource, Episode>,
|
||||||
|
IHandle<EpisodeGrabbedEvent>,
|
||||||
|
IHandle<EpisodeDownloadedEvent>
|
||||||
|
{
|
||||||
|
private readonly IEpisodeService _episodeService;
|
||||||
|
|
||||||
|
protected EpisodeModuleWithSignalR(IEpisodeService episodeService, ICommandExecutor commandExecutor)
|
||||||
|
: base(commandExecutor)
|
||||||
|
{
|
||||||
|
_episodeService = episodeService;
|
||||||
|
|
||||||
|
GetResourceById = GetEpisode;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected EpisodeModuleWithSignalR(IEpisodeService episodeService, ICommandExecutor commandExecutor, string resource)
|
||||||
|
: base(commandExecutor, resource)
|
||||||
|
{
|
||||||
|
_episodeService = episodeService;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected EpisodeResource GetEpisode(int id)
|
||||||
|
{
|
||||||
|
return _episodeService.GetEpisode(id).InjectTo<EpisodeResource>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(EpisodeGrabbedEvent message)
|
||||||
|
{
|
||||||
|
foreach (var episode in message.Episode.Episodes)
|
||||||
|
{
|
||||||
|
var resource = episode.InjectTo<EpisodeResource>();
|
||||||
|
resource.Grabbed = true;
|
||||||
|
|
||||||
|
BroadcastResourceChange(ModelAction.Updated, resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(EpisodeDownloadedEvent message)
|
||||||
|
{
|
||||||
|
foreach (var episode in message.Episode.Episodes)
|
||||||
|
{
|
||||||
|
BroadcastResourceChange(ModelAction.Updated, episode.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,7 +13,10 @@ namespace NzbDrone.Api.Extensions.Pipelines
|
||||||
|
|
||||||
private void Handle(NancyContext context)
|
private void Handle(NancyContext context)
|
||||||
{
|
{
|
||||||
context.Response.Headers.Add("X-ApplicationVersion", BuildInfo.Version.ToString());
|
if (!context.Response.Headers.ContainsKey("X-ApplicationVersion"))
|
||||||
|
{
|
||||||
|
context.Response.Headers.Add("X-ApplicationVersion", BuildInfo.Version.ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,11 +6,11 @@ using NzbDrone.Common.EnvironmentInfo;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Frontend.Mappers
|
namespace NzbDrone.Api.Frontend.Mappers
|
||||||
{
|
{
|
||||||
public class LogFileMapper : StaticResourceMapperBase
|
public class UpdateLogFileMapper : StaticResourceMapperBase
|
||||||
{
|
{
|
||||||
private readonly IAppFolderInfo _appFolderInfo;
|
private readonly IAppFolderInfo _appFolderInfo;
|
||||||
|
|
||||||
public LogFileMapper(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, Logger logger)
|
public UpdateLogFileMapper(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, Logger logger)
|
||||||
: base(diskProvider, logger)
|
: base(diskProvider, logger)
|
||||||
{
|
{
|
||||||
_appFolderInfo = appFolderInfo;
|
_appFolderInfo = appFolderInfo;
|
||||||
|
@ -21,12 +21,12 @@ namespace NzbDrone.Api.Frontend.Mappers
|
||||||
var path = resourceUrl.Replace('/', Path.DirectorySeparatorChar);
|
var path = resourceUrl.Replace('/', Path.DirectorySeparatorChar);
|
||||||
path = Path.GetFileName(path);
|
path = Path.GetFileName(path);
|
||||||
|
|
||||||
return Path.Combine(_appFolderInfo.GetLogFolder(), path);
|
return Path.Combine(_appFolderInfo.GetUpdateLogFolder(), path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool CanHandle(string resourceUrl)
|
public override bool CanHandle(string resourceUrl)
|
||||||
{
|
{
|
||||||
return resourceUrl.StartsWith("/logfile/") && resourceUrl.EndsWith(".txt");
|
return resourceUrl.StartsWith("/updatelogfile/") && resourceUrl.EndsWith(".txt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
using System.IO;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Frontend.Mappers
|
||||||
|
{
|
||||||
|
public class LogFileMapper : StaticResourceMapperBase
|
||||||
|
{
|
||||||
|
private readonly IAppFolderInfo _appFolderInfo;
|
||||||
|
|
||||||
|
public LogFileMapper(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, Logger logger)
|
||||||
|
: base(diskProvider, logger)
|
||||||
|
{
|
||||||
|
_appFolderInfo = appFolderInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string Map(string resourceUrl)
|
||||||
|
{
|
||||||
|
var path = resourceUrl.Replace('/', Path.DirectorySeparatorChar);
|
||||||
|
path = Path.GetFileName(path);
|
||||||
|
|
||||||
|
return Path.Combine(_appFolderInfo.GetLogFolder(), path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanHandle(string resourceUrl)
|
||||||
|
{
|
||||||
|
return resourceUrl.StartsWith("/logfile/") && resourceUrl.EndsWith(".txt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,63 +1,43 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
using Nancy;
|
using NzbDrone.Core.Configuration;
|
||||||
using Nancy.Responses;
|
|
||||||
|
|
||||||
namespace NzbDrone.Api.Logs
|
namespace NzbDrone.Api.Logs
|
||||||
{
|
{
|
||||||
public class LogFileModule : NzbDroneRestModule<LogFileResource>
|
public class LogFileModule : LogFileModuleBase
|
||||||
{
|
{
|
||||||
private const string LOGFILE_ROUTE = @"/(?<filename>nzbdrone(?:\.\d+)?\.txt)";
|
|
||||||
|
|
||||||
private readonly IAppFolderInfo _appFolderInfo;
|
private readonly IAppFolderInfo _appFolderInfo;
|
||||||
private readonly IDiskProvider _diskProvider;
|
private readonly IDiskProvider _diskProvider;
|
||||||
|
|
||||||
public LogFileModule(IAppFolderInfo appFolderInfo,
|
public LogFileModule(IAppFolderInfo appFolderInfo,
|
||||||
IDiskProvider diskProvider)
|
IDiskProvider diskProvider,
|
||||||
: base("log/file")
|
IConfigFileProvider configFileProvider)
|
||||||
|
: base(diskProvider, configFileProvider, "")
|
||||||
{
|
{
|
||||||
_appFolderInfo = appFolderInfo;
|
_appFolderInfo = appFolderInfo;
|
||||||
_diskProvider = diskProvider;
|
_diskProvider = diskProvider;
|
||||||
GetResourceAll = GetLogFiles;
|
|
||||||
|
|
||||||
Get[LOGFILE_ROUTE] = options => GetLogFile(options.filename);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<LogFileResource> GetLogFiles()
|
protected override IEnumerable<string> GetLogFiles()
|
||||||
{
|
{
|
||||||
var result = new List<LogFileResource>();
|
return _diskProvider.GetFiles(_appFolderInfo.GetLogFolder(), SearchOption.TopDirectoryOnly);
|
||||||
|
}
|
||||||
var files = _diskProvider.GetFiles(_appFolderInfo.GetLogFolder(), SearchOption.TopDirectoryOnly);
|
|
||||||
|
|
||||||
for (int i = 0; i < files.Length; i++)
|
protected override string GetLogFilePath(string filename)
|
||||||
|
{
|
||||||
|
return Path.Combine(_appFolderInfo.GetLogFolder(), filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string DownloadUrlRoot
|
||||||
|
{
|
||||||
|
get
|
||||||
{
|
{
|
||||||
var file = files[i];
|
return "logfile";
|
||||||
|
|
||||||
result.Add(new LogFileResource
|
|
||||||
{
|
|
||||||
Id = i + 1,
|
|
||||||
Filename = Path.GetFileName(file),
|
|
||||||
LastWriteTime = _diskProvider.FileGetLastWriteUtc(file)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.OrderByDescending(l => l.LastWriteTime).ToList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response GetLogFile(string filename)
|
|
||||||
{
|
|
||||||
var filePath = Path.Combine(_appFolderInfo.GetLogFolder(), filename);
|
|
||||||
|
|
||||||
if (!_diskProvider.FileExists(filePath))
|
|
||||||
return new NotFoundResponse();
|
|
||||||
|
|
||||||
var data = _diskProvider.ReadAllText(filePath);
|
|
||||||
|
|
||||||
return new TextResponse(data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
|
using Nancy;
|
||||||
|
using Nancy.Responses;
|
||||||
|
using NzbDrone.Core.Configuration;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Logs
|
||||||
|
{
|
||||||
|
public abstract class LogFileModuleBase : NzbDroneRestModule<LogFileResource>
|
||||||
|
{
|
||||||
|
protected const string LOGFILE_ROUTE = @"/(?<filename>[-.a-zA-Z0-9]+?\.txt)";
|
||||||
|
|
||||||
|
private readonly IDiskProvider _diskProvider;
|
||||||
|
private readonly IConfigFileProvider _configFileProvider;
|
||||||
|
|
||||||
|
public LogFileModuleBase(IDiskProvider diskProvider,
|
||||||
|
IConfigFileProvider configFileProvider,
|
||||||
|
String route)
|
||||||
|
: base("log/file" + route)
|
||||||
|
{
|
||||||
|
_diskProvider = diskProvider;
|
||||||
|
_configFileProvider = configFileProvider;
|
||||||
|
GetResourceAll = GetLogFilesResponse;
|
||||||
|
|
||||||
|
Get[LOGFILE_ROUTE] = options => GetLogFileResponse(options.filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<LogFileResource> GetLogFilesResponse()
|
||||||
|
{
|
||||||
|
var result = new List<LogFileResource>();
|
||||||
|
|
||||||
|
var files = GetLogFiles().ToList();
|
||||||
|
|
||||||
|
for (int i = 0; i < files.Count; i++)
|
||||||
|
{
|
||||||
|
var file = files[i];
|
||||||
|
var filename = Path.GetFileName(file);
|
||||||
|
|
||||||
|
result.Add(new LogFileResource
|
||||||
|
{
|
||||||
|
Id = i + 1,
|
||||||
|
Filename = filename,
|
||||||
|
LastWriteTime = _diskProvider.FileGetLastWriteUtc(file),
|
||||||
|
ContentsUrl = String.Format("{0}/api/{1}/{2}", _configFileProvider.UrlBase, Resource, filename),
|
||||||
|
DownloadUrl = String.Format("{0}/{1}/{2}", _configFileProvider.UrlBase, DownloadUrlRoot, filename)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.OrderByDescending(l => l.LastWriteTime).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Response GetLogFileResponse(String filename)
|
||||||
|
{
|
||||||
|
var filePath = GetLogFilePath(filename);
|
||||||
|
|
||||||
|
if (!_diskProvider.FileExists(filePath))
|
||||||
|
return new NotFoundResponse();
|
||||||
|
|
||||||
|
var data = _diskProvider.ReadAllText(filePath);
|
||||||
|
|
||||||
|
return new TextResponse(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract IEnumerable<String> GetLogFiles();
|
||||||
|
protected abstract String GetLogFilePath(String filename);
|
||||||
|
|
||||||
|
protected abstract String DownloadUrlRoot { get; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,5 +7,7 @@ namespace NzbDrone.Api.Logs
|
||||||
{
|
{
|
||||||
public String Filename { get; set; }
|
public String Filename { get; set; }
|
||||||
public DateTime LastWriteTime { get; set; }
|
public DateTime LastWriteTime { get; set; }
|
||||||
|
public String ContentsUrl { get; set; }
|
||||||
|
public String DownloadUrl { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
|
using NzbDrone.Core.Configuration;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Logs
|
||||||
|
{
|
||||||
|
public class UpdateLogFileModule : LogFileModuleBase
|
||||||
|
{
|
||||||
|
private readonly IAppFolderInfo _appFolderInfo;
|
||||||
|
private readonly IDiskProvider _diskProvider;
|
||||||
|
|
||||||
|
public UpdateLogFileModule(IAppFolderInfo appFolderInfo,
|
||||||
|
IDiskProvider diskProvider,
|
||||||
|
IConfigFileProvider configFileProvider)
|
||||||
|
: base(diskProvider, configFileProvider, "/update")
|
||||||
|
{
|
||||||
|
_appFolderInfo = appFolderInfo;
|
||||||
|
_diskProvider = diskProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IEnumerable<String> GetLogFiles()
|
||||||
|
{
|
||||||
|
return _diskProvider.GetFiles(_appFolderInfo.GetUpdateLogFolder(), SearchOption.TopDirectoryOnly)
|
||||||
|
.Where(f => Regex.IsMatch(Path.GetFileName(f), LOGFILE_ROUTE.TrimStart('/'), RegexOptions.IgnoreCase))
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override String GetLogFilePath(String filename)
|
||||||
|
{
|
||||||
|
return Path.Combine(_appFolderInfo.GetUpdateLogFolder(), filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override String DownloadUrlRoot
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return "updatelogfile";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -117,6 +117,7 @@
|
||||||
<Compile Include="EpisodeFiles\EpisodeFileResource.cs" />
|
<Compile Include="EpisodeFiles\EpisodeFileResource.cs" />
|
||||||
<Compile Include="Directories\DirectoryLookupService.cs" />
|
<Compile Include="Directories\DirectoryLookupService.cs" />
|
||||||
<Compile Include="Directories\DirectoryModule.cs" />
|
<Compile Include="Directories\DirectoryModule.cs" />
|
||||||
|
<Compile Include="Episodes\EpisodeModuleWithSignalR.cs" />
|
||||||
<Compile Include="Episodes\EpisodeModule.cs" />
|
<Compile Include="Episodes\EpisodeModule.cs" />
|
||||||
<Compile Include="Episodes\EpisodeResource.cs" />
|
<Compile Include="Episodes\EpisodeResource.cs" />
|
||||||
<Compile Include="Episodes\RenameEpisodeModule.cs" />
|
<Compile Include="Episodes\RenameEpisodeModule.cs" />
|
||||||
|
@ -129,6 +130,7 @@
|
||||||
<Compile Include="Extensions\NancyJsonSerializer.cs" />
|
<Compile Include="Extensions\NancyJsonSerializer.cs" />
|
||||||
<Compile Include="Extensions\RequestExtensions.cs" />
|
<Compile Include="Extensions\RequestExtensions.cs" />
|
||||||
<Compile Include="Frontend\IsCacheableSpecification.cs" />
|
<Compile Include="Frontend\IsCacheableSpecification.cs" />
|
||||||
|
<Compile Include="Frontend\Mappers\UpdateLogFileMapper.cs" />
|
||||||
<Compile Include="Frontend\Mappers\FaviconMapper.cs" />
|
<Compile Include="Frontend\Mappers\FaviconMapper.cs" />
|
||||||
<Compile Include="Frontend\Mappers\IndexHtmlMapper.cs" />
|
<Compile Include="Frontend\Mappers\IndexHtmlMapper.cs" />
|
||||||
<Compile Include="Frontend\Mappers\LogFileMapper.cs" />
|
<Compile Include="Frontend\Mappers\LogFileMapper.cs" />
|
||||||
|
@ -141,6 +143,8 @@
|
||||||
<Compile Include="Health\HealthModule.cs" />
|
<Compile Include="Health\HealthModule.cs" />
|
||||||
<Compile Include="History\HistoryResource.cs" />
|
<Compile Include="History\HistoryResource.cs" />
|
||||||
<Compile Include="History\HistoryModule.cs" />
|
<Compile Include="History\HistoryModule.cs" />
|
||||||
|
<Compile Include="Logs\LogFileModuleBase.cs" />
|
||||||
|
<Compile Include="Logs\UpdateLogFileModule.cs" />
|
||||||
<Compile Include="MediaCovers\MediaCoverModule.cs" />
|
<Compile Include="MediaCovers\MediaCoverModule.cs" />
|
||||||
<Compile Include="Metadata\MetadataResource.cs" />
|
<Compile Include="Metadata\MetadataResource.cs" />
|
||||||
<Compile Include="Metadata\MetadataModule.cs" />
|
<Compile Include="Metadata\MetadataModule.cs" />
|
||||||
|
|
|
@ -2,17 +2,18 @@
|
||||||
using NzbDrone.Api.Episodes;
|
using NzbDrone.Api.Episodes;
|
||||||
using NzbDrone.Api.Extensions;
|
using NzbDrone.Api.Extensions;
|
||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Wanted
|
namespace NzbDrone.Api.Wanted
|
||||||
{
|
{
|
||||||
public class CutoffModule : NzbDroneRestModule<EpisodeResource>
|
public class CutoffModule : EpisodeModuleWithSignalR
|
||||||
{
|
{
|
||||||
private readonly IEpisodeCutoffService _episodeCutoffService;
|
private readonly IEpisodeCutoffService _episodeCutoffService;
|
||||||
private readonly SeriesRepository _seriesRepository;
|
private readonly ISeriesRepository _seriesRepository;
|
||||||
|
|
||||||
public CutoffModule(IEpisodeCutoffService episodeCutoffService, SeriesRepository seriesRepository)
|
public CutoffModule(IEpisodeService episodeService, IEpisodeCutoffService episodeCutoffService, ISeriesRepository seriesRepository, ICommandExecutor commandExecutor)
|
||||||
:base("wanted/cutoff")
|
:base(episodeService, commandExecutor, "wanted/cutoff")
|
||||||
{
|
{
|
||||||
_episodeCutoffService = episodeCutoffService;
|
_episodeCutoffService = episodeCutoffService;
|
||||||
_seriesRepository = seriesRepository;
|
_seriesRepository = seriesRepository;
|
||||||
|
|
|
@ -2,17 +2,18 @@
|
||||||
using NzbDrone.Api.Episodes;
|
using NzbDrone.Api.Episodes;
|
||||||
using NzbDrone.Api.Extensions;
|
using NzbDrone.Api.Extensions;
|
||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Wanted
|
namespace NzbDrone.Api.Wanted
|
||||||
{
|
{
|
||||||
public class MissingModule : NzbDroneRestModule<EpisodeResource>
|
public class MissingModule : EpisodeModuleWithSignalR
|
||||||
{
|
{
|
||||||
private readonly IEpisodeService _episodeService;
|
private readonly IEpisodeService _episodeService;
|
||||||
private readonly SeriesRepository _seriesRepository;
|
private readonly ISeriesRepository _seriesRepository;
|
||||||
|
|
||||||
public MissingModule(IEpisodeService episodeService, SeriesRepository seriesRepository)
|
public MissingModule(IEpisodeService episodeService, ISeriesRepository seriesRepository, ICommandExecutor commandExecutor)
|
||||||
:base("wanted/missing")
|
:base(episodeService, commandExecutor, "wanted/missing")
|
||||||
{
|
{
|
||||||
_episodeService = episodeService;
|
_episodeService = episodeService;
|
||||||
_seriesRepository = seriesRepository;
|
_seriesRepository = seriesRepository;
|
||||||
|
|
|
@ -42,9 +42,8 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||||
{
|
{
|
||||||
var url = remoteEpisode.Release.DownloadUrl;
|
var url = remoteEpisode.Release.DownloadUrl;
|
||||||
var title = remoteEpisode.Release.Title + ".nzb";
|
var title = remoteEpisode.Release.Title + ".nzb";
|
||||||
|
var category = Settings.TvCategory;
|
||||||
string category = Settings.TvCategory;
|
var priority = remoteEpisode.IsRecentEpisode() ? Settings.RecentTvPriority : Settings.OlderTvPriority;
|
||||||
int priority = remoteEpisode.IsRecentEpisode() ? Settings.RecentTvPriority : Settings.OlderTvPriority;
|
|
||||||
|
|
||||||
_logger.Info("Adding report [{0}] to the queue.", title);
|
_logger.Info("Adding report [{0}] to the queue.", title);
|
||||||
|
|
||||||
|
@ -271,10 +270,9 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||||
_proxy.GetVersion(settings);
|
_proxy.GetVersion(settings);
|
||||||
|
|
||||||
var config = _proxy.GetConfig(settings);
|
var config = _proxy.GetConfig(settings);
|
||||||
|
|
||||||
var categories = GetCategories(config);
|
var categories = GetCategories(config);
|
||||||
|
|
||||||
if (!categories.Any(v => v.Name == settings.TvCategory))
|
if (!settings.TvCategory.IsNullOrWhiteSpace() && !categories.Any(v => v.Name == settings.TvCategory))
|
||||||
{
|
{
|
||||||
throw new ApplicationException("Category does not exist");
|
throw new ApplicationException("Category does not exist");
|
||||||
}
|
}
|
||||||
|
|
|
@ -222,7 +222,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||||
{
|
{
|
||||||
var categories = _proxy.GetCategories(settings);
|
var categories = _proxy.GetCategories(settings);
|
||||||
|
|
||||||
if (!categories.Any(v => v == settings.TvCategory))
|
if (!settings.TvCategory.IsNullOrWhiteSpace() && !categories.Any(v => v == settings.TvCategory))
|
||||||
{
|
{
|
||||||
throw new ApplicationException("Category does not exist");
|
throw new ApplicationException("Category does not exist");
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Instrumentation.Commands
|
||||||
|
{
|
||||||
|
public class DeleteUpdateLogFilesCommand : Command
|
||||||
|
{
|
||||||
|
public override bool SendUpdatesToClient
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
using System.IO;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
|
@ -12,7 +13,7 @@ namespace NzbDrone.Core.Instrumentation
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DeleteLogFilesService : IDeleteLogFilesService, IExecute<DeleteLogFilesCommand>
|
public class DeleteLogFilesService : IDeleteLogFilesService, IExecute<DeleteLogFilesCommand>, IExecute<DeleteUpdateLogFilesCommand>
|
||||||
{
|
{
|
||||||
private readonly IDiskProvider _diskProvider;
|
private readonly IDiskProvider _diskProvider;
|
||||||
private readonly IAppFolderInfo _appFolderInfo;
|
private readonly IAppFolderInfo _appFolderInfo;
|
||||||
|
@ -27,12 +28,14 @@ namespace NzbDrone.Core.Instrumentation
|
||||||
|
|
||||||
public void Execute(DeleteLogFilesCommand message)
|
public void Execute(DeleteLogFilesCommand message)
|
||||||
{
|
{
|
||||||
var logFiles = _diskProvider.GetFiles(_appFolderInfo.GetLogFolder(), SearchOption.TopDirectoryOnly);
|
_logger.Debug("Deleting all files in: {0}", _appFolderInfo.GetLogFolder());
|
||||||
|
_diskProvider.EmptyFolder(_appFolderInfo.GetLogFolder());
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var logFile in logFiles)
|
public void Execute(DeleteUpdateLogFilesCommand message)
|
||||||
{
|
{
|
||||||
_diskProvider.DeleteFile(logFile);
|
_logger.Debug("Deleting all files in: {0}", _appFolderInfo.GetUpdateLogFolder());
|
||||||
}
|
_diskProvider.EmptyFolder(_appFolderInfo.GetUpdateLogFolder());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,8 +73,9 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
|
|
||||||
private IEnumerable<RenameEpisodeFilePreview> GetPreviews(Series series, List<Episode> episodes, List<EpisodeFile> files)
|
private IEnumerable<RenameEpisodeFilePreview> GetPreviews(Series series, List<Episode> episodes, List<EpisodeFile> files)
|
||||||
{
|
{
|
||||||
foreach (var file in files)
|
foreach (var f in files)
|
||||||
{
|
{
|
||||||
|
var file = f;
|
||||||
var episodesInFile = episodes.Where(e => e.EpisodeFileId == file.Id).ToList();
|
var episodesInFile = episodes.Where(e => e.EpisodeFileId == file.Id).ToList();
|
||||||
|
|
||||||
if (!episodesInFile.Any())
|
if (!episodesInFile.Any())
|
||||||
|
@ -95,18 +96,13 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
SeasonNumber = seasonNumber,
|
SeasonNumber = seasonNumber,
|
||||||
EpisodeNumbers = episodesInFile.Select(e => e.EpisodeNumber).ToList(),
|
EpisodeNumbers = episodesInFile.Select(e => e.EpisodeNumber).ToList(),
|
||||||
EpisodeFileId = file.Id,
|
EpisodeFileId = file.Id,
|
||||||
ExistingPath = GetRelativePath(series.Path, file.Path),
|
ExistingPath = series.Path.GetRelativePath(file.Path),
|
||||||
NewPath = GetRelativePath(series.Path, newPath)
|
NewPath = series.Path.GetRelativePath(newPath)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetRelativePath(string seriesPath, string path)
|
|
||||||
{
|
|
||||||
return path.Substring(seriesPath.Length + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RenameFiles(List<EpisodeFile> episodeFiles, Series series)
|
private void RenameFiles(List<EpisodeFile> episodeFiles, Series series)
|
||||||
{
|
{
|
||||||
var renamed = new List<EpisodeFile>();
|
var renamed = new List<EpisodeFile>();
|
||||||
|
|
|
@ -334,6 +334,7 @@
|
||||||
<Compile Include="Indexers\RssSyncCommand.cs" />
|
<Compile Include="Indexers\RssSyncCommand.cs" />
|
||||||
<Compile Include="Indexers\XElementExtensions.cs" />
|
<Compile Include="Indexers\XElementExtensions.cs" />
|
||||||
<Compile Include="Instrumentation\Commands\ClearLogCommand.cs" />
|
<Compile Include="Instrumentation\Commands\ClearLogCommand.cs" />
|
||||||
|
<Compile Include="Instrumentation\Commands\DeleteUpdateLogFilesCommand.cs" />
|
||||||
<Compile Include="Instrumentation\Commands\DeleteLogFilesCommand.cs" />
|
<Compile Include="Instrumentation\Commands\DeleteLogFilesCommand.cs" />
|
||||||
<Compile Include="Instrumentation\Commands\TrimLogCommand.cs" />
|
<Compile Include="Instrumentation\Commands\TrimLogCommand.cs" />
|
||||||
<Compile Include="Instrumentation\DeleteLogFilesService.cs" />
|
<Compile Include="Instrumentation\DeleteLogFilesService.cs" />
|
||||||
|
|
|
@ -55,7 +55,7 @@ define(
|
||||||
|
|
||||||
_importSeries: function () {
|
_importSeries: function () {
|
||||||
this.rootFolderLayout = new RootFolderLayout();
|
this.rootFolderLayout = new RootFolderLayout();
|
||||||
this.rootFolderLayout.on('folderSelected', this._folderSelected, this);
|
this.listenTo(this.rootFolderLayout, 'folderSelected', this._folderSelected);
|
||||||
AppLayout.modalRegion.show(this.rootFolderLayout);
|
AppLayout.modalRegion.show(this.rootFolderLayout);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -10,9 +10,14 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<h2 class="series-title">
|
<h2 class="series-title">
|
||||||
{{titleWithYear}}
|
{{titleWithYear}}
|
||||||
{{#unless_eq status compare="continuing"}}
|
|
||||||
<span class="label label-important">Ended</span>
|
<span class="labels">
|
||||||
{{/unless_eq}}
|
<span class="label label-primary">{{network}}</span>
|
||||||
|
{{#unless_eq status compare="continuing"}}
|
||||||
|
<span class="label label-danger">Ended</span>
|
||||||
|
{{/unless_eq}}
|
||||||
|
</span>
|
||||||
|
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="row new-series-overview x-overview">
|
<div class="row new-series-overview x-overview">
|
||||||
|
|
|
@ -40,9 +40,13 @@
|
||||||
padding-bottom : 20px;
|
padding-bottom : 20px;
|
||||||
|
|
||||||
.series-title {
|
.series-title {
|
||||||
.label {
|
.labels {
|
||||||
margin-left: 15px;
|
margin-left : 10px;
|
||||||
vertical-align: middle;
|
|
||||||
|
.label {
|
||||||
|
font-size : 12px;
|
||||||
|
vertical-align : middle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.year {
|
.year {
|
||||||
|
|
|
@ -14,7 +14,7 @@ define(
|
||||||
},
|
},
|
||||||
|
|
||||||
templateHelpers: {
|
templateHelpers: {
|
||||||
icalHttpUrl : window.location.protocol + '//' + window.location.host + StatusModel.get('urlBase') + '/feed/calendar/NzbDrone.ics',
|
icalHttpUrl : window.location.protocol + '//' + window.location.host + StatusModel.get('urlBase') + '/feed/calendar/NzbDrone.ics?apikey=' + window.NzbDrone.ApiKey,
|
||||||
icalWebCalUrl : 'webcal://' + window.location.host + StatusModel.get('urlBase') + '/feed/calendar/NzbDrone.ics'
|
icalWebCalUrl : 'webcal://' + window.location.host + StatusModel.get('urlBase') + '/feed/calendar/NzbDrone.ics'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -6,21 +6,26 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body edit-series-modal">
|
<div class="modal-body edit-series-modal">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div>
|
<div class="col-md-12">
|
||||||
<div class="form-horizontal">
|
<div class="form-horizontal">
|
||||||
<div class="form-group">
|
|
||||||
<label class="control-label">iCal feed</label>
|
|
||||||
|
|
||||||
<div class="controls ical-url">
|
<div class="form-group">
|
||||||
<div class="input-group">
|
<label class="col-sm-3 control-label">iCal feed</label>
|
||||||
<input type="text" class="x-ical-url" value="{{icalHttpUrl}}" readonly="readonly" />
|
|
||||||
<button class="btn btn-icon-only x-ical-copy" title="Copy to clipboard"><i class="icon-copy"></i></button>
|
<div class="col-sm-1 col-sm-push-8 help-inline">
|
||||||
<a class="btn btn-icon-only no-router" title="Subscribe" href="{{icalWebCalUrl}}" target="_blank"><i class="icon-calendar-empty"></i></a>
|
<i class="icon-nd-form-info" title="Copy this url into your clients subscription form or use the subscribe button if your browser support webcal"/>
|
||||||
</div>
|
|
||||||
<span class="help-inline">
|
|
||||||
<i class="icon-nd-form-info" title="Copy this url into your clients subscription form or use the subscribe button if your browser support webcal"/>
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-8 col-sm-pull-1">
|
||||||
|
<div class="input-group ical-url">
|
||||||
|
<input type="text" class="form-control x-ical-url" value="{{icalHttpUrl}}" readonly="readonly" />
|
||||||
|
<div class="input-group-btn">
|
||||||
|
<button class="btn btn-icon-only x-ical-copy" title="Copy to clipboard"><i class="icon-copy"></i></button>
|
||||||
|
<button class="btn btn-icon-only no-router"><a title="Subscribe" href="{{icalWebCalUrl}}" target="_blank"><i class="icon-calendar-empty"></i></a></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -178,7 +178,6 @@
|
||||||
.ical-url {
|
.ical-url {
|
||||||
|
|
||||||
input {
|
input {
|
||||||
width : 440px;
|
cursor : text !important;
|
||||||
cursor : text;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,8 +67,9 @@ define(
|
||||||
|
|
||||||
initialize: function () {
|
initialize: function () {
|
||||||
this.collection = new BlacklistCollection({ tableName: 'blacklist' });
|
this.collection = new BlacklistCollection({ tableName: 'blacklist' });
|
||||||
|
|
||||||
this.listenTo(this.collection, 'sync', this._showTable);
|
this.listenTo(this.collection, 'sync', this._showTable);
|
||||||
vent.on(vent.Events.CommandComplete, this._commandComplete, this);
|
this.listenTo(vent, vent.Events.CommandComplete, this._commandComplete);
|
||||||
},
|
},
|
||||||
|
|
||||||
onShow: function () {
|
onShow: function () {
|
||||||
|
|
|
@ -59,8 +59,7 @@ define(
|
||||||
initialize: function () {
|
initialize: function () {
|
||||||
this.listenTo(this.model, 'change:monitored', this._setMonitoredState);
|
this.listenTo(this.model, 'change:monitored', this._setMonitoredState);
|
||||||
this.listenTo(vent, vent.Events.SeriesDeleted, this._onSeriesDeleted);
|
this.listenTo(vent, vent.Events.SeriesDeleted, this._onSeriesDeleted);
|
||||||
|
this.listenTo(vent, vent.Events.CommandComplete, this._commandComplete);
|
||||||
vent.on(vent.Events.CommandComplete, this._commandComplete, this);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onShow: function () {
|
onShow: function () {
|
||||||
|
|
|
@ -31,7 +31,7 @@ define(
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize: function () {
|
initialize: function () {
|
||||||
vent.on(vent.Events.CommandComplete, this._commandComplete, this);
|
this.listenTo(vent, vent.Events.CommandComplete, this._commandComplete);
|
||||||
},
|
},
|
||||||
|
|
||||||
onRender: function(){
|
onRender: function(){
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
define(
|
define(
|
||||||
[
|
[
|
||||||
'backbone',
|
'backbone'
|
||||||
'System/StatusModel'
|
], function (Backbone) {
|
||||||
], function (Backbone, StatusModel) {
|
|
||||||
return Backbone.Model.extend({
|
return Backbone.Model.extend({
|
||||||
url: function () {
|
url: function () {
|
||||||
return StatusModel.get('urlBase') + '/api/log/file/' + this.get('filename');
|
return this.get('contentsUrl');
|
||||||
},
|
},
|
||||||
|
|
||||||
parse: function (contents) {
|
parse: function (contents) {
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
define(
|
define(
|
||||||
[
|
[
|
||||||
'Cells/NzbDroneCell',
|
'../../../Cells/NzbDroneCell'
|
||||||
'System/StatusModel'
|
], function (NzbDroneCell) {
|
||||||
], function (NzbDroneCell, StatusModel) {
|
|
||||||
return NzbDroneCell.extend({
|
return NzbDroneCell.extend({
|
||||||
|
|
||||||
className: 'download-log-cell',
|
className: 'download-log-cell',
|
||||||
|
|
||||||
render: function () {
|
render: function () {
|
||||||
this.$el.empty();
|
this.$el.empty();
|
||||||
this.$el.html('<a href="{0}/logfile/{1}" class="no-router" target="_blank">Download</a>'.format(StatusModel.get('urlBase'), this.cellValue));
|
this.$el.html('<a href="{0}" class="no-router" target="_blank">Download</a>'.format(this.cellValue));
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
define(
|
define(
|
||||||
[
|
[
|
||||||
'Cells/NzbDroneCell'
|
'../../../Cells/NzbDroneCell'
|
||||||
], function (NzbDroneCell) {
|
], function (NzbDroneCell) {
|
||||||
return NzbDroneCell.extend({
|
return NzbDroneCell.extend({
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ define(
|
||||||
'System/Logs/Files/FilenameCell',
|
'System/Logs/Files/FilenameCell',
|
||||||
'Cells/RelativeDateCell',
|
'Cells/RelativeDateCell',
|
||||||
'System/Logs/Files/DownloadLogCell',
|
'System/Logs/Files/DownloadLogCell',
|
||||||
'System/Logs/Files/LogFileCollection',
|
|
||||||
'System/Logs/Files/Row',
|
'System/Logs/Files/Row',
|
||||||
'System/Logs/Files/ContentsView',
|
'System/Logs/Files/ContentsView',
|
||||||
'System/Logs/Files/ContentsModel',
|
'System/Logs/Files/ContentsModel',
|
||||||
|
@ -20,7 +19,6 @@ define(
|
||||||
FilenameCell,
|
FilenameCell,
|
||||||
RelativeDateCell,
|
RelativeDateCell,
|
||||||
DownloadLogCell,
|
DownloadLogCell,
|
||||||
LogFileCollection,
|
|
||||||
LogFileRow,
|
LogFileRow,
|
||||||
ContentsView,
|
ContentsView,
|
||||||
ContentsModel,
|
ContentsModel,
|
||||||
|
@ -48,18 +46,19 @@ define(
|
||||||
cell : RelativeDateCell
|
cell : RelativeDateCell
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name : 'filename',
|
name : 'downloadUrl',
|
||||||
label : '',
|
label : '',
|
||||||
cell : DownloadLogCell,
|
cell : DownloadLogCell,
|
||||||
sortable: false
|
sortable: false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
initialize: function () {
|
initialize: function (options) {
|
||||||
this.collection = new LogFileCollection();
|
this.collection = options.collection;
|
||||||
|
this.deleteFilesCommand = options.deleteFilesCommand;
|
||||||
|
|
||||||
vent.on(vent.Commands.ShowLogFile, this._fetchLogFileContents, this);
|
this.listenTo(vent, vent.Commands.ShowLogFile, this._fetchLogFileContents);
|
||||||
vent.on(vent.Events.CommandComplete, this._commandComplete, this);
|
this.listenTo(vent, vent.Events.CommandComplete, this._commandComplete);
|
||||||
this.listenTo(this.collection, 'sync', this._collectionSynced);
|
this.listenTo(this.collection, 'sync', this._collectionSynced);
|
||||||
|
|
||||||
this.collection.fetch();
|
this.collection.fetch();
|
||||||
|
@ -83,11 +82,10 @@ define(
|
||||||
ownerContext : this,
|
ownerContext : this,
|
||||||
callback : this._refreshTable
|
callback : this._refreshTable
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
title : 'Delete Log Files',
|
title : 'Delete Log Files',
|
||||||
icon : 'icon-trash',
|
icon : 'icon-trash',
|
||||||
command : 'deleteLogFiles',
|
command : this.deleteFilesCommand,
|
||||||
successMessage : 'Log files have been deleted',
|
successMessage : 'Log files have been deleted',
|
||||||
errorMessage : 'Failed to delete log files'
|
errorMessage : 'Failed to delete log files'
|
||||||
}
|
}
|
||||||
|
@ -125,11 +123,7 @@ define(
|
||||||
this.contents.show(new LoadingView());
|
this.contents.show(new LoadingView());
|
||||||
|
|
||||||
var model = options.model;
|
var model = options.model;
|
||||||
var filename = model.get('filename');
|
var contentsModel = new ContentsModel(model.toJSON());
|
||||||
|
|
||||||
var contentsModel = new ContentsModel({
|
|
||||||
filename: filename
|
|
||||||
});
|
|
||||||
|
|
||||||
this.listenToOnce(contentsModel, 'sync', this._showDetails);
|
this.listenToOnce(contentsModel, 'sync', this._showDetails);
|
||||||
|
|
||||||
|
@ -151,7 +145,7 @@ define(
|
||||||
},
|
},
|
||||||
|
|
||||||
_commandComplete: function (options) {
|
_commandComplete: function (options) {
|
||||||
if (options.command.get('name') === 'deletelogfiles') {
|
if (options.command.get('name') === this.deleteFilesCommand.toLowerCase()) {
|
||||||
this._refreshTable();
|
this._refreshTable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
define(
|
define(
|
||||||
[
|
[
|
||||||
'vent',
|
'../../../vent',
|
||||||
'backgrid'
|
'backgrid'
|
||||||
], function (vent, Backgrid) {
|
], function (vent, Backgrid) {
|
||||||
|
|
||||||
|
|
|
@ -3,24 +3,29 @@ define(
|
||||||
[
|
[
|
||||||
'marionette',
|
'marionette',
|
||||||
'System/Logs/Table/LogsTableLayout',
|
'System/Logs/Table/LogsTableLayout',
|
||||||
'System/Logs/Files/LogFileLayout'
|
'System/Logs/Files/LogFileLayout',
|
||||||
], function (Marionette, LogsTableLayout, LogsFileLayout) {
|
'System/Logs/Files/LogFileCollection',
|
||||||
|
'System/Logs/Updates/LogFileCollection'
|
||||||
|
], function (Marionette, LogsTableLayout, LogsFileLayout, LogFileCollection, UpdateLogFileCollection) {
|
||||||
return Marionette.Layout.extend({
|
return Marionette.Layout.extend({
|
||||||
template: 'System/Logs/LogsLayoutTemplate',
|
template: 'System/Logs/LogsLayoutTemplate',
|
||||||
|
|
||||||
ui: {
|
ui: {
|
||||||
tableTab: '.x-table-tab',
|
tableTab : '.x-table-tab',
|
||||||
filesTab: '.x-files-tab'
|
filesTab : '.x-files-tab',
|
||||||
|
updateFilesTab : '.x-update-files-tab'
|
||||||
},
|
},
|
||||||
|
|
||||||
regions: {
|
regions: {
|
||||||
table: '#table',
|
table : '#table',
|
||||||
files: '#files'
|
files : '#files',
|
||||||
|
updateFiles : '#update-files'
|
||||||
},
|
},
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
'click .x-table-tab': '_showTable',
|
'click .x-table-tab' : '_showTable',
|
||||||
'click .x-files-tab': '_showFiles'
|
'click .x-files-tab' : '_showFiles',
|
||||||
|
'click .x-update-files-tab' : '_showUpdateFiles'
|
||||||
},
|
},
|
||||||
|
|
||||||
onShow: function () {
|
onShow: function () {
|
||||||
|
@ -42,7 +47,22 @@ define(
|
||||||
}
|
}
|
||||||
|
|
||||||
this.ui.filesTab.tab('show');
|
this.ui.filesTab.tab('show');
|
||||||
this.files.show(new LogsFileLayout());
|
this.files.show(new LogsFileLayout({
|
||||||
|
collection: new LogFileCollection(),
|
||||||
|
deleteFilesCommand: 'deleteLogFiles'
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
_showUpdateFiles: function (e) {
|
||||||
|
if (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ui.updateFilesTab.tab('show');
|
||||||
|
this.updateFiles.show(new LogsFileLayout({
|
||||||
|
collection: new UpdateLogFileCollection(),
|
||||||
|
deleteFilesCommand: 'deleteUpdateLogFiles'
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-1 col-sm-2">
|
<div class="col-md-2 col-sm-2">
|
||||||
<ul class="nav nav-pills nav-stacked">
|
<ul class="nav nav-pills nav-stacked">
|
||||||
<li><a href="#table" class="x-table-tab no-router">Table</a></li>
|
<li><a href="#table" class="x-table-tab no-router">Table</a></li>
|
||||||
<li><a href="#files" class="x-files-tab no-router">Files</a></li>
|
<li><a href="#files" class="x-files-tab no-router">Files</a></li>
|
||||||
|
<li><a href="#update-files" class="x-update-files-tab no-router">Updates</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-11 col-sm-10">
|
<div class="col-md-10 col-sm-10">
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
<div class="tab-pane" id="table"></div>
|
<div class="tab-pane" id="table"></div>
|
||||||
<div class="tab-pane" id="files"></div>
|
<div class="tab-pane" id="files"></div>
|
||||||
|
<div class="tab-pane" id="update-files"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -61,7 +61,7 @@ define(
|
||||||
this.collection = new LogCollection();
|
this.collection = new LogCollection();
|
||||||
|
|
||||||
this.listenTo(this.collection, 'sync', this._showTable);
|
this.listenTo(this.collection, 'sync', this._showTable);
|
||||||
vent.on(vent.Events.CommandComplete, this._commandComplete, this);
|
this.listenTo(vent, vent.Events.CommandComplete, this._commandComplete);
|
||||||
},
|
},
|
||||||
|
|
||||||
onRender: function () {
|
onRender: function () {
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
define(
|
||||||
|
[
|
||||||
|
'backbone',
|
||||||
|
'System/Logs/Updates/LogFileModel'
|
||||||
|
], function (Backbone, LogFileModel) {
|
||||||
|
return Backbone.Collection.extend({
|
||||||
|
url : window.NzbDrone.ApiRoot + '/log/file/update',
|
||||||
|
model: LogFileModel,
|
||||||
|
|
||||||
|
state: {
|
||||||
|
sortKey: 'lastWriteTime',
|
||||||
|
order : 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,8 @@
|
||||||
|
'use strict';
|
||||||
|
define(
|
||||||
|
[
|
||||||
|
'backbone'
|
||||||
|
], function (Backbone) {
|
||||||
|
return Backbone.Model.extend({
|
||||||
|
});
|
||||||
|
});
|
|
@ -4,10 +4,10 @@
|
||||||
<li><a href="#updates" class="x-updates-tab no-router">Updates</a></li>
|
<li><a href="#updates" class="x-updates-tab no-router">Updates</a></li>
|
||||||
<li class="lifecycle-controls pull-right">
|
<li class="lifecycle-controls pull-right">
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button class="btn btn-default btn-icon-only x-shutdown" title="Shutdown">
|
<button class="btn btn-default btn-icon-only x-shutdown" title="Shutdown" data-container="body">
|
||||||
<i class="icon-nd-shutdown"></i>
|
<i class="icon-nd-shutdown"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-default btn-icon-only x-restart" title="Restart">
|
<button class="btn btn-default btn-icon-only x-restart" title="Restart" data-container="body">
|
||||||
<i class="icon-nd-restart"></i>
|
<i class="icon-nd-restart"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -14,7 +14,8 @@ define([
|
||||||
'Shared/LoadingView',
|
'Shared/LoadingView',
|
||||||
'Shared/Messenger',
|
'Shared/Messenger',
|
||||||
'Commands/CommandController',
|
'Commands/CommandController',
|
||||||
'backgrid.selectall'
|
'backgrid.selectall',
|
||||||
|
'Mixins/backbone.signalr.mixin'
|
||||||
], function (_,
|
], function (_,
|
||||||
Marionette,
|
Marionette,
|
||||||
Backgrid,
|
Backgrid,
|
||||||
|
@ -81,7 +82,7 @@ define([
|
||||||
],
|
],
|
||||||
|
|
||||||
initialize : function () {
|
initialize : function () {
|
||||||
this.collection = new CutoffUnmetCollection();
|
this.collection = new CutoffUnmetCollection().bindSignalR({ updateOnly: true });
|
||||||
|
|
||||||
this.listenTo(this.collection, 'sync', this._showTable);
|
this.listenTo(this.collection, 'sync', this._showTable);
|
||||||
},
|
},
|
||||||
|
|
|
@ -14,7 +14,8 @@ define([
|
||||||
'Shared/LoadingView',
|
'Shared/LoadingView',
|
||||||
'Shared/Messenger',
|
'Shared/Messenger',
|
||||||
'Commands/CommandController',
|
'Commands/CommandController',
|
||||||
'backgrid.selectall'
|
'backgrid.selectall',
|
||||||
|
'Mixins/backbone.signalr.mixin'
|
||||||
], function (_,
|
], function (_,
|
||||||
Marionette,
|
Marionette,
|
||||||
Backgrid,
|
Backgrid,
|
||||||
|
@ -81,7 +82,7 @@ define([
|
||||||
],
|
],
|
||||||
|
|
||||||
initialize : function () {
|
initialize : function () {
|
||||||
this.collection = new MissingCollection();
|
this.collection = new MissingCollection().bindSignalR({ updateOnly: true });
|
||||||
|
|
||||||
this.listenTo(this.collection, 'sync', this._showTable);
|
this.listenTo(this.collection, 'sync', this._showTable);
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue