165 lines
4.0 KiB
Go
Executable File
165 lines
4.0 KiB
Go
Executable File
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"local/args"
|
|
"local/oauth2"
|
|
"local/storage"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
type Uploader int
|
|
|
|
const (
|
|
UploaderTodo = Uploader(iota)
|
|
UploaderLedger
|
|
)
|
|
|
|
var uploaders = map[string]Uploader{
|
|
"todo": UploaderTodo,
|
|
"ledger": UploaderLedger,
|
|
}
|
|
|
|
type Config struct {
|
|
EmailUser string
|
|
EmailPass string
|
|
EmailIMAP string
|
|
TodoAddr string
|
|
TodoToken string
|
|
TodoList string
|
|
TodoTag string
|
|
Uploader Uploader
|
|
Storage storage.DB
|
|
}
|
|
|
|
var config Config
|
|
|
|
func NewConfig() Config {
|
|
as := args.NewArgSet()
|
|
|
|
as.Append(args.STRING, "emailuser", "email username", "breellocaldev@gmail.com")
|
|
as.Append(args.STRING, "emailpass", "email password", "ML3WQRFSqe9rQ8qNkm")
|
|
as.Append(args.STRING, "emailimap", "email imap", "imap.gmail.com:993")
|
|
|
|
as.Append(args.STRING, "uploader", "todo, ledger", "todo")
|
|
|
|
as.Append(args.STRING, "todoaddr", "todo addr", "https://todo-server.remote.blapointe.com")
|
|
as.Append(args.STRING, "todopass", "todo pass", "gJtEXbbLHLf54yS9EdujtVN2n6Y")
|
|
as.Append(args.STRING, "todotoken", "todo token", "")
|
|
as.Append(args.STRING, "todolist", "todo list", "")
|
|
as.Append(args.STRING, "todotag", "todo tag", "expense")
|
|
|
|
as.Append(args.STRING, "authaddr", "auth addr", "https://auth.remote.blapointe.com")
|
|
as.Append(args.STRING, "store", "store type", "map")
|
|
as.Append(args.STRING, "storeaddr", "store addr", "/tmp/store")
|
|
as.Append(args.STRING, "storeuser", "store user", "")
|
|
as.Append(args.STRING, "storepass", "store pass", "")
|
|
|
|
if err := as.Parse(); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
uploader := as.GetString("uploader")
|
|
ul, ok := uploaders[uploader]
|
|
if !ok {
|
|
panic("invalid uploader: " + uploader)
|
|
}
|
|
|
|
storage, err := storage.New(storage.TypeFromString(as.GetString("store")), as.GetString("storeaddr"), as.GetString("storeuser"), as.GetString("storepass"))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
config = Config{
|
|
EmailUser: as.GetString("emailuser"),
|
|
EmailPass: as.GetString("emailpass"),
|
|
EmailIMAP: as.GetString("emailimap"),
|
|
TodoAddr: as.GetString("todoaddr"),
|
|
TodoTag: as.GetString("todotag"),
|
|
Storage: storage,
|
|
Uploader: ul,
|
|
}
|
|
|
|
if config.Uploader == UploaderTodo {
|
|
token := as.GetString("todotoken")
|
|
if len(token) == 0 {
|
|
token = getToken(as)
|
|
}
|
|
|
|
list := as.GetString("todolist")
|
|
if len(list) == 0 {
|
|
list = getList(as, token)
|
|
}
|
|
config.TodoToken = token
|
|
config.TodoList = list
|
|
}
|
|
|
|
return 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
|
|
}
|
|
|
|
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
|
|
}
|