X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fmodels%2Fvideo%2Fthumbnail.ts;h=05c58cf19cc57b5bd494b9b82f37dffb0a06ad54;hb=dbd9fb44ddd880622265097bd7baf4dd71ea0861;hp=3cad6c668d0f3260d395b70c5d68a40359de2328;hpb=a8b1b40485145ac1eae513a661d7dd6e0986ce96;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/models/video/thumbnail.ts b/server/models/video/thumbnail.ts index 3cad6c668..05c58cf19 100644 --- a/server/models/video/thumbnail.ts +++ b/server/models/video/thumbnail.ts @@ -3,6 +3,8 @@ import { join } from 'path' import { AfterDestroy, AllowNull, + BeforeCreate, + BeforeUpdate, BelongsTo, Column, CreatedAt, @@ -13,8 +15,9 @@ import { Table, UpdatedAt } from 'sequelize-typescript' -import { buildRemoteVideoBaseUrl } from '@server/helpers/activitypub' -import { MThumbnailVideo, MVideoAccountLight } from '@server/types/models' +import { afterCommitIfTransaction } from '@server/helpers/database-utils' +import { MThumbnail, MThumbnailVideo, MVideo } from '@server/types/models' +import { AttributesOnly } from '@shared/typescript-utils' import { ThumbnailType } from '../../../shared/models/videos/thumbnail.type' import { logger } from '../../helpers/logger' import { CONFIG } from '../../initializers/config' @@ -38,7 +41,7 @@ import { VideoPlaylistModel } from './video-playlist' } ] }) -export class ThumbnailModel extends Model { +export class ThumbnailModel extends Model>> { @AllowNull(false) @Column @@ -96,6 +99,9 @@ export class ThumbnailModel extends Model { @UpdatedAt updatedAt: Date + // If this thumbnail replaced existing one, track the old name + previousThumbnailFilename: string + private static readonly types: { [ id in ThumbnailType ]: { label: string, directory: string, staticPath: string } } = { [ThumbnailType.MINIATURE]: { label: 'miniature', @@ -109,6 +115,12 @@ export class ThumbnailModel extends Model { } } + @BeforeCreate + @BeforeUpdate + static removeOldFile (instance: ThumbnailModel, options) { + return afterCommitIfTransaction(options.transaction, () => instance.removePreviousFilenameIfNeeded()) + } + @AfterDestroy static removeFiles (instance: ThumbnailModel) { logger.info('Removing %s file %s.', ThumbnailModel.types[instance.type].label, instance.filename) @@ -118,7 +130,18 @@ export class ThumbnailModel extends Model { .catch(err => logger.error('Cannot remove thumbnail file %s.', instance.filename, err)) } - static loadWithVideoByName (filename: string, thumbnailType: ThumbnailType): Promise { + static loadByFilename (filename: string, thumbnailType: ThumbnailType): Promise { + const query = { + where: { + filename, + type: thumbnailType + } + } + + return ThumbnailModel.findOne(query) + } + + static loadWithVideoByFilename (filename: string, thumbnailType: ThumbnailType): Promise { const query = { where: { filename, @@ -135,22 +158,39 @@ export class ThumbnailModel extends Model { return ThumbnailModel.findOne(query) } - getFileUrl (video: MVideoAccountLight) { + static buildPath (type: ThumbnailType, filename: string) { + const directory = ThumbnailModel.types[type].directory + + return join(directory, filename) + } + + getFileUrl (video: MVideo) { const staticPath = ThumbnailModel.types[this.type].staticPath + this.filename if (video.isOwned()) return WEBSERVER.URL + staticPath - if (this.fileUrl) return this.fileUrl - // Fallback if we don't have a file URL - return buildRemoteVideoBaseUrl(video, staticPath) + return this.fileUrl } getPath () { - const directory = ThumbnailModel.types[this.type].directory - return join(directory, this.filename) + return ThumbnailModel.buildPath(this.type, this.filename) + } + + getPreviousPath () { + return ThumbnailModel.buildPath(this.type, this.previousThumbnailFilename) } removeThumbnail () { return remove(this.getPath()) } + + removePreviousFilenameIfNeeded () { + if (!this.previousThumbnailFilename) return + + const previousPath = this.getPreviousPath() + remove(previousPath) + .catch(err => logger.error('Cannot remove previous thumbnail file %s.', previousPath, { err })) + + this.previousThumbnailFilename = undefined + } }