crunch-node/app.js

631 lines
21 KiB
JavaScript

var express = require('express');
var flash = require('express-flash');
var path = require('path');
var passport = require('passport');
var Strategy = require('passport-local').Strategy;
var async = require('async');
var multer = require('multer');
var fs = require('fs');
var markdown = require( "markdown" ).markdown;
var moment = require("moment");
// Get connected to our database
var MongoClient = require('mongodb').MongoClient;
Post = require('./post.js');
User = require('./user.js');
Category = require('./category.js');
Static = require('./static.js');
var database = require('./db.js');
var genPhotos = require('./genPhotos.js');
var app = express();
// Get config variables
var config = require('./config.js').config;
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// Make HTML pretty while we're setting up our jade templates
// but it doesn't need to be pretty in production.
// uncomment after placing your favicon in /public
//app.use(require('serve-favicon')(path.join(__dirname, 'public',
// 'favicon.ico')));
app.use(flash());
app.use(require('morgan')('dev'));
app.use(require('cookie-parser')());
app.use(require('body-parser').urlencoded({ extended: true }));
app.use(require('express-session')({
secret: 'amdasdfasdfamd',
resave: true,
saveUninitialized: true })
);
app.use(express.static(path.join(__dirname, 'public')));
var upload = multer({ dest: config.uploadDir });
// Setup authentication via twitter.
passport.use(new Strategy(
function(username, password, done) {
User.verify(username, password, function(err, user) {
console.log("Verifying user: " + username);
if (!user) { return done(null, false); }
return done(null, user);
});
}
));
passport.serializeUser(function(user, done) {
console.log("Serializing user: "+user.username);
done(null, user.username);
});
passport.deserializeUser(function(username, done) {
console.log("Deserializing user: "+username);
User.getByUsername(username, function (err, user) {
if (!user) { return done(false); }
done(null, user);
});
});
app.use(passport.initialize());
app.use(passport.session());
// Require logins for all admin pages other pages have to be handled separately.
app.all('/admin*', require('connect-ensure-login').ensureLoggedIn());
// User management routing
app.get('/login', function(req, res) {
res.render('admin-login', {user: req.user});
});
app.post('/login',
passport.authenticate('local', { successReturnToOrRedirect: '/admin', failureRedirect: '/login' })
);
app.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
}
);
// Post management routing
// GET /admin/post/list
app.get('/admin/post/list/:start?',
function(req, res, next) {
var count = 25;
if (req.params.start) {
var start = req.params.start;
} else {
var start = 0;
}
Post.getPosts(count, start, function(err, posts){
res.render('admin-post-list', {posts, user: req.user});
});
}
);
// GET /admin/post/view
app.get('/admin/post/view/:uuid?',
function (req, res, next) {
if (req.params.uuid) {
Post.getByUUID(req.params.uuid, function(err, post) {
res.render('admin-post-view', {
successNotice: req.flash('successNotice'),
failureNotice: req.flash('failureNotice'),
post: post,
content: markdown.toHTML(post.get("markdown")),
user: req.user
})
})
}
else {
res.redirect('/admin/post/list');
}
}
);
// GET /admin/post/new
app.get('/admin/post/new',
function(req, res, next) {
Category.getCategories(null, null, function (err, categories) {
res.render('admin-post-new', { categories: categories, user: req.user });
});
}
);
// POST /admin/post/new
app.post('/admin/post/new',
function(req, res, next) {
var post = new Post();
post.set("title", req.body.title);
if (req.body.slug != "") {
post.set("slug", req.body.slug);
} else {
post.set("slug", post.makeSlug());
}
if (req.body.postDate != "") {
post.set("postDate", new Date(req.body.postDate));
post.set("updatedDate", new Date(req.body.postDate));
}
post.tagPost(req.body.tags);
post.set("markdown", req.body.markdown);
Category.getByName(req.body.category, function (err, category) {
post.set("category", category.get("uuid"));
//console.log(post);
post.save(function (err) {
if (!err) {
req.flash('successNotice', 'Post created.');
res.redirect('/admin/post/edit/'+post.get("uuid"));
}
else {
req.flash('failureNotice', 'Post creation failed');
res.redirect('/admin/post/new/');
}
});
});
}
);
// GET /admin/post/edit
app.get('/admin/post/edit/:uuid',
function(req, res, next) {
Post.getByUUID(req.params.uuid, function(err, post) {
Category.getByUUID(post.get("category"), function(err, category) {
Category.getCategories(null, null, function(err, categories) {
var tags = ""
for (i=0; i<post.get("tags").length; i++) {
tags += post.get("tags")[i].name + " ";
}
res.render('admin-post-edit', {
successNotice: req.flash('successNotice'),
failureNotice: req.flash('failureNotice'),
categories: categories,
category: category,
post: post,
postTags: tags,
user: req.user
});
});
});
});
}
);
// POST /admin/post/edit
app.post('/admin/post/edit/:uuid',
function(req, res, next) {
Post.getByUUID(req.params.uuid, function(err, post) {
post.set("title", req.body.title);
post.set("slug", req.body.slug);
post.set("markdown", req.body.markdown);
post.set("postDate", new Date(req.body.postDate));
post.tagPost(req.body.tags);
Category.getByName(req.body.category, function(err, category) {
post.set("category", category.get("uuid"));
post.save(function(err) {
if (!err) {
req.flash("successNotice", "Post updated.");
res.redirect("/admin/post/edit/"+post.get("uuid"));
}
else {
req.flash("failureNotice", "Post failed to update.");
res.redirect("/admin/post/edit/"+post.get("uuid"));
}
});
});
});
}
);
// GET /admin/post/regenerate
app.get('/admin/post/regenerate/:uuid?',
function(req, res, next) {
if (req.params.uuid) {
Static.updateBuildFolder(function (err) { if (err) console.log(err); });
post = Post.getByUUID(req.params.uuid, function (err, post) {
console.log("Got post: "+post.get("title"));
if (err) console.log(err);
post.generatePost(function (err) {
if (!err) {
req.flash('successNotice', 'Post regenerated successfully.');
res.redirect('/admin/post/view/'+req.params.uuid);
}
else {
console.log(err);
req.flash('failureNotice', 'Post regeneration failed, check logs.');
res.redirect('/admin/post/view/'+req.params.uuid);
}
})
});
}
else {
res.redirect('/admin/post/list');
}
}
);
// Photo management Routing
app.get('/admin/photo/list/:start?',
function(req, res, next) {
var count = 25;
if (req.params.start) {
var start = req.params.start;
} else {
var start = 0;
}
database.listPhotos(count, start, function(photos){
for (photo in photos) {
var date = new Date(photos[photo].photoDate);
photos[photo].dateString = date.getFullYear() + '-' +
("0" + (date.getMonth()+1)).slice(-2) + '-' +
("0" + date.getDate()).slice(-2);
}
res.render('admin-photo-list', {photos, user: req.user});
});
}
);
app.get('/admin/photo/view/:id?',
function (req, res, next) {
if (req.params.id) {
database.getPhotoById(req.params.id, function(row) {
res.render('admin-photo-view', {
successNotice: req.flash('successNotice'),
failureNotice: req.flash('failureNotice'),
photo: row,
srcPath: '/'+row.path,
user: req.user
})
})
}
else {
res.redirect('/admin/photo/list');
}
}
);
app.get('/admin/photo/new',
function(req, res, next) {
res.render('admin-photo-new', { user: req.user });
}
);
app.post('/admin/photo/new',
upload.single('photo'),
function(req, res, next) {
console.log(req.file);
if ( req.body.title != "") {
var title = req.body.title;
}
else {
var title = req.file.originalname.split('.').slice(0,-1).join(' ');
}
var extension = req.file.originalname.split('.').slice(-1);
if (req.body.photoDate != "") {
var photoDate = helper.dateToEpoch(new Date(req.body.photoDate));
}
else {
var photoDate = helper.dateToEpoch(new Date());
}
if (req.body.slug != "") {
var slug = req.body.slug;
}
else if ( req.body.title != "" ){
var slug = helper.makeSlug(title+'-'+photoDate);
}
else {
var cleanFileName = req.file.originalname.split('.').slice(0,-1).join('-');
var slug = helper.makeSlug(cleanFileName+'-'+photoDate);
}
var mimetype = req.file.mimetype;
var tags = helper.parseTags(req.body.tags);
var markdown = req.body.markdown;
var updatedDate = photoDate;
var createDate = helper.dateToEpoch(new Date());
var categoryName = req.body.category;
var path = req.file.path;
database.createPhoto(title, slug, markdown, extension, mimetype, photoDate, updatedDate, createDate, path, function(err, row) {
if (err) console.log(err);
console.log(row);
database.tagPhoto(row.id, tags);
req.flash('successNotice', 'Photo created.');
res.redirect('/admin/photo/view/'+row.id);
});
}
);
app.get('/admin/photo/edit/:id',
function(req, res, next) {
var id = req.params.id;
async.parallel({
photoTags: function(callback) {
database.getPhotoTagsAsString(id, function(tagString) {
callback(null, tagString);
})
},
photo: function(callback) {
database.getPhotoById(id, function(photo) {
callback(null, photo);
})
}
},
function(err, results) {
res.render('admin-photo-edit', {
successNotice: req.flash('successNotice'),
failureNotice: req.flash('failureNotice'),
photo: results.photo,
srcPath: '/'+results.photo.path,
photoTags: results.photoTags,
formattedDate: helper.epochToDateString(results.photo.photoDate),
user: req.user
});
});
}
);
app.post('/admin/photo/edit/:id',
function(req, res, next) {
var id = req.params.id;
var title = req.body.title;
var slug = req.body.slug;
var markdown = req.body.markdown;
var photoDate = helper.dateToEpoch(new Date(req.body.photoDate));
var tags = helper.parseTags(req.body.tags);
console.log('Post '+id+' update request received');
database.tagPhoto(id, tags);
database.updatePhoto(id, title, slug, markdown, photoDate, function(err, row) {
req.flash('successNotice', 'Photo updated.');
res.redirect('/admin/photo/view/'+id);
});
}
);
app.get('/admin/photo/regenerate/:id',
function(req, res, next) {
console.log('Generating resized images for: '+req.params.id);
genStatic.generateStatic(function(err){ if (err) console.log(err) });
genPhotos.generatePhotoSizesById(req.params.id, function(err) {
if (!err) {
genPhotos.generatePhotoPage(req.params.id, function(err) {
if (!err) {
req.flash("successNotice", "Photo regenerated");
res.redirect('/admin/photo/view/'+req.params.id);
}
else {
req.flash('failureNotice', 'Photo was unable to be resized.');
res.redirect('/admin/photo/view/'+req.params.id);
}
})
}
else {
req.flash('failureNotice', 'Photo was unable to be resized.');
res.redirect('/admin/photo/view/'+req.params.id);
}
});
}
);
// Admin dashboard page.
app.get('/admin',
function(req, res, next) {
Post.countPosts(function (err, postCount) {
Category.countCategories(function (err, categoryCount) {
Post.getLastGenerateDate(function (err, lastGenerateDate) {
Post.getLastUploadDate( function (err, lastUploadDate) {
res.render('admin-dashboard', {
successNotice: req.flash('successNotice'),
failureNotice: req.flash('failureNotice'),
categories: categoryCount,
posts: postCount,
galleries: "###",
photos: "###",
tags: "###",
regenerateDate: moment(lastGenerateDate).format("YYYY-MM-DD HH:mm"),
uploadDate: moment(lastUploadDate).format("YYYY-MM-DD HH:mm"),
user: req.user});
})
})
})
})
}
);
// Routes for previewing sent versions of the built items.
app.get('/blog/*',
require('connect-ensure-login').ensureLoggedIn(),
function(req, res, next) {
if (req.params[0] != '') {
var path = __dirname + '/' + config.genDir + '/blog/' + req.params[0];
console.log('Trying to serve: ' + path);
fs.exists(path, function(exists) {
if (exists) {
console.log(path + ' exists serving...');
res.sendFile(path);
}
else {
console.log(path + ' does not exist...');
if (path.slice(-1) != '/') path += '/';
path += 'index.html'
console.log('Trying to serve: ' + path);
fs.exists(path, function(exists) {
if (exists) {
console.log(path + ' exists serving...');
res.sendFile(path);
}
});
}
});
}
}
);
app.get('/photos/*',
require('connect-ensure-login').ensureLoggedIn(),
function(req, res, next) {
if (req.params[0] != '') {
var path = __dirname + '/' + config.genDir + '/photos/' + req.params[0];
console.log('Trying to serve: ' + path);
fs.exists(path, function(exists) {
if (exists) {
console.log(path + ' exists serving...');
res.sendFile(path);
}
else {
console.log(path + ' does not exist...');
if (path.slice(-1) != '/') path += '/';
path += 'index.html'
console.log('Trying to serve: ' + path);
fs.exists(path, function(exists) {
if (exists) {
console.log(path + ' exists serving...');
res.sendFile(path);
}
});
}
});
}
}
);
app.get('/galleries/*',
require('connect-ensure-login').ensureLoggedIn(),
function(req, res, next) {
if (req.params[0] != '') {
var path = __dirname + '/' + config.genDir + '/galleries/' + req.params[0];
console.log('Trying to serve: ' + path);
fs.exists(path, function(exists) {
if (exists) {
console.log(path + ' exists serving...');
res.sendFile(path);
}
else {
console.log(path + ' does not exist...');
if (path.slice(-1) != '/') path += '/';
path += 'index.html'
console.log('Trying to serve: ' + path);
fs.exists(path, function(exists) {
if (exists) {
console.log(path + ' exists serving...');
res.sendFile(path);
}
});
}
});
}
}
);
app.get('/static/*',
require('connect-ensure-login').ensureLoggedIn(),
function(req, res, next) {
if (req.params[0] != '') {
var path = __dirname + '/' + config.genDir + '/static/' + req.params[0];
console.log('Trying to serve: ' + path);
fs.exists(path, function(exists) {
if (exists) {
console.log(path + ' exists serving...');
res.sendFile(path);
}
else {
console.log(path + ' does not exist...');
if (path.slice(-1) != '/') path += '/';
path += 'index.html'
console.log('Trying to serve: ' + path);
fs.exists(path, function(exists) {
if (exists) {
console.log(path + ' exists serving...');
res.sendFile(path);
}
});
}
});
}
}
);
app.get('/'+config.uploadDir+'/*',
require('connect-ensure-login').ensureLoggedIn(),
function(req, res, next) {
if (req.params[0] != '') {
var path = __dirname + '/'+ config.uploadDir + '/'+ req.params[0];
console.log('Trying to serve: ' + path);
fs.exists(path, function(exists) {
if (exists) {
console.log(path + ' exists serving...');
res.sendFile(path);
}
else {
console.log(path + ' does not exist...');
if (path.slice(-1) != '/') path += '/';
path += 'index.html'
console.log('Trying to serve: ' + path);
fs.exists(path, function(exists) {
if (exists) {
console.log(path + ' exists serving...');
res.sendFile(path);
}
});
}
});
}
}
);
// Have to have some sort of home page.
app.get('/', function(req, res, next) {
res.render('admin-index', { title: 'AMDavidson.com', user: req.user });
}
);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('admin-error', {
message: err.message,
error: err,
user: req.user
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
user: req.user,
error: {}
});
});
app.set('port', process.env.PORT || 3000)
var server = require('http').createServer(app)
MongoClient.connect('mongodb://localhost/crunch', function(err, database) {
if (!err) {
global.db = database;
server.listen(app.get('port'), function() {
console.log("Server listening on port " + app.get('port'));
});
}
});