diff --git a/src/routes/subsonic.js b/src/routes/subsonic.js index 113aabe..15d2747 100644 --- a/src/routes/subsonic.js +++ b/src/routes/subsonic.js @@ -383,6 +383,132 @@ router.get('/getAlbum.view', authenticateSubsonic, async (req, res) => { } }); +// Get album list +router.get('/getAlbumList.view', authenticateSubsonic, async (req, res) => { + try { + const { type, size, offset } = req.query; + const limit = parseInt(size) || 500; + const skip = parseInt(offset) || 0; + + let orderBy = 'year DESC, album'; + + switch(type) { + case 'random': + orderBy = 'RANDOM()'; + break; + case 'newest': + orderBy = 'created_at DESC'; + break; + case 'frequent': + case 'recent': + orderBy = 'album'; + break; + case 'alphabeticalByName': + orderBy = 'album'; + break; + case 'alphabeticalByArtist': + orderBy = 'album_artist, album'; + break; + } + + const albums = await all(` + SELECT DISTINCT album, album_artist, year, + (SELECT artwork_path FROM tracks t2 WHERE t2.album = tracks.album LIMIT 1) as artwork_path, + COUNT(*) as track_count + FROM tracks + WHERE is_single = 0 + GROUP BY album, album_artist + ORDER BY ${orderBy} + LIMIT ? OFFSET ? + `, [limit, skip]); + + let albumListXml = '\n'; + + albums.forEach(album => { + const albumId = crypto.createHash('md5').update(`album-${album.album}-${album.album_artist}`).digest('hex'); + const artistId = crypto.createHash('md5').update(`artist-${album.album_artist}`).digest('hex'); + const coverArt = album.artwork_path ? albumId : ''; + + albumListXml += ` \n`; + }); + + albumListXml += ''; + + sendSubsonicResponse(res, albumListXml); + } catch (error) { + console.error('Error in getAlbumList:', error); + sendSubsonicError(res, 0, error.message); + } +}); + +// Get album list 2 (ID3) +router.get('/getAlbumList2.view', authenticateSubsonic, async (req, res) => { + try { + const { type, size, offset } = req.query; + const limit = parseInt(size) || 500; + const skip = parseInt(offset) || 0; + + let orderBy = 'year DESC, album'; + + switch(type) { + case 'random': + orderBy = 'RANDOM()'; + break; + case 'newest': + orderBy = 'created_at DESC'; + break; + case 'alphabeticalByName': + orderBy = 'album'; + break; + case 'alphabeticalByArtist': + orderBy = 'album_artist, album'; + break; + } + + const albums = await all(` + SELECT DISTINCT album, album_artist, year, + (SELECT artwork_path FROM tracks t2 WHERE t2.album = tracks.album LIMIT 1) as artwork_path, + COUNT(*) as track_count + FROM tracks + WHERE is_single = 0 + GROUP BY album, album_artist + ORDER BY ${orderBy} + LIMIT ? OFFSET ? + `, [limit, skip]); + + let albumListXml = '\n'; + + albums.forEach(album => { + const albumId = crypto.createHash('md5').update(`album-${album.album}-${album.album_artist}`).digest('hex'); + const artistId = crypto.createHash('md5').update(`artist-${album.album_artist}`).digest('hex'); + const coverArt = album.artwork_path ? albumId : ''; + + albumListXml += ` \n`; + }); + + albumListXml += ''; + + sendSubsonicResponse(res, albumListXml); + } catch (error) { + console.error('Error in getAlbumList2:', error); + sendSubsonicError(res, 0, error.message); + } +}); + // Get random songs router.get('/getRandomSongs.view', authenticateSubsonic, async (req, res) => { try {