-
-
Notifications
You must be signed in to change notification settings - Fork 56
/
Copy pathcli.js
executable file
·234 lines (202 loc) · 5.76 KB
/
cli.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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
#!/usr/bin/env node
var program = require('commander')
var fs = require('fs')
var Progress = require('progress')
var scanner = require('./main')
function action (paths, options) {
var format = options.format || 'json'
var hideProgressBar = !options.progress
var verbose = options.verbose
var summary = options.summary
var response = []
var files = []
var percentages = []
var startTime = new Date()
// https://gist.github.com/kethinov/6658166
var walkSync = function (dir, filelist) {
var files = fs.readdirSync(dir)
filelist = filelist || []
files.forEach(function (file) {
if (fs.statSync(dir + '/' + file).isDirectory()) {
filelist = walkSync(dir + '/' + file, filelist)
} else {
filelist.push(dir + '/' + file)
}
})
return filelist
}
paths = paths.filter(function (element, index, array) {
try {
fs.accessSync(element, fs.F_OK)
return true
} catch (e) {
console.log('Warning: File or directory "' + element + '" does not exist.')
}
})
// Read all paths
for (var i = 0; i < paths.length; i++) {
var path = paths[i]
if (fs.lstatSync(path).isDirectory()) {
files.push.apply(files, walkSync(path))
} else {
files.push(path)
}
}
if (files.length === 0) {
throw new Error('No files were found.')
}
files = files.filter(function (element, index, array) {
return (['pdf', 'jpeg', 'jpg', 'gif', 'png', 'bmp'].indexOf(element.split('.').pop().toLowerCase()) !== -1)
})
if (files.length === 0) {
throw new Error('No image or PDF files could be found.')
}
var stderr = process.stderr
var bar = new Progress('Parsing :current/:total |:bar| :elapseds', {
complete: '\u2591',
incomplete: ' ',
width: 35,
total: files.length,
clear: !hideProgressBar,
stream: hideProgressBar ? function () {} : stderr
})
function updateProgressBar () {
bar.update(percentages.reduce(function (a, b) {
return a + b
}, 0) / files.length)
}
var interval = setInterval(function () {
updateProgressBar()
if (bar.complete) {
clearInterval(interval)
}
}, 300)
var filesDone = []
for (i = 0; i < files.length; i++) {
var file = files[i]
var filename = file
var stream = fs.createReadStream(file)
filesDone[i] = false;
(function (filename, index) {
percentages[index] = 0
scanner(stream)
.setVerbose(verbose)
.logger(function (message) {
stderr.clearLine()
stderr.cursorTo(0)
stderr.write(message)
stderr.write('\n')
bar.render()
})
.ticker(function (percent) {
percentages[index] = percent
updateProgressBar()
})
.parse(function (error, details) {
filesDone[index] = true
if (error) {
response[filename] = {
'error': error.message || error
}
} else {
if (!verbose) delete details.verboseText
response[filename] = details
}
if (filesDone.every(function (element) {
return element
})) {
if (format === 'json') {
console.log(JSON.stringify(sortResponse(response), null, 4))
} else {
console.log(response)
}
if (summary) {
var statisticsObject = statistics(response)
console.log('\n---------\nI was able to parse ' +
(statisticsObject.total / files.length * 100).toFixed(1) +
'% (' + statisticsObject.total + ') of the ' + files.length + ' file(s) in ' + ((new Date() - startTime) / 1000).toFixed(1) + 's.\n' +
(statisticsObject.amount / files.length * 100).toFixed(1) +
'% (' + statisticsObject.amount + ') amounts and ' +
(statisticsObject.date / files.length * 100).toFixed(1) +
'% (' + statisticsObject.date + ') dates could be parsed.\n---------\n')
}
}
})
}(filename, i))
}
}
function sortResponse (response) {
var keys = Object.keys(response)
naturalSort(keys)
var sorted = {}
for (var i = 0; i < keys.length; i++) {
sorted[keys[i]] = response[keys[i]]
}
return sorted
}
// http://stackoverflow.com/a/2802804
function naturalSort (ar, index) {
var L = ar.length
var i, who, next
var isi = typeof index === 'number'
var rx = /(\.\d+)|(\d+(\.\d+)?)|([^\d.]+)|(\.(\D+|$))/g
function nSort (aa, bb) {
var a = aa[0]
var b = bb[0]
var a1, b1, n
var i = 0
var L = a.length
while (i < L) {
if (!b[i]) return 1
a1 = a[i]
b1 = b[i++]
if (a1 !== b1) {
n = a1 - b1
if (!isNaN(n)) return n
return a1 > b1 ? 1 : -1
}
}
return b[i] !== undefined ? -1 : 0
}
for (i = 0; i < L; i++) {
who = ar[i]
next = isi ? ar[i][index] || '' : who
ar[i] = [String(next).toLowerCase().match(rx), who]
}
ar.sort(nSort)
for (i = 0; i < L; i++) {
ar[i] = ar[i][1]
}
}
function statistics (objects) {
var countTotal = 0
var countAmount = 0
var countDate = 0
for (var key in objects) {
var object = objects[key]
if (!object.error) {
if (object.amount && object.date) {
++countTotal
}
if (object.date) {
++countDate
}
if (object.amount) {
++countAmount
}
}
}
return {
total: countTotal,
amount: countAmount,
date: countDate
}
}
program
.arguments('<path...>')
.option('-f, --format <format>', 'format to return, json (default) or text')
.option('-p, --progress', 'add a progress bar')
.option('-s, --summary', 'show summary details')
.option('-v, --verbose', 'show verbose information')
.action(action)
.parse(process.argv)