From e15fb2a07be16e1a33c75f615456a4f2bc89845b Mon Sep 17 00:00:00 2001 From: Artemy Date: Sun, 13 Aug 2023 21:39:23 +0300 Subject: [PATCH] feat: handlers --- package-lock.json | 4 ++-- package.json | 3 ++- src/app.ts | 23 +++++++++++++---------- src/handlers/handler.interface.ts | 6 ++++++ src/handlers/main.ts | 16 ++++++++++++++++ src/handlers/readability.ts | 22 ++++++++++++++++++++++ 6 files changed, 61 insertions(+), 13 deletions(-) create mode 100644 src/handlers/handler.interface.ts create mode 100644 src/handlers/main.ts create mode 100644 src/handlers/readability.ts diff --git a/package-lock.json b/package-lock.json index 81f6f87..0f1517c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "dottxt", + "name": "txtdot", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "dottxt", + "name": "txtdot", "version": "1.0.0", "license": "ISC", "dependencies": { diff --git a/package.json b/package.json index 812a179..ee6e0a8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { - "name": "dottxt", + "name": "txtdot", "version": "1.0.0", + "private": true, "description": "", "main": "dist/app.js", "dependencies": { diff --git a/src/app.ts b/src/app.ts index a58cb28..4f29887 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,10 +1,9 @@ import { IConfigService } from "./config/config.interface"; import { ConfigService } from "./config/config.service"; import express from "express"; -import axios from "axios"; -import { JSDOM } from "jsdom"; -import { Readability } from "@mozilla/readability"; import NodeCache from "node-cache"; +import { readability } from "./handlers/readability"; +import minify from "./handlers/main"; class App { config: IConfigService; @@ -37,12 +36,8 @@ class App { const url = (req.query.url || "/nothing") as string; const type = (req.query.type || "html") as string; - axios - .get(url) - .then((response) => { - const dom = new JSDOM(response.data, { url: url }); - const reader = new Readability(dom.window.document); - const parsed = reader.parse(); + minify(url) + .then((parsed) => { const content = type === "html" ? parsed?.content : parsed?.textContent; @@ -50,10 +45,18 @@ class App { res.send(content); }) .catch((err) => { - res.status(500).send(err); + res.status(500).send({ error: err.message }); }); }); + app.get("/readability", async (req, res) => { + const url = (req.query.url || "/nothing") as string; + const parsed = await readability(url); + + this.cache.set(req.originalUrl || req.url, parsed); + res.send(parsed); + }); + app.listen(this.config.get("PORT"), () => { console.log(`Listening on port ${this.config.get("PORT")}`); }); diff --git a/src/handlers/handler.interface.ts b/src/handlers/handler.interface.ts new file mode 100644 index 0000000..26c2053 --- /dev/null +++ b/src/handlers/handler.interface.ts @@ -0,0 +1,6 @@ +export interface IHandlerOutput { + content: string; + textContent: string; + title: string; + lang: string; +} diff --git a/src/handlers/main.ts b/src/handlers/main.ts new file mode 100644 index 0000000..2757e2f --- /dev/null +++ b/src/handlers/main.ts @@ -0,0 +1,16 @@ +import { IHandlerOutput } from "./handler.interface"; +import { readability } from "./readability"; + +export default function minify(url: string): Promise { + const host = new URL(url).hostname; + + return fallback[host]?.(url) || fallback["*"](url); +} + +const fallback: Fallback = { + "*": readability, +}; + +interface Fallback { + [host: string]: (url: string) => Promise; +} diff --git a/src/handlers/readability.ts b/src/handlers/readability.ts new file mode 100644 index 0000000..0a6f39a --- /dev/null +++ b/src/handlers/readability.ts @@ -0,0 +1,22 @@ +import { Readability } from "@mozilla/readability"; +import axios from "axios"; +import { JSDOM } from "jsdom"; +import { IHandlerOutput } from "./handler.interface"; + +export async function readability(url: string): Promise { + const response = await axios.get(url); + const dom = new JSDOM(response.data, { url: url }); + const reader = new Readability(dom.window.document); + const parsed = reader.parse(); + + if (!parsed) { + throw new Error("Failed to parse [readability]"); + } + + return { + content: parsed.content, + textContent: parsed.textContent, + title: parsed.title, + lang: parsed.lang, + }; +}