<commit_before>// multiclock app.js

var beginYear = new Date();
beginYear.setMonth(0);
beginYear.setDate(1);
beginYear.setHours(0);
beginYear.setMinutes(0);
beginYear.setSeconds(0);

var endYear = new Date();
endYear.setMonth(11);
endYear.setDate(31);
endYear.setHours(23);
endYear.setMinutes(59);
endYear.setSeconds(59);

var oneDay = 1000 * 60 * 60 * 24;

var dayScale = d3.scale.linear().domain([24, 0]).range([0, 2 * Math.PI]);
var yearScale = d3.scale.linear().domain([endYear.getTime(), beginYear.getTime()]).range([0, 2 * Math.PI]);
var yearDegreesScale = d3.scale.linear().domain([beginYear.getTime(), endYear.getTime()]).range([0, 360]);

function initializeDayCircle(face) {
	// set of arcs representing 24hours, showing sunlight

	var dayCircle = face.append('g')
		.attr('id','dayCircle');

	var sunlightArc = d3.svg.arc()
		.innerRadius(200)
		.outerRadius(220)
		.startAngle(dayScale(6))
		.endAngle(dayScale(20));

	dayCircle.append("path")
		.attr("id", 'sunlightArc')
		.attr("d", sunlightArc)

	var nightArc = d3.svg.arc()
		.innerRadius(200)
		.outerRadius(220)
		.startAngle(dayScale(20))
		.endAngle(dayScale(30));

	dayCircle.append("path")
		.attr("id", 'nightArc')
		.attr("d", nightArc);
}

function initializeClockArcs(face) {
	// small mark that weeps once a minute

	var minuteArc = d3.svg.arc()
		.innerRadius(80)
		.outerRadius(85)
		.startAngle(-0.025 * Math.PI)
		.endAngle(0.025 * Math.PI);

	face.append("path")
		.attr("id", 'minuteArc')
		.attr("d", minuteArc)

	// small arc that sweeps once an hour

	var hourArc = d3.svg.arc()
		.innerRadius(87)
		.outerRadius(92)
		.startAngle(-0.025 * Math.PI)
		.endAngle(0.025 * Math.PI);

	face.append("path")
		.attr("id", 'hourArc')
		.attr("d", hourArc);
}

function getEasterForYear(Y) {
    // http://coderzone.org/library/Get-Easter-Date-for-any-year-in-Javascript_1059.htm
    var C = Math.floor(Y/100);
    var N = Y - 19*Math.floor(Y/19);
    var K = Math.floor((C - 17)/25);
    var I = C - Math.floor(C/4) - Math.floor((C - K)/3) + 19*N + 15;
    I = I - 30*Math.floor((I/30));
    I = I - Math.floor(I/28)*(1 - Math.floor(I/28)*Math.floor(29/(I + 1))*Math.floor((21 - N)/11));
    var J = Y + Math.floor(Y/4) + I + 2 - C + Math.floor(C/4);
    J = J - 7*Math.floor(J/7);
    var L = I - J;
    var M = 3 + Math.floor((L + 40)/44);
    var D = L + 28 - 31*Math.floor(M/4);

    return new Date(Y, M-1, D);
}

function getSeasonsForYear(Y) {
    var days = {};

    // epiphany is fixed
    days.epiphany = new Date(Y,0,6);
    // easter follows crazy formula above
    days.easter = getEasterForYear(Y);
    // ash wednesday fixed days before easter
    days.ashWednesday = new Date(days.easter.getTime() - 45 * oneDay);
    // palm sunday one week before easter
    days.palmSunday = new Date(days.easter.getTime() - 7 * oneDay);
    // pentecost 50 days after easter
    days.pentecost = new Date(days.easter.getTime() + 49 * oneDay);
    // ascension 40 days after easter
    days.ascension = new Date(days.easter.getTime() + 39 * oneDay);

    // christmas is fixed
    days.christmas = new Date(Y,11,25);

    //advent starts the closest sunday before nov 30?
    days.advent = new Date(Y, 10, 30);
    days.advent = new Date(days.advent.getTime() - days.advent.getDay() * oneDay);

    // console.log(days);

    var seasons = [
	    [days.advent.getTime(), days.christmas.getTime(), 'advent'],
	    [days.ashWednesday.getTime(), days.palmSunday.getTime(), 'lent'],
	    [days.palmSunday.getTime(), days.easter.getTime(), 'holyWeek'],
	    [days.easter.getTime(), days.pentecost.getTime(), 'easter'],
	    [days.pentecost.getTime(), days.advent.getTime(), 'ordinary']
    ];

    // console.log(seasons);
    return seasons;
}

function addSundays(seasons, Y) {
	var D = new Date(Y,0,1)
	var day = D.getDay();
	if (day != 0) D.setDate(D.getDate() + (7 - day));

	while (D) {
	    D.setDate(D.getDate()+7);
	    if (D.getFullYear() != Y) return;
	    seasons.push([D.getTime(), D.getTime() + 0.3 * oneDay, 'sunday']);
	}
}

function initializeYearCircle(face) {
	// set of arcs representing a year, showing liturgical calendar

	var yearCircle = face.append('g')
		.attr('id', 'yearCircle');

	var seasons = getSeasonsForYear(new Date().getFullYear());

	addSundays(seasons, new Date().getFullYear());

	var seasonArc = d3.svg.arc()
		.innerRadius(300)
		.outerRadius(340)
		.startAngle(function(d) {
			return yearScale(d[0]);
		})
		.endAngle(function(d){
			return yearScale(d[1]);
		});

	yearCircle.selectAll("path")
		.data(seasons)
		.enter()
		.append("path")
		.attr("d", seasonArc)
		.attr("id", function(d){
			return d[2];
		});

	yearCircle.selectAll("path").data(seasons).enter();
}

function initializeClock() {
	var vis = d3.select("#svg_donut");

	var face = vis.append('g')
		.attr('id','clock-face')
		.attr('transform','translate(400,400)');

	// background gray circle

	var fullArc = d3.svg.arc()
		.innerRadius(80)
		.outerRadius(340)
		.startAngle(0)
		.endAngle(2 * Math.PI);

	face.append("path")
		.attr("id", 'fullArc')
		.attr("d", fullArc)

	initializeClockArcs(face);

	initializeDayCircle(face);

	initializeYearCircle(face);

	// vertical mark showing now

	face.append("rect")
      .attr("class", "bar")
      .attr("x", 0)
      .attr("width", 1)
      .attr("y", -340)
      .attr("height", 300);
}

function step(timestamp) {
	d3.select('#minuteArc')
		.attr('transform', function(d){
			var angle = 360 * ((new Date().getTime() / 1000) % 60) / 60.0;
			return 'rotate(' + angle + ')';
		});

	d3.select('#hourArc')
		.attr('transform', function(d){
			var angle = 360 * ((new Date().getTime() / 1000) % 3600) / 3600.0;
			return 'rotate(' + angle + ')';
		});

	d3.select('#dayCircle')
		.attr('transform', function(d){
			var tmp = new Date();
			var percentage = (tmp.getHours() * 3600 + tmp.getMinutes() * 60) / 86400.0;
			var angle = 360 * percentage;
			return 'rotate(' + angle + ')';
		});

	d3.select('#yearCircle')
		.attr('transform', function(d){
			var tmp = new Date();
			return 'rotate(' + yearDegreesScale(tmp.getTime()) + ')';
		});

	window.setTimeout(step, 200);
}

initializeClock();
window.setTimeout(step, 200);<commit_msg>transitions are teh awesomez<commit_after>// multiclock app.js

var beginYear = new Date();
beginYear.setMonth(0);
beginYear.setDate(1);
beginYear.setHours(0);
beginYear.setMinutes(0);
beginYear.setSeconds(0);

var endYear = new Date();
endYear.setMonth(11);
endYear.setDate(31);
endYear.setHours(23);
endYear.setMinutes(59);
endYear.setSeconds(59);

var oneDay = 1000 * 60 * 60 * 24;

var dayScale = d3.scale.linear().domain([24, 0]).range([0, 2 * Math.PI]);
var yearScale = d3.scale.linear().domain([endYear.getTime(), beginYear.getTime()]).range([0, 2 * Math.PI]);
var yearDegreesScale = d3.scale.linear().domain([beginYear.getTime(), endYear.getTime()]).range([0, 360]);

function initializeDayCircle(face) {
	// set of arcs representing 24hours, showing sunlight

	var dayCircle = face.append('g')
		.attr('id','dayCircle');

	var sunlightArc = d3.svg.arc()
		.innerRadius(200)
		.outerRadius(220)
		.startAngle(dayScale(6))
		.endAngle(dayScale(20));

	dayCircle.append("path")
		.attr("id", 'sunlightArc')
		.attr("d", sunlightArc)

	var nightArc = d3.svg.arc()
		.innerRadius(200)
		.outerRadius(220)
		.startAngle(dayScale(20))
		.endAngle(dayScale(30));

	dayCircle.append("path")
		.attr("id", 'nightArc')
		.attr("d", nightArc);
}

function initializeClockArcs(face) {
	// small mark that weeps once a minute

	var minuteArc = d3.svg.arc()
		.innerRadius(80)
		.outerRadius(85)
		.startAngle(-0.025 * Math.PI)
		.endAngle(0.025 * Math.PI);

	face.append("path")
		.attr("id", 'minuteArc')
		.attr("d", minuteArc)

	// small arc that sweeps once an hour

	var hourArc = d3.svg.arc()
		.innerRadius(87)
		.outerRadius(92)
		.startAngle(-0.025 * Math.PI)
		.endAngle(0.025 * Math.PI);

	face.append("path")
		.attr("id", 'hourArc')
		.attr("d", hourArc);
}

function getEasterForYear(Y) {
    // http://coderzone.org/library/Get-Easter-Date-for-any-year-in-Javascript_1059.htm
    var C = Math.floor(Y/100);
    var N = Y - 19*Math.floor(Y/19);
    var K = Math.floor((C - 17)/25);
    var I = C - Math.floor(C/4) - Math.floor((C - K)/3) + 19*N + 15;
    I = I - 30*Math.floor((I/30));
    I = I - Math.floor(I/28)*(1 - Math.floor(I/28)*Math.floor(29/(I + 1))*Math.floor((21 - N)/11));
    var J = Y + Math.floor(Y/4) + I + 2 - C + Math.floor(C/4);
    J = J - 7*Math.floor(J/7);
    var L = I - J;
    var M = 3 + Math.floor((L + 40)/44);
    var D = L + 28 - 31*Math.floor(M/4);

    return new Date(Y, M-1, D);
}

function getSeasonsForYear(Y) {
    var days = {};

    // epiphany is fixed
    days.epiphany = new Date(Y,0,6);
    // easter follows crazy formula above
    days.easter = getEasterForYear(Y);
    // ash wednesday fixed days before easter
    days.ashWednesday = new Date(days.easter.getTime() - 45 * oneDay);
    // palm sunday one week before easter
    days.palmSunday = new Date(days.easter.getTime() - 7 * oneDay);
    // pentecost 50 days after easter
    days.pentecost = new Date(days.easter.getTime() + 49 * oneDay);
    // ascension 40 days after easter
    days.ascension = new Date(days.easter.getTime() + 39 * oneDay);

    // christmas is fixed
    days.christmas = new Date(Y,11,25);

    //advent starts the closest sunday before nov 30?
    days.advent = new Date(Y, 10, 30);
    days.advent = new Date(days.advent.getTime() - days.advent.getDay() * oneDay);

    // console.log(days);

    var seasons = [
	    [days.advent.getTime(), days.christmas.getTime(), 'advent'],
	    [days.ashWednesday.getTime(), days.palmSunday.getTime(), 'lent'],
	    [days.palmSunday.getTime(), days.easter.getTime(), 'holyWeek'],
	    [days.easter.getTime(), days.pentecost.getTime(), 'easter'],
	    [days.pentecost.getTime(), days.advent.getTime(), 'ordinary']
    ];

    // console.log(seasons);
    return seasons;
}

function addSundays(seasons, Y) {
	var D = new Date(Y,0,1)
	var day = D.getDay();
	if (day != 0) D.setDate(D.getDate() + (7 - day));

	while (D) {
	    D.setDate(D.getDate()+7);
	    if (D.getFullYear() != Y) return;
	    seasons.push([D.getTime(), D.getTime() + 0.3 * oneDay, 'sunday']);
	}
}

function initializeYearCircle(face) {
	// set of arcs representing a year, showing liturgical calendar

	var yearCircle = face.append('g')
		.attr('id', 'yearCircle');

	var seasons = getSeasonsForYear(new Date().getFullYear());

	addSundays(seasons, new Date().getFullYear());

	var seasonArc = d3.svg.arc()
		.innerRadius(300)
		.outerRadius(340)
		.startAngle(function(d) {
			return yearScale(d[0]);
		})
		.endAngle(function(d){
			return yearScale(d[1]);
		});

	yearCircle.selectAll("path")
		.data(seasons)
		.enter()
		.append("path")
		.attr("d", seasonArc)
		.attr("id", function(d){
			return d[2];
		});

	yearCircle.selectAll("path").data(seasons).enter();
}

function initializeClock() {
	var vis = d3.select("#svg_donut");

	var face = vis.append('g')
		.attr('id','clock-face')
		.attr('transform','translate(400,400)');

	// background gray circle

	var fullArc = d3.svg.arc()
		.innerRadius(80)
		.outerRadius(340)
		.startAngle(0)
		.endAngle(2 * Math.PI);

	face.append("path")
		.attr("id", 'fullArc')
		.attr("d", fullArc)

	initializeClockArcs(face);

	initializeDayCircle(face);

	initializeYearCircle(face);

	// vertical mark showing now

	face.append("rect")
      .attr("class", "bar")
      .attr("x", 0)
      .attr("width", 1)
      .attr("y", -340)
      .attr("height", 300);
}

function step(timestamp) {

	d3.select('#minuteArc')
		.transition()
		.attr('transform', function(d){
			var angle = 360 * ((new Date().getTime() / 1000) % 60) / 60.0;
			return 'rotate(' + Math.round(angle) + ')';
		});

	d3.select('#hourArc')
		.transition()
		.attr('transform', function(d){
			var angle = 360 * ((new Date().getTime() / 1000) % 3600) / 3600.0;
			return 'rotate(' + angle + ')';
		});

	d3.select('#dayCircle')
		.transition()
		.attr('transform', function(d){
			var tmp = new Date();
			var percentage = (tmp.getHours() * 3600 + tmp.getMinutes() * 60) / 86400.0;
			var angle = 360 * percentage;
			return 'rotate(' + angle + ')';
		});

	d3.select('#yearCircle')
		.transition()
		.attr('transform', function(d){
			var tmp = new Date();
			return 'rotate(' + yearDegreesScale(tmp.getTime()) + ')';
		});

	window.setTimeout(step, 1000);
}

initializeClock();
window.setTimeout(step, 1000);<|endoftext|>


<commit_before>/////////////////////////////////////
/* Problem 1 (this is your demo)
Write a function called sum() that takes in two numbers as arguments and then returns an array where the first element is the sum of those numbers, and the second element is a string that EXACTLY follows this example and uses the values that were input into the function:

"The sum of 4 and 7 is 11."

Test this function by hand in the console to get it working, and when you think it is finished, uncomment the call for the testSum() function below and check the console to see if the test passes.*/

// Write your code here
function sum(input1, input2) {
  var total = input1 + input2;
  var stringOutcome = 'The sum of ' + input1 + ' and ' + input2 + ' is ' + total + '.';
  var outcome = [total, stringOutcome];

return outcome;
}
// Here is the test for sum(); uncomment it to run it

testSum(4, 7);

// Once you get the test passing, do an a-c-p cycle, synchronize the code between both GitHubs and both laptops, and swap Driver/Navigator roles. Don't forget to create a new branch for your work on the next question!

/////////////////////////////////////
/* Problem 2
Write a function called multiply() that takes in two numbers as arguments and returns an array where the first element is the product of those numbers, and the second element is a string that EXACTLY follows this example and uses the values that were input into the function:

"The product of 4 and 7 is 28."

Test this function by hand in the console to get it working, and when you think it is finished, uncomment the call for the testMultiply() function and see if the test passes.*/

// Write your code here
function multiply(input3, input4){
  var totalFromSum = input3 * input4;
  var stringOutcomeSum = 'The product of ' + input3 + ' and ' +  input4 + ' is ' + totalFromSum + '.';
  var outcomeFromSum = [totalFromSum, stringOutcomeSum];

  return outcomeFromSum;
}
// Here is the test for multiply(); uncomment it to run it
testMultiply(4,7);

// Once you get the test passing, do an a-c-p cycle, synchronize the code between both GitHubs and both laptops, and swap Driver/Navigator roles. Don't forget to create a new branch for your work on the next question!

/////////////////////////////////////
/* Problem 3
Write a function called sumAndMultiply() that takes in three numbers as arguments and returns an array where the first element is the sum of those three numbers, the second element is the product of those three numbers,  and the third and fourth elements are strings that EXACTLY follow this example and use the values that were input into the function:

Third element: "4 and 7 and 5 sum to 16."
Fourth element: "The product of 4 and 7 and 5 is 140."

Test this function by hand in the console to get it working, and when you think it is finished, uncomment the call for the testMultiply() function and see if the test passes.*/

// Write your code here
function sumAndMultiply(input5, input6, input7){
  var totalSum = input5 + input6 + input7;
  var sumMultiply = input5 * input6 * input7;
  var sumMultiplyOutcome = [totalSum, sumMultiply, input5 + ' and ' + input6 + ' and ' + input7 + ' sum to ' + totalSum + '.', 'The product of ' + input5 + ' and ' + input6 + ' and ' + input7 + ' is ' + sumMultiply + '.'];

  return sumMultiplyOutcome;

  /*function sumAndMultiply(sam1, sam2, sam3){
  var add3nums = sam1 + sam2 + sam3;
  var mult3nums = sam1 * sam2 * sam3;
  var samArrayStorage = [add3nums, mult3nums, sam1 + " and " + sam2 + " and " + sam3 + " sum to " + add3nums + ".", "The product of " + sam1 + " and " + sam2 + " and " + sam3 + " is " + mult3nums + "."];
  retur

[7:49]
the return is just

[7:49]
return samArrayStorage; */

}
// Here is the test for sumAndMultiply(); uncomment it to run it
testSumAndMultiply(4,7,5);

// Once you get the test passing, do an a-c-p cycle, synchronize the code between both GitHubs and both laptops, and swap Driver/Navigator roles. don't forget to create a new branch for your work on the next question!

/////////////////////////////////////
/* Problem 4
Write a function called sumArray() that takes in an array of numbers as its argument and then returns an array where the first element is the sum of the numbers in the array, and the second element is a string that EXACTLY follows this example and uses the values that were input into the function:

"2,3,4 was passed in as an array of numbers, and 9 is their sum."

Test this function by hand in the console to get it working, and when you think it is finished, uncomment the call for the testSumArray() function and see if the test passes.*/
/*var arratString = [arratSum, testArray[0] + "," + testArrat[1] + "," + testArray[2] + " was passed in as an array of numbers, and " + sumArray + " is their sum.";*/
// Write your code here
function sumArray(testArray){
  var arraySum = testArray[0] + testArray[1] + testArray[2];
  var arrayString = [arraySum, testArray[0] + ',' + testArray[1] + ',' + testArray[2] + ' was passed in as an array of numbers, and ' + arraySum + ' is their sum.'];
return arrayString;
}
 testArray = [2,3,4];

// Here is the test for sumArray(); uncomment it to run it
testSumArray(testArray);

// Once you get the test passing, do an a-c-p cycle, synchronize the code between both GitHubs and both laptops, and swap Driver/Navigator roles. Don't forget to create a new branch for your work on the next question!

/////////////////////////////////////
/* Problem 5
Write a function called multiplyArray() that takes an array of numbers as its argument and returns an array whose first element is the product of those numbers, and the second element is a string that EXACTLY follows this example and uses the values that were input into the function:

"The numbers 2,3,4 have a product of 24."

Test this function by hand in the console to get it working, and when you think it is finished, uncomment the call for the testMultiplyArray() function and see if the test passes.*/

// Write your code here

// Here is the test for multiplyArray(); uncomment it to run it
testMultiplyArray(testArray);

// Once you get the test passing, do an a-c-p cycle, synchronize the code between both GitHubs and both laptops, and swap Driver/Navigator roles. Submit the link to the repo via Canvas.

/////////////////////////////////////
/////////////////////////////////////
/////////////////////////////////////
/////////////////////////////////////
/////////////////////////////////////
/////////////////////////////////////
/////////////////////////////////////
/////////////////////////////////////
/////////////////////////////////////
/////////////////////////////////////

function testSum() {
  if (sum(4,7)[1] === 'The sum of 4 and 7 is 11.') {
    console.log('%c TEST FOR sum() PASSES', 'color: green');
  } else {
    console.log('%c TEST FOR sum() FAILS', 'color: red');
  }
}

function testMultiply() {
  if (multiply(5,9)[1] === 'The product of 5 and 9 is 45.') {
    console.log('%c TEST FOR multiply() PASSES', 'color: green');
  } else {
    console.log('%c TEST FOR multiply() FAILS', 'color: red');
  }
}

function testSumAndMultiply() {
  if (sumAndMultiply(4, 7, 5)[2] === '4 and 7 and 5 sum to 16.' && sumAndMultiply(4, 7, 5)[3] === 'The product of 4 and 7 and 5 is 140.') {
    console.log('%c TEST FOR sumAndMultiply() PASSES', 'color: green');
  } else {
    console.log('%c TEST FOR sumAndMultiply() FAILS', 'color: red');
  }
}

function testSumArray() {
  if (sumArray(testArray)[1] === '2,3,4 was passed in as an array of numbers, and 9 is their sum.') {
    console.log('%c TEST FOR sumArray() PASSES', 'color: green');
  } else {
    console.log('%c TEST FOR sumArray() FAILS', 'color: red');
  }
}

function testMultiplyArray() {
  if (multiplyArray(testArray)[1] === 'The numbers 2,3,4 have a product of 24.') {
    console.log('%c TEST FOR multiplyArray() PASSES', 'color: green');
  } else {
    console.log('%c TEST FOR multiplyArray() FAILS', 'color: red');
  }
}
<commit_msg>added function to question 5<commit_after>/////////////////////////////////////
/* Problem 1 (this is your demo)
Write a function called sum() that takes in two numbers as arguments and then returns an array where the first element is the sum of those numbers, and the second element is a string that EXACTLY follows this example and uses the values that were input into the function:

"The sum of 4 and 7 is 11."

Test this function by hand in the console to get it working, and when you think it is finished, uncomment the call for the testSum() function below and check the console to see if the test passes.*/

// Write your code here
function sum(input1, input2) {
  var total = input1 + input2;
  var stringOutcome = 'The sum of ' + input1 + ' and ' + input2 + ' is ' + total + '.';
  var outcome = [total, stringOutcome];

return outcome;
}
// Here is the test for sum(); uncomment it to run it

testSum(4, 7);

// Once you get the test passing, do an a-c-p cycle, synchronize the code between both GitHubs and both laptops, and swap Driver/Navigator roles. Don't forget to create a new branch for your work on the next question!

/////////////////////////////////////
/* Problem 2
Write a function called multiply() that takes in two numbers as arguments and returns an array where the first element is the product of those numbers, and the second element is a string that EXACTLY follows this example and uses the values that were input into the function:

"The product of 4 and 7 is 28."

Test this function by hand in the console to get it working, and when you think it is finished, uncomment the call for the testMultiply() function and see if the test passes.*/

// Write your code here
function multiply(input3, input4){
  var totalFromSum = input3 * input4;
  var stringOutcomeSum = 'The product of ' + input3 + ' and ' +  input4 + ' is ' + totalFromSum + '.';
  var outcomeFromSum = [totalFromSum, stringOutcomeSum];

  return outcomeFromSum;
}
// Here is the test for multiply(); uncomment it to run it
testMultiply(4,7);

// Once you get the test passing, do an a-c-p cycle, synchronize the code between both GitHubs and both laptops, and swap Driver/Navigator roles. Don't forget to create a new branch for your work on the next question!

/////////////////////////////////////
/* Problem 3
Write a function called sumAndMultiply() that takes in three numbers as arguments and returns an array where the first element is the sum of those three numbers, the second element is the product of those three numbers,  and the third and fourth elements are strings that EXACTLY follow this example and use the values that were input into the function:

Third element: "4 and 7 and 5 sum to 16."
Fourth element: "The product of 4 and 7 and 5 is 140."

Test this function by hand in the console to get it working, and when you think it is finished, uncomment the call for the testMultiply() function and see if the test passes.*/

// Write your code here
function sumAndMultiply(input5, input6, input7){
  var totalSum = input5 + input6 + input7;
  var sumMultiply = input5 * input6 * input7;
  var sumMultiplyOutcome = [totalSum, sumMultiply, input5 + ' and ' + input6 + ' and ' + input7 + ' sum to ' + totalSum + '.', 'The product of ' + input5 + ' and ' + input6 + ' and ' + input7 + ' is ' + sumMultiply + '.'];

  return sumMultiplyOutcome;

  /*function sumAndMultiply(sam1, sam2, sam3){
  var add3nums = sam1 + sam2 + sam3;
  var mult3nums = sam1 * sam2 * sam3;
  var samArrayStorage = [add3nums, mult3nums, sam1 + " and " + sam2 + " and " + sam3 + " sum to " + add3nums + ".", "The product of " + sam1 + " and " + sam2 + " and " + sam3 + " is " + mult3nums + "."];
  retur

[7:49]
the return is just

[7:49]
return samArrayStorage; */

}
// Here is the test for sumAndMultiply(); uncomment it to run it
testSumAndMultiply(4,7,5);

// Once you get the test passing, do an a-c-p cycle, synchronize the code between both GitHubs and both laptops, and swap Driver/Navigator roles. don't forget to create a new branch for your work on the next question!

/////////////////////////////////////
/* Problem 4
Write a function called sumArray() that takes in an array of numbers as its argument and then returns an array where the first element is the sum of the numbers in the array, and the second element is a string that EXACTLY follows this example and uses the values that were input into the function:

"2,3,4 was passed in as an array of numbers, and 9 is their sum."

Test this function by hand in the console to get it working, and when you think it is finished, uncomment the call for the testSumArray() function and see if the test passes.*/
/*var arratString = [arratSum, testArray[0] + "," + testArrat[1] + "," + testArray[2] + " was passed in as an array of numbers, and " + sumArray + " is their sum.";*/
// Write your code here
function sumArray(testArray){
  var arraySum = testArray[0] + testArray[1] + testArray[2];
  var arrayString = [arraySum, testArray[0] + ',' + testArray[1] + ',' + testArray[2] + ' was passed in as an array of numbers, and ' + arraySum + ' is their sum.'];
return arrayString;
}
 testArray = [2,3,4];

// Here is the test for sumArray(); uncomment it to run it
testSumArray(testArray);

// Once you get the test passing, do an a-c-p cycle, synchronize the code between both GitHubs and both laptops, and swap Driver/Navigator roles. Don't forget to create a new branch for your work on the next question!

/////////////////////////////////////
/* Problem 5
Write a function called multiplyArray() that takes an array of numbers as its argument and returns an array whose first element is the product of those numbers, and the second element is a string that EXACTLY follows this example and uses the values that were input into the function:

"The numbers 2,3,4 have a product of 24."

Test this function by hand in the console to get it working, and when you think it is finished, uncomment the call for the testMultiplyArray() function and see if the test passes.*/

// Write your code here
function multiplyArray(testArray){
  var arrayMultiply = testArray[0] * testArray[1] * testArray[2];
  var multiString = [arrayMultiply, 'The numbers ' + testArray[0] + ',' + testArray[1] + ',' + testArray[2] + ' have a product of ' + arrayMultiply + '.'];
return multiString;
}
// Here is the test for multiplyArray(); uncomment it to run it
testMultiplyArray(testArray);

// Once you get the test passing, do an a-c-p cycle, synchronize the code between both GitHubs and both laptops, and swap Driver/Navigator roles. Submit the link to the repo via Canvas.

/////////////////////////////////////
/////////////////////////////////////
/////////////////////////////////////
/////////////////////////////////////
/////////////////////////////////////
/////////////////////////////////////
/////////////////////////////////////
/////////////////////////////////////
/////////////////////////////////////
/////////////////////////////////////

function testSum() {
  if (sum(4,7)[1] === 'The sum of 4 and 7 is 11.') {
    console.log('%c TEST FOR sum() PASSES', 'color: green');
  } else {
    console.log('%c TEST FOR sum() FAILS', 'color: red');
  }
}

function testMultiply() {
  if (multiply(5,9)[1] === 'The product of 5 and 9 is 45.') {
    console.log('%c TEST FOR multiply() PASSES', 'color: green');
  } else {
    console.log('%c TEST FOR multiply() FAILS', 'color: red');
  }
}

function testSumAndMultiply() {
  if (sumAndMultiply(4, 7, 5)[2] === '4 and 7 and 5 sum to 16.' && sumAndMultiply(4, 7, 5)[3] === 'The product of 4 and 7 and 5 is 140.') {
    console.log('%c TEST FOR sumAndMultiply() PASSES', 'color: green');
  } else {
    console.log('%c TEST FOR sumAndMultiply() FAILS', 'color: red');
  }
}

function testSumArray() {
  if (sumArray(testArray)[1] === '2,3,4 was passed in as an array of numbers, and 9 is their sum.') {
    console.log('%c TEST FOR sumArray() PASSES', 'color: green');
  } else {
    console.log('%c TEST FOR sumArray() FAILS', 'color: red');
  }
}

function testMultiplyArray() {
  if (multiplyArray(testArray)[1] === 'The numbers 2,3,4 have a product of 24.') {
    console.log('%c TEST FOR multiplyArray() PASSES', 'color: green');
  } else {
    console.log('%c TEST FOR multiplyArray() FAILS', 'color: red');
  }
}
<|endoftext|>


<commit_before>"use strict";
/**
 * Created by Andre LeFort on 2015-04-10.
 */

// Some bootstrapping
var requestify = require( 'requestify' ),
    mongoose = require('mongoose'),
    Schema = mongoose.Schema,
    models = require('../models/models.js'),
    http = require('http-request'),
    fs = require('fs'),
    zip = require('adm-zip'),
    csv = require('ya-csv');

var lcboLoader = {
    config: {
        url: 'https://lcboapi.com/',
        urlnonhttps: 'http://lcboapi.com/',
        per_page: 100,
        first_page: 1,
        headers: {
            'Authorization': 'Token MDphNWJlOWVlNi1kZmU2LTExZTQtOTI0Mi1iYmJjODAzYmFiMWY6akFwYTA1MG5RbHFXb3RNSG03NUE2ZUNjVnZFT3Rick9CNDNH'
        }
    },
    mongo: {
        store: {
            schema: models.schema.store
        },
        product: {
            schema: models.schema.product
        },
        inventory: {
            schema: models.schema.inventory
        }
    },
    pager: {
        stores: {},
        products: {},
        inventories: {}
    }
};

var db = mongoose.connect('mongodb://127.0.0.1:27017/lcbo');
var store = mongoose.model('store', lcboLoader.mongo.store.schema);
var product = mongoose.model('product', lcboLoader.mongo.product.schema);
var inventory = mongoose.model('inventory', lcboLoader.mongo.inventory.schema);

function getPager(element, callback){
    requestify.request(lcboLoader.config.url+element, {
        method: 'GET',
        params: {
            'per_page': lcboLoader.config.per_page,
            'page': lcboLoader.config.first_page
        },
        headers: lcboLoader.config.headers
    }).then(function(response) {
        var paging = response.getBody().pager;
        lcboLoader.pager[element] = paging;
        if(callback !== undefined){
            callback();
        }
    });
}

function getAllStores(){
    if(lcboLoader.pager.stores.current_page <= lcboLoader.pager.stores.total_pages) {
        requestify.request(lcboLoader.config.url+'stores', {
            method: 'GET',
            params: {
                'per_page': lcboLoader.config.per_page,
                'page': lcboLoader.pager.stores.current_page
            },
            headers: lcboLoader.config.headers
        }).then(function (response) {
            handleStoreData(response.getBody());
        });
    }else{

    }
}

function getAllProducts(){
    if(lcboLoader.pager.products.current_page <= lcboLoader.pager.products.total_pages) {
        requestify.request(lcboLoader.config.url + 'products', {
            method: 'GET',
            params: {
                'per_page': lcboLoader.config.per_page,
                'page': lcboLoader.pager.products.current_page
            },
            headers: lcboLoader.config.headers
        }).then(function (response) {
            console.log(response.getBody().pager);
            handleProductData(response.getBody());
        });
    }
}

function getAllInventories(){
    if(lcboLoader.pager.inventories.current_page <= lcboLoader.pager.inventories.total_pages) {
        requestify.request(lcboLoader.config.url + 'inventories', {
            method: 'GET',
            params: {
                'per_page': lcboLoader.config.per_page,
                'page': lcboLoader.pager.inventories.current_page
            },
            headers: lcboLoader.config.headers
        }).then(function (response) {
            console.log(response.getBody().pager);
            handleInventoryData(response.getBody());
        });
    }
}

function handleStoreData(data){
    var result = data.result;
    var key;

    for(key in result){
        processStoreRecord(result[key]);
    }

    lcboLoader.pager.stores.current_page++;
    getAllStores();

}

function handleProductData(data){
    var result = data.result;
    var key;

    for(key in result){
        processProductRecord(result[key]);
    }

    lcboLoader.pager.products.current_page++;
    getAllProducts();

}

function handleInventoryData(data){
    var result = data.result;
    var key;

    for(key in result){
        processInventoryRecord(result[key]);
    }

    lcboLoader.pager.inventories.current_page++;
    getAllInventories();

}

function processStoreRecord(storeRecord){
    store.findOne({ id: storeRecord.id }, function (err, doc) {
        if (err){
            console.log(err);
            process.exit();
        }

        if(doc == null){
            doc = store(storeRecord);
        }else{
            // Update all records
            var newDoc = store(storeRecord);
            newDoc._id = doc._id;
            doc = newDoc;
        }
        doc.save(function(err, doc) {
            return;
        });

        return;
    });
}

function processProductRecord(productRecord){
    product.findOne({ id: productRecord.id }, function (err, doc) {

        if (err){
            console.log(err);
            process.exit();
        }

        if(doc == null){
            doc = product(productRecord);
        }else{
            // Update all records
            var newDoc = product(productRecord);
            newDoc._id = doc._id;
            doc = newDoc;
        }
        doc.save(function(err, doc) {
            return;

        });

        return;
    });
}
function processInventoryRecord(inventoryRecord){
    inventory.findOne({ product_id: inventoryRecord.product_id, store_id: inventoryRecord.store_id }, function (err, doc) {

        if (err){
            console.log(err);
            process.exit();
        }

        if(doc == null){
            doc = inventory(inventoryRecord);
        }else{
            // Update all records
            var newDoc = inventory(inventoryRecord);
            newDoc._id = doc._id;
            doc = newDoc;
        }
        doc.save(function(err, doc) {
            return;
        });

        return;
    });
}

function getDatasetsZip(){
    var options = {url: lcboLoader.config.urlnonhttps + 'datasets/latest.zip'};
    http.get(options, 'data/latest.zip', function (error, result) {
        if (error) {
            console.error(error);
        } else {
            console.log('File downloaded at: ' + result.file);
            extractDatasetsZip();
        }
    });
}

function extractDatasetsZip(){
    // reading archives
    var zipfile = new zip('data/latest.zip');

    zipfile.extractAllTo("./data", true);

    //Load Data now
    console.log('Done extracting csv files');

}

function convertTsFs(record){
    for(var innerKey in record){
        if(record[innerKey] == 't'){
            record[innerKey] = true;
        }else if(record[innerKey] == 'f'){
            record[innerKey] = false;
        }
    }

    return record;
}

function loadDataset(schema, fileName){
    // equivalent of csv.createCsvFileReader('data.csv')
    var reader = csv.createCsvFileReader(fileName, {columnsFromHeader: true});
    var writer = new csv.CsvWriter(process.stdout);

    reader.addListener('data', function(data) {
        var record = convertTsFs(data);

        if(schema == 'stores'){
            processStoreRecord(record);
        }else if (schema == 'products'){
            processProductRecord(record);
        }else if(schema == 'inventories') {
            processInventoryRecord(record);
        }
    });
}

//getDatasetsZip();
//extractDatasetsZip();
//loadDataset('stores', './data/stores.csv');
//loadDataset('products', './data/products.csv');
loadDataset('inventories', './data/inventories.csv');
<commit_msg>no more to json<commit_after>"use strict";
/**
 * Created by Andre LeFort on 2015-04-10.
 */

// Some bootstrapping
var requestify = require( 'requestify' ),
    mongoose = require('mongoose'),
    Schema = mongoose.Schema,
    models = require('../models/models.js'),
    http = require('http-request'),
    fs = require('fs'),
    zip = require('adm-zip'),
    csv = require('ya-csv');

var lcboLoader = {
    config: {
        url: 'https://lcboapi.com/',
        urlnonhttps: 'http://lcboapi.com/',
        per_page: 100,
        first_page: 1,
        headers: {
            'Authorization': 'Token MDphNWJlOWVlNi1kZmU2LTExZTQtOTI0Mi1iYmJjODAzYmFiMWY6akFwYTA1MG5RbHFXb3RNSG03NUE2ZUNjVnZFT3Rick9CNDNH'
        }
    },
    mongo: {
        store: {
            schema: models.schema.store
        },
        product: {
            schema: models.schema.product
        },
        inventory: {
            schema: models.schema.inventory
        }
    },
    pager: {
        stores: {},
        products: {},
        inventories: {}
    }
};

var db = mongoose.connect('mongodb://127.0.0.1:27017/lcbo');
var store = mongoose.model('store', lcboLoader.mongo.store.schema);
var product = mongoose.model('product', lcboLoader.mongo.product.schema);
var inventory = mongoose.model('inventory', lcboLoader.mongo.inventory.schema);

function getPager(element, callback){
    requestify.request(lcboLoader.config.url+element, {
        method: 'GET',
        params: {
            'per_page': lcboLoader.config.per_page,
            'page': lcboLoader.config.first_page
        },
        headers: lcboLoader.config.headers
    }).then(function(response) {
        var paging = response.getBody().pager;
        lcboLoader.pager[element] = paging;
        if(callback !== undefined){
            callback();
        }
    });
}

function getAllStores(){
    if(lcboLoader.pager.stores.current_page <= lcboLoader.pager.stores.total_pages) {
        requestify.request(lcboLoader.config.url+'stores', {
            method: 'GET',
            params: {
                'per_page': lcboLoader.config.per_page,
                'page': lcboLoader.pager.stores.current_page
            },
            headers: lcboLoader.config.headers
        }).then(function (response) {
            handleStoreData(response.getBody());
        });
    }else{

    }
}

function getAllProducts(){
    if(lcboLoader.pager.products.current_page <= lcboLoader.pager.products.total_pages) {
        requestify.request(lcboLoader.config.url + 'products', {
            method: 'GET',
            params: {
                'per_page': lcboLoader.config.per_page,
                'page': lcboLoader.pager.products.current_page
            },
            headers: lcboLoader.config.headers
        }).then(function (response) {
            console.log(response.getBody().pager);
            handleProductData(response.getBody());
        });
    }
}

function getAllInventories(){
    if(lcboLoader.pager.inventories.current_page <= lcboLoader.pager.inventories.total_pages) {
        requestify.request(lcboLoader.config.url + 'inventories', {
            method: 'GET',
            params: {
                'per_page': lcboLoader.config.per_page,
                'page': lcboLoader.pager.inventories.current_page
            },
            headers: lcboLoader.config.headers
        }).then(function (response) {
            console.log(response.getBody().pager);
            handleInventoryData(response.getBody());
        });
    }
}

function handleStoreData(data){
    var result = data.result;
    var key;

    for(key in result){
        processStoreRecord(result[key]);
    }

    lcboLoader.pager.stores.current_page++;
    getAllStores();

}

function handleProductData(data){
    var result = data.result;
    var key;

    for(key in result){
        processProductRecord(result[key]);
    }

    lcboLoader.pager.products.current_page++;
    getAllProducts();

}

function handleInventoryData(data){
    var result = data.result;
    var key;

    for(key in result){
        processInventoryRecord(result[key]);
    }

    lcboLoader.pager.inventories.current_page++;
    getAllInventories();

}

function processStoreRecord(storeRecord){
    store.findOne({ id: storeRecord.id }, function (err, doc) {
        if (err){
            console.log(err);
            process.exit();
        }

        if(doc == null){
            doc = store(storeRecord);
        }else{
            // Update all records
            var newDoc = store(storeRecord);
            newDoc._id = doc._id;
            doc = newDoc;
        }
        doc.save(function(err, doc) {
            return;
        });

        return;
    });
}

function processProductRecord(productRecord){
    product.findOne({ id: productRecord.id }, function (err, doc) {

        if (err){
            console.log(err);
            process.exit();
        }

        if(doc == null){
            doc = product(productRecord);
        }else{
            // Update all records
            var newDoc = product(productRecord);
            newDoc._id = doc._id;
            doc = newDoc;
        }
        doc.save(function(err, doc) {
            return;

        });

        return;
    });
}
function processInventoryRecord(inventoryRecord){
      var  doc = inventory(inventoryRecord);

    doc.save(function(err, doc) {
        return;
    });
}

function getDatasetsZip(){
    var options = {url: lcboLoader.config.urlnonhttps + 'datasets/latest.zip'};
    http.get(options, 'data/latest.zip', function (error, result) {
        if (error) {
            console.error(error);
        } else {
            console.log('File downloaded at: ' + result.file);
            extractDatasetsZip();
        }
    });
}

function extractDatasetsZip(){
    // reading archives
    var zipfile = new zip('data/latest.zip');

    zipfile.extractAllTo("./data", true);

    //Load Data now
    console.log('Done extracting csv files');

}

function convertTsFs(record){
    for(var innerKey in record){
        if(record[innerKey] == 't'){
            record[innerKey] = true;
        }else if(record[innerKey] == 'f'){
            record[innerKey] = false;
        }
    }

    return record;
}

function loadDataset(schema, fileName){
    // equivalent of csv.createCsvFileReader('data.csv')
    var reader = csv.createCsvFileReader(fileName, {columnsFromHeader: true});
    var writer = new csv.CsvWriter(process.stdout);

    reader.addListener('data', function(data) {
        var record = convertTsFs(data);

        if(schema == 'stores'){
            processStoreRecord(record);
        }else if (schema == 'products'){
            processProductRecord(record);
        }else if(schema == 'inventories') {
            processInventoryRecord(record);
        }
    });
}

//getDatasetsZip();
//extractDatasetsZip();
//loadDataset('stores', './data/stores.csv');
//loadDataset('products', './data/products.csv');
loadDataset('inventories', './data/inventories.csv');
<|endoftext|>


<commit_before>'use strict';
// External dependencies
const express = require('express');
const path = require('path');
const favicon = require('serve-favicon');
const serveIndex = require('serve-index');
const logger = require('morgan');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const i18n = require('i18n');
const hbs = require('hbs'); // handlebars templating
const hbsutils = require('hbs-utils')(hbs);
const lessMiddleware = require('less-middleware');
const session = require('express-session');
const RDBStore = require('session-rethinkdb')(session);
const flash = require('express-flash');
const useragent = require('express-useragent');
const passport = require('passport');
const csrf = require('csurf'); // protect against request forgery using tokens
const config = require('config');
const compression = require('compression');
const WebHooks = require('node-webhooks');

// Internal dependencies
const languages = require('./locales/languages');
const reviews = require('./routes/reviews');
const actions = require('./routes/actions');
const users = require('./routes/users');
const teams = require('./routes/teams');
const pages = require('./routes/pages');
const processUploads = require('./routes/process-uploads');
const blogPosts = require('./routes/blog-posts');
const api = require('./routes/api');
const apiHelper = require('./routes/helpers/api');
const flashHelper = require('./routes/helpers/flash');
const things = require('./routes/things');
const ErrorProvider = require('./routes/errors');
const debug = require('./util/debug');

// Initialize custom HBS helpers
require('./util/handlebars-helpers.js');

let initializedApp;

// Returns a promise that resolves once all asynchronous setup work has
// completed and the app object can be used.
// db is a reference to a database instance with an active connection pool.
// If not provided, we will attempt to acquire the current instance.
function getApp(db = require('./db')) {

  return new Promise((resolve, reject) => {

    if (initializedApp)
      return resolve(initializedApp);

    // Push promises into this array that need to resolve before the app itself
    // is ready for use
    let asyncJobs = [];

    // Auth setup
    require('./auth');

    // i18n setup
    i18n.configure({
      locales: languages.getValidLanguages(),
      cookie: 'locale',
      autoReload: true,
      updateFiles: false,
      directory: __dirname + '/locales'
    });

    // express setup
    const app = express();

    // view engine setup
    app.set('views', path.join(__dirname, 'views'));

    asyncJobs.push(new Promise(resolveJob =>
      hbsutils.registerWatchedPartials(__dirname + '/views/partials', undefined, () => resolveJob())
    ));

    app.set('view engine', 'hbs');

    app.use(cookieParser());
    app.use(i18n.init); // Requires cookie parser!
    app.use(useragent.express()); // expose UA object to req.useragent

    const store = new RDBStore(db.r, {
      table: 'sessions'
    });

    // We do not get an error event from this module, so this is a potential
    // cause of hangs during the initialization. Set DEBUG=session to debug.
    asyncJobs.push(new Promise(resolve => {
      debug.app('Awaiting session store initialization.');
      store.on('connect', function() {
        debug.app('Session store initialized.');
        db.r
          .table('sessions')
          .wait({ timeout: 5 })
          .then(resolve)
          .catch(reject);
      });
    }));

    app.use(session({
      key: 'libreviews_session',
      resave: true,
      saveUninitialized: true,
      secret: config.get('sessionSecret'),
      cookie: {
        maxAge: config.get('sessionCookieDuration') * 1000 * 60
      },
      store
    }));

    app.use(flash());
    app.use(flashHelper);

    app.use(favicon(path.join(__dirname, 'static/img/favicon.ico'))); // not logged

    if (config.get('logger'))
      app.use(logger(config.get('logger')));

    app.use('/static/downloads', serveIndex(path.join(__dirname, 'static/downloads'), {
      'icons': true,
      template: path.join(__dirname, 'views/downloads.html')
    }));

    let cssPath = path.join(__dirname, 'static', 'css');
    app.use('/static/css', lessMiddleware(cssPath));
    app.use('/static', express.static(path.join(__dirname, 'static')));
    app.use('/robots.txt', (req, res) => {
      res.type('text');
      res.send('User-agent: *\nDisallow: /api/\n');
    });

    // Initialize Passport and restore authentication state, if any, from the
    // session.
    app.use(passport.initialize());
    app.use(passport.session());

    // API requests do not require CSRF protection (hence declared before CSRF
    // middleware), but session-authenticated POST requests do require the
    // X-Requested-With header to be set, which ensures they're subject to CORS
    // rules. This middleware also sets req.isAPI to true for API requests.
    app.use('/api', apiHelper.prepareRequest);

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

    app.use(compression());

    let errorProvider = new ErrorProvider(app);

    if (config.maintenanceMode) {
      // Will not pass along control to any future routes but just render
      // generic maintenance mode message instead
      app.use('/', errorProvider.maintenanceMode);
    }

    // ?uselang=xx changes language temporarily if xx is a valid, different code
    app.use('/', function(req, res, next) {
      let locale = req.query.uselang || req.query.useLang;
      if (locale && languages.isValid(locale) && locale !== req.locale) {
        req.localeChange = { old: req.locale, new: locale };
        i18n.setLocale(req, locale);
      }
      return next();
    });

    app.use('/api', api);

    // Upload processing has to be done before CSRF middleware kicks in
    app.use('/', processUploads);
    app.use(csrf());
    app.use('/', pages);
    app.use('/', reviews);
    app.use('/', actions);
    app.use('/', teams);
    app.use('/', blogPosts);
    app.use('/user', users);

    // Goes last to avoid accidental overlap w/ reserved routes
    app.use('/', things);

    // Catches 404s and serves "not found" page
    app.use(errorProvider.notFound);

    // Catches the following:
    // - bad JSON data in POST bodies
    // - errors explicitly passed along with next(error)
    // - other unhandled errors
    app.use(errorProvider.generic);

    app.locals.webHooks = new WebHooks({
      db: path.join(__dirname, 'config/webHooksDB.json')
    });

    Promise
      .all(asyncJobs)
      .then(() => {
        let mode = app.get('env') == 'production' ? 'PRODUCTION' : 'DEVELOPMENT';
        debug.app(`App is up and running in ${mode} mode.`);
        initializedApp = app;
        resolve(app);
      })
      .catch(error => reject(error));

  });
}

module.exports = getApp;
<commit_msg>Compress more compressible assets<commit_after>'use strict';
// External dependencies
const express = require('express');
const path = require('path');
const favicon = require('serve-favicon');
const serveIndex = require('serve-index');
const logger = require('morgan');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const i18n = require('i18n');
const hbs = require('hbs'); // handlebars templating
const hbsutils = require('hbs-utils')(hbs);
const lessMiddleware = require('less-middleware');
const session = require('express-session');
const RDBStore = require('session-rethinkdb')(session);
const flash = require('express-flash');
const useragent = require('express-useragent');
const passport = require('passport');
const csrf = require('csurf'); // protect against request forgery using tokens
const config = require('config');
const compression = require('compression');
const WebHooks = require('node-webhooks');

// Internal dependencies
const languages = require('./locales/languages');
const reviews = require('./routes/reviews');
const actions = require('./routes/actions');
const users = require('./routes/users');
const teams = require('./routes/teams');
const pages = require('./routes/pages');
const processUploads = require('./routes/process-uploads');
const blogPosts = require('./routes/blog-posts');
const api = require('./routes/api');
const apiHelper = require('./routes/helpers/api');
const flashHelper = require('./routes/helpers/flash');
const things = require('./routes/things');
const ErrorProvider = require('./routes/errors');
const debug = require('./util/debug');

// Initialize custom HBS helpers
require('./util/handlebars-helpers.js');

let initializedApp;

// Returns a promise that resolves once all asynchronous setup work has
// completed and the app object can be used.
// db is a reference to a database instance with an active connection pool.
// If not provided, we will attempt to acquire the current instance.
function getApp(db = require('./db')) {

  return new Promise((resolve, reject) => {

    if (initializedApp)
      return resolve(initializedApp);

    // Push promises into this array that need to resolve before the app itself
    // is ready for use
    let asyncJobs = [];

    // Auth setup
    require('./auth');

    // i18n setup
    i18n.configure({
      locales: languages.getValidLanguages(),
      cookie: 'locale',
      autoReload: true,
      updateFiles: false,
      directory: __dirname + '/locales'
    });

    // express setup
    const app = express();

    // view engine setup
    app.set('views', path.join(__dirname, 'views'));

    asyncJobs.push(new Promise(resolveJob =>
      hbsutils.registerWatchedPartials(__dirname + '/views/partials', undefined, () => resolveJob())
    ));

    app.set('view engine', 'hbs');

    app.use(cookieParser());
    app.use(i18n.init); // Requires cookie parser!
    app.use(useragent.express()); // expose UA object to req.useragent

    const store = new RDBStore(db.r, {
      table: 'sessions'
    });

    // We do not get an error event from this module, so this is a potential
    // cause of hangs during the initialization. Set DEBUG=session to debug.
    asyncJobs.push(new Promise(resolve => {
      debug.app('Awaiting session store initialization.');
      store.on('connect', function() {
        debug.app('Session store initialized.');
        db.r
          .table('sessions')
          .wait({ timeout: 5 })
          .then(resolve)
          .catch(reject);
      });
    }));

    app.use(session({
      key: 'libreviews_session',
      resave: true,
      saveUninitialized: true,
      secret: config.get('sessionSecret'),
      cookie: {
        maxAge: config.get('sessionCookieDuration') * 1000 * 60
      },
      store
    }));

    app.use(flash());
    app.use(flashHelper);

    app.use(compression());

    app.use(favicon(path.join(__dirname, 'static/img/favicon.ico'))); // not logged

    if (config.get('logger'))
      app.use(logger(config.get('logger')));

    app.use('/static/downloads', serveIndex(path.join(__dirname, 'static/downloads'), {
      'icons': true,
      template: path.join(__dirname, 'views/downloads.html')
    }));

    let cssPath = path.join(__dirname, 'static', 'css');
    app.use('/static/css', lessMiddleware(cssPath));
    app.use('/static', express.static(path.join(__dirname, 'static')));
    app.use('/robots.txt', (req, res) => {
      res.type('text');
      res.send('User-agent: *\nDisallow: /api/\n');
    });

    // Initialize Passport and restore authentication state, if any, from the
    // session.
    app.use(passport.initialize());
    app.use(passport.session());

    // API requests do not require CSRF protection (hence declared before CSRF
    // middleware), but session-authenticated POST requests do require the
    // X-Requested-With header to be set, which ensures they're subject to CORS
    // rules. This middleware also sets req.isAPI to true for API requests.
    app.use('/api', apiHelper.prepareRequest);

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

    let errorProvider = new ErrorProvider(app);

    if (config.maintenanceMode) {
      // Will not pass along control to any future routes but just render
      // generic maintenance mode message instead
      app.use('/', errorProvider.maintenanceMode);
    }

    // ?uselang=xx changes language temporarily if xx is a valid, different code
    app.use('/', function(req, res, next) {
      let locale = req.query.uselang || req.query.useLang;
      if (locale && languages.isValid(locale) && locale !== req.locale) {
        req.localeChange = { old: req.locale, new: locale };
        i18n.setLocale(req, locale);
      }
      return next();
    });

    app.use('/api', api);

    // Upload processing has to be done before CSRF middleware kicks in
    app.use('/', processUploads);
    app.use(csrf());
    app.use('/', pages);
    app.use('/', reviews);
    app.use('/', actions);
    app.use('/', teams);
    app.use('/', blogPosts);
    app.use('/user', users);

    // Goes last to avoid accidental overlap w/ reserved routes
    app.use('/', things);

    // Catches 404s and serves "not found" page
    app.use(errorProvider.notFound);

    // Catches the following:
    // - bad JSON data in POST bodies
    // - errors explicitly passed along with next(error)
    // - other unhandled errors
    app.use(errorProvider.generic);

    app.locals.webHooks = new WebHooks({
      db: path.join(__dirname, 'config/webHooksDB.json')
    });

    Promise
      .all(asyncJobs)
      .then(() => {
        let mode = app.get('env') == 'production' ? 'PRODUCTION' : 'DEVELOPMENT';
        debug.app(`App is up and running in ${mode} mode.`);
        initializedApp = app;
        resolve(app);
      })
      .catch(error => reject(error));

  });
}

module.exports = getApp;
<|endoftext|>


<commit_before>/**
 * Module dependencies.
 */

var express = require('express');
var MongoStore = require('connect-mongo')(express);
var flash = require('express-flash');
var less = require('less-middleware');
var path = require('path');
var mongoose = require('mongoose');
var passport = require('passport');
var expressValidator = require('express-validator');

var app = express();

/**
 * Load controllers.
 */

var homeController = require('./controllers/home');
var userController = require('./controllers/user');
var apiController = require('./controllers/api');
var contactController = require('./controllers/contact');

/**
 * API keys + Passport configuration.
 */

var secrets = require('./config/secrets');
var passportConf = require('./config/passport');

/**
 * Mongoose configuration.
 */

mongoose.connect(secrets.db);
mongoose.connection.on('error', function() {
  console.log('✗ MongoDB Connection Error. Please make sure MongoDB is running.'.red);
});

/**
 * Express configuration.
 */
app.locals.cacheBuster = Date.now();
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.compress());
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.cookieParser());
app.use(express.json());
app.use(express.urlencoded());
app.use(expressValidator());
app.use(express.methodOverride());
app.use(express.session({
  secret: 'your secret code',
  store: new MongoStore({
    db: secrets.db
  })
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(function(req, res, next) {
  res.locals.user = req.user;
  next();
});
app.use(flash());
app.use(less({ src: __dirname + '/public', compress: true }));
app.use(app.router);
app.use(express.static( path.join(__dirname, 'public'), { maxAge: 864000000 } ));
app.use(function(req, res) {
  res.render('404', { status: 404 });
});
app.use(express.errorHandler());

/**
 * Application routes.
 */

app.get('/', homeController.index);
app.get('/login', userController.getLogin);
app.post('/login', userController.postLogin);
app.get('/logout', userController.logout);
app.get('/signup', userController.getSignup);
app.post('/signup', userController.postSignup);
app.get('/contact', contactController.getContact);
app.post('/contact', contactController.postContact);
app.get('/account', passportConf.isAuthenticated, userController.getAccount);
app.post('/account/profile', passportConf.isAuthenticated, userController.postUpdateProfile);
app.post('/account/password', passportConf.isAuthenticated, userController.postUpdatePassword);
app.post('/account/delete', passportConf.isAuthenticated, userController.postDeleteAccount);
app.get('/account/unlink/:provider', passportConf.isAuthenticated, userController.getOauthUnlink);
app.get('/api', apiController.getApi);
app.get('/api/foursquare', passportConf.isAuthenticated, passportConf.isAuthorized, apiController.getFoursquare);
app.get('/api/tumblr', passportConf.isAuthenticated, passportConf.isAuthorized, apiController.getTumblr);
app.get('/api/facebook', passportConf.isAuthenticated, apiController.getFacebook);
app.get('/api/scraping', apiController.getScraping);
app.get('/api/github', passportConf.isAuthenticated, passportConf.isAuthorized, apiController.getGithub);
app.get('/api/lastfm', apiController.getLastfm);
app.get('/api/nyt', apiController.getNewYorkTimes);
app.get('/api/twitter', passportConf.isAuthenticated, apiController.getTwitter);
app.get('/api/aviary', apiController.getAviary);
app.get('/api/paypal', apiController.getPayPal);
app.get('/api/paypal/success', apiController.getPayPalSuccess);
app.get('/api/paypal/cancel', apiController.getPayPalCancel);
app.get('/auth/facebook', passport.authenticate('facebook', { scope: 'email' }));
app.get('/auth/facebook/callback', passport.authenticate('facebook', { successRedirect: '/', failureRedirect: '/login' }));
app.get('/auth/github', passport.authenticate('github'));
app.get('/auth/github/callback', passport.authenticate('github', { successRedirect: '/', failureRedirect: '/login' }));
app.get('/auth/google', passport.authenticate('google', { scope: 'profile email' }));
app.get('/auth/google/callback', passport.authenticate('google', { successRedirect: '/', failureRedirect: '/login' }));
app.get('/auth/twitter', passport.authenticate('twitter'));
app.get('/auth/twitter/callback', passport.authenticate('twitter', { successRedirect: '/', failureRedirect: '/login' }));
app.get('/auth/foursquare', passport.authorize('foursquare'));
app.get('/auth/foursquare/callback', passport.authorize('foursquare', { failureRedirect: '/api' }), function(req, res) { res.redirect('/api/foursquare'); });
app.get('/auth/tumblr', passport.authorize('tumblr'));
app.get('/auth/tumblr/callback', passport.authorize('tumblr', { failureRedirect: '/api' }), function(req, res) { res.redirect('/api/tumblr'); });

app.listen(app.get('port'), function() {
  console.log('✔ Express server listening on port ' + app.get('port'));
});
<commit_msg>Add mode type to console.log when you start the server<commit_after>/**
 * Module dependencies.
 */

var express = require('express');
var MongoStore = require('connect-mongo')(express);
var flash = require('express-flash');
var less = require('less-middleware');
var path = require('path');
var mongoose = require('mongoose');
var passport = require('passport');
var expressValidator = require('express-validator');

var app = express();

/**
 * Load controllers.
 */

var homeController = require('./controllers/home');
var userController = require('./controllers/user');
var apiController = require('./controllers/api');
var contactController = require('./controllers/contact');

/**
 * API keys + Passport configuration.
 */

var secrets = require('./config/secrets');
var passportConf = require('./config/passport');

/**
 * Mongoose configuration.
 */

mongoose.connect(secrets.db);
mongoose.connection.on('error', function() {
  console.log('✗ MongoDB Connection Error. Please make sure MongoDB is running.'.red);
});

/**
 * Express configuration.
 */
app.locals.cacheBuster = Date.now();
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.compress());
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.cookieParser());
app.use(express.json());
app.use(express.urlencoded());
app.use(expressValidator());
app.use(express.methodOverride());
app.use(express.session({
  secret: 'your secret code',
  store: new MongoStore({
    db: secrets.db
  })
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(function(req, res, next) {
  res.locals.user = req.user;
  next();
});
app.use(flash());
app.use(less({ src: __dirname + '/public', compress: true }));
app.use(app.router);
app.use(express.static( path.join(__dirname, 'public'), { maxAge: 864000000 } ));
app.use(function(req, res) {
  res.render('404', { status: 404 });
});
app.use(express.errorHandler());

/**
 * Application routes.
 */

app.get('/', homeController.index);
app.get('/login', userController.getLogin);
app.post('/login', userController.postLogin);
app.get('/logout', userController.logout);
app.get('/signup', userController.getSignup);
app.post('/signup', userController.postSignup);
app.get('/contact', contactController.getContact);
app.post('/contact', contactController.postContact);
app.get('/account', passportConf.isAuthenticated, userController.getAccount);
app.post('/account/profile', passportConf.isAuthenticated, userController.postUpdateProfile);
app.post('/account/password', passportConf.isAuthenticated, userController.postUpdatePassword);
app.post('/account/delete', passportConf.isAuthenticated, userController.postDeleteAccount);
app.get('/account/unlink/:provider', passportConf.isAuthenticated, userController.getOauthUnlink);
app.get('/api', apiController.getApi);
app.get('/api/foursquare', passportConf.isAuthenticated, passportConf.isAuthorized, apiController.getFoursquare);
app.get('/api/tumblr', passportConf.isAuthenticated, passportConf.isAuthorized, apiController.getTumblr);
app.get('/api/facebook', passportConf.isAuthenticated, apiController.getFacebook);
app.get('/api/scraping', apiController.getScraping);
app.get('/api/github', passportConf.isAuthenticated, passportConf.isAuthorized, apiController.getGithub);
app.get('/api/lastfm', apiController.getLastfm);
app.get('/api/nyt', apiController.getNewYorkTimes);
app.get('/api/twitter', passportConf.isAuthenticated, apiController.getTwitter);
app.get('/api/aviary', apiController.getAviary);
app.get('/api/paypal', apiController.getPayPal);
app.get('/api/paypal/success', apiController.getPayPalSuccess);
app.get('/api/paypal/cancel', apiController.getPayPalCancel);
app.get('/auth/facebook', passport.authenticate('facebook', { scope: 'email' }));
app.get('/auth/facebook/callback', passport.authenticate('facebook', { successRedirect: '/', failureRedirect: '/login' }));
app.get('/auth/github', passport.authenticate('github'));
app.get('/auth/github/callback', passport.authenticate('github', { successRedirect: '/', failureRedirect: '/login' }));
app.get('/auth/google', passport.authenticate('google', { scope: 'profile email' }));
app.get('/auth/google/callback', passport.authenticate('google', { successRedirect: '/', failureRedirect: '/login' }));
app.get('/auth/twitter', passport.authenticate('twitter'));
app.get('/auth/twitter/callback', passport.authenticate('twitter', { successRedirect: '/', failureRedirect: '/login' }));
app.get('/auth/foursquare', passport.authorize('foursquare'));
app.get('/auth/foursquare/callback', passport.authorize('foursquare', { failureRedirect: '/api' }), function(req, res) { res.redirect('/api/foursquare'); });
app.get('/auth/tumblr', passport.authorize('tumblr'));
app.get('/auth/tumblr/callback', passport.authorize('tumblr', { failureRedirect: '/api' }), function(req, res) { res.redirect('/api/tumblr'); });

app.listen(app.get('port'), function() {
  console.log("✔ Express server listening on port %d in %s mode", app.get('port'), app.settings.env);
});
<|endoftext|>


<commit_before>var scp = require('scp'),
    sha1 = require('sha1'),
    fs = require('fs'),
    path = require('path'),
    clipboard = require("copy-paste").global(),
    notifier = require('node-notifier'),
    gaze = require('gaze');

// Should be moved to config file
var screenshotDirectory = '/Users/philipp/Desktop/';
var screenshotDirectoryArchive = '/Users/philipp/Documents/Developement/Node/ScreenUpload/tmp/'
var scpUser = 'dewey';
var scpHost = 'notmyhostna.me';
var scpPort = '22';
var scpRemotePath = '/var/www/img.notmyhostna.me/';
var scpRemoteURL = 'https://img.notmyhostna.me/';
// End of config
//
console.log("Start ScreenUpload script")

// Watch provided path from config for new files matching the screenshot default name.
gaze('Screen\ Shot *.png', {
    cwd: screenshotDirectory
}, function(err, watcher) {
    if (err) {
        console.log("Error watching folder")
        console.log(err)
    } else {
        // Watch for 'added' event
        this.on('added', function(filepath) {
            // Create temp file name for uploading and move to archive.
            var imageName = sha1(filepath);
            var imageNameNew = imageName + path.extname(filepath);
            var filepathNew = screenshotDirectoryArchive + imageNameNew;
            var imageRemoteURL = scpRemoteURL + imageNameNew;
            console.log("Rename file")
            fs.renameSync(filepath, filepathNew)

            // Upload file
            scp.send({
                file: 'tmp/' + imageNameNew,
                user: scpUser,
                host: scpHost,
                port: scpPort,
                path: scpRemotePath
            }, function(err) {
                if (err) {
                    console.log("Uploading error")
                    console.log(err);
                } else {
                    console.log("Uploading successful")
                    // Copy to clipboard
                    copy(imageRemoteURL);

                    notifier.notify({
                        'title': 'ScreenUpload',
                        'message': 'Upload finished.'
                    });
                }
            });
        });
    }
});<commit_msg>Patched scp library and included as scp-custom<commit_after>var scp = require('scp-custom'),
    sha1 = require('sha1'),
    fs = require('fs'),
    path = require('path'),
    clipboard = require("copy-paste").global(),
    notifier = require('node-notifier'),
    gaze = require('gaze');

// Should be moved to config file
var screenshotDirectory = '/Users/philipp/Desktop/';
var screenshotDirectoryArchive = '/Users/philipp/Documents/Developement/Node/ScreenUpload/tmp/'
var scpUser = 'dewey';
var scpHost = 'notmyhostna.me';
var scpPort = '22';
var scpRemotePath = '/var/www/img.notmyhostna.me/';
var scpRemoteURL = 'https://img.notmyhostna.me/';
// End of config
//
console.log("Start ScreenUpload script")

// Watch provided path from config for new files matching the screenshot default name.
gaze('Screen\ Shot *.png', {
    cwd: screenshotDirectory
}, function(err, watcher) {
    if (err) {
        console.log("Error watching folder")
        console.log(err)
    } else {
        // Watch for 'added' event
        this.on('added', function(filepath) {
            // Create temp file name for uploading and move to archive.
            var imageName = sha1(filepath);
            var imageNameNew = imageName + path.extname(filepath);
            var filepathNew = screenshotDirectoryArchive + imageNameNew;
            var imageRemoteURL = scpRemoteURL + imageNameNew;
            console.log("Rename file")
            fs.renameSync(filepath, filepathNew)

            // Upload file
            scp.send({
                file: filepathNew,
                user: scpUser,
                host: scpHost,
                port: scpPort,
                path: scpRemotePath
            }, function(err) {
                if (err) {
                    console.log("Uploading error")
                    console.log(err);
                } else {
                    console.log("Uploading successful")
                    // Copy to clipboard
                    copy(imageRemoteURL);

                    notifier.notify({
                        'title': 'ScreenUpload',
                        'message': 'Upload finished.'
                    });
                }
            });
        });
    }
});<|endoftext|>


<commit_before>var express = require('express')
  , app = express()
  , fs = require('fs')
  , path = require('path')
  , server = require("http").createServer(app)
  , io = require('socket.io').listen(server)
  , arDrone = require('ar-drone')
  , arDroneConstants = require('ar-drone/lib/constants')
  ;

// Fetch configuration
try {
    var config = require('./config');
} catch (err) {
    console.log("Missing or corrupted config file. Have a look at config.js.example if you need an example.");
    process.exit(-1);
}

// Override the drone ip using an environment variable,
// using the same convention as node-ar-drone
var drone_ip = process.env.DEFAULT_DRONE_IP || '192.168.1.1';

// Keep track of plugins js and css to load them in the view
var scripts = []
  , styles = []
  ;

app.configure(function () {
    app.set('port', process.env.PORT || 3000);
    app.set('views', __dirname + '/views');
    app.set('view engine', 'ejs', { pretty: true });
    app.use(express.favicon());
    app.use(express.logger('dev'));
    app.use(app.router);
    app.use(express.static(path.join(__dirname, 'public')));
    app.use("/components", express.static(path.join(__dirname, 'components')));
});

app.configure('development', function () {
    app.use(express.errorHandler());
    app.locals.pretty = true;
});

app.get('/', function (req, res) {
    res.render('index', {
        title: 'Express'
        ,scripts: scripts
        ,styles: styles
        ,options: {
          keyboard: config.keyboard
        }
    });
});

function navdata_option_mask(c) {
  return 1 << c;
}

// From the SDK.
var navdata_options = (
    navdata_option_mask(arDroneConstants.options.DEMO)
  | navdata_option_mask(arDroneConstants.options.VISION_DETECT)
  | navdata_option_mask(arDroneConstants.options.MAGNETO)
  | navdata_option_mask(arDroneConstants.options.WIFI)
);

// Connect and configure the drone
var client = new arDrone.createClient();
client.config('general:navdata_demo', 'TRUE');
client.config('video:video_channel', '0');
client.config('general:navdata_options', navdata_options);

// Add a handler on navdata updates
var latestNavData;
client.on('navdata', function (d) {
    latestNavData = d;
});

// Signal landed and flying events.
client.on('landing', function () {
  console.log('LANDING');
  io.sockets.emit('landing');
});
client.on('landed', function () {
  console.log('LANDED');
  io.sockets.emit('landed');
});
client.on('takeoff', function() {
  console.log('TAKEOFF');
  io.sockets.emit('takeoff');
});
client.on('hovering', function() {
  console.log('HOVERING');
  io.sockets.emit('hovering');
});
client.on('flying', function() {
  console.log('FLYING');
  io.sockets.emit('flying');
});

// Process new websocket connection
io.set('log level', 1);
io.sockets.on('connection', function (socket) {
  socket.emit('event', { message: 'Welcome to cockpit :-)' });
});

// Schedule a time to push navdata updates
var pushNavData = function() {
    io.sockets.emit('navdata', latestNavData);
};
var navTimer = setInterval(pushNavData, 100);

// Prepare dependency map for plugins
var deps = {
    server: server
  , app: app
  , io: io
  , client: client
  , config: config
};

// Load the plugins
var dir = path.join(__dirname, 'plugins');
config.plugins.forEach(function (plugin) {
    console.log("Loading " + plugin + " plugin.");

    // Load the backend code
    require(path.join(dir, plugin))(plugin, deps);

    // Add the public assets to a static route
    if (fs.existsSync(assets = path.join(dir, plugin, 'public'))) {
      app.use("/plugin/" + plugin, express.static(assets));
    }

    // Add the js to the view
    if (fs.existsSync(js = path.join(assets, 'js'))) {
        fs.readdirSync(js).forEach(function(script) {
            scripts.push("/plugin/" + plugin + "/js/" + script);
        });
    }

    // Add the css to the view
    if (fs.existsSync(css = path.join(assets, 'css'))) {
        fs.readdirSync(css).forEach(function(style) {
            styles.push("/plugin/" + plugin + "/css/" + style);
        });
    }
});

// Start the web server
server.listen(app.get('port'), function() {
  console.log('AR. Drone WebFlight is listening on port ' + app.get('port'));
});

<commit_msg>increase timeout for client<commit_after>var express = require('express')
  , app = express()
  , fs = require('fs')
  , path = require('path')
  , server = require("http").createServer(app)
  , io = require('socket.io').listen(server)
  , arDrone = require('ar-drone')
  , arDroneConstants = require('ar-drone/lib/constants')
  ;

// Fetch configuration
try {
    var config = require('./config');
} catch (err) {
    console.log("Missing or corrupted config file. Have a look at config.js.example if you need an example.");
    process.exit(-1);
}

// Override the drone ip using an environment variable,
// using the same convention as node-ar-drone
var drone_ip = process.env.DEFAULT_DRONE_IP || '192.168.1.1';

// Keep track of plugins js and css to load them in the view
var scripts = []
  , styles = []
  ;

app.configure(function () {
    app.set('port', process.env.PORT || 3000);
    app.set('views', __dirname + '/views');
    app.set('view engine', 'ejs', { pretty: true });
    app.use(express.favicon());
    app.use(express.logger('dev'));
    app.use(app.router);
    app.use(express.static(path.join(__dirname, 'public')));
    app.use("/components", express.static(path.join(__dirname, 'components')));
});

app.configure('development', function () {
    app.use(express.errorHandler());
    app.locals.pretty = true;
});

app.get('/', function (req, res) {
    res.render('index', {
        title: 'Express'
        ,scripts: scripts
        ,styles: styles
        ,options: {
          keyboard: config.keyboard
        }
    });
});

function navdata_option_mask(c) {
  return 1 << c;
}

// From the SDK.
var navdata_options = (
    navdata_option_mask(arDroneConstants.options.DEMO)
  | navdata_option_mask(arDroneConstants.options.VISION_DETECT)
  | navdata_option_mask(arDroneConstants.options.MAGNETO)
  | navdata_option_mask(arDroneConstants.options.WIFI)
);

// Connect and configure the drone
var client = new arDrone.createClient({timeout:4000});
client.config('general:navdata_demo', 'TRUE');
client.config('video:video_channel', '0');
client.config('general:navdata_options', navdata_options);

// Add a handler on navdata updates
var latestNavData;
client.on('navdata', function (d) {
    latestNavData = d;
});

// Signal landed and flying events.
client.on('landing', function () {
  console.log('LANDING');
  io.sockets.emit('landing');
});
client.on('landed', function () {
  console.log('LANDED');
  io.sockets.emit('landed');
});
client.on('takeoff', function() {
  console.log('TAKEOFF');
  io.sockets.emit('takeoff');
});
client.on('hovering', function() {
  console.log('HOVERING');
  io.sockets.emit('hovering');
});
client.on('flying', function() {
  console.log('FLYING');
  io.sockets.emit('flying');
});

// Process new websocket connection
io.set('log level', 1);
io.sockets.on('connection', function (socket) {
  socket.emit('event', { message: 'Welcome to cockpit :-)' });
});

// Schedule a time to push navdata updates
var pushNavData = function() {
    io.sockets.emit('navdata', latestNavData);
};
var navTimer = setInterval(pushNavData, 100);

// Prepare dependency map for plugins
var deps = {
    server: server
  , app: app
  , io: io
  , client: client
  , config: config
};

// Load the plugins
var dir = path.join(__dirname, 'plugins');
config.plugins.forEach(function (plugin) {
    console.log("Loading " + plugin + " plugin.");

    // Load the backend code
    require(path.join(dir, plugin))(plugin, deps);

    // Add the public assets to a static route
    if (fs.existsSync(assets = path.join(dir, plugin, 'public'))) {
      app.use("/plugin/" + plugin, express.static(assets));
    }

    // Add the js to the view
    if (fs.existsSync(js = path.join(assets, 'js'))) {
        fs.readdirSync(js).forEach(function(script) {
            scripts.push("/plugin/" + plugin + "/js/" + script);
        });
    }

    // Add the css to the view
    if (fs.existsSync(css = path.join(assets, 'css'))) {
        fs.readdirSync(css).forEach(function(style) {
            styles.push("/plugin/" + plugin + "/css/" + style);
        });
    }
});

// Start the web server
server.listen(app.get('port'), function() {
  console.log('AR. Drone WebFlight is listening on port ' + app.get('port'));
});

<|endoftext|>


<commit_before>require('newrelic');
var express = require('express');
var jsdom = require("jsdom");
var request = require('request');
var db = require('./config/db');
var Posts = require('./models/posts');
var Comments = require('./models/comments');

var app = express();

var BASE_URL = 'http://www.producthunt.com';

app.configure(function (){
  app.set('port', process.env.PORT || 8888);
  app.use(express.cookieParser('keyboard cat'));
  app.use(express.session({ secret: 'keyboard cat' }));
  app.use(app.router);
});

app.get('/', function (req, res) {
  res.redirect('https://github.com/karan/Hook');
});

app.get('/today', function (req, res) {

  var today = new Date().toJSON().slice(0,10);

  Posts.findOne({date: today}, function (err, obj) {

    if (obj && obj.expires < Date.now()) {
      // post expired, scrape again, and save
      console.log("posts expired - " + today);
      getHomePosts(null, function (posts) {
        Posts.findOneAndUpdate({date: today}, {posts: posts, expires: new Date(Date.now() + 60*60*1000)}, {new: true}, function (err, newObj) {
          res.send(200, {
            status: 'success',
            hunts: posts
          });
        });
      });
    } else if (obj) {
      console.log("posts not expired - " + today);
      // not expired, just return this
      res.send(200, {
        status: 'success',
        hunts: obj.posts
      });
    } else {
      // not in the db, scrape and send
      console.log("posts not found in db - " + today);

      getHomePosts(null, function (posts) {
        console.log("got details");
        new Posts({
          date: today,
          posts: posts
        }).save(function (err) {
          res.send(200, {
            status: 'success',
            hunts: posts
          });
        });
      });

    }

  });

});

app.get("/posts/:slug", function (req, res) {

  var post_url = '/posts/'+req.params.slug;

  Comments.findOne({'permalink': post_url}, function(err, commentobj) {

    if (commentobj && commentobj.expires < Date.now()) {
      // expired. Scrape again, save and send
      console.log("expired");
      getPostDetails(post_url, function (post) {
        console.log(post);
        getComments(post_url, function (err, comments, related) {
          Comments.findOneAndUpdate({permalink: post_url}, {post: post, comments: comments, expires: new Date(Date.now() + 2*60*60*1000)}, function (err, newObj) {
            res.send(200, {
              status: 'success',
              post: post,
              comments: comments
            });
          });
        });
      });
    } else if (commentobj) {
      console.log("in db - fine");
      // not expired, just send response
      res.send(200, {
        status: 'success',
        post: commentobj.post,
        comments: commentobj.comments
      });
    } else {
      console.log("not in db");
      // not in db, scrape, save and send
      getPostDetails(post_url, function (post) {
        console.log(post);
        getComments(post_url, function (err, comments, related) {
          new Comments({
            post: post,
            permalink: post.permalink,
            comments: comments
          }).save(function(err) {
            res.send(200, {
              status: 'success',
              post: post,
              comments: comments
            });
          });
        });
      });

    }

  });

});

function getPostDetails(post_url, callback) {
  var url = post_url ? BASE_URL + post_url : BASE_URL;
  console.log(url);

  jsdom.env(
    url,
    ["http://code.jquery.com/jquery.js"],
    function (errors, window) {

      if (errors) {
        console.log(errors);
      }
      console.log(window.title);
      var $ = window.$;

      console.log($);

      var header_dom = $(".comments-header");

      var votes = +header_dom.find(".vote-count").text();
      console.log(votes);
      var name = /Posted by (.*) \d+ .*/g.exec(header_dom.find(".posted-by").text().trim().replace(/"/g, ""))[1];
      var username = header_dom.find(".user-with-tooltip").attr("href").slice(1).trim().replace(/"/g, "");
      var title = header_dom.find(".post-url").text();
      var tagline = header_dom.find(".post-tagline").text();

      console.log(title);

      var comment_count = $($(".modal-container").find(".subhead")[2]).text().trim().match(/(\d+)/g);
      comment_count = comment_count ? comment_count[0] : 0;

      var permalink = post_url;

      request({url: BASE_URL+header_dom.find(".post-url").attr("href"), followRedirect: false}, function (error, response, body) {
        url = response.headers.location;

        callback({
          'title': title,
          'votes': votes,
          'user': {
            'username': username,
            'name': name
          },
          'rank': 1,
          'tagline': tagline,
          'comment_count': comment_count,
          'permalink': permalink,
          'url': url
        });

      });

    }
  );
}

function getComments(url, callback) {

  jsdom.env(
    BASE_URL+url,
    ["http://code.jquery.com/jquery.js"],
    function (errors, window) {
      var $ = window.$;

      var comments = [];

      var comments_dom = $(".comment-thread");

      if (comments_dom.length === 0) {
        return callback(null, comments);
      }

      comments_dom.each(function (index) {
        var this_comments = $(this).find(".comment");

        this_comments.each(function (com_count) {
          var username = $(this).find(".comment-body").data("comment-by").match(/\(\@(.*)\)/)[1];
          var name = $(this).find(".comment-user-name a").text();
          var comment = $(this).find(".actual-comment").text();
          var comment_html = $(this).find(".actual-comment").html();

          console.log(username + "--" + name);

          if (com_count === 0) {
            // Get the top level comment
            comments.push({
              index: index+1,
              user: {
                username: username,
                name: name
              },
              comment: comment,
              comment_html: comment_html,
              children: []
            });
          } else {
            // Get the child comment
            comments[comments.length-1].children.push({
              index: com_count+1,
              user: {
                username: username,
                name: name
              },
              comment: comment,
              comment_html: comment_html
            });
          }

          if (comments.length === comments_dom.length) {
            callback(null, comments);
          }
        });

      });

    }
  );

}

function getHomePosts(post_url, callback) {
  var url = post_url ? BASE_URL + post_url : BASE_URL;
  console.log(url);
  var posts = [];

  jsdom.env(
    url,
    ["http://code.jquery.com/jquery.js"],
    function (errors, window) {
      var $ = window.$;

      var container = post_url ? $(".modal-container") : null;
      var $ph_posts = post_url ? $(".modal-container .posts-group tr") : $(".today tr");

      $ph_posts.each(function (rank) {

        var votes = +$(this).find(".upvote").text();
        var name = $(this).find("h3.user-name").clone().children().remove().end().text().trim().replace(/"/g, "");
        var username = $(this).find("span.user-handle").text().trim().replace(/"/g, "").match(/\(\@(.*)\)/)[1];
        var title = $(this).find(".post-url").text();
        var tagline = $(this).find(".post-tagline").text();

        if (container) {
          var comment_count = $(container.find(".subhead")[2]).text().trim().match(/(\d+)/g);;
        } else {
          var comment_count = $(this).find(".view-discussion").text().trim().match(/(\d+)/g);
        }
        comment_count = comment_count ? comment_count[0] : 0;

        var permalink = post_url ? post_url : $(this).find(".view-discussion").attr("data-url");

        request({url: BASE_URL+$(this).find(".post-url").attr("href"), followRedirect: false}, function (error, response, body) {
          url = response.headers.location;

          posts.push({
            'title': title,
            'votes': votes,
            'user': {
              'username': username,
              'name': name
            },
            'rank': rank + 1,
            'tagline': tagline,
            'comment_count': comment_count,
            'permalink': permalink,
            'url': url
          });

          console.log(posts);

          if (posts.length === $ph_posts.length) {
            callback(posts);
          }

        });

      });
    }
  );
}

app.listen(app.get('port'));
<commit_msg>fix conflicts<commit_after>require('newrelic');
var express = require('express');
var jsdom = require("jsdom");
var request = require('request');
var db = require('./config/db');
var Posts = require('./models/posts');
var Comments = require('./models/comments');

var app = express();

var BASE_URL = 'http://www.producthunt.com';

app.configure(function (){
  app.set('port', process.env.PORT || 8888);
  app.use(express.cookieParser('keyboard cat'));
  app.use(express.session({ secret: 'keyboard cat' }));
  app.use(app.router);
});

app.get('/', function (req, res) {
  res.redirect('https://github.com/karan/Hook');
});

app.get('/today', function (req, res) {

  var today = new Date().toJSON().slice(0,10);

  Posts.findOne({date: today}, function (err, obj) {

    if (obj && obj.expires < Date.now()) {
      // post expired, scrape again, and save
      console.log("posts expired - " + today);
      getHomePosts(null, function (posts) {
        Posts.findOneAndUpdate({date: today}, {posts: posts, expires: new Date(Date.now() + 60*60*1000)}, {new: true}, function (err, newObj) {
          res.send(200, {
            status: 'success',
            hunts: posts
          });
        });
      });
    } else if (obj) {
      console.log("posts not expired - " + today);
      // not expired, just return this
      res.send(200, {
        status: 'success',
        hunts: obj.posts
      });
    } else {
      // not in the db, scrape and send
      console.log("posts not found in db - " + today);

      getHomePosts(null, function (posts) {
        console.log("got details");
        new Posts({
          date: today,
          posts: posts
        }).save(function (err) {
          res.send(200, {
            status: 'success',
            hunts: posts
          });
        });
      });

    }

  });

});

app.get("/posts/:slug", function (req, res) {

  var post_url = '/posts/'+req.params.slug;

  Comments.findOne({'permalink': post_url}, function(err, commentobj) {

    if (commentobj && commentobj.expires < Date.now()) {
      // expired. Scrape again, save and send
      console.log("expired");
      getPostDetails(post_url, function (post) {
        console.log(post);
        getComments(post_url, function (err, comments, related) {
          Comments.findOneAndUpdate({permalink: post_url}, {post: post, comments: comments, expires: new Date(Date.now() + 2*60*60*1000)}, function (err, newObj) {
            res.send(200, {
              status: 'success',
              post: post,
              comments: comments
            });
          });
        });
      });
    } else if (commentobj) {
      console.log("in db - fine");
      // not expired, just send response
      res.send(200, {
        status: 'success',
        post: commentobj.post,
        comments: commentobj.comments
      });
    } else {
      console.log("not in db");
      // not in db, scrape, save and send
      getPostDetails(post_url, function (post) {
        console.log(post);
        getComments(post_url, function (err, comments, related) {
          new Comments({
            post: post,
            permalink: post.permalink,
            comments: comments
          }).save(function(err) {
            res.send(200, {
              status: 'success',
              post: post,
              comments: comments
            });
          });
        });
      });

    }

  });

});

function getPostDetails(post_url, callback) {
  var url = post_url ? BASE_URL + post_url : BASE_URL;
  console.log(url);

  jsdom.env(
    url,
    ["http://code.jquery.com/jquery.js"],
    function (errors, window) {

      if (errors) {
        console.log(errors);
      }
      console.log(window.title);
      var $ = window.$;

      console.log($);

      var header_dom = $(".comments-header");

      var votes = +header_dom.find(".vote-count").text();
      var name = /Posted by (.*) \d+ .*/g.exec(header_dom.find(".posted-by").text().trim().replace(/"/g, ""))[1];
      var username = header_dom.find(".user-with-tooltip").attr("href").slice(1).trim().replace(/"/g, "");
      var title = header_dom.find(".post-url").text();
      var tagline = header_dom.find(".post-tagline").text();

      var comment_count = $($(".modal-container").find(".subhead")[2]).text().trim().match(/(\d+)/g);
      comment_count = comment_count ? comment_count[0] : 0;

      var permalink = post_url;

      request({url: BASE_URL+header_dom.find(".post-url").attr("href"), followRedirect: false}, function (error, response, body) {
        url = response.headers.location;

        callback({
          'title': title,
          'votes': votes,
          'user': {
            'username': username,
            'name': name
          },
          'rank': 1,
          'tagline': tagline,
          'comment_count': comment_count,
          'permalink': permalink,
          'url': url
        });

      });

    }
  );
}

function getComments(url, callback) {

  jsdom.env(
    BASE_URL+url,
    ["http://code.jquery.com/jquery.js"],
    function (errors, window) {
      var $ = window.$;

      var comments = [];

      var comments_dom = $(".comment-thread");

      if (comments_dom.length === 0) {
        return callback(null, comments);
      }

      comments_dom.each(function (index) {
        var this_comments = $(this).find(".comment");

        this_comments.each(function (com_count) {
          var username = $(this).find(".comment-body").data("comment-by").match(/\(\@(.*)\)/)[1];
          var name = $(this).find(".comment-user-name a").text();
          var comment = $(this).find(".actual-comment").text();
          var comment_html = $(this).find(".actual-comment").html();

          console.log(username + "--" + name);

          if (com_count === 0) {
            // Get the top level comment
            comments.push({
              index: index+1,
              user: {
                username: username,
                name: name
              },
              comment: comment,
              comment_html: comment_html,
              children: []
            });
          } else {
            // Get the child comment
            comments[comments.length-1].children.push({
              index: com_count+1,
              user: {
                username: username,
                name: name
              },
              comment: comment,
              comment_html: comment_html
            });
          }

          if (comments.length === comments_dom.length) {
            callback(null, comments);
          }
        });

      });

    }
  );

}

function getHomePosts(post_url, callback) {
  var url = post_url ? BASE_URL + post_url : BASE_URL;
  console.log(url);
  var posts = [];

  jsdom.env(
    url,
    ["http://code.jquery.com/jquery.js"],
    function (errors, window) {
      var $ = window.$;

      var container = post_url ? $(".modal-container") : null;
      var $ph_posts = post_url ? $(".modal-container .posts-group tr") : $(".today tr");

      $ph_posts.each(function (rank) {

        var votes = +$(this).find(".upvote").text();
        var name = $(this).find("h3.user-name").clone().children().remove().end().text().trim().replace(/"/g, "");
        var username = $(this).find("span.user-handle").text().trim().replace(/"/g, "").match(/\(\@(.*)\)/)[1];
        var title = $(this).find(".post-url").text();
        var tagline = $(this).find(".post-tagline").text();

        if (container) {
          var comment_count = $(container.find(".subhead")[2]).text().trim().match(/(\d+)/g);;
        } else {
          var comment_count = $(this).find(".view-discussion").text().trim().match(/(\d+)/g);
        }
        comment_count = comment_count ? comment_count[0] : 0;

        var permalink = post_url ? post_url : $(this).find(".view-discussion").attr("data-url");

        request({url: BASE_URL+$(this).find(".post-url").attr("href"), followRedirect: false}, function (error, response, body) {
          url = response.headers.location;

          posts.push({
            'title': title,
            'votes': votes,
            'user': {
              'username': username,
              'name': name
            },
            'rank': rank + 1,
            'tagline': tagline,
            'comment_count': comment_count,
            'permalink': permalink,
            'url': url
          });

          console.log(posts);

          if (posts.length === $ph_posts.length) {
            callback(posts);
          }

        });

      });
    }
  );
}

app.listen(app.get('port'));
<|endoftext|>