hw4: ready for submission
This commit is contained in:
parent
0cb7ed641a
commit
f6d54b18fd
2 changed files with 72 additions and 9 deletions
4
hw4/Claudio_Maggioni/readme.md
Normal file
4
hw4/Claudio_Maggioni/readme.md
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
# Bonuses implemented:
|
||||||
|
- *Excercise 5*, File statistics
|
||||||
|
- *Excercise 6*, Tag cloud
|
||||||
|
- *Excercise 7*, JSON Tag cloud
|
|
@ -8,6 +8,16 @@ const formidable = require('formidable');
|
||||||
|
|
||||||
const routes = Object.create(null);
|
const routes = Object.create(null);
|
||||||
|
|
||||||
|
function noSubPaths(req, path) {
|
||||||
|
const p = url.parse(req.url);
|
||||||
|
if (p.pathname != path && p.pathname != path) {
|
||||||
|
error(res, 404, `Only "${path}" path is accessible under this prefix`);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function error(res, code, text = '') {
|
function error(res, code, text = '') {
|
||||||
res.writeHead(code, { 'Content-Type': 'text/html' });
|
res.writeHead(code, { 'Content-Type': 'text/html' });
|
||||||
res.end(`<!DOCTYPE html>
|
res.end(`<!DOCTYPE html>
|
||||||
|
@ -191,12 +201,8 @@ function wordMap(string) {
|
||||||
return wordDict;
|
return wordDict;
|
||||||
}
|
}
|
||||||
|
|
||||||
routes['stats'] = (req, res) => {
|
function getFileStats(req, res, path, callback) {
|
||||||
const p = url.parse(req.url, true);
|
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'];
|
const reqFile = p && p.query && '/' + p.query['file'];
|
||||||
if (!reqFile) {
|
if (!reqFile) {
|
||||||
|
@ -204,9 +210,9 @@ routes['stats'] = (req, res) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { file, name, ext } = fileData(reqFile, '/stats', { isPath: true });
|
const { file, name, ext } = fileData(reqFile, path, { isPath: true });
|
||||||
if (ext != 'txt' && ext != 'html') {
|
if (ext != 'txt' && ext != 'html') {
|
||||||
error(res, 400, 'Only txt and html files can be processed by /stats');
|
error(res, 400, `Only txt and html files can be processed by ${path}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,6 +223,18 @@ routes['stats'] = (req, res) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const dict = wordMap(data);
|
const dict = wordMap(data);
|
||||||
|
|
||||||
|
callback({ reqFile: reqFile, dict: dict });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
routes['stats'] = (req, res) => {
|
||||||
|
if (noSubPaths(req, '/stats')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
getFileStats(req, res, '/stats', ({ reqFile, dict }) => {
|
||||||
res.writeHead(200, { 'Content-Type': 'text/html' });
|
res.writeHead(200, { 'Content-Type': 'text/html' });
|
||||||
res.write(`<!DOCTYPE html>
|
res.write(`<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
@ -251,6 +269,47 @@ routes['stats'] = (req, res) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
routes['cloud'] = (req, res) => {
|
||||||
|
if (noSubPaths(req, '/cloud')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
getFileStats(req, res, '/cloud', ({ reqFile, dict }) => {
|
||||||
|
if (req.headers.accept && req.headers.accept == 'application/json') {
|
||||||
|
res.writeHead(200, {'Content-Type': 'application/json' });
|
||||||
|
res.end(JSON.stringify(dict, null, 2));
|
||||||
|
} else {
|
||||||
|
res.writeHead(200, { 'Content-Type': 'text/html' });
|
||||||
|
res.write(`<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Cloud for ${reqFile}</title>
|
||||||
|
<style>
|
||||||
|
table { border-collapse: collapse; }
|
||||||
|
td, th { border: 1px solid black; }
|
||||||
|
th { font-weight: bold; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Tag cloud for "${reqFile}"</h1>
|
||||||
|
<div class="cloud">`);
|
||||||
|
|
||||||
|
const max = Math.max(...Object.values(dict));
|
||||||
|
const min = Math.min(...Object.values(dict));
|
||||||
|
|
||||||
|
for (const word in dict) {
|
||||||
|
const size = 0.75 + ((dict[word] - min) / max) * 4 + 'rem';
|
||||||
|
res.write(`<span style="font-size: ${size}"> ${word} </span>`);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.end(`</div>
|
||||||
|
</body>
|
||||||
|
</html>`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Main server handler
|
// Main server handler
|
||||||
function onRequest(req, res) {
|
function onRequest(req, res) {
|
||||||
const pathname = url.parse(req.url).pathname;
|
const pathname = url.parse(req.url).pathname;
|
||||||
|
|
Reference in a new issue