Skip to content

Commit

Permalink
Update:Get all user playlists for library API endpoint performance im…
Browse files Browse the repository at this point in the history
…provement #2852
  • Loading branch information
advplyr committed May 27, 2024
1 parent 94400f7 commit 1576164
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 59 deletions.
3 changes: 1 addition & 2 deletions server/controllers/LibraryController.js
Original file line number Diff line number Diff line change
Expand Up @@ -512,8 +512,7 @@ class LibraryController {
* @param {*} res
*/
async getUserPlaylistsForLibrary(req, res) {
let playlistsForUser = await Database.playlistModel.getPlaylistsForUserAndLibrary(req.user.id, req.library.id)
playlistsForUser = await Promise.all(playlistsForUser.map(async (p) => p.getOldJsonExpanded()))
let playlistsForUser = await Database.playlistModel.getOldPlaylistsForUserAndLibrary(req.user.id, req.library.id)

const payload = {
results: [],
Expand Down
151 changes: 94 additions & 57 deletions server/models/Playlist.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,24 @@ class Playlist extends Model {
},
order: [['playlistMediaItems', 'order', 'ASC']]
})
return playlists.map(p => this.getOldPlaylist(p))
return playlists.map((p) => this.getOldPlaylist(p))
}

static getOldPlaylist(playlistExpanded) {
const items = playlistExpanded.playlistMediaItems.map(pmi => {
const libraryItemId = pmi.mediaItem?.podcast?.libraryItem?.id || pmi.mediaItem?.libraryItem?.id || null
if (!libraryItemId) {
Logger.error(`[Playlist] Invalid playlist media item - No library item id found`, JSON.stringify(pmi, null, 2))
return null
}
return {
episodeId: pmi.mediaItemType === 'podcastEpisode' ? pmi.mediaItemId : '',
libraryItemId
}
}).filter(pmi => pmi)
const items = playlistExpanded.playlistMediaItems
.map((pmi) => {
const mediaItem = pmi.mediaItem || pmi.dataValues?.mediaItem
const libraryItemId = mediaItem?.podcast?.libraryItem?.id || mediaItem?.libraryItem?.id || null
if (!libraryItemId) {
Logger.error(`[Playlist] Invalid playlist media item - No library item id found`, JSON.stringify(pmi, null, 2))
return null
}
return {
episodeId: pmi.mediaItemType === 'podcastEpisode' ? pmi.mediaItemId : '',
libraryItemId
}
})
.filter((pmi) => pmi)

return new oldPlaylist({
id: playlistExpanded.id,
Expand All @@ -77,25 +80,26 @@ class Playlist extends Model {
* @returns {Promise<object>} oldPlaylist.toJSONExpanded
*/
async getOldJsonExpanded(include) {
this.playlistMediaItems = await this.getPlaylistMediaItems({
include: [
{
model: this.sequelize.models.book,
include: this.sequelize.models.libraryItem
},
{
model: this.sequelize.models.podcastEpisode,
include: {
model: this.sequelize.models.podcast,
this.playlistMediaItems =
(await this.getPlaylistMediaItems({
include: [
{
model: this.sequelize.models.book,
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 libraryItemIds = oldPlaylist.items.map(i => i.libraryItemId)
const libraryItemIds = oldPlaylist.items.map((i) => i.libraryItemId)

let libraryItems = await this.sequelize.models.libraryItem.getAllOldLibraryItems({
id: libraryItemIds
Expand Down Expand Up @@ -138,7 +142,7 @@ class Playlist extends Model {

/**
* Get playlist by id
* @param {string} playlistId
* @param {string} playlistId
* @returns {Promise<oldPlaylist|null>} returns null if not found
*/
static async getById(playlistId) {
Expand Down Expand Up @@ -167,12 +171,13 @@ class Playlist extends Model {
}

/**
* Get playlists for user and optionally for library
* @param {string} userId
* @param {[string]} libraryId optional
* @returns {Promise<Playlist[]>}
* Get old playlists for user and optionally for library
*
* @param {string} userId
* @param {string} [libraryId]
* @returns {Promise<oldPlaylist[]>}
*/
static async getPlaylistsForUserAndLibrary(userId, libraryId = null) {
static async getOldPlaylistsForUserAndLibrary(userId, libraryId = null) {
if (!userId && !libraryId) return []
const whereQuery = {}
if (userId) {
Expand All @@ -181,7 +186,7 @@ class Playlist extends Model {
if (libraryId) {
whereQuery.libraryId = libraryId
}
const playlists = await this.findAll({
const playlistsExpanded = await this.findAll({
where: whereQuery,
include: {
model: this.sequelize.models.playlistMediaItem,
Expand All @@ -204,14 +209,44 @@ class Playlist extends Model {
['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
}

/**
* Get number of playlists for a user and library
* @param {string} userId
* @param {string} libraryId
* @returns
* @param {string} userId
* @param {string} libraryId
* @returns
*/
static async getNumPlaylistsForUserAndLibrary(userId, libraryId) {
return this.count({
Expand All @@ -224,7 +259,7 @@ class Playlist extends Model {

/**
* Get all playlists for mediaItemIds
* @param {string[]} mediaItemIds
* @param {string[]} mediaItemIds
* @returns {Promise<Playlist[]>}
*/
static async getPlaylistsForMediaItemIds(mediaItemIds) {
Expand Down Expand Up @@ -263,9 +298,9 @@ class Playlist extends Model {
const playlists = []
for (const playlistMediaItem of playlistMediaItemsExpanded) {
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) {
pmi.mediaItem = pmi.book
pmi.dataValues.mediaItem = pmi.dataValues.book
Expand All @@ -286,21 +321,24 @@ class Playlist extends Model {

/**
* Initialize model
* @param {import('../Database').sequelize} sequelize
* @param {import('../Database').sequelize} sequelize
*/
static init(sequelize) {
super.init({
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true
super.init(
{
id: {
type: DataTypes.UUID,
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
library.hasMany(Playlist)
Expand All @@ -311,14 +349,14 @@ class Playlist extends Model {
})
Playlist.belongsTo(user)

Playlist.addHook('afterFind', findResult => {
Playlist.addHook('afterFind', (findResult) => {
if (!findResult) return

if (!Array.isArray(findResult)) findResult = [findResult]

for (const instance of findResult) {
if (instance.playlistMediaItems?.length) {
instance.playlistMediaItems = instance.playlistMediaItems.map(pmi => {
instance.playlistMediaItems = instance.playlistMediaItems.map((pmi) => {
if (pmi.mediaItemType === 'book' && pmi.book !== undefined) {
pmi.mediaItem = pmi.book
pmi.dataValues.mediaItem = pmi.dataValues.book
Expand All @@ -334,10 +372,9 @@ class Playlist extends Model {
return pmi
})
}

}
})
}
}

module.exports = Playlist
module.exports = Playlist

0 comments on commit 1576164

Please sign in to comment.