railsware-gcal4ruby 0.5.5

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG ADDED
@@ -0,0 +1,80 @@
1
+ #=CHANGELOG
2
+ #==version 0.5.5
3
+ #* Fixed calendar :find
4
+ #==version 0.5.4
5
+ #* Fixed Service#to_iframe bgcolor bug
6
+ #==version 0.5.3
7
+ #* Fixed bug when loading event attributes when initializing
8
+ #==version 0.5.2
9
+ #* Fixed calendar.public functionality for making calendars publicly viewable.
10
+ #* Fixed to_iframe output methods
11
+ #* Fixed issue with creating new events
12
+ #==version 0.5.1
13
+ #* Minor fixes to to_iframe methods
14
+ #==version 0.5.0 - MAJOR CHANGES
15
+ #* Now using GData4Ruby library as base class for service, calendar, and event objects. This removed the base.rb class, which is now inherited from
16
+ # GData4ruby
17
+ #* Added 'events' method to service to get all events for an account.
18
+ #* Major interface changes to find methods - these are not backwards compatible changes.
19
+ #* Changed Event#find default behavior to search all calendars.
20
+ #* Major interface changes to to_iframe methods - these are not backwards compatible changes.
21
+ #* Added support for multiple reminders.
22
+ #* Improved object relationship for events. Events are now service-centric, i.e. events are instantiated with a service object.
23
+ #* Event calendar is now set through a 'calendar' attribute.
24
+ #* Fixes to event recurrence handling and display.
25
+ #* Added support for reminders with recurring events.
26
+ #* Numerous improvements to performance.
27
+ #* Calendar objects no longer have to query ACL feed to determine editability.
28
+ #* Added support for event statuses: cancelled, tentative or confirmed.
29
+ #==version 0.3.2
30
+ #* Updated the Event.find method to support finding all events by passing :all as the query term.
31
+ #==version 0.3.1
32
+ #* Fixed Event.find method to work with secondary calendars and google apps accounts. Fix provided by groesser3.
33
+ #* Added max results to Calendar.find.
34
+ #==version 0.3.0
35
+ #* Rewrote Event.find to improve performance significantly.
36
+ #* Added improvements to event recurrence handling, including loading existing recurrences, changing recurring events to non recurring and vice versa.
37
+ #* Added support for initialization attributes to Event, Calendar, Service and Recurrence.
38
+ #* Fixed query string typo in Event.find. Fix provided by nat.lownes.
39
+ #==version 0.2.11
40
+ #* Added support for GML elements in calendar events. Fix provided by nat.lownes.
41
+ #* Fixed event status bug where cancelled events were marked confirmed. Fix provided by rifraf.
42
+ #==version 0.2.10
43
+ #* Fixed library support for Google Hosted Apps accounts running in forced SSL mode.
44
+ #==version 0.2.9
45
+ #* Fixed small SSL redirect bug due to variable misnaming in base.rb. Fix provided by JohnMetta
46
+ #==version 0.2.8
47
+ #* Merged changes from edruder and h13ronim from the unofficial github repo - http://github.com/h13ronim/gcal4ruby/commits/master
48
+ #==version 0.2.7
49
+ #* Added fix for finding events in calendars that have more than 25 entries
50
+ #==version 0.2.6
51
+ #* Added fix for updated google calendar XML per http://cookingandcoding.wordpress.com/2009/06/08/new-ruby-google-calendar-api-gem-gcal4ruby/#comment-183
52
+ #==version 0.2.5
53
+ #* Added calendar color support to to_iframe methods in Calendar and Service.
54
+ #==version 0.2.4
55
+ #* Fixed bug with ACL check in Calendar#load
56
+ #==version 0.2.3
57
+ #* Implemented to_iframe method for calendars and services to output embeddable iframe text.
58
+ #* Added switch to turn off ACL check for public calendars. Can increase effeciency if turned off.
59
+ #==version 0.2.2
60
+ #* Fixed URL encoding problem in Event.find method.
61
+ #* cleaned up Event.find method to allow for finding events by id
62
+ #* updated Calendar.find method to add params hash
63
+ #* added 'published', 'updated', and 'edited' attributes
64
+ #==version 0.2.1
65
+ #* fixed Event.find calendar specification
66
+ #==version 0.2.0
67
+ #* Fixed redirect URI query params problem
68
+ #* Updated syntax for finding events to include most google api parameters, Non-backwards compatible.
69
+ #==version 0.1.4
70
+ #* Added additional search criteria for Event.find
71
+ #==version 0.1.3
72
+ #* Added support for authenticating with Google Hosted Apps accounts
73
+ #* Added flag to indicate whether a calendar is editable
74
+ #* Added handling to gracefully throw error when trying to create event on a non-editable (shared) calendar
75
+ #==version 0.1.2
76
+ #* Fixed to_xml dump problem with hidden and selected attributes
77
+ #==version 0.1.1
78
+ #* Added all_day indicator to event to indicate an all day event
79
+ #==version 0.1.0
80
+ #* Initial Version
data/README ADDED
@@ -0,0 +1,97 @@
1
+ #=GCal4Ruby
2
+ #
3
+ #==Introduction
4
+ #GCal4Ruby is a full featured wrapper for the google calendar API. GCal4Ruby implements
5
+ #all of the functionality available through the Google Calnedar API, including permissions,
6
+ #attendees, reminders and event recurrence.
7
+ #
8
+ #==Author and Contact Information
9
+ #GCal4Ruby was created and is maintained by {Mike Reich}[mailto:mike@seabourneconsulting.com]
10
+ #and is licenses under the GPL v2. Feel free to use and update, but be sure to contribute your
11
+ #code back to the project and attribute as required by the license.
12
+ #===Website
13
+ #http://cookingandcoding.com/gcal4ruby/
14
+ #
15
+ #==Description
16
+ #GCal4Ruby has three major components: the service, calendar and event objects. Each service
17
+ #has many calendars, which in turn have many events. Each service is the representation of a
18
+ #google account, and thus must be successfully authenticated using valid Google Calendar
19
+ #account credentials.
20
+ #
21
+ #==Examples
22
+ #Below are some common usage examples. For more examples, check the documentation.
23
+ #===Service
24
+ #1. Authenticate
25
+ # service = Service.new
26
+ # service.authenticate("user@gmail.com", "password")
27
+ #
28
+ #2. Get Calendar List
29
+ # calendars = service.calendars
30
+ #
31
+ #===Calendar
32
+ #All usages assume a successfully authenticated Service.
33
+ #1. Create a new Calendar
34
+ # cal = Calendar.new(service)
35
+ #
36
+ #2. Find a calendar by ID
37
+ # cal = Calendar.find(service, {:id => cal_id})
38
+ #
39
+ #3. Get all calendar events
40
+ # cal = Calendar.find(service, {:id => cal_id})
41
+ # events = cal.events
42
+ #
43
+ #4. Find an existing calendar by title
44
+ # cal = Calendar.find(service, {:title => "New Calendar"})
45
+ #
46
+ #5. Find all calendars containing a search term
47
+ # cal = Calendar.find(service, "Soccer Team")
48
+ #===Event
49
+ #All usages assume a successfully authenticated Service and valid Calendar.
50
+ #1. Create a new Event
51
+ # event = Event.new(service, {:calendar => cal, :title => "Soccer Game", :start => Time.parse("12-06-2009 at 12:30 PM"), :end => Time.parse("12-06-2009 at 1:30 PM"), :where => "Merry Playfields"})
52
+ # event.save
53
+ #
54
+ #2. Find an existing Event by title
55
+ # event = Event.find(service, {:title => "Soccer Game"})
56
+ #
57
+ #3. Find an existing Event by ID
58
+ # event = Event.find(service, {:id => event.id})
59
+ #
60
+ #4. Find all events containing the search term
61
+ # event = Event.find(service, "Soccer Game")
62
+ #
63
+ #5. Find all events on a calendar containing the search term
64
+ # event = Event.find(service, "Soccer Game", {:calendar => cal.id})
65
+ #
66
+ #6. Find events within a date range
67
+ # event = Event.find(service, "Soccer Game", {'start-min' => Time.parse("01/01/2010").utc.xmlschema, 'start-max' => Time.parse("06/01/2010").utc.xmlschema})
68
+ #
69
+ #7. Create a recurring event for every saturday
70
+ # event = Event.new(service)
71
+ # event.title = "Baseball Game"
72
+ # event.calendar = cal
73
+ # event.where = "Municipal Stadium"
74
+ # event.recurrence = Recurrence.new
75
+ # event.recurrence.start_time = Time.parse("06/20/2009 at 4:30 PM")
76
+ # event.recurrence.end_time = Time.parse("06/20/2009 at 6:30 PM")
77
+ # event.recurrence.frequency = {"weekly" => ["SA"]}
78
+ # event.save
79
+ #
80
+ #8. Create an event with a 15 minute email reminder
81
+ # event = Event.new(service)
82
+ # event.calendar = cal
83
+ # event.title = "Dinner with Kate"
84
+ # event.start_time = Time.parse("06/20/2009 at 5 pm")
85
+ # event.end_time = Time.parse("06/20/2009 at 8 pm")
86
+ # event.where = "Luigi's"
87
+ # event.reminder = {:minutes => 15, :method => 'email'}
88
+ # event.save
89
+ #
90
+ #9. Create an event with attendees
91
+ # event = Event.new(service)
92
+ # event.calendar = cal
93
+ # event.title = "Dinner with Kate"
94
+ # event.start_time = Time.parse("06/20/2009 at 5 pm")
95
+ # event.end_time = Time.parse("06/20/2009 at 8 pm")
96
+ # event.attendees => {:name => "Kate", :email => "kate@gmail.com"}
97
+ # event.save
@@ -0,0 +1,366 @@
1
+ # Author:: Mike Reich (mike@seabourneconsulting.com)
2
+ # Copyright:: Copyright (C) 2010 Mike Reich
3
+ # License:: GPL v2
4
+ #--
5
+ # Licensed under the General Public License (GPL), Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ #
15
+ # Feel free to use and update, but be sure to contribute your
16
+ # code back to the project and attribute as required by the license.
17
+ #++
18
+ require 'gdata4ruby/acl/access_rule'
19
+ module GCal4Ruby
20
+ #The Calendar Class is the representation of a Google Calendar. Each user account
21
+ #can have multiple calendars. You must have an authenticated Service object before
22
+ #using the Calendar object.
23
+ #=Usage
24
+ #All usages assume a successfully authenticated Service.
25
+ #1. Create a new Calendar
26
+ # cal = Calendar.new(service)
27
+ #
28
+ #2. Find a calendar by ID
29
+ # cal = Calendar.find(service, {:id => cal_id})
30
+ #
31
+ #3. Get all calendar events
32
+ # cal = Calendar.find(service, {:id => cal_id})
33
+ # events = cal.events
34
+ #
35
+ #4. Find an existing calendar by title
36
+ # cal = Calendar.find(service, {:title => "New Calendar"})
37
+ #
38
+ #5. Find all calendars containing a search term
39
+ # cal = Calendar.find(service, "Soccer Team")
40
+ #
41
+ #After a calendar object has been created or loaded, you can change any of the
42
+ #attributes like you would any other object. Be sure to save the calendar to write changes
43
+ #to the Google Calendar service.
44
+ class Calendar < GData4Ruby::GDataObject
45
+ CALENDAR_FEED = "http://www.google.com/calendar/feeds/default/owncalendars/full/"
46
+ CALENDAR_QUERY_FEED = "http://www.google.com/calendar/feeds/default/calendars/"
47
+ CALENDAR_XML = "<entry xmlns='http://www.w3.org/2005/Atom'
48
+ xmlns:gd='http://schemas.google.com/g/2005'
49
+ xmlns:gCal='http://schemas.google.com/gCal/2005'>
50
+ <title type='text'></title>
51
+ <summary type='text'></summary>
52
+ <gCal:timezone value='America/Los_Angeles'></gCal:timezone>
53
+ <gCal:hidden value='false'></gCal:hidden>
54
+ <gCal:color value='#2952A3'></gCal:color>
55
+ <gd:where rel='' label='' valueString='Oakland'></gd:where>
56
+ </entry>"
57
+
58
+ #A short description of the calendar
59
+ attr_accessor :summary
60
+
61
+ #Boolean value indicating the calendar visibility
62
+ attr_accessor :hidden
63
+
64
+ #The calendar timezone[http://code.google.com/apis/calendar/docs/2.0/reference.html#gCaltimezone]
65
+ attr_accessor :timezone
66
+
67
+ #The calendar color. Must be one of these[http://code.google.com/apis/calendar/docs/2.0/reference.html#gCalcolor] values.
68
+ attr_accessor :color
69
+
70
+ #The calendar geo location, if any
71
+ attr_accessor :where
72
+
73
+ #A boolean value indicating whether the calendar appears by default when viewed online
74
+ attr_accessor :selected
75
+
76
+ #A flag indicating whether the calendar is editable by this account
77
+ attr_reader :editable
78
+
79
+ #Accepts a Service object and an optional attributes hash for initialization. Returns the new Calendar
80
+ #if successful, otherwise raises the InvalidService error.
81
+ def initialize(service, attributes = {})
82
+ super(service, attributes)
83
+ if !service.is_a?(Service)
84
+ raise InvalidService
85
+ end
86
+ @xml = CALENDAR_XML
87
+ @service ||= service
88
+ @exists = false
89
+ @title ||= ""
90
+ @summary ||= ""
91
+ @public ||= false
92
+ @hidden ||= false
93
+ @timezone ||= "America/Los_Angeles"
94
+ @color ||= "#2952A3"
95
+ @where ||= ""
96
+ attributes.each do |key, value|
97
+ self.send("#{key}=", value)
98
+ end
99
+ return true
100
+ end
101
+
102
+ #Returns true if the calendar exists on the Google Calendar system (i.e. was
103
+ #loaded or has been saved). Otherwise returns false.
104
+ def exists?
105
+ return @exists
106
+ end
107
+
108
+ #Returns true if the calendar is publically accessable, otherwise returns false.
109
+ def public?
110
+ return @public
111
+ end
112
+
113
+ #Returns an array of Event objects corresponding to each event in the calendar.
114
+ def events
115
+ events = []
116
+ ret = @service.send_request(GData4Ruby::Request.new(:get, @content_uri))
117
+ REXML::Document.new(ret.body).root.elements.each("entry"){}.map do |entry|
118
+ entry = GData4Ruby::Utils.add_namespaces(entry)
119
+ e = Event.new(service)
120
+ if e.load(entry.to_s)
121
+ events << e
122
+ end
123
+ end
124
+ return events
125
+ end
126
+
127
+
128
+ #Saves the calendar.
129
+ def save
130
+ public = @public
131
+ ret = super
132
+ return ret if public == @public
133
+ if public
134
+ puts 'setting calendar to public' if service.debug
135
+ rule = GData4Ruby::ACL::AccessRule.new(service, self)
136
+ rule.role = 'http://schemas.google.com/gCal/2005#read'
137
+ rule.save
138
+ else
139
+ rule = GData4Ruby::ACL::AccessRule.find(service, self, {:user => 'default'})
140
+ rule.delete if rule
141
+ end
142
+ reload
143
+ end
144
+
145
+ #Set the calendar to public (p = true) or private (p = false). Publically viewable
146
+ #calendars can be accessed by anyone without having to log in to google calendar. See
147
+ #Calendar#to_iframe on how to display a public calendar in a webpage.
148
+ def public=(p)
149
+ @public = p
150
+ end
151
+
152
+ #Creates a new instance of the object
153
+ def create
154
+ return service.send_request(GData4Ruby::Request.new(:post, CALENDAR_FEED, to_xml()))
155
+ end
156
+
157
+ #Finds a Calendar based on a text query or by an id. Parameters are:
158
+ #*service*:: A valid Service object to search.
159
+ #*query*:: either a string containing a text query to search by, or a hash containing an +id+ key with an associated id to find, or a +query+ key containint a text query to search for, or a +title+ key containing a title to search.
160
+ #*args*:: a hash containing optional additional query paramters to use. See http://code.google.com/apis/gdata/docs/2.0/reference.html#Queries for a full list of possible values. Example:
161
+ # {'max-results' => '100'}
162
+ #If an ID is specified, a single instance of the calendar is returned if found, otherwise false.
163
+ #If a query term or title text is specified, and array of matching results is returned, or an empty array if nothing
164
+ #was found.
165
+ def self.find(service, query, args = {})
166
+ raise ArgumentError, 'query must be a hash or string' if not query.is_a? Hash and not query.is_a? String
167
+ if query.is_a? Hash and query[:id]
168
+ id = query[:id]
169
+ puts "id passed, finding calendar by id" if service.debug
170
+ puts "id = "+id if service.debug
171
+ d = service.send_request(GData4Ruby::Request.new(:get, CALENDAR_FEED+id, {"If-Not-Match" => "*"}))
172
+ puts d.inspect if service.debug
173
+ if d
174
+ return get_instance(service, d)
175
+ end
176
+ else
177
+ #fugly, but Google doesn't provide a way to query the calendar feed directly
178
+ old_public = service.check_public
179
+ service.check_public = false
180
+ results = []
181
+ cals = service.calendars
182
+ cals.each do |cal|
183
+ if query.is_a?(Hash)
184
+ results << cal if query[:query] and cal.title.downcase.include? query[:query].downcase
185
+ results << cal if query[:title] and cal.title == query[:title]
186
+ else
187
+ results << cal if cal.title.downcase.include? query.downcase
188
+ end
189
+ end
190
+ service.check_public = old_public
191
+ return results
192
+ end
193
+ return false
194
+ end
195
+
196
+ #Reloads the calendar objects information from the stored server version. Returns true
197
+ #if successful, otherwise returns false. Any information not saved will be overwritten.
198
+ def reload
199
+ return false if not @exists
200
+ t = Calendar.find(service, {:id => @id})
201
+ if t
202
+ load(t.to_xml)
203
+ else
204
+ return false
205
+ end
206
+ end
207
+
208
+ #Returns the xml representation of the Calenar.
209
+ def to_xml
210
+ xml = REXML::Document.new(super)
211
+ xml.root.elements.each(){}.map do |ele|
212
+ case ele.name
213
+ when "summary"
214
+ ele.text = @summary
215
+ when "timezone"
216
+ ele.attributes["value"] = @timezone
217
+ when "hidden"
218
+ ele.attributes["value"] = @hidden.to_s
219
+ when "color"
220
+ ele.attributes["value"] = @color
221
+ when "selected"
222
+ ele.attributes["value"] = @selected.to_s
223
+ end
224
+ end
225
+ xml.to_s
226
+ end
227
+
228
+ #Loads the Calendar with returned data from Google Calendar feed. Returns true if successful.
229
+ def load(string)
230
+ super(string)
231
+ @exists = true
232
+ @xml = string
233
+ xml = REXML::Document.new(string)
234
+ xml.root.elements.each(){}.map do |ele|
235
+ case ele.name
236
+ when "id"
237
+ @id = ele.text.gsub("http://www.google.com/calendar/feeds/default/calendars/", "")
238
+ when 'summary'
239
+ @summary = ele.text
240
+ when "color"
241
+ @color = ele.attributes['value']
242
+ when 'hidden'
243
+ @hidden = ele.attributes["value"] == "true" ? true : false
244
+ when 'timezone'
245
+ @timezone = ele.attributes["value"]
246
+ when "selected"
247
+ @selected = ele.attributes["value"] == "true" ? true : false
248
+ when "link"
249
+ if ele.attributes['rel'] == 'edit'
250
+ @edit_feed = ele.attributes['href']
251
+ end
252
+ when 'accesslevel'
253
+ @editable = (ele.attributes["value"] == 'editor' or ele.attributes["value"] == 'owner' or ele.attributes["value"] == 'root')
254
+ end
255
+ end
256
+
257
+ if @service.check_public
258
+ puts "Getting ACL Feed" if @service.debug
259
+
260
+ #rescue error on shared calenar ACL list access
261
+ begin
262
+ ret = @service.send_request(GData4Ruby::Request.new(:get, @acl_uri))
263
+ rescue Exception => e
264
+ puts "ACL Feed Get Failed: #{e.inspect}" if @service.debug
265
+ @public = false
266
+ return true
267
+ end
268
+ r = REXML::Document.new(ret.read_body)
269
+ r.root.elements.each("entry") do |ele|
270
+ e = GData4Ruby::ACL::AccessRule.new(service, self)
271
+ ele = GData4Ruby::Utils.add_namespaces(ele)
272
+ e.load(ele.to_s)
273
+ puts 'acl rule = '+e.inspect if service.debug
274
+ @public = (e.role.include? 'read' and e.user == 'default')
275
+ puts 'public = '+@public.to_s if service.debug
276
+ break if @public
277
+ end
278
+ else
279
+ @public = false
280
+ end
281
+ return true
282
+ end
283
+
284
+ #Helper function to return a formatted iframe embedded google calendar. Parameters are:
285
+ #1. *params*: a hash of parameters that affect the display of the embedded calendar. Accepts any parameter that the google iframe recognizes. Here are the most common:
286
+ # height:: the height of the embedded calendar in pixels
287
+ # width:: the width of the embedded calendar in pixels
288
+ # title:: the title to display
289
+ # bgcolor:: the background color. Limited choices, see google docs for allowable values.
290
+ # color:: the color of the calendar elements. Limited choices, see google docs for allowable values.
291
+ # showTitle:: set to '0' to hide the title
292
+ # showDate:: set to '0' to hide the current date
293
+ # showNav:: set to '0 to hide the navigation tools
294
+ # showPrint:: set to '0' to hide the print icon
295
+ # showTabs:: set to '0' to hide the tabs
296
+ # showCalendars:: set to '0' to hide the calendars selection drop down
297
+ # showTz:: set to '0' to hide the timezone selection
298
+ # border:: the border width in pixels
299
+ # dates:: a range of dates to display in the format of 'yyyymmdd/yyyymmdd'. Example: 20090820/20091001
300
+ # privateKey:: use to display a private calendar. You can find this key under the calendar settings pane of the Google Calendar website.
301
+ # ctz:: The timezone to convert event times to
302
+ def to_iframe(params = {})
303
+ params[:height] ||= "600"
304
+ params[:width] ||= "600"
305
+ params[:title] ||= (self.title ? self.title : '')
306
+ params[:bgcolor] ||= "#FFFFFF"
307
+ params[:color] ||= "#2952A3"
308
+ params[:border] ||= "0"
309
+ params.each{|key, value| params[key] = CGI::escape(value)}
310
+ output = "#{params.to_a.collect{|a| a.join("=")}.join("&")}"
311
+
312
+ output += "&src=#{id}"
313
+
314
+ "<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>"
315
+ end
316
+
317
+ #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
318
+ #service, but does require you know the google calendar id.
319
+ #1. *id*: the unique google assigned id for the calendar to display.
320
+ #2. *params*: a hash of parameters that affect the display of the embedded calendar. Accepts any parameter that the google iframe recognizes. Here are the most common:
321
+ # height:: the height of the embedded calendar in pixels
322
+ # width:: the width of the embedded calendar in pixels
323
+ # title:: the title to display
324
+ # bgcolor:: the background color. Limited choices, see google docs for allowable values.
325
+ # color:: the color of the calendar elements. Limited choices, see google docs for allowable values.
326
+ # showTitle:: set to '0' to hide the title
327
+ # showDate:: set to '0' to hide the current date
328
+ # showNav:: set to '0 to hide the navigation tools
329
+ # showPrint:: set to '0' to hide the print icon
330
+ # showTabs:: set to '0' to hide the tabs
331
+ # showCalendars:: set to '0' to hide the calendars selection drop down
332
+ # showTz:: set to '0' to hide the timezone selection
333
+ # border:: the border width in pixels
334
+ # dates:: a range of dates to display in the format of 'yyyymmdd/yyyymmdd'. Example: 20090820/20091001
335
+ # privateKey:: use to display a private calendar. You can find this key under the calendar settings pane of the Google Calendar website.
336
+ def self.to_iframe(id, params = {})
337
+ params[:height] ||= "600"
338
+ params[:width] ||= "600"
339
+ params[:bgcolor] ||= "#FFFFFF"
340
+ params[:color] ||= "#2952A3"
341
+ params[:border] ||= "0"
342
+ params.each{|key, value| params[key] = CGI::escape(value)}
343
+ output = "#{params.to_a.collect{|a| a.join("=")}.join("&")}"
344
+
345
+ output += "&src=#{id}"
346
+
347
+ "<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>"
348
+ end
349
+
350
+ private
351
+ def self.get_instance(service, d)
352
+ if d.is_a? Net::HTTPOK
353
+ xml = REXML::Document.new(d.read_body).root
354
+ if xml.name == 'feed'
355
+ xml = xml.elements.each("entry"){}[0]
356
+ end
357
+ else
358
+ xml = d
359
+ end
360
+ ele = GData4Ruby::Utils::add_namespaces(xml)
361
+ cal = Calendar.new(service)
362
+ cal.load(ele.to_s)
363
+ cal
364
+ end
365
+ end
366
+ end