Dwelling/dwelling.js

164 lines
5.0 KiB
JavaScript

const path = require("path");
const Koa = require("koa");
const koaPug = require("koa-pug");
const koaRouter = require("koa-router");
// const koaServe = require("koa-static");
const bodyParser = require("koa-body")({multipart: true});
const mysql = require("mysql");
const fetch = require("node-fetch");
const config = require("./config");
const util = require("./util");
const guestbook = require("./dwelling/guestbook");
const mindflow = require("./dwelling/mindflow");
const articles_meta = {
"rpi_root_on_external_drive": {
title: "How to move a root from SD card to external drive on Raspberry Pi",
description: "Article on moving a root partition to an ext. drive on Raspberry Pi."
},
"setting_up_a_tor_proxy_relay_hiddenserv": {
title: "Setting up a Tor proxy, relay and hidden service",
description: "Article on setting up a Tor proxy, relay and hidden service."
},
"setting_up_a_mail_server": {
title: "Setting up a mail server",
description: "Article on creating your own mail server using Postfix and Dovecot."
},
"nginx_recipes_and_tips": {
title: "NGiNX's recipes & tips",
description: "Article on tips and recipes for NGiNX webserver."
},
};
async function getProcesses() {
let reimu = await fetch("http://reimu.home:14882/processes").then(r => r.json());
let sakuya = await fetch("http://sakuya.home:14882/processes").then(r => r.json());
return Object.fromEntries(Object.entries(reimu.processes).concat(Object.entries(sakuya.processes)));
}
function setRoutes(router) {
router.get('/', async ctx => {
await ctx.render('index', {
description: "A homepage of a russian guy Arav. Not just homepage, but FTP, radio, and smth more as well."
});
})
.get('/rss.xml', async ctx => {
ctx.type = 'xml';
await ctx.render('rss', {
doctype: 'xml',
protocol: ctx.protocol,
host: ctx.header.host,
author: "me@arav.top (Alexander \"Arav\")",
items: await mindflow.getPostsForRSS()
})
})
.get('/stuff', async ctx => {
await ctx.render('stuff', {
title: "/ Stuff",
description: "Here I share my programs, scripts, articles, may be other stuff."
})
})
.get('/mindflow', async ctx => {
await ctx.render('mindflow', {
title: "/ Mindflow",
description: "Here I will post updates on my infrastructure, my very important opinions and thoughts.",
tz: util.getTimezone(ctx),
diary: await mindflow.getPosts("Diary"),
updates: await mindflow.getPosts("Update")
})
})
.get('/stuff/article/:article', async ctx => {
if (ctx.params.article) {
return await ctx.render("articles/" + ctx.params.article, {
title: "/ Article / " + articles_meta[ctx.params.article].title,
description: articles_meta[ctx.params.article].description
});
} else {
return ctx.throw(404);
}
})
.get('/about', async ctx => {
await ctx.render('about', {
title: "/ About",
description: "This is a page where I'm telling about me and my home server.",
services: await getProcesses()
})
})
.get('/guestbook', async ctx => {
const page = ctx.request.query.p !== undefined ? ctx.request.query.p : 1;
const page_size = ctx.request.query.ps !== undefined ? ctx.request.query.ps : guestbook.pageSize;
let posts;
try {
posts = await guestbook.getPosts(page, page_size);
} catch(err) {
posts = null;
}
return await ctx.render('guestbook', {
title: "/ Guestbook",
description: "This is my guestbook. Welcome.",
tz: util.getTimezone(ctx),
owner: config.dwelling.guestbook.owner,
posts: posts,
error: posts === null,
pages_count: Math.ceil(await guestbook.getPostsCount() / page_size) });
})
.post('/guestbook', bodyParser, async ctx => {
const post = ctx.request.body;
post.hide_email = post.hide_email !== undefined;
post.hide_website = post.hide_website !== undefined;
try {
if (await guestbook.addPost(post))
ctx.redirect("/guestbook");
} catch(err) {
ctx.type = "text/plain";
if (err instanceof mysql.MysqlError)
ctx.body = `Database failed so your post wasn't added. So your time wasn't wasted here's your message:\n${post.message}`;
else
ctx.body = `Your post was rejected because of "${err}". So your time wasn't wasted here's your message:\n${post.message}`;
}
});
}
module.exports = () => {
const app = new Koa();
const pug = new koaPug({
viewPath: path.join(__dirname, "views", "dwelling"),
locals: {
date_: (date, tz) => util.datetime(date, util.formats.post_date, tz),
mindflowDateToId: (date, tz) => util.datetime(date, util.formats.id_date, tz),
rssLink: util.rssLink },
app: app
});
const dwelling_router = koaRouter();
setRoutes(dwelling_router);
app.proxy = true;
app
.use(async (ctx, next) => {
try {
await next();
if (ctx.status === 404) ctx.throw(404);
} catch (err) {
if (ctx.status === 404)
await ctx.render('404');
else
await ctx.render('500');
}
})
// .use(koaServe(path.join("static", "shared")))
// .use(koaServe(path.join("static", "dwelling")))
.use(dwelling_router.routes())
.listen(config.dwelling.port, config.dwelling.host);
return app;
};