110 lines
3.7 KiB
TypeScript
110 lines
3.7 KiB
TypeScript
import express, { Router, Request, Response } from "express";
|
|
import { Page, PostMetadata } from "../metadata";
|
|
import { ArticleObject } from "./activity";
|
|
import Article from "../entity/Article";
|
|
import { getConnection } from "typeorm";
|
|
import uuidv4 from "uuid/v4";
|
|
|
|
const domain = process.env.DOMAIN;
|
|
|
|
export async function setup(posts: Page[]) {
|
|
const repository = getConnection().getRepository(Article);
|
|
for (const post of posts) {
|
|
const postMeta = <PostMetadata>post.metadata;
|
|
if (await repository.findOne(postMeta.permalink)) {
|
|
continue;
|
|
}
|
|
const articleObject = {
|
|
"@context": [
|
|
"https://www.w3.org/ns/activitystreams",
|
|
],
|
|
"type": "Article",
|
|
"id": `https://${domain}${post.metadata.permalink}`,
|
|
"published": (<Date>postMeta.date).toISOString(),
|
|
"inReplyTo": null,
|
|
"conversation": `https://${domain}/ap/conversation/${uuidv4()}`,
|
|
"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
|
|
};
|
|
const article = new Article();
|
|
article.id = postMeta.permalink;
|
|
article.articleObject = articleObject;
|
|
article.conversation = articleObject.conversation;
|
|
article.hasFederated = false;
|
|
await getConnection().manager.save(article);
|
|
//db.run("INSERT OR IGNORE INTO articles(id, article_doc, conversation, has_federated) VALUES($id, $article_doc, $conversation, $has_federated)", {
|
|
//$id: postMeta.permalink,
|
|
//$article_doc: JSON.stringify(articleObject),
|
|
//$conversation: articleObject.conversation,
|
|
//$has_federated: 0
|
|
//}, (err) => {
|
|
//if (err) console.log(`Encountered error inserting article ${postMeta.permalink}`, err);
|
|
//});
|
|
}
|
|
}
|
|
|
|
export async function toFederate(): Promise<[string, ArticleObject][]> {
|
|
return new Promise(async (resolve, reject) => {
|
|
const articles: Article[] = await getConnection().createQueryBuilder().select("article").from(Article, "article").where("article.hasFederated = :hasFederated", { hasFederated: false }).getMany();
|
|
|
|
let result: [string, ArticleObject][] = [];
|
|
articles.forEach(it => {
|
|
result.push([it.id, it.articleObject]);
|
|
});
|
|
resolve(result);
|
|
//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/", async (req, res, next) => {
|
|
const best = req.accepts(["text/html", "application/activity+json"]);
|
|
console.log(best);
|
|
if (best === "text/html") {
|
|
next();
|
|
} else if (best === "application/activity+json") {
|
|
const id = `/${req.params.category}/${req.params.year}/${req.params.slug}/`;
|
|
const repository = getConnection().getRepository(Article);
|
|
try {
|
|
const article = await repository.findOne(id);
|
|
res.type("application/activity+json").json(article.articleObject).end();
|
|
} catch (err) {
|
|
res.status(500).end(err);
|
|
}
|
|
|
|
//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/activity+json");
|
|
//res.end(result.article_doc);
|
|
//});
|
|
} else {
|
|
res.status(415).end("No acceptable content-type given. text/html or application/activity+json are supported");
|
|
}
|
|
});
|
|
}
|