aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/lib/activitypub/videos.ts
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-02-18 10:15:11 +0100
committerChocobozzz <chocobozzz@cpy.re>2021-02-18 13:38:09 +0100
commitd9a2a03196275065c28f4a0b7d4d7bc9992d77a1 (patch)
tree14579db95cd07506bf3d8e5c0af3ef1630e8700c /server/lib/activitypub/videos.ts
parent2451916e45420fedf556913ce121f3964c4b57d6 (diff)
downloadPeerTube-d9a2a03196275065c28f4a0b7d4d7bc9992d77a1.tar.gz
PeerTube-d9a2a03196275065c28f4a0b7d4d7bc9992d77a1.tar.zst
PeerTube-d9a2a03196275065c28f4a0b7d4d7bc9992d77a1.zip
Don't guess remote tracker URL
Diffstat (limited to 'server/lib/activitypub/videos.ts')
-rw-r--r--server/lib/activitypub/videos.ts59
1 files changed, 53 insertions, 6 deletions
diff --git a/server/lib/activitypub/videos.ts b/server/lib/activitypub/videos.ts
index a5f6537eb..66330a964 100644
--- a/server/lib/activitypub/videos.ts
+++ b/server/lib/activitypub/videos.ts
@@ -3,7 +3,8 @@ import { maxBy, minBy } from 'lodash'
3import * as magnetUtil from 'magnet-uri' 3import * as magnetUtil from 'magnet-uri'
4import { basename, join } from 'path' 4import { basename, join } from 'path'
5import * as request from 'request' 5import * as request from 'request'
6import * as sequelize from 'sequelize' 6import { Transaction } from 'sequelize/types'
7import { TrackerModel } from '@server/models/server/tracker'
7import { VideoLiveModel } from '@server/models/video/video-live' 8import { VideoLiveModel } from '@server/models/video/video-live'
8import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' 9import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
9import { 10import {
@@ -16,12 +17,16 @@ import {
16 ActivityUrlObject, 17 ActivityUrlObject,
17 ActivityVideoUrlObject 18 ActivityVideoUrlObject
18} from '../../../shared/index' 19} from '../../../shared/index'
19import { ActivityIconObject, VideoObject } from '../../../shared/models/activitypub/objects' 20import { ActivityIconObject, ActivityTrackerUrlObject, VideoObject } from '../../../shared/models/activitypub/objects'
20import { VideoPrivacy } from '../../../shared/models/videos' 21import { VideoPrivacy } from '../../../shared/models/videos'
21import { ThumbnailType } from '../../../shared/models/videos/thumbnail.type' 22import { ThumbnailType } from '../../../shared/models/videos/thumbnail.type'
22import { VideoStreamingPlaylistType } from '../../../shared/models/videos/video-streaming-playlist.type' 23import { VideoStreamingPlaylistType } from '../../../shared/models/videos/video-streaming-playlist.type'
23import { buildRemoteVideoBaseUrl, checkUrlsSameHost, getAPId } from '../../helpers/activitypub' 24import { buildRemoteVideoBaseUrl, checkUrlsSameHost, getAPId } from '../../helpers/activitypub'
24import { isAPVideoFileMetadataObject, sanitizeAndCheckVideoTorrentObject } from '../../helpers/custom-validators/activitypub/videos' 25import {
26 isAPVideoFileUrlMetadataObject,
27 isAPVideoTrackerUrlObject,
28 sanitizeAndCheckVideoTorrentObject
29} from '../../helpers/custom-validators/activitypub/videos'
25import { isArray } from '../../helpers/custom-validators/misc' 30import { isArray } from '../../helpers/custom-validators/misc'
26import { isVideoFileInfoHashValid } from '../../helpers/custom-validators/videos' 31import { isVideoFileInfoHashValid } from '../../helpers/custom-validators/videos'
27import { deleteNonExistingModels, resetSequelizeInstance, retryTransactionWrapper } from '../../helpers/database-utils' 32import { deleteNonExistingModels, resetSequelizeInstance, retryTransactionWrapper } from '../../helpers/database-utils'
@@ -83,7 +88,7 @@ import { addVideoShares, shareVideoByServerAndChannel } from './share'
83import { addVideoComments } from './video-comments' 88import { addVideoComments } from './video-comments'
84import { createRates } from './video-rates' 89import { createRates } from './video-rates'
85 90
86async function federateVideoIfNeeded (videoArg: MVideoAPWithoutCaption, isNewVideo: boolean, transaction?: sequelize.Transaction) { 91async function federateVideoIfNeeded (videoArg: MVideoAPWithoutCaption, isNewVideo: boolean, transaction?: Transaction) {
87 const video = videoArg as MVideoAP 92 const video = videoArg as MVideoAP
88 93
89 if ( 94 if (
@@ -433,6 +438,12 @@ async function updateVideoFromAP (options: {
433 await setVideoTags({ video: videoUpdated, tags, transaction: t, defaultValue: videoUpdated.Tags }) 438 await setVideoTags({ video: videoUpdated, tags, transaction: t, defaultValue: videoUpdated.Tags })
434 } 439 }
435 440
441 // Update trackers
442 {
443 const trackers = getTrackerUrls(videoObject, videoUpdated)
444 await setVideoTrackers({ video: videoUpdated, trackers, transaction: t })
445 }
446
436 { 447 {
437 // Update captions 448 // Update captions
438 await VideoCaptionModel.deleteAllCaptionsOfRemoteVideo(videoUpdated.id, t) 449 await VideoCaptionModel.deleteAllCaptionsOfRemoteVideo(videoUpdated.id, t)
@@ -577,7 +588,7 @@ function isAPVideoUrlObject (url: any): url is ActivityVideoUrlObject {
577 return MIMETYPES.VIDEO.MIMETYPE_EXT[urlMediaType] && urlMediaType.startsWith('video/') 588 return MIMETYPES.VIDEO.MIMETYPE_EXT[urlMediaType] && urlMediaType.startsWith('video/')
578} 589}
579 590
580function isAPStreamingPlaylistUrlObject (url: ActivityUrlObject): url is ActivityPlaylistUrlObject { 591function isAPStreamingPlaylistUrlObject (url: any): url is ActivityPlaylistUrlObject {
581 return url && url.mediaType === 'application/x-mpegURL' 592 return url && url.mediaType === 'application/x-mpegURL'
582} 593}
583 594
@@ -671,6 +682,12 @@ async function createVideo (videoObject: VideoObject, channel: MChannelAccountLi
671 }) 682 })
672 await Promise.all(videoCaptionsPromises) 683 await Promise.all(videoCaptionsPromises)
673 684
685 // Process trackers
686 {
687 const trackers = getTrackerUrls(videoObject, videoCreated)
688 await setVideoTrackers({ video: videoCreated, trackers, transaction: t })
689 }
690
674 videoCreated.VideoFiles = videoFiles 691 videoCreated.VideoFiles = videoFiles
675 692
676 if (videoCreated.isLive) { 693 if (videoCreated.isLive) {
@@ -797,7 +814,7 @@ function videoFileActivityUrlToDBAttributes (
797 : parsed.xs 814 : parsed.xs
798 815
799 // Fetch associated metadata url, if any 816 // Fetch associated metadata url, if any
800 const metadata = urls.filter(isAPVideoFileMetadataObject) 817 const metadata = urls.filter(isAPVideoFileUrlMetadataObject)
801 .find(u => { 818 .find(u => {
802 return u.height === fileUrl.height && 819 return u.height === fileUrl.height &&
803 u.fps === fileUrl.fps && 820 u.fps === fileUrl.fps &&
@@ -889,3 +906,33 @@ function getPreviewUrl (previewIcon: ActivityIconObject, video: MVideoWithHost)
889 ? previewIcon.url 906 ? previewIcon.url
890 : buildRemoteVideoBaseUrl(video, join(LAZY_STATIC_PATHS.PREVIEWS, video.generatePreviewName())) 907 : buildRemoteVideoBaseUrl(video, join(LAZY_STATIC_PATHS.PREVIEWS, video.generatePreviewName()))
891} 908}
909
910function getTrackerUrls (object: VideoObject, video: MVideoWithHost) {
911 let wsFound = false
912
913 const trackers = object.url.filter(u => isAPVideoTrackerUrlObject(u))
914 .map((u: ActivityTrackerUrlObject) => {
915 if (u.rel.includes('websocket')) wsFound = true
916
917 return u.href
918 })
919
920 if (wsFound) return trackers
921
922 return [
923 buildRemoteVideoBaseUrl(video, '/tracker/socket', REMOTE_SCHEME.WS),
924 buildRemoteVideoBaseUrl(video, '/tracker/announce')
925 ]
926}
927
928async function setVideoTrackers (options: {
929 video: MVideo
930 trackers: string[]
931 transaction?: Transaction
932}) {
933 const { video, trackers, transaction } = options
934
935 const trackerInstances = await TrackerModel.findOrCreateTrackers(trackers, transaction)
936
937 await video.$set('Trackers', trackerInstances, { transaction })
938}