New: Added album disambiguation to UI and Naming [ex. Weezer (Blue Album)] (#431)

pull/447/head
Qstick 6 years ago committed by GitHub
parent 54d1d90e16
commit e6a43b2dc0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -114,6 +114,7 @@ class HistoryRow extends Component {
<AlbumTitleLink <AlbumTitleLink
foreignAlbumId={album.foreignAlbumId} foreignAlbumId={album.foreignAlbumId}
title={album.title} title={album.title}
disambiguation={album.disambiguation}
/> />
</TableRowCell> </TableRowCell>
); );

@ -158,6 +158,7 @@ class QueueRow extends Component {
<AlbumTitleLink <AlbumTitleLink
foreignAlbumId={album.foreignAlbumId} foreignAlbumId={album.foreignAlbumId}
title={album.title} title={album.title}
disambiguation={album.disambiguation}
/> />
</TableRowCell> </TableRowCell>
); );

@ -2,19 +2,20 @@ import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import Link from 'Components/Link/Link'; import Link from 'Components/Link/Link';
function AlbumTitleLink({ foreignAlbumId, title }) { function AlbumTitleLink({ foreignAlbumId, title, disambiguation }) {
const link = `/album/${foreignAlbumId}`; const link = `/album/${foreignAlbumId}`;
return ( return (
<Link to={link}> <Link to={link}>
{title} {title}{disambiguation ? ` (${disambiguation})` : ''}
</Link> </Link>
); );
} }
AlbumTitleLink.propTypes = { AlbumTitleLink.propTypes = {
foreignAlbumId: PropTypes.string.isRequired, foreignAlbumId: PropTypes.string.isRequired,
title: PropTypes.string.isRequired title: PropTypes.string.isRequired,
disambiguation: PropTypes.string
}; };
export default AlbumTitleLink; export default AlbumTitleLink;

@ -136,6 +136,7 @@ class AlbumDetails extends Component {
const { const {
id, id,
title, title,
disambiguation,
albumType, albumType,
statistics, statistics,
monitored, monitored,
@ -251,7 +252,7 @@ class AlbumDetails extends Component {
<div className={styles.info}> <div className={styles.info}>
<div className={styles.titleContainer}> <div className={styles.titleContainer}>
<div className={styles.title}> <div className={styles.title}>
{title} {title}{disambiguation ? ` (${disambiguation})` : ''}
</div> </div>
<div className={styles.artistNavigationButtons}> <div className={styles.artistNavigationButtons}>
@ -444,6 +445,7 @@ AlbumDetails.propTypes = {
id: PropTypes.number.isRequired, id: PropTypes.number.isRequired,
foreignAlbumId: PropTypes.string.isRequired, foreignAlbumId: PropTypes.string.isRequired,
title: PropTypes.string.isRequired, title: PropTypes.string.isRequired,
disambiguation: PropTypes.string,
albumType: PropTypes.string.isRequired, albumType: PropTypes.string.isRequired,
statistics: PropTypes.object.isRequired, statistics: PropTypes.object.isRequired,
releaseDate: PropTypes.string.isRequired, releaseDate: PropTypes.string.isRequired,

@ -76,6 +76,7 @@ class AlbumRow extends Component {
secondaryTypes, secondaryTypes,
title, title,
ratings, ratings,
disambiguation,
isSaving, isSaving,
artistMonitored, artistMonitored,
foreignAlbumId, foreignAlbumId,
@ -124,8 +125,9 @@ class AlbumRow extends Component {
className={styles.title} className={styles.title}
> >
<AlbumTitleLink <AlbumTitleLink
title={title}
foreignAlbumId={foreignAlbumId} foreignAlbumId={foreignAlbumId}
title={title}
disambiguation={disambiguation}
/> />
</TableRowCell> </TableRowCell>
); );
@ -239,6 +241,7 @@ AlbumRow.propTypes = {
duration: PropTypes.number.isRequired, duration: PropTypes.number.isRequired,
title: PropTypes.string.isRequired, title: PropTypes.string.isRequired,
ratings: PropTypes.object.isRequired, ratings: PropTypes.object.isRequired,
disambiguation: PropTypes.string,
secondaryTypes: PropTypes.arrayOf(PropTypes.string).isRequired, secondaryTypes: PropTypes.arrayOf(PropTypes.string).isRequired,
foreignAlbumId: PropTypes.string.isRequired, foreignAlbumId: PropTypes.string.isRequired,
isSaving: PropTypes.bool, isSaving: PropTypes.bool,

@ -187,6 +187,7 @@ class ArtistIndexRow extends Component {
> >
<AlbumTitleLink <AlbumTitleLink
title={nextAlbum.title} title={nextAlbum.title}
disambiguation={nextAlbum.disambiguation}
foreignAlbumId={nextAlbum.foreignAlbumId} foreignAlbumId={nextAlbum.foreignAlbumId}
/> />
</VirtualTableRowCell> </VirtualTableRowCell>
@ -211,6 +212,7 @@ class ArtistIndexRow extends Component {
> >
<AlbumTitleLink <AlbumTitleLink
title={lastAlbum.title} title={lastAlbum.title}
disambiguation={lastAlbum.disambiguation}
foreignAlbumId={lastAlbum.foreignAlbumId} foreignAlbumId={lastAlbum.foreignAlbumId}
/> />
</VirtualTableRowCell> </VirtualTableRowCell>

@ -134,7 +134,9 @@ class NamingModal extends Component {
{ token: '{Album CleanTitle}', example: 'Album Title' }, { 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 = [ const mediumTokens = [

@ -21,6 +21,7 @@ function CutoffUnmetRow(props) {
foreignAlbumId, foreignAlbumId,
albumType, albumType,
title, title,
disambiguation,
isSelected, isSelected,
columns, columns,
onSelectedChange onSelectedChange
@ -62,6 +63,7 @@ function CutoffUnmetRow(props) {
<AlbumTitleLink <AlbumTitleLink
foreignAlbumId={foreignAlbumId} foreignAlbumId={foreignAlbumId}
title={title} title={title}
disambiguation={disambiguation}
/> />
</TableRowCell> </TableRowCell>
); );
@ -140,6 +142,7 @@ CutoffUnmetRow.propTypes = {
foreignAlbumId: PropTypes.string.isRequired, foreignAlbumId: PropTypes.string.isRequired,
albumType: PropTypes.string.isRequired, albumType: PropTypes.string.isRequired,
title: PropTypes.string.isRequired, title: PropTypes.string.isRequired,
disambiguation: PropTypes.string,
isSelected: PropTypes.bool, isSelected: PropTypes.bool,
columns: PropTypes.arrayOf(PropTypes.object).isRequired, columns: PropTypes.arrayOf(PropTypes.object).isRequired,
onSelectedChange: PropTypes.func.isRequired onSelectedChange: PropTypes.func.isRequired

@ -20,6 +20,7 @@ function MissingRow(props) {
albumType, albumType,
foreignAlbumId, foreignAlbumId,
title, title,
disambiguation,
isSelected, isSelected,
columns, columns,
onSelectedChange onSelectedChange
@ -55,30 +56,13 @@ function MissingRow(props) {
); );
} }
// if (name === 'episode') {
// return (
// <TableRowCell
// key={name}
// className={styles.episode}
// >
// <SeasonEpisodeNumber
// seasonNumber={seasonNumber}
// episodeNumber={episodeNumber}
// absoluteEpisodeNumber={absoluteEpisodeNumber}
// sceneSeasonNumber={sceneSeasonNumber}
// sceneEpisodeNumber={sceneEpisodeNumber}
// sceneAbsoluteEpisodeNumber={sceneAbsoluteEpisodeNumber}
// />
// </TableRowCell>
// );
// }
if (name === 'albumTitle') { if (name === 'albumTitle') {
return ( return (
<TableRowCell key={name}> <TableRowCell key={name}>
<AlbumTitleLink <AlbumTitleLink
foreignAlbumId={foreignAlbumId} foreignAlbumId={foreignAlbumId}
title={title} title={title}
disambiguation={disambiguation}
/> />
</TableRowCell> </TableRowCell>
); );
@ -101,21 +85,6 @@ function MissingRow(props) {
); );
} }
// if (name === 'status') {
// return (
// <TableRowCell
// key={name}
// className={styles.status}
// >
// <EpisodeStatusConnector
// albumId={id}
// trackFileId={trackFileId}
// albumEntity={albumEntities.WANTED_MISSING}
// />
// </TableRowCell>
// );
// }
if (name === 'actions') { if (name === 'actions') {
return ( return (
<AlbumSearchCellConnector <AlbumSearchCellConnector
@ -144,6 +113,7 @@ MissingRow.propTypes = {
foreignAlbumId: PropTypes.string.isRequired, foreignAlbumId: PropTypes.string.isRequired,
albumType: PropTypes.string.isRequired, albumType: PropTypes.string.isRequired,
title: PropTypes.string.isRequired, title: PropTypes.string.isRequired,
disambiguation: PropTypes.string,
isSelected: PropTypes.bool, isSelected: PropTypes.bool,
columns: PropTypes.arrayOf(PropTypes.object).isRequired, columns: PropTypes.arrayOf(PropTypes.object).isRequired,
onSelectedChange: PropTypes.func.isRequired onSelectedChange: PropTypes.func.isRequired

@ -12,6 +12,7 @@ namespace Lidarr.Api.V1.Albums
public class AlbumResource : RestResource public class AlbumResource : RestResource
{ {
public string Title { get; set; } public string Title { get; set; }
public string Disambiguation { get; set; }
public int ArtistId { get; set; } public int ArtistId { get; set; }
public List<string> AlbumLabel { get; set; } public List<string> AlbumLabel { get; set; }
public string ForeignAlbumId { get; set; } public string ForeignAlbumId { get; set; }
@ -66,6 +67,7 @@ namespace Lidarr.Api.V1.Albums
ReleaseDate = model.ReleaseDate, ReleaseDate = model.ReleaseDate,
Genres = model.Genres, Genres = model.Genres,
Title = model.Title, Title = model.Title,
Disambiguation = model.Disambiguation,
Images = model.Images, Images = model.Images,
Ratings = model.Ratings, Ratings = model.Ratings,
Duration = model.Duration, Duration = model.Duration,
@ -87,6 +89,7 @@ namespace Lidarr.Api.V1.Albums
Id = resource.Id, Id = resource.Id,
ForeignAlbumId = resource.ForeignAlbumId, ForeignAlbumId = resource.ForeignAlbumId,
Title = resource.Title, Title = resource.Title,
Disambiguation = resource.Disambiguation,
Images = resource.Images, Images = resource.Images,
Monitored = resource.Monitored, Monitored = resource.Monitored,
CurrentRelease = resource.CurrentRelease CurrentRelease = resource.CurrentRelease

@ -33,6 +33,8 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
_album = Builder<Album> _album = Builder<Album>
.CreateNew() .CreateNew()
.With(s => s.Title = "Hybrid Theory") .With(s => s.Title = "Hybrid Theory")
.With(s => s.AlbumType = "Album")
.With(s => s.Disambiguation = "The Best Album")
.Build(); .Build();
@ -147,6 +149,24 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
.Should().Be("Hybrid Theory"); .Should().Be("Hybrid Theory");
} }
[Test]
public void should_replace_Album_Type()
{
_namingConfig.StandardTrackFormat = "{Album Type}";
Subject.BuildTrackFileName(new List<Track> { _track1 }, _artist, _album, _trackFile)
.Should().Be("Album");
}
[Test]
public void should_replace_Album_Disambiguation()
{
_namingConfig.StandardTrackFormat = "{Album Disambiguation}";
Subject.BuildTrackFileName(new List<Track> { _track1 }, _artist, _album, _trackFile)
.Should().Be("The Best Album");
}
[Test] [Test]
public void should_replace_Album_underscore_Title() public void should_replace_Album_underscore_Title()
{ {

@ -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();
}
}
}

@ -19,6 +19,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
public DateTime ReleaseDate { get; set; } public DateTime ReleaseDate { get; set; }
public List<ImageResource> Images { get; set; } public List<ImageResource> Images { get; set; }
public string Title { get; set; } public string Title { get; set; }
public string Disambiguation { get; set; }
public string Overview { get; set; } public string Overview { get; set; }
public List<string> Genres { get; set; } public List<string> Genres { get; set; }
public List<string> Labels { get; set; } public List<string> Labels { get; set; }

@ -262,6 +262,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
{ {
Album album = new Album(); Album album = new Album();
album.Title = resource.Title; album.Title = resource.Title;
album.Disambiguation = resource.Disambiguation;
album.ForeignAlbumId = resource.Id; album.ForeignAlbumId = resource.Id;
album.ReleaseDate = resource.ReleaseDate; album.ReleaseDate = resource.ReleaseDate;
album.CleanTitle = Parser.Parser.CleanArtistName(album.Title); album.CleanTitle = Parser.Parser.CleanArtistName(album.Title);

@ -22,6 +22,7 @@ namespace NzbDrone.Core.Music
public string ForeignAlbumId { get; set; } public string ForeignAlbumId { get; set; }
public int ArtistId { get; set; } public int ArtistId { get; set; }
public string Title { get; set; } public string Title { get; set; }
public string Disambiguation { get; set; }
public string CleanTitle { get; set; } public string CleanTitle { get; set; }
public DateTime? ReleaseDate { get; set; } public DateTime? ReleaseDate { get; set; }
public List<string> Label { get; set; } public List<string> Label { get; set; }

@ -92,6 +92,7 @@ namespace NzbDrone.Core.Music
album.LastInfoSync = DateTime.UtcNow; album.LastInfoSync = DateTime.UtcNow;
album.CleanTitle = albumInfo.CleanTitle; album.CleanTitle = albumInfo.CleanTitle;
album.Title = albumInfo.Title ?? "Unknown"; album.Title = albumInfo.Title ?? "Unknown";
album.Disambiguation = albumInfo.Disambiguation;
album.AlbumType = albumInfo.AlbumType; album.AlbumType = albumInfo.AlbumType;
album.SecondaryTypes = albumInfo.SecondaryTypes; album.SecondaryTypes = albumInfo.SecondaryTypes;
album.Genres = albumInfo.Genres; album.Genres = albumInfo.Genres;

@ -189,6 +189,7 @@
<Compile Include="Datastore\Migration\015_remove_fanzub.cs" /> <Compile Include="Datastore\Migration\015_remove_fanzub.cs" />
<Compile Include="Datastore\Migration\016_update_artist_history_indexes.cs" /> <Compile Include="Datastore\Migration\016_update_artist_history_indexes.cs" />
<Compile Include="Datastore\Migration\017_remove_nma.cs" /> <Compile Include="Datastore\Migration\017_remove_nma.cs" />
<Compile Include="Datastore\Migration\018_album_disambiguation.cs" />
<Compile Include="Datastore\Migration\Framework\MigrationContext.cs" /> <Compile Include="Datastore\Migration\Framework\MigrationContext.cs" />
<Compile Include="Datastore\Migration\Framework\MigrationController.cs" /> <Compile Include="Datastore\Migration\Framework\MigrationController.cs" />
<Compile Include="Datastore\Migration\Framework\MigrationDbFactory.cs" /> <Compile Include="Datastore\Migration\Framework\MigrationDbFactory.cs" />

@ -269,6 +269,12 @@ namespace NzbDrone.Core.Organizer
tokenHandlers["{Album CleanTitle}"] = m => CleanTitle(album.Title); tokenHandlers["{Album CleanTitle}"] = m => CleanTitle(album.Title);
tokenHandlers["{Album TitleThe}"] = m => TitleThe(album.Title); tokenHandlers["{Album TitleThe}"] = m => TitleThe(album.Title);
tokenHandlers["{Album Type}"] = m => album.AlbumType; tokenHandlers["{Album Type}"] = m => album.AlbumType;
if (album.Disambiguation != null)
{
tokenHandlers["{Album Disambiguation}"] = m => album.Disambiguation;
}
if (album.ReleaseDate.HasValue) if (album.ReleaseDate.HasValue)
{ {
tokenHandlers["{Release Year}"] = m => album.ReleaseDate.Value.Year.ToString(); tokenHandlers["{Release Year}"] = m => album.ReleaseDate.Value.Year.ToString();

@ -38,6 +38,7 @@ namespace NzbDrone.Core.Organizer
Title = "The Album Title", Title = "The Album Title",
ReleaseDate = System.DateTime.Today, ReleaseDate = System.DateTime.Today,
AlbumType = "Album", AlbumType = "Album",
Disambiguation = "The Best Album",
Media = new List<Medium> Media = new List<Medium>
{ {
new Medium new Medium

Loading…
Cancel
Save