package main
import (
"fmt"
"html/template"
"io/ioutil"
"log"
"net"
"net/http"
"os"
"os/signal"
"path"
"time"
"github.com/VictorAvelar/mollie-api-go/mollie"
"gopkg.in/yaml.v2"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
)
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) {
events := getEvents("loveit")
tomEvents := getEvents("tom_waits")
c.HTML(http.StatusOK, "index.html", map[string]interface{}{
"events": events,
"tomEvents": tomEvents,
"nowYear": time.Now().Format("2006"),
})
}
func loveIt(c *gin.Context) {
c.Redirect(http.StatusFound, "/")
}
func albumsHandler(c *gin.Context) {
albums := getAlbums()
c.HTML(http.StatusOK, "albums.html", map[string]interface{}{
"nowYear": time.Now().Format("2006"),
"albums": albums,
})
}
func handle404(c *gin.Context) {
c.HTML(http.StatusOK, "404.html", map[string]interface{}{})
}
func songsHandler(c *gin.Context) {
albums := getAlbums()
albumTitle := c.Param("album")
songTitle := c.Param("song")
album, err := getAlbum(albums, albumTitle)
if err != nil {
c.HTML(http.StatusNotFound, "404.html", map[string]interface{}{})
return
}
song, err := getSong(album, songTitle)
if err != nil {
c.HTML(http.StatusNotFound, "404.html", map[string]interface{}{})
return
}
c.HTML(http.StatusOK, "song.html", map[string]interface{}{
"nowYear": time.Now().Format("2006"),
"album": album,
"song": song,
"albumTitle": albumTitle,
})
}
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 main() {
if len(os.Args) > 1 {
ROOT_DIR = os.Args[1]
} else {
ROOT_DIR = "/var/www/flipnew"
}
r := gin.New()
r.SetFuncMap(template.FuncMap{
"formatMoney": func(cents int) string {
return fmt.Sprintf("€%.2f", float64(float64(cents)/100))
},
})
log.Printf("Running from with app root dir: %s\n", ROOT_DIR)
db := GetDB()
defer db.Close()
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)
}
r.LoadHTMLGlob(path.Join(ROOT_DIR, "templates/*.html"))
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.GET("/albums", albumsHandler)
r.GET("/albums/:album/:song", songsHandler)
r.GET("/love-it", loveIt)
r.GET("/preorder", preorderIndex)
r.POST("/preorder", postCreateOrder)
r.POST("/preorder/bestellen", postGetOrderInfo)
r.POST("/preorder/webhook", postMollieWebhook)
r.GET("/preorder/bedankt", getPreOrderThankYou)
r.POST("/preorder/retry/:orderid", postOrderRetry)
r.GET("/preorder/pending/:orderid", getPendingOrder)
r.NoRoute(handle404)
sockPath := path.Join(ROOT_DIR, "run/flip.sock")
sock := createSocket(sockPath)
server := http.Server{
Handler: r,
}
fmt.Println("Running...")
go func() {
log.Fatal(server.Serve(sock))
}()
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/flip.sock"))
}