示例#1
0
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.")
	}
}
示例#2
0
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
}
示例#3
0
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)
}
示例#4
0
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
}
示例#5
0
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"]
}
示例#6
0
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
}
示例#7
0
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
}
示例#8
0
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
}
示例#9
0
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...)
}
示例#10
0
func Put(path string, data string) []byte {
	req, err := http.NewRequest("PUT", PostBase+path, strings.NewReader(data))
	utils.Check(err)
	return fire(req)
}
示例#11
0
func Get(path string, params url.Values) []byte {
	req, err := http.NewRequest("GET", getURL(path, params), nil)
	utils.Check(err)
	return fire(req)
}
示例#12
0
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"]
}