-import { ActivityLike } from '../../../../shared/models/activitypub/activity'
-import { database as db } from '../../../initializers'
-import { AccountInstance } from '../../../models/account/account-interface'
-import { getOrCreateAccountAndServer } from '../account'
-import { sendLikeToVideoFollowers } from '../send/send-like'
+import { ActivityLike } from '../../../../shared/models/activitypub'
import { retryTransactionWrapper } from '../../../helpers/database-utils'
+import { sequelizeTypescript } from '../../../initializers'
+import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
+import { ActorModel } from '../../../models/activitypub/actor'
+import { getOrCreateActorAndServerAndModel } from '../actor'
+import { forwardActivity, forwardVideoRelatedActivity } from '../send/utils'
+import { getOrCreateAccountAndVideoAndChannel } from '../videos'
+import { getActorsInvolvedInVideo } from '../audience'
async function processLikeActivity (activity: ActivityLike) {
- const account = await getOrCreateAccountAndServer(activity.actor)
+ const actor = await getOrCreateActorAndServerAndModel(activity.actor)
- return processLikeVideo(account, activity.object)
+ return processLikeVideo(actor, activity)
}
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
-async function processLikeVideo (byAccount: AccountInstance, videoUrl: string) {
+async function processLikeVideo (actor: ActorModel, activity: ActivityLike) {
const options = {
- arguments: [ byAccount, videoUrl ],
+ arguments: [ actor, activity ],
errorMessage: 'Cannot like the video with many retries.'
}
return retryTransactionWrapper(createVideoLike, options)
}
-function createVideoLike (byAccount: AccountInstance, videoUrl: string) {
- return db.sequelize.transaction(async t => {
- const video = await db.Video.loadByUrlAndPopulateAccount(videoUrl)
+async function createVideoLike (byActor: ActorModel, activity: ActivityLike) {
+ const videoUrl = activity.object
- if (!video) throw new Error('Unknown video ' + videoUrl)
+ const byAccount = byActor.Account
+ if (!byAccount) throw new Error('Cannot create like with the non account actor ' + byActor.url)
+ const { video } = await getOrCreateAccountAndVideoAndChannel(videoUrl)
+
+ return sequelizeTypescript.transaction(async t => {
const rate = {
type: 'like' as 'like',
videoId: video.id,
accountId: byAccount.id
}
- const [ , created ] = await db.AccountVideoRate.findOrCreate({
+ const [ , created ] = await AccountVideoRateModel.findOrCreate({
where: rate,
- defaults: rate
+ defaults: rate,
+ transaction: t
})
- await video.increment('likes')
+ if (created === true) await video.increment('likes', { transaction: t })
+
+ if (video.isOwned() && created === true) {
+ // Don't resend the activity to the sender
+ const exceptions = [ byActor ]
- if (video.isOwned() && created === true) await sendLikeToVideoFollowers(byAccount, video, undefined)
+ await forwardVideoRelatedActivity(activity, t, exceptions, video)
+ }
})
}