1 | 'use strict'
|
2 |
|
3 | const EventEmitter = require('events')
|
4 | const lib = require('./lib')
|
5 | const beginReady = require('./begin-ready')
|
6 |
|
7 | const EXIFTOOL_PATH = 'exiftool'
|
8 |
|
9 | const events = {
|
10 | OPEN: 'exiftool_opened',
|
11 | EXIT: 'exiftool_exit',
|
12 | }
|
13 |
|
14 | class ExiftoolProcess extends EventEmitter {
|
15 |
|
16 | |
17 |
|
18 |
|
19 |
|
20 | constructor(bin) {
|
21 | super()
|
22 | this._bin = lib.isString(bin) ? bin : EXIFTOOL_PATH
|
23 | this._process = undefined
|
24 | this._open = false
|
25 | }
|
26 |
|
27 | |
28 |
|
29 |
|
30 |
|
31 | close() {
|
32 | if (!this._open) {
|
33 | return Promise.reject(new Error('Exiftool process is not open'))
|
34 | }
|
35 | return lib.close(this._process)
|
36 | .then(() => {
|
37 | this._stdoutResolveWs.end()
|
38 | this._stderrResolveWs.end()
|
39 | this._open = false
|
40 | })
|
41 | }
|
42 |
|
43 | _assignEncoding(encoding) {
|
44 | let _encoding
|
45 | if (encoding === null) {
|
46 | _encoding = undefined
|
47 | } else if (lib.isString(encoding)) {
|
48 | _encoding = encoding
|
49 | } else {
|
50 | _encoding = 'utf8'
|
51 | }
|
52 | this._encoding = _encoding
|
53 | }
|
54 | |
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 | open(encoding) {
|
61 | this._assignEncoding(encoding)
|
62 | if (this._open) {
|
63 | return Promise.reject(new Error('Exiftool process is already open'))
|
64 | }
|
65 | return lib.spawn(this._bin)
|
66 | .then((exiftoolProcess) => {
|
67 |
|
68 | this.emit(events.OPEN, exiftoolProcess.pid)
|
69 | this._process = exiftoolProcess
|
70 |
|
71 | exiftoolProcess.on('exit', this._exitListener.bind(this))
|
72 |
|
73 |
|
74 | if (this._encoding) {
|
75 | exiftoolProcess.stdout.setEncoding(this._encoding)
|
76 | exiftoolProcess.stderr.setEncoding(this._encoding)
|
77 | }
|
78 | this._stdoutResolveWs = beginReady.setupResolveWriteStreamPipe(exiftoolProcess.stdout)
|
79 | this._stderrResolveWs = beginReady.setupResolveWriteStreamPipe(exiftoolProcess.stderr)
|
80 |
|
81 |
|
82 | this._stdoutResolveWs.on('error', console.error)
|
83 | this._stderrResolveWs.on('error', console.error)
|
84 |
|
85 |
|
86 |
|
87 |
|
88 |
|
89 | this._open = true
|
90 |
|
91 | return exiftoolProcess.pid
|
92 | })
|
93 | }
|
94 |
|
95 | _exitListener() {
|
96 |
|
97 | this.emit(events.EXIT)
|
98 | this._open = false
|
99 | }
|
100 |
|
101 | |
102 |
|
103 |
|
104 |
|
105 | get isOpen() {
|
106 | return this._open
|
107 | }
|
108 |
|
109 | _executeCommand(command, args, argsNoSplit, debug) {
|
110 |
|
111 | if (!this._open) {
|
112 | return Promise.reject(new Error('exiftool is not open'))
|
113 | }
|
114 | if (this._process.signalCode === 'SIGTERM') {
|
115 | return Promise.reject(new Error('Could not connect to the exiftool process'))
|
116 | }
|
117 |
|
118 | const proc = debug === true ? process : this._process
|
119 | return lib.executeCommand(proc, this._stdoutResolveWs,
|
120 | this._stderrResolveWs, command, args, argsNoSplit, this._encoding)
|
121 | }
|
122 |
|
123 | |
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 |
|
131 | readMetadata(file, args) {
|
132 | return this._executeCommand(file, args)
|
133 | }
|
134 |
|
135 | |
136 |
|
137 |
|
138 |
|
139 |
|
140 |
|
141 |
|
142 |
|
143 |
|
144 | writeMetadata(file, data, args, debug) {
|
145 | if (!lib.isString(file)) {
|
146 | throw new Error('File must be a string')
|
147 | }
|
148 | if (!lib.checkDataObject(data)) {
|
149 | return Promise.reject(new Error('Data argument is not an object'))
|
150 | }
|
151 |
|
152 | const writeArgs = lib.mapDataToTagArray(data)
|
153 | return this._executeCommand(file, args, writeArgs, debug)
|
154 | }
|
155 | }
|
156 |
|
157 | module.exports = {
|
158 | ExiftoolProcess,
|
159 | EXIFTOOL_PATH,
|
160 | events,
|
161 | }
|