]>
Commit | Line | Data |
---|---|---|
28dfb44b | 1 | import { resetSequelizeInstance, runInReadCommittedTransaction } from '@server/helpers/database-utils' |
136d7efd | 2 | import { logger } from '@server/helpers/logger' |
b5e1cd9a | 3 | import { AccountModel } from '@server/models/account/account' |
136d7efd C |
4 | import { VideoChannelModel } from '@server/models/video/video-channel' |
5 | import { MAccount, MActor, MActorFull, MChannel } from '@server/types/models' | |
6 | import { ActivityPubActor, ActorImageType } from '@shared/models' | |
b5e1cd9a | 7 | import { getOrCreateAPOwner } from './get' |
d0800f76 | 8 | import { updateActorImages } from './image' |
136d7efd | 9 | import { fetchActorFollowsCount } from './shared' |
d0800f76 | 10 | import { getImagesInfoFromObject } from './shared/object-to-model-attributes' |
136d7efd C |
11 | |
12 | export class APActorUpdater { | |
13 | ||
14 | private accountOrChannel: MAccount | MChannel | |
15 | ||
16 | private readonly actorFieldsSave: object | |
17 | private readonly accountOrChannelFieldsSave: object | |
18 | ||
19 | constructor ( | |
20 | private readonly actorObject: ActivityPubActor, | |
21 | private readonly actor: MActorFull | |
22 | ) { | |
23 | this.actorFieldsSave = this.actor.toJSON() | |
24 | ||
25 | if (this.actorObject.type === 'Group') this.accountOrChannel = this.actor.VideoChannel | |
26 | else this.accountOrChannel = this.actor.Account | |
27 | ||
28 | this.accountOrChannelFieldsSave = this.accountOrChannel.toJSON() | |
29 | } | |
30 | ||
31 | async update () { | |
d0800f76 | 32 | const avatarsInfo = getImagesInfoFromObject(this.actorObject, ActorImageType.AVATAR) |
33 | const bannersInfo = getImagesInfoFromObject(this.actorObject, ActorImageType.BANNER) | |
136d7efd C |
34 | |
35 | try { | |
28dfb44b | 36 | await this.updateActorInstance(this.actor, this.actorObject) |
136d7efd | 37 | |
28dfb44b C |
38 | this.accountOrChannel.name = this.actorObject.name || this.actorObject.preferredUsername |
39 | this.accountOrChannel.description = this.actorObject.summary | |
136d7efd | 40 | |
b5e1cd9a C |
41 | if (this.accountOrChannel instanceof VideoChannelModel) { |
42 | const owner = await getOrCreateAPOwner(this.actorObject, this.actorObject.url) | |
43 | this.accountOrChannel.accountId = owner.Account.id | |
44 | this.accountOrChannel.Account = owner.Account as AccountModel | |
45 | ||
46 | this.accountOrChannel.support = this.actorObject.support | |
47 | } | |
136d7efd | 48 | |
28dfb44b | 49 | await runInReadCommittedTransaction(async t => { |
d0800f76 | 50 | await updateActorImages(this.actor, ActorImageType.BANNER, bannersInfo, t) |
51 | await updateActorImages(this.actor, ActorImageType.AVATAR, avatarsInfo, t) | |
136d7efd C |
52 | }) |
53 | ||
28dfb44b | 54 | await runInReadCommittedTransaction(async t => { |
bbfdeb39 C |
55 | await this.actor.save({ transaction: t }) |
56 | await this.accountOrChannel.save({ transaction: t }) | |
28dfb44b C |
57 | }) |
58 | ||
136d7efd C |
59 | logger.info('Remote account %s updated', this.actorObject.url) |
60 | } catch (err) { | |
61 | if (this.actor !== undefined && this.actorFieldsSave !== undefined) { | |
62 | resetSequelizeInstance(this.actor, this.actorFieldsSave) | |
63 | } | |
64 | ||
65 | if (this.accountOrChannel !== undefined && this.accountOrChannelFieldsSave !== undefined) { | |
66 | resetSequelizeInstance(this.accountOrChannel, this.accountOrChannelFieldsSave) | |
67 | } | |
68 | ||
69 | // This is just a debug because we will retry the insert | |
70 | logger.debug('Cannot update the remote account.', { err }) | |
71 | throw err | |
72 | } | |
73 | } | |
74 | ||
75 | private async updateActorInstance (actorInstance: MActor, actorObject: ActivityPubActor) { | |
76 | const { followersCount, followingCount } = await fetchActorFollowsCount(actorObject) | |
77 | ||
78 | actorInstance.type = actorObject.type | |
79 | actorInstance.preferredUsername = actorObject.preferredUsername | |
80 | actorInstance.url = actorObject.id | |
81 | actorInstance.publicKey = actorObject.publicKey.publicKeyPem | |
82 | actorInstance.followersCount = followersCount | |
83 | actorInstance.followingCount = followingCount | |
84 | actorInstance.inboxUrl = actorObject.inbox | |
85 | actorInstance.outboxUrl = actorObject.outbox | |
86 | actorInstance.followersUrl = actorObject.followers | |
87 | actorInstance.followingUrl = actorObject.following | |
88 | ||
89 | if (actorObject.published) actorInstance.remoteCreatedAt = new Date(actorObject.published) | |
90 | ||
91 | if (actorObject.endpoints?.sharedInbox) { | |
92 | actorInstance.sharedInboxUrl = actorObject.endpoints.sharedInbox | |
93 | } | |
94 | ||
95 | // Force actor update | |
96 | actorInstance.changed('updatedAt', true) | |
97 | } | |
98 | } |