deardesi.js/bin/deardesi.js

453 lines
12 KiB
JavaScript
Raw Normal View History

2015-01-16 04:58:27 +00:00
#!/usr/bin/env node
2020-11-09 03:30:15 +00:00
"use strict";
2015-01-13 21:50:17 +00:00
2020-11-09 03:30:15 +00:00
var PromiseA = require("bluebird"),
fs = PromiseA.promisifyAll(require("fs")),
fsx = PromiseA.promisifyAll(require("fs.extra")),
tar = require("tar"),
2015-01-22 01:13:47 +00:00
//, requestAsync = PromiseA.promisify(require('request'))
2020-11-09 03:30:15 +00:00
request = PromiseA.promisifyAll(require("request")),
forEachAsync = require("foreachasync").forEachAsync,
2015-01-22 01:13:47 +00:00
//, spawn = require('child_process').spawn
2020-11-09 03:30:15 +00:00
path = require("path"),
cli = require("cli"),
UUID = require("node-uuid"),
Desi,
zlib = require("zlib");
2015-01-13 21:50:17 +00:00
cli.parse({
2020-11-09 03:30:15 +00:00
blogdir: ["d", "Where your blog is, i.e. ~/path/to/blog", "string", "./"],
//, output: ['o', 'name of output directory within ~/path/to/blog', 'string', './compiled']
2015-01-13 21:50:17 +00:00
});
2015-01-16 04:56:14 +00:00
function init() {
2020-11-09 03:30:15 +00:00
Desi = require("desirae").Desirae;
2015-01-16 04:56:14 +00:00
2015-01-23 09:56:27 +00:00
//
// 1. Transform (yml, slug, etc)
//
Desi.registerTransform(
2020-11-09 03:30:15 +00:00
"lint",
require("desirae/lib/transform-core").DesiraeTransformCore.lint,
{ collections: true }
2015-01-23 09:56:27 +00:00
);
Desi.registerTransform(
2020-11-09 03:30:15 +00:00
"root",
require("desirae/lib/transform-core").DesiraeTransformCore.root,
{ root: true }
2015-01-23 09:56:27 +00:00
);
Desi.registerTransform(
2020-11-09 03:30:15 +00:00
"normalize",
require("desirae/lib/transform-core").DesiraeTransformCore.normalize,
{ root: true, collections: true }
2015-01-23 09:56:27 +00:00
);
Desi.registerTransform(
2020-11-09 03:30:15 +00:00
"disqus",
require("desirae/lib/transform-core").DesiraeTransformCore.disqus,
{ collections: true }
2015-01-23 09:56:27 +00:00
);
//
// 2. Aggregate (rss, categories, tags, etc)
//
2020-11-09 03:30:15 +00:00
Desi.registerAggregator(
require("desirae/lib/aggregate-core").DesiraeAggregateCore.collate
);
2015-01-23 09:56:27 +00:00
//
// 3. Datamap (ruhoh, desirae, jade, mustache, liquid)
//
2020-11-09 03:30:15 +00:00
Desi.registerDataMapper(
"desirae",
require("desirae/lib/datamap-core").DesiraeDatamapCore
);
Desi.registerDataMapper(
"desirae@1.0",
require("desirae/lib/datamap-core").DesiraeDatamapCore
);
2015-01-24 01:24:46 +00:00
// TODO ruhoh versions are ruhoh-twitter (1.0) and ruhoh-boostrap-2 (2.6)
2020-11-09 03:30:15 +00:00
Desi.registerDataMapper(
"ruhoh",
require("desirae-datamap-ruhoh").DesiraeDatamapRuhoh
);
Desi.registerDataMapper(
"ruhoh@1.0",
require("desirae-datamap-ruhoh").DesiraeDatamapRuhoh
);
Desi.registerDataMapper(
"ruhoh@2.6",
require("desirae-datamap-ruhoh").DesiraeDatamapRuhoh
);
2015-01-23 09:56:27 +00:00
//
// 4. Render (md -> html, less -> css, etc)
//
Desi.registerRenderer(
2020-11-09 03:30:15 +00:00
"js",
require("desirae/lib/render-core").DesiraeRenderJs,
{ themes: true, assets: true }
2015-01-23 09:56:27 +00:00
);
Desi.registerRenderer(
2020-11-09 03:30:15 +00:00
"css",
require("desirae/lib/render-core").DesiraeRenderCss,
{ themes: true, assets: true }
2015-01-23 09:56:27 +00:00
);
2020-11-09 03:30:15 +00:00
["html", "htm", "xhtm", "xhtml"].forEach(function (ext) {
2015-01-23 09:56:27 +00:00
Desi.registerRenderer(
2020-11-09 03:30:15 +00:00
ext,
require("desirae/lib/render-core").DesiraeRenderHtml,
{ root: true, collections: true, themes: true, assets: true }
2015-01-23 09:56:27 +00:00
);
});
2020-11-09 03:30:15 +00:00
["md", "markdown", "mdown", "mkdn", "mkd", "mdwn", "mdtxt", "mdtext"].forEach(
function (ext) {
Desi.registerRenderer(
ext,
require("desirae/lib/render-core").DesiraeRenderMarkdown,
{ root: true, collections: true }
);
}
);
2015-01-23 09:56:27 +00:00
Desi.registerRenderer(
2020-11-09 03:30:15 +00:00
"jade",
require("desirae/lib/render-core").DesiraeRenderJade,
// TODO how to support jade in place of Mustache for layouts?
{ root: true, collections: true, themes: true }
2015-01-23 09:56:27 +00:00
);
2015-01-16 04:56:14 +00:00
}
2015-01-21 20:29:44 +00:00
function serve(displayDir, blogdir) {
2020-11-09 03:30:15 +00:00
var http = require("http"),
2015-01-13 21:50:17 +00:00
//, https = require('https')
2020-11-09 03:30:15 +00:00
app = require("../server").create({ blogdir: blogdir }),
server;
server = http
.createServer(app)
.listen(65080, function () {
console.info("Listening from " + displayDir);
console.info(
"Listening on http://local.dear.desi:" + server.address().port
);
})
.on("error", function (err) {
if (/EADDRINUSE/.test(err.message)) {
console.error("");
console.error("You're already running desi in another tab.");
console.error("");
console.error(
"Go to the other tab and press <control> + c to stop her. Then you can come back here to try again."
);
console.error("");
console.error("");
return;
}
2015-01-22 01:13:47 +00:00
2020-11-09 03:30:15 +00:00
throw err;
});
2015-01-13 21:50:17 +00:00
//secureServer = https.createServer(app).listen(65043);
}
2015-01-15 06:41:52 +00:00
function build(blogdir) {
2020-11-09 03:30:15 +00:00
var desi = {},
env = {};
2015-01-15 06:41:52 +00:00
env.working_path = env.blogdir = blogdir;
2015-01-23 09:56:27 +00:00
2015-01-15 06:41:52 +00:00
Desi.init(desi, env).then(function () {
2020-11-09 03:30:15 +00:00
env.url = desi.site.base_url + desi.site.base_path.replace(/^\/$/, "");
2015-01-15 06:41:52 +00:00
env.base_url = desi.site.base_url;
env.base_path = desi.site.base_path;
2020-11-09 03:30:15 +00:00
env.compiled_path = "compiled";
2015-01-15 06:41:52 +00:00
//env.since = 0;
Desi.buildAll(desi, env).then(function () {
2015-01-23 09:56:27 +00:00
Desi.write(desi, env).then(function (info) {
console.info(
2020-11-09 03:30:15 +00:00
"wrote",
info.numFiles,
"files",
"(" +
((info.size && (info.size / (1024 * 1024)).toFixed(2)) || "unkown"),
"MiB)",
"in",
((info.end - info.start) / 1000).toFixed(3) + "s"
2015-01-23 09:56:27 +00:00
);
2020-11-09 03:30:15 +00:00
console.info(
"Built and saved to " + path.join(env.working_path, env.compiled_path)
);
2015-01-15 06:41:52 +00:00
});
});
});
}
2015-01-16 00:17:23 +00:00
function createPost(originalDir, blogdir, title, extra) {
if (!title) {
2020-11-09 03:30:15 +00:00
console.error('Usage desi post "My First Post"');
2015-01-16 00:17:23 +00:00
console.error("(you didn't specify a title)");
process.exit(1);
}
if (extra) {
2020-11-09 03:30:15 +00:00
console.error('Usage desi post "My First Post"');
console.error(
"(too many arguments - maybe you didn't put your title in quotes?)"
);
2015-01-16 00:17:23 +00:00
process.exit(1);
}
2020-11-09 03:30:15 +00:00
var desi = {},
env = {},
post = {},
slug,
filepath,
displaypath;
2015-01-16 00:17:23 +00:00
env.working_path = env.blogdir = blogdir;
2015-01-18 01:16:04 +00:00
Desi.init(desi, env).then(function () {
2015-01-23 09:56:27 +00:00
// TODO move this 'create new post' logic to desirae proper
2020-11-09 03:30:15 +00:00
var collectionname = Object.keys(desi.config.collections)[0],
collection = desi.config.collections[collectionname],
entity = {};
/*
2015-01-16 00:17:23 +00:00
Desi.init(desi, env).then(function () {
env.url = desi.site.base_url + desi.site.base_path.replace(/^\/$/, '');
env.base_url = desi.site.base_url;
env.base_path = desi.site.base_path;
env.compiled_path = 'compiled';
//env.since = 0;
*/
post.title = title;
post.description = "";
post.date = Desi.toLocaleDate(new Date());
// TODO use site.permalink or collection.permalink or something like that
2015-01-23 09:56:27 +00:00
slug = Desi.slugify(post.title);
2020-11-09 03:30:15 +00:00
2015-01-16 00:17:23 +00:00
// TODO as per config
post.uuid = UUID.v4();
// TODO as per config for default collection and default format (jade, md, etc)
2020-11-09 03:30:15 +00:00
filepath = path.join(blogdir, collectionname, slug + ".md");
displaypath = path
.join(originalDir, "posts", slug + ".md")
.replace(/^\/(Users|home)\/[^\/]+\//, "~/")
.replace(/ /g, "\\ ");
2015-01-16 00:17:23 +00:00
2020-11-09 03:30:15 +00:00
["updated", "theme", "layout", "swatch"].forEach(function (key) {
2015-01-16 00:17:23 +00:00
if (!post[key]) {
delete post[key];
}
});
2015-01-23 09:56:27 +00:00
Object.keys(post).forEach(function (key) {
entity[key] = post[key];
});
entity.slug = slug;
post.permalink = Desi.permalinkify(
2020-11-09 03:30:15 +00:00
desi,
collection.fallback_permalink || collection.permalink,
entity
);
return Desi.fsapi
.putFiles(
[
{
path: filepath,
contents:
"---\n" +
Desi.YAML.stringify(post).trim() +
"\n" +
"---\n" +
"\n" +
"\n",
},
],
{ overwrite: false }
)
.then(function (r) {
var err;
if (r.error || r.errors.length) {
err = r.error || r.errors[0];
if (/exists/i.test(err.message)) {
console.error("");
console.error(
"Looks like that post already exists. Try a different name?"
);
console.error("");
console.error("");
} else {
throw err;
}
2015-01-16 00:17:23 +00:00
}
2020-11-09 03:30:15 +00:00
console.log("");
console.log(displaypath);
console.log("");
console.log(
"Markdown: [" +
post.title +
"](" +
desi.site.base_url +
path.join(desi.site.base_path, post.permalink) +
")"
);
console.log(
'HTML: <a href="' +
desi.site.base_url +
path.join(desi.site.base_path, post.permalink) +
'">' +
post.title +
"</a>"
);
console.log("");
console.log("");
console.log("vim " + displaypath);
console.log("(or emacs " + displaypath + ", if you swing that way)");
console.log("");
console.log("");
});
/*
2015-01-16 00:17:23 +00:00
});
*/
});
}
2015-01-22 01:13:47 +00:00
function initialize(displayPath, blogdir) {
console.info("\nCreating new blog", displayPath);
2020-11-09 03:30:15 +00:00
return fs
.readdirAsync(blogdir)
.then(function (nodes) {
// ignore dotfiles (.DS_Store, etc)
nodes = nodes.filter(function (node) {
return !/^\./.test(node);
});
2015-01-22 01:13:47 +00:00
2020-11-09 03:30:15 +00:00
if (nodes.length) {
console.error(
"\n\tOops! It looks like that directory is already being used"
);
console.error(
"\nIf you want you can DELETE it and start from scratch:"
);
console.error("\n\trm -r '" + blogdir.replace("'", "'\"'\"'") + "'");
console.error("\nOr you can specify a different directory.");
console.error("\n");
process.exit(1);
2015-01-22 01:13:47 +00:00
}
2020-11-09 03:30:15 +00:00
})
.catch(function (/*err*/) {
// doesn't exist? No problamo (all the better, actually)
return;
})
.then(function () {
return fsx.mkdirp(blogdir);
})
.then(function () {
2015-01-22 01:13:47 +00:00
return new PromiseA(function (resolve, reject) {
2020-11-09 03:30:15 +00:00
var t = tar.Extract({ path: blogdir, strip: 1 }),
gunzip = zlib.createGunzip();
console.info("Downloading blog template...", displayPath);
request
.get(
"https://github.com/DearDesi/desirae-blog-template/archive/v1.1.0.tar.gz"
)
2015-01-22 01:13:47 +00:00
.pipe(gunzip)
.pipe(t)
2020-11-09 03:30:15 +00:00
.on("end", resolve)
.on("error", reject);
});
})
.then(function () {
var themes;
themes = [
{
name: "ruhoh-twitter",
url:
"https://github.com/DearDesi/ruhoh-twitter/archive/v1.0.0.tar.gz",
},
{
name: "ruhoh-bootstrap-2",
url:
"https://github.com/DearDesi/ruhoh-bootstrap-2/archive/v1.0.1.tar.gz",
},
];
return forEachAsync(themes, function (theme) {
return new PromiseA(function (resolve, reject) {
var t = tar.Extract({
path: path.join(blogdir, "themes", theme.name),
strip: 1,
}),
gunzip = zlib.createGunzip();
console.info("Downloading theme '" + theme.name + "'");
request
.get(theme.url)
.pipe(gunzip)
.pipe(t)
.on("end", resolve)
.on("error", reject);
});
2015-01-22 01:13:47 +00:00
});
2020-11-09 03:30:15 +00:00
})
.then(function () {
console.info("Done.");
console.info("\nTo start the web editor run this:");
console.info(
"\n\tdesi serve -d '" + blogdir.replace("'", "'\"'\"'") + "'"
);
2015-01-22 01:13:47 +00:00
});
}
2015-01-13 21:50:17 +00:00
cli.main(function (args, options) {
2015-01-16 04:56:14 +00:00
init();
2020-11-09 03:30:15 +00:00
var command = args[0],
blogdir = options.blogdir,
originalDir = blogdir,
displayPath;
2015-01-13 21:50:17 +00:00
if (!blogdir) {
2020-11-09 03:30:15 +00:00
blogdir = path.resolve("./");
originalDir = "./";
2015-01-13 21:50:17 +00:00
}
2020-11-09 03:30:15 +00:00
displayPath = path
.resolve(originalDir)
.replace(/^\/(Users|home)\/[^\/]+\//, "~/")
.replace(/ /g, "\\ ");
2015-01-22 01:13:47 +00:00
2020-11-09 03:30:15 +00:00
if ("init" === command) {
2015-01-22 01:13:47 +00:00
initialize(displayPath, blogdir);
2015-01-13 21:50:17 +00:00
return;
}
2020-11-09 03:30:15 +00:00
if (!fs.existsSync(path.join(blogdir, "site.yml"))) {
2015-01-22 01:13:47 +00:00
console.error("Usage: desi [serve|init|post] -d ~/path/to/blog");
2020-11-09 03:30:15 +00:00
console.error(
"(if ~/path/to/blog doesn't yet exist or doesn't have config.yml, site.yml, etc, " +
"try `deardesi init -d ~/path/to/blog'"
);
2015-01-13 21:50:17 +00:00
process.exit(1);
return;
2020-11-09 03:30:15 +00:00
} else if ("build" === command) {
2015-01-15 06:41:52 +00:00
build(blogdir);
return;
2020-11-09 03:30:15 +00:00
} else if ("post" === command) {
2015-01-16 00:17:23 +00:00
createPost(originalDir, blogdir, args[1], args[2]);
2015-01-13 21:50:17 +00:00
return;
2020-11-09 03:30:15 +00:00
} else if ("serve" === command) {
2015-01-21 20:29:44 +00:00
serve(displayPath, blogdir);
2015-01-13 21:50:17 +00:00
return;
2020-11-09 03:30:15 +00:00
} else {
2015-01-16 00:17:23 +00:00
console.error("Usage: desi [serve|init|post] -d ~/path/to/blog");
2015-01-13 21:50:17 +00:00
return;
}
});