google_contacts_api 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -28,14 +28,19 @@ oauth_access_token_for_user
28
28
 
29
29
  google_contacts_user = GoogleContactsApi::User.new(oauth_access_token_for_user)
30
30
  contacts = google_contacts_user.contacts
31
+ # => <GoogleContactsApi::ContactSet: @start_index=1, @items_per_page=100000, @total_results=638>
31
32
  groups = google_contacts_user.groups
33
+ # => <GoogleContactsApi::GroupSet: @start_index=1, @items_per_page=100000, @total_results=8>
32
34
 
33
35
  # group methods
34
36
  group = groups.first
37
+ # => <GoogleContactsApi::Group: System Group: My Contacts>
35
38
  group.contacts
39
+ # => <GoogleContactsApi::ContactSet: @start_index=1, @items_per_page=100000, @total_results=20>
36
40
 
37
41
  # contact methods
38
42
  contact = contacts.first
43
+ # => <GoogleContactsApi::Contact: Alvin>
39
44
  contact.photo
40
45
  contact.title
41
46
  contact.id
@@ -43,7 +48,9 @@ contact.primary_email
43
48
  contact.emails
44
49
  ```
45
50
 
46
- In addition, Contacts and Groups are subclasses of [Hashie::Mash](https://github.com/intridea/hashie), so you can access any of the underlying data directly. Note that data is retrieved using Google's JSON API so the equivalent content of an XML element from the XML API is stored under the key "$t".
51
+ `ContactSet` and `GroupSet` both implement `Enumberable`.
52
+
53
+ In addition, `Contact` and `Group` are subclasses of [Hashie::Mash](https://github.com/intridea/hashie), so you can access any of the underlying data directly (for example, if Google returns new data [in their API](https://developers.google.com/google-apps/contacts/v3/)). Note that data is retrieved using Google's JSON API so the equivalent content of an XML element from the XML API is stored under the key "$t".
47
54
 
48
55
  The easiest way to see the convenience methods I've provided is to look at the RSpec tests.
49
56
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.1
1
+ 0.4.2
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "google_contacts_api"
8
- s.version = "0.4.1"
8
+ s.version = "0.4.2"
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"]
@@ -35,6 +35,7 @@ Gem::Specification.new do |s|
35
35
  "lib/google_contacts_api/result.rb",
36
36
  "lib/google_contacts_api/result_set.rb",
37
37
  "lib/google_contacts_api/user.rb",
38
+ "lib/google_contacts_api/version.rb",
38
39
  "spec/contact_set.json",
39
40
  "spec/empty_contact_set.json",
40
41
  "spec/errors/auth_sub_401.html",
@@ -7,7 +7,4 @@ require 'google_contacts_api/contact_set'
7
7
  require 'google_contacts_api/result'
8
8
  require 'google_contacts_api/group'
9
9
  require 'google_contacts_api/contact'
10
-
11
- module GoogleContactsApi
12
- VERSION = "0.3.3"
13
- end
10
+ require 'google_contacts_api/version'
@@ -1,39 +1,40 @@
1
1
  module GoogleContactsApi
2
+ # Represents a single contact.
3
+ # Methods we could implement:
4
+ # :categories, (:content again), :links, (:title again), :email
5
+ # :extended_properties, :deleted, :im, :name,
6
+ # :organizations, :phone_numbers, :structured_postal_addresses, :where
2
7
  class Contact < GoogleContactsApi::Result
3
- # :categories, (:content again), :links, (:title again), :email
4
- # :extended_properties, :deleted, :im, :name,
5
- # :organizations, :phone_numbers, :structured_postal_addresses, :where
6
-
7
8
  # Returns the array of links, as link is an array for Hashie.
8
9
  def links
9
10
  self["link"].map { |l| l.href }
10
11
  end
11
-
12
+
12
13
  # Returns link to get this contact
13
14
  def self_link
14
15
  _link = self["link"].find { |l| l.rel == "self" }
15
16
  _link ? _link.href : nil
16
17
  end
17
-
18
+
18
19
  # Returns alternative, possibly off-Google home page link
19
20
  def alternate_link
20
21
  _link = self["link"].find { |l| l.rel == "alternate" }
21
22
  _link ? _link.href : nil
22
23
  end
23
-
24
+
24
25
  # Returns link for photo
25
26
  # (still need authentication to get the photo data, though)
26
27
  def photo_link
27
28
  _link = self["link"].find { |l| l.rel == "http://schemas.google.com/contacts/2008/rel#photo" }
28
29
  _link ? _link.href : nil
29
30
  end
30
-
31
+
31
32
  # Returns binary data for the photo. You can probably
32
33
  # use it in a data-uri. This is in PNG format.
33
34
  def photo
34
35
  return nil unless @api && photo_link
35
36
  response = @api.oauth.get(photo_link)
36
-
37
+
37
38
  case GoogleContactsApi::Api.parse_response_code(response)
38
39
  # maybe return a placeholder instead of nil
39
40
  when 400; return nil
@@ -45,13 +46,13 @@ module GoogleContactsApi
45
46
  else; return response.body
46
47
  end
47
48
  end
48
-
49
+
49
50
  # Returns link to add/replace the photo
50
51
  def edit_photo_link
51
52
  _link = self["link"].find { |l| l.rel == "http://schemas.google.com/contacts/2008/rel#edit_photo" }
52
53
  _link ? _link.href : nil
53
54
  end
54
-
55
+
55
56
  # Returns link to edit the contact
56
57
  def edit_link
57
58
  _link = self["link"].find { |l| l.rel == "edit" }
@@ -62,12 +63,12 @@ module GoogleContactsApi
62
63
  def phone_numbers
63
64
  self["gd$phoneNumber"] ? self["gd$phoneNumber"].map { |e| e['$t'] } : []
64
65
  end
65
-
66
+
66
67
  # Returns all email addresses for the contact
67
68
  def emails
68
69
  self["gd$email"] ? self["gd$email"].map { |e| e.address } : []
69
70
  end
70
-
71
+
71
72
  # Returns primary email for the contact
72
73
  def primary_email
73
74
  if self["gd$email"]
@@ -77,13 +78,15 @@ module GoogleContactsApi
77
78
  nil # no emails at all
78
79
  end
79
80
  end
80
-
81
+
81
82
  # Returns all instant messaging addresses for the contact.
82
83
  # Doesn't yet distinguish protocols
83
84
  def ims
84
85
  self["gd$im"] ? self["gd$im"].map { |i| i.address } : []
85
86
  end
86
87
 
88
+ # Convenience method to return a nested $t field.
89
+ # If the field doesn't exist, return nil
87
90
  def nested_t_field_or_nil(level1, level2)
88
91
  if self[level1]
89
92
  self[level1][level2] ? self[level1][level2]['$t']: nil
@@ -116,12 +119,17 @@ module GoogleContactsApi
116
119
  spouse_rel['$t'] if spouse_rel
117
120
  end
118
121
 
122
+ # Return an Array of Hashes representing addresses with formatted metadata.
119
123
  def addresses
120
124
  self['gd$structuredPostalAddress'] ? self['gd$structuredPostalAddress'].map(&method(:format_address)) : []
121
125
  end
126
+
127
+ # Return an Array of Hashes representing phone numbers with formatted metadata.
122
128
  def phone_numbers_full
123
129
  self["gd$phoneNumber"] ? self["gd$phoneNumber"].map(&method(:format_phone_number)) : []
124
130
  end
131
+
132
+ # Return an Array of Hashes representing emails with formatted metadata.
125
133
  def emails_full
126
134
  self["gd$email"] ? self["gd$email"].map(&method(:format_email)) : []
127
135
  end
@@ -1,6 +1,7 @@
1
1
  module GoogleContactsApi
2
+ # Represents a set of contacts.
2
3
  class ContactSet < GoogleContactsApi::ResultSet
3
- # Populate from a response that contains contacts
4
+ # Initialize a ContactSet from an API response body that contains contacts data
4
5
  def initialize(response_body, api = nil)
5
6
  super
6
7
  if @parsed.nil? || @parsed.feed.nil? || @parsed.feed.entry.nil?
@@ -1,3 +1,4 @@
1
+ # Module that implements a method to get contacts for a user or group
1
2
  module GoogleContactsApi
2
3
  module Contacts
3
4
  # Retrieve the contacts for this user or group
@@ -1,33 +1,35 @@
1
1
  module GoogleContactsApi
2
+ # Represents a single group.
2
3
  class Group < GoogleContactsApi::Result
3
4
  include GoogleContactsApi::Contacts
4
- # Populate from a single entry element in the result response
5
- # when requesting a set of Contacts
6
5
 
6
+ # Return true if this is a system group.
7
7
  def system_group?
8
8
  !self["gContact$systemGroup"].nil?
9
9
  end
10
10
 
11
+ # Return the contacts in this group and cache them.
11
12
  def contacts(params = {})
12
13
  # contacts in this group
13
14
  @contacts ||= super({"group" => self.id}.merge(params))
14
15
  end
15
-
16
+
17
+ # Return the contacts in this group, retrieving them again from the server.
16
18
  def contacts!(params = {})
17
19
  # contacts in this group
18
20
  @contacts = super({"group" => self.id}.merge(params))
19
21
  end
20
-
22
+
21
23
  # Returns the array of links, as link is an array for Hashie.
22
24
  def links
23
25
  self["link"].map { |l| l.href }
24
26
  end
25
-
27
+
26
28
  def self_link
27
29
  _link = self["link"].find { |l| l.rel == "self" }
28
30
  _link ? _link.href : nil
29
31
  end
30
-
32
+
31
33
  def edit_link
32
34
  _link = self["link"].find { |l| l.rel == "edit" }
33
35
  _link ? _link.href : nil
@@ -1,6 +1,6 @@
1
1
  module GoogleContactsApi
2
2
  class GroupSet < GoogleContactsApi::ResultSet
3
- # Populate from a response that contains contacts
3
+ # Initialize a GroupSet from an API response body that contains groups data
4
4
  def initialize(response_body, api = nil)
5
5
  super
6
6
  @results = @parsed.feed.entry.map { |e| GoogleContactsApi::Group.new(e, nil, api) }
@@ -1,16 +1,12 @@
1
1
  require 'hashie'
2
2
 
3
3
  module GoogleContactsApi
4
- # Base class for Group and Contact
4
+ # Base class for Group and Contact.
5
+ # In the JSON responses, ":" from the equivalent XML response is replaced
6
+ # with a "$", while element content is instead keyed with "$t".
5
7
  class Result < Hashie::Mash
6
- # Note that the title is really just the (full) name
7
- # ":" replaced with $, element content is keyed with $t
8
-
9
- # These are the accessors we can write
10
- # :id, :title, :updated, :content
11
-
12
8
  attr_reader :api
13
- # Populate from a single result Hash/Hashie
9
+ # Initialize a Result from a single result's Hash/Hashie
14
10
  def initialize(source_hash = nil, default = nil, api = nil, &blk)
15
11
  @api = api if api
16
12
  super(source_hash, default, &blk)
@@ -25,7 +21,9 @@ module GoogleContactsApi
25
21
  _id = self["id"]
26
22
  _id ? _id["$t"] : nil
27
23
  end
28
-
24
+
25
+ # For Contacts, returns the (full) name.
26
+ # For Groups, returns the name of the group.
29
27
  def title
30
28
  _title = self["title"]
31
29
  _title ? _title["$t"] : nil
@@ -1,7 +1,8 @@
1
1
  require 'json'
2
2
 
3
3
  module GoogleContactsApi
4
- # Base class for GroupSet and ContactSet
4
+ # Base class for GroupSet and ContactSet that generically represents
5
+ # a set of results.
5
6
  class ResultSet
6
7
  include Enumerable
7
8
  attr_reader :api
@@ -7,8 +7,7 @@ module GoogleContactsApi
7
7
  @api = GoogleContactsApi::Api.new(oauth)
8
8
  end
9
9
 
10
- # Retrieve the groups for this user
11
- # TODO: Handle 403, 404, 401
10
+ # Retrieve the groups for this user.
12
11
  def groups(params = {})
13
12
  params = params.with_indifferent_access
14
13
  # compose params into a string
@@ -27,6 +26,7 @@ module GoogleContactsApi
27
26
  response = @api.get(url, params)
28
27
 
29
28
  case GoogleContactsApi::Api.parse_response_code(response)
29
+ # TODO: Better handle 401, 403, 404
30
30
  when 401; raise
31
31
  when 403; raise
32
32
  when 404; raise
@@ -0,0 +1,10 @@
1
+ module GoogleContactsApi
2
+ module Version
3
+ MAJOR = 0
4
+ MINOR = 4
5
+ PATCH = 2
6
+ BUILD = nil
7
+
8
+ STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.')
9
+ end
10
+ end
data/spec/spec_helper.rb CHANGED
@@ -6,7 +6,7 @@ require 'hashie'
6
6
  require 'net/http'
7
7
  require 'google_contacts_api'
8
8
 
9
- puts "Testing version #{GoogleContactsApi::VERSION}"
9
+ puts "Testing version #{GoogleContactsApi::Version::STRING}"
10
10
 
11
11
  # Requires supporting files with custom matchers and macros, etc,
12
12
  # in ./support/ and its subdirectories.
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.1
4
+ version: 0.4.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -213,6 +213,7 @@ files:
213
213
  - lib/google_contacts_api/result.rb
214
214
  - lib/google_contacts_api/result_set.rb
215
215
  - lib/google_contacts_api/user.rb
216
+ - lib/google_contacts_api/version.rb
216
217
  - spec/contact_set.json
217
218
  - spec/empty_contact_set.json
218
219
  - spec/errors/auth_sub_401.html
@@ -234,7 +235,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
234
235
  version: '0'
235
236
  segments:
236
237
  - 0
237
- hash: -2779317021500043099
238
+ hash: -1381068612794242354
238
239
  required_rubygems_version: !ruby/object:Gem::Requirement
239
240
  none: false
240
241
  requirements: