New: Allow monitoring all albums for import list artist

pull/6/head
ta264 6 years ago
parent 8e777025cb
commit 23316329ed

@ -10,3 +10,7 @@
display: none; display: none;
} }
.labelIcon {
margin-left: 8px;
}

@ -1,6 +1,7 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import { inputTypes, kinds } from 'Helpers/Props'; import { icons, inputTypes, kinds, tooltipPositions } from 'Helpers/Props';
import Icon from 'Components/Icon';
import Button from 'Components/Link/Button'; import Button from 'Components/Link/Button';
import SpinnerErrorButton from 'Components/Link/SpinnerErrorButton'; import SpinnerErrorButton from 'Components/Link/SpinnerErrorButton';
import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import LoadingIndicator from 'Components/Loading/LoadingIndicator';
@ -12,10 +13,41 @@ import Form from 'Components/Form/Form';
import FormGroup from 'Components/Form/FormGroup'; import FormGroup from 'Components/Form/FormGroup';
import FormLabel from 'Components/Form/FormLabel'; import FormLabel from 'Components/Form/FormLabel';
import FormInputGroup from 'Components/Form/FormInputGroup'; import FormInputGroup from 'Components/Form/FormInputGroup';
import Popover from 'Components/Tooltip/Popover';
import ProviderFieldFormGroup from 'Components/Form/ProviderFieldFormGroup'; import ProviderFieldFormGroup from 'Components/Form/ProviderFieldFormGroup';
import DescriptionList from 'Components/DescriptionList/DescriptionList';
import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem';
import styles from './EditImportListModalContent.css'; import styles from './EditImportListModalContent.css';
function ImportListMonitoringOptionsPopoverContent() {
return (
<DescriptionList>
<DescriptionListItem
title="None"
data="Do not monitor artists or albums"
/>
<DescriptionListItem
title="Specific Album"
data="Monitor artists but only monitor albums explicitly included in the list"
/>
<DescriptionListItem
title="All Artist Albums"
data="Monitor artists and all albums for each artist included on the import list"
/>
</DescriptionList>
);
}
function EditImportListModalContent(props) { function EditImportListModalContent(props) {
const monitorOptions = [
{ key: 'none', value: 'None' },
{ key: 'specificAlbum', value: 'Specific Album' },
{ key: 'entireArtist', value: 'All Artist Albums' }
];
const { const {
advancedSettings, advancedSettings,
isFetching, isFetching,
@ -92,11 +124,26 @@ function EditImportListModalContent(props) {
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<FormLabel>Monitor</FormLabel> <FormLabel>
Monitor
<Popover
anchor={
<Icon
className={styles.labelIcon}
name={icons.INFO}
/>
}
title="Monitoring Options"
body={<ImportListMonitoringOptionsPopoverContent />}
position={tooltipPositions.RIGHT}
/>
</FormLabel>
<FormInputGroup <FormInputGroup
type={inputTypes.CHECK} type={inputTypes.SELECT}
name="shouldMonitor" name="shouldMonitor"
values={monitorOptions}
helpText={'Monitor artists and albums added from this list'} helpText={'Monitor artists and albums added from this list'}
{...shouldMonitor} {...shouldMonitor}
onChange={onInputChange} onChange={onInputChange}

@ -107,8 +107,8 @@ export default {
[SELECT_IMPORT_LIST_SCHEMA]: (state, { payload }) => { [SELECT_IMPORT_LIST_SCHEMA]: (state, { payload }) => {
return selectProviderSchema(state, section, payload, (selectedSchema) => { return selectProviderSchema(state, section, payload, (selectedSchema) => {
selectedSchema.enableRss = selectedSchema.supportsRss; selectedSchema.enableAutomaticAdd = true;
selectedSchema.enableSearch = selectedSchema.supportsSearch; selectedSchema.shouldMonitor = 'entireArtist';
return selectedSchema; return selectedSchema;
}); });

@ -5,7 +5,7 @@ namespace Lidarr.Api.V1.ImportLists
public class ImportListResource : ProviderResource public class ImportListResource : ProviderResource
{ {
public bool EnableAutomaticAdd { get; set; } public bool EnableAutomaticAdd { get; set; }
public bool ShouldMonitor { get; set; } public ImportListMonitorType ShouldMonitor { get; set; }
public string RootFolderPath { get; set; } public string RootFolderPath { get; set; }
public int QualityProfileId { get; set; } public int QualityProfileId { get; set; }
public int LanguageProfileId { get; set; } public int LanguageProfileId { get; set; }

@ -39,7 +39,7 @@ namespace NzbDrone.Core.Test.ImportListTests
Mocker.GetMock<IImportListFactory>() Mocker.GetMock<IImportListFactory>()
.Setup(v => v.Get(It.IsAny<int>())) .Setup(v => v.Get(It.IsAny<int>()))
.Returns(new ImportListDefinition{ ShouldMonitor = true }); .Returns(new ImportListDefinition{ ShouldMonitor = ImportListMonitorType.SpecificAlbum });
Mocker.GetMock<IFetchAndParseImportList>() Mocker.GetMock<IFetchAndParseImportList>()
.Setup(v => v.Fetch()) .Setup(v => v.Fetch())
@ -83,6 +83,13 @@ namespace NzbDrone.Core.Test.ImportListTests
}); });
} }
private void WithMonitorType(ImportListMonitorType monitor)
{
Mocker.GetMock<IImportListFactory>()
.Setup(v => v.Get(It.IsAny<int>()))
.Returns(new ImportListDefinition{ ShouldMonitor = monitor });
}
[Test] [Test]
public void should_search_if_artist_title_and_no_artist_id() public void should_search_if_artist_title_and_no_artist_id()
{ {
@ -152,17 +159,20 @@ namespace NzbDrone.Core.Test.ImportListTests
.Verify(v => v.AddArtists(It.Is<List<Artist>>(t=>t.Count == 0))); .Verify(v => v.AddArtists(It.Is<List<Artist>>(t=>t.Count == 0)));
} }
[Test] [TestCase(ImportListMonitorType.None, false)]
public void should_add_if_not_existing_artist() [TestCase(ImportListMonitorType.SpecificAlbum, true)]
[TestCase(ImportListMonitorType.EntireArtist, true)]
public void should_add_if_not_existing_artist(ImportListMonitorType monitor, bool expectedArtistMonitored)
{ {
WithArtistId(); WithArtistId();
WithAlbum(); WithAlbum();
WithAlbumId(); WithAlbumId();
WithMonitorType(monitor);
Subject.Execute(new ImportListSyncCommand()); Subject.Execute(new ImportListSyncCommand());
Mocker.GetMock<IAddArtistService>() Mocker.GetMock<IAddArtistService>()
.Verify(v => v.AddArtists(It.Is<List<Artist>>(t => t.Count == 1))); .Verify(v => v.AddArtists(It.Is<List<Artist>>(t => t.Count == 1 && t.First().Monitored == expectedArtistMonitored)));
} }
[Test] [Test]
@ -180,11 +190,12 @@ namespace NzbDrone.Core.Test.ImportListTests
} }
[Test] [Test]
public void should_mark_album_for_monitor_if_album_id() public void should_mark_album_for_monitor_if_album_id_and_specific_monitor_selected()
{ {
WithArtistId(); WithArtistId();
WithAlbum(); WithAlbum();
WithAlbumId(); WithAlbumId();
WithMonitorType(ImportListMonitorType.SpecificAlbum);
Subject.Execute(new ImportListSyncCommand()); Subject.Execute(new ImportListSyncCommand());
@ -192,6 +203,20 @@ namespace NzbDrone.Core.Test.ImportListTests
.Verify(v => v.AddArtists(It.Is<List<Artist>>(t => t.Count == 1 && t.First().AddOptions.AlbumsToMonitor.Contains("09474d62-17dd-3a4f-98fb-04c65f38a479")))); .Verify(v => v.AddArtists(It.Is<List<Artist>>(t => t.Count == 1 && t.First().AddOptions.AlbumsToMonitor.Contains("09474d62-17dd-3a4f-98fb-04c65f38a479"))));
} }
[Test]
public void should_not_mark_album_for_monitor_if_album_id_and_monitor_all_selected()
{
WithArtistId();
WithAlbum();
WithAlbumId();
WithMonitorType(ImportListMonitorType.EntireArtist);
Subject.Execute(new ImportListSyncCommand());
Mocker.GetMock<IAddArtistService>()
.Verify(v => v.AddArtists(It.Is<List<Artist>>(t => t.Count == 1 && !t.First().AddOptions.AlbumsToMonitor.Any())));
}
[Test] [Test]
public void should_not_mark_album_for_monitor_if_no_album_id() public void should_not_mark_album_for_monitor_if_no_album_id()
{ {
@ -202,6 +227,5 @@ namespace NzbDrone.Core.Test.ImportListTests
Mocker.GetMock<IAddArtistService>() Mocker.GetMock<IAddArtistService>()
.Verify(v => v.AddArtists(It.Is<List<Artist>>(t => t.Count == 1 && t.First().AddOptions.AlbumsToMonitor.Count == 0))); .Verify(v => v.AddArtists(It.Is<List<Artist>>(t => t.Count == 1 && t.First().AddOptions.AlbumsToMonitor.Count == 0)));
} }
} }
} }

@ -5,7 +5,7 @@ namespace NzbDrone.Core.ImportLists
public class ImportListDefinition : ProviderDefinition public class ImportListDefinition : ProviderDefinition
{ {
public bool EnableAutomaticAdd { get; set; } public bool EnableAutomaticAdd { get; set; }
public bool ShouldMonitor { get; set; } public ImportListMonitorType ShouldMonitor { get; set; }
public int ProfileId { get; set; } public int ProfileId { get; set; }
public int LanguageProfileId { get; set; } public int LanguageProfileId { get; set; }
public int MetadataProfileId { get; set; } public int MetadataProfileId { get; set; }
@ -15,4 +15,11 @@ namespace NzbDrone.Core.ImportLists
public ImportListStatus Status { get; set; } public ImportListStatus Status { get; set; }
} }
public enum ImportListMonitorType
{
None,
SpecificAlbum,
EntireArtist
}
} }

@ -130,13 +130,14 @@ namespace NzbDrone.Core.ImportLists
// Append Artist if not already in DB or already on add list // Append Artist if not already in DB or already on add list
if (existingArtist == null && excludedArtist == null && artistsToAdd.All(s => s.Metadata.Value.ForeignArtistId != report.ArtistMusicBrainzId)) if (existingArtist == null && excludedArtist == null && artistsToAdd.All(s => s.Metadata.Value.ForeignArtistId != report.ArtistMusicBrainzId))
{ {
var monitored = importList.ShouldMonitor != ImportListMonitorType.None;
artistsToAdd.Add(new Artist artistsToAdd.Add(new Artist
{ {
Metadata = new ArtistMetadata { Metadata = new ArtistMetadata {
ForeignArtistId = report.ArtistMusicBrainzId, ForeignArtistId = report.ArtistMusicBrainzId,
Name = report.Artist Name = report.Artist
}, },
Monitored = importList.ShouldMonitor, Monitored = monitored,
RootFolderPath = importList.RootFolderPath, RootFolderPath = importList.RootFolderPath,
QualityProfileId = importList.ProfileId, QualityProfileId = importList.ProfileId,
LanguageProfileId = importList.LanguageProfileId, LanguageProfileId = importList.LanguageProfileId,
@ -144,15 +145,15 @@ namespace NzbDrone.Core.ImportLists
Tags = importList.Tags, Tags = importList.Tags,
AlbumFolder = true, AlbumFolder = true,
AddOptions = new AddArtistOptions { AddOptions = new AddArtistOptions {
SearchForMissingAlbums = importList.ShouldMonitor, SearchForMissingAlbums = monitored,
Monitored = importList.ShouldMonitor, Monitored = monitored,
Monitor = importList.ShouldMonitor ? MonitorTypes.All : MonitorTypes.None Monitor = monitored ? MonitorTypes.All : MonitorTypes.None
} }
}); });
} }
// Add Album so we know what to monitor // Add Album so we know what to monitor
if (report.AlbumMusicBrainzId.IsNotNullOrWhiteSpace() && artistsToAdd.Any(s => s.Metadata.Value.ForeignArtistId == report.ArtistMusicBrainzId) && importList.ShouldMonitor) if (report.AlbumMusicBrainzId.IsNotNullOrWhiteSpace() && artistsToAdd.Any(s => s.Metadata.Value.ForeignArtistId == report.ArtistMusicBrainzId) && importList.ShouldMonitor == ImportListMonitorType.SpecificAlbum)
{ {
artistsToAdd.Find(s => s.Metadata.Value.ForeignArtistId == report.ArtistMusicBrainzId).AddOptions.AlbumsToMonitor.Add(report.AlbumMusicBrainzId); artistsToAdd.Find(s => s.Metadata.Value.ForeignArtistId == report.ArtistMusicBrainzId).AddOptions.AlbumsToMonitor.Add(report.AlbumMusicBrainzId);
} }

Loading…
Cancel
Save