cs210-gdata4ruby 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG ADDED
@@ -0,0 +1,14 @@
1
+ #=CHANGELOG
2
+ #==version 0.1.5
3
+ #* Changed license to LGPLv3
4
+ #==version 0.1.4
5
+ #* Bugfix for GeoRSS and GML namespaces
6
+ #==version 0.1.3
7
+ #* Added support for Geo/GeoRSS namespaces in base gdata object
8
+ #* Added support for Ruby 1.9
9
+ #==version 0.1.2
10
+ #* Added better support for 'default' users in AccessRule
11
+ #==version 0.1.1
12
+ #* Added additional common attributes, including content, published, updated and author info
13
+ #==version 0.1.0
14
+ #* Initial Version
data/README.md ADDED
@@ -0,0 +1,45 @@
1
+ #GData4Ruby
2
+
3
+ ##Introduction
4
+
5
+ GData4Ruby is a full featured wrapper for the Google Data base API. GData4Ruby provides the ability
6
+ to authenticate with GData using the ClientLogin method. The package also includes a base gdata object
7
+ that can be subclassed to provide basic CRUD functions for all Google API service objects. Additionally,
8
+ a basic ACL object is included for interacting with ACL feeds and setting access rules.
9
+
10
+ ##Author and Contact Information
11
+
12
+ GData4Ruby was created and is maintained by [Mike Reich](mailto:mike@seabourneconsulting.com])
13
+ and is licenses under the LGPL v3. You can find the text of the LGPL
14
+ here: http://www.gnu.org/licenses/lgpl.html. Feel free to use and update, but be sure to contribute your
15
+ code back to the project and attribute as required by the license.
16
+
17
+ ##Website
18
+
19
+ [http://cookingandcoding.com/gdata4ruby/](http://cookingandcoding.com/gdata4ruby/)
20
+
21
+ ##Description
22
+
23
+ GData4Ruby has three major components: the service, the GData object and the AccessRule object. Each service
24
+ represents a google account, and includes a username (email) and a password. You can use the GData service
25
+ to authenticate either a google account or a google apps account.
26
+
27
+ The GData object provides a base class for interacting with Google API objects, i.e. Documents, Events, etc. The GData object contains common attributes present in all Google API objects, and provides interfaces for basic CRUD functions. This class is meant to be subclassed.
28
+
29
+ The AccessRule object provides a base class for interacting with Google Access Control Lists. ACLs provide the main permissions mechanism for most Google API services.
30
+
31
+ ##Examples
32
+
33
+ Below are some common usage examples. For more examples, check the documentation.
34
+
35
+ ###Service
36
+
37
+ 1. Authenticate
38
+
39
+ service = Service.new
40
+ service.authenticate("user@gmail.com", "password", "cl")
41
+
42
+ 2. Authenticate with a specified GData version
43
+
44
+ service = Service.new({:gdata_version => '3.0'})
45
+ service.authenticate("user@gmail.com", "password", "cl")
@@ -0,0 +1,127 @@
1
+ # Author:: Mike Reich (mike@seabourneconsulting.com)
2
+ # Copyright:: Copyright (C) 2010 Mike Reich
3
+ # License:: GPL v2
4
+ #--
5
+ # Licensed under the General Public License (GPL), Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ #
15
+ # Feel free to use and update, but be sure to contribute your
16
+ # code back to the project and attribute as required by the license.
17
+ #++
18
+ require 'gdata4ruby/gdata_object'
19
+
20
+ module GData4Ruby
21
+
22
+ #Contains classes for interacting with Google ACL feeds
23
+ module ACL
24
+
25
+ #Represents an individual access rule entry in a Google ACL feed.
26
+ class AccessRule < GDataObject
27
+ XML = "<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gAcl='http://schemas.google.com/acl/2007'>
28
+ <category scheme='http://schemas.google.com/g/2005#kind'
29
+ term='http://schemas.google.com/acl/2007#accessRule'/>
30
+ <gAcl:role value=''/>
31
+ <gAcl:scope type='user' value=''/>
32
+ </entry>"
33
+
34
+ #The Rule's user
35
+ attr_accessor :user
36
+
37
+ #The user's role
38
+ attr_accessor :role
39
+
40
+ #The parent GDataObject the rule applies to
41
+ attr_accessor :parent
42
+
43
+ #Creates a new AccessRule object. You must pass a valid Service and GDataObject, and can pass an optional hash
44
+ #of attributes to initialize the object with.
45
+ def initialize(service, parent, attributes = {})
46
+ super(service, attributes)
47
+ @xml = XML
48
+ raise ArgumentError, 'parent must be a GData4Ruby::GDataObject' if not parent.is_a? GData4Ruby::GDataObject
49
+ @parent = parent
50
+ @role = @user = nil
51
+ end
52
+
53
+ #Creates the AccessRule using the parent's acl_uri attribute.
54
+ def create
55
+ ret = service.send_request(Request.new(:post, @parent.acl_uri, to_xml))
56
+ if not ret or not load(ret.read_body)
57
+ raise SaveFailed, 'Could not create access rule'
58
+ end
59
+ return ret
60
+ end
61
+
62
+ #Loads data into the object. Accepts a string containing an XML <entry> object.
63
+ def load(string)
64
+ super(string)
65
+ @folders = []
66
+ xml = REXML::Document.new(string)
67
+ xml.root.elements.each(){}.map do |ele|
68
+ case ele.name
69
+ when 'role'
70
+ @role = ele.attributes['value']
71
+ when 'scope'
72
+ @user = ele.attributes['value'] ? ele.attributes['value'] : ele.attributes['type']
73
+ end
74
+ end
75
+ end
76
+
77
+ #Deletes the AccessRule
78
+ def delete
79
+ if @exists
80
+ @role = 'none'
81
+ service.send_request(Request.new(:put, @edit_uri, self.to_xml, {"If-Match" => "*", 'Content-Type' => 'application/atom+xml'}))
82
+ end
83
+ @exists = false
84
+ return true
85
+ end
86
+
87
+ #Finds an AccessRule based on the args passed.
88
+ #
89
+ #Args can be a hash containing either:
90
+ #*user*:: an email address/user id to search for. If found, returns the matching AccessRule object.
91
+ #*role*:: the role to search for. Returns an array of matching AccessRules, or an empty array if no matches are found.
92
+ def self.find(service, parent, args = {})
93
+ raise ArgumentError, 'Must supply a username or role to find by' if not args[:user] and not args[:role]
94
+ rules = []
95
+ ret = service.send_request(GData4Ruby::Request.new(:get, parent.acl_uri))
96
+ xml = REXML::Document.new(ret.read_body).root
97
+ xml.elements.each("entry") do |e|
98
+ e = GData4Ruby::Utils::add_namespaces(e)
99
+ rule = AccessRule.new(service, parent)
100
+ rule.load(e.to_s)
101
+ return rule if args[:user] and rule.user == args[:user]
102
+ rules << rule if args[:role] and rule.role == args[:role]
103
+ end
104
+ return args[:user] ? false : rules
105
+ end
106
+
107
+ #Returns a string containing the XML representation of the AccessRule
108
+ def to_xml
109
+ xml = REXML::Document.new(super)
110
+ xml.root.elements.each(){}.map do |ele|
111
+ case ele.name
112
+ when "role"
113
+ ele.attributes['value'] = @role
114
+ when 'scope'
115
+ if @user and @user != 'default'
116
+ ele.attributes['value'] = @user
117
+ else
118
+ ele.attributes['type'] = 'default'
119
+ ele.delete_attribute("value")
120
+ end
121
+ end
122
+ end
123
+ xml.to_s
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,158 @@
1
+ # Author:: Mike Reich (mike@seabourneconsulting.com)
2
+ # Copyright:: Copyright (C) 2010 Mike Reich
3
+ # License:: GPL v2
4
+ #--
5
+ # Licensed under the General Public License (GPL), Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ #
15
+ # Feel free to use and update, but be sure to contribute your
16
+ # code back to the project and attribute as required by the license.
17
+ #++
18
+
19
+ require "net/http"
20
+ require "net/https"
21
+ require 'time'
22
+ require 'cgi'
23
+ require 'gdata4ruby/request'
24
+ require 'gdata4ruby/utils/utils'
25
+ require 'rexml/document'
26
+
27
+ Net::HTTP.version_1_2
28
+
29
+ # GData4Ruby is a full featured wrapper for the base google data API
30
+
31
+ module GData4Ruby
32
+
33
+ class AuthenticationFailed < StandardError; end #:nodoc: all
34
+
35
+ class NotAuthenticated < StandardError; end
36
+
37
+ class InvalidService < StandardError; end
38
+
39
+ class HTTPRequestFailed < StandardError; end
40
+
41
+ class QueryParameterError < StandardError; end
42
+
43
+ #The ProxyInfo class contains information for configuring a proxy connection
44
+
45
+ class ProxyInfo
46
+ attr_accessor :address, :port, :username, :password
47
+ @address = nil
48
+ @port = nil
49
+ @username = nil
50
+ @password = nil
51
+
52
+ #The initialize function accepts four variables for configuring the ProxyInfo object.
53
+ #The proxy connection is initiated using the builtin Net::HTTP proxy support.
54
+
55
+ def initialize(address, port, username=nil, password=nil)
56
+ @address = address
57
+ @port = port
58
+ @username = username
59
+ @password = password
60
+ end
61
+ end
62
+
63
+ #The Base class includes the basic HTTP methods for communicating with the Google Data API.
64
+ #You shouldn't use this class directly, rather access the functionality through
65
+ #the Service subclass.
66
+
67
+ class Base
68
+ AUTH_URL = "https://www.google.com/accounts/ClientLogin"
69
+ @proxy_info = nil
70
+ @auth_token = nil
71
+ @debug = false
72
+ @gdata_version = '2.1'
73
+
74
+ #Contains the ProxyInfo object for using a proxy server
75
+ attr_accessor :proxy_info
76
+
77
+ #If set to true, debug will dump all raw HTTP requests and responses
78
+ attr_accessor :debug
79
+
80
+ #The GData version used by the service
81
+ attr_accessor :gdata_version
82
+
83
+ #Optionally, pass a hash of attributes to populate the class. If you want to use a GData version
84
+ #other than the default (2.1), pass a key/value pair, i.e. {:gdata_version => '1.0'}
85
+ def initialize(attributes = {})
86
+ @gdata_version = attributes[:gdata_version] ? attributes[:gdata_version] : '2.1'
87
+ end
88
+
89
+ #Sends a request to the Google Data System. Accepts a valid Request object, and returns a
90
+ #HTTPResult class.
91
+ def send_request(request)
92
+ raise ArgumentError 'Request must be a GData4Ruby::Request object' if not request.is_a?Request
93
+ puts "sending #{request.type} to url = #{request.url.to_s}" if @debug
94
+ do_request(request)
95
+ end
96
+
97
+ private
98
+
99
+ def do_request(request)
100
+ ret = nil
101
+ add_auth_header(request)
102
+ http = get_http_object(request.url)
103
+ puts "Sending request\nHeader: #{request.headers.inspect.to_s}\nContent: #{request.content.to_s}\n" if @debug
104
+ http.start do |ht|
105
+ ret = case request.type
106
+ when :get
107
+ ht.get(request.url.to_s, request.headers)
108
+ when :post
109
+ ht.post(request.url.to_s, request.content, request.headers)
110
+ when :put
111
+ ht.put(request.url.to_s, request.content, request.headers)
112
+ when :delete
113
+ ht.delete(request.url.to_s, request.headers)
114
+ end
115
+ end
116
+
117
+ while ret.is_a?(Net::HTTPRedirection)
118
+ puts "Redirect received, resending request" if @debug
119
+ request.parameters = nil
120
+ request.url = ret['location']
121
+ puts "sending #{request.type} to url = #{request.url.to_s}" if @debug
122
+ ret = do_request(request)
123
+ end
124
+ if not ret.is_a?(Net::HTTPSuccess)
125
+ puts "invalid response received: "+ret.code if @debug
126
+ raise HTTPRequestFailed, ret.body
127
+ end
128
+ puts "20x response received\nResponse: \n"+ret.read_body if @debug
129
+ return ret
130
+ end
131
+
132
+ def get_http_object(location)
133
+ if @proxy_info and @proxy_info.address
134
+ http = Net::HTTP.new(location.host, location.port, @proxy_info.address, @proxy_info.port, @proxy_info.username, @proxy_info.password)
135
+ else
136
+ http = Net::HTTP.new(location.host, location.port)
137
+ end
138
+ if location.scheme == 'https'
139
+ #fixed http/http misnaming via JohnMetta
140
+ puts "SSL True" if @debug
141
+ http.use_ssl = true
142
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
143
+ end
144
+ return http
145
+ end
146
+
147
+ def add_auth_header(request)
148
+ if @auth_token
149
+ if request.headers
150
+ request.headers.merge!({'Authorization' => "GoogleLogin auth=#{@auth_token}", "GData-Version" => @gdata_version})
151
+ else
152
+ content_type = (request.type == :get or request.type == :delete) ? 'application/x-www-form-urlencoded' : 'application/atom+xml'
153
+ request.headers = {'Authorization' => "GoogleLogin auth=#{@auth_token}", "GData-Version" => @gdata_version, 'Content-Type' => content_type}
154
+ end
155
+ end
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,197 @@
1
+ # Author:: Mike Reich (mike@seabourneconsulting.com)
2
+ # Copyright:: Copyright (C) 2010 Mike Reich
3
+ # License:: GPL v2
4
+ #--
5
+ # Licensed under the General Public License (GPL), Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ #
15
+ # Feel free to use and update, but be sure to contribute your
16
+ # code back to the project and attribute as required by the license.
17
+ #++
18
+
19
+ require 'gdata4ruby/service'
20
+ require 'time'
21
+
22
+ module GData4Ruby
23
+ #The GDataObject class represents any <entry> object returned by a Google Service. Includes
24
+ #attributes for accessing the common elements/parameters of the object, and methods for CRUD
25
+ #operations.
26
+ class GDataObject
27
+ #A Service object
28
+ attr_accessor :service
29
+
30
+ #The entry title.
31
+ attr_accessor :title
32
+
33
+ #The raw date the document was published
34
+ attr_reader :published
35
+
36
+ #The raw date the document was last updated
37
+ attr_reader :updated
38
+
39
+ #The author/owner name
40
+ attr_reader :author_name
41
+
42
+ #The author/owner email
43
+ attr_reader :author_email
44
+
45
+ #The current instance etag for the entry
46
+ attr_reader :etag
47
+
48
+ #The parent URI, if any
49
+ attr_reader :parent_uri
50
+
51
+ #The edit URI, for making changes to the entry
52
+ attr_reader :edit_uri
53
+
54
+ #A hash of additional feedLinks
55
+ attr_reader :feed_links
56
+
57
+ #The unique entry id, as represented by the <gd:resourceId> tag. Not to be confused
58
+ #with the Atom <id> tag, which is accessible as the feed_uri attribute.
59
+ attr_reader :id
60
+
61
+ #The entry's feed uri, otherwise known as the Atom <id> element value.
62
+ attr_reader :feed_uri
63
+
64
+ #A hash of categories
65
+ attr_reader :categories
66
+
67
+ #The feedLink that represents the entry's ACL feed.
68
+ attr_reader :acl_uri
69
+
70
+ #The content uri for exporting the object content
71
+ attr_reader :content_uri
72
+
73
+ #The kind (type) of the object
74
+ attr_reader :kind
75
+
76
+ #Indicates whether the object exists on the Google servers, i.e. has been created/saved.
77
+ def exists?
78
+ return @exists
79
+ end
80
+
81
+ #Initializes a new GDataObject. You must pass a valid Service object, and can pass
82
+ #an optional array of attributes to initialize values. To load data into an object,
83
+ #use the load method.
84
+ def initialize(service, attributes = {})
85
+ @xml ||= ''
86
+ @service ||= service
87
+ @exists = false
88
+ @title = @content_uri = @etag = @acl_uri = @edit_uri = @parent_uri = @feed_uri = @kind = nil
89
+ @categories = @feed_links = []
90
+ @include_etag = true
91
+ attributes.each do |key, value|
92
+ self.send("#{key}=", value)
93
+ end
94
+ end
95
+
96
+ public
97
+ #Loads data into the object. Accepts a string containing an XML <entry> from a GData
98
+ #compliant feed.
99
+ def load(string)
100
+ @exists = @include_etag = true
101
+ @xml = string
102
+ xml = REXML::Document.new(string)
103
+ xml.root.elements.each(){}.map do |ele|
104
+ @etag = xml.root.attributes['etag'] if xml.root.attributes['etag']
105
+ case ele.name
106
+ when "id"
107
+ puts 'setting id' if service.debug
108
+ @feed_uri = ele.text
109
+ when 'content'
110
+ @content_uri = ele.attributes['src'] if ele.attributes['src']
111
+ when 'resourceId'
112
+ @id = ele.text
113
+ when 'title'
114
+ @title = ele.text
115
+ when 'category'
116
+ @categories << {:label => ele.attributes['label'],
117
+ :scheme => ele.attributes['scheme'],
118
+ :term => ele.attributes['term']}
119
+ if ele.attributes['scheme'] and ele.attributes['scheme'] == 'http://schemas.google.com/g/2005#kind'
120
+ @kind = if ele.attributes['label']
121
+ ele.attributes['label']
122
+ else
123
+ ele.attributes['term']
124
+ end
125
+ end
126
+ when 'link'
127
+ case ele.attributes['rel']
128
+ when 'http://schemas.google.com/docs/2007#parent'
129
+ @parent_uri = ele.attributes['href']
130
+ when 'edit'
131
+ @edit_uri = ele.attributes['href']
132
+ when 'http://schemas.google.com/acl/2007#accessControlList'
133
+ @acl_uri = ele.attributes['href'] if not @acl_uri
134
+ end
135
+ when 'feedLink'
136
+ @feed_links << {:rel => ele.attributes['rel'], :href => ele.attributes['href']}
137
+ @acl_uri = ele.attributes['href'] if ele.attributes['rel'].include? 'accessControlList' and not @acl_uri
138
+ when 'author'
139
+ ele.elements.each('name'){}.map {|e| @author_name = e.text}
140
+ ele.elements.each('email'){}.map {|e| @author_email = e.text}
141
+ when 'published'
142
+ @published = Time.parse(ele.text) rescue nil
143
+ when 'updated'
144
+ @updated = Time.parse(ele.text) rescue nil
145
+ end
146
+ end
147
+ return xml.root
148
+ end
149
+
150
+ #Saves the object if it exsits, otherwise creates it.
151
+ def save
152
+ if @exists
153
+ ret = service.send_request(Request.new(:put, @edit_uri, to_xml))
154
+ else
155
+ ret = create
156
+ end
157
+ if not ret or not load(ret.read_body)
158
+ raise SaveFailed, 'Could not save object'
159
+ end
160
+ return true
161
+ end
162
+
163
+ #Creates the object. This must be overridden in a subclass, as the feed url for creating new
164
+ #objects/entries is service dependent. In other words, each google service uses a different
165
+ #URI for saving new objects.
166
+ def create
167
+ return false
168
+ end
169
+
170
+ #Deletes the object.
171
+ def delete
172
+ if @exists
173
+ service.send_request(Request.new(:delete, @edit_uri, nil, {"If-Match" => "*"}))
174
+ end
175
+ @exists = false
176
+ return true
177
+ end
178
+
179
+ #Creates a new string containing the XML representation of the object as a GData compliant <entry>
180
+ #element.
181
+ def to_xml
182
+ xml = REXML::Document.new(@xml)
183
+ xml.root.elements.each(){}.map do |ele|
184
+ if @include_etag
185
+ xml.root.attributes['gd:etag'] = @etag if @etag and @etag != ''
186
+ else
187
+ xml.root.delete_attribute('gd:etag')
188
+ end
189
+ case ele.name
190
+ when "title"
191
+ ele.text = @title
192
+ end
193
+ end
194
+ xml.to_s
195
+ end
196
+ end
197
+ end
@@ -0,0 +1,61 @@
1
+ # Author:: Mike Reich (mike@seabourneconsulting.com)
2
+ # Copyright:: Copyright (C) 2010 Mike Reich
3
+ # License:: GPL v2
4
+ #--
5
+ # Licensed under the General Public License (GPL), Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ #
15
+ # Feel free to use and update, but be sure to contribute your
16
+ # code back to the project and attribute as required by the license.
17
+ #++
18
+ require "uri"
19
+
20
+ module GData4Ruby
21
+ #The Request class holds all information needed to make a Request to a Google service.
22
+ class Request
23
+ #The HTTP request type, must be one of :get, :post, :put, :delete
24
+ attr_accessor :type
25
+
26
+ #The HTTP request content, only valid for :put and :post requests
27
+ attr_accessor :content
28
+
29
+ #Optional. Additional headers to pass with the request.
30
+ attr_accessor :headers
31
+
32
+ #Optional. Additional query parameters (i.e. "?param=value") to append to the request url
33
+ attr_reader :parameters
34
+
35
+ #Creates a new request object.
36
+ def initialize(type, url, content = nil, headers = nil, query_parameters = nil)
37
+ @parameters = nil
38
+ @headers = headers
39
+ @content = content
40
+ @type = type
41
+ @url = URI.parse(url)
42
+ self.parameters = query_parameters
43
+ end
44
+
45
+ #The HTTP url to send the request to
46
+ def url=(new_url)
47
+ @url = new_url
48
+ end
49
+
50
+ #A hash of additional query parameters (i.e. {'param' => 'value') to append to the request url
51
+ def parameters=(query_parameters)
52
+ raise ArgumentError, 'Query parameters must be a Hash' if query_parameters != nil and not query_parameters.is_a? Hash
53
+ @parameters = query_parameters.is_a?(Hash) ? "?#{query_parameters.to_a.collect{|a| a.join("=")}.join("&")}" : nil
54
+ end
55
+
56
+ #The HTTP url to send the request to
57
+ def url
58
+ return URI.parse("#{@url+(@parameters ? @parameters : '')}")
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,58 @@
1
+ # Author:: Mike Reich (mike@seabourneconsulting.com)
2
+ # Copyright:: Copyright (C) 2010 Mike Reich
3
+ # License:: GPL v2
4
+ #--
5
+ # Licensed under the General Public License (GPL), Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ #
15
+ # Feel free to use and update, but be sure to contribute your
16
+ # code back to the project and attribute as required by the license.
17
+ #++
18
+ require 'gdata4ruby/base'
19
+
20
+ module GData4Ruby
21
+ #The service class is the main handler for all direct interactions with the
22
+ #Google Data API.
23
+
24
+ class Service < Base
25
+ #Convenience attribute contains the currently authenticated account name
26
+ attr_reader :account
27
+
28
+ # The token returned by the Google servers, used to authorize all subsequent messages
29
+ attr_reader :auth_token
30
+
31
+ #Accepts an optional attributes hash for initialization values, most likely :gdata_version
32
+ def initialize(attributes = {})
33
+ super(attributes)
34
+ attributes.each do |key, value|
35
+ self.send("#{key}=", value)
36
+ end
37
+ end
38
+
39
+ # The authenticate method passes the username and password to google servers.
40
+ # If authentication succeeds, returns true, otherwise raises the AuthenticationFailed error.
41
+ # Thanks to David King and Scott Taylor for Ruby 1.9 fix.
42
+ def authenticate(username, password, service)
43
+ @auth_token = nil
44
+ ret = nil
45
+ ret = send_request(Request.new(:post, AUTH_URL, "Email=#{username}&Passwd=#{password}&source=GCal4Ruby&service=#{service}&accountType=HOSTED_OR_GOOGLE"))
46
+ if ret.class == Net::HTTPOK
47
+ body = ret.read_body
48
+ lines = body.send(body.respond_to?(:lines) ? :lines : :to_s).to_a
49
+ @auth_token = lines.to_a[2].gsub("Auth=", "").strip
50
+ @account = username
51
+ @password = password
52
+ return true
53
+ else
54
+ raise AuthenticationFailed
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,35 @@
1
+ # Author:: Mike Reich (mike@seabourneconsulting.com)
2
+ # Copyright:: Copyright (C) 2010 Mike Reich
3
+ # License:: GPL v2
4
+ #--
5
+ # Licensed under the General Public License (GPL), Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ #
15
+ # Feel free to use and update, but be sure to contribute your
16
+ # code back to the project and attribute as required by the license.
17
+ #++
18
+ module GData4Ruby
19
+ #A helper class that includes commonly used utility methods.
20
+ class Utils
21
+ #Adds common Google namespaces to an element. Useful for processing individual events returned from in a feed.
22
+ def self.add_namespaces(entry)
23
+ entry.attributes["xmlns:openSearch"] = "http://a9.com/-/spec/opensearch/1.1/"
24
+ entry.attributes["xmlns:gAcl"] = "http://schemas.google.com/acl/2007"
25
+ entry.attributes["xmlns:gCal"] = "http://schemas.google.com/gCal/2005"
26
+ entry.attributes["xmlns:gd"] = "http://schemas.google.com/g/2005"
27
+ entry.attributes["xmlns:app"] = "http://www.w3.org/2007/app"
28
+ entry.attributes["xmlns:docs"] = "http://schemas.google.com/docs/2007"
29
+ entry.attributes["xmlns"] = "http://www.w3.org/2005/Atom"
30
+ entry.attributes["xmlns:georss"] = "http://www.georss.org/georss"
31
+ entry.attributes["xmlns:gml"] = "http://www.opengis.net/gml"
32
+ entry
33
+ end
34
+ end
35
+ end
data/lib/gdata4ruby.rb ADDED
@@ -0,0 +1 @@
1
+ require "gdata4ruby/service"
data/test/unit.rb ADDED
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'rubygems'
4
+ require 'gdata4ruby'
5
+ include GData4Ruby
6
+
7
+ @service = Service.new
8
+ @username = nil
9
+ @password = nil
10
+
11
+ def tester
12
+ if ARGV.include?("-d")
13
+ @service.debug = true
14
+ end
15
+ ARGV.each do |ar|
16
+ if ar.match("username=")
17
+ @username = ar.gsub("username=", "")
18
+ end
19
+ if ar.match("password=")
20
+ @password = ar.gsub("password=", "")
21
+ end
22
+ end
23
+ service_test
24
+ end
25
+
26
+ def service_test
27
+ puts "---Starting Service Test---"
28
+ puts "1. Authenticate"
29
+ if @service.authenticate(@username, @password, 'cl')
30
+ successful
31
+ else
32
+ failed
33
+ end
34
+
35
+ puts "2. Authenticate with GData version 3.0"
36
+ @service = Service.new({:gdata_version => '3.0'})
37
+ if @service.authenticate(@username, @password, 'cl') and @service.gdata_version == '3.0'
38
+ successful
39
+ else
40
+ failed
41
+ end
42
+ end
43
+
44
+ def failed(m = nil)
45
+ puts "Test Failed"
46
+ puts m if m
47
+ exit()
48
+ end
49
+
50
+ def successful(m = nil)
51
+ puts "Test Successful"
52
+ puts m if m
53
+ end
54
+
55
+ tester
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cs210-gdata4ruby
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.5
6
+ platform: ruby
7
+ authors:
8
+ - Mike Reich
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-04-13 00:00:00 -07:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description: A full featured wrapper for interacting with the base Google Data API, including authentication and basic object handling
18
+ email: mike@seabourneconsulting.com
19
+ executables: []
20
+
21
+ extensions: []
22
+
23
+ extra_rdoc_files: []
24
+
25
+ files:
26
+ - README.md
27
+ - CHANGELOG
28
+ - lib/gdata4ruby.rb
29
+ - lib/gdata4ruby/base.rb
30
+ - lib/gdata4ruby/service.rb
31
+ - lib/gdata4ruby/request.rb
32
+ - lib/gdata4ruby/gdata_object.rb
33
+ - lib/gdata4ruby/utils/utils.rb
34
+ - lib/gdata4ruby/acl/access_rule.rb
35
+ - test/unit.rb
36
+ has_rdoc: true
37
+ homepage: http://cookingandcoding.com/gdata4ruby/
38
+ licenses: []
39
+
40
+ post_install_message:
41
+ rdoc_options: []
42
+
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: "0"
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ requirements: []
58
+
59
+ rubyforge_project: gdata4ruby
60
+ rubygems_version: 1.6.1
61
+ signing_key:
62
+ specification_version: 3
63
+ summary: A full featured wrapper for interacting with the base Google Data API
64
+ test_files:
65
+ - test/unit.rb