ResourceWriter.coffee 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. UrlCache = require "./UrlCache"
  2. Path = require "path"
  3. fs = require "fs"
  4. async = require "async"
  5. mkdirp = require "mkdirp"
  6. OutputFileFinder = require "./OutputFileFinder"
  7. Metrics = require "./Metrics"
  8. module.exports = ResourceWriter =
  9. syncResourcesToDisk: (project_id, resources, basePath, callback = (error) ->) ->
  10. @_removeExtraneousFiles resources, basePath, (error) =>
  11. return callback(error) if error?
  12. jobs = for resource in resources
  13. do (resource) =>
  14. (callback) => @_writeResourceToDisk(project_id, resource, basePath, callback)
  15. async.series jobs, callback
  16. _removeExtraneousFiles: (resources, basePath, _callback = (error) ->) ->
  17. timer = new Metrics.Timer("unlink-output-files")
  18. callback = (error) ->
  19. timer.done()
  20. _callback(error)
  21. OutputFileFinder.findOutputFiles resources, basePath, (error, outputFiles) ->
  22. return callback(error) if error?
  23. jobs = []
  24. for file in outputFiles or []
  25. do (file) ->
  26. path = file.path
  27. should_delete = true
  28. if path.match(/^output\./) or path.match(/\.aux$/)
  29. should_delete = false
  30. if path == "output.pdf" or path == "output.dvi" or path == "output.log"
  31. should_delete = true
  32. if should_delete
  33. jobs.push (callback) -> ResourceWriter._deleteFileIfNotDirectory Path.join(basePath, path), callback
  34. async.series jobs, callback
  35. _deleteFileIfNotDirectory: (path, callback = (error) ->) ->
  36. fs.stat path, (error, stat) ->
  37. return callback(error) if error?
  38. if stat.isFile()
  39. fs.unlink path, callback
  40. else
  41. callback()
  42. _writeResourceToDisk: (project_id, resource, basePath, callback = (error) ->) ->
  43. path = Path.normalize(Path.join(basePath, resource.path))
  44. if (path.slice(0, basePath.length) != basePath)
  45. return callback new Error("resource path is outside root directory")
  46. mkdirp Path.dirname(path), (error) ->
  47. return callback(error) if error?
  48. # TODO: Don't overwrite file if it hasn't been modified
  49. if resource.url?
  50. UrlCache.downloadUrlToFile(
  51. project_id,
  52. resource.url,
  53. path,
  54. resource.modified,
  55. callback
  56. )
  57. else
  58. fs.writeFile path, resource.content, callback