concerto_simple_rss 0.0.8 → 0.0.9

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0eceaf899ce25371ae25b97401b6f5f148abcd9c
4
- data.tar.gz: 40395c9ad8b3b698176adaaad36505a9fc5ffa77
3
+ metadata.gz: 27bcb6e184059a5cbae750cb4851cf0161e966e0
4
+ data.tar.gz: ff9e1a3d2da810814ae11b4d1bbd8f9e89433ac2
5
5
  SHA512:
6
- metadata.gz: aaf5f4ccd942a437b4699c6d62ee8a2e00c20c4402f0547a1400c3e77073b2eabb8a857bd05c2442a46c8c3ab58960b08ff725d2fe19c3989ae8c7c6edade4ba
7
- data.tar.gz: 2c0ac3d2abadc5461adbd249d5700fb3079d03459dc1f99c47bcb937c76e09ad8c7894f6dfff2e92386caef2addac3ee4f8155a2170e872325d5dc41036ac1aa
6
+ metadata.gz: 506c01f6444c666f2a5756f81c5a2c205382216a09ad5a7a9a57c3f28d326d32d06c76973e04cb0d14032a07952dc00a00cfb21eb5170daaa17aec17be2d8130
7
+ data.tar.gz: 94afe471154677c38a7ef8af2205f91e2d62cb3ae1e8a5f4f6aa52f5fb23fcc05ef571d7497081067de1217a701e79a10c9fd985b7b0a3b7d67c4effb93c30d4
@@ -1,41 +1,51 @@
1
- function initializeSimpleRSSPreview() {
2
- // When changes are made to url input, get rss data and build preview
3
- $('#simple_rss_config_url').keyup(function (e) {
4
- rss_url = $('#simple_rss_config_url').val();
5
- getRSSData(rss_url);
6
- });
1
+ function toggleSimpleRssConditionalInputs() {
2
+ if ($('select#simple_rss_config_output_format').val() == 'xslt') {
3
+ $('div#simple_rss_maxitems').hide();
4
+ $('div#simple_rss_xslmarkup').show();
5
+ } else {
6
+ $('div#simple_rss_maxitems').show();
7
+ $('div#simple_rss_xslmarkup').hide();
8
+ }
7
9
  }
8
10
 
9
- function getRSSData(rss_url) {
10
- // Get the rss data based in input url
11
- $.ajax({
12
- type: "GET",
13
- dataType: 'jsonp',
14
- url: document.location.protocol + '//ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=1000&callback=?&q=' + encodeURIComponent(rss_url),
15
- success: function (rss_data) {
16
- simpleRSSPreview(rss_data);
17
- },
18
- error: function () {
19
- $('#preview_div').html("Could not load preview")
11
+ function previewSimpleRss() {
12
+ var url = $('input#simple_rss_config_url').data('url');
13
+ if (url) {
14
+ rss_url = $('input#simple_rss_config_url').val();
15
+ output_format = $('select#simple_rss_config_output_format').val();
16
+ max_items = $('input#simple_rss_config_max_items').val();
17
+ reverse_order = $('select#simple_rss_config_reverse_order').val();
18
+ xsl = $('textarea#simple_rss_config_xsl').val();
19
+ if (max_items == '') {
20
+ max_items = '0';
20
21
  }
21
- });
22
+ $("#preview_div").load(url, { data: {
23
+ url: rss_url,
24
+ output_format: output_format,
25
+ max_items: max_items,
26
+ reverse_order: reverse_order,
27
+ xsl: xsl
28
+ }, type: 'SimpleRss' });
29
+ }
22
30
  }
23
31
 
24
- function simpleRSSPreview(rss_data) {
32
+ var initializedSimpleRssHandlers = false;
33
+ function initializeSimpleRssHandlers() {
34
+ if (!initializedSimpleRssHandlers) {
35
+ $('select#simple_rss_config_output_format').on('change', toggleSimpleRssConditionalInputs);
36
+ toggleSimpleRssConditionalInputs();
25
37
 
26
- // Store all article entries and clear preview
27
- articles = rss_data['responseData']['feed']['entries'];
28
- $('#preview_div').html();
38
+ // on blur and change of url, display format, reverse_order, max items, and xsl
39
+ // not on keyup (poor man's debouncing technique?)
40
+ $('input#simple_rss_config_url').on('blur', previewSimpleRss);
41
+ $('select#simple_rss_config_output_format').on('change', previewSimpleRss);
42
+ $('input#simple_rss_config_max_items').on('blur', previewSimpleRss);
43
+ $('select#simple_rss_config_reverse_order').on('change', previewSimpleRss);
44
+ $('textarea#simple_rss_config_xsl').on('blur', previewSimpleRss);
29
45
 
30
- // Build rss preview for only a sample of article titles
31
- rss_preview = "<div><p style='font-weight: bold'>Found " + articles.length + " articles total</p></div>";
32
- for (var i = 0; i < Math.min(4, articles.length); i++) {
33
- rss_preview += "<div>" +
34
- "<p style='font-size: 14px; text-decoration: underline'>" + articles[i]['title'] + "</p>" +
35
- "<p>" + articles[i]['contentSnippet'] + "</p>" + "</div>";
46
+ initializedSimpleRssHandlers = true;
36
47
  }
37
- $('#preview_div').html(rss_preview);
38
48
  }
39
49
 
40
- $(document).ready(initializeSimpleRSSPreview);
41
- $(document).on('page:change', initializeSimpleRSSPreview);
50
+ $(document).ready(initializeSimpleRssHandlers);
51
+ $(document).on('page:change', initializeSimpleRssHandlers);
@@ -8,28 +8,44 @@ class SimpleRss < DynamicContent
8
8
  contents = []
9
9
 
10
10
  url = self.config['url']
11
- type, feed_title, rss = fetch_feed(url)
11
+ type, feed_title, rss, raw = fetch_feed(url)
12
12
 
13
13
  if (["RSS", "ATOM"].include? type) && !feed_title.blank?
14
14
  # it is a valid feed
15
15
  if !self.config['reverse_order'].blank? && self.config['reverse_order'] == '1'
16
16
  rss.items.reverse!
17
17
  end
18
+ feed_items = rss.items
19
+ if !self.config['max_items'].blank? && self.config['max_items'].to_i > 0
20
+ feed_items = feed_items.first(self.config['max_items'].to_i)
21
+ end
18
22
  case self.config['output_format']
19
23
  when 'headlines'
20
- rss.items.each_slice(5).with_index do |items, index|
24
+ feed_items.each_slice(5).with_index do |items, index|
21
25
  htmltext = HtmlText.new()
22
26
  htmltext.name = "#{feed_title} (#{index+1})"
23
27
  htmltext.data = "<h1>#{feed_title}</h1> #{items_to_html(items, type)}"
24
28
  contents << htmltext
25
29
  end
26
30
  when 'detailed'
27
- rss.items.each_with_index do |item, index|
31
+ feed_items.each_with_index do |item, index|
28
32
  htmltext = HtmlText.new()
29
33
  htmltext.name = "#{feed_title} (#{index+1})"
30
34
  htmltext.data = item_to_html(item, type)
31
35
  contents << htmltext
32
36
  end
37
+ when 'xslt'
38
+ require 'rexml/document'
39
+ require 'xml/xslt'
40
+
41
+ XML::XSLT.registerErrorHandler { |string| puts string }
42
+ xslt = XML::XSLT.new()
43
+ xslt.xml = REXML::Document.new(raw)
44
+ xslt.xsl = REXML::Document.new(self.config['xsl'])
45
+ htmltext = HtmlText.new()
46
+ htmltext.name = "#{feed_title}"
47
+ htmltext.data = xslt.serve()
48
+ contents << htmltext
33
49
  else
34
50
  raise ArgumentError, 'Unexpected output format for RSS feed.'
35
51
  end
@@ -41,7 +57,7 @@ class SimpleRss < DynamicContent
41
57
  return contents
42
58
  end
43
59
 
44
- # fetch the feed, return the type, title, and contents
60
+ # fetch the feed, return the type, title, and contents (parsed) and raw feed (unparsed)
45
61
  def fetch_feed(url)
46
62
  require 'rss'
47
63
  require 'net/http'
@@ -49,13 +65,18 @@ class SimpleRss < DynamicContent
49
65
  type = 'UNKNOWN'
50
66
  title = ''
51
67
  rss = nil
68
+ feed = nil
52
69
 
53
70
  begin
54
- uri = URI.parse(url)
55
- http = Net::HTTP.new(uri.host, uri.port)
56
- http.use_ssl = uri.scheme == 'https'
57
- request = Net::HTTP::Get.new(uri.request_uri)
58
- feed = http.request(request).body
71
+ # cache same url for 1 minute to alleviate redundant calls when previewing
72
+ feed = Rails.cache.fetch(url, :expires_in => 1.minute) do
73
+ uri = URI.parse(url)
74
+ http = Net::HTTP.new(uri.host, uri.port)
75
+ http.use_ssl = uri.scheme == 'https'
76
+ request = Net::HTTP::Get.new(uri.request_uri)
77
+ http.request(request).body
78
+ end
79
+
59
80
  rss = RSS::Parser.parse(feed, false, true)
60
81
  raise "feed could not be parsed" if rss.nil?
61
82
  rescue => e
@@ -75,7 +96,7 @@ class SimpleRss < DynamicContent
75
96
  end
76
97
  end
77
98
 
78
- return type, title, rss
99
+ return type, title, rss, feed
79
100
  end
80
101
 
81
102
  def item_to_html(item, type)
@@ -114,7 +135,7 @@ class SimpleRss < DynamicContent
114
135
  # Simple RSS processing needs a feed URL and the format of the output content.
115
136
  def self.form_attributes
116
137
  attributes = super()
117
- attributes.concat([:config => [:url, :output_format, :reverse_order]])
138
+ attributes.concat([:config => [:url, :output_format, :reverse_order, :max_items, :xsl]])
118
139
  end
119
140
 
120
141
  # if the feed is valid we store the title in config
@@ -127,17 +148,60 @@ class SimpleRss < DynamicContent
127
148
  if (["RSS", "ATOM"].include? type) && !title.blank?
128
149
  self.config['title'] = title
129
150
  else
130
- errors.add(:config_url, "does not appear to be an RSS feed")
151
+ errors.add(:base, "URL does not appear to be an RSS feed")
131
152
  end
132
153
  end
133
154
  end
134
155
 
135
156
  def validate_config
136
157
  if self.config['url'].blank?
137
- errors.add(:config_url, "can't be blank")
158
+ errors.add(:base, "URL can't be blank")
159
+ end
160
+
161
+ if !['headlines', 'detailed', 'xslt'].include?(self.config['output_format'])
162
+ errors.add(:base, "Display Format must be Headlines or Articles or XSLT")
163
+ end
164
+
165
+ if self.config['output_format'] == 'xslt'
166
+ if self.config['xsl'].blank?
167
+ errors.add(:base, "XSL Markup can't be blank when using the XSLT Display Format")
168
+ else
169
+ url = self.config['url']
170
+ unless url.blank?
171
+ require 'rexml/document'
172
+ require 'xml/xslt'
173
+
174
+ type, title, rss, raw = fetch_feed(url)
175
+ if ["RSS", "ATOM"].include? type
176
+ begin
177
+ xslt = XML::XSLT.new()
178
+ xslt.xml = REXML::Document.new(raw)
179
+ xslt.xsl = REXML::Document.new(self.config['xsl'])
180
+ rescue XML::XSLT::ParsingError
181
+ errors.add(:base, "XSL Markup could not be parsed")
182
+ end
183
+ end
184
+ end
185
+ end
138
186
  end
139
- if !['headlines', 'detailed'].include?(self.config['output_format'])
140
- errors.add(:config_output_format, "must be Headlines or Articles")
187
+ end
188
+
189
+ # return the first item for use as a preview
190
+ # data is a hash of the config
191
+ def self.preview(data)
192
+ begin
193
+ o = SimpleRss.create()
194
+ o.config['url'] = data[:url]
195
+ o.config['output_format'] = data[:output_format]
196
+ o.config['max_items'] = data[:max_items]
197
+ o.config['reverse_order'] = data[:reverse_order]
198
+ o.config['xsl'] = data[:xsl]
199
+ results = o.build_content.first.data
200
+ rescue => e
201
+ results = "Unable to preview #{e.message}"
141
202
  end
203
+
204
+ return results
142
205
  end
206
+
143
207
  end
@@ -5,14 +5,14 @@
5
5
  <div class="clearfix">
6
6
  <%= config.label :url %>
7
7
  <div class="input">
8
- <%= config.url_field :url, :placeholder => 'http://feeds.bbci.co.uk/news/rss.xml', :class => "input-xxlarge", :value => @content.config['url'] %>
8
+ <%= config.url_field :url, :placeholder => 'http://feeds.bbci.co.uk/news/rss.xml', :class => "input-xxlarge", :value => @content.config['url'], "data-url" => preview_contents_path %>
9
9
  <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>
10
10
  </div>
11
11
  </div>
12
12
  <div class="clearfix">
13
13
  <%= config.label :output_format, 'Display Format' %>
14
14
  <div class="input">
15
- <%= config.select :output_format, [["Headlines", "headlines"], ["Articles", "detailed"]], :selected => @content.config['output_format'] %>
15
+ <%= config.select :output_format, [["Headlines", "headlines"], ["Articles", "detailed"], ["XSLT", "xslt"]], :selected => @content.config['output_format'] %>
16
16
  </div>
17
17
  </div>
18
18
  <div class="clearfix">
@@ -21,5 +21,17 @@
21
21
  <%= config.select :reverse_order, [["No", 0], ["Yes", 1]] %>
22
22
  </div>
23
23
  </div>
24
+ <div class="clearfix" id="simple_rss_maxitems">
25
+ <%= config.label :max_items, 'Maximum items from feed' %>
26
+ <div class="input">
27
+ <%= config.number_field :max_items, :min => 0, :step => 1, :value => @content.config['max_items'] %>
28
+ </div>
29
+ </div>
30
+ <div class="clearfix" id="simple_rss_xslmarkup">
31
+ <%= label_tooltip "simple_rss", :config_xsl, "XSL Markup", :tip => "The XSL Markup field is only used when the Display Format is set to XSLT." %>
32
+ <div class="input">
33
+ <%= config.text_area :xsl, :class => "span12", :rows =>4, :value => @content.config['xsl'] %>
34
+ </div>
35
+ </div>
24
36
  <% end %>
25
37
  </fieldset>
@@ -1,3 +1,3 @@
1
1
  module ConcertoSimpleRss
2
- VERSION = "0.0.8"
2
+ VERSION = "0.0.9"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: concerto_simple_rss
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Michalski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-12 00:00:00.000000000 Z
11
+ date: 2014-01-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ~>
25
25
  - !ruby/object:Gem::Version
26
26
  version: 3.2.11
27
+ - !ruby/object:Gem::Dependency
28
+ name: ruby-xslt
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '0.9'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '0.9'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: sqlite3
29
43
  requirement: !ruby/object:Gem::Requirement