<commit_before>Cell = function(str_index, str){
  this.id = parseInt(str_index);
  this.str = str;
  this.column = parseInt(str_index) % 7;
  this.row = Math.floor(parseInt(str_index) / 7);
};

Cell.prototype = function(){
};

// Cell.prototype.get_row = function(){
// };

// Cell.prototype.get_column = function(){
// };
Board = function(board_string){
  this.board = [];
  for (var i = 0; i < board_string.length; i++) {
    str = board_string[i];
    this.board.push(new Cell(i, str));
  }
};

Board.prototype.getColumn = function(column) {
  this.columnArray = [];
  for(i=41; i >= 0; i--) {
    if (this.board[i].column === column) {
      this.columnArray.push(this.board[i]);
    }
  }
};

var countUp = 0;
Board.prototype.columnDrop = function(playerLetter) {
  if (this.columnArray[countUp].str !== playerLetter) {
    this.columnArray[countUp].str = playerLetter;
    countUp = 0;
  }
  else if (this.columnArray[countUp].str === playerLetter) {
    countUp++;
    this.columnDrop();
  }
};

// Board.prototype.play = function(player, cell){
//   // On board cell "cell" (so 5th cell), for player 1
//   // Change .str property from "-" to "goblin"
// };

// Board.prototype.play = function(player, cell){
//   debugger
// };

// Board.prototype.nextAvailable = function(column) {
//   for (var i = 0; i < board.length; i++) {

//   }
// };

game = new Board("------------------------------------------");
// game.nextAvailable(5);
// game.play(1, 5)
// game.play(2, 6)
// game.player1(0)
game.getColumn(0);
game.columnDrop();
game.columnDrop();
game.columnDrop();
game.getColumn(1);
game.columnDrop();
game.columnDrop();
game.columnDrop();
// game.player2

// class Guess
//   include Navigation, SolvingLogic
//   attr_reader :valid, :board
//   def initialize(board_string)
//     @valid = true
//     @board = board_string.each_char.with_index.map { |char, index| Cell.new(index, char.to_i) }
//     solve
//   end

// Tree = function() {

//   FRUIT_BEARING_AGE = 5;
//   MAX_AGE = 50;

//   this.age = 0;
//   this.height = 0;
//   this.orangeCount = 0;
//   this.isAlive = true;
// };

// Tree.prototype.grow = function() {
//   this.orangeCount = 0;
//   this.age ++;
//   this.height += 10;

//   if (this.age >= FRUIT_BEARING_AGE){
//     this.orangeCount += Math.floor((Math.random() * 50) + 1);
//   };

//   if (this.age > MAX_AGE) {
//     this.isAlive = false;
//   };
// };

// Tree.prototype.dropOrange = function() {
//   this.orangeCount--;
//   return new Orange;
// };

// Tree.prototype.pickOrange = function() {
//   this.orangeCount--;
//   return new Orange;
// };

// Orange = function() {
//   this.diameter = Math.floor((Math.random() * 6) + 1);
// };
<commit_msg>first commit<commit_after>Cell = function(str_index, str){
  this.id = parseInt(str_index);
  this.str = str;
  this.column = parseInt(str_index) % 7;
  this.row = Math.floor(parseInt(str_index) / 7);
};

Cell.prototype = function(){
};

// Cell.prototype.get_row = function(){
// };

// Cell.prototype.get_column = function(){
// };
Board = function(board_string){
  this.board = [];
  for (var i = 0; i < board_string.length; i++) {
    str = board_string[i];
    this.board.push(new Cell(i, str));
  }
};

Board.prototype.getColumn = function(column) {
  this.columnArray = [];
  for(i=41; i >= 0; i--) {
    if (this.board[i].column === column) {
      this.columnArray.push(this.board[i]);
    }
  }
  this.columnDrop();
};

Board.prototype.countUp = 0;

Board.prototype.columnDrop = function() {
  if (this.columnArray[this.countUp].str !== "x") {
    this.columnArray[this.countUp].str = "x";
    this.countUp = 0;
  }
  else if (this.columnArray[this.countUp].str === "x") {
    this.countUp++;
    this.columnDrop();
  }
};

Board.prototype.to_s = function(){
  for (var i = 0; i < this.board.length; i++) {
    for (var y = 0; y < 6; y++) {
      console.log(this.board[i].str)
    }
    console.log("\n")
    // console.log("String: " + this.board[i].str);
    // console.log("Column: " + this.board[i].column)
    // console.log("Row: " + this.board[i].row)
  }
}

// Board.prototype.play = function(player, cell){
//   // On board cell "cell" (so 5th cell), for player 1
//   // Change .str property from "-" to "goblin"
// };

// Board.prototype.play = function(player, cell){
//   debugger
// };

// Board.prototype.nextAvailable = function(column) {
//   for (var i = 0; i < board.length; i++) {

//   }
// };

game = new Board("------------------------------------------");
// game.nextAvailable(5);
// game.play(1, 5)
// game.play(2, 6)
// game.player1(0)
game.getColumn(0);
game.getColumn(1);
// game.to_s();

console.log("-") console.log("-")

// game.player2

// class Guess
//   include Navigation, SolvingLogic
//   attr_reader :valid, :board
//   def initialize(board_string)
//     @valid = true
//     @board = board_string.each_char.with_index.map { |char, index| Cell.new(index, char.to_i) }
//     solve
//   end

// Tree = function() {

//   FRUIT_BEARING_AGE = 5;
//   MAX_AGE = 50;

//   this.age = 0;
//   this.height = 0;
//   this.orangeCount = 0;
//   this.isAlive = true;
// };

// Tree.prototype.grow = function() {
//   this.orangeCount = 0;
//   this.age ++;
//   this.height += 10;

//   if (this.age >= FRUIT_BEARING_AGE){
//     this.orangeCount += Math.floor((Math.random() * 50) + 1);
//   };

//   if (this.age > MAX_AGE) {
//     this.isAlive = false;
//   };
// };

// Tree.prototype.dropOrange = function() {
//   this.orangeCount--;
//   return new Orange;
// };

// Tree.prototype.pickOrange = function() {
//   this.orangeCount--;
//   return new Orange;
// };

// Orange = function() {
//   this.diameter = Math.floor((Math.random() * 6) + 1);
// };
<|endoftext|>


<commit_before>var express = require('express'),
    app = express(),
    request = require('request');

app.locals.pretty = true;

app.use(express.favicon());
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.static(__dirname + '/public'));

app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function(){
  app.use(express.errorHandler());
});

app.post('/', function(req, res, next){
    var jsonStr = req.body.data,
        js = JSON.parse(jsonStr),
        deps = js.dependencies;

    res.render('home', {ctx:'root',deps:deps});

});

app.get('/', function(req, res){
    res.render('home',{ctx:'root', deps:[]});
});

app.get('/npm/:name', function(req, res){
    var name = req.params.name;
    res.render('npm',{ctx:'package', name:name});
});

// /history?name=underscore
app.get('/history', function(req,res){

    var name = req.query.name;

    request('http://registry.npmjs.org/' + name, function(err, resp, body){
        if(err) return next(err);

        var json = JSON.parse(body);
        res.send(json.time);
    });
});

var server = app.listen(3000);
console.log('Express server started on port %s', server.address().port);
<commit_msg>maintain form data between posts<commit_after>var express = require('express'),
    app = express(),
    request = require('request');

app.locals.pretty = true;

app.use(express.favicon());
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.static(__dirname + '/public'));

app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function(){
  app.use(express.errorHandler());
});

app.locals.ctx = 'root';
app.locals.data = '';

app.post('/', function(req, res, next){
    var jsonStr = req.body.data,
        js = JSON.parse(jsonStr),
        deps = js.dependencies;

    res.locals.data = jsonStr;

    res.render('home', {deps:deps});

});

app.get('/', function(req, res){
    res.render('home',{deps:[]});
});

app.get('/npm/:name', function(req, res){
    var name = req.params.name;
    res.locals.ctx = 'package';
    res.render('npm',{name:name});
});

// /history?name=underscore
app.get('/history', function(req,res){

    var name = req.query.name;

    request('http://registry.npmjs.org/' + name, function(err, resp, body){
        if(err) return next(err);

        var json = JSON.parse(body);
        res.send(json.time);
    });
});

var server = app.listen(3000);
console.log('Express server started on port %s', server.address().port);
<|endoftext|>


<commit_before>'use strict';

const pg = require('pg');
const express = require('express');
const bodyParser = require('body-parser');
require('dotenv').config()
// const requestProxy = require('express-request-proxy');
const superagent = require('superagent');
require('handlebars');
const PORT = process.env.PORT || 3000;
const app = express();

const conString = process.env.DATABASE_URL;
const client = new pg.Client(conString);
client.connect();
client.on('error', err => console.error(err));

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static('./public'));

app.get('/bigoven/:text/:category', (request, response) => {
  superagent
    .get(`https://api2.bigoven.com/recipes?any_kw=${request.params.text}&include_primarycat=${request.params.category}&rpp=20&api_key=${process.env.API_KEY}`)
    .end((err, superagentResponse) => {
      response.send(superagentResponse.body);
    });
});

app.get('/bigoven/:recipeId', (request,response) => {
  superagent
    .get(`https://api2.bigoven.com/recipe/${request.params.recipeId}?api_key=${process.env.API_KEY}`)
    .end((err,superagentResponse) => {
      response.send(superagentResponse.body);
    });
});

app.get('/login', (request, response) => {
  let sql = `SELECT * FROM users WHERE username = $1 AND password = $2`

  client.query(sql, request.query.userCheck)
    .then(result => response.send(result.rows[0]))
    .catch(console.error);
})

app.get('/myRecipes', (request, response) => {
  var numUserId = Number(request.query.userId);
  console.log('this is the request body', numUserId);
  let sql = 'SELECT recipe_id, title, photo_url FROM recipes INNER JOIN normalize ON recipes.recipe_id = normalize.recipe_id WHERE user_id = $1;'
  client.query(sql, [numUserId])
    .then(result => response.send(result.rows))
    .catch(console.error);
})

app.post('/addUser', (request, response) => {
  console.log('request:', request.query.userName);
  // let sql =
})

app.post('/myRecipes', (request, response) => {
  // i'm adding a recipe to the recipe table
  var numRecipeId = Number(request.body.recipeId);
  var numUserId = Number(request.body.userId);
  console.log('this is the request body', numRecipeId, numUserId, request.body.recipeTitle, request.body.recipePhotoUrl);
  let sql = 'INSERT INTO recipes(recipe_id, title, photo_url) VALUES($1, $2, $3)'

  client.query(sql, [numRecipeId, request.body.recipeTitle, request.body.PhotoUrl], function(err){
    if (err) {
      console.log('error:', err);
    } else {
      let normalSql = 'INSERT INTO normalize(recipe_id, user_id) VALUES($1, $2)'

      client.query(normalSql, [numRecipeId, numUserId],
        function (err) {
          if (err) {
            console.log('error:', err);
          } else {
            response.send('ok');
          }
        })

    }
  })
})

app.get('*', (request, response) => response.sendFile('index.html', {root: './public'}));
app.listen(PORT, () => console.log(`server started on port ${PORT}!`));
<commit_msg>same as before<commit_after>'use strict';

const pg = require('pg');
const express = require('express');
const bodyParser = require('body-parser');
require('dotenv').config()
// const requestProxy = require('express-request-proxy');
const superagent = require('superagent');
require('handlebars');
const PORT = process.env.PORT || 3000;
const app = express();

const conString = process.env.DATABASE_URL;
const client = new pg.Client(conString);
client.connect();
client.on('error', err => console.error(err));

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static('./public'));

app.get('/bigoven/:text/:category', (request, response) => {
  superagent
    .get(`https://api2.bigoven.com/recipes?any_kw=${request.params.text}&include_primarycat=${request.params.category}&rpp=20&api_key=${process.env.API_KEY}`)
    .end((err, superagentResponse) => {
      response.send(superagentResponse.body);
    });
});

app.get('/bigoven/:recipeId', (request,response) => {
  superagent
    .get(`https://api2.bigoven.com/recipe/${request.params.recipeId}?api_key=${process.env.API_KEY}`)
    .end((err,superagentResponse) => {
      response.send(superagentResponse.body);
    });
});

app.get('/login', (request, response) => {
  let sql = `SELECT * FROM users WHERE username = $1 AND password = $2`

  client.query(sql, request.query.userCheck)
    .then(result => response.send(result.rows[0]))
    .catch(console.error);
})

app.get('/myRecipes', (request, response) => {
  var numUserId = Number(request.query.userId);
  console.log('this is the request body', numUserId);
  let sql = 'SELECT recipes.recipe_id, recipes.title, recipes.photo_url FROM recipes INNER JOIN normalize ON recipes.recipe_id = normalize.recipe_id WHERE user_id = $1;'
  client.query(sql, [numUserId])
    .then(result => response.send(result.rows))
    .catch(console.error);
})

app.post('/addUser', (request, response) => {
  console.log('request:', request.query.userName);
  // let sql =
})

app.post('/myRecipes', (request, response) => {
  // i'm adding a recipe to the recipe table
  var numRecipeId = Number(request.body.recipeId);
  var numUserId = Number(request.body.userId);
  console.log('this is the request body', numRecipeId, numUserId, request.body.recipeTitle, request.body.recipePhotoUrl);
  let sql = 'INSERT INTO recipes(recipe_id, title, photo_url) VALUES($1, $2, $3)'

  client.query(sql, [numRecipeId, request.body.recipeTitle, request.body.PhotoUrl], function(err){
    if (err) {
      console.log('error:', err);
    } else {
      let normalSql = 'INSERT INTO normalize(recipe_id, user_id) VALUES($1, $2)'

      client.query(normalSql, [numRecipeId, numUserId],
        function (err) {
          if (err) {
            console.log('error:', err);
          } else {
            response.send('ok');
          }
        })

    }
  })
})

app.get('*', (request, response) => response.sendFile('index.html', {root: './public'}));
app.listen(PORT, () => console.log(`server started on port ${PORT}!`));
<|endoftext|>


<commit_before>const MongoClient = require('mongodb').MongoClient
const objectID = require('mongodb').ObjectID
const express = require('express')
const path = require('path')
const bodyParser = require('body-parser')
const mqtt = require('mqtt').connect('mqtt://broker')
const chalk = require('chalk')
const moment = require('moment')
const basicAuth = require('basic-auth')
const app = express()
let http = require('http').Server(app)
let io = require('socket.io')(http)

let auth = (req, res, next) => {
  let user = basicAuth(req)
  if (!user || !user.name || !user.pass) {
    res.set('WWW-Authenticate', 'Basic realm=Authorization Required')
    res.sendStatus(401)
  }
  if (user.name === 'handsofblue67' && user.pass === '@basicAuth') {
    next();
  } else {
    res.set('WWW-Authenticate', 'Basic realm=Authorization Required')
    res.sendStatus(401)
  }
}

mqtt.on('connect', () => {
  mqtt.subscribe('/status/#')
  mqtt.subscribe('/currentSettings/#')

  MongoClient.connect('mongodb://db', (err, db) => {
    if (err) console.error('error connecting to mongodb ' + err)

    io.on('connection', socket => {
      console.log('user connected')

      // on web client disconnect
      socket.on('disconnect', () => console.log('user disconnected'))

      // on toggle from web client
      socket.on('toggle', pub => mqtt.publish(pub.topic, pub.message))

      mqtt.on('message', (topic, message) => {
        message = JSON.parse(message.toString())
        // message is a device defintion or a devices status report
        topicRegExp = new RegExp(/currentSettings\/.*/)
        console.log(topic)
        topicRegExp.test(topic) ? updateDevice(message) : addStatus(message)
      })

      // each device and its current settings (one document per device)
      let updateDevice = device => {
        db.collection('devices')
          .updateOne({ 'deviceID': device.deviceID }, { $set: device }, { upsert: true })
      }

      // inputs usually append a document, outputs usually update a single document (its current state)
      let addStatus = status => {
        db.collection('devices').findOne({ 'deviceID': status.deviceID }, (err, result) => {
          switch (result.primaryType) {
            case 'digitalOutput':
              db.collection('statuses')
                .updateOne({ 'deviceID': status.deviceID }, { $set: status }, { upsert: true }, () => {
                  io.emit('stateChange', { type: 'state', status: status })
                })
              break
            case 'digitalInput':
              db.collection('statuses').insertOne(status, () => {
                io.emit('digitalInputChange', { type: 'state', status: status })
              })
              break
            case 'analogOutput':
              db.collection('statuses')
                .updateOne({ 'deviceID': status.deviceID }, { $set: status }, { upsert: true }, () => {
                  io.emit('analogStateChange', { type: 'state', status: status })
              })
            case 'analogInput':
              db.collection('statuses').insertOne(status, () => {
                io.emit('analogInputChange', { type: 'state', status: status })
              })
              break
          }
        })
      }
    })

    app.use(bodyParser.json())
      .use(bodyParser.urlencoded({ extended: true }))
      .use(require('morgan')('dev'))
      .use(express.static(path.join(__dirname, 'dist')))
      .use('/lights', express.static(path.join(__dirname, 'dist')))
      .use('/maps', express.static(path.join(__dirname, 'dist')))
      .use('/charts', express.static(path.join(__dirname, 'dist')))

      .get('/api/devices/:type', (req, res) => {
        db.collection('devices')
          .find({ 'primaryType': req.params.type })
          .toArray((err, docs) => {
            if (err) console.log(err)
            res.send(docs)
          })
      })

      .get('/api/devices', (req, res) => {
        db.collection('devices')
          .find({}).toArray((err, docs) => {
            res.send(docs)
          })
      })

      .get('/api/statuses/:deviceID', (req, res) => {
        db.collection('statuses')
          .find({ 'deviceID': +req.params.deviceID })
          .toArray((err, docs) => {
            if (err) console.log(err)
            res.send(docs)
          })
      })

      .post('/api/publish', (req, res) => {
        mqtt.publish(`${req.body.topic}`, req.body.message)
        res.status(200).send('message published')
      })

      .delete('/api/statuses/:id', (req, res) => {
        db.collection('statuses')
          .deleteOne({ _id: new objectID(req.params.id) }, (err, result) => {
            if (err) console.log(err)
            res.send(result)
          })
      })

      .get('/api/broker', (req, res) => {
        res.send('mqtt//broker')
      })

      .get('/api/geofence', (req, res) => {
        db.collection('geofence')
          .distinct('device', (err, result) => {
            if (err) console.log(err)
            res.send(result)
          })
      })

      .post('/api/geofence', auth, (req, res) => {
        console.log(req.body)
        db.collection('geofence').insertOne(req.body)
        res.status(200).send('geofence event saved')
      })

      .get('/api/geofence/:device', (req, res) => {
        const start = moment().startOf('day')
        const end = moment().endOf('day')
        db.collection('geofence')
          //.find({'device':req.params.device,'timestamp':{$gte:start,$lt:end}})
          .find({ 'device': req.params.device })
          .sort({ 'timestamp': -1 })
          .limit(2)
          .toArray((err, docs) => {
            if (err) console.log(err)
            res.send(docs)
          })
      })
    // app.listen(3000)
    http.listen(3000)
  })

})

// module.exports = app;<commit_msg>implemented aggregate, but doesn't seem to be doing much<commit_after>const MongoClient = require('mongodb').MongoClient
const objectID = require('mongodb').ObjectID
const express = require('express')
const path = require('path')
const bodyParser = require('body-parser')
const mqtt = require('mqtt').connect('mqtt://broker')
const chalk = require('chalk')
const moment = require('moment')
const basicAuth = require('basic-auth')
const app = express()
let http = require('http').Server(app)
let io = require('socket.io')(http)

let auth = (req, res, next) => {
  let user = basicAuth(req)
  if (!user || !user.name || !user.pass) {
    res.set('WWW-Authenticate', 'Basic realm=Authorization Required')
    res.sendStatus(401)
  }
  if (user.name === 'handsofblue67' && user.pass === '@basicAuth') {
    next();
  } else {
    res.set('WWW-Authenticate', 'Basic realm=Authorization Required')
    res.sendStatus(401)
  }
}

mqtt.on('connect', () => {
  mqtt.subscribe('/status/#')
  mqtt.subscribe('/currentSettings/#')

  MongoClient.connect('mongodb://db', (err, db) => {
    if (err) console.error('error connecting to mongodb ' + err)

    io.on('connection', socket => {
      console.log('user connected')

      // on web client disconnect
      socket.on('disconnect', () => console.log('user disconnected'))

      // on toggle from web client
      socket.on('toggle', pub => mqtt.publish(pub.topic, pub.message))

      mqtt.on('message', (topic, message) => {
        message = JSON.parse(message.toString())
        // message is a device defintion or a devices status report
        topicRegExp = new RegExp(/currentSettings\/.*/)
        console.log(topic)
        topicRegExp.test(topic) ? updateDevice(message) : addStatus(message)
      })

      // each device and its current settings (one document per device)
      let updateDevice = device => {
        db.collection('devices')
          .updateOne({ 'deviceID': device.deviceID }, { $set: device }, { upsert: true })
      }

      // inputs usually append a document, outputs usually update a single document (its current state)
      let addStatus = status => {
        db.collection('devices').findOne({ 'deviceID': status.deviceID }, (err, result) => {
          switch (result.primaryType) {
            case 'digitalOutput':
              db.collection('statuses')
                .updateOne({ 'deviceID': status.deviceID }, { $set: status }, { upsert: true }, () => {
                  io.emit('stateChange', { type: 'state', status: status })
                })
              break
            case 'digitalInput':
              db.collection('statuses').insertOne(status, () => {
                io.emit('digitalInputChange', { type: 'state', status: status })
              })
              break
            case 'analogOutput':
              db.collection('statuses')
                .updateOne({ 'deviceID': status.deviceID }, { $set: status }, { upsert: true }, () => {
                  io.emit('analogStateChange', { type: 'state', status: status })
              })
            case 'analogInput':
              db.collection('statuses').insertOne(status, () => {
                io.emit('analogInputChange', { type: 'state', status: status })
              })
              break
          }
        })
      }
    })

    app.use(bodyParser.json())
      .use(bodyParser.urlencoded({ extended: true }))
      .use(require('morgan')('dev'))
      .use(express.static(path.join(__dirname, 'dist')))
      .use('/lights', express.static(path.join(__dirname, 'dist')))
      .use('/maps', express.static(path.join(__dirname, 'dist')))
      .use('/charts', express.static(path.join(__dirname, 'dist')))

      .get('/api/devices/:type', (req, res) => {
        db.collection('devices')
          .find({ 'primaryType': req.params.type })
          .toArray((err, docs) => {
            if (err) console.log(err)
            res.send(docs)
          })
      })

      .get('/api/devices', (req, res) => {
        db.collection('devices')
          .find({}).toArray((err, docs) => {
            res.send(docs)
          })
      })

      .get('/api/statuses/:deviceID', (req, res) => {
        db.collection('statuses')
	  .aggregate(
	    {$match:{'deviceID':+req.params.deviceID}},
	    {$sample:{size:500}})
	  .toArray((err, docs) => {
	    if (err) console.log(err)
   	    res.send(docs)
	  })
          //.find({ 'deviceID': +req.params.deviceID })
          //.toArray((err, docs) => {
           // if (err) console.log(err)
            //res.send(docs)
//          })
      })

      .post('/api/publish', (req, res) => {
        mqtt.publish(`${req.body.topic}`, req.body.message)
        res.status(200).send('message published')
      })

      .delete('/api/statuses/:id', (req, res) => {
        db.collection('statuses')
          .deleteOne({ _id: new objectID(req.params.id) }, (err, result) => {
            if (err) console.log(err)
            res.send(result)
          })
      })

      .get('/api/broker', (req, res) => {
        res.send('mqtt//broker')
      })

      .get('/api/geofence', (req, res) => {
        db.collection('geofence')
          .distinct('device', (err, result) => {
            if (err) console.log(err)
            res.send(result)
          })
      })

      .post('/api/geofence', auth, (req, res) => {
        console.log(req.body)
        db.collection('geofence').insertOne(req.body)
        res.status(200).send('geofence event saved')
      })

      .get('/api/geofence/:device', (req, res) => {
        const start = moment().startOf('day')
        const end = moment().endOf('day')
        db.collection('geofence')
          //.find({'device':req.params.device,'timestamp':{$gte:start,$lt:end}})
          .find({ 'device': req.params.device })
          .sort({ 'timestamp': -1 })
          .limit(2)
          .toArray((err, docs) => {
            if (err) console.log(err)
            res.send(docs)
          })
      })
    // app.listen(3000)
    http.listen(3000)
  })

})

// module.exports = app;
<|endoftext|>


<commit_before>const express = require('express');
const path = require('path');
const fs = require('fs');
const sqlite3 = require('sqlite3');
const config = require('./config.js');

const db = new sqlite3.Database(config.databasePath);
const server = express();
const http = require('http').Server(server);
const io = require('socket.io')(http);

http.listen(config.port, '', '', () => console.log(`Megumin.love running on port ${config.port}!`));
// info for self: listening using http because socket.io doesn't take an express instance (see socket.io docs)

const pagePath = path.join(__dirname, '/pages');
const errorPath = path.join(pagePath, '/errorTemplates');
const pages = [];

fs.readdirSync(pagePath).forEach(file => {
	let page = file.slice(0, -5).toLowerCase();
	if(file.substr(-5, 5) !== ".html" || config.errorTemplates.includes(page)) return;

	pages.push({
		name: file,
		path: path.join(pagePath, file),
		route: page === "index" ? "/" : "/" + page
	});
});

server.use(express.static('resources'));

var counter;

db.get("SELECT counter FROM yamero_counter", [], (error, row) => {
	counter = row["counter"];
});

server.get('/port', (req, res) => {
	res.send(`${config.port}`);
});

server.get('/counter', (req, res) => {
	if(req.params.inc) counter++;
	res.send(`${counter}`);
});

io.on('connection', (socket) => {
	socket.on('click', (data) => {
		counter++;
		io.sockets.emit('update', {counter: counter});
	});
});

for(let page of pages) {
	server.get(page.route, (req, res) => res.sendFile(page.path));
};

for(let error of config.errorTemplates) {
	server.use((req, res) => res.status(error).sendFile(`${errorPath}/${error}.html`))
};

setInterval(() => { db.get("UPDATE yamero_counter SET `counter` ="+counter); }, 1000*60*config.updateInterval); // update sql every 30min<commit_msg>query instead of params, oops<commit_after>const express = require('express');
const path = require('path');
const fs = require('fs');
const sqlite3 = require('sqlite3');
const config = require('./config.js');

const db = new sqlite3.Database(config.databasePath);
const server = express();
const http = require('http').Server(server);
const io = require('socket.io')(http);

http.listen(config.port, '', '', () => console.log(`Megumin.love running on port ${config.port}!`));
// info for self: listening using http because socket.io doesn't take an express instance (see socket.io docs)

const pagePath = path.join(__dirname, '/pages');
const errorPath = path.join(pagePath, '/errorTemplates');
const pages = [];

fs.readdirSync(pagePath).forEach(file => {
	let page = file.slice(0, -5).toLowerCase();
	if(file.substr(-5, 5) !== ".html" || config.errorTemplates.includes(page)) return;

	pages.push({
		name: file,
		path: path.join(pagePath, file),
		route: page === "index" ? "/" : "/" + page
	});
});

server.use(express.static('resources'));

var counter;

db.get("SELECT counter FROM yamero_counter", [], (error, row) => {
	counter = row["counter"];
});

server.get('/port', (req, res) => {
	res.send(`${config.port}`);
});

server.get('/counter', (req, res) => {
	if(req.query.inc) counter++;
	res.send(`${counter}`);
});

io.on('connection', (socket) => {
	socket.on('click', (data) => {
		counter++;
		io.sockets.emit('update', {counter: counter});
	});
});

for(let page of pages) {
	server.get(page.route, (req, res) => res.sendFile(page.path));
};

for(let error of config.errorTemplates) {
	server.use((req, res) => res.status(error).sendFile(`${errorPath}/${error}.html`))
};

setInterval(() => { db.get("UPDATE yamero_counter SET `counter` ="+counter); }, 1000*60*config.updateInterval); // update sql every 30min<|endoftext|>


<commit_before>// ordered alphabetically by `fullName`
module.exports = {
  'afl-3.0': {
    name: 'AFL-3.0',
    fullName: 'Academic Free License 3.0 (AFL-3.0)',
    placeholders: {
      description: '',
      user: '',
      year: ''
    }
  },
  'bsd-2-clause': {
    name: 'BSD-2-Clause',
    fullName: 'BSD 2-Clause "Simplified" or "FreeBSD" License (BSD-2-Clause)',
    placeholders: {
      description: '',
      user: '<OWNER>',
      year: '<YEAR>'
    }
  },
  'bsd-3-clause': {
    name: 'BSD-3-Clause',
    fullName: 'BSD 3-Clause "New" or "Revised" License (BSD-3-Clause)',
    placeholders: {
      description: '',
      user: '<OWNER>',
      year: '<YEAR>'
    }
  },
  'agpl-3.0': {
    name: 'AGPL-3.0',
    fullName: 'GNU Affero General Public License 3.0 (AGPL-3.0)',
    placeholders: {
      description: '<one line to give the program\'s name and a brief idea of what it does.>',
      user: '<name of author>',
      year: '<year>'
    }
  },
  'gpl-3.0': {
    name: 'GPL-3.0',
    fullName: 'GNU General Public License 3.0 (GPL-3.0)',
    placeholders: {
      description: '<one line to give the program\'s name and a brief idea of what it does.>',
      user: '<name of author>',
      year: '<year>'
    }
  },
  isc: {
    name: 'ISC',
    fullName: 'ISC License (ISC)',
    placeholders: {
      description: '',
      user: "Company or Person's Name",
      year: '4-digit year'
    }
  },
  mit: {
    name: 'MIT',
    fullName: 'The MIT License (MIT)',
    placeholders: {
      description: '',
      user: '<copyright holders>',
      year: '<year>'
    }
  },
  w3c: {
    name: 'W3C',
    fullName: 'The W3C SOFTWARE NOTICE AND LICENSE (W3C)',
    placeholders: {
      description: '',
      user: '',
      year: ''
    }
  }
  'zlib-libpng': {
    name: 'zlib/libpng',
    fullName: 'The zlib/libpng License',
    placeholders: {
      description: '',
      user: '<copyright holders>',
      year: '<year>'
    }
  }
};
<commit_msg>Add missing comma<commit_after>// ordered alphabetically by `fullName`
module.exports = {
  'afl-3.0': {
    name: 'AFL-3.0',
    fullName: 'Academic Free License 3.0 (AFL-3.0)',
    placeholders: {
      description: '',
      user: '',
      year: ''
    }
  },
  'bsd-2-clause': {
    name: 'BSD-2-Clause',
    fullName: 'BSD 2-Clause "Simplified" or "FreeBSD" License (BSD-2-Clause)',
    placeholders: {
      description: '',
      user: '<OWNER>',
      year: '<YEAR>'
    }
  },
  'bsd-3-clause': {
    name: 'BSD-3-Clause',
    fullName: 'BSD 3-Clause "New" or "Revised" License (BSD-3-Clause)',
    placeholders: {
      description: '',
      user: '<OWNER>',
      year: '<YEAR>'
    }
  },
  'agpl-3.0': {
    name: 'AGPL-3.0',
    fullName: 'GNU Affero General Public License 3.0 (AGPL-3.0)',
    placeholders: {
      description: '<one line to give the program\'s name and a brief idea of what it does.>',
      user: '<name of author>',
      year: '<year>'
    }
  },
  'gpl-3.0': {
    name: 'GPL-3.0',
    fullName: 'GNU General Public License 3.0 (GPL-3.0)',
    placeholders: {
      description: '<one line to give the program\'s name and a brief idea of what it does.>',
      user: '<name of author>',
      year: '<year>'
    }
  },
  isc: {
    name: 'ISC',
    fullName: 'ISC License (ISC)',
    placeholders: {
      description: '',
      user: "Company or Person's Name",
      year: '4-digit year'
    }
  },
  mit: {
    name: 'MIT',
    fullName: 'The MIT License (MIT)',
    placeholders: {
      description: '',
      user: '<copyright holders>',
      year: '<year>'
    }
  },
  w3c: {
    name: 'W3C',
    fullName: 'The W3C SOFTWARE NOTICE AND LICENSE (W3C)',
    placeholders: {
      description: '',
      user: '',
      year: ''
    }
  },
  'zlib-libpng': {
    name: 'zlib/libpng',
    fullName: 'The zlib/libpng License',
    placeholders: {
      description: '',
      user: '<copyright holders>',
      year: '<year>'
    }
  }
};
<|endoftext|>


<commit_before>var duplexify = require('duplexify')
var streams = require('./streams')

var noop = function () {}

var pbs = function (down, encode, decode) {
  var iterators = []

  decode.puts(function (req, cb) {
    down.put(req.key, req.value, function (err) {
      encode.callbacks({id: req.id, error: err && err.message}, cb)
    })
  })

  decode.gets(function (req, cb) {
    down.get(req.key, {valueEncoding: 'binary'}, function (err, value) {
      encode.callbacks({id: req.id, error: err && err.message, value: value}, cb)
    })
  })

  decode.deletes(function (req, cb) {
    down.del(req.key, function (err) {
      encode.callbacks({id: req.id, error: err && err.message}, cb)
    })
  })

  decode.batches(function (req, cb) {
    down.batch(req.ops, function (err) {
      encode.callbacks({id: req.id, error: err && err.message}, cb)
    })
  })

  decode.iterators(function (req, cb) {
    var prev = iterators[req.id]

    if (prev) {
      if (!req.batch) {
        prev.end()
      } else {
        prev.batch = req.batch
        prev.next()
      }
      return cb()
    }

    var first = true
    var nexting = false
    var ended = false
    var iterator = down.iterator(req.options)

    var end = function () {
      ended = true
      iterators[req.id] = null
      while (iterators.length && iterators[iterators.length - 1]) iterators.pop()
      iterator.end(noop)
    }

    var next = function () {
      if (nexting || ended) return
      if (!first && (!data.batch || data.error || (!data.key && !data.value))) return
      first = false
      nexting = true
      iterator.next(function (err, key, value) {
        nexting = false
        data.error = err && err.message
        data.key = key
        data.value = value
        data.batch--
        encode.iterators(data, next)
      })
    }

    var data = iterators[req.id] = {
      id: req.id,
      batch: req.batch,
      key: null,
      value: null,
      next: next,
      end: end
    }

    next()
    cb()
  })

  return null
}

module.exports = function (db, opts) {
  if (opts && opts.encode && opts.decode) {
    if (!db.isOpen()) throw new Error('db must be open to use raw encode/decode mode')
    return pbs(db.db, opts.encode, opts.decode)
  }

  var encode = streams.Server.encode()
  var decode = streams.Client.decode()

  if (db.isOpen()) {
    pbs(db.db, encode, decode)
    return duplexify(decode, encode)
  }

  var stream = duplexify()

  db.open(function () {
    pbs(db.db, encode, decode)
    stream.setWritable(decode)
    stream.setReadable(encode)
  })

  return stream
}
<commit_msg>clean on client stream end<commit_after>var duplexify = require('duplexify')
var eos = require('end-of-stream')
var streams = require('./streams')

var noop = function () {}

var pbs = function (down, encode, decode) {
  var iterators = []

  decode.puts(function (req, cb) {
    down.put(req.key, req.value, function (err) {
      encode.callbacks({id: req.id, error: err && err.message}, cb)
    })
  })

  decode.gets(function (req, cb) {
    down.get(req.key, {valueEncoding: 'binary'}, function (err, value) {
      encode.callbacks({id: req.id, error: err && err.message, value: value}, cb)
    })
  })

  decode.deletes(function (req, cb) {
    down.del(req.key, function (err) {
      encode.callbacks({id: req.id, error: err && err.message}, cb)
    })
  })

  decode.batches(function (req, cb) {
    down.batch(req.ops, function (err) {
      encode.callbacks({id: req.id, error: err && err.message}, cb)
    })
  })

  decode.iterators(function (req, cb) {
    while (iterators.length < req.id) iterators.push(null)

    var prev = iterators[req.id]

    if (prev) {
      if (!req.batch) {
        prev.end()
      } else {
        prev.batch = req.batch
        prev.next()
      }
      return cb()
    }

    var first = true
    var nexting = false
    var ended = false
    var iterator = down.iterator(req.options)

    var end = function () {
      ended = true
      iterators[req.id] = null
      while (iterators.length && iterators[iterators.length - 1]) iterators.pop()
      iterator.end(noop)
    }

    var next = function () {
      if (nexting || ended) return
      if (!first && (!data.batch || data.error || (!data.key && !data.value))) return
      first = false
      nexting = true
      iterator.next(function (err, key, value) {
        nexting = false
        data.error = err && err.message
        data.key = key
        data.value = value
        data.batch--
        encode.iterators(data, next)
      })
    }

    var data = iterators[req.id] = {
      id: req.id,
      batch: req.batch,
      key: null,
      value: null,
      next: next,
      end: end
    }

    next()
    cb()
  })

  eos(decode, function () {
    for (var i = 0; i < iterators.length; i++) {
      if (!iterators[i]) continue
      iterators[i].end()
    }
  })

  return null
}

module.exports = function (db, opts) {
  if (opts && opts.encode && opts.decode) {
    if (!db.isOpen()) throw new Error('db must be open to use raw encode/decode mode')
    return pbs(db.db, opts.encode, opts.decode)
  }

  var encode = streams.Server.encode()
  var decode = streams.Client.decode()

  if (db.isOpen()) {
    pbs(db.db, encode, decode)
    return duplexify(decode, encode)
  }

  var stream = duplexify()

  db.open(function () {
    pbs(db.db, encode, decode)
    stream.setWritable(decode)
    stream.setReadable(encode)
  })

  return stream
}
<|endoftext|>


<commit_before>// Copyright 2017 TODO Group. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

const spawnSync = require('child_process').spawnSync

class Linguist {
  /**
   * Returns the languages found in the project.
   * Associate Array of language String to Array of filenames that are written in that language
   *
   * Throws 'Linguist not installed' error if command line of 'linguist' is not available.
   */
  identifyLanguagesSync (targetDir) {
    // Command was renamed in https://github.com/github/linguist/pull/4208
    for (const command of ['github-linguist', 'linguist']) {
      const output = spawnSync(command, [targetDir, '--json']).stdout
      if (output !== null) {
        return JSON.parse(output.toString())
      }
    }

    throw new Error('Linguist not installed')
  }
}

module.exports = new Linguist()
<commit_msg>Fix github-linguist finding on Windows<commit_after>// Copyright 2017 TODO Group. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

const isWindows = require('is-windows')
const spawnSync = require('child_process').spawnSync

class Linguist {
  /**
   * Returns the languages found in the project.
   * Associate Array of language String to Array of filenames that are written in that language
   *
   * Throws 'Linguist not installed' error if command line of 'linguist' is not available.
   */
  identifyLanguagesSync (targetDir) {
    // Command was renamed in https://github.com/github/linguist/pull/4208
    for (const command of ['github-linguist', 'linguist']) {
      const output = spawnSync(isWindows() ? `${command}.bat` : command, [targetDir, '--json']).stdout
      if (output !== null) {
        return JSON.parse(output.toString())
      }
    }

    throw new Error('Linguist not installed')
  }
}

module.exports = new Linguist()
<|endoftext|>


<commit_before>#!/usr/bin/env node
'use strict';

// Setup env variables from local .env file. After this call, all variables
// from .env file can be access via `process.env`.
var dotEnvLoaded = require('dotenv').config({
    silent: true,
});
console.log('.env file loaded:', dotEnvLoaded);

var autoprefixer = require('metalsmith-autoprefixer');
var beautify = require('metalsmith-beautify');
var ignore = require('metalsmith-ignore');
var layouts = require('metalsmith-layouts');
var markdown = require('metalsmith-markdown');
var s3 = require('metalsmith-s3');
var sass = require('metalsmith-sass');

var metalsmithPrismicServer = require('metalsmith-prismic-server');

var handlebarsHelpers = require('./plugins/handlebars-helpers');
var utils = require('./utils/utils.js');

var argv = require('process').argv;

var config = {
  // See src/config.js in metalsmith-prismic-server for all options

  /**
   * Configure metalsmith-prismic linkResolver
   * Generates prismic links and paths for the files in a prismic collections
   *
   * E.g. The paths for each blog-post in the blog-post.md collection will be generated as:
   *      /blog-post/my-second-blog-post/index.html
   *
   * E.g. The paths for prismic author links will be generated as:
   *      /author/bob/
   *
   * Note: the linkResolver does not affect single prismic files
   *
   * *TEMPLATE* adjust this example function to suit your prismic content and folder structures
   * *TEMPLATE* If omitted, links and paths will be generated with the default format of:
   * *TEMPLATE* "/<document.type>/<document.id>/<document.slug>"
   */
  prismicLinkResolver (ctx, doc) {
    if (doc.isBroken) {
      return;
    }

    // For prismic collection files append 'index.html'
    // Leave it out for prismic link paths
    var filename = 'index.html';

    var language = utils.getLanguageFromTags(doc);
    if (language) {
      // *TEMPLATE-i18n* Use this linkResolver to generate i18n-links based on languages tags defined in Prismic
      // *TEMPLATE-i18n* E.g. The paths for each blog-post in the fi/i18n-blog-post.md collection will be generated as:
      // *TEMPLATE-i18n*      /fi/i18n-blog-post/mun-toka-blogipostaus/index.html
      // *TEMPLATE-i18n* Note: if all documents in prismic have a language tag, the root needs to handled manually
      switch (doc.type) {
        case 'i18n-example':
          return '/' + language + '/' + filename;
        default:
          return '/' + language + '/' + doc.type + '/' +  (doc.uid || doc.slug) + '/' + filename;
      }
    } else {
      switch (doc.type) {
        case 'home':
          return '/' + filename;
        default:
          return '/' + doc.type + '/' +  (doc.uid || doc.slug) + '/' + filename;
      }
    }
  },

  // Metalsmith plugins passed to metalsmithPrismicServer
  plugins: {
    common: [
      // Render markdown files to html
      markdown(),
      // Register handlebars helpers
      handlebarsHelpers(),
      // Render with handlebars templates
      layouts({
        engine: 'handlebars',
        directory: 'layouts',
        partials: 'partials',
        pattern: '**/*.html'
      }),
      // Style using sass
      sass({
        outputDir: 'style/'
      }),
      // Autoprefix styles
      autoprefixer({
        // Support browsers based on these versions
        browsers: ['last 2 versions',
                   '> 5%']
      }),
      // Prettify output
      beautify({
        indent_size: 2,
        indent_char: ' ',
        wrap_line_length: 0,
        end_with_newline: true,
        css: true,
        html: true
      }),
      // Ignore some files
      ignore([
        '**/*.scss'
      ])
    ],
    deploy: [
      s3({
        action: 'write',
        bucket: 'metalsmith-prismic-template.futurice.com',
        region: 'eu-west-1'
      })
    ]
  }
};

function run() {
  // Start server
  switch (argv[2]) {
    case 'dev':
      metalsmithPrismicServer.dev(config);
      break;
    case 'prod':
      metalsmithPrismicServer.prod(config);
      break;
    case 'build':
      metalsmithPrismicServer.build(config, []);
      break;
    default:
      console.error(`invalid command '${argv[2]}'`);
  }
}

if (require.main === module) {
  // Only run server if run from script
  run();
}
<commit_msg>Undo linkresolver change<commit_after>#!/usr/bin/env node
'use strict';

// Setup env variables from local .env file. After this call, all variables
// from .env file can be access via `process.env`.
var dotEnvLoaded = require('dotenv').config({
    silent: true,
});
console.log('.env file loaded:', dotEnvLoaded);

var autoprefixer = require('metalsmith-autoprefixer');
var beautify = require('metalsmith-beautify');
var ignore = require('metalsmith-ignore');
var layouts = require('metalsmith-layouts');
var markdown = require('metalsmith-markdown');
var s3 = require('metalsmith-s3');
var sass = require('metalsmith-sass');

var metalsmithPrismicServer = require('metalsmith-prismic-server');

var handlebarsHelpers = require('./plugins/handlebars-helpers');
var utils = require('./utils/utils.js');

var argv = require('process').argv;

var config = {
  // See src/config.js in metalsmith-prismic-server for all options

  /**
   * Configure metalsmith-prismic linkResolver
   * Generates prismic links and paths for the files in a prismic collections
   *
   * E.g. The paths for each blog-post in the blog-post.md collection will be generated as:
   *      /blog-post/my-second-blog-post/index.html
   *
   * E.g. The paths for prismic author links will be generated as:
   *      /author/bob/
   *
   * Note: the linkResolver does not affect single prismic files
   *
   * *TEMPLATE* adjust this example function to suit your prismic content and folder structures
   * *TEMPLATE* If omitted, links and paths will be generated with the default format of:
   * *TEMPLATE* "/<document.type>/<document.id>/<document.slug>"
   */
  prismicLinkResolver (ctx, doc) {
    if (doc.isBroken) {
      return;
    }

    // For prismic collection files append 'index.html'
    // Leave it out for prismic link paths
    var filename = doc.data ? 'index.html' : '';

    var language = utils.getLanguageFromTags(doc);
    if (language) {
      // *TEMPLATE-i18n* Use this linkResolver to generate i18n-links based on languages tags defined in Prismic
      // *TEMPLATE-i18n* E.g. The paths for each blog-post in the fi/i18n-blog-post.md collection will be generated as:
      // *TEMPLATE-i18n*      /fi/i18n-blog-post/mun-toka-blogipostaus/index.html
      // *TEMPLATE-i18n* Note: if all documents in prismic have a language tag, the root needs to handled manually
      switch (doc.type) {
        case 'i18n-example':
          return '/' + language + '/' + filename;
        default:
          return '/' + language + '/' + doc.type + '/' +  (doc.uid || doc.slug) + '/' + filename;
      }
    } else {
      switch (doc.type) {
        case 'home':
          return '/' + filename;
        default:
          return '/' + doc.type + '/' +  (doc.uid || doc.slug) + '/' + filename;
      }
    }
  },

  // Metalsmith plugins passed to metalsmithPrismicServer
  plugins: {
    common: [
      // Render markdown files to html
      markdown(),
      // Register handlebars helpers
      handlebarsHelpers(),
      // Render with handlebars templates
      layouts({
        engine: 'handlebars',
        directory: 'layouts',
        partials: 'partials',
        pattern: '**/*.html'
      }),
      // Style using sass
      sass({
        outputDir: 'style/'
      }),
      // Autoprefix styles
      autoprefixer({
        // Support browsers based on these versions
        browsers: ['last 2 versions',
                   '> 5%']
      }),
      // Prettify output
      beautify({
        indent_size: 2,
        indent_char: ' ',
        wrap_line_length: 0,
        end_with_newline: true,
        css: true,
        html: true
      }),
      // Ignore some files
      ignore([
        '**/*.scss'
      ])
    ],
    deploy: [
      s3({
        action: 'write',
        bucket: 'metalsmith-prismic-template.futurice.com',
        region: 'eu-west-1'
      })
    ]
  }
};

function run() {
  // Start server
  switch (argv[2]) {
    case 'dev':
      metalsmithPrismicServer.dev(config);
      break;
    case 'prod':
      metalsmithPrismicServer.prod(config);
      break;
    case 'build':
      metalsmithPrismicServer.build(config, []);
      break;
    default:
      console.error(`invalid command '${argv[2]}'`);
  }
}

if (require.main === module) {
  // Only run server if run from script
  run();
}
<|endoftext|>


<commit_before>var fs = require('fs');
var path = require('path');
var os = require('os');
var util = require('util');

var async = require('async');
var DMP;
var diff_match_patch = require('diff_match_patch');
var JS_DMP = new diff_match_patch.diff_match_patch();
var log = require("floorine");
var mkdirp = require("mkdirp");
var _ = require("lodash");

var ignores = require("./ignores");
var utils = require("./utils");

try {
  DMP = require("native-diff-match-patch");
} catch (e) {
  log.warn("No native-diff-match-patch. You won't be able to patch binary files.");
}

var fsevents;
if (process.platform === "darwin") {
  try {
    fsevents = require('fsevents');
  } catch (e) {
    log.warn('native fsevents can not be required.  This is not good');
  }
}

var Listener = function (_path, conn, hooks) {
  var self = this;

  self.path = _path;
  self.conn = conn;
  self.bufs = {};
  self.paths_to_ids = {};
  self.watchers = {};
  self.expected_changes = {};
  self.ignore_patterns = ["node_modules"];
  self.hooks = hooks;
};

Listener.prototype.buf_by_path = function (rel_path) {
  var self = this,
    buf_id = self.paths_to_ids[rel_path];

  return self.bufs[buf_id];
};

Listener.prototype.listener = function (parent_path, event, rel_to_parent_path) {
  var self = this,
    should_delete,
    abs_path = path.join(parent_path, rel_to_parent_path),
    buf_path = path.relative(self.path, abs_path),
    buf = self.buf_by_path(buf_path);

  log.log('%s was %sd', buf_path, event);

  if (event === 'rename') {
    /* rename can fire under the following:
      thing was renamed
      new file was created
      file was moved
      file was deleted
    */
    self.on_create(abs_path, buf);
    return;
  }

  if (!buf) {
    return self.create_buf(buf_path);
  }

  if (buf.buf === undefined) {
    return log.log('ignoring change');
  }

  self.on_change(abs_path, buf);
};

Listener.prototype.watch_path = function (_path, ig) {
  var self = this;

  if (self.watchers[_path]) {
    log.debug("Already watching", _path);
    return;
  }

  if (ig && ig.is_ignored(_path)) {
    return;
  }
  if (!ig) {
    ig = ignores.build_ignores(_path, self.path);
  }

  if (!fsevents) {
    return self.node_watch_path(_path, ig);
  }
  if (!_.isEmpty(self.watchers)) {
    return log.debug('Already have a watcher, ignoring watch request for', _path);
  }
  self.osx_watch_path(_path, ig);

};

Listener.prototype.on_create = function (abs_path, buf) {
  var self = this,
    current,
    md5;

  log.log('created', abs_path);

  if (!buf) {
    self.create_buf(abs_path);
    return;
  }

  try {
    /*jslint stupid: true */
    current = fs.readFileSync(abs_path);
    /*jslint stupid: false */
  } catch (ignore) {
    self.on_delete(abs_path, buf);
    return;
  }

  md5 = utils.md5(current);

  // change contents sometimes (underlying inode was stomped)
  if (buf.md5 === md5) {
    return;
  }

  self.conn.send_patch(buf, current);
};

Listener.prototype.on_change = function (abs_path, buf) {
  var self = this,
    current,
    md5;

  if (!buf) {
    return;
  }

  /*jslint stupid: true */
  current = fs.readFileSync(abs_path);
  /*jslint stupid: false */

  md5 = utils.md5(current);
  if (md5 === buf.md5) {
    return log.debug('got expected change');
  }

  log.log('new md5 is', md5);

  self.conn.send_patch(buf, current);
};

Listener.prototype.on_delete = function (abs_path, buf) {
  var self = this;

  if (!buf) {
    return;
  }
  log.debug("Deleted %s", abs_path);
  return self.conn.send_delete_buf(buf.id);
};

Listener.prototype.on_rename = function (abs_path, buf) {
  if (buf) {
    log.debug("Renamed %s %s", abs_path, buf.id);
  }
};

Listener.prototype.osx_watch_path = function (_path) {
  var self = this,
    get_buf,
    watcher = fsevents(_path);

  get_buf = function (abs_path) {
    var buf_path = path.relative(self.path, abs_path),
      buf = self.buf_by_path(buf_path);

    return [abs_path, buf];
  };

  watcher.on('created', function (abs_path) {
    self.on_create.apply(self, get_buf(abs_path));
  });

  watcher.on('deleted', function (abs_path) {
    self.on_delete.apply(self, get_buf(abs_path));
  });

  watcher.on('modified', function (abs_path) {
    self.on_change.apply(self, get_buf(abs_path));
  });

  watcher.on('moved-out', function (abs_path) {
    self.on_rename.apply(self, get_buf(abs_path));
  });

  watcher.on('moved-in', function (abs_path) {
    self.on_rename.apply(self, get_buf(abs_path));
  });

  self.watchers[_path] = watcher;
};

Listener.prototype.node_watch_path = function (_path, ig) {
  var self = this,
    paths,
    stats;

  /*jslint stupid: true */
  stats = fs.lstatSync(_path);
  /*jslint stupid: false */
  if (stats.isSymbolicLink()) {
    return log.error('Skipping adding %s because it is a symlink.', _path);
  }

  self.watchers[_path] = fs.watch(_path, self.listener.bind(self, _path));

  /*jslint stupid: true */
  paths = fs.readdirSync(_path);
  /*jslint stupid: false */

  _.each(paths, function (p) {
    var p_path = path.join(_path, p),
      ignored,
      child_ig;

    if (p[0] === '.' && !_.contains(ignores.HIDDEN_WHITELIST, p)) {
      return log.log('Not creating buf for hidden path', p_path);
    }
    ignored = ig.is_ignored(p_path);
    if (ignored) {
      return log.log(util.format('Not adding %s because path is ignored.', p_path));
    }
    /*jslint stupid: true */
    stats = fs.lstatSync(p_path);
    /*jslint stupid: false */
    if (stats.isDirectory()) {
      child_ig = new ignores.Ignore(ig, p_path);
      self.watch_path(p_path, child_ig);
    }
  });
};

Listener.prototype.create_buf = function (_path, ig) {
  var self = this,
    stats,
    buf,
    encoding,
    existing,
    ig_path,
    rel_path,
    paths;

  try {
    /*jslint stupid: true */
    stats = fs.lstatSync(_path);
    /*jslint stupid: false */
  } catch (e) {
    log.error(util.format('Error statting %s: %s', _path, e.toString()));
    return;
  }
  if (stats.isSymbolicLink()) {
    return log.error('Skipping adding %s because it is a symlink.', _path);
  }

  if (!ig) {
    if (stats.isDirectory()) {
      ig_path = _path;
    } else {
      ig_path = path.dirname(_path);
    }
    ig = ignores.build_ignores(ig_path, self.path);
  }

  if (ig.is_ignored(_path)) {
    return;
  }

  if (stats.isFile()) {
    rel_path = path.relative(self.path, _path);
    existing = self.buf_by_path(rel_path);
    if (existing) {
      return;
    }

    try {
      /*jslint stupid: true */
      buf = fs.readFileSync(_path);
      /*jslint stupid: false */
    } catch (e2) {
      log.error(util.format('Error readFileSync %s: %s', _path, e2.toString()));
      return;
    }
    encoding = utils.is_binary(buf) ? 'base64' : 'utf8';
    return self.conn.send_create_buf({
      'buf': buf.toString(encoding),
      'encoding': encoding,
      'md5': utils.md5(buf),
      'path': rel_path
    });
  }

  if (!stats.isDirectory()) {
    return;
  }

  try {
    /*jslint stupid: true */
    paths = fs.readdirSync(_path);
    /*jslint stupid: false */
  } catch (e3) {
    log.error(util.format('Error readdiring %s: %s', _path, e3.toString()));
    return;
  }

  _.each(paths, function (p) {
    var p_path = path.join(_path, p),
      ignored,
      child_ig;

    if (p[0] === '.' && !_.contains(ignores.HIDDEN_WHITELIST, p)) {
      return log.log('Not creating buf for hidden path', p_path);
    }
    ignored = ig.is_ignored(p_path);
    if (ignored) {
      return log.log(util.format('Not adding %s because path is ignored.', p_path));
    }

    try {
      /*jslint stupid: true */
      stats = fs.lstatSync(p_path);
      /*jslint stupid: false */
    } catch (e) {
      log.error(util.format('Error lstatSync %s: %s', p_path, e.toString()));
      return;
    }
    if (stats.isDirectory()) {
      child_ig = new ignores.Ignore(ig, p_path);
      self.create_buf(p_path, child_ig);
    } else {
      self.create_buf(p_path, ig);
    }
  });
  return;
};

Listener.prototype.patch = function (patch_text, md5, id) {
  var self = this,
    res,
    self_md5_after,
    patches,
    buf = self.bufs[id];

  if (!buf) {
    return self.conn.send_get_buf(id);
  }
  if (buf.buf === undefined) {
    return;
  }

  if (buf.encoding === "utf8") {
    try {
      patches = JS_DMP.patch_fromText(patch_text);
    } catch (e2) {
      log.error("Couldn't parse patch text:", patch_text, "\nException:", e2);
      return self.conn.disconnect("Unable to parse the patch sent from the server.");
    }
    if (patches.length === 0) {
      return log.log("Patch is empty.");
    }
    res = JS_DMP.patch_apply(patches, buf.buf.toString());
  } else if (DMP) {
    try {
      res = DMP.patch_apply(patch_text, buf.encoding === 'utf8' ? buf.buf.toString() : buf.buf);
    } catch (e) {
      log.error("Couldn't parse patch text:", patch_text, "\nException:", e);
      return self.conn.disconnect("Unable to parse the patch sent from the server.");
    }
  } else {
    // TODO: don't send a billion get_bufs
    return self.conn.send_get_buf(id);
  }

  if (!utils.patched_cleanly(res)) {
    log.warn(util.format("Re-fetching %s because it wasn't patched cleanly.", buf.path));
    return self.conn.send_get_buf(id);
  }

  self_md5_after = utils.md5(res[0]);
  if (self_md5_after !== md5) {
    log.log('md5s don\'t match. expected', md5, 'but md5 was', self_md5_after);
    return self.conn.send_get_buf(id);
  }

  if (!Buffer.isBuffer(res[0])) {
    res[0] = new Buffer(res[0]);
  }

  buf.buf = res[0];
  buf.md5 = md5;

  self.write(buf);
};

Listener.prototype.rename = function (old_path, new_path) {
  var self = this,
    buf = self.buf_by_path(old_path);

  delete self.paths_to_ids[old_path];
  self.paths_to_ids[new_path] = buf;
  buf.path = new_path;
  mkdirp.sync(path.dirname(new_path));
  /*jslint stupid: true */
  fs.renameSync(old_path, new_path);
  /*jslint stupid: false */
};

Listener.prototype.delete_buf = function (_path) {
  var self = this,
    buf = self.buf_by_path(_path),
    realpath = path.join(self.path, _path),
    dir = path.normalize(path.dirname(realpath));

  if (buf) {
    delete self.bufs[buf.id];
  }
  delete self.paths_to_ids[_path];

  fs.unlink(realpath, function (err, result) {
    if (err) {
      return log.warn('Tried to delete', realpath, 'but I couldn\'t because', err, result);
    }
    log.log('Deleted', realpath);

    while (dir && dir !== self.path && path.relative(self.path, dir).indexOf('..') === -1) {
      try {
        /*jslint stupid: true */
        fs.rmdirSync(dir);
        /*jslint stupid: false */
        log.log("Deleted empty directory", dir);
      } catch (e) {
        return log.debug("Couldn't delete", dir);
      }
      dir = path.normalize(path.dirname(dir));
    }
  });
};

Listener.prototype.write = function (buf) {
  var self = this,
    realpath = path.join(self.path, buf.path);

  if (buf.path === ".floo") {
    self.hooks.expect_md5(buf.md5);
  }

  log.log("Writing", buf.path);

  mkdirp(path.dirname(realpath), function (err) {
    if (err) {
      log.warn(err);
    }
    fs.writeFile(realpath, buf.buf, {encoding: buf.encoding}, function (err) {
      if (err) {
        return log.error(err);
      }
    });
  });
};

module.exports = Listener;
<commit_msg>don't read a deleted file multiple times<commit_after>var fs = require('fs');
var path = require('path');
var os = require('os');
var util = require('util');

var async = require('async');
var DMP;
var diff_match_patch = require('diff_match_patch');
var JS_DMP = new diff_match_patch.diff_match_patch();
var log = require("floorine");
var mkdirp = require("mkdirp");
var _ = require("lodash");

var ignores = require("./ignores");
var utils = require("./utils");

try {
  DMP = require("native-diff-match-patch");
} catch (e) {
  log.warn("No native-diff-match-patch. You won't be able to patch binary files.");
}

var fsevents;
if (process.platform === "darwin") {
  try {
    fsevents = require('fsevents');
  } catch (e) {
    log.warn('native fsevents can not be required.  This is not good');
  }
}

var Listener = function (_path, conn, hooks) {
  var self = this;

  self.path = _path;
  self.conn = conn;
  self.bufs = {};
  self.paths_to_ids = {};
  self.watchers = {};
  self.expected_changes = {};
  self.ignore_patterns = ["node_modules"];
  self.hooks = hooks;
};

Listener.prototype.buf_by_path = function (rel_path) {
  var self = this,
    buf_id = self.paths_to_ids[rel_path];

  return self.bufs[buf_id];
};

Listener.prototype.listener = function (parent_path, event, rel_to_parent_path) {
  var self = this,
    should_delete,
    abs_path = path.join(parent_path, rel_to_parent_path),
    buf_path = path.relative(self.path, abs_path),
    buf = self.buf_by_path(buf_path);

  log.log('%s was %sd', buf_path, event);

  if (event === 'rename') {
    /* rename can fire under the following:
      thing was renamed
      new file was created
      file was moved
      file was deleted
    */
    self.on_create(abs_path, buf);
    return;
  }

  if (!buf) {
    return self.create_buf(buf_path);
  }

  if (buf.buf === undefined) {
    return log.log('ignoring change');
  }

  self.on_change(abs_path, buf);
};

Listener.prototype.watch_path = function (_path, ig) {
  var self = this;

  if (self.watchers[_path]) {
    log.debug("Already watching", _path);
    return;
  }

  if (ig && ig.is_ignored(_path)) {
    return;
  }
  if (!ig) {
    ig = ignores.build_ignores(_path, self.path);
  }

  if (!fsevents) {
    return self.node_watch_path(_path, ig);
  }
  if (!_.isEmpty(self.watchers)) {
    return log.debug('Already have a watcher, ignoring watch request for', _path);
  }
  self.osx_watch_path(_path, ig);

};

Listener.prototype.on_create = function (abs_path, buf) {
  var self = this,
    current,
    md5;

  log.log('created', abs_path);

  try {
    /*jslint stupid: true */
    current = fs.readFileSync(abs_path);
    /*jslint stupid: false */
  } catch (ignore) {
    if (buf) {
      self.on_delete(abs_path, buf);
    }
    return;
  }

  if (!buf) {
    self.create_buf(abs_path);
    return;
  }

  md5 = utils.md5(current);

  // change contents sometimes (underlying inode was stomped)
  if (buf.md5 === md5) {
    return;
  }

  self.conn.send_patch(buf, current);
};

Listener.prototype.on_change = function (abs_path, buf) {
  var self = this,
    current,
    md5;

  if (!buf) {
    return;
  }

  /*jslint stupid: true */
  current = fs.readFileSync(abs_path);
  /*jslint stupid: false */

  md5 = utils.md5(current);
  if (md5 === buf.md5) {
    return log.debug('got expected change');
  }

  log.log('new md5 is', md5);

  self.conn.send_patch(buf, current);
};

Listener.prototype.on_delete = function (abs_path, buf) {
  var self = this;

  if (!buf) {
    return;
  }
  log.debug("Deleted %s", abs_path);
  return self.conn.send_delete_buf(buf.id);
};

Listener.prototype.on_rename = function (abs_path, buf) {
  if (buf) {
    log.debug("Renamed %s %s", abs_path, buf.id);
  }
};

Listener.prototype.osx_watch_path = function (_path) {
  var self = this,
    get_buf,
    watcher = fsevents(_path);

  get_buf = function (abs_path) {
    var buf_path = path.relative(self.path, abs_path),
      buf = self.buf_by_path(buf_path);

    return [abs_path, buf];
  };

  watcher.on('created', function (abs_path) {
    self.on_create.apply(self, get_buf(abs_path));
  });

  watcher.on('deleted', function (abs_path) {
    self.on_delete.apply(self, get_buf(abs_path));
  });

  watcher.on('modified', function (abs_path) {
    self.on_change.apply(self, get_buf(abs_path));
  });

  watcher.on('moved-out', function (abs_path) {
    self.on_rename.apply(self, get_buf(abs_path));
  });

  watcher.on('moved-in', function (abs_path) {
    self.on_rename.apply(self, get_buf(abs_path));
  });

  self.watchers[_path] = watcher;
};

Listener.prototype.node_watch_path = function (_path, ig) {
  var self = this,
    paths,
    stats;

  /*jslint stupid: true */
  stats = fs.lstatSync(_path);
  /*jslint stupid: false */
  if (stats.isSymbolicLink()) {
    return log.error('Skipping adding %s because it is a symlink.', _path);
  }

  self.watchers[_path] = fs.watch(_path, self.listener.bind(self, _path));

  /*jslint stupid: true */
  paths = fs.readdirSync(_path);
  /*jslint stupid: false */

  _.each(paths, function (p) {
    var p_path = path.join(_path, p),
      ignored,
      child_ig;

    if (p[0] === '.' && !_.contains(ignores.HIDDEN_WHITELIST, p)) {
      return log.log('Not creating buf for hidden path', p_path);
    }
    ignored = ig.is_ignored(p_path);
    if (ignored) {
      return log.log(util.format('Not adding %s because path is ignored.', p_path));
    }
    /*jslint stupid: true */
    stats = fs.lstatSync(p_path);
    /*jslint stupid: false */
    if (stats.isDirectory()) {
      child_ig = new ignores.Ignore(ig, p_path);
      self.watch_path(p_path, child_ig);
    }
  });
};

Listener.prototype.create_buf = function (_path, ig) {
  var self = this,
    stats,
    buf,
    encoding,
    existing,
    ig_path,
    rel_path,
    paths;

  try {
    /*jslint stupid: true */
    stats = fs.lstatSync(_path);
    /*jslint stupid: false */
  } catch (e) {
    log.error(util.format('Error statting %s: %s', _path, e.toString()));
    return;
  }
  if (stats.isSymbolicLink()) {
    return log.error('Skipping adding %s because it is a symlink.', _path);
  }

  if (!ig) {
    if (stats.isDirectory()) {
      ig_path = _path;
    } else {
      ig_path = path.dirname(_path);
    }
    ig = ignores.build_ignores(ig_path, self.path);
  }

  if (ig.is_ignored(_path)) {
    return;
  }

  if (stats.isFile()) {
    rel_path = path.relative(self.path, _path);
    existing = self.buf_by_path(rel_path);
    if (existing) {
      return;
    }

    try {
      /*jslint stupid: true */
      buf = fs.readFileSync(_path);
      /*jslint stupid: false */
    } catch (e2) {
      log.error(util.format('Error readFileSync %s: %s', _path, e2.toString()));
      return;
    }
    encoding = utils.is_binary(buf) ? 'base64' : 'utf8';
    return self.conn.send_create_buf({
      'buf': buf.toString(encoding),
      'encoding': encoding,
      'md5': utils.md5(buf),
      'path': rel_path
    });
  }

  if (!stats.isDirectory()) {
    return;
  }

  try {
    /*jslint stupid: true */
    paths = fs.readdirSync(_path);
    /*jslint stupid: false */
  } catch (e3) {
    log.error(util.format('Error readdiring %s: %s', _path, e3.toString()));
    return;
  }

  _.each(paths, function (p) {
    var p_path = path.join(_path, p),
      ignored,
      child_ig;

    if (p[0] === '.' && !_.contains(ignores.HIDDEN_WHITELIST, p)) {
      return log.log('Not creating buf for hidden path', p_path);
    }
    ignored = ig.is_ignored(p_path);
    if (ignored) {
      return log.log(util.format('Not adding %s because path is ignored.', p_path));
    }

    try {
      /*jslint stupid: true */
      stats = fs.lstatSync(p_path);
      /*jslint stupid: false */
    } catch (e) {
      log.error(util.format('Error lstatSync %s: %s', p_path, e.toString()));
      return;
    }
    if (stats.isDirectory()) {
      child_ig = new ignores.Ignore(ig, p_path);
      self.create_buf(p_path, child_ig);
    } else {
      self.create_buf(p_path, ig);
    }
  });
  return;
};

Listener.prototype.patch = function (patch_text, md5, id) {
  var self = this,
    res,
    self_md5_after,
    patches,
    buf = self.bufs[id];

  if (!buf) {
    return self.conn.send_get_buf(id);
  }
  if (buf.buf === undefined) {
    return;
  }

  if (buf.encoding === "utf8") {
    try {
      patches = JS_DMP.patch_fromText(patch_text);
    } catch (e2) {
      log.error("Couldn't parse patch text:", patch_text, "\nException:", e2);
      return self.conn.disconnect("Unable to parse the patch sent from the server.");
    }
    if (patches.length === 0) {
      return log.log("Patch is empty.");
    }
    res = JS_DMP.patch_apply(patches, buf.buf.toString());
  } else if (DMP) {
    try {
      res = DMP.patch_apply(patch_text, buf.encoding === 'utf8' ? buf.buf.toString() : buf.buf);
    } catch (e) {
      log.error("Couldn't parse patch text:", patch_text, "\nException:", e);
      return self.conn.disconnect("Unable to parse the patch sent from the server.");
    }
  } else {
    // TODO: don't send a billion get_bufs
    return self.conn.send_get_buf(id);
  }

  if (!utils.patched_cleanly(res)) {
    log.warn(util.format("Re-fetching %s because it wasn't patched cleanly.", buf.path));
    return self.conn.send_get_buf(id);
  }

  self_md5_after = utils.md5(res[0]);
  if (self_md5_after !== md5) {
    log.log('md5s don\'t match. expected', md5, 'but md5 was', self_md5_after);
    return self.conn.send_get_buf(id);
  }

  if (!Buffer.isBuffer(res[0])) {
    res[0] = new Buffer(res[0]);
  }

  buf.buf = res[0];
  buf.md5 = md5;

  self.write(buf);
};

Listener.prototype.rename = function (old_path, new_path) {
  var self = this,
    buf = self.buf_by_path(old_path);

  delete self.paths_to_ids[old_path];
  self.paths_to_ids[new_path] = buf;
  buf.path = new_path;
  mkdirp.sync(path.dirname(new_path));
  /*jslint stupid: true */
  fs.renameSync(old_path, new_path);
  /*jslint stupid: false */
};

Listener.prototype.delete_buf = function (_path) {
  var self = this,
    buf = self.buf_by_path(_path),
    realpath = path.join(self.path, _path),
    dir = path.normalize(path.dirname(realpath));

  if (buf) {
    delete self.bufs[buf.id];
  }
  delete self.paths_to_ids[_path];

  fs.unlink(realpath, function (err, result) {
    if (err) {
      return log.warn('Tried to delete', realpath, 'but I couldn\'t because', err, result);
    }
    log.log('Deleted', realpath);

    while (dir && dir !== self.path && path.relative(self.path, dir).indexOf('..') === -1) {
      try {
        /*jslint stupid: true */
        fs.rmdirSync(dir);
        /*jslint stupid: false */
        log.log("Deleted empty directory", dir);
      } catch (e) {
        return log.debug("Couldn't delete", dir);
      }
      dir = path.normalize(path.dirname(dir));
    }
  });
};

Listener.prototype.write = function (buf) {
  var self = this,
    realpath = path.join(self.path, buf.path);

  if (buf.path === ".floo") {
    self.hooks.expect_md5(buf.md5);
  }

  log.log("Writing", buf.path);

  mkdirp(path.dirname(realpath), function (err) {
    if (err) {
      log.warn(err);
    }
    fs.writeFile(realpath, buf.buf, {encoding: buf.encoding}, function (err) {
      if (err) {
        return log.error(err);
      }
    });
  });
};

module.exports = Listener;
<|endoftext|>


<commit_before>var path = require('path');
var app = require('express')();
var http = require('http').createServer(app);
// var io = require('socket.io')(http, {origins: '*:*'});
var io = require('socket.io')(http, {origins: '*:*'});
var REQUEST_PATH = path.dirname(__dirname);

var clients = {};
var clientsByPlayer = {};
var playersByClient = {};
var rooms = [];
var roomByPlayer = {};

var PORT = 8080;
var TAGS = ['green', 'blue', 'yellow', 'red', 'magenta', 'orange'];
var STATE_CREATED = 'created';
var STATE_PLAYING = 'playing';

function getRoom(id)
{
    for (var i = 0, len = rooms.length; i < len; i++) {
        var room = rooms[i];
        if (room.id == id) {
            return room;
        }
    }
    return false;
}

function removeRoom(id)
{
    for (var i = 0, len = rooms.length; i < len; i++) {
        var room = rooms[i];
        if (room && room.id == id) {
            rooms.splice(i, 1);
        }
    }
    return false;
}

function getRandomInt(min, max)
{
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

function getRandomTag()
{
    return TAGS[getRandomInt(0, TAGS.length - 1)];
}

function createGrid(maxRows, maxCols)
{
    var grid = [];

    for(var row = 0; row < maxRows; row++) {

        grid[row] = [];
        var mod = row % 2 === 0;

        for (var col = 0; col < maxCols; col++) {

            // last col
            if (!mod && col >= maxCols - 1) {
                continue;
            }

            grid[row][col] = getRandomTag();
        }
    }

    return grid;
}

function createBubbles(len)
{
    var bubbles = [];

    for (var i = 0; i < len; i++) {
        bubbles.push(getRandomTag());
    }

    return bubbles;
}

// io.set('origins', '*:*');
//
// app.use(function (req, res, next) {
//     res.header("Access-Control-Allow-Origin", "*");
//     res.header("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With");
//     res.header("Access-Control-Allow-Methods", "GET, PUT, POST");
//     if ('OPTIONS' === req.method) {
//         res.status(204).send();
//     }
//     else {
//         next();
//     }
// });

io.on('connection', function(socket) {

    clients[socket.id] = socket;
    console.log('a user connected', Object.keys(clients).length, socket.id);

    socket.on('disconnect', function() {

        console.log('a user disconnect', playersByClient[socket.id], Object.keys(clients).length, socket.id);

        var playerId = playersByClient[socket.id];

        for (var i = 0, len = rooms.length; i < len; i++) {

            var room = rooms[i];

            if (!room) {
                continue;
            }

            var p1 = room.players[0];
            var p2 = room.players[1];

            if (p1.id == playerId) {
                if (p2) {
                    var p2Client = clients[clientsByPlayer[p2.id]];

                    if (p2Client) {
                        p2Client.emit('host-close-room');
                    }
                }
                removeRoom(room.id);
                break;
            }

            if (p2 && p2.id == playerId) {
                room.players.pop();
                var p1Client = clients[clientsByPlayer[p1.id]];
                if (p1Client) {
                    p1Client.emit('player-leave-room', room);
                }
                break;
            }
        }

        delete clientsByPlayer[playerId];
        delete playersByClient[socket.id];
        delete clients[socket.id];
    });

    socket.on('join', function(playerId, done) {

        console.log('join', playerId);

        if (clientsByPlayer[playerId]) {
            return done('Nickname '+ playerId +' is already taken');
        }

        clientsByPlayer[playerId] = socket.id;
        playersByClient[socket.id] = playerId;
        done(false);
    });

    socket.on('player-fire', function(data, done) {

        var room = roomByPlayer[data.playerId];
        var p1 = room.players[0];
        var p2 = room.players[1];
        var tag = getRandomTag();
        var client;

        console.log('player-fire', data, tag);

        if (data.playerId == p1.id) {
            client = clients[clientsByPlayer[p2.id]];
        } else {
            client = clients[clientsByPlayer[p1.id]];
        }

        if (client) {
            client.emit('player-fire', {angle: data.angle, tag: tag});
        }
        if (!client) {
            console.error('client not found');
            console.error(' - room', room);
            console.error(' - data', data);
        }

        done(false, tag);
    });

    socket.on('finish', function(data) {

        console.log('game-finish', data);
        var p1 = data.room.players[0];
        var p2 = data.room.players[1];
        var client;
        console.log(' - game-finish', p1, p2);

        if (p1.id == data.winnerID) {
            client = clients[clientsByPlayer[p2.id]];
        } else {
            client = clients[clientsByPlayer[p1.id]];
        }
        client.emit('finish', data.winnerID);
        removeRoom(data.room.id);
    });

    socket.on('play', function(room, done) {

        var p1 = room.players[0];
        var p2 = room.players[1];
        var maxRows = 3;
        var maxCols = 8;

        p1.grid = createGrid(maxRows, maxCols);
        p1.bubbles = createBubbles(3);

        p2.grid = createGrid(maxRows, maxCols);
        p2.bubbles = createBubbles(3);

        var p2Client = clients[clientsByPlayer[p2.id]];

        if (!p2Client) {
            console.error('play - error', p1, p2);
            return done('player 2 client not found', room);
        }

        p2Client.emit('play', room);

        console.log('play', p1.bubbles, p2.bubbles);

        done(false, room);
    });

    socket.on('get-rooms', function(data, done) {
        done(false, rooms);
    });

    socket.on('leave-room', function(data, done) {

        console.log('leave-room', data.player.id);
        var room = getRoom(data.room);

        if (!room) {
            return done('Room not found');
        }

        var p1 = room.players[0];
        var p2 = room.players[1];

        console.log('  - leave-room', data, room, clientsByPlayer);

        if (data.player.id == p1.id) {
            if (p2) {
                clients[clientsByPlayer[p2.id]].emit('host-close-room');
                delete roomByPlayer[p2.id];
            }
            delete roomByPlayer[p1.id];
            removeRoom(data.room);
            return done(false);
        }

        delete roomByPlayer[p2.id];
        room.players.pop();
        var hostClient = clients[clientsByPlayer[p1.id]];
        hostClient.emit('player-leave-room', room);
        done(false);
    });

    socket.on('join-room', function(data, done) {

        console.log('join-room', data.player.id);
        var room = getRoom(data.room);

        if (!room) {
            return done('Room not found');
        }

        if (room.players.length == 2) {
            return done('the room is full');
        }

        var p1 = room.players[0];
        room.players.push(data.player);
        console.log(' - join-room', room, p1);

        roomByPlayer[data.player.id] = room;
        var hostClient = clients[clientsByPlayer[p1.id]];

        if (!hostClient) {
            console.error('host client not found!');
            console.error(' - room', room);
            console.error(' - data', data);
            console.error(' - clientsByPlayer', clientsByPlayer);
            console.error(' - clients', Object.keys(clients));
            return done('host client not found!');
        }

        hostClient.emit('player-join-room', room);

        done(false, room);
    });

    socket.on('create-room', function(data, done) {

        console.log('create-room', data.player.id);
        var id = 'room-'+ (rooms.length < 10 ? '0'+rooms.length : rooms.length);
        var room = {
            id : id,
            name: data.name || id,
            host : data.player,
            players: [
                data.player,
            ],
            state : STATE_CREATED,
        }
        rooms.push(room);
        roomByPlayer[data.player.id] = room;
        done(false, room);

        socket.broadcast.emit('create-room');
    });

});

http.listen(PORT, function() {
    console.log('listening on ' + PORT);
});
<commit_msg>fixed<commit_after>var path = require('path');
var app = require('express')();
var http = require('http').createServer(app);
// var io = require('socket.io')(http, {origins: '*:*'});
var io = require('socket.io')(http, {origins: '*:*'});
var REQUEST_PATH = path.dirname(__dirname);

var clients = {};
var clientsByPlayer = {};
var playersByClient = {};
var rooms = [];
var roomByPlayer = {};

var PORT = 8080;
var TAGS = ['green', 'blue', 'yellow', 'red', 'magenta', 'orange'];
var STATE_CREATED = 'created';
var STATE_PLAYING = 'playing';

function getRoom(id)
{
    for (var i = 0, len = rooms.length; i < len; i++) {
        var room = rooms[i];
        if (room.id == id) {
            return room;
        }
    }
    return false;
}

function removeRoom(id)
{
    for (var i = 0, len = rooms.length; i < len; i++) {
        var room = rooms[i];
        if (room && room.id == id) {
            rooms.splice(i, 1);
        }
    }
    return false;
}

function getRandomInt(min, max)
{
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

function getRandomTag()
{
    return TAGS[getRandomInt(0, TAGS.length - 1)];
}

function createGrid(maxRows, maxCols)
{
    var grid = [];

    for(var row = 0; row < maxRows; row++) {

        grid[row] = [];
        var mod = row % 2 === 0;

        for (var col = 0; col < maxCols; col++) {

            // last col
            if (!mod && col >= maxCols - 1) {
                continue;
            }

            grid[row][col] = getRandomTag();
        }
    }

    return grid;
}

function createBubbles(len)
{
    var bubbles = [];

    for (var i = 0; i < len; i++) {
        bubbles.push(getRandomTag());
    }

    return bubbles;
}

// io.set('origins', '*:*');
//
// app.use(function (req, res, next) {
//     res.header("Access-Control-Allow-Origin", "*");
//     res.header("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With");
//     res.header("Access-Control-Allow-Methods", "GET, PUT, POST");
//     if ('OPTIONS' === req.method) {
//         res.status(204).send();
//     }
//     else {
//         next();
//     }
// });

io.on('connection', function(socket) {

    clients[socket.id] = socket;
    console.log('a user connected', Object.keys(clients).length, socket.id);

    socket.on('disconnect', function() {

        console.log('a user disconnect', playersByClient[socket.id], Object.keys(clients).length, socket.id);

        var playerId = playersByClient[socket.id];

        for (var i = 0, len = rooms.length; i < len; i++) {

            var room = rooms[i];

            if (!room) {
                continue;
            }

            var p1 = room.players[0];
            var p2 = room.players[1];

            if (p1.id == playerId) {
                if (p2) {
                    var p2Client = clients[clientsByPlayer[p2.id]];

                    if (p2Client) {
                        p2Client.emit('host-close-room');
                    }
                }
                removeRoom(room.id);
                break;
            }

            if (p2 && p2.id == playerId) {
                room.players.pop();
                var p1Client = clients[clientsByPlayer[p1.id]];
                if (p1Client) {
                    p1Client.emit('player-leave-room', room);
                }
                break;
            }
        }

        delete clientsByPlayer[playerId];
        delete playersByClient[socket.id];
        delete clients[socket.id];
    });

    socket.on('join', function(playerId, done) {

        console.log('join', playerId);

        if (clientsByPlayer[playerId]) {
            return done('Nickname '+ playerId +' is already taken');
        }

        clientsByPlayer[playerId] = socket.id;
        playersByClient[socket.id] = playerId;
        done(false);
    });

    socket.on('player-fire', function(data, done) {

        var room = roomByPlayer[data.playerId];
        var p1 = room.players[0];
        var p2 = room.players[1];
        var tag = getRandomTag();
        var client;

        console.log('player-fire', data, tag);

        if (data.playerId == p1.id) {
            client = clients[clientsByPlayer[p2.id]];
        } else {
            client = clients[clientsByPlayer[p1.id]];
        }

        if (client) {
            client.emit('player-fire', {angle: data.angle, tag: tag});
        }
        if (!client) {
            console.error('client not found');
            console.error(' - room', room);
            console.error(' - data', data);
            console.error(' - clientsByPlayer', clientsByPlayer);
            console.error(' - clients', Object.keys(clients));
        }

        done(false, tag);
    });

    socket.on('finish', function(data) {

        console.log('game-finish', data);
        var p1 = data.room.players[0];
        var p2 = data.room.players[1];
        var client;
        console.log(' - game-finish', p1, p2);

        if (p1.id == data.winnerID) {
            client = clients[clientsByPlayer[p2.id]];
        } else {
            client = clients[clientsByPlayer[p1.id]];
        }
        client.emit('finish', data.winnerID);
        removeRoom(data.room.id);
    });

    socket.on('play', function(room, done) {

        var p1 = room.players[0];
        var p2 = room.players[1];
        var maxRows = 3;
        var maxCols = 8;

        p1.grid = createGrid(maxRows, maxCols);
        p1.bubbles = createBubbles(3);

        p2.grid = createGrid(maxRows, maxCols);
        p2.bubbles = createBubbles(3);

        var p2Client = clients[clientsByPlayer[p2.id]];

        if (!p2Client) {
            console.error('play - error', p1, p2);
            return done('player 2 client not found', room);
        }

        p2Client.emit('play', room);

        console.log('play', p1.bubbles, p2.bubbles);

        done(false, room);
    });

    socket.on('get-rooms', function(data, done) {
        done(false, rooms);
    });

    socket.on('leave-room', function(data, done) {

        console.log('leave-room', data.player.id);
        var room = getRoom(data.room);

        if (!room) {
            return done('Room not found');
        }

        var p1 = room.players[0];
        var p2 = room.players[1];

        console.log('  - leave-room', data, room, clientsByPlayer);

        if (data.player.id == p1.id) {
            if (p2) {
                clients[clientsByPlayer[p2.id]].emit('host-close-room');
                delete roomByPlayer[p2.id];
            }
            delete roomByPlayer[p1.id];
            removeRoom(data.room);
            return done(false);
        }

        delete roomByPlayer[p2.id];
        room.players.pop();
        var hostClient = clients[clientsByPlayer[p1.id]];
        hostClient.emit('player-leave-room', room);
        done(false);
    });

    socket.on('join-room', function(data, done) {

        console.log('join-room', data.player.id);
        var room = getRoom(data.room);

        if (!room) {
            return done('Room not found');
        }

        if (room.players.length == 2) {
            return done('the room is full');
        }

        var p1 = room.players[0];
        room.players.push(data.player);
        console.log(' - join-room', room, p1);

        roomByPlayer[data.player.id] = room;
        var hostClient = clients[clientsByPlayer[p1.id]];

        if (!hostClient) {
            console.error('host client not found!');
            console.error(' - room', room);
            console.error(' - data', data);
            console.error(' - clientsByPlayer', clientsByPlayer);
            console.error(' - clients', Object.keys(clients));
            return done('host client not found!');
        }

        hostClient.emit('player-join-room', room);

        done(false, room);
    });

    socket.on('create-room', function(data, done) {

        console.log('create-room', data.player.id);
        var id = 'room-'+ (rooms.length < 10 ? '0'+rooms.length : rooms.length);
        var room = {
            id : id,
            name: data.name || id,
            host : data.player,
            players: [
                data.player,
            ],
            state : STATE_CREATED,
        }
        rooms.push(room);
        roomByPlayer[data.player.id] = room;
        done(false, room);

        socket.broadcast.emit('create-room');
    });

});

http.listen(PORT, function() {
    console.log('listening on ' + PORT);
});
<|endoftext|>