concerto_simple_rss 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
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