gdatum 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.
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: