var connect = require( 'connect' );
var Session = connect.middleware.session.Session;
var parseCookie = connect.utils.parseCookie;
+var Backchannel = require('../bc/backchannel');
// Depracated
// Used for initial testing
});
}
+function checkAjax( req, res, next ) {
+ if ( req.xhr ) {
+ next();
+ } else {
+ res.redirect( '/' );
+ }
+}
+
// Dynamic Helpers are loaded automatically into views
app.dynamicHelpers( {
// express-messages is for flash messages for easy
// Used to display all available schools and any courses
// in those schools.
// Public with some private information
-app.get( '/schools', loadUser, function( req, res ) {
+app.get( '/schools', checkAjax, loadUser, function( req, res ) {
var user = req.user;
+ var schoolList = [];
// Find all schools and sort by name
// XXX mongoose's documentation on sort is extremely poor, tread carefully
School.find( {} ).sort( 'name', '1' ).run( function( err, schools ) {
if( schools ) {
// If schools are found, loop through them gathering any courses that are
// associated with them and then render the page with that information.
- async.forEach(
- schools,
- function( school, callback ) {
- // Check if user is authorized with each school
- school.authorize( user, function( authorized ) {
- // This is used to display interface elements for those users
- // that are are allowed to see them, for instance a 'New Course' button.
- school.authorized = authorized;
-
- // Find all courses for school by it's id and sort by name
- Course.find( { 'school' : school._id } ).sort( 'name', '1' ).run( function( err, courses ) {
- // If any courses are found, set them to the appropriate school, otherwise
- // leave empty.
- if( courses.length > 0 ) {
- school.courses = courses.filter(function(course) {
- if (!course.deleted) return course;
- });
- } else {
- school.courses = [];
- }
- // This tells async (the module) that each iteration of forEach is
- // done and will continue to call the rest until they have all been
- // completed, at which time the last function below will be called.
- callback();
- });
- });
- },
- // After all schools and courses have been found, render them
- function( err ) {
- res.render( 'schools', { 'schools' : schools } );
- }
- );
+ res.json({ 'schools' : schools.map(function(school) {
+ return school.sanitized;
+ })})
} else {
// If no schools have been found, display none
- res.render( 'schools', { 'schools' : [] } );
+ //res.render( 'schools', { 'schools' : [] } );
+ res.json({ 'schools' : [] });
}
});
});
+app.get( '/school/:id', checkAjax, loadUser, loadSchool, function( req, res ) {
+ var school = req.school;
+ var user = req.user;
+
+ school.authorize( user, function( authorized ) {
+ // This is used to display interface elements for those users
+ // that are are allowed to see th)m, for instance a 'New Course' button.
+ var sanitizedSchool = school.sanitized;
+ sanitizedSchool.authorized = authorized;
+ // Find all courses for school by it's id and sort by name
+ Course.find( { 'school' : school._id } ).sort( 'name', '1' ).run( function( err, courses ) {
+ // If any courses are found, set them to the appropriate school, otherwise
+ // leave empty.
+ if( courses.length > 0 ) {
+ sanitizedSchool.courses = courses.filter(function(course) {
+ if (!course.deleted) return course;
+ }).map(function(course) {
+ return course.sanitized;
+ });
+ } else {
+ sanitizedSchool.courses = [];
+ }
+ // This tells async (the module) that each iteration of forEach is
+ // done and will continue to call the rest until they have all been
+ // completed, at which time the last function below will be called.
+ res.json({ 'school': sanitizedSchool })
+ });
+ });
+});
+
// New course page
// Displays form to create new course
// Private, requires user to be authorized
//
// Data types:
// Posts - Posts are the main items in backchannel, useful for questions or discussion points
-// [[ example object needed]]
+// [[ example object needed with explanation E.G:
+/*
+ Post: { postID: '999-1',
+ userID: '1234',
+ userName: 'Bob Jones',
+ userAffil: 'Instructor',
+ body: 'This is the text content of the post.',
+ comments: { {<commentObj>, <commentObj>, ...},
+ public: true,
+ votes: [ <userID>, <userID>, ...],
+ reports: [ <userID>, <userID>, ...]
+ }
+ Comment: { body: 'foo bar', userName: 'Bob Jones', userAffil: 'Instructor' }
+
+ if anonymous: userName => 'Anonymous', userAffil => 'N/A'
+*/
+//
+//
+//
// Comments - Comments are replies to posts, for clarification or answering questions
// [[ example object needed]]
// Votes - Votes signifyg a users approval of a post
// [[ example needed ]]
// reports - An array of user ids which are the users that reported the post
// [[ reports would be "this post is flagged as inappropriate"? ]]
+// [[ bruml: consistent terminology needed ]]
//
// Posts and comments can be made anonymously. When a post is anonymous, the users info is stripped
// from the post and the userName is set to Anonymous and the userAffil to N/A. This is to allow
}
});
-
-var backchannel = io
-.of( '/backchannel' )
-.on( 'connection', function( socket ) {
-
- socket.on('subscribe', function(lecture, cb) {
- socket.join(lecture);
+var backchannel = new Backchannel(app, io.of('/backchannel'), {
+ subscribe: function(lecture, send) {
Post.find({'lecture': lecture}, function(err, posts) {
- if (socket.handshake.user) {
- cb(posts);
- } else {
- var posts = posts.filter(
- function(post) {
- if (post.public)
- return post;
- }
- )
- cb(posts)
- }
+ send(posts);
});
- });
-
- socket.on('post', function(res) {
+ },
+ post: function(fillPost) {
var post = new Post;
- var _post = res.post;
- var lecture = res.lecture;
- post.lecture = lecture;
- if ( _post.anonymous ) {
- post.userid = 0;
- post.userName = 'Anonymous';
- post.userAffil = 'N/A';
- } else {
- post.userName = _post.userName;
- post.userAffil = _post.userAffil;
- }
-
- post.public = _post.public;
- post.date = new Date();
- post.body = _post.body;
- post.votes = [];
- post.reports = [];
- post.save(function(err) {
- if (err) {
- // XXX some error handling
- console.log(err);
- } else {
- if (post.public) {
- backchannel.in(lecture).emit('post', post);
- } else {
- privateEmit(lecture, 'post', post);
- }
- }
+ fillPost(post, function(send) {
+ post.save(function(err) {
+ send();
+ });
});
- });
-
- socket.on('vote', function(res) {
- var vote = res.vote;
- var lecture = res.lecture;
- Post.findById(vote.parentid, function( err, post ) {
- if (!err) {
- if (post.votes.indexOf(vote.userid) == -1) {
- post.votes.push(vote.userid);
- post.save(function(err) {
- if (err) {
- // XXX error handling
- } else {
- if (post.public) {
- backchannel.in(lecture).emit('vote', vote);
- } else {
- privteEmit(lecture, 'vote', vote);
- }
- }
- });
- }
- }
- })
- });
-
- socket.on('report', function(res) {
- var report = res.report;
- var lecture = res.lecture;
- Post.findById(report.parentid, function( err, post ){
- if (!err) {
- if (post.reports.indexOf(report.userid) == -1) {
- post.reports.push(report.userid);
- post.save(function(err) {
- if (err) {
- // XXX error handling
- } else {
- if (post.public) {
- backchannel.in(lecture).emit('report', report);
- } else {
- privateEmit(lecture, 'report', report);
- }
- }
- });
- }
- }
- })
- });
-
- socket.on('comment', function(res) {
- var comment = res.comment;
- var lecture = res.lecture;
- console.log('anon', comment.anonymous);
- if ( comment.anonymous ) {
- comment.userid = 0;
- comment.userName = 'Anonymous';
- comment.userAffil = 'N/A';
- }
- Post.findById(comment.parentid, function( err, post ) {
- if (!err) {
- post.comments.push(comment);
- post.date = new Date();
+ },
+ items: function(postId, addItem) {
+ Post.findById(postId, function( err, post ) {
+ addItem(post, function(send) {
post.save(function(err) {
- if (err) {
- console.log(err);
- } else {
- if (post.public) {
- backchannel.in(lecture).emit('comment', comment);
- } else {
- privateEmit(lecture, 'comment', comment);
- }
- }
- })
- }
- })
- });
-
- function privateEmit(lecture, event, data) {
- backchannel.clients(lecture).forEach(function(socket) {
- if (socket.handshake.user)
- socket.emit(event, data);
+ send();
+ });
+ })
})
}
-
- socket.on('disconnect', function() {
- //delete clients[socket.id];
- });
});
+
+
var counters = {};
var counts = io