utils.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. const { spawn } = require('child_process');
  2. const fs = require('fs-extra');
  3. const crypto = require('crypto');
  4. const baseX = require('base-x');
  5. const BASE36 = '0123456789abcdefghijklmnopqrstuvwxyz';
  6. const bs36 = baseX(BASE36);
  7. function toBase36(data) {
  8. return bs36.encode(Buffer.from(data));
  9. }
  10. function fromBase36(data) {
  11. return bs36.decode(data);
  12. }
  13. function getFileHash(filename, hashName, enc) {
  14. return new Promise((resolve, reject) => {
  15. const hash = crypto.createHash(hashName);
  16. const rs = fs.createReadStream(filename);
  17. rs.on('error', reject);
  18. rs.on('data', chunk => hash.update(chunk));
  19. rs.on('end', () => resolve(hash.digest(enc)));
  20. });
  21. }
  22. function sleep(ms) {
  23. return new Promise(resolve => setTimeout(resolve, ms));
  24. }
  25. function randomHexString(len) {
  26. return crypto.randomBytes(len).toString('hex')
  27. }
  28. async function touchFile(filename) {
  29. await fs.utimes(filename, Date.now()/1000, Date.now()/1000);
  30. }
  31. function spawnProcess(cmd, opts) {
  32. let {args, killAfter, onData, abort} = opts;
  33. killAfter = (killAfter ? killAfter : 120);//seconds
  34. onData = (onData ? onData : () => {});
  35. args = (args ? args : []);
  36. return new Promise((resolve, reject) => { (async() => {
  37. let resolved = false;
  38. const proc = spawn(cmd, args, {detached: true});
  39. let stdout = '';
  40. proc.stdout.on('data', (data) => {
  41. stdout += data;
  42. onData(data);
  43. });
  44. let stderr = '';
  45. proc.stderr.on('data', (data) => {
  46. stderr += data;
  47. onData(data);
  48. });
  49. proc.on('close', (code) => {
  50. resolved = true;
  51. resolve({status: 'close', code, stdout, stderr});
  52. });
  53. proc.on('error', (error) => {
  54. reject({status: 'error', error, stdout, stderr});
  55. });
  56. while (!resolved) {
  57. await sleep(1000);
  58. killAfter -= 1;
  59. if (killAfter <= 0 || (abort && abort())) {
  60. process.kill(proc.pid);
  61. if (killAfter <= 0) {
  62. reject({status: 'killed', stdout, stderr});
  63. } else {
  64. reject({status: 'abort', stdout, stderr});
  65. }
  66. break;
  67. }
  68. }
  69. })().catch(reject); });
  70. }
  71. module.exports = {
  72. toBase36,
  73. fromBase36,
  74. getFileHash,
  75. sleep,
  76. randomHexString,
  77. touchFile,
  78. spawnProcess
  79. };