<commit_before>var task_start = performance.now();
var measurement_start = performance.now();

// for ticks per second
var tick = 0;
var lastTime = 0.0;

// last measured angles
var alpha = 0.0;
var beta = 0.0;
var gamma = 0.0;

// angles of calibration
var correctionX = 0.0;
var correctionY = 0.0;
var correctionZ = 0.0;

// defines state of system
var measurementActive = false;
var data = [];
var angles = [];
tail = 0;
const NUM_ANGLES = 10;

// for fold
const REL_POINTS = 4;
const USED_SIGMA = 0.025;

var state = -1;
const INIT = 0;
const CALIBRATE = 1;
const READY = 2;
const MEASURE = 3;
const CALCULATE = 4;

function main() {
	init();
}

function init() {
	state = INIT;
	document.getElementById("actionBtn").value = "Please hold still and press button for calibration.";
}

function calibrate() {
	state = CALIBRATE;
	document.getElementById("actionBtn").value = "Now Calibrating";
	startNewMeasurement();
}

function ready() {
	alert("X: " + correctionX + " Y: " + correctionY + " Z: " + correctionZ);
	state = READY;
	resetAngles();
	document.getElementById("actionBtn").value = "Press to start measurement.";
}

function measure() {
	state = MEASURE;
	startNewMeasurement();
	document.getElementById("actionBtn").value = "Now measuring. Press again to stop measurement.";
}

function calculate() {
	stopMeasurement();
	state = CALCULATE;
	prepareData();
	var zDistance = calculateDistance();
	document.querySelector("#zdist_acc").innerHTML = "Traveled Z-distance: " + zDistance;

	ready();
}

// ------------------------------------------------------------

function performAction() {
	switch (state) {
		case INIT: calibrate();
			break;
		case CALIBRATE: document.getElementById("actionBtn").value = "Please wait";
			break;
		case READY: measure();
			break;
		case MEASURE: calculate();
			break;
		case CALCULATE: document.getElementById("actionBtn").value = "Please wait";
			break;
		default: alert("Invalid state: " + state);
			break;
	}
}

// ------------------------------------------------------------

// measurement routine
window.ondevicemotion = function(event) {
	var ax = -event.accelerationIncludingGravity.x;
	var ay = -event.accelerationIncludingGravity.y;
	var az = -event.accelerationIncludingGravity.z;

	if(measurementActive) { // record data
		var newItem = [];
		newItem["time"] = (performance.now() - task_start) / 1000.0;
		newItem["ax"] = ax;
		newItem["ay"] = ay;
		newItem["az"] = az;
		data.push(newItem);

		if (state == CALIBRATE && data.length >= 100) {
			stopMeasurement();
		}
	}

	var outAx = (Math.round(ax * 10000) / 10000.0);
	var outAy = (Math.round(ay * 10000) / 10000.0);
	var outAz = (Math.round(az * 10000) / 10000.0);
	var outAlpha = (Math.round(alpha * 10000) / 10000.0);
	var outBeta = (Math.round(beta * 10000) / 10000.0);
	var outGamma = (Math.round(gamma * 10000) / 10000.0);

	var currentTime = performance.now() - measurement_start;
	var outTime = (Math.round(currentTime) / 1000.0);

	document.querySelector("#x_acc").innerHTML = "X = " + outAx;
	document.querySelector("#y_acc").innerHTML = "Y = " + outAy;
	document.querySelector("#z_acc").innerHTML = "Z = " + outAz;
	document.querySelector("#time_acc").innerHTML = "Time = " + outTime;

	document.querySelector("#mag_alpha").innerHTML = "alpha = " + outAlpha;
	document.querySelector("#mag_beta").innerHTML = "beta = " + outBeta;
	document.querySelector("#mag_gamma").innerHTML = "gamma = " + outGamma;

	// measurements per second
	tick = tick + 1;

	if (currentTime - lastTime >= 1000.0) {
		lastTime = Math.floor(currentTime);
		document.querySelector("#tick_acc").innerHTML = "Ticks per Second = " + tick;
		tick = 0;
	}
}

// Stores current angles for later interpolation
window.addEventListener("deviceorientation", function(event) {

	var ang = [];
	ang["time"] = (performance.now() - task_start) / 1000.0;

	// angles in system
	alpha = event.alpha;
	beta = (event.beta + 360.0);
	gamma = -event.gamma;

	ang["alpha"] = alpha;
	ang["beta"] = beta;
	ang["gamma"] = gamma;

	if (state != CALCULATE) {
		if (measurementActive || (angles.length <= NUM_ANGLES))  {
			angles.push(ang);
		} else if (tail > 0) {
			angles.push(ang);
			tail = tail - 1;
			if (state == CALIBRATE && tail == 0) {
				performCalibration();
			}
		} else {
			angles.shift();
			angles.push(ang);
		}
	}

}, true);

// ------------------------------------------------------------

// Transforms measurements into world space and corrects them according to calibration
function prepareData() {
	// get relating angles for acceleration
	addAnglesToData(USED_SIGMA, REL_POINTS);

	for (var i = 0; i < data.length; i++) {

		// transform into world space
		var vec = [];
		vec["x"] = data[i]["ax"];
		vec["y"] = data[i]["ay"];
		vec["z"] = data[i]["az"]
		vec = transformDeviceToWorld(vec, data[i]["alpha"], data[i]["beta"], data[i]["gamma"]);

		// calibrate
		if (state != CALIBRATE) {
			data[i]["ax"] = vec["x"] - correctionX;
			data[i]["ay"] = vec["y"] - correctionY;
			data[i]["az"] = vec["z"] - correctionZ;
		} else { // state == CALIBRATE
			data[i]["ax"] = vec["x"];
			data[i]["ay"] = vec["y"];
			data[i]["az"] = vec["z"];
		}

		// normalize time
		data[i]["time"] = data[i]["time"] - data[0]["time"];
	}
}

// trial for z distance
function calculateDistance() {
    var speed = [];

	speed.push(0.0);

	for (var i = 1; i < data.length; i++) { // simple trapez rule
		var interval = (data[i]["time"] - data[i - 1]["time"]);
		var avgAcceleration = (data[i]["az"] + data[i - 1]["az"]) / 2.0;
		var newSpeed = speed[i - 1] + avgAcceleration * interval;
		speed.push(newSpeed);
	}

	var dist = 0.0;
	for (var i = 1; i < speed.length; i++) {
		var interval = (data[i]["time"] - data[i - 1]["time"]);
		var avgSpeed = (speed[i - 1] + speed[i]) / 2.0;
		dist = dist + avgSpeed * interval;
	}

	return dist;
}

// performs calibration based on measured data
function performCalibration() {
	alert("HIT PREPARE");
	prepareData();
	alert("LEFT PREPARE");
	var sum_x = 0.0;
	var sum_y = 0.0;
	var sum_z = 0.0;

	for (var i = 0; i < data.length; i++) {
		sum_x += data[i]["ax"];
		sum_y += data[i]["ay"];
		sum_z += data[i]["az"];
	}

	correctionX = sum_x / data.length;
	correctionY = sum_y / data.length;
	correctionZ = sum_z / data.length;

	ready();

}

// ------------------------------------------------------------

// folds the data with a gaussian distribution to derive acurate angles
function addAnglesToData(sigma, rel_points) {
	if (angles.length < NUM_ANGLES * 2) {
		alert("Error, not enough measurements. Please try again.")
		return;
	}
	if (angles.rel_points > NUM_ANGLES) {
		alert("Please reduce relevant points.")
		return;
	}
	var variance = sigma * sigma;

	var lastJ = 0;
	for (var i = 0; i < data.length; i++) {
		var closest = -1;
		var relevantAngles = [];

		// find nearest measurement
		for (var j = lastJ; j < angles.length; j++) {
			if ((angles[j]["time"] <= data[i]["time"]) && (data[i]["time"] <= angles[j + 1]["time"])) {
				lastJ = j;
				if ((data[i]["time"] - angles[j]["time"]) < (angles[j + 1]["time"] - data[i]["time"])) {
					closest = j;
				} else {
					closest = j+1;
				}
				relevantAngles.push(closest);
				break;
			}
		}

		alert("HIT CLOSEST " + closest);

		// get relevant angles for fold
		var hiID = closest + 1;
		var loID = closest - 1;
		while(relevantAngles.length < rel_points) {
			alert(relevantAngles.length + "  " + rel_points);
			if ((data[i]["time"] - angles[loID]["time"]) < (angles[hiID]["time"] - data[i]["time"])) {
				relevantAngles.push(loID);
				loID = loID - 1;
			} else {
				relevantAngles.push(hiID);
				hiID = hiID + 1;
			}
			alert(relevantAngles.length + "  " + rel_points);
		}
		alert("HIT RELEVANT");

		// fold
		var sum = 0.0;
		data[i]["alpha"] = 0.0;
		data[i]["beta"] = 0.0;
		data[i]["gamma"] = 0.0;
		for (var j = 0; j < relevantAngles; j++) {
			var fa = Math.exp(-((data[i]["time"] - angles[relevantAngles[i]]["time"])
				* (data[i]["time"] - angles[relevantAngles[i]]["time"])) / (2 * variance));
			data[i]["alpha"] = fa * angles[relevantAngles[i]]["alpha"];
			data[i]["beta"] = fa * angles[relevantAngles[i]]["beta"];
			data[i]["gamma"] = fa * angles[relevantAngles[i]]["gamma"];
			sum = sum + fa;
		}

		data[i]["alpha"] = data[i]["alpha"] / sum;
		data[i]["beta"] = data[i]["beta"] / sum;
		data[i]["gamma"] = data[i]["gamma"] / sum;

		alert("HIT " + i);
	}
}

// starts measurement and clears data
function startNewMeasurement() {
	resetMeasurement();
	measurement_start = performance.now();
	measurementActive = true;
}

// stops measurement and clears data
function resetMeasurement() {
	stopMeasurement();
	data.length = 0;
}

// stop measurements
function stopMeasurement() {
	measurementActive = false;
	tail = NUM_ANGLES;
}

// resets angles
function resetAngles() {
	angles.length = 0;
}
<commit_msg>Test angular calibration<commit_after>var task_start = performance.now();
var measurement_start = performance.now();

// for ticks per second
var tick = 0;
var lastTime = 0.0;

// last measured angles
var alpha = 0.0;
var beta = 0.0;
var gamma = 0.0;

// angles of calibration
var correctionX = 0.0;
var correctionY = 0.0;
var correctionZ = 0.0;

// defines state of system
var measurementActive = false;
var data = [];
var angles = [];
tail = 0;
const NUM_ANGLES = 10;

// for fold
const REL_POINTS = 4;
const USED_SIGMA = 0.025;

var state = -1;
const INIT = 0;
const CALIBRATE = 1;
const READY = 2;
const MEASURE = 3;
const CALCULATE = 4;

function main() {
	init();
}

function init() {
	state = INIT;
	document.getElementById("actionBtn").value = "Please hold still and press button for calibration.";
}

function calibrate() {
	state = CALIBRATE;
	document.getElementById("actionBtn").value = "Now Calibrating";
	startNewMeasurement();
}

function ready() {
	alert("X: " + correctionX + " Y: " + correctionY + " Z: " + correctionZ);
	state = READY;
	resetAngles();
	document.getElementById("actionBtn").value = "Press to start measurement.";
}

function measure() {
	state = MEASURE;
	startNewMeasurement();
	document.getElementById("actionBtn").value = "Now measuring. Press again to stop measurement.";
}

function calculate() {
	stopMeasurement();
	state = CALCULATE;
	prepareData();
	var zDistance = calculateDistance();
	document.querySelector("#zdist_acc").innerHTML = "Traveled Z-distance: " + zDistance;

	ready();
}

// ------------------------------------------------------------

function performAction() {
	switch (state) {
		case INIT: calibrate();
			break;
		case CALIBRATE: document.getElementById("actionBtn").value = "Please wait";
			break;
		case READY: measure();
			break;
		case MEASURE: calculate();
			break;
		case CALCULATE: document.getElementById("actionBtn").value = "Please wait";
			break;
		default: alert("Invalid state: " + state);
			break;
	}
}

// ------------------------------------------------------------

// measurement routine
window.ondevicemotion = function(event) {
	var ax = -event.accelerationIncludingGravity.x;
	var ay = -event.accelerationIncludingGravity.y;
	var az = -event.accelerationIncludingGravity.z;

	if(measurementActive) { // record data
		var newItem = [];
		newItem["time"] = (performance.now() - task_start) / 1000.0;
		newItem["ax"] = ax;
		newItem["ay"] = ay;
		newItem["az"] = az;
		data.push(newItem);

		if (state == CALIBRATE && data.length >= 100) {
			stopMeasurement();
		}
	}

	var outAx = (Math.round(ax * 10000) / 10000.0);
	var outAy = (Math.round(ay * 10000) / 10000.0);
	var outAz = (Math.round(az * 10000) / 10000.0);
	var outAlpha = (Math.round(alpha * 10000) / 10000.0);
	var outBeta = (Math.round(beta * 10000) / 10000.0);
	var outGamma = (Math.round(gamma * 10000) / 10000.0);

	var currentTime = performance.now() - measurement_start;
	var outTime = (Math.round(currentTime) / 1000.0);

	document.querySelector("#x_acc").innerHTML = "X = " + outAx;
	document.querySelector("#y_acc").innerHTML = "Y = " + outAy;
	document.querySelector("#z_acc").innerHTML = "Z = " + outAz;
	document.querySelector("#time_acc").innerHTML = "Time = " + outTime;

	document.querySelector("#mag_alpha").innerHTML = "alpha = " + outAlpha;
	document.querySelector("#mag_beta").innerHTML = "beta = " + outBeta;
	document.querySelector("#mag_gamma").innerHTML = "gamma = " + outGamma;

	// measurements per second
	tick = tick + 1;

	if (currentTime - lastTime >= 1000.0) {
		lastTime = Math.floor(currentTime);
		document.querySelector("#tick_acc").innerHTML = "Ticks per Second = " + tick;
		tick = 0;
	}
}

// Stores current angles for later interpolation
window.addEventListener("deviceorientation", function(event) {

	var ang = [];
	ang["time"] = (performance.now() - task_start) / 1000.0;

	// angles in system
	alpha = event.alpha;
	beta = (event.beta + 360.0);
	gamma = -event.gamma;

	ang["alpha"] = alpha;
	ang["beta"] = beta;
	ang["gamma"] = gamma;

	if (state != CALCULATE) {
		if (measurementActive || (angles.length <= NUM_ANGLES))  {
			angles.push(ang);
		} else if (tail > 0) {
			angles.push(ang);
			tail = tail - 1;
			if (state == CALIBRATE && tail == 0) {
				performCalibration();
			}
		} else {
			angles.shift();
			angles.push(ang);
		}
	}

}, true);

// ------------------------------------------------------------

// Transforms measurements into world space and corrects them according to calibration
function prepareData() {
	// get relating angles for acceleration
	addAnglesToData(USED_SIGMA, REL_POINTS);

	for (var i = 0; i < data.length; i++) {

		// transform into world space
		var vec = [];
		vec["x"] = data[i]["ax"];
		vec["y"] = data[i]["ay"];
		vec["z"] = data[i]["az"]
		vec = transformDeviceToWorld(vec, data[i]["alpha"], data[i]["beta"], data[i]["gamma"]);

		// calibrate
		if (state != CALIBRATE) {
			data[i]["ax"] = vec["x"] - correctionX;
			data[i]["ay"] = vec["y"] - correctionY;
			data[i]["az"] = vec["z"] - correctionZ;
		} else { // state == CALIBRATE
			data[i]["ax"] = vec["x"];
			data[i]["ay"] = vec["y"];
			data[i]["az"] = vec["z"];
		}

		// normalize time
		data[i]["time"] = data[i]["time"] - data[0]["time"];
	}
}

// trial for z distance
function calculateDistance() {
    var speed = [];

	speed.push(0.0);

	for (var i = 1; i < data.length; i++) { // simple trapez rule
		var interval = (data[i]["time"] - data[i - 1]["time"]);
		var avgAcceleration = (data[i]["az"] + data[i - 1]["az"]) / 2.0;
		var newSpeed = speed[i - 1] + avgAcceleration * interval;
		speed.push(newSpeed);
	}

	var dist = 0.0;
	for (var i = 1; i < speed.length; i++) {
		var interval = (data[i]["time"] - data[i - 1]["time"]);
		var avgSpeed = (speed[i - 1] + speed[i]) / 2.0;
		dist = dist + avgSpeed * interval;
	}

	return dist;
}

// performs calibration based on measured data
function performCalibration() {
	alert("HIT PREPARE");
	prepareData();
	alert("LEFT PREPARE");
	var sum_x = 0.0;
	var sum_y = 0.0;
	var sum_z = 0.0;

	for (var i = 0; i < data.length; i++) {
		sum_x += data[i]["ax"];
		sum_y += data[i]["ay"];
		sum_z += data[i]["az"];
	}

	correctionX = sum_x / data.length;
	correctionY = sum_y / data.length;
	correctionZ = sum_z / data.length;

	ready();

}

// ------------------------------------------------------------

// folds the data with a gaussian distribution to derive acurate angles
function addAnglesToData(sigma, rel_points) {
	if (angles.length < NUM_ANGLES * 2) {
		alert("Error, not enough measurements. Please try again.")
		return;
	}
	if (angles.rel_points > NUM_ANGLES) {
		alert("Please reduce relevant points.")
		return;
	}
	var variance = sigma * sigma;

	var lastJ = 0;
	for (var i = 0; i < data.length; i++) {
		var closest = -1;
		var relevantAngles = [];

		// find nearest measurement
		for (var j = lastJ; j < angles.length; j++) {
			if ((angles[j]["time"] <= data[i]["time"]) && (data[i]["time"] <= angles[j + 1]["time"])) {
				lastJ = j;
				if ((data[i]["time"] - angles[j]["time"]) < (angles[j + 1]["time"] - data[i]["time"])) {
					closest = j;
				} else {
					closest = j+1;
				}
				relevantAngles.push(closest);
				break;
			}
		}

		// get relevant angles for fold
		var hiID = closest + 1;
		var loID = closest - 1;
		while(relevantAngles.length < rel_points) {
			if ((data[i]["time"] - angles[loID]["time"]) < (angles[hiID]["time"] - data[i]["time"])) {
				relevantAngles.push(loID);
				loID = loID - 1;
			} else {
				relevantAngles.push(hiID);
				hiID = hiID + 1;
			}
		}

		// fold
		var sum = 0.0;
		data[i]["alpha"] = 0.0;
		data[i]["beta"] = 0.0;
		data[i]["gamma"] = 0.0;
		for (var j = 0; j < relevantAngles; j++) {
			var fa = Math.exp(-((data[i]["time"] - angles[relevantAngles[i]]["time"])
				* (data[i]["time"] - angles[relevantAngles[i]]["time"])) / (2 * variance));
			data[i]["alpha"] = fa * angles[relevantAngles[i]]["alpha"];
			data[i]["beta"] = fa * angles[relevantAngles[i]]["beta"];
			data[i]["gamma"] = fa * angles[relevantAngles[i]]["gamma"];
			sum = sum + fa;
		}

		data[i]["alpha"] = data[i]["alpha"] / sum;
		data[i]["beta"] = data[i]["beta"] / sum;
		data[i]["gamma"] = data[i]["gamma"] / sum;
	}
}

// starts measurement and clears data
function startNewMeasurement() {
	resetMeasurement();
	measurement_start = performance.now();
	measurementActive = true;
}

// stops measurement and clears data
function resetMeasurement() {
	stopMeasurement();
	data.length = 0;
}

// stop measurements
function stopMeasurement() {
	measurementActive = false;
	tail = NUM_ANGLES;
}

// resets angles
function resetAngles() {
	angles.length = 0;
}
<|endoftext|>


<commit_before>var Model = require('../model/models.js'),
	validator = require('validator'),
	addressValidator = require('address-validator'),
	_= require('underscore');
    Address = addressValidator.Address;

module.exports.show = function(req, res) {
	res.render('properties');
};

module.exports.create = function(req, res) {
	var street = req.body.street;
	var zipcode = req.body.zipcode;
	var city = req.body.city;
	var state = req.body.state;
	var country = req.body.country;
	var bedrooms = req.body.bedrooms;
	var bathrooms = req.body.bathrooms;
	var parking = req.body.parking;
	var squareFootage = req.body.squareFootage;

	if (!validator.isNumeric(zipcode)) {
		req.flash('error', "Please, enter a valid zipcode.");
	}

	if (!validator.isNumeric(bedrooms) || !validator.isInt(bedrooms, {min:0, max:15})) {
		req.flash('error', "Please, enter a valid number of bedrooms.");
	}

	if (!validator.isNumeric(bathrooms) || !validator.isInt(bathrooms, {min:0, max:15})) {
		req.flash('error', "Please, enter a valid number of bathrooms.");
	}

	if (!validator.isNumeric(parking)) {
		req.flash('error', "Please, enter a valid number of parking units.");
	}

	if (!validator.isNumeric(squareFootage)) {
		req.flash('error', "Please, enter a valid square footage.");
	}

	var testAddress = new Address({
		street: street,
		city: city,
		state: state,
		country: country
	});

    var newAddress;
    var first;
// addressValidator.match.streetAddress` -> tells the validator that you think the input should be a street address. This data makes the validator more accurate.
	addressValidator.validate(testAddress, addressValidator.match.streetAddress, function(err, exact, inexact) {
        first = exact[0];

        newAddress = {
            street: first.streetNumber + " " + first.street,
            city: first.city,
            state: first.state,
            country: first.countryAbbr,
            zipcode: first.postalCode,
            latitude: first.location.lat,
            longitude: first.location.lon,
			bedrooms: bedrooms,
            bathrooms: bathrooms,
            parking: parking,
            squareFootage: squareFootage
            // owner: Model.PropertyManager.username;  // figure this out.
        };
        console.log("after setting new address");
        console.log(newAddress);
	});

	console.log("after address validation");
	console.log(newAddress);
    Model.Property.create(newAddress).then(function() {
        console.log("Adding to property table...");
        res.redirect('/properties');
    }).catch(function(error) {
        req.flash('error', "Please, enter a valid address.");
        res.redirect('/properties');
    });
};<commit_msg>debugging adding to property table<commit_after>var Model = require('../model/models.js'),
	validator = require('validator'),
	addressValidator = require('address-validator'),
	_= require('underscore');
    Address = addressValidator.Address;

module.exports.show = function(req, res) {
	res.render('properties');
};

module.exports.create = function(req, res) {
	var street = req.body.street;
	var zipcode = req.body.zipcode;
	var city = req.body.city;
	var state = req.body.state;
	var country = req.body.country;
	var bedrooms = req.body.bedrooms;
	var bathrooms = req.body.bathrooms;
	var parking = req.body.parking;
	var squareFootage = req.body.squareFootage;

	if (!validator.isNumeric(zipcode)) {
		req.flash('error', "Please, enter a valid zipcode.");
	}

	if (!validator.isNumeric(bedrooms) || !validator.isInt(bedrooms, {min:0, max:15})) {
		req.flash('error', "Please, enter a valid number of bedrooms.");
	}

	if (!validator.isNumeric(bathrooms) || !validator.isInt(bathrooms, {min:0, max:15})) {
		req.flash('error', "Please, enter a valid number of bathrooms.");
	}

	if (!validator.isNumeric(parking)) {
		req.flash('error', "Please, enter a valid number of parking units.");
	}

	if (!validator.isNumeric(squareFootage)) {
		req.flash('error', "Please, enter a valid square footage.");
	}

	var testAddress = new Address({
		street: street,
		city: city,
		state: state,
		country: country
	});

    var newAddress;
    var first;
// addressValidator.match.streetAddress` -> tells the validator that you think the input should be a street address. This data makes the validator more accurate.
	addressValidator.validate(testAddress, addressValidator.match.streetAddress, function(err, exact, inexact) {
        first = exact[0];
        if (first == null) {
        	req.flash('error', "Please enter a valid address.");
        }

        newAddress = {
            street: first.streetNumber + " " + first.street,
            city: first.city,
            state: first.state,
            country: first.countryAbbr,
            zipcode: first.postalCode,
            latitude: first.location.lat,
            longitude: first.location.lon,
			bedrooms: bedrooms,
            bathrooms: bathrooms,
            parking: parking,
            squareFootage: squareFootage
            // owner: Model.PropertyManager.username;  // figure this out.
        };
        console.log("new address:");
        console.log(newAddress);

        Model.Property.create(newAddress).then(function() {
        	console.log("Adding to property table...");
        	res.redirect('/properties');
    	}).catch(function(error) {
        	req.flash('error', "fuck up in adding to property table");
        	res.redirect('/properties');
    	});
	});

	// console.log("after address validation");
	// console.log(newAddress);
    // Model.Property.create(newAddress).then(function() {
    //     console.log("Adding to property table...");
    //     res.redirect('/properties');
    // }).catch(function(error) {
    //     req.flash('error', "Please, enter a valid address.");
    //     res.redirect('/properties');
    // });
};<|endoftext|>


<commit_before>var mongoose = require('mongoose'),
    Account = mongoose.model('Account'),
    ntwitter = require('twit'),
    keys = require('../../../config/twitterKeys.json'),
    params, maxTweets = 200,
    foundTweets = 0,
    corpus, twit, acct, res, mode = 'timeline',
    publicSources = {
        'earthquake': 1,
        'usgs': 1,
        'ieeevis': 1,
        'twitscores':1
    }

    /* Checks cache for screenname, count and date.
     *
     * This should use maxid if date is stale so that the
     * full record doesn't need to be fetched...
     *
     * */

exports.checkCache = function(acct, args) {
    //no way to access cache
    if (!acct.streams) return null
    if (!args) return null

    var sn = ct = mode = null
    if (args[0]) mode = args[0]
    if (args[1]) sn = args[1]
    if (args[2]) ct = args[2]
    var dt = new Date();
    dt.setMinutes(dt.getMinutes() - 15);

    for (var index in acct.streams) {
        var at = acct.streams[index]
        if (at.screen_name == sn && at.mode == mode && at.count >= ct && at.dateRequested >= dt) {

            content = JSON.parse(at.content)
            //ghetto fix when you have time!
            for (i in content) {
                content[i] = content[i].slice(0, ct)
            }
            at.content = JSON.stringify(content)
            return at
        }
    }
    return null
}

exports.init = function(account, args, resp) {

    acct = account
    res = resp
    corpus = "{"
    mode = args[0]
    foundTweets = 0

    var key = keys,
        isPublic = true

        //check to see whether the account is associated with twitter
    if (acct) {
        if (!(acct.email == 'public')) isPublic = false
        if (acct.tokens) {
            key.access_token = acct.tokens.token
            key.access_token_secret = acct.tokens.tokenSecret
        }
    } else return res.json({
        "error": "no account could be found or used"
    })
    twit = new ntwitter(key)

    //set up parameters for timeline or followers
    if (args) {
        if (args[2]) maxTweets = args[2]
        if (mode == 'timeline') {
            corpus = {
                "tweets": []
            }
            params = {
                screen_name: args[1],
                count: 200,
                include_rts: true
            }
            startGettingTweets(getTweets, isPublic, args[1])
        } else if (mode == 'followers') {

            params = {
                screen_name: args[1],
                count: (args[2]) ? args[2] : 5
            }
            startGettingTweets(getFollowersById, isPublic, args[1])
        } else {
            return res.json({
                "error": "Must query for either timeline or followers"
            })
        }
    }
}

function startGettingTweets(cb, isPublic, source) {
    //if the account is not associated, ensure request is a "public" feed
    if (isPublic) {
        if (!(source in publicSources)) {
            var srcs = ""
            for (i in publicSources) {
                srcs += i + " "
            }
            return res.json({
                "error": source + " isn't supported without " +
                    "authenticating via twitter; public sources include: " + srcs
            })
        }
    }
    cb(null, "")
}

function getFollowersById(blank, tweets) {

    var corpus = {
        "followers": []
    }, param = {
            "screen_name": params.screen_name
        }

    twit.get('followers/ids', param, function(err, data) {
        if (err) return res.json({
            "error": "unable to retrieve from twitter api"
        })

        if (!data) return res.json({
            "error": "no results found"
        })
        //only take as many as was requested
        data = data.ids.slice(0, params.count)
        param = {
            "user_id": data.toString()
        }

        twit.get('/users/lookup', param, function(err, processed) {
            if (err) return res.json({"err":err})
            if (!processed) return res.json({
                "err":"the number of items you "+
                "requested appears to be to large"})
            for (var i = 0; i < processed.length; i++) {
                corpus.followers.push(processed[i].screen_name)
            }
            updateTweets(corpus)
        })
    })
}

function getTweets(maxid, tweets) {
    if (maxid) params.max_id = maxid

    if ((maxTweets - foundTweets) < params.count)
        params.count = maxTweets - foundTweets

    twit.get("/statuses/user_timeline", params, function(err, data) {
        if (err) return res.json({
            "error": err
        })

        if (data.length > 1 && maxTweets > foundTweets) {

            var tweetID = countRT = countT = 0
            data.forEach(function(rawtweet) {
                if (rawtweet.retweeted_status) {
                    tweet = rawtweet.retweeted_status
                    countRT++
                } else {
                    tweet = rawtweet
                    countT++
                }
                corpus.tweets.push({
                    "date": tweet.created_at,
                    "tweet": tweet.text
                })
                tweetID = tweet.id
            });
            foundTweets = countRT + countT + foundTweets
            console.log(countRT + " retweets and " + countT + " tweets")
            getTweets(tweetID, "")

        } else {
            updateTweets(corpus)
        }
    })
}

function updateTweets(corpus) {

    console.log(corpus)
    res.json(corpus)

    var updateDate = {
        'screen_name': params.screen_name,
        'count': maxTweets,
        'content': JSON.stringify(corpus),
        'dateRequested': Date.now(),
        'maxid': 0,
        'mode': mode
    }

    replaceCache = function(acct, sn, data) {
        for (a in acct.streams) {
            if (acct.streams[a].screen_name == sn) {
                acct.streams.splice(a)
                acct.streams.push(data)
                return acct
            }
        }
        acct.streams.push(data)
        return acct
    }
    acct = replaceCache(acct, params.screen_name, updateDate)
    acct.save(function(err) {
        if (err) console.log(err)
        return true;
    })
}
<commit_msg>temporary fix: invalid twitter keys<commit_after>var mongoose = require('mongoose'),
    Account = mongoose.model('Account'),
    ntwitter = require('twit'),
    keys = require('../../../config/twitterKeys.json'),
    params, maxTweets = 200,
    foundTweets = 0,
    corpus, twit, acct, res, mode = 'timeline',
    publicSources = {
        'earthquake': 1,
        'usgs': 1,
        'ieeevis': 1,
        'twitscores':1
    }

    /* Checks cache for screenname, count and date.
     *
     * This should use maxid if date is stale so that the
     * full record doesn't need to be fetched...
     *
     * */

exports.checkCache = function(acct, args) {
    //no way to access cache
    if (!acct.streams) return null
    if (!args) return null

    var sn = ct = mode = null
    if (args[0]) mode = args[0]
    if (args[1]) sn = args[1]
    if (args[2]) ct = args[2]
    var dt = new Date();
    dt.setMinutes(dt.getMinutes() - 15);

    for (var index in acct.streams) {
        var at = acct.streams[index]
        if (at.screen_name == sn && at.mode == mode && at.count >= ct && at.dateRequested >= dt) {

            content = JSON.parse(at.content)
            //ghetto fix when you have time!
            for (i in content) {
                content[i] = content[i].slice(0, ct)
            }
            at.content = JSON.stringify(content)
            return at
        }
    }
    return null
}

exports.init = function(account, args, resp) {

    acct = account
    res = resp
    corpus = "{"
    mode = args[0]
    foundTweets = 0

    var key = keys,
        isPublic = true

        //check to see whether the account is associated with twitter
    if (acct) {
        if (!(acct.email == 'public')) isPublic = false
        if (acct.tokens) {
            key.access_token = acct.tokens.token
            key.access_token_secret = acct.tokens.tokenSecret
        }
    } else return res.json({
        "error": "no account could be found or used"
    })
    try { twit = new ntwitter(key) }
    catch (err) {
        acct.tokens=null
        acct.save()
    }

    //set up parameters for timeline or followers
    if (args) {
        if (args[2]) maxTweets = args[2]
        if (mode == 'timeline') {
            corpus = {
                "tweets": []
            }
            params = {
                screen_name: args[1],
                count: 200,
                include_rts: true
            }
            startGettingTweets(getTweets, isPublic, args[1])
        } else if (mode == 'followers') {

            params = {
                screen_name: args[1],
                count: (args[2]) ? args[2] : 5
            }
            startGettingTweets(getFollowersById, isPublic, args[1])
        } else {
            return res.json({
                "error": "Must query for either timeline or followers"
            })
        }
    }
}

function startGettingTweets(cb, isPublic, source) {
    //if the account is not associated, ensure request is a "public" feed
    if (isPublic) {
        if (!(source in publicSources)) {
            var srcs = ""
            for (i in publicSources) {
                srcs += i + " "
            }
            return res.json({
                "error": source + " isn't supported without " +
                    "authenticating via twitter; public sources include: " + srcs
            })
        }
    }
    cb(null, "")
}

function getFollowersById(blank, tweets) {

    var corpus = {
        "followers": []
    }, param = {
            "screen_name": params.screen_name
        }

    twit.get('followers/ids', param, function(err, data) {
        if (err) return res.json({
            "error": "unable to retrieve from twitter api"
        })

        if (!data) return res.json({
            "error": "no results found"
        })
        //only take as many as was requested
        data = data.ids.slice(0, params.count)
        param = {
            "user_id": data.toString()
        }

        twit.get('/users/lookup', param, function(err, processed) {
            if (err) return res.json({"err":err})
            if (!processed) return res.json({
                "err":"the number of items you "+
                "requested appears to be to large"})
            for (var i = 0; i < processed.length; i++) {
                corpus.followers.push(processed[i].screen_name)
            }
            updateTweets(corpus)
        })
    })
}

function getTweets(maxid, tweets) {
    if (maxid) params.max_id = maxid

    if ((maxTweets - foundTweets) < params.count)
        params.count = maxTweets - foundTweets

    twit.get("/statuses/user_timeline", params, function(err, data) {
        if (err) return res.json({
            "error": err
        })

        if (data.length > 1 && maxTweets > foundTweets) {

            var tweetID = countRT = countT = 0
            data.forEach(function(rawtweet) {
                if (rawtweet.retweeted_status) {
                    tweet = rawtweet.retweeted_status
                    countRT++
                } else {
                    tweet = rawtweet
                    countT++
                }
                corpus.tweets.push({
                    "date": tweet.created_at,
                    "tweet": tweet.text
                })
                tweetID = tweet.id
            });
            foundTweets = countRT + countT + foundTweets
            console.log(countRT + " retweets and " + countT + " tweets")
            getTweets(tweetID, "")

        } else {
            updateTweets(corpus)
        }
    })
}

function updateTweets(corpus) {

    console.log(corpus)
    res.json(corpus)

    var updateDate = {
        'screen_name': params.screen_name,
        'count': maxTweets,
        'content': JSON.stringify(corpus),
        'dateRequested': Date.now(),
        'maxid': 0,
        'mode': mode
    }

    replaceCache = function(acct, sn, data) {
        for (a in acct.streams) {
            if (acct.streams[a].screen_name == sn) {
                acct.streams.splice(a)
                acct.streams.push(data)
                return acct
            }
        }
        acct.streams.push(data)
        return acct
    }
    acct = replaceCache(acct, params.screen_name, updateDate)
    acct.save(function(err) {
        if (err) console.log(err)
        return true;
    })
}
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
var app = {
    // Application Constructor
    initialize: function() {
        this.bindEvents();

        this.insideRegion = false;
        this.lastUpdateDate = null;
        this.totalTimeInRegion = 0;
    },
    // Bind Event Listeners
    //
    // Bind any events that are required on startup. Common events are:
    // 'load', 'deviceready', 'offline', and 'online'.
    bindEvents: function() {
        document.addEventListener('deviceready', this.onDeviceReady, false);
    },
    // deviceready Event Handler
    //
    onDeviceReady: function() {
        // add click handle for reset button
        document.getElementById('reset').addEventListener('click', app.onResetClick, false);

        // setup timer to update the total time in region
        setInterval(app.updateTotalTimeInRegion, 1000);

        // setup the location manager
        app.setupLocationManager();

        // inital update to total time in region
        app.updateTotalTimeInRegion();
    },
    setupLocationManager: function() {
        var uuid = 'E2C56DB5-DFFB-48D2-B060-D0F5A71096E0';
        var identifier = 'region';
        var major = 1;
        var minor = 2;

        // create a beacon region to monitor
        var beaconRegion = new cordova.plugins.locationManager.BeaconRegion(identifier, uuid, major, minor);

        // create a delegate for the location manager
        var delegate = new cordova.plugins.locationManager.Delegate();
        delegate.didDetermineStateForRegion = app.didDetermineStateForRegion;

        // set the delegate on the location manager
        cordova.plugins.locationManager.setDelegate(delegate);

        // request authorization (needed for iOS 8 and above)
        cordova.plugins.locationManager.requestAlwaysAuthorization();

        // start monitoring beacon region
        cordova.plugins.locationManager.startMonitoringForRegion(beaconRegion)
            .fail(alert)
            .done();
    },
    didDetermineStateForRegion: function(pluginResult) {
        var regionState = pluginResult.state;

        if (regionState === 'CLRegionStateInside') {
            // we are inside the region
            app.insideRegion = true;
        } else {
            // we are outside the region
            app.insideRegion = false;
        }

        // update the total time in region
        app.updateTotalTimeInRegion();
    },
    onResetClick: function() {
        // clear the total time
        app.totalTimeInRegion = 0;

        // update the total time in region
        app.updateTotalTimeInRegion();
    },
    updateTotalTimeInRegion: function() {
        // get the date for now
        var now = new Date();

        if (app.insideRegion) {
            // we are inside the region, calculate the seconds since the last update
            var secondsSinceLastUpdate = (now.getTime() - app.lastUpdateDate.getTime()) / 1000.0;

            // update the total time
            app.totalTimeInRegion += secondsSinceLastUpdate;
        }

        // update the last update date to now
        app.lastUpdateDate = now;

        // display the total time
        app.displayTotalTimeInRegion();
    },
    displayTotalTimeInRegion: function() {
        // breakdown the total time to hours, minutes, seconds
        var hours = Math.floor(app.totalTimeInRegion / 3600);
        var minutes = Math.floor((app.totalTimeInRegion % 3600) / 60);
        var seconds = Math.floor(app.totalTimeInRegion % 60);

        // convert to a string to display
        var totalTimeInRegionText = 'Hours: ' + hours + ' ' +
                                    'Minutes: ' + minutes + ' ' +
                                    'Seconds: ' + seconds;

        document.getElementById('totalTimeInRegion').textContent = totalTimeInRegionText;
    }
};
<commit_msg>reorder a few things<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
var app = {
    // Application Constructor
    initialize: function() {
        this.bindEvents();

        this.insideRegion = false;
        this.lastUpdateDate = null;
        this.totalTimeInRegion = 0;
    },
    // Bind Event Listeners
    //
    // Bind any events that are required on startup. Common events are:
    // 'load', 'deviceready', 'offline', and 'online'.
    bindEvents: function() {
        document.addEventListener('deviceready', this.onDeviceReady, false);
    },
    // deviceready Event Handler
    //
    onDeviceReady: function() {
        // setup the location manager
        app.setupLocationManager();

        // setup timer to update the total time in region
        setInterval(app.updateTotalTimeInRegion, 1000);

        // inital update to total time in region
        app.updateTotalTimeInRegion();

        // add click handle for reset button
        document.getElementById('reset').addEventListener('click', app.onResetClick, false);
    },
    setupLocationManager: function() {
        var uuid = 'E2C56DB5-DFFB-48D2-B060-D0F5A71096E0';
        var identifier = 'region';
        var major = 1;
        var minor = 2;

        // create a beacon region to monitor
        var beaconRegion = new cordova.plugins.locationManager.BeaconRegion(identifier, uuid, major, minor);

        // create a delegate for the location manager
        var delegate = new cordova.plugins.locationManager.Delegate();
        delegate.didDetermineStateForRegion = app.didDetermineStateForRegion;

        // set the delegate on the location manager
        cordova.plugins.locationManager.setDelegate(delegate);

        // request authorization (needed for iOS 8 and above)
        cordova.plugins.locationManager.requestAlwaysAuthorization();

        // start monitoring beacon region
        cordova.plugins.locationManager.startMonitoringForRegion(beaconRegion)
            .fail(alert)
            .done();
    },
    didDetermineStateForRegion: function(pluginResult) {
        var regionState = pluginResult.state;

        if (regionState === 'CLRegionStateInside') {
            // we are inside the region
            app.insideRegion = true;
        } else {
            // we are outside the region
            app.insideRegion = false;
        }

        // update the total time in region
        app.updateTotalTimeInRegion();
    },
    updateTotalTimeInRegion: function() {
        // get the date for now
        var now = new Date();

        if (app.insideRegion) {
            // we are inside the region, calculate the seconds since the last update
            var secondsSinceLastUpdate = (now.getTime() - app.lastUpdateDate.getTime()) / 1000.0;

            // update the total time
            app.totalTimeInRegion += secondsSinceLastUpdate;
        }

        // update the last update date to now
        app.lastUpdateDate = now;

        // display the total time
        app.displayTotalTimeInRegion();
    },
    displayTotalTimeInRegion: function() {
        // breakdown the total time to hours, minutes, seconds
        var hours = Math.floor(app.totalTimeInRegion / 3600);
        var minutes = Math.floor((app.totalTimeInRegion % 3600) / 60);
        var seconds = Math.floor(app.totalTimeInRegion % 60);

        // convert to a string to display
        var totalTimeInRegionText = 'Hours: ' + hours + ' ' +
                                    'Minutes: ' + minutes + ' ' +
                                    'Seconds: ' + seconds;

        document.getElementById('totalTimeInRegion').textContent = totalTimeInRegionText;
    },
    onResetClick: function() {
        // clear the total time
        app.totalTimeInRegion = 0;

        // update the total time in region
        app.updateTotalTimeInRegion();
    }
};
<|endoftext|>


<commit_before>import http from 'http';
import https from 'https';

import _ from 'underscore';

import { settings } from '../../../settings';
import { FileUploadClass, FileUpload } from '../lib/FileUpload';
import '../../ufs/AmazonS3/server.js';

const get = function(file, req, res) {
	const forceDownload = typeof req.query.download !== 'undefined';
	const fileUrl = this.store.getRedirectURL(file, forceDownload);

	if (!fileUrl) {
		return res.end();
	}

	const storeType = file.store.split(':').pop();
	if (settings.get(`FileUpload_S3_Proxy_${ storeType }`)) {
		const request = /^https:/.test(fileUrl) ? https : http;

		return FileUpload.proxyFile(file.name, fileUrl, forceDownload, request, req, res);
	}

	return FileUpload.redirectToFile(fileUrl, req, res);
};

const copy = function(file, out) {
	const fileUrl = this.store.getRedirectURL(file);

	if (fileUrl) {
		const request = /^https:/.test(fileUrl) ? https : http;
		request.get(fileUrl, (fileRes) => fileRes.pipe(out));
	} else {
		out.end();
	}
};

const AmazonS3Uploads = new FileUploadClass({
	name: 'AmazonS3:Uploads',
	get,
	copy,
	// store setted bellow
});

const AmazonS3Avatars = new FileUploadClass({
	name: 'AmazonS3:Avatars',
	get,
	copy,
	// store setted bellow
});

const AmazonS3UserDataFiles = new FileUploadClass({
	name: 'AmazonS3:UserDataFiles',
	get,
	copy,
	// store setted bellow
});

const configure = _.debounce(function() {
	const Bucket = settings.get('FileUpload_S3_Bucket');
	const Acl = settings.get('FileUpload_S3_Acl');
	const AWSAccessKeyId = settings.get('FileUpload_S3_AWSAccessKeyId');
	const AWSSecretAccessKey = settings.get('FileUpload_S3_AWSSecretAccessKey');
	const URLExpiryTimeSpan = settings.get('FileUpload_S3_URLExpiryTimeSpan');
	const Region = settings.get('FileUpload_S3_Region');
	const SignatureVersion = settings.get('FileUpload_S3_SignatureVersion');
	const ForcePathStyle = settings.get('FileUpload_S3_ForcePathStyle');
	// const CDN = RocketChat.settings.get('FileUpload_S3_CDN');
	const BucketURL = settings.get('FileUpload_S3_BucketURL');

	if (!Bucket) {
		return;
	}

	const config = {
		connection: {
			signatureVersion: SignatureVersion,
			s3ForcePathStyle: ForcePathStyle,
			params: {
				Bucket,
				ACL: Acl,
			},
			region: Region,
		},
		URLExpiryTimeSpan,
	};

	if (AWSAccessKeyId) {
		config.connection.accessKeyId = AWSAccessKeyId;
	}

	if (AWSSecretAccessKey) {
		config.connection.secretAccessKey = AWSSecretAccessKey;
	}

	if (BucketURL) {
		config.connection.endpoint = BucketURL;
	}

	AmazonS3Uploads.store = FileUpload.configureUploadsStore('AmazonS3', AmazonS3Uploads.name, config);
	AmazonS3Avatars.store = FileUpload.configureUploadsStore('AmazonS3', AmazonS3Avatars.name, config);
	AmazonS3UserDataFiles.store = FileUpload.configureUploadsStore('AmazonS3', AmazonS3UserDataFiles.name, config);
}, 500);

settings.get(/^FileUpload_S3_/, configure);
<commit_msg>[FIX] Update AmazonS3 file upload with error handling and sync operation (#10372)<commit_after>import http from 'http';
import https from 'https';

import _ from 'underscore';

import { settings } from '../../../settings';
import { FileUploadClass, FileUpload } from '../lib/FileUpload';
import '../../ufs/AmazonS3/server.js';

const get = function(file, req, res) {
	const forceDownload = typeof req.query.download !== 'undefined';

	this.store.getRedirectURL(file, forceDownload, (err, fileUrl) => {
		if (err) {
			return console.error(err);
		}

		if (!fileUrl) {
			return res.end();
		}

		const storeType = file.store.split(':').pop();
		if (settings.get(`FileUpload_S3_Proxy_${ storeType }`)) {
			const request = /^https:/.test(fileUrl) ? https : http;

			return FileUpload.proxyFile(file.name, fileUrl, forceDownload, request, req, res);
		}

		return FileUpload.redirectToFile(fileUrl, req, res);
	});
};

const copy = function(file, out) {
	const fileUrl = this.store.getRedirectURL(file);

	if (fileUrl) {
		const request = /^https:/.test(fileUrl) ? https : http;
		request.get(fileUrl, (fileRes) => fileRes.pipe(out));
	} else {
		out.end();
	}
};

const AmazonS3Uploads = new FileUploadClass({
	name: 'AmazonS3:Uploads',
	get,
	copy,
	// store setted bellow
});

const AmazonS3Avatars = new FileUploadClass({
	name: 'AmazonS3:Avatars',
	get,
	copy,
	// store setted bellow
});

const AmazonS3UserDataFiles = new FileUploadClass({
	name: 'AmazonS3:UserDataFiles',
	get,
	copy,
	// store setted bellow
});

const configure = _.debounce(function() {
	const Bucket = settings.get('FileUpload_S3_Bucket');
	const Acl = settings.get('FileUpload_S3_Acl');
	const AWSAccessKeyId = settings.get('FileUpload_S3_AWSAccessKeyId');
	const AWSSecretAccessKey = settings.get('FileUpload_S3_AWSSecretAccessKey');
	const URLExpiryTimeSpan = settings.get('FileUpload_S3_URLExpiryTimeSpan');
	const Region = settings.get('FileUpload_S3_Region');
	const SignatureVersion = settings.get('FileUpload_S3_SignatureVersion');
	const ForcePathStyle = settings.get('FileUpload_S3_ForcePathStyle');
	// const CDN = RocketChat.settings.get('FileUpload_S3_CDN');
	const BucketURL = settings.get('FileUpload_S3_BucketURL');

	if (!Bucket) {
		return;
	}

	const config = {
		connection: {
			signatureVersion: SignatureVersion,
			s3ForcePathStyle: ForcePathStyle,
			params: {
				Bucket,
				ACL: Acl,
			},
			region: Region,
		},
		URLExpiryTimeSpan,
	};

	if (AWSAccessKeyId) {
		config.connection.accessKeyId = AWSAccessKeyId;
	}

	if (AWSSecretAccessKey) {
		config.connection.secretAccessKey = AWSSecretAccessKey;
	}

	if (BucketURL) {
		config.connection.endpoint = BucketURL;
	}

	AmazonS3Uploads.store = FileUpload.configureUploadsStore('AmazonS3', AmazonS3Uploads.name, config);
	AmazonS3Avatars.store = FileUpload.configureUploadsStore('AmazonS3', AmazonS3Avatars.name, config);
	AmazonS3UserDataFiles.store = FileUpload.configureUploadsStore('AmazonS3', AmazonS3UserDataFiles.name, config);
}, 500);

settings.get(/^FileUpload_S3_/, configure);
<|endoftext|>


<commit_before>import {
  BaseModel, field, identifier, hasMany, identifiedBy,
} from '../../base';
import { filter, includes, first } from 'lodash';
import { readonly } from 'core-decorators';
import { computed } from 'mobx';
import Term from './term';

@identifiedBy('offerings/offering')
export default class Offering extends BaseModel {

  @readonly static possibleTerms = [
    'winter', 'sprint', 'summer', 'fall',
  ];

  @identifier id;
  @field title;
  @field description;
  @field is_concept_coach;
  @field is_tutor;
  @field appearance_code;

  @hasMany({ model: Term }) active_term_years;

  @computed get validTerms() {
    if (this.is_concept_coach){
      return filter(this.active_term_years, (t) => t.year == 2017 && includes(['spring', 'summer'], t.term));
    }
    return this.active_term_years;
  }

  @computed get currentTerm() {
    return first(this.validTerms);
  }
}
<commit_msg>order terms correctly<commit_after>import {
  BaseModel, field, identifier, hasMany, identifiedBy,
} from '../../base';
import { filter, includes, first } from 'lodash';
import { readonly } from 'core-decorators';
import { computed } from 'mobx';
import Term from './term';

@identifiedBy('offerings/offering')
export default class Offering extends BaseModel {

  @readonly static possibleTerms = [
    'spring', 'summer', 'fall', 'winter',
  ];

  @identifier id;
  @field title;
  @field description;
  @field is_concept_coach;
  @field is_tutor;
  @field appearance_code;

  @hasMany({ model: Term }) active_term_years;

  @computed get validTerms() {
    if (this.is_concept_coach){
      return filter(this.active_term_years, (t) => t.year == 2017 && includes(['spring', 'summer'], t.term));
    }
    return this.active_term_years;
  }

  @computed get currentTerm() {
    return first(this.validTerms);
  }
}
<|endoftext|>


<commit_before>import Promise from 'bluebird'
import Immutable from 'immutable'
import {isUndefined} from 'lodash'

import {isTrue} from 'app/helpers/is'
import findResults from 'app/helpers/findResults'
import findWordForProgress from 'app/helpers/findWordForProgress'
import stoAreas from 'sto-areas'

let areas = Immutable.Map({
	// Degrees
	'd-ba': stoAreas.degree.bachelorOfArts,
	// 'd-bm': stoAreas.degree.bachelorOfMusic,

	// Majors
	'm-csci':  stoAreas.major.computerScience,
	'm-asian': stoAreas.major.asianStudies,
	'm-chem':  stoAreas.major.chemistry,
	'm-phys':  stoAreas.major.physics,
	'm-math':  stoAreas.major.mathematics,
	'm-esth':  stoAreas.major.exerciseScience,
	'm-engl':  stoAreas.major.english,

	// Concentrations
	'c-asian': stoAreas.concentration.asianStudies,
	'c-stat':  stoAreas.concentration.statistics,
	'c-chin':  stoAreas.concentration.chinaStudies,
	'c-japan': stoAreas.concentration.japanStudies,

	// Emphases
})

/**
 * Controls the 'no result' result from areas of study.
 *
 * @param {String} type
 * @param {String} title
 * @param {String} id
 * @returns {Object}
 */
let noResult = (type, title, id) => {
	return {
		id: id,
		title: title,
		result: false,
		progress: {at: 0, of: 1, word: 'zero'},
		type: type,
		details: [{
			title: `${type} not found!`,
			description: `This ${type} could not be found.`,
		}],
	}
}

/**
 * Checks a student object against an area of study.
 *
 * @param {Object} student
 * @param {Object} area
 * @promise ResultsPromise
 * @fulfill {Object} - The details of the area check.
 */
function checkStudentAgainstArea(student, area) {
	let title = area.title
	let type = area.type
	let id = area.id

	let areaChecker = areas.get(area.id)

	if (!areaChecker)
		return Promise.resolve(noResult(type, title, id))

	return areaChecker(student)
		.then((studentResults) => {
			let listOfResults = findResults(studentResults.details)

			let currentProgress = Immutable.List(listOfResults).filterNot(isUndefined).filter(isTrue).size
			let maxProgress = listOfResults.length
			let progressName = findWordForProgress(maxProgress, currentProgress)

			let progress = {at: currentProgress, of: maxProgress, word: progressName}

			let result = studentResults.result
			let details = studentResults.details

			return {id, title, type, progress, result, details}
		})
}

/**
 * Checks a student objects graduation possibilities against all of its areas of study.
 *
 * @param {Student} student
 * @promise GraduatabilityPromise
 * @fulfill {Object} - The details of the students graduation prospects.
 */
function checkStudentGraduatability(student) {
	let areaResults = student.studies.map((area) => checkStudentAgainstArea(student, area)).toArray()
	// console.log('areaResults', student.studies.toArray(), areaResults)

	return Promise.all(areaResults).then((areas) => {
		areas = Immutable.List(areas)
		let graduatability = (areas.map(a => a.result).filter(isTrue).size - areas.size) >= 1
		return {graduatability: graduatability, areaDetails: areas}
	})
}

export default checkStudentGraduatability
<commit_msg>Use array destructuring in checkStudentGraduatability<commit_after>import Promise from 'bluebird'
import Immutable from 'immutable'
import {isUndefined} from 'lodash'

import {isTrue} from 'app/helpers/is'
import findResults from 'app/helpers/findResults'
import findWordForProgress from 'app/helpers/findWordForProgress'
import stoAreas from 'sto-areas'

let areas = Immutable.Map({
	// Degrees
	'd-ba': stoAreas.degree.bachelorOfArts,
	// 'd-bm': stoAreas.degree.bachelorOfMusic,

	// Majors
	'm-csci':  stoAreas.major.computerScience,
	'm-asian': stoAreas.major.asianStudies,
	'm-chem':  stoAreas.major.chemistry,
	'm-phys':  stoAreas.major.physics,
	'm-math':  stoAreas.major.mathematics,
	'm-esth':  stoAreas.major.exerciseScience,
	'm-engl':  stoAreas.major.english,

	// Concentrations
	'c-asian': stoAreas.concentration.asianStudies,
	'c-stat':  stoAreas.concentration.statistics,
	'c-chin':  stoAreas.concentration.chinaStudies,
	'c-japan': stoAreas.concentration.japanStudies,

	// Emphases
})

/**
 * Controls the 'no result' result from areas of study.
 *
 * @param {String} type
 * @param {String} title
 * @param {String} id
 * @returns {Object}
 */
let noResult = (type, title, id) => {
	return {
		id: id,
		title: title,
		result: false,
		progress: {at: 0, of: 1, word: 'zero'},
		type: type,
		details: [{
			title: `${type} not found!`,
			description: `This ${type} could not be found.`,
		}],
	}
}

/**
 * Checks a student object against an area of study.
 *
 * @param {Object} student
 * @param {Object} area
 * @promise ResultsPromise
 * @fulfill {Object} - The details of the area check.
 */
function checkStudentAgainstArea(student, area) {
	let {title, type, id} = area

	let areaChecker = areas.get(area.id)

	if (!areaChecker)
		return Promise.resolve(noResult(type, title, id))

	return areaChecker(student)
		.then((studentResults) => {
			let listOfResults = findResults(studentResults.details)

			let currentProgress = Immutable.List(listOfResults).filterNot(isUndefined).filter(isTrue).size
			let maxProgress = listOfResults.length
			let progressName = findWordForProgress(maxProgress, currentProgress)

			let progress = {at: currentProgress, of: maxProgress, word: progressName}

			let result = studentResults.result
			let details = studentResults.details

			return {id, title, type, progress, result, details}
		})
}

/**
 * Checks a student objects graduation possibilities against all of its areas of study.
 *
 * @param {Student} student
 * @promise GraduatabilityPromise
 * @fulfill {Object} - The details of the students graduation prospects.
 */
function checkStudentGraduatability(student) {
	let areaResults = student.studies.map((area) => checkStudentAgainstArea(student, area)).toArray()
	// console.log('areaResults', student.studies.toArray(), areaResults)

	return Promise.all(areaResults).then((areas) => {
		areas = Immutable.List(areas)
		let graduatability = (areas.map(a => a.result).filter(isTrue).size - areas.size) >= 1
		return {graduatability: graduatability, areaDetails: areas}
	})
}

export default checkStudentGraduatability
<|endoftext|>


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';

class AdminCarusel extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            main_images: gon.global.main_images,
        }
        this.inputs = [];
    }

    openFileInput(i) {
        this.inputs[i].click();
    }

    generateHiddenInputs(formData) {
        const { form } = this.props;
        return <input
            type="file"
            name={`site[site_settings_attributes][4][image]`}
            value={formData}
            style={{opacity: 0, filter: 'alpha(opacity=0)', width: 0, overflow: 'hidden' }}
        />
    }

    renderInputs(image, i) {
        // XXX : warning, if backend changes the attributes for image, this needs to be changed
        // as of now each image gets appended after the 6th attribute
        const attributesOffset = 6;
        return (

 this.openFileInput(i) }>
                Select file

                    Recommended dimensions: 1280x500

                    Max. size: 1MB

                <input
                    ref={input => this.inputs.push(input)}
                    type="file"
                    name={`site[site_settings_attributes][${attributesOffset + i}][image]`}
                    accept="image/*"
                    data-type="background"
                    />

                    <input type="text" placeholder="image attribution" name={`site[site_settings_attributes][${attributesOffset + i}][attribution]`} />
                    <input type="text" placeholder="attribution link" name={`site[site_settings_attributes][${attributesOffset + i}][link]`} />

        )
    }

    render() {
        console.log(this);
        return (

Homepage cover image

You can select multiple images to make an carusel

                    {this.state.main_images.map((image, i) => this.renderInputs(image, i))}

        )
    }

}

export default AdminCarusel;

{/*

Homepage cover images

Add several images if you want a carousel.

    <%= settings_form.file_field :image, id: 'main', accept: 'image/*', 'data-type': 'background' %>
    <%= settings_form.label :image, value: 'Change homepage cover image', for: 'main', tabindex: '0' %>
    <% if settings_form.object.present? && settings_form.object.image_file_name %>
      <div class="preview -high js-preview" style="background-image: url('<%= settings_form.object.image.url %>');">

    <% else %>

        Select file

    <% end %>

        Recommended dimensions: 1280x500

        Max. size: 1MB

        <%= settings_form.text_field :attribution_label, placeholder: 'Add an attribution label to the image' %>
        <%= settings_form.text_field :attribution_link, placeholder: 'Add an attribution link to the image' %>

 */}
<commit_msg>filter images and have an empty one as default<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';

class AdminCarusel extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            main_images: [ ...gon.global.main_images.filter(i => i.value && i.value.length > 0), {} ],
        }
        this.inputs = [];
    }

    openFileInput(i) {
        this.inputs[i].click();
    }

    generateHiddenInputs(formData) {
        const { form } = this.props;
        return <input
            type="file"
            name={`site[site_settings_attributes][4][image]`}
            value={formData}
            style={{opacity: 0, filter: 'alpha(opacity=0)', width: 0, overflow: 'hidden' }}
        />
    }

    renderInputs(image, i) {
        // XXX : warning, if backend changes the attributes for image, this needs to be changed
        // as of now each image gets appended after the 6th attribute
        const attributesOffset = 6;
        return (

 this.openFileInput(i) }>
                Select file

                    Recommended dimensions: 1280x500

                    Max. size: 1MB

                <input
                    ref={input => this.inputs.push(input)}
                    type="file"
                    name={`site[site_settings_attributes][${attributesOffset + i}][image]`}
                    accept="image/*"
                    data-type="background"
                    />

                    <input type="text" placeholder="image attribution" name={`site[site_settings_attributes][${attributesOffset + i}][attribution]`} />
                    <input type="text" placeholder="attribution link" name={`site[site_settings_attributes][${attributesOffset + i}][link]`} />

        )
    }

    render() {
        console.log(this);
        return (

Homepage cover image

You can select multiple images to make an carusel

                    {this.state.main_images.map((image, i) => this.renderInputs(image, i))}

        )
    }

}

export default AdminCarusel;
<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
	Schema = mongoose.Schema;

	/**
 * A Validation function for local strategy properties
 */
var validateLocalStrategyProperty = function(property) {
	return ((this.provider !== 'local' && !this.updated) || property.length>0);
};

var CandidateSchema = new Schema({
	fName: {
		type: String,
		trim: true,
		default: '',
		validate: [validateLocalStrategyProperty, 'Please fill in your first name']
	},
	lName: {
		type: String,
		trim: true,
		default: '',
		validate: [validateLocalStrategyProperty, 'Please fill in your last name']
	},
	email: {
		type: String,
		unique: 'Email is already associated with a candidate',
		trim: true,
		default: '',
		validate: [validateLocalStrategyProperty, 'Please fill in your email'],
		match: [/.+\@.+\..+/, 'Please fill a valid email address']
	},
	status: {
		type: String,
		enum: ['volunteer','invited','accepted'],
		default: 'volunteer'
		trim: true
	},
	events: {
		type: [{
			eventsID: {type: Objectid}
			accepted: {type: Boolean, default: 'false'}
		}]

	},
	accept_key: {
		type: string,
		default: 'false'
	},
	note: {
		type: string,
		default: ''
	}

});

CandidateSchema.CreateAcceptKey = function() {
	        var chars =
"01@2345$6789-ABCDEF+GHIJK=LMNO*PQRSTU#VWXT+Zabcdefghiklmnopqrstuvwxyz";
        var randomstring = '';
        var string_length = 100;
        for (var i=0; i<string_length; i++) {
                var rnum = Math.floor(Math.random() * chars.length);
                randomstring += chars.substring(rnum,rnum+1);
        }
        return randomstring;

};

mongoose.model('Candidate', CandidateSchema);<commit_msg>bug fix in candidate<commit_after>'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
	Schema = mongoose.Schema;

	/**
 * A Validation function for local strategy properties
 */
var validateLocalStrategyProperty = function(property) {
	return ((this.provider !== 'local' && !this.updated) || property.length>0);
};

var CandidateSchema = new Schema({
	fName: {
		type: String,
		trim: true,
		default: '',
		validate: [validateLocalStrategyProperty, 'Please fill in your first name']
	},
	lName: {
		type: String,
		trim: true,
		default: '',
		validate: [validateLocalStrategyProperty, 'Please fill in your last name']
	},
	email: {
		type: String,
		unique: 'Email is already associated with a candidate',
		trim: true,
		default: '',
		validate: [validateLocalStrategyProperty, 'Please fill in your email'],
		match: [/.+\@.+\..+/, 'Please fill a valid email address']
	},
	status: {
		type: String,
		enum: ['volunteer','invited','accepted'],
		default: 'volunteer'
	},
	events: {
		type: [{
			eventsID: {type: Objectid}
			accepted: {type: Boolean, default: 'false'}
		}]

	},
	accept_key: {
		type: string,
		default: 'false'
	},
	note: {
		type: string,
		default: ''
	}

});

CandidateSchema.CreateAcceptKey = function() {
	        var chars =
"01@2345$6789-ABCDEF+GHIJK=LMNO*PQRSTU#VWXT+Zabcdefghiklmnopqrstuvwxyz";
        var randomstring = '';
        var string_length = 100;
        for (var i=0; i<string_length; i++) {
                var rnum = Math.floor(Math.random() * chars.length);
                randomstring += chars.substring(rnum,rnum+1);
        }
        return randomstring;

};

mongoose.model('Candidate', CandidateSchema);<|endoftext|>


<commit_before>/**
 * @name:      PyHouse/src/Modules/Web/js/mqtt.js
 * @author:    D. Brian Kimmel
 * @contact:   D.BrianKimmel@gmail.com
 * @copyright: (c) 2015-2015 by D. Brian Kimmel
 * @license:   MIT License
 * @note:      Created on June 18, 2015
 * @summary:   Displays the Mqtt element
 *
 */

helpers.Widget.subclass(mqtt, 'MqttWidget').methods(

	function __init__(self, node) {
		mqtt.MqttWidget.upcall(self, '__init__', node);
	},

// ============================================================================
	/**
     * Place the widget in the workspace.
	 *
	 * @param self is    <"Instance" of undefined.mqtt.MqttWidget>
	 * @returns a deferred
	 */
	function ready(self) {
		function cb_widgetready(res) {
			self.hideWidget();
		}
		function eb_widgetready(p_reason) {
			Divmod.debug('---', 'ERROR - mqtt.eb_widgetready() - ' + p_reason);
		}
		var uris = collectIMG_src(self.node, null);
		var l_defer = loadImages(uris);
		l_defer.addCallback(cb_widgetready);
		l_defer.addErrback(eb_widgetready);
		return l_defer;
	},
	function startWidget(self) {
		self.node.style.display = 'block';
		showSelectionButtons(self);
		self.fetchDataFromServer();
	},

// ============================================================================
	/**
	 * This triggers getting the data from the server.
	 */
	function fetchDataFromServer(self) {
		function cb_fetchDataFromServer(p_json) {
			globals.Computer = JSON.parse(p_json);
			console.log("mqtt.fetchDataFromServer() - Computer = %O", globals.Computer);
			self.buildLcarSelectScreen();
		}
		function eb_fetchDataFromServer(p_result) {
			Divmod.debug('---', 'mqtt.eb_fetchDataFromServer() was called. ERROR = ' + p_result);
		}
        var l_defer = self.callRemote("getServerData");  // @ web_mqtt.py
		l_defer.addCallback(cb_fetchDataFromServer);
		l_defer.addErrback(eb_fetchDataFromServer);
        return false;
	},
	/**
	 * Build a screen full of buttons - One for each broker and some actions.
	 */
	function buildLcarSelectScreen(self){
		var l_button_html = buildLcarSelectionButtonsTable(globals.Computer.Mqtt.Brokers, 'handleMenuOnClick');
		var l_html = build_lcars_top('Mqtt', 'lcars-salmon-color');
		l_html += build_lcars_middle_menu(15, l_button_html);
		l_html += build_lcars_bottom();
		self.nodeById('SelectionButtonsDiv').innerHTML = l_html;
	},
	/**
	 * Event handler for selection buttons.
	 *
	 * The user can click on a selection button, the "Add" button or the "Back" button.
	 *
	 * @param self is    <"Instance" of undefined.mqtt.MqttWidget>
	 * @param p_mqtt is  the node of the button that was clicked.
	 */
	function handleMenuOnClick(self, p_mqtt) {
		var l_ix = p_mqtt.name;
		var l_name = p_mqtt.value;
		globals.Computer.MqttIx = l_ix;
		globals.Computer.MqttName = l_name;
		if (l_ix <= 1000) {  // One of the mqtt buttons.
			var l_obj = globals.Computer.Mqtt.Brokers[l_ix];
			globals.Computer.MqttObj = l_obj;
			showDataEntryFields(self);
			self.buildLcarDataEntryScreen(l_obj, 'handleDataEntryOnClick');
		} else if (l_ix == 10001) {  // The "Add" button
			showDataEntryFields(self);
			var l_entry = self.createEntry();
			self.buildLcarDataEntryScreen(l_entry, 'handleDataEntryOnClick');
		} else if (l_ix == 10002) {  // The "Back" button
			self.showWidget('ComputerMenu');
		}
	},

// ============================================================================
	/**
	 * Build a screen full of data entry fields.
	 */
	function buildLcarDataEntryScreen(self, p_entry, p_handler){
		var l_obj = arguments[1];
		var l_html = build_lcars_top('Mqtt Data', 'lcars-salmon-color');
		l_html += build_lcars_middle_menu(20, self.buildEntry(l_obj, p_handler));
		l_html += build_lcars_bottom();
		self.nodeById('DataEntryDiv').innerHTML = l_html;
	},
	function buildEntry(self, p_obj, p_handler, p_onchange) {
		var l_html = buildBaseEntry(self, p_obj);
		l_html = self.buildMqttEntry(p_obj, l_html);
		l_html += buildLcarEntryButtons(p_handler);
		return l_html;
	},
    function buildMqttEntry(self, p_obj, p_html) {
		p_html += buildLcarTextWidget(self, 'Addr', 'Broker Address', p_obj.BrokerAddress);
		p_html += buildLcarTextWidget(self, 'Port', 'Port', p_obj.BrokerPort);
        return p_html;
    },
	function fetchEntry(self) {
    	var l_data = fetchBaseEntry(self, l_data);
		l_data = self.fetchMqttEntry(l_data);
       return l_data;
	},
    function fetchMqttEntry(self, p_data) {
        p_data.BrokerAddress = fetchTextWidget(self, 'Addr');
        p_data.BrokerPort = fetchTextWidget(self, 'Port');
    	return p_data;
    },
    function createEntry(self) {
    	var l_ix = 0;
    	try {
    		l_ix = Object.keys(globals.Computer.Mqtt.Brokers).length);
    	}
    	catch(e_err) {
    		l_ix = 0;
    	}
        var l_data = createBaseEntry(self, l_ix);
        l_data = self.createMqttEntry(l_data);
        return l_data;
    },
    function createMqttEntry(self, p_data) {
		p_data.BrokerAddress = '';
		p_data.BrokerPort = '1883';
        return p_data;
    },

// ============================================================================
	/**
	 * Event handler for mqtt buttons at bottom of entry portion of this widget.
	 * Get the possibly changed data and send it to the server.
	 *
	 * @param self is   <"Instance" of undefined.mqtt.MqttWidget>
	 * @param p_node is the button node that was clicked on
	 */
	function handleDataEntryOnClick(self, p_node) {
		function cb_handleDataEntryOnClick(p_json) {
			self.startWidget();
		}
		function eb_handleDataEntryOnClick(p_reason){
			Divmod.debug('---', 'mqtt.eb_handleDataEntryOnClick() was called. ERROR =' + p_reason);
		}
		var l_ix = p_node.name;
		var l_defer;
		var l_json;
		switch(l_ix) {
		case '10003':  // Change Button
	    	l_json = JSON.stringify(self.fetchEntry());
	        l_defer = self.callRemote("saveMqttData", l_json);  // @ web_schedule
			l_defer.addCallback(cb_handleDataEntryOnClick);
			l_defer.addErrback(eb_handleDataEntryOnClick);
			break;
		case '10002':  // Back button
			showSelectionButtons(self);
			break;
		case '10004':  // Delete button
			var l_obj = self.fetchEntry();
			l_obj.Delete = true;
	    	l_json = JSON.stringify(l_obj);
	        l_defer = self.callRemote("saveMqttData", l_json);  // @ web_rooms
			l_defer.addCallback(cb_handleDataEntryOnClick);
			l_defer.addErrback(eb_handleDataEntryOnClick);
			break;
		default:
			Divmod.debug('---', 'mqtt.handleDataEntryOnClick(Default) was called. l_ix:' + l_ix);
			break;
		}
		// return false stops the resetting of the server.
        return false;
	}
);
// Divmod.debug('---', 'mqtt.handleMenuOnClick(1) was called. ' + l_ix + ' ' + l_name);
// console.log("mqtt.handleMenuOnClick() - l_obj = %O", l_obj);
// ### END DBK
<commit_msg>Fix typo<commit_after>/**
 * @name:      PyHouse/src/Modules/Web/js/mqtt.js
 * @author:    D. Brian Kimmel
 * @contact:   D.BrianKimmel@gmail.com
 * @copyright: (c) 2015-2015 by D. Brian Kimmel
 * @license:   MIT License
 * @note:      Created on June 18, 2015
 * @summary:   Displays the Mqtt element
 *
 */

helpers.Widget.subclass(mqtt, 'MqttWidget').methods(

	function __init__(self, node) {
		mqtt.MqttWidget.upcall(self, '__init__', node);
	},

// ============================================================================
	/**
     * Place the widget in the workspace.
	 *
	 * @param self is    <"Instance" of undefined.mqtt.MqttWidget>
	 * @returns a deferred
	 */
	function ready(self) {
		function cb_widgetready(res) {
			self.hideWidget();
		}
		function eb_widgetready(p_reason) {
			Divmod.debug('---', 'ERROR - mqtt.eb_widgetready() - ' + p_reason);
		}
		var uris = collectIMG_src(self.node, null);
		var l_defer = loadImages(uris);
		l_defer.addCallback(cb_widgetready);
		l_defer.addErrback(eb_widgetready);
		return l_defer;
	},
	function startWidget(self) {
		self.node.style.display = 'block';
		showSelectionButtons(self);
		self.fetchDataFromServer();
	},

// ============================================================================
	/**
	 * This triggers getting the data from the server.
	 */
	function fetchDataFromServer(self) {
		function cb_fetchDataFromServer(p_json) {
			globals.Computer = JSON.parse(p_json);
			console.log("mqtt.fetchDataFromServer() - Computer = %O", globals.Computer);
			self.buildLcarSelectScreen();
		}
		function eb_fetchDataFromServer(p_result) {
			Divmod.debug('---', 'mqtt.eb_fetchDataFromServer() was called. ERROR = ' + p_result);
		}
        var l_defer = self.callRemote("getServerData");  // @ web_mqtt.py
		l_defer.addCallback(cb_fetchDataFromServer);
		l_defer.addErrback(eb_fetchDataFromServer);
        return false;
	},
	/**
	 * Build a screen full of buttons - One for each broker and some actions.
	 */
	function buildLcarSelectScreen(self){
		var l_button_html = buildLcarSelectionButtonsTable(globals.Computer.Mqtt.Brokers, 'handleMenuOnClick');
		var l_html = build_lcars_top('Mqtt', 'lcars-salmon-color');
		l_html += build_lcars_middle_menu(15, l_button_html);
		l_html += build_lcars_bottom();
		self.nodeById('SelectionButtonsDiv').innerHTML = l_html;
	},
	/**
	 * Event handler for selection buttons.
	 *
	 * The user can click on a selection button, the "Add" button or the "Back" button.
	 *
	 * @param self is    <"Instance" of undefined.mqtt.MqttWidget>
	 * @param p_mqtt is  the node of the button that was clicked.
	 */
	function handleMenuOnClick(self, p_mqtt) {
		var l_ix = p_mqtt.name;
		var l_name = p_mqtt.value;
		globals.Computer.MqttIx = l_ix;
		globals.Computer.MqttName = l_name;
		if (l_ix <= 1000) {  // One of the mqtt buttons.
			var l_obj = globals.Computer.Mqtt.Brokers[l_ix];
			globals.Computer.MqttObj = l_obj;
			showDataEntryFields(self);
			self.buildLcarDataEntryScreen(l_obj, 'handleDataEntryOnClick');
		} else if (l_ix == 10001) {  // The "Add" button
			showDataEntryFields(self);
			var l_entry = self.createEntry();
			self.buildLcarDataEntryScreen(l_entry, 'handleDataEntryOnClick');
		} else if (l_ix == 10002) {  // The "Back" button
			self.showWidget('ComputerMenu');
		}
	},

// ============================================================================
	/**
	 * Build a screen full of data entry fields.
	 */
	function buildLcarDataEntryScreen(self, p_entry, p_handler){
		var l_obj = arguments[1];
		var l_html = build_lcars_top('Mqtt Data', 'lcars-salmon-color');
		l_html += build_lcars_middle_menu(20, self.buildEntry(l_obj, p_handler));
		l_html += build_lcars_bottom();
		self.nodeById('DataEntryDiv').innerHTML = l_html;
	},
	function buildEntry(self, p_obj, p_handler, p_onchange) {
		var l_html = buildBaseEntry(self, p_obj);
		l_html = self.buildMqttEntry(p_obj, l_html);
		l_html += buildLcarEntryButtons(p_handler);
		return l_html;
	},
    function buildMqttEntry(self, p_obj, p_html) {
		p_html += buildLcarTextWidget(self, 'Addr', 'Broker Address', p_obj.BrokerAddress);
		p_html += buildLcarTextWidget(self, 'Port', 'Port', p_obj.BrokerPort);
        return p_html;
    },
	function fetchEntry(self) {
    	var l_data = fetchBaseEntry(self, l_data);
		l_data = self.fetchMqttEntry(l_data);
       return l_data;
	},
    function fetchMqttEntry(self, p_data) {
        p_data.BrokerAddress = fetchTextWidget(self, 'Addr');
        p_data.BrokerPort = fetchTextWidget(self, 'Port');
    	return p_data;
    },
    function createEntry(self) {
    	var l_ix = 0;
    	try {
    		l_ix = Object.keys(globals.Computer.Mqtt.Brokers).length;
    	}
    	catch(e_err) {
    		l_ix = 0;
    	}
        var l_data = createBaseEntry(self, l_ix);
        l_data = self.createMqttEntry(l_data);
        return l_data;
    },
    function createMqttEntry(self, p_data) {
		p_data.BrokerAddress = '';
		p_data.BrokerPort = '1883';
        return p_data;
    },

// ============================================================================
	/**
	 * Event handler for mqtt buttons at bottom of entry portion of this widget.
	 * Get the possibly changed data and send it to the server.
	 *
	 * @param self is   <"Instance" of undefined.mqtt.MqttWidget>
	 * @param p_node is the button node that was clicked on
	 */
	function handleDataEntryOnClick(self, p_node) {
		function cb_handleDataEntryOnClick(p_json) {
			self.startWidget();
		}
		function eb_handleDataEntryOnClick(p_reason){
			Divmod.debug('---', 'mqtt.eb_handleDataEntryOnClick() was called. ERROR =' + p_reason);
		}
		var l_ix = p_node.name;
		var l_defer;
		var l_json;
		switch(l_ix) {
		case '10003':  // Change Button
	    	l_json = JSON.stringify(self.fetchEntry());
	        l_defer = self.callRemote("saveMqttData", l_json);  // @ web_schedule
			l_defer.addCallback(cb_handleDataEntryOnClick);
			l_defer.addErrback(eb_handleDataEntryOnClick);
			break;
		case '10002':  // Back button
			showSelectionButtons(self);
			break;
		case '10004':  // Delete button
			var l_obj = self.fetchEntry();
			l_obj.Delete = true;
	    	l_json = JSON.stringify(l_obj);
	        l_defer = self.callRemote("saveMqttData", l_json);  // @ web_rooms
			l_defer.addCallback(cb_handleDataEntryOnClick);
			l_defer.addErrback(eb_handleDataEntryOnClick);
			break;
		default:
			Divmod.debug('---', 'mqtt.handleDataEntryOnClick(Default) was called. l_ix:' + l_ix);
			break;
		}
		// return false stops the resetting of the server.
        return false;
	}
);
// Divmod.debug('---', 'mqtt.handleMenuOnClick(1) was called. ' + l_ix + ' ' + l_name);
// console.log("mqtt.handleMenuOnClick() - l_obj = %O", l_obj);
// ### END DBK
<|endoftext|>


<commit_before>angular.module('thumbsCheckApp')
  .controller('QuizCtrl', function($scope, $firebaseObject, $firebaseArray, Ref, $rootScope, $location, user, broadcastInstructorRole) {
    // To get userID.role from web browser localStorage
    if (localStorage.getItem(user.uid) !== 'instructor') {
      $location.path('/student-main');
    } else {
      // Broadcast role to navbar.js controller
      broadcastInstructorRole.broadcast('instructor');
    }

    /*Quiz*/
    $scope.choices = [];
    var quizesRef = Ref.child('quizes');
    var quizes = $firebaseArray(quizesRef);
    $scope.quizes = quizes;

    $scope.add = function() {
      $scope.choices.push('');
    };

    $scope.remove = function(index) {
      console.log(index);
      $scope.choices.splice(index, 1);
    };

    $scope.addQuiz = function(question, choices) {
      var quiz = {};

      quiz.question = question;
      quiz.choices = choices;
      console.log(quiz);
      quizes.$add(quiz);

      // clear form
      $scope.question = '';
      $scope.choices = [];
    };

    $scope.saveChange = function($index, choice) {
      // saves user input into $scope.choices based on ng-Change
      $scope.choices[$index] = choice;
    };

    /*Accordion*/
    // quiz trigger
    var triggerRef = Ref.child('quizTrigger');
    $scope.quizTrigger = $firebaseObject(triggerRef);

    // Show only one quiz at a time
    $scope.oneAtATime = true;
    $scope.pushQuiz = function(quiz) {
      // console.log('clicked', quiz);
      var newQuizRef = Ref.child('newQuiz');
      var newQuizObj = $firebaseObject(newQuizRef);
      newQuizObj.quiz = quiz;
      newQuizObj.$save();

      // Remove the quizResponses table
      $firebaseObject(Ref.child('quizResponses')).$remove();

      // Initlize variables for $scope.total()
      $scope.numberOfChoice = quiz.choices.length;
      $scope.quizData = quiz;
      $scope.stacked = [];
    };

    // Quiz Response
    var quizResponsesRef = Ref.child('quizResponses');
    var quizResponsesObj = $firebaseObject(quizResponsesRef);
    $scope.quizResponses = quizResponsesObj;
    // watch firebase responses, upon change, update counts and studentList
    quizResponsesObj.$loaded().then(function() {
      quizResponsesObj.$watch(function() {
        // console.log('watch');
        results = $scope.total();
        // $scope.quizResult = results[0];
        // $scope.studentList = results[1];
      });
    });

    // calculate total votes for each category into result
    // Populate list of students githubID for each catergory into studentList
    $scope.total = function() {
      // Initialize quizCounts and studentList
      var quizCounts = [];
      var studentList = {};
      for (var i = 0; i < $scope.numberOfChoice; i++) {
        quizCounts.push(0);
        studentList[i] = [];
      }
      // console.log('result initial',quizCounts);
      // console.log('studentList', studentList);

      // for input of $scope.pickRandom()
      // console.log('studentList',studentList);
      quizResponsesObj.$loaded().then(function(responses) {
        // console.log('responses:', responses);

        // Make key: $id and $priority non-enumerable
        Object.defineProperty(responses, '$id', {
          enumerable: false
        });
        Object.defineProperty(responses, '$priority', {
          enumerable: false
        });
        Object.defineProperty(responses, '$$conf', {
          enumerable: false
        });

        for (var key in responses) {
          if (responses.hasOwnProperty(key)) {
            // console.log('key',key);
            var response = responses[key][key];
            // console.log('choice index', response);
            // console.log('type',typeof response);
            quizCounts[response] += 1;
            studentList[response].push(key);
          }
        }

        // debugger;
        $scope.populateProgressBar(quizCounts);
        $scope.studentList = studentList;
        // console.log('quizCounts before return', quizCounts);
        // console.log('studentList', studentList);
      });
    };

    $scope.pickRandom = function(array) {
      var randomStudentInfo;
      randomStudentInfo = pickRandomService.pickRandomStudent(studentList);

      var studentRef = Ref.child('students');
      // Retrieve studentName from firebase "students", then generate the pickedStudent object

      $firebaseObject(studentRef).$loaded().then(function(students) {
        $scope.studentName = students[randomStudentInfo.uid];
        $scope.pickedStudent = {
          name: students[randomStudentInfo.uid],
          imageUrl: randomStudentInfo.path
        };
      });
    };

    $scope.populateProgressBar = function(quizResult) {
      // if($scope.quizCounts){return;}
      $scope.stacked = [];
      var types = ['success', 'info', 'warning', 'danger'];
      // $scope.quizResult = [2,50,50];
      // quizResult
      // console.log('quizResult progress', quizResult);
      var quizCountsTotal = quizResult.reduce(function(memo, x) {
        return memo + x;
      });

      // console.log('counts total',quizCountsTotal);

      quizResult.forEach(function(val, i) {
        var percent = Math.floor((val / quizCountsTotal) * 100);
        var type = types[i];
        $scope.stacked.push({
          value: percent,
          type: type,
          choice: $scope.quizData.choices[i]
        });
      });
    };

  });
<commit_msg>refactor<commit_after>angular.module('thumbsCheckApp')
  .controller('QuizCtrl', function($scope, $firebaseObject, $firebaseArray, Ref, user, verifyInstructorService) {
    // To get userID.role from web browser localStorage
    //if (localStorage.getItem(user.uid) !== 'instructor') {
    //  $location.path('/student-main');
    //} else {
    //  // Broadcast role to navbar.js controller
    //  broadcastInstructorRole.broadcast('instructor');
    //}
    verifyInstructorService.verifyIfInstructor(user.uid);

    /*Quiz*/
    $scope.choices = [];
    var quizesRef = Ref.child('quizes');
    var quizes = $firebaseArray(quizesRef);
    $scope.quizes = quizes;

    $scope.add = function() {
      $scope.choices.push('');
    };

    $scope.remove = function(index) {
      console.log(index);
      $scope.choices.splice(index, 1);
    };

    $scope.addQuiz = function(question, choices) {
      var quiz = {};

      quiz.question = question;
      quiz.choices = choices;
      console.log(quiz);
      quizes.$add(quiz);

      // clear form
      $scope.question = '';
      $scope.choices = [];
    };

    $scope.saveChange = function($index, choice) {
      // saves user input into $scope.choices based on ng-Change
      $scope.choices[$index] = choice;
    };

    /*Accordion*/
    // quiz trigger
    var triggerRef = Ref.child('quizTrigger');
    $scope.quizTrigger = $firebaseObject(triggerRef);

    // Show only one quiz at a time
    $scope.oneAtATime = true;
    $scope.pushQuiz = function(quiz) {
      // console.log('clicked', quiz);
      var newQuizRef = Ref.child('newQuiz');
      var newQuizObj = $firebaseObject(newQuizRef);
      newQuizObj.quiz = quiz;
      newQuizObj.$save();

      // Remove the quizResponses table
      $firebaseObject(Ref.child('quizResponses')).$remove();

      // Initlize variables for $scope.total()
      $scope.numberOfChoice = quiz.choices.length;
      $scope.quizData = quiz;
      $scope.stacked = [];
    };

    // Quiz Response
    var quizResponsesRef = Ref.child('quizResponses');
    var quizResponsesObj = $firebaseObject(quizResponsesRef);
    $scope.quizResponses = quizResponsesObj;
    // watch firebase responses, upon change, update counts and studentList
    quizResponsesObj.$loaded().then(function() {
      quizResponsesObj.$watch(function() {
        // console.log('watch');
        results = $scope.total();
        // $scope.quizResult = results[0];
        // $scope.studentList = results[1];
      });
    });

    // calculate total votes for each category into result
    // Populate list of students githubID for each catergory into studentList
    $scope.total = function() {
      // Initialize quizCounts and studentList
      var quizCounts = [];
      var studentList = {};
      for (var i = 0; i < $scope.numberOfChoice; i++) {
        quizCounts.push(0);
        studentList[i] = [];
      }
      // console.log('result initial',quizCounts);
      // console.log('studentList', studentList);

      // for input of $scope.pickRandom()
      // console.log('studentList',studentList);
      quizResponsesObj.$loaded().then(function(responses) {
        // console.log('responses:', responses);

        // Make key: $id and $priority non-enumerable
        Object.defineProperty(responses, '$id', {
          enumerable: false
        });
        Object.defineProperty(responses, '$priority', {
          enumerable: false
        });
        Object.defineProperty(responses, '$$conf', {
          enumerable: false
        });

        for (var key in responses) {
          if (responses.hasOwnProperty(key)) {
            // console.log('key',key);
            var response = responses[key][key];
            // console.log('choice index', response);
            // console.log('type',typeof response);
            quizCounts[response] += 1;
            studentList[response].push(key);
          }
        }

        // debugger;
        $scope.populateProgressBar(quizCounts);
        $scope.studentList = studentList;
        // console.log('quizCounts before return', quizCounts);
        // console.log('studentList', studentList);
      });
    };

    $scope.pickRandom = function(array) {
      var randomStudentInfo;
      randomStudentInfo = pickRandomService.pickRandomStudent(studentList);

      var studentRef = Ref.child('students');
      // Retrieve studentName from firebase "students", then generate the pickedStudent object

      $firebaseObject(studentRef).$loaded().then(function(students) {
        $scope.studentName = students[randomStudentInfo.uid];
        $scope.pickedStudent = {
          name: students[randomStudentInfo.uid],
          imageUrl: randomStudentInfo.path
        };
      });
    };

    $scope.populateProgressBar = function(quizResult) {
      // if($scope.quizCounts){return;}
      $scope.stacked = [];
      var types = ['success', 'info', 'warning', 'danger'];
      // $scope.quizResult = [2,50,50];
      // quizResult
      // console.log('quizResult progress', quizResult);
      var quizCountsTotal = quizResult.reduce(function(memo, x) {
        return memo + x;
      });

      // console.log('counts total',quizCountsTotal);

      quizResult.forEach(function(val, i) {
        var percent = Math.floor((val / quizCountsTotal) * 100);
        var type = types[i];
        $scope.stacked.push({
          value: percent,
          type: type,
          choice: $scope.quizData.choices[i]
        });
      });
    };

  });
<|endoftext|>