aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/video
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2022-10-12 16:09:02 +0200
committerChocobozzz <chocobozzz@cpy.re>2022-10-24 14:48:24 +0200
commit3545e72c686ff1725bbdfd8d16d693e2f4aa75a3 (patch)
treee7f1d12ef5dae1e1142c3a8d0b681c1dbbb0de10 /server/models/video
parent38a3ccc7f8ad0ea94362b58c732af7c387ab46be (diff)
downloadPeerTube-3545e72c686ff1725bbdfd8d16d693e2f4aa75a3.tar.gz
PeerTube-3545e72c686ff1725bbdfd8d16d693e2f4aa75a3.tar.zst
PeerTube-3545e72c686ff1725bbdfd8d16d693e2f4aa75a3.zip
Put private videos under a specific subdirectory
Diffstat (limited to 'server/models/video')
-rw-r--r--server/models/video/formatter/video-format-utils.ts22
-rw-r--r--server/models/video/video-file.ts29
-rw-r--r--server/models/video/video-streaming-playlist.ts21
-rw-r--r--server/models/video/video.ts24
4 files changed, 65 insertions, 31 deletions
diff --git a/server/models/video/formatter/video-format-utils.ts b/server/models/video/formatter/video-format-utils.ts
index e1b0eb610..76745f4b5 100644
--- a/server/models/video/formatter/video-format-utils.ts
+++ b/server/models/video/formatter/video-format-utils.ts
@@ -34,6 +34,7 @@ import {
34import { 34import {
35 MServer, 35 MServer,
36 MStreamingPlaylistRedundanciesOpt, 36 MStreamingPlaylistRedundanciesOpt,
37 MUserId,
37 MVideo, 38 MVideo,
38 MVideoAP, 39 MVideoAP,
39 MVideoFile, 40 MVideoFile,
@@ -245,8 +246,12 @@ function sortByResolutionDesc (fileA: MVideoFile, fileB: MVideoFile) {
245function videoFilesModelToFormattedJSON ( 246function videoFilesModelToFormattedJSON (
246 video: MVideoFormattable, 247 video: MVideoFormattable,
247 videoFiles: MVideoFileRedundanciesOpt[], 248 videoFiles: MVideoFileRedundanciesOpt[],
248 includeMagnet = true 249 options: {
250 includeMagnet?: boolean // default true
251 } = {}
249): VideoFile[] { 252): VideoFile[] {
253 const { includeMagnet = true } = options
254
250 const trackerUrls = includeMagnet 255 const trackerUrls = includeMagnet
251 ? video.getTrackerUrls() 256 ? video.getTrackerUrls()
252 : [] 257 : []
@@ -281,11 +286,14 @@ function videoFilesModelToFormattedJSON (
281 }) 286 })
282} 287}
283 288
284function addVideoFilesInAPAcc ( 289function addVideoFilesInAPAcc (options: {
285 acc: ActivityUrlObject[] | ActivityTagObject[], 290 acc: ActivityUrlObject[] | ActivityTagObject[]
286 video: MVideo, 291 video: MVideo
287 files: MVideoFile[] 292 files: MVideoFile[]
288) { 293 user?: MUserId
294}) {
295 const { acc, video, files } = options
296
289 const trackerUrls = video.getTrackerUrls() 297 const trackerUrls = video.getTrackerUrls()
290 298
291 const sortedFiles = (files || []) 299 const sortedFiles = (files || [])
@@ -370,7 +378,7 @@ function videoModelToActivityPubObject (video: MVideoAP): VideoObject {
370 } 378 }
371 ] 379 ]
372 380
373 addVideoFilesInAPAcc(url, video, video.VideoFiles || []) 381 addVideoFilesInAPAcc({ acc: url, video, files: video.VideoFiles || [] })
374 382
375 for (const playlist of (video.VideoStreamingPlaylists || [])) { 383 for (const playlist of (video.VideoStreamingPlaylists || [])) {
376 const tag = playlist.p2pMediaLoaderInfohashes 384 const tag = playlist.p2pMediaLoaderInfohashes
@@ -382,7 +390,7 @@ function videoModelToActivityPubObject (video: MVideoAP): VideoObject {
382 href: playlist.getSha256SegmentsUrl(video) 390 href: playlist.getSha256SegmentsUrl(video)
383 }) 391 })
384 392
385 addVideoFilesInAPAcc(tag, video, playlist.VideoFiles || []) 393 addVideoFilesInAPAcc({ acc: tag, video, files: playlist.VideoFiles || [] })
386 394
387 url.push({ 395 url.push({
388 type: 'Link', 396 type: 'Link',
diff --git a/server/models/video/video-file.ts b/server/models/video/video-file.ts
index d4f07f85f..1a608932f 100644
--- a/server/models/video/video-file.ts
+++ b/server/models/video/video-file.ts
@@ -24,6 +24,7 @@ import { extractVideo } from '@server/helpers/video'
24import { buildRemoteVideoBaseUrl } from '@server/lib/activitypub/url' 24import { buildRemoteVideoBaseUrl } from '@server/lib/activitypub/url'
25import { getHLSPublicFileUrl, getWebTorrentPublicFileUrl } from '@server/lib/object-storage' 25import { getHLSPublicFileUrl, getWebTorrentPublicFileUrl } from '@server/lib/object-storage'
26import { getFSTorrentFilePath } from '@server/lib/paths' 26import { getFSTorrentFilePath } from '@server/lib/paths'
27import { isVideoInPrivateDirectory } from '@server/lib/video-privacy'
27import { isStreamingPlaylist, MStreamingPlaylistVideo, MVideo, MVideoWithHost } from '@server/types/models' 28import { isStreamingPlaylist, MStreamingPlaylistVideo, MVideo, MVideoWithHost } from '@server/types/models'
28import { VideoResolution, VideoStorage } from '@shared/models' 29import { VideoResolution, VideoStorage } from '@shared/models'
29import { AttributesOnly } from '@shared/typescript-utils' 30import { AttributesOnly } from '@shared/typescript-utils'
@@ -295,6 +296,16 @@ export class VideoFileModel extends Model<Partial<AttributesOnly<VideoFileModel>
295 return VideoFileModel.findOne(query) 296 return VideoFileModel.findOne(query)
296 } 297 }
297 298
299 static loadWithVideoByFilename (filename: string): Promise<MVideoFileVideo | MVideoFileStreamingPlaylistVideo> {
300 const query = {
301 where: {
302 filename
303 }
304 }
305
306 return VideoFileModel.scope(ScopeNames.WITH_VIDEO_OR_PLAYLIST).findOne(query)
307 }
308
298 static loadWithVideoOrPlaylistByTorrentFilename (filename: string) { 309 static loadWithVideoOrPlaylistByTorrentFilename (filename: string) {
299 const query = { 310 const query = {
300 where: { 311 where: {
@@ -305,6 +316,10 @@ export class VideoFileModel extends Model<Partial<AttributesOnly<VideoFileModel>
305 return VideoFileModel.scope(ScopeNames.WITH_VIDEO_OR_PLAYLIST).findOne(query) 316 return VideoFileModel.scope(ScopeNames.WITH_VIDEO_OR_PLAYLIST).findOne(query)
306 } 317 }
307 318
319 static load (id: number): Promise<MVideoFile> {
320 return VideoFileModel.findByPk(id)
321 }
322
308 static loadWithMetadata (id: number) { 323 static loadWithMetadata (id: number) {
309 return VideoFileModel.scope(ScopeNames.WITH_METADATA).findByPk(id) 324 return VideoFileModel.scope(ScopeNames.WITH_METADATA).findByPk(id)
310 } 325 }
@@ -467,7 +482,7 @@ export class VideoFileModel extends Model<Partial<AttributesOnly<VideoFileModel>
467 } 482 }
468 483
469 getVideoOrStreamingPlaylist (this: MVideoFileVideo | MVideoFileStreamingPlaylistVideo): MVideo | MStreamingPlaylistVideo { 484 getVideoOrStreamingPlaylist (this: MVideoFileVideo | MVideoFileStreamingPlaylistVideo): MVideo | MStreamingPlaylistVideo {
470 if (this.videoId) return (this as MVideoFileVideo).Video 485 if (this.videoId || (this as MVideoFileVideo).Video) return (this as MVideoFileVideo).Video
471 486
472 return (this as MVideoFileStreamingPlaylistVideo).VideoStreamingPlaylist 487 return (this as MVideoFileStreamingPlaylistVideo).VideoStreamingPlaylist
473 } 488 }
@@ -508,7 +523,17 @@ export class VideoFileModel extends Model<Partial<AttributesOnly<VideoFileModel>
508 } 523 }
509 524
510 getFileStaticPath (video: MVideo) { 525 getFileStaticPath (video: MVideo) {
511 if (this.isHLS()) return join(STATIC_PATHS.STREAMING_PLAYLISTS.HLS, video.uuid, this.filename) 526 if (this.isHLS()) {
527 if (isVideoInPrivateDirectory(video.privacy)) {
528 return join(STATIC_PATHS.STREAMING_PLAYLISTS.PRIVATE_HLS, video.uuid, this.filename)
529 }
530
531 return join(STATIC_PATHS.STREAMING_PLAYLISTS.HLS, video.uuid, this.filename)
532 }
533
534 if (isVideoInPrivateDirectory(video.privacy)) {
535 return join(STATIC_PATHS.PRIVATE_WEBSEED, this.filename)
536 }
512 537
513 return join(STATIC_PATHS.WEBSEED, this.filename) 538 return join(STATIC_PATHS.WEBSEED, this.filename)
514 } 539 }
diff --git a/server/models/video/video-streaming-playlist.ts b/server/models/video/video-streaming-playlist.ts
index 2b6771f27..b919046ed 100644
--- a/server/models/video/video-streaming-playlist.ts
+++ b/server/models/video/video-streaming-playlist.ts
@@ -17,6 +17,7 @@ import {
17} from 'sequelize-typescript' 17} from 'sequelize-typescript'
18import { getHLSPublicFileUrl } from '@server/lib/object-storage' 18import { getHLSPublicFileUrl } from '@server/lib/object-storage'
19import { generateHLSMasterPlaylistFilename, generateHlsSha256SegmentsFilename } from '@server/lib/paths' 19import { generateHLSMasterPlaylistFilename, generateHlsSha256SegmentsFilename } from '@server/lib/paths'
20import { isVideoInPrivateDirectory } from '@server/lib/video-privacy'
20import { VideoFileModel } from '@server/models/video/video-file' 21import { VideoFileModel } from '@server/models/video/video-file'
21import { MStreamingPlaylist, MStreamingPlaylistFilesVideo, MVideo } from '@server/types/models' 22import { MStreamingPlaylist, MStreamingPlaylistFilesVideo, MVideo } from '@server/types/models'
22import { sha1 } from '@shared/extra-utils' 23import { sha1 } from '@shared/extra-utils'
@@ -250,7 +251,7 @@ export class VideoStreamingPlaylistModel extends Model<Partial<AttributesOnly<Vi
250 return getHLSPublicFileUrl(this.playlistUrl) 251 return getHLSPublicFileUrl(this.playlistUrl)
251 } 252 }
252 253
253 return WEBSERVER.URL + this.getMasterPlaylistStaticPath(video.uuid) 254 return WEBSERVER.URL + this.getMasterPlaylistStaticPath(video)
254 } 255 }
255 256
256 return this.playlistUrl 257 return this.playlistUrl
@@ -262,7 +263,7 @@ export class VideoStreamingPlaylistModel extends Model<Partial<AttributesOnly<Vi
262 return getHLSPublicFileUrl(this.segmentsSha256Url) 263 return getHLSPublicFileUrl(this.segmentsSha256Url)
263 } 264 }
264 265
265 return WEBSERVER.URL + this.getSha256SegmentsStaticPath(video.uuid) 266 return WEBSERVER.URL + this.getSha256SegmentsStaticPath(video)
266 } 267 }
267 268
268 return this.segmentsSha256Url 269 return this.segmentsSha256Url
@@ -287,11 +288,19 @@ export class VideoStreamingPlaylistModel extends Model<Partial<AttributesOnly<Vi
287 return Object.assign(this, { Video: video }) 288 return Object.assign(this, { Video: video })
288 } 289 }
289 290
290 private getMasterPlaylistStaticPath (videoUUID: string) { 291 private getMasterPlaylistStaticPath (video: MVideo) {
291 return join(STATIC_PATHS.STREAMING_PLAYLISTS.HLS, videoUUID, this.playlistFilename) 292 if (isVideoInPrivateDirectory(video.privacy)) {
293 return join(STATIC_PATHS.STREAMING_PLAYLISTS.PRIVATE_HLS, video.uuid, this.playlistFilename)
294 }
295
296 return join(STATIC_PATHS.STREAMING_PLAYLISTS.HLS, video.uuid, this.playlistFilename)
292 } 297 }
293 298
294 private getSha256SegmentsStaticPath (videoUUID: string) { 299 private getSha256SegmentsStaticPath (video: MVideo) {
295 return join(STATIC_PATHS.STREAMING_PLAYLISTS.HLS, videoUUID, this.segmentsSha256Filename) 300 if (isVideoInPrivateDirectory(video.privacy)) {
301 return join(STATIC_PATHS.STREAMING_PLAYLISTS.PRIVATE_HLS, video.uuid, this.segmentsSha256Filename)
302 }
303
304 return join(STATIC_PATHS.STREAMING_PLAYLISTS.HLS, video.uuid, this.segmentsSha256Filename)
296 } 305 }
297} 306}
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index 468117504..82362917e 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -52,7 +52,7 @@ import {
52import { AttributesOnly } from '@shared/typescript-utils' 52import { AttributesOnly } from '@shared/typescript-utils'
53import { peertubeTruncate } from '../../helpers/core-utils' 53import { peertubeTruncate } from '../../helpers/core-utils'
54import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' 54import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
55import { exists, isBooleanValid } from '../../helpers/custom-validators/misc' 55import { exists, isBooleanValid, isUUIDValid } from '../../helpers/custom-validators/misc'
56import { 56import {
57 isVideoDescriptionValid, 57 isVideoDescriptionValid,
58 isVideoDurationValid, 58 isVideoDurationValid,
@@ -1696,12 +1696,12 @@ export class VideoModel extends Model<Partial<AttributesOnly<VideoModel>>> {
1696 let files: VideoFile[] = [] 1696 let files: VideoFile[] = []
1697 1697
1698 if (Array.isArray(this.VideoFiles)) { 1698 if (Array.isArray(this.VideoFiles)) {
1699 const result = videoFilesModelToFormattedJSON(this, this.VideoFiles, includeMagnet) 1699 const result = videoFilesModelToFormattedJSON(this, this.VideoFiles, { includeMagnet })
1700 files = files.concat(result) 1700 files = files.concat(result)
1701 } 1701 }
1702 1702
1703 for (const p of (this.VideoStreamingPlaylists || [])) { 1703 for (const p of (this.VideoStreamingPlaylists || [])) {
1704 const result = videoFilesModelToFormattedJSON(this, p.VideoFiles, includeMagnet) 1704 const result = videoFilesModelToFormattedJSON(this, p.VideoFiles, { includeMagnet })
1705 files = files.concat(result) 1705 files = files.concat(result)
1706 } 1706 }
1707 1707
@@ -1868,22 +1868,14 @@ export class VideoModel extends Model<Partial<AttributesOnly<VideoModel>>> {
1868 return setAsUpdated('video', this.id, transaction) 1868 return setAsUpdated('video', this.id, transaction)
1869 } 1869 }
1870 1870
1871 requiresAuth () { 1871 requiresAuth (paramId: string) {
1872 return this.privacy === VideoPrivacy.PRIVATE || this.privacy === VideoPrivacy.INTERNAL || !!this.VideoBlacklist 1872 if (this.privacy === VideoPrivacy.UNLISTED) {
1873 } 1873 if (!isUUIDValid(paramId)) return true
1874 1874
1875 setPrivacy (newPrivacy: VideoPrivacy) { 1875 return false
1876 if (this.privacy === VideoPrivacy.PRIVATE && newPrivacy !== VideoPrivacy.PRIVATE) {
1877 this.publishedAt = new Date()
1878 } 1876 }
1879 1877
1880 this.privacy = newPrivacy 1878 return this.privacy === VideoPrivacy.PRIVATE || this.privacy === VideoPrivacy.INTERNAL || !!this.VideoBlacklist
1881 }
1882
1883 isConfidential () {
1884 return this.privacy === VideoPrivacy.PRIVATE ||
1885 this.privacy === VideoPrivacy.UNLISTED ||
1886 this.privacy === VideoPrivacy.INTERNAL
1887 } 1879 }
1888 1880
1889 async setNewState (newState: VideoState, isNewVideo: boolean, transaction: Transaction) { 1881 async setNewState (newState: VideoState, isNewVideo: boolean, transaction: Transaction) {