Class: GContacts::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/google-contacts/client.rb

Constant Summary

API_URI =
{
  :contacts => {:all => "https://www.google.com/m8/feeds/contacts/default/%s", :create => URI("https://www.google.com/m8/feeds/contacts/default/full"), :get => "https://www.google.com/m8/feeds/contacts/default/%s/%s", :update => "https://www.google.com/m8/feeds/contacts/default/full/%s", :batch => URI("https://www.google.com/m8/feeds/contacts/default/full/batch")},
  :groups => {:all => "https://www.google.com/m8/feeds/groups/default/%s", :create => URI("https://www.google.com/m8/feeds/groups/default/full"), :get => "https://www.google.com/m8/feeds/groups/default/%s/%s", :update => "https://www.google.com/m8/feeds/groups/default/full/%s", :batch => URI("https://www.google.com/m8/feeds/groups/default/full/batch")}
}

Instance Method Summary (collapse)

Constructor Details

- (GContacts::Client) initialize(args)

Initializes a new client

Parameters:

  • args (Hash)

Options Hash (args):

  • :access_token (String)

    OAuth2 access token

  • :default_type (Symbol)

    Which API to call by default, can either be :contacts or :groups, defaults to :contacts

  • :debug_output (IO, Optional)

    Dump the results of HTTP requests to the given IO

Raises:

  • (GContacts::MissingToken)


23
24
25
26
27
28
29
# File 'lib/google-contacts/client.rb', line 23

def initialize(args)
  unless args[:access_token]
    raise ArgumentError, "Access token must be passed"
  end

  @options = {:default_type => :contacts}.merge(args)
end

Instance Method Details

- (GContacts::List) all(args = {})

Retrieves all contacts/groups up to the default limit

Parameters:

  • args (Hash) (defaults to: {})

Options Hash (args):

  • :params (Hash, Optional)

    Query string arguments when sending the API request

  • :headers (Hash, Optional)

    Any additional headers to pass with the API request

  • :api_type (Symbol, Optional)

    Override which part of the API is called, can either be :contacts or :groups

Returns:

Raises:

  • (Net::HTTPError)


41
42
43
44
45
46
47
# File 'lib/google-contacts/client.rb', line 41

def all(args={})
  uri = API_URI[args.delete(:api_type) || @options[:default_type]]
  raise ArgumentError, "Unsupported type given" unless uri

  response = http_request(:get, URI(uri[:all] % (args.delete(:type) || :full)), args)
  List.new(Nori.parse(response, :nokogiri))
end

- (GContacts::List) batch!(list, args = {})

Sends an array of Element to be updated/created/deleted

Parameters:

  • list (Array)

    Array of elements

  • list (GContacts::List)

    Array of elements

  • args (Hash) (defaults to: {})

Options Hash (args):

  • :params (Hash, Optional)

    Query string arguments when sending the API request

  • :headers (Hash, Optional)

    Any additional headers to pass with the API request

  • :api_type (Symbol, Optional)

    Override which part of the API is called, can either be :contacts or :groups

Returns:

Raises:



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/google-contacts/client.rb', line 186

def batch!(list, args={})
  return List.new if list.empty?

  uri = API_URI[args.delete(:api_type) || @options[:default_type]]
  raise ArgumentError, "Unsupported type given" unless uri

  xml = "<?xml version='1.0' encoding='UTF-8'?>\n"
  xml << "<feed xmlns='http://www.w3.org/2005/Atom' xmlns:gContact='http://schemas.google.com/contact/2008' xmlns:gd='http://schemas.google.com/g/2005' xmlns:batch='http://schemas.google.com/gdata/batch'>\n"
  list.each do |element|
    xml << element.to_xml(true) if element.has_modifier?
  end
  xml << "</feed>"

  results = http_request(:post, uri[:batch], :body => xml, :headers => {"Content-Type" => "application/atom+xml"})
  List.new(Nori.parse(results, :nokogiri))
end

- (GContacts::Element) create!(element)

Immediately creates the element on Google

Returns:

Raises:



117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/google-contacts/client.rb', line 117

def create!(element)
  uri = API_URI["#{element.category}s".to_sym]
  raise InvalidKind, "Unsupported kind #{element.category}" unless uri

  xml = "<?xml version='1.0' encoding='UTF-8'?>\n#{element.to_xml}"

  data = Nori.parse(http_request(:post, uri[:create], :body => xml, :headers => {"Content-Type" => "application/atom+xml"}), :nokogiri)
  unless data["entry"]
    raise InvalidResponse, "Created but response wasn't a valid element"
  end

  Element.new(data["entry"])
end

- (Object) delete!(element)

Immediately removes the element on Google

Parameters:

Raises:



162
163
164
165
166
167
168
169
# File 'lib/google-contacts/client.rb', line 162

def delete!(element)
  uri = API_URI["#{element.category}s".to_sym]
  raise InvalidKind, "Unsupported kind #{element.category}" unless uri

  http_request(:delete, URI(uri[:get] % [:base, File.basename(element.id)]), :headers => {"Content-Type" => "application/atom+xml", "If-Match" => element.etag})

  true
end

- (GContacts::Element) get(id, args = {})

Get a single contact or group from the server

Parameters:

  • id (String)

    ID to update

  • args (Hash) (defaults to: {})

Options Hash (args):

  • :params (Hash, Optional)

    Query string arguments when sending the API request

  • :headers (Hash, Optional)

    Any additional headers to pass with the API request

  • :api_type (Symbol, Optional)

    Override which part of the API is called, can either be :contacts or :groups

  • :type (Symbol, Optional)

    What data type to request, can either be :full or :base, defaults to :base

Returns:

Raises:



95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/google-contacts/client.rb', line 95

def get(id, args={})
  uri = API_URI[args.delete(:api_type) || @options[:default_type]]
  raise ArgumentError, "Unsupported type given" unless uri

  response = Nori.parse(http_request(:get, URI(uri[:get] % [args.delete(:type) || :full, id]), args), :nokogiri)

  if response and response["entry"]
    Element.new(response["entry"])
  else
    nil
  end
end

- (GContacts::List) paginate_all(args = {})

Repeatedly calls #all until all data is loaded

Parameters:

  • args (Hash) (defaults to: {})

Options Hash (args):

  • :params (Hash, Optional)

    Query string arguments when sending the API request

  • :headers (Hash, Optional)

    Any additional headers to pass with the API request

  • :api_type (Symbol, Optional)

    Override which part of the API is called, can either be :contacts or :groups

  • :type (Symbol, Optional)

    What data type to request, can either be :full or :base, defaults to :base

Returns:

Raises:

  • (Net::HTTPError)


60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/google-contacts/client.rb', line 60

def paginate_all(args={})
  uri = API_URI[args.delete(:api_type) || @options[:default_type]]
  raise ArgumentError, "Unsupported type given" unless uri
  uri = URI(uri[:all] % (args.delete(:type) || :full))

  while true do
    list = List.new(Nori.parse(http_request(:get, uri, args), :nokogiri))
    list.each {|entry| yield entry}

    # Nothing left to paginate
    # Or just to be safe, we're about to get caught in an infinite loop
    if list.empty? or list.next_uri.nil? or uri == list.next_uri
      break
    end

    uri = list.next_uri

    # If we have any params remove them, the URI Google returns will include them
    args.delete(:params)
  end
end

- (GContacts::Element) update!(element)

Immediately updates the element on Google

Parameters:

Returns:

Raises:



141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/google-contacts/client.rb', line 141

def update!(element)
  uri = API_URI["#{element.category}s".to_sym]
  raise InvalidKind, "Unsupported kind #{element.category}" unless uri

  xml = "<?xml version='1.0' encoding='UTF-8'?>\n#{element.to_xml}"

  data = Nori.parse(http_request(:put, URI(uri[:get] % [:base, File.basename(element.id)]), :body => xml, :headers => {"Content-Type" => "application/atom+xml", "If-Match" => element.etag}), :nokogiri)
  unless data["entry"]
    raise InvalidResponse, "Updated but response wasn't a valid element"
  end

  Element.new(data["entry"])
end