diff options
| author | a73x <[email protected]> | 2024-08-25 15:14:42 +0100 |
|---|---|---|
| committer | a73x <[email protected]> | 2024-08-25 15:14:42 +0100 |
| commit | ffdc0a5c34a0b78cec776049efde074147112ae5 (patch) | |
| tree | 8b0a644790c630b0d5ae0512073d2566b87314ca /cmd | |
| parent | 92a974b622f26645579e51c946a1266862384002 (diff) | |
feat: ssh access
Diffstat (limited to 'cmd')
| -rw-r--r-- | cmd/home/main.go | 213 |
1 files changed, 43 insertions, 170 deletions
diff --git a/cmd/home/main.go b/cmd/home/main.go index 5a4573f..9585266 100644 --- a/cmd/home/main.go +++ b/cmd/home/main.go @@ -1,181 +1,54 @@ package main import ( - "bytes" - "fmt" - "io" - "io/fs" - "log" - "net/http" - "path/filepath" - "strings" - "text/template" + "context" + "errors" + "os" + "os/signal" + "syscall" "time" - "git.sr.ht/~a73x/home" - "github.com/yuin/goldmark" - "github.com/yuin/goldmark/parser" - "go.abhg.dev/goldmark/frontmatter" - "go.uber.org/zap" -) - -type CommonData struct { - Posts []PostData -} - -type PostData struct { - Title string - Path string -} - -func GeneratePosts(mux *http.ServeMux) ([]PostData, error) { - converter := goldmark.New( - goldmark.WithExtensions( - &frontmatter.Extender{}, - )) - - t, err := template.ParseFS(home.Content, "templates/layouts/*.html") - if err != nil { - return nil, fmt.Errorf("failed to parse layouts: %v", err) - } - - final := []PostData{} - posts, err := fs.Glob(home.Content, "posts/*.md") - if err != nil { - return nil, fmt.Errorf("failed to glob posts: %v", err) - } - - for _, post := range posts { - postName := filepath.Base(post) - postName = strings.Split(postName, ".")[0] + ".html" - - // parse markdown - input, err := fs.ReadFile(home.Content, post) - if err != nil { - return nil, fmt.Errorf("failed to read post: %v", err) - } - - var b bytes.Buffer - ctx := parser.NewContext() - if err := converter.Convert(input, &b, parser.WithContext(ctx)); err != nil { - return nil, err - } - - d := frontmatter.Get(ctx) - var meta map[string]string - if err := d.Decode(&meta); err != nil { - return nil, err - } - - foo, err := t.ParseFS(home.Content, "templates/post.html") - if err != nil { - return nil, fmt.Errorf("failed to parse post template: %v", err) - } - - content, err := io.ReadAll(&b) - if err != nil { - return nil, fmt.Errorf("failed to read post template: %v", err) - } - - type IPostData struct { - Title string - Post string - } - mux.HandleFunc("/posts/"+postName, func(w http.ResponseWriter, r *http.Request) { - if err := foo.ExecuteTemplate(w, "post.html", IPostData{ - Title: meta["title"], - Post: string(content), - }); err != nil { - fmt.Println(err) - } - }) - - final = append(final, PostData{ - Title: meta["title"], - Path: "posts/" + postName, - }) - } + "git.sr.ht/~a73x/home/tui" + "git.sr.ht/~a73x/home/web" - return final, nil -} - -func loadTemplates(mux *http.ServeMux, data any) error { - tmplFiles, err := fs.ReadDir(home.Content, "templates") - if err != nil { - return fmt.Errorf("failed to parse template layouts") - } - - for _, tmpl := range tmplFiles { - if tmpl.IsDir() { - continue - } + "github.com/charmbracelet/log" + "github.com/charmbracelet/ssh" +) - pt, err := template.ParseFS(home.Content, "templates/"+tmpl.Name(), "templates/layouts/*.html") - if err != nil { - return fmt.Errorf("failed to parse template "+tmpl.Name(), err) - } +const ( + port = "2222" +) - if tmpl.Name() == "index.html" { - mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - pt.ExecuteTemplate(w, tmpl.Name(), data) - }) - } else if tmpl.Name() == "page.html" { - continue - } else { - mux.HandleFunc("/"+tmpl.Name(), func(w http.ResponseWriter, r *http.Request) { - pt, err := template.ParseFS(home.Content, "templates/"+tmpl.Name(), "templates/layouts/*.html") - if err != nil { - fmt.Printf("failed to parse template "+tmpl.Name(), err) - } - pt.ExecuteTemplate(w, tmpl.Name(), data) - }) - } - } - return nil -} func main() { - logger, _ := zap.NewProduction() - loggingMiddleware := func(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - start := time.Now() - next.ServeHTTP(w, r) - logger.Info("request received", - zap.String("url", r.URL.Path), - zap.String("method", r.Method), - zap.Duration("duration", time.Since(start)), - zap.String("user-agent", r.UserAgent()), - ) - }) - } - - mux := http.NewServeMux() - postData, err := GeneratePosts(mux) - data := CommonData{ - Posts: postData, - } - - if err != nil { - log.Fatal("failed to generate posts", err) - } - - if err := loadTemplates(mux, data); err != nil { - log.Fatal("failed to parse templates", err) - } - - staticFs, err := fs.Sub(home.Content, "public/static") - if err != nil { - log.Fatal(err) - } - - mux.Handle("GET /static", http.FileServer(http.FS(staticFs))) - - server := http.Server{ - Addr: ":8080", - Handler: loggingMiddleware(mux), - } - - err = server.ListenAndServe() - if err != nil { - log.Fatal(err) + host := os.Getenv("DOMAIN") + if host == "" { + host = "localhost" + } + server, err := web.New() + + s, err := tui.New(host, port) + + done := make(chan os.Signal, 1) + signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) + log.Info("Starting SSH server", "host", host, "port", port) + go func() { + if err := server.ListenAndServe(); err != nil { + log.Error("fail running web server", "error", err) + } + done <- nil + }() + go func() { + if err = s.ListenAndServe(); err != nil && !errors.Is(err, ssh.ErrServerClosed) { + log.Error("Could not start server", "error", err) + done <- nil + } + }() + + <-done + log.Info("Stopping SSH server") + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer func() { cancel() }() + if err := s.Shutdown(ctx); err != nil && !errors.Is(err, ssh.ErrServerClosed) { + log.Error("Could not stop server", "error", err) } } |
