<commit_before>/*
 * Author: Tony Brix, http://tonybrix.info
 * License: MIT
 */

(function ($) {
	//modified from http://stackoverflow.com/a/12924488/806777
	var getRangeFromPoint = function (x, y) {
		var range = null;

		// First try ie way
		if (typeof document.body.createTextRange !== "undefined") {
			range = document.body.createTextRange();
			range.moveToPoint(x, y);
			range.select();
			range = window.getSelection().getRangeAt(0);
		} else if (typeof document.createRange !== "undefined") {
			// Try the standards-based way next
			if (document.caretPositionFromPoint) {
				var pos = document.caretPositionFromPoint(x, y);
				range = document.createRange();
				range.setStart(pos.offsetNode, pos.offset);
				range.collapse(true);
			}

			// Next, the WebKit way
			else if (document.caretRangeFromPoint) {
				range = document.caretRangeFromPoint(x, y);
			}
		}

		return range;
	};

	var getLastNode = function (childNodes) {
		for (var i = childNodes.length - 1; i >= 0; i--) {
			if (childNodes[i].childNodes.length > 0) {
				var lastNode = getLastNode(childNodes[i].childNodes);
				if (lastNode !== null) {
					return lastNode;
				} else {
					continue;
				}
			} else if (childNodes[i].data !== "") {
				return childNodes[i];
			}
		}
		return null;
	};

	//modified from http://stackoverflow.com/a/20398132/806777
	var insertTextAtCursor = function (text) {
		var sel = window.getSelection();

		//fix a bug that won't create a new line if there isn't a new line at the end of the text
		var textLastChar = text.substring(text.length - 1);
		var fulltext = $(this).text();
		var newLineNode = document.createTextNode("\n");
		var lastChar = null, lastNode = null;
		if (fulltext !== "") {
			lastChar = fulltext.substring(fulltext.length - 1);
			lastNode = getLastNode(this.childNodes);
		}
		var needsExtra = (textLastChar === "\n" && lastChar !== "\n" && (lastChar === null || (sel.anchorNode === lastNode && sel.anchorOffset === lastNode.length) || (sel.focusNode === lastNode && sel.focusOffset === lastNode.length)));

		//make the text replace selection
		var textNode = document.createTextNode(text);
		var range = sel.getRangeAt(0);
		range.deleteContents();
		//check if it needs an extra new line
		if (needsExtra) {
			range.insertNode(newLineNode);
		}
		range.insertNode(textNode);

		//create a new range
		range = document.createRange();
		range.setStartAfter(textNode);
		range.collapse(true);

		//make the cursor there
		sel.removeAllRanges();
		sel.addRange(range);
	};

	var addImgOnDrop = function (file, caretX, caretY) {
		//PENDING: make image resizable?
		//PENDING: set cursor: move; on img?
		var $this = $(this);
		var reader = new FileReader();

		reader.onload = function (event) {
			var image = new Image();
			image.onload = function () {
				//copy img to mouse position
				var sel = window.getSelection();
				var range = getRangeFromPoint(caretX, caretY);
				if (range !== null) {
					range.insertNode(this);

					//set cursor after
					range.collapse(false);
					sel.removeAllRanges();
					sel.addRange(range);
				} else if ($this.is(":focus")) {

					//add  after selection
					range = sel.getRangeAt(0);
					range.collapse(false);
					range.insertNode(this);

					//set cursor after
					range.collapse(false);
					sel.removeAllRanges();
					sel.addRange(range);
				} else {
					$this.append(this);
				}
			};
			image.onerror = function () {
				//PENDING: more verbose error message?
				alert("Not an image");
			};
			image.src = event.target.result;
		};
		reader.readAsDataURL(file);
	};

	//modified from http://stackoverflow.com/a/12244703/806777
	var selectAllText = function () {
		if (document.body.createTextRange) {
			var range = document.body.createTextRange();
			range.moveToElementText(this);
			range.select();
		} else if (window.getSelection) {
			var selection = window.getSelection();
			var range = document.createRange();
			range.selectNodeContents(this);
			selection.removeAllRanges();
			selection.addRange(range);
		}
	};

	var settings = {
		allowHTML: true,
		allowImg: true,
		pastePlainText: true
	};

	$.fn.toTextarea = function (options) {
		if (options === "destroy" || options === true) {
			return this.each(function () {
				delete this.value;
				$(this).css({
					border: "",
					"white-space": "",
					padding: ""
				}).prop({
					contentEditable: false
				}).off(".toTextarea").data({
					isTextarea: false
				});
			});
		} else if (options === "disable") {
			return this.css({
				"background-color": "#eee",
				color: "#555"
			}).prop({
				contentEditable: false
			}).data({
				disabled: true
			});
		} else if (options === "enable") {
			return this.css({
				"background-color": "",
				color: ""
			}).prop({
				contentEditable: true
			}).data({
				disabled: false
			});
		} else {
			if ($.isPlainObject(options)) {
				$.extend(settings, options);
			}
			return this.each(function () {
				var $this = $(this);
				var isTextarea = $this.data().isTextarea || false;
				if (!isTextarea) {
					if (this.hasOwnProperty("value")) {
						delete this.value;
					}
					Object.defineProperty(this, "value", {
						set: function (value) {
							this.innerHTML = value;
						},
						get: function () {
							return this.innerHTML;
						}
					});
					var allowHTML = settings.allowHTML;
					if (typeof settings.allowHTML === "function") {
						allowHTML = settings.allowHTML.call(this);
					}
					var allowImg = settings.allowImg;
					if (typeof settings.allowImg === "function") {
						allowImg = settings.allowImg.call(this);
					}
					var pastePlainText = settings.pastePlainText;
					if (typeof settings.pastePlainText === "function") {
						pastePlainText = settings.pastePlainText.call(this);
					}
					$this
							.css({
								border: "1px solid #aaa",
								"white-space": "pre-wrap",
								"word-wrap": "break-word",
								padding: "1px"
							})
							.prop({
								contentEditable: true
							})
							.data({
								isTextarea: true,
								disabled: false
							})
							.on("keypress.toTextarea", function (e) {
								if (!$(this).data().disabled && e.which === 13) {
									var newLine;
									newLine = "\n";
									insertTextAtCursor.call(this, newLine);
									e.preventDefault();
									return false;
								}
							})
							.on("select.toTextarea", function () {
								if (!$(this).data().disabled) {
									selectAllText.call(this);
								}
							});
					if (allowImg) {
						$this
								.on("drop.toTextarea", function (e) {
									if (!$(this).data().disabled && e.originalEvent.dataTransfer.files.length > 0) {
										for (var i = 0, length = e.originalEvent.dataTransfer.files.length; i < length; i++) {
											addImgOnDrop.call(this, e.originalEvent.dataTransfer.files[i], e.originalEvent.clientX, e.originalEvent.clientY);
										}
										e.preventDefault();
										$(this).trigger("input");
										return false;
									}
								})
								.on("dragover.toTextarea", function (e) {
									if (!$(this).data().disabled && e.originalEvent.dataTransfer.types.length > 0 && e.originalEvent.dataTransfer.types[0] === "Files") {
										e.preventDefault();
										return false;
									}
								});
					}
					if (!allowHTML) {
						$this.on("keydown.toTextarea", function (e) {
							if (!$(this).data().disabled && e.ctrlKey) {
								if (e.which in {66: 1, 73: 1}) {
									e.preventDefault();
									return false;
								}
							}
						});
					}
					if (!allowHTML || pastePlainText) {
						$this.on("paste.toTextarea", function (e) {
							if (!$(this).data().disabled) {
								var text = null;
								if (window.clipboardData) {
									text = window.clipboardData.getData("Text");
								} else if (e.originalEvent.clipboardData) {
									text = e.originalEvent.clipboardData.getData("text/plain");
								} else {
									return true;
								}
								insertTextAtCursor.call(this, text);
								e.preventDefault();
								$(this).trigger("input");
								return false;
							}
						});
					}
				}
			});
		}
	};
})(jQuery);
<commit_msg>added singleLine option, set default to no html<commit_after>/*
 * Author: Tony Brix, http://tonybrix.info
 * License: MIT
 */

(function ($) {
	//modified from http://stackoverflow.com/a/12924488/806777
	var getRangeFromPoint = function (x, y) {
		var range = null;

		// First try ie way
		if (typeof document.body.createTextRange !== "undefined") {
			range = document.body.createTextRange();
			range.moveToPoint(x, y);
			range.select();
			range = window.getSelection().getRangeAt(0);
		} else if (typeof document.createRange !== "undefined") {
			// Try the standards-based way next
			if (document.caretPositionFromPoint) {
				var pos = document.caretPositionFromPoint(x, y);
				range = document.createRange();
				range.setStart(pos.offsetNode, pos.offset);
				range.collapse(true);
			}

			// Next, the WebKit way
			else if (document.caretRangeFromPoint) {
				range = document.caretRangeFromPoint(x, y);
			}
		}

		return range;
	};

	var getLastNode = function (childNodes) {
		for (var i = childNodes.length - 1; i >= 0; i--) {
			if (childNodes[i].childNodes.length > 0) {
				var lastNode = getLastNode(childNodes[i].childNodes);
				if (lastNode !== null) {
					return lastNode;
				} else {
					continue;
				}
			} else if (childNodes[i].data !== "") {
				return childNodes[i];
			}
		}
		return null;
	};

	//modified from http://stackoverflow.com/a/20398132/806777
	var insertTextAtCursor = function (text, x, y) {
		var sel = window.getSelection();

		//fix a bug that won't create a new line if there isn't a new line at the end of the text
		var textLastChar = text.substring(text.length - 1);
		var fulltext = $(this).text();
		var newLineNode = document.createTextNode("\n");
		var lastChar = null, lastNode = null;
		if (fulltext !== "") {
			lastChar = fulltext.substring(fulltext.length - 1);
			lastNode = getLastNode(this.childNodes);
		}
		var needsExtra = (textLastChar === "\n" && lastChar !== "\n" && (lastChar === null || (sel.anchorNode === lastNode && sel.anchorOffset === lastNode.length) || (sel.focusNode === lastNode && sel.focusOffset === lastNode.length)));

		//make the text replace selection
		var textNode = document.createTextNode(text);
		var range = null;
		if (typeof x !== "undefined" && typeof y !== "undefined") {
			range = getRangeFromPoint(x, y);
		} else {
			range = sel.getRangeAt(0);
		}
		range.deleteContents();
		//check if it needs an extra new line
		if (needsExtra) {
			range.insertNode(newLineNode);
		}
		range.insertNode(textNode);

		//create a new range
		range = document.createRange();
		range.setStartAfter(textNode);
		range.collapse(true);

		//make the cursor there
		sel.removeAllRanges();
		sel.addRange(range);
	};

	var insertHTMLAtCursor = function (html, x, y) {
		var sel = window.getSelection();

		//make the text replace selection
		var temp = document.createElement("div");
		temp.innerHTML = html;
		var htmlNodes = temp.childNodes;
		var range = null;
		if (typeof x !== "undefined" && typeof y !== "undefined") {
			range = getRangeFromPoint(x, y);
		} else {
			range = sel.getRangeAt(0);
		}
		range.deleteContents();
		//insert all child nodes
		var lastNode = null;
		for (var i = 0; i < htmlNodes.length; i++) {
			lastNode = htmlNodes[i];
			range.insertNode(lastNode);
		}

		//create a new range
		range = document.createRange();
		range.setStartAfter(lastNode);
		range.collapse(true);

		//make the cursor there
		sel.removeAllRanges();
		sel.addRange(range);
	};

	var addImgOnDrop = function (file, caretX, caretY) {
		//PENDING: make image resizable?
		//PENDING: set cursor: move; on img?
		var $this = $(this);
		var reader = new FileReader();

		reader.onload = function (event) {
			var image = new Image();
			image.onload = function () {
				//copy img to mouse position
				var sel = window.getSelection();
				var range = getRangeFromPoint(caretX, caretY);
				if (range !== null) {
					range.insertNode(this);

					//set cursor after
					range.collapse(false);
					sel.removeAllRanges();
					sel.addRange(range);
				} else if ($this.is(":focus")) {

					//add  after selection
					range = sel.getRangeAt(0);
					range.collapse(false);
					range.insertNode(this);

					//set cursor after
					range.collapse(false);
					sel.removeAllRanges();
					sel.addRange(range);
				} else {
					$this.append(this);
				}
			};
			image.onerror = function () {
				//PENDING: more verbose error message?
				alert("Not an image");
			};
			image.src = event.target.result;
		};
		reader.readAsDataURL(file);
	};

	//modified from http://stackoverflow.com/a/12244703/806777
	var selectAllText = function () {
		if (document.body.createTextRange) {
			var range = document.body.createTextRange();
			range.moveToElementText(this);
			range.select();
		} else if (window.getSelection) {
			var selection = window.getSelection();
			var range = document.createRange();
			range.selectNodeContents(this);
			selection.removeAllRanges();
			selection.addRange(range);
		}
	};

	var settings = {
		allowHTML: false,
		allowImg: false,
		singleLine: false,
		pastePlainText: true
	};

	$.fn.toTextarea = function (options) {
		if (options === "destroy" || options === true) {
			return this.each(function () {
				delete this.value;
				$(this).css({
					border: "",
					"white-space": "",
					padding: ""
				}).prop({
					contentEditable: false
				}).off(".toTextarea").data({
					isTextarea: false
				});
			});
		} else if (options === "disable") {
			return this.css({
				"background-color": "#eee",
				color: "#555"
			}).prop({
				contentEditable: false
			}).data({
				disabled: true
			});
		} else if (options === "enable") {
			return this.css({
				"background-color": "",
				color: ""
			}).prop({
				contentEditable: true
			}).data({
				disabled: false
			});
		} else {
			if ($.isPlainObject(options)) {
				$.extend(settings, options);
			}
			return this.each(function () {
				var $this = $(this);
				var isTextarea = $this.data().isTextarea || false;
				if (!isTextarea) {
					if (this.hasOwnProperty("value")) {
						delete this.value;
					}
					Object.defineProperty(this, "value", {
						configurable: true,
						set: function (value) {
							this.innerHTML = value;
						},
						get: function () {
							return this.innerHTML;
						}
					});
					var allowHTML = settings.allowHTML;
					if (typeof settings.allowHTML === "function") {
						allowHTML = settings.allowHTML.call(this);
					}
					var allowImg = settings.allowImg;
					if (typeof settings.allowImg === "function") {
						allowImg = settings.allowImg.call(this);
					}
					var singleLine = settings.singleLine;
					if (typeof settings.singleLine === "function") {
						singleLine = settings.singleLine.call(this);
					}
					var pastePlainText = settings.pastePlainText;
					if (typeof settings.pastePlainText === "function") {
						pastePlainText = settings.pastePlainText.call(this);
					}
					$this
							.css({
								border: "1px solid #aaa",
								"white-space": (singleLine ? "pre" : "pre-wrap"),
								"word-wrap": "break-word",
								padding: "1px"
							})
							.prop({
								contentEditable: true
							})
							.data({
								isTextarea: true,
								disabled: false
							})
							.on("select.toTextarea", function () {
								if (!$(this).data().disabled) {
									selectAllText.call(this);
								}
							});
					if (singleLine) {
						$this
								.on("keypress.toTextarea", function (e) {
									if (!$(this).data().disabled && e.which === 13) {
										e.preventDefault();
										return false;
									}
								});
						//if (!allowHTML || pastePlainText) {
						//PENDING: not allowing pasting html for now.
						$this
								.on("paste.toTextarea", function (e) {
									if (!$(this).data().disabled) {
										var text = null;
										if (window.clipboardData) {
											text = window.clipboardData.getData("Text");
										} else if (e.originalEvent.clipboardData) {
											text = e.originalEvent.clipboardData.getData("text/plain");
										} else {
											return true;
										}
										text = text.replace(/[\n]/g, " ");
										insertTextAtCursor.call(this, text);
										e.preventDefault();
										$(this).trigger("input");
										return false;
									}
								})
								.on("drop.toTextarea", function (e) {
									if (!$(this).data().disabled) {
										var text = null;
										text = e.originalEvent.dataTransfer.getData("text/plain");
										text = text.replace(/[\n]/g, " ");
										insertTextAtCursor.call(this, text, e.originalEvent.clientX, e.originalEvent.clientY);
										e.preventDefault();
										$(this).trigger("input");
										return false;
									}
								});
						/*} else {
						 //PENDING: this is giving me problems, For now if they allow html let it go to multiple lines.
						 //PENDING: maybe check after paste and remove new lines?

						 $this
						 .on("paste.toTextarea", function (e) {
						 if (!$(this).data().disabled) {
						 var text = null;
						 if (window.clipboardData) {
						 text = window.clipboardData.getData("Text");
						 } else if (e.originalEvent.clipboardData) {
						 text = e.originalEvent.clipboardData.getData("text/html");
						 } else {
						 return true;
						 }
						 text = text.replace(/[\n]/g, " ");
						 insertHTMLAtCursor.call(this, text);
						 e.preventDefault();
						 $(this).trigger("input");
						 return false;
						 }
						 })
						 .on("drop.toTextarea", function (e) {
						 if (!$(this).data().disabled) {
						 var text = null;
						 text = e.originalEvent.dataTransfer.getData("text/html");
						 text = text.replace(/[\n]/g, " ");
						 insertHTMLAtCursor.call(this, text, e.originalEvent.clientX, e.originalEvent.clientY);
						 e.preventDefault();
						 $(this).trigger("input");
						 return false;
						 }
						 });
						 }*/

					} else {
						$this.on("keypress.toTextarea", function (e) {
							if (!$(this).data().disabled && e.which === 13) {
								insertTextAtCursor.call(this, "\n");
								e.preventDefault();
								return false;
							}
						});
						if (!allowHTML || pastePlainText) {
							$this
									.on("paste.toTextarea", function (e) {
										if (!$(this).data().disabled) {
											var text = null;
											if (window.clipboardData) {
												text = window.clipboardData.getData("Text");
											} else if (e.originalEvent.clipboardData) {
												text = e.originalEvent.clipboardData.getData("text/plain");
											} else {
												return true;
											}
											insertTextAtCursor.call(this, text);
											e.preventDefault();
											$(this).trigger("input");
											return false;
										}
									})
									.on("drop.toTextarea", function (e) {
										if (!$(this).data().disabled) {
											var text = null;
											text = e.originalEvent.dataTransfer.getData("text/plain");
											insertTextAtCursor.call(this, text, e.originalEvent.clientX, e.originalEvent.clientY);
											e.preventDefault();
											$(this).trigger("input");
											return false;
										}
									});
						}
					}
					if (allowImg) {
						$this
								.on("drop.toTextarea", function (e) {
									if (!$(this).data().disabled && e.originalEvent.dataTransfer.files.length > 0) {
										for (var i = 0, length = e.originalEvent.dataTransfer.files.length; i < length; i++) {
											addImgOnDrop.call(this, e.originalEvent.dataTransfer.files[i], e.originalEvent.clientX, e.originalEvent.clientY);
										}
										e.preventDefault();
										$(this).trigger("input");
										return false;
									}
								})
								.on("dragover.toTextarea", function (e) {
									if (!$(this).data().disabled && e.originalEvent.dataTransfer.types.length > 0 && e.originalEvent.dataTransfer.types[0] === "Files") {
										e.preventDefault();
										return false;
									}
								});
					}
					if (!allowHTML) {
						$this.on("keydown.toTextarea", function (e) {
							if (!$(this).data().disabled && e.ctrlKey) {
								if (e.which in {66: 1, 73: 1}) {
									e.preventDefault();
									return false;
								}
							}
						});
					}
				}
			});
		}
	};
})(jQuery);
<|endoftext|>


<commit_before>const express = require('express');
const path = require('path');
const favicon = require('serve-favicon');
const logger = require('morgan');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const expressValidator = require('express-validator');
const session = require('express-session');
const mongoose = require('mongoose');
const MongoStore = require('connect-mongo')(session);
const util = require('util');

const app = express();

// routes
const index = require('./routes/index');
const users = require('./routes/users');
// database connect
const mongoDB = 'mongodb://localhost/dronemap';
mongoose.connect(mongoDB);
const db = mongoose.connection;

//handle mongo error
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
db.once('open', function() {
  // we're connected!
});

//use sessions for tracking logins
app.use(session({
  secret: 'no pain no gain',
  resave: true,
  saveUninitialized: false,
  store: new MongoStore({
    mongooseConnection: db,
  }),
}));

app.locals.inspect = util.inspect;

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

// uncomment after placing your favicon in /public
app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(expressValidator());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/js', express.static(__dirname + '/node_modules/popper.js/dist'));
app.use('/js', express.static(__dirname + '/node_modules/jquery/dist'));
app.use('/bootstrap', express.static(__dirname + '/node_modules/bootstrap'));
app.use('/font-awesome', express.static(__dirname + '/node_modules/font-awesome'));
app.use('/open-iconic', express.static(__dirname + '/node_modules/open-iconic'));

app.use(function(req, res, next) {
  res.locals.userId = req.session.userId;
  res.locals.user = req.session.user;
  next();
});

app.use('/', index);
app.use('/users', users);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  let err = new Error('Not Found');
  err.status = 404;
  next(err);
});

function logErrors(err, next) {
  console.error(err.stack);
  next(err);
}
app.use(logErrors);// error handler

app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};
  logErrors(err, next);
  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;
<commit_msg>refactoring<commit_after>const express = require('express');
const path = require('path');
const favicon = require('serve-favicon');
const logger = require('morgan');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const expressValidator = require('express-validator');
const session = require('express-session');
const mongoose = require('mongoose');
const MongoStore = require('connect-mongo')(session);
const util = require('util');
// routes
const index = require('./routes/index');
const users = require('./routes/users');
// database connect
const mongoDB = 'mongodb://localhost/dronemap';
mongoose.connect(mongoDB);
const db = mongoose.connection;

//handle mongo error
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
db.once('open', function() {
  // we're connected!
});

const app = express();

//use sessions for tracking logins
app.use(session({
  secret: 'no pain no gain',
  resave: true,
  saveUninitialized: false,
  store: new MongoStore({
    mongooseConnection: db,
  }),
}));

app.locals.inspect = util.inspect;

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

// uncomment after placing your favicon in /public
app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(expressValidator());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/js', express.static(__dirname + '/node_modules/popper.js/dist'));
app.use('/js', express.static(__dirname + '/node_modules/jquery/dist'));
app.use('/bootstrap', express.static(__dirname + '/node_modules/bootstrap'));
app.use('/font-awesome', express.static(__dirname + '/node_modules/font-awesome'));
app.use('/open-iconic', express.static(__dirname + '/node_modules/open-iconic'));

app.use(function(req, res, next) {
  res.locals.userId = req.session.userId;
  res.locals.user = req.session.user;
  next();
});

app.use('/', index);
app.use('/users', users);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  let err = new Error('Not Found');
  err.status = 404;
  next(err);
});

function logErrors(err, next) {
  console.error(err.stack);
  next(err);
}
app.use(logErrors);// error handler

app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};
  logErrors(err, next);
  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;
<|endoftext|>


<commit_before>'use strict';

var OpalCard = require('./opal.js'),
    config   = require('./config.json');

var opal = new OpalCard(config.opal.username, config.opal.password);

// opal.turnOnDevMode();

// opal.getCardTransactions(function (err, data) {
//   if (err) {
//     console.log(err);
//   } else {
//     console.log(data);
//     console.log('');
//     opal.getCardInfo(function (err, data) {
//       if (err) {
//         console.log(err);
//       } else {
//         console.log(data);
//         console.log('');
//       }
//     });
//   }
// });

function getOverallFares(transactions) {
  var overallPrice    = 0,
      overallDiscount = 0,
      overallPaid     = 0;
  transactions.forEach(function (transaction) {
    if (transaction.journey) {
      overallPrice    += transaction.fare.price;
      overallDiscount += transaction.fare.discount;
      overallPaid     += transaction.fare.paid;
    }
  });
  return {
    overallPrice: overallPrice,
    overallDiscount: overallDiscount,
    overallPaid: overallPaid
  };
}

opal.getCardInfo()
.then(function (data) {
  console.log(data);
  console.log('');
  return opal.getUserDetails();
})
.then(function (data) {
  console.log(data);
  console.log('');
  return opal.getCardTransactions({
    month: 7,
    year: 2014
  });
})
.then(function (data) {
  console.log(JSON.stringify(data, null, '  '));
  console.log('');
  console.log(JSON.stringify(getOverallFares(data), null, '  '));
})
.fail(function (err) {
  console.log(err);
});
<commit_msg>update app.js<commit_after>'use strict';

var OpalCard = require('./lib/opal.js'),
    config   = require('./config.json');

var opal = new OpalCard(config.opal.username, config.opal.password);

// opal.getCardTransactions(function (err, data) {
//   if (err) {
//     console.log(err);
//   } else {
//     console.log(data);
//     console.log('');
//     opal.getCardInfo(function (err, data) {
//       if (err) {
//         console.log(err);
//       } else {
//         console.log(data);
//         console.log('');
//       }
//     });
//   }
// });

function getOverallFares(transactions) {
  var overallPrice    = 0,
      overallDiscount = 0,
      overallPaid     = 0;
  transactions.forEach(function (transaction) {
    if (transaction.journey) {
      overallPrice    += transaction.fare.price;
      overallDiscount += transaction.fare.discount;
      overallPaid     += transaction.fare.paid;
    }
  });
  return {
    overallPrice: overallPrice,
    overallDiscount: overallDiscount,
    overallPaid: overallPaid
  };
}

opal.getCardInfo()
.then(function (data) {
  console.log(data);
  console.log('');
  return opal.getUserDetails();
})
.then(function (data) {
  console.log(data);
  console.log('');
  return opal.getCardTransactions({
    month: 7,
    year: 2014
  });
})
.then(function (data) {
  console.log(JSON.stringify(data, null, '  '));
  console.log('');
  console.log(JSON.stringify(getOverallFares(data), null, '  '));
})
.fail(function (err) {
  console.log(err);
});
<|endoftext|>


<commit_before>'use strict';

console.log('Launching…');

var meta = require('./package.json');
var express = require('express');
var compression = require('compression');
var bodyParser = require('body-parser');
var exec = require('child_process').exec;
var path = require('path');
var Fs = require('fs');
var Promise = require('promise');
var Uuid = require('node-uuid');

var DocumentDownloader = require('./lib/document-downloader');
var History = require('./lib/history');
var JsonHttpService = require('./lib/json-http-service');
var Publisher = require('./lib/publisher');
var SpecberusWrapper = require('./functions.js').SpecberusWrapper;
var ThirdPartyResourcesChecker = require('./lib/third-party-resources-checker');
var TokenChecker = require('./functions.js').TokenChecker;

// Configuration file
require('./config.js');

// Pseudo-constants:
var STATUS_STARTED = 'started';
var STATUS_ERROR = 'error';
var STATUS_SUCCESS = 'success';

var app = express();
var requests = {};
var argTempLocation = process.argv[2] || global.DEFAULT_TEMP_LOCATION;
var argHttpLocation  = process.argv[3] || global.DEFAULT_HTTP_LOCATION;
var port = process.argv[4] || global.DEFAULT_PORT;
var argResultLocation = process.argv[5] || global.DEFAULT_RESULT_LOCATION;

app.use(compression());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(corsHandler);
app.use(express.static('views'));
app.use(express.static('assets'));

if (process.env.NODE_ENV === 'production') {
  app.set('views', __dirname + '/dist/views');
  app.use(express.static(__dirname + '/dist/assets'));
}
else {
  app.set('views', __dirname + '/views');
  app.use(express.static(__dirname + '/assets'));
}

// Index Page
app.get('/', function (request, response) {
  response.sendFile(__dirname + '/views/index.html');
});

// API methods

app.get('/api/version', function (req, res) {
  res.send(meta.version);
});

app.get('/api/version-specberus', function (req, res) {
  res.send(SpecberusWrapper.version);
});

app.get('/api/status', function (req, res) {
  var id = req.query ? req.query.id : null;
  var file = argResultLocation + path.sep + id + '.json';

  if (id) {
    Fs.exists(file, function (exists) {
      if (exists) res.status(200).sendFile(file);
      else if (requests && requests[id]) {
        res.status(200).json(requests[id]);
      }
      else res.status(404).send('No job found with ID “' + id + '”.');
    });
  }
  else res.status(400).send('Missing required parameter “ID”.');
});

app.post('/api/request', function (req, res) {
  var url = req.body ? req.body.url : null;
  var decision = req.body ? req.body.decision : null;
  var token = req.body ? req.body.token : null;
  var id = Uuid.v4();

  if (!url || !decision || !token) {
    res.status(500).send(
      'Missing required parameters “url”, “decision” and/or “token”.'
    );
  }
  else {
    requests[id] = {
      id: id,
      url: url,
      version: meta.version,
      'version-specberus': SpecberusWrapper.version,
      decision: decision,
      jobs: {},
      history: new History(),
      status: STATUS_STARTED
    };

    orchestrate(requests[id], token).then(function () {
      console.log(
        'Spec at ' + url + ' (decision: ' + decision + ') has FINISHED.'
      );
    }, function () {
      console.log(
        'Spec at ' + url + ' (decision: ' + decision + ') has FAILED.'
      );
    });
    res.status(202).send(id);
  }
});

/**
* Add CORS headers to responses if the client is explicitly allowed.
*
* First, this ensures that the testbed page on the test server, listening on a different port, can GET and POST to Echidna.
* Most importantly, this is necessary to attend publication requests from third parties, eg GitHub.
*/

function corsHandler(req, res, next) {
  if (req && req.headers && req.headers.origin) {
    if (global.ALLOWED_CLIENTS.some(function (regex) {
      return regex.test(req.headers.origin);
    })) {
      res.header('Access-Control-Allow-Origin', req.headers.origin);
      res.header('Access-Control-Allow-Methods', 'GET,POST');
      res.header('Access-Control-Allow-Headers', 'Content-Type');
    }
  }
  next();
}

function trInstaller(source, dest) {
  return new Promise(function (resolve, reject) {
    var cmd = global.TR_INSTALL_CMD + ' ' + source + ' ' + dest;
    exec(cmd, function (err) {
      if (err) reject(err);
      else resolve();
    });
  });
}

function updateTrShortlink(uri) {
  return new Promise(function (resolve, reject) {
    var cmd = global.UPDATE_TR_SHORTLINK_CMD + ' ' + uri;
    exec(cmd, function (err) {
      if (err) reject(err);
      else resolve();
    });
  });
}

function Job() {
  if (typeof this !== 'object') {
    throw new TypeError('Jobs must be constructed via new');
  }

  this.status = '';
  this.errors = [];
}

function dumpJobResult(dest, result) {
  Fs.writeFile(dest, JSON.stringify(result, null, 2) + '\n', function (err) {
    if (err) return console.error(err);
  });
}

function orchestrate(spec, token) {
  spec.jobs['retrieve-resources'] = new Job();
  spec.jobs['specberus'] = new Job();
  spec.jobs['token-checker'] = new Job();
  spec.jobs['third-party-checker'] = new Job();
  spec.jobs['publish'] = new Job();
  spec.jobs['tr-install'] = new Job();
  spec.jobs['update-tr-shortlink'] = new Job();

  var W3C_PREFIX = 'http://www.w3.org';

  var tempLocation = argTempLocation + path.sep + spec.id + path.sep;
  var resultLocation = argResultLocation + path.sep + spec.id + '.json';
  var httpLocation = argHttpLocation + '/' + spec.id + '/Overview.html';

  function runSpecberus(httpLocation, spec) {
    spec.jobs['specberus'].status = 'pending';

    return SpecberusWrapper.validate(httpLocation)
      .then(function (report) {
        if (report.errors.isEmpty()) {
          spec.jobs['specberus'].status = 'ok';
          spec.history = spec.history.add('The document passed specberus.');

          return Promise.resolve(report);
        }
        else {
          spec.jobs['specberus'].status = 'failure';
          spec.jobs['specberus'].errors = report.errors;
          spec.history = spec.history.add('The document failed Specberus.');

          return Promise.reject(
            new Error('This document has failed Specberus.')
          );
        }
      }).catch(function (error) {
        spec.jobs['specberus'].status = 'error';
        spec.jobs['specberus'].errors.push(error.toString());
        spec.history = spec.history.add(
          'An error occurred while running Specberus.'
        );

        return Promise.reject(error);
      });
  }

  function runTokenChecker(report, url) {
    return TokenChecker.check(report.metadata.get('latestVersion'), token)
      .then(function (authReport) {
        var simpleSource1 = authReport.source.replace(/^https:/i, 'http:');
        var simpleSource2 = authReport.source.replace(/^http:/i, 'https:');
        var matchSource = (
          url.indexOf(simpleSource1) === 0 ||
          url.indexOf(simpleSource2) === 0
        );

        if (authReport.authorized && matchSource) {
          console.log('TokenChecker SUCCESS');
          return Promise.resolve(authReport);
        }
        else {
          console.log('TokenChecker FAILURE');
          console.log(authReport);
          return Promise.reject(
            new Error('You are not allowed to publish this document.')
          );
        }
      });
  }

  function runThirdPartyResourcesChecker(httpLocation) {
    return ThirdPartyResourcesChecker.check(httpLocation)
      .then(function (extResources) {
        if (extResources.length === 0) {
          console.log('ThirdPartyResourcesChecker SUCCESS');
          return Promise.resolve(extResources);
        }
        else {
          console.log('ThirdPartyResourcesChecker FAILURE');
          console.log(extResources);
          return Promise.reject(
            new Error('There are external resources in this document.')
          );
        }
      });
  }

  function runPublisher(specberusReport) {
    return specberusReport.then(function (report) {
      var pubsystemService = new JsonHttpService(
        global.W3C_PUBSYSTEM_URL,
        global.USERNAME,
        global.PASSWORD
      );

      return new Publisher(pubsystemService).publish(report.metadata)
        .then(function (errors) {
          if (errors.isEmpty()) {
            console.log('Publisher SUCCESS');
            return Promise.resolve(errors);
          }
          else {
            console.log('Publisher FAILED');
            console.log(errors.toJSON());
            return Promise.reject(
              new Error('There was a problem with the publication system.')
            );
          }
        });
    });
  }

  function runTrInstaller(specberusReport, tempLocation) {
    return specberusReport.then(function (report) {
      var finalTRpath = report.metadata.get('thisVersion')
        .replace(W3C_PREFIX, '');
      return trInstaller(tempLocation, finalTRpath);
    });
  }

  function runShortlink(specberusReport) {
    return specberusReport.then(function (report) {
      return updateTrShortlink(report.metadata.get('thisVersion'));
    });
  }

  function finishTasks(specberusReport, spec, resultLocation) {
    return specberusReport.then(function (report) {
      var cmd =
        global.SENDMAIL + ' SUCCESS ' + global.MAILING_LIST + ' ' +
        report.metadata.get('thisVersion');

      exec(cmd, function (err, stdout, stderr) {
        if (err) console.error(stderr);
      });

      spec.status = STATUS_SUCCESS;
      dumpJobResult(resultLocation, spec);
      return Promise.resolve('finished');
    });
  }

  var specberusReport = DocumentDownloader.fetchAndInstall(
    spec.url,
    tempLocation
  ).then(function () {
    return runSpecberus(httpLocation, spec);
  });

  return specberusReport
    .then(function (report) {
      return runTokenChecker(report, spec.url);
    }).then(function () {
      return runThirdPartyResourcesChecker(httpLocation);
    })
    .then(function () {
      return runPublisher(specberusReport);
    })
    .then(function () {
      return runTrInstaller(specberusReport, tempLocation);
    })
    .then(function () {
      return runShortlink(specberusReport);
    })
    .then(function () {
      return finishTasks(specberusReport, spec, resultLocation);
    })
    .catch(function (err) {
      console.log(err.stack);

      spec.status = STATUS_ERROR;
      var cmd =
        global.SENDMAIL + ' ERROR ' + global.MAILING_LIST + ' ' + spec.url +
        ' \'' + JSON.stringify(spec, null, 2) + '\'';
      exec(cmd, function (err, stdout, stderr) {
        if (err) console.error(stderr);
      });
      dumpJobResult(resultLocation, spec);
      return Promise.reject(new Error('Orchestrator has failed.'));
    });

  /*
  spec.jobs['retrieve-resources'].status = 'pending';

    spec.jobs['retrieve-resources'].status = 'ok';
    spec.history = spec.history.add('The file has been retrieved.');

      spec.jobs['token-checker'].status = 'pending';

        spec.jobs['token-checker'].status = 'ok';
        spec.history = spec.history.add('You are authorized to publish');
        spec.jobs['third-party-checker'].status = 'pending';

          spec.jobs['third-party-checker'].status = 'ok';
          spec.history = spec.history.add('The document passed the third party checker.');
          spec.jobs['publish'].status = 'pending';

            spec.jobs['publish'].status = 'ok';
            spec.jobs['tr-install'].status = 'pending';

              spec.jobs['tr-install'].status = 'ok';
              spec.jobs['update-tr-shortlink'].status = 'pending';

                spec.jobs['update-tr-shortlink'].status = 'ok';
                spec.history = spec.history.add('The document has been published at ' + report.metadata.get('thisVersion') + '.');
                spec.status = STATUS_SUCCESS;

                spec.jobs['update-tr-shortlink'].status = 'error';
                spec.jobs['update-tr-shortlink'].errors.push(err.toString());

              spec.jobs['tr-install'].status = 'error';
              spec.jobs['tr-install'].errors.push(err.toString());

            spec.jobs['publish'].status = 'failure';
            spec.jobs['publish'].errors = errors;
            spec.history = spec.history.add('The document could not be published: ' + errors.map(function (error) {
              return error.message;
            }));

            spec.jobs['publish'].status = 'error';
            spec.jobs['publish'].errors.push(err.toString());
            spec.history = spec.history.add('The document could not be published: ' + err.message);

          spec.jobs['token-checker'].status = 'failure';
          spec.jobs['token-checker'].errors.push('Not authorized');
          spec.history = spec.history.add('You are not authorized to publish');

          spec.jobs['token-checker'].status = 'error';
          spec.jobs['token-checker'].errors.push(err.toString());

        spec.history = spec.history.add('The document contains non-authorized resources');
        spec.jobs['third-party-checker'].status = 'failure';
        spec.jobs['third-party-checker'].errors = extResources;

        spec.jobs['third-party-checker'].status = 'error';
        spec.jobs['third-party-checker'].errors.push(err.toString());

    spec.history = spec.history.add('The document could not be retrieved.');
    spec.jobs['retrieve-resources'].status = 'error';
    spec.jobs['retrieve-resources'].errors.push(err.toString());

  spec.history = spec.history.add('A system error occurred during the process.');
*/
}

app.listen(process.env.PORT || port).on('error', function (err) {
  if (err) {
    console.error('Error while trying to launch the server: “' + err + '”.');
  }
});

console.log(
  meta.name +
  ' version ' + meta.version +
  ' running on ' + process.platform +
  ' and listening on port ' + port +
  '. The server time is ' + new Date().toLocaleTimeString() + '.'
);
<commit_msg>Add status and history report to the Token Checker step<commit_after>'use strict';

console.log('Launching…');

var meta = require('./package.json');
var express = require('express');
var compression = require('compression');
var bodyParser = require('body-parser');
var exec = require('child_process').exec;
var path = require('path');
var Fs = require('fs');
var Promise = require('promise');
var Uuid = require('node-uuid');

var DocumentDownloader = require('./lib/document-downloader');
var History = require('./lib/history');
var JsonHttpService = require('./lib/json-http-service');
var Publisher = require('./lib/publisher');
var SpecberusWrapper = require('./functions.js').SpecberusWrapper;
var ThirdPartyResourcesChecker = require('./lib/third-party-resources-checker');
var TokenChecker = require('./functions.js').TokenChecker;

// Configuration file
require('./config.js');

// Pseudo-constants:
var STATUS_STARTED = 'started';
var STATUS_ERROR = 'error';
var STATUS_SUCCESS = 'success';

var app = express();
var requests = {};
var argTempLocation = process.argv[2] || global.DEFAULT_TEMP_LOCATION;
var argHttpLocation  = process.argv[3] || global.DEFAULT_HTTP_LOCATION;
var port = process.argv[4] || global.DEFAULT_PORT;
var argResultLocation = process.argv[5] || global.DEFAULT_RESULT_LOCATION;

app.use(compression());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(corsHandler);
app.use(express.static('views'));
app.use(express.static('assets'));

if (process.env.NODE_ENV === 'production') {
  app.set('views', __dirname + '/dist/views');
  app.use(express.static(__dirname + '/dist/assets'));
}
else {
  app.set('views', __dirname + '/views');
  app.use(express.static(__dirname + '/assets'));
}

// Index Page
app.get('/', function (request, response) {
  response.sendFile(__dirname + '/views/index.html');
});

// API methods

app.get('/api/version', function (req, res) {
  res.send(meta.version);
});

app.get('/api/version-specberus', function (req, res) {
  res.send(SpecberusWrapper.version);
});

app.get('/api/status', function (req, res) {
  var id = req.query ? req.query.id : null;
  var file = argResultLocation + path.sep + id + '.json';

  if (id) {
    Fs.exists(file, function (exists) {
      if (exists) res.status(200).sendFile(file);
      else if (requests && requests[id]) {
        res.status(200).json(requests[id]);
      }
      else res.status(404).send('No job found with ID “' + id + '”.');
    });
  }
  else res.status(400).send('Missing required parameter “ID”.');
});

app.post('/api/request', function (req, res) {
  var url = req.body ? req.body.url : null;
  var decision = req.body ? req.body.decision : null;
  var token = req.body ? req.body.token : null;
  var id = Uuid.v4();

  if (!url || !decision || !token) {
    res.status(500).send(
      'Missing required parameters “url”, “decision” and/or “token”.'
    );
  }
  else {
    requests[id] = {
      id: id,
      url: url,
      version: meta.version,
      'version-specberus': SpecberusWrapper.version,
      decision: decision,
      jobs: {},
      history: new History(),
      status: STATUS_STARTED
    };

    orchestrate(requests[id], token).then(function () {
      console.log(
        'Spec at ' + url + ' (decision: ' + decision + ') has FINISHED.'
      );
    }, function () {
      console.log(
        'Spec at ' + url + ' (decision: ' + decision + ') has FAILED.'
      );
    });
    res.status(202).send(id);
  }
});

/**
* Add CORS headers to responses if the client is explicitly allowed.
*
* First, this ensures that the testbed page on the test server, listening on a different port, can GET and POST to Echidna.
* Most importantly, this is necessary to attend publication requests from third parties, eg GitHub.
*/

function corsHandler(req, res, next) {
  if (req && req.headers && req.headers.origin) {
    if (global.ALLOWED_CLIENTS.some(function (regex) {
      return regex.test(req.headers.origin);
    })) {
      res.header('Access-Control-Allow-Origin', req.headers.origin);
      res.header('Access-Control-Allow-Methods', 'GET,POST');
      res.header('Access-Control-Allow-Headers', 'Content-Type');
    }
  }
  next();
}

function trInstaller(source, dest) {
  return new Promise(function (resolve, reject) {
    var cmd = global.TR_INSTALL_CMD + ' ' + source + ' ' + dest;
    exec(cmd, function (err) {
      if (err) reject(err);
      else resolve();
    });
  });
}

function updateTrShortlink(uri) {
  return new Promise(function (resolve, reject) {
    var cmd = global.UPDATE_TR_SHORTLINK_CMD + ' ' + uri;
    exec(cmd, function (err) {
      if (err) reject(err);
      else resolve();
    });
  });
}

function Job() {
  if (typeof this !== 'object') {
    throw new TypeError('Jobs must be constructed via new');
  }

  this.status = '';
  this.errors = [];
}

function dumpJobResult(dest, result) {
  Fs.writeFile(dest, JSON.stringify(result, null, 2) + '\n', function (err) {
    if (err) return console.error(err);
  });
}

function orchestrate(spec, token) {
  spec.jobs['retrieve-resources'] = new Job();
  spec.jobs['specberus'] = new Job();
  spec.jobs['token-checker'] = new Job();
  spec.jobs['third-party-checker'] = new Job();
  spec.jobs['publish'] = new Job();
  spec.jobs['tr-install'] = new Job();
  spec.jobs['update-tr-shortlink'] = new Job();

  var W3C_PREFIX = 'http://www.w3.org';

  var tempLocation = argTempLocation + path.sep + spec.id + path.sep;
  var resultLocation = argResultLocation + path.sep + spec.id + '.json';
  var httpLocation = argHttpLocation + '/' + spec.id + '/Overview.html';

  function runSpecberus(httpLocation, spec) {
    spec.jobs['specberus'].status = 'pending';

    return SpecberusWrapper.validate(httpLocation)
      .then(function (report) {
        if (report.errors.isEmpty()) {
          spec.jobs['specberus'].status = 'ok';
          spec.history = spec.history.add('The document passed specberus.');

          return Promise.resolve(report);
        }
        else {
          spec.jobs['specberus'].status = 'failure';
          spec.jobs['specberus'].errors = report.errors;
          spec.history = spec.history.add('The document failed Specberus.');

          return Promise.reject(
            new Error('This document has failed Specberus.')
          );
        }
      }).catch(function (error) {
        spec.jobs['specberus'].status = 'error';
        spec.jobs['specberus'].errors.push(error.toString());
        spec.history = spec.history.add(
          'An error occurred while running Specberus.'
        );

        return Promise.reject(error);
      });
  }

  function runTokenChecker(report, url, spec) {
    spec.jobs['token-checker'].status = 'pending';

    return TokenChecker.check(report.metadata.get('latestVersion'), token)
      .then(function (authReport) {
        var simpleSource1 = authReport.source.replace(/^https:/i, 'http:');
        var simpleSource2 = authReport.source.replace(/^http:/i, 'https:');
        var matchSource = (
          url.indexOf(simpleSource1) === 0 ||
          url.indexOf(simpleSource2) === 0
        );

        if (authReport.authorized && matchSource) {
          spec.jobs['token-checker'].status = 'ok';
          spec.history = spec.history.add('You are authorized to publish');

          return Promise.resolve(authReport);
        }
        else {
          spec.jobs['token-checker'].status = 'failure';
          spec.jobs['token-checker'].errors.push('Not authorized');
          spec.history = spec.history.add('You are not authorized to publish');

          return Promise.reject(
            new Error('You are not allowed to publish this document.')
          );
        }
      }).catch(function (error) {
        spec.jobs['token-checker'].status = 'error';
        spec.jobs['token-checker'].errors.push(error.toString());
        spec.history = spec.history.add(
          'An error occurred while running the Token Checker.'
        );

        return Promise.reject(error);
      });
  }

  function runThirdPartyResourcesChecker(httpLocation) {
    return ThirdPartyResourcesChecker.check(httpLocation)
      .then(function (extResources) {
        if (extResources.length === 0) {
          console.log('ThirdPartyResourcesChecker SUCCESS');
          return Promise.resolve(extResources);
        }
        else {
          console.log('ThirdPartyResourcesChecker FAILURE');
          console.log(extResources);
          return Promise.reject(
            new Error('There are external resources in this document.')
          );
        }
      });
  }

  function runPublisher(specberusReport) {
    return specberusReport.then(function (report) {
      var pubsystemService = new JsonHttpService(
        global.W3C_PUBSYSTEM_URL,
        global.USERNAME,
        global.PASSWORD
      );

      return new Publisher(pubsystemService).publish(report.metadata)
        .then(function (errors) {
          if (errors.isEmpty()) {
            console.log('Publisher SUCCESS');
            return Promise.resolve(errors);
          }
          else {
            console.log('Publisher FAILED');
            console.log(errors.toJSON());
            return Promise.reject(
              new Error('There was a problem with the publication system.')
            );
          }
        });
    });
  }

  function runTrInstaller(specberusReport, tempLocation) {
    return specberusReport.then(function (report) {
      var finalTRpath = report.metadata.get('thisVersion')
        .replace(W3C_PREFIX, '');
      return trInstaller(tempLocation, finalTRpath);
    });
  }

  function runShortlink(specberusReport) {
    return specberusReport.then(function (report) {
      return updateTrShortlink(report.metadata.get('thisVersion'));
    });
  }

  function finishTasks(specberusReport, spec, resultLocation) {
    return specberusReport.then(function (report) {
      var cmd =
        global.SENDMAIL + ' SUCCESS ' + global.MAILING_LIST + ' ' +
        report.metadata.get('thisVersion');

      exec(cmd, function (err, stdout, stderr) {
        if (err) console.error(stderr);
      });

      spec.status = STATUS_SUCCESS;
      dumpJobResult(resultLocation, spec);
      return Promise.resolve('finished');
    });
  }

  var specberusReport = DocumentDownloader.fetchAndInstall(
    spec.url,
    tempLocation
  ).then(function () {
    return runSpecberus(httpLocation, spec);
  });

  return specberusReport
    .then(function (report) {
      return runTokenChecker(report, spec.url, spec);
    }).then(function () {
      return runThirdPartyResourcesChecker(httpLocation);
    })
    .then(function () {
      return runPublisher(specberusReport);
    })
    .then(function () {
      return runTrInstaller(specberusReport, tempLocation);
    })
    .then(function () {
      return runShortlink(specberusReport);
    })
    .then(function () {
      return finishTasks(specberusReport, spec, resultLocation);
    })
    .catch(function (err) {
      console.log(err.stack);

      spec.status = STATUS_ERROR;
      var cmd =
        global.SENDMAIL + ' ERROR ' + global.MAILING_LIST + ' ' + spec.url +
        ' \'' + JSON.stringify(spec, null, 2) + '\'';
      exec(cmd, function (err, stdout, stderr) {
        if (err) console.error(stderr);
      });
      dumpJobResult(resultLocation, spec);
      return Promise.reject(new Error('Orchestrator has failed.'));
    });

  /*
  spec.jobs['retrieve-resources'].status = 'pending';

    spec.jobs['retrieve-resources'].status = 'ok';
    spec.history = spec.history.add('The file has been retrieved.');

        spec.jobs['third-party-checker'].status = 'pending';

          spec.jobs['third-party-checker'].status = 'ok';
          spec.history = spec.history.add('The document passed the third party checker.');
          spec.jobs['publish'].status = 'pending';

            spec.jobs['publish'].status = 'ok';
            spec.jobs['tr-install'].status = 'pending';

              spec.jobs['tr-install'].status = 'ok';
              spec.jobs['update-tr-shortlink'].status = 'pending';

                spec.jobs['update-tr-shortlink'].status = 'ok';
                spec.history = spec.history.add('The document has been published at ' + report.metadata.get('thisVersion') + '.');
                spec.status = STATUS_SUCCESS;

                spec.jobs['update-tr-shortlink'].status = 'error';
                spec.jobs['update-tr-shortlink'].errors.push(err.toString());

              spec.jobs['tr-install'].status = 'error';
              spec.jobs['tr-install'].errors.push(err.toString());

            spec.jobs['publish'].status = 'failure';
            spec.jobs['publish'].errors = errors;
            spec.history = spec.history.add('The document could not be published: ' + errors.map(function (error) {
              return error.message;
            }));

            spec.jobs['publish'].status = 'error';
            spec.jobs['publish'].errors.push(err.toString());
            spec.history = spec.history.add('The document could not be published: ' + err.message);

        spec.history = spec.history.add('The document contains non-authorized resources');
        spec.jobs['third-party-checker'].status = 'failure';
        spec.jobs['third-party-checker'].errors = extResources;

        spec.jobs['third-party-checker'].status = 'error';
        spec.jobs['third-party-checker'].errors.push(err.toString());

    spec.history = spec.history.add('The document could not be retrieved.');
    spec.jobs['retrieve-resources'].status = 'error';
    spec.jobs['retrieve-resources'].errors.push(err.toString());

  spec.history = spec.history.add('A system error occurred during the process.');
*/
}

app.listen(process.env.PORT || port).on('error', function (err) {
  if (err) {
    console.error('Error while trying to launch the server: “' + err + '”.');
  }
});

console.log(
  meta.name +
  ' version ' + meta.version +
  ' running on ' + process.platform +
  ' and listening on port ' + port +
  '. The server time is ' + new Date().toLocaleTimeString() + '.'
);
<|endoftext|>


<commit_before>/**
 * Flotr Defaults
 */
Flotr.defaultOptions = {
  colors: ['#00A8F0', '#C0D800', '#CB4B4B', '#4DA74D', '#9440ED'], //=> The default colorscheme. When there are > 5 series, additional colors are generated.
  ieBackgroundColor: '#FFFFFF', // Background color for excanvas clipping
  title: null,             // => The graph's title
  subtitle: null,          // => The graph's subtitle
  shadowSize: 4,           // => size of the 'fake' shadow
  defaultType: null,       // => default series type
  HtmlText: true,          // => wether to draw the text using HTML or on the canvas
  fontColor: '#545454',    // => default font color
  fontSize: 7.5,           // => canvas' text font size
  resolution: 1,           // => resolution of the graph, to have printer-friendly graphs !
  parseFloat: true,        // => whether to preprocess data for floats (ie. if input is string)
  xaxis: {
    ticks: null,           // => format: either [1, 3] or [[1, 'a'], 3]
    minorTicks: null,      // => format: either [1, 3] or [[1, 'a'], 3]
    showLabels: true,      // => setting to true will show the axis ticks labels, hide otherwise
    showMinorLabels: false,// => true to show the axis minor ticks labels, false to hide
    labelsAngle: 0,        // => labels' angle, in degrees
    title: null,           // => axis title
    titleAngle: 0,         // => axis title's angle, in degrees
    noTicks: 5,            // => number of ticks for automagically generated ticks
    minorTickFreq: null,   // => number of minor ticks between major ticks for autogenerated ticks
    tickFormatter: Flotr.defaultTickFormatter, // => fn: number, Object -> string
    tickDecimals: null,    // => no. of decimals, null means auto
    min: null,             // => min. value to show, null means set automatically
    max: null,             // => max. value to show, null means set automatically
    autoscale: false,      // => Turns autoscaling on with true
    autoscaleMargin: 0,    // => margin in % to add if auto-setting min/max
    color: null,           // => color of the ticks
    mode: 'normal',        // => can be 'time' or 'normal'
    timeFormat: null,
    timeMode:'UTC',        // => For UTC time ('local' for local time).
    timeUnit:'millisecond',// => Unit for time (millisecond, second, minute, hour, day, month, year)
    scaling: 'linear',     // => Scaling, can be 'linear' or 'logarithmic'
    base: Math.E,
    titleAlign: 'center',
    margin: true           // => Turn off margins with false
  },
  x2axis: {},
  yaxis: {
    ticks: null,           // => format: either [1, 3] or [[1, 'a'], 3]
    minorTicks: null,      // => format: either [1, 3] or [[1, 'a'], 3]
    showLabels: true,      // => setting to true will show the axis ticks labels, hide otherwise
    showMinorLabels: false,// => true to show the axis minor ticks labels, false to hide
    labelsAngle: 0,        // => labels' angle, in degrees
    title: null,           // => axis title
    titleAngle: 90,        // => axis title's angle, in degrees
    noTicks: 5,            // => number of ticks for automagically generated ticks
    minorTickFreq: null,   // => number of minor ticks between major ticks for autogenerated ticks
    tickFormatter: Flotr.defaultTickFormatter, // => fn: number, Object -> string
    tickDecimals: null,    // => no. of decimals, null means auto
    min: null,             // => min. value to show, null means set automatically
    max: null,             // => max. value to show, null means set automatically
    autoscale: false,      // => Turns autoscaling on with true
    autoscaleMargin: 0,    // => margin in % to add if auto-setting min/max
    color: null,           // => The color of the ticks
    scaling: 'linear',     // => Scaling, can be 'linear' or 'logarithmic'
    base: Math.E,
    titleAlign: 'right',
    margin: true           // => Turn off margins with false
  },
  y2axis: {
    titleAngle: 270
  },
  grid: {
    color: '#545454',      // => primary color used for outline and labels
    backgroundColor: null, // => null for transparent, else color
    backgroundImage: null, // => background image. String or object with src, left and top
    watermarkAlpha: 0.4,   // =>
    tickColor: '#DDDDDD',  // => color used for the ticks
    labelMargin: 3,        // => margin in pixels
    verticalLines: true,   // => whether to show gridlines in vertical direction
    minorVerticalLines: null, // => whether to show gridlines for minor ticks in vertical dir.
    horizontalLines: true, // => whether to show gridlines in horizontal direction
    minorHorizontalLines: null, // => whether to show gridlines for minor ticks in horizontal dir.
    outlineWidth: 1,       // => width of the grid outline/border in pixels
    outline : 'nsew',      // => walls of the outline to display
    circular: false        // => if set to true, the grid will be circular, must be used when radars are drawn
  },
  mouse: {
    track: false,          // => true to track the mouse, no tracking otherwise
    trackAll: false,
    position: 'se',        // => position of the value box (default south-east)
    relative: false,       // => next to the mouse cursor
    trackFormatter: Flotr.defaultTrackFormatter, // => formats the values in the value box
    margin: 5,             // => margin in pixels of the valuebox
    lineColor: '#FF3F19',  // => line color of points that are drawn when mouse comes near a value of a series
    trackDecimals: 1,      // => decimals for the track values
    sensibility: 2,        // => the lower this number, the more precise you have to aim to show a value
    trackY: true,          // => whether or not to track the mouse in the y axis
    radius: 3,             // => radius of the track point
    fillColor: null,       // => color to fill our select bar with only applies to bar and similar graphs (only bars for now)
    fillOpacity: 0.4       // => opacity of the fill color, set to 1 for a solid fill, 0 hides the fill
  }
};
<commit_msg>Keep this at center for canvas regression tests.<commit_after>/**
 * Flotr Defaults
 */
Flotr.defaultOptions = {
  colors: ['#00A8F0', '#C0D800', '#CB4B4B', '#4DA74D', '#9440ED'], //=> The default colorscheme. When there are > 5 series, additional colors are generated.
  ieBackgroundColor: '#FFFFFF', // Background color for excanvas clipping
  title: null,             // => The graph's title
  subtitle: null,          // => The graph's subtitle
  shadowSize: 4,           // => size of the 'fake' shadow
  defaultType: null,       // => default series type
  HtmlText: true,          // => wether to draw the text using HTML or on the canvas
  fontColor: '#545454',    // => default font color
  fontSize: 7.5,           // => canvas' text font size
  resolution: 1,           // => resolution of the graph, to have printer-friendly graphs !
  parseFloat: true,        // => whether to preprocess data for floats (ie. if input is string)
  xaxis: {
    ticks: null,           // => format: either [1, 3] or [[1, 'a'], 3]
    minorTicks: null,      // => format: either [1, 3] or [[1, 'a'], 3]
    showLabels: true,      // => setting to true will show the axis ticks labels, hide otherwise
    showMinorLabels: false,// => true to show the axis minor ticks labels, false to hide
    labelsAngle: 0,        // => labels' angle, in degrees
    title: null,           // => axis title
    titleAngle: 0,         // => axis title's angle, in degrees
    noTicks: 5,            // => number of ticks for automagically generated ticks
    minorTickFreq: null,   // => number of minor ticks between major ticks for autogenerated ticks
    tickFormatter: Flotr.defaultTickFormatter, // => fn: number, Object -> string
    tickDecimals: null,    // => no. of decimals, null means auto
    min: null,             // => min. value to show, null means set automatically
    max: null,             // => max. value to show, null means set automatically
    autoscale: false,      // => Turns autoscaling on with true
    autoscaleMargin: 0,    // => margin in % to add if auto-setting min/max
    color: null,           // => color of the ticks
    mode: 'normal',        // => can be 'time' or 'normal'
    timeFormat: null,
    timeMode:'UTC',        // => For UTC time ('local' for local time).
    timeUnit:'millisecond',// => Unit for time (millisecond, second, minute, hour, day, month, year)
    scaling: 'linear',     // => Scaling, can be 'linear' or 'logarithmic'
    base: Math.E,
    titleAlign: 'center',
    margin: true           // => Turn off margins with false
  },
  x2axis: {},
  yaxis: {
    ticks: null,           // => format: either [1, 3] or [[1, 'a'], 3]
    minorTicks: null,      // => format: either [1, 3] or [[1, 'a'], 3]
    showLabels: true,      // => setting to true will show the axis ticks labels, hide otherwise
    showMinorLabels: false,// => true to show the axis minor ticks labels, false to hide
    labelsAngle: 0,        // => labels' angle, in degrees
    title: null,           // => axis title
    titleAngle: 90,        // => axis title's angle, in degrees
    noTicks: 5,            // => number of ticks for automagically generated ticks
    minorTickFreq: null,   // => number of minor ticks between major ticks for autogenerated ticks
    tickFormatter: Flotr.defaultTickFormatter, // => fn: number, Object -> string
    tickDecimals: null,    // => no. of decimals, null means auto
    min: null,             // => min. value to show, null means set automatically
    max: null,             // => max. value to show, null means set automatically
    autoscale: false,      // => Turns autoscaling on with true
    autoscaleMargin: 0,    // => margin in % to add if auto-setting min/max
    color: null,           // => The color of the ticks
    scaling: 'linear',     // => Scaling, can be 'linear' or 'logarithmic'
    base: Math.E,
    titleAlign: 'center',
    margin: true           // => Turn off margins with false
  },
  y2axis: {
    titleAngle: 270
  },
  grid: {
    color: '#545454',      // => primary color used for outline and labels
    backgroundColor: null, // => null for transparent, else color
    backgroundImage: null, // => background image. String or object with src, left and top
    watermarkAlpha: 0.4,   // =>
    tickColor: '#DDDDDD',  // => color used for the ticks
    labelMargin: 3,        // => margin in pixels
    verticalLines: true,   // => whether to show gridlines in vertical direction
    minorVerticalLines: null, // => whether to show gridlines for minor ticks in vertical dir.
    horizontalLines: true, // => whether to show gridlines in horizontal direction
    minorHorizontalLines: null, // => whether to show gridlines for minor ticks in horizontal dir.
    outlineWidth: 1,       // => width of the grid outline/border in pixels
    outline : 'nsew',      // => walls of the outline to display
    circular: false        // => if set to true, the grid will be circular, must be used when radars are drawn
  },
  mouse: {
    track: false,          // => true to track the mouse, no tracking otherwise
    trackAll: false,
    position: 'se',        // => position of the value box (default south-east)
    relative: false,       // => next to the mouse cursor
    trackFormatter: Flotr.defaultTrackFormatter, // => formats the values in the value box
    margin: 5,             // => margin in pixels of the valuebox
    lineColor: '#FF3F19',  // => line color of points that are drawn when mouse comes near a value of a series
    trackDecimals: 1,      // => decimals for the track values
    sensibility: 2,        // => the lower this number, the more precise you have to aim to show a value
    trackY: true,          // => whether or not to track the mouse in the y axis
    radius: 3,             // => radius of the track point
    fillColor: null,       // => color to fill our select bar with only applies to bar and similar graphs (only bars for now)
    fillOpacity: 0.4       // => opacity of the fill color, set to 1 for a solid fill, 0 hides the fill
  }
};
<|endoftext|>


<commit_before>'use strict';

//global variables
var hours = ['6am', '7am', '8am', '9am', '10am', '11am', '12pm', '1pm', '2pm', '3pm', '4pm', '5pm', '6pm', '7pm', '8pm',];
var storeInfo = [];
var salesTable = document.getElementById('sales');

//CONSTRUCTOR FUNCTION
function Store(location, minCust, maxCust, avgCookieSale) {

  this.location = location;
  this.minCust = minCust;
  this.maxCust = maxCust;
  this.avgCookieSale = avgCookieSale;
  this.cookiesPerHour = [];
  this.dailySales = 0;
  storeInfo.push(this);
}

//Method using random number to calculate Customers Per Hour
Store.prototype.randomCustomers = function() {
  return (Math.random() * (this.maxCust - this.minCust + 1) + this.minCust);
  // console.log('customerph:', customersPH);
};

//Method to calculate Cookies Per Hour
Store.prototype.calcCookiesPerHour = function() {
  for (var i = 0; i < hours.length; i++) {
    // console.log('randomCustomers:', this.randomCustomers());
    this.cookiesPerHour.push(Math.floor(this.randomCustomers() * this.avgCookieSale));
    // console.log('array:', this.cookiesPerHour);
  }
};

//Method to calculate totals for each store
Store.prototype.calcTotal = function() {
  for (var i in this.cookiesPerHour) {
    this.dailySales += this.cookiesPerHour[i];
  }
};

// Method to Render function to create TD elements for table in HTML
Store.prototype.render = function() {
  // create tr element for the object
  var trEl = document.createElement('tr');
  //create and append td element to above tr for the Location Names needed on for Column
  var tdEl1 = document.createElement('td');
  tdEl1.textContent = this.location;
  trEl.appendChild(tdEl1);

  //Loop needed to populate 2nd and follow on td elements for the above tr in table
  for (var i = 0; i < hours.length; i++) {
    var tdEl = document.createElement('td');
    // give that element content
    tdEl.textContent = this.cookiesPerHour[i];
    // console.log(this.cookiesPerHour);
    // append tha element to the right spot in the DOM
    trEl.appendChild(tdEl);
  };

  // sum += this.dailySales[i];
  //Add dailySales for each store to Daily Totals Column
  tdEl = document.createElement('td');// could do th for styling purposes
  tdEl.textContent = this.dailySales;
  trEl.appendChild(tdEl);

  //add this tr to the table!
  salesTable.appendChild(trEl);
};

//function to draw header row
function makeHeaderRow() {
  // create tr
  var trEl = document.createElement('tr');

  var thEl = document.createElement('th');
  thEl.textContent = 'Store';
  trEl.appendChild(thEl);

  //for loop to create all the data td's
  for (var i in hours) {
    // create td
    thEl = document.createElement('th');
    // give td content (Name for an individual cat)
    thEl.textContent = hours[i];
    // console.log(i);
    // append the td
    trEl.appendChild(thEl);
  }
  //create and append th element to above tr for the last td to 'Display Totals'
  thEl = document.createElement('th');
  thEl.textContent = 'Daily Total';
  trEl.appendChild(thEl);

  // append the tr to the table
  salesTable.appendChild(trEl);
}

//function to calculate cookies per hour, calculate total and render
function cookiesTotalRender() {
  for(var i = 0; i < storeInfo.length; i++){
    storeInfo[i].calcCookiesPerHour();
    storeInfo[i].calcTotal();
    storeInfo[i].render();
  }
};

new Store('1st and Pike', 23, 65, 6.3);
new Store('SeaTac', 24, 65, 1.2);
new Store('Seattle Center', 38, 65, 3.7);
new Store('Capitol Hill', 38, 65, 2.3);
new Store('Alki', 23, 16, 4.6);

makeHeaderRow();
cookiesTotalRender();
<commit_msg>changed some columns to 'th' elements for styling purposes.<commit_after>'use strict';

//global variables
var hours = ['6am', '7am', '8am', '9am', '10am', '11am', '12pm', '1pm', '2pm', '3pm', '4pm', '5pm', '6pm', '7pm', '8pm',];
var storeInfo = [];
var salesTable = document.getElementById('sales');

//CONSTRUCTOR FUNCTION
function Store(location, minCust, maxCust, avgCookieSale) {

  this.location = location;
  this.minCust = minCust;
  this.maxCust = maxCust;
  this.avgCookieSale = avgCookieSale;
  this.cookiesPerHour = [];
  this.dailySales = 0;
  storeInfo.push(this);
}

//Method using random number to calculate Customers Per Hour
Store.prototype.randomCustomers = function() {
  return (Math.random() * (this.maxCust - this.minCust + 1) + this.minCust);
  // console.log('customerph:', customersPH);
};

//Method to calculate Cookies Per Hour
Store.prototype.calcCookiesPerHour = function() {
  for (var i = 0; i < hours.length; i++) {
    // console.log('randomCustomers:', this.randomCustomers());
    this.cookiesPerHour.push(Math.floor(this.randomCustomers() * this.avgCookieSale));
    // console.log('array:', this.cookiesPerHour);
  }
};

//Method to calculate totals for each store
Store.prototype.calcTotal = function() {
  for (var i in this.cookiesPerHour) {
    this.dailySales += this.cookiesPerHour[i];
  }
};

// Method to Render function to create TD elements for table in HTML
Store.prototype.render = function() {
  // create tr element for the object
  var trEl = document.createElement('tr');
  //create and append td element to above tr for the Location Names needed on for Column
  var thEl = document.createElement('th');
  thEl.textContent = this.location;
  trEl.appendChild(thEl);

  //Loop needed to populate 2nd and follow on td elements for the above tr in table
  for (var i = 0; i < hours.length; i++) {
    var tdEl = document.createElement('td');
    // give that element content
    tdEl.textContent = this.cookiesPerHour[i];
    // console.log(this.cookiesPerHour);
    // append tha element to the right spot in the DOM
    trEl.appendChild(tdEl);
  };

  // sum += this.dailySales[i];
  //Add dailySales for each store to Daily Totals Column
  thEl = document.createElement('th');// could do th for styling purposes
  thEl.textContent = this.dailySales;
  trEl.appendChild(thEl);

  //add this tr to the table!
  salesTable.appendChild(trEl);
};

//function to draw header row
function makeHeaderRow() {
  // create tr
  var trEl = document.createElement('tr');

  var thEl = document.createElement('th');
  thEl.textContent = 'Store';
  trEl.appendChild(thEl);

  //for loop to create all the data td's
  for (var i in hours) {
    // create td
    thEl = document.createElement('th');
    // give td content (Name for an individual cat)
    thEl.textContent = hours[i];
    // console.log(i);
    // append the td
    trEl.appendChild(thEl);
  }
  //create and append th element to above tr for the last td to 'Display Totals'
  thEl = document.createElement('th');
  thEl.textContent = 'Daily Total';
  trEl.appendChild(thEl);

  // append the tr to the table
  salesTable.appendChild(trEl);
}

//function to calculate cookies per hour, calculate total and render
function cookiesTotalRender() {
  for(var i = 0; i < storeInfo.length; i++){
    storeInfo[i].calcCookiesPerHour();
    storeInfo[i].calcTotal();
    storeInfo[i].render();
  }
};

new Store('1st and Pike', 23, 65, 6.3);
new Store('SeaTac', 24, 65, 1.2);
new Store('Seattle Center', 38, 65, 3.7);
new Store('Capitol Hill', 38, 65, 2.3);
new Store('Alki', 23, 16, 4.6);

makeHeaderRow();
cookiesTotalRender();
<|endoftext|>


<commit_before>/*global jQuery, $, _, AjaxSolr, EUMSSI, CONF, UTIL */
(function(callback){
	if (typeof define === 'function' && define.amd) {
		define(['core/AbstractManager'], callback);
	} else {
		callback();
	}
}(function(){

	/**
	 * @see http://wiki.apache.org/solr/SolJSON#JSON_specific_parameters
	 * @class Manager
	 * @augments AjaxSolr.AbstractManager
	 */
	AjaxSolr.Manager = AjaxSolr.AbstractManager.extend(/** @lends AjaxSolr.Manager.prototype */
		{
			//Transversal Flag
			// Pagination Request Flag, true if the request is maded from paginator
			flag_PaginationRequest: false, //// When click to filter by some Facet maintains the rest only update the number of times
			//flag_TagFacetRequest : false,
			//// When click to filter by some Country on MapChartWidget
			//flag_MapChartRequest : false,

			// The fields that solr has indexed, must be fetched on start.
			_solrFields : [],

			/**
			 * Custom REQUEST execution for jQuery
			 * @param servlet
			 * @param string
			 * @param handler
			 * @param errorHandler
			 */
			executeRequest: function(servlet, string, handler, errorHandler){
				var self = this, options = {dataType: 'json'};
				this._regenFilter();
				string = string || this.store.string();

				handler = handler || function(data){
					self.handleResponse(data);
				};

				errorHandler = errorHandler || function(jqXHR, textStatus, errorThrown){
					self.handleError(textStatus + ', ' + errorThrown);
				};

				if (this.proxyUrl) {
					options.url = this.proxyUrl;
					options.data = {query: string};
					options.type = 'POST';
				} else {
					//ORIGINAL
					// options.url = this.solrUrl + servlet + '?' + string + '&wt=json&json.wrf=?';
					//MINE - problems with json.wrf param
					options.url = this.solrUrl + servlet + '?' + string + '&wt=json';
					options.headers = {Origin: undefined};
				}

				this._showLoader();
				jQuery.ajax(options).done(handler).fail(errorHandler).always(this._hideLoader.bind(this));
			},

			/**
			 * Refresh the Filter query
			 * @private
			 */
			_regenFilter: function(){
				var q = EUMSSI.FilterManager.getQueryString();
				var fq = EUMSSI.FilterManager.getFilterQueryString();

				this.store.addByValue("q",q);
				this._lastq = q;

				this.store.removeByValue("fq",this._lastfq);
				if(fq.length > 0){
					this.store.addByValue("fq",fq);
					this._lastfq = fq;
				} else {
					this._lastfq = "";
				}
			},

			/**
			 * Fetch the current indexed fields on Solr
			 * and save it in Manager._solrFields
			 */
			retrieveSolrFieldsNames: function(){
				$.ajax({
					url: this.solrUrl + this.servlet + '?' + "q=*%3A*&rows=0&wt=csv&indent=true",
					success: function(response){
						this._solrFields = response.split(",").sort();
					}.bind(this)
				});
			},

			/**
			 * Obtain the Segments of the given Item
			 * @param parentId
			 */
			getSegmentsByParentId: function(parentId){
				var url = this.segmentsCoreUrl +
					this.servlet + '?' +
					"q=" + this.getLastQuery() +
					"&wt=json&indent=true" +
					"&rows=15&fq=parent_id%3A"+AjaxSolr.Parameter.escapeValue(parentId);
				return $.ajax({
					url: url,
					success: function(response){
						this._solrFields = response.split(",").sort();
					}.bind(this)
				});
			},

			/**
			 * Retrieve Tweets with the current Query
			 * @param {number} [start=0] - The current page start index for the current search.
			 * @param {string} [order=desc] - Sort for the Solr.
			 * @param {number} [gapsize=10] - The paginagion gap size.
			 * @returns {*}
			 */
			getTweets: function(start, order, gapsize){
				var url = this.solrUrl + this.servlet + '?';
				var sort = "meta.extracted.text.polarity.numeric " + (order || "desc");
				var discretePolarity = !!order ? "NEGATIVE" : "POSITIVE";
				var params = {
					q : this.getLastQuery(),
					//For the moment only retrieve the NEGATIVE OR POSITIVE excluding NEUTRAL
					fq : "meta.source.tweetId:* AND meta.extracted.text.polarity.numeric:* AND meta.extracted.text.polarity.discrete:\"" + discretePolarity +"\"",
					sort : sort,
					wt : "json",
					ident : "true",
					rows: (gapsize || 10),		// pageSize
					start: (start || 0)			// paginationGap start
				};
				return $.ajax({ url: url + $.param(params) });
			},

			_showLoader: function(){
				$(".result-panel-content").addClass("ui-loading-modal");
			},

			_hideLoader: function(){
				$(".result-panel-content").removeClass("ui-loading-modal");
			},

			/* Filter Interface  */
			addFilter: function(filterName, query, widgetId, filterText){
				EUMSSI.FilterManager.addFilter(filterName, query, widgetId, filterText);
			},

			removeFilterByName: function(filterName, widgetId){
				EUMSSI.FilterManager.removeFilterByName(filterName, widgetId);
			},

			removeFilterByWidget: function(widgetId){
				EUMSSI.FilterManager.removeFilterByWidget(widgetId);
			},

			getLastFilterQuery: function(){
				return this._lastfq || "";
			},

			getLastQuery: function(){
				return this._lastq || "*:*";
			}

		});

}));
<commit_msg>Polarity Widget, update sorting fields fix.<commit_after>/*global jQuery, $, _, AjaxSolr, EUMSSI, CONF, UTIL */
(function(callback){
	if (typeof define === 'function' && define.amd) {
		define(['core/AbstractManager'], callback);
	} else {
		callback();
	}
}(function(){

	/**
	 * @see http://wiki.apache.org/solr/SolJSON#JSON_specific_parameters
	 * @class Manager
	 * @augments AjaxSolr.AbstractManager
	 */
	AjaxSolr.Manager = AjaxSolr.AbstractManager.extend(/** @lends AjaxSolr.Manager.prototype */
		{
			//Transversal Flag
			// Pagination Request Flag, true if the request is maded from paginator
			flag_PaginationRequest: false, //// When click to filter by some Facet maintains the rest only update the number of times
			//flag_TagFacetRequest : false,
			//// When click to filter by some Country on MapChartWidget
			//flag_MapChartRequest : false,

			// The fields that solr has indexed, must be fetched on start.
			_solrFields : [],

			/**
			 * Custom REQUEST execution for jQuery
			 * @param servlet
			 * @param string
			 * @param handler
			 * @param errorHandler
			 */
			executeRequest: function(servlet, string, handler, errorHandler){
				var self = this, options = {dataType: 'json'};
				this._regenFilter();
				string = string || this.store.string();

				handler = handler || function(data){
					self.handleResponse(data);
				};

				errorHandler = errorHandler || function(jqXHR, textStatus, errorThrown){
					self.handleError(textStatus + ', ' + errorThrown);
				};

				if (this.proxyUrl) {
					options.url = this.proxyUrl;
					options.data = {query: string};
					options.type = 'POST';
				} else {
					//ORIGINAL
					// options.url = this.solrUrl + servlet + '?' + string + '&wt=json&json.wrf=?';
					//MINE - problems with json.wrf param
					options.url = this.solrUrl + servlet + '?' + string + '&wt=json';
					options.headers = {Origin: undefined};
				}

				this._showLoader();
				jQuery.ajax(options).done(handler).fail(errorHandler).always(this._hideLoader.bind(this));
			},

			/**
			 * Refresh the Filter query
			 * @private
			 */
			_regenFilter: function(){
				var q = EUMSSI.FilterManager.getQueryString();
				var fq = EUMSSI.FilterManager.getFilterQueryString();

				this.store.addByValue("q",q);
				this._lastq = q;

				this.store.removeByValue("fq",this._lastfq);
				if(fq.length > 0){
					this.store.addByValue("fq",fq);
					this._lastfq = fq;
				} else {
					this._lastfq = "";
				}
			},

			/**
			 * Fetch the current indexed fields on Solr
			 * and save it in Manager._solrFields
			 */
			retrieveSolrFieldsNames: function(){
				$.ajax({
					url: this.solrUrl + this.servlet + '?' + "q=*%3A*&rows=0&wt=csv&indent=true",
					success: function(response){
						this._solrFields = response.split(",").sort();
					}.bind(this)
				});
			},

			/**
			 * Obtain the Segments of the given Item
			 * @param parentId
			 */
			getSegmentsByParentId: function(parentId){
				var url = this.segmentsCoreUrl +
					this.servlet + '?' +
					"q=" + this.getLastQuery() +
					"&wt=json&indent=true" +
					"&rows=15&fq=parent_id%3A"+AjaxSolr.Parameter.escapeValue(parentId);
				return $.ajax({
					url: url,
					success: function(response){
						this._solrFields = response.split(",").sort();
					}.bind(this)
				});
			},

			/**
			 * Retrieve Tweets with the current Query
			 * @param {number} [start=0] - The current page start index for the current search.
			 * @param {string} [order=desc] - Sort for the Solr.
			 * @param {number} [gapsize=10] - The paginagion gap size.
			 * @returns {*}
			 */
			getTweets: function(start, order, gapsize){
				var url = this.solrUrl + this.servlet + '?';
				var sort = "meta.extracted.text.polarity.numeric " + (order || "desc");
				var discretePolarity = order === "asc" ? "NEGATIVE" : "POSITIVE";
				var params = {
					q : this.getLastQuery(),
					//For the moment only retrieve the NEGATIVE OR POSITIVE excluding NEUTRAL
					fq : "meta.source.tweetId:* AND meta.extracted.text.polarity.numeric:* AND meta.extracted.text.polarity.discrete:\"" + discretePolarity +"\"",
					sort : sort,
					wt : "json",
					ident : "true",
					rows: (gapsize || 10),		// pageSize
					start: (start || 0)			// paginationGap start
				};
				return $.ajax({ url: url + $.param(params) });
			},

			_showLoader: function(){
				$(".result-panel-content").addClass("ui-loading-modal");
			},

			_hideLoader: function(){
				$(".result-panel-content").removeClass("ui-loading-modal");
			},

			/* Filter Interface  */
			addFilter: function(filterName, query, widgetId, filterText){
				EUMSSI.FilterManager.addFilter(filterName, query, widgetId, filterText);
			},

			removeFilterByName: function(filterName, widgetId){
				EUMSSI.FilterManager.removeFilterByName(filterName, widgetId);
			},

			removeFilterByWidget: function(widgetId){
				EUMSSI.FilterManager.removeFilterByWidget(widgetId);
			},

			getLastFilterQuery: function(){
				return this._lastfq || "";
			},

			getLastQuery: function(){
				return this._lastq || "*:*";
			}

		});

}));
<|endoftext|>


<commit_before>/*
* Copyright 2015 CareerBuilder, LLC
* Licensed 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 express    = require('express'); 		// call express
var https      = require('https');
var fs         = require('fs');
var bodyParser = require('body-parser');
var path       = require('path');
var favicon    = require('serve-favicon');
global.config  = require('./config.json');
var app        = express(); 			// define our app using express

app.set('view engine','html');
app.engine('html', require('ejs').renderFile);
app.use(express.static(path.join(__dirname, 'client')));
app.set('views', __dirname + '/client/views');
app.use(bodyParser.json({limit: '50mb'}));
app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));
app.use(favicon(__dirname + '/favicon.ico'));

var port = 3000;

// ROUTES FOR OUR API
// =============================================================================
//

app.get('/', function(req, res){
  res.render('index');
});

app.use('/api/', require('./routes/api.js'));

//keep this last, as it will return 404
app.use(function(req, res, next){
  res.status(404);
  // respond with html page
  if (req.accepts('html')) {
    return res.render('404', { url: req.url });
  }
  // respond with json
  if (req.accepts('json')) {
    return res.send({Error: 'Not a valid endpoint'});
  }
  // default to plain-text. send()
  return res.type('txt').send('Not found');
});

if('SSL' in global.config){
  var config = {
    key: fs.readFileSync(global.config.SSL.keyfile),
   cert: fs.readFileSync(global.config.SSL.certfile)
  };
  https.createServer(config, app).listen(port);
}
else{
  app.listen(port);
}
console.log('Magic happens on port ' + port);
<commit_msg>test out http redirect<commit_after>/*
* Copyright 2015 CareerBuilder, LLC
* Licensed 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 express    = require('express'); 		// call express
var https      = require('https');
var fs         = require('fs');
var bodyParser = require('body-parser');
var path       = require('path');
var favicon    = require('serve-favicon');
global.config  = require('./config.json');
var app        = express(); 			// define our app using express

app.set('view engine','html');
app.engine('html', require('ejs').renderFile);
app.use(express.static(path.join(__dirname, 'client')));
app.set('views', __dirname + '/client/views');
app.use(bodyParser.json({limit: '50mb'}));
app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));
app.use(favicon(__dirname + '/favicon.ico'));

var httpport = 3000;
var httpsport = 3001;

// ROUTES FOR OUR API
// =============================================================================
//

app.get('/', function(req, res){
  res.render('index');
});

app.use('/api/', require('./routes/api.js'));

//keep this last, as it will return 404
app.use(function(req, res, next){
  res.status(404);
  // respond with html page
  if (req.accepts('html')) {
    return res.render('404', { url: req.url });
  }
  // respond with json
  if (req.accepts('json')) {
    return res.send({Error: 'Not a valid endpoint'});
  }
  // default to plain-text. send()
  return res.type('txt').send('Not found');
});

if('SSL' in global.config){
  var config = {
    key: fs.readFileSync(global.config.SSL.keyfile),
   cert: fs.readFileSync(global.config.SSL.certfile)
  };
  https.createServer(config, app).listen(httpsport);
  console.log('Magic happens on port ' + httpsport);
  var redir = express();
  redir.use(function(req, res, next){
    return res.redirect('https://'+req.hostname+req.url);
  });
  redir.listen(httpport);
}
else{
  app.listen(httpport);
  console.log('Magic happens on port ' + httpport);
}
<|endoftext|>