Merge branch 'release/v1.0.0' into develop
[oweals/peertube.git] / server / lib / activitypub / process / process-like.ts
1 import { ActivityLike } from '../../../../shared/models/activitypub'
2 import { retryTransactionWrapper } from '../../../helpers/database-utils'
3 import { sequelizeTypescript } from '../../../initializers'
4 import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
5 import { ActorModel } from '../../../models/activitypub/actor'
6 import { forwardVideoRelatedActivity } from '../send/utils'
7 import { getOrCreateVideoAndAccountAndChannel } from '../videos'
8
9 async function processLikeActivity (activity: ActivityLike, byActor: ActorModel) {
10   return retryTransactionWrapper(processLikeVideo, byActor, activity)
11 }
12
13 // ---------------------------------------------------------------------------
14
15 export {
16   processLikeActivity
17 }
18
19 // ---------------------------------------------------------------------------
20
21 async function processLikeVideo (byActor: ActorModel, activity: ActivityLike) {
22   const videoUrl = activity.object
23
24   const byAccount = byActor.Account
25   if (!byAccount) throw new Error('Cannot create like with the non account actor ' + byActor.url)
26
27   const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: videoUrl })
28
29   return sequelizeTypescript.transaction(async t => {
30     const rate = {
31       type: 'like' as 'like',
32       videoId: video.id,
33       accountId: byAccount.id
34     }
35     const [ , created ] = await AccountVideoRateModel.findOrCreate({
36       where: rate,
37       defaults: rate,
38       transaction: t
39     })
40     if (created === true) await video.increment('likes', { transaction: t })
41
42     if (video.isOwned() && created === true) {
43       // Don't resend the activity to the sender
44       const exceptions = [ byActor ]
45
46       await forwardVideoRelatedActivity(activity, t, exceptions, video)
47     }
48   })
49 }