aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/lib/activitypub/process
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2022-03-24 13:36:47 +0100
committerChocobozzz <chocobozzz@cpy.re>2022-04-15 09:49:35 +0200
commitb211106695bb82f6c32e53306081b5262c3d109d (patch)
treefa187de1c33b0956665f5362e29af6b0f6d8bb57 /server/lib/activitypub/process
parent69d48ee30c9d47cddf0c3c047dc99a99dcb6e894 (diff)
downloadPeerTube-b211106695bb82f6c32e53306081b5262c3d109d.tar.gz
PeerTube-b211106695bb82f6c32e53306081b5262c3d109d.tar.zst
PeerTube-b211106695bb82f6c32e53306081b5262c3d109d.zip
Support video views/viewers stats in server
* Add "currentTime" and "event" body params to view endpoint * Merge watching and view endpoints * Introduce WatchAction AP activity * Add tables to store viewer information of local videos * Add endpoints to fetch video views/viewers stats of local videos * Refactor views/viewers handlers * Support "views" and "viewers" counters for both VOD and live videos
Diffstat (limited to 'server/lib/activitypub/process')
-rw-r--r--server/lib/activitypub/process/process-create.ts21
-rw-r--r--server/lib/activitypub/process/process-view.ts4
2 files changed, 22 insertions, 3 deletions
diff --git a/server/lib/activitypub/process/process-create.ts b/server/lib/activitypub/process/process-create.ts
index b5b1a0feb..3e7931bb2 100644
--- a/server/lib/activitypub/process/process-create.ts
+++ b/server/lib/activitypub/process/process-create.ts
@@ -1,6 +1,7 @@
1import { isBlockedByServerOrAccount } from '@server/lib/blocklist' 1import { isBlockedByServerOrAccount } from '@server/lib/blocklist'
2import { isRedundancyAccepted } from '@server/lib/redundancy' 2import { isRedundancyAccepted } from '@server/lib/redundancy'
3import { ActivityCreate, CacheFileObject, PlaylistObject, VideoCommentObject, VideoObject } from '@shared/models' 3import { VideoModel } from '@server/models/video/video'
4import { ActivityCreate, CacheFileObject, PlaylistObject, VideoCommentObject, VideoObject, WatchActionObject } from '@shared/models'
4import { retryTransactionWrapper } from '../../../helpers/database-utils' 5import { retryTransactionWrapper } from '../../../helpers/database-utils'
5import { logger } from '../../../helpers/logger' 6import { logger } from '../../../helpers/logger'
6import { sequelizeTypescript } from '../../../initializers/database' 7import { sequelizeTypescript } from '../../../initializers/database'
@@ -8,6 +9,7 @@ import { APProcessorOptions } from '../../../types/activitypub-processor.model'
8import { MActorSignature, MCommentOwnerVideo, MVideoAccountLightBlacklistAllFiles } from '../../../types/models' 9import { MActorSignature, MCommentOwnerVideo, MVideoAccountLightBlacklistAllFiles } from '../../../types/models'
9import { Notifier } from '../../notifier' 10import { Notifier } from '../../notifier'
10import { createOrUpdateCacheFile } from '../cache-file' 11import { createOrUpdateCacheFile } from '../cache-file'
12import { createOrUpdateLocalVideoViewer } from '../local-video-viewer'
11import { createOrUpdateVideoPlaylist } from '../playlists' 13import { createOrUpdateVideoPlaylist } from '../playlists'
12import { forwardVideoRelatedActivity } from '../send/shared/send-utils' 14import { forwardVideoRelatedActivity } from '../send/shared/send-utils'
13import { resolveThread } from '../video-comments' 15import { resolveThread } from '../video-comments'
@@ -32,6 +34,10 @@ async function processCreateActivity (options: APProcessorOptions<ActivityCreate
32 return retryTransactionWrapper(processCreateVideoComment, activity, byActor, notify) 34 return retryTransactionWrapper(processCreateVideoComment, activity, byActor, notify)
33 } 35 }
34 36
37 if (activityType === 'WatchAction') {
38 return retryTransactionWrapper(processCreateWatchAction, activity)
39 }
40
35 if (activityType === 'CacheFile') { 41 if (activityType === 'CacheFile') {
36 return retryTransactionWrapper(processCreateCacheFile, activity, byActor) 42 return retryTransactionWrapper(processCreateCacheFile, activity, byActor)
37 } 43 }
@@ -81,6 +87,19 @@ async function processCreateCacheFile (activity: ActivityCreate, byActor: MActor
81 } 87 }
82} 88}
83 89
90async function processCreateWatchAction (activity: ActivityCreate) {
91 const watchAction = activity.object as WatchActionObject
92
93 if (watchAction.actionStatus !== 'CompletedActionStatus') return
94
95 const video = await VideoModel.loadByUrl(watchAction.object)
96 if (video.remote) return
97
98 await sequelizeTypescript.transaction(async t => {
99 return createOrUpdateLocalVideoViewer(watchAction, video, t)
100 })
101}
102
84async function processCreateVideoComment (activity: ActivityCreate, byActor: MActorSignature, notify: boolean) { 103async function processCreateVideoComment (activity: ActivityCreate, byActor: MActorSignature, notify: boolean) {
85 const commentObject = activity.object as VideoCommentObject 104 const commentObject = activity.object as VideoCommentObject
86 const byAccount = byActor.Account 105 const byAccount = byActor.Account
diff --git a/server/lib/activitypub/process/process-view.ts b/server/lib/activitypub/process/process-view.ts
index c59940164..bad079843 100644
--- a/server/lib/activitypub/process/process-view.ts
+++ b/server/lib/activitypub/process/process-view.ts
@@ -1,4 +1,4 @@
1import { VideoViews } from '@server/lib/video-views' 1import { VideoViewsManager } from '@server/lib/views/video-views-manager'
2import { ActivityView } from '../../../../shared/models/activitypub' 2import { ActivityView } from '../../../../shared/models/activitypub'
3import { APProcessorOptions } from '../../../types/activitypub-processor.model' 3import { APProcessorOptions } from '../../../types/activitypub-processor.model'
4import { MActorSignature } from '../../../types/models' 4import { MActorSignature } from '../../../types/models'
@@ -32,7 +32,7 @@ async function processCreateView (activity: ActivityView, byActor: MActorSignatu
32 ? new Date(activity.expires) 32 ? new Date(activity.expires)
33 : undefined 33 : undefined
34 34
35 await VideoViews.Instance.processView({ video, ip: null, viewerExpires }) 35 await VideoViewsManager.Instance.processRemoteView({ video, viewerExpires })
36 36
37 if (video.isOwned()) { 37 if (video.isOwned()) {
38 // Forward the view but don't resend the activity to the sender 38 // Forward the view but don't resend the activity to the sender