Skip to content

Commit

Permalink
Fixed: "Specific Book" setting for lidarr list import
Browse files Browse the repository at this point in the history
Fixes #2435

(cherry picked from commit 466876da624843f62c849dfb28ac9515b6fe3a2c)
  • Loading branch information
TomW1605 authored and ta264 committed Aug 3, 2022
1 parent d85d2bb commit d96775a
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 57 deletions.
Expand Up @@ -73,6 +73,18 @@ private void WithAlbumId()
_importListReports.First().AlbumMusicBrainzId = "09474d62-17dd-3a4f-98fb-04c65f38a479";
}

private void WithSecondBook()
{
var importListItem2 = new ImportListItemInfo
{
Artist = "Linkin Park",
ArtistMusicBrainzId = "f59c5520-5f46-4d2c-b2c4-822eabf53419",
Album = "Meteora 2",
AlbumMusicBrainzId = "madeup"
};
_importListReports.Add(importListItem2);
}

private void WithExistingArtist()
{
Mocker.GetMock<IArtistService>()
Expand Down Expand Up @@ -275,5 +287,28 @@ public void should_not_add_album_if_excluded_artist()
Mocker.GetMock<IAddAlbumService>()
.Verify(v => v.AddAlbums(It.Is<List<Album>>(t => t.Count == 0), false, It.IsAny<bool>()));
}

[TestCase(ImportListMonitorType.None, 0, false)]
[TestCase(ImportListMonitorType.SpecificAlbum, 2, true)]
[TestCase(ImportListMonitorType.EntireArtist, 0, true)]
public void should_add_two_albums(ImportListMonitorType monitor, int expectedAlbumsMonitored, bool expectedArtistMonitored)
{
WithAlbum();
WithAlbumId();
WithSecondBook();
WithArtistId();
WithMonitorType(monitor);

Subject.Execute(new ImportListSyncCommand());

Mocker.GetMock<IAddAlbumService>()
.Verify(v => v.AddAlbums(It.Is<List<Album>>(t => t.Count == 2), false, true));
Mocker.GetMock<IAddArtistService>()
.Verify(v => v.AddArtists(It.Is<List<Artist>>(t => t.Count == 1 &&
t.First().AddOptions.AlbumsToMonitor.Count == expectedAlbumsMonitored &&
t.First().Monitored == expectedArtistMonitored),
false,
true));
}
}
}
115 changes: 66 additions & 49 deletions src/NzbDrone.Core/ImportLists/ImportListSyncService.cs
Expand Up @@ -104,7 +104,7 @@ private List<Album> ProcessReports(List<ImportListItemInfo> reports)
MapAlbumReport(report);
}

ProcessAlbumReport(importList, report, listExclusions, albumsToAdd);
ProcessAlbumReport(importList, report, listExclusions, albumsToAdd, artistsToAdd);
}
else if (report.Artist.IsNotNullOrWhiteSpace() || report.ArtistMusicBrainzId.IsNotNullOrWhiteSpace())
{
Expand Down Expand Up @@ -147,11 +147,11 @@ private void MapAlbumReport(ImportListItemInfo report)

report.AlbumMusicBrainzId = mappedAlbum.ForeignAlbumId;
report.Album = mappedAlbum.Title;
report.Artist = mappedAlbum.ArtistMetadata?.Value?.Name;
report.ArtistMusicBrainzId = mappedAlbum.ArtistMetadata?.Value?.ForeignArtistId;
report.Artist ??= mappedAlbum.ArtistMetadata?.Value?.Name;
report.ArtistMusicBrainzId ??= mappedAlbum.ArtistMetadata?.Value?.ForeignArtistId;
}

private void ProcessAlbumReport(ImportListDefinition importList, ImportListItemInfo report, List<ImportListExclusion> listExclusions, List<Album> albumsToAdd)
private void ProcessAlbumReport(ImportListDefinition importList, ImportListItemInfo report, List<ImportListExclusion> listExclusions, List<Album> albumsToAdd, List<Artist> artistsToAdd)
{
if (report.AlbumMusicBrainzId == null)
{
Expand All @@ -169,13 +169,13 @@ private void ProcessAlbumReport(ImportListDefinition importList, ImportListItemI

if (excludedAlbum != null)
{
_logger.Debug("{0} [{1}] Rejected due to list exlcusion", report.AlbumMusicBrainzId, report.Album);
_logger.Debug("{0} [{1}] Rejected due to list exclusion", report.AlbumMusicBrainzId, report.Album);
return;
}

if (excludedArtist != null)
{
_logger.Debug("{0} [{1}] Rejected due to list exlcusion for parent artist", report.AlbumMusicBrainzId, report.Album);
_logger.Debug("{0} [{1}] Rejected due to list exclusion for parent artist", report.AlbumMusicBrainzId, report.Album);
return;
}

Expand Down Expand Up @@ -211,25 +211,32 @@ private void ProcessAlbumReport(ImportListDefinition importList, ImportListItemI
{
var monitored = importList.ShouldMonitor != ImportListMonitorType.None;

var toAddArtist = new Artist
{
Monitored = monitored,
RootFolderPath = importList.RootFolderPath,
QualityProfileId = importList.ProfileId,
MetadataProfileId = importList.MetadataProfileId,
Tags = importList.Tags,
AddOptions = new AddArtistOptions
{
SearchForMissingAlbums = monitored,
Monitored = monitored,
Monitor = monitored ? MonitorTypes.All : MonitorTypes.None
}
};

if (report.ArtistMusicBrainzId != null && report.Artist != null)
{
toAddArtist = ProcessArtistReport(importList, report, listExclusions, artistsToAdd);
}

var toAdd = new Album
{
ForeignAlbumId = report.AlbumMusicBrainzId,
Monitored = monitored,
AnyReleaseOk = true,
Artist = new Artist
{
Monitored = monitored,
RootFolderPath = importList.RootFolderPath,
QualityProfileId = importList.ProfileId,
MetadataProfileId = importList.MetadataProfileId,
Tags = importList.Tags,
AddOptions = new AddArtistOptions
{
SearchForMissingAlbums = monitored,
Monitored = monitored,
Monitor = monitored ? MonitorTypes.All : MonitorTypes.None
}
},
Artist = toAddArtist,
AddOptions = new AddAlbumOptions
{
SearchForNewAlbum = monitored
Expand All @@ -238,7 +245,7 @@ private void ProcessAlbumReport(ImportListDefinition importList, ImportListItemI

if (importList.ShouldMonitor == ImportListMonitorType.SpecificAlbum)
{
toAdd.Artist.Value.AddOptions.AlbumsToMonitor.Add(toAdd.ForeignAlbumId);
toAddArtist.AddOptions.AlbumsToMonitor.Add(toAdd.ForeignAlbumId);
}

albumsToAdd.Add(toAdd);
Expand All @@ -253,11 +260,11 @@ private void MapArtistReport(ImportListItemInfo report)
report.Artist = mappedArtist?.Metadata.Value?.Name;
}

private void ProcessArtistReport(ImportListDefinition importList, ImportListItemInfo report, List<ImportListExclusion> listExclusions, List<Artist> artistsToAdd)
private Artist ProcessArtistReport(ImportListDefinition importList, ImportListItemInfo report, List<ImportListExclusion> listExclusions, List<Artist> artistsToAdd)
{
if (report.ArtistMusicBrainzId == null)
{
return;
return null;
}

// Check to see if artist in DB
Expand All @@ -266,51 +273,61 @@ private void ProcessArtistReport(ImportListDefinition importList, ImportListItem
// Check to see if artist excluded
var excludedArtist = listExclusions.Where(s => s.ForeignId == report.ArtistMusicBrainzId).SingleOrDefault();

// Check to see if artist in import
var existingImportArtist = artistsToAdd.Find(i => i.ForeignArtistId == report.ArtistMusicBrainzId);

if (excludedArtist != null)
{
_logger.Debug("{0} [{1}] Rejected due to list exlcusion", report.ArtistMusicBrainzId, report.Artist);
return;
_logger.Debug("{0} [{1}] Rejected due to list exclusion", report.ArtistMusicBrainzId, report.Artist);
return null;
}

if (existingArtist != null)
{
_logger.Debug("{0} [{1}] Rejected, Author Exists in DB. Ensuring Author monitored", report.ArtistMusicBrainzId, report.Artist);
_logger.Debug("{0} [{1}] Rejected, artist exists in DB. Ensuring artist monitored", report.ArtistMusicBrainzId, report.Artist);

if (!existingArtist.Monitored)
{
existingArtist.Monitored = true;
_artistService.UpdateArtist(existingArtist);
}

return;
return existingArtist;
}

// Append Artist if not already in DB or already on add list
if (artistsToAdd.All(s => s.Metadata.Value.ForeignArtistId != report.ArtistMusicBrainzId))
if (existingImportArtist != null)
{
var monitored = importList.ShouldMonitor != ImportListMonitorType.None;
_logger.Debug("{0} [{1}] Rejected, artist exists in Import.", report.ArtistMusicBrainzId, report.Artist);

return existingImportArtist;
}

var monitored = importList.ShouldMonitor != ImportListMonitorType.None;

artistsToAdd.Add(new Artist
var toAdd = new Artist
{
Metadata = new ArtistMetadata
{
Metadata = new ArtistMetadata
{
ForeignArtistId = report.ArtistMusicBrainzId,
Name = report.Artist
},
ForeignArtistId = report.ArtistMusicBrainzId,
Name = report.Artist
},
Monitored = monitored,
MonitorNewItems = importList.MonitorNewItems,
RootFolderPath = importList.RootFolderPath,
QualityProfileId = importList.ProfileId,
MetadataProfileId = importList.MetadataProfileId,
Tags = importList.Tags,
AddOptions = new AddArtistOptions
{
SearchForMissingAlbums = monitored,
Monitored = monitored,
MonitorNewItems = importList.MonitorNewItems,
RootFolderPath = importList.RootFolderPath,
QualityProfileId = importList.ProfileId,
MetadataProfileId = importList.MetadataProfileId,
Tags = importList.Tags,
AddOptions = new AddArtistOptions
{
SearchForMissingAlbums = monitored,
Monitored = monitored,
Monitor = monitored ? MonitorTypes.All : MonitorTypes.None
}
});
}
Monitor = monitored ? MonitorTypes.All : MonitorTypes.None
}
};

artistsToAdd.Add(toAdd);

return toAdd;
}

public void Execute(ImportListSyncCommand message)
Expand Down
12 changes: 12 additions & 0 deletions src/NzbDrone.Core/ImportLists/Lidarr/LidarrAPIResource.cs
Expand Up @@ -4,6 +4,7 @@ namespace NzbDrone.Core.ImportLists.Lidarr
{
public class LidarrArtist
{
public int Id { get; set; }
public string ArtistName { get; set; }
public string ForeignArtistId { get; set; }
public string Overview { get; set; }
Expand All @@ -13,6 +14,17 @@ public class LidarrArtist
public HashSet<int> Tags { get; set; }
}

public class LidarrAlbum
{
public int ArtistId { get; set; }
public string Title { get; set; }
public string ForeignAlbumId { get; set; }
public string Overview { get; set; }
public List<MediaCover.MediaCover> Images { get; set; }
public bool Monitored { get; set; }
public LidarrArtist Artist { get; set; }
}

public class LidarrProfile
{
public string Name { get; set; }
Expand Down
19 changes: 13 additions & 6 deletions src/NzbDrone.Core/ImportLists/Lidarr/LidarrImport.cs
Expand Up @@ -30,21 +30,28 @@ public class LidarrImport : ImportListBase<LidarrSettings>

public override IList<ImportListItemInfo> Fetch()
{
var artists = new List<ImportListItemInfo>();
var artistsAndAlbums = new List<ImportListItemInfo>();

try
{
var remoteAlbums = _lidarrV1Proxy.GetAlbums(Settings);
var remoteArtists = _lidarrV1Proxy.GetArtists(Settings);

foreach (var remoteArtist in remoteArtists)
var artistDict = remoteArtists.ToDictionary(x => x.Id);

foreach (var remoteAlbum in remoteAlbums)
{
var remoteArtist = artistDict[remoteAlbum.ArtistId];
if ((!Settings.ProfileIds.Any() || Settings.ProfileIds.Contains(remoteArtist.QualityProfileId)) &&
(!Settings.TagIds.Any() || Settings.TagIds.Any(x => remoteArtist.Tags.Any(y => y == x))))
(!Settings.TagIds.Any() || Settings.TagIds.Any(x => remoteArtist.Tags.Any(y => y == x))) &&
remoteAlbum.Monitored && remoteArtist.Monitored)
{
artists.Add(new ImportListItemInfo
artistsAndAlbums.Add(new ImportListItemInfo
{
ArtistMusicBrainzId = remoteArtist.ForeignArtistId,
Artist = remoteArtist.ArtistName
Artist = remoteArtist.ArtistName,
AlbumMusicBrainzId = remoteAlbum.ForeignAlbumId,
Album = remoteAlbum.Title
});
}
}
Expand All @@ -56,7 +63,7 @@ public override IList<ImportListItemInfo> Fetch()
_importListStatusService.RecordFailure(Definition.Id);
}

return CleanupListItems(artists);
return CleanupListItems(artistsAndAlbums);
}

public override object RequestAction(string action, IDictionary<string, string> query)
Expand Down
6 changes: 6 additions & 0 deletions src/NzbDrone.Core/ImportLists/Lidarr/LidarrV1Proxy.cs
Expand Up @@ -12,6 +12,7 @@ namespace NzbDrone.Core.ImportLists.Lidarr
public interface ILidarrV1Proxy
{
List<LidarrArtist> GetArtists(LidarrSettings settings);
List<LidarrAlbum> GetAlbums(LidarrSettings settings);
List<LidarrProfile> GetProfiles(LidarrSettings settings);
List<LidarrTag> GetTags(LidarrSettings settings);
ValidationFailure Test(LidarrSettings settings);
Expand All @@ -33,6 +34,11 @@ public List<LidarrArtist> GetArtists(LidarrSettings settings)
return Execute<LidarrArtist>("/api/v1/artist", settings);
}

public List<LidarrAlbum> GetAlbums(LidarrSettings settings)
{
return Execute<LidarrAlbum>("/api/v1/album", settings);
}

public List<LidarrProfile> GetProfiles(LidarrSettings settings)
{
return Execute<LidarrProfile>("/api/v1/qualityprofile", settings);
Expand Down
4 changes: 2 additions & 2 deletions src/NzbDrone.Core/Music/Services/AlbumMonitoredService.cs
Expand Up @@ -41,9 +41,9 @@ public void SetAlbumMonitoredStatus(Artist artist, MonitoringOptions monitoringO
if (monitoredAlbums.Any())
{
ToggleAlbumsMonitoredState(
albums.Where(s => monitoredAlbums.Any(t => t == s.ForeignAlbumId)), true);
albums.Where(s => monitoredAlbums.Contains(s.ForeignAlbumId)), true);
ToggleAlbumsMonitoredState(
albums.Where(s => monitoredAlbums.Any(t => t != s.ForeignAlbumId)), false);
albums.Where(s => !monitoredAlbums.Contains(s.ForeignAlbumId)), false);
}
else
{
Expand Down

0 comments on commit d96775a

Please sign in to comment.