Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate albums by MusicBrainz Album ID #2538

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
01260ef
Update mapping.go
certuna Sep 25, 2023
87f737f
Update mediafile_repository.go
certuna Sep 25, 2023
2989f7a
Update playlist_track_repository.go
certuna Sep 26, 2023
f1cd684
Update album.go
certuna Sep 26, 2023
977a388
Update SongDatagrid.js
certuna Sep 26, 2023
f277dc2
Update PlayButton.js
certuna Sep 26, 2023
575e55c
Update ContextMenus.js
certuna Sep 26, 2023
57c02ee
Update AlbumSongs.js
certuna Sep 26, 2023
8226931
Merge branch 'navidrome:master' into mbzAlbumID
certuna Oct 20, 2023
c3a6229
Update mapping.go
certuna Nov 1, 2023
755edf1
Update mapping.go
certuna Nov 1, 2023
e1b770c
Update mapping.go
certuna Nov 1, 2023
efabf33
Update mapping.go
certuna Nov 1, 2023
6ab58f1
Merge branch 'navidrome:master' into mbzAlbumID
certuna Nov 1, 2023
d2bdb37
Update mapping.go
certuna Nov 1, 2023
57183ef
make albumID() a generic function
certuna Nov 5, 2023
36a5ad2
Update mapping.go
certuna Nov 5, 2023
2e95c68
Update mapping.go
certuna Nov 5, 2023
ca906d4
Merge branch 'navidrome:master' into mbzAlbumID
certuna Nov 9, 2023
02c9287
Merge branch 'navidrome:master' into mbzAlbumID
certuna Nov 12, 2023
67c57b2
Merge branch 'navidrome:master' into mbzAlbumID
certuna Nov 16, 2023
27e1413
Merge branch 'navidrome:master' into mbzAlbumID
certuna Nov 22, 2023
9cdde9d
fix reversion
certuna Nov 23, 2023
d430f1a
Merge branch 'navidrome:master' into mbzAlbumID
certuna Nov 27, 2023
cff274a
Merge branch 'navidrome:master' into mbzAlbumID
certuna Dec 3, 2023
6789d86
Merge branch 'navidrome:master' into mbzAlbumID
certuna Dec 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions model/album.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ func (a Album) CoverArtID() ArtworkID {
type DiscID struct {
AlbumID string `json:"albumId"`
ReleaseDate string `json:"releaseDate"`
MbzAlbumID string `json:"mbzAlbumID"`
DiscNumber int `json:"discNumber"`
}

Expand Down
4 changes: 2 additions & 2 deletions persistence/mediafile_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ func NewMediaFileRepository(ctx context.Context, o orm.QueryExecutor) *mediaFile
r.ormer = o
r.tableName = "media_file"
r.sortMappings = map[string]string{
"artist": "order_artist_name asc, order_album_name asc, release_date asc, disc_number asc, track_number asc",
"album": "order_album_name asc, release_date asc, disc_number asc, track_number asc, order_artist_name asc, title asc",
"artist": "order_artist_name asc, order_album_name asc, release_date asc, mbz_album_id asc, disc_number asc, track_number asc",
"album": "order_album_name asc, release_date asc, mbz_album_id asc, disc_number asc, track_number asc, order_artist_name asc, title asc",
"random": "RANDOM()",
}
r.filterMappings = map[string]filterFunc{
Expand Down
4 changes: 2 additions & 2 deletions persistence/playlist_track_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func (r *playlistTrackRepository) Add(mediaFileIds []string) (int, error) {
}

func (r *playlistTrackRepository) addMediaFileIds(cond Sqlizer) (int, error) {
sq := Select("id").From("media_file").Where(cond).OrderBy("album_artist, album, release_date, disc_number, track_number")
sq := Select("id").From("media_file").Where(cond).OrderBy("album_artist, album, release_date, mbz_album_id, disc_number, track_number")
var ids []string
err := r.queryAll(sq, &ids)
if err != nil {
Expand All @@ -147,7 +147,7 @@ func (r *playlistTrackRepository) AddDiscs(discs []model.DiscID) (int, error) {
}
var clauses Or
for _, d := range discs {
clauses = append(clauses, And{Eq{"album_id": d.AlbumID}, Eq{"release_date": d.ReleaseDate}, Eq{"disc_number": d.DiscNumber}})
clauses = append(clauses, And{Eq{"album_id": d.AlbumID}, Eq{"release_date": d.ReleaseDate}, Eq{"mbz_album_id": d.MbzAlbumID}, Eq{"disc_number": d.DiscNumber}})
}
return r.addMediaFileIds(clauses)
}
Expand Down
19 changes: 11 additions & 8 deletions scanner/mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ func (s mediaFileMapper) toMediaFile(md metadata.Tags) model.MediaFile {
mf.ID = s.trackID(md)
mf.Year, mf.Date, mf.OriginalYear, mf.OriginalDate, mf.ReleaseYear, mf.ReleaseDate = s.mapDates(md)
mf.Title = s.mapTrackTitle(md)
mf.Album = md.Album()
mf.AlbumID = s.albumID(md, mf.ReleaseDate)
mf.Album = s.mapAlbumName(md)
mf.ArtistID = s.artistID(md)
mf.Artist = s.mapArtistName(md)
Expand Down Expand Up @@ -77,6 +75,11 @@ func (s mediaFileMapper) toMediaFile(md metadata.Tags) model.MediaFile {
mf.Bpm = md.Bpm()
mf.CreatedAt = md.BirthTime()
mf.UpdatedAt = md.ModificationTime()
if conf.Server.Scanner.GroupAlbumReleases {
mf.AlbumID = s.albumID(mf.Album, mf.AlbumArtistID)
} else {
mf.AlbumID = s.albumID(mf.Album, mf.AlbumArtistID, mf.MbzAlbumID, mf.ReleaseDate)
}

return *mf
}
Expand Down Expand Up @@ -127,14 +130,14 @@ func (s mediaFileMapper) trackID(md metadata.Tags) string {
return fmt.Sprintf("%x", md5.Sum([]byte(md.FilePath())))
}

func (s mediaFileMapper) albumID(md metadata.Tags, releaseDate string) string {
albumPath := strings.ToLower(fmt.Sprintf("%s\\%s", s.mapAlbumArtistName(md), s.mapAlbumName(md)))
if !conf.Server.Scanner.GroupAlbumReleases {
if len(releaseDate) != 0 {
albumPath = fmt.Sprintf("%s\\%s", albumPath, releaseDate)
func (s mediaFileMapper) albumID(values ...string) string {
var albumPath = strings.Builder{}
for _, value := range values {
if value != "" {
fmt.Fprintf(&albumPath, "\\%s", value)
}
}
return fmt.Sprintf("%x", md5.Sum([]byte(albumPath)))
return fmt.Sprintf("%x", md5.Sum([]byte(albumPath.String())))
}

func (s mediaFileMapper) artistID(md metadata.Tags) string {
Expand Down
2 changes: 1 addition & 1 deletion ui/src/album/AlbumSongs.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ const AlbumSongs = (props) => {
trackNumber: isDesktop && (
<TextField
source="trackNumber"
sortBy="releaseDate asc, discNumber asc, trackNumber asc"
sortBy="releaseDate asc, mbzAlbumId asc, discNumber asc, trackNumber asc"
label="#"
sortable={false}
/>
Expand Down
8 changes: 6 additions & 2 deletions ui/src/common/ContextMenus.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,10 +200,14 @@ export const AlbumContextMenu = (props) =>
resource={'album'}
songQueryParams={{
pagination: { page: 1, perPage: -1 },
sort: { field: 'releaseDate, discNumber, trackNumber', order: 'ASC' },
sort: {
field: 'releaseDate, mbzAlbumId, discNumber, trackNumber',
order: 'ASC',
},
filter: {
album_id: props.record.id,
release_date: props.releaseDate,
mbz_album_id: props.mbzAlbumId,
disc_number: props.discNumber,
},
}}
Expand Down Expand Up @@ -231,7 +235,7 @@ export const ArtistContextMenu = (props) =>
songQueryParams={{
pagination: { page: 1, perPage: 200 },
sort: {
field: 'album, releaseDate, discNumber, trackNumber',
field: 'album, releaseDate, mbzAlbumId, discNumber, trackNumber',
order: 'ASC',
},
filter: { album_artist_id: props.record.id },
Expand Down
6 changes: 5 additions & 1 deletion ui/src/common/PlayButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,14 @@ export const PlayButton = ({ record, size, className }) => {
dataProvider
.getList('song', {
pagination: { page: 1, perPage: -1 },
sort: { field: 'releaseDate, discNumber, trackNumber', order: 'ASC' },
sort: {
field: 'releaseDate, mbzAlbumId, discNumber, trackNumber',
order: 'ASC',
},
filter: {
album_id: record.id,
release_date: record.releaseDate,
mbz_album_id: record.mbzAlbumId,
disc_number: record.discNumber,
},
})
Expand Down
49 changes: 33 additions & 16 deletions ui/src/common/SongDatagrid.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,36 +60,40 @@ const ReleaseRow = forwardRef(
const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))
const classes = useStyles({ isDesktop })
const translate = useTranslate()
const handlePlaySubset = (releaseDate) => () => {
onClick(releaseDate)
const handlePlaySubset = (releaseDate, mbzAlbumId) => () => {
onClick(releaseDate, mbzAlbumId)
}

let releaseTitle = []

if (record.releaseDate) {
releaseTitle.push(translate('resources.album.fields.released'))
releaseTitle.push(formatFullDate(record.releaseDate))
if (record.catalogNum && isDesktop) {
releaseTitle.push('· Cat #')
releaseTitle.push(record.catalogNum)
}
releaseTitle.push(
translate('resources.album.fields.released') +
' ' +
formatFullDate(record.releaseDate)
)
}
if (record.catalogNum && isDesktop) {
releaseTitle.push('Cat # ' + record.catalogNum)
}

return (
<TableRow
hover
ref={ref}
onClick={handlePlaySubset(record.releaseDate)}
onClick={handlePlaySubset(record.releaseDate, record.mbzAlbumId)}
className={classes.row}
>
<TableCell colSpan={colSpan}>
<Typography variant="h6" className={classes.subtitle}>
{releaseTitle.join(' ')}
{releaseTitle.join(' · ')}
</Typography>
</TableCell>
<TableCell>
<AlbumContextMenu
record={{ id: record.albumId }}
releaseDate={record.releaseDate}
mbzAlbumId={record.mbzAlbumId}
showLove={false}
className={classes.contextMenu}
visible={contextAlwaysVisible}
Expand All @@ -104,8 +108,8 @@ const DiscSubtitleRow = forwardRef(
({ record, onClick, colSpan, contextAlwaysVisible }, ref) => {
const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))
const classes = useStyles({ isDesktop })
const handlePlaySubset = (releaseDate, discNumber) => () => {
onClick(releaseDate, discNumber)
const handlePlaySubset = (releaseDate, mbzAlbumId, discNumber) => () => {
onClick(releaseDate, mbzAlbumId, discNumber)
}

let subtitle = []
Expand All @@ -120,7 +124,11 @@ const DiscSubtitleRow = forwardRef(
<TableRow
hover
ref={ref}
onClick={handlePlaySubset(record.releaseDate, record.discNumber)}
onClick={handlePlaySubset(
record.releaseDate,
record.mbzAlbumId,
record.discNumber
)}
className={classes.row}
>
<TableCell colSpan={colSpan}>
Expand All @@ -134,6 +142,7 @@ const DiscSubtitleRow = forwardRef(
record={{ id: record.albumId }}
discNumber={record.discNumber}
releaseDate={record.releaseDate}
mbzAlbumId={record.mbzAlbumId}
showLove={false}
className={classes.contextMenu}
visible={contextAlwaysVisible}
Expand Down Expand Up @@ -167,6 +176,7 @@ export const SongDatagridRow = ({
{
albumId: record?.albumId,
releaseDate: record?.releaseDate,
mbzAlbumId: record?.mbzAlbumId,
discNumber: record?.discNumber,
},
],
Expand Down Expand Up @@ -245,16 +255,21 @@ const SongDatagridBody = ({
const { ids, data } = rest

const playSubset = useCallback(
(releaseDate, discNumber) => {
(releaseDate, mbzAlbumId, discNumber) => {
let idsToPlay = []
if (discNumber !== undefined) {
idsToPlay = ids.filter(
(id) =>
data[id].releaseDate === releaseDate &&
data[id].mbzAlbumId === mbzAlbumId &&
data[id].discNumber === discNumber
)
} else {
idsToPlay = ids.filter((id) => data[id].releaseDate === releaseDate)
idsToPlay = ids.filter(
(id) =>
(releaseDate && data[id].releaseDate === releaseDate) ||
(mbzAlbumId && data[id].mbzAlbumId === mbzAlbumId)
)
}
dispatch(playTracks(data, idsToPlay))
},
Expand All @@ -275,6 +290,7 @@ const SongDatagridBody = ({
if (
acc.length === 0 ||
(last && data[id].discNumber !== data[last].discNumber) ||
(last && data[id].mbzAlbumId !== data[last].mbzAlbumId) ||
(last && data[id].releaseDate !== data[last].releaseDate)
) {
acc.push(id)
Expand All @@ -299,7 +315,8 @@ const SongDatagridBody = ({
const last = acc && acc[acc.length - 1]
if (
acc.length === 0 ||
(last && data[id].releaseDate !== data[last].releaseDate)
(last && data[id].releaseDate !== data[last].releaseDate) ||
(last && data[id].mbzAlbumId !== data[last].mbzAlbumId)
) {
acc.push(id)
}
Expand Down