syndication 0.5.1 → 0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README +20 -14
- data/examples/google.rb +23 -0
- data/lib/syndication/atom.rb +9 -11
- data/lib/syndication/common.rb +3 -2
- data/lib/syndication/content.rb +1 -1
- data/lib/syndication/dublincore.rb +1 -1
- data/lib/syndication/google.rb +58 -0
- data/lib/syndication/podcast.rb +1 -1
- data/lib/syndication/rss.rb +11 -7
- data/lib/syndication/syndication.rb +1 -1
- data/lib/syndication/tagsoup.rb +5 -3
- data/rakefile +10 -2
- data/test/atomtest.rb +3 -3
- data/test/google.rb +91 -0
- data/test/rsstest.rb +6 -6
- data/test/tagsouptest.rb +5 -6
- metadata +7 -3
data/README
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# = Syndication 0.
|
1
|
+
# = Syndication 0.6
|
2
2
|
#
|
3
3
|
# This module provides classes for parsing web syndication feeds in RSS and
|
4
4
|
# Atom formats.
|
@@ -19,12 +19,12 @@
|
|
19
19
|
#
|
20
20
|
# == License
|
21
21
|
#
|
22
|
-
# Syndication is Copyright 2005 mathew <meta@pobox.com>, and is licensed
|
22
|
+
# Syndication is Copyright 2005-2006 mathew <meta@pobox.com>, and is licensed
|
23
23
|
# under the same terms as Ruby.
|
24
24
|
#
|
25
25
|
# == Requirements
|
26
26
|
#
|
27
|
-
# Built and tested using Ruby 1.8.
|
27
|
+
# Built and tested using Ruby 1.8.4. Needs only the standard library.
|
28
28
|
#
|
29
29
|
# == Rationale
|
30
30
|
#
|
@@ -52,7 +52,7 @@
|
|
52
52
|
# breaking existing code that used the RSS module, I opted for an all-new
|
53
53
|
# implementation.
|
54
54
|
#
|
55
|
-
# This is the result.
|
55
|
+
# This is the result. The first release was version 0.4, which was actually my
|
56
56
|
# fourth attempt at putting together a clean, simple, universal API for RSS
|
57
57
|
# and Atom parsing. (The first three never saw public release.)
|
58
58
|
#
|
@@ -80,8 +80,8 @@
|
|
80
80
|
#
|
81
81
|
# Other features:
|
82
82
|
#
|
83
|
-
# - Optional support for RSS 1.0 Dublin Core, Syndication and Content modules
|
84
|
-
#
|
83
|
+
# - Optional support for RSS 1.0 Dublin Core, Syndication and Content modules,
|
84
|
+
# Apple iTunes Podcast elements, and Google Calendar.
|
85
85
|
#
|
86
86
|
# - Content module decodes CDATA-escaped or encoded HTML content for you.
|
87
87
|
#
|
@@ -103,9 +103,9 @@
|
|
103
103
|
# In the interests of balance, here are some key disadvantages over the
|
104
104
|
# standard library RSS support:
|
105
105
|
#
|
106
|
-
# - No support for _generating_ RSS feeds
|
107
|
-
# you're using Rails, you can use RXML; if not, you can
|
108
|
-
#
|
106
|
+
# - No support for _generating_ RSS feeds, only for parsing them. If
|
107
|
+
# you're using Rails, you can use RXML; if not, you can use rss/maker.
|
108
|
+
# My feeling is that XML generation isn't a wheel that needs reinventing.
|
109
109
|
#
|
110
110
|
# - Different API, not a drop-in replacement.
|
111
111
|
#
|
@@ -166,6 +166,8 @@
|
|
166
166
|
#
|
167
167
|
# - Knows about many more namespaces.
|
168
168
|
#
|
169
|
+
# - Can generate feeds.
|
170
|
+
#
|
169
171
|
# Cons:
|
170
172
|
# - Skimpy documentation.
|
171
173
|
#
|
@@ -206,14 +208,18 @@
|
|
206
208
|
# Here are some possible improvements:
|
207
209
|
#
|
208
210
|
# - RSS and Atom generation. Create objects, then call Syndication::FeedMaker
|
209
|
-
# to generate XML in various flavors.
|
211
|
+
# to generate XML in various flavors. This probably won't happen until an XML
|
212
|
+
# generator is picked for the Ruby standard library.
|
210
213
|
#
|
211
214
|
# - Faster date parsing. It turns out that when I asked for parsed dates in
|
212
215
|
# my test code, the profiler showed Date.parse chewing up 25% of the total
|
213
|
-
# CPU time used. A more specific date parser
|
214
|
-
#
|
215
|
-
#
|
216
|
-
#
|
216
|
+
# CPU time used. A more specific ISO8601 specific date parser could cut
|
217
|
+
# that down drastically.
|
218
|
+
#
|
219
|
+
# - Additional Google Data support. I just wanted to be able to display my
|
220
|
+
# upcoming calendar dates, but clearly there is a lot more that could be
|
221
|
+
# implemented. Unfortunately, recurring events don't seem to have a clean
|
222
|
+
# XML representation in Google's data feeds yet.
|
217
223
|
#
|
218
224
|
# == Feedback
|
219
225
|
#
|
data/examples/google.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# Atom syndication example:
|
2
|
+
# Output upcoming events from a Google calendar feed
|
3
|
+
|
4
|
+
require 'open-uri'
|
5
|
+
require 'syndication/atom'
|
6
|
+
require 'syndication/google'
|
7
|
+
|
8
|
+
MY_CALENDAR = 'http://www.google.com/calendar/feeds/j4a3sad66efnj3rm5ou2fbnsbg@group.calendar.google.com/public/full'
|
9
|
+
|
10
|
+
parser = Syndication::Atom::Parser.new
|
11
|
+
feed = nil
|
12
|
+
open(MY_CALENDAR) {|file|
|
13
|
+
text = file.read
|
14
|
+
feed = parser.parse(text)
|
15
|
+
}
|
16
|
+
t = feed.updated.strftime("%H:%I on %A %d %B")
|
17
|
+
puts "#{feed.title.txt}: #{feed.subtitle.txt} (updated #{t})"
|
18
|
+
for e in feed.entries
|
19
|
+
if e.gd_when && e.gd_when.first
|
20
|
+
t = e.gd_when.first.strftime("%d %b %y")
|
21
|
+
puts "#{t}: #{e.title.txt}"
|
22
|
+
end
|
23
|
+
end
|
data/lib/syndication/atom.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
# Provides classes for parsing Atom web syndication feeds.
|
2
2
|
# See Syndication class for documentation.
|
3
3
|
#
|
4
|
-
# Copyright � mathew <meta@pobox.com> 2005.
|
4
|
+
# Copyright � mathew <meta@pobox.com> 2005-2006.
|
5
5
|
# Licensed under the same terms as Ruby.
|
6
|
-
#
|
7
|
-
# $Header: /var/cvs/syndication/syndication/lib/syndication/atom.rb,v 1.2 2005/10/17 15:05:21 meta Exp $
|
8
6
|
|
9
7
|
require 'uri'
|
10
8
|
require 'rexml/parsers/streamparser'
|
@@ -165,7 +163,7 @@ module Syndication
|
|
165
163
|
# Catch tag end events if we're collecting embedded XHTML.
|
166
164
|
def tag_end(endtag, current)
|
167
165
|
if @tag == endtag
|
168
|
-
if @type == 'xhtml' and
|
166
|
+
if @type == 'xhtml' and !defined? @div_stripped
|
169
167
|
@xhtml.sub!(/^\s*<div>\s*/m,'')
|
170
168
|
@xhtml.sub!(/\s*<\/div>\s*$/m,'')
|
171
169
|
@div_stripped = true
|
@@ -303,7 +301,7 @@ module Syndication
|
|
303
301
|
|
304
302
|
# Add a Syndication::Category value to the feed
|
305
303
|
def category=(obj)
|
306
|
-
if
|
304
|
+
if !defined? @categories
|
307
305
|
@categories = Array.new
|
308
306
|
end
|
309
307
|
@categories.push(obj)
|
@@ -311,7 +309,7 @@ module Syndication
|
|
311
309
|
|
312
310
|
# Add a Syndication::Entry to the feed
|
313
311
|
def entry=(obj)
|
314
|
-
if
|
312
|
+
if !defined? @entries
|
315
313
|
@entries = Array.new
|
316
314
|
end
|
317
315
|
@entries.push(obj)
|
@@ -319,7 +317,7 @@ module Syndication
|
|
319
317
|
|
320
318
|
# Add a Syndication::Person contributor to the feed
|
321
319
|
def contributor=(obj)
|
322
|
-
if
|
320
|
+
if !defined? @contributors
|
323
321
|
@contributors = Array.new
|
324
322
|
end
|
325
323
|
@contributors.push(obj)
|
@@ -327,7 +325,7 @@ module Syndication
|
|
327
325
|
|
328
326
|
# Add a Syndication::Link to the feed
|
329
327
|
def link=(obj)
|
330
|
-
if
|
328
|
+
if !defined? @links
|
331
329
|
@links = Array.new
|
332
330
|
end
|
333
331
|
@links.push(obj)
|
@@ -386,7 +384,7 @@ module Syndication
|
|
386
384
|
|
387
385
|
# Add a Category object to the entry
|
388
386
|
def category=(obj)
|
389
|
-
if
|
387
|
+
if !defined? @categories
|
390
388
|
@categories = Array.new
|
391
389
|
end
|
392
390
|
@categories.push(obj)
|
@@ -394,7 +392,7 @@ module Syndication
|
|
394
392
|
|
395
393
|
# Add a Person to the entry to represent a contributor
|
396
394
|
def contributor=(obj)
|
397
|
-
if
|
395
|
+
if !defined? @contributors
|
398
396
|
@contributors = Array.new
|
399
397
|
end
|
400
398
|
@contributors.push(obj)
|
@@ -402,7 +400,7 @@ module Syndication
|
|
402
400
|
|
403
401
|
# Add a Link to the entry
|
404
402
|
def link=(obj)
|
405
|
-
if
|
403
|
+
if !defined? @links
|
406
404
|
@links = Array.new
|
407
405
|
end
|
408
406
|
@links.push(obj)
|
data/lib/syndication/common.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# The file common.rb contains code common to both Atom and RSS parsing.
|
2
2
|
#
|
3
|
-
# Copyright � mathew <meta@pobox.com>
|
3
|
+
# Copyright � mathew <meta@pobox.com> 2006.
|
4
4
|
# Licensed under the same terms as Ruby.
|
5
5
|
#
|
6
6
|
# $Header: /var/cvs/syndication/syndication/lib/syndication/common.rb,v 1.4 2005/10/23 22:51:17 meta Exp $
|
@@ -138,7 +138,8 @@ module Syndication
|
|
138
138
|
'http://www.w3.org/1999/02/22-rdf-syntax-ns#' => 'rdf',
|
139
139
|
'http://purl.org/rss/1.0/modules/content/' => 'content',
|
140
140
|
'http://www.itunes.com/DTDs/Podcast-1.0.dtd' => 'itunes',
|
141
|
-
'http://www.w3.org/1999/xhtml' => 'xhtml'
|
141
|
+
'http://www.w3.org/1999/xhtml' => 'xhtml',
|
142
|
+
'http://schemas.google.com/g/2005' => 'gd'
|
142
143
|
}
|
143
144
|
|
144
145
|
# Create a new AbstractParser. The optional argument consists of text to
|
data/lib/syndication/content.rb
CHANGED
@@ -0,0 +1,58 @@
|
|
1
|
+
# Copyright � mathew <meta@pobox.com> 2006.
|
2
|
+
# Licensed under the same terms as Ruby.
|
3
|
+
|
4
|
+
module Syndication
|
5
|
+
|
6
|
+
# Mixin for Google Data in Atom feeds.
|
7
|
+
#
|
8
|
+
# If you require 'syndication/google' these methods are added to the
|
9
|
+
# Syndication::Atom::Entry and Syndication::Atom::Feed classes.
|
10
|
+
#
|
11
|
+
# See http://code.google.com/apis/gdata/calendar.html for more information
|
12
|
+
# on Google Calendar Data APIs.
|
13
|
+
#
|
14
|
+
# See examples/google.rb for a simple example.
|
15
|
+
#
|
16
|
+
module Google
|
17
|
+
# Where the event is to occur
|
18
|
+
attr_reader :gd_where
|
19
|
+
|
20
|
+
def gd_where=(attrs)
|
21
|
+
if attrs['valueString']
|
22
|
+
@gd_where = attrs['valueString']
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def gd_when=(attrs)
|
27
|
+
if attrs['startTime']
|
28
|
+
@starttime = attrs['startTime']
|
29
|
+
end
|
30
|
+
if attrs['endTime']
|
31
|
+
@endtime = attrs['endTime']
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# When the event is to occur, as an Array of [start DateTime, end DateTime].
|
36
|
+
def gd_when
|
37
|
+
s = e = nil
|
38
|
+
if @starttime
|
39
|
+
s = DateTime.parse(@starttime)
|
40
|
+
end
|
41
|
+
if @endtime
|
42
|
+
e = DateTime.parse(@endtime)
|
43
|
+
end
|
44
|
+
return [s,e]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
module Atom
|
49
|
+
class Entry
|
50
|
+
include Google
|
51
|
+
end
|
52
|
+
|
53
|
+
class Feed
|
54
|
+
include Google
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
data/lib/syndication/podcast.rb
CHANGED
data/lib/syndication/rss.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
# This module provides classes and methods for parsing RSS web syndication
|
2
2
|
# feeds.
|
3
3
|
#
|
4
|
-
# Copyright � mathew <meta@pobox.com> 2005.
|
4
|
+
# Copyright � mathew <meta@pobox.com> 2005-2006.
|
5
5
|
# Licensed under the same terms as Ruby.
|
6
|
-
#
|
7
|
-
# $Header: /var/cvs/syndication/syndication/lib/syndication/rss.rb,v 1.2 2005/10/17 15:05:21 meta Exp $
|
8
6
|
|
9
7
|
require 'uri'
|
10
8
|
require 'rexml/parsers/streamparser'
|
@@ -20,7 +18,7 @@ module Syndication
|
|
20
18
|
# <category> elements
|
21
19
|
def store_category(cat)
|
22
20
|
if cat.kind_of?(String)
|
23
|
-
if
|
21
|
+
if !defined? @category
|
24
22
|
@category = Array.new
|
25
23
|
end
|
26
24
|
@category << cat
|
@@ -189,7 +187,7 @@ module RSS
|
|
189
187
|
# that; we just make the Channel recognize it and store the values.
|
190
188
|
def hour=(hr)
|
191
189
|
if hr.kind_of?(String)
|
192
|
-
if
|
190
|
+
if !defined? @skiphours
|
193
191
|
@skiphours = Array.new
|
194
192
|
end
|
195
193
|
h = hr.to_i
|
@@ -203,7 +201,7 @@ module RSS
|
|
203
201
|
# that; we just make the Channel recognize it and store the values.
|
204
202
|
def day=(dayname)
|
205
203
|
if dayname.kind_of?(String)
|
206
|
-
if
|
204
|
+
if !defined? @skipdays
|
207
205
|
@skipdays = Array.new
|
208
206
|
end
|
209
207
|
@skipdays << dayname
|
@@ -279,9 +277,15 @@ module RSS
|
|
279
277
|
# The image for the feed, as a Syndication::Image object.
|
280
278
|
attr_accessor :image
|
281
279
|
|
280
|
+
def initialize(parent, tag = nil, attrs = nil)
|
281
|
+
# Explicitly initialize to nil to avoid warnings
|
282
|
+
@items = @category = @skiphours = @skipdays = nil
|
283
|
+
super
|
284
|
+
end
|
285
|
+
|
282
286
|
# Add an item to the feed.
|
283
287
|
def item=(obj)
|
284
|
-
if
|
288
|
+
if (!defined? @items) || (@items == nil)
|
285
289
|
@items = Array.new
|
286
290
|
end
|
287
291
|
@items.push(obj)
|
data/lib/syndication/tagsoup.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
|
-
# Copyright � mathew <meta@pobox.com> 2005.
|
1
|
+
# Copyright � mathew <meta@pobox.com> 2005-2006.
|
2
2
|
# Licensed under the same terms as Ruby.
|
3
|
-
#
|
4
|
-
# $Header: /var/cvs/syndication/syndication/lib/syndication/tagsoup.rb,v 1.2 2005/10/17 15:05:21 meta Exp $
|
5
3
|
|
6
4
|
require 'cgi'
|
7
5
|
|
@@ -37,6 +35,10 @@ module Syndication
|
|
37
35
|
end
|
38
36
|
}
|
39
37
|
listener.tag_start(tag, pairs)
|
38
|
+
# Tags with end tag build in, XML style
|
39
|
+
if thing[-2,1] == '/'
|
40
|
+
listener.tag_end(tag)
|
41
|
+
end
|
40
42
|
end
|
41
43
|
else
|
42
44
|
# It's text
|
data/rakefile
CHANGED
@@ -2,9 +2,10 @@
|
|
2
2
|
require 'rake/rdoctask'
|
3
3
|
require 'rake/packagetask'
|
4
4
|
require 'rake/gempackagetask'
|
5
|
+
require 'rake/testtask'
|
5
6
|
require 'rubygems'
|
6
7
|
|
7
|
-
PKG_VERSION = "0.
|
8
|
+
PKG_VERSION = "0.6"
|
8
9
|
|
9
10
|
desc "Create HTML documentation from RDOC"
|
10
11
|
Rake::RDocTask.new do |rd|
|
@@ -34,7 +35,7 @@ spec = Gem::Specification.new do |s|
|
|
34
35
|
item.include?("CVS") || item.include?("html")
|
35
36
|
end
|
36
37
|
s.require_path = "lib"
|
37
|
-
s.test_files = ["test/atomtest.rb", "test/rsstest.rb",
|
38
|
+
s.test_files = ["test/atomtest.rb", "test/rsstest.rb", "test/google.rb",
|
38
39
|
"test/tagsouptest.rb"]
|
39
40
|
s.has_rdoc = true
|
40
41
|
s.extra_rdoc_files = ["README", "IMPLEMENTATION", "CHANGES", "DEVELOPER"]
|
@@ -46,6 +47,13 @@ Rake::GemPackageTask.new(spec) do |pkg|
|
|
46
47
|
pkg.need_tar = true
|
47
48
|
end
|
48
49
|
|
50
|
+
desc "Run unit tests"
|
51
|
+
Rake::TestTask.new("test") { |t|
|
52
|
+
t.pattern = 'test/*.rb'
|
53
|
+
t.verbose = true
|
54
|
+
t.warning = true
|
55
|
+
}
|
56
|
+
|
49
57
|
task :default do
|
50
58
|
puts "This is a pure Ruby library, no compilation is required."
|
51
59
|
puts "Try rake --tasks"
|
data/test/atomtest.rb
CHANGED
@@ -13,7 +13,7 @@ module Syndication
|
|
13
13
|
|
14
14
|
# A set of minimal assertions that can be applied to every well-formed parsed
|
15
15
|
# feed.
|
16
|
-
def
|
16
|
+
def baseline_atom_assertions(feed)
|
17
17
|
assert_not_nil(feed, 'Parser returned nil')
|
18
18
|
assert_kind_of(Syndication::Atom::Feed, feed)
|
19
19
|
assert_not_nil(feed.title, 'Feed#title was nil')
|
@@ -48,7 +48,7 @@ module Syndication
|
|
48
48
|
</feed>
|
49
49
|
EOF
|
50
50
|
f = Syndication::Atom::Parser.new.parse(xml)
|
51
|
-
|
51
|
+
baseline_atom_assertions(f)
|
52
52
|
assert(f.title.txt == 'One good turn usually gets most of the blanket.')
|
53
53
|
assert(f.updated.strftime('%F %T') == '2005-08-20 21:14:38')
|
54
54
|
assert(f.entries.length == 1, 'Wrong number of entries in feed')
|
@@ -152,7 +152,7 @@ module Syndication
|
|
152
152
|
</feed>
|
153
153
|
EOF
|
154
154
|
f = Syndication::Atom::Parser.new.parse(xml)
|
155
|
-
|
155
|
+
baseline_atom_assertions(f)
|
156
156
|
assert(f.categories.length == 2)
|
157
157
|
assert(f.contributors.length == 2)
|
158
158
|
assert(f.contributors[0].name == 'Phil Space', "Feed#contributors name didn't match")
|
data/test/google.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
# Copyright © mathew <meta@pobox.com> 2005.
|
2
|
+
# Licensed under the same terms as Ruby.
|
3
|
+
|
4
|
+
require 'syndication/atom'
|
5
|
+
require 'syndication/google'
|
6
|
+
require 'test/unit'
|
7
|
+
require 'pp'
|
8
|
+
|
9
|
+
module Syndication
|
10
|
+
|
11
|
+
# This class contains the unit tests for the Syndication module.
|
12
|
+
class Tests < Test::Unit::TestCase
|
13
|
+
|
14
|
+
# A set of minimal assertions that can be applied to every well-formed parsed
|
15
|
+
# feed.
|
16
|
+
def baseline_assertions(feed)
|
17
|
+
assert_not_nil(feed, 'Parser returned nil')
|
18
|
+
assert_kind_of(Syndication::Atom::Feed, feed)
|
19
|
+
assert_not_nil(feed.title, 'Feed#title was nil')
|
20
|
+
assert_not_nil(feed.id, 'Feed#id was nil')
|
21
|
+
assert_not_nil(feed.updated, 'Feed#updated was nil')
|
22
|
+
assert_kind_of(DateTime, feed.updated)
|
23
|
+
assert(feed.entries.length > 0, 'No entries in feed')
|
24
|
+
for entry in feed.entries
|
25
|
+
assert_not_nil(entry.title, 'Entry#title was nil')
|
26
|
+
assert_not_nil(entry.id, 'Entry#id was nil')
|
27
|
+
assert(entry.links.length > 0, 'No links in entry')
|
28
|
+
assert_not_nil(entry.links[0], 'Entry#links[0] was nil')
|
29
|
+
assert_not_nil(entry.updated, 'Entry#updated was nil')
|
30
|
+
assert_kind_of(DateTime, entry.updated)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Minimal test
|
35
|
+
def test_atom_google
|
36
|
+
xml = <<EOF
|
37
|
+
<feed xmlns='http://www.w3.org/2005/Atom'
|
38
|
+
xmlns:gd='http://schemas.google.com/g/2005'>
|
39
|
+
<id>http://www.google.com/calendar/feeds/jo@gmail.com/private-magicCookie/full</id>
|
40
|
+
<updated>2006-03-29T07:35:59.000Z</updated>
|
41
|
+
<title type='text'>Jo March</title>
|
42
|
+
<subtitle type='text'>This is my main calendar.</subtitle>
|
43
|
+
<link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml'
|
44
|
+
href='http://www.google.com/calendar/feeds/jo@gmail.com/private-magicCookie/full'></link>
|
45
|
+
<link rel='self' type='application/atom+xml'
|
46
|
+
href='http://www.google.com/calendar/feeds/jo@gmail.com/private-magicCookie/full'></link>
|
47
|
+
<author>
|
48
|
+
<name>Jo March</name>
|
49
|
+
<email>jo@gmail.com</email>
|
50
|
+
</author>
|
51
|
+
<generator version='1.0' uri='http://www.google.com/calendar/'>CL2</generator>
|
52
|
+
<gd:where valueString='California'></gd:where>
|
53
|
+
<entry>
|
54
|
+
<id>http://www.google.com/calendar/feeds/jo@gmail.com/private-magicCookie/full/entryID</id>
|
55
|
+
<published>2006-03-30T22:00:00.000Z</published>
|
56
|
+
<updated>2006-03-28T05:47:31.000Z</updated>
|
57
|
+
<category scheme='http://schemas.google.com/g/2005#kind'
|
58
|
+
term='http://schemas.google.com/g/2005#event'></category>
|
59
|
+
<title type='text'>Lunch with Darcy</title>
|
60
|
+
<content type='text'>Lunch to discuss future plans.</content>
|
61
|
+
<link rel='alternate' type='text/html'
|
62
|
+
href='http://www.google.com/calendar/event?eid=aTJxcnNqbW9tcTJnaTE5cnMybmEwaW04bXMgbWFyY2guam9AZ21haWwuY29t'
|
63
|
+
title='alternate'></link>
|
64
|
+
<link rel='self' type='application/atom+xml'
|
65
|
+
href='http://www.google.com/calendar/feeds/jo@gmail.com/private-magicCookie/full/entryID'></link>
|
66
|
+
<author>
|
67
|
+
<name>Jo March</name>
|
68
|
+
<email>jo@gmail.com</email>
|
69
|
+
</author>
|
70
|
+
<gd:transparency
|
71
|
+
value='http://schemas.google.com/g/2005#event.opaque'></gd:transparency>
|
72
|
+
<gd:eventStatus
|
73
|
+
value='http://schemas.google.com/g/2005#event.confirmed'></gd:eventStatus>
|
74
|
+
<gd:comments>
|
75
|
+
<gd:feedLink
|
76
|
+
href='http://www.google.com/calendar/feeds/jo@gmail.com/private-magicCookie/full/entryID/comments/'></gd:feedLink>
|
77
|
+
</gd:comments>
|
78
|
+
<gd:when startTime='2006-03-30T22:00:00.000Z'
|
79
|
+
endTime='2006-03-30T23:00:00.000Z'></gd:when>
|
80
|
+
<gd:where></gd:where>
|
81
|
+
</entry>
|
82
|
+
</feed>
|
83
|
+
EOF
|
84
|
+
f = Syndication::Atom::Parser.new.parse(xml)
|
85
|
+
baseline_assertions(f)
|
86
|
+
entry = f.entries.first
|
87
|
+
assert(entry.gd_when.to_s == "2006-03-30T22:00:00Z2006-03-30T23:00:00Z")
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
data/test/rsstest.rb
CHANGED
@@ -16,7 +16,7 @@ class Tests < Test::Unit::TestCase
|
|
16
16
|
|
17
17
|
# A set of minimal assertions that can be applied to every well-formed parsed
|
18
18
|
# feed.
|
19
|
-
def
|
19
|
+
def baseline_rss_assertions(feed)
|
20
20
|
assert_not_nil(feed)
|
21
21
|
assert_kind_of(Syndication::RSS::Feed, feed)
|
22
22
|
loi = feed.items
|
@@ -42,7 +42,7 @@ class Tests < Test::Unit::TestCase
|
|
42
42
|
</rss>
|
43
43
|
EOF
|
44
44
|
f = Syndication::RSS::Parser.new.parse(xml)
|
45
|
-
|
45
|
+
baseline_rss_assertions(f)
|
46
46
|
assert(f.channel.title == 'I like coffee')
|
47
47
|
assert(f.channel.link == 'http://www.coffeegeek.com/')
|
48
48
|
assert(f.channel.description == 'Hand over the latte & nobody gets hurt.')
|
@@ -75,7 +75,7 @@ class Tests < Test::Unit::TestCase
|
|
75
75
|
</rdf:RDF>
|
76
76
|
EOF
|
77
77
|
f = Syndication::RSS::Parser.new.parse(xml)
|
78
|
-
|
78
|
+
baseline_rss_assertions(f)
|
79
79
|
assert(f.channel.title == 'OtterNet')
|
80
80
|
assert(f.channel.link == 'http://www.otternet.com/')
|
81
81
|
assert(f.channel.description == 'Otternet has pages & pages of information about otters.')
|
@@ -156,7 +156,7 @@ class Tests < Test::Unit::TestCase
|
|
156
156
|
</rss>
|
157
157
|
EOF
|
158
158
|
f = Syndication::RSS::Parser.new.parse(xml)
|
159
|
-
|
159
|
+
baseline_rss_assertions(f)
|
160
160
|
for elem in %w(title link description language copyright managingeditor webmaster pubdate lastbuilddate category generator docs cloud ttl textinput rating skiphours skipdays)
|
161
161
|
assert_not_nil(f.channel.send(elem), "feed.channel.#{elem} is nil, it shouldn't be")
|
162
162
|
assert(f.channel.send(elem).to_s.length > 0)
|
@@ -232,7 +232,7 @@ class Tests < Test::Unit::TestCase
|
|
232
232
|
</rdf:RDF>
|
233
233
|
EOF
|
234
234
|
f = Syndication::RSS::Parser.new.parse(xml)
|
235
|
-
|
235
|
+
baseline_rss_assertions(f)
|
236
236
|
for elem in %w(title link description textinput)
|
237
237
|
assert_not_nil(f.channel.send(elem), "feed.channel.#{elem} is nil, it shouldn't be")
|
238
238
|
assert(f.channel.send(elem).to_s.length > 0)
|
@@ -283,7 +283,7 @@ class Tests < Test::Unit::TestCase
|
|
283
283
|
</rdf:RDF>
|
284
284
|
EOF
|
285
285
|
f = Syndication::RSS::Parser.new.parse(xml)
|
286
|
-
|
286
|
+
baseline_rss_assertions(f)
|
287
287
|
il = f.items
|
288
288
|
assert(il.length == 2)
|
289
289
|
i1 = il.first
|
data/test/tagsouptest.rb
CHANGED
@@ -6,7 +6,6 @@
|
|
6
6
|
require 'syndication/tagsoup'
|
7
7
|
require 'test/unit'
|
8
8
|
require 'rexml/document'
|
9
|
-
require 'pp'
|
10
9
|
|
11
10
|
module Syndication
|
12
11
|
|
@@ -66,17 +65,17 @@ three<fourc™
|
|
66
65
|
@events = Array.new
|
67
66
|
REXML::Document.parse_stream(xml, self)
|
68
67
|
@rexml = @events
|
69
|
-
puts "REXML\n-----"
|
70
|
-
pp @rexml
|
71
|
-
puts "\nTAGSOUP\n-------"
|
72
|
-
pp @tagsoup
|
68
|
+
#puts "REXML\n-----"
|
69
|
+
#pp @rexml
|
70
|
+
#puts "\nTAGSOUP\n-------"
|
71
|
+
#pp @tagsoup
|
73
72
|
errs = false
|
74
73
|
for tsevt in @tagsoup
|
75
74
|
rxevt = @rexml.shift
|
76
75
|
if rxevt
|
77
76
|
if tsevt.to_s != rxevt.to_s
|
78
77
|
errs = true
|
79
|
-
puts "TagSoup: [#{tsevt}]\nREXML: [#{rxevt}]"
|
78
|
+
#puts "TagSoup: [#{tsevt}]\nREXML: [#{rxevt}]"
|
80
79
|
end
|
81
80
|
end
|
82
81
|
end
|
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
!ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
rubygems_version: 0.8.11
|
3
3
|
specification_version: 1
|
4
4
|
name: syndication
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date:
|
6
|
+
version: "0.6"
|
7
|
+
date: 2006-06-18 00:00:00 -05:00
|
8
8
|
summary: A web syndication parser for Atom and RSS with a uniform API
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -34,14 +34,17 @@ files:
|
|
34
34
|
- lib/syndication/podcast.rb
|
35
35
|
- lib/syndication/content.rb
|
36
36
|
- lib/syndication/tagsoup.rb
|
37
|
+
- lib/syndication/google.rb
|
37
38
|
- lib/syndication/rss.rb
|
38
39
|
- lib/syndication/syndication.rb
|
39
40
|
- lib/syndication/atom.rb
|
40
41
|
- test/tagsouptest.rb
|
42
|
+
- test/google.rb
|
41
43
|
- test/rsstest.rb
|
42
44
|
- test/atomtest.rb
|
43
45
|
- examples/apple.rb
|
44
46
|
- examples/yahoo.rb
|
47
|
+
- examples/google.rb
|
45
48
|
- rakefile
|
46
49
|
- README
|
47
50
|
- IMPLEMENTATION
|
@@ -50,6 +53,7 @@ files:
|
|
50
53
|
test_files:
|
51
54
|
- test/atomtest.rb
|
52
55
|
- test/rsstest.rb
|
56
|
+
- test/google.rb
|
53
57
|
- test/tagsouptest.rb
|
54
58
|
rdoc_options: []
|
55
59
|
|