- ? 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<GotResponse>((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<any>((res, rej) => {
- const torrentName = videoUUID + '-' + resolution + '.torrent'
- const torrentPath = buildServerDirectory(server, join('torrents', torrentName))
-
- readFile(torrentPath, (err, data) => {
- if (err) return rej(err)
-
- return res(parseTorrent(data))
- })
- })