import { Transaction } from 'sequelize' ; import { ActivityAudience , ActivityCreate } from '../../../../shared/models/activitypub' ; import { VideoPrivacy } from '../../../../shared/models/videos' ; import { VideoCommentModel } from '../../../models/video/video-comment' ; import { broadcastToActors , broadcastToFollowers , sendVideoRelatedActivity , unicastTo } from './utils' ; import { audiencify , getActorsInvolvedInVideo , getAudience , getAudienceFromFollowersOf , getVideoCommentAudience } from '../audience' ; import { logger , loggerTagsFactory } from '../../../helpers/logger' ; import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model' ; import { MActorLight , MCommentOwnerVideo , MVideoAccountLight , MVideoAP , MVideoPlaylistFull , MVideoRedundancyFileVideo , MVideoRedundancyStreamingPlaylistVideo } from '../../../types/models' ; import { getServerActor } from '@server/models/application/application' ; import { ContextType } from '@shared/models/activitypub/context' ; const lTags = loggerTagsFactory ( 'ap' , 'create' ) ; async function sendCreateVideo ( video , t ) { if ( ! video . hasPrivacyForFederation ( ) ) return undefined ; logger . info ( 'Creating job to send video creation of %s.' , video . url , lTags ( video . uuid ) ) ; const byActor = video . VideoChannel . Account . Actor ; const videoObject = video . toActivityPubObject ( ) ; const audience = getAudience ( byActor , video . privacy === VideoPrivacy . PUBLIC ) ; const createActivity = buildCreateActivity ( video . url , byActor , videoObject , audience ) ; return broadcastToFollowers ( createActivity , byActor , [ byActor ] , t ) ; } async function sendCreateCacheFile ( byActor , video , fileRedundancy ) { logger . info ( 'Creating job to send file cache of %s.' , fileRedundancy . url , lTags ( video . uuid ) ) ; return sendVideoRelatedCreateActivity ( { byActor , video , url : fileRedundancy . url , object : fileRedundancy . toActivityPubObject ( ) , contextType : 'CacheFile' } ) ; } async function sendCreateVideoPlaylist ( playlist , t ) { if ( playlist . privacy === VideoPlaylistPrivacy . PRIVATE ) return undefined ; logger . info ( 'Creating job to send create video playlist of %s.' , playlist . url , lTags ( playlist . uuid ) ) ; const byActor = playlist . OwnerAccount . Actor ; const audience = getAudience ( byActor , playlist . privacy === VideoPlaylistPrivacy . PUBLIC ) ; const object = await playlist . toActivityPubObject ( null , t ) ; const createActivity = buildCreateActivity ( playlist . url , byActor , object , audience ) ; const serverActor = await getServerActor ( ) ; const toFollowersOf = [ byActor , serverActor ] ; if ( playlist . VideoChannel ) toFollowersOf . push ( playlist . VideoChannel . Actor ) ; return broadcastToFollowers ( createActivity , byActor , toFollowersOf , t ) ; } async function sendCreateVideoComment ( comment , t ) { logger . info ( 'Creating job to send comment %s.' , comment . url ) ; const isOrigin = comment . Video . isOwned ( ) ; const byActor = comment . Account . Actor ; const threadParentComments = await VideoCommentModel . listThreadParentComments ( comment , t ) ; const commentObject = comment . toActivityPubObject ( threadParentComments ) ; const actorsInvolvedInComment = await getActorsInvolvedInVideo ( comment . Video , t ) ; actorsInvolvedInComment . push ( byActor ) ; const parentsCommentActors = threadParentComments . filter ( c => ! c . isDeleted ( ) ) . map ( c => c . Account . Actor ) ; let audience ; if ( isOrigin ) { audience = getVideoCommentAudience ( comment , threadParentComments , actorsInvolvedInComment , isOrigin ) ; } else { audience = getAudienceFromFollowersOf ( actorsInvolvedInComment . concat ( parentsCommentActors ) ) ; } const createActivity = buildCreateActivity ( comment . url , byActor , commentObject , audience ) ; const actorsException = [ byActor ] ; await broadcastToActors ( createActivity , byActor , parentsCommentActors , t , actorsException ) ; await broadcastToFollowers ( createActivity , byActor , [ byActor ] , t ) ; if ( isOrigin ) return broadcastToFollowers ( createActivity , byActor , actorsInvolvedInComment , t , actorsException ) ; t . afterCommit ( ( ) => unicastTo ( createActivity , byActor , comment . Video . VideoChannel . Account . Actor . getSharedInbox ( ) ) ) ; } function buildCreateActivity ( url , byActor , object , audience ? ) { if ( ! audience ) audience = getAudience ( byActor ) ; return audiencify ( { type : 'Create' as 'Create' , id : url + '/activity' , actor : byActor . url , object : audiencify ( object , audience ) } , audience ) ; } export { sendCreateVideo , buildCreateActivity , sendCreateVideoComment , sendCreateVideoPlaylist , sendCreateCacheFile } ; async function sendVideoRelatedCreateActivity ( options ) { const activityBuilder = ( audience ) => { return buildCreateActivity ( options . url , options . byActor , options . object , audience ) ; } ; return sendVideoRelatedActivity ( activityBuilder , options ) ; }