Put private videos under a specific subdirectory

This commit is contained in:
Chocobozzz
2022-10-12 16:09:02 +02:00
committed by Chocobozzz
parent 38a3ccc7f8
commit 3545e72c68
105 changed files with 2929 additions and 1308 deletions

View File

@@ -34,6 +34,7 @@ import {
import {
MServer,
MStreamingPlaylistRedundanciesOpt,
MUserId,
MVideo,
MVideoAP,
MVideoFile,
@@ -245,8 +246,12 @@ function sortByResolutionDesc (fileA: MVideoFile, fileB: MVideoFile) {
function videoFilesModelToFormattedJSON (
video: MVideoFormattable,
videoFiles: MVideoFileRedundanciesOpt[],
includeMagnet = true
options: {
includeMagnet?: boolean // default true
} = {}
): VideoFile[] {
const { includeMagnet = true } = options
const trackerUrls = includeMagnet
? video.getTrackerUrls()
: []
@@ -281,11 +286,14 @@ function videoFilesModelToFormattedJSON (
})
}
function addVideoFilesInAPAcc (
acc: ActivityUrlObject[] | ActivityTagObject[],
video: MVideo,
function addVideoFilesInAPAcc (options: {
acc: ActivityUrlObject[] | ActivityTagObject[]
video: MVideo
files: MVideoFile[]
) {
user?: MUserId
}) {
const { acc, video, files } = options
const trackerUrls = video.getTrackerUrls()
const sortedFiles = (files || [])
@@ -370,7 +378,7 @@ function videoModelToActivityPubObject (video: MVideoAP): VideoObject {
}
]
addVideoFilesInAPAcc(url, video, video.VideoFiles || [])
addVideoFilesInAPAcc({ acc: url, video, files: video.VideoFiles || [] })
for (const playlist of (video.VideoStreamingPlaylists || [])) {
const tag = playlist.p2pMediaLoaderInfohashes
@@ -382,7 +390,7 @@ function videoModelToActivityPubObject (video: MVideoAP): VideoObject {
href: playlist.getSha256SegmentsUrl(video)
})
addVideoFilesInAPAcc(tag, video, playlist.VideoFiles || [])
addVideoFilesInAPAcc({ acc: tag, video, files: playlist.VideoFiles || [] })
url.push({
type: 'Link',

View File

@@ -24,6 +24,7 @@ import { extractVideo } from '@server/helpers/video'
import { buildRemoteVideoBaseUrl } from '@server/lib/activitypub/url'
import { getHLSPublicFileUrl, getWebTorrentPublicFileUrl } from '@server/lib/object-storage'
import { getFSTorrentFilePath } from '@server/lib/paths'
import { isVideoInPrivateDirectory } from '@server/lib/video-privacy'
import { isStreamingPlaylist, MStreamingPlaylistVideo, MVideo, MVideoWithHost } from '@server/types/models'
import { VideoResolution, VideoStorage } from '@shared/models'
import { AttributesOnly } from '@shared/typescript-utils'
@@ -295,6 +296,16 @@ export class VideoFileModel extends Model<Partial<AttributesOnly<VideoFileModel>
return VideoFileModel.findOne(query)
}
static loadWithVideoByFilename (filename: string): Promise<MVideoFileVideo | MVideoFileStreamingPlaylistVideo> {
const query = {
where: {
filename
}
}
return VideoFileModel.scope(ScopeNames.WITH_VIDEO_OR_PLAYLIST).findOne(query)
}
static loadWithVideoOrPlaylistByTorrentFilename (filename: string) {
const query = {
where: {
@@ -305,6 +316,10 @@ export class VideoFileModel extends Model<Partial<AttributesOnly<VideoFileModel>
return VideoFileModel.scope(ScopeNames.WITH_VIDEO_OR_PLAYLIST).findOne(query)
}
static load (id: number): Promise<MVideoFile> {
return VideoFileModel.findByPk(id)
}
static loadWithMetadata (id: number) {
return VideoFileModel.scope(ScopeNames.WITH_METADATA).findByPk(id)
}
@@ -467,7 +482,7 @@ export class VideoFileModel extends Model<Partial<AttributesOnly<VideoFileModel>
}
getVideoOrStreamingPlaylist (this: MVideoFileVideo | MVideoFileStreamingPlaylistVideo): MVideo | MStreamingPlaylistVideo {
if (this.videoId) return (this as MVideoFileVideo).Video
if (this.videoId || (this as MVideoFileVideo).Video) return (this as MVideoFileVideo).Video
return (this as MVideoFileStreamingPlaylistVideo).VideoStreamingPlaylist
}
@@ -508,7 +523,17 @@ export class VideoFileModel extends Model<Partial<AttributesOnly<VideoFileModel>
}
getFileStaticPath (video: MVideo) {
if (this.isHLS()) return join(STATIC_PATHS.STREAMING_PLAYLISTS.HLS, video.uuid, this.filename)
if (this.isHLS()) {
if (isVideoInPrivateDirectory(video.privacy)) {
return join(STATIC_PATHS.STREAMING_PLAYLISTS.PRIVATE_HLS, video.uuid, this.filename)
}
return join(STATIC_PATHS.STREAMING_PLAYLISTS.HLS, video.uuid, this.filename)
}
if (isVideoInPrivateDirectory(video.privacy)) {
return join(STATIC_PATHS.PRIVATE_WEBSEED, this.filename)
}
return join(STATIC_PATHS.WEBSEED, this.filename)
}

View File

@@ -17,6 +17,7 @@ import {
} from 'sequelize-typescript'
import { getHLSPublicFileUrl } from '@server/lib/object-storage'
import { generateHLSMasterPlaylistFilename, generateHlsSha256SegmentsFilename } from '@server/lib/paths'
import { isVideoInPrivateDirectory } from '@server/lib/video-privacy'
import { VideoFileModel } from '@server/models/video/video-file'
import { MStreamingPlaylist, MStreamingPlaylistFilesVideo, MVideo } from '@server/types/models'
import { sha1 } from '@shared/extra-utils'
@@ -250,7 +251,7 @@ export class VideoStreamingPlaylistModel extends Model<Partial<AttributesOnly<Vi
return getHLSPublicFileUrl(this.playlistUrl)
}
return WEBSERVER.URL + this.getMasterPlaylistStaticPath(video.uuid)
return WEBSERVER.URL + this.getMasterPlaylistStaticPath(video)
}
return this.playlistUrl
@@ -262,7 +263,7 @@ export class VideoStreamingPlaylistModel extends Model<Partial<AttributesOnly<Vi
return getHLSPublicFileUrl(this.segmentsSha256Url)
}
return WEBSERVER.URL + this.getSha256SegmentsStaticPath(video.uuid)
return WEBSERVER.URL + this.getSha256SegmentsStaticPath(video)
}
return this.segmentsSha256Url
@@ -287,11 +288,19 @@ export class VideoStreamingPlaylistModel extends Model<Partial<AttributesOnly<Vi
return Object.assign(this, { Video: video })
}
private getMasterPlaylistStaticPath (videoUUID: string) {
return join(STATIC_PATHS.STREAMING_PLAYLISTS.HLS, videoUUID, this.playlistFilename)
private getMasterPlaylistStaticPath (video: MVideo) {
if (isVideoInPrivateDirectory(video.privacy)) {
return join(STATIC_PATHS.STREAMING_PLAYLISTS.PRIVATE_HLS, video.uuid, this.playlistFilename)
}
return join(STATIC_PATHS.STREAMING_PLAYLISTS.HLS, video.uuid, this.playlistFilename)
}
private getSha256SegmentsStaticPath (videoUUID: string) {
return join(STATIC_PATHS.STREAMING_PLAYLISTS.HLS, videoUUID, this.segmentsSha256Filename)
private getSha256SegmentsStaticPath (video: MVideo) {
if (isVideoInPrivateDirectory(video.privacy)) {
return join(STATIC_PATHS.STREAMING_PLAYLISTS.PRIVATE_HLS, video.uuid, this.segmentsSha256Filename)
}
return join(STATIC_PATHS.STREAMING_PLAYLISTS.HLS, video.uuid, this.segmentsSha256Filename)
}
}

View File

@@ -52,7 +52,7 @@ import {
import { AttributesOnly } from '@shared/typescript-utils'
import { peertubeTruncate } from '../../helpers/core-utils'
import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
import { exists, isBooleanValid } from '../../helpers/custom-validators/misc'
import { exists, isBooleanValid, isUUIDValid } from '../../helpers/custom-validators/misc'
import {
isVideoDescriptionValid,
isVideoDurationValid,
@@ -1696,12 +1696,12 @@ export class VideoModel extends Model<Partial<AttributesOnly<VideoModel>>> {
let files: VideoFile[] = []
if (Array.isArray(this.VideoFiles)) {
const result = videoFilesModelToFormattedJSON(this, this.VideoFiles, includeMagnet)
const result = videoFilesModelToFormattedJSON(this, this.VideoFiles, { includeMagnet })
files = files.concat(result)
}
for (const p of (this.VideoStreamingPlaylists || [])) {
const result = videoFilesModelToFormattedJSON(this, p.VideoFiles, includeMagnet)
const result = videoFilesModelToFormattedJSON(this, p.VideoFiles, { includeMagnet })
files = files.concat(result)
}
@@ -1868,22 +1868,14 @@ export class VideoModel extends Model<Partial<AttributesOnly<VideoModel>>> {
return setAsUpdated('video', this.id, transaction)
}
requiresAuth () {
return this.privacy === VideoPrivacy.PRIVATE || this.privacy === VideoPrivacy.INTERNAL || !!this.VideoBlacklist
}
requiresAuth (paramId: string) {
if (this.privacy === VideoPrivacy.UNLISTED) {
if (!isUUIDValid(paramId)) return true
setPrivacy (newPrivacy: VideoPrivacy) {
if (this.privacy === VideoPrivacy.PRIVATE && newPrivacy !== VideoPrivacy.PRIVATE) {
this.publishedAt = new Date()
return false
}
this.privacy = newPrivacy
}
isConfidential () {
return this.privacy === VideoPrivacy.PRIVATE ||
this.privacy === VideoPrivacy.UNLISTED ||
this.privacy === VideoPrivacy.INTERNAL
return this.privacy === VideoPrivacy.PRIVATE || this.privacy === VideoPrivacy.INTERNAL || !!this.VideoBlacklist
}
async setNewState (newState: VideoState, isNewVideo: boolean, transaction: Transaction) {