Server-Side Scripting/Strings and Files/Go

From Wikiversity
Jump to navigation Jump to search

server.go[edit | edit source]

// This program reads a user-selected text file of Fahrenheit
// temperatures and converts the temperatures to Celsius.
//
// File format:
// 32° F
// 98.6° F
// 212° F
//
// References:
//  https://www.mathsisfun.com/temperature-conversion.html
//  https://golang.org/doc/
//  https://tutorialedge.net/golang/go-file-upload-tutorial/

package main

import (
    "io"
    "io/ioutil"
    "mime/multipart"
    "net/http"
    "strconv"
    "strings"
)

var FORM = `
<h1>Temperature Conversion</h1>
<p>Select a file of Fahrenheit temperatures for conversion:</p>
<form method="POST" enctype="multipart/form-data">
<input type="hidden" name="MAX_FILE_SIZE" value="1048576" />
<input type="file" id="file" name="file">
<input type="submit">
</form>
`

func handler(response http.ResponseWriter, request *http.Request) {
    response.Header().Set("Content-Type", "text/html charset=utf-8")

    result := ""

    switch request.Method {
        case "GET":
            result = FORM
        case "POST":
            result = "<h1>Temperature Conversion</h1>";
            file, handler, err := request.FormFile("file")
            if err != nil {
                result += err.Error()
            }
            result += "<h2>" + handler.Filename + "</h2>"
            result += processFile(file);
        default:
            result = "Unexpected request method: " + request.Method
    }

    io.WriteString(response, result)
}

func processFile(file multipart.File) string {
    result := "<table><tr><th>Fahrenheit</th><th>Celsius</th></tr>"

    bytes, err := ioutil.ReadAll(file)
    if (err != nil) {
        return err.Error()
    }

    text := string(bytes)
    text = strings.TrimSpace(text)
    lines := strings.Split(text, "\n")
    for _, line := range lines {
        result += processLine(line)
    }
    result += "</table>"
    return result
}

func processLine(line string) string {
    index := strings.Index(line, "° F")
    if index < 0 {
        return "Invalid file format"
    }

    fahrenheit, err := strconv.ParseFloat(line[0:index], 64)
    if err != nil {
        return err.Error()
    }

    celsius := (fahrenheit - 32) * 5 / 9
    result := "<tr><td>" + strconv.FormatFloat(fahrenheit, 'f', 1, 64) + "</td>"
    result += "<td>" + strconv.FormatFloat(celsius, 'f', 1, 64) + "</td></tr>"

    return result
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8000", nil)
}

Try It[edit | edit source]

Copy and paste the code above into the following free online development environment or use your own Go compiler / interpreter / IDE.