From adc08c3bc4c3106a9e7d20fcb00b9e5757cee1a5 Mon Sep 17 00:00:00 2001 From: Nate Meyer <672246+notnmeyer@users.noreply.github.com> Date: Tue, 9 Jul 2024 19:30:58 -0700 Subject: [PATCH 1/8] move the output format validation to a more logical spot --- cmd/show.go | 19 +++++++++++-- internal/output-formatter/output-formatter.go | 28 ++----------------- 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/cmd/show.go b/cmd/show.go index a21ab97..f1c7c02 100644 --- a/cmd/show.go +++ b/cmd/show.go @@ -8,8 +8,10 @@ import ( "github.com/spf13/cobra" ) -type ShowConfig struct { - Output string +var outputFormats = []string{ + "markdown", "md", + "text", + "web", } var showCmd = &cobra.Command{ @@ -27,6 +29,10 @@ var showCmd = &cobra.Command{ log.Fatalf(err.Error()) } + if !validOutputFormat(format) { + log.Fatalf("output must be one of %v\n", outputFormats) + } + logContents, err := dl.Show(format) if err != nil { log.Fatalf(err.Error()) @@ -40,3 +46,12 @@ func init() { rootCmd.AddCommand(showCmd) showCmd.PersistentFlags().StringP("output", "o", "markdown", "Format output") } + +func validOutputFormat(format string) bool { + for _, v := range outputFormats { + if v == format { + return true + } + } + return false +} diff --git a/internal/output-formatter/output-formatter.go b/internal/output-formatter/output-formatter.go index 6199155..6ae360c 100644 --- a/internal/output-formatter/output-formatter.go +++ b/internal/output-formatter/output-formatter.go @@ -1,25 +1,16 @@ package outputFormatter import ( - "fmt" - "github.com/charmbracelet/glamour" ) -var MarkdownFormats = []string{ +var OutputFormats = []string{ "markdown", "md", -} - -var OutputFormats = append( - MarkdownFormats, "text", -) + "web", +} func Format(format, content string) (string, error) { - if !contains(OutputFormats, format) { - return "", fmt.Errorf("output must be one of %v\n", OutputFormats) - } - switch format { case "markdown", "md": renderer, _ := glamour.NewTermRenderer( @@ -36,16 +27,3 @@ func Format(format, content string) (string, error) { return content, nil } - -func isMarkdownFormat() { - -} - -func contains(list []string, item string) bool { - for _, val := range list { - if val == item { - return true - } - } - return false -} From 699c7019e074069152e3a68d65e8719b4f02b924 Mon Sep 17 00:00:00 2001 From: Nate Meyer <672246+notnmeyer@users.noreply.github.com> Date: Tue, 9 Jul 2024 21:14:23 -0700 Subject: [PATCH 2/8] hack together some basic show-in-browser bits --- internal/daylog/daylog.go | 63 +++++++++++++++++++++++++++++++++++++++ templates/show.html | 40 +++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 templates/show.html diff --git a/internal/daylog/daylog.go b/internal/daylog/daylog.go index 947ef03..a7bf7bc 100644 --- a/internal/daylog/daylog.go +++ b/internal/daylog/daylog.go @@ -1,11 +1,17 @@ package daylog import ( + "encoding/base64" "fmt" + "log" + "net/http" "os" + "os/exec" "path/filepath" + "runtime" "strconv" "strings" + "sync" "time" "github.com/adrg/xdg" @@ -68,6 +74,26 @@ func (d *DayLog) Show(format string) (string, error) { return "", err } + if format == "web" { + fmt.Printf("opening %s in your browser...", d.Path) + + var wg sync.WaitGroup + wg.Add(1) + + // start the server in a goroutine + go startServer(&wg) + + // build the url and open it in a browser + data := base64.StdEncoding.EncodeToString([]byte(contents)) + url := fmt.Sprintf("http://localhost:8000/show?content=%s", data) + open(url) + + // wait until the request has been served + wg.Wait() + + return "", nil + } + contents, err = outputFormatter.Format(format, contents) if err != nil { return "", err @@ -76,6 +102,43 @@ func (d *DayLog) Show(format string) (string, error) { return contents, nil } +// TODO: relocate this +func startServer(wg *sync.WaitGroup) { + server := &http.Server{Addr: ":8000"} + dir, err := os.Getwd() + if err != nil { + log.Fatal(err) + } + + http.HandleFunc("/show", func(w http.ResponseWriter, r *http.Request) { + defer wg.Done() + http.ServeFile(w, r, filepath.Join(dir, "templates/show.html")) + }) + + if err := server.ListenAndServe(); err != http.ErrServerClosed { + log.Fatalf("ListenAndServe(): %v", err) + } +} + +// TODO: relocate this +func open(url string) { + var err error + switch runtime.GOOS { + case "linux": + err = exec.Command("xdg-open", url).Start() + case "windows": + err = exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start() + case "darwin": + err = exec.Command("open", url).Start() + default: + log.Fatalf("Unsupported platform") + } + + if err != nil { + log.Fatalf("Error opening URL in default browser: %v", err) + } +} + // returns the complete path to log file func logPath(path string, year, month, day int) (string, error) { path, err := createDir( diff --git a/templates/show.html b/templates/show.html new file mode 100644 index 0000000..4cf5e83 --- /dev/null +++ b/templates/show.html @@ -0,0 +1,40 @@ + + + + + + Markdown Renderer + + + + +
+ + + From b8bb8a8c2e4dc1f67b8e6f3f0ee763a2bdfb9a47 Mon Sep 17 00:00:00 2001 From: Nate Meyer <672246+notnmeyer@users.noreply.github.com> Date: Wed, 10 Jul 2024 21:56:53 -0700 Subject: [PATCH 3/8] embed html in app --- internal/daylog/daylog.go | 61 +++++++------------ internal/server/server.go | 32 ++++++++++ .../server/templates}/show.html | 1 + 3 files changed, 55 insertions(+), 39 deletions(-) create mode 100644 internal/server/server.go rename {templates => internal/server/templates}/show.html (99%) diff --git a/internal/daylog/daylog.go b/internal/daylog/daylog.go index a7bf7bc..64793e3 100644 --- a/internal/daylog/daylog.go +++ b/internal/daylog/daylog.go @@ -4,7 +4,6 @@ import ( "encoding/base64" "fmt" "log" - "net/http" "os" "os/exec" "path/filepath" @@ -18,6 +17,7 @@ import ( "github.com/markusmobius/go-dateparser" "github.com/notnmeyer/daylog-cli/internal/editor" "github.com/notnmeyer/daylog-cli/internal/output-formatter" + "github.com/notnmeyer/daylog-cli/internal/server" ) type DayLog struct { @@ -81,11 +81,12 @@ func (d *DayLog) Show(format string) (string, error) { wg.Add(1) // start the server in a goroutine - go startServer(&wg) + go server.Start(&wg) // build the url and open it in a browser data := base64.StdEncoding.EncodeToString([]byte(contents)) url := fmt.Sprintf("http://localhost:8000/show?content=%s", data) + fmt.Println(url) open(url) // wait until the request has been served @@ -102,43 +103,6 @@ func (d *DayLog) Show(format string) (string, error) { return contents, nil } -// TODO: relocate this -func startServer(wg *sync.WaitGroup) { - server := &http.Server{Addr: ":8000"} - dir, err := os.Getwd() - if err != nil { - log.Fatal(err) - } - - http.HandleFunc("/show", func(w http.ResponseWriter, r *http.Request) { - defer wg.Done() - http.ServeFile(w, r, filepath.Join(dir, "templates/show.html")) - }) - - if err := server.ListenAndServe(); err != http.ErrServerClosed { - log.Fatalf("ListenAndServe(): %v", err) - } -} - -// TODO: relocate this -func open(url string) { - var err error - switch runtime.GOOS { - case "linux": - err = exec.Command("xdg-open", url).Start() - case "windows": - err = exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start() - case "darwin": - err = exec.Command("open", url).Start() - default: - log.Fatalf("Unsupported platform") - } - - if err != nil { - log.Fatalf("Error opening URL in default browser: %v", err) - } -} - // returns the complete path to log file func logPath(path string, year, month, day int) (string, error) { path, err := createDir( @@ -228,3 +192,22 @@ func createIfMissing(d *DayLog) error { return nil } + +// calls "open" or whatever the platform equivilent is on a url +func open(url string) { + var err error + switch runtime.GOOS { + case "linux": + err = exec.Command("xdg-open", url).Start() + case "windows": + err = exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start() + case "darwin": + err = exec.Command("open", url).Start() + default: + log.Fatalf("Unsupported platform") + } + + if err != nil { + log.Fatalf("Error opening URL in default browser: %v", err) + } +} diff --git a/internal/server/server.go b/internal/server/server.go new file mode 100644 index 0000000..ebf8046 --- /dev/null +++ b/internal/server/server.go @@ -0,0 +1,32 @@ +package server + +import ( + "embed" + "log" + "net/http" + "sync" +) + +//go:embed templates/show.html +var fs embed.FS + +func Start(wg *sync.WaitGroup) { + server := &http.Server{Addr: ":8000"} + + http.HandleFunc("/show", func(w http.ResponseWriter, r *http.Request) { + defer wg.Done() + + data, err := fs.ReadFile("templates/show.html") + if err != nil { + http.Error(w, "could not read embedded file", http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "text/html") + w.Write(data) + }) + + if err := server.ListenAndServe(); err != http.ErrServerClosed { + log.Fatalf("ListenAndServe(): %v", err) + } +} diff --git a/templates/show.html b/internal/server/templates/show.html similarity index 99% rename from templates/show.html rename to internal/server/templates/show.html index 4cf5e83..eb2ab9f 100644 --- a/templates/show.html +++ b/internal/server/templates/show.html @@ -5,6 +5,7 @@ Markdown Renderer + -
+