You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Lidarr/src/NzbDrone.Core/Download/CompletedDownloadService.cs

188 lines
7.5 KiB

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Download.TrackedDownloads;
using NzbDrone.Core.History;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.MediaFiles.Events;
using NzbDrone.Core.MediaFiles.TrackImport;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Music;
namespace NzbDrone.Core.Download
{
public interface ICompletedDownloadService
{
void Check(TrackedDownload trackedDownload);
void Import(TrackedDownload trackedDownload);
}
public class CompletedDownloadService : ICompletedDownloadService
{
private readonly IEventAggregator _eventAggregator;
private readonly IHistoryService _historyService;
private readonly IDownloadedTracksImportService _downloadedTracksImportService;
private readonly IArtistService _artistService;
private readonly IProvideImportItemService _provideImportItemService;
private readonly ITrackedDownloadAlreadyImported _trackedDownloadAlreadyImported;
public CompletedDownloadService(IEventAggregator eventAggregator,
IHistoryService historyService,
IProvideImportItemService provideImportItemService,
IDownloadedTracksImportService downloadedTracksImportService,
IArtistService artistService,
ITrackedDownloadAlreadyImported trackedDownloadAlreadyImported)
{
_eventAggregator = eventAggregator;
_historyService = historyService;
_provideImportItemService = provideImportItemService;
_downloadedTracksImportService = downloadedTracksImportService;
_artistService = artistService;
_trackedDownloadAlreadyImported = trackedDownloadAlreadyImported;
}
public void Check(TrackedDownload trackedDownload)
{
if (trackedDownload.DownloadItem.Status != DownloadItemStatus.Completed ||
trackedDownload.RemoteAlbum == null)
{
return;
}
SetImportItem(trackedDownload);
// Only process tracked downloads that are still downloading
if (trackedDownload.State != TrackedDownloadState.Downloading)
{
return;
}
var historyItem = _historyService.MostRecentForDownloadId(trackedDownload.DownloadItem.DownloadId);
if (historyItem == null && trackedDownload.DownloadItem.Category.IsNullOrWhiteSpace())
{
trackedDownload.Warn("Download wasn't grabbed by Lidarr and not in a category, Skipping.");
return;
}
if (!ValidatePath(trackedDownload))
{
return;
}
var artist = trackedDownload.RemoteAlbum.Artist;
if (artist == null)
{
if (historyItem != null)
{
artist = _artistService.GetArtist(historyItem.ArtistId);
}
if (artist == null)
{
trackedDownload.Warn("Artist name mismatch, automatic import is not possible.");
return;
}
}
trackedDownload.State = TrackedDownloadState.ImportPending;
}
public void Import(TrackedDownload trackedDownload)
{
SetImportItem(trackedDownload);
if (!ValidatePath(trackedDownload))
{
return;
}
trackedDownload.State = TrackedDownloadState.Importing;
var outputPath = trackedDownload.ImportItem.OutputPath.FullPath;
var importResults = _downloadedTracksImportService.ProcessPath(outputPath, ImportMode.Auto, trackedDownload.RemoteAlbum.Artist, trackedDownload.DownloadItem);
if (importResults.Empty())
{
trackedDownload.Warn("No files found are eligible for import in {0}", outputPath);
trackedDownload.State = TrackedDownloadState.ImportPending;
return;
}
var allTracksImported = importResults.All(c => c.Result == ImportResultType.Imported) ||
importResults.Count(c => c.Result == ImportResultType.Imported) >=
Math.Max(1, trackedDownload.RemoteAlbum.Albums.Sum(x => x.AlbumReleases.Value.Where(y => y.Monitored).Sum(z => z.TrackCount)));
if (allTracksImported)
{
trackedDownload.State = TrackedDownloadState.Imported;
_eventAggregator.PublishEvent(new DownloadCompletedEvent(trackedDownload, trackedDownload.RemoteAlbum.Artist.Id));
return;
}
// Double check if all albums were imported by checking the history if at least one
// file was imported. This will allow the decision engine to reject already imported
// albums and still mark the download complete when all files are imported.
if (importResults.Any(c => c.Result == ImportResultType.Imported))
{
var historyItems = _historyService.FindByDownloadId(trackedDownload.DownloadItem.DownloadId)
.OrderByDescending(h => h.Date)
.ToList();
var allTracksImportedInHistory = _trackedDownloadAlreadyImported.IsImported(trackedDownload, historyItems);
if (allTracksImportedInHistory)
{
trackedDownload.State = TrackedDownloadState.Imported;
_eventAggregator.PublishEvent(new DownloadCompletedEvent(trackedDownload, trackedDownload.RemoteAlbum.Artist.Id));
return;
}
}
trackedDownload.State = TrackedDownloadState.ImportPending;
if (importResults.Any(c => c.Result != ImportResultType.Imported))
{
trackedDownload.State = TrackedDownloadState.ImportFailed;
var statusMessages = importResults
.Where(v => v.Result != ImportResultType.Imported)
Whole album matching and fingerprinting (#592) * Cache result of GetAllArtists * Fixed: Manual import not respecting album import notifications * Fixed: partial album imports stay in queue, prompting manual import * Fixed: Allow release if tracks are missing * Fixed: Be tolerant of missing/extra "The" at start of artist name * Improve manual import UI * Omit video tracks from DB entirely * Revert "faster test packaging in build.sh" This reverts commit 2723e2a7b86bcbff9051fd2aced07dd807b4bcb7. -u and -T are not supported on macOS * Fix tests on linux and macOS * Actually lint on linux On linux yarn runs scripts with sh not bash so ** doesn't recursively glob * Match whole albums * Option to disable fingerprinting * Rip out MediaInfo * Don't split up things that have the same album selected in manual import * Try to speed up IndentificationService * More speedups * Some fixes and increase power of recording id * Fix NRE when no tags * Fix NRE when some (but not all) files in a directory have missing tags * Bump taglib, tidy up tag parsing * Add a health check * Remove media info setting * Tags -> audioTags * Add some tests where tags are null * Rename history events * Add missing method to interface * Reinstate MediaInfo tags and update info with artist scan Also adds migration to remove old format media info * This file no longer exists * Don't penalise year if missing from tags * Formatting improvements * Use correct system newline * Switch to the netstandard2.0 library to support net 461 * TagLib.File is IDisposable so should be in a using * Improve filename matching and add tests * Neater logging of parsed tags * Fix disk scan tests for new media info update * Fix quality detection source * Fix Inexact Artist/Album match * Add button to clear track mapping * Fix warning * Pacify eslint * Use \ not / * Fix UI updates * Fix media covers Prevent localizing URL propaging back to the metadata object * Reduce database overhead broadcasting UI updates * Relax timings a bit to make test pass * Remove irrelevant tests * Test framework for identification service * Fix PreferMissingToBadMatch test case * Make fingerprinting more robust * More logging * Penalize unknown media format and country * Prefer USA to UK * Allow Data CD * Fix exception if fingerprinting fails for all files * Fix tests * Fix NRE * Allow apostrophes and remove accents in filename aggregation * Address codacy issues * Cope with old versions of fpcalc and suggest upgrade * fpcalc health check passes if fingerprinting disabled * Get the Artist meta with the artist * Fix the mapper so that lazy loaded lists will be populated on Join And therefore we can join TrackFiles on Tracks by default and avoid an extra query * Rename subtitle -> lyric * Tidy up MediaInfoFormatter
6 years ago
.Select(v => new TrackedDownloadStatusMessage(Path.GetFileName(v.ImportDecision.Item.Path), v.Errors))
.ToArray();
trackedDownload.Warn(statusMessages);
Whole album matching and fingerprinting (#592) * Cache result of GetAllArtists * Fixed: Manual import not respecting album import notifications * Fixed: partial album imports stay in queue, prompting manual import * Fixed: Allow release if tracks are missing * Fixed: Be tolerant of missing/extra "The" at start of artist name * Improve manual import UI * Omit video tracks from DB entirely * Revert "faster test packaging in build.sh" This reverts commit 2723e2a7b86bcbff9051fd2aced07dd807b4bcb7. -u and -T are not supported on macOS * Fix tests on linux and macOS * Actually lint on linux On linux yarn runs scripts with sh not bash so ** doesn't recursively glob * Match whole albums * Option to disable fingerprinting * Rip out MediaInfo * Don't split up things that have the same album selected in manual import * Try to speed up IndentificationService * More speedups * Some fixes and increase power of recording id * Fix NRE when no tags * Fix NRE when some (but not all) files in a directory have missing tags * Bump taglib, tidy up tag parsing * Add a health check * Remove media info setting * Tags -> audioTags * Add some tests where tags are null * Rename history events * Add missing method to interface * Reinstate MediaInfo tags and update info with artist scan Also adds migration to remove old format media info * This file no longer exists * Don't penalise year if missing from tags * Formatting improvements * Use correct system newline * Switch to the netstandard2.0 library to support net 461 * TagLib.File is IDisposable so should be in a using * Improve filename matching and add tests * Neater logging of parsed tags * Fix disk scan tests for new media info update * Fix quality detection source * Fix Inexact Artist/Album match * Add button to clear track mapping * Fix warning * Pacify eslint * Use \ not / * Fix UI updates * Fix media covers Prevent localizing URL propaging back to the metadata object * Reduce database overhead broadcasting UI updates * Relax timings a bit to make test pass * Remove irrelevant tests * Test framework for identification service * Fix PreferMissingToBadMatch test case * Make fingerprinting more robust * More logging * Penalize unknown media format and country * Prefer USA to UK * Allow Data CD * Fix exception if fingerprinting fails for all files * Fix tests * Fix NRE * Allow apostrophes and remove accents in filename aggregation * Address codacy issues * Cope with old versions of fpcalc and suggest upgrade * fpcalc health check passes if fingerprinting disabled * Get the Artist meta with the artist * Fix the mapper so that lazy loaded lists will be populated on Join And therefore we can join TrackFiles on Tracks by default and avoid an extra query * Rename subtitle -> lyric * Tidy up MediaInfoFormatter
6 years ago
_eventAggregator.PublishEvent(new AlbumImportIncompleteEvent(trackedDownload));
return;
}
}
private void SetImportItem(TrackedDownload trackedDownload)
{
trackedDownload.ImportItem = _provideImportItemService.ProvideImportItem(trackedDownload.DownloadItem, trackedDownload.ImportItem);
}
private bool ValidatePath(TrackedDownload trackedDownload)
{
var downloadItemOutputPath = trackedDownload.ImportItem.OutputPath;
if (downloadItemOutputPath.IsEmpty)
{
trackedDownload.Warn("Download doesn't contain intermediate path, Skipping.");
return false;
}
if ((OsInfo.IsWindows && !downloadItemOutputPath.IsWindowsPath) ||
(OsInfo.IsNotWindows && !downloadItemOutputPath.IsUnixPath))
{
trackedDownload.Warn("[{0}] is not a valid local path. You may need a Remote Path Mapping.", downloadItemOutputPath);
return false;
}
return true;
}
}
}