aboutsummaryrefslogtreecommitdiff
path: root/cmd/parser
diff options
context:
space:
mode:
authorSamuel Johnson <[email protected]>2025-11-23 23:52:30 -0500
committerSamuel Johnson <[email protected]>2025-11-23 23:52:30 -0500
commit1692aea0951f1d46af01211bd3e32920c443505f (patch)
tree07e8a77a2f3eb1852289ebb0ed63154c3329c5b0 /cmd/parser
parenta431c6737f230be70c0fa44e5b30337b044db6fb (diff)
Add markdown parsing endpoint
Diffstat (limited to 'cmd/parser')
-rw-r--r--cmd/parser/main.go109
1 files changed, 98 insertions, 11 deletions
diff --git a/cmd/parser/main.go b/cmd/parser/main.go
index 3933935..c9c80c8 100644
--- a/cmd/parser/main.go
+++ b/cmd/parser/main.go
@@ -2,48 +2,86 @@ package main
import (
"bytes"
+ "context"
+ "database/sql"
"fmt"
"log"
"net/http"
"os"
"strconv"
+ "time"
"github.com/joho/godotenv"
"github.com/yuin/goldmark"
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/renderer/html"
+ "golang.org/x/crypto/bcrypt"
+
+ _ "github.com/jackc/pgx/v5/stdlib"
)
+var db *sql.DB
var mdParser goldmark.Markdown
+func writeErr(w http.ResponseWriter, errcode int, msg string) {
+ w.WriteHeader(errcode)
+ w.Write([]byte(msg))
+ return
+}
+
func mdServe(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
- w.WriteHeader(405)
- w.Write([]byte("Method Not Allowed"))
+ writeErr(w, 405, "Method Not Allowed")
return
}
- err := r.ParseForm()
+ err := r.ParseMultipartForm(4 << 20)
if err != nil {
- w.WriteHeader(500)
- w.Write([]byte("Failed to retrieve form data"))
+ writeErr(w, 500, "Failed to retrieve form data")
return
}
var buf bytes.Buffer
-
- log.Print(r.Form)
+
md := r.PostForm.Get("raw")
- log.Print(md)
+
err = mdParser.Convert([]byte(md), &buf)
if err != nil {
- w.WriteHeader(500)
- w.Write([]byte("Failed to compile markdown into html"))
+ writeErr(w, 500, fmt.Sprintf("Failed to compile markdown into html: %v", err))
return
}
- w.Write([]byte(md))
+ ctx, cancel := context.WithTimeout(r.Context(), 5 * time.Second)
+ defer cancel()
+
+ tx, err := db.BeginTx(ctx, nil)
+ if err != nil {
+ writeErr(w, 500, fmt.Sprintf("Failed to initialize transaction: %v", err))
+ return
+ }
+ defer tx.Rollback()
+
+ stmt, err := tx.PrepareContext(ctx, "INSERT INTO posts (name, content) VALUES ($1, $2);")
+ if err != nil {
+ writeErr(w, 500, fmt.Sprintf("Failed to prepare DB statement: %v", err))
+ return
+ }
+ defer stmt.Close()
+
+ _, err = stmt.ExecContext(ctx, os.Getenv("webmaster"), buf.Bytes())
+ if err != nil {
+ writeErr(w, 500, fmt.Sprintf("Failed to execute statement: %v", err))
+ return
+ }
+
+ err = tx.Commit()
+ if err != nil {
+ writeErr(w, 500, fmt.Sprintf("Failed to commit DB transaction: %v", err))
+ }
+
+ w.WriteHeader(200)
+ w.Write([]byte("Successfully parsed and stored markdown"))
}
func main() {
@@ -66,6 +104,55 @@ func main() {
),
)
+ host := "localhost"
+ port := 5432
+ dbName := os.Getenv("db_name")
+ user := os.Getenv("db_user")
+ pass := os.Getenv("db_pass")
+ connStr := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", host, port, user, pass, dbName)
+
+ db, err = sql.Open("pgx", connStr)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Unable to connect to DB: %v\n", err)
+ os.Exit(1)
+ }
+ defer db.Close()
+
+ _, table_check := db.Query("SELECT * FROM posts;")
+ if table_check != nil {
+ _, err = db.Exec("CREATE TABLE posts (id SERIAL PRIMARY KEY, name VARCHAR(50) NOT NULL, time DATE DEFAULT CURRENT_DATE, content TEXT NOT NULL);")
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Unable to create posts table: %v\n", err)
+ os.Exit(1)
+ }
+ }
+
+ webmaster := os.Getenv("webmaster")
+ passOne := os.Getenv("blog_pass1")
+ passTwo := os.Getenv("blog_pass2")
+
+ _, table_check = db.Query("SELECT * FROM users;")
+ if table_check != nil {
+ _, err = db.Exec("CREATE TABLE logins (id SERIAL PRIMARY KEY, name VARCHAR(50) NOT NULL, time DATE DEFAULT CURRENT_DATE, pass_one TEXT NOT NULL, pass_two TEXT NOT NULL);")
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Unable to create logins table: %v\n", err)
+ os.Exit(1)
+ }
+
+ hashOne, errHashOne := bcrypt.GenerateFromPassword([]byte(passOne), 12)
+ hashTwo, errHashTwo := bcrypt.GenerateFromPassword([]byte(passTwo), 12)
+ if errHashOne != nil || errHashTwo != nil {
+ fmt.Fprintf(os.Stderr, "Failed to hash password")
+ os.Exit(1)
+ }
+
+ _, err = db.Exec(fmt.Sprintf("INSERT INTO logins (name, pass_one, pass_two) VALUES ('%s', '%s', '%s');", webmaster, hashOne, hashTwo))
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Unable to add webmaster to logins table: %v\n", err)
+ os.Exit(1)
+ }
+ }
+
router := http.NewServeMux()
router.HandleFunc("/", mdServe)