From af971e06c620bd46a5aa64c8833364e7022b5e3d Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 6 Jul 2021 15:22:51 +0200 Subject: Introduce search command --- shared/extra-utils/videos/videos.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'shared/extra-utils/videos') diff --git a/shared/extra-utils/videos/videos.ts b/shared/extra-utils/videos/videos.ts index 469ea4d63..a45c0402a 100644 --- a/shared/extra-utils/videos/videos.ts +++ b/shared/extra-utils/videos/videos.ts @@ -10,7 +10,7 @@ import validator from 'validator' import { getLowercaseExtension } from '@server/helpers/core-utils' import { buildUUID } from '@server/helpers/uuid' import { HttpStatusCode } from '@shared/core-utils' -import { VideosCommonQuery } from '@shared/models' +import { BooleanBothQuery, VideosCommonQuery } from '@shared/models' import { loadLanguages, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../server/initializers/constants' import { VideoDetails, VideoPrivacy } from '../../models/videos' import { @@ -159,7 +159,7 @@ function getVideosList (url: string) { .expect('Content-Type', /json/) } -function getVideosListWithToken (url: string, token: string, query: { nsfw?: boolean } = {}) { +function getVideosListWithToken (url: string, token: string, query: { nsfw?: BooleanBothQuery } = {}) { const path = '/api/v1/videos' return request(url) @@ -219,7 +219,7 @@ function getAccountVideos ( count: number, sort?: string, query: { - nsfw?: boolean + nsfw?: BooleanBothQuery search?: string } = {} ) { @@ -245,7 +245,7 @@ function getVideoChannelVideos ( start: number, count: number, sort?: string, - query: { nsfw?: boolean } = {} + query: { nsfw?: BooleanBothQuery } = {} ) { const path = '/api/v1/video-channels/' + videoChannelName + '/videos' -- cgit v1.2.3 From 4f2199144e428c16460750305f737b890c1ac322 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 8 Jul 2021 10:18:40 +0200 Subject: Introduce live command --- shared/extra-utils/videos/index.ts | 13 +++ shared/extra-utils/videos/live-command.ts | 156 ++++++++++++++++++++++++++++++ shared/extra-utils/videos/live.ts | 139 ++------------------------ 3 files changed, 175 insertions(+), 133 deletions(-) create mode 100644 shared/extra-utils/videos/index.ts create mode 100644 shared/extra-utils/videos/live-command.ts (limited to 'shared/extra-utils/videos') diff --git a/shared/extra-utils/videos/index.ts b/shared/extra-utils/videos/index.ts new file mode 100644 index 000000000..c9c884285 --- /dev/null +++ b/shared/extra-utils/videos/index.ts @@ -0,0 +1,13 @@ +export * from './live-command' +export * from './live' +export * from './services' +export * from './video-blacklist' +export * from './video-captions' +export * from './video-change-ownership' +export * from './video-channels' +export * from './video-comments' +export * from './video-history' +export * from './video-imports' +export * from './video-playlists' +export * from './video-streaming-playlists' +export * from './videos' diff --git a/shared/extra-utils/videos/live-command.ts b/shared/extra-utils/videos/live-command.ts new file mode 100644 index 000000000..55811b8ba --- /dev/null +++ b/shared/extra-utils/videos/live-command.ts @@ -0,0 +1,156 @@ +/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ + +import { readdir } from 'fs-extra' +import { omit } from 'lodash' +import { join } from 'path' +import { LiveVideo, LiveVideoCreate, LiveVideoUpdate, VideoCreateResult, VideoDetails, VideoState } from '@shared/models' +import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' +import { buildServerDirectory, wait } from '../miscs/miscs' +import { unwrapBody } from '../requests' +import { waitUntilLog } from '../server/servers' +import { AbstractCommand, OverrideCommandOptions } from '../shared' +import { sendRTMPStream, testFfmpegStreamError } from './live' +import { getVideoWithToken } from './videos' + +export class LiveCommand extends AbstractCommand { + + getLive (options: OverrideCommandOptions & { + videoId: number | string + }) { + const path = '/api/v1/videos/live' + + return this.getRequestBody({ + ...options, + + path: path + '/' + options.videoId, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + updateLive (options: OverrideCommandOptions & { + videoId: number | string + fields: LiveVideoUpdate + }) { + const { videoId, fields } = options + const path = '/api/v1/videos/live' + + return this.putBodyRequest({ + ...options, + + path: path + '/' + videoId, + fields, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } + + async createLive (options: OverrideCommandOptions & { + fields: LiveVideoCreate + }) { + const { fields } = options + const path = '/api/v1/videos/live' + + const attaches: any = {} + if (fields.thumbnailfile) attaches.thumbnailfile = fields.thumbnailfile + if (fields.previewfile) attaches.previewfile = fields.previewfile + + const body = await unwrapBody<{ video: VideoCreateResult }>(this.postUploadRequest({ + ...options, + + path, + attaches, + fields: omit(fields, 'thumbnailfile', 'previewfile'), + defaultExpectedStatus: HttpStatusCode.OK_200 + })) + + return body.video + } + + async sendRTMPStreamInVideo (options: OverrideCommandOptions & { + videoId: number | string + fixtureName?: string + }) { + const { videoId, fixtureName } = options + const videoLive = await this.getLive({ videoId }) + + return sendRTMPStream(videoLive.rtmpUrl, videoLive.streamKey, fixtureName) + } + + async runAndTestFfmpegStreamError (options: OverrideCommandOptions & { + videoId: number | string + shouldHaveError: boolean + }) { + const command = await this.sendRTMPStreamInVideo(options) + + return testFfmpegStreamError(command, options.shouldHaveError) + } + + waitUntilLivePublished (options: OverrideCommandOptions & { + videoId: number | string + }) { + const { videoId } = options + return this.waitUntilLiveState({ videoId, state: VideoState.PUBLISHED }) + } + + waitUntilLiveWaiting (options: OverrideCommandOptions & { + videoId: number | string + }) { + const { videoId } = options + return this.waitUntilLiveState({ videoId, state: VideoState.WAITING_FOR_LIVE }) + } + + waitUntilLiveEnded (options: OverrideCommandOptions & { + videoId: number | string + }) { + const { videoId } = options + return this.waitUntilLiveState({ videoId, state: VideoState.LIVE_ENDED }) + } + + waitUntilLiveSegmentGeneration (options: OverrideCommandOptions & { + videoUUID: string + resolution: number + segment: number + }) { + const { resolution, segment, videoUUID } = options + const segmentName = `${resolution}-00000${segment}.ts` + + return waitUntilLog(this.server, `${videoUUID}/${segmentName}`, 2, false) + } + + async waitUntilLiveSaved (options: OverrideCommandOptions & { + videoId: number | string + }) { + let video: VideoDetails + + do { + const res = await getVideoWithToken(this.server.url, options.token ?? this.server.accessToken, options.videoId) + video = res.body + + await wait(500) + } while (video.isLive === true && video.state.id !== VideoState.PUBLISHED) + } + + async getPlaylistsCount (options: OverrideCommandOptions & { + videoUUID: string + }) { + const basePath = buildServerDirectory(this.server, 'streaming-playlists') + const hlsPath = join(basePath, 'hls', options.videoUUID) + + const files = await readdir(hlsPath) + + return files.filter(f => f.endsWith('.m3u8')).length + } + + private async waitUntilLiveState (options: OverrideCommandOptions & { + videoId: number | string + state: VideoState + }) { + let video: VideoDetails + + do { + const res = await getVideoWithToken(this.server.url, options.token ?? this.server.accessToken, options.videoId) + video = res.body + + await wait(500) + } while (video.state.id !== options.state) + } +} diff --git a/shared/extra-utils/videos/live.ts b/shared/extra-utils/videos/live.ts index c0384769b..285a39c7e 100644 --- a/shared/extra-utils/videos/live.ts +++ b/shared/extra-utils/videos/live.ts @@ -3,69 +3,9 @@ import { expect } from 'chai' import * as ffmpeg from 'fluent-ffmpeg' import { pathExists, readdir } from 'fs-extra' -import { omit } from 'lodash' import { join } from 'path' -import { LiveVideo, LiveVideoCreate, LiveVideoUpdate, VideoDetails, VideoState } from '@shared/models' -import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' import { buildAbsoluteFixturePath, buildServerDirectory, wait } from '../miscs/miscs' -import { makeGetRequest, makePutBodyRequest, makeUploadRequest } from '../requests/requests' -import { ServerInfo, waitUntilLog } from '../server/servers' -import { getVideoWithToken } from './videos' - -function getLive (url: string, token: string, videoId: number | string, statusCodeExpected = HttpStatusCode.OK_200) { - const path = '/api/v1/videos/live' - - return makeGetRequest({ - url, - token, - path: path + '/' + videoId, - statusCodeExpected - }) -} - -function updateLive ( - url: string, - token: string, - videoId: number | string, - fields: LiveVideoUpdate, - statusCodeExpected = HttpStatusCode.NO_CONTENT_204 -) { - const path = '/api/v1/videos/live' - - return makePutBodyRequest({ - url, - token, - path: path + '/' + videoId, - fields, - statusCodeExpected - }) -} - -function createLive (url: string, token: string, fields: LiveVideoCreate, statusCodeExpected = HttpStatusCode.OK_200) { - const path = '/api/v1/videos/live' - - const attaches: any = {} - if (fields.thumbnailfile) attaches.thumbnailfile = fields.thumbnailfile - if (fields.previewfile) attaches.previewfile = fields.previewfile - - const updatedFields = omit(fields, 'thumbnailfile', 'previewfile') - - return makeUploadRequest({ - url, - path, - token, - attaches, - fields: updatedFields, - statusCodeExpected - }) -} - -async function sendRTMPStreamInVideo (url: string, token: string, videoId: number | string, fixtureName?: string) { - const res = await getLive(url, token, videoId) - const videoLive = res.body as LiveVideo - - return sendRTMPStream(videoLive.rtmpUrl, videoLive.streamKey, fixtureName) -} +import { ServerInfo } from '../server/servers' function sendRTMPStream (rtmpBaseUrl: string, streamKey: string, fixtureName = 'video_short.mp4') { const fixture = buildAbsoluteFixturePath(fixtureName) @@ -109,12 +49,6 @@ function waitFfmpegUntilError (command: ffmpeg.FfmpegCommand, successAfterMS = 1 }) } -async function runAndTestFfmpegStreamError (url: string, token: string, videoId: number | string, shouldHaveError: boolean) { - const command = await sendRTMPStreamInVideo(url, token, videoId) - - return testFfmpegStreamError(command, shouldHaveError) -} - async function testFfmpegStreamError (command: ffmpeg.FfmpegCommand, shouldHaveError: boolean) { let error: Error @@ -136,48 +70,9 @@ async function stopFfmpeg (command: ffmpeg.FfmpegCommand) { await wait(500) } -function waitUntilLivePublished (url: string, token: string, videoId: number | string) { - return waitUntilLiveState(url, token, videoId, VideoState.PUBLISHED) -} - -function waitUntilLiveWaiting (url: string, token: string, videoId: number | string) { - return waitUntilLiveState(url, token, videoId, VideoState.WAITING_FOR_LIVE) -} - -function waitUntilLiveEnded (url: string, token: string, videoId: number | string) { - return waitUntilLiveState(url, token, videoId, VideoState.LIVE_ENDED) -} - -function waitUntilLiveSegmentGeneration (server: ServerInfo, videoUUID: string, resolutionNum: number, segmentNum: number) { - const segmentName = `${resolutionNum}-00000${segmentNum}.ts` - return waitUntilLog(server, `${videoUUID}/${segmentName}`, 2, false) -} - -async function waitUntilLiveState (url: string, token: string, videoId: number | string, state: VideoState) { - let video: VideoDetails - - do { - const res = await getVideoWithToken(url, token, videoId) - video = res.body - - await wait(500) - } while (video.state.id !== state) -} - -async function waitUntilLiveSaved (url: string, token: string, videoId: number | string) { - let video: VideoDetails - - do { - const res = await getVideoWithToken(url, token, videoId) - video = res.body - - await wait(500) - } while (video.isLive === true && video.state.id !== VideoState.PUBLISHED) -} - async function waitUntilLivePublishedOnAllServers (servers: ServerInfo[], videoId: string) { for (const server of servers) { - await waitUntilLivePublished(server.url, server.accessToken, videoId) + await server.liveCommand.waitUntilLivePublished({ videoId }) } } @@ -206,33 +101,11 @@ async function checkLiveCleanup (server: ServerInfo, videoUUID: string, resoluti expect(files).to.contain('segments-sha256.json') } -async function getPlaylistsCount (server: ServerInfo, videoUUID: string) { - const basePath = buildServerDirectory(server, 'streaming-playlists') - const hlsPath = join(basePath, 'hls', videoUUID) - - const files = await readdir(hlsPath) - - return files.filter(f => f.endsWith('.m3u8')).length -} - -// --------------------------------------------------------------------------- - export { - getLive, - getPlaylistsCount, - waitUntilLiveSaved, - waitUntilLivePublished, - updateLive, - createLive, - runAndTestFfmpegStreamError, - checkLiveCleanup, - waitUntilLiveSegmentGeneration, - stopFfmpeg, - waitUntilLiveWaiting, - sendRTMPStreamInVideo, - waitUntilLiveEnded, + sendRTMPStream, waitFfmpegUntilError, + testFfmpegStreamError, + stopFfmpeg, waitUntilLivePublishedOnAllServers, - sendRTMPStream, - testFfmpegStreamError + checkLiveCleanup } -- cgit v1.2.3 From d897210c2db1ca2acc1e7b28a13127647ab2222c Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 8 Jul 2021 10:23:21 +0200 Subject: Introduce services command --- shared/extra-utils/videos/index.ts | 2 +- shared/extra-utils/videos/services-command.ts | 28 +++++++++++++++++++++++++++ shared/extra-utils/videos/services.ts | 24 ----------------------- 3 files changed, 29 insertions(+), 25 deletions(-) create mode 100644 shared/extra-utils/videos/services-command.ts delete mode 100644 shared/extra-utils/videos/services.ts (limited to 'shared/extra-utils/videos') diff --git a/shared/extra-utils/videos/index.ts b/shared/extra-utils/videos/index.ts index c9c884285..fe5dc6655 100644 --- a/shared/extra-utils/videos/index.ts +++ b/shared/extra-utils/videos/index.ts @@ -1,6 +1,6 @@ export * from './live-command' export * from './live' -export * from './services' +export * from './services-command' export * from './video-blacklist' export * from './video-captions' export * from './video-change-ownership' diff --git a/shared/extra-utils/videos/services-command.ts b/shared/extra-utils/videos/services-command.ts new file mode 100644 index 000000000..3b618ef66 --- /dev/null +++ b/shared/extra-utils/videos/services-command.ts @@ -0,0 +1,28 @@ +import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' +import { AbstractCommand, OverrideCommandOptions } from '../shared' + +export class ServicesCommand extends AbstractCommand { + + getOEmbed (options: OverrideCommandOptions & { + oembedUrl: string + format?: string + maxHeight?: number + maxWidth?: number + }) { + const path = '/services/oembed' + const query = { + url: options.oembedUrl, + format: options.format, + maxheight: options.maxHeight, + maxwidth: options.maxWidth + } + + return this.getRequest({ + ...options, + + path, + query, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } +} diff --git a/shared/extra-utils/videos/services.ts b/shared/extra-utils/videos/services.ts deleted file mode 100644 index e13a788bd..000000000 --- a/shared/extra-utils/videos/services.ts +++ /dev/null @@ -1,24 +0,0 @@ -import * as request from 'supertest' -import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' - -function getOEmbed (url: string, oembedUrl: string, format?: string, maxHeight?: number, maxWidth?: number) { - const path = '/services/oembed' - const query = { - url: oembedUrl, - format, - maxheight: maxHeight, - maxwidth: maxWidth - } - - return request(url) - .get(path) - .query(query) - .set('Accept', 'application/json') - .expect(HttpStatusCode.OK_200) -} - -// --------------------------------------------------------------------------- - -export { - getOEmbed -} -- cgit v1.2.3 From 04aed76711909507e74905bde3a7fa024d3585c9 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 8 Jul 2021 10:25:50 +0200 Subject: Shorter live methods --- shared/extra-utils/videos/live-command.ts | 30 +++++++++++++++--------------- shared/extra-utils/videos/live.ts | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'shared/extra-utils/videos') diff --git a/shared/extra-utils/videos/live-command.ts b/shared/extra-utils/videos/live-command.ts index 55811b8ba..e36c632ee 100644 --- a/shared/extra-utils/videos/live-command.ts +++ b/shared/extra-utils/videos/live-command.ts @@ -14,7 +14,7 @@ import { getVideoWithToken } from './videos' export class LiveCommand extends AbstractCommand { - getLive (options: OverrideCommandOptions & { + get (options: OverrideCommandOptions & { videoId: number | string }) { const path = '/api/v1/videos/live' @@ -27,7 +27,7 @@ export class LiveCommand extends AbstractCommand { }) } - updateLive (options: OverrideCommandOptions & { + update (options: OverrideCommandOptions & { videoId: number | string fields: LiveVideoUpdate }) { @@ -43,7 +43,7 @@ export class LiveCommand extends AbstractCommand { }) } - async createLive (options: OverrideCommandOptions & { + async create (options: OverrideCommandOptions & { fields: LiveVideoCreate }) { const { fields } = options @@ -70,12 +70,12 @@ export class LiveCommand extends AbstractCommand { fixtureName?: string }) { const { videoId, fixtureName } = options - const videoLive = await this.getLive({ videoId }) + const videoLive = await this.get({ videoId }) return sendRTMPStream(videoLive.rtmpUrl, videoLive.streamKey, fixtureName) } - async runAndTestFfmpegStreamError (options: OverrideCommandOptions & { + async runAndTestStreamError (options: OverrideCommandOptions & { videoId: number | string shouldHaveError: boolean }) { @@ -84,28 +84,28 @@ export class LiveCommand extends AbstractCommand { return testFfmpegStreamError(command, options.shouldHaveError) } - waitUntilLivePublished (options: OverrideCommandOptions & { + waitUntilPublished (options: OverrideCommandOptions & { videoId: number | string }) { const { videoId } = options - return this.waitUntilLiveState({ videoId, state: VideoState.PUBLISHED }) + return this.waitUntilState({ videoId, state: VideoState.PUBLISHED }) } - waitUntilLiveWaiting (options: OverrideCommandOptions & { + waitUntilWaiting (options: OverrideCommandOptions & { videoId: number | string }) { const { videoId } = options - return this.waitUntilLiveState({ videoId, state: VideoState.WAITING_FOR_LIVE }) + return this.waitUntilState({ videoId, state: VideoState.WAITING_FOR_LIVE }) } - waitUntilLiveEnded (options: OverrideCommandOptions & { + waitUntilEnded (options: OverrideCommandOptions & { videoId: number | string }) { const { videoId } = options - return this.waitUntilLiveState({ videoId, state: VideoState.LIVE_ENDED }) + return this.waitUntilState({ videoId, state: VideoState.LIVE_ENDED }) } - waitUntilLiveSegmentGeneration (options: OverrideCommandOptions & { + waitUntilSegmentGeneration (options: OverrideCommandOptions & { videoUUID: string resolution: number segment: number @@ -116,7 +116,7 @@ export class LiveCommand extends AbstractCommand { return waitUntilLog(this.server, `${videoUUID}/${segmentName}`, 2, false) } - async waitUntilLiveSaved (options: OverrideCommandOptions & { + async waitUntilSaved (options: OverrideCommandOptions & { videoId: number | string }) { let video: VideoDetails @@ -129,7 +129,7 @@ export class LiveCommand extends AbstractCommand { } while (video.isLive === true && video.state.id !== VideoState.PUBLISHED) } - async getPlaylistsCount (options: OverrideCommandOptions & { + async countPlaylists (options: OverrideCommandOptions & { videoUUID: string }) { const basePath = buildServerDirectory(this.server, 'streaming-playlists') @@ -140,7 +140,7 @@ export class LiveCommand extends AbstractCommand { return files.filter(f => f.endsWith('.m3u8')).length } - private async waitUntilLiveState (options: OverrideCommandOptions & { + private async waitUntilState (options: OverrideCommandOptions & { videoId: number | string state: VideoState }) { diff --git a/shared/extra-utils/videos/live.ts b/shared/extra-utils/videos/live.ts index 285a39c7e..92cb9104c 100644 --- a/shared/extra-utils/videos/live.ts +++ b/shared/extra-utils/videos/live.ts @@ -72,7 +72,7 @@ async function stopFfmpeg (command: ffmpeg.FfmpegCommand) { async function waitUntilLivePublishedOnAllServers (servers: ServerInfo[], videoId: string) { for (const server of servers) { - await server.liveCommand.waitUntilLivePublished({ videoId }) + await server.liveCommand.waitUntilPublished({ videoId }) } } -- cgit v1.2.3 From a1637fa1e25b60a88f7cfe50aac8953f50d55761 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 8 Jul 2021 10:55:16 +0200 Subject: Specify if we want to fallback to the server token --- shared/extra-utils/videos/live-command.ts | 3 +++ shared/extra-utils/videos/services-command.ts | 1 + 2 files changed, 4 insertions(+) (limited to 'shared/extra-utils/videos') diff --git a/shared/extra-utils/videos/live-command.ts b/shared/extra-utils/videos/live-command.ts index e36c632ee..4f03c9127 100644 --- a/shared/extra-utils/videos/live-command.ts +++ b/shared/extra-utils/videos/live-command.ts @@ -23,6 +23,7 @@ export class LiveCommand extends AbstractCommand { ...options, path: path + '/' + options.videoId, + implicitToken: true, defaultExpectedStatus: HttpStatusCode.OK_200 }) } @@ -39,6 +40,7 @@ export class LiveCommand extends AbstractCommand { path: path + '/' + videoId, fields, + implicitToken: true, defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 }) } @@ -59,6 +61,7 @@ export class LiveCommand extends AbstractCommand { path, attaches, fields: omit(fields, 'thumbnailfile', 'previewfile'), + implicitToken: true, defaultExpectedStatus: HttpStatusCode.OK_200 })) diff --git a/shared/extra-utils/videos/services-command.ts b/shared/extra-utils/videos/services-command.ts index 3b618ef66..313b7878c 100644 --- a/shared/extra-utils/videos/services-command.ts +++ b/shared/extra-utils/videos/services-command.ts @@ -22,6 +22,7 @@ export class ServicesCommand extends AbstractCommand { path, query, + implicitToken: false, defaultExpectedStatus: HttpStatusCode.OK_200 }) } -- cgit v1.2.3 From e3d15a6a9aed97a004d9dac1b7a6499d794e080a Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 8 Jul 2021 11:17:55 +0200 Subject: Introduce blacklist command --- shared/extra-utils/videos/blacklist-command.ts | 77 +++++++++++++++++++++++++ shared/extra-utils/videos/index.ts | 2 +- shared/extra-utils/videos/video-blacklist.ts | 79 -------------------------- 3 files changed, 78 insertions(+), 80 deletions(-) create mode 100644 shared/extra-utils/videos/blacklist-command.ts delete mode 100644 shared/extra-utils/videos/video-blacklist.ts (limited to 'shared/extra-utils/videos') diff --git a/shared/extra-utils/videos/blacklist-command.ts b/shared/extra-utils/videos/blacklist-command.ts new file mode 100644 index 000000000..fdae6b469 --- /dev/null +++ b/shared/extra-utils/videos/blacklist-command.ts @@ -0,0 +1,77 @@ + +import { ResultList } from '@shared/models' +import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' +import { VideoBlacklist, VideoBlacklistType } from '../../models/videos' +import { AbstractCommand, OverrideCommandOptions } from '../shared' + +export class BlacklistCommand extends AbstractCommand { + + add (options: OverrideCommandOptions & { + videoId: number | string + reason?: string + unfederate?: boolean + }) { + const { videoId, reason, unfederate } = options + const path = '/api/v1/videos/' + videoId + '/blacklist' + + return this.postBodyRequest({ + ...options, + + path, + fields: { reason, unfederate }, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } + + update (options: OverrideCommandOptions & { + videoId: number | string + reason?: string + }) { + const { videoId, reason } = options + const path = '/api/v1/videos/' + videoId + '/blacklist' + + return this.putBodyRequest({ + ...options, + + path, + fields: { reason }, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } + + remove (options: OverrideCommandOptions & { + videoId: number | string + }) { + const { videoId } = options + const path = '/api/v1/videos/' + videoId + '/blacklist' + + return this.deleteRequest({ + ...options, + + path, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } + + list (options: OverrideCommandOptions & { + sort?: string + type?: VideoBlacklistType + } = {}) { + const { sort, type } = options + const path = '/api/v1/videos/blacklist/' + + const query = { sort, type } + + return this.getRequestBody>({ + ...options, + + path, + query, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } +} diff --git a/shared/extra-utils/videos/index.ts b/shared/extra-utils/videos/index.ts index fe5dc6655..67f5faf54 100644 --- a/shared/extra-utils/videos/index.ts +++ b/shared/extra-utils/videos/index.ts @@ -1,7 +1,7 @@ +export * from './blacklist-command' export * from './live-command' export * from './live' export * from './services-command' -export * from './video-blacklist' export * from './video-captions' export * from './video-change-ownership' export * from './video-channels' diff --git a/shared/extra-utils/videos/video-blacklist.ts b/shared/extra-utils/videos/video-blacklist.ts deleted file mode 100644 index aa1548537..000000000 --- a/shared/extra-utils/videos/video-blacklist.ts +++ /dev/null @@ -1,79 +0,0 @@ -import * as request from 'supertest' -import { VideoBlacklistType } from '../../models/videos' -import { makeGetRequest } from '..' -import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' - -function addVideoToBlacklist ( - url: string, - token: string, - videoId: number | string, - reason?: string, - unfederate?: boolean, - specialStatus = HttpStatusCode.NO_CONTENT_204 -) { - const path = '/api/v1/videos/' + videoId + '/blacklist' - - return request(url) - .post(path) - .send({ reason, unfederate }) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(specialStatus) -} - -function updateVideoBlacklist ( - url: string, - token: string, - videoId: number, - reason?: string, - specialStatus = HttpStatusCode.NO_CONTENT_204 -) { - const path = '/api/v1/videos/' + videoId + '/blacklist' - - return request(url) - .put(path) - .send({ reason }) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(specialStatus) -} - -function removeVideoFromBlacklist (url: string, token: string, videoId: number | string, specialStatus = HttpStatusCode.NO_CONTENT_204) { - const path = '/api/v1/videos/' + videoId + '/blacklist' - - return request(url) - .delete(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(specialStatus) -} - -function getBlacklistedVideosList (parameters: { - url: string - token: string - sort?: string - type?: VideoBlacklistType - specialStatus?: HttpStatusCode -}) { - const { url, token, sort, type, specialStatus = HttpStatusCode.OK_200 } = parameters - const path = '/api/v1/videos/blacklist/' - - const query = { sort, type } - - return makeGetRequest({ - url, - path, - query, - token, - statusCodeExpected: specialStatus - }) -} - -// --------------------------------------------------------------------------- - -export { - addVideoToBlacklist, - removeVideoFromBlacklist, - getBlacklistedVideosList, - updateVideoBlacklist -} -- cgit v1.2.3 From a2470c9f4bfc7f49f4b94de935bacdd53fd54f29 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 8 Jul 2021 11:49:38 +0200 Subject: Introduce captions command --- shared/extra-utils/videos/captions-command.ts | 66 ++++++++++++++++++++++++ shared/extra-utils/videos/captions.ts | 17 +++++++ shared/extra-utils/videos/index.ts | 3 +- shared/extra-utils/videos/video-captions.ts | 72 --------------------------- 4 files changed, 85 insertions(+), 73 deletions(-) create mode 100644 shared/extra-utils/videos/captions-command.ts create mode 100644 shared/extra-utils/videos/captions.ts delete mode 100644 shared/extra-utils/videos/video-captions.ts (limited to 'shared/extra-utils/videos') diff --git a/shared/extra-utils/videos/captions-command.ts b/shared/extra-utils/videos/captions-command.ts new file mode 100644 index 000000000..908b6dae6 --- /dev/null +++ b/shared/extra-utils/videos/captions-command.ts @@ -0,0 +1,66 @@ +import { ResultList, VideoCaption } from '@shared/models' +import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' +import { buildAbsoluteFixturePath } from '../miscs/miscs' +import { AbstractCommand, OverrideCommandOptions } from '../shared' + +export class CaptionsCommand extends AbstractCommand { + + createVideoCaption (options: OverrideCommandOptions & { + videoId: string | number + language: string + fixture: string + mimeType?: string + }) { + const { videoId, language, fixture, mimeType } = options + + const path = '/api/v1/videos/' + videoId + '/captions/' + language + + const captionfile = buildAbsoluteFixturePath(fixture) + const captionfileAttach = mimeType + ? [ captionfile, { contentType: mimeType } ] + : captionfile + + return this.putUploadRequest({ + ...options, + + path, + fields: {}, + attaches: { + captionfile: captionfileAttach + }, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } + + listVideoCaptions (options: OverrideCommandOptions & { + videoId: string | number + }) { + const { videoId } = options + const path = '/api/v1/videos/' + videoId + '/captions' + + return this.getRequestBody>({ + ...options, + + path, + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + deleteVideoCaption (options: OverrideCommandOptions & { + videoId: string | number + language: string + }) { + const { videoId, language } = options + const path = '/api/v1/videos/' + videoId + '/captions/' + language + + return this.deleteRequest({ + ...options, + + path, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } +} diff --git a/shared/extra-utils/videos/captions.ts b/shared/extra-utils/videos/captions.ts new file mode 100644 index 000000000..2246bd133 --- /dev/null +++ b/shared/extra-utils/videos/captions.ts @@ -0,0 +1,17 @@ +import { expect } from 'chai' +import * as request from 'supertest' +import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' + +async function testCaptionFile (url: string, captionPath: string, containsString: string) { + const res = await request(url) + .get(captionPath) + .expect(HttpStatusCode.OK_200) + + expect(res.text).to.contain(containsString) +} + +// --------------------------------------------------------------------------- + +export { + testCaptionFile +} diff --git a/shared/extra-utils/videos/index.ts b/shared/extra-utils/videos/index.ts index 67f5faf54..03b4756d5 100644 --- a/shared/extra-utils/videos/index.ts +++ b/shared/extra-utils/videos/index.ts @@ -1,8 +1,9 @@ export * from './blacklist-command' +export * from './captions' +export * from './captions-command' export * from './live-command' export * from './live' export * from './services-command' -export * from './video-captions' export * from './video-change-ownership' export * from './video-channels' export * from './video-comments' diff --git a/shared/extra-utils/videos/video-captions.ts b/shared/extra-utils/videos/video-captions.ts deleted file mode 100644 index 62eec7b90..000000000 --- a/shared/extra-utils/videos/video-captions.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { makeDeleteRequest, makeGetRequest, makeUploadRequest } from '../requests/requests' -import * as request from 'supertest' -import * as chai from 'chai' -import { buildAbsoluteFixturePath } from '../miscs/miscs' -import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' - -const expect = chai.expect - -function createVideoCaption (args: { - url: string - accessToken: string - videoId: string | number - language: string - fixture: string - mimeType?: string - statusCodeExpected?: number -}) { - const path = '/api/v1/videos/' + args.videoId + '/captions/' + args.language - - const captionfile = buildAbsoluteFixturePath(args.fixture) - const captionfileAttach = args.mimeType ? [ captionfile, { contentType: args.mimeType } ] : captionfile - - return makeUploadRequest({ - method: 'PUT', - url: args.url, - path, - token: args.accessToken, - fields: {}, - attaches: { - captionfile: captionfileAttach - }, - statusCodeExpected: args.statusCodeExpected || HttpStatusCode.NO_CONTENT_204 - }) -} - -function listVideoCaptions (url: string, videoId: string | number) { - const path = '/api/v1/videos/' + videoId + '/captions' - - return makeGetRequest({ - url, - path, - statusCodeExpected: HttpStatusCode.OK_200 - }) -} - -function deleteVideoCaption (url: string, token: string, videoId: string | number, language: string) { - const path = '/api/v1/videos/' + videoId + '/captions/' + language - - return makeDeleteRequest({ - url, - token, - path, - statusCodeExpected: HttpStatusCode.NO_CONTENT_204 - }) -} - -async function testCaptionFile (url: string, captionPath: string, containsString: string) { - const res = await request(url) - .get(captionPath) - .expect(HttpStatusCode.OK_200) - - expect(res.text).to.contain(containsString) -} - -// --------------------------------------------------------------------------- - -export { - createVideoCaption, - listVideoCaptions, - testCaptionFile, - deleteVideoCaption -} -- cgit v1.2.3 From 72cbfc5695ec5ebdb9721d3648218f63feeaeac5 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 8 Jul 2021 13:56:04 +0200 Subject: Introduce change ownership command --- .../extra-utils/videos/change-ownership-command.ts | 69 +++++++++++++++++++++ shared/extra-utils/videos/index.ts | 2 +- .../extra-utils/videos/video-change-ownership.ts | 72 ---------------------- 3 files changed, 70 insertions(+), 73 deletions(-) create mode 100644 shared/extra-utils/videos/change-ownership-command.ts delete mode 100644 shared/extra-utils/videos/video-change-ownership.ts (limited to 'shared/extra-utils/videos') diff --git a/shared/extra-utils/videos/change-ownership-command.ts b/shared/extra-utils/videos/change-ownership-command.ts new file mode 100644 index 000000000..03f77a95f --- /dev/null +++ b/shared/extra-utils/videos/change-ownership-command.ts @@ -0,0 +1,69 @@ + +import { ResultList, VideoChangeOwnership } from '@shared/models' +import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' +import { AbstractCommand, OverrideCommandOptions } from '../shared' + +export class ChangeOwnershipCommand extends AbstractCommand { + + create (options: OverrideCommandOptions & { + videoId: number | string + username: string + }) { + const { videoId, username } = options + const path = '/api/v1/videos/' + videoId + '/give-ownership' + + return this.postBodyRequest({ + ...options, + + path, + fields: { username }, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } + + list (options: OverrideCommandOptions = {}) { + const path = '/api/v1/videos/ownership' + + return this.getRequestBody>({ + ...options, + + path, + query: { sort: '-createdAt' }, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + accept (options: OverrideCommandOptions & { + ownershipId: number + channelId: number + }) { + const { ownershipId, channelId } = options + const path = '/api/v1/videos/ownership/' + ownershipId + '/accept' + + return this.postBodyRequest({ + ...options, + + path, + fields: { channelId }, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } + + refuse (options: OverrideCommandOptions & { + ownershipId: number + }) { + const { ownershipId } = options + const path = '/api/v1/videos/ownership/' + ownershipId + '/refuse' + + return this.postBodyRequest({ + ...options, + + path, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } +} diff --git a/shared/extra-utils/videos/index.ts b/shared/extra-utils/videos/index.ts index 03b4756d5..815c7f944 100644 --- a/shared/extra-utils/videos/index.ts +++ b/shared/extra-utils/videos/index.ts @@ -1,10 +1,10 @@ export * from './blacklist-command' export * from './captions' export * from './captions-command' +export * from './change-ownership-command' export * from './live-command' export * from './live' export * from './services-command' -export * from './video-change-ownership' export * from './video-channels' export * from './video-comments' export * from './video-history' diff --git a/shared/extra-utils/videos/video-change-ownership.ts b/shared/extra-utils/videos/video-change-ownership.ts deleted file mode 100644 index ef82a7636..000000000 --- a/shared/extra-utils/videos/video-change-ownership.ts +++ /dev/null @@ -1,72 +0,0 @@ -import * as request from 'supertest' -import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' - -function changeVideoOwnership ( - url: string, - token: string, - videoId: number | string, - username, - expectedStatus = HttpStatusCode.NO_CONTENT_204 -) { - const path = '/api/v1/videos/' + videoId + '/give-ownership' - - return request(url) - .post(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .send({ username }) - .expect(expectedStatus) -} - -function getVideoChangeOwnershipList (url: string, token: string) { - const path = '/api/v1/videos/ownership' - - return request(url) - .get(path) - .query({ sort: '-createdAt' }) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(HttpStatusCode.OK_200) - .expect('Content-Type', /json/) -} - -function acceptChangeOwnership ( - url: string, - token: string, - ownershipId: string, - channelId: number, - expectedStatus = HttpStatusCode.NO_CONTENT_204 -) { - const path = '/api/v1/videos/ownership/' + ownershipId + '/accept' - - return request(url) - .post(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .send({ channelId }) - .expect(expectedStatus) -} - -function refuseChangeOwnership ( - url: string, - token: string, - ownershipId: string, - expectedStatus = HttpStatusCode.NO_CONTENT_204 -) { - const path = '/api/v1/videos/ownership/' + ownershipId + '/refuse' - - return request(url) - .post(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(expectedStatus) -} - -// --------------------------------------------------------------------------- - -export { - changeVideoOwnership, - getVideoChangeOwnershipList, - acceptChangeOwnership, - refuseChangeOwnership -} -- cgit v1.2.3 From e6346d59e63135cf012ed18c102d3b0179ef565f Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 8 Jul 2021 15:54:39 +0200 Subject: Introduce playlist command --- shared/extra-utils/videos/index.ts | 3 +- shared/extra-utils/videos/playlists-command.ts | 280 ++++++++++++++++++++++ shared/extra-utils/videos/playlists.ts | 25 ++ shared/extra-utils/videos/video-playlists.ts | 320 ------------------------- shared/extra-utils/videos/videos.ts | 23 -- 5 files changed, 307 insertions(+), 344 deletions(-) create mode 100644 shared/extra-utils/videos/playlists-command.ts create mode 100644 shared/extra-utils/videos/playlists.ts delete mode 100644 shared/extra-utils/videos/video-playlists.ts (limited to 'shared/extra-utils/videos') diff --git a/shared/extra-utils/videos/index.ts b/shared/extra-utils/videos/index.ts index 815c7f944..1f6241d7e 100644 --- a/shared/extra-utils/videos/index.ts +++ b/shared/extra-utils/videos/index.ts @@ -4,11 +4,12 @@ export * from './captions-command' export * from './change-ownership-command' export * from './live-command' export * from './live' +export * from './playlists-command' +export * from './playlists' export * from './services-command' export * from './video-channels' export * from './video-comments' export * from './video-history' export * from './video-imports' -export * from './video-playlists' export * from './video-streaming-playlists' export * from './videos' diff --git a/shared/extra-utils/videos/playlists-command.ts b/shared/extra-utils/videos/playlists-command.ts new file mode 100644 index 000000000..f77decc1a --- /dev/null +++ b/shared/extra-utils/videos/playlists-command.ts @@ -0,0 +1,280 @@ +import { omit, pick } from 'lodash' +import { + BooleanBothQuery, + ResultList, + VideoExistInPlaylist, + VideoPlaylist, + VideoPlaylistCreateResult, + VideoPlaylistElement, + VideoPlaylistElementCreateResult, + VideoPlaylistReorder +} from '@shared/models' +import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' +import { VideoPlaylistCreate } from '../../models/videos/playlist/video-playlist-create.model' +import { VideoPlaylistElementCreate } from '../../models/videos/playlist/video-playlist-element-create.model' +import { VideoPlaylistElementUpdate } from '../../models/videos/playlist/video-playlist-element-update.model' +import { VideoPlaylistType } from '../../models/videos/playlist/video-playlist-type.model' +import { VideoPlaylistUpdate } from '../../models/videos/playlist/video-playlist-update.model' +import { unwrapBody } from '../requests' +import { AbstractCommand, OverrideCommandOptions } from '../shared' +import { videoUUIDToId } from './videos' + +export class PlaylistsCommand extends AbstractCommand { + + list (options: OverrideCommandOptions & { + start?: number + count?: number + sort?: string + }) { + const path = '/api/v1/video-playlists' + const query = pick(options, [ 'start', 'count', 'sort' ]) + + return this.getRequestBody>({ + ...options, + + path, + query, + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + listByChannel (options: OverrideCommandOptions & { + handle: string + start?: number + count?: number + sort?: string + }) { + const path = '/api/v1/video-channels/' + options.handle + '/video-playlists' + const query = pick(options, [ 'start', 'count', 'sort' ]) + + return this.getRequestBody>({ + ...options, + + path, + query, + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + listByAccount (options: OverrideCommandOptions & { + handle: string + start?: number + count?: number + sort?: string + search?: string + playlistType?: VideoPlaylistType + }) { + const path = '/api/v1/accounts/' + options.handle + '/video-playlists' + const query = pick(options, [ 'start', 'count', 'sort', 'search', 'playlistType' ]) + + return this.getRequestBody>({ + ...options, + + path, + query, + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + get (options: OverrideCommandOptions & { + playlistId: number | string + }) { + const { playlistId } = options + const path = '/api/v1/video-playlists/' + playlistId + + return this.getRequestBody({ + ...options, + + path, + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + listVideos (options: OverrideCommandOptions & { + playlistId: number | string + start?: number + count?: number + query?: { nsfw?: BooleanBothQuery } + }) { + const path = '/api/v1/video-playlists/' + options.playlistId + '/videos' + const query = options.query ?? {} + + return this.getRequestBody>({ + ...options, + + path, + query: { + ...query, + start: options.start, + count: options.count + }, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + delete (options: OverrideCommandOptions & { + playlistId: number | string + }) { + const path = '/api/v1/video-playlists/' + options.playlistId + + return this.deleteRequest({ + ...options, + + path, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } + + async create (options: OverrideCommandOptions & { + attributes: VideoPlaylistCreate + }) { + const path = '/api/v1/video-playlists' + + const fields = omit(options.attributes, 'thumbnailfile') + + const attaches = options.attributes.thumbnailfile + ? { thumbnailfile: options.attributes.thumbnailfile } + : {} + + const body = await unwrapBody<{ videoPlaylist: VideoPlaylistCreateResult }>(this.postUploadRequest({ + ...options, + + path, + fields, + attaches, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.OK_200 + })) + + return body.videoPlaylist + } + + update (options: OverrideCommandOptions & { + attributes: VideoPlaylistUpdate + playlistId: number | string + }) { + const path = '/api/v1/video-playlists/' + options.playlistId + + const fields = omit(options.attributes, 'thumbnailfile') + + const attaches = options.attributes.thumbnailfile + ? { thumbnailfile: options.attributes.thumbnailfile } + : {} + + return this.putUploadRequest({ + ...options, + + path, + fields, + attaches, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } + + async addElement (options: OverrideCommandOptions & { + playlistId: number | string + attributes: VideoPlaylistElementCreate | { videoId: string } + }) { + const attributes = { + ...options.attributes, + + videoId: await videoUUIDToId(this.server.url, options.attributes.videoId) + } + + const path = '/api/v1/video-playlists/' + options.playlistId + '/videos' + + const body = await unwrapBody<{ videoPlaylistElement: VideoPlaylistElementCreateResult }>(this.postBodyRequest({ + ...options, + + path, + fields: attributes, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.OK_200 + })) + + return body.videoPlaylistElement + } + + updateElement (options: OverrideCommandOptions & { + playlistId: number | string + elementId: number | string + attributes: VideoPlaylistElementUpdate + }) { + const path = '/api/v1/video-playlists/' + options.playlistId + '/videos/' + options.elementId + + return this.putBodyRequest({ + ...options, + + path, + fields: options.attributes, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } + + removeElement (options: OverrideCommandOptions & { + playlistId: number | string + elementId: number + }) { + const path = '/api/v1/video-playlists/' + options.playlistId + '/videos/' + options.elementId + + return this.deleteRequest({ + ...options, + + path, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } + + reorderElements (options: OverrideCommandOptions & { + playlistId: number | string + attributes: VideoPlaylistReorder + }) { + const path = '/api/v1/video-playlists/' + options.playlistId + '/videos/reorder' + + return this.postBodyRequest({ + ...options, + + path, + fields: options.attributes, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } + + getPrivacies (options: OverrideCommandOptions = {}) { + const path = '/api/v1/video-playlists/privacies' + + return this.getRequestBody<{ [ id: number ]: string }>({ + ...options, + + path, + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + videosExist (options: OverrideCommandOptions & { + videoIds: number[] + }) { + const { videoIds } = options + const path = '/api/v1/users/me/video-playlists/videos-exist' + + return this.getRequestBody({ + ...options, + + path, + query: { videoIds }, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } +} diff --git a/shared/extra-utils/videos/playlists.ts b/shared/extra-utils/videos/playlists.ts new file mode 100644 index 000000000..023333c87 --- /dev/null +++ b/shared/extra-utils/videos/playlists.ts @@ -0,0 +1,25 @@ +import { expect } from 'chai' +import { readdir } from 'fs-extra' +import { join } from 'path' +import { root } from '../' + +async function checkPlaylistFilesWereRemoved ( + playlistUUID: string, + internalServerNumber: number, + directories = [ 'thumbnails' ] +) { + const testDirectory = 'test' + internalServerNumber + + for (const directory of directories) { + const directoryPath = join(root(), testDirectory, directory) + + const files = await readdir(directoryPath) + for (const file of files) { + expect(file).to.not.contain(playlistUUID) + } + } +} + +export { + checkPlaylistFilesWereRemoved +} diff --git a/shared/extra-utils/videos/video-playlists.ts b/shared/extra-utils/videos/video-playlists.ts deleted file mode 100644 index c6f799e5d..000000000 --- a/shared/extra-utils/videos/video-playlists.ts +++ /dev/null @@ -1,320 +0,0 @@ -import { makeDeleteRequest, makeGetRequest, makePostBodyRequest, makePutBodyRequest, makeUploadRequest } from '../requests/requests' -import { VideoPlaylistCreate } from '../../models/videos/playlist/video-playlist-create.model' -import { omit } from 'lodash' -import { VideoPlaylistUpdate } from '../../models/videos/playlist/video-playlist-update.model' -import { VideoPlaylistElementCreate } from '../../models/videos/playlist/video-playlist-element-create.model' -import { VideoPlaylistElementUpdate } from '../../models/videos/playlist/video-playlist-element-update.model' -import { videoUUIDToId } from './videos' -import { join } from 'path' -import { root } from '..' -import { readdir } from 'fs-extra' -import { expect } from 'chai' -import { VideoPlaylistType } from '../../models/videos/playlist/video-playlist-type.model' -import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' - -function getVideoPlaylistsList (url: string, start: number, count: number, sort?: string) { - const path = '/api/v1/video-playlists' - - const query = { - start, - count, - sort - } - - return makeGetRequest({ - url, - path, - query, - statusCodeExpected: HttpStatusCode.OK_200 - }) -} - -function getVideoChannelPlaylistsList (url: string, videoChannelName: string, start: number, count: number, sort?: string) { - const path = '/api/v1/video-channels/' + videoChannelName + '/video-playlists' - - const query = { - start, - count, - sort - } - - return makeGetRequest({ - url, - path, - query, - statusCodeExpected: HttpStatusCode.OK_200 - }) -} - -function getAccountPlaylistsList (url: string, accountName: string, start: number, count: number, sort?: string, search?: string) { - const path = '/api/v1/accounts/' + accountName + '/video-playlists' - - const query = { - start, - count, - sort, - search - } - - return makeGetRequest({ - url, - path, - query, - statusCodeExpected: HttpStatusCode.OK_200 - }) -} - -function getAccountPlaylistsListWithToken ( - url: string, - token: string, - accountName: string, - start: number, - count: number, - playlistType?: VideoPlaylistType, - sort?: string -) { - const path = '/api/v1/accounts/' + accountName + '/video-playlists' - - const query = { - start, - count, - playlistType, - sort - } - - return makeGetRequest({ - url, - token, - path, - query, - statusCodeExpected: HttpStatusCode.OK_200 - }) -} - -function getVideoPlaylist (url: string, playlistId: number | string, statusCodeExpected = HttpStatusCode.OK_200) { - const path = '/api/v1/video-playlists/' + playlistId - - return makeGetRequest({ - url, - path, - statusCodeExpected - }) -} - -function getVideoPlaylistWithToken (url: string, token: string, playlistId: number | string, statusCodeExpected = HttpStatusCode.OK_200) { - const path = '/api/v1/video-playlists/' + playlistId - - return makeGetRequest({ - url, - token, - path, - statusCodeExpected - }) -} - -function deleteVideoPlaylist (url: string, token: string, playlistId: number | string, statusCodeExpected = HttpStatusCode.NO_CONTENT_204) { - const path = '/api/v1/video-playlists/' + playlistId - - return makeDeleteRequest({ - url, - path, - token, - statusCodeExpected - }) -} - -function createVideoPlaylist (options: { - url: string - token: string - playlistAttrs: VideoPlaylistCreate - expectedStatus?: number -}) { - const path = '/api/v1/video-playlists' - - const fields = omit(options.playlistAttrs, 'thumbnailfile') - - const attaches = options.playlistAttrs.thumbnailfile - ? { thumbnailfile: options.playlistAttrs.thumbnailfile } - : {} - - return makeUploadRequest({ - method: 'POST', - url: options.url, - path, - token: options.token, - fields, - attaches, - statusCodeExpected: options.expectedStatus || HttpStatusCode.OK_200 - }) -} - -function updateVideoPlaylist (options: { - url: string - token: string - playlistAttrs: VideoPlaylistUpdate - playlistId: number | string - expectedStatus?: number -}) { - const path = '/api/v1/video-playlists/' + options.playlistId - - const fields = omit(options.playlistAttrs, 'thumbnailfile') - - const attaches = options.playlistAttrs.thumbnailfile - ? { thumbnailfile: options.playlistAttrs.thumbnailfile } - : {} - - return makeUploadRequest({ - method: 'PUT', - url: options.url, - path, - token: options.token, - fields, - attaches, - statusCodeExpected: options.expectedStatus || HttpStatusCode.NO_CONTENT_204 - }) -} - -async function addVideoInPlaylist (options: { - url: string - token: string - playlistId: number | string - elementAttrs: VideoPlaylistElementCreate | { videoId: string } - expectedStatus?: number -}) { - options.elementAttrs.videoId = await videoUUIDToId(options.url, options.elementAttrs.videoId) - - const path = '/api/v1/video-playlists/' + options.playlistId + '/videos' - - return makePostBodyRequest({ - url: options.url, - path, - token: options.token, - fields: options.elementAttrs, - statusCodeExpected: options.expectedStatus || HttpStatusCode.OK_200 - }) -} - -function updateVideoPlaylistElement (options: { - url: string - token: string - playlistId: number | string - playlistElementId: number | string - elementAttrs: VideoPlaylistElementUpdate - expectedStatus?: number -}) { - const path = '/api/v1/video-playlists/' + options.playlistId + '/videos/' + options.playlistElementId - - return makePutBodyRequest({ - url: options.url, - path, - token: options.token, - fields: options.elementAttrs, - statusCodeExpected: options.expectedStatus || HttpStatusCode.NO_CONTENT_204 - }) -} - -function removeVideoFromPlaylist (options: { - url: string - token: string - playlistId: number | string - playlistElementId: number - expectedStatus?: number -}) { - const path = '/api/v1/video-playlists/' + options.playlistId + '/videos/' + options.playlistElementId - - return makeDeleteRequest({ - url: options.url, - path, - token: options.token, - statusCodeExpected: options.expectedStatus || HttpStatusCode.NO_CONTENT_204 - }) -} - -function reorderVideosPlaylist (options: { - url: string - token: string - playlistId: number | string - elementAttrs: { - startPosition: number - insertAfterPosition: number - reorderLength?: number - } - expectedStatus?: number -}) { - const path = '/api/v1/video-playlists/' + options.playlistId + '/videos/reorder' - - return makePostBodyRequest({ - url: options.url, - path, - token: options.token, - fields: options.elementAttrs, - statusCodeExpected: options.expectedStatus || HttpStatusCode.NO_CONTENT_204 - }) -} - -async function checkPlaylistFilesWereRemoved ( - playlistUUID: string, - internalServerNumber: number, - directories = [ 'thumbnails' ] -) { - const testDirectory = 'test' + internalServerNumber - - for (const directory of directories) { - const directoryPath = join(root(), testDirectory, directory) - - const files = await readdir(directoryPath) - for (const file of files) { - expect(file).to.not.contain(playlistUUID) - } - } -} - -function getVideoPlaylistPrivacies (url: string) { - const path = '/api/v1/video-playlists/privacies' - - return makeGetRequest({ - url, - path, - statusCodeExpected: HttpStatusCode.OK_200 - }) -} - -function doVideosExistInMyPlaylist (url: string, token: string, videoIds: number[]) { - const path = '/api/v1/users/me/video-playlists/videos-exist' - - return makeGetRequest({ - url, - token, - path, - query: { videoIds }, - statusCodeExpected: HttpStatusCode.OK_200 - }) -} - -// --------------------------------------------------------------------------- - -export { - getVideoPlaylistPrivacies, - - getVideoPlaylistsList, - getVideoChannelPlaylistsList, - getAccountPlaylistsList, - getAccountPlaylistsListWithToken, - - getVideoPlaylist, - getVideoPlaylistWithToken, - - createVideoPlaylist, - updateVideoPlaylist, - deleteVideoPlaylist, - - addVideoInPlaylist, - updateVideoPlaylistElement, - removeVideoFromPlaylist, - - reorderVideosPlaylist, - - checkPlaylistFilesWereRemoved, - - doVideosExistInMyPlaylist -} diff --git a/shared/extra-utils/videos/videos.ts b/shared/extra-utils/videos/videos.ts index a45c0402a..920c93072 100644 --- a/shared/extra-utils/videos/videos.ts +++ b/shared/extra-utils/videos/videos.ts @@ -262,28 +262,6 @@ function getVideoChannelVideos ( }) } -function getPlaylistVideos ( - url: string, - accessToken: string, - playlistId: number | string, - start: number, - count: number, - query: { nsfw?: boolean } = {} -) { - const path = '/api/v1/video-playlists/' + playlistId + '/videos' - - return makeGetRequest({ - url, - path, - query: immutableAssign(query, { - start, - count - }), - token: accessToken, - statusCodeExpected: HttpStatusCode.OK_200 - }) -} - function getVideosListPagination (url: string, start: number, count: number, sort?: string, skipCount?: boolean) { const path = '/api/v1/videos' @@ -871,7 +849,6 @@ export { getLocalVideos, completeVideoCheck, checkVideoFilesWereRemoved, - getPlaylistVideos, getMyVideosWithFilter, uploadVideoAndGetId, getLocalIdByUUID, -- cgit v1.2.3 From 313228e9c3b5bcef5391228c9b949d05d32ad7bb Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 8 Jul 2021 16:21:42 +0200 Subject: Introduce history command --- shared/extra-utils/videos/history-command.ts | 59 ++++++++++++++++++++++++++++ shared/extra-utils/videos/index.ts | 2 +- shared/extra-utils/videos/video-history.ts | 49 ----------------------- 3 files changed, 60 insertions(+), 50 deletions(-) create mode 100644 shared/extra-utils/videos/history-command.ts delete mode 100644 shared/extra-utils/videos/video-history.ts (limited to 'shared/extra-utils/videos') diff --git a/shared/extra-utils/videos/history-command.ts b/shared/extra-utils/videos/history-command.ts new file mode 100644 index 000000000..8a144a312 --- /dev/null +++ b/shared/extra-utils/videos/history-command.ts @@ -0,0 +1,59 @@ +import { ResultList, Video } from '@shared/models' +import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' +import { AbstractCommand, OverrideCommandOptions } from '../shared' + +export class HistoryCommand extends AbstractCommand { + + wathVideo (options: OverrideCommandOptions & { + videoId: number | string + currentTime: number + }) { + const { videoId, currentTime } = options + + const path = '/api/v1/videos/' + videoId + '/watching' + const fields = { currentTime } + + return this.putBodyRequest({ + ...options, + + path, + fields, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } + + list (options: OverrideCommandOptions & { + search?: string + } = {}) { + const { search } = options + const path = '/api/v1/users/me/history/videos' + + return this.getRequestBody>({ + ...options, + + path, + query: { + search + }, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + remove (options: OverrideCommandOptions & { + beforeDate?: string + } = {}) { + const { beforeDate } = options + const path = '/api/v1/users/me/history/videos/remove' + + return this.postBodyRequest({ + ...options, + + path, + fields: { beforeDate }, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } +} diff --git a/shared/extra-utils/videos/index.ts b/shared/extra-utils/videos/index.ts index 1f6241d7e..74667fc06 100644 --- a/shared/extra-utils/videos/index.ts +++ b/shared/extra-utils/videos/index.ts @@ -2,6 +2,7 @@ export * from './blacklist-command' export * from './captions' export * from './captions-command' export * from './change-ownership-command' +export * from './history-command' export * from './live-command' export * from './live' export * from './playlists-command' @@ -9,7 +10,6 @@ export * from './playlists' export * from './services-command' export * from './video-channels' export * from './video-comments' -export * from './video-history' export * from './video-imports' export * from './video-streaming-playlists' export * from './videos' diff --git a/shared/extra-utils/videos/video-history.ts b/shared/extra-utils/videos/video-history.ts deleted file mode 100644 index b989e14dc..000000000 --- a/shared/extra-utils/videos/video-history.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { makeGetRequest, makePostBodyRequest, makePutBodyRequest } from '../requests/requests' -import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' - -function userWatchVideo ( - url: string, - token: string, - videoId: number | string, - currentTime: number, - statusCodeExpected = HttpStatusCode.NO_CONTENT_204 -) { - const path = '/api/v1/videos/' + videoId + '/watching' - const fields = { currentTime } - - return makePutBodyRequest({ url, path, token, fields, statusCodeExpected }) -} - -function listMyVideosHistory (url: string, token: string, search?: string) { - const path = '/api/v1/users/me/history/videos' - - return makeGetRequest({ - url, - path, - token, - query: { - search - }, - statusCodeExpected: HttpStatusCode.OK_200 - }) -} - -function removeMyVideosHistory (url: string, token: string, beforeDate?: string) { - const path = '/api/v1/users/me/history/videos/remove' - - return makePostBodyRequest({ - url, - path, - token, - fields: beforeDate ? { beforeDate } : {}, - statusCodeExpected: HttpStatusCode.NO_CONTENT_204 - }) -} - -// --------------------------------------------------------------------------- - -export { - userWatchVideo, - listMyVideosHistory, - removeMyVideosHistory -} -- cgit v1.2.3 From 6910f20f114b5bd020258a3a9a3f2117819a60c2 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 8 Jul 2021 16:49:51 +0200 Subject: Introduce import command --- shared/extra-utils/videos/imports-command.ts | 86 ++++++++++++++++++++++++++ shared/extra-utils/videos/index.ts | 2 +- shared/extra-utils/videos/video-imports.ts | 90 ---------------------------- 3 files changed, 87 insertions(+), 91 deletions(-) create mode 100644 shared/extra-utils/videos/imports-command.ts delete mode 100644 shared/extra-utils/videos/video-imports.ts (limited to 'shared/extra-utils/videos') diff --git a/shared/extra-utils/videos/imports-command.ts b/shared/extra-utils/videos/imports-command.ts new file mode 100644 index 000000000..024aa363f --- /dev/null +++ b/shared/extra-utils/videos/imports-command.ts @@ -0,0 +1,86 @@ + +import { ResultList } from '@shared/models' +import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' +import { VideoImport, VideoImportCreate } from '../../models/videos' +import { unwrapBody } from '../requests' +import { AbstractCommand, OverrideCommandOptions } from '../shared' + +export class ImportsCommand extends AbstractCommand { + + static getYoutubeVideoUrl () { + return 'https://www.youtube.com/watch?v=msX3jv1XdvM' + } + + static getYoutubeHDRVideoUrl () { + /** + * The video is used to check format-selection correctness wrt. HDR, + * which brings its own set of oddities outside of a MediaSource. + * FIXME: refactor once HDR is supported at playback + * + * The video needs to have the following format_ids: + * (which you can check by using `youtube-dl -F`): + * - 303 (1080p webm vp9) + * - 299 (1080p mp4 avc1) + * - 335 (1080p webm vp9.2 HDR) + * + * 15 jan. 2021: TEST VIDEO NOT CURRENTLY PROVIDING + * - 400 (1080p mp4 av01) + * - 315 (2160p webm vp9 HDR) + * - 337 (2160p webm vp9.2 HDR) + * - 401 (2160p mp4 av01 HDR) + */ + return 'https://www.youtube.com/watch?v=qR5vOXbZsI4' + } + + static getMagnetURI () { + // eslint-disable-next-line max-len + return 'magnet:?xs=https%3A%2F%2Fpeertube2.cpy.re%2Fstatic%2Ftorrents%2Fb209ca00-c8bb-4b2b-b421-1ede169f3dbc-720.torrent&xt=urn:btih:0f498834733e8057ed5c6f2ee2b4efd8d84a76ee&dn=super+peertube2+video&tr=wss%3A%2F%2Fpeertube2.cpy.re%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fpeertube2.cpy.re%2Ftracker%2Fannounce&ws=https%3A%2F%2Fpeertube2.cpy.re%2Fstatic%2Fwebseed%2Fb209ca00-c8bb-4b2b-b421-1ede169f3dbc-720.mp4' + } + + static getBadVideoUrl () { + return 'https://download.cpy.re/peertube/bad_video.mp4' + } + + static getGoodVideoUrl () { + return 'https://download.cpy.re/peertube/good_video.mp4' + } + + importVideo (options: OverrideCommandOptions & { + attributes: VideoImportCreate & { torrentfile?: string } + }) { + const { attributes } = options + const path = '/api/v1/videos/imports' + + let attaches: any = {} + if (attributes.torrentfile) attaches = { torrentfile: attributes.torrentfile } + + return unwrapBody(this.postUploadRequest({ + ...options, + + path, + attaches, + fields: options.attributes, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.OK_200 + })) + } + + getMyVideoImports (options: OverrideCommandOptions & { + sort?: string + } = {}) { + const { sort } = options + const path = '/api/v1/users/me/videos/imports' + + const query = {} + if (sort) query['sort'] = sort + + return this.getRequestBody>({ + ...options, + + path, + query: { sort }, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } +} diff --git a/shared/extra-utils/videos/index.ts b/shared/extra-utils/videos/index.ts index 74667fc06..372cf7a90 100644 --- a/shared/extra-utils/videos/index.ts +++ b/shared/extra-utils/videos/index.ts @@ -3,6 +3,7 @@ export * from './captions' export * from './captions-command' export * from './change-ownership-command' export * from './history-command' +export * from './imports-command' export * from './live-command' export * from './live' export * from './playlists-command' @@ -10,6 +11,5 @@ export * from './playlists' export * from './services-command' export * from './video-channels' export * from './video-comments' -export * from './video-imports' export * from './video-streaming-playlists' export * from './videos' diff --git a/shared/extra-utils/videos/video-imports.ts b/shared/extra-utils/videos/video-imports.ts deleted file mode 100644 index 81c0163cb..000000000 --- a/shared/extra-utils/videos/video-imports.ts +++ /dev/null @@ -1,90 +0,0 @@ - -import { VideoImportCreate } from '../../models/videos' -import { makeGetRequest, makeUploadRequest } from '../requests/requests' -import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' - -function getYoutubeVideoUrl () { - return 'https://www.youtube.com/watch?v=msX3jv1XdvM' -} - -function getYoutubeHDRVideoUrl () { - /** - * The video is used to check format-selection correctness wrt. HDR, - * which brings its own set of oddities outside of a MediaSource. - * FIXME: refactor once HDR is supported at playback - * - * The video needs to have the following format_ids: - * (which you can check by using `youtube-dl -F`): - * - 303 (1080p webm vp9) - * - 299 (1080p mp4 avc1) - * - 335 (1080p webm vp9.2 HDR) - * - * 15 jan. 2021: TEST VIDEO NOT CURRENTLY PROVIDING - * - 400 (1080p mp4 av01) - * - 315 (2160p webm vp9 HDR) - * - 337 (2160p webm vp9.2 HDR) - * - 401 (2160p mp4 av01 HDR) - */ - return 'https://www.youtube.com/watch?v=qR5vOXbZsI4' -} - -function getMagnetURI () { - // eslint-disable-next-line max-len - return 'magnet:?xs=https%3A%2F%2Fpeertube2.cpy.re%2Fstatic%2Ftorrents%2Fb209ca00-c8bb-4b2b-b421-1ede169f3dbc-720.torrent&xt=urn:btih:0f498834733e8057ed5c6f2ee2b4efd8d84a76ee&dn=super+peertube2+video&tr=wss%3A%2F%2Fpeertube2.cpy.re%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fpeertube2.cpy.re%2Ftracker%2Fannounce&ws=https%3A%2F%2Fpeertube2.cpy.re%2Fstatic%2Fwebseed%2Fb209ca00-c8bb-4b2b-b421-1ede169f3dbc-720.mp4' -} - -function getBadVideoUrl () { - return 'https://download.cpy.re/peertube/bad_video.mp4' -} - -function getGoodVideoUrl () { - return 'https://download.cpy.re/peertube/good_video.mp4' -} - -function importVideo ( - url: string, - token: string, - attributes: VideoImportCreate & { torrentfile?: string }, - statusCodeExpected = HttpStatusCode.OK_200 -) { - const path = '/api/v1/videos/imports' - - let attaches: any = {} - if (attributes.torrentfile) attaches = { torrentfile: attributes.torrentfile } - - return makeUploadRequest({ - url, - path, - token, - attaches, - fields: attributes, - statusCodeExpected - }) -} - -function getMyVideoImports (url: string, token: string, sort?: string) { - const path = '/api/v1/users/me/videos/imports' - - const query = {} - if (sort) query['sort'] = sort - - return makeGetRequest({ - url, - query, - path, - token, - statusCodeExpected: HttpStatusCode.OK_200 - }) -} - -// --------------------------------------------------------------------------- - -export { - getBadVideoUrl, - getYoutubeVideoUrl, - getYoutubeHDRVideoUrl, - importVideo, - getMagnetURI, - getMyVideoImports, - getGoodVideoUrl -} -- cgit v1.2.3 From 57f879a540551c3b958b0991c8e1e3657a4481d8 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 9 Jul 2021 10:21:10 +0200 Subject: Introduce streaming playlists command --- shared/extra-utils/videos/index.ts | 3 +- .../videos/streaming-playlists-command.ts | 45 ++++++++++++ shared/extra-utils/videos/streaming-playlists.ts | 76 ++++++++++++++++++++ .../videos/video-streaming-playlists.ts | 82 ---------------------- 4 files changed, 123 insertions(+), 83 deletions(-) create mode 100644 shared/extra-utils/videos/streaming-playlists-command.ts create mode 100644 shared/extra-utils/videos/streaming-playlists.ts delete mode 100644 shared/extra-utils/videos/video-streaming-playlists.ts (limited to 'shared/extra-utils/videos') diff --git a/shared/extra-utils/videos/index.ts b/shared/extra-utils/videos/index.ts index 372cf7a90..f87ae8eea 100644 --- a/shared/extra-utils/videos/index.ts +++ b/shared/extra-utils/videos/index.ts @@ -9,7 +9,8 @@ export * from './live' export * from './playlists-command' export * from './playlists' export * from './services-command' +export * from './streaming-playlists-command' +export * from './streaming-playlists' export * from './video-channels' export * from './video-comments' -export * from './video-streaming-playlists' export * from './videos' diff --git a/shared/extra-utils/videos/streaming-playlists-command.ts b/shared/extra-utils/videos/streaming-playlists-command.ts new file mode 100644 index 000000000..4caec7137 --- /dev/null +++ b/shared/extra-utils/videos/streaming-playlists-command.ts @@ -0,0 +1,45 @@ + +import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' +import { unwrapBody, unwrapText } from '../requests' +import { AbstractCommand, OverrideCommandOptions } from '../shared' + +export class StreamingPlaylistsCommand extends AbstractCommand { + + get (options: OverrideCommandOptions & { + url: string + }) { + return unwrapText(this.getRawRequest({ + ...options, + + url: options.url, + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + })) + } + + getSegment (options: OverrideCommandOptions & { + url: string + range?: string + }) { + return unwrapText(this.getRawRequest({ + ...options, + + url: options.url, + range: options.range, + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200, + })) + } + + getSegmentSha256 (options: OverrideCommandOptions & { + url: string + }) { + return unwrapBody<{ [ id: string ]: string }>(this.getRawRequest({ + ...options, + + url: options.url, + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + })) + } +} diff --git a/shared/extra-utils/videos/streaming-playlists.ts b/shared/extra-utils/videos/streaming-playlists.ts new file mode 100644 index 000000000..0324c739a --- /dev/null +++ b/shared/extra-utils/videos/streaming-playlists.ts @@ -0,0 +1,76 @@ +import { expect } from 'chai' +import { sha256 } from '@server/helpers/core-utils' +import { HttpStatusCode } from '@shared/core-utils' +import { VideoStreamingPlaylist } from '@shared/models' +import { ServerInfo } from '../server' + +async function checkSegmentHash (options: { + server: ServerInfo + baseUrlPlaylist: string + baseUrlSegment: string + videoUUID: string + resolution: number + hlsPlaylist: VideoStreamingPlaylist +}) { + const { server, baseUrlPlaylist, baseUrlSegment, videoUUID, resolution, hlsPlaylist } = options + const command = server.streamingPlaylistsCommand + + const playlist = await command.get({ url: `${baseUrlPlaylist}/${videoUUID}/${resolution}.m3u8` }) + + const videoName = `${videoUUID}-${resolution}-fragmented.mp4` + + const matches = /#EXT-X-BYTERANGE:(\d+)@(\d+)/.exec(playlist) + + const length = parseInt(matches[1], 10) + const offset = parseInt(matches[2], 10) + const range = `${offset}-${offset + length - 1}` + + const segmentBody = await command.getSegment({ + url: `${baseUrlSegment}/${videoUUID}/${videoName}`, + expectedStatus: HttpStatusCode.PARTIAL_CONTENT_206, + range: `bytes=${range}` + }) + + const shaBody = await command.getSegmentSha256({ url: hlsPlaylist.segmentsSha256Url }) + expect(sha256(segmentBody)).to.equal(shaBody[videoName][range]) +} + +async function checkLiveSegmentHash (options: { + server: ServerInfo + baseUrlSegment: string + videoUUID: string + segmentName: string + hlsPlaylist: VideoStreamingPlaylist +}) { + const { server, baseUrlSegment, videoUUID, segmentName, hlsPlaylist } = options + const command = server.streamingPlaylistsCommand + + const segmentBody = await command.getSegment({ url: `${baseUrlSegment}/${videoUUID}/${segmentName}` }) + const shaBody = await command.getSegmentSha256({ url: hlsPlaylist.segmentsSha256Url }) + + expect(sha256(segmentBody)).to.equal(shaBody[segmentName]) +} + +async function checkResolutionsInMasterPlaylist (options: { + server: ServerInfo + playlistUrl: string + resolutions: number[] +}) { + const { server, playlistUrl, resolutions } = options + + const masterPlaylist = await server.streamingPlaylistsCommand.get({ url: playlistUrl }) + + for (const resolution of resolutions) { + const reg = new RegExp( + '#EXT-X-STREAM-INF:BANDWIDTH=\\d+,RESOLUTION=\\d+x' + resolution + ',(FRAME-RATE=\\d+,)?CODECS="avc1.64001f,mp4a.40.2"' + ) + + expect(masterPlaylist).to.match(reg) + } +} + +export { + checkSegmentHash, + checkLiveSegmentHash, + checkResolutionsInMasterPlaylist +} diff --git a/shared/extra-utils/videos/video-streaming-playlists.ts b/shared/extra-utils/videos/video-streaming-playlists.ts deleted file mode 100644 index 99c2e1880..000000000 --- a/shared/extra-utils/videos/video-streaming-playlists.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { makeRawRequest } from '../requests/requests' -import { sha256 } from '../../../server/helpers/core-utils' -import { VideoStreamingPlaylist } from '../../models/videos/video-streaming-playlist.model' -import { expect } from 'chai' -import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' - -function getPlaylist (url: string, statusCodeExpected = HttpStatusCode.OK_200) { - return makeRawRequest(url, statusCodeExpected) -} - -function getSegment (url: string, statusCodeExpected = HttpStatusCode.OK_200, range?: string) { - return makeRawRequest(url, statusCodeExpected, range) -} - -function getSegmentSha256 (url: string, statusCodeExpected = HttpStatusCode.OK_200) { - return makeRawRequest(url, statusCodeExpected) -} - -async function checkSegmentHash ( - baseUrlPlaylist: string, - baseUrlSegment: string, - videoUUID: string, - resolution: number, - hlsPlaylist: VideoStreamingPlaylist -) { - const res = await getPlaylist(`${baseUrlPlaylist}/${videoUUID}/${resolution}.m3u8`) - const playlist = res.text - - const videoName = `${videoUUID}-${resolution}-fragmented.mp4` - - const matches = /#EXT-X-BYTERANGE:(\d+)@(\d+)/.exec(playlist) - - const length = parseInt(matches[1], 10) - const offset = parseInt(matches[2], 10) - const range = `${offset}-${offset + length - 1}` - - const res2 = await getSegment(`${baseUrlSegment}/${videoUUID}/${videoName}`, HttpStatusCode.PARTIAL_CONTENT_206, `bytes=${range}`) - - const resSha = await getSegmentSha256(hlsPlaylist.segmentsSha256Url) - - const sha256Server = resSha.body[videoName][range] - expect(sha256(res2.body)).to.equal(sha256Server) -} - -async function checkLiveSegmentHash ( - baseUrlSegment: string, - videoUUID: string, - segmentName: string, - hlsPlaylist: VideoStreamingPlaylist -) { - const res2 = await getSegment(`${baseUrlSegment}/${videoUUID}/${segmentName}`) - - const resSha = await getSegmentSha256(hlsPlaylist.segmentsSha256Url) - - const sha256Server = resSha.body[segmentName] - expect(sha256(res2.body)).to.equal(sha256Server) -} - -async function checkResolutionsInMasterPlaylist (playlistUrl: string, resolutions: number[]) { - const res = await getPlaylist(playlistUrl) - - const masterPlaylist = res.text - - for (const resolution of resolutions) { - const reg = new RegExp( - '#EXT-X-STREAM-INF:BANDWIDTH=\\d+,RESOLUTION=\\d+x' + resolution + ',(FRAME-RATE=\\d+,)?CODECS="avc1.64001f,mp4a.40.2"' - ) - - expect(masterPlaylist).to.match(reg) - } -} - -// --------------------------------------------------------------------------- - -export { - getPlaylist, - getSegment, - checkResolutionsInMasterPlaylist, - getSegmentSha256, - checkLiveSegmentHash, - checkSegmentHash -} -- cgit v1.2.3 From a54618880c394ad7571f3f3222dc96ec2dd10d9a Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 9 Jul 2021 11:21:30 +0200 Subject: Introduce channels command --- shared/extra-utils/videos/channels-command.ts | 157 +++++++++++++++++++++ shared/extra-utils/videos/channels.ts | 20 +++ shared/extra-utils/videos/index.ts | 5 +- shared/extra-utils/videos/video-channels.ts | 192 -------------------------- 4 files changed, 180 insertions(+), 194 deletions(-) create mode 100644 shared/extra-utils/videos/channels-command.ts create mode 100644 shared/extra-utils/videos/channels.ts delete mode 100644 shared/extra-utils/videos/video-channels.ts (limited to 'shared/extra-utils/videos') diff --git a/shared/extra-utils/videos/channels-command.ts b/shared/extra-utils/videos/channels-command.ts new file mode 100644 index 000000000..a98c5cc93 --- /dev/null +++ b/shared/extra-utils/videos/channels-command.ts @@ -0,0 +1,157 @@ +import { pick } from 'lodash' +import { ResultList, VideoChannel, VideoChannelCreateResult } from '@shared/models' +import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' +import { VideoChannelCreate } from '../../models/videos/channel/video-channel-create.model' +import { VideoChannelUpdate } from '../../models/videos/channel/video-channel-update.model' +import { unwrapBody } from '../requests' +import { AbstractCommand, OverrideCommandOptions } from '../shared' + +export class ChannelsCommand extends AbstractCommand { + + list (options: OverrideCommandOptions & { + start?: number + count?: number + sort?: string + withStats?: boolean + } = {}) { + const path = '/api/v1/video-channels' + + return this.getRequestBody>({ + ...options, + + path, + query: pick(options, [ 'start', 'count', 'sort', 'withStats' ]), + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + listByAccount (options: OverrideCommandOptions & { + accountName: string + start?: number + count?: number + sort?: string + withStats?: boolean + search?: string + }) { + const { accountName, sort = 'createdAt' } = options + const path = '/api/v1/accounts/' + accountName + '/video-channels' + + return this.getRequestBody>({ + ...options, + + path, + query: { sort, ...pick(options, [ 'start', 'count', 'withStats', 'search' ]) }, + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + async create (options: OverrideCommandOptions & { + attributes: VideoChannelCreate + }) { + const path = '/api/v1/video-channels/' + + // Default attributes + const defaultAttributes = { + displayName: 'my super video channel', + description: 'my super channel description', + support: 'my super channel support' + } + const attributes = { ...defaultAttributes, ...options.attributes } + + const body = await unwrapBody<{ videoChannel: VideoChannelCreateResult }>(this.postBodyRequest({ + ...options, + + path, + fields: attributes, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.OK_200 + })) + + return body.videoChannel + } + + update (options: OverrideCommandOptions & { + channelName: string + attributes: VideoChannelUpdate + }) { + const { channelName, attributes } = options + const path = '/api/v1/video-channels/' + channelName + + return this.putBodyRequest({ + ...options, + + path, + fields: attributes, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } + + delete (options: OverrideCommandOptions & { + channelName: string + }) { + const path = '/api/v1/video-channels/' + options.channelName + + return this.deleteRequest({ + ...options, + + path, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } + + get (options: OverrideCommandOptions & { + channelName: string + }) { + const path = '/api/v1/video-channels/' + options.channelName + + return this.getRequestBody({ + ...options, + + path, + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + updateImage (options: OverrideCommandOptions & { + fixture: string + channelName: string | number + type: 'avatar' | 'banner' + }) { + const { channelName, fixture, type } = options + + const path = `/api/v1/video-channels/${channelName}/${type}/pick` + + return this.updateImageRequest({ + ...options, + + path, + fixture, + fieldname: type + 'file', + + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + deleteImage (options: OverrideCommandOptions & { + channelName: string | number + type: 'avatar' | 'banner' + }) { + const { channelName, type } = options + + const path = `/api/v1/video-channels/${channelName}/${type}` + + return this.deleteRequest({ + ...options, + + path, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } +} diff --git a/shared/extra-utils/videos/channels.ts b/shared/extra-utils/videos/channels.ts new file mode 100644 index 000000000..a77543c92 --- /dev/null +++ b/shared/extra-utils/videos/channels.ts @@ -0,0 +1,20 @@ +import { User } from '../../models/users/user.model' +import { ServerInfo } from '../server/servers' +import { getMyUserInformation } from '../users/users' + +function setDefaultVideoChannel (servers: ServerInfo[]) { + const tasks: Promise[] = [] + + for (const server of servers) { + const p = getMyUserInformation(server.url, server.accessToken) + .then(res => { server.videoChannel = (res.body as User).videoChannels[0] }) + + tasks.push(p) + } + + return Promise.all(tasks) +} + +export { + setDefaultVideoChannel +} diff --git a/shared/extra-utils/videos/index.ts b/shared/extra-utils/videos/index.ts index f87ae8eea..3bc219281 100644 --- a/shared/extra-utils/videos/index.ts +++ b/shared/extra-utils/videos/index.ts @@ -1,7 +1,9 @@ export * from './blacklist-command' -export * from './captions' export * from './captions-command' +export * from './captions' export * from './change-ownership-command' +export * from './channels' +export * from './channels-command' export * from './history-command' export * from './imports-command' export * from './live-command' @@ -11,6 +13,5 @@ export * from './playlists' export * from './services-command' export * from './streaming-playlists-command' export * from './streaming-playlists' -export * from './video-channels' export * from './video-comments' export * from './videos' diff --git a/shared/extra-utils/videos/video-channels.ts b/shared/extra-utils/videos/video-channels.ts deleted file mode 100644 index 0aab93e52..000000000 --- a/shared/extra-utils/videos/video-channels.ts +++ /dev/null @@ -1,192 +0,0 @@ -/* eslint-disable @typescript-eslint/no-floating-promises */ - -import * as request from 'supertest' -import { VideoChannelUpdate } from '../../models/videos/channel/video-channel-update.model' -import { VideoChannelCreate } from '../../models/videos/channel/video-channel-create.model' -import { makeDeleteRequest, makeGetRequest, updateImageRequest } from '../requests/requests' -import { ServerInfo } from '../server/servers' -import { MyUser, User } from '../../models/users/user.model' -import { getMyUserInformation } from '../users/users' -import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' - -function getVideoChannelsList (url: string, start: number, count: number, sort?: string, withStats?: boolean) { - const path = '/api/v1/video-channels' - - const req = request(url) - .get(path) - .query({ start: start }) - .query({ count: count }) - - if (sort) req.query({ sort }) - if (withStats) req.query({ withStats }) - - return req.set('Accept', 'application/json') - .expect(HttpStatusCode.OK_200) - .expect('Content-Type', /json/) -} - -function getAccountVideoChannelsList (parameters: { - url: string - accountName: string - start?: number - count?: number - sort?: string - specialStatus?: HttpStatusCode - withStats?: boolean - search?: string -}) { - const { - url, - accountName, - start, - count, - sort = 'createdAt', - specialStatus = HttpStatusCode.OK_200, - withStats = false, - search - } = parameters - - const path = '/api/v1/accounts/' + accountName + '/video-channels' - - return makeGetRequest({ - url, - path, - query: { - start, - count, - sort, - withStats, - search - }, - statusCodeExpected: specialStatus - }) -} - -function addVideoChannel ( - url: string, - token: string, - videoChannelAttributesArg: VideoChannelCreate, - expectedStatus = HttpStatusCode.OK_200 -) { - const path = '/api/v1/video-channels/' - - // Default attributes - let attributes = { - displayName: 'my super video channel', - description: 'my super channel description', - support: 'my super channel support' - } - attributes = Object.assign(attributes, videoChannelAttributesArg) - - return request(url) - .post(path) - .send(attributes) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(expectedStatus) -} - -function updateVideoChannel ( - url: string, - token: string, - channelName: string, - attributes: VideoChannelUpdate, - expectedStatus = HttpStatusCode.NO_CONTENT_204 -) { - const body: any = {} - const path = '/api/v1/video-channels/' + channelName - - if (attributes.displayName) body.displayName = attributes.displayName - if (attributes.description) body.description = attributes.description - if (attributes.support) body.support = attributes.support - if (attributes.bulkVideosSupportUpdate) body.bulkVideosSupportUpdate = attributes.bulkVideosSupportUpdate - - return request(url) - .put(path) - .send(body) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(expectedStatus) -} - -function deleteVideoChannel (url: string, token: string, channelName: string, expectedStatus = HttpStatusCode.NO_CONTENT_204) { - const path = '/api/v1/video-channels/' + channelName - - return request(url) - .delete(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(expectedStatus) -} - -function getVideoChannel (url: string, channelName: string) { - const path = '/api/v1/video-channels/' + channelName - - return request(url) - .get(path) - .set('Accept', 'application/json') - .expect(HttpStatusCode.OK_200) - .expect('Content-Type', /json/) -} - -function updateVideoChannelImage (options: { - url: string - accessToken: string - fixture: string - videoChannelName: string | number - type: 'avatar' | 'banner' -}) { - const path = `/api/v1/video-channels/${options.videoChannelName}/${options.type}/pick` - - return updateImageRequest({ ...options, path, fieldname: options.type + 'file' }) -} - -function deleteVideoChannelImage (options: { - url: string - accessToken: string - videoChannelName: string | number - type: 'avatar' | 'banner' -}) { - const path = `/api/v1/video-channels/${options.videoChannelName}/${options.type}` - - return makeDeleteRequest({ - url: options.url, - token: options.accessToken, - path, - statusCodeExpected: 204 - }) -} - -function setDefaultVideoChannel (servers: ServerInfo[]) { - const tasks: Promise[] = [] - - for (const server of servers) { - const p = getMyUserInformation(server.url, server.accessToken) - .then(res => { server.videoChannel = (res.body as User).videoChannels[0] }) - - tasks.push(p) - } - - return Promise.all(tasks) -} - -async function getDefaultVideoChannel (url: string, token: string) { - const res = await getMyUserInformation(url, token) - - return (res.body as MyUser).videoChannels[0].id -} - -// --------------------------------------------------------------------------- - -export { - updateVideoChannelImage, - getVideoChannelsList, - getAccountVideoChannelsList, - addVideoChannel, - updateVideoChannel, - deleteVideoChannel, - getVideoChannel, - setDefaultVideoChannel, - deleteVideoChannelImage, - getDefaultVideoChannel -} -- cgit v1.2.3 From 12edc1495a36b2199f1bf1ba37f50c7b694be382 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 9 Jul 2021 14:15:11 +0200 Subject: Introduce comments command --- shared/extra-utils/videos/comments-command.ts | 132 ++++++++++++++++++++ shared/extra-utils/videos/index.ts | 3 +- .../videos/streaming-playlists-command.ts | 2 +- shared/extra-utils/videos/video-comments.ts | 138 --------------------- 4 files changed, 135 insertions(+), 140 deletions(-) create mode 100644 shared/extra-utils/videos/comments-command.ts delete mode 100644 shared/extra-utils/videos/video-comments.ts (limited to 'shared/extra-utils/videos') diff --git a/shared/extra-utils/videos/comments-command.ts b/shared/extra-utils/videos/comments-command.ts new file mode 100644 index 000000000..b31f3e2dd --- /dev/null +++ b/shared/extra-utils/videos/comments-command.ts @@ -0,0 +1,132 @@ +import { pick } from 'lodash' +import { ResultList, VideoComment, VideoCommentThreads, VideoCommentThreadTree } from '@shared/models' +import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' +import { unwrapBody } from '../requests' +import { AbstractCommand, OverrideCommandOptions } from '../shared' + +export class CommentsCommand extends AbstractCommand { + + listForAdmin (options: OverrideCommandOptions & { + start?: number + count?: number + sort?: string + isLocal?: boolean + search?: string + searchAccount?: string + searchVideo?: string + } = {}) { + const { sort = '-createdAt' } = options + const path = '/api/v1/videos/comments' + + const query = { sort, ...pick(options, [ 'start', 'count', 'isLocal', 'search', 'searchAccount', 'searchVideo' ]) } + + return this.getRequestBody>({ + ...options, + + path, + query, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + listThreads (options: OverrideCommandOptions & { + videoId: number | string + start?: number + count?: number + sort?: string + }) { + const { start, count, sort, videoId } = options + const path = '/api/v1/videos/' + videoId + '/comment-threads' + + return this.getRequestBody({ + ...options, + + path, + query: { start, count, sort }, + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + getThread (options: OverrideCommandOptions & { + videoId: number | string + threadId: number + }) { + const { videoId, threadId } = options + const path = '/api/v1/videos/' + videoId + '/comment-threads/' + threadId + + return this.getRequestBody({ + ...options, + + path, + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + async createThread (options: OverrideCommandOptions & { + videoId: number | string + text: string + }) { + const { videoId, text } = options + const path = '/api/v1/videos/' + videoId + '/comment-threads' + + const body = await unwrapBody<{ comment: VideoComment }>(this.postBodyRequest({ + ...options, + + path, + fields: { text }, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.OK_200 + })) + + return body.comment + } + + async addReply (options: OverrideCommandOptions & { + videoId: number | string + toCommentId: number + text: string + }) { + const { videoId, toCommentId, text } = options + const path = '/api/v1/videos/' + videoId + '/comments/' + toCommentId + + const body = await unwrapBody<{ comment: VideoComment }>(this.postBodyRequest({ + ...options, + + path, + fields: { text }, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.OK_200 + })) + + return body.comment + } + + async findCommentId (options: OverrideCommandOptions & { + videoId: number | string + text: string + }) { + const { videoId, text } = options + const { data } = await this.listThreads({ videoId, count: 25, sort: '-createdAt' }) + + return data.find(c => c.text === text).id + } + + delete (options: OverrideCommandOptions & { + videoId: number | string + commentId: number + }) { + const { videoId, commentId } = options + const path = '/api/v1/videos/' + videoId + '/comments/' + commentId + + return this.deleteRequest({ + ...options, + + path, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } +} diff --git a/shared/extra-utils/videos/index.ts b/shared/extra-utils/videos/index.ts index 3bc219281..652d82842 100644 --- a/shared/extra-utils/videos/index.ts +++ b/shared/extra-utils/videos/index.ts @@ -4,6 +4,7 @@ export * from './captions' export * from './change-ownership-command' export * from './channels' export * from './channels-command' +export * from './comments-command' export * from './history-command' export * from './imports-command' export * from './live-command' @@ -13,5 +14,5 @@ export * from './playlists' export * from './services-command' export * from './streaming-playlists-command' export * from './streaming-playlists' -export * from './video-comments' +export * from './comments-command' export * from './videos' diff --git a/shared/extra-utils/videos/streaming-playlists-command.ts b/shared/extra-utils/videos/streaming-playlists-command.ts index 4caec7137..b109597c9 100644 --- a/shared/extra-utils/videos/streaming-playlists-command.ts +++ b/shared/extra-utils/videos/streaming-playlists-command.ts @@ -27,7 +27,7 @@ export class StreamingPlaylistsCommand extends AbstractCommand { url: options.url, range: options.range, implicitToken: false, - defaultExpectedStatus: HttpStatusCode.OK_200, + defaultExpectedStatus: HttpStatusCode.OK_200 })) } diff --git a/shared/extra-utils/videos/video-comments.ts b/shared/extra-utils/videos/video-comments.ts deleted file mode 100644 index 71b9f875a..000000000 --- a/shared/extra-utils/videos/video-comments.ts +++ /dev/null @@ -1,138 +0,0 @@ -/* eslint-disable @typescript-eslint/no-floating-promises */ - -import * as request from 'supertest' -import { makeDeleteRequest, makeGetRequest } from '../requests/requests' -import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' - -function getAdminVideoComments (options: { - url: string - token: string - start: number - count: number - sort?: string - isLocal?: boolean - search?: string - searchAccount?: string - searchVideo?: string -}) { - const { url, token, start, count, sort, isLocal, search, searchAccount, searchVideo } = options - const path = '/api/v1/videos/comments' - - const query = { - start, - count, - sort: sort || '-createdAt' - } - - if (isLocal !== undefined) Object.assign(query, { isLocal }) - if (search !== undefined) Object.assign(query, { search }) - if (searchAccount !== undefined) Object.assign(query, { searchAccount }) - if (searchVideo !== undefined) Object.assign(query, { searchVideo }) - - return makeGetRequest({ - url, - path, - token, - query, - statusCodeExpected: HttpStatusCode.OK_200 - }) -} - -function getVideoCommentThreads (url: string, videoId: number | string, start: number, count: number, sort?: string, token?: string) { - const path = '/api/v1/videos/' + videoId + '/comment-threads' - - const req = request(url) - .get(path) - .query({ start: start }) - .query({ count: count }) - - if (sort) req.query({ sort }) - if (token) req.set('Authorization', 'Bearer ' + token) - - return req.set('Accept', 'application/json') - .expect(HttpStatusCode.OK_200) - .expect('Content-Type', /json/) -} - -function getVideoThreadComments (url: string, videoId: number | string, threadId: number, token?: string) { - const path = '/api/v1/videos/' + videoId + '/comment-threads/' + threadId - - const req = request(url) - .get(path) - .set('Accept', 'application/json') - - if (token) req.set('Authorization', 'Bearer ' + token) - - return req.expect(HttpStatusCode.OK_200) - .expect('Content-Type', /json/) -} - -function addVideoCommentThread ( - url: string, - token: string, - videoId: number | string, - text: string, - expectedStatus = HttpStatusCode.OK_200 -) { - const path = '/api/v1/videos/' + videoId + '/comment-threads' - - return request(url) - .post(path) - .send({ text }) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(expectedStatus) -} - -function addVideoCommentReply ( - url: string, - token: string, - videoId: number | string, - inReplyToCommentId: number, - text: string, - expectedStatus = HttpStatusCode.OK_200 -) { - const path = '/api/v1/videos/' + videoId + '/comments/' + inReplyToCommentId - - return request(url) - .post(path) - .send({ text }) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(expectedStatus) -} - -async function findCommentId (url: string, videoId: number | string, text: string) { - const res = await getVideoCommentThreads(url, videoId, 0, 25, '-createdAt') - - return res.body.data.find(c => c.text === text).id as number -} - -function deleteVideoComment ( - url: string, - token: string, - videoId: number | string, - commentId: number, - statusCodeExpected = HttpStatusCode.NO_CONTENT_204 -) { - const path = '/api/v1/videos/' + videoId + '/comments/' + commentId - - return makeDeleteRequest({ - url, - path, - token, - statusCodeExpected - }) -} - -// --------------------------------------------------------------------------- - -export { - getVideoCommentThreads, - getAdminVideoComments, - getVideoThreadComments, - addVideoCommentThread, - addVideoCommentReply, - findCommentId, - deleteVideoComment -} -- cgit v1.2.3 From dd0ebb715123dfa126a82d4e4fe3a04064ae77b8 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 9 Jul 2021 16:23:01 +0200 Subject: Introduce notifications command --- shared/extra-utils/videos/streaming-playlists-command.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared/extra-utils/videos') diff --git a/shared/extra-utils/videos/streaming-playlists-command.ts b/shared/extra-utils/videos/streaming-playlists-command.ts index b109597c9..fab3eb556 100644 --- a/shared/extra-utils/videos/streaming-playlists-command.ts +++ b/shared/extra-utils/videos/streaming-playlists-command.ts @@ -21,7 +21,7 @@ export class StreamingPlaylistsCommand extends AbstractCommand { url: string range?: string }) { - return unwrapText(this.getRawRequest({ + return unwrapBody(this.getRawRequest({ ...options, url: options.url, -- cgit v1.2.3 From 6c5065a011b099618681a37bd77eaa7bd3db752e Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 13 Jul 2021 09:43:59 +0200 Subject: Introduce server commands --- shared/extra-utils/videos/captions-command.ts | 4 ++-- shared/extra-utils/videos/live-command.ts | 7 +++---- shared/extra-utils/videos/live.ts | 4 ++-- shared/extra-utils/videos/playlists.ts | 2 +- shared/extra-utils/videos/videos.ts | 30 +++++++-------------------- 5 files changed, 15 insertions(+), 32 deletions(-) (limited to 'shared/extra-utils/videos') diff --git a/shared/extra-utils/videos/captions-command.ts b/shared/extra-utils/videos/captions-command.ts index 908b6dae6..ac3bde7a9 100644 --- a/shared/extra-utils/videos/captions-command.ts +++ b/shared/extra-utils/videos/captions-command.ts @@ -1,6 +1,6 @@ +import { HttpStatusCode } from '@shared/core-utils' import { ResultList, VideoCaption } from '@shared/models' -import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' -import { buildAbsoluteFixturePath } from '../miscs/miscs' +import { buildAbsoluteFixturePath } from '../miscs' import { AbstractCommand, OverrideCommandOptions } from '../shared' export class CaptionsCommand extends AbstractCommand { diff --git a/shared/extra-utils/videos/live-command.ts b/shared/extra-utils/videos/live-command.ts index 4f03c9127..a494e60fa 100644 --- a/shared/extra-utils/videos/live-command.ts +++ b/shared/extra-utils/videos/live-command.ts @@ -5,9 +5,8 @@ import { omit } from 'lodash' import { join } from 'path' import { LiveVideo, LiveVideoCreate, LiveVideoUpdate, VideoCreateResult, VideoDetails, VideoState } from '@shared/models' import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' -import { buildServerDirectory, wait } from '../miscs/miscs' +import { wait } from '../miscs' import { unwrapBody } from '../requests' -import { waitUntilLog } from '../server/servers' import { AbstractCommand, OverrideCommandOptions } from '../shared' import { sendRTMPStream, testFfmpegStreamError } from './live' import { getVideoWithToken } from './videos' @@ -116,7 +115,7 @@ export class LiveCommand extends AbstractCommand { const { resolution, segment, videoUUID } = options const segmentName = `${resolution}-00000${segment}.ts` - return waitUntilLog(this.server, `${videoUUID}/${segmentName}`, 2, false) + return this.server.serversCommand.waitUntilLog(`${videoUUID}/${segmentName}`, 2, false) } async waitUntilSaved (options: OverrideCommandOptions & { @@ -135,7 +134,7 @@ export class LiveCommand extends AbstractCommand { async countPlaylists (options: OverrideCommandOptions & { videoUUID: string }) { - const basePath = buildServerDirectory(this.server, 'streaming-playlists') + const basePath = this.server.serversCommand.buildDirectory('streaming-playlists') const hlsPath = join(basePath, 'hls', options.videoUUID) const files = await readdir(hlsPath) diff --git a/shared/extra-utils/videos/live.ts b/shared/extra-utils/videos/live.ts index 92cb9104c..0efcc2883 100644 --- a/shared/extra-utils/videos/live.ts +++ b/shared/extra-utils/videos/live.ts @@ -4,7 +4,7 @@ import { expect } from 'chai' import * as ffmpeg from 'fluent-ffmpeg' import { pathExists, readdir } from 'fs-extra' import { join } from 'path' -import { buildAbsoluteFixturePath, buildServerDirectory, wait } from '../miscs/miscs' +import { buildAbsoluteFixturePath, wait } from '../miscs' import { ServerInfo } from '../server/servers' function sendRTMPStream (rtmpBaseUrl: string, streamKey: string, fixtureName = 'video_short.mp4') { @@ -77,7 +77,7 @@ async function waitUntilLivePublishedOnAllServers (servers: ServerInfo[], videoI } async function checkLiveCleanup (server: ServerInfo, videoUUID: string, resolutions: number[] = []) { - const basePath = buildServerDirectory(server, 'streaming-playlists') + const basePath = server.serversCommand.buildDirectory('streaming-playlists') const hlsPath = join(basePath, 'hls', videoUUID) if (resolutions.length === 0) { diff --git a/shared/extra-utils/videos/playlists.ts b/shared/extra-utils/videos/playlists.ts index 023333c87..3dde52bb9 100644 --- a/shared/extra-utils/videos/playlists.ts +++ b/shared/extra-utils/videos/playlists.ts @@ -1,7 +1,7 @@ import { expect } from 'chai' import { readdir } from 'fs-extra' import { join } from 'path' -import { root } from '../' +import { root } from '../miscs' async function checkPlaylistFilesWereRemoved ( playlistUUID: string, diff --git a/shared/extra-utils/videos/videos.ts b/shared/extra-utils/videos/videos.ts index 920c93072..5dd71ce8b 100644 --- a/shared/extra-utils/videos/videos.ts +++ b/shared/extra-utils/videos/videos.ts @@ -13,15 +13,7 @@ import { HttpStatusCode } from '@shared/core-utils' import { BooleanBothQuery, VideosCommonQuery } from '@shared/models' import { loadLanguages, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../server/initializers/constants' import { VideoDetails, VideoPrivacy } from '../../models/videos' -import { - buildAbsoluteFixturePath, - buildServerDirectory, - dateIsValid, - immutableAssign, - testImage, - wait, - webtorrentAdd -} from '../miscs/miscs' +import { buildAbsoluteFixturePath, dateIsValid, testImage, wait, webtorrentAdd } from '../miscs' import { makeGetRequest, makePutBodyRequest, makeRawRequest, makeUploadRequest } from '../requests/requests' import { waitJobs } from '../server/jobs' import { ServerInfo } from '../server/servers' @@ -165,7 +157,7 @@ function getVideosListWithToken (url: string, token: string, query: { nsfw?: Boo return request(url) .get(path) .set('Authorization', 'Bearer ' + token) - .query(immutableAssign(query, { sort: 'name' })) + .query({ sort: 'name', ...query }) .set('Accept', 'application/json') .expect(HttpStatusCode.OK_200) .expect('Content-Type', /json/) @@ -228,11 +220,7 @@ function getAccountVideos ( return makeGetRequest({ url, path, - query: immutableAssign(query, { - start, - count, - sort - }), + query: { ...query, start, count, sort }, token: accessToken, statusCodeExpected: HttpStatusCode.OK_200 }) @@ -252,11 +240,7 @@ function getVideoChannelVideos ( return makeGetRequest({ url, path, - query: immutableAssign(query, { - start, - count, - sort - }), + query: { ...query, start, count, sort }, token: accessToken, statusCodeExpected: HttpStatusCode.OK_200 }) @@ -320,7 +304,7 @@ async function removeAllVideos (server: ServerInfo) { async function checkVideoFilesWereRemoved ( videoUUID: string, - serverNumber: number, + server: ServerInfo, directories = [ 'redundancy', 'videos', @@ -333,7 +317,7 @@ async function checkVideoFilesWereRemoved ( ] ) { for (const directory of directories) { - const directoryPath = buildServerDirectory({ internalServerNumber: serverNumber }, directory) + const directoryPath = server.serversCommand.buildDirectory(directory) const directoryExists = await pathExists(directoryPath) if (directoryExists === false) continue @@ -607,7 +591,7 @@ function rateVideo (url: string, accessToken: string, id: number | string, ratin function parseTorrentVideo (server: ServerInfo, videoUUID: string, resolution: number) { return new Promise((res, rej) => { const torrentName = videoUUID + '-' + resolution + '.torrent' - const torrentPath = buildServerDirectory(server, join('torrents', torrentName)) + const torrentPath = server.serversCommand.buildDirectory(join('torrents', torrentName)) readFile(torrentPath, (err, data) => { if (err) return rej(err) -- cgit v1.2.3 From 7926c5f9b3ffcabb1ffb0dcfa5e48b8e0b88fbc0 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 13 Jul 2021 14:23:01 +0200 Subject: Introduce user command --- shared/extra-utils/videos/channels.ts | 6 ++---- shared/extra-utils/videos/videos.ts | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'shared/extra-utils/videos') diff --git a/shared/extra-utils/videos/channels.ts b/shared/extra-utils/videos/channels.ts index a77543c92..9e7ec565d 100644 --- a/shared/extra-utils/videos/channels.ts +++ b/shared/extra-utils/videos/channels.ts @@ -1,13 +1,11 @@ -import { User } from '../../models/users/user.model' import { ServerInfo } from '../server/servers' -import { getMyUserInformation } from '../users/users' function setDefaultVideoChannel (servers: ServerInfo[]) { const tasks: Promise[] = [] for (const server of servers) { - const p = getMyUserInformation(server.url, server.accessToken) - .then(res => { server.videoChannel = (res.body as User).videoChannels[0] }) + const p = server.usersCommand.getMyInfo() + .then(user => { server.videoChannel = user.videoChannels[0] }) tasks.push(p) } diff --git a/shared/extra-utils/videos/videos.ts b/shared/extra-utils/videos/videos.ts index 5dd71ce8b..5e20f8010 100644 --- a/shared/extra-utils/videos/videos.ts +++ b/shared/extra-utils/videos/videos.ts @@ -17,7 +17,7 @@ import { buildAbsoluteFixturePath, dateIsValid, testImage, wait, webtorrentAdd } import { makeGetRequest, makePutBodyRequest, makeRawRequest, makeUploadRequest } from '../requests/requests' import { waitJobs } from '../server/jobs' import { ServerInfo } from '../server/servers' -import { getMyUserInformation } from '../users/users' +import { xxxgetMyUserInformation } from '../users' loadLanguages() @@ -339,7 +339,7 @@ async function uploadVideo ( let defaultChannelId = '1' try { - const res = await getMyUserInformation(url, accessToken) + const res = await xxxgetMyUserInformation(url, accessToken) defaultChannelId = res.body.videoChannels[0].id } catch (e) { /* empty */ } -- cgit v1.2.3 From d23dd9fbfc4d26026352c10f81d2795ceaf2908a Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 15 Jul 2021 10:02:54 +0200 Subject: Introduce videos command --- shared/extra-utils/videos/index.ts | 1 + shared/extra-utils/videos/live-command.ts | 7 +- shared/extra-utils/videos/playlists-command.ts | 17 +- shared/extra-utils/videos/videos-command.ts | 583 ++++++++++++++++++++ shared/extra-utils/videos/videos.ts | 714 +------------------------ 5 files changed, 618 insertions(+), 704 deletions(-) create mode 100644 shared/extra-utils/videos/videos-command.ts (limited to 'shared/extra-utils/videos') diff --git a/shared/extra-utils/videos/index.ts b/shared/extra-utils/videos/index.ts index 652d82842..26e663f46 100644 --- a/shared/extra-utils/videos/index.ts +++ b/shared/extra-utils/videos/index.ts @@ -15,4 +15,5 @@ export * from './services-command' export * from './streaming-playlists-command' export * from './streaming-playlists' export * from './comments-command' +export * from './videos-command' export * from './videos' diff --git a/shared/extra-utils/videos/live-command.ts b/shared/extra-utils/videos/live-command.ts index a494e60fa..5adf601cc 100644 --- a/shared/extra-utils/videos/live-command.ts +++ b/shared/extra-utils/videos/live-command.ts @@ -9,7 +9,6 @@ import { wait } from '../miscs' import { unwrapBody } from '../requests' import { AbstractCommand, OverrideCommandOptions } from '../shared' import { sendRTMPStream, testFfmpegStreamError } from './live' -import { getVideoWithToken } from './videos' export class LiveCommand extends AbstractCommand { @@ -124,8 +123,7 @@ export class LiveCommand extends AbstractCommand { let video: VideoDetails do { - const res = await getVideoWithToken(this.server.url, options.token ?? this.server.accessToken, options.videoId) - video = res.body + video = await this.server.videosCommand.getWithToken({ token: options.token, id: options.videoId }) await wait(500) } while (video.isLive === true && video.state.id !== VideoState.PUBLISHED) @@ -149,8 +147,7 @@ export class LiveCommand extends AbstractCommand { let video: VideoDetails do { - const res = await getVideoWithToken(this.server.url, options.token ?? this.server.accessToken, options.videoId) - video = res.body + video = await this.server.videosCommand.getWithToken({ token: options.token, id: options.videoId }) await wait(500) } while (video.state.id !== options.state) diff --git a/shared/extra-utils/videos/playlists-command.ts b/shared/extra-utils/videos/playlists-command.ts index f77decc1a..75c8f2433 100644 --- a/shared/extra-utils/videos/playlists-command.ts +++ b/shared/extra-utils/videos/playlists-command.ts @@ -1,23 +1,22 @@ import { omit, pick } from 'lodash' +import { HttpStatusCode } from '@shared/core-utils' import { BooleanBothQuery, ResultList, VideoExistInPlaylist, VideoPlaylist, + VideoPlaylistCreate, VideoPlaylistCreateResult, VideoPlaylistElement, + VideoPlaylistElementCreate, VideoPlaylistElementCreateResult, - VideoPlaylistReorder + VideoPlaylistElementUpdate, + VideoPlaylistReorder, + VideoPlaylistType, + VideoPlaylistUpdate } from '@shared/models' -import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' -import { VideoPlaylistCreate } from '../../models/videos/playlist/video-playlist-create.model' -import { VideoPlaylistElementCreate } from '../../models/videos/playlist/video-playlist-element-create.model' -import { VideoPlaylistElementUpdate } from '../../models/videos/playlist/video-playlist-element-update.model' -import { VideoPlaylistType } from '../../models/videos/playlist/video-playlist-type.model' -import { VideoPlaylistUpdate } from '../../models/videos/playlist/video-playlist-update.model' import { unwrapBody } from '../requests' import { AbstractCommand, OverrideCommandOptions } from '../shared' -import { videoUUIDToId } from './videos' export class PlaylistsCommand extends AbstractCommand { @@ -185,7 +184,7 @@ export class PlaylistsCommand extends AbstractCommand { const attributes = { ...options.attributes, - videoId: await videoUUIDToId(this.server.url, options.attributes.videoId) + videoId: await this.server.videosCommand.getId({ ...options, uuid: options.attributes.videoId }) } const path = '/api/v1/video-playlists/' + options.playlistId + '/videos' diff --git a/shared/extra-utils/videos/videos-command.ts b/shared/extra-utils/videos/videos-command.ts new file mode 100644 index 000000000..574705474 --- /dev/null +++ b/shared/extra-utils/videos/videos-command.ts @@ -0,0 +1,583 @@ +/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/no-floating-promises */ + +import { expect } from 'chai' +import { createReadStream, stat } from 'fs-extra' +import got, { Response as GotResponse } from 'got' +import { omit, pick } from 'lodash' +import validator from 'validator' +import { buildUUID } from '@server/helpers/uuid' +import { loadLanguages } from '@server/initializers/constants' +import { HttpStatusCode } from '@shared/core-utils' +import { + ResultList, + UserVideoRateType, + Video, + VideoCreate, + VideoCreateResult, + VideoDetails, + VideoFileMetadata, + VideoPrivacy, + VideosCommonQuery, + VideosWithSearchCommonQuery +} from '@shared/models' +import { buildAbsoluteFixturePath, wait } from '../miscs' +import { unwrapBody } from '../requests' +import { ServerInfo, waitJobs } from '../server' +import { AbstractCommand, OverrideCommandOptions } from '../shared' + +export type VideoEdit = Partial> & { + fixture?: string + thumbnailfile?: string + previewfile?: string +} + +export class VideosCommand extends AbstractCommand { + + constructor (server: ServerInfo) { + super(server) + + loadLanguages() + } + + getCategories (options: OverrideCommandOptions = {}) { + const path = '/api/v1/videos/categories' + + return this.getRequestBody<{ [id: number]: string }>({ + ...options, + path, + + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + getLicences (options: OverrideCommandOptions = {}) { + const path = '/api/v1/videos/licences' + + return this.getRequestBody<{ [id: number]: string }>({ + ...options, + path, + + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + getLanguages (options: OverrideCommandOptions = {}) { + const path = '/api/v1/videos/languages' + + return this.getRequestBody<{ [id: string]: string }>({ + ...options, + path, + + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + getPrivacies (options: OverrideCommandOptions = {}) { + const path = '/api/v1/videos/privacies' + + return this.getRequestBody<{ [id in VideoPrivacy]: string }>({ + ...options, + path, + + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + // --------------------------------------------------------------------------- + + getDescription (options: OverrideCommandOptions & { + descriptionPath: string + }) { + return this.getRequestBody<{ description: string }>({ + ...options, + path: options.descriptionPath, + + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + getFileMetadata (options: OverrideCommandOptions & { + url: string + }) { + return unwrapBody(this.getRawRequest({ + ...options, + + url: options.url, + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + })) + } + + // --------------------------------------------------------------------------- + + view (options: OverrideCommandOptions & { + id: number | string + xForwardedFor?: string + }) { + const { id, xForwardedFor } = options + const path = '/api/v1/videos/' + id + '/views' + + return this.postBodyRequest({ + ...options, + + path, + xForwardedFor, + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } + + rate (options: OverrideCommandOptions & { + id: number | string + rating: UserVideoRateType + }) { + const { id, rating } = options + const path = '/api/v1/videos/' + id + '/rate' + + return this.putBodyRequest({ + ...options, + + path, + fields: { rating }, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } + + // --------------------------------------------------------------------------- + + get (options: OverrideCommandOptions & { + id: number | string + }) { + const path = '/api/v1/videos/' + options.id + + return this.getRequestBody({ + ...options, + + path, + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + getWithToken (options: OverrideCommandOptions & { + id: number | string + }) { + return this.get({ + ...options, + + token: this.buildCommonRequestToken({ ...options, implicitToken: true }) + }) + } + + async getId (options: OverrideCommandOptions & { + uuid: number | string + }) { + const { uuid } = options + + if (validator.isUUID('' + uuid) === false) return uuid as number + + const { id } = await this.get({ ...options, id: uuid }) + + return id + } + + // --------------------------------------------------------------------------- + + listMyVideos (options: OverrideCommandOptions & { + start?: number + count?: number + sort?: string + search?: string + isLive?: boolean + } = {}) { + const path = '/api/v1/users/me/videos' + + return this.getRequestBody>({ + ...options, + + path, + query: pick(options, [ 'start', 'count', 'sort', 'search', 'isLive' ]), + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + // --------------------------------------------------------------------------- + + list (options: OverrideCommandOptions & VideosCommonQuery = {}) { + const path = '/api/v1/videos' + + const query = this.buildListQuery(options) + + return this.getRequestBody>({ + ...options, + + path, + query: { sort: 'name', ...query }, + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + listWithToken (options: OverrideCommandOptions & VideosCommonQuery = {}) { + return this.list({ + ...options, + + token: this.buildCommonRequestToken({ ...options, implicitToken: true }) + }) + } + + listByAccount (options: OverrideCommandOptions & VideosWithSearchCommonQuery & { + accountName: string + }) { + const { accountName, search } = options + const path = '/api/v1/accounts/' + accountName + '/videos' + + return this.getRequestBody>({ + ...options, + + path, + query: { search, ...this.buildListQuery(options) }, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + listByChannel (options: OverrideCommandOptions & VideosWithSearchCommonQuery & { + videoChannelName: string + }) { + const { videoChannelName } = options + const path = '/api/v1/video-channels/' + videoChannelName + '/videos' + + return this.getRequestBody>({ + ...options, + + path, + query: this.buildListQuery(options), + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + // --------------------------------------------------------------------------- + + update (options: OverrideCommandOptions & { + id: number | string + attributes?: VideoEdit + }) { + const { id, attributes = {} } = options + const path = '/api/v1/videos/' + id + + // Upload request + if (attributes.thumbnailfile || attributes.previewfile) { + const attaches: any = {} + if (attributes.thumbnailfile) attaches.thumbnailfile = attributes.thumbnailfile + if (attributes.previewfile) attaches.previewfile = attributes.previewfile + + return this.putUploadRequest({ + ...options, + + path, + fields: options.attributes, + attaches: { + thumbnailfile: attributes.thumbnailfile, + previewfile: attributes.previewfile + }, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } + + return this.putBodyRequest({ + ...options, + + path, + fields: options.attributes, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } + + remove (options: OverrideCommandOptions & { + id: number | string + }) { + const path = '/api/v1/videos/' + options.id + + return this.deleteRequest({ + ...options, + + path, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } + + async removeAll () { + const { data } = await this.list() + + for (const v of data) { + await this.remove({ id: v.id }) + } + } + + // --------------------------------------------------------------------------- + + async upload (options: OverrideCommandOptions & { + attributes?: VideoEdit + mode?: 'legacy' | 'resumable' // default legacy + } = {}) { + const { mode = 'legacy', expectedStatus } = options + let defaultChannelId = 1 + + try { + const { videoChannels } = await this.server.usersCommand.getMyInfo({ token: options.token }) + defaultChannelId = videoChannels[0].id + } catch (e) { /* empty */ } + + // Override default attributes + const attributes = { + name: 'my super video', + category: 5, + licence: 4, + language: 'zh', + channelId: defaultChannelId, + nsfw: true, + waitTranscoding: false, + description: 'my super description', + support: 'my super support text', + tags: [ 'tag' ], + privacy: VideoPrivacy.PUBLIC, + commentsEnabled: true, + downloadEnabled: true, + fixture: 'video_short.webm', + + ...options.attributes + } + + const res = mode === 'legacy' + ? await this.buildLegacyUpload({ ...options, attributes }) + : await this.buildResumeUpload({ ...options, attributes }) + + // Wait torrent generation + if (expectedStatus === HttpStatusCode.OK_200) { + let video: VideoDetails + + do { + video = await this.getWithToken({ ...options, id: video.uuid }) + + await wait(50) + } while (!video.files[0].torrentUrl) + } + + return res + } + + async buildLegacyUpload (options: OverrideCommandOptions & { + attributes: VideoEdit + }): Promise { + const path = '/api/v1/videos/upload' + + return unwrapBody<{ video: VideoCreateResult }>(this.postUploadRequest({ + ...options, + + path, + fields: this.buildUploadFields(options.attributes), + attaches: this.buildUploadAttaches(options.attributes), + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.OK_200 + })).then(body => body.video || body as any) + } + + async buildResumeUpload (options: OverrideCommandOptions & { + attributes: VideoEdit + }) { + const { attributes, expectedStatus } = options + + let size = 0 + let videoFilePath: string + let mimetype = 'video/mp4' + + if (attributes.fixture) { + videoFilePath = buildAbsoluteFixturePath(attributes.fixture) + size = (await stat(videoFilePath)).size + + if (videoFilePath.endsWith('.mkv')) { + mimetype = 'video/x-matroska' + } else if (videoFilePath.endsWith('.webm')) { + mimetype = 'video/webm' + } + } + + const initializeSessionRes = await this.prepareResumableUpload({ ...options, attributes, size, mimetype }) + const initStatus = initializeSessionRes.status + + if (videoFilePath && initStatus === HttpStatusCode.CREATED_201) { + const locationHeader = initializeSessionRes.header['location'] + expect(locationHeader).to.not.be.undefined + + const pathUploadId = locationHeader.split('?')[1] + + const result = await this.sendResumableChunks({ ...options, pathUploadId, videoFilePath, size }) + + return result.body.video + } + + const expectedInitStatus = expectedStatus === HttpStatusCode.OK_200 + ? HttpStatusCode.CREATED_201 + : expectedStatus + + expect(initStatus).to.equal(expectedInitStatus) + + return initializeSessionRes.body.video as VideoCreateResult + } + + async prepareResumableUpload (options: OverrideCommandOptions & { + attributes: VideoEdit + size: number + mimetype: string + }) { + const { attributes, size, mimetype } = options + + const path = '/api/v1/videos/upload-resumable' + + return this.postUploadRequest({ + ...options, + + path, + headers: { + 'X-Upload-Content-Type': mimetype, + 'X-Upload-Content-Length': size.toString() + }, + fields: { filename: attributes.fixture, ...this.buildUploadFields(options.attributes) }, + implicitToken: true, + defaultExpectedStatus: null + }) + } + + sendResumableChunks (options: OverrideCommandOptions & { + pathUploadId: string + videoFilePath: string + size: number + contentLength?: number + contentRangeBuilder?: (start: number, chunk: any) => string + }) { + const { pathUploadId, videoFilePath, size, contentLength, contentRangeBuilder, expectedStatus = HttpStatusCode.OK_200 } = options + + const path = '/api/v1/videos/upload-resumable' + let start = 0 + + const token = this.buildCommonRequestToken({ ...options, implicitToken: true }) + const url = this.server.url + + const readable = createReadStream(videoFilePath, { highWaterMark: 8 * 1024 }) + return new Promise>((resolve, reject) => { + readable.on('data', async function onData (chunk) { + readable.pause() + + const headers = { + 'Authorization': 'Bearer ' + token, + 'Content-Type': 'application/octet-stream', + 'Content-Range': contentRangeBuilder + ? contentRangeBuilder(start, chunk) + : `bytes ${start}-${start + chunk.length - 1}/${size}`, + 'Content-Length': contentLength ? contentLength + '' : chunk.length + '' + } + + const res = await got<{ video: VideoCreateResult }>({ + url, + method: 'put', + headers, + path: path + '?' + pathUploadId, + body: chunk, + responseType: 'json', + throwHttpErrors: false + }) + + start += chunk.length + + if (res.statusCode === expectedStatus) { + return resolve(res) + } + + if (res.statusCode !== HttpStatusCode.PERMANENT_REDIRECT_308) { + readable.off('data', onData) + return reject(new Error('Incorrect transient behaviour sending intermediary chunks')) + } + + readable.resume() + }) + }) + } + + quickUpload (options: OverrideCommandOptions & { + name: string + nsfw?: boolean + privacy?: VideoPrivacy + fixture?: string + }) { + const attributes: VideoEdit = { name: options.name } + if (options.nsfw) attributes.nsfw = options.nsfw + if (options.privacy) attributes.privacy = options.privacy + if (options.fixture) attributes.fixture = options.fixture + + return this.upload({ ...options, attributes }) + } + + async randomUpload (options: OverrideCommandOptions & { + wait?: boolean // default true + additionalParams?: VideoEdit & { prefixName: string } + } = {}) { + const { wait = true, additionalParams } = options + const prefixName = additionalParams?.prefixName || '' + const name = prefixName + buildUUID() + + const attributes = { name, additionalParams } + + if (wait) await waitJobs([ this.server ]) + + const result = await this.upload({ ...options, attributes }) + + return { ...result, name } + } + + // --------------------------------------------------------------------------- + + private buildListQuery (options: VideosCommonQuery) { + return pick(options, [ + 'start', + 'count', + 'sort', + 'nsfw', + 'isLive', + 'categoryOneOf', + 'licenceOneOf', + 'languageOneOf', + 'tagsOneOf', + 'tagsAllOf', + 'filter', + 'skipCount' + ]) + } + + private buildUploadFields (attributes: VideoEdit) { + return omit(attributes, [ 'thumbnailfile', 'previewfile' ]) + } + + private buildUploadAttaches (attributes: VideoEdit) { + const attaches: { [ name: string ]: string } = {} + + for (const key of [ 'thumbnailfile', 'previewfile' ]) { + if (attributes[key]) attaches[key] = buildAbsoluteFixturePath(attributes[key]) + } + + if (attributes.fixture) attaches.videofile = buildAbsoluteFixturePath(attributes.fixture) + + return attaches + } +} diff --git a/shared/extra-utils/videos/videos.ts b/shared/extra-utils/videos/videos.ts index 5e20f8010..19f0df8b8 100644 --- a/shared/extra-utils/videos/videos.ts +++ b/shared/extra-utils/videos/videos.ts @@ -1,306 +1,16 @@ /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/no-floating-promises */ import { expect } from 'chai' -import { createReadStream, pathExists, readdir, readFile, stat } from 'fs-extra' -import got, { Response as GotResponse } from 'got/dist/source' -import * as parseTorrent from 'parse-torrent' +import { pathExists, readdir } from 'fs-extra' import { join } from 'path' -import * as request from 'supertest' -import validator from 'validator' import { getLowercaseExtension } from '@server/helpers/core-utils' -import { buildUUID } from '@server/helpers/uuid' import { HttpStatusCode } from '@shared/core-utils' -import { BooleanBothQuery, VideosCommonQuery } from '@shared/models' -import { loadLanguages, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../server/initializers/constants' -import { VideoDetails, VideoPrivacy } from '../../models/videos' -import { buildAbsoluteFixturePath, dateIsValid, testImage, wait, webtorrentAdd } from '../miscs' -import { makeGetRequest, makePutBodyRequest, makeRawRequest, makeUploadRequest } from '../requests/requests' -import { waitJobs } from '../server/jobs' +import { VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../server/initializers/constants' +import { dateIsValid, testImage, webtorrentAdd } from '../miscs' +import { makeRawRequest } from '../requests/requests' +import { waitJobs } from '../server' import { ServerInfo } from '../server/servers' -import { xxxgetMyUserInformation } from '../users' - -loadLanguages() - -type VideoAttributes = { - name?: string - category?: number - licence?: number - language?: string - nsfw?: boolean - commentsEnabled?: boolean - downloadEnabled?: boolean - waitTranscoding?: boolean - description?: string - originallyPublishedAt?: string - tags?: string[] - channelId?: number - privacy?: VideoPrivacy - fixture?: string - support?: string - thumbnailfile?: string - previewfile?: string - scheduleUpdate?: { - updateAt: string - privacy?: VideoPrivacy - } -} - -function getVideoCategories (url: string) { - const path = '/api/v1/videos/categories' - - return makeGetRequest({ - url, - path, - statusCodeExpected: HttpStatusCode.OK_200 - }) -} - -function getVideoLicences (url: string) { - const path = '/api/v1/videos/licences' - - return makeGetRequest({ - url, - path, - statusCodeExpected: HttpStatusCode.OK_200 - }) -} - -function getVideoLanguages (url: string) { - const path = '/api/v1/videos/languages' - - return makeGetRequest({ - url, - path, - statusCodeExpected: HttpStatusCode.OK_200 - }) -} - -function getVideoPrivacies (url: string) { - const path = '/api/v1/videos/privacies' - - return makeGetRequest({ - url, - path, - statusCodeExpected: HttpStatusCode.OK_200 - }) -} - -function getVideo (url: string, id: number | string, expectedStatus = HttpStatusCode.OK_200) { - const path = '/api/v1/videos/' + id - - return request(url) - .get(path) - .set('Accept', 'application/json') - .expect(expectedStatus) -} - -async function getVideoIdFromUUID (url: string, uuid: string) { - const res = await getVideo(url, uuid) - - return res.body.id -} - -function getVideoFileMetadataUrl (url: string) { - return request(url) - .get('/') - .set('Accept', 'application/json') - .expect(HttpStatusCode.OK_200) - .expect('Content-Type', /json/) -} - -function viewVideo (url: string, id: number | string, expectedStatus = HttpStatusCode.NO_CONTENT_204, xForwardedFor?: string) { - const path = '/api/v1/videos/' + id + '/views' - - const req = request(url) - .post(path) - .set('Accept', 'application/json') - - if (xForwardedFor) { - req.set('X-Forwarded-For', xForwardedFor) - } - - return req.expect(expectedStatus) -} - -function getVideoWithToken (url: string, token: string, id: number | string, expectedStatus = HttpStatusCode.OK_200) { - const path = '/api/v1/videos/' + id - - return request(url) - .get(path) - .set('Authorization', 'Bearer ' + token) - .set('Accept', 'application/json') - .expect(expectedStatus) -} - -function getVideoDescription (url: string, descriptionPath: string) { - return request(url) - .get(descriptionPath) - .set('Accept', 'application/json') - .expect(HttpStatusCode.OK_200) - .expect('Content-Type', /json/) -} - -function getVideosList (url: string) { - const path = '/api/v1/videos' - - return request(url) - .get(path) - .query({ sort: 'name' }) - .set('Accept', 'application/json') - .expect(HttpStatusCode.OK_200) - .expect('Content-Type', /json/) -} - -function getVideosListWithToken (url: string, token: string, query: { nsfw?: BooleanBothQuery } = {}) { - const path = '/api/v1/videos' - - return request(url) - .get(path) - .set('Authorization', 'Bearer ' + token) - .query({ sort: 'name', ...query }) - .set('Accept', 'application/json') - .expect(HttpStatusCode.OK_200) - .expect('Content-Type', /json/) -} - -function getLocalVideos (url: string) { - const path = '/api/v1/videos' - - return request(url) - .get(path) - .query({ sort: 'name', filter: 'local' }) - .set('Accept', 'application/json') - .expect(HttpStatusCode.OK_200) - .expect('Content-Type', /json/) -} - -function getMyVideos (url: string, accessToken: string, start: number, count: number, sort?: string, search?: string) { - const path = '/api/v1/users/me/videos' - - const req = request(url) - .get(path) - .query({ start: start }) - .query({ count: count }) - .query({ search: search }) - - if (sort) req.query({ sort }) - - return req.set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + accessToken) - .expect(HttpStatusCode.OK_200) - .expect('Content-Type', /json/) -} - -function getMyVideosWithFilter (url: string, accessToken: string, query: { isLive?: boolean }) { - const path = '/api/v1/users/me/videos' - - return makeGetRequest({ - url, - path, - token: accessToken, - query, - statusCodeExpected: HttpStatusCode.OK_200 - }) -} - -function getAccountVideos ( - url: string, - accessToken: string, - accountName: string, - start: number, - count: number, - sort?: string, - query: { - nsfw?: BooleanBothQuery - search?: string - } = {} -) { - const path = '/api/v1/accounts/' + accountName + '/videos' - - return makeGetRequest({ - url, - path, - query: { ...query, start, count, sort }, - token: accessToken, - statusCodeExpected: HttpStatusCode.OK_200 - }) -} - -function getVideoChannelVideos ( - url: string, - accessToken: string, - videoChannelName: string, - start: number, - count: number, - sort?: string, - query: { nsfw?: BooleanBothQuery } = {} -) { - const path = '/api/v1/video-channels/' + videoChannelName + '/videos' - - return makeGetRequest({ - url, - path, - query: { ...query, start, count, sort }, - token: accessToken, - statusCodeExpected: HttpStatusCode.OK_200 - }) -} - -function getVideosListPagination (url: string, start: number, count: number, sort?: string, skipCount?: boolean) { - const path = '/api/v1/videos' - - const req = request(url) - .get(path) - .query({ start: start }) - .query({ count: count }) - - if (sort) req.query({ sort }) - if (skipCount) req.query({ skipCount }) - - return req.set('Accept', 'application/json') - .expect(HttpStatusCode.OK_200) - .expect('Content-Type', /json/) -} - -function getVideosListSort (url: string, sort: string) { - const path = '/api/v1/videos' - - return request(url) - .get(path) - .query({ sort: sort }) - .set('Accept', 'application/json') - .expect(HttpStatusCode.OK_200) - .expect('Content-Type', /json/) -} - -function getVideosWithFilters (url: string, query: VideosCommonQuery) { - const path = '/api/v1/videos' - - return request(url) - .get(path) - .query(query) - .set('Accept', 'application/json') - .expect(HttpStatusCode.OK_200) - .expect('Content-Type', /json/) -} - -function removeVideo (url: string, token: string, id: number | string, expectedStatus = HttpStatusCode.NO_CONTENT_204) { - const path = '/api/v1/videos' - - return request(url) - .delete(path + '/' + id) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(expectedStatus) -} - -async function removeAllVideos (server: ServerInfo) { - const resVideos = await getVideosList(server.url) - - for (const v of resVideos.body.data) { - await removeVideo(server.url, server.accessToken, v.id) - } -} +import { VideoEdit } from './videos-command' async function checkVideoFilesWereRemoved ( videoUUID: string, @@ -329,280 +39,20 @@ async function checkVideoFilesWereRemoved ( } } -async function uploadVideo ( - url: string, - accessToken: string, - videoAttributesArg: VideoAttributes, - specialStatus = HttpStatusCode.OK_200, - mode: 'legacy' | 'resumable' = 'legacy' -) { - let defaultChannelId = '1' - - try { - const res = await xxxgetMyUserInformation(url, accessToken) - defaultChannelId = res.body.videoChannels[0].id - } catch (e) { /* empty */ } - - // Override default attributes - const attributes = Object.assign({ - name: 'my super video', - category: 5, - licence: 4, - language: 'zh', - channelId: defaultChannelId, - nsfw: true, - waitTranscoding: false, - description: 'my super description', - support: 'my super support text', - tags: [ 'tag' ], - privacy: VideoPrivacy.PUBLIC, - commentsEnabled: true, - downloadEnabled: true, - fixture: 'video_short.webm' - }, videoAttributesArg) - - const res = mode === 'legacy' - ? await buildLegacyUpload(url, accessToken, attributes, specialStatus) - : await buildResumeUpload(url, accessToken, attributes, specialStatus) - - // Wait torrent generation - if (specialStatus === HttpStatusCode.OK_200) { - let video: VideoDetails - do { - const resVideo = await getVideoWithToken(url, accessToken, res.body.video.uuid) - video = resVideo.body - - await wait(50) - } while (!video.files[0].torrentUrl) - } - - return res -} - function checkUploadVideoParam ( - url: string, + server: ServerInfo, token: string, - attributes: Partial, - specialStatus = HttpStatusCode.OK_200, + attributes: Partial, + expectedStatus = HttpStatusCode.OK_200, mode: 'legacy' | 'resumable' = 'legacy' ) { return mode === 'legacy' - ? buildLegacyUpload(url, token, attributes, specialStatus) - : buildResumeUpload(url, token, attributes, specialStatus) -} - -async function buildLegacyUpload (url: string, token: string, attributes: VideoAttributes, specialStatus = HttpStatusCode.OK_200) { - const path = '/api/v1/videos/upload' - const req = request(url) - .post(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - - buildUploadReq(req, attributes) - - if (attributes.fixture !== undefined) { - req.attach('videofile', buildAbsoluteFixturePath(attributes.fixture)) - } - - return req.expect(specialStatus) -} - -async function buildResumeUpload (url: string, token: string, attributes: VideoAttributes, specialStatus = HttpStatusCode.OK_200) { - let size = 0 - let videoFilePath: string - let mimetype = 'video/mp4' - - if (attributes.fixture) { - videoFilePath = buildAbsoluteFixturePath(attributes.fixture) - size = (await stat(videoFilePath)).size - - if (videoFilePath.endsWith('.mkv')) { - mimetype = 'video/x-matroska' - } else if (videoFilePath.endsWith('.webm')) { - mimetype = 'video/webm' - } - } - - const initializeSessionRes = await prepareResumableUpload({ url, token, attributes, size, mimetype }) - const initStatus = initializeSessionRes.status - - if (videoFilePath && initStatus === HttpStatusCode.CREATED_201) { - const locationHeader = initializeSessionRes.header['location'] - expect(locationHeader).to.not.be.undefined - - const pathUploadId = locationHeader.split('?')[1] - - return sendResumableChunks({ url, token, pathUploadId, videoFilePath, size, specialStatus }) - } - - const expectedInitStatus = specialStatus === HttpStatusCode.OK_200 - ? HttpStatusCode.CREATED_201 - : specialStatus - - expect(initStatus).to.equal(expectedInitStatus) - - return initializeSessionRes -} - -async function prepareResumableUpload (options: { - url: string - token: string - attributes: VideoAttributes - size: number - mimetype: string -}) { - const { url, token, attributes, size, mimetype } = options - - const path = '/api/v1/videos/upload-resumable' - - const req = request(url) - .post(path) - .set('Authorization', 'Bearer ' + token) - .set('X-Upload-Content-Type', mimetype) - .set('X-Upload-Content-Length', size.toString()) - - buildUploadReq(req, attributes) - - if (attributes.fixture) { - req.field('filename', attributes.fixture) - } - - return req -} - -function sendResumableChunks (options: { - url: string - token: string - pathUploadId: string - videoFilePath: string - size: number - specialStatus?: HttpStatusCode - contentLength?: number - contentRangeBuilder?: (start: number, chunk: any) => string -}) { - const { url, token, pathUploadId, videoFilePath, size, specialStatus, contentLength, contentRangeBuilder } = options - - const expectedStatus = specialStatus || HttpStatusCode.OK_200 - - const path = '/api/v1/videos/upload-resumable' - let start = 0 - - const readable = createReadStream(videoFilePath, { highWaterMark: 8 * 1024 }) - return new Promise((resolve, reject) => { - readable.on('data', async function onData (chunk) { - readable.pause() - - const headers = { - 'Authorization': 'Bearer ' + token, - 'Content-Type': 'application/octet-stream', - 'Content-Range': contentRangeBuilder - ? contentRangeBuilder(start, chunk) - : `bytes ${start}-${start + chunk.length - 1}/${size}`, - 'Content-Length': contentLength ? contentLength + '' : chunk.length + '' - } - - const res = await got({ - url, - method: 'put', - headers, - path: path + '?' + pathUploadId, - body: chunk, - responseType: 'json', - throwHttpErrors: false - }) - - start += chunk.length - - if (res.statusCode === expectedStatus) { - return resolve(res) - } - - if (res.statusCode !== HttpStatusCode.PERMANENT_REDIRECT_308) { - readable.off('data', onData) - return reject(new Error('Incorrect transient behaviour sending intermediary chunks')) - } - - readable.resume() - }) - }) -} - -function updateVideo ( - url: string, - accessToken: string, - id: number | string, - attributes: VideoAttributes, - statusCodeExpected = HttpStatusCode.NO_CONTENT_204 -) { - const path = '/api/v1/videos/' + id - const body = {} - - if (attributes.name) body['name'] = attributes.name - if (attributes.category) body['category'] = attributes.category - if (attributes.licence) body['licence'] = attributes.licence - if (attributes.language) body['language'] = attributes.language - if (attributes.nsfw !== undefined) body['nsfw'] = JSON.stringify(attributes.nsfw) - if (attributes.commentsEnabled !== undefined) body['commentsEnabled'] = JSON.stringify(attributes.commentsEnabled) - if (attributes.downloadEnabled !== undefined) body['downloadEnabled'] = JSON.stringify(attributes.downloadEnabled) - if (attributes.originallyPublishedAt !== undefined) body['originallyPublishedAt'] = attributes.originallyPublishedAt - if (attributes.description) body['description'] = attributes.description - if (attributes.tags) body['tags'] = attributes.tags - if (attributes.privacy) body['privacy'] = attributes.privacy - if (attributes.channelId) body['channelId'] = attributes.channelId - if (attributes.scheduleUpdate) body['scheduleUpdate'] = attributes.scheduleUpdate - - // Upload request - if (attributes.thumbnailfile || attributes.previewfile) { - const attaches: any = {} - if (attributes.thumbnailfile) attaches.thumbnailfile = attributes.thumbnailfile - if (attributes.previewfile) attaches.previewfile = attributes.previewfile - - return makeUploadRequest({ - url, - method: 'PUT', - path, - token: accessToken, - fields: body, - attaches, - statusCodeExpected - }) - } - - return makePutBodyRequest({ - url, - path, - fields: body, - token: accessToken, - statusCodeExpected - }) -} - -function rateVideo (url: string, accessToken: string, id: number | string, rating: string, specialStatus = HttpStatusCode.NO_CONTENT_204) { - const path = '/api/v1/videos/' + id + '/rate' - - return request(url) - .put(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + accessToken) - .send({ rating }) - .expect(specialStatus) -} - -function parseTorrentVideo (server: ServerInfo, videoUUID: string, resolution: number) { - return new Promise((res, rej) => { - const torrentName = videoUUID + '-' + resolution + '.torrent' - const torrentPath = server.serversCommand.buildDirectory(join('torrents', torrentName)) - - readFile(torrentPath, (err, data) => { - if (err) return rej(err) - - return res(parseTorrent(data)) - }) - }) + ? server.videosCommand.buildLegacyUpload({ token, attributes, expectedStatus }) + : server.videosCommand.buildResumeUpload({ token, attributes, expectedStatus }) } async function completeVideoCheck ( - url: string, + server: ServerInfo, video: any, attributes: { name: string @@ -644,7 +94,7 @@ async function completeVideoCheck ( if (!attributes.likes) attributes.likes = 0 if (!attributes.dislikes) attributes.dislikes = 0 - const host = new URL(url).host + const host = new URL(server.url).host const originHost = attributes.account.host expect(video.name).to.equal(attributes.name) @@ -681,8 +131,7 @@ async function completeVideoCheck ( expect(video.originallyPublishedAt).to.be.null } - const res = await getVideo(url, video.uuid) - const videoDetails: VideoDetails = res.body + const videoDetails = await server.videosCommand.get({ id: video.uuid }) expect(videoDetails.files).to.have.lengthOf(attributes.files.length) expect(videoDetails.tags).to.deep.equal(attributes.tags) @@ -738,148 +187,33 @@ async function completeVideoCheck ( } expect(videoDetails.thumbnailPath).to.exist - await testImage(url, attributes.thumbnailfile || attributes.fixture, videoDetails.thumbnailPath) + await testImage(server.url, attributes.thumbnailfile || attributes.fixture, videoDetails.thumbnailPath) if (attributes.previewfile) { expect(videoDetails.previewPath).to.exist - await testImage(url, attributes.previewfile, videoDetails.previewPath) + await testImage(server.url, attributes.previewfile, videoDetails.previewPath) } } -async function videoUUIDToId (url: string, id: number | string) { - if (validator.isUUID('' + id) === false) return id - - const res = await getVideo(url, id) - return res.body.id -} - -async function uploadVideoAndGetId (options: { - server: ServerInfo - videoName: string - nsfw?: boolean - privacy?: VideoPrivacy - token?: string - fixture?: string -}) { - const videoAttrs: any = { name: options.videoName } - if (options.nsfw) videoAttrs.nsfw = options.nsfw - if (options.privacy) videoAttrs.privacy = options.privacy - if (options.fixture) videoAttrs.fixture = options.fixture - - const res = await uploadVideo(options.server.url, options.token || options.server.accessToken, videoAttrs) - - return res.body.video as { id: number, uuid: string, shortUUID: string } -} - -async function getLocalIdByUUID (url: string, uuid: string) { - const res = await getVideo(url, uuid) - - return res.body.id -} - // serverNumber starts from 1 -async function uploadRandomVideoOnServers (servers: ServerInfo[], serverNumber: number, additionalParams: any = {}) { +async function uploadRandomVideoOnServers ( + servers: ServerInfo[], + serverNumber: number, + additionalParams?: VideoEdit & { prefixName?: string } +) { const server = servers.find(s => s.serverNumber === serverNumber) - const res = await uploadRandomVideo(server, false, additionalParams) + const res = await server.videosCommand.randomUpload({ wait: false, ...additionalParams }) await waitJobs(servers) return res } -async function uploadRandomVideo (server: ServerInfo, wait = true, additionalParams: any = {}) { - const prefixName = additionalParams.prefixName || '' - const name = prefixName + buildUUID() - - const data = Object.assign({ name }, additionalParams) - const res = await uploadVideo(server.url, server.accessToken, data) - - if (wait) await waitJobs([ server ]) - - return { uuid: res.body.video.uuid, name } -} - // --------------------------------------------------------------------------- export { - getVideoDescription, - getVideoCategories, - uploadRandomVideo, - getVideoLicences, - videoUUIDToId, - getVideoPrivacies, - getVideoLanguages, - getMyVideos, - getAccountVideos, - getVideoChannelVideos, - getVideo, - getVideoFileMetadataUrl, - getVideoWithToken, - getVideosList, - removeAllVideos, checkUploadVideoParam, - getVideosListPagination, - getVideosListSort, - removeVideo, - getVideosListWithToken, - uploadVideo, - sendResumableChunks, - getVideosWithFilters, - uploadRandomVideoOnServers, - updateVideo, - rateVideo, - viewVideo, - parseTorrentVideo, - getLocalVideos, completeVideoCheck, - checkVideoFilesWereRemoved, - getMyVideosWithFilter, - uploadVideoAndGetId, - getLocalIdByUUID, - getVideoIdFromUUID, - prepareResumableUpload -} - -// --------------------------------------------------------------------------- - -function buildUploadReq (req: request.Test, attributes: VideoAttributes) { - - for (const key of [ 'name', 'support', 'channelId', 'description', 'originallyPublishedAt' ]) { - if (attributes[key] !== undefined) { - req.field(key, attributes[key]) - } - } - - for (const key of [ 'nsfw', 'commentsEnabled', 'downloadEnabled', 'waitTranscoding' ]) { - if (attributes[key] !== undefined) { - req.field(key, JSON.stringify(attributes[key])) - } - } - - for (const key of [ 'language', 'privacy', 'category', 'licence' ]) { - if (attributes[key] !== undefined) { - req.field(key, attributes[key].toString()) - } - } - - const tags = attributes.tags || [] - for (let i = 0; i < tags.length; i++) { - req.field('tags[' + i + ']', attributes.tags[i]) - } - - for (const key of [ 'thumbnailfile', 'previewfile' ]) { - if (attributes[key] !== undefined) { - req.attach(key, buildAbsoluteFixturePath(attributes[key])) - } - } - - if (attributes.scheduleUpdate) { - if (attributes.scheduleUpdate.updateAt) { - req.field('scheduleUpdate[updateAt]', attributes.scheduleUpdate.updateAt) - } - - if (attributes.scheduleUpdate.privacy) { - req.field('scheduleUpdate[privacy]', attributes.scheduleUpdate.privacy) - } - } + uploadRandomVideoOnServers, + checkVideoFilesWereRemoved } -- cgit v1.2.3 From 89d241a79c262b9775c233b73cff080043ebb5e6 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 16 Jul 2021 09:04:35 +0200 Subject: Shorter server command names --- shared/extra-utils/videos/channels.ts | 4 ++-- shared/extra-utils/videos/live-command.ts | 8 ++++---- shared/extra-utils/videos/live.ts | 4 ++-- shared/extra-utils/videos/playlists-command.ts | 2 +- shared/extra-utils/videos/streaming-playlists.ts | 6 +++--- shared/extra-utils/videos/videos-command.ts | 2 +- shared/extra-utils/videos/videos.ts | 10 +++++----- 7 files changed, 18 insertions(+), 18 deletions(-) (limited to 'shared/extra-utils/videos') diff --git a/shared/extra-utils/videos/channels.ts b/shared/extra-utils/videos/channels.ts index 9e7ec565d..81e818094 100644 --- a/shared/extra-utils/videos/channels.ts +++ b/shared/extra-utils/videos/channels.ts @@ -4,8 +4,8 @@ function setDefaultVideoChannel (servers: ServerInfo[]) { const tasks: Promise[] = [] for (const server of servers) { - const p = server.usersCommand.getMyInfo() - .then(user => { server.videoChannel = user.videoChannels[0] }) + const p = server.users.getMyInfo() + .then(user => { server.store.channel = user.videoChannels[0] }) tasks.push(p) } diff --git a/shared/extra-utils/videos/live-command.ts b/shared/extra-utils/videos/live-command.ts index 5adf601cc..fd66c9924 100644 --- a/shared/extra-utils/videos/live-command.ts +++ b/shared/extra-utils/videos/live-command.ts @@ -114,7 +114,7 @@ export class LiveCommand extends AbstractCommand { const { resolution, segment, videoUUID } = options const segmentName = `${resolution}-00000${segment}.ts` - return this.server.serversCommand.waitUntilLog(`${videoUUID}/${segmentName}`, 2, false) + return this.server.servers.waitUntilLog(`${videoUUID}/${segmentName}`, 2, false) } async waitUntilSaved (options: OverrideCommandOptions & { @@ -123,7 +123,7 @@ export class LiveCommand extends AbstractCommand { let video: VideoDetails do { - video = await this.server.videosCommand.getWithToken({ token: options.token, id: options.videoId }) + video = await this.server.videos.getWithToken({ token: options.token, id: options.videoId }) await wait(500) } while (video.isLive === true && video.state.id !== VideoState.PUBLISHED) @@ -132,7 +132,7 @@ export class LiveCommand extends AbstractCommand { async countPlaylists (options: OverrideCommandOptions & { videoUUID: string }) { - const basePath = this.server.serversCommand.buildDirectory('streaming-playlists') + const basePath = this.server.servers.buildDirectory('streaming-playlists') const hlsPath = join(basePath, 'hls', options.videoUUID) const files = await readdir(hlsPath) @@ -147,7 +147,7 @@ export class LiveCommand extends AbstractCommand { let video: VideoDetails do { - video = await this.server.videosCommand.getWithToken({ token: options.token, id: options.videoId }) + video = await this.server.videos.getWithToken({ token: options.token, id: options.videoId }) await wait(500) } while (video.state.id !== options.state) diff --git a/shared/extra-utils/videos/live.ts b/shared/extra-utils/videos/live.ts index 0efcc2883..353595811 100644 --- a/shared/extra-utils/videos/live.ts +++ b/shared/extra-utils/videos/live.ts @@ -72,12 +72,12 @@ async function stopFfmpeg (command: ffmpeg.FfmpegCommand) { async function waitUntilLivePublishedOnAllServers (servers: ServerInfo[], videoId: string) { for (const server of servers) { - await server.liveCommand.waitUntilPublished({ videoId }) + await server.live.waitUntilPublished({ videoId }) } } async function checkLiveCleanup (server: ServerInfo, videoUUID: string, resolutions: number[] = []) { - const basePath = server.serversCommand.buildDirectory('streaming-playlists') + const basePath = server.servers.buildDirectory('streaming-playlists') const hlsPath = join(basePath, 'hls', videoUUID) if (resolutions.length === 0) { diff --git a/shared/extra-utils/videos/playlists-command.ts b/shared/extra-utils/videos/playlists-command.ts index 75c8f2433..cbfc7e10f 100644 --- a/shared/extra-utils/videos/playlists-command.ts +++ b/shared/extra-utils/videos/playlists-command.ts @@ -184,7 +184,7 @@ export class PlaylistsCommand extends AbstractCommand { const attributes = { ...options.attributes, - videoId: await this.server.videosCommand.getId({ ...options, uuid: options.attributes.videoId }) + videoId: await this.server.videos.getId({ ...options, uuid: options.attributes.videoId }) } const path = '/api/v1/video-playlists/' + options.playlistId + '/videos' diff --git a/shared/extra-utils/videos/streaming-playlists.ts b/shared/extra-utils/videos/streaming-playlists.ts index 0324c739a..e8fd2f232 100644 --- a/shared/extra-utils/videos/streaming-playlists.ts +++ b/shared/extra-utils/videos/streaming-playlists.ts @@ -13,7 +13,7 @@ async function checkSegmentHash (options: { hlsPlaylist: VideoStreamingPlaylist }) { const { server, baseUrlPlaylist, baseUrlSegment, videoUUID, resolution, hlsPlaylist } = options - const command = server.streamingPlaylistsCommand + const command = server.streamingPlaylists const playlist = await command.get({ url: `${baseUrlPlaylist}/${videoUUID}/${resolution}.m3u8` }) @@ -43,7 +43,7 @@ async function checkLiveSegmentHash (options: { hlsPlaylist: VideoStreamingPlaylist }) { const { server, baseUrlSegment, videoUUID, segmentName, hlsPlaylist } = options - const command = server.streamingPlaylistsCommand + const command = server.streamingPlaylists const segmentBody = await command.getSegment({ url: `${baseUrlSegment}/${videoUUID}/${segmentName}` }) const shaBody = await command.getSegmentSha256({ url: hlsPlaylist.segmentsSha256Url }) @@ -58,7 +58,7 @@ async function checkResolutionsInMasterPlaylist (options: { }) { const { server, playlistUrl, resolutions } = options - const masterPlaylist = await server.streamingPlaylistsCommand.get({ url: playlistUrl }) + const masterPlaylist = await server.streamingPlaylists.get({ url: playlistUrl }) for (const resolution of resolutions) { const reg = new RegExp( diff --git a/shared/extra-utils/videos/videos-command.ts b/shared/extra-utils/videos/videos-command.ts index 574705474..5556cddf6 100644 --- a/shared/extra-utils/videos/videos-command.ts +++ b/shared/extra-utils/videos/videos-command.ts @@ -336,7 +336,7 @@ export class VideosCommand extends AbstractCommand { let defaultChannelId = 1 try { - const { videoChannels } = await this.server.usersCommand.getMyInfo({ token: options.token }) + const { videoChannels } = await this.server.users.getMyInfo({ token: options.token }) defaultChannelId = videoChannels[0].id } catch (e) { /* empty */ } diff --git a/shared/extra-utils/videos/videos.ts b/shared/extra-utils/videos/videos.ts index 19f0df8b8..86f49384d 100644 --- a/shared/extra-utils/videos/videos.ts +++ b/shared/extra-utils/videos/videos.ts @@ -27,7 +27,7 @@ async function checkVideoFilesWereRemoved ( ] ) { for (const directory of directories) { - const directoryPath = server.serversCommand.buildDirectory(directory) + const directoryPath = server.servers.buildDirectory(directory) const directoryExists = await pathExists(directoryPath) if (directoryExists === false) continue @@ -47,8 +47,8 @@ function checkUploadVideoParam ( mode: 'legacy' | 'resumable' = 'legacy' ) { return mode === 'legacy' - ? server.videosCommand.buildLegacyUpload({ token, attributes, expectedStatus }) - : server.videosCommand.buildResumeUpload({ token, attributes, expectedStatus }) + ? server.videos.buildLegacyUpload({ token, attributes, expectedStatus }) + : server.videos.buildResumeUpload({ token, attributes, expectedStatus }) } async function completeVideoCheck ( @@ -131,7 +131,7 @@ async function completeVideoCheck ( expect(video.originallyPublishedAt).to.be.null } - const videoDetails = await server.videosCommand.get({ id: video.uuid }) + const videoDetails = await server.videos.get({ id: video.uuid }) expect(videoDetails.files).to.have.lengthOf(attributes.files.length) expect(videoDetails.tags).to.deep.equal(attributes.tags) @@ -202,7 +202,7 @@ async function uploadRandomVideoOnServers ( additionalParams?: VideoEdit & { prefixName?: string } ) { const server = servers.find(s => s.serverNumber === serverNumber) - const res = await server.videosCommand.randomUpload({ wait: false, ...additionalParams }) + const res = await server.videos.randomUpload({ wait: false, ...additionalParams }) await waitJobs(servers) -- cgit v1.2.3 From 254d3579f5338f5fd775c17d15cdfc37078bcfb4 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 16 Jul 2021 09:47:51 +0200 Subject: Use an object to represent a server --- shared/extra-utils/videos/channels.ts | 4 ++-- shared/extra-utils/videos/live.ts | 6 +++--- shared/extra-utils/videos/streaming-playlists.ts | 8 ++++---- shared/extra-utils/videos/videos-command.ts | 4 ++-- shared/extra-utils/videos/videos.ts | 10 +++++----- 5 files changed, 16 insertions(+), 16 deletions(-) (limited to 'shared/extra-utils/videos') diff --git a/shared/extra-utils/videos/channels.ts b/shared/extra-utils/videos/channels.ts index 81e818094..756c47453 100644 --- a/shared/extra-utils/videos/channels.ts +++ b/shared/extra-utils/videos/channels.ts @@ -1,6 +1,6 @@ -import { ServerInfo } from '../server/servers' +import { PeerTubeServer } from '../server/server' -function setDefaultVideoChannel (servers: ServerInfo[]) { +function setDefaultVideoChannel (servers: PeerTubeServer[]) { const tasks: Promise[] = [] for (const server of servers) { diff --git a/shared/extra-utils/videos/live.ts b/shared/extra-utils/videos/live.ts index 353595811..502964b1a 100644 --- a/shared/extra-utils/videos/live.ts +++ b/shared/extra-utils/videos/live.ts @@ -5,7 +5,7 @@ import * as ffmpeg from 'fluent-ffmpeg' import { pathExists, readdir } from 'fs-extra' import { join } from 'path' import { buildAbsoluteFixturePath, wait } from '../miscs' -import { ServerInfo } from '../server/servers' +import { PeerTubeServer } from '../server/server' function sendRTMPStream (rtmpBaseUrl: string, streamKey: string, fixtureName = 'video_short.mp4') { const fixture = buildAbsoluteFixturePath(fixtureName) @@ -70,13 +70,13 @@ async function stopFfmpeg (command: ffmpeg.FfmpegCommand) { await wait(500) } -async function waitUntilLivePublishedOnAllServers (servers: ServerInfo[], videoId: string) { +async function waitUntilLivePublishedOnAllServers (servers: PeerTubeServer[], videoId: string) { for (const server of servers) { await server.live.waitUntilPublished({ videoId }) } } -async function checkLiveCleanup (server: ServerInfo, videoUUID: string, resolutions: number[] = []) { +async function checkLiveCleanup (server: PeerTubeServer, videoUUID: string, resolutions: number[] = []) { const basePath = server.servers.buildDirectory('streaming-playlists') const hlsPath = join(basePath, 'hls', videoUUID) diff --git a/shared/extra-utils/videos/streaming-playlists.ts b/shared/extra-utils/videos/streaming-playlists.ts index e8fd2f232..002ae08b2 100644 --- a/shared/extra-utils/videos/streaming-playlists.ts +++ b/shared/extra-utils/videos/streaming-playlists.ts @@ -2,10 +2,10 @@ import { expect } from 'chai' import { sha256 } from '@server/helpers/core-utils' import { HttpStatusCode } from '@shared/core-utils' import { VideoStreamingPlaylist } from '@shared/models' -import { ServerInfo } from '../server' +import { PeerTubeServer } from '../server' async function checkSegmentHash (options: { - server: ServerInfo + server: PeerTubeServer baseUrlPlaylist: string baseUrlSegment: string videoUUID: string @@ -36,7 +36,7 @@ async function checkSegmentHash (options: { } async function checkLiveSegmentHash (options: { - server: ServerInfo + server: PeerTubeServer baseUrlSegment: string videoUUID: string segmentName: string @@ -52,7 +52,7 @@ async function checkLiveSegmentHash (options: { } async function checkResolutionsInMasterPlaylist (options: { - server: ServerInfo + server: PeerTubeServer playlistUrl: string resolutions: number[] }) { diff --git a/shared/extra-utils/videos/videos-command.ts b/shared/extra-utils/videos/videos-command.ts index 5556cddf6..feef5a771 100644 --- a/shared/extra-utils/videos/videos-command.ts +++ b/shared/extra-utils/videos/videos-command.ts @@ -22,7 +22,7 @@ import { } from '@shared/models' import { buildAbsoluteFixturePath, wait } from '../miscs' import { unwrapBody } from '../requests' -import { ServerInfo, waitJobs } from '../server' +import { PeerTubeServer, waitJobs } from '../server' import { AbstractCommand, OverrideCommandOptions } from '../shared' export type VideoEdit = Partial> & { @@ -33,7 +33,7 @@ export type VideoEdit = Partial, expectedStatus = HttpStatusCode.OK_200, @@ -52,7 +52,7 @@ function checkUploadVideoParam ( } async function completeVideoCheck ( - server: ServerInfo, + server: PeerTubeServer, video: any, attributes: { name: string @@ -197,7 +197,7 @@ async function completeVideoCheck ( // serverNumber starts from 1 async function uploadRandomVideoOnServers ( - servers: ServerInfo[], + servers: PeerTubeServer[], serverNumber: number, additionalParams?: VideoEdit & { prefixName?: string } ) { -- cgit v1.2.3 From 59bbcced37005dd511daca9bd58ae2998cb931b1 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 16 Jul 2021 10:19:16 +0200 Subject: Centralize test URLs --- shared/extra-utils/videos/imports-command.ts | 38 ---------------------------- 1 file changed, 38 deletions(-) (limited to 'shared/extra-utils/videos') diff --git a/shared/extra-utils/videos/imports-command.ts b/shared/extra-utils/videos/imports-command.ts index 024aa363f..de8b65829 100644 --- a/shared/extra-utils/videos/imports-command.ts +++ b/shared/extra-utils/videos/imports-command.ts @@ -7,44 +7,6 @@ import { AbstractCommand, OverrideCommandOptions } from '../shared' export class ImportsCommand extends AbstractCommand { - static getYoutubeVideoUrl () { - return 'https://www.youtube.com/watch?v=msX3jv1XdvM' - } - - static getYoutubeHDRVideoUrl () { - /** - * The video is used to check format-selection correctness wrt. HDR, - * which brings its own set of oddities outside of a MediaSource. - * FIXME: refactor once HDR is supported at playback - * - * The video needs to have the following format_ids: - * (which you can check by using `youtube-dl -F`): - * - 303 (1080p webm vp9) - * - 299 (1080p mp4 avc1) - * - 335 (1080p webm vp9.2 HDR) - * - * 15 jan. 2021: TEST VIDEO NOT CURRENTLY PROVIDING - * - 400 (1080p mp4 av01) - * - 315 (2160p webm vp9 HDR) - * - 337 (2160p webm vp9.2 HDR) - * - 401 (2160p mp4 av01 HDR) - */ - return 'https://www.youtube.com/watch?v=qR5vOXbZsI4' - } - - static getMagnetURI () { - // eslint-disable-next-line max-len - return 'magnet:?xs=https%3A%2F%2Fpeertube2.cpy.re%2Fstatic%2Ftorrents%2Fb209ca00-c8bb-4b2b-b421-1ede169f3dbc-720.torrent&xt=urn:btih:0f498834733e8057ed5c6f2ee2b4efd8d84a76ee&dn=super+peertube2+video&tr=wss%3A%2F%2Fpeertube2.cpy.re%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fpeertube2.cpy.re%2Ftracker%2Fannounce&ws=https%3A%2F%2Fpeertube2.cpy.re%2Fstatic%2Fwebseed%2Fb209ca00-c8bb-4b2b-b421-1ede169f3dbc-720.mp4' - } - - static getBadVideoUrl () { - return 'https://download.cpy.re/peertube/bad_video.mp4' - } - - static getGoodVideoUrl () { - return 'https://download.cpy.re/peertube/good_video.mp4' - } - importVideo (options: OverrideCommandOptions & { attributes: VideoImportCreate & { torrentfile?: string } }) { -- cgit v1.2.3 From c0e8b12e7fd554ba4d2ceb0c4900804c6a4c63ea Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 16 Jul 2021 10:42:24 +0200 Subject: Refactor requests --- shared/extra-utils/videos/blacklist-command.ts | 2 +- shared/extra-utils/videos/captions-command.ts | 2 +- shared/extra-utils/videos/captions.ts | 2 +- .../extra-utils/videos/change-ownership-command.ts | 2 +- shared/extra-utils/videos/channels-command.ts | 2 +- shared/extra-utils/videos/comments-command.ts | 2 +- shared/extra-utils/videos/history-command.ts | 2 +- shared/extra-utils/videos/imports-command.ts | 2 +- shared/extra-utils/videos/live-command.ts | 2 +- shared/extra-utils/videos/playlists-command.ts | 2 +- shared/extra-utils/videos/services-command.ts | 2 +- .../videos/streaming-playlists-command.ts | 3 +- shared/extra-utils/videos/streaming-playlists.ts | 2 +- shared/extra-utils/videos/videos-command.ts | 36 ++++++++++++---------- shared/extra-utils/videos/videos.ts | 2 +- 15 files changed, 34 insertions(+), 31 deletions(-) (limited to 'shared/extra-utils/videos') diff --git a/shared/extra-utils/videos/blacklist-command.ts b/shared/extra-utils/videos/blacklist-command.ts index fdae6b469..9404d4c08 100644 --- a/shared/extra-utils/videos/blacklist-command.ts +++ b/shared/extra-utils/videos/blacklist-command.ts @@ -1,6 +1,6 @@ import { ResultList } from '@shared/models' -import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' +import { HttpStatusCode } from '@shared/models' import { VideoBlacklist, VideoBlacklistType } from '../../models/videos' import { AbstractCommand, OverrideCommandOptions } from '../shared' diff --git a/shared/extra-utils/videos/captions-command.ts b/shared/extra-utils/videos/captions-command.ts index ac3bde7a9..04dd32f84 100644 --- a/shared/extra-utils/videos/captions-command.ts +++ b/shared/extra-utils/videos/captions-command.ts @@ -1,4 +1,4 @@ -import { HttpStatusCode } from '@shared/core-utils' +import { HttpStatusCode } from '@shared/models' import { ResultList, VideoCaption } from '@shared/models' import { buildAbsoluteFixturePath } from '../miscs' import { AbstractCommand, OverrideCommandOptions } from '../shared' diff --git a/shared/extra-utils/videos/captions.ts b/shared/extra-utils/videos/captions.ts index 2246bd133..ff8a43366 100644 --- a/shared/extra-utils/videos/captions.ts +++ b/shared/extra-utils/videos/captions.ts @@ -1,6 +1,6 @@ import { expect } from 'chai' import * as request from 'supertest' -import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' +import { HttpStatusCode } from '@shared/models' async function testCaptionFile (url: string, captionPath: string, containsString: string) { const res = await request(url) diff --git a/shared/extra-utils/videos/change-ownership-command.ts b/shared/extra-utils/videos/change-ownership-command.ts index 03f77a95f..ef6f07536 100644 --- a/shared/extra-utils/videos/change-ownership-command.ts +++ b/shared/extra-utils/videos/change-ownership-command.ts @@ -1,6 +1,6 @@ import { ResultList, VideoChangeOwnership } from '@shared/models' -import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' +import { HttpStatusCode } from '@shared/models' import { AbstractCommand, OverrideCommandOptions } from '../shared' export class ChangeOwnershipCommand extends AbstractCommand { diff --git a/shared/extra-utils/videos/channels-command.ts b/shared/extra-utils/videos/channels-command.ts index a98c5cc93..e5393ff56 100644 --- a/shared/extra-utils/videos/channels-command.ts +++ b/shared/extra-utils/videos/channels-command.ts @@ -1,6 +1,6 @@ import { pick } from 'lodash' import { ResultList, VideoChannel, VideoChannelCreateResult } from '@shared/models' -import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' +import { HttpStatusCode } from '@shared/models' import { VideoChannelCreate } from '../../models/videos/channel/video-channel-create.model' import { VideoChannelUpdate } from '../../models/videos/channel/video-channel-update.model' import { unwrapBody } from '../requests' diff --git a/shared/extra-utils/videos/comments-command.ts b/shared/extra-utils/videos/comments-command.ts index b31f3e2dd..7368f3ea2 100644 --- a/shared/extra-utils/videos/comments-command.ts +++ b/shared/extra-utils/videos/comments-command.ts @@ -1,6 +1,6 @@ import { pick } from 'lodash' +import { HttpStatusCode } from '@shared/models' import { ResultList, VideoComment, VideoCommentThreads, VideoCommentThreadTree } from '@shared/models' -import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' import { unwrapBody } from '../requests' import { AbstractCommand, OverrideCommandOptions } from '../shared' diff --git a/shared/extra-utils/videos/history-command.ts b/shared/extra-utils/videos/history-command.ts index 8a144a312..41afc6bc6 100644 --- a/shared/extra-utils/videos/history-command.ts +++ b/shared/extra-utils/videos/history-command.ts @@ -1,5 +1,5 @@ +import { HttpStatusCode } from '@shared/models' import { ResultList, Video } from '@shared/models' -import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' import { AbstractCommand, OverrideCommandOptions } from '../shared' export class HistoryCommand extends AbstractCommand { diff --git a/shared/extra-utils/videos/imports-command.ts b/shared/extra-utils/videos/imports-command.ts index de8b65829..d30f9745b 100644 --- a/shared/extra-utils/videos/imports-command.ts +++ b/shared/extra-utils/videos/imports-command.ts @@ -1,6 +1,6 @@ +import { HttpStatusCode } from '@shared/models' import { ResultList } from '@shared/models' -import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' import { VideoImport, VideoImportCreate } from '../../models/videos' import { unwrapBody } from '../requests' import { AbstractCommand, OverrideCommandOptions } from '../shared' diff --git a/shared/extra-utils/videos/live-command.ts b/shared/extra-utils/videos/live-command.ts index fd66c9924..9dfe3087e 100644 --- a/shared/extra-utils/videos/live-command.ts +++ b/shared/extra-utils/videos/live-command.ts @@ -3,8 +3,8 @@ import { readdir } from 'fs-extra' import { omit } from 'lodash' import { join } from 'path' +import { HttpStatusCode } from '@shared/models' import { LiveVideo, LiveVideoCreate, LiveVideoUpdate, VideoCreateResult, VideoDetails, VideoState } from '@shared/models' -import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' import { wait } from '../miscs' import { unwrapBody } from '../requests' import { AbstractCommand, OverrideCommandOptions } from '../shared' diff --git a/shared/extra-utils/videos/playlists-command.ts b/shared/extra-utils/videos/playlists-command.ts index cbfc7e10f..40162c30d 100644 --- a/shared/extra-utils/videos/playlists-command.ts +++ b/shared/extra-utils/videos/playlists-command.ts @@ -1,5 +1,5 @@ import { omit, pick } from 'lodash' -import { HttpStatusCode } from '@shared/core-utils' +import { HttpStatusCode } from '@shared/models' import { BooleanBothQuery, ResultList, diff --git a/shared/extra-utils/videos/services-command.ts b/shared/extra-utils/videos/services-command.ts index 313b7878c..06760df42 100644 --- a/shared/extra-utils/videos/services-command.ts +++ b/shared/extra-utils/videos/services-command.ts @@ -1,4 +1,4 @@ -import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' +import { HttpStatusCode } from '@shared/models' import { AbstractCommand, OverrideCommandOptions } from '../shared' export class ServicesCommand extends AbstractCommand { diff --git a/shared/extra-utils/videos/streaming-playlists-command.ts b/shared/extra-utils/videos/streaming-playlists-command.ts index fab3eb556..9662685da 100644 --- a/shared/extra-utils/videos/streaming-playlists-command.ts +++ b/shared/extra-utils/videos/streaming-playlists-command.ts @@ -1,5 +1,4 @@ - -import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' +import { HttpStatusCode } from '@shared/models' import { unwrapBody, unwrapText } from '../requests' import { AbstractCommand, OverrideCommandOptions } from '../shared' diff --git a/shared/extra-utils/videos/streaming-playlists.ts b/shared/extra-utils/videos/streaming-playlists.ts index 002ae08b2..007d3d98d 100644 --- a/shared/extra-utils/videos/streaming-playlists.ts +++ b/shared/extra-utils/videos/streaming-playlists.ts @@ -1,6 +1,6 @@ import { expect } from 'chai' import { sha256 } from '@server/helpers/core-utils' -import { HttpStatusCode } from '@shared/core-utils' +import { HttpStatusCode } from '@shared/models' import { VideoStreamingPlaylist } from '@shared/models' import { PeerTubeServer } from '../server' diff --git a/shared/extra-utils/videos/videos-command.ts b/shared/extra-utils/videos/videos-command.ts index feef5a771..f46d386f4 100644 --- a/shared/extra-utils/videos/videos-command.ts +++ b/shared/extra-utils/videos/videos-command.ts @@ -7,7 +7,7 @@ import { omit, pick } from 'lodash' import validator from 'validator' import { buildUUID } from '@server/helpers/uuid' import { loadLanguages } from '@server/initializers/constants' -import { HttpStatusCode } from '@shared/core-utils' +import { HttpStatusCode } from '@shared/models' import { ResultList, UserVideoRateType, @@ -234,10 +234,10 @@ export class VideosCommand extends AbstractCommand { } listByAccount (options: OverrideCommandOptions & VideosWithSearchCommonQuery & { - accountName: string + handle: string }) { - const { accountName, search } = options - const path = '/api/v1/accounts/' + accountName + '/videos' + const { handle, search } = options + const path = '/api/v1/accounts/' + handle + '/videos' return this.getRequestBody>({ ...options, @@ -250,10 +250,10 @@ export class VideosCommand extends AbstractCommand { } listByChannel (options: OverrideCommandOptions & VideosWithSearchCommonQuery & { - videoChannelName: string + handle: string }) { - const { videoChannelName } = options - const path = '/api/v1/video-channels/' + videoChannelName + '/videos' + const { handle } = options + const path = '/api/v1/video-channels/' + handle + '/videos' return this.getRequestBody>({ ...options, @@ -309,13 +309,13 @@ export class VideosCommand extends AbstractCommand { }) { const path = '/api/v1/videos/' + options.id - return this.deleteRequest({ + return unwrapBody(this.deleteRequest({ ...options, path, implicitToken: true, defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 - }) + })) } async removeAll () { @@ -396,7 +396,7 @@ export class VideosCommand extends AbstractCommand { async buildResumeUpload (options: OverrideCommandOptions & { attributes: VideoEdit - }) { + }): Promise { const { attributes, expectedStatus } = options let size = 0 @@ -414,7 +414,8 @@ export class VideosCommand extends AbstractCommand { } } - const initializeSessionRes = await this.prepareResumableUpload({ ...options, attributes, size, mimetype }) + // Do not check status automatically, we'll check it manually + const initializeSessionRes = await this.prepareResumableUpload({ ...options, expectedStatus: null, attributes, size, mimetype }) const initStatus = initializeSessionRes.status if (videoFilePath && initStatus === HttpStatusCode.CREATED_201) { @@ -425,7 +426,7 @@ export class VideosCommand extends AbstractCommand { const result = await this.sendResumableChunks({ ...options, pathUploadId, videoFilePath, size }) - return result.body.video + return result.body?.video || result.body as any } const expectedInitStatus = expectedStatus === HttpStatusCode.OK_200 @@ -434,7 +435,7 @@ export class VideosCommand extends AbstractCommand { expect(initStatus).to.equal(expectedInitStatus) - return initializeSessionRes.body.video as VideoCreateResult + return initializeSessionRes.body.video || initializeSessionRes.body } async prepareResumableUpload (options: OverrideCommandOptions & { @@ -455,7 +456,10 @@ export class VideosCommand extends AbstractCommand { 'X-Upload-Content-Length': size.toString() }, fields: { filename: attributes.fixture, ...this.buildUploadFields(options.attributes) }, + // Fixture will be sent later + attaches: this.buildUploadAttaches(omit(options.attributes, 'fixture')), implicitToken: true, + defaultExpectedStatus: null }) } @@ -539,10 +543,10 @@ export class VideosCommand extends AbstractCommand { const attributes = { name, additionalParams } - if (wait) await waitJobs([ this.server ]) - const result = await this.upload({ ...options, attributes }) + if (wait) await waitJobs([ this.server ]) + return { ...result, name } } @@ -566,7 +570,7 @@ export class VideosCommand extends AbstractCommand { } private buildUploadFields (attributes: VideoEdit) { - return omit(attributes, [ 'thumbnailfile', 'previewfile' ]) + return omit(attributes, [ 'fixture', 'thumbnailfile', 'previewfile' ]) } private buildUploadAttaches (attributes: VideoEdit) { diff --git a/shared/extra-utils/videos/videos.ts b/shared/extra-utils/videos/videos.ts index b41533808..a96073c56 100644 --- a/shared/extra-utils/videos/videos.ts +++ b/shared/extra-utils/videos/videos.ts @@ -4,7 +4,7 @@ import { expect } from 'chai' import { pathExists, readdir } from 'fs-extra' import { join } from 'path' import { getLowercaseExtension } from '@server/helpers/core-utils' -import { HttpStatusCode } from '@shared/core-utils' +import { HttpStatusCode } from '@shared/models' import { VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../server/initializers/constants' import { dateIsValid, testImage, webtorrentAdd } from '../miscs' import { makeRawRequest } from '../requests/requests' -- cgit v1.2.3 From 4c7e60bc17ee5830399bac4aa273356903421b4c Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 16 Jul 2021 14:27:30 +0200 Subject: Reorganize imports --- shared/extra-utils/videos/blacklist-command.ts | 3 +-- shared/extra-utils/videos/captions-command.ts | 3 +-- shared/extra-utils/videos/change-ownership-command.ts | 3 +-- shared/extra-utils/videos/channels-command.ts | 3 +-- shared/extra-utils/videos/comments-command.ts | 3 +-- shared/extra-utils/videos/history-command.ts | 3 +-- shared/extra-utils/videos/imports-command.ts | 3 +-- shared/extra-utils/videos/live-command.ts | 3 +-- shared/extra-utils/videos/playlists-command.ts | 2 +- shared/extra-utils/videos/streaming-playlists.ts | 3 +-- shared/extra-utils/videos/videos-command.ts | 15 ++++++++------- shared/extra-utils/videos/videos.ts | 2 +- 12 files changed, 19 insertions(+), 27 deletions(-) (limited to 'shared/extra-utils/videos') diff --git a/shared/extra-utils/videos/blacklist-command.ts b/shared/extra-utils/videos/blacklist-command.ts index 9404d4c08..3a2ef89ba 100644 --- a/shared/extra-utils/videos/blacklist-command.ts +++ b/shared/extra-utils/videos/blacklist-command.ts @@ -1,6 +1,5 @@ -import { ResultList } from '@shared/models' -import { HttpStatusCode } from '@shared/models' +import { HttpStatusCode, ResultList } from '@shared/models' import { VideoBlacklist, VideoBlacklistType } from '../../models/videos' import { AbstractCommand, OverrideCommandOptions } from '../shared' diff --git a/shared/extra-utils/videos/captions-command.ts b/shared/extra-utils/videos/captions-command.ts index 04dd32f84..a0608e1a6 100644 --- a/shared/extra-utils/videos/captions-command.ts +++ b/shared/extra-utils/videos/captions-command.ts @@ -1,5 +1,4 @@ -import { HttpStatusCode } from '@shared/models' -import { ResultList, VideoCaption } from '@shared/models' +import { HttpStatusCode, ResultList, VideoCaption } from '@shared/models' import { buildAbsoluteFixturePath } from '../miscs' import { AbstractCommand, OverrideCommandOptions } from '../shared' diff --git a/shared/extra-utils/videos/change-ownership-command.ts b/shared/extra-utils/videos/change-ownership-command.ts index ef6f07536..ad4c726ef 100644 --- a/shared/extra-utils/videos/change-ownership-command.ts +++ b/shared/extra-utils/videos/change-ownership-command.ts @@ -1,6 +1,5 @@ -import { ResultList, VideoChangeOwnership } from '@shared/models' -import { HttpStatusCode } from '@shared/models' +import { HttpStatusCode, ResultList, VideoChangeOwnership } from '@shared/models' import { AbstractCommand, OverrideCommandOptions } from '../shared' export class ChangeOwnershipCommand extends AbstractCommand { diff --git a/shared/extra-utils/videos/channels-command.ts b/shared/extra-utils/videos/channels-command.ts index e5393ff56..f8eb3f885 100644 --- a/shared/extra-utils/videos/channels-command.ts +++ b/shared/extra-utils/videos/channels-command.ts @@ -1,6 +1,5 @@ import { pick } from 'lodash' -import { ResultList, VideoChannel, VideoChannelCreateResult } from '@shared/models' -import { HttpStatusCode } from '@shared/models' +import { HttpStatusCode, ResultList, VideoChannel, VideoChannelCreateResult } from '@shared/models' import { VideoChannelCreate } from '../../models/videos/channel/video-channel-create.model' import { VideoChannelUpdate } from '../../models/videos/channel/video-channel-update.model' import { unwrapBody } from '../requests' diff --git a/shared/extra-utils/videos/comments-command.ts b/shared/extra-utils/videos/comments-command.ts index 7368f3ea2..dd14e4b64 100644 --- a/shared/extra-utils/videos/comments-command.ts +++ b/shared/extra-utils/videos/comments-command.ts @@ -1,6 +1,5 @@ import { pick } from 'lodash' -import { HttpStatusCode } from '@shared/models' -import { ResultList, VideoComment, VideoCommentThreads, VideoCommentThreadTree } from '@shared/models' +import { HttpStatusCode, ResultList, VideoComment, VideoCommentThreads, VideoCommentThreadTree } from '@shared/models' import { unwrapBody } from '../requests' import { AbstractCommand, OverrideCommandOptions } from '../shared' diff --git a/shared/extra-utils/videos/history-command.ts b/shared/extra-utils/videos/history-command.ts index 41afc6bc6..13b7150c1 100644 --- a/shared/extra-utils/videos/history-command.ts +++ b/shared/extra-utils/videos/history-command.ts @@ -1,5 +1,4 @@ -import { HttpStatusCode } from '@shared/models' -import { ResultList, Video } from '@shared/models' +import { HttpStatusCode, ResultList, Video } from '@shared/models' import { AbstractCommand, OverrideCommandOptions } from '../shared' export class HistoryCommand extends AbstractCommand { diff --git a/shared/extra-utils/videos/imports-command.ts b/shared/extra-utils/videos/imports-command.ts index d30f9745b..e4944694d 100644 --- a/shared/extra-utils/videos/imports-command.ts +++ b/shared/extra-utils/videos/imports-command.ts @@ -1,6 +1,5 @@ -import { HttpStatusCode } from '@shared/models' -import { ResultList } from '@shared/models' +import { HttpStatusCode, ResultList } from '@shared/models' import { VideoImport, VideoImportCreate } from '../../models/videos' import { unwrapBody } from '../requests' import { AbstractCommand, OverrideCommandOptions } from '../shared' diff --git a/shared/extra-utils/videos/live-command.ts b/shared/extra-utils/videos/live-command.ts index 9dfe3087e..bf9486a05 100644 --- a/shared/extra-utils/videos/live-command.ts +++ b/shared/extra-utils/videos/live-command.ts @@ -3,8 +3,7 @@ import { readdir } from 'fs-extra' import { omit } from 'lodash' import { join } from 'path' -import { HttpStatusCode } from '@shared/models' -import { LiveVideo, LiveVideoCreate, LiveVideoUpdate, VideoCreateResult, VideoDetails, VideoState } from '@shared/models' +import { HttpStatusCode, LiveVideo, LiveVideoCreate, LiveVideoUpdate, VideoCreateResult, VideoDetails, VideoState } from '@shared/models' import { wait } from '../miscs' import { unwrapBody } from '../requests' import { AbstractCommand, OverrideCommandOptions } from '../shared' diff --git a/shared/extra-utils/videos/playlists-command.ts b/shared/extra-utils/videos/playlists-command.ts index 40162c30d..6f329800e 100644 --- a/shared/extra-utils/videos/playlists-command.ts +++ b/shared/extra-utils/videos/playlists-command.ts @@ -1,7 +1,7 @@ import { omit, pick } from 'lodash' -import { HttpStatusCode } from '@shared/models' import { BooleanBothQuery, + HttpStatusCode, ResultList, VideoExistInPlaylist, VideoPlaylist, diff --git a/shared/extra-utils/videos/streaming-playlists.ts b/shared/extra-utils/videos/streaming-playlists.ts index 007d3d98d..1ae3fefc1 100644 --- a/shared/extra-utils/videos/streaming-playlists.ts +++ b/shared/extra-utils/videos/streaming-playlists.ts @@ -1,7 +1,6 @@ import { expect } from 'chai' import { sha256 } from '@server/helpers/core-utils' -import { HttpStatusCode } from '@shared/models' -import { VideoStreamingPlaylist } from '@shared/models' +import { HttpStatusCode, VideoStreamingPlaylist } from '@shared/models' import { PeerTubeServer } from '../server' async function checkSegmentHash (options: { diff --git a/shared/extra-utils/videos/videos-command.ts b/shared/extra-utils/videos/videos-command.ts index f46d386f4..40cc4dc28 100644 --- a/shared/extra-utils/videos/videos-command.ts +++ b/shared/extra-utils/videos/videos-command.ts @@ -7,8 +7,8 @@ import { omit, pick } from 'lodash' import validator from 'validator' import { buildUUID } from '@server/helpers/uuid' import { loadLanguages } from '@server/initializers/constants' -import { HttpStatusCode } from '@shared/models' import { + HttpStatusCode, ResultList, UserVideoRateType, Video, @@ -332,7 +332,7 @@ export class VideosCommand extends AbstractCommand { attributes?: VideoEdit mode?: 'legacy' | 'resumable' // default legacy } = {}) { - const { mode = 'legacy', expectedStatus } = options + const { mode = 'legacy' } = options let defaultChannelId = 1 try { @@ -360,22 +360,23 @@ export class VideosCommand extends AbstractCommand { ...options.attributes } - const res = mode === 'legacy' + const created = mode === 'legacy' ? await this.buildLegacyUpload({ ...options, attributes }) : await this.buildResumeUpload({ ...options, attributes }) // Wait torrent generation + const expectedStatus = this.buildExpectedStatus({ ...options, defaultExpectedStatus: HttpStatusCode.OK_200 }) if (expectedStatus === HttpStatusCode.OK_200) { let video: VideoDetails do { - video = await this.getWithToken({ ...options, id: video.uuid }) + video = await this.getWithToken({ ...options, id: created.uuid }) await wait(50) } while (!video.files[0].torrentUrl) } - return res + return created } async buildLegacyUpload (options: OverrideCommandOptions & { @@ -535,13 +536,13 @@ export class VideosCommand extends AbstractCommand { async randomUpload (options: OverrideCommandOptions & { wait?: boolean // default true - additionalParams?: VideoEdit & { prefixName: string } + additionalParams?: VideoEdit & { prefixName?: string } } = {}) { const { wait = true, additionalParams } = options const prefixName = additionalParams?.prefixName || '' const name = prefixName + buildUUID() - const attributes = { name, additionalParams } + const attributes = { name, ...additionalParams } const result = await this.upload({ ...options, attributes }) diff --git a/shared/extra-utils/videos/videos.ts b/shared/extra-utils/videos/videos.ts index a96073c56..9a9bfb3cf 100644 --- a/shared/extra-utils/videos/videos.ts +++ b/shared/extra-utils/videos/videos.ts @@ -202,7 +202,7 @@ async function uploadRandomVideoOnServers ( additionalParams?: VideoEdit & { prefixName?: string } ) { const server = servers.find(s => s.serverNumber === serverNumber) - const res = await server.videos.randomUpload({ wait: false, ...additionalParams }) + const res = await server.videos.randomUpload({ wait: false, additionalParams }) await waitJobs(servers) -- cgit v1.2.3 From 4d029ef8ec3d5274eeaa3ee6d808eb7035e7faef Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 20 Jul 2021 14:15:15 +0200 Subject: Add ability for instances to follow any actor --- shared/extra-utils/videos/comments-command.ts | 21 +++++++++++++++++++++ shared/extra-utils/videos/videos-command.ts | 10 ++++++++++ 2 files changed, 31 insertions(+) (limited to 'shared/extra-utils/videos') diff --git a/shared/extra-utils/videos/comments-command.ts b/shared/extra-utils/videos/comments-command.ts index dd14e4b64..5034c57ad 100644 --- a/shared/extra-utils/videos/comments-command.ts +++ b/shared/extra-utils/videos/comments-command.ts @@ -5,6 +5,10 @@ import { AbstractCommand, OverrideCommandOptions } from '../shared' export class CommentsCommand extends AbstractCommand { + private lastVideoId: number | string + private lastThreadId: number + private lastReplyId: number + listForAdmin (options: OverrideCommandOptions & { start?: number count?: number @@ -80,6 +84,9 @@ export class CommentsCommand extends AbstractCommand { defaultExpectedStatus: HttpStatusCode.OK_200 })) + this.lastThreadId = body.comment.id + this.lastVideoId = videoId + return body.comment } @@ -100,9 +107,23 @@ export class CommentsCommand extends AbstractCommand { defaultExpectedStatus: HttpStatusCode.OK_200 })) + this.lastReplyId = body.comment.id + return body.comment } + async addReplyToLastReply (options: OverrideCommandOptions & { + text: string + }) { + return this.addReply({ ...options, videoId: this.lastVideoId, toCommentId: this.lastReplyId }) + } + + async addReplyToLastThread (options: OverrideCommandOptions & { + text: string + }) { + return this.addReply({ ...options, videoId: this.lastVideoId, toCommentId: this.lastThreadId }) + } + async findCommentId (options: OverrideCommandOptions & { videoId: number | string text: string diff --git a/shared/extra-utils/videos/videos-command.ts b/shared/extra-utils/videos/videos-command.ts index 40cc4dc28..98465e8f6 100644 --- a/shared/extra-utils/videos/videos-command.ts +++ b/shared/extra-utils/videos/videos-command.ts @@ -267,6 +267,16 @@ export class VideosCommand extends AbstractCommand { // --------------------------------------------------------------------------- + async find (options: OverrideCommandOptions & { + name: string + }) { + const { data } = await this.list(options) + + return data.find(v => v.name === options.name) + } + + // --------------------------------------------------------------------------- + update (options: OverrideCommandOptions & { id: number | string attributes?: VideoEdit -- cgit v1.2.3 From c63830f15403ac4e750829f27d8bbbdc9a59282c Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 21 Jul 2021 13:58:35 +0200 Subject: Rename captions commands --- shared/extra-utils/videos/captions-command.ts | 6 +++--- shared/extra-utils/videos/comments-command.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'shared/extra-utils/videos') diff --git a/shared/extra-utils/videos/captions-command.ts b/shared/extra-utils/videos/captions-command.ts index a0608e1a6..a65ea99e3 100644 --- a/shared/extra-utils/videos/captions-command.ts +++ b/shared/extra-utils/videos/captions-command.ts @@ -4,7 +4,7 @@ import { AbstractCommand, OverrideCommandOptions } from '../shared' export class CaptionsCommand extends AbstractCommand { - createVideoCaption (options: OverrideCommandOptions & { + add (options: OverrideCommandOptions & { videoId: string | number language: string fixture: string @@ -32,7 +32,7 @@ export class CaptionsCommand extends AbstractCommand { }) } - listVideoCaptions (options: OverrideCommandOptions & { + list (options: OverrideCommandOptions & { videoId: string | number }) { const { videoId } = options @@ -47,7 +47,7 @@ export class CaptionsCommand extends AbstractCommand { }) } - deleteVideoCaption (options: OverrideCommandOptions & { + delete (options: OverrideCommandOptions & { videoId: string | number language: string }) { diff --git a/shared/extra-utils/videos/comments-command.ts b/shared/extra-utils/videos/comments-command.ts index 5034c57ad..f0d163a07 100644 --- a/shared/extra-utils/videos/comments-command.ts +++ b/shared/extra-utils/videos/comments-command.ts @@ -84,7 +84,7 @@ export class CommentsCommand extends AbstractCommand { defaultExpectedStatus: HttpStatusCode.OK_200 })) - this.lastThreadId = body.comment.id + this.lastThreadId = body.comment?.id this.lastVideoId = videoId return body.comment @@ -107,7 +107,7 @@ export class CommentsCommand extends AbstractCommand { defaultExpectedStatus: HttpStatusCode.OK_200 })) - this.lastReplyId = body.comment.id + this.lastReplyId = body.comment?.id return body.comment } -- cgit v1.2.3