rrsimple-rss 1.3.5 → 1.3.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/lib/rrsimple-rss.rb +23 -18
- data/rrsimple-rss.gemspec +1 -1
- data/test/base/base_test.rb +38 -22
- metadata +8 -10
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YTg0ZWNjZGZjZWU5NmVkODVmOWU1ZGNkM2NlYWE4ZDZkODZlZjc2Mg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
Y2I4NWY4MjlhMDM3MTE1Y2FmNjBlZTEzNTM2YTFjZmI0ZjkwMjlkOA==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZjU0YTA3YWM1M2Y0ZjM4YWIwZmUyMTliNTUyYzg3YmI5YjRiMWY5MmQ0M2Q1
|
10
|
+
Mjc1NDkyZDQ0NmY4OTIwM2NjNTRhMzA4N2VlZjRiYTcwYzIxN2Y2YTQ3M2Q3
|
11
|
+
MTdkOWNlYmUyYmFjNjI0MDg3MjdhOGU4ZjM3MjhiMDY4MGFmMTg=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZjRiMTA1YzhlZTg1NzczM2JlMjVkNjIwNjAwMmNmZTg0N2Y1MzY1MTJhODY2
|
14
|
+
NDE1MzIyODI2MGNjYWRjMzNjZDcxZjA1ZmEyOTEwODQwOTM0N2I4YzAyODhh
|
15
|
+
MTUyOGFjN2I5YTNlYWYyYjFkMDIxNzlhYWI4ODBkNTQ2ZDY3ZTY=
|
data/lib/rrsimple-rss.rb
CHANGED
@@ -2,17 +2,17 @@ require 'cgi'
|
|
2
2
|
require 'time'
|
3
3
|
|
4
4
|
class RRSimpleRSS
|
5
|
-
VERSION = "1.3.
|
6
|
-
|
5
|
+
VERSION = "1.3.6"
|
6
|
+
|
7
7
|
attr_reader :items, :source
|
8
8
|
alias :entries :items
|
9
9
|
|
10
10
|
@@feed_tags = [
|
11
11
|
:id,
|
12
12
|
:title, :subtitle, :link,
|
13
|
-
:description,
|
13
|
+
:description,
|
14
14
|
:author, :webMaster, :managingEditor, :contributor,
|
15
|
-
:pubDate, :lastBuildDate, :updated, :'dc:date',
|
15
|
+
:pubDate, :lastBuildDate, :updated, :'dc:date', :'dc:subject',
|
16
16
|
:generator, :language, :docs, :cloud,
|
17
17
|
:ttl, :skipHours, :skipDays,
|
18
18
|
:image, :logo, :icon, :rating,
|
@@ -26,7 +26,7 @@ class RRSimpleRSS
|
|
26
26
|
:title, :link, :'link+alternate', :'link+self', :'link+edit', :'link+replies',
|
27
27
|
:author, :contributor,
|
28
28
|
:description, :summary, :content, :'content:encoded', :comments,
|
29
|
-
:pubDate, :published, :updated, :expirationDate, :modified, :'dc:date',
|
29
|
+
:pubDate, :published, :updated, :expirationDate, :modified, :'dc:date', :'dc:subject',
|
30
30
|
:category, :categories, :guid,
|
31
31
|
:'trackback:ping', :'trackback:about',
|
32
32
|
:'dc:creator', :'dc:title', :'dc:subject', :'dc:rights', :'dc:publisher',
|
@@ -41,7 +41,7 @@ class RRSimpleRSS
|
|
41
41
|
@source = source.respond_to?(:read) ? source.read : source.to_s
|
42
42
|
@items = Array.new
|
43
43
|
@options = Hash.new.update(options)
|
44
|
-
|
44
|
+
|
45
45
|
parse
|
46
46
|
end
|
47
47
|
|
@@ -73,10 +73,10 @@ class RRSimpleRSS
|
|
73
73
|
|
74
74
|
def parse
|
75
75
|
raise RRSimpleRSSError, "Poorly formatted feed" unless @source =~ %r{<(channel|feed).*?>.*?</(channel|feed)>}mi
|
76
|
-
|
76
|
+
|
77
77
|
# Feed's title and link
|
78
78
|
feed_content = $1 if @source =~ %r{(.*?)<(rss:|atom:)?(item|entry).*?>.*?</(rss:|atom:)?(item|entry)>}mi
|
79
|
-
|
79
|
+
|
80
80
|
@@feed_tags.each do |tag|
|
81
81
|
if feed_content && feed_content =~ %r{<(rss:|atom:)?#{tag}(.*?)>(.*?)</(rss:|atom:)?#{tag}>}mi
|
82
82
|
nil
|
@@ -87,14 +87,14 @@ class RRSimpleRSS
|
|
87
87
|
elsif @source =~ %r{<(rss:|atom:)?#{tag}(.*?)\/\s*>}mi
|
88
88
|
nil
|
89
89
|
end
|
90
|
-
|
90
|
+
|
91
91
|
if $2 || $3
|
92
92
|
tag_cleaned = clean_tag(tag)
|
93
93
|
instance_variable_set("@#{ tag_cleaned }", clean_content(tag, $2, $3))
|
94
94
|
self.class.class_eval("attr_reader :#{ tag_cleaned }")
|
95
95
|
end
|
96
96
|
end
|
97
|
-
|
97
|
+
|
98
98
|
# RSS items' title, link, and description
|
99
99
|
@source.scan( %r{<(rss:|atom:)?(item|entry)([\s][^>]*)?>(.*?)</(rss:|atom:)?(item|entry)>}mi ) do |match|
|
100
100
|
item = Hash.new
|
@@ -103,13 +103,13 @@ class RRSimpleRSS
|
|
103
103
|
tag_data = tag.to_s.split("+")
|
104
104
|
tag = tag_data[0]
|
105
105
|
rel = tag_data[1]
|
106
|
-
|
106
|
+
|
107
107
|
if match[3] =~ %r{<(rss:|atom:)?#{tag}(.*?)rel=['"]#{rel}['"](.*?)>(.*?)</(rss:|atom:)?#{tag}>}mi
|
108
108
|
nil
|
109
109
|
elsif match[3] =~ %r{<(rss:|atom:)?#{tag}(.*?)rel=['"]#{rel}['"](.*?)/\s*>}mi
|
110
110
|
nil
|
111
111
|
end
|
112
|
-
|
112
|
+
|
113
113
|
item[clean_tag("#{tag}+#{rel}")] = clean_content(tag, $3, $4) if $3 || $4
|
114
114
|
elsif tag.to_s.include?("#")
|
115
115
|
tag_data = tag.to_s.split("#")
|
@@ -120,7 +120,7 @@ class RRSimpleRSS
|
|
120
120
|
elsif match[3] =~ %r{<(rss:|atom:)?#{tag}(.*?)#{attrib}=['"](.*?)['"](.*?)/\s*>}mi
|
121
121
|
nil
|
122
122
|
end
|
123
|
-
|
123
|
+
|
124
124
|
item[clean_tag("#{tag}_#{attrib}")] = clean_content(tag, attrib, $3) if $3
|
125
125
|
else
|
126
126
|
if match[3] =~ %r{<(rss:|atom:)?#{tag}(.*?)>(.*?)</(rss:|atom:)?#{tag}>}mi
|
@@ -128,13 +128,15 @@ class RRSimpleRSS
|
|
128
128
|
elsif match[3] =~ %r{<(rss:|atom:)?#{tag}(.*?)/\s*>}mi
|
129
129
|
nil
|
130
130
|
end
|
131
|
-
|
132
|
-
if tag == :category
|
131
|
+
|
132
|
+
if tag == :category
|
133
133
|
item[tag] = match[3].scan(%r{<(rss:|atom:)?#{tag}(.*?)>(.*?)</(rss:|atom:)?#{tag}>}mi).map {|x| category(x[2])}
|
134
|
+
elsif tag == :keywords
|
135
|
+
item[tag] = match[3].scan(%r{<(rss:|atom:)?dc:subject rdf:type="keywords"(.*?)>(.*?)<\/(rss:|atom:)?dc:subject>}mi).map {|x| x[2].gsub(";", ",") }
|
134
136
|
else
|
135
137
|
item[clean_tag(tag)] = clean_content(tag, $2, $3) if $2 || $3
|
136
138
|
end
|
137
|
-
|
139
|
+
|
138
140
|
end
|
139
141
|
end
|
140
142
|
|
@@ -157,7 +159,10 @@ class RRSimpleRSS
|
|
157
159
|
when :author, :contributor, :skipHours, :skipDays
|
158
160
|
unescape(content.gsub(/<.*?>/,''))
|
159
161
|
when :"full-text"
|
160
|
-
CGI.unescapeHTML unescape(content.gsub(/<.*?>/,'')).force_encoding("UTF-8")
|
162
|
+
CGI.unescapeHTML unescape(content.gsub(/<.*?>/,'')).force_encoding("UTF-8")
|
163
|
+
when :link
|
164
|
+
"#{attrs} " =~ /href=['"]?([^'"]*)['" ]/mi
|
165
|
+
$1
|
161
166
|
else
|
162
167
|
content.empty? && "#{attrs} " =~ /href=['"]?([^'"]*)['" ]/mi ? $1.strip : unescape(content)
|
163
168
|
end
|
@@ -166,7 +171,7 @@ class RRSimpleRSS
|
|
166
171
|
def clean_tag(tag)
|
167
172
|
tag != :'full-text' ? tag.to_s.gsub(':','_').intern : tag.to_s.gsub('-','_').intern
|
168
173
|
end
|
169
|
-
|
174
|
+
|
170
175
|
def unescape(content)
|
171
176
|
if content.respond_to?(:force_encoding) && content.force_encoding("binary") =~ /([^-_.!~*'()a-zA-Z\d;\/?:@&=+$,\[\]]%)/n then
|
172
177
|
CGI.unescape(content).gsub(/(<!\[CDATA\[|\]\]>)/,'').strip
|
data/rrsimple-rss.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "rrsimple-rss"
|
3
|
-
s.version = "1.3.
|
3
|
+
s.version = "1.3.6"
|
4
4
|
s.date = "2010-07-06"
|
5
5
|
s.summary = "A simple, flexible, extensible, and liberal RSS and Atom reader for Ruby. It is designed to be backwards compatible with the standard RSS parser, but will never do RSS generation."
|
6
6
|
s.email = "rodrigo@rrmartins.com"
|
data/test/base/base_test.rb
CHANGED
@@ -7,45 +7,48 @@ require 'pry'
|
|
7
7
|
class BaseTest < Test::Unit::TestCase
|
8
8
|
def setup
|
9
9
|
@rss_prnews = RRSimpleRSS.parse open(File.dirname(__FILE__) + '/../data/prnews.xml')
|
10
|
-
@rss_bbc
|
11
|
-
@
|
12
|
-
@
|
13
|
-
@
|
14
|
-
@
|
15
|
-
@
|
10
|
+
@rss_bbc = RRSimpleRSS.parse open(File.dirname(__FILE__) + '/../data/bbc.xml')
|
11
|
+
@rss_bbc2 = RRSimpleRSS.parse open(File.dirname(__FILE__) + '/../data/bbc2.xml')
|
12
|
+
@rss_baboo = RRSimpleRSS.parse open(File.dirname(__FILE__) + '/../data/baboo.xml')
|
13
|
+
@rss09 = RRSimpleRSS.parse open(File.dirname(__FILE__) + '/../data/rss09.rdf')
|
14
|
+
@rss20 = RRSimpleRSS.parse open(File.dirname(__FILE__) + '/../data/rss20.xml')
|
15
|
+
@media_rss = RRSimpleRSS.parse open(File.dirname(__FILE__) + '/../data/media_rss.xml')
|
16
|
+
@atom = RRSimpleRSS.parse open(File.dirname(__FILE__) + '/../data/atom.xml')
|
16
17
|
end
|
17
|
-
|
18
|
+
|
18
19
|
def test_channel
|
19
|
-
assert_equal @
|
20
|
-
assert_equal @
|
21
|
-
assert_equal @
|
22
|
-
assert_equal @
|
23
|
-
assert_equal @
|
20
|
+
assert_equal @rss_bbc2, @rss_bbc2.channel
|
21
|
+
assert_equal @rss_bbc, @rss_bbc.channel
|
22
|
+
assert_equal @rss09, @rss09.channel
|
23
|
+
assert_equal @rss20, @rss20.channel
|
24
|
+
assert_equal @atom, @atom.feed
|
25
|
+
assert_equal @rss_baboo, @rss_baboo.feed
|
24
26
|
assert_equal @rss_prnews, @rss_prnews.feed
|
25
27
|
end
|
26
|
-
|
28
|
+
|
27
29
|
def test_items
|
28
30
|
assert_kind_of Array, @rss_baboo.items
|
29
31
|
assert_kind_of Array, @rss_bbc.items
|
32
|
+
assert_kind_of Array, @rss_bbc2.items
|
30
33
|
assert_kind_of Array, @rss09.items
|
31
34
|
assert_kind_of Array, @rss20.items
|
32
35
|
assert_kind_of Array, @atom.entries
|
33
36
|
assert_kind_of Array, @rss_prnews.items
|
34
37
|
end
|
35
|
-
|
38
|
+
|
36
39
|
def test_rss_prnews
|
37
|
-
assert_equal 20,
|
40
|
+
assert_equal 20, @rss_prnews.items.size
|
38
41
|
assert_equal "PR Newswire Releases", @rss_prnews.title.force_encoding("UTF-8")
|
39
42
|
assert_equal "http://www.prnewswire.com/news-releases/sva-promove-exposicao-de-cartazes-que-retrata-a-evolucao-do-design-grafico-nos-ultimos-70-anos-540199401.html", @rss_prnews.channel.link
|
40
43
|
assert_equal "http://www.prnewswire.com/news-releases/sva-promove-exposicao-de-cartazes-que-retrata-a-evolucao-do-design-grafico-nos-ultimos-70-anos-540199401.html", @rss_prnews.items.first.link
|
41
44
|
assert_equal "http://www.prnewswire.com/news-releases/sva-promove-exposicao-de-cartazes-que-retrata-a-evolucao-do-design-grafico-nos-ultimos-70-anos-540199401.html", @rss_prnews.items.first[:link]
|
42
45
|
assert_equal Time.parse("2015-11-04 15:30:00 -0200"), @rss_prnews.items.first.pubDate
|
43
46
|
assert_equal Time.parse("2015-11-09 11:55:45 -0200"), @rss_prnews.channel.lastBuildDate
|
44
|
-
assert_nil
|
47
|
+
assert_nil @rss_prnews.items.first.full_text
|
45
48
|
assert_not_nil @rss_prnews.items.first.description
|
46
49
|
assert_kind_of Array, @rss_prnews.items.first.keywords
|
47
50
|
assert_kind_of Array, @rss_prnews.items.first.category
|
48
|
-
assert_equal "Art",
|
51
|
+
assert_equal "Art", @rss_prnews.items.first.category.first
|
49
52
|
end
|
50
53
|
|
51
54
|
def test_rss_baboo
|
@@ -56,8 +59,8 @@ class BaseTest < Test::Unit::TestCase
|
|
56
59
|
assert_equal "http://www.baboo.com.br/internet/lista-do-procon-sp-com-lojas-online-que-devem-ser-evitadas-e-atualizada/", @rss_baboo.items.first[:link]
|
57
60
|
assert_equal Time.parse("2015-11-05 14:11:24 -0200"), @rss_baboo.items.first.pubDate
|
58
61
|
assert_equal Time.parse("2015-11-05 14:11:24 -0200"), @rss_baboo.channel.lastBuildDate
|
59
|
-
assert_nil
|
60
|
-
assert_not_nil
|
62
|
+
assert_nil @rss_baboo.items.first.full_text
|
63
|
+
assert_not_nil @rss_baboo.items.first.description
|
61
64
|
assert_kind_of Array, @rss_baboo.items.first.category
|
62
65
|
end
|
63
66
|
|
@@ -73,6 +76,19 @@ class BaseTest < Test::Unit::TestCase
|
|
73
76
|
assert_kind_of Array, @rss_bbc.items.first.category
|
74
77
|
end
|
75
78
|
|
79
|
+
def test_rss_bbc2
|
80
|
+
assert_equal 3, @rss_bbc2.items.size
|
81
|
+
assert_equal "BBCBrasil.com | Notícias", @rss_bbc2.title.force_encoding("UTF-8")
|
82
|
+
assert_equal "http://www.bbc.com/portuguese/full_all.xml", @rss_bbc2.channel.link
|
83
|
+
assert_equal "http://www.bbc.com/portuguese/noticias/2015/11/151109_catacumbas_paris_brasileiro_cc", @rss_bbc2.items.first.link
|
84
|
+
assert_equal "http://www.bbc.com/portuguese/noticias/2015/11/151109_catacumbas_paris_brasileiro_cc", @rss_bbc2.items.first[:link]
|
85
|
+
assert_equal Time.parse("2015-11-09 16:40:33 -0200"), @rss_bbc2.items.first.updated
|
86
|
+
assert_equal Time.parse("2015-11-09 13:29:35 -0200"), @rss_bbc2.channel.updated
|
87
|
+
assert_not_nil @rss_bbc2.items.first.content
|
88
|
+
assert_nil @rss_bbc2.items.first.category.first
|
89
|
+
assert_kind_of Array, @rss_bbc2.items.first.keywords
|
90
|
+
end
|
91
|
+
|
76
92
|
def test_rss09
|
77
93
|
assert_equal 10, @rss09.items.size
|
78
94
|
assert_equal "Slashdot", @rss09.title
|
@@ -106,7 +122,7 @@ class BaseTest < Test::Unit::TestCase
|
|
106
122
|
assert_nil @media_rss.items.first.full_text
|
107
123
|
assert_kind_of Array, @media_rss.items.first.category
|
108
124
|
end
|
109
|
-
|
125
|
+
|
110
126
|
def test_rss20
|
111
127
|
assert_equal 10, @rss20.items.size
|
112
128
|
assert_equal "Technoblog", @rss20.title
|
@@ -117,7 +133,7 @@ class BaseTest < Test::Unit::TestCase
|
|
117
133
|
assert_nil @rss20.items.first.full_text
|
118
134
|
assert_kind_of Array, @rss20.items.first.category
|
119
135
|
end
|
120
|
-
|
136
|
+
|
121
137
|
def test_atom
|
122
138
|
assert_equal 1, @atom.entries.size
|
123
139
|
assert_equal "dive into mark", @atom.title
|
@@ -127,7 +143,7 @@ class BaseTest < Test::Unit::TestCase
|
|
127
143
|
assert_nil @atom.entries.first.full_text
|
128
144
|
assert_kind_of Array, @atom.entries.first.category
|
129
145
|
end
|
130
|
-
|
146
|
+
|
131
147
|
def test_bad_feed
|
132
148
|
assert_raise(RRSimpleRSSError) { RRSimpleRSS.parse(open(File.dirname(__FILE__) + '/../data/not-rss.xml')) }
|
133
149
|
end
|
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rrsimple-rss
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
5
|
-
prerelease:
|
4
|
+
version: 1.3.6
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Lucas Carlson
|
@@ -20,42 +19,41 @@ executables: []
|
|
20
19
|
extensions: []
|
21
20
|
extra_rdoc_files: []
|
22
21
|
files:
|
23
|
-
- install.rb
|
24
|
-
- lib/rrsimple-rss.rb
|
25
22
|
- LICENSE
|
26
|
-
- Rakefile
|
27
23
|
- README.markdown
|
24
|
+
- Rakefile
|
25
|
+
- install.rb
|
26
|
+
- lib/rrsimple-rss.rb
|
28
27
|
- rrsimple-rss.gemspec
|
29
28
|
- test/base/base_test.rb
|
30
|
-
- test/data/bbc.xml
|
31
29
|
- test/data/atom.xml
|
30
|
+
- test/data/bbc.xml
|
32
31
|
- test/data/not-rss.xml
|
33
32
|
- test/data/rss09.rdf
|
34
33
|
- test/data/rss20.xml
|
35
34
|
- test/test_helper.rb
|
36
35
|
homepage: http://github.com/rrmartins/simple-rss
|
37
36
|
licenses: []
|
37
|
+
metadata: {}
|
38
38
|
post_install_message:
|
39
39
|
rdoc_options: []
|
40
40
|
require_paths:
|
41
41
|
- lib
|
42
42
|
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
-
none: false
|
44
43
|
requirements:
|
45
44
|
- - ! '>='
|
46
45
|
- !ruby/object:Gem::Version
|
47
46
|
version: '0'
|
48
47
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
48
|
requirements:
|
51
49
|
- - ! '>='
|
52
50
|
- !ruby/object:Gem::Version
|
53
51
|
version: '0'
|
54
52
|
requirements: []
|
55
53
|
rubyforge_project: rrsimple-rss
|
56
|
-
rubygems_version:
|
54
|
+
rubygems_version: 2.4.8
|
57
55
|
signing_key:
|
58
|
-
specification_version:
|
56
|
+
specification_version: 4
|
59
57
|
summary: A simple, flexible, extensible, and liberal RSS and Atom reader for Ruby.
|
60
58
|
It is designed to be backwards compatible with the standard RSS parser, but will
|
61
59
|
never do RSS generation.
|