Files
farmcal/cmd/server/main.go

95 lines
2.6 KiB
Go

package main
import (
"database/sql"
"errors"
"log"
"net/http"
"os"
"strings"
"time"
_ "github.com/go-sql-driver/mysql"
)
var monthNames = []string{
"Januar", "Februar", "Maerz", "April", "Mai", "Juni",
"Juli", "August", "September", "Oktober", "November", "Dezember",
}
type App struct {
db *sql.DB
}
func main() {
addr := readEnv("APP_ADDR", ":8080")
dsn := readEnv("DB_DSN", "farmcal:farmcal@tcp(127.0.0.1:3306)/farmcal?parseTime=true")
db, err := sql.Open("mysql", dsn)
if err != nil {
log.Fatalf("db open failed: %v", err)
}
defer db.Close()
if err := db.Ping(); err != nil {
log.Fatalf("db ping failed: %v", err)
}
if err := ensureSchema(db); err != nil {
log.Fatalf("schema setup failed: %v", err)
}
app := &App{db: db}
mux := http.NewServeMux()
mux.HandleFunc("/", app.handleDashboard)
mux.HandleFunc("/fields", app.handleFieldsPage)
mux.HandleFunc("/crops", app.handleCropsPage)
mux.HandleFunc("/planning", app.handlePlanningPage)
mux.HandleFunc("/general", app.handleGeneralPage)
mux.HandleFunc("/settings/days", app.handleSetDaysPerMonth)
mux.HandleFunc("/settings/time", app.handleSetCurrentTime)
mux.HandleFunc("/fields/create", app.handleCreateField)
mux.HandleFunc("/fields/update", app.handleUpdateField)
mux.HandleFunc("/fields/delete", app.handleDeleteField)
mux.HandleFunc("/field-groups/create", app.handleCreateFieldGroup)
mux.HandleFunc("/field-groups/delete", app.handleDeleteFieldGroup)
mux.HandleFunc("/crops/create", app.handleCreateCrop)
mux.HandleFunc("/crops/update", app.handleUpdateCrop)
mux.HandleFunc("/crops/delete", app.handleDeleteCrop)
mux.HandleFunc("/crop-steps/create", app.handleCreateCropStep)
mux.HandleFunc("/crop-steps/delete", app.handleDeleteCropStep)
mux.HandleFunc("/plans/create", app.handleCreatePlan)
mux.HandleFunc("/plans/delete", app.handleDeletePlan)
mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
srv := &http.Server{
Addr: addr,
Handler: withLogging(mux),
ReadHeaderTimeout: 5 * time.Second,
}
log.Printf("FarmCal listening on %s", addr)
if err := srv.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
log.Fatalf("server stopped: %v", err)
}
}
func readEnv(key, fallback string) string {
v := strings.TrimSpace(os.Getenv(key))
if v == "" {
return fallback
}
return v
}
func withLogging(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
next.ServeHTTP(w, r)
log.Printf("%s %s %s", r.Method, r.URL.Path, time.Since(start).Round(time.Millisecond))
})
}