syndication 0.5.1 → 0.6
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 +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
|
|