2022-05-11 18:35:34 +00:00
|
|
|
import Express from "express";
|
|
|
|
// v2 api
|
|
|
|
import convertv2 from "./lib/convert.js";
|
|
|
|
import serveStatic from "serve-static";
|
|
|
|
import cors from "cors";
|
|
|
|
import errorPage from "./lib/errorPage.js";
|
|
|
|
import morgan from "morgan";
|
|
|
|
import { detector } from "megalodon";
|
|
|
|
|
|
|
|
const app = Express();
|
2022-08-02 23:54:55 +00:00
|
|
|
app.disable("x-powered-by");
|
2022-05-11 18:35:34 +00:00
|
|
|
|
|
|
|
const logger = morgan(":method :url :status via :referrer - :response-time ms");
|
|
|
|
|
|
|
|
app.use(
|
|
|
|
serveStatic("public", {
|
|
|
|
maxAge: "1d",
|
|
|
|
})
|
|
|
|
);
|
|
|
|
|
|
|
|
function doCache(res, durationSecs) {
|
|
|
|
res.set({
|
|
|
|
"Cache-Control": "max-age=" + durationSecs,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// this just redirects to the
|
|
|
|
app.options("/api/feed", cors());
|
|
|
|
app.get("/api/feed", cors(), logger, function (req, res) {
|
|
|
|
// get feed url
|
|
|
|
const feedUrl = req.query.url;
|
|
|
|
if (!feedUrl) {
|
|
|
|
res
|
|
|
|
.status(400)
|
|
|
|
.send(errorPage(400, "You need to specify a feed URL", null));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-08-02 23:54:55 +00:00
|
|
|
let userUrl = "";
|
|
|
|
|
|
|
|
if (typeof feedUrl === "string") {
|
|
|
|
userUrl = feedUrl.replace(/\.atom.*/i, "");
|
|
|
|
}
|
2022-05-11 18:35:34 +00:00
|
|
|
|
|
|
|
const redirectUrl = "/api/v1/feed?";
|
|
|
|
const qs = ["userurl=" + encodeURIComponent(userUrl), "api=v1"];
|
|
|
|
|
|
|
|
["size", "theme", "boosts", "replies"].forEach((key) => {
|
2022-08-02 23:54:55 +00:00
|
|
|
if (typeof req.query[key] !== "undefined") {
|
2022-05-11 18:35:34 +00:00
|
|
|
qs.push(key + "=" + encodeURIComponent(req.query[key]));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
res.redirect(redirectUrl + qs.join("&"));
|
|
|
|
});
|
|
|
|
|
|
|
|
app.options("/api/v1/feed", cors());
|
|
|
|
app.get("/api/v1/feed", cors(), logger, async function (req, res) {
|
|
|
|
// get feed url
|
|
|
|
// userUrl
|
|
|
|
let type = req.query.instance_type;
|
|
|
|
let userUrl = req.query.userurl;
|
2022-08-02 23:54:55 +00:00
|
|
|
if (!userUrl) {
|
2022-05-11 18:35:34 +00:00
|
|
|
const user = req.query.user;
|
|
|
|
const instance = req.query.instance;
|
2022-08-02 23:54:55 +00:00
|
|
|
if (!type) {
|
2022-05-11 18:35:34 +00:00
|
|
|
type = await detector(instance).catch(() => "");
|
|
|
|
}
|
2022-08-02 23:54:55 +00:00
|
|
|
switch (type) {
|
|
|
|
case "mastodon":
|
|
|
|
case "pleroma":
|
|
|
|
userUrl = instance + "/users/" + user;
|
|
|
|
break;
|
|
|
|
case "misskey":
|
|
|
|
userUrl = instance + "/@" + user;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
res
|
|
|
|
.status(400)
|
|
|
|
.send(errorPage(400, "You need to specify a user URL", null));
|
|
|
|
return;
|
2022-05-11 18:35:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const feedUrl = req.query.feedurl;
|
|
|
|
|
|
|
|
const opts = {};
|
2022-08-02 23:54:55 +00:00
|
|
|
opts.size = req.query.size;
|
|
|
|
|
|
|
|
opts.theme = req.query.theme;
|
|
|
|
|
|
|
|
opts.theme = opts.theme.replace("auto-", `${type}-`);
|
|
|
|
opts.theme ??= "auto-auto";
|
|
|
|
|
|
|
|
if (typeof req.query.header === "string")
|
|
|
|
opts.header = req.query.header.toLowerCase() === "true";
|
|
|
|
if (typeof req.query.boosts === "string")
|
|
|
|
opts.boosts = req.query.boosts.toLowerCase() === "true";
|
|
|
|
if (typeof req.query.replies === "string")
|
2022-05-11 18:35:34 +00:00
|
|
|
opts.replies = req.query.replies.toLowerCase() === "true";
|
|
|
|
opts.instance_type = type;
|
|
|
|
opts.userUrl = userUrl;
|
|
|
|
opts.feedUrl = feedUrl;
|
|
|
|
opts.mastofeedUrl = req.url;
|
|
|
|
|
|
|
|
convertv2(opts)
|
|
|
|
.then((data) => {
|
|
|
|
doCache(res, 60 * 60);
|
|
|
|
res.status(200).send(data);
|
|
|
|
})
|
|
|
|
.catch((er) => {
|
|
|
|
res
|
|
|
|
.status(500)
|
|
|
|
.send(errorPage(500, null, { theme: opts.theme, size: opts.size }));
|
|
|
|
// TODO log the error
|
2022-08-02 23:54:55 +00:00
|
|
|
console.error("error:", er, er.stack);
|
2022-05-11 18:35:34 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2022-08-02 23:54:55 +00:00
|
|
|
// eslint-disable-next-line no-unused-vars
|
|
|
|
app.use(function (req, res, _next) {
|
|
|
|
// respond with html page
|
|
|
|
if (req.accepts("html")) {
|
|
|
|
res.status(404).send("Not found");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// respond with json
|
|
|
|
if (req.accepts("json")) {
|
|
|
|
res.status(404).json({ error: "Not found" });
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// default to plain-text. send()
|
|
|
|
res.status(404).type("txt").send("Not found");
|
|
|
|
});
|
|
|
|
|
2022-05-11 18:35:34 +00:00
|
|
|
app.listen(process.env.PORT || 8000, "127.0.0.1", function () {
|
|
|
|
console.log("Server started, listening on " + (process.env.PORT || 8000));
|
|
|
|
});
|