h13ronim-gcal4ruby 0.2.6

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,446 @@
1
+ require 'gcal4ruby/event'
2
+
3
+ module GCal4Ruby
4
+ #The Calendar Class is the representation of a Google Calendar. Each user account
5
+ #can have multiple calendars. You must have an authenticated Service object before
6
+ #using the Calendar object.
7
+ #=Usage
8
+ #All usages assume a successfully authenticated Service.
9
+ #1. Create a new Calendar
10
+ # cal = Calendar.new(service)
11
+ #
12
+ #2. Find an existing Calendar
13
+ # cal = Calendar.find(service, "New Calendar", :first)
14
+ #
15
+ #3. Find all calendars containing the search term
16
+ # cal = Calendar.find(service, "Soccer Team")
17
+ #
18
+ #4. Find a calendar by ID
19
+ # cal = Calendar.find(service, id, :first)
20
+ #
21
+ #After a calendar object has been created or loaded, you can change any of the
22
+ #attributes like you would any other object. Be sure to save the calendar to write changes
23
+ #to the Google Calendar service.
24
+
25
+ class Calendar
26
+ CALENDAR_FEED = "http://www.google.com/calendar/feeds/default/owncalendars/full"
27
+
28
+ #The calendar title
29
+ attr_accessor :title
30
+
31
+ #A short description of the calendar
32
+ attr_accessor :summary
33
+
34
+ #The parent Service object passed on initialization
35
+ attr_reader :service
36
+
37
+ #The unique calendar id
38
+ attr_reader :id
39
+
40
+ #Boolean value indicating the calendar visibility
41
+ attr_accessor :hidden
42
+
43
+ #The calendar timezone[http://code.google.com/apis/calendar/docs/2.0/reference.html#gCaltimezone]
44
+ attr_accessor :timezone
45
+
46
+ #The calendar color. Must be one of these[http://code.google.com/apis/calendar/docs/2.0/reference.html#gCalcolor] values.
47
+ attr_accessor :color
48
+
49
+ #The calendar geo location, if any
50
+ attr_accessor :where
51
+
52
+ #A boolean value indicating whether the calendar appears by default when viewed online
53
+ attr_accessor :selected
54
+
55
+ #The event feed for the calendar
56
+ attr_reader :event_feed
57
+
58
+ #A flag indicating whether the calendar is editable by this account
59
+ attr_reader :editable
60
+
61
+ #Returns true if the calendar exists on the Google Calendar system (i.e. was
62
+ #loaded or has been saved). Otherwise returns false.
63
+ def exists?
64
+ return @exists
65
+ end
66
+
67
+ #Returns true if the calendar is publically accessable, otherwise returns false.
68
+ def public?
69
+ return @public
70
+ end
71
+
72
+ #Returns an array of Event objects corresponding to each event in the calendar.
73
+ def events
74
+ events = []
75
+ ret = @service.send_get(@event_feed)
76
+ REXML::Document.new(ret.body).root.elements.each("entry"){}.map do |entry|
77
+ entry.attributes["xmlns:gCal"] = "http://schemas.google.com/gCal/2005"
78
+ entry.attributes["xmlns:gd"] = "http://schemas.google.com/g/2005"
79
+ entry.attributes["xmlns:app"] = "http://www.w3.org/2007/app"
80
+ entry.attributes["xmlns"] = "http://www.w3.org/2005/Atom"
81
+ e = Event.new(self)
82
+ if e.load(entry.to_s)
83
+ events << e
84
+ end
85
+ end
86
+ return events
87
+ end
88
+
89
+ #Set the calendar to public (p = true) or private (p = false). Publically viewable
90
+ #calendars can be accessed by anyone without having to log in to google calendar. See
91
+ #Calendar#to_iframe for options to display a public calendar in a webpage.
92
+ def public=(p)
93
+ if p
94
+ permissions = 'http://schemas.google.com/gCal/2005#read'
95
+ else
96
+ permissions = 'none'
97
+ end
98
+
99
+ #if p != @public
100
+ path = "http://www.google.com/calendar/feeds/#{@id}/acl/full/default"
101
+ request = REXML::Document.new(ACL_XML)
102
+ request.root.elements.each() do |ele|
103
+ if ele.name == 'role'
104
+ ele.attributes['value'] = permissions
105
+ end
106
+
107
+ end
108
+ if @service.send_put(path, request.to_s, {"Content-Type" => "application/atom+xml", "Content-Length" => request.length.to_s})
109
+ @public = p
110
+ return true
111
+ else
112
+ return false
113
+ end
114
+ #end
115
+ end
116
+
117
+ #Accepts a Service object. Returns the new Calendar if successful, otherwise raises the InvalidService
118
+ #error.
119
+ def initialize(service)
120
+ super()
121
+ if !service.is_a?(Service)
122
+ raise InvalidService
123
+ end
124
+ @xml = CALENDAR_XML
125
+ @service = service
126
+ @exists = false
127
+ @title = ""
128
+ @summary = ""
129
+ @public = false
130
+ @id = nil
131
+ @hidden = false
132
+ @timezone = "America/Los_Angeles"
133
+ @color = "#2952A3"
134
+ @where = ""
135
+ return true
136
+ end
137
+
138
+ #Deletes a calendar. If successful, returns true, otherwise false. If successful, the
139
+ #calendar object is cleared.
140
+ def delete
141
+ if @exists
142
+ if @service.send_delete(CALENDAR_FEED+"/"+@id)
143
+ @exists = false
144
+ @title = nil
145
+ @summary = nil
146
+ @public = false
147
+ @id = nil
148
+ @hidden = false
149
+ @timezone = nil
150
+ @color = nil
151
+ @where = nil
152
+ return true
153
+ else
154
+ return false
155
+ end
156
+ else
157
+ return false
158
+ end
159
+ end
160
+
161
+ #If the calendar does not exist, creates it, otherwise updates the calendar info. Returns
162
+ #true if the save is successful, otherwise false.
163
+ def save
164
+ if @exists
165
+ ret = service.send_put(@edit_feed, to_xml(), {'Content-Type' => 'application/atom+xml'})
166
+ else
167
+ ret = service.send_post(CALENDAR_FEED, to_xml(), {'Content-Type' => 'application/atom+xml'})
168
+ end
169
+ if !@exists
170
+ if load(ret.read_body)
171
+ return true
172
+ else
173
+ raise CalendarSaveFailed
174
+ end
175
+ end
176
+ return true
177
+ end
178
+
179
+ #Class method for querying the google service for specific calendars. The service parameter
180
+ #should be an appropriately authenticated Service. The term parameter can be any string. The
181
+ #scope parameter may be either :all to return an array of matches, or :first to return
182
+ #the first match as a Calendar object.
183
+ def self.find(service, query_term=nil, params = {})
184
+ t = query_term.downcase
185
+ cals = service.calendars
186
+ ret = []
187
+ cals.each do |cal|
188
+ title = cal.title || ""
189
+ summary = cal.summary || ""
190
+ id = cal.id || ""
191
+ if id == query_term
192
+ return cal
193
+ end
194
+ if title.downcase.match(t) or summary.downcase.match(t)
195
+ if params[:scope] == :first
196
+ return cal
197
+ else
198
+ ret << cal
199
+ end
200
+ end
201
+ end
202
+ ret
203
+ end
204
+
205
+ def self.get(service, id)
206
+ url = 'http://www.google.com/calendar/feeds/default/allcalendars/full/'+id
207
+ ret = service.send_get(url)
208
+ puts "==return=="
209
+ puts ret.body
210
+ end
211
+
212
+ def self.query(service, query_term)
213
+ url = 'http://www.google.com/calendar/feeds/default/allcalendars/full'+"?q="+CGI.escape(query_term)
214
+ ret = service.send_get(url)
215
+ puts "==return=="
216
+ puts ret.body
217
+ end
218
+
219
+ #Reloads the calendar objects information from the stored server version. Returns true
220
+ #if successful, otherwise returns false. Any information not saved will be overwritten.
221
+ def reload
222
+ if not @exists
223
+ return false
224
+ end
225
+ t = Calendar.find(service, @id, :first)
226
+ if t
227
+ load(t.to_xml)
228
+ else
229
+ return false
230
+ end
231
+ end
232
+
233
+ #Returns the xml representation of the Calenar.
234
+ def to_xml
235
+ xml = REXML::Document.new(@xml)
236
+ xml.root.elements.each(){}.map do |ele|
237
+ case ele.name
238
+ when "title"
239
+ ele.text = @title
240
+ when "summary"
241
+ ele.text = @summary
242
+ when "timezone"
243
+ ele.attributes["value"] = @timezone
244
+ when "hidden"
245
+ ele.attributes["value"] = @hidden.to_s
246
+ when "color"
247
+ ele.attributes["value"] = @color
248
+ when "selected"
249
+ ele.attributes["value"] = @selected.to_s
250
+ end
251
+ end
252
+ xml.to_s
253
+ end
254
+
255
+ #Loads the Calendar with returned data from Google Calendar feed. Returns true if successful.
256
+ def load(string)
257
+ @exists = true
258
+ @xml = string
259
+ xml = REXML::Document.new(string)
260
+ xml.root.elements.each(){}.map do |ele|
261
+ case ele.name
262
+ when "id"
263
+ @id = ele.text.gsub("http://www.google.com/calendar/feeds/default/calendars/", "")
264
+ when 'title'
265
+ @title = ele.text
266
+ when 'summary'
267
+ @summary = ele.text
268
+ when "color"
269
+ @color = ele.attributes['value']
270
+ when 'hidden'
271
+ @hidden = ele.attributes["value"] == "true" ? true : false
272
+ when 'timezone'
273
+ @timezone = ele.attributes["value"]
274
+ when "selected"
275
+ @selected = ele.attributes["value"] == "true" ? true : false
276
+ when "link"
277
+ if ele.attributes['rel'] == 'edit'
278
+ @edit_feed = ele.attributes['href']
279
+ end
280
+ end
281
+ end
282
+
283
+ @event_feed = "http://www.google.com/calendar/feeds/#{@id}/private/full"
284
+
285
+ if @service.check_public
286
+ puts "Getting ACL Feed" if @service.debug
287
+
288
+ #rescue error on shared calenar ACL list access
289
+ begin
290
+ ret = @service.send_get("http://www.google.com/calendar/feeds/#{@id}/acl/full/")
291
+ rescue Exception => e
292
+ @public = false
293
+ @editable = false
294
+ return true
295
+ end
296
+ @editable = true
297
+ r = REXML::Document.new(ret.read_body)
298
+ r.root.elements.each("entry") do |ele|
299
+ ele.elements.each do |e|
300
+ #puts "e = "+e.to_s if @service.debug
301
+ #puts "previous element = "+e.previous_element.to_s if @service.debug
302
+ if e.name == 'role' and e.previous_element.name == 'scope' and e.previous_element.attributes['type'] == 'default'
303
+ if e.attributes['value'].match('#read')
304
+ @public = true
305
+ else
306
+ @public = false
307
+ end
308
+ end
309
+ end
310
+ end
311
+ else
312
+ @public = false
313
+ @editable = true
314
+ end
315
+ return true
316
+ end
317
+
318
+ #Helper function to return the currently loaded calendar formatted iframe embedded google calendar.
319
+ #1. *params*: a hash of parameters that affect the display of the embedded calendar:
320
+ # height:: the height of the embedded calendar in pixels
321
+ # width:: the width of the embedded calendar in pixels
322
+ # title:: the title to display
323
+ # bgcolor:: the background color. Limited choices, see google docs for allowable values.
324
+ # color:: the color of the calendar elements. Limited choices, see google docs for allowable values.
325
+ # showTitle:: set to 'false' to hide the title
326
+ # showDate:: set to 'false' to hide the current date
327
+ # showNav:: set to 'false to hide the navigation tools
328
+ # showPrint:: set to 'false' to hide the print icon
329
+ # showTabs:: set to 'false' to hide the tabs
330
+ # showCalendars:: set to 'false' to hide the calendars selection drop down
331
+ # showTimezone:: set to 'false' to hide the timezone selection
332
+ # border:: the border width in pixels
333
+ # dates:: a range of dates to display in the format of 'yyyymmdd/yyyymmdd'. Example: 20090820/20091001
334
+ # privateKey:: use to display a private calendar. You can find this key under the calendar settings pane of the Google Calendar website.
335
+ def to_iframe(params = {})
336
+ if not self.id
337
+ raise "The calendar must exist and be saved before you can use this method."
338
+ end
339
+ params[:id] = self.id
340
+ params[:height] ||= "600"
341
+ params[:width] ||= "600"
342
+ params[:bgcolor] ||= "#FFFFFF"
343
+ params[:color] ||= "#2952A3"
344
+ params[:showTitle] = params[:showTitle] == false ? "showTitle=0" : ''
345
+ params[:showNav] = params[:showNav] == false ? "showNav=0" : ''
346
+ params[:showDate] = params[:showDate] == false ? "showDate=0" : ''
347
+ params[:showPrint] = params[:showPrint] == false ? "showPrint=0" : ''
348
+ params[:showTabs] = params[:showTabs] == false ? "showTabs=0" : ''
349
+ params[:showCalendars] = params[:showCalendars] == false ? "showCalendars=0" : ''
350
+ params[:showTimezone] = params[:showTimezone] == false ? 'showTz=0' : ''
351
+ params[:border] ||= "0"
352
+ output = ''
353
+ params.each do |key, value|
354
+ case key
355
+ when :height then output += "height=#{value}"
356
+ when :width then output += "width=#{value}"
357
+ when :title then output += "title=#{CGI.escape(value)}"
358
+ when :bgcolor then output += "bgcolor=#{CGI.escape(value)}"
359
+ when :showTitle then output += value
360
+ when :showDate then output += value
361
+ when :showNav then output += value
362
+ when :showPrint then output += value
363
+ when :showTabs then output += value
364
+ when :showCalendars then output += value
365
+ when :showTimezone then output += value
366
+ when :viewMode then output += "mode=#{value}"
367
+ when :dates then output += "dates=#{CGI.escape(value)}"
368
+ when :privateKey then output += "pvttk=#{value}"
369
+ end
370
+ output += "&amp;"
371
+ end
372
+
373
+ output += "src=#{params[:id]}&amp;color=#{CGI.escape(params[:color])}"
374
+
375
+ "<iframe src='http://www.google.com/calendar/embed?#{output}' style='#{params[:border]} px solid;' width='#{params[:width]}' height='#{params[:height]}' frameborder='#{params[:border]}' scrolling='no'></iframe>"
376
+ end
377
+
378
+ #Helper function to return a specified calendar id as a formatted iframe embedded google calendar. This function does not require loading the calendar information from the Google calendar
379
+ #service, but does require you know the google calendar id.
380
+ #1. *id*: the unique google assigned id for the calendar to display.
381
+ #2. *params*: a hash of parameters that affect the display of the embedded calendar:
382
+ # height:: the height of the embedded calendar in pixels
383
+ # width:: the width of the embedded calendar in pixels
384
+ # title:: the title to display
385
+ # bgcolor:: the background color. Limited choices, see google docs for allowable values.
386
+ # color:: the color of the calendar elements. Limited choices, see google docs for allowable values.
387
+ # showTitle:: set to 'false' to hide the title
388
+ # showDate:: set to 'false' to hide the current date
389
+ # showNav:: set to 'false to hide the navigation tools
390
+ # showPrint:: set to 'false' to hide the print icon
391
+ # showTabs:: set to 'false' to hide the tabs
392
+ # showCalendars:: set to 'false' to hide the calendars selection drop down
393
+ # showTimezone:: set to 'false' to hide the timezone selection
394
+ # border:: the border width in pixels
395
+ # dates:: a range of dates to display in the format of 'yyyymmdd/yyyymmdd'. Example: 20090820/20091001
396
+ # privateKey:: use to display a private calendar. You can find this key under the calendar settings pane of the Google Calendar website.
397
+ def self.to_iframe(id, params = {})
398
+ params[:id] = id
399
+ params[:height] ||= "600"
400
+ params[:width] ||= "600"
401
+ params[:bgcolor] ||= "#FFFFFF"
402
+ params[:color] ||= "#2952A3"
403
+ params[:showTitle] = params[:showTitle] == false ? "showTitle=0" : ''
404
+ params[:showNav] = params[:showNav] == false ? "showNav=0" : ''
405
+ params[:showDate] = params[:showDate] == false ? "showDate=0" : ''
406
+ params[:showPrint] = params[:showPrint] == false ? "showPrint=0" : ''
407
+ params[:showTabs] = params[:showTabs] == false ? "showTabs=0" : ''
408
+ params[:showCalendars] = params[:showCalendars] == false ? "showCalendars=0" : ''
409
+ params[:showTimezone] = params[:showTimezone] == false ? 'showTz=0' : ''
410
+ params[:border] ||= "0"
411
+ output = ''
412
+ params.each do |key, value|
413
+ case key
414
+ when :height then output += "height=#{value}"
415
+ when :width then output += "width=#{value}"
416
+ when :title then output += "title=#{CGI.escape(value)}"
417
+ when :bgcolor then output += "bgcolor=#{CGI.escape(value)}"
418
+ when :showTitle then output += value
419
+ when :showDate then output += value
420
+ when :showNav then output += value
421
+ when :showPrint then output += value
422
+ when :showTabs then output += value
423
+ when :showCalendars then output += value
424
+ when :showTimezone then output += value
425
+ when :viewMode then output += "mode=#{value}"
426
+ when :dates then output += "dates=#{CGI.escape(value)}"
427
+ when :privateKey then output += "pvttk=#{value}"
428
+ end
429
+ output += "&amp;"
430
+ end
431
+
432
+ output += "src=#{params[:id]}&amp;color=#{CGI.escape(params[:color])}"
433
+
434
+ "<iframe src='http://www.google.com/calendar/embed?#{output}' style='#{params[:border]} px solid;' width='#{params[:width]}' height='#{params[:height]}' frameborder='#{params[:border]}' scrolling='no'></iframe>"
435
+ end
436
+
437
+ private
438
+ @xml
439
+ @exists = false
440
+ @public = false
441
+ @event_feed = ''
442
+ @edit_feed = ''
443
+
444
+ end
445
+
446
+ end