From cbf1a8f43966519fcfe68f7c53bfdfb220d61100 Mon Sep 17 00:00:00 2001 From: sloum Date: Tue, 21 Jan 2020 21:19:27 -0800 Subject: [PATCH] Uses goroutines for saving files and eliminates needless calls to DrawMessage --- client.go | 107 ++++++------------------------------------------------ 1 file changed, 12 insertions(+), 95 deletions(-) diff --git a/client.go b/client.go index ed642a2..6cf9be2 100644 --- a/client.go +++ b/client.go @@ -197,7 +197,6 @@ func (c *client) TakeControlInput() { err := c.PageState.NavigateHistory(-1) if err != nil { c.SetMessage(err.Error(), false) - c.DrawMessage() } else { c.SetHeaderUrl() c.SetPercentRead() @@ -208,7 +207,6 @@ func (c *client) TakeControlInput() { err := c.ReloadPage() if err != nil { c.SetMessage(err.Error(), false) - c.DrawMessage() } else { c.Draw() } @@ -222,7 +220,6 @@ func (c *client) TakeControlInput() { err := c.PageState.NavigateHistory(1) if err != nil { c.SetMessage(err.Error(), false) - c.DrawMessage() } else { c.SetHeaderUrl() c.SetPercentRead() @@ -238,7 +235,6 @@ func (c *client) TakeControlInput() { err := c.NextSearchItem(1) if err != nil { c.SetMessage(err.Error(), false) - c.DrawMessage() } case 'N': // Previous search item @@ -246,7 +242,6 @@ func (c *client) TakeControlInput() { err := c.NextSearchItem(-1) if err != nil { c.SetMessage(err.Error(), false) - c.DrawMessage() } case '/': // Search for text @@ -259,13 +254,11 @@ func (c *client) TakeControlInput() { c.ClearMessageLine() if err != nil { c.SetMessage(err.Error(), true) - c.DrawMessage() break } err = c.find(entry) if err != nil { c.SetMessage(err.Error(), true) - c.DrawMessage() } err = c.NextSearchItem(0) if err != nil { @@ -282,10 +275,9 @@ func (c *client) TakeControlInput() { c.ClearMessageLine() if err != nil { c.SetMessage(err.Error(), true) - c.DrawMessage() break } else if strings.TrimSpace(entry) == "" { - c.DrawMessage() + c.ClearMessage() break } @@ -293,12 +285,10 @@ func (c *client) TakeControlInput() { p, err := parser.Parse() if err != nil { c.SetMessage(err.Error(), true) - c.DrawMessage() } else { err := c.routeCommandInput(p) if err != nil { c.SetMessage(err.Error(), true) - c.DrawMessage() } } } @@ -335,10 +325,9 @@ func (c *client) simpleCommand(action string) { cui.Exit(0, "") case "H", "HOME": if c.Options["homeurl"] != "unset" { - go c.Visit(c.Options["homeurl"]) + c.Visit(c.Options["homeurl"]) } else { c.SetMessage(fmt.Sprintf("No home address has been set"), false) - c.DrawMessage() } case "B", "BOOKMARKS": c.BookMarks.ToggleOpen() @@ -348,24 +337,21 @@ func (c *client) simpleCommand(action string) { err := c.ReloadPage() if err != nil { c.SetMessage(err.Error(), false) - c.DrawMessage() } else { c.Draw() } case "SEARCH": c.search("", "", "?") case "HELP", "?": - go c.Visit(helplocation) + c.Visit(helplocation) default: c.SetMessage(fmt.Sprintf("Unknown action %q", action), true) - c.DrawMessage() } } func (c *client) doCommand(action string, values []string) { if length := len(values); length != 1 { c.SetMessage(fmt.Sprintf("Expected 1 argument, received %d", len(values)), true) - c.DrawMessage() return } @@ -376,20 +362,16 @@ func (c *client) doCommand(action string, values []string) { err := c.Certs.Purge(values[0]) if err != nil { c.SetMessage(err.Error(), true) - c.DrawMessage() return } if values[0] == "*" { c.SetMessage("All certificates have been purged", false) - c.DrawMessage() } else { c.SetMessage(fmt.Sprintf("The certificate for %q has been purged", strings.ToLower(values[0])), false) - c.DrawMessage() } err = saveConfig() if err != nil { c.SetMessage("Error saving purge to file", true) - c.DrawMessage() } case "SEARCH": c.search(values[0], "", "") @@ -400,7 +382,6 @@ func (c *client) doCommand(action string, values []string) { u, err := MakeUrl(values[0]) if err != nil { c.SetMessage(err.Error(), true) - c.DrawMessage() return } fns := strings.Split(u.Resource, "/") @@ -413,18 +394,15 @@ func (c *client) doCommand(action string, values []string) { if fn == "" { fn = "index" } - c.saveFile(u, fn) - + go c.saveFile(u, fn) default: c.SetMessage(fmt.Sprintf("Unknown action %q", action), true) - c.DrawMessage() } } func (c *client) doCommandAs(action string, values []string) { if len(values) < 2 { c.SetMessage(fmt.Sprintf("Expected 2+ arguments, received %d", len(values)), true) - c.DrawMessage() return } @@ -437,16 +415,13 @@ func (c *client) doCommandAs(action string, values []string) { msg, err := c.BookMarks.Add(values) if err != nil { c.SetMessage(err.Error(), true) - c.DrawMessage() return } c.SetMessage(msg, false) - c.DrawMessage() err = saveConfig() if err != nil { c.SetMessage("Error saving bookmark to file", true) - c.DrawMessage() } if c.BookMarks.IsOpen { c.Draw() @@ -458,7 +433,6 @@ func (c *client) doCommandAs(action string, values []string) { val := strings.Join(values[1:], " ") if !validateOpt(values[0], val) { c.SetMessage(fmt.Sprintf("Invalid setting for %q", values[0]), true) - c.DrawMessage() return } c.Options[values[0]] = lowerCaseOpt(values[0], val) @@ -466,13 +440,11 @@ func (c *client) doCommandAs(action string, values []string) { c.Certs.LoadCertificate(c.Options["tlscertificate"], c.Options["tlskey"]) } else if values[0] == "configlocation" { c.SetMessage("Cannot set READ ONLY setting 'configlocation'", true) - c.DrawMessage() return } err := saveConfig() if err != nil { c.SetMessage("Value set, but error saving config to file", true) - c.DrawMessage() } else { c.SetMessage(fmt.Sprintf("%s is now set to %q", values[0], c.Options[values[0]]), false) c.Draw() @@ -480,10 +452,8 @@ func (c *client) doCommandAs(action string, values []string) { return } c.SetMessage(fmt.Sprintf("Unable to set %s, it does not exist", values[0]), true) - c.DrawMessage() default: c.SetMessage(fmt.Sprintf("Unknown command structure"), true) - c.DrawMessage() } } @@ -491,7 +461,6 @@ func (c *client) doLinkCommandAs(action, target string, values []string) { num, err := strconv.Atoi(target) if err != nil { c.SetMessage(fmt.Sprintf("Expected link number, got %q", target), true) - c.DrawMessage() return } @@ -500,7 +469,6 @@ func (c *client) doLinkCommandAs(action, target string, values []string) { links := c.PageState.History[c.PageState.Position].Links if num >= len(links) || num < 0 { c.SetMessage(fmt.Sprintf("Invalid link id: %s", target), true) - c.DrawMessage() return } @@ -512,16 +480,13 @@ func (c *client) doLinkCommandAs(action, target string, values []string) { msg, err := c.BookMarks.Add(bm) if err != nil { c.SetMessage(err.Error(), true) - c.DrawMessage() return } c.SetMessage(msg, false) - c.DrawMessage() err = saveConfig() if err != nil { c.SetMessage("Error saving bookmark to file", true) - c.DrawMessage() } if c.BookMarks.IsOpen { c.Draw() @@ -533,7 +498,6 @@ func (c *client) doLinkCommandAs(action, target string, values []string) { c.doCommandAs(action, out) default: c.SetMessage(fmt.Sprintf("Unknown command structure"), true) - c.DrawMessage() } } @@ -541,7 +505,6 @@ func (c *client) saveFile(u Url, name string) { var file []byte var err error c.SetMessage(fmt.Sprintf("Saving %s ...", name), false) - c.DrawMessage() switch u.Scheme { case "gopher": file, err = gopher.Retrieve(u.Host, u.Port, u.Resource) @@ -551,13 +514,11 @@ func (c *client) saveFile(u Url, name string) { file, err = http.Fetch(u.Full) default: c.SetMessage(fmt.Sprintf("Saving files over %s is not supported", u.Scheme), true) - c.DrawMessage() return } if err != nil { c.SetMessage(err.Error(), true) - c.DrawMessage() return } @@ -567,18 +528,15 @@ func (c *client) saveFile(u Url, name string) { err = ioutil.WriteFile(savePath, file, 0644) if err != nil { c.SetMessage("Error writing file: "+err.Error(), true) - c.DrawMessage() return } c.SetMessage(fmt.Sprintf("File saved to: %s", savePath), false) - c.DrawMessage() } func (c *client) saveFileFromData(d, name string) { data := []byte(d) c.SetMessage(fmt.Sprintf("Saving %s ...", name), false) - c.DrawMessage() // We are ignoring the error here since WriteFile will // generate the same error, and will handle the messaging @@ -586,19 +544,16 @@ func (c *client) saveFileFromData(d, name string) { err := ioutil.WriteFile(savePath, data, 0644) if err != nil { c.SetMessage("Error writing file: "+err.Error(), true) - c.DrawMessage() return } c.SetMessage(fmt.Sprintf("File saved to: %s", savePath), false) - c.DrawMessage() } func (c *client) doLinkCommand(action, target string) { num, err := strconv.Atoi(target) if err != nil { c.SetMessage(fmt.Sprintf("Expected number, got %q", target), true) - c.DrawMessage() } switch action { @@ -606,16 +561,13 @@ func (c *client) doLinkCommand(action, target string) { msg, err := c.BookMarks.Delete(num) if err != nil { c.SetMessage(err.Error(), true) - c.DrawMessage() return } c.SetMessage(msg, false) - c.DrawMessage() err = saveConfig() if err != nil { c.SetMessage("Error saving bookmark deletion to file", true) - c.DrawMessage() } if c.BookMarks.IsOpen { c.Draw() @@ -623,7 +575,6 @@ func (c *client) doLinkCommand(action, target string) { case "BOOKMARKS", "B": if num > len(c.BookMarks.Links)-1 { c.SetMessage(fmt.Sprintf("There is no bookmark with ID %d", num), true) - c.DrawMessage() return } c.Visit(c.BookMarks.Links[num]) @@ -633,23 +584,19 @@ func (c *client) doLinkCommand(action, target string) { links := c.PageState.History[c.PageState.Position].Links if num >= len(links) || num < 0 { c.SetMessage(fmt.Sprintf("Invalid link id: %s", target), true) - c.DrawMessage() return } link := links[num] c.SetMessage(fmt.Sprintf("[%d] %s", num+1, link), false) - c.DrawMessage() case "WRITE", "W": links := c.PageState.History[c.PageState.Position].Links if len(links) < num || num < 1 { c.SetMessage("Invalid link ID", true) - c.DrawMessage() return } u, err := MakeUrl(links[num-1]) if err != nil { c.SetMessage(err.Error(), true) - c.DrawMessage() return } fns := strings.Split(u.Resource, "/") @@ -662,10 +609,9 @@ func (c *client) doLinkCommand(action, target string) { if fn == "" { fn = "index" } - c.saveFile(u, fn) + go c.saveFile(u, fn) default: c.SetMessage("Unknown command structure", true) - c.DrawMessage() } } @@ -684,7 +630,6 @@ func (c *client) search(query, url, question string) { c.ClearMessageLine() if err != nil { c.SetMessage(err.Error(), true) - c.DrawMessage() return } else if strings.TrimSpace(entry) == "" { c.ClearMessage() @@ -700,21 +645,19 @@ func (c *client) search(query, url, question string) { u, err := MakeUrl(url) if err != nil { c.SetMessage("The search url is not a valid url", true) - c.DrawMessage() return } switch u.Scheme { case "gopher": - go c.Visit(fmt.Sprintf("%s\t%s", u.Full, entry)) + c.Visit(fmt.Sprintf("%s\t%s", u.Full, entry)) case "gemini": // TODO url escape the entry variable escapedEntry := entry - go c.Visit(fmt.Sprintf("%s?%s", u.Full, escapedEntry)) + c.Visit(fmt.Sprintf("%s?%s", u.Full, escapedEntry)) case "http", "https": c.Visit(u.Full) default: c.SetMessage(fmt.Sprintf("%q is not a supported protocol", u.Scheme), true) - c.DrawMessage() } } @@ -723,12 +666,10 @@ func (c *client) Scroll(amount int) { bottom := len(c.BookMarks.Titles) - c.Height + 5 // 3 for the three bars: top, msg, bottom if amount < 0 && c.BookMarks.Position == 0 { c.SetMessage("The bookmark ladder does not go up any further", false) - c.DrawMessage() fmt.Print("\a") return } else if (amount > 0 && c.BookMarks.Position == bottom) || bottom < 0 { c.SetMessage("Feel the ground beneath your bookmarks", false) - c.DrawMessage() fmt.Print("\a") return } @@ -747,13 +688,11 @@ func (c *client) Scroll(amount int) { bottom := len(page.WrappedContent) - c.Height + 3 // 3 for the three bars: top, msg, bottom if amount < 0 && page.ScrollPosition == 0 { c.SetMessage("You are already at the top", false) - c.DrawMessage() fmt.Print("\a") return } else if (amount > 0 && page.ScrollPosition == bottom) || bottom < 0 { c.FootBar.SetPercentRead(100) c.SetMessage("You are already at the bottom", false) - c.DrawMessage() fmt.Print("\a") return } @@ -810,16 +749,15 @@ func (c *client) SetPercentRead() { func (c *client) displayConfigValue(setting string) { if val, ok := c.Options[setting]; ok { c.SetMessage(fmt.Sprintf("%s is set to: %q", setting, val), false) - c.DrawMessage() } else { c.SetMessage(fmt.Sprintf("Invalid: %q does not exist", setting), true) - c.DrawMessage() } } func (c *client) SetMessage(msg string, isError bool) { c.MessageIsErr = isError c.Message = strings.Replace(msg, "\t", "%09", -1) + c.DrawMessage() } func (c *client) DrawMessage() { @@ -870,7 +808,6 @@ func (c *client) goToLink(l string) { item, err := strconv.Atoi(l) if err != nil { c.SetMessage(fmt.Sprintf("Invalid link id: %s", l), true) - c.DrawMessage() return } if item <= linkcount && item > 0 { @@ -878,7 +815,6 @@ func (c *client) goToLink(l string) { c.Visit(linkurl) } else { c.SetMessage(fmt.Sprintf("Invalid link id: %s", l), true) - c.DrawMessage() return } } @@ -897,13 +833,11 @@ func (c *client) SetHeaderUrl() { // appropriate protocol handler func (c *client) Visit(url string) { c.SetMessage("Loading...", false) - c.DrawMessage() url = strings.Replace(url, "%09", "\t", -1) u, err := MakeUrl(url) if err != nil { c.SetMessage(err.Error(), true) - c.DrawMessage() return } @@ -922,7 +856,6 @@ func (c *client) Visit(url string) { c.handleFinger(u) default: c.SetMessage(fmt.Sprintf("%q is not a supported protocol", u.Scheme), true) - c.DrawMessage() } } @@ -936,14 +869,13 @@ func (c *client) handleGopher(u Url) { if filename == "" { filename = "gopherfile" } - c.saveFile(u, filename) + go c.saveFile(u, filename) } else if u.Mime == "7" { c.search("", u.Full, "?") } else { content, links, err := gopher.Visit(u.Mime, u.Host, u.Port, u.Resource) if err != nil { c.SetMessage(err.Error(), true) - c.DrawMessage() return } pg := MakePage(u, content, links) @@ -960,7 +892,6 @@ func (c *client) handleGemini(u Url) { capsule, err := gemini.Visit(u.Host, u.Port, u.Resource, &c.Certs) if err != nil { c.SetMessage(err.Error(), true) - c.DrawMessage() return } go saveConfig() @@ -978,34 +909,28 @@ func (c *client) handleGemini(u Url) { c.Draw() } else { c.SetMessage("The file is non-text: writing to disk...", false) - c.DrawMessage() nameSplit := strings.Split(u.Resource, "/") filename := nameSplit[len(nameSplit)-1] - c.saveFileFromData(capsule.Content, filename) + go c.saveFileFromData(capsule.Content, filename) } case 3: c.SetMessage(fmt.Sprintf("Follow redirect (y/n): %s?", capsule.Content), false) - c.DrawMessage() ch := cui.Getch() if ch == 'y' || ch == 'Y' { c.Visit(capsule.Content) } else { c.SetMessage("Redirect aborted", false) - c.DrawMessage() } } } func (c *client) handleTelnet(u Url) { c.SetMessage("Attempting to start telnet session", false) - c.DrawMessage() msg, err := telnet.StartSession(u.Host, u.Port) if err != nil { c.SetMessage(err.Error(), true) - c.DrawMessage() } else { c.SetMessage(msg, true) - c.DrawMessage() } c.Draw() } @@ -1014,7 +939,6 @@ func (c *client) handleLocal(u Url) { content, links, err := local.Open(u.Resource) if err != nil { c.SetMessage(err.Error(), true) - c.DrawMessage() return } pg := MakePage(u, content, links) @@ -1030,7 +954,6 @@ func (c *client) handleFinger(u Url) { content, err := finger.Finger(u.Host, u.Port, u.Resource) if err != nil { c.SetMessage(err.Error(), true) - c.DrawMessage() return } pg := MakePage(u, content, []string{}) @@ -1050,7 +973,6 @@ func (c *client) handleWeb(u Url) { page, err := http.Visit(wm, u.Full, c.Width-1) if err != nil { c.SetMessage(fmt.Sprintf("%s error: %s", wm, err.Error()), true) - c.DrawMessage() return } pg := MakePage(u, page.Content, page.Links) @@ -1062,28 +984,23 @@ func (c *client) handleWeb(u Url) { c.Draw() } else { c.SetMessage("The file is non-text: writing to disk...", false) - c.DrawMessage() var fn string if i := strings.LastIndex(u.Full, "/"); i > 0 && i+1 < len(u.Full) { fn = u.Full[i+1:] } else { fn = "bombadillo.download" } - c.saveFile(u, fn) + go c.saveFile(u, fn) } case "gui": c.SetMessage("Attempting to open in gui web browser", false) - c.DrawMessage() msg, err := http.OpenInBrowser(u.Full) if err != nil { c.SetMessage(err.Error(), true) - } else { - c.SetMessage(msg, false) } - c.DrawMessage() + c.SetMessage(msg, false) default: c.SetMessage("Current 'webmode' setting does not allow http/https", false) - c.DrawMessage() } }