var marked = require('marked'),
_ = require('underscore'),
sanitizer = require('sanitizer'),
nodemailer = require("nodemailer");
exports.sanitize = function(content, opts) {
var markdowned, sanitized_output, urlFunc;
try {
markdowned = marked(content);
} catch(e) {
markdowned = content;
}
var exp = /(\bhttps?:\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/igm;
markdowned = markdowned.replace(exp, "$1");
if (opts && opts.stripUrls) {
urlFunc = function(str) {
if (str.match(/^(http:\/\/(www\.)?sencha.com|#))/)) {
return str;
} else {
return '';
}
};
}
sanitized_output = sanitizer.sanitize(markdowned, urlFunc);
sanitized_output = sanitized_output.replace(/'/g, ''');
return sanitized_output;
};
exports.formatComments = function(comments, req) {
return _.map(comments, function(comment) {
comment = _.extend(comment._doc, {
score: comment.upVotes.length - comment.downVotes.length,
createdAt: String(comment.createdAt)
});
if (req.session.user) {
comment.upVote = _.contains(comment.upVotes, req.session.user.username);
comment.downVote = _.contains(comment.downVotes, req.session.user.username);
}
return comment;
});
};
exports.vote = function(req, res, comment) {
var voteDirection;
if (req.session.user.username == comment.author) {
// Ignore votes from the author
res.json({success: false, reason: 'You cannot vote on your own content'});
return;
} else if (req.body.vote == 'up' && !_.include(comment.upVotes, req.session.user.username)) {
var voted = _.include(comment.downVotes, req.session.user.username);
comment.downVotes = _.reject(comment.downVotes, function(v) {
return v == req.session.user.username;
});
if (!voted) {
voteDirection = 'up';
comment.upVotes.push(req.session.user.username);
}
} else if (req.body.vote == 'down' && !_.include(comment.downVotes, req.session.user.username)) {
var voted = _.include(comment.upVotes, req.session.user.username);
comment.upVotes = _.reject(comment.upVotes, function(v) {
return v == req.session.user.username;
});
if (!voted) {
voteDirection = 'down';
comment.downVotes.push(req.session.user.username);
}
}
comment.save(function(err, response) {
res.json({
success: true,
direction: voteDirection,
total: (comment.upVotes.length - comment.downVotes.length)
});
});
};
exports.requireLoggedInUser = function(req, res, next) {
if (!req.session || !req.session.user) {
res.json({success: false, reason: 'Forbidden'}, 403);
} else {
next();
}
};
exports.findComment = function(req, res, next) {
if (req.params.commentId) {
Comment.findById(req.params.commentId, function(err, comment) {
req.comment = comment;
next();
});
} else {
res.json({success: false, reason: 'No such comment'});
}
};
exports.sendEmailUpdates = function(comment) {
var mailTransport = nodemailer.createTransport("SMTP",{
host: 'localhost',
port: 25
});
var sendSubscriptionEmail = function(emails) {
var email = emails.shift();
if (email) {
nodemailer.sendMail(email, function(err){
if (err){
console.log(err);
} else{
console.log("Sent email to " + email.to);
sendSubscriptionEmail(emails);
}
});
} else {
console.log("Finished sending emails");
mailTransport.close();
}
}
var subscriptionBody = {
sdk: comment.sdk,
version: comment.version,
target: comment.target
};
var emails = [];
Subscription.find(subscriptionBody, function(err, subscriptions) {
_.each(subscriptions, function(subscription) {
var mailOptions = {
transport: mailTransport,
from: "Sencha Documentation ",
to: subscription.email,
subject: "Comment on '" + comment.title + "'",
text: [
"A comment by " + comment.author + " on '" + comment.title + "' was posted on the Sencha Documentation:\n",
comment.content + "\n",
"--",
"Original thread: " + comment.url,
"Unsubscribe from this thread: http://projects.sencha.com/auth/unsubscribe/" + subscription._id,
"Unsubscribe from all threads: http://projects.sencha.com/auth/unsubscribe/" + subscription._id + '?all=true'
].join("\n")
}
if (Number(comment.userId) != Number(subscription.userId)) {
emails.push(mailOptions);
}
});
if (emails.length) {
sendSubscriptionEmail(emails);
} else {
console.log("No emails to send");
}
});
}
exports.getCommentsMeta = function(req, res, next) {
var map = function() {
if (this.target) {
emit(this.target.slice(0,3).join('__'), 1);
} else {
return;
}
}
var reduce = function(key, values) {
var i = 0, total = 0;
for (; i< values.length; i++) {
total += values[i];
}
return total;
}
mongoose.connection.db.executeDbCommand({
mapreduce: 'comments',
map: map.toString(),
reduce: reduce.toString(),
out: 'commentCounts',
query: {
deleted: { '$ne': true },
sdk: req.params.sdk,
version: req.params.version
}
}, function(err, dbres) {
mongoose.connection.db.collection('commentCounts', function(err, collection) {
collection.find({}).toArray(function(err, comments) {
req.commentsMeta = comments;
next()
});
});
});
}
exports.getCommentSubscriptions = function(req, res, next) {
if (req.session.user) {
Subscription.find({
sdk: req.params.sdk,
version: req.params.version,
userId: req.session.user.userid
}, function(err, subscriptions) {
req.commentSubscriptions = _.map(subscriptions, function(subscription) {
return subscription.target;
});
next();
})
} else {
next();
}
}