Software zum Installieren eines Smart-Mirror Frameworks , zum Nutzen von hochschulrelevanten Informationen, auf einem Raspberry-Pi.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.js 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. 'use strict';
  2. const fs = require('fs');
  3. const path = require('path');
  4. const crypto = require('crypto');
  5. const isStream = require('is-stream');
  6. const {Worker} = (() => {
  7. try {
  8. return require('worker_threads');
  9. } catch (_) {
  10. return {};
  11. }
  12. })();
  13. let worker; // Lazy
  14. let taskIdCounter = 0;
  15. const tasks = new Map();
  16. const recreateWorkerError = sourceError => {
  17. const error = new Error(sourceError.message);
  18. for (const [key, value] of Object.entries(sourceError)) {
  19. if (key !== 'message') {
  20. error[key] = value;
  21. }
  22. }
  23. return error;
  24. };
  25. const createWorker = () => {
  26. worker = new Worker(path.join(__dirname, 'thread.js'));
  27. worker.on('message', message => {
  28. const task = tasks.get(message.id);
  29. tasks.delete(message.id);
  30. if (tasks.size === 0) {
  31. worker.unref();
  32. }
  33. if (message.error === undefined) {
  34. task.resolve(message.value);
  35. } else {
  36. task.reject(recreateWorkerError(message.error));
  37. }
  38. });
  39. worker.on('error', error => {
  40. // Any error here is effectively an equivalent of segfault, and have no scope, so we just throw it on callback level
  41. throw error;
  42. });
  43. };
  44. const taskWorker = (method, args, transferList) => new Promise((resolve, reject) => {
  45. const id = taskIdCounter++;
  46. tasks.set(id, {resolve, reject});
  47. if (worker === undefined) {
  48. createWorker();
  49. }
  50. worker.ref();
  51. worker.postMessage({id, method, args}, transferList);
  52. });
  53. const hasha = (input, options = {}) => {
  54. let outputEncoding = options.encoding || 'hex';
  55. if (outputEncoding === 'buffer') {
  56. outputEncoding = undefined;
  57. }
  58. const hash = crypto.createHash(options.algorithm || 'sha512');
  59. const update = buffer => {
  60. const inputEncoding = typeof buffer === 'string' ? 'utf8' : undefined;
  61. hash.update(buffer, inputEncoding);
  62. };
  63. if (Array.isArray(input)) {
  64. input.forEach(update);
  65. } else {
  66. update(input);
  67. }
  68. return hash.digest(outputEncoding);
  69. };
  70. hasha.stream = (options = {}) => {
  71. let outputEncoding = options.encoding || 'hex';
  72. if (outputEncoding === 'buffer') {
  73. outputEncoding = undefined;
  74. }
  75. const stream = crypto.createHash(options.algorithm || 'sha512');
  76. stream.setEncoding(outputEncoding);
  77. return stream;
  78. };
  79. hasha.fromStream = async (stream, options = {}) => {
  80. if (!isStream(stream)) {
  81. throw new TypeError('Expected a stream');
  82. }
  83. return new Promise((resolve, reject) => {
  84. // TODO: Use `stream.pipeline` and `stream.finished` when targeting Node.js 10
  85. stream
  86. .on('error', reject)
  87. .pipe(hasha.stream(options))
  88. .on('error', reject)
  89. .on('finish', function () {
  90. resolve(this.read());
  91. });
  92. });
  93. };
  94. if (Worker === undefined) {
  95. hasha.fromFile = async (filePath, options) => hasha.fromStream(fs.createReadStream(filePath), options);
  96. hasha.async = async (input, options) => hasha(input, options);
  97. } else {
  98. hasha.fromFile = async (filePath, {algorithm = 'sha512', encoding = 'hex'} = {}) => {
  99. const hash = await taskWorker('hashFile', [algorithm, filePath]);
  100. if (encoding === 'buffer') {
  101. return Buffer.from(hash);
  102. }
  103. return Buffer.from(hash).toString(encoding);
  104. };
  105. hasha.async = async (input, {algorithm = 'sha512', encoding = 'hex'} = {}) => {
  106. if (encoding === 'buffer') {
  107. encoding = undefined;
  108. }
  109. const hash = await taskWorker('hash', [algorithm, input]);
  110. if (encoding === undefined) {
  111. return Buffer.from(hash);
  112. }
  113. return Buffer.from(hash).toString(encoding);
  114. };
  115. }
  116. hasha.fromFileSync = (filePath, options) => hasha(fs.readFileSync(filePath), options);
  117. module.exports = hasha;