Music albums grouping and page

This commit is contained in:
advplyr 2023-01-02 18:02:04 -06:00
parent 9de7be1cb4
commit d6da161b13
11 changed files with 210 additions and 18 deletions

View file

@ -492,6 +492,32 @@ class LibraryController {
res.json(payload)
}
// api/libraries/:id/albums
async getAlbumsForLibrary(req, res) {
if (!req.library.isMusic) {
return res.status(400).send('Invalid library media type')
}
let libraryItems = this.db.libraryItems.filter(li => li.libraryId === req.library.id)
let albums = libraryHelpers.groupMusicLibraryItemsIntoAlbums(libraryItems)
albums = naturalSort(albums).asc(a => a.title) // Alphabetical by album title
const payload = {
results: [],
total: albums.length,
limit: req.query.limit && !isNaN(req.query.limit) ? Number(req.query.limit) : 0,
page: req.query.page && !isNaN(req.query.page) ? Number(req.query.page) : 0
}
if (payload.limit) {
const startIndex = payload.page * payload.limit
albums = albums.slice(startIndex, startIndex + payload.limit)
}
payload.results = albums
res.json(payload)
}
async getLibraryFilterData(req, res) {
res.json(libraryHelpers.getDistinctFilterDataNew(req.libraryItems))
}

View file

@ -29,6 +29,9 @@ class Library {
get isPodcast() {
return this.mediaType === 'podcast'
}
get isMusic() {
return this.mediaType === 'music'
}
construct(library) {
this.id = library.id

View file

@ -76,6 +76,7 @@ class ApiRouter {
this.router.get('/libraries/:id/series', LibraryController.middleware.bind(this), LibraryController.getAllSeriesForLibrary.bind(this))
this.router.get('/libraries/:id/collections', LibraryController.middleware.bind(this), LibraryController.getCollectionsForLibrary.bind(this))
this.router.get('/libraries/:id/playlists', LibraryController.middleware.bind(this), LibraryController.getUserPlaylistsForLibrary.bind(this))
this.router.get('/libraries/:id/albums', LibraryController.middleware.bind(this), LibraryController.getAlbumsForLibrary.bind(this))
this.router.get('/libraries/:id/personalized', LibraryController.middleware.bind(this), LibraryController.getLibraryUserPersonalizedOptimal.bind(this))
this.router.get('/libraries/:id/filterdata', LibraryController.middleware.bind(this), LibraryController.getLibraryFilterData.bind(this))
this.router.get('/libraries/:id/search', LibraryController.middleware.bind(this), LibraryController.search.bind(this))

View file

@ -1,4 +1,5 @@
const { sort, createNewSortInstance } = require('../libs/fastSort')
const Logger = require('../Logger')
const { getTitlePrefixAtEnd, isNullOrNaN, getTitleIgnorePrefix } = require('../utils/index')
const naturalSort = createNewSortInstance({
comparer: new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }).compare
@ -701,5 +702,34 @@ module.exports = {
return shelf
})
},
groupMusicLibraryItemsIntoAlbums(libraryItems) {
const albums = {}
libraryItems.forEach((li) => {
const albumTitle = li.media.metadata.album
const albumArtist = li.media.metadata.albumArtist
if (albumTitle && !albums[albumTitle]) {
albums[albumTitle] = {
title: albumTitle,
artist: albumArtist,
libraryItemId: li.media.coverPath ? li.id : null,
numTracks: 1
}
} else if (albumTitle && albums[albumTitle].artist === albumArtist) {
if (!albums[albumTitle].libraryItemId && li.media.coverPath) albums[albumTitle].libraryItemId = li.id
albums[albumTitle].numTracks++
} else {
if (albumTitle) {
Logger.warn(`Music track "${li.media.metadata.title}" with album "${albumTitle}" has a different album artist then another track in the same album. This track album artist is "${albumArtist}" but the album artist is already set to "${albums[albumTitle].artist}"`)
}
if (!albums['_none_']) albums['_none_'] = { title: 'No Album', artist: 'Various Artists', libraryItemId: null, numTracks: 0 }
albums['_none_'].numTracks++
}
})
return Object.values(albums)
}
}

View file

@ -361,12 +361,12 @@ function getDataFromMediaDir(libraryMediaType, folderPath, relPath, serverSettin
// Called from Scanner.js
async function getLibraryItemFileData(libraryMediaType, folder, libraryItemPath, isSingleMediaItem, serverSettings = {}) {
libraryItemPath = libraryItemPath.replace(/\\/g, '/')
var folderFullPath = folder.fullPath.replace(/\\/g, '/')
const folderFullPath = folder.fullPath.replace(/\\/g, '/')
var libraryItemDir = libraryItemPath.replace(folderFullPath, '').slice(1)
var libraryItemData = {}
const libraryItemDir = libraryItemPath.replace(folderFullPath, '').slice(1)
let libraryItemData = {}
var fileItems = []
let fileItems = []
if (isSingleMediaItem) { // Single media item in root of folder
fileItems = [
@ -388,8 +388,8 @@ async function getLibraryItemFileData(libraryMediaType, folder, libraryItemPath,
libraryItemData = getDataFromMediaDir(libraryMediaType, folderFullPath, libraryItemDir, serverSettings, fileNames)
}
var libraryItemDirStats = await getFileTimestampsWithIno(libraryItemData.path)
var libraryItem = {
const libraryItemDirStats = await getFileTimestampsWithIno(libraryItemData.path)
const libraryItem = {
ino: libraryItemDirStats.ino,
mtimeMs: libraryItemDirStats.mtimeMs || 0,
ctimeMs: libraryItemDirStats.ctimeMs || 0,