mirror of
https://github.com/Chocobozzz/PeerTube.git
synced 2025-10-03 09:49:20 +02:00
96 lines
3.2 KiB
TypeScript
96 lines
3.2 KiB
TypeScript
import { LogoType, UploadImageType, UploadImageType_Type } from '@peertube/peertube-models'
|
|
import { buildUUID, getLowercaseExtension } from '@peertube/peertube-node-utils'
|
|
import { buildImageSize } from '@server/helpers/image-utils.js'
|
|
import { UploadImageModel } from '@server/models/application/upload-image.js'
|
|
import { remove } from 'fs-extra/esm'
|
|
import { retryTransactionWrapper } from '../helpers/database-utils.js'
|
|
import { UPLOAD_IMAGES_SIZE } from '../initializers/constants.js'
|
|
import { sequelizeTypescript } from '../initializers/database.js'
|
|
import { MActorUploadImages } from '../types/models/index.js'
|
|
import { processImageFromWorker } from './worker/parent-process.js'
|
|
|
|
export async function replaceUploadImage (options: {
|
|
actor: MActorUploadImages
|
|
imagePhysicalFile: { path: string }
|
|
type: UploadImageType_Type
|
|
}) {
|
|
const { actor, imagePhysicalFile, type } = options
|
|
|
|
const processImageSize = async (imageSizeArg: { width: number, height: number }) => {
|
|
const imageSize = await buildImageSize(imagePhysicalFile.path, imageSizeArg)
|
|
|
|
const extension = getLowercaseExtension(imagePhysicalFile.path)
|
|
const imageName = buildUUID() + extension
|
|
const destination = UploadImageModel.getPathOf(imageName)
|
|
|
|
await processImageFromWorker({ path: imagePhysicalFile.path, destination, newSize: imageSize, keepOriginal: true })
|
|
|
|
return { imageName, imageSize }
|
|
}
|
|
|
|
const processedImages = await Promise.all(UPLOAD_IMAGES_SIZE[type].map(processImageSize))
|
|
await remove(imagePhysicalFile.path)
|
|
|
|
return retryTransactionWrapper(() =>
|
|
sequelizeTypescript.transaction(async t => {
|
|
const imagesToDelete = await UploadImageModel.listByActorAndType(actor, type, t)
|
|
|
|
for (const toDelete of imagesToDelete) {
|
|
await toDelete.destroy({ transaction: t })
|
|
|
|
actor.UploadImages = actor.UploadImages.filter(image => image.id !== toDelete.id)
|
|
}
|
|
|
|
for (const toCreate of processedImages) {
|
|
const uploadImage = await UploadImageModel.create({
|
|
filename: toCreate.imageName,
|
|
height: toCreate.imageSize.height,
|
|
width: toCreate.imageSize.width,
|
|
fileUrl: null,
|
|
type,
|
|
actorId: actor.id
|
|
}, { transaction: t })
|
|
|
|
actor.UploadImages.push(uploadImage)
|
|
}
|
|
})
|
|
)
|
|
}
|
|
|
|
export async function deleteUploadImages (options: {
|
|
actor: MActorUploadImages
|
|
type: UploadImageType_Type
|
|
}) {
|
|
const { actor, type } = options
|
|
|
|
return retryTransactionWrapper(() => {
|
|
return sequelizeTypescript.transaction(async t => {
|
|
const imagesToDelete = await UploadImageModel.listByActorAndType(actor, type, t)
|
|
|
|
for (const toDelete of imagesToDelete) {
|
|
await toDelete.destroy({ transaction: t })
|
|
}
|
|
|
|
actor.UploadImages = []
|
|
})
|
|
})
|
|
}
|
|
|
|
export function logoTypeToUploadImageEnum (logoType: LogoType) {
|
|
switch (logoType) {
|
|
case 'favicon':
|
|
return UploadImageType.INSTANCE_FAVICON
|
|
|
|
case 'header-wide':
|
|
return UploadImageType.INSTANCE_HEADER_WIDE
|
|
|
|
case 'header-square':
|
|
return UploadImageType.INSTANCE_HEADER_SQUARE
|
|
|
|
case 'opengraph':
|
|
return UploadImageType.INSTANCE_OPENGRAPH
|
|
|
|
default:
|
|
return logoType satisfies never
|
|
}
|
|
}
|