131 lines
4.1 KiB
Go
131 lines
4.1 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"log/slog"
|
||
|
"math/rand"
|
||
|
"net/http"
|
||
|
"os"
|
||
|
"path/filepath"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
"text/template"
|
||
|
"time"
|
||
|
|
||
|
"git.andreafazzi.eu/andrea/probo/models"
|
||
|
)
|
||
|
|
||
|
var Dir = "data"
|
||
|
|
||
|
type ExamSession []*models.Exam
|
||
|
|
||
|
func generateRandomID() string {
|
||
|
id := ""
|
||
|
for i := 0; i < 6; i++ {
|
||
|
id += strconv.Itoa(rand.Intn(9) + 1)
|
||
|
}
|
||
|
return id
|
||
|
}
|
||
|
|
||
|
func createExamSessionHandler(w http.ResponseWriter, r *http.Request) {
|
||
|
var p ExamSession
|
||
|
err := json.NewDecoder(r.Body).Decode(&p)
|
||
|
if err != nil {
|
||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
id := generateRandomID()
|
||
|
path := filepath.Join(Dir, id)
|
||
|
|
||
|
err = os.MkdirAll(path, os.ModePerm)
|
||
|
if err != nil {
|
||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
for _, exam := range p {
|
||
|
file, err := os.Create(filepath.Join(path, strconv.Itoa(exam.Participant.Token)) + ".json")
|
||
|
if err != nil {
|
||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||
|
return
|
||
|
}
|
||
|
defer file.Close()
|
||
|
|
||
|
err = json.NewEncoder(file).Encode(exam)
|
||
|
if err != nil {
|
||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
response := map[string]string{"id": id}
|
||
|
json.NewEncoder(w).Encode(response)
|
||
|
}
|
||
|
|
||
|
func getExamHandler(w http.ResponseWriter, r *http.Request) {
|
||
|
urlParts := strings.Split(r.URL.Path, "/")
|
||
|
|
||
|
examID := urlParts[1]
|
||
|
token := urlParts[2]
|
||
|
|
||
|
filePath := filepath.Join(Dir, examID, token+".json")
|
||
|
|
||
|
data, err := os.ReadFile(filePath)
|
||
|
if err != nil {
|
||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
exam := new(models.Exam)
|
||
|
err = json.Unmarshal(data, &exam)
|
||
|
if err != nil {
|
||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
w.Header().Set("Content-Type", "text/html")
|
||
|
tmpl := template.Must(template.New("exam").Parse(`
|
||
|
<!DOCTYPE html>
|
||
|
<html>
|
||
|
<head>
|
||
|
<title>{{.Name}}</title>
|
||
|
</head>
|
||
|
<body>
|
||
|
<h1>{{.Name}}</h1>
|
||
|
<h2>{{.Participant.Firstname}} {{.Participant.Lastname}}</h2>
|
||
|
<form>
|
||
|
{{range $index, $quiz := .Quizzes}}
|
||
|
<h3>Question {{$index}}:</h3>
|
||
|
<p>{{$quiz.Question.Text}}</p>
|
||
|
{{range $answer := $quiz.Answers}}
|
||
|
<input type="radio"
|
||
|
id="{{$answer.ID}}" name="$answer.ID"
|
||
|
value="{{$answer.Text}}">
|
||
|
<label
|
||
|
for="{{$answer.ID}}">{{$answer.Text}}</label><br>
|
||
|
{{end}}
|
||
|
<br>
|
||
|
{{end}}
|
||
|
<input type="submit" value="Invia">
|
||
|
</form>
|
||
|
</body>
|
||
|
</html>
|
||
|
`))
|
||
|
|
||
|
err = tmpl.Execute(w, exam)
|
||
|
if err != nil {
|
||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
func main() {
|
||
|
mux := http.NewServeMux()
|
||
|
mux.HandleFunc("/create", createExamSessionHandler)
|
||
|
mux.HandleFunc("/", getExamHandler)
|
||
|
|
||
|
slog.Info("Probo server started", "at", time.Now())
|
||
|
http.ListenAndServe(":8080", mux)
|
||
|
}
|