Update:Get all user playlists for library API endpoint performance improvement #2852

This commit is contained in:
advplyr 2024-05-27 15:37:02 -05:00
parent 94400f7794
commit 1576164218
2 changed files with 95 additions and 59 deletions

View File

@ -512,8 +512,7 @@ class LibraryController {
* @param {*} res * @param {*} res
*/ */
async getUserPlaylistsForLibrary(req, res) { async getUserPlaylistsForLibrary(req, res) {
let playlistsForUser = await Database.playlistModel.getPlaylistsForUserAndLibrary(req.user.id, req.library.id) let playlistsForUser = await Database.playlistModel.getOldPlaylistsForUserAndLibrary(req.user.id, req.library.id)
playlistsForUser = await Promise.all(playlistsForUser.map(async (p) => p.getOldJsonExpanded()))
const payload = { const payload = {
results: [], results: [],

View File

@ -43,21 +43,24 @@ class Playlist extends Model {
}, },
order: [['playlistMediaItems', 'order', 'ASC']] order: [['playlistMediaItems', 'order', 'ASC']]
}) })
return playlists.map(p => this.getOldPlaylist(p)) return playlists.map((p) => this.getOldPlaylist(p))
} }
static getOldPlaylist(playlistExpanded) { static getOldPlaylist(playlistExpanded) {
const items = playlistExpanded.playlistMediaItems.map(pmi => { const items = playlistExpanded.playlistMediaItems
const libraryItemId = pmi.mediaItem?.podcast?.libraryItem?.id || pmi.mediaItem?.libraryItem?.id || null .map((pmi) => {
if (!libraryItemId) { const mediaItem = pmi.mediaItem || pmi.dataValues?.mediaItem
Logger.error(`[Playlist] Invalid playlist media item - No library item id found`, JSON.stringify(pmi, null, 2)) const libraryItemId = mediaItem?.podcast?.libraryItem?.id || mediaItem?.libraryItem?.id || null
return null if (!libraryItemId) {
} Logger.error(`[Playlist] Invalid playlist media item - No library item id found`, JSON.stringify(pmi, null, 2))
return { return null
episodeId: pmi.mediaItemType === 'podcastEpisode' ? pmi.mediaItemId : '', }
libraryItemId return {
} episodeId: pmi.mediaItemType === 'podcastEpisode' ? pmi.mediaItemId : '',
}).filter(pmi => pmi) libraryItemId
}
})
.filter((pmi) => pmi)
return new oldPlaylist({ return new oldPlaylist({
id: playlistExpanded.id, id: playlistExpanded.id,
@ -77,25 +80,26 @@ class Playlist extends Model {
* @returns {Promise<object>} oldPlaylist.toJSONExpanded * @returns {Promise<object>} oldPlaylist.toJSONExpanded
*/ */
async getOldJsonExpanded(include) { async getOldJsonExpanded(include) {
this.playlistMediaItems = await this.getPlaylistMediaItems({ this.playlistMediaItems =
include: [ (await this.getPlaylistMediaItems({
{ include: [
model: this.sequelize.models.book, {
include: this.sequelize.models.libraryItem model: this.sequelize.models.book,
},
{
model: this.sequelize.models.podcastEpisode,
include: {
model: this.sequelize.models.podcast,
include: this.sequelize.models.libraryItem include: this.sequelize.models.libraryItem
},
{
model: this.sequelize.models.podcastEpisode,
include: {
model: this.sequelize.models.podcast,
include: this.sequelize.models.libraryItem
}
} }
} ],
], order: [['order', 'ASC']]
order: [['order', 'ASC']] })) || []
}) || []
const oldPlaylist = this.sequelize.models.playlist.getOldPlaylist(this) const oldPlaylist = this.sequelize.models.playlist.getOldPlaylist(this)
const libraryItemIds = oldPlaylist.items.map(i => i.libraryItemId) const libraryItemIds = oldPlaylist.items.map((i) => i.libraryItemId)
let libraryItems = await this.sequelize.models.libraryItem.getAllOldLibraryItems({ let libraryItems = await this.sequelize.models.libraryItem.getAllOldLibraryItems({
id: libraryItemIds id: libraryItemIds
@ -167,12 +171,13 @@ class Playlist extends Model {
} }
/** /**
* Get playlists for user and optionally for library * Get old playlists for user and optionally for library
*
* @param {string} userId * @param {string} userId
* @param {[string]} libraryId optional * @param {string} [libraryId]
* @returns {Promise<Playlist[]>} * @returns {Promise<oldPlaylist[]>}
*/ */
static async getPlaylistsForUserAndLibrary(userId, libraryId = null) { static async getOldPlaylistsForUserAndLibrary(userId, libraryId = null) {
if (!userId && !libraryId) return [] if (!userId && !libraryId) return []
const whereQuery = {} const whereQuery = {}
if (userId) { if (userId) {
@ -181,7 +186,7 @@ class Playlist extends Model {
if (libraryId) { if (libraryId) {
whereQuery.libraryId = libraryId whereQuery.libraryId = libraryId
} }
const playlists = await this.findAll({ const playlistsExpanded = await this.findAll({
where: whereQuery, where: whereQuery,
include: { include: {
model: this.sequelize.models.playlistMediaItem, model: this.sequelize.models.playlistMediaItem,
@ -204,7 +209,37 @@ class Playlist extends Model {
['playlistMediaItems', 'order', 'ASC'] ['playlistMediaItems', 'order', 'ASC']
] ]
}) })
return playlists
const oldPlaylists = []
for (const playlistExpanded of playlistsExpanded) {
const oldPlaylist = this.getOldPlaylist(playlistExpanded)
const libraryItems = []
for (const pmi of playlistExpanded.playlistMediaItems) {
let mediaItem = pmi.mediaItem || pmi.dataValues.mediaItem
if (!mediaItem) {
Logger.error(`[Playlist] Invalid playlist media item - No media item found`, JSON.stringify(mediaItem, null, 2))
continue
}
let libraryItem = mediaItem.libraryItem || mediaItem.podcast?.libraryItem
if (mediaItem.podcast) {
libraryItem.media = mediaItem.podcast
libraryItem.media.podcastEpisodes = [mediaItem]
delete mediaItem.podcast.libraryItem
} else {
libraryItem.media = mediaItem
delete mediaItem.libraryItem
}
const oldLibraryItem = this.sequelize.models.libraryItem.getOldLibraryItem(libraryItem)
libraryItems.push(oldLibraryItem)
}
const oldPlaylistJson = oldPlaylist.toJSONExpanded(libraryItems)
oldPlaylists.push(oldPlaylistJson)
}
return oldPlaylists
} }
/** /**
@ -263,9 +298,9 @@ class Playlist extends Model {
const playlists = [] const playlists = []
for (const playlistMediaItem of playlistMediaItemsExpanded) { for (const playlistMediaItem of playlistMediaItemsExpanded) {
const playlist = playlistMediaItem.playlist const playlist = playlistMediaItem.playlist
if (playlists.some(p => p.id === playlist.id)) continue if (playlists.some((p) => p.id === playlist.id)) continue
playlist.playlistMediaItems = playlist.playlistMediaItems.map(pmi => { playlist.playlistMediaItems = playlist.playlistMediaItems.map((pmi) => {
if (pmi.mediaItemType === 'book' && pmi.book !== undefined) { if (pmi.mediaItemType === 'book' && pmi.book !== undefined) {
pmi.mediaItem = pmi.book pmi.mediaItem = pmi.book
pmi.dataValues.mediaItem = pmi.dataValues.book pmi.dataValues.mediaItem = pmi.dataValues.book
@ -289,18 +324,21 @@ class Playlist extends Model {
* @param {import('../Database').sequelize} sequelize * @param {import('../Database').sequelize} sequelize
*/ */
static init(sequelize) { static init(sequelize) {
super.init({ super.init(
id: { {
type: DataTypes.UUID, id: {
defaultValue: DataTypes.UUIDV4, type: DataTypes.UUID,
primaryKey: true defaultValue: DataTypes.UUIDV4,
primaryKey: true
},
name: DataTypes.STRING,
description: DataTypes.TEXT
}, },
name: DataTypes.STRING, {
description: DataTypes.TEXT sequelize,
}, { modelName: 'playlist'
sequelize, }
modelName: 'playlist' )
})
const { library, user } = sequelize.models const { library, user } = sequelize.models
library.hasMany(Playlist) library.hasMany(Playlist)
@ -311,14 +349,14 @@ class Playlist extends Model {
}) })
Playlist.belongsTo(user) Playlist.belongsTo(user)
Playlist.addHook('afterFind', findResult => { Playlist.addHook('afterFind', (findResult) => {
if (!findResult) return if (!findResult) return
if (!Array.isArray(findResult)) findResult = [findResult] if (!Array.isArray(findResult)) findResult = [findResult]
for (const instance of findResult) { for (const instance of findResult) {
if (instance.playlistMediaItems?.length) { if (instance.playlistMediaItems?.length) {
instance.playlistMediaItems = instance.playlistMediaItems.map(pmi => { instance.playlistMediaItems = instance.playlistMediaItems.map((pmi) => {
if (pmi.mediaItemType === 'book' && pmi.book !== undefined) { if (pmi.mediaItemType === 'book' && pmi.book !== undefined) {
pmi.mediaItem = pmi.book pmi.mediaItem = pmi.book
pmi.dataValues.mediaItem = pmi.dataValues.book pmi.dataValues.mediaItem = pmi.dataValues.book
@ -334,7 +372,6 @@ class Playlist extends Model {
return pmi return pmi
}) })
} }
} }
}) })
} }