Add getAlbumList and getAlbumList2 endpoints for Albums view
This commit is contained in:
@@ -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 = '<albumList>\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 += ` <album id="${albumId}" name="${escapeXml(album.album)}" `;
|
||||||
|
albumListXml += `artist="${escapeXml(album.album_artist || 'Unknown')}" `;
|
||||||
|
albumListXml += `artistId="${artistId}" `;
|
||||||
|
albumListXml += `coverArt="${coverArt}" `;
|
||||||
|
albumListXml += `songCount="${album.track_count}" `;
|
||||||
|
albumListXml += `created="2024-01-01T00:00:00" `;
|
||||||
|
albumListXml += `year="${album.year || ''}" `;
|
||||||
|
albumListXml += `genre=""/>\n`;
|
||||||
|
});
|
||||||
|
|
||||||
|
albumListXml += '</albumList>';
|
||||||
|
|
||||||
|
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 = '<albumList2>\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 += ` <album id="${albumId}" name="${escapeXml(album.album)}" `;
|
||||||
|
albumListXml += `artist="${escapeXml(album.album_artist || 'Unknown')}" `;
|
||||||
|
albumListXml += `artistId="${artistId}" `;
|
||||||
|
albumListXml += `coverArt="${coverArt}" `;
|
||||||
|
albumListXml += `songCount="${album.track_count}" `;
|
||||||
|
albumListXml += `created="2024-01-01T00:00:00" `;
|
||||||
|
albumListXml += `year="${album.year || ''}" `;
|
||||||
|
albumListXml += `genre=""/>\n`;
|
||||||
|
});
|
||||||
|
|
||||||
|
albumListXml += '</albumList2>';
|
||||||
|
|
||||||
|
sendSubsonicResponse(res, albumListXml);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error in getAlbumList2:', error);
|
||||||
|
sendSubsonicError(res, 0, error.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Get random songs
|
// Get random songs
|
||||||
router.get('/getRandomSongs.view', authenticateSubsonic, async (req, res) => {
|
router.get('/getRandomSongs.view', authenticateSubsonic, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user