gdata2 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CREDITS ADDED
@@ -0,0 +1,3 @@
1
+
2
+ This code began as a project by Jérôme Bousquié as a google code project:
3
+ http://code.google.com/p/gdatav2rubyclientlib/.
data/History.txt ADDED
File without changes
data/Manifest.txt ADDED
@@ -0,0 +1,15 @@
1
+ CREDITS
2
+ History.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ TODO
7
+ bin/config.yml
8
+ bin/sync-google-apps
9
+ gdata2.gemspec
10
+ lib/gdata.rb
11
+ lib/gdata/apps.rb
12
+ lib/gdata/apps/email.rb
13
+ lib/gdata/apps/provisioning.rb
14
+ lib/gdata/messages.rb
15
+ scripts/test.rb
data/README.txt ADDED
@@ -0,0 +1,70 @@
1
+ = gdata2
2
+
3
+ == DESCRIPTION:
4
+
5
+ gdata2 is a Ruby wrapper around the Google Data API's.
6
+
7
+ == FEATURES:
8
+
9
+ * Provides simple to use ruby-like api to Google Data API's.
10
+
11
+ == INSTALL:
12
+
13
+ === Ruby Gem:
14
+
15
+ sudo gem install gdata2
16
+
17
+ === Manual Download:
18
+
19
+ Install ruby-net-ldap gem
20
+ Install sequel gem
21
+ Install sqlite3-ruby gem
22
+ Download the latest release from <URL>
23
+
24
+ === Git:
25
+
26
+ You can check out the git repository at http://github.com/<URL>
27
+
28
+ == TODO:
29
+
30
+ #Unfinished
31
+ * Document the configuration yml for gapps-provision
32
+ * Set timestamps on the resulting database
33
+ * Un neuter the creation queue
34
+ * Un neuter the alteration queue
35
+ * enter code for the creation of admin users from the gapps-provision
36
+ file?
37
+ * inserts into the google alias table appears to not check and see if
38
+ they already exist
39
+
40
+ Adding more Google Data apis to the bundle.
41
+ # Apps APIs
42
+ * Provisioning
43
+ * Email Settings
44
+ * Calendar Data
45
+ * Reporting
46
+ # Data APIs
47
+ * Contacts Data
48
+ * Documents List Data
49
+ * Spreadsheets Data'
50
+
51
+ == SYNOPSIS:
52
+
53
+ TODO: write new
54
+
55
+ == LICENSE:
56
+
57
+ Copyright 2008-2009 Jérôme Bousquié
58
+ Copyright 2009 Montana State University
59
+
60
+ Licensed under the Apache License, Version 2.0 (the "License");
61
+ you may not use this file except in compliance with the License.
62
+ You may obtain a copy of the License at
63
+
64
+ http://www.apache.org/licenses/LICENSE-2.0
65
+
66
+ Unless required by applicable law or agreed to in writing, software
67
+ distributed under the License is distributed on an "AS IS" BASIS,
68
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
69
+ See the License for the specific language governing permissions and
70
+ limitations under the License.
data/Rakefile ADDED
@@ -0,0 +1,62 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require "spec/rake/spectask"
6
+ require './lib/gdata'
7
+
8
+ class Hoe
9
+ def extra_deps; @extra_deps.reject { |x| Array(x).first == "hoe" } end
10
+ end # copied from the Rakefile of the sup project
11
+
12
+ Hoe.new('gdata2', "0.1") do |p|
13
+ p.rubyforge_name = 'gdata2'
14
+ p.author = 'Ivan R. Judson'
15
+ p.email = 'ivan.judson@montana.edu'
16
+ p.summary = 'Ruby Wrapper for the Google Data APIs'
17
+ p.description = p.paragraphs_of('README.txt', 2..3).join("\n\n")
18
+ p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
19
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
20
+ p.remote_rdoc_dir = ''
21
+ end
22
+
23
+
24
+ RDOC_OPTS = [
25
+ '--quiet',
26
+ '--title', 'gdata2 APIs',
27
+ '--main', 'README.txt',
28
+ '--charset', 'utf-8',
29
+ '--inline-source',
30
+ '--tab-width', '2',
31
+ '--line-numbers',
32
+ ]
33
+
34
+ Rake::RDocTask.new do |rdoc|
35
+ rdoc.rdoc_dir = 'doc/'
36
+ rdoc.options = RDOC_OPTS
37
+ rdoc.main = "README.txt"
38
+ rdoc.rdoc_files.add [
39
+ 'LICENSE.txt',
40
+ 'README.txt',
41
+ 'History.txt',
42
+ 'lib/**/*.rb'
43
+ ]
44
+ end
45
+
46
+ # desc "Run all specs"
47
+ # Spec::Rake::SpecTask.new do |t|
48
+ # t.spec_files = FileList["spec/**/*_spec.rb"]
49
+ # t.spec_opts = ["--options", "spec/spec.opts"]
50
+ # end
51
+ #
52
+ # desc "Run all specs and get coverage statistics"
53
+ # Spec::Rake::SpecTask.new('spec:rcov') do |t|
54
+ # t.spec_files = FileList["spec/**/*_spec.rb"]
55
+ # t.rcov = true
56
+ # t.spec_opts = ["--options", "spec/spec.opts"]
57
+ # end
58
+ #
59
+ # Rake::Task[:default].prerequisites.clear
60
+ # task :default => :spec
61
+
62
+ # vim: syntax=Ruby
data/TODO ADDED
@@ -0,0 +1,12 @@
1
+ TODO List
2
+ ===========================
3
+ Adding more Google Data apis to the bundle.
4
+ # Apps APIs
5
+ * Provisioning
6
+ * Email Settings
7
+ * Calendar Data
8
+ * Reporting
9
+ # Data APIs
10
+ * Contacts Data
11
+ * Documents List Data
12
+ * Spreadsheets Data'
data/gdata2.gemspec ADDED
@@ -0,0 +1,34 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = %q{gdata2}
3
+ s.version = "0.1"
4
+ s.authors = ["Jérôme Bousquié", "Ivan R. Judson"]
5
+ s.email = "ivan.judson@montana.edu"
6
+ s.date = %q{2009-02-20}
7
+ s.homepage = ""
8
+ s.summary = "Ruby wrapper for Google Data API's"
9
+ s.description = "gdata2 is a ruby wrapper for the google data apis"
10
+
11
+ s.has_rdoc = true
12
+ s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"]
13
+ s.rdoc_options = ["--main", "README.txt"]
14
+ s.files = ["CREDITS", "History.txt", "Manifest.txt", "README.txt",
15
+ "Rakefile", "TODO", "gdata2.gemspec", "lib/gdata.rb",
16
+ "lib/gdata/apps/provisioning.rb"]
17
+ s.require_paths = ["lib"]
18
+ s.rubyforge_project = "gdata2"
19
+ s.rubygems_version = "1.3.1"
20
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
21
+
22
+ if s.respond_to? :specification_version then
23
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
24
+ s.specification_version = 2
25
+
26
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
+ s.add_development_dependency(%q<hoe>, [">= 1.8.3"])
28
+ else
29
+ s.add_dependency(%q<hoe>, [">= 1.8.3"])
30
+ end
31
+ else
32
+ s.add_dependency(%q<hoe>, [">= 1.8.3"])
33
+ end
34
+ end
data/lib/gdata.rb ADDED
@@ -0,0 +1,58 @@
1
+ $:.unshift(File.expand_path(File.dirname(__FILE__))) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ module GData #:nodoc:
5
+ require 'net/https'
6
+ require 'cgi'
7
+
8
+ class Connection
9
+ attr_reader :http_connection
10
+
11
+ # Establishes SSL connection to Google host
12
+ def initialize(host, port, proxy=nil, proxy_port=nil, proxy_user=nil, proxy_passwd=nil)
13
+ conn = Net::HTTP.new(host, port, proxy, proxy_port, proxy_user, proxy_passwd)
14
+ conn.use_ssl = true
15
+ conn.verify_mode = OpenSSL::SSL::VERIFY_PEER
16
+ conn.verify_mode = OpenSSL::SSL::VERIFY_NONE
17
+ store = OpenSSL::X509::Store.new
18
+ store.set_default_paths
19
+ conn.cert_store = store
20
+ conn.start
21
+ @http_connection = conn
22
+ end
23
+
24
+ # Performs the http request and returns the http response
25
+ def perform(method, path='', body=nil, header=nil)
26
+ backoff_factor = 2
27
+ resp = nil
28
+ while resp.nil?
29
+ begin
30
+ req = Net::HTTPGenericRequest.new(method, ! body.nil?, true, path)
31
+ req['Content-Type'] = header['Content-Type'] if header['Content-Type']
32
+ req['Authorization'] = header['Authorization'] if header['Authorization']
33
+ req['Content-length'] = body.length.to_s if body
34
+ resp = @http_connection.request(req, body)
35
+ rescue Timeout::Error
36
+ retry
37
+ rescue GData::GDataError => e
38
+ if e.code == "503"
39
+ resp = nil
40
+ sleep(backoff_factor)
41
+ backoff_factor *= backoff_factor
42
+ else
43
+ return e
44
+ end
45
+ rescue Errno::EPIPE
46
+ retry
47
+ rescue EOFError
48
+ end
49
+ end
50
+
51
+ return resp
52
+ end
53
+ end
54
+
55
+ class GDataError < RuntimeError
56
+ attr_accessor :code, :input, :reason
57
+ end
58
+ end
@@ -0,0 +1,437 @@
1
+ $:.unshift(File.expand_path(File.dirname(__FILE__))) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'messages'
5
+
6
+ module GData #:nodoc:
7
+ module Apps #:nodoc:
8
+ # =Administrative object for accessing your domain
9
+ # Examples
10
+ #
11
+ # adminuser = "root@mydomain.com"
12
+ # password = "PaSsWo4d!"
13
+ # gapp = GApps.new('root@mydomain.com','PaSsWoRd')
14
+ # myapps = Provisioning.new(gapp)
15
+ # (see examples in ProvisioningApi.new documentation for handling proxies)
16
+ #
17
+ # new_user = myapps.create_user("jsmith", "john", "smith", "secret", nil, "2048")
18
+ # puts new_user.family_name
19
+ # puts new_user.given_name
20
+ #
21
+ # Want to update a user ?
22
+ #
23
+ # user = myapps.retrieve_user('jsmith')
24
+ # user_updated = myapps.update_user(user.username, user.given_name, user.family_name, nil, nil, "true")
25
+ #
26
+ # Want to add an alias or nickname ?
27
+ #
28
+ # new_nickname = myapps.create_nickname("jsmith", "john.smith")
29
+ #
30
+ # Want to handle errors ?
31
+ #
32
+ # begin
33
+ # user = myapps.retrieve_user('noone')
34
+ # puts "givenName : "+user.given_name, "familyName : "+user.family_name, "username : "+user.username"
35
+ # puts "admin ? : "+user.admin
36
+ # rescue GDataError => e
37
+ # puts "errorcode = " +e.code, "input : "+e.input, "reason : "+e.reason
38
+ # end
39
+ #
40
+ # Group ?
41
+ #
42
+ # new_list = myapps.create_group("sale-dep")
43
+ # new_address = myapps.add_to_group("sale-dep", "bibi@ruby-forge.org")
44
+ #
45
+
46
+ class Provisioning
47
+
48
+ @@google_host = 'apps-apis.google.com'
49
+
50
+ # Creates a new Provisioning object
51
+ #
52
+ # apps: Google Apps Object (GData::GApps)
53
+ #
54
+ #
55
+ # Examples :
56
+ # standard : no proxy
57
+ # gapp = GApps.new('root@mydomain.com','PaSsWoRd')
58
+ # myapps = Provisioning.new(gapp)
59
+ # proxy :
60
+ # gapp = GApps.new('root@mydomain.com','PaSsWoRd','domain.proxy.com',8080)
61
+ # myapps = Provisioning.new(gapp)
62
+ # authenticated proxy :
63
+ # gapp = GApps.new('root@mydomain.com','PaSsWoRd','domain.proxy.com',8080,'foo','bAr')
64
+ # myapps = ProvisioningApi.new(gapp)
65
+ #
66
+ def initialize(apps)
67
+ @apps = apps
68
+ setup_actions()
69
+ end
70
+
71
+ # Creates an account in your domain, returns a UserEntry instance
72
+ # params :
73
+ # username, given_name, family_name and password are required
74
+ # passwd_hash_function (optional) : nil (default) or "SHA-1"
75
+ # quota (optional) : nil (default) or integer for limit in MB
76
+ # ex :
77
+ # gapp = GApps.new('root@mydomain.com','PaSsWoRd')
78
+ # myapps = ProvisioningApi.new(gapp)
79
+ # user = myapps.create('jsmith', 'John', 'Smith', 'p455wD')
80
+ #
81
+ # By default, a new user must change his password at first login. Please use update_user if you want to change this just after the creation.
82
+ def create_user(username, given_name, family_name, password, passwd_hash_function=nil, quota=nil)
83
+ msg = ProvisioningMessage.new
84
+ msg.about_login(username,password,passwd_hash_function,"false","false", "true")
85
+ msg.about_name(family_name, given_name)
86
+ msg.about_quota(quota.to_s) if quota
87
+ response = @apps.request(:user_create,nil, msg.to_s)
88
+ #user_entry = UserEntry.new(response.elements["entry"])
89
+ end
90
+
91
+
92
+ # Returns a UserEntry instance from a username
93
+ # ex :
94
+ # gapp = GApps.new('root@mydomain.com','PaSsWoRd')
95
+ # myapps = ProvisioningApi.new(gapp)
96
+ # user = myapps.retrieve_user('jsmith')
97
+ # puts "givenName : "+user.given_name
98
+ # puts "familyName : "+user.family_name
99
+ def retrieve_user(username)
100
+ xml_response = @apps.request(:user_retrieve, username)
101
+ if xml_response.respond_to? :elements
102
+ user_entry = UserEntry.new(xml_response.elements["entry"])
103
+ end
104
+ end
105
+
106
+ # Returns a UserEntry array populated with all the users in the domain. May take a while depending on the number of users in your domain.
107
+ # ex :
108
+ # gapp = GApps.new('root@mydomain.com','PaSsWoRd')
109
+ # myapps = ProvisioningApi.new(gapp)
110
+ # list= myapps.retrieve_all_users
111
+ # list.each{ |user| puts user.username}
112
+ # puts 'nb users : ',list.size
113
+ def retrieve_all_users
114
+ response = @apps.request(:user_retrieve_all)
115
+ user_feed = Feed.new(response.elements["feed"], UserEntry)
116
+ user_feed = add_next_feeds(user_feed, response, UserEntry)
117
+ end
118
+
119
+ # Returns a UserEntry array populated with 100 users, starting from a username
120
+ # ex :
121
+ # gapp = GApps.new('root@mydomain.com','PaSsWoRd')
122
+ # myapps = ProvisioningApi.new(gapp)
123
+ # list= myapps.retrieve_page_of_users("jsmtih")
124
+ # list.each{ |user| puts user.username}
125
+ def retrieve_page_of_users(start_username)
126
+ param='?startUsername='+start_username
127
+ response = @apps.request(:user_retrieve_all,param)
128
+ user_feed = Feed.new(response.elements["feed"], UserEntry)
129
+ end
130
+
131
+ # Updates an account in your domain, returns a UserEntry instance
132
+ # params :
133
+ # username is required and can't be updated.
134
+ # given_name and family_name are required, may be updated.
135
+ # if set to nil, every other parameter won't update the attribute.
136
+ # passwd_hash_function : string "SHA-1" or nil (default)
137
+ # admin : string "true" or string "false" or nil (no boolean : true or false).
138
+ # suspended : string "true" or string "false" or nil (no boolean : true or false)
139
+ # change_passwd : string "true" or string "false" or nil (no boolean : true or false)
140
+ # quota : limit en MB, ex : string "2048"
141
+ # ex :
142
+ # gapp = GApps.new('root@mydomain.com','PaSsWoRd')
143
+ # myapps = ProvisioningApi.new(gapp)
144
+ # user = myapps.update('jsmith', 'John', 'Smith', nil, nil, "true", nil, "true", nil)
145
+ # puts user.admin => "true"
146
+ def update_user(username, given_name, family_name, password=nil, passwd_hash_function=nil, admin=nil, suspended=nil, changepasswd=nil, quota=nil)
147
+ msg = ProvisioningMessage.new
148
+ msg.about_login(username,password,passwd_hash_function,admin,suspended, changepasswd)
149
+ msg.about_name(family_name, given_name)
150
+ msg.about_quota(quota) if quota
151
+ response = @apps.request(:user_update,username, msg.to_s)
152
+ #user_entry = UserEntry.new(response.elements["entry"])
153
+ end
154
+
155
+ # Deletes an account in your domain
156
+ # ex :
157
+ # gapp = GApps.new('root@mydomain.com','PaSsWoRd')
158
+ # myapps = ProvisioningApi.new(gapp)
159
+ # myapps.delete('jsmith')
160
+ def delete_user(username)
161
+ response = @apps.request(:user_delete,username)
162
+ end
163
+
164
+ # Creates a nickname for the username in your domain and returns a NicknameEntry instance
165
+ # gapp = GApps.new('root@mydomain.com','PaSsWoRd')
166
+ # myapps = ProvisioningApi.new(gapp)
167
+ # mynewnick = myapps.create_nickname('jsmith', 'john.smith')
168
+ def create_nickname(username, nickname)
169
+ msg = ProvisioningMessage.new
170
+ msg.about_login(username)
171
+ msg.about_nickname(nickname)
172
+ response = @apps.request(:nickname_create,nil, msg.to_s)
173
+ #nickname_entry = NicknameEntry.new(response.elements["entry"])
174
+ end
175
+
176
+ # Returns a NicknameEntry instance from a nickname
177
+ # ex :
178
+ # gapp = GApps.new('root@mydomain.com','PaSsWoRd')
179
+ # myapps = ProvisioningApi.new(gapp)
180
+ # nickname = myapps.retrieve_nickname('jsmith')
181
+ # puts "login : "+nickname.login
182
+ def retrieve_nickname(nickname)
183
+ xml_response = @apps.request(:nickname_retrieve, nickname)
184
+ nickname_entry = NicknameEntry.new(xml_response.elements["entry"])
185
+ end
186
+
187
+ # Returns a NicknameEntry array from a username
188
+ # ex : lists jsmith's nicknames
189
+ # gapp = GApps.new('root@mydomain.com','PaSsWoRd')
190
+ # myapps = ProvisioningApi.new(gapp)
191
+ # mynicks = myapps.retrieve('jsmith')
192
+ # mynicks.each {|nick| puts nick.nickname }
193
+ def retrieve_nicknames(username)
194
+ xml_response = @apps.request(:nickname_retrieve_all_for_user, username, @headers)
195
+
196
+ nicknames_feed = Feed.new(xml_response.elements["feed"], NicknameEntry)
197
+ nicknames_feed = add_next_feeds(nicknames_feed, xml_response, NicknameEntry)
198
+ end
199
+
200
+ # Returns a NicknameEntry array for the whole domain. May take a while depending on the number of users in your domain.
201
+ # gapp = GApps.new('root@mydomain.com','PaSsWoRd')
202
+ # myapps = ProvisioningApi.new(gapp)
203
+ # allnicks = myapps.retrieve_all_nicknames
204
+ # allnicks.each {|nick| puts nick.nickname }
205
+ def retrieve_all_nicknames
206
+ xml_response = @apps.request(:nickname_retrieve_all_in_domain, nil, @headers)
207
+ nicknames_feed = Feed.new(xml_response.elements["feed"], NicknameEntry)
208
+ nicknames_feed = add_next_feeds(nicknames_feed, xml_response, NicknameEntry)
209
+ end
210
+
211
+ # Deletes the nickname in your domain
212
+ # gapp = GApps.new('root@mydomain.com','PaSsWoRd')
213
+ # myapps = ProvisioningApi.new(gapp)
214
+ # myapps.delete_nickname('john.smith')
215
+ def delete_nickname(nickname)
216
+ response = @apps.request(:nickname_delete,nickname)
217
+ end
218
+
219
+ # Returns a NicknameEntry array populated with 100 nicknames, starting from a nickname
220
+ # ex :
221
+ # gapp = GApps.new('root@mydomain.com','PaSsWoRd')
222
+ # myapps = ProvisioningApi.new(gapp)
223
+ # list= myapps.retrieve_page_of_nicknames("joe")
224
+ # list.each{ |nick| puts nick.login}
225
+ def retrieve_page_of_nicknames(start_nickname)
226
+ param='?startNickname='+start_nickname
227
+ xml_response = @apps.request(:nickname_retrieve_all_in_domain, param, @headers)
228
+ nicknames_feed = Feed.new(xml_response.elements["feed"], NicknameEntry)
229
+ end
230
+
231
+ def create_group
232
+ raise NotImplementedError
233
+ end
234
+
235
+ def update_group
236
+ raise NotImplementedError
237
+ end
238
+
239
+ def retrieve_group
240
+ raise NotImplementedError
241
+ end
242
+
243
+ def delete_group
244
+ raise NotImplementedError
245
+ end
246
+
247
+ def add_member_to_group
248
+ raise NotImplementedError
249
+ end
250
+
251
+ def retrieve_members_of_group
252
+ raise NotImplementedError
253
+ end
254
+
255
+ def remove_member_from_group
256
+ raise NotImplementedError
257
+ end
258
+
259
+ def add_owner_to_group
260
+ raise NotImplementedError
261
+ end
262
+
263
+ def retrieve_owner_of_group
264
+ raise NotImplementedError
265
+ end
266
+
267
+ def remove_owner_from_group
268
+ raise NotImplementedError
269
+ end
270
+
271
+ # private methods
272
+ private #:nodoc:
273
+
274
+ # Associates methods, http verbs and URL for REST access
275
+ def setup_actions
276
+ domain = @apps.domain
277
+ path_user = '/a/feeds/'+domain+'/user/2.0'
278
+ path_nickname = '/a/feeds/'+domain+'/nickname/2.0'
279
+ path_email_list = '/a/feeds/'+domain+'/emailList/2.0'
280
+ path_group = '/a/feeds/group/2.0/'+domain
281
+
282
+ @apps.register_action(:domain_login, {:method => 'POST', :path => '/accounts/ClientLogin' })
283
+ @apps.register_action(:user_create, { :method => 'POST', :path => path_user })
284
+ @apps.register_action(:user_retrieve, { :method => 'GET', :path => path_user+'/' })
285
+ @apps.register_action(:user_retrieve_all, { :method => 'GET', :path => path_user })
286
+ @apps.register_action(:user_update, { :method => 'PUT', :path => path_user +'/' })
287
+ @apps.register_action(:user_delete, { :method => 'DELETE', :path => path_user +'/' })
288
+ @apps.register_action(:nickname_create, { :method => 'POST', :path =>path_nickname })
289
+ @apps.register_action(:nickname_retrieve, { :method => 'GET', :path =>path_nickname+'/' })
290
+ @apps.register_action(:nickname_retrieve_all_for_user, { :method => 'GET', :path =>path_nickname+'?username=' })
291
+ @apps.register_action(:nickname_retrieve_all_in_domain, { :method => 'GET', :path =>path_nickname })
292
+ @apps.register_action(:nickname_delete, { :method => 'DELETE', :path =>path_nickname+'/' })
293
+ @apps.register_action(:group_create, { :method => 'POST', :path => path_group })
294
+ @apps.register_action(:group_update, { :method => 'PUT', :path => path_group })
295
+ @apps.register_action(:group_retrieve, { :method => 'GET', :path => path_group })
296
+ @apps.register_action(:group_delete, { :method => 'DELETE', :path => path_group })
297
+
298
+ # special action "next" for linked feed results. :path will be affected with URL received in a link tag.
299
+ @apps.register_action(:next, {:method => 'GET', :path =>'' })
300
+ end
301
+
302
+ # Completes the feed by following et requesting the URL links
303
+ def add_next_feeds(current_feed, xml_content, element_class)
304
+ XPath.each(xml_content, 'feed/link') { |link|
305
+ if link.attributes.has_key?("rel") && link.attributes["rel"] == "next"
306
+ next_response = @apps.request(:next, link.attributes["href"])
307
+ current_feed.concat(Feed.new(next_response.elements["feed"], element_class))
308
+ current_feed = add_next_feeds(current_feed, next_response, element_class)
309
+ end
310
+ }
311
+ return current_feed
312
+ end
313
+ end
314
+
315
+
316
+ # UserEntry object.
317
+ #
318
+ # Handles API responses relative to a user
319
+ #
320
+ # Attributes :
321
+ # username : string
322
+ # given_name : string
323
+ # family_name : string
324
+ # suspended : string "true" or string "false"
325
+ # ip_whitelisted : string "true" or string "false"
326
+ # admin : string "true" or string "false"
327
+ # change_password_at_next_login : string "true" or string "false"
328
+ # agreed_to_terms : string "true" or string "false"
329
+ # quota_limit : string (value in MB)
330
+ class UserEntry
331
+ attr_reader :given_name, :family_name, :username, :suspended, :ip_whitelisted, :admin, :change_password_at_next_login, :agreed_to_terms, :quota_limit
332
+
333
+ # UserEntry constructor. Needs a REXML::Element <entry> as parameter
334
+ def initialize(entry) #:nodoc:
335
+ @family_name = entry.elements["apps:name"].attributes["familyName"]
336
+ @given_name = entry.elements["apps:name"].attributes["givenName"]
337
+ @username = entry.elements["apps:login"].attributes["userName"]
338
+ @suspended = entry.elements["apps:login"].attributes["suspended"]
339
+ @ip_whitelisted = entry.elements["apps:login"].attributes["ipWhitelisted"]
340
+ @admin = entry.elements["apps:login"].attributes["admin"]
341
+ @change_password_at_next_login = entry.elements["apps:login"].attributes["changePasswordAtNextLogin"]
342
+ @agreed_to_terms = entry.elements["apps:login"].attributes["agreedToTerms"]
343
+ @quota_limit = entry.elements["apps:quota"].attributes["limit"]
344
+ end
345
+
346
+ def to_s
347
+ outstr = "#<#{self.class}:0x#{self.object_id.to_s(16)}>\n"
348
+ instance_variables.sort.each do |v|
349
+ outstr += "\t#{v[1,v.length-1]} : #{instance_variable_get(v).to_s}\n"
350
+ end
351
+ outstr
352
+ end
353
+ end
354
+
355
+ # NicknameEntry object.
356
+ #
357
+ # Handles API responses relative to a nickname
358
+ #
359
+ # Attributes :
360
+ # login : string
361
+ # nickname : string
362
+ class NicknameEntry
363
+ attr_reader :login, :nickname
364
+
365
+ # NicknameEntry constructor. Needs a REXML::Element <entry> as parameter
366
+ def initialize(entry) #:nodoc:
367
+ @login = entry.elements["apps:login"].attributes["userName"]
368
+ if entry.elements["apps:nickname"].nil?
369
+ # IRJ Some call is failing 10 minutes into a run, I'll debug
370
+ @nickname = nil
371
+ else
372
+ @nickname = entry.elements["apps:nickname"].attributes["name"]
373
+ end
374
+ end
375
+
376
+ def to_s
377
+ outstr = "#<#{self.class}:0x#{self.object_id.to_s(16)}>\n"
378
+ outstr += "\t#{@login} : #{@nickname}"
379
+ end
380
+ end
381
+
382
+ # UserFeed object : Array populated with Element_class objects (UserEntry, NicknameEntry, EmailListEntry or EmailListRecipientEntry)
383
+ class Feed < Array #:nodoc:
384
+
385
+ # UserFeed constructor. Populates an array with Element_class objects. Each object is an xml <entry> parsed from the REXML::Element <feed>.
386
+ # Ex : user_feed = Feed.new(xml_feed, UserEntry)
387
+ # nickname_feed = Feed.new(xml_feed, NicknameEntry)
388
+ def initialize(xml_feed, element_class)
389
+ if xml_feed.respond_to? :elements
390
+ xml_feed.elements.each("entry"){ |entry| self << element_class.new(entry) }
391
+ end
392
+ end
393
+ end
394
+
395
+ class ProvisioningMessage < GData::RequestMessage #:nodoc:
396
+ def initialize
397
+ super
398
+ self.elements["atom:entry"].add_element "atom:category", {"scheme" => "http://schemas.google.com/g/2005#kind"}
399
+ end
400
+
401
+ # adds <apps:login> element in the message body.
402
+ # warning : if valued admin, suspended, or change_passwd_at_next_login must be the STRINGS "true" or "false", not the boolean true or false
403
+ # when needed to construct the message, should always been used before other "about_" methods so that the category tag can be overwritten
404
+ # only values permitted for hash_function_function_name : "SHA-1" or nil
405
+ def about_login(user_name, passwd=nil, hash_function_name=nil, admin=nil, suspended=nil, change_passwd_at_next_login=nil)
406
+ self.elements["atom:entry/atom:category"].add_attribute("term", "http://schemas.google.com/apps/2006#user")
407
+ self.elements["atom:entry"].add_element "apps:login", {"userName" => user_name }
408
+ self.elements["atom:entry/apps:login"].add_attribute("password", passwd) if not passwd.nil?
409
+ self.elements["atom:entry/apps:login"].add_attribute("hashFunctionName", hash_function_name) if not hash_function_name.nil?
410
+ self.elements["atom:entry/apps:login"].add_attribute("admin", admin) if not admin.nil?
411
+ self.elements["atom:entry/apps:login"].add_attribute("suspended", suspended) if not suspended.nil?
412
+ self.elements["atom:entry/apps:login"].add_attribute("changePasswordAtNextLogin", change_passwd_at_next_login) if not change_passwd_at_next_login.nil?
413
+ return self
414
+ end
415
+
416
+ # adds <apps:quota> in the message body.
417
+ # limit in MB: integer
418
+ def about_quota(limit)
419
+ self.elements["atom:entry"].add_element "apps:quota", {"limit" => limit }
420
+ return self
421
+ end
422
+
423
+ # adds <apps:name> in the message body.
424
+ def about_name(family_name, given_name)
425
+ self.elements["atom:entry"].add_element "apps:name", {"familyName" => family_name, "givenName" => given_name }
426
+ return self
427
+ end
428
+
429
+ # adds <apps:nickname> in the message body.
430
+ def about_nickname(name)
431
+ self.elements["atom:entry/atom:category"].add_attribute("term", "http://schemas.google.com/apps/2006#nickname")
432
+ self.elements["atom:entry"].add_element "apps:nickname", {"name" => name}
433
+ return self
434
+ end
435
+ end
436
+ end
437
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gdata2
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ version: "0.1"
9
+ platform: ruby
10
+ authors:
11
+ - "J\xC3\xA9r\xC3\xB4me Bousqui\xC3\xA9"
12
+ - Ivan R. Judson
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2009-02-20 00:00:00 -05:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: hoe
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 1
30
+ - 8
31
+ - 3
32
+ version: 1.8.3
33
+ type: :development
34
+ version_requirements: *id001
35
+ description: gdata2 is a ruby wrapper for the google data apis
36
+ email: ivan.judson@montana.edu
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - History.txt
43
+ - Manifest.txt
44
+ - README.txt
45
+ files:
46
+ - CREDITS
47
+ - History.txt
48
+ - Manifest.txt
49
+ - README.txt
50
+ - Rakefile
51
+ - TODO
52
+ - gdata2.gemspec
53
+ - lib/gdata.rb
54
+ - lib/gdata/apps/provisioning.rb
55
+ has_rdoc: true
56
+ homepage: ""
57
+ licenses: []
58
+
59
+ post_install_message:
60
+ rdoc_options:
61
+ - --main
62
+ - README.txt
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ segments:
71
+ - 0
72
+ version: "0"
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ segments:
79
+ - 0
80
+ version: "0"
81
+ requirements: []
82
+
83
+ rubyforge_project: gdata2
84
+ rubygems_version: 1.3.7
85
+ signing_key:
86
+ specification_version: 2
87
+ summary: Ruby wrapper for Google Data API's
88
+ test_files: []
89
+