X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fmodels%2Factor%2Factor-image.ts;h=9c34a0101acf46c778f548933f7ed924d756d5a0;hb=3f0ceab06e5320f62f593c49daa30d963dbc36f9;hp=ae05b4969d894adaeb99433aaa76ef4dc5b92f95;hpb=7d9ba5c08999c6482f0bc5e0c09c6f55b7724090;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/models/actor/actor-image.ts b/server/models/actor/actor-image.ts index ae05b4969..9c34a0101 100644 --- a/server/models/actor/actor-image.ts +++ b/server/models/actor/actor-image.ts @@ -1,14 +1,29 @@ import { remove } from 'fs-extra' import { join } from 'path' -import { AfterDestroy, AllowNull, Column, CreatedAt, Default, Is, Model, Table, UpdatedAt } from 'sequelize-typescript' -import { MActorImageFormattable } from '@server/types/models' -import { ActorImageType } from '@shared/models' +import { + AfterDestroy, + AllowNull, + BelongsTo, + Column, + CreatedAt, + Default, + ForeignKey, + Is, + Model, + Table, + UpdatedAt +} from 'sequelize-typescript' +import { MActorImage, MActorImageFormattable } from '@server/types/models' +import { getLowercaseExtension } from '@shared/core-utils' +import { ActivityIconObject, ActorImageType } from '@shared/models' +import { AttributesOnly } from '@shared/typescript-utils' import { ActorImage } from '../../../shared/models/actors/actor-image.model' import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' import { logger } from '../../helpers/logger' import { CONFIG } from '../../initializers/config' -import { LAZY_STATIC_PATHS } from '../../initializers/constants' -import { throwIfNotValid } from '../utils' +import { LAZY_STATIC_PATHS, MIMETYPES, WEBSERVER } from '../../initializers/constants' +import { buildSQLAttributes, throwIfNotValid } from '../shared' +import { ActorModel } from './actor' @Table({ tableName: 'actorImage', @@ -16,10 +31,14 @@ import { throwIfNotValid } from '../utils' { fields: [ 'filename' ], unique: true + }, + { + fields: [ 'actorId', 'type', 'width' ], + unique: true } ] }) -export class ActorImageModel extends Model { +export class ActorImageModel extends Model>> { @AllowNull(false) @Column @@ -54,15 +73,39 @@ export class ActorImageModel extends Model { @UpdatedAt updatedAt: Date + @ForeignKey(() => ActorModel) + @Column + actorId: number + + @BelongsTo(() => ActorModel, { + foreignKey: { + allowNull: false + }, + onDelete: 'CASCADE' + }) + Actor: ActorModel + @AfterDestroy static removeFilesAndSendDelete (instance: ActorImageModel) { logger.info('Removing actor image file %s.', instance.filename) // Don't block the transaction instance.removeImage() - .catch(err => logger.error('Cannot remove actor image file %s.', instance.filename, err)) + .catch(err => logger.error('Cannot remove actor image file %s.', instance.filename, { err })) } + // --------------------------------------------------------------------------- + + static getSQLAttributes (tableName: string, aliasPrefix = '') { + return buildSQLAttributes({ + model: this, + tableName, + aliasPrefix + }) + } + + // --------------------------------------------------------------------------- + static loadByName (filename: string) { const query = { where: { @@ -73,20 +116,44 @@ export class ActorImageModel extends Model { return ActorImageModel.findOne(query) } + static getImageUrl (image: MActorImage) { + if (!image) return undefined + + return WEBSERVER.URL + image.getStaticPath() + } + toFormattedJSON (this: MActorImageFormattable): ActorImage { return { + width: this.width, path: this.getStaticPath(), createdAt: this.createdAt, updatedAt: this.updatedAt } } - getStaticPath () { - if (this.type === ActorImageType.AVATAR) { - return join(LAZY_STATIC_PATHS.AVATARS, this.filename) + toActivityPubObject (): ActivityIconObject { + const extension = getLowercaseExtension(this.filename) + + return { + type: 'Image', + mediaType: MIMETYPES.IMAGE.EXT_MIMETYPE[extension], + height: this.height, + width: this.width, + url: ActorImageModel.getImageUrl(this) } + } - return join(LAZY_STATIC_PATHS.BANNERS, this.filename) + getStaticPath () { + switch (this.type) { + case ActorImageType.AVATAR: + return join(LAZY_STATIC_PATHS.AVATARS, this.filename) + + case ActorImageType.BANNER: + return join(LAZY_STATIC_PATHS.BANNERS, this.filename) + + default: + throw new Error('Unknown actor image type: ' + this.type) + } } getPath () { @@ -97,4 +164,8 @@ export class ActorImageModel extends Model { const imagePath = join(CONFIG.STORAGE.ACTOR_IMAGES, this.filename) return remove(imagePath) } + + isOwned () { + return !this.fileUrl + } }