108 lines
1.8 KiB
Go
108 lines
1.8 KiB
Go
package pretix
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"strings"
|
|
"sync"
|
|
|
|
"git.luj0ga.de/franconian/matrix-pretix/internal/config"
|
|
"git.luj0ga.de/franconian/matrix-pretix/internal/matrix"
|
|
)
|
|
|
|
type Server struct {
|
|
client http.Client
|
|
config *config.ServerConfig
|
|
db *sql.DB
|
|
matrix *matrix.Client
|
|
}
|
|
|
|
func NewServer(config *config.ServerConfig, db *sql.DB, matrix *matrix.Client) *Server {
|
|
return &Server{
|
|
config: config,
|
|
db: db,
|
|
matrix: matrix,
|
|
}
|
|
}
|
|
|
|
func (s Server) ListenAndServe(ctx context.Context, wg *sync.WaitGroup) error {
|
|
err := s.createTables()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
http.HandleFunc("/", http.NotFound)
|
|
http.HandleFunc("/order_placed", s.orderPlaced)
|
|
|
|
server := http.Server{
|
|
Addr: s.config.ListenAddress,
|
|
}
|
|
|
|
go func() {
|
|
wg.Add(1)
|
|
defer wg.Done()
|
|
|
|
<-ctx.Done()
|
|
|
|
err := server.Shutdown(context.Background())
|
|
if err != nil {
|
|
log.Print(err)
|
|
}
|
|
}()
|
|
|
|
log.Print("listening on ", s.config.ListenAddress)
|
|
|
|
err = server.ListenAndServe()
|
|
if err != http.ErrServerClosed {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s Server) createTables() error {
|
|
tables := []string{
|
|
`CREATE TABLE IF NOT EXISTS orders (
|
|
code TEXT PRIMARY KEY ON CONFLICT IGNORE
|
|
);
|
|
`,
|
|
}
|
|
|
|
tx, err := s.db.Begin()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, table := range tables {
|
|
_, err := tx.Exec(table)
|
|
if err != nil {
|
|
if err := tx.Rollback(); err != nil {
|
|
log.Print(err)
|
|
}
|
|
|
|
return err
|
|
}
|
|
}
|
|
|
|
err = tx.Commit()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s Server) buildURL(endpoint string, args ...any) string {
|
|
baseURL := strings.TrimSuffix(s.config.BaseURL, "/")
|
|
return fmt.Sprintf(endpoint, append([]any{baseURL}, args...)...)
|
|
}
|
|
|
|
func writeStatus(w http.ResponseWriter, code int) {
|
|
w.WriteHeader(code)
|
|
io.WriteString(w, http.StatusText(code))
|
|
}
|