]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/lib/activitypub/process/process-create.ts
Federate video views
[github/Chocobozzz/PeerTube.git] / server / lib / activitypub / process / process-create.ts
1 import { ActivityCreate, VideoChannelObject } from '../../../../shared'
2 import { VideoAbuseObject } from '../../../../shared/models/activitypub/objects/video-abuse-object'
3 import { ViewObject } from '../../../../shared/models/activitypub/objects/view-object'
4 import { logger, retryTransactionWrapper } from '../../../helpers'
5 import { database as db } from '../../../initializers'
6 import { AccountInstance } from '../../../models/account/account-interface'
7 import { getOrCreateAccountAndServer } from '../account'
8 import { sendCreateViewToVideoFollowers } from '../send/send-create'
9 import { getVideoChannelActivityPubUrl } from '../url'
10 import { videoChannelActivityObjectToDBAttributes } from './misc'
11
12 async function processCreateActivity (activity: ActivityCreate) {
13 const activityObject = activity.object
14 const activityType = activityObject.type
15 const account = await getOrCreateAccountAndServer(activity.actor)
16
17 if (activityType === 'View') {
18 return processCreateView(activityObject as ViewObject)
19 } else if (activityType === 'VideoChannel') {
20 return processCreateVideoChannel(account, activityObject as VideoChannelObject)
21 } else if (activityType === 'Flag') {
22 return processCreateVideoAbuse(account, activityObject as VideoAbuseObject)
23 }
24
25 logger.warn('Unknown activity object type %s when creating activity.', activityType, { activity: activity.id })
26 return Promise.resolve(undefined)
27 }
28
29 // ---------------------------------------------------------------------------
30
31 export {
32 processCreateActivity
33 }
34
35 // ---------------------------------------------------------------------------
36
37 async function processCreateView (view: ViewObject) {
38 const video = await db.Video.loadByUrlAndPopulateAccount(view.object)
39
40 if (!video) throw new Error('Unknown video ' + view.object)
41
42 const account = await db.Account.loadByUrl(view.actor)
43 if (!account) throw new Error('Unknown account ' + view.actor)
44
45 await video.increment('views')
46
47 if (video.isOwned()) await sendCreateViewToVideoFollowers(account, video, undefined)
48 }
49
50 function processCreateVideoChannel (account: AccountInstance, videoChannelToCreateData: VideoChannelObject) {
51 const options = {
52 arguments: [ account, videoChannelToCreateData ],
53 errorMessage: 'Cannot insert the remote video channel with many retries.'
54 }
55
56 return retryTransactionWrapper(addRemoteVideoChannel, options)
57 }
58
59 function addRemoteVideoChannel (account: AccountInstance, videoChannelToCreateData: VideoChannelObject) {
60 logger.debug('Adding remote video channel "%s".', videoChannelToCreateData.uuid)
61
62 return db.sequelize.transaction(async t => {
63 let videoChannel = await db.VideoChannel.loadByUUIDOrUrl(videoChannelToCreateData.uuid, videoChannelToCreateData.id, t)
64 if (videoChannel) throw new Error('Video channel with this URL/UUID already exists.')
65
66 const videoChannelData = videoChannelActivityObjectToDBAttributes(videoChannelToCreateData, account)
67 videoChannel = db.VideoChannel.build(videoChannelData)
68 videoChannel.url = getVideoChannelActivityPubUrl(videoChannel)
69
70 videoChannel = await videoChannel.save({ transaction: t })
71 logger.info('Remote video channel with uuid %s inserted.', videoChannelToCreateData.uuid)
72
73 return videoChannel
74 })
75 }
76
77 function processCreateVideoAbuse (account: AccountInstance, videoAbuseToCreateData: VideoAbuseObject) {
78 const options = {
79 arguments: [ account, videoAbuseToCreateData ],
80 errorMessage: 'Cannot insert the remote video abuse with many retries.'
81 }
82
83 return retryTransactionWrapper(addRemoteVideoAbuse, options)
84 }
85
86 function addRemoteVideoAbuse (account: AccountInstance, videoAbuseToCreateData: VideoAbuseObject) {
87 logger.debug('Reporting remote abuse for video %s.', videoAbuseToCreateData.object)
88
89 return db.sequelize.transaction(async t => {
90 const video = await db.Video.loadByUrlAndPopulateAccount(videoAbuseToCreateData.object, t)
91 if (!video) {
92 logger.warn('Unknown video %s for remote video abuse.', videoAbuseToCreateData.object)
93 return undefined
94 }
95
96 const videoAbuseData = {
97 reporterAccountId: account.id,
98 reason: videoAbuseToCreateData.content,
99 videoId: video.id
100 }
101
102 await db.VideoAbuse.create(videoAbuseData)
103
104 logger.info('Remote abuse for video uuid %s created', videoAbuseToCreateData.object)
105 })
106 }