-
-
Notifications
You must be signed in to change notification settings - Fork 96
/
Copy pathapp.js
147 lines (128 loc) · 4.83 KB
/
app.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
var path = require('path');
var LatexOnline = require('./lib/LatexOnline');
var Janitor = require('./lib/Janitor');
var HealthMonitor = require('./lib/HealthMonitor');
var utils = require('./lib/utilities');
var logger = utils.logger('app.js');
var VERSION = process.env.VERSION || "master";
VERSION = VERSION.substr(0, 9);
// Will be initialized later.
var latexOnline;
var healthMonitor;
// Initialize service dependencies.
LatexOnline.create('/tmp/downloads/', '/tmp/storage/')
.then(onInitialized)
function onInitialized(latex) {
latexOnline = latex;
if (!latexOnline) {
logger.error('ERROR: failed to initialize latexOnline');
return;
}
// Initialize janitor to clean up stale storage.
var expiry = utils.hours(24);
var cleanupTimeout = utils.minutes(5);
var janitor = new Janitor(latexOnline, expiry, cleanupTimeout);
// Initialize health monitor
healthMonitor = new HealthMonitor(latexOnline);
// Launch server.
var port = process.env.PORT || 2700;
var listener = app.listen(port, () => {
logger.info("Express server started", {
port: listener.address().port,
env: app.settings.env,
sha: VERSION
});
});
}
// Initialize server.
var express = require('express');
var compression = require('compression');
var app = express();
app.use(compression());
app.use(express.static(__dirname + '/public'));
function sendError(res, userError) {
res.set('Content-Type', 'text/plain');
var statusCode = userError ? 400 : 500;
var error = userError || 'Internal Server Error';
res.status(statusCode).send(error)
}
async function handleResult(res, preparation, force, downloadName) {
var {request, downloader, userError} = preparation;
if (!request) {
sendError(res, userError);
return;
}
var compilation = latexOnline.compilationWithFingerprint(request.fingerprint);
if (force && compilation)
latexOnline.removeCompilation(compilation);
compilation = latexOnline.getOrCreateCompilation(request, downloader);
await compilation.run();
// In case of URL compilation and cached compilation object, the downlaoder
// has to be cleaned up.
downloader.dispose();
if (compilation.userError) {
sendError(res, compilation.userError);
} else if (compilation.success) {
if (downloadName)
res.set('content-disposition', `attachment; filename="${downloadName}"`);
res.status(200).sendFile(compilation.outputPath(), {acceptRanges: false});
} else {
res.status(400).sendFile(compilation.logPath(), {acceptRanges: false});
}
}
app.get('/version', (req, res) => {
res.json({
version: VERSION,
link: `http://github.com/aslushnikov/latex-online/commit/${VERSION}`
});
});
app.get('/health.json', (req, res) => {
if (!healthMonitor) {
sendError(res, 'ERROR: health monitor is not initialized.');
return;
}
var result = {
uptime: healthMonitor.uptime(),
health: healthMonitor.healthPoints()
};
res.json(result);
});
app.get('/health', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'health.html'));
});
app.get('/compile', async (req, res) => {
req.socket.setTimeout(1000 * 60 * 5); // 5 minutes
var forceCompilation = req.query && !!req.query.force;
var command = req.query && req.query.command ? req.query.command : 'pdflatex';
command = command.trim().toLowerCase();
var preparation;
if (req.query.text) {
preparation = await latexOnline.prepareTextCompilation(req.query.text, command);
} else if (req.query.url) {
preparation = await latexOnline.prepareURLCompilation(req.query.url, command);
} else if (req.query.git) {
var workdir = req.query.workdir || '';
preparation = await latexOnline.prepareGitCompilation(req.query.git, req.query.target, 'master', command, workdir);
}
if (preparation)
handleResult(res, preparation, forceCompilation, req.query.download);
else
sendError(res, 'ERROR: failed to parse request: ' + JSON.stringify(req.query));
});
var multer = require('multer')
var upload = multer({ dest: '/tmp/file-uploads/' })
app.post('/data', upload.any(), async (req, res) => {
if (!req.files || req.files.length !== 1) {
sendError(res, 'ERROR: files are not uploaded to server.');
return;
}
var command = req.query && req.query.command ? req.query.command : 'pdflatex';
command = command.trim().toLowerCase();
var file = req.files[0];
var preparation = await latexOnline.prepareTarballCompilation(file.path, req.query.target, command);
if (preparation)
await handleResult(res, preparation, true /* force */, null /* downloadName */);
else
sendError(res, 'ERROR: failed to process file upload!');
utils.unlink(file.path);
});