mirror of
https://github.com/lidarr/lidarr.git
synced 2025-07-30 03:38:26 -07:00
New: Run missing root folder health check when an import is successful
This commit is contained in:
parent
8ce1d4bcab
commit
0e7a22dc95
8 changed files with 94 additions and 9 deletions
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using NzbDrone.Common.Messaging;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.HealthCheck
|
namespace NzbDrone.Core.HealthCheck
|
||||||
{
|
{
|
||||||
|
@ -7,10 +6,19 @@ namespace NzbDrone.Core.HealthCheck
|
||||||
public class CheckOnAttribute : Attribute
|
public class CheckOnAttribute : Attribute
|
||||||
{
|
{
|
||||||
public Type EventType { get; set; }
|
public Type EventType { get; set; }
|
||||||
|
public CheckOnCondition Condition { get; set; }
|
||||||
|
|
||||||
public CheckOnAttribute(Type eventType)
|
public CheckOnAttribute(Type eventType, CheckOnCondition condition = CheckOnCondition.Always)
|
||||||
{
|
{
|
||||||
EventType = eventType;
|
EventType = eventType;
|
||||||
|
Condition = condition;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum CheckOnCondition
|
||||||
|
{
|
||||||
|
Always,
|
||||||
|
FailedOnly,
|
||||||
|
SuccessfulOnly
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Core.MediaFiles.Events;
|
||||||
using NzbDrone.Core.Music;
|
using NzbDrone.Core.Music;
|
||||||
using NzbDrone.Core.Music.Events;
|
using NzbDrone.Core.Music.Events;
|
||||||
|
|
||||||
|
@ -7,6 +8,8 @@ namespace NzbDrone.Core.HealthCheck.Checks
|
||||||
{
|
{
|
||||||
[CheckOn(typeof(ArtistDeletedEvent))]
|
[CheckOn(typeof(ArtistDeletedEvent))]
|
||||||
[CheckOn(typeof(ArtistMovedEvent))]
|
[CheckOn(typeof(ArtistMovedEvent))]
|
||||||
|
[CheckOn(typeof(TrackImportedEvent), CheckOnCondition.FailedOnly)]
|
||||||
|
[CheckOn(typeof(TrackImportFailedEvent), CheckOnCondition.SuccessfulOnly)]
|
||||||
public class RootFolderCheck : HealthCheckBase
|
public class RootFolderCheck : HealthCheckBase
|
||||||
{
|
{
|
||||||
private readonly IArtistService _artistService;
|
private readonly IArtistService _artistService;
|
||||||
|
|
14
src/NzbDrone.Core/HealthCheck/EventDrivenHealthCheck.cs
Normal file
14
src/NzbDrone.Core/HealthCheck/EventDrivenHealthCheck.cs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
namespace NzbDrone.Core.HealthCheck
|
||||||
|
{
|
||||||
|
public class EventDrivenHealthCheck
|
||||||
|
{
|
||||||
|
public IProvideHealthCheck HealthCheck { get; set; }
|
||||||
|
public CheckOnCondition Condition { get; set; }
|
||||||
|
|
||||||
|
public EventDrivenHealthCheck(IProvideHealthCheck healthCheck, CheckOnCondition condition)
|
||||||
|
{
|
||||||
|
HealthCheck = healthCheck;
|
||||||
|
Condition = condition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,7 +29,7 @@ namespace NzbDrone.Core.HealthCheck
|
||||||
private readonly IProvideHealthCheck[] _healthChecks;
|
private readonly IProvideHealthCheck[] _healthChecks;
|
||||||
private readonly IProvideHealthCheck[] _startupHealthChecks;
|
private readonly IProvideHealthCheck[] _startupHealthChecks;
|
||||||
private readonly IProvideHealthCheck[] _scheduledHealthChecks;
|
private readonly IProvideHealthCheck[] _scheduledHealthChecks;
|
||||||
private readonly Dictionary<Type, IProvideHealthCheck[]> _eventDrivenHealthChecks;
|
private readonly Dictionary<Type, EventDrivenHealthCheck[]> _eventDrivenHealthChecks;
|
||||||
private readonly IEventAggregator _eventAggregator;
|
private readonly IEventAggregator _eventAggregator;
|
||||||
private readonly ICacheManager _cacheManager;
|
private readonly ICacheManager _cacheManager;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
@ -58,10 +58,10 @@ namespace NzbDrone.Core.HealthCheck
|
||||||
return _healthCheckResults.Values.ToList();
|
return _healthCheckResults.Values.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Dictionary<Type, IProvideHealthCheck[]> GetEventDrivenHealthChecks()
|
private Dictionary<Type, EventDrivenHealthCheck[]> GetEventDrivenHealthChecks()
|
||||||
{
|
{
|
||||||
return _healthChecks
|
return _healthChecks
|
||||||
.SelectMany(h => h.GetType().GetAttributes<CheckOnAttribute>().Select(a => Tuple.Create(a.EventType, h)))
|
.SelectMany(h => h.GetType().GetAttributes<CheckOnAttribute>().Select(a => Tuple.Create(a.EventType, new EventDrivenHealthCheck(h, a.Condition))))
|
||||||
.GroupBy(t => t.Item1, t => t.Item2)
|
.GroupBy(t => t.Item1, t => t.Item2)
|
||||||
.ToDictionary(g => g.Key, g => g.ToArray());
|
.ToDictionary(g => g.Key, g => g.ToArray());
|
||||||
}
|
}
|
||||||
|
@ -111,15 +111,42 @@ namespace NzbDrone.Core.HealthCheck
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
IProvideHealthCheck[] checks;
|
EventDrivenHealthCheck[] checks;
|
||||||
if (!_eventDrivenHealthChecks.TryGetValue(message.GetType(), out checks))
|
if (!_eventDrivenHealthChecks.TryGetValue(message.GetType(), out checks))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var filteredChecks = new List<IProvideHealthCheck>();
|
||||||
|
var healthCheckResults = _healthCheckResults.Values.ToList();
|
||||||
|
|
||||||
|
foreach (var eventDrivenHealthCheck in checks)
|
||||||
|
{
|
||||||
|
if (eventDrivenHealthCheck.Condition == CheckOnCondition.Always)
|
||||||
|
{
|
||||||
|
filteredChecks.Add(eventDrivenHealthCheck.HealthCheck);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var healthCheckType = eventDrivenHealthCheck.HealthCheck.GetType();
|
||||||
|
|
||||||
|
if (eventDrivenHealthCheck.Condition == CheckOnCondition.FailedOnly &&
|
||||||
|
healthCheckResults.Any(r => r.Source == healthCheckType))
|
||||||
|
{
|
||||||
|
filteredChecks.Add(eventDrivenHealthCheck.HealthCheck);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eventDrivenHealthCheck.Condition == CheckOnCondition.SuccessfulOnly &&
|
||||||
|
healthCheckResults.None(r => r.Source == healthCheckType))
|
||||||
|
{
|
||||||
|
filteredChecks.Add(eventDrivenHealthCheck.HealthCheck);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Add debounce
|
// TODO: Add debounce
|
||||||
|
|
||||||
PerformHealthCheck(checks);
|
PerformHealthCheck(filteredChecks.ToArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
using System;
|
||||||
|
using NzbDrone.Common.Messaging;
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.MediaFiles.Events
|
||||||
|
{
|
||||||
|
public class TrackImportFailedEvent : IEvent
|
||||||
|
{
|
||||||
|
public Exception Exception { get; set; }
|
||||||
|
public LocalTrack TrackInfo { get; }
|
||||||
|
public bool NewDownload { get; }
|
||||||
|
public string DownloadClient { get; }
|
||||||
|
public string DownloadId { get; }
|
||||||
|
|
||||||
|
public TrackImportFailedEvent(Exception exception, LocalTrack trackInfo, bool newDownload, DownloadClientItem downloadClientItem)
|
||||||
|
{
|
||||||
|
Exception = exception;
|
||||||
|
TrackInfo = trackInfo;
|
||||||
|
NewDownload = newDownload;
|
||||||
|
|
||||||
|
if (downloadClientItem != null)
|
||||||
|
{
|
||||||
|
DownloadClient = downloadClientItem.DownloadClient;
|
||||||
|
DownloadId = downloadClientItem.DownloadId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,10 @@
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common;
|
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.EnsureThat;
|
using NzbDrone.Common.EnsureThat;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.MediaFiles.Events;
|
using NzbDrone.Core.MediaFiles.Events;
|
||||||
|
using NzbDrone.Core.MediaFiles.TrackImport;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
using NzbDrone.Core.Music;
|
using NzbDrone.Core.Music;
|
||||||
using NzbDrone.Core.Organizer;
|
using NzbDrone.Core.Organizer;
|
||||||
|
@ -166,7 +166,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
|
|
||||||
if (!_diskProvider.FolderExists(rootFolder))
|
if (!_diskProvider.FolderExists(rootFolder))
|
||||||
{
|
{
|
||||||
throw new TrackImport.RootFolderNotFoundException(string.Format("Root folder '{0}' was not found.", rootFolder));
|
throw new RootFolderNotFoundException(string.Format("Root folder '{0}' was not found.", rootFolder));
|
||||||
}
|
}
|
||||||
|
|
||||||
var changed = false;
|
var changed = false;
|
||||||
|
|
|
@ -131,6 +131,8 @@ namespace NzbDrone.Core.MediaFiles.TrackImport
|
||||||
catch (RootFolderNotFoundException e)
|
catch (RootFolderNotFoundException e)
|
||||||
{
|
{
|
||||||
_logger.Warn(e, "Couldn't import track " + localTrack);
|
_logger.Warn(e, "Couldn't import track " + localTrack);
|
||||||
|
_eventAggregator.PublishEvent(new TrackImportFailedEvent(e, localTrack, newDownload, downloadClientItem));
|
||||||
|
|
||||||
importResults.Add(new ImportResult(importDecision, "Failed to import track, Root folder missing."));
|
importResults.Add(new ImportResult(importDecision, "Failed to import track, Root folder missing."));
|
||||||
}
|
}
|
||||||
catch (DestinationAlreadyExistsException e)
|
catch (DestinationAlreadyExistsException e)
|
||||||
|
|
|
@ -469,6 +469,7 @@
|
||||||
<Compile Include="HealthCheck\Checks\ProxyCheck.cs" />
|
<Compile Include="HealthCheck\Checks\ProxyCheck.cs" />
|
||||||
<Compile Include="HealthCheck\Checks\RootFolderCheck.cs" />
|
<Compile Include="HealthCheck\Checks\RootFolderCheck.cs" />
|
||||||
<Compile Include="HealthCheck\Checks\UpdateCheck.cs" />
|
<Compile Include="HealthCheck\Checks\UpdateCheck.cs" />
|
||||||
|
<Compile Include="HealthCheck\EventDrivenHealthCheck.cs" />
|
||||||
<Compile Include="HealthCheck\HealthCheck.cs" />
|
<Compile Include="HealthCheck\HealthCheck.cs" />
|
||||||
<Compile Include="HealthCheck\HealthCheckBase.cs" />
|
<Compile Include="HealthCheck\HealthCheckBase.cs" />
|
||||||
<Compile Include="HealthCheck\HealthCheckCompleteEvent.cs" />
|
<Compile Include="HealthCheck\HealthCheckCompleteEvent.cs" />
|
||||||
|
@ -643,6 +644,7 @@
|
||||||
<Compile Include="MediaFiles\Commands\RenameArtistCommand.cs" />
|
<Compile Include="MediaFiles\Commands\RenameArtistCommand.cs" />
|
||||||
<Compile Include="MediaFiles\Events\TrackFileRenamedEvent.cs" />
|
<Compile Include="MediaFiles\Events\TrackFileRenamedEvent.cs" />
|
||||||
<Compile Include="MediaFiles\Events\TrackFolderCreatedEvent.cs" />
|
<Compile Include="MediaFiles\Events\TrackFolderCreatedEvent.cs" />
|
||||||
|
<Compile Include="MediaFiles\Events\TrackImportFailedEvent.cs" />
|
||||||
<Compile Include="MediaFiles\MediaFileDeletionService.cs" />
|
<Compile Include="MediaFiles\MediaFileDeletionService.cs" />
|
||||||
<Compile Include="MediaFiles\MediaInfo\MediaInfoFormatter.cs" />
|
<Compile Include="MediaFiles\MediaInfo\MediaInfoFormatter.cs" />
|
||||||
<Compile Include="MediaFiles\RenameTrackFilePreview.cs" />
|
<Compile Include="MediaFiles\RenameTrackFilePreview.cs" />
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue