You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
262 lines
5.8 KiB
262 lines
5.8 KiB
package main
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"time"
|
|
|
|
// "github.com/joho/godotenv"
|
|
"html/template"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"strconv"
|
|
|
|
_ "github.com/go-sql-driver/mysql"
|
|
)
|
|
|
|
var db *sql.DB
|
|
|
|
// Check errors and fail if they're bad
|
|
func check(err error) {
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
// Get all the currently available hooks
|
|
func getHooks() []Hook {
|
|
rows, err := db.Query("SELECT ID FROM HOOKS")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
var hooks []Hook
|
|
for rows.Next() {
|
|
var hook Hook
|
|
err = rows.Scan(&hook.Name)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
hooks = append(hooks, hook)
|
|
}
|
|
return hooks
|
|
}
|
|
|
|
// Show the index
|
|
func index(w http.ResponseWriter, r *http.Request) {
|
|
log.Println(r.URL.String())
|
|
if r.URL.String() == "/" {
|
|
t := template.Must(template.New("index.tmpl").ParseFiles("html/index.tmpl"))
|
|
for i, j := range getHooks() {
|
|
log.Printf("%d: %s\n", i, j.Name)
|
|
}
|
|
err := t.Execute(w, getHooks())
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
} else {
|
|
http.ServeFile(w, r, "html/404.html")
|
|
}
|
|
}
|
|
|
|
//Run a particular hook (will probably come up with a better solution)
|
|
func runHook(w http.ResponseWriter, r *http.Request, hook Hook) {
|
|
fmt.Fprintln(w, hook.Name)
|
|
}
|
|
|
|
// Handles all of the hooks
|
|
func hookHandler(w http.ResponseWriter, r *http.Request) {
|
|
log.Println(r.URL.String())
|
|
name := r.URL.String()[len("/hook/"):]
|
|
|
|
row := db.QueryRow("SELECT EXISTS(SELECT id FROM HOOKS WHERE HOOKS.id = ?)", name)
|
|
var res int
|
|
row.Scan(&res)
|
|
if res == 0 {
|
|
http.ServeFile(w, r, "html/404.html")
|
|
return
|
|
}
|
|
hook := Hook{
|
|
Name: name,
|
|
params: nil,
|
|
actions: nil,
|
|
}
|
|
runHook(w, r, hook)
|
|
}
|
|
|
|
// Shows all of the hooks
|
|
func showHooks(w http.ResponseWriter, r *http.Request) {
|
|
log.Println(r.URL.String())
|
|
if r.URL.String() != "/hooks/" {
|
|
http.ServeFile(w, r, "html/404.html")
|
|
return
|
|
}
|
|
hooks := getHooks()
|
|
allHooks := ""
|
|
for _, h := range hooks {
|
|
allHooks += h.Name + "\n"
|
|
}
|
|
fmt.Fprint(w, allHooks)
|
|
}
|
|
|
|
// Creates a new hook
|
|
func createHook(w http.ResponseWriter, r *http.Request) {
|
|
log.Println(r.URL.String())
|
|
// Doesn't actually work yet
|
|
if r.URL.String() == "/hook/create/" {
|
|
http.ServeFile(w, r, "html/create.html")
|
|
return
|
|
}
|
|
// Create a hook
|
|
name := r.URL.String()[len("/hook/create/"):]
|
|
statement, err := db.Prepare("INSERT IGNORE INTO HOOKS(id) VALUES(?)")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
fmt.Fprintln(w, err)
|
|
return
|
|
}
|
|
defer statement.Close()
|
|
statement.Exec(name)
|
|
fmt.Fprintln(w, name)
|
|
}
|
|
|
|
// Delete one hook
|
|
func deleteHook(w http.ResponseWriter, r *http.Request) {
|
|
log.Println(r.URL.String())
|
|
name := r.URL.String()[len("/hook/delete/"):]
|
|
statement, err := db.Prepare("DELETE FROM HOOKS where ID=(?)")
|
|
if err != nil {
|
|
log.Println(err)
|
|
fmt.Fprintln(w, err)
|
|
return
|
|
}
|
|
defer statement.Close()
|
|
res, err := statement.Exec(name)
|
|
if err != nil {
|
|
log.Println(err)
|
|
fmt.Fprintln(w, err)
|
|
return
|
|
}
|
|
n, err := res.RowsAffected()
|
|
if err != nil {
|
|
log.Println(err)
|
|
fmt.Fprintln(w, err)
|
|
return
|
|
}
|
|
if n == 0 {
|
|
http.ServeFile(w, r, "html/404.html")
|
|
return
|
|
}
|
|
fmt.Fprintln(w, name)
|
|
// log.Println(cap(Hooks))
|
|
// //Clear hooks (this is perfectly safe to do)
|
|
// Hooks = nil
|
|
}
|
|
|
|
// func init() {
|
|
// // Loads values from .env into the system
|
|
// if err := godotenv.Load(); err != nil {
|
|
// log.Println("No .env file found")
|
|
// }
|
|
// }
|
|
|
|
func main() {
|
|
// Check if a value exists and fail if it doesn't
|
|
checkExists := func(exists bool, msg string) {
|
|
if !exists {
|
|
log.Fatal(msg)
|
|
}
|
|
}
|
|
|
|
// Get user credentials
|
|
user, exists := os.LookupEnv("MYSQL_USER")
|
|
checkExists(exists, "Couldn't find database user")
|
|
password, exists := os.LookupEnv("MYSQL_PASSWORD")
|
|
checkExists(exists, "Couldn't find database password")
|
|
|
|
// Get database params
|
|
dbServer, exists := os.LookupEnv("MYSQL_SERVER")
|
|
checkExists(exists, "Couldn't find database server")
|
|
dbPort, exists := os.LookupEnv("MYSQL_PORT")
|
|
checkExists(exists, "Couldn't find database port")
|
|
dbName, exists := os.LookupEnv("MYSQL_DATABASE")
|
|
checkExists(exists, "Couldn't find database name")
|
|
connectionString := fmt.Sprintf(
|
|
"%s:%s@tcp(%s:%s)/%s",
|
|
user,
|
|
password,
|
|
dbServer,
|
|
dbPort,
|
|
dbName,
|
|
)
|
|
|
|
// Check how many times to try the db before quitting
|
|
attemptsStr, exists := os.LookupEnv("DB_ATTEMPTS")
|
|
if !exists {
|
|
attemptsStr = "5"
|
|
}
|
|
attempts, err := strconv.Atoi(attemptsStr)
|
|
if err != nil {
|
|
attempts = 5
|
|
}
|
|
|
|
|
|
timeoutStr, exists := os.LookupEnv("DB_CONNECTION_TIMEOUT")
|
|
if !exists {
|
|
timeoutStr = "5"
|
|
}
|
|
timeout, err := strconv.Atoi(timeoutStr)
|
|
if err != nil {
|
|
timeout = 5
|
|
}
|
|
|
|
for i := 1; i <= attempts; i++ {
|
|
db, err = sql.Open("mysql", connectionString)
|
|
if err != nil && i != attempts {
|
|
log.Printf(
|
|
"WARNING: Could not connect to db on attempt %d. Trying again in %d seconds.\n",
|
|
attempts,
|
|
timeout,
|
|
)
|
|
} else if err != nil {
|
|
log.Fatalf("Could not connect to db after %d attempts\n", attempts)
|
|
}
|
|
time.Sleep(time.Duration(timeout) * time.Second)
|
|
}
|
|
log.Println("Connection to db succeeded!")
|
|
defer db.Close()
|
|
|
|
|
|
// Open the db and initialize the table if it doesn't exist
|
|
db, err = sql.Open("mysql", connectionString)
|
|
|
|
//// DEBUG: Making sure table is good
|
|
// if err := dropDB(db); err != nil {
|
|
// log.Fatal(err)
|
|
// }
|
|
|
|
// Create database if it doesn't exist
|
|
if err := createDB(db); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// Get listen address and port
|
|
addr, exists := os.LookupEnv("LISTEN")
|
|
checkExists(exists, "Couldn't find listen address")
|
|
port, exists := os.LookupEnv("PORT")
|
|
checkExists(exists, "Couldn't find port")
|
|
|
|
// Handle hooks
|
|
http.HandleFunc("/hook/delete/", deleteHook)
|
|
http.HandleFunc("/hook/create/", createHook)
|
|
http.HandleFunc("/hook/", hookHandler)
|
|
http.HandleFunc("/hooks/", showHooks)
|
|
http.HandleFunc("/", index)
|
|
http.Handle("/css/", http.StripPrefix("/css/", http.FileServer(http.Dir("html/css"))))
|
|
|
|
// Start the server
|
|
log.Println("Starting server")
|
|
log.Fatal(http.ListenAndServe(addr+":"+port, nil))
|
|
}
|