Photo creation and editing done. Photo building not yet completed. Serving of built files done.
250
app.js
|
@ -4,6 +4,8 @@ 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 helper = require('./helper.js');
|
||||
var db = require('./db.js');
|
||||
|
@ -33,8 +35,10 @@ app.use(require('express-session')({ secret: 'amdasdfasdfamd',
|
|||
resave: true, saveUninitialized: true }));
|
||||
app.use(express.static(path.join(__dirname, 'public')));
|
||||
|
||||
var upload = multer({ dest: 'data/uploads/' })
|
||||
|
||||
// Get config variables
|
||||
var config = require('./config');
|
||||
var config = require('./config.js').config;
|
||||
|
||||
// Setup authentication via twitter.
|
||||
passport.use(new Strategy(
|
||||
|
@ -60,6 +64,10 @@ passport.deserializeUser(function(id, done) {
|
|||
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});
|
||||
});
|
||||
|
@ -73,8 +81,8 @@ app.get('/logout', function(req, res) {
|
|||
res.redirect('/');
|
||||
});
|
||||
|
||||
// Post management routing
|
||||
app.get('/admin/post/list/:start?',
|
||||
require('connect-ensure-login').ensureLoggedIn(),
|
||||
function(req, res, next) {
|
||||
var count = 25;
|
||||
if (req.params.start) {
|
||||
|
@ -93,14 +101,7 @@ app.get('/admin/post/list/:start?',
|
|||
});
|
||||
});
|
||||
|
||||
app.get('/admin/photo/new',
|
||||
require('connect-ensure-login').ensureLoggedIn(),
|
||||
function(req, res, next) {
|
||||
res.render('admin-photo-new', { user: req.user });
|
||||
});
|
||||
|
||||
app.get('/admin/post/new',
|
||||
require('connect-ensure-login').ensureLoggedIn(),
|
||||
function(req, res, next) {
|
||||
db.listCategories(function(rows){
|
||||
res.render('admin-post-new', { categories: rows, user: req.user });
|
||||
|
@ -108,22 +109,27 @@ app.get('/admin/post/new',
|
|||
});
|
||||
|
||||
app.post('/admin/post/new',
|
||||
require('connect-ensure-login').ensureLoggedIn(),
|
||||
function(req, res, next) {
|
||||
var title = req.body.title;
|
||||
if (req.body.slug != "") {
|
||||
slug = req.body.slug;
|
||||
var slug = req.body.slug;
|
||||
} else {
|
||||
slug = helper.makeSlug(title);
|
||||
var slug = helper.makeSlug(title);
|
||||
}
|
||||
var markdown = req.body.markdown;
|
||||
var postDate = helper.dateToEpoch(new Date(req.body.postDate));
|
||||
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);
|
||||
});
|
||||
|
@ -131,7 +137,6 @@ app.post('/admin/post/new',
|
|||
});
|
||||
|
||||
app.get('/admin/post/edit/:id',
|
||||
require('connect-ensure-login').ensureLoggedIn(),
|
||||
function(req, res, next) {
|
||||
var id = req.params.id;
|
||||
async.parallel({
|
||||
|
@ -157,11 +162,16 @@ app.get('/admin/post/edit/:id',
|
|||
}
|
||||
},
|
||||
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: results.postCategory,
|
||||
postCategory: categoryName,
|
||||
post: results.post,
|
||||
postTags: results.postTags,
|
||||
formattedDate: helper.epochToDateString(results.post.postDate),
|
||||
|
@ -171,15 +181,15 @@ app.get('/admin/post/edit/:id',
|
|||
});
|
||||
|
||||
app.post('/admin/post/edit/:id',
|
||||
require('connect-ensure-login').ensureLoggedIn(),
|
||||
function(req, res, next) {
|
||||
var id = req.params.id;
|
||||
var title = req.body.title;
|
||||
var slug = helper.makeSlug(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) {
|
||||
|
@ -190,7 +200,6 @@ app.post('/admin/post/edit/:id',
|
|||
});
|
||||
|
||||
app.get('/admin/post/rebuild/:id?',
|
||||
require('connect-ensure-login').ensureLoggedIn(),
|
||||
function(req, res, next) {
|
||||
if (req.params.id) {
|
||||
build.buildPost(req.params.id, function(err) {
|
||||
|
@ -210,8 +219,119 @@ app.get('/admin/post/rebuild/:id?',
|
|||
|
||||
});
|
||||
|
||||
// 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/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);
|
||||
}
|
||||
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/');
|
||||
});
|
||||
});
|
||||
|
||||
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,
|
||||
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/edit/'+id);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Admin dashboard page.
|
||||
app.get('/admin',
|
||||
require('connect-ensure-login').ensureLoggedIn(),
|
||||
function(req, res, next) {
|
||||
async.parallel({
|
||||
categories: function(callback) {
|
||||
|
@ -241,19 +361,21 @@ app.get('/admin',
|
|||
},
|
||||
rebuildDate: function(callback) {
|
||||
db.getLastRebuildDate(function(date) {
|
||||
var dateString = helper.epochToDateString(date.date).slice(0,-14);
|
||||
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,-14);
|
||||
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,
|
||||
|
@ -266,6 +388,92 @@ app.get('/admin',
|
|||
);
|
||||
});
|
||||
|
||||
// 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);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Have to have some sort of home page.
|
||||
app.get('/', function(req, res, next) {
|
||||
res.render('admin-index', { title: 'AMDavidson.com', user: req.user });
|
||||
});
|
||||
|
|
BIN
data/uploads/028f89c0fce0a9b7e7a502463b2ef4ab
Normal file
After Width: | Height: | Size: 96 KiB |
BIN
data/uploads/079865cad95566595cdf759a8299e583
Normal file
After Width: | Height: | Size: 96 KiB |
BIN
data/uploads/56f468c284788419bc512912ffa92a10
Normal file
After Width: | Height: | Size: 96 KiB |
BIN
data/uploads/5c6ccd44082e66a34054fefee7084bc7
Normal file
After Width: | Height: | Size: 96 KiB |
BIN
data/uploads/8ebac3195e597b01c964632fc654fcd4
Normal file
After Width: | Height: | Size: 96 KiB |
BIN
data/uploads/9c4f8478bf14d1634210b05150a2c2b8
Normal file
After Width: | Height: | Size: 96 KiB |
BIN
data/uploads/adb2d841ac54ded11de821c18624471c
Normal file
After Width: | Height: | Size: 96 KiB |
BIN
data/uploads/aecb2a9e7f05855a88e40375771722eb
Normal file
After Width: | Height: | Size: 96 KiB |
BIN
data/uploads/b4a4ab36382c78301c694781ddcde451
Normal file
After Width: | Height: | Size: 96 KiB |
BIN
data/uploads/c71ebc37c19f19793f156ea867759d7b
Normal file
After Width: | Height: | Size: 96 KiB |
BIN
data/uploads/c7ff1b41545d5e9fc8ce44393a9e3e86
Normal file
After Width: | Height: | Size: 96 KiB |
BIN
data/uploads/ccf08d5995bbbf617ff70a8496a1497e
Normal file
After Width: | Height: | Size: 96 KiB |
BIN
data/uploads/ea11cb7ee99ea7fa5c67357ab106dd2e
Normal file
After Width: | Height: | Size: 96 KiB |
247
db.js
|
@ -1,8 +1,11 @@
|
|||
var sqlite = require('sqlite3').verbose();
|
||||
var db = new sqlite.Database('./app.db');
|
||||
var helper = require('./helper.js');
|
||||
var async = require('async');
|
||||
|
||||
var config = require('./config.js').config;
|
||||
var helper = require('./helper.js');
|
||||
|
||||
var db = new sqlite.Database(config.dbPath);
|
||||
|
||||
// Function to get a user record by the username and password
|
||||
// Returns SQL row for that user
|
||||
exports.getUser = function(username, password, cb) {
|
||||
|
@ -112,25 +115,45 @@ exports.listPosts = function(count, start, cb) {
|
|||
});
|
||||
}
|
||||
|
||||
// Function to get a list of photos of a certain count and starting at an offset
|
||||
// Returns a list of photo objects
|
||||
exports.listPhotos = function(count, start, cb) {
|
||||
db.all('SELECT * FROM photos ORDER BY photoDate DESC, title ASC \
|
||||
LIMIT '+count+' OFFSET '+start+';',
|
||||
function(err, photos) {
|
||||
console.log(err);
|
||||
cb(photos);
|
||||
});
|
||||
}
|
||||
|
||||
// NON-EXPORTED function to create a category if it does not exist
|
||||
// Returns a row of category information
|
||||
var getOrCreateCategory = function(name, cb) {
|
||||
db.get('SELECT * FROM categories WHERE name = "'+name+'";', function(err, row) {
|
||||
if (!err) {
|
||||
if (!err && row) {
|
||||
console.log('Category '+name+' exists.');
|
||||
cb(row);
|
||||
} else {
|
||||
console.log('Category '+name+' does not exist. Creating...');
|
||||
epoch = helper.dateToEpoch(new Date());
|
||||
db.run('INSERT INTO categories (\
|
||||
name, slug, description, createDate, updatedDate, \
|
||||
lastBuildDate) VALUES (\
|
||||
name = "'+name+'", \
|
||||
slug = "'+helper.makeSlug('name')+'", \
|
||||
createDate = '+epoch+');',
|
||||
name, slug, createDate \
|
||||
) VALUES (\
|
||||
"'+name+'", \
|
||||
"'+helper.makeSlug(name)+'", \
|
||||
'+epoch+');',
|
||||
function(err, row) {
|
||||
db.get('SELECT * FROM categories WHERE name = "'+name+'";',
|
||||
function(err, row){
|
||||
cb(row);
|
||||
})
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
else {
|
||||
console.log('Category '+name+' created.');
|
||||
db.get('SELECT * FROM categories WHERE name = "'+name+'";',
|
||||
function(err, row){
|
||||
cb(row);
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
})
|
||||
|
@ -139,26 +162,42 @@ var getOrCreateCategory = function(name, cb) {
|
|||
// Function to set a category for a post given a post id and a category name
|
||||
// Returns error code
|
||||
exports.setPostCategory = function(postId, categoryName, cb) {
|
||||
console.log('Setting post '+postId+' category to '+categoryName);
|
||||
getOrCreateCategory(categoryName, function(category) {
|
||||
db.get('SELECT categoryId FROM categoryPosts \
|
||||
WHERE postId = '+postId+';',
|
||||
function(err, row) {
|
||||
if (row) {
|
||||
console.log('Post '+postId+' has assigned category of '+row.categoryId);
|
||||
if (row.categoryId == category.id) {
|
||||
cb(err);
|
||||
console.log('Current post category is the same as new post category, no update necessary.');
|
||||
cb(null);
|
||||
} else {
|
||||
console.log("Current post category ("+row.categoryId+") doesn't match new category ("+category.id+"), updating record.");
|
||||
db.run('UPDATE categoryPosts SET \
|
||||
categoryId = '+category.id+'\
|
||||
categoryId = '+category.id+' \
|
||||
WHERE postId = '+postId+';',
|
||||
function(err, row) {
|
||||
cb(err);
|
||||
function(err) {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
else {
|
||||
console.log("Category updated.");
|
||||
cb(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
db.run('INSERT INTO categoryPosts (postId, categoryId) \
|
||||
VALUES ('+postId+', '+category.id+');',
|
||||
function(err, row) {
|
||||
cb(err);
|
||||
console.log('Post '+postId+' has no category assigned. Inserting record.');
|
||||
db.run('INSERT INTO categoryPosts (postId, categoryId) VALUES ('+postId+', '+category.id+');',
|
||||
function(err) {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
else {
|
||||
console.log('Post '+postId+' assigned to category '+category.id);
|
||||
cb(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -178,6 +217,7 @@ exports.createPost = function(title, slug, markdown, postDate, updatedDate,
|
|||
markdown, \
|
||||
postDate, \
|
||||
createDate, \
|
||||
updatedDate, \
|
||||
lastBuildDate, \
|
||||
lastUpload) \
|
||||
VALUES (\
|
||||
|
@ -186,9 +226,11 @@ exports.createPost = function(title, slug, markdown, postDate, updatedDate,
|
|||
"'+markdown+'", \
|
||||
"'+postDate+'", \
|
||||
"'+createDate+'", \
|
||||
"'+updatedDate+'", \
|
||||
(strftime("%s","1900-01-01 00:00")*1000), \
|
||||
(strftime("%s","1900-01-01 00:00")*1000));',
|
||||
function(err, row) {
|
||||
if (err) console.log(err);
|
||||
db.get('SELECT * FROM posts WHERE title = "'+title+'" AND createDate = '+createDate+';', function(err, row){
|
||||
cb(err, row);
|
||||
})
|
||||
|
@ -229,7 +271,17 @@ exports.getPostCategory = function(id, cb) {
|
|||
db.get('SELECT * FROM categories WHERE id = (\
|
||||
SELECT categoryId FROM categoryPosts WHERE postId = '+id+');',
|
||||
function(err, row) {
|
||||
cb(row);
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
if (row) {
|
||||
console.log('Post '+id+' category is '+row.name);
|
||||
cb(row);
|
||||
}
|
||||
else {
|
||||
cb(null);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -244,7 +296,6 @@ var getOrCreateTag = function(tag, cb) {
|
|||
}
|
||||
if (row) {
|
||||
console.log(slug+' tag exists');
|
||||
console.log(row);
|
||||
cb(row);
|
||||
}
|
||||
else {
|
||||
|
@ -255,13 +306,8 @@ var getOrCreateTag = function(tag, cb) {
|
|||
console.log(slug+' tag created');
|
||||
db.get('SELECT * FROM tags WHERE slug = "'+slug+'" LIMIT 1;',
|
||||
function (err, row) {
|
||||
if (!err) {
|
||||
console.log(row);
|
||||
cb(row);
|
||||
}
|
||||
else {
|
||||
console.log(err);
|
||||
}
|
||||
if (err) console.log(err);
|
||||
if (row) cb(row);
|
||||
});
|
||||
};
|
||||
});
|
||||
|
@ -276,6 +322,7 @@ exports.getOrCreateTag = getOrCreateTag;
|
|||
// Inputs: Post ID, List of Tag names
|
||||
// Does not return.
|
||||
exports.tagPost = function (postId, tags) {
|
||||
|
||||
console.log('Deleting old tags');
|
||||
db.run('DELETE FROM postTags WHERE postId = '+postId+';',
|
||||
function(err) {
|
||||
|
@ -351,3 +398,145 @@ var getPostTagsAsString = function(postId, cb) {
|
|||
}
|
||||
|
||||
exports.getPostTagsAsString = getPostTagsAsString;
|
||||
|
||||
|
||||
// Function to tag a photo with a list of tag names
|
||||
// Inputs: Photo ID, List of Tag names
|
||||
// Does not return.
|
||||
exports.tagPhoto = function (photoId, tags) {
|
||||
|
||||
console.log('Deleting old tags');
|
||||
db.run('DELETE FROM photoTags WHERE photoId = '+photoId+';',
|
||||
function(err) {
|
||||
console.log('Old tags deleted');
|
||||
for (var i = 0, size = tags.length; i < size; i++) {
|
||||
getOrCreateTag(tags[i], function(row) {
|
||||
db.run('INSERT INTO photoTags (photoId, tagId) \
|
||||
VALUES ('+photoId+', '+row.id+');',
|
||||
function(err) {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
else {
|
||||
console.log('Photo '+photoId+' tagged as '+row.name);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Function to get tag ids associated with a particular photo id
|
||||
// Inputs: Photo ID
|
||||
// Returns: Records associated with tags of that photo id
|
||||
var getPhotoTags = function (photoId, cb) {
|
||||
db.all('SELECT tagId FROM photoTags WHERE photoId = '+photoId+';',
|
||||
function(err, rows) {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
else {
|
||||
var tagList = [];
|
||||
for (row in rows) {
|
||||
tagList.push(rows[row].tagId);
|
||||
}
|
||||
tagList = tagList.join(', ');
|
||||
console.log('Tag ids for photo '+photoId+': '+tagList);
|
||||
db.all('SELECT * FROM tags WHERE id IN ('+tagList+');',
|
||||
function(err, rows) {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
else {
|
||||
cb(rows);
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
exports.getPhotoTags = getPhotoTags;
|
||||
|
||||
|
||||
// Function that returns all the photo tags as a space separated string.
|
||||
// Inputs: Photo ID, callback function.
|
||||
// Returns: callback of string with all tags separated by spaces.
|
||||
var getPhotoTagsAsString = function(photoId, cb) {
|
||||
getPhotoTags(photoId, function(tags) {
|
||||
var str = false;
|
||||
for (tag in tags) {
|
||||
if (!str) {
|
||||
str = tags[tag].name;
|
||||
}
|
||||
else {
|
||||
str = str + ' ' + tags[tag].name;
|
||||
}
|
||||
}
|
||||
console.log("Tags for photo "+photoId+": "+str);
|
||||
cb(str);
|
||||
})
|
||||
}
|
||||
|
||||
exports.getPhotoTagsAsString = getPhotoTagsAsString;
|
||||
|
||||
// Function to get a photo record by the id of the photo
|
||||
// Returns the photo record
|
||||
exports.getPhotoById = function(id, cb) {
|
||||
db.get('SELECT * FROM photos WHERE id = ?', id, function(err, row) {
|
||||
cb(row);
|
||||
});
|
||||
}
|
||||
|
||||
// Function to create a new photo
|
||||
// Returns the photo id
|
||||
exports.createPhoto = function(title, slug, markdown, photoDate, updatedDate,
|
||||
createDate, path, cb) {
|
||||
db.run('INSERT INTO photos (\
|
||||
title, \
|
||||
slug, \
|
||||
description, \
|
||||
path, \
|
||||
photoDate, \
|
||||
createDate, \
|
||||
updatedDate, \
|
||||
lastBuildDate, \
|
||||
lastUpload) \
|
||||
VALUES (\
|
||||
"'+title+'", \
|
||||
"'+slug+'", \
|
||||
"'+markdown+'", \
|
||||
"'+path+'", \
|
||||
"'+photoDate+'", \
|
||||
"'+createDate+'", \
|
||||
"'+updatedDate+'", \
|
||||
(strftime("%s","1900-01-01 00:00")*1000), \
|
||||
(strftime("%s","1900-01-01 00:00")*1000));',
|
||||
function(err, row) {
|
||||
db.get('SELECT * FROM photos WHERE title = "'+title+'" AND createDate = '+createDate+';', function(err, row){
|
||||
if (err) console.log(err);
|
||||
cb(err, row);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// Function to update an existing post record
|
||||
// Returns the post object
|
||||
exports.updatePhoto = function(id, title, slug, markdown, photoDate, cb) {
|
||||
console.log("updatePost called.");
|
||||
db.run('UPDATE photos SET \
|
||||
title = "'+title+'", \
|
||||
slug = "'+slug+'", \
|
||||
description = "'+markdown+'", \
|
||||
photoDate = '+helper.dateToEpoch(photoDate)+', \
|
||||
updatedDate = '+helper.dateToEpoch(new Date())+' \
|
||||
WHERE id = '+id+';',
|
||||
function(err) {
|
||||
console.log('updatePhoto UPDATE result: '+err);
|
||||
db.get('SELECT * FROM photos WHERE id = '+id+';', function(err, row) {
|
||||
console.log('updatePhoto SELECT result: ' + err);
|
||||
cb(row);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -51,11 +51,8 @@ exports.makeSlug = function(str) {
|
|||
// Parse a string of tags
|
||||
// Returns a list of tags
|
||||
exports.parseTags = function(str) {
|
||||
console.log('tag parse '+str);
|
||||
str = str.replace(/,/g,'');
|
||||
console.log('tag parse '+str);
|
||||
var list = str.split(" ");
|
||||
console.log('tag parse '+list);
|
||||
for (var i = 0, size = list.length; i < size; i++) {
|
||||
list[i] = list[i].trim();
|
||||
}
|
||||
|
|
13
package.json
|
@ -3,20 +3,21 @@
|
|||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"async": "~1.5.0",
|
||||
"body-parser": "~1.13.2",
|
||||
"connect-ensure-login": "~0.1.1",
|
||||
"cookie-parser": "~1.3.5",
|
||||
"debug": "~2.2.0",
|
||||
"express": "~4.13.1",
|
||||
"express-session": "~1.12.0",
|
||||
"express-flash": "~0.0.2",
|
||||
"express-session": "~1.12.0",
|
||||
"jade": "~1.11.0",
|
||||
"markdown": "~0.5.0",
|
||||
"morgan": "~1.6.1",
|
||||
"serve-favicon": "~2.3.0",
|
||||
"multer": "~1.1.0",
|
||||
"passport": "~0.3.0",
|
||||
"passport-local": "~1.0.0",
|
||||
"connect-ensure-login": "~0.1.1",
|
||||
"sqlite3": "~3.1.0",
|
||||
"async": "~1.5.0",
|
||||
"markdown": "~0.5.0"
|
||||
"serve-favicon": "~2.3.0",
|
||||
"sqlite3": "~3.1.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ CREATE TABLE "photos" (
|
|||
"path" TEXT NOT NULL, -- The path of the photo location on disk
|
||||
"title" TEXT, -- The title of the photo
|
||||
"slug" TEXT NOT NULL UNIQUE, -- A slug form of the title or id
|
||||
"description" TEXT NOT NULL, -- The photo description in markdown format
|
||||
"description" TEXT, -- The photo description in markdown format
|
||||
"photoDate" INTEGER, -- The date that the photo should go live and be sorted by
|
||||
"updatedDate" INTEGER, -- The date that the photo was last updated
|
||||
"createDate" INTEGER NOT NULL, -- The date the photo was created
|
||||
|
|
33
views/admin-photo-edit.jade
Normal file
|
@ -0,0 +1,33 @@
|
|||
extends admin-layout
|
||||
|
||||
block content
|
||||
div(class="row")
|
||||
include ./admin-sidebar.jade
|
||||
|
||||
div(class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main")
|
||||
h1(class="page-header") Edit Photo
|
||||
|
||||
include ./admin-messages.jade
|
||||
|
||||
form(method="post", action="/admin/photo/edit/#{photo.id}")
|
||||
div(class="row page-header")
|
||||
h1 put photo here
|
||||
div(class="input-group input-group-lg col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
input(class="form-control", type="text", name="title", placeholder="Enter title", value="#{photo.title}")
|
||||
div(class="input-group col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
input(class="form-control", type="text", name="slug", placeholder="Enter slug (optional)", value="#{photo.slug}")
|
||||
div(class="row page-header")
|
||||
div(class="input-group col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
input(type="text", class="form-control", placeholder="Publish Date", name="photoDate", value="#{formattedDate}")
|
||||
div(class="input-group col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
input(type="text", class="form-control", placeholder="Tags", name="tags" value="#{photoTags}")
|
||||
div(class="row page-header")
|
||||
div(class="input-group col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
textarea(class="form-control", rows="12", name="markdown", placeholder="Markdown formatted description")
|
||||
| #{photo.description}
|
||||
div(class="row")
|
||||
div(class="input-group col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
div(class="pull-left")
|
||||
button(type="submit", class="btn btn-lg btn-success", name="submit") Update Photo
|
||||
div(class="pull-right")
|
||||
button(type="submit", class="btn btn-lg btn-danger", name="submit") Delete Photo
|
25
views/admin-photo-list.jade
Normal file
|
@ -0,0 +1,25 @@
|
|||
extends admin-layout
|
||||
|
||||
block content
|
||||
div(class="row")
|
||||
include ./admin-sidebar.jade
|
||||
|
||||
div(class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main")
|
||||
h1(class="page-header") Photos
|
||||
|
||||
include ./admin-messages.jade
|
||||
|
||||
table(class="table table-striped")
|
||||
each photo in photos
|
||||
tr
|
||||
td #{photo.id}
|
||||
td #{photo.title}
|
||||
td #{photo.dateString}
|
||||
td
|
||||
a(href="/admin/photo/edit/#{photo.id}") Edit
|
||||
| -
|
||||
a(href="/admin/photo/delete/#{photo.id}") Delete
|
||||
| -
|
||||
a(href="/admin/photo/rebuild/#{photo.id}") Rebuild
|
||||
| -
|
||||
a(href="/admin/photo/publish/#{photo.id}") Publish
|
31
views/admin-photo-new.jade
Normal file
|
@ -0,0 +1,31 @@
|
|||
extends admin-layout
|
||||
|
||||
block content
|
||||
div(class="row")
|
||||
include ./admin-sidebar.jade
|
||||
|
||||
div(class="col-sm-10 col-sm-offset-2 col-md-10 col-md-offset-2 main")
|
||||
h1(class="page-header") New Photo
|
||||
|
||||
include ./admin-messages.jade
|
||||
|
||||
form(method="post", action="/admin/photo/new", enctype="multipart/form-data")
|
||||
div(class="row page-header")
|
||||
div(class="input-group input-group-lg col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
input(class="form-control", type="file", name="photo", accept="image/*", placeholder="Upload File")
|
||||
div(class="input-group input-group-lg col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
input(class="form-control", type="text", name="title", placeholder="Enter title")
|
||||
div(class="input-group col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
input(class="form-control", type="text", name="slug", placeholder="Enter slug (optional)")
|
||||
div(class="row page-header")
|
||||
div(class="input-group col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
input(type="text", class="form-control", placeholder="Publish Date", name="photoDate")
|
||||
div(class="input-group col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
input(type="text", class="form-control", placeholder="Tags", name="tags")
|
||||
div(class="row page-header")
|
||||
div(class="input-group col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
textarea(class="form-control", rows="12", name="markdown", placeholder="Markdown formatted description")
|
||||
div(class="row")
|
||||
div(class="input-group col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
div(class="pull-left")
|
||||
button(type="submit", class="btn btn-lg btn-success", name="submit") Create Photo
|
|
@ -22,7 +22,7 @@ block content
|
|||
ul(class="dropdown-menu")
|
||||
each row in categories
|
||||
li: a(href="#", onClick="document.getElementById('category').value = '#{row.name}'") #{row.name}
|
||||
input(type="text", class="form-control", aria-label="Post category", name="category", id="category" value="#{postCategory.name}")
|
||||
input(type="text", class="form-control", aria-label="Post category", name="category", id="category" value="#{categoryName}")
|
||||
div(class="input-group col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
input(type="text", class="form-control", placeholder="Publish Date", name="postDate", value="#{formattedDate}")
|
||||
div(class="input-group col-xs-10 col-xs-offset-1 col-md-10 col-md-offset-1")
|
||||
|
|
|
@ -16,12 +16,12 @@ block content
|
|||
td #{post.title}
|
||||
td #{post.dateString}
|
||||
td
|
||||
a(href="/admin/post/edit/#{post.id}") Edit Post
|
||||
a(href="/admin/post/edit/#{post.id}") Edit
|
||||
| -
|
||||
a(href="/admin/post/delete/#{post.id}") Delete Post
|
||||
a(href="/admin/post/delete/#{post.id}") Delete
|
||||
| -
|
||||
a(href="/admin/post/rebuild/#{post.id}") Force Rebuild
|
||||
a(href="/admin/post/rebuild/#{post.id}") Rebuild
|
||||
| -
|
||||
a(href="/admin/post/publish/#{post.id}") Force Publish
|
||||
a(href="/admin/post/publish/#{post.id}") Publish
|
||||
|
||||
|
||||
|
|
|
@ -4,15 +4,15 @@ div(class="col-sm-3 col-md-2 sidebar")
|
|||
|
||||
ul(class="nav nav-sidebar")
|
||||
li: a(href="/admin/post/new") New Post
|
||||
li: a(href="/admin/post/list") Edit Post
|
||||
li: a(href="/admin/post/list") All Posts
|
||||
|
||||
ul(class="nav nav-sidebar")
|
||||
li: a(href="/admin/category/new") New Category
|
||||
li: a(href="/admin/category/list") Edit Category
|
||||
li: a(href="/admin/photo/new") New Photo
|
||||
li: a(href="/admin/photo/list") All Photos
|
||||
|
||||
ul(class="nav nav-sidebar")
|
||||
li: a(href="/admin/gallery/new") New Gallery
|
||||
li: a(href="/admin/gallery/list") Edit Gallery
|
||||
li: a(href="/admin/gallery/list") All Galleries
|
||||
|
||||
ul(class="nav nav-sidebar")
|
||||
form(action="/admin/rebuild/", method="get")
|
||||
|
|
7
views/render-photo.jade
Normal file
|
@ -0,0 +1,7 @@
|
|||
extends render-layout
|
||||
|
||||
block content
|
||||
div: img(src="#{medURL}")
|
||||
|
||||
h3: a(href="#{url}") #{title}
|
||||
div !{content}
|