X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fmodels%2Fvideo%2Fvideo.ts;h=12b9375743702ce9c4778584ad7d66e0dbbcd957;hb=3726c3725506d0f8a26ded34f42d7bcfb5d0e639;hp=ba4cf541b49615ee63410772bfdce2be17ad2e6f;hpb=17ddba4950d72e07968a3e87e9ea68b7c61f5b97;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/models/video/video.ts b/server/models/video/video.ts index ba4cf541b..12b937574 100644 --- a/server/models/video/video.ts +++ b/server/models/video/video.ts @@ -25,7 +25,6 @@ import { UpdatedAt } from 'sequelize-typescript' import { buildNSFWFilter } from '@server/helpers/express-utils' -import { uuidToShort } from '@server/helpers/uuid' import { getPrivaciesForFederation, isPrivacyForFederation, isStateForFederation } from '@server/helpers/video' import { LiveManager } from '@server/lib/live/live-manager' import { removeHLSObjectStorage, removeWebTorrentObjectStorage } from '@server/lib/object-storage' @@ -33,14 +32,24 @@ import { getHLSDirectory, getHLSRedundancyDirectory } from '@server/lib/paths' import { VideoPathManager } from '@server/lib/video-path-manager' import { getServerActor } from '@server/models/application/application' import { ModelCache } from '@server/models/model-cache' -import { AttributesOnly, buildVideoEmbedPath, buildVideoWatchPath, pick } from '@shared/core-utils' -import { VideoInclude } from '@shared/models' -import { VideoFile } from '@shared/models/videos/video-file.model' -import { ResultList, UserRight, VideoPrivacy, VideoState } from '../../../shared' -import { VideoObject } from '../../../shared/models/activitypub/objects' -import { Video, VideoDetails, VideoRateType, VideoStorage } from '../../../shared/models/videos' -import { ThumbnailType } from '../../../shared/models/videos/thumbnail.type' -import { VideoStreamingPlaylistType } from '../../../shared/models/videos/video-streaming-playlist.type' +import { buildVideoEmbedPath, buildVideoWatchPath, pick } from '@shared/core-utils' +import { ffprobePromise, getAudioStream, uuidToShort } from '@shared/extra-utils' +import { + ResultList, + ThumbnailType, + UserRight, + Video, + VideoDetails, + VideoFile, + VideoInclude, + VideoObject, + VideoPrivacy, + VideoRateType, + VideoState, + VideoStorage, + VideoStreamingPlaylistType +} from '@shared/models' +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' @@ -746,7 +755,7 @@ export class VideoModel extends Model>> { // Remove physical files and torrents instance.VideoFiles.forEach(file => { - tasks.push(instance.removeFileAndTorrent(file)) + tasks.push(instance.removeWebTorrentFileAndTorrent(file)) }) // Remove playlists file @@ -1041,6 +1050,7 @@ export class VideoModel extends Model>> { languageOneOf?: string[] tagsOneOf?: string[] tagsAllOf?: string[] + privacyOneOf?: VideoPrivacy[] accountId?: number videoChannelId?: number @@ -1059,6 +1069,7 @@ export class VideoModel extends Model>> { search?: string }) { VideoModel.throwIfPrivateIncludeWithoutUser(options.include, options.user) + VideoModel.throwIfPrivacyOneOfWithoutUser(options.privacyOneOf, options.user) const trendingDays = options.sort.endsWith('trending') ? CONFIG.TRENDING.VIDEOS.INTERVAL_DAYS @@ -1082,6 +1093,7 @@ export class VideoModel extends Model>> { 'languageOneOf', 'tagsOneOf', 'tagsAllOf', + 'privacyOneOf', 'isLocal', 'include', 'displayOnlyForFollower', @@ -1119,6 +1131,7 @@ export class VideoModel extends Model>> { languageOneOf?: string[] tagsOneOf?: string[] tagsAllOf?: string[] + privacyOneOf?: VideoPrivacy[] displayOnlyForFollower: DisplayOnlyForFollowerOptions | null @@ -1140,6 +1153,7 @@ export class VideoModel extends Model>> { uuids?: string[] }) { VideoModel.throwIfPrivateIncludeWithoutUser(options.include, options.user) + VideoModel.throwIfPrivacyOneOfWithoutUser(options.privacyOneOf, options.user) const serverActor = await getServerActor() @@ -1153,6 +1167,7 @@ export class VideoModel extends Model>> { 'languageOneOf', 'tagsOneOf', 'tagsAllOf', + 'privacyOneOf', 'user', 'isLocal', 'host', @@ -1510,14 +1525,19 @@ export class VideoModel extends Model>> { private static throwIfPrivateIncludeWithoutUser (include: VideoInclude, user: MUserAccountId) { if (VideoModel.isPrivateInclude(include) && !user?.hasRight(UserRight.SEE_ALL_VIDEOS)) { - throw new Error('Try to filter all-local but no user has not the see all videos right') + throw new Error('Try to filter all-local but user cannot see all videos') + } + } + + private static throwIfPrivacyOneOfWithoutUser (privacyOneOf: VideoPrivacy[], user: MUserAccountId) { + if (privacyOneOf && !user?.hasRight(UserRight.SEE_ALL_VIDEOS)) { + throw new Error('Try to choose video privacies but user cannot see all videos') } } private static isPrivateInclude (include: VideoInclude) { return include & VideoInclude.BLACKLISTED || include & VideoInclude.BLOCKED_OWNER || - include & VideoInclude.HIDDEN_PRIVACY || include & VideoInclude.NOT_PUBLISHED_STATE } @@ -1658,12 +1678,20 @@ export class VideoModel extends Model>> { return peertubeTruncate(this.description, { length: maxLength }) } - getMaxQualityResolution () { + getMaxQualityFileInfo () { const file = this.getMaxQualityFile() const videoOrPlaylist = file.getVideoOrStreamingPlaylist() - return VideoPathManager.Instance.makeAvailableVideoFile(videoOrPlaylist, file, originalFilePath => { - return getVideoFileResolution(originalFilePath) + return VideoPathManager.Instance.makeAvailableVideoFile(file.withVideoOrPlaylist(videoOrPlaylist), async originalFilePath => { + const probe = await ffprobePromise(originalFilePath) + + const { audioStream } = await getAudioStream(originalFilePath, probe) + + return { + audioStream, + + ...await getVideoFileResolution(originalFilePath, probe) + } }) } @@ -1695,7 +1723,7 @@ export class VideoModel extends Model>> { .concat(toAdd) } - removeFileAndTorrent (videoFile: MVideoFile, isRedundancy = false) { + removeWebTorrentFileAndTorrent (videoFile: MVideoFile, isRedundancy = false) { const filePath = isRedundancy ? VideoPathManager.Instance.getFSRedundancyVideoFilePath(this, videoFile) : VideoPathManager.Instance.getFSVideoFileOutputPath(this, videoFile) @@ -1731,7 +1759,7 @@ export class VideoModel extends Model>> { ) if (streamingPlaylist.storage === VideoStorage.OBJECT_STORAGE) { - await removeHLSObjectStorage(streamingPlaylist, this) + await removeHLSObjectStorage(streamingPlaylist.withVideo(this)) } } } @@ -1754,8 +1782,8 @@ export class VideoModel extends Model>> { return this.hasPrivacyForFederation() === false && isPrivacyForFederation(newPrivacy) === true } - setAsRefreshed () { - return setAsUpdated('video', this.id) + setAsRefreshed (transaction?: Transaction) { + return setAsUpdated('video', this.id, transaction) } requiresAuth () {