concerto_simple_rss 0.7 → 0.8
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 +4 -4
- data/app/assets/javascripts/concerto_simple_rss/simple_rss.js +6 -0
- data/app/models/simple_rss.rb +184 -131
- data/app/views/contents/simple_rss/_form_top.html.erb +18 -1
- data/config/locales/en.yml +7 -0
- data/lib/concerto_simple_rss/engine.rb +4 -0
- data/lib/concerto_simple_rss/version.rb +1 -1
- metadata +18 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aa7e279123911a7477853d01e1ac97f6a9a9d6b9
|
4
|
+
data.tar.gz: 9f34f22652616db1752b96f52431aef37809d6c0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d3052c45ead7cabeb914416882979d34fcec3f207ad5d906acc6aaecf08d28101c7d4a92b43dbd67346032dac7b083c8ad50d3867ee9c6dc10fa8ae687804254
|
7
|
+
data.tar.gz: 6a341b98a8a0471de16426be656a717b9d0306f080710581adc41c8720080c8acecbc44c25eb23e4189814e619cb0ccf3fbb1f2e4ba0e22f4db023e8809f3409
|
@@ -12,6 +12,8 @@ function previewSimpleRss() {
|
|
12
12
|
var url = $('input#simple_rss_config_url').data('url');
|
13
13
|
if (url) {
|
14
14
|
rss_url = $('input#simple_rss_config_url').val();
|
15
|
+
userid = $('input#simple_rss_config_url_userid').val();
|
16
|
+
password = $('input#simple_rss_config_url_password').val();
|
15
17
|
output_format = $('select#simple_rss_config_output_format').val();
|
16
18
|
max_items = $('input#simple_rss_config_max_items').val();
|
17
19
|
reverse_order = $('select#simple_rss_config_reverse_order').val();
|
@@ -22,6 +24,8 @@ function previewSimpleRss() {
|
|
22
24
|
}
|
23
25
|
$("#preview_div").load(url, { data: {
|
24
26
|
url: rss_url,
|
27
|
+
url_userid: userid,
|
28
|
+
url_password: password,
|
25
29
|
output_format: output_format,
|
26
30
|
max_items: max_items,
|
27
31
|
reverse_order: reverse_order,
|
@@ -40,6 +44,8 @@ function initializeSimpleRssHandlers() {
|
|
40
44
|
// on blur and change of url, display format, reverse_order, max items, and xsl
|
41
45
|
// not on keyup (poor man's debouncing technique?)
|
42
46
|
$('input#simple_rss_config_url').on('blur', previewSimpleRss);
|
47
|
+
$('input#simple_rss_config_url_userid').on('blur', previewSimpleRss);
|
48
|
+
$('input#simple_rss_config_url_password').on('blur', previewSimpleRss);
|
43
49
|
$('select#simple_rss_config_output_format').on('change', previewSimpleRss);
|
44
50
|
$('input#simple_rss_config_max_items').on('blur', previewSimpleRss);
|
45
51
|
$('select#simple_rss_config_reverse_order').on('change', previewSimpleRss);
|
data/app/models/simple_rss.rb
CHANGED
@@ -1,137 +1,176 @@
|
|
1
1
|
class SimpleRss < DynamicContent
|
2
|
+
require 'base64'
|
2
3
|
|
3
4
|
DISPLAY_NAME = 'RSS Feed'
|
4
5
|
|
5
6
|
validate :validate_config, :validate_feed
|
6
7
|
|
8
|
+
# Load a configuration hash.
|
9
|
+
# Converts the JSON data stored for the content into the configuration.
|
10
|
+
# Called during `after_find`.
|
11
|
+
def load_config
|
12
|
+
j = JSON.load(self.data)
|
13
|
+
|
14
|
+
# decrypt fields
|
15
|
+
unless j.blank?
|
16
|
+
encrypted_userid = Base64.decode64(j['url_userid_enc']) unless j['url_userid_enc'].blank?
|
17
|
+
encrypted_password = Base64.decode64(j['url_password_enc']) unless j['url_password_enc'].blank?
|
18
|
+
|
19
|
+
j['url_userid'] = (encrypted_userid.blank? ? "" : encrypted_userid.decrypt)
|
20
|
+
j['url_password'] = (encrypted_password.blank? ? "" : encrypted_password.decrypt)
|
21
|
+
end
|
22
|
+
|
23
|
+
self.config = j
|
24
|
+
end
|
25
|
+
|
26
|
+
# Prepare the configuration to be saved.
|
27
|
+
# Compress the config hash back into JSON to be stored in the database.
|
28
|
+
# Called during `before_validation`.
|
29
|
+
def save_config
|
30
|
+
j = self.config.deep_dup
|
31
|
+
|
32
|
+
# encrypt fields
|
33
|
+
j['url_userid_enc'] = (j['url_userid'].blank? ? "" : Base64.encode64(j['url_userid'].encrypt))
|
34
|
+
j['url_password_enc'] = (j['url_password'].blank? ? "" : Base64.encode64(j['url_password'].encrypt))
|
35
|
+
j.delete 'url_userid'
|
36
|
+
j.delete 'url_password'
|
37
|
+
self.data = JSON.dump(j)
|
38
|
+
end
|
39
|
+
|
7
40
|
def build_content
|
8
41
|
contents = []
|
9
42
|
|
10
43
|
url = self.config['url']
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
feed_items = feed_items.first(self.config['max_items'].to_i)
|
21
|
-
end
|
22
|
-
case self.config['output_format']
|
23
|
-
when 'headlines'
|
24
|
-
feed_items.each_slice(5).with_index do |items, index|
|
25
|
-
htmltext = HtmlText.new()
|
26
|
-
htmltext.name = "#{feed_title} (#{index+1})"
|
27
|
-
htmltext.data = sanitize("<h1>#{feed_title}</h1> #{items_to_html(items, type)}")
|
28
|
-
contents << htmltext
|
44
|
+
unless url.blank?
|
45
|
+
url_userid = self.config['url_userid']
|
46
|
+
url_password = self.config['url_password']
|
47
|
+
type, feed_title, rss, raw = fetch_feed(url, url_userid, url_password)
|
48
|
+
|
49
|
+
if (["RSS", "ATOM"].include? type) && !feed_title.blank?
|
50
|
+
# it is a valid feed
|
51
|
+
if !self.config['reverse_order'].blank? && self.config['reverse_order'] == '1'
|
52
|
+
rss.items.reverse!
|
29
53
|
end
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
htmltext.name = "#{feed_title} (#{index+1})"
|
34
|
-
htmltext.data = sanitize(item_to_html(item, type))
|
35
|
-
contents << htmltext
|
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
|
-
begin
|
44
|
-
xslt.xml = REXML::Document.new(raw)
|
45
|
-
rescue REXML::ParseException => e
|
46
|
-
Rails.logger.error("Unable to parse incoming feed: #{e.message}")
|
47
|
-
raise "Unable to parse incoming feed. "
|
48
|
-
rescue => e
|
49
|
-
raise e
|
54
|
+
feed_items = rss.items
|
55
|
+
if !self.config['max_items'].blank? && self.config['max_items'].to_i > 0
|
56
|
+
feed_items = feed_items.first(self.config['max_items'].to_i)
|
50
57
|
end
|
58
|
+
case self.config['output_format']
|
59
|
+
when 'headlines'
|
60
|
+
feed_items.each_slice(5).with_index do |items, index|
|
61
|
+
htmltext = HtmlText.new()
|
62
|
+
htmltext.name = "#{feed_title} (#{index+1})"
|
63
|
+
htmltext.data = sanitize("<h1>#{feed_title}</h1> #{items_to_html(items, type)}")
|
64
|
+
contents << htmltext
|
65
|
+
end
|
66
|
+
when 'detailed'
|
67
|
+
feed_items.each_with_index do |item, index|
|
68
|
+
htmltext = HtmlText.new()
|
69
|
+
htmltext.name = "#{feed_title} (#{index+1})"
|
70
|
+
htmltext.data = sanitize(item_to_html(item, type))
|
71
|
+
contents << htmltext
|
72
|
+
end
|
73
|
+
when 'xslt'
|
74
|
+
require 'rexml/document'
|
75
|
+
require 'xml/xslt'
|
51
76
|
|
52
|
-
|
53
|
-
xslt
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
raise e
|
63
|
-
end
|
77
|
+
#XML::XSLT.registerErrorHandler { |string| puts string }
|
78
|
+
xslt = XML::XSLT.new()
|
79
|
+
begin
|
80
|
+
xslt.xml = REXML::Document.new(raw)
|
81
|
+
rescue REXML::ParseException => e
|
82
|
+
Rails.logger.error("Unable to parse incoming feed: #{e.message}")
|
83
|
+
raise "Unable to parse incoming feed. "
|
84
|
+
rescue => e
|
85
|
+
raise e
|
86
|
+
end
|
64
87
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
88
|
+
begin
|
89
|
+
xslt.xsl = REXML::Document.new(self.config['xsl'])
|
90
|
+
rescue REXML::ParseException => e
|
91
|
+
Rails.logger.error("Unable to parse Xsl: #{e.message}")
|
92
|
+
# fmt is <rexml::parseexception: message :> trace ... so just pull out the message
|
93
|
+
s = e.message
|
94
|
+
msg_stop = s.index(">")
|
95
|
+
s = s.slice(23, msg_stop - 23) if !msg_stop.nil?
|
96
|
+
raise "Unable to parse Xsl. #{s}"
|
97
|
+
rescue => e
|
98
|
+
raise e
|
99
|
+
end
|
72
100
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
101
|
+
# add a replace [gsub] function for more powerful transforms. You can use this in a transform
|
102
|
+
# by adding the bogus namespace http://concerto.functions
|
103
|
+
# A nodeset comes in as an array of REXML::Elements
|
104
|
+
XML::XSLT.registerExtFunc("http://concerto.functions", "replace") do |nodes, pattern, replacement|
|
105
|
+
result = xslt_replace(nodes, pattern, replacement)
|
106
|
+
result
|
107
|
+
end
|
77
108
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
#
|
88
|
-
if
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
# if there are any content-items then add each one as a separate content
|
95
|
-
# and strip off the content-item wrapper
|
96
|
-
nodes.each do |n|
|
109
|
+
XML::XSLT.registerExtFunc("http://schemas.concerto-signage.org/functions", "replace") do |nodes, pattern, replacement|
|
110
|
+
result = xslt_replace(nodes, pattern, replacement)
|
111
|
+
result
|
112
|
+
end
|
113
|
+
|
114
|
+
data = xslt.serve()
|
115
|
+
# xslt.serve does always return a string with ASCII-8BIT encoding regardless of what the actual encoding is
|
116
|
+
data = data.force_encoding(xslt.xml.encoding) if data
|
117
|
+
|
118
|
+
# try to load the transformed data as an xml document so we can see if there are
|
119
|
+
# mulitple content-items that we need to parse out, if we cant then treat it as one content item
|
120
|
+
begin
|
121
|
+
data_xml = REXML::Document.new('<root>' + data + '</root>')
|
122
|
+
nodes = REXML::XPath.match(data_xml, "//content-item")
|
123
|
+
# if there are no content-items then add the whole result (data) as one content
|
124
|
+
if nodes.count == 0
|
97
125
|
htmltext = HtmlText.new()
|
98
126
|
htmltext.name = "#{feed_title}"
|
99
|
-
htmltext.data = sanitize(
|
127
|
+
htmltext.data = sanitize(data)
|
100
128
|
contents << htmltext
|
129
|
+
else
|
130
|
+
# if there are any content-items then add each one as a separate content
|
131
|
+
# and strip off the content-item wrapper
|
132
|
+
nodes.each do |n|
|
133
|
+
htmltext = HtmlText.new()
|
134
|
+
htmltext.name = "#{feed_title}"
|
135
|
+
htmltext.data = sanitize(n.to_s.gsub(/^\s*\<content-item\>/, '').gsub(/\<\/content-item\>\s*$/,''))
|
136
|
+
contents << htmltext
|
137
|
+
end
|
101
138
|
end
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
139
|
+
rescue => e
|
140
|
+
# maybe the html was not xml compliant-- this happens frequently in rss feed descriptions
|
141
|
+
# look for another separator and use it, if it exists
|
142
|
+
|
143
|
+
if data.include?("</content-item>")
|
144
|
+
# if there are any content-items then add each one as a separate content
|
145
|
+
# and strip off the content-item wrapper
|
146
|
+
data.split("</content-item>").each do |n|
|
147
|
+
htmltext = HtmlText.new()
|
148
|
+
htmltext.name = "#{feed_title}"
|
149
|
+
htmltext.data = sanitize(n.sub("<content-item>", ""))
|
150
|
+
contents << htmltext if !htmltext.data.strip.blank?
|
151
|
+
end
|
152
|
+
|
153
|
+
else
|
154
|
+
Rails.logger.error("unable to parse resultant xml, assuming it is one content item #{e.message}")
|
155
|
+
# raise "unable to parse resultant xml #{e.message}"
|
156
|
+
# add the whole result as one content
|
111
157
|
htmltext = HtmlText.new()
|
112
158
|
htmltext.name = "#{feed_title}"
|
113
|
-
htmltext.data = sanitize(
|
114
|
-
contents << htmltext
|
159
|
+
htmltext.data = sanitize(data)
|
160
|
+
contents << htmltext
|
115
161
|
end
|
116
|
-
|
117
|
-
else
|
118
|
-
Rails.logger.error("unable to parse resultant xml, assuming it is one content item #{e.message}")
|
119
|
-
# raise "unable to parse resultant xml #{e.message}"
|
120
|
-
# add the whole result as one content
|
121
|
-
htmltext = HtmlText.new()
|
122
|
-
htmltext.name = "#{feed_title}"
|
123
|
-
htmltext.data = sanitize(data)
|
124
|
-
contents << htmltext
|
125
162
|
end
|
163
|
+
else
|
164
|
+
raise ArgumentError, 'Unexpected output format for RSS feed.'
|
126
165
|
end
|
166
|
+
elsif type == "ERROR"
|
167
|
+
raise rss
|
127
168
|
else
|
128
|
-
|
169
|
+
Rails.logger.error("could not fetch #{type} feed for #{feed_title} at #{url}")
|
170
|
+
raise "Unexpected feed format for #{url}."
|
129
171
|
end
|
130
|
-
else
|
131
|
-
Rails.logger.error("could not fetch #{type} feed for #{feed_title} at #{url}")
|
132
|
-
raise "Unexpected feed format for #{url}."
|
133
172
|
end
|
134
|
-
|
173
|
+
|
135
174
|
return contents
|
136
175
|
end
|
137
176
|
|
@@ -162,7 +201,8 @@ class SimpleRss < DynamicContent
|
|
162
201
|
end
|
163
202
|
|
164
203
|
# fetch the feed, return the type, title, and contents (parsed) and raw feed (unparsed)
|
165
|
-
def fetch_feed(url)
|
204
|
+
def fetch_feed(url, url_userid, url_password)
|
205
|
+
require 'encryptor'
|
166
206
|
require 'rss'
|
167
207
|
require 'open-uri'
|
168
208
|
|
@@ -171,28 +211,35 @@ class SimpleRss < DynamicContent
|
|
171
211
|
rss = nil
|
172
212
|
feed = nil
|
173
213
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
Rails.logger.debug("unable to fetch or parse feed - #{url}, #{e.message}")
|
185
|
-
rss = e.message
|
186
|
-
else
|
187
|
-
type = rss.feed_type.upcase
|
214
|
+
unless url.blank?
|
215
|
+
begin
|
216
|
+
# cache same url for 1 minute to alleviate redundant calls when previewing
|
217
|
+
feed = Rails.cache.fetch(url, :expires_in => 1.minute) do
|
218
|
+
if url_userid.blank? or url_password.blank?
|
219
|
+
open(url).read()
|
220
|
+
else
|
221
|
+
open(url, http_basic_authentication: [url_userid, url_password]).read()
|
222
|
+
end
|
223
|
+
end
|
188
224
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
225
|
+
rss = RSS::Parser.parse(feed, false, true)
|
226
|
+
raise "feed could not be parsed" if rss.nil?
|
227
|
+
rescue => e
|
228
|
+
# cant parse rss or url is bad
|
229
|
+
Rails.logger.debug("unable to fetch or parse feed - #{url}, #{e.message}")
|
230
|
+
rss = e.message
|
231
|
+
type = "ERROR"
|
194
232
|
else
|
195
|
-
|
233
|
+
type = rss.feed_type.upcase
|
234
|
+
|
235
|
+
case type
|
236
|
+
when "RSS"
|
237
|
+
title = rss.channel.title
|
238
|
+
when "ATOM"
|
239
|
+
title = rss.title.content
|
240
|
+
else
|
241
|
+
#title = "unknown feed type"
|
242
|
+
end
|
196
243
|
end
|
197
244
|
end
|
198
245
|
|
@@ -238,16 +285,18 @@ class SimpleRss < DynamicContent
|
|
238
285
|
# Simple RSS processing needs a feed URL and the format of the output content.
|
239
286
|
def self.form_attributes
|
240
287
|
attributes = super()
|
241
|
-
attributes.concat([:config => [:url, :output_format, :reverse_order, :max_items, :xsl, :sanitize_tags]])
|
288
|
+
attributes.concat([:config => [:url, :url_userid, :url_password, :output_format, :reverse_order, :max_items, :xsl, :sanitize_tags]])
|
242
289
|
end
|
243
290
|
|
244
291
|
# if the feed is valid we store the title in config
|
245
292
|
def validate_feed
|
246
293
|
url = self.config['url']
|
294
|
+
url_userid = self.config['url_userid']
|
295
|
+
url_password = self.config['url_password']
|
247
296
|
unless url.blank?
|
248
|
-
Rails.logger.debug("looking up feed title for #{url}")
|
297
|
+
Rails.logger.debug("looking up feed title for #{url}")
|
249
298
|
|
250
|
-
type, title = fetch_feed(url)
|
299
|
+
type, title = fetch_feed(url, url_userid, url_password)
|
251
300
|
if (["RSS", "ATOM"].include? type) && !title.blank?
|
252
301
|
self.config['title'] = title
|
253
302
|
else
|
@@ -270,11 +319,13 @@ class SimpleRss < DynamicContent
|
|
270
319
|
errors.add(:base, "XSL Markup can't be blank when using the XSLT Display Format")
|
271
320
|
else
|
272
321
|
url = self.config['url']
|
322
|
+
url_userid = self.config['url_userid']
|
323
|
+
url_password = self.config['url_password']
|
273
324
|
unless url.blank?
|
274
325
|
require 'rexml/document'
|
275
326
|
require 'xml/xslt'
|
276
327
|
|
277
|
-
type, title, rss, raw = fetch_feed(url)
|
328
|
+
type, title, rss, raw = fetch_feed(url, url_userid, url_password)
|
278
329
|
if ["RSS", "ATOM"].include? type
|
279
330
|
begin
|
280
331
|
xslt = XML::XSLT.new()
|
@@ -295,6 +346,8 @@ class SimpleRss < DynamicContent
|
|
295
346
|
begin
|
296
347
|
o = SimpleRss.create()
|
297
348
|
o.config['url'] = data[:url]
|
349
|
+
o.config['url_userid'] = data[:url_userid]
|
350
|
+
o.config['url_password'] = data[:url_password]
|
298
351
|
o.config['output_format'] = data[:output_format]
|
299
352
|
o.config['max_items'] = data[:max_items]
|
300
353
|
o.config['reverse_order'] = data[:reverse_order]
|
@@ -6,9 +6,26 @@
|
|
6
6
|
<%= config.label :url %>
|
7
7
|
<div class="input">
|
8
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
|
-
<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
9
|
</div>
|
11
10
|
</div>
|
11
|
+
|
12
|
+
<div class="row-fluid">
|
13
|
+
<div class="span6">
|
14
|
+
<div class="clearfix span6">
|
15
|
+
<%= label_tooltip "simple_rss", :url_userid, t("activerecord.attributes.simple_rss.config_url_userid"), tip: t("basic_auth_tip") %>
|
16
|
+
<div class="input">
|
17
|
+
<%= config.text_field :url_userid, :class => "input-medium", autocomplete: :off %>
|
18
|
+
</div>
|
19
|
+
</div>
|
20
|
+
<div class="clearfix span6">
|
21
|
+
<%= config.label :url_password, t("activerecord.attributes.simple_rss.config_url_password") %>
|
22
|
+
<div class="input">
|
23
|
+
<%= config.password_field :url_password, :class => "input-medium", autocomplete: :off %>
|
24
|
+
</div>
|
25
|
+
</div>
|
26
|
+
</div>
|
27
|
+
</div>
|
28
|
+
|
12
29
|
<div class="clearfix">
|
13
30
|
<%= config.label :output_format, 'Display Format' %>
|
14
31
|
<div class="input">
|
@@ -1,9 +1,13 @@
|
|
1
1
|
module ConcertoSimpleRss
|
2
2
|
class Engine < ::Rails::Engine
|
3
|
+
require 'encryptor'
|
4
|
+
|
3
5
|
isolate_namespace ConcertoSimpleRss
|
4
6
|
|
5
7
|
initializer "register content type" do |app|
|
6
8
|
app.config.content_types << SimpleRss
|
9
|
+
|
10
|
+
Encryptor.default_options.merge!(key: ENV["SECRET_KEY_BASE"])
|
7
11
|
end
|
8
12
|
end
|
9
13
|
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.
|
4
|
+
version: '0.8'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Michalski
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-09-
|
11
|
+
date: 2015-09-24 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: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: encryptor
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: ruby-xslt
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -57,6 +71,7 @@ files:
|
|
57
71
|
- app/views/contents/simple_rss/_render_grid.html.erb
|
58
72
|
- app/views/contents/simple_rss/_render_tile.html.erb
|
59
73
|
- app/views/contents/simple_rss/_tab_icon.html.erb
|
74
|
+
- config/locales/en.yml
|
60
75
|
- config/routes.rb
|
61
76
|
- lib/concerto_simple_rss.rb
|
62
77
|
- lib/concerto_simple_rss/engine.rb
|
@@ -113,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
128
|
version: '0'
|
114
129
|
requirements: []
|
115
130
|
rubyforge_project:
|
116
|
-
rubygems_version: 2.
|
131
|
+
rubygems_version: 2.2.3
|
117
132
|
signing_key:
|
118
133
|
specification_version: 4
|
119
134
|
summary: RSS Dynamic Concerto for Concerto 2.
|