Add ability to list and delete original file

In admin
This commit is contained in:
Chocobozzz
2024-03-26 14:05:19 +01:00
parent 058ef6912c
commit a159b8b517
21 changed files with 295 additions and 45 deletions

View File

@@ -4,7 +4,8 @@ export const VideoInclude = {
BLACKLISTED: 1 << 1,
BLOCKED_OWNER: 1 << 2,
FILES: 1 << 3,
CAPTIONS: 1 << 4
CAPTIONS: 1 << 4,
SOURCE: 1 << 5
} as const
export type VideoIncludeType = typeof VideoInclude[keyof typeof VideoInclude]

View File

@@ -4,6 +4,7 @@ import { VideoFile } from './file/index.js'
import { VideoConstant } from './video-constant.model.js'
import { VideoPrivacyType } from './video-privacy.enum.js'
import { VideoScheduleUpdate } from './video-schedule-update.model.js'
import { VideoSource } from './video-source.model.js'
import { VideoStateType } from './video-state.enum.js'
import { VideoStreamingPlaylist } from './video-streaming-playlist.model.js'
@@ -75,6 +76,8 @@ export interface VideoAdditionalAttributes {
files: VideoFile[]
streamingPlaylists: VideoStreamingPlaylist[]
videoSource: VideoSource
}
export interface VideoDetails extends Video {

View File

@@ -183,6 +183,20 @@ export class VideosCommand extends AbstractCommand {
})
}
deleteSource (options: OverrideCommandOptions & {
id: number | string
}) {
const path = '/api/v1/videos/' + options.id + '/source/file'
return this.deleteRequest({
...options,
path,
implicitToken: true,
defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
})
}
async getId (options: OverrideCommandOptions & {
uuid: number | string
}) {
@@ -273,12 +287,12 @@ export class VideosCommand extends AbstractCommand {
const privacyOneOf = getAllPrivacies()
return this.list({
...options,
include,
nsfw,
privacyOneOf,
...options,
token: this.buildCommonRequestToken({ ...options, implicitToken: true })
})
}

View File

@@ -209,6 +209,38 @@ describe('Test video sources API validator', function () {
})
})
describe('When deleting video source file', function () {
let userAccessToken: string
let videoId: string
before(async function () {
userAccessToken = await server.users.generateUserAndToken('user56')
await server.config.enableMinimumTranscoding({ keepOriginal: true })
const { uuid } = await server.videos.quickUpload({ name: 'with source' })
videoId = uuid
await waitJobs([ server ])
})
it('Should fail without token', async function () {
await server.videos.deleteSource({ id: videoId, token: null, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
})
it('Should fail with another user', async function () {
await server.videos.deleteSource({ id: videoId, token: userAccessToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
})
it('Should fail with an unknown video', async function () {
await server.videos.deleteSource({ id: 42, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
})
it('Should succeed with the correct params', async function () {
await server.videos.deleteSource({ id: videoId })
})
})
after(async function () {
await cleanupTests([ server ])
})

View File

@@ -48,7 +48,8 @@ describe('Test video filters validators', function () {
const validIncludes = [
VideoInclude.NONE,
VideoInclude.BLOCKED_OWNER,
VideoInclude.NOT_PUBLISHED_STATE | VideoInclude.BLACKLISTED
VideoInclude.NOT_PUBLISHED_STATE | VideoInclude.BLACKLISTED,
VideoInclude.SOURCE
]
async function testEndpoints (options: {

View File

@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
import { getAllFiles } from '@peertube/peertube-core-utils'
import { HttpStatusCode, VideoPrivacy } from '@peertube/peertube-models'
import { HttpStatusCode, VideoInclude, VideoPrivacy } from '@peertube/peertube-models'
import { areMockObjectStorageTestsDisabled } from '@peertube/peertube-node-utils'
import {
ObjectStorageCommand,
@@ -104,6 +104,20 @@ describe('Test video source management', function () {
expect(source.metadata?.streams).to.be.an('array')
})
it('Should include video source file when listing videos in admin', async function () {
const { total, data } = await servers[0].videos.listAllForAdmin({ include: VideoInclude.SOURCE, sort: 'publishedAt' })
expect(total).to.equal(2)
expect(data).to.have.lengthOf(2)
expect(data[0].videoSource).to.exist
expect(data[0].videoSource.inputFilename).to.equal(fixture1)
expect(data[0].videoSource.fileDownloadUrl).to.be.null
expect(data[1].videoSource).to.exist
expect(data[1].videoSource.inputFilename).to.equal(fixture2)
expect(data[1].videoSource.fileDownloadUrl).to.exist
})
it('Should have kept original video file', async function () {
await checkSourceFile({ server: servers[0], fsCount: 1, fixture: fixture2, uuid: uuids[uuids.length - 1] })
})
@@ -135,6 +149,33 @@ describe('Test video source management', function () {
expect(source.metadata?.streams).to.be.an('array')
})
it('Should delete video source file', async function () {
await servers[0].videos.deleteSource({ id: uuids[uuids.length - 1] })
const { total, data } = await servers[0].videos.listAllForAdmin({ include: VideoInclude.SOURCE, sort: 'publishedAt' })
expect(total).to.equal(3)
expect(data).to.have.lengthOf(3)
expect(data[0].videoSource).to.exist
expect(data[0].videoSource.inputFilename).to.equal(fixture1)
expect(data[0].videoSource.fileDownloadUrl).to.be.null
expect(data[1].videoSource).to.exist
expect(data[1].videoSource.inputFilename).to.equal(fixture2)
expect(data[1].videoSource.fileDownloadUrl).to.exist
expect(data[2].videoSource).to.exist
expect(data[2].videoSource.fileDownloadUrl).to.not.exist
expect(data[2].videoSource.createdAt).to.exist
expect(data[2].videoSource.fps).to.be.null
expect(data[2].videoSource.height).to.be.null
expect(data[2].videoSource.width).to.be.null
expect(data[2].videoSource.resolution.id).to.be.null
expect(data[2].videoSource.resolution.label).to.be.null
expect(data[2].videoSource.size).to.be.null
expect(data[2].videoSource.metadata).to.be.null
})
it('Should delete all videos and do not have original files anymore', async function () {
this.timeout(60000)