Loading jquery in chome extension service worker manifest v3 - google-chrome-extension

I am having a extension where it can notify about new items added to RSS feed reader
All works in v2, but v3 I am unable to load jquery into service worker, since chrome doesnt allow.
As a workaround I have added as module
"background": {
"service_worker": "js/background.js","type": "module"
},
But still its a issue and says ReferenceError: $ is not defined
at Object.parseFeed
Or is there a way I can tweak my code to read xml without jquery?
import $ as module from 'js/jquery-2.1.4.min.js';
var Storage = (function() {
return {
getFeeds: function(callback, returnArray, sortArray) {
returnArray = typeof returnArray !== 'undefined' ? returnArray : true;
sortArray = typeof sortArray !== 'undefined' ? sortArray : true;
chrome.storage.sync.get(function(dataObject) {
var result = dataObject;
if (returnArray) {
var feedArray = this.parseDataObjectIntoArray(dataObject);
result = sortArray ? this.sortArrayOfObjects(feedArray, 'position') : feedArray;
} else {
delete result['RssR:Settings'];
}
callback(result)
}.bind(this));
},
getFeedByUrl: function(feedUrl, callback) {
chrome.storage.sync.get(feedUrl, function(feedData) {
callback(feedData[feedUrl]);
});
},
removeFeedByUrl: function(feedUrl) {
chrome.storage.sync.remove(feedUrl);
},
saveFeedData: function(feedData) {
var saveFeed = {};
saveFeed[feedData.url] = feedData;
this.setDataObject(saveFeed);
},
parseDataObjectIntoArray: function(object) {
var array = [];
Object.keys(object).forEach(function(objectKey) {
if (objectKey.indexOf('RssR:Settings') !== 0) {
array.push(object[objectKey]);
}
});
return array;
},
sortArrayOfObjects: function(array, sortKey) {
array.sort(function(a, b) {
if (typeof a[sortKey] === 'undefined') {
return true;
} else if (typeof b[sortKey] === 'undefined') {
return false;
}
return a[sortKey] - b[sortKey];
});
return array;
},
clearAllData: function() {
chrome.storage.sync.clear();
},
setDataObject: function(dataObject) {
chrome.storage.sync.set(dataObject);
}
}
}());
Array.prototype.max = function() {
return Math.max.apply(null, this);
};
function msToTime(ms) {
let seconds = (ms / 1000).toFixed(1);
let minutes = (ms / (1000 * 60)).toFixed(1);
let hours = (ms / (1000 * 60 * 60)).toFixed(1);
let days = (ms / (1000 * 60 * 60 * 24)).toFixed(1);
if (seconds < 60) return seconds + " Sec";
else if (minutes < 60) return minutes + " Min";
else if (hours < 24) return hours + " Hrs";
else return days + " Days"
}
var FeedService = (function() {
return {
downloadFeed: function(feed) {
if (!feed.url) {
return;
}
console.log(feed.url)
fetch(feed.url)
.then(response => response.text())
.then(xmlString => {
console.log(xmlString)
this.parseFeed(xmlString, feed);
}
)
.then(data => console.log(data))
},
parseFeed: function(rawData, existingFeedData) {
var newFeedData = {};
var $feedEntries = $(rawData).find("entry").length > 0 ? $(rawData).find("entry") : $(rawData).find('item');
var lastUpdate = Date.now()
console.log("Now = " + lastUpdate)
lastUpdate = (existingFeedData && existingFeedData.lastUpdate) || Date.now()
console.log("Last Update = " + lastUpdate)
console.log("existingFeedData = " + JSON.stringify(existingFeedData))
pubDates = [];
$feedEntries.each(function(index, elm) {
pubDates.push(new Date($(elm).find("pubDate").text()).getTime())
if (lastUpdate < new Date($(elm).find("pubDate").text()).getTime()) {
console.log($(elm).find("title").text().substring(0, 20));
chrome.notifications.create(
$(elm).find("link").text(), {
type: "basic",
iconUrl: "../icons/254.png",
title: $(elm).find("title").text(),
message: "(" + msToTime((Date.now() - new Date($(elm).find("pubDate").text()).getTime())) + ") ",
requireInteraction: true
},
function() {}
);
}
}.bind(this));
console.log("Max date = " + Math.max.apply(null, pubDates))
existingFeedData.lastUpdate = Math.max.apply(null, pubDates);
Storage.saveFeedData(existingFeedData);
},
getUrlForFeed: function($feed, feedSettings) {
if (feedSettings.linkType && $feed.find(feedSettings.linkType).length > 0) {
return $feed.find(feedSettings.linkType).text();
} else if ($feed.find('link').length == 1) {
return $feed.find('link').text();
} else {
if ($feed.find('link[rel="shorturl"]').length > 0) {
return $feed.find('link[rel="shorturl"]').attr('href');
} else if ($feed.find('link[rel="alternate"]').length > 0) {
return $feed.find('link[rel="alternate"]').attr('href');
} else if ($feed.find('link[rel="related"]').length > 0) {
return $feed.find('link[rel="related"]').attr('href');
} else {
return $feed.find('link').first();
}
}
},
saveFeed: function(existingFeedData, newFeedData) {
;
},
updateReadStatusOfNewItems: function(oldItems, newItems) {
if (typeof oldItems === 'undefined' || Object.keys(oldItems).length == 0 || Object.keys(newItems).length == 0) {
return newItems;
}
Object.keys(newItems).forEach(function(url) {
if (oldItems[url]) {
newItems[url].unread = oldItems[url].unread;
}
});
return newItems;
},
setNewBadge: function() {
chrome.browserAction.setBadgeText({
text: 'NEW'
});
}
};
}());
chrome.alarms.onAlarm.addListener(function(alarm) {
if (alarm.name == 'updateRssFeeds') {
console.log("Called!")
updateRssFeeds();
}
});
chrome.notifications.onClicked.addListener(function(notificationId) {
chrome.tabs.create({
url: notificationId
});
});
chrome.runtime.onInstalled.addListener(onInstall);
function onInstall() {
chrome.runtime.openOptionsPage();
chrome.alarms.create('updateRssFeeds', {
when: 0,
periodInMinutes: 1
});
}
function updateRssFeeds() {
Storage.getFeeds(function(feeds) {
feeds.forEach(function(feed) {
FeedService.downloadFeed(feed);
});
}, true, false)
}

Related

nodejs, cascade calls to asynchronous function until condition occurs

I need to call several time an asynchronous function (here, to force motor speed), until maximum speed is reached.
But I don't know how to code "multiple calls" with no predefined number of call.
Here is the base of my code.
/* drive motor
from initialSpeedPercent
to finalSpeedPercent
step by step with delay
*/
var initialSpeedPercent = 0;
var finalSpeedPercent = 80;
var duration = 2000; // in millisecond
var accelerationStep = 5;
var stepSpeed = (finalSpeedPercent - initialSpeedPercent) / (accelerationStep - 1);
var stepDuration = duration / (accelerationStep - 1);
function setMotorSpeed( percentOfSpeed, funcWhenCompleted) {
// send consign to motor then return
console.log( `motorspeed set to ${percentOfSpeed}`);
let err = undefined; // depending of motor behavior
if (err) {
funcWhenCompleted( { cmd: 'setMotorSpeed', err: err }, undefined );
}
else {
funcWhenCompleted( undefined, { cmd: 'setMotorSpeed', newSpeed: percentOfSpeed } );
}
}
const promiseSpeed = new Promise( function ( resolve, reject ) {
initialSpeedPercent += stepSpeed;
setMotorSpeed( initialSpeedPercent, function (err, result) {
if (err) {
reject( err);
} else {
// resolve after step duration
setTimeout( () => {
resolve( result );
}, stepDuration );
}
} );
} );
promiseSpeed
.then( ( result ) => {
console.log( 'promiseSpeed success:', result );
... how to call in cascade.... until result.newSpeed >= finalSpeedPercent ?
promiseSpeed
.then( ( result ) => {
console.log( 'promiseSpeed success:', result );
} );
} )
.catch( ( error ) => {
console.log( 'promiseSpeed error:', error );
} )
.finally( () => {
console.log('promiseSpeed() is done!');
} );
How to do that ?
I have found this solution. But I suppose there is a more simple way to do that.
How to avoid a dangerous stack overflow if there are to much inside-call ?
/* _testCascade.js
- Drive motor speed principle, step by step
*/
Date.prototype.yyyymmddhhmmsslll = function() {
var yyyy = this.getFullYear();
var mm = this.getMonth() < 9 ? "0" + (this.getMonth() + 1) : (this.getMonth() + 1); // getMonth() is zero-based
var dd = this.getDate() < 10 ? "0" + this.getDate() : this.getDate();
var hh = this.getHours() < 10 ? "0" + this.getHours() : this.getHours();
var min = this.getMinutes() < 10 ? "0" + this.getMinutes() : this.getMinutes();
var ss = this.getSeconds() < 10 ? "0" + this.getSeconds() : this.getSeconds();
var lll = this.getMilliseconds() < 10 ? "00" + this.getMilliseconds() :
this.getMilliseconds() < 100 ? "0" + this.getMilliseconds() :
this.getMilliseconds();
return yyyy + '-' + mm + '-' + dd + ' ' + hh + ':' + min + ':' + ss + '.' + lll;
};
/* #params: { fromSpeed: -50, stepSpeed: +10, toSpeed: -12 }
speed(s) in percent, from -100 to +100
*/
function driveMotor( params) {
const funcName = "driveMotor";
// console.log( `${new Date()} > ${funcName} > enter with params: ${JSON.stringify(params)}...`);
return new Promise((successCallback,failureCallback) => {
let objective = params.fromSpeed + params.stepSpeed;
// TIMEOUT simulate asynchronous command of speed
setTimeout( function() {
const funcName = "asyncDriveMotor";
// console.log( `${new Date()} > ${funcName} > command executed with objective: ${objective}...`);
if (Math.random() > .2) {
// if (true) {
// console.log( `${new Date()} > ${funcName} > success with objective: ${objective}...`);
let success = params;
success.reachedSpeed = objective;
successCallback( { err: undefined, success: success } );
} else {
// console.log( `${new Date()} > ${funcName} > Promise FAILS with objective: ${objective}...`);
failureCallback( { err: true, success: undefined} );
}
}, 100);
})
}
function progressiveDriveMotorSpeed( params) {
if (params.stepSpeed == 0) {
return;
}
if (params.fromSpeed < -100
|| params.fromSpeed > +100) return;
if (params.toSpeed < -100
|| params.toSpeed > +100) return;
let promise = driveMotor( params );
promise.then( function(result) {
const funcName = "driveMotor.then";
let stop = false;
console.log( `${new Date()} > ${funcName} > result: ${JSON.stringify(result)} `);
if (result.err) {
console.log( `${new Date()} > ${funcName} > err: ${result.err}...stop required`);
stop = true;
} else {
// console.log( `${new Date()} > ${funcName} > success...`);
if (result.success.stepSpeed > 0) {
if (result.success.reachedSpeed >= result.success.toSpeed) {
stop = true;
}
}
if (result.success.stepSpeed < 0) {
if (result.success.reachedSpeed <= result.success.toSpeed) {
stop = true;
}
}
// console.log( `${new Date()} > ${funcName} > success 2...stop: ${stop}`);
if (stop == false) {
params.fromSpeed = result.success.reachedSpeed;
if ( (params.fromSpeed + params.stepSpeed) > params.toSpeed) {
params.fromSpeed = params.toSpeed - params.stepSpeed;
console.log( `${new Date()} > ${funcName} > adjust in order to reach exactly...params.fromSpeed: ${params.fromSpeed}`);
}
// recall
progressiveDriveMotorSpeed( params);
}
}
})
.catch( function( result) {
const funcName = "catch";
if (result.err) {
console.log( `${new Date()} > ${funcName} > FAILURE...result: ${JSON.stringify(result)} with params: ${JSON.stringify( params)} `);
} else {
console.log( `${new Date()} > ${funcName} > COMPLETED...result: ${JSON.stringify(result)} with params: ${JSON.stringify( params)}`);
}
});
}
/* tests:
progressiveDriveMotorSpeed( { fromSpeed: 0, stepSpeed: 10, toSpeed: 50 } );
progressiveDriveMotorSpeed( { fromSpeed: 0, stepSpeed: 10, toSpeed: 48 } );
progressiveDriveMotorSpeed( { fromSpeed: 50, stepSpeed: -10, toSpeed: 0 } );
progressiveDriveMotorSpeed( { fromSpeed: -50, stepSpeed: +10, toSpeed: -12 } );
*/
progressiveDriveMotorSpeed( { fromSpeed: -50, stepSpeed: +10, toSpeed: -12 });

How to optimize query for super user?

I am doing the following query in pseudo code:
Give me all users in age range (provided by user input)
User's who have been seen the least recent first (10 at a time)
User's interest must include one of my interests
User's who have not been swiped left or right by me
If I swiped through 1,000 users and then someone swiped all the same 1,000 then a new user is added making it 1,001. Since all the other 1,000 have been least recent since each new user gets the most recent being the date they create their account, then it has to go through the 1,000 before getting to 1,001 leading to a 3-4 minute query call which is not ok.
My current stack includes Javascript for my web, Backend uses NodeJs with Mongodb.
The three queries look like this:
var minAge = (req.body.min);
var maxAge = (req.body.max);
var swipersCount = 0;
verifyLoginFilter(req, function(loggedIn, userObj, uid) {
if (loggedIn && !userObj.accountFrozen) {
//doing -1 on min and +1 on max for inclusive
var minAgeMinusOne = minAge - 1;
if (minAge === 0) {
minAgeMinusOne = 0;
}
var maxAgePlusOne = maxAge + 1;
var theSwipers, swipersInterests;
var x = 0;
var y = 0;
var skipCount = 0;
grabSwiperLastSwiped();
function grabSwiperLastSwiped() {
User.find({
"$and": [
{ accountFrozen: false },
{ creditsAvailable: { $gt: minAgeMinusOne } },
{ userId: { $ne: uid } }, {
"$or": [
{ "minAge": { "$lt": maxAgePlusOne, "$gt": minAgeMinusOne } },
{ "maxAge": { "$lt": maxAgePlusOne, "$gt": minAgeMinusOne } }
]
}
]
})
.limit(10).sort({ dateLastSwiped: 1 }).skip(skipCount).select({ userId: 1, activeInterests: 1, creditsAvailable: 1, dateLastSwiped: 1 })
.exec(function(err, swipers) {
if (err) {
return res.json({ statusCode: alertErrors.mongodb });
} else {
if (swipers.length > 0) {
theSwipers = swipers;
grabSwiperInterests();
} else {
return res.json({ statusCode: alertErrors.noSwipers });
}
}
});
}
function grabSwiperInterests() {
var today = new Date();
var finalMax;
if (theSwipers[x].creditsAvailable > maxAgePlusOne) {
finalMax = maxAgePlusOne;
} else {
finalMax = theSwipers[x].creditsAvailable;
}
Interests.
find({
"$and": [
{ userId: theSwipers[x].userId },
{ paused: false },
{ _id: { $nin: userObj.personSwiped } }
]
}).limit(10)
.sort({ dailyCredits: 1 })
.exec(function(err, interests) {
if (err) {
return res.json({ statusCode: alertErrors.mongodb });
} else {
if (interests.length > 0) {
swipersInterests = interests;
checkInterst();
} else {
nextSwiper();
}
}
});
}
function nextSwiper() {
swiperCount++;
console.log("nextSwiper " + theSwipers[x].userId + " number " + swiperCount);
if (x === theSwipers.length - 1) {
x = 0;
skipCount = skipCount + theSwipers.length;
grabSwiperLastSwiped();
} else {
console.log("nextSwiper " + theSwipers.length + " x " + x);
x++;
grabSwiperInterests();
}
}
function nextInterest() {
console.log("nextInterest");
if (y === swipersInterests.length - 1) {
nextSwiper();
} else {
y++;
checkInterst();
}
}

Network Error 12030 using Websockets

Hello there i am integrating Wowza Media Server with Temasys plugin(for crossbrowser support) and the code runs great on Chrome but on IE11+ its is giving me network error.Please see attached image and code for details.
const GO_BUTTON_START = "Publish";
const GO_BUTTON_STOP = "Stop";
var video = document.querySelector('video');
var peerConnection = null;
var peerConnectionConfig = {'iceServers': []};
var localStream = null;
var wsURL = "wss://localhost.streamlock.net/webrtc-session.json";
var wsConnection = null;
var streamInfo = {applicationName:"webrtc", streamName:"myStream", sessionId:"[empty]"};
var userData = {param1:"value1"};
var videoBitrate = 360;
var audioBitrate = 64;
var newAPI = false;
navigator.getUserMedia = navigator.getUserMedia || navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
window.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
window.RTCIceCandidate = window.RTCIceCandidate || window.mozRTCIceCandidate || window.webkitRTCIceCandidate;
window.RTCSessionDescription = window.RTCSessionDescription || window.mozRTCSessionDescription || window.webkitRTCSessionDescription;
//var constraints = {
//audio: false,
//video: true
//};
function successCallback(stream) {
window.stream = stream; // make stream available to browser console
localStream=stream;
console.log(localStream);
video = attachMediaStream(video, stream);
}
function errorCallback(error) {
console.log('navigator.getUserMedia error: ', error);
}
function pageReady()
{
$("#buttonGo").attr('value', GO_BUTTON_START);
var constraints =
{
video: true,
audio: false,
};
//alert('here');
navigator.getUserMedia(constraints, successCallback, errorCallback);
console.log("newAPI: "+newAPI);
}
function wsConnect(url)
{
wsConnection = new WebSocket(url);
wsConnection.binaryType = 'arraybuffer';
wsConnection.onopen = function()
{
console.log("wsConnection.onopen");
peerConnection = new RTCPeerConnection(peerConnectionConfig);
peerConnection.onicecandidate = gotIceCandidate;
if (newAPI)
{
var localTracks = localStream.getTracks();
for(localTrack in localTracks)
{
console.log("video stream"+localStream);
peerConnection.addTrack(localTracks[localTrack], localStream);
}
}
else
{
console.log("video stream"+localStream);
peerConnection.addStream(localStream);
}
peerConnection.createOffer(gotDescription, errorHandler);
}
wsConnection.onmessage = function(evt)
{
console.log("wsConnection.onmessage: "+evt.data);
var msgJSON = JSON.parse(evt.data);
var msgStatus = Number(msgJSON['status']);
var msgCommand = msgJSON['command'];
if (msgStatus != 200)
{
$("#sdpDataTag").html(msgJSON['statusDescription']);
stopPublisher();
}
else
{
$("#sdpDataTag").html("");
var sdpData = msgJSON['sdp'];
if (sdpData !== undefined)
{
console.log('sdp: '+msgJSON['sdp']);
peerConnection.setRemoteDescription(new RTCSessionDescription(sdpData), function() {
//peerConnection.createAnswer(gotDescription, errorHandler);
}, errorHandler);
}
var iceCandidates = msgJSON['iceCandidates'];
if (iceCandidates !== undefined)
{
for(var index in iceCandidates)
{
console.log('iceCandidates: '+iceCandidates[index]);
peerConnection.addIceCandidate(new RTCIceCandidate(iceCandidates[index]));
}
}
}
if (wsConnection != null)
wsConnection.close();
wsConnection = null;
}
wsConnection.onclose = function(error)
{
console.log("wsConnection.onclose"+error);
}
wsConnection.onerror = function(evt)
{
console.log("wsConnection.onerror: "+JSON.stringify(evt));
$("#sdpDataTag").html('WebSocket connection failed: '+wsURL);
stopPublisher();
}
}
function startPublisher()
{
wsURL = $('#sdpURL').val();
streamInfo.applicationName = $('#applicationName').val();
streamInfo.streamName = $('#streamName').val();
videoBitrate = $('#videoBitrate').val();
audioBitrate = $('#audioBitrate').val();
$.cookie("webrtcPublishWSURL", wsURL, { expires: 365 });
$.cookie("webrtcPublishApplicationName", streamInfo.applicationName, { expires: 365 });
$.cookie("webrtcPublishStreamName", streamInfo.streamName, { expires: 365 });
$.cookie("webrtcPublishVideoBitrate", videoBitrate, { expires: 365 });
$.cookie("webrtcPublishAudioBitrate", audioBitrate, { expires: 365 });
console.log("startPublisher: wsURL:"+wsURL+" streamInfo:"+JSON.stringify(streamInfo));
wsConnect(wsURL);
$("#buttonGo").attr('value', GO_BUTTON_STOP);
}
function stopPublisher()
{
if (peerConnection != null)
peerConnection.close();
peerConnection = null;
if (wsConnection != null)
wsConnection.close();
wsConnection = null;
$("#buttonGo").attr('value', GO_BUTTON_START);
console.log("stopPublisher");
}
function btn_start()
{
alert('button clicked');
if (peerConnection == null)
startPublisher();
else
stopPublisher();
}
function gotIceCandidate(event)
{
if(event.candidate != null)
{
//console.log('gotIceCandidate: '+JSON.stringify({'ice': event.candidate}));
}
}
function gotDescription(description)
{
var enhanceData = new Object();
if (audioBitrate !== undefined)
enhanceData.audioBitrate = Number(audioBitrate);
if (videoBitrate !== undefined)
enhanceData.videoBitrate = Number(videoBitrate);
description.sdp = enhanceSDP(description.sdp, enhanceData);
console.log('gotDescription: '+JSON.stringify({'sdp': description}));
peerConnection.setLocalDescription(description, function () {
wsConnection.send('{"direction":"publish", "command":"sendOffer", "streamInfo":'+JSON.stringify(streamInfo)+', "sdp":'+JSON.stringify(description)+', "userData":'+JSON.stringify(userData)+'}');
console.log("stream info"+JSON.stringify(streamInfo));
console.log("stream description"+JSON.stringify(description));
console.log("stream userData"+JSON.stringify(userData));
}, function() {console.log('set description error')});
}
function enhanceSDP(sdpStr, enhanceData)
{
var sdpLines = sdpStr.split(/\r\n/);
var sdpSection = 'header';
var hitMID = false;
var sdpStrRet = '';
for(var sdpIndex in sdpLines)
{
var sdpLine = sdpLines[sdpIndex];
if (sdpLine.length <= 0)
continue;
sdpStrRet += sdpLine+'\r\n';
if (sdpLine.indexOf("m=audio") === 0)
{
sdpSection = 'audio';
hitMID = false;
}
else if (sdpLine.indexOf("m=video") === 0)
{
sdpSection = 'video';
hitMID = false;
}
if (sdpLine.indexOf("a=mid:") === 0)
{
if (!hitMID)
{
if ('audio'.localeCompare(sdpSection) == 0)
{
if (enhanceData.audioBitrate !== undefined)
{
sdpStrRet += 'b=AS:' + enhanceData.audioBitrate + '\r\n';
sdpStrRet += 'b=TIAS:' + (enhanceData.audioBitrate*1024) + '\r\n';
}
}
else if ('video'.localeCompare(sdpSection) == 0)
{
if (enhanceData.videoBitrate !== undefined)
{
sdpStrRet += 'b=AS:' + enhanceData.videoBitrate + '\r\n';
sdpStrRet += 'b=TIAS:' + (enhanceData.videoBitrate*1024) + '\r\n';
}
}
hitMID = true;
}
}
}
return sdpStrRet;
}
function errorHandler(error)
{
console.log(error);
}
Click here to see image

nodejs async how to set callback

I have the following piece of code which is working fine.
var config = require('./config');
var cheerio = require('cheerio');
var myhttp = require('./myHttp');
var stringHelper = require('./stringHelper');
var Base64 = require('./base64.js').Base64;
var Encrypt = require('./Encrypt.js');
var myEncode = require('./Encode.js');
var rules = require('./rules');
var io = require('socket.io-emitter')({ host: '127.0.0.1', port: 6379 });
var mysql = require('mysql');
delete require.cache[require.resolve('./requestLogin1.js')]
var myvar = require('./requestLogin1.js');
var connection = mysql.createConnection(
{
host : 'localhost',
user : 'root',
password : 'abc',
database : 'abcd'
}
);
connection.connect(function(err) {
if (err) {
console.log('error connecting: ' + err.stack);
return;
}
});
var timerOB;
var timerMW;
var timerP;
var timerTL;
var news = {
'mw': [],
'ob': [],
'all': {},
};
var status = false;
function round(rnum, rlength) {
return newnumber = Math.round(rnum * Math.pow(10, rlength)) / Math.pow(10, rlength);
}
function roundup(rnum, rlength) {
return newnumber = Math.ceil(rnum * Math.pow(10, rlength)) / Math.pow(10, rlength);
}
function rounddown(rnum, rlength) {
return newnumber = Math.floor(rnum * Math.pow(10, rlength)) / Math.pow(10, rlength);
}
function function1(_html) {
console.log('function1 run')
var $ = cheerio.load(_html);
var v_lgnid = $('#userId').attr('value');
var v_psswrd = config.password;
var v_data = v_lgnid + "|" + v_psswrd;
var _key = $('#accntid').attr('value');
if (_key) {
v_data = Base64.encode(Encrypt.AESEncryptCtr(v_data, _key , "256"));
v_data = escape(v_data);
myhttp.get(
'https://example.com/ValidPassword.jsp?' + $('#name').attr('value') + "=" + v_data,
function (_htmlShowImage) {
if (_htmlShowImage && _htmlShowImage.trim() == "OK") {
function2();
} else {
console.log('Login Fail');
}
});
} else {
login();
console.log('Encrypt password error');
}
}
function function2() {
myhttp.get(
'https://example.com/QuestionsAuth.jsp',
function (_htmlShowImage) {
var $ = cheerio.load(_htmlShowImage);
var sLoginID = $('#sLoginID').attr('value');
var Answer1 = config.answer1;
var Answer2 = config.answer2;
var Index1 = $('#st1').attr('value');
var Index2 = $('#st2').attr('value');
var v_data = sLoginID + "|" + Answer1 + "|" + Answer2 + "|" + Index1 + "|" + Index2;
v_data = Base64.encode(Encrypt.AESEncryptCtr(v_data, $('#key_questauth').attr('value'), "256"));
v_data = escape(v_data);
myhttp.get(
'https://example.com/ValidAnswers.jsp?' + $('#name_questauth').attr('value') + "=" + v_data,
function (_htmlShowImage) {
if (_htmlShowImage && _htmlShowImage.trim() == "OK") {
//rootCallback();
myhttp.get(
'https://example.com/DefaultLogin.jsp',
function (_html) {
console.log('Login sucess')
stringHelper.SaveFileCookies('abcd.txt', myhttp.loadCookie(), 'save cookie login sucess');
if (timerMW) {
clearTimeout(timerMW);
}
timerMW = setTimeout(function6, config.DelayExtractMW);
if (timerOB) {
clearTimeout(timerOB);
}
timerOB = setTimeout(function5, config.DelayExtractOB);
if (timerP) {
clearTimeout(timerP);
}
timerP = setTimeout(function4, config.function4);
});
} else {
console.log('Login Fail - timer');
}
});
});
}
var login = function () {
if (timerMW) {
clearTimeout(timerMW);
}
if (timerOB) {
clearTimeout(timerOB);
}
if (timerP) {
clearTimeout(timerP);
}
if (timerTL) {
clearTimeout(timerTL);
}
myhttp.init();
myhttp.post(
'https://example.com/ShowImage.jsp',
{ "requiredLogin": myEncode.Convert(config.uname) },
function (_htmlpost) {
if (_htmlpost) {
function1(_htmlpost);
} else {
if (timerTL) {
clearTimeout(timerTL);
}
timerTL = setTimeout(login, config.DelayNestError);
}
});
}
exports.login = login;
function function3() {
return {
TS: '',
MWP: 0,
LTP: 0,
NQ: 0,
OBBP: '',
OBSP: '',
CurrTime: 0,
rules: {}
};
}
function function4() {
status = false;
myhttp.get('https://example.com/PB.jsp?Exchange=',
function (_html) {
if (_html && _html.length > 10) {
news.pn = {};
$ = cheerio.load(_html);
$('tr[id^="TR"]').each(function () {
status = true;
var symbol = $('td:nth-child(3)', this).text().trim();
var objob = {
'NQ': parseInt($('td:nth-child(11)', this).text().trim()),
};
var post = {
'symbol': symbol,
'nq': objob.NQ
};
connection.query('INSERT INTO NP SET ?', post, function (err,result){
if (err)
{console.log("NP sql insert error : " +symbol);}
else {
console.log("data inserted into NP Table : " +symbol);
}
});
var objstock = news.all[symbol];
if (typeof objstock!='undefined') {
objstock.NQ = objob.NQ;
news.pn[symbol] = objob;
news.all[symbol] = objstock;
if (status) {
io.emit('news', news);
}
}
else
{
console.log('symbol not found');
}
});
if (timerP) {
clearTimeout(timerP);
}
console.log('setTimer function4:' + config.DelayExtractPn);
timerP = setTimeout(function4, config.DelayExtractPn);
}
connection.query('UPDATE MASTER1 SET tbq = (SELECT sum(a.bq) FROM (select distinct symbol, bq from NP) as a)', function (err,result){
if (err)
{console.log("CQ06 skipped: ");}
else {
console.log("Step 6 - Master1 tbq data updated");
}
});
connection.query('UPDATE MASTER1 SET tsq = (SELECT sum(a.sq) FROM (select distinct symbol, sq from NP) as a)', function (err,result){
if (err)
{console.log("CQ07 skipped: ");}
else {
console.log("Step 7 - Master1 tsq data updated");
}
});
});
}
function function5() {
status = false;
myhttp.get('https://example.com/OB.jsp?Exchange=&OrderType=All',
function (_html) {
if (_html && _html.length > 10) {
$ = cheerio.load(_html);
console.log('OB - Step 2 - html loaded for parsing');
news.ob = [];
$('tr[id^="TR"]').each(function () {
var statusOrder = $('td:nth-child(20)', this).text().trim();
if (statusOrder.toLowerCase().indexOf('open') >= 0) {
status = true;
var objob = {
'symbol': $('td:nth-child(6)', this).text().trim(),
'buysell': $('td:nth-child(9)', this).text().trim(),
'ordernumber': $('input[name="Select"]', this).attr('value'),
};
var objstock = news.all[objob.symbol];
objstock.OBBP = objob.buysell == "BUY"?objob.ordernumber:"";
objstock.OBSP = objob.buysell == "SELL"?objob.ordernumber:"";
news.ob.push(objob);
}
});
if (status) {
io.emit('news', news);
}
if (timerOB) {
clearTimeout(timerOB);
}
timerOB = setTimeout(function5, config.DelayExtractOB);
}
});
}
function function6() {
myhttp.get(
'https://example.com/MW.jsp?',
function (_html) {
if (_html && _html.length > 10) {
var $ = cheerio.load(_html);
status = false;
news.mw = [];
var countCheckRule = 0;
var countCheckedRule = 0;
var tmpall = {};
$('tr[onclick]').each(function () {
status = true;
var data1 = $("input[onclick*='Apply(']", this).attr('onclick');
var arrdata1 = data1.split("','");
var stockid = arrdata1[1].split('|')[0];
var symbol = $('td:nth-child(3)', this).text().trim();
var price = parseFloat($('td:nth-child(4)', this).text().trim());
var cTime = stringHelper.getIndiaTime();
var CurrTime = cTime.toLocaleTimeString();//(will be updated every 60 seconds)
news.mw.push({
'symbol': symbol,
'price': price,
'stockid': stockid,
'CurrTime': CurrTime,
});
var objstock = news.all[symbol];
if (!objstock) {
objstock = function3();
}
if (!news.pn[symbol]) {
objstock.NQ = 0;
}
var notfoundob = true;
for (var symbolkey in news.ob) {
if (news.ob[symbolkey].symbol == symbol) {
notfoundob = false;
}
}
if (notfoundob) {
objstock.OBBP = "";
objstock.OBSP = "";
}
objstock.TS = symbol;//trade symbol
objstock.MWP = stockid;//trade id
objstock.LTP = price;
objstock.CurrTime = CurrTime;
rules.checRules(objstock, myhttp, function (rules_res) {
objstock.rules = rules_res;
tmpall[symbol] = objstock;
});
countCheckRule++;
});
rules.rule12(tmpall, function (_tmpall) {
tmpall = _tmpall;
});
news.all = tmpall;
if (!status) {
login();
console.log('MW - Step 9 - logged out');
} else {
io.emit('news', news);
if (timerMW) {
clearTimeout(timerMW);
}
timerMW = setTimeout(function6, config.DelayExtractMW);
}
} else {
if (timerMW) {
clearTimeout(timerMW);
}
timerMW = setTimeout(function6, config.DelayExtractMW);
}
});
}
Now i want to use async to ensure that function6 is run only after function4 & function5 is run.
I have tried to learn about async from various forums and have changed the code as follows:
var async = require('async'); //line added
// change made
async.parallel([
function function4(callback) {
status = false;
myhttp.get('https://example.com/PB.jsp?Exchange=',
function (_html) {
if (_html && _html.length > 10) {
news.pn = {};
$ = cheerio.load(_html);
$('tr[id^="TR"]').each(function () {
status = true;
var symbol = $('td:nth-child(3)', this).text().trim();
var objob = {
'NQ': parseInt($('td:nth-child(11)', this).text().trim()),
};
console.log('Posn - Step 3A - Found position:' + symbol);
var post = {
'symbol': symbol,
'nq': objob.NQ
};
connection.query('INSERT INTO NP SET ?', post, function (err,result){
if (err)
{console.log("NP sql insert error : " +symbol);}
else {
console.log("data inserted into NP Table : " +symbol);
}
});
var objstock = news.all[symbol];
if (typeof objstock!='undefined') {
objstock.NQ = objob.NQ;
news.pn[symbol] = objob;
news.all[symbol] = objstock;
if (status) {
io.emit('news', news);
}
}
else
{
console.log('symbol not found');
}
});
if (timerP) {
clearTimeout(timerP);
}
console.log('setTimer function4:' + config.DelayExtractPn);
timerP = setTimeout(function4, config.DelayExtractPn);
}
connection.query('UPDATE MASTER1 SET tbq = (SELECT sum(a.bq) FROM (select distinct symbol, bq from NP) as a)', function (err,result){
if (err)
{console.log("CQ06 skipped: ");}
else {
console.log("Step 6 - Master1 tbq data updated");
}
});
connection.query('UPDATE MASTER1 SET tsq = (SELECT sum(a.sq) FROM (select distinct symbol, sq from NP) as a)', function (err,result){
if (err)
{console.log("CQ07 skipped: ");}
else {
console.log("Step 7 - Master1 tsq data updated");
}
});
callback(); //line added
});
},
function function5(callback) {
status = false;
myhttp.get('https://example.com/OB.jsp?Exchange=&OrderType=All',
function (_html) {
if (_html && _html.length > 10) {
$ = cheerio.load(_html);
console.log('OB - Step 2 - html loaded for parsing');
news.ob = [];
$('tr[id^="TR"]').each(function () {
var statusOrder = $('td:nth-child(20)', this).text().trim();
if (statusOrder.toLowerCase().indexOf('open') >= 0 || statusOrder.toLowerCase().indexOf('trigger pending') >= 0) {
status = true;
var objob = {
'symbol': $('td:nth-child(6)', this).text().trim(),
'buysell': $('td:nth-child(9)', this).text().trim(),
'ordernumber': $('input[name="Select"]', this).attr('value'),
};
var objstock = news.all[objob.symbol];
objstock.OBBP = objob.buysell == "BUY"?objob.ordernumber:"";
objstock.OBSP = objob.buysell == "SELL"?objob.ordernumber:"";
news.ob.push(objob);
}
});
if (status) {
console.log('OB - Step 5 - pushed to html page');
io.emit('news', news);
}
if (timerOB) {
clearTimeout(timerOB);
}
timerOB = setTimeout(function5, config.DelayExtractOB);
}
callback(); //line added
});
}
],
function function6() {
myhttp.get(
'https://example.com/MW.jsp?',
function (_html) {
if (_html && _html.length > 10) {
var $ = cheerio.load(_html);
status = false;
news.mw = [];
var countCheckRule = 0;
var countCheckedRule = 0;
var tmpall = {};
$('tr[onclick]').each(function () {
status = true;
var data1 = $("input[onclick*='Apply(']", this).attr('onclick');
var arrdata1 = data1.split("','");
var stockid = arrdata1[1].split('|')[0];
var symbol = $('td:nth-child(3)', this).text().trim();
var price = parseFloat($('td:nth-child(4)', this).text().trim());
var cTime = stringHelper.getIndiaTime();
var CurrTime = cTime.toLocaleTimeString();//(will be updated every 60 seconds)
news.mw.push({
'symbol': symbol,
'price': price,
'stockid': stockid,
'CurrTime': CurrTime,
});
var objstock = news.all[symbol];
if (!objstock) {
objstock = function3();
}
if (!news.pn[symbol]) {
objstock.NQ = 0;
}
var notfoundob = true;
for (var symbolkey in news.ob) {
if (news.ob[symbolkey].symbol == symbol) {
notfoundob = false;
}
}
if (notfoundob) {
objstock.OBBP = "";
objstock.OBSP = "";
}
objstock.TS = symbol;//trade symbol
objstock.MWP = stockid;//trade id
objstock.LTP = price;
objstock.CurrTime = CurrTime;
rules.checRules(objstock, myhttp, function (rules_res) {
objstock.rules = rules_res;
tmpall[symbol] = objstock;
});
countCheckRule++;
});
//new check rules
rules.rule12(tmpall, function (_tmpall) {
tmpall = _tmpall;
});
news.all = tmpall;
if (!status) {
login();
} else {
io.emit('news', news);
if (timerMW) {
clearTimeout(timerMW);
}
timerMW = setTimeout(function6, config.DelayExtractMW);
}
} else {
if (timerMW) {
clearTimeout(timerMW);
}
timerMW = setTimeout(function6, config.DelayExtractMW);
}
});
});
Since my original functions do not have any callback, and since async needs callback, i have tried to code a callback in function4 & function5 - but I guess i have not coded it correctly.
I am getting an error in the line where callback is present that states "TypeError: undefined is not a function".
How do i correct this?
Related Question No. 2 : the current code has a timer function whereby function4, function5 and function6 runs with a preset timer. If async works, how do i define a timer whereby the combined set of function4,5 & 6 works based on a preset timer?
Sorry about the long code -- i am new to nodejs and was handed over this code as such and am trying to get this change made.
Thanks for your guidance.
You can instead make function4 and function5 to return promise and then execute function6 only after both function4's and function5's promise gets resolved.

I am trying to export rallygrid data in excel file, but getting only headers not values

I am trying to export rallygrid data in excel file, but getting only headers not values.
Below is my code which I wrote to generate grid and export button
From here [https://github.com/andreano/TaskDelta/blob/master/App.js], I stole the export code
prepareChart: function(iteration_data) {
this.converted_values = [];
this.accept_values = [];
this.commit_values = [];
parents = [];
rootParent = this.getContext().getProject().Name;
sortedArray = [];
var project_hash = {}; // project_by_name, with children
Ext.Array.each(iteration_data, function(iteration){
if ((iteration.ProjectName != rootParent && iteration.ChildCount > 0) || iteration.ParentName == rootParent) {
parents.push(iteration.ProjectName);
}
// make a place for me
if ( ! project_hash[iteration.ProjectName] ) { project_hash[iteration.ProjectName] = []; }
// make a place for my parent so it can know children
if ( iteration.ParentName ) {
if ( ! project_hash[iteration.ParentName]) { project_hash[iteration.ParentName] = []; }
project_hash[iteration.ParentName] = Ext.Array.merge( project_hash[iteration.ParentName], iteration.ProjectName);
}
}, this);
// build order this way:
//console.log("Current: ", this.getContext().getProject().Name );
// order the array by parents to children to grandchildren
sortedArray = this._getTreeArray( this.getContext().getProject().Name , project_hash);
parents = Ext.Array.unique(parents);
sortedData = [];
Ext.Array.each(sortedArray, function(name){
Ext.Array.each(iteration_data, function(ite){
if(ite.ProjectName == name) {
sortedData.push(ite);
};
});
});
Ext.Array.each(iteration_data, function(iteration){
if (iteration.ProjectName == rootParent) {
sortedData.push(iteration);
}
}, this);
iteration_data = sortedData;
sprints = [];
teams = [];
this.ratio = {};
for ( var i=0; i<iteration_data.length; i++ ) {
commit_accept_ratio = 0;
var data_point = iteration_data[i];
this.commit_values.push( data_point.Commit );
this.accept_values.push( data_point.Accept );
if ( data_point.Commit > data_point.Accept ) {
this.converted_values.push( data_point.Commit - data_point.Accept );
} else {
this.converted_values.push( 0 );
}
if (data_point.Commit != 0) {
commit_accept_ratio = (data_point.Accept / data_point.Commit ) * 100;
} else {
commit_accept_ratio = 0;
};
sprints.push(iteration_data[i].Name);
teams.push(iteration_data[i].ProjectName);
teams.push(rootParent);
this.ratio[data_point.ObjectID] = commit_accept_ratio;
}
this.sprints = Ext.Array.unique(sprints).sort();
this.teams = Ext.Array.unique(teams);
removable_teams = [];
for ( var i=0; i<this.teams.length; i++ ) {
team_name = null;
var count = 0;
Ext.Array.each(iteration_data, function(data) {
if (this.teams[i] == data.ProjectName && data.Commit == 0 || null || undefined && data.Accept == 0 || null || undefined) {
count += 1;
team_name = data.ProjectName;
}
}, this);
if (count == this.sprints.length) {
removable_teams.push(team_name);
}
}
removable_teams = Ext.Array.unique(removable_teams);
records = [];
recordHash = {};
summaryHash = {};
Ext.Array.each(iteration_data, function(iter) {
if (!recordHash[iter.ProjectName]) {
recordHash[iter.ProjectName] = {
Team: iter.ProjectName,
Name: '4 Sprint Summary',
Commit: [],
Accept: [],
Perc: [],
Summary: 0
};
}
if (!Ext.Array.contains(removable_teams, iter.ProjectName)) {
recordHash[iter.ProjectName]["Commit-" + iter.Name] = iter.Commit;
recordHash[iter.ProjectName]["Accept-" + iter.Name] = iter.Accept;
recordHash[iter.ProjectName]["Perc-" + iter.Name] = this.ratio[iter.ObjectID];
}
}, this);
var summaryArray = Ext.Array.slice( this.sprints, (this.sprints.length - 4))
var iterated_data = [];
Ext.Array.each(summaryArray, function(summ){
Ext.Array.each(iteration_data, function(team) {
if( summ == team.Name){
iterated_data.push(team);
}
});
});
Ext.Array.each(iteration_data, function(summ){
Ext.Array.each(iterated_data, function(team) {
if (!summaryHash[team.ProjectName]) {
summaryHash[team.ProjectName] = {
Commit: 0,
Accept: 0,
Total: 0
};
};
if (!Ext.Array.contains(removable_teams, team.ProjectName)) {
if( summ.ProjectName == team.ProjectName && summ.Name == team.Name) {
summaryHash[team.ProjectName]["Commit"] += summ.Commit;
summaryHash[team.ProjectName]["Accept"] += summ.Accept;
if (summaryHash[team.ProjectName]["Commit"] != 0) {
summaryHash[team.ProjectName]["Total"] = (summaryHash[team.ProjectName]["Accept"] / summaryHash[team.ProjectName]["Commit"] ) * 100;
} else {
summaryHash[team.ProjectName]["Total"] = 0;
};
};
}
});
}, this);
Ext.Object.each(recordHash, function(key, value) {
if (summaryHash[key]) {
value["Summary"] = summaryHash[key].Total;
records.push(value);
}
});
var cfgsValues = [];
cfgsValues.push({text: 'Team', style:"background-color: #D2EBC8", dataIndex: 'Team', width: 170, renderer: function(value, meta_data, record, row, col) {
if (Ext.Array.contains(parents, value)) {
meta_data.style = "background-color: #FFF09E";
return Ext.String.format("<div style='font-weight:bold;text-align:center'>{0}</div>", value);
} else if (rootParent == value){
meta_data.style = "background-color: #CC6699";
return Ext.String.format("<div style='font-weight:bold;text-align:center'>{0}</div>", value);
} else {
return value;
};
}});
cfgsValues.push({text: '4 Sprint Summary', style:"background-color: #D2EBC8", width: 70, dataIndex: 'Summary', renderer: function(value, meta_data, record) {
var color = null;
if (value >= 80 && value <= 120) {
color = "#00AF4F";
}
else if (value >= 60 && value <= 80) {
color = "#FBFE08";
}
else if (value <= 60) {
color = "#FC0002";
}
else if (value >= 120) {
color = "#98CCFB";
};
meta_data.style = "background-color: "+color+"";
return Ext.Number.toFixed(value, 0)+"%";
}});
Ext.Array.each(this.sprints, function(sprint) {
cfgsValues.push(
{text: sprint, style:'background-color:#D2EBC8;text-align:center;font-weight:bold', defaults: {enableColumnHide:false}, columns:[
{text: "Commit", dataIndex: 'Commit-' + sprint, width: 50, renderer: function(value, meta_data, record) {
if( value ) {
return value;
} else {
return "NA";
}
}},
{text: "Accept", dataIndex: 'Accept-' + sprint, width: 60, renderer: function(value, meta_data, record) {
if( value) {
return value;
} else {
return "NA";
}
}},
{text: "%", dataIndex: 'Perc-'+ sprint, width: 50, renderer: function(value, meta_data, record) {
var color = null;
if (value >= 80 && value <= 120) {
color = "#00AF4F";
}
else if (value >= 60 && value <= 80) {
color = "#FBFE08";
}
else if (value <= 60) {
color = "#FC0002";
}
else if (value >= 120) {
color = "#98CCFB";
}
meta_data.style = "background-color: "+color+"";
if (value) {
return Ext.Number.toFixed(value, 0)+"%";
} else {
return "NA";
};
}}
]}
);
});
var chart = Ext.getCmp('mychart');
if (chart) {
chart.destroy();
};
Ext.Array.each(this.sprints, function(sprint) {
Ext.Array.each(records, function(record) {
if (record["Accept-" + sprint] == undefined) {
record["Accept-" + sprint] = undefined;
}
if (record["Commit-" + sprint] == undefined) {
record["Commit-" + sprint] = undefined;
}
if (record["Perc-" + sprint] == undefined) {
record["Perc-" + sprint] = undefined;
}
});
});
this.add({
xtype: 'rallygrid',
id: 'mychart',
store: Ext.create('Rally.data.custom.Store', {
data: records,
pageSize: 100
}),
//viewConfig: {
//stripeRows: false
//},
columnCfgs: cfgsValues,
//columnLines: true
});
this.globalStore = Ext.getCmp('mychart');
console.log("this.globalStore", this.globalStore);
this.down('#grid_box').add(this.globalStore);
//this.setLoading(false);
},
_addPrintButton: function() {
var me = this;
this.down('#print_button_box').add( {
xtype: 'rallybutton',
itemId: 'print_button',
text: 'Export to Excel',
disabled: false,
margin: '20 10 10 0',
region: "right",
handler: function() {
me._onClickExport();
}
});
},
_onClickExport: function () { //using this function to export to csv
var that = this;
if (this.down('#grid_box')){
//Ext.getBody().mask('Exporting Tasks...');
//console.log('inside export');
setTimeout(function () {
var template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-' +
'microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head>' +
'<!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>' +
'{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet>' +
'</x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}' +
'</table></body></html>';
var base64 = function (s) {
return window.btoa(unescape(encodeURIComponent(s)));
};
var format = function (s, c) {
return s.replace(/{(\w+)}/g, function (m, p) {
return c[p];
});
};
var table = that.getComponent('grid_box');
//console.log("Exporting table ",table);
var excel_data = '<tr>';
Ext.Array.each(table.getEl().dom.outerHTML.match(/<span .*?x-column-header-text.*?>.*?<\/span>/gm), function (column_header_span) {
excel_data += (column_header_span.replace(/span/g, 'td'));
});
excel_data += '</tr>';
Ext.Array.each(table.getEl().dom.outerHTML.match(/<tr class="x-grid-row.*?<\/tr>/gm), function (line) {
excel_data += line.replace(/[^\011\012\015\040-\177]/g, '>>');
});
//console.log("Excel data ",excel_data);
var ctx = {worksheet: name || 'Worksheet', table: excel_data};
window.location.href = 'data:application/vnd.ms-excel;base64,' + base64(format(template, ctx));
Ext.getBody().unmask();
}, 500);
}else{
console.log("grid_box does not exist");
}
}
There is an example in new AppSDK2 documentation of exporting to CSV.
I also have an example of exporting to CSV in this github repo.

Resources