import { Command } from 'commander' ; import { Netrc } from 'netrc-parser' ; import { join } from 'path' ; import { createLogger , format , transports } from 'winston' ; import { loadLanguages } from '@server/initializers/constants' ; import { root } from '@shared/core-utils' ; import { UserRole } from '@shared/models' ; import { PeerTubeServer } from '@shared/server-commands' ; import { VideoPrivacy } from '../../shared/models/videos' ; import { getAppNumber , isTestInstance } from '../helpers/core-utils' ; let configName = 'PeerTube/CLI' ; if ( isTestInstance ( ) ) configName += `-${ getAppNumber ( ) }` ; const config = require ( 'application-config' ) ( configName ) ; const version = require ( join ( root ( ) , 'package.json' ) ) . version ; async function getAdminTokenOrDie ( server , username , password ) { const token = await server . login . getAccessToken ( username , password ) ; const me = await server . users . getMyInfo ( { token } ) ; if ( me . role !== UserRole . ADMINISTRATOR ) { console . error ( 'You must be an administrator.' ) ; process . exit ( - 1 ) ; } return token ; } interface Settings { remotes : any [ ] ; default : number ; } async function getSettings ( ) { const defaultSettings = { remotes : [ ] , default : - 1 } ; const data = await config . read ( ) ; return Object . keys ( data ) . length === 0 ? defaultSettings : data ; } async function getNetrc ( ) { const Netrc = require ( 'netrc-parser' ) . Netrc ; const netrc = isTestInstance ( ) ? new Netrc ( join ( root ( ) , 'test' + getAppNumber ( ) , 'netrc' ) ) : new Netrc ( ) ; await netrc . load ( ) ; return netrc ; } function writeSettings ( settings ) { return config . write ( settings ) ; } function deleteSettings ( ) { return config . trash ( ) ; } function getRemoteObjectOrDie ( program , settings , netrc ) { const options = program . opts ( ) ; if ( ! options . url || ! options . username || ! options . password ) { if ( settings . remotes . length === 0 || Object . keys ( netrc . machines ) . length === 0 ) { if ( ! options . url ) console . error ( '--url field is required.' ) ; if ( ! options . username ) console . error ( '--username field is required.' ) ; if ( ! options . password ) console . error ( '--password field is required.' ) ; return process . exit ( - 1 ) ; } let url = options . url ; let username = options . username ; let password = options . password ; if ( ! url && settings . default !== - 1 ) url = settings . remotes [ settings . default ] ; const machine = netrc . machines [ url ] ; if ( ! username && machine ) username = machine . login ; if ( ! password && machine ) password = machine . password ; return { url , username , password } ; } return { url : options . url , username : options . username , password : options . password } ; } function buildCommonVideoOptions ( 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 ( '--no-comments-enabled' , 'Disable video comments' ) . option ( '-s, --support <support>' , 'Video support text' ) . option ( '--no-wait-transcoding' , 'Do not wait transcoding before publishing the video' ) . option ( '--no-download-enabled' , 'Disable video download' ) . option ( '-v, --verbose <verbose>' , 'Verbosity, from 0/\'error\' to 4/\'debug\'' , 'info' ) ; } async function buildVideoAttributesFromCommander ( server , command , defaultAttributes = { } ) { const options = command . opts ( ) ; const defaultBooleanAttributes = { nsfw : false , commentsEnabled : true , downloadEnabled : true , waitTranscoding : true } ; const booleanAttributes = { } ; for ( const key of Object . keys ( defaultBooleanAttributes ) ) { if ( options [ key ] !== undefined ) { booleanAttributes [ key ] = options [ key ] ; } else if ( defaultAttributes [ key ] !== undefined ) { booleanAttributes [ key ] = defaultAttributes [ key ] ; } else { booleanAttributes [ key ] = defaultBooleanAttributes [ key ] ; } } const videoAttributes = { name : options . videoName || defaultAttributes . name , category : options . category || defaultAttributes . category || undefined , licence : options . licence || defaultAttributes . licence || undefined , language : options . language || defaultAttributes . language || undefined , privacy : options . privacy || defaultAttributes . privacy || VideoPrivacy . PUBLIC , support : options . support || defaultAttributes . support || undefined , description : options . videoDescription || defaultAttributes . description || undefined , tags : options . tags || defaultAttributes . tags || undefined } ; Object . assign ( videoAttributes , booleanAttributes ) ; if ( options . channelName ) { const videoChannel = await server . channels . get ( { channelName : options . channelName } ) ; Object . assign ( videoAttributes , { channelId : videoChannel . id } ) ; if ( ! videoAttributes . support && videoChannel . support ) { Object . assign ( videoAttributes , { support : videoChannel . support } ) ; } } return videoAttributes ; } function getServerCredentials ( program ) { return Promise . all ( [ getSettings ( ) , getNetrc ( ) ] ) . then ( ( [ settings , netrc ] ) => { return getRemoteObjectOrDie ( program , settings , netrc ) ; } ) ; } function buildServer ( url ) { loadLanguages ( ) ; return new PeerTubeServer ( { url } ) ; } async function assignToken ( server , username , password ) { const bodyClient = await server . login . getClient ( ) ; const client = { id : bodyClient . client_id , secret : bodyClient . client_secret } ; const body = await server . login . login ( { client , user : { username , password } } ) ; server . accessToken = body . access_token ; } function getLogger ( logLevel = 'info' ) { const logLevels = { 0 : 0 , error : 0 , 1 : 1 , warn : 1 , 2 : 2 , info : 2 , 3 : 3 , verbose : 3 , 4 : 4 , debug : 4 } ; const logger = createLogger ( { levels : logLevels , format : format . combine ( format . splat ( ) , format . simple ( ) ) , transports : [ new ( transports . Console ) ( { level : logLevel } ) ] } ) ; return logger ; } export { version , getLogger , getSettings , getNetrc , getRemoteObjectOrDie , writeSettings , deleteSettings , getServerCredentials , buildCommonVideoOptions , buildVideoAttributesFromCommander , getAdminTokenOrDie , buildServer , assignToken } ;