-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathindex.js
160 lines (144 loc) · 3.82 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
var child_process = require('child_process');
var exec = child_process.exec;
var UnrarStream = require('./lib/stream.js');
/**
* constructor
* @param {String|Object} options File path or options
*/
var Unrar = function(options) {
this._arguments = options.arguments || [];
this._filepath = options.path || options;
this._unrarBin = options.bin || '';
this._failOnPasswords = options.failOnPasswords || false;
};
/**
* Lists entries of archive
* @param {Function} done Callback
* @return {Array} Entries
*/
Unrar.prototype.list = function(done) {
var self = this;
var child = self._exec(['vt', '-v'], function(err, stdout) {
if (err) {
return done(err);
}
var chunks = stdout.split(/\r?\n\r?\n/);
chunks.slice(2, chunks.length - 1);
var list = chunks.map(extractProps);
// Filter & Remove dublicates
var unique = {};
for (i = 0, n = list.length; i < n; i++) {
var item = list[i];
if (item.name && item.ratio !== "-->" && item.ratio !== "<->") // Only proper items
unique[fileId(item)] = item;
}
var i = 0;
list = [];
for (var item in unique) {
list[i++] = unique[item];
}
// End Filter & Remove dublicates
done(null, list);
});
child.stderr.on('data', function(data) {
if (data.toString().trim().indexOf('Enter password') === 0) {
child.kill();
done(new Error('Password protected file'));
}
})
};
/**
* Creates readable stream of entry
* @param {String} entryname Name of entry
* @return {Object} Readable stream
*/
Unrar.prototype.stream = function(entryname) {
return new UnrarStream({
entryname: entryname,
filepath: this._filepath,
arguments: this._arguments,
bin: this._unrarBin,
});
};
/**
* Executes unrar
* @private
* @param {Array} args Arguments
* @param {Function} done Callback
* @return {ChildProcess}
*/
Unrar.prototype._exec = function(args, done) {
var self = this;
args = args.concat(self._arguments);
var command =
(self._unrarBin ? '"'+self._unrarBin+'"' : 'unrar')+' ' +
args.join(' ') +
' "' + self._filepath + '"';
return exec(command, function(err, stdout, stderr) {
if (err) {
return done(err);
}
if (stderr.length > 0) {
return done(new Error(stderr));
}
if (stdout.length > 0 && stdout.match(/.*is not RAR archive.*/g)) {
return done(new Error('Unsupported RAR file.'));
}
if (stdout.length > 0 && stdout.match(/.*Checksum error in the encrypted file.*/g)) {
return done(new Error('Invalid Password.'));
}
if (self._failOnPasswords && stdout.match(/.*Flags: encrypted.*/g)) {
return done(new Error('Password protected file'));
}
done(null, stdout);
});
};
/**
* Generate unique Identifier per File
* @param {Object} item
* @return {String} id
*/
function fileId(item) {
return [item.name, item.type, item.crc32].join("-");
}
/**
* Normalizes description of entry
* @param {Buffer} raw Chunk
* @return {Object} Parsed description
*/
function extractProps(raw) {
var desc = {};
var props = raw.split(/\r?\n/);
props.forEach(function(prop) {
prop = prop.split(': ');
var key = normalizeKey(prop[0]);
var val = prop[1];
desc[key] = val;
});
return desc;
}
/**
* Normalizes keys of entry description
* @param {String} key Raw key
* @return {String} Normalized key
*/
function normalizeKey(key) {
var normKey = key;
normKey = normKey.toLowerCase();
normKey = normKey.replace(/^\s+/, '');
var keys = {
'name': 'name',
'type': 'type',
'size': 'size',
'packed size': 'packedSize',
'ratio': 'ratio',
'mtime': 'mtime',
'attributes': 'attributes',
'crc32': 'crc32',
'host os': 'hostOS',
'compression': 'compression',
'flags': 'flags'
};
return keys[normKey] || key;
}
module.exports = Unrar;