Skip to content

Commit

Permalink
[0.2.0] Initial commit to github
Browse files Browse the repository at this point in the history
  • Loading branch information
alejandro committed Nov 13, 2011
0 parents commit e907b3b
Show file tree
Hide file tree
Showing 12 changed files with 455 additions and 0 deletions.
35 changes: 35 additions & 0 deletions app.js
@@ -0,0 +1,35 @@

/**
* Module dependencies.
*/

var express = require('express')
, routes = require('./routes')

var app = module.exports = express.createServer();

// Configuration

app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});

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

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

// Routes

app.get('/', routes.index);

app.listen(3000);
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
2 changes: 2 additions & 0 deletions bdd/dotcloud.yml
@@ -0,0 +1,2 @@
node-comm:
type: redis
231 changes: 231 additions & 0 deletions lib/comments.js
@@ -0,0 +1,231 @@
/*
* node-comm
* Copyright (c) 2011 Alejandro Morales <vamg008@gmail.com>
* MIT Licensed
*/

/* Change this for your own namespace */
const NAMESPACE = 'ncomm';
var redis = require('./redis').redis,
url = require('url').parse,
util = require('./utils.js').util;


/* threadKey
* Defining the mask for process. Receive two arguments:
* @id that is the page identifier for example: http://test.com/d/i/r/topath the id would be dirtopath
* @parent is the hostname for of the page: i.e test.com
*/
var threadKey = module.exports.newComment = function(id,parent) {
return NAMESPACE + ':' + parent + ':' + id;
}

/* shortTKeys
* Defining the mask for a site. Receive one argument:
* @parent is the hostname for the page: i.e test.com
* In redis is a hash
*/
var shortTKeys = module.exports.urlThreadKey = function(parent) {
return NAMESPACE + ':' + parent;
}
/* convertURL(ur)
* Convert url to only alphanumeric chars for redis key string support
*/
var convertURL = function(_url) {
var host = url(_url).hostname,
slug = url(_url).pathname;
/* We don't want to make a key with a protocol that is not browser based (?) */
return { host: host, slug: slug.replace(/[^\w \xC0-\xFF]/g,'') };
}
var slOff = function(_url){
return _url.replace(/[^\w \xC0-\xFF]/g,'') ;
}

/* Delete duplicate members */
Array.prototype.unique = function () {
var r = new Array();
o:for(var i = 0, n = this.length; i < n; i++){
for(var x = 0, y = r.length; x < y; x++) {
if(r[x]==this[i]) {
continue o;
}
}
r[r.length] = this[i];
}
return r;
}
/*
* A new Comment has these params:
* @url: Has the asociate url for the comment Box
* @username: The username that post the comment
* @reply: an Array that contains two values, a bolean that define if the comment is a reply and a commentId or null(by default)
* @comment: the comment.
* @id: Comment # id like 1,2,3,4
*/
/*
* A valid comment looks like this:
{ url:'http://numbus.co:8080/f/prueba/h',
comment: { authorId: "4ebef2c27f21bd298a000000", comment: "YOUR COMMENT",time: Date.now(),
parent: "URL parent or comment parent as reply" } }
*/
var newComment = module.exports.newComment = function(Object,res) {
var O = Object;
/* the RegExp was a const but everytwo presented a bug */
if (/^(http:\/\/)([\w]+\.){1,}[A-Z]{2,}\b/gi.test(O.url)) {
var threadId = convertURL(O.url).slug,
parent = convertURL(O.url).host;
thread = threadKey(threadId,parent),
toJSONString = function(val){val.comment = util.toStaticHTML(val.comment);return JSON.stringify(val)};
redis.exists(thread, function(e,d){
if (e) res('No ok: ' + e,null);
redis.hincrby(thread,'id',1,function(e4,d4){
redis.hincrby('u:' + O.comment.authorId, 'id',1, function(error, data){
O.comment.lid = data, O.comment.id = d4; /* Setting up floating points */
redis.multi()
.HSET('u:' + O.comment.authorId, data, toJSONString(O.comment))
.HSET(thread,d4, toJSONString(O.comment))
.lpush(shortTKeys(parent),url(O.url).pathname)
.exec(function(e2,d2){
if (e2) res('No ok: ' + err, null)
res(null, d2)
});
});
});
})
} else {
res('I need an url', null)
}
}
var deleteComment = exports.deleteComment = function(Object,res){
var nO = Object;
if (/^(http:\/\/)([\w]+\.){1,}[A-Z]{2,}\b/gi.test(nO.url)) {
var threadId = convertURL(nO.url).slug,
parent = convertURL(nO.url).host;
thread = threadKey(threadId,parent),
comment = nO.comment;
redis.multi()
.HDEL(thread, comment.id)
.HDEL('u:'+ comment.authorId, comment.lid)
.exec(function(e,d2){
if (e) {
res('No ok: ' + e, null)
} else {
res(null, 'ok')
}
});
} else {
res('I need an url', null)
}
}

var fetchByThread = module.exports.fetch = function(Object,res){
var nO = Object,
threadId = convertURL(nO.url).slug,
parent = convertURL(nO.url).host,
thread = threadKey(threadId,parent);
redis.hgetall(thread, function(e,d){
if (e){
res(e,null);
} else {
res(null,d);
}
});
}
var fetchByUser = module.exports.fetchByUser = function(Object, res) {
redis.hgetall('u:' + Object.comment.authorId, function(e,d){
if (!e) {
res(null, d);
} else {
res(e,null);
}
});
}
var fetchBySite = module.exports.fetchBySite = function(site,res){
redis.lrange(shortTKeys(site), 0, -1, function(e,d){
if (e) {
res(e, null);
} else {
var d = d.unique();
var r = [];
var i = 0;
d.forEach(function(u){
var threadId = slOff(u),
parent = site,
thread = threadKey(threadId,parent);
redis.hgetall(thread, function(e,dd){
i++;
r.push({"path": u, "comments": dd});
if (i === d.length) {
res(null, JSON.stringify(r));
}
});

});

}
});
}
var merge = module.exports.merge = function (obj1, obj2) {
for (var p in obj2) {
try {
if ( obj2[p].constructor===Object ) {
obj1[p] = merge(obj2[p], obj1[p]);
} else {
if (typeof parseFloat(p) != 'number') {
obj1[p] = obj2[p];
}
}
} catch(e) {
obj1[p] = obj2[p];
}
}
return obj1;
}
var edit = module.exports.edit = function(obj, res){
var nO = obj,
threadId = convertURL(nO.url).slug,
parent = convertURL(nO.url).host,
thread = threadKey(threadId,parent);
redis.hget(thread, nO.comment.id, function(e,d){
if (d) {
d = JSON.parse(d);
d.comment = nO.comment.comment;
d.time = Date.now();
redis.hset(thread, nO.comment.id, JSON.stringify(d), function(e,d){
if (d===0) d ='ok';
res(e,d);
});
}
});
}

/*
var test = {url:'http://numbus.co:8080/f/pruebas/h/hsas', comment: { authorId: "4ebef2c27f21bd298a000000", comment: "He SIDO EDITADO 2 veces",time: Date.now(), parent: "URL parent or comment parent as reply sistema",id:2,lid:1 } };
edit(test, function(e,d){
console.log(d);
});
*/
/* Pruebas */
/*
* All the methods are asyncronous...
* for example for a new comment just do:
var test = { url:'http://numbus.co:8080/f/pruebas/h', comment: { authorId: "4ebef2c27f21bd298a000000", comment: "YOUR PROBANDO",time: Date.now(), parent: "URL parent or comment parent as reply sistema" } };
newComment(test, function(e,d){
console.log(d);
});
* for delete a comment do:
var dtest ={url:'http://numbus.co:8080/f/pruebas/h',comment:{authorId: "4ebef2c27f21bd298a000000",lid:1,id:1}}
deleteComment(dtest, function(e,d){
console.log(d);
});
*/
/*
for (var i=0;i<1; i++) {
comment= { authorId: "4ebef2c27f21bd298a000000", comment: "YOUR PROBANDO" +i,time: Date.now(), parent: "URL parent or comment parent as reply sistema" } ;
newComment({ url:'http://numbus.co/f/pruebas/h/hsas', comment:comment}, function(e,d){
});
}
*/
6 changes: 6 additions & 0 deletions lib/options.js
@@ -0,0 +1,6 @@
exports.codeName = 'node-com';
exports.ver = '0.3.1';
exports.port = '8100';
exports.type = 'env';
exports.env = process.env.NODE_ENV || 'DEV';
exports.processDate = Date.now();
18 changes: 18 additions & 0 deletions lib/redis.js
@@ -0,0 +1,18 @@
var options = require('./options');
var redis = require('redis');
if (options.env == 'production') {
var createRedisClient = function() {
var db = redis.createClient(9034, 'carp.redistogo.com');
var dbAuth=function() { db.auth('2ac23e223b531f90263935c0f6ff4a1e');};
db.addListener('connected',dbAuth);
db.addListener('reconnected',dbAuth);
db.on("error", function (err) {
console.log((err).red);
});
dbAuth();
return db;
};
exports.redis = createRedisClient();
} else {
exports.redis = redis.createClient();
}
42 changes: 42 additions & 0 deletions lib/utils.js
@@ -0,0 +1,42 @@
var util= exports.util = {
urlRE: /https?:\/\/([-\w\.]+)+(:\d+)?(\/([^\s]*(\?\S+)?)?)?/g,

// html sanitizer
toStaticHTML: function(inputHtml) {
inputHtml = inputHtml.toString();
return inputHtml.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;");
},

//pads n with zeros on the left,
//digits is minimum length of output
//zeroPad(3, 5); returns "005"
//zeroPad(2, 500); returns "500"
zeroPad: function (digits, n) {
n = n.toString();
while (n.length < digits)
n = '0' + n;
return n;
},

//it is almost 8 o'clock PM here
//timeString(new Date); returns "19:49"
timeString: function (date) {
var minutes = date.getMinutes().toString();
var hours = date.getHours().toString();
return this.zeroPad(2, hours) + ":" + this.zeroPad(2, minutes);
},

//does the argument only contain whitespace?
isBlank: function(text) {
var blank = /^\s*$/;
return (text.match(blank) !== null);
}
};

//used to keep the most recent messages visible
function scrollDown () {
window.scrollBy(0, 100000000000000000);
$("#entry").focus();
}
9 changes: 9 additions & 0 deletions package.json
@@ -0,0 +1,9 @@
{
"name": "application-name"
, "version": "0.0.1"
, "private": true
, "dependencies": {
"express": "2.5.0"
, "jade": ">= 0.0.1"
}
}

0 comments on commit e907b3b

Please sign in to comment.