node-ftp icon indicating copy to clipboard operation
node-ftp copied to clipboard

Duplicated uploads

Open the-noob opened this issue 8 years ago • 8 comments

I have a watcher on a folder that is supposed to upload all new files.

watcher.on('add', (pathAndFilename) => {
  logger.info(`File '${pathAndFilename}' was added`);

  ftpClient.on('ready', () => {
    ftpClient.put(pathAndFilename, pathAndFilename.split(path.sep).pop(), (error) => {
      if (error) {
        logger.error(`Error transferring over FTP '${pathAndFilename}'`, error);
      } else {
        logger.info(`File successfully transferred over FTP '${pathAndFilename}'`);
      }
      ftpClient.end();
    });
  });

  ftpClient.connect({
    host: ftpHost,
    port: ftpPort,
    user: ftpUser,
    password: ftpPassword,
  });
})

Every time a new file is being uploaded the FTP reuploads the previous ones. i.e.

start ftp
add `file1` -> ftp uploads `file1`
add `file2` -> ftp uploads `file1`, `file2`
add `file3` -> ftp uploads `file1`, `file2`, `file3`
...

the-noob avatar Oct 03 '17 11:10 the-noob

I do not think you should close the FTP connection if you are watching it.

icetee avatar Oct 21 '17 04:10 icetee

Maybe it's not clear from my snippet but I am watching a local folder and then upload any new files being added to that folder. As it might be hours in between the connection needs to be closed.

the-noob avatar Oct 21 '17 11:10 the-noob

The problem is to subscribe to the event every time you connected FTP. Bad way.

icetee avatar Oct 21 '17 13:10 icetee

Check this.

const EventEmitter = require('events');
const fs = require('fs');
const Client = require('../lib/connection');
const config = { ... };

const client = new Client();
const emitter = new EventEmitter();
const watchPath = './__folder/';
const uploadList = [];

const ready = () => client.cwd('/keymaps/', () => emitter.emit('connected'));

client.on('error', (err) => {
  console.error('ERROR: ', err);
});

client.on('close', (err) => {
  console.error('CLOSE: ', err);
});

const connected = () => {
  const upload = (filename, key) => {
    client.put(watchPath + filename, filename, (err) => {
      if (err) throw err;

      console.log('Uploaded: ', filename);
      delete uploadList[key]

      client.list((err, list) => {
        if (err) throw err;
        console.log(list);
      });
    });
  };

  uploadList.forEach(upload);
  client.end();
};

fs.watch(watchPath, { encoding: 'utf8' }, (eventType, filename) => {
  if (eventType === 'change') {
    uploadList.push(filename);
    emitter.emit('upload');
  }
});

client.on('ready', ready);
emitter.on('upload', (eventType, filename) => client.connect(config));
emitter.on('connected', connected);

icetee avatar Oct 21 '17 14:10 icetee

I hope I helped.

icetee avatar Oct 21 '17 21:10 icetee

I've just used another library that behaves as expected.

the-noob avatar Oct 22 '17 15:10 the-noob

can you suggest what another library you have used because I am facing the same problem?

amit1989patel avatar Nov 06 '17 11:11 amit1989patel

jsftp

the-noob avatar Nov 06 '17 19:11 the-noob