shadowfacts.net/lib/activitypub/articles.ts

75 lines
2.1 KiB
TypeScript

import express, { Router, Request, Response } from "express";
import { Page, PostMetadata } from "../metadata";
import { Article } from "./activity";
import { Database } from "sqlite3";
const domain = process.env.DOMAIN;
export async function setup(posts: Page[], db: Database) {
for (const post of posts) {
const postMeta = <PostMetadata>post.metadata;
const articleObject = {
"@context": [
"https://www.w3.org/ns/activitystreams",
],
"type": "Article",
"id": `https://${domain}${post.metadata.permalink}`,
"published": (<Date>postMeta.date).toISOString(),
"inReplyTo": null,
"url": `https://${domain}${postMeta.permalink}`,
"attributedTo": `https://${domain}/ap/actor`,
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"cc": [
`https://${domain}/ap/actor/followers`
],
"name": postMeta.title,
"content": post.text
};
db.run("INSERT OR IGNORE INTO articles(id, article_doc, has_federated) VALUES($id, $article_doc, $has_federated)", {
$id: postMeta.permalink,
$article_doc: JSON.stringify(articleObject),
$has_federated: 0
}, (err) => {
if (err) console.log(`Encountered error inserting article ${postMeta.permalink}`, err);
});
}
}
export async function toFederate(db: Database): Promise<[string, Article][]> {
return new Promise((resolve, reject) => {
db.all("SELECT id, article_doc FROM articles WHERE has_federated = $has_federated", {
$has_federated: 0
}, (err, rows) => {
if (err) reject(err);
else {
let result: [string, Article][] = [];
for (const row of rows) {
result.push([row.id, JSON.parse(row.article_doc)]);
}
resolve(result);
}
});
});
}
export function route(router: Router) {
router.use("/:category/:year/:slug/", (req, res, next) => {
if (req.accepts("text/html")) {
next();
} else {
const db = <Database>req.app.get("db")
db.get("SELECT article_doc FROM articles WHERE id = $id", {
$id: `/${req.params.category}/${req.params.year}/${req.params.slug}/`
}, (err, result) => {
if (err) {
res.status(500).end(err);
return;
}
res.type("application/json");
res.end(result.article_doc);
});
}
});
}