send-update.ts 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import { Transaction } from 'sequelize'
  2. import { ActivityAudience, ActivityUpdate } from '../../../../shared/models/activitypub'
  3. import { VideoPrivacy } from '../../../../shared/models/videos'
  4. import { AccountModel } from '../../../models/account/account'
  5. import { VideoModel } from '../../../models/video/video'
  6. import { VideoShareModel } from '../../../models/video/video-share'
  7. import { getUpdateActivityPubUrl } from '../url'
  8. import { broadcastToFollowers, sendVideoRelatedActivity } from './utils'
  9. import { audiencify, getActorsInvolvedInVideo, getAudience } from '../audience'
  10. import { logger } from '../../../helpers/logger'
  11. import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model'
  12. import {
  13. MAccountDefault,
  14. MActor,
  15. MActorLight,
  16. MChannelDefault,
  17. MVideoAP,
  18. MVideoAPWithoutCaption,
  19. MVideoPlaylistFull,
  20. MVideoRedundancyVideo
  21. } from '../../../types/models'
  22. import { getServerActor } from '@server/models/application/application'
  23. async function sendUpdateVideo (videoArg: MVideoAPWithoutCaption, t: Transaction, overrodeByActor?: MActor) {
  24. const video = videoArg as MVideoAP
  25. if (!video.hasPrivacyForFederation()) return undefined
  26. logger.info('Creating job to update video %s.', video.url)
  27. const byActor = overrodeByActor || video.VideoChannel.Account.Actor
  28. const url = getUpdateActivityPubUrl(video.url, video.updatedAt.toISOString())
  29. // Needed to build the AP object
  30. if (!video.VideoCaptions) {
  31. video.VideoCaptions = await video.$get('VideoCaptions', { transaction: t })
  32. }
  33. const videoObject = video.toActivityPubObject()
  34. const audience = getAudience(byActor, video.privacy === VideoPrivacy.PUBLIC)
  35. const updateActivity = buildUpdateActivity(url, byActor, videoObject, audience)
  36. const actorsInvolved = await getActorsInvolvedInVideo(video, t)
  37. if (overrodeByActor) actorsInvolved.push(overrodeByActor)
  38. return broadcastToFollowers(updateActivity, byActor, actorsInvolved, t)
  39. }
  40. async function sendUpdateActor (accountOrChannel: MChannelDefault | MAccountDefault, t: Transaction) {
  41. const byActor = accountOrChannel.Actor
  42. logger.info('Creating job to update actor %s.', byActor.url)
  43. const url = getUpdateActivityPubUrl(byActor.url, byActor.updatedAt.toISOString())
  44. const accountOrChannelObject = (accountOrChannel as any).toActivityPubObject() // FIXME: typescript bug?
  45. const audience = getAudience(byActor)
  46. const updateActivity = buildUpdateActivity(url, byActor, accountOrChannelObject, audience)
  47. let actorsInvolved: MActor[]
  48. if (accountOrChannel instanceof AccountModel) {
  49. // Actors that shared my videos are involved too
  50. actorsInvolved = await VideoShareModel.loadActorsWhoSharedVideosOf(byActor.id, t)
  51. } else {
  52. // Actors that shared videos of my channel are involved too
  53. actorsInvolved = await VideoShareModel.loadActorsByVideoChannel(accountOrChannel.id, t)
  54. }
  55. actorsInvolved.push(byActor)
  56. return broadcastToFollowers(updateActivity, byActor, actorsInvolved, t)
  57. }
  58. async function sendUpdateCacheFile (byActor: MActorLight, redundancyModel: MVideoRedundancyVideo) {
  59. logger.info('Creating job to update cache file %s.', redundancyModel.url)
  60. const associatedVideo = redundancyModel.getVideo()
  61. if (!associatedVideo) {
  62. logger.warn('Cannot send update activity for redundancy %s: no video files associated.', redundancyModel.url)
  63. return
  64. }
  65. const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(associatedVideo.id)
  66. const activityBuilder = (audience: ActivityAudience) => {
  67. const redundancyObject = redundancyModel.toActivityPubObject()
  68. const url = getUpdateActivityPubUrl(redundancyModel.url, redundancyModel.updatedAt.toISOString())
  69. return buildUpdateActivity(url, byActor, redundancyObject, audience)
  70. }
  71. return sendVideoRelatedActivity(activityBuilder, { byActor, video, contextType: 'CacheFile' })
  72. }
  73. async function sendUpdateVideoPlaylist (videoPlaylist: MVideoPlaylistFull, t: Transaction) {
  74. if (videoPlaylist.privacy === VideoPlaylistPrivacy.PRIVATE) return undefined
  75. const byActor = videoPlaylist.OwnerAccount.Actor
  76. logger.info('Creating job to update video playlist %s.', videoPlaylist.url)
  77. const url = getUpdateActivityPubUrl(videoPlaylist.url, videoPlaylist.updatedAt.toISOString())
  78. const object = await videoPlaylist.toActivityPubObject(null, t)
  79. const audience = getAudience(byActor, videoPlaylist.privacy === VideoPlaylistPrivacy.PUBLIC)
  80. const updateActivity = buildUpdateActivity(url, byActor, object, audience)
  81. const serverActor = await getServerActor()
  82. const toFollowersOf = [ byActor, serverActor ]
  83. if (videoPlaylist.VideoChannel) toFollowersOf.push(videoPlaylist.VideoChannel.Actor)
  84. return broadcastToFollowers(updateActivity, byActor, toFollowersOf, t)
  85. }
  86. // ---------------------------------------------------------------------------
  87. export {
  88. sendUpdateActor,
  89. sendUpdateVideo,
  90. sendUpdateCacheFile,
  91. sendUpdateVideoPlaylist
  92. }
  93. // ---------------------------------------------------------------------------
  94. function buildUpdateActivity (url: string, byActor: MActorLight, object: any, audience?: ActivityAudience): ActivityUpdate {
  95. if (!audience) audience = getAudience(byActor)
  96. return audiencify(
  97. {
  98. type: 'Update' as 'Update',
  99. id: url,
  100. actor: byActor.url,
  101. object: audiencify(object, audience)
  102. },
  103. audience
  104. )
  105. }