From cf36d983a024d4bdf757dab568258d1b37857fe3 Mon Sep 17 00:00:00 2001 From: Andrew Davidson Date: Thu, 21 Jan 2016 21:17:49 -0500 Subject: [PATCH] Finished converting post model to a cohesive model supported by mongodb. #6 --- app.js | 123 ++++++-------- category.js | 96 +++++++++++ dump/crunch/categories.bson | Bin 0 -> 172 bytes dump/crunch/categories.metadata.json | 1 + genPosts.js | 110 ------------ post.js | 244 +++++++++++++++++++++++++++ schemas.js | 5 +- static.js | 21 ++- views/admin-post-edit.jade | 2 +- views/render-post.jade | 6 +- 10 files changed, 414 insertions(+), 194 deletions(-) create mode 100644 category.js create mode 100644 dump/crunch/categories.bson create mode 100644 dump/crunch/categories.metadata.json delete mode 100644 genPosts.js create mode 100644 post.js diff --git a/app.js b/app.js index f1d1272..aea2847 100644 --- a/app.js +++ b/app.js @@ -7,15 +7,17 @@ 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 +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 genStatic = require('./genStatic.js'); var genPhotos = require('./genPhotos.js'); var app = express(); @@ -92,6 +94,7 @@ app.get('/logout', function(req, res) { ); // Post management routing +// GET /admin/post/list app.get('/admin/post/list/:start?', function(req, res, next) { var count = 25; @@ -103,9 +106,10 @@ app.get('/admin/post/list/:start?', 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) { @@ -125,6 +129,7 @@ app.get('/admin/post/view/:uuid?', } ); +// GET /admin/post/new app.get('/admin/post/new', function(req, res, next) { Category.getCategories(null, null, function (err, categories) { @@ -133,6 +138,7 @@ app.get('/admin/post/new', } ); +// POST /admin/post/new app.post('/admin/post/new', function(req, res, next) { var post = new Post(); @@ -151,7 +157,7 @@ app.post('/admin/post/new', Category.getByName(req.body.category, function (err, category) { post.set("category", category.get("uuid")); - console.log(post); + //console.log(post); post.save(function (err) { if (!err) { req.flash('successNotice', 'Post created.'); @@ -166,6 +172,7 @@ app.post('/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) { @@ -190,6 +197,7 @@ app.get('/admin/post/edit/:uuid', } ); +// POST /admin/post/edit app.post('/admin/post/edit/:uuid', function(req, res, next) { Post.getByUUID(req.params.uuid, function(err, post) { @@ -215,26 +223,31 @@ app.post('/admin/post/edit/:uuid', } ); -app.get('/admin/post/regenerate/:id?', +// GET /admin/post/regenerate +app.get('/admin/post/regenerate/:uuid?', function(req, res, next) { - if (req.params.id) { - genStatic.generateStatic(function(err){ if (err) console.log(err) }); - genPosts.generatePost(req.params.id, function(err) { - if (!err) { - req.flash('successNotice', 'Post regenerated successfully.'); - res.redirect('/admin/post/view/'+req.params.id); - } - else { - req.flash('failureNotice', 'Post regeneration failed, check logs.'); - res.redirect('/admin/post/view/'+req.params.id); - } + 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 @@ -402,60 +415,26 @@ app.get('/admin/photo/regenerate/:id', // Admin dashboard page. app.get('/admin', function(req, res, next) { - async.parallel({ - categories: function(callback) { - database.countCategories(function(count) { - callback(null, count); - }); - }, - posts: function(callback) { - Post.countPosts(function(err, count) { - callback(null, count); - }); - }, - galleries: function(callback) { - database.countGalleries(function(count) { - callback(null, count); - }); - }, - photos: function(callback) { - database.countPhotos(function(count) { - callback(null, count); - }); - }, - tags: function(callback) { - database.countTags(function(count) { - callback(null, count); - }); - }, - regenerateDate: function(callback) { - database.getLastRegenerateDate(function(date) { - var dateString = helper.epochToDateString(date.date).slice(0,-12); - callback(null, dateString); - }); - }, - uploadDate: function(callback) { - database.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, - regenerateDate: results.regenerateDate, - uploadDate: results.uploadDate, - user: req.user}); - } - ); -} + 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. diff --git a/category.js b/category.js new file mode 100644 index 0000000..79e866e --- /dev/null +++ b/category.js @@ -0,0 +1,96 @@ +var moment = require("moment"); +var _ = require("lodash"); +var schemas = require('./schemas.js'); + + +var Category = function(data) { + this.data = data; +} + +Category.prototype.data = {} + +Category.prototype.get = function (name) { + return this.data[name]; +} + +Category.prototype.set = function (name, value) { + this.data[name] = value; +} + +Category.prototype.sanitize = function (data) { + data = data || {}; + schema = schemas.category; + return _.pick(_.defaults(data, schema), _.keys(schema)); +} + +Category.prototype.save = function (callback) { + var self = this; + this.data = this.sanitize(this.data); + db.collection("categories").save(this.data, callback(err)); +} + +// Function to get a YYYY-MM-DD format of the current CategoryDate +// Requires no arguments. +Category.prototype.getShortDate = function () { + return moment(this.get("createdDate")).format("YYYY-MM-DD"); +} + +// Get a specific category by its name +// Returns a Category object +Category.getByName = function (name, callback) { + db.collection("categories").findOne({name: name}, function(err, doc) { + callback(err, new Category(doc)); + }); +} + +// Get a specific category by its UUID +// Returns a Category object +Category.getByUUID = function (uuid, callback) { + db.collection("categories").findOne({uuid: uuid}, function(err, doc) { + callback(err, new Category(doc)); + }); +} + +// Function to get a count of current Categories +// Returns count of Categories +Category.countCategories = function(callback) { + db.collection("categories").find({}).count(function (err, count) { + if (err) console.log(err); + callback(err, count); + }); +} + +// Function to get a list of all existing categories +// Start and count are optional, but if start is used, count must be used as well. +// Returns an array of Category objects +Category.getCategories = function(count, start, callback) { + if (typeof callback === undefined) { + if (typeof start === undefined) { + callback = count; + count = undefined; + start = undefined; + } + else { + callback = start; + start = undefined; + } + } + + var options = {} + if (start) options.skip=start; + if (count) options.limit=count; + options.sort = {name: 1}; + + db.collection("categories").find({}, options).toArray(function(err, docs) { + if (err) console.log(err); + var rows = []; + for (i=0; i$4be3)H84=na19R8WMBXQ2F5NQ literal 0 HcmV?d00001 diff --git a/dump/crunch/categories.metadata.json b/dump/crunch/categories.metadata.json new file mode 100644 index 0000000..898a8ae --- /dev/null +++ b/dump/crunch/categories.metadata.json @@ -0,0 +1 @@ +{"options":{},"indexes":[{"v":1,"key":{"_id":1},"name":"_id_","ns":"crunch.categories"}]} \ No newline at end of file diff --git a/genPosts.js b/genPosts.js deleted file mode 100644 index 7e52cca..0000000 --- a/genPosts.js +++ /dev/null @@ -1,110 +0,0 @@ -var fs = require('fs'); -var mkdirp = require('mkdirp'); -var jade = require('jade'); -var markdown = require( "markdown" ).markdown; -var async = require('async'); - -var db = require('./db.js'); - -// Generate all archive pages associated with a particular post ID -// This currently calls the functions to make the yearly and monthly archives. -var generatePostArchives = function (id, cb) { - db.getPostById(id, function(post) { - console.log('Generating dependencies for Post: '+id); - var date = new Date(post.postDate); - var year = date.getFullYear(); - console.log('Generating archive for year: '+year); - var month = date.getMonth()+1; - async.parallel({ - monthArchiveErr: function(callback) { - generatePostMonthArchive(year, function(err) { - callback(null, err); - }); - }, - yearArchiveErr: function(callback) { - generatePostYearArchive(month, function(err) { - callback(null, err); - }); - } - }, function(err, results) { - if (!yearArchiveErr && !monthArchiveErr) { - cb(null); - } - else if (yearArchiveErr) { - cb(yearArchiveErr); - } - else if (monthArchiveErr) { - cb(monthArchiveErr); - } - else { - cb(null); - } - }); - - }); -} -exports.generatePostArchives = generatePostArchives; - - -// Function that generates the yearly archive pages. -// TODO: make this not a skeleton. -// TODO: create pagination. -var generatePostYearArchive = function (year, cb) { - console.log('Generating archive for year: '+year); - cb(null); -} -exports.generatePostYearArchive = generatePostYearArchive; - - -// Function that generates the monthly archive pages. -// TODO: Make this not a skeleton. -// TODO: create pagination. -var generatePostMonthArchive = function (month, cb) { - console.log('Generating archive for month: '+month); - cb(null); -} -exports.generatePostMonthArchive = generatePostMonthArchive; - - -// Function to generate a single post page. -// TODO: (re)generate images as required. -var generatePost = function (id, cb) { - db.getPostById(id, function(post) { - console.log('Fetching post id: '+id); - var title = post.title; - var content = markdown.toHTML(post.markdown); - var slug = post.slug; - var postDate = helper.epochToShortDateString(post.postDate); - var url = '/blog/'+postDate.slice(0,4)+'/'+postDate.slice(5,7)+'/'+slug+'/'; - var filepath = 'generated'+url; - var filename = filepath+'index.html'; - var options = { - pretty: false, - title: title, - content: content, - slug: slug, - url: url, - postDate: postDate - }; - - console.log('Rendering post: '+title); - var jadeOut = jade.renderFile('views/render-post.jade', options); - - console.log('Creating directory: '+filepath); - mkdirp(filepath, function(err) { - if (err) { - console.log(err); - } - else { - console.log('Writing to file: '+filename); - - fs.writeFile(filename, jadeOut, 'utf-8', function(err) { - if (err) console.log(err); - cb(err); - }); - } - }); - }); -} - -exports.generatePost = generatePost; diff --git a/post.js b/post.js new file mode 100644 index 0000000..b7db9ec --- /dev/null +++ b/post.js @@ -0,0 +1,244 @@ +var moment = require("moment"); +var _ = require("lodash"); +var fs = require('fs'); +var mkdirp = require('mkdirp'); +var jade = require('jade'); +var markdown = require( "markdown" ).markdown; +var path = require('path'); +var schemas = require('./schemas.js'); +var config = require("./config.js").config; + +var Post = function(data) { + this.data = this.sanitize(data); +} + +//////////////////////////////////////////////////////////////////////////////////////// +// Prototype Setup +//////////////////////////////////////////////////////////////////////////////////////// + +Post.prototype.data = {} + +Post.prototype.get = function (name) { + return this.data[name]; +} + +Post.prototype.set = function (name, value) { + this.data[name] = value; +} + +Post.prototype.sanitize = function (data) { + data = data || {}; + schema = schemas.post; + return _.pick(_.defaults(data, schema), _.keys(schema)); +} + +Post.prototype.save = function (callback) { + var self = this; + this.set("updatedDate", new Date()); + this.data = this.sanitize(this.data); + db.collection("posts").update({uuid: this.get("uuid")}, this.data, {upsert: true}, function(err) { + callback(err); + }); +} + +//////////////////////////////////////////////////////////////////////////////////////// +// Prototype Functions +//////////////////////////////////////////////////////////////////////////////////////// + +// Parse a string of tags +// Returns a list of tags +Post.prototype.tagPost = function(str) { + this.set("tags", []); + + // we don't need no stinking commas + var str = str.replace(/,/g,''); + + // remove accents, swap ñ for n, etc + var from = "àáäâèéëêìíïîòóöôùúüûñç·/,:;&%"; + var to = "aaaaeeeeiiiioooouuuunc-------"; + for (var i=0, l=from.length ; i