mirror of
https://github.com/finos/SymphonyElectron.git
synced 2024-12-29 02:11:28 -06:00
150 lines
4.9 KiB
JavaScript
150 lines
4.9 KiB
JavaScript
'use strict';
|
|
|
|
const electron = require('electron');
|
|
const app = electron.app;
|
|
const childProcess = require('child_process');
|
|
const fs = require('fs');
|
|
const os = require('os');
|
|
const path = require('path');
|
|
|
|
const { isMac, isDevEnv } = require('../utils/misc.js');
|
|
|
|
// static ref to child process, only allow one screen snippet at time, so
|
|
// hold ref to prev, so can kill before starting next snippet.
|
|
let child;
|
|
|
|
/**
|
|
* Captures a user selected portion of the monitor and returns jpeg image
|
|
* encoded in base64 format.
|
|
*/
|
|
class ScreenSnippet {
|
|
/**
|
|
* Returns promise.
|
|
*
|
|
* If successful will resolves with jpeg image encoded in base64 format:
|
|
* {
|
|
* type: 'image/jpg;base64',
|
|
* data: base64-data
|
|
* }
|
|
*
|
|
* Otherwise if not successful will reject with object
|
|
* containing: { type: ['WARN','ERROR'], message: String }
|
|
*/
|
|
capture() {
|
|
return new Promise((resolve, reject) => {
|
|
let captureUtil, captureUtilArgs;
|
|
|
|
let tmpFilename = 'symphonyImage-' + Date.now() + '.jpg';
|
|
let tmpDir = os.tmpdir();
|
|
|
|
let outputFileName = path.join(tmpDir, tmpFilename);
|
|
|
|
if (isMac) {
|
|
// utilize Mac OSX built-in screencapture tool which has been
|
|
// available since OSX ver 10.2.
|
|
captureUtil = '/usr/sbin/screencapture';
|
|
captureUtilArgs = [ '-i', '-s', '-t', 'jpg', outputFileName ];
|
|
} else {
|
|
// use custom built windows screen capture tool
|
|
if (isDevEnv) {
|
|
// for dev env pick up tool from node nodules
|
|
captureUtil =
|
|
path.join(__dirname,
|
|
'../../node_modules/screen-snippet/bin/Release/ScreenSnippet.exe');
|
|
} else {
|
|
// for production gets installed next to exec.
|
|
let execPath = path.dirname(app.getPath('exe'));
|
|
captureUtil = path.join(execPath, 'ScreenSnippet.exe');
|
|
}
|
|
|
|
captureUtilArgs = [ outputFileName ];
|
|
}
|
|
|
|
// only allow one screen capture at a time.
|
|
if (child) {
|
|
child.kill();
|
|
}
|
|
|
|
child = childProcess.execFile(captureUtil, captureUtilArgs, (error) => {
|
|
// will be called when child process exits.
|
|
if (error && error.killed) {
|
|
// processs was killed, just resolve with no data.
|
|
resolve();
|
|
} else {
|
|
this._readResult(outputFileName, resolve, reject, error);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
// private methods below here
|
|
|
|
_readResult(outputFileName, resolve, reject, childProcessErr) {
|
|
fs.readFile(outputFileName, (readErr, data) => {
|
|
if (readErr) {
|
|
let returnErr;
|
|
if (readErr.code === 'ENOENT') {
|
|
// no such file exists, user likely aborted
|
|
// creating snippet. also include any error when
|
|
// creating child process.
|
|
returnErr = this._createWarn('file does not exist ' +
|
|
childProcessErr);
|
|
} else {
|
|
returnErr = this._createError(readErr + ',' +
|
|
childProcessErr);
|
|
}
|
|
|
|
reject(returnErr);
|
|
return;
|
|
}
|
|
|
|
if (!data) {
|
|
reject(this._createWarn('no file data provided'));
|
|
return;
|
|
}
|
|
|
|
try {
|
|
// convert binary data to base64 encoded string
|
|
let output = Buffer(data).toString('base64');
|
|
resolve({
|
|
type: 'image/jpg;base64',
|
|
data: output
|
|
});
|
|
} catch (error) {
|
|
reject(this._createError(error));
|
|
}
|
|
finally {
|
|
// remove tmp file (async)
|
|
fs.unlink(outputFileName, function(removeErr) {
|
|
// note: node complains if calling async
|
|
// func without callback.
|
|
/* eslint-disable no-console */
|
|
if (removeErr) {
|
|
console.error(
|
|
'error removing temp snippet file: ' +
|
|
outputFileName + ', err:' + removeErr);
|
|
}
|
|
/* eslint-enable no-console */
|
|
});
|
|
}
|
|
});
|
|
|
|
}
|
|
|
|
/* eslint-disable class-methods-use-this */
|
|
_createError(msg) {
|
|
var err = new Error(msg);
|
|
err.type = 'ERROR';
|
|
return err;
|
|
}
|
|
|
|
_createWarn(msg) {
|
|
var err = new Error(msg);
|
|
err.type = 'WARN';
|
|
return err;
|
|
}
|
|
/* eslint-enable class-methods-use-this */
|
|
}
|
|
|
|
module.exports = ScreenSnippet;
|