gdatum 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (8) hide show
  1. data/LICENSE +19 -0
  2. data/Manifest +7 -0
  3. data/README +11 -0
  4. data/Rakefile +39 -0
  5. data/lib/gcal.rb +125 -0
  6. data/test/fixture.xml +76 -0
  7. data/test/test_gcal.rb +47 -0
  8. metadata +60 -0
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2007 Christian Carter
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -0,0 +1,7 @@
1
+ ./lib/gcal.rb
2
+ ./LICENSE
3
+ ./Rakefile
4
+ ./README
5
+ ./test/fixture.xml
6
+ ./test/test_gcal.rb
7
+ ./Manifest
data/README ADDED
@@ -0,0 +1,11 @@
1
+ == Google Calendar Data API
2
+
3
+ This gem provides access to the calendar API to GData.
4
+
5
+ Usage:
6
+ g = GData.new(uri) # you can find your cal URI by following these directions: http://code.google.com/apis/calendar/developers_guide_protocol.html#find_feed_url
7
+
8
+ g.calendar # returns a calendar object
9
+ g.calendar.events.first.title # returns teh title of teh first event in the calendar
10
+
11
+ g.new_event(:title => "Blah") #makes a new event titles blah (note, you need all the stuff in GData#new_xml to get it to work)
@@ -0,0 +1,39 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ DIR = File.dirname(__FILE__)
5
+
6
+ begin
7
+ require 'rake/clean'
8
+ gem 'echoe', '>= 1.2'
9
+ require 'echoe'
10
+ require 'fileutils'
11
+ include FileUtils
12
+
13
+ CLEAN.include ['*.gem']
14
+
15
+ echoe = Echoe.new("gdatum", "0.1") do |p|
16
+ p.author = "Christian Carter"
17
+ p.rubyforge_name = "metacampsite"
18
+ p.name = "gdatum"
19
+ p.description = "A really simple ruby client to the GData API"
20
+ p.email = "cdcarter at gmail dot com"
21
+ p.summary = p.description
22
+ p.url = "http://metacampsite.com"
23
+ p.need_tar = false
24
+ p.need_tar_gz = true
25
+ p.test_globs = ["*_test.rb"]
26
+ p.extra_deps = ["hpricot"]
27
+ p.clean_globs = CLEAN
28
+ end
29
+
30
+ rescue LoadError => boom
31
+ puts "You are missing a dependency required for meta-operations on this gem."
32
+ puts "#{boom.to_s.capitalize}."
33
+
34
+ desc 'Run tests.'
35
+ desc 'Run the test suite.'
36
+ task :test do
37
+ system "ruby -Ibin:lib:test test/test_gcal.rb" # or whatever
38
+ end
39
+ end
@@ -0,0 +1,125 @@
1
+ ['rubygems','hpricot','net/http'].each {|x| require x}
2
+
3
+ class GCalendar
4
+ attr_accessor :title, :subtitle, :id, :link, :author_name, :author_email, :version, :where, :events
5
+
6
+ def initialize(hash={})
7
+ @events = []
8
+ hash.each {|k,v| self.send("#{k}=",v)}
9
+ end
10
+
11
+ def << (events)
12
+ @events.concat events
13
+ end
14
+
15
+ def to_html
16
+ content = <<-EOF
17
+ <div class="calendar" id="#{self.id}">
18
+ <h1>#{self.title}</h1>
19
+ <h2>#{self.subtitle}</h2>
20
+ #{self.events.map {|x| x.to_html}}
21
+ </div>
22
+ EOF
23
+ end
24
+ end
25
+
26
+ class GEvent
27
+ attr_accessor :id, :title, :content, :start_time, :end_time, :where, :author_name, :author_email
28
+
29
+ def initialize(hash={})
30
+ hash.each {|k,v| self.send("#{k}=",v)}
31
+ end
32
+
33
+ def to_html
34
+ content = <<-EOF
35
+ <div class="event" id="#{self.id}">
36
+ <h3>#{self.title}</h3>
37
+ <p class="content">#{self.content}<br/>#{self.start_time} - #{self.end_time}<br/>#{self.where}</p>
38
+ <p class="author">#{self.author_name}<br/>#{self.author_email}</p>
39
+ </div>
40
+ EOF
41
+ end
42
+ end
43
+
44
+ class GData
45
+ class HTTPFailure < Exception;end
46
+
47
+ def initialize(uri)
48
+ @uri = uri
49
+ end
50
+
51
+ def new_event(event={})
52
+ entry = new_xml(event)
53
+ http = Net::HTTP.new('www.google.com', 80)
54
+ response, data = http.post(@uri, entry)
55
+ raise HTTPFailure unless response.is_a? Net::HTTPSuccess
56
+ return data
57
+ end
58
+
59
+ def new_xml(event={})
60
+ content = <<-EOF
61
+ <?xml version="1.0"?>
62
+ <entry xmlns='http://www.w3.org/2005/Atom' xmlns:gd='http://schemas.google.com/g/2005'>
63
+ <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/g/2005#event'></category>
64
+ <title type='text'>#{event[:title]}</title>
65
+ <content type='text'>#{event[:content]}</content>
66
+ <author>
67
+ <name>#{event[:author]}</name>
68
+ <email>#{event[:email]}</email>
69
+ </author>
70
+
71
+ <gd:transparency value='http://schemas.google.com/g/2005#event.opaque'></gd:transparency>
72
+ <gd:eventStatus value='http://schemas.google.com/g/2005#event.confirmed'> </gd:eventStatus>
73
+
74
+ <gd:where valueString='#{event[:where]}'></gd:where>
75
+ <gd:when startTime='#{event[:startTime]}' endTime='#{event[:endTime]}'></gd:when>
76
+ </entry>
77
+ EOF
78
+ end
79
+
80
+ def calendar
81
+ unless @calendar
82
+ data = get_calendar
83
+ @calendar = parse_calendar(data)
84
+ @calendar << parse_events(data)
85
+ end
86
+ @calendar
87
+ end
88
+
89
+ def get_calendar
90
+ http = Net::HTTP.new('www.google.com', 80)
91
+ response, data = http.get(@uri)
92
+ raise HTTPFailure unless response.is_a? Net::HTTPSuccess
93
+ data
94
+ end
95
+
96
+ def parse_calendar(data)
97
+ cal = Hpricot.XML(data)
98
+ hash = {}
99
+ hash[:title] = cal.search("//feed/title").inner_html
100
+ hash[:subtitle] = cal.search("//feed/subtitle").inner_html
101
+ hash[:id] = cal.search("//feed/id").inner_html
102
+ hash[:link] = cal.search("//feed/link[@rel='self']").attr('href')
103
+ hash[:author_name] = cal.search("//feed/author/name").inner_html
104
+ hash[:author_email] = cal.search("//feed/author/email").inner_html
105
+ hash[:version] = cal.search("//feed/generator").attr('version')
106
+ hash[:where] = (cal/"gd:where").select {|x| x.parent.name == "feed" }[0].attributes['valueString']
107
+ return GCalendar.new(hash)
108
+ end
109
+
110
+ def parse_events(data)
111
+ cal = Hpricot.XML(data)
112
+ (cal/:entry).map do |event|
113
+ hash = {}
114
+ hash[:title] = (event/:title).inner_html
115
+ hash[:content] = (event/:content).inner_html
116
+ hash[:id] = (event/:id).inner_html
117
+ hash[:author_name] = (event/:author/:name).inner_html
118
+ hash[:author_email] = (event/:author/:email).inner_html
119
+ hash[:start_time] = (event/'gd:when').attr('startTime')
120
+ hash[:end_time] = (event/'gd:when').attr('endTime')
121
+ hash[:where] = (event/"gd:where").inner_html
122
+ GEvent.new(hash)
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,76 @@
1
+ <feed xmlns='http://www.w3.org/2005/Atom'
2
+ xmlns:gd='http://schemas.google.com/g/2005'>
3
+ <id>http://www.google.com/calendar/feeds/jo@gmail.com/private-magicCookie/full</id>
4
+ <updated>2006-03-29T07:35:59.000Z</updated>
5
+ <title type='text'>Jo March</title>
6
+ <subtitle type='text'>This is my main calendar.</subtitle>
7
+ <link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml'
8
+ href='http://www.google.com/calendar/feeds/jo@gmail.com/private-magicCookie/full'></link>
9
+ <link rel='self' type='application/atom+xml'
10
+ href='http://www.google.com/calendar/feeds/jo@gmail.com/private-magicCookie/full'></link>
11
+ <author>
12
+ <name>Jo March</name>
13
+ <email>jo@gmail.com</email>
14
+ </author>
15
+ <generator version='1.0' uri='http://www.google.com/calendar/'>CL2</generator>
16
+ <gd:where valueString='California'></gd:where>
17
+ <entry>
18
+ <id>http://www.google.com/calendar/feeds/jo@gmail.com/private-magicCookie/full/entryID</id>
19
+ <published>2006-03-30T22:00:00.000Z</published>
20
+ <updated>2006-03-28T05:47:31.000Z</updated>
21
+ <category scheme='http://schemas.google.com/g/2005#kind'
22
+ term='http://schemas.google.com/g/2005#event'></category>
23
+ <title type='text'>Lunch with Darcy</title>
24
+ <content type='text'>Lunch to discuss future plans.</content>
25
+ <link rel='alternate' type='text/html'
26
+ href='http://www.google.com/calendar/event?eid=aTJxcnNqbW9tcTJnaTE5cnMybmEwaW04bXMgbWFyY2guam9AZ21haWwuY29t'
27
+ title='alternate'></link>
28
+ <link rel='self' type='application/atom+xml'
29
+ href='http://www.google.com/calendar/feeds/jo@gmail.com/private-magicCookie/full/entryID'></link>
30
+ <author>
31
+ <name>Jo March</name>
32
+ <email>jo@gmail.com</email>
33
+ </author>
34
+ <gd:transparency
35
+ value='http://schemas.google.com/g/2005#event.opaque'></gd:transparency>
36
+ <gd:eventStatus
37
+ value='http://schemas.google.com/g/2005#event.confirmed'></gd:eventStatus>
38
+ <gd:comments>
39
+ <gd:feedLink
40
+ href='http://www.google.com/calendar/feeds/jo@gmail.com/private-magicCookie/full/entryID/comments/'></gd:feedLink>
41
+ </gd:comments>
42
+ <gd:when startTime='2006-03-30T22:00:00.000Z'
43
+ endTime='2006-03-30T23:00:00.000Z'></gd:when>
44
+ <gd:where>The Cafe</gd:where>
45
+ </entry>
46
+
47
+ <entry>
48
+ <id>http://www.google.com/calendar/feeds/jo@gmail.com/private-magicCookie/full/entryID</id>
49
+ <published>2006-02-30T22:00:00.000Z</published>
50
+ <updated>2006-02-28T05:47:31.000Z</updated>
51
+ <category scheme='http://schemas.google.com/g/2005#kind'
52
+ term='http://schemas.google.com/g/2005#event'></category>
53
+ <title type='text'>Meeting with Josh</title>
54
+ <content type='text'>Lunch to discuss raise.</content>
55
+ <link rel='alternate' type='text/html'
56
+ href='http://www.google.com/calendar/event?eid=aTJxcnNqbW9tcTJnaTE5cnMybmEwaW04bXMgbWFyY2guam9AZ21haWwuY29t'
57
+ title='alternate'></link>
58
+ <link rel='self' type='application/atom+xml'
59
+ href='http://www.google.com/calendar/feeds/jo@gmail.com/private-magicCookie/full/entryID'></link>
60
+ <author>
61
+ <name>Jo March</name>
62
+ <email>jo@gmail.com</email>
63
+ </author>
64
+ <gd:transparency
65
+ value='http://schemas.google.com/g/2005#event.opaque'></gd:transparency>
66
+ <gd:eventStatus
67
+ value='http://schemas.google.com/g/2005#event.confirmed'></gd:eventStatus>
68
+ <gd:comments>
69
+ <gd:feedLink
70
+ href='http://www.google.com/calendar/feeds/jo@gmail.com/private-magicCookie/full/entryID/comments/'></gd:feedLink>
71
+ </gd:comments>
72
+ <gd:when startTime='2006-03-28T22:00:00.000Z'
73
+ endTime='2006-03-28T23:00:00.000Z'></gd:when>
74
+ <gd:where>The Office</gd:where>
75
+ </entry>
76
+ </feed>
@@ -0,0 +1,47 @@
1
+ require "test/unit"
2
+
3
+ require "gcal"
4
+
5
+ class TestGData < Test::Unit::TestCase
6
+ def setup
7
+ @gdata = GData.new("http://www.google.com/calendar/feeds/jo@gmail.com/private-magicCookie/full")
8
+ @fixture = File.read('test/fixture.xml')
9
+ end
10
+
11
+ def test_calendar_append
12
+ cal = @gdata.parse_calendar(@fixture)
13
+ events = @gdata.parse_events(@fixture)
14
+ assert_equal(0, cal.events.size)
15
+ cal << events
16
+ assert_equal(2, cal.events.size)
17
+ end
18
+
19
+ def test_parse_calendar
20
+ result = @gdata.parse_calendar(@fixture)
21
+ assert_instance_of(GCalendar, result)
22
+ assert_equal('Jo March', result.author_name)
23
+ assert_equal('jo@gmail.com', result.author_email)
24
+ assert_equal('Jo March', result.title)
25
+ assert_equal('This is my main calendar.', result.subtitle)
26
+ assert_equal('1.0', result.version)
27
+ assert_equal('California', result.where)
28
+ assert_equal('http://www.google.com/calendar/feeds/jo@gmail.com/private-magicCookie/full', result.id)
29
+ assert_equal('http://www.google.com/calendar/feeds/jo@gmail.com/private-magicCookie/full', result.link)
30
+ end
31
+
32
+ def test_parse_events
33
+ result = @gdata.parse_events(@fixture)
34
+ assert_instance_of(Array, result)
35
+ assert_equal(2, result.size)
36
+ assert_instance_of(GEvent, result[0])
37
+ event1 = result[0]
38
+ assert_equal("Lunch with Darcy", event1.title)
39
+ assert_equal("Lunch to discuss future plans.", event1.content)
40
+ assert_equal('http://www.google.com/calendar/feeds/jo@gmail.com/private-magicCookie/full/entryID', event1.id)
41
+ assert_equal("The Cafe", event1.where)
42
+ assert_equal('2006-03-30T22:00:00.000Z', event1.start_time)
43
+ assert_equal('2006-03-30T23:00:00.000Z', event1.end_time)
44
+ assert_equal('Jo March', event1.author_name)
45
+ assert_equal('jo@gmail.com', event1.author_email)
46
+ end
47
+ end
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.2
3
+ specification_version: 1
4
+ name: gdatum
5
+ version: !ruby/object:Gem::Version
6
+ version: "0.1"
7
+ date: 2007-06-24 00:00:00 -05:00
8
+ summary: A really simple ruby client to the GData API
9
+ require_paths:
10
+ - lib
11
+ email: cdcarter at gmail dot com
12
+ homepage: http://metacampsite.com
13
+ rubyforge_project: metacampsite
14
+ description: A really simple ruby client to the GData API
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Christian Carter
31
+ files:
32
+ - ./lib/gcal.rb
33
+ - ./LICENSE
34
+ - ./Rakefile
35
+ - ./README
36
+ - ./test/fixture.xml
37
+ - ./test/test_gcal.rb
38
+ - ./Manifest
39
+ test_files: []
40
+
41
+ rdoc_options: []
42
+
43
+ extra_rdoc_files: []
44
+
45
+ executables: []
46
+
47
+ extensions: []
48
+
49
+ requirements: []
50
+
51
+ dependencies:
52
+ - !ruby/object:Gem::Dependency
53
+ name: hpricot
54
+ version_requirement:
55
+ version_requirements: !ruby/object:Gem::Version::Requirement
56
+ requirements:
57
+ - - ">"
58
+ - !ruby/object:Gem::Version
59
+ version: 0.0.0
60
+ version: