railsware-gcal4ruby 0.5.5
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/CHANGELOG +80 -0
- data/README +97 -0
- data/lib/gcal4ruby/calendar.rb +366 -0
- data/lib/gcal4ruby/event.rb +446 -0
- data/lib/gcal4ruby/recurrence.rb +273 -0
- data/lib/gcal4ruby/service.rb +160 -0
- data/lib/gcal4ruby.rb +1 -0
- data/test/unit.rb +182 -0
- metadata +89 -0
@@ -0,0 +1,273 @@
|
|
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
|
+
|
19
|
+
class Time
|
20
|
+
#Returns a ISO 8601 complete formatted string of the time
|
21
|
+
def complete
|
22
|
+
self.utc.strftime("%Y%m%dT%H%M%S")
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.parse_complete(value)
|
26
|
+
d, h = value.split("T")
|
27
|
+
return Time.parse(d+" "+h.gsub("Z", ""))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
module GCal4Ruby
|
32
|
+
#The Recurrence class stores information on an Event's recurrence. The class implements
|
33
|
+
#the RFC 2445 iCalendar recurrence description.
|
34
|
+
class Recurrence
|
35
|
+
#The event start date/time
|
36
|
+
attr_reader :start_time
|
37
|
+
#The event end date/time
|
38
|
+
attr_reader :end_time
|
39
|
+
#the event reference
|
40
|
+
attr_reader :event
|
41
|
+
#The date until which the event will be repeated
|
42
|
+
attr_reader :repeat_until
|
43
|
+
#The event frequency
|
44
|
+
attr_reader :frequency
|
45
|
+
#True if the event is all day (i.e. no start/end time)
|
46
|
+
attr_accessor :all_day
|
47
|
+
|
48
|
+
#Accepts an optional attributes hash or a string containing a properly formatted ISO 8601 recurrence rule. Returns a new Recurrence object
|
49
|
+
def initialize(vars = {})
|
50
|
+
if vars.is_a? Hash
|
51
|
+
vars.each do |key, value|
|
52
|
+
self.send("#{key}=", value)
|
53
|
+
end
|
54
|
+
elsif vars.is_a? String
|
55
|
+
self.load(vars)
|
56
|
+
end
|
57
|
+
@all_day ||= false
|
58
|
+
end
|
59
|
+
|
60
|
+
#Accepts a string containing a properly formatted ISO 8601 recurrence rule and loads it into the recurrence object
|
61
|
+
def load(rec)
|
62
|
+
attrs = rec.split("\n")
|
63
|
+
attrs.each do |val|
|
64
|
+
key, value = val.split(":")
|
65
|
+
case key
|
66
|
+
when 'DTSTART'
|
67
|
+
@start_time = Time.parse_complete(value)
|
68
|
+
when 'DTSTART;VALUE=DATE'
|
69
|
+
@start_time = Time.parse(value)
|
70
|
+
@all_day = true
|
71
|
+
when 'DTSTART;VALUE=DATE-TIME'
|
72
|
+
@start_time = Time.parse_complete(value)
|
73
|
+
when 'DTEND'
|
74
|
+
@end_time = Time.parse_complete(value)
|
75
|
+
when 'DTEND;VALUE=DATE'
|
76
|
+
@end_time = Time.parse(value)
|
77
|
+
when 'DTEND;VALUE=DATE-TIME'
|
78
|
+
@end_time = Time.parse_complete(value)
|
79
|
+
when 'RRULE'
|
80
|
+
vals = value.split(";")
|
81
|
+
key = ''
|
82
|
+
by = ''
|
83
|
+
int = nil
|
84
|
+
vals.each do |rr|
|
85
|
+
a, h = rr.split("=")
|
86
|
+
case a
|
87
|
+
when 'FREQ'
|
88
|
+
key = h.downcase.capitalize
|
89
|
+
when 'INTERVAL'
|
90
|
+
int = h
|
91
|
+
when 'UNTIL'
|
92
|
+
@repeat_until = Time.parse(value)
|
93
|
+
else
|
94
|
+
by = h.split(",")
|
95
|
+
end
|
96
|
+
end
|
97
|
+
@frequency = {key => by}
|
98
|
+
@frequency.merge({'interval' => int}) if int
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def to_s
|
104
|
+
output = ''
|
105
|
+
if @frequency
|
106
|
+
f = ''
|
107
|
+
i = ''
|
108
|
+
by = ''
|
109
|
+
@frequency.each do |key, v|
|
110
|
+
if v.is_a?(Array)
|
111
|
+
if v.size > 0
|
112
|
+
value = v.join(",")
|
113
|
+
else
|
114
|
+
value = nil
|
115
|
+
end
|
116
|
+
else
|
117
|
+
value = v
|
118
|
+
end
|
119
|
+
f += "#{key.downcase} " if key != 'interval'
|
120
|
+
case key.downcase
|
121
|
+
when "secondly"
|
122
|
+
by += "every #{value} second"
|
123
|
+
when "minutely"
|
124
|
+
by += "every #{value} minute"
|
125
|
+
when "hourly"
|
126
|
+
by += "every #{value} hour"
|
127
|
+
when "weekly"
|
128
|
+
by += "on #{value}" if value
|
129
|
+
when "monthly"
|
130
|
+
by += "on #{value}"
|
131
|
+
when "yearly"
|
132
|
+
by += "on the #{value} day of the year"
|
133
|
+
when 'interval'
|
134
|
+
i += "for #{value} times"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
output += f+i+by
|
138
|
+
end
|
139
|
+
if @repeat_until
|
140
|
+
output += " and repeats until #{@repeat_until.strftime("%m/%d/%Y")}"
|
141
|
+
end
|
142
|
+
output
|
143
|
+
end
|
144
|
+
|
145
|
+
#Returns a string with the correctly formatted ISO 8601 recurrence rule
|
146
|
+
def to_recurrence_string
|
147
|
+
|
148
|
+
output = ''
|
149
|
+
if @all_day
|
150
|
+
output += "DTSTART;VALUE=DATE:#{@start_time.utc.strftime("%Y%m%d")}\n"
|
151
|
+
else
|
152
|
+
output += "DTSTART;VALUE=DATE-TIME:#{@start_time.complete}\n"
|
153
|
+
end
|
154
|
+
if @all_day
|
155
|
+
output += "DTEND;VALUE=DATE:#{@end_time.utc.strftime("%Y%m%d")}\n"
|
156
|
+
else
|
157
|
+
output += "DTEND;VALUE=DATE-TIME:#{@end_time.complete}\n"
|
158
|
+
end
|
159
|
+
output += "RRULE:"
|
160
|
+
if @frequency
|
161
|
+
f = 'FREQ='
|
162
|
+
i = ''
|
163
|
+
by = ''
|
164
|
+
@frequency.each do |key, v|
|
165
|
+
if v.is_a?(Array)
|
166
|
+
if v.size > 0
|
167
|
+
value = v.join(",")
|
168
|
+
else
|
169
|
+
value = nil
|
170
|
+
end
|
171
|
+
else
|
172
|
+
value = v
|
173
|
+
end
|
174
|
+
f += "#{key.upcase};" if key != 'interval'
|
175
|
+
case key.downcase
|
176
|
+
when "secondly"
|
177
|
+
by += "BYSECOND=#{value};"
|
178
|
+
when "minutely"
|
179
|
+
by += "BYMINUTE=#{value};"
|
180
|
+
when "hourly"
|
181
|
+
by += "BYHOUR=#{value};"
|
182
|
+
when "weekly"
|
183
|
+
by += "BYDAY=#{value};" if value
|
184
|
+
when "monthly"
|
185
|
+
by += "BYDAY=#{value};"
|
186
|
+
when "yearly"
|
187
|
+
by += "BYYEARDAY=#{value};"
|
188
|
+
when 'interval'
|
189
|
+
i += "INTERVAL=#{value};"
|
190
|
+
end
|
191
|
+
end
|
192
|
+
output += f+i+by
|
193
|
+
end
|
194
|
+
if @repeat_until
|
195
|
+
output += "UNTIL=#{@repeat_until.strftime("%Y%m%d")}"
|
196
|
+
end
|
197
|
+
|
198
|
+
output += "\n"
|
199
|
+
end
|
200
|
+
|
201
|
+
#Sets the start date/time. Must be a Time object.
|
202
|
+
def start_time=(s)
|
203
|
+
if not s.is_a?(Time)
|
204
|
+
raise RecurrenceValueError, "Start must be a date or a time"
|
205
|
+
else
|
206
|
+
@start_time = s
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
#Sets the end Date/Time. Must be a Time object.
|
211
|
+
def end_time=(e)
|
212
|
+
if not e.is_a?(Time)
|
213
|
+
raise RecurrenceValueError, "End must be a date or a time"
|
214
|
+
else
|
215
|
+
@end_time = e
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
#Sets the parent event reference
|
220
|
+
def event=(e)
|
221
|
+
if not e.is_a?(Event)
|
222
|
+
raise RecurrenceValueError, "Event must be an event"
|
223
|
+
else
|
224
|
+
@event = e
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
#Sets the end date for the recurrence
|
229
|
+
def repeat_until=(r)
|
230
|
+
if not r.is_a?(Date)
|
231
|
+
raise RecurrenceValueError, "Repeat_until must be a date"
|
232
|
+
else
|
233
|
+
@repeat_until = r
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
#Sets the frequency of the recurrence. Should be a hash with one of
|
238
|
+
#"SECONDLY", "MINUTELY", "HOURLY", "DAILY", "WEEKLY", "MONTHLY", "YEARLY" as the key,
|
239
|
+
#and as the value, an array containing zero to n of the following:
|
240
|
+
#- *Secondly*: A value between 0 and 59. Causes the event to repeat on that second of each minut.
|
241
|
+
#- *Minutely*: A value between 0 and 59. Causes the event to repeat on that minute of every hour.
|
242
|
+
#- *Hourly*: A value between 0 and 23. Causes the even to repeat on that hour of every day.
|
243
|
+
#- *Daily*: No value needed - will cause the event to repeat every day until the repeat_until date.
|
244
|
+
#- *Weekly*: A value of the first two letters of a day of the week. Causes the event to repeat on that day.
|
245
|
+
#- *Monthly*: A value of a positive or negative integer (i.e. +1) prepended to a day-of-week string ('TU') to indicate the position of the day within the month. E.g. +1TU would be the first tuesday of the month.
|
246
|
+
#- *Yearly*: A value of 1 to 366 indicating the day of the year. May be negative to indicate counting down from the last day of the year.
|
247
|
+
#
|
248
|
+
#Optionally, you may specific a second hash pair to set the interval the event repeats:
|
249
|
+
# "interval" => '2'
|
250
|
+
#If the interval is missing, it is assumed to be 1.
|
251
|
+
#
|
252
|
+
#===Examples
|
253
|
+
#Repeat event every Tuesday:
|
254
|
+
# frequency = {"Weekly" => ["TU"]}
|
255
|
+
#
|
256
|
+
#Repeat every first and third Monday of the month
|
257
|
+
# frequency = {"Monthly" => ["+1MO", "+3MO"]}
|
258
|
+
#
|
259
|
+
#Repeat on the last day of every year
|
260
|
+
# frequency = {"Yearly" => [366]}
|
261
|
+
#
|
262
|
+
#Repeat every other week on Friday
|
263
|
+
# frequency = {"Weekly" => ["FR"], "interval" => "2"}
|
264
|
+
|
265
|
+
def frequency=(f)
|
266
|
+
if f.is_a?(Hash)
|
267
|
+
@frequency = f
|
268
|
+
else
|
269
|
+
raise RecurrenceValueError, "Frequency must be a hash (see documentation)"
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
@@ -0,0 +1,160 @@
|
|
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'
|
19
|
+
require 'gdata4ruby/gdata_object'
|
20
|
+
require 'gdata4ruby/utils/utils'
|
21
|
+
require 'gdata4ruby/acl/access_rule'
|
22
|
+
require 'gcal4ruby/calendar'
|
23
|
+
require 'gcal4ruby/event'
|
24
|
+
require 'gcal4ruby/recurrence'
|
25
|
+
require 'rexml/document'
|
26
|
+
|
27
|
+
module GCal4Ruby
|
28
|
+
#The service class is the main handler for all direct interactions with the
|
29
|
+
#Google Calendar API. A service represents a single user account. Each user
|
30
|
+
#account can have multiple calendars, so you'll need to find the calendar you
|
31
|
+
#want from the service, using the Calendar#find class method.
|
32
|
+
#=Usage
|
33
|
+
#
|
34
|
+
#1. Authenticate
|
35
|
+
# service = Service.new
|
36
|
+
# service.authenticate("user@gmail.com", "password")
|
37
|
+
#
|
38
|
+
#2. Get Calendar List
|
39
|
+
# calendars = service.calendars
|
40
|
+
#
|
41
|
+
class Service < GData4Ruby::Service
|
42
|
+
CALENDAR_LIST_FEED = 'http://www.google.com/calendar/feeds/default/allcalendars/full'
|
43
|
+
|
44
|
+
#Convenience attribute contains the currently authenticated account name
|
45
|
+
attr_reader :account
|
46
|
+
|
47
|
+
# The token returned by the Google servers, used to authorize all subsequent messages
|
48
|
+
attr_reader :auth_token
|
49
|
+
|
50
|
+
# Determines whether GCal4Ruby ensures a calendar is public. Setting this to false can increase speeds by
|
51
|
+
# 50% but can cause errors if you try to do something to a calendar that is not public and you don't have
|
52
|
+
# adequate permissions
|
53
|
+
attr_accessor :check_public
|
54
|
+
|
55
|
+
#Accepts an optional attributes hash for initialization values
|
56
|
+
def initialize(attributes = {})
|
57
|
+
super(attributes)
|
58
|
+
attributes.each do |key, value|
|
59
|
+
self.send("#{key}=", value)
|
60
|
+
end
|
61
|
+
@check_public ||= true
|
62
|
+
end
|
63
|
+
|
64
|
+
def default_event_feed
|
65
|
+
return "http://www.google.com/calendar/feeds/#{@account}/private/full"
|
66
|
+
end
|
67
|
+
|
68
|
+
# The authenticate method passes the username and password to google servers.
|
69
|
+
# If authentication succeeds, returns true, otherwise raises the AuthenticationFailed error.
|
70
|
+
def authenticate(username, password, service='cl')
|
71
|
+
super(username, password, service)
|
72
|
+
end
|
73
|
+
|
74
|
+
#Helper function to reauthenticate to a new Google service without having to re-set credentials.
|
75
|
+
def reauthenticate(service='cl')
|
76
|
+
authenticate(@account, @password, service)
|
77
|
+
end
|
78
|
+
|
79
|
+
#Returns an array of Calendar objects for each calendar associated with
|
80
|
+
#the authenticated account.
|
81
|
+
def calendars
|
82
|
+
if not @auth_token
|
83
|
+
raise NotAuthenticated
|
84
|
+
end
|
85
|
+
ret = send_request(GData4Ruby::Request.new(:get, CALENDAR_LIST_FEED, nil, {"max-results" => "10000"}))
|
86
|
+
cals = []
|
87
|
+
REXML::Document.new(ret.body).root.elements.each("entry"){}.map do |entry|
|
88
|
+
entry = GData4Ruby::Utils.add_namespaces(entry)
|
89
|
+
cal = Calendar.new(self)
|
90
|
+
cal.load(entry.to_s)
|
91
|
+
cals << cal
|
92
|
+
end
|
93
|
+
return cals
|
94
|
+
end
|
95
|
+
|
96
|
+
#Returns an array of Event objects for each event in this account
|
97
|
+
def events
|
98
|
+
if not @auth_token
|
99
|
+
raise NotAuthenticated
|
100
|
+
end
|
101
|
+
ret = send_request(GData4Ruby::Request.new(:get, default_event_feed, nil, {"max-results" => "10000"}))
|
102
|
+
events = []
|
103
|
+
REXML::Document.new(ret.body).root.elements.each("entry"){}.map do |entry|
|
104
|
+
entry = GData4Ruby::Utils.add_namespaces(entry)
|
105
|
+
event = Event.new(self)
|
106
|
+
event.load(entry.to_s)
|
107
|
+
events << event
|
108
|
+
end
|
109
|
+
return events
|
110
|
+
end
|
111
|
+
|
112
|
+
#Helper function to return a formatted iframe embedded google calendar. Parameters are:
|
113
|
+
#1. *cals*: either an array of calendar ids, or <em>:all</em> for all calendars, or <em>:first</em> for the first (usally default) calendar
|
114
|
+
#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:
|
115
|
+
# height:: the height of the embedded calendar in pixels
|
116
|
+
# width:: the width of the embedded calendar in pixels
|
117
|
+
# title:: the title to display
|
118
|
+
# bgcolor:: the background color. Limited choices, see google docs for allowable values.
|
119
|
+
# showTitle:: set to '0' to hide the title
|
120
|
+
# showDate:: set to '0' to hide the current date
|
121
|
+
# showNav:: set to '0 to hide the navigation tools
|
122
|
+
# showPrint:: set to '0' to hide the print icon
|
123
|
+
# showTabs:: set to '0' to hide the tabs
|
124
|
+
# showCalendars:: set to '0' to hide the calendars selection drop down
|
125
|
+
# showTz:: set to '0' to hide the timezone selection
|
126
|
+
# border:: the border width in pixels
|
127
|
+
# dates:: a range of dates to display in the format of 'yyyymmdd/yyyymmdd'. Example: 20090820/20091001
|
128
|
+
# privateKey:: use to display a private calendar. You can find this key under the calendar settings pane of the Google Calendar website.
|
129
|
+
# ctz:: The timezone to convert event times to
|
130
|
+
#3. *colors*: a hash of calendar ids as key and color values as associated hash values. Example: {'test@gmail.com' => '#7A367A'}
|
131
|
+
def to_iframe(cals, params = {}, colors = {})
|
132
|
+
params[:height] ||= "600"
|
133
|
+
params[:width] ||= "600"
|
134
|
+
params[:title] ||= (self.account ? self.account : '')
|
135
|
+
params[:bgcolor] ||= "#FFFFFF"
|
136
|
+
params[:border] ||= "0"
|
137
|
+
params.each{|key, value| params[key] = CGI::escape(value)}
|
138
|
+
output = "#{params.to_a.collect{|a| a.join("=")}.join("&")}&"
|
139
|
+
|
140
|
+
if cals.is_a?(Array)
|
141
|
+
for c in cals
|
142
|
+
output += "src=#{c}&"
|
143
|
+
if colors and colors[c]
|
144
|
+
output += "color=%23#{colors[c].gsub("#", "")}&"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
elsif cals == :all
|
148
|
+
cal_list = calendars()
|
149
|
+
for c in cal_list
|
150
|
+
output += "src=#{c.id}&"
|
151
|
+
end
|
152
|
+
elsif cals == :first
|
153
|
+
cal_list = calendars()
|
154
|
+
output += "src=#{cal_list[0].id}&"
|
155
|
+
end
|
156
|
+
|
157
|
+
"<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>"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
data/lib/gcal4ruby.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "gcal4ruby/service"
|
data/test/unit.rb
ADDED
@@ -0,0 +1,182 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'gcal4ruby'
|
5
|
+
include GCal4Ruby
|
6
|
+
|
7
|
+
@service = Service.new
|
8
|
+
@username = nil
|
9
|
+
@password = nil
|
10
|
+
|
11
|
+
def tester
|
12
|
+
if ARGV.include?("-d")
|
13
|
+
@service.debug = true
|
14
|
+
end
|
15
|
+
ARGV.each do |ar|
|
16
|
+
if ar.match("username=")
|
17
|
+
@username = ar.gsub("username=", "")
|
18
|
+
end
|
19
|
+
if ar.match("password=")
|
20
|
+
@password = ar.gsub("password=", "")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
service_test
|
24
|
+
calendar_test
|
25
|
+
event_test
|
26
|
+
event_recurrence_test
|
27
|
+
end
|
28
|
+
|
29
|
+
def service_test
|
30
|
+
puts "---Starting Service Test---"
|
31
|
+
puts "1. Authenticate"
|
32
|
+
if @service.authenticate(@username, @password)
|
33
|
+
successful
|
34
|
+
else
|
35
|
+
failed
|
36
|
+
end
|
37
|
+
|
38
|
+
puts "2. Calendar List"
|
39
|
+
cals = @service.calendars
|
40
|
+
if cals
|
41
|
+
successful "Calendars for this Account:"
|
42
|
+
cals.each do |cal|
|
43
|
+
puts cal.title
|
44
|
+
end
|
45
|
+
else
|
46
|
+
failed
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def calendar_test
|
51
|
+
puts "---Starting Calendar Test---"
|
52
|
+
|
53
|
+
puts "1. Create Calendar"
|
54
|
+
cal = Calendar.new(@service)
|
55
|
+
cal.title = "test calendar"+Time.now.to_s
|
56
|
+
puts "Calender exists = "+cal.exists?.to_s
|
57
|
+
if cal.save
|
58
|
+
successful cal.to_xml
|
59
|
+
else
|
60
|
+
failed
|
61
|
+
end
|
62
|
+
|
63
|
+
puts "2. Edit Calendar"
|
64
|
+
cal.title = "renamed title"
|
65
|
+
if cal.save
|
66
|
+
successful cal.to_xml
|
67
|
+
else
|
68
|
+
puts "Test 2 Failed"
|
69
|
+
end
|
70
|
+
|
71
|
+
puts "3. Find Calendar by ID"
|
72
|
+
c = Calendar.find(@service, {:id => cal.id})
|
73
|
+
if c.title == cal.title
|
74
|
+
successful
|
75
|
+
else
|
76
|
+
failed "#{c.title} not equal to #{cal.title}"
|
77
|
+
end
|
78
|
+
|
79
|
+
puts "4. Delete Calendar"
|
80
|
+
if cal.delete and not cal.exists?
|
81
|
+
successful
|
82
|
+
else
|
83
|
+
failed
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def event_test
|
88
|
+
puts "---Starting Event Test---"
|
89
|
+
|
90
|
+
puts "1. Create Event"
|
91
|
+
event = Event.new(@service)
|
92
|
+
event.calendar = @service.calendars[0]
|
93
|
+
event.title = "Test Event"
|
94
|
+
event.content = "Test event content"
|
95
|
+
event.start_time = Time.now+1800
|
96
|
+
event.end_time = Time.now+5400
|
97
|
+
if event.save
|
98
|
+
successful event.to_xml
|
99
|
+
else
|
100
|
+
failed
|
101
|
+
end
|
102
|
+
|
103
|
+
puts "2. Edit Event"
|
104
|
+
event.title = "Edited title"
|
105
|
+
if event.save
|
106
|
+
successful event.to_xml
|
107
|
+
else
|
108
|
+
failed
|
109
|
+
end
|
110
|
+
|
111
|
+
puts "3. Reload Event"
|
112
|
+
if event.reload
|
113
|
+
successful
|
114
|
+
end
|
115
|
+
|
116
|
+
puts "4. Find Event by id"
|
117
|
+
e = Event.find(@service, {:id => event.id})
|
118
|
+
if e.title == event.title
|
119
|
+
successful
|
120
|
+
else
|
121
|
+
failed "Found event doesn't match existing event"
|
122
|
+
end
|
123
|
+
|
124
|
+
puts "5. Delete Event"
|
125
|
+
if event.delete
|
126
|
+
successful
|
127
|
+
else
|
128
|
+
failed
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def event_recurrence_test
|
133
|
+
puts "---Starting Event Recurrence Test---"
|
134
|
+
|
135
|
+
@first_start = Time.now
|
136
|
+
@first_end = Time.now+3600
|
137
|
+
@first_freq = {'weekly' => ['TU']}
|
138
|
+
@second_start = Time.now+86000
|
139
|
+
@second_end = Time.now+89600
|
140
|
+
@second_freq = {'weekly' => ['SA']}
|
141
|
+
|
142
|
+
puts "1. Create Recurring Event"
|
143
|
+
event = Event.new(@service)
|
144
|
+
event.calendar = @service.calendars[0]
|
145
|
+
event.title = "Test Recurring Event"
|
146
|
+
event.content = "Test event content"
|
147
|
+
event.recurrence = Recurrence.new({:start_time => @first_start, :end_time => @first_end, :frequency => @first_freq})
|
148
|
+
if event.save
|
149
|
+
successful event.to_xml
|
150
|
+
else
|
151
|
+
failed("recurrence = "+event.recurrence.to_s)
|
152
|
+
end
|
153
|
+
|
154
|
+
puts "2. Edit Recurrence"
|
155
|
+
event.title = "Edited recurring title"
|
156
|
+
event.recurrence = Recurrence.new({:start_time => @second_start, :end_time => @second_end, :frequency => @second_freq})
|
157
|
+
if event.save
|
158
|
+
successful event.to_xml
|
159
|
+
else
|
160
|
+
failed
|
161
|
+
end
|
162
|
+
|
163
|
+
puts "3. Delete Event"
|
164
|
+
if event.delete
|
165
|
+
successful
|
166
|
+
else
|
167
|
+
failed
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def failed(m = nil)
|
172
|
+
puts "Test Failed"
|
173
|
+
puts m if m
|
174
|
+
exit()
|
175
|
+
end
|
176
|
+
|
177
|
+
def successful(m = nil)
|
178
|
+
puts "Test Successful"
|
179
|
+
puts m if m
|
180
|
+
end
|
181
|
+
|
182
|
+
tester
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: railsware-gcal4ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 1
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 5
|
9
|
+
- 5
|
10
|
+
version: 0.5.5
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Mike Reich
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-07-08 00:00:00 +03:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: gdata4ruby
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 25
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 1
|
33
|
+
- 1
|
34
|
+
version: 0.1.1
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
description: "GCal4Ruby is a Ruby Gem that can be used to interact with the current version of the Google Calendar API. GCal4Ruby provides the following features: Create and edit calendar events, Add and invite users to events, Set reminders, Make recurring events."
|
38
|
+
email: mike@seabourneconsulting.com
|
39
|
+
executables: []
|
40
|
+
|
41
|
+
extensions: []
|
42
|
+
|
43
|
+
extra_rdoc_files: []
|
44
|
+
|
45
|
+
files:
|
46
|
+
- README
|
47
|
+
- CHANGELOG
|
48
|
+
- lib/gcal4ruby.rb
|
49
|
+
- lib/gcal4ruby/service.rb
|
50
|
+
- lib/gcal4ruby/calendar.rb
|
51
|
+
- lib/gcal4ruby/event.rb
|
52
|
+
- lib/gcal4ruby/recurrence.rb
|
53
|
+
- test/unit.rb
|
54
|
+
has_rdoc: true
|
55
|
+
homepage: http://cookingandcoding.com/gcal4ruby/
|
56
|
+
licenses: []
|
57
|
+
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options: []
|
60
|
+
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
hash: 3
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
hash: 3
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
version: "0"
|
81
|
+
requirements: []
|
82
|
+
|
83
|
+
rubyforge_project: gcal4ruby
|
84
|
+
rubygems_version: 1.3.7
|
85
|
+
signing_key:
|
86
|
+
specification_version: 3
|
87
|
+
summary: A full featured wrapper for interacting with the Google Calendar API
|
88
|
+
test_files:
|
89
|
+
- test/unit.rb
|