Permalink
Browse files

Merge branch 'master' of github.com:joyent/node-camp

  • Loading branch information...
2 parents 8eaf091 + 975d05b commit 245abe18b079548cfb29adb0612a5a6fdd48aeb2 @creationix creationix committed Dec 14, 2010
View
8 blog/server.js
@@ -39,7 +39,7 @@ app.configure('production', function(){
app.get('/', function(req, res, next){
storage.find(function(err, posts){
if (err) return next(err);
- res.render('index', {locals: { posts: posts } });
+ res.render('index', {locals: { posts: posts, localVariable: 'This is my local variable' } });
});
});
@@ -87,8 +87,10 @@ app.get('/admin/login', function(req, res){
});
app.get('/admin/logout', function(req, res){
- req.logout();
- res.redirect('/admin');
+ setTimeout(function(){
+ req.logout();
+ res.redirect('/admin');
+ }, 2000);
});
app.post('/admin/login', function(req, res){
View
2 blog/test/app.test.js
@@ -14,7 +14,7 @@ module.exports = {
{ url: '/' },
{ status: 200, headers: { 'Content-Type': 'text/html; charset=utf-8' }},
function(res){
- assert.includes(res.body, '<title>Express</title>');
+ assert.includes(res.body, 'My cool blog');
});
}
View
28 blog/views/archive.jade
@@ -1,12 +1,20 @@
h2 Archive
-- if (!posts.length)
- p
- | No posts to show.
- a(href: '/admin') Go to admin?
-- else
- - each post in posts
- .archive
- span.date= post.date
- h3
- a(href: '/post/' + post.id)= post.title
+:markdown
+ | ## Hello
+
+:javascript
+ | var a = '5';
+ | var b = '5';
+
+:realtime(repaint: 'connections')
+ - if (!posts.length)
+ p
+ | No posts to show.
+ a(href: '/admin') Go to admin?
+ - else
+ - each post in posts
+ .archive
+ span.date= post.date
+ h3
+ a(href: '/post/' + post.id)= post.title
View
2 blog/views/index.jade
@@ -10,4 +10,4 @@ h2 Latest posts
h1
a(href: '/post/' + post.id)= post.title
h4= post.date
- != post.content
+ = post.content
View
2 blog/views/layout.jade
@@ -4,6 +4,8 @@ html
title= this.app.set('name')
link(rel='stylesheet', href='/stylesheets/style.css')
body
+ h1= localVariable
+ h2= this.connection.remoteAddress
#header
h1= this.app.set('name')
nav
View
19 chat/README.md
@@ -0,0 +1,19 @@
+Chat Example with Socket.IO
+===========================
+
+## Installation requirements
+
+Install the packages `express`, `socket.io`, and `jade` with [NPM](http://npmjs.org)
+
+ npm install express
+ npm install socket.io
+ npm install jade
+
+## Project description
+
+The goal is to create the quintessential realtime application on the web:
+a chat client. It involves the following concepts
+
+* Realtime communication schemes
+* Connect/Express + Socket.IO integration
+* JSON as a transport encoding mechanism
View
18 chat/public/javascripts/json.js
@@ -0,0 +1,18 @@
+if(!this.JSON){JSON=function(){function f(n){return n<10?'0'+n:n;}
+Date.prototype.toJSON=function(){return this.getUTCFullYear()+'-'+
+f(this.getUTCMonth()+1)+'-'+
+f(this.getUTCDate())+'T'+
+f(this.getUTCHours())+':'+
+f(this.getUTCMinutes())+':'+
+f(this.getUTCSeconds())+'Z';};var m={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};function stringify(value,whitelist){var a,i,k,l,r=/["\\\x00-\x1f\x7f-\x9f]/g,v;switch(typeof value){case'string':return r.test(value)?'"'+value.replace(r,function(a){var c=m[a];if(c){return c;}
+c=a.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+
+(c%16).toString(16);})+'"':'"'+value+'"';case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';}
+if(typeof value.toJSON==='function'){return stringify(value.toJSON());}
+a=[];if(typeof value.length==='number'&&!(value.propertyIsEnumerable('length'))){l=value.length;for(i=0;i<l;i+=1){a.push(stringify(value[i],whitelist)||'null');}
+return'['+a.join(',')+']';}
+if(whitelist){l=whitelist.length;for(i=0;i<l;i+=1){k=whitelist[i];if(typeof k==='string'){v=stringify(value[k],whitelist);if(v){a.push(stringify(k)+':'+v);}}}}else{for(k in value){if(typeof k==='string'){v=stringify(value[k],whitelist);if(v){a.push(stringify(k)+':'+v);}}}}
+return'{'+a.join(',')+'}';}}
+return{stringify:stringify,parse:function(text,filter){var j;function walk(k,v){var i,n;if(v&&typeof v==='object'){for(i in v){if(Object.prototype.hasOwnProperty.apply(v,[i])){n=walk(i,v[i]);if(n!==undefined){v[i]=n;}}}}
+return filter(k,v);}
+if(/^[\],:{}\s]*$/.test(text.replace(/\\./g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof filter==='function'?walk('',j):j;}
+throw new SyntaxError('parseJSON');}};}();}
View
29 chat/public/javascripts/main.js
@@ -0,0 +1,29 @@
+function message(obj){
+ var el = document.createElement('p');
+ if ('announcement' in obj) el.innerHTML = '<em>' + esc(obj.announcement) + '</em>';
+ else if ('message' in obj) el.innerHTML = '<b>' + esc(obj.message[0]) + ':</b> ' + esc(obj.message[1]);
+ document.getElementById('chat').appendChild(el);
+ document.getElementById('chat').scrollTop = 1000000;
+}
+
+function send(){
+ var val = document.getElementById('text').value;
+ socket.send(val);
+ message({ message: ['you', val] });
+ document.getElementById('text').value = '';
+}
+
+function esc(msg){
+ return String(msg).replace(/</g, '&lt;').replace(/>/g, '&gt;');
+};
+
+var socket = new io.Socket(null, {port: 8080, rememberTransport: false});
+socket.connect();
+socket.on('message', function(obj){
+ if ('buffer' in obj){
+ document.getElementById('form').style.display='block';
+ document.getElementById('chat').innerHTML = '';
+
+ for (var i in obj.buffer) message(obj.buffer[i]);
+ } else message(obj);
+});
View
20 chat/public/stylesheets/style.css
@@ -0,0 +1,20 @@
+body {
+ padding: 50px;
+ font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
+}
+
+#chat { height: 400px; overflow: auto; border: 1px solid #eee; font: 13px Helvetica, Arial; }
+
+#chat p { padding: 8px; margin: 0; }
+
+#chat p:nth-child(odd) { background: #F6F6F6; }
+
+#form { background: #333; padding: 5px 10px; display: none; }
+
+#form input[type=text] { width: 90%; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; padding: 5px; background: #fff; border: 1px solid #fff; }
+
+#form input[type=submit] { cursor: pointer; background: #999; border: none; padding: 6px 8px; -moz-border-radius: 8px; -webkit-border-radius: 8px; margin-left: 5px; text-shadow: 0 1px 0 #fff; }
+
+#form input[type=submit]:hover { background: #A2A2A2; }
+
+#form input[type=submit]:active { position: relative; top: 2px; }
View
87 chat/server.js
@@ -0,0 +1,87 @@
+
+/**
+ * Module dependencies.
+ */
+
+var express = require('express');
+
+var app = module.exports = express.createServer();
+
+var io = require('socket.io');
+
+var http = require('http');
+
+// Configuration
+
+app.configure(function(){
+ app.set('views', __dirname + '/views');
+ app.set('view engine', 'jade');
+ app.use(express.bodyDecoder());
+ app.use(express.methodOverride());
+ app.use(app.router);
+ app.use(express.staticProvider(__dirname + '/public'));
+});
+
+app.configure('development', function(){
+ app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
+});
+
+app.configure('production', function(){
+ app.use(express.errorHandler());
+});
+
+// Routes
+
+app.get('/', function(req, res){
+ res.render('index', {
+ locals: {
+ title: 'Express'
+ }
+ });
+});
+
+app.listen(8080);
+
+var io = io.listen(app)
+ , buffer = [];
+
+io.on('connection', function(client){
+ client.send({ buffer: buffer });
+ client.broadcast({ announcement: client.sessionId + ' connected' });
+
+ client.on('message', function(message){
+ var msg = { message: [client.sessionId, message] };
+ buffer.push(msg);
+ if (buffer.length > 15) buffer.shift();
+ client.broadcast(msg);
+ });
+
+ client.on('disconnect', function(){
+ client.broadcast({ announcement: client.sessionId + ' disconnected' });
+ });
+});
+
+// twitter streaming
+var lastTweetId;
+
+setInterval(function(){
+ var client = http.createClient(80, 'search.twitter.com');
+ var request = client.request('GET', '/search.json?q=bieber', {Host: 'search.twitter.com'});
+ request.end();
+ request.on('response', function(response){
+ var data = '';
+ response.on('data', function(chunk){
+ data += chunk;
+ });
+ response.on('end', function(){
+ var obj = JSON.parse(data);
+ var lastTweet = obj.results.shift();
+ if (lastTweet.id_str != lastTweetId){
+ io.broadcast({ announcement: lastTweet.text });
+ lastTweetId = lastTweet.id_str;
+ }
+ });
+ });
+}, 5000);
+
+console.log("Express server listening on port %d", app.address().port)
View
20 chat/test/app.test.js
@@ -0,0 +1,20 @@
+
+// Run $ expresso
+
+/**
+ * Module dependencies.
+ */
+
+var app = require('../app');
+
+
+module.exports = {
+ 'GET /': function(assert){
+ assert.response(app,
+ { url: '/' },
+ { status: 200, headers: { 'Content-Type': 'text/html; charset=utf-8' }},
+ function(res){
+ assert.includes(res.body, '<title>Express</title>');
+ });
+ }
+};
View
8 chat/views/index.jade
@@ -0,0 +1,8 @@
+h1 Socket.IO Chat
+
+#chat
+ p Connecting
+
+form(id: 'form', onsubmit: 'send(); return false;')
+ input(type: 'text', autocomplete: 'off', id: 'text')
+ input(type: 'submit', value: 'Send')
View
9 chat/views/layout.jade
@@ -0,0 +1,9 @@
+!!!
+html
+ head
+ title Socket.IO Chat
+ link(rel='stylesheet', href='/stylesheets/style.css')
+ script(src: '/javascripts/json.js')
+ script(src: '/socket.io/socket.io.js');
+ script(src: '/javascripts/main.js')
+ body!= body

0 comments on commit 245abe1

Please sign in to comment.