UNPKG

3.26 kBJavaScriptView Raw
1'use strict';
2const cp = require('child_process');
3const fs = require('fs');
4const path = require('path');
5const EventEmitter = require('events');
6const EOL = require('os').EOL;
7const lib = require('./lib');
8const BeginReadySnitch = require('./begin-ready-snitch')
9
10const EXIFTOOL_PATH = 'exiftool';
11
12const events = {
13 OPEN: 'exiftool_opened',
14 EXIT: 'exiftool_exit',
15}
16
17class ExiftoolProcess extends EventEmitter {
18
19 /**
20 * Create an instance of ExoftoolProcess class.
21 * @param {string} [bin=vendor/Image-ExifTool/exiftool] - path to executable
22 */
23 constructor(bin) {
24 super();
25 this._bin = bin !== undefined ? bin : EXIFTOOL_PATH;
26 this._process = undefined;
27 this._open = false;
28 }
29
30 /**
31 * Close the exiftool process by passing -stay_open false.
32 * @returns {Promise} a promise to stop the process.
33 */
34 close() {
35 if (!this._open) {
36 return Promise.reject(new Error('Exiftool process is not open'));
37 }
38 return lib.close(this._process)
39 .then(() => {
40 this._open = false;
41 });
42 }
43
44 /**
45 * Spawn exfitool process with -stay_open True -@ - arguments.
46 * @returns {Promise} a promise to spawn exiftool in stay_open mode.
47 */
48 open() {
49 if (this._open) {
50 return Promise.reject(new Error('Exiftool process is already open'));
51 }
52 return lib.spawn(this._bin).then((process) => {
53 //console.log(`Started exiftool process %s`, process.pid);
54 this.emit(events.OPEN, process.pid);
55 this._process = process;
56
57 process.on('exit', () => this._exitListener());
58
59 this._stdoutSnitch = new BeginReadySnitch(process.stdout)
60 this._stderrSnitch = new BeginReadySnitch(process.stderr)
61
62 this._open = true;
63
64 return process.pid;
65 });
66 }
67
68 _exitListener() {
69 //console.log('exfitool process exit');
70 this.emit(events.EXIT);
71 this._open = false; // try to respawn?
72 }
73
74 /**
75 * Checks if process is opens.
76 * @returns {boolean} true if open and false otherwise.
77 */
78 get isOpen() {
79 return this._open;
80 }
81
82 _executeCommand(command, args) {
83 //test this!
84 if (!this._open) {
85 return Promise.reject(new Error('exiftool is not open'));
86 }
87 if (this._process.signalCode === 'SIGTERM') {
88 return Promise.reject(new Error('Could not connect to the exiftool process'));
89 }
90
91 return lib.executeCommand(this._process, this._stdoutSnitch, this._stderrSnitch, command, args);
92 }
93
94 /**
95 * Read metadata of a file or directory.
96 * @param {string} file - path to the file or directory
97 * @param {Array} args - any additional arguments, e.g.,
98 * ['Orientation#'] to report Orientation only, or ['-FileSize'] to exclude FileSize
99 * @returns {Promise} a promise resolved with data (array or null) and error
100 * (string or null) properties from stdout and stderr of exiftool.
101 */
102 readMetadata(file, args) {
103 return this._executeCommand(file, args);
104 }
105}
106
107module.exports = {
108 ExiftoolProcess,
109 EXIFTOOL_PATH,
110 events,
111}