]> git.r.bdr.sh - rbdr/blog/commitdiff
Use new generators
authorBen Beltran <redacted>
Mon, 1 Jun 2020 21:33:40 +0000 (23:33 +0200)
committerBen Beltran <redacted>
Mon, 1 Jun 2020 21:33:40 +0000 (23:33 +0200)
lib/blog.js
lib/generators/html.js [new file with mode: 0644]
lib/generators/rss.js [new file with mode: 0644]
lib/generators/static.js [new file with mode: 0644]

index 6b3397fd7d2f008ac1de39cb4552583fd0723124..98efabdf1fc618636390ef5874704aa0f9028bc7 100644 (file)
@@ -1,25 +1,24 @@
 'use strict';
 
 'use strict';
 
-const { exec } = require('child_process');
 const { access, mkdir, readdir, readFile, rmdir, writeFile } = require('fs/promises');
 const { access, mkdir, readdir, readFile, rmdir, writeFile } = require('fs/promises');
-const { template } = require('dot');
 const { ncp } = require('ncp');
 const { join } = require('path');
 const Marked = require('marked');
 const { debuglog, promisify } = require('util');
 
 const { ncp } = require('ncp');
 const { join } = require('path');
 const Marked = require('marked');
 const { debuglog, promisify } = require('util');
 
+const StaticGenerator = require('./generators/static');
+const HTMLGenerator = require('./generators/html');
+const RSSGenerator = require('./generators/rss');
+
 const internals = {
 
   // Promisified functions
   ncp: promisify(ncp),
 
 const internals = {
 
   // Promisified functions
   ncp: promisify(ncp),
 
-  exec: promisify(exec),
   debuglog: debuglog('blog'),
 
   // constants
 
   debuglog: debuglog('blog'),
 
   // constants
 
-  kAssetsDirectoryName: 'assets',
-  kIndexName: 'index.html',
   kFileNotFoundError: 'ENOENT',
   kMarkdownRe: /\.md$/i,
   kMetadataFilename: 'metadata.json',
   kFileNotFoundError: 'ENOENT',
   kMarkdownRe: /\.md$/i,
   kMetadataFilename: 'metadata.json',
@@ -36,7 +35,7 @@ const internals = {
  * updating posts, and handling the publishing.
  *
  * @class Blog
  * updating posts, and handling the publishing.
  *
  * @class Blog
- * @param {Potluck.tConfiguration} config the initialization options to
+ * @param {Blog.tConfiguration} config the initialization options to
  * extend the instance
  */
 module.exports = class Blog {
  * extend the instance
  */
 module.exports = class Blog {
@@ -102,33 +101,40 @@ module.exports = class Blog {
 
   async _generate() {
 
 
   async _generate() {
 
-    const assetsTarget = join(this.staticDirectory, internals.kAssetsDirectoryName);
-    const indexTarget = join(this.staticDirectory, internals.kIndexName);
-    const indexLocation = join(this.templatesDirectory, internals.kIndexName);
-    const posts = [];
+    internals.debuglog('Generating output');
+
+    const posts = await this._readPosts(this.postsDirectory);
+
+    await StaticGenerator(this.postsDirectory, this.staticDirectory, posts);
+    await HTMLGenerator(this.templatesDirectory, this.staticDirectory, posts);
+    await RSSGenerator(this.templatesDirectory, this.staticDirectory, posts);
+  }
+
+  // Reads the posts into an array
 
 
-    internals.debuglog(`Removing ${assetsTarget}`);
-    await rmdir(assetsTarget, { recursive: true });
+  async _readPosts(source) {
+
+    internals.debuglog('Reading posts');
+    const posts = [];
 
     for (let i = 0; i < this.maxPosts; ++i) {
 
     for (let i = 0; i < this.maxPosts; ++i) {
-      const sourcePath = join(this.postsDirectory, `${i}`);
+      const postSourcePath = join(source, `${i}`);
 
 
-      try {
-        await access(this.postsDirectory);
+      internals.debuglog(`Reading ${postSourcePath} into posts array`);
 
 
-        const assetsSource = join(sourcePath, internals.kAssetsDirectoryName);
-        const postContentPath = await this._findBlogContent(sourcePath);
+      try {
+        await access(postSourcePath);
 
 
-        internals.debuglog(`Copying ${assetsSource} to ${assetsTarget}`);
-        await internals.ncp(assetsSource, assetsTarget);
+        const metadata = await this._getMetadata(i);
 
 
+        const postContentPath = await this._findBlogContent(postSourcePath);
         internals.debuglog(`Reading ${postContentPath}`);
         const postContent = await readFile(postContentPath, { encoding: 'utf8' });
 
         internals.debuglog('Parsing markdown');
         posts.push({
         internals.debuglog(`Reading ${postContentPath}`);
         const postContent = await readFile(postContentPath, { encoding: 'utf8' });
 
         internals.debuglog('Parsing markdown');
         posts.push({
-          html: Marked(postContent),
-          id: i + 1
+          ...metadata,
+          html: Marked(postContent)
         });
       }
       catch (error) {
         });
       }
       catch (error) {
@@ -141,12 +147,7 @@ module.exports = class Blog {
       }
     }
 
       }
     }
 
-    internals.debuglog(`Reading ${indexLocation}`);
-    const indexTemplate = await readFile(indexLocation, { encoding: 'utf8' });
-
-    internals.debuglog('Generating HTML');
-    const indexHtml = template(indexTemplate)({ posts });
-    await writeFile(indexTarget, indexHtml);
+    return posts;
   }
 
   // Shift the posts, delete any remainder.
   }
 
   // Shift the posts, delete any remainder.
@@ -180,13 +181,13 @@ module.exports = class Blog {
 
   // Attempts to read existing metadata. Otherwise generates new set.
 
 
   // Attempts to read existing metadata. Otherwise generates new set.
 
-  async _getMetadata() {
+  async _getMetadata(index = 0) {
 
 
-    const metadataTarget = join(this.postsDirectory, '0', internals.kMetadataFilename);
+    const metadataTarget = join(this.postsDirectory, String(index), internals.kMetadataFilename);
 
     try {
       internals.debuglog(`Looking for metadata at ${metadataTarget}`);
 
     try {
       internals.debuglog(`Looking for metadata at ${metadataTarget}`);
-      return await readFile(metadataTarget);
+      return JSON.parse(await readFile(metadataTarget, { encoding: 'utf8' }));
     }
     catch (e) {
       internals.debuglog(`Metadata not found or unreadable. Generating new set.`);
     }
     catch (e) {
       internals.debuglog(`Metadata not found or unreadable. Generating new set.`);
@@ -196,7 +197,7 @@ module.exports = class Blog {
         createdOn
       };
 
         createdOn
       };
 
-      return JSON.stringify(metadata, null, 2);
+      return metadata;
     }
   }
 
     }
   }
 
@@ -207,7 +208,7 @@ module.exports = class Blog {
 
     const metadataTarget = join(this.postsDirectory, '0', internals.kMetadataFilename);
     internals.debuglog(`Writing ${metadataTarget}`);
 
     const metadataTarget = join(this.postsDirectory, '0', internals.kMetadataFilename);
     internals.debuglog(`Writing ${metadataTarget}`);
-    await writeFile(metadataTarget, metadata);
+    await writeFile(metadataTarget, JSON.stringify(metadata, null, 2));
   }
 
   // Copies a post directory to the latest slot.
   }
 
   // Copies a post directory to the latest slot.
diff --git a/lib/generators/html.js b/lib/generators/html.js
new file mode 100644 (file)
index 0000000..ba2676c
--- /dev/null
@@ -0,0 +1,35 @@
+'use strict';
+
+const { template } = require('dot');
+const { readFile, writeFile } = require('fs/promises');
+const { join } = require('path');
+const { debuglog } = require('util');
+
+const internals = {
+  debuglog: debuglog('blog'),
+
+  kIndexName: 'index.html'
+};
+
+/**
+ * Generates the blog index page
+ *
+ * @name HTMLGenerator
+ * @param {string} source the source directory
+ * @param {string} target the target directory
+ * @param {Array.<Blog.tPost>} posts the list of posts
+ */
+module.exports = async function HTMLGenerator(source, target, posts) {
+
+  internals.debuglog('Generating HTML');
+  const indexTarget = join(target, internals.kIndexName);
+  const indexLocation = join(source, internals.kIndexName);
+
+  internals.debuglog(`Reading ${indexLocation}`);
+  const indexTemplate = await readFile(indexLocation, { encoding: 'utf8' });
+
+  internals.debuglog('Writing HTML');
+  const indexHtml = template(indexTemplate)({ posts });
+  await writeFile(indexTarget, indexHtml);
+};
+
diff --git a/lib/generators/rss.js b/lib/generators/rss.js
new file mode 100644 (file)
index 0000000..a1fcb08
--- /dev/null
@@ -0,0 +1,42 @@
+'use strict';
+
+const { template } = require('dot');
+const { encodeXML } = require('entities');
+const { readFile, writeFile } = require('fs/promises');
+const { join } = require('path');
+const { debuglog } = require('util');
+
+const internals = {
+  debuglog: debuglog('blog'),
+
+  kFeedName: 'feed.xml'
+};
+
+/**
+ * Generates an RSS feed XML file
+ *
+ * @name RSSGenerator
+ * @param {string} source the source directory
+ * @param {string} target the target directory
+ * @param {Array.<Blog.tPost>} posts the list of posts
+ */
+module.exports = async function RSSGenerator(source, target, posts) {
+
+  internals.debuglog('Generating RSS');
+  const feedTarget = join(target, internals.kFeedName);
+  const feedLocation = join(source, internals.kFeedName);
+
+  internals.debuglog(`Reading ${feedLocation}`);
+  const feedTemplate = await readFile(feedLocation, { encoding: 'utf8' });
+
+  internals.debuglog('Writing RSS');
+  posts = posts.map((post) => ({
+    ...post,
+    createdOn: (new Date(post.createdOn)).toUTCString(),
+    html: encodeXML(post.html)
+  }));
+  const feedXml = template(feedTemplate)({ posts });
+  await writeFile(feedTarget, feedXml);
+};
+
+
diff --git a/lib/generators/static.js b/lib/generators/static.js
new file mode 100644 (file)
index 0000000..eb3c631
--- /dev/null
@@ -0,0 +1,50 @@
+'use strict';
+
+const { access, rmdir } = require('fs/promises');
+const { ncp } = require('ncp');
+const { join } = require('path');
+const { debuglog, promisify } = require('util');
+
+const internals = {
+  ncp: promisify(ncp),
+  debuglog: debuglog('blog'),
+
+  kAssetsDirectoryName: 'assets'
+};
+
+/**
+ * Generates the static assets required for the blog
+ *
+ * @name StaticGenerator
+ * @param {string} source the source directory
+ * @param {string} target the target directory
+ * @param {Array.<Blog.tPost>} posts the list of posts
+ */
+module.exports = async function StaticGenerator(source, target, posts) {
+
+  const assetsTarget = join(target, internals.kAssetsDirectoryName);
+
+  internals.debuglog(`Removing ${assetsTarget}`);
+  await rmdir(assetsTarget, { recursive: true });
+
+  for (let i = 0; i < posts.length; ++i) {
+    const postSourcePath = join(source, `${i}`);
+
+    try {
+      await access(postSourcePath);
+
+      const assetsSource = join(postSourcePath, internals.kAssetsDirectoryName);
+
+      internals.debuglog(`Copying ${assetsSource} to ${assetsTarget}`);
+      await internals.ncp(assetsSource, assetsTarget);
+    }
+    catch (error) {
+      if (error.code === internals.kFileNotFoundError) {
+        internals.debuglog(`Skipping ${i}`);
+        continue;
+      }
+
+      throw error;
+    }
+  }
+};