D about/open.tmpl => about/open.tmpl +0 -7
@@ 1,7 0,0 @@
-# Opening {{.Filename}}
-
-You have chosen to open {{.Filename}} which is {{.MediaType}} from {{.Hostname}}.
-
-=> save Save file
-=> open Open in external program
-=> abort Abort
M browser.go => browser.go +1 -45
@@ 3,9 3,7 @@ package main
import (
"astronaut/styles"
"astronaut/ui"
- "bufio"
"fmt"
- "io"
"log"
"math"
"math/rand"
@@ 30,7 28,6 @@ const (
ModeNormal Mode = iota
ModeCommand
ModeInput
- ModeSave
ModeFollow
)
@@ 59,9 56,6 @@ type Browser struct {
input ui.Input
- // save mode
- data io.ReadCloser
-
// follow mode
hint string
hints []Hint
@@ 191,7 185,7 @@ func (b *Browser) Draw() {
b.statusView.DrawText(0, 0, b.message.text, style)
}
- case ModeCommand, ModeInput, ModeSave:
+ case ModeCommand, ModeInput:
b.input.Draw()
case ModeFollow:
@@ 290,31 284,6 @@ func (b *Browser) Event(event tcell.Event) {
tab.DoBackground(req)
}
- case ModeSave:
- switch event := event.(type) {
- case *ui.EventTextInput:
- b.mode = ModeNormal
- data := b.data
- defer data.Close()
- b.data = nil
- if event.NoInput() {
- return
- }
- // TODO: Avoid overwriting files
- // TODO: Download directory?
- f, err := os.Create(event.Text())
- if err != nil {
- tab.Error(err)
- return
- }
- defer f.Close()
- _, err = io.Copy(bufio.NewWriter(f), data)
- if err != nil {
- tab.Error(err)
- return
- }
- }
-
case ModeFollow:
text := tab.Text()
if text == nil {
@@ 705,19 674,6 @@ func (b *Browser) InputMode(prompt string, sensitive bool) {
b.input.Sensitive(sensitive)
}
-func (b *Browser) SaveMode(data io.ReadCloser, name string) {
- b.mu.Lock()
- defer b.mu.Unlock()
- b.saveMode(data, name)
-}
-
-func (b *Browser) saveMode(data io.ReadCloser, name string) {
- b.mode = ModeSave
- b.data = data
- b.input.Prompt("Save as ")
- b.input.SetInput(name)
-}
-
func (b *Browser) FollowMode() error {
text := b.tabs[b.tab].Text()
if text == nil {
M command.go => command.go +16 -3
@@ 1,10 1,11 @@
package main
import (
+ "bufio"
"errors"
"io"
"net/url"
- "path"
+ "os"
"strconv"
"strings"
@@ 264,9 265,21 @@ func cmdScroll(b *Browser, args ...string) error {
}
func cmdSave(b *Browser, args ...string) error {
+ if len(args) < 1 {
+ return errors.New("usage: save <path>")
+ }
tab := b.tabs[b.tab]
- name := path.Base(tab.URL())
- b.saveMode(io.NopCloser(&tab.buf), name)
+ name := args[0]
+
+ f, err := os.OpenFile(name, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0644)
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+ _, err = io.Copy(bufio.NewWriter(f), &tab.buf)
+ if err != nil {
+ return err
+ }
return nil
}
M tab.go => tab.go +3 -55
@@ 634,7 634,7 @@ func (t *Tab) handle(req *gemini.Request, resp *gemini.Response) error {
defer resp.Body.Close()
return t.handleText(resp, mediatype, params)
}
- return t.handleDownload(req, resp, mediatype)
+ return t.openResponse(req, resp, mediatype)
}
func (t *Tab) handleText(resp *gemini.Response, mediatype string, params map[string]string) error {
@@ 655,60 655,9 @@ func (t *Tab) handleText(resp *gemini.Response, mediatype string, params map[str
return err
}
-func (t *Tab) handleDownload(req *gemini.Request, resp *gemini.Response, mediatype string) error {
+func (t *Tab) openResponse(req *gemini.Request, resp *gemini.Response, mediatype string) error {
filename := path.Base(req.URL.Path)
- ch := make(chan int)
- const (
- save = iota + 1
- open
- )
-
- {
- t.setStyle(styles.Warning)
- defer t.setStyle(tcell.StyleDefault)
-
- ctx := struct {
- Hostname string
- Filename string
- MediaType string
- }{
- req.URL.Hostname(),
- filename,
- mediatype,
- }
- var buf bytes.Buffer
- templates.ExecuteTemplate(&buf, "open.tmpl", ctx)
- gem := NewParsedGemText(t.view, t, io.NopCloser(&buf))
- gem.action = func(action string) {
- switch action {
- case "save":
- ch <- save
- case "open":
- ch <- open
- default:
- close(ch)
- }
- }
- t.setText(gem)
- defer t.setText(nil)
- }
-
- select {
- case choice := <-ch:
- switch choice {
- case save:
- t.browser.SaveMode(resp.Body, filename)
- return nil
- case open:
- defer resp.Body.Close()
- return t.openResponse(resp, filename)
- }
- }
- return nil
-}
-
-func (t *Tab) openResponse(resp *gemini.Response, filename string) error {
f, err := os.CreateTemp("", "astronaut-*-"+filename)
if err != nil {
return err
@@ 721,8 670,7 @@ func (t *Tab) openResponse(resp *gemini.Response, filename string) error {
// TODO: Configurable open command?
cmd := exec.Command("xdg-open", f.Name())
- cmd.Stderr = os.Stderr
- if err := cmd.Start(); err != nil {
+ if err := cmd.Run(); err != nil {
return err
}
return nil