package main import ( "html/template" "log" "nkode-icon-manager/internal" "nkode-icon-manager/templates" "os" "path/filepath" "strings" "time" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" ) type DeleteSelected struct { Svgs []string `json:"svgs" binding:"required"` } var upgrader = websocket.Upgrader{ ReadBufferSize: 1024, WriteBufferSize: 1024, } 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.GET("/ws", func(c *gin.Context) { conn, err := upgrader.Upgrade(c.Writer, c.Request, nil) if err != nil { log.Panicln("error upgrading ws: ", err) return } defer conn.Close() for { conn.WriteMessage(websocket.TextMessage, []byte("Hello Socket")) time.Sleep(time.Second) } }) router.GET("/ws-example", func(c *gin.Context) { c.HTML(200, "ws-example.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") }