import express, { Request, Response, NextFunction } from "express"; import fileUpload, { UploadedFile } from "express-fileupload"; import path from "path"; import fs from "fs"; import { JobManager, runGhostscript, createJobId } from "./jobs"; import type { context, options } from "./jobs"; const app = express() const jobManager = new JobManager() app.set('view engine', 'ejs'); app.use(express.static(path.join(__dirname, 'static'))); app.use(fileUpload()) app.get('/', (req: Request, res: Response) => { res.render('index') }) app.post('/new_job', (req: Request, res: Response) => { try { const jobId = createJobId(); const file = req.files?.file as UploadedFile; // Ensure file was uploaded and is of correct type if (!file) { return res.status(400).render("upload_err", {code: 400}) } if (file.mimetype !== 'application/pdf') { return res.status(415).render("upload_err", {code: 415}) } // Write file to disk const filePath = `./uploads/${jobId}/in.pdf`; fs.mkdirSync(`./uploads/${jobId}`, { recursive: true }); file.mv(filePath, (err) => { if (err) { throw err; } const quality: string = req.body.quality; const opts: options = { quality }; const ctx: context = { jobManager, jobId, filePath }; runGhostscript(ctx, opts); res.render('processing', { job_id: jobId }); }); } catch (error) { if (error) console.error(error); res.status(500).send('Internal Server Error'); } }); app.get('/job_state', (req: Request, res: Response) => { const job_id: string = req.query.job_id as string; if (!job_id) { res.status(400).send("Missing job ID") } const jobStatus = jobManager.get_job_status(job_id); // If job doesn't exist, return 404 if (Object.keys(jobStatus).length === 0) { res.status(404).send('Job not found'); return; } // Send job status as JSON response res.json(jobStatus); }) app.get('/download', (req: Request, res: Response) => { try{ const jobId = req.query.job_id as string; if (!jobId) { res.status(400).send("Missing job ID") } const jobStatus = jobManager.get_job_status(jobId); if (Object.keys(jobStatus).length === 0) { res.status(404).send('Job not found, files expire after 10 minutes'); return; } const filePath = path.join('.', 'uploads', `${jobId}`, `out.pdf`); console.log("Download Request: ", filePath) if (fs.existsSync(filePath)) { // Set the appropriate headers for the PDF file res.setHeader('Content-Type', 'application/pdf'); res.setHeader('Content-Disposition', `attachment; filename=SpeedyF-output.pdf`); // Create a read stream to the PDF file and pipe it to the response const stream = fs.createReadStream(filePath); stream.pipe(res); } else { // If the file doesn't exist, return a 404 Not Found response res.status(404).send('File not found'); } } catch (error) { // If an error occurs, return a 500 Internal Server Error response console.error('An error occurred:', error); res.status(500).send('Internal Server Error'); } }); const port = process.env.PORT || 3000; app.listen(port, () => { console.log(`Server listening on port ${port}`) })