google_contacts_api 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/google_contacts_api.gemspec +2 -2
- data/lib/google_contacts_api/contact.rb +71 -25
- data/spec/google_contacts_api_spec.rb +62 -21
- metadata +3 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.6.0
|
data/google_contacts_api.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "google_contacts_api"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.6.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Alvin Liang"]
|
12
|
-
s.date = "2015-
|
12
|
+
s.date = "2015-06-15"
|
13
13
|
s.description = "Lets you read from the Google Contacts API. Posting to come later."
|
14
14
|
s.email = "ayliang@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -22,10 +22,15 @@ module GoogleContactsApi
|
|
22
22
|
_link ? _link.href : nil
|
23
23
|
end
|
24
24
|
|
25
|
+
# Returns link entry for the photo
|
26
|
+
def photo_link_entry
|
27
|
+
self["link"].find { |l| l.rel == "http://schemas.google.com/contacts/2008/rel#photo" }
|
28
|
+
end
|
29
|
+
|
25
30
|
# Returns link for photo
|
26
31
|
# (still need authentication to get the photo data, though)
|
27
32
|
def photo_link
|
28
|
-
_link =
|
33
|
+
_link = photo_link_entry
|
29
34
|
_link ? _link.href : nil
|
30
35
|
end
|
31
36
|
|
@@ -85,6 +90,21 @@ module GoogleContactsApi
|
|
85
90
|
self["gd$im"] ? self["gd$im"].map { |i| i.address } : []
|
86
91
|
end
|
87
92
|
|
93
|
+
def photo_with_metadata
|
94
|
+
# etag is always specified if actual photo is present
|
95
|
+
_link = photo_link_entry
|
96
|
+
return nil unless @api && _link['gd$etag']
|
97
|
+
|
98
|
+
response = @api.oauth.get(_link.href)
|
99
|
+
if GoogleContactsApi::Api.parse_response_code(response) == 200
|
100
|
+
{
|
101
|
+
etag: _link['gd$etag'].gsub('"',''),
|
102
|
+
content_type: response.headers['content-type'],
|
103
|
+
data: response.body
|
104
|
+
}
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
88
108
|
# Convenience method to return a nested $t field.
|
89
109
|
# If the field doesn't exist, return nil
|
90
110
|
def nested_t_field_or_nil(level1, level2)
|
@@ -110,6 +130,12 @@ module GoogleContactsApi
|
|
110
130
|
def name_suffix
|
111
131
|
nested_t_field_or_nil 'gd$name', 'gd$nameSuffix'
|
112
132
|
end
|
133
|
+
def birthday
|
134
|
+
if self['gContact$birthday']
|
135
|
+
day, month, year = self['gContact$birthday']['when'].split('-').reverse
|
136
|
+
{ year: year == '' ? nil : year.to_i, month: month.to_i, day: day.to_i }
|
137
|
+
end
|
138
|
+
end
|
113
139
|
|
114
140
|
def relations
|
115
141
|
self['gContact$relation'] ? self['gContact$relation'] : []
|
@@ -123,46 +149,66 @@ module GoogleContactsApi
|
|
123
149
|
|
124
150
|
# Return an Array of Hashes representing addresses with formatted metadata.
|
125
151
|
def addresses
|
126
|
-
|
152
|
+
format_entities('gd$structuredPostalAddress', :format_address)
|
153
|
+
end
|
154
|
+
def organizations
|
155
|
+
format_entities('gd$organization')
|
156
|
+
end
|
157
|
+
def websites
|
158
|
+
format_entities('gContact$website')
|
127
159
|
end
|
128
160
|
|
129
161
|
# Return an Array of Hashes representing phone numbers with formatted metadata.
|
130
162
|
def phone_numbers_full
|
131
|
-
|
163
|
+
format_entities('gd$phoneNumber', :format_phone_number)
|
132
164
|
end
|
133
165
|
|
134
166
|
# Return an Array of Hashes representing emails with formatted metadata.
|
135
167
|
def emails_full
|
136
|
-
|
168
|
+
format_entities('gd$email')
|
137
169
|
end
|
138
170
|
|
139
171
|
private
|
172
|
+
def format_entities(key, format_method=:format_entity)
|
173
|
+
self[key] ? self[key].map(&method(format_method)) : []
|
174
|
+
end
|
175
|
+
|
176
|
+
def format_entity(unformatted, default_rel=nil, text_key=nil)
|
177
|
+
attrs = Hash[unformatted.map { |key, value|
|
178
|
+
case key
|
179
|
+
when 'primary'
|
180
|
+
[:primary, value == true || value == 'true']
|
181
|
+
when 'rel'
|
182
|
+
[:rel, value.gsub('http://schemas.google.com/g/2005#', '')]
|
183
|
+
when '$t'
|
184
|
+
[text_key || key.underscore.to_sym, value]
|
185
|
+
else
|
186
|
+
[key.sub('gd$', '').underscore.to_sym, value['$t'] ? value['$t'] : value]
|
187
|
+
end
|
188
|
+
}]
|
189
|
+
attrs[:rel] ||= default_rel
|
190
|
+
attrs[:primary] = false if attrs[:primary].nil?
|
191
|
+
attrs
|
192
|
+
end
|
193
|
+
|
140
194
|
def format_address(unformatted)
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
195
|
+
address = format_entity(unformatted, 'work')
|
196
|
+
address[:street] ||= nil
|
197
|
+
address[:city] ||= nil
|
198
|
+
address[:region] ||= nil
|
199
|
+
address[:postcode] ||= nil
|
200
|
+
address[:country] = format_country(unformatted['gd$country'])
|
201
|
+
address.delete :formatted_address
|
202
|
+
address
|
148
203
|
end
|
149
204
|
|
150
|
-
def
|
151
|
-
|
152
|
-
|
153
|
-
formatted[key.underscore.to_sym] = value ? value.gsub('http://schemas.google.com/g/2005#', '') : value
|
154
|
-
end
|
155
|
-
formatted[:primary] = unformatted['primary'] ? unformatted['primary'] == 'true' : false
|
156
|
-
formatted
|
205
|
+
def format_country(country)
|
206
|
+
return nil unless country
|
207
|
+
country['$t'].nil? || country['$t'] == '' ? country['code'] : country['$t']
|
157
208
|
end
|
158
209
|
|
159
210
|
def format_phone_number(unformatted)
|
160
|
-
unformatted
|
161
|
-
unformatted.delete '$t'
|
162
|
-
format_email_or_phone unformatted
|
163
|
-
end
|
164
|
-
def format_email(unformatted)
|
165
|
-
format_email_or_phone unformatted
|
211
|
+
format_entity unformatted, nil, :number
|
166
212
|
end
|
167
213
|
end
|
168
|
-
end
|
214
|
+
end
|
@@ -266,6 +266,14 @@ describe "GoogleContactsApi" do
|
|
266
266
|
it "should return the right self link" do
|
267
267
|
expect(@contact.self_link).to eq("https://www.google.com/m8/feeds/contacts/example%40gmail.com/full/0")
|
268
268
|
end
|
269
|
+
it "should return the right photo link entry" do
|
270
|
+
expect(@contact.photo_link_entry).to eq({
|
271
|
+
"rel" => "http://schemas.google.com/contacts/2008/rel#photo",
|
272
|
+
"type" => "image/*",
|
273
|
+
"href" => "https://www.google.com/m8/feeds/photos/media/example%40gmail.com/0",
|
274
|
+
"gd$etag" => "\"dxt2DAEZfCp7ImA-AV4zRxBoPG4UK3owXBM.\""
|
275
|
+
})
|
276
|
+
end
|
269
277
|
it "should return the right photo link" do
|
270
278
|
expect(@contact.photo_link).to eq("https://www.google.com/m8/feeds/photos/media/example%40gmail.com/0")
|
271
279
|
end
|
@@ -289,6 +297,22 @@ describe "GoogleContactsApi" do
|
|
289
297
|
expect(@oauth).to receive("get").with(@contact.photo_link)
|
290
298
|
@contact.photo
|
291
299
|
end
|
300
|
+
it "should fetch a photo with metadata" do
|
301
|
+
@oauth = double("oauth")
|
302
|
+
allow(@oauth).to receive(:get).and_return(Hashie::Mash.new({
|
303
|
+
"body" => "some response",
|
304
|
+
"code" => 200,
|
305
|
+
"headers" => { "content-type" => "image/jpeg" }
|
306
|
+
}))
|
307
|
+
@api = double("api")
|
308
|
+
allow(@api).to receive(:oauth).and_return(@oauth)
|
309
|
+
@contact = GoogleContactsApi::Contact.new(@contact_json_hash, nil, @api)
|
310
|
+
expect(@oauth).to receive("get").with(@contact.photo_link)
|
311
|
+
expect(@contact.photo_with_metadata).to eq( { data: 'some response',
|
312
|
+
etag: 'dxt2DAEZfCp7ImA-AV4zRxBoPG4UK3owXBM.',
|
313
|
+
content_type: 'image/jpeg'
|
314
|
+
} )
|
315
|
+
end
|
292
316
|
# TODO: there isn't any phone number in here
|
293
317
|
pending "should return all phone numbers"
|
294
318
|
it "should return all e-mail addresses" do
|
@@ -331,6 +355,9 @@ describe "GoogleContactsApi" do
|
|
331
355
|
'gd$familyName' => { '$t' => 'Doe' },
|
332
356
|
'gd$fullName' => { '$t' => 'John Doe' }
|
333
357
|
},
|
358
|
+
'gContact$birthday' => {
|
359
|
+
'when' => '1988-05-12'
|
360
|
+
},
|
334
361
|
'gContact$relation' => [ { '$t' => 'Jane', 'rel' => 'spouse' } ],
|
335
362
|
'gd$structuredPostalAddress' => [
|
336
363
|
{
|
@@ -343,12 +370,11 @@ describe "GoogleContactsApi" do
|
|
343
370
|
},
|
344
371
|
{
|
345
372
|
'rel' => 'http://schemas.google.com/g/2005#home',
|
373
|
+
'primary' => 'true',
|
346
374
|
'gd$country' => { '$t' => 'United States of America' },
|
347
375
|
'gd$formattedAddress' => { '$t' => "123 Far Ln.\nAnywhere\nMO\n67891\nUnited States of America" },
|
348
376
|
'gd$city' => { '$t' => 'Anywhere' },
|
349
|
-
'gd$street' => { '$t' => '123 Far Ln.' }
|
350
|
-
'gd$region' => { '$t' => 'MO' },
|
351
|
-
'gd$postcode' => { '$t' => '67891' }
|
377
|
+
'gd$street' => { '$t' => '123 Far Ln.' }
|
352
378
|
}
|
353
379
|
],
|
354
380
|
'gd$email' => [
|
@@ -364,6 +390,13 @@ describe "GoogleContactsApi" do
|
|
364
390
|
'$t' => '(123) 334-5158',
|
365
391
|
'rel' => 'http://schemas.google.com/g/2005#mobile'
|
366
392
|
}
|
393
|
+
],
|
394
|
+
'gd$organization' => [
|
395
|
+
{
|
396
|
+
'gd$orgTitle' => { '$t' => 'Worker Person' },
|
397
|
+
'gd$orgName' => { '$t' => 'Example, Inc' },
|
398
|
+
'rel' => 'http://schemas.google.com/g/2005#other'
|
399
|
+
}
|
367
400
|
]
|
368
401
|
)
|
369
402
|
end
|
@@ -399,29 +432,23 @@ describe "GoogleContactsApi" do
|
|
399
432
|
expect(@partly_empty.spouse).to be_nil
|
400
433
|
expect(@contact_v3.spouse).to eq('Jane')
|
401
434
|
end
|
435
|
+
|
436
|
+
it 'has birthday' do
|
437
|
+
expect(@empty.birthday).to be_nil
|
438
|
+
expect(@contact_v3.birthday).to eq({ year: 1988, month: 5, day: 12 })
|
439
|
+
|
440
|
+
contact_birthday_no_year = GoogleContactsApi::Contact.new('gContact$birthday' => { 'when' => '--05-12' })
|
441
|
+
expect(contact_birthday_no_year.birthday).to eq({ year: nil, month: 5, day: 12 })
|
442
|
+
end
|
402
443
|
|
403
444
|
it 'has addresses' do
|
404
445
|
expect(@empty.addresses).to eq([])
|
405
446
|
|
406
447
|
formatted_addresses = [
|
407
|
-
{
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
:city => 'Somwhere',
|
412
|
-
:street => '2345 Long Dr. #232',
|
413
|
-
:region => 'IL',
|
414
|
-
:postcode => '12345'
|
415
|
-
},
|
416
|
-
{
|
417
|
-
:rel => 'home',
|
418
|
-
:country => 'United States of America',
|
419
|
-
:formatted_address => "123 Far Ln.\nAnywhere\nMO\n67891\nUnited States of America",
|
420
|
-
:city => 'Anywhere',
|
421
|
-
:street => '123 Far Ln.',
|
422
|
-
:region => 'MO',
|
423
|
-
:postcode => '67891'
|
424
|
-
}
|
448
|
+
{ rel: 'work', primary: false, country: 'United States of America', city: 'Somwhere', street: '2345 Long Dr. #232',
|
449
|
+
region: 'IL', postcode: '12345' },
|
450
|
+
{ rel: 'home', primary: true, country: 'United States of America', city: 'Anywhere', street: '123 Far Ln.',
|
451
|
+
region: nil, postcode: nil }
|
425
452
|
]
|
426
453
|
expect(@contact_v3.addresses).to eq(formatted_addresses)
|
427
454
|
end
|
@@ -434,6 +461,20 @@ describe "GoogleContactsApi" do
|
|
434
461
|
expect(@empty.emails_full).to eq([])
|
435
462
|
expect(@contact_v3.emails_full).to eq([ { :primary => true, :address => 'johnsmith@example.com', :rel => 'other' } ])
|
436
463
|
end
|
464
|
+
|
465
|
+
it 'has organizations' do
|
466
|
+
expect(@empty.organizations).to eq([])
|
467
|
+
|
468
|
+
formatted_organizations = [
|
469
|
+
{
|
470
|
+
org_title: 'Worker Person',
|
471
|
+
org_name: 'Example, Inc',
|
472
|
+
primary: false,
|
473
|
+
rel: 'other'
|
474
|
+
}
|
475
|
+
]
|
476
|
+
expect(@contact_v3.organizations).to eq(formatted_organizations)
|
477
|
+
end
|
437
478
|
end
|
438
479
|
end
|
439
480
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: google_contacts_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-06-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -236,7 +236,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
236
236
|
version: '0'
|
237
237
|
segments:
|
238
238
|
- 0
|
239
|
-
hash: -
|
239
|
+
hash: -3275918105127347361
|
240
240
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
241
241
|
none: false
|
242
242
|
requirements:
|