From 9593da5626eac46589fbf6955082fee2549c8be1 Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Sun, 2 Oct 2016 22:21:37 -0600 Subject: [PATCH] Additional work with archivers --- core/archive_util.js | 62 +++++++++++++++++++++++++++++++++++++------- core/config.js | 9 +++---- core/file_area.js | 6 ++++- 3 files changed, 62 insertions(+), 15 deletions(-) diff --git a/core/archive_util.js b/core/archive_util.js index fb378a84..b84b8b98 100644 --- a/core/archive_util.js +++ b/core/archive_util.js @@ -37,7 +37,7 @@ class Archiver { canCompress() { return this.can('compress'); } canDecompress() { return this.can('decompress'); } - canList() { return this.can('list'); } + canList() { return this.can('list'); } // :TODO: validate entryMatch canExtract() { return this.can('extract'); } } @@ -53,8 +53,8 @@ module.exports = class ArchiveUtil { if(!archiveUtil) { archiveUtil = new ArchiveUtil(); archiveUtil.init(); - return archiveUtil; } + return archiveUtil; } init() { @@ -127,17 +127,17 @@ module.exports = class ArchiveUtil { }); } - spawnHandler(comp, action, cb) { + spawnHandler(proc, action, cb) { // pty.js doesn't currently give us a error when things fail, // so we have this horrible, horrible hack: let err; - comp.once('data', d => { + proc.once('data', d => { if(_.isString(d) && d.startsWith('execvp(3) failed.: No such file or directory')) { err = new Error(`${action} failed: ${d.trim()}`); } }); - comp.once('exit', exitCode => { + proc.once('exit', exitCode => { if(exitCode) { return cb(new Error(`${action} failed with exit code: ${exitCode}`)); } @@ -161,9 +161,9 @@ module.exports = class ArchiveUtil { }; const args = archiver.compress.args.map( arg => stringFormat(arg, fmtObj) ); - const comp = pty.spawn(archiver.compress.cmd, args, this.getPtyOpts()); + const proc = pty.spawn(archiver.compress.cmd, args, this.getPtyOpts()); - return this.spawnHandler(comp, 'Compression', cb); + return this.spawnHandler(proc, 'Compression', cb); } extractTo(archivePath, extractPath, archType, cb) { @@ -179,9 +179,53 @@ module.exports = class ArchiveUtil { }; const args = archiver.decompress.args.map( arg => stringFormat(arg, fmtObj) ); - const comp = pty.spawn(archiver.decompress.cmd, args, this.getPtyOpts()); + const proc = pty.spawn(archiver.decompress.cmd, args, this.getPtyOpts()); - return this.spawnHandler(comp, 'Decompression', cb); + return this.spawnHandler(proc, 'Decompression', cb); + } + + listEntries(archivePath, archType, cb) { + const archiver = this.getArchiver(archType); + + if(!archiver) { + return cb(new Error(`Unknown archive type: ${archType}`)); + } + + const fmtObj = { + archivePath : archivePath, + }; + + const args = archiver.list.args.map( arg => stringFormat(arg, fmtObj) ); + const proc = pty.spawn(archiver.list.cmd, args, this.getPtyOpts()); + + let output = ''; + proc.on('data', data => { + // :TODO: hack for: execvp(3) failed.: No such file or directory + + output += data; + }); + + proc.once('exit', exitCode => { + if(exitCode) { + return cb(new Error(`List failed with exit code: ${exitCode}`)); + } + //if(err) { + // return cb(err); + // } + + const entries = []; + const entryMatchRe = new RegExp(archiver.list.entryMatch, 'g'); + let m; + while(null !== (m = entryMatchRe.exec(output))) { + // :TODO: allow alternate ordering!!! + entries.push({ + size : m[1], + fileName : m[2], + }); + } + + return cb(null, entries); + }); } getPtyOpts() { diff --git a/core/config.js b/core/config.js index 211e779d..8c2a89c5 100644 --- a/core/config.js +++ b/core/config.js @@ -223,12 +223,11 @@ function getDefaultConfig() { cmd : '7z', args : [ 'e', '-o{extractPath}', '{archivePath}' ] }, - /* list : { - cmd : '7z', - args : [ 'l', '{archivePath}' ], - match : '...someregex...' - },*/ + cmd : '7z', + args : [ 'l', '{archivePath}' ], + entryMatch : '^[0-9]{4}-[0-9]{2}-[0-9]{2}\\s[0-9]{2}:[0-9]{2}:[0-9]{2}\\s[A-Za-z\\.]{5}\\s+([0-9]+)\\s+[0-9]+\\s+([^\\n]+)$', + }, extract : { cmd : '7z', args : [ 'x', '-o{extractPath}', '{archivePath}', '{fileList}' ], diff --git a/core/file_area.js b/core/file_area.js index 0a684442..4f33d218 100644 --- a/core/file_area.js +++ b/core/file_area.js @@ -141,11 +141,15 @@ function getExistingFileEntriesBySha1(sha1, cb) { } function addNewArchiveFileEnty(fileEntry, filePath, archiveType, cb) { + const archiveUtil = ArchiveUtil.getInstance(); + async.series( [ function getArchiveFileList(callback) { // :TODO: get list of files in archive - return callback(null); + archiveUtil.listEntries(filePath, archiveType, (err, entries) => { + return callback(err); + }); } ], err => {