Loading Rakefile +4 −3 Original line number Diff line number Diff line Loading @@ -158,13 +158,14 @@ class JsDuckRunner # This excludes Opera and IE < 8. # We check explicitly for IE version to make sure the code works the # same way in both real IE7 and IE7-mode of IE8/9. def add_comments(db_name) def add_comments(db_name, version) comments_base_url = "http://projects.sencha.com/auth" @options += ["--head-html", <<-EOHTML] <script type="text/javascript"> Docs.enableComments = ("withCredentials" in new XMLHttpRequest()) || (Ext.ieVersion >= 8); Docs.baseUrl = "#{comments_base_url}"; Docs.commentsDb = "#{db_name}"; Docs.commentsVersion = "#{version}"; </script> EOHTML end Loading Loading @@ -344,7 +345,7 @@ task :sdk, [:mode] => :sass do |t, args| runner.add_seo if mode == "debug" || mode == "live" runner.add_export_notice("ext-js/4-0") if mode == "export" runner.add_google_analytics if mode == "live" runner.add_comments('comments-ext-js-4') if mode == "debug" || mode == "live" runner.add_comments('ext-js', '4') if mode == "debug" || mode == "live" runner.run runner.copy_sdk_examples if mode == "export" || mode == "live" Loading Loading @@ -441,7 +442,7 @@ task :touch2, [:mode] => :sass do |t, args| runner.add_debug if mode == "debug" runner.add_seo if mode == "debug" || mode == "live" runner.add_google_analytics if mode == "live" runner.add_comments('comments-touch-2') if mode == "debug" || mode == "live" runner.add_comments('touch', '2') if mode == "debug" || mode == "live" runner.run runner.copy_touch2_build if mode != "export" Loading opt/comments-server-side/.gitignore +1 −1 Original line number Diff line number Diff line config.js node_modules opt/comments-server-side/ForumUser.js +6 −2 Original line number Diff line number Diff line Loading @@ -63,14 +63,18 @@ ForumUser.prototype = { getUserFromResult: function(result) { var ids, id; if (result.membergroupids) { var ids = result.membergroupids.split(','); ids = result.membergroupids.split(','); result.membergroupids = []; for(var id in ids) { for (id in ids) { result.membergroupids.push(Number(ids[id])); } } result.moderator = _.include(result.membergroupids, 7); return result; } }; opt/comments-server-side/app.js +75 −39 Original line number Diff line number Diff line Loading @@ -118,6 +118,31 @@ app.namespace('/auth', function(){ req.session.user = null; res.json({ success: true }); }); /** * Handles comment unsubscription requests. */ app.get('/unsubscribe/:subscriptionId', function(req, res) { Subscription.findOne({ _id: req.params.subscriptionId }, function(err, subscription) { if (err) throw(err); if (subscription) { if (req.query.all == 'true') { Subscription.remove({ userId: subscription.userId }, function(err) { res.send("You have been unsubscribed from all threads."); }); } else { Subscription.remove({ _id: req.params.subscriptionId }, function(err) { res.send("You have been unsubscribed from that thread."); }); } } else { res.send("You are already unsubscribed.") } }); }); }); Loading Loading @@ -157,43 +182,8 @@ app.namespace('/auth/:sdk/:version', function(){ /** * Returns number of comments for each class / method */ app.get('/comments_meta', function(req, res) { 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) { res.send(comments); }); }); }); app.get('/comments_meta', util.getCommentsMeta, util.getCommentSubscriptions, function(req, res) { res.send({ comments: req.commentsMeta, subscriptions: req.commentSubscriptions || [] }); }); /** Loading @@ -216,6 +206,7 @@ app.namespace('/auth/:sdk/:version', function(){ var comment = new Comment({ author: req.session.user.username, userId: req.session.user.userid, content: req.body.comment, action: req.body.action, rating: Number(req.body.rating), Loading @@ -226,11 +217,16 @@ app.namespace('/auth/:sdk/:version', function(){ target: target, emaiHash: crypto.createHash('md5').update(req.session.user.email).digest("hex"), sdk: req.params.sdk, version: req.params.version version: req.params.version, moderator: req.session.user.moderator, title: req.body.title, url: req.body.url }); comment.save(function(err, response) { res.json({ success: true, id: response._id, action: req.body.action }); util.sendEmailUpdates(comment); }); }); Loading Loading @@ -275,7 +271,7 @@ app.namespace('/auth/:sdk/:version', function(){ var canDelete = false, comment = req.comment; canDelete = _.include(req.session.user.membergroupids, 7) || req.session.user.username == doc.body.author; canDelete = _.include(req.session.user.membergroupids, 7) || req.session.user.username == req.comment.author; if (!canDelete) { res.json({ success: false, reason: 'Forbidden' }, 403); Loading @@ -289,8 +285,48 @@ app.namespace('/auth/:sdk/:version', function(){ }); }); /** * Get email subscriptions */ app.get('/subscriptions', util.getCommentSubscriptions, function(req, res) { res.json({ subscriptions: req.commentSubscriptions }); }); /** * Subscibe / unsubscribe to a comment thread */ app.post('/subscribe', util.requireLoggedInUser, function(req, res) { var subscriptionBody = { sdk: req.params.sdk, version: req.params.version, target: JSON.parse(req.body.target), userId: req.session.user.userid }; Subscription.findOne(subscriptionBody, function(err, subscription) { if (subscription && req.body.subscribed == 'false') { subscription.remove(function(err, ok) { res.send({ success: true }); }); } else if (!subscription && req.body.subscribed == 'true') { subscription = new Subscription(subscriptionBody); subscription.email = req.session.user.email; subscription.save(function(err, ok) { res.send({ success: true }); }); } }); }); }); app.listen(3000); console.log("Server started..."); opt/comments-server-side/database.js +15 −1 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ Comment = mongoose.model('Comment', new mongoose.Schema({ action: String, author: String, userId: Number, content: String, contentHtml: String, createdAt: Date, Loading @@ -16,7 +17,20 @@ Comment = mongoose.model('Comment', new mongoose.Schema({ target: Array, upVotes: Array, deleted: Boolean, updates: Array updates: Array, mod: Boolean, title: String, url: String })); Subscription = mongoose.model('Subscription', new mongoose.Schema({ sdk: String, version: String, createdAt: Date, userId: Number, email: String, target: Array })); mongoose.connect(config.mongoDb); Loading
Rakefile +4 −3 Original line number Diff line number Diff line Loading @@ -158,13 +158,14 @@ class JsDuckRunner # This excludes Opera and IE < 8. # We check explicitly for IE version to make sure the code works the # same way in both real IE7 and IE7-mode of IE8/9. def add_comments(db_name) def add_comments(db_name, version) comments_base_url = "http://projects.sencha.com/auth" @options += ["--head-html", <<-EOHTML] <script type="text/javascript"> Docs.enableComments = ("withCredentials" in new XMLHttpRequest()) || (Ext.ieVersion >= 8); Docs.baseUrl = "#{comments_base_url}"; Docs.commentsDb = "#{db_name}"; Docs.commentsVersion = "#{version}"; </script> EOHTML end Loading Loading @@ -344,7 +345,7 @@ task :sdk, [:mode] => :sass do |t, args| runner.add_seo if mode == "debug" || mode == "live" runner.add_export_notice("ext-js/4-0") if mode == "export" runner.add_google_analytics if mode == "live" runner.add_comments('comments-ext-js-4') if mode == "debug" || mode == "live" runner.add_comments('ext-js', '4') if mode == "debug" || mode == "live" runner.run runner.copy_sdk_examples if mode == "export" || mode == "live" Loading Loading @@ -441,7 +442,7 @@ task :touch2, [:mode] => :sass do |t, args| runner.add_debug if mode == "debug" runner.add_seo if mode == "debug" || mode == "live" runner.add_google_analytics if mode == "live" runner.add_comments('comments-touch-2') if mode == "debug" || mode == "live" runner.add_comments('touch', '2') if mode == "debug" || mode == "live" runner.run runner.copy_touch2_build if mode != "export" Loading
opt/comments-server-side/.gitignore +1 −1 Original line number Diff line number Diff line config.js node_modules
opt/comments-server-side/ForumUser.js +6 −2 Original line number Diff line number Diff line Loading @@ -63,14 +63,18 @@ ForumUser.prototype = { getUserFromResult: function(result) { var ids, id; if (result.membergroupids) { var ids = result.membergroupids.split(','); ids = result.membergroupids.split(','); result.membergroupids = []; for(var id in ids) { for (id in ids) { result.membergroupids.push(Number(ids[id])); } } result.moderator = _.include(result.membergroupids, 7); return result; } };
opt/comments-server-side/app.js +75 −39 Original line number Diff line number Diff line Loading @@ -118,6 +118,31 @@ app.namespace('/auth', function(){ req.session.user = null; res.json({ success: true }); }); /** * Handles comment unsubscription requests. */ app.get('/unsubscribe/:subscriptionId', function(req, res) { Subscription.findOne({ _id: req.params.subscriptionId }, function(err, subscription) { if (err) throw(err); if (subscription) { if (req.query.all == 'true') { Subscription.remove({ userId: subscription.userId }, function(err) { res.send("You have been unsubscribed from all threads."); }); } else { Subscription.remove({ _id: req.params.subscriptionId }, function(err) { res.send("You have been unsubscribed from that thread."); }); } } else { res.send("You are already unsubscribed.") } }); }); }); Loading Loading @@ -157,43 +182,8 @@ app.namespace('/auth/:sdk/:version', function(){ /** * Returns number of comments for each class / method */ app.get('/comments_meta', function(req, res) { 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) { res.send(comments); }); }); }); app.get('/comments_meta', util.getCommentsMeta, util.getCommentSubscriptions, function(req, res) { res.send({ comments: req.commentsMeta, subscriptions: req.commentSubscriptions || [] }); }); /** Loading @@ -216,6 +206,7 @@ app.namespace('/auth/:sdk/:version', function(){ var comment = new Comment({ author: req.session.user.username, userId: req.session.user.userid, content: req.body.comment, action: req.body.action, rating: Number(req.body.rating), Loading @@ -226,11 +217,16 @@ app.namespace('/auth/:sdk/:version', function(){ target: target, emaiHash: crypto.createHash('md5').update(req.session.user.email).digest("hex"), sdk: req.params.sdk, version: req.params.version version: req.params.version, moderator: req.session.user.moderator, title: req.body.title, url: req.body.url }); comment.save(function(err, response) { res.json({ success: true, id: response._id, action: req.body.action }); util.sendEmailUpdates(comment); }); }); Loading Loading @@ -275,7 +271,7 @@ app.namespace('/auth/:sdk/:version', function(){ var canDelete = false, comment = req.comment; canDelete = _.include(req.session.user.membergroupids, 7) || req.session.user.username == doc.body.author; canDelete = _.include(req.session.user.membergroupids, 7) || req.session.user.username == req.comment.author; if (!canDelete) { res.json({ success: false, reason: 'Forbidden' }, 403); Loading @@ -289,8 +285,48 @@ app.namespace('/auth/:sdk/:version', function(){ }); }); /** * Get email subscriptions */ app.get('/subscriptions', util.getCommentSubscriptions, function(req, res) { res.json({ subscriptions: req.commentSubscriptions }); }); /** * Subscibe / unsubscribe to a comment thread */ app.post('/subscribe', util.requireLoggedInUser, function(req, res) { var subscriptionBody = { sdk: req.params.sdk, version: req.params.version, target: JSON.parse(req.body.target), userId: req.session.user.userid }; Subscription.findOne(subscriptionBody, function(err, subscription) { if (subscription && req.body.subscribed == 'false') { subscription.remove(function(err, ok) { res.send({ success: true }); }); } else if (!subscription && req.body.subscribed == 'true') { subscription = new Subscription(subscriptionBody); subscription.email = req.session.user.email; subscription.save(function(err, ok) { res.send({ success: true }); }); } }); }); }); app.listen(3000); console.log("Server started...");
opt/comments-server-side/database.js +15 −1 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ Comment = mongoose.model('Comment', new mongoose.Schema({ action: String, author: String, userId: Number, content: String, contentHtml: String, createdAt: Date, Loading @@ -16,7 +17,20 @@ Comment = mongoose.model('Comment', new mongoose.Schema({ target: Array, upVotes: Array, deleted: Boolean, updates: Array updates: Array, mod: Boolean, title: String, url: String })); Subscription = mongoose.model('Subscription', new mongoose.Schema({ sdk: String, version: String, createdAt: Date, userId: Number, email: String, target: Array })); mongoose.connect(config.mongoDb);