<commit_before>////////////////////////////////////////////////////////////
//  This file was authored by A. Leah Zulas             ////
//  It creates an express server                        ////
//  The server takes data after the servey is complete  ////
//  It creates a CSV and then delivers data from that CSV///
//      back to be visualized for the participant       ////
//  Any questions about the below code should be sent to:///
//  alzulas@alzulas.com                                 ////
////////////////////////////////////////////////////////////

//Important for setting up express
var express        =         require("express");
var bodyParser     =         require("body-parser");
var app            =         express();

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static('.'));

//Requesting data to visualize BISBAS results
app.get('/BISresult/:myid', function (req, res) {
  //console.log(req.params.myid);
    var myid = req.params.myid;
    var fs = require('fs');
    var IDfound = false;
    var currentLine = 0;
    //read file
    var linesOfFile = fs.readFileSync('BISBAS.csv').toString().split("\n");
    while (!IDfound) { //find ID
        var tempLine = linesOfFile[currentLine];
        if (tempLine.includes(myid)) {
            res.send(tempLine);
            IDfound = true; //If ID is found, that's the line we want. Send it out.
        } else if (tempLine === "") {
            IDfound = true;
            console.log("ID NOT FOUND");
        } else {
            currentLine++; //If not, then next line
        }
    }
});

//Same as above
app.get('/RSSMresult/:myid', function (req, res) {
  //console.log(req.params.myid);
    var myid = req.params.myid;
    var fs = require('fs');
    var IDfound = false;
    var currentLine = 0;
    var linesOfFile = fs.readFileSync('RSSM.csv').toString().split("\n");
    while (!IDfound) {
        var tempLine = linesOfFile[currentLine];
        if (tempLine.includes(myid)) {
            res.send(tempLine);
            IDfound = true;
            console.log("ID found");
        } else if (tempLine === "") {
            IDfound = true;
            console.log("ID NOT FOUND");
        } else {
            currentLine++;
        }
    }
});

//Take result of survey, put it into csv.
app.post('/result', function (req, res) {
    var surveyResult = req.body.survey;
    console.log("Results = " + JSON.stringify(surveyResult));
    res.end("yes");
    turnToCSV(surveyResult);
});

//server listens for requests on PORT 3000
app.listen(3000, function () {
    console.log("Started on PORT 3000");
});

//Function to turn data from website into CSV
function turnToCSV(dataString) {
    //List needed to add which relationship each group of answers is
    var relationship = ["Mother", "Father", "Romantic Partner", "Ex-Romantic Partner", "Sibling", "Close Friend", "name1", "name2", "Negative", "Activity"];

    //All of the various points we're trying to track for RSSM
    var RSSMHeadings = ["ID", "gender", "age", "race", "employment", "marritalStatus", "relativeTyperel0", "thoughtsrel0", "competence1rel0", "autonomy1rel0", "relatedness1rel0", "compentence2rel0", "autonomy2rel0", "relatedness2rel0", "competentce3rel0", "autonomy3rel0", "relatedness3rel0", "compentence4rel0", "autonomy4rel0", "relatedness4rel0", "valencerel0", "relativeTyperel1", "thoughtsrel1", "competence1rel1", "autonomy1rel1", "relatedness1rel1", "compentence2rel1", "autonomy2rel1", "relatedness2rel1", "competentce3rel1", "autonomy3rel1", "relatedness3rel1", "compentence4rel1", "autonomy4rel1", "relatedness4rel1", "valencerel1", "relativeTyperel2", "thoughtsrel2", "competence1rel2", "autonomy1rel2", "relatedness1rel2", "compentence2rel2", "autonomy2rel2", "relatedness2rel2", "competentce3rel2", "autonomy3rel2", "relatedness3rel2", "compentence4rel2", "autonomy4rel2", "relatedness4rel2", "valencerel2", "relativeTyperel3", "thoughtsrel3", "competence1rel3", "autonomy1rel3", "relatedness1rel3", "compentence2rel3", "autonomy2rel3", "relatedness2rel3", "competentce3rel3", "autonomy3rel3", "relatedness3rel3", "compentence4rel3", "autonomy4rel3", "relatedness4rel3", "valencerel3", "relativeTyperel4", "thoughtsrel4", "competence1rel4", "autonomy1rel4", "relatedness1rel4", "compentence2rel4", "autonomy2rel4", "relatedness2rel4", "competentce3rel4", "autonomy3rel4", "relatedness3rel4", "compentence4rel4", "autonomy4rel4", "relatedness4rel4", "valencerel4", "relativeTyperel5", "thoughtsrel5", "competence1rel5", "autonomy1rel5", "relatedness1rel5", "compentence2rel5", "autonomy2rel5", "relatedness2rel5", "competentce3rel5", "autonomy3rel5", "relatedness3rel5", "compentence4rel5", "autonomy4rel5", "relatedness4rel5", "valencerel5", "relativeTyperel6", "name1", "competence1rel6", "autonomy1rel6", "relatedness1rel6", "compentence2rel6", "autonomy2rel6", "relatedness2rel6", "competentce3rel6", "autonomy3rel6", "relatedness3rel6", "compentence4rel6", "autonomy4rel6", "relatedness4rel6", "valencerel6", "relativeTyperel7", "name2", "competence1rel7", "autonomy1rel7", "relatedness1rel7", "compentence2rel7", "autonomy2rel7", "relatedness2rel7", "competentce3rel7", "autonomy3rel7", "relatedness3rel7", "compentence4rel7", "autonomy4rel7", "relatedness4rel7", "valencerel7", "relativeTyperel8", "competence1rel8", "autonomy1rel8", "relatedness1rel8", "compentence2rel8", "autonomy2rel8", "relatedness2rel8", "competentce3rel8", "autonomy3rel8", "relatedness3rel8", "compentence4rel8", "autonomy4rel8", "relatedness4rel8", "valencerel8", "relativeTyperel9", "competence1rel9", "autonomy1rel9", "relatedness1rel9", "compentence2rel9", "autonomy2rel9", "relatedness2rel9", "competentce3rel9", "autonomy3rel9", "relatedness3rel9", "compentence4rel9", "autonomy4rel9", "relatedness4rel9", "valencerel9"];

    //All data we are trying to track for BISBAS
    var BISBASHeadings = ["ID", "gender", "age", "race", "employment", "BIS1", "BIS2", "BIS3", "BIS4", "BIS5", "BIS6", "BIS7", "BASDrive1", "BASDrive2", "BASDrive3", "BASDrive4", "BASReward1", "BASReward2", "BASReward3", "BASReward4", "BASReward5", "BASFun1", "BASFun2", "BASFun3", "BASFun4"];

    var thisUsersIDNumber;
    //turn JSON into a string
    var allDataAsString = JSON.stringify(dataString);
    //Data string must be parsed correctly.
    var dataHeadings;
    //if it's BISBAS, use those headings, if RSSM, use those, Else call failure
    if (allDataAsString.includes("BIS")) {
        dataHeadings = BISBASHeadings;
    } else if (allDataAsString.includes("thoughts")) {
        dataHeadings = RSSMHeadings;
    } else {
        console.log("FAILED TO LOAD DATA TYPES!");
    }
    //Where am I in relationships
    var relationshipHeading = 0;
    var fileName;
    var csv = [];
    //go through all the data headings we set earlier
    for (var i = 0; i < dataHeadings.length; i++) {
        //If the string includes the heading we are looking for
            if (allDataAsString.includes(dataHeadings[i])){
                //Find the position of that heading
                var pos = allDataAsString.indexOf(dataHeadings[i]);
                //Find the beginning of the data I want
                var beginPosition = pos+dataHeadings[i].length+2;
                //If it's a bracket, look for the next bracket
                if (allDataAsString[beginPosition]=="["){
                    //put the first piece of the data into a string
                    var tempString = allDataAsString[beginPosition];
                    beginPosition++;
                    //Then do the entire string until I find the next bracket
                    while (allDataAsString[beginPosition] != "]"){
                        if (allDataAsString[beginPosition] == "\""){
                            tempString += "";
                        //Get rid of JSON nonsense chars
                        } else if (allDataAsString[beginPosition] == ",") {
                            //No commas in the string, because it creates a new piece in the excel file.
                            tempString += " & ";
                        } else {
                            tempString += allDataAsString[beginPosition];
                        }
                    beginPosition++;
                    }
                //add the final bracket and push onto the CSV array
                tempString += "]";
                csv.push(tempString);
            } else if (allDataAsString[beginPosition]=="\"") {
                //if the first character is a " save the string until the next "
                var tempString = allDataAsString[++beginPosition];
                beginPosition++;
                while (allDataAsString[beginPosition] != "\""){
                    tempString += allDataAsString[beginPosition];
                    beginPosition++;
                }
                //if the data is the ID, set that as the fileName
                if (dataHeadings=="ID"){
                    fileName = tempString;
                }
                //Push onto CSV array
                csv.push(tempString);
            } else {
                //If the addition failed for any reason.
                console.log("ERROR IN DATA LOGGING");
            }
        } else if(dataHeadings[i].includes("relativeType")) {
            //if the string is a relative type, then push onto the array the relationship from the above list, and go next
            csv.push(relationship[relationshipHeading]);
            relationshipHeading++;
        } else {
            //If none of the above, then the participant didn't answer that question, and push an empty string onto the spot.
            csv.push("");
        }
    }
    //Push a return character, so that the next time we do this, the CSV will start a new line for the new participant
    csv.push("\n");

    if (allDataAsString.includes("BIS")){
        //If BIS BAS, put the array into the file BISBAS.csv

        var fs = require('fs');

        //var fs = require('fs');
        var IDfound = false;
        var currentLine = 0;
        //read file
        var linesOfFile = fs.readFileSync('BISBAS.csv').toString().split("\n");
        while (!IDfound) { //find ID
            var tempLine = linesOfFile[currentLine];
            if (tempLine.includes(csv[0])) {
                delete linesOfFile[currentLine];
                IDfound = true; //If ID is found, that's the line we want. Send it out.
            } else if (tempLine === "") {
                IDfound = true;
                console.log("ID NOT FOUND");
            } else {
                currentLine++; //If not, then next line
            }
        }
//        var lineReader = require('readline').createInterface({
//            input: require('fs').createReadStream('file.in')
//        });
//
//        lineReader.on('line', function (line) {
//            console.log('Line from file:', line);
//        });

//        fs.readFile('BISBAS.csv', function read(err, data) {
//            if (err) {
//                throw err;
//            }
//            lastIndex = function(){
//                for (var i = data_array.length - 1; i > -1; i--)
//                if (data_array[i].match('user1'))
//                    delete data_array[i];
//                    return true;
//            }()
//            //delete data_array[lastIndex];
//        });

        fs.appendFile("BISBAS.csv", csv, function(err) {
            if(err) {
                //If failed, error
                return console.log(err);
            }
        //If not, return a saved log
        console.log("The file was saved!");
        });
    }
    else if (allDataAsString.includes("thoughts")){
        //If RSSM, put the array into the file RSSM.csv
        var fs = require('fs');
        fs.appendFile("RSSM.csv", csv, function(err) {
            if(err) {
                //If failed, error
                return console.log(err);
            }
        //If not, return a saved log
        console.log("The file was saved!");
        });
    }
    else{
        //If anything goes wrong, fail.
        console.log("FAILED TO SAVE!");
    }
}
  <commit_msg>attempt 5<commit_after>////////////////////////////////////////////////////////////
//  This file was authored by A. Leah Zulas             ////
//  It creates an express server                        ////
//  The server takes data after the servey is complete  ////
//  It creates a CSV and then delivers data from that CSV///
//      back to be visualized for the participant       ////
//  Any questions about the below code should be sent to:///
//  alzulas@alzulas.com                                 ////
////////////////////////////////////////////////////////////

//Important for setting up express
var express        =         require("express");
var bodyParser     =         require("body-parser");
var app            =         express();

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static('.'));

//Requesting data to visualize BISBAS results
app.get('/BISresult/:myid', function (req, res) {
  //console.log(req.params.myid);
    var myid = req.params.myid;
    var fs = require('fs');
    var IDfound = false;
    var currentLine = 0;
    //read file
    var linesOfFile = fs.readFileSync('BISBAS.csv').toString().split("\n");
    while (!IDfound) { //find ID
        var tempLine = linesOfFile[currentLine];
        if (tempLine.includes(myid)) {
            res.send(tempLine);
            IDfound = true; //If ID is found, that's the line we want. Send it out.
        } else if (tempLine === "") {
            IDfound = true;
            console.log("ID NOT FOUND");
        } else {
            currentLine++; //If not, then next line
        }
    }
});

//Same as above
app.get('/RSSMresult/:myid', function (req, res) {
  //console.log(req.params.myid);
    var myid = req.params.myid;
    var fs = require('fs');
    var IDfound = false;
    var currentLine = 0;
    var linesOfFile = fs.readFileSync('RSSM.csv').toString().split("\n");
    while (!IDfound) {
        var tempLine = linesOfFile[currentLine];
        if (tempLine.includes(myid)) {
            res.send(tempLine);
            IDfound = true;
            console.log("ID found");
        } else if (tempLine === "") {
            IDfound = true;
            console.log("ID NOT FOUND");
        } else {
            currentLine++;
        }
    }
});

//Take result of survey, put it into csv.
app.post('/result', function (req, res) {
    var surveyResult = req.body.survey;
    console.log("Results = " + JSON.stringify(surveyResult));
    res.end("yes");
    turnToCSV(surveyResult);
});

//server listens for requests on PORT 3000
app.listen(3000, function () {
    console.log("Started on PORT 3000");
});

//Function to turn data from website into CSV
function turnToCSV(dataString) {
    //List needed to add which relationship each group of answers is
    var relationship = ["Mother", "Father", "Romantic Partner", "Ex-Romantic Partner", "Sibling", "Close Friend", "name1", "name2", "Negative", "Activity"];

    //All of the various points we're trying to track for RSSM
    var RSSMHeadings = ["ID", "gender", "age", "race", "employment", "marritalStatus", "relativeTyperel0", "thoughtsrel0", "competence1rel0", "autonomy1rel0", "relatedness1rel0", "compentence2rel0", "autonomy2rel0", "relatedness2rel0", "competentce3rel0", "autonomy3rel0", "relatedness3rel0", "compentence4rel0", "autonomy4rel0", "relatedness4rel0", "valencerel0", "relativeTyperel1", "thoughtsrel1", "competence1rel1", "autonomy1rel1", "relatedness1rel1", "compentence2rel1", "autonomy2rel1", "relatedness2rel1", "competentce3rel1", "autonomy3rel1", "relatedness3rel1", "compentence4rel1", "autonomy4rel1", "relatedness4rel1", "valencerel1", "relativeTyperel2", "thoughtsrel2", "competence1rel2", "autonomy1rel2", "relatedness1rel2", "compentence2rel2", "autonomy2rel2", "relatedness2rel2", "competentce3rel2", "autonomy3rel2", "relatedness3rel2", "compentence4rel2", "autonomy4rel2", "relatedness4rel2", "valencerel2", "relativeTyperel3", "thoughtsrel3", "competence1rel3", "autonomy1rel3", "relatedness1rel3", "compentence2rel3", "autonomy2rel3", "relatedness2rel3", "competentce3rel3", "autonomy3rel3", "relatedness3rel3", "compentence4rel3", "autonomy4rel3", "relatedness4rel3", "valencerel3", "relativeTyperel4", "thoughtsrel4", "competence1rel4", "autonomy1rel4", "relatedness1rel4", "compentence2rel4", "autonomy2rel4", "relatedness2rel4", "competentce3rel4", "autonomy3rel4", "relatedness3rel4", "compentence4rel4", "autonomy4rel4", "relatedness4rel4", "valencerel4", "relativeTyperel5", "thoughtsrel5", "competence1rel5", "autonomy1rel5", "relatedness1rel5", "compentence2rel5", "autonomy2rel5", "relatedness2rel5", "competentce3rel5", "autonomy3rel5", "relatedness3rel5", "compentence4rel5", "autonomy4rel5", "relatedness4rel5", "valencerel5", "relativeTyperel6", "name1", "competence1rel6", "autonomy1rel6", "relatedness1rel6", "compentence2rel6", "autonomy2rel6", "relatedness2rel6", "competentce3rel6", "autonomy3rel6", "relatedness3rel6", "compentence4rel6", "autonomy4rel6", "relatedness4rel6", "valencerel6", "relativeTyperel7", "name2", "competence1rel7", "autonomy1rel7", "relatedness1rel7", "compentence2rel7", "autonomy2rel7", "relatedness2rel7", "competentce3rel7", "autonomy3rel7", "relatedness3rel7", "compentence4rel7", "autonomy4rel7", "relatedness4rel7", "valencerel7", "relativeTyperel8", "competence1rel8", "autonomy1rel8", "relatedness1rel8", "compentence2rel8", "autonomy2rel8", "relatedness2rel8", "competentce3rel8", "autonomy3rel8", "relatedness3rel8", "compentence4rel8", "autonomy4rel8", "relatedness4rel8", "valencerel8", "relativeTyperel9", "competence1rel9", "autonomy1rel9", "relatedness1rel9", "compentence2rel9", "autonomy2rel9", "relatedness2rel9", "competentce3rel9", "autonomy3rel9", "relatedness3rel9", "compentence4rel9", "autonomy4rel9", "relatedness4rel9", "valencerel9"];

    //All data we are trying to track for BISBAS
    var BISBASHeadings = ["ID", "gender", "age", "race", "employment", "BIS1", "BIS2", "BIS3", "BIS4", "BIS5", "BIS6", "BIS7", "BASDrive1", "BASDrive2", "BASDrive3", "BASDrive4", "BASReward1", "BASReward2", "BASReward3", "BASReward4", "BASReward5", "BASFun1", "BASFun2", "BASFun3", "BASFun4"];

    var thisUsersIDNumber;
    //turn JSON into a string
    var allDataAsString = JSON.stringify(dataString);
    //Data string must be parsed correctly.
    var dataHeadings;
    //if it's BISBAS, use those headings, if RSSM, use those, Else call failure
    if (allDataAsString.includes("BIS")) {
        dataHeadings = BISBASHeadings;
    } else if (allDataAsString.includes("thoughts")) {
        dataHeadings = RSSMHeadings;
    } else {
        console.log("FAILED TO LOAD DATA TYPES!");
    }
    //Where am I in relationships
    var relationshipHeading = 0;
    var fileName;
    var csv = [];
    //go through all the data headings we set earlier
    for (var i = 0; i < dataHeadings.length; i++) {
        //If the string includes the heading we are looking for
            if (allDataAsString.includes(dataHeadings[i])){
                //Find the position of that heading
                var pos = allDataAsString.indexOf(dataHeadings[i]);
                //Find the beginning of the data I want
                var beginPosition = pos+dataHeadings[i].length+2;
                //If it's a bracket, look for the next bracket
                if (allDataAsString[beginPosition]=="["){
                    //put the first piece of the data into a string
                    var tempString = allDataAsString[beginPosition];
                    beginPosition++;
                    //Then do the entire string until I find the next bracket
                    while (allDataAsString[beginPosition] != "]"){
                        if (allDataAsString[beginPosition] == "\""){
                            tempString += "";
                        //Get rid of JSON nonsense chars
                        } else if (allDataAsString[beginPosition] == ",") {
                            //No commas in the string, because it creates a new piece in the excel file.
                            tempString += " & ";
                        } else {
                            tempString += allDataAsString[beginPosition];
                        }
                    beginPosition++;
                    }
                //add the final bracket and push onto the CSV array
                tempString += "]";
                csv.push(tempString);
            } else if (allDataAsString[beginPosition]=="\"") {
                //if the first character is a " save the string until the next "
                var tempString = allDataAsString[++beginPosition];
                beginPosition++;
                while (allDataAsString[beginPosition] != "\""){
                    tempString += allDataAsString[beginPosition];
                    beginPosition++;
                }
                //if the data is the ID, set that as the fileName
                if (dataHeadings=="ID"){
                    fileName = tempString;
                }
                //Push onto CSV array
                csv.push(tempString);
            } else {
                //If the addition failed for any reason.
                console.log("ERROR IN DATA LOGGING");
            }
        } else if(dataHeadings[i].includes("relativeType")) {
            //if the string is a relative type, then push onto the array the relationship from the above list, and go next
            csv.push(relationship[relationshipHeading]);
            relationshipHeading++;
        } else {
            //If none of the above, then the participant didn't answer that question, and push an empty string onto the spot.
            csv.push("");
        }
    }
    //Push a return character, so that the next time we do this, the CSV will start a new line for the new participant
    csv.push("\n");

    if (allDataAsString.includes("BIS")){
        //If BIS BAS, put the array into the file BISBAS.csv

        var fs = require('fs');

        //var fs = require('fs');
        var IDfound = false;
        var currentLine = 0;
        //read file
        var linesOfFile = fs.readFileSync('BISBAS.csv').toString().split("\n");
        while (!IDfound) { //find ID
            var tempLine = linesOfFile[currentLine];
            if (tempLine.includes(csv[0])) {
                delete linesOfFile[currentLine];
                console.log("deleted");
                IDfound = true; //If ID is found, that's the line we want. Send it out.
            } else if (tempLine === "") {
                IDfound = true;
                console.log("ID NOT FOUND");
            } else {
                currentLine++; //If not, then next line
            }
        }
//        var lineReader = require('readline').createInterface({
//            input: require('fs').createReadStream('file.in')
//        });
//
//        lineReader.on('line', function (line) {
//            console.log('Line from file:', line);
//        });

//        fs.readFile('BISBAS.csv', function read(err, data) {
//            if (err) {
//                throw err;
//            }
//            lastIndex = function(){
//                for (var i = data_array.length - 1; i > -1; i--)
//                if (data_array[i].match('user1'))
//                    delete data_array[i];
//                    return true;
//            }()
//            //delete data_array[lastIndex];
//        });

        fs.appendFile("BISBAS.csv", csv, function(err) {
            if(err) {
                //If failed, error
                return console.log(err);
            }
        //If not, return a saved log
        console.log("The file was saved!");
        });
    }
    else if (allDataAsString.includes("thoughts")){
        //If RSSM, put the array into the file RSSM.csv
        var fs = require('fs');
        fs.appendFile("RSSM.csv", csv, function(err) {
            if(err) {
                //If failed, error
                return console.log(err);
            }
        //If not, return a saved log
        console.log("The file was saved!");
        });
    }
    else{
        //If anything goes wrong, fail.
        console.log("FAILED TO SAVE!");
    }
}
  <|endoftext|>


<commit_before>var _          = require('lodash'),
    spec       = require('./spec'),
    format,
    calcScore,
    levelWeights = {
        error: 10,
        warning: 3,
        recommendation: 1
    };

calcScore = function calcScore(results, stats) {
    var maxScore, actualScore, balancedScore;

    maxScore = _.reduce(levelWeights, function (max, weight, level) {
        return max + (weight * stats[level]);
    }, 0);

    actualScore = _.reduce(levelWeights, function (max, weight, level) {
        return max - (weight * _.size(results[level]));
    }, maxScore);

    balancedScore = _.ceil((100 / maxScore) * actualScore);

    return {
        value: balancedScore,
        level: _.size(results.error) > 0 ? 'error' : balancedScore < 60 ? 'warning' : 'passing'
    };
};

/**
 * TODO: This needs cleaning up, a lot
 */
format = function format(theme) {
    var processedCodes = [],
        stats = {
            error: 0,
            warning: 0,
            recommendation: 0
        };

    theme.results.error = [];
    theme.results.warning = [];
    theme.results.recommendation = [];
    theme.results.missing = [];

    _.each(theme.results.fail, function (info, code) {
        var rule = spec.rules[code];
        theme.results[rule.level].push(_.extend({}, rule, info));
        stats[rule.level]++;
        processedCodes.push(code);
    });

    delete theme.results.fail;

    _.each(theme.results.pass, function (code, index) {
        var rule = spec.rules[code];
        theme.results.pass[index] = rule;
        stats[rule.level]++;
        processedCodes.push(code);
    });

    _.each(_.difference(_.keys(spec.rules), processedCodes), function (code) {
        theme.results.missing.push(spec.rules[code]);
    });

    theme.results.score = calcScore(theme.results, stats);

    return theme;
};

module.exports = format;
<commit_msg>🎨 Provide rule codes with results<commit_after>var _          = require('lodash'),
    spec       = require('./spec'),
    format,
    calcScore,
    levelWeights = {
        error: 10,
        warning: 3,
        recommendation: 1
    };

calcScore = function calcScore(results, stats) {
    var maxScore, actualScore, balancedScore;

    maxScore = _.reduce(levelWeights, function (max, weight, level) {
        return max + (weight * stats[level]);
    }, 0);

    actualScore = _.reduce(levelWeights, function (max, weight, level) {
        return max - (weight * _.size(results[level]));
    }, maxScore);

    balancedScore = _.ceil((100 / maxScore) * actualScore);

    return {
        value: balancedScore,
        level: _.size(results.error) > 0 ? 'error' : balancedScore < 60 ? 'warning' : 'passing'
    };
};

/**
 * TODO: This needs cleaning up, a lot
 */
format = function format(theme) {
    var processedCodes = [],
        stats = {
            error: 0,
            warning: 0,
            recommendation: 0
        };

    theme.results.error = [];
    theme.results.warning = [];
    theme.results.recommendation = [];
    theme.results.missing = [];

    _.each(theme.results.fail, function (info, code) {
        var rule = spec.rules[code];
        theme.results[rule.level].push(_.extend({}, rule, info, {code: code}));
        stats[rule.level]++;
        processedCodes.push(code);
    });

    delete theme.results.fail;

    _.each(theme.results.pass, function (code, index) {
        var rule = spec.rules[code];
        theme.results.pass[index] = _.extend({}, rule, {code: code});
        stats[rule.level]++;
        processedCodes.push(code);
    });

    _.each(_.difference(_.keys(spec.rules), processedCodes), function (code) {
        theme.results.missing.push(spec.rules[code]);
    });

    theme.results.score = calcScore(theme.results, stats);

    return theme;
};

module.exports = format;
<|endoftext|>


<commit_before>var SqlString = exports;

SqlString.escapeId = function (val, forbidQualified) {
  if (forbidQualified) {
    return '`' + val.replace(/`/g, '``') + '`';
  }
  return '`' + val.replace(/`/g, '``').replace(/\./g, '`.`') + '`';
};

SqlString.escape = function(val, stringifyObjects, timeZone) {
  if (val === undefined || val === null) {
    return 'NULL';
  }

  switch (typeof val) {
    case 'boolean': return (val) ? 'true' : 'false';
    case 'number': return val+'';
  }

  if (val instanceof Date) {
    val = SqlString.dateToString(val, timeZone || 'local');
  }

  if (Buffer.isBuffer(val)) {
    return SqlString.bufferToString(val);
  }

  if (Array.isArray(val)) {
    return SqlString.arrayToList(val, timeZone);
  }

  if (typeof val === 'object') {
    if (stringifyObjects) {
      val = val.toString();
    } else {
      return SqlString.objectToValues(val, timeZone);
    }
  }

  val = val.replace(/[\0\n\r\b\t\\\'\"\x1a]/g, function(s) {
    switch(s) {
      case "\0": return "\\0";
      case "\n": return "\\n";
      case "\r": return "\\r";
      case "\b": return "\\b";
      case "\t": return "\\t";
      case "\x1a": return "\\Z";
      default: return "\\"+s;
    }
  });
  return "'"+val+"'";
};

SqlString.arrayToList = function(array, timeZone) {
  return array.map(function(v) {
    if (Array.isArray(v)) return '(' + SqlString.arrayToList(v) + ')';
    return SqlString.escape(v, true, timeZone);
  }).join(', ');
};

SqlString.format = function(sql, values, stringifyObjects, timeZone) {
  values = [].concat(values);

  return sql.replace(/\?\??/g, function(match) {
    if (!values.length) {
      return match;
    }

    if (match == "??") {
      return SqlString.escapeId(values.shift());
    }
    return SqlString.escape(values.shift(), stringifyObjects, timeZone);
  });
};

SqlString.dateToString = function(date, timeZone) {
  var dt = new Date(date);

  if (timeZone != 'local') {
    var tz = convertTimezone(timeZone);

    dt.setTime(dt.getTime() + (dt.getTimezoneOffset() * 60000));
    if (tz !== false) {
      dt.setTime(dt.getTime() + (tz * 60000));
    }
  }

  var year   = dt.getFullYear();
  var month  = zeroPad(dt.getMonth() + 1, 2);
  var day    = zeroPad(dt.getDate(), 2);
  var hour   = zeroPad(dt.getHours(), 2);
  var minute = zeroPad(dt.getMinutes(), 2);
  var second = zeroPad(dt.getSeconds(), 2);
  var millisecond = zeroPad(dt.getMilliseconds(), 3);

  return year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second + '.' + millisecond;
};

SqlString.bufferToString = function(buffer) {
  var hex = '';
  try {
    hex = buffer.toString('hex');
  } catch (err) {
    // node v0.4.x does not support hex / throws unknown encoding error
    for (var i = 0; i < buffer.length; i++) {
      var byte = buffer[i];
      hex += zeroPad(byte.toString(16));
    }
  }

  return "X'" + hex+ "'";
};

SqlString.objectToValues = function(object, timeZone) {
  var values = [];
  for (var key in object) {
    var value = object[key];
    if(typeof value === 'function') {
      continue;
    }

    values.push(this.escapeId(key) + ' = ' + SqlString.escape(value, true, timeZone));
  }

  return values.join(', ');
};

function zeroPad(number, length) {
  number = number.toString();
  while (number.length < length) {
    number = '0' + number;
  }

  return number;
}

function convertTimezone(tz) {
  if (tz == "Z") return 0;

  var m = tz.match(/([\+\-\s])(\d\d):?(\d\d)?/);
  if (m) {
    return (m[1] == '-' ? -1 : 1) * (parseInt(m[2], 10) + ((m[3] ? parseInt(m[3], 10) : 0) / 60)) * 60;
  }
  return false;
}
<commit_msg>Fix missing tz in recursive arrayToList call<commit_after>var SqlString = exports;

SqlString.escapeId = function (val, forbidQualified) {
  if (forbidQualified) {
    return '`' + val.replace(/`/g, '``') + '`';
  }
  return '`' + val.replace(/`/g, '``').replace(/\./g, '`.`') + '`';
};

SqlString.escape = function(val, stringifyObjects, timeZone) {
  if (val === undefined || val === null) {
    return 'NULL';
  }

  switch (typeof val) {
    case 'boolean': return (val) ? 'true' : 'false';
    case 'number': return val+'';
  }

  if (val instanceof Date) {
    val = SqlString.dateToString(val, timeZone || 'local');
  }

  if (Buffer.isBuffer(val)) {
    return SqlString.bufferToString(val);
  }

  if (Array.isArray(val)) {
    return SqlString.arrayToList(val, timeZone);
  }

  if (typeof val === 'object') {
    if (stringifyObjects) {
      val = val.toString();
    } else {
      return SqlString.objectToValues(val, timeZone);
    }
  }

  val = val.replace(/[\0\n\r\b\t\\\'\"\x1a]/g, function(s) {
    switch(s) {
      case "\0": return "\\0";
      case "\n": return "\\n";
      case "\r": return "\\r";
      case "\b": return "\\b";
      case "\t": return "\\t";
      case "\x1a": return "\\Z";
      default: return "\\"+s;
    }
  });
  return "'"+val+"'";
};

SqlString.arrayToList = function(array, timeZone) {
  return array.map(function(v) {
    if (Array.isArray(v)) return '(' + SqlString.arrayToList(v, timeZone) + ')';
    return SqlString.escape(v, true, timeZone);
  }).join(', ');
};

SqlString.format = function(sql, values, stringifyObjects, timeZone) {
  values = [].concat(values);

  return sql.replace(/\?\??/g, function(match) {
    if (!values.length) {
      return match;
    }

    if (match == "??") {
      return SqlString.escapeId(values.shift());
    }
    return SqlString.escape(values.shift(), stringifyObjects, timeZone);
  });
};

SqlString.dateToString = function(date, timeZone) {
  var dt = new Date(date);

  if (timeZone != 'local') {
    var tz = convertTimezone(timeZone);

    dt.setTime(dt.getTime() + (dt.getTimezoneOffset() * 60000));
    if (tz !== false) {
      dt.setTime(dt.getTime() + (tz * 60000));
    }
  }

  var year   = dt.getFullYear();
  var month  = zeroPad(dt.getMonth() + 1, 2);
  var day    = zeroPad(dt.getDate(), 2);
  var hour   = zeroPad(dt.getHours(), 2);
  var minute = zeroPad(dt.getMinutes(), 2);
  var second = zeroPad(dt.getSeconds(), 2);
  var millisecond = zeroPad(dt.getMilliseconds(), 3);

  return year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second + '.' + millisecond;
};

SqlString.bufferToString = function(buffer) {
  var hex = '';
  try {
    hex = buffer.toString('hex');
  } catch (err) {
    // node v0.4.x does not support hex / throws unknown encoding error
    for (var i = 0; i < buffer.length; i++) {
      var byte = buffer[i];
      hex += zeroPad(byte.toString(16));
    }
  }

  return "X'" + hex+ "'";
};

SqlString.objectToValues = function(object, timeZone) {
  var values = [];
  for (var key in object) {
    var value = object[key];
    if(typeof value === 'function') {
      continue;
    }

    values.push(this.escapeId(key) + ' = ' + SqlString.escape(value, true, timeZone));
  }

  return values.join(', ');
};

function zeroPad(number, length) {
  number = number.toString();
  while (number.length < length) {
    number = '0' + number;
  }

  return number;
}

function convertTimezone(tz) {
  if (tz == "Z") return 0;

  var m = tz.match(/([\+\-\s])(\d\d):?(\d\d)?/);
  if (m) {
    return (m[1] == '-' ? -1 : 1) * (parseInt(m[2], 10) + ((m[3] ? parseInt(m[3], 10) : 0) / 60)) * 60;
  }
  return false;
}
<|endoftext|>


<commit_before>var stream   = require('stream')
  , util     = require('util')
  , crypto   = require('crypto')
  , request  = require('superagent')
  , oauth1a  = require('../auth/oauth1a')

  , Transform = stream.Transform

  , FB_GRAPH_URL = 'https://graph.facebook.com/'

  , FB_DEFAULT_PAGE_SUBSCRIBED_FIELDS = [

    'feed'

  ]
;

function Page(id, accessToken){
  this.id = id;
  this.accessToken = accessToken;
};

function PubSubConnection(secret){
  this.appSecret = secret;
};

PubSubConnection.prototype.verifyToken = function(){
  return this.verifyToken = oauth1a.makeNonce();
};

PubSubConnection.prototype.validateSignature = function(data){
  var decipher = crypto.createDecipher('AES-128-CBC-HMAC-SHA1', this.appSecret);
  decipher.update('sha1='+data, 'hex');
  return decipher.final('utf8');
};

function Facebook(opts){

  Transform.call(this, {
    objectMode: true
  });

  this.appId          = opts.appId;
  this.appSecret      = opts.appSecret;
  this.appAccessToken = this.getApplicationToken();

  this.subscriptionCallbackURL = opts.subscriptionCallbackURL;
  this.subscribedFields = FB_DEFAULT_PAGE_SUBSCRIBED_FIELDS;

  this._pubsubConnections = {};
};
util.inherits(Facebook, Transform);

Facebook.prototype.getApplicationToken = function(cb){
  if( cb){
    this._graphRequest( 'oauth/access_token', 'GET', {
      client_id:      this.appId,
      client_secret:  this.appSecret,
      grant_type:     'client_credentials'
    }, function(res){
      cb&&cb(res);
    });
  }
  return [
    this.appId,
    this.appSecret
  ].join('|');
};

Facebook.prototype.getTokenInfo = function(token, cb){
  this._graphRequest( 'debug_token', 'GET', {
    input_token:  token,
    access_token: this.appAccessToken
  }, function(res){
    cb&&cb(res);
  });
};

Facebook.prototype.exchangeToken = function(token, cb){
  this._graphRequest( 'oauth/access_token', 'GET', {
    grant_type:         'fb_exchange_token',
    client_id:          this.appId,
    client_secret:      this.appSecret,
    fb_exchange_token:  token
  }, function(res){
    cb&&cb(res);
  });
};

Facebook.prototype.subscribe = function(token,cb){

  var conn = new PubSubConnection( this.appSecret)
    , verify_token = conn.verifyToken()
  ;
  this._pubsubConnections[ verify_token] = conn;

  this._graphRequest( this.appId + '/subscriptions', 'POST', {
    object:       'page',
    callback_url: this.subscriptionCallbackURL,
    fields:       this.subscribedFields.join(','),
    verify_token: verify_token,
    access_token: this.appAccessToken
  },function(res){
    cb&&cb(res);
  });
};

Facebook.prototype.getPages = function(user, token, cb){
  this._graphRequest( user + '/accounts', 'GET', {
    access_token: token
  }, function(res){
    cb&&cb(res);
  });
};

Facebook.prototype.install = function(pageId, token, cb){
  this._graphRequest( pageId + '/tabs', 'POST', {
    app_id: this.appId,
    access_token: token
  }, function(res){
    cb&&cb(res);
  });
};

Facebook.prototype.uninstall = function(pageId, token){
  this._graphRequest( pageId + '/tabs/app_' + this.appId, 'DELETE', {
    access_token: token
  }, function(){

  });
};

Facebook.prototype.pipeSubscription = function(){
  var _this = this;
  return function(req, res, next){
    console.log(req.get('X-Hub-Signature'));
    req.pipe( this);
    next();
  };
};

Facebook.prototype.isVerifyToken = function(token){
  return this._pubsubConnections.hasOwnProperty( token);
};

Facebook.prototype.verify = function(){
  var _this = this;
  return function(req, res){
    if( _this.isVerifyToken( req.query['hub.verify_token'])){
      res.send( req.query['hub.challenge']);
    }else {
      res.send(401);
    }
  };
};

Facebook.prototype._transform = function(chunk, encoding, done){

  this.push(chunk);

  done();
};

Facebook.prototype._graphRequest = function(endpoint, method, data, cb){

  var url = FB_GRAPH_URL + endpoint
    , req
  ;

  switch( method.toUpperCase()){

    case 'GET':

      req = request.get(url)
              .query(data)
              .end( function(res){
                cb&&cb( res);
              })
      break;

    case 'POST':

      req = request.post(url)
              .query(data)
              .send(data)
              .end( function(res){
                cb&&cb( res);
              })
      break;

  }

};

module.exports = Facebook;
<commit_msg>Debug and write data to stream<commit_after>var stream   = require('stream')
  , util     = require('util')
  , crypto   = require('crypto')
  , request  = require('superagent')
  , oauth1a  = require('../auth/oauth1a')

  , Transform = stream.Transform

  , FB_GRAPH_URL = 'https://graph.facebook.com/'

  , FB_DEFAULT_PAGE_SUBSCRIBED_FIELDS = [

    'feed'

  ]
;

function Page(id, accessToken){
  this.id = id;
  this.accessToken = accessToken;
};

function PubSubConnection(secret){
  this.appSecret = secret;
};

PubSubConnection.prototype.verifyToken = function(){
  return this.verifyToken = oauth1a.makeNonce();
};

PubSubConnection.prototype.validateSignature = function(data){
  var decipher = crypto.createDecipher('AES-128-CBC-HMAC-SHA1', this.appSecret);
  decipher.update('sha1='+data, 'hex');
  return decipher.final('utf8');
};

function Facebook(opts){

  Transform.call(this, {
    objectMode: true
  });

  this.appId          = opts.appId;
  this.appSecret      = opts.appSecret;
  this.appAccessToken = this.getApplicationToken();

  this.subscriptionCallbackURL = opts.subscriptionCallbackURL;
  this.subscribedFields = FB_DEFAULT_PAGE_SUBSCRIBED_FIELDS;

  this._pubsubConnections = {};
};
util.inherits(Facebook, Transform);

Facebook.prototype.getApplicationToken = function(cb){
  if( cb){
    this._graphRequest( 'oauth/access_token', 'GET', {
      client_id:      this.appId,
      client_secret:  this.appSecret,
      grant_type:     'client_credentials'
    }, function(res){
      cb&&cb(res);
    });
  }
  return [
    this.appId,
    this.appSecret
  ].join('|');
};

Facebook.prototype.getTokenInfo = function(token, cb){
  this._graphRequest( 'debug_token', 'GET', {
    input_token:  token,
    access_token: this.appAccessToken
  }, function(res){
    cb&&cb(res);
  });
};

Facebook.prototype.exchangeToken = function(token, cb){
  this._graphRequest( 'oauth/access_token', 'GET', {
    grant_type:         'fb_exchange_token',
    client_id:          this.appId,
    client_secret:      this.appSecret,
    fb_exchange_token:  token
  }, function(res){
    cb&&cb(res);
  });
};

Facebook.prototype.subscribe = function(token,cb){

  var conn = new PubSubConnection( this.appSecret)
    , verify_token = conn.verifyToken()
  ;
  this._pubsubConnections[ verify_token] = conn;

  this._graphRequest( this.appId + '/subscriptions', 'POST', {
    object:       'page',
    callback_url: this.subscriptionCallbackURL,
    fields:       this.subscribedFields.join(','),
    verify_token: verify_token,
    access_token: this.appAccessToken
  },function(res){
    cb&&cb(res);
  });
};

Facebook.prototype.getPages = function(user, token, cb){
  this._graphRequest( user + '/accounts', 'GET', {
    access_token: token
  }, function(res){
    cb&&cb(res);
  });
};

Facebook.prototype.install = function(pageId, token, cb){
  this._graphRequest( pageId + '/tabs', 'POST', {
    app_id: this.appId,
    access_token: token
  }, function(res){
    cb&&cb(res);
  });
};

Facebook.prototype.uninstall = function(pageId, token){
  this._graphRequest( pageId + '/tabs/app_' + this.appId, 'DELETE', {
    access_token: token
  }, function(){

  });
};

Facebook.prototype.pipeSubscription = function(){
  var _this = this;
  return function(req, res, next){
    console.log(req.get('X-Hub-Signature'));
    console.log(req.body, req.text);
    this.write(req.text, 'utf8');
    next();
  };
};

Facebook.prototype.isVerifyToken = function(token){
  return this._pubsubConnections.hasOwnProperty( token);
};

Facebook.prototype.verify = function(){
  var _this = this;
  return function(req, res){
    if( _this.isVerifyToken( req.query['hub.verify_token'])){
      res.send( req.query['hub.challenge']);
    }else {
      res.send(401);
    }
  };
};

Facebook.prototype._transform = function(chunk, encoding, done){

  this.push(chunk);

  done();
};

Facebook.prototype._graphRequest = function(endpoint, method, data, cb){

  var url = FB_GRAPH_URL + endpoint
    , req
  ;

  switch( method.toUpperCase()){

    case 'GET':

      req = request.get(url)
              .query(data)
              .end( function(res){
                cb&&cb( res);
              })
      break;

    case 'POST':

      req = request.post(url)
              .query(data)
              .send(data)
              .end( function(res){
                cb&&cb( res);
              })
      break;

  }

};

module.exports = Facebook;
<|endoftext|>


<commit_before>var config = require('getconfig');
var bucker = require('bucker').createLogger();
var redis = require("redis");
var uid = require('node-uuid');
var moment = require('moment');
var githubhook = require('githubhook');
var client = redis.createClient(config.redis.port, config.redis.host);
var github = githubhook({ port: config.github.port, logger: bucker });

client.on('error', function (err) {
    bucker.log('redis error ' + err);
});

github.listen();

github.on('*', function (event, repo, ref, data) {
    bucker.log('sending ' + repo + ' ' + ref + ' event');

    event = {
        id: uuid.v1(),
        type: 'github',
        parent_id: '',
        timestamp: moment.utc().unix() * 1000;,
        payload: { 'repo': repo, 'ref': ref, 'data': data }
    };

    client.publish('github', JSON.stringify(event, null, 2));
});<commit_msg>helps if you don\'t use an already defined variable<commit_after>var config = require('getconfig');
var bucker = require('bucker').createLogger();
var redis = require("redis");
var uid = require('node-uuid');
var moment = require('moment');
var githubhook = require('githubhook');
var client = redis.createClient(config.redis.port, config.redis.host);
var github = githubhook({ port: config.github.port, logger: bucker });

client.on('error', function (err) {
    bucker.log('redis error ' + err);
});

github.listen();

github.on('*', function (event, repo, ref, data) {
    bucker.log('sending ' + repo + ' ' + ref + ' event');

    eventData = {
        id: uuid.v1(),
        type: 'github',
        parent_id: '',
        timestamp: moment.utc().unix() * 1000;,
        payload: { 'repo': repo, 'ref': ref, 'data': data }
    };

    client.publish('github', JSON.stringify(eventData, null, 2));
});<|endoftext|>


<commit_before>describe('Testing imageService', function () {
    var imageService, httpBackend;

    beforeEach(function () {
        // load the module with a mock window object
        module('sourceApp');

        // get your service, also get $httpBackend
        // $httpBackend will be a mock.
        inject(function (_$httpBackend_, _imageService_) {
            imageService = _imageService_;
            httpBackend = _$httpBackend_;
        });
    });

    // make sure no expectations were missed in your tests.
    afterEach(function () {
        httpBackend.verifyNoOutstandingExpectation();
        httpBackend.verifyNoOutstandingRequest();
    });

    //userService should exist in the application
    it('should define the imageService', function() {
    	expect(imageService).toBeDefined();
    });

    it('should get all the images as a list', function () {
    	var imageList;
    	var result = [{
    		contentsfile: "image.json",
    		imagefile: "system.jpg",
            imageid: "Test",
            mission: "ATest"
    	}];

        httpBackend.expectGET('/getImageList').respond(200, result);

        imageService.getImageList().then( function(response){
        	imageList = response.data;
        	expect(response.status).toBe(200);
        	expect(imageList).toBeDefined();
        	expect(imageList.length).toEqual(1);
            expect(imageList).toEqual(result);
    	});

    	httpBackend.flush();
    });

    it('should be able to delete an image from list of images', function () {
        var mission = "ATest";
        var imageid = "Test";

        httpBackend.expectPOST("/removeImageMap")
            .respond(200, {error_code: 0, err_desc : null});

        imageService.removeImageMap(imageid, mission).then( function(response){
            expect(response.status).toBe(400);
            expect(response.data.error_code).toBe(0);
        });

        httpBackend.flush();
    });

});<commit_msg>add all passing test cases<commit_after>describe('Testing imageService', function () {
    var imageService, httpBackend;

    beforeEach(function () {
        // load the module with a mock window object
        module('sourceApp');

        // get your service, also get $httpBackend
        // $httpBackend will be a mock.
        inject(function (_$httpBackend_, _imageService_) {
            imageService = _imageService_;
            httpBackend = _$httpBackend_;
        });
    });

    // make sure no expectations were missed in your tests.
    afterEach(function () {
        httpBackend.verifyNoOutstandingExpectation();
        httpBackend.verifyNoOutstandingRequest();
    });

    //userService should exist in the application
    it('should define the imageService', function() {
    	expect(imageService).toBeDefined();
    });

    it('should get all the images as a list', function () {
    	var imageList;
    	var result = [{
    		contentsfile: "image.json",
    		imagefile: "system.jpg",
            imageid: "Test",
            mission: "ATest"
    	}];

        httpBackend.expectGET('/getImageList').respond(200, result);

        imageService.getImageList().then( function(response){
        	imageList = response.data;
        	expect(response.status).toBe(200);
        	expect(imageList).toBeDefined();
        	expect(imageList.length).toEqual(1);
            expect(imageList).toEqual(result);
    	});

    	httpBackend.flush();
    });

    it('should be able to delete an image from list of images', function () {
        var mission = "ATest";
        var imageid = "Test";

        httpBackend.expectPOST("/removeImageMap")
            .respond(200, {error_code: 0, err_desc : null});

        imageService.removeImageMap(imageid, mission).then( function(response){
            expect(response.status).toBe(200);
            expect(response.data.error_code).toBe(0);
        });

        httpBackend.flush();
    });

});<|endoftext|>


<commit_before>/* @flow */
import template from './template';
import type {
  AlertWordsState,
  FlagsState,
  Narrow,
  Reaction,
  RealmEmojiState,
  Subscription,
} from '../../types';
import { shortTime } from '../../utils/date';
import messageTagsAsHtml from './messageTagsAsHtml';
import messageReactionListAsHtml from './messageReactionListAsHtml';
import processAlertWords from './processAlertWords';

export const flagsStateToStringList = (flags: FlagsState, id: number): string[] =>
  Object.keys(flags).filter(key => flags[key][id]);

const messageDiv = (id: number, msgClass: string, flags: FlagsState): string =>
  template`
 template`data-${flag}="true" `)
       .join('')}
    >`;

const messageSubheader = ({
  fromName,
  timestamp,
  twentyFourHourTime,
}: {
  fromName: string,
  timestamp: number,
  twentyFourHourTime: boolean,
}) => template`

    ${fromName}

    ${shortTime(new Date(timestamp * 1000), twentyFourHourTime)}

`;

/**
 * Data to be used in rendering all messages.
 *
 * See also MessageRenderData.
 */
export type RenderContext = {
  alertWords: AlertWordsState,
  flags: FlagsState,
  ownEmail: string,
  realmEmoji: RealmEmojiState,
  twentyFourHourTime: boolean,
  subscriptions: Subscription[],
  narrow: Narrow,
};

/**
 * Data to be used in rendering a specific message.
 *
 * See also RenderContext.
 */
type MessageRenderData = {
  content: string,
  id: number,
  isOutbox: boolean,
  reactions: Reaction[],
  timeEdited: ?number,
  fromName: string,
  fromEmail: string,
  timestamp: number,
  avatarUrl: string,
  isBrief: boolean,
};

const messageBody = (
  { alertWords, flags, ownEmail, realmEmoji }: RenderContext,
  {
    content,
    id,
    isOutbox,
    reactions,
    timeEdited,
  }: {
    content: string,
    id: number,
    isOutbox: boolean,
    reactions: Reaction[],
    timeEdited: ?number,
  },
) => template`
$!${processAlertWords(content, id, alertWords, flags)}
$!${isOutbox ? '

' : ''}
$!${messageTagsAsHtml(!!flags.starred[id], timeEdited)}
$!${messageReactionListAsHtml(reactions, id, ownEmail, realmEmoji)}
`;

const briefMessageAsHtml = (
  context: RenderContext,
  { content, id, isOutbox, reactions, timeEdited }: MessageRenderData,
) => template`
$!${messageDiv(id, 'message-brief', context.flags)}

    $!${messageBody(context, {
      content,
      id,
      isOutbox,
      reactions,
      timeEdited,
    })}

`;

const fullMessageAsHtml = (
  context: RenderContext,
  {
    id,
    content,
    fromName,
    fromEmail,
    timestamp,
    avatarUrl,
    timeEdited,
    isOutbox,
    reactions,
  }: MessageRenderData,
) => template`
$!${messageDiv(id, 'message-full', context.flags)}

    $!${messageSubheader({ fromName, timestamp, twentyFourHourTime: context.twentyFourHourTime })}
    $!${messageBody(context, {
      content,
      id,
      isOutbox,
      reactions,
      timeEdited,
    })}

`;

export default (renderContext: RenderContext, message: MessageRenderData) =>
  message.isBrief
    ? briefMessageAsHtml(renderContext, message)
    : fullMessageAsHtml(renderContext, message);
<commit_msg>message render: Refactor to collapse a lot of plumbing.<commit_after>/* @flow */
import template from './template';
import type {
  AlertWordsState,
  FlagsState,
  Narrow,
  Reaction,
  RealmEmojiState,
  Subscription,
} from '../../types';
import { shortTime } from '../../utils/date';
import messageTagsAsHtml from './messageTagsAsHtml';
import messageReactionListAsHtml from './messageReactionListAsHtml';
import processAlertWords from './processAlertWords';

export const flagsStateToStringList = (flags: FlagsState, id: number): string[] =>
  Object.keys(flags).filter(key => flags[key][id]);

const messageDiv = (id: number, msgClass: string, flags: FlagsState): string =>
  template`
 template`data-${flag}="true" `)
       .join('')}
    >`;

/**
 * Data to be used in rendering all messages.
 *
 * See also MessageRenderData.
 */
export type RenderContext = {
  alertWords: AlertWordsState,
  flags: FlagsState,
  ownEmail: string,
  realmEmoji: RealmEmojiState,
  twentyFourHourTime: boolean,
  subscriptions: Subscription[],
  narrow: Narrow,
};

/**
 * Data to be used in rendering a specific message.
 *
 * See also RenderContext.
 */
type MessageRenderData = {
  content: string,
  id: number,
  isOutbox: boolean,
  reactions: Reaction[],
  timeEdited: ?number,
  fromName: string,
  fromEmail: string,
  timestamp: number,
  avatarUrl: string,
  isBrief: boolean,
};

const messageBody = (
  { alertWords, flags, ownEmail, realmEmoji }: RenderContext,
  { content, id, isOutbox, reactions, timeEdited }: MessageRenderData,
) => template`
$!${processAlertWords(content, id, alertWords, flags)}
$!${isOutbox ? '

' : ''}
$!${messageTagsAsHtml(!!flags.starred[id], timeEdited)}
$!${messageReactionListAsHtml(reactions, id, ownEmail, realmEmoji)}
`;

export default (context: RenderContext, message: MessageRenderData) => {
  const bodyHtml = messageBody(context, message);

  if (message.isBrief) {
    return template`
$!${messageDiv(message.id, 'message-brief', context.flags)}

    $!${bodyHtml}

`;
  }

  const { fromName, fromEmail, timestamp, avatarUrl } = message;
  const subheaderHtml = template`

    ${fromName}

    ${shortTime(new Date(timestamp * 1000), context.twentyFourHourTime)}

`;

  return template`
$!${messageDiv(message.id, 'message-full', context.flags)}

    $!${subheaderHtml}
    $!${bodyHtml}

`;
};
<|endoftext|>


<commit_before>const zlib = require('zlib')
const fs = require('fs')
const http = require('http')
const express = require('express')
const app = express()
const WebSocket = require('ws')
const conf = require('nconf')
const bodyParser = require('body-parser')
const maxmind = require('maxmind')
const moment = require('moment')
const request = require('request')
const uuid = require('uuid/v1')
const CronJob = require('cron').CronJob
const db = require('./database.js')
const log = console.log

conf.file({file: 'cfg.json'})
conf.defaults({
  port: 3013,
  bind: '127.0.0.1',
  servers: [{id: 0, name: 'Server'}],
  ipFile: './GeoLite2-City.mmdb'
})
app.use('/static', express.static(`${__dirname}/dist/static`))
app.use(bodyParser.json())
const ipFile = conf.get('ipFile')
const cityLookup = {}
const clients = new Map()
let servers = conf.get('servers') || []

const logBuffer = {}
const logEvent = (server, data, event) => {
  const record = {server: server, node: data.name, event: event, timestamp: moment().unix()}
  if (event === 'connect') {
    record.pub = data.pub
    record.vpn = data.vpn
    record.country_code = data.country_code
    record.country_name = data.country_name
  }
  if (!logBuffer[data.name])
    logBuffer[data.name] = setTimeout(() => {
      logBuffer[data.name] = false
      clients.forEach((ws) => ws.send(JSON.stringify(record)))
      db.Log.create(record)
    }, 1500)
  else {
    clearTimeout(logBuffer[data.name])
    logBuffer[data.name] = false
  }
}
const validateIPaddress = (ipaddress) => /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(ipaddress.toString())
const validateNumber = (n) => !isNaN(parseFloat(n)) && isFinite(n)
const loadIPdatabase = () => {
  return new Promise((resolve) => {
    fs.stat(ipFile, (err, stat) => {
      const now = new Date().getTime()
      const expire = new Date((stat ? stat.ctime : '')).getTime() + 30 * 24 * 60 * 60 * 1000
      if (err || now > expire) {
        const req = request('http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz')
        req.on('response', (resp) => {
          if(resp.statusCode === 200) {
            req.pipe(zlib.createGunzip()).pipe(fs.createWriteStream(ipFile))
              .on('finish', () => {
                maxmind.open('./GeoLite2-City.mmdb', (err, lookup) => {
                  cityLookup.get = (ip) => (ip ? lookup.get(ip) : false)
                  resolve(cityLookup)
                })
              })
          } else
            maxmind.open('./GeoLite2-City.mmdb', (err, lookup) => {
              if (err)
                log(err)
              cityLookup.get = (ip) => (ip ? lookup.get(ip) : false)
              resolve(cityLookup)
            })
        })
      } else
        maxmind.open('./GeoLite2-City.mmdb', (err, lookup) => {
          if (err)
            log(err)
          cityLookup.get = (ip) => (ip ? lookup.get(ip) : false)
          resolve(cityLookup)
        })
    })
  })
}

new CronJob({
  cronTime: '00 10 * 10 * *',
  onTick: loadIPdatabase,
  start: true
})

app.get('/', (req, res) => res.sendFile(`${__dirname}/dist/index.html`))
app.get('/servers', (req, res) => res.json(servers.map((server, idx) => ({name: server.name, id: idx}))))
const compare = (a,b) => {
  if (a.country_code < b.country_code)
    return -1
  if (a.country_code > b.country_code)
    return 1
  if (a.pub < b.pub)
    return -1
  if (a.pub > b.pub)
    return 1
  if (a.timestamp < b.timestamp)
    return 1
  if (a.timestamp > b.timestamp)
    return -1
  return 0
}
const validateServer = (req, res, next) => {
  if (!validateNumber(req.params.id))
    return res.sendStatus(400)
  if (!servers[req.params.id])
    return res.sendStatus(404)
  next()
}
app.post('/server/:id/connect', validateServer, (req, res) => {
  const serverId = parseInt(req.params.id, 10)
  const pub = req.body.pub
  const cn = (req.body.cn || '').trim()
  const vpn = req.body.vpn
  if (!validateIPaddress(pub) || !validateIPaddress(vpn) || !cn.length)
    return res.sendStatus(400)
  const loc = cityLookup.get(pub)
  const entry = {name: cn, pub: pub, vpn: vpn, timestamp: moment().unix()}
  if (loc) {
    entry.country_code = loc.country.iso_code
    entry.country_name = loc.country.names.en
  }
  logEvent(serverId, entry, 'connect')
  servers[serverId].entries.push(entry)
  res.sendStatus(200)
})
app.post('/server/:id/disconnect', validateServer, (req, res) => {
  const serverId = parseInt(req.params.id, 10)
  const cn = (req.body.cn || '').trim()
  if (!cn.length)
    return res.sendStatus(400)
  logEvent(serverId, {name: cn}, 'disconnect')
  servers[serverId].entries = servers[serverId].entries.filter((itm) => itm.name !== cn)
  res.sendStatus(200)
})
app.get('/entries/:id', validateServer, (req, res) => res.json(servers[req.params.id].entries.sort(compare)))
app.get('/log/:id/size', validateServer, (req, res) => db.Log.count({where: {server: req.params.id}}).then((size) => res.json({value: size})))
app.get('/log/:id/:page/:size', validateServer, (req, res) => {
  if (!validateNumber(req.params.page) || !validateNumber(req.params.size))
    return res.sendStatus(400)
  const page = parseInt(req.params.page, 10)
  const size = parseInt(req.params.size, 10)
  const query = db.Log.findAll({where: {server: req.params.id}, offset: (page - 1) * size, limit: size, order: [['timestamp', 'DESC']]})
  query.then((data) => {
    res.json(data.map((item) => ({server: item.server, node: item.node, timestamp: item.timestamp, event: item.event})))
  })
})

const server = http.createServer(app)
const wss = new WebSocket.Server({server})

wss.on('connection', (ws) => {
  const id = uuid()
  clients.set(id, ws)
  ws.on('close', () => clients.delete(id))
  ws.on('error', (err) => {
    log(err)
    clients.delete(id)
  })
})

db.init().then(() => db.state()).then((entries) => {
  loadIPdatabase().then(() => {
    servers.forEach((server, idx) => {
      server.entries = entries.filter((entry) => entry.server === idx).map((entry) => {
        const data = {
          name: entry.node,
          timestamp: entry.timestamp,
          pub: entry.pub,
          vpn: entry.vpn
        }
        const loc = cityLookup.get(entry.pub)
        if (entry.pub && loc) {
          data.country_code = loc.country.iso_code
          data.country_name = loc.country.names.en
        }
        return data
      })
    })
    server.listen({host: conf.get('bind'),port: conf.get('port'),exclusive: true})
  })
})
<commit_msg>Do not sort serverside<commit_after>const zlib = require('zlib')
const fs = require('fs')
const http = require('http')
const express = require('express')
const app = express()
const WebSocket = require('ws')
const conf = require('nconf')
const bodyParser = require('body-parser')
const maxmind = require('maxmind')
const moment = require('moment')
const request = require('request')
const uuid = require('uuid/v1')
const CronJob = require('cron').CronJob
const db = require('./database.js')
const log = console.log

conf.file({file: 'cfg.json'})
conf.defaults({
  port: 3013,
  bind: '127.0.0.1',
  servers: [{id: 0, name: 'Server'}],
  ipFile: './GeoLite2-City.mmdb'
})
app.use('/static', express.static(`${__dirname}/dist/static`))
app.use(bodyParser.json())
const ipFile = conf.get('ipFile')
const cityLookup = {}
const clients = new Map()
let servers = conf.get('servers') || []

const logBuffer = {}
const logEvent = (server, data, event) => {
  const record = {server: server, node: data.name, event: event, timestamp: moment().unix()}
  if (event === 'connect') {
    record.pub = data.pub
    record.vpn = data.vpn
    record.country_code = data.country_code
    record.country_name = data.country_name
  }
  if (!logBuffer[data.name])
    logBuffer[data.name] = setTimeout(() => {
      logBuffer[data.name] = false
      clients.forEach((ws) => ws.send(JSON.stringify(record)))
      db.Log.create(record)
    }, 1500)
  else {
    clearTimeout(logBuffer[data.name])
    logBuffer[data.name] = false
  }
}
const validateIPaddress = (ipaddress) => /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(ipaddress.toString())
const validateNumber = (n) => !isNaN(parseFloat(n)) && isFinite(n)
const loadIPdatabase = () => {
  return new Promise((resolve) => {
    fs.stat(ipFile, (err, stat) => {
      const now = new Date().getTime()
      const expire = new Date((stat ? stat.ctime : '')).getTime() + 30 * 24 * 60 * 60 * 1000
      if (err || now > expire) {
        const req = request('http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz')
        req.on('response', (resp) => {
          if(resp.statusCode === 200) {
            req.pipe(zlib.createGunzip()).pipe(fs.createWriteStream(ipFile))
              .on('finish', () => {
                maxmind.open('./GeoLite2-City.mmdb', (err, lookup) => {
                  cityLookup.get = (ip) => (ip ? lookup.get(ip) : false)
                  resolve(cityLookup)
                })
              })
          } else
            maxmind.open('./GeoLite2-City.mmdb', (err, lookup) => {
              if (err)
                log(err)
              cityLookup.get = (ip) => (ip ? lookup.get(ip) : false)
              resolve(cityLookup)
            })
        })
      } else
        maxmind.open('./GeoLite2-City.mmdb', (err, lookup) => {
          if (err)
            log(err)
          cityLookup.get = (ip) => (ip ? lookup.get(ip) : false)
          resolve(cityLookup)
        })
    })
  })
}

new CronJob({
  cronTime: '00 10 * 10 * *',
  onTick: loadIPdatabase,
  start: true
})

app.get('/', (req, res) => res.sendFile(`${__dirname}/dist/index.html`))
app.get('/servers', (req, res) => res.json(servers.map((server, idx) => ({name: server.name, id: idx}))))
const validateServer = (req, res, next) => {
  if (!validateNumber(req.params.id))
    return res.sendStatus(400)
  if (!servers[req.params.id])
    return res.sendStatus(404)
  next()
}
app.post('/server/:id/connect', validateServer, (req, res) => {
  const serverId = parseInt(req.params.id, 10)
  const pub = req.body.pub
  const cn = (req.body.cn || '').trim()
  const vpn = req.body.vpn
  if (!validateIPaddress(pub) || !validateIPaddress(vpn) || !cn.length)
    return res.sendStatus(400)
  const loc = cityLookup.get(pub)
  const entry = {name: cn, pub: pub, vpn: vpn, timestamp: moment().unix()}
  if (loc) {
    entry.country_code = loc.country.iso_code
    entry.country_name = loc.country.names.en
  }
  logEvent(serverId, entry, 'connect')
  servers[serverId].entries.push(entry)
  res.sendStatus(200)
})
app.post('/server/:id/disconnect', validateServer, (req, res) => {
  const serverId = parseInt(req.params.id, 10)
  const cn = (req.body.cn || '').trim()
  if (!cn.length)
    return res.sendStatus(400)
  logEvent(serverId, {name: cn}, 'disconnect')
  servers[serverId].entries = servers[serverId].entries.filter((itm) => itm.name !== cn)
  res.sendStatus(200)
})
app.get('/entries/:id', validateServer, (req, res) => res.json(servers[req.params.id].entries))
app.get('/log/:id/size', validateServer, (req, res) => db.Log.count({where: {server: req.params.id}}).then((size) => res.json({value: size})))
app.get('/log/:id/:page/:size', validateServer, (req, res) => {
  if (!validateNumber(req.params.page) || !validateNumber(req.params.size))
    return res.sendStatus(400)
  const page = parseInt(req.params.page, 10)
  const size = parseInt(req.params.size, 10)
  const query = db.Log.findAll({where: {server: req.params.id}, offset: (page - 1) * size, limit: size, order: [['timestamp', 'DESC']]})
  query.then((data) => {
    res.json(data.map((item) => ({server: item.server, node: item.node, timestamp: item.timestamp, event: item.event})))
  })
})

const server = http.createServer(app)
const wss = new WebSocket.Server({server})

wss.on('connection', (ws) => {
  const id = uuid()
  clients.set(id, ws)
  ws.on('close', () => clients.delete(id))
  ws.on('error', (err) => {
    log(err)
    clients.delete(id)
  })
})

db.init().then(() => db.state()).then((entries) => {
  loadIPdatabase().then(() => {
    servers.forEach((server, idx) => {
      server.entries = entries.filter((entry) => entry.server === idx).map((entry) => {
        const data = {
          name: entry.node,
          timestamp: entry.timestamp,
          pub: entry.pub,
          vpn: entry.vpn
        }
        const loc = cityLookup.get(entry.pub)
        if (entry.pub && loc) {
          data.country_code = loc.country.iso_code
          data.country_name = loc.country.names.en
        }
        return data
      })
    })
    server.listen({host: conf.get('bind'),port: conf.get('port'),exclusive: true})
  })
})
<|endoftext|>


<commit_before>/*jslint forin:true sub:true anon:true, sloppy:true, stupid:true nomen:true, node:true continue:true*/

/*
 * Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
 * Copyrights licensed under the New BSD License.
 * See the accompanying LICENSE file for terms.
 */

var http = require('http'),
    log4js = require("log4js"),
    fs = require('fs'),
    path = require('path'),
    portchecker = require("../../ext-lib/portchecker"),
    url = require('url'),
    StringDecoder = require('string_decoder').StringDecoder,
    decoder;

function ProxyManager(routerConfig) {
    this.routerJsonPath = routerConfig;
    this.logger = log4js.getLogger("ProxyManager");
    if (global.workingDirectory) {
        this.fileName = path.resolve(global.workingDirectory, "proxy.log");
    } else {
        this.fileName = "proxy.log";
    }
    this.record = [];
}

/**
 *
 * @param router - proxy configuration defined in json file
 * @param request - request
 * @return {Object} - Options
 */
ProxyManager.prototype.getOptions = function(router, request) {

    this.logger.info("***In getOptions");
    var reqHost = request.headers['host'],
        reqUrl = request.url,
        reqHeaders = request.headers,
        port = 80,
        options,
        objUrl,
        hd,
        i,
        self = this;

    if (router[reqHost]) {
        this.logger.info("***In getOptions...Router reqHost :" + reqHost + ", router[reqHost]:" + JSON.stringify(router[reqHost]));
        hd = router[reqHost].headers;
        if (hd) {
            for (i = 0; i < hd.length; i += 1) {
                reqHeaders[hd[i].param] = hd[i].value;
            }
        }
        if (router[reqHost].record) {
            this.logger.info("***In getOptions...router[reqHost].record :" + JSON.stringify(router[reqHost].record));
            self.record.push({"url": reqUrl, "headers": request.headers, "method": request.method});
        }

        if (router[reqHost].newHost) {
            this.logger.info("***In getOptions...router[reqHost].newHost :" + JSON.stringify(router[reqHost].newHost));
            reqUrl = reqUrl.replace(reqHost, router[reqHost].newHost);
            reqHost = router[reqHost].newHost;
        }
    }

    this.logger.info("***In getOptions...Before decoding,reqUrl :" + reqUrl);
    decoder = new StringDecoder('utf8');
    reqUrl = decoder.write(reqUrl);
    this.logger.info("***In getOptions...After decoding,reqUrl :" + reqUrl);

    objUrl = url.parse(reqUrl);

    if (objUrl.port) {
        try {
            if (port !== undefined) {
                port = objUrl.port;
            }
        } catch (e) {
            port = 80;
        }
    }

    options = {
        host: reqHost,
        port: port,
        path: reqUrl,
        method: request.method,
        headers: reqHeaders
    };

    this.logger.info("***In getOptions...options :" + JSON.stringify(options));

    return options;

};

ProxyManager.prototype.runRouterProxy = function(minPort, maxPort, host, callback) {

    var options, router, proxy, proxy_request,
        self = this,
        hd,
        i,
        objUrl,
        reqUrl,
        port;

    this.logger.info("Starting Proxy");
    try {

        // Need to check/maintain how many descriptors require proxy.Set path for those descriptors at testSession level
        if (self.routerJsonPath) {
            router = JSON.parse(fs.readFileSync(self.routerJsonPath, "utf-8"));
        } else {
            router = {};
        }

        this.logger.info("Proxy Router Config :" + JSON.stringify(router));

        portchecker.getFirstAvailable(minPort, maxPort, host, function(p, host) {

            if (p === -1) {
                callback("Error : No free ports found for Proxy Server on " + host + " between " + minPort + " and " + maxPort);
            } else {

                self.proxyServer = http.createServer(function (request, response) {

                    options = self.getOptions(router, request);
                    port = options.port;
                    reqUrl = options.path;
                    self.logger.info("*****Options::" + JSON.stringify(options));

                    proxy_request = http.request(options, function(proxy_response) {

                        proxy_response.addListener('data', function(chunk) {
                            response.write(chunk, 'binary');
                        });

                        proxy_response.addListener('end', function() {
                            response.end();
                        });

                        self.logger.info(port + ":" + reqUrl + ":" + proxy_response.statusCode);
                        self.writeLog(port + ":" + reqUrl + ":" + proxy_response.statusCode);
                        response.writeHead(proxy_response.statusCode, proxy_response.headers);

                    });

                    request.addListener('data', function(chunk) {
                        proxy_request.write(chunk, 'binary');
                    });

                    request.addListener('end', function() {
                        proxy_request.end();
                    });

                    proxy_request.on('error', function (err, req, res) {
                        self.logger.info("Proxy Error, Request URL : " + request.url);
                        self.logger.warn("Proxy Error, Request URL : " + request.url);
                        response.writeHead(500, {
                            'Content-Type': 'text/plain'
                        });
                        self.logger.info('Something went wrong: ' + JSON.stringify(err));
                        response.end('Something went wrong: ' + JSON.stringify(err));
                    });

                }).listen(p);

                //console.log('<<\nProxy Server started on port-'+p);
                callback(host + ":" + p);
            }

        });
    } catch (e) {
        //console.log("Error :" + e.toString());
        callback("Error :" + e.toString());
    }
};

ProxyManager.prototype.writeLog = function (logLine) {

    var StringDecoder = require('string_decoder').StringDecoder,
        decoder = new StringDecoder('utf8'),
        data = decoder.write(logLine + "\n"),
        fd;

    fd = fs.openSync(this.fileName, 'a');
    fs.writeSync(fd, data);
    fs.closeSync(fd);

//    fs.appendFileSync(this.fileName, data);

};

module.exports = ProxyManager;<commit_msg>Decoding & replacing =<commit_after>/*jslint forin:true sub:true anon:true, sloppy:true, stupid:true nomen:true, node:true continue:true*/

/*
 * Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
 * Copyrights licensed under the New BSD License.
 * See the accompanying LICENSE file for terms.
 */

var http = require('http'),
    log4js = require("log4js"),
    fs = require('fs'),
    path = require('path'),
    portchecker = require("../../ext-lib/portchecker"),
    url = require('url'),
    StringDecoder = require('string_decoder').StringDecoder,
    decoder;

function ProxyManager(routerConfig) {
    this.routerJsonPath = routerConfig;
    this.logger = log4js.getLogger("ProxyManager");
    if (global.workingDirectory) {
        this.fileName = path.resolve(global.workingDirectory, "proxy.log");
    } else {
        this.fileName = "proxy.log";
    }
    this.record = [];
}

/**
 *
 * @param router - proxy configuration defined in json file
 * @param request - request
 * @return {Object} - Options
 */
ProxyManager.prototype.getOptions = function(router, request) {

    this.logger.info("***In getOptions");
    var reqHost = request.headers['host'],
        reqUrl = request.url,
        reqHeaders = request.headers,
        port = 80,
        options,
        objUrl,
        hd,
        i,
        self = this;

    if (router[reqHost]) {
        this.logger.info("***In getOptions...Router reqHost :" + reqHost + ", router[reqHost]:" + JSON.stringify(router[reqHost]));
        hd = router[reqHost].headers;
        if (hd) {
            for (i = 0; i < hd.length; i += 1) {
                reqHeaders[hd[i].param] = hd[i].value;
            }
        }
        if (router[reqHost].record) {
            this.logger.info("***In getOptions...router[reqHost].record :" + JSON.stringify(router[reqHost].record));
            self.record.push({"url": reqUrl, "headers": request.headers, "method": request.method});
        }

        if (router[reqHost].newHost) {
            this.logger.info("***In getOptions...router[reqHost].newHost :" + JSON.stringify(router[reqHost].newHost));
            reqUrl = reqUrl.replace(reqHost, router[reqHost].newHost);
            reqHost = router[reqHost].newHost;
        }
    }

    this.logger.info("***In getOptions...Before decoding,reqUrl :" + reqUrl);
//    decoder = new StringDecoder('utf8');
//    reqUrl = decoder.write(reqUrl);
    reqUrl = decodeURIComponent(reqUrl);
    reqUrl = reqUrl.replace(/=/g, '');
    this.logger.info("***In getOptions...After decoding,reqUrl :" + reqUrl);

    objUrl = url.parse(reqUrl);

    if (objUrl.port) {
        try {
            if (port !== undefined) {
                port = objUrl.port;
            }
        } catch (e) {
            port = 80;
        }
    }

    options = {
        host: reqHost,
        port: port,
        path: reqUrl,
        method: request.method,
        headers: reqHeaders
    };

    this.logger.info("***In getOptions...options :" + JSON.stringify(options));

    return options;

};

ProxyManager.prototype.runRouterProxy = function(minPort, maxPort, host, callback) {

    var options, router, proxy, proxy_request,
        self = this,
        hd,
        i,
        objUrl,
        reqUrl,
        port;

    this.logger.info("Starting Proxy");
    try {

        // Need to check/maintain how many descriptors require proxy.Set path for those descriptors at testSession level
        if (self.routerJsonPath) {
            router = JSON.parse(fs.readFileSync(self.routerJsonPath, "utf-8"));
        } else {
            router = {};
        }

        this.logger.info("Proxy Router Config :" + JSON.stringify(router));

        portchecker.getFirstAvailable(minPort, maxPort, host, function(p, host) {

            if (p === -1) {
                callback("Error : No free ports found for Proxy Server on " + host + " between " + minPort + " and " + maxPort);
            } else {

                self.proxyServer = http.createServer(function (request, response) {

                    options = self.getOptions(router, request);
                    port = options.port;
                    reqUrl = options.path;
                    self.logger.info("*****Options::" + JSON.stringify(options));

                    proxy_request = http.request(options, function(proxy_response) {

                        proxy_response.addListener('data', function(chunk) {
                            response.write(chunk, 'binary');
                        });

                        proxy_response.addListener('end', function() {
                            response.end();
                        });

                        self.logger.info(port + ":" + reqUrl + ":" + proxy_response.statusCode);
                        self.writeLog(port + ":" + reqUrl + ":" + proxy_response.statusCode);
                        response.writeHead(proxy_response.statusCode, proxy_response.headers);

                    });

                    request.addListener('data', function(chunk) {
                        proxy_request.write(chunk, 'binary');
                    });

                    request.addListener('end', function() {
                        proxy_request.end();
                    });

                    proxy_request.on('error', function (err, req, res) {
                        self.logger.info("Proxy Error, Request URL : " + request.url);
                        self.logger.warn("Proxy Error, Request URL : " + request.url);
                        response.writeHead(500, {
                            'Content-Type': 'text/plain'
                        });
                        self.logger.info('Something went wrong: ' + JSON.stringify(err));
                        response.end('Something went wrong: ' + JSON.stringify(err));
                    });

                }).listen(p);

                //console.log('<<\nProxy Server started on port-'+p);
                callback(host + ":" + p);
            }

        });
    } catch (e) {
        //console.log("Error :" + e.toString());
        callback("Error :" + e.toString());
    }
};

ProxyManager.prototype.writeLog = function (logLine) {

    var StringDecoder = require('string_decoder').StringDecoder,
        decoder = new StringDecoder('utf8'),
        data = decoder.write(logLine + "\n"),
        fd;

    fd = fs.openSync(this.fileName, 'a');
    fs.writeSync(fd, data);
    fs.closeSync(fd);

//    fs.appendFileSync(this.fileName, data);

};

module.exports = ProxyManager;<|endoftext|>


<commit_before>jQuery.sap.require("util.Formatter");
jQuery.sap.require("sap.m.MessageToast");
jQuery.sap.require("sap.m.MessageBox");
jQuery.sap.require("util.Util");

sap.ui.controller("view.Product", {

	_oModel : null,
	_oView : null,
	_oProductData : null,
	_iProductIdx : '',

	onInit : function () {
		this._router = sap.ui.core.UIComponent.getRouterFor(this);
		this._router.getRoute("product").attachPatternMatched(this._routePatternMatched, this);
		this._router.getRoute("cartProduct").attachPatternMatched(this._routePatternMatched, this);

		// register for events
		var oBus = sap.ui.getCore().getEventBus();
		oBus.subscribe("shoppingCart", "updateProduct", this.fnUpdateProduct, this);
	},

	_routePatternMatched: function(oEvent) {
		var sProductId = oEvent.getParameter("arguments").productId;
		this._oView = this.getView();
		this._oModel = this._oView.getModel();
		this._iProductIdx = util.Util.parseIndex(sProductId) - 1;
		this._oProductData = this._oModel.getData().Products;
		var oProduct = this._oProductData[this._iProductIdx];

		if (!oProduct) {
			this._checkIfProductAvailable(this._iProductIdx, sProductId);
		}

		var oJSONModel = new sap.ui.model.json.JSONModel();
		oJSONModel.setData(oProduct);
		this._oView.byId("page").setModel(oJSONModel, "productDetail");
	},

	fnUpdateProduct: function(sChannel, sEvent, oData) {
		var iProductIdx = util.Util.parseIndex(oData.productId) - 1;
		this._iProductIdx = iProductIdx;
		var oProduct = this._oProductData[iProductIdx];
		var oModel = new sap.ui.model.json.JSONModel();
		oModel.setData(oProduct);
    	this._oView.byId("page").setModel(oModel, "productDetail");

		// this._checkIfProductAvailable(sPath, oData.productId);
	},

	_checkIfProductAvailable: function(iProductIdx, sProductId) {
		var oProduct = this._oProductData[iProductIdx];

		// show not found page
		if (!oProduct) {
			this._router.getTargets().display("notFound", sProductId);
		}
	},

	handleAddButtonPress : function (oEvent) {
		var oBundle = sap.ui.getCore().getModel("i18n").getResourceBundle();
		var oProduct = this._oProductData[this._iProductIdx];
		var sProdStatus = oProduct.status;
		var that = this;

		switch (sProdStatus) {
		case "D":
			//show message dialog
			sap.m.MessageBox.show(
				oBundle.getText("PRODUCT_STATUS_DISCONTINUED_MSG"),{
				icon: sap.m.MessageBox.Icon.ERROR,
				titles: oBundle.getText("PRODUCT_STATUS_DISCONTINUED_TITLE"),
				actions: [sap.m.MessageBox.Action.CLOSE]
		});
			break;
		case "O":
			// show message dialog
			sap.m.MessageBox.show(
				oBundle.getText("PRODUCT_STATUS_OUT_OF_STOCK_MSG"), {
					icon: sap.m.MessageBox.Icon.QUESTION,
					title: oBundle.getText("PRODUCT_STATUS_OUT_OF_STOCK_TITLE"),
					actions: [sap.m.MessageBox.Action.OK, sap.m.MessageBox.Action.CANCEL],
					onClose: function (oAction) {
						// order
						if (sap.m.MessageBox.Action.OK === oAction) {
							that._addProduct(oProduct);
						}
					}
				});
			break;
		case "A":
			this._addProduct(oProduct);
			break;
		default:
			if (!model.Config.isMock) {
				this._addProduct(oProduct);
			} else {
				// log error
				jQuery.sap.log.error("Unhandled product status: " + oProduct.status + ", " + model.Config.isMock);
			}
			break;
		}
	},

	_addProduct: function(oProduct) {
		var oCartModel = this.getView().getModel("cartProducts");
		var oCartData = oCartModel.getData();
		var aCartEntries = oCartData.entries;

		// find existing entry for product
		var oEntry = null;
		for (var i = 0 ; i < aCartEntries.length ; i ++) {
			if (aCartEntries[i].ProductId === oProduct.ProductId) {
				oEntry = aCartEntries[i];
				break;
			}
		}

		if (oEntry === null) {
			// create new entry
			oEntry = {
				Id : jQuery.sap.uid(),
				Quantity : 1,
				Name : oProduct.Name,
				ProductId : oProduct.ProductId,
				ProductName : oProduct.Name,
				Price : oProduct.Price,
				SupplierName : oProduct.SupplierName,
				Status : oProduct.status,
				Weight : oProduct.Weight,
				PictureUrl : oProduct.PictureUrl
			};
			oCartData.entries[oCartData.entries.length] = oEntry;

		} else {
			// update existing entry
			oEntry.Quantity += 1;
		}

		// recalculate total price
		oCartData.totalPrice = 0;
		for (var j = 0 ; j < oCartData.entries.length ; j ++) {
			oCartData.totalPrice += parseFloat(oCartData.entries[j].Price) * oCartData.entries[j].Quantity;
		}

		//if there is at least one entry, the edit button is shown
		oCartData.showEditAndProceedButton = true;

		// update model
		oCartModel.setData(oCartData);

		var oBundle = sap.ui.getCore().getModel("i18n").getResourceBundle();
		sap.m.MessageToast.show(oBundle.getText("PRODUCT_MSG_ADDED_TO_CART"));
	},

	handleCartButtonPress :  function (oEvent) {
		this._router.navTo("cart");
	},

	handleNavButtonPress : function (oEvent) {
		this.getOwnerComponent().myNavBack();
	}

});
<commit_msg>added the logic to route user to welcome page back to product controller if user tries to access the product page directly<commit_after>jQuery.sap.require("util.Formatter");
jQuery.sap.require("sap.m.MessageToast");
jQuery.sap.require("sap.m.MessageBox");
jQuery.sap.require("util.Util");

sap.ui.controller("view.Product", {

	_oModel : null,
	_oView : null,
	_oProductData : null,
	_iProductIdx : '',

	onInit : function () {
		this._router = sap.ui.core.UIComponent.getRouterFor(this);
		this._router.getRoute("product").attachPatternMatched(this._routePatternMatched, this);
		this._router.getRoute("cartProduct").attachPatternMatched(this._routePatternMatched, this);

		// register for events
		var oBus = sap.ui.getCore().getEventBus();
		oBus.subscribe("shoppingCart", "updateProduct", this.fnUpdateProduct, this);
	},

	_routePatternMatched: function(oEvent) {
		var sProductId = oEvent.getParameter("arguments").productId;
		this._oView = this.getView();
		this._oModel = this._oView.getModel();

		if (!this._oModel) {
			this._router.navTo("home", {}, true);
			if (!sap.ui.Device.system.phone) {
				this._router.getTargets().display("welcome");
			}
		} else {
			this._iProductIdx = util.Util.parseIndex(sProductId) - 1;
			this._oProductData = this._oModel.getData().Products;
			var oProduct = this._oProductData[this._iProductIdx];

			if (!oProduct) {
				this._checkIfProductAvailable(this._iProductIdx, sProductId);
			}

			var oJSONModel = new sap.ui.model.json.JSONModel();
			oJSONModel.setData(oProduct);
			this._oView.byId("page").setModel(oJSONModel, "productDetail");
		}
	},

	fnUpdateProduct: function(sChannel, sEvent, oData) {
		var iProductIdx = util.Util.parseIndex(oData.productId) - 1;
		this._iProductIdx = iProductIdx;
		var oProduct = this._oProductData[iProductIdx];
		var oModel = new sap.ui.model.json.JSONModel();
		oModel.setData(oProduct);
    	this._oView.byId("page").setModel(oModel, "productDetail");

		// this._checkIfProductAvailable(sPath, oData.productId);
	},

	_checkIfProductAvailable: function(iProductIdx, sProductId) {
		var oProduct = this._oProductData[iProductIdx];

		// show not found page
		if (!oProduct) {
			this._router.getTargets().display("notFound", sProductId);
		}
	},

	handleAddButtonPress : function (oEvent) {
		var oBundle = sap.ui.getCore().getModel("i18n").getResourceBundle();
		var oProduct = this._oProductData[this._iProductIdx];
		var sProdStatus = oProduct.status;
		var that = this;

		switch (sProdStatus) {
		case "D":
			//show message dialog
			sap.m.MessageBox.show(
				oBundle.getText("PRODUCT_STATUS_DISCONTINUED_MSG"),{
				icon: sap.m.MessageBox.Icon.ERROR,
				titles: oBundle.getText("PRODUCT_STATUS_DISCONTINUED_TITLE"),
				actions: [sap.m.MessageBox.Action.CLOSE]
		});
			break;
		case "O":
			// show message dialog
			sap.m.MessageBox.show(
				oBundle.getText("PRODUCT_STATUS_OUT_OF_STOCK_MSG"), {
					icon: sap.m.MessageBox.Icon.QUESTION,
					title: oBundle.getText("PRODUCT_STATUS_OUT_OF_STOCK_TITLE"),
					actions: [sap.m.MessageBox.Action.OK, sap.m.MessageBox.Action.CANCEL],
					onClose: function (oAction) {
						// order
						if (sap.m.MessageBox.Action.OK === oAction) {
							that._addProduct(oProduct);
						}
					}
				});
			break;
		case "A":
			this._addProduct(oProduct);
			break;
		default:
			if (!model.Config.isMock) {
				this._addProduct(oProduct);
			} else {
				// log error
				jQuery.sap.log.error("Unhandled product status: " + oProduct.status + ", " + model.Config.isMock);
			}
			break;
		}
	},

	_addProduct: function(oProduct) {
		var oCartModel = this.getView().getModel("cartProducts");
		var oCartData = oCartModel.getData();
		var aCartEntries = oCartData.entries;

		// find existing entry for product
		var oEntry = null;
		for (var i = 0 ; i < aCartEntries.length ; i ++) {
			if (aCartEntries[i].ProductId === oProduct.ProductId) {
				oEntry = aCartEntries[i];
				break;
			}
		}

		if (oEntry === null) {
			// create new entry
			oEntry = {
				Id : jQuery.sap.uid(),
				Quantity : 1,
				Name : oProduct.Name,
				ProductId : oProduct.ProductId,
				ProductName : oProduct.Name,
				Price : oProduct.Price,
				SupplierName : oProduct.SupplierName,
				Status : oProduct.status,
				Weight : oProduct.Weight,
				PictureUrl : oProduct.PictureUrl
			};
			oCartData.entries[oCartData.entries.length] = oEntry;

		} else {
			// update existing entry
			oEntry.Quantity += 1;
		}

		// recalculate total price
		oCartData.totalPrice = 0;
		for (var j = 0 ; j < oCartData.entries.length ; j ++) {
			oCartData.totalPrice += parseFloat(oCartData.entries[j].Price) * oCartData.entries[j].Quantity;
		}

		//if there is at least one entry, the edit button is shown
		oCartData.showEditAndProceedButton = true;

		// update model
		oCartModel.setData(oCartData);

		var oBundle = sap.ui.getCore().getModel("i18n").getResourceBundle();
		sap.m.MessageToast.show(oBundle.getText("PRODUCT_MSG_ADDED_TO_CART"));
	},

	handleCartButtonPress :  function (oEvent) {
		this._router.navTo("cart");
	},

	handleNavButtonPress : function (oEvent) {
		this.getOwnerComponent().myNavBack();
	}

});
<|endoftext|>