feed_me 0.6.2 → 0.7.0

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.
@@ -68,7 +68,7 @@ private
68
68
  return nil unless xml
69
69
  association = self.class.properties[name]
70
70
 
71
- nodes = xml.xpath("./#{association[:path]}")
71
+ nodes = xml.xpath(association[:path].to_s)
72
72
  parser = FeedMe.const_get(association[:use].to_s)
73
73
 
74
74
  nodes.map do |node|
@@ -80,7 +80,7 @@ private
80
80
  return nil unless xml
81
81
  association = self.class.properties[name]
82
82
 
83
- node = xml.xpath("./#{association[:path]}").first
83
+ node = xml.xpath(association[:path].to_s).first
84
84
  parser = FeedMe.const_get(association[:use].to_s)
85
85
 
86
86
  parser.new(self, node)
@@ -90,11 +90,11 @@ private
90
90
  return nil unless xml
91
91
  property = self.class.properties[name]
92
92
 
93
- values = xml.xpath("./#{property[:path]}").map do |node|
93
+ values = xml.xpath(property[:path].to_s).map do |node|
94
94
  result = extract_result(node, property[:from])
95
95
  cast_result(result, property[:as])
96
96
  end
97
-
97
+
98
98
  case property[:cardinality]
99
99
  when :many
100
100
  return values
@@ -113,9 +113,9 @@ private
113
113
 
114
114
  def cast_result(result, as)
115
115
  if as == :time
116
- Time.parse(result)
116
+ Time.parse(result).utc
117
117
  else
118
- result
118
+ result.to_s.strip
119
119
  end
120
120
  end
121
121
 
@@ -26,12 +26,15 @@ module FeedMe
26
26
  # then returns a parser object
27
27
  def parse(feed)
28
28
  document = Nokogiri::XML(feed)
29
- if root = document.root
29
+ if root = document.root
30
30
  root.add_namespace_definition('atom', 'http://www.w3.org/2005/Atom')
31
+ root.add_namespace_definition('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#')
32
+ root.add_namespace_definition('rss1', 'http://purl.org/rss/1.0/')
33
+ root.add_namespace_definition('dc', 'http://purl.org/dc/elements/1.1/')
31
34
  parsers.each do |parser|
32
35
  node = root.xpath(parser.root_node).first
33
36
  if node
34
- return parser.new(node, document.encoding)
37
+ return parser.new(node)
35
38
  end
36
39
  end
37
40
  end
@@ -41,13 +44,10 @@ module FeedMe
41
44
 
42
45
  end # class << self
43
46
 
44
- def initialize(xml, encoding)
47
+ def initialize(xml)
45
48
  @xml = xml
46
- @encoding = encoding
47
49
  end
48
50
 
49
- attr_reader :encoding
50
-
51
51
  end
52
52
 
53
53
  class AtomFeedParser < FeedParser
@@ -81,4 +81,21 @@ module FeedMe
81
81
 
82
82
  has_one :author, :path => 'managingEditor', :use => :Rss2PersonParser
83
83
  end
84
+
85
+ class Rss1FeedParser < FeedParser
86
+ root_node "//rdf:RDF"
87
+
88
+ property :title, :path => 'rss1:channel/rss1:title'
89
+ property :description, :path => 'rss1:channel/rss1:description'
90
+ property :feed_id, :path => :undefined
91
+ property :updated_at, :path => 'rss1:channel/dc:date', :as => :time
92
+ property :url, :path => 'rss1:channel/rss1:link'
93
+ property :href, :path => 'rss1:channel/@rdf:about'
94
+ property :generator, :path => :undefined
95
+
96
+ has_many :entries, :path => 'rss1:channel/rss1:items/rdf:Seq/rdf:li', :use => :Rss1ItemParser
97
+
98
+ has_one :author, :path => 'rss1:channel', :use => :Rss1PersonParser
99
+
100
+ end
84
101
  end
@@ -22,4 +22,19 @@ module FeedMe
22
22
 
23
23
  has_one :author, :use => :Rss2PersonParser
24
24
  end
25
+
26
+ class Rss1ItemParser < ItemParser
27
+ property :title, :path => 'rss1:title'
28
+ property :updated_at, :path => 'dc:date', :as => :time
29
+ property :item_id, :path => '@rdf:about'
30
+ property :url, :path => 'rss1:link'
31
+ property :content, :path => 'rss1:description'
32
+
33
+ has_one :author, :path => '.', :use => :Rss1PersonParser
34
+
35
+ def xml
36
+ resource = super.xpath('@rdf:resource').to_s
37
+ super.xpath("//rss1:item[@rdf:about='#{resource}']").first
38
+ end
39
+ end
25
40
  end
@@ -20,4 +20,10 @@ module FeedMe
20
20
  end
21
21
  end
22
22
 
23
+ class Rss1PersonParser < PersonParser
24
+ property :email, :path => :undefined
25
+ property :name, :path => 'dc:creator'
26
+ property :uri, :path => :undefined
27
+ end
28
+
23
29
  end
@@ -31,6 +31,7 @@ describe FeedMe::FeedParser do
31
31
  before :each do
32
32
  @atom = FeedMe::FeedParser.parse(open(fixture('welformed.atom')).read)
33
33
  @rss2 = FeedMe::FeedParser.parse(open(fixture('welformed.rss2')).read)
34
+ @rss1 = FeedMe::FeedParser.parse(open(fixture('welformed.rss1')).read)
34
35
  end
35
36
 
36
37
  it "should be an atom parser for an atom feed" do
@@ -55,16 +56,6 @@ describe FeedMe::FeedParser do
55
56
  it_should_behave_like "all parsing methods"
56
57
  end
57
58
 
58
- describe '#encoding' do
59
- it "should return the encoding for an atom feed" do
60
- @atom.encoding.should == 'UTF-8'
61
- end
62
-
63
- it "should return the encoding for an atom feed" do
64
- @rss2.encoding.should == 'iso-8859-1'
65
- end
66
- end
67
-
68
59
  describe '#title' do
69
60
  it "should be valid for an atom feed" do
70
61
  @atom.title.should == "Test feed"
@@ -73,6 +64,10 @@ describe FeedMe::FeedParser do
73
64
  it "should be valid for an rss2 feed" do
74
65
  @rss2.title.should == "Lift Off News"
75
66
  end
67
+
68
+ it "should be valid for an rss1 feed" do
69
+ @rss1.title.should == "XML.com"
70
+ end
76
71
  end
77
72
 
78
73
  describe '#description' do
@@ -83,6 +78,10 @@ describe FeedMe::FeedParser do
83
78
  it "should be valid for an rss2 feed" do
84
79
  @rss2.description.should == "Liftoff to Space Exploration."
85
80
  end
81
+
82
+ it "should be valid for an rss1 feed" do
83
+ @rss1.description.should == "XML.com features a rich mix of information and services"
84
+ end
86
85
  end
87
86
 
88
87
  describe '#feed_id' do
@@ -93,6 +92,10 @@ describe FeedMe::FeedParser do
93
92
  it "should be nil for an rss2 feed" do
94
93
  @rss2.feed_id.should be_nil
95
94
  end
95
+
96
+ it "should be nil for an rss1 feed" do
97
+ @rss1.feed_id.should be_nil
98
+ end
96
99
  end
97
100
 
98
101
  describe '#updated_at' do
@@ -103,6 +106,10 @@ describe FeedMe::FeedParser do
103
106
  it "should be valid for an rss2 feed" do
104
107
  @rss2.updated_at.should == Time.utc(2003, 6, 10, 9, 41, 1)
105
108
  end
109
+
110
+ it "should be taken from dublin core time for an rss1 feed" do
111
+ @rss1.updated_at.should == Time.utc(2010, 6, 3, 14, 56, 42)
112
+ end
106
113
  end
107
114
 
108
115
  describe '#href' do
@@ -110,9 +117,13 @@ describe FeedMe::FeedParser do
110
117
  @atom.href.should == "http://imaginary.host/posts.atom"
111
118
  end
112
119
 
113
- it "should be nil for an atom feed" do
120
+ it "should be nil for an rss2 feed" do
114
121
  @rss2.href.should be_nil
115
122
  end
123
+
124
+ it "should be valid for an rss1 feed" do
125
+ @rss1.href.should == "http://www.xml.com/xml/news.rss"
126
+ end
116
127
  end
117
128
 
118
129
  describe '#url' do
@@ -123,6 +134,10 @@ describe FeedMe::FeedParser do
123
134
  it "should be valid for an rss2 feed" do
124
135
  @rss2.url.should == "http://liftoff.msfc.nasa.gov/"
125
136
  end
137
+
138
+ it "should be valid for an rss1 feed" do
139
+ @rss1.url.should == "http://xml.com/pub"
140
+ end
126
141
  end
127
142
 
128
143
  describe '#generator' do
@@ -133,6 +148,10 @@ describe FeedMe::FeedParser do
133
148
  it "should be valid for an rss2 feed" do
134
149
  @rss2.generator.should == "Weblog Editor 2.0"
135
150
  end
151
+
152
+ it "should be nil for an rss1 feed" do
153
+ @rss1.generator.should be_nil
154
+ end
136
155
  end
137
156
 
138
157
  describe '#author.name' do
@@ -143,6 +162,10 @@ describe FeedMe::FeedParser do
143
162
  it "should be valid for an rss2 feed" do
144
163
  @rss2.author.name.should == "Mary Jo"
145
164
  end
165
+
166
+ it "should be taken from dublin core for an rss1 feed" do
167
+ @rss1.author.name.should == "Foopaq (mailto:support@foopaq.se)"
168
+ end
146
169
  end
147
170
 
148
171
  describe '#author.email' do
@@ -153,6 +176,10 @@ describe FeedMe::FeedParser do
153
176
  it "should be valid for an rss2 feed" do
154
177
  @rss2.author.email.should == "editor@example.com"
155
178
  end
179
+
180
+ it "should be nil for an rss1 feed" do
181
+ @rss1.author.email.should be_nil
182
+ end
156
183
  end
157
184
 
158
185
  describe '#author.uri' do
@@ -163,6 +190,10 @@ describe FeedMe::FeedParser do
163
190
  it "should be nil for an rss2 feed" do
164
191
  @rss2.author.uri.should be_nil
165
192
  end
193
+
194
+ it "should be nil for an rss1 feed" do
195
+ @rss1.author.uri.should be_nil
196
+ end
166
197
  end
167
198
 
168
199
  describe '#entries' do
@@ -193,6 +224,20 @@ describe FeedMe::FeedParser do
193
224
  @rss2.entries.first.item_id.should == "http://liftoff.msfc.nasa.gov/2003/06/03.html#item573"
194
225
  end
195
226
 
227
+ it "should return an array of entries for an rss1 feed" do
228
+ @rss1.entries.should be_an_instance_of(Array)
229
+ end
230
+
231
+ it "should have the correct length for an rss1 feed" do
232
+ @rss1.should have(3).entries
233
+ end
234
+
235
+ it "should return items that are properly parsed for an rss1 feed" do
236
+ @rss1.entries.first.title.should == "Processing Inclusions with XSLT"
237
+ @rss1.entries.first.url.should == "http://google.com/foobar"
238
+ @rss1.entries.first.item_id.should == "http://xml.com/pub/2000/08/09/xslt/xslt.html"
239
+ end
240
+
196
241
  it "should allow items to be read more than once" do
197
242
  item = @rss2.entries.first
198
243
  item.item_id.should == "http://liftoff.msfc.nasa.gov/2003/06/03.html#item573"
@@ -285,6 +330,49 @@ describe FeedMe::FeedParser do
285
330
  author.email.should == "editor@example.com"
286
331
  author.uri.should be_nil
287
332
  end
333
+
334
+ it "should serialize the title of an rss1 feed" do
335
+ @rss1.to_hash[:title].should == "XML.com"
336
+ end
337
+
338
+ it "should serialize the description of an rss1 feed" do
339
+ @rss1.to_hash[:description].should == "XML.com features a rich mix of information and services"
340
+ end
341
+
342
+ it "should serialize the feed_id of an rss1 feed" do
343
+ @rss1.to_hash[:feed_id].should be_nil
344
+ end
345
+
346
+ it "should serialize the updated_at time of an rss1 feed" do
347
+ @rss1.to_hash[:updated_at].should == Time.utc(2010, 6, 3, 14, 56, 42)
348
+ end
349
+
350
+ it "should serialize the href of an rss1 feed" do
351
+ @rss1.to_hash[:href].should == "http://www.xml.com/xml/news.rss"
352
+ end
353
+
354
+ it "should serialize the url of an rss1 feed" do
355
+ @rss1.to_hash[:url].should == "http://xml.com/pub"
356
+ end
357
+
358
+ it "should serialize the generator of an rss1 feed" do
359
+ @rss1.to_hash[:generator].should be_nil
360
+ end
361
+
362
+ it "should serialize the entries of an rss1 feed" do
363
+ @rss1.to_hash[:entries].should be_an_instance_of(Array)
364
+ @rss1.to_hash[:entries].first.title.should == "Processing Inclusions with XSLT"
365
+ @rss1.to_hash[:entries].first.url.should == "http://google.com/foobar"
366
+ end
367
+
368
+ it "should serialize the author of an rss1 feed" do
369
+
370
+ author = @rss1.to_hash[:author]
371
+
372
+ author.name.should == "Foopaq (mailto:support@foopaq.se)"
373
+ author.email.should be_nil
374
+ author.uri.should be_nil
375
+ end
288
376
  end
289
377
 
290
378
  end
@@ -9,6 +9,8 @@ describe FeedMe::ItemParser do
9
9
  @atom = @atom_feed.entries.first
10
10
  @rss2_feed = FeedMe::FeedParser.open(fixture('welformed.rss2'))
11
11
  @rss2 = @rss2_feed.entries.first
12
+ @rss1_feed = FeedMe::FeedParser.open(fixture('welformed.rss1'))
13
+ @rss1 = @rss1_feed.entries.first
12
14
  end
13
15
 
14
16
  describe '#to_hash' do
@@ -25,6 +27,10 @@ describe FeedMe::ItemParser do
25
27
  it "should be valid for an rss2 feed" do
26
28
  @rss2.title.should == "Star City"
27
29
  end
30
+
31
+ it "should be valid for an rss1 feed" do
32
+ @rss1.title.should == "Processing Inclusions with XSLT"
33
+ end
28
34
  end
29
35
 
30
36
  describe '#content' do
@@ -35,6 +41,10 @@ describe FeedMe::ItemParser do
35
41
  it "should be valid for an rss2 feed" do
36
42
  @rss2.content.should == "This is content"
37
43
  end
44
+
45
+ it "should be valid for an rss1 feed" do
46
+ @rss1.content.should == "Processing document inclusions with general XML tools can be problematic."
47
+ end
38
48
  end
39
49
 
40
50
  describe '#item_id' do
@@ -45,6 +55,10 @@ describe FeedMe::ItemParser do
45
55
  it "should be valid for an rss2 feed" do
46
56
  @rss2.item_id.should == "http://liftoff.msfc.nasa.gov/2003/06/03.html#item573"
47
57
  end
58
+
59
+ it "should be valid for an rss1 feed" do
60
+ @rss1.item_id.should == "http://xml.com/pub/2000/08/09/xslt/xslt.html"
61
+ end
48
62
  end
49
63
 
50
64
  describe '#updated_at' do
@@ -55,6 +69,10 @@ describe FeedMe::ItemParser do
55
69
  it "should be valid for an rss2 feed" do
56
70
  @rss2.updated_at.should == Time.utc(2003, 6, 3, 9, 39, 21)
57
71
  end
72
+
73
+ it "should be taken from dublin core for an rss1 feed" do
74
+ @rss1.updated_at.should == Time.utc(2010, 6, 3, 10, 7, 42)
75
+ end
58
76
  end
59
77
 
60
78
  describe '#url' do
@@ -65,6 +83,10 @@ describe FeedMe::ItemParser do
65
83
  it "should be valid for an rss2 feed" do
66
84
  @rss2.url.should == "http://liftoff.msfc.nasa.gov/news/2003/news-starcity.asp"
67
85
  end
86
+
87
+ it "should be valid for an rss1 feed" do
88
+ @rss1.url.should == "http://google.com/foobar"
89
+ end
68
90
  end
69
91
 
70
92
  describe '#categories' do
@@ -81,6 +103,10 @@ describe FeedMe::ItemParser do
81
103
  it "should be valid for an rss2 feed" do
82
104
  @rss2.author.name.should == "Chuck Norris"
83
105
  end
106
+
107
+ it "should be taken from dublin core for an rss1 feed" do
108
+ @rss1.author.name.should == "akeri.se"
109
+ end
84
110
  end
85
111
 
86
112
  describe '#author.email' do
@@ -91,6 +117,10 @@ describe FeedMe::ItemParser do
91
117
  it "should be valid for an rss2 feed" do
92
118
  @rss2.author.email.should == "da_man@example.com"
93
119
  end
120
+
121
+ it "should be nil for an rss1 feed" do
122
+ @rss1.author.email.should be_nil
123
+ end
94
124
  end
95
125
 
96
126
  describe '#author.uri' do
@@ -101,6 +131,10 @@ describe FeedMe::ItemParser do
101
131
  it "should be nil for an rss2 feed" do
102
132
  @rss2.author.uri.should be_nil
103
133
  end
134
+
135
+ it "should be nil for an rss1 feed" do
136
+ @rss1.author.uri.should be_nil
137
+ end
104
138
  end
105
139
 
106
140
  describe '#to_hash' do
@@ -152,6 +186,31 @@ describe FeedMe::ItemParser do
152
186
  author.email.should == "da_man@example.com"
153
187
  author.uri.should be_nil
154
188
  end
189
+
190
+ it "should serialize the title for an rss1 feed" do
191
+ @rss1.to_hash[:title].should == "Processing Inclusions with XSLT"
192
+ end
193
+
194
+ it "should serialize the item_id for an rss1 feed" do
195
+ @rss1.to_hash[:item_id].should == "http://xml.com/pub/2000/08/09/xslt/xslt.html"
196
+ end
197
+
198
+ it "should serialize updated_at for an rss1 feed" do
199
+ @rss1.to_hash[:updated_at].should == Time.utc(2010, 6, 3, 10, 7, 42)
200
+ end
201
+
202
+ it "should serialize the url for an rss1 feed" do
203
+ @rss1.to_hash[:url].should == "http://google.com/foobar"
204
+ end
205
+
206
+ it "should serialize the author of an rss1 feed" do
207
+ author = @rss1.to_hash[:author]
208
+
209
+ author.name.should == "akeri.se"
210
+ author.email.should be_nil
211
+ author.uri.should be_nil
212
+ end
213
+
155
214
  end
156
215
 
157
216
  end
@@ -163,6 +222,8 @@ describe "Without an author", FeedMe::ItemParser do
163
222
  @atom = @atom_feed.entries[1]
164
223
  @rss2_feed = FeedMe::FeedParser.open(fixture('welformed.rss2'))
165
224
  @rss2 = @rss2_feed.entries[1]
225
+ @rss1_feed = FeedMe::FeedParser.open(fixture('welformed.rss1'))
226
+ @rss1 = @rss1_feed.entries[1]
166
227
  end
167
228
 
168
229
  describe '#author.name' do
@@ -173,6 +234,10 @@ describe "Without an author", FeedMe::ItemParser do
173
234
  it "should be valid for an rss2 feed" do
174
235
  @rss2.author.name.should be_nil
175
236
  end
237
+
238
+ it "should be valid for an rss1 feed" do
239
+ @rss1.author.name.should be_nil
240
+ end
176
241
  end
177
242
 
178
243
  end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: feed_me
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 3
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
- - 6
8
- - 2
9
- version: 0.6.2
8
+ - 7
9
+ - 0
10
+ version: 0.7.0
10
11
  platform: ruby
11
12
  authors:
12
13
  - Jonas Nicklas
@@ -15,16 +16,18 @@ autorequire: feed_me
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2010-03-22 00:00:00 +00:00
19
+ date: 2010-06-04 00:00:00 +02:00
19
20
  default_executable:
20
21
  dependencies:
21
22
  - !ruby/object:Gem::Dependency
22
23
  name: nokogiri
23
24
  prerelease: false
24
25
  requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
25
27
  requirements:
26
28
  - - ">="
27
29
  - !ruby/object:Gem::Version
30
+ hash: 3
28
31
  segments:
29
32
  - 0
30
33
  version: "0"
@@ -50,6 +53,9 @@ files:
50
53
  - lib/feed_me/feed_parser.rb
51
54
  - lib/feed_me/item_parser.rb
52
55
  - lib/feed_me/person_parser.rb
56
+ - spec/feed_parser_spec.rb
57
+ - spec/item_parser_spec.rb
58
+ - spec/spec_helper.rb
53
59
  has_rdoc: true
54
60
  homepage: http://github.com/jnicklas/feed_me
55
61
  licenses: []
@@ -60,23 +66,27 @@ rdoc_options:
60
66
  require_paths:
61
67
  - lib
62
68
  required_ruby_version: !ruby/object:Gem::Requirement
69
+ none: false
63
70
  requirements:
64
71
  - - ">="
65
72
  - !ruby/object:Gem::Version
73
+ hash: 3
66
74
  segments:
67
75
  - 0
68
76
  version: "0"
69
77
  required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
70
79
  requirements:
71
80
  - - ">="
72
81
  - !ruby/object:Gem::Version
82
+ hash: 3
73
83
  segments:
74
84
  - 0
75
85
  version: "0"
76
86
  requirements: []
77
87
 
78
88
  rubyforge_project:
79
- rubygems_version: 1.3.6
89
+ rubygems_version: 1.3.7
80
90
  signing_key:
81
91
  specification_version: 3
82
92
  summary: Nice and simple RSS and atom feed parsing built on hpricot