]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/models/video/thumbnail.ts
Generate a name for thumbnails
[github/Chocobozzz/PeerTube.git] / server / models / video / thumbnail.ts
CommitLineData
a8b1b404 1import { remove } from 'fs-extra'
e8bafea3 2import { join } from 'path'
2735a154
C
3import {
4 AfterDestroy,
5 AllowNull,
6 BelongsTo,
7 Column,
8 CreatedAt,
9 DataType,
10 Default,
11 ForeignKey,
12 Model,
13 Table,
14 UpdatedAt
15} from 'sequelize-typescript'
a8b1b404
C
16import { buildRemoteVideoBaseUrl } from '@server/helpers/activitypub'
17import { MThumbnailVideo, MVideoAccountLight } from '@server/types/models'
18import { ThumbnailType } from '../../../shared/models/videos/thumbnail.type'
e8bafea3 19import { logger } from '../../helpers/logger'
e8bafea3 20import { CONFIG } from '../../initializers/config'
a8b1b404 21import { CONSTRAINTS_FIELDS, LAZY_STATIC_PATHS, STATIC_PATHS, WEBSERVER } from '../../initializers/constants'
e8bafea3
C
22import { VideoModel } from './video'
23import { VideoPlaylistModel } from './video-playlist'
e8bafea3
C
24
25@Table({
26 tableName: 'thumbnail',
27 indexes: [
28 {
29 fields: [ 'videoId' ]
30 },
31 {
32 fields: [ 'videoPlaylistId' ],
33 unique: true
a8b1b404
C
34 },
35 {
36 fields: [ 'filename', 'type' ],
37 unique: true
e8bafea3
C
38 }
39 ]
40})
b49f22d8 41export class ThumbnailModel extends Model {
e8bafea3
C
42
43 @AllowNull(false)
44 @Column
45 filename: string
46
47 @AllowNull(true)
48 @Default(null)
49 @Column
50 height: number
51
52 @AllowNull(true)
53 @Default(null)
54 @Column
55 width: number
56
57 @AllowNull(false)
58 @Column
59 type: ThumbnailType
60
61 @AllowNull(true)
2735a154 62 @Column(DataType.STRING(CONSTRAINTS_FIELDS.COMMONS.URL.max))
9cc8d43e 63 fileUrl: string
e8bafea3 64
65af03a2
C
65 @AllowNull(true)
66 @Column
67 automaticallyGenerated: boolean
68
e8bafea3
C
69 @ForeignKey(() => VideoModel)
70 @Column
71 videoId: number
72
73 @BelongsTo(() => VideoModel, {
74 foreignKey: {
75 allowNull: true
76 },
77 onDelete: 'CASCADE'
78 })
79 Video: VideoModel
80
81 @ForeignKey(() => VideoPlaylistModel)
82 @Column
83 videoPlaylistId: number
84
85 @BelongsTo(() => VideoPlaylistModel, {
86 foreignKey: {
87 allowNull: true
88 },
89 onDelete: 'CASCADE'
90 })
91 VideoPlaylist: VideoPlaylistModel
92
93 @CreatedAt
94 createdAt: Date
95
96 @UpdatedAt
97 updatedAt: Date
98
a1587156 99 private static readonly types: { [ id in ThumbnailType ]: { label: string, directory: string, staticPath: string } } = {
3acc5084
C
100 [ThumbnailType.MINIATURE]: {
101 label: 'miniature',
e8bafea3
C
102 directory: CONFIG.STORAGE.THUMBNAILS_DIR,
103 staticPath: STATIC_PATHS.THUMBNAILS
104 },
105 [ThumbnailType.PREVIEW]: {
106 label: 'preview',
107 directory: CONFIG.STORAGE.PREVIEWS_DIR,
557b13ae 108 staticPath: LAZY_STATIC_PATHS.PREVIEWS
e8bafea3
C
109 }
110 }
111
112 @AfterDestroy
65af03a2 113 static removeFiles (instance: ThumbnailModel) {
e8bafea3
C
114 logger.info('Removing %s file %s.', ThumbnailModel.types[instance.type].label, instance.filename)
115
116 // Don't block the transaction
117 instance.removeThumbnail()
118 .catch(err => logger.error('Cannot remove thumbnail file %s.', instance.filename, err))
119 }
120
a8b1b404 121 static loadWithVideoByName (filename: string, thumbnailType: ThumbnailType): Promise<MThumbnailVideo> {
e2600d8b
C
122 const query = {
123 where: {
a8b1b404
C
124 filename,
125 type: thumbnailType
126 },
127 include: [
128 {
129 model: VideoModel.unscoped(),
130 required: true
131 }
132 ]
e2600d8b
C
133 }
134
135 return ThumbnailModel.findOne(query)
136 }
137
ca6d3622
C
138 getFileUrl (video: MVideoAccountLight) {
139 const staticPath = ThumbnailModel.types[this.type].staticPath + this.filename
e8bafea3 140
ca6d3622
C
141 if (video.isOwned()) return WEBSERVER.URL + staticPath
142 if (this.fileUrl) return this.fileUrl
143
144 // Fallback if we don't have a file URL
145 return buildRemoteVideoBaseUrl(video, staticPath)
e8bafea3
C
146 }
147
536598cf 148 getPath () {
e8bafea3 149 const directory = ThumbnailModel.types[this.type].directory
536598cf
C
150 return join(directory, this.filename)
151 }
e8bafea3 152
536598cf
C
153 removeThumbnail () {
154 return remove(this.getPath())
e8bafea3
C
155 }
156}