Federated video streaming platform using ActivityPub and P2P in the web browser with Angular. https://joinpeertube.org/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

248 lines
7.0 KiB

  1. import { Command } from 'commander'
  2. import { Netrc } from 'netrc-parser'
  3. import { join } from 'path'
  4. import { createLogger, format, transports } from 'winston'
  5. import { loadLanguages } from '@server/initializers/constants'
  6. import { root } from '@shared/core-utils'
  7. import { UserRole } from '@shared/models'
  8. import { PeerTubeServer } from '@shared/server-commands'
  9. import { VideoPrivacy } from '../../shared/models/videos'
  10. import { getAppNumber, isTestInstance } from '../helpers/core-utils'
  11. let configName = 'PeerTube/CLI'
  12. if (isTestInstance()) configName += `-${getAppNumber()}`
  13. const config = require('application-config')(configName)
  14. const version = require(join(root(), 'package.json')).version
  15. async function getAdminTokenOrDie (server: PeerTubeServer, username: string, password: string) {
  16. const token = await server.login.getAccessToken(username, password)
  17. const me = await server.users.getMyInfo({ token })
  18. if (me.role !== UserRole.ADMINISTRATOR) {
  19. console.error('You must be an administrator.')
  20. process.exit(-1)
  21. }
  22. return token
  23. }
  24. interface Settings {
  25. remotes: any[]
  26. default: number
  27. }
  28. async function getSettings (): Promise<Settings> {
  29. const defaultSettings = {
  30. remotes: [],
  31. default: -1
  32. }
  33. const data = await config.read()
  34. return Object.keys(data).length === 0
  35. ? defaultSettings
  36. : data
  37. }
  38. async function getNetrc () {
  39. const Netrc = require('netrc-parser').Netrc
  40. const netrc = isTestInstance()
  41. ? new Netrc(join(root(), 'test' + getAppNumber(), 'netrc'))
  42. : new Netrc()
  43. await netrc.load()
  44. return netrc
  45. }
  46. function writeSettings (settings: Settings) {
  47. return config.write(settings)
  48. }
  49. function deleteSettings () {
  50. return config.trash()
  51. }
  52. function getRemoteObjectOrDie (
  53. program: Command,
  54. settings: Settings,
  55. netrc: Netrc
  56. ): { url: string, username: string, password: string } {
  57. const options = program.opts()
  58. if (!options.url || !options.username || !options.password) {
  59. // No remote and we don't have program parameters: quit
  60. if (settings.remotes.length === 0 || Object.keys(netrc.machines).length === 0) {
  61. if (!options.url) console.error('--url field is required.')
  62. if (!options.username) console.error('--username field is required.')
  63. if (!options.password) console.error('--password field is required.')
  64. return process.exit(-1)
  65. }
  66. let url: string = options.url
  67. let username: string = options.username
  68. let password: string = options.password
  69. if (!url && settings.default !== -1) url = settings.remotes[settings.default]
  70. const machine = netrc.machines[url]
  71. if (!username && machine) username = machine.login
  72. if (!password && machine) password = machine.password
  73. return { url, username, password }
  74. }
  75. return {
  76. url: options.url,
  77. username: options.username,
  78. password: options.password
  79. }
  80. }
  81. function buildCommonVideoOptions (command: Command) {
  82. function list (val) {
  83. return val.split(',')
  84. }
  85. return command
  86. .option('-n, --video-name <name>', 'Video name')
  87. .option('-c, --category <category_number>', 'Category number')
  88. .option('-l, --licence <licence_number>', 'Licence number')
  89. .option('-L, --language <language_code>', 'Language ISO 639 code (fr or en...)')
  90. .option('-t, --tags <tags>', 'Video tags', list)
  91. .option('-N, --nsfw', 'Video is Not Safe For Work')
  92. .option('-d, --video-description <description>', 'Video description')
  93. .option('-P, --privacy <privacy_number>', 'Privacy')
  94. .option('-C, --channel-name <channel_name>', 'Channel name')
  95. .option('--no-comments-enabled', 'Disable video comments')
  96. .option('-s, --support <support>', 'Video support text')
  97. .option('--no-wait-transcoding', 'Do not wait transcoding before publishing the video')
  98. .option('--no-download-enabled', 'Disable video download')
  99. .option('-v, --verbose <verbose>', 'Verbosity, from 0/\'error\' to 4/\'debug\'', 'info')
  100. }
  101. async function buildVideoAttributesFromCommander (server: PeerTubeServer, command: Command, defaultAttributes: any = {}) {
  102. const options = command.opts()
  103. const defaultBooleanAttributes = {
  104. nsfw: false,
  105. commentsEnabled: true,
  106. downloadEnabled: true,
  107. waitTranscoding: true
  108. }
  109. const booleanAttributes: { [id in keyof typeof defaultBooleanAttributes]: boolean } | {} = {}
  110. for (const key of Object.keys(defaultBooleanAttributes)) {
  111. if (options[key] !== undefined) {
  112. booleanAttributes[key] = options[key]
  113. } else if (defaultAttributes[key] !== undefined) {
  114. booleanAttributes[key] = defaultAttributes[key]
  115. } else {
  116. booleanAttributes[key] = defaultBooleanAttributes[key]
  117. }
  118. }
  119. const videoAttributes = {
  120. name: options.videoName || defaultAttributes.name,
  121. category: options.category || defaultAttributes.category || undefined,
  122. licence: options.licence || defaultAttributes.licence || undefined,
  123. language: options.language || defaultAttributes.language || undefined,
  124. privacy: options.privacy || defaultAttributes.privacy || VideoPrivacy.PUBLIC,
  125. support: options.support || defaultAttributes.support || undefined,
  126. description: options.videoDescription || defaultAttributes.description || undefined,
  127. tags: options.tags || defaultAttributes.tags || undefined
  128. }
  129. Object.assign(videoAttributes, booleanAttributes)
  130. if (options.channelName) {
  131. const videoChannel = await server.channels.get({ channelName: options.channelName })
  132. Object.assign(videoAttributes, { channelId: videoChannel.id })
  133. if (!videoAttributes.support && videoChannel.support) {
  134. Object.assign(videoAttributes, { support: videoChannel.support })
  135. }
  136. }
  137. return videoAttributes
  138. }
  139. function getServerCredentials (program: Command) {
  140. return Promise.all([ getSettings(), getNetrc() ])
  141. .then(([ settings, netrc ]) => {
  142. return getRemoteObjectOrDie(program, settings, netrc)
  143. })
  144. }
  145. function buildServer (url: string) {
  146. loadLanguages()
  147. return new PeerTubeServer({ url })
  148. }
  149. async function assignToken (server: PeerTubeServer, username: string, password: string) {
  150. const bodyClient = await server.login.getClient()
  151. const client = { id: bodyClient.client_id, secret: bodyClient.client_secret }
  152. const body = await server.login.login({ client, user: { username, password } })
  153. server.accessToken = body.access_token
  154. }
  155. function getLogger (logLevel = 'info') {
  156. const logLevels = {
  157. 0: 0,
  158. error: 0,
  159. 1: 1,
  160. warn: 1,
  161. 2: 2,
  162. info: 2,
  163. 3: 3,
  164. verbose: 3,
  165. 4: 4,
  166. debug: 4
  167. }
  168. const logger = createLogger({
  169. levels: logLevels,
  170. format: format.combine(
  171. format.splat(),
  172. format.simple()
  173. ),
  174. transports: [
  175. new (transports.Console)({
  176. level: logLevel
  177. })
  178. ]
  179. })
  180. return logger
  181. }
  182. // ---------------------------------------------------------------------------
  183. export {
  184. version,
  185. getLogger,
  186. getSettings,
  187. getNetrc,
  188. getRemoteObjectOrDie,
  189. writeSettings,
  190. deleteSettings,
  191. getServerCredentials,
  192. buildCommonVideoOptions,
  193. buildVideoAttributesFromCommander,
  194. getAdminTokenOrDie,
  195. buildServer,
  196. assignToken
  197. }