Fix deleting episode library file removes episode from playlist #3784

This commit is contained in:
advplyr 2025-01-03 12:06:20 -06:00
parent de7296eaab
commit 63466ec48b
4 changed files with 67 additions and 30 deletions

View File

@ -695,6 +695,27 @@ class Database {
await book.destroy() await book.destroy()
} }
const playlistMediaItemsWithNoMediaItem = await this.playlistMediaItemModel.findAll({
include: [
{
model: this.bookModel,
attributes: ['id']
},
{
model: this.podcastEpisodeModel,
attributes: ['id']
}
],
where: {
'$book.id$': null,
'$podcastEpisode.id$': null
}
})
for (const playlistMediaItem of playlistMediaItemsWithNoMediaItem) {
Logger.warn(`Found playlistMediaItem with no book or podcastEpisode - removing it`)
await playlistMediaItem.destroy()
}
// Remove empty series // Remove empty series
const emptySeries = await this.seriesModel.findAll({ const emptySeries = await this.seriesModel.findAll({
include: { include: {

View File

@ -971,6 +971,7 @@ class LibraryItemController {
} }
} else if (req.libraryItem.media.podcastEpisodes.some((ep) => ep.audioFile.ino === req.params.fileid)) { } else if (req.libraryItem.media.podcastEpisodes.some((ep) => ep.audioFile.ino === req.params.fileid)) {
const episodeToRemove = req.libraryItem.media.podcastEpisodes.find((ep) => ep.audioFile.ino === req.params.fileid) const episodeToRemove = req.libraryItem.media.podcastEpisodes.find((ep) => ep.audioFile.ino === req.params.fileid)
await Database.playlistModel.removeMediaItemsFromPlaylists([episodeToRemove.id])
await episodeToRemove.destroy() await episodeToRemove.destroy()
req.libraryItem.media.podcastEpisodes = req.libraryItem.media.podcastEpisodes.filter((ep) => ep.audioFile.ino !== req.params.fileid) req.libraryItem.media.podcastEpisodes = req.libraryItem.media.podcastEpisodes.filter((ep) => ep.audioFile.ino !== req.params.fileid)

View File

@ -1,5 +1,6 @@
const { DataTypes, Model, Op } = require('sequelize') const { DataTypes, Model, Op } = require('sequelize')
const Logger = require('../Logger') const Logger = require('../Logger')
const SocketAuthority = require('../SocketAuthority')
class Playlist extends Model { class Playlist extends Model {
constructor(values, options) { constructor(values, options) {
@ -163,6 +164,49 @@ class Playlist extends Model {
return playlists return playlists
} }
/**
* Removes media items and re-orders playlists
*
* @param {string[]} mediaItemIds
*/
static async removeMediaItemsFromPlaylists(mediaItemIds) {
if (!mediaItemIds?.length) return
const playlistsWithItem = await this.getPlaylistsForMediaItemIds(mediaItemIds)
if (!playlistsWithItem.length) return
for (const playlist of playlistsWithItem) {
let numMediaItems = playlist.playlistMediaItems.length
let order = 1
// Remove items in playlist and re-order
for (const playlistMediaItem of playlist.playlistMediaItems) {
if (mediaItemIds.includes(playlistMediaItem.mediaItemId)) {
await playlistMediaItem.destroy()
numMediaItems--
} else {
if (playlistMediaItem.order !== order) {
playlistMediaItem.update({
order
})
}
order++
}
}
// If playlist is now empty then remove it
const jsonExpanded = await playlist.getOldJsonExpanded()
if (!numMediaItems) {
Logger.info(`[ApiRouter] Playlist "${playlist.name}" has no more items - removing it`)
await playlist.destroy()
SocketAuthority.clientEmitter(playlist.userId, 'playlist_removed', jsonExpanded)
} else {
SocketAuthority.clientEmitter(playlist.userId, 'playlist_updated', jsonExpanded)
}
}
}
/** /**
* Initialize model * Initialize model
* @param {import('../Database').sequelize} sequelize * @param {import('../Database').sequelize} sequelize

View File

@ -361,36 +361,7 @@ class ApiRouter {
} }
// remove item from playlists // remove item from playlists
const playlistsWithItem = await Database.playlistModel.getPlaylistsForMediaItemIds(mediaItemIds) await Database.playlistModel.removeMediaItemsFromPlaylists(mediaItemIds)
for (const playlist of playlistsWithItem) {
let numMediaItems = playlist.playlistMediaItems.length
let order = 1
// Remove items in playlist and re-order
for (const playlistMediaItem of playlist.playlistMediaItems) {
if (mediaItemIds.includes(playlistMediaItem.mediaItemId)) {
await playlistMediaItem.destroy()
numMediaItems--
} else {
if (playlistMediaItem.order !== order) {
playlistMediaItem.update({
order
})
}
order++
}
}
// If playlist is now empty then remove it
const jsonExpanded = await playlist.getOldJsonExpanded()
if (!numMediaItems) {
Logger.info(`[ApiRouter] Playlist "${playlist.name}" has no more items - removing it`)
await playlist.destroy()
SocketAuthority.clientEmitter(playlist.userId, 'playlist_removed', jsonExpanded)
} else {
SocketAuthority.clientEmitter(playlist.userId, 'playlist_updated', jsonExpanded)
}
}
// Close rss feed - remove from db and emit socket event // Close rss feed - remove from db and emit socket event
await RssFeedManager.closeFeedForEntityId(libraryItemId) await RssFeedManager.closeFeedForEntityId(libraryItemId)