<commit_before>angular.module('palladioAlluvial', ['palladio', 'palladio.services'])
	.run(['componentService', function(componentService) {
		var compileStringFunction = function (newScope, options) {

			newScope.dimensions = newScope.dimensions ? newScope.dimensions : [];
			newScope.height = newScope.height ? newScope.height : 400;

			var compileString = '

';

			return compileString;
		};

		componentService.register('alluvial', compileStringFunction);
	}])
	.directive('palladioAlluvial', function (palladioService, dataService) {
		return {
			scope : {
				dimensions: '=',
				chartHeight: '='
			},
			template : '

',
			link : {
				pre : function(scope, element) {

				},

				post : function(scope, element, attrs) {
					var margin = 5;
					var columnWidth = 20;
					var numValues = 30;

					var xfilter = dataService.getDataSync().xfilter;
					var dimKeys = scope.dimensions.map(function(d) { return d.key; });
					var dimensions = dataService.getDataSync().metadata.filter(function(d) {
						return dimKeys.indexOf(d.key) > -1;
					}).map(function(k) {
						return xfilter.dimension(function(d) { return d[k.key]; });
					});

					var countKey = dataService.getDataSync().metadata.filter(function (d) { return d.countable === true; })[0].key;

					var reducer = reductio().exception(function(d) { return d[countKey]; }).exceptionCount(true);
					var groups = dimensions.map(function(d) {
						return reducer(d.group())
							.order(function(d) { return d.exceptionCount; });
					});

					var linkKeys = [];
					dimKeys.forEach(function(d, i) {
						if(i < dimKeys.length-1) {
							linkKeys.push([d, dimKeys[i+1]]);
						}
					});
					var linkDimensions = linkKeys.map(function(k) {
						return xfilter.dimension(function(d) { return [d[k[0]], d[k[1]]]; });
					});
					var linkGroups = linkDimensions.map(function(d) {
						return reducer(d.group());
					});

					function addCounts(array) {
						return array.reduce(function(a,b) {
							return a + b.value.exceptionCount;
						}, 0);
					}

					function buildOffset(array, initial, attr, adj) {
						attr = attr ? attr : 'offset';
						adj = adj ? adj : 1;
						var offset = initial ? initial : 0;
						array.forEach(function(d) {
							d.value[attr] = offset;
							offset += d.value.exceptionCount * adj;
						});
						return array;
					}

					function buildOther(array, total) {
						var exceptionCount = addCounts(array);
						if(total-exceptionCount > 0) {
							array.pop(); // Remove last element so we have a constant # of elements
							array.push({
								key: "Other (generated)",
								value: {
									exceptionCount: total - addCounts(array),
								}
							});
						}
						return array;
					}

					var columnOffsetScale = d3.scale.linear()
							.domain([0, groups.length - 1])
							.range([0 + margin, 1000 - margin*2 - columnWidth]);

					var columnTotals, columnScales, dataGroups, linkMaps, dataLinks;

					var calcData = function() {
						columnTotals = groups.map(function(g) {
							return addCounts(g.all());
						});

						columnScales = columnTotals.map(function(d) {
							return d3.scale.linear()
								.domain([0,d])
								.range([0, scope.chartHeight - margin*2]);
						});

						dataGroups = groups.map(function(d, i) {
							var top = d.top(numValues);
							var length = top.length;
							return buildOffset(buildOther(top, columnTotals[i])).map(function(h) { h.index = i; h.length = length; return h; });
						});

						linkMaps = linkGroups.map(function() { return d3.map(); });
						linkGroups.forEach(function(g,i) {
							g.all().forEach(function(d) {
								linkMaps[i].set(d.key, d);
							});
						});

						dataLinks = linkGroups.map(function(d,i) {
							var startKeys = dataGroups[i].map(function(c) { return { key: c.key, value: c.value.exceptionCount, offset: c.value.offset }; });
							var endKeys = dataGroups[i+1].map(function(c) { return { key: c.key, value: c.value.exceptionCount, offset: c.value.offset }; });

							var links = [];

							startKeys.forEach(function(sk) {
								var nodeLinks = [];

								endKeys.forEach(function(ek) {
									// Not all possible links actually exist
									if(linkMaps[i].has([sk.key,ek.key])) {
										nodeLinks.push(linkMaps[i].get([sk.key,ek.key]));
									}
								});

								nodeLinks.sort(function(a,b) { return b.value.exceptionCount - a.value.exceptionCount; });
								var totalLinks = addCounts(nodeLinks);
								var adj = 1;
								if(totalLinks > sk.value) {
									adj = sk.value / totalLinks;
								}
								nodeLinks.forEach(function(d) { d.value.sAdj = adj; });

								buildOffset(nodeLinks, sk.offset, 'sOffset', adj);
								links = links.concat(nodeLinks);
							});

							endKeys.forEach(function(ek) {
								var nodeLinks = [];

								startKeys.forEach(function(sk) {
									if(linkMaps[i].has([sk.key, ek.key])){
										nodeLinks.push(linkMaps[i].get([sk.key,ek.key]));
									}
								});

								nodeLinks.sort(function(a,b) { return b.value.exceptionCount - a.value.exceptionCount; });

								var totalLinks = addCounts(nodeLinks);
								var adj = 1;
								if(totalLinks > ek.value) {
									adj = ek.value / totalLinks;
								}
								nodeLinks.forEach(function(d) { d.value.tAdj = adj; });

								buildOffset(nodeLinks, ek.offset, 'tOffset', adj);

								// Filter out links that are already recorded so we don't double-add.
								nodeLinks.filter(function(d) { return links.indexOf(d) !== -1; });

								links = links.concat(nodeLinks);
							});

							links.forEach(function(d) { d.index = i; });

							return links;
						});
					};

					calcData();

					element.height(scope.chartHeight);

					var nodes, links;

					var svg = d3.select(element[0]).append('svg');
					svg.attr('height', scope.chartHeight);
					svg.attr('width', '100%');

					var g = svg.append('g')
							.attr('transform', 'translate(5,5)');

					var columns = g.selectAll('.column')
							.data(dataGroups);

					columns.enter()
						.append('g')
							.attr('class', 'column');

					var linkColumns = g.selectAll('.link-column')
							.data(linkKeys);

					linkColumns.enter()
						.append('g')
							.attr('class', 'link-column');

					var curvature = 0.5;
					var linkWidth = columnOffsetScale(2) - columnOffsetScale(1) - columnWidth - 4;
					function link(d) {
						var x0 = 0,
							x1 = linkWidth,
							xi = d3.interpolateNumber(x0, x1),
							x2 = xi(curvature),
							x3 = xi(1 - curvature),
							sy0 = columnScales[d.index](d.value.sOffset),
							ty1 = columnScales[d.index+1](d.value.tOffset),
							sy2 = columnScales[d.index](d.value.sOffset) + columnScales[d.index](d.value.exceptionCount * d.value.sAdj)-1,
							ty3 = columnScales[d.index+1](d.value.tOffset) + columnScales[d.index+1](d.value.exceptionCount * d.value.tAdj)-1;
						return "M" + x0 + "," + sy0 +
							"C" + x2 + "," + sy0 +
							" " + x3 + "," + ty1 +
							" " + x1 + "," + ty1 +
							"L" + x1 + "," + ty3 +
							"C" + x3 + "," + ty3 +
							" " + x2 + "," + sy2 +
							" " + x0 + "," + sy2;
					}

					var nodeTip = d3.tip()
							.offset([-10, 0])
							.attr("class","d3-tip")
							.html(function(d){ return d.key + ' (' + d.value.exceptionCount + ')'; });

					var linkTipLeft = d3.tip()
							.offset(function(d) {
								if(columnScales[d.index+1](d.value.tOffset) < columnScales[d.index](d.value.sOffset)) {
									return [columnScales[d.index](d.value.sOffset)-columnScales[d.index+1](d.value.tOffset)-10, -(columnOffsetScale(1) - columnOffsetScale(0))/2 + columnWidth];
								} else {
									return [-10, -(columnOffsetScale(1) - columnOffsetScale(0))/2 + columnWidth];
								}
							})
							.attr("class","d3-tip")
							.html(function(d){ return d.key[0] + ' (' + d.value.exceptionCount + ')'; });

					var linkTipRight = d3.tip()
							.offset(function(d) {
								if(columnScales[d.index+1](d.value.tOffset) > columnScales[d.index](d.value.sOffset)) {
									return [columnScales[d.index+1](d.value.tOffset)-columnScales[d.index](d.value.sOffset)-10, (columnOffsetScale(1) - columnOffsetScale(0))/2 - columnWidth];
								} else {
									return [-10, (columnOffsetScale(1) - columnOffsetScale(0))/2 - columnWidth];
								}
							})
							.attr("class","d3-tip")
							.html(function(d){ return d.key[1] + ' (' + d.value.exceptionCount + ')'; });

					svg.call(nodeTip);
					svg.call(linkTipLeft);
					svg.call(linkTipRight);

					var update = function() {
						calcData();

						nodes = columns.selectAll('.node')
							.data(function(d, i) { return dataGroups[i].filter(function(d) { return d.value.exceptionCount > 0; }); },
									function(d, i) { return i + d.key; });

						nodes.enter()
							.append('rect')
								.attr('class', 'node')
								.attr('width', '20px')
								.attr('fill', '#dddddd')
								.on('mouseover', function(d) {
									nodeTip.show(d);
									d3.select(this)
										.attr('fill', '#bbbbbb');
									links.filter(function(l) {
										return l.index === d.index && l.key[0] === d.key;
									}).attr('fill', '#bbbbbb');
									links.filter(function(l) {
										return l.index === d.index-1 && l.key[1] === d.key;
									}).attr('fill', '#bbbbbb');
								})
								.on('mouseout', function(d) {
									nodeTip.hide(d);
									d3.select(this)
										.attr('fill', '#dddddd');
									links.filter(function(l) {
										return l.index === d.index && l.key[0] === d.key;
									}).attr('fill', '#dddddd');
									links.filter(function(l) {
										return l.index === d.index-1 && l.key[1] === d.key;
									}).attr('fill', '#dddddd');
								});

						nodes.exit().remove();

						links = linkColumns.selectAll('.link')
								.data(function(d, i) {
									return dataLinks[i].filter(function(d) { return d.value.exceptionCount > 0; });
								}, function(d, i) { return i + d.key.join(); });

						links.enter()
							.append('path')
								.attr('class', 'link')
								.style('opacity', "0.5")
								.attr('fill', '#dddddd')
							.on('mouseover', function(d) {
								linkTipLeft.show(d);
								linkTipRight.show(d);
								d3.select(this)
									.attr('fill', "#bbbbbb");
							})
							.on('mouseout', function(d) {
								linkTipLeft.hide(d);
								linkTipRight.hide(d);
								d3.select(this)
									.attr('fill', "#dddddd");
							});

						links.exit().remove();

						columns.attr('transform', function(d, i) { return 'translate(' + columnOffsetScale(i) + ',0)'; });

						linkColumns.attr('transform', function(d, i) { return 'translate(' + (columnOffsetScale(i)+columnWidth+2) + ',0)'; });

						nodes.transition()
								.attr('height', function(d, i) {
									if(d.value.exceptionCount > 0) {
										if(i < d.length-1) {
											return columnScales[d.index](d.value.exceptionCount)-1;
										} else {
											return columnScales[d.index](d.value.exceptionCount);
										}
									}
								})
							.transition()
								.attr('transform', function (d) { return 'translate(0,' + columnScales[d.index](d.value.offset) + ')'; });

						links.attr('d', link);
					};

					update();

					palladioService.onUpdate('alluvial', update);
				}
			}
		};
	});
<commit_msg>Headers, improved animation indices, improved fill colors<commit_after>angular.module('palladioAlluvial', ['palladio', 'palladio.services'])
	.run(['componentService', function(componentService) {
		var compileStringFunction = function (newScope, options) {

			newScope.dimensions = newScope.dimensions ? newScope.dimensions : [];
			newScope.height = newScope.height ? newScope.height : 400;

			var compileString = '

';

			return compileString;
		};

		componentService.register('alluvial', compileStringFunction);
	}])
	.directive('palladioAlluvial', function (palladioService, dataService) {
		return {
			scope : {
				dimensions: '=',
				chartHeight: '='
			},
			template : '

',
			link : {
				pre : function(scope, element) {

				},

				post : function(scope, element, attrs) {
					var margin = 5;
					var marginTop = 15;
					var columnWidth = 20;
					var numValues = 30;
					var headerSpace = 20;
					var nodeFill = '#aaaaaa';
					var nodeMouseOver = '#888888';
					var linkFill = '#dddddd';
					var linkMouseOver = '#bbbbbb';

					var xfilter = dataService.getDataSync().xfilter;
					var metadata = dataService.getDataSync().metadata;
					var dimKeys = scope.dimensions.map(function(d) { return d.key; });
					var dimDescs = scope.dimensions.map(function(d) { return d.description; });
					var dimensions = scope.dimensions.map(function(k) {
						return xfilter.dimension(function(d) { return d[k.key]; });
					});

					var countKey = dataService.getDataSync().metadata.filter(function (d) { return d.countable === true; })[0].key;

					var reducer = reductio().exception(function(d) { return d[countKey]; }).exceptionCount(true);
					var groups = dimensions.map(function(d) {
						return reducer(d.group())
							.order(function(d) { return d.exceptionCount; });
					});

					var linkKeys = [];
					dimKeys.forEach(function(d, i) {
						if(i < dimKeys.length-1) {
							linkKeys.push([d, dimKeys[i+1]]);
						}
					});
					var linkDimensions = linkKeys.map(function(k) {
						return xfilter.dimension(function(d) { return [d[k[0]], d[k[1]]]; });
					});
					var linkGroups = linkDimensions.map(function(d) {
						return reducer(d.group());
					});

					function addCounts(array) {
						return array.reduce(function(a,b) {
							return a + b.value.exceptionCount;
						}, 0);
					}

					function buildOffset(array, initial, attr, adj) {
						attr = attr ? attr : 'offset';
						adj = adj ? adj : 1;
						var offset = initial ? initial : 0;
						array.forEach(function(d) {
							d.value[attr] = offset;
							offset += d.value.exceptionCount * adj;
						});
						return array;
					}

					function buildOther(array, total) {
						var exceptionCount = addCounts(array);
						if(total-exceptionCount > 0) {
							array.pop(); // Remove last element so we have a constant # of elements
							array.push({
								key: "Other (generated)",
								value: {
									exceptionCount: total - addCounts(array),
								}
							});
						}
						return array;
					}

					var columnOffsetScale = d3.scale.linear()
							.domain([0, groups.length - 1])
							.range([0 + margin, 1000 - margin*2 - columnWidth]);

					var columnTotals, columnScales, dataGroups, linkMaps, dataLinks;

					var calcData = function() {
						columnTotals = groups.map(function(g) {
							return addCounts(g.all());
						});

						columnScales = columnTotals.map(function(d) {
							return d3.scale.linear()
								.domain([0,d])
								.range([0, scope.chartHeight - headerSpace - margin - marginTop]);
						});

						dataGroups = groups.map(function(d, i) {
							var top = d.top(numValues);
							var length = top.length;
							return buildOffset(buildOther(top, columnTotals[i])).map(function(h) { h.index = i; h.length = length; return h; });
						});

						linkMaps = linkGroups.map(function() { return d3.map(); });
						linkGroups.forEach(function(g,i) {
							g.all().forEach(function(d) {
								linkMaps[i].set(d.key, d);
							});
						});

						dataLinks = linkGroups.map(function(d,i) {
							var startKeys = dataGroups[i].map(function(c) { return { key: c.key, value: c.value.exceptionCount, offset: c.value.offset }; });
							var endKeys = dataGroups[i+1].map(function(c) { return { key: c.key, value: c.value.exceptionCount, offset: c.value.offset }; });

							var links = [];

							startKeys.forEach(function(sk) {
								var nodeLinks = [];

								endKeys.forEach(function(ek) {
									// Not all possible links actually exist
									if(linkMaps[i].has([sk.key,ek.key])) {
										nodeLinks.push(linkMaps[i].get([sk.key,ek.key]));
									}
								});

								nodeLinks.sort(function(a,b) { return b.value.exceptionCount - a.value.exceptionCount; });
								var totalLinks = addCounts(nodeLinks);
								var adj = 1;
								if(totalLinks > sk.value) {
									adj = sk.value / totalLinks;
								}
								nodeLinks.forEach(function(d) { d.value.sAdj = adj; });

								buildOffset(nodeLinks, sk.offset, 'sOffset', adj);
								links = links.concat(nodeLinks);
							});

							endKeys.forEach(function(ek) {
								var nodeLinks = [];

								startKeys.forEach(function(sk) {
									if(linkMaps[i].has([sk.key, ek.key])){
										nodeLinks.push(linkMaps[i].get([sk.key,ek.key]));
									}
								});

								nodeLinks.sort(function(a,b) { return b.value.exceptionCount - a.value.exceptionCount; });

								var totalLinks = addCounts(nodeLinks);
								var adj = 1;
								if(totalLinks > ek.value) {
									adj = ek.value / totalLinks;
								}
								nodeLinks.forEach(function(d) { d.value.tAdj = adj; });

								buildOffset(nodeLinks, ek.offset, 'tOffset', adj);

								// Filter out links that are already recorded so we don't double-add.
								nodeLinks.filter(function(d) { return links.indexOf(d) !== -1; });

								links = links.concat(nodeLinks);
							});

							links.forEach(function(d) { d.index = i; });

							return links;
						});
					};

					calcData();

					element.height(scope.chartHeight);

					var nodes, links;

					var svg = d3.select(element[0]).append('svg');
					svg.attr('height', scope.chartHeight);
					svg.attr('width', '100%');

					var enclosure = svg.append('g')
							.attr('transform', 'translate(5,20)');

					var headers = enclosure.selectAll('.column-header')
							.data(dimDescs);
					headers.enter()
						.append('text')
							.attr('class', 'column-header')
							.text(function(d) { return d; })
							.style('font-size', '12px');

					// Do once everything is rendered - because reasons???
					setTimeout(function(){
						headers
							.attr('transform', function(d, i) {
								if(i === 0) {
									// First
									return 'translate(' + columnOffsetScale(i) + ',10)';
								} else if(i === dimDescs.length-1) {
									// Last
									return 'translate(' + (columnOffsetScale(i) - this.getBBox().width + columnWidth) + ',10)';
								} else {
									// Middle
									return 'translate(' + (columnOffsetScale(i) - this.getBBox().width/2 + columnWidth/2) + ',10)';
								}
							});
					},0);

					var g = enclosure.append('g')
							.attr('transform', 'translate(0,' + headerSpace + ')');

					var columns = g.selectAll('.column')
							.data(dataGroups);

					columns.enter()
						.append('g')
							.attr('class', 'column');

					var linkColumns = g.selectAll('.link-column')
							.data(linkKeys);

					linkColumns.enter()
						.append('g')
							.attr('class', 'link-column');

					var curvature = 0.5;
					var linkWidth = columnOffsetScale(2) - columnOffsetScale(1) - columnWidth - 4;
					function link(d) {
						var x0 = 0,
							x1 = linkWidth,
							xi = d3.interpolateNumber(x0, x1),
							x2 = xi(curvature),
							x3 = xi(1 - curvature),
							sy0 = columnScales[d.index](d.value.sOffset),
							ty1 = columnScales[d.index+1](d.value.tOffset),
							sy2 = columnScales[d.index](d.value.sOffset) + columnScales[d.index](d.value.exceptionCount * d.value.sAdj)-1,
							ty3 = columnScales[d.index+1](d.value.tOffset) + columnScales[d.index+1](d.value.exceptionCount * d.value.tAdj)-1;
						return "M" + x0 + "," + sy0 +
							"C" + x2 + "," + sy0 +
							" " + x3 + "," + ty1 +
							" " + x1 + "," + ty1 +
							"L" + x1 + "," + ty3 +
							"C" + x3 + "," + ty3 +
							" " + x2 + "," + sy2 +
							" " + x0 + "," + sy2;
					}

					var nodeTip = d3.tip()
							.offset([-10, 0])
							.attr("class","d3-tip")
							.html(function(d){ return d.key + ' (' + d.value.exceptionCount + ')'; });

					var linkTipLeft = d3.tip()
							.offset(function(d) {
								if(columnScales[d.index+1](d.value.tOffset) < columnScales[d.index](d.value.sOffset)) {
									return [columnScales[d.index](d.value.sOffset)-columnScales[d.index+1](d.value.tOffset)-10, -(columnOffsetScale(1) - columnOffsetScale(0))/2 + columnWidth];
								} else {
									return [-10, -(columnOffsetScale(1) - columnOffsetScale(0))/2 + columnWidth];
								}
							})
							.attr("class","d3-tip")
							.html(function(d){ return d.key[0] + ' (' + d.value.exceptionCount + ')'; });

					var linkTipRight = d3.tip()
							.offset(function(d) {
								if(columnScales[d.index+1](d.value.tOffset) > columnScales[d.index](d.value.sOffset)) {
									return [columnScales[d.index+1](d.value.tOffset)-columnScales[d.index](d.value.sOffset)-10, (columnOffsetScale(1) - columnOffsetScale(0))/2 - columnWidth];
								} else {
									return [-10, (columnOffsetScale(1) - columnOffsetScale(0))/2 - columnWidth];
								}
							})
							.attr("class","d3-tip")
							.html(function(d){ return d.key[1] + ' (' + d.value.exceptionCount + ')'; });

					svg.call(nodeTip);
					svg.call(linkTipLeft);
					svg.call(linkTipRight);

					var update = function() {
						calcData();

						nodes = columns.selectAll('.node')
							.data(function(d, i) { return dataGroups[i].filter(function(d) { return d.value.exceptionCount > 0; }); },
									function(d) { return d.index + d.key; });

						nodes.enter()
							.append('rect')
								.attr('class', 'node')
								.attr('width', '20px')
								.attr('fill', nodeFill)
								.on('mouseover', function(d) {
									nodeTip.show(d);
									d3.select(this)
										.attr('fill', nodeMouseOver);
									links.filter(function(l) {
										return l.index === d.index && l.key[0] === d.key;
									}).attr('fill', linkMouseOver);
									links.filter(function(l) {
										return l.index === d.index-1 && l.key[1] === d.key;
									}).attr('fill', linkMouseOver);
								})
								.on('mouseout', function(d) {
									nodeTip.hide(d);
									d3.select(this)
										.attr('fill', nodeFill);
									links.filter(function(l) {
										return l.index === d.index && l.key[0] === d.key;
									}).attr('fill', linkFill);
									links.filter(function(l) {
										return l.index === d.index-1 && l.key[1] === d.key;
									}).attr('fill', linkFill);
								});

						nodes.exit().remove();

						links = linkColumns.selectAll('.link')
								.data(function(d, i) {
									return dataLinks[i].filter(function(d) { return d.value.exceptionCount > 0; });
								}, function(d, i) { return i + d.key.join(); });

						links.enter()
							.append('path')
								.attr('class', 'link')
								.style('opacity', "0.5")
								.attr('fill', linkFill)
							.on('mouseover', function(d) {
								linkTipLeft.show(d);
								linkTipRight.show(d);
								d3.select(this)
									.attr('fill', linkMouseOver);
							})
							.on('mouseout', function(d) {
								linkTipLeft.hide(d);
								linkTipRight.hide(d);
								d3.select(this)
									.attr('fill', linkFill);
							});

						links.exit().remove();

						columns.attr('transform', function(d, i) { return 'translate(' + columnOffsetScale(i) + ',0)'; });

						linkColumns.attr('transform', function(d, i) { return 'translate(' + (columnOffsetScale(i)+columnWidth+2) + ',0)'; });

						nodes.transition()
								.attr('height', function(d, i) {
									if(d.value.exceptionCount > 0) {
										if(i < d.length-1) {
											return columnScales[d.index](d.value.exceptionCount)-1;
										} else {
											return columnScales[d.index](d.value.exceptionCount);
										}
									}
								})
							.transition()
								.attr('transform', function (d) { return 'translate(0,' + columnScales[d.index](d.value.offset) + ')'; });

						links.attr('d', link);
					};

					update();

					palladioService.onUpdate('alluvial', update);
				}
			}
		};
	});
<|endoftext|>


<commit_before>var _ = require('underscore'),
    async = require('async'),
    sqlite3 = require('sqlite3'),
    sql = require('../lib/rdbql.js').dialect('sqlite3');

function repeat(pattern, count) {
    if (count < 1) return '';
    var result = '';
    while (count > 0) {
        if (count & 1) result += pattern;
        count >>= 1, pattern += pattern;
    }
    return result;
}

function Runner(adapter, level, step) {
    this.adapter = adapter;
    this.level = level || 1;
    this.step = step;
};

Runner.prototype.run = function (next) {
    var series = [];
    if (_.isArray(this.step)) {
        _.each(this.step, function (step) {
            var runner = this.createRunner(step);
            series.push(_.bind(runner.run, runner));
        }, this);
    } else if (this.step instanceof sql.statement) {
        var q = this.step.toString();
        var p = this.step.params();
        if (this.step instanceof sql.select) {
            series.push(_.bind(function (next) {
                this.adapter.all(q, p, function (err, rows) {
                    console.log("_SQL:_");
                    console.log("
");
                    console.log(q);
                    console.log("params:", p);
                    console.log(err || rows);
                    console.log("
");
                    next(err, rows);
                });
            }, this));
        } else {
            series.push(_.bind(function (next) {
                this.adapter.run(q, p, function (err) {
                    console.log("_SQL:_");
                    console.log("
");
                    console.log(q);
                    console.log("params:", p);
                    console.log(err || ("last insert id = "+this.lastID+", changes = "+this.changes));
                    console.log("
");
                    next(err);
                });
            }, this));
        }
    } else if (_.isObject(this.step)) {
        if (this.step.comment) {
            series.push(_.bind(function (next) {
                console.log();
                console.log(( this.level && repeat('#', this.level)+" " || "") + this.step.comment);
                console.log();
                next();
            }, this));
        }
        if (this.step.js) {
            series.push(_.bind(function (next) {
                var js = _.isArray(this.step.js) ? this.step.js.join("\n") : this.step.js;
                console.log("_Javascript:_");
                console.log("
");
                console.log(js);
                console.log("
");
                var runner = this.createRunner(eval(js));
                runner.run(next);
            }, this));
        }
        if (this.step.transaction) {
            var runner = this.createRunner(this.step.transaction);
            runner.level += 1;
            series.push(_.bind(runner.run, runner));
        }
    }
    async.series(series, function (err, result) {
        if (next) {
            next(err, result);
        }
    });
};

Runner.prototype.createRunner = function (step) {
    return new Runner(this.adapter, this.level, step);
};

var transaction = [
    require('./_initSchema.js'),
    require('./_insertRows.js'),
    require('./_select.js'),
];

var runner = new Runner(new sqlite3.Database(':memory:'), 0, transaction);

module.exports = runner;

runner.run(function () {
    console.log("that's it!");
});<commit_msg>improved formatting: EXAMPLES.md<commit_after>var _ = require('underscore'),
    async = require('async'),
    sqlite3 = require('sqlite3'),
    sql = require('../lib/rdbql.js').dialect('sqlite3');

function repeat(pattern, count) {
    if (count < 1) return '';
    var result = '';
    while (count > 0) {
        if (count & 1) result += pattern;
        count >>= 1, pattern += pattern;
    }
    return result;
}

function Runner(adapter, level, step) {
    this.adapter = adapter;
    this.level = level || 1;
    this.step = step;
};

Runner.prototype.run = function (next) {
    var series = [];
    if (_.isArray(this.step)) {
        _.each(this.step, function (step) {
            var runner = this.createRunner(step);
            series.push(_.bind(runner.run, runner));
        }, this);
    } else if (this.step instanceof sql.statement) {
        var q = this.step.toString();
        var p = this.step.params();
        if (this.step instanceof sql.select) {
            series.push(_.bind(function (next) {
                this.adapter.all(q, p, function (err, rows) {
                    console.log("_SQL:_");
                    console.log("
", q, "
");
                    console.log("_Result:_");
                    console.log("
", err || rows, "
");
                    next(err, rows);
                });
            }, this));
        } else {
            series.push(_.bind(function (next) {
                this.adapter.run(q, p, function (err) {
                    console.log("_SQL:_");
                    console.log("
", q, "
");
                    console.log("_Result:_");
                    console.log("
", err || ("last insert id = "+this.lastID+", changes = "+this.changes), "
");
                    next(err);
                });
            }, this));
        }
    } else if (_.isObject(this.step)) {
        if (this.step.comment) {
            series.push(_.bind(function (next) {
                console.log();
                console.log(( this.level && repeat('#', this.level)+" " || "") + this.step.comment);
                console.log();
                next();
            }, this));
        }
        if (this.step.js) {
            series.push(_.bind(function (next) {
                var js = _.isArray(this.step.js) ? this.step.js.join("\n") : this.step.js;
                console.log("_Javascript:_");
                console.log("
");
                console.log(js);
                console.log("
");
                var runner = this.createRunner(eval(js));
                runner.run(next);
            }, this));
        }
        if (this.step.transaction) {
            var runner = this.createRunner(this.step.transaction);
            runner.level += 1;
            series.push(_.bind(runner.run, runner));
        }
    }
    async.series(series, function (err, result) {
        if (next) {
            next(err, result);
        }
    });
};

Runner.prototype.createRunner = function (step) {
    return new Runner(this.adapter, this.level, step);
};

var transaction = [
    require('./_initSchema.js'),
    require('./_insertRows.js'),
    require('./_select.js'),
];

var runner = new Runner(new sqlite3.Database(':memory:'), 0, transaction);

module.exports = runner;

runner.run(function () {
    console.log("that's it!");
});<|endoftext|>


<commit_before>var r = require('express').Router(),
	ObjectId = require('mongodb').ObjectId,
	db = require('../libs/db-connector.js')

r.get('/all', function (req, res) {
	db().collection('profiles').find({hidden: {$ne: true}, year: req.query.year || (new Date()).getFullYear()  }).toArray(function (err, profiles) {
		if (!err && profiles) {
			res.json(profiles)
		}
		else if (!!err) {
			res.status(500).json('')
		}
	})
})

r.get('/all-from-institution', function (req, res) {
	if (req.query.id && req.query.id.length === 24) {
		var _id = ObjectId(req.query.id)
		db().collection('profiles').find({institution: _id, year: req.query.year || (new Date()).getFullYear()}).toArray(function (err, profiles) {
			if (!err && profiles.length > 0) {
				res.json(profiles)
			}
			else if (!!err) {
				console.log(err)
				res.status(500).json('')
			}
			else {
				res.status(404).json('No institution profile found')
			}
		})
	}
	else {
		res.status(412).json('Missing parameter')
	}
})

r.get('/single', function (req, res) {
	if (req.query.id && req.query.id.length === 24) {
		var _id = ObjectId(req.query.id)
		db().collection('profiles').find({_id: _id, year: req.query.year || (new Date()).getFullYear()}).toArray(function (err, profile) {
			if (!err && profile[0]) {
				res.json(profile[0])
			}
			else if (!!err) {
				console.log(err)
				res.status(500).json('Contains malformed data; please removed any copy-pasted images and re insert them with the editor')
			}
			else {
				res.status(404).json('Profile not found')
			}
		})
	}
	else {
		res.status(412).json('Missing parameter')
	}
})

r.get('/meta', function (req, res) {
	db().collection('meta_profiles').find({}).sort({required: -1, _id:1}).toArray(function (err, metaProfiles) {
		res.json(metaProfiles)
	})
})

r.post('/save', function (req, res) {

	if (!!req.body && !!req.body.data && !!req.body.data.institution) {
		var data = req.body.data
		delete data._id
		req.body.data.institution = ObjectId(req.body.data.institution)
		db().collection('profiles').update({'year': (new Date()).getFullYear(), institution: req.body.data.institution}, {$set: data}, {upsert: true, new: true, doc:true}, function (err, doc) {
			db().collection('profiles').update({'year': (new Date()).getFullYear() - 1, institution: req.body.data.institution}, {$set: {hidden: true}})
			if (err) {
				console.log(err)
				res.status(500).json('Contains malformed data; please removed any copy-pasted images and re insert them with the editor')
			}
			else res.status(200).json('OK')
		})
	}
	else {
		res.status(412).json('Missing parameter')
	}
})

module.exports = r
<commit_msg>trying to sort year issue<commit_after>var r = require('express').Router(),
	ObjectId = require('mongodb').ObjectId,
	db = require('../libs/db-connector.js')

r.get('/all', function (req, res) {
	db().collection('profiles').find({hidden: {$ne: true}}).toArray(function (err, profiles) {
		if (!err && profiles) {
			res.json(profiles)
		}
		else if (!!err) {
			res.status(500).json('')
		}
	})
})

r.get('/all-from-institution', function (req, res) {
	if (req.query.id && req.query.id.length === 24) {
		var _id = ObjectId(req.query.id)
		db().collection('profiles').find({institution: _id, year: req.query.year || (new Date()).getFullYear()}).toArray(function (err, profiles) {
			if (!err && profiles.length > 0) {
				res.json(profiles)
			}
			else if (!!err) {
				console.log(err)
				res.status(500).json('')
			}
			else {
				res.status(404).json('No institution profile found')
			}
		})
	}
	else {
		res.status(412).json('Missing parameter')
	}
})

r.get('/single', function (req, res) {
	if (req.query.id && req.query.id.length === 24) {
		var _id = ObjectId(req.query.id)
		db().collection('profiles').find({_id: _id, year: req.query.year || (new Date()).getFullYear()}).toArray(function (err, profile) {
			if (!err && profile[0]) {
				res.json(profile[0])
			}
			else if (!!err) {
				console.log(err)
				res.status(500).json('Contains malformed data; please removed any copy-pasted images and re insert them with the editor')
			}
			else {
				res.status(404).json('Profile not found')
			}
		})
	}
	else {
		res.status(412).json('Missing parameter')
	}
})

r.get('/meta', function (req, res) {
	db().collection('meta_profiles').find({}).sort({required: -1, _id:1}).toArray(function (err, metaProfiles) {
		res.json(metaProfiles)
	})
})

r.post('/save', function (req, res) {

	if (!!req.body && !!req.body.data && !!req.body.data.institution) {
		var data = req.body.data
		delete data._id
		req.body.data.institution = ObjectId(req.body.data.institution)
		db().collection('profiles').update({'year': (new Date()).getFullYear(), institution: req.body.data.institution}, {$set: data}, {upsert: true, new: true, doc:true}, function (err, doc) {
			db().collection('profiles').update({'year': (new Date()).getFullYear() - 1, institution: req.body.data.institution}, {$set: {hidden: true}})
			if (err) {
				console.log(err)
				res.status(500).json('Contains malformed data; please removed any copy-pasted images and re insert them with the editor')
			}
			else res.status(200).json('OK')
		})
	}
	else {
		res.status(412).json('Missing parameter')
	}
})

module.exports = r
<|endoftext|>


<commit_before>var Docker = require('../lib/docker');

var docker = new Docker({
  socketPath: '/var/run/docker.sock'
});

docker.run('ubuntu', [], process.stdout, {
  'Volumes': {
    '/stuff': {}
  },
  'ExposedPorts': {
    '80/tcp': {}
  },
  'Hostconfig': {
    'Binds': ['/home/vagrant:/stuff'],
  }
}, function(err, data, container) {
  if (err){
    return console.error(err);
  }
  console.log(data.StatusCode);
});

//run and give a container a name and a label
docker.run('redis', [], process.stdout, {
  "Name": 'MyNamedContainer',
  "Labels": {
    "environment": "blueWhale"
  },
  "HostConfig": {
    "PortBindings": {
      "6379/tcp": [
        {
          "HostPort": "0"   //Map container to a random unused port.
        }
      ]
    }
  }
}, function(err, data, container) {
  if (err){
    return console.error(err);
  }
  console.log(data.StatusCode);
});<commit_msg>tweaking args to not have two runs on stdout<commit_after>var Docker = require('../lib/docker');

var docker = new Docker({
  socketPath: '/var/run/docker.sock'
});

docker.run('ubuntu', [], process.stdout, {
  'Volumes': {
    '/stuff': {}
  },
  'ExposedPorts': {
    '80/tcp': {}
  },
  'Hostconfig': {
    'Binds': ['/home/vagrant:/stuff'],
  }
}, function(err, data, container) {
  if (err){
    return console.error(err);
  }
  console.log(data.StatusCode);
});

//run and give a container a name and a label
docker.run('redis', [], undefined, {
  "name": 'MyNamedContainer',
  "Labels": {
    "environment": "blueWhale"
  },
  "HostConfig": {
    "PortBindings": {
      "6379/tcp": [
        {
          "HostPort": "0"   //Map container to a random unused port.
        }
      ]
    }
  }
}, function(err, data, container) {
  if (err){
    return console.error(err);
  }
  console.log(data.StatusCode);
});<|endoftext|>


<commit_before>// User service
// Users API resources
// author @sauliuz

var util = require('util');
var express = require('express');
var bodyParser = require('body-parser');
var cors = require('cors');
var request = require('request');
var fh = require('fh-mbaas-api');

var validator = require('validator');
var crypto = require('crypto');
var uuid = require('uuid');
var request = require('request');
var async = require("async");
var moment = require('moment');

// common methods
var helper = require('../utilities/helper.js');

// service endpoints
// TODO move these to configuration.
//var userServiceUrl = 'https://psdev-yt5t7w6ayhgkm527grvejshb-evals-dev.mbaas1.tom.redhatmobile.com/users';
var userServiceUrl = 'http://localhost:8001/users';

// main functionality
function projectRoutes() {

  var projectRouter = new express.Router();
  projectRouter.use(cors());
  projectRouter.use(bodyParser());

  // API resource to get all projects
  projectRouter.get('/', function(req, res) {

    // preparing mondodb query for all projects
    var options = {
      "act": "list",
      "type": "sematProjects" // Entity/Collection name
    };

    fh.db(options, function (err, data) {

      if (err) {
        console.error("dbcomms error: " + err);
        // internal error response
        helper.internal500(res);
      }
      else {
        // user list response
        res.status(200);
        res.json(data);
      }
    });
  });

  // API resource to retrieve single project details
  projectRouter.get('/:projectid', function(req, res) {

    // initial stage, mock responses
    res.status(200);

    var project = {'projectname':'Lufthansa','projectid':'5703f9eb5306583d5a000019','current_practice':'Discovery',"semat_alphas": {"opportunity": "identified","requirements": "conceived","stakeholders": "recognised","team": "not established","way_of_working": "not established","work": "not established","software_system": "not established"},'users':[{"userid": "5703f9eb5306583d5a000118"}]};

    res.json({
      status: "success",
      project: project
    });
  });

  // API resource to get all projects for specific user
  projectRouter.get('/user/:userid', function(req, res) {

    // approach
    // 1. validate the format of userid and user token
    // 2. get details from User service which project id's he has attached
    // 3. get the details of array of projectid's and return back to the client

    // security
    // 1. client application provides user token it received after user
    // has logged in via user service.
    // 2. project service is just proxying user token. If user token is not admin
    // project service will just proxy the error response back

    var token = req.headers.token || '';
    var userid = req.params.userid || '';

    // validate if valid uuid value
    if (validator.isUUID(token,4) && validator.isAlphanumeric(userid)){

      // get user details from user service
      var options = {
        url: userServiceUrl+'/'+userid,
        headers: {
          'User-Agent': 'user-service',
          'token':token
        }
      };

      request(options, function callback(error, response, body) {

        // comms error
        if (error) {
          console.error('communication with user service failed: ' + error);
          var errormsg = 'communication with user service failed';
          // internal error response
          helper.internal500(res, errormsg);
        }
        else if (response.statusCode == 200) {

          var user = JSON.parse(response.body);
          var userProjects = [];

          if (user.fields) {
            var userProjectIds = user.fields.projects || [];

            // looping through project ids
            // and making async db requests to retrieve project information
            async.each(userProjectIds,

              function(projectId, callback){

                // all user lookup
                var options = {
                  "act": "read",
                  "type": "sematProjects",
                  "guid": ""+projectId.projectid
                };

                // db query
                fh.db(options, function (err, data) {

                  if (err) {
                    console.error("db error: " + err);
                    callback();
                  }
                  else if (JSON.stringify(data) == '{}'){
                    console.error('project with id: '+projectId.projectid+' not found');
                    callback();
                  }
                  else {
                    // got project data
                    // prepare data and push to array
                    var singleProject = {};
                    singleProject.project_name = data.fields.project_name;
                    singleProject.projectid = data.guid;
                    singleProject.current_practice = data.fields.current_practice;
                    singleProject.semat_alphas = data.fields.semat_alphas;
                    singleProject.users = data.fields.users;

                    userProjects.push(singleProject);
                    callback();
                  }
                });
              },

              // asynch stuff done. send response
              function(err){
                res.status(200);
                res.json({
                  status: "success",
                  projects: userProjects
                });
              }
            ); // end async.each()

          }
        }
        else if (response.statusCode == 302) {
          helper.relogin302(res);
        }
        else if (response.statusCode == 404) {
          helper.notFound404(res);
        }
        else {
          helper.generic400(res);
        }
      });
    }
    else { // payload validation failed
      helper.malformed400(res);
    }
  });

  // API resource to create a new project
  projectRouter.post('/', function(req, res) {

    // implementation
    // 1. validate project_name and the users array from the request JSON payload
    // 2. create a new project with the provided details details or fail with malformed request.
    // project guid becomes a unique id.

    // retrieve request payload details
    var project_name = req.body.project_name || '';
    var users = req.body.users || '';

    // only progress if all required fields are present
    if (validator.isAlphanumeric(project_name) && (Object.prototype.toString.call(users) === '[object Array]')) {

      // validation passed
      // create the new project

      // TODO
      // semat alphas / alpha states relate to specific library
      // hardcoded for now, but to be dynamically pulled in the future
      var semat_alphas = {
        "opportunity": "not_defined",
        "requirements": "not_defined",
        "stakeholders": "not_defined",
        "team": "not_defined",
        "way_of_working": "not_defined",
        "work": "not_defined",
        "software_system": "not_defined"
      }

      // initial entry to the project history log
      var history = [];
      var now = moment();
      var history_entry = {'time': now.format('YYYY-MM-DD HH:mm:ss'), 'message':'project created'};
      history.push(history_entry);

      // new project data
      var options = {
        "act": "create",
        "type": "sematProjects", // Entity/Collection name
        "fields": {
          "project_name": ""+project_name,
          "current_practice":"",
          "semat_alphas": semat_alphas,
          "users": users,
          "history": history
        }
      };

      // mongodb request
      fh.db(options, function (err, data) {
        // db comms error
        if (err) {
          console.error("dbcomms error: " + err);
          // internal error response
          helper.internal500(res);
        }
        else { // new project created

          var project = {};
          project.project_name = data.fields.project_name;
          project.projectid = data.guid;
          project.current_practice = data.fields.current_practice;
          project.semat_alphas = data.fields.semat_alphas;
          project.history = data.fields.history;

          // good to send the response
          res.status(200);
          res.json({
            status: "success",
            project: project,
            users: data.fields.users
          });
        }
      });
    }

    else { // malformed request, wrong request values
      helper.malformed400(res);
    }
  });

  // API resource to update an existing project
  projectRouter.put('/:projectid', function(req, res) {

    // initial stage, mock responses
    res.status(200);

    var project = {'projectname':'Project Name 1','projectid':'5703f9eb5306583d5a000018','current_practice':'Discovery',"semat_alphas": {"opportunity": "identified","requirements": "conceived","stakeholders": "recognised","team": "not established","way_of_working": "not established","work": "not established","software_system": "not established"},"users":[{"userid": "5703f9eb5306583d5a000118"}]};

    res.json({
      status: "success",
      project: project
    });
  });

  // API resource to delete an existing project
  projectRouter.delete('/:guid', function(req, res) {

    var guid = req.params.guid || '';

    // prepare project delete
    var options = {
      "act": "delete",
      "type": "sematProjects", // Entity/Collection name
      "guid": ""+guid
    };

    fh.db(options, function (err, data) {

      if (err) {
        console.error("dbcomms error: " + err);
        // internal error response
        helper.internal500(res);
      }
      else {
        // if returned object is empty
        // the project was not found in database
        data = JSON.stringify(data);

        if (data === '{}'){
          helper.notFound404(res);
        }
        else { // successfully deleted the project
          res.status(200);
          res.json({status: 'success', message: 'project deleted'});
        }
      }
    });
  });

  // Generic catch all
  // if non of the above routes are matched
  // provide generic error responses
  projectRouter.get('*', function(req, res) {

      // error response
      res.status(400);
      res.json({
        status: 'error',
        message: 'malformed request, check JSON schema',
        "code":"400"
      });
  });

  projectRouter.post('*', function(req, res) {

      // error response
      res.status(400);
      res.json({
        status: 'error',
        message: 'malformed request, check JSON schema',
        "code":"400"
      });
  });

  // end of resources
  return projectRouter;
};

module.exports = projectRoutes;
<commit_msg>project update by id<commit_after>// User service
// Users API resources
// author @sauliuz

var util = require('util');
var express = require('express');
var bodyParser = require('body-parser');
var cors = require('cors');
var request = require('request');
var fh = require('fh-mbaas-api');

var validator = require('validator');
var crypto = require('crypto');
var uuid = require('uuid');
var request = require('request');
var async = require("async");
var moment = require('moment');

// common methods
var helper = require('../utilities/helper.js');

// service endpoints
// TODO move these to configuration.
//var userServiceUrl = 'https://psdev-yt5t7w6ayhgkm527grvejshb-evals-dev.mbaas1.tom.redhatmobile.com/users';
var userServiceUrl = 'http://localhost:8001/users';

// main functionality
function projectRoutes() {

  var projectRouter = new express.Router();
  projectRouter.use(cors());
  projectRouter.use(bodyParser());

  // API resource to get all projects
  projectRouter.get('/', function(req, res) {

    // preparing mondodb query for all projects
    var options = {
      "act": "list",
      "type": "sematProjects" // Entity/Collection name
    };

    fh.db(options, function (err, data) {

      if (err) {
        console.error("dbcomms error: " + err);
        // internal error response
        helper.internal500(res);
      }
      else {
        // user list response
        res.status(200);
        res.json(data);
      }
    });
  });

  // API resource to retrieve single project details
  projectRouter.get('/:projectid', function(req, res) {

    // initial stage, mock responses
    res.status(200);

    var project = {'projectname':'Lufthansa','projectid':'5703f9eb5306583d5a000019','current_practice':'Discovery',"semat_alphas": {"opportunity": "identified","requirements": "conceived","stakeholders": "recognised","team": "not established","way_of_working": "not established","work": "not established","software_system": "not established"},'users':[{"userid": "5703f9eb5306583d5a000118"}]};

    res.json({
      status: "success",
      project: project
    });
  });

  // API resource to get all projects for specific user
  projectRouter.get('/user/:userid', function(req, res) {

    // approach
    // 1. validate the format of userid and user token
    // 2. get details from User service which project id's he has attached
    // 3. get the details of array of projectid's and return back to the client

    // security
    // 1. client application provides user token it received after user
    // has logged in via user service.
    // 2. project service is just proxying user token. If user token is not admin
    // project service will just proxy the error response back

    var token = req.headers.token || '';
    var userid = req.params.userid || '';

    // validate if valid uuid value
    if (validator.isUUID(token,4) && validator.isAlphanumeric(userid)){

      // get user details from user service
      var options = {
        url: userServiceUrl+'/'+userid,
        headers: {
          'User-Agent': 'user-service',
          'token':token
        }
      };

      request(options, function callback(error, response, body) {

        // comms error
        if (error) {
          console.error('communication with user service failed: ' + error);
          var errormsg = 'communication with user service failed';
          // internal error response
          helper.internal500(res, errormsg);
        }
        else if (response.statusCode == 200) {

          var user = JSON.parse(response.body);
          var userProjects = [];

          if (user.fields) {
            var userProjectIds = user.fields.projects || [];

            // looping through project ids
            // and making async db requests to retrieve project information
            async.each(userProjectIds,

              function(projectId, callback){

                // all user lookup
                var options = {
                  "act": "read",
                  "type": "sematProjects",
                  "guid": ""+projectId.projectid
                };

                // db query
                fh.db(options, function (err, data) {

                  if (err) {
                    console.error("db error: " + err);
                    callback();
                  }
                  else if (JSON.stringify(data) == '{}'){
                    console.error('project with id: '+projectId.projectid+' not found');
                    callback();
                  }
                  else {
                    // got project data
                    // prepare data and push to array
                    var singleProject = {};
                    singleProject.project_name = data.fields.project_name;
                    singleProject.projectid = data.guid;
                    singleProject.current_practice = data.fields.current_practice;
                    singleProject.semat_alphas = data.fields.semat_alphas;
                    singleProject.users = data.fields.users;

                    userProjects.push(singleProject);
                    callback();
                  }
                });
              },

              // asynch stuff done. send response
              function(err){
                res.status(200);
                res.json({
                  status: "success",
                  projects: userProjects
                });
              }
            ); // end async.each()

          }
        }
        else if (response.statusCode == 302) {
          helper.relogin302(res);
        }
        else if (response.statusCode == 404) {
          helper.notFound404(res);
        }
        else {
          helper.generic400(res);
        }
      });
    }
    else { // payload validation failed
      helper.malformed400(res);
    }
  });

  // API resource to create a new project
  projectRouter.post('/', function(req, res) {

    // implementation
    // 1. validate project_name and the users array from the request JSON payload
    // 2. create a new project with the provided details details or fail with malformed request.
    // project guid becomes a unique id.

    // retrieve request payload details
    var project_name = req.body.project_name || '';
    var users = req.body.users || '';

    // only progress if all required fields are present
    if (validator.isAlphanumeric(project_name) && (Object.prototype.toString.call(users) === '[object Array]')) {

      // validation passed
      // create the new project

      // TODO
      // semat alphas / alpha states relate to specific library
      // hardcoded for now, but to be dynamically pulled in the future
      var semat_alphas = {
        "opportunity": "not_defined",
        "requirements": "not_defined",
        "stakeholders": "not_defined",
        "team": "not_defined",
        "way_of_working": "not_defined",
        "work": "not_defined",
        "software_system": "not_defined"
      }

      // initial entry to the project history log
      var history = [];
      var now = moment();
      var history_entry = {'time': now.format('YYYY-MM-DD HH:mm:ss'), 'message':'project created'};
      history.push(history_entry);

      // new project data
      var options = {
        "act": "create",
        "type": "sematProjects", // Entity/Collection name
        "fields": {
          "project_name": ""+project_name,
          "current_practice":"",
          "semat_alphas": semat_alphas,
          "users": users,
          "history": history
        }
      };

      // mongodb request
      fh.db(options, function (err, data) {
        // db comms error
        if (err) {
          console.error("dbcomms error: " + err);
          // internal error response
          helper.internal500(res);
        }
        else { // new project created

          var project = {};
          project.project_name = data.fields.project_name;
          project.projectid = data.guid;
          project.current_practice = data.fields.current_practice;
          project.semat_alphas = data.fields.semat_alphas;
          project.history = data.fields.history;

          // good to send the response
          res.status(200);
          res.json({
            status: "success",
            project: project,
            users: data.fields.users
          });
        }
      });
    }

    else { // malformed request, wrong request values
      helper.malformed400(res);
    }
  });

  // API resource to update an existing project
  projectRouter.put('/:projectid', function(req, res) {

    // implementation
    // 1. validate if all required request parameters are present / valid
    // 2. retrieve the instance of the project by id
    // 3. modify the submitted parameters
    // 4. update the project object in the DB

    var guid = req.params.projectid || '';

    // preparing for validation
    var semat_alphas = req.body.semat_alphas || {};
    var history = req.body.history || '';
    var users = req.body.users || [];

    // validate if valid uuid value
    if ((Object.prototype.toString.call(history) === '[object Array]') &&
        (Object.prototype.toString.call(users) === '[object Array]')){

      // TODO security - only admin users can update
      // first we retrieve project by id
      var options = {
        "act": "read",
        "type": "sematProjects",
        "guid": ""+guid
      };

      fh.db(options, function (err, entity) {

        var entityString = JSON.stringify(entity);

        if (err) {
          console.error("dbcomms error: " + err);
          // internal error response
          helper.internal500(res);

        } else if (entityString === '{}'){
            console.error('project with id: '+guid+' not found');
            helper.notFound404(res);

        } else {

          // project found and will be updated
          var entityToUpdate = entity.fields;
          console.log('retrieved project: ' + entityToUpdate);
          entityToUpdate.semat_alphas = semat_alphas;
          entityToUpdate.history.push(history[0]);
          entityToUpdate.users.push(users[0]);

          // prepare query
          var options = {
            "act": "update",
            "type": "sematProjects",
            "guid": ""+guid,
            "fields": entityToUpdate
          };

          // db query
          fh.db(options, function (err, data) {
            if (err) {
              console.error("dbcomms error: " + err);
              // internal error response
              helper.internal500(res);
            }
            else {

              // user details response
              res.status(200);
              res.json({status: 'success', project:data});
            }
          });

        }

      });

    } else { // bad request parameters
      // generic 400 error response
      helper.generic400(res);
    }

    // // initial stage, mock responses
    // res.status(200);
    //
    // var project = {'projectname':'Project Name 1','projectid':'5703f9eb5306583d5a000018','current_practice':'Discovery',"semat_alphas": {"opportunity": "identified","requirements": "conceived","stakeholders": "recognised","team": "not established","way_of_working": "not established","work": "not established","software_system": "not established"},"users":[{"userid": "5703f9eb5306583d5a000118"}]};
    //
    // res.json({
    //   status: "success",
    //   project: project
    // });

  });

  // API resource to delete an existing project
  projectRouter.delete('/:guid', function(req, res) {

    var guid = req.params.guid || '';

    // prepare project delete
    var options = {
      "act": "delete",
      "type": "sematProjects", // Entity/Collection name
      "guid": ""+guid
    };

    fh.db(options, function (err, data) {

      if (err) {
        console.error("dbcomms error: " + err);
        // internal error response
        helper.internal500(res);
      }
      else {
        // if returned object is empty
        // the project was not found in database
        data = JSON.stringify(data);

        if (data === '{}'){
          helper.notFound404(res);
        }
        else { // successfully deleted the project
          res.status(200);
          res.json({status: 'success', message: 'project deleted'});
        }
      }
    });
  });

  // Generic catch all
  // if non of the above routes are matched
  // provide generic error responses
  projectRouter.get('*', function(req, res) {

      // error response
      res.status(400);
      res.json({
        status: 'error',
        message: 'malformed request, check JSON schema',
        "code":"400"
      });
  });

  projectRouter.post('*', function(req, res) {

      // error response
      res.status(400);
      res.json({
        status: 'error',
        message: 'malformed request, check JSON schema',
        "code":"400"
      });
  });

  // end of resources
  return projectRouter;
};

module.exports = projectRoutes;
<|endoftext|>


<commit_before>var aws = require ('aws-lib');

var awsKey = "";
var awsPrivateKey = "";

// See "http://docs.amazonwebservices.com/AWSSimpleQueueService/latest/APIReference/"
// General SQS actions do not require a "path" (CreateQueue, ListQueue, etc)

sqs = aws.createSQSClient( awsKey, awsPrivateKey);

sqs.call ( "ListQueues", {}, function (err, result) {
    console.log("ListQueues result: " + JSON.stringify(result));
});

// Specific Queue options (CreateMessage, DeleteMessage, etc)
// need a specific path
// http://sqs.us-east-1.amazonaws.com/123456789012/testQueue/
// /accountid/queue_name
var options = {
    "path" : "/123456789012/testQueue/"
};
var outbound = {
    MessageBody : "Test Message"
};

sqs = aws.createSQSClient(awsKey, awsPrivateKey, options);
sqs.call ( "SendMessage", outbound, function (result ) {
    console.log("result: " + JSON.stringify(result));
});

<commit_msg>Update examples/sqs.js<commit_after>var aws = require ('aws-lib');

var awsKey = "";
var awsPrivateKey = "";

// See "http://docs.amazonwebservices.com/AWSSimpleQueueService/latest/APIReference/"
// General SQS actions do not require a "path" (CreateQueue, ListQueue, etc)

sqs = aws.createSQSClient( awsKey, awsPrivateKey);

sqs.call ( "ListQueues", {}, function (err, result) {
    console.log("ListQueues result: " + JSON.stringify(result));
});

// Specific Queue options (CreateMessage, DeleteMessage, etc)
// need a specific path
// http://sqs.us-east-1.amazonaws.com/123456789012/testQueue/
// /accountid/queue_name
var options = {
    "path" : "/123456789012/testQueue/"
};
var outbound = {
    MessageBody : "Test Message"
};

sqs = aws.createSQSClient(awsKey, awsPrivateKey, options);
sqs.call ( "SendMessage", outbound, function (err, result ) {
    console.log("result: " + JSON.stringify(result));
});

<|endoftext|>


<commit_before>var mediamanager="undefined"!=typeof mediamanager?mediamanager:{};mediamanager.external=new function(){var e="https://{shortname}.getmediamanager.com/api/v1/external",i={};this.client=function(i){mediamanager.client(i),e=parseBaseURL()},this.addFilter=function(e,n){i[e]=n},this.embed=function(e,i){return"undefined"!=typeof mediamanager.embed?"undefined"!=typeof e?(mediamanager.embed(i),void ping(e,mediamanager.id)):void console.error("No templateID passed"):void console.error("Missing Media Manager smart embed!")},ping=function(e,i){var n=this.parseBaseURL().replace("/external","");request(n+"/ajax/embed/video/"+i,null,{external_template:e})},serialize=function(e){var i=[];for(var n in e)e.hasOwnProperty(n)&&i.push(encodeURIComponent(n)+"="+encodeURIComponent(e[n]));return i.join("&")},parseBaseURL=function(){return"undefined"!=typeof mediamanager.sn?e.replace("{shortname}",mediamanager.sn):void console.error("Missing client shortname")},request=function(e,n,t){n=n||function(){},t=$.extend(t||{},i),nanoajax.ajax({url:e+"?"+serialize(t),method:"GET"},function(e,i,t){var o=JSON.parse(i);return"undefined"!=typeof o.error?void console.error(o.error.message):void n(o,e,t)})},this.template=new function(){this.getMostViewedVideos=function(i,n){return"undefined"==typeof i?void console.error("Missing templateID"):void request(e+"/template/"+i+"/videos/mostviewed",n)},this.getVideos=function(i,n){return"undefined"==typeof i?void console.error("Missing templateID"):void request(e+"/template/"+i+"/videos/latest",n)},this.searchVideos=function(i,n,t){return"undefined"==typeof i?void console.error("Missing templateID"):void request(e+"/template/"+i+"/video/search",t,{term:n})},this.getVideos=function(i,n){return"undefined"==typeof i?void console.error("Missing templateID"):void request(e+"/template/"+i+"/videos",n)},this.getAudios=function(i,n){return"undefined"==typeof i?void console.error("Missing templateID"):void request(e+"/template/"+i+"/audios",n)},this.recommendVideo=function(i,n,t){return"undefined"==typeof i?void console.error("Missing templateID"):"undefined"==typeof n?void console.error("Missing videoid"):void request(e+"/template/"+i+"/videos/recommend/"+n,t)}},this.playlist=new function(){this.getVideos=function(i,n,t){return"undefined"==typeof n?void console.error("Missing templateID"):"undefined"==typeof i?void console.error("Missing playlistID"):(mediamanager.external.addFilter("templateID",n),void request(e+"/playlist/"+i+"/videos",t))},this.getAudios=function(i,n,t){return"undefined"==typeof n?void console.error("Missing templateID"):"undefined"==typeof i?void console.error("Missing playlistID"):(mediamanager.external.addFilter("templateID",n),void request(e+"/playlist/"+i+"/audios",t))},this.getVideos=function(i,n,t){return"undefined"==typeof n?void console.error("Missing templateID"):"undefined"==typeof i?void console.error("Missing playlistID"):(mediamanager.external.addFilter("templateID",n),void request(e+"/playlist/"+i+"/videos",t))},this.getAudio=function(i,n,t,o){return"undefined"==typeof n?void console.error("Missing templateID"):"undefined"==typeof i?void console.error("Missing playlistID"):(mediamanager.external.addFilter("templateID",n),void request(e+"/playlist/"+i+"/audio/"+t,o))},this.getVideo=function(i,n,t,o){return"undefined"==typeof n?void console.error("Missing templateID"):"undefined"==typeof i?void console.error("Missing playlistID"):(mediamanager.external.addFilter("templateID",n),void request(e+"/playlist/"+i+"/video/"+t,o))}}};<commit_msg>Compiling previous commit<commit_after>var mediamanager="undefined"!=typeof mediamanager?mediamanager:{};mediamanager.external=new function(){var e="https://{shortname}.getmediamanager.com/api/v1/external",i={};this.client=function(i){mediamanager.client(i),e=parseBaseURL()},this.addFilter=function(e,n){i[e]=n},this.embed=function(e,i){return"undefined"!=typeof mediamanager.embed?"undefined"!=typeof e?(mediamanager.embed(i),void ping(e,mediamanager.id)):void console.error("No templateID passed"):void console.error("Missing Media Manager smart embed!")},ping=function(e,i){var n=this.parseBaseURL().replace("/external","");request(n+"/ajax/embed/video/"+i,null,{external_template:e})},serialize=function(e){var i=[];for(var n in e)e.hasOwnProperty(n)&&i.push(encodeURIComponent(n)+"="+encodeURIComponent(e[n]));return i.join("&")},parseBaseURL=function(){return"undefined"!=typeof mediamanager.sn?e.replace("{shortname}",mediamanager.sn):void console.error("Missing client shortname")},request=function(e,n,t){n=n||function(){},t=$.extend(t||{},i),nanoajax.ajax({url:e+"?"+serialize(t),method:"GET"},function(e,i,t){var o=JSON.parse(i);return"undefined"!=typeof o.error?void console.error(o.error.message):void n(o,e,t)})},this.template=new function(){this.getMostViewedVideos=function(i,n){return"undefined"==typeof i?void console.error("Missing templateID"):void request(e+"/template/"+i+"/videos/mostviewed",n)},this.getLatestVideos=function(i,n){return"undefined"==typeof i?void console.error("Missing templateID"):void request(e+"/template/"+i+"/videos/latest",n)},this.getVideo=function(i,n,t){return"undefined"==typeof n?void console.error("Missing templateID"):"undefined"==typeof i?void console.error("Missing videoID"):void request(e+"/template/"+n+"/video/"+i,t)},this.searchVideos=function(i,n,t){return"undefined"==typeof i?void console.error("Missing templateID"):void request(e+"/template/"+i+"/video/search",t,{term:n})},this.getVideos=function(i,n){return"undefined"==typeof i?void console.error("Missing templateID"):void request(e+"/template/"+i+"/videos",n)},this.getAudios=function(i,n){return"undefined"==typeof i?void console.error("Missing templateID"):void request(e+"/template/"+i+"/audios",n)},this.recommendVideo=function(i,n,t){return"undefined"==typeof i?void console.error("Missing templateID"):"undefined"==typeof n?void console.error("Missing videoid"):void request(e+"/template/"+i+"/videos/recommend/"+n,t)}},this.playlist=new function(){this.getVideos=function(i,n,t){return"undefined"==typeof n?void console.error("Missing templateID"):"undefined"==typeof i?void console.error("Missing playlistID"):(mediamanager.external.addFilter("templateID",n),void request(e+"/playlist/"+i+"/videos",t))},this.getAudios=function(i,n,t){return"undefined"==typeof n?void console.error("Missing templateID"):"undefined"==typeof i?void console.error("Missing playlistID"):(mediamanager.external.addFilter("templateID",n),void request(e+"/playlist/"+i+"/audios",t))},this.getVideos=function(i,n,t){return"undefined"==typeof n?void console.error("Missing templateID"):"undefined"==typeof i?void console.error("Missing playlistID"):(mediamanager.external.addFilter("templateID",n),void request(e+"/playlist/"+i+"/videos",t))},this.getAudio=function(i,n,t,o){return"undefined"==typeof n?void console.error("Missing templateID"):"undefined"==typeof i?void console.error("Missing playlistID"):(mediamanager.external.addFilter("templateID",n),void request(e+"/playlist/"+i+"/audio/"+t,o))},this.getVideo=function(i,n,t,o){return"undefined"==typeof n?void console.error("Missing templateID"):"undefined"==typeof i?void console.error("Missing playlistID"):(mediamanager.external.addFilter("templateID",n),void request(e+"/playlist/"+i+"/video/"+t,o))}}};
<|endoftext|>


<commit_before>// ARTIFACT ///////////////////////////////////////////////////////

// added as part of the ingress #13magnus in november 2013, artifacts
// are additional game elements overlayed on the intel map
// currently there are only jarvis-related entities
// - shards: move between portals (along links) each hour. more than one can be at a portal
// - targets: specific portals - one per team
// the artifact data includes details for the specific portals, so can be useful

window.artifact = function() {}

window.artifact.setup = function() {
  artifact.REFRESH_JITTER = 2*60;  // 2 minute random period so not all users refresh at once
  artifact.REFRESH_SUCCESS = 60*60;  // 60 minutes on success
  artifact.REFRESH_FAILURE = 2*60;  // 2 minute retry on failure

  artifact.idle = false;
  artifact.clearData();

  addResumeFunction(artifact.idleResume);

  // move the initial data request onto a very short timer. prevents thrown exceptions causing IITC boot failures
  setTimeout (artifact.requestData, 1);

  artifact._layer = new L.LayerGroup();
  addLayerGroup ('Artifacts (Jarvis shards)', artifact._layer, true);

  $('#toolbox').append(' Artifacts');

}

window.artifact.requestData = function() {
  if (isIdle()) {
    artifact.idle = true;
  } else {
    window.postAjax('getArtifactInfo', {}, artifact.handleSuccess, artifact.handleError);
  }
}

window.artifact.idleResume = function() {
  if (artifact.idle) {
    artifact.idle = false;
    artifact.requestData();
  }
}

window.artifact.handleSuccess = function(data) {
  artifact.processData (data);

  // start the next refresh at a multiple of REFRESH_SUCCESS seconds, plus a random REFRESH_JITTER amount to prevent excessive server hits at one time
  var now = Date.now();
  var nextTime = Math.ceil(now/(artifact.REFRESH_SUCCESS*1000))*(artifact.REFRESH_SUCCESS*1000) + Math.floor(Math.random()*artifact.REFRESH_JITTER*1000);

  setTimeout (artifact.requestData, nextTime - now);
}

window.artifact.handleFailure = function(data) {
  // no useful data on failure - do nothing

  setTimeout (artifact.requestData, artifact.REFRESH_FAILURE*1000);
}

window.artifact.processData = function(data) {

  if (data.error || !data.artifacts) {
    console.warn('Failed to find artifacts in artifact response');
  }

  artifact.clearData();

  $.each (data.artifacts, function(i,artData) {
    if (artData.artifactId != 'jarvis') {
      // jarvis artifacts - fragmentInfos and targetInfos
      // (future types? completely unknown at this time!)
      console.warn('Note: unknown artifactId '+artData.artifactId+' - guessing how to handle it');
    }

    artifact.artifactTypes[artData.artifactId] = artData.artifactId;

    if (artData.fragmentInfos) {
      artifact.processFragmentInfos (artData.artifactId, artData.fragmentInfos);
    }

    if (artData.targetInfos) {
      artifact.processTargetInfos (artData.artifactId, artData.targetInfos);
    }

    // other data in future? completely unknown!
  });

  // redraw the artifact layer
  artifact.updateLayer();

}

window.artifact.clearData = function() {

  artifact.portalInfo = {};
  artifact.artifactTypes = {};
}

window.artifact.processFragmentInfos = function (id, fragments) {
  $.each(fragments, function(i, fragment) {
    if (!artifact.portalInfo[fragment.portalGuid]) {
      artifact.portalInfo[fragment.portalGuid] = { _entityData: fragment.portalInfo };
    }

    if (!artifact.portalInfo[fragment.portalGuid][id]) artifact.portalInfo[fragment.portalGuid][id] = {};

    if (!artifact.portalInfo[fragment.portalGuid][id].fragments) artifact.portalInfo[fragment.portalGuid][id].fragments = [];

    $.each(fragment.fragments, function(i,f) {
      artifact.portalInfo[fragment.portalGuid][id].fragments.push(f);
    });

  });
}

window.artifact.processTargetInfos = function (id, targets) {
  $.each(targets, function(i, target) {
    if (!artifact.portalInfo[target.portalGuid]) {
      artifact.portalInfo[target.portalGuid] = { _entityData: target.portalInfo };
    }

    if (!artifact.portalInfo[target.portalGuid][id]) artifact.portalInfo[target.portalGuid][id] = {};

    artifact.portalInfo[target.portalGuid][id].target = target.team === 'RESISTANCE' ? TEAM_RES : TEAM_ENL;
  });
}

window.artifact.getArtifactTypes = function() {
  return Object.keys(artifact.artifactTypes);
}

window.artifact.isArtifact = function(type) {
  return type in artifact.artifactTypes;
}

// used to render portals that would otherwise be below the visible level
window.artifact.getArtifactEntities = function() {
  var entities = [];

  // create fake entities from the artifact data
  $.each (artifact.portalInfo, function(guid,data) {
    var timestamp = 0; // we don't have a valid timestamp - so let's use 0
    var ent = [ guid, timestamp, data._entityData ];
    entities.push(ent);
  });

  return entities;
}

window.artifact.getInterestingPortals = function() {
  return Object.keys(artifact.portalInfo);
}

// quick test for portal being relevant to artifacts - of any type
window.artifact.isInterestingPortal = function(guid) {
  return guid in artifact.portalInfo;
}

// get the artifact data for a specified artifact id (e.g. 'jarvis'), if it exists - otherwise returns something 'false'y
window.artifact.getPortalData = function(guid,artifactId) {
  return artifact.portalInfo[guid] && artifact.portalInfo[guid][artifactId];
}

window.artifact.updateLayer = function() {
  artifact._layer.clearLayers();

  $.each(artifact.portalInfo, function(guid,data) {
    var latlng = L.latLng ([data._entityData.latE6/1E6, data._entityData.lngE6/1E6]);

    // jarvis shard icon
    var iconUrl = undefined;
    var iconSize = 0;
    var opacity = 1.0;

    if (data.jarvis) {
      if (data.jarvis.target) {
        // target portal - show the target marker. use the count of fragments at the target to pick the right icon - it has segments that fill up

        var count = data.jarvis.fragments ? data.jarvis.fragments.length : 0;

        iconUrl = '//commondatastorage.googleapis.com/ingress.com/img/map_icons/marker_images/jarvis_shard_target_'+count+'.png';
        iconSize = 100/2; // 100 pixels - half that size works better
      } else if (data.jarvis.fragments) {
        iconUrl = '//commondatastorage.googleapis.com/ingress.com/img/map_icons/marker_images/jarvis_shard.png';
        iconSize = 60/2; // 60 pixels - half that size works better
        opacity = 0.6; // these often hide portals - let's make them semi transparent
      }

    }

    if (iconUrl) {
      var icon = L.icon({
        iconUrl: iconUrl,
        iconSize: [iconSize,iconSize],
        iconAnchor: [iconSize/2,iconSize/2],
        className: 'no-pointer-events'  // the clickable: false below still blocks events going through to the svg underneath
      });

      var marker = L.marker (latlng, {icon: icon, clickable: false, keyboard: false, opacity: opacity });

      artifact._layer.addLayer(marker);
    } else {
      console.warn('Oops! no URL for artifact portal icon?!');
    }
  });

}

window.artifact.showArtifactList = function() {

  var html = '
Artifact portals
';

  var types = { 'jarvis': 'Jarvis Shards' };

  $.each(types, function(type, name) {

    html += '

'+types[type]+'
';

    html += '
';
    html += '
Portal	Details
';

    var tableRows = [];

    $.each(artifact.portalInfo, function(guid, data) {
      if (type in data) {
        // this portal has data for this artifact type - add it to the table

        var sortVal = 0;

        var onclick = 'zoomToAndShowPortal(\''+guid+'\',['+data._entityData.latE6/1E6+','+data._entityData.lngE6/1E6+'])';
        var row = '
'+escapeHtmlSpecialChars(data._entityData.title)+'	';

        row += '';

        if (data[type].target) {
          row += ''+(data[type].target==TEAM_RES?'Resistance':'Enlightened')+' target ';
          sortVal = 100000+data[type].target;
        }

        if (data[type].fragments) {
          if (data[type].target) {
            row += '
';
          }
          row += 'Shard: #'+data[type].fragments.join(', #')+' ';
          sortVal = Math.min.apply(null, data[type].fragments); // use min shard number at portal as sort key
        }

        row += '
';

        tableRows.push ( [sortVal, row] );
      }
    });

    // sort the rows
    tableRows.sort(function(a,b) {
      return a[0]-b[0];
    });

    // and add them to the table
    html += tableRows.map(function(a){return a[1];}).join('');

    html += '
';
  });

  dialog({
    title: 'Artifacts',
    html: html,
    width: 400,
    position: {my: 'right center', at: 'center-60 center', of: window, collision: 'fit'}
  });

}
<commit_msg>add artifact support for likely new 'amar artifacts'. seems to be the same system as the jarvis shards, but different display names, and URLs for resources<commit_after>// ARTIFACT ///////////////////////////////////////////////////////

// added as part of the ingress #13magnus in november 2013, artifacts
// are additional game elements overlayed on the intel map
// currently there are only jarvis-related entities
// - shards: move between portals (along links) each hour. more than one can be at a portal
// - targets: specific portals - one per team
// the artifact data includes details for the specific portals, so can be useful
// 2014-02-06: intel site updates hint at new 'amar artifacts', likely following the same system as above

window.artifact = function() {}

window.artifact.setup = function() {
  artifact.REFRESH_JITTER = 2*60;  // 2 minute random period so not all users refresh at once
  artifact.REFRESH_SUCCESS = 60*60;  // 60 minutes on success
  artifact.REFRESH_FAILURE = 2*60;  // 2 minute retry on failure

  artifact.idle = false;
  artifact.clearData();

  addResumeFunction(artifact.idleResume);

  // move the initial data request onto a very short timer. prevents thrown exceptions causing IITC boot failures
  setTimeout (artifact.requestData, 1);

  artifact._layer = new L.LayerGroup();
  addLayerGroup ('Artifacts (Jarvis shards)', artifact._layer, true);

  $('#toolbox').append(' Artifacts');

}

window.artifact.requestData = function() {
  if (isIdle()) {
    artifact.idle = true;
  } else {
    window.postAjax('getArtifactInfo', {}, artifact.handleSuccess, artifact.handleError);
  }
}

window.artifact.idleResume = function() {
  if (artifact.idle) {
    artifact.idle = false;
    artifact.requestData();
  }
}

window.artifact.handleSuccess = function(data) {
  artifact.processData (data);

  // start the next refresh at a multiple of REFRESH_SUCCESS seconds, plus a random REFRESH_JITTER amount to prevent excessive server hits at one time
  var now = Date.now();
  var nextTime = Math.ceil(now/(artifact.REFRESH_SUCCESS*1000))*(artifact.REFRESH_SUCCESS*1000) + Math.floor(Math.random()*artifact.REFRESH_JITTER*1000);

  setTimeout (artifact.requestData, nextTime - now);
}

window.artifact.handleFailure = function(data) {
  // no useful data on failure - do nothing

  setTimeout (artifact.requestData, artifact.REFRESH_FAILURE*1000);
}

window.artifact.processData = function(data) {

  if (data.error || !data.artifacts) {
    console.warn('Failed to find artifacts in artifact response');
  }

  artifact.clearData();

  $.each (data.artifacts, function(i,artData) {
    if (artData.artifactId != 'jarvis') {
      // jarvis artifacts - fragmentInfos and targetInfos
      // (future types? completely unknown at this time!)
      console.warn('Note: unknown artifactId '+artData.artifactId+' - guessing how to handle it');
    }

    artifact.artifactTypes[artData.artifactId] = artData.artifactId;

    if (artData.fragmentInfos) {
      artifact.processFragmentInfos (artData.artifactId, artData.fragmentInfos);
    }

    if (artData.targetInfos) {
      artifact.processTargetInfos (artData.artifactId, artData.targetInfos);
    }

    // other data in future? completely unknown!
  });

  // redraw the artifact layer
  artifact.updateLayer();

}

window.artifact.clearData = function() {

  artifact.portalInfo = {};
  artifact.artifactTypes = {};
}

window.artifact.processFragmentInfos = function (id, fragments) {
  $.each(fragments, function(i, fragment) {
    if (!artifact.portalInfo[fragment.portalGuid]) {
      artifact.portalInfo[fragment.portalGuid] = { _entityData: fragment.portalInfo };
    }

    if (!artifact.portalInfo[fragment.portalGuid][id]) artifact.portalInfo[fragment.portalGuid][id] = {};

    if (!artifact.portalInfo[fragment.portalGuid][id].fragments) artifact.portalInfo[fragment.portalGuid][id].fragments = [];

    $.each(fragment.fragments, function(i,f) {
      artifact.portalInfo[fragment.portalGuid][id].fragments.push(f);
    });

  });
}

window.artifact.processTargetInfos = function (id, targets) {
  $.each(targets, function(i, target) {
    if (!artifact.portalInfo[target.portalGuid]) {
      artifact.portalInfo[target.portalGuid] = { _entityData: target.portalInfo };
    }

    if (!artifact.portalInfo[target.portalGuid][id]) artifact.portalInfo[target.portalGuid][id] = {};

    artifact.portalInfo[target.portalGuid][id].target = target.team === 'RESISTANCE' ? TEAM_RES : TEAM_ENL;
  });
}

window.artifact.getArtifactTypes = function() {
  return Object.keys(artifact.artifactTypes);
}

window.artifact.isArtifact = function(type) {
  return type in artifact.artifactTypes;
}

// used to render portals that would otherwise be below the visible level
window.artifact.getArtifactEntities = function() {
  var entities = [];

  // create fake entities from the artifact data
  $.each (artifact.portalInfo, function(guid,data) {
    var timestamp = 0; // we don't have a valid timestamp - so let's use 0
    var ent = [ guid, timestamp, data._entityData ];
    entities.push(ent);
  });

  return entities;
}

window.artifact.getInterestingPortals = function() {
  return Object.keys(artifact.portalInfo);
}

// quick test for portal being relevant to artifacts - of any type
window.artifact.isInterestingPortal = function(guid) {
  return guid in artifact.portalInfo;
}

// get the artifact data for a specified artifact id (e.g. 'jarvis'), if it exists - otherwise returns something 'false'y
window.artifact.getPortalData = function(guid,artifactId) {
  return artifact.portalInfo[guid] && artifact.portalInfo[guid][artifactId];
}

window.artifact.updateLayer = function() {
  artifact._layer.clearLayers();

  $.each(artifact.portalInfo, function(guid,data) {
    var latlng = L.latLng ([data._entityData.latE6/1E6, data._entityData.lngE6/1E6]);

    // jarvis shard icon
    var iconUrl = undefined;
    var iconSize = 0;
    var opacity = 1.0;

    // redundant as of 2014-02-05 - jarvis shards removed
    if (data.jarvis) {
      if (data.jarvis.target) {
        // target portal - show the target marker. use the count of fragments at the target to pick the right icon - it has segments that fill up

        var count = data.jarvis.fragments ? data.jarvis.fragments.length : 0;

        iconUrl = '//commondatastorage.googleapis.com/ingress.com/img/map_icons/marker_images/jarvis_shard_target_'+count+'.png';
        iconSize = 100/2; // 100 pixels - half that size works better
      } else if (data.jarvis.fragments) {
        iconUrl = '//commondatastorage.googleapis.com/ingress.com/img/map_icons/marker_images/jarvis_shard.png';
        iconSize = 60/2; // 60 pixels - half that size works better
        opacity = 0.6; // these often hide portals - let's make them semi transparent
      }

    }
    // 2014-02-06: a guess at whats needed for the new artifacts
    if (data.amar) {
      if (data.amar.target) {
        // target portal - show the target marker. use the count of fragments at the target to pick the right icon - it has segments that fill up

        var count = data.amar.fragments ? data.amar.fragments.length : 0;

        iconUrl = '//commondatastorage.googleapis.com/ingress.com/img/map_icons/marker_images/amar_shard_target_'+count+'.png';
        iconSize = 100/2; // 100 pixels - half that size works better
      } else if (data.amar.fragments) {
        iconUrl = '//commondatastorage.googleapis.com/ingress.com/img/map_icons/marker_images/amar_shard.png';
        iconSize = 60/2; // 60 pixels - half that size works better
        opacity = 0.6; // these often hide portals - let's make them semi transparent
      }

    }

    if (iconUrl) {
      var icon = L.icon({
        iconUrl: iconUrl,
        iconSize: [iconSize,iconSize],
        iconAnchor: [iconSize/2,iconSize/2],
        className: 'no-pointer-events'  // the clickable: false below still blocks events going through to the svg underneath
      });

      var marker = L.marker (latlng, {icon: icon, clickable: false, keyboard: false, opacity: opacity });

      artifact._layer.addLayer(marker);
    } else {
      console.warn('Oops! no URL for artifact portal icon?!');
    }
  });

}

window.artifact.showArtifactList = function() {

  var html = '';

  var typeNames = { 'jarvis': 'Jarvis Shards', 'amar': 'Amar Artifacts' };

  if (Object.keys(artifact.artifactTypes).length == 0) {
    html += 'No artifacts at this time';
  }

  $.each(artifact.artifactTypes, function(type,type2) {
    var name = typeNames[type] || ('New artifact type: '+type);

    html += '

'+types[type]+'
';

    html += '
';
    html += '
Portal	Details
';

    var tableRows = [];

    $.each(artifact.portalInfo, function(guid, data) {
      if (type in data) {
        // this portal has data for this artifact type - add it to the table

        var sortVal = 0;

        var onclick = 'zoomToAndShowPortal(\''+guid+'\',['+data._entityData.latE6/1E6+','+data._entityData.lngE6/1E6+'])';
        var row = '
'+escapeHtmlSpecialChars(data._entityData.title)+'	';

        row += '';

        if (data[type].target) {
          row += ''+(data[type].target==TEAM_RES?'Resistance':'Enlightened')+' target ';
          sortVal = 100000+data[type].target;
        }

        if (data[type].fragments) {
          if (data[type].target) {
            row += '
';
          }
          row += 'Shard: #'+data[type].fragments.join(', #')+' ';
          sortVal = Math.min.apply(null, data[type].fragments); // use min shard number at portal as sort key
        }

        row += '
';

        tableRows.push ( [sortVal, row] );
      }
    });

    // sort the rows
    tableRows.sort(function(a,b) {
      return a[0]-b[0];
    });

    // and add them to the table
    html += tableRows.map(function(a){return a[1];}).join('');

    html += '
';
  });

  dialog({
    title: 'Artifacts',
    html: html,
    width: 400,
    position: {my: 'right center', at: 'center-60 center', of: window, collision: 'fit'}
  });

}
<|endoftext|>


<commit_before>var SandCastle = require('../lib').SandCastle,
  equal = require('assert').equal;

var sandcastle = new SandCastle({
  api: './examples/api.js', // We provide an API with the setTimeout function.,
  timeout: 1000
});

// Keep track of execution stats.
var stats = {
  script1: 0,
  script2: 0,
  script3: 0
};

// A non-malicious script with a timeout.
var script1 = sandcastle.createScript("\
  exports.main = function() {\
    setTimeout(function() {\
      exit('script1')\
    }, 250)\
  }\
");

script1.on('exit', function(err, output) {
  stats[output] += 1;
});

script1.on('timeout', function() {
  // reschedule script1 when it times out.
  script1.run();
});

// a malicious script that loops infinitely.
var script2 = sandcastle.createScript("\
  exports.main = function() {\
    while('script2') {};\
  }\
");

script2.on('exit', function(err, output) {
  stats[output] += 1;
});

// A non-malicious script with a timeout.
var script3 = sandcastle.createScript("\
  exports.main = function() {\
    setTimeout(function() {\
      exit('script3')\
    }, 500)\
  }\
");

script3.on('exit', function(err, output) {
  stats[output] += 1;
});

script3.on('timeout', function() {

  // reschedule script3 when it times out.

  script3.removeAllListeners('exit');
  script3.on('exit', function(err, output) {
    stats.script3 += 1;

    // Make sure the scripts were
    // executed the appropriate # of times.
    equal(stats.script1, 2);
    equal(stats.script2, 0);
    equal(stats.script3, 2);
    console.log('scripts executed the correct # of times', stats)

    process.exit(0);
  });
  script3.run();
});

// Running script 1 and 3 will take.
// about 2 seconds to complete.
script1.run();
script3.run();

var id = setInterval(function() {
  if (script1.exited && script3.exited) {
    clearInterval(id);

    // both script1 and script 2 exited after their first execution.
    // next we will schedule them with a malicious script.

    script3.run();
    script1.run();
    // script2 is malicious and will cause the sandbox to shutdown
    // script1 and script3's timeout methods however cause them to be
    // rescheduled.
    script2.run();
  }
}, 1000);<commit_msg>using benchmark.js to test long lived sandboxes with malicious jobs.<commit_after>var SandCastle = require('../lib').SandCastle,
  equal = require('assert').equal;

var sandcastle = new SandCastle({
  api: './examples/api.js', // We provide an API with the setTimeout function.,
  timeout: 2000
});

(function execute(n) {

  if (!n) {
    process.exit(0);
    return;
  }

  // Keep track of execution stats.
  var stats = {
    script1: 0,
    script2: 0,
    script3: 0
  };

  // A non-malicious script with a timeout.
  var script1 = sandcastle.createScript("\
    exports.main = function() {\
      setTimeout(function() {\
        exit('script1')\
      }, 10)\
    }\
  ");

  script1.on('exit', function(err, output) {
    stats[output] += 1;
  });

  script1.on('timeout', function() {
    // reschedule script1 when it times out.
    script1.run();
  });

  // a malicious script that loops infinitely.
  var script2 = sandcastle.createScript("\
    exports.main = function() {\
      while('script2') {};\
    }\
  ");

  script2.on('exit', function(err, output) {
    stats[output] += 1;
  });

  // A non-malicious script with a timeout.
  var script3 = sandcastle.createScript("\
    exports.main = function() {\
      setTimeout(function() {\
        exit('script3')\
      }, 1000)\
    }\
  ");

  script3.on('exit', function(err, output) {
    stats[output] += 1;
  });

  script3.on('timeout', function() {

    // reschedule script3 when it times out.

    script3.removeAllListeners('exit');
    script3.on('exit', function(err, output) {
      stats.script3 += 1;

      // Make sure the scripts were
      // executed the appropriate # of times.
      equal(stats.script1, 2);
      equal(stats.script2, 0);
      equal(stats.script3, 2);
      console.log('scripts executed the correct # of times', stats)
      setTimeout(function() {
        execute(n - 1);
      }, 0);
    });
    script3.run();
  });

  // Running script 1 and 3 will take.
  // about 2 seconds to complete.
  script1.run();
  script3.run();

  var id = setInterval(function() {
    if (script1.exited && script3.exited) {
      clearInterval(id);

      // both script1 and script 2 exited after their first execution.
      // next we will schedule them with a malicious script.

      script3.run();
      script1.run();
      // script2 is malicious and will cause the sandbox to shutdown
      // script1 and script3's timeout methods however cause them to be
      // rescheduled.
      script2.run();
    }
  }, 1000);

})(1000);<|endoftext|>


<commit_before>'use strict';

var path = process.cwd();
var ClickHandler = require(path + '/app/controllers/clickHandler.server.js');

module.exports = function (app, passport) {

	function isLoggedIn (req, res, next) {
		if (req.isAuthenticated()) {
			return next();
		} else {
			res.redirect('/login');
		}
	}

	var clickHandler = new ClickHandler();

	app.route('/')
		.get(isLoggedIn, function (req, res) {
			res.sendFile(path + '/public/index.html');
		});

	app.route('/login')
		.get(function (req, res) {
			res.sendFile(path + '/public/login.html');
		});

	app.route('/logout')
		.get(function (req, res) {
			req.logout();
			res.redirect('/login');
		});

	app.route('/profile')
		.get(isLoggedIn, function (req, res) {
			res.sendFile(path + '/public/profile.html');
		});

	app.route('/api/:id')
		.get(isLoggedIn, function (req, res) {
			res.json(req.user.github);
		});

	app.route('/auth/github')
		.get(passport.authenticate('github'));

	app.route('/auth/github/callback')
		.get(passport.authenticate('github', {
			successRedirect: '/',
			failureRedirect: '/login'
		}));

	app.route('/api/:id/clicks')
		.get(isLoggedIn, clickHandler.getClicks)
		.post(isLoggedIn, clickHandler.addClick)
		.delete(isLoggedIn, clickHandler.resetClicks);
};
<commit_msg>Headers API<commit_after>'use strict';

var path = process.cwd();
var ClickHandler = require(path + '/app/controllers/clickHandler.server.js');

module.exports = function (app, passport) {

	function isLoggedIn (req, res, next) {
		if (req.isAuthenticated()) {
			return next();
		} else {
			res.redirect('/login');
		}
	}

	var clickHandler = new ClickHandler();

	app.route('/')
		.get(isLoggedIn, function (req, res) {
			res.sendFile(path + '/public/index.html');
		});

	app.route('/login')
		.get(function (req, res) {
			res.sendFile(path + '/public/login.html');
		});

	app.route('/logout')
		.get(function (req, res) {
			req.logout();
			res.redirect('/login');
		});

	app.route('/profile')
		.get(isLoggedIn, function (req, res) {
			res.sendFile(path + '/public/profile.html');
		});

	app.route('/api/:id')
		.get(isLoggedIn, function (req, res) {
			res.json(req.user.github);
		});

	app.route('/auth/github')
		.get(passport.authenticate('github'));

	app.route('/auth/github/callback')
		.get(passport.authenticate('github', {
			successRedirect: '/',
			failureRedirect: '/login'
		}));

	app.route('/api/:id/clicks')
		.get(isLoggedIn, clickHandler.getClicks)
		.post(isLoggedIn, clickHandler.addClick)
		.delete(isLoggedIn, clickHandler.resetClicks);

	// Added Routes for API projects //

	// Timestamp API project
	app.route('/timestamp')
		.get((req, res) => {
			res.sendFile(path + '/public/timestamp.html');
	});
	app.route('/timestamp/:query')
		.get((req, res) => {
		var queryDate = req.params.query,
		    months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
		    dateObj = {};

		if(+queryDate){
			dateObj.unix = queryDate;
			var nDate = new Date(queryDate * 1000);
			dateObj.natural = months[nDate.getMonth()] + ' ' + nDate.getDate() + ', ' + nDate.getFullYear();
		}else if(!isNaN(Date.parse(queryDate)) ){
			dateObj.unix = Date.parse(queryDate) / 1000;
			dateObj.natural = queryDate;
		}else{
			dateObj.unix = null;
			dateObj.natural = null;
		}

		res.end(JSON.stringify(dateObj));
	});

	// Headers API Project
	app.route('/headers')
		.get( (req, res) => {
			var headersObj = {},
			    reg = /(?:\()([\w\s\d;]+)(?:\))/,
		            userFiltered = reg.exec(req.headers['user-agent']);

			headersObj.ip = req.headers['x-forwarded-for'],
			headersObj.lang = req.headers['accept-language'].split(',')[0],
			headersObj.software = userFiltered[1];

			res.end(JSON.stringify(headersObj));

	});
};
<|endoftext|>