Browse Source

storage-node: Recreate head command for CLI.

Shamil Gadelshin 4 years ago
parent
commit
9d3675ccad
3 changed files with 135 additions and 127 deletions
  1. 2 2
      storage-node/packages/cli/package.json
  2. 126 123
      storage-node/packages/cli/src/cli.ts
  3. 7 2
      yarn.lock

+ 2 - 2
storage-node/packages/cli/package.json

@@ -41,9 +41,9 @@
   },
   "dependencies": {
     "@joystream/storage-runtime-api": "^0.1.0",
+    "axios": "^0.19.2",
     "chalk": "^2.4.2",
     "lodash": "^4.17.11",
-    "meow": "^5.0.0",
-    "request": "^2.88.0"
+    "meow": "^5.0.0"
   }
 }

+ 126 - 123
storage-node/packages/cli/src/cli.ts

@@ -73,6 +73,19 @@ function loadIdentity(api, filename, passphrase) {
   }
 }
 
+function validateHeadParameters(url: string, contentId: string) : boolean {
+  return url && url !== "" && contentId && contentId !=="";
+}
+
+function showHeadUsage() {
+  console.log(chalk.yellow(`
+        Invalid parameters for 'head' command.
+        Usage:   storage-cli head colossusURL contentID
+        Example: storage-cli head http://localhost:3001 0x7a6ba7e9157e5fba190dc146fe1baa8180e29728a5c76779ed99655500cff795
+      `));
+}
+
+
 const commands = {
   // add Alice well known account as storage provider
   'dev-init': async api => {
@@ -91,136 +104,126 @@ const commands = {
   // resolve the ipns id to the asset put api url of the storage-node
   // before uploading..
   upload: async (api, url, filename, doTypeId, keyfile, passphrase) => {
-    loadIdentity(api, keyfile, passphrase)
-    // Check parameters
-    assertFile('file', filename)
-
-    const size = fs.statSync(filename).size
-    debug(`File "${filename}" is ${chalk.green(size)} Bytes.`)
-
-    if (!doTypeId) {
-      doTypeId = 1
-    }
-
-    debug('Data Object Type ID is: ' + chalk.green(doTypeId))
-
-    // Generate content ID
-    // FIXME this require path is like this because of
-    // https://github.com/Joystream/apps/issues/207
-    const { ContentId } = require('@joystream/types/media')
-    let cid = ContentId.generate()
-    cid = cid.encode().toString()
-    debug('Generated content ID: ' + chalk.green(cid))
-
-    // Create Data Object
-    await api.assets.createDataObject(api.identities.key.address, cid, doTypeId, size)
-    debug('Data object created.')
-
-    // TODO in future, optionally contact liaison here?
-    const request = require('request')
-    url = `${url}asset/v0/${cid}`
-    debug('Uploading to URL', chalk.green(url))
-
-    const f = fs.createReadStream(filename)
-    const opts = {
-      url,
-      headers: {
-        'content-type': '',
-        'content-length': `${size}`,
-      },
-      json: true,
-    }
-    return new Promise((resolve, reject) => {
-      const r = request.put(opts, (error, response, body) => {
-        if (error) {
-          reject(error)
-          return
-        }
-
-        if (response.statusCode / 100 !== 2) {
-          reject(new Error(`${response.statusCode}: ${body.message || 'unknown reason'}`))
-          return
-        }
-        debug('Upload successful:', body.message)
-        resolve()
-      })
-      f.pipe(r)
-    })
+    // loadIdentity(api, keyfile, passphrase)
+    // // Check parameters
+    // assertFile('file', filename)
+    //
+    // const size = fs.statSync(filename).size
+    // debug(`File "${filename}" is ${chalk.green(size)} Bytes.`)
+    //
+    // if (!doTypeId) {
+    //   doTypeId = 1
+    // }
+    //
+    // debug('Data Object Type ID is: ' + chalk.green(doTypeId))
+    //
+    // // Generate content ID
+    // // FIXME this require path is like this because of
+    // // https://github.com/Joystream/apps/issues/207
+    // const { ContentId } = require('@joystream/types/media')
+    // let cid = ContentId.generate()
+    // cid = cid.encode().toString()
+    // debug('Generated content ID: ' + chalk.green(cid))
+    //
+    // // Create Data Object
+    // await api.assets.createDataObject(api.identities.key.address, cid, doTypeId, size)
+    // debug('Data object created.')
+    //
+    // // TODO in future, optionally contact liaison here?
+    // const request = require('request')
+    // url = `${url}asset/v0/${cid}`
+    // debug('Uploading to URL', chalk.green(url))
+    //
+    // const f = fs.createReadStream(filename)
+    // const opts = {
+    //   url,
+    //   headers: {
+    //     'content-type': '',
+    //     'content-length': `${size}`,
+    //   },
+    //   json: true,
+    // }
+    // return new Promise((resolve, reject) => {
+    //   const r = request.put(opts, (error, response, body) => {
+    //     if (error) {
+    //       reject(error)
+    //       return
+    //     }
+    //
+    //     if (response.statusCode / 100 !== 2) {
+    //       reject(new Error(`${response.statusCode}: ${body.message || 'unknown reason'}`))
+    //       return
+    //     }
+    //     debug('Upload successful:', body.message)
+    //     resolve()
+    //   })
+    //   f.pipe(r)
+    // })
   },
   // needs to be updated to take a content id and resolve it a potential set
   // of providers that has it, and select one (possibly try more than one provider)
   // to fetch it from the get api url of a provider..
   download: async (api, url, contentId, filename) => {
-    const request = require('request')
-    url = `${url}asset/v0/${contentId}`
-    debug('Downloading URL', chalk.green(url), 'to', chalk.green(filename))
-
-    const f = fs.createWriteStream(filename)
-    const opts = {
-      url,
-      json: true,
-    }
-    return new Promise((resolve, reject) => {
-      const r = request.get(opts, (error, response, body) => {
-        if (error) {
-          reject(error)
-          return
-        }
-
-        debug(
-          'Downloading',
-          chalk.green(response.headers['content-type']),
-          'of size',
-          chalk.green(response.headers['content-length']),
-          '...'
-        )
-
-        f.on('error', err => {
-          reject(err)
-        })
-
-        f.on('finish', () => {
-          if (response.statusCode / 100 !== 2) {
-            reject(new Error(`${response.statusCode}: ${body.message || 'unknown reason'}`))
-            return
-          }
-          debug('Download completed.')
-          resolve()
-        })
-      })
-      r.pipe(f)
-    })
+    // const request = require('request')
+    // url = `${url}asset/v0/${contentId}`
+    // debug('Downloading URL', chalk.green(url), 'to', chalk.green(filename))
+    //
+    // const f = fs.createWriteStream(filename)
+    // const opts = {
+    //   url,
+    //   json: true,
+    // }
+    // return new Promise((resolve, reject) => {
+    //   const r = request.get(opts, (error, response, body) => {
+    //     if (error) {
+    //       reject(error)
+    //       return
+    //     }
+    //
+    //     debug(
+    //       'Downloading',
+    //       chalk.green(response.headers['content-type']),
+    //       'of size',
+    //       chalk.green(response.headers['content-length']),
+    //       '...'
+    //     )
+    //
+    //     f.on('error', err => {
+    //       reject(err)
+    //     })
+    //
+    //     f.on('finish', () => {
+    //       if (response.statusCode / 100 !== 2) {
+    //         reject(new Error(`${response.statusCode}: ${body.message || 'unknown reason'}`))
+    //         return
+    //       }
+    //       debug('Download completed.')
+    //       resolve()
+    //     })
+    //   })
+    //   r.pipe(f)
+    // })
   },
-  // similar to 'download' function
-  head: async (api, url, contentId) => {
-    const request = require('request')
-    url = `${url}asset/v0/${contentId}`
-    debug('Checking URL', chalk.green(url), '...')
-
-    const opts = {
-      url,
-      json: true,
+  // Shows asset information derived from request headers.
+  // Accepts colossus URL and content ID.
+  head: async (api: any, url: string, contentId: string) => {
+    if (!validateHeadParameters(url, contentId)){
+      return showHeadUsage();
     }
-    return new Promise((resolve, reject) => {
-      request.head(opts, (error, response, body) => {
-        if (error) {
-          reject(error)
-          return
-        }
-
-        if (response.statusCode / 100 !== 2) {
-          reject(new Error(`${response.statusCode}: ${body.message || 'unknown reason'}`))
-          return
-        }
-
-        for (const propname in response.headers) {
-          debug(`  ${chalk.yellow(propname)}: ${response.headers[propname]}`)
-        }
-
-        resolve()
-      })
-    })
-  },
+
+    const assetUrl = `${url}/asset/v0/${contentId}`;
+    console.log(chalk.yellow('Asset URL:', assetUrl));
+
+    try {
+      const response = await axios.head(assetUrl);
+
+      console.log(chalk.green(`Content type: ${response.headers['content-type']}`));
+      console.log(chalk.green(`Content lenth: ${response.headers['content-length']}`));
+
+    } catch (err) {
+      console.log(chalk.red(`Colossus request failed: ${err.message}`));
+    }
+  }
 }
 
 export async function main() {

+ 7 - 2
yarn.lock

@@ -5600,7 +5600,7 @@ axios@^0.18.0:
     follow-redirects "1.5.10"
     is-buffer "^2.0.2"
 
-axios@^0.19.0:
+axios@^0.19.0, axios@^0.19.2:
   version "0.19.2"
   resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27"
   integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==
@@ -22800,11 +22800,16 @@ typescript-formatter@^7.2.2:
     commandpost "^1.0.0"
     editorconfig "^0.15.0"
 
-typescript@3.7.2, typescript@3.7.x, typescript@^3.0.3, typescript@^3.6.4, typescript@^3.7.2, typescript@^3.8.3, typescript@^3.9.6:
+typescript@3.7.2, typescript@3.7.x, typescript@^3.0.3, typescript@^3.6.4, typescript@^3.7.2:
   version "3.7.2"
   resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.2.tgz#27e489b95fa5909445e9fef5ee48d81697ad18fb"
   integrity sha512-ml7V7JfiN2Xwvcer+XAf2csGO1bPBdRbFCkYBczNZggrBZ9c7G3riSUeJmqEU5uOtXNPMhE3n+R4FA/3YOAWOQ==
 
+typescript@^3.8.3, typescript@^3.9.6:
+  version "3.9.6"
+  resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.6.tgz#8f3e0198a34c3ae17091b35571d3afd31999365a"
+  integrity sha512-Pspx3oKAPJtjNwE92YS05HQoY7z2SFyOpHo9MqJor3BXAGNaPUs83CuVp9VISFkSjyRfiTpmKuAYGJB7S7hOxw==
+
 u2f-api@0.2.7:
   version "0.2.7"
   resolved "https://registry.yarnpkg.com/u2f-api/-/u2f-api-0.2.7.tgz#17bf196b242f6bf72353d9858e6a7566cc192720"