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
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;
|
|
}
|
|
}
|