feat: add page image caching to improve PDF navigation performance

This commit is contained in:
ɧσℓσ
2025-12-10 19:37:43 +01:00
parent b5cd54e33d
commit d3457fcdbc

View File

@@ -15,7 +15,7 @@ class PdfHandler {
constructor() {
this.storageDir = process.env.PDF_STORAGE_DIR || path.join(process.cwd(), 'data', 'pdfs');
this.sessionFile = path.join(this.storageDir, 'sessions.json');
this.sessions = new Map(); // messageId -> { pdfPath, totalPages, ownerId, createdAt, downloadUrl, isPublic }
this.sessions = new Map(); // messageId -> { pdfPath, totalPages, ownerId, createdAt, downloadUrl, isPublic, imagePaths }
pdfjsLib.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.min.js');
this.ensureStorageDir();
this.loadSessions();
@@ -60,7 +60,9 @@ class PdfHandler {
return;
}
const pageBuffer = await this.renderPage(pdf, 1);
const imagePaths = await this.renderAllPages(pdf, totalPages);
const pageBuffer = fs.readFileSync(imagePaths[0]);
const title = this.getPdfTitle(sourceUrl);
const messageOptions = this.buildMessageOptions(pageBuffer, 1, totalPages, interaction.user.id, sourceUrl, title);
@@ -78,7 +80,8 @@ class PdfHandler {
ownerId: interaction.user.id,
createdAt: Date.now(),
downloadUrl: sourceUrl,
isPublic
isPublic,
imagePaths
});
this.saveSessions();
@@ -123,8 +126,18 @@ class PdfHandler {
}
try {
const { pdf } = await this.loadPdf(session.pdfPath);
const pageBuffer = await this.renderPage(pdf, clampedPage);
let pageBuffer;
if (session.imagePaths?.[clampedPage - 1] && fs.existsSync(session.imagePaths[clampedPage - 1])) {
pageBuffer = fs.readFileSync(session.imagePaths[clampedPage - 1]);
} else {
const { pdf } = await this.loadPdf(session.pdfPath);
const buffer = await this.renderPage(pdf, clampedPage);
const filePath = this.writeImageFile(buffer, clampedPage);
session.imagePaths = session.imagePaths || [];
session.imagePaths[clampedPage - 1] = filePath;
this.saveSessions();
pageBuffer = buffer;
}
const title = this.getPdfTitle(session.downloadUrl);
const messageOptions = this.buildMessageOptions(pageBuffer, clampedPage, totalPages, ownerId, session.downloadUrl, title);
@@ -175,6 +188,29 @@ class PdfHandler {
return sharp(buffer).png({ quality: 90 }).toBuffer();
}
/**
* Rend toutes les pages et retourne la liste des chemins de fichiers
*/
async renderAllPages(pdf, totalPages) {
const paths = [];
for (let i = 1; i <= totalPages; i++) {
const buffer = await this.renderPage(pdf, i);
const filePath = this.writeImageFile(buffer, i);
paths.push(filePath);
}
return paths;
}
/**
* Écrit une image en cache et retourne le chemin
*/
writeImageFile(buffer, pageIndex) {
const fileName = `page-${pageIndex}-${Date.now()}-${Math.random().toString(36).slice(2)}.png`;
const targetPath = path.join(this.storageDir, fileName);
fs.writeFileSync(targetPath, buffer);
return targetPath;
}
/**
* Construit le message Discord avec image + boutons
*/