Post Publishing Script
04/13/15
Okay, now that I have a means of generating my blog and diary areas, I think it might be good to have a means of updating what is published to each area. I'm thinking using it should be something like:
node publish.js diary post_publishing_script_150413.html
So, I'll feed the area I'm pusblishing and the file I want to publish.
Now, in all honesty, publishing isn't a particularly complicated thing, and I got a vim macro that does it for me. The problem is, however, that it limits the design of this site to publish more-or-less manually. Further, I have this tendency to forget things that I should do before publishing, like make sure my links actually go somewhere. So a script will help me improve the system, and also be another step towards doing it all dynamically from the node server.
All right, let's start, as I tend to do, with a blank javascript file.
/*jslint node: true */
(function () {
'use strict';
// TODO:
var args;
args = (function () {
var processArgs = process.argv.slice(2);
return processArgs;
}());
}());
That's how I usually like to start a node script right now. The args function is still something I want to improve in general, though, but right now it's a good way to start.
Okay, I got carried away, and now I've got something I more-or-less like:
/*jslint node: true */
(function () {
'use strict';
var args,
usage,
errorCount,
publishCount,
publishPosts;
errorCount = 0;
usage = function (err) {
if (errorCount === 0) {
console.log('USAGE: publish <area> <file> [<file>] [...]');
console.log(' area: diary or blog');
console.log(' file: html file containing post to publish');
console.log();
}
if (err) {
console.log('Error: ' + err);
}
errorCount += 1;
return false;
};
args = (function () {
var processArgs,
area,
validAreas,
files;
processArgs = process.argv.slice(2);
if (processArgs.length < 2) {
return usage();
}
area = processArgs[0];
validAreas = ['diary', 'blog', 'test'];
if (validAreas.indexOf(area) === -1) {
return usage('area must be diary or blog');
}
files = processArgs.slice(1);
return {
area: area,
files: files
};
}());
if (!args) {
return;
}
publishPosts = function (area, filenames) {
var path,
database,
fs,
publishedPosts;
path = require('path');
database = path.join('database', area + '.txt');
fs = require('fs');
// Move posts to published area
filenames.forEach(function (filename) {
var publishedPath;
publishedPath = path.join(
'public',
area,
path.basename(filename)
);
fs.rename(filename, publishedPath, function (err) {
if (err) {
console.log(
'Error moving ' + filename + ' to ' + area
);
}
});
});
publishedPosts = '\n'
+ filenames.map(function (filename) {
return path.basename(filename);
}).join('\n');
// Add to the database of published posts
fs.appendFile(database, publishedPosts, 'utf-8', function (err) {
if (err) {
return console.log('Failed to publish to ' + area);
}
});
};
publishCount = 0;
args.files.forEach(function (filename) {
var fs;
fs = require('fs');
fs.readFile(filename, 'utf-8', function (err, data) {
if (err) {
return usage('could not open ' + filename);
}
// Verify no empty strings in file to be published
if (data.indexOf('""') !== -1) {
return usage('Empty string "" in ' + filename);
}
// TODO: Verify there's actually a post to publish
publishCount += 1;
if (publishCount === args.files.length) {
publishPosts(args.area, args.files);
}
});
});
}());
It works! Time to write a proper blog post about this.
Realization... putting '""' into this post flags it.... I'll just change the search string used instead of smarter verification. Smarter verifcation can happen later.