diff --git a/app.go b/app.go index 7fec710..62b8f7b 100644 --- a/app.go +++ b/app.go @@ -1,11 +1,21 @@ package main import ( + "bytes" "context" + "fmt" + "io" + "io/ioutil" + "log" + "net/http" + "os" + "os/user" + "path/filepath" "varia.zone/snackbar/components" "github.com/a-h/templ" + "github.com/codeclysm/extract/v3" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" ) @@ -24,23 +34,107 @@ func (a *App) startup(ctx context.Context) { a.ctx = ctx } -func (a App) domReady(ctx context.Context) { +func ensureDataDir(homeDir string) error { + paths := []string{ + filepath.Join(homeDir, ".local"), + filepath.Join(homeDir, ".local", "snackbar"), + filepath.Join(homeDir, ".local", "snackbar", "hugo"), + filepath.Join(homeDir, ".local", "snackbar", "sites"), + } + + for _, fpath := range paths { + if _, err := os.Stat(fpath); err != nil && os.IsNotExist(err) { + if err := os.Mkdir(fpath, 0764); err != nil { + return err + } + } + } + + return nil +} + +func ensureHugoBin(homeDir string) error { + hugoVersion := "0.124.1" + dataDir := filepath.Join(homeDir, ".local", "snackbar") + hugoDir := filepath.Join(dataDir, "hugo") + hugoBinPath := filepath.Join(hugoDir, "hugo") + hugoTarPath := filepath.Join(hugoDir, fmt.Sprintf("hugo-%s.tar.gz", hugoVersion)) + url := fmt.Sprintf("https://github.com/gohugoio/hugo/releases/download/v%s/hugo_extended_%s_linux-amd64.tar.gz", hugoVersion, hugoVersion) + + if _, err := os.Stat(hugoBinPath); err != nil && os.IsNotExist(err) { + if err := httpGetFile(hugoTarPath, url); err != nil { + return err + } + } + + fpath, err := ioutil.ReadFile(hugoTarPath) + if err != nil { + return err + } + if err := extract.Gz(context.TODO(), bytes.NewBuffer(fpath), hugoDir, nil); err != nil { + return err + } + + return nil +} + +func httpGetFile(filepath, url string) error { + out, err := os.Create(filepath) + if err != nil { + return err + } + defer out.Close() + + resp, err := http.Get(url) + if err != nil { + return err + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return err + } + + _, err = io.Copy(out, resp.Body) + if err != nil { + return err + } + + return nil } -func (a *App) beforeClose(ctx context.Context) (prevent bool) { - return false +func initialise(w http.ResponseWriter, r *http.Request) { + usr, err := user.Current() + if err != nil { + w.Write([]byte(fmt.Sprintf("unable to determine user: %s", err))) + } + + if err := ensureDataDir(usr.HomeDir); err != nil { + w.Write([]byte(fmt.Sprintf("unable to create data directory: %s", err))) + } + + if err := ensureHugoBin(usr.HomeDir); err != nil { + w.Write([]byte(fmt.Sprintf("unable to download hugo binary: %s", err))) + } + + // TODO: is there a Hugo site already? + + templ.Handler(components.NewSiteInput()).ServeHTTP(w, r) } -func (a *App) shutdown(ctx context.Context) { +func hugoNewSite(w http.ResponseWriter, r *http.Request) { + log.Printf("NEW SITE BEING CREATED: %s", r.FormValue("site-name")) } // NewRouter creates a new web router. func NewRouter() *chi.Mux { router := chi.NewRouter() + router.Use(middleware.Logger) router.Use(middleware.Recoverer) - router.Get("/", templ.Handler(components.NewSiteForm("/")).ServeHTTP) + router.Get("/init", initialise) + router.Post("/hugo/new", hugoNewSite) return router } diff --git a/components/templates.templ b/components/templates.templ index 4614303..4a6e5a4 100644 --- a/components/templates.templ +++ b/components/templates.templ @@ -1,33 +1,11 @@ package components -import "net/http" - -templ TextInput(name string, placeholder string, method string, endpoint string, hxTrigger string) { - -} - -templ NewSiteForm(endpoint string) { -