import { Transaction } from 'sequelize' ; import { ActivityAudience , ActivityUpdate } from '../../../../shared/models/activitypub' ; import { VideoPrivacy } from '../../../../shared/models/videos' ; import { AccountModel } from '../../../models/account/account' ; import { VideoModel } from '../../../models/video/video' ; import { VideoShareModel } from '../../../models/video/video-share' ; import { getUpdateActivityPubUrl } from '../url' ; import { broadcastToFollowers , sendVideoRelatedActivity } from './utils' ; import { audiencify , getActorsInvolvedInVideo , getAudience } from '../audience' ; import { logger } from '../../../helpers/logger' ; import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model' ; import { MAccountDefault , MActor , MActorLight , MChannelDefault , MVideoAP , MVideoAPWithoutCaption , MVideoPlaylistFull , MVideoRedundancyVideo } from '../../../types/models' ; import { getServerActor } from '@server/models/application/application' ; async function sendUpdateVideo ( videoArg , t , overrodeByActor ? ) { const video = videoArg as MVideoAP ; if ( ! video . hasPrivacyForFederation ( ) ) return undefined ; logger . info ( 'Creating job to update video %s.' , video . url ) ; const byActor = overrodeByActor || video . VideoChannel . Account . Actor ; const url = getUpdateActivityPubUrl ( video . url , video . updatedAt . toISOString ( ) ) ; if ( ! video . VideoCaptions ) { video . VideoCaptions = await video . $get ( 'VideoCaptions' , { transaction : t } ) ; } const videoObject = video . toActivityPubObject ( ) ; const audience = getAudience ( byActor , video . privacy === VideoPrivacy . PUBLIC ) ; const updateActivity = buildUpdateActivity ( url , byActor , videoObject , audience ) ; const actorsInvolved = await getActorsInvolvedInVideo ( video , t ) ; if ( overrodeByActor ) actorsInvolved . push ( overrodeByActor ) ; return broadcastToFollowers ( updateActivity , byActor , actorsInvolved , t ) ; } async function sendUpdateActor ( accountOrChannel , t ) { const byActor = accountOrChannel . Actor ; logger . info ( 'Creating job to update actor %s.' , byActor . url ) ; const url = getUpdateActivityPubUrl ( byActor . url , byActor . updatedAt . toISOString ( ) ) ; const accountOrChannelObject = ( accountOrChannel as any ) . toActivityPubObject ( ) ; const audience = getAudience ( byActor ) ; const updateActivity = buildUpdateActivity ( url , byActor , accountOrChannelObject , audience ) ; let actorsInvolved ; if ( accountOrChannel instanceof AccountModel ) { actorsInvolved = await VideoShareModel . loadActorsWhoSharedVideosOf ( byActor . id , t ) ; } else { actorsInvolved = await VideoShareModel . loadActorsByVideoChannel ( accountOrChannel . id , t ) ; } actorsInvolved . push ( byActor ) ; return broadcastToFollowers ( updateActivity , byActor , actorsInvolved , t ) ; } async function sendUpdateCacheFile ( byActor , redundancyModel ) { logger . info ( 'Creating job to update cache file %s.' , redundancyModel . url ) ; const associatedVideo = redundancyModel . getVideo ( ) ; if ( ! associatedVideo ) { logger . warn ( 'Cannot send update activity for redundancy %s: no video files associated.' , redundancyModel . url ) ; return ; } const video = await VideoModel . loadAndPopulateAccountAndServerAndTags ( associatedVideo . id ) ; const activityBuilder = ( audience ) => { const redundancyObject = redundancyModel . toActivityPubObject ( ) ; const url = getUpdateActivityPubUrl ( redundancyModel . url , redundancyModel . updatedAt . toISOString ( ) ) ; return buildUpdateActivity ( url , byActor , redundancyObject , audience ) ; } ; return sendVideoRelatedActivity ( activityBuilder , { byActor , video , contextType : 'CacheFile' } ) ; } async function sendUpdateVideoPlaylist ( videoPlaylist , t ) { if ( videoPlaylist . privacy === VideoPlaylistPrivacy . PRIVATE ) return undefined ; const byActor = videoPlaylist . OwnerAccount . Actor ; logger . info ( 'Creating job to update video playlist %s.' , videoPlaylist . url ) ; const url = getUpdateActivityPubUrl ( videoPlaylist . url , videoPlaylist . updatedAt . toISOString ( ) ) ; const object = await videoPlaylist . toActivityPubObject ( null , t ) ; const audience = getAudience ( byActor , videoPlaylist . privacy === VideoPlaylistPrivacy . PUBLIC ) ; const updateActivity = buildUpdateActivity ( url , byActor , object , audience ) ; const serverActor = await getServerActor ( ) ; const toFollowersOf = [ byActor , serverActor ] ; if ( videoPlaylist . VideoChannel ) toFollowersOf . push ( videoPlaylist . VideoChannel . Actor ) ; return broadcastToFollowers ( updateActivity , byActor , toFollowersOf , t ) ; } export { sendUpdateActor , sendUpdateVideo , sendUpdateCacheFile , sendUpdateVideoPlaylist } ; function buildUpdateActivity ( url , byActor , object , audience ? ) { if ( ! audience ) audience = getAudience ( byActor ) ; return audiencify ( { type : 'Update' as 'Update' , id : url , actor : byActor . url , object : audiencify ( object , audience ) } , audience ) ; }