80 lines
2.2 KiB
JavaScript
80 lines
2.2 KiB
JavaScript
import express from 'express';
|
|
import cors from 'cors';
|
|
import { tmpdir } from 'os';
|
|
import { join } from 'path';
|
|
import { promises as fs } from 'fs';
|
|
import { v4 as uuidV4 } from 'uuid';
|
|
import Epub from 'epub-gen';
|
|
|
|
const app = express();
|
|
const PORT = process.env.PORT || 4000;
|
|
const ORIGIN = process.env.CLIENT_ORIGIN || 'http://localhost:5173';
|
|
|
|
app.use(cors({ origin: ORIGIN, credentials: true }));
|
|
app.use(express.json({ limit: '10mb' }));
|
|
|
|
const sanitizeHtml = (text = '') =>
|
|
text
|
|
.replace(/&/g, '&')
|
|
.replace(/</g, '<')
|
|
.replace(/>/g, '>')
|
|
.replace(/"/g, '"')
|
|
.replace(/'/g, ''')
|
|
.replace(/\n/g, '<br/>');
|
|
|
|
app.post('/generate-epub', async (req, res) => {
|
|
const { text, meta, cover } = req.body || {};
|
|
if (!text || !text.trim()) {
|
|
return res.status(400).json({ message: 'text is required' });
|
|
}
|
|
|
|
const title = meta?.title || 'imgPub OCR Export';
|
|
const author = meta?.author || 'imgPub';
|
|
const filename = meta?.filename || `imgpub${Date.now()}.epub`;
|
|
|
|
const content = [
|
|
{
|
|
title,
|
|
data: `<div>${sanitizeHtml(text)}</div>`,
|
|
},
|
|
];
|
|
|
|
const outputPath = join(tmpdir(), `imgpub-${uuidV4()}.epub`);
|
|
let coverPath;
|
|
|
|
try {
|
|
if (cover?.data) {
|
|
const coverBuffer = Buffer.from(cover.data, 'base64');
|
|
const coverExtension =
|
|
cover?.mimeType?.split('/').pop() || cover?.filename?.split('.').pop() || 'png';
|
|
coverPath = join(tmpdir(), `imgpub-cover-${uuidV4()}.${coverExtension}`);
|
|
await fs.writeFile(coverPath, coverBuffer);
|
|
}
|
|
|
|
const epubOptions = { title, author, content };
|
|
if (coverPath) {
|
|
epubOptions.cover = coverPath;
|
|
}
|
|
|
|
const epub = new Epub(epubOptions, outputPath);
|
|
await epub.promise;
|
|
const buffer = await fs.readFile(outputPath);
|
|
await fs.unlink(outputPath).catch(() => {});
|
|
if (coverPath) {
|
|
await fs.unlink(coverPath).catch(() => {});
|
|
}
|
|
res.json({ filename, data: buffer.toString('base64') });
|
|
} catch (error) {
|
|
console.error('EPUB generation failed:', error);
|
|
res.status(500).json({ message: 'EPUB generation failed' });
|
|
}
|
|
});
|
|
|
|
app.get('/', (_, res) => {
|
|
res.json({ status: 'ok' });
|
|
});
|
|
|
|
app.listen(PORT, () => {
|
|
console.log(`imgPub EPUB server listening on port ${PORT}`);
|
|
});
|