mirror of https://github.com/lidarr/Lidarr
New: Option to Import via Script
(cherry picked from commit 9f1e2151206a077334a9c34a12a373b465752d87)
This commit is contained in:
parent
f38f00c64e
commit
c8a950eb40
|
@ -68,29 +68,29 @@ class MediaManagement extends Component {
|
|||
<NamingConnector />
|
||||
|
||||
{
|
||||
isFetching &&
|
||||
isFetching ?
|
||||
<FieldSet legend={translate('NamingSettings')}>
|
||||
<LoadingIndicator />
|
||||
</FieldSet>
|
||||
</FieldSet> : null
|
||||
}
|
||||
|
||||
{
|
||||
!isFetching && error &&
|
||||
!isFetching && error ?
|
||||
<FieldSet legend={translate('NamingSettings')}>
|
||||
<div>
|
||||
{translate('UnableToLoadMediaManagementSettings')}
|
||||
</div>
|
||||
</FieldSet>
|
||||
</FieldSet> : null
|
||||
}
|
||||
|
||||
{
|
||||
hasSettings && !isFetching && !error &&
|
||||
hasSettings && !isFetching && !error ?
|
||||
<Form
|
||||
id="mediaManagementSettings"
|
||||
{...otherProps}
|
||||
>
|
||||
{
|
||||
advancedSettings &&
|
||||
advancedSettings ?
|
||||
<FieldSet legend={translate('Folders')}>
|
||||
<FormGroup
|
||||
advancedSettings={advancedSettings}
|
||||
|
@ -127,11 +127,11 @@ class MediaManagement extends Component {
|
|||
{...settings.deleteEmptyFolders}
|
||||
/>
|
||||
</FormGroup>
|
||||
</FieldSet>
|
||||
</FieldSet> : null
|
||||
}
|
||||
|
||||
{
|
||||
advancedSettings &&
|
||||
advancedSettings ?
|
||||
<FieldSet
|
||||
legend={translate('Importing')}
|
||||
>
|
||||
|
@ -194,6 +194,41 @@ class MediaManagement extends Component {
|
|||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup
|
||||
advancedSettings={advancedSettings}
|
||||
isAdvanced={true}
|
||||
size={sizes.MEDIUM}
|
||||
>
|
||||
<FormLabel>{translate('ImportUsingScript')}</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="useScriptImport"
|
||||
helpText={translate('UseScriptImportHelpText')}
|
||||
onChange={onInputChange}
|
||||
{...settings.useScriptImport}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
{
|
||||
settings.useScriptImport.value ?
|
||||
<FormGroup
|
||||
advancedSettings={advancedSettings}
|
||||
isAdvanced={true}
|
||||
>
|
||||
<FormLabel>{translate('ImportScriptPath')}</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.PATH}
|
||||
includeFiles={true}
|
||||
name="scriptImportPath"
|
||||
helpText={translate('ScriptImportPathHelpText')}
|
||||
onChange={onInputChange}
|
||||
{...settings.scriptImportPath}
|
||||
/>
|
||||
</FormGroup> : null
|
||||
}
|
||||
|
||||
<FormGroup size={sizes.MEDIUM}>
|
||||
<FormLabel>
|
||||
{translate('ImportExtraFiles')}
|
||||
|
@ -209,7 +244,7 @@ class MediaManagement extends Component {
|
|||
</FormGroup>
|
||||
|
||||
{
|
||||
settings.importExtraFiles.value &&
|
||||
settings.importExtraFiles.value ?
|
||||
<FormGroup
|
||||
advancedSettings={advancedSettings}
|
||||
isAdvanced={true}
|
||||
|
@ -228,9 +263,9 @@ class MediaManagement extends Component {
|
|||
onChange={onInputChange}
|
||||
{...settings.extraFileExtensions}
|
||||
/>
|
||||
</FormGroup>
|
||||
</FormGroup> : null
|
||||
}
|
||||
</FieldSet>
|
||||
</FieldSet> : null
|
||||
}
|
||||
|
||||
<FieldSet
|
||||
|
@ -375,7 +410,7 @@ class MediaManagement extends Component {
|
|||
</FieldSet>
|
||||
|
||||
{
|
||||
advancedSettings && !isWindows &&
|
||||
advancedSettings && !isWindows ?
|
||||
<FieldSet
|
||||
legend={translate('Permissions')}
|
||||
>
|
||||
|
@ -434,9 +469,9 @@ class MediaManagement extends Component {
|
|||
{...settings.chownGroup}
|
||||
/>
|
||||
</FormGroup>
|
||||
</FieldSet>
|
||||
</FieldSet> : null
|
||||
}
|
||||
</Form>
|
||||
</Form> : null
|
||||
}
|
||||
</PageContentBody>
|
||||
</PageContent>
|
||||
|
|
|
@ -32,6 +32,9 @@ namespace Lidarr.Api.V1.Config
|
|||
.When(c => !string.IsNullOrWhiteSpace(c.RecycleBin));
|
||||
SharedValidator.RuleFor(c => c.RecycleBinCleanupDays).GreaterThanOrEqualTo(0);
|
||||
SharedValidator.RuleFor(c => c.ChmodFolder).SetValidator(folderChmodValidator).When(c => !string.IsNullOrEmpty(c.ChmodFolder) && (OsInfo.IsLinux || OsInfo.IsOsx));
|
||||
|
||||
SharedValidator.RuleFor(c => c.ScriptImportPath).IsValidPath().When(c => c.UseScriptImport);
|
||||
|
||||
SharedValidator.RuleFor(c => c.MinimumFreeSpaceWhenImporting).GreaterThanOrEqualTo(100);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,8 @@ namespace Lidarr.Api.V1.Config
|
|||
public bool SkipFreeSpaceCheckWhenImporting { get; set; }
|
||||
public int MinimumFreeSpaceWhenImporting { get; set; }
|
||||
public bool CopyUsingHardlinks { get; set; }
|
||||
public bool UseScriptImport { get; set; }
|
||||
public string ScriptImportPath { get; set; }
|
||||
public bool ImportExtraFiles { get; set; }
|
||||
public string ExtraFileExtensions { get; set; }
|
||||
}
|
||||
|
@ -53,6 +55,8 @@ namespace Lidarr.Api.V1.Config
|
|||
SkipFreeSpaceCheckWhenImporting = model.SkipFreeSpaceCheckWhenImporting,
|
||||
MinimumFreeSpaceWhenImporting = model.MinimumFreeSpaceWhenImporting,
|
||||
CopyUsingHardlinks = model.CopyUsingHardlinks,
|
||||
UseScriptImport = model.UseScriptImport,
|
||||
ScriptImportPath = model.ScriptImportPath,
|
||||
ImportExtraFiles = model.ImportExtraFiles,
|
||||
ExtraFileExtensions = model.ExtraFileExtensions,
|
||||
};
|
||||
|
|
|
@ -200,6 +200,20 @@ namespace NzbDrone.Core.Configuration
|
|||
set { SetValue("CopyUsingHardlinks", value); }
|
||||
}
|
||||
|
||||
public bool UseScriptImport
|
||||
{
|
||||
get { return GetValueBoolean("UseScriptImport", false); }
|
||||
|
||||
set { SetValue("UseScriptImport", value); }
|
||||
}
|
||||
|
||||
public string ScriptImportPath
|
||||
{
|
||||
get { return GetValue("ScriptImportPath"); }
|
||||
|
||||
set { SetValue("ScriptImportPath", value); }
|
||||
}
|
||||
|
||||
public bool ImportExtraFiles
|
||||
{
|
||||
get { return GetValueBoolean("ImportExtraFiles", false); }
|
||||
|
|
|
@ -32,6 +32,8 @@ namespace NzbDrone.Core.Configuration
|
|||
bool SkipFreeSpaceCheckWhenImporting { get; set; }
|
||||
int MinimumFreeSpaceWhenImporting { get; set; }
|
||||
bool CopyUsingHardlinks { get; set; }
|
||||
bool UseScriptImport { get; set; }
|
||||
string ScriptImportPath { get; set; }
|
||||
bool ImportExtraFiles { get; set; }
|
||||
string ExtraFileExtensions { get; set; }
|
||||
bool WatchLibraryForChanges { get; set; }
|
||||
|
|
|
@ -392,6 +392,8 @@
|
|||
"ImportListStatusCheckSingleClientMessage": "Lists unavailable due to failures: {0}",
|
||||
"ImportLists": "Import Lists",
|
||||
"ImportMechanismHealthCheckMessage": "Enable Completed Download Handling",
|
||||
"ImportScriptPath": "Import Script Path",
|
||||
"ImportUsingScript": "Import Using Script",
|
||||
"ImportedTo": "Imported To",
|
||||
"Importing": "Importing",
|
||||
"Inactive": "Inactive",
|
||||
|
@ -754,6 +756,7 @@
|
|||
"SceneInformation": "Scene Information",
|
||||
"SceneNumberHasntBeenVerifiedYet": "Scene number hasn't been verified yet",
|
||||
"Scheduled": "Scheduled",
|
||||
"ScriptImportPathHelpText": "The path to the script to use for importing",
|
||||
"ScriptPath": "Script Path",
|
||||
"ScrubAudioTagsHelpText": "Remove existing tags from files, leaving only those added by Lidarr.",
|
||||
"ScrubExistingTags": "Scrub Existing Tags",
|
||||
|
@ -963,6 +966,7 @@
|
|||
"UrlBaseHelpTextWarning": "Requires restart to take effect",
|
||||
"UseHardlinksInsteadOfCopy": "Use Hardlinks instead of Copy",
|
||||
"UseProxy": "Use Proxy",
|
||||
"UseScriptImportHelpText": "Copy files for importing using a script (ex. for transcoding)",
|
||||
"Usenet": "Usenet",
|
||||
"UsenetDelay": "Usenet Delay",
|
||||
"UsenetDelayHelpText": "Delay in minutes to wait before grabbing a release from Usenet",
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Processes;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
||||
namespace NzbDrone.Core.MediaFiles
|
||||
{
|
||||
public interface IImportScript
|
||||
{
|
||||
public ScriptImportDecision TryImport(string sourcePath, string destinationFilePath, LocalTrack localTrack, TrackFile trackFile, TransferMode mode);
|
||||
}
|
||||
|
||||
public class ImportScriptService : IImportScript
|
||||
{
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
private readonly IProcessProvider _processProvider;
|
||||
private readonly IConfigService _configService;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public ImportScriptService(IProcessProvider processProvider,
|
||||
IConfigService configService,
|
||||
IConfigFileProvider configFileProvider,
|
||||
Logger logger)
|
||||
{
|
||||
_processProvider = processProvider;
|
||||
_configService = configService;
|
||||
_configFileProvider = configFileProvider;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public ScriptImportDecision TryImport(string sourcePath, string destinationFilePath, LocalTrack localTrack, TrackFile trackFile, TransferMode mode)
|
||||
{
|
||||
var artist = localTrack.Artist;
|
||||
var oldFiles = localTrack.OldFiles;
|
||||
var downloadClientInfo = localTrack.DownloadItem?.DownloadClientInfo;
|
||||
var downloadId = localTrack.DownloadItem?.DownloadId;
|
||||
|
||||
if (!_configService.UseScriptImport)
|
||||
{
|
||||
return ScriptImportDecision.DeferMove;
|
||||
}
|
||||
|
||||
var environmentVariables = new StringDictionary();
|
||||
|
||||
environmentVariables.Add("Lidarr_SourcePath", sourcePath);
|
||||
environmentVariables.Add("Lidarr_DestinationPath", destinationFilePath);
|
||||
|
||||
environmentVariables.Add("Lidarr_InstanceName", _configFileProvider.InstanceName);
|
||||
environmentVariables.Add("Lidarr_ApplicationUrl", _configService.ApplicationUrl);
|
||||
environmentVariables.Add("Lidarr_TransferMode", mode.ToString());
|
||||
|
||||
environmentVariables.Add("Lidarr_Artist_Id", artist.Id.ToString());
|
||||
environmentVariables.Add("Lidarr_Artist_Name", artist.Metadata.Value.Name);
|
||||
environmentVariables.Add("Lidarr_Artist_Path", artist.Path);
|
||||
environmentVariables.Add("Lidarr_Artist_MBId", artist.Metadata.Value.ForeignArtistId);
|
||||
environmentVariables.Add("Lidarr_Artist_Type", artist.Metadata.Value.Type);
|
||||
|
||||
environmentVariables.Add("Lidarr_Album_Id", localTrack.Album.Id.ToString());
|
||||
environmentVariables.Add("Lidarr_Album_Title", localTrack.Album.Title);
|
||||
environmentVariables.Add("Lidarr_Album_Overview", localTrack.Album.Overview);
|
||||
environmentVariables.Add("Lidarr_Album_MBId", localTrack.Album.ForeignAlbumId);
|
||||
environmentVariables.Add("Lidarr_AlbumRelease_MBId", localTrack.Release.ForeignReleaseId);
|
||||
environmentVariables.Add("Lidarr_Album_ReleaseDate", localTrack.Release.ReleaseDate.ToString());
|
||||
|
||||
environmentVariables.Add("Lidarr_Download_Client", downloadClientInfo?.Name ?? string.Empty);
|
||||
environmentVariables.Add("Lidarr_Download_Client_Type", downloadClientInfo?.Type ?? string.Empty);
|
||||
environmentVariables.Add("Lidarr_Download_Id", downloadId ?? string.Empty);
|
||||
|
||||
if (oldFiles.Any())
|
||||
{
|
||||
environmentVariables.Add("Lidarr_DeletedPaths", string.Join("|", oldFiles.Select(e => e.Path)));
|
||||
environmentVariables.Add("Lidarr_DeletedDateAdded", string.Join("|", oldFiles.Select(e => e.DateAdded)));
|
||||
}
|
||||
|
||||
_logger.Debug("Executing external script: {0}", _configService.ScriptImportPath);
|
||||
|
||||
var processOutput = _processProvider.StartAndCapture(_configService.ScriptImportPath, $"\"{sourcePath}\" \"{destinationFilePath}\"", environmentVariables);
|
||||
|
||||
_logger.Debug("Executed external script: {0} - Status: {1}", _configService.ScriptImportPath, processOutput.ExitCode);
|
||||
_logger.Debug("Script Output: \r\n{0}", string.Join("\r\n", processOutput.Lines));
|
||||
|
||||
switch (processOutput.ExitCode)
|
||||
{
|
||||
case 0: // Copy complete
|
||||
return ScriptImportDecision.MoveComplete;
|
||||
case 2: // Copy complete, file potentially changed, should try renaming again
|
||||
// trackFile.MediaInfo = _videoFileInfoReader.GetMediaInfo(destinationFilePath);
|
||||
trackFile.Path = null;
|
||||
return ScriptImportDecision.RenameRequested;
|
||||
case 3: // Let Lidarr handle it
|
||||
return ScriptImportDecision.DeferMove;
|
||||
default: // Error, fail to import
|
||||
throw new ScriptImportException("Moving with script failed! Exit code {0}", processOutput.ExitCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
namespace NzbDrone.Core.MediaFiles
|
||||
{
|
||||
public enum ScriptImportDecision
|
||||
{
|
||||
MoveComplete,
|
||||
RenameRequested,
|
||||
RejectExtra,
|
||||
DeferMove
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using NzbDrone.Common.Exceptions;
|
||||
|
||||
namespace NzbDrone.Core.MediaFiles
|
||||
{
|
||||
public class ScriptImportException : NzbDroneException
|
||||
{
|
||||
public ScriptImportException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public ScriptImportException(string message, params object[] args)
|
||||
: base(message, args)
|
||||
{
|
||||
}
|
||||
|
||||
public ScriptImportException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -31,6 +31,7 @@ namespace NzbDrone.Core.MediaFiles
|
|||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly IRootFolderWatchingService _rootFolderWatchingService;
|
||||
private readonly IMediaFileAttributeService _mediaFileAttributeService;
|
||||
private readonly IImportScript _scriptImportDecider;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly IConfigService _configService;
|
||||
private readonly Logger _logger;
|
||||
|
@ -43,6 +44,7 @@ namespace NzbDrone.Core.MediaFiles
|
|||
IDiskProvider diskProvider,
|
||||
IRootFolderWatchingService rootFolderWatchingService,
|
||||
IMediaFileAttributeService mediaFileAttributeService,
|
||||
IImportScript scriptImportDecider,
|
||||
IEventAggregator eventAggregator,
|
||||
IConfigService configService,
|
||||
Logger logger)
|
||||
|
@ -55,6 +57,7 @@ namespace NzbDrone.Core.MediaFiles
|
|||
_diskProvider = diskProvider;
|
||||
_rootFolderWatchingService = rootFolderWatchingService;
|
||||
_mediaFileAttributeService = mediaFileAttributeService;
|
||||
_scriptImportDecider = scriptImportDecider;
|
||||
_eventAggregator = eventAggregator;
|
||||
_configService = configService;
|
||||
_logger = logger;
|
||||
|
@ -63,6 +66,11 @@ namespace NzbDrone.Core.MediaFiles
|
|||
public TrackFile MoveTrackFile(TrackFile trackFile, Artist artist)
|
||||
{
|
||||
var tracks = _trackService.GetTracksByFileId(trackFile.Id);
|
||||
return MoveTrackFile(trackFile, artist, tracks);
|
||||
}
|
||||
|
||||
private TrackFile MoveTrackFile(TrackFile trackFile, Artist artist, List<Track> tracks)
|
||||
{
|
||||
var album = _albumService.GetAlbum(trackFile.AlbumId);
|
||||
var newFileName = _buildFileNames.BuildTrackFileName(tracks, artist, album, trackFile);
|
||||
var filePath = _buildFileNames.BuildTrackFilePath(artist, newFileName, Path.GetExtension(trackFile.Path));
|
||||
|
@ -83,7 +91,7 @@ namespace NzbDrone.Core.MediaFiles
|
|||
|
||||
_logger.Debug("Moving track file: {0} to {1}", trackFile.Path, filePath);
|
||||
|
||||
return TransferFile(trackFile, localTrack.Artist, localTrack.Tracks, filePath, TransferMode.Move);
|
||||
return TransferFile(trackFile, localTrack.Artist, localTrack.Tracks, filePath, TransferMode.Move, localTrack);
|
||||
}
|
||||
|
||||
public TrackFile CopyTrackFile(TrackFile trackFile, LocalTrack localTrack)
|
||||
|
@ -96,14 +104,14 @@ namespace NzbDrone.Core.MediaFiles
|
|||
if (_configService.CopyUsingHardlinks)
|
||||
{
|
||||
_logger.Debug("Hardlinking track file: {0} to {1}", trackFile.Path, filePath);
|
||||
return TransferFile(trackFile, localTrack.Artist, localTrack.Tracks, filePath, TransferMode.HardLinkOrCopy);
|
||||
return TransferFile(trackFile, localTrack.Artist, localTrack.Tracks, filePath, TransferMode.HardLinkOrCopy, localTrack);
|
||||
}
|
||||
|
||||
_logger.Debug("Copying track file: {0} to {1}", trackFile.Path, filePath);
|
||||
return TransferFile(trackFile, localTrack.Artist, localTrack.Tracks, filePath, TransferMode.Copy);
|
||||
return TransferFile(trackFile, localTrack.Artist, localTrack.Tracks, filePath, TransferMode.Copy, localTrack);
|
||||
}
|
||||
|
||||
private TrackFile TransferFile(TrackFile trackFile, Artist artist, List<Track> tracks, string destinationFilePath, TransferMode mode)
|
||||
private TrackFile TransferFile(TrackFile trackFile, Artist artist, List<Track> tracks, string destinationFilePath, TransferMode mode, LocalTrack localTrack = null)
|
||||
{
|
||||
Ensure.That(trackFile, () => trackFile).IsNotNull();
|
||||
Ensure.That(artist, () => artist).IsNotNull();
|
||||
|
@ -122,10 +130,34 @@ namespace NzbDrone.Core.MediaFiles
|
|||
}
|
||||
|
||||
_rootFolderWatchingService.ReportFileSystemChangeBeginning(trackFilePath, destinationFilePath);
|
||||
_diskTransferService.TransferFile(trackFilePath, destinationFilePath, mode);
|
||||
|
||||
var transfer = true;
|
||||
|
||||
trackFile.Path = destinationFilePath;
|
||||
|
||||
if (localTrack is not null)
|
||||
{
|
||||
var scriptImportDecision = _scriptImportDecider.TryImport(trackFilePath, destinationFilePath, localTrack, trackFile, mode);
|
||||
|
||||
switch (scriptImportDecision)
|
||||
{
|
||||
case ScriptImportDecision.DeferMove:
|
||||
break;
|
||||
case ScriptImportDecision.RenameRequested:
|
||||
MoveTrackFile(trackFile, artist, trackFile.Tracks);
|
||||
transfer = false;
|
||||
break;
|
||||
case ScriptImportDecision.MoveComplete:
|
||||
transfer = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (transfer)
|
||||
{
|
||||
_diskTransferService.TransferFile(trackFilePath, destinationFilePath, mode);
|
||||
}
|
||||
|
||||
_updateTrackFileService.ChangeFileDateForFile(trackFile, artist, tracks);
|
||||
|
||||
try
|
||||
|
|
|
@ -216,8 +216,7 @@ namespace NzbDrone.Core.MediaFiles.TrackImport
|
|||
trackFile.SceneName = localTrack.SceneName;
|
||||
trackFile.OriginalFilePath = GetOriginalFilePath(downloadClientItem, localTrack);
|
||||
|
||||
var moveResult = _trackFileUpgrader.UpgradeTrackFile(trackFile, localTrack, copyOnly);
|
||||
oldFiles = moveResult.OldFiles;
|
||||
oldFiles = _trackFileUpgrader.UpgradeTrackFile(trackFile, localTrack, copyOnly).OldFiles;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -108,6 +108,7 @@ namespace NzbDrone.Core.MediaFiles.TrackImport
|
|||
var localTrack = new LocalTrack
|
||||
{
|
||||
DownloadClientAlbumInfo = downloadClientItemInfo,
|
||||
DownloadItem = downloadClientItem,
|
||||
FolderAlbumInfo = folderInfo,
|
||||
Path = file.FullName,
|
||||
Size = file.Length,
|
||||
|
|
|
@ -70,6 +70,8 @@ namespace NzbDrone.Core.MediaFiles
|
|||
_mediaFileService.Delete(file, DeleteMediaFileReason.Upgrade);
|
||||
}
|
||||
|
||||
localTrack.OldFiles = moveFileResult.OldFiles;
|
||||
|
||||
if (copyOnly)
|
||||
{
|
||||
moveFileResult.TrackFile = _trackFileMover.CopyTrackFile(trackFile, localTrack);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.MediaFiles.TrackImport.Identification;
|
||||
using NzbDrone.Core.Music;
|
||||
using NzbDrone.Core.Qualities;
|
||||
|
@ -19,11 +21,13 @@ namespace NzbDrone.Core.Parser.Model
|
|||
public ParsedTrackInfo FileTrackInfo { get; set; }
|
||||
public ParsedAlbumInfo FolderAlbumInfo { get; set; }
|
||||
public ParsedAlbumInfo DownloadClientAlbumInfo { get; set; }
|
||||
public DownloadClientItem DownloadItem { get; set; }
|
||||
public List<string> AcoustIdResults { get; set; }
|
||||
public Artist Artist { get; set; }
|
||||
public Album Album { get; set; }
|
||||
public AlbumRelease Release { get; set; }
|
||||
public List<Track> Tracks { get; set; }
|
||||
public List<TrackFile> OldFiles { get; set; }
|
||||
public Distance Distance { get; set; }
|
||||
public QualityModel Quality { get; set; }
|
||||
public bool ExistingFile { get; set; }
|
||||
|
|
Loading…
Reference in New Issue