| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- child = require "child_process"
- logger = require "logger-sharelatex"
- metrics = require "../../infrastructure/Metrics"
- fs = require "fs"
- Path = require "path"
- _ = require("underscore")
- ONE_MEG = 1024 * 1024
- module.exports = ArchiveManager =
- _isZipTooLarge: (source, callback = (err, isTooLarge)->)->
- callback = _.once callback
- unzip = child.spawn("unzip", ["-l", source])
- output = ""
- unzip.stdout.on "data", (d)->
- output += d
- error = null
- unzip.stderr.on "data", (chunk) ->
- error ||= ""
- error += chunk
- unzip.on "error", (err) ->
- logger.error {err, source}, "unzip failed"
- if err.code == "ENOENT"
- logger.error "unzip command not found. Please check the unzip command is installed"
- callback(err)
- unzip.on "close", (exitCode) ->
- if error?
- error = new Error(error)
- logger.error err:error, source: source, "error checking zip size"
- lines = output.split("\n")
- lastLine = lines[lines.length - 2]?.trim()
- totalSizeInBytes = lastLine?.split(" ")?[0]
- totalSizeInBytesAsInt = parseInt(totalSizeInBytes)
- if !totalSizeInBytesAsInt? or isNaN(totalSizeInBytesAsInt)
- logger.err source:source, totalSizeInBytes:totalSizeInBytes, totalSizeInBytesAsInt:totalSizeInBytesAsInt, lastLine:lastLine, exitCode:exitCode, "error getting bytes of zip"
- return callback(new Error("error getting bytes of zip"))
- isTooLarge = totalSizeInBytes > (ONE_MEG * 300)
- callback(error, isTooLarge)
-
- extractZipArchive: (source, destination, _callback = (err) ->) ->
- callback = (args...) ->
- _callback(args...)
- _callback = () ->
- ArchiveManager._isZipTooLarge source, (err, isTooLarge)->
- if err?
- logger.err err:err, "error checking size of zip file"
- return callback(err)
- if isTooLarge
- return callback(new Error("zip_too_large"))
- timer = new metrics.Timer("unzipDirectory")
- logger.log source: source, destination: destination, "unzipping file"
- unzip = child.spawn("unzip", [source, "-d", destination])
- # don't remove this line, some zips need
- # us to listen on this for some unknow reason
- unzip.stdout.on "data", (d)->
- error = null
- unzip.stderr.on "data", (chunk) ->
- error ||= ""
- error += chunk
- unzip.on "error", (err) ->
- logger.error {err, source, destination}, "unzip failed"
- if err.code == "ENOENT"
- logger.error "unzip command not found. Please check the unzip command is installed"
- callback(err)
- unzip.on "close", () ->
- timer.done()
- if error?
- error = new Error(error)
- logger.error err:error, source: source, destination: destination, "error unzipping file"
- callback(error)
-
- findTopLevelDirectory: (directory, callback = (error, topLevelDir) ->) ->
- fs.readdir directory, (error, files) ->
- return callback(error) if error?
- if files.length == 1
- childPath = Path.join(directory, files[0])
- fs.stat childPath, (error, stat) ->
- return callback(error) if error?
- if stat.isDirectory()
- return callback(null, childPath)
- else
- return callback(null, directory)
- else
- return callback(null, directory)
|