<commit_before>/*
-----------------------------------------------------------------------------
Copyright (c) 2014-2015 Seth Anderson

This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the
use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software in a
product, an acknowledgment in the product documentation would be appreciated
but is not required.

2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.

3. This notice may not be removed or altered from any source distribution.
-----------------------------------------------------------------------------
*/

var mongoose = require("mongoose"),
	q = require("q"),
	Lan = require("../model/lan.js"),
	Game = require("../model/game.js"),
	Rsvp = require("../model/rsvp.js"),
	authorize = require("../authorization.js").authorize,
	blendedAuthenticate = require("../utils/common.js").blendedAuthenticate,
	sanitizeBodyForDB = require("../utils/common.js").sanitizeBodyForDB;;

module.exports = function(app, prefix){
	app.get(prefix,
	function(req, res){
		Lan.find({})
		.exec(function(err, docs){
			if(err){
				res.status(500).end();
			}else{
				res.send(docs || []);
			}
		});
	});

	app.get(prefix + "/:lan",
	function(req, res){
		var query = null;
		if(req.params.lan === "current"){
			query = Lan.findOne({active: true, acceptingRsvps: true}, null, {sort: {beginDate: "-1"}});
		}else if(req.params.lan === "next"){
			query = Lan.findOne({active: true, acceptingRsvps: true}, null, {sort: {beginDate: "-1"}});
			query.where("beginDate").gt(Date.now());
		}else{
			query = Lan.findById(req.params.lan);
		}

		query.exec(function(err, doc){
			if(err){
				res.status(500).end();
			}else if(!doc){
				res.status(404).end();
			}else{
				res.send(doc);
			}
		});
	});

	app.get(prefix + "/:lan/games",
	function(req, res){
		var deferred = q.defer(),
			query = null,
			year;
		if(req.params.lan === "current"){
			query = Lan.findOne({active: true, acceptingRsvps: true}, null, {sort: {beginDate: "-1"}});
		}else if(req.params.lan === "next"){
			query = Lan.findOne({active: true, acceptingRsvps: true}, null, {sort: {beginDate: "-1"}});
			query.where("beginDate").gt(Date.now());
		}else{
			query = Lan.findById(req.params.lan);
		}
		query.exec(function(err, doc){
			if(err){
				deferred.reject(err);
			}else if(!doc){
				res.status(404).end();
			}else{
				year = doc.beginDate.getFullYear();
				deferred.resolve(doc.games);
			}
		});

		deferred.promise.then(function(data){
			var gameIds = [];
			for(var i = 0; i < data.length; i += 1){
				gameIds.push(data[i].game);
			}
			Game.find({_id: {$in: gameIds}})
			.populate("stores.store")
			.exec(function(err, docs){
				if(err){
					res.status(500).end();
				}else{
					res.send({
						year: year,
						games: docs
					});
				}
			});
		}, function(err){
			res.status(500).end();
		});
	});

	app.get(prefix + "/:lan/rsvps",
	function(req, res){
		var deferred = q.defer(),
			query = null,
			year;
		if(req.params.lan === "current"){
			query = Lan.findOne({active: true, acceptingRsvps: true}, null, {sort: {beginDate: "-1"}});
		}else if(req.params.lan === "next"){
			query = Lan.findOne({active: true, acceptingRsvps: true}, null, {sort: {beginDate: "-1"}});
			query.where("beginDate").gt(Date.now());
		}else{
			query = Lan.findById(req.params.lan);
		}
		query.exec(function(err, doc){
			if(err){
				deferred.reject(err);
			}else if(!doc){
				res.status(404).end();
			}else{
				year = doc.beginDate.getFullYear();
				deferred.resolve(doc);
			}
		});

		deferred.promise.then(function(data){
			Rsvp.find({lan: data._id})
			.populate("tournaments.game", "name")
			.exec(function(err, docs){
				if(err){
					res.status(500).end();
				}else{
					var rsvps = JSON.parse(JSON.stringify(docs));
					for(var i = 0; i < rsvps.length; i += 1){
						for(var j = 0; j < rsvps[i].tournaments.length; j += 1){
							for(var k = 0; k < data.games.length; k += 1){
								if(data.games[k].game.toString() === rsvps[i].tournaments[j].game._id.toString()){
									rsvps[i].tournaments[j].game.tournamentName = data.games[k].tournamentName;
									rsvps[i].tournaments[j].game.tournament = data.games[k].tournament;
								}
							}
						}
					}
					res.send(rsvps);
				}
			});
		}, function(err){
			res.status(500).end();
		});
	});

	app.post(prefix,
		blendedAuthenticate,
		authorize({hasRoles: ["admin"]}),
		sanitizeBodyForDB,
	function(req, res){
		var lan = new Lan(req.body);
		lan.save(function(err){
			if(err){
				res.status(400).end();
			}else{
				res.status(201)
				.location(prefix + "/" + lan._id)
				.send({_id: lan._id});
			}
		});
	});

	app.put(prefix + "/:lan",
		blendedAuthenticate,
		authorize({hasRoles: ["admin"]}),
		sanitizeBodyForDB,
	function(req, res){
		Lan.findByIdAndUpdate(req.params.lan, req.body, function(err, doc){
			if(err){
				res.status(400).end();
			}else if(!doc){
				res.status(404).end();
			}else{
				res.status(200).end();
			}
		});
	});

	app.delete(prefix + "/:lan",
		blendedAuthenticate,
		authorize({hasRoles: ["admin"]}),
	function(req, res){
		Lan.findByIdAndRemove(req.params.lan, function(err, doc){
			if(err){
				res.status(400).end();
			}else if(!doc){
				res.status(404).end();
			}else{
				res.status(200).end();
			}
		});
	});
}
<commit_msg>Added some user info to /api/lan/:id/rsvps route<commit_after>/*
-----------------------------------------------------------------------------
Copyright (c) 2014-2015 Seth Anderson

This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the
use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software in a
product, an acknowledgment in the product documentation would be appreciated
but is not required.

2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.

3. This notice may not be removed or altered from any source distribution.
-----------------------------------------------------------------------------
*/

var mongoose = require("mongoose"),
	q = require("q"),
	Lan = require("../model/lan.js"),
	Game = require("../model/game.js"),
	Rsvp = require("../model/rsvp.js"),
	authorize = require("../authorization.js").authorize,
	blendedAuthenticate = require("../utils/common.js").blendedAuthenticate,
	sanitizeBodyForDB = require("../utils/common.js").sanitizeBodyForDB;;

module.exports = function(app, prefix){
	app.get(prefix,
	function(req, res){
		Lan.find({})
		.exec(function(err, docs){
			if(err){
				res.status(500).end();
			}else{
				res.send(docs || []);
			}
		});
	});

	app.get(prefix + "/:lan",
	function(req, res){
		var query = null;
		if(req.params.lan === "current"){
			query = Lan.findOne({active: true, acceptingRsvps: true}, null, {sort: {beginDate: "-1"}});
		}else if(req.params.lan === "next"){
			query = Lan.findOne({active: true, acceptingRsvps: true}, null, {sort: {beginDate: "-1"}});
			query.where("beginDate").gt(Date.now());
		}else{
			query = Lan.findById(req.params.lan);
		}

		query.exec(function(err, doc){
			if(err){
				res.status(500).end();
			}else if(!doc){
				res.status(404).end();
			}else{
				res.send(doc);
			}
		});
	});

	app.get(prefix + "/:lan/games",
	function(req, res){
		var deferred = q.defer(),
			query = null,
			year;
		if(req.params.lan === "current"){
			query = Lan.findOne({active: true, acceptingRsvps: true}, null, {sort: {beginDate: "-1"}});
		}else if(req.params.lan === "next"){
			query = Lan.findOne({active: true, acceptingRsvps: true}, null, {sort: {beginDate: "-1"}});
			query.where("beginDate").gt(Date.now());
		}else{
			query = Lan.findById(req.params.lan);
		}
		query.exec(function(err, doc){
			if(err){
				deferred.reject(err);
			}else if(!doc){
				res.status(404).end();
			}else{
				year = doc.beginDate.getFullYear();
				deferred.resolve(doc.games);
			}
		});

		deferred.promise.then(function(data){
			var gameIds = [];
			for(var i = 0; i < data.length; i += 1){
				gameIds.push(data[i].game);
			}
			Game.find({_id: {$in: gameIds}})
			.populate("stores.store")
			.exec(function(err, docs){
				if(err){
					res.status(500).end();
				}else{
					res.send({
						year: year,
						games: docs
					});
				}
			});
		}, function(err){
			res.status(500).end();
		});
	});

	app.get(prefix + "/:lan/rsvps",
	function(req, res){
		var deferred = q.defer(),
			query = null,
			year;
		if(req.params.lan === "current"){
			query = Lan.findOne({active: true, acceptingRsvps: true}, null, {sort: {beginDate: "-1"}});
		}else if(req.params.lan === "next"){
			query = Lan.findOne({active: true, acceptingRsvps: true}, null, {sort: {beginDate: "-1"}});
			query.where("beginDate").gt(Date.now());
		}else{
			query = Lan.findById(req.params.lan);
		}
		query.exec(function(err, doc){
			if(err){
				deferred.reject(err);
			}else if(!doc){
				res.status(404).end();
			}else{
				year = doc.beginDate.getFullYear();
				deferred.resolve(doc);
			}
		});

		deferred.promise.then(function(data){
			Rsvp.find({lan: data._id})
			.populate("user tournaments.game", "email firstName lastName primaryHandle name")
			.exec(function(err, docs){
				if(err){
					res.status(500).end();
				}else{
					var rsvps = JSON.parse(JSON.stringify(docs));
					for(var i = 0; i < rsvps.length; i += 1){
						for(var j = 0; j < rsvps[i].tournaments.length; j += 1){
							for(var k = 0; k < data.games.length; k += 1){
								if(data.games[k].game.toString() === rsvps[i].tournaments[j].game._id.toString()){
									rsvps[i].tournaments[j].game.tournamentName = data.games[k].tournamentName;
									rsvps[i].tournaments[j].game.tournament = data.games[k].tournament;
								}
							}
						}
					}
					res.send(rsvps);
				}
			});
		}, function(err){
			res.status(500).end();
		});
	});

	app.post(prefix,
		blendedAuthenticate,
		authorize({hasRoles: ["admin"]}),
		sanitizeBodyForDB,
	function(req, res){
		var lan = new Lan(req.body);
		lan.save(function(err){
			if(err){
				res.status(400).end();
			}else{
				res.status(201)
				.location(prefix + "/" + lan._id)
				.send({_id: lan._id});
			}
		});
	});

	app.put(prefix + "/:lan",
		blendedAuthenticate,
		authorize({hasRoles: ["admin"]}),
		sanitizeBodyForDB,
	function(req, res){
		Lan.findByIdAndUpdate(req.params.lan, req.body, function(err, doc){
			if(err){
				res.status(400).end();
			}else if(!doc){
				res.status(404).end();
			}else{
				res.status(200).end();
			}
		});
	});

	app.delete(prefix + "/:lan",
		blendedAuthenticate,
		authorize({hasRoles: ["admin"]}),
	function(req, res){
		Lan.findByIdAndRemove(req.params.lan, function(err, doc){
			if(err){
				res.status(400).end();
			}else if(!doc){
				res.status(404).end();
			}else{
				res.status(200).end();
			}
		});
	});
}
<|endoftext|>


<commit_before>var appRouter = function(app) {
	const DEFAULT_RESPONSE = { "post": "fhuuump" }; // silenced shotgun sound for error handling/secret reasons

	app.get("/", (req, res) => {
			if (app.cachedData.post !== "") {
				res.send(app.cachedData);
				app.generateMarkovChain();
			}
			else {
				res.send(DEFAULT_RESPONSE);
			}
	});

	// Need to include token from Heroku settings as query paramater in POST requests to these routes
	app.get("/testbot", (req, res) => {

		if (req.query.token !== process.env.TOKEN) {
			res.send({ "status: ": "ERROR: invalid query parameters" });
		}

		var target;

		if (req.query.topic) {
			target = req.query.topic;
		}

		app.initBot(target, null, (response) => {

			if (response === "post failed") {
				res.send({ "status: ": response)};
			}

			else {
				res.writeHead(302, {
					Location: "https://boards.endoftheinter.net/showmessages.php?topic=" + response
				});

				res.end();
			}

		});

	});

	app.get("/reply", (req, res) => {

		if (req.query.token !== process.env.TOKEN	|| !req.query.topic || !req.query.msg) {
			res.send({ "status: ": "ERROR: invalid query parameters" });
		}

		app.initBot(req.query.topic, req.query.msg, (topicId) => {

			res.writeHead(302, {
				Location: "https://boards.endoftheinter.net/showmessages.php?topic=" + topicId
			});

			res.end();
		});

	});

	app.get("/pastebin", (req, res) => {
		if (req.query.token !== process.env.TOKEN) {
			res.send({ "status: ": "ERROR: invalid query parameters" });
		}

		else {
			app.addNewQuotes(req.query.url, (status) => {
				res.send({ "status: ": status });
			});
		}
	});

	app.get("/subscribe", (req, res) => {

		if (req.query.token !== process.env.TOKEN || !req.query.topic) {
			res.send(DEFAULT_RESPONSE);
		}

		app.subscribeToUpdates(req.query.topic, null, null, (response) => {
			res.send(response);
		});

	});

};

module.exports = appRouter;<commit_msg>Stupid bugfix<commit_after>var appRouter = function(app) {
	const DEFAULT_RESPONSE = { "post": "fhuuump" }; // silenced shotgun sound for error handling/secret reasons

	app.get("/", (req, res) => {
			if (app.cachedData.post !== "") {
				res.send(app.cachedData);
				app.generateMarkovChain();
			}
			else {
				res.send(DEFAULT_RESPONSE);
			}
	});

	// Need to include token from Heroku settings as query paramater in POST requests to these routes
	app.get("/testbot", (req, res) => {

		if (req.query.token !== process.env.TOKEN) {
			res.send({ "status: ": "ERROR: invalid query parameters" });
		}

		var target;

		if (req.query.topic) {
			target = req.query.topic;
		}

		app.initBot(target, null, (response) => {

			if (response === "post failed") {
				res.send({ "status: ": response});
			}

			else {
				res.writeHead(302, {
					Location: "https://boards.endoftheinter.net/showmessages.php?topic=" + response
				});

				res.end();
			}

		});

	});

	app.get("/reply", (req, res) => {

		if (req.query.token !== process.env.TOKEN	|| !req.query.topic || !req.query.msg) {
			res.send({ "status: ": "ERROR: invalid query parameters" });
		}

		app.initBot(req.query.topic, req.query.msg, (topicId) => {

			res.writeHead(302, {
				Location: "https://boards.endoftheinter.net/showmessages.php?topic=" + topicId
			});

			res.end();
		});

	});

	app.get("/pastebin", (req, res) => {
		if (req.query.token !== process.env.TOKEN) {
			res.send({ "status: ": "ERROR: invalid query parameters" });
		}

		else {
			app.addNewQuotes(req.query.url, (status) => {
				res.send({ "status: ": status });
			});
		}
	});

	app.get("/subscribe", (req, res) => {

		if (req.query.token !== process.env.TOKEN || !req.query.topic) {
			res.send(DEFAULT_RESPONSE);
		}

		app.subscribeToUpdates(req.query.topic, null, null, (response) => {
			res.send(response);
		});

	});

};

module.exports = appRouter;<|endoftext|>


<commit_before>/*
 * Adds the routes for various scroll views and CRUD operations
 * @param app - The Scroll app instance
 */
module.exports = function(app) {
  var config = app.config.views;

  // post-type scrolls
  app.get('/post/:slug', function(req, res) {
    this.controllers.scroll.findOne('post', req.params.slug,
      function(err, scroll) {
        res.render(config.post.view, {post:scroll});
      });
  }, 'post');

  // edit a page-type scrolls
  app.get('/post/:slug/edit', app.restrict, function(req, res) {
    this.controllers.scroll.findOne('post', req.params.slug,
      function(err, scroll) {
        res.render(config.edit.view, {
          scroll: (scroll || {slug:req.params.slug,type:'post'})
        });
      });
  }, 'edit');

  // edit a page-type scrolls
  app.get('/:page/edit', app.restrict, function(req, res) {
    this.controllers.scroll.findOne('page', req.params.page,
      function(err, scroll) {
        res.render(config.edit.view, {
          scroll: (scroll || {slug:req.params.page,type:'page'})
        });
      });
  }, 'edit');

  // page-type scrolls
  app.get('/:page', function(req, res) {
    this.controllers.scroll.findOne('page', req.params.page,
      function(err, scroll) {
        res.render(config.page.view, {page:scroll});
      });
  }, 'page');

  /*--------------------------------------
   Scroll data CRUD operations
  --------------------------------------*/
  var crud = new app.Router();
  crud.use(app.restrict);

  crud.post('/', function(req, res) {
      this.controllers.scroll.save(req.body, function(err, scroll) {
        res.send(scroll);
      });
    }.bind(app))
    .put('/:id', app.restrict, function(req, res) {
      req.body.id = req.params.id;
      this.controllers.scroll.save(req.body, function(err) {
        res.send(err || {success:true});
      });
    }.bind(app))
    .delete('/:id', app.restrict, function(req, res) {
      this.controllers.scroll.remove(req.params.id, function(err) {
        res.send(err || {success:true});
      });
    }.bind(app));

  app.use('/scroll', crud);
};
<commit_msg>Added the view to the data passed to the view template.<commit_after>/*
 * Adds the routes for various scroll views and CRUD operations
 * @param app - The Scroll app instance
 */
module.exports = function(app) {
  var config = app.config.views;

  // post-type scrolls
  app.get('/post/:slug', function(req, res) {
    this.controllers.scroll.findOne('post', req.params.slug,
      function(err, scroll) {
        res.render(config.post.view, {view:'post',post:scroll});
      });
  }, 'post');

  // edit a page-type scrolls
  app.get('/post/:slug/edit', app.restrict, function(req, res) {
    this.controllers.scroll.findOne('post', req.params.slug,
      function(err, scroll) {
        res.render(config.edit.view, {
          view:'edit',
          scroll: (scroll || {slug:req.params.slug,type:'post'})
        });
      });
  }, 'edit');

  // edit a page-type scrolls
  app.get('/:page/edit', app.restrict, function(req, res) {
    this.controllers.scroll.findOne('page', req.params.page,
      function(err, scroll) {
        res.render(config.edit.view, {
          view:'edit',
          scroll: (scroll || {slug:req.params.page,type:'page'})
        });
      });
  }, 'edit');

  // page-type scrolls
  app.get('/:page', function(req, res) {
    this.controllers.scroll.findOne('page', req.params.page,
      function(err, scroll) {
        res.render(config.page.view, {view:'page',page:scroll});
      });
  }, 'page');

  /*--------------------------------------
   Scroll data CRUD operations
  --------------------------------------*/
  var crud = new app.Router();
  crud.use(app.restrict);

  crud.post('/', function(req, res) {
      this.controllers.scroll.save(req.body, function(err, scroll) {
        res.send(scroll);
      });
    }.bind(app))
    .put('/:id', app.restrict, function(req, res) {
      req.body.id = req.params.id;
      this.controllers.scroll.save(req.body, function(err) {
        res.send(err || {success:true});
      });
    }.bind(app))
    .delete('/:id', app.restrict, function(req, res) {
      this.controllers.scroll.remove(req.params.id, function(err) {
        res.send(err || {success:true});
      });
    }.bind(app));

  app.use('/scroll', crud);
};
<|endoftext|>


<commit_before>/*
 * Serve content over a socket
 */

var config = require('../config');
var rdb = config.rdb;
var rdbLogger = config.rdbLogger;
var io = config.io;
var maxReports = config.maxReports;
var banExpiration = config.banExpiration;

var db = require('../db');
var Reported = db.Reported;

module.exports = function (socket) {

  // Add socket to session
  if (typeof socket.handshake.sw === 'undefined') {
    socket.emit('error');
    return;
  } else if (typeof socket.handshake.sw.s() === 'undefined') {
    socket.emit('error');
    return;
  }// else {
    /*socket.handshake.session.sockets.push(socket.id);
    socket.handshake.session.save();
  }*/
  rdb.sadd('chat:online', socket.id, rdbLogger);
  console.log(
    'New socket, ' + socket.id + ' ' +
    JSON.stringify(socket.handshake.sw.s())
  );

  // Looking for a new stranger.
  socket.on('stranger:req', function (data) {
    console.log(
      'Socket requested, ' + socket.id + ' ' +
      JSON.stringify(socket.handshake.sw.s())
    );

    if (authenticate(socket)) {
      if (isActive(socket.handshake.sw.s())) {
        var res;
        rdb.srandmember('chat:waiting', function (err, reply) {
          if (err) {
            socket.emit('stranger:err',
                        {err: 'Something happened when looking up for strangers.'}
                       );
          } else if (!reply) {
            res = getStrangerSocket(socket);

            if (res.ok) {
              res.strangerSocket.set('strangerSID', '');
              res.strangerSocket.set('lastStrangerIp', socket.handshake.sw.s().ip);
              socket.set('strangerSID', '');
              res.strangerSocket.emit('stranger:disconnected');
            }

            rdb.sadd('chat:waiting', socket.id);
            // TODO: setInterval(); or node events
          } else {
            res = getStrangerSocket(socket);

            if (res.ok) {
              res.strangerSocket.set('strangerSID', '');
              res.strangerSocket.set('lastStrangerIp', socket.handshake.sw.s().ip);
              socket.set('strangerSID', '');
              res.strangerSocket.emit('stranger:disconnected');
            }

            console.log('stranger found, ' + reply);
            rdb.srem('chat:waiting', reply);

            strangerSocket = io.sockets.socket(reply);
            socket.set('strangerSID', reply);
            strangerSocket.set('strangerSID', socket.id);

            socket.handshake.sw.s().chatCount += 1;
            socket.handshake.sw.save();
            strangerSocket.handshake.sw.s().chatCount += 1;
            strangerSocket.handshake.sw.save();

            socket.emit('stranger:res', {
              fullName: strangerSocket.handshake.sw.s().fullName,
            });

            strangerSocket.emit('stranger:res', {
              fullName: socket.handshake.sw.s().fullName,
            });
          }
        });
        //socket.emit('stranger:res', {found: false});
      } else {
        socket.handshake.sw.destroy();
        socket.emit('error');
      }
    }
  });

  socket.on('stranger:report', function (data) {
    if (authenticate(socket)) {
      if (data.noStranger) {
        socket.get('lastStrangerIp', function (err, ip) {
          if (err || !ip) {
            console.error('[Socket] No last stranger available.');
            if (err) console.error(err);
          } else {
            Reported.findOne({ip: ip}, function (err, reported) {
              if (err) {
                console.error('[Socket] in reporting: ' + err);
              } else if (!reported){
                var reported = new Reported({ip: ip});
                reported.reporters.push(socket.handshake.sw.s().ip);
                reported.save(function (err, reported) {
                  if (err) {
                    console.error('[Socket] Error in saving report: ' + err);
                  }
                });
              } else {
                if (reported.reporters.indexOf(socket.handshake.sw.s().ip) === -1) {
                  if (reported.reporters.length >= maxReports - 1) {
                    Banned.findOne({ip: ip}, function (err, banned) {
                      if (err) {
                      } else if (!banned) {
                        var banned = new Banned(
                          {ip: ip, expires: new Date(Date.now() + banExpiration)}
                        );
                        banned.save(function (err, banned) {
                          if (err) {
                            console.error('[Socket] Error in saving a banned user.');
                          }
                        });
                        reported.remove(function (err) {
                          if (err) {
                            console.error('[Socket] Error in removing the reported person after ban.');
                          }
                        });
                        socket.handshake.sw.destroy();
                      } else {
                      }
                    });
                  } else {
                    reported.update(
                      {$push: {reporters: ip}},
                      function (err, reported) {
                        if (err) {
                          console.error('[Socket] Could not add reporter ip.');
                        }
                      }
                    );
                  }
                }
              }
           });
          }
        });
      } else {
        var res = getStrangerSocket(socket);

        if (res.ok) {
          if (res.strangerSocket.handshake.sw.s().ip) {
            var ip = res.strangerSocket.handshake.sw.s().ip;
            Reported.findOne({ip: ip}, function (err, reported) {
              if (err) {
                console.error("[Socket] in reporting: " + err);
              } else if (!reported) {
                var reported = new Reported({
                  ip: ip
                });
                reported.reporters.push(socket.handshake.sw.s().ip);
                reported.save(function (err, reported) {
                  if (err) {
                    console.error('[Socket] Error while saving report: ' + err);
                  }
                });
              } else {
                if (reported.reporters.indexOf(socket.handshake.sw.s().ip) === -1) {
                  if (reported.reporters.length >= maxReports - 1) {
                    Banned.findOne({ip: ip}, function (err, banned) {
                      if (err) {
                      } else if (!banned) {
                        var banned = new Banned(
                          {ip: ip, expires: new Date(Date.now() + banExpiration)}
                        );
                        banned.save(function (err, banned) {
                          if (err) {
                            console.error('[Socket] Error in saving a banned user.');
                          }
                        });
                        reported.remove(function (err) {
                          if (err) {
                            console.error('[Socket] Error in removing the reported person after ban.');
                          }
                        });
                        socket.handshake.sw.destroy();
                      } else {
                      }
                    });
                  } else {
                    reported.update(
                      {$push: {reporters: ip}},
                      function (err, reported) {
                        if (err) {
                          console.error('[Socket] Could not add reporter ip.');
                        }
                      }
                    );
                  }
                }
              }
           });
          } else {
            console.error('[Socket] stranger socket has no ip for report.');
          }
        } else {
          console.error('[Socket] Getting stranger socket for report failed.');
        }
      }
    } else {
      socket.handshake.sw.destroy();
      socket.emit('error');
    }
  });

  // New message to be sent
  socket.on('msg:send', function (data) {
    if (authenticate(socket)) {
      if (data.msg.trim()) {
        socket.handshake.sw.s().msgCount += 1;
        socket.handshake.sw.save();
        var res = getStrangerSocket(socket);

        if (res.ok) {
          data.msg = {text: data.msg};
          data.msg.from = 'stranger';
          res.strangerSocket.emit('msg:recv', {msg: data.msg});
        }
      } else {
        socket.emit('msg:failed');
      }
    }
  });

  // Typing status
  socket.on('msg:typing', function (data) {
    if (authenticate(socket)) {
      var res = getStrangerSocket(socket);

      if (res.ok) {
        res.strangerSocket.emit('msg:strangerTyping', data);
      }
    }
  });

  // Socket disconnected.
  socket.on('disconnect', function () {
    console.log('Socket disconnected, ' + socket.id);
    rdb.srem('chat:online', socket.id, rdbLogger);
    rdb.srem('chat:waiting', socket.id, rdbLogger);
    var res = getStrangerSocket(socket);

    if (res.ok) {
      console.log('Stranger disconnected, ' + res.strangerSocket.id);
      res.strangerSocket.set('strangerSID', '');
      res.strangerSocket.set('lastStrangerIp', socket.handshake.sw.s().ip);
      socket.set('strangerSID', '');
      res.strangerSocket.emit('stranger:disconnected');
    }
  });

//  setInterval(function () {
//    socket.emit('send:time', {
//      time: (new Date()).toString()
//    });
//  }, 1000);
};

function getStrangerSocket(socket) {
  var ok = true;
  var strangerSocket = null;
  socket.get('strangerSID', function (err, sid) {
    if (err || !sid) {
      socket.emit('msg:err');
      ok = false;
    } else {
      strangerSocket = io.sockets.socket(sid);
    }
  });

  return {ok: ok, strangerSocket: strangerSocket};
}

function isActive(session) {
  if (session.msgCount === 0 && session.chatCount >= 3) {
    return false;
  }
  return true;
}

function authenticate(socket) {
  if (typeof socket.handshake.sw.s() !== 'undefined') {
    if (socket.handshake.sw.s().loggedIn) {
      return true;
    }
  }
  socket.emit('error');
  return false;
}
/*
function updateParallelSessions(socket) {
  var errorHandler = function (err) {
    if (err) {
      console.log('Error in parallel update session.');
    }
  };
  if (! socket.handshake.session) {
    errorHandler(true);
  }
  var parallelSocket;
  for (var sidIndex in socket.handshake.session.sockets) {
    if (socket.handshake.session.sockets[sidIndex] !== socket.id) {
      parallelSocket = io.sockets.socket(
        socket.handshake.session.sockets[sidIndex]
      );
      if (parallelSocket) {
        if (typeof parallelSocket.handshake === 'undefined') {
          errorHandler(true);
        } else if (typeof parallelSocket.handshake.session === 'undefined') {
          errorHandler(true);
        } else {
          parallelSocket.handshake.session.reload(errorHandler);
        }
      } else {
        errorHandler(true);
      }
    }
  }
}*/
<commit_msg>Should kick the reporteds in the teeth, not the reporters :D.<commit_after>/*
 * Serve content over a socket
 */

var config = require('../config');
var rdb = config.rdb;
var rdbLogger = config.rdbLogger;
var io = config.io;
var maxReports = config.maxReports;
var banExpiration = config.banExpiration;

var db = require('../db');
var Reported = db.Reported;

module.exports = function (socket) {

  // Add socket to session
  if (typeof socket.handshake.sw === 'undefined') {
    socket.emit('error');
    return;
  } else if (typeof socket.handshake.sw.s() === 'undefined') {
    socket.emit('error');
    return;
  }// else {
    /*socket.handshake.session.sockets.push(socket.id);
    socket.handshake.session.save();
  }*/
  rdb.sadd('chat:online', socket.id, rdbLogger);
  console.log(
    'New socket, ' + socket.id + ' ' +
    JSON.stringify(socket.handshake.sw.s())
  );

  // Looking for a new stranger.
  socket.on('stranger:req', function (data) {
    console.log(
      'Socket requested, ' + socket.id + ' ' +
      JSON.stringify(socket.handshake.sw.s())
    );

    if (authenticate(socket)) {
      if (isActive(socket.handshake.sw.s())) {
        var res;
        rdb.srandmember('chat:waiting', function (err, reply) {
          if (err) {
            socket.emit('stranger:err',
                        {err: 'Something happened when looking up for strangers.'}
                       );
          } else if (!reply) {
            res = getStrangerSocket(socket);

            if (res.ok) {
              res.strangerSocket.set('strangerSID', '');
              res.strangerSocket.set('lastStrangerIp', socket.handshake.sw.s().ip);
              socket.set('strangerSID', '');
              res.strangerSocket.emit('stranger:disconnected');
            }

            rdb.sadd('chat:waiting', socket.id);
            // TODO: setInterval(); or node events
          } else {
            res = getStrangerSocket(socket);

            if (res.ok) {
              res.strangerSocket.set('strangerSID', '');
              res.strangerSocket.set('lastStrangerIp', socket.handshake.sw.s().ip);
              socket.set('strangerSID', '');
              res.strangerSocket.emit('stranger:disconnected');
            }

            console.log('stranger found, ' + reply);
            rdb.srem('chat:waiting', reply);

            strangerSocket = io.sockets.socket(reply);
            socket.set('strangerSID', reply);
            strangerSocket.set('strangerSID', socket.id);

            socket.handshake.sw.s().chatCount += 1;
            socket.handshake.sw.save();
            strangerSocket.handshake.sw.s().chatCount += 1;
            strangerSocket.handshake.sw.save();

            socket.emit('stranger:res', {
              fullName: strangerSocket.handshake.sw.s().fullName,
            });

            strangerSocket.emit('stranger:res', {
              fullName: socket.handshake.sw.s().fullName,
            });
          }
        });
        //socket.emit('stranger:res', {found: false});
      } else {
        socket.handshake.sw.destroy();
        socket.emit('error');
      }
    }
  });

  socket.on('stranger:report', function (data) {
    if (authenticate(socket)) {
      if (data.noStranger) {
        socket.get('lastStrangerIp', function (err, ip) {
          if (err || !ip) {
            console.error('[Socket] No last stranger available.');
            if (err) console.error(err);
          } else {
            Reported.findOne({ip: ip}, function (err, reported) {
              if (err) {
                console.error('[Socket] in reporting: ' + err);
              } else if (!reported){
                var reported = new Reported({ip: ip});
                reported.reporters.push(socket.handshake.sw.s().ip);
                reported.save(function (err, reported) {
                  if (err) {
                    console.error('[Socket] Error in saving report: ' + err);
                  }
                });
              } else {
                if (reported.reporters.indexOf(socket.handshake.sw.s().ip) === -1) {
                  if (reported.reporters.length >= maxReports - 1) {
                    Banned.findOne({ip: ip}, function (err, banned) {
                      if (err) {
                      } else if (!banned) {
                        var banned = new Banned(
                          {ip: ip, expires: new Date(Date.now() + banExpiration)}
                        );
                        banned.save(function (err, banned) {
                          if (err) {
                            console.error('[Socket] Error in saving a banned user.');
                          }
                        });
                        reported.remove(function (err) {
                          if (err) {
                            console.error('[Socket] Error in removing the reported person after ban.');
                          }
                        });
                        //socket.handshake.sw.destroy();
                        //socket.emit('error');
                      } else {
                      }
                    });
                  } else {
                    reported.update(
                      {$push: {reporters: ip}},
                      function (err, reported) {
                        if (err) {
                          console.error('[Socket] Could not add reporter ip.');
                        }
                      }
                    );
                  }
                }
              }
           });
          }
        });
      } else {
        var res = getStrangerSocket(socket);

        if (res.ok) {
          if (res.strangerSocket.handshake.sw.s().ip) {
            var ip = res.strangerSocket.handshake.sw.s().ip;
            Reported.findOne({ip: ip}, function (err, reported) {
              if (err) {
                console.error("[Socket] in reporting: " + err);
              } else if (!reported) {
                var reported = new Reported({
                  ip: ip
                });
                reported.reporters.push(socket.handshake.sw.s().ip);
                reported.save(function (err, reported) {
                  if (err) {
                    console.error('[Socket] Error while saving report: ' + err);
                  }
                });
              } else {
                if (reported.reporters.indexOf(socket.handshake.sw.s().ip) === -1) {
                  if (reported.reporters.length >= maxReports - 1) {
                    Banned.findOne({ip: ip}, function (err, banned) {
                      if (err) {
                      } else if (!banned) {
                        var banned = new Banned(
                          {ip: ip, expires: new Date(Date.now() + banExpiration)}
                        );
                        banned.save(function (err, banned) {
                          if (err) {
                            console.error('[Socket] Error in saving a banned user.');
                          }
                        });
                        reported.remove(function (err) {
                          if (err) {
                            console.error('[Socket] Error in removing the reported person after ban.');
                          }
                        });
                        res.strangerSocket.handshake.sw.destroy();
                        res.strangerSocket.emit('error');
                      } else {
                      }
                    });
                  } else {
                    reported.update(
                      {$push: {reporters: ip}},
                      function (err, reported) {
                        if (err) {
                          console.error('[Socket] Could not add reporter ip.');
                        }
                      }
                    );
                  }
                }
              }
           });
          } else {
            console.error('[Socket] stranger socket has no ip for report.');
          }
        } else {
          console.error('[Socket] Getting stranger socket for report failed.');
        }
      }
    } else {
      socket.handshake.sw.destroy();
      socket.emit('error');
    }
  });

  // New message to be sent
  socket.on('msg:send', function (data) {
    if (authenticate(socket)) {
      if (data.msg.trim()) {
        socket.handshake.sw.s().msgCount += 1;
        socket.handshake.sw.save();
        var res = getStrangerSocket(socket);

        if (res.ok) {
          data.msg = {text: data.msg};
          data.msg.from = 'stranger';
          res.strangerSocket.emit('msg:recv', {msg: data.msg});
        }
      } else {
        socket.emit('msg:failed');
      }
    }
  });

  // Typing status
  socket.on('msg:typing', function (data) {
    if (authenticate(socket)) {
      var res = getStrangerSocket(socket);

      if (res.ok) {
        res.strangerSocket.emit('msg:strangerTyping', data);
      }
    }
  });

  // Socket disconnected.
  socket.on('disconnect', function () {
    console.log('Socket disconnected, ' + socket.id);
    rdb.srem('chat:online', socket.id, rdbLogger);
    rdb.srem('chat:waiting', socket.id, rdbLogger);
    var res = getStrangerSocket(socket);

    if (res.ok) {
      console.log('Stranger disconnected, ' + res.strangerSocket.id);
      res.strangerSocket.set('strangerSID', '');
      res.strangerSocket.set('lastStrangerIp', socket.handshake.sw.s().ip);
      socket.set('strangerSID', '');
      res.strangerSocket.emit('stranger:disconnected');
    }
  });

//  setInterval(function () {
//    socket.emit('send:time', {
//      time: (new Date()).toString()
//    });
//  }, 1000);
};

function getStrangerSocket(socket) {
  var ok = true;
  var strangerSocket = null;
  socket.get('strangerSID', function (err, sid) {
    if (err || !sid) {
      socket.emit('msg:err');
      ok = false;
    } else {
      strangerSocket = io.sockets.socket(sid);
    }
  });

  return {ok: ok, strangerSocket: strangerSocket};
}

function isActive(session) {
  if (session.msgCount === 0 && session.chatCount >= 3) {
    return false;
  }
  return true;
}

function authenticate(socket) {
  if (typeof socket.handshake.sw.s() !== 'undefined') {
    if (socket.handshake.sw.s().loggedIn) {
      return true;
    }
  }
  socket.emit('error');
  return false;
}
/*
function updateParallelSessions(socket) {
  var errorHandler = function (err) {
    if (err) {
      console.log('Error in parallel update session.');
    }
  };
  if (! socket.handshake.session) {
    errorHandler(true);
  }
  var parallelSocket;
  for (var sidIndex in socket.handshake.session.sockets) {
    if (socket.handshake.session.sockets[sidIndex] !== socket.id) {
      parallelSocket = io.sockets.socket(
        socket.handshake.session.sockets[sidIndex]
      );
      if (parallelSocket) {
        if (typeof parallelSocket.handshake === 'undefined') {
          errorHandler(true);
        } else if (typeof parallelSocket.handshake.session === 'undefined') {
          errorHandler(true);
        } else {
          parallelSocket.handshake.session.reload(errorHandler);
        }
      } else {
        errorHandler(true);
      }
    }
  }
}*/
<|endoftext|>


<commit_before>module.exports = {

//---------------------------------------------------------------------
// Action Name
//
// This is the name of the action displayed in the editor.
//---------------------------------------------------------------------

name: "Canvas Generate Progress Bar",

//---------------------------------------------------------------------
// Action Section
//
// This is the section the action will fall into.
//---------------------------------------------------------------------

section: "Image Editing",

//---------------------------------------------------------------------
// Action Subtitle
//
// This function generates the subtitle displayed next to the name.
//---------------------------------------------------------------------

subtitle: function(data) {
	const storeTypes = ["", "Temp Variable", "Server Variable", "Global Variable"];
	const type = ["Basic", "Circle"];
	const index = parseInt(data.type);
	return `Generate ${type[index]} Progress Bar ${storeTypes[parseInt(data.storage)]} (${data.varName})`;
},

//https://github.com/LeonZ2019/
author: "LeonZ",
version: "1.1.0",

//---------------------------------------------------------------------
// Action Storage Function
//
// Stores the relevant variable info for the editor.
//---------------------------------------------------------------------

variableStorage: function(data, varType) {
	const type = parseInt(data.storage);
	if(type !== varType) return;
	return ([data.varName, 'Image']);
},
//---------------------------------------------------------------------
// Action Fields
//
// These are the fields for the action. These fields are customized
// by creating elements with corresponding IDs in the HTML. These
// are also the names of the fields stored in the action's JSON data.
//---------------------------------------------------------------------

fields: ["storage", "varName", "type", "width", "height", "lineWidth", "lineCap", "percent", "color"],

//---------------------------------------------------------------------
// Command HTML
//
// This function returns a string containing the HTML used for
// editting actions.
//
// The "isEvent" parameter will be true if this action is being used
// for an event. Due to their nature, events lack certain information,
// so edit the HTML to reflect this.
//
// The "data" parameter stores constants for select elements to use.
// Each is an array: index 0 for commands, index 1 for events.
// The names are: sendTargets, members, roles, channels,
//                messages, servers, variables
//---------------------------------------------------------------------

html: function(isEvent, data) {
	return `

		Type:

		<select id="type" class="round" onchange="glob.onChange1(this)">
			<option value="0" selected>Basic</option>
			<option value="1">Circle</option>

		</select>

Width:

		<input id="width" class="round" type="text">

Height:

		<input id="height" class="round" type="text">

		Line Width:

		<input id="lineWidth" class="round" type="text">

		Line Cap:

		<select id="lineCap" class="round">
			<option value="0" selected>Butt</option>
			<option value="1">Round</option>
			<option value="1">Square</option>
		</select>

		Percent:

		<input id="percent" class="round" type="text">

		Color:

		<input id="color" class="round" type="text" value="FFFFFF">

		Store In:

		<select id="storage" class="round">
			${data.variables[1]}
		</select>

		Variable Name:

		<input id="varName" class="round" type="text">

`
},

//---------------------------------------------------------------------
// Action Editor Init Code
//
// When the HTML is first applied to the action editor, this code
// is also run. This helps add modifications or setup reactionary
// functions for the DOM elements.
//---------------------------------------------------------------------

init: function() {
	const {glob, document} = this;

	glob.onChange1 = function(event) {
		const Change1text = document.getElementById("Change1text");
		const Change2text = document.getElementById("Change2text");
		if (event.value === "0") {
			Change1text.innerHTML = "Width:";
			Change2text.innerHTML = "Height:";
		} else if (event.value === "1") {
			Change1text.innerHTML = "Radius:";
			Change2text.innerHTML = "Size:";
		}
	}
	glob.onChange1(document.getElementById('type'));
},

//---------------------------------------------------------------------
// Action Bot Function
//
// This is the function for the action within the Bot's Action class.
// Keep in mind event calls won't have access to the "msg" parameter,
// so be sure to provide checks for variable existance.
//---------------------------------------------------------------------

action: function(cache) {
	const Canvas = require('canvas');
	const data = cache.actions[cache.index];
	const storage = parseInt(data.storage);
	const varName = this.evalMessage(data.varName, cache);
	const type = parseInt(data.type);
	const width = parseInt(data.width);
	const height = parseInt(data.height);
	const percent = this.evalMessage(data.percent, cache);
	const lineWidth = parseInt(data.lineWidth);
	const lineCap = parseInt(data.lineCap);
	let Cap;
	switch(lineCap) {
		case 0:
			Cap = "butt";
			break;
		case 1:
			Cap = "round";
			break;
		case 2:
			Cap = "sqaure";
	}
	const color = this.evalMessage(data.color, cache);
	let canvas;
	if (type == 0) {
		canvas = Canvas.createCanvas(width,height);
	} else if (type == 1) {
		canvas = Canvas.createCanvas(height,height);
	}
	const ctx = canvas.getContext('2d');
	if (color.startsWith("#")) {
		ctx.strokeStyle = color;
	} else {
		ctx.strokeStyle = "#"+color;
	}
	ctx.lineCap = Cap;
	ctx.lineWidth = lineWidth;
	if (type == 0) {
		ctx.beginPath();
		ctx.moveTo(0, height/2);
		ctx.lineTo(width*percent/100, height/2);
	} else if (type == 1) {
		ctx.translate(height / 2, height / 2);
		ctx.rotate(-0.5 * Math.PI);
		ctx.beginPath();
		ctx.arc(0, 0, width, 0, Math.PI * 2 * percent / 100, false);
	}
	ctx.stroke();
	const result = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
	this.storeValue(result, storage, varName, cache);
	this.callNextAction(cache);
},

//---------------------------------------------------------------------
// Action Bot Mod
//
// Upon initialization of the bot, this code is run. Using the bot's
// DBM namespace, one can add/modify existing functions if necessary.
// In order to reduce conflictions between mods, be sure to alias
// functions you wish to overwrite.
//---------------------------------------------------------------------

mod: function(DBM) {
}

}; // End of module<commit_msg>Fix line cap problem<commit_after>module.exports = {

//---------------------------------------------------------------------
// Action Name
//
// This is the name of the action displayed in the editor.
//---------------------------------------------------------------------

name: "Canvas Generate Progress Bar",

//---------------------------------------------------------------------
// Action Section
//
// This is the section the action will fall into.
//---------------------------------------------------------------------

section: "Image Editing",

//---------------------------------------------------------------------
// Action Subtitle
//
// This function generates the subtitle displayed next to the name.
//---------------------------------------------------------------------

subtitle: function(data) {
	const storeTypes = ["", "Temp Variable", "Server Variable", "Global Variable"];
	const type = ["Basic", "Circle"];
	const index = parseInt(data.type);
	return `Generate ${type[index]} Progress Bar ${storeTypes[parseInt(data.storage)]} (${data.varName})`;
},

//https://github.com/LeonZ2019/
author: "LeonZ",
version: "1.1.0",

//---------------------------------------------------------------------
// Action Storage Function
//
// Stores the relevant variable info for the editor.
//---------------------------------------------------------------------

variableStorage: function(data, varType) {
	const type = parseInt(data.storage);
	if(type !== varType) return;
	return ([data.varName, 'Image']);
},
//---------------------------------------------------------------------
// Action Fields
//
// These are the fields for the action. These fields are customized
// by creating elements with corresponding IDs in the HTML. These
// are also the names of the fields stored in the action's JSON data.
//---------------------------------------------------------------------

fields: ["storage", "varName", "type", "width", "height", "lineWidth", "lineCap", "percent", "color"],

//---------------------------------------------------------------------
// Command HTML
//
// This function returns a string containing the HTML used for
// editting actions.
//
// The "isEvent" parameter will be true if this action is being used
// for an event. Due to their nature, events lack certain information,
// so edit the HTML to reflect this.
//
// The "data" parameter stores constants for select elements to use.
// Each is an array: index 0 for commands, index 1 for events.
// The names are: sendTargets, members, roles, channels,
//                messages, servers, variables
//---------------------------------------------------------------------

html: function(isEvent, data) {
	return `

		Type:

		<select id="type" class="round" onchange="glob.onChange1(this)">
			<option value="0" selected>Basic</option>
			<option value="1">Circle</option>

		</select>

Width:

		<input id="width" class="round" type="text">

Height:

		<input id="height" class="round" type="text">

		Line Width:

		<input id="lineWidth" class="round" type="text">

		Line Cap:

		<select id="lineCap" class="round">
			<option value="0" selected>Square</option>
			<option value="1">Round</option>
		</select>

		Percent:

		<input id="percent" class="round" type="text">

		Color:

		<input id="color" class="round" type="text" value="FFFFFF">

		Store In:

		<select id="storage" class="round">
			${data.variables[1]}
		</select>

		Variable Name:

		<input id="varName" class="round" type="text">

`
},

//---------------------------------------------------------------------
// Action Editor Init Code
//
// When the HTML is first applied to the action editor, this code
// is also run. This helps add modifications or setup reactionary
// functions for the DOM elements.
//---------------------------------------------------------------------

init: function() {
	const {glob, document} = this;

	glob.onChange1 = function(event) {
		const Change1text = document.getElementById("Change1text");
		const Change2text = document.getElementById("Change2text");
		if (event.value === "0") {
			Change1text.innerHTML = "Width:";
			Change2text.innerHTML = "Height:";
		} else if (event.value === "1") {
			Change1text.innerHTML = "Radius:";
			Change2text.innerHTML = "Size:";
		}
	}
	glob.onChange1(document.getElementById('type'));
},

//---------------------------------------------------------------------
// Action Bot Function
//
// This is the function for the action within the Bot's Action class.
// Keep in mind event calls won't have access to the "msg" parameter,
// so be sure to provide checks for variable existance.
//---------------------------------------------------------------------

action: function(cache) {
	const Canvas = require('canvas');
	const data = cache.actions[cache.index];
	const storage = parseInt(data.storage);
	const varName = this.evalMessage(data.varName, cache);
	const type = parseInt(data.type);
	const width = parseInt(data.width);
	const height = parseInt(data.height);
	const percent = this.evalMessage(data.percent, cache);
	const lineWidth = parseInt(data.lineWidth);
	const lineCap = parseInt(data.lineCap);
	let Cap;
	switch(lineCap) {
		case 0:
			Cap = "sqaure";
			break;
		case 1:
			Cap = "round";
			break;
	}
	const color = this.evalMessage(data.color, cache);
	let canvas;
	if (type == 0) {
		canvas = Canvas.createCanvas(width,height);
	} else if (type == 1) {
		canvas = Canvas.createCanvas(height,height);
	}
	const ctx = canvas.getContext('2d');
	if (color.startsWith("#")) {
		ctx.strokeStyle = color;
	} else {
		ctx.strokeStyle = "#"+color;
	}
	ctx.lineWidth = lineWidth;
	if (type == 0) {
		ctx.beginPath();
		switch(lineCap) {
			case 0:
				ctx.lineTo(0, height/2);
				ctx.lineTo(width*percent/100, height/2);
				break;
			case 1:
				ctx.lineTo(height/4, height/2);
				ctx.lineTo(width*percent/100-height/4, height/2);
				break;
		}
	} else if (type == 1) {
		ctx.translate(height / 2, height / 2);
		ctx.rotate(-0.5 * Math.PI);
		ctx.beginPath();
		ctx.arc(0, 0, width, 0, Math.PI * 2 * percent / 100, false);
	}
	ctx.lineCap = Cap;
	ctx.stroke();
	const result = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
	this.storeValue(result, storage, varName, cache);
	this.callNextAction(cache);
},

//---------------------------------------------------------------------
// Action Bot Mod
//
// Upon initialization of the bot, this code is run. Using the bot's
// DBM namespace, one can add/modify existing functions if necessary.
// In order to reduce conflictions between mods, be sure to alias
// functions you wish to overwrite.
//---------------------------------------------------------------------

mod: function(DBM) {
}

}; // End of module<|endoftext|>


<commit_before>'use strict';

/*
 * Defining the Package
 */
var Module = require('meanio').Module;

var Groups = new Module('groups');

/*
 * All MEAN packages require registration
 * Dependency injection is used to define required modules
 */
Groups.register(function(app, auth, database) {

  //We enable routing. By default the Package Object is passed to the routes
  Groups.routes(app, auth, database);

  //We are adding a link to the main menu for all authenticated users

  //Groups.aggregateAsset('js','/packages/system/public/services/menus.js', {group:'footer', absolute:true, weight:-9999});
  //Groups.aggregateAsset('js', 'test.js', {group: 'footer', weight: -1});

  Groups.aggregateAsset('css', 'groups.css');

  return Groups;
});
<commit_msg>make the group create and view part of the main navbar<commit_after>'use strict';

/*
 * Defining the Package
 */
var Module = require('meanio').Module;

var Groups = new Module('groups');

/*
 * All MEAN packages require registration
 * Dependency injection is used to define required modules
 */
Groups.register(function(app, auth, database) {

  //We enable routing. By default the Package Object is passed to the routes
  Groups.routes(app, auth, database);
  Groups.menus.add({
    'roles': ['authenticated'],
    'title': 'Groups',
    'link': 'all groups'
  });
  Groups.menus.add({
    'roles': ['authenticated'],
    'title': 'Create New Group',
    'link': 'create group'
  });

  //We are adding a link to the main menu for all authenticated users

  //Groups.aggregateAsset('js','/packages/system/public/services/menus.js', {group:'footer', absolute:true, weight:-9999});
  //Groups.aggregateAsset('js', 'test.js', {group: 'footer', weight: -1});

  Groups.aggregateAsset('css', 'groups.css');

  return Groups;
});
<|endoftext|>


<commit_before>/**
 * @author Karl-Magnus Jönsson
 * @copyright Kristianstads kommun
 * @license MIT license
 */

/**
 * @requires sMap/Module.js
 */

sMap.Module.GetFeatureInfo = OpenLayers.Class(sMap.Module, {

	/**
	 * The events that this module will listen to. Each event listener
	 * is connected to a method defined in this module, with the same
	 * name as the event. When another module triggers this event, the
	 * method will be called (and other modules which are listening
	 * to the same event).
	 *
	 * Look at the event listeners as a public API of the module.
	 */
	EVENT_LISTENERS : ["featuredeleted"],

	/**
	 * The events triggered from this module. Note that some modules
	 * both listens to and trigger events.
	 */
	EVENT_TRIGGERS : ["addtomenu", "addtoolbutton","showlayer","hidelayer","addlayer"],

	initialize : function(options) {
		options = options || {};

		this.EVENT_LISTENERS =
			sMap.Module.GetFeatureInfo.prototype.EVENT_LISTENERS.concat(
				sMap.Module.prototype.EVENT_LISTENERS
        );
		this.EVENT_TRIGGERS =
			sMap.Module.GetFeatureInfo.prototype.EVENT_TRIGGERS.concat(
				sMap.Module.prototype.EVENT_TRIGGERS
        );

		// This allows your control to be extended by sending in a parameter hash object
		// For example overriding a method in this class or in the parent class (see next step).
		OpenLayers.Util.applyDefaults(this, options);
		// This calls the parent class's constructor and allows to
		// extend it (e.g. override methods).
		sMap.Module.prototype.initialize.apply(this, [options]);

	},

	activate : function() {
		if (this.active===true) {
			return false;
		}
		if(!this.infocontrol){
			this.addControl();
			this.addInfoLayer();
			this.addDeleteControl();
		}
		//this.infocontrol.activate();

		var selmodule = this.getModule("Select");
		selmodule.deactivate();
		if (!this.dialogDiv){
			this.dialogDiv = this.makeDialogContent();
			this.dialogDiv = this.makeDialog(this.dialogDiv);
		}
		this.dialogDiv.dialog("open");
		this.toggleDelete();
		// Call the activate method of the parent class
		return sMap.Module.prototype.activate.apply(
	            this, arguments);
	},

	deactivate : function() {
		if (this.active!==true) {
			return false;
		}
		this.infocontrol.deactivate();
		this.deletecontrol.deactivate();
		var selmodule = this.getModule("Select");
		selmodule.activate();
		if (this.dialogDiv && this.dialogDiv.dialog("isOpen") === true) {
			return this.dialogDiv.dialog("close");
		}
		// Call the deactivate method of the parent class
		return sMap.Module.prototype.deactivate.apply(
	            this, arguments
	        );
	},

	destroy : function() {
		// Call the destroy method of the parent class
		return sMap.Module.prototype.destroy.apply(this, arguments);
	},

    /**
     * Called when all modules are initialized, i.e. after initialize.
     * All initial HTML should be produced from here.
     * @returns {void}
     */
	drawContent : function() {
		var eventChooser = this.addToToolsMenu ? "addtomenu" : "addtoolbutton";

		sMap.events.triggerEvent(eventChooser, this, {
			index : this.toolbarIndex,
			label : eventChooser=="addtomenu" ? this.lang.buttonText : null,
			hoverText : this.lang.buttonText,
			iconCSS : "ui-icon-plus",
			tagID : "button-getfeatureinfo"
		});
	},
	/**
	 * gets the module with modulename
	 * @param modulname
	 * @returns
	 */
	getModule : function(modulename){
		var m = sMap.moduleController.modules;
		for (var i=0;i<m.length;i++){
			if (m[i].MODULE_NAME == modulename) {
				return m[i];
			}
		}
	},
	/**
	 * Adds the WMSGetFeatureInfo control to the map. Adds the layer to get the information from
	 */
	addControl : function(){
		var getinfoLayerExists = this.map.getLayersByName(this.getInfoLayer).length == 1 ? true : false;
		if (!getinfoLayerExists){
			sMap.events.triggerEvent("showlayer", this, {
			    layerName : this.getInfoLayer
			});
			sMap.events.triggerEvent("hidelayer", this, {
			    layerName : this.getInfoLayer
			});
		}
		var getinfolayer = this.map.getLayersByName(this.getInfoLayer),
			self = this,
			infocontrol = new OpenLayers.Control.WMSGetFeatureInfo({
			url: getinfolayer.URL,
			layers : getinfolayer,
            queryVisible: false,
            infoFormat: "text/plain",
            eventListeners: {
                getfeatureinfo: function(event) {
                	self.addInfoFeatures(event);
                }
            }
        });
        this.map.addControl(infocontrol);
        this.infocontrol = infocontrol;
	},
	/**
	 * Adds the infoLayer to the map
	 */
	addInfoLayer : function() {
		var infoLayerExists = this.map.getLayersByName(this.infoLayerConfig.name).length == 1 ? true : false;
		if (!infoLayerExists){
			var s = this.infoLayerConfig.style;
			this.infoLayer = new OpenLayers.Layer.Vector(this.infoLayerConfig.name, {
				styleMap : new OpenLayers.StyleMap({
						"default": new OpenLayers.Style( s["default"] ),
						"select": new OpenLayers.Style( s["select"] ),
						"temporary": new OpenLayers.Style( s["temporary"] )
				}),
				projection: new OpenLayers.Projection(this.map.projection),
				selectable: true,
				displayInLayerSwitcher: this.infoLayerConfig.displayInLayerSwitcher
			});
			sMap.config.layers.overlays.push(this.infoLayerConfig);
			sMap.events.triggerEvent("addlayer", this, {
				layer : this.infoLayer
			});
			this.infoLayer.setZIndex(this.zIndex);
			this.showHideInfoLayer();
		}
	},
	/**
	 * Tests if info layer has features and shows it if it has otherwise it will be hidden
	 */
	showHideInfoLayer: function(){
		if (this.infoLayer.features.length>0 && !this.infoLayer.visibility){
			sMap.events.triggerEvent("showlayer", this, {
				layerName : this.infoLayer.name
			});
		}
		if (this.infoLayer.features.length==0 && this.infoLayer.visibility){
			sMap.events.triggerEvent("hidelayer", this, {
				layerName : this.infoLayer.name
			});
		}
	},
	/**
	 * Adds features to the infolayer
	 */
	addInfoFeatures : function(event){
		var lonlat = this.map.getLonLatFromPixel(event.xy),
			text = "Ingen data",
			zeros = Math.pow(10, this.decimals);
		if (event.text.indexOf('no results') == -1) {	//Interpret the text response
	        var lines = event.text.split('\n');
	        for (var lcv = 0; lcv < (lines.length); lcv++) {
	            var vals = lines[lcv].replace(/^\s*/,'').replace(/\s*$/,'').replace(/ = /,"=").replace(/'/g,'').split('=');
	            if (vals[1] == "") {
	                vals[1] = "Unknown";
	            }
	            if (vals[0].indexOf(this.attributeName) != -1 ) {
	                text = Math.round(vals[1]*zeros)/zeros + " m";  //Bug in OL 2.11. Labels fail when numeric data. " m" is a workaround
	            }
	        }
	    }
		var geometry = new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat),
			attributes = {info:text},
			feature = new OpenLayers.Feature.Vector(geometry,attributes),
			addlabels = $("#gfi-addlabels").prop('checked');
		if (!addlabels){
			this.clearPoints();
		}
		this.infoLayer.addFeatures([feature]);
		this.listPoints();
		this.showHideInfoLayer();
	},
	/**
	 * Clear all info points
	 */
	clearPoints : function(){
		this.infoLayer.removeAllFeatures();
		this.listPoints();
	},
	/**
	* Add deletecontrol
	*/
	addDeleteControl : function(){
		var del = new OpenLayers.Control.DeleteFeature(this.infoLayer, {
			title: "Tar bort punkter"
		});
		this.map.addControl(del);
		this.deletecontrol = del;
	},
	/**
	 * toggle deletecontrol
	 */
	toggleDelete : function(){
		var state = $("#gfi-digidiv :radio:checked").attr('id');
		if (state==="gfi-del"){
			this.infocontrol.deactivate();
			this.deletecontrol.activate();
		}
		else
		{
			this.infocontrol.activate();
			this.deletecontrol.deactivate();
		}
	},
	 featuredeleted : function(){
		this.listPoints();
	 },
	 /**
	 * List all points in the infolayer and add to the dialog
	 */
	listPoints : function(){
		var textrow,
			listdiv = $("#gfi-list"),
			zeros = Math.pow(10, this.decimals);
//		if (listdiv.html()!=""){
			listdiv.html("");  //Clear the previous results
			for (var i = 0;i < this.infoLayer.features.length;i++){
				var f = this.infoLayer.features[i];
				textrow=Math.round(f.geometry.y*zeros)/zeros + "," +Math.round(f.geometry.x*zeros)/zeros + "," +f.attributes.info.replace('m','') + "
";
				listdiv.append(textrow);
			}
//		}
	},
	/**
	 * Make a dialogDiv with description, options and a list button
	 */
	makeDialogContent : function() {
		var self = this,
			dialogDiv = $("
"),
			infoText = $(""+this.lang.descriptionText+"");
		infoText.css({
			"width" : "170px",
			"display" : "inline"
		});
		dialogDiv.append(infoText);
		var cbAddLabels = $("
"+this.lang.addPointsText+"<input id='gfi-addlabels' type='checkbox' name='gfiAdd' checked />
");
		dialogDiv.append(cbAddLabels);
		var divhtml = " <input type='radio' id='gfi-dig' name='radio' checked='checked' value='dig'>"+this.lang.addButtonText+""+
					   "<input type='radio' id='gfi-del' name='radio'>"+this.lang.deleteButtonText+"",
						digidiv = $(divhtml);
		digidiv.buttonset();
		digidiv.change(function(){
			self.toggleDelete();
		});
		dialogDiv.append(digidiv);
		var clearbutton = $("<button id='gfi-clear'>"+this.lang.clearButtonText+"</button>");
		clearbutton.click(function() {
			self.clearPoints();
		});
		clearbutton.button();
		dialogDiv.append(clearbutton);
		if (this.listButton){
			// var button = $("<button id='gfi-listpoints'>"+this.lang.listButtonText+"</button>");
			// button.click(function() {
				// self.listPoints();
			// });
			// button.button();
			// dialogDiv.append(button);
			var listdiv = $("
");
			dialogDiv.append(listdiv);
		}
		return dialogDiv;
	},
	/**
	 * Make the dialog to which all html is added.
	 */
	makeDialog : function(dialogDiv) {
		var self = this;
		dialogDiv.dialog({
			autoOpen : false,
			title : this.lang.headerText,
			position : this.dialogStartPosition,
			width : this.width,
			height : this.height,
			resizable : true,
			close : function() {
				// Deactivate module
				self.deactivate.call(self);
			},
			open : null
		});
		return dialogDiv;
	},
	// Class name needed when you want to fetch your module...
	// should correspond to the real class name.
	CLASS_NAME : "sMap.Module.GetFeatureInfo"

});<commit_msg>#24 featuredeleted listener bug<commit_after>/**
 * @author Karl-Magnus Jönsson
 * @copyright Kristianstads kommun
 * @license MIT license
 */

/**
 * @requires sMap/Module.js
 */

sMap.Module.GetFeatureInfo = OpenLayers.Class(sMap.Module, {

	/**
	 * The events that this module will listen to. Each event listener
	 * is connected to a method defined in this module, with the same
	 * name as the event. When another module triggers this event, the
	 * method will be called (and other modules which are listening
	 * to the same event).
	 *
	 * Look at the event listeners as a public API of the module.
	 */
	EVENT_LISTENERS : ["featuredeleted"],

	/**
	 * The events triggered from this module. Note that some modules
	 * both listens to and trigger events.
	 */
	EVENT_TRIGGERS : ["addtomenu", "addtoolbutton","showlayer","hidelayer","addlayer"],

	initialize : function(options) {
		options = options || {};

		this.EVENT_LISTENERS =
			sMap.Module.GetFeatureInfo.prototype.EVENT_LISTENERS.concat(
				sMap.Module.prototype.EVENT_LISTENERS
        );
		this.EVENT_TRIGGERS =
			sMap.Module.GetFeatureInfo.prototype.EVENT_TRIGGERS.concat(
				sMap.Module.prototype.EVENT_TRIGGERS
        );

		// This allows your control to be extended by sending in a parameter hash object
		// For example overriding a method in this class or in the parent class (see next step).
		OpenLayers.Util.applyDefaults(this, options);
		// This calls the parent class's constructor and allows to
		// extend it (e.g. override methods).
		sMap.Module.prototype.initialize.apply(this, [options]);

	},

	activate : function() {
		if (this.active===true) {
			return false;
		}
		if(!this.infocontrol){
			this.addControl();
			this.addInfoLayer();
			this.addDeleteControl();
		}
		//this.infocontrol.activate();

		var selmodule = this.getModule("Select");
		selmodule.deactivate();
		if (!this.dialogDiv){
			this.dialogDiv = this.makeDialogContent();
			this.dialogDiv = this.makeDialog(this.dialogDiv);
		}
		this.dialogDiv.dialog("open");
		this.toggleDelete();
		// Call the activate method of the parent class
		return sMap.Module.prototype.activate.apply(
	            this, arguments);
	},

	deactivate : function() {
		if (this.active!==true) {
			return false;
		}
		this.infocontrol.deactivate();
		this.deletecontrol.deactivate();
		var selmodule = this.getModule("Select");
		selmodule.activate();
		if (this.dialogDiv && this.dialogDiv.dialog("isOpen") === true) {
			return this.dialogDiv.dialog("close");
		}
		// Call the deactivate method of the parent class
		return sMap.Module.prototype.deactivate.apply(
	            this, arguments
	        );
	},

	destroy : function() {
		// Call the destroy method of the parent class
		return sMap.Module.prototype.destroy.apply(this, arguments);
	},

    /**
     * Called when all modules are initialized, i.e. after initialize.
     * All initial HTML should be produced from here.
     * @returns {void}
     */
	drawContent : function() {
		var eventChooser = this.addToToolsMenu ? "addtomenu" : "addtoolbutton";

		sMap.events.triggerEvent(eventChooser, this, {
			index : this.toolbarIndex,
			label : eventChooser=="addtomenu" ? this.lang.buttonText : null,
			hoverText : this.lang.buttonText,
			iconCSS : "ui-icon-plus",
			tagID : "button-getfeatureinfo"
		});
	},
	/**
	 * gets the module with modulename
	 * @param modulname
	 * @returns
	 */
	getModule : function(modulename){
		var m = sMap.moduleController.modules;
		for (var i=0;i<m.length;i++){
			if (m[i].MODULE_NAME == modulename) {
				return m[i];
			}
		}
	},
	/**
	 * Adds the WMSGetFeatureInfo control to the map. Adds the layer to get the information from
	 */
	addControl : function(){
		var getinfoLayerExists = this.map.getLayersByName(this.getInfoLayer).length == 1 ? true : false;
		if (!getinfoLayerExists){
			sMap.events.triggerEvent("showlayer", this, {
			    layerName : this.getInfoLayer
			});
			sMap.events.triggerEvent("hidelayer", this, {
			    layerName : this.getInfoLayer
			});
		}
		var getinfolayer = this.map.getLayersByName(this.getInfoLayer),
			self = this,
			infocontrol = new OpenLayers.Control.WMSGetFeatureInfo({
			url: getinfolayer.URL,
			layers : getinfolayer,
            queryVisible: false,
            infoFormat: "text/plain",
            eventListeners: {
                getfeatureinfo: function(event) {
                	self.addInfoFeatures(event);
                }
            }
        });
        this.map.addControl(infocontrol);
        this.infocontrol = infocontrol;
	},
	/**
	 * Adds the infoLayer to the map
	 */
	addInfoLayer : function() {
		var infoLayerExists = this.map.getLayersByName(this.infoLayerConfig.name).length == 1 ? true : false;
		if (!infoLayerExists){
			var s = this.infoLayerConfig.style;
			this.infoLayer = new OpenLayers.Layer.Vector(this.infoLayerConfig.name, {
				styleMap : new OpenLayers.StyleMap({
						"default": new OpenLayers.Style( s["default"] ),
						"select": new OpenLayers.Style( s["select"] ),
						"temporary": new OpenLayers.Style( s["temporary"] )
				}),
				projection: new OpenLayers.Projection(this.map.projection),
				selectable: true,
				displayInLayerSwitcher: this.infoLayerConfig.displayInLayerSwitcher
			});
			sMap.config.layers.overlays.push(this.infoLayerConfig);
			sMap.events.triggerEvent("addlayer", this, {
				layer : this.infoLayer
			});
			this.infoLayer.setZIndex(this.zIndex);
			this.showHideInfoLayer();
		}
	},
	/**
	 * Tests if info layer has features and shows it if it has otherwise it will be hidden
	 */
	showHideInfoLayer: function(){
		if (this.infoLayer.features.length>0 && !this.infoLayer.visibility){
			sMap.events.triggerEvent("showlayer", this, {
				layerName : this.infoLayer.name
			});
		}
		if (this.infoLayer.features.length==0 && this.infoLayer.visibility){
			sMap.events.triggerEvent("hidelayer", this, {
				layerName : this.infoLayer.name
			});
		}
	},
	/**
	 * Adds features to the infolayer
	 */
	addInfoFeatures : function(event){
		var lonlat = this.map.getLonLatFromPixel(event.xy),
			text = "Ingen data",
			zeros = Math.pow(10, this.decimals);
		if (event.text.indexOf('no results') == -1) {	//Interpret the text response
	        var lines = event.text.split('\n');
	        for (var lcv = 0; lcv < (lines.length); lcv++) {
	            var vals = lines[lcv].replace(/^\s*/,'').replace(/\s*$/,'').replace(/ = /,"=").replace(/'/g,'').split('=');
	            if (vals[1] == "") {
	                vals[1] = "Unknown";
	            }
	            if (vals[0].indexOf(this.attributeName) != -1 ) {
	                text = Math.round(vals[1]*zeros)/zeros + " m";  //Bug in OL 2.11. Labels fail when numeric data. " m" is a workaround
	            }
	        }
	    }
		var geometry = new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat),
			attributes = {info:text},
			feature = new OpenLayers.Feature.Vector(geometry,attributes),
			addlabels = $("#gfi-addlabels").prop('checked');
		if (!addlabels){
			this.clearPoints();
		}
		this.infoLayer.addFeatures([feature]);
		this.listPoints();
		this.showHideInfoLayer();
	},
	/**
	 * Clear all info points
	 */
	clearPoints : function(){
		this.infoLayer.removeAllFeatures();
		this.listPoints();
	},
	/**
	* Add deletecontrol
	*/
	addDeleteControl : function(){
		var del = new OpenLayers.Control.DeleteFeature(this.infoLayer, {
			title: "Tar bort punkter"
		});
		this.map.addControl(del);
		this.deletecontrol = del;
	},
	/**
	 * toggle deletecontrol
	 */
	toggleDelete : function(){
		var state = $("#gfi-digidiv :radio:checked").attr('id');
		if (state==="gfi-del"){
			this.infocontrol.deactivate();
			this.deletecontrol.activate();
		}
		else
		{
			this.infocontrol.activate();
			this.deletecontrol.deactivate();
		}
	},
	 featuredeleted : function(){
		if (this.infoLayer){
			this.listPoints();
		}
	 },
	 /**
	 * List all points in the infolayer and add to the dialog
	 */
	listPoints : function(){
		var textrow,
			listdiv = $("#gfi-list"),
			zeros = Math.pow(10, this.decimals);
//		if (listdiv.html()!=""){
			listdiv.html("");  //Clear the previous results
			for (var i = 0;i < this.infoLayer.features.length;i++){
				var f = this.infoLayer.features[i];
				textrow=Math.round(f.geometry.y*zeros)/zeros + "," +Math.round(f.geometry.x*zeros)/zeros + "," +f.attributes.info.replace('m','') + "
";
				listdiv.append(textrow);
			}
//		}
	},
	/**
	 * Make a dialogDiv with description, options and a list button
	 */
	makeDialogContent : function() {
		var self = this,
			dialogDiv = $("
"),
			infoText = $(""+this.lang.descriptionText+"");
		infoText.css({
			"width" : "170px",
			"display" : "inline"
		});
		dialogDiv.append(infoText);
		var cbAddLabels = $("
"+this.lang.addPointsText+"<input id='gfi-addlabels' type='checkbox' name='gfiAdd' checked />
");
		dialogDiv.append(cbAddLabels);
		var divhtml = " <input type='radio' id='gfi-dig' name='radio' checked='checked' value='dig'>"+this.lang.addButtonText+""+
					   "<input type='radio' id='gfi-del' name='radio'>"+this.lang.deleteButtonText+"",
						digidiv = $(divhtml);
		digidiv.buttonset();
		digidiv.change(function(){
			self.toggleDelete();
		});
		dialogDiv.append(digidiv);
		var clearbutton = $("<button id='gfi-clear'>"+this.lang.clearButtonText+"</button>");
		clearbutton.click(function() {
			self.clearPoints();
		});
		clearbutton.button();
		dialogDiv.append(clearbutton);
		if (this.listButton){
			// var button = $("<button id='gfi-listpoints'>"+this.lang.listButtonText+"</button>");
			// button.click(function() {
				// self.listPoints();
			// });
			// button.button();
			// dialogDiv.append(button);
			var listdiv = $("
");
			dialogDiv.append(listdiv);
		}
		return dialogDiv;
	},
	/**
	 * Make the dialog to which all html is added.
	 */
	makeDialog : function(dialogDiv) {
		var self = this;
		dialogDiv.dialog({
			autoOpen : false,
			title : this.lang.headerText,
			position : this.dialogStartPosition,
			width : this.width,
			height : this.height,
			resizable : true,
			close : function() {
				// Deactivate module
				self.deactivate.call(self);
			},
			open : null
		});
		return dialogDiv;
	},
	// Class name needed when you want to fetch your module...
	// should correspond to the real class name.
	CLASS_NAME : "sMap.Module.GetFeatureInfo"

});<|endoftext|>


<commit_before><commit_msg>Wrote getStationResponseTime client-side function to replace same function in 'GetAreaResponseTime.php'<commit_after><|endoftext|>


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

/* global cordova, FileSystem */

var argscheck = require('cordova/argscheck'),
    exec = require('cordova/exec'),
    FileTransferError = require('./FileTransferError'),
    ProgressEvent = require('org.apache.cordova.file.ProgressEvent');

function newProgressEvent(result) {
    var pe = new ProgressEvent();
    pe.lengthComputable = result.lengthComputable;
    pe.loaded = result.loaded;
    pe.total = result.total;
    return pe;
}

function getUrlCredentials(urlString) {
    var credentialsPattern = /^https?\:\/\/(?:(?:(([^:@\/]*)(?::([^@\/]*))?)?@)?([^:\/?#]*)(?::(\d*))?).*$/,
        credentials = credentialsPattern.exec(urlString);

    return credentials && credentials[1];
}

function getBasicAuthHeader(urlString) {
    var header =  null;

    // This is changed due to MS Windows doesn't support credentials in http uris
    // so we detect them by regexp and strip off from result url
    // Proof: http://social.msdn.microsoft.com/Forums/windowsapps/en-US/a327cf3c-f033-4a54-8b7f-03c56ba3203f/windows-foundation-uri-security-problem

    if (window.btoa) {
        var credentials = getUrlCredentials(urlString);
        if (credentials) {
            var authHeader = "Authorization";
            var authHeaderValue = "Basic " + window.btoa(credentials);

            header = {
                name : authHeader,
                value : authHeaderValue
            };
        }
    }

    return header;
}

function convertHeadersToArray(headers) {
    var result = [];
    for (var header in headers) {
        if (headers.hasOwnProperty(header)) {
            var headerValue = headers[header];
            result.push({
                name: header,
                value: headerValue.toString()
            });
        }
    }
    return result;
}

var idCounter = 0;

/**
 * FileTransfer uploads a file to a remote server.
 * @constructor
 */
var FileTransfer = function() {
    this._id = ++idCounter;
    this.onprogress = null; // optional callback
};

/**
* Given an absolute file path, uploads a file on the device to a remote server
* using a multipart HTTP request.
* @param filePath {String}           Full path of the file on the device
* @param server {String}             URL of the server to receive the file
* @param successCallback (Function}  Callback to be invoked when upload has completed
* @param errorCallback {Function}    Callback to be invoked upon error
* @param options {FileUploadOptions} Optional parameters such as file name and mimetype
* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
*/
FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {
    argscheck.checkArgs('ssFFO*', 'FileTransfer.upload', arguments);
    // check for options
    var fileKey = null;
    var fileName = null;
    var mimeType = null;
    var params = null;
    var chunkedMode = true;
    var headers = null;
    var httpMethod = null;
    var basicAuthHeader = getBasicAuthHeader(server);
    if (basicAuthHeader) {
        server = server.replace(getUrlCredentials(server) + '@', '');

        options = options || {};
        options.headers = options.headers || {};
        options.headers[basicAuthHeader.name] = basicAuthHeader.value;
    }

    if (options) {
        fileKey = options.fileKey;
        fileName = options.fileName;
        mimeType = options.mimeType;
        headers = options.headers;
        httpMethod = options.httpMethod || "POST";
        if (httpMethod.toUpperCase() == "PUT"){
            httpMethod = "PUT";
        } else {
            httpMethod = "POST";
        }
        if (options.chunkedMode !== null || typeof options.chunkedMode != "undefined") {
            chunkedMode = options.chunkedMode;
        }
        if (options.params) {
            params = options.params;
        }
        else {
            params = {};
        }
    }

    if (cordova.platformId === "windowsphone") {
        headers = headers && convertHeadersToArray(headers);
        params = params && convertHeadersToArray(params);
    }

    var fail = errorCallback && function(e) {
        var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body, e.exception);
        errorCallback(error);
    };

    var self = this;
    var win = function(result) {
        if (typeof result.lengthComputable != "undefined") {
            if (self.onprogress) {
                self.onprogress(newProgressEvent(result));
            }
        } else {
            if (successCallback) {
                successCallback(result);
            }
        }
    };
    exec(win, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id, httpMethod]);
};

/**
 * Downloads a file form a given URL and saves it to the specified directory.
 * @param source {String}          URL of the server to receive the file
 * @param target {String}         Full path of the file on the device
 * @param successCallback (Function}  Callback to be invoked when upload has completed
 * @param errorCallback {Function}    Callback to be invoked upon error
 * @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
 * @param options {FileDownloadOptions} Optional parameters such as headers
 */
FileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts, options) {
    argscheck.checkArgs('ssFF*', 'FileTransfer.download', arguments);
    var self = this;

    var basicAuthHeader = getBasicAuthHeader(source);
    if (basicAuthHeader) {
        source = source.replace(getUrlCredentials(source) + '@', '');

        options = options || {};
        options.headers = options.headers || {};
        options.headers[basicAuthHeader.name] = basicAuthHeader.value;
    }

    var headers = null;
    if (options) {
        headers = options.headers || null;
    }

    if (cordova.platformId === "windowsphone" && headers) {
        headers = convertHeadersToArray(headers);
    }

    var win = function(downloadResult) {
        var result = downloadResult;
        if(downloadResult.orientation) {
            result = downloadResult.result;
        }
        var orientation = downloadResult.orientation || 1;

        if (typeof result.lengthComputable != "undefined") {
            if (self.onprogress) {
                return self.onprogress(newProgressEvent(result));
            }
        } else if (successCallback) {
            var entry = null;
            if (result.isDirectory) {
                entry = new (require('org.apache.cordova.file.DirectoryEntry'))();
            }
            else if (result.isFile) {
                entry = new (require('org.apache.cordova.file.FileEntry'))();
            }
            entry.isDirectory = result.isDirectory;
            entry.isFile = result.isFile;
            entry.name = result.name;
            entry.fullPath = result.fullPath;
            entry.filesystem = new FileSystem(result.filesystemName || (result.filesystem == window.PERSISTENT ? 'persistent' : 'temporary'));
            entry.nativeURL = result.nativeURL;
            successCallback(entry, orientation);
        }
    };

    var fail = errorCallback && function(e) {
        var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body, e.exception);
        errorCallback(error);
    };

    exec(win, fail, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id, headers]);
};

/**
 * Aborts the ongoing file transfer on this object. The original error
 * callback for the file transfer will be called if necessary.
 */
FileTransfer.prototype.abort = function() {
    exec(null, null, 'FileTransfer', 'abort', [this._id]);
};

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

/* global cordova, FileSystem */

var argscheck = require('cordova/argscheck'),
    exec = require('cordova/exec'),
    FileTransferError = require('./FileTransferError'),
    ProgressEvent = require('cordova-plugin-file.ProgressEvent');

function newProgressEvent(result) {
    var pe = new ProgressEvent();
    pe.lengthComputable = result.lengthComputable;
    pe.loaded = result.loaded;
    pe.total = result.total;
    return pe;
}

function getUrlCredentials(urlString) {
    var credentialsPattern = /^https?\:\/\/(?:(?:(([^:@\/]*)(?::([^@\/]*))?)?@)?([^:\/?#]*)(?::(\d*))?).*$/,
        credentials = credentialsPattern.exec(urlString);

    return credentials && credentials[1];
}

function getBasicAuthHeader(urlString) {
    var header =  null;

    // This is changed due to MS Windows doesn't support credentials in http uris
    // so we detect them by regexp and strip off from result url
    // Proof: http://social.msdn.microsoft.com/Forums/windowsapps/en-US/a327cf3c-f033-4a54-8b7f-03c56ba3203f/windows-foundation-uri-security-problem

    if (window.btoa) {
        var credentials = getUrlCredentials(urlString);
        if (credentials) {
            var authHeader = "Authorization";
            var authHeaderValue = "Basic " + window.btoa(credentials);

            header = {
                name : authHeader,
                value : authHeaderValue
            };
        }
    }

    return header;
}

function convertHeadersToArray(headers) {
    var result = [];
    for (var header in headers) {
        if (headers.hasOwnProperty(header)) {
            var headerValue = headers[header];
            result.push({
                name: header,
                value: headerValue.toString()
            });
        }
    }
    return result;
}

var idCounter = 0;

/**
 * FileTransfer uploads a file to a remote server.
 * @constructor
 */
var FileTransfer = function() {
    this._id = ++idCounter;
    this.onprogress = null; // optional callback
};

/**
* Given an absolute file path, uploads a file on the device to a remote server
* using a multipart HTTP request.
* @param filePath {String}           Full path of the file on the device
* @param server {String}             URL of the server to receive the file
* @param successCallback (Function}  Callback to be invoked when upload has completed
* @param errorCallback {Function}    Callback to be invoked upon error
* @param options {FileUploadOptions} Optional parameters such as file name and mimetype
* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
*/
FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {
    argscheck.checkArgs('ssFFO*', 'FileTransfer.upload', arguments);
    // check for options
    var fileKey = null;
    var fileName = null;
    var mimeType = null;
    var params = null;
    var chunkedMode = true;
    var headers = null;
    var httpMethod = null;
    var basicAuthHeader = getBasicAuthHeader(server);
    if (basicAuthHeader) {
        server = server.replace(getUrlCredentials(server) + '@', '');

        options = options || {};
        options.headers = options.headers || {};
        options.headers[basicAuthHeader.name] = basicAuthHeader.value;
    }

    if (options) {
        fileKey = options.fileKey;
        fileName = options.fileName;
        mimeType = options.mimeType;
        headers = options.headers;
        httpMethod = options.httpMethod || "POST";
        if (httpMethod.toUpperCase() == "PUT"){
            httpMethod = "PUT";
        } else {
            httpMethod = "POST";
        }
        if (options.chunkedMode !== null || typeof options.chunkedMode != "undefined") {
            chunkedMode = options.chunkedMode;
        }
        if (options.params) {
            params = options.params;
        }
        else {
            params = {};
        }
    }

    if (cordova.platformId === "windowsphone") {
        headers = headers && convertHeadersToArray(headers);
        params = params && convertHeadersToArray(params);
    }

    var fail = errorCallback && function(e) {
        var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body, e.exception);
        errorCallback(error);
    };

    var self = this;
    var win = function(result) {
        if (typeof result.lengthComputable != "undefined") {
            if (self.onprogress) {
                self.onprogress(newProgressEvent(result));
            }
        } else {
            if (successCallback) {
                successCallback(result);
            }
        }
    };
    exec(win, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id, httpMethod]);
};

/**
 * Downloads a file form a given URL and saves it to the specified directory.
 * @param source {String}          URL of the server to receive the file
 * @param target {String}         Full path of the file on the device
 * @param successCallback (Function}  Callback to be invoked when upload has completed
 * @param errorCallback {Function}    Callback to be invoked upon error
 * @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
 * @param options {FileDownloadOptions} Optional parameters such as headers
 */
FileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts, options) {
    argscheck.checkArgs('ssFF*', 'FileTransfer.download', arguments);
    var self = this;

    var basicAuthHeader = getBasicAuthHeader(source);
    if (basicAuthHeader) {
        source = source.replace(getUrlCredentials(source) + '@', '');

        options = options || {};
        options.headers = options.headers || {};
        options.headers[basicAuthHeader.name] = basicAuthHeader.value;
    }

    var headers = null;
    if (options) {
        headers = options.headers || null;
    }

    if (cordova.platformId === "windowsphone" && headers) {
        headers = convertHeadersToArray(headers);
    }

    var win = function(downloadResult) {
        var result = downloadResult;
        if(downloadResult.orientation) {
            result = downloadResult.result;
        }
        var orientation = downloadResult.orientation || 1;

        if (typeof result.lengthComputable != "undefined") {
            if (self.onprogress) {
                return self.onprogress(newProgressEvent(result));
            }
        } else if (successCallback) {
            var entry = null;
            if (result.isDirectory) {
                entry = new (require('cordova-plugin-file.DirectoryEntry'))();
            }
            else if (result.isFile) {
                entry = new (require('cordova-plugin-file.FileEntry'))();
            }
            entry.isDirectory = result.isDirectory;
            entry.isFile = result.isFile;
            entry.name = result.name;
            entry.fullPath = result.fullPath;
            entry.filesystem = new FileSystem(result.filesystemName || (result.filesystem == window.PERSISTENT ? 'persistent' : 'temporary'));
            entry.nativeURL = result.nativeURL;
            successCallback(entry, orientation);
        }
    };

    var fail = errorCallback && function(e) {
        var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body, e.exception);
        errorCallback(error);
    };

    exec(win, fail, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id, headers]);
};

/**
 * Aborts the ongoing file transfer on this object. The original error
 * callback for the file transfer will be called if necessary.
 */
FileTransfer.prototype.abort = function() {
    exec(null, null, 'FileTransfer', 'abort', [this._id]);
};

module.exports = FileTransfer;
<|endoftext|>