github.com/wtfutil/wtf@v0.43.0/modules/asana/client.go (about) 1 package asana 2 3 import ( 4 "fmt" 5 "strings" 6 "time" 7 8 asana "bitbucket.org/mikehouston/asana-go" 9 ) 10 11 func fetchTasksFromProject(token, projectId, mode string) ([]*TaskItem, error) { 12 taskItems := []*TaskItem{} 13 uidToName := make(map[string]string) 14 15 client := asana.NewClientWithAccessToken(token) 16 17 uid, err := getCurrentUserId(client, mode) 18 if err != nil { 19 return nil, err 20 } 21 22 q := &asana.TaskQuery{ 23 Project: projectId, 24 } 25 26 fetchedTasks, _, err := getTasksFromAsana(client, q) 27 if err != nil { 28 return nil, fmt.Errorf("error fetching tasks: %s", err) 29 } 30 31 processFetchedTasks(client, &fetchedTasks, &taskItems, &uidToName, mode, projectId, uid) 32 33 return taskItems, nil 34 } 35 36 func fetchTasksFromProjectSections(token, projectId string, sections []string, mode string) ([]*TaskItem, error) { 37 taskItems := []*TaskItem{} 38 uidToName := make(map[string]string) 39 40 client := asana.NewClientWithAccessToken(token) 41 42 uid, err := getCurrentUserId(client, mode) 43 if err != nil { 44 return nil, err 45 } 46 47 p := &asana.Project{ 48 ID: projectId, 49 } 50 51 for _, section := range sections { 52 53 sectionId, err := findSection(client, p, section) 54 if err != nil { 55 return nil, fmt.Errorf("error fetching tasks: %s", err) 56 } 57 58 q := &asana.TaskQuery{ 59 Section: sectionId, 60 } 61 62 fetchedTasks, _, err := getTasksFromAsana(client, q) 63 if err != nil { 64 return nil, fmt.Errorf("error fetching tasks: %s", err) 65 } 66 67 if len(fetchedTasks) > 0 { 68 taskItem := &TaskItem{ 69 name: section, 70 taskType: TASK_SECTION, 71 } 72 73 taskItems = append(taskItems, taskItem) 74 } 75 76 processFetchedTasks(client, &fetchedTasks, &taskItems, &uidToName, mode, projectId, uid) 77 78 } 79 80 return taskItems, nil 81 } 82 83 func fetchTasksFromWorkspace(token, workspaceId, mode string) ([]*TaskItem, error) { 84 taskItems := []*TaskItem{} 85 uidToName := make(map[string]string) 86 87 client := asana.NewClientWithAccessToken(token) 88 89 uid, err := getCurrentUserId(client, mode) 90 if err != nil { 91 return nil, err 92 } 93 94 q := &asana.TaskQuery{ 95 Workspace: workspaceId, 96 Assignee: "me", 97 } 98 99 fetchedTasks, _, err := getTasksFromAsana(client, q) 100 if err != nil { 101 return nil, fmt.Errorf("error fetching tasks: %s", err) 102 } 103 104 processFetchedTasks(client, &fetchedTasks, &taskItems, &uidToName, mode, workspaceId, uid) 105 106 return taskItems, nil 107 108 } 109 110 func toggleTaskCompletionById(token, taskId string) error { 111 client := asana.NewClientWithAccessToken(token) 112 113 t := &asana.Task{ 114 ID: taskId, 115 } 116 117 err := t.Fetch(client) 118 if err != nil { 119 return fmt.Errorf("error fetching task: %s", err) 120 } 121 122 updateReq := &asana.UpdateTaskRequest{} 123 124 if *t.Completed { 125 f := false 126 updateReq.Completed = &f 127 } else { 128 t := true 129 updateReq.Completed = &t 130 } 131 132 err = t.Update(client, updateReq) 133 if err != nil { 134 return fmt.Errorf("error updating task: %s", err) 135 } 136 137 return nil 138 } 139 140 func processFetchedTasks(client *asana.Client, fetchedTasks *[]*asana.Task, taskItems *[]*TaskItem, uidToName *map[string]string, mode, projectId, uid string) { 141 142 for _, task := range *fetchedTasks { 143 switch { 144 case strings.HasSuffix(mode, "_all"): 145 if task.Assignee != nil { 146 // Check if we have already looked up this user 147 if assigneeName, ok := (*uidToName)[task.Assignee.ID]; ok { 148 task.Assignee.Name = assigneeName 149 } else { 150 // We haven't looked up this user before, perform the lookup now 151 assigneeName, err := getOtherUserEmail(client, task.Assignee.ID) 152 if err != nil { 153 task.Assignee.Name = "Error" 154 } 155 (*uidToName)[task.Assignee.ID] = assigneeName 156 task.Assignee.Name = assigneeName 157 } 158 } else { 159 task.Assignee = &asana.User{ 160 Name: "Unassigned", 161 } 162 } 163 taskItem := buildTaskItem(task, projectId) 164 (*taskItems) = append((*taskItems), taskItem) 165 case !strings.HasSuffix(mode, "_all") && task.Assignee != nil && task.Assignee.ID == uid: 166 taskItem := buildTaskItem(task, projectId) 167 (*taskItems) = append((*taskItems), taskItem) 168 } 169 } 170 } 171 172 func buildTaskItem(task *asana.Task, projectId string) *TaskItem { 173 dueOnString := "" 174 if task.DueOn != nil { 175 dueOn := time.Time(*task.DueOn) 176 currentYear, _, _ := time.Now().Date() 177 if currentYear != dueOn.Year() { 178 dueOnString = dueOn.Format("Jan 2 2006") 179 } else { 180 dueOnString = dueOn.Format("Jan 2") 181 } 182 } 183 184 assignString := "" 185 if task.Assignee != nil { 186 assignString = task.Assignee.Name 187 } 188 189 taskItem := &TaskItem{ 190 name: task.Name, 191 id: task.ID, 192 numSubtasks: task.NumSubtasks, 193 dueOn: dueOnString, 194 url: fmt.Sprintf("https://app.asana.com/0/%s/%s/f", projectId, task.ID), 195 taskType: TASK_TYPE, 196 completed: *task.Completed, 197 assignee: assignString, 198 } 199 200 return taskItem 201 202 } 203 204 func getOtherUserEmail(client *asana.Client, uid string) (string, error) { 205 if uid == "" { 206 return "", fmt.Errorf("missing uid") 207 } 208 209 u := &asana.User{ 210 ID: uid, 211 } 212 213 err := u.Fetch(client, nil) 214 if err != nil { 215 return "", fmt.Errorf("error fetching user: %s", err) 216 } 217 218 return u.Email, nil 219 } 220 221 func getCurrentUserId(client *asana.Client, mode string) (string, error) { 222 if strings.HasSuffix(mode, "_all") { 223 return "", nil 224 } 225 u, err := client.CurrentUser() 226 if err != nil { 227 return "", fmt.Errorf("error getting current user: %s", err) 228 } 229 230 return u.ID, nil 231 } 232 233 func findSection(client *asana.Client, project *asana.Project, sectionName string) (string, error) { 234 sectionId := "" 235 236 sections, _, err := project.Sections(client, &asana.Options{ 237 Limit: 100, 238 }) 239 if err != nil { 240 return "", fmt.Errorf("error getting sections: %s", err) 241 } 242 243 for _, section := range sections { 244 if section.Name == sectionName { 245 sectionId = section.ID 246 break 247 } 248 } 249 250 if sectionId == "" { 251 return "", fmt.Errorf("we didn't find the section %s", sectionName) 252 } 253 254 return sectionId, nil 255 } 256 257 func getTasksFromAsana(client *asana.Client, q *asana.TaskQuery) ([]*asana.Task, bool, error) { 258 moreTasks := false 259 260 tasks, np, err := client.QueryTasks(q, &asana.Options{ 261 Limit: 100, 262 Fields: []string{ 263 "assignee", 264 "name", 265 "num_subtasks", 266 "due_on", 267 "completed", 268 }, 269 }) 270 271 if err != nil { 272 return nil, false, fmt.Errorf("error querying tasks: %s", err) 273 } 274 275 if np != nil { 276 moreTasks = true 277 } 278 279 return tasks, moreTasks, nil 280 }