gemfedwiki

gemini fedwiki proxy
git clone git://jb55.com/gemfedwiki
Log | Files | Refs | README

commit 7e0c8c4f9399cecc0471523ddb79cdb506827ea4
Author: William Casarin <jb55@jb55.com>
Date:   Tue, 26 Oct 2021 21:49:27 -0700

let's do this

Diffstat:
A.gitignore | 1+
A.rgignore | 1+
Agemfedwiki | 23+++++++++++++++++++++++
Aindex.gmi | 6++++++
Aindex.js | 117+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apackage.json | 23+++++++++++++++++++++++
6 files changed, 171 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/.rgignore b/.rgignore @@ -0,0 +1 @@ +node_modules diff --git a/gemfedwiki b/gemfedwiki @@ -0,0 +1,23 @@ +#!/usr/bin/env node + +const fs = require('fs') + +const gemfedwiki = require('./') + +const cert = read_pem('cert.pem') +const key = read_pem('key.pem') +const passphrase = process.env.PASSPHRASE + +const server = gemfedwiki({cert, key, passphrase}) +const port = process.env.PORT || 1965 + +server.listen(port) +console.log(`gemfedwiki server listening on 0.0.0.0:${port}`) + +function read_pem(filename) +{ + if (!fs.existsSync(filename)) + throw new Error(`Couldn't load ${filename}`) + + return fs.readFileSync(filename) +} diff --git a/index.gmi b/index.gmi @@ -0,0 +1,6 @@ +# fed.wiki gemini portal + +Welcome to the fediwiki gemini portal. Here are some interesting links to get you started + +=> /fed.wiki.org +=> /dayton.fed.wiki The Dayton Experiment Hyperbook diff --git a/index.js b/index.js @@ -0,0 +1,117 @@ +const request = require('superagent') +const fs = require('fs') +const {createServer} = require('@derhuerst/gemini') + +function push_paragraph(lines, text) +{ + lines.push('') + lines.push(text) +} + +function slugify(text) +{ + return text.toLowerCase().split(/\s+/).join('-') +} + +function parse_links(text) +{ + let links = [] + const matches = text.matchAll(/\[\[([^\]]+)\]\]/g) + for (const match of matches) { + let [slug, name] = match[1].split(":").map(t => t.trim()) + if (name == null) + name = slug + slug = slugify(slug) + links.push({slug, name}) + } + + return links +} + +function process_item(root, lines, item) +{ + if (item.type === 'paragraph' || item.type === 'markdown') { + const text = item.text.trim() + const links = parse_links(text) + + lines.push('') + lines.push(text) + + if (links.length !== 0) + lines.push('') + + for (const {slug, name} of links) { + lines.push(`=> ${root}/${slug} ${name}`) + } + } +} + +function fedwiki2gmi(root, article) +{ + let lines = [] + lines.push(`# ${article.title}`) + + for (const item of article.story) { + process_item(root, lines, item) + } + + return lines.join("\n") + "\n" +} + +function last(arr) +{ + if (arr.length === 0) + return null + return arr[arr.length - 1] +} + +async function make_request(json_url, root="") +{ + const res = await request.get(json_url) + return fedwiki2gmi(root, res.body) +} + +async function make_index_request(host, root="") +{ + const res = await request.get(host + '/') + const file = last(res.redirects) + const json = file.replace(/.html$/, ".json") + return await make_request(json, root) +} + +async function handle_request(req, res) +{ + console.log(req.path) + + if (req.path === "/") { + fs.readFile("index.gmi", (err, dat) => { + res.end(dat) + }) + return + } + + const indreq = req.path.match(/^\/([^/]+)\/?$/) + if (indreq) { + const gmi = await make_index_request(indreq[1], "/" + indreq[1]) + res.end(gmi) + return + } + + const pathreq = req.path.match(/\/([^/]+)\/(.*)$/) + if (!pathreq) return res.gone() + + const host = pathreq[1] + const slug = pathreq[2] + const url = host + "/" + slug + ".json" + const gmi = await make_request(url, "/" + host) + + res.end(gmi) +} + +function serve(opts) +{ + // opts = { cert, key, passphrase } + return createServer(opts, handle_request) +} + +module.exports = serve diff --git a/package.json b/package.json @@ -0,0 +1,23 @@ +{ + "name": "gemfedwiki", + "description": "fedwiki to gemini", + "version": "0.1.0", + "repository": { + "url": "http://git.jb55.com/gemfedwiki" + }, + "main": "index.js", + "scripts": { + "test": "tap test/*.js" + }, + "bin": { + "gemfedwiki": "./gemfedwiki" + }, + "dependencies": { + "@derhuerst/gemini": "^1.2.0", + "stdin": "0.0.1", + "superagent": "^6.1.0" + }, + "devDependencies": { + "tap": "~0.2.5" + } +}