diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts index b659f53ed..3d1b2e1a2 100644 --- a/server/controllers/api/videos/index.ts +++ b/server/controllers/api/videos/index.ts @@ -411,12 +411,7 @@ async function viewVideo (req: express.Request, res: express.Response) { ]) const serverActor = await getServerActor() - - // Send the event to the origin server - // If we own the video, we'll send an update event when we'll process the views (in our job queue) - if (videoInstance.isOwned() === false) { - await sendCreateView(serverActor, videoInstance, undefined) - } + await sendCreateView(serverActor, videoInstance, undefined) return res.status(204).end() } diff --git a/server/lib/activitypub/process/process-create.ts b/server/lib/activitypub/process/process-create.ts index f7fb09fba..cd7ea01aa 100644 --- a/server/lib/activitypub/process/process-create.ts +++ b/server/lib/activitypub/process/process-create.ts @@ -87,10 +87,19 @@ async function processCreateDislike (byActor: ActorModel, activity: ActivityCrea async function processCreateView (byActor: ActorModel, activity: ActivityCreate) { const view = activity.object as ViewObject - const video = await VideoModel.loadByUrl(view.object) - if (!video || video.isOwned() === false) return + const options = { + videoObject: view.object, + fetchType: 'only-video' as 'only-video' + } + const { video } = await getOrCreateVideoAndAccountAndChannel(options) await Redis.Instance.addVideoView(video.id) + + if (video.isOwned()) { + // Don't resend the activity to the sender + const exceptions = [ byActor ] + await forwardVideoRelatedActivity(activity, undefined, exceptions, video) + } } async function processCacheFile (byActor: ActorModel, activity: ActivityCreate) { diff --git a/server/lib/job-queue/handlers/video-views.ts b/server/lib/job-queue/handlers/video-views.ts index f44c3c727..038ef43e2 100644 --- a/server/lib/job-queue/handlers/video-views.ts +++ b/server/lib/job-queue/handlers/video-views.ts @@ -24,12 +24,10 @@ async function processVideosViews () { try { const views = await Redis.Instance.getVideoViews(videoId, hour) if (isNaN(views)) { - logger.error('Cannot process videos views of video %d in hour %d: views number is NaN.', videoId, hour) + logger.error('Cannot process videos views of video %d in hour %d: views number is NaN (%s).', videoId, hour, views) } else { logger.debug('Adding %d views to video %d in hour %d.', views, videoId, hour) - await VideoModel.incrementViews(videoId, views) - try { await VideoViewModel.create({ startDate, @@ -39,7 +37,14 @@ async function processVideosViews () { }) const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(videoId) - if (video.isOwned()) await federateVideoIfNeeded(video, false) + if (video.isOwned()) { + // If this is a remote video, the origin instance will send us an update + await VideoModel.incrementViews(videoId, views) + + // Send video update + video.views += views + await federateVideoIfNeeded(video, false) + } } catch (err) { logger.debug('Cannot create video views for video %d in hour %d. Maybe the video does not exist anymore?', videoId, hour) }