diff --git a/frontend/src/InteractiveImport/Interactive/InteractiveImportRow.js b/frontend/src/InteractiveImport/Interactive/InteractiveImportRow.js
index f8d797d53..470553638 100644
--- a/frontend/src/InteractiveImport/Interactive/InteractiveImportRow.js
+++ b/frontend/src/InteractiveImport/Interactive/InteractiveImportRow.js
@@ -65,7 +65,6 @@ class InteractiveImportRow extends Component {
album,
tracks,
isSingleFileRelease,
- cuesheetPath,
quality,
isSelected,
onValidRowChange
@@ -84,7 +83,7 @@ class InteractiveImportRow extends Component {
const isValid = !!(
artist &&
album &&
- ((isSingleFileRelease && cuesheetPath) || tracks.length) &&
+ (isSingleFileRelease || tracks.length) &&
quality
);
@@ -261,7 +260,7 @@ class InteractiveImportRow extends Component {
@@ -269,7 +268,7 @@ class InteractiveImportRow extends Component {
showTrackNumbersLoading &&
}
{
- !isSingleFileRelease && showTrackNumbersPlaceholder ? : trackNumbers
+ showTrackNumbersPlaceholder ? : trackNumbers
}
diff --git a/src/NzbDrone.Core/MediaFiles/CueSheet.cs b/src/NzbDrone.Core/MediaFiles/CueSheet.cs
new file mode 100644
index 000000000..bcf330f58
--- /dev/null
+++ b/src/NzbDrone.Core/MediaFiles/CueSheet.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Collections.Generic;
+using System.IO.Abstractions;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using NzbDrone.Core.Datastore;
+
+namespace NzbDrone.Core.MediaFiles
+{
+ public class CueSheet : ModelBase
+ {
+ public CueSheet(IFileInfo fileInfo)
+ {
+ using (var fs = fileInfo.OpenRead())
+ {
+ var bytes = new byte[fileInfo.Length];
+ var encoding = new UTF8Encoding(true);
+ string content;
+ while (fs.Read(bytes, 0, bytes.Length) > 0)
+ {
+ content = encoding.GetString(bytes);
+ var lines = content.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
+
+ // Single-file cue means it's an unsplit image
+ var fileNames = ReadFieldFromCuesheet(lines, "FILE");
+ IsSingleFileRelease = fileNames.Count == 1;
+ FileName = fileNames[0];
+
+ var performers = ReadFieldFromCuesheet(lines, "PERFORMER");
+ if (performers.Count > 0)
+ {
+ Performer = performers[0];
+ }
+
+ var titles = ReadFieldFromCuesheet(lines, "TITLE");
+ if (titles.Count > 0)
+ {
+ Title = titles[0];
+ }
+
+ Date = ReadOptionalFieldFromCuesheet(lines, "REM DATE");
+ }
+ }
+ }
+
+ public bool IsSingleFileRelease { get; set; }
+ public string FileName { get; set; }
+ public string Title { get; set; }
+ public string Performer { get; set; }
+ public string Date { get; set; }
+
+ private static List ReadFieldFromCuesheet(string[] lines, string fieldName)
+ {
+ var results = new List();
+ var candidates = lines.Where(l => l.StartsWith(fieldName)).ToList();
+ foreach (var candidate in candidates)
+ {
+ var matches = Regex.Matches(candidate, "\"(.*?)\"");
+ var result = matches.ToList()[0].Groups[1].Value;
+ results.Add(result);
+ }
+
+ return results;
+ }
+
+ private static string ReadOptionalFieldFromCuesheet(string[] lines, string fieldName)
+ {
+ var results = lines.Where(l => l.StartsWith(fieldName));
+ if (results.Any())
+ {
+ var matches = Regex.Matches(results.ToList()[0], fieldName + " (.+)");
+ var result = matches.ToList()[0].Groups[1].Value;
+ return result;
+ }
+
+ return "";
+ }
+ }
+}
diff --git a/src/NzbDrone.Core/MediaFiles/TrackImport/Aggregation/Aggregators/AggregateFilenameInfo.cs b/src/NzbDrone.Core/MediaFiles/TrackImport/Aggregation/Aggregators/AggregateFilenameInfo.cs
index 9afb5e927..63d57512f 100644
--- a/src/NzbDrone.Core/MediaFiles/TrackImport/Aggregation/Aggregators/AggregateFilenameInfo.cs
+++ b/src/NzbDrone.Core/MediaFiles/TrackImport/Aggregation/Aggregators/AggregateFilenameInfo.cs
@@ -65,13 +65,18 @@ namespace NzbDrone.Core.MediaFiles.TrackImport.Aggregation.Aggregators
|| tracks.Any(x => x.FileTrackInfo.DiscNumber == 0))
{
_logger.Debug("Missing data in tags, trying filename augmentation");
- if (tracks.Count == 1 && tracks[0].IsSingleFileRelease)
+ if (release.IsSingleFileRelease)
{
- tracks[0].FileTrackInfo.ArtistTitle = tracks[0].Artist.Name;
- tracks[0].FileTrackInfo.AlbumTitle = tracks[0].Album.Title;
+ for (var i = 0; i < tracks.Count; ++i)
+ {
+ tracks[i].FileTrackInfo.ArtistTitle = tracks[i].Artist.Name;
+ tracks[i].FileTrackInfo.AlbumTitle = tracks[i].Album.Title;
+ tracks[i].FileTrackInfo.DiscNumber = i + 1;
+ tracks[i].FileTrackInfo.DiscCount = tracks.Count;
- // TODO this is too bold, the release year is not the one from the .cue file
- tracks[0].FileTrackInfo.Year = (uint)tracks[0].Album.ReleaseDate.Value.Year;
+ // TODO this is too bold, the release year is not the one from the .cue file
+ tracks[i].FileTrackInfo.Year = (uint)tracks[i].Album.ReleaseDate.Value.Year;
+ }
}
else
{
diff --git a/src/NzbDrone.Core/MediaFiles/TrackImport/Identification/CandidateService.cs b/src/NzbDrone.Core/MediaFiles/TrackImport/Identification/CandidateService.cs
index 1d3e0e140..f74508c3a 100644
--- a/src/NzbDrone.Core/MediaFiles/TrackImport/Identification/CandidateService.cs
+++ b/src/NzbDrone.Core/MediaFiles/TrackImport/Identification/CandidateService.cs
@@ -131,11 +131,11 @@ namespace NzbDrone.Core.MediaFiles.TrackImport.Identification
private List GetDbCandidatesByAlbum(LocalAlbumRelease localAlbumRelease, Album album, bool includeExisting)
{
- if (localAlbumRelease.LocalTracks.Count == 1 && localAlbumRelease.LocalTracks[0].IsSingleFileRelease)
+ if (localAlbumRelease.IsSingleFileRelease)
{
return GetDbCandidatesByRelease(_releaseService.GetReleasesByAlbum(album.Id)
- .OrderBy(x => x.ReleaseDate)
- .ToList(), includeExisting);
+ .OrderBy(x => x.ReleaseDate)
+ .ToList(), includeExisting);
}
// sort candidate releases by closest track count so that we stand a chance of
diff --git a/src/NzbDrone.Core/MediaFiles/TrackImport/Identification/DistanceCalculator.cs b/src/NzbDrone.Core/MediaFiles/TrackImport/Identification/DistanceCalculator.cs
index a2f68fd15..4b53efff4 100644
--- a/src/NzbDrone.Core/MediaFiles/TrackImport/Identification/DistanceCalculator.cs
+++ b/src/NzbDrone.Core/MediaFiles/TrackImport/Identification/DistanceCalculator.cs
@@ -120,7 +120,7 @@ namespace NzbDrone.Core.MediaFiles.TrackImport.Identification
var releaseYear = release.ReleaseDate?.Year ?? 0;
// The single file version's year is from the album year already, to avoid false positives here we consider it's always different
- var isSameWithAlbumYear = (localTracks.Count == 1 && localTracks[0].IsSingleFileRelease) ? false : localYear == albumYear;
+ var isSameWithAlbumYear = localTracks.All(x => x.IsSingleFileRelease == true) ? false : localYear == albumYear;
if (isSameWithAlbumYear || localYear == releaseYear)
{
dist.Add("year", 0.0);
@@ -179,7 +179,7 @@ namespace NzbDrone.Core.MediaFiles.TrackImport.Identification
}
// tracks
- if (localTracks.Count == 1 && localTracks[0].IsSingleFileRelease)
+ if (localTracks.All(x => x.IsSingleFileRelease == true))
{
dist.Add("tracks", 0);
}
diff --git a/src/NzbDrone.Core/MediaFiles/TrackImport/Identification/IdentificationService.cs b/src/NzbDrone.Core/MediaFiles/TrackImport/Identification/IdentificationService.cs
index 32cd6f43a..bf5b76501 100644
--- a/src/NzbDrone.Core/MediaFiles/TrackImport/Identification/IdentificationService.cs
+++ b/src/NzbDrone.Core/MediaFiles/TrackImport/Identification/IdentificationService.cs
@@ -154,7 +154,7 @@ namespace NzbDrone.Core.MediaFiles.TrackImport.Identification
private bool ShouldFingerprint(LocalAlbumRelease localAlbumRelease)
{
- if (localAlbumRelease.LocalTracks.Count == 1 && localAlbumRelease.LocalTracks[0].IsSingleFileRelease)
+ if (localAlbumRelease.IsSingleFileRelease)
{
return false;
}
@@ -340,10 +340,18 @@ namespace NzbDrone.Core.MediaFiles.TrackImport.Identification
localAlbumRelease.AlbumRelease = release;
localAlbumRelease.ExistingTracks = extraTracks;
localAlbumRelease.TrackMapping = mapping;
- if (localAlbumRelease.LocalTracks.Count == 1 && localAlbumRelease.LocalTracks[0].IsSingleFileRelease)
+ if (localAlbumRelease.IsSingleFileRelease)
{
- localAlbumRelease.LocalTracks[0].Tracks = release.Tracks;
- localAlbumRelease.LocalTracks[0].Tracks.ForEach(x => x.IsSingleFileRelease = true);
+ localAlbumRelease.LocalTracks.ForEach(x => x.Tracks.Clear());
+ for (var i = 0; i < release.Tracks.Value.Count; i++)
+ {
+ var track = release.Tracks.Value[i];
+ var localTrackIndex = localAlbumRelease.LocalTracks.FindIndex(x => x.FileTrackInfo.DiscNumber == track.MediumNumber);
+ if (localTrackIndex != -1)
+ {
+ localAlbumRelease.LocalTracks[localTrackIndex].Tracks.Add(track);
+ }
+ }
}
if (currDistance == 0.0)
@@ -360,10 +368,9 @@ namespace NzbDrone.Core.MediaFiles.TrackImport.Identification
public TrackMapping MapReleaseTracks(List localTracks, List