From e6a43b2dc04a27a6565236a98d7007bd74ebaad0 Mon Sep 17 00:00:00 2001 From: Qstick Date: Fri, 20 Jul 2018 18:33:56 -0400 Subject: [PATCH] New: Added album disambiguation to UI and Naming [ex. Weezer (Blue Album)] (#431) --- frontend/src/Activity/History/HistoryRow.js | 1 + frontend/src/Activity/Queue/QueueRow.js | 1 + frontend/src/Album/AlbumTitleLink.js | 7 ++-- frontend/src/Album/Details/AlbumDetails.js | 4 ++- frontend/src/Artist/Details/AlbumRow.js | 5 ++- .../src/Artist/Index/Table/ArtistIndexRow.js | 2 ++ .../MediaManagement/Naming/NamingModal.js | 4 ++- .../src/Wanted/CutoffUnmet/CutoffUnmetRow.js | 3 ++ frontend/src/Wanted/Missing/MissingRow.js | 36 ++----------------- src/Lidarr.Api.V1/Albums/AlbumResource.cs | 3 ++ .../FileNameBuilderFixture.cs | 20 +++++++++++ .../Migration/018_album_disambiguation.cs | 14 ++++++++ .../SkyHook/Resource/AlbumResource.cs | 1 + .../MetadataSource/SkyHook/SkyHookProxy.cs | 1 + src/NzbDrone.Core/Music/Album.cs | 1 + .../Music/RefreshAlbumService.cs | 1 + src/NzbDrone.Core/NzbDrone.Core.csproj | 1 + .../Organizer/FileNameBuilder.cs | 6 ++++ .../Organizer/FileNameSampleService.cs | 1 + 19 files changed, 73 insertions(+), 39 deletions(-) create mode 100644 src/NzbDrone.Core/Datastore/Migration/018_album_disambiguation.cs diff --git a/frontend/src/Activity/History/HistoryRow.js b/frontend/src/Activity/History/HistoryRow.js index 715851b7e..5976d1da1 100644 --- a/frontend/src/Activity/History/HistoryRow.js +++ b/frontend/src/Activity/History/HistoryRow.js @@ -114,6 +114,7 @@ class HistoryRow extends Component { ); diff --git a/frontend/src/Activity/Queue/QueueRow.js b/frontend/src/Activity/Queue/QueueRow.js index 5d5e9dbd2..3dac22f33 100644 --- a/frontend/src/Activity/Queue/QueueRow.js +++ b/frontend/src/Activity/Queue/QueueRow.js @@ -158,6 +158,7 @@ class QueueRow extends Component { ); diff --git a/frontend/src/Album/AlbumTitleLink.js b/frontend/src/Album/AlbumTitleLink.js index 42945430b..8b4dfe212 100644 --- a/frontend/src/Album/AlbumTitleLink.js +++ b/frontend/src/Album/AlbumTitleLink.js @@ -2,19 +2,20 @@ import PropTypes from 'prop-types'; import React from 'react'; import Link from 'Components/Link/Link'; -function AlbumTitleLink({ foreignAlbumId, title }) { +function AlbumTitleLink({ foreignAlbumId, title, disambiguation }) { const link = `/album/${foreignAlbumId}`; return ( - {title} + {title}{disambiguation ? ` (${disambiguation})` : ''} ); } AlbumTitleLink.propTypes = { foreignAlbumId: PropTypes.string.isRequired, - title: PropTypes.string.isRequired + title: PropTypes.string.isRequired, + disambiguation: PropTypes.string }; export default AlbumTitleLink; diff --git a/frontend/src/Album/Details/AlbumDetails.js b/frontend/src/Album/Details/AlbumDetails.js index 2a62a2833..63e0f69a1 100644 --- a/frontend/src/Album/Details/AlbumDetails.js +++ b/frontend/src/Album/Details/AlbumDetails.js @@ -136,6 +136,7 @@ class AlbumDetails extends Component { const { id, title, + disambiguation, albumType, statistics, monitored, @@ -251,7 +252,7 @@ class AlbumDetails extends Component {
- {title} + {title}{disambiguation ? ` (${disambiguation})` : ''}
@@ -444,6 +445,7 @@ AlbumDetails.propTypes = { id: PropTypes.number.isRequired, foreignAlbumId: PropTypes.string.isRequired, title: PropTypes.string.isRequired, + disambiguation: PropTypes.string, albumType: PropTypes.string.isRequired, statistics: PropTypes.object.isRequired, releaseDate: PropTypes.string.isRequired, diff --git a/frontend/src/Artist/Details/AlbumRow.js b/frontend/src/Artist/Details/AlbumRow.js index c230d635a..e2d6cf65e 100644 --- a/frontend/src/Artist/Details/AlbumRow.js +++ b/frontend/src/Artist/Details/AlbumRow.js @@ -76,6 +76,7 @@ class AlbumRow extends Component { secondaryTypes, title, ratings, + disambiguation, isSaving, artistMonitored, foreignAlbumId, @@ -124,8 +125,9 @@ class AlbumRow extends Component { className={styles.title} > ); @@ -239,6 +241,7 @@ AlbumRow.propTypes = { duration: PropTypes.number.isRequired, title: PropTypes.string.isRequired, ratings: PropTypes.object.isRequired, + disambiguation: PropTypes.string, secondaryTypes: PropTypes.arrayOf(PropTypes.string).isRequired, foreignAlbumId: PropTypes.string.isRequired, isSaving: PropTypes.bool, diff --git a/frontend/src/Artist/Index/Table/ArtistIndexRow.js b/frontend/src/Artist/Index/Table/ArtistIndexRow.js index 79d923d5b..c1907693d 100644 --- a/frontend/src/Artist/Index/Table/ArtistIndexRow.js +++ b/frontend/src/Artist/Index/Table/ArtistIndexRow.js @@ -187,6 +187,7 @@ class ArtistIndexRow extends Component { > @@ -211,6 +212,7 @@ class ArtistIndexRow extends Component { > diff --git a/frontend/src/Settings/MediaManagement/Naming/NamingModal.js b/frontend/src/Settings/MediaManagement/Naming/NamingModal.js index 79a5b0a1e..21dcce3a5 100644 --- a/frontend/src/Settings/MediaManagement/Naming/NamingModal.js +++ b/frontend/src/Settings/MediaManagement/Naming/NamingModal.js @@ -134,7 +134,9 @@ class NamingModal extends Component { { token: '{Album CleanTitle}', example: 'Album Title' }, - { token: '{Album Type}', example: 'Album Type' } + { token: '{Album Type}', example: 'Album Type' }, + + { token: '{Album Disambiguation}', example: 'Disambiguation' } ]; const mediumTokens = [ diff --git a/frontend/src/Wanted/CutoffUnmet/CutoffUnmetRow.js b/frontend/src/Wanted/CutoffUnmet/CutoffUnmetRow.js index 9756da8ac..d29fc6232 100644 --- a/frontend/src/Wanted/CutoffUnmet/CutoffUnmetRow.js +++ b/frontend/src/Wanted/CutoffUnmet/CutoffUnmetRow.js @@ -21,6 +21,7 @@ function CutoffUnmetRow(props) { foreignAlbumId, albumType, title, + disambiguation, isSelected, columns, onSelectedChange @@ -62,6 +63,7 @@ function CutoffUnmetRow(props) { ); @@ -140,6 +142,7 @@ CutoffUnmetRow.propTypes = { foreignAlbumId: PropTypes.string.isRequired, albumType: PropTypes.string.isRequired, title: PropTypes.string.isRequired, + disambiguation: PropTypes.string, isSelected: PropTypes.bool, columns: PropTypes.arrayOf(PropTypes.object).isRequired, onSelectedChange: PropTypes.func.isRequired diff --git a/frontend/src/Wanted/Missing/MissingRow.js b/frontend/src/Wanted/Missing/MissingRow.js index 55dd23b99..f54a5c82b 100644 --- a/frontend/src/Wanted/Missing/MissingRow.js +++ b/frontend/src/Wanted/Missing/MissingRow.js @@ -20,6 +20,7 @@ function MissingRow(props) { albumType, foreignAlbumId, title, + disambiguation, isSelected, columns, onSelectedChange @@ -55,30 +56,13 @@ function MissingRow(props) { ); } - // if (name === 'episode') { - // return ( - // - // - // - // ); - // } - if (name === 'albumTitle') { return ( ); @@ -101,21 +85,6 @@ function MissingRow(props) { ); } - // if (name === 'status') { - // return ( - // - // - // - // ); - // } - if (name === 'actions') { return ( AlbumLabel { get; set; } public string ForeignAlbumId { get; set; } @@ -66,6 +67,7 @@ namespace Lidarr.Api.V1.Albums ReleaseDate = model.ReleaseDate, Genres = model.Genres, Title = model.Title, + Disambiguation = model.Disambiguation, Images = model.Images, Ratings = model.Ratings, Duration = model.Duration, @@ -87,6 +89,7 @@ namespace Lidarr.Api.V1.Albums Id = resource.Id, ForeignAlbumId = resource.ForeignAlbumId, Title = resource.Title, + Disambiguation = resource.Disambiguation, Images = resource.Images, Monitored = resource.Monitored, CurrentRelease = resource.CurrentRelease diff --git a/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/FileNameBuilderFixture.cs b/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/FileNameBuilderFixture.cs index e4b982f1d..8b2cf3243 100644 --- a/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/FileNameBuilderFixture.cs +++ b/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/FileNameBuilderFixture.cs @@ -33,6 +33,8 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests _album = Builder .CreateNew() .With(s => s.Title = "Hybrid Theory") + .With(s => s.AlbumType = "Album") + .With(s => s.Disambiguation = "The Best Album") .Build(); @@ -147,6 +149,24 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests .Should().Be("Hybrid Theory"); } + [Test] + public void should_replace_Album_Type() + { + _namingConfig.StandardTrackFormat = "{Album Type}"; + + Subject.BuildTrackFileName(new List { _track1 }, _artist, _album, _trackFile) + .Should().Be("Album"); + } + + [Test] + public void should_replace_Album_Disambiguation() + { + _namingConfig.StandardTrackFormat = "{Album Disambiguation}"; + + Subject.BuildTrackFileName(new List { _track1 }, _artist, _album, _trackFile) + .Should().Be("The Best Album"); + } + [Test] public void should_replace_Album_underscore_Title() { diff --git a/src/NzbDrone.Core/Datastore/Migration/018_album_disambiguation.cs b/src/NzbDrone.Core/Datastore/Migration/018_album_disambiguation.cs new file mode 100644 index 000000000..f862b207e --- /dev/null +++ b/src/NzbDrone.Core/Datastore/Migration/018_album_disambiguation.cs @@ -0,0 +1,14 @@ +using FluentMigrator; +using NzbDrone.Core.Datastore.Migration.Framework; + +namespace NzbDrone.Core.Datastore.Migration +{ + [Migration(18)] + public class album_disambiguation : NzbDroneMigrationBase + { + protected override void MainDbUpgrade() + { + Alter.Table("Albums").AddColumn("Disambiguation").AsString().Nullable(); + } + } +} diff --git a/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/AlbumResource.cs b/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/AlbumResource.cs index 3ef2e5670..5f80f29d8 100644 --- a/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/AlbumResource.cs +++ b/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/AlbumResource.cs @@ -19,6 +19,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook.Resource public DateTime ReleaseDate { get; set; } public List Images { get; set; } public string Title { get; set; } + public string Disambiguation { get; set; } public string Overview { get; set; } public List Genres { get; set; } public List Labels { get; set; } diff --git a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs index 08de85f10..2c39bdb3a 100644 --- a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs +++ b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs @@ -262,6 +262,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook { Album album = new Album(); album.Title = resource.Title; + album.Disambiguation = resource.Disambiguation; album.ForeignAlbumId = resource.Id; album.ReleaseDate = resource.ReleaseDate; album.CleanTitle = Parser.Parser.CleanArtistName(album.Title); diff --git a/src/NzbDrone.Core/Music/Album.cs b/src/NzbDrone.Core/Music/Album.cs index c01a452b1..789ff8173 100644 --- a/src/NzbDrone.Core/Music/Album.cs +++ b/src/NzbDrone.Core/Music/Album.cs @@ -22,6 +22,7 @@ namespace NzbDrone.Core.Music public string ForeignAlbumId { get; set; } public int ArtistId { get; set; } public string Title { get; set; } + public string Disambiguation { get; set; } public string CleanTitle { get; set; } public DateTime? ReleaseDate { get; set; } public List Label { get; set; } diff --git a/src/NzbDrone.Core/Music/RefreshAlbumService.cs b/src/NzbDrone.Core/Music/RefreshAlbumService.cs index 3f4456fd1..cc8f5fe54 100644 --- a/src/NzbDrone.Core/Music/RefreshAlbumService.cs +++ b/src/NzbDrone.Core/Music/RefreshAlbumService.cs @@ -92,6 +92,7 @@ namespace NzbDrone.Core.Music album.LastInfoSync = DateTime.UtcNow; album.CleanTitle = albumInfo.CleanTitle; album.Title = albumInfo.Title ?? "Unknown"; + album.Disambiguation = albumInfo.Disambiguation; album.AlbumType = albumInfo.AlbumType; album.SecondaryTypes = albumInfo.SecondaryTypes; album.Genres = albumInfo.Genres; diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index 3232e66a6..eb9124e12 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -189,6 +189,7 @@ + diff --git a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs index 9a0e68d85..5f84f4c00 100644 --- a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs +++ b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs @@ -269,6 +269,12 @@ namespace NzbDrone.Core.Organizer tokenHandlers["{Album CleanTitle}"] = m => CleanTitle(album.Title); tokenHandlers["{Album TitleThe}"] = m => TitleThe(album.Title); tokenHandlers["{Album Type}"] = m => album.AlbumType; + + if (album.Disambiguation != null) + { + tokenHandlers["{Album Disambiguation}"] = m => album.Disambiguation; + } + if (album.ReleaseDate.HasValue) { tokenHandlers["{Release Year}"] = m => album.ReleaseDate.Value.Year.ToString(); diff --git a/src/NzbDrone.Core/Organizer/FileNameSampleService.cs b/src/NzbDrone.Core/Organizer/FileNameSampleService.cs index f11d1785c..9f739e80b 100644 --- a/src/NzbDrone.Core/Organizer/FileNameSampleService.cs +++ b/src/NzbDrone.Core/Organizer/FileNameSampleService.cs @@ -38,6 +38,7 @@ namespace NzbDrone.Core.Organizer Title = "The Album Title", ReleaseDate = System.DateTime.Today, AlbumType = "Album", + Disambiguation = "The Best Album", Media = new List { new Medium