<commit_before>'use strict';

angular.module('countingDown.controllers')
.controller('MainCtrl', function ($scope, $timeout, $moment, $location) {

  $scope.timeDateInput = '';
  $scope.title = 'hgf';
  $scope.years = 0;
  $scope.days = 0;
  $scope.hours = 0;
  $scope.minutes = 0;
  $scope.seconds = 0;

  $scope.hasValidDate = false;
  $scope.hasValidTitle = false;

  var secondsPerYear = 31557600;
  var secondsPerDay = 86400;
  var secondsPerHour = 3600;
  var secondsPerMinute = 60;
  var setQueryStringParams = function (title, unixTime) {
    var encodedTitle = encodeURIComponent(title);

    $location.search({
      title: encodedTitle,
      t: unixTime
    });
  };

  $scope.handleStart = function () {
    $scope.hasValidDate = true;
  };

  var validateTitle = function (title) {
    if (title === 'undefined' || title === 'null' || title === '') {
      $scope.hasValidTitle = false;
      $scope.title = '';
    } else {
      $scope.title = title;
    }
  };

});
<commit_msg>Converting date time  to unix time<commit_after>'use strict';

angular.module('countingDown.controllers')
.controller('MainCtrl', function ($scope, $timeout, $moment, $location) {

  $scope.timeDateInput = '';
  $scope.title = 'hgf';
  $scope.years = 0;
  $scope.days = 0;
  $scope.hours = 0;
  $scope.minutes = 0;
  $scope.seconds = 0;

  $scope.hasValidDate = false;
  $scope.hasValidTitle = false;

  var secondsPerYear = 31557600;
  var secondsPerDay = 86400;
  var secondsPerHour = 3600;
  var secondsPerMinute = 60;
  var unixTime = 0;

  var setQueryStringParams = function (title, unixTime) {
    var encodedTitle = encodeURIComponent(title);

    $location.search({
      title: encodedTitle,
      t: unixTime
    });
  };

  var convertTimeToUnix = function (dateTime) {
    var momentTime = $moment(dateTime);
    return momentTime.unix();
  };

  $scope.handleStart = function () {
    $scope.hasValidDate = true;
  };

  var validateTitle = function (title) {
    if (title === 'undefined' || title === 'null' || title === '') {
      $scope.hasValidTitle = false;
      $scope.title = '';
    } else {
      $scope.title = title;
    }
  };

});
<|endoftext|>


<commit_before>module.exports = function(options, callback) {

	var path = require('flavored-path');
	var fs = require('fs');
	var childProcess = require('child_process');

	// due to bug in jpgjs processing OSX jpg images https://github.com/notmasteryet/jpgjs/issues/34
	// when requesting JPG capture as PNG, so JIMP can read it
	var ext = extension(options.output);
	if(ext === "jpeg" || ext === "jpg") {
		options.intermediate = path.resolve(path.join(__dirname, uniqueId() + ".png")); // create an intermediate file that can be processed, then deleted
		capture(options.intermediate, callbackReturn);
	}
	else
		capture(options.output, callbackReturn); // when jpegjs bug fixed, only need this line

	function callbackReturn(error, success) {
		// called from capture
		// callback with options, in case options added
		callback(error, options);
	}

	function uniqueId() {
		function s4() {
			return Math.floor((1 + Math.random()) * 0x10000)
				.toString(16)
				.substring(1);
		}
		return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
			s4() + '-' + s4() + s4() + s4();
	}

	function extension(file) {
		return path.extname(file).toLowerCase().substring(1);
	}

	function capture(output, callback) {
		var cmd = "screencapture"
			+ " -t " + path.extname(output).toLowerCase().substring(1) // will create PNG by default
			+ " -x " + output.replace(/ /g, '\\ ') + "";

		childProcess.exec(cmd, function(error, stdout, stderr) {
			if(error)
				callback(error, null);
			else {
				try {
					fs.statSync(output);
					callback(null, true);
				}
				catch (error) {
					callback(error, null);
				}
			}
		});
	}
};<commit_msg>Changed exec to spawn<commit_after>module.exports = function(options, callback) {
	var path = require('path');
	var fs = require('fs');
	var childProcess = require('child_process');

	// due to bug in jpgjs processing OSX jpg images https://github.com/notmasteryet/jpgjs/issues/34
	// when requesting JPG capture as PNG, so JIMP can read it
	var ext = extension(options.output);
	if(ext === "jpeg" || ext === "jpg") {
		options.intermediate = path.resolve(path.join(__dirname, uniqueId() + ".png")); // create an intermediate file that can be processed, then deleted
		capture(options.intermediate, callbackReturn);
	}
	else
		capture(options.output, callbackReturn); // when jpegjs bug fixed, only need this line

	function callbackReturn(error, success) {
		// called from capture
		// callback with options, in case options added
		callback(error, options);
	}

	function uniqueId() {
		function s4() {
			return Math.floor((1 + Math.random()) * 0x10000)
				.toString(16)
				.substring(1);
		}
		return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
			s4() + '-' + s4() + s4() + s4();
	}

	function extension(file) {
		return path.extname(file).toLowerCase().substring(1);
	}

	function capture(output, callback) {
		var cmd = "screencapture";
		var args = [
			// will create PNG by default
			"-t",
			path.extname(output).toLowerCase().substring(1),
			"-x",
			output
		];

		var captureChild = childProcess.spawn(cmd, args);

		captureChild.on('close', function(error) {
			if (error)
				callback(error.toString());
			else
				callback();
		});

		captureChild.stderr.on('data', function(data) {
			callback(data.toString());
		});
	}
};<|endoftext|>


<commit_before>#!/usr/bin/env node

'use strict'

const request = require('request')

/**
* @desc createEndpointsURL oncatenate the parts of an endpoint url from a task
* and an id.
* @param {string} task The name of the task to be requested
* @param {string} id The id of either a project or a submission
* @return {string} The endpoint URL
*/
function createEndpointsURL (task, id) {
  let base = 'https://review-api.udacity.com/api/v1'
  return {
    'certifications': `${base}/me/certifications/`,
    'assigned': `${base}/me/submissions/assigned/`,
    'submissions': `${base}/me/submissions/`,
    'feedbacks': `${base}/me/student_feedbacks/`,
    'stats': `${base}/me/student_feedbacks_stats/`,
    'completed': `${base}/me/submissions/completed/`,
    'assign': `${base}/projects/${id}/submissions/assign`,
    'unassign': `${base}/submissions/${id}/unassign`
  }[task]
}

/**
* @desc apiCall Calls an endpoint.
* @param {string} task The task to be requested
* @param {string} method The method to be used
* @param {string} id The id of the project or the submission
* @return Promise with the response
*/
module.exports = (task, method = 'GET', id = '',isChinese=true) => {
  if (isChinese){
    return requestInChinese(task,method,id)
  } else {
    return requestInEnglish(task,method,id)
  }
}

function requestInChinese(task,method = 'GET',id = ''){
    var options = {
    url : createEndpointsURL(task, id),
    method : method,
    headers : {
      'Authorization': require('./apiConfig').token
    },
    json: true,
    form: {lang:"zh-cn"}
  }
  return new Promise((resolve, reject) => {
    request(options, (err, res, body) => {
      if (err) {
        reject(err)
      } else if (res.statusCode === 401) {
        throw new Error('401: Unauthorized')
      }
      resolve(res)
    })
  })
}

function requestInEnglish(task , method = 'GET' , id = '') {
    var options = {
    url : createEndpointsURL(task, id),
    method : method,
    headers : {
      'Authorization': require('./apiConfig').token
    },
    json: true
  }
  return new Promise((resolve, reject) => {
    request(options, (err, res, body) => {
      if (err) {
        reject(err)
      } else if (res.statusCode === 401) {
        throw new Error('401: Unauthorized')
      }
      resolve(res)
    })
  })
}
<commit_msg>Fix Bug: add time out<commit_after>#!/usr/bin/env node

'use strict'

const request = require('request')

/**
* @desc createEndpointsURL oncatenate the parts of an endpoint url from a task
* and an id.
* @param {string} task The name of the task to be requested
* @param {string} id The id of either a project or a submission
* @return {string} The endpoint URL
*/
function createEndpointsURL (task, id) {
  let base = 'https://review-api.udacity.com/api/v1'
  return {
    'certifications': `${base}/me/certifications/`,
    'assigned': `${base}/me/submissions/assigned/`,
    'submissions': `${base}/me/submissions/`,
    'feedbacks': `${base}/me/student_feedbacks/`,
    'stats': `${base}/me/student_feedbacks_stats/`,
    'completed': `${base}/me/submissions/completed/`,
    'assign': `${base}/projects/${id}/submissions/assign`,
    'unassign': `${base}/submissions/${id}/unassign`
  }[task]
}

/**
* @desc apiCall Calls an endpoint.
* @param {string} task The task to be requested
* @param {string} method The method to be used
* @param {string} id The id of the project or the submission
* @return Promise with the response
*/
module.exports = (task, method = 'GET', id = '',isChinese=true) => {
  if (isChinese){
    return requestInChinese(task,method,id)
  } else {
    return requestInEnglish(task,method,id)
  }
}

function requestInChinese(task,method = 'GET',id = ''){
    var options = {
    url : createEndpointsURL(task, id),
    method : method,
    headers : {
      'Authorization': require('./apiConfig').token
    },
    json: true,
    form: {lang:"zh-cn"},
    timeout: 20000
  }
  return new Promise((resolve, reject) => {
    request(options, (err, res, body) => {
      if (err) {
        reject(err)
        if (err.code === 'ETIMEDOUT'){
          throw new Error('time out\n')
        }
      } else if (res.statusCode === 401) {
        throw new Error('401: Unauthorized')
      }
      resolve(res)
    })
  })
}

function requestInEnglish(task , method = 'GET' , id = '') {
    var options = {
    url : createEndpointsURL(task, id),
    method : method,
    headers : {
      'Authorization': require('./apiConfig').token
    },
    json: true,
    timeout: 20000
  }
  return new Promise((resolve, reject) => {
    request(options, (err, res, body) => {
      if (err) {
        reject(err)
        if (err.code === 'ETIMEDOUT'){
          throw new Error('time out\n')
        }
      } else if (res.statusCode === 401) {
        throw new Error('401: Unauthorized')
      }
      resolve(res)
    })
  })
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) (2017) - Aikar's Minecraft Timings Parser
 *
 *  Written by Aikar <aikar@aikar.co>
 *    + Contributors (See AUTHORS)
 *
 *  http://aikar.co
 *  http://starlis.com
 *
 *  @license MIT
 *
 */
const webpack = require('webpack');
const path = require('path');
const fs = require('fs');
const gutil = require("gulp-util");
const CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin");
const DefinePlugin = require('webpack/lib/DefinePlugin');
const ProvidePlugin = require('webpack/lib/ProvidePlugin');
const UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin');
const DedupePlugin = require('webpack/lib/optimize/DedupePlugin');
const EnvironmentPlugin = require('webpack/lib/EnvironmentPlugin');
const AssetsPlugin = require('assets-webpack-plugin');
const WebpackAutoCleanBuildPlugin = require("webpack-auto-clean-build-plugin");
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

const cssPattern = '_[name]_[local]-[hash:5]';
module.exports = function(isProduction, watch) {
	watch = watch || false;
	process.env.NODE_ENV = isProduction ? "production" : "development";
	gutil.log("[webpack] isProduction: " + (isProduction ? "true" : "false"));

	function webpackOutput(cb) {
		return function(err, stats) {
			if(err) throw new gutil.PluginError("webpack", err);
			let statLog = stats.toString({
				assets: true,
				colors: true,
				version: false,
				hash: false,
				timings: false,
				chunks: false,
				chunkModules: false,
			});
			for (const line of statLog.split("\n")) {
				gutil.log("[webpack]", line);
			}
			cb && cb();
		}
	}

	const config = {
		context: __dirname,
		entry: {
			vendor: [
				"babel-polyfill",
				"jquery",
				"chart.js",
				"react",
				"react-dom",
			],
			timings: ["./src/js/timings"]
		},
		watch: watch,
		bail: isProduction,
		cache: !isProduction,
		devtool: isProduction ? 'cheap-module-source-map' : 'cheap-module-eval-source-map',
		output: {
			path: path.join(__dirname, "dist"),
			publicPath: "dist/", // relative path for github pages
			filename: "[name].[chunkhash].js",
			chunkFilename: "chunk.[id].[chunkhash].js",
			pathinfo: !isProduction,
		},
		resolve: {
			extensions: ['.js', '.jsx']
		},
		recordsOutputPath: path.join(__dirname, ".cache", "records.json"),
		module: {
			rules: [
				{
					test: [/\.(js|jsx)$/],
					exclude: /node_modules/,
					use: {
						loader: 'babel-loader',
						options: {
							cacheDirectory: isProduction ? null : '.cache/babel',
							"presets": [
								["es2015", {"loose": true, modules: false}],
								"react",
								"stage-0"
							],
							plugins: [
								'transform-runtime'
							],
							babelrc: false,
						}
					}
				},

				//{ test: /\.css$/, use: ["style-loader"] },
				{
					test: /\.scss$/,
					exclude: /(node_modules)/,
					loader: ExtractTextPlugin.extract({
						fallbackLoader: 'style-loader',
						loader: [
							{
								loader: 'css-loader',
								query: {
									sourceMap: true,
									localIdentName: cssPattern,
									importLoaders: 1
								}
							},
							'postcss-loader',
							{
								loader: 'sass-loader',
								query: {
									sourceMap: true
								}
							}
						]
					})
				},
				{
					test: /\.(png|jpg|gif)$/, use: [{
						loader: "url-loader",
						options: {
							prefix: "img/",
							limit: 5000
						}
					}]
				},
				{
					test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, use: [{
						loader: "url-loader",
						options: {
							limit: 10000,
							mimetype: "application/font-woff"
						}
					}],
				},
				{
					test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, use: [{
						loader: "url-loader",
						options: {
							limit: 10000,
							mimetype: "application/octet-stream"
						}
					}]
				},
				{ test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, use: ["file-loader"] },
				{
					test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, use: [{
						loader: "url-loader",
						options: {
							limit: 10000,
							mimetype: "image/svg+xml"
						}
					}]
				}
			]
		},
		plugins: [
			new webpack.LoaderOptionsPlugin({
				minimize: isProduction,
				debug: !isProduction,
				options: {
					context: __dirname
				}
			}),
			new CleanWebpackPlugin([path.join(__dirname, "dist")], {
				verbose: false,
			}),
			new WebpackAutoCleanBuildPlugin(),
			new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 20 }),
			new DefinePlugin({
				'process.env.NODE_ENV': JSON.stringify(isProduction ? 'production' : 'development'),
			}),
			isProduction ? new UglifyJsPlugin({
				mangle: true,
				sourceMap: true,
			}) : null,
			new AssetsPlugin({path: path.join(__dirname, "dist")}),
			new CommonsChunkPlugin({
				name: 'vendor',
				minChunks: 3,
				filename: "vendor.[chunkhash].js",
			}),
			new ExtractTextPlugin({
				filename: "[name].[chunkhash].css",
				disable: false,
				allChunks: true
			}),
			function() {
				// Delete the empty .js files for themes
				const compiler = this;
				compiler.plugin("emit", (result, callback) => {
					for (const id of Object.keys(result.assets)) {
						if (id.match(/timings-theme.*\.js(\.map)?$/)) {
							delete result.assets[id];
						}
					}
					return callback();
				});
			}
		],
		// examples for chunks: https://github.com/webpack/webpack/tree/master/examples/multiple-entry-points
		node: {
			fs: 'empty',
			net: 'empty',
			tls: 'empty'
		}
	};
	const themes = fs.readdirSync(path.join(__dirname, "src/css/themes/"));
	for (const themeFile of themes) {
		const theme = themeFile.match(/(.*)\.scss/)[1];
		config.entry['timings-theme-' + theme] = "./src/css/themes/" + themeFile;
	}

	config.plugins = config.plugins.filter((plugin) => plugin); // remove nulls
	Object.defineProperty(config, 'reporter', {
		value: webpackOutput,
		enumerable: false
	});
	return config;
};
const main = path.basename(require.main.filename);
if (main !== 'gulp.js') {
	// running as main webpack process
	module.exports = module.exports(process.env.NODE_ENV === 'production');
}

function escapeRegExpString(str) { return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); }
function pathToRegExp(p) { return new RegExp("^" + escapeRegExpString(p)); }
<commit_msg>change to [hash] for filenames to avoid cache issues<commit_after>/*
 * Copyright (c) (2017) - Aikar's Minecraft Timings Parser
 *
 *  Written by Aikar <aikar@aikar.co>
 *    + Contributors (See AUTHORS)
 *
 *  http://aikar.co
 *  http://starlis.com
 *
 *  @license MIT
 *
 */
const webpack = require('webpack');
const path = require('path');
const fs = require('fs');
const gutil = require("gulp-util");
const CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin");
const DefinePlugin = require('webpack/lib/DefinePlugin');
const ProvidePlugin = require('webpack/lib/ProvidePlugin');
const UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin');
const DedupePlugin = require('webpack/lib/optimize/DedupePlugin');
const EnvironmentPlugin = require('webpack/lib/EnvironmentPlugin');
const AssetsPlugin = require('assets-webpack-plugin');
const WebpackAutoCleanBuildPlugin = require("webpack-auto-clean-build-plugin");
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

const cssPattern = '_[name]_[local]-[hash:5]';
module.exports = function(isProduction, watch) {
	watch = watch || false;
	process.env.NODE_ENV = isProduction ? "production" : "development";
	gutil.log("[webpack] isProduction: " + (isProduction ? "true" : "false"));

	function webpackOutput(cb) {
		return function(err, stats) {
			if(err) throw new gutil.PluginError("webpack", err);
			let statLog = stats.toString({
				assets: true,
				colors: true,
				version: false,
				hash: false,
				timings: false,
				chunks: false,
				chunkModules: false,
			});
			for (const line of statLog.split("\n")) {
				gutil.log("[webpack]", line);
			}
			cb && cb();
		}
	}

	const config = {
		context: __dirname,
		entry: {
			vendor: [
				"babel-polyfill",
				"jquery",
				"chart.js",
				"react",
				"react-dom",
			],
			timings: ["./src/js/timings"]
		},
		watch: watch,
		bail: isProduction,
		cache: !isProduction,
		devtool: isProduction ? 'cheap-module-source-map' : 'cheap-module-eval-source-map',
		output: {
			path: path.join(__dirname, "dist"),
			publicPath: "dist/",
			filename: "[name].[hash].js",
			chunkFilename: "chunk.[id].[hash].js",
			pathinfo: !isProduction,
		},
		resolve: {
			extensions: ['.js', '.jsx']
		},
		recordsOutputPath: path.join(__dirname, ".cache", "records.json"),
		module: {
			rules: [
				{
					test: [/\.(js|jsx)$/],
					exclude: /node_modules/,
					use: {
						loader: 'babel-loader',
						options: {
							cacheDirectory: isProduction ? null : '.cache/babel',
							"presets": [
								["es2015", {"loose": true, modules: false}],
								"react",
								"stage-0"
							],
							plugins: [
								'transform-runtime'
							],
							babelrc: false,
						}
					}
				},

				//{ test: /\.css$/, use: ["style-loader"] },
				{
					test: /\.scss$/,
					exclude: /(node_modules)/,
					loader: ExtractTextPlugin.extract({
						fallbackLoader: 'style-loader',
						loader: [
							{
								loader: 'css-loader',
								query: {
									sourceMap: true,
									localIdentName: cssPattern,
									importLoaders: 1
								}
							},
							'postcss-loader',
							{
								loader: 'sass-loader',
								query: {
									sourceMap: true
								}
							}
						]
					})
				},
				{
					test: /\.(png|jpg|gif)$/, use: [{
						loader: "url-loader",
						options: {
							prefix: "img/",
							limit: 5000
						}
					}]
				},
				{
					test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, use: [{
						loader: "url-loader",
						options: {
							limit: 10000,
							mimetype: "application/font-woff"
						}
					}],
				},
				{
					test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, use: [{
						loader: "url-loader",
						options: {
							limit: 10000,
							mimetype: "application/octet-stream"
						}
					}]
				},
				{ test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, use: ["file-loader"] },
				{
					test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, use: [{
						loader: "url-loader",
						options: {
							limit: 10000,
							mimetype: "image/svg+xml"
						}
					}]
				}
			]
		},
		plugins: [
			new webpack.LoaderOptionsPlugin({
				minimize: isProduction,
				debug: !isProduction,
				options: {
					context: __dirname
				}
			}),
			new CleanWebpackPlugin([path.join(__dirname, "dist")], {
				verbose: false,
			}),
			new WebpackAutoCleanBuildPlugin(),
			new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 20 }),
			new DefinePlugin({
				'process.env.NODE_ENV': JSON.stringify(isProduction ? 'production' : 'development'),
			}),
			isProduction ? new UglifyJsPlugin({
				mangle: true,
				sourceMap: true,
			}) : null,
			new AssetsPlugin({path: path.join(__dirname, "dist")}),
			new CommonsChunkPlugin({
				name: 'vendor',
				minChunks: 3,
				filename: "vendor.[hash].js",
			}),
			new ExtractTextPlugin({
				filename: "[name].[hash].css",
				disable: false,
				allChunks: true
			}),
			function() {
				// Delete the empty .js files for themes
				const compiler = this;
				compiler.plugin("emit", (result, callback) => {
					for (const id of Object.keys(result.assets)) {
						if (id.match(/timings-theme.*\.js(\.map)?$/)) {
							delete result.assets[id];
						}
					}
					return callback();
				});
			}
		],
		// examples for chunks: https://github.com/webpack/webpack/tree/master/examples/multiple-entry-points
		node: {
			fs: 'empty',
			net: 'empty',
			tls: 'empty'
		}
	};
	const themes = fs.readdirSync(path.join(__dirname, "src/css/themes/"));
	for (const themeFile of themes) {
		const theme = themeFile.match(/(.*)\.scss/)[1];
		config.entry['timings-theme-' + theme] = "./src/css/themes/" + themeFile;
	}

	config.plugins = config.plugins.filter((plugin) => plugin); // remove nulls
	Object.defineProperty(config, 'reporter', {
		value: webpackOutput,
		enumerable: false
	});
	return config;
};
const main = path.basename(require.main.filename);
if (main !== 'gulp.js') {
	// running as main webpack process
	module.exports = module.exports(process.env.NODE_ENV === 'production');
}

function escapeRegExpString(str) { return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); }
function pathToRegExp(p) { return new RegExp("^" + escapeRegExpString(p)); }
<|endoftext|>


<commit_before>var HtmlWebpackPlugin = require('html-webpack-plugin')
var autoprefixer      = require('autoprefixer');
var csswring          = require('csswring');
var webpack           = require('webpack');
var path              = require('path');
var fs                = require('fs');

var config = {
  entry: ['webpack/hot/dev-server', './src/scripts/app.js'],
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: '[name].[hash].js',
    publicPath: '/'
  },
  devServer: {
    inline:true,
    port: 9090,
  },
  eslint: {
    reporter: require('eslint-friendly-formatter'),
  },
  module: {
    loaders: [{
      test: /\.js$/,
      loaders: ['react-hot', 'babel?presets[]=es2015&presets[]=react', 'eslint'],
      exclude: /node_modules/
    }, {
      test: /\.scss$/,
      loader: 'style!css!postcss!sass'
    }, {
      test: /\.woff$|\.ttf$|\.wav$|\.mp3$/,
      loader: 'file'
    }, {
      test: /\.jpe?g$|\.gif$|\.png$|\.svg$/,
      loaders: [
        'url?limit=8192&hash=sha512&digest=hex&name=[hash].[ext]',
        'image?bypassOnDebug&optimizationLevel=7&interlaced=false'
      ]
    }]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      inject: 'body'
    })
  ],
  postcss: [autoprefixer, csswring],
  devtool: 'eval',
  devtool: 'sourcemap',
};

module.exports = config;
<commit_msg>adding sass to loader<commit_after>var HtmlWebpackPlugin = require('html-webpack-plugin')
var autoprefixer      = require('autoprefixer');
var csswring          = require('csswring');
var webpack           = require('webpack');
var path              = require('path');
var fs                = require('fs');

var config = {
  entry: ['webpack/hot/dev-server', './src/scripts/app.js'],
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: '[name].[hash].js',
    publicPath: '/'
  },
  devServer: {
    inline:true,
    port: 9090,
  },
  eslint: {
    reporter: require('eslint-friendly-formatter'),
  },
  module: {
    loaders: [{
      test: /\.js$/,
      loaders: ['react-hot', 'babel?presets[]=es2015&presets[]=react', 'eslint'],
      exclude: /node_modules/
    }, {
      test: /\.scss$|\.sass$/,
      loader: 'style!css!postcss!sass'
    }, {
      test: /\.woff$|\.ttf$|\.wav$|\.mp3$/,
      loader: 'file'
    }, {
      test: /\.jpe?g$|\.gif$|\.png$|\.svg$/,
      loaders: [
        'url?limit=8192&hash=sha512&digest=hex&name=[hash].[ext]',
        'image?bypassOnDebug&optimizationLevel=7&interlaced=false'
      ]
    }]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      inject: 'body'
    })
  ],
  postcss: [autoprefixer, csswring],
  devtool: 'eval',
  devtool: 'sourcemap',
};

module.exports = config;
<|endoftext|>


<commit_before>'use strict';

angular.module('openSenseMapApp')
  .controller('RegisterCtrl', ['$scope', '$state', '$http', '$q', '$timeout', '$filter', '$location', 'leafletData', 'OpenSenseBoxAPI', 'SensorIcons', '$translate', function($scope, $state, $http, $q, $timeout, $filter, $location, leafletData, OpenSenseBoxAPI, SensorIcons, $translate){
    $scope.osemapi = OpenSenseBoxAPI;
    $scope.icons = SensorIcons;
    $scope.alerts = [];
    $scope.editing = {};
    $scope.isCustom = {};
    $scope.sensorSetup = "";
    $scope.models = {
      home: false,
      basic: false,
      custom: false,

      wifi: false,
      ethernet: false
    };

    $scope.modelSelected = {
      id: false,
      name: false
    };

    $scope.markers = {};

    //new user object
    $scope.user = {
      firstname: '',
      lastname: '',
      email: '',
      lang: 'de_DE'
    };

    //new sensebox object
    $scope.newSenseBox = {
      id: '',
      name: '',
      model: '',
      boxType: 'fixed',
      sensors: [],
      tag: '',
      exposure: '',
      orderID: '',
      loc: [{
        'type':'feature',
        'geometry': {
          'type':'Point',
          'coordinates':[]
        }
      }]
    };

    $scope.mqttEnabled = false;
    $scope.mqtt = {
      url: '',
      topic: '',
      messageFormat: '',
      decodeOptions: '',
      connectionOptions: ''
    };

    $scope.editMarkerInput =  angular.copy($scope.markers);
    $scope.$watchCollection('editMarkerInput.box', function (newValue) {
      if (newValue && newValue.lat && newValue.lng) {
        if ($scope.markers.box === undefined) {
          $scope.markers.box = {};
        }
        $scope.markers.box.lng = newValue.lng;
        $scope.markers.box.lat = newValue.lat;
      }
    });

    $scope.invalidHardware = false;

    $scope.submit = function() {
      console.log($scope.sensors);
      if($scope.rc.sampleWizard.currentIndex !== 1) {
        this.generateID();
        this.goToMap();
      } else if ($scope.rc.sampleWizard.currentIndex === 1) {
        if ($scope.modelSelected.id === false) {
          $scope.invalidHardware = true;
        } else {
          $scope.invalidHardware = false;
        }

        if ($scope.sensors.length === 0) {
          $scope.sensorIncomplete = true;
        } else {
          $scope.sensorIncomplete = false;
        }
      }
      $scope.rc.sampleWizard.forward();
    };

    $scope.goToMap = function() {
      $timeout(function() {
        leafletData.getMap().then(function(map) {
          $scope.$watch('$viewContentLoaded', function() {
            map.invalidateSize();
          });
        });
      }, 100);
    };

    $scope.$watch('modelSelected.id', function(newValue) {
      console.log('Selected ' + newValue);
      switch(newValue) {
        case 'homeEthernet':
          $scope.modelSelected.name = 'senseBox Home Ethernet';
          $scope.models = {
            home: true,
            basic: false,
            custom: false,
            wifi: false,
            ethernet: true
          };
          $scope.sensors = [];
          $scope.sensorSetup = $scope.modelSelected.id;
          break;
        case 'homeWifi':
          $scope.modelSelected.name = 'senseBox Home Wifi';
          $scope.models = {
            home: true,
            basic: false,
            custom: false,
            wifi: true,
            ethernet: false
          };
          $scope.sensors = [];
          $scope.sensorSetup = $scope.modelSelected.id;
          break;
        case 'basicEthernet':
          $scope.modelSelected.name = 'senseBox Basic Ethernet';
          $scope.models = {
            home: false,
            basic: true,
            custom: false,
            wifi: false,
            ethernet: true
          };
          $scope.sensors = [];
          $scope.sensorSetup = $scope.modelSelected.id;
          break;
        case 'basicWifi':
          $scope.modelSelected.name = 'senseBox Basic Wifi';
          $scope.models = {
            home: false,
            basic: true,
            custom: false,
            wifi: true,
            ethernet: false
          };
          $scope.sensors = [];
          $scope.sensorSetup = $scope.modelSelected.id;
          break;
        case 'custom':
          $scope.modelSelected.name = 'senseBox manuelle Konfiguration';
          $scope.models = {
            home: false,
            basic: false,
            custom: true,
            wifi: false,
            ethernet: false
          };
          $scope.sensorSetup = "";
          break;
        default:
          $scope.modelSelected.name = false;
          break;
      }
      $scope.invalidHardware = false;
    });

    $scope.enableMQTT = function () {
      $scope.mqttEnabled = !$scope.mqttEnabled;
    }

    $scope.defaults = {
      minZoom: 2,
      maxZoom: 22,
      tileLayer: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
      tileLayerOptions: {
        subdomains: 'abc',
        attribution: '© OpenStreetMap contributors | Tiles © Mapbox',
        detectRetina: true,
        reuseTiles: true,
        maxZoom: 22,
      },
      worldCopyJump: true,
      scrollWheelZoom: true,
      center: {
        lat: 51.04139389812637,
        lng: 10.21728515625,
        zoom: 5
      }
    };
    angular.extend($scope, {
      center: {
        autoDiscover: true
      },
      events: {
        map: {
          enable: ['click', 'locationfound', 'locationerror'],
          logic: 'emit'
        }
      }
    });

    $scope.edit = function (index) {
      $scope.editing[index]=true;
    };

    $scope.remove = function (index) {
      $scope.sensors.splice(index,1);
      $scope.isCustom[index]=false;
      $scope.editing[index]=false;
      for(var i=0; i < $scope.sensors.length; i++){
        $scope.sensors[i].id=i;
      }
      if ( $scope.sensors.length === 0) {
        $scope.sensorSetup = "";
        $scope.sensorIncomplete = true;
      } else {
        $scope.sensorSetup = JSON.stringify($scope.sensors);
      }
    };

    $scope.makeCustom = function(title, index) {
      if(title==='Anderer'){
        $scope.isCustom[index]=true;
      } else {
        return false;
      }
    };

    $scope.add = function () {
      var sensor = {
        id: $scope.sensors.length,
        icon: '',
        title: '',
        unit: '',
        sensorType: ''
      };
      $scope.sensors.push(sensor);
      $scope.sensorSetup = JSON.stringify($scope.sensors);
      this.edit(sensor.id);
      $scope.sensorIncomplete = false;
    };

    $scope.setSensorIcon = function(sensor,newIcon) {
      sensor.icon = newIcon.name;
    };

    $scope.fixedBox = true;
    $scope.change = function () {
      $scope.fixedBox = !$scope.fixedBox;
    };
    $scope.sensors = [];

    // example sensor list used for custom setup
    $scope.phenomenoms = [
      {value: 1, text: 'Temperatur', unit:'°C', type:'BMP085'},
      {value: 2, text: 'Luftfeuchtigkeit', unit:'%', type:'DHT11'},
      {value: 3, text: 'Luftdruck', unit:'Pa', type:'BMP085'},
      {value: 4, text: 'Schall', unit:'Pegel', type:'LM386'},
      {value: 5, text: 'Licht', unit:'Pegel', type:'GL5528'},
      {value: 6, text: 'Licht (digital)', unit: 'lx', type: 'TSL2561'},
      {value: 7, text: 'UV-Intensität', unit: 'µW/cm²', type: 'GUVA-S12D'},
      {value: 8, text: 'Kamera', unit: '', type: ''},
      {value: 99, text: 'Anderer', unit: '', type: ''},
    ];

    $scope.generateID = function () {
      var timestamp = (new Date().getTime() / 1000 | 0).toString(16);
      var objectid = timestamp + 'xxxxxxxxxxxxxxxx'.replace(/[x]/g, function() {
        return (Math.random() * 16 | 0).toString(16);
      }).toLowerCase();
      $scope.newSenseBox.orderID = objectid;
    };

    $scope.fallback = function(copy) {
      window.prompt('Press cmd+c to copy the text below.', copy);
    };

    $scope.showMap = false;
    $scope.$watch('showMap', function(value) {
      if (value === true) {
        leafletData.getMap('map_register').then(function(map) {
          map.invalidateSize();
        });
      }
    });

    $scope.open = {
      collapse1: true,
      collapse2: false,
      collapse3: false
    };

    $scope.$watchCollection('open.collapse2',function (newValue) {
      if (newValue) {
        $scope.modelSelected.id = 'custom';
      }
    });

    $scope.goToMap = function() {
      $timeout(function() {
        leafletData.getMap('map_register').then(function(map) {
          $scope.$watch('$viewContentLoaded', function() {
            map.invalidateSize();
          });
        });
      }, 100);
    };

    $scope.$on('leafletDirectiveMarker.map_register.dragend', function(e, args) {
      $scope.markers[args.modelName].lat = parseFloat(args.model.lat.toFixed(6));
      $scope.markers[args.modelName].lng = parseFloat(args.model.lng.toFixed(6));
      $scope.editMarkerInput =  angular.copy($scope.markers);
    });

    $scope.$on('leafletDirectiveMap.map_register.click', function(e, args) {
      if (Object.keys($scope.markers).length === 0) {
        $scope.markers.box = {
          'lat': parseFloat(args.leafletEvent.latlng.lat.toFixed(6)),
          'lng': parseFloat(args.leafletEvent.latlng.lng.toFixed(6)),
          'draggable': true
        };
      } else {
        $scope.markers.box.lat = parseFloat(args.leafletEvent.latlng.lat.toFixed(6));
        $scope.markers.box.lng = parseFloat(args.leafletEvent.latlng.lng.toFixed(6));
        $scope.markers.box.draggable = true;
      }
      $scope.editMarkerInput =  angular.copy($scope.markers);
    });

    $scope.$on('leafletDirectiveMap.map_register.locationfound', function(e, args){
      if (Object.keys($scope.markers).length === 0) {
        $scope.markers.box = {
          'lat': parseFloat(args.leafletEvent.latlng.lat.toFixed(6)),
          'lng': parseFloat(args.leafletEvent.latlng.lng.toFixed(6)),
          'draggable': true
        };
      } else {
        $scope.markers.box.lat = parseFloat(args.leafletEvent.latlng.lat.toFixed(6));
        $scope.markers.box.lng = parseFloat(args.leafletEvent.latlng.lng.toFixed(6));
        $scope.markers.box.draggable = true;
      }
      leafletData.getMap('map_register').then(function(map) {
        map.setView([args.leafletEvent.latlng.lat,args.leafletEvent.latlng.lng],16);
      });
      $scope.editMarkerInput =  angular.copy($scope.markers);
    });

    $scope.$on('leafletDirectiveMap.map_register.locationerror', function(event){
      //TODO set alert
      console.log(event);
    });

    $scope.goToBox = function () {
      $state.go('explore.map.boxdetails', { id: $scope.newSenseBox.id });
    };

    var downloadArduino = function () {
      var boxid = $scope.newSenseBox.id;
      var apikey = $scope.newSenseBox.apikey;
      $http.get($scope.osemapi.url+'/boxes/'+boxid+'/script', { headers: { 'X-ApiKey': apikey } })
        .success(function(data, status){
          $scope.boxScript = data;
        }).error(function(data, status){
          // todo: display an error message
      });
    };

    var loadSensors = function () {
      var boxid = $scope.newSenseBox.id;
      $http.get($scope.osemapi.url+'/boxes/'+boxid, {})
        .success(function(data, status){
          $scope.registeredSensors = data["sensors"];
        }).error(function(data, status){
          // todo: display an error message
      });
    }

    $scope.completeRegistration = function () {
      $scope.alerts = [];
      $scope.newSenseBox.apikey = $scope.newSenseBox.orderID;
      $scope.newSenseBox.user = $scope.user;
      if ($scope.mqttEnabled) {
        $scope.newSenseBox.mqtt = $scope.mqtt;
      }
      $scope.newSenseBox.loc[0].geometry.coordinates.push($scope.markers.box.lng);
      $scope.newSenseBox.loc[0].geometry.coordinates.push($scope.markers.box.lat);
      if ($translate.proposedLanguage() !== undefined) {
        $scope.newSenseBox.user["lang"] = $translate.proposedLanguage();
      }
      if ($scope.modelSelected.id === 'custom') {
        for (var i = 0; i < $scope.sensors.length; i++) {
          $scope.newSenseBox.sensors = $scope.sensors;
        }
      } else {
        $scope.newSenseBox.model = $scope.modelSelected.id;
      }

      $http.post($scope.osemapi.url+'/boxes', $scope.newSenseBox)
        .success( function (data) {
          $scope.newSenseBox.id = data.boxes[0];
          $scope.rc.sampleWizard.forward();
          $translate('REGISTRATION_SUCCESS').then(function (msg) {
            var alert = {
              type: 'success',
              msg: msg
            };
            $scope.alerts.push(alert);
            $scope.regSuccess = true;
          });
          downloadArduino();
          loadSensors();
        })
        .error( function (err) {
          $translate('REGISTRATION_FAIL').then(function (msg) {
            var alert = {
              type: 'danger',
              msg: msg
            };
            $scope.alerts.push(alert);
          });
        });
    };
}]);
<commit_msg>fix map in registration<commit_after>'use strict';

angular.module('openSenseMapApp')
  .controller('RegisterCtrl', ['$scope', '$state', '$http', '$q', '$timeout', '$filter', '$location', 'leafletData', 'OpenSenseBoxAPI', 'SensorIcons', '$translate', function($scope, $state, $http, $q, $timeout, $filter, $location, leafletData, OpenSenseBoxAPI, SensorIcons, $translate){
    $scope.osemapi = OpenSenseBoxAPI;
    $scope.icons = SensorIcons;
    $scope.alerts = [];
    $scope.editing = {};
    $scope.isCustom = {};
    $scope.sensorSetup = "";
    $scope.models = {
      home: false,
      basic: false,
      custom: false,

      wifi: false,
      ethernet: false
    };

    $scope.modelSelected = {
      id: false,
      name: false
    };

    $scope.markers = {};

    //new user object
    $scope.user = {
      firstname: '',
      lastname: '',
      email: '',
      lang: 'de_DE'
    };

    //new sensebox object
    $scope.newSenseBox = {
      id: '',
      name: '',
      model: '',
      boxType: 'fixed',
      sensors: [],
      tag: '',
      exposure: '',
      orderID: '',
      loc: [{
        'type':'feature',
        'geometry': {
          'type':'Point',
          'coordinates':[]
        }
      }]
    };

    $scope.mqttEnabled = false;
    $scope.mqtt = {
      url: '',
      topic: '',
      messageFormat: '',
      decodeOptions: '',
      connectionOptions: ''
    };

    $scope.editMarkerInput =  angular.copy($scope.markers);
    $scope.$watchCollection('editMarkerInput.box', function (newValue) {
      if (newValue && newValue.lat && newValue.lng) {
        if ($scope.markers.box === undefined) {
          $scope.markers.box = {};
        }
        $scope.markers.box.lng = newValue.lng;
        $scope.markers.box.lat = newValue.lat;
      }
    });

    $scope.invalidHardware = false;

    $scope.submit = function() {
      console.log($scope.mqttEnabled);
      if($scope.rc.sampleWizard.currentIndex === 1) {
        this.generateID();
        this.goToMap();
      } else if ($scope.rc.sampleWizard.currentIndex === 2) {
        if ($scope.modelSelected.id === false) {
          $scope.invalidHardware = true;
        } else {
          $scope.invalidHardware = false;
        }

        if ($scope.sensors.length === 0) {
          $scope.sensorIncomplete = true;
        } else {
          $scope.sensorIncomplete = false;
        }
      }
      $scope.rc.sampleWizard.forward();
    };

    $scope.goToMap = function() {
      $timeout(function() {
        leafletData.getMap().then(function(map) {
          $scope.$watch('$viewContentLoaded', function() {
            map.invalidateSize();
          });
        });
      }, 100);
    };

    $scope.$watch('modelSelected.id', function(newValue) {
      console.log('Selected ' + newValue);
      switch(newValue) {
        case 'homeEthernet':
          $scope.modelSelected.name = 'senseBox Home Ethernet';
          $scope.models = {
            home: true,
            basic: false,
            custom: false,
            wifi: false,
            ethernet: true
          };
          $scope.sensors = [];
          $scope.sensorSetup = $scope.modelSelected.id;
          break;
        case 'homeWifi':
          $scope.modelSelected.name = 'senseBox Home Wifi';
          $scope.models = {
            home: true,
            basic: false,
            custom: false,
            wifi: true,
            ethernet: false
          };
          $scope.sensors = [];
          $scope.sensorSetup = $scope.modelSelected.id;
          break;
        case 'basicEthernet':
          $scope.modelSelected.name = 'senseBox Basic Ethernet';
          $scope.models = {
            home: false,
            basic: true,
            custom: false,
            wifi: false,
            ethernet: true
          };
          $scope.sensors = [];
          $scope.sensorSetup = $scope.modelSelected.id;
          break;
        case 'basicWifi':
          $scope.modelSelected.name = 'senseBox Basic Wifi';
          $scope.models = {
            home: false,
            basic: true,
            custom: false,
            wifi: true,
            ethernet: false
          };
          $scope.sensors = [];
          $scope.sensorSetup = $scope.modelSelected.id;
          break;
        case 'custom':
          $scope.modelSelected.name = 'senseBox manuelle Konfiguration';
          $scope.models = {
            home: false,
            basic: false,
            custom: true,
            wifi: false,
            ethernet: false
          };
          $scope.sensorSetup = "";
          break;
        default:
          $scope.modelSelected.name = false;
          break;
      }
      $scope.invalidHardware = false;
    });

    $scope.enableMQTT = function () {
      $scope.mqttEnabled = !$scope.mqttEnabled;
    }

    $scope.defaults = {
      minZoom: 2,
      maxZoom: 22,
      tileLayer: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
      tileLayerOptions: {
        subdomains: 'abc',
        attribution: '© OpenStreetMap contributors | Tiles © Mapbox',
        detectRetina: true,
        reuseTiles: true,
        maxZoom: 22,
      },
      worldCopyJump: true,
      scrollWheelZoom: true,
      center: {
        lat: 51.04139389812637,
        lng: 10.21728515625,
        zoom: 5
      }
    };
    angular.extend($scope, {
      center: {
        autoDiscover: true
      },
      events: {
        map: {
          enable: ['click', 'locationfound', 'locationerror'],
          logic: 'emit'
        }
      }
    });

    $scope.edit = function (index) {
      $scope.editing[index]=true;
    };

    $scope.remove = function (index) {
      $scope.sensors.splice(index,1);
      $scope.isCustom[index]=false;
      $scope.editing[index]=false;
      for(var i=0; i < $scope.sensors.length; i++){
        $scope.sensors[i].id=i;
      }
      if ( $scope.sensors.length === 0) {
        $scope.sensorSetup = "";
        $scope.sensorIncomplete = true;
      } else {
        $scope.sensorSetup = JSON.stringify($scope.sensors);
      }
    };

    $scope.makeCustom = function(title, index) {
      if(title==='Anderer'){
        $scope.isCustom[index]=true;
      } else {
        return false;
      }
    };

    $scope.add = function () {
      var sensor = {
        id: $scope.sensors.length,
        icon: '',
        title: '',
        unit: '',
        sensorType: ''
      };
      $scope.sensors.push(sensor);
      $scope.sensorSetup = JSON.stringify($scope.sensors);
      this.edit(sensor.id);
      $scope.sensorIncomplete = false;
    };

    $scope.setSensorIcon = function(sensor,newIcon) {
      sensor.icon = newIcon.name;
    };

    $scope.fixedBox = true;
    $scope.change = function () {
      $scope.fixedBox = !$scope.fixedBox;
    };
    $scope.sensors = [];

    // example sensor list used for custom setup
    $scope.phenomenoms = [
      {value: 1, text: 'Temperatur', unit:'°C', type:'BMP085'},
      {value: 2, text: 'Luftfeuchtigkeit', unit:'%', type:'DHT11'},
      {value: 3, text: 'Luftdruck', unit:'Pa', type:'BMP085'},
      {value: 4, text: 'Schall', unit:'Pegel', type:'LM386'},
      {value: 5, text: 'Licht', unit:'Pegel', type:'GL5528'},
      {value: 6, text: 'Licht (digital)', unit: 'lx', type: 'TSL2561'},
      {value: 7, text: 'UV-Intensität', unit: 'µW/cm²', type: 'GUVA-S12D'},
      {value: 8, text: 'Kamera', unit: '', type: ''},
      {value: 99, text: 'Anderer', unit: '', type: ''},
    ];

    $scope.generateID = function () {
      var timestamp = (new Date().getTime() / 1000 | 0).toString(16);
      var objectid = timestamp + 'xxxxxxxxxxxxxxxx'.replace(/[x]/g, function() {
        return (Math.random() * 16 | 0).toString(16);
      }).toLowerCase();
      $scope.newSenseBox.orderID = objectid;
    };

    $scope.fallback = function(copy) {
      window.prompt('Press cmd+c to copy the text below.', copy);
    };

    $scope.showMap = false;
    $scope.$watch('showMap', function(value) {
      if (value === true) {
        leafletData.getMap('map_register').then(function(map) {
          map.invalidateSize();
        });
      }
    });

    $scope.open = {
      collapse1: true,
      collapse2: false,
      collapse3: false
    };

    $scope.$watchCollection('open.collapse2',function (newValue) {
      if (newValue) {
        $scope.modelSelected.id = 'custom';
      }
    });

    $scope.goToMap = function() {
      $timeout(function() {
        leafletData.getMap('map_register').then(function(map) {
          $scope.$watch('$viewContentLoaded', function() {
            map.invalidateSize();
          });
        });
      }, 100);
    };

    $scope.$on('leafletDirectiveMarker.map_register.dragend', function(e, args) {
      $scope.markers[args.modelName].lat = parseFloat(args.model.lat.toFixed(6));
      $scope.markers[args.modelName].lng = parseFloat(args.model.lng.toFixed(6));
      $scope.editMarkerInput =  angular.copy($scope.markers);
    });

    $scope.$on('leafletDirectiveMap.map_register.click', function(e, args) {
      if (Object.keys($scope.markers).length === 0) {
        $scope.markers.box = {
          'lat': parseFloat(args.leafletEvent.latlng.lat.toFixed(6)),
          'lng': parseFloat(args.leafletEvent.latlng.lng.toFixed(6)),
          'draggable': true
        };
      } else {
        $scope.markers.box.lat = parseFloat(args.leafletEvent.latlng.lat.toFixed(6));
        $scope.markers.box.lng = parseFloat(args.leafletEvent.latlng.lng.toFixed(6));
        $scope.markers.box.draggable = true;
      }
      $scope.editMarkerInput =  angular.copy($scope.markers);
    });

    $scope.$on('leafletDirectiveMap.map_register.locationfound', function(e, args){
      if (Object.keys($scope.markers).length === 0) {
        $scope.markers.box = {
          'lat': parseFloat(args.leafletEvent.latlng.lat.toFixed(6)),
          'lng': parseFloat(args.leafletEvent.latlng.lng.toFixed(6)),
          'draggable': true
        };
      } else {
        $scope.markers.box.lat = parseFloat(args.leafletEvent.latlng.lat.toFixed(6));
        $scope.markers.box.lng = parseFloat(args.leafletEvent.latlng.lng.toFixed(6));
        $scope.markers.box.draggable = true;
      }
      leafletData.getMap('map_register').then(function(map) {
        map.setView([args.leafletEvent.latlng.lat,args.leafletEvent.latlng.lng],16);
      });
      $scope.editMarkerInput =  angular.copy($scope.markers);
    });

    $scope.$on('leafletDirectiveMap.map_register.locationerror', function(event){
      //TODO set alert
      console.log(event);
    });

    $scope.goToBox = function () {
      $state.go('explore.map.boxdetails', { id: $scope.newSenseBox.id });
    };

    var downloadArduino = function () {
      var boxid = $scope.newSenseBox.id;
      var apikey = $scope.newSenseBox.apikey;
      $http.get($scope.osemapi.url+'/boxes/'+boxid+'/script', { headers: { 'X-ApiKey': apikey } })
        .success(function(data, status){
          $scope.boxScript = data;
        }).error(function(data, status){
          // todo: display an error message
      });
    };

    var loadSensors = function () {
      var boxid = $scope.newSenseBox.id;
      $http.get($scope.osemapi.url+'/boxes/'+boxid, {})
        .success(function(data, status){
          $scope.registeredSensors = data["sensors"];
        }).error(function(data, status){
          // todo: display an error message
      });
    }

    $scope.completeRegistration = function () {
      $scope.alerts = [];
      $scope.newSenseBox.apikey = $scope.newSenseBox.orderID;
      $scope.newSenseBox.user = $scope.user;
      if ($scope.mqttEnabled) {
        $scope.newSenseBox.mqtt = $scope.mqtt;
      }
      $scope.newSenseBox.loc[0].geometry.coordinates.push($scope.markers.box.lng);
      $scope.newSenseBox.loc[0].geometry.coordinates.push($scope.markers.box.lat);
      if ($translate.proposedLanguage() !== undefined) {
        $scope.newSenseBox.user["lang"] = $translate.proposedLanguage();
      }
      if ($scope.modelSelected.id === 'custom') {
        for (var i = 0; i < $scope.sensors.length; i++) {
          $scope.newSenseBox.sensors = $scope.sensors;
        }
      } else {
        $scope.newSenseBox.model = $scope.modelSelected.id;
      }

      $http.post($scope.osemapi.url+'/boxes', $scope.newSenseBox)
        .success( function (data) {
          $scope.newSenseBox.id = data.boxes[0];
          $scope.rc.sampleWizard.forward();
          $translate('REGISTRATION_SUCCESS').then(function (msg) {
            var alert = {
              type: 'success',
              msg: msg
            };
            $scope.alerts.push(alert);
            $scope.regSuccess = true;
          });
          downloadArduino();
          loadSensors();
        })
        .error( function (err) {
          $translate('REGISTRATION_FAIL').then(function (msg) {
            var alert = {
              type: 'danger',
              msg: msg
            };
            $scope.alerts.push(alert);
          });
        });
    };
}]);
<|endoftext|>


<commit_before>module.exports = {
  /* get the reminders due today with req.session.username and
  'new Date().toISOString().slice(0,10)' and return it in JSON.*/
  get: function(req, res) {
    res.type('text/json');
    db.collection("reminders").find({
      name: req.session.username/*,
      dueDate: {$gte: new Date(req.param('today'))},
      startReminding: {$lt: new Date(req.param('today'))}*/
    }).toArray(function(err, reminders) {
      if (!err) // gotta get the contents of the reminders, since they're not static.
        res.send(reminders);
      else
        res.send(500, err);
    });
  },
  /* add 1 or a batch or reminders in the valid JSON format to the db with req.session.username and req.body.reminders.
     if action=add, then add them. if action=remove, then remove them.*/
  post: function(req, res) {
    res.type('text/json');
    // remove existing reminders for this box so that there's no dublicates.
    db.collection("reminders").removeMany({
      $and: [{name: req.session.username}, {box: req.body.box}, {monday: req.body.monday}]
    }, function(err, result) {
      if (!err) {
        if (req.body.options) { // if there aren't options the client just wants to delete reminders
          var m = new Date(req.body.monday);

          var dueDate = new Date(m.getFullYear(),
            m.getMonth(),
            m.getDate() + parseInt(req.body.box.split('').reverse()[0]));

          dueDate.setHours(23, 59, 59, 0); // Until the end of the day

          var startReminders = new Date(dueDate.getFullYear(),
            dueDate.getMonth(),
            dueDate.getDate() - (parseInt(req.body.options.startReminding)+1));

          startReminders.setHours(0, 0, 0, 0); // At the beginning of the day
          var reminders = {
            startRemindingNum: req.body.options.startReminding,
            startReminding: startReminders,
            dueDate: dueDate,

            monday: req.body.monday,
            box: req.body.box,
            description: req.body.description,
            colorCode: req.body.colorCode,

            name: req.session.username
          };
          db.collection("reminders").insert(reminders, function(err, result) {
            if (!err)
              res.send(200);
            else
              res.send(500, err);
          });
        } else {
          res.send(200);
        }
      } else {
        res.end(500, err);
      }
    });
  }
};<commit_msg>quick fix for reminder date thing<commit_after>module.exports = {
  /* get the reminders due today with req.session.username and
  'new Date().toISOString().slice(0,10)' and return it in JSON.*/
  get: function(req, res) {
    res.type('text/json');
    db.collection("reminders").find({
      name: req.session.username/*,
      dueDate: {$gte: new Date(req.param('today'))},
      startReminding: {$lt: new Date(req.param('today'))}*/
    }).toArray(function(err, reminders) {
      if (!err) // gotta get the contents of the reminders, since they're not static.
        res.send(reminders);
      else
        res.send(500, err);
    });
  },
  /* add 1 or a batch or reminders in the valid JSON format to the db with req.session.username and req.body.reminders.
     if action=add, then add them. if action=remove, then remove them.*/
  post: function(req, res) {
    res.type('text/json');
    // remove existing reminders for this box so that there's no dublicates.
    db.collection("reminders").removeMany({
      $and: [{name: req.session.username}, {box: req.body.box}, {monday: req.body.monday}]
    }, function(err, result) {
      if (!err) {
        if (req.body.options) { // if there aren't options the client just wants to delete reminders
          var m = new Date(req.body.monday);

          var dueDate = new Date(m.getFullYear(),
            m.getMonth(),
            m.getDate() + parseInt(req.body.box.split('').reverse()[0]-1));

          dueDate.setHours(23, 59, 59, 0); // Until the end of the day

          var startReminders = new Date(dueDate.getFullYear(),
            dueDate.getMonth(),
            dueDate.getDate() - (parseInt(req.body.options.startReminding)+1));

          startReminders.setHours(0, 0, 0, 0); // At the beginning of the day
          var reminders = {
            startRemindingNum: req.body.options.startReminding,
            startReminding: startReminders,
            dueDate: dueDate,

            monday: req.body.monday,
            box: req.body.box,
            description: req.body.description,
            colorCode: req.body.colorCode,

            name: req.session.username
          };
          db.collection("reminders").insert(reminders, function(err, result) {
            if (!err)
              res.send(200);
            else
              res.send(500, err);
          });
        } else {
          res.send(200);
        }
      } else {
        res.end(500, err);
      }
    });
  }
};<|endoftext|>


<commit_before>'use strict';

require('dotenv').load();

const webpack = require('webpack');
const HTMLPlugin = require('html-webpack-plugin');
// const CleanPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
// require('clean-webpack-plugin');

const production = process.env.NODE_ENV === 'production';

let plugins = [
  new ExtractTextPlugin({filename: 'bundle.css'}),
  new HTMLPlugin({template: `${__dirname}/app/index.html`}),
  new webpack.DefinePlugin({
    __API_URL__: JSON.stringify(process.env.API_URL),
    __DEBUG__: JSON.stringify(!production),
  }),
];

// if(production){
//   plugins = plugins.concat([
//     new webpack.optimize.UglifyJsPlugin({
//       mangle: true,
//       compress: {warnings: false},
//     }),
//     new CleanPlugin(),
//   ]);
// }

module.exports = {
  entry: `${__dirname}/app/entry.js`,
  devtool: production ? false : 'source-map',
  output: {
    filename: 'bundle.js',
    path: `${__dirname}/build`,
  },
  plugins,
  module: {
    loaders: [
      {
        test:/\.js$/,
        // exclude: /node-modules/,
        use: ['babel-loader'],
      },
      {
        test: /\.html$/,
        use: ['html-loader'],
      },
      {
        test: /\.scss$/,
        use: ExtractTextPlugin.extract({
          use: [
            {
              loader: 'css-loader',
              options: {sourceMap:true},
            },
            {
              loader: 'sass-loader',
              options: {
                sourceMap: true,
                includePaths: [`${__dirname}/app/scss`],
              },
            },
          ],
        }),
      },
    ],
  },
};
<commit_msg>disable dotenv - temp fix?<commit_after>'use strict';

// require('dotenv').load();

const webpack = require('webpack');
const HTMLPlugin = require('html-webpack-plugin');
// const CleanPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
// require('clean-webpack-plugin');

const production = process.env.NODE_ENV === 'production';

let plugins = [
  new ExtractTextPlugin({filename: 'bundle.css'}),
  new HTMLPlugin({template: `${__dirname}/app/index.html`}),
  new webpack.DefinePlugin({
    __API_URL__: JSON.stringify(process.env.API_URL),
    __DEBUG__: JSON.stringify(!production),
  }),
];

// if(production){
//   plugins = plugins.concat([
//     new webpack.optimize.UglifyJsPlugin({
//       mangle: true,
//       compress: {warnings: false},
//     }),
//     new CleanPlugin(),
//   ]);
// }

module.exports = {
  entry: `${__dirname}/app/entry.js`,
  devtool: production ? false : 'source-map',
  output: {
    filename: 'bundle.js',
    path: `${__dirname}/build`,
  },
  plugins,
  module: {
    loaders: [
      {
        test:/\.js$/,
        // exclude: /node-modules/,
        use: ['babel-loader'],
      },
      {
        test: /\.html$/,
        use: ['html-loader'],
      },
      {
        test: /\.scss$/,
        use: ExtractTextPlugin.extract({
          use: [
            {
              loader: 'css-loader',
              options: {sourceMap:true},
            },
            {
              loader: 'sass-loader',
              options: {
                sourceMap: true,
                includePaths: [`${__dirname}/app/scss`],
              },
            },
          ],
        }),
      },
    ],
  },
};
<|endoftext|>


<commit_before>(function(app) {
  'use strict';

  var helper = app.helper || require('../helper.js');
  var dom = app.dom || require('../dom.js');
  var Component = app.Component || require('./component.js');
  var Main = app.Main || require('./main.js');
  var EntryCollection = app.EntryCollection || require('../collections/entry-collection.js');
  var Sidebar = app.Sidebar || require('./sidebar.js');

  var Body = Component.inherits(function(props) {
    this.dragCount = this.prop(0);

    this.entryCollection = new EntryCollection({ jsonLoader: dom.loadJSON });

    this.sidebar = new Sidebar({
      element: this.childElement('.sidebar'),
      moduleDragStarter: Body.prototype.moduleDragStarter.bind(this),
      moduleDragEnder: Body.prototype.moduleDragEnder.bind(this),
      moduleDropper: Body.prototype.moduleDropper.bind(this),
      entrySearcher: Body.prototype.entrySearcher.bind(this),
    });

    this.main = new Main({
      element: this.childElement('.main'),
      sidebarToggler: Body.prototype.sidebarToggler.bind(this),
      moduleDragStarter: Body.prototype.moduleDragStarter.bind(this),
      moduleDragEnder: Body.prototype.moduleDragEnder.bind(this),
      loadStarter: Body.prototype.loadStarter.bind(this),
      loadEnder: Body.prototype.loadEnder.bind(this),
    });

    this.registerReadyListener();
  });

  Body.prototype.isDragging = function() {
    return (this.dragCount() > 0);
  };

  Body.prototype.incrementDragCount = function() {
    this.dragCount(this.dragCount() + 1);
  };

  Body.prototype.decrementDragCount = function() {
    this.dragCount(this.dragCount() - 1);
  };

  Body.prototype.currentDemoName = function() {
    return dom.urlQuery(dom.location()).demo || '';
  };

  Body.prototype.demoUrl = function(name) {
    return 'demos/' + name + '.json';
  };

  Body.prototype.registerReadyListener = function() {
    dom.ready(Body.prototype.onready.bind(this));
  };

  Body.prototype.toggleSidebar = function(visible) {
    return dom.transition(this.element(), function() {
      this.sidebar.disabled(!visible);
      this.main.isFullWidth(!visible);
    }.bind(this));
  };

  Body.prototype.loadDemo = function(name) {
    return (name ? this.main.loadUrl(this.demoUrl(name)) : Promise.resolve());
  };

  Body.prototype.render = function() {
    return dom.body();
  };

  Body.prototype.redraw = function() {
    this.redrawDOMToggleClassBy('isDragging', 'dragging');
  };

  Body.prototype.onready = function() {
    this.loadStarter();
    this.entryCollection.load().then(function() {
      this.sidebar.loadContent();
      return this.loadDemo(this.currentDemoName());
    }.bind(this)).catch(function(e) {
      alert(e);
    }).then(function() {
      this.loadEnder();
    }.bind(this));
  };

  Body.prototype.moduleDragStarter = function() {
    this.incrementDragCount();
  };

  Body.prototype.moduleDragEnder = function() {
    this.decrementDragCount();
  };

  Body.prototype.moduleDropper = function(name, x, y) {
    var point = this.main.contentLocalPoint({ x: x, y: y });
    if (point.x < 0 || point.y < 0) {
      return;
    }

    var entry = this.entryCollection.get(name);
    this.main.loadModule(helper.extend({
      title: entry.label,
      name: name,
    }, point), entry.visiblePortNames);
  };

  Body.prototype.entrySearcher = function(searchText) {
    return this.entryCollection.search(searchText);
  };

  Body.prototype.sidebarToggler = function(visible) {
    return this.toggleSidebar(visible);
  };

  Body.prototype.loadStarter = function() {
    this.sidebar.disabled(true);
    this.main.disabled(true);
  };

  Body.prototype.loadEnder = function() {
    this.sidebar.disabled(false);
    this.main.disabled(false);
  };

  if (typeof module !== 'undefined' && module.exports) {
    module.exports = Body;
  } else {
    app.Body = Body;
  }
})(this.app || (this.app = {}));
<commit_msg>Make 'onredraw' event of body component<commit_after>(function(app) {
  'use strict';

  var helper = app.helper || require('../helper.js');
  var dom = app.dom || require('../dom.js');
  var Component = app.Component || require('./component.js');
  var Main = app.Main || require('./main.js');
  var EntryCollection = app.EntryCollection || require('../collections/entry-collection.js');
  var Sidebar = app.Sidebar || require('./sidebar.js');

  var Body = Component.inherits(function(props) {
    this.dragCount = this.prop(0);

    this.entryCollection = new EntryCollection({ jsonLoader: dom.loadJSON });

    this.sidebar = new Sidebar({
      element: this.childElement('.sidebar'),
      moduleDragStarter: Body.prototype.moduleDragStarter.bind(this),
      moduleDragEnder: Body.prototype.moduleDragEnder.bind(this),
      moduleDropper: Body.prototype.moduleDropper.bind(this),
      entrySearcher: Body.prototype.entrySearcher.bind(this),
    });

    this.main = new Main({
      element: this.childElement('.main'),
      sidebarToggler: Body.prototype.sidebarToggler.bind(this),
      moduleDragStarter: Body.prototype.moduleDragStarter.bind(this),
      moduleDragEnder: Body.prototype.moduleDragEnder.bind(this),
      loadStarter: Body.prototype.loadStarter.bind(this),
      loadEnder: Body.prototype.loadEnder.bind(this),
    });

    this.registerReadyListener();
  });

  Body.prototype.isDragging = function() {
    return (this.dragCount() > 0);
  };

  Body.prototype.incrementDragCount = function() {
    this.dragCount(this.dragCount() + 1);
  };

  Body.prototype.decrementDragCount = function() {
    this.dragCount(this.dragCount() - 1);
  };

  Body.prototype.currentDemoName = function() {
    return dom.urlQuery(dom.location()).demo || '';
  };

  Body.prototype.demoUrl = function(name) {
    return 'demos/' + name + '.json';
  };

  Body.prototype.registerReadyListener = function() {
    dom.ready(Body.prototype.onready.bind(this));
  };

  Body.prototype.toggleSidebar = function(visible) {
    return dom.transition(this.element(), function() {
      this.sidebar.disabled(!visible);
      this.main.isFullWidth(!visible);
    }.bind(this));
  };

  Body.prototype.loadDemo = function(name) {
    return (name ? this.main.loadUrl(this.demoUrl(name)) : Promise.resolve());
  };

  Body.prototype.render = function() {
    return dom.body();
  };

  Body.prototype.onredraw = function() {
    this.redrawDOMToggleClassBy('isDragging', 'dragging');
  };

  Body.prototype.onready = function() {
    this.loadStarter();
    this.entryCollection.load().then(function() {
      this.sidebar.loadContent();
      return this.loadDemo(this.currentDemoName());
    }.bind(this)).catch(function(e) {
      alert(e);
    }).then(function() {
      this.loadEnder();
    }.bind(this));
  };

  Body.prototype.moduleDragStarter = function() {
    this.incrementDragCount();
  };

  Body.prototype.moduleDragEnder = function() {
    this.decrementDragCount();
  };

  Body.prototype.moduleDropper = function(name, x, y) {
    var point = this.main.contentLocalPoint({ x: x, y: y });
    if (point.x < 0 || point.y < 0) {
      return;
    }

    var entry = this.entryCollection.get(name);
    this.main.loadModule(helper.extend({
      title: entry.label,
      name: name,
    }, point), entry.visiblePortNames);
  };

  Body.prototype.entrySearcher = function(searchText) {
    return this.entryCollection.search(searchText);
  };

  Body.prototype.sidebarToggler = function(visible) {
    return this.toggleSidebar(visible);
  };

  Body.prototype.loadStarter = function() {
    this.sidebar.disabled(true);
    this.main.disabled(true);
  };

  Body.prototype.loadEnder = function() {
    this.sidebar.disabled(false);
    this.main.disabled(false);
  };

  if (typeof module !== 'undefined' && module.exports) {
    module.exports = Body;
  } else {
    app.Body = Body;
  }
})(this.app || (this.app = {}));
<|endoftext|>


<commit_before>'use strict';
angular.module('trellocloneApp')
    .controller('WorkItemCtrl', ['$scope', 'workItemFactory', 'userFactory',

        function ($scope, workItemFactory, userFactory) {

            $scope.status;
            $scope.issues;
            $scope.users = [];

            $scope.newWorkItem = {};
            $scope.workItems = [
                [],
                [],
                []
            ];
            $scope.formData = {};

            function refresh() {
                setTimeout(function () {
                    var token = window.localStorage.getItem("token");

                    if (typeof token !== 'undefined') {
                        getInProgressWorkItems(token);
                        getNotStartedWorkItems(token);
                        getCompletedWorkItems(token);
                    } else {
                        window.location.href = '/login';
                    }
                    console.dir($scope.workItems);
                    getAllUsers();
                }, 500);
            }

            refresh();

            function getAllUsers() {
                userFactory.getAllUsers()
                    .success(function (usersResponse) {
                        $scope.users = usersResponse.users;
                    })
                    .error(function (error) {
                        $scope.users =
                            [{
                                username: 'user',
                                userId: 'userId',
                                id: 1
                            }];
                        $scope.status = 'Unable to load users data: ' + error.message;
                    });
            }

            function getInProgressWorkItems(token) {
                workItemFactory.getWorkItemsInProgress(token)
                    .success(function (workItemsInProgress) {
                        $scope.workItems[1] = workItemsInProgress;
                    })
                    .error(function (error) {
                        $scope.workItems[1] = [{
                            id: '1',
                            title: 'title1',
                            description: 'description1'
                        }];
                        $scope.status = 'Unable to load workItem data: ' + error.message;
                    });
            }

            function getNotStartedWorkItems(token) {
                workItemFactory.getNotStartedWorkItems(token)
                    .success(function (notStartedWorkItems) {
                        $scope.workItems[0] = notStartedWorkItems;
                    })
                    .error(function (error) {
                        $scope.workItems[0] = [{
                            id: '2',
                            title: 'title2',
                            description: 'description2'
                        }];
                        $scope.status = 'Unable to load workItem data: ' + error.message;
                    });
            }

            function getCompletedWorkItems(token) {
                workItemFactory.getCompletedWorkItems(token)
                    .success(function (completedWorkItems) {
                        $scope.workItems[2] = completedWorkItems;
                    })
                    .error(function (error) {
                        $scope.workItems[2] = [{
                            id: '3',
                            title: 'title3',
                            description: 'description3'
                        }];
                        $scope.status = 'Unable to load workitem data: ' + error.message;
                    });
            }

            $scope.deleteWorkItem = function (id) {
                workItemFactory.deleteWorkItem(id)
                    .success(function () {
                        $scope.status = 'Deleted workitem! Refreshing workitem list...';

                        $scope.issues = null;
                        refresh();
                        $('.modal-backdrop').remove();
                        $('body').removeClass('modal-open');
                    })
                    .error(function (error) {
                        $scope.status = 'Unable to delete workitem: ' + error.message;
                    });
            };

            function createOptions(listName) {
                var _listName = listName;
                var options = {
                    placeholder: 'app',
                    connectWith: '.apps-container',
                    receive: function (something) {

                        switch (_listName) {

                        case 'NOT_STARTED':
                            workItemFactory.setNotStarted(something.toElement.id);
                            refresh();
                            break;
                        case 'IN_PROGRESS':
                            $('#progress').addClass('fa-pulse');
                            workItemFactory.setInProgress(something.toElement.id);
                            refresh();
                            break;
                        case 'COMPLETED':
                            workItemFactory.setCompleted(something.toElement.id);
                            refresh();
                            break;

                        default:
                        }
                    },
                    remove: function () {
                        if (_listName === 'IN_PROGRESS' && $scope.workItems[1].length === 0) {
                            $('#progress').removeClass('fa-pulse');
                        }
                    }
                };
                return options;
            }

            $scope.sortableOptionsList = [createOptions('NOT_STARTED'), createOptions('IN_PROGRESS'), createOptions('COMPLETED')];

            $scope.addWorkItem = function () {
                $scope.workItems[0].push({
                    title: this.workItem
                });
                $scope.workItem = '';
            };

            $scope.saveWorkItem = function () {
                //Stänger ner modalen
                $('.modal-backdrop').remove();
                $('body').removeClass('modal-open');

                var workitem = angular.copy($scope.formData);
                //Skickar datan till servern
                workItemFactory.updateWorkItem(workitem);
                //laddar om datan från servern
                refresh();
            };

            $scope.saveNewWorkItem = function () {

                $('.modal-backdrop').remove();
                $('.modal').remove();
                $('body').removeClass('modal-open');

                var workitem = angular.copy($scope.newWorkItem);
                $scope.newWorkItem = {};

                workItemFactory.saveWorkItem(workitem);

                refresh();
            };

            $scope.initFormData = function (workItem) {
                $scope.formData = angular.copy(workItem);
            };

            $scope.setUserToWorkItem = function (userId, workItemId) {
                userFactory.addWorkItemToUser(userId, workItemId);
            };
        }
    ]);<commit_msg>redirectar nu till login om man inte är authenticated<commit_after>'use strict';
angular.module('trellocloneApp')
    .controller('WorkItemCtrl', ['$scope', 'workItemFactory', 'userFactory',

        function ($scope, workItemFactory, userFactory) {

            $scope.status;
            $scope.issues;
            $scope.users = [];

            $scope.newWorkItem = {};
            $scope.workItems = [
                [],
                [],
                []
            ];
            $scope.formData = {};

            function refresh() {
                setTimeout(function () {
                    var token = window.localStorage.getItem("token");

                    if (typeof token !== 'undefined') {
                        getInProgressWorkItems(token);
                        getNotStartedWorkItems(token);
                        getCompletedWorkItems(token);
                    } else {
                        window.location.href = '#/login';
                    }
                    console.dir($scope.workItems);
                    getAllUsers();
                }, 500);
            }

            refresh();

            function getAllUsers() {
                userFactory.getAllUsers()
                    .success(function (usersResponse) {
                        $scope.users = usersResponse.users;
                    })
                    .error(function (error) {
                        window.location.href = '#/login';
                        $scope.status = 'Unable to load users data: ' + error.message;
                    });
            }

            function getInProgressWorkItems(token) {
                workItemFactory.getWorkItemsInProgress(token)
                    .success(function (workItemsInProgress) {
                        $scope.workItems[1] = workItemsInProgress;
                    })
                    .error(function (error) {
                        window.location.href = '#/login';
                        $scope.status = 'Unable to load workItem data: ' + error.message;
                    });
            }

            function getNotStartedWorkItems(token) {
                workItemFactory.getNotStartedWorkItems(token)
                    .success(function (notStartedWorkItems) {
                        $scope.workItems[0] = notStartedWorkItems;
                    })
                    .error(function (error) {
                        window.location.href = '#/login';
                        $scope.status = 'Unable to load workItem data: ' + error.message;
                    });
            }

            function getCompletedWorkItems(token) {
                workItemFactory.getCompletedWorkItems(token)
                    .success(function (completedWorkItems) {
                        $scope.workItems[2] = completedWorkItems;
                    })
                    .error(function (error) {
                        $scope.workItems[2] = [{
                            id: '3',
                            title: 'title3',
                            description: 'description3'
                        }];
                        $scope.status = 'Unable to load workitem data: ' + error.message;
                    });
            }

            $scope.deleteWorkItem = function (id) {
                workItemFactory.deleteWorkItem(id)
                    .success(function () {
                        $scope.status = 'Deleted workitem! Refreshing workitem list...';

                        $scope.issues = null;
                        refresh();
                        $('.modal-backdrop').remove();
                        $('body').removeClass('modal-open');
                    })
                    .error(function (error) {
                        $scope.status = 'Unable to delete workitem: ' + error.message;
                    });
            };

            function createOptions(listName) {
                var _listName = listName;
                var options = {
                    placeholder: 'app',
                    connectWith: '.apps-container',
                    receive: function (something) {

                        switch (_listName) {

                        case 'NOT_STARTED':
                            workItemFactory.setNotStarted(something.toElement.id);
                            refresh();
                            break;
                        case 'IN_PROGRESS':
                            $('#progress').addClass('fa-pulse');
                            workItemFactory.setInProgress(something.toElement.id);
                            refresh();
                            break;
                        case 'COMPLETED':
                            workItemFactory.setCompleted(something.toElement.id);
                            refresh();
                            break;

                        default:
                        }
                    },
                    remove: function () {
                        if (_listName === 'IN_PROGRESS' && $scope.workItems[1].length === 0) {
                            $('#progress').removeClass('fa-pulse');
                        }
                    }
                };
                return options;
            }

            $scope.sortableOptionsList = [createOptions('NOT_STARTED'), createOptions('IN_PROGRESS'), createOptions('COMPLETED')];

            $scope.addWorkItem = function () {
                $scope.workItems[0].push({
                    title: this.workItem
                });
                $scope.workItem = '';
            };

            $scope.saveWorkItem = function () {
                //Stänger ner modalen
                $('.modal-backdrop').remove();
                $('body').removeClass('modal-open');

                var workitem = angular.copy($scope.formData);
                //Skickar datan till servern
                workItemFactory.updateWorkItem(workitem);
                //laddar om datan från servern
                refresh();
            };

            $scope.saveNewWorkItem = function () {

                $('.modal-backdrop').remove();
                $('.modal').remove();
                $('body').removeClass('modal-open');

                var workitem = angular.copy($scope.newWorkItem);
                $scope.newWorkItem = {};

                workItemFactory.saveWorkItem(workitem);

                refresh();
            };

            $scope.initFormData = function (workItem) {
                $scope.formData = angular.copy(workItem);
            };

            $scope.setUserToWorkItem = function (userId, workItemId) {
                userFactory.addWorkItemToUser(userId, workItemId);
            };
        }
    ]);<|endoftext|>


<commit_before>/*
 * Copyright (c) $year, Den Norske Turistforening (DNT)
 *
 * https://github.com/Turistforeningen/turadmin
 */

var sentry = require('../lib/sentry');

module.exports = function (app, options) {
    "use strict";

    var ntbApiUri = options.ntbApiUri;
    var ntbApiKey = options.ntbApiKey;
    var restler = require('restler');
    var underscore = require('underscore');
    var util = require('util');

    /*
        Move id from document object to _id on result object, to update client side model with id.
     */
    var moveId = function (data) {
        if (data.document && data.document._id) {
            data._id = data.document._id;
        } else {
            sentry.captureMessage('ID is missing in result after post!', {extra: {data: data}});
        }
        data.document = undefined;
    };

    var makeRequest = function (path, req, res, onCompleteOverride, getAll) {
        var API_LIMIT = 50;
        var PROXY_LIMIT = 1000;

        // Strip query params from path to get URL
        var url = ntbApiUri + path.split('?')[0];

        // Set the approperiate method if overridden using _method
        var method = req.body._method || req.method;
        delete req.body._method;

        // Create options object and set user agent & API key
        var options = {headers: {'User-Agent': 'turadmin-v2.0'}};
        options.query = req.query || {};
        options.query.api_key = ntbApiKey;

        // Apply query params from passed path to query object
        // The URL-params will override existing req params with matching keys
        var paramsStr = path.split('?')[1];

        if (typeof paramsStr === 'string') {
            var paramsArr = paramsStr.split('&');

            for (var i = 0, key, val; i < paramsArr.length; i++) {
                key = decodeURIComponent(paramsArr[i].split('=')[0]);
                val = decodeURIComponent(paramsArr[i].split('=')[1] || "");

                // Backbone will encode spaces as "+", while NTB expects "%20" which will be taken care of by restler
                if (val.indexOf('+') !== -1) {
                    val = val.replace(/\+/g, ' ');
                }

                options.query[key] = val;
            }
        }

        // Callbacks
        var onCompleteDefault = function (data, response) {
            res.statusCode = (!!response) ? response.statusCode : 0;
            if (data.document !== undefined) { // NOTE: Why the if?
                data.document = undefined;
            }
            res.json(data);
        };

        var onComplete = onCompleteOverride || onCompleteDefault;

        var onCompletePost = function (data, response) {
            if (!!response && !!response.statusCode) {
                res.statusCode = response.statusCode;
            }
            moveId(data);
            res.json(data);
        };

        onCompletePost = onCompleteOverride || onCompletePost;

        var onCompletePostGpx = function (data, gpx) {
            data = underscore.extend(data, gpx);
            onCompletePost(data);
        };

        if (method === "GET") {
            // Adds support for a higher limit than the one set in NTB API, but not higher than internal PROXY_LIMIT
            // Will sequentially perform the number of requests necessary for collecting the number of objects
            // set in the custom limit.
            if (options.query.limit > API_LIMIT) {
                var customLimit = Math.min(options.query.limit, PROXY_LIMIT);
                options.query.limit = API_LIMIT;

                var skip = 0; // Number of objects to skip. This will increase for each request
                var all = []; // Array that will eventually contain objects from all requests

                var prepData = function (data, response) {

                    if (data.documents && data.documents.length) {
                        for (var i = 0; i < data.documents.length; i++) {
                            if (all.length < customLimit) {
                                all.push(data.documents[i]);
                            }
                        }

                        if ((all.length === data.total) || (all.length >= customLimit)) {
                            onComplete({documents: all, count: all.length, total: data.total}, response);

                        } else {
                            options.query = options.query || {};
                            skip += data.count;
                            options.query.skip = skip;

                            restler.get(url, options).on('complete', prepData);
                        }

                    } else {
                        onComplete(data, response);
                    }
                };

                restler.get(url, options).on('complete', prepData);

            } else {
                restler.get(url, options).on('complete', onComplete);
            }

        } else if (method === "POST") {
            restler.postJson(url, req.body, options).on('complete', onCompletePost);

        } else if (method === "PUT") {
            options.headers['content-type'] = 'application/json';
            options.data = JSON.stringify(req.body);

            restler.put(url, options).on('complete', onComplete);

        } else if (method === "PATCH") {
            options.headers['content-type'] = 'application/json';
            options.data = JSON.stringify(req.body);

            restler.patch(url, options).on('complete', onComplete);

        } else if (method === "DELETE") {
            restler.del(url, options).on('complete', onComplete);
        }
    };

    app.get('/restProxy/turer', function (req, res, next) {
        if (req.query && req.query.gruppe) {
            res.cookie('userDefaultRouteFetchQuery_' + req.session.userId, {
                'gruppe': req.query.gruppe
            }, {
                signed: true,
                maxAge: 2628000000
            });

        } else if ((req.session.authType == 'dnt-connect') && (req.query && req.query['privat.opprettet_av.id'])) {
            res.cookie('userDefaultRouteFetchQuery_' + req.session.userId, {
                'privat.opprettet_av.id': req.query['privat.opprettet_av.id']
            }, {
                signed: true,
                maxAge: 2628000000
            });
        }
        next();
    });

    app.all('/restProxy/*', function (req, res, next) {
        if (req.session && req.session.isAuthenticated === true) {
            var path = req.url;
            path = path.replace('restProxy/', '');
            makeRequest(path, req, res);

        } else {
            res.statusCode = 401;
            res.json({message: 'Bad credentials'});
        }
    });

    return {makeApiRequest: makeRequest};
};
<commit_msg>Use encodeURI to make sure URL is properly encoded<commit_after>/*
 * Copyright (c) $year, Den Norske Turistforening (DNT)
 *
 * https://github.com/Turistforeningen/turadmin
 */

var sentry = require('../lib/sentry');

module.exports = function (app, options) {
    "use strict";

    var ntbApiUri = options.ntbApiUri;
    var ntbApiKey = options.ntbApiKey;
    var restler = require('restler');
    var underscore = require('underscore');
    var util = require('util');

    /*
        Move id from document object to _id on result object, to update client side model with id.
     */
    var moveId = function (data) {
        if (data.document && data.document._id) {
            data._id = data.document._id;
        } else {
            sentry.captureMessage('ID is missing in result after post!', {extra: {data: data}});
        }
        data.document = undefined;
    };

    var makeRequest = function (path, req, res, onCompleteOverride, getAll) {
        var API_LIMIT = 50;
        var PROXY_LIMIT = 1000;

        // Strip query params from path to get URL
        var url = ntbApiUri + path.split('?')[0];

        // Set the approperiate method if overridden using _method
        var method = req.body._method || req.method;
        delete req.body._method;

        // Create options object and set user agent & API key
        var options = {headers: {'User-Agent': 'turadmin-v2.0'}};
        options.query = req.query || {};
        options.query.api_key = ntbApiKey;

        // Apply query params from passed path to query object
        // The URL-params will override existing req params with matching keys
        var paramsStr = path.split('?')[1];

        if (typeof paramsStr === 'string') {
            var paramsArr = paramsStr.split('&');

            for (var i = 0, key, val; i < paramsArr.length; i++) {
                key = decodeURIComponent(paramsArr[i].split('=')[0]);
                val = decodeURIComponent(paramsArr[i].split('=')[1] || "");

                // Backbone will encode spaces as "+", while NTB expects "%20" which will be taken care of by restler
                if (val.indexOf('+') !== -1) {
                    val = val.replace(/\+/g, ' ');
                }

                options.query[key] = val;
            }
        }

        // Callbacks
        var onCompleteDefault = function (data, response) {
            res.statusCode = (!!response) ? response.statusCode : 0;
            if (data.document !== undefined) { // NOTE: Why the if?
                data.document = undefined;
            }
            res.json(data);
        };

        var onComplete = onCompleteOverride || onCompleteDefault;

        var onCompletePost = function (data, response) {
            if (!!response && !!response.statusCode) {
                res.statusCode = response.statusCode;
            }
            moveId(data);
            res.json(data);
        };

        onCompletePost = onCompleteOverride || onCompletePost;

        var onCompletePostGpx = function (data, gpx) {
            data = underscore.extend(data, gpx);
            onCompletePost(data);
        };

        if (method === "GET") {
            // Adds support for a higher limit than the one set in NTB API, but not higher than internal PROXY_LIMIT
            // Will sequentially perform the number of requests necessary for collecting the number of objects
            // set in the custom limit.
            if (options.query.limit > API_LIMIT) {
                var customLimit = Math.min(options.query.limit, PROXY_LIMIT);
                options.query.limit = API_LIMIT;

                var skip = 0; // Number of objects to skip. This will increase for each request
                var all = []; // Array that will eventually contain objects from all requests

                var prepData = function (data, response) {

                    if (data.documents && data.documents.length) {
                        for (var i = 0; i < data.documents.length; i++) {
                            if (all.length < customLimit) {
                                all.push(data.documents[i]);
                            }
                        }

                        if ((all.length === data.total) || (all.length >= customLimit)) {
                            onComplete({documents: all, count: all.length, total: data.total}, response);

                        } else {
                            options.query = options.query || {};
                            skip += data.count;
                            options.query.skip = skip;

                            restler.get(encodeURI(url), options).on('complete', prepData);
                        }

                    } else {
                        onComplete(data, response);
                    }
                };
                restler.get(encodeURI(url), options).on('complete', prepData);

            } else {
                restler.get(encodeURI(url), options).on('complete', onComplete);
            }

        } else if (method === "POST") {
            restler.postJson(url, req.body, options).on('complete', onCompletePost);

        } else if (method === "PUT") {
            options.headers['content-type'] = 'application/json';
            options.data = JSON.stringify(req.body);

            restler.put(url, options).on('complete', onComplete);

        } else if (method === "PATCH") {
            options.headers['content-type'] = 'application/json';
            options.data = JSON.stringify(req.body);

            restler.patch(url, options).on('complete', onComplete);

        } else if (method === "DELETE") {
            restler.del(url, options).on('complete', onComplete);
        }
    };

    app.get('/restProxy/turer', function (req, res, next) {
        if (req.query && req.query.gruppe) {
            res.cookie('userDefaultRouteFetchQuery_' + req.session.userId, {
                'gruppe': req.query.gruppe
            }, {
                signed: true,
                maxAge: 2628000000
            });

        } else if ((req.session.authType == 'dnt-connect') && (req.query && req.query['privat.opprettet_av.id'])) {
            res.cookie('userDefaultRouteFetchQuery_' + req.session.userId, {
                'privat.opprettet_av.id': req.query['privat.opprettet_av.id']
            }, {
                signed: true,
                maxAge: 2628000000
            });
        }
        next();
    });

    app.all('/restProxy/*', function (req, res, next) {
        if (req.session && req.session.isAuthenticated === true) {
            var path = req.url;
            path = path.replace('restProxy/', '');
            makeRequest(path, req, res);

        } else {
            res.statusCode = 401;
            res.json({message: 'Bad credentials'});
        }
    });

    return {makeApiRequest: makeRequest};
};
<|endoftext|>