LocalFileWriter.js 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. const fs = require('fs')
  2. const uuid = require('node-uuid')
  3. const path = require('path')
  4. const Stream = require('stream')
  5. const { callbackify, promisify } = require('util')
  6. const metrics = require('metrics-sharelatex')
  7. const Settings = require('settings-sharelatex')
  8. const { WriteError } = require('./Errors')
  9. module.exports = {
  10. promises: {
  11. writeStream,
  12. deleteFile
  13. },
  14. writeStream: callbackify(writeStream),
  15. deleteFile: callbackify(deleteFile)
  16. }
  17. const pipeline = promisify(Stream.pipeline)
  18. async function writeStream(stream, key) {
  19. const timer = new metrics.Timer('writingFile')
  20. const fsPath = _getPath(key)
  21. const writeStream = fs.createWriteStream(fsPath)
  22. try {
  23. await pipeline(stream, writeStream)
  24. timer.done()
  25. return fsPath
  26. } catch (err) {
  27. await deleteFile(fsPath)
  28. throw new WriteError({
  29. message: 'problem writing file locally',
  30. info: { err, fsPath }
  31. }).withCause(err)
  32. }
  33. }
  34. async function deleteFile(fsPath) {
  35. if (!fsPath) {
  36. return
  37. }
  38. try {
  39. await promisify(fs.unlink)(fsPath)
  40. } catch (err) {
  41. if (err.code !== 'ENOENT') {
  42. throw new WriteError({
  43. message: 'failed to delete file',
  44. info: { fsPath }
  45. }).withCause(err)
  46. }
  47. }
  48. }
  49. function _getPath(key) {
  50. if (key == null) {
  51. key = uuid.v1()
  52. }
  53. key = key.replace(/\//g, '-')
  54. return path.join(Settings.path.uploadFolder, key)
  55. }