utils.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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 bufferRemoveZeroes(buf) {
  14. const i = buf.indexOf(0);
  15. if (i >= 0) {
  16. return buf.slice(0, i);
  17. }
  18. return buf;
  19. }
  20. function getFileHash(filename, hashName, enc) {
  21. return new Promise((resolve, reject) => {
  22. const hash = crypto.createHash(hashName);
  23. const rs = fs.createReadStream(filename);
  24. rs.on('error', reject);
  25. rs.on('data', chunk => hash.update(chunk));
  26. rs.on('end', () => resolve(hash.digest(enc)));
  27. });
  28. }
  29. function sleep(ms) {
  30. return new Promise(resolve => setTimeout(resolve, ms));
  31. }
  32. function randomHexString(len) {
  33. return crypto.randomBytes(len).toString('hex')
  34. }
  35. async function touchFile(filename) {
  36. await fs.utimes(filename, Date.now()/1000, Date.now()/1000);
  37. }
  38. function spawnProcess(cmd, opts) {
  39. let {args, killAfter, onData, abort} = opts;
  40. killAfter = (killAfter ? killAfter : 120);//seconds
  41. onData = (onData ? onData : () => {});
  42. args = (args ? args : []);
  43. return new Promise((resolve, reject) => { (async() => {
  44. let resolved = false;
  45. const proc = spawn(cmd, args, {detached: true});
  46. let stdout = '';
  47. proc.stdout.on('data', (data) => {
  48. stdout += data;
  49. onData(data);
  50. });
  51. let stderr = '';
  52. proc.stderr.on('data', (data) => {
  53. stderr += data;
  54. onData(data);
  55. });
  56. proc.on('close', (code) => {
  57. resolved = true;
  58. resolve({status: 'close', code, stdout, stderr});
  59. });
  60. proc.on('error', (error) => {
  61. reject({status: 'error', error, stdout, stderr});
  62. });
  63. while (!resolved) {
  64. await sleep(1000);
  65. killAfter -= 1;
  66. if (killAfter <= 0 || (abort && abort())) {
  67. process.kill(proc.pid);
  68. if (killAfter <= 0) {
  69. reject({status: 'killed', stdout, stderr});
  70. } else {
  71. reject({status: 'abort', stdout, stderr});
  72. }
  73. break;
  74. }
  75. }
  76. })().catch(reject); });
  77. }
  78. module.exports = {
  79. toBase36,
  80. fromBase36,
  81. bufferRemoveZeroes,
  82. getFileHash,
  83. sleep,
  84. randomHexString,
  85. touchFile,
  86. spawnProcess
  87. };