concerto_simple_rss 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,46 +2,104 @@ class SimpleRss < DynamicContent
2
2
 
3
3
  DISPLAY_NAME = 'RSS Feed'
4
4
 
5
- validate :validate_config
5
+ validate :validate_config, :validate_feed
6
6
 
7
7
  def build_content
8
- require 'rss'
9
- require 'net/http'
10
- url = self.config['url']
11
- feed = Net::HTTP.get_response(URI.parse(url)).body
12
-
13
- rss = RSS::Parser.parse(feed, false, true)
14
8
  contents = []
9
+
10
+ url = self.config['url']
11
+ type, feed_title, rss = fetch_feed(url)
15
12
 
16
- feed_title = rss.channel.title
17
-
18
- case self.config['output_format']
19
- when 'headlines'
20
- rss.items.each_slice(5).with_index do |items, index|
21
- htmltext = HtmlText.new()
22
- htmltext.name = "#{feed_title} (#{index+1})"
23
- htmltext.data = "<h1>#{feed_title}</h1> #{items_to_html(items)}"
24
- contents << htmltext
25
- end
26
- when 'detailed'
27
- rss.items.each_with_index do |item, index|
28
- htmltext = HtmlText.new()
29
- htmltext.name = "#{feed_title} (#{index+1})"
30
- htmltext.data = item_to_html(item)
31
- contents << htmltext
13
+ if (["RSS", "ATOM"].include? type) && !feed_title.blank?
14
+ # it is a valid feed
15
+ case self.config['output_format']
16
+ when 'headlines'
17
+ rss.items.each_slice(5).with_index do |items, index|
18
+ htmltext = HtmlText.new()
19
+ htmltext.name = "#{feed_title} (#{index+1})"
20
+ htmltext.data = "<h1>#{feed_title}</h1> #{items_to_html(items, type)}"
21
+ contents << htmltext
22
+ end
23
+ when 'detailed'
24
+ rss.items.each_with_index do |item, index|
25
+ htmltext = HtmlText.new()
26
+ htmltext.name = "#{feed_title} (#{index+1})"
27
+ htmltext.data = item_to_html(item, type)
28
+ contents << htmltext
29
+ end
30
+ else
31
+ raise ArgumentError, 'Unexpected output format for RSS feed.'
32
32
  end
33
33
  else
34
- raise ArgumentError, 'Unexpected output format for RSS feed.'
34
+ Rails.logger.error("could not fetch #{type} feed for #{feed_title} at #{url}")
35
+ raise "Unexpected feed format for #{url}."
35
36
  end
37
+
36
38
  return contents
37
39
  end
38
40
 
39
- def item_to_html(item)
40
- return "<h1>#{item.title}</h1><p>#{item.description}</p>"
41
+ # fetch the feed, return the type, title, and contents
42
+ def fetch_feed(url)
43
+ require 'rss'
44
+ require 'net/http'
45
+
46
+ type = 'UNKNOWN'
47
+ title = ''
48
+ rss = nil
49
+
50
+ begin
51
+ feed = Net::HTTP.get_response(URI.parse(url)).body
52
+ rss = RSS::Parser.parse(feed, false, true)
53
+ rescue => e
54
+ # cant parse rss or url is bad
55
+ Rails.logger.debug("unable to fetch or parse feed - #{url}, #{e.message}")
56
+ rss = e.message
57
+ else
58
+ type = rss.feed_type.upcase
59
+
60
+ case type
61
+ when "RSS"
62
+ title = rss.channel.title
63
+ when "ATOM"
64
+ title = rss.title.content
65
+ else
66
+ #title = "unknown feed type"
67
+ end
68
+ end
69
+
70
+ return type, title, rss
41
71
  end
42
72
 
43
- def items_to_html(items)
44
- return items.collect{|item| "<h2>#{item.title}</h2>"}.join(" ")
73
+ def item_to_html(item, type)
74
+ case type
75
+ when "RSS"
76
+ title = item.title
77
+ description = item.description
78
+ when "ATOM"
79
+ title = item.title.content
80
+
81
+ # seems like the hard way, but the only way I could figure out to get the
82
+ # contents without it being html encoded. most likely a prime candidate for optimizing
83
+ require 'rexml/document'
84
+ entry_xml = REXML::Document.new(item.to_s)
85
+ content_html = REXML::XPath.first(entry_xml, "entry/content").text
86
+
87
+ description = (item.summary.nil? ? content_html : item.summary.content)
88
+ end
89
+
90
+ return "<h1>#{title}</h1><p>#{description.html_safe}</p>"
91
+ end
92
+
93
+ def items_to_html(items, type)
94
+ return items.collect {|item|
95
+ case type
96
+ when "RSS"
97
+ title = item.title
98
+ when "ATOM"
99
+ title = item.title.content
100
+ end
101
+
102
+ "<h2>#{title}</h2>" }.join(" ")
45
103
  end
46
104
 
47
105
  # Simple RSS processing needs a feed URL and the format of the output content.
@@ -50,6 +108,21 @@ class SimpleRss < DynamicContent
50
108
  attributes.concat([:config => [:url, :output_format]])
51
109
  end
52
110
 
111
+ # if the feed is valid we store the title in config
112
+ def validate_feed
113
+ url = self.config['url']
114
+ unless url.blank?
115
+ Rails.logger.debug("looking up feed title for #{url}")
116
+
117
+ type, title = fetch_feed(url)
118
+ if (["RSS", "ATOM"].include? type) && !title.blank?
119
+ self.config['title'] = title
120
+ else
121
+ errors.add(:config_url, "does not appear to be an RSS feed")
122
+ end
123
+ end
124
+ end
125
+
53
126
  def validate_config
54
127
  if self.config['url'].blank?
55
128
  errors.add(:config_url, "can't be blank")
@@ -5,6 +5,7 @@
5
5
  <%= config.label :url %>
6
6
  <div class="input">
7
7
  <%= config.url_field :url, :placeholder => 'http://feeds.bbci.co.uk/news/rss.xml', :class => "input-xxlarge", :value => @content.config['url'] %>
8
+ <div><small>You can verify an RSS feed at <a href="http://validator.w3.org/feed/" target="_blank">http://validator.w3.org/feed/</a></small></div>
8
9
  </div>
9
10
  </div>
10
11
  <div class="clearfix">
@@ -0,0 +1,3 @@
1
+ <div class="grid-item with-shadow">
2
+ <i class="ficon-rss-sign icon-4x orange"></i>
3
+ </div>
@@ -0,0 +1,18 @@
1
+ <div class="default-padding">
2
+ <% if content.config.include?('title') %>
3
+ <h1><%= content.config['title'] %></h1>
4
+ <p></p>
5
+ <% end %>
6
+ <h2 class="center">
7
+ <%= content.name %>
8
+ </h2>
9
+ <p>
10
+ <%= content.config['url'] %>
11
+ </p>
12
+ </div>
13
+ <% if content.config.include?('last_ok_refresh') %>
14
+ <div class="brand muted default-padding">
15
+ <br/>
16
+ <%= distance_of_time_in_words_to_now(Time.at(content.config['last_ok_refresh'])).titleize %> Ago
17
+ </div>
18
+ <% end %>
@@ -0,0 +1 @@
1
+ <i class="ficon-rss-sign"></i>
@@ -1,3 +1,3 @@
1
1
  module ConcertoSimpleRss
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: concerto_simple_rss
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-30 00:00:00.000000000 -07:00
12
+ date: 2013-06-13 00:00:00.000000000 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rails
17
- requirement: &70276077747540 !ruby/object:Gem::Requirement
17
+ requirement: &70295685543440 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ~>
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 3.2.11
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *70276077747540
25
+ version_requirements: *70295685543440
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: sqlite3
28
- requirement: &70276077745540 !ruby/object:Gem::Requirement
28
+ requirement: &70295685542820 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,7 +33,7 @@ dependencies:
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
- version_requirements: *70276077745540
36
+ version_requirements: *70295685542820
37
37
  description: Simple support to render RSS content in Concerto 2.
38
38
  email:
39
39
  - bmichalski@gmail.com
@@ -41,11 +41,13 @@ executables: []
41
41
  extensions: []
42
42
  extra_rdoc_files: []
43
43
  files:
44
- - app/assets/stylesheets/concert_simple_rss/application.css
44
+ - app/assets/stylesheets/concerto_simple_rss/application.css
45
45
  - app/models/simple_rss.rb
46
- - app/views/contents/simple_rss/_form_top.html
47
- - app/views/contents/simple_rss/_render_default.html
48
- - app/views/contents/simple_rss/_render_tile.html
46
+ - app/views/contents/simple_rss/_form_top.html.erb
47
+ - app/views/contents/simple_rss/_render_default.html.erb
48
+ - app/views/contents/simple_rss/_render_grid.html.erb
49
+ - app/views/contents/simple_rss/_render_tile.html.erb
50
+ - app/views/contents/simple_rss/_tab_icon.html.erb
49
51
  - config/routes.rb
50
52
  - lib/concerto_simple_rss/engine.rb
51
53
  - lib/concerto_simple_rss/version.rb
@@ -1,3 +0,0 @@
1
- <h1><%= content.name %></h1>
2
- <br />
3
- <%= content.config['url'] %>