Skip to content

Instantly share code, notes, and snippets.

@sgodbillon
Created February 24, 2011 18:09
Show Gist options
  • Save sgodbillon/842580 to your computer and use it in GitHub Desktop.
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
// 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)
})
})
})
}
/***** 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/');
$(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()
})
<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