diff options
Diffstat (limited to 'server/models')
-rw-r--r-- | server/models/video/formatter/video-format-utils.ts | 22 | ||||
-rw-r--r-- | server/models/video/video-file.ts | 29 | ||||
-rw-r--r-- | server/models/video/video-streaming-playlist.ts | 21 | ||||
-rw-r--r-- | server/models/video/video.ts | 24 |
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 { | |||
34 | import { | 34 | import { |
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) { | |||
245 | function videoFilesModelToFormattedJSON ( | 246 | function 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 | ||
284 | function addVideoFilesInAPAcc ( | 289 | function 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' | |||
24 | import { buildRemoteVideoBaseUrl } from '@server/lib/activitypub/url' | 24 | import { buildRemoteVideoBaseUrl } from '@server/lib/activitypub/url' |
25 | import { getHLSPublicFileUrl, getWebTorrentPublicFileUrl } from '@server/lib/object-storage' | 25 | import { getHLSPublicFileUrl, getWebTorrentPublicFileUrl } from '@server/lib/object-storage' |
26 | import { getFSTorrentFilePath } from '@server/lib/paths' | 26 | import { getFSTorrentFilePath } from '@server/lib/paths' |
27 | import { isVideoInPrivateDirectory } from '@server/lib/video-privacy' | ||
27 | import { isStreamingPlaylist, MStreamingPlaylistVideo, MVideo, MVideoWithHost } from '@server/types/models' | 28 | import { isStreamingPlaylist, MStreamingPlaylistVideo, MVideo, MVideoWithHost } from '@server/types/models' |
28 | import { VideoResolution, VideoStorage } from '@shared/models' | 29 | import { VideoResolution, VideoStorage } from '@shared/models' |
29 | import { AttributesOnly } from '@shared/typescript-utils' | 30 | import { 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' |
18 | import { getHLSPublicFileUrl } from '@server/lib/object-storage' | 18 | import { getHLSPublicFileUrl } from '@server/lib/object-storage' |
19 | import { generateHLSMasterPlaylistFilename, generateHlsSha256SegmentsFilename } from '@server/lib/paths' | 19 | import { generateHLSMasterPlaylistFilename, generateHlsSha256SegmentsFilename } from '@server/lib/paths' |
20 | import { isVideoInPrivateDirectory } from '@server/lib/video-privacy' | ||
20 | import { VideoFileModel } from '@server/models/video/video-file' | 21 | import { VideoFileModel } from '@server/models/video/video-file' |
21 | import { MStreamingPlaylist, MStreamingPlaylistFilesVideo, MVideo } from '@server/types/models' | 22 | import { MStreamingPlaylist, MStreamingPlaylistFilesVideo, MVideo } from '@server/types/models' |
22 | import { sha1 } from '@shared/extra-utils' | 23 | import { 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 { | |||
52 | import { AttributesOnly } from '@shared/typescript-utils' | 52 | import { AttributesOnly } from '@shared/typescript-utils' |
53 | import { peertubeTruncate } from '../../helpers/core-utils' | 53 | import { peertubeTruncate } from '../../helpers/core-utils' |
54 | import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' | 54 | import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' |
55 | import { exists, isBooleanValid } from '../../helpers/custom-validators/misc' | 55 | import { exists, isBooleanValid, isUUIDValid } from '../../helpers/custom-validators/misc' |
56 | import { | 56 | import { |
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) { |