-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
171 lines (147 loc) · 5.39 KB
/
main.go
File metadata and controls
171 lines (147 loc) · 5.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
// Copyright 2023 Bill Nixon. All rights reserved.
// Use of this source code is governed by the license found in the LICENSE file.
package main
import (
"context"
"fmt"
"html/template"
"log/slog"
"net/http"
"os"
"time"
"github.com/bnixon67/webapp/webapp"
"github.com/bnixon67/webapp/webauth"
"github.com/bnixon67/webapp/webhandler"
"github.com/bnixon67/webapp/weblog"
"github.com/bnixon67/webapp/webserver"
"github.com/bnixon67/webapp/webutil"
_ "github.com/go-sql-driver/mysql"
)
type BidApp struct {
*webauth.AuthApp
*BidDB
AuctionStart, AuctionEnd time.Time
}
const (
ExitUsage = iota + 1 // ExitUsage indicates a usage error.
ExitConfig // ExitConfig indicates a config error.
ExitLog // ExitLog indicates a log error.
ExitTemplate // ExitTemplate indicates a template error.
ExitDB // ExitConfig indicates a database error.
ExitApp // ExitHandler indicates an app error.
ExitServer // ExitServer indicates a server error.
)
func main() {
// Check for command line argument with config file.
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, "Usage: %s [config file]\n", os.Args[0])
os.Exit(ExitUsage)
}
// Read config.
cfg, err := webauth.LoadConfigFromJSON(os.Args[1])
if err != nil {
fmt.Fprintln(os.Stderr, "Failed to load config:", err)
os.Exit(ExitConfig)
}
// Validate config.
missingFields, err := cfg.MissingFields()
if err != nil {
fmt.Fprintln(os.Stderr, "Failed to validate config:", err)
os.Exit(ExitConfig)
}
if len(missingFields) != 0 {
fmt.Fprintln(os.Stderr, "Missing fields in config", missingFields)
os.Exit(ExitConfig)
}
// Initialize logging.
err = weblog.Init(cfg.Log)
if err != nil {
fmt.Fprintln(os.Stderr, "Failed to init logging:", err)
os.Exit(ExitLog)
}
// Define the custom function
funcMap := template.FuncMap{
"ToTimeZone": webutil.ToTimeZone,
}
// Initialize templates with custom functions.
tmpl, err := webutil.TemplatesWithFuncs(cfg.App.TmplPattern, funcMap)
if err != nil {
fmt.Fprintln(os.Stderr, "Failed to init templates:", err)
os.Exit(ExitTemplate)
}
// Initialize db
db, err := webauth.InitDB(cfg.SQL.DriverName, cfg.SQL.DataSourceName)
if err != nil {
fmt.Fprintln(os.Stderr, "Failed to init db:", err)
os.Exit(ExitDB)
}
// Create the web login app.
app, err := webauth.NewApp(webapp.WithName(cfg.App.Name), webapp.WithTemplate(tmpl), webauth.WithConfig(*cfg), webauth.WithDB(db))
if err != nil {
fmt.Fprintln(os.Stderr, "Failed to create new webauth:", err)
os.Exit(ExitApp)
}
// Embed web login app into BidApp
bidApp := BidApp{AuthApp: app, BidDB: &BidDB{}}
bidApp.BidDB.sqlDB = app.DB
err = bidApp.ConfigAuction()
if err != nil {
slog.Error("failed to ConfigAuction", "err", err)
return
}
slog.Info("create app", "bidApp", bidApp)
// Create a new ServeMux to handle HTTP requests.
mux := http.NewServeMux()
// Register handlers
mux.Handle("/", http.RedirectHandler("/gallery", http.StatusMovedPermanently))
mux.HandleFunc("/pico.min.css", webhandler.FileHandler("html/pico.min.css"))
mux.HandleFunc("/gobid.css", webhandler.FileHandler("html/gobid.css"))
mux.HandleFunc("/bids.js", webhandler.FileHandler("html/bids.js"))
mux.HandleFunc("/gallery.js", webhandler.FileHandler("html/gallery.js"))
mux.HandleFunc("/toggle.js", webhandler.FileHandler("html/toggle.js"))
mux.HandleFunc("/favicon.ico", webhandler.FileHandler("html/favicon.ico"))
mux.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir("images"))))
mux.HandleFunc("GET /login", app.LoginGetHandler)
mux.HandleFunc("POST /login", app.LoginPostHandler)
mux.HandleFunc("GET /build", app.BuildHandlerGet)
mux.HandleFunc("/register", app.RegisterHandler)
mux.HandleFunc("/logout", app.LogoutHandler)
mux.HandleFunc("/forgot", app.ForgotHandler)
mux.HandleFunc("/reset", app.ResetHandler)
mux.HandleFunc("/users", app.UsersHandler)
mux.HandleFunc("/userscsv", app.UsersCSVHandler)
mux.HandleFunc("/gallery", bidApp.GalleryHandler)
mux.HandleFunc("/items", bidApp.ItemsHandler)
mux.HandleFunc("/item/", bidApp.ItemHandler)
mux.HandleFunc("/edit/", bidApp.ItemEditHandler)
mux.HandleFunc("/winners", bidApp.WinnerHandler)
mux.HandleFunc("/winnerscsv", bidApp.WinnersCSVHandler)
mux.HandleFunc("/bids", bidApp.BidsHandler)
mux.HandleFunc("/events", app.EventsHandler)
mux.HandleFunc("/eventscsv", app.EventsCSVHandler)
mux.HandleFunc("GET /confirm", app.ConfirmHandlerGet)
mux.HandleFunc("GET /confirmed", app.ConfirmedHandlerGet)
mux.HandleFunc("GET /confirm_request", app.ConfirmRequestHandlerGet)
mux.HandleFunc("GET /confirm_request_sent", app.ConfirmRequestSentHandlerGet)
mux.HandleFunc("POST /confirm", app.ConfirmHandlerPost)
mux.HandleFunc("POST /confirm_request", app.ConfirmRequestHandlerPost)
// Create the web server.
srv, err := webserver.New(
webserver.WithAddr(cfg.Server.Host+":"+cfg.Server.Port),
webserver.WithHandler(webhandler.NewRequestIDMiddleware(webhandler.MiddlewareLogger(webhandler.LogRequest(mux)))),
webserver.WithTLS(cfg.Server.CertFile, cfg.Server.KeyFile),
)
if err != nil {
fmt.Fprintln(os.Stderr, "Error creating server:", err)
os.Exit(ExitServer)
}
// Create a new context.
ctx := context.Background()
// Run the web server.
err = srv.Run(ctx)
if err != nil {
slog.Error("error running server", "err", err)
fmt.Fprintln(os.Stderr, "Error running server:", err)
os.Exit(ExitServer)
}
}