Browse Source

Add ability to override CLI import attributes

Chocobozzz 4 years ago
parent
commit
1205823fec
4 changed files with 151 additions and 72 deletions
  1. 51 13
      server/tests/cli/peertube.ts
  2. 66 3
      server/tools/cli.ts
  3. 17 21
      server/tools/peertube-import-videos.ts
  4. 17 35
      server/tools/peertube-upload.ts

+ 51 - 13
server/tests/cli/peertube.ts

@@ -10,18 +10,20 @@ import {
   execCLI,
   flushAndRunServer,
   getEnvCli,
-  getMyUserInformation,
+  getVideo,
   getVideosList,
+  getVideosListWithToken, removeVideo,
   ServerInfo,
   setAccessTokensToServers,
-  userLogin, waitJobs
+  userLogin,
+  waitJobs
 } from '../../../shared/extra-utils'
-import { User, Video } from '../../../shared'
+import { Video, VideoDetails } from '../../../shared'
 import { getYoutubeVideoUrl } from '../../../shared/extra-utils/videos/video-imports'
 
 describe('Test CLI wrapper', function () {
   let server: ServerInfo
-  let channelId: number
+  let userAccessToken: string
 
   const cmd = 'node ./dist/server/tools/peertube.js'
 
@@ -33,11 +35,11 @@ describe('Test CLI wrapper', function () {
 
     await createUser({ url: server.url, accessToken: server.accessToken, username: 'user_1', password: 'super_password' })
 
-    const userAccessToken = await userLogin(server, { username: 'user_1', password: 'super_password' })
+    userAccessToken = await userLogin(server, { username: 'user_1', password: 'super_password' })
 
     {
-      const res = await addVideoChannel(server.url, userAccessToken, { name: 'user_channel', displayName: 'User channel' })
-      channelId = res.body.videoChannel.id
+      const args = { name: 'user_channel', displayName: 'User channel', support: 'super support text' }
+      await addVideoChannel(server.url, userAccessToken, args)
     }
   })
 
@@ -82,7 +84,7 @@ describe('Test CLI wrapper', function () {
 
     const fixture = buildAbsoluteFixturePath('60fps_720p_small.mp4')
 
-    const params = `-f ${fixture} --video-name 'test upload' --channel-id ${channelId}`
+    const params = `-f ${fixture} --video-name 'test upload' --channel-name user_channel --support 'support_text'`
 
     await execCLI(`${env} ${cmd} upload ${params}`)
   })
@@ -93,8 +95,12 @@ describe('Test CLI wrapper', function () {
     expect(res.body.total).to.equal(1)
 
     const videos: Video[] = res.body.data
-    expect(videos[0].name).to.equal('test upload')
-    expect(videos[0].channel.name).to.equal('user_channel')
+
+    const video: VideoDetails = (await getVideo(server.url, videos[0].uuid)).body
+
+    expect(video.name).to.equal('test upload')
+    expect(video.support).to.equal('support_text')
+    expect(video.channel.name).to.equal('user_channel')
   })
 
   it('Should import a video', async function () {
@@ -102,7 +108,7 @@ describe('Test CLI wrapper', function () {
 
     const env = getEnvCli(server)
 
-    const params = `--target-url ${getYoutubeVideoUrl()} --channel-id ${channelId}`
+    const params = `--target-url ${getYoutubeVideoUrl()} --channel-name user_channel`
 
     await execCLI(`${env} ${cmd} import ${params}`)
   })
@@ -118,9 +124,41 @@ describe('Test CLI wrapper', function () {
 
     const videos: Video[] = res.body.data
     const video = videos.find(v => v.name === 'small video - youtube')
-
     expect(video).to.not.be.undefined
-    expect(video.channel.name).to.equal('user_channel')
+
+    const videoDetails: VideoDetails = (await getVideo(server.url, video.id)).body
+    expect(videoDetails.channel.name).to.equal('user_channel')
+    expect(videoDetails.support).to.equal('super support text')
+    expect(videoDetails.nsfw).to.be.false
+
+    // So we can reimport it
+    await removeVideo(server.url, userAccessToken, video.id)
+  })
+
+  it('Should import and override some imported attributes', async function () {
+    this.timeout(60000)
+
+    const env = getEnvCli(server)
+
+    const params = `--target-url ${getYoutubeVideoUrl()} --channel-name user_channel --video-name toto --nsfw --support support`
+
+    await execCLI(`${env} ${cmd} import ${params}`)
+
+    await waitJobs([ server ])
+
+    {
+      const res = await getVideosList(server.url)
+      expect(res.body.total).to.equal(2)
+
+      const videos: Video[] = res.body.data
+      const video = videos.find(v => v.name === 'toto')
+      expect(video).to.not.be.undefined
+
+      const videoDetails: VideoDetails = (await getVideo(server.url, video.id)).body
+      expect(videoDetails.channel.name).to.equal('user_channel')
+      expect(videoDetails.support).to.equal('support')
+      expect(videoDetails.nsfw).to.be.true
+    }
   })
 
   it('Should remove the auth user', async function () {

+ 66 - 3
server/tools/cli.ts

@@ -1,7 +1,9 @@
 import { Netrc } from 'netrc-parser'
-import { isTestInstance, getAppNumber } from '../helpers/core-utils'
+import { getAppNumber, isTestInstance } from '../helpers/core-utils'
 import { join } from 'path'
-import { root } from '../../shared/extra-utils'
+import { getVideoChannel, root } from '../../shared/extra-utils'
+import { Command } from 'commander'
+import { VideoChannel, VideoPrivacy } from '../../shared/models/videos'
 
 let configName = 'PeerTube/CLI'
 if (isTestInstance()) configName += `-${getAppNumber()}`
@@ -94,6 +96,64 @@ function getRemoteObjectOrDie (program: any, settings: Settings, netrc: Netrc) {
   }
 }
 
+function buildCommonVideoOptions (command: Command) {
+  function list (val) {
+    return val.split(',')
+  }
+
+  return command
+    .option('-n, --video-name <name>', 'Video name')
+    .option('-c, --category <category_number>', 'Category number')
+    .option('-l, --licence <licence_number>', 'Licence number')
+    .option('-L, --language <language_code>', 'Language ISO 639 code (fr or en...)')
+    .option('-t, --tags <tags>', 'Video tags', list)
+    .option('-N, --nsfw', 'Video is Not Safe For Work')
+    .option('-d, --video-description <description>', 'Video description')
+    .option('-P, --privacy <privacy_number>', 'Privacy')
+    .option('-C, --channel-name <channel_name>', 'Channel name')
+    .option('-m, --comments-enabled', 'Enable comments')
+    .option('-s, --support <support>', 'Video support text')
+    .option('-w, --wait-transcoding', 'Wait transcoding before publishing the video')
+}
+
+async function buildVideoAttributesFromCommander (url: string, command: Command, defaultAttributes: any) {
+  const booleanAttributes: { [id: string]: boolean } = {}
+
+  for (const key of [ 'nsfw', 'commentsEnabled', 'downloadEnabled', 'waitTranscoding' ]) {
+    if (command[ key ] !== undefined) {
+      booleanAttributes[key] = command[ key ]
+    } else if (defaultAttributes[key] !== undefined) {
+      booleanAttributes[key] = defaultAttributes[key]
+    } else {
+      booleanAttributes[key] = false
+    }
+  }
+
+  const videoAttributes = {
+    name: command[ 'videoName' ] || defaultAttributes.name,
+    category: command[ 'category' ] || defaultAttributes.category || undefined,
+    licence: command[ 'licence' ] || defaultAttributes.licence || undefined,
+    language: command[ 'language' ] || defaultAttributes.language || undefined,
+    privacy: command[ 'privacy' ] || defaultAttributes.privacy || VideoPrivacy.PUBLIC,
+    support: command[ 'support' ] || defaultAttributes.support || undefined
+  }
+
+  Object.assign(videoAttributes, booleanAttributes)
+
+  if (command[ 'channelName' ]) {
+    const res = await getVideoChannel(url, command['channelName'])
+    const videoChannel: VideoChannel = res.body
+
+    Object.assign(videoAttributes, { channelId: videoChannel.id })
+
+    if (!videoAttributes.support && videoChannel.support) {
+      Object.assign(videoAttributes, { support: videoChannel.support })
+    }
+  }
+
+  return videoAttributes
+}
+
 // ---------------------------------------------------------------------------
 
 export {
@@ -103,5 +163,8 @@ export {
   getNetrc,
   getRemoteObjectOrDie,
   writeSettings,
-  deleteSettings
+  deleteSettings,
+
+  buildCommonVideoOptions,
+  buildVideoAttributesFromCommander
 }

+ 17 - 21
server/tools/peertube-import-videos.ts

@@ -3,7 +3,6 @@ require('tls').DEFAULT_ECDH_CURVE = 'auto'
 
 import * as program from 'commander'
 import { join } from 'path'
-import { VideoPrivacy } from '../../shared/models/videos'
 import { doRequestAndSaveToFile } from '../helpers/requests'
 import { CONSTRAINTS_FIELDS } from '../initializers/constants'
 import { getClient, getVideoCategories, login, searchVideoWithSort, uploadVideo } from '../../shared/extra-utils/index'
@@ -12,7 +11,7 @@ import * as prompt from 'prompt'
 import { remove } from 'fs-extra'
 import { sha256 } from '../helpers/core-utils'
 import { buildOriginallyPublishedAt, safeGetYoutubeDL } from '../helpers/youtube-dl'
-import { getNetrc, getRemoteObjectOrDie, getSettings } from './cli'
+import { buildCommonVideoOptions, buildVideoAttributesFromCommander, getNetrc, getRemoteObjectOrDie, getSettings } from './cli'
 
 type UserInfo = {
   username: string
@@ -24,14 +23,16 @@ const processOptions = {
   maxBuffer: Infinity
 }
 
-program
+let command = program
   .name('import-videos')
+
+command = buildCommonVideoOptions(command)
+
+command
   .option('-u, --url <url>', 'Server url')
   .option('-U, --username <username>', 'Username')
   .option('-p, --password <token>', 'Password')
   .option('-t, --target-url <targetUrl>', 'Video target URL')
-  .option('-C, --channel-id <channel_id>', 'Channel ID')
-  .option('-l, --language <languageCode>', 'Language ISO 639 code (fr or en...)')
   .option('-v, --verbose', 'Verbose mode')
   .parse(process.argv)
 
@@ -179,7 +180,7 @@ async function uploadVideoOnPeerTube (parameters: {
 
   const originallyPublishedAt = buildOriginallyPublishedAt(videoInfo)
 
-  const videoAttributes = {
+  const defaultAttributes = {
     name: truncate(videoInfo.title, {
       'length': CONSTRAINTS_FIELDS.VIDEOS.NAME.max,
       'separator': /,? +/,
@@ -187,24 +188,19 @@ async function uploadVideoOnPeerTube (parameters: {
     }),
     category,
     licence,
-    language: program[ 'language' ],
     nsfw: isNSFW(videoInfo),
-    waitTranscoding: true,
-    commentsEnabled: true,
-    downloadEnabled: true,
-    description: videoInfo.description || undefined,
-    support: undefined,
-    tags,
-    privacy: VideoPrivacy.PUBLIC,
-    fixture: videoPath,
-    thumbnailfile,
-    previewfile: thumbnailfile,
-    originallyPublishedAt: originallyPublishedAt ? originallyPublishedAt.toISOString() : null
+    description: videoInfo.description,
+    tags
   }
 
-  if (program[ 'channelId' ]) {
-    Object.assign(videoAttributes, { channelId: program['channelId'] })
-  }
+  const videoAttributes = await buildVideoAttributesFromCommander(url, program, defaultAttributes)
+
+  Object.assign(videoAttributes, {
+    originallyPublishedAt: originallyPublishedAt ? originallyPublishedAt.toISOString() : null,
+    thumbnailfile,
+    previewfile: thumbnailfile,
+    fixture: videoPath
+  })
 
   console.log('\nUploading on PeerTube video "%s".', videoAttributes.name)
 

+ 17 - 35
server/tools/peertube-upload.ts

@@ -3,24 +3,18 @@ import { access, constants } from 'fs-extra'
 import { isAbsolute } from 'path'
 import { getClient, login } from '../../shared/extra-utils'
 import { uploadVideo } from '../../shared/extra-utils/'
-import { VideoPrivacy } from '../../shared/models/videos'
-import { getNetrc, getRemoteObjectOrDie, getSettings } from './cli'
+import { buildCommonVideoOptions, buildVideoAttributesFromCommander, getNetrc, getRemoteObjectOrDie, getSettings } from './cli'
 
-program
+let command = program
   .name('upload')
+
+command = buildCommonVideoOptions(command)
+
+command
+
   .option('-u, --url <url>', 'Server url')
   .option('-U, --username <username>', 'Username')
   .option('-p, --password <token>', 'Password')
-  .option('-n, --video-name <name>', 'Video name')
-  .option('-P, --privacy <privacy_number>', 'Privacy')
-  .option('-N, --nsfw', 'Video is Not Safe For Work')
-  .option('-c, --category <category_number>', 'Category number')
-  .option('-C, --channel-id <channel_id>', 'Channel ID')
-  .option('-m, --comments-enabled', 'Enable comments')
-  .option('-l, --licence <licence_number>', 'Licence number')
-  .option('-L, --language <language_code>', 'Language ISO 639 code (fr or en...)')
-  .option('-d, --video-description <description>', 'Video description')
-  .option('-t, --tags <tags>', 'Video tags', list)
   .option('-b, --thumbnail <thumbnailPath>', 'Thumbnail path')
   .option('-v, --preview <previewPath>', 'Preview path')
   .option('-f, --file <file>', 'Video absolute file path')
@@ -30,10 +24,9 @@ Promise.all([ getSettings(), getNetrc() ])
        .then(([ settings, netrc ]) => {
          const { url, username, password } = getRemoteObjectOrDie(program, settings, netrc)
 
-         if (!program[ 'videoName' ] || !program[ 'file' ] || !program[ 'channelId' ]) {
+         if (!program[ 'videoName' ] || !program[ 'file' ]) {
            if (!program[ 'videoName' ]) console.error('--video-name is required.')
            if (!program[ 'file' ]) console.error('--file is required.')
-           if (!program[ 'channelId' ]) console.error('--channel-id is required.')
 
            process.exit(-1)
          }
@@ -70,24 +63,17 @@ async function run (url: string, username: string, password: string) {
 
   console.log('Uploading %s video...', program[ 'videoName' ])
 
-  const videoAttributes = {
-    name: program[ 'videoName' ],
-    category: program[ 'category' ] || undefined,
-    channelId: program[ 'channelId' ],
-    licence: program[ 'licence' ] || undefined,
-    language: program[ 'language' ] || undefined,
-    nsfw: program[ 'nsfw' ] !== undefined ? program[ 'nsfw' ] : false,
-    description: program[ 'videoDescription' ] || undefined,
-    tags: program[ 'tags' ] || [],
-    commentsEnabled: program[ 'commentsEnabled' ] !== undefined ? program[ 'commentsEnabled' ] : true,
-    downloadEnabled: program[ 'downloadEnabled' ] !== undefined ? program[ 'downloadEnabled' ] : true,
+  const defaultAttributes = {
+    tags: command[ 'tags' ],
+    description: command[ 'videoDescription' ]
+  }
+  const videoAttributes = await buildVideoAttributesFromCommander(url, program, defaultAttributes)
+
+  Object.assign(videoAttributes, {
     fixture: program[ 'file' ],
     thumbnailfile: program[ 'thumbnail' ],
-    previewfile: program[ 'preview' ],
-    waitTranscoding: true,
-    privacy: program[ 'privacy' ] || VideoPrivacy.PUBLIC,
-    support: undefined
-  }
+    previewfile: program[ 'preview' ]
+  })
 
   try {
     await uploadVideo(url, accessToken, videoAttributes)
@@ -100,7 +86,3 @@ async function run (url: string, username: string, password: string) {
 }
 
 // ----------------------------------------------------------------------------
-
-function list (val) {
-  return val.split(',')
-}