Class: GCal4Ruby::Calendar

Inherits:
GData4Ruby::GDataObject
  • Object
show all
Defined in:
lib/gcal4ruby/calendar.rb

Overview

The Calendar Class is the representation of a Google Calendar. Each user account can have multiple calendars. You must have an authenticated Service object before using the Calendar object.

Usage

All usages assume a successfully authenticated Service.

  1. Create a new Calendar cal = Calendar.new(service)

  2. Find a calendar by ID cal = Calendar.find(service, => cal_id)

  3. Get all calendar events cal = Calendar.find(service, => cal_id) events = cal.events

  4. Find an existing calendar by title cal = Calendar.find(service, => “New Calendar”)

  5. Find all calendars containing a search term cal = Calendar.find(service, “Soccer Team”)

After a calendar object has been created or loaded, you can change any of the attributes like you would any other object. Be sure to save the calendar to write changes to the Google Calendar service.

Constant Summary collapse

ALL_CALENDARS_FEED =
'https://www.google.com/calendar/feeds/default/allcalendars/full'
OWN_CALENDARS_FEED =
'https://www.google.com/calendar/feeds/default/owncalendars/full'
CALENDAR_XML =
"<entry xmlns='http://www.w3.org/2005/Atom'
       xmlns:gd='http://schemas.google.com/g/2005' 
       xmlns:gCal='http://schemas.google.com/gCal/2005'>
  <title type='text'></title>
  <summary type='text'></summary>
  <gCal:timezone value='America/Los_Angeles'></gCal:timezone>
  <gCal:hidden value='false'></gCal:hidden>
  <gCal:color value='#2952A3'></gCal:color>
  <gd:where rel='' label='' valueString='Oakland'></gd:where>
</entry>"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(service, attributes = {}) ⇒ Calendar

Accepts a Service object and an optional attributes hash for initialization. Returns the new Calendar if successful, otherwise raises the InvalidService error.



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/gcal4ruby/calendar.rb', line 87

def initialize(service, attributes = {})
  super(service, attributes)
  if !service.is_a?(Service)
    raise InvalidService
  end
  @xml = @@calendar_xml
  @service ||= service
  @updated_at = nil
  @exists = false
  @title ||= ""
  @summary ||= ""
  @public ||= false
  @hidden ||= false
  @timezone ||= "America/Los_Angeles"
  @color ||= "#2952A3"
  @where ||= ""
  attributes.each do |key, value|
    if self.respond_to?("#{key}=")
      self.send("#{key}=", value)
    end
  end
  @debug ||= false
  return true
end

Instance Attribute Details

#colorObject

The calendar color. Must be one of these values.



71
72
73
# File 'lib/gcal4ruby/calendar.rb', line 71

def color
  @color
end

#editableObject (readonly)

A flag indicating whether the calendar is editable by this account



80
81
82
# File 'lib/gcal4ruby/calendar.rb', line 80

def editable
  @editable
end

#hiddenObject

Boolean value indicating the calendar visibility



65
66
67
# File 'lib/gcal4ruby/calendar.rb', line 65

def hidden
  @hidden
end

#selectedObject

A boolean value indicating whether the calendar appears by default when viewed online



77
78
79
# File 'lib/gcal4ruby/calendar.rb', line 77

def selected
  @selected
end

#summaryObject

A short description of the calendar



62
63
64
# File 'lib/gcal4ruby/calendar.rb', line 62

def summary
  @summary
end

#timezoneObject

The calendar timezone



68
69
70
# File 'lib/gcal4ruby/calendar.rb', line 68

def timezone
  @timezone
end

#titleObject

The calendar title



59
60
61
# File 'lib/gcal4ruby/calendar.rb', line 59

def title
  @title
end

#updated_atObject (readonly)

Timestamp when last updated



83
84
85
# File 'lib/gcal4ruby/calendar.rb', line 83

def updated_at
  @updated_at
end

#whereObject

The calendar geo location, if any



74
75
76
# File 'lib/gcal4ruby/calendar.rb', line 74

def where
  @where
end

Class Method Details

.find(service, query, args = {}) ⇒ Object

Finds a Calendar based on a text query or by an id. Parameters are:

service

A valid Service object to search.

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.

args

a hash containing optional additional query paramters to use. See code.google.com/apis/gdata/docs/2.0/reference.html#Queries for a full list of possible values. Example:

=> ‘100’ If an ID is specified, a single instance of the calendar is returned if found, otherwise false. If a query term or title text is specified, and array of matching results is returned, or an empty array if nothing was found.

Raises:

  • (ArgumentError)


175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/gcal4ruby/calendar.rb', line 175

def self.find(service, query, args = {})
  raise ArgumentError, 'query must be a hash or string' if not query.is_a? Hash and not query.is_a? String
  if query.is_a? Hash and query[:id]
    id = query[:id]
    puts "id passed, finding calendar by id" if service.debug
    puts "id = "+id if service.debug
    d = service.send_request(GData4Ruby::Request.new(:get, "#{OWN_CALENDARS_FEED}/#{id}", {"If-Not-Match" => "*"}))
    puts d.inspect if service.debug
    if d
      return get_instance(service, d)
    end
  else
    #fugly, but Google doesn't provide a way to query the calendar feed directly
    old_public = service.check_public
    service.check_public = false
    results = []
    cals = service.calendars
    cals.each do |cal|
      if query.is_a?(Hash)
        results << cal if query[:query] and cal.title.downcase.include? query[:query].downcase
        results << cal if query[:title] and cal.title == query[:title]
      else
        results << cal if cal.title.downcase.include? query.downcase
      end
    end
    service.check_public = old_public
    return results
  end
  return false
end

.to_iframe(id, params = {}) ⇒ Object

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 service, but does require you know the google calendar id.

  1. id: the unique google assigned id for the calendar to display.

  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:

height:: the height of the embedded calendar in pixels
width:: the width of the embedded calendar in pixels
title:: the title to display
bgcolor:: the background color.  Limited choices, see google docs for allowable values.
color:: the color of the calendar elements.  Limited choices, see google docs for allowable values.
showTitle:: set to '0' to hide the title
showDate:: set to '0' to hide the current date
showNav:: set to '0 to hide the navigation tools
showPrint:: set to '0' to hide the print icon
showTabs:: set to '0' to hide the tabs
showCalendars:: set to '0' to hide the calendars selection drop down
showTz:: set to '0' to hide the timezone selection
border:: the border width in pixels
dates:: a range of dates to display in the format of 'yyyymmdd/yyyymmdd'.  Example: 20090820/20091001
privateKey:: use to display a private calendar.  You can find this key under the calendar settings pane of the Google Calendar website.


356
357
358
359
360
361
362
363
364
365
366
367
368
# File 'lib/gcal4ruby/calendar.rb', line 356

def self.to_iframe(id, params = {})
  params[:height] ||= "600"
  params[:width] ||= "600"
  params[:bgcolor] ||= "#FFFFFF"
  params[:color] ||= "#2952A3"
  params[:border] ||= "0"
  params.each{|key, value| params[key] = CGI::escape(value)}
  output = "#{params.to_a.collect{|a| a.join("=")}.join("&")}"
  
  output += "&src=#{id}"
  
  "<iframe src='#{service.create_url("www.google.com/calendar/embed?"+output)}' style='#{params[:border]} px solid;' width='#{params[:width]}' height='#{params[:height]}' frameborder='#{params[:border]}' scrolling='no'></iframe>"  
end

Instance Method Details

#createObject

Creates a new instance of the object



163
164
165
# File 'lib/gcal4ruby/calendar.rb', line 163

def create
  return service.send_request(GData4Ruby::Request.new(:post, OWN_CALENDARS_FEED, to_xml()))
end

#eventsObject

Returns an array of Event objects corresponding to each event in the calendar.



124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/gcal4ruby/calendar.rb', line 124

def events
  events = []
  ret = service.send_request(GData4Ruby::Request.new(:get, @content_uri))
  REXML::Document.new(ret.body).root.elements.each("entry"){}.map do |entry|
    entry = GData4Ruby::Utils.add_namespaces(entry)
    e = Event.new(service)
    if e.load(entry.to_s)
      events << e
    end
  end
  return events
end

#exists?Boolean

Returns true if the calendar exists on the Google Calendar system (i.e. was loaded or has been saved). Otherwise returns false.

Returns:

  • (Boolean)


114
115
116
# File 'lib/gcal4ruby/calendar.rb', line 114

def exists?
  return @exists
end

#load(string) ⇒ Object

Loads the Calendar with returned data from Google Calendar feed. Returns true if successful.



239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/gcal4ruby/calendar.rb', line 239

def load(string)
  super(string)
  @exists = true
  @xml = string
  xml = REXML::Document.new(string)
  xml.root.elements.each(){}.map do |ele|
    case ele.name
      when "id"
      @id = ele.text.gsub("http://www.google.com/calendar/feeds/default/calendars/", "")
      when "updated"
      @updated_at = Time.xmlschema ele.text
      when 'summary'
      @summary = ele.text
      when "color"
      @color = ele.attributes['value']
      when 'hidden'
      @hidden = ele.attributes["value"] == "true" ? true : false
      when 'timezone'
      @timezone = ele.attributes["value"]
      when "selected"
      @selected = ele.attributes["value"] == "true" ? true : false
      when "link"
      if ele.attributes['rel'] == 'edit'
        @edit_feed = ele.attributes['href']
      end
      when 'accesslevel'
      @editable = (ele.attributes["value"] == 'editor' or ele.attributes["value"] == 'owner' or ele.attributes["value"] == 'root')
    end
  end
  
  if service.check_public
    log("Getting ACL Feed")
    
    # If the ACL URI doesn't exist, then its definitely not public
    if (@acl_uri == nil)
      log("Not Public")
      @public = false
      return true
    end
    
    #rescue error on shared calenar ACL list access
    begin 
      log("ACL URI: #{@acl_uri}")
      ret = service.send_request(GData4Ruby::Request.new(:get, @acl_uri))
    rescue Exception => e
      log("ACL Feed Get Failed: #{e.inspect}")
      @public = false
      return true
    end
    r = REXML::Document.new(ret.read_body)
    r.root.elements.each("entry") do |ele|
      e = GData4Ruby::ACL::AccessRule.new(service.gdata_service, self)
      ele = GData4Ruby::Utils.add_namespaces(ele)
      e.load(ele.to_s)
      log('ACL Rule: '+e.inspect)
      @public = (e.role.include? 'read' and e.user == 'default')
      log('Public: '+@public.to_s)
      break if @public
    end
  else
    @public = false
  end
  return true
end

#public=(p) ⇒ Object

Set the calendar to public (p = true) or private (p = false). Publically viewable calendars can be accessed by anyone without having to log in to google calendar. See Calendar#to_iframe on how to display a public calendar in a webpage.



158
159
160
# File 'lib/gcal4ruby/calendar.rb', line 158

def public=(p)
  @public = p
end

#public?Boolean

Returns true if the calendar is publically accessable, otherwise returns false.

Returns:

  • (Boolean)


119
120
121
# File 'lib/gcal4ruby/calendar.rb', line 119

def public?
  return @public
end

#reloadObject

Reloads the calendar objects information from the stored server version. Returns true if successful, otherwise returns false. Any information not saved will be overwritten.



208
209
210
211
212
213
214
215
216
# File 'lib/gcal4ruby/calendar.rb', line 208

def reload
  return false if not @exists
  t = Calendar.find(service, {:id => @id})
  if t
    load(t.to_xml)
  else
    return false
  end
end

#saveObject

Saves the calendar.



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/gcal4ruby/calendar.rb', line 139

def save
  public = @public
  ret = super
  return ret if public == @public
  if public
    log('setting calendar to public')
    rule = GData4Ruby::ACL::AccessRule.new(service.gdata_service, self)
    rule.role = 'http://schemas.google.com/gCal/2005#read'
    rule.save
  else
    rule = GData4Ruby::ACL::AccessRule.find(service.gdata_service, self, {:user => 'default'})
    rule.delete if rule
  end
  reload
end

#to_iframe(params = {}) ⇒ Object

Helper function to return a formatted iframe embedded google calendar. Parameters are:

  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:

height:: the height of the embedded calendar in pixels
width:: the width of the embedded calendar in pixels
title:: the title to display
bgcolor:: the background color.  Limited choices, see google docs for allowable values.
color:: the color of the calendar elements.  Limited choices, see google docs for allowable values.
showTitle:: set to '0' to hide the title
showDate:: set to '0' to hide the current date
showNav:: set to '0 to hide the navigation tools
showPrint:: set to '0' to hide the print icon
showTabs:: set to '0' to hide the tabs
showCalendars:: set to '0' to hide the calendars selection drop down
showTz:: set to '0' to hide the timezone selection
border:: the border width in pixels
dates:: a range of dates to display in the format of 'yyyymmdd/yyyymmdd'.  Example: 20090820/20091001
privateKey:: use to display a private calendar.  You can find this key under the calendar settings pane of the Google Calendar website.
ctz:: The timezone to convert event times to


322
323
324
325
326
327
328
329
330
331
332
333
334
335
# File 'lib/gcal4ruby/calendar.rb', line 322

def to_iframe(params = {})
  params[:height] ||= "600"
  params[:width] ||= "600"
  params[:title] ||= (self.title ? self.title : '')
  params[:bgcolor] ||= "#FFFFFF"
  params[:color] ||= "#2952A3"
  params[:border] ||= "0"
  params.each{|key, value| params[key] = CGI::escape(value)}
  output = "#{params.to_a.collect{|a| a.join("=")}.join("&")}"
  
  output += "&src=#{id}"
  
  "<iframe src='#{service.create_url("www.google.com/calendar/embed?"+output)}' style='#{params[:border]} px solid;' width='#{params[:width]}' height='#{params[:height]}' frameborder='#{params[:border]}' scrolling='no'></iframe>"  
end

#to_xmlObject

Returns the xml representation of the Calenar.



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/gcal4ruby/calendar.rb', line 219

def to_xml
  xml = REXML::Document.new(super)
  xml.root.elements.each(){}.map do |ele|
    case ele.name
      when "summary"
      ele.text = @summary
      when "timezone"
      ele.attributes["value"] = @timezone
      when "hidden"
      ele.attributes["value"] = @hidden.to_s
      when "color"
      ele.attributes["value"] = @color
      when "selected"
      ele.attributes["value"] = @selected.to_s
    end
  end
  xml.to_s
end