2023-06-18 21:20:52 +00:00
|
|
|
import express from "express";
|
2023-06-19 10:05:59 +00:00
|
|
|
import { Readability, isProbablyReaderable } from "@mozilla/readability";
|
2023-06-18 21:20:52 +00:00
|
|
|
import got from "got";
|
2023-06-18 22:44:17 +00:00
|
|
|
import path from "path";
|
|
|
|
import { fileURLToPath } from "url";
|
2023-06-20 07:32:07 +00:00
|
|
|
import fetch from "node-fetch";
|
2023-06-19 12:11:22 +00:00
|
|
|
import "dotenv/config";
|
2023-06-20 09:48:11 +00:00
|
|
|
import { parseHTML } from "linkedom";
|
2023-06-18 21:20:52 +00:00
|
|
|
|
|
|
|
const app = express();
|
2023-06-19 10:05:59 +00:00
|
|
|
const port = 8888;
|
2023-06-18 21:20:52 +00:00
|
|
|
|
2023-06-18 22:46:43 +00:00
|
|
|
// @ts-ignore
|
2023-06-18 22:44:17 +00:00
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
|
|
|
|
|
|
const __dirname = path.dirname(__filename);
|
|
|
|
|
2023-06-19 11:58:21 +00:00
|
|
|
app.get("/", async (req, res) => {
|
|
|
|
const searchEngine = "https://api.search.brave.com/res/v1/web/search";
|
2023-06-19 10:05:59 +00:00
|
|
|
let query = req.query.q as string;
|
2023-06-18 21:20:52 +00:00
|
|
|
|
2023-06-19 10:05:59 +00:00
|
|
|
if (!query) {
|
2023-06-18 22:44:17 +00:00
|
|
|
res.sendFile(path.join(__dirname + "/dist/index.html"));
|
2023-06-20 07:32:07 +00:00
|
|
|
return;
|
2023-06-18 21:20:52 +00:00
|
|
|
}
|
|
|
|
|
2023-06-20 07:32:07 +00:00
|
|
|
const key = process.env.CYCLIC_BRAVE_KEY;
|
2023-06-19 12:01:17 +00:00
|
|
|
|
|
|
|
if (!key) {
|
|
|
|
throw new Error("No brave key found");
|
|
|
|
}
|
|
|
|
|
2023-06-19 11:58:21 +00:00
|
|
|
fetch(`${searchEngine}?q=${query}`, {
|
2023-06-19 10:40:07 +00:00
|
|
|
headers: {
|
2023-06-20 07:32:07 +00:00
|
|
|
Accept: "*/*",
|
2023-06-19 11:58:21 +00:00
|
|
|
"Accept-Encoding": "gzip, deflate, br",
|
2023-06-19 12:01:17 +00:00
|
|
|
"X-Subscription-Token": key,
|
2023-06-19 11:58:21 +00:00
|
|
|
},
|
|
|
|
})
|
|
|
|
.then((page) => {
|
2023-06-20 07:32:07 +00:00
|
|
|
page.json().then((response) => {
|
|
|
|
const results: any[] = [];
|
|
|
|
const url = process.env.DEV_MODE
|
|
|
|
? "http://localhost:8888/blazed"
|
|
|
|
: "https://blaze.cyclic.app/blazed";
|
2023-06-19 12:01:17 +00:00
|
|
|
// @ts-ignore
|
2023-06-20 07:32:07 +00:00
|
|
|
response.web.results.forEach((result) => {
|
2023-06-19 11:58:21 +00:00
|
|
|
results.push(`
|
2023-06-20 07:45:18 +00:00
|
|
|
<article>
|
2023-06-20 07:32:07 +00:00
|
|
|
<a href="${url}?url=${result.url}">
|
2023-06-19 11:58:21 +00:00
|
|
|
<h2>${result.title}</h2>
|
2023-06-20 07:32:07 +00:00
|
|
|
</a>
|
2023-06-19 13:27:14 +00:00
|
|
|
<span>${result.meta_url.hostname}</span>
|
2023-06-19 11:58:21 +00:00
|
|
|
<p>${result.description}</p>
|
2023-06-20 07:45:18 +00:00
|
|
|
</article>
|
2023-06-19 12:11:22 +00:00
|
|
|
<hr />
|
2023-06-19 11:58:21 +00:00
|
|
|
`);
|
2023-06-20 07:32:07 +00:00
|
|
|
});
|
2023-06-19 12:11:22 +00:00
|
|
|
res.send(`<html>
|
|
|
|
<head>
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
2023-06-20 07:32:07 +00:00
|
|
|
<title>Blaze - ${query}</title>
|
2023-06-19 13:27:14 +00:00
|
|
|
<style>
|
2023-06-20 07:32:07 +00:00
|
|
|
body {font-family:sans-serif}
|
2023-06-19 13:27:14 +00:00
|
|
|
h2 {margin-bottom:0}
|
2023-06-20 07:32:07 +00:00
|
|
|
span {font-size:.9rem}
|
2023-06-19 13:27:14 +00:00
|
|
|
</style>
|
2023-06-19 12:11:22 +00:00
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
${results.join("")}
|
|
|
|
</body>
|
|
|
|
</html>`);
|
2023-06-20 07:32:07 +00:00
|
|
|
});
|
2023-06-18 21:20:52 +00:00
|
|
|
})
|
|
|
|
.catch((err) => {
|
|
|
|
console.log(err);
|
|
|
|
});
|
|
|
|
});
|
2023-06-18 22:52:20 +00:00
|
|
|
|
2023-06-20 09:48:11 +00:00
|
|
|
app.get("/blazed", async (req, res) => {
|
2023-06-20 07:32:07 +00:00
|
|
|
const pageToBlaze = req.query.url as string;
|
2023-06-20 09:48:11 +00:00
|
|
|
console.time("blaze");
|
2023-06-20 07:32:07 +00:00
|
|
|
|
2023-06-20 09:48:11 +00:00
|
|
|
try {
|
|
|
|
const response = await got(pageToBlaze);
|
|
|
|
const { document } = parseHTML(response.body);
|
2023-06-20 07:32:07 +00:00
|
|
|
|
2023-06-20 09:48:11 +00:00
|
|
|
if (!isProbablyReaderable(document)) {
|
|
|
|
return res.sendFile(path.join(__dirname, "/dist/not_blazed.html"));
|
|
|
|
}
|
2023-06-20 07:32:07 +00:00
|
|
|
|
2023-06-20 09:48:11 +00:00
|
|
|
const reader = new Readability(document);
|
|
|
|
const article = reader.parse();
|
2023-06-20 07:32:07 +00:00
|
|
|
|
2023-06-20 09:48:11 +00:00
|
|
|
if (!article) {
|
|
|
|
return res.send("Something went wrong");
|
|
|
|
}
|
2023-06-20 07:32:07 +00:00
|
|
|
|
2023-06-20 09:48:11 +00:00
|
|
|
res.send(article.content);
|
|
|
|
} catch (err) {
|
|
|
|
console.log(err);
|
|
|
|
} finally {
|
|
|
|
console.timeEnd("blaze");
|
|
|
|
}
|
2023-06-20 07:32:07 +00:00
|
|
|
});
|
2023-06-19 10:05:59 +00:00
|
|
|
|
2023-06-19 12:55:28 +00:00
|
|
|
app.get("/info", (_, res) => {
|
|
|
|
res.sendFile(path.join(__dirname + "/dist/info.html"));
|
2023-06-20 07:32:07 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
app.get("/ooops", (_, res) => {
|
|
|
|
res.sendFile(path.join(__dirname + "/dist/info_not_blazed.html"));
|
|
|
|
});
|
2023-06-19 12:55:28 +00:00
|
|
|
|
2023-06-20 07:41:34 +00:00
|
|
|
app.get("/favicon.svg", (_, res) => {
|
|
|
|
res.sendFile(path.join(__dirname + "/favicon.svg"));
|
|
|
|
});
|
|
|
|
|
2023-06-18 22:52:20 +00:00
|
|
|
app.listen(port, () => {
|
|
|
|
console.log(`Got request`);
|
|
|
|
});
|