func Comment(c *cli.Context) { taskId := api.FindTaskId(c.Args().First(), false) task, stories := api.Task(taskId, true) tmpFile := os.TempDir() + "/asana_comment.txt" f, err := os.Create(tmpFile) utils.Check(err) defer f.Close() err = template(f, task, stories) utils.Check(err) cmd := exec.Command(os.Getenv("EDITOR"), tmpFile) cmd.Stdin, cmd.Stdout = os.Stdin, os.Stdout err = cmd.Run() txt, err := ioutil.ReadFile(tmpFile) utils.Check(err) postComment := trim(string(txt)) if postComment != "" { commented := api.CommentTo(taskId, postComment) fmt.Println("Commented on Task: \"" + task.Name + "\"\n") fmt.Println(commented) } else { fmt.Println("Aborting comment due to empty content.") } }
func Task(taskId string, verbose bool) (Task_t, []Story_t) { var ( err error t map[string]Task_t ss map[string][]Story_t stories []Story_t ) task_chan, stories_chan := make(chan []byte), make(chan []byte) go func() { task_chan <- Get("/api/1.0/tasks/"+taskId, nil) }() stories = nil if verbose { go func() { stories_chan <- Get("/api/1.0/tasks/"+taskId+"/stories", nil) }() err = json.Unmarshal(<-stories_chan, &ss) utils.Check(err) stories = ss["data"] } err = json.Unmarshal(<-task_chan, &t) utils.Check(err) return t["data"], stories }
func Browse(c *cli.Context) { taskId := api.FindTaskId(c.Args().First(), true) url := "https://app.asana.com/0/" + strconv.Itoa(config.Load().Workspace) + "/" + taskId launcher, err := utils.BrowserLauncher() utils.Check(err) cmd := exec.Command(launcher, url) err = cmd.Start() utils.Check(err) }
func FindTaskId(index string, autoFirst bool) string { if index == "" { if autoFirst == false { log.Fatal("fatal: Task index is required.") } else { index = "0" } } var id string txt, err := ioutil.ReadFile(utils.CacheFile()) if err != nil { // cache file not exist ind, parseErr := strconv.Atoi(index) utils.Check(parseErr) task := Tasks(url.Values{}, false)[ind] id = strconv.Itoa(task.Id) } else { lines := regexp.MustCompile("\n").Split(string(txt), -1) for i, line := range lines { if index == strconv.Itoa(i) { line = regexp.MustCompile("^[0-9]*:").ReplaceAllString(line, "") // remove index id = regexp.MustCompile("^[0-9]*").FindString(line) } } } return id }
func Update(taskId string, key string, value string) Task_t { respBody := Put("/tasks/"+taskId, `{"data":{"`+key+`":"`+value+`"}}`) var output map[string]Task_t err := json.Unmarshal(respBody, &output) utils.Check(err) return output["data"] }
func CommentTo(taskId string, comment string) string { respBody := Post("/tasks/"+taskId+"/stories", `{"data":{"text":"`+comment+`"}}`) var output map[string]Commented_t err := json.Unmarshal(respBody, &output) utils.Check(err) return output["data"].Text }
func Load() Conf { var dat []byte var err error dat, err = ioutil.ReadFile(utils.Home() + "/.asana.yml") if err != nil { fmt.Println("Config file isn't set.\n ==> $ asana config") os.Exit(1) } conf := Conf{} err = yaml.Unmarshal(dat, &conf) utils.Check(err) return conf }
func fire(req *http.Request) []byte { client := &http.Client{} req.Header.Set("User-Agent", UserAgent) req.Header.Set("Authorization", "Bearer "+config.Load().Personal_access_token) resp, err := client.Do(req) body, err := ioutil.ReadAll(resp.Body) utils.Check(err) if resp.StatusCode >= 300 { println(resp.Status) } return body }
func Tasks(params url.Values, withCompleted bool) []Task_t { params.Add("workspace", strconv.Itoa(config.Load().Workspace)) params.Add("assignee", "me") params.Add("opt_fields", "name,completed,due_on") var tasks map[string][]Task_t err := json.Unmarshal(Get("/api/1.0/tasks", params), &tasks) utils.Check(err) var tasks_without_due, tasks_with_due []Task_t for _, t := range tasks["data"] { if !withCompleted && t.Completed { continue } if t.Due_on == "" { tasks_without_due = append(tasks_without_due, t) } else { tasks_with_due = append(tasks_with_due, t) } } sort.Sort(ByDue(tasks_with_due)) return append(tasks_with_due, tasks_without_due...) }
func Put(path string, data string) []byte { req, err := http.NewRequest("PUT", PostBase+path, strings.NewReader(data)) utils.Check(err) return fire(req) }
func Get(path string, params url.Values) []byte { req, err := http.NewRequest("GET", getURL(path, params), nil) utils.Check(err) return fire(req) }
func Me() Me_t { var me map[string]Me_t err := json.Unmarshal(Get("/api/1.0/users/me", nil), &me) utils.Check(err) return me["data"] }