diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..ee933a7 --- /dev/null +++ b/docs/README.md @@ -0,0 +1 @@ +# Electron 模板:远程控制、进程/数据监控、软件/服务管理、网页插件 diff --git a/node-desktop-capturer/.gitignore b/node-desktop-capturer/.gitignore new file mode 100644 index 0000000..cb4e535 --- /dev/null +++ b/node-desktop-capturer/.gitignore @@ -0,0 +1,31 @@ +# Created by .ignore support plugin (hsz.mobi) +### Node template +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git +node_modules + + diff --git a/node-desktop-capturer/.npmignore b/node-desktop-capturer/.npmignore new file mode 100644 index 0000000..8962746 --- /dev/null +++ b/node-desktop-capturer/.npmignore @@ -0,0 +1,33 @@ +# Created by .ignore support plugin (hsz.mobi) +### Node template +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git +node_modules + +# IntelliJ +.idea +*.iml \ No newline at end of file diff --git a/node-desktop-capturer/LICENSE b/node-desktop-capturer/LICENSE new file mode 100644 index 0000000..f9dfd77 --- /dev/null +++ b/node-desktop-capturer/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 johnvmt + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/node-desktop-capturer/README.md b/node-desktop-capturer/README.md new file mode 100755 index 0000000..b0a7b99 --- /dev/null +++ b/node-desktop-capturer/README.md @@ -0,0 +1,64 @@ +# node-node-desktop-capturer + +Take a screenshot of the computer on which Node is running, using platform-specific external tools included with the package. + +Supports Windows (win32), OSX (darwin) and Linux platforms + +- Windows version uses nircmd (http://nircmd.nirsoft.net) +- Linux version uses scrot + +## How to install + +This is a forked version of a module, so to install it in your project use `yarn add https://github.com/jhotujec/node-node-desktop-capturer` + +## Available Options + +- quality: JPEG quality (0 to 100) +- width: use in conjunction with height, or by itself to maintain aspect ratio +- height: use in conjunction with width, or by itself to maintain aspect ratio + +## Examples + +### Full resolution + +```js +var screenshot = require("node-desktop-capturer"); + +screenshot("screenshot.png", function (error, complete) { + if (error) console.log("Screenshot failed", error); + else console.log("Screenshot succeeded"); +}); +``` + +### Resize to 400px wide, maintain aspect ratio + +```js +var screenshot = require("node-desktop-capturer"); + +screenshot("screenshot.png", { width: 400 }, function (error, complete) { + if (error) console.log("Screenshot failed", error); + else console.log("Screenshot succeeded"); +}); +``` + +### Resize to 400x300, set JPG quality to 60% + +```js +var screenshot = require("node-desktop-capturer"); + +screenshot( + "screenshot.jpg", + { width: 400, height: 300, quality: 60 }, + function (error, complete) { + if (error) console.log("Screenshot failed", error); + else console.log("Screenshot succeeded"); + } +); +``` + +## TODOs + +- Tests +- Multi-screen support +- Cropping +- Return contents of image, rather than writing file diff --git a/node-desktop-capturer/capture/bin/nircmd.exe b/node-desktop-capturer/capture/bin/nircmd.exe new file mode 100755 index 0000000..54f8436 Binary files /dev/null and b/node-desktop-capturer/capture/bin/nircmd.exe differ diff --git a/node-desktop-capturer/capture/bin/scrot/LICENSE b/node-desktop-capturer/capture/bin/scrot/LICENSE new file mode 100644 index 0000000..b59bd3c --- /dev/null +++ b/node-desktop-capturer/capture/bin/scrot/LICENSE @@ -0,0 +1,12 @@ +Copyright Tom Gilbert 2000 + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies of the Software, its documentation and marketing & publicity materials, and acknowledgment shall be given +in the documentation, materials and software packages that this Software was used. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONIN‐ +FRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH +THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/node-desktop-capturer/capture/bin/scrot/scrot b/node-desktop-capturer/capture/bin/scrot/scrot new file mode 100755 index 0000000..e6cabbd Binary files /dev/null and b/node-desktop-capturer/capture/bin/scrot/scrot differ diff --git a/node-desktop-capturer/capture/darwin.js b/node-desktop-capturer/capture/darwin.js new file mode 100644 index 0000000..a71a55b --- /dev/null +++ b/node-desktop-capturer/capture/darwin.js @@ -0,0 +1,59 @@ +module.exports = function(options, callback) { + var path = require('path'); + var fs = require('fs'); + var childProcess = require('child_process'); + + // due to bug in jpgjs processing OSX jpg images https://github.com/notmasteryet/jpgjs/issues/34 + // when requesting JPG capture as PNG, so JIMP can read it + var ext = extension(options.output); + if(ext === "jpeg" || ext === "jpg") { + options.intermediate = path.resolve(path.join(__dirname.replace('app.asar', 'app.asar.unpacked'), uniqueId() + ".png")); // create an intermediate file that can be processed, then deleted + capture(options.intermediate, callbackReturn); + } + else + capture(options.output, callbackReturn); // when jpegjs bug fixed, only need this line + + function callbackReturn(error, success) { + // called from capture + // callback with options, in case options added + callback(error, options); + } + + function uniqueId() { + function s4() { + return Math.floor((1 + Math.random()) * 0x10000) + .toString(16) + .substring(1); + } + return s4() + s4() + '-' + s4() + '-' + s4() + '-' + + s4() + '-' + s4() + s4() + s4(); + } + + function extension(file) { + return path.extname(file).toLowerCase().substring(1); + } + + function capture(output, callback) { + var cmd = "screencapture"; + var args = [ + // will create PNG by default + "-t", + path.extname(output).toLowerCase().substring(1), + "-x", + output + ]; + + var captureChild = childProcess.spawn(cmd, args); + + captureChild.on('close', function(error) { + if (error) + callback(error.toString()); + else + callback(); + }); + + captureChild.stderr.on('data', function(data) { + callback(data.toString()); + }); + } +}; \ No newline at end of file diff --git a/node-desktop-capturer/capture/linux.js b/node-desktop-capturer/capture/linux.js new file mode 100755 index 0000000..b4a9b67 --- /dev/null +++ b/node-desktop-capturer/capture/linux.js @@ -0,0 +1,17 @@ +module.exports = function(options, callback) { + + var fs = require('fs'); + var childProcess = require('child_process'); + var path = require('path'); + + var scrot = childProcess.spawn(path.join(__dirname, "bin", "scrot", "scrot"), [options.output]); + scrot.on('close', function(code, signal) { + try { + fs.statSync(options.output); + callback(null, options); // callback with options, in case options added + } + catch(error) { + callback("file_not_found", null); + } + }); +}; \ No newline at end of file diff --git a/node-desktop-capturer/capture/win32.js b/node-desktop-capturer/capture/win32.js new file mode 100755 index 0000000..1220c1b --- /dev/null +++ b/node-desktop-capturer/capture/win32.js @@ -0,0 +1,18 @@ +module.exports = function(options, callback) { + + var fs = require('fs'); + var childProcess = require('child_process'); + var path = require('path'); + + var nircmd = childProcess.spawn(path.join(__dirname.replace('app.asar', 'app.asar.unpacked'), "bin", "nircmd.exe"), ["savescreenshot", options.output]); + + nircmd.on('close', function(code, signal) { + try { + fs.statSync(options.output); + callback(null, options); // callback with options, in case options added + } + catch(error) { + callback("file_not_found", null); + } + }); +}; \ No newline at end of file diff --git a/node-desktop-capturer/module.js b/node-desktop-capturer/module.js new file mode 100755 index 0000000..fdaee33 --- /dev/null +++ b/node-desktop-capturer/module.js @@ -0,0 +1,100 @@ +module.exports = function() { + return new Screenshot(arguments); +}; + +var path = require('flavored-path'); +var jimp = require('jimp'); +var fs = require('fs'); + +function Screenshot(args) { + var config = this.parseArgs(args); + var self = this; + + try { + require("./capture/" + process.platform + ".js")(config.options, function(error, options) { + // TODO add option for string, rather than file + if(error && typeof config.callback === "function") + config.callback(error, null); + else if(!error) { + if (typeof options.intermediate === "string") { + self.processImage(options.intermediate, options.output, options, function (error, success) { + fs.unlink(options.intermediate, handleCallback); // delete intermediate + }); + } + else + self.processImage(options.output, options.output, options, handleCallback); + } + }); + } + catch(error) { + if(typeof error == "object" && typeof error.code === "string" && error.code === "MODULE_NOT_FOUND") + handleCallback("unsupported_platform"); + } + + function handleCallback(error, success) { + if(typeof config.callback === "function") { + if(typeof success === "undefined") + success = !error; + config.callback(error, success); + } + } +} + +Screenshot.prototype.processImage = function(input, output, options, callback) { + if(typeof options.width !== "number" && typeof options.height !== "number" && typeof options.quality !== "number") // no processing required + callback(null); + else { + new jimp(input, function (err, image) { + if(typeof options.width === "number") + var resWidth = Math.floor(options.width); + if(typeof options.height === "number") + var resHeight = Math.floor(options.height); + + if(typeof resWidth === "number" && typeof resHeight !== "number") // resize to width, maintain aspect ratio + var resHeight = Math.floor(image.bitmap.height * (resWidth / image.bitmap.width)); + else if(typeof resHeight === "number" && typeof resWidth !== "number") // resize to height, maintain aspect ratio + var resWidth = Math.floor(image.bitmap.width * (resHeight / image.bitmap.height)); + + try { + image.resize(resWidth, resHeight); + + if(typeof options.quality === "number" && options.quality >= 0 && options.quality <= 100) + image.quality(Math.floor(options.quality)); // only works with JPEGs + + image.write(output, callback); + } + catch(error) { + callback(error); + } + }); + } +}; + +Screenshot.prototype.parseArgs = function(args) { + var config = {options: {}}; + + for(var property in args) { + if (args.hasOwnProperty(property)) { + switch(typeof args[property]) { + case "string": + var file = args[property]; + break; + case "function": + config.callback = args[property]; + break; + case "object": + if(args[property] != null) + config.options = args[property]; + break; + } + } + } + + if(typeof file === "string") + config.options.output = file; + + if(typeof config.options.output === "string") + config.options.output = path.normalize(config.options.output); + + return config; +}; diff --git a/node-desktop-capturer/package.json b/node-desktop-capturer/package.json new file mode 100755 index 0000000..79145c2 --- /dev/null +++ b/node-desktop-capturer/package.json @@ -0,0 +1,19 @@ +{ + "name": "node-desktop-capturer", + "version": "0.0.1", + "description": "Cross-platform screenshot module, using external tools", + "license": "MIT", + "author": { + "name": "John Murphy-Teixidor", + "email": "johnvmt@gmail.com" + }, + "repository": { + "type": "git", + "url": "https://github.com/FE-Kits/electron-screen-sharing" + }, + "dependencies": { + "jimp": "0.2.x", + "flavored-path": "0.0.x" + }, + "main": "module.js" +} diff --git a/websocket-proxy/README.md b/websocket-proxy/README.md new file mode 100644 index 0000000..1918e9b --- /dev/null +++ b/websocket-proxy/README.md @@ -0,0 +1 @@ +# websocket-proxy