forked from WEB-IMB-WS2526/lab-development-imb
07: Lösungen
parent
8284e554da
commit
b392786fe4
|
|
@ -0,0 +1,48 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Book struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Author string `json:"author"`
|
||||||
|
Read bool `json:"read"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Library struct {
|
||||||
|
Books []Book `json:"books"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lib *Library) Add(title, author string) {
|
||||||
|
id := len(lib.Books) + 1
|
||||||
|
lib.Books = append(lib.Books, Book{ID: id, Title: title, Author: author, Read: false})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lib *Library) MarkRead(id int) {
|
||||||
|
for i := range lib.Books {
|
||||||
|
if lib.Books[i].ID == id {
|
||||||
|
lib.Books[i].Read = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lib *Library) Save(filename string) error {
|
||||||
|
data, err := json.MarshalIndent(lib, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return os.WriteFile(filename, data, 0644)
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadLibrary(filename string) (*Library, error) {
|
||||||
|
data, err := os.ReadFile(filename)
|
||||||
|
if err != nil {
|
||||||
|
return &Library{}, nil
|
||||||
|
}
|
||||||
|
var lib Library
|
||||||
|
err = json.Unmarshal(data, &lib)
|
||||||
|
return &lib, err
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"books": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"title": "Der Steppenwolf",
|
||||||
|
"author": "Hermann Hesse",
|
||||||
|
"read": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"title": "Clean Code",
|
||||||
|
"author": "Robert C. Martin",
|
||||||
|
"read": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if len(os.Args) < 2 {
|
||||||
|
fmt.Println("Usage: add <title> <author> | list | read <id>")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
lib, _ := LoadLibrary("books.json")
|
||||||
|
|
||||||
|
switch os.Args[1] {
|
||||||
|
case "add":
|
||||||
|
if len(os.Args) < 4 {
|
||||||
|
fmt.Println("Usage: add <title> <author>")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
lib.Add(os.Args[2], os.Args[3])
|
||||||
|
lib.Save("books.json")
|
||||||
|
fmt.Println("Buch hinzugefügt.")
|
||||||
|
|
||||||
|
case "list":
|
||||||
|
for _, b := range lib.Books {
|
||||||
|
status := " "
|
||||||
|
if b.Read {
|
||||||
|
status = "✓"
|
||||||
|
}
|
||||||
|
fmt.Printf("[%s] %d: \"%s\" by %s\n", status, b.ID, b.Title, b.Author)
|
||||||
|
}
|
||||||
|
|
||||||
|
case "read":
|
||||||
|
if len(os.Args) < 3 {
|
||||||
|
fmt.Println("Geben Sie eine Buch-ID ein.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
id, err := strconv.Atoi(os.Args[2])
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Ungültige ID-Eingabe.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
lib.MarkRead(id)
|
||||||
|
lib.Save("books.json")
|
||||||
|
fmt.Println("Buch als gelesen markiert.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type workshopHandler int
|
||||||
|
|
||||||
|
func parseCheckboxValue(value string) string {
|
||||||
|
if value == "" || (value != "ja" && value != "on") {
|
||||||
|
return "nein"
|
||||||
|
}
|
||||||
|
return "ja"
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseRadiobuttonValue(value string) (string, error) {
|
||||||
|
if value == "" || (value != "praesenz" && value != "online") {
|
||||||
|
return "", errors.New("Auswahl nicht erlaubt.")
|
||||||
|
}
|
||||||
|
return value, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worksh workshopHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
if r.Method != http.MethodPost {
|
||||||
|
http.Error(w, "Nur POST-Anfragen erlaubt", http.StatusMethodNotAllowed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Formulardaten parsen und Überprüfen, ob ungültige Formulardaten gesendet wurde
|
||||||
|
if err := r.ParseForm(); err != nil {
|
||||||
|
http.Error(w, "Fehler beim Parsen des Formulars", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Überprüfen, ob leeres Formular gesendet wurde
|
||||||
|
if len(r.PostForm) == 0 {
|
||||||
|
http.Error(w, "Kein Formular gesendet", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Formulardaten auslesen und ggf. überprüfen
|
||||||
|
vorname := r.PostForm.Get("vorname")
|
||||||
|
if vorname == "" {
|
||||||
|
http.Error(w, "Pflichtfeld fehlt.", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
nachname := r.PostForm.Get("nachname")
|
||||||
|
if nachname == "" {
|
||||||
|
http.Error(w, "Pflichtfeld fehlt.", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
email := r.PostForm.Get("email")
|
||||||
|
telefon := r.PostForm.Get("telefon")
|
||||||
|
sessions := r.PostForm["sessions"]
|
||||||
|
agb := parseCheckboxValue(r.PostForm.Get("agb"))
|
||||||
|
if agb == "nein" {
|
||||||
|
http.Error(w, "AGB wurde nicht akzeptiert.", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
newsletter := parseCheckboxValue(r.PostForm.Get("newsletter"))
|
||||||
|
equipment := parseCheckboxValue(r.PostForm.Get("equipment"))
|
||||||
|
format, err := parseRadiobuttonValue(r.PostForm.Get("format"))
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "Ungültige Auswahl des Formats.", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ausgabe im Terminal
|
||||||
|
fmt.Fprintf(w, "Neue Registrierung erhalten:\n")
|
||||||
|
fmt.Fprintf(w, "Vorname: %s\n", vorname)
|
||||||
|
fmt.Fprintf(w, "Nachname: %s\n", nachname)
|
||||||
|
fmt.Fprintf(w, "E-Mail: %s\n", email)
|
||||||
|
fmt.Fprintf(w, "Telefon: %s\n", telefon)
|
||||||
|
fmt.Fprintf(w, "Bevorzugte Sessions: \n")
|
||||||
|
for _, session := range sessions {
|
||||||
|
fmt.Fprintf(w, " - %s\n", session)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, "AGB: %s\n", agb)
|
||||||
|
fmt.Fprintf(w, "Newsletter: %s\n", newsletter)
|
||||||
|
fmt.Fprintf(w, "Equipment benötigt: %s\n", equipment)
|
||||||
|
fmt.Fprintf(w, "Teilnahmeformat: %s", format)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var workshop workshopHandler
|
||||||
|
fmt.Println("Server läuft auf localhost:8080...")
|
||||||
|
log.Fatal(http.ListenAndServe(":8080", workshop))
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Workshop-Anmeldung</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<form action="http://localhost:8080/registrierung" method="post">
|
||||||
|
<fieldset>
|
||||||
|
<legend>Persönliche Angaben:</legend>
|
||||||
|
<label for="vorname">Vorname:</label><br>
|
||||||
|
<input type="text" name="vorname" id="vorname" placeholder="Vorname" required><br>
|
||||||
|
|
||||||
|
<label for="nachname">Nachname:</label><br>
|
||||||
|
<input type="text" name="nachname" id="nachname" placeholder="Nachname" required><br>
|
||||||
|
|
||||||
|
<label for="email">E-Mail:</label><br>
|
||||||
|
<input type="email" name="email" id="email" autocomplete="email"><br>
|
||||||
|
|
||||||
|
<label for="telefon">Handynummer:</label><br>
|
||||||
|
<input type="tel" name="telefon" id="telefon" pattern="^01[5-7][0-9]{7,10}$"><br><br>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<legend>Kursauswahl:</legend>
|
||||||
|
<label for="kurs">Kurs:</label><br>
|
||||||
|
<input type="text" name="kurs" id="kurs" value="Webentwicklung Basics" readonly disabled><br><br>
|
||||||
|
|
||||||
|
<label for="sessions">Bevorzugte Session:</label><br>
|
||||||
|
<select id="sessions" name="sessions" multiple size="4">
|
||||||
|
<option value="vormittag">Vormittag</option>
|
||||||
|
<option value="nachmittag">Nachmittag</option>
|
||||||
|
<option value="abendsession">Abend</option>
|
||||||
|
<option value="wochenende">Wochenende</option>
|
||||||
|
</select><br>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<legend>Zusätzliche Optionen:</legend>
|
||||||
|
<input type="checkbox" id="agb" name="agb" required>
|
||||||
|
<label for="agb">Ich akzeptiere die Teilnahmebedingungen.</label><br>
|
||||||
|
|
||||||
|
<input type="checkbox" id="newsletter" name="newsletter" value="ja">
|
||||||
|
<label for="newsletter">Newsletter abonnieren.</label><br>
|
||||||
|
|
||||||
|
<input type="checkbox" id="equipment" name="equipment" value="ja">
|
||||||
|
<label for="equipment">Ich benötige spezielles Equipment.</label><br>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<legend>Teilnahmeformat:</legend>
|
||||||
|
Format wählen:<br>
|
||||||
|
<input type="radio" id="online" name="format" value="online" required>
|
||||||
|
<label for="online">Online</label><br>
|
||||||
|
|
||||||
|
<input type="radio" id="praesenz" name="format" value="praesenz">
|
||||||
|
<label for="praesenz">Präsenz</label><br>
|
||||||
|
</fieldset>
|
||||||
|
<br>
|
||||||
|
<input type="submit" value="Jetzt anmelden">
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,119 @@
|
||||||
|
{
|
||||||
|
"openapi": "3.0.0",
|
||||||
|
"info": {
|
||||||
|
"title": "Workshop API",
|
||||||
|
"version": "1.0.0"
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "http://localhost:8080"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/registrierung": {
|
||||||
|
"post": {
|
||||||
|
"summary": "Sends all information needed for registering at a workshop",
|
||||||
|
"requestBody": {
|
||||||
|
"required": false,
|
||||||
|
"content": {
|
||||||
|
"application/x-www-form-urlencoded": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/RegistrierungForm"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/RegistrierungForm"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Success",
|
||||||
|
"content": {
|
||||||
|
"text/html": {
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"content": {
|
||||||
|
"text/plain": {
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Kein Formular gesendet"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"RegistrierungForm": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"vorname",
|
||||||
|
"nachname",
|
||||||
|
"agb",
|
||||||
|
"format"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"vorname": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Zoya"
|
||||||
|
},
|
||||||
|
"nachname": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Akhtar"
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "z.akhtar@test.de"
|
||||||
|
},
|
||||||
|
"telefon": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Zoya"
|
||||||
|
},
|
||||||
|
"sessions": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "vormittag"
|
||||||
|
},
|
||||||
|
"example": [
|
||||||
|
"vormittag",
|
||||||
|
"nachmittag"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"agb": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["on","ja"],
|
||||||
|
"example": "on"
|
||||||
|
},
|
||||||
|
"newsletter": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["on","ja"],
|
||||||
|
"example": "ja"
|
||||||
|
},
|
||||||
|
"equipment": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["on","ja"],
|
||||||
|
"example": "ja"
|
||||||
|
},
|
||||||
|
"format": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["online","praesenz"],
|
||||||
|
"example": "online"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue