summaryrefslogtreecommitdiff
path: root/cmd/home
diff options
context:
space:
mode:
authora73x <[email protected]>2024-08-25 15:14:42 +0100
committera73x <[email protected]>2024-08-25 15:14:42 +0100
commitffdc0a5c34a0b78cec776049efde074147112ae5 (patch)
tree8b0a644790c630b0d5ae0512073d2566b87314ca /cmd/home
parent92a974b622f26645579e51c946a1266862384002 (diff)
feat: ssh access
Diffstat (limited to 'cmd/home')
-rw-r--r--cmd/home/main.go213
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)
}
}