share.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import { Transaction } from 'sequelize'
  2. import { VideoPrivacy } from '../../../shared/models/videos'
  3. import { getServerActor } from '../../helpers/utils'
  4. import { VideoModel } from '../../models/video/video'
  5. import { VideoShareModel } from '../../models/video/video-share'
  6. import { sendUndoAnnounce, sendVideoAnnounce } from './send'
  7. import { getAnnounceActivityPubUrl } from './url'
  8. import { VideoChannelModel } from '../../models/video/video-channel'
  9. import * as Bluebird from 'bluebird'
  10. import { doRequest } from '../../helpers/requests'
  11. import { getOrCreateActorAndServerAndModel } from './actor'
  12. import { logger } from '../../helpers/logger'
  13. import { CRAWL_REQUEST_CONCURRENCY } from '../../initializers'
  14. async function shareVideoByServerAndChannel (video: VideoModel, t: Transaction) {
  15. if (video.privacy === VideoPrivacy.PRIVATE) return undefined
  16. return Promise.all([
  17. shareByServer(video, t),
  18. shareByVideoChannel(video, t)
  19. ])
  20. }
  21. async function changeVideoChannelShare (video: VideoModel, oldVideoChannel: VideoChannelModel, t: Transaction) {
  22. logger.info('Updating video channel of video %s: %s -> %s.', video.uuid, oldVideoChannel.name, video.VideoChannel.name)
  23. await undoShareByVideoChannel(video, oldVideoChannel, t)
  24. await shareByVideoChannel(video, t)
  25. }
  26. async function addVideoShares (shareUrls: string[], instance: VideoModel) {
  27. await Bluebird.map(shareUrls, async shareUrl => {
  28. try {
  29. // Fetch url
  30. const { body } = await doRequest({
  31. uri: shareUrl,
  32. json: true,
  33. activityPub: true
  34. })
  35. if (!body || !body.actor) throw new Error('Body of body actor is invalid')
  36. const actorUrl = body.actor
  37. const actor = await getOrCreateActorAndServerAndModel(actorUrl)
  38. const entry = {
  39. actorId: actor.id,
  40. videoId: instance.id,
  41. url: shareUrl
  42. }
  43. await VideoShareModel.findOrCreate({
  44. where: {
  45. url: shareUrl
  46. },
  47. defaults: entry
  48. })
  49. } catch (err) {
  50. logger.warn('Cannot add share %s.', shareUrl, { err })
  51. }
  52. }, { concurrency: CRAWL_REQUEST_CONCURRENCY })
  53. }
  54. export {
  55. changeVideoChannelShare,
  56. addVideoShares,
  57. shareVideoByServerAndChannel
  58. }
  59. // ---------------------------------------------------------------------------
  60. async function shareByServer (video: VideoModel, t: Transaction) {
  61. const serverActor = await getServerActor()
  62. const serverShareUrl = getAnnounceActivityPubUrl(video.url, serverActor)
  63. return VideoShareModel.findOrCreate({
  64. defaults: {
  65. actorId: serverActor.id,
  66. videoId: video.id,
  67. url: serverShareUrl
  68. },
  69. where: {
  70. url: serverShareUrl
  71. },
  72. transaction: t
  73. }).then(([ serverShare, created ]) => {
  74. if (created) return sendVideoAnnounce(serverActor, serverShare, video, t)
  75. return undefined
  76. })
  77. }
  78. async function shareByVideoChannel (video: VideoModel, t: Transaction) {
  79. const videoChannelShareUrl = getAnnounceActivityPubUrl(video.url, video.VideoChannel.Actor)
  80. return VideoShareModel.findOrCreate({
  81. defaults: {
  82. actorId: video.VideoChannel.actorId,
  83. videoId: video.id,
  84. url: videoChannelShareUrl
  85. },
  86. where: {
  87. url: videoChannelShareUrl
  88. },
  89. transaction: t
  90. }).then(([ videoChannelShare, created ]) => {
  91. if (created) return sendVideoAnnounce(video.VideoChannel.Actor, videoChannelShare, video, t)
  92. return undefined
  93. })
  94. }
  95. async function undoShareByVideoChannel (video: VideoModel, oldVideoChannel: VideoChannelModel, t: Transaction) {
  96. // Load old share
  97. const oldShare = await VideoShareModel.load(oldVideoChannel.actorId, video.id, t)
  98. if (!oldShare) return new Error('Cannot find old video channel share ' + oldVideoChannel.actorId + ' for video ' + video.id)
  99. await sendUndoAnnounce(oldVideoChannel.Actor, oldShare, video, t)
  100. await oldShare.destroy({ transaction: t })
  101. }