Best JavaScript code snippet using qawolf
snip.js
Source:snip.js
1// various tools by Adrien Joly2// tests: tests/tess-snips.js3var fs = require('fs');4var urlModule = require('url');5var http = require('http');6var https = require('https');7var querystring = require('querystring');8var firstWeek = new Date('Monday January 3, 2011 08:00'); // week #1 = 1st of january 20109// privacy helper: anonymise email address10exports.formatEmail = function (emailAddr) {11 if (typeof emailAddr !== 'string' || emailAddr.length < 1)12 return '<invalid_email>';13 const [name, domain] = emailAddr.split('@');14 return name.substring(0, 1).concat('*********@').concat(domain);15};16exports.formatPrivateFields = (obj) => {17 if (typeof obj !== 'object') return obj;18 const res = { ...obj };19 if (typeof obj.email === 'string') res.email = exports.formatEmail(obj.email);20 if (typeof obj.md5 === 'string') res.md5 = '<MD5_HASH>';21 return res;22};23// privacy-enforcing console.log helper24exports.console = {25 log(...args) {26 const filteredArgs = args.map(exports.formatPrivateFields);27 console.log(...filteredArgs);28 },29};30exports.getWeekNumber = function (date) {31 return date && Math.floor(1 + (date - firstWeek) / 1000 / 60 / 60 / 24 / 7);32};33exports.weekNumberToDate = function (weekNumber) {34 return new Date(firstWeek.getTime() + 7 * 24 * 60 * 60 * 1000 * weekNumber);35};36exports.forEachFileLine = function (fileName, lineHandler) {37 var buffer = '';38 function processBuffer(flush) {39 var parts = buffer.replace('\r', '').split('\n');40 buffer = !flush && parts.pop();41 parts.forEach(lineHandler);42 }43 fs.createReadStream(fileName)44 .addListener('data', function (data) {45 buffer += data.toString();46 processBuffer();47 })48 .addListener('end', function () {49 processBuffer(true);50 lineHandler();51 });52};53// =========================================================================54// string manipulation / regular expressions55exports.removeAccents = function (str) {56 return !str57 ? ''58 : str59 .replace(/[à âä]/gi, 'a')60 .replace(/[éèêë]/gi, 'e')61 .replace(/[îï]/gi, 'i')62 .replace(/[ôö]/gi, 'o')63 .replace(/[ùûü]/gi, 'u');64};65//var regexUrl = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;66var regexUrl =67 /(\b(https?|ftp|file):\/\/([-A-Z0-9+&@#$*'()%?=~_|!:,.;]*)[-A-Z0-9+&@#/%?=~_|!:,.;]*[-A-Z0-9+&@#/%=~_|])/gi;68var regexUrl2 = /(\b(https?|ftp|file):\/\/([^/\s]*)[^\s]*)/gi;69exports.replaceURLWithHTMLLinks = function (text) {70 return String(text || '').replace(regexUrl2, "<a href='$1'>$3...</a>");71};72exports.replaceURLWithFullHTMLLinks = function (text) {73 return String(text || '').replace(regexUrl, "<a href='$1'>$1</a>");74};75exports.shortenURLs = function (text) {76 return String(text || '').replace(regexUrl, '$3...');77};78// source: http://css-tricks.com/snippets/javascript/htmlentities-for-javascript/79exports.htmlEntities = function (str) {80 return String(str || '')81 .replace(/&/g, '&')82 .replace(/</g, '<')83 .replace(/>/g, '>')84 .replace(/"/g, '"');85};86exports.addSlashes = function (str) {87 return typeof str == 'string'88 ? str.replace(/\\/g, '\\\\').replace(/'/g, "\\'").replace(/"/g, '\\"')89 : str;90};91exports.sanitizeJsStringInHtml = function (str) {92 return exports.htmlEntities(exports.addSlashes(str || ''));93};94exports.getSafeOpenwhydURL = function (url, safeUrlPrefix) {95 if (typeof url !== 'string' || url.includes('<script')) return false;96 const fullURL = new URL(url, safeUrlPrefix);97 if (`${fullURL.protocol}//${fullURL.host}` !== safeUrlPrefix) return false;98 else return fullURL;99};100var timeScales = [101 { 'minute(s)': 60 },102 { 'hour(s)': 60 },103 { 'day(s)': 24 },104 { 'month(s)': 30 },105 { 'year(s)': 12 },106];107exports.renderTimestamp = function (timestamp) {108 var t = timestamp / 1000,109 lastScale = 'second(s)';110 for (let i in timeScales) {111 var scaleTitle;112 for (scaleTitle in timeScales[i]);113 var scaleVal = timeScales[i][scaleTitle];114 if (t / scaleVal < 1) break;115 t = t / scaleVal;116 lastScale = scaleTitle;117 }118 var rounded = Math.round(t);119 return rounded + ' ' + lastScale.replace(/\(s\)/g, rounded > 1 ? 's' : '');120};121exports.MONTHS_SHORT = [122 'Jan',123 'Feb',124 'Mar',125 'Apr',126 'May',127 'Jun',128 'Jul',129 'Aug',130 'Sep',131 'Oct',132 'Nov',133 'Dec',134];135exports.renderShortMonthYear = function (date) {136 var t = new Date(date);137 var sameYear = false; //(new Date()).getFullYear() == t.getFullYear();138 return (139 exports.MONTHS_SHORT[t.getMonth()] + (sameYear ? '' : ' ' + t.getFullYear())140 );141};142exports.padNumber = function (str, n) {143 var ret = '' + str;144 while (145 ret.length < n // pad with leading zeroes146 )147 ret = '0' + ret;148 return ret;149};150exports.renderTime = function (date) {151 var t = new Date(date);152 return t.getHours() + ':' + exports.padNumber(t.getMinutes(), 2);153};154// minimal sanitization of function name: remove javascript's special / control characters155exports.sanitizeJsIdentifier = function (id) {156 return ('' + id).replace(/\/\\\n\(\)\[\];\./g, ' ');157};158exports.renderJsCallback = function (fctName, obj) {159 return (160 exports.sanitizeJsIdentifier(fctName) +161 '(' +162 (typeof obj == 'object' ? JSON.stringify(obj) : '"' + obj + '"') +163 ');'164 );165};166// =========================================================================167// music track related functions168exports.cleanTrackName = function (str) {169 return !str170 ? ''171 : str172 .trim()173 .replace(/^\d+([-./\\]\d+)+\s+/, '') // remove prefixing date174 .replace(/^\d+[.]+\s+/, '') // remove prefixing track number175 .replace(/^#\d+\s+/, '') // remove prefixing rank176 .replace(/\([^)]*\)/g, '') // remove parentheses177 .replace(/\[[^]]*\]/g, '') // remove brackets178 .replace(/\s+/, ' ') // remove extra/duplicate whitespace179 .trim();180};181// to run on cleaned track names, for better performance182exports.normalizeArtistName = function (artistName) {183 return exports184 .removeAccents(artistName.trim().toLowerCase())185 .replace(/[^a-z0-9]/g, ''); // remove non alpha characters186};187var reQuotes = /"[^")]*"/g;188var reSeparator = /-+\s+/g;189var reOnlyDigits = /^\d+$/;190// to run on cleaned track names, for better performance191exports.detectArtistName = function (trackName) {192 var quoted = trackName.match(reQuotes) || [];193 var splitted = (trackName || '').replace(reQuotes, ' - ').split(reSeparator);194 // remove track title (last item of the string, or quoted items)195 splitted.length = splitted.length - (quoted.length || 1);196 for (let i in splitted) {197 var normalized = exports.normalizeArtistName(splitted[i]);198 if (normalized && !reOnlyDigits.test(normalized)) return splitted[i].trim();199 }200 return null;201};202// to run on cleaned track names, for better performance203exports.detectTrackFields = function (trackName) {204 var quoted = trackName.match(reQuotes) || [];205 if (quoted.length == 1) return JSON.stringify(quoted);206 else return null;207};208// =========================================================================209// data structures210exports.arrayHas = function (array, value) {211 if (array) for (let i in array) if (value == array[i]) return true;212 return false;213};214exports.values = function (set) {215 var list = [];216 for (let i in set)217 if (set[i])218 // TODO: remove this line219 list.push(set[i]);220 return list;221};222exports.mapToObjArray = function (map, keyFieldName, valueFieldName) {223 var array = [];224 for (let k in map) {225 var obj = {};226 if (keyFieldName) obj[keyFieldName] = k;227 if (valueFieldName) obj[valueFieldName] = map[k];228 else if (typeof map[k] == 'object')229 for (let f in map[k]) obj[f] = map[k][f];230 array.push(obj);231 }232 return array;233};234exports.arrayToSet = function (array, value) {235 var set = {};236 for (let i in array)237 if (array[i])238 // TODO: remove this line239 set[array[i]] = value !== undefined ? value : true;240 return set;241};242exports.objArrayToSet = function (array, attr, val) {243 var set = {};244 for (let i in array)245 if (array[i] && attr in array[i]) set[array[i][attr]] = val || array[i];246 return set;247};248exports.groupObjectsBy = function (array, attr) {249 var r = {};250 var path = ('' + attr).split('.');251 if (path.length > 1) {252 for (let i in array) {253 const obj = array[i] || {};254 let key = obj;255 for (let j in path) {256 key = (key || {})[path[j]];257 }258 if (key) (r[key] = r[key] || []).push(obj);259 }260 } else {261 for (let i in array) {262 const obj = array[i] || {};263 let key = obj[attr];264 if (key)265 // TODO: fix this line266 (r[key] = r[key] || []).push(obj);267 }268 }269 return r;270};271exports.removeDuplicates = function (array, keyFieldName) {272 if (keyFieldName)273 return exports.mapToObjArray(274 exports.objArrayToSet(array, keyFieldName),275 keyFieldName276 );277 else return Object.keys(exports.arrayToSet(array));278};279exports.objArrayToValueArray = function (array, attr) {280 var list = [];281 for (let i in array)282 if (array[i] && array[i][attr])283 // TODO: fix this line, cf line 217284 list.push(array[i][attr]);285 return list;286};287exports.forEachArrayItem = function (array, handler, cb) {288 var i = 0;289 var length = array.length;290 (function next() {291 setTimeout(function () {292 if (i < length) handler(array[i++], next);293 else if (cb) cb(array);294 }, 0);295 })();296};297exports.getMapFieldNames = function (map /*, firstField*/) {298 var fieldNames = [],299 fieldSet = {};300 for (let i in map) {301 for (let f in map[i])302 if (!fieldSet[f]) {303 // TODO: check this line304 fieldNames.push(f);305 fieldSet[f] = true;306 }307 }308 /*if (firstField)309 fieldNames.unshift(firstField);*/310 return fieldNames;311};312exports.excludeKeys = function (map = [], keySet = {}) {313 const res = [];314 for (let k in map)315 if (!keySet[k])316 // TODO: check this line317 res[k] = map[k];318 return res;319};320exports.checkMissingFields = function (obj, fieldSet) {321 if (!obj || typeof obj !== 'object') return { error: 'object is null' };322 for (let f in fieldSet)323 if (fieldSet[f] && !(f in obj))324 return { field: f, expected: true, error: 'missing field: ' + f };325 else if (!fieldSet[f] && f in obj)326 return { field: f, expected: false, error: 'forbidden field: ' + f };327};328exports.checkMistypedFields = function (obj, fieldTypeSet) {329 if (!obj || typeof obj !== 'object') return { error: 'object is null' };330 function Error(error, f) {331 return {332 field: f,333 type: typeof obj[f],334 expected: fieldTypeSet[f],335 error: error + ': ' + f,336 };337 }338 for (let f in fieldTypeSet)339 if (fieldTypeSet[f]) {340 if (!(f in obj)) return Error('missing field', f);341 else if (342 typeof obj[f] !== fieldTypeSet[f] &&343 (fieldTypeSet[f] !== 'array' || !obj[f].splice)344 )345 return Error('mistyped field', f);346 } else if (f in obj) return Error('forbidden field', f);347};348// translateFields({a,b,c}, {b:"bb"}) => {a,bb,c}349exports.translateFields = function (obj, mapping) {350 if (obj && typeof obj === 'object')351 for (let f in mapping)352 if (f in obj) {353 obj[mapping[f]] = obj[f];354 delete obj[f];355 }356 return obj;357};358// filterFields({a,b,c}, {b:"bb"}) => {bb}359exports.filterFields = function (obj, mapping) {360 var finalObj = {};361 for (let field in mapping)362 if (field in obj)363 finalObj[mapping[field] === true ? field : mapping[field]] = obj[field];364 return finalObj;365};366// =========================================================================367// sorting comparators368exports.descSort = function (a, b) {369 return parseInt(b) - parseInt(a);370};371exports.ascSort = function (a, b) {372 if (a < b) return -1;373 if (a > b) return 1;374 return 0;375};376exports.makeFieldSort = function (field, sortFct) {377 return function (a, b) {378 return sortFct(a[field], b[field]);379 };380};381// by http://andrew.hedges.name382exports.getLevenshteinDistance = (function () {383 function minimator(x, y, z) {384 if (x < y && x < z) return x;385 if (y < x && y < z) return y;386 return z;387 }388 return function (a, b) {389 var cost,390 m = a.length,391 n = b.length;392 if (m < n) {393 var c = a;394 a = b;395 b = c;396 var o = m;397 m = n;398 n = o;399 }400 var r = [];401 r[0] = [];402 for (let c = 0; c < n + 1; c++) r[0][c] = c;403 for (let i = 1; i < m + 1; i++) {404 r[i] = [];405 r[i][0] = i;406 for (let j = 1; j < n + 1; j++) {407 cost = a.charAt(i - 1) == b.charAt(j - 1) ? 0 : 1;408 r[i][j] = minimator(409 r[i - 1][j] + 1,410 r[i][j - 1] + 1,411 r[i - 1][j - 1] + cost412 );413 }414 }415 return r[m][n];416 };417})();418// =========================================================================419// table structures420exports.DataTable = function () {421 this.table = [];422 this.header = null; //[]; // fields423 this.fromArray = (array, header) => {424 if (header) this.header = header;425 this.table = array;426 return this;427 };428 this.fromMap = (map, header) => {429 this.header = header || exports.getMapFieldNames(map);430 //table = /*mapToTable(map, header);*/ [];431 for (let i in map) {432 var line = [433 /*i*/434 ];435 //for (let f in map[i]) line.push(map[i][f]);436 for (let f in this.header) line.push(map[i][this.header[f]]);437 this.table.push(line);438 }439 return this;440 };441 this.sort = (fct) => {442 this.table.sort(fct);443 return this;444 };445 const getFullTableCopy = () => {446 return [].concat(this.header ? [this.header] : []).concat(this.table);447 };448 const toCharSeparatedValues = (charSepar, replacement, lineSepar) => {449 var table = getFullTableCopy();450 var regExp = new RegExp('[' + charSepar + '\n"]', 'g');451 for (let i in table) {452 for (let j in table[i])453 table[i][j] = ('' + table[i][j]).replace(regExp, replacement || ' ');454 //console.log(i, table[i]);455 table[i] = table[i].join(charSepar);456 }457 return table.join(lineSepar || '\n');458 };459 this.toTsv = () => {460 return toCharSeparatedValues('\t');461 };462 this.toCsv = () => {463 return toCharSeparatedValues(',');464 };465 const valToHtmlCell = (val) => {466 return '<td>' + exports.htmlEntities(val) + '</td>';467 };468 this.toHtml = () => {469 var table = getFullTableCopy().map((line) => {470 return '<tr>' + line.map(valToHtmlCell).join('') + '</tr>';471 });472 return [473 '<!DOCTYPE html>',474 '<html>',475 '<head>',476 '<meta charset="utf-8"/>',477 '</head>',478 '<body>',479 '<p>' + this.table.length + ' items</p>',480 '<table>',481 "<thead style='background:#ccc;'>",482 table.shift(),483 '</thead>',484 '<tbody>',485 ]486 .concat(table)487 .concat(['</tbody', '</table>', '</body>', '</html>'])488 .join('\n');489 };490 return this;491};492// =========================================================================493// HTTP requests494var httpDomains = {};495exports.httpSetDomain = function (regex, options) {496 if (!options) delete httpDomains[regex];497 else httpDomains[regex] = [regex, options];498};499exports.httpDomains = httpDomains;500exports.httpGetDomain = function (domain) {501 for (let i in httpDomains)502 if (httpDomains[i][0].test(domain)) return httpDomains[i][1];503};504function _httpRequest(options, callback) {505 var data = '',506 body = options.body;507 if (body)508 // => don't forget to add Content-Type and Content-Length headers in that case509 delete options.body;510 //console.log("httpRequest", options.host + options.path);511 var req = (options.protocol === 'http:' ? http : https)512 .request(options, function (res) {513 if (options.responseEncoding)514 res.setEncoding(options.responseEncoding /*'utf-8'*/);515 res.addListener('data', function (chunk) {516 data += chunk.toString();517 });518 res.addListener('end', function () {519 callback(null, data, res);520 });521 })522 .on('error', function (err) {523 //console.log("[ERR] snip.httpRequest ", url, err);524 //console.error("[ERR] snip.httpRequest ", url, err);525 callback(err);526 });527 req.end(body);528 return req;529}530exports.httpRequest = function (url, options = {}, callback) {531 var urlObj = urlModule.parse(url);532 options.method = options.method || 'GET';533 options.protocol = urlObj.protocol;534 options.host = urlObj.hostname;535 options.port = urlObj.port || (urlObj.protocol === 'https:' ? 443 : 80);536 options.path = urlObj.path; //url; //urlObj.pathname537 //options.headers = {'Accept':'application/json'};538 var domainOpts = exports.httpGetDomain(options.host) || {};539 if (domainOpts.queue) {540 const runNext = () => {541 //console.log("5-next?", options.host, domainOpts.queue.length);542 return domainOpts.queue.length && domainOpts.queue[0](); // run next request in line543 };544 //console.log("1-REQ", options.host, domainOpts.queue.length);545 domainOpts.queue.push(546 _httpRequest.bind(null, options, function () {547 //console.log("2-RES", options.host, domainOpts.queue.length);548 callback.apply(null, arguments);549 //console.log("3-END", options.host, domainOpts.queue.length);550 domainOpts.queue.shift(); // request id done => dequeue551 //console.log("4 =>", options.host, domainOpts.queue.length);552 runNext();553 })554 );555 return domainOpts.queue.length == 1 ? runNext() : undefined;556 }557 return _httpRequest(options, callback);558};559exports.httpRequestWithParams = function (url, options, cb) {560 if (options.params) {561 url += '?' + querystring.stringify(options.params);562 delete options.params;563 }564 if (options.body) {565 options.body =566 typeof options.body == 'object'567 ? querystring.stringify(options.body)568 : options.body;569 options.headers = options.headers || {};570 options.headers['Content-Type'] = 'application/x-www-form-urlencoded';571 options.headers['Content-Length'] = options.body.length;572 }573 return exports.httpRequest(url, options, cb);574};575exports.httpRequestJSON = function (url, options, callback) {576 return exports.httpRequest(url, options, function (err, data, res) {577 if (err) callback(err, null, res);578 else {579 try {580 if (typeof data == 'string') data = JSON.parse(data);581 callback(null, data, res);582 } catch (e) {583 //console.error(e);584 callback(e, data, res);585 }586 }587 });588};589function BasicCache() {590 var cache = {};591 this.get = function (url) {592 return cache[url];593 };594 this.set = function (url, data) {595 return (cache[url] = data);596 };597 this.dump = function () {598 return cache;599 };600 this.restore = function (cacheDump) {601 return (cache = cacheDump);602 };603 return this;604}605exports.HttpRequestCache = function (cache) {606 var realRequest = exports.httpRequest;607 this.cache = cache = cache || new BasicCache();608 this.httpRequest = function (url, options, callback) {609 // TODO: options are ignored for now610 var cached = cache.get(url);611 if (cached) {612 //console.warn("used cached request for", url, "...");613 callback(null, cached);614 } else {615 //console.warn("making a real request to", url, "...");616 realRequest(url, options, function (err, data, res) {617 cache.set(url, data);618 callback(err, data, res);619 });620 }621 };622};623// =========================================================================624/**625 * simple implementation of an async event emitter626 * listeners are called in sequence, based on callbacks627 * inspired by: https://github.com/joyent/node/blob/master/lib/events.js628 **/629function AsyncEventEmitter() {630 this._eventListeners = {};631}632AsyncEventEmitter.prototype.on = function (evtName, listener) {633 this._eventListeners[evtName] = this._eventListeners[evtName] || [];634 this._eventListeners[evtName].push(listener);635 return this;636};637AsyncEventEmitter.prototype.emit = function (evtName, param, callback) {638 var listeners = this._eventListeners[evtName];639 if (!listeners) return false;640 listeners = listeners.slice(); // duplicate array641 const nextListener = () => {642 process.nextTick(() => {643 if (listeners.length) {644 //var args = Array.prototype.slice.call(arguments, 1);645 listeners.pop().call(this, param, nextListener);646 } else if (callback) callback();647 });648 };649 nextListener();650 return true;651};652exports.AsyncEventEmitter = AsyncEventEmitter;653// =========================================================================654/**655 * callWhenDone: a simple synchronized callback closure656 * @author adrienjoly, whyd657 */658exports.callWhenDone = function (callback) {659 var counter = 0;660 return function (incr) {661 if (0 == (counter += incr)) callback();662 };663};664// =========================================================================665/**666 * checkParams: validate an object against two sets of types properties: mandatory and optional667 * returns validated object, or throws an error.668 * @author adrienjoly, whyd669 */670exports.checkParams = function (obj, mandatorySet, optionalSet) {671 var finalObj = {};672 function storeIfValid(fieldName, typeSet) {673 if (typeof obj[fieldName] != typeSet[fieldName])674 throw Error('invalid field value: ' + fieldName);675 else finalObj[fieldName] = obj[fieldName];676 }677 obj = obj || {};678 for (let fieldName in mandatorySet) storeIfValid(fieldName, mandatorySet);679 for (let fieldName in optionalSet)680 if (fieldName in obj && obj[fieldName] != null)681 storeIfValid(fieldName, optionalSet);682 return finalObj;683};684// =========================================================================685var MAX_NB_MENTIONS = 6;686var RE_MENTION = /@\[([^\]]*)\]\(user:([^)]*)\)/gi;687exports.RE_MENTION = RE_MENTION;688exports.extractMentions = function (commentText) {689 var mentions = [];690 for (;;) {691 // extract user id (last matched group) of each mention692 var mentionedUid = (RE_MENTION.exec(commentText) || []).pop();693 if (mentionedUid) mentions.push(mentionedUid);694 else break;695 }696 return mentions.slice(0, MAX_NB_MENTIONS);697};698// =========================================================================699// class to track the execution of long jobs, with callback timeout capability700exports.Worker = function (options) {701 options = options || {};702 var jobs = 0,703 interval = null;704 function addJob(job) {705 console.log('added job: ' + job);706 ++jobs;707 if (!interval)708 interval = setInterval(function () {709 console.log('(' + jobs + ' jobs)');710 }, options.statusDisplayInterval || 5000);711 }712 function removeJob(job) {713 clearTimeout(job.timeout);714 job.done = null;715 --jobs;716 if (!jobs) interval = clearInterval(interval);717 console.log('removed job: ' + job);718 }719 function Job(id) {720 this.toString = function () {721 return id;722 };723 this.done = () => {724 removeJob(this);725 delete this;726 };727 this.wrapCallback = (callback) => {728 return function () {729 if (this && this.done) {730 callback && callback.apply(null, arguments);731 this.done();732 } else733 console.log(734 'warning: intercepted callback from terminated job ' + this735 );736 };737 };738 this.timeout = setTimeout(() => {739 console.log(740 'job ' + this + ' was still running 1 minute after launch => destroying'741 );742 console.warn(743 'destroyed a job that was still running 1 minute after launch'744 );745 removeJob(this);746 delete this;747 }, options.expiry || 60000);748 addJob(this);749 return this;750 }751 this.newJob = function (id) {752 return new Job(id);753 };754 this.countPendingJobs = function () {755 return jobs;756 };757 return this;758};759/*760// tested with expiry duration of 6000 milliseconds761var worker = new exports.Worker({expiry:6000})762var cb = worker.newJob("test1").wrapCallback(function(){763 console.log("callback1");764});765var cb2 = worker.newJob("test2").wrapCallback(function(){766 console.log("callback2");767});768setTimeout(cb, 2000); // -> callback1 displayed, then job removed769// -> test1 job expiry error message, then job removed770setTimeout(cb, 7000); // -> error: intercepted callback tentative for test1 (already terminated)771setTimeout(cb2, 8000); // -> error: intercepted callback tentative for test2 (already terminated)...
background.js
Source:background.js
...127function setBusy(busy) {128 isBusy += ((busy) ? 1 : -1);129 updateIcon();130}131function countPendingJobs() {132 return Array.from(options.downloadList.values()).filter((e) =>133 [JOB_STATE.WAITING, JOB_STATE.RUNNING].includes(e.state)).length;134}135function updateIcon() {136 const n = countPendingJobs();137 browser.browserAction.setBadgeText({text: n === 0 ? "" : n.toString()});138 if (options.appError !== APP_ERROR.NONE) {139 browser.browserAction.setIcon({path: "data/sucker-error.svg"});140 } else if (isBusy > 0) {141 browser.browserAction.setIcon({path: "data/sucker-busy.svg"});142 } else if (selectList.size > 0) {143 browser.browserAction.setIcon({path: "data/sucker-new.svg"});144 } else {145 browser.browserAction.setIcon({path: "data/sucker-idle.svg"});146 }147}148// Consider two durations as equal, even if there's a difference of 1 in the last digit.149function sameLength(t1, t2) {150 return Math.abs(parseInt(t1.replace(/:/g, "")) - parseInt(t2.replace(/:/g, ""))) < 2;...
simBoard.js
Source:simBoard.js
1const mongoose = require("mongoose");2const _ = require("lodash");3require('moment-timezone');4const {5 simsBoardSchema6} = require("./simBoardSchema");7const {8 createPostForSaleJobBySimIds,9 jobSchema,10} = require("./postForSaleJobs");11const elasticsearch = require("./elasticsearch");12const {13 delMemcache14} = require("./memcache");15const crypto = require("crypto");16const upsertMany = require("@meanie/mongoose-upsert-many");17mongoose.plugin(upsertMany);18const getCollectionName = (agency_id) => `kho${agency_id}`;19const removeSale = async (20 data,21 updated_at,22 is_admin = false,23 user = null,24 request_id = null,25 size = 0,26 from = 027) => {28 let query = [];29 let arrQuerySim = [];30 let arrLogSim = [];31 let arrJobLogsim = []32 if (!is_admin) {33 34 data.map((sim) => arrQuerySim.push(sim.sim));35 let sim = await getElasticSims(arrQuerySim);36 const dataMap = _.groupBy(37 [38 ...data.map((agency) => ({39 agency40 })),41 ...sim.map((element) => ({42 element43 })),44 ],45 (m) => (m.agency && m.agency.sim) || (m.element && m.element.id)46 );47 _.values(dataMap).map(async (arr) => {48 const agency = arr.find((m) => m.agency).agency;49 const element = (arr.find((m) => m.element) || {}).element;50 if (!element) return;51 if (element.s3.length === 0) return;52 element.s3 = _.remove(element.s3, function (n) {53 return parseInt(agency.agency_id) !== n54 })55 let s_filter = element.s.filter((sim) =>56 sim.rs ?57 sim.rs === true && sim.id == agency.agency_id :58 sim.id == agency.agency_id59 );60 let getOldAgencySaleSim = element.s.filter(61 (agency_s) =>62 agency_s.rs != false &&63 agency_s.d == false &&64 agency_s.id != agency.agency_id &&65 agency_s !== null66 );67 let maxTimeOfLastAgencySaleSim = Math.max(68 ...getOldAgencySaleSim.map((b) => b.l.sec)69 );70 let getMinPb = {};71 delete element.cr;72 if (getOldAgencySaleSim.length > 0) {73 let getMaxValue = getOldAgencySaleSim.reduce(74 (prev, curr) => {75 return prev.pb > curr.pb ? prev : curr;76 }77 );78 element.p = getMaxValue.pb;79 element.pb = getMaxValue.pb;80 element.pg = getMaxValue.pg;81 element.l.sec = maxTimeOfLastAgencySaleSim;82 getMinPb = getOldAgencySaleSim.reduce((prev, curr) => {83 return prev.pg < curr.pg ? prev : curr;84 });85 } else {86 element.p = 0;87 element.pb = 0;88 element.pg = 0;89 getMinPb = {90 rs: false91 };92 }93 query.push({94 update: {95 _index: "khoso",96 _type: "sim",97 _id: element.id, //"sá» si",98 },99 });100 s_filter.map((sim_element) => {101 let data_log = {102 ...sim_element,103 sim: element.id,104 l_type: 2,105 };106 arrLogSim.push(data_log);107 });108 element.s = getOldAgencySaleSim;109 element.s4 = getMinPb;110 query.push({111 doc: element,112 });113 })114 try {115 if (query.length > 0) {116 await elasticsearch.bulk({117 body: query,118 })119 }120 sim.map(x => {121 x.s.map(y => {122 arrJobLogsim.push({123 sim: x.id,124 root_agency: y.id125 })126 })127 })128 return129 } catch (error) {130 console.log(error);131 }132 } else {133 let offset_new = from ? from : 0; //offset134 let limit = size ? size : 10000; //limit135 const simsJobModel = mongoose.model("post_for_sale_jobs", jobSchema);136 let query_data = buildQRSearchSimByCode(137 user.agency_id,138 limit,139 offset_new140 );141 let result_data = await elasticsearch.search(query_data);142 let data_search = result_data.body.hits.hits.map((m) => m._source);143 let sim_to_remove = data_search.map((sim) => sim.id);144 let countPendingJobs = await simsJobModel.findOne({145 request_id: request_id,146 });147 if (sim_to_remove.length < 10000 && !countPendingJobs) {148 let data_to_remove_with_agencyid = sim_to_remove.map((sim) => ({149 sim: sim,150 agency_id: user.agency_id,151 }));152 await removeSale(data_to_remove_with_agencyid, new Date());153 const collection_name = getCollectionName(user.agency_id);154 const model = mongoose.model(collection_name, simsBoardSchema);155 await model.deleteMany({156 sell_status: 1,157 sim: {158 $in: sim_to_remove159 },160 });161 } else {162 await createPostForSaleJobBySimIds(163 user,164 sim_to_remove,165 2,166 request_id,167 new Date(),168 false,169 true170 );171 let query_count = buildQRSearchSimByCode(172 user.agency_id,173 10000,174 offset_new + 10000175 );176 let result_count = await elasticsearch.search(query_count);177 if (result_count.body.hits.hits.length > 0) {178 await removeSale({},179 new Date(),180 true,181 user,182 request_id,183 10000,184 offset_new + 10000185 );186 } else {187 await simsJobModel.updateMany({188 request_id: request_id,189 status: "WAITING_JOB"190 }, {191 status: "PENDING",192 updated_at: new Date()193 });194 return;195 }196 }197 }198};199const changeSaledSimES = async (data) => {200 let query = [];201 let arrQuerySim = [];202 data.map((sim) => arrQuerySim.push(sim.sim));203 let sim = await getElasticSims(arrQuerySim);204 const dataMap = _.groupBy(205 [206 ...data.map((agency) => ({ agency })),207 ...sim.map((element) => ({ element })),208 ],209 (m) => (m.agency && m.agency.sim) || (m.element && m.element.id)210 );211 _.values(dataMap).map((arr) => {212 const agency = arr.find((m) => m.agency).agency;213 const element = (arr.find((m) => m.element) || {}).element;214 if (!element) return;215 let newS3 = (element.s3 || []).filter(216 (e) => e !== parseInt(agency.agency_id)217 );218 element.s3 = newS3;219 let sim = element.s.filter((sim) =>220 sim.rs221 ? sim.rs === true && sim.id == agency.agency_id222 : sim.id == agency.agency_id223 );224 let getOldAgencySaleSim = element.s.filter(225 (agency_s) =>226 agency_s.rs != false &&227 agency_s.d == false &&228 agency_s.id != agency.agency_id229 );230 let maxTimeOfLastAgencySaleSim = Math.max(231 ...getOldAgencySaleSim.map((b) => b.l.sec)232 );233 if (getOldAgencySaleSim.length > 0) {234 let getMaxValue = getOldAgencySaleSim.reduce((prev, curr) => {235 return prev.pb > curr.pb ? prev : curr;236 });237 element.p = getMaxValue.pb;238 element.pb = getMaxValue.pb;239 element.pg = getMaxValue.pg;240 element.l.sec = maxTimeOfLastAgencySaleSim;241 } else {242 element.p = 0;243 element.pb = 0;244 element.pg = 0;245 // element.l.sec = 0246 }247 sim.map((sim_element) => {248 query.push({249 update: {250 _index: "khoso",251 _type: "sim",252 _id: element.id, //"sá» sim",253 },254 });255 sim_element.d = true;256 let data_log = { ...sim_element, sim: element.id };257 // sendLogToLogstash([data_log]);258 // sim_element.rs = false;259 element.s = element.s.filter((item) => item.id != sim_element.id);260 query.push({261 doc: element,262 });263 });264 });265 const a =266 query.length &&267 (await elasticsearch.bulk({268 body: query,269 }));270};271const buildQRSearchSimByCode = (agencyId, limit, offset) => {272 let arr_must = new Array();273 return {274 body: {275 track_total_hits: true,276 query: {277 bool: {278 must: [{ term: { s3: agencyId } }],279 must_not: [],280 should: [],281 },282 },283 from: offset,284 size: limit,285 sort: [286 {287 "l.sec": {288 order: "asc",289 },290 },291 ],292 },293 };294};295const getElasticSims = async (phones) => {296 const query = {297 body: {298 query: {299 bool: {300 must: [{301 terms: {302 id: phones303 }304 }],305 must_not: [],306 should: [],307 },308 },309 size: "10000",310 },311 };312 const result = await elasticsearch.search(query);313 const data = result.body.hits.hits.map((m) => m._source);314 return data;315};316module.exports = {317 deleteSims: async (318 user,319 sims,320 created_at,321 ) => {322 const collection_name = getCollectionName(user.agency_id);323 const model = mongoose.model(collection_name, simsBoardSchema);324 const existed = await model325 .find({326 sim: {327 $in: sims328 },329 sell_status: {330 $ne: 3331 },332 })333 .select({334 _id: 1,335 sim: 1,336 agency_id: 1337 })338 .then((m) => m.map((n) => n.toJSON()));339 await removeSale(existed, created_at);340 await model.deleteMany({341 sim: {342 $in: existed.map((x) => x["sim"])343 }344 });345 return;346 },347 doDeleteSimsJob: async (348 user,349 index_gte,350 index_lt,351 created_at,352 ) => {353 const collection_name = getCollectionName(user.agency_id);354 const model = mongoose.model(collection_name, simsBoardSchema);355 const existed = await model356 .find({357 sim_status: {358 $ne: 1359 },360 sell_status: {361 $ne: 3362 },363 })364 .select({365 _id: 1,366 sim: 1,367 agency_id: 1368 })369 .limit(index_lt - index_gte)370 .then((m) => m.map((n) => n.toJSON()));371 await removeSale(existed, created_at);372 await model.deleteMany({373 sim: {374 $in: existed.map((x) => x["sim"])375 }376 });377 return;378 },379 doChangeSaledSimsJob: async (380 user,381 index_gte,382 index_lt,383 request_id,384 created_at,385 is_admin = false386 ) => {387 const collection_name = getCollectionName(user.agency_id);388 const model = mongoose.model(collection_name, simsBoardSchema);389 const existed = await model390 .find({})391 .limit(index_lt - index_gte)392 .then((m) => m.map((n) => n.toJSON()));393 await changeSaledSimES(existed);394 const writes = existed.map((item) => {395 return {396 updateOne: {397 filter: {398 _id: item._id,399 },400 update: {401 $set: {402 sell_status: 4,403 sim_status: 4,404 updated_at: created_at,405 },406 $push: {407 logs: {408 $each: [409 item["sell_status"] !== 2 && {410 type: "CHANGE_SELLED_STATUS",411 request_id,412 from_sell_status: item["sell_status"],413 to_sell_status: 4,414 date: created_at,415 user: user.user_id,416 is_admin,417 },418 item["sim_status"] !== 1 && {419 type: "CHANGE_SIM_STATUS",420 request_id,421 from_sim_status: item["sim_status"],422 to_sim_status: 4,423 date: created_at,424 user: user.user_id,425 is_admin,426 },427 ].filter(Boolean),428 },429 },430 },431 },432 };433 });434 const result = writes.length && (await model.bulkWrite(_.flatten(writes)));435 return result;436 },437 changeSaledSim: async (438 user,439 sims,440 request_id,441 created_at,442 is_admin = false443 ) => {444 const collection_name = getCollectionName(user.agency_id);445 const model = mongoose.model(collection_name, simsBoardSchema);446 const existed = await model447 .find({448 sim: {449 $in: sims450 },451 sell_status: 1,452 })453 .then((m) => m.map((n) => n.toJSON()));454 if (existed.length > 0) {455 await changeSaledSimES(existed);456 const writes = await Promise.all(457 existed.map(async (item) => {458 const keyCache = crypto459 .createHash("md5")460 .update(item["sim"])461 .digest("hex");462 await delMemcache(keyCache);463 return {464 updateOne: {465 filter: {466 _id: item._id,467 },468 update: {469 $set: {470 sell_status: 4,471 sim_status: 4,472 updated_at: created_at,473 sim_hold_interval_in_seconds: null,474 sim_hold_expired_at: null,475 customer: null,476 },477 $push: {478 logs: {479 $each: [480 item["sim_status"] !== 1 && {481 type: "CHANGE_SELLED_STATUS",482 request_id,483 from_sell_status: item["sim_status"],484 to_sell_status: 4,485 date: created_at,486 user: user.user_id,487 is_admin,488 },489 item["sim_status"] !== 1 && {490 type: "CHANGE_SIM_STATUS",491 request_id,492 from_sim_status: item["sim_status"],493 to_sim_status: 4,494 date: created_at,495 user: user.user_id,496 is_admin,497 },498 ].filter(Boolean),499 },500 },501 },502 },503 };504 })505 );506 const result =507 writes.length && (await model.bulkWrite(_.flatten(writes)));508 return result;509 } else {510 return 0;511 }512 },...
Using AI Code Generation
1const qawolf = require("qawolf");2const { countPendingJobs } = require("qawolf/src/queue");3async function run() {4 const browser = await qawolf.launch();5 const page = await qawolf.createPage(browser);6 await qawolf.stopVideos();7 await browser.close();8}9run();
Using AI Code Generation
1const { countPendingJobs } = require("@qawolf/qawolf");2(async () => {3 const pendingJobs = await countPendingJobs();4 console.log(pendingJobs);5})();6{ pending: 0 }7const { countPendingJobs } = require("@qawolf/qawolf");8(async () => {9 const pendingJobs = await countPendingJobs();10 console.log(pendingJobs);11})();12{ pending: 0 }13const { countPendingJobs } = require("@qawolf/qawolf");14describe("my test", () => {15 it("should wait for the queue", async () => {16 const pendingJobs = await countPendingJobs();17 expect(pendingJobs.pending).toBe(0);18 });19});
Using AI Code Generation
1const { countPendingJobs } = require('qawolf');2(async () => {3 console.log(await countPendingJobs());4})();5const { countJobs } = require('qawolf');6(async () => {7 console.log(await countJobs());8})();9const { countActiveJobs } = require('qawolf');10(async () => {11 console.log(await countActiveJobs());12})();13const { countActiveJobs } = require('qawolf');14(async () => {15 console.log(await countActiveJobs());16})();17const { countActiveJobs } = require('qawolf');18(async () => {19 console.log(await countActiveJobs());20})();21const { countActiveJobs } = require('qawolf');22(async () => {23 console.log(await countActiveJobs());24})();
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!