Created
February 24, 2011 18:09
-
-
Save sgodbillon/842580 to your computer and use it in GitHub Desktop.
Minitwitter in full javascript both client/server side with mongodb and nodeJS -- full app available on https://github.com/sgodbillon/minitwitter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Full source code available on https://github.com/sgodbillon/minitwitter | |
var nmnLocation = '/path/to/node-mongodb-native' | |
var Db = require(nmnLocation).Db, | |
Server = require(nmnLocation).Server; | |
var host = 'localhost'; | |
var port = 27017; | |
var getTweetsCollection = function(callback) { | |
var db = new Db('minitwitter', new Server(host, port)) | |
db.open(function() { | |
db.createCollection('tweets', function() { | |
db.collection('tweets', function(error, collection) { | |
console.log(error) | |
callback(collection) | |
db.close() | |
}) | |
}) | |
}) | |
} | |
this.createTweet = function(tweet, callback) { | |
getTweetsCollection(function(collection) { | |
collection.insert(tweet) | |
}) | |
} | |
this.listTweets = function(search, callback) { | |
var filter = {} | |
if(search.message) { | |
filter.message = search.message.replace(/[^\w\s]/g, '') | |
filter.message = new RegExp('.*' + filter.message + '.*') | |
} | |
getTweetsCollection(function(collection) { | |
collection.find(filter, {sort: [['date', 'descending']]}, function(error, docs) { | |
var result = [] | |
docs.each(function(i, doc) { | |
if(doc == null) | |
callback(result) | |
else result.push(doc) | |
}) | |
}) | |
}) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/***** HTTP layer *****/ | |
var SYS = require('sys'); | |
var HTTP = require('http'); | |
var URL = require('url'); | |
var FS = require('fs'); | |
var PATH = require('path'); | |
HTTP.createServer(function (request, response) { | |
var parsedURL = URL.parse(request.url, true) | |
console.log('->', parsedURL.pathname) | |
// list tweets | |
if(parsedURL.pathname == '/tweets' && request.method == 'GET') { | |
var search = {} | |
if(parsedURL.query && parsedURL.query.search) | |
search.message = parsedURL.query.search | |
require('./mongo').listTweets(search, function(tweets) { | |
var result = JSON.stringify(tweets) | |
response.writeHead(200, { | |
'Content-Length': result.length, | |
'Content-Type': 'text/json' | |
}) | |
response.end(result) | |
}) | |
// create a tweet | |
} else if(parsedURL.pathname == '/tweets' && request.method == 'POST') { | |
var obj = undefined | |
request.on('data', function(data) { | |
try { | |
data = data.toString().replace(/\n/g, '\\n') | |
obj = JSON.parse(data) | |
obj.date = new Date().getTime() | |
require('./mongo').createTweet(obj, function() { | |
response.writeHead(201) | |
response.end() | |
}) | |
} catch(e) { | |
console.log('data were', typeof data, data, 'e=',e) | |
response.writeHead(500, 'Wrong data: not JSON?') | |
response.end() | |
} | |
}) | |
request.on('end', function() { | |
if(!obj) { | |
response.writeHead(500, 'No data?') | |
response.end(); | |
} | |
}) | |
// index | |
} else if(parsedURL.pathname == '/' && request.method == 'GET') { | |
var view = FS.readFileSync(__dirname + '/index.html') | |
response.writeHead(200, { | |
'Content-Type': 'text/html' | |
}) | |
response.write(view) | |
response.end() | |
// static files | |
} else if(parsedURL.pathname.indexOf('/public/') == 0 && request.method == 'GET') { | |
var path = __dirname + parsedURL.pathname | |
path = PATH.normalize(path) | |
if(path.indexOf(__dirname) != 0) { | |
response.writeHead(403, 'Forbidden') | |
response.end() | |
} else { | |
PATH.exists(path, function(exists) { | |
if(exists) { | |
var head = {} | |
if(/css$/.test(path)) { | |
head['Content-Type'] = 'text/css' | |
} | |
if(/js$/.test(path)) { | |
head['Content-Type'] = 'text/javascript' | |
} | |
if(/png$/.test(path)) { | |
head['Content-Type'] = 'image/png' | |
} | |
if(/(jpg|jpeg)$/.test(path)) { | |
head['Content-Type'] = 'image/jpeg' | |
} | |
console.log('served static file', path, 'with head', SYS.inspect(head)) | |
response.writeHead(200, head) | |
response.write(FS.readFileSync(path)) | |
response.end() | |
} else { | |
response.writeHead(404) | |
response.end() | |
} | |
}) | |
} | |
// not found. | |
} else { | |
response.writeHead(404, 'Not Found!!') | |
response.end() | |
} | |
}).listen(8124); | |
console.log('Server running at http://127.0.0.1:8124/'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$(function() { | |
var makeTagLinks = function(str) { | |
return str.replace(/(#\w+)/g, '<a class="tag" href="#">$1</a>') | |
} | |
var createTweet = function(tweet, callback) { | |
$.post('/tweets',tweet, function() { | |
console.log('created tweet', tweet) | |
if(callback) callback() | |
}) | |
} | |
var listTweets = function(params, callback) { | |
$.get('/tweets', params || {}, function(data) { | |
console.log('list tweets', data) | |
if(callback) callback(data) | |
}) | |
} | |
var updateTweetList = function(params) { | |
listTweets(params, function(data) { | |
var $ul = $('#tweets ul') | |
$ul.children().remove() | |
$.each(data, function(i, tweet) { | |
$ul.append('<li><img src="/public/images/zengularity-logo-without-name.png" class="picture"/><a href="#" class="user">SGO</a>' + makeTagLinks(tweet.message) + '</div></li>') | |
}) | |
}) | |
} | |
$('#new-tweet form').submit(function() { | |
createTweet(JSON.stringify({"message": $('#message').val()}), function() { | |
updateTweetList() | |
}) | |
return false | |
}) | |
$('#search').submit(function() { | |
updateTweetList({search: $('#search input').val()}) | |
return false | |
}) | |
$('.tag').live('click', function() { | |
$('#search input').val($(this).text()) | |
$('#search').submit() | |
return false | |
}) | |
updateTweetList() | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<title>Home</title> | |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | |
<link rel="stylesheet" type="text/css" media="screen" href="/public/stylesheets/main.css"> | |
<link rel="shortcut icon" type="image/png" href="/public/images/favicon.png"> | |
<script src="/public/javascripts/jquery-1.4.2.min.js" type="text/javascript" charset="utf-8"></script> | |
<script src="/public/javascripts/zentweet-client.js" type="text/javascript" charset="utf-8"></script> | |
</head> | |
<body> | |
<header> | |
<a href="/">Zentweet</a> | |
<form id="search" action="#" method="post"> | |
<input type="text" placeholder="search" name="search" /> | |
</form> | |
</header> | |
<article id="new-tweet"> | |
<form action="#" method="post"> | |
<div> | |
<label>What's happening ?</label> | |
<textarea type="text" name="message" id="message"></textarea> | |
</div> | |
<div> | |
<input type="submit" /> | |
</div> | |
</form> | |
</article> | |
<article id="tweets"> | |
<ul> | |
</ul> | |
</article> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment