Browse Source

Fix announce activities

Chocobozzz 6 years ago
parent
commit
7acee6f18a

+ 2 - 5
server/controllers/activitypub/outbox.ts

@@ -43,21 +43,18 @@ async function outboxController (req: express.Request, res: express.Response, ne
   const followersMatrix = await ActorModel.getActorsFollowerSharedInboxUrls(actors, undefined)
 
   for (const video of data.data) {
-    const videoObject = video.toActivityPubObject()
-
     const byActor = video.VideoChannel.Account.Actor
     const createActivityAudience = buildAudience(followersMatrix[byActor.id])
 
     // This is a shared video
     if (video.VideoShares !== undefined && video.VideoShares.length !== 0) {
-      const createActivity = await createActivityData(video.url, byActor, videoObject, undefined, createActivityAudience)
-
       const announceAudience = buildAudience(followersMatrix[actor.id])
       const url = getAnnounceActivityPubUrl(video.url, actor)
-      const announceActivity = await announceActivityData(url, actor, createActivity, undefined, announceAudience)
+      const announceActivity = await announceActivityData(url, actor, video.url, undefined, announceAudience)
 
       activities.push(announceActivity)
     } else {
+      const videoObject = video.toActivityPubObject()
       const createActivity = await createActivityData(video.url, byActor, videoObject, undefined, createActivityAudience)
 
       activities.push(createActivity)

+ 2 - 3
server/helpers/custom-validators/activitypub/announce.ts

@@ -1,11 +1,10 @@
 import { isActivityPubUrlValid, isBaseActivityValid } from './misc'
-import { isVideoTorrentCreateActivityValid } from './videos'
 
 function isAnnounceActivityValid (activity: any) {
   return isBaseActivityValid(activity, 'Announce') &&
     (
-      isVideoTorrentCreateActivityValid(activity.object) ||
-      isActivityPubUrlValid(activity.object)
+      isActivityPubUrlValid(activity.object) ||
+      (activity.object && isActivityPubUrlValid(activity.object.id))
     )
 }
 

+ 4 - 22
server/lib/activitypub/process/process-announce.ts

@@ -1,6 +1,5 @@
 import { ActivityAnnounce } from '../../../../shared/models/activitypub'
 import { retryTransactionWrapper } from '../../../helpers/database-utils'
-import { logger } from '../../../helpers/logger'
 import { sequelizeTypescript } from '../../../initializers'
 import { ActorModel } from '../../../models/activitypub/actor'
 import { VideoModel } from '../../../models/video/video'
@@ -8,24 +7,11 @@ import { VideoShareModel } from '../../../models/video/video-share'
 import { getOrCreateActorAndServerAndModel } from '../actor'
 import { forwardActivity } from '../send/misc'
 import { getOrCreateAccountAndVideoAndChannel } from '../videos'
-import { processCreateActivity } from './process-create'
 
 async function processAnnounceActivity (activity: ActivityAnnounce) {
-  const announcedActivity = activity.object
   const actorAnnouncer = await getOrCreateActorAndServerAndModel(activity.actor)
 
-  if (typeof announcedActivity === 'string') {
-    return processVideoShare(actorAnnouncer, activity)
-  } else if (announcedActivity.type === 'Create' && announcedActivity.object.type === 'Video') {
-    return processVideoShare(actorAnnouncer, activity)
-  }
-
-  logger.warn(
-    'Unknown activity object type %s -> %s when announcing activity.', announcedActivity.type, announcedActivity.object.type,
-    { activity: activity.id }
-  )
-
-  return undefined
+  return processVideoShare(actorAnnouncer, activity)
 }
 
 // ---------------------------------------------------------------------------
@@ -46,15 +32,11 @@ function processVideoShare (actorAnnouncer: ActorModel, activity: ActivityAnnoun
 }
 
 async function shareVideo (actorAnnouncer: ActorModel, activity: ActivityAnnounce) {
-  const announced = activity.object
+  const objectUri = typeof activity.object === 'string' ? activity.object : activity.object.id
   let video: VideoModel
 
-  if (typeof announced === 'string') {
-    const res = await getOrCreateAccountAndVideoAndChannel(announced)
-    video = res.video
-  } else {
-    video = await processCreateActivity(announced)
-  }
+  const res = await getOrCreateAccountAndVideoAndChannel(objectUri)
+  video = res.video
 
   return sequelizeTypescript.transaction(async t => {
     // Add share entry

+ 2 - 53
server/lib/activitypub/process/process-create.ts

@@ -1,20 +1,17 @@
-import * as Bluebird from 'bluebird'
 import { ActivityCreate, VideoTorrentObject } from '../../../../shared'
 import { DislikeObject, VideoAbuseObject, ViewObject } from '../../../../shared/models/activitypub/objects'
 import { VideoCommentObject } from '../../../../shared/models/activitypub/objects/video-comment-object'
-import { VideoRateType } from '../../../../shared/models/videos'
 import { retryTransactionWrapper } from '../../../helpers/database-utils'
 import { logger } from '../../../helpers/logger'
 import { sequelizeTypescript } from '../../../initializers'
 import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
 import { ActorModel } from '../../../models/activitypub/actor'
-import { VideoModel } from '../../../models/video/video'
 import { VideoAbuseModel } from '../../../models/video/video-abuse'
 import { VideoCommentModel } from '../../../models/video/video-comment'
 import { getOrCreateActorAndServerAndModel } from '../actor'
 import { forwardActivity, getActorsInvolvedInVideo } from '../send/misc'
-import { addVideoComments, resolveThread } from '../video-comments'
-import { addVideoShares, getOrCreateAccountAndVideoAndChannel } from '../videos'
+import { resolveThread } from '../video-comments'
+import { getOrCreateAccountAndVideoAndChannel } from '../videos'
 
 async function processCreateActivity (activity: ActivityCreate) {
   const activityObject = activity.object
@@ -53,57 +50,9 @@ async function processCreateVideo (
 
   const { video } = await getOrCreateAccountAndVideoAndChannel(videoToCreateData, actor)
 
-  // Process outside the transaction because we could fetch remote data
-  if (videoToCreateData.likes && Array.isArray(videoToCreateData.likes.orderedItems)) {
-    logger.info('Adding likes of video %s.', video.uuid)
-    await createRates(videoToCreateData.likes.orderedItems, video, 'like')
-  }
-
-  if (videoToCreateData.dislikes && Array.isArray(videoToCreateData.dislikes.orderedItems)) {
-    logger.info('Adding dislikes of video %s.', video.uuid)
-    await createRates(videoToCreateData.dislikes.orderedItems, video, 'dislike')
-  }
-
-  if (videoToCreateData.shares && Array.isArray(videoToCreateData.shares.orderedItems)) {
-    logger.info('Adding shares of video %s.', video.uuid)
-    await addVideoShares(video, videoToCreateData.shares.orderedItems)
-  }
-
-  if (videoToCreateData.comments && Array.isArray(videoToCreateData.comments.orderedItems)) {
-    logger.info('Adding comments of video %s.', video.uuid)
-    await addVideoComments(video, videoToCreateData.comments.orderedItems)
-  }
-
   return video
 }
 
-async function createRates (actorUrls: string[], video: VideoModel, rate: VideoRateType) {
-  let rateCounts = 0
-  const tasks: Bluebird<number>[] = []
-
-  for (const actorUrl of actorUrls) {
-    const actor = await getOrCreateActorAndServerAndModel(actorUrl)
-    const p = AccountVideoRateModel
-      .create({
-        videoId: video.id,
-        accountId: actor.Account.id,
-        type: rate
-      })
-      .then(() => rateCounts += 1)
-
-    tasks.push(p)
-  }
-
-  await Promise.all(tasks)
-
-  logger.info('Adding %d %s to video %s.', rateCounts, rate, video.uuid)
-
-  // This is "likes" and "dislikes"
-  await video.increment(rate + 's', { by: rateCounts })
-
-  return
-}
-
 async function processCreateDislike (byActor: ActorModel, activity: ActivityCreate) {
   const options = {
     arguments: [ byActor, activity ],

+ 4 - 8
server/lib/activitypub/send/send-announce.ts

@@ -1,6 +1,5 @@
 import { Transaction } from 'sequelize'
-import { ActivityAnnounce, ActivityAudience, ActivityCreate } from '../../../../shared/models/activitypub'
-import { VideoPrivacy } from '../../../../shared/models/videos'
+import { ActivityAnnounce, ActivityAudience } from '../../../../shared/models/activitypub'
 import { ActorModel } from '../../../models/activitypub/actor'
 import { VideoModel } from '../../../models/video/video'
 import { getAnnounceActivityPubUrl } from '../url'
@@ -16,14 +15,11 @@ import { createActivityData } from './send-create'
 
 async function buildVideoAnnounceToFollowers (byActor: ActorModel, video: VideoModel, t: Transaction) {
   const url = getAnnounceActivityPubUrl(video.url, byActor)
-  const videoObject = video.toActivityPubObject()
-
-  const announcedAudience = await getAudience(byActor, t, video.privacy === VideoPrivacy.PUBLIC)
-  const announcedActivity = await createActivityData(url, video.VideoChannel.Account.Actor, videoObject, t, announcedAudience)
+  const announcedObject = video.url
 
   const accountsToForwardView = await getActorsInvolvedInVideo(video, t)
   const audience = getObjectFollowersAudience(accountsToForwardView)
-  return announceActivityData(url, byActor, announcedActivity, t, audience)
+  return announceActivityData(url, byActor, announcedObject, t, audience)
 }
 
 async function sendVideoAnnounceToFollowers (byActor: ActorModel, video: VideoModel, t: Transaction) {
@@ -48,7 +44,7 @@ async function sendVideoAnnounceToOrigin (byActor: ActorModel, video: VideoModel
 async function announceActivityData (
   url: string,
   byActor: ActorModel,
-  object: ActivityCreate,
+  object: string,
   t: Transaction,
   audience?: ActivityAudience
 ): Promise<ActivityAnnounce> {

+ 52 - 1
server/lib/activitypub/videos.ts

@@ -1,15 +1,17 @@
+import * as Bluebird from 'bluebird'
 import * as magnetUtil from 'magnet-uri'
 import { join } from 'path'
 import * as request from 'request'
 import { ActivityIconObject } from '../../../shared/index'
 import { VideoTorrentObject } from '../../../shared/models/activitypub/objects'
-import { VideoPrivacy } from '../../../shared/models/videos'
+import { VideoPrivacy, VideoRateType } from '../../../shared/models/videos'
 import { isVideoTorrentObjectValid } from '../../helpers/custom-validators/activitypub/videos'
 import { isVideoFileInfoHashValid } from '../../helpers/custom-validators/videos'
 import { retryTransactionWrapper } from '../../helpers/database-utils'
 import { logger } from '../../helpers/logger'
 import { doRequest, doRequestAndSaveToFile } from '../../helpers/requests'
 import { ACTIVITY_PUB, CONFIG, REMOTE_SCHEME, sequelizeTypescript, STATIC_PATHS, VIDEO_MIMETYPE_EXT } from '../../initializers'
+import { AccountVideoRateModel } from '../../models/account/account-video-rate'
 import { ActorModel } from '../../models/activitypub/actor'
 import { TagModel } from '../../models/video/tag'
 import { VideoModel } from '../../models/video/video'
@@ -17,6 +19,7 @@ import { VideoChannelModel } from '../../models/video/video-channel'
 import { VideoFileModel } from '../../models/video/video-file'
 import { VideoShareModel } from '../../models/video/video-share'
 import { getOrCreateActorAndServerAndModel } from './actor'
+import { addVideoComments } from './video-comments'
 
 function fetchRemoteVideoPreview (video: VideoModel, reject: Function) {
   const host = video.VideoChannel.Account.Actor.Server.host
@@ -210,9 +213,57 @@ async function getOrCreateAccountAndVideoAndChannel (videoObject: VideoTorrentOb
 
   const video = await retryTransactionWrapper(getOrCreateVideo, options)
 
+  // Process outside the transaction because we could fetch remote data
+  if (videoObject.likes && Array.isArray(videoObject.likes.orderedItems)) {
+    logger.info('Adding likes of video %s.', video.uuid)
+    await createRates(videoObject.likes.orderedItems, video, 'like')
+  }
+
+  if (videoObject.dislikes && Array.isArray(videoObject.dislikes.orderedItems)) {
+    logger.info('Adding dislikes of video %s.', video.uuid)
+    await createRates(videoObject.dislikes.orderedItems, video, 'dislike')
+  }
+
+  if (videoObject.shares && Array.isArray(videoObject.shares.orderedItems)) {
+    logger.info('Adding shares of video %s.', video.uuid)
+    await addVideoShares(video, videoObject.shares.orderedItems)
+  }
+
+  if (videoObject.comments && Array.isArray(videoObject.comments.orderedItems)) {
+    logger.info('Adding comments of video %s.', video.uuid)
+    await addVideoComments(video, videoObject.comments.orderedItems)
+  }
+
   return { actor, channelActor, video }
 }
 
+async function createRates (actorUrls: string[], video: VideoModel, rate: VideoRateType) {
+  let rateCounts = 0
+  const tasks: Bluebird<number>[] = []
+
+  for (const actorUrl of actorUrls) {
+    const actor = await getOrCreateActorAndServerAndModel(actorUrl)
+    const p = AccountVideoRateModel
+      .create({
+        videoId: video.id,
+        accountId: actor.Account.id,
+        type: rate
+      })
+      .then(() => rateCounts += 1)
+
+    tasks.push(p)
+  }
+
+  await Promise.all(tasks)
+
+  logger.info('Adding %d %s to video %s.', rateCounts, rate, video.uuid)
+
+  // This is "likes" and "dislikes"
+  await video.increment(rate + 's', { by: rateCounts })
+
+  return
+}
+
 async function addVideoShares (instance: VideoModel, shareUrls: string[]) {
   for (const shareUrl of shareUrls) {
     // Fetch url

+ 1 - 1
shared/models/activitypub/activity.ts

@@ -59,7 +59,7 @@ export interface ActivityReject extends BaseActivity {
 
 export interface ActivityAnnounce extends BaseActivity {
   type: 'Announce'
-  object: ActivityCreate | string
+  object: string | { id: string }
 }
 
 export interface ActivityUndo extends BaseActivity {