<commit_before>'use strict'

const express = require('express')
const Slapp = require('slapp')
const ConvoStore = require('slapp-convo-beepboop')
const Context = require('slapp-context-beepboop')

// use `PORT` env var on Beep Boop - default to 3000 locally
var port = process.env.PORT || 3000

var slapp = Slapp({
  // Beep Boop sets the SLACK_VERIFY_TOKEN env var
  verify_token: process.env.SLACK_VERIFY_TOKEN,
  convo_store: ConvoStore(),
  context: Context()
})

var startTeaState = false
var teaUsers = []

var HELP_TEXT = `
I will respond to the following messages:
\`help\` - to see this message.
\`hi\` - to demonstrate a conversation that tracks state.
\`thanks\` - to demonstrate a simple response.
\`<type-any-other-text>\` - to demonstrate a random emoticon response, some of the time :wink:.
\`attachment\` - to see a Slack attachment message.
`

//*********************************************
// Setup different handlers for messages
//*********************************************

// response to the user typing "help"
slapp.message('help', ['mention', 'direct_message', 'ambient'], (msg) => {
  msg.say(HELP_TEXT)
})

slapp.message('^(me|yes|y|ye|yeah)$',['ambient', 'mention'], (msg) => {
  if (startTeaState) {
    teaUsers.push(msg.body.event.user)
    var user = '<@' + msg.body.event.user + '>'
    msg.say('ok - ' + user + ' is in')
    //array.push(item.id);
  }
})

slapp.message('^(tea|t|:tea:)$',['ambient', 'mention'], (msg) => {
  if (startTeaState) {
    msg.say('already started')
    //startTeaState = false
  } else {
    teaUsers.length = 0
    teaUsers.push(msg.body.event.user)
    var user = '<@' + msg.body.event.user + '>'
    msg.say('<!here> time for tea!!! - who wants in? ' + user + ' is')
    //msg.say('<!user> is in')
    //msg.say('<@user> is in 2')
    //msg.say(user + ' is i')
    startTeaState = true

    setTimeout(() => {
    msg.say('30 seconds left - any one else?')
      setTimeout(() => {
        startTeaState = false
        if (teaUsers.length != 0) {
          var teaMakerId = teaUsers[Math.floor(Math.random()*teaUsers.length)]
          var teaMaker = '<@' + teaMakerId + '>'
          // remove duplicates from array
          var uniqueNames = [];
          teaUsers.forEach(function(element) {
            var foundInUnique = false
            uniqueNames.forEach(function(element2) {
              if (element == element2) {
                foundInUnique = true
              }
            })
            if (foundInUnique == false) {
              uniqueNames.push(element)
            }
          })
          if (uniqueNames.length > 1) {
            var listOfDrinkers = ''
            uniqueNames.forEach(function(element) {
              if (element != teaMakerId) {
                listOfDrinkers = listOfDrinkers + '<@' + element + '> '
              }
            })
            if (listOfDrinkers == '') {
              // making it for themselves
              msg.say(teaMaker + ' you\'re making tea for yourself')
            } else {
              msg.say(teaMaker + ' you\'re making tea for ' + uniqueNames.length + ' people: ' + listOfDrinkers + 'and yourself')
            }
          } else {
            msg.say(teaMaker + ' you\'re making tea for yourself')
          }
        }
  }, 30000)
  }, 30000)
    //teaUsers
  }
  })

/*
// "Conversation" flow that tracks state - kicks off when user says hi, hello or hey
slapp
  .message('^(hi|hello|hey)$', ['direct_mention', 'direct_message'], (msg, text) => {
    msg
      .say(`${text}, how are you?`)
      // sends next event from user to this route, passing along state
      .route('how-are-you', { greeting: text })
  })
  .route('how-are-you', (msg, state) => {
    var text = (msg.body.event && msg.body.event.text) || ''

    // user may not have typed text as their next action, ask again and re-route
    if (!text) {
      return msg
        .say("Whoops, I'm still waiting to hear how you're doing.")
        .say('How are you?')
        .route('how-are-you', state)
    }

    // add their response to state
    state.status = text

    msg
      .say(`Ok then. What's your favorite color?`)
      .route('color', state)
  })
  .route('color', (msg, state) => {
    var text = (msg.body.event && msg.body.event.text) || ''

    // user may not have typed text as their next action, ask again and re-route
    if (!text) {
      return msg
        .say("I'm eagerly awaiting to hear your favorite color.")
        .route('color', state)
    }

    // add their response to state
    state.color = text

    msg
      .say('Thanks for sharing.')
      .say(`Here's what you've told me so far: \`\`\`${JSON.stringify(state)}\`\`\``)
    // At this point, since we don't route anywhere, the "conversation" is over
  })*/
/*
// Can use a regex as well
slapp.message(/^(thanks|thank you)/i, ['mention', 'direct_message'], (msg) => {
  // You can provide a list of responses, and a random one will be chosen
  // You can also include slack emoji in your responses
  msg.say([
    "You're welcome :smile:",
    'You bet',
    ':+1: Of course',
    'Anytime :sun_with_face: :full_moon_with_face:'
  ])
})*/

// demonstrate returning an attachment...
slapp.message('attachment', ['mention', 'direct_message'], (msg) => {
  msg.say({
    text: 'Check out this amazing attachment! :confetti_ball: ',
    attachments: [{
      text: 'Slapp is a robust open source library that sits on top of the Slack APIs',
      title: 'Slapp Library - Open Source',
      image_url: 'https://storage.googleapis.com/beepboophq/_assets/bot-1.22f6fb.png',
      title_link: 'https://beepboophq.com/',
      color: '#7CD197'
    }]
  })
})
/*
// Catch-all for any other responses not handled above
slapp.message('.*', ['direct_mention', 'direct_message'], (msg) => {
  // respond only 40% of the time
  if (Math.random() < 0.4) {
    msg.say([':wave:', ':pray:', ':raised_hands:'])
  }
})*/

// attach Slapp to express server
var server = slapp.attachToExpress(express())

// start http server
server.listen(port, (err) => {
  if (err) {
    return console.error(err)
  }

  console.log(`Listening on port ${port}`)
})
<commit_msg>change limit to two mins<commit_after>'use strict'

const express = require('express')
const Slapp = require('slapp')
const ConvoStore = require('slapp-convo-beepboop')
const Context = require('slapp-context-beepboop')

// use `PORT` env var on Beep Boop - default to 3000 locally
var port = process.env.PORT || 3000

var slapp = Slapp({
  // Beep Boop sets the SLACK_VERIFY_TOKEN env var
  verify_token: process.env.SLACK_VERIFY_TOKEN,
  convo_store: ConvoStore(),
  context: Context()
})

var startTeaState = false
var teaUsers = []

var HELP_TEXT = `
I will respond to the following messages:
\`help\` - to see this message.
\`hi\` - to demonstrate a conversation that tracks state.
\`thanks\` - to demonstrate a simple response.
\`<type-any-other-text>\` - to demonstrate a random emoticon response, some of the time :wink:.
\`attachment\` - to see a Slack attachment message.
`

//*********************************************
// Setup different handlers for messages
//*********************************************

// response to the user typing "help"
slapp.message('help', ['mention', 'direct_message', 'ambient'], (msg) => {
  msg.say(HELP_TEXT)
})

slapp.message('^(me|yes|y|ye|yeah)$',['ambient', 'mention'], (msg) => {
  if (startTeaState) {
    teaUsers.push(msg.body.event.user)
    var user = '<@' + msg.body.event.user + '>'
    msg.say('ok - ' + user + ' is in')
    //array.push(item.id);
  }
})

slapp.message('^(tea|t|:tea:)$',['ambient', 'mention'], (msg) => {
  if (startTeaState) {
    msg.say('already started')
    //startTeaState = false
  } else {
    teaUsers.length = 0
    teaUsers.push(msg.body.event.user)
    var user = '<@' + msg.body.event.user + '>'
    msg.say('<!here> time for tea!!! - who wants in? ' + user + ' is')
    //msg.say('<!user> is in')
    //msg.say('<@user> is in 2')
    //msg.say(user + ' is i')
    startTeaState = true

    setTimeout(() => {
    msg.say('1 minute left - any one else?')
      setTimeout(() => {
        startTeaState = false
        if (teaUsers.length != 0) {
          var teaMakerId = teaUsers[Math.floor(Math.random()*teaUsers.length)]
          var teaMaker = '<@' + teaMakerId + '>'
          // remove duplicates from array
          var uniqueNames = [];
          teaUsers.forEach(function(element) {
            var foundInUnique = false
            uniqueNames.forEach(function(element2) {
              if (element == element2) {
                foundInUnique = true
              }
            })
            if (foundInUnique == false) {
              uniqueNames.push(element)
            }
          })
          if (uniqueNames.length > 1) {
            var listOfDrinkers = ''
            uniqueNames.forEach(function(element) {
              if (element != teaMakerId) {
                listOfDrinkers = listOfDrinkers + '<@' + element + '> '
              }
            })
            if (listOfDrinkers == '') {
              // making it for themselves
              msg.say(teaMaker + ' you\'re making tea for yourself')
            } else {
              msg.say(teaMaker + ' you\'re making tea for ' + uniqueNames.length + ' people: ' + listOfDrinkers + 'and yourself')
            }
          } else {
            msg.say(teaMaker + ' you\'re making tea for yourself')
          }
        }
  }, 60000)
  }, 60000)
    //teaUsers
  }
  })

/*
// "Conversation" flow that tracks state - kicks off when user says hi, hello or hey
slapp
  .message('^(hi|hello|hey)$', ['direct_mention', 'direct_message'], (msg, text) => {
    msg
      .say(`${text}, how are you?`)
      // sends next event from user to this route, passing along state
      .route('how-are-you', { greeting: text })
  })
  .route('how-are-you', (msg, state) => {
    var text = (msg.body.event && msg.body.event.text) || ''

    // user may not have typed text as their next action, ask again and re-route
    if (!text) {
      return msg
        .say("Whoops, I'm still waiting to hear how you're doing.")
        .say('How are you?')
        .route('how-are-you', state)
    }

    // add their response to state
    state.status = text

    msg
      .say(`Ok then. What's your favorite color?`)
      .route('color', state)
  })
  .route('color', (msg, state) => {
    var text = (msg.body.event && msg.body.event.text) || ''

    // user may not have typed text as their next action, ask again and re-route
    if (!text) {
      return msg
        .say("I'm eagerly awaiting to hear your favorite color.")
        .route('color', state)
    }

    // add their response to state
    state.color = text

    msg
      .say('Thanks for sharing.')
      .say(`Here's what you've told me so far: \`\`\`${JSON.stringify(state)}\`\`\``)
    // At this point, since we don't route anywhere, the "conversation" is over
  })*/
/*
// Can use a regex as well
slapp.message(/^(thanks|thank you)/i, ['mention', 'direct_message'], (msg) => {
  // You can provide a list of responses, and a random one will be chosen
  // You can also include slack emoji in your responses
  msg.say([
    "You're welcome :smile:",
    'You bet',
    ':+1: Of course',
    'Anytime :sun_with_face: :full_moon_with_face:'
  ])
})*/

// demonstrate returning an attachment...
slapp.message('attachment', ['mention', 'direct_message'], (msg) => {
  msg.say({
    text: 'Check out this amazing attachment! :confetti_ball: ',
    attachments: [{
      text: 'Slapp is a robust open source library that sits on top of the Slack APIs',
      title: 'Slapp Library - Open Source',
      image_url: 'https://storage.googleapis.com/beepboophq/_assets/bot-1.22f6fb.png',
      title_link: 'https://beepboophq.com/',
      color: '#7CD197'
    }]
  })
})
/*
// Catch-all for any other responses not handled above
slapp.message('.*', ['direct_mention', 'direct_message'], (msg) => {
  // respond only 40% of the time
  if (Math.random() < 0.4) {
    msg.say([':wave:', ':pray:', ':raised_hands:'])
  }
})*/

// attach Slapp to express server
var server = slapp.attachToExpress(express())

// start http server
server.listen(port, (err) => {
  if (err) {
    return console.error(err)
  }

  console.log(`Listening on port ${port}`)
})
<|endoftext|>


<commit_before>var express = require('express'), app = express()
, http = require('http')
, server = http.createServer(app).listen(process.env.PORT || 3000)
, io = require('socket.io').listen(server);
var jade = require('jade');

app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.set("view options", { layout: false });
app.configure(function() {
    app.use(express.static(__dirname + '/public'));
    app.use(express.urlencoded());
    app.use(app.router);

});

//usersList: id -> username
//usersListr: username -> id
var usersList = new Array();
var usersListr = new Array();

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

    //TODO: bug connect with valid username, shutdown server, restart server, username is now null
    socket.set('username', username);
    console.log('User ' + username + ' connected');

    if (typeof username !== 'undefined' && typeof username != null) {
        usersList[socket.id] = username;
        usersListr[username] = socket.id;
    }

    io.sockets.emit('loadUsersList', {'roomName' : 'Lobby', 'usernamesList' : getUsernamesList("Lobby")});
    io.sockets.emit('numConnected', {'numConnected' : io.sockets.clients().length});

    socket.emit('updateRoomsList', getUserRoomList(socket));

    console.log(io.sockets.clients().length + ' connected');

    socket.on('sendMessage', function (clientData) {
        socket.get('username', function (error, name) {
            var data = { 'message' : clientData.messageBody, 'username' : name, 'roomName' : clientData.messageRoom};
            if (clientData.messageRoom == "Lobby") {
                socket.broadcast.to('').emit('sendMessageResponse', data);
            }
            else {
                console.log("broadcast room: " + clientData.messageRoom);
                socket.broadcast.to(clientData.messageRoom).emit('sendMessageResponse', data);
            }

            console.log('user ' + name + ' send this : ' + clientData.messageBody + " to room: " + clientData.messageRoom);
        });
    });

    socket.on('createRoom', function (roomName) {
        socket.get('username', function (error, name) {
            var created = false;
            var errorCode = 0;
            if(!isValidString(roomName)) {
                errorCode = 1;
            }
            else if (typeof io.sockets.manager.rooms['/' + roomName] !== 'undefined') {
                errorCode = 2;
            }
            else if (roomName == "Lobby") {
                errorCode = 3;
            }
            else {
                console.log("User " + name + " created room name: " + roomName);
                created = true;
            }
            var data = {'created' : created, 'roomName' : roomName, 'errorCode' : errorCode};
            socket.emit('createRoomResponse', data);

        });
    });

    socket.on('joinRoom', function (roomName) {
        socket.get('username', function (error, username) {
            socket.join(roomName);

            socket.emit('updateRoomsList', getUserRoomList(socket));
            console.log("sending room list to client: " + getUserRoomList(socket));

            io.sockets.in(roomName).emit('loadUsersList', {'roomName' : roomName, 'usernamesList' : getUsernamesList(roomName)});
            console.log("Added user: " + username + " to room: " + roomName);
            console.log("User is in rooms: ");
            console.log(io.roomClients[socket.id]);
        });
    });

    socket.on('leaveRoom', function (roomName) {
        socket.get('username', function (error, username) {
            socket.leave(roomName);

            socket.emit('updateRoomsList', getUserRoomList(socket));

            io.sockets.in(roomName).emit('loadUsersList', {'roomName' : roomName, 'usernamesList' : getUsernamesList(roomName)});
            console.log("Removed user: " + username + " from room: " + roomName);
            console.log("User is in rooms: ");
            console.log(io.sockets.manager.roomClients[socket.id]);
        });
    });

    //data.username: who to invite
    //data.roomName: the room to invite to
    socket.on('inviteUser', function (data) {
        socket.get('username', function (error, username) {
            //TODO notify the target client with a modal
            //do data validation here
            //cannot invite youself, cannot invite someone already in room
            if (data.username != username && !io.sockets.manager.roomClients[usersListr[data.username]]["/" + data.roomName]) {
                io.sockets.socket(usersListr[data.username]).emit('roomInvite', {'inviter' : username, 'roomName' : data.roomName});
            }
            else {
                console.log("Cannot invite user: " + data.username + " to room: " + data.roomName);
                //TODO emit a message to the socket of an error
            }
        });
    });

    socket.on('acceptInvitation', function (roomName) {
        var data = {'created' : true, 'roomName' : roomName, 'errorCode' : 0};
        socket.emit('createRoomResponse', data);
    });

    socket.on('disconnect', function() {
        socket.get('username', function (error, username) {
            console.log('User ' + username + ' has disconnected');
            io.sockets.emit('numConnected', {'numConnected' : io.sockets.clients().length});

            for (room in io.sockets.manager.roomClients[socket.id]) {
                socket.leave(room);
                console.log("Leaving room: " + room);

                if (room == "") {
                    console.log("Broadcasting to Lobby");
                    socket.broadcast.to(room).emit('loadUsersList', getUsernamesList(''));
                }
                else {
                    console.log("Broadcasting to room:" + room);
                    socket.broadcast.to(room).emit('loadUsersList', getUsernamesList(room.substring(1)));
                }

                console.log(io.sockets.manager.roomClients[socket.id]);
            }

            console.log("usersList was ");
            console.log(usersList);
            delete usersListr[usersList[socket.id]]
            delete usersList[socket.id];
            console.log("usersList is now ");
            console.log(usersList);

            for (room in io.sockets.manager.roomClients[socket.id]) {
                if(room == "") {
                    io.sockets.emit('loadUsersList', {'roomName' : 'Lobby', 'usernamesList' : getUsernamesList("Lobby")});
                }
                else {
                    io.sockets.emit('loadUsersList', {'roomName' : room.substring(1), 'usernamesList' : getUsernamesList(room.substring(1))});
                }
            }
        });
    });
});

//Determines whether the given string is a proper username or room
//alphanumeric + underscore + hyphen
//TODO provide support for spaces?
function isValidString (string) {
    var valid = /^[a-zA-Z0-9-_]*$/.test(string) ? true : false;
    return valid;
}

//given a room, generate a list of usernames that represent users in that room
function getUsernamesList(room) {
    var usernamesList = new Array();
    if(room == "Lobby" || room == "") {
        for (var i = 0 ; i < io.sockets.clients().length ; i++) {
            if(usersList[io.sockets.clients()[i].id]) {
                usernamesList.push(usersList[io.sockets.clients()[i].id]);
            }
        }
    }
    else {
        for (var i = 0 ; i < io.sockets.clients(room).length ; i++) {
            if(usersList[io.sockets.clients()[i].id]) {
                usernamesList.push(usersList[io.sockets.clients(room)[i].id]);
            }
        }
    }
    return usernamesList;
}

function getUserRoomList(socket) {
    var roomList = new Array();
    for (room in io.sockets.manager.roomClients[socket.id]) {
        if(room == "") {
            roomList.push("Lobby");
        }
        else {
            roomList.push(room.substring(1));
        }
    }
    return roomList;
}

var username;
app.post('/main', function(req, res){
    console.log("POST Request made to " + '/main');
    username = req.body.username;
    if(isValidString(username) && !usersListr[username]) {
        console.log("User logged in as " + username);
        res.render('main.jade');
    }
    else {
        res.render('login.jade', {"usernameInvalid": true});
    }
});

app.get('/main', function(req, res){
    console.log("GET Request made to " + '/main');
    res.render('login.jade');
});

app.get('/', function(req, res){
    console.log("GET Request made to " + '/');
    res.render('login.jade');
});
<commit_msg>Fixed up logging messages<commit_after>var express = require('express'), app = express()
, http = require('http')
, server = http.createServer(app).listen(process.env.PORT || 3000)
, io = require('socket.io').listen(server);

io.set('log level', 1);

var jade = require('jade');

app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.set("view options", { layout: false });
app.configure(function() {
    app.use(express.static(__dirname + '/public'));
    app.use(express.urlencoded());
    app.use(app.router);

});

//usersList: id -> username
//usersListr: username -> id
var usersList = new Array();
var usersListr = new Array();

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

    //TODO: bug connect with valid username, shutdown server, restart server, username is now null
    socket.set('username', username);
    console.log('User ' + username + ' connected');

    if (typeof username !== 'undefined' && typeof username != null) {
        usersList[socket.id] = username;
        usersListr[username] = socket.id;
    }

    io.sockets.emit('loadUsersList', {'roomName' : 'Lobby', 'usernamesList' : getUsernamesList("Lobby")});
    io.sockets.emit('numConnected', {'numConnected' : io.sockets.clients().length});

    socket.emit('updateRoomsList', getUserRoomList(socket));

    console.log(io.sockets.clients().length + ' connected');

    socket.on('sendMessage', function (clientData) {
        socket.get('username', function (error, name) {
            var data = { 'message' : clientData.messageBody, 'username' : name, 'roomName' : clientData.messageRoom};
            if (clientData.messageRoom == "Lobby") {
                socket.broadcast.to('').emit('sendMessageResponse', data);
            }
            else {
                socket.broadcast.to(clientData.messageRoom).emit('sendMessageResponse', data);
            }

            console.log('User ' + name + ' send this : ' + clientData.messageBody + " to room: " + clientData.messageRoom);
        });
    });

    socket.on('createRoom', function (roomName) {
        socket.get('username', function (error, name) {
            var created = false;
            var errorCode = 0;
            if(!isValidString(roomName)) {
                errorCode = 1;
            }
            else if (typeof io.sockets.manager.rooms['/' + roomName] !== 'undefined') {
                errorCode = 2;
            }
            else if (roomName == "Lobby") {
                errorCode = 3;
            }
            else {
                console.log("User " + name + " created room name: " + roomName);
                created = true;
            }
            var data = {'created' : created, 'roomName' : roomName, 'errorCode' : errorCode};
            socket.emit('createRoomResponse', data);

        });
    });

    socket.on('joinRoom', function (roomName) {
        socket.get('username', function (error, username) {
            socket.join(roomName);

            socket.emit('updateRoomsList', getUserRoomList(socket));

            io.sockets.in(roomName).emit('loadUsersList', {'roomName' : roomName, 'usernamesList' : getUsernamesList(roomName)});
            console.log("Added user: " + username + " to room: " + roomName);
            console.log("User: " + username + " is in rooms: ");
            console.log(io.roomClients[socket.id]);
        });
    });

    socket.on('leaveRoom', function (roomName) {
        socket.get('username', function (error, username) {
            socket.leave(roomName);

            socket.emit('updateRoomsList', getUserRoomList(socket));

            io.sockets.in(roomName).emit('loadUsersList', {'roomName' : roomName, 'usernamesList' : getUsernamesList(roomName)});
            console.log("Removed user: " + username + " from room: " + roomName);
            console.log("User: " + username + " is in rooms: ");
            console.log(io.sockets.manager.roomClients[socket.id]);
        });
    });

    //data.username: who to invite
    //data.roomName: the room to invite to
    socket.on('inviteUser', function (data) {
        socket.get('username', function (error, username) {
            //TODO notify the target client with a modal
            //do data validation here
            //cannot invite youself, cannot invite someone already in room
            if (data.username != username && !io.sockets.manager.roomClients[usersListr[data.username]]["/" + data.roomName]) {
                io.sockets.socket(usersListr[data.username]).emit('roomInvite', {'inviter' : username, 'roomName' : data.roomName});
            }
            else {
                console.log("Cannot invite user: " + data.username + " to room: " + data.roomName);
                //TODO emit a message to the socket of an error
            }
        });
    });

    socket.on('acceptInvitation', function (roomName) {
        var data = {'created' : true, 'roomName' : roomName, 'errorCode' : 0};
        socket.emit('createRoomResponse', data);
    });

    socket.on('disconnect', function() {
        socket.get('username', function (error, username) {
            console.log('User ' + username + ' has disconnected');
            io.sockets.emit('numConnected', {'numConnected' : io.sockets.clients().length});

            for (room in io.sockets.manager.roomClients[socket.id]) {
                socket.leave(room);

                if (room == "") {
                    socket.broadcast.to(room).emit('loadUsersList', getUsernamesList(''));
                }
                else {
                    socket.broadcast.to(room).emit('loadUsersList', getUsernamesList(room.substring(1)));
                }
            }

            console.log("usersList was ");
            console.log(usersList);
            delete usersListr[usersList[socket.id]]
            delete usersList[socket.id];
            console.log("usersList is now ");
            console.log(usersList);

            for (room in io.sockets.manager.roomClients[socket.id]) {
                if(room == "") {
                    io.sockets.emit('loadUsersList', {'roomName' : 'Lobby', 'usernamesList' : getUsernamesList("Lobby")});
                }
                else {
                    io.sockets.emit('loadUsersList', {'roomName' : room.substring(1), 'usernamesList' : getUsernamesList(room.substring(1))});
                }
            }
        });
    });
});

//Determines whether the given string is a proper username or room
//alphanumeric + underscore + hyphen
//TODO provide support for spaces?
function isValidString (string) {
    var valid = /^[a-zA-Z0-9-_]*$/.test(string) ? true : false;
    return valid;
}

//given a room, generate a list of usernames that represent users in that room
function getUsernamesList(room) {
    var usernamesList = new Array();
    if(room == "Lobby" || room == "") {
        for (var i = 0 ; i < io.sockets.clients().length ; i++) {
            if(usersList[io.sockets.clients()[i].id]) {
                usernamesList.push(usersList[io.sockets.clients()[i].id]);
            }
        }
    }
    else {
        for (var i = 0 ; i < io.sockets.clients(room).length ; i++) {
            if(usersList[io.sockets.clients()[i].id]) {
                usernamesList.push(usersList[io.sockets.clients(room)[i].id]);
            }
        }
    }
    return usernamesList;
}

function getUserRoomList(socket) {
    var roomList = new Array();
    for (room in io.sockets.manager.roomClients[socket.id]) {
        if(room == "") {
            roomList.push("Lobby");
        }
        else {
            roomList.push(room.substring(1));
        }
    }
    return roomList;
}

var username;
app.post('/main', function(req, res){
    console.log("POST Request made to " + '/main');
    username = req.body.username;
    if(isValidString(username) && !usersListr[username]) {
        console.log("User logged in as " + username);
        res.render('main.jade');
    }
    else {
        res.render('login.jade', {"usernameInvalid": true});
    }
});

app.get('/main', function(req, res){
    console.log("GET Request made to " + '/main');
    res.render('login.jade');
});

app.get('/', function(req, res){
    console.log("GET Request made to " + '/');
    res.render('login.jade');
});
<|endoftext|>


<commit_before>/*The MIT License (MIT)

Copyright (c) [2015] [Andros Chu-Meng Yang]

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.

Dear reader who either skipped the entire reading of the license or actually read it
to those whom it may concern server.js is the most up-to-date and complete early and cleaner rewrite compared
to index.js. Client.html's script was also a clean re-write early one
that is all*/

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var url = require('url');

//List of rooms and their descriptions
var roomList = {};

//key - room : pair - chatlog of room in array form
var roomChatLogs = {};

//Key - room : pair - array of user list for room
var roomConnectedUsers = {};

//Key - room :: pair - how many hours are remaining for the room
var roomLives = {};

  app.get('/', function(req, res){
        if(req.query.renewRoom != null){
            roomLives[removeQuotes(req.query.renewRoom)] = 24;
            console.log("Renewing room "  + removeQuotes(req.query.renewRoom));
            res.sendFile(__dirname + '/renew.html');
            return;
        }

        if(req.query.createRoom != null){
          createRoom(removeQuotes(req.query.createRoom),
            removeQuotes(req.query.description),
            removeQuotes(req.query.lifetime));
            //Redirect the user to the room they just created
            res.statusCode = 302;
            res.setHeader("Location", '/?room=' + req.query.createRoom + '"');
            res.end();
        }
        res.sendFile(__dirname + '/client.html');
  });

    //TODO remove createroom default
    createRoom('developer', 'testing room for tests of testacular tests', 2);
    expirationManager();

  io.on('connection', function(socket){
    socket.on('UserConnectionAttempt', function(room, nickname){
      //Meaninless debug
      console.log('User ' + nickname + ' is attempting to connect to ' +
        'room ' + room + ' from ip ' + socket.handshake.address);
      if(!hastableContains(roomList, room)){
        socket.emit('UserConnectionFailed', "roomNonExistant");
        return;
      }

      socket.join(room);
      //Tell the room who has walked in ;)
      sendServerMessage(nickname + " has joined room " + room, room);
      io.to(room).emit('userJoin', nickname);
      socket.emit('init', roomChatLogs[room], roomConnectedUsers[room], roomList[room]);
      //get userList array and push
      roomConnectedUsers[room].push(nickname);

      socket.on('disconnect', function(){
        //if the room was already destroyed
        if(roomConnectedUsers[room] == null)
          return;

        var userList = roomConnectedUsers[room];
        userList = removeElement(nickname, userList);
        roomConnectedUsers[room] = userList;
        io.to(room).emit('userLeave', userList, nickname);
      });
    });
    socket.on('OnChatMessage', function(room, message, nickname){
      sendChatMessage(message, room, nickname);
    });

  });
//process.env.PORT is used by heroku
  http.listen(process.env.PORT || 5000), function(){
    console.log('listening on *:5000');
  });

  function createRoom(room, description, expiration){
    if(expiration > 48)
      expiration = 48;

    if(hastableContains(roomList, room))
      return;

    console.log('Creating new room ' + room);
    roomChatLogs[room] = [];
    roomConnectedUsers[room] = [];
    roomList[room] = description;
    roomLives[room] = expiration;
  }

  function removeElement(target, array){
    var i = array.indexOf(target);
    if(i != -1) {
      array.splice(i, 1);
    }
    return array;
  }

  function expirationManager(){
    setInterval(function(){
      console.log('Running the expiration cycle');
      for (var key in roomLives) {
        roomLives[key] -= 1;
        if(roomLives[key] <= 0){
          console.log("Room " + key + " has expired");
          io.emit()
          delete roomLives[key];
          delete roomChatLogs[key];
          delete roomList[key];
          delete roomConnectedUsers[key];
          io.to(key).emit('OnRoomExpire');
        }
      };
    }, 600000);
  }

  function sendServerMessage(message, room){
    io.to(room).emit('serverMessage', message);
  }

  function sendChatMessage(message, room, nickname){
    var timestamp = getTimestamp();
    console.log(nickname + ' : ' + message + ' @ ' + timestamp);
    io.to(room).emit('chatMessage', message, nickname, timestamp);
    roomChatLogs[room].push(message + "," + nickname + "," + timestamp);
  }

  function getTimestamp(){
    return new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '')
  }

  function hastableContains(hastable, value){
    return value in hastable;
  }

  function removeQuotes(string){
    if(string == null)
      return;

   return string.replace(new RegExp('"', 'g'), '');
  }<commit_msg>Heroku<commit_after>/*The MIT License (MIT)

Copyright (c) [2015] [Andros Chu-Meng Yang]

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.

Dear reader who either skipped the entire reading of the license or actually read it
to those whom it may concern server.js is the most up-to-date and complete early and cleaner rewrite compared
to index.js. Client.html's script was also a clean re-write early one
that is all*/

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var url = require('url');

//List of rooms and their descriptions
var roomList = {};

//key - room : pair - chatlog of room in array form
var roomChatLogs = {};

//Key - room : pair - array of user list for room
var roomConnectedUsers = {};

//Key - room :: pair - how many hours are remaining for the room
var roomLives = {};

  app.get('/', function(req, res){
        if(req.query.renewRoom != null){
            roomLives[removeQuotes(req.query.renewRoom)] = 24;
            console.log("Renewing room "  + removeQuotes(req.query.renewRoom));
            res.sendFile(__dirname + '/renew.html');
            return;
        }

        if(req.query.createRoom != null){
          createRoom(removeQuotes(req.query.createRoom),
            removeQuotes(req.query.description),
            removeQuotes(req.query.lifetime));
            //Redirect the user to the room they just created
            res.statusCode = 302;
            res.setHeader("Location", '/?room=' + req.query.createRoom + '"');
            res.end();
        }
        res.sendFile(__dirname + '/client.html');
  });

    //TODO remove createroom default
    createRoom('developer', 'testing room for tests of testacular tests', 2);
    expirationManager();

  io.on('connection', function(socket){
    socket.on('UserConnectionAttempt', function(room, nickname){
      //Meaninless debug
      console.log('User ' + nickname + ' is attempting to connect to ' +
        'room ' + room + ' from ip ' + socket.handshake.address);
      if(!hastableContains(roomList, room)){
        socket.emit('UserConnectionFailed', "roomNonExistant");
        return;
      }

      socket.join(room);
      //Tell the room who has walked in ;)
      sendServerMessage(nickname + " has joined room " + room, room);
      io.to(room).emit('userJoin', nickname);
      socket.emit('init', roomChatLogs[room], roomConnectedUsers[room], roomList[room]);
      //get userList array and push
      roomConnectedUsers[room].push(nickname);

      socket.on('disconnect', function(){
        //if the room was already destroyed
        if(roomConnectedUsers[room] == null)
          return;

        var userList = roomConnectedUsers[room];
        userList = removeElement(nickname, userList);
        roomConnectedUsers[room] = userList;
        io.to(room).emit('userLeave', userList, nickname);
      });
    });
    socket.on('OnChatMessage', function(room, message, nickname){
      sendChatMessage(message, room, nickname);
    });

  });
//process.env.PORT is used by heroku
  http.listen(process.env.PORT || 5000, function(){
    console.log('listening on *:5000');
  });

  function createRoom(room, description, expiration){
    if(expiration > 48)
      expiration = 48;

    if(hastableContains(roomList, room))
      return;

    console.log('Creating new room ' + room);
    roomChatLogs[room] = [];
    roomConnectedUsers[room] = [];
    roomList[room] = description;
    roomLives[room] = expiration;
  }

  function removeElement(target, array){
    var i = array.indexOf(target);
    if(i != -1) {
      array.splice(i, 1);
    }
    return array;
  }

  function expirationManager(){
    setInterval(function(){
      console.log('Running the expiration cycle');
      for (var key in roomLives) {
        roomLives[key] -= 1;
        if(roomLives[key] <= 0){
          console.log("Room " + key + " has expired");
          io.emit()
          delete roomLives[key];
          delete roomChatLogs[key];
          delete roomList[key];
          delete roomConnectedUsers[key];
          io.to(key).emit('OnRoomExpire');
        }
      };
    }, 600000);
  }

  function sendServerMessage(message, room){
    io.to(room).emit('serverMessage', message);
  }

  function sendChatMessage(message, room, nickname){
    var timestamp = getTimestamp();
    console.log(nickname + ' : ' + message + ' @ ' + timestamp);
    io.to(room).emit('chatMessage', message, nickname, timestamp);
    roomChatLogs[room].push(message + "," + nickname + "," + timestamp);
  }

  function getTimestamp(){
    return new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '')
  }

  function hastableContains(hastable, value){
    return value in hastable;
  }

  function removeQuotes(string){
    if(string == null)
      return;

   return string.replace(new RegExp('"', 'g'), '');
  }<|endoftext|>


<commit_before>#!/bin/env node
const express = require('express');
const request = require('request');
const redis   = require('redis');
const youtube = require('youtube-api');
const serverStatic = require('serve-static');
const imgix = require('imgix-core-js');

require('dotenv').config({
    silent: true
});

if (!process.env.GOOGLE_API_KEY) {
    console.warn('No GOOGLE_API_KEY var available, unable to query Youtube');
}

youtube.authenticate({
    type: 'key',
    key: process.env.GOOGLE_API_KEY,
    userIp: '123.123.123.1'
});

/**
 *  Define the sample application.
 */
var Posterframe = function() {

    //  Scope.
    var self = this;

    /*  ================================================================  */
    /*  Helper functions.                                                 */
    /*  ================================================================  */

    /**
     *  Set up server IP address and port # using env variables/defaults.
     */
    self.setupVariables = function() {
        //  Set the environment variables we need.
        self.ipaddress = process.env.OPENSHIFT_NODEJS_IP;
        self.port      = process.env.OPENSHIFT_NODEJS_PORT || process.env.PORT || 8080;

        if (typeof self.ipaddress === 'undefined') {
            //  Log errors on OpenShift but continue w/ 127.0.0.1 - this
            //  allows us to run/test the app locally.
            console.warn('No OPENSHIFT_NODEJS_IP var, using 127.0.0.1');
            self.ipaddress = '127.0.0.1';

            self.client = redis.createClient();
        } else {
            self.client = redis.createClient( process.env.OPENSHIFT_REDIS_PORT, process.env.OPENSHIFT_REDIS_HOST );
            self.client.auth( process.env.REDIS_PASSWORD );
            console.log('Password: ', process.env.REDIS_PASSWORD, process.env.OPENSHIFT_REDIS_PORT, process.env.OPENSHIFT_REDIS_HOST );
        }
    };

    /**
     *  terminator === the termination handler
     *  Terminate server on receipt of the specified signal.
     *  @param {string} sig  Signal to terminate on.
     */
    self.terminator = function(sig){
        if (typeof sig === 'string') {
           console.log('%s: Received %s - terminating sample app ...',
                       Date(Date.now()), sig);
           process.exit();
        }
        console.log('%s: Node server stopped.', Date(Date.now()) );
    };

    /**
     *  Setup termination handlers (for exit and a list of signals).
     */
    self.setupTerminationHandlers = function(){
        //  Process on exit and signals.
        process.on('exit', function() { self.terminator(); });

        // Removed 'SIGPIPE' from the list - bugz 852598.
        ['SIGHUP', 'SIGINT', 'SIGQUIT', 'SIGILL', 'SIGTRAP', 'SIGABRT',
         'SIGBUS', 'SIGFPE', 'SIGUSR1', 'SIGSEGV', 'SIGUSR2', 'SIGTERM'
        ].forEach(function(element) {
            process.on(element, function() { self.terminator(element); });
        });
    };

    /*  ================================================================  */
    /*  App server functions (main app logic here).                       */
    /*  ================================================================  */

    /**
     *  Initialize the server (express) and create the routes and register
     *  the handlers.
     */
    self.initializeServer = function() {
        self.app = express();

        self.app.use(serverStatic('public/'));

        self.app.use(function(req, res, next){

            if (req.originalUrl.match(/vimeo\.com/)) {
                var props = self.getPropertiesFromURL( req.originalUrl );
                self.fetchVimeo( req, res, props );
            } else if ( req.originalUrl.match(/youtube|youtu\.be/) ) {
                self.fetchYoutube( req, res );
            } else {
                next();
            }
        });

        self.app.get('/', function(req, res) {
            res.sendfile('public/index.html');
        });
    };

    self.overrideCache = function( url ) {
        var matches = url.match(/^\/force/);

        return matches ? true : false;
    };

    self.getPropertiesFromURL = function( url ) {

        var parts = url.split('/'),
            keys = ['id', 'width'],
            props = {},
            pointer = 0;

        for (var i = 0; i < parts.length; i++) {

            var n = parseInt( parts[i], 10 );

            if (!isNaN(n)) {
                props[keys[pointer]] = n;
                pointer++;
            }
        }

        return props;
    };

    self.fetchVimeo = function(req, res, properties ) {
        self.client.get(properties.id, function(err, result) {
            console.log('Original URL:', req.originalUrl );

            if (err || !result || self.overrideCache(req.originalUrl)) {
                console.log('Querying vimeo ID: ', properties.id);
                self.queryVimeo( req, res, properties );
            } else {
                console.log('Redis works!', result, properties );
                res.redirect( self.resizeThumbnailByUrl( result, req.query ));
            }
       });
    };

    self.fetchYoutube = function(req, res ) {
        var ids = req.originalUrl.match('v=([A-z0-9-]+)');

        if ( ids === null ) {
            ids = [req.originalUrl.split('/').pop()];
        }

        if ( ids ) {
            var youtube_id = ids.pop();

            console.log('Original URL:', req.originalUrl );
            console.log('Youtube ID:', youtube_id );

            self.client.get( youtube_id, function(err, result) {
                if (err || !result || self.overrideCache(req.originalUrl) ) {

                    youtube.videos.list({
                        part: 'id,snippet',
                        id: youtube_id
                    }, function(err,data) {
                        if (err || !data) {
                            console.log(err, data);
                            console.log(process.env.OPENSHIFT_NODEJS_IP);
                            throw err;
                        }

                        if ( data.items.length ) {

                            var thumbnails = data.items.pop().snippet.thumbnails;
                            var largest_thumbnail = thumbnails[ Object.keys(thumbnails)[Object.keys(thumbnails).length -  1]];

                            self.client.setex( youtube_id, 21600, largest_thumbnail.url );

                            res.redirect( largest_thumbnail.url );

                        }
                    });

                } else {
                    console.log('Loading via Redis:', result );
                    res.redirect(result);
                }
            });
        } else {
            console.warn('Error fetching:', req.originalUrl );
        }
    };

    self.resizeThumbnailByUrl = function ( thumbnail_url, properties ) {

        console.log('Imgix credentials present?', !process.env.IMGIX_HOST_URL, !process.env.IMGIX_SECURE_URL_TOKEN );

        if (Object.keys(properties).length === 0 || (!process.env.IMGIX_HOST_URL || !process.env.IMGIX_SECURE_URL_TOKEN)) {
            return thumbnail_url;
        }

        var client = new imgix({
            host: process.env.IMGIX_HOST_URL,
            secureURLToken: process.env.IMGIX_SECURE_URL_TOKEN,
            includeLibraryParam: false
        });

        return client.buildURL(thumbnail_url, properties);
    };

    self.queryVimeo = function( req, res, properties ) {
       request('http://vimeo.com/api/oembed.json?url=http://vimeo.com/' + properties.id, function(err, response, body) {
            if ( !err && response.statusCode === 200 ) {
                var json = JSON.parse(body),
                    thumbnail_url = self.resizeThumbnailByUrl( json.thumbnail_url.replace(/_[0-9x]+/,''), properties );

                self.client.setex(properties.id, 21600, thumbnail_url );
                console.log(thumbnail_url);
                res.redirect( thumbnail_url );
            } else {
                console.log(err, response);
            }
        });
    };

    /**
     *  Initializes the sample application.
     */
    self.initialize = function() {
        self.setupVariables();
        self.setupTerminationHandlers();

        // Create the express server and routes.
        self.initializeServer();
    };

    /**
     *  Start the server (starts up the sample application).
     */
    self.start = function() {
        //  Start the app on the specific interface (and port).
        self.app.listen(self.port, self.ipaddress, function() {
            console.log('%s: Node server started on http://%s:%d ...',
                        Date(Date.now() ), self.ipaddress, self.port);
        });
    };

};   /*  Posterframe Application.  */

/**
 *  main():  Main code.
 */
var app = new Posterframe();
app.initialize();
app.start();
<commit_msg>Don't use imgix unless query params included<commit_after>#!/bin/env node
const express = require('express');
const request = require('request');
const redis   = require('redis');
const youtube = require('youtube-api');
const serverStatic = require('serve-static');
const imgix = require('imgix-core-js');

require('dotenv').config({
    silent: true
});

if (!process.env.GOOGLE_API_KEY) {
    console.warn('No GOOGLE_API_KEY var available, unable to query Youtube');
}

youtube.authenticate({
    type: 'key',
    key: process.env.GOOGLE_API_KEY,
    userIp: '123.123.123.1'
});

/**
 *  Define the sample application.
 */
var Posterframe = function() {

    //  Scope.
    var self = this;

    /*  ================================================================  */
    /*  Helper functions.                                                 */
    /*  ================================================================  */

    /**
     *  Set up server IP address and port # using env variables/defaults.
     */
    self.setupVariables = function() {
        //  Set the environment variables we need.
        self.ipaddress = process.env.OPENSHIFT_NODEJS_IP;
        self.port      = process.env.OPENSHIFT_NODEJS_PORT || process.env.PORT || 8080;

        if (typeof self.ipaddress === 'undefined') {
            //  Log errors on OpenShift but continue w/ 127.0.0.1 - this
            //  allows us to run/test the app locally.
            console.warn('No OPENSHIFT_NODEJS_IP var, using 127.0.0.1');
            self.ipaddress = '127.0.0.1';

            self.client = redis.createClient();
        } else {
            self.client = redis.createClient( process.env.OPENSHIFT_REDIS_PORT, process.env.OPENSHIFT_REDIS_HOST );
            self.client.auth( process.env.REDIS_PASSWORD );
            console.log('Password: ', process.env.REDIS_PASSWORD, process.env.OPENSHIFT_REDIS_PORT, process.env.OPENSHIFT_REDIS_HOST );
        }
    };

    /**
     *  terminator === the termination handler
     *  Terminate server on receipt of the specified signal.
     *  @param {string} sig  Signal to terminate on.
     */
    self.terminator = function(sig){
        if (typeof sig === 'string') {
           console.log('%s: Received %s - terminating sample app ...',
                       Date(Date.now()), sig);
           process.exit();
        }
        console.log('%s: Node server stopped.', Date(Date.now()) );
    };

    /**
     *  Setup termination handlers (for exit and a list of signals).
     */
    self.setupTerminationHandlers = function(){
        //  Process on exit and signals.
        process.on('exit', function() { self.terminator(); });

        // Removed 'SIGPIPE' from the list - bugz 852598.
        ['SIGHUP', 'SIGINT', 'SIGQUIT', 'SIGILL', 'SIGTRAP', 'SIGABRT',
         'SIGBUS', 'SIGFPE', 'SIGUSR1', 'SIGSEGV', 'SIGUSR2', 'SIGTERM'
        ].forEach(function(element) {
            process.on(element, function() { self.terminator(element); });
        });
    };

    /*  ================================================================  */
    /*  App server functions (main app logic here).                       */
    /*  ================================================================  */

    /**
     *  Initialize the server (express) and create the routes and register
     *  the handlers.
     */
    self.initializeServer = function() {
        self.app = express();

        self.app.use(serverStatic('public/'));

        self.app.use(function(req, res, next){

            if (req.originalUrl.match(/vimeo\.com/)) {
                var props = self.getPropertiesFromURL( req.originalUrl );
                self.fetchVimeo( req, res, props );
            } else if ( req.originalUrl.match(/youtube|youtu\.be/) ) {
                self.fetchYoutube( req, res );
            } else {
                next();
            }
        });

        self.app.get('/', function(req, res) {
            res.sendfile('public/index.html');
        });
    };

    self.overrideCache = function( url ) {
        var matches = url.match(/^\/force/);

        return matches ? true : false;
    };

    self.getPropertiesFromURL = function( url ) {

        var parts = url.split('/'),
            keys = ['id', 'width'],
            props = {},
            pointer = 0;

        for (var i = 0; i < parts.length; i++) {

            var n = parseInt( parts[i], 10 );

            if (!isNaN(n)) {
                props[keys[pointer]] = n;
                pointer++;
            }
        }

        return props;
    };

    self.fetchVimeo = function(req, res, properties ) {
        self.client.get(properties.id, function(err, result) {
            console.log('Original URL:', req.originalUrl );

            if (err || !result || self.overrideCache(req.originalUrl)) {
                console.log('Querying vimeo ID: ', properties.id);
                self.queryVimeo( req, res, properties );
            } else {
                console.log('Redis works!', result, properties );
                res.redirect( self.resizeThumbnailByUrl( result, req.query ));
            }
       });
    };

    self.fetchYoutube = function(req, res ) {
        var ids = req.originalUrl.match('v=([A-z0-9-]+)');

        if ( ids === null ) {
            ids = [req.originalUrl.split('/').pop()];
        }

        if ( ids ) {
            var youtube_id = ids.pop();

            console.log('Original URL:', req.originalUrl );
            console.log('Youtube ID:', youtube_id );

            self.client.get( youtube_id, function(err, result) {
                if (err || !result || self.overrideCache(req.originalUrl) ) {

                    youtube.videos.list({
                        part: 'id,snippet',
                        id: youtube_id
                    }, function(err,data) {
                        if (err || !data) {
                            console.log(err, data);
                            console.log(process.env.OPENSHIFT_NODEJS_IP);
                            throw err;
                        }

                        if ( data.items.length ) {

                            var thumbnails = data.items.pop().snippet.thumbnails;
                            var largest_thumbnail = thumbnails[ Object.keys(thumbnails)[Object.keys(thumbnails).length -  1]];

                            self.client.setex( youtube_id, 21600, largest_thumbnail.url );

                            res.redirect( largest_thumbnail.url );

                        }
                    });

                } else {
                    console.log('Loading via Redis:', result );
                    res.redirect(result);
                }
            });
        } else {
            console.warn('Error fetching:', req.originalUrl );
        }
    };

    self.resizeThumbnailByUrl = function ( thumbnail_url, properties ) {

        console.log('Imgix credentials present?', !process.env.IMGIX_HOST_URL, !process.env.IMGIX_SECURE_URL_TOKEN );

        if (Object.keys(properties).length === 0 || (!process.env.IMGIX_HOST_URL || !process.env.IMGIX_SECURE_URL_TOKEN)) {
            return thumbnail_url;
        }

        var client = new imgix({
            host: process.env.IMGIX_HOST_URL,
            secureURLToken: process.env.IMGIX_SECURE_URL_TOKEN,
            includeLibraryParam: false
        });

        return client.buildURL(thumbnail_url, properties);
    };

    self.queryVimeo = function( req, res, properties ) {
       request('http://vimeo.com/api/oembed.json?url=http://vimeo.com/' + properties.id, function(err, response, body) {
            if ( !err && response.statusCode === 200 ) {
                var json = JSON.parse(body),
                    thumbnail_url = self.resizeThumbnailByUrl( json.thumbnail_url.replace(/_[0-9x]+/,''), req.query );

                self.client.setex(properties.id, 21600, thumbnail_url );
                console.log(thumbnail_url);
                res.redirect( thumbnail_url );
            } else {
                console.log(err, response);
            }
        });
    };

    /**
     *  Initializes the sample application.
     */
    self.initialize = function() {
        self.setupVariables();
        self.setupTerminationHandlers();

        // Create the express server and routes.
        self.initializeServer();
    };

    /**
     *  Start the server (starts up the sample application).
     */
    self.start = function() {
        //  Start the app on the specific interface (and port).
        self.app.listen(self.port, self.ipaddress, function() {
            console.log('%s: Node server started on http://%s:%d ...',
                        Date(Date.now() ), self.ipaddress, self.port);
        });
    };

};   /*  Posterframe Application.  */

/**
 *  main():  Main code.
 */
var app = new Posterframe();
app.initialize();
app.start();
<|endoftext|>


<commit_before>// Modules
var http=require('http'),
	fs=require('fs'),
	url = require('url'),
	crypto = require('crypto'),
	zlib = require('zlib');

// Constants
const MIME_TYPES={
	'html':'text/html',
	'js':'text/javascript',
	'manifest':'text/cache-manifest',
	'css': 'text/css',
	'png': 'image/png',
	'jpg': 'image/jpeg',
	'ico': 'image/ico',
	'mp3': 'audio/mp3',
	'ogg': 'audio/ogg',
	'mid': 'audio/x-midi',
	'json': 'application/json',
	'csv': 'text/csv',
	'webapp':'application/x-web-app-manifest+json'
	};

// Global vars
var rootDirectory=__dirname+'/www', // default directory
	domain='hexa.insertafter.com',
	port=8127;

// HTTP Server

// looking for the RootDirectory on CLI args
if(process.argv[2])
	rootDirectory=process.argv[2];
if(!fs.statSync(rootDirectory).isDirectory())
	throw Error('Cannot stat the given rootDirectory ('+rootDirectory+').');

var httpServer=http.createServer(function (request, response) {
	// Parsing URI
	var parsedUrl=url.parse(request.url);
	// Dynamic contents
	// generating the manifest
	if(parsedUrl.pathname==='/application.manifest'&&
		(request.method=='HEAD'||request.method=='GET')) {
		// parralelizing folder stat
		var folders=['images','css'];
		var listings=[];
		var foldersLeft=folders.length;
		folders.forEach(function(name) {
			fs.readdir(rootDirectory+'/'+name,function(error,file) {
				if(error) {
					response.writeHead(500);
					response.end();
					throw Error('Unable to read the folder "'+name+'".');
				}
				listings[name]=file;
				// when all folders are stated
				if(0==--foldersLeft) {
					response.writeHead(200,{'Content-Type':MIME_TYPES['manifest']});
					// generating the manifest
					response.write('CACHE MANIFEST\n# v 1.1\n\nCACHE:\n/index.html\n');
					folders.forEach(function(name) {
						for(var i=listings[name].length-1; i>=0; i--) {
							if(-1!==listings[name][i].indexOf('.')&&'list.json'!==listings[name][i])
								response.write('/'+name+'/'+listings[name][i]+'\n');
							}
						});
					// ending the manifest
					response.end('javascript/production.js\n\nFALLBACK:\n\n\nNETWORK:\n*\n');
					}
				});
			});
		return;
		}

	// Static contents : read-only access
	if('HEAD'!==request.method&&'GET'!==request.method) {
		response.writeHead(401);
		response.end();
		return;
	}
	// No query params
	if('search' in parsedUrl) {
		response.writeHead(401);
		response.end();
	}
	// redirecting the rootDirectory to index.html
	if('/'===parsedUrl.pathname||!parsedUrl.pathname) {
		response.writeHead(301,{'Location':'/index.html'});
		response.end();
		return;
	}
	// Checking the file corresponding to the path
	fs.stat(rootDirectory+parsedUrl.pathname,
		function(error,result) {
			var headers={}, code=0, start=0, end;
			// Sending 404 errors
			if(error||!result.isFile()) {
				response.writeHead(404);
				response.end();
				return;
			}
			// Reading file ext
			var ext=parsedUrl.pathname
				.replace(/^(?:.*)\.([a-z0-9]+)$/,'$1');
			if(!MIME_TYPES[ext]) {
				response.writeHead(500);
				response.end();
				throw Error('Unsupported MIME type ('+ext+')');
			}
			headers['Content-Type']=MIME_TYPES[ext];
			headers['Content-Length']=result.size;
			// Looking for ranged requests
			if(request.headers.range) {
				var chunks = request.headers.range.replace(/bytes=/, "").split("-");
				start = parseInt(chunks[0],10);
				end =  chunks[1] ? parseInt(chunks[1], 10) :
					headers['Content-Length']-1;
				headers['Content-Range'] = 'bytes ' + start + '-' + end + '/'
					+ (headers['Content-Length']);
				headers['Accept-Ranges'] = 'bytes';
				headers['Content-Length']= (end-start)+1;
				headers['Transfer-Encoding'] = 'chunked';
				headers['Connection'] = 'close';
				code=206;
			} else {
				code=200;
			}
			if('GET'===request.method) {
				if(0===MIME_TYPES[ext].indexOf('text/')
					&&request.headers['accept-encoding']) {
					// setting content encoding
					if(request.headers['accept-encoding'].match(/\bdeflate\b/)) {
						headers['Content-Encoding'] = 'deflate';
						delete headers['Content-Length'];
					} else if (request.headers['accept-encoding'].match(/\bgzip\b/)) {
						headers['Content-Encoding'] = 'gzip';
						delete headers['Content-Length'];
					}
				}
				// sending code and headers
				response.writeHead(code, headers);
				// getting ofstream
				var ofstream=fs.createReadStream(rootDirectory
					+parsedUrl.pathname,{start: start, end: end});
				if(headers['Content-Encoding']) {
					ofstream.pipe('gzip'===headers['Content-Encoding']?
							zlib.createGzip():zlib.createDeflate())
						.pipe(response);
				}
				else {
					ofstream.pipe(response);
				}
			} else {
				// sending code and headers
				response.writeHead(code, headers);
				response.end();
			}
		}
	);
}).listen(port);

console.log('Server started on http://'+domain+':'+port+'/, '
	+'serving directory :'+rootDirectory);

<commit_msg>Fixed Node 0.10 update bug<commit_after>// Modules
var http=require('http'),
	fs=require('fs'),
	url = require('url'),
	crypto = require('crypto'),
	zlib = require('zlib');

// Constants
const MIME_TYPES={
	'html':'text/html',
	'js':'text/javascript',
	'manifest':'text/cache-manifest',
	'css': 'text/css',
	'png': 'image/png',
	'jpg': 'image/jpeg',
	'ico': 'image/ico',
	'mp3': 'audio/mp3',
	'ogg': 'audio/ogg',
	'mid': 'audio/x-midi',
	'json': 'application/json',
	'csv': 'text/csv',
	'webapp':'application/x-web-app-manifest+json'
	};

// Global vars
var rootDirectory=__dirname+'/www', // default directory
	domain='hexa.insertafter.com',
	port=8127;

// HTTP Server

// looking for the RootDirectory on CLI args
if(process.argv[2])
	rootDirectory=process.argv[2];
if(!fs.statSync(rootDirectory).isDirectory())
	throw Error('Cannot stat the given rootDirectory ('+rootDirectory+').');

var httpServer=http.createServer(function (request, response) {
	// Parsing URI
	var parsedUrl=url.parse(request.url);
	// Dynamic contents
	// generating the manifest
	if(parsedUrl.pathname==='/application.manifest'&&
		(request.method=='HEAD'||request.method=='GET')) {
		// parralelizing folder stat
		var folders=['images','css'];
		var listings=[];
		var foldersLeft=folders.length;
		folders.forEach(function(name) {
			fs.readdir(rootDirectory+'/'+name,function(error,file) {
				if(error) {
					response.writeHead(500);
					response.end();
					throw Error('Unable to read the folder "'+name+'".');
				}
				listings[name]=file;
				// when all folders are stated
				if(0==--foldersLeft) {
					response.writeHead(200,{'Content-Type':MIME_TYPES['manifest']});
					// generating the manifest
					response.write('CACHE MANIFEST\n# v 1.1\n\nCACHE:\n/index.html\n');
					folders.forEach(function(name) {
						for(var i=listings[name].length-1; i>=0; i--) {
							if(-1!==listings[name][i].indexOf('.')&&'list.json'!==listings[name][i])
								response.write('/'+name+'/'+listings[name][i]+'\n');
							}
						});
					// ending the manifest
					response.end('javascript/production.js\n\nFALLBACK:\n\n\nNETWORK:\n*\n');
					}
				});
			});
		return;
		}

	// Static contents : read-only access
	if('HEAD'!==request.method&&'GET'!==request.method) {
		response.writeHead(401);
		response.end();
		return;
	}
	// No query params
	if(parsedUrl.search) {
		response.writeHead(401);
		response.end();
	}
	// redirecting the rootDirectory to index.html
	if('/'===parsedUrl.pathname||!parsedUrl.pathname) {
		response.writeHead(301,{'Location':'/index.html'});
		response.end();
		return;
	}
	// Checking the file corresponding to the path
	fs.stat(rootDirectory+parsedUrl.pathname,
		function(error,result) {
			var headers={}, code=0, start=0, end;
			// Sending 404 errors
			if(error||!result.isFile()) {
				response.writeHead(404);
				response.end();
				return;
			}
			// Reading file ext
			var ext=parsedUrl.pathname
				.replace(/^(?:.*)\.([a-z0-9]+)$/,'$1');
			if(!MIME_TYPES[ext]) {
				response.writeHead(500);
				response.end();
				throw Error('Unsupported MIME type ('+ext+')');
			}
			headers['Content-Type']=MIME_TYPES[ext];
			headers['Content-Length']=result.size;
			// Looking for ranged requests
			if(request.headers.range) {
				var chunks = request.headers.range.replace(/bytes=/, "").split("-");
				start = parseInt(chunks[0],10);
				end =  chunks[1] ? parseInt(chunks[1], 10) :
					headers['Content-Length']-1;
				headers['Content-Range'] = 'bytes ' + start + '-' + end + '/'
					+ (headers['Content-Length']);
				headers['Accept-Ranges'] = 'bytes';
				headers['Content-Length']= (end-start)+1;
				headers['Transfer-Encoding'] = 'chunked';
				headers['Connection'] = 'close';
				code=206;
			} else {
				code=200;
			}
			if('GET'===request.method) {
				if(0===MIME_TYPES[ext].indexOf('text/')
					&&request.headers['accept-encoding']) {
					// setting content encoding
					if(request.headers['accept-encoding'].match(/\bdeflate\b/)) {
						headers['Content-Encoding'] = 'deflate';
						delete headers['Content-Length'];
					} else if (request.headers['accept-encoding'].match(/\bgzip\b/)) {
						headers['Content-Encoding'] = 'gzip';
						delete headers['Content-Length'];
					}
				}
				// sending code and headers
				response.writeHead(code, headers);
				// getting ofstream
				var ofstream=fs.createReadStream(rootDirectory
					+parsedUrl.pathname,{start: start, end: end});
				if(headers['Content-Encoding']) {
					ofstream.pipe('gzip'===headers['Content-Encoding']?
							zlib.createGzip():zlib.createDeflate())
						.pipe(response);
				}
				else {
					ofstream.pipe(response);
				}
			} else {
				// sending code and headers
				response.writeHead(code, headers);
				response.end();
			}
		}
	);
}).listen(port);

console.log('Server started on http://'+domain+':'+port+'/, '
	+'serving directory :'+rootDirectory);

<|endoftext|>


<commit_before>import SplitEditor from './split.js';
import React, { Component } from 'react'
import PropTypes from 'prop-types';
import DiffMatchPatch from 'diff-match-patch';

export default class DiffComponent extends Component {
  constructor(props) {
    super(props);
    this.state={
      value: this.props.value,
    };
    this.onChange = this.onChange.bind(this);
    this.diff = this.diff.bind(this);
  }

  onChange(value) {
    this.setState({
      value: value
    });
    if(this.props.onChange){
      this.props.onChange(value);
    }
  }

  diff() {
    const dmp = new DiffMatchPatch();
    const lhString = this.state.value[0];
    const rhString = this.state.value[1];

    if (lhString.length === 0 && rhString.length === 0) {
      return [];
    }

    const diff = dmp.diff_main(lhString, rhString);
    dmp.diff_cleanupSemantic(diff);

    const diffedLines = this.generateDiffedLines(diff);
    const codeEditorSettings = this.setCodeMarkers(diffedLines);
    return codeEditorSettings;
  }

  generateDiffedLines(diff) {
    const C = {
      DIFF_EQUAL: 0,
      DIFF_DELETE: -1,
      DIFF_INSERT: 1,
    };

    const diffedLines = {
      left: [],
      right: [],
    };

    const cursor = {
      left: 1,
      right: 1,
    };

    diff.forEach((chunk) => {
      const chunkType = chunk[0];
      const text = chunk[1];
      let lines = text.split('\n').length - 1;

      // diff-match-patch sometimes returns empty strings at random
      if (text.length === 0) {
        return;
      }

      const firstChar = text[0];
      const lastChar = text[text.length - 1];
      let linesToHighlight = 0;

      switch (chunkType) {
      case C.DIFF_EQUAL:
        cursor.left += lines;
        cursor.right += lines;

        break;
      case C.DIFF_DELETE:

        // If the deletion starts with a newline, push the cursor down to that line
        if (firstChar === '\n') {
          cursor.left++;
          lines--;
        }

        linesToHighlight = lines;

        // If the deletion does not include a newline, highlight the same line on the right
        if (linesToHighlight === 0) {
          diffedLines.right.push({
            startLine: cursor.right,
            endLine: cursor.right,
          });
        }

        // If the last character is a newline, we don't want to highlight that line
        if (lastChar === '\n') {
          linesToHighlight -= 1;
        }

        diffedLines.left.push({
          startLine: cursor.left,
          endLine: cursor.left + linesToHighlight,
        });

        cursor.left += lines;
        break;
      case C.DIFF_INSERT:

        // If the insertion starts with a newline, push the cursor down to that line
        if (firstChar === '\n') {
          cursor.right++;
          lines--;
        }

        linesToHighlight = lines;

        // If the insertion does not include a newline, highlight the same line on the left
        if (linesToHighlight === 0) {
          diffedLines.left.push({
            startLine: cursor.left,
            endLine: cursor.left,
          });
        }

        // If the last character is a newline, we don't want to highlight that line
        if (lastChar === '\n') {
          linesToHighlight -= 1;
        }

        diffedLines.right.push({
          startLine: cursor.right,
          endLine: cursor.right + linesToHighlight,
        });

        cursor.right += lines;
        break;
      default:
        throw new Error('Diff type was not defined.');
      }
    });
    return diffedLines;
  }

  // Receives a collection of line numbers and iterates through them to highlight appropriately
  // Returns an object that tells the render() method how to display the code editors
  setCodeMarkers(diffedLines = { left: [], right: [] }) {
    const codeEditorSettings = [];

    const newMarkerSet = {
      left: [],
      right: [],
    };

    for (let i = 0; i < diffedLines.left.length; i++) {
      let markerObj = {
        startRow: diffedLines.left[i].startLine - 1,
        endRow: diffedLines.left[i].endLine,
        type: 'text',
        className: 'codeMarker',
      };
      newMarkerSet.left.push(markerObj);
    }

    for (let i = 0; i < diffedLines.right.length; i++) {
      let markerObj = {
        startRow: diffedLines.right[i].startLine - 1,
        endRow: diffedLines.right[i].endLine,
        type: 'text',
        className: 'codeMarker',
      };
      newMarkerSet.right.push(markerObj);
    }

    codeEditorSettings[0] = newMarkerSet.left;
    codeEditorSettings[1] = newMarkerSet.right;

    return codeEditorSettings;
  }

  render() {
    const markers = this.diff();
    return (
      <SplitEditor
        name={this.props.name}
        className={this.props.className}
        focus={this.props.focus}
        orientation={this.props.orientation}
        splits={this.props.splits}
        mode={this.props.mode}
        theme={this.props.theme}
        height={this.props.height}
        width={this.props.width}
        fontSize={this.props.fontSize}
        showGutter={this.props.showGutter}
        onChange={this.onChange}
        onPaste={this.props.onPaste}
        onLoad={this.props.onLoad}
        onScroll={this.props.onScroll}
        minLines={this.props.minLines}
        maxLines={this.props.maxLines}
        readOnly={this.props.readOnly}
        highlightActiveLine={this.props.highlightActiveLine}
        showPrintMargin={this.props.showPrintMargin}
        tabSize={this.props.tabSize}
        cursorStart={this.props.cursorStart}
        editorProps={this.props.editorProps}
        style={this.props.style}
        scrollMargin={this.props.scrollMargin}
        setOptions={this.props.setOptions}
        wrapEnabled={this.props.wrapEnabled}
        enableBasicAutocompletion={this.props.enableBasicAutocompletion}
        enableLiveAutocompletion={this.props.enableLiveAutocompletion}
        value={this.state.value}
        markers={markers}
      />
    );
  }
}

DiffComponent.propTypes = {
  cursorStart: PropTypes.number,
  editorProps: PropTypes.object,
  enableBasicAutocompletion: PropTypes.bool,
  enableLiveAutocompletion: PropTypes.bool,
  focus: PropTypes.bool,
  fontSize: PropTypes.number,
  height: PropTypes.string,
  highlightActiveLine: PropTypes.bool,
  maxLines: PropTypes.func,
  minLines: PropTypes.func,
  mode: PropTypes.string,
  name: PropTypes.string,
  className: PropTypes.string,
  onLoad: PropTypes.func,
  onPaste: PropTypes.func,
  onScroll: PropTypes.func,
  onChange:PropTypes.func,
  orientation: PropTypes.string,
  readOnly: PropTypes.bool,
  scrollMargin: PropTypes.array,
  setOptions: PropTypes.object,
  showGutter: PropTypes.bool,
  showPrintMargin: PropTypes.bool,
  splits: PropTypes.number,
  style: PropTypes.object,
  tabSize: PropTypes.number,
  theme: PropTypes.string,
  value: PropTypes.array,
  width: PropTypes.string,
  wrapEnabled: PropTypes.bool,
}

DiffComponent.defaultProps = {
  cursorStart: 1,
  editorProps: {},
  enableBasicAutocompletion: false,
  enableLiveAutocompletion: false,
  focus: false,
  fontSize: 12,
  height: '500px',
  highlightActiveLine: true,
  maxLines: null,
  minLines: null,
  mode: '',
  name: 'brace-editor',
  onLoad: null,
  onScroll: null,
  onPaste: null,
  onChange:null,
  orientation: 'beside',
  readOnly: false,
  scrollMargin: [ 0, 0, 0, 0],
  setOptions: {},
  showGutter: true,
  showPrintMargin: true,
  splits: 2,
  style: {},
  tabSize: 4,
  theme: 'github',
  value: ['',''],
  width: '500px',
  wrapEnabled: true,
}
<commit_msg>Diff responds to value change (#480)<commit_after>import SplitEditor from './split.js';
import React, { Component } from 'react'
import PropTypes from 'prop-types';
import DiffMatchPatch from 'diff-match-patch';

export default class DiffComponent extends Component {
  constructor(props) {
    super(props);
    this.state={
      value: this.props.value,
    };
    this.onChange = this.onChange.bind(this);
    this.diff = this.diff.bind(this);
  }

  componentWillReceiveProps(props) {
    const {value} = props;

    if (value !== this.state.value) {
      this.setState({value});
    }
  }

  onChange(value) {
    this.setState({
      value: value
    });
    if(this.props.onChange){
      this.props.onChange(value);
    }
  }

  diff() {
    const dmp = new DiffMatchPatch();
    const lhString = this.state.value[0];
    const rhString = this.state.value[1];

    if (lhString.length === 0 && rhString.length === 0) {
      return [];
    }

    const diff = dmp.diff_main(lhString, rhString);
    dmp.diff_cleanupSemantic(diff);

    const diffedLines = this.generateDiffedLines(diff);
    const codeEditorSettings = this.setCodeMarkers(diffedLines);
    return codeEditorSettings;
  }

  generateDiffedLines(diff) {
    const C = {
      DIFF_EQUAL: 0,
      DIFF_DELETE: -1,
      DIFF_INSERT: 1,
    };

    const diffedLines = {
      left: [],
      right: [],
    };

    const cursor = {
      left: 1,
      right: 1,
    };

    diff.forEach((chunk) => {
      const chunkType = chunk[0];
      const text = chunk[1];
      let lines = text.split('\n').length - 1;

      // diff-match-patch sometimes returns empty strings at random
      if (text.length === 0) {
        return;
      }

      const firstChar = text[0];
      const lastChar = text[text.length - 1];
      let linesToHighlight = 0;

      switch (chunkType) {
      case C.DIFF_EQUAL:
        cursor.left += lines;
        cursor.right += lines;

        break;
      case C.DIFF_DELETE:

        // If the deletion starts with a newline, push the cursor down to that line
        if (firstChar === '\n') {
          cursor.left++;
          lines--;
        }

        linesToHighlight = lines;

        // If the deletion does not include a newline, highlight the same line on the right
        if (linesToHighlight === 0) {
          diffedLines.right.push({
            startLine: cursor.right,
            endLine: cursor.right,
          });
        }

        // If the last character is a newline, we don't want to highlight that line
        if (lastChar === '\n') {
          linesToHighlight -= 1;
        }

        diffedLines.left.push({
          startLine: cursor.left,
          endLine: cursor.left + linesToHighlight,
        });

        cursor.left += lines;
        break;
      case C.DIFF_INSERT:

        // If the insertion starts with a newline, push the cursor down to that line
        if (firstChar === '\n') {
          cursor.right++;
          lines--;
        }

        linesToHighlight = lines;

        // If the insertion does not include a newline, highlight the same line on the left
        if (linesToHighlight === 0) {
          diffedLines.left.push({
            startLine: cursor.left,
            endLine: cursor.left,
          });
        }

        // If the last character is a newline, we don't want to highlight that line
        if (lastChar === '\n') {
          linesToHighlight -= 1;
        }

        diffedLines.right.push({
          startLine: cursor.right,
          endLine: cursor.right + linesToHighlight,
        });

        cursor.right += lines;
        break;
      default:
        throw new Error('Diff type was not defined.');
      }
    });
    return diffedLines;
  }

  // Receives a collection of line numbers and iterates through them to highlight appropriately
  // Returns an object that tells the render() method how to display the code editors
  setCodeMarkers(diffedLines = { left: [], right: [] }) {
    const codeEditorSettings = [];

    const newMarkerSet = {
      left: [],
      right: [],
    };

    for (let i = 0; i < diffedLines.left.length; i++) {
      let markerObj = {
        startRow: diffedLines.left[i].startLine - 1,
        endRow: diffedLines.left[i].endLine,
        type: 'text',
        className: 'codeMarker',
      };
      newMarkerSet.left.push(markerObj);
    }

    for (let i = 0; i < diffedLines.right.length; i++) {
      let markerObj = {
        startRow: diffedLines.right[i].startLine - 1,
        endRow: diffedLines.right[i].endLine,
        type: 'text',
        className: 'codeMarker',
      };
      newMarkerSet.right.push(markerObj);
    }

    codeEditorSettings[0] = newMarkerSet.left;
    codeEditorSettings[1] = newMarkerSet.right;

    return codeEditorSettings;
  }

  render() {
    const markers = this.diff();
    return (
      <SplitEditor
        name={this.props.name}
        className={this.props.className}
        focus={this.props.focus}
        orientation={this.props.orientation}
        splits={this.props.splits}
        mode={this.props.mode}
        theme={this.props.theme}
        height={this.props.height}
        width={this.props.width}
        fontSize={this.props.fontSize}
        showGutter={this.props.showGutter}
        onChange={this.onChange}
        onPaste={this.props.onPaste}
        onLoad={this.props.onLoad}
        onScroll={this.props.onScroll}
        minLines={this.props.minLines}
        maxLines={this.props.maxLines}
        readOnly={this.props.readOnly}
        highlightActiveLine={this.props.highlightActiveLine}
        showPrintMargin={this.props.showPrintMargin}
        tabSize={this.props.tabSize}
        cursorStart={this.props.cursorStart}
        editorProps={this.props.editorProps}
        style={this.props.style}
        scrollMargin={this.props.scrollMargin}
        setOptions={this.props.setOptions}
        wrapEnabled={this.props.wrapEnabled}
        enableBasicAutocompletion={this.props.enableBasicAutocompletion}
        enableLiveAutocompletion={this.props.enableLiveAutocompletion}
        value={this.state.value}
        markers={markers}
      />
    );
  }
}

DiffComponent.propTypes = {
  cursorStart: PropTypes.number,
  editorProps: PropTypes.object,
  enableBasicAutocompletion: PropTypes.bool,
  enableLiveAutocompletion: PropTypes.bool,
  focus: PropTypes.bool,
  fontSize: PropTypes.number,
  height: PropTypes.string,
  highlightActiveLine: PropTypes.bool,
  maxLines: PropTypes.func,
  minLines: PropTypes.func,
  mode: PropTypes.string,
  name: PropTypes.string,
  className: PropTypes.string,
  onLoad: PropTypes.func,
  onPaste: PropTypes.func,
  onScroll: PropTypes.func,
  onChange:PropTypes.func,
  orientation: PropTypes.string,
  readOnly: PropTypes.bool,
  scrollMargin: PropTypes.array,
  setOptions: PropTypes.object,
  showGutter: PropTypes.bool,
  showPrintMargin: PropTypes.bool,
  splits: PropTypes.number,
  style: PropTypes.object,
  tabSize: PropTypes.number,
  theme: PropTypes.string,
  value: PropTypes.array,
  width: PropTypes.string,
  wrapEnabled: PropTypes.bool,
}

DiffComponent.defaultProps = {
  cursorStart: 1,
  editorProps: {},
  enableBasicAutocompletion: false,
  enableLiveAutocompletion: false,
  focus: false,
  fontSize: 12,
  height: '500px',
  highlightActiveLine: true,
  maxLines: null,
  minLines: null,
  mode: '',
  name: 'brace-editor',
  onLoad: null,
  onScroll: null,
  onPaste: null,
  onChange:null,
  orientation: 'beside',
  readOnly: false,
  scrollMargin: [ 0, 0, 0, 0],
  setOptions: {},
  showGutter: true,
  showPrintMargin: true,
  splits: 2,
  style: {},
  tabSize: 4,
  theme: 'github',
  value: ['',''],
  width: '500px',
  wrapEnabled: true,
}
<|endoftext|>


<commit_before>"use strict";

// increase the libuv threadpool size to 1.5x the number of logical CPUs.
process.env.UV_THREADPOOL_SIZE = process.env.UV_THREADPOOL_SIZE || Math.ceil(Math.max(4, require('os').cpus().length * 1.5));

var path = require("path");
var raven = require("raven");

var onHeaders = require('on-headers');

var tessera = require("tessera"),
    express = require("express"),
    cors = require("cors"),
    tilelive = require("tilelive-cache")(require("tilelive"), {
      size: process.env.CACHE_SIZE,
      sources: process.env.SOURCE_CACHE_SIZE
    });

var app = express().disable("x-powered-by");

require("tessera/modules")(tilelive, {});

var loggingThreshold = +(process.env.LOG_MS || 5000);
var slowLogger = function(req, res, next) {
    var startAt = process.hrtime()

    onHeaders(res, function () {
      if (this.getHeader('X-Response-Time')) return;

      var diff = process.hrtime(startAt)
      var ms = diff[0] * 1e3 + diff[1] * 1e-6

      if (ms > loggingThreshold) {
        console.log("SLOW REQUEST ", req.url, " ", ms, " ms");
      }
      this.setHeader('X-Response-Time', ms.toFixed(3) + 'ms')
    })

    next()
  }

var config = require("./tessera.json");
Object.keys(config).forEach(function(prefix) {
  if (config[prefix].timing !== false) {
    app.use(prefix, slowLogger);
  }

  if (config[prefix].cors !== false) {
    app.use(prefix, cors());
  }

  app.use(raven.middleware.express(process.env.SENTRY_DSN));
  app.use(prefix, express.static(path.join(__dirname, "node_modules/tessera/public")));
  app.use(prefix, express.static(path.join(__dirname, "node_modules/tessera/bower_components")));
  app.use(prefix, tessera(tilelive, config[prefix]));
});

app.listen(process.env.PORT || 8080, function() {
  console.log("Listening at http://%s:%d/", this.address().address, this.address().port);
});
<commit_msg>log full url<commit_after>"use strict";

// increase the libuv threadpool size to 1.5x the number of logical CPUs.
process.env.UV_THREADPOOL_SIZE = process.env.UV_THREADPOOL_SIZE || Math.ceil(Math.max(4, require('os').cpus().length * 1.5));

var path = require("path");
var raven = require("raven");

var onHeaders = require('on-headers');

var tessera = require("tessera"),
    express = require("express"),
    cors = require("cors"),
    tilelive = require("tilelive-cache")(require("tilelive"), {
      size: process.env.CACHE_SIZE,
      sources: process.env.SOURCE_CACHE_SIZE
    });

var app = express().disable("x-powered-by");

require("tessera/modules")(tilelive, {});

var loggingThreshold = +(process.env.LOG_MS || 5000);
var slowLogger = function(req, res, next) {
    var startAt = process.hrtime()

    onHeaders(res, function () {
      if (this.getHeader('X-Response-Time')) return;

      var diff = process.hrtime(startAt)
      var ms = diff[0] * 1e3 + diff[1] * 1e-6

      if (ms > loggingThreshold) {
        console.log("SLOW REQUEST ", req.originalUrl, " ", ms, " ms");
      }
      this.setHeader('X-Response-Time', ms.toFixed(3) + 'ms')
    })

    next()
  }

var config = require("./tessera.json");
Object.keys(config).forEach(function(prefix) {
  if (config[prefix].timing !== false) {
    app.use(prefix, slowLogger);
  }

  if (config[prefix].cors !== false) {
    app.use(prefix, cors());
  }

  app.use(raven.middleware.express(process.env.SENTRY_DSN));
  app.use(prefix, express.static(path.join(__dirname, "node_modules/tessera/public")));
  app.use(prefix, express.static(path.join(__dirname, "node_modules/tessera/bower_components")));
  app.use(prefix, tessera(tilelive, config[prefix]));
});

app.listen(process.env.PORT || 8080, function() {
  console.log("Listening at http://%s:%d/", this.address().address, this.address().port);
});
<|endoftext|>


<commit_before>var url = require('url'),
   http = require('http'),
   https = require('https'),
   express = require('express'),
   request = require('request'),
   app = express(),
   message = require('./lib/message.js'),
   utils = require('./lib/utils.js'),
   couch = require('./lib/couch.js');

var config = utils.loadConfig();
var port = process.env.PORT || config.stardust_port || 9999;
var DATABASE_URL = "http://" + config.couch_host + ':' + config.couch_port;

// reverse proxy for couchdb
app.use(function(req, res, next){
   var proxy_path = req.path.match(/^\/db(.*)$/);
   if(proxy_path){
      var db_url = DATABASE_URL + proxy_path[1];
      req.pipe(request({
         uri: db_url,
         method: req.method
      })).pipe(res);
   } else {
      next();
   }
});

app.use(express.bodyParser());

app.listen(port, null, function (err) {
   if (err)
      console.log('Error: ' + err);
   console.log('StarDust, at your service: http://localhost:' + port);
});

// Convenience for allowing CORS on routes
app.all('*', function (req, res, next) {
   res.header('Access-Control-Allow-Origin', '*');
   res.header('Access-Control-Allow-Methods', 'GET, POST');
   res.header('Access-Control-Allow-Headers', 'Content-Type');
   next();
});

app.post('/auth', function(req, res) {
   request.post({
      url: 'https://login.persona.org/verify',
      json: {
         assertion: req.body.assertion,
         audience: req.body.app           //Should be hardcoded
      }
   }, function(e, r, body) {
      if(body && body.email) {
         req.session.email = body.email;

         res.json({ success: true });
      } else {
         res.json({ success: false });
      }
   });
});

app.post('/register', function (req, res) {
   console.log("/register");

   //TODO: Only clients of an approved app can register
   //if (req.body.appSecret === config.appSecret) {

   //create User
   couch.createUser(req.body.creds, function (err, user) {

      //create DB
      couch.createDB(req.body.app, req.body.creds, function (err, dbname) {
         res.json(err ? { error: err } : { db: dbname });
      });
   });

   //}
});

app.post('/dust', function (req, res) {
   var dust = req.body.dust;

   console.log('get dust: ' + dust);

   couch.getDust(req.body.app, req.body.user, dust, function (err, dust) {
      res.json(err ? { error: err } : dust );
   });

});

app.post('/burst', function (req, res) {
   console.log("/burst");

});

<commit_msg>New auth flow<commit_after>var url = require('url'),
   http = require('http'),
   https = require('https'),
   express = require('express'),
   request = require('request'),
   app = express(),
   message = require('./lib/message.js'),
   utils = require('./lib/utils.js'),
   couch = require('./lib/couch.js');

var config = utils.loadConfig();
var port = process.env.PORT || config.stardust_port || 9999;
var DATABASE_URL = "http://" + config.couch_host + ':' + config.couch_port;

// reverse proxy for couchdb
app.use(function (req, res, next) {
   var proxy_path = req.path.match(/^\/db(.*)$/);
   if (proxy_path) {
      var db_url = DATABASE_URL + proxy_path[1];
      req.pipe(request({
         uri: db_url,
         method: req.method
      })).pipe(res);
   } else {
      next();
   }
});

app.use(express.bodyParser());

app.listen(port, null, function (err) {
   if (err)
      console.log('Error: ' + err);
   console.log('StarDust, at your service: http://localhost:' + port);
});

// Convenience for allowing CORS on routes
app.all('*', function (req, res, next) {
   res.header('Access-Control-Allow-Origin', '*');
   res.header('Access-Control-Allow-Methods', 'GET, POST');
   res.header('Access-Control-Allow-Headers', 'Content-Type');
   next();
});

app.post('/auth', function (req, res) {

   if (req.body.assertion) {
      //AUTH WITH PERSONA
      request.post({
         url: 'https://login.persona.org/verify',
         json: {
            assertion: req.body.assertion,
            audience: req.body.app           //Should be hardcoded
         }
      }, function (e, r, body) {
         if (body && body.email) {
            req.session.email = body.email;

            res.json({ success: true });
         } else {
            res.json({ success: false });
         }
      });

   }
   else if(req.body.fbid) {
      //AUTH WITH FACEBOOK

   }
});

app.post('/register', function (req, res) {
   console.log("/register");

   //TODO: Only clients of an approved app can register
   //if (req.body.appSecret === config.appSecret) {

   //create User
   couch.createUser(req.body.creds, function (err, user) {

      //create DB
      couch.createDB(req.body.app, req.body.creds, function (err, dbname) {
         res.json(err ? { error: err } : { db: dbname });
      });
   });

   //}
});

app.post('/dust', function (req, res) {
   var dust = req.body.dust;

   console.log('get dust: ' + dust);

   couch.getDust(req.body.app, req.body.user, dust, function (err, dust) {
      res.json(err ? { error: err } : dust);
   });

});

app.post('/burst', function (req, res) {
   console.log("/burst");

});

<|endoftext|>