228 lines
5.3 KiB
Go
228 lines
5.3 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"html/template"
|
|
"io/ioutil"
|
|
"log"
|
|
"net"
|
|
"net/http"
|
|
"os"
|
|
"os/signal"
|
|
"path"
|
|
"time"
|
|
|
|
"github.com/VictorAvelar/mollie-api-go/v3/mollie"
|
|
"github.com/gin-contrib/multitemplate"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
yaml "gopkg.in/yaml.v2"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// var SOCKNAME = "thomas.sock"
|
|
var addr = "0.0.0.0:3000"
|
|
|
|
type Config struct {
|
|
MollieToken string `yaml:"mollie_token"`
|
|
MollieTesting bool `yaml:"mollie_testing"`
|
|
MollieWebhook string `yaml:"mollie_webhook"`
|
|
MollieRedirectURL string `yaml:"mollie_redirect_url"`
|
|
MailServer string `yaml:"mail_server"`
|
|
MailPort int `yaml:"mail_port"`
|
|
MailUser string `yaml:"mail_user"`
|
|
MailPass string `yaml:"mail_pass"`
|
|
FromAddr string `yaml:"from_addr"`
|
|
BCC string `yaml:"bcc"`
|
|
}
|
|
|
|
var config Config
|
|
|
|
var mollieClient *mollie.Client
|
|
|
|
var ROOT_DIR string
|
|
|
|
func notFound(w http.ResponseWriter, r *http.Request) error {
|
|
w.WriteHeader(http.StatusNotFound)
|
|
|
|
t, err := template.ParseFiles(path.Join(ROOT_DIR, "templates/404.html"))
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return t.Execute(w, nil)
|
|
}
|
|
|
|
func index(c *gin.Context) {
|
|
db := getDB(c)
|
|
|
|
products := []Product{}
|
|
|
|
db.Order("id desc").Find(&products)
|
|
|
|
c.HTML(http.StatusOK, "index", map[string]interface{}{
|
|
"products": products,
|
|
})
|
|
}
|
|
|
|
func getPage(name string) func(c *gin.Context) {
|
|
return func(c *gin.Context) {
|
|
c.HTML(http.StatusOK, name, map[string]interface{}{})
|
|
}
|
|
}
|
|
|
|
func handle404(c *gin.Context) {
|
|
c.HTML(http.StatusOK, "404.html", map[string]interface{}{})
|
|
}
|
|
|
|
func createSocket(s string) net.Listener {
|
|
os.Remove(s)
|
|
|
|
log.Println("Creating UNIX socket:", s)
|
|
sock, err := net.Listen("unix", s)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
err = os.Chmod(s, 0777)
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return sock
|
|
}
|
|
|
|
func getDB(c *gin.Context) *gorm.DB {
|
|
item, _ := c.Get("db")
|
|
db := item.(*gorm.DB)
|
|
|
|
return db
|
|
}
|
|
|
|
func getProd(id uint, products []Product) *Product {
|
|
for _, prod := range products {
|
|
if prod.ID == id {
|
|
return &prod
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func createMyRender(base string) multitemplate.Renderer {
|
|
r := multitemplate.NewRenderer()
|
|
|
|
f := template.FuncMap{
|
|
"formatMoney": func(cents int) string {
|
|
return fmt.Sprintf("€%.2f", float64(float64(cents)/100))
|
|
},
|
|
"mult": func(x, y int) int {
|
|
return x * y
|
|
},
|
|
"plus": func(a, b int) int {
|
|
return a + b
|
|
},
|
|
"total": func(a Product, ac int, b Product, bc int, c Product, cc int) int {
|
|
return a.Price*ac + b.Price*bc + c.Price*cc
|
|
},
|
|
"nowYear": func() string {
|
|
return time.Now().Format("2006")
|
|
},
|
|
"getProd": getProd,
|
|
"countries": func() map[string]string {
|
|
return countries
|
|
},
|
|
"menu": func() []MenuItem {
|
|
return getMenuItems()
|
|
},
|
|
}
|
|
|
|
r.AddFromFilesFuncs("404.html", f, path.Join(base, "base.html"), path.Join(base, "404.html"))
|
|
r.AddFromFilesFuncs("index", f, path.Join(base, "base.html"), path.Join(base, "index.html"))
|
|
r.AddFromFilesFuncs("orderInfo", f, path.Join(base, "base.html"), path.Join(base, "order_info.html"))
|
|
r.AddFromFilesFuncs("orderPending", f, path.Join(base, "base.html"), path.Join(base, "order_pending.html"))
|
|
r.AddFromFilesFuncs("orderThankyou", f, path.Join(base, "base.html"), path.Join(base, "order_thankyou.html"))
|
|
r.AddFromFilesFuncs("checkout", f, path.Join(base, "base.html"), path.Join(base, "order_checkout.html"))
|
|
r.AddFromFilesFuncs("terms-and-conditions", f, path.Join(base, "base.html"), path.Join(base, "terms-and-conditions.html"))
|
|
r.AddFromFilesFuncs("terms-of-delivery", f, path.Join(base, "base.html"), path.Join(base, "terms-of-delivery.html"))
|
|
|
|
return r
|
|
}
|
|
|
|
func main() {
|
|
if len(os.Args) > 1 {
|
|
ROOT_DIR = os.Args[1]
|
|
}
|
|
|
|
go func() {
|
|
getMenuItems()
|
|
}()
|
|
|
|
log.Printf("Running from with app root dir: %s\n", ROOT_DIR)
|
|
|
|
configPath := path.Join(ROOT_DIR, "data/config/config.yaml")
|
|
configBytes, err := ioutil.ReadFile(configPath)
|
|
|
|
if err != nil {
|
|
panic(fmt.Sprintf("Can't open config file at %s; %v", configPath, err))
|
|
}
|
|
|
|
if err := yaml.Unmarshal([]byte(configBytes), &config); err != nil {
|
|
panic(fmt.Sprintf("Can't parse config file at %s; %v", configPath, err))
|
|
}
|
|
|
|
if mollieClient, err = initMollie(); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
db := GetDB()
|
|
|
|
r := gin.Default()
|
|
r.HTMLRender = createMyRender(path.Join(ROOT_DIR, "templates"))
|
|
|
|
r.Use(func(c *gin.Context) {
|
|
c.Set("db", db)
|
|
c.Next()
|
|
})
|
|
|
|
if k, v := os.LookupEnv("RUN_STATIC"); v && k == "true" {
|
|
r.Static("/static", "./dist")
|
|
}
|
|
|
|
r.GET("/", index)
|
|
r.POST("/order", postGetOrderInfo)
|
|
r.GET("/order", index)
|
|
r.POST("/order/checkout", postCheckout)
|
|
r.POST("/order/create-order", createOrder)
|
|
r.POST("/order/webhook", postMollieWebhook)
|
|
r.GET("/order/thankyou", getPreOrderThankYou)
|
|
r.POST("/order/retry/:orderid", postOrderRetry)
|
|
r.GET("/order/pending/:orderid", getPendingOrder)
|
|
r.GET("/terms-and-conditions", getPage("terms-and-conditions"))
|
|
r.GET("/terms-of-delivery", getPage("terms-of-delivery"))
|
|
r.NoRoute(handle404)
|
|
|
|
// sockPath := path.Join(ROOT_DIR, "run", SOCKNAME)
|
|
// sock := createSocket(sockPath)
|
|
|
|
server := http.Server{
|
|
Handler: r,
|
|
Addr: addr,
|
|
}
|
|
|
|
fmt.Println("Running...")
|
|
go func() {
|
|
log.Fatal(server.ListenAndServe())
|
|
}()
|
|
|
|
c := make(chan os.Signal, 1)
|
|
signal.Notify(c, os.Interrupt)
|
|
|
|
// Block until a signal is received.
|
|
<-c
|
|
fmt.Println("Stopping...")
|
|
// os.Remove(path.Join(ROOT_DIR, "run", SOCKNAME))
|
|
}
|