hw4: ex5 passes tests

This commit is contained in:
Claudio Maggioni (maggicl) 2019-10-13 12:55:16 +02:00
parent 50d194ac2d
commit 0cb7ed641a

View file

@ -25,12 +25,13 @@ function error(res, code, text = '') {
</html>`); </html>`);
} }
function fileData(reqUrl, prefix, wantExt = true) { function fileData(reqUrl, prefix, options = {}) {
const uri = decodeURIComponent(url.parse(reqUrl).pathname const uri = decodeURIComponent(
.substring(prefix.length)).replace(/\/+$/, ''); !options.isPath ? url.parse(reqUrl).pathname.substring(prefix.length) : reqUrl
).replace(/\/+$/, '');
const file = __dirname + '/NodeStaticFiles' + uri; const file = __dirname + '/NodeStaticFiles' + uri;
const name = file.substring(file.lastIndexOf('/') + 1); const name = file.substring(file.lastIndexOf('/') + 1);
const ext = wantExt ? name.substring(name.indexOf('.') + 1) : null; const ext = !options.noExt ? name.substring(name.indexOf('.') + 1) : null;
return { return {
uri: !uri ? '/' : uri, uri: !uri ? '/' : uri,
@ -46,7 +47,7 @@ routes['explore'] = (req, res) => {
return; return;
} }
const { uri, file, name } = fileData(req.url, '/explore', false); const { uri, file, name } = fileData(req.url, '/explore', { noExt: true });
fs.readdir(file, { withFileTypes: true }, (err, dir) => { fs.readdir(file, { withFileTypes: true }, (err, dir) => {
if (err) { if (err) {
@ -174,8 +175,80 @@ routes['upload'] = (req, res) => {
</html>`); </html>`);
}; };
function wordMap(string) {
const words = string.trim().split(/[^\w]+/);
const wordDict = {};
for (const word of words) {
if (word.trim() == '') {
continue;
}
if (!wordDict[word]) {
wordDict[word] = 1;
} else {
wordDict[word]++;
}
}
return wordDict;
}
routes['stats'] = (req, res) => { routes['stats'] = (req, res) => {
res.end() const p = url.parse(req.url, true);
if (p.pathname != '/stats' && p.pathname != '/stats') {
error(res, 404, 'Only "/stats" path is accessible under this prefix');
return;
}
const reqFile = p && p.query && '/' + p.query['file'];
if (!reqFile) {
error(res, 400, 'Search parameter "file" is required');
return;
}
const { file, name, ext } = fileData(reqFile, '/stats', { isPath: true });
if (ext != 'txt' && ext != 'html') {
error(res, 400, 'Only txt and html files can be processed by /stats');
return;
}
fs.readFile(file, 'utf8', (err, data) => {
if (err) {
error(res, 404, 'File not found: ' + JSON.stringify(err));
return;
}
const dict = wordMap(data);
res.writeHead(200, { 'Content-Type': 'text/html' });
res.write(`<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Stats for ${reqFile}</title>
<style>
table { border-collapse: collapse; }
td, th { border: 1px solid black; }
th { font-weight: bold; }
</style>
</head>
<body>
<h1>Word frequency count for "${reqFile}"</h1>
<table id="frequency-tbl">
<thead>
<tr><th>Word</th><th>Freq.</th></tr>
</thead>
<tbody>`);
for (const word in dict) {
res.write(`<tr>
<td class="word">${word}</td>
<td class="frequency">${dict[word]}</td>
</tr>`);
}
res.end(`</tbody>
</table>
</body>
</html>`);
});
}; };
// Main server handler // Main server handler
@ -190,6 +263,5 @@ function onRequest(req, res) {
} }
} }
http.createServer(onRequest).listen(3000); http.createServer(onRequest).listen(3000);
console.log('Server started at localhost:3000'); console.log('Server started at localhost:3000');