You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

62 lines
1.7 KiB

/**
* Load full QQ mailbox PDF text for sample mail body (一字不落).
*/
import { execFile } from "child_process";
import { promisify } from "util";
import path from "path";
import fs from "fs/promises";
const execFileAsync = promisify(execFile);
async function listPdfs(root: string): Promise<string[]> {
const out: string[] = [];
const stack = [root];
while (stack.length) {
const cur = stack.pop()!;
let entries;
try {
entries = await fs.readdir(cur, { withFileTypes: true });
} catch {
continue;
}
for (const e of entries) {
const full = path.join(cur, e.name);
if (e.isDirectory()) stack.push(full);
else if (/\.pdf$/i.test(e.name) && /邮箱/i.test(e.name)) out.push(full);
}
}
return out;
}
/** Prefer *邮箱.pdf under sample dir; return extracted text or null */
export async function loadMailboxPdfBody(
sampleDirAbs: string,
): Promise<string | null> {
const pdfs = await listPdfs(sampleDirAbs);
if (!pdfs.length) return null;
// Prefer QQ邮箱 / N邮箱 over other PDFs
pdfs.sort((a, b) => {
const score = (p: string) => {
const n = path.basename(p);
if (/^QQ/i.test(n)) return 0;
if (/^\d邮箱/i.test(n)) return 1;
return 2;
};
return score(a) - score(b);
});
const target = pdfs[0];
try {
const script = path.join(process.cwd(), "scripts", "extract-pdf-text.py");
const { stdout } = await execFileAsync(
"python",
[script, target],
{ maxBuffer: 12_000_000, encoding: "utf8", windowsHide: true },
);
const t = (stdout || "").replace(/\r\n/g, "\n").trim();
return t.length > 20 ? t : null;
} catch (err) {
console.warn("loadMailboxPdfBody failed", target, err);
return null;
}
}