rufus-google 0.0.1
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/README.txt +98 -0
- data/lib/rufus-google.rb +3 -0
- data/lib/rufus/ahttp.rb +64 -0
- data/lib/rufus/gcal.rb +208 -0
- data/lib/rufus/google.rb +228 -0
- data/lib/rufus/gversion.rb +42 -0
- data/test/t0.rb +31 -0
- data/test/t_0_cal.rb +39 -0
- data/test/test.rb +3 -0
- metadata +82 -0
data/README.txt
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
|
2
|
+
= rufus-google
|
3
|
+
|
4
|
+
rufus-google should probably be named "rufus-gcal" for now, as only google calendar stuff is implemented.
|
5
|
+
|
6
|
+
This gem leverages 'atom-tools' to play with Google Data APIs.
|
7
|
+
|
8
|
+
The only authentication mechanism implemented for now is "ClientLogin".
|
9
|
+
|
10
|
+
(There is a one way synchronization tool for ical to gcal at
|
11
|
+
|
12
|
+
http://github.com/jmettraux/rufus-google/tree/master/tools/itog.rb
|
13
|
+
|
14
|
+
work in progress...)
|
15
|
+
|
16
|
+
|
17
|
+
== getting it
|
18
|
+
|
19
|
+
sudo gem install rufus-google
|
20
|
+
|
21
|
+
or at
|
22
|
+
|
23
|
+
http://rubyforge.org/frs/?group_id=4812
|
24
|
+
|
25
|
+
|
26
|
+
== usage
|
27
|
+
|
28
|
+
Using Google Calendar :
|
29
|
+
|
30
|
+
require 'rubygems'
|
31
|
+
require 'rufus/gcal'
|
32
|
+
|
33
|
+
calendars = Rufus::Google::Calendar.get_calendars(
|
34
|
+
:account => ENV['GUSER'], :password => ENV['GPASS'])
|
35
|
+
|
36
|
+
#calendars.values.each { |c| p [ c.name, c.href ] }
|
37
|
+
|
38
|
+
cal = calendars['gwork']
|
39
|
+
|
40
|
+
event_id = cal.post_quick!('Tennis with John November 13 3pm-4:30pm')
|
41
|
+
|
42
|
+
cal.events(:q => 'tennis').each do |e|
|
43
|
+
puts
|
44
|
+
puts e.to_s
|
45
|
+
end
|
46
|
+
|
47
|
+
cal.delete!(event_id)
|
48
|
+
|
49
|
+
puts "#{cal.events(:q => 'tennis').size} tennis events"
|
50
|
+
|
51
|
+
|
52
|
+
Other Google APIs will be covered later, if the need arise.
|
53
|
+
|
54
|
+
|
55
|
+
== dependencies
|
56
|
+
|
57
|
+
the 'rufus-verbs' and the 'atom-tools' gems.
|
58
|
+
|
59
|
+
|
60
|
+
== mailing list
|
61
|
+
|
62
|
+
On the rufus-ruby list[http://groups.google.com/group/rufus-ruby] :
|
63
|
+
|
64
|
+
http://groups.google.com/group/rufus-ruby
|
65
|
+
|
66
|
+
|
67
|
+
== issue tracker
|
68
|
+
|
69
|
+
http://rubyforge.org/tracker/?atid=18584&group_id=4812&func=browse
|
70
|
+
|
71
|
+
|
72
|
+
== irc
|
73
|
+
|
74
|
+
irc.freenode.net #ruote
|
75
|
+
|
76
|
+
|
77
|
+
== source
|
78
|
+
|
79
|
+
http://github.com/jmettraux/rufus-google
|
80
|
+
|
81
|
+
git clone git://github.com/jmettraux/rufus-google.git
|
82
|
+
|
83
|
+
|
84
|
+
== author
|
85
|
+
|
86
|
+
John Mettraux, jmettraux@gmail.com
|
87
|
+
http://jmettraux.wordpress.com
|
88
|
+
|
89
|
+
|
90
|
+
== the rest of Rufus
|
91
|
+
|
92
|
+
http://rufus.rubyforge.org
|
93
|
+
|
94
|
+
|
95
|
+
== license
|
96
|
+
|
97
|
+
MIT
|
98
|
+
|
data/lib/rufus-google.rb
ADDED
data/lib/rufus/ahttp.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
#
|
2
|
+
#--
|
3
|
+
# Copyright (c) 2008, John Mettraux, jmettraux@gmail.com
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
#
|
23
|
+
# (MIT license)
|
24
|
+
#++
|
25
|
+
#
|
26
|
+
|
27
|
+
#
|
28
|
+
# John Mettraux
|
29
|
+
#
|
30
|
+
# Made in Japan
|
31
|
+
#
|
32
|
+
# Tue Nov 11 22:18:23 JST 2008
|
33
|
+
#
|
34
|
+
|
35
|
+
require 'atom/http'
|
36
|
+
|
37
|
+
module Rufus
|
38
|
+
module Google
|
39
|
+
|
40
|
+
class Http < Atom::HTTP
|
41
|
+
|
42
|
+
def initialize (auth_token)
|
43
|
+
|
44
|
+
@auth_token = auth_token
|
45
|
+
|
46
|
+
super(nil)
|
47
|
+
#super({})
|
48
|
+
|
49
|
+
@allow_all_redirects = true
|
50
|
+
end
|
51
|
+
|
52
|
+
def http_request (
|
53
|
+
url_s, method, body=nil, headers={}, www_a=nil, redir_limit=5)
|
54
|
+
|
55
|
+
headers['Authorization'] = "GoogleLogin auth=#{@auth_token}"
|
56
|
+
headers['GData-Version'] = GDATA_VERSION
|
57
|
+
|
58
|
+
super(url_s, method, body, headers, www_a, redir_limit)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
data/lib/rufus/gcal.rb
ADDED
@@ -0,0 +1,208 @@
|
|
1
|
+
#
|
2
|
+
#--
|
3
|
+
# Copyright (c) 2008, John Mettraux, jmettraux@gmail.com
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
#
|
23
|
+
# (MIT license)
|
24
|
+
#++
|
25
|
+
#
|
26
|
+
|
27
|
+
#
|
28
|
+
# John Mettraux
|
29
|
+
#
|
30
|
+
# "Made in Japan" as opposed to "Swiss Made"
|
31
|
+
#
|
32
|
+
# Wed Nov 12 09:14:09 JST 2008
|
33
|
+
#
|
34
|
+
|
35
|
+
require 'rexml/element'
|
36
|
+
require 'rufus/google'
|
37
|
+
|
38
|
+
|
39
|
+
module Rufus
|
40
|
+
module Google
|
41
|
+
|
42
|
+
class Calendar
|
43
|
+
|
44
|
+
include CollectionMixin
|
45
|
+
|
46
|
+
#
|
47
|
+
# Returns all the events in the calendar.
|
48
|
+
#
|
49
|
+
# The query hash can be used to 'query' those events. It currently
|
50
|
+
# accepts :q, :start_min and :start_max as keys.
|
51
|
+
#
|
52
|
+
def events (query={})
|
53
|
+
|
54
|
+
q = query.inject([]) { |a, (k, v)|
|
55
|
+
a << "#{k.to_s.gsub(/\_/, '-')}=#{v}"
|
56
|
+
}.join("&")
|
57
|
+
|
58
|
+
q = "?#{q}" if q.length > 0
|
59
|
+
|
60
|
+
feed = Rufus::Google.feed_for("#{href}#{q}", @token)
|
61
|
+
feed.update!
|
62
|
+
|
63
|
+
feed.entries.collect { |e| Event.new(e) }
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
# Posts (creates) a QuickAdd event
|
68
|
+
# in this calendar.
|
69
|
+
#
|
70
|
+
# http://code.google.com/apis/calendar/developers_guide_protocol.html#CreatingQuickAdd
|
71
|
+
#
|
72
|
+
def post_quick! (event_text)
|
73
|
+
|
74
|
+
post!(Event.create_quick(event_text))
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# Returns a hash calendar_name => calendar
|
79
|
+
#
|
80
|
+
# an example :
|
81
|
+
#
|
82
|
+
# calendars = Rufus::Google::Calendar.get_calendars(
|
83
|
+
# :account => ENV['GUSER'], :password => env['GPASS'])
|
84
|
+
# calendars.values.each { |c| p [ c.name, c.href ] }
|
85
|
+
#
|
86
|
+
def self.get_calendars (options)
|
87
|
+
|
88
|
+
options[:service] = :cl
|
89
|
+
|
90
|
+
feed = Rufus::Google.feed_for(
|
91
|
+
'https://www.google.com/calendar/feeds/default', options)
|
92
|
+
|
93
|
+
feed.update! # fetch the data over the net
|
94
|
+
|
95
|
+
feed.entries.inject({}) { |h, e|
|
96
|
+
c = Calendar.new(options[:auth], e)
|
97
|
+
h[c.name] = c
|
98
|
+
h
|
99
|
+
}
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
#
|
104
|
+
# A google calendar event.
|
105
|
+
#
|
106
|
+
class Event
|
107
|
+
|
108
|
+
include EntryMixin
|
109
|
+
|
110
|
+
def start_time
|
111
|
+
evalue('when', 'startTime', :time => true)
|
112
|
+
end
|
113
|
+
|
114
|
+
def end_time
|
115
|
+
evalue('when', 'endTime', :time => true)
|
116
|
+
end
|
117
|
+
|
118
|
+
def where
|
119
|
+
evalue('where', 'valueString')
|
120
|
+
end
|
121
|
+
|
122
|
+
# TODO : add method for recurrence
|
123
|
+
|
124
|
+
def to_s
|
125
|
+
{
|
126
|
+
:id => @entry.id,
|
127
|
+
:etag => etag,
|
128
|
+
:title => @entry.title.to_s,
|
129
|
+
:start_time => start_time,
|
130
|
+
:end_time => end_time,
|
131
|
+
:where => where,
|
132
|
+
:author => "#{author.name} #{author.email}"
|
133
|
+
}.inspect
|
134
|
+
end
|
135
|
+
|
136
|
+
def self.create (opts)
|
137
|
+
|
138
|
+
e = Atom::Entry.new
|
139
|
+
e.title = opts[:title]
|
140
|
+
e.updated!
|
141
|
+
|
142
|
+
if c = opts[:content]
|
143
|
+
e.content = c
|
144
|
+
e.content['type'] = opts[:type] || 'text'
|
145
|
+
end
|
146
|
+
|
147
|
+
if st = opts[:start_time]
|
148
|
+
|
149
|
+
st = st.is_a?(DateTime) ? st : DateTime.parse(st)
|
150
|
+
st = st.to_s
|
151
|
+
st = st[0, 10] if opts[:all_day]
|
152
|
+
|
153
|
+
w = REXML::Element.new('gd:when')
|
154
|
+
w.add_attribute('startTime', st)
|
155
|
+
|
156
|
+
if et = opts[:end_time]
|
157
|
+
|
158
|
+
et = et.is_a?(DateTime) ? et : DateTime.parse(et)
|
159
|
+
et = et.to_s
|
160
|
+
et = et[0, 10] if opts[:all_day]
|
161
|
+
|
162
|
+
w.add_attribute('endTime', et)
|
163
|
+
end
|
164
|
+
|
165
|
+
e.extensions << w
|
166
|
+
end
|
167
|
+
|
168
|
+
if rc = opts[:recurrence]
|
169
|
+
|
170
|
+
r = REXML::Element.new('gd:recurrence')
|
171
|
+
r.text = rc
|
172
|
+
|
173
|
+
e.extensions << r
|
174
|
+
end
|
175
|
+
|
176
|
+
e.extensions.attributes['xmlns:gd'] =
|
177
|
+
'http://schemas.google.com/g/2005'
|
178
|
+
e.extensions.attributes['xmlns:gCal'] =
|
179
|
+
'http://schemas.google.com/gCal/2005'
|
180
|
+
|
181
|
+
#p e.to_xml.to_s
|
182
|
+
|
183
|
+
Event.new(e)
|
184
|
+
end
|
185
|
+
|
186
|
+
#
|
187
|
+
# Creates a QuickAdd event.
|
188
|
+
#
|
189
|
+
# http://code.google.com/apis/calendar/developers_guide_protocol.html#CreatingQuickAdd
|
190
|
+
#
|
191
|
+
def self.create_quick (text)
|
192
|
+
|
193
|
+
e = create(
|
194
|
+
:title => 'nada',
|
195
|
+
:type => 'html',
|
196
|
+
:content => text)
|
197
|
+
|
198
|
+
qa = REXML::Element.new('gCal:quickadd')
|
199
|
+
qa.add_attribute('value', 'true')
|
200
|
+
e.entry.extensions << qa
|
201
|
+
|
202
|
+
e
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
data/lib/rufus/google.rb
ADDED
@@ -0,0 +1,228 @@
|
|
1
|
+
#
|
2
|
+
#--
|
3
|
+
# Copyright (c) 2008, John Mettraux, jmettraux@gmail.com
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
#
|
23
|
+
# (MIT license)
|
24
|
+
#++
|
25
|
+
#
|
26
|
+
|
27
|
+
#
|
28
|
+
# John Mettraux
|
29
|
+
#
|
30
|
+
# Made in Japan
|
31
|
+
#
|
32
|
+
# Tue Nov 11 15:21:44 JST 2008
|
33
|
+
#
|
34
|
+
|
35
|
+
require 'cgi'
|
36
|
+
require 'uri'
|
37
|
+
require 'time'
|
38
|
+
require 'rufus/verbs'
|
39
|
+
require 'atom/feed'
|
40
|
+
#require 'atom/service'
|
41
|
+
require 'atom/collection'
|
42
|
+
require 'rufus/ahttp'
|
43
|
+
|
44
|
+
module Rufus
|
45
|
+
module Google
|
46
|
+
|
47
|
+
GDATA_VERSION = '2'
|
48
|
+
|
49
|
+
#
|
50
|
+
# Gets an auth token via the Google ClientLogin facility
|
51
|
+
#
|
52
|
+
def self.get_auth_tokens (options)
|
53
|
+
|
54
|
+
account = options[:account]
|
55
|
+
account_type = options[:account_type] || 'GOOGLE'
|
56
|
+
password = options[:password]
|
57
|
+
service = options[:service] || :cl
|
58
|
+
source = options[:source] || "rufus.rubyforge.org-rufus_google-#{VERSION}"
|
59
|
+
|
60
|
+
account = "#{account}@gmail.com" unless account.index('@')
|
61
|
+
|
62
|
+
password = CGI.escape(password)
|
63
|
+
|
64
|
+
data = ''
|
65
|
+
data << "accountType=#{account_type}&"
|
66
|
+
data << "Email=#{account}&"
|
67
|
+
data << "Passwd=#{password}&"
|
68
|
+
data << "service=#{service}&"
|
69
|
+
data << "source=#{source}"
|
70
|
+
|
71
|
+
headers = { 'Content-type' => 'application/x-www-form-urlencoded' }
|
72
|
+
headers['GData-Version'] = GDATA_VERSION
|
73
|
+
|
74
|
+
r = Rufus::Verbs.post(
|
75
|
+
'https://www.google.com/accounts/ClientLogin',
|
76
|
+
:headers => headers,
|
77
|
+
:data => data)
|
78
|
+
|
79
|
+
code = r.code.to_i
|
80
|
+
|
81
|
+
raise r.body if code == 403
|
82
|
+
raise "not a 200 OK reply : #{code} : #{r.body}" unless code == 200
|
83
|
+
|
84
|
+
tokens = r.body.split.inject({}) { |h, l|
|
85
|
+
md = l.match(/^(.*)=(.*$)/)
|
86
|
+
h[md[1].downcase.to_sym] = md[2]
|
87
|
+
h
|
88
|
+
}
|
89
|
+
|
90
|
+
options.merge!(tokens)
|
91
|
+
|
92
|
+
tokens
|
93
|
+
end
|
94
|
+
|
95
|
+
#
|
96
|
+
# Returns the auth token for a google account.
|
97
|
+
#
|
98
|
+
def self.get_auth_token (options)
|
99
|
+
|
100
|
+
return options if options.is_a?(String)
|
101
|
+
|
102
|
+
options[:auth] || get_auth_tokens(options)[:auth]
|
103
|
+
end
|
104
|
+
|
105
|
+
#
|
106
|
+
# A small method for getting an atom-tools Feed instance.
|
107
|
+
# The options hash is a get_auth_token() hash.
|
108
|
+
#
|
109
|
+
def self.feed_for (feed_uri, options)
|
110
|
+
|
111
|
+
token = get_auth_token(options)
|
112
|
+
|
113
|
+
Atom::Feed.new(feed_uri, Rufus::Google::Http.new(token))
|
114
|
+
end
|
115
|
+
|
116
|
+
module CollectionMixin
|
117
|
+
|
118
|
+
attr_reader :name, :href
|
119
|
+
|
120
|
+
def initialize (auth_token, entry)
|
121
|
+
|
122
|
+
@token = auth_token
|
123
|
+
@name = entry.title.to_s
|
124
|
+
@href = entry.links.find { |l| l.rel == 'alternate' }.href
|
125
|
+
end
|
126
|
+
|
127
|
+
#
|
128
|
+
# Posts (creates) an object
|
129
|
+
#
|
130
|
+
# Returns the URI of the created resource.
|
131
|
+
#
|
132
|
+
def post! (o)
|
133
|
+
|
134
|
+
r = collection.post!(o.entry)
|
135
|
+
|
136
|
+
raise "posting object of class #{o.class} failed : #{r.body}" \
|
137
|
+
unless r.code.to_i == 201
|
138
|
+
|
139
|
+
r['Location']
|
140
|
+
end
|
141
|
+
|
142
|
+
#
|
143
|
+
# Removes an object from the collection
|
144
|
+
#
|
145
|
+
def delete! (entry)
|
146
|
+
|
147
|
+
uri = entry.entry.edit_url
|
148
|
+
|
149
|
+
#r = collection.delete!(nil, uri)
|
150
|
+
r = collection.http.delete(uri, nil, { 'If-Match' => entry.etag })
|
151
|
+
|
152
|
+
raise "failed to delete entry (#{r.code}): #{r.body}" \
|
153
|
+
unless r.code.to_i == 200
|
154
|
+
|
155
|
+
r
|
156
|
+
end
|
157
|
+
|
158
|
+
protected
|
159
|
+
|
160
|
+
#
|
161
|
+
# returns the Atom::Collection instance
|
162
|
+
#
|
163
|
+
def collection
|
164
|
+
|
165
|
+
return @collection if @collection
|
166
|
+
|
167
|
+
@collection = Atom::Collection.new(
|
168
|
+
href, Rufus::Google::Http.new(@token))
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
#
|
173
|
+
# A mixin for entry based objects (like cal events for example)
|
174
|
+
#
|
175
|
+
module EntryMixin
|
176
|
+
|
177
|
+
attr_reader :entry
|
178
|
+
|
179
|
+
#
|
180
|
+
# Creates a google calendar event based on the info found in an
|
181
|
+
# atom-tools Entry instance.
|
182
|
+
#
|
183
|
+
def initialize (entry)
|
184
|
+
@entry = entry
|
185
|
+
end
|
186
|
+
|
187
|
+
def title
|
188
|
+
@entry.title.to_s
|
189
|
+
end
|
190
|
+
|
191
|
+
def author
|
192
|
+
@entry.authors.first
|
193
|
+
end
|
194
|
+
|
195
|
+
def authors
|
196
|
+
@entry.authors
|
197
|
+
end
|
198
|
+
|
199
|
+
def etag
|
200
|
+
@entry.extensions.attributes['gd:etag']
|
201
|
+
end
|
202
|
+
|
203
|
+
protected
|
204
|
+
|
205
|
+
#
|
206
|
+
# fetches a value in the extension part of the entry
|
207
|
+
#
|
208
|
+
# :time => true will attempt to parse the value to a Time instance
|
209
|
+
#
|
210
|
+
def evalue (elt_name, att_name, options={})
|
211
|
+
|
212
|
+
v = @entry.extensions.find { |e|
|
213
|
+
e.name == elt_name
|
214
|
+
}
|
215
|
+
|
216
|
+
return nil unless v
|
217
|
+
|
218
|
+
v = v.attribute(att_name)
|
219
|
+
|
220
|
+
v = Time.parse(v.value) if options[:time] == true
|
221
|
+
|
222
|
+
v
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#
|
2
|
+
#--
|
3
|
+
# Copyright (c) 2008, John Mettraux, jmettraux@gmail.com
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
#
|
23
|
+
# (MIT license)
|
24
|
+
#++
|
25
|
+
#
|
26
|
+
|
27
|
+
#
|
28
|
+
# John Mettraux
|
29
|
+
#
|
30
|
+
# Made in Japan
|
31
|
+
#
|
32
|
+
# Wed Nov 12 20:08:24 JST 2008
|
33
|
+
#
|
34
|
+
|
35
|
+
module Rufus
|
36
|
+
module Google
|
37
|
+
|
38
|
+
VERSION = '0.0.1'
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
data/test/t0.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rufus/gcal'
|
4
|
+
|
5
|
+
calendars = Rufus::Google::Calendar.get_calendars(
|
6
|
+
:account => ENV['GUSER'], :password => ENV['GPASS'])
|
7
|
+
|
8
|
+
#calendars.values.each { |c| p [ c.name, c.href ] }
|
9
|
+
|
10
|
+
cal = calendars['gtest']
|
11
|
+
|
12
|
+
#id = cal.post_quick!('Tennis with John November 13 3pm-4:30pm')
|
13
|
+
#t = Time.now
|
14
|
+
#id = cal.post!(Rufus::Google::Event.create(
|
15
|
+
# :title => 'drink Tequila at the Tennis club',
|
16
|
+
# :start_time => t,
|
17
|
+
# :end_time => t + 3600))
|
18
|
+
|
19
|
+
#cal.events(:q => 'tennis').each do |e|
|
20
|
+
cal.events().each do |e|
|
21
|
+
puts
|
22
|
+
puts e.to_s
|
23
|
+
#puts e.entry.to_s.gsub(/</, "\n<")
|
24
|
+
#puts e.entry.inspect
|
25
|
+
#p e.entry.extensions.attributes
|
26
|
+
#cal.delete!(e)
|
27
|
+
end
|
28
|
+
#cal.delete!(id)
|
29
|
+
|
30
|
+
#puts "#{cal.events(:q => 'tennis').size} tennis events"
|
31
|
+
|
data/test/t_0_cal.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# Testing rufus-google
|
4
|
+
#
|
5
|
+
# Wed Nov 12 20:59:36 JST 2008
|
6
|
+
#
|
7
|
+
|
8
|
+
require 'test/unit'
|
9
|
+
require 'rubygems'
|
10
|
+
require 'rufus/gcal'
|
11
|
+
|
12
|
+
class Test0Cal < Test::Unit::TestCase
|
13
|
+
|
14
|
+
def test_0
|
15
|
+
|
16
|
+
calendars = Rufus::Google::Calendar.get_calendars(
|
17
|
+
:account => ENV['GUSER'], :password => ENV['GPASS'])
|
18
|
+
|
19
|
+
cal = calendars['gtest']
|
20
|
+
|
21
|
+
#cal.events(:q => 'zorglub').each { |e| puts e.entry.to_s }
|
22
|
+
#cal.events(:q => 'zorglub').each { |e| puts e.to_s }
|
23
|
+
#return
|
24
|
+
cal.events(:q => 'zorglub').each { |e| cal.delete!(e) }
|
25
|
+
|
26
|
+
event_id = cal.post_quick!('Tennis with Zorglub November 13 3pm-4:30pm')
|
27
|
+
|
28
|
+
evts = cal.events(:q => 'zorglub')
|
29
|
+
|
30
|
+
assert_equal 1, evts.size
|
31
|
+
assert_equal 'Tennis with Zorglub', evts.first.title
|
32
|
+
|
33
|
+
cal.delete!(evts.first)
|
34
|
+
|
35
|
+
assert_equal [], cal.events(:q => 'zorglub')
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
data/test/test.rb
ADDED
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rufus-google
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- John Mettraux
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-12-03 00:00:00 +09:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rufus-verbs
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: atom-tools
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
description:
|
36
|
+
email: john at gmail dot com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- README.txt
|
43
|
+
files:
|
44
|
+
- lib/rufus
|
45
|
+
- lib/rufus/ahttp.rb
|
46
|
+
- lib/rufus/gcal.rb
|
47
|
+
- lib/rufus/google.rb
|
48
|
+
- lib/rufus/gversion.rb
|
49
|
+
- lib/rufus-google.rb
|
50
|
+
- test/t0.rb
|
51
|
+
- test/t_0_cal.rb
|
52
|
+
- test/test.rb
|
53
|
+
- README.txt
|
54
|
+
has_rdoc: true
|
55
|
+
homepage: http://rufus.rubyforge.org/rufus-google
|
56
|
+
post_install_message:
|
57
|
+
rdoc_options: []
|
58
|
+
|
59
|
+
require_paths:
|
60
|
+
- lib
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: "0"
|
66
|
+
version:
|
67
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: "0"
|
72
|
+
version:
|
73
|
+
requirements:
|
74
|
+
- rufus-verbs
|
75
|
+
- atom-tools
|
76
|
+
rubyforge_project: rufus
|
77
|
+
rubygems_version: 1.3.1
|
78
|
+
signing_key:
|
79
|
+
specification_version: 2
|
80
|
+
summary: snippets of Ruby code for accessing Google stuff
|
81
|
+
test_files:
|
82
|
+
- test/test.rb
|