google_apps_api 0.1.0
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/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +17 -0
- data/Rakefile +56 -0
- data/VERSION +1 -0
- data/google_apps_api.gemspec +85 -0
- data/lib/config/calendar.yml +34 -0
- data/lib/config/provisioning.yml +36 -0
- data/lib/google_apps_api/base_api.rb +157 -0
- data/lib/google_apps_api/calendar.rb +65 -0
- data/lib/google_apps_api/calendar_resources.rb +34 -0
- data/lib/google_apps_api/contacts.rb +53 -0
- data/lib/google_apps_api/exceptions.rb +19 -0
- data/lib/google_apps_api/provisioning.rb +294 -0
- data/lib/google_apps_api/user_profiles.rb +101 -0
- data/lib/google_apps_api.rb +15 -0
- data/lib/load_config.rb +17 -0
- data/private/gapps-config.yml +5 -0
- data/private/userscalendars.xml +113 -0
- data/test/google_apps_api-calendar_resources_test.rb +41 -0
- data/test/google_apps_api_calendar_test.rb +81 -0
- data/test/google_apps_api_contacts_test.rb +27 -0
- data/test/google_apps_api_provisioning_test.rb +78 -0
- data/test/google_apps_api_user_profiles_test.rb +30 -0
- data/test/helper.rb +10 -0
- data/test/test_helper.rb +15 -0
- metadata +127 -0
@@ -0,0 +1,294 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
module GoogleAppsApi #:nodoc:
|
4
|
+
module Provisioning
|
5
|
+
class Api < GoogleAppsApi::BaseApi
|
6
|
+
attr_reader :token
|
7
|
+
|
8
|
+
|
9
|
+
def initialize(*args)
|
10
|
+
super(:provisioning, *args)
|
11
|
+
end
|
12
|
+
|
13
|
+
def retrieve_user(username)
|
14
|
+
request(:retrieve_user, :username => username)
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
def retrieve_all_users
|
19
|
+
request(:retrieve_all_users)
|
20
|
+
end
|
21
|
+
#
|
22
|
+
# # Returns a UserEntry array populated with 100 users, starting from a username
|
23
|
+
# # ex :
|
24
|
+
# # myapps = ProvisioningApi.new('root@mydomain.com','PaSsWoRd')
|
25
|
+
# # list= myapps.retrieve_page_of_users("jsmtih")
|
26
|
+
# # list.each{ |user| puts user.username}
|
27
|
+
# def retrieve_page_of_users(start_username)
|
28
|
+
# param='?startUsername='+start_username
|
29
|
+
# response = request(:user_retrieve_all,param,@headers)
|
30
|
+
# user_feed = Feed.new(response.elements["feed"], UserEntry)
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
#
|
34
|
+
# def contacts_retrieve_all()
|
35
|
+
# response = request(:contacts_retrieve_all,nil, @headers)
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# Creates an account in your domain, returns a UserEntry instance
|
39
|
+
# params :
|
40
|
+
# username, given_name, family_name and password are required
|
41
|
+
# passwd_hash_function (optional) : nil (default) or "SHA-1"
|
42
|
+
# quota (optional) : nil (default) or integer for limit in MB
|
43
|
+
# ex :
|
44
|
+
# myapps = ProvisioningApi.new('root@mydomain.com','PaSsWoRd')
|
45
|
+
# user = myapps.create('jsmith', 'John', 'Smith', 'p455wD')
|
46
|
+
#
|
47
|
+
# 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.
|
48
|
+
def create_user(username, *args)
|
49
|
+
options = args.extract_options!
|
50
|
+
options.each { |k,v| options[k] = escapeXML(v)}
|
51
|
+
|
52
|
+
res = <<-DESCXML
|
53
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
54
|
+
<atom:entry xmlns:atom="http://www.w3.org/2005/Atom"
|
55
|
+
xmlns:apps="http://schemas.google.com/apps/2006">
|
56
|
+
<atom:category scheme="http://schemas.google.com/g/2005#kind"
|
57
|
+
term="http://schemas.google.com/apps/2006#user"/>
|
58
|
+
<apps:login userName="#{escapeXML(username)}"
|
59
|
+
password="#{options[:password]}" suspended="false"/>
|
60
|
+
<apps:name familyName="#{options[:family_name]}" givenName="#{options[:given_name]}"/>
|
61
|
+
</atom:entry>
|
62
|
+
|
63
|
+
DESCXML
|
64
|
+
|
65
|
+
|
66
|
+
request(:create_user, :body => res.strip)
|
67
|
+
end
|
68
|
+
#
|
69
|
+
# # Updates an account in your domain, returns a UserEntry instance
|
70
|
+
# # params :
|
71
|
+
# # username is required and can't be updated.
|
72
|
+
# # given_name and family_name are required, may be updated.
|
73
|
+
# # if set to nil, every other parameter won't update the attribute.
|
74
|
+
# # passwd_hash_function : string "SHA-1", "MD5" or nil (default)
|
75
|
+
# # admin : string "true" or string "false" or nil (no boolean : true or false).
|
76
|
+
# # suspended : string "true" or string "false" or nil (no boolean : true or false)
|
77
|
+
# # change_passwd : string "true" or string "false" or nil (no boolean : true or false)
|
78
|
+
# # quota : limit en MB, ex : string "2048"
|
79
|
+
# # ex :
|
80
|
+
# # myapps = ProvisioningApi.new('root@mydomain.com','PaSsWoRd')
|
81
|
+
# # user = myapps.update('jsmith', 'John', 'Smith', nil, nil, "true", nil, "true", nil)
|
82
|
+
# # puts user.admin => "true"
|
83
|
+
def update_user(username, *args)
|
84
|
+
options = args.extract_options!
|
85
|
+
options.each { |k,v| options[k] = escapeXML(v)}
|
86
|
+
|
87
|
+
res = <<-DESCXML
|
88
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
89
|
+
<atom:entry xmlns:atom="http://www.w3.org/2005/Atom"
|
90
|
+
xmlns:apps="http://schemas.google.com/apps/2006">
|
91
|
+
<atom:category scheme="http://schemas.google.com/g/2005#kind"
|
92
|
+
term="http://schemas.google.com/apps/2006#user"/>
|
93
|
+
<apps:name familyName="#{options[:family_name]}" givenName="#{options[:given_name]}"/>
|
94
|
+
</atom:entry>
|
95
|
+
|
96
|
+
DESCXML
|
97
|
+
request(:update_user, :username => username, :body => res.strip)
|
98
|
+
end
|
99
|
+
#
|
100
|
+
# # Renames a user, returns a UserEntry instance
|
101
|
+
# # ex :
|
102
|
+
# #
|
103
|
+
# # myapps = ProvisioningApi.new('root@mydomain.com','PaSsWoRd')
|
104
|
+
# # user = myapps.rename_user('jsmith','jdoe')
|
105
|
+
# #
|
106
|
+
# # It is recommended to log out rhe user from all browser sessions and service before renaming.
|
107
|
+
# # Once renamed, the old username becomes a nickname of the new username.
|
108
|
+
# # Note from Google: Google Talk will lose all remembered chat invitations after renaming.
|
109
|
+
# # The user must request permission to chat with friends again.
|
110
|
+
# # Also, when a user is renamed, the old username is retained as a nickname to ensure continuous mail delivery in the case of email forwarding settings.
|
111
|
+
# # To remove the nickname, you should issue an HTTP DELETE to the nicknames feed after renaming.
|
112
|
+
# def rename_user(username, new_username)
|
113
|
+
# msg = RequestMessage.new
|
114
|
+
# msg.about_login(new_username)
|
115
|
+
# msg.add_path('https://'+@@google_host+@action[:user_rename][:path]+username)
|
116
|
+
# response = request(:user_update,username,@headers, msg.to_s)
|
117
|
+
# end
|
118
|
+
#
|
119
|
+
# # Suspends an account in your domain, returns a UserEntry instance
|
120
|
+
# # ex :
|
121
|
+
# # myapps = ProvisioningApi.new('root@mydomain.com','PaSsWoRd')
|
122
|
+
# # user = myapps.suspend('jsmith')
|
123
|
+
# # puts user.suspended => "true"
|
124
|
+
# def suspend_user(username)
|
125
|
+
# msg = RequestMessage.new
|
126
|
+
# msg.about_login(username,nil,nil,nil,"true")
|
127
|
+
# msg.add_path('https://'+@@google_host+@action[:user_update][:path]+username)
|
128
|
+
# response = request(:user_update,username,@headers, msg.to_s)
|
129
|
+
# user_entry = UserEntry.new(response.elements["entry"])
|
130
|
+
# end
|
131
|
+
#
|
132
|
+
# # Restores a suspended account in your domain, returns a UserEntry instance
|
133
|
+
# # ex :
|
134
|
+
# # myapps = ProvisioningApi.new('root@mydomain.com','PaSsWoRd')
|
135
|
+
# # user = myapps.restore('jsmith')
|
136
|
+
# # puts user.suspended => "false"
|
137
|
+
# def restore_user(username)
|
138
|
+
# msg = RequestMessage.new
|
139
|
+
# msg.about_login(username,nil,nil,nil,"false")
|
140
|
+
# msg.add_path('https://'+@@google_host+@action[:user_update][:path]+username)
|
141
|
+
# response = request(:user_update,username,@headers, msg.to_s)
|
142
|
+
# user_entry = UserEntry.new(response.elements["entry"])
|
143
|
+
# end
|
144
|
+
#
|
145
|
+
# # Deletes an account in your domain
|
146
|
+
# # ex :
|
147
|
+
# # myapps = ProvisioningApi.new('root@mydomain.com','PaSsWoRd')
|
148
|
+
# # myapps.delete('jsmith')
|
149
|
+
def delete_user(username)
|
150
|
+
response = request(:delete_user, :username => username)
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
|
157
|
+
#
|
158
|
+
#
|
159
|
+
# class RequestMessage < Document #:nodoc:
|
160
|
+
# # Request message constructor.
|
161
|
+
# # parameter type : "user", "nickname" or "emailList"
|
162
|
+
#
|
163
|
+
# # creates the object and initiates the construction
|
164
|
+
# def initialize
|
165
|
+
# super '<?xml version="1.0" encoding="UTF-8"?>'
|
166
|
+
# self.add_element "atom:entry", {"xmlns:apps" => "http://schemas.google.com/apps/2006",
|
167
|
+
# "xmlns:gd" => "http://schemas.google.com/g/2005",
|
168
|
+
# "xmlns:atom" => "http://www.w3.org/2005/Atom"}
|
169
|
+
#
|
170
|
+
# self.elements["atom:entry"].add_element "atom:category", {"scheme" => "http://schemas.google.com/g/2005#kind"}
|
171
|
+
#
|
172
|
+
# end
|
173
|
+
#
|
174
|
+
# # adds <atom:id> element in the message body. Url is inserted as a text.
|
175
|
+
# def add_path(url)
|
176
|
+
# self.elements["atom:entry"].add_element "atom:id"
|
177
|
+
# self.elements["atom:entry/atom:id"].text = url
|
178
|
+
# end
|
179
|
+
#
|
180
|
+
# # adds <apps:emailList> element in the message body.
|
181
|
+
# def about_email_list(email_list)
|
182
|
+
# self.elements["atom:entry/atom:category"].add_attribute("term", "http://schemas.google.com/apps/2006#emailList")
|
183
|
+
# self.elements["atom:entry"].add_element "apps:emailList", {"name" => email_list }
|
184
|
+
# end
|
185
|
+
#
|
186
|
+
# # adds <apps:property> element in the message body for a group.
|
187
|
+
# def about_group(group_id, properties)
|
188
|
+
# self.elements["atom:entry/atom:category"].add_attribute("term", "http://schemas.google.com/apps/2006#emailList")
|
189
|
+
# self.elements["atom:entry"].add_element "apps:property", {"name" => "groupId", "value" => group_id }
|
190
|
+
# self.elements["atom:entry"].add_element "apps:property", {"name" => "groupName", "value" => properties[0] }
|
191
|
+
# self.elements["atom:entry"].add_element "apps:property", {"name" => "description", "value" => properties[1] }
|
192
|
+
# self.elements["atom:entry"].add_element "apps:property", {"name" => "emailPermission", "value" => properties[2] }
|
193
|
+
# end
|
194
|
+
#
|
195
|
+
# # adds <apps:property> element in the message body for a member.
|
196
|
+
# def about_member(email_address)
|
197
|
+
# self.elements["atom:entry/atom:category"].add_attribute("term", "http://schemas.google.com/apps/2006#user")
|
198
|
+
# self.elements["atom:entry"].add_element "apps:property", {"name" => "memberId", "value" => email_address }
|
199
|
+
# end
|
200
|
+
#
|
201
|
+
# # adds <apps:property> element in the message body for an owner.
|
202
|
+
# def about_owner(email_address)
|
203
|
+
# self.elements["atom:entry/atom:category"].add_attribute("term", "http://schemas.google.com/apps/2006#user")
|
204
|
+
# self.elements["atom:entry"].add_element "apps:property", {"name" => "email", "value" => email_address }
|
205
|
+
# end
|
206
|
+
#
|
207
|
+
#
|
208
|
+
# # adds <apps:login> element in the message body.
|
209
|
+
# # warning : if valued admin, suspended, or change_passwd_at_next_login must be the STRINGS "true" or "false", not the boolean true or false
|
210
|
+
# # when needed to construct the message, should always been used before other "about_" methods so that the category tag can be overwritten
|
211
|
+
# # only values permitted for hash_function_function_name : "SHA-1", "MD5" or nil
|
212
|
+
# def about_login(user_name, passwd=nil, hash_function_name=nil, admin=nil, suspended=nil, change_passwd_at_next_login=nil)
|
213
|
+
# self.elements["atom:entry/atom:category"].add_attribute("term", "http://schemas.google.com/apps/2006#user")
|
214
|
+
# self.elements["atom:entry"].add_element "apps:login", {"userName" => user_name }
|
215
|
+
# self.elements["atom:entry/apps:login"].add_attribute("password", passwd) if not passwd.nil?
|
216
|
+
# self.elements["atom:entry/apps:login"].add_attribute("hashFunctionName", hash_function_name) if not hash_function_name.nil?
|
217
|
+
# self.elements["atom:entry/apps:login"].add_attribute("admin", admin) if not admin.nil?
|
218
|
+
# self.elements["atom:entry/apps:login"].add_attribute("suspended", suspended) if not suspended.nil?
|
219
|
+
# self.elements["atom:entry/apps:login"].add_attribute("changePasswordAtNextLogin", change_passwd_at_next_login) if not change_passwd_at_next_login.nil?
|
220
|
+
# return self
|
221
|
+
# end
|
222
|
+
#
|
223
|
+
# # adds <apps:quota> in the message body.
|
224
|
+
# # limit in MB: integer
|
225
|
+
# def about_quota(limit)
|
226
|
+
# self.elements["atom:entry"].add_element "apps:quota", {"limit" => limit }
|
227
|
+
# return self
|
228
|
+
# end
|
229
|
+
#
|
230
|
+
# # adds <apps:name> in the message body.
|
231
|
+
# def about_name(family_name, given_name)
|
232
|
+
# self.elements["atom:entry"].add_element "apps:name", {"familyName" => family_name, "givenName" => given_name }
|
233
|
+
# return self
|
234
|
+
# end
|
235
|
+
#
|
236
|
+
# # adds <apps:nickname> in the message body.
|
237
|
+
# def about_nickname(name)
|
238
|
+
# self.elements["atom:entry/atom:category"].add_attribute("term", "http://schemas.google.com/apps/2006#nickname")
|
239
|
+
# self.elements["atom:entry"].add_element "apps:nickname", {"name" => name}
|
240
|
+
# return self
|
241
|
+
# end
|
242
|
+
#
|
243
|
+
# # adds <gd:who> in the message body.
|
244
|
+
# def about_who(email)
|
245
|
+
# self.elements["atom:entry"].add_element "gd:who", {"email" => email }
|
246
|
+
# return self
|
247
|
+
# end
|
248
|
+
#
|
249
|
+
# end
|
250
|
+
# end
|
251
|
+
end
|
252
|
+
|
253
|
+
|
254
|
+
|
255
|
+
class UserEntry < Entry
|
256
|
+
attr_accessor :given_name, :family_name, :username, :suspended, :ip_whitelisted, :admin, :change_password_at_next_login, :agreed_to_terms, :quota_limit
|
257
|
+
|
258
|
+
def initialize(xml = nil)
|
259
|
+
if xml
|
260
|
+
@family_name = xml.at_xpath("//apps:name").attribute("familyName").content
|
261
|
+
@given_name = xml.at_xpath("//apps:name").attribute("givenName").content
|
262
|
+
@username = xml.at_xpath("//apps:login").attribute("userName").content
|
263
|
+
@suspended = xml.at_xpath("//apps:login").attribute("suspended").content
|
264
|
+
@ip_whitelisted = xml.at_xpath("//apps:login").attribute("ipWhitelisted").content
|
265
|
+
@admin = xml.at_xpath("//apps:login").attribute("admin").content
|
266
|
+
@change_password_at_next_login = xml.at_xpath("//apps:login").attribute("changePasswordAtNextLogin").content
|
267
|
+
@agreed_to_terms = xml.at_xpath("//apps:login").attribute("agreedToTerms").content
|
268
|
+
@quota_limit = xml.at_xpath("//apps:quota").attribute("limit").content
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
def to_s
|
273
|
+
username
|
274
|
+
end
|
275
|
+
|
276
|
+
def inspect
|
277
|
+
"<UserEntry: #{username} : #{given_name} #{family_name}>"
|
278
|
+
end
|
279
|
+
|
280
|
+
def create_message(*args)
|
281
|
+
|
282
|
+
end
|
283
|
+
#
|
284
|
+
# def add_message
|
285
|
+
# Nokogiri::XML::Builder.new { |xml|
|
286
|
+
# xml.entry(:xmlns => "http://www.w3.org/2005/Atom") {
|
287
|
+
# xml.id_ {
|
288
|
+
# xml.text id.to_s
|
289
|
+
# }
|
290
|
+
# }
|
291
|
+
# }.to_xml
|
292
|
+
# end
|
293
|
+
end
|
294
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# require 'cgi'
|
4
|
+
# require 'rexml/document'
|
5
|
+
#
|
6
|
+
|
7
|
+
include REXML
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
module GoogleAppsApi #:nodoc:
|
12
|
+
module UserProfiles
|
13
|
+
|
14
|
+
|
15
|
+
class Api < GoogleAppsApi::BaseApi
|
16
|
+
|
17
|
+
attr_reader :token
|
18
|
+
|
19
|
+
def initialize(*args)
|
20
|
+
action_list = {
|
21
|
+
:domain_login => [:post, ':auth:/accounts/ClientLogin' ],
|
22
|
+
:retrieve_all => [:get, ':basic_path:/full?v=3.0'],
|
23
|
+
:retrieve_user => [:get, ':basic_path:/full/'],
|
24
|
+
:set_emails => [:put, ':basic_path:/full/'],
|
25
|
+
:next => [:get, '' ]
|
26
|
+
}
|
27
|
+
|
28
|
+
options = args.extract_options!
|
29
|
+
domain = options[:domain]
|
30
|
+
|
31
|
+
options.merge!(:action_hash => action_list, :auth => "https://www.google.com", :feed => "https://www.google.com", :service => "cp")
|
32
|
+
options[:basic_path] = options[:feed] + "/m8/feeds/profiles/domain/#{options[:domain]}"
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
super(options)
|
37
|
+
end
|
38
|
+
|
39
|
+
def retrieve_all()
|
40
|
+
response = request(:retrieve_all)
|
41
|
+
return response.to_s
|
42
|
+
end
|
43
|
+
|
44
|
+
def retrieve_user(user)
|
45
|
+
response = request(:retrieve_user, :query => user + "?v=3.0")
|
46
|
+
return response.to_s
|
47
|
+
end
|
48
|
+
|
49
|
+
def set_emails(user, *args)
|
50
|
+
emails = args.extract_options!
|
51
|
+
doc = Document.new(retrieve_user(user).to_s)
|
52
|
+
doc.elements.each("entry/gd:email") do |e|
|
53
|
+
|
54
|
+
e.parent.delete(e)
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
primary = emails.delete(:primary) || :other
|
59
|
+
|
60
|
+
base = doc.elements["entry"]
|
61
|
+
emails.each_pair do |loc, email|
|
62
|
+
base.add_element("gd:email", "address" => email, "rel" => "http://schemas.google.com/g/2005##{loc.to_s}", "primary" => loc == primary ? "true" : "false")
|
63
|
+
end
|
64
|
+
|
65
|
+
response = request(:set_emails,:query => user + "?v=3.0", :body => doc.to_s)
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
# class RequestMessage < Document #:nodoc:
|
71
|
+
# # Request message constructor.
|
72
|
+
# # parameter type : "user", "nickname" or "emailList"
|
73
|
+
#
|
74
|
+
# # creates the object and initiates the construction
|
75
|
+
# def initialize(*args)
|
76
|
+
# options = args.extract_options!
|
77
|
+
# super '<?xml version="1.0" encoding="UTF-8"?>'
|
78
|
+
# self.add_element "entry", { "xmlns:gd" => "http://schemas.google.com/g/2005",
|
79
|
+
# "xmlns:atom" => "http://www.w3.org/2005/Atom", "xmlns:batch" => 'http://schemas.google.com/gdata/batch', "xmlns:gContact" => "http://schemas.google.com/contact/2008"}
|
80
|
+
# # self.elements["entry"].add_element "atom:category", {"scheme" => "http://schemas.google.com/g/2005#kind", "term" => "http://schemas.google.com/contact/2008#contact"}
|
81
|
+
# end
|
82
|
+
#
|
83
|
+
# def add_contact(*args)
|
84
|
+
# options = args.extract_options!
|
85
|
+
# base = self.elements["atom:entry"]
|
86
|
+
# base.add_element("atom:title", {"type" => "text"}).text = options[:name]
|
87
|
+
# base.add_element("atom:content", {"type" => "text"}).text = "Notes"
|
88
|
+
# (options[:email] || {}).each_pair do |email_type, address|
|
89
|
+
# base.add_element("gd:email", {"rel" => "http://schemas.google.com/g/2005##{email_type.to_s}", "address" => address})
|
90
|
+
# end
|
91
|
+
# end
|
92
|
+
#
|
93
|
+
# def update_contact(*args)
|
94
|
+
# options = args.extract_options!
|
95
|
+
# end
|
96
|
+
# end
|
97
|
+
#
|
98
|
+
# end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'httpclient'
|
2
|
+
require 'cgi'
|
3
|
+
require 'nokogiri'
|
4
|
+
require "active_support"
|
5
|
+
|
6
|
+
require "load_config"
|
7
|
+
require "google_apps_api/base_api"
|
8
|
+
require "google_apps_api/calendar"
|
9
|
+
require "google_apps_api/calendar_resources"
|
10
|
+
require "google_apps_api/provisioning"
|
11
|
+
require "google_apps_api/exceptions"
|
12
|
+
require "google_apps_api/contacts"
|
13
|
+
require "google_apps_api/user_profiles"
|
14
|
+
|
15
|
+
|
data/lib/load_config.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module GoogleAppsApi
|
2
|
+
|
3
|
+
def self.load_yaml_configs
|
4
|
+
result = {}
|
5
|
+
Dir.glob(File.dirname(__FILE__) + "/config/*.yml").each do |file|
|
6
|
+
result.merge!(YAML::load(File.open(file)))
|
7
|
+
end
|
8
|
+
|
9
|
+
return result
|
10
|
+
end
|
11
|
+
|
12
|
+
@@config = GoogleAppsApi::load_yaml_configs
|
13
|
+
|
14
|
+
mattr_reader :config
|
15
|
+
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns:gCal="http://schemas.google.com/gCal/2005" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:gd="http://schemas.google.com/g/2005" gd:etag="W/"CUcERH0_fyp7IWA9WxFRGUw."" gd:kind="calendar#calendarFeed">
|
3
|
+
<id>http://www.google.com/calendar/feeds/jws2135%40ocelot.cul.columbia.edu/allcalendars/full</id>
|
4
|
+
<updated>2010-05-03T18:56:45.347Z</updated>
|
5
|
+
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/gCal/2005#calendarmeta"/>
|
6
|
+
<title>jws2135@ocelot.cul.columbia.edu's Calendar List</title>
|
7
|
+
<link rel="alternate" type="text/html" href="http://www.google.com/calendar/render"/>
|
8
|
+
<link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="https://www.google.com/calendar/feeds/jws2135%40ocelot.cul.columbia.edu/allcalendars/full"/>
|
9
|
+
<link rel="http://schemas.google.com/g/2005#post" type="application/atom+xml" href="https://www.google.com/calendar/feeds/jws2135%40ocelot.cul.columbia.edu/allcalendars/full"/>
|
10
|
+
<link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/jws2135%40ocelot.cul.columbia.edu/allcalendars/full"/>
|
11
|
+
<author>
|
12
|
+
<name>jws2135@ocelot.cul.columbia.edu</name>
|
13
|
+
<email>jws2135@ocelot.cul.columbia.edu</email>
|
14
|
+
</author>
|
15
|
+
<generator version="1.0" uri="http://www.google.com/calendar">Google Calendar</generator>
|
16
|
+
<openSearch:startIndex>1</openSearch:startIndex>
|
17
|
+
<entry gd:etag="W/"A0AFR347eCp7IWA9WxFRF0U."" gd:kind="calendar#calendar">
|
18
|
+
<id>http://www.google.com/calendar/feeds/jws2135%40ocelot.cul.columbia.edu/calendars/jws2135%40ocelot.cul.columbia.edu</id>
|
19
|
+
<published>2010-05-03T18:56:45.279Z</published>
|
20
|
+
<updated>2010-05-02T08:41:56.000Z</updated>
|
21
|
+
<app:edited>2010-05-02T08:41:56.000Z</app:edited>
|
22
|
+
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/gCal/2005#calendarmeta"/>
|
23
|
+
<title type="text">jws2135@ocelot.cul.columbia.edu</title>
|
24
|
+
<content type="application/atom+xml" src="http://www.google.com/calendar/feeds/jws2135%40ocelot.cul.columbia.edu/private/full"/>
|
25
|
+
<link rel="alternate" type="application/atom+xml" href="http://www.google.com/calendar/feeds/jws2135%40ocelot.cul.columbia.edu/private/full"/>
|
26
|
+
<link rel="http://schemas.google.com/gCal/2005#eventFeed" type="application/atom+xml" href="http://www.google.com/calendar/feeds/jws2135%40ocelot.cul.columbia.edu/private/full"/>
|
27
|
+
<link rel="http://schemas.google.com/acl/2007#accessControlList" type="application/atom+xml" href="http://www.google.com/calendar/feeds/jws2135%40ocelot.cul.columbia.edu/acl/full"/>
|
28
|
+
<link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/jws2135%40ocelot.cul.columbia.edu/allcalendars/full/jws2135%40ocelot.cul.columbia.edu"/>
|
29
|
+
<link rel="edit" type="application/atom+xml" href="https://www.google.com/calendar/feeds/jws2135%40ocelot.cul.columbia.edu/allcalendars/full/jws2135%40ocelot.cul.columbia.edu"/>
|
30
|
+
<author>
|
31
|
+
<name>jws2135@ocelot.cul.columbia.edu</name>
|
32
|
+
<email>jws2135@ocelot.cul.columbia.edu</email>
|
33
|
+
</author>
|
34
|
+
<gCal:accesslevel value="owner"/>
|
35
|
+
<gCal:color value="#A32929"/>
|
36
|
+
<gCal:hidden value="false"/>
|
37
|
+
<gCal:selected value="true"/>
|
38
|
+
<gCal:timezone value="America/New_York"/>
|
39
|
+
<gCal:timesCleaned value="0"/>
|
40
|
+
</entry>
|
41
|
+
<entry gd:etag="W/"D0QFQX47eCp7IWA9WxFSFks."" gd:kind="calendar#calendar">
|
42
|
+
<id>http://www.google.com/calendar/feeds/jws2135%40ocelot.cul.columbia.edu/calendars/ocelot.cul.columbia.edu_i1upo9o0jh38ot1js88paksntk%40group.calendar.google.com</id>
|
43
|
+
<published>2010-05-03T18:56:45.337Z</published>
|
44
|
+
<updated>2010-04-19T08:21:50.000Z</updated>
|
45
|
+
<app:edited>2010-04-19T08:21:50.000Z</app:edited>
|
46
|
+
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/gCal/2005#calendarmeta"/>
|
47
|
+
<title type="text">James' Private</title>
|
48
|
+
<summary type="text"/>
|
49
|
+
<content type="application/atom+xml" src="http://www.google.com/calendar/feeds/ocelot.cul.columbia.edu_i1upo9o0jh38ot1js88paksntk%40group.calendar.google.com/private/full"/>
|
50
|
+
<link rel="alternate" type="application/atom+xml" href="http://www.google.com/calendar/feeds/ocelot.cul.columbia.edu_i1upo9o0jh38ot1js88paksntk%40group.calendar.google.com/private/full"/>
|
51
|
+
<link rel="http://schemas.google.com/gCal/2005#eventFeed" type="application/atom+xml" href="http://www.google.com/calendar/feeds/ocelot.cul.columbia.edu_i1upo9o0jh38ot1js88paksntk%40group.calendar.google.com/private/full"/>
|
52
|
+
<link rel="http://schemas.google.com/acl/2007#accessControlList" type="application/atom+xml" href="http://www.google.com/calendar/feeds/ocelot.cul.columbia.edu_i1upo9o0jh38ot1js88paksntk%40group.calendar.google.com/acl/full"/>
|
53
|
+
<link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/jws2135%40ocelot.cul.columbia.edu/allcalendars/full/ocelot.cul.columbia.edu_i1upo9o0jh38ot1js88paksntk%40group.calendar.google.com"/>
|
54
|
+
<link rel="edit" type="application/atom+xml" href="https://www.google.com/calendar/feeds/jws2135%40ocelot.cul.columbia.edu/allcalendars/full/ocelot.cul.columbia.edu_i1upo9o0jh38ot1js88paksntk%40group.calendar.google.com"/>
|
55
|
+
<author>
|
56
|
+
<name>James' Private</name>
|
57
|
+
</author>
|
58
|
+
<gCal:accesslevel value="owner"/>
|
59
|
+
<gCal:color value="#0D7813"/>
|
60
|
+
<gCal:hidden value="false"/>
|
61
|
+
<gd:where valueString=""/>
|
62
|
+
<gCal:selected value="true"/>
|
63
|
+
<gCal:timezone value="UTC"/>
|
64
|
+
<gCal:timesCleaned value="0"/>
|
65
|
+
</entry>
|
66
|
+
<entry gd:etag="W/"CkAMQn47eCp7IWA9WxFSEk4."" gd:kind="calendar#calendar">
|
67
|
+
<id>http://www.google.com/calendar/feeds/jws2135%40ocelot.cul.columbia.edu/calendars/nco2104%40ocelot.cul.columbia.edu</id>
|
68
|
+
<published>2010-05-03T18:56:45.326Z</published>
|
69
|
+
<updated>2010-04-14T07:39:43.000Z</updated>
|
70
|
+
<app:edited>2010-04-14T07:39:43.000Z</app:edited>
|
71
|
+
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/gCal/2005#calendarmeta"/>
|
72
|
+
<title type="text">nco2104@ocelot.cul.columbia.edu</title>
|
73
|
+
<content type="application/atom+xml" src="http://www.google.com/calendar/feeds/nco2104%40ocelot.cul.columbia.edu/private/full"/>
|
74
|
+
<link rel="alternate" type="application/atom+xml" href="http://www.google.com/calendar/feeds/nco2104%40ocelot.cul.columbia.edu/private/full"/>
|
75
|
+
<link rel="http://schemas.google.com/gCal/2005#eventFeed" type="application/atom+xml" href="http://www.google.com/calendar/feeds/nco2104%40ocelot.cul.columbia.edu/private/full"/>
|
76
|
+
<link rel="http://schemas.google.com/acl/2007#accessControlList" type="application/atom+xml" href="http://www.google.com/calendar/feeds/nco2104%40ocelot.cul.columbia.edu/acl/full"/>
|
77
|
+
<link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/jws2135%40ocelot.cul.columbia.edu/allcalendars/full/nco2104%40ocelot.cul.columbia.edu"/>
|
78
|
+
<link rel="edit" type="application/atom+xml" href="https://www.google.com/calendar/feeds/jws2135%40ocelot.cul.columbia.edu/allcalendars/full/nco2104%40ocelot.cul.columbia.edu"/>
|
79
|
+
<author>
|
80
|
+
<name>nco2104@ocelot.cul.columbia.edu</name>
|
81
|
+
<email>nco2104@ocelot.cul.columbia.edu</email>
|
82
|
+
</author>
|
83
|
+
<gCal:accesslevel value="root"/>
|
84
|
+
<gCal:color value="#AB8B00"/>
|
85
|
+
<gCal:hidden value="false"/>
|
86
|
+
<gCal:selected value="true"/>
|
87
|
+
<gCal:timezone value="America/New_York"/>
|
88
|
+
<gCal:timesCleaned value="0"/>
|
89
|
+
</entry>
|
90
|
+
<entry gd:etag="W/"DkYHR347eCp7IWA9WxFRGEU."" gd:kind="calendar#calendar">
|
91
|
+
<id>http://www.google.com/calendar/feeds/jws2135%40ocelot.cul.columbia.edu/calendars/en.usa%23holiday%40group.v.calendar.google.com</id>
|
92
|
+
<published>2010-05-03T18:56:45.279Z</published>
|
93
|
+
<updated>2010-05-03T10:55:36.000Z</updated>
|
94
|
+
<app:edited>2010-05-03T10:55:36.000Z</app:edited>
|
95
|
+
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/gCal/2005#calendarmeta"/>
|
96
|
+
<title type="text">US Holidays</title>
|
97
|
+
<summary type="text">US Holidays</summary>
|
98
|
+
<content type="application/atom+xml" src="http://www.google.com/calendar/feeds/en.usa%23holiday%40group.v.calendar.google.com/private/full"/>
|
99
|
+
<link rel="alternate" type="application/atom+xml" href="http://www.google.com/calendar/feeds/en.usa%23holiday%40group.v.calendar.google.com/private/full"/>
|
100
|
+
<link rel="http://schemas.google.com/gCal/2005#eventFeed" type="application/atom+xml" href="http://www.google.com/calendar/feeds/en.usa%23holiday%40group.v.calendar.google.com/private/full"/>
|
101
|
+
<link rel="self" type="application/atom+xml" href="https://www.google.com/calendar/feeds/jws2135%40ocelot.cul.columbia.edu/allcalendars/full/en.usa%23holiday%40group.v.calendar.google.com"/>
|
102
|
+
<link rel="edit" type="application/atom+xml" href="https://www.google.com/calendar/feeds/jws2135%40ocelot.cul.columbia.edu/allcalendars/full/en.usa%23holiday%40group.v.calendar.google.com"/>
|
103
|
+
<author>
|
104
|
+
<name>US Holidays</name>
|
105
|
+
</author>
|
106
|
+
<gCal:accesslevel value="read"/>
|
107
|
+
<gCal:color value="#2952A3"/>
|
108
|
+
<gCal:hidden value="false"/>
|
109
|
+
<gCal:selected value="true"/>
|
110
|
+
<gCal:timezone value="America/New_York"/>
|
111
|
+
<gCal:timesCleaned value="0"/>
|
112
|
+
</entry>
|
113
|
+
</feed>
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# require 'test_helper'
|
2
|
+
#
|
3
|
+
# class GappsCalendarResourcesTest < Test::Unit::TestCase
|
4
|
+
#
|
5
|
+
# context "given a connection to apps.cul" do
|
6
|
+
# setup do
|
7
|
+
# gapps_config =YAML::load_file("private/gapps-config.yml")["apps_ocelot"].symbolize_keys!
|
8
|
+
# @api = GoogleAppsApi::CalendarResources::Api.new(gapps_config)
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# should "have a token" do
|
12
|
+
# assert @api.token
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
#
|
16
|
+
#
|
17
|
+
# should "be able to retrieve all resources" do
|
18
|
+
# assert @api.retrieve_all_resources
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# #
|
22
|
+
# # should "be able to create a user" do
|
23
|
+
# # assert_raises GoogleAppsApi::GDataError do
|
24
|
+
# # @api.retrieve_user("not_a_real_user")
|
25
|
+
# # end
|
26
|
+
# #
|
27
|
+
# # @api.create_user("not_a_real_user", "Not", "Real", "test_password", nil)
|
28
|
+
# #
|
29
|
+
# # assert_equal @api.retrieve_user("not_a_real_user").username, "not_a_real_user"
|
30
|
+
# #
|
31
|
+
# # @api.delete_user("not_a_real_user")
|
32
|
+
# #
|
33
|
+
# # assert_raises GoogleAppsApi::GDataError do
|
34
|
+
# # @api.retrieve_user("not_a_real_user")
|
35
|
+
# # end
|
36
|
+
#
|
37
|
+
#
|
38
|
+
#
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# end
|