1 import { remove } from 'fs-extra'
2 import { join } from 'path'
3 import { AfterDestroy, AllowNull, Column, CreatedAt, Default, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
4 import { MActorImageFormattable } from '@server/types/models'
5 import { AttributesOnly } from '@shared/core-utils'
6 import { ActorImageType } from '@shared/models'
7 import { ActorImage } from '../../../shared/models/actors/actor-image.model'
8 import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
9 import { logger } from '../../helpers/logger'
10 import { CONFIG } from '../../initializers/config'
11 import { LAZY_STATIC_PATHS } from '../../initializers/constants'
12 import { throwIfNotValid } from '../utils'
15 tableName: 'actorImage',
18 fields: [ 'filename' ],
23 export class ActorImageModel extends Model<Partial<AttributesOnly<ActorImageModel>>> {
40 @Is('ActorImageFileUrl', value => throwIfNotValid(value, isActivityPubUrlValid, 'fileUrl', true))
59 static removeFilesAndSendDelete (instance: ActorImageModel) {
60 logger.info('Removing actor image file %s.', instance.filename)
62 // Don't block the transaction
63 instance.removeImage()
64 .catch(err => logger.error('Cannot remove actor image file %s.', instance.filename, err))
67 static loadByName (filename: string) {
74 return ActorImageModel.findOne(query)
77 toFormattedJSON (this: MActorImageFormattable): ActorImage {
79 path: this.getStaticPath(),
80 createdAt: this.createdAt,
81 updatedAt: this.updatedAt
86 if (this.type === ActorImageType.AVATAR) {
87 return join(LAZY_STATIC_PATHS.AVATARS, this.filename)
90 return join(LAZY_STATIC_PATHS.BANNERS, this.filename)
94 return join(CONFIG.STORAGE.ACTOR_IMAGES, this.filename)
98 const imagePath = join(CONFIG.STORAGE.ACTOR_IMAGES, this.filename)
99 return remove(imagePath)