Initial commit with Email Import Wizard and Task Processor updates
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
import * as fs from 'fs/promises';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import { PDFDocument, degrees } from 'pdf-lib';
|
||||
import type { InboxDocument } from '../database/entities/inbox-document.entity';
|
||||
|
||||
/**
|
||||
* Wendet die virtuellen Edits (DeletedPages, Rotations) auf das Original-PDF an
|
||||
* und schreibt das Ergebnis in eine temporäre Datei. Gibt den Pfad zurück.
|
||||
* Aufrufer ist verantwortlich für das Aufräumen.
|
||||
*/
|
||||
export async function applyEditsToTemp(
|
||||
doc: InboxDocument,
|
||||
pdfPath: string,
|
||||
): Promise<string> {
|
||||
const bytes = await fs.readFile(pdfPath);
|
||||
const pdf = await PDFDocument.load(bytes, { ignoreEncryption: true });
|
||||
|
||||
const rotations = doc.Rotations ?? {};
|
||||
for (const [pageStr, rot] of Object.entries(rotations)) {
|
||||
const pageNum = Number(pageStr);
|
||||
if (!Number.isInteger(pageNum)) continue;
|
||||
const idx = pageNum - 1;
|
||||
if (idx < 0 || idx >= pdf.getPageCount()) continue;
|
||||
const normalized = ((Math.round(rot / 90) * 90) % 360 + 360) % 360;
|
||||
if (normalized === 0) continue;
|
||||
pdf.getPage(idx).setRotation(degrees(normalized));
|
||||
}
|
||||
|
||||
// Seiten in absteigender Reihenfolge entfernen, damit Indizes stabil bleiben
|
||||
const deleted = [...(doc.DeletedPages ?? [])].sort((a, b) => b - a);
|
||||
for (const pageNum of deleted) {
|
||||
const idx = pageNum - 1;
|
||||
if (idx < 0 || idx >= pdf.getPageCount()) continue;
|
||||
pdf.removePage(idx);
|
||||
}
|
||||
|
||||
const out = await pdf.save();
|
||||
|
||||
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'inbox-pp-'));
|
||||
const tmpPath = path.join(tmpDir, 'document.pdf');
|
||||
await fs.writeFile(tmpPath, out);
|
||||
return tmpPath;
|
||||
}
|
||||
|
||||
export async function cleanupTemp(filePath: string | null): Promise<void> {
|
||||
if (!filePath) return;
|
||||
try {
|
||||
await fs.unlink(filePath);
|
||||
await fs.rmdir(path.dirname(filePath)).catch(() => undefined);
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
export async function extractSectionToTemp(
|
||||
pdfPath: string,
|
||||
pageIndices: number[],
|
||||
): Promise<string> {
|
||||
const bytes = await fs.readFile(pdfPath);
|
||||
const srcPdf = await PDFDocument.load(bytes, { ignoreEncryption: true });
|
||||
const outPdf = await PDFDocument.create();
|
||||
const copied = await outPdf.copyPages(srcPdf, pageIndices);
|
||||
copied.forEach(p => outPdf.addPage(p));
|
||||
const out = await outPdf.save();
|
||||
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'inbox-section-'));
|
||||
const tmpPath = path.join(tmpDir, 'section.pdf');
|
||||
await fs.writeFile(tmpPath, out);
|
||||
return tmpPath;
|
||||
}
|
||||
Reference in New Issue
Block a user