Skip to content

Instantly share code, notes, and snippets.

@chorim
Last active August 18, 2019 18:41
Show Gist options
  • Save chorim/4dcbcda4e35f27e5089353e9eca2af07 to your computer and use it in GitHub Desktop.
Save chorim/4dcbcda4e35f27e5089353e9eca2af07 to your computer and use it in GitHub Desktop.
Adonis multiple file upload
/**
* Moves file from tmp directory to the user
* defined location.
*
* @method move
*
* @param {String} location
* @param {Object} options
*
* @return {Promise}
*/
async move (location, options = {}) {
options.name = options.name || this.clientName
/**
* Throw error when stream has been consumed but there
* is no `tmp` file. Since after this there is no
* way to move file anywhere.
*/
if (!this.tmpPath && this.ended) {
throw CE.FileMoveException.invalidMoveState(this.fieldName)
}
/**
* Validate file for extension or size checks. Size
* check may get ignored here if there is no tmp
* file, since size is calculated once stream
* is consumed.
*/
await this._validateFn()
if (_.size(this._error)) {
return
}
/**
* If stream was not used, stream file to
* the user specificed location
*/
if (!this.ended) {
try {
await this._streamFile(path.join(location, options.name), this.validationOptions.size)
this.fileName = options.name
this._location = location
this.status = 'moved'
debug('streamed file to final location %s - %s', this.fieldName, this.fileName)
} catch (error) {
this.setError(getError('size', { size: this.validationOptions.size }), 'size')
}
return
}
/**
* Otherwise move the tmpFile to the user specified
* location.
*/
try {
await fs.move(this.tmpPath, path.join(location, options.name))
this.fileName = options.name
this._location = location
this.status = 'moved'
} catch (error) {
this.setError(getError('exist', { name: options.name }), 'exist')
return
}
debug('moved file to final location %s - %s', this.fieldName, this.fileName)
}
moveAll (location, callback) {
const AsyncFunction = (async () => {}).constructor;
callback = typeof (callback) === 'function' ? callback : function () {}
if (callback instanceof AsyncFunction) {
return Promise.all(_.map(this._files, (file) => {
return callback(file).then(file.move.bind(file, location))
}))
} else {
return Promise.all(_.map(this._files, (file) => {
return file.move(location, callback(file))
}))
}
}
const crypto = require('crypto')
const fs = require('fs')
class FileHash {
// Algorithm depends on availability of OpenSSL on platform
// Another algorithms: 'sha1', 'md5', 'sha256', 'sha512' ...
get(fileName, algorithm = 'md5') {
return new Promise((resolve, reject) => {
let shasum = crypto.createHash(algorithm);
try {
let s = fs.ReadStream(fileName)
s.on('data', function (data) {
shasum.update(data)
})
// making digest
s.on('end', function () {
const hash = shasum.digest('hex')
return resolve(hash);
})
} catch (error) {
return reject('hash calc fail');
}
})
}
}
module.exports = new FileHash()
const uploadFiles = request.file('upload_files', {
types: ['image'],
size: '2mb'
})
// console.log(uploadFiles)
if (uploadFiles) {
try {
await uploadFiles.moveAll(Helpers.tmpPath('uploads'), async (file) => {
const fileHash = await hash.get(file.tmpPath, 'sha256')
return { name: `${fileHash}.${file.subtype}` }
})
} catch (e) {
console.log(e)
}
// await uploadFiles.moveAll(Helpers.tmpPath('uploads'))
if (!uploadFiles.movedAll()) {
return response.status(400).json({ error: uploadFiles.errors() })
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment