From 65af03a241aa83ab7ba71278b6c99acd26428b8a Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 1 Aug 2019 16:54:24 +0200 Subject: Automatically update playlist thumbnails --- server/controllers/api/video-playlist.ts | 67 +++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 18 deletions(-) (limited to 'server/controllers/api/video-playlist.ts') diff --git a/server/controllers/api/video-playlist.ts b/server/controllers/api/video-playlist.ts index 540120cca..bd454f553 100644 --- a/server/controllers/api/video-playlist.ts +++ b/server/controllers/api/video-playlist.ts @@ -40,6 +40,7 @@ import { JobQueue } from '../../lib/job-queue' import { CONFIG } from '../../initializers/config' import { sequelizeTypescript } from '../../initializers/database' import { createPlaylistMiniatureFromExisting } from '../../lib/thumbnail' +import { VideoModel } from '../../models/video/video' const reqThumbnailFile = createReqFiles([ 'thumbnailfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT, { thumbnailfile: CONFIG.STORAGE.TMP_DIR }) @@ -171,13 +172,16 @@ async function addVideoPlaylist (req: express.Request, res: express.Response) { const thumbnailField = req.files['thumbnailfile'] const thumbnailModel = thumbnailField - ? await createPlaylistMiniatureFromExisting(thumbnailField[0].path, videoPlaylist) + ? await createPlaylistMiniatureFromExisting(thumbnailField[0].path, videoPlaylist, false) : undefined const videoPlaylistCreated: VideoPlaylistModel = await sequelizeTypescript.transaction(async t => { const videoPlaylistCreated = await videoPlaylist.save({ transaction: t }) - if (thumbnailModel) await videoPlaylistCreated.setAndSaveThumbnail(thumbnailModel, t) + if (thumbnailModel) { + thumbnailModel.automaticallyGenerated = false + await videoPlaylistCreated.setAndSaveThumbnail(thumbnailModel, t) + } // We need more attributes for the federation videoPlaylistCreated.OwnerAccount = await AccountModel.load(user.Account.id, t) @@ -206,7 +210,7 @@ async function updateVideoPlaylist (req: express.Request, res: express.Response) const thumbnailField = req.files['thumbnailfile'] const thumbnailModel = thumbnailField - ? await createPlaylistMiniatureFromExisting(thumbnailField[0].path, videoPlaylistInstance) + ? await createPlaylistMiniatureFromExisting(thumbnailField[0].path, videoPlaylistInstance, false) : undefined try { @@ -239,7 +243,10 @@ async function updateVideoPlaylist (req: express.Request, res: express.Response) const playlistUpdated = await videoPlaylistInstance.save(sequelizeOptions) - if (thumbnailModel) await playlistUpdated.setAndSaveThumbnail(thumbnailModel, t) + if (thumbnailModel) { + thumbnailModel.automaticallyGenerated = false + await playlistUpdated.setAndSaveThumbnail(thumbnailModel, t) + } const isNewPlaylist = wasPrivatePlaylist && playlistUpdated.privacy !== VideoPlaylistPrivacy.PRIVATE @@ -301,23 +308,17 @@ async function addVideoInPlaylist (req: express.Request, res: express.Response) videoPlaylist.changed('updatedAt', true) await videoPlaylist.save({ transaction: t }) - await sendUpdateVideoPlaylist(videoPlaylist, t) - return playlistElement }) // If the user did not set a thumbnail, automatically take the video thumbnail - if (videoPlaylist.hasThumbnail() === false) { - logger.info('Generating default thumbnail to playlist %s.', videoPlaylist.url) - - const inputPath = join(CONFIG.STORAGE.THUMBNAILS_DIR, video.getMiniature().filename) - const thumbnailModel = await createPlaylistMiniatureFromExisting(inputPath, videoPlaylist, true) - - thumbnailModel.videoPlaylistId = videoPlaylist.id - - await thumbnailModel.save() + if (videoPlaylist.hasThumbnail() === false || (videoPlaylist.hasGeneratedThumbnail() && playlistElement.position === 1)) { + await generateThumbnailForPlaylist(videoPlaylist, video) } + sendUpdateVideoPlaylist(videoPlaylist, undefined) + .catch(err => logger.error('Cannot send video playlist update.', { err })) + logger.info('Video added in playlist %s at position %d.', videoPlaylist.uuid, playlistElement.position) return res.json({ @@ -365,11 +366,17 @@ async function removeVideoFromPlaylist (req: express.Request, res: express.Respo videoPlaylist.changed('updatedAt', true) await videoPlaylist.save({ transaction: t }) - await sendUpdateVideoPlaylist(videoPlaylist, t) - logger.info('Video playlist element %d of playlist %s deleted.', videoPlaylistElement.position, videoPlaylist.uuid) }) + // Do we need to regenerate the default thumbnail? + if (positionToDelete === 1 && videoPlaylist.hasGeneratedThumbnail()) { + await regeneratePlaylistThumbnail(videoPlaylist) + } + + sendUpdateVideoPlaylist(videoPlaylist, undefined) + .catch(err => logger.error('Cannot send video playlist update.', { err })) + return res.type('json').status(204).end() } @@ -413,8 +420,13 @@ async function reorderVideosPlaylist (req: express.Request, res: express.Respons await sendUpdateVideoPlaylist(videoPlaylist, t) }) + // The first element changed + if ((start === 1 || insertAfter === 0) && videoPlaylist.hasGeneratedThumbnail()) { + await regeneratePlaylistThumbnail(videoPlaylist) + } + logger.info( - 'Reordered playlist %s (inserted after %d elements %d - %d).', + 'Reordered playlist %s (inserted after position %d elements %d - %d).', videoPlaylist.uuid, insertAfter, start, start + reorderLength - 1 ) @@ -440,3 +452,22 @@ async function getVideoPlaylistVideos (req: express.Request, res: express.Respon } return res.json(getFormattedObjects(resultList.data, resultList.total, options)) } + +async function regeneratePlaylistThumbnail (videoPlaylist: VideoPlaylistModel) { + await videoPlaylist.Thumbnail.destroy() + videoPlaylist.Thumbnail = null + + const firstElement = await VideoPlaylistElementModel.loadFirstElementWithVideoThumbnail(videoPlaylist.id) + if (firstElement) await generateThumbnailForPlaylist(videoPlaylist, firstElement.Video) +} + +async function generateThumbnailForPlaylist (videoPlaylist: VideoPlaylistModel, video: VideoModel) { + logger.info('Generating default thumbnail to playlist %s.', videoPlaylist.url) + + const inputPath = join(CONFIG.STORAGE.THUMBNAILS_DIR, video.getMiniature().filename) + const thumbnailModel = await createPlaylistMiniatureFromExisting(inputPath, videoPlaylist, true, true) + + thumbnailModel.videoPlaylistId = videoPlaylist.id + + videoPlaylist.Thumbnail = await thumbnailModel.save() +} -- cgit v1.2.3