Server-Side Scripting/Strings and Files/Node.js (Express)

app.js

edit
// Demonstrates a complete server-side website using:
//   * static HTML and CSS
//   * a template
//   * a code module
//
// NOTE: Static pages (html, css, images, etc.) are placed in
// a folder named "static". Template pages are placed in a folder
// named "templates".
//
// Folder structure:
// app.js
// hello.js
// static
//   index.html
//   static.html
//   styles.css
// templates
//   template.html
//
// References:
//  https://repl.it/languages/express
//  https://expressjs.com/en/guide/routing.html
//  https://www.npmjs.com/package/express-fileupload

const express = require("express");
const fileUpload = require('express-fileupload');

const app = express();

app.use(express.static(__dirname + '/static'));
app.use(express.urlencoded({
        extended: true
}));

app.use(fileUpload({
    limits: { fileSize: 1 * 1024 * 1024 },
}));

const fs = require("fs");
fs.readdirSync("./routes").map((filename) => {
    const module = require("./routes/" + filename);
    const route = filename.replace(".js", "")
    app.use("/" + route, module);
});

app.listen(3000, () => console.log('server started'));

routes/lesson5.js

edit
// This program reads a user-selected text file of Celsius
// temperatures and converts the temperatures to Fahrenheit.
//
// File format:
// Country,MaximumTemperature
// Bulgaria,45.2 °C
// Canada,45 °C
//
//  https://www.mathsisfun.com/temperature-conversion.html
//  https://en.wikibooks.org/wiki/JavaScript
//  https://www.npmjs.com/package/express-fileupload

const express = require('express')
const fs = require("fs");
const handlebars = require('handlebars');
const router = express.Router()

router.get("/", function (request, response) {
    let source = fs.readFileSync("./templates/lesson5.html");
    let template = handlebars.compile(source.toString());
    let data = {
        table: ""
    }
    result = template(data);
    response.send(result);
});

router.post("/", function (request, response) {
    let result = "";

    if (!request.files || Object.keys(request.files).length == 0) {
        result = "No file selected"
    } else {
        let file = request.files.file;
        result += "<h2>" + file.name + "</h2>";
        result += processFile(file)
    }

    let source = fs.readFileSync("./templates/lesson5.html");
    let template = handlebars.compile(source.toString());
    let data = {
        table: result
    }
    result = template(data);
    response.send(result);
});

function processFile(file) {
    let result = "<table><tr><th>Celsius</th><th>Fahrenheit</th></tr>";
    let text = file.data.toString();
    let lines = text.trim().split("\n");

    // forEach doesn't return a value. Using global.forEach instead.
    global.forEach = "";
    lines.forEach(processLine);
    result += global.forEach;
    delete global.forEach;

    result += "</table>";
    return result
}

function processLine(line) {
    // skip heading
    let index = line.indexOf("Country,MaximumTemperature");
    if (index >= 0) {
        return;
    }

    // find temperature
    let start = line.indexOf(",");
    let end = line.indexOf("°C");
    if (start < 0 || end < 0) {
        global.forEach += "Invalid file format";
        return
    }

    let celsius = Number(line.substring(start + 1, end));
    let fahrenheit = celsius * 9 / 5 + 32;

    global.forEach += "<tr><td>" + celsius + "</td>";
    global.forEach += "<td>" + fahrenheit.toFixed(1) + "</td></tr>";
}

module.exports = router;

templates/lesson5.html

edit
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Lesson 5</title>
    <link rel="stylesheet" href="styles.css">
    <style>
        p {
            min-height: 1em;
        }
    </style>
</head>

<body>
    <h1>Temperature Conversion</h1>
    <p>Select a file of Fahrenheit temperatures for conversion:</p>
    <form method="POST" enctype="multipart/form-data">
        <input type="file" id="file" name="file">
        <input type="submit">
    </form>
    {{{table}}}
</body>

</html>

Try It

edit

Copy and paste the code above into the following free online development environment or use your own Node.js (Express) compiler / interpreter / IDE.