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.
@@ -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
+
@@ -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,5 @@
1
+ apps_ocelot:
2
+ domain: ocelot.cul.columbia.edu
3
+ admin_user: _sc_api
4
+ admin_password: G6Jb1sYEbYVwye
5
+ admin_email: _sc_api@ocelot.cul.columbia.edu
@@ -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/&quot;CUcERH0_fyp7IWA9WxFRGUw.&quot;" 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/&quot;A0AFR347eCp7IWA9WxFRF0U.&quot;" 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/&quot;D0QFQX47eCp7IWA9WxFSFks.&quot;" 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/&quot;CkAMQn47eCp7IWA9WxFSEk4.&quot;" 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/&quot;DkYHR347eCp7IWA9WxFRGEU.&quot;" 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