-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
98 lines (85 loc) · 3.25 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import cluster from 'cluster';
import { exit } from 'process';
import { execSync } from 'child_process';
import os from 'os';
import { fileURLToPath } from 'url';
import express from 'express';
import path from 'path';
import { renderFile } from 'ejs';
import body_parser from 'body-parser';
import file_upload from 'express-fileupload';
import connect_slashes from 'connect-slashes';
import { router as routes_convert } from './routes/convert.js';
import { router as routes_admin } from './routes/admin.js';
import { DocConverter } from './converter.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
let converter; // Global reference to converter so it doesn't get garbage collected
function add_fork(env = {}) {
let worker = cluster.fork(env);
worker.on('exit', () => {
console.error('Cluster worker crashed, starting a new one: env =', env);
add_fork(env);
});
}
if (cluster.isPrimary) {
// Check that the server was started in the expected way (it matters for env variables)
if (!process.env?.npm_command || process.env.npm_command != 'start') {
console.error('Must be started with `npm start`');
exit(1);
}
// Check some environment things
const node_version = execSync('node --version').toString();
if (!node_version.startsWith('v18.') && !node_version.startsWith('v19.')) {
console.error('NodeJS version 18 or 19 is required');
exit(1);
}
try {
execSync('pdf2svg');
} catch (err) {
if (err.status === 127) {
console.error('pdf2svg not found; are you using the paper_convert conda environment?');
exit(1);
}
}
if (process.env.npm_package_config_admin_page_password === 'change-me') {
console.error('Admin page password not set in package.json')
exit(1)
}
// Create a worker for all CPU cores but 1, to be used for document conversion
const num_workers = Math.max(1, os.cpus().length - 1);
for (let i = 0; i < num_workers; ++i) {
add_fork({'is_server': true});
}
add_fork({'is_converter': true});
} else if (process.env.is_converter) {
console.log('Started converter');
converter = new DocConverter();
} else {
var app = express();
// Use EJS for template rendering
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'html');
app.engine('html', renderFile);
// Parse the body of requests (will go into `req.body.xxx`)
app.use(body_parser.urlencoded({extended: false}));
// Parse file uploads
app.use(file_upload({
limits: {
fileSize: 50 * 1024 * 1024, // 50 MB
},
abortOnLimit: true,
createParentPath: true,
}));
// Serve static assets, making clear what is publicly accessible
app.use('/', express.static(path.join(__dirname, 'public')));
// Redirect /xx/ to /xx to standardize URLs and avoid some relative URL problems
app.use(connect_slashes(false));
// Additional routes
routes_convert.docs_dir = path.join(__dirname, 'papers');
app.use('/', routes_convert);
routes_admin.docs_dir = routes_convert.docs_dir;
app.use('/admin', routes_admin);
app.listen(3000);
console.log('Listening on port 3000');
}