]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/lib/activitypub/process/process-create.ts
Bumped to version v1.0.0-beta.13
[github/Chocobozzz/PeerTube.git] / server / lib / activitypub / process / process-create.ts
CommitLineData
268eebed 1import { ActivityCreate, VideoAbuseState, VideoTorrentObject } from '../../../../shared'
3fd3ab2d 2import { DislikeObject, VideoAbuseObject, ViewObject } from '../../../../shared/models/activitypub/objects'
6d852470 3import { VideoCommentObject } from '../../../../shared/models/activitypub/objects/video-comment-object'
da854ddd
C
4import { retryTransactionWrapper } from '../../../helpers/database-utils'
5import { logger } from '../../../helpers/logger'
3fd3ab2d 6import { sequelizeTypescript } from '../../../initializers'
3fd3ab2d 7import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
50d6de9c 8import { ActorModel } from '../../../models/activitypub/actor'
3fd3ab2d 9import { VideoAbuseModel } from '../../../models/video/video-abuse'
50d6de9c 10import { getOrCreateActorAndServerAndModel } from '../actor'
83e6519b 11import { addVideoComment, resolveThread } from '../video-comments'
1297eb5d 12import { getOrCreateVideoAndAccountAndChannel } from '../videos'
9588d4f4 13import { forwardActivity, forwardVideoRelatedActivity } from '../send/utils'
6b616860 14import { Redis } from '../../redis'
e4f97bab 15
0d0e8dd0 16async function processCreateActivity (activity: ActivityCreate) {
e4f97bab
C
17 const activityObject = activity.object
18 const activityType = activityObject.type
50d6de9c 19 const actor = await getOrCreateActorAndServerAndModel(activity.actor)
e4f97bab 20
40ff5707 21 if (activityType === 'View') {
50d6de9c 22 return processCreateView(actor, activity)
0032ebe9 23 } else if (activityType === 'Dislike') {
90d4bb81 24 return retryTransactionWrapper(processCreateDislike, actor, activity)
50d6de9c 25 } else if (activityType === 'Video') {
f6eebcb3 26 return processCreateVideo(activity)
8e13fa7d 27 } else if (activityType === 'Flag') {
90d4bb81 28 return retryTransactionWrapper(processCreateVideoAbuse, actor, activityObject as VideoAbuseObject)
6d852470 29 } else if (activityType === 'Note') {
90d4bb81 30 return retryTransactionWrapper(processCreateVideoComment, actor, activity)
e4f97bab
C
31 }
32
33 logger.warn('Unknown activity object type %s when creating activity.', activityType, { activity: activity.id })
0d0e8dd0 34 return Promise.resolve(undefined)
e4f97bab
C
35}
36
37// ---------------------------------------------------------------------------
38
39export {
40 processCreateActivity
41}
42
43// ---------------------------------------------------------------------------
44
f6eebcb3 45async function processCreateVideo (activity: ActivityCreate) {
50d6de9c
C
46 const videoToCreateData = activity.object as VideoTorrentObject
47
1297eb5d 48 const { video } = await getOrCreateVideoAndAccountAndChannel(videoToCreateData)
50d6de9c 49
50d6de9c
C
50 return video
51}
52
50d6de9c 53async function processCreateDislike (byActor: ActorModel, activity: ActivityCreate) {
63c93323 54 const dislike = activity.object as DislikeObject
50d6de9c
C
55 const byAccount = byActor.Account
56
57 if (!byAccount) throw new Error('Cannot create dislike with the non account actor ' + byActor.url)
0032ebe9 58
1297eb5d 59 const { video } = await getOrCreateVideoAndAccountAndChannel(dislike.object)
0032ebe9 60
2ccaeeb3 61 return sequelizeTypescript.transaction(async t => {
0032ebe9
C
62 const rate = {
63 type: 'dislike' as 'dislike',
64 videoId: video.id,
65 accountId: byAccount.id
66 }
3fd3ab2d 67 const [ , created ] = await AccountVideoRateModel.findOrCreate({
0032ebe9 68 where: rate,
63c93323
C
69 defaults: rate,
70 transaction: t
0032ebe9 71 })
f00984c0 72 if (created === true) await video.increment('dislikes', { transaction: t })
0032ebe9 73
63c93323
C
74 if (video.isOwned() && created === true) {
75 // Don't resend the activity to the sender
50d6de9c 76 const exceptions = [ byActor ]
9588d4f4
C
77
78 await forwardVideoRelatedActivity(activity, t, exceptions, video)
63c93323 79 }
0032ebe9
C
80 })
81}
82
6d852470 83async function processCreateView (byActor: ActorModel, activity: ActivityCreate) {
63c93323
C
84 const view = activity.object as ViewObject
85
1297eb5d 86 const { video } = await getOrCreateVideoAndAccountAndChannel(view.object)
40ff5707 87
7bc29171
C
88 const actor = await ActorModel.loadByUrl(view.actor)
89 if (!actor) throw new Error('Unknown actor ' + view.actor)
40ff5707 90
6b616860 91 await Redis.Instance.addVideoView(video.id)
40ff5707 92
63c93323
C
93 if (video.isOwned()) {
94 // Don't resend the activity to the sender
6d852470 95 const exceptions = [ byActor ]
63c93323
C
96 await forwardActivity(activity, undefined, exceptions)
97 }
40ff5707
C
98}
99
90d4bb81 100async function processCreateVideoAbuse (actor: ActorModel, videoAbuseToCreateData: VideoAbuseObject) {
8e13fa7d
C
101 logger.debug('Reporting remote abuse for video %s.', videoAbuseToCreateData.object)
102
50d6de9c
C
103 const account = actor.Account
104 if (!account) throw new Error('Cannot create dislike with the non account actor ' + actor.url)
105
1297eb5d 106 const { video } = await getOrCreateVideoAndAccountAndChannel(videoAbuseToCreateData.object)
8e13fa7d 107
2ccaeeb3 108 return sequelizeTypescript.transaction(async t => {
8e13fa7d
C
109 const videoAbuseData = {
110 reporterAccountId: account.id,
111 reason: videoAbuseToCreateData.content,
268eebed
C
112 videoId: video.id,
113 state: VideoAbuseState.PENDING
8e13fa7d
C
114 }
115
3fd3ab2d 116 await VideoAbuseModel.create(videoAbuseData)
8e13fa7d
C
117
118 logger.info('Remote abuse for video uuid %s created', videoAbuseToCreateData.object)
119 })
120}
6d852470 121
90d4bb81 122async function processCreateVideoComment (byActor: ActorModel, activity: ActivityCreate) {
83e6519b 123 const commentObject = activity.object as VideoCommentObject
6d852470
C
124 const byAccount = byActor.Account
125
126 if (!byAccount) throw new Error('Cannot create video comment with the non account actor ' + byActor.url)
127
83e6519b 128 const { video } = await resolveThread(commentObject.inReplyTo)
2ccaeeb3 129
83e6519b 130 const { created } = await addVideoComment(video, commentObject.id)
93ef8a9d 131
83e6519b
C
132 if (video.isOwned() && created === true) {
133 // Don't resend the activity to the sender
134 const exceptions = [ byActor ]
93ef8a9d 135
83e6519b
C
136 await forwardVideoRelatedActivity(activity, undefined, exceptions, video)
137 }
6d852470 138}