UNPKG

rsshub

Version:
200 lines (199 loc) 5.49 kB
import { t as rofetch } from "./ofetch-eUBdfMpp.mjs"; import { n as generateHeaders } from "./header-generator-DACPoxdp.mjs"; import { createHash } from "node:crypto"; import { load } from "cheerio"; //#region lib/routes/ichunqiu/jsl.ts const toPrimitive = (v) => Array.isArray(v) ? v.join(",") : typeof v === "object" ? "[object Object]" : v; const binaryPrecedence = { "|": 1, "^": 2, "&": 3, "<<": 4, ">>": 4, "+": 5, "-": 5, "*": 6, "/": 6, "%": 6 }; const evaluateJsl = (source) => { let pos = 0; const skipSpaces = () => { while (source[pos] === " ") pos++; }; const expect = (char) => { skipSpaces(); if (source[pos++] !== char) throw new Error(`Expected ${char} at ${pos - 1} in JSL expression`); }; const primary = () => { skipSpaces(); const char = source[pos]; if (char === "(") { pos++; const value = expression(0); expect(")"); return value; } if (char === "'") { const end = source.indexOf("'", pos + 1); const value = source.slice(pos + 1, end); pos = end + 1; return value; } if (char === "[") { pos++; skipSpaces(); if (source[pos] === "]") { pos++; return []; } const value = expression(0); expect("]"); return [value]; } if (char === "{") { pos++; expect("}"); return {}; } if (source.startsWith("true", pos)) { pos += 4; return true; } if (source.startsWith("false", pos)) { pos += 5; return false; } const digits = /^\d+/.exec(source.slice(pos)); if (digits) { pos += digits[0].length; return Number(digits[0]); } throw new Error(`Unexpected ${JSON.stringify(char)} at ${pos} in JSL expression`); }; const unary = () => { skipSpaces(); const op = source[pos]; if (op !== void 0 && "-+~!".includes(op)) { pos++; const value = unary(); switch (op) { case "-": return -Number(toPrimitive(value)); case "+": return Number(toPrimitive(value)); case "~": return ~Number(toPrimitive(value)); default: return !value; } } return primary(); }; const readBinaryOperator = () => { skipSpaces(); const two = source.slice(pos, pos + 2); if (two === "<<" || two === ">>") return two; const one = source[pos]; return one && binaryPrecedence[one] === void 0 ? void 0 : one; }; const applyBinary = (op, left, right) => { const a = toPrimitive(left); const b = toPrimitive(right); if (op === "+") return typeof a === "string" || typeof b === "string" ? `${a}${b}` : Number(a) + Number(b); const x = Number(a); const y = Number(b); switch (op) { case "-": return x - y; case "*": return x * y; case "/": return x / y; case "%": return x % y; case "<<": return x << y; case ">>": return x >> y; case "&": return x & y; case "^": return x ^ y; default: return x | y; } }; const expression = (minPrecedence) => { let left = unary(); let op = readBinaryOperator(); while (op && binaryPrecedence[op] >= minPrecedence) { pos += op.length; left = applyBinary(op, left, expression(binaryPrecedence[op] + 1)); op = readBinaryOperator(); } return left; }; const result = expression(0); skipSpaces(); if (pos !== source.length) throw new Error(`Unexpected trailing input at ${pos} in JSL expression`); return String(toPrimitive(result)); }; //#endregion //#region lib/routes/ichunqiu/index.ts const route = { path: "/", categories: ["programming"], example: "/ichunqiu", features: { antiCrawler: true }, name: "资讯", maintainers: ["8430177"], handler }; const solveJsl = ({ bts, chars, ct, ha }) => { for (const a of chars) for (const b of chars) { const answer = bts[0] + a + b + bts[1]; if (createHash(ha).update(answer).digest("hex") === ct) return answer; } throw new Error("Failed to solve __jsl_clearance_s"); }; async function handler() { const baseSite = "https://bbs.ichunqiu.com/"; const link = `${baseSite}portal.php`; const cookies = /* @__PURE__ */ new Map(); const headers = generateHeaders(); const fetchPage = async () => { const response = await rofetch.raw(link, { headers: { ...headers, cookie: [...cookies].map(([name, value]) => `${name}=${value}`).join("; ") }, ignoreResponseError: true, responseType: "text" }); for (const cookie of response.headers.getSetCookie()) { const [name, value] = cookie.split(";", 1)[0].split("=", 2); cookies.set(name, value); } return response._data; }; let body = await fetchPage(); for (let round = 0; round < 5 && !body.includes("class=\"module"); round++) { const assignment = body.match(/document\.cookie=(.+?);location\.href/s); const challenge = body.match(/go\((\{.+?\})\)/s); if (assignment) { const [name, value] = evaluateJsl(assignment[1]).split(";", 1)[0].split("=", 2); cookies.set(name, value); } else if (challenge) { const puzzle = JSON.parse(challenge[1]); cookies.set(puzzle.tn, solveJsl(puzzle)); } else throw new Error("Unrecognized response"); body = await fetchPage(); } const $ = load(body); return { title: "i春秋学院 ~ 资讯", link: baseSite, description: "i春秋学院 ~ 资讯", item: $(".module dl").toArray().map((item) => { const $item = $(item); const a = $item.find("dt a[title]"); const title = a.attr("title"); if (!title) return; return { title, link: new URL(a.attr("href"), baseSite).href, description: $item.find("dd:not(.m)").text().trim() }; }).filter((item) => item !== void 0) }; } //#endregion export { route };