]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/lib/activitypub/actors/image.ts
Translated using Weblate (Persian)
[github/Chocobozzz/PeerTube.git] / server / lib / activitypub / actors / image.ts
CommitLineData
136d7efd
C
1import { Transaction } from 'sequelize/types'
2import { logger } from '@server/helpers/logger'
3import { ActorImageModel } from '@server/models/actor/actor-image'
4import { MActorImage, MActorImages } from '@server/types/models'
5import { ActorImageType } from '@shared/models'
6
7type ImageInfo = {
8 name: string
9 fileUrl: string
10 height: number
11 width: number
12 onDisk?: boolean
13}
14
d0800f76 15async function updateActorImages (actor: MActorImages, type: ActorImageType, imagesInfo: ImageInfo[], t: Transaction) {
e0bfb72c
C
16 const getAvatarsOrBanners = () => {
17 const result = type === ActorImageType.AVATAR
18 ? actor.Avatars
19 : actor.Banners
20
21 return result || []
22 }
136d7efd 23
d0800f76 24 if (imagesInfo.length === 0) {
25 await deleteActorImages(actor, type, t)
26 }
27
e0bfb72c
C
28 // Cleanup old images that did not have a width
29 for (const oldImageModel of getAvatarsOrBanners()) {
30 if (oldImageModel.width) continue
31
32 await safeDeleteActorImage(actor, oldImageModel, type, t)
33 }
34
d0800f76 35 for (const imageInfo of imagesInfo) {
e0bfb72c 36 const oldImageModel = getAvatarsOrBanners().find(i => imageInfo.width && i.width === imageInfo.width)
136d7efd 37
d0800f76 38 if (oldImageModel) {
39 // Don't update the avatar if the file URL did not change
e0bfb72c 40 if (imageInfo.fileUrl && oldImageModel.fileUrl === imageInfo.fileUrl) {
d0800f76 41 continue
42 }
136d7efd 43
d0800f76 44 await safeDeleteActorImage(actor, oldImageModel, type, t)
136d7efd 45 }
136d7efd 46
136d7efd
C
47 const imageModel = await ActorImageModel.create({
48 filename: imageInfo.name,
49 onDisk: imageInfo.onDisk ?? false,
50 fileUrl: imageInfo.fileUrl,
51 height: imageInfo.height,
52 width: imageInfo.width,
d0800f76 53 type,
54 actorId: actor.id
136d7efd
C
55 }, { transaction: t })
56
d0800f76 57 addActorImage(actor, type, imageModel)
136d7efd
C
58 }
59
60 return actor
61}
62
d0800f76 63async function deleteActorImages (actor: MActorImages, type: ActorImageType, t: Transaction) {
136d7efd 64 try {
d0800f76 65 const association = buildAssociationName(type)
136d7efd 66
d0800f76 67 for (const image of actor[association]) {
68 await image.destroy({ transaction: t })
136d7efd 69 }
d0800f76 70
71 actor[association] = []
136d7efd
C
72 } catch (err) {
73 logger.error('Cannot remove old image of actor %s.', actor.url, { err })
74 }
75
76 return actor
77}
78
d0800f76 79async function safeDeleteActorImage (actor: MActorImages, toDelete: MActorImage, type: ActorImageType, t: Transaction) {
80 try {
81 await toDelete.destroy({ transaction: t })
82
83 const association = buildAssociationName(type)
84 actor[association] = actor[association].filter(image => image.id !== toDelete.id)
85 } catch (err) {
86 logger.error('Cannot remove old actor image of actor %s.', actor.url, { err })
87 }
88}
89
136d7efd
C
90// ---------------------------------------------------------------------------
91
92export {
93 ImageInfo,
94
d0800f76 95 updateActorImages,
96 deleteActorImages
136d7efd
C
97}
98
99// ---------------------------------------------------------------------------
100
d0800f76 101function addActorImage (actor: MActorImages, type: ActorImageType, imageModel: MActorImage) {
102 const association = buildAssociationName(type)
103 if (!actor[association]) actor[association] = []
104
105 actor[association].push(imageModel)
106}
136d7efd 107
d0800f76 108function buildAssociationName (type: ActorImageType) {
109 return type === ActorImageType.AVATAR
110 ? 'Avatars'
111 : 'Banners'
136d7efd 112}