thomas-shop/main.go

228 lines
5.3 KiB
Go
Raw Permalink Normal View History

2022-05-02 16:26:06 +02:00
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,
})
}
2022-06-08 16:53:49 +02:00
func getPage(name string) func(c *gin.Context) {
return func(c *gin.Context) {
c.HTML(http.StatusOK, name, map[string]interface{}{})
}
}
2022-05-02 16:26:06 +02:00
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"))
2022-07-07 10:40:30 +02:00
r.AddFromFilesFuncs("terms-and-conditions", f, path.Join(base, "base.html"), path.Join(base, "new_terms.html"))
2022-06-08 16:53:49 +02:00
r.AddFromFilesFuncs("terms-of-delivery", f, path.Join(base, "base.html"), path.Join(base, "terms-of-delivery.html"))
2022-05-02 16:26:06 +02:00
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()
})
2022-06-08 16:53:49 +02:00
if k, v := os.LookupEnv("RUN_STATIC"); v && k == "true" {
r.Static("/static", "./dist")
}
2022-05-02 16:26:06 +02:00
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)
2022-06-08 16:53:49 +02:00
r.GET("/terms-and-conditions", getPage("terms-and-conditions"))
r.GET("/terms-of-delivery", getPage("terms-of-delivery"))
2022-05-02 16:26:06 +02:00
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))
}