123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- import { join } from 'path'
- import {
- AfterDestroy,
- AllowNull,
- BelongsTo,
- Column,
- CreatedAt,
- DataType,
- Default,
- ForeignKey,
- Model,
- Table,
- UpdatedAt
- } from 'sequelize-typescript'
- import { CONSTRAINTS_FIELDS, LAZY_STATIC_PATHS, STATIC_PATHS, WEBSERVER } from '../../initializers/constants'
- import { logger } from '../../helpers/logger'
- import { remove } from 'fs-extra'
- import { CONFIG } from '../../initializers/config'
- import { VideoModel } from './video'
- import { VideoPlaylistModel } from './video-playlist'
- import { ThumbnailType } from '../../../shared/models/videos/thumbnail.type'
- import { MVideoAccountLight } from '@server/types/models'
- import { buildRemoteVideoBaseUrl } from '@server/helpers/activitypub'
- @Table({
- tableName: 'thumbnail',
- indexes: [
- {
- fields: [ 'videoId' ]
- },
- {
- fields: [ 'videoPlaylistId' ],
- unique: true
- }
- ]
- })
- export class ThumbnailModel extends Model {
- @AllowNull(false)
- @Column
- filename: string
- @AllowNull(true)
- @Default(null)
- @Column
- height: number
- @AllowNull(true)
- @Default(null)
- @Column
- width: number
- @AllowNull(false)
- @Column
- type: ThumbnailType
- @AllowNull(true)
- @Column(DataType.STRING(CONSTRAINTS_FIELDS.COMMONS.URL.max))
- fileUrl: string
- @AllowNull(true)
- @Column
- automaticallyGenerated: boolean
- @ForeignKey(() => VideoModel)
- @Column
- videoId: number
- @BelongsTo(() => VideoModel, {
- foreignKey: {
- allowNull: true
- },
- onDelete: 'CASCADE'
- })
- Video: VideoModel
- @ForeignKey(() => VideoPlaylistModel)
- @Column
- videoPlaylistId: number
- @BelongsTo(() => VideoPlaylistModel, {
- foreignKey: {
- allowNull: true
- },
- onDelete: 'CASCADE'
- })
- VideoPlaylist: VideoPlaylistModel
- @CreatedAt
- createdAt: Date
- @UpdatedAt
- updatedAt: Date
- private static readonly types: { [ id in ThumbnailType ]: { label: string, directory: string, staticPath: string } } = {
- [ThumbnailType.MINIATURE]: {
- label: 'miniature',
- directory: CONFIG.STORAGE.THUMBNAILS_DIR,
- staticPath: STATIC_PATHS.THUMBNAILS
- },
- [ThumbnailType.PREVIEW]: {
- label: 'preview',
- directory: CONFIG.STORAGE.PREVIEWS_DIR,
- staticPath: LAZY_STATIC_PATHS.PREVIEWS
- }
- }
- @AfterDestroy
- static removeFiles (instance: ThumbnailModel) {
- logger.info('Removing %s file %s.', ThumbnailModel.types[instance.type].label, instance.filename)
- // Don't block the transaction
- instance.removeThumbnail()
- .catch(err => logger.error('Cannot remove thumbnail file %s.', instance.filename, err))
- }
- static loadByName (filename: string) {
- const query = {
- where: {
- filename
- }
- }
- return ThumbnailModel.findOne(query)
- }
- static generateDefaultPreviewName (videoUUID: string) {
- return videoUUID + '.jpg'
- }
- getFileUrl (video: MVideoAccountLight) {
- 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)
- }
- getPath () {
- const directory = ThumbnailModel.types[this.type].directory
- return join(directory, this.filename)
- }
- removeThumbnail () {
- return remove(this.getPath())
- }
- }
|