Refractor activities sending

This commit is contained in:
Chocobozzz 2018-09-14 16:51:35 +02:00
parent d61b817890
commit a2377d15ee
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
11 changed files with 140 additions and 155 deletions

View File

@ -393,9 +393,9 @@ async function viewVideo (req: express.Request, res: express.Response) {
Redis.Instance.setIPVideoView(ip, videoInstance.uuid) Redis.Instance.setIPVideoView(ip, videoInstance.uuid)
]) ])
const serverAccount = await getServerActor() const serverActor = await getServerActor()
await sendCreateView(serverAccount, videoInstance, undefined) await sendCreateView(serverActor, videoInstance, undefined)
return res.status(204).end() return res.status(204).end()
} }

View File

@ -6,7 +6,7 @@ import { VideoModel } from '../../models/video/video'
import { VideoCommentModel } from '../../models/video/video-comment' import { VideoCommentModel } from '../../models/video/video-comment'
import { VideoShareModel } from '../../models/video/video-share' import { VideoShareModel } from '../../models/video/video-share'
function getVideoAudience (video: VideoModel, actorsInvolvedInVideo: ActorModel[]) { function getRemoteVideoAudience (video: VideoModel, actorsInvolvedInVideo: ActorModel[]): ActivityAudience {
return { return {
to: [ video.VideoChannel.Account.Actor.url ], to: [ video.VideoChannel.Account.Actor.url ],
cc: actorsInvolvedInVideo.map(a => a.followersUrl) cc: actorsInvolvedInVideo.map(a => a.followersUrl)
@ -18,7 +18,7 @@ function getVideoCommentAudience (
threadParentComments: VideoCommentModel[], threadParentComments: VideoCommentModel[],
actorsInvolvedInVideo: ActorModel[], actorsInvolvedInVideo: ActorModel[],
isOrigin = false isOrigin = false
) { ): ActivityAudience {
const to = [ ACTIVITY_PUB.PUBLIC ] const to = [ ACTIVITY_PUB.PUBLIC ]
const cc: string[] = [] const cc: string[] = []
@ -41,7 +41,7 @@ function getVideoCommentAudience (
} }
} }
function getObjectFollowersAudience (actorsInvolvedInObject: ActorModel[]) { function getAudienceFromFollowersOf (actorsInvolvedInObject: ActorModel[]): ActivityAudience {
return { return {
to: [ ACTIVITY_PUB.PUBLIC ].concat(actorsInvolvedInObject.map(a => a.followersUrl)), to: [ ACTIVITY_PUB.PUBLIC ].concat(actorsInvolvedInObject.map(a => a.followersUrl)),
cc: [] cc: []
@ -83,9 +83,9 @@ function audiencify<T> (object: T, audience: ActivityAudience) {
export { export {
buildAudience, buildAudience,
getAudience, getAudience,
getVideoAudience, getRemoteVideoAudience,
getActorsInvolvedInVideo, getActorsInvolvedInVideo,
getObjectFollowersAudience, getAudienceFromFollowersOf,
audiencify, audiencify,
getVideoCommentAudience getVideoCommentAudience
} }

View File

@ -41,6 +41,8 @@ async function processDeleteActivity (activity: ActivityDelete) {
{ {
const videoInstance = await VideoModel.loadByUrlAndPopulateAccount(objectUrl) const videoInstance = await VideoModel.loadByUrlAndPopulateAccount(objectUrl)
if (videoInstance) { if (videoInstance) {
if (videoInstance.isOwned()) throw new Error(`Remote instance cannot delete owned video ${videoInstance.url}.`)
return retryTransactionWrapper(processDeleteVideo, actor, videoInstance) return retryTransactionWrapper(processDeleteVideo, actor, videoInstance)
} }
} }

View File

@ -4,14 +4,14 @@ import { ActorModel } from '../../../models/activitypub/actor'
import { VideoModel } from '../../../models/video/video' import { VideoModel } from '../../../models/video/video'
import { VideoShareModel } from '../../../models/video/video-share' import { VideoShareModel } from '../../../models/video/video-share'
import { broadcastToFollowers } from './utils' import { broadcastToFollowers } from './utils'
import { audiencify, getActorsInvolvedInVideo, getAudience, getObjectFollowersAudience } from '../audience' import { audiencify, getActorsInvolvedInVideo, getAudience, getAudienceFromFollowersOf } from '../audience'
import { logger } from '../../../helpers/logger' import { logger } from '../../../helpers/logger'
async function buildAnnounceWithVideoAudience (byActor: ActorModel, videoShare: VideoShareModel, video: VideoModel, t: Transaction) { async function buildAnnounceWithVideoAudience (byActor: ActorModel, videoShare: VideoShareModel, video: VideoModel, t: Transaction) {
const announcedObject = video.url const announcedObject = video.url
const actorsInvolvedInVideo = await getActorsInvolvedInVideo(video, t) const actorsInvolvedInVideo = await getActorsInvolvedInVideo(video, t)
const audience = getObjectFollowersAudience(actorsInvolvedInVideo) const audience = getAudienceFromFollowersOf(actorsInvolvedInVideo)
const activity = buildAnnounceActivity(videoShare.url, byActor, announcedObject, audience) const activity = buildAnnounceActivity(videoShare.url, byActor, announcedObject, audience)

View File

@ -1,21 +1,13 @@
import { Transaction } from 'sequelize' import { Transaction } from 'sequelize'
import { ActivityAudience, ActivityCreate } from '../../../../shared/models/activitypub' import { ActivityAudience, ActivityCreate } from '../../../../shared/models/activitypub'
import { VideoPrivacy } from '../../../../shared/models/videos' import { VideoPrivacy } from '../../../../shared/models/videos'
import { getServerActor } from '../../../helpers/utils'
import { ActorModel } from '../../../models/activitypub/actor' import { ActorModel } from '../../../models/activitypub/actor'
import { VideoModel } from '../../../models/video/video' import { VideoModel } from '../../../models/video/video'
import { VideoAbuseModel } from '../../../models/video/video-abuse' import { VideoAbuseModel } from '../../../models/video/video-abuse'
import { VideoCommentModel } from '../../../models/video/video-comment' import { VideoCommentModel } from '../../../models/video/video-comment'
import { getVideoAbuseActivityPubUrl, getVideoDislikeActivityPubUrl, getVideoViewActivityPubUrl } from '../url' import { getVideoAbuseActivityPubUrl, getVideoDislikeActivityPubUrl, getVideoViewActivityPubUrl } from '../url'
import { broadcastToActors, broadcastToFollowers, unicastTo } from './utils' import { broadcastToActors, broadcastToFollowers, sendVideoRelatedActivity, unicastTo } from './utils'
import { import { audiencify, getActorsInvolvedInVideo, getAudience, getAudienceFromFollowersOf, getVideoCommentAudience } from '../audience'
audiencify,
getActorsInvolvedInVideo,
getAudience,
getObjectFollowersAudience,
getVideoAudience,
getVideoCommentAudience
} from '../audience'
import { logger } from '../../../helpers/logger' import { logger } from '../../../helpers/logger'
import { VideoRedundancyModel } from '../../../models/redundancy/video-redundancy' import { VideoRedundancyModel } from '../../../models/redundancy/video-redundancy'
@ -40,6 +32,7 @@ async function sendVideoAbuse (byActor: ActorModel, videoAbuse: VideoAbuseModel,
logger.info('Creating job to send video abuse %s.', url) logger.info('Creating job to send video abuse %s.', url)
// Custom audience, we only send the abuse to the origin instance
const audience = { to: [ video.VideoChannel.Account.Actor.url ], cc: [] } const audience = { to: [ video.VideoChannel.Account.Actor.url ], cc: [] }
const createActivity = buildCreateActivity(url, byActor, videoAbuse.toActivityPubObject(), audience) const createActivity = buildCreateActivity(url, byActor, videoAbuse.toActivityPubObject(), audience)
@ -49,15 +42,15 @@ async function sendVideoAbuse (byActor: ActorModel, videoAbuse: VideoAbuseModel,
async function sendCreateCacheFile (byActor: ActorModel, fileRedundancy: VideoRedundancyModel) { async function sendCreateCacheFile (byActor: ActorModel, fileRedundancy: VideoRedundancyModel) {
logger.info('Creating job to send file cache of %s.', fileRedundancy.url) logger.info('Creating job to send file cache of %s.', fileRedundancy.url)
const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(fileRedundancy.VideoFile.Video.id)
const redundancyObject = fileRedundancy.toActivityPubObject() const redundancyObject = fileRedundancy.toActivityPubObject()
const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(fileRedundancy.VideoFile.Video.id) return sendVideoRelatedCreateActivity({
const actorsInvolvedInVideo = await getActorsInvolvedInVideo(video, undefined) byActor,
video,
const audience = getVideoAudience(video, actorsInvolvedInVideo) url: fileRedundancy.url,
const createActivity = buildCreateActivity(fileRedundancy.url, byActor, redundancyObject, audience) object: redundancyObject
})
return unicastTo(createActivity, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl)
} }
async function sendCreateVideoComment (comment: VideoCommentModel, t: Transaction) { async function sendCreateVideoComment (comment: VideoCommentModel, t: Transaction) {
@ -70,6 +63,7 @@ async function sendCreateVideoComment (comment: VideoCommentModel, t: Transactio
const commentObject = comment.toActivityPubObject(threadParentComments) const commentObject = comment.toActivityPubObject(threadParentComments)
const actorsInvolvedInComment = await getActorsInvolvedInVideo(comment.Video, t) const actorsInvolvedInComment = await getActorsInvolvedInVideo(comment.Video, t)
// Add the actor that commented too
actorsInvolvedInComment.push(byActor) actorsInvolvedInComment.push(byActor)
const parentsCommentActors = threadParentComments.map(c => c.Account.Actor) const parentsCommentActors = threadParentComments.map(c => c.Account.Actor)
@ -78,7 +72,7 @@ async function sendCreateVideoComment (comment: VideoCommentModel, t: Transactio
if (isOrigin) { if (isOrigin) {
audience = getVideoCommentAudience(comment, threadParentComments, actorsInvolvedInComment, isOrigin) audience = getVideoCommentAudience(comment, threadParentComments, actorsInvolvedInComment, isOrigin)
} else { } else {
audience = getObjectFollowersAudience(actorsInvolvedInComment.concat(parentsCommentActors)) audience = getAudienceFromFollowersOf(actorsInvolvedInComment.concat(parentsCommentActors))
} }
const createActivity = buildCreateActivity(comment.url, byActor, commentObject, audience) const createActivity = buildCreateActivity(comment.url, byActor, commentObject, audience)
@ -103,24 +97,14 @@ async function sendCreateView (byActor: ActorModel, video: VideoModel, t: Transa
const url = getVideoViewActivityPubUrl(byActor, video) const url = getVideoViewActivityPubUrl(byActor, video)
const viewActivity = buildViewActivity(byActor, video) const viewActivity = buildViewActivity(byActor, video)
const actorsInvolvedInVideo = await getActorsInvolvedInVideo(video, t) return sendVideoRelatedCreateActivity({
// Use the server actor to send the view
// Send to origin byActor,
if (video.isOwned() === false) { video,
const audience = getVideoAudience(video, actorsInvolvedInVideo) url,
const createActivity = buildCreateActivity(url, byActor, viewActivity, audience) object: viewActivity,
transaction: t
return unicastTo(createActivity, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl) })
}
// Send to followers
const audience = getObjectFollowersAudience(actorsInvolvedInVideo)
const createActivity = buildCreateActivity(url, byActor, viewActivity, audience)
// Use the server actor to send the view
const serverActor = await getServerActor()
const actorsException = [ byActor ]
return broadcastToFollowers(createActivity, serverActor, actorsInvolvedInVideo, t, actorsException)
} }
async function sendCreateDislike (byActor: ActorModel, video: VideoModel, t: Transaction) { async function sendCreateDislike (byActor: ActorModel, video: VideoModel, t: Transaction) {
@ -129,22 +113,13 @@ async function sendCreateDislike (byActor: ActorModel, video: VideoModel, t: Tra
const url = getVideoDislikeActivityPubUrl(byActor, video) const url = getVideoDislikeActivityPubUrl(byActor, video)
const dislikeActivity = buildDislikeActivity(byActor, video) const dislikeActivity = buildDislikeActivity(byActor, video)
const actorsInvolvedInVideo = await getActorsInvolvedInVideo(video, t) return sendVideoRelatedCreateActivity({
byActor,
// Send to origin video,
if (video.isOwned() === false) { url,
const audience = getVideoAudience(video, actorsInvolvedInVideo) object: dislikeActivity,
const createActivity = buildCreateActivity(url, byActor, dislikeActivity, audience) transaction: t
})
return unicastTo(createActivity, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl)
}
// Send to followers
const audience = getObjectFollowersAudience(actorsInvolvedInVideo)
const createActivity = buildCreateActivity(url, byActor, dislikeActivity, audience)
const actorsException = [ byActor ]
return broadcastToFollowers(createActivity, byActor, actorsInvolvedInVideo, t, actorsException)
} }
function buildCreateActivity (url: string, byActor: ActorModel, object: any, audience?: ActivityAudience): ActivityCreate { function buildCreateActivity (url: string, byActor: ActorModel, object: any, audience?: ActivityAudience): ActivityCreate {
@ -189,3 +164,19 @@ export {
sendCreateVideoComment, sendCreateVideoComment,
sendCreateCacheFile sendCreateCacheFile
} }
// ---------------------------------------------------------------------------
async function sendVideoRelatedCreateActivity (options: {
byActor: ActorModel,
video: VideoModel,
url: string,
object: any,
transaction?: Transaction
}) {
const activityBuilder = (audience: ActivityAudience) => {
return buildCreateActivity(options.url, options.byActor, options.object, audience)
}
return sendVideoRelatedActivity(activityBuilder, options)
}

View File

@ -5,21 +5,22 @@ import { VideoModel } from '../../../models/video/video'
import { VideoCommentModel } from '../../../models/video/video-comment' import { VideoCommentModel } from '../../../models/video/video-comment'
import { VideoShareModel } from '../../../models/video/video-share' import { VideoShareModel } from '../../../models/video/video-share'
import { getDeleteActivityPubUrl } from '../url' import { getDeleteActivityPubUrl } from '../url'
import { broadcastToActors, broadcastToFollowers, unicastTo } from './utils' import { broadcastToActors, broadcastToFollowers, sendVideoRelatedActivity, unicastTo } from './utils'
import { audiencify, getActorsInvolvedInVideo, getVideoCommentAudience } from '../audience' import { audiencify, getActorsInvolvedInVideo, getVideoCommentAudience } from '../audience'
import { logger } from '../../../helpers/logger' import { logger } from '../../../helpers/logger'
async function sendDeleteVideo (video: VideoModel, t: Transaction) { async function sendDeleteVideo (video: VideoModel, transaction: Transaction) {
logger.info('Creating job to broadcast delete of video %s.', video.url) logger.info('Creating job to broadcast delete of video %s.', video.url)
const url = getDeleteActivityPubUrl(video.url)
const byActor = video.VideoChannel.Account.Actor const byActor = video.VideoChannel.Account.Actor
const activity = buildDeleteActivity(url, video.url, byActor) const activityBuilder = (audience: ActivityAudience) => {
const url = getDeleteActivityPubUrl(video.url)
const actorsInvolved = await getActorsInvolvedInVideo(video, t) return buildDeleteActivity(url, video.url, byActor, audience)
}
return broadcastToFollowers(activity, byActor, actorsInvolved, t) return sendVideoRelatedActivity(activityBuilder, { byActor, video, transaction })
} }
async function sendDeleteActor (byActor: ActorModel, t: Transaction) { async function sendDeleteActor (byActor: ActorModel, t: Transaction) {

View File

@ -3,31 +3,20 @@ import { ActivityAudience, ActivityLike } from '../../../../shared/models/activi
import { ActorModel } from '../../../models/activitypub/actor' import { ActorModel } from '../../../models/activitypub/actor'
import { VideoModel } from '../../../models/video/video' import { VideoModel } from '../../../models/video/video'
import { getVideoLikeActivityPubUrl } from '../url' import { getVideoLikeActivityPubUrl } from '../url'
import { broadcastToFollowers, unicastTo } from './utils' import { sendVideoRelatedActivity } from './utils'
import { audiencify, getActorsInvolvedInVideo, getAudience, getObjectFollowersAudience, getVideoAudience } from '../audience' import { audiencify, getAudience } from '../audience'
import { logger } from '../../../helpers/logger' import { logger } from '../../../helpers/logger'
async function sendLike (byActor: ActorModel, video: VideoModel, t: Transaction) { async function sendLike (byActor: ActorModel, video: VideoModel, t: Transaction) {
logger.info('Creating job to like %s.', video.url) logger.info('Creating job to like %s.', video.url)
const url = getVideoLikeActivityPubUrl(byActor, video) const activityBuilder = (audience: ActivityAudience) => {
const url = getVideoLikeActivityPubUrl(byActor, video)
const accountsInvolvedInVideo = await getActorsInvolvedInVideo(video, t) return buildLikeActivity(url, byActor, video, audience)
// Send to origin
if (video.isOwned() === false) {
const audience = getVideoAudience(video, accountsInvolvedInVideo)
const data = buildLikeActivity(url, byActor, video, audience)
return unicastTo(data, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl)
} }
// Send to followers return sendVideoRelatedActivity(activityBuilder, { byActor, video, transaction: t })
const audience = getObjectFollowersAudience(accountsInvolvedInVideo)
const activity = buildLikeActivity(url, byActor, video, audience)
const followersException = [ byActor ]
return broadcastToFollowers(activity, byActor, accountsInvolvedInVideo, t, followersException)
} }
function buildLikeActivity (url: string, byActor: ActorModel, video: VideoModel, audience?: ActivityAudience): ActivityLike { function buildLikeActivity (url: string, byActor: ActorModel, video: VideoModel, audience?: ActivityAudience): ActivityLike {

View File

@ -11,8 +11,8 @@ import { ActorModel } from '../../../models/activitypub/actor'
import { ActorFollowModel } from '../../../models/activitypub/actor-follow' import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
import { VideoModel } from '../../../models/video/video' import { VideoModel } from '../../../models/video/video'
import { getActorFollowActivityPubUrl, getUndoActivityPubUrl, getVideoDislikeActivityPubUrl, getVideoLikeActivityPubUrl } from '../url' import { getActorFollowActivityPubUrl, getUndoActivityPubUrl, getVideoDislikeActivityPubUrl, getVideoLikeActivityPubUrl } from '../url'
import { broadcastToFollowers, unicastTo } from './utils' import { broadcastToFollowers, sendVideoRelatedActivity, unicastTo } from './utils'
import { audiencify, getActorsInvolvedInVideo, getAudience, getObjectFollowersAudience, getVideoAudience } from '../audience' import { audiencify, getAudience } from '../audience'
import { buildCreateActivity, buildDislikeActivity } from './send-create' import { buildCreateActivity, buildDislikeActivity } from './send-create'
import { buildFollowActivity } from './send-follow' import { buildFollowActivity } from './send-follow'
import { buildLikeActivity } from './send-like' import { buildLikeActivity } from './send-like'
@ -39,53 +39,6 @@ async function sendUndoFollow (actorFollow: ActorFollowModel, t: Transaction) {
return unicastTo(undoActivity, me, following.inboxUrl) return unicastTo(undoActivity, me, following.inboxUrl)
} }
async function sendUndoLike (byActor: ActorModel, video: VideoModel, t: Transaction) {
logger.info('Creating job to undo a like of video %s.', video.url)
const likeUrl = getVideoLikeActivityPubUrl(byActor, video)
const undoUrl = getUndoActivityPubUrl(likeUrl)
const actorsInvolvedInVideo = await getActorsInvolvedInVideo(video, t)
const likeActivity = buildLikeActivity(likeUrl, byActor, video)
// Send to origin
if (video.isOwned() === false) {
const audience = getVideoAudience(video, actorsInvolvedInVideo)
const undoActivity = undoActivityData(undoUrl, byActor, likeActivity, audience)
return unicastTo(undoActivity, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl)
}
const audience = getObjectFollowersAudience(actorsInvolvedInVideo)
const undoActivity = undoActivityData(undoUrl, byActor, likeActivity, audience)
const followersException = [ byActor ]
return broadcastToFollowers(undoActivity, byActor, actorsInvolvedInVideo, t, followersException)
}
async function sendUndoDislike (byActor: ActorModel, video: VideoModel, t: Transaction) {
logger.info('Creating job to undo a dislike of video %s.', video.url)
const dislikeUrl = getVideoDislikeActivityPubUrl(byActor, video)
const undoUrl = getUndoActivityPubUrl(dislikeUrl)
const actorsInvolvedInVideo = await getActorsInvolvedInVideo(video, t)
const dislikeActivity = buildDislikeActivity(byActor, video)
const createDislikeActivity = buildCreateActivity(dislikeUrl, byActor, dislikeActivity)
if (video.isOwned() === false) {
const audience = getVideoAudience(video, actorsInvolvedInVideo)
const undoActivity = undoActivityData(undoUrl, byActor, createDislikeActivity, audience)
return unicastTo(undoActivity, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl)
}
const undoActivity = undoActivityData(undoUrl, byActor, createDislikeActivity)
const followersException = [ byActor ]
return broadcastToFollowers(undoActivity, byActor, actorsInvolvedInVideo, t, followersException)
}
async function sendUndoAnnounce (byActor: ActorModel, videoShare: VideoShareModel, video: VideoModel, t: Transaction) { async function sendUndoAnnounce (byActor: ActorModel, videoShare: VideoShareModel, video: VideoModel, t: Transaction) {
logger.info('Creating job to undo announce %s.', videoShare.url) logger.info('Creating job to undo announce %s.', videoShare.url)
@ -98,20 +51,32 @@ async function sendUndoAnnounce (byActor: ActorModel, videoShare: VideoShareMode
return broadcastToFollowers(undoActivity, byActor, actorsInvolvedInVideo, t, followersException) return broadcastToFollowers(undoActivity, byActor, actorsInvolvedInVideo, t, followersException)
} }
async function sendUndoLike (byActor: ActorModel, video: VideoModel, t: Transaction) {
logger.info('Creating job to undo a like of video %s.', video.url)
const likeUrl = getVideoLikeActivityPubUrl(byActor, video)
const likeActivity = buildLikeActivity(likeUrl, byActor, video)
return sendUndoVideoRelatedActivity({ byActor, video, url: likeUrl, activity: likeActivity, transaction: t })
}
async function sendUndoDislike (byActor: ActorModel, video: VideoModel, t: Transaction) {
logger.info('Creating job to undo a dislike of video %s.', video.url)
const dislikeUrl = getVideoDislikeActivityPubUrl(byActor, video)
const dislikeActivity = buildDislikeActivity(byActor, video)
const createDislikeActivity = buildCreateActivity(dislikeUrl, byActor, dislikeActivity)
return sendUndoVideoRelatedActivity({ byActor, video, url: dislikeUrl, activity: createDislikeActivity, transaction: t })
}
async function sendUndoCacheFile (byActor: ActorModel, redundancyModel: VideoRedundancyModel, t: Transaction) { async function sendUndoCacheFile (byActor: ActorModel, redundancyModel: VideoRedundancyModel, t: Transaction) {
logger.info('Creating job to undo cache file %s.', redundancyModel.url) logger.info('Creating job to undo cache file %s.', redundancyModel.url)
const undoUrl = getUndoActivityPubUrl(redundancyModel.url)
const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(redundancyModel.VideoFile.Video.id) const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(redundancyModel.VideoFile.Video.id)
const actorsInvolvedInVideo = await getActorsInvolvedInVideo(video, t)
const audience = getVideoAudience(video, actorsInvolvedInVideo)
const createActivity = buildCreateActivity(redundancyModel.url, byActor, redundancyModel.toActivityPubObject()) const createActivity = buildCreateActivity(redundancyModel.url, byActor, redundancyModel.toActivityPubObject())
const undoActivity = undoActivityData(undoUrl, byActor, createActivity, audience) return sendUndoVideoRelatedActivity({ byActor, video, url: redundancyModel.url, activity: createActivity, transaction: t })
return unicastTo(undoActivity, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl)
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -144,3 +109,19 @@ function undoActivityData (
audience audience
) )
} }
async function sendUndoVideoRelatedActivity (options: {
byActor: ActorModel,
video: VideoModel,
url: string,
activity: ActivityFollow | ActivityLike | ActivityCreate | ActivityAnnounce,
transaction: Transaction
}) {
const activityBuilder = (audience: ActivityAudience) => {
const undoUrl = getUndoActivityPubUrl(options.url)
return undoActivityData(undoUrl, options.byActor, options.activity, audience)
}
return sendVideoRelatedActivity(activityBuilder, options)
}

View File

@ -7,8 +7,8 @@ import { VideoModel } from '../../../models/video/video'
import { VideoChannelModel } from '../../../models/video/video-channel' import { VideoChannelModel } from '../../../models/video/video-channel'
import { VideoShareModel } from '../../../models/video/video-share' import { VideoShareModel } from '../../../models/video/video-share'
import { getUpdateActivityPubUrl } from '../url' import { getUpdateActivityPubUrl } from '../url'
import { broadcastToFollowers, unicastTo } from './utils' import { broadcastToFollowers, sendVideoRelatedActivity, unicastTo } from './utils'
import { audiencify, getActorsInvolvedInVideo, getAudience, getObjectFollowersAudience } from '../audience' import { audiencify, getActorsInvolvedInVideo, getAudience, getAudienceFromFollowersOf } from '../audience'
import { logger } from '../../../helpers/logger' import { logger } from '../../../helpers/logger'
import { VideoCaptionModel } from '../../../models/video/video-caption' import { VideoCaptionModel } from '../../../models/video/video-caption'
import { VideoRedundancyModel } from '../../../models/redundancy/video-redundancy' import { VideoRedundancyModel } from '../../../models/redundancy/video-redundancy'
@ -61,16 +61,16 @@ async function sendUpdateActor (accountOrChannel: AccountModel | VideoChannelMod
async function sendUpdateCacheFile (byActor: ActorModel, redundancyModel: VideoRedundancyModel) { async function sendUpdateCacheFile (byActor: ActorModel, redundancyModel: VideoRedundancyModel) {
logger.info('Creating job to update cache file %s.', redundancyModel.url) logger.info('Creating job to update cache file %s.', redundancyModel.url)
const url = getUpdateActivityPubUrl(redundancyModel.url, redundancyModel.updatedAt.toISOString())
const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(redundancyModel.VideoFile.Video.id) const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(redundancyModel.VideoFile.Video.id)
const redundancyObject = redundancyModel.toActivityPubObject() const activityBuilder = (audience: ActivityAudience) => {
const redundancyObject = redundancyModel.toActivityPubObject()
const url = getUpdateActivityPubUrl(redundancyModel.url, redundancyModel.updatedAt.toISOString())
const accountsInvolvedInVideo = await getActorsInvolvedInVideo(video, undefined) return buildUpdateActivity(url, byActor, redundancyObject, audience)
const audience = getObjectFollowersAudience(accountsInvolvedInVideo) }
const updateActivity = buildUpdateActivity(url, byActor, redundancyObject, audience) return sendVideoRelatedActivity(activityBuilder, { byActor, video })
return unicastTo(updateActivity, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl)
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@ -1,13 +1,36 @@
import { Transaction } from 'sequelize' import { Transaction } from 'sequelize'
import { Activity } from '../../../../shared/models/activitypub' import { Activity, ActivityAudience } from '../../../../shared/models/activitypub'
import { logger } from '../../../helpers/logger' import { logger } from '../../../helpers/logger'
import { ActorModel } from '../../../models/activitypub/actor' import { ActorModel } from '../../../models/activitypub/actor'
import { ActorFollowModel } from '../../../models/activitypub/actor-follow' import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
import { JobQueue } from '../../job-queue' import { JobQueue } from '../../job-queue'
import { VideoModel } from '../../../models/video/video' import { VideoModel } from '../../../models/video/video'
import { getActorsInvolvedInVideo } from '../audience' import { getActorsInvolvedInVideo, getAudienceFromFollowersOf, getRemoteVideoAudience } from '../audience'
import { getServerActor } from '../../../helpers/utils' import { getServerActor } from '../../../helpers/utils'
async function sendVideoRelatedActivity (activityBuilder: (audience: ActivityAudience) => Activity, options: {
byActor: ActorModel,
video: VideoModel,
transaction?: Transaction
}) {
const actorsInvolvedInVideo = await getActorsInvolvedInVideo(options.video, options.transaction)
// Send to origin
if (options.video.isOwned() === false) {
const audience = getRemoteVideoAudience(options.video, actorsInvolvedInVideo)
const activity = activityBuilder(audience)
return unicastTo(activity, options.byActor, options.video.VideoChannel.Account.Actor.sharedInboxUrl)
}
// Send to followers
const audience = getAudienceFromFollowersOf(actorsInvolvedInVideo)
const activity = activityBuilder(audience)
const actorsException = [ options.byActor ]
return broadcastToFollowers(activity, options.byActor, actorsInvolvedInVideo, options.transaction, actorsException)
}
async function forwardVideoRelatedActivity ( async function forwardVideoRelatedActivity (
activity: Activity, activity: Activity,
t: Transaction, t: Transaction,
@ -110,7 +133,8 @@ export {
unicastTo, unicastTo,
forwardActivity, forwardActivity,
broadcastToActors, broadcastToActors,
forwardVideoRelatedActivity forwardVideoRelatedActivity,
sendVideoRelatedActivity
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@ -65,7 +65,6 @@ describe('Test stats (excluding redundancy)', function () {
expect(data.totalVideos).to.equal(1) expect(data.totalVideos).to.equal(1)
expect(data.totalInstanceFollowers).to.equal(2) expect(data.totalInstanceFollowers).to.equal(2)
expect(data.totalInstanceFollowing).to.equal(1) expect(data.totalInstanceFollowing).to.equal(1)
expect(data.videosRedundancy).to.have.lengthOf(0)
}) })
it('Should have the correct stats on instance 2', async function () { it('Should have the correct stats on instance 2', async function () {
@ -80,7 +79,6 @@ describe('Test stats (excluding redundancy)', function () {
expect(data.totalVideos).to.equal(1) expect(data.totalVideos).to.equal(1)
expect(data.totalInstanceFollowers).to.equal(1) expect(data.totalInstanceFollowers).to.equal(1)
expect(data.totalInstanceFollowing).to.equal(1) expect(data.totalInstanceFollowing).to.equal(1)
expect(data.videosRedundancy).to.have.lengthOf(0)
}) })
it('Should have the correct stats on instance 3', async function () { it('Should have the correct stats on instance 3', async function () {
@ -95,7 +93,6 @@ describe('Test stats (excluding redundancy)', function () {
expect(data.totalVideos).to.equal(1) expect(data.totalVideos).to.equal(1)
expect(data.totalInstanceFollowing).to.equal(1) expect(data.totalInstanceFollowing).to.equal(1)
expect(data.totalInstanceFollowers).to.equal(0) expect(data.totalInstanceFollowers).to.equal(0)
expect(data.videosRedundancy).to.have.lengthOf(0)
}) })
after(async function () { after(async function () {