mirror of https://github.com/lidarr/Lidarr
Add the support to copy .cue files to the media library folder.
(cherry picked from commit 57ae74b49afea29100882edbe6e49fa24210bbbf)
This commit is contained in:
parent
31016bca8a
commit
16a3fbe25b
|
@ -58,6 +58,11 @@ const columns = [
|
|||
label: () => 'Is Single File Release',
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'cuesheetPath',
|
||||
label: () => 'Cuesheet Path',
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'releaseGroup',
|
||||
label: () => translate('ReleaseGroup'),
|
||||
|
@ -441,6 +446,7 @@ class InteractiveImportModalContent extends Component {
|
|||
onSelectedChange={this.onSelectedChange}
|
||||
onValidRowChange={this.onValidRowChange}
|
||||
isSingleFileRelease={item.isSingleFileRelease}
|
||||
cuesheetPath={item.cuesheetPath}
|
||||
/>
|
||||
);
|
||||
})
|
||||
|
|
|
@ -135,6 +135,7 @@ class InteractiveImportModalContentConnector extends Component {
|
|||
albumReleaseId,
|
||||
tracks,
|
||||
isSingleFileRelease,
|
||||
cuesheetPath,
|
||||
quality,
|
||||
disableReleaseSwitching
|
||||
} = item;
|
||||
|
@ -149,7 +150,7 @@ class InteractiveImportModalContentConnector extends Component {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!isSingleFileRelease && (!tracks || !tracks.length)) {
|
||||
if (!(isSingleFileRelease && cuesheetPath) && (!tracks || !tracks.length)) {
|
||||
this.setState({ interactiveImportErrorMessage: 'One or more tracks must be chosen for each selected file' });
|
||||
return false;
|
||||
}
|
||||
|
@ -166,6 +167,7 @@ class InteractiveImportModalContentConnector extends Component {
|
|||
albumReleaseId,
|
||||
trackIds: _.map(tracks, 'id'),
|
||||
isSingleFileRelease: item.isSingleFileRelease,
|
||||
cuesheetPath: item.cuesheetPath,
|
||||
quality,
|
||||
downloadId: this.props.downloadId,
|
||||
disableReleaseSwitching
|
||||
|
|
|
@ -65,6 +65,7 @@ class InteractiveImportRow extends Component {
|
|||
album,
|
||||
tracks,
|
||||
isSingleFileRelease,
|
||||
cuesheetPath,
|
||||
quality,
|
||||
isSelected,
|
||||
onValidRowChange
|
||||
|
@ -83,7 +84,7 @@ class InteractiveImportRow extends Component {
|
|||
const isValid = !!(
|
||||
artist &&
|
||||
album &&
|
||||
(isSingleFileRelease || tracks.length) &&
|
||||
((isSingleFileRelease && cuesheetPath) || tracks.length) &&
|
||||
quality
|
||||
);
|
||||
|
||||
|
@ -169,6 +170,7 @@ class InteractiveImportRow extends Component {
|
|||
albumReleaseId,
|
||||
tracks,
|
||||
isSingleFileRelease,
|
||||
cuesheetPath,
|
||||
quality,
|
||||
releaseGroup,
|
||||
size,
|
||||
|
@ -281,6 +283,15 @@ class InteractiveImportRow extends Component {
|
|||
}
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell
|
||||
id={id}
|
||||
title={'Cuesheet Path'}
|
||||
>
|
||||
{
|
||||
cuesheetPath
|
||||
}
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCellButton
|
||||
title={translate('ClickToChangeReleaseGroup')}
|
||||
onPress={this.onSelectReleaseGroupPress}
|
||||
|
@ -422,6 +433,7 @@ InteractiveImportRow.propTypes = {
|
|||
albumReleaseId: PropTypes.number,
|
||||
tracks: PropTypes.arrayOf(PropTypes.object),
|
||||
isSingleFileRelease: PropTypes.bool.isRequired,
|
||||
cuesheetPath: PropTypes.string.isRequired,
|
||||
releaseGroup: PropTypes.string,
|
||||
quality: PropTypes.object,
|
||||
size: PropTypes.number.isRequired,
|
||||
|
|
|
@ -207,6 +207,7 @@ export const actionHandlers = handleThunks({
|
|||
albumReleaseId: item.albumReleaseId ? item.albumReleaseId : undefined,
|
||||
trackIds: (item.tracks || []).map((e) => e.id),
|
||||
isSingleFileRelease: item.isSingleFileRelease,
|
||||
cuesheetPath: item.cuesheetPath,
|
||||
quality: item.quality,
|
||||
releaseGroup: item.releaseGroup,
|
||||
downloadId: item.downloadId,
|
||||
|
|
|
@ -85,6 +85,7 @@ namespace Lidarr.Api.V1.ManualImport
|
|||
ReplaceExistingFiles = resource.ReplaceExistingFiles,
|
||||
DisableReleaseSwitching = resource.DisableReleaseSwitching,
|
||||
IsSingleFileRelease = resource.IsSingleFileRelease,
|
||||
CuesheetPath = resource.CuesheetPath,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace Lidarr.Api.V1.ManualImport
|
|||
public bool ReplaceExistingFiles { get; set; }
|
||||
public bool DisableReleaseSwitching { get; set; }
|
||||
public bool IsSingleFileRelease { get; set; }
|
||||
public string CuesheetPath { get; set; }
|
||||
}
|
||||
|
||||
public static class ManualImportResourceMapper
|
||||
|
@ -54,6 +55,7 @@ namespace Lidarr.Api.V1.ManualImport
|
|||
Quality = model.Quality,
|
||||
ReleaseGroup = model.ReleaseGroup,
|
||||
IsSingleFileRelease = model.IsSingleFileRelease,
|
||||
CuesheetPath = model.CuesheetPath,
|
||||
|
||||
// QualityWeight
|
||||
DownloadId = model.DownloadId,
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace Lidarr.Api.V1.ManualImport
|
|||
public bool ReplaceExistingFiles { get; set; }
|
||||
public bool DisableReleaseSwitching { get; set; }
|
||||
public bool IsSingleFileRelease { get; set; }
|
||||
|
||||
public string CuesheetPath { get; set; }
|
||||
public IEnumerable<Rejection> Rejections { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -140,6 +140,7 @@ namespace NzbDrone.Core.MediaFiles
|
|||
|
||||
CleanMediaFiles(folder, files.Select(x => x.FullName).ToList());
|
||||
mediaFileList.AddRange(files);
|
||||
mediaFileList.RemoveAll(x => x.Extension == ".cue");
|
||||
}
|
||||
|
||||
musicFilesStopwatch.Stop();
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.IO;
|
|||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnsureThat;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.MediaFiles.Events;
|
||||
using NzbDrone.Core.MediaFiles.TrackImport;
|
||||
|
@ -90,6 +91,21 @@ namespace NzbDrone.Core.MediaFiles
|
|||
|
||||
EnsureTrackFolder(trackFile, localTrack, filePath);
|
||||
|
||||
if (!localTrack.CuesheetPath.Empty())
|
||||
{
|
||||
var directory = Path.GetDirectoryName(filePath);
|
||||
var fileName = Path.GetFileNameWithoutExtension(filePath);
|
||||
var cuesheetPath = Path.Combine(directory, fileName + ".cue");
|
||||
_diskTransferService.TransferFile(localTrack.CuesheetPath, cuesheetPath, TransferMode.Copy);
|
||||
var lines = new List<string>(File.ReadAllLines(cuesheetPath));
|
||||
var fileLineIndex = lines.FindIndex(line => line.Contains("FILE"));
|
||||
if (fileLineIndex != -1)
|
||||
{
|
||||
lines[fileLineIndex] = "FILE \"" + Path.GetFileName(filePath) + "\" WAVE";
|
||||
File.WriteAllLines(cuesheetPath, lines);
|
||||
}
|
||||
}
|
||||
|
||||
if (_configService.CopyUsingHardlinks)
|
||||
{
|
||||
_logger.Debug("Attempting to hardlink track file: {0} to {1}", trackFile.Path, filePath);
|
||||
|
|
|
@ -16,6 +16,7 @@ namespace NzbDrone.Core.MediaFiles.TrackImport.Manual
|
|||
public string DownloadId { get; set; }
|
||||
public bool DisableReleaseSwitching { get; set; }
|
||||
public bool IsSingleFileRelease { get; set; }
|
||||
public string CuesheetPath { get; set; }
|
||||
|
||||
public bool Equals(ManualImportFile other)
|
||||
{
|
||||
|
|
|
@ -33,5 +33,6 @@ namespace NzbDrone.Core.MediaFiles.TrackImport.Manual
|
|||
public bool ReplaceExistingFiles { get; set; }
|
||||
public bool DisableReleaseSwitching { get; set; }
|
||||
public bool IsSingleFileRelease { get; set; }
|
||||
public string CuesheetPath { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -186,6 +186,7 @@ namespace NzbDrone.Core.MediaFiles.TrackImport.Manual
|
|||
audioFiles.RemoveAll(l => cueFiles.Contains(l));
|
||||
foreach (var cueFile in cueFiles)
|
||||
{
|
||||
// TODO move this to the disk service
|
||||
using (var fs = cueFile.OpenRead())
|
||||
{
|
||||
var bytes = new byte[cueFile.Length];
|
||||
|
@ -239,19 +240,19 @@ namespace NzbDrone.Core.MediaFiles.TrackImport.Manual
|
|||
audioFile
|
||||
};
|
||||
|
||||
results.AddRange(ProcessFolder(downloadId, artistFromCue, albumsFromCue[0], filter, replaceExistingFiles, downloadClientItem, albumTitle, tempAudioFiles, true));
|
||||
results.AddRange(ProcessFolder(downloadId, artistFromCue, albumsFromCue[0], filter, replaceExistingFiles, downloadClientItem, albumTitle, tempAudioFiles, cueFile.FullName));
|
||||
audioFiles.Remove(audioFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
results.AddRange(ProcessFolder(downloadId, artist, null, filter, replaceExistingFiles, downloadClientItem, directoryInfo.Name, audioFiles, false));
|
||||
results.AddRange(ProcessFolder(downloadId, artist, null, filter, replaceExistingFiles, downloadClientItem, directoryInfo.Name, audioFiles, string.Empty));
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private List<ManualImportItem> ProcessFolder(string downloadId, Artist overrideArtist, Album overrideAlbum, FilterFilesType filter, bool replaceExistingFiles, DownloadClientItem downloadClientItem, string albumTitle, List<IFileInfo> audioFiles, bool isSingleFileRelease)
|
||||
private List<ManualImportItem> ProcessFolder(string downloadId, Artist overrideArtist, Album overrideAlbum, FilterFilesType filter, bool replaceExistingFiles, DownloadClientItem downloadClientItem, string albumTitle, List<IFileInfo> audioFiles, string cuesheetPath)
|
||||
{
|
||||
var idOverrides = new IdentificationOverrides
|
||||
{
|
||||
|
@ -262,7 +263,7 @@ namespace NzbDrone.Core.MediaFiles.TrackImport.Manual
|
|||
{
|
||||
DownloadClientItem = downloadClientItem,
|
||||
ParsedAlbumInfo = Parser.Parser.ParseAlbumTitle(albumTitle),
|
||||
IsSingleFileRelease = isSingleFileRelease
|
||||
IsSingleFileRelease = !cuesheetPath.Empty()
|
||||
};
|
||||
var config = new ImportDecisionMakerConfig
|
||||
{
|
||||
|
@ -286,7 +287,10 @@ namespace NzbDrone.Core.MediaFiles.TrackImport.Manual
|
|||
var existingDecisions = decisions.Except(newFiles.Select(x => x.Decision));
|
||||
var existingItems = existingDecisions.Select(x => MapItem(x, null, replaceExistingFiles, false));
|
||||
|
||||
return newItems.Concat(existingItems).ToList();
|
||||
var itemsList = newItems.Concat(existingItems).ToList();
|
||||
itemsList.ForEach(item => { item.CuesheetPath = cuesheetPath; });
|
||||
|
||||
return itemsList;
|
||||
}
|
||||
|
||||
public List<ManualImportItem> UpdateItems(List<ManualImportItem> items)
|
||||
|
@ -405,6 +409,7 @@ namespace NzbDrone.Core.MediaFiles.TrackImport.Manual
|
|||
item.ReplaceExistingFiles = replaceExistingFiles;
|
||||
item.DisableReleaseSwitching = disableReleaseSwitching;
|
||||
item.IsSingleFileRelease = decision.Item.IsSingleFileRelease;
|
||||
item.CuesheetPath = decision.Item.CuesheetPath;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
@ -454,6 +459,7 @@ namespace NzbDrone.Core.MediaFiles.TrackImport.Manual
|
|||
Album = album,
|
||||
Release = release,
|
||||
IsSingleFileRelease = file.IsSingleFileRelease,
|
||||
CuesheetPath = file.CuesheetPath,
|
||||
};
|
||||
|
||||
if (file.IsSingleFileRelease)
|
||||
|
|
|
@ -32,6 +32,7 @@ namespace NzbDrone.Core.Parser.Model
|
|||
public string ReleaseGroup { get; set; }
|
||||
public string SceneName { get; set; }
|
||||
public bool IsSingleFileRelease { get; set; }
|
||||
public string CuesheetPath { get; set; }
|
||||
public override string ToString()
|
||||
{
|
||||
return Path;
|
||||
|
|
Loading…
Reference in New Issue