node-scp-async icon indicating copy to clipboard operation
node-scp-async copied to clipboard

[Feature request] Add progress callback

Open VityaSchel opened this issue 3 years ago • 3 comments

Please add callback from stdout of scp process to see how many bytes or percents are already uploaded and how many left

VityaSchel avatar May 07 '22 09:05 VityaSchel

I found myself wondering the same thing when using this for a project. But I wasn't ready to take 'Not Implemented' as an answer.

This is a rather archaic solution, but a solution none-the-less.

Inspecting the Client Object after initialization, cross-referenced to the source code, we can use a key handled by the sole dependency mscdev/ssh2. While they also don't have the feature we need they do track each received packet via _client._protocol._onPacket. We can hijack this in a way to also track each packet being received, giving us activity, so semblance of loading. But we also need to ensure we don't overwrite the function being called here already.

Below is a small mockup I did for this, working on a NodeJS CLI Application. Where when a packet is received it outputs *.

const { Client } = require("node-scp");

(async () => {
  const client = await Client({
    host: "host",
    port: "port",
    username: "user",
    password: "pass"
  });

  var loader = new Loader(packet_cache_buster);
  var origOnPacket = client.sftpWrapper._client._protocol._onPacket;
  var onPack = () => {
    origOnPacket();
    loader.addPacket();
  };
  client.sftpWrapper._client._protocol._onPacket = onPack;

  // continue on with what you need to do.
})();

The above will allow you to specify whatever function you need everytime a packet is received during the connection. Here I obviously set the groundwork to call a class Loader method titled addPacket. Which is below for posterity.

class Loader {
  constructor(buster) {
    this.totalPackets = 0;
    this.packetCache = 0;
    this.packetCacheBuster = buster;
  }
  addPacket() {
    this.totalPackets++;
    if (this.packetCache > this.packetCacheBuster) {
      this.packetCache = 0;
      this.showLoad();
    } else {
      this.packetCache++;
    }
  }
  showLoad() {
    process.stdout.write("*");
  }
}

Few notes on the above.

  • packet_cache_buster: This is a value you need to set that determines how many packets it takes to show your user a single *. This depends on the content you are downloading. If its 600 byte shell scripts it can be 1, but if its HD Movies, it should be much higher like 4000.
  • process.stdout: While this is what I'm using in the CLI to show each * right next to each other, keep in mind if you use it on Windows and its a TTY context, its async, meaning the text may become interleaved with other console.log uses. So use it the way you think is best.

I'm sure this can be expanded, but its working for me, and hope it can work for you.

confused-Techie avatar May 26 '22 07:05 confused-Techie

This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 5 days

github-actions[bot] avatar Aug 25 '22 03:08 github-actions[bot]

this fucking bot

VityaSchel avatar Aug 25 '22 07:08 VityaSchel

Just curious, but why do you need this when you can use the step function in the options? (or are you talking about something completely different here when referring to 'upload' ?)

await client.uploadFile(sourcePath, remotePath, { step: (total, nb, fsize) => console.log(total, fsize) });

sp00x avatar Nov 02 '22 17:11 sp00x

Just curious, but why do you need this when you can use the step function in the options? (or are you talking about something completely different here when referring to 'upload' ?)

await client.uploadFile(sourcePath, remotePath, { step: (total, nb, fsize) => console.log(total, fsize) });

Wow, yeah that would totally work for this. Must've missed that in the docs for ssh2

confused-Techie avatar Nov 04 '22 00:11 confused-Techie

This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 5 days

github-actions[bot] avatar Feb 02 '23 02:02 github-actions[bot]