aeth 2 months ago
parent
commit
462c00fd75

+ 3 - 4
.gitignore

@@ -1,15 +1,14 @@
 # ignoring environment variable file
 *.env
+*.env.template
 
 # everything in the build directory
-build/linux/webserver/*
-build/linux/seed/*
+build/linux/keiji/*
+build/linux/keiji-ctl/*
 
 html/assets/images/*
 html/
 
-# db seed data
-db_seed/*
 
 sqlite.db
 

+ 11 - 10
cmd/keiji-ctl/keiji-ctl.go

@@ -12,15 +12,16 @@ import (
 	"os"
 	"path"
 
+	"git.aetherial.dev/aeth/keiji/pkg/auth"
 	"git.aetherial.dev/aeth/keiji/pkg/controller"
-	"git.aetherial.dev/aeth/keiji/pkg/helpers"
+	"git.aetherial.dev/aeth/keiji/pkg/storage"
 	_ "github.com/mattn/go-sqlite3"
 )
 
 // authenticate and get the cookie needed to make updates
-func auth(url, username, password string) *http.Cookie {
+func authenticate(url, username, password string) *http.Cookie {
 	client := http.Client{}
-	b, _ := json.Marshal(helpers.Credentials{Username: username, Password: password})
+	b, _ := json.Marshal(auth.Credentials{Username: username, Password: password})
 	req, _ := http.NewRequest(http.MethodPost, url, bytes.NewReader(b))
 	req.Header.Add("Content-Type", "application/json")
 	resp, err := client.Do(req)
@@ -82,7 +83,7 @@ func main() {
 
 	switch cmd {
 	case "auth":
-		cookie := auth(fmt.Sprintf("%s/login", address), os.Getenv("KEIJI_USERNAME"), os.Getenv("KEIJI_PASSWORD"))
+		cookie := authenticate(fmt.Sprintf("%s/login", address), os.Getenv("KEIJI_USERNAME"), os.Getenv("KEIJI_PASSWORD"))
 		fmt.Println(cookie.Value)
 
 	case "asset":
@@ -91,7 +92,7 @@ func main() {
 			log.Fatal(err)
 		}
 		_, fileName := path.Split(pngFile)
-		item := helpers.Asset{
+		item := storage.Asset{
 			Name: fileName,
 			Data: b,
 		}
@@ -121,7 +122,7 @@ func main() {
 		}
 		_, fileName := path.Split(pngFile)
 		fmt.Println(fileName)
-		item := helpers.NavBarItem{
+		item := storage.NavBarItem{
 			Link:     fileName,
 			Redirect: redirect,
 			Png:      b,
@@ -144,7 +145,7 @@ func main() {
 		fmt.Println("png item upload successfully.")
 		os.Exit(0)
 	case "menu":
-		b, _ := json.Marshal(helpers.MenuLinkPair{LinkText: text, MenuLink: redirect})
+		b, _ := json.Marshal(storage.LinkPair{Text: text, Link: redirect})
 		req, _ := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/admin/menu", address), bytes.NewReader(b))
 		req.AddCookie(prepareCookie(address))
 		req.Header.Add("Content-Type", "application/json")
@@ -162,9 +163,9 @@ func main() {
 		fmt.Println("menu item uploaded successfully.")
 		os.Exit(0)
 	case "admin":
-		tables := make(map[string][]helpers.TableData)
-		adminPage := helpers.AdminPage{Tables: tables}
-		adminPage.Tables[col] = append(adminPage.Tables[col], helpers.TableData{Link: redirect, DisplayName: text})
+		tables := make(map[string][]storage.TableData)
+		adminPage := storage.AdminPage{Tables: tables}
+		adminPage.Tables[col] = append(adminPage.Tables[col], storage.TableData{Link: redirect, DisplayName: text})
 		b, _ := json.Marshal(adminPage)
 		req, _ := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/admin/panel", address), bytes.NewReader(b))
 		req.AddCookie(prepareCookie(address))

+ 35 - 22
cmd/keiji/keiji.go

@@ -8,37 +8,51 @@ import (
 	"log"
 	"os"
 	"path"
+	"strconv"
 
 	"github.com/gin-contrib/multitemplate"
 	"github.com/gin-gonic/gin"
 
 	"git.aetherial.dev/aeth/keiji/pkg/env"
-	"git.aetherial.dev/aeth/keiji/pkg/helpers"
 	"git.aetherial.dev/aeth/keiji/pkg/routes"
+	"git.aetherial.dev/aeth/keiji/pkg/storage"
 	"git.aetherial.dev/aeth/keiji/pkg/webpages"
 
 	_ "github.com/mattn/go-sqlite3"
 )
 
-var DOMAIN_NAME string
+var contentMode, envPath string
+var blank bool
+
+func printUsage() string {
+	return "wrong"
+}
 
 func main() {
-	embedPtr := flag.Bool("embed", false, "Force the server to serve embedded content, for production use")
-	fsPtr := flag.Bool("fs", false, "Force the server to serve embedded content, for production use")
-	envPtr := flag.String("env", ".env", "pass specific ..env file to the program startup")
+	flag.StringVar(&contentMode, "content", "", "pass the option to run the webserver using filesystem or embedded html")
+	flag.StringVar(&envPath, "env", ".env", "pass specific ..env file to the program startup")
+	flag.BoolVar(&blank, "blank", false, "create a blank .env template")
 	flag.Parse()
-	err := env.LoadAndVerifyEnv(*envPtr, env.REQUIRED_VARS)
+	if blank {
+		env.WriteTemplate(".env.template")
+		fmt.Println("Blank template written to: .env.template")
+		os.Exit(0)
+	}
+	err := env.LoadAndVerifyEnv(envPath, env.REQUIRED_VARS)
 	if err != nil {
 		log.Fatal("Error when loading env file: ", err)
 	}
 	var srcOpt webpages.ServiceOption
-	var htmlReader fs.FS
-	if *embedPtr == true {
-		srcOpt = webpages.EMBED
-	}
-	if *fsPtr == true {
+	switch contentMode {
+	case "fs":
 		srcOpt = webpages.FILESYSTEM
+	case "embed":
+		srcOpt = webpages.EMBED
+	default:
+		printUsage()
+		os.Exit(1)
 	}
+	var htmlReader fs.FS
 	htmlReader = webpages.NewContentLayer(srcOpt)
 	renderer := multitemplate.NewDynamic()
 	templateNames := []string{
@@ -55,13 +69,9 @@ func main() {
 		"writing",
 		"listing",
 	}
+	e := gin.Default()
 	if srcOpt == webpages.FILESYSTEM {
-		for i := range templateNames {
-			name := templateNames[i]
-			filePath := path.Join(os.Getenv("WEB_ROOT"), "html", fmt.Sprintf("%s.html", name))
-			fmt.Println(filePath)
-			renderer.AddFromFiles(name, filePath)
-		}
+		e.LoadHTMLGlob(path.Join(os.Getenv("WEB_ROOT"), "html", "*.html"))
 	} else {
 		for i := range templateNames {
 			name := templateNames[i]
@@ -70,21 +80,24 @@ func main() {
 				webpages.ReadToString(htmlReader, path.Join("html", name+".html")),
 			)
 		}
+		e.HTMLRender = renderer
 	}
-	e := gin.Default()
 	dbfile := "sqlite.db"
 	db, err := sql.Open("sqlite3", dbfile)
 	if err != nil {
 		log.Fatal(err)
 	}
-	e.HTMLRender = renderer
-	webserverDb := helpers.NewSQLiteRepo(db)
+	webserverDb := storage.NewSQLiteRepo(db)
 	err = webserverDb.Migrate()
 	if err != nil {
 		log.Fatal(err)
 	}
-	routes.Register(e, DOMAIN_NAME, webserverDb, htmlReader)
-	if os.Getenv("SSL_MODE") == "ON" {
+	routes.Register(e, os.Getenv("DOMAIN_NAME"), webserverDb, htmlReader)
+	ssl, err := strconv.ParseBool(os.Getenv("USE_SSL"))
+	if err != nil {
+		log.Fatal("Invalid option passed to USE_SSL: ", os.Getenv("USE_SSL"))
+	}
+	if ssl {
 		e.RunTLS(fmt.Sprintf("%s:%s", os.Getenv("HOST_ADDR"), os.Getenv("HOST_PORT")),
 			os.Getenv(env.CHAIN), os.Getenv(env.KEY))
 	}

+ 1 - 1
pkg/helpers/auth.go → pkg/auth/auth.go

@@ -1,4 +1,4 @@
-package helpers
+package auth
 
 import (
 	"os"

+ 10 - 9
pkg/controller/admin_handlers.go

@@ -3,7 +3,8 @@ package controller
 import (
 	"net/http"
 
-	"git.aetherial.dev/aeth/keiji/pkg/helpers"
+	"git.aetherial.dev/aeth/keiji/pkg/auth"
+	"git.aetherial.dev/aeth/keiji/pkg/storage"
 	"github.com/gin-gonic/gin"
 )
 
@@ -27,11 +28,11 @@ func (c *Controller) ServeLogin(ctx *gin.Context) {
 // @Name Auth
 // @Summary serves recieves admin user and pass, sets a cookie
 // @Tags admin
-// @Param cred body helpers.Credentials true "Admin Credentials"
+// @Param cred body storage.Credentials true "Admin Credentials"
 // @Router /login [post]
 func (c *Controller) Auth(ctx *gin.Context) {
 
-	var cred helpers.Credentials
+	var cred auth.Credentials
 
 	err := ctx.ShouldBind(&cred)
 	if err != nil {
@@ -40,7 +41,7 @@ func (c *Controller) Auth(ctx *gin.Context) {
 		})
 		return
 	}
-	cookie, err := helpers.Authorize(&cred, c.Cache)
+	cookie, err := auth.Authorize(&cred, c.Cache)
 	if err != nil {
 		ctx.JSON(400, map[string]string{
 			"Error": err.Error(),
@@ -66,8 +67,8 @@ func (c *Controller) Auth(ctx *gin.Context) {
 @Router /admin/panel
 */
 func (c *Controller) AddAdminTableEntry(ctx *gin.Context) {
-	tables := make(map[string][]helpers.TableData)
-	adminPage := helpers.AdminPage{Tables: tables}
+	tables := make(map[string][]storage.TableData)
+	adminPage := storage.AdminPage{Tables: tables}
 	err := ctx.ShouldBind(&adminPage)
 	if err != nil {
 		ctx.JSON(400, map[string]string{
@@ -97,7 +98,7 @@ func (c *Controller) AddAdminTableEntry(ctx *gin.Context) {
 @Router /admin/menu
 */
 func (c *Controller) AddMenuItem(ctx *gin.Context) {
-	var item helpers.MenuLinkPair
+	var item storage.LinkPair
 	err := ctx.ShouldBind(&item)
 	if err != nil {
 		ctx.JSON(400, map[string]string{
@@ -123,7 +124,7 @@ func (c *Controller) AddMenuItem(ctx *gin.Context) {
 */
 func (c *Controller) AddNavbarItem(ctx *gin.Context) {
 
-	var item helpers.NavBarItem
+	var item storage.NavBarItem
 	err := ctx.ShouldBind(&item)
 	if err != nil {
 		ctx.JSON(400, map[string]string{
@@ -157,7 +158,7 @@ func (c *Controller) AddNavbarItem(ctx *gin.Context) {
 @Router /admin/assets
 */
 func (c *Controller) AddAsset(ctx *gin.Context) {
-	var item helpers.Asset
+	var item storage.Asset
 	err := ctx.ShouldBind(&item)
 	if err != nil {
 		ctx.JSON(400, map[string]string{

+ 2 - 2
pkg/controller/cdn_handlers.go

@@ -8,7 +8,7 @@ import (
 	"path"
 	"strings"
 
-	"git.aetherial.dev/aeth/keiji/pkg/helpers"
+	"git.aetherial.dev/aeth/keiji/pkg/storage"
 	"github.com/gin-gonic/gin"
 )
 
@@ -23,7 +23,7 @@ func (c *Controller) ServeImage(ctx *gin.Context) {
 			"Error": "the requested file could not be found",
 		})
 	}
-	css := fmt.Sprintf("%s/%s", helpers.GetImageStore(), f)
+	css := fmt.Sprintf("%s/%s", storage.GetImageStore(), f)
 	b, err := os.ReadFile(css)
 	if err != nil {
 		ctx.JSON(500, map[string]string{

+ 13 - 13
pkg/controller/content_handlers.go

@@ -7,7 +7,7 @@ import (
 	"log"
 	"time"
 
-	"git.aetherial.dev/aeth/keiji/pkg/helpers"
+	"git.aetherial.dev/aeth/keiji/pkg/storage"
 	"github.com/gin-gonic/gin"
 )
 
@@ -15,12 +15,12 @@ import (
 Serves the admin panel with all of the documents in each blog category for editing
 */
 func (c *Controller) ServeBlogDirectory(ctx *gin.Context) {
-	tableData := helpers.AdminPage{Tables: map[string][]helpers.TableData{}}
-	for i := range helpers.Topics {
-		docs := c.database.GetByCategory(helpers.Topics[i])
+	tableData := storage.AdminPage{Tables: map[string][]storage.TableData{}}
+	for i := range storage.Topics {
+		docs := c.database.GetByCategory(storage.Topics[i])
 		for z := range docs {
-			tableData.Tables[helpers.Topics[i]] = append(tableData.Tables[helpers.Topics[i]],
-				helpers.TableData{
+			tableData.Tables[storage.Topics[i]] = append(tableData.Tables[storage.Topics[i]],
+				storage.TableData{
 					DisplayName: docs[z].Title,
 					Link:        fmt.Sprintf("/admin/options/%s", docs[z].Ident),
 				},
@@ -49,7 +49,7 @@ func (c *Controller) GetBlogPostEditor(ctx *gin.Context) {
 		})
 		return
 	}
-	doc, err := c.database.GetDocument(helpers.Identifier(post))
+	doc, err := c.database.GetDocument(storage.Identifier(post))
 	if err != nil {
 		ctx.JSON(500, map[string]string{
 			"Error": err.Error(),
@@ -62,7 +62,7 @@ func (c *Controller) GetBlogPostEditor(ctx *gin.Context) {
 			"headers": c.database.GetNavBarLinks(),
 		},
 		"Ident":        doc.Ident,
-		"Topics":       helpers.Topics,
+		"Topics":       storage.Topics,
 		"Title":        doc.Title,
 		"DefaultTopic": doc.Category,
 		"Created":      doc.Created,
@@ -74,7 +74,7 @@ func (c *Controller) GetBlogPostEditor(ctx *gin.Context) {
 Update an existing blog post
 */
 func (c *Controller) UpdateBlogPost(ctx *gin.Context) {
-	var doc helpers.Document
+	var doc storage.Document
 
 	err := ctx.ShouldBind(&doc)
 	if err != nil {
@@ -101,7 +101,7 @@ func (c *Controller) ServeNewBlogPage(ctx *gin.Context) {
 			"headers": c.database.GetNavBarLinks(),
 		},
 		"Post":    true,
-		"Topics":  helpers.Topics,
+		"Topics":  storage.Topics,
 		"Created": time.Now().UTC().String(),
 	})
 }
@@ -110,7 +110,7 @@ func (c *Controller) ServeNewBlogPage(ctx *gin.Context) {
 Reciever for the ServeNewBlogPage UI screen. Adds a new document to the database
 */
 func (c *Controller) MakeBlogPost(ctx *gin.Context) {
-	var doc helpers.Document
+	var doc storage.Document
 	err := ctx.ShouldBind(&doc)
 	if err != nil {
 		ctx.HTML(500, "upload_status", gin.H{"UpdateMessage": "Update Failed!", "Color": "red"})
@@ -141,7 +141,7 @@ func (c *Controller) ServeFileUpload(ctx *gin.Context) {
 Reciever for the page served to created a new visual media post
 */
 func (c *Controller) SaveFile(ctx *gin.Context) {
-	var img helpers.Image
+	var img storage.Image
 	err := ctx.ShouldBind(&img)
 	if err != nil {
 		ctx.HTML(500, "upload_status", gin.H{"UpdateMessage": err, "Color": "red"})
@@ -202,7 +202,7 @@ func (c *Controller) DeleteDocument(ctx *gin.Context) {
 		return
 
 	}
-	err := c.database.DeleteDocument(helpers.Identifier(id))
+	err := c.database.DeleteDocument(storage.Identifier(id))
 	if err != nil {
 		ctx.HTML(500, "upload_status", gin.H{"UpdateMessage": "Delete Failed!", "Color": "red"})
 		return

+ 7 - 5
pkg/controller/controller.go

@@ -3,18 +3,20 @@ package controller
 import (
 	"io/fs"
 
-	"git.aetherial.dev/aeth/keiji/pkg/helpers"
+	"git.aetherial.dev/aeth/keiji/pkg/auth"
+	"git.aetherial.dev/aeth/keiji/pkg/storage"
 )
 
 type Controller struct {
 	Domain   string
-	database helpers.DocumentIO
-	Cache    *helpers.AuthCache
+	database storage.DocumentIO
+	Cache    *auth.AuthCache
 	FileIO   fs.FS
 }
 
-func NewController(domain string, database helpers.DocumentIO, files fs.FS) *Controller {
-	return &Controller{Cache: helpers.NewCache(),
+func NewController(domain string, database storage.DocumentIO, files fs.FS) *Controller {
+	return &Controller{
+		Cache:    auth.NewCache(),
 		Domain:   domain,
 		database: database,
 		FileIO:   files,

+ 28 - 9
pkg/controller/html_handlers.go

@@ -4,10 +4,29 @@ import (
 	"html/template"
 	"net/http"
 
-	"git.aetherial.dev/aeth/keiji/pkg/helpers"
+	"git.aetherial.dev/aeth/keiji/pkg/storage"
 	"github.com/gin-gonic/gin"
+	"github.com/gomarkdown/markdown"
+	"github.com/gomarkdown/markdown/html"
+	"github.com/gomarkdown/markdown/parser"
 )
 
+/*
+	 convert markdown to html
+		:param md: the byte array containing the Markdown to convert
+*/
+func MdToHTML(md []byte) []byte {
+	extensions := parser.CommonExtensions | parser.AutoHeadingIDs | parser.NoEmptyLineBeforeBlock
+	p := parser.NewWithExtensions(extensions)
+	doc := p.Parse(md)
+
+	htmlFlags := html.CommonFlags | html.HrefTargetBlank
+	opts := html.RendererOptions{Flags: htmlFlags}
+	renderer := html.NewRenderer(opts)
+
+	return markdown.Render(doc, renderer)
+}
+
 // @Name ServePost
 // @Summary serves HTML files out of the HTML directory
 // @Tags webpages
@@ -20,14 +39,14 @@ func (c *Controller) ServePost(ctx *gin.Context) {
 		})
 		return
 	}
-	doc, err := c.database.GetDocument(helpers.Identifier(post))
+	doc, err := c.database.GetDocument(storage.Identifier(post))
 	if err != nil {
 		ctx.JSON(500, map[string]string{
 			"Error": err.Error(),
 		})
 		return
 	}
-	if doc.Category == helpers.CONFIGURATION {
+	if doc.Category == storage.CONFIGURATION {
 		ctx.Status(404)
 		return
 	}
@@ -38,7 +57,7 @@ func (c *Controller) ServePost(ctx *gin.Context) {
 		"Title":   doc.Title,
 		"Ident":   doc.Ident,
 		"Created": doc.Created,
-		"Body":    template.HTML(helpers.MdToHTML([]byte(doc.Body))),
+		"Body":    template.HTML(MdToHTML([]byte(doc.Body))),
 		"menu":    c.database.GetDropdownElements(),
 	})
 
@@ -49,10 +68,10 @@ func (c *Controller) ServePost(ctx *gin.Context) {
 // @Tags webpages
 // @Router / [get]
 func (c *Controller) ServeHome(ctx *gin.Context) {
-	home := c.database.GetByCategory(helpers.HOMEPAGE)
-	var content helpers.Document
+	home := c.database.GetByCategory(storage.HOMEPAGE)
+	var content storage.Document
 	if len(home) == 0 {
-		content = helpers.Document{
+		content = storage.Document{
 			Body: "Under construction. Sry :(",
 		}
 	} else {
@@ -72,7 +91,7 @@ func (c *Controller) ServeHome(ctx *gin.Context) {
 // @Tags webpages
 // @Router /blog [get]
 func (c *Controller) ServeBlog(ctx *gin.Context) {
-	ctx.HTML(http.StatusOK, "writing", c.database.GetByCategory(helpers.BLOG))
+	ctx.HTML(http.StatusOK, "writing", c.database.GetByCategory(storage.BLOG))
 }
 
 // @Name ServeCreative
@@ -80,7 +99,7 @@ func (c *Controller) ServeBlog(ctx *gin.Context) {
 // @Tags webpages
 // @Router /creative [get]
 func (c *Controller) ServeCreative(ctx *gin.Context) {
-	ctx.HTML(http.StatusOK, "writing", c.database.GetByCategory(helpers.CREATIVE))
+	ctx.HTML(http.StatusOK, "writing", c.database.GetByCategory(storage.CREATIVE))
 }
 
 // @Name ServeDigitalArt

+ 41 - 10
pkg/env/env.go

@@ -2,26 +2,33 @@ package env
 
 import (
 	"fmt"
+	"log"
 	"os"
 
 	"github.com/joho/godotenv"
 )
 
 const IMAGE_STORE = "IMAGE_STORE"
+const WEB_ROOT = "WEB_ROOT"
+const DOMAIN_NAME = "DOMAIN_NAME"
 const HOST_PORT = "HOST_PORT"
 const HOST_ADDR = "HOST_ADDR"
 const SSL_MODE = "SSL_MODE"
 const CHAIN = "CHAIN"
 const KEY = "KEY"
 
-var REQUIRED_VARS = []string{
-	IMAGE_STORE,
-	HOST_PORT,
-	HOST_ADDR,
-	CHAIN,
-	KEY,
-	SSL_MODE,
+var OPTION_VARS = map[string]string{
+	IMAGE_STORE: "#the location for keiji to store the images uploaded (string)",
+	WEB_ROOT:    "#the location to pull HTML and various web assets from. Only if using 'keiji -content fs' (string)",
+	CHAIN:       "#the path to the SSL public key chain (string)",
+	KEY:         "#the path to the SSL private key (string)",
+}
 
+var REQUIRED_VARS = map[string]string{
+	HOST_PORT:   "#the port to run the server on (int)",
+	HOST_ADDR:   "#the address for the server to listen on (string)",
+	DOMAIN_NAME: "#the servers domain name, i.e. 'aetherial.dev', or 'localhost' (string)",
+	SSL_MODE:    "#chose to use SSL or not (boolean)",
 }
 
 type EnvNotSet struct {
@@ -33,10 +40,34 @@ func (e *EnvNotSet) Error() string {
 }
 
 /*
-  verify all environment vars passed in are set
-          :param vars: array of strings to verify
+Write out a blank .env configuration with the the required configuration (uncommented) and the
+optional configuration (commented out)
+
+	:param path: the path to write the template to
+*/
+func WriteTemplate(path string) {
+	var out string
+	out = out + "####### Required Configuration #######\n"
+	for k, v := range REQUIRED_VARS {
+		out = out + fmt.Sprintf("%s\n%s=\n", v, k)
+	}
+	out = out + "\n####### Optional Configuration #######\n"
+	for k, v := range OPTION_VARS {
+		out = out + fmt.Sprintf("# %s\n# %s=\n", v, k)
+	}
+	err := os.WriteFile(path, []byte(out), os.ModePerm)
+	if err != nil {
+		log.Fatal("Failed to write file: ", err)
+	}
+
+}
+
+/*
+verify all environment vars passed in are set
+
+	:param vars: array of strings to verify
 */
-func LoadAndVerifyEnv(path string, vars []string) error {
+func LoadAndVerifyEnv(path string, vars map[string]string) error {
 
 	err := godotenv.Load(path)
 	if err != nil {

+ 0 - 74
pkg/helpers/helpers.go

@@ -1,74 +0,0 @@
-package helpers
-
-import (
-	"github.com/gomarkdown/markdown"
-	"github.com/gomarkdown/markdown/html"
-	"github.com/gomarkdown/markdown/parser"
-)
-
-const TECHNICAL = "technical"
-const CONFIGURATION = "configuration"
-const BLOG = "blog"
-const CREATIVE = "creative"
-const DIGITAL_ART = "digital_art"
-const HOMEPAGE = "homepage"
-
-var Topics = []string{
-	TECHNICAL,
-	BLOG,
-	CREATIVE,
-	HOMEPAGE,
-}
-
-type HeaderCollection struct {
-	Category string       `json:"category"`
-	Elements []HeaderElem `json:"elements"`
-}
-
-type HeaderElem struct {
-	Png  string `json:"png"`
-	Link string `json:"link"`
-}
-
-type ImageElement struct {
-	ImgUrl string `json:"img_url"`
-}
-
-type MenuElement struct {
-	Png       string         `json:"png"`
-	Category  string         `json:"category"`
-	MenuLinks []MenuLinkPair `json:"menu_links"`
-}
-
-type DocumentOld struct {
-	Ident    Identifier `json:"identifier"`
-	Created  string     `json:"created"`
-	Body     string     `json:"body"`
-	Category string     `json:"category"`
-	Sample   string
-}
-
-type AdminPage struct {
-	Tables map[string][]TableData `json:"tables"`
-}
-
-type TableData struct { // TODO: add this to the database io interface
-	DisplayName string `json:"display_name"`
-	Link        string `json:"link"`
-}
-
-/*
-	 convert markdown to html
-		:param md: the byte array containing the Markdown to convert
-*/
-func MdToHTML(md []byte) []byte {
-	extensions := parser.CommonExtensions | parser.AutoHeadingIDs | parser.NoEmptyLineBeforeBlock
-	p := parser.NewWithExtensions(extensions)
-	doc := p.Parse(md)
-
-	htmlFlags := html.CommonFlags | html.HrefTargetBlank
-	opts := html.RendererOptions{Flags: htmlFlags}
-	renderer := html.NewRenderer(opts)
-
-	return markdown.Render(doc, renderer)
-}

+ 2 - 2
pkg/routes/register.go

@@ -4,11 +4,11 @@ import (
 	"io/fs"
 
 	"git.aetherial.dev/aeth/keiji/pkg/controller"
-	"git.aetherial.dev/aeth/keiji/pkg/helpers"
+	"git.aetherial.dev/aeth/keiji/pkg/storage"
 	"github.com/gin-gonic/gin"
 )
 
-func Register(e *gin.Engine, domain string, database helpers.DocumentIO, files fs.FS) {
+func Register(e *gin.Engine, domain string, database storage.DocumentIO, files fs.FS) {
 	c := controller.NewController(domain, database, files)
 	web := e.Group("")
 	web.GET("/", c.ServeHome)

+ 44 - 16
pkg/helpers/storage.go → pkg/storage/storage.go

@@ -1,4 +1,4 @@
-package helpers
+package storage
 
 import (
 	"database/sql"
@@ -15,6 +15,20 @@ import (
 	"github.com/google/uuid"
 )
 
+const TECHNICAL = "technical"
+const CONFIGURATION = "configuration"
+const BLOG = "blog"
+const CREATIVE = "creative"
+const DIGITAL_ART = "digital_art"
+const HOMEPAGE = "homepage"
+
+var Topics = []string{
+	TECHNICAL,
+	BLOG,
+	CREATIVE,
+	HOMEPAGE,
+}
+
 type DatabaseSchema struct {
 	// Gotta figure out what this looks like
 	// so that the ExtractAll() function gets
@@ -22,9 +36,23 @@ type DatabaseSchema struct {
 
 }
 
-type MenuLinkPair struct {
-	MenuLink string `json:"link"`
-	LinkText string `json:"text"`
+type MenuElement struct {
+	Png       string     `json:"png"`
+	Category  string     `json:"category"`
+	MenuLinks []LinkPair `json:"menu_links"`
+}
+type AdminPage struct {
+	Tables map[string][]TableData `json:"tables"`
+}
+
+type TableData struct { // TODO: add this to the database io interface
+	DisplayName string `json:"display_name"`
+	Link        string `json:"link"`
+}
+
+type LinkPair struct {
+	Link string `json:"link"`
+	Text string `json:"text"`
 }
 
 type NavBarItem struct {
@@ -89,10 +117,10 @@ type DocumentIO interface {
 	AddAsset(name string, data []byte) error
 	AddAdminTableEntry(TableData, string) error
 	AddNavbarItem(NavBarItem) error
-	AddMenuItem(MenuLinkPair) error
+	AddMenuItem(LinkPair) error
 	GetByCategory(category string) []Document
 	AllDocuments() []Document
-	GetDropdownElements() []MenuLinkPair
+	GetDropdownElements() []LinkPair
 	GetNavBarLinks() []NavBarItem
 	GetAssets() []Asset
 	GetAdminTables() AdminPage
@@ -198,7 +226,7 @@ func (s *SQLiteRepo) Seed(menu string, pngs string, dir string) { // TODO: make
 			continue
 		}
 		info := strings.Split(entries[i], "=")
-		err := s.AddMenuItem(MenuLinkPair{MenuLink: info[0], LinkText: info[1]})
+		err := s.AddMenuItem(LinkPair{Link: info[0], Text: info[1]})
 		if err != nil {
 			log.Fatal(err)
 		}
@@ -241,16 +269,16 @@ func (s *SQLiteRepo) Seed(menu string, pngs string, dir string) { // TODO: make
 }
 
 /*
-Get all dropdown menu elements. Returns a list of MenuLinkPair structs with the text and redirect location
+Get all dropdown menu elements. Returns a list of LinkPair structs with the text and redirect location
 */
-func (s *SQLiteRepo) GetDropdownElements() []MenuLinkPair {
+func (s *SQLiteRepo) GetDropdownElements() []LinkPair {
 	rows, err := s.db.Query("SELECT * FROM menu")
-	var menuItems []MenuLinkPair
+	var menuItems []LinkPair
 	defer rows.Close()
 	for rows.Next() {
 		var id int
-		var item MenuLinkPair
-		err = rows.Scan(&id, &item.MenuLink, &item.LinkText)
+		var item LinkPair
+		err = rows.Scan(&id, &item.Link, &item.Text)
 		if err != nil {
 			log.Fatal(err)
 		}
@@ -471,17 +499,17 @@ func (s *SQLiteRepo) UpdateDocument(doc Document) error {
 }
 
 /*
-Adds a MenuLinkPair to the menu database table
+Adds a LinkPair to the menu database table
 
-	:param item: the MenuLinkPair to upload
+	:param item: the LinkPair to upload
 */
-func (s *SQLiteRepo) AddMenuItem(item MenuLinkPair) error {
+func (s *SQLiteRepo) AddMenuItem(item LinkPair) error {
 	tx, err := s.db.Begin()
 	if err != nil {
 		return err
 	}
 	stmt, _ := tx.Prepare("INSERT INTO menu(link, text) VALUES (?,?)")
-	_, err = stmt.Exec(item.MenuLink, item.LinkText)
+	_, err = stmt.Exec(item.Link, item.Text)
 	if err != nil {
 		tx.Rollback()
 		return err

+ 0 - 1
pkg/webpages/pages.go

@@ -52,7 +52,6 @@ Implementing the io.FS interface for interoperability
 */
 func (f FilesystemWebpages) Open(file string) (fs.File, error) {
 	filePath := path.Join(os.Getenv("WEB_ROOT"), file)
-	fmt.Println(filePath)
 	fh, err := os.Open(filePath)
 	if err != nil {
 		fmt.Printf("Error opening the file: %s because %s", filePath, err)