package main import ( "errors" "fmt" "io/ioutil" "local/oauth2" "net/http" "net/url" "os" "strconv" "strings" "time" ) func Upload(config Config, transaction *Transaction) error { switch config.Uploader { case UploaderTodo: return uploadTodo(config, transaction) case UploaderLedger: return uploadLedger(config, transaction) default: return errors.New("not impl: uploader") } } func uploadTodo(config Config, transaction *Transaction) error { params := url.Values{ "list": {config.TodoList}, "title": {transaction.Format()}, "tag": {config.TodoTag}, } req, err := http.NewRequest("POST", config.TodoAddr+"/ajax.php?newTask", strings.NewReader(params.Encode())) if err != nil { return err } req.Header.Set("Cookie", oauth2.COOKIE+"="+config.TodoToken) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") resp, err := http.DefaultClient.Do(req) if err != nil { return err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { b, _ := ioutil.ReadAll(resp.Body) return fmt.Errorf("bad status from todo: %v: %s", resp.StatusCode, b) } return nil } func uploadLedger(config Config, transaction *Transaction) error { f, err := os.OpenFile(config.TodoAddr, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { return err } defer f.Close() amount, _ := strconv.ParseFloat(transaction.Amount, 32) amount *= -1 remote := "Withdrawal:" if amount > 0 { remote = "Deposit:" } remote += strings.ReplaceAll(transaction.Account, " ", "") fmt.Fprintf(f, "%-50s%-s\n", formatGMailDate(transaction.Date), transaction.Account) fmt.Fprintf(f, "%-50s%-50s$%.2f\n", "", "AssetAccount:"+transaction.Bank.String(), amount) fmt.Fprintf(f, "%-50s%-s\n", "", remote) return nil } func formatGMailDate(s string) string { for _, format := range []string{ "[Mon, 2 Jan 2006 15:04:05 -0700 (MST)]", "[Mon, 2 Jan 2006 15:04:05 -0700]", } { time, err := time.Parse(format, s) if err == nil { return time.Format("2006-01-02") } } return s }