Refractor comment creation from federation
[oweals/peertube.git] / server / lib / activitypub / video-rates.ts
1 import { Transaction } from 'sequelize'
2 import { AccountModel } from '../../models/account/account'
3 import { VideoModel } from '../../models/video/video'
4 import { sendCreateDislike, sendLike, sendUndoDislike, sendUndoLike } from './send'
5 import { VideoRateType } from '../../../shared/models/videos'
6 import * as Bluebird from 'bluebird'
7 import { getOrCreateActorAndServerAndModel } from './actor'
8 import { AccountVideoRateModel } from '../../models/account/account-video-rate'
9 import { logger } from '../../helpers/logger'
10 import { CRAWL_REQUEST_CONCURRENCY } from '../../initializers'
11
12 async function createRates (actorUrls: string[], video: VideoModel, rate: VideoRateType) {
13   let rateCounts = 0
14
15   await Bluebird.map(actorUrls, async actorUrl => {
16     try {
17       const actor = await getOrCreateActorAndServerAndModel(actorUrl)
18       const [ , created ] = await AccountVideoRateModel
19         .findOrCreate({
20           where: {
21             videoId: video.id,
22             accountId: actor.Account.id
23           },
24           defaults: {
25             videoId: video.id,
26             accountId: actor.Account.id,
27             type: rate
28           }
29         })
30
31       if (created) rateCounts += 1
32     } catch (err) {
33       logger.warn('Cannot add rate %s for actor %s.', rate, actorUrl, { err })
34     }
35   }, { concurrency: CRAWL_REQUEST_CONCURRENCY })
36
37   logger.info('Adding %d %s to video %s.', rateCounts, rate, video.uuid)
38
39   // This is "likes" and "dislikes"
40   if (rateCounts !== 0) await video.increment(rate + 's', { by: rateCounts })
41
42   return
43 }
44
45 async function sendVideoRateChange (account: AccountModel,
46                               video: VideoModel,
47                               likes: number,
48                               dislikes: number,
49                               t: Transaction) {
50   const actor = account.Actor
51
52   // Keep the order: first we undo and then we create
53
54   // Undo Like
55   if (likes < 0) await sendUndoLike(actor, video, t)
56   // Undo Dislike
57   if (dislikes < 0) await sendUndoDislike(actor, video, t)
58
59   // Like
60   if (likes > 0) await sendLike(actor, video, t)
61   // Dislike
62   if (dislikes > 0) await sendCreateDislike(actor, video, t)
63 }
64
65 export {
66   createRates,
67   sendVideoRateChange
68 }