srivatsavdamaraju commited on
Commit
b8b8b00
Β·
verified Β·
1 Parent(s): 393089e

Create server.js

Browse files
Files changed (1) hide show
  1. server.js +191 -0
server.js ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const express = require("express");
2
+ const cors = require("cors");
3
+ const puppeteer = require("puppeteer");
4
+
5
+ const app = express();
6
+ const PORT = process.env.PORT || 7860; // Hugging Face uses port 7860
7
+
8
+ // Middleware
9
+ app.use(cors());
10
+ app.use(express.json({ limit: "5mb" }));
11
+
12
+ // Root endpoint - Health check
13
+ app.get("/", (_req, res) => {
14
+ res.json({
15
+ status: "ok",
16
+ message: "HTML to PDF API is running",
17
+ version: "1.0.0",
18
+ endpoints: {
19
+ health: "GET / or GET /health",
20
+ convert: "POST /api/html-to-pdf"
21
+ },
22
+ usage: {
23
+ method: "POST",
24
+ url: "/api/html-to-pdf",
25
+ body: {
26
+ html_code: "Your HTML content here",
27
+ pdf_options: {
28
+ format: "A4",
29
+ printBackground: true,
30
+ margin: {
31
+ top: "10mm",
32
+ right: "10mm",
33
+ bottom: "10mm",
34
+ left: "10mm"
35
+ }
36
+ }
37
+ }
38
+ }
39
+ });
40
+ });
41
+
42
+ // Health check endpoint
43
+ app.get("/health", (_req, res) => {
44
+ res.json({
45
+ status: "healthy",
46
+ timestamp: new Date().toISOString(),
47
+ uptime: process.uptime()
48
+ });
49
+ });
50
+
51
+ // Main PDF conversion endpoint
52
+ app.post("/api/html-to-pdf", async (req, res) => {
53
+ let browser;
54
+ const startTime = Date.now();
55
+
56
+ try {
57
+ const { html_code: htmlContent, pdf_options: pdfOptions } = req.body || {};
58
+
59
+ // Validate input
60
+ if (!htmlContent || !htmlContent.trim()) {
61
+ return res.status(400).json({
62
+ error: "html_code is required",
63
+ success: false
64
+ });
65
+ }
66
+
67
+ console.log(`[${new Date().toISOString()}] Starting PDF generation...`);
68
+
69
+ // Launch browser - using Puppeteer's bundled Chromium
70
+ browser = await puppeteer.launch({
71
+ args: [
72
+ "--no-sandbox",
73
+ "--disable-setuid-sandbox",
74
+ "--disable-dev-shm-usage",
75
+ "--disable-gpu",
76
+ "--disable-software-rasterizer",
77
+ "--disable-extensions",
78
+ "--disable-background-networking",
79
+ "--disable-default-apps",
80
+ "--disable-sync",
81
+ "--metrics-recording-only",
82
+ "--mute-audio",
83
+ "--no-first-run"
84
+ ],
85
+ headless: true
86
+ // Remove executablePath - let Puppeteer use its bundled Chromium
87
+ });
88
+
89
+ const page = await browser.newPage();
90
+
91
+ // Set content
92
+ await page.setContent(
93
+ `<!DOCTYPE html>
94
+ <html>
95
+ <head>
96
+ <meta charset="utf-8" />
97
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
98
+ </head>
99
+ <body>
100
+ ${htmlContent}
101
+ </body>
102
+ </html>`,
103
+ {
104
+ waitUntil: "networkidle0",
105
+ timeout: 30000
106
+ }
107
+ );
108
+
109
+ // Generate PDF with default options merged with user options
110
+ const defaultPdfOptions = {
111
+ format: "A4",
112
+ printBackground: true,
113
+ margin: {
114
+ top: "10mm",
115
+ right: "10mm",
116
+ bottom: "10mm",
117
+ left: "10mm"
118
+ }
119
+ };
120
+
121
+ const pdfBuffer = await page.pdf({
122
+ ...defaultPdfOptions,
123
+ ...(pdfOptions || {})
124
+ });
125
+
126
+ await browser.close();
127
+ browser = null;
128
+
129
+ const processingTime = Date.now() - startTime;
130
+ console.log(`[${new Date().toISOString()}] PDF generated successfully in ${processingTime}ms`);
131
+
132
+ res.json({
133
+ pdf_base64: pdfBuffer.toString("base64"),
134
+ success: true,
135
+ processing_time_ms: processingTime,
136
+ pdf_size_bytes: pdfBuffer.length
137
+ });
138
+
139
+ } catch (err) {
140
+ console.error(`[${new Date().toISOString()}] PDF Generation Error:`, err);
141
+
142
+ if (browser) {
143
+ try {
144
+ await browser.close();
145
+ } catch (closeErr) {
146
+ console.error("Browser close error:", closeErr);
147
+ }
148
+ }
149
+
150
+ res.status(500).json({
151
+ error: "Failed to generate PDF",
152
+ details: err.message,
153
+ success: false
154
+ });
155
+ }
156
+ });
157
+
158
+ // 404 handler
159
+ app.use((_req, res) => {
160
+ res.status(404).json({
161
+ error: "Endpoint not found",
162
+ available_endpoints: [
163
+ "GET /",
164
+ "GET /health",
165
+ "POST /api/html-to-pdf"
166
+ ]
167
+ });
168
+ });
169
+
170
+ // Start server
171
+ app.listen(PORT, "0.0.0.0", () => {
172
+ console.log(`
173
+ ╔════════════════════════════════════════╗
174
+ β•‘ HTML to PDF API Server β•‘
175
+ β•‘ Status: Running βœ… β•‘
176
+ β•‘ Port: ${PORT} β•‘
177
+ β•‘ URL: http://0.0.0.0:${PORT} β•‘
178
+ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
179
+ `);
180
+ });
181
+
182
+ // Graceful shutdown
183
+ process.on('SIGTERM', () => {
184
+ console.log('SIGTERM signal received: closing HTTP server');
185
+ process.exit(0);
186
+ });
187
+
188
+ process.on('SIGINT', () => {
189
+ console.log('SIGINT signal received: closing HTTP server');
190
+ process.exit(0);
191
+ });