-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathget_contacts.go
167 lines (144 loc) · 4.03 KB
/
get_contacts.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
package main
import (
"encoding/json"
"errors"
"fmt"
"log"
"strings"
"code.google.com/p/goauth2/oauth"
)
func get_primary_email(gd_email_list []interface{}) (string, error) {
if len(gd_email_list) < 1 {
return "", errors.New("Less than one element in the email list")
}
for i := range gd_email_list {
email_mapping := gd_email_list[i].(map[string]interface{})
if email_mapping["primary"] == "true" {
return email_mapping["address"].(string), nil
}
}
email_mapping := gd_email_list[0].(map[string]interface{})
email := email_mapping["address"].(string)
return email, nil
}
// Returns a list of email_entry structs to be attached to an contact_entry
func get_email(gd_email_list []interface{}) ([]email_entry, error) {
var email_entry_list []email_entry
if len(gd_email_list) < 1 {
return email_entry_list, errors.New("Less than one element in the email list")
}
for i := range gd_email_list {
email_mapping := gd_email_list[i].(map[string]interface{})
for k, v := range(email_mapping) {
value := v.(string)
if k == "rel" {
idx := strings.Index(value, "#")
address_association := value[idx+1:]
email_entry_list = append(email_entry_list, email_entry { email_mapping["address"].(string), address_association})
}
}
}
return email_entry_list, nil
}
type contacts_response struct {
Feed struct {
Entries entry_list `json:"entry"`
} `json:"feed"`
}
type entry_list []contact_entry
func (list *entry_list) UnmarshalJSON(b []byte) error {
// Unmarshal all entries
var entries []contact_entry
err := json.Unmarshal(b, &entries)
if err != nil {
return err
}
// Keep only the entries with email
for _, v := range entries {
if len(v.Emails) != 0 && v.Name != "" {
*list = append(*list, v)
}
}
return nil
}
type contact_entry struct {
Emails []email_entry
Name string
}
type email_entry struct {
Address string
Association string
}
func (ce *contact_entry) UnmarshalJSON(b []byte) error {
data := make(map[string]interface{})
err := json.Unmarshal(b, &data)
if err != nil {
return err
}
gdEmail := data["gd$email"]
if gdEmail == nil {
ce = nil
return nil
}
emails, err := get_email(gdEmail.([]interface{}))
if err != nil {
return err
}
title := data["title"].(map[string]interface{})["$t"]
if title != nil && title != "" {
ce.Name = title.(string)
}
ce.Emails = emails
return nil
}
// This function does the work of obtaining the contacts from the server
func fetch_all_contacts(transport *oauth.Transport) contacts_response {
// XXX: increase the max-results
request_url := fmt.Sprintf("https://www.google.com/m8/feeds/contacts/default/thin?alt=json&max-results=10000")
// fmt.Println("request_url is", request_url)
resp, _ := transport.Client().Get(request_url)
defer resp.Body.Close()
var result contacts_response
err := json.NewDecoder(resp.Body).Decode(&result)
if err != nil {
log.Fatal(err)
}
return result
}
// This function turns the response from fetch_all_contacts into a list of strings
func all_contacts(transport *oauth.Transport) []string {
result := fetch_all_contacts(transport)
var all_contacts []string
for _, v := range result.Feed.Entries {
for i := range v.Emails {
all_contacts = append(all_contacts, fmt.Sprintf("%s\t%s\t%s", v.Emails[i].Address, v.Name, v.Emails[i].Association))
}
}
return all_contacts
}
func print_all_contacts(transport *oauth.Transport) {
all := all_contacts(transport)
if len(all) < 1 {
fmt.Println("No contacts found")
} else {
for line := range all {
fmt.Printf("%s\n", all[line])
}
}
}
func print_matching_contacts(transport *oauth.Transport, query_str string) {
all := all_contacts(transport)
contacts_matched := 0
for line := range all {
if strings.Contains(strings.ToLower(all[line]), strings.ToLower(query_str)) {
if contacts_matched == 0 {
fmt.Printf("Gonetact found contacts that matched your query '%s'\n", query_str)
}
fmt.Printf("%s\n", all[line])
contacts_matched++
}
}
if contacts_matched == 0 {
fmt.Printf("I couldn't find any contacts that matched the query '%s'\n", query_str)
}
}