Leszek Wiesner 3 lat temu
rodzic
commit
2a8ddef4d1

+ 1 - 1
cli/README.md

@@ -45,7 +45,7 @@ $ npm install -g @joystream/cli
 $ joystream-cli COMMAND
 running command...
 $ joystream-cli (-v|--version|version)
-@joystream/cli/0.3.2 linux-x64 node-v13.12.0
+@joystream/cli/0.5.0 linux-x64 node-v13.12.0
 $ joystream-cli --help [COMMAND]
 USAGE
   $ joystream-cli COMMAND

+ 5 - 3
cli/package.json

@@ -1,7 +1,7 @@
 {
   "name": "@joystream/cli",
   "description": "Command Line Interface for Joystream community and governance activities",
-  "version": "0.3.2",
+  "version": "0.5.0",
   "author": "Leszek Wiesner",
   "bin": {
     "joystream-cli": "./bin/run"
@@ -40,7 +40,9 @@
     "moment": "^2.24.0",
     "proper-lockfile": "^4.1.1",
     "slug": "^2.1.1",
-    "tslib": "^1.11.1"
+    "tslib": "^1.11.1",
+    "mime-types": "^2.1.30",
+    "@types/mime-types": "^2.1.0"
   },
   "devDependencies": {
     "@oclif/dev-cli": "^1.22.2",
@@ -104,7 +106,7 @@
         "description": "Working group lead and worker actions"
       },
       "content": {
-        "description": "Interactions with content directory module - managing classes, schemas, entities and permissions"
+        "description": "Interactions with content directory module - managing vidoes, channels, assets, categories and curator groups"
       }
     }
   },

+ 5 - 5
cli/src/Types.ts

@@ -251,15 +251,15 @@ export type VideoCategoryInputParameters = VideoCategoryMetadata.AsObject
 
 // JSONSchema utility types
 export type JSONTypeName<T> = T extends string
-  ? 'string'
+  ? 'string' | ['string', 'null']
   : T extends number
-  ? 'number'
+  ? 'number' | ['number', 'null']
   : T extends any[]
-  ? 'array'
+  ? 'array' | ['array', 'null']
   : T extends Record<string, unknown>
-  ? 'object'
+  ? 'object' | ['object', 'null']
   : T extends boolean
-  ? 'boolean'
+  ? 'boolean' | ['boolean', 'null']
   : never
 
 export type PropertySchema<P> = Omit<

+ 9 - 5
cli/src/base/UploadCommandBase.ts

@@ -12,6 +12,7 @@ import ffprobeInstaller from '@ffprobe-installer/ffprobe'
 import ffmpeg from 'fluent-ffmpeg'
 import path from 'path'
 import chalk from 'chalk'
+import mimeTypes from 'mime-types'
 
 ffmpeg.setFfprobePath(ffprobeInstaller.path)
 
@@ -29,6 +30,10 @@ export default abstract class UploadCommandBase extends ContentDirectoryCommandB
     return cachedSize !== undefined ? cachedSize : fs.statSync(path).size
   }
 
+  normalizeEndpoint(endpoint: string) {
+    return endpoint.endsWith('/') ? endpoint : endpoint + '/'
+  }
+
   createReadStreamWithProgressBar(
     filePath: string,
     barTitle: string,
@@ -104,7 +109,7 @@ export default abstract class UploadCommandBase extends ContentDirectoryCommandB
 
     const size = this.getFileSize(filePath)
     const container = path.extname(filePath).slice(1)
-    const mimeType = `video/${container}` // TODO: Is this enough?
+    const mimeType = mimeTypes.lookup(container) || `unknown`
     return {
       size,
       container,
@@ -129,16 +134,15 @@ export default abstract class UploadCommandBase extends ContentDirectoryCommandB
 
   assetUrl(endpointRoot: string, contentId: ContentId): string {
     // This will also make sure the resulting url is a valid url
-    return new URL(`asset/v0/${contentId.encode()}`, endpointRoot).toString()
+    return new URL(`asset/v0/${contentId.encode()}`, this.normalizeEndpoint(endpointRoot)).toString()
   }
 
   async getRandomProviderEndpoint(): Promise<string | null> {
     const endpoints = _.shuffle(await this.getApi().allStorageProviderEndpoints())
     for (const endpoint of endpoints) {
       try {
-        const url = new URL(endpoint).toString()
-        // TODO: Some better way to test if provider is online?
-        await axios.get(url, { validateStatus: (s) => s === 404 /* 404 is expected */ })
+        const url = new URL('swagger.json', this.normalizeEndpoint(endpoint)).toString()
+        await axios.head(url)
         return endpoint
       } catch (e) {
         continue

+ 21 - 3
cli/src/commands/content/updateChannel.ts

@@ -6,6 +6,8 @@ import UploadCommandBase from '../../base/UploadCommandBase'
 import { CreateInterface } from '@joystream/types'
 import { ChannelUpdateParameters } from '@joystream/types/content'
 import { ChannelInputSchema } from '../../json-schemas/ContentDirectory'
+import { Option } from '@polkadot/types'
+import { AccountId } from '@polkadot/types/interfaces'
 
 export default class UpdateChannelCommand extends UploadCommandBase {
   static description = 'Update existing content directory channel.'
@@ -25,6 +27,22 @@ export default class UpdateChannelCommand extends UploadCommandBase {
     },
   ]
 
+  parseRewardAccountInput(rewardAccount?: string | null): string | null | Option<AccountId> {
+    if (rewardAccount === undefined) {
+      // Reward account remains unchanged
+      return null
+    }
+    else if (rewardAccount === null) {
+      // Reward account changed to empty
+      // FIXME: There seems to be no way to encode it currently
+      return this.createType('Option<AccountId>', null)
+    }
+    else {
+      // Reward account set to new account
+      return rewardAccount
+    }
+  }
+
   async run() {
     const {
       flags: { input },
@@ -41,7 +59,7 @@ export default class UpdateChannelCommand extends UploadCommandBase {
 
     const meta = channelMetadataFromInput(channelInput)
 
-    const { coverPhotoPath, avatarPhotoPath } = channelInput
+    const { coverPhotoPath, avatarPhotoPath, rewardAccount } = channelInput
     const inputPaths = [coverPhotoPath, avatarPhotoPath].filter((p) => p !== undefined) as string[]
     const inputAssets = await this.prepareInputAssets(inputPaths, input)
     const assets = inputAssets.map(({ parameters }) => ({ Upload: parameters }))
@@ -56,10 +74,10 @@ export default class UpdateChannelCommand extends UploadCommandBase {
     const channelUpdateParameters: CreateInterface<ChannelUpdateParameters> = {
       assets,
       new_meta: metadataToBytes(meta),
-      reward_account: channelInput.rewardAccount,
+      reward_account: this.parseRewardAccountInput(rewardAccount),
     }
 
-    this.jsonPrettyPrint(JSON.stringify({ assets, metadata: meta.toObject() }))
+    this.jsonPrettyPrint(JSON.stringify({ assets, metadata: meta.toObject(), rewardAccount }))
 
     await this.requireConfirmation('Do you confirm the provided input?', true)
 

+ 1 - 1
cli/src/json-schemas/ContentDirectory.ts

@@ -29,7 +29,7 @@ export const ChannelInputSchema: JsonSchema<ChannelInputParameters> = {
     title: { type: 'string' },
     coverPhotoPath: { type: 'string' },
     avatarPhotoPath: { type: 'string' },
-    rewardAccount: { type: 'string' },
+    rewardAccount: { type: ['string', 'null'] },
   },
 }
 

+ 17 - 0
yarn.lock

@@ -5062,6 +5062,11 @@
   resolved "https://registry.yarnpkg.com/@types/memoizee/-/memoizee-0.4.4.tgz#a8a5e917ef70c79523b8b8d57f529e49616a760c"
   integrity sha512-c9+1g6+6vEqcw5UuM0RbfQV0mssmZcoG9+hNC5ptDCsv4G+XJW1Z4pE13wV5zbc9e0+YrDydALBTiD3nWG1a3g==
 
+"@types/mime-types@^2.1.0":
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/@types/mime-types/-/mime-types-2.1.0.tgz#9ca52cda363f699c69466c2a6ccdaad913ea7a73"
+  integrity sha1-nKUs2jY/aZxpRmwqbM2q2RPqenM=
+
 "@types/mime@*":
   version "2.0.3"
   resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.3.tgz#c893b73721db73699943bfc3653b1deb7faa4a3a"
@@ -20070,6 +20075,11 @@ mime-db@1.44.0, "mime-db@>= 1.40.0 < 2":
   resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92"
   integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==
 
+mime-db@1.47.0:
+  version "1.47.0"
+  resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c"
+  integrity sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==
+
 mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24:
   version "2.1.25"
   resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.25.tgz#39772d46621f93e2a80a856c53b86a62156a6437"
@@ -20084,6 +20094,13 @@ mime-types@^2.1.18, mime-types@^2.1.26, mime-types@^2.1.27, mime-types@~2.1.17:
   dependencies:
     mime-db "1.44.0"
 
+mime-types@^2.1.30:
+  version "2.1.30"
+  resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d"
+  integrity sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==
+  dependencies:
+    mime-db "1.47.0"
+
 mime@1.6.0, mime@^1.3.4, mime@^1.4.1:
   version "1.6.0"
   resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"