diff --git a/config.go b/config.go index c462695..19d52c8 100755 --- a/config.go +++ b/config.go @@ -1,15 +1,11 @@ package main import ( - "encoding/json" - "fmt" - "io/ioutil" - "gogs.inhome.blapointe.com/local/args" - "gogs.inhome.blapointe.com/local/oauth2" - "gogs.inhome.blapointe.com/local/storage" "log" - "net/http" "strings" + + "gitea.inhome.blapointe.com/local/args" + "gitea.inhome.blapointe.com/local/storage" ) type Uploader int @@ -124,64 +120,9 @@ func NewConfig() Config { } func getToken(as *args.ArgSet) string { - c := &http.Client{CheckRedirect: func(r *http.Request, via []*http.Request) error { - return http.ErrUseLastResponse - }} - body := "username=" + as.GetString("todopass") - name := strings.Split(as.GetString("todoaddr"), ".")[0] - name = strings.TrimPrefix(name, "http://") - name = strings.TrimPrefix(name, "https://") - req, err := http.NewRequest("POST", as.GetString("authaddr")+"/authorize/"+name+"?"+oauth2.REDIRECT+"=127.0.0.1", strings.NewReader(body)) - if err != nil { - panic(err) - } - req.Header.Set("Content-Type", "application/x-www-form-urlencoded") - resp, err := c.Do(req) - if err != nil { - panic(err) - } - defer resp.Body.Close() - if resp.StatusCode > 399 { - panic("bad status getting token: " + resp.Status) - } - cookie := resp.Header.Get("Set-Cookie") - token := cookie[strings.Index(cookie, "=")+1:] - token = strings.Split(token, "; ")[0] - if len(token) == 0 { - panic(fmt.Sprintf("no token found: (%v) %v", resp.StatusCode, resp.Header)) - } - return token + panic("DEAD") } func getList(as *args.ArgSet, token string) string { - req, err := http.NewRequest("GET", as.GetString("todoaddr")+"/ajax.php?loadLists", nil) - if err != nil { - panic(err) - } - req.Header.Set("Cookie", oauth2.COOKIE+"="+token) - resp, err := http.DefaultClient.Do(req) - if err != nil { - panic(err) - } - defer resp.Body.Close() - var r struct { - List []struct { - ID string `json:"id"` - } `json:"list"` - } - b, err := ioutil.ReadAll(resp.Body) - if err != nil { - panic(err) - } - if err := json.Unmarshal(b, &r); err != nil { - panic(fmt.Errorf("%v: %s", err, b)) - } - if len(r.List) == 0 { - panic("no lists found") - } - list := r.List[0].ID - if len(list) == 0 { - panic("empty list found") - } - return list + panic("DEAD") } diff --git a/go.mod b/go.mod index b368adf..cddedf0 100644 --- a/go.mod +++ b/go.mod @@ -1,18 +1,17 @@ -module gogs.inhome.blapointe.com/local/email-xactions-to-todo +module gitea.inhome.blapointe.com/local/email-xactions-to-todo go 1.17 require ( + gitea.inhome.blapointe.com/local-sandbox/contact v0.0.2-0.20231109150121-14036702ee2a + gitea.inhome.blapointe.com/local/args v0.0.0-20231109145953-eb2e1c1b8d56 + gitea.inhome.blapointe.com/local/storage v0.0.0-20231109151605-736d446d407d github.com/google/uuid v1.3.0 - gogs.inhome.blapointe.com/local-sandbox/contact v0.0.2-0.20230410170022-4b1b19400094 - gogs.inhome.blapointe.com/local/args v0.0.0-20230410154220-44370f257b34 - gogs.inhome.blapointe.com/local/oauth2 v0.0.0-20230410162733-d39498ff8454 - gogs.inhome.blapointe.com/local/storage v0.0.0-20230410162102-db39d7b02e29 - gopkg.in/yaml.v2 v2.4.0 ) require ( cloud.google.com/go v0.33.1 // indirect + gitea.inhome.blapointe.com/local/logb v0.0.0-20231109150430-1221d87a6dbc // indirect github.com/Unknwon/goconfig v0.0.0-20181105214110-56bd8ab18619 // indirect github.com/abbot/go-http-auth v0.4.0 // indirect github.com/aws/aws-sdk-go v1.15.81 // indirect @@ -46,15 +45,15 @@ require ( github.com/xdg-go/stringprep v1.0.2 // indirect github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect go.mongodb.org/mongo-driver v1.7.2 // indirect - gogs.inhome.blapointe.com/local/logb v0.0.0-20230410154319-880efa39d871 // indirect golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 // indirect golang.org/x/net v0.0.0-20190522155817-f3200d17e092 // indirect golang.org/x/oauth2 v0.0.0-20181120190819-8f65e3013eba // indirect golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 // indirect golang.org/x/text v0.3.7 // indirect - golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect + golang.org/x/time v0.0.0-20181108054448-85acf8d2951c // indirect google.golang.org/api v0.0.0-20181120235003-faade3cbb06a // indirect google.golang.org/appengine v1.3.0 // indirect gopkg.in/ini.v1 v1.42.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index 77cdd83..3319e52 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,14 @@ bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= cloud.google.com/go v0.33.1 h1:fmJQWZ1w9PGkHR1YL/P7HloDvqlmKQ4Vpb7PC2e+aCk= cloud.google.com/go v0.33.1/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +gitea.inhome.blapointe.com/local-sandbox/contact v0.0.2-0.20231109150121-14036702ee2a h1:vDt7kgsUwsI6fq7ObPUuUQ2CiIts3RaEsvcuwruspEY= +gitea.inhome.blapointe.com/local-sandbox/contact v0.0.2-0.20231109150121-14036702ee2a/go.mod h1:3LBm8MXwR5D5Z8gwp5p39KmabJR/F7cxBSZwVHWTfQQ= +gitea.inhome.blapointe.com/local/args v0.0.0-20231109145953-eb2e1c1b8d56 h1:zTGGZ77KLFagqUvDSgTOnm0qF+iSLwQWiEtGjb2jjlY= +gitea.inhome.blapointe.com/local/args v0.0.0-20231109145953-eb2e1c1b8d56/go.mod h1:SqCOE3bE3wvrztVIQGHuyxHKfDjRKU9EWhBdkmkiwyc= +gitea.inhome.blapointe.com/local/logb v0.0.0-20231109150430-1221d87a6dbc h1:u3akQkq12V8xWXlcDgjZxIK6hqo6f1eHd9KOxAKMoKc= +gitea.inhome.blapointe.com/local/logb v0.0.0-20231109150430-1221d87a6dbc/go.mod h1:KwilawX4UgD4HxSJAVFEzkuckrnHeQrd49KwUX6GpYU= +gitea.inhome.blapointe.com/local/storage v0.0.0-20231109151605-736d446d407d h1:SQq4hWImnvtrRfpPgOW4go+sBjMluuhRL/43b8L0yB4= +gitea.inhome.blapointe.com/local/storage v0.0.0-20231109151605-736d446d407d/go.mod h1:TRK5z/XTT6jws++Q21Y8DQot+5vZGTNeHf+RjuY8aQk= github.com/Azure/azure-pipeline-go v0.1.8/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg= github.com/Azure/azure-storage-blob-go v0.0.0-20181023070848-cf01652132cc/go.mod h1:oGfmITT1V6x//CswqY2gtAHND+xIP64/qL7a5QJix0Y= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= @@ -191,17 +199,6 @@ github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7Jul github.com/yunify/qingstor-sdk-go v2.2.15+incompatible/go.mod h1:w6wqLDQ5bBTzxGJ55581UrSwLrsTAsdo9N6yX/8d9RY= go.mongodb.org/mongo-driver v1.7.2 h1:pFttQyIiJUHEn50YfZgC9ECjITMT44oiN36uArf/OFg= go.mongodb.org/mongo-driver v1.7.2/go.mod h1:Q4oFMbo1+MSNqICAdYMlC/zSTrwCogR4R8NzkI+yfU8= -gogs.inhome.blapointe.com/local-sandbox/contact v0.0.2-0.20230410170022-4b1b19400094 h1:XaA0Pr+CsoDIpmwh6y/acNKRcBAp+HHh8Jnp1TFDrMw= -gogs.inhome.blapointe.com/local-sandbox/contact v0.0.2-0.20230410170022-4b1b19400094/go.mod h1:09XWh7o68eXoDrVd9RSQBZOLYUmR7nlA2P3779usmgA= -gogs.inhome.blapointe.com/local/args v0.0.0-20230410154220-44370f257b34 h1:0tuX5dfOksiOQD1vbJjVNVTVxTTIng7UrUdSLF5T+Ao= -gogs.inhome.blapointe.com/local/args v0.0.0-20230410154220-44370f257b34/go.mod h1:YG9n3Clg7683ohkVnJK2hdX8bBS9EojIsd1qPZumX0Y= -gogs.inhome.blapointe.com/local/logb v0.0.0-20230410154319-880efa39d871 h1:cMGPiwvK/QGg4TfW8VasO6SsS/O7UQmwyKDErV/ozoA= -gogs.inhome.blapointe.com/local/logb v0.0.0-20230410154319-880efa39d871/go.mod h1:E0pLNvMLzY0Kth1W078y+06z1AUyVMWnChMpRFf4w2Q= -gogs.inhome.blapointe.com/local/oauth2 v0.0.0-20230410162733-d39498ff8454 h1:U8gUhe9E97/uG3ne6D1VONCCVC6jjBbF1gDMKn3GCeo= -gogs.inhome.blapointe.com/local/oauth2 v0.0.0-20230410162733-d39498ff8454/go.mod h1:YDG4DAUbmKcQUDWdZAJyoUtX+N2zQIFQ0fz88lAPuiU= -gogs.inhome.blapointe.com/local/router v0.0.0-20230410162418-08ccdc13df87/go.mod h1:FCXhK6+lzJcxBsptnei6vw9pChuQvr4NtuosngjVJDk= -gogs.inhome.blapointe.com/local/storage v0.0.0-20230410162102-db39d7b02e29 h1:SPSz7yQsEfScqyLlBS5uNSOGeT203BkIkFCL8jrm/FA= -gogs.inhome.blapointe.com/local/storage v0.0.0-20230410162102-db39d7b02e29/go.mod h1:zk8Fe2Ezc2f6oOe2yllsbEhXqssUU1K2faoS0eQ9alY= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -241,9 +238,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c h1:fqgJT0MGcGpPgpWU7VRdRjuArfcOvC4AoJmILihzhDg= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= -golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= diff --git a/main.go b/main.go index 40697f8..5b2e475 100755 --- a/main.go +++ b/main.go @@ -4,7 +4,7 @@ import ( "log" "regexp" - "gogs.inhome.blapointe.com/local-sandbox/contact" + "gitea.inhome.blapointe.com/local-sandbox/contact" ) func main() { diff --git a/upload.go b/upload.go index 333d64c..4dd25b4 100755 --- a/upload.go +++ b/upload.go @@ -1,27 +1,20 @@ package main import ( - "bytes" "errors" "fmt" - "io/ioutil" - "gogs.inhome.blapointe.com/local/oauth2" - "net/http" - "net/url" "os" - "path" "regexp" "strconv" - "strings" "time" - yaml "gopkg.in/yaml.v2" + "github.com/google/uuid" ) func Upload(config Config, transaction *Transaction) error { switch config.Uploader { case UploaderTodo: - return uploadTodo(config, transaction) + panic("DEAD") case UploaderLedger: return uploadLedger(config, transaction) case UploaderPTTodo: @@ -31,67 +24,14 @@ func Upload(config Config, transaction *Transaction) error { } } -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 uploadPTTodo(config Config, transaction *Transaction) error { - b, err := ioutil.ReadFile(config.TodoAddr) - if os.IsNotExist(err) { - b = []byte("todo:\n") - } else if err != nil { - return err - } else if len(b) == 0 { - b = []byte("todo:\n") - } - f, err := ioutil.TempFile(path.Dir(config.TodoAddr), path.Base("."+config.TodoAddr)) + f, err := os.Create(fmt.Sprintf("%s.todo.%s", config.TodoAddr, uuid.New().String())) if err != nil { return err } defer f.Close() - sep := []byte{'\n'} - seek := []byte("todo:") - for len(b) > 0 { - idx := bytes.Index(b, sep) - if idx == -1 { - idx = len(b) - 1 - } - fmt.Fprintf(f, "%s\n", b[:idx]) - if bytes.Equal(bytes.TrimSpace(b[:idx]), seek) { - fmt.Fprintf(f, `- {"todo":%q, "tags":%q}%s`, transaction.Format(), config.TodoTag, "\n") - } - b = b[idx+1:] - } - f.Close() - var v interface{} - b, err = ioutil.ReadFile(f.Name()) - if err != nil { - return err - } - if err := yaml.Unmarshal(b, &v); err != nil { - return err - } - return os.Rename(f.Name(), config.TodoAddr) + fmt.Fprintf(f, `- {"todo":%q, "tags":%q}%s`, transaction.Format(), config.TodoTag, "\n") + return f.Close() } func uploadLedger(config Config, transaction *Transaction) error { diff --git a/upload_test.go b/upload_test.go index ec826ac..7e7eed2 100644 --- a/upload_test.go +++ b/upload_test.go @@ -3,17 +3,30 @@ package main import ( "bytes" "io/ioutil" - "gogs.inhome.blapointe.com/local/storage" "os" "path" + "path/filepath" "testing" + "gitea.inhome.blapointe.com/local/storage" + "github.com/google/uuid" ) func TestUploadPTTodo(t *testing.T) { addr := path.Join(t.TempDir(), "test.upload.pttodo") config := Config{TodoAddr: addr, TodoTag: "expense"} + reset := func(t *testing.T) { + files, err := filepath.Glob(addr + "*") + if err != nil { + t.Fatal(err) + } + for _, f := range files { + if f != addr { + os.Remove(f) + } + } + } xaction := func() *Transaction { return &Transaction{ ID: "id", @@ -24,6 +37,7 @@ func TestUploadPTTodo(t *testing.T) { } } t.Run("full file", func(t *testing.T) { + defer reset(t) if err := ioutil.WriteFile(addr, []byte(` todo: - first @@ -37,18 +51,18 @@ done: [] if err != nil { t.Error(err) } - b, err := ioutil.ReadFile(addr) + files, err := filepath.Glob(addr + ".todo.*") if err != nil { t.Error(err) } - if bytes.Compare(bytes.TrimSpace(b), bytes.TrimSpace([]byte(` -todo: -- {"todo":"(today) /UCCU: 1.23 @ vendor vendor", "tags":"expense"} -- first -- todo: second -scheduled: [] -done: [] - `))) != 0 { + if len(files) != 1 { + t.Fatal(files) + } + b, err := ioutil.ReadFile(files[0]) + if err != nil { + t.Error(err) + } + if bytes.Compare(bytes.TrimSpace(b), bytes.TrimSpace([]byte(`- {"todo":"(today) /UCCU: 1.23 @ vendor vendor", "tags":"expense"}`))) != 0 { t.Errorf("full file came out wrong: got %s", b) } if !bytes.Contains(b, []byte(xaction().Format())) { @@ -57,12 +71,20 @@ done: [] t.Logf("%s", b) }) t.Run("no file", func(t *testing.T) { + defer reset(t) os.Remove(addr) err := uploadPTTodo(config, xaction()) if err != nil { t.Error(err) } - b, err := ioutil.ReadFile(addr) + files, err := filepath.Glob(addr + ".todo.*") + if err != nil { + t.Error(err) + } + if len(files) != 1 { + t.Fatal(files) + } + b, err := ioutil.ReadFile(files[0]) if err != nil { t.Error(err) } @@ -72,6 +94,7 @@ done: [] t.Logf("%s", b) }) t.Run("empty file", func(t *testing.T) { + defer reset(t) if err := ioutil.WriteFile(addr, []byte{}, os.ModePerm); err != nil { t.Fatal(err) } @@ -79,7 +102,14 @@ done: [] if err != nil { t.Error(err) } - b, err := ioutil.ReadFile(addr) + files, err := filepath.Glob(addr + ".todo.*") + if err != nil { + t.Error(err) + } + if len(files) != 1 { + t.Fatal(files) + } + b, err := ioutil.ReadFile(files[0]) if err != nil { t.Error(err) }