package main
import (
"html/template"
"log"
"nkode-icon-manager/internal"
"nkode-icon-manager/templates"
"os"
"path/filepath"
"strings"
"github.com/gin-gonic/gin"
)
type DeleteSelected struct {
Svgs []string `json:"svgs" binding:"required"`
}
func main() {
router := gin.Default()
funcMap := template.FuncMap{
"safeHTML": func(s string) template.HTML {
return template.HTML(s)
},
}
templ := template.New("app-templates").Funcs(funcMap)
templ = template.Must(templ.ParseFS(templates.TemplateFS, "*.html"))
router.SetHTMLTemplate(templ)
router.Static("/assets/", "./assets")
logger := log.Default()
approvePath := "/Users/donov/svgs/clean_nkode_icons/"
_ = os.MkdirAll(approvePath, 0766)
unresolvedPath := "/Users/donov/svgs/unresolved_icons/"
_ = os.MkdirAll(unresolvedPath, 0766)
rejectedPath := "/Users/donov/svgs/rejected_icons/"
_ = os.MkdirAll(rejectedPath, 0766)
currentSVG := ""
router.GET("/", func(c *gin.Context) {
c.HTML(200, "home.html", nil)
})
router.GET("/view-all-icons", func(c *gin.Context) {
data := struct {
SVGs []internal.SVGData
Path string
SVGCount int
}{
SVGs: nil,
Path: approvePath,
SVGCount: 0,
}
svgs, err := internal.GetSvgsFromPath(approvePath)
if err != nil {
logger.Println(err)
c.HTML(200, "view-all-icons.html", nil)
return
}
data.SVGs = svgs
data.SVGCount = len(svgs)
c.HTML(200, "view-all-icons.html", data)
})
router.GET("/approve-icon", func(c *gin.Context) {
svg, err := os.ReadFile(currentSVG)
if err != nil {
log.Fatalln("unable to read current svg: ", err)
}
data := struct {
SVG string
}{
SVG: string(svg),
}
c.HTML(200, "approve-icon.html", data)
})
router.GET("/create-icon", func(c *gin.Context) {
if currentSVG != "" {
c.Redirect(302, "/approve-icon")
}
c.HTML(200, "create-icon.html", nil)
})
router.POST("/prompt-icon", func(c *gin.Context) {
var form struct {
Prompt string `form:"prompt" binding:"required"`
}
if err := c.ShouldBind(&form); err != nil {
log.Println("error prompt icon: ", err)
c.String(400, "malformed form")
return
}
svgFilePath, err := internal.DownloadIcon(form.Prompt, unresolvedPath)
if err != nil {
log.Println("error prompt icon: ", err)
c.String(400, "download error")
return
}
currentSVG = svgFilePath
c.Redirect(302, "/approve-icon")
})
router.POST("/approve-icon", func(c *gin.Context) {
var form struct {
Approved string `form:"approved" binding:"required"`
}
if err := c.ShouldBind(&form); err != nil {
log.Println("error approve icon: ", err)
c.String(400, "malformed form")
return
}
splitPath := strings.Split(currentSVG, "/")
svgFile := splitPath[len(splitPath)-1]
splitSvgFile := strings.Split(svgFile, ".")
var movePath string
if form.Approved == "yes" {
movePath = approvePath
} else {
log.Println("approved: ", form.Approved)
movePath = rejectedPath
}
newSvgFilePath := internal.FindNoneCollisionFileName(splitSvgFile[0], "svg", movePath)
if err := os.Rename(currentSVG, newSvgFilePath); err != nil {
log.Fatalln("err moving svg: ", err)
}
currentSVG = ""
c.Redirect(302, "/create-icon")
})
router.POST("/delete-selected", func(c *gin.Context) {
svgs := DeleteSelected{}
if err := c.ShouldBindBodyWithJSON(&svgs); err != nil {
log.Println("json body didn't bind ", err)
c.String(400, "err with json body")
return
}
// TODO: this is very insecure. a real implementation needs to sanitize inputs
for _, svg := range svgs.Svgs {
log.Println("removing: ", svg)
if err := os.Remove(filepath.Join(approvePath, svg)); err != nil {
log.Println("error removing: ", svg, " with error ", err)
}
}
c.Redirect(302, "/")
})
router.Run(":5155")
}