]> git.r.bdr.sh - rbdr/blog/commitdiff
Add archive publishing
authorRuben Beltran del Rio <redacted>
Sun, 8 May 2022 18:44:49 +0000 (20:44 +0200)
committerRuben Beltran del Rio <redacted>
Sun, 8 May 2022 18:44:49 +0000 (20:44 +0200)
README.md
bin/blog.js
lib/archivers/gemlog.js
lib/blog.js
package-lock.json
package.json
templates/index.html

index d0c4eb12ce88bf296036de493e6ca94e205e7201..41de942a8eff1d8757a347dc90960ff30f553b2d 100644 (file)
--- a/README.md
+++ b/README.md
@@ -101,7 +101,8 @@ as a gemlog format).
 
 This gets updated every time you add or update a post.
 
 
 This gets updated every time you add or update a post.
 
-The publishing will not publish the archive. This is up to you to control.
+Publishing with `--publish` will not publish the archive. Instead you should
+use `--publish-archive`, which will `rsync` it to the destination provided.
 
 ## Debugging
 
 
 ## Debugging
 
index 3c37f47a9b06046b77512ae177fde3719f732c2a..8f0ab70e3ad192c54a42a2b639971c5ef8cc2e73 100755 (executable)
@@ -8,7 +8,7 @@ const Minimist = require('minimist');
 
 const internals = {
   blog: new Blog(Config),
 
 const internals = {
   blog: new Blog(Config),
-  expectedKeys: ['add',  'generate', 'update', 'publish', 'version'],
+  expectedKeys: ['add',  'generate', 'update', 'publish', 'publish-archive', 'version'],
 
   // Application entry point. Reads arguments and calls the
   // corresponding method from the blog lib
 
   // Application entry point. Reads arguments and calls the
   // corresponding method from the blog lib
@@ -47,6 +47,11 @@ const internals = {
             await internals.blog.publish(value);
             return;
           }
             await internals.blog.publish(value);
             return;
           }
+
+          if (argument === 'publish-archive') {
+            await internals.blog.publishArchive(value);
+            return;
+          }
         }
       }
 
         }
       }
 
@@ -89,7 +94,8 @@ const internals = {
     console.error('blog --add path/to/blog_post\t\t(creates new blog post)');
     console.error('blog --update path/to/blog_post\t\t(updates latest blog post)');
     console.error('blog --generate \t\t\t(generates the blog assets)');
     console.error('blog --add path/to/blog_post\t\t(creates new blog post)');
     console.error('blog --update path/to/blog_post\t\t(updates latest blog post)');
     console.error('blog --generate \t\t\t(generates the blog assets)');
-    console.error('blog --publish <bucket> \t\t\t\t(publishes the blog to an S3 bucket)');
+    console.error('blog --publish <bucket> \t\t(publishes the blog to an S3 bucket)');
+    console.error('blog --publish-archive <destination> \t(publishes the archive to a remote host)');
     console.error('blog --version \t\t\t\t(print the version)');
   }
 };
     console.error('blog --version \t\t\t\t(print the version)');
   }
 };
index d50d411bc8af23a4ff7777181cabc7c72cb3bcfd..50bb33407c7da12fc2f0356c9eb3af15d188c670 100644 (file)
@@ -1,20 +1,36 @@
 const { mkdir, readdir, rm, writeFile } = require('fs/promises');
 const { debuglog, promisify } = require('util');
 const { ncp } = require('ncp');
 const { mkdir, readdir, rm, writeFile } = require('fs/promises');
 const { debuglog, promisify } = require('util');
 const { ncp } = require('ncp');
-const { join } = require('path');
+const { resolve, join } = require('path');
 
 const internals = {
 
 const internals = {
-  kArchiveName: '.gemlog',
+  kArchiveName: resolve(join(__dirname, '../..', '.gemlog')),
   kIndexName: 'index.gmi',
   kGeminiRe: /\.gmi$/i,
 
   ncp: promisify(ncp),
   debuglog: debuglog('blog'),
   kIndexName: 'index.gmi',
   kGeminiRe: /\.gmi$/i,
 
   ncp: promisify(ncp),
   debuglog: debuglog('blog'),
+
+  buildUrl(id, slug) {
+    return `./${id}/${slug}`;
+  },
+
+  buildTitle (id, slug) {
+    const date = new Date(Number(id));
+    const shortDate = date.toISOString().split('T')[0]
+    const title = slug.split('-').join(' ');
+    return `${shortDate} ${title}`
+  },
+
+  buildLink(id, slug) {
+    return `=> ${internals.buildUrl(id,slug)} ${internals.buildTitle(id,slug)}`;
+  }
 };
 
 module.exports = async function(archiveDirectory) {
   internals.debuglog(`Reading archive ${archiveDirectory}`);
 };
 
 module.exports = async function(archiveDirectory) {
   internals.debuglog(`Reading archive ${archiveDirectory}`);
-  const postIds = await readdir(archiveDirectory)
+  const postIds = (await readdir(archiveDirectory))
+    .sort((a, b) => Number(b) - Number(a));
   const posts = [];
   for (const id of postIds) {
     const postDirectory = join(archiveDirectory, id);
   const posts = [];
   for (const id of postIds) {
     const postDirectory = join(archiveDirectory, id);
@@ -26,8 +42,14 @@ module.exports = async function(archiveDirectory) {
 
   internals.debuglog(`Read ${posts.length} posts`);
 
 
   internals.debuglog(`Read ${posts.length} posts`);
 
-  const index = ['# Unlimited Pizza Gemlog Archive', '',
-    ...posts.map((post) => `=> ./${post.id}/${post.slug}`)].join('\n');
+  const index = [
+    '# Unlimited Pizza Gemlog Archive', '',
+    '=> https://blog.unlimited.pizza/feed.xml ðŸ“° RSS Feed',
+    '=> https://blog.unlimited.pizza/index.txt ðŸ“‘ http text version (latest 3 posts)',
+    '',
+    ...posts.map((post) => internals.buildLink(post.id, post.slug)),
+    '', '=> ../ ðŸŠī Back to main page'
+  ].join('\n');
 
   try {
     internals.debuglog('Removing index');
 
   try {
     internals.debuglog('Removing index');
index 8ae3e21a28884f1b091b1f3e4d221d0543481cf8..ff52554a07ed5faa44c817f4e12bceb35f7ee539 100644 (file)
@@ -3,7 +3,7 @@
 const { access, mkdir, readdir, readFile, rm, writeFile } = require('fs/promises');
 const { exec } = require('child_process');
 const { ncp } = require('ncp');
 const { access, mkdir, readdir, readFile, rm, writeFile } = require('fs/promises');
 const { exec } = require('child_process');
 const { ncp } = require('ncp');
-const { join } = require('path');
+const { resolve, join } = require('path');
 const ParseGemini = require('gemini-to-html/parse');
 const RenderGemini = require('gemini-to-html/render');
 const { debuglog, promisify } = require('util');
 const ParseGemini = require('gemini-to-html/parse');
 const RenderGemini = require('gemini-to-html/render');
 const { debuglog, promisify } = require('util');
@@ -126,6 +126,38 @@ module.exports = class Blog {
     internals.debuglog('Finished publishing');
   }
 
     internals.debuglog('Finished publishing');
   }
 
+  /**
+   * Publishes the archive to a host using rsync. Currently assumes
+   * gemlog archive.
+   *
+   * @function publishArchive
+   * @memberof Blog
+   * @return {Promise<undefined>} empty promise, returns no value
+   * @instance
+   */
+  async publishArchive(host) {
+
+    internals.debuglog(`Publishing archive to ${host}`);
+    try {
+      await internals.exec('which rsync');
+    }
+    catch (err) {
+      console.error('Please install rsync to publish the archive.');
+    }
+
+    try {
+      const gemlogPath = resolve(join(__dirname, '../', '.gemlog'));
+      internals.debuglog(`Reading archive from ${gemlogPath}`);
+      await internals.exec(`rsync -r ${gemlogPath}/ ${host}`);
+    }
+    catch (err) {
+      console.error('Failed to publish archive');
+      console.error(err.stderr);
+    }
+
+    internals.debuglog('Finished publishing');
+  }
+
   // Parses Gemini for each page, copies assets and generates index.
 
   async generate() {
   // Parses Gemini for each page, copies assets and generates index.
 
   async generate() {
index 3efff4a78a3f2db78e343050cc14b8505bb53b8d..4dfb22809ddd84693b26ad64d226809deeab69d4 100644 (file)
@@ -13,7 +13,6 @@
         "entities": "^3.0.1",
         "gemini-to-html": "^2.1.0",
         "getenv": "^1.0.0",
         "entities": "^3.0.1",
         "gemini-to-html": "^2.1.0",
         "getenv": "^1.0.0",
-        "marked": "^4.0.8",
         "minimist": "^1.2.5",
         "ncp": "^2.0.0"
       },
         "minimist": "^1.2.5",
         "ncp": "^2.0.0"
       },
       "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==",
       "dev": true
     },
       "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==",
       "dev": true
     },
-    "node_modules/marked": {
-      "version": "4.0.8",
-      "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.8.tgz",
-      "integrity": "sha512-dkpJMIlJpc833hbjjg8jraw1t51e/eKDoG8TFOgc5O0Z77zaYKigYekTDop5AplRoKFGIaoazhYEhGkMtU3IeA==",
-      "bin": {
-        "marked": "bin/marked.js"
-      },
-      "engines": {
-        "node": ">= 12"
-      }
-    },
     "node_modules/mdurl": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
     "node_modules/mdurl": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
       "dev": true,
       "requires": {}
     },
       "dev": true,
       "requires": {}
     },
-    "marked": {
-      "version": "4.0.8",
-      "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.8.tgz",
-      "integrity": "sha512-dkpJMIlJpc833hbjjg8jraw1t51e/eKDoG8TFOgc5O0Z77zaYKigYekTDop5AplRoKFGIaoazhYEhGkMtU3IeA=="
-    },
     "mdurl": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
     "mdurl": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
index 8bc21f92f5b677ac3a4bf28d831d437f7d132970..1df9fb34b772d4376c4f46b5ab5c76c7d25f0c8e 100644 (file)
@@ -26,7 +26,6 @@
     "entities": "^3.0.1",
     "gemini-to-html": "^2.1.0",
     "getenv": "^1.0.0",
     "entities": "^3.0.1",
     "gemini-to-html": "^2.1.0",
     "getenv": "^1.0.0",
-    "marked": "^4.0.8",
     "minimist": "^1.2.5",
     "ncp": "^2.0.0"
   },
     "minimist": "^1.2.5",
     "ncp": "^2.0.0"
   },
index b8f9213f9310d25ef8fb218033a73c5723d85aea..f5dbbc3cfcb92955097b926652567006bbdd37d6 100644 (file)
@@ -28,6 +28,7 @@
     <main>
     <p>
     This blog is also available in <a href="/index.txt">plain text</a>.
     <main>
     <p>
     This blog is also available in <a href="/index.txt">plain text</a>.
+    Archive available in <a href="gemini://gemini.unlimited.pizza/gemlog">gemini</a>
     </p>
     <p>
     â†’ <a href="http://unlimited.pizza">home</a>.
     </p>
     <p>
     â†’ <a href="http://unlimited.pizza">home</a>.