import { pageToStartAndCount } from '../../helpers/core-utils'
import { ACTIVITY_PUB, CONFIG, ROUTE_CACHE_LIFETIME } from '../../initializers'
import { buildVideoAnnounce } from '../../lib/activitypub/send'
-import { audiencify, getAudience } from '../../lib/activitypub/send/misc'
+import { audiencify, getAudience } from '../../lib/activitypub/audience'
import { createActivityData } from '../../lib/activitypub/send/send-create'
import { asyncMiddleware, executeIfActivityPub, localAccountValidator } from '../../middlewares'
import { videoChannelsGetValidator, videosGetValidator, videosShareValidator } from '../../middlewares/validators'
import { logger } from '../../helpers/logger'
import { ACTIVITY_PUB } from '../../initializers/constants'
import { announceActivityData, createActivityData } from '../../lib/activitypub/send'
-import { buildAudience } from '../../lib/activitypub/send/misc'
+import { buildAudience } from '../../lib/activitypub/audience'
import { asyncMiddleware, localAccountValidator } from '../../middlewares'
import { AccountModel } from '../../models/account/account'
import { ActorModel } from '../../models/activitypub/actor'
--- /dev/null
+import { Transaction } from 'sequelize'
+import { ActivityAudience } from '../../../shared/models/activitypub'
+import { ACTIVITY_PUB } from '../../initializers'
+import { ActorModel } from '../../models/activitypub/actor'
+import { VideoModel } from '../../models/video/video'
+import { VideoCommentModel } from '../../models/video/video-comment'
+import { VideoShareModel } from '../../models/video/video-share'
+
+function getVideoAudience (video: VideoModel, actorsInvolvedInVideo: ActorModel[]) {
+ return {
+ to: [ video.VideoChannel.Account.Actor.url ],
+ cc: actorsInvolvedInVideo.map(a => a.followersUrl)
+ }
+}
+
+function getVideoCommentAudience (
+ videoComment: VideoCommentModel,
+ threadParentComments: VideoCommentModel[],
+ actorsInvolvedInVideo: ActorModel[],
+ isOrigin = false
+) {
+ const to = [ ACTIVITY_PUB.PUBLIC ]
+ const cc = [ ]
+
+ // Owner of the video we comment
+ if (isOrigin === false) {
+ cc.push(videoComment.Video.VideoChannel.Account.Actor.url)
+ }
+
+ // Followers of the poster
+ cc.push(videoComment.Account.Actor.followersUrl)
+
+ // Send to actors we reply to
+ for (const parentComment of threadParentComments) {
+ cc.push(parentComment.Account.Actor.url)
+ }
+
+ return {
+ to,
+ cc: cc.concat(actorsInvolvedInVideo.map(a => a.followersUrl))
+ }
+}
+
+function getObjectFollowersAudience (actorsInvolvedInObject: ActorModel[]) {
+ return {
+ to: [ ACTIVITY_PUB.PUBLIC ].concat(actorsInvolvedInObject.map(a => a.followersUrl)),
+ cc: []
+ }
+}
+
+async function getActorsInvolvedInVideo (video: VideoModel, t: Transaction) {
+ const actors = await VideoShareModel.loadActorsByShare(video.id, t)
+ actors.push(video.VideoChannel.Account.Actor)
+
+ return actors
+}
+
+async function getAudience (actorSender: ActorModel, t: Transaction, isPublic = true) {
+ return buildAudience([ actorSender.followersUrl ], isPublic)
+}
+
+function buildAudience (followerInboxUrls: string[], isPublic = true) {
+ // Thanks Mastodon: https://github.com/tootsuite/mastodon/blob/master/app/lib/activitypub/tag_manager.rb#L47
+ let to = []
+ let cc = []
+
+ if (isPublic) {
+ to = [ ACTIVITY_PUB.PUBLIC ]
+ cc = followerInboxUrls
+ } else { // Unlisted
+ to = [ ]
+ cc = [ ]
+ }
+
+ return { to, cc }
+}
+
+function audiencify <T> (object: T, audience: ActivityAudience) {
+ return Object.assign(object, audience)
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ buildAudience,
+ getAudience,
+ getVideoAudience,
+ getActorsInvolvedInVideo,
+ getObjectFollowersAudience,
+ audiencify,
+ getVideoCommentAudience
+}
export * from './process'
export * from './send'
export * from './actor'
-export * from './fetch'
export * from './share'
export * from './videos'
export * from './video-comments'
import { VideoModel } from '../../../models/video/video'
import { VideoShareModel } from '../../../models/video/video-share'
import { getOrCreateActorAndServerAndModel } from '../actor'
-import { forwardActivity } from '../send/misc'
+import { forwardActivity } from '../send/utils'
import { getOrCreateAccountAndVideoAndChannel } from '../videos'
async function processAnnounceActivity (activity: ActivityAnnounce) {
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 { getActorsInvolvedInVideo } from '../audience'
import { resolveThread } from '../video-comments'
import { getOrCreateAccountAndVideoAndChannel } from '../videos'
+import { forwardActivity } from '../send/utils'
async function processCreateActivity (activity: ActivityCreate) {
const activityObject = activity.object
import { VideoChannelModel } from '../../../models/video/video-channel'
import { VideoCommentModel } from '../../../models/video/video-comment'
import { getOrCreateActorAndServerAndModel } from '../actor'
-import { forwardActivity } from '../send/misc'
+import { forwardActivity } from '../send/utils'
async function processDeleteActivity (activity: ActivityDelete) {
const objectUrl = typeof activity.object === 'string' ? activity.object : activity.object.id
import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
import { ActorModel } from '../../../models/activitypub/actor'
import { getOrCreateActorAndServerAndModel } from '../actor'
-import { forwardActivity } from '../send/misc'
+import { forwardActivity } from '../send/utils'
import { getOrCreateAccountAndVideoAndChannel } from '../videos'
async function processLikeActivity (activity: ActivityLike) {
import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
import { ActorModel } from '../../../models/activitypub/actor'
import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
-import { forwardActivity } from '../send/misc'
+import { forwardActivity } from '../send/utils'
import { getOrCreateAccountAndVideoAndChannel } from '../videos'
import { VideoShareModel } from '../../../models/video/video-share'
import { fetchAvatarIfExists, getOrCreateActorAndServerAndModel, updateActorAvatarInstance, updateActorInstance } from '../actor'
import {
generateThumbnailFromUrl,
- getOrCreateAccountAndVideoAndChannel, getOrCreateVideoChannel,
+ getOrCreateAccountAndVideoAndChannel,
+ getOrCreateVideoChannel,
videoActivityObjectToDBAttributes,
videoFileActivityUrlToDBAttributes
} from '../videos'
import { ActorModel } from '../../../models/activitypub/actor'
import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
import { getActorFollowAcceptActivityPubUrl, getActorFollowActivityPubUrl } from '../url'
-import { unicastTo } from './misc'
+import { unicastTo } from './utils'
import { followActivityData } from './send-follow'
async function sendAccept (actorFollow: ActorFollowModel) {
import { ActorModel } from '../../../models/activitypub/actor'
import { VideoModel } from '../../../models/video/video'
import { VideoShareModel } from '../../../models/video/video-share'
-import { broadcastToFollowers, getActorsInvolvedInVideo, getAudience, getObjectFollowersAudience } from './misc'
+import { broadcastToFollowers } from './utils'
+import { getActorsInvolvedInVideo, getAudience, getObjectFollowersAudience } from '../audience'
async function buildVideoAnnounce (byActor: ActorModel, videoShare: VideoShareModel, video: VideoModel, t: Transaction) {
const announcedObject = video.url
import { VideoAbuseModel } from '../../../models/video/video-abuse'
import { VideoCommentModel } from '../../../models/video/video-comment'
import { getVideoAbuseActivityPubUrl, getVideoDislikeActivityPubUrl, getVideoViewActivityPubUrl } from '../url'
+import { broadcastToActors, broadcastToFollowers, unicastTo } from './utils'
import {
audiencify,
- broadcastToActors,
- broadcastToFollowers,
getActorsInvolvedInVideo,
getAudience,
getObjectFollowersAudience,
- getOriginVideoAudience,
- getVideoCommentAudience,
- unicastTo
-} from './misc'
+ getVideoAudience,
+ getVideoCommentAudience
+} from '../audience'
async function sendCreateVideo (video: VideoModel, t: Transaction) {
if (video.privacy === VideoPrivacy.PRIVATE) return undefined
// Send to origin
if (video.isOwned() === false) {
- const audience = getOriginVideoAudience(video, actorsInvolvedInVideo)
+ const audience = getVideoAudience(video, actorsInvolvedInVideo)
const data = await createActivityData(url, byActor, viewActivityData, t, audience)
return unicastTo(data, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl)
// Send to origin
if (video.isOwned() === false) {
- const audience = getOriginVideoAudience(video, actorsInvolvedInVideo)
+ const audience = getVideoAudience(video, actorsInvolvedInVideo)
const data = await createActivityData(url, byActor, dislikeActivityData, t, audience)
return unicastTo(data, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl)
import { VideoCommentModel } from '../../../models/video/video-comment'
import { VideoShareModel } from '../../../models/video/video-share'
import { getDeleteActivityPubUrl } from '../url'
-import { audiencify, broadcastToActors, broadcastToFollowers, getActorsInvolvedInVideo, getVideoCommentAudience, unicastTo } from './misc'
+import { broadcastToActors, broadcastToFollowers, unicastTo } from './utils'
+import { audiencify, getActorsInvolvedInVideo, getVideoCommentAudience } from '../audience'
async function sendDeleteVideo (video: VideoModel, t: Transaction) {
const url = getDeleteActivityPubUrl(video.url)
import { ActorModel } from '../../../models/activitypub/actor'
import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
import { getActorFollowActivityPubUrl } from '../url'
-import { unicastTo } from './misc'
+import { unicastTo } from './utils'
function sendFollow (actorFollow: ActorFollowModel) {
const me = actorFollow.ActorFollower
import { ActorModel } from '../../../models/activitypub/actor'
import { VideoModel } from '../../../models/video/video'
import { getVideoLikeActivityPubUrl } from '../url'
-import {
- audiencify,
- broadcastToFollowers,
- getActorsInvolvedInVideo,
- getAudience,
- getObjectFollowersAudience,
- getOriginVideoAudience,
- unicastTo
-} from './misc'
+import { broadcastToFollowers, unicastTo } from './utils'
+import { audiencify, getActorsInvolvedInVideo, getAudience, getObjectFollowersAudience, getVideoAudience } from '../audience'
async function sendLike (byActor: ActorModel, video: VideoModel, t: Transaction) {
const url = getVideoLikeActivityPubUrl(byActor, video)
// Send to origin
if (video.isOwned() === false) {
- const audience = getOriginVideoAudience(video, accountsInvolvedInVideo)
+ const audience = getVideoAudience(video, accountsInvolvedInVideo)
const data = await likeActivityData(url, byActor, video, t, audience)
return unicastTo(data, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl)
import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
import { VideoModel } from '../../../models/video/video'
import { getActorFollowActivityPubUrl, getUndoActivityPubUrl, getVideoDislikeActivityPubUrl, getVideoLikeActivityPubUrl } from '../url'
-import {
- audiencify,
- broadcastToFollowers,
- getActorsInvolvedInVideo,
- getAudience,
- getObjectFollowersAudience,
- getOriginVideoAudience,
- unicastTo
-} from './misc'
+import { broadcastToFollowers, unicastTo } from './utils'
+import { audiencify, getActorsInvolvedInVideo, getAudience, getObjectFollowersAudience, getVideoAudience } from '../audience'
import { createActivityData, createDislikeActivityData } from './send-create'
import { followActivityData } from './send-follow'
import { likeActivityData } from './send-like'
// Send to origin
if (video.isOwned() === false) {
- const audience = getOriginVideoAudience(video, actorsInvolvedInVideo)
+ const audience = getVideoAudience(video, actorsInvolvedInVideo)
const data = await undoActivityData(undoUrl, byActor, object, t, audience)
return unicastTo(data, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl)
const object = await createActivityData(dislikeUrl, byActor, dislikeActivity, t)
if (video.isOwned() === false) {
- const audience = getOriginVideoAudience(video, actorsInvolvedInVideo)
+ const audience = getVideoAudience(video, actorsInvolvedInVideo)
const data = await undoActivityData(undoUrl, byActor, object, t, audience)
return unicastTo(data, byActor, video.VideoChannel.Account.Actor.sharedInboxUrl)
import { VideoChannelModel } from '../../../models/video/video-channel'
import { VideoShareModel } from '../../../models/video/video-share'
import { getUpdateActivityPubUrl } from '../url'
-import { audiencify, broadcastToFollowers, getAudience } from './misc'
+import { broadcastToFollowers } from './utils'
+import { audiencify, getAudience } from '../audience'
async function sendUpdateVideo (video: VideoModel, t: Transaction) {
const byActor = video.VideoChannel.Account.Actor
import { Transaction } from 'sequelize'
-import { Activity, ActivityAudience } from '../../../../shared/models/activitypub'
+import { Activity } from '../../../../shared/models/activitypub'
import { logger } from '../../../helpers/logger'
-import { ACTIVITY_PUB } from '../../../initializers'
import { ActorModel } from '../../../models/activitypub/actor'
import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
-import { VideoModel } from '../../../models/video/video'
-import { VideoCommentModel } from '../../../models/video/video-comment'
-import { VideoShareModel } from '../../../models/video/video-share'
import { JobQueue } from '../../job-queue'
async function forwardActivity (
return JobQueue.Instance.createJob({ type: 'activitypub-http-unicast', payload })
}
-function getOriginVideoAudience (video: VideoModel, actorsInvolvedInVideo: ActorModel[]) {
- return {
- to: [ video.VideoChannel.Account.Actor.url ],
- cc: actorsInvolvedInVideo.map(a => a.followersUrl)
- }
-}
-
-function getVideoCommentAudience (
- videoComment: VideoCommentModel,
- threadParentComments: VideoCommentModel[],
- actorsInvolvedInVideo: ActorModel[],
- isOrigin = false
-) {
- const to = [ ACTIVITY_PUB.PUBLIC ]
- const cc = [ ]
-
- // Owner of the video we comment
- if (isOrigin === false) {
- cc.push(videoComment.Video.VideoChannel.Account.Actor.url)
- }
-
- // Followers of the poster
- cc.push(videoComment.Account.Actor.followersUrl)
-
- // Send to actors we reply to
- for (const parentComment of threadParentComments) {
- cc.push(parentComment.Account.Actor.url)
- }
-
- return {
- to,
- cc: cc.concat(actorsInvolvedInVideo.map(a => a.followersUrl))
- }
-}
-
-function getObjectFollowersAudience (actorsInvolvedInObject: ActorModel[]) {
- return {
- to: [ ACTIVITY_PUB.PUBLIC ].concat(actorsInvolvedInObject.map(a => a.followersUrl)),
- cc: []
- }
-}
-
-async function getActorsInvolvedInVideo (video: VideoModel, t: Transaction) {
- const actors = await VideoShareModel.loadActorsByShare(video.id, t)
- actors.push(video.VideoChannel.Account.Actor)
-
- return actors
-}
-
-async function getAudience (actorSender: ActorModel, t: Transaction, isPublic = true) {
- return buildAudience([ actorSender.followersUrl ], isPublic)
-}
-
-function buildAudience (followerInboxUrls: string[], isPublic = true) {
- // Thanks Mastodon: https://github.com/tootsuite/mastodon/blob/master/app/lib/activitypub/tag_manager.rb#L47
- let to = []
- let cc = []
-
- if (isPublic) {
- to = [ ACTIVITY_PUB.PUBLIC ]
- cc = followerInboxUrls
- } else { // Unlisted
- to = [ ]
- cc = [ ]
- }
+// ---------------------------------------------------------------------------
- return { to, cc }
+export {
+ broadcastToFollowers,
+ unicastTo,
+ forwardActivity,
+ broadcastToActors
}
-function audiencify <T> (object: T, audience: ActivityAudience) {
- return Object.assign(object, audience)
-}
+// ---------------------------------------------------------------------------
async function computeFollowerUris (toActorFollower: ActorModel[], actorsException: ActorModel[], t: Transaction) {
const toActorFollowerIds = toActorFollower.map(a => a.id)
const sharedInboxesException = actorsException.map(f => f.sharedInboxUrl || f.inboxUrl)
return Array.from(toActorSharedInboxesSet)
- .filter(sharedInbox => sharedInboxesException.indexOf(sharedInbox) === -1)
-}
-
-// ---------------------------------------------------------------------------
-
-export {
- broadcastToFollowers,
- unicastTo,
- buildAudience,
- getAudience,
- getOriginVideoAudience,
- getActorsInvolvedInVideo,
- getObjectFollowersAudience,
- forwardActivity,
- audiencify,
- getVideoCommentAudience,
- computeUris,
- broadcastToActors
+ .filter(sharedInbox => sharedInboxesException.indexOf(sharedInbox) === -1)
}