Переглянути джерело

Prevent composed post data loss when posting fails

Keeps temporary post file around until a post successfully goes through.
tags/v0.3
Matt Baer 8 роки тому
джерело
коміт
1d61f6f485
4 змінених файлів з 54 додано та 17 видалено
  1. +32
    -9
      writeas/cli.go
  2. +14
    -8
      writeas/posts.go
  3. +4
    -0
      writeas/posts_nix.go
  4. +4
    -0
      writeas/posts_win.go

+ 32
- 9
writeas/cli.go Переглянути файл

@@ -3,6 +3,7 @@ package main
import (
"bufio"
"bytes"
"errors"
"fmt"
"github.com/codegangsta/cli"
"io"
@@ -201,7 +202,7 @@ func check(err error) {
}
}

func handlePost(fullPost []byte, c *cli.Context) {
func handlePost(fullPost []byte, c *cli.Context) error {
tor := c.Bool("tor") || c.Bool("t")
if c.Int("tor-port") != 0 {
torPort = c.Int("tor-port")
@@ -212,15 +213,16 @@ func handlePost(fullPost []byte, c *cli.Context) {
fmt.Println("Posting...")
}

DoPost(fullPost, false, tor, c.Bool("code"))
return DoPost(fullPost, false, tor, c.Bool("code"))
}

func cmdPost(c *cli.Context) {
handlePost(readStdIn(), c)
err := handlePost(readStdIn(), c)
check(err)
}

func cmdNew(c *cli.Context) {
p := composeNewPost()
fname, p := composeNewPost()
if p == nil {
// Assume composeNewPost already told us what the error was. Abort now.
os.Exit(1)
@@ -228,11 +230,26 @@ func cmdNew(c *cli.Context) {

// Ensure we have something to post
if len(*p) == 0 {
// Clean up temporary post
if fname != "" {
os.Remove(fname)
}

fmt.Println("Empty post. Bye!")
os.Exit(0)
}

handlePost(*p, c)
err := handlePost(*p, c)
if err != nil {
fmt.Printf("Error posting: %s\n", err)
fmt.Println(messageRetryCompose(fname))
os.Exit(1)
}

// Clean up temporary post
if fname != "" {
os.Remove(fname)
}
}

func cmdDelete(c *cli.Context) {
@@ -387,7 +404,7 @@ func DoFetch(friendlyId string, tor bool) {
}
}

func DoPost(post []byte, encrypt, tor, code bool) {
func DoPost(post []byte, encrypt, tor, code bool) error {
data := url.Values{}
data.Set("w", string(post))
if encrypt {
@@ -407,12 +424,16 @@ func DoPost(post []byte, encrypt, tor, code bool) {
r.Header.Add("Content-Length", strconv.Itoa(len(data.Encode())))

resp, err := client.Do(r)
check(err)
if err != nil {
return err
}
defer resp.Body.Close()

if resp.StatusCode == http.StatusOK {
content, err := ioutil.ReadAll(resp.Body)
check(err)
if err != nil {
return err
}

nlPos := strings.Index(string(content), "\n")
url := content[:nlPos]
@@ -424,8 +445,10 @@ func DoPost(post []byte, encrypt, tor, code bool) {

fmt.Printf("%s\n", url)
} else {
fmt.Printf("Unable to post: %s\n", resp.Status)
return errors.New(fmt.Sprintf("Unable to post: %s", resp.Status))
}

return nil
}

func DoUpdate(post []byte, friendlyId, token string, tor bool) {


+ 14
- 8
writeas/posts.go Переглянути файл

@@ -98,41 +98,47 @@ func getPosts() *[]Post {
return &posts
}

func composeNewPost() *[]byte {
func composeNewPost() (string, *[]byte) {
f, err := fileutils.TempFile(os.TempDir(), "WApost", "txt")
if err != nil {
if DEBUG {
panic(err)
} else {
fmt.Printf("Error creating temp file: %s\n", err)
return nil
return "", nil
}
}
defer os.Remove(f.Name())
f.Close()

cmd := editPostCmd(f.Name())
if cmd == nil {
os.Remove(f.Name())

fmt.Println(NO_EDITOR_ERR)
return nil
return "", nil
}
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Start(); err != nil {
os.Remove(f.Name())

if DEBUG {
panic(err)
} else {
fmt.Printf("Error starting editor: %s\n", err)
return nil
return "", nil
}
}

// If something fails past this point, the temporary post file won't be
// removed automatically. Calling function should handle this.
if err := cmd.Wait(); err != nil {
if DEBUG {
panic(err)
} else {
fmt.Printf("Editor finished with error: %s\n", err)
return nil
return "", nil
}
}

@@ -142,8 +148,8 @@ func composeNewPost() *[]byte {
panic(err)
} else {
fmt.Printf("Error reading post: %s\n", err)
return nil
return "", nil
}
}
return &post
return f.Name(), &post
}

+ 4
- 0
writeas/posts_nix.go Переглянути файл

@@ -38,3 +38,7 @@ func editPostCmd(fname string) *exec.Cmd {
}
return exec.Command(editor, fname)
}

func messageRetryCompose(fname string) string {
return fmt.Sprintf("To retry this post, run:\n cat %s | writeas", fname)
}

+ 4
- 0
writeas/posts_win.go Переглянути файл

@@ -20,3 +20,7 @@ func editPostCmd(fname string) *exec.Cmd {
// NOTE this won't work if fname contains spaces.
return exec.Command("cmd", "/C start /WAIT "+fname)
}

func messageRetryCompose(fname string) string {
return fmt.Sprintf("To retry this post, run:\n type %s | writeas.exe", fname)
}

Завантаження…
Відмінити
Зберегти