<commit_before>var passport = require('passport')
  , mongoose = require('mongoose')
  , _ = require('underscore')
  , fs = require('fs');

var User = mongoose.model('User')
  , Project = mongoose.model('Project');

module.exports = function(app) {

  app.get('/api/projects', loadProjects, render('projects'));

  app.post('/api/projects/create', isAuth, validateProject, saveProject, gracefulRes);

  app.get('/api/projects/remove/:project_id', isAuth, isProjectLeader, removeProject, gracefulRes);

  app.get('/api/projects/create', isAuth, setViewVar('statuses', app.get('statuses')), render('new_project'));

  app.post('/api/cover', isAuth, uploadCover);

  app.get('/api/projects/edit/:project_id', isAuth, setViewVar('statuses', app.get('statuses')), isProjectLeader, loadProject, render('edit'));

  app.post('/api/projects/edit/:project_id', isAuth, isProjectLeader, validateProject, updateProject, gracefulRes);

  app.get('/api/projects/join/:project_id', isAuth, joinProject, followProject, loadProject, gracefulRes);

  app.get('/api/projects/leave/:project_id', isAuth, isProjectMember, leaveProject, loadProject, gracefulRes);

  app.get('/api/projects/follow/:project_id', isAuth, followProject, loadProject, gracefulRes);

  app.get('/api/projects/unfollow/:project_id', isAuth, isProjectFollower, unfollowProject, loadProject, gracefulRes);

  app.get('/api/p/:project_id', loadProject, render('project_full'));

  app.get('/api/search', loadSearchProjects, render('projects'));

};

/*
 * Render templates
 */
var render = function(path) {
  return function(req, res) {
    res.render(path, function(err, html){
      if(err) return res.send(500);
      res.json({html: html});
    });
  };
};

/*
 * Render jade view
 */
var renderView = function(path) {
  return function(req, res) {
    res.render(path);
  };
};

/*
 * Redirect to a route
 */

var redirect = function(route) {
  return function(req, res) {
    res.redirect(route);
  };
};

/*
 * Add current user template variable
 */

var loadUser = function(req, res, next) {
  res.locals.user = req.user;
  next();
};

/*
 * Makes vars available to views
 */

var setViewVar = function(key, value) {
  return function(req, res, next) {
    res.locals[key] = value;
    next();
  };
};

/*
 * Load app providers
 */

var loadProviders = function(req, res, next) {
  res.locals.providers = req.app.get('providers');
  next();
};

/*
 * Check if current user is authenticated
 */

var isAuth = function(req, res, next){
  (req.isAuthenticated()) ? next() : res.send(403);
};

/*
 * Check if current user is project leader
 */

var isProjectLeader = function(req, res, next){
  Project.findById(req.params.project_id, function(err, project) {
    if (err || !project) return res.send(404);

    if ((project.domain && req.user.admin_in.indexOf(project.domain) >= 0)
       || req.user.id === project.leader.id ){

      req.project = project;
      next();
    }
    else return res.send(401);
  });
};

/*
 * Load all projects
 */

var loadProjects = function(req, res, next) {
  Project.find({domain: req.subdomains[0]})
  .populate('contributors')
  .populate('followers')
  .populate('leader')
  .exec(function(err, projects) {
    if(err) return res.send(500);
    res.locals.projects = projects;
    res.locals.user = req.user;
    res.locals.userExists = userExistsInArray;
    next();
  });
};

/*
 * Load specific project
 */

var loadProject = function(req, res, next) {
  Project.findById(req.params.project_id)
  .populate('contributors')
  .populate('followers')
  .populate('leader')
  .exec(function(err, project) {
    if(err || !project) return res.send(500);
    res.locals.project = project;
    res.locals.user = req.user;
    res.locals.userExists = userExistsInArray;
    next();
  });
};

var userExistsInArray = function(user, arr){
  return _.find(arr, function(u){
    return (u.id == user.id);
  });
};

/*
 * Load searched projects
 * TODO: use mongoose plugin for keywords
 */

var loadSearchProjects = function(req, res, next) {
  var regex = new RegExp(req.query.q, 'i');
  var query = {};

  if(!req.query.q.length) return res.redirect('/api/projects');

  if(req.query.type === "title") query['title'] = regex;
  else if(req.query.type === "tag") query['tags'] = regex;
  else return res.send(500);

  query.domain = req.subdomains[0];

  Project
  .find(query, function(err, projects) {
    if(err) return res.send(500);
    res.locals.projects = projects;
    res.locals.user = req.user;
    res.locals.userExists = userExistsInArray;
    next();
  });
};

/*
 * Check project fields
 */

var validateProject = function(req, res, next) {
  if(req.body.title && req.body.description) next();
  else res.send(500, "Project Title and Description fields must be complete.");
};

/*
 * Save new project
 */

var saveProject = function(req, res, next) {
  var project = new Project({
      title: req.body.title
    , description: req.body.description
    , link: req.body.link
    , status: req.body.status
    , tags: req.body.tags && req.body.tags.length ? req.body.tags.split(',') : []
    , created_at: Date.now()
    , leader: req.user._id
    , followers: [req.user._id]
    , contributors: [req.user._id]
    , cover: req.body.cover
    , domain: req.subdomains[0]
  });

  project.save(function(err, project){
    if(err) return res.send(500);
    res.locals.project = project;
    next();
  });
};

/*
 * Remove a project
 */

var removeProject = function(req, res, next) {
  res.locals.project = {id: req.project.id};
  req.project.remove(function(err){
    if(err) res.send(500);
    else next();
  });
};

/*
 * Update existing project
 */

var updateProject = function(req, res, next) {
  var project = req.project;

  project.title = req.body.title || project.title;
  project.description = req.body.description || project.description;
  project.link = req.body.link || project.link;
  project.status = req.body.status || project.status;
  project.cover = req.body.cover || project.cover;
  project.tags = (req.body.tags && req.body.tags.split(',')) || project.tags;

  project.save(function(err, project){
    if(err) return res.send(500);
    res.locals.project = project;
    next();
  });
};

/*
 * Upload cover if exist
 */

var uploadCover = function(req, res, next) {
  var cover = (req.files && req.files.cover && req.files.cover.type.indexOf('image/') != -1
    && '/uploads/' + req.files.cover.path.split('/').pop() + '.' + req.files.cover.name.split('.').pop());

  if(req.files && req.files.cover && req.files.cover.type.indexOf('image/') != -1) {
    var tmp_path = req.files.cover.path
      , target_path = './public' + cover;

    fs.rename(tmp_path, target_path, function(err) {
      if (err) throw err;
      fs.unlink(tmp_path, function() {
        if (err) throw err;
        res.json({href: cover});
      });
    });
  }
};

/*
 * Check if current user is member of a project
 */

var isProjectMember = function(req, res, next) {
  Project.findOne({_id: req.params.project_id, contributors: req.user.id}, function(err, project){
    if(err || !project) return res.send(500);
    req.project = project;
    next();
  });
};

/*
 * Check if current user is follower of a project
 */

var isProjectFollower = function(req, res, next) {
  Project.findOne({_id: req.params.project_id, followers: req.user.id}, function(err, project){
    if(err || !project) return res.send(500);
    req.project = project;
    next();
  });
};

 /*
 * Add current user as a group contributor
 */

var joinProject = function(req, res, next) {
  Project.update({_id: req.params.project_id}, { $addToSet : { 'contributors': req.user.id }}, function(err){
    if(err) return res.send(500);
    next();
  });
};

/*
 * Remove current user from a group
 */

var leaveProject = function(req, res, next) {
  Project.update({_id: req.params.project_id}, { $pull: {'contributors': req.user._id }}, function(err){
    if(err) return res.send(500);
    next();
  });
};

/*
 * Add current user as project follower
 */

var followProject = function(req, res, next) {
  Project.update({_id: req.params.project_id}, { $addToSet : { 'followers': req.user.id }}, function(err){
    if(err) return res.send(500);
    next();
  });
};

/*
 * Unfollow
 */

var unfollowProject = function(req, res, next) {
  Project.update({_id: req.params.project_id},{ $pull: {'followers': req.user._id }}, function(err){
    if(err) return res.send(500);
    next();
  });
};

/*
 * Return something good
 */

var gracefulRes = function(req, res) {
  res.json({err: null, id: res.locals.project.id});
};
<commit_msg>fix non http urls<commit_after>var passport = require('passport')
  , mongoose = require('mongoose')
  , _ = require('underscore')
  , fs = require('fs');

var User = mongoose.model('User')
  , Project = mongoose.model('Project');

module.exports = function(app) {

  app.get('/api/projects', loadProjects, render('projects'));

  app.post('/api/projects/create', isAuth, validateProject, saveProject, gracefulRes);

  app.get('/api/projects/remove/:project_id', isAuth, isProjectLeader, removeProject, gracefulRes);

  app.get('/api/projects/create', isAuth, setViewVar('statuses', app.get('statuses')), render('new_project'));

  app.post('/api/cover', isAuth, uploadCover);

  app.get('/api/projects/edit/:project_id', isAuth, setViewVar('statuses', app.get('statuses')), isProjectLeader, loadProject, render('edit'));

  app.post('/api/projects/edit/:project_id', isAuth, isProjectLeader, validateProject, updateProject, gracefulRes);

  app.get('/api/projects/join/:project_id', isAuth, joinProject, followProject, loadProject, gracefulRes);

  app.get('/api/projects/leave/:project_id', isAuth, isProjectMember, leaveProject, loadProject, gracefulRes);

  app.get('/api/projects/follow/:project_id', isAuth, followProject, loadProject, gracefulRes);

  app.get('/api/projects/unfollow/:project_id', isAuth, isProjectFollower, unfollowProject, loadProject, gracefulRes);

  app.get('/api/p/:project_id', loadProject, render('project_full'));

  app.get('/api/search', loadSearchProjects, render('projects'));

};

/*
 * Render templates
 */
var render = function(path) {
  return function(req, res) {
    res.render(path, function(err, html){
      if(err) return res.send(500);
      res.json({html: html});
    });
  };
};

/*
 * Render jade view
 */
var renderView = function(path) {
  return function(req, res) {
    res.render(path);
  };
};

/*
 * Redirect to a route
 */

var redirect = function(route) {
  return function(req, res) {
    res.redirect(route);
  };
};

/*
 * Add current user template variable
 */

var loadUser = function(req, res, next) {
  res.locals.user = req.user;
  next();
};

/*
 * Makes vars available to views
 */

var setViewVar = function(key, value) {
  return function(req, res, next) {
    res.locals[key] = value;
    next();
  };
};

/*
 * Load app providers
 */

var loadProviders = function(req, res, next) {
  res.locals.providers = req.app.get('providers');
  next();
};

/*
 * Check if current user is authenticated
 */

var isAuth = function(req, res, next){
  (req.isAuthenticated()) ? next() : res.send(403);
};

/*
 * Check if current user is project leader
 */

var isProjectLeader = function(req, res, next){
  Project.findById(req.params.project_id, function(err, project) {
    if (err || !project) return res.send(404);

    if ((project.domain && req.user.admin_in.indexOf(project.domain) >= 0)
       || req.user.id === project.leader.id ){

      req.project = project;
      next();
    }
    else return res.send(401);
  });
};

/*
 * Load all projects
 */

var loadProjects = function(req, res, next) {
  Project.find({domain: req.subdomains[0]})
  .populate('contributors')
  .populate('followers')
  .populate('leader')
  .exec(function(err, projects) {
    if(err) return res.send(500);
    res.locals.projects = projects;
    res.locals.user = req.user;
    res.locals.userExists = userExistsInArray;
    next();
  });
};

/*
 * Load specific project
 */

var loadProject = function(req, res, next) {
  Project.findById(req.params.project_id)
  .populate('contributors')
  .populate('followers')
  .populate('leader')
  .exec(function(err, project) {
    if(err || !project) return res.send(500);
    res.locals.project = project;
    res.locals.user = req.user;
    res.locals.userExists = userExistsInArray;
    next();
  });
};

var userExistsInArray = function(user, arr){
  return _.find(arr, function(u){
    return (u.id == user.id);
  });
};

/*
 * Load searched projects
 * TODO: use mongoose plugin for keywords
 */

var loadSearchProjects = function(req, res, next) {
  var regex = new RegExp(req.query.q, 'i');
  var query = {};

  if(!req.query.q.length) return res.redirect('/api/projects');

  if(req.query.type === "title") query['title'] = regex;
  else if(req.query.type === "tag") query['tags'] = regex;
  else return res.send(500);

  query.domain = req.subdomains[0];

  Project
  .find(query, function(err, projects) {
    if(err) return res.send(500);
    res.locals.projects = projects;
    res.locals.user = req.user;
    res.locals.userExists = userExistsInArray;
    next();
  });
};

/*
 * Check project fields
 */

var validateProject = function(req, res, next) {
  if(req.body.title && req.body.description) next();
  else res.send(500, "Project Title and Description fields must be complete.");
};

/*
 * Save new project
 */

var saveProject = function(req, res, next) {
  if(req.body.link && req.body.link.indexOf('http') != 0) {
    req.body.link = 'http://' + req.body.link;
  }

  var project = new Project({
      title: req.body.title
    , description: req.body.description
    , link: req.body.link
    , status: req.body.status
    , tags: req.body.tags && req.body.tags.length ? req.body.tags.split(',') : []
    , created_at: Date.now()
    , leader: req.user._id
    , followers: [req.user._id]
    , contributors: [req.user._id]
    , cover: req.body.cover
    , domain: req.subdomains[0]
  });

  project.save(function(err, project){
    if(err) return res.send(500);
    res.locals.project = project;
    next();
  });
};

/*
 * Remove a project
 */

var removeProject = function(req, res, next) {
  res.locals.project = {id: req.project.id};
  req.project.remove(function(err){
    if(err) res.send(500);
    else next();
  });
};

/*
 * Update existing project
 */

var updateProject = function(req, res, next) {
  var project = req.project;

  project.title = req.body.title || project.title;
  project.description = req.body.description || project.description;
  project.link = req.body.link || project.link;
  project.status = req.body.status || project.status;
  project.cover = req.body.cover || project.cover;
  project.tags = (req.body.tags && req.body.tags.split(',')) || project.tags;

  project.save(function(err, project){
    if(err) return res.send(500);
    res.locals.project = project;
    next();
  });
};

/*
 * Upload cover if exist
 */

var uploadCover = function(req, res, next) {
  var cover = (req.files && req.files.cover && req.files.cover.type.indexOf('image/') != -1
    && '/uploads/' + req.files.cover.path.split('/').pop() + '.' + req.files.cover.name.split('.').pop());

  if(req.files && req.files.cover && req.files.cover.type.indexOf('image/') != -1) {
    var tmp_path = req.files.cover.path
      , target_path = './public' + cover;

    fs.rename(tmp_path, target_path, function(err) {
      if (err) throw err;
      fs.unlink(tmp_path, function() {
        if (err) throw err;
        res.json({href: cover});
      });
    });
  }
};

/*
 * Check if current user is member of a project
 */

var isProjectMember = function(req, res, next) {
  Project.findOne({_id: req.params.project_id, contributors: req.user.id}, function(err, project){
    if(err || !project) return res.send(500);
    req.project = project;
    next();
  });
};

/*
 * Check if current user is follower of a project
 */

var isProjectFollower = function(req, res, next) {
  Project.findOne({_id: req.params.project_id, followers: req.user.id}, function(err, project){
    if(err || !project) return res.send(500);
    req.project = project;
    next();
  });
};

 /*
 * Add current user as a group contributor
 */

var joinProject = function(req, res, next) {
  Project.update({_id: req.params.project_id}, { $addToSet : { 'contributors': req.user.id }}, function(err){
    if(err) return res.send(500);
    next();
  });
};

/*
 * Remove current user from a group
 */

var leaveProject = function(req, res, next) {
  Project.update({_id: req.params.project_id}, { $pull: {'contributors': req.user._id }}, function(err){
    if(err) return res.send(500);
    next();
  });
};

/*
 * Add current user as project follower
 */

var followProject = function(req, res, next) {
  Project.update({_id: req.params.project_id}, { $addToSet : { 'followers': req.user.id }}, function(err){
    if(err) return res.send(500);
    next();
  });
};

/*
 * Unfollow
 */

var unfollowProject = function(req, res, next) {
  Project.update({_id: req.params.project_id},{ $pull: {'followers': req.user._id }}, function(err){
    if(err) return res.send(500);
    next();
  });
};

/*
 * Return something good
 */

var gracefulRes = function(req, res) {
  res.json({err: null, id: res.locals.project.id});
};
<|endoftext|>


<commit_before>/**
 *
 * The MIT License (MIT)
 *
 * https://www.flowchain.co
 *
 * Copyright (c) 2016-present Jollen
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

'use strict';

var Debug = require('./debug');

/**
 * Chord Node Class
 */
var Node = require('../p2p');

/*
 * Chord protocols
 */
var Chord = require('../p2p/libs/message');

/**
 * Chord Utils
 */
var ChordUtils = require('../p2p/libs/utils');

/**
 * Web of Things Framework
 */
var Framework = require('../wot/framework')
  , WebsocketBroker = require('../wot/broker')
  , WebsocketRouter = require('../wot/router')
  , WebsocketRequestHandlers = require('../wot/requestHandlers');

/**
 * Util Modules
 */
var merge = require('utils-merge');
var uuid = require('uuid');
var util = require('util');
var WebSocketClient = require('websocket').client;

/*
 * Chord utils
 */
var serialize = JSON.stringify;
var deserialize = JSON.parse;

/*
 * Blockchain system
 */
var Miner = require('../block/mining');      // Import flowchain miner
var block = require('../block/genesis');     // Import flowchain genesis block

/*
 * Consensus systems
 */
var Consensus = require('../Consensus');
var bi = new Consensus.BI;

/**
 * WebSocket URL Router
 */
var wsHandlers = {
   "/object/([A-Za-z0-9-]+)/viewer": WebsocketRequestHandlers.viewer,
   "/object/([A-Za-z0-9-]+)/status": WebsocketRequestHandlers.status,
   "/object/([A-Za-z0-9-]+)/send": WebsocketRequestHandlers.send,

   "/node/([A-Za-z0-9-]+)/receive": WebsocketRequestHandlers.receive
};

/*
 * Constructor - bind a Chord node
 *
 * @param {Object} Chord server
 */
function Server() {
  this.port = process.env.PORT || 8000;
  this.host = process.env.HOST || 'localhost';
  this.endpoint = process.env.ENDPOINT || null;
  this.thingid = process.env.THINGID || '5550937980d51931b3000009';
  this.server = null;

  // initialize the public attributes
  this.nodes = {};

  // initialize the private attributes
  this._options = {}

  // Websocket connection of endpoint
  this.endpointConnection = null;

  /*
   * Create a unique ID for the new node.
   *
   *  1. The ID of the node can be hashed by IP address.
   *  2. Hased by URI at this project.
   */
  if (process.env.ENV === 'development')
    var id = ChordUtils.hashTestId(process.env.ID);
  else
    var id = ChordUtils.hash(uuid.v4());

  // Create a new Chord node with the ID
  var node = new Node(id, this);

  // The Node instances
  this.node = this.nodes[id] = node;
  this.last_node = id;

  // Create a new miner
  this.miner = new Miner();
  this._miner_id = 0;

  // Blocks
  this.blockchain = [];
};

/**
 * The server event handlers
 */
Server.prototype.onData = function(payload) {
  // Parse the data received from Chord node (WebSocket client)
  var packet = deserialize(payload.data);

  // Request URI
  var pathname = payload.pathname;

  if (typeof packet.message === 'undefined'
        || typeof packet.message.type === 'undefined') {
    // Not a chord message
    if (typeof this._options.ondata === 'function') {
        var req = {
          node: {}
        };
        var res = {
          save: function() {},
          read: function() {}
        };

        req.node = this.node;
        req.data = packet;
        res.save = this.save.bind(this);
        res.read = this.read.bind(this);

        return this._options.ondata(req, res);
    }
  }

  /*
   * Format of 'packet'.
   *
   *  { message: { type: 0, id: '77c44c4f7bd4044129babdf235d943ff25a1d5f0' },
   *  from: { id: '77c44c4f7bd4044129babdf235d943ff25a1d5f0' } }
   */

  // Get last node's instance by ID
  var to = this.nodes[this.last_node];

  // Forward the message
  if (packet.to) {
    // Forward this message to the node ID
    to = this.nodes[packet.to];
  }

  var tx = {};

  if (typeof packet.message.data !== 'undefined') {
    tx = packet.message.data;
  }

  // This message is for me to query data of my blocks
  if (typeof this._options.onquery === 'function'
        && typeof tx !== 'undefined'
        && typeof tx.origin !== 'undefined'
        && packet.message.type === Chord.MESSAGE) {
    var req = {
      node: {}
    };
    var res = {
      save: function() {},
      read: function() {},
      send: function() {}
    };

    req.node = this.node;
    req.payload = payload;
    req.block = this.blockchain[this.blockchain.length - 1];
    req.tx = tx;

    res.save = this.save.bind(this);
    res.read = this.read.bind(this);
    res.send = this.sendAsset.bind(this);

    return this._options.onquery(req, res);

  // The message is for me
  } else if (typeof this._options.onmessage === 'function'
        && packet.message.type === Chord.MESSAGE) {
    var req = {
      node: {}
    };
    var res = {
      save: function() {},
      read: function() {},
      send: function() {}
    };

    req.node = this.node;
    req.payload = payload;
    req.block = this.blockchain[this.blockchain.length - 1];

    res.save = this.save.bind(this);
    res.read = this.read.bind(this);
    res.send = this.sendAsset.bind(this);

    return this._options.onmessage(req, res);
  }

  // Get node instance by ID and dispatch the message
  if (to) {
    to.dispatch(packet.from, packet.message);
  }
};

/**
 * Web of things framework event handlers
 */
Server.prototype.onNewThing = function(thing) {
  if (Debug.Verbose)
    console.info('onNewThing:', thing);

  // Invoke framework API to register new thing
  this.registerThing(thing);
};

/**
 * Start a Websocket server
 *
 * @param options {Object} - Configuration file
 * @returns {None}
 * @api public
 */
Server.prototype.start = function(options) {
  var self = this;
  var options = options || {};

  for (var prop in options) {
    if (options.hasOwnProperty(prop)
        && typeof(this._options[prop]) === 'undefined')
      this._options[prop] = options[prop];
  }

  // Prepare to start Websocket server
  var server = new WebsocketBroker({
    port: this.port,
    host: this.host
  });

  var router = new WebsocketRouter();

  // Websocket server events (the protocol layer)
  server.on('data', this.onData.bind(this));

  // Web of things framework event aggregation (the things layer)
  server.on('newThing', this.onNewThing.bind(this));

  // Connect to a subsequent Chord node
  if (typeof options.join === 'object') {
    this.node.join(options.join);
  }

  server.start(router.route, wsHandlers);

  this.server = server;

  console.log('----- Genesis Block -----');
  console.log( JSON.stringify(block) );

  console.log('----- Start mining -----');
  var miner = this.miner;

  miner.setTransactions([this.node]);
  miner.setPreviousBlock(block);

  // Start to generate a hash
  this._miner_id = setInterval(function() {
      miner.generateHash();

      // A success hash is generated
      if (miner.isSuccess()) {
          var block = miner.getNewBlock();

          // Successful mined and save the new block
          self.blockchain.push(block);

          miner.setPreviousBlock(block);

          console.log('Difficulty: ' + block.difficulty)
          console.log('Block #' + block.no + ': ' + block.hash);
      } else {
          var block = miner.getMiningBlock();
          //console.log('current difficulty = ' + block.difficulty)
      }
  }, 50);

  // Event callbacks
  if (typeof this._options.onstart === 'function') {
    var req = {
      node: {}
    };
    var res = {
      save: function() {},
      read: function() {}
    };

    req.node = this.node;
    res.save = this.save.bind(this);
    res.read = this.read.bind(this);

    this._options.onstart(req, res);
  }
};

/**
 * Shutdown the Websocket server.
 *
 * @param cb {Function} The complete callback
 * @return {}
 * @api public
 */
Server.prototype.shutdown = function(cb) {
  clearInterval(this._miner_id);
  this.node.clearIntervals();
  if (this.server)
    this.server.shutdown(cb);
}

/*
 * CRUD of data query
 *
 * @param {Object} { address: '127.0.0.1', port: 8000 }
 * @param {Object} { type: 2, id: 'b283326930a8b2baded20bb1cf5b6358' }
 */
Server.prototype.save = function(data) {
  return this.node.save(data);
};

/*
 * CRUD of data query
 *
 * @param key {String} -
 */
Server.prototype.read = function(key) {
  return this.node.read(key);
};

/**
 * The RPC to send a Chord message.
 *
 * @param to {Object} - Destination. e.g. { address: '127.0.0.1', port: 8000 }
 * @param packet {Object} - Data payload e.g. { type: 2, id: 'b283326930a8b2baded20bb1cf5b6358' }
 * @returns {None}
 * @api public
 */
var connections = [];

Server.prototype.sendChordMessage = function(to, packet) {
  var uri = util.format('ws://%s:%s/node/%s/receive', to.address, to.port, packet.message.id);
  var host = util.format('ws://%s:%s', to.address, to.port);
  var payload = {
    message: packet.message,
    from: packet.from
  };

  // Connection cache
  var connection = connections[host] || null;

  if (ChordUtils.DebugServer)
    console.info('send to ' + uri);

  if (connection) {
    if (connection.connected) {
      connection.sendUTF(JSON.stringify(payload));
    } else {
      delete connections[host];
    }

    return 0;
  }

  var client = new WebSocketClient();

  client.on('connect', function(connection) {
    if (connection.connected) {
      connection.sendUTF(JSON.stringify(payload));
      connections[host] = connection;
    } else {
      delete connections[host];
    }
  });

  client.connect(uri, '');
};

/**
 * Give an asset to endpoint.
 *
 * @param asset {Object} - Issued asset to be gave out
 * @returns {Object}
 * @api public
 */
Server.prototype.sendAsset = function(asset) {
    // Start forward data to endpoint
    var endpoint = this.endpoint;
    var connection = this.endpointConnection;
    var self = this;

    if (!endpoint) return;

    if (!/^(ws|wss):\/\//.test(endpoint)) {
        endpoint = 'ws://' + endpoint;
    }

    if (connection === null) {
        var wsClient = new WebSocketClient();

        wsClient.on('connectFailed', function(error) {
            self.endpointConnection = null;
        });

        wsClient.on('connect', function(conn) {
            conn.on('error', function(error) {
                self.endpointConnection = null;
            });
            conn.on('close', function() {
                self.endpointConnection = null;
            });
            conn.on('message', function(message) {
            });

            self.endpointConnection = conn;
        });

        var uri = util.format('%s/object/%s/send', endpoint, this.thingid);

        // initial websocket connection
        return wsClient.connect(uri, '');
    }

    if (typeof asset === 'object')
        asset = JSON.stringify(asset);

    // Send data to endpont
    connection.sendUTF(asset);
};

/**
 * Create a web of things server
 *
 * @returns {Object}
 * @api public
 */
function createServer() {
    var _server = new Server();

    // Combined Websocket server with web of things framework
    var server = new Framework({
        server: _server
    });

    return server;
}

/**
 * Export the server.
 */
module.exports = createServer();
<commit_msg>fix bugs<commit_after>/**
 *
 * The MIT License (MIT)
 *
 * https://www.flowchain.co
 *
 * Copyright (c) 2016-present Jollen
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

'use strict';

var Debug = require('./debug');

/**
 * Chord Node Class
 */
var Node = require('../p2p');

/*
 * Chord protocols
 */
var Chord = require('../p2p/libs/message');

/**
 * Chord Utils
 */
var ChordUtils = require('../p2p/libs/utils');

/**
 * Web of Things Framework
 */
var Framework = require('../wot/framework')
  , WebsocketBroker = require('../wot/broker')
  , WebsocketRouter = require('../wot/router')
  , WebsocketRequestHandlers = require('../wot/requestHandlers');

/**
 * Util Modules
 */
var merge = require('utils-merge');
var uuid = require('uuid');
var util = require('util');
var WebSocketClient = require('websocket').client;

/*
 * Chord utils
 */
var serialize = JSON.stringify;
var deserialize = JSON.parse;

/*
 * Blockchain system
 */
var Miner = require('../block/mining');      // Import flowchain miner
var block = require('../block/genesis');     // Import flowchain genesis block

/*
 * Consensus systems
 */
var Consensus = require('../consensus');
var bi = new Consensus.BI;

/**
 * WebSocket URL Router
 */
var wsHandlers = {
   "/object/([A-Za-z0-9-]+)/viewer": WebsocketRequestHandlers.viewer,
   "/object/([A-Za-z0-9-]+)/status": WebsocketRequestHandlers.status,
   "/object/([A-Za-z0-9-]+)/send": WebsocketRequestHandlers.send,

   "/node/([A-Za-z0-9-]+)/receive": WebsocketRequestHandlers.receive
};

/*
 * Constructor - bind a Chord node
 *
 * @param {Object} Chord server
 */
function Server() {
  this.port = process.env.PORT || 8000;
  this.host = process.env.HOST || 'localhost';
  this.endpoint = process.env.ENDPOINT || null;
  this.thingid = process.env.THINGID || '5550937980d51931b3000009';
  this.server = null;

  // initialize the public attributes
  this.nodes = {};

  // initialize the private attributes
  this._options = {}

  // Websocket connection of endpoint
  this.endpointConnection = null;

  /*
   * Create a unique ID for the new node.
   *
   *  1. The ID of the node can be hashed by IP address.
   *  2. Hased by URI at this project.
   */
  if (process.env.ENV === 'development')
    var id = ChordUtils.hashTestId(process.env.ID);
  else
    var id = ChordUtils.hash(uuid.v4());

  // Create a new Chord node with the ID
  var node = new Node(id, this);

  // The Node instances
  this.node = this.nodes[id] = node;
  this.last_node = id;

  // Create a new miner
  this.miner = new Miner();
  this._miner_id = 0;

  // Blocks
  this.blockchain = [];
};

/**
 * The server event handlers
 */
Server.prototype.onData = function(payload) {
  // Parse the data received from Chord node (WebSocket client)
  var packet = deserialize(payload.data);

  // Request URI
  var pathname = payload.pathname;

  if (typeof packet.message === 'undefined'
        || typeof packet.message.type === 'undefined') {
    // Not a chord message
    if (typeof this._options.ondata === 'function') {
        var req = {
          node: {}
        };
        var res = {
          save: function() {},
          read: function() {}
        };

        req.node = this.node;
        req.data = packet;
        res.save = this.save.bind(this);
        res.read = this.read.bind(this);

        return this._options.ondata(req, res);
    }
  }

  /*
   * Format of 'packet'.
   *
   *  { message: { type: 0, id: '77c44c4f7bd4044129babdf235d943ff25a1d5f0' },
   *  from: { id: '77c44c4f7bd4044129babdf235d943ff25a1d5f0' } }
   */

  // Get last node's instance by ID
  var to = this.nodes[this.last_node];

  // Forward the message
  if (packet.to) {
    // Forward this message to the node ID
    to = this.nodes[packet.to];
  }

  var tx = {};

  if (typeof packet.message.data !== 'undefined') {
    tx = packet.message.data;
  }

  // This message is for me to query data of my blocks
  if (typeof this._options.onquery === 'function'
        && typeof tx !== 'undefined'
        && typeof tx.origin !== 'undefined'
        && packet.message.type === Chord.MESSAGE) {
    var req = {
      node: {}
    };
    var res = {
      save: function() {},
      read: function() {},
      send: function() {}
    };

    req.node = this.node;
    req.payload = payload;
    req.block = this.blockchain[this.blockchain.length - 1];
    req.tx = tx;

    res.save = this.save.bind(this);
    res.read = this.read.bind(this);
    res.send = this.sendAsset.bind(this);

    return this._options.onquery(req, res);

  // The message is for me
  } else if (typeof this._options.onmessage === 'function'
        && packet.message.type === Chord.MESSAGE) {
    var req = {
      node: {}
    };
    var res = {
      save: function() {},
      read: function() {},
      send: function() {}
    };

    req.node = this.node;
    req.payload = payload;
    req.block = this.blockchain[this.blockchain.length - 1];

    res.save = this.save.bind(this);
    res.read = this.read.bind(this);
    res.send = this.sendAsset.bind(this);

    return this._options.onmessage(req, res);
  }

  // Get node instance by ID and dispatch the message
  if (to) {
    to.dispatch(packet.from, packet.message);
  }
};

/**
 * Web of things framework event handlers
 */
Server.prototype.onNewThing = function(thing) {
  if (Debug.Verbose)
    console.info('onNewThing:', thing);

  // Invoke framework API to register new thing
  this.registerThing(thing);
};

/**
 * Start a Websocket server
 *
 * @param options {Object} - Configuration file
 * @returns {None}
 * @api public
 */
Server.prototype.start = function(options) {
  var self = this;
  var options = options || {};

  for (var prop in options) {
    if (options.hasOwnProperty(prop)
        && typeof(this._options[prop]) === 'undefined')
      this._options[prop] = options[prop];
  }

  // Prepare to start Websocket server
  var server = new WebsocketBroker({
    port: this.port,
    host: this.host
  });

  var router = new WebsocketRouter();

  // Websocket server events (the protocol layer)
  server.on('data', this.onData.bind(this));

  // Web of things framework event aggregation (the things layer)
  server.on('newThing', this.onNewThing.bind(this));

  // Connect to a subsequent Chord node
  if (typeof options.join === 'object') {
    this.node.join(options.join);
  }

  server.start(router.route, wsHandlers);

  this.server = server;

  console.log('----- Genesis Block -----');
  console.log( JSON.stringify(block) );

  console.log('----- Start mining -----');
  var miner = this.miner;

  miner.setTransactions([this.node]);
  miner.setPreviousBlock(block);

  // Start to generate a hash
  this._miner_id = setInterval(function() {
      miner.generateHash();

      // A success hash is generated
      if (miner.isSuccess()) {
          var block = miner.getNewBlock();

          // Successful mined and save the new block
          self.blockchain.push(block);

          miner.setPreviousBlock(block);

          console.log('Difficulty: ' + block.difficulty)
          console.log('Block #' + block.no + ': ' + block.hash);
      } else {
          var block = miner.getMiningBlock();
          //console.log('current difficulty = ' + block.difficulty)
      }
  }, 50);

  // Event callbacks
  if (typeof this._options.onstart === 'function') {
    var req = {
      node: {}
    };
    var res = {
      save: function() {},
      read: function() {}
    };

    req.node = this.node;
    res.save = this.save.bind(this);
    res.read = this.read.bind(this);

    this._options.onstart(req, res);
  }
};

/**
 * Shutdown the Websocket server.
 *
 * @param cb {Function} The complete callback
 * @return {}
 * @api public
 */
Server.prototype.shutdown = function(cb) {
  clearInterval(this._miner_id);
  this.node.clearIntervals();
  if (this.server)
    this.server.shutdown(cb);
}

/*
 * CRUD of data query
 *
 * @param {Object} { address: '127.0.0.1', port: 8000 }
 * @param {Object} { type: 2, id: 'b283326930a8b2baded20bb1cf5b6358' }
 */
Server.prototype.save = function(data) {
  return this.node.save(data);
};

/*
 * CRUD of data query
 *
 * @param key {String} -
 */
Server.prototype.read = function(key) {
  return this.node.read(key);
};

/**
 * The RPC to send a Chord message.
 *
 * @param to {Object} - Destination. e.g. { address: '127.0.0.1', port: 8000 }
 * @param packet {Object} - Data payload e.g. { type: 2, id: 'b283326930a8b2baded20bb1cf5b6358' }
 * @returns {None}
 * @api public
 */
var connections = [];

Server.prototype.sendChordMessage = function(to, packet) {
  var uri = util.format('ws://%s:%s/node/%s/receive', to.address, to.port, packet.message.id);
  var host = util.format('ws://%s:%s', to.address, to.port);
  var payload = {
    message: packet.message,
    from: packet.from
  };

  // Connection cache
  var connection = connections[host] || null;

  if (ChordUtils.DebugServer)
    console.info('send to ' + uri);

  if (connection) {
    if (connection.connected) {
      connection.sendUTF(JSON.stringify(payload));
    } else {
      delete connections[host];
    }

    return 0;
  }

  var client = new WebSocketClient();

  client.on('connect', function(connection) {
    if (connection.connected) {
      connection.sendUTF(JSON.stringify(payload));
      connections[host] = connection;
    } else {
      delete connections[host];
    }
  });

  client.connect(uri, '');
};

/**
 * Give an asset to endpoint.
 *
 * @param asset {Object} - Issued asset to be gave out
 * @returns {Object}
 * @api public
 */
Server.prototype.sendAsset = function(asset) {
    // Start forward data to endpoint
    var endpoint = this.endpoint;
    var connection = this.endpointConnection;
    var self = this;

    if (!endpoint) return;

    if (!/^(ws|wss):\/\//.test(endpoint)) {
        endpoint = 'ws://' + endpoint;
    }

    if (connection === null) {
        var wsClient = new WebSocketClient();

        wsClient.on('connectFailed', function(error) {
            self.endpointConnection = null;
        });

        wsClient.on('connect', function(conn) {
            conn.on('error', function(error) {
                self.endpointConnection = null;
            });
            conn.on('close', function() {
                self.endpointConnection = null;
            });
            conn.on('message', function(message) {
            });

            self.endpointConnection = conn;
        });

        var uri = util.format('%s/object/%s/send', endpoint, this.thingid);

        // initial websocket connection
        return wsClient.connect(uri, '');
    }

    if (typeof asset === 'object')
        asset = JSON.stringify(asset);

    // Send data to endpont
    connection.sendUTF(asset);
};

/**
 * Create a web of things server
 *
 * @returns {Object}
 * @api public
 */
function createServer() {
    var _server = new Server();

    // Combined Websocket server with web of things framework
    var server = new Framework({
        server: _server
    });

    return server;
}

/**
 * Export the server.
 */
module.exports = createServer();
<|endoftext|>


<commit_before>'use strict';

var express = require('express');
var router = express.Router();
var extend = require('node.extend');
var redis = require("redis");
var client = redis.createClient();
var request = require('request');
var lxc = require('../lxc');
var os = require('os');
var spawn = require('child_process').spawn;

var totalMem = os.totalmem();
var timeoutEvents = {};
var ip2name = {};
var availContainers = [];
var usedContainers = [];

var getFreeMem = function(callback){

	var prc = spawn('free',  ['-b']);

	prc.stdout.setEncoding('utf8');
	prc.stdout.on('data', function (data) {
	  var str = data.toString()
	  var lines = str.split(/\n/g);
	  for(var i = 0; i < lines.length; i++) {
	     lines[i] = lines[i].split(/\s+/);
	  }
	  var freeMem = Number(lines[2][3]);
	  return callback(freeMem);
	});

	prc.on('close', function (code) {
	});
};

var lxcTimeout = function(ip, time){
	var name = ip2name[ip];
	console.log(name)
	time = time || 900000; // 15 minutes
	var keys = Object.keys(timeoutEvents)
	if(keys.indexOf(name) !== -1){
		clearTimeout(timeoutEvents[name])
	}
	timeoutEvents[name] = setTimeout(function(){
		lxc.stop(name);
	}, time);
}

var runner = function(req, res, ip){
	lxcTimeout(ip);

	var httpOptions = {
		url:'http://' + ip + ':15000',
		body: JSON.stringify({
			code: req.body.code
		})
	};

	return request.post(httpOptions, function(error, response, body){
		body = JSON.parse(body);
		body['ip'] = ip.replace('10.0.', '');
		return res.json(body);
	});
};

var addToRedis = function(){
	lxc.info(req.params.name, null, function(data){
			var domain = req.query.domain || 'vm42.us';
			domain = req.params.name+'.'+domain;
			client.SADD("hosts", domain, function(){});

			var ip = data.ip + ':5000';
			client.HSET(domain, "ip", ip, redis.print);
			client.HSET(domain, "updated", (new Date).getTime(), redis.print);
			client.hset(domain, "include", "proxy.include");
			return res.json({status: 200, info: data});
	 });
};

router.get('/start/:name', function(req, res, next){
	return lxc.start(req.params.name, function(data){
		if(!data){
			return res.json({status: 500, name: req.params.name, message: data});
		}else{
			res.json({});
		}
	});
});

router.get('/live/:template/:name', function(req, res, next){
	return lxc.startEphemeral(req.params.name, req.params.template, function (data) {
		console.log('live', arguments);
		return res.json(data);
	});
});

router.get('/stop/:name', function(req, res, next){
	return lxc.stop(req.params.name, function(data){
		console.log('stop', arguments);
		if(data){
			return res.json({status: 500, name: req.params.name, message: data});
		}else{
			return res.json({status: 200});
		}
	});
});

router.get('/clone/:template/:name', function(req, res, next){
	return lxc.clone(req.params.name, req.params.template, function(data){
		console.log('clone', arguments);
		if( data.match(/Created container/) ){
			return res.json({status: 200});
		}else{
			return res.json({status: 500, message: data});
		}
	});
});

router.get('/destroy/:name', function(req, res, next){
	return lxc.destroy(req.params.name, function(data){
		console.log('destroy', arguments);
		if(data){
			return res.json({status: 500, message: data});
		}else{
			return res.json({status: 200});
		}
	});
});

router.get('/info/:name', function(req, res, next){
	return lxc.info(req.params.name, function(data){
		return res.json(data);
	});
});

router.get('/list', function(req, res, next) {
	return lxc.list(function(data){
		return res.json(data);
	});
});

router.post('/run/:ip?', function doRun(req, res, next){
	// check if server is

	return lxc.list(function(data){
		if(!req.params.ip) data = [];
		var ip = '10.0.'+ req.params.ip;
		var found = false;

		for(var idx=data.length; idx--;){
			if( data[idx]['ipv4'] === ip ){
				found = true;
				break;
			}
		}

		if(found){
			return runner(req, res, ip)
		}else{
			var name = 'crunner-'+(Math.random()*100).toString().replace('.','');
			return lxc.startEphemeral(name, 'crunner', function(data){
				ip2name[data.ip] = name;
				return runner(req, res, data.ip);
			});
		}
	});

});

// freeMem: 97700 totalmem 513818624 usedMem: 0
// freeMem: 420,472 totalmem 513,818,624 usedMem: 100
var startAll = function(){
	getFreeMem(function(freeMem){
		var usedMemPercent = Math.round(( (totalMem-freeMem) /totalMem)*100);
		console.log('freeMem:', freeMem, 'totalmem', totalMem, 'usedMemPercent:', usedMemPercent);
		if(usedMemPercent < 81 ){
			var name = 'crunner-'+(Math.random()*100).toString().replace('.','');
			return lxc.startEphemeral(name, 'crunner', function(data){
				ip2name[data.ip] = name;
				availContainers.push(data.ip);
				return startAll();
			});
		}else{
			console.log('using', usedMemPercent, 'percent memory, stopping container creation!', availContainers.length, 'created');
		}
	});
}

startAll();

module.exports = router;
<commit_msg>load stuff<commit_after>'use strict';

var express = require('express');
var router = express.Router();
var extend = require('node.extend');
var redis = require("redis");
var client = redis.createClient();
var request = require('request');
var lxc = require('../lxc');
var os = require('os');
var spawn = require('child_process').spawn;

var totalMem = os.totalmem();
var timeoutEvents = {};
var ip2name = {};
var availContainers = [];
var usedContainers = [];

var getFreeMem = function(callback){

	var prc = spawn('free',  ['-b']);

	prc.stdout.setEncoding('utf8');
	prc.stdout.on('data', function (data) {
	  var str = data.toString()
	  var lines = str.split(/\n/g);
	  for(var i = 0; i < lines.length; i++) {
	     lines[i] = lines[i].split(/\s+/);
	  }
	  var freeMem = Number(lines[2][3]);
	  return callback(freeMem);
	});

	prc.on('close', function (code) {
	});
};

var lxcTimeout = function(ip, time){
	var name = ip2name[ip];
	console.log(name)
	time = time || 900000; // 15 minutes
	var keys = Object.keys(timeoutEvents)
	if(keys.indexOf(name) !== -1){
		clearTimeout(timeoutEvents[name])
	}
	timeoutEvents[name] = setTimeout(function(){
		lxc.stop(name);
	}, time);
}

var runner = function(req, res, ip){
	lxcTimeout(ip);

	var httpOptions = {
		url:'http://' + ip + ':15000',
		body: JSON.stringify({
			code: req.body.code
		})
	};

	return request.post(httpOptions, function(error, response, body){
		body = JSON.parse(body);
		body['ip'] = ip.replace('10.0.', '');
		return res.json(body);
	});
};

var addToRedis = function(){
	lxc.info(req.params.name, null, function(data){
			var domain = req.query.domain || 'vm42.us';
			domain = req.params.name+'.'+domain;
			client.SADD("hosts", domain, function(){});

			var ip = data.ip + ':5000';
			client.HSET(domain, "ip", ip, redis.print);
			client.HSET(domain, "updated", (new Date).getTime(), redis.print);
			client.hset(domain, "include", "proxy.include");
			return res.json({status: 200, info: data});
	 });
};

router.get('/start/:name', function(req, res, next){
	return lxc.start(req.params.name, function(data){
		if(!data){
			return res.json({status: 500, name: req.params.name, message: data});
		}else{
			res.json({});
		}
	});
});

router.get('/live/:template/:name', function(req, res, next){
	return lxc.startEphemeral(req.params.name, req.params.template, function (data) {
		console.log('live', arguments);
		return res.json(data);
	});
});

router.get('/stop/:name', function(req, res, next){
	return lxc.stop(req.params.name, function(data){
		console.log('stop', arguments);
		if(data){
			return res.json({status: 500, name: req.params.name, message: data});
		}else{
			return res.json({status: 200});
		}
	});
});

router.get('/clone/:template/:name', function(req, res, next){
	return lxc.clone(req.params.name, req.params.template, function(data){
		console.log('clone', arguments);
		if( data.match(/Created container/) ){
			return res.json({status: 200});
		}else{
			return res.json({status: 500, message: data});
		}
	});
});

router.get('/destroy/:name', function(req, res, next){
	return lxc.destroy(req.params.name, function(data){
		console.log('destroy', arguments);
		if(data){
			return res.json({status: 500, message: data});
		}else{
			return res.json({status: 200});
		}
	});
});

router.get('/info/:name', function(req, res, next){
	return lxc.info(req.params.name, function(data){
		return res.json(data);
	});
});

router.get('/list', function(req, res, next) {
	return lxc.list(function(data){
		return res.json(data);
	});
});

router.post('/run/:ip?', function doRun(req, res, next){
	// check if server is

	return lxc.list(function(data){
		if(!req.params.ip) data = [];
		var ip = '10.0.'+ req.params.ip;
		var found = false;

		for(var idx=data.length; idx--;){
			if( data[idx]['ipv4'] === ip ){
				found = true;
				break;
			}
		}

		if(found){
			return runner(req, res, ip)
		}else{
			return runner(req, res, availContainers.pop());
		}
	});

});

// freeMem: 97700 totalmem 513818624 usedMem: 0
// freeMem: 420,472 totalmem 513,818,624 usedMem: 100
var startAll = function(){
	getFreeMem(function(freeMem){
		var usedMemPercent = Math.round(( (totalMem-freeMem) /totalMem)*100);
		console.log('freeMem:', freeMem, 'totalmem', totalMem, 'usedMemPercent:', usedMemPercent);
		if(usedMemPercent < 81 ){
			var name = 'crunner-'+(Math.random()*100).toString().replace('.','');
			return lxc.startEphemeral(name, 'crunner', function(data){
				ip2name[data.ip] = name;
				availContainers.push(data.ip);
				return startAll();
			});
		}else{
			console.log('using', usedMemPercent, 'percent memory, stopping container creation!', availContainers.length, 'created');
		}
	});
}

startAll();

module.exports = router;
<|endoftext|>


<commit_before>/*! matchMedia() polyfill addListener/removeListener extension. Author & copyright (c) 2012: Scott Jehl. Dual MIT/BSD license */
(function(){
	// monkeypatch unsupported addListener/removeListener with polling
	if( !window.matchMedia( "all" ).addListener ){
		var oldMM = window.matchMedia;

		window.matchMedia = function( q ){
			var ret = oldMM( q ),
				listeners = [],
				last = ret.matches,
				timer,
				check = function(){
					var list = oldMM( q ),
						unmatchToMatch = list.matches && !last,
						matchToUnmatch = !list.matches && last;

                                        //fire callbacks only if transitioning to or from matched state
					if( unmatchToMatch || matchToUnmatch ){
						for( var i =0, il = listeners.length; i< il; i++ ){
							listeners[ i ].call( ret, list );
						}
					}
					last = list.matches;
				};

			ret.addListener = function( cb ){
				listeners.push( cb );
				if( !timer ){
					timer = setInterval( check, 1000 );
				}
			};

			ret.removeListener = function( cb ){
				for( var i =0, il = listeners.length; i< il; i++ ){
					if( listeners[ i ] === cb ){
						listeners.splice( i, 1 );
					}
				}
				if( !listeners.length && timer ){
					clearInterval( timer );
				}
			};

			return ret;
		};
	}
}());
<commit_msg>Rewrite of addListener to use window.resize rather than creating 'setInterval' for each media query using addListener.<commit_after>/*! matchMedia() polyfill addListener/removeListener extension. Author & copyright (c) 2012: Scott Jehl. Dual MIT/BSD license */
(function(){
    // monkeypatch unsupported addListener/removeListener
    if (window.matchMedia && !window.matchMedia('all').addListener){
        var localMatchMedia = window.matchMedia,
            hasMediaQueries = localMatchMedia('only all').matches,
            isListening     = false,
            timeoutID       = 0,    // setTimeout for debouncing 'handleChange'
            queries         = [],   // Contains each 'mql' and associated 'listeners' if 'addListener' is used
            handleChange    = function(evt) {
                // Debounce
                clearTimeout(timeoutID);

                timeoutID = setTimeout(function() {
                    for (var i = 0, il = queries.length; i < il; i++) {
                        var mql         = queries[i].mql,
                            listeners   = queries[i].listeners || [],
                            matches     = localMatchMedia(mql.media).matches;

                        // Update mql.matches value and call listeners
                        // Fire listeners only if transitioning to or from matched state
                        if (matches !== mql.matches) {
                            mql.matches = matches;

                            for (var j = 0, jl = listeners.length; j < jl; j++) {
                                listeners[j].call(window, mql);
                            }
                        }
                    }
                }, 30);
            };

        window.matchMedia = function(media) {
            var mql         = localMatchMedia(media),
                listeners   = [],
                id          = 0;

            mql.addListener = function(listener) {
                // Changes would not occur to css media type so return now (Affects IE <= 8)
                if (!hasMediaQueries) {
                    return;
                }

                // Set up 'resize' listener for browsers that support CSS3 media queries (Not for IE <= 8)
                // There should only ever be 1 resize listener running for performance
                if (!isListening) {
                    isListening = true;
                    window.addEventListener('resize', handleChange, true);
                }

                // Push object only if it has not been pushed already
                !id && (id = queries.push({
                    mql         : mql,
                    listeners   : listeners
                }));

                listeners.push(listener);
            };

            mql.removeListener = function(listener) {
                for (var i = 0, il = listeners.length; i < il; i++){
                    if (listeners[i] === listener){
                        listeners.splice(i, 1);
                    }
                }
            };

            return mql;
        };
    }
}());<|endoftext|>


<commit_before>var exec = require("cordova/exec");

/**
    attribute SpeechGrammarList grammars;
    attribute DOMString lang;
    attribute boolean continuous;
    attribute boolean interimResults;
    attribute unsigned long maxAlternatives;
    attribute DOMString serviceURI;
 */
var SpeechRecognition = function () {
    this.grammars = null;
    this.lang = "en";
    this.continuous = false;
    this.interimResults = false;
    this.maxAlternatives = 1;
    this.serviceURI = "";

    // event methods
    this.onaudiostart = null;
    this.onsoundstart = null;
    this.onspeechstart = null;
    this.onspeechend = null;
    this.onsoundend = null;
    this.onaudioend = null;
    this.onresult = null;
    this.onnomatch = null;
    this.onerror = null;
    this.onstart = null;
    this.onend = null;
};

SpeechRecognition.prototype.start = function() {
    exec(null, null, "SpeechRecognition", "start", []);
};

SpeechRecognition.prototype.stop = function() {
    exec(null, null, "SpeechRecognition", "stop", []);
};

SpeechRecognition.prototype.abort = function() {
    exec(null, null, "SpeechRecognition", "abort", []);
};

module.exports = SpeechRecognition;
<commit_msg>Add code to start speech rec engine when a SpeechRecognition object is created<commit_after>var exec = require("cordova/exec");

/**
    attribute SpeechGrammarList grammars;
    attribute DOMString lang;
    attribute boolean continuous;
    attribute boolean interimResults;
    attribute unsigned long maxAlternatives;
    attribute DOMString serviceURI;
 */
var SpeechRecognition = function () {
    this.grammars = null;
    this.lang = "en";
    this.continuous = false;
    this.interimResults = false;
    this.maxAlternatives = 1;
    this.serviceURI = "";

    // event methods
    this.onaudiostart = null;
    this.onsoundstart = null;
    this.onspeechstart = null;
    this.onspeechend = null;
    this.onsoundend = null;
    this.onaudioend = null;
    this.onresult = null;
    this.onnomatch = null;
    this.onerror = null;
    this.onstart = null;
    this.onend = null;

    exec(null, null, "SpeechRecognition", "init", []);
};

SpeechRecognition.prototype.start = function() {
    exec(null, null, "SpeechRecognition", "start", []);
};

SpeechRecognition.prototype.stop = function() {
    exec(null, null, "SpeechRecognition", "stop", []);
};

SpeechRecognition.prototype.abort = function() {
    exec(null, null, "SpeechRecognition", "abort", []);
};

module.exports = SpeechRecognition;
<|endoftext|>


<commit_before>'use strict';

const DIR = __dirname + '/../';
const DIR_TMPL = DIR + 'tmpl/';
const DIR_HTML = DIR + 'html/';
const DIR_COMMON = DIR + 'common/';
const DIR_JSON = DIR + 'json/';
const DIR_SERVER = './';
const DIR_FS = DIR_TMPL + 'fs/';

const fs = require('fs');

const flop = require('flop');
const ponse = require('ponse');
const files = require('files-io');
const rendy = require('rendy');
const exec = require('execon');
const minify = require('minify');
const format = require('format-io');
const squad = require('squad');
const apart = require('apart');

const config = require(DIR_SERVER + 'config');
const root = require(DIR_SERVER + 'root');
const prefixer = require(DIR_SERVER + 'prefixer');
const prefix = squad(prefixer, apart(config, 'prefix'));
const CloudFunc = require(DIR_COMMON + 'cloudfunc');

const PATH_INDEX = DIR_HTML + 'index.html';

const TMPL_PATH   = [
    'file',
    'panel',
    'path',
    'pathLink',
    'link'
];

const Template = {};
const FS = CloudFunc.FS;

const CSS_URL = require(DIR_JSON + 'css.json')
    .map((name) => {
        return 'css/' + name + '.css';
    }).join(':');

module.exports = (req, res, next) => {
    check(req, res, next);

    readFiles(() => {
        route(req, res, next);
    });
};

/**
 * additional processing of index file
 */
function indexProcessing(options) {
    let from;
    let to;
    let left = '';
    let right = '';
    const keysPanel = '<div id="js-keyspanel" class="{{ className }}';
    const isOnePanel = config('onePanelMode');
    const noConfig = !config('configDialog');
    const noConsole = !config('console');
    const panel = options.panel;

    let data = options.data;

    if (!config('showKeysPanel')) {
        from = rendy(keysPanel, {
            className: 'keyspanel'
        });

        to = rendy(keysPanel, {
            className: 'keyspanel hidden'
        });

        data = data.replace(from, to);
    }

    if (isOnePanel)
        data = data
            .replace('icon-move', 'icon-move none')
            .replace('icon-copy', 'icon-copy none');

    if (noConfig)
        data = data
             .replace('icon-config', 'icon-config none');

    if (noConsole)
        data = data
             .replace('icon-console', 'icon-console none');

    left = rendy(Template.panel, {
        side        : 'left',
        content     : panel,
        className   : !isOnePanel ? '' : 'panel-single'
    });

    if (!isOnePanel)
        right = rendy(Template.panel, {
            side        : 'right',
            content     : panel,
            className   : ''
        });

    data = rendy(data, {
        title: CloudFunc.getTitle(),
        fm: left + right,
        prefix: prefix(),
        css: CSS_URL
    });

    return data;
}

function readFiles(callback) {
    const paths = {};
    const lengthTmpl = Object.keys(Template).length;
    const lenthPath = TMPL_PATH.length;
    const isRead = lengthTmpl === lenthPath;

    if (typeof callback !== 'function')
        throw Error('callback should be a function!');

    if (isRead)
        return callback();

    const filesList = TMPL_PATH.map((name) => {
        const path = DIR_FS + name + '.hbs';

        paths[path] = name;

        return path;
    });

    files.read(filesList, 'utf8', (error, files) => {
        if (error)
            throw error;

        Object.keys(files).forEach((path) => {
            const name = paths[path];

            Template[name] = files[path];
        });

        callback();
    });
}

/**
 * routing of server queries
 */
function route(request, response, callback) {
    let name = ponse.getPathName(request);

    const isAuth = RegExp('^(/auth|/auth/github)$').test(name);
    const isFS = RegExp('^/$|^' + FS).test(name);
    const p = {
        request     : request,
        response    : response,
        gzip        : true,
        name        : name
    };

    if (!isAuth && !isFS)
        return callback();

    if (isAuth) {
        p.name = DIR_HTML + name + '.html';
        ponse.sendFile(p);
        return;
    }

    if (!isFS)
        return;

    name = name.replace(CloudFunc.FS, '') || '/';
    const fullPath = root(name);

    flop.read(fullPath, (error, dir) => {
        if (dir)
            dir.path = format.addSlashToEnd(name);

        if (!error)
            return buildIndex(dir, (error, data) => {
                p.name = PATH_INDEX;

                if (error)
                    return ponse.sendError(error, p);

                ponse.send(data, p);
            });

        if (error.code !== 'ENOTDIR')
            return ponse.sendError(error, p);

        fs.realpath(fullPath, (error, pathReal) => {
            if (!error)
                p.name = pathReal;
            else
                p.name = name;

            p.gzip = false;
            ponse.sendFile(p);
        });
    });
}

function buildIndex(json, callback) {
    const isMinify = config('minify');

    exec.if(!isMinify, (error, name) => {
        fs.readFile(name || PATH_INDEX, 'utf8', (error, template) => {
            if (error)
                return;

            const panel = CloudFunc.buildFromJSON({
                data        : json,
                prefix      : prefix(),
                template    : Template
            });

            const data = indexProcessing({
                panel   : panel,
                data    : template
            });

            callback(error, data);
        });
    },  (callback) => {
        minify(PATH_INDEX, 'name', callback);
    });
}

function check(req, res, next) {
    if (!req)
        throw Error('req could not be empty!');

    if (!res)
        throw Error('res could not be empty!');

    if (typeof next !== 'function')
        throw Error('next should be function!');
}

<commit_msg>chore(route) rm " "<commit_after>'use strict';

const DIR = __dirname + '/../';
const DIR_TMPL = DIR + 'tmpl/';
const DIR_HTML = DIR + 'html/';
const DIR_COMMON = DIR + 'common/';
const DIR_JSON = DIR + 'json/';
const DIR_SERVER = './';
const DIR_FS = DIR_TMPL + 'fs/';

const fs = require('fs');

const flop = require('flop');
const ponse = require('ponse');
const files = require('files-io');
const rendy = require('rendy');
const exec = require('execon');
const minify = require('minify');
const format = require('format-io');
const squad = require('squad');
const apart = require('apart');

const config = require(DIR_SERVER + 'config');
const root = require(DIR_SERVER + 'root');
const prefixer = require(DIR_SERVER + 'prefixer');
const prefix = squad(prefixer, apart(config, 'prefix'));
const CloudFunc = require(DIR_COMMON + 'cloudfunc');

const PATH_INDEX = DIR_HTML + 'index.html';

const TMPL_PATH   = [
    'file',
    'panel',
    'path',
    'pathLink',
    'link'
];

const Template = {};
const FS = CloudFunc.FS;

const CSS_URL = require(DIR_JSON + 'css.json')
    .map((name) => {
        return 'css/' + name + '.css';
    }).join(':');

module.exports = (req, res, next) => {
    check(req, res, next);

    readFiles(() => {
        route(req, res, next);
    });
};

/**
 * additional processing of index file
 */
function indexProcessing(options) {
    let from;
    let to;
    let left = '';
    let right = '';
    const keysPanel = '<div id="js-keyspanel" class="{{ className }}';
    const isOnePanel = config('onePanelMode');
    const noConfig = !config('configDialog');
    const noConsole = !config('console');
    const panel = options.panel;

    let data = options.data;

    if (!config('showKeysPanel')) {
        from = rendy(keysPanel, {
            className: 'keyspanel'
        });

        to = rendy(keysPanel, {
            className: 'keyspanel hidden'
        });

        data = data.replace(from, to);
    }

    if (isOnePanel)
        data = data
            .replace('icon-move', 'icon-move none')
            .replace('icon-copy', 'icon-copy none');

    if (noConfig)
        data = data
             .replace('icon-config', 'icon-config none');

    if (noConsole)
        data = data
             .replace('icon-console', 'icon-console none');

    left = rendy(Template.panel, {
        side        : 'left',
        content     : panel,
        className   : !isOnePanel ? '' : 'panel-single'
    });

    if (!isOnePanel)
        right = rendy(Template.panel, {
            side        : 'right',
            content     : panel,
            className   : ''
        });

    data = rendy(data, {
        title: CloudFunc.getTitle(),
        fm: left + right,
        prefix: prefix(),
        css: CSS_URL
    });

    return data;
}

function readFiles(callback) {
    const paths = {};
    const lengthTmpl = Object.keys(Template).length;
    const lenthPath = TMPL_PATH.length;
    const isRead = lengthTmpl === lenthPath;

    if (typeof callback !== 'function')
        throw Error('callback should be a function!');

    if (isRead)
        return callback();

    const filesList = TMPL_PATH.map((name) => {
        const path = DIR_FS + name + '.hbs';

        paths[path] = name;

        return path;
    });

    files.read(filesList, 'utf8', (error, files) => {
        if (error)
            throw error;

        Object.keys(files).forEach((path) => {
            const name = paths[path];

            Template[name] = files[path];
        });

        callback();
    });
}

/**
 * routing of server queries
 */
function route(request, response, callback) {
    let name = ponse.getPathName(request);

    const isAuth = RegExp('^(/auth|/auth/github)$').test(name);
    const isFS = RegExp('^/$|^' + FS).test(name);
    const p = {
        request     : request,
        response    : response,
        gzip        : true,
        name        : name
    };

    if (!isAuth && !isFS)
        return callback();

    if (isAuth) {
        p.name = DIR_HTML + name + '.html';
        ponse.sendFile(p);
        return;
    }

    if (!isFS)
        return;

    name = name.replace(CloudFunc.FS, '') || '/';
    const fullPath = root(name);

    flop.read(fullPath, (error, dir) => {
        if (dir)
            dir.path = format.addSlashToEnd(name);

        if (!error)
            return buildIndex(dir, (error, data) => {
                p.name = PATH_INDEX;

                if (error)
                    return ponse.sendError(error, p);

                ponse.send(data, p);
            });

        if (error.code !== 'ENOTDIR')
            return ponse.sendError(error, p);

        fs.realpath(fullPath, (error, pathReal) => {
            if (!error)
                p.name = pathReal;
            else
                p.name = name;

            p.gzip = false;
            ponse.sendFile(p);
        });
    });
}

function buildIndex(json, callback) {
    const isMinify = config('minify');

    exec.if(!isMinify, (error, name) => {
        fs.readFile(name || PATH_INDEX, 'utf8', (error, template) => {
            if (error)
                return;

            const panel = CloudFunc.buildFromJSON({
                data        : json,
                prefix      : prefix(),
                template    : Template
            });

            const data = indexProcessing({
                panel   : panel,
                data    : template
            });

            callback(error, data);
        });
    },  (callback) => {
        minify(PATH_INDEX, 'name', callback);
    });
}

function check(req, res, next) {
    if (!req)
        throw Error('req could not be empty!');

    if (!res)
        throw Error('res could not be empty!');

    if (typeof next !== 'function')
        throw Error('next should be function!');
}

<|endoftext|>


<commit_before>import { CODE_OK } from '../../common';
import { prihlaseniValid } from './prihlaseniReducer';

export const hideError = () => ({ type: 'PRIHLASENI_HIDE_ERROR' });

export const inputChanged = (name, event) => ({
  type: 'PRIHLASENI_INPUT_CHANGED',
  name,
  value: event.target.value
});

export const reset = () => ({
  type: 'PRIHLASENI_RESET'
});

const validateEmpty = () => ({ type: 'PRIHLASENI_VALIDATE_EMPTY' });

const validationError = () => ({
  type: 'PRIHLASENI_FORM_INVALID',
  code: 'nejde uložit',
  status: 'Přihláška nejde uložit. Povinná pole nejsou vyplněna.'
});

export const saveUcastRequest = () => ({
  type: 'PRIHLASENI_SAVE_REQUEST'
});

export const saveUcastSuccess = json => ({
  type: 'PRIHLASENI_SAVE_SUCCESS',
  receivedAt: Date.now()
});

export const saveUcastError = ({ code, status, err, ...rest }) => ({
  type: 'PRIHLASENI_SAVE_ERROR',
  code,
  status,
  err,
  ...rest,
  receivedAt: Date.now()
});

export const saveUcast = () => async (dispatch, getState, wsClient) => {
  await dispatch(validateEmpty());

  const { registrator: { prihlaseni } } = getState();
  if (!prihlaseniValid(prihlaseni)) {
    dispatch(validationError());
    return;
  }

  dispatch(saveUcastRequest());

  try {
    const response = await wsClient.sendRequest(
      saveUcast(prihlaseni.ucastnikId, prihlaseni.udaje, prihlaseni.prihlaska)
    );
    const { code } = response;
    if (code === CODE_OK) {
      dispatch(saveUcastSuccess(response));
    } else {
      dispatch(saveUcastError(response));
    }
  } catch (err) {
    dispatch(saveUcastError({ code: 'internal error', err }));
  }
};
<commit_msg>Fix call site of saveUcast() API endpoint.<commit_after>import { CODE_OK, saveUcast as saveUcastAction } from '../../common';
import { AKTUALNI_ROK } from '../../constants';
import { prihlaseniValid } from './prihlaseniReducer';

export const hideError = () => ({ type: 'PRIHLASENI_HIDE_ERROR' });

export const inputChanged = (name, event) => ({
  type: 'PRIHLASENI_INPUT_CHANGED',
  name,
  value: event.target.value
});

export const reset = () => ({
  type: 'PRIHLASENI_RESET'
});

const validateEmpty = () => ({ type: 'PRIHLASENI_VALIDATE_EMPTY' });

const validationError = () => ({
  type: 'PRIHLASENI_FORM_INVALID',
  code: 'nejde uložit',
  status: 'Přihláška nejde uložit. Povinná pole nejsou vyplněna.'
});

export const saveUcastRequest = () => ({
  type: 'PRIHLASENI_SAVE_REQUEST'
});

export const saveUcastSuccess = json => ({
  type: 'PRIHLASENI_SAVE_SUCCESS',
  receivedAt: Date.now()
});

export const saveUcastError = ({ code, status, err, ...rest }) => ({
  type: 'PRIHLASENI_SAVE_ERROR',
  code,
  status,
  err,
  ...rest,
  receivedAt: Date.now()
});

export const saveUcast = () => async (dispatch, getState, wsClient) => {
  await dispatch(validateEmpty());

  const state = getState();
  const { registrator: { prihlaseni } } = state;
  if (!prihlaseniValid(prihlaseni)) {
    dispatch(validationError());
    return;
  }

  dispatch(saveUcastRequest());

  try {
    const response = await wsClient.sendRequest(
      saveUcastAction(
        {
          id: prihlaseni.ucastnikId,
          rok: AKTUALNI_ROK,
          udaje: prihlaseni.udaje,
          prihlaska: prihlaseni.prihlaska
        },
        state.auth.token
      )
    );
    const { code } = response;
    if (code === CODE_OK) {
      dispatch(saveUcastSuccess(response));
    } else {
      dispatch(saveUcastError(response));
    }
  } catch (err) {
    dispatch(saveUcastError({ code: 'internal error', err }));
  }
};
<|endoftext|>


<commit_before>var User = require('../models/jobs_model');
var authController = require('../lib/auth');

module.exports = function(app, jwtauth) {
  app.post('/jobs', jwtauth, function(req, res) {
    var newJob = new Job({
      wakeUpTime: req.body.wakeUpTime,
      parent: req.body.parent,
      options: req.body.options,
      zipcode: req.body.zipcode,
      recurring: req.body.recurring,
      jobDate: req.body.jobDate
    });

    newJob.save(function(err, data) {
      if (err) return res.send(err);
      res.json(data);
    });
  });
  app.get('/jobs', jwtauth, function(req, res) {
    newJob.find({}, function(err, data) {
      if (err) return res.status(500).send(err);
      res.json(data);
    });
  });
};
<commit_msg>error fix >> beer<commit_after>var Job = require('../models/jobs_model');
var authController = require('../lib/auth');

module.exports = function(app, jwtauth) {
  app.post('/jobs', jwtauth, function(req, res) {
    var newJob = new Job({
      wakeUpTime: req.body.wakeUpTime,
      parent: req.body.parent,
      options: req.body.options,
      zipcode: req.body.zipcode,
      recurring: req.body.recurring,
      jobDate: req.body.jobDate
    });

    newJob.save(function(err, data) {
      if (err) return res.send(err);
      res.json(data);
    });
  });
  app.get('/jobs', jwtauth, function(req, res) {
    newJob.find({}, function(err, data) {
      if (err) return res.status(500).send(err);
      res.json(data);
    });
  });
};
<|endoftext|>


<commit_before>texts = [
	"The quick brown fox jumps over the lazy dog.",
	"Grumpy wizards make toxic brew for the evil queen and jack.",
	"Oak is strong and also gives shade.",
	"Cats and dogs each hate the other.",
	"The pipe began to rust while new.",
	"Open the crate but don't break the glass.",
	"Add the sum to the product of these three.",
	"Thieves who rob friends deserve jail.",
	"The ripe taste of cheese improves with age.",
	"Act on these orders with great speed.",
	"The hog crawled under the high fence.",
	"Move the vat over the hot fire.",

	"The sky above the port was the color of television, tuned to a dead channel.",
	"He who controls the past controls the future. He who controls the present controls the past.",

	"Whoever fights monsters should see to it that in the process he does not become a monster.",
	"He who has a why to live can bear almost any how.",
	"Anywhere can be paradise as long as you have the will to live.",
	"This convenient fabrication is your attempt to change reality.",
	"You can't bridge the gap between your own truth and the reality of others.",
	"In order to determine whether we can know anything with certainty, we first have to doubt everything we know.",
	"I think, therefore I am.",

	"You can’t cling to the past, because no matter how tightly you hold on, it’s already gone.",
	"Welcome to the real world. It sucks. You're gonna love it!",
	"I’m not so good with advice. Can I interest you in a sarcastic comment?",

	"SYSCALL_DEFINE1(brk, unsigned long, brk)"
];

// Select a random text
function getText() {
	let rand = Math.floor(Math.random() * texts.length);
	return texts[rand];
}

module.exports.texts = texts;
module.exports.getText = getText;
<commit_msg>Some quotes from HGTTG and Discworld<commit_after>texts = [
	"The quick brown fox jumps over the lazy dog.",
	"Grumpy wizards make toxic brew for the evil queen and jack.",
	"Oak is strong and also gives shade.",
	"Cats and dogs each hate the other.",
	"The pipe began to rust while new.",
	"Open the crate but don't break the glass.",
	"Add the sum to the product of these three.",
	"Thieves who rob friends deserve jail.",
	"The ripe taste of cheese improves with age.",
	"Act on these orders with great speed.",
	"The hog crawled under the high fence.",
	"Move the vat over the hot fire.",

	"The sky above the port was the color of television, tuned to a dead channel.",
	"He who controls the past controls the future. He who controls the present controls the past.",

	"Whoever fights monsters should see to it that in the process he does not become a monster.",
	"He who has a why to live can bear almost any how.",
	"Anywhere can be paradise as long as you have the will to live.",
	"This convenient fabrication is your attempt to change reality.",
	"You can't bridge the gap between your own truth and the reality of others.",
	"In order to determine whether we can know anything with certainty, we first have to doubt everything we know.",
	"I think, therefore I am.",

	"You can’t cling to the past, because no matter how tightly you hold on, it’s already gone.",
	"Welcome to the real world. It sucks. You're gonna love it!",
	"I’m not so good with advice. Can I interest you in a sarcastic comment?",
	"If there's anything more important than my ego around, I want it caught and shot now."
	"For a moment, nothing happened. Then, after a second or so, nothing continued to happen."
	"This planet has - or rather had - a problem, which was this: most of the people living on it were unhappy for pretty much of the time. Many solutions were suggested for this problem, but most of these were largely concerned with the movement of small green pieces of paper, which was odd because on the whole it wasn't the small green pieces of paper that were unhappy."
	"Anyone who is capable of getting themselves made President should on no account be allowed to do the job." //Mr Trump?
	"The pen is mightier than the sword if the sword is very short, and the pen is very sharp."
	"It would seem that you have no useful skill or talent whatsoever," he said. "Have you thought of going into teaching?"
	"If you ignore the rules, people will, half the time, quietly rewrite them so they don't apply to you."
	"Give a man a fire and he's warm for the day. But set fire to him and he's warm for the rest of his life."
	"There are, it has been said, two types of people in the world. There are those who, when presented with a glass that is exactly half full, say: this glass is half full. And then there are those who say: this glass is half empty. The world belongs, however, to those who can look at the glass and say: What's up with this glass? Excuse me? Excuse me? This is my glass? I don't think so. My glass was full! And it was a bigger glass!"
	"Thunder rolled. It rolled a six."
	"You have to start out learning to believe the little lies. "So we can believe the big ones?" Yes. Justice. Duty. Mercy. That sort of thing."

	"Take the universe and grind it down to the finest powder, and sieve it through the finest sieve, and then show me one atom of justice, one molecule of mercy. And yet, you try to act as if there is some ideal order in the world. As if there is some, some rightness in the universe, by which it may be judged."
	"Real stupidity beats artificial intelligence every time."
	"The trouble with having an open mind, of course, is that people will insist on coming along and trying to put things in it."

	"SYSCALL_DEFINE1(brk, unsigned long, brk)"
];

// Select a random text
function getText() {
	let rand = Math.floor(Math.random() * texts.length);
	return texts[rand];
}

module.exports.texts = texts;
module.exports.getText = getText;
<|endoftext|>


<commit_before>/* Compose - Render crypto "signature" of a message */
Mailpile.compose_render_signature = function(status) {
    if (status === 'sign') {
        $('.compose-crypto-signature').data('crypto_color', 'crypto-color-blue');
        $('.compose-crypto-signature').attr('title', $('.compose-crypto-signature').data('crypto_title_signed'));
        $('.compose-crypto-signature span.icon').removeClass('icon-signature-none').addClass('icon-signature-verified');
        $('.compose-crypto-signature span.text').html($('.compose-crypto-signature').data('crypto_signed'));
        $('.compose-crypto-signature').removeClass('none').addClass('signed bounce');

    } else if (status === 'none') {
        $('.compose-crypto-signature').data('crypto_color', 'crypto-color-gray');
        $('.compose-crypto-signature').attr('title', $('.compose-crypto-signature').data('crypto_title_not_signed'));
        $('.compose-crypto-signature span.icon').removeClass('icon-signature-verified').addClass('icon-signature-none');
        $('.compose-crypto-signature span.text').html($('.compose-crypto-signature').data('crypto_not_signed'));
        $('.compose-crypto-signature').removeClass('signed').addClass('none bounce');

    } else {
        $('.compose-crypto-signature').data('crypto_color', 'crypto-color-red');
        $('.compose-crypto-signature').attr('title', $('.compose-crypto-signature').data('crypto_title_signed_error'));
        $('.compose-crypto-signature span.icon').removeClass('icon-signature-none icon-signature-verified').addClass('icon-signature-error');
        $('.compose-crypto-signature span.text').html($('.compose-crypto-signature').data('crypto_signed_error'));
        $('.compose-crypto-signature').removeClass('none').addClass('error bounce');
    }

      // Set Form Value
    if ($('#compose-signature').val() !== status) {

        $('.compose-crypto-signature').addClass('bounce');
        $('#compose-signature').val(status);

        // Remove Animation
        setTimeout(function() {
          $('.compose-crypto-signature').removeClass('bounce');
        }, 1000);

        this.compose_set_crypto_state();
    }
};

/* Compose - Render crypto "encryption" of a message */
Mailpile.compose_render_encryption = function(status) {
    if (status == 'encrypt') {
        $('.compose-crypto-encryption').data('crypto_color', 'crypto-color-green');
        $('.compose-crypto-encryption').attr('title', $('.compose-crypto-encryption').data('crypto_title_encrypt'));
        $('.compose-crypto-encryption span.icon').removeClass('icon-lock-open').addClass('icon-lock-closed');
        $('.compose-crypto-encryption span.text').html($('.compose-crypto-encryption').data('crypto_encrypt'));
        $('.compose-crypto-encryption').removeClass('none error cannot').addClass('encrypted');

    } else if (status === 'cannot') {
        $('.compose-crypto-encryption').data('crypto_color', 'crypto-color-orange');
        $('.compose-crypto-encryption').attr('title', $('.compose-crypto-encryption').data('crypto_title_cannot_encrypt'));
        $('.compose-crypto-encryption span.icon').removeClass('icon-lock-closed').addClass('icon-lock-open');
        $('.compose-crypto-encryption span.text').html($('.compose-crypto-encryption').data('crypto_cannot_encrypt'));
        $('.compose-crypto-encryption').removeClass('none encrypted error').addClass('cannot');

    } else if (status === 'none') {
        $('.compose-crypto-encryption').data('crypto_color', 'crypto-color-gray');
        $('.compose-crypto-encryption').attr('title', $('.compose-crypto-encryption').data('crypto_title_none'));
        $('.compose-crypto-encryption span.icon').removeClass('icon-lock-closed').addClass('icon-lock-open');
        $('.compose-crypto-encryption span.text').html($('.compose-crypto-encryption').data('crypto_none'));
        $('.compose-crypto-encryption').removeClass('encrypted cannot error').addClass('none');

    } else {
        $('.compose-crypto-encryption').data('crypto_color', 'crypto-color-red');
        $('.compose-crypto-encryption').attr('title', $('.compose-crypto-encryption').data('crypto_title_encrypt_error'));
        $('.compose-crypto-encryption span.icon').removeClass('icon-lock-open icon-lock-closed').addClass('icon-lock-error');
        $('.compose-crypto-encryption span.text').html($('.compose-crypto-encryption').data('crypto_cannot_encrypt'));
        $('.compose-crypto-encryption').removeClass('encrypted cannot none').addClass('error');
    }

    // Set Form Value
    if ($('#compose-encryption').val() !== status) {

        $('.compose-crypto-encryption').addClass('bounce');
        $('#compose-encryption').val(status);

        // Remove Animation
        setTimeout(function() {
          $('.compose-crypto-encryption').removeClass('bounce');
        }, 1000);

        this.compose_set_crypto_state();
    }
};

/* Compose - Render adding new message to thread */
Mailpile.compose_render_message_thread = function(mid) {
  window.location.href = Mailpile.urls.message_sent + mid + "/";
  // FIXME: make this ajaxy and nice transitions and such
  // $('#form-compose-' + mid).slideUp().remove();
};<commit_msg>Make status icon less fluxy.<commit_after>/* Compose - Render crypto "signature" of a message */
Mailpile.compose_render_signature = function(status) {
    if (status === 'sign') {
        $('.compose-crypto-signature').data('crypto_color', 'crypto-color-blue');
        $('.compose-crypto-signature').attr('title', $('.compose-crypto-signature').data('crypto_title_signed'));
        $('.compose-crypto-signature span.icon').removeClass('icon-signature-none').addClass('icon-signature-verified');
        $('.compose-crypto-signature span.text').html($('.compose-crypto-signature').data('crypto_signed'));
        $('.compose-crypto-signature').removeClass('none').addClass('signed bounce');

    } else if (status === 'none') {
        $('.compose-crypto-signature').data('crypto_color', 'crypto-color-gray');
        $('.compose-crypto-signature').attr('title', $('.compose-crypto-signature').data('crypto_title_not_signed'));
        $('.compose-crypto-signature span.icon').removeClass('icon-signature-verified').addClass('icon-signature-none');
        $('.compose-crypto-signature span.text').html($('.compose-crypto-signature').data('crypto_not_signed'));
        $('.compose-crypto-signature').removeClass('signed').addClass('none bounce');

    } else {
        $('.compose-crypto-signature').data('crypto_color', 'crypto-color-red');
        $('.compose-crypto-signature').attr('title', $('.compose-crypto-signature').data('crypto_title_signed_error'));
        $('.compose-crypto-signature span.icon').removeClass('icon-signature-none icon-signature-verified').addClass('icon-signature-error');
        $('.compose-crypto-signature span.text').html($('.compose-crypto-signature').data('crypto_signed_error'));
        $('.compose-crypto-signature').removeClass('none').addClass('error bounce');
    }

      // Set Form Value
    if ($('#compose-signature').val() !== status) {

        $('.compose-crypto-signature').addClass('bounce');
        $('#compose-signature').val(status);

        // Remove Animation
        setTimeout(function() {
          $('.compose-crypto-signature').removeClass('bounce');
        }, 1000);

        this.compose_set_crypto_state();
    }
};

/* Compose - Render crypto "encryption" of a message */
Mailpile.compose_render_encryption = function(status) {
    console.log("Status: le " + status);
    if (status == 'encrypt') {
        $('.compose-crypto-encryption').data('crypto_color', 'crypto-color-green');
        $('.compose-crypto-encryption').attr('title', $('.compose-crypto-encryption').data('crypto_title_encrypt'));
        $('.compose-crypto-encryption span.icon').removeClass('icon-lock-open').addClass('icon-lock-closed');
        $('.compose-crypto-encryption span.text').html($('.compose-crypto-encryption').data('crypto_encrypt'));
        $('.compose-crypto-encryption').removeClass('none error cannot').addClass('encrypted');

    } else if (status === 'cannot') {
        $('.compose-crypto-encryption').data('crypto_color', 'crypto-color-orange');
        $('.compose-crypto-encryption').attr('title', $('.compose-crypto-encryption').data('crypto_title_cannot_encrypt'));
        $('.compose-crypto-encryption span.icon').removeClass('icon-lock-closed').addClass('icon-lock-open');
        $('.compose-crypto-encryption span.text').html($('.compose-crypto-encryption').data('crypto_cannot_encrypt'));
        $('.compose-crypto-encryption').removeClass('none encrypted error').addClass('cannot');

    } else if (status === 'none' || status == '') {
        $('.compose-crypto-encryption').data('crypto_color', 'crypto-color-gray');
        $('.compose-crypto-encryption').attr('title', $('.compose-crypto-encryption').data('crypto_title_none'));
        $('.compose-crypto-encryption span.icon').removeClass('icon-lock-closed').addClass('icon-lock-open');
        $('.compose-crypto-encryption span.text').html($('.compose-crypto-encryption').data('crypto_none'));
        $('.compose-crypto-encryption').removeClass('encrypted cannot error').addClass('none');

    } else {
        $('.compose-crypto-encryption').data('crypto_color', 'crypto-color-red');
        $('.compose-crypto-encryption').attr('title', $('.compose-crypto-encryption').data('crypto_title_encrypt_error'));
        $('.compose-crypto-encryption span.icon').removeClass('icon-lock-open icon-lock-closed').addClass('icon-lock-error');
        $('.compose-crypto-encryption span.text').html($('.compose-crypto-encryption').data('crypto_cannot_encrypt'));
        $('.compose-crypto-encryption').removeClass('encrypted cannot none').addClass('error');
    }

    // Set Form Value
    if ($('#compose-encryption').val() !== status) {

        $('.compose-crypto-encryption').addClass('bounce');
        $('#compose-encryption').val(status);

        // Remove Animation
        setTimeout(function() {
          $('.compose-crypto-encryption').removeClass('bounce');
        }, 1000);

        this.compose_set_crypto_state();
    }
};

/* Compose - Render adding new message to thread */
Mailpile.compose_render_message_thread = function(mid) {
  window.location.href = Mailpile.urls.message_sent + mid + "/";
  // FIXME: make this ajaxy and nice transitions and such
  // $('#form-compose-' + mid).slideUp().remove();
};<|endoftext|>


<commit_before>const express = require('express')
const router = express.Router()

const apiCache = require('./../server/ApiCache')

/* GET api listing. */
router.get('/getForecastWeather/:city', async function(req, res, next) {
  try {
    let response = await apiCache.getInstance().getCachedForecastWeather(req.params, req.app.get('apiAccessor'))
    res.send(response)
  } catch (e) {
    next(e)
  }
})

router.get('/getCurrentWeather/:city', async function(req, res, next) {
  try {
    let response = await apiCache.getInstance().getCachedCurrentWeather(req.params, req.app.get('apiAccessor'))
    res.send(response)
  } catch (e) {
    next(e)
  }
})

router.get('/search/:input', (req, res, next) => {
  let cityNames = Object.keys(apiCache.getInstance().getNamesCache())
  let filteredCities = cityNames.filter((e) => {
    return e.indexOf(req.params.input) >= 0
  })

  res.send(filteredCities)
})

module.exports = router
<commit_msg>Revert "heroku update"<commit_after>const express = require('express')
const router = express.Router()

const apiCache = require('./../server/ApiCache')

/* GET api listing. */
router.get('/getForecastWeather/:city', async (req, res, next) => {
  try {
    let response = await apiCache.getInstance().getCachedForecastWeather(req.params, req.app.get('apiAccessor'))
    res.send(response)
  } catch (e) {
    next(e)
  }
})

router.get('/getCurrentWeather/:city', async (req, res, next) => {
  try {
    let response = await apiCache.getInstance().getCachedCurrentWeather(req.params, req.app.get('apiAccessor'))
    res.send(response)
  } catch (e) {
    next(e)
  }
})

router.get('/search/:input', (req, res, next) => {
  let cityNames = Object.keys(apiCache.getInstance().getNamesCache())
  let filteredCities = cityNames.filter((e) => {
    return e.indexOf(req.params.input) >= 0
  })

  res.send(filteredCities)
})

module.exports = router
<|endoftext|>


<commit_before>import {esc} from 'db/models';

const emailRegex = /^([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22))*\x40([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d))*$/;

function getRemoteIp(req) {
    const remote_address = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
    const ip_match = remote_address ? remote_address.match(/(\d+\.\d+\.\d+\.\d+)/) : null;
    return ip_match ? ip_match[1] : esc(remote_address);
}

var ip_last_hit = new Map();
function rateLimitReq(ctx, req) {
    const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
    const now = Date.now()

    // purge hits older than minutes_max
    ip_last_hit.forEach((v, k) => {
        const seconds = (now - v) / 1000;
        if (seconds > 1) {
            ip_last_hit.delete(ip)
        }
    })

    let result = false;
    // if ip is still in the map, abort
    if (ip_last_hit.has(ip)) {
        // console.log(`api rate limited for ${ip}: ${req}`);
        // throw new Error(`Rate limit reached: one call per ${minutes_max} minutes allowed.`);
        console.error(`Rate limit reached: one call per 1 second allowed.`);
        ctx.status = 429;
        ctx.body = 'Too Many Requests';
        result = true;
    }

    // record api hit
    ip_last_hit.set(ip, now);
    return result;
}

function checkCSRF(ctx, csrf) {
    try { ctx.assertCSRF(csrf); } catch (e) {
        ctx.status = 403;
        ctx.body = 'invalid csrf token';
        console.log('-- invalid csrf token -->', ctx.request.method, ctx.request.url, ctx.session.uid);
        return false;
    }
    return true;
}

module.exports = {
    emailRegex,
    getRemoteIp,
    rateLimitReq,
    checkCSRF
};
<commit_msg>Set rate req limit to 0.5 seconds<commit_after>import {esc} from 'db/models';

const emailRegex = /^([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22))*\x40([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d))*$/;

function getRemoteIp(req) {
    const remote_address = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
    const ip_match = remote_address ? remote_address.match(/(\d+\.\d+\.\d+\.\d+)/) : null;
    return ip_match ? ip_match[1] : esc(remote_address);
}

var ip_last_hit = new Map();
function rateLimitReq(ctx, req) {
    const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
    const now = Date.now()

    // purge hits older than minutes_max
    ip_last_hit.forEach((v, k) => {
        const seconds = (now - v) / 1000;
        if (seconds > 0.5) {
            ip_last_hit.delete(ip)
        }
    })

    let result = false;
    // if ip is still in the map, abort
    if (ip_last_hit.has(ip)) {
        // console.log(`api rate limited for ${ip}: ${req}`);
        // throw new Error(`Rate limit reached: one call per ${minutes_max} minutes allowed.`);
        console.error(`Rate limit reached: one call per 0.5 second allowed.`);
        ctx.status = 429;
        ctx.body = 'Too Many Requests';
        result = true;
    }

    // record api hit
    ip_last_hit.set(ip, now);
    return result;
}

function checkCSRF(ctx, csrf) {
    try { ctx.assertCSRF(csrf); } catch (e) {
        ctx.status = 403;
        ctx.body = 'invalid csrf token';
        console.log('-- invalid csrf token -->', ctx.request.method, ctx.request.url, ctx.session.uid);
        return false;
    }
    return true;
}

module.exports = {
    emailRegex,
    getRemoteIp,
    rateLimitReq,
    checkCSRF
};
<|endoftext|>