crunch-node/app.js

615 lines
20 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 helper = require('./helper.js');
var db = require('./db.js');
var build = require('./build.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) {
db.getUser(username, password, function(user) {
if (!user) { return done(null, false); }
return done(null, user);
});
}
));
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
db.getUserById(id, function (user) {
if (!user) { return done(false); }
done(null, user);
});
});
app.use(passport.initialize());
app.use(passport.session());
// Require logins for all admin pages.
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
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;
}
db.listPosts(count, start, function(posts){
for (post in posts) {
var date = new Date(posts[post].postDate);
posts[post].dateString = date.getFullYear() + '-' +
("0" + (date.getMonth()+1)).slice(-2) + '-' +
("0" + date.getDate()).slice(-2);
}
res.render('admin-post-list', {posts, user: req.user});
});
});
app.get('/admin/post/view/:id?',
function (req, res, next) {
if (req.params.id) {
db.getPostById(req.params.id, function(row) {
res.render('admin-post-view', {
successNotice: req.flash('successNotice'),
failureNotice: req.flash('failureNotice'),
date: helper.epochToShortDateString(row.postDate),
post: row,
content: markdown.toHTML(row.markdown),
user: req.user
})
})
}
else {
res.redirect('/admin/post/list');
}
}
);
app.get('/admin/post/new',
function(req, res, next) {
db.listCategories(function(rows){
res.render('admin-post-new', { categories: rows, user: req.user });
});
});
app.post('/admin/post/new',
function(req, res, next) {
var title = req.body.title;
if (req.body.slug != "") {
var slug = req.body.slug;
} else {
var slug = helper.makeSlug(title);
}
var markdown = req.body.markdown;
if (req.body.postDate != "") {
var postDate = helper.dateToEpoch(new Date(req.body.postDate));
} else {
var postDate = helper.dateToEpoch(new Date());
}
var updatedDate = postDate;
var createDate = helper.dateToEpoch(new Date());
var categoryName = req.body.category;
var tags = helper.parseTags(req.body.tags);
db.createPost(title, slug, markdown, postDate, updatedDate, createDate, function(err, row) {
db.setPostCategory(row.id, categoryName, function(category) {
db.tagPost(row.id, tags);
req.flash('successNotice', 'Post created.');
res.redirect('/admin/post/edit/'+row.id);
});
});
});
app.get('/admin/post/edit/:id',
function(req, res, next) {
var id = req.params.id;
async.parallel({
categories: function(callback) {
db.listCategories(function(categories) {
callback(null, categories);
})
},
postCategory: function(callback) {
db.getPostCategory(id, function(category) {
callback(null, category);
})
},
postTags: function(callback) {
db.getPostTagsAsString(id, function(tagString) {
callback(null, tagString);
})
},
post: function(callback) {
db.getPostById(id, function(post) {
callback(null, post);
})
}
},
function(err, results) {
if (results.postCategory) {
var categoryName = results.postCategory.name;
} else {
var categoryName = null;
}
res.render('admin-post-edit', {
successNotice: req.flash('successNotice'),
failureNotice: req.flash('failureNotice'),
categories: results.categories,
postCategory: categoryName,
post: results.post,
postTags: results.postTags,
formattedDate: helper.epochToDateString(results.post.postDate),
user: req.user
});
});
});
app.post('/admin/post/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 postDate = helper.dateToEpoch(new Date(req.body.postDate));
var categoryName = req.body.category;
var tags = helper.parseTags(req.body.tags);
console.log('Post '+id+' update request received');
db.tagPost(id, tags);
db.updatePost(id, title, slug, markdown, postDate, function(err, row) {
db.setPostCategory(id, categoryName, function(err) {
req.flash('successNotice', 'Post updated.');
res.redirect('/admin/post/edit/'+id);
});
});
});
app.get('/admin/post/rebuild/:id?',
function(req, res, next) {
if (req.params.id) {
build.buildStatic(function(err){ if (err) console.log(err) });
build.buildPost(req.params.id, function(err) {
if (!err) {
req.flash('successNotice', 'Post rebuilt successfully.');
res.redirect('/admin/post/view/'+req.params.id);
}
else {
req.flash('failureNotice', 'Post rebuild failed, check logs.');
res.redirect('/admin/post/view/'+req.params.id);
}
});
}
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;
}
db.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) {
db.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(' ');
}
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 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;
db.createPhoto(title, slug, markdown, photoDate, updatedDate, createDate, path, function(err, row) {
console.log(row);
db.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) {
db.getPhotoTagsAsString(id, function(tagString) {
callback(null, tagString);
})
},
photo: function(callback) {
db.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');
db.tagPhoto(id, tags);
db.updatePhoto(id, title, slug, markdown, photoDate, function(err, row) {
req.flash('successNotice', 'Photo updated.');
res.redirect('/admin/photo/view/'+id);
});
});
// Admin dashboard page.
app.get('/admin',
function(req, res, next) {
async.parallel({
categories: function(callback) {
db.countCategories(function(count) {
callback(null, count);
});
},
posts: function(callback) {
db.countPosts(function(count) {
callback(null, count);
});
},
galleries: function(callback) {
db.countGalleries(function(count) {
callback(null, count);
});
},
photos: function(callback) {
db.countPhotos(function(count) {
callback(null, count);
});
},
tags: function(callback) {
db.countTags(function(count) {
callback(null, count);
});
},
rebuildDate: function(callback) {
db.getLastRebuildDate(function(date) {
var dateString = helper.epochToDateString(date.date).slice(0,-12);
callback(null, dateString);
});
},
uploadDate: function(callback) {
db.getLastUploadDate(function(date) {
var dateString = helper.epochToDateString(date.date).slice(0,-12);
callback(null, dateString);
});
}
},
function(err, results) {
res.render('admin-dashboard', {
successNotice: req.flash('successNotice'),
failureNotice: req.flash('failureNotice'),
categories: results.categories,
posts: results.posts,
galleries: results.galleries,
photos: results.photos,
tags: results.tags,
rebuildDate: results.rebuildDate,
uploadDate: results.uploadDate,
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 + '/build/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 + '/build/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 + '/build/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 + '/build/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('/data/*',
require('connect-ensure-login').ensureLoggedIn(),
function(req, res, next) {
if (req.params[0] != '') {
var path = __dirname + '/data/' + 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)
server.listen(app.get('port'), function() {
console.log("Server listening on port " + app.get('port'));
});