aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/lib/actor-image.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/lib/actor-image.ts')
-rw-r--r--server/lib/actor-image.ts51
1 files changed, 31 insertions, 20 deletions
diff --git a/server/lib/actor-image.ts b/server/lib/actor-image.ts
index ca7f9658d..59afa93bd 100644
--- a/server/lib/actor-image.ts
+++ b/server/lib/actor-image.ts
@@ -3,50 +3,57 @@ import { queue } from 'async'
3import * as LRUCache from 'lru-cache' 3import * as LRUCache from 'lru-cache'
4import { extname, join } from 'path' 4import { extname, join } from 'path'
5import { v4 as uuidv4 } from 'uuid' 5import { v4 as uuidv4 } from 'uuid'
6import { ActorImageType } from '@shared/models'
6import { retryTransactionWrapper } from '../helpers/database-utils' 7import { retryTransactionWrapper } from '../helpers/database-utils'
7import { processImage } from '../helpers/image-utils' 8import { processImage } from '../helpers/image-utils'
8import { downloadImage } from '../helpers/requests' 9import { downloadImage } from '../helpers/requests'
9import { CONFIG } from '../initializers/config' 10import { CONFIG } from '../initializers/config'
10import { AVATARS_SIZE, LRU_CACHE, QUEUE_CONCURRENCY } from '../initializers/constants' 11import { ACTOR_IMAGES_SIZE, LRU_CACHE, QUEUE_CONCURRENCY } from '../initializers/constants'
11import { sequelizeTypescript } from '../initializers/database' 12import { sequelizeTypescript } from '../initializers/database'
12import { MAccountDefault, MChannelDefault } from '../types/models' 13import { MAccountDefault, MChannelDefault } from '../types/models'
13import { deleteActorAvatarInstance, updateActorAvatarInstance } from './activitypub/actor' 14import { deleteActorImageInstance, updateActorImageInstance } from './activitypub/actor'
14import { sendUpdateActor } from './activitypub/send' 15import { sendUpdateActor } from './activitypub/send'
15 16
16async function updateLocalActorAvatarFile ( 17async function updateLocalActorImageFile (
17 accountOrChannel: MAccountDefault | MChannelDefault, 18 accountOrChannel: MAccountDefault | MChannelDefault,
18 avatarPhysicalFile: Express.Multer.File 19 imagePhysicalFile: Express.Multer.File,
20 type: ActorImageType
19) { 21) {
20 const extension = extname(avatarPhysicalFile.filename) 22 const imageSize = type === ActorImageType.AVATAR
23 ? ACTOR_IMAGES_SIZE.AVATARS
24 : ACTOR_IMAGES_SIZE.BANNERS
21 25
22 const avatarName = uuidv4() + extension 26 const extension = extname(imagePhysicalFile.filename)
23 const destination = join(CONFIG.STORAGE.ACTOR_IMAGES, avatarName) 27
24 await processImage(avatarPhysicalFile.path, destination, AVATARS_SIZE) 28 const imageName = uuidv4() + extension
29 const destination = join(CONFIG.STORAGE.ACTOR_IMAGES, imageName)
30 await processImage(imagePhysicalFile.path, destination, imageSize)
25 31
26 return retryTransactionWrapper(() => { 32 return retryTransactionWrapper(() => {
27 return sequelizeTypescript.transaction(async t => { 33 return sequelizeTypescript.transaction(async t => {
28 const avatarInfo = { 34 const actorImageInfo = {
29 name: avatarName, 35 name: imageName,
30 fileUrl: null, 36 fileUrl: null,
37 type,
31 onDisk: true 38 onDisk: true
32 } 39 }
33 40
34 const updatedActor = await updateActorAvatarInstance(accountOrChannel.Actor, avatarInfo, t) 41 const updatedActor = await updateActorImageInstance(accountOrChannel.Actor, actorImageInfo, t)
35 await updatedActor.save({ transaction: t }) 42 await updatedActor.save({ transaction: t })
36 43
37 await sendUpdateActor(accountOrChannel, t) 44 await sendUpdateActor(accountOrChannel, t)
38 45
39 return updatedActor.Avatar 46 return type === ActorImageType.AVATAR
47 ? updatedActor.Avatar
48 : updatedActor.Banner
40 }) 49 })
41 }) 50 })
42} 51}
43 52
44async function deleteLocalActorAvatarFile ( 53async function deleteLocalActorImageFile (accountOrChannel: MAccountDefault | MChannelDefault, type: ActorImageType) {
45 accountOrChannel: MAccountDefault | MChannelDefault
46) {
47 return retryTransactionWrapper(() => { 54 return retryTransactionWrapper(() => {
48 return sequelizeTypescript.transaction(async t => { 55 return sequelizeTypescript.transaction(async t => {
49 const updatedActor = await deleteActorAvatarInstance(accountOrChannel.Actor, t) 56 const updatedActor = await deleteActorImageInstance(accountOrChannel.Actor, type, t)
50 await updatedActor.save({ transaction: t }) 57 await updatedActor.save({ transaction: t })
51 58
52 await sendUpdateActor(accountOrChannel, t) 59 await sendUpdateActor(accountOrChannel, t)
@@ -56,10 +63,14 @@ async function deleteLocalActorAvatarFile (
56 }) 63 })
57} 64}
58 65
59type DownloadImageQueueTask = { fileUrl: string, filename: string } 66type DownloadImageQueueTask = { fileUrl: string, filename: string, type: ActorImageType }
60 67
61const downloadImageQueue = queue<DownloadImageQueueTask, Error>((task, cb) => { 68const downloadImageQueue = queue<DownloadImageQueueTask, Error>((task, cb) => {
62 downloadImage(task.fileUrl, CONFIG.STORAGE.ACTOR_IMAGES, task.filename, AVATARS_SIZE) 69 const size = task.type === ActorImageType.AVATAR
70 ? ACTOR_IMAGES_SIZE.AVATARS
71 : ACTOR_IMAGES_SIZE.BANNERS
72
73 downloadImage(task.fileUrl, CONFIG.STORAGE.ACTOR_IMAGES, task.filename, size)
63 .then(() => cb()) 74 .then(() => cb())
64 .catch(err => cb(err)) 75 .catch(err => cb(err))
65}, QUEUE_CONCURRENCY.ACTOR_PROCESS_IMAGE) 76}, QUEUE_CONCURRENCY.ACTOR_PROCESS_IMAGE)
@@ -79,7 +90,7 @@ const actorImagePathUnsafeCache = new LRUCache<string, string>({ max: LRU_CACHE.
79 90
80export { 91export {
81 actorImagePathUnsafeCache, 92 actorImagePathUnsafeCache,
82 updateLocalActorAvatarFile, 93 updateLocalActorImageFile,
83 deleteLocalActorAvatarFile, 94 deleteLocalActorImageFile,
84 pushActorImageProcessInQueue 95 pushActorImageProcessInQueue
85} 96}