Repositorio del curso CCOM4030 el semestre B91 del proyecto Artesanías con el Instituto de Cultura

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. 'use strict';
  2. // @ts-check
  3. // ==================================================================================
  4. // utils.js
  5. // ----------------------------------------------------------------------------------
  6. // Description: System Information - library
  7. // for Node.js
  8. // Copyright: (c) 2014 - 2020
  9. // Author: Sebastian Hildebrandt
  10. // ----------------------------------------------------------------------------------
  11. // License: MIT
  12. // ==================================================================================
  13. // 0. helper functions
  14. // ----------------------------------------------------------------------------------
  15. const os = require('os');
  16. const fs = require('fs');
  17. const spawn = require('child_process').spawn;
  18. const exec = require('child_process').exec;
  19. const execSync = require('child_process').execSync;
  20. const util = require('util');
  21. let _platform = process.platform;
  22. const _linux = (_platform === 'linux');
  23. const _darwin = (_platform === 'darwin');
  24. const _windows = (_platform === 'win32');
  25. const _freebsd = (_platform === 'freebsd');
  26. const _openbsd = (_platform === 'openbsd');
  27. const _netbsd = (_platform === 'netbsd');
  28. // const _sunos = (_platform === 'sunos');
  29. let _cores = 0;
  30. let wmicPath = '';
  31. let codepage = '';
  32. const execOptsWin = {
  33. windowsHide: true,
  34. maxBuffer: 1024 * 20000,
  35. encoding: 'UTF-8',
  36. env: util._extend({}, process.env, { LANG: 'en_US.UTF-8' })
  37. };
  38. function toInt(value) {
  39. let result = parseInt(value, 10);
  40. if (isNaN(result)) {
  41. result = 0;
  42. }
  43. return result;
  44. }
  45. function isFunction(functionToCheck) {
  46. let getType = {};
  47. return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
  48. }
  49. function unique(obj) {
  50. let uniques = [];
  51. let stringify = {};
  52. for (let i = 0; i < obj.length; i++) {
  53. let keys = Object.keys(obj[i]);
  54. keys.sort(function (a, b) { return a - b; });
  55. let str = '';
  56. for (let j = 0; j < keys.length; j++) {
  57. str += JSON.stringify(keys[j]);
  58. str += JSON.stringify(obj[i][keys[j]]);
  59. }
  60. if (!{}.hasOwnProperty.call(stringify, str)) {
  61. uniques.push(obj[i]);
  62. stringify[str] = true;
  63. }
  64. }
  65. return uniques;
  66. }
  67. function sortByKey(array, keys) {
  68. return array.sort(function (a, b) {
  69. let x = '';
  70. let y = '';
  71. keys.forEach(function (key) {
  72. x = x + a[key]; y = y + b[key];
  73. });
  74. return ((x < y) ? -1 : ((x > y) ? 1 : 0));
  75. });
  76. }
  77. function cores() {
  78. if (_cores === 0) {
  79. _cores = os.cpus().length;
  80. }
  81. return _cores;
  82. }
  83. function getValue(lines, property, separator, trimmed) {
  84. separator = separator || ':';
  85. property = property.toLowerCase();
  86. trimmed = trimmed || false;
  87. for (let i = 0; i < lines.length; i++) {
  88. let line = lines[i].toLowerCase().replace(/\t/g, '');
  89. if (trimmed) {
  90. line = line.trim();
  91. }
  92. if (line.startsWith(property)) {
  93. const parts = lines[i].split(separator);
  94. if (parts.length >= 2) {
  95. parts.shift();
  96. return parts.join(separator).trim();
  97. } else {
  98. return '';
  99. }
  100. }
  101. }
  102. return '';
  103. }
  104. function decodeEscapeSequence(str, base) {
  105. base = base || 16;
  106. return str.replace(/\\x([0-9A-Fa-f]{2})/g, function () {
  107. return String.fromCharCode(parseInt(arguments[1], base));
  108. });
  109. }
  110. function detectSplit(str) {
  111. let seperator = '';
  112. let part = 0;
  113. str.split('').forEach(element => {
  114. if (element >= '0' && element <= '9') {
  115. if (part === 1) { part++; }
  116. } else {
  117. if (part === 0) { part++; }
  118. if (part === 1) {
  119. seperator += element;
  120. }
  121. }
  122. });
  123. return seperator;
  124. }
  125. function parseTime(t, pmDesignator) {
  126. pmDesignator = pmDesignator || '';
  127. t = t.toUpperCase();
  128. let hour = 0;
  129. let min = 0;
  130. let splitter = detectSplit(t);
  131. let parts = t.split(splitter);
  132. if (parts.length >= 2) {
  133. if (parts[2]) {
  134. parts[1] += parts[2];
  135. }
  136. let isPM = (parts[1] && (parts[1].toLowerCase().indexOf('pm') > -1) || (parts[1].toLowerCase().indexOf('p.m.') > -1) || (parts[1].toLowerCase().indexOf('p. m.') > -1) || (parts[1].toLowerCase().indexOf('n') > -1) || (parts[1].toLowerCase().indexOf('ch') > -1) || (parts[1].toLowerCase().indexOf('ös') > -1) || (pmDesignator && parts[1].toLowerCase().indexOf(pmDesignator) > -1));
  137. hour = parseInt(parts[0], 10);
  138. min = parseInt(parts[1], 10);
  139. hour = isPM && hour < 12 ? hour + 12 : hour;
  140. return ('0' + hour).substr(-2) + ':' + ('0' + min).substr(-2);
  141. }
  142. }
  143. function parseDateTime(dt, culture) {
  144. const result = {
  145. date: '',
  146. time: ''
  147. };
  148. culture = culture || {};
  149. let dateFormat = (culture.dateFormat || '').toLowerCase();
  150. let pmDesignator = (culture.pmDesignator || '');
  151. const parts = dt.split(' ');
  152. if (parts[0]) {
  153. if (parts[0].indexOf('/') >= 0) {
  154. // Dateformat: mm/dd/yyyy or dd/mm/yyyy or dd/mm/yy or yyyy/mm/dd
  155. const dtparts = parts[0].split('/');
  156. if (dtparts.length === 3) {
  157. if (dtparts[0].length === 4) {
  158. // Dateformat: yyyy/mm/dd
  159. result.date = dtparts[0] + '-' + ('0' + dtparts[1]).substr(-2) + '-' + ('0' + dtparts[2]).substr(-2);
  160. } else if (dtparts[2].length === 2) {
  161. if ((dateFormat.indexOf('/d/') > -1 || dateFormat.indexOf('/dd/') > -1)) {
  162. // Dateformat: mm/dd/yy
  163. result.date = '20' + dtparts[2] + '-' + ('0' + dtparts[1]).substr(-2) + '-' + ('0' + dtparts[0]).substr(-2);
  164. } else {
  165. // Dateformat: dd/mm/yy
  166. result.date = '20' + dtparts[2] + '-' + ('0' + dtparts[1]).substr(-2) + '-' + ('0' + dtparts[0]).substr(-2);
  167. }
  168. } else {
  169. // Dateformat: mm/dd/yyyy or dd/mm/yyyy
  170. const isEN = ((dt.toLowerCase().indexOf('pm') > -1) || (dt.toLowerCase().indexOf('p.m.') > -1) || (dt.toLowerCase().indexOf('p. m.') > -1) || (dt.toLowerCase().indexOf('am') > -1) || (dt.toLowerCase().indexOf('a.m.') > -1) || (dt.toLowerCase().indexOf('a. m.') > -1));
  171. if ((isEN || dateFormat.indexOf('/d/') > -1 || dateFormat.indexOf('/dd/') > -1) && dateFormat.indexOf('dd/') !== 0) {
  172. // Dateformat: mm/dd/yyyy
  173. result.date = dtparts[2] + '-' + ('0' + dtparts[0]).substr(-2) + '-' + ('0' + dtparts[1]).substr(-2);
  174. } else {
  175. // Dateformat: dd/mm/yyyy
  176. result.date = dtparts[2] + '-' + ('0' + dtparts[1]).substr(-2) + '-' + ('0' + dtparts[0]).substr(-2);
  177. }
  178. }
  179. }
  180. }
  181. if (parts[0].indexOf('.') >= 0) {
  182. const dtparts = parts[0].split('.');
  183. if (dtparts.length === 3) {
  184. if (dateFormat.indexOf('.d.') > -1 || dateFormat.indexOf('.dd.') > -1) {
  185. // Dateformat: mm.dd.yyyy
  186. result.date = dtparts[2] + '-' + ('0' + dtparts[0]).substr(-2) + '-' + ('0' + dtparts[1]).substr(-2);
  187. } else {
  188. // Dateformat: dd.mm.yyyy
  189. result.date = dtparts[2] + '-' + ('0' + dtparts[1]).substr(-2) + '-' + ('0' + dtparts[0]).substr(-2);
  190. }
  191. }
  192. }
  193. if (parts[0].indexOf('-') >= 0) {
  194. // Dateformat: yyyy-mm-dd
  195. const dtparts = parts[0].split('-');
  196. if (dtparts.length === 3) {
  197. result.date = dtparts[0] + '-' + ('0' + dtparts[1]).substr(-2) + '-' + ('0' + dtparts[2]).substr(-2);
  198. }
  199. }
  200. }
  201. if (parts[1]) {
  202. parts.shift();
  203. let time = parts.join(' ');
  204. result.time = parseTime(time, pmDesignator);
  205. }
  206. return result;
  207. }
  208. function parseHead(head, rights) {
  209. let space = (rights > 0);
  210. let count = 1;
  211. let from = 0;
  212. let to = 0;
  213. let result = [];
  214. for (let i = 0; i < head.length; i++) {
  215. if (count <= rights) {
  216. // if (head[i] === ' ' && !space) {
  217. if (/\s/.test(head[i]) && !space) {
  218. to = i - 1;
  219. result.push({
  220. from: from,
  221. to: to + 1,
  222. cap: head.substring(from, to + 1)
  223. });
  224. from = to + 2;
  225. count++;
  226. }
  227. space = head[i] === ' ';
  228. } else {
  229. if (!/\s/.test(head[i]) && space) {
  230. to = i - 1;
  231. if (from < to) {
  232. result.push({
  233. from: from,
  234. to: to,
  235. cap: head.substring(from, to)
  236. });
  237. }
  238. from = to + 1;
  239. count++;
  240. }
  241. space = head[i] === ' ';
  242. }
  243. }
  244. to = 1000;
  245. result.push({
  246. from: from,
  247. to: to,
  248. cap: head.substring(from, to)
  249. });
  250. let len = result.length;
  251. for (var i = 0; i < len; i++) {
  252. if (result[i].cap.replace(/\s/g, '').length === 0) {
  253. if (i + 1 < len) {
  254. result[i].to = result[i + 1].to;
  255. result[i].cap = result[i].cap + result[i + 1].cap;
  256. result.splice(i + 1, 1);
  257. len = len - 1;
  258. }
  259. }
  260. }
  261. return result;
  262. }
  263. function findObjectByKey(array, key, value) {
  264. for (let i = 0; i < array.length; i++) {
  265. if (array[i][key] === value) {
  266. return i;
  267. }
  268. }
  269. return -1;
  270. }
  271. function getWmic() {
  272. if (os.type() === 'Windows_NT' && !wmicPath) {
  273. wmicPath = process.env.WINDIR + '\\system32\\wbem\\wmic.exe';
  274. if (!fs.existsSync(wmicPath)) {
  275. try {
  276. const wmicPathArray = execSync('WHERE WMIC').toString().split('\r\n');
  277. if (wmicPathArray && wmicPathArray.length) {
  278. wmicPath = wmicPathArray[0];
  279. } else {
  280. wmicPath = 'wmic';
  281. }
  282. } catch (e) {
  283. wmicPath = 'wmic';
  284. }
  285. }
  286. }
  287. return wmicPath;
  288. }
  289. function wmic(command, options) {
  290. options = options || execOptsWin;
  291. return new Promise((resolve) => {
  292. process.nextTick(() => {
  293. try {
  294. exec(getWmic() + ' ' + command, options, function (error, stdout) {
  295. resolve(stdout, error);
  296. }).stdin.end();
  297. } catch (e) {
  298. resolve('', e);
  299. }
  300. });
  301. });
  302. }
  303. function getVboxmanage() {
  304. return _windows ? process.env.VBOX_INSTALL_PATH || process.env.VBOX_MSI_INSTALL_PATH + '\\VBoxManage.exe' + '" ' : 'vboxmanage';
  305. }
  306. function powerShell(cmd) {
  307. let result = '';
  308. return new Promise((resolve) => {
  309. process.nextTick(() => {
  310. try {
  311. const child = spawn('powershell.exe', ['-NoLogo', '-InputFormat', 'Text', '-NoExit', '-ExecutionPolicy', 'Unrestricted', '-Command', '-'], {
  312. stdio: 'pipe',
  313. windowsHide: true,
  314. maxBuffer: 1024 * 20000,
  315. encoding: 'UTF-8',
  316. env: util._extend({}, process.env, { LANG: 'en_US.UTF-8' })
  317. });
  318. if (child && !child.pid) {
  319. child.on('error', function () {
  320. resolve(result);
  321. });
  322. }
  323. if (child && child.pid) {
  324. child.stdout.on('data', function (data) {
  325. result = result + data.toString('utf8');
  326. });
  327. child.stderr.on('data', function () {
  328. child.kill();
  329. resolve(result);
  330. });
  331. child.on('close', function () {
  332. child.kill();
  333. resolve(result);
  334. });
  335. child.on('error', function () {
  336. child.kill();
  337. resolve(result);
  338. });
  339. try {
  340. child.stdin.write(cmd + os.EOL);
  341. child.stdin.write('exit' + os.EOL);
  342. child.stdin.end();
  343. } catch (e) {
  344. child.kill();
  345. resolve(result);
  346. }
  347. } else {
  348. resolve(result);
  349. }
  350. } catch (e) {
  351. resolve(result);
  352. }
  353. });
  354. });
  355. }
  356. function getCodepage() {
  357. if (_windows) {
  358. if (!codepage) {
  359. try {
  360. const stdout = execSync('chcp');
  361. const lines = stdout.toString().split('\r\n');
  362. const parts = lines[0].split(':');
  363. codepage = parts.length > 1 ? parts[1].replace('.', '') : '';
  364. } catch (err) {
  365. codepage = '437';
  366. }
  367. }
  368. return codepage;
  369. }
  370. if (_linux || _darwin || _freebsd || _openbsd || _netbsd) {
  371. if (!codepage) {
  372. try {
  373. const stdout = execSync('echo $LANG');
  374. const lines = stdout.toString().split('\r\n');
  375. const parts = lines[0].split('.');
  376. codepage = parts.length > 1 ? parts[1].trim() : '';
  377. if (!codepage) {
  378. codepage = 'UTF-8';
  379. }
  380. } catch (err) {
  381. codepage = 'UTF-8';
  382. }
  383. }
  384. return codepage;
  385. }
  386. }
  387. function isRaspberry() {
  388. const PI_MODEL_NO = [
  389. 'BCM2708',
  390. 'BCM2709',
  391. 'BCM2710',
  392. 'BCM2835',
  393. 'BCM2837B0'
  394. ];
  395. let cpuinfo = [];
  396. try {
  397. cpuinfo = fs.readFileSync('/proc/cpuinfo', { encoding: 'utf8' }).split('\n');
  398. } catch (e) {
  399. return false;
  400. }
  401. const hardware = getValue(cpuinfo, 'hardware');
  402. return (hardware && PI_MODEL_NO.indexOf(hardware) > -1);
  403. }
  404. function isRaspbian() {
  405. let osrelease = [];
  406. try {
  407. osrelease = fs.readFileSync('/etc/os-release', { encoding: 'utf8' }).split('\n');
  408. } catch (e) {
  409. return false;
  410. }
  411. const id = getValue(osrelease, 'id');
  412. return (id && id.indexOf('raspbian') > -1);
  413. }
  414. function execWin(cmd, opts, callback) {
  415. if (!callback) {
  416. callback = opts;
  417. opts = execOptsWin;
  418. }
  419. let newCmd = 'chcp 65001 > nul && cmd /C ' + cmd + ' && chcp ' + codepage + ' > nul';
  420. exec(newCmd, opts, function (error, stdout) {
  421. callback(error, stdout);
  422. });
  423. }
  424. function darwinXcodeExists() {
  425. const cmdLineToolsExists = fs.existsSync('/Library/Developer/CommandLineTools/usr/bin/');
  426. const xcodeAppExists = fs.existsSync('/Applications/Xcode.app/Contents/Developer/Tools');
  427. const xcodeExists = fs.existsSync('/Library/Developer/Xcode/');
  428. return (cmdLineToolsExists || xcodeExists || xcodeAppExists);
  429. }
  430. function nanoSeconds() {
  431. const time = process.hrtime();
  432. if (!Array.isArray(time) || time.length !== 2) {
  433. return 0;
  434. }
  435. return +time[0] * 1e9 + +time[1];
  436. }
  437. function countUniqueLines(lines, startingWith) {
  438. startingWith = startingWith || '';
  439. const uniqueLines = [];
  440. lines.forEach(line => {
  441. if (line.startsWith(startingWith)) {
  442. if (uniqueLines.indexOf(line) === -1) {
  443. uniqueLines.push(line);
  444. }
  445. }
  446. });
  447. return uniqueLines.length;
  448. }
  449. function countLines(lines, startingWith) {
  450. startingWith = startingWith || '';
  451. const uniqueLines = [];
  452. lines.forEach(line => {
  453. if (line.startsWith(startingWith)) {
  454. uniqueLines.push(line);
  455. }
  456. });
  457. return uniqueLines.length;
  458. }
  459. function sanitizeShellString(str) {
  460. let result = str;
  461. result = result.replace(/>/g, '');
  462. result = result.replace(/</g, '');
  463. result = result.replace(/\*/g, '');
  464. result = result.replace(/\?/g, '');
  465. result = result.replace(/\[/g, '');
  466. result = result.replace(/\]/g, '');
  467. result = result.replace(/\|/g, '');
  468. result = result.replace(/\`/g, '');
  469. result = result.replace(/\$/g, '');
  470. result = result.replace(/;/g, '');
  471. result = result.replace(/&/g, '');
  472. result = result.replace(/\)/g, '');
  473. result = result.replace(/\(/g, '');
  474. result = result.replace(/\$/g, '');
  475. result = result.replace(/#/g, '');
  476. result = result.replace(/\\/g, '');
  477. result = result.replace(/\t/g, '');
  478. result = result.replace(/\n/g, '');
  479. result = result.replace(/\"/g, '');
  480. return result;
  481. }
  482. function noop() { }
  483. exports.toInt = toInt;
  484. exports.execOptsWin = execOptsWin;
  485. exports.getCodepage = getCodepage;
  486. exports.execWin = execWin;
  487. exports.isFunction = isFunction;
  488. exports.unique = unique;
  489. exports.sortByKey = sortByKey;
  490. exports.cores = cores;
  491. exports.getValue = getValue;
  492. exports.decodeEscapeSequence = decodeEscapeSequence;
  493. exports.parseDateTime = parseDateTime;
  494. exports.parseHead = parseHead;
  495. exports.findObjectByKey = findObjectByKey;
  496. exports.getWmic = getWmic;
  497. exports.wmic = wmic;
  498. exports.darwinXcodeExists = darwinXcodeExists;
  499. exports.getVboxmanage = getVboxmanage;
  500. exports.powerShell = powerShell;
  501. exports.nanoSeconds = nanoSeconds;
  502. exports.countUniqueLines = countUniqueLines;
  503. exports.countLines = countLines;
  504. exports.noop = noop;
  505. exports.isRaspberry = isRaspberry;
  506. exports.isRaspbian = isRaspbian;
  507. exports.sanitizeShellString = sanitizeShellString;