Merge pull request #28 from TxtDot/stack-overflow-parser
feat: stackoverflow parser for questions page
This commit is contained in:
commit
d3186be26d
@ -15,6 +15,7 @@ import {
|
|||||||
LocalResourceError,
|
LocalResourceError,
|
||||||
NotHtmlMimetypeError,
|
NotHtmlMimetypeError,
|
||||||
} from "../errors/main";
|
} from "../errors/main";
|
||||||
|
import stackoverflow from "./stackoverflow/main";
|
||||||
|
|
||||||
export default async function handlePage(
|
export default async function handlePage(
|
||||||
url: string, // remote URL
|
url: string, // remote URL
|
||||||
@ -60,11 +61,13 @@ type EngineFunction = (window: DOMWindow) => Promise<IHandlerOutput>;
|
|||||||
export const engines: Engines = {
|
export const engines: Engines = {
|
||||||
readability,
|
readability,
|
||||||
google,
|
google,
|
||||||
|
stackoverflow,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const engineList: string[] = Object.keys(engines);
|
export const engineList: string[] = Object.keys(engines);
|
||||||
|
|
||||||
const fallback: Engines = {
|
const fallback: Engines = {
|
||||||
|
"stackoverflow.com": engines.stackoverflow,
|
||||||
"www.google.com": engines.google,
|
"www.google.com": engines.google,
|
||||||
"*": engines.readability,
|
"*": engines.readability,
|
||||||
};
|
};
|
||||||
|
31
src/handlers/stackoverflow/main.ts
Normal file
31
src/handlers/stackoverflow/main.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { IHandlerOutput } from "../handler.interface";
|
||||||
|
import { DOMWindow } from "jsdom";
|
||||||
|
import { EngineParseError } from "../../errors/main";
|
||||||
|
import qPostsHandler from "./questions-posts";
|
||||||
|
|
||||||
|
export default async function stackoverflow(
|
||||||
|
window: DOMWindow
|
||||||
|
): Promise<IHandlerOutput> {
|
||||||
|
const url = new URL(window.location.href);
|
||||||
|
|
||||||
|
const path = url.pathname.split("/").filter((p) => p !== "");
|
||||||
|
|
||||||
|
let result: IHandlerOutput = {
|
||||||
|
content: "",
|
||||||
|
textContent: "",
|
||||||
|
title: "",
|
||||||
|
lang: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (path[0] === "questions") {
|
||||||
|
if (path.length === 3) {
|
||||||
|
result = await qPostsHandler(window);
|
||||||
|
} else if (path.length === 1) {
|
||||||
|
result.content = "questions";
|
||||||
|
} else {
|
||||||
|
throw new EngineParseError("Invalid URL [stackoverflow]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
9
src/handlers/stackoverflow/post-parser.ts
Normal file
9
src/handlers/stackoverflow/post-parser.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
export default function postParser(el: Element | null): string {
|
||||||
|
if (!el) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
const body = el.querySelector(".js-post-body")?.innerHTML || "";
|
||||||
|
const voteCount = el.querySelector(".js-vote-count")?.textContent || "";
|
||||||
|
|
||||||
|
return `<h3>${voteCount} votes</h3>${body}`;
|
||||||
|
}
|
26
src/handlers/stackoverflow/questions-posts.ts
Normal file
26
src/handlers/stackoverflow/questions-posts.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { DOMWindow } from "jsdom";
|
||||||
|
import { IHandlerOutput } from "../handler.interface";
|
||||||
|
import postParser from "./post-parser";
|
||||||
|
|
||||||
|
export default async function qPostsHandler(
|
||||||
|
window: DOMWindow
|
||||||
|
): Promise<IHandlerOutput> {
|
||||||
|
const questionEl = window.document.getElementById("question");
|
||||||
|
const question = postParser(questionEl);
|
||||||
|
|
||||||
|
const title =
|
||||||
|
window.document.querySelector(".question-hyperlink")?.innerHTML || "";
|
||||||
|
|
||||||
|
const allAnswers = [...window.document.querySelectorAll(".answer")];
|
||||||
|
|
||||||
|
const answers = allAnswers.map((a) => postParser(a));
|
||||||
|
|
||||||
|
return {
|
||||||
|
content: `${question}<hr>${answers.length} answers <hr>${answers.join(
|
||||||
|
"<hr>"
|
||||||
|
)}`,
|
||||||
|
textContent: "question",
|
||||||
|
title,
|
||||||
|
lang: "en",
|
||||||
|
};
|
||||||
|
}
|
@ -28,11 +28,14 @@ table {
|
|||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
img, picture, video {
|
img,
|
||||||
|
picture,
|
||||||
|
video {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame, iframe {
|
frame,
|
||||||
|
iframe {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
<div class="title">
|
<div class="title">
|
||||||
<%= parsed.title %>
|
<%= parsed.title %>
|
||||||
</div>
|
</div>
|
||||||
|
<hr>
|
||||||
<%- parsed.content %>
|
<%- parsed.content %>
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user