feat: add persistent PDF storage with session management across restarts
This commit is contained in:
@@ -16,7 +16,7 @@ RUN apk add --no-cache python3 make g++ cairo-dev pango-dev libjpeg-turbo-dev gi
|
|||||||
COPY src/ ./src/
|
COPY src/ ./src/
|
||||||
|
|
||||||
# Crée les répertoires pour les volumes
|
# Crée les répertoires pour les volumes
|
||||||
RUN mkdir -p /app/config
|
RUN mkdir -p /app/config /app/data/pdfs
|
||||||
|
|
||||||
# Crée le fichier projects.json
|
# Crée le fichier projects.json
|
||||||
COPY config/projects.json.example /app/config/projects.json
|
COPY config/projects.json.example /app/config/projects.json
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ services:
|
|||||||
# Volumes pour la configuration
|
# Volumes pour la configuration
|
||||||
volumes:
|
volumes:
|
||||||
- ./config/projects.json:/app/config/projects.json:ro # Fichier projects.json en lecture seule
|
- ./config/projects.json:/app/config/projects.json:ro # Fichier projects.json en lecture seule
|
||||||
|
- pdf-data:/app/data/pdfs #
|
||||||
|
|
||||||
# Réseau
|
# Réseau
|
||||||
networks:
|
networks:
|
||||||
|
|||||||
@@ -13,8 +13,12 @@ const logger = require('../../utils/logger');
|
|||||||
*/
|
*/
|
||||||
class PdfHandler {
|
class PdfHandler {
|
||||||
constructor() {
|
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 }
|
||||||
pdfjsLib.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.min.js');
|
pdfjsLib.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.min.js');
|
||||||
|
this.ensureStorageDir();
|
||||||
|
this.loadSessions();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,6 +80,7 @@ class PdfHandler {
|
|||||||
downloadUrl: sourceUrl,
|
downloadUrl: sourceUrl,
|
||||||
isPublic
|
isPublic
|
||||||
});
|
});
|
||||||
|
this.saveSessions();
|
||||||
|
|
||||||
logger.info(`PDF affiché (${totalPages} pages) par ${interaction.user.tag}`);
|
logger.info(`PDF affiché (${totalPages} pages) par ${interaction.user.tag}`);
|
||||||
|
|
||||||
@@ -135,9 +140,10 @@ class PdfHandler {
|
|||||||
*/
|
*/
|
||||||
async downloadPdf(url) {
|
async downloadPdf(url) {
|
||||||
const response = await axios.get(url, { responseType: 'arraybuffer' });
|
const response = await axios.get(url, { responseType: 'arraybuffer' });
|
||||||
const tmpPath = path.join(os.tmpdir(), `pdf-${Date.now()}-${Math.random().toString(36).slice(2)}.pdf`);
|
const fileName = `pdf-${Date.now()}-${Math.random().toString(36).slice(2)}.pdf`;
|
||||||
fs.writeFileSync(tmpPath, response.data);
|
const targetPath = path.join(this.storageDir, fileName);
|
||||||
return tmpPath;
|
fs.writeFileSync(targetPath, response.data);
|
||||||
|
return targetPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -222,6 +228,47 @@ class PdfHandler {
|
|||||||
return 'Visualisation PDF';
|
return 'Visualisation PDF';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Persistance des sessions pour survivre aux redémarrages
|
||||||
|
*/
|
||||||
|
ensureStorageDir() {
|
||||||
|
fs.mkdirSync(this.storageDir, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
loadSessions() {
|
||||||
|
try {
|
||||||
|
if (!fs.existsSync(this.sessionFile)) return;
|
||||||
|
const raw = fs.readFileSync(this.sessionFile, 'utf8');
|
||||||
|
const data = JSON.parse(raw);
|
||||||
|
data.forEach(entry => {
|
||||||
|
if (entry.pdfPath && fs.existsSync(entry.pdfPath)) {
|
||||||
|
this.sessions.set(entry.messageId, {
|
||||||
|
pdfPath: entry.pdfPath,
|
||||||
|
totalPages: entry.totalPages,
|
||||||
|
ownerId: entry.ownerId,
|
||||||
|
createdAt: entry.createdAt,
|
||||||
|
downloadUrl: entry.downloadUrl,
|
||||||
|
isPublic: entry.isPublic
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
logger.error('Erreur lors du chargement des sessions PDF persistées:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
saveSessions() {
|
||||||
|
try {
|
||||||
|
const data = [];
|
||||||
|
for (const [messageId, session] of this.sessions.entries()) {
|
||||||
|
data.push({ messageId, ...session });
|
||||||
|
}
|
||||||
|
fs.writeFileSync(this.sessionFile, JSON.stringify(data, null, 2), 'utf8');
|
||||||
|
} catch (e) {
|
||||||
|
logger.error('Erreur lors de la sauvegarde des sessions PDF:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = PdfHandler;
|
module.exports = PdfHandler;
|
||||||
|
|||||||
Reference in New Issue
Block a user