bcms_bmedia_feeds 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +11 -0
- data/README.markdown +27 -0
- data/app/assets/javascripts/application.js +15 -0
- data/app/assets/javascripts/bcms_feeds/application.js +15 -0
- data/app/assets/stylesheets/application.css +13 -0
- data/app/assets/stylesheets/bcms_feeds/application.css +13 -0
- data/app/controllers/bcms_feeds/application_controller.rb +4 -0
- data/app/helpers/bcms_feeds/application_helper.rb +4 -0
- data/app/models/bcms_feeds/feed.rb +62 -0
- data/app/portlets/feed_portlet.rb +17 -0
- data/app/views/portlets/feed/_form.html.erb +11 -0
- data/app/views/portlets/feed/render.html.erb +12 -0
- data/config/routes.rb +2 -0
- data/db/migrate/20090813213104_add_feeds.rb +13 -0
- data/db/migrate/20100115202209_modify_feeds_table_to_use_mediumtext.rb +15 -0
- data/db/migrate/20120710201056_bcms_feeds_v2_0_0.rb +7 -0
- data/lib/bcms_bmedia_feeds.rb +5 -0
- data/lib/bcms_feeds/engine.rb +7 -0
- data/lib/bcms_feeds/version.rb +3 -0
- data/lib/generators/bcms_bmedia_feeds/install/USAGE +3 -0
- data/lib/generators/bcms_bmedia_feeds/install/install_generator.rb +23 -0
- data/lib/tasks/bcms_feeds_tasks.rake +4 -0
- metadata +113 -0
data/Gemfile
ADDED
data/README.markdown
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
Feed Module
|
2
|
+
==========
|
3
|
+
|
4
|
+
This is a fork of https://github.com/jonleighton/bcms_feeds which updates the module to work with BrowserCMS 3.5.x and later. It will be released as bcms_bmedia_feeds since the original gem is owned by jonleighton.
|
5
|
+
|
6
|
+
Overview
|
7
|
+
========
|
8
|
+
|
9
|
+
This is a BrowserCMS module which fetches, caches and displays RSS/Atom feeds.
|
10
|
+
|
11
|
+
Installation
|
12
|
+
============
|
13
|
+
|
14
|
+
For installation instructions see http://www.browsercms.org/doc/guides/html/installing_modules.html
|
15
|
+
|
16
|
+
$ gem install bcms_bmedia_feeds
|
17
|
+
$ rails g cms:install bcms_bmedia_feeds
|
18
|
+
|
19
|
+
To incorporate a feed in your page, add a Feed Portlet to a page. Specify the URL of the feed. You can use the code section to manipulate this data as necessary, and the template to format it. SimpleRSS [http://simple-rss.rubyforge.org/] is used for parsing, and a parsed version of the feed will be available in the @feed variable.
|
20
|
+
|
21
|
+
Feeds are cached in the database for 30 minutes. If there is a failure fetching a remote feed, the expiry time of the cached feed will be extended by 10 minutes. When fetching remote feeds, the timeout length is 10 seconds.
|
22
|
+
|
23
|
+
Issues
|
24
|
+
=====
|
25
|
+
|
26
|
+
* Escaping html - Feeds will often use HTML in their post bodies. If you decide the 3rd party site is 'trustworthy' enough to just render unescaped HTML from their site on, then you can unescape the XML. By default, its contents are shown as XML encoded bodies.
|
27
|
+
* Cached Pages - If a page with a feed portlet on it has been cached, it will not update with as much frequency as might be expected. You can solve this by turning off page caching for that page.
|
@@ -0,0 +1,15 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// the compiled file.
|
9
|
+
//
|
10
|
+
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
11
|
+
// GO AFTER THE REQUIRES BELOW.
|
12
|
+
//
|
13
|
+
//= require jquery
|
14
|
+
//= require jquery_ujs
|
15
|
+
//= require_tree .
|
@@ -0,0 +1,15 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// the compiled file.
|
9
|
+
//
|
10
|
+
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
11
|
+
// GO AFTER THE REQUIRES BELOW.
|
12
|
+
//
|
13
|
+
//= require jquery
|
14
|
+
//= require jquery_ujs
|
15
|
+
//= require_tree .
|
@@ -0,0 +1,13 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
9
|
+
* compiled file, but it's generally better to create a new file per style scope.
|
10
|
+
*
|
11
|
+
*= require_self
|
12
|
+
*= require_tree .
|
13
|
+
*/
|
@@ -0,0 +1,13 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
9
|
+
* compiled file, but it's generally better to create a new file per style scope.
|
10
|
+
*
|
11
|
+
*= require_self
|
12
|
+
*= require_tree .
|
13
|
+
*/
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'timeout'
|
3
|
+
require 'simple-rss'
|
4
|
+
|
5
|
+
module BcmsFeeds
|
6
|
+
class Feed < ActiveRecord::Base
|
7
|
+
TTL = 30.minutes
|
8
|
+
TTL_ON_ERROR = 10.minutes
|
9
|
+
TIMEOUT = 10 # In seconds
|
10
|
+
|
11
|
+
delegate :entries, :items, :to => :parsed_contents
|
12
|
+
attr_accessible :url, :contents, :expires_at
|
13
|
+
|
14
|
+
def parsed_contents
|
15
|
+
@parsed_contents ||= SimpleRSS.parse(contents)
|
16
|
+
end
|
17
|
+
|
18
|
+
def contents
|
19
|
+
if expires_at.nil? || expires_at < Time.now.utc
|
20
|
+
begin
|
21
|
+
self.expires_at = Time.now.utc + TTL
|
22
|
+
new_contents = remote_contents
|
23
|
+
SimpleRSS.parse(new_contents) # Check that we can actually parse it
|
24
|
+
write_attribute(:contents, new_contents)
|
25
|
+
save
|
26
|
+
rescue StandardError, Timeout::Error, SimpleRSSError => exception
|
27
|
+
logger.error("Loading feed #{url} failed with #{exception.inspect}")
|
28
|
+
self.expires_at = Time.now.utc + TTL_ON_ERROR
|
29
|
+
save
|
30
|
+
end
|
31
|
+
else
|
32
|
+
logger.info("Loading feed from cache: #{url}")
|
33
|
+
end
|
34
|
+
read_attribute(:contents)
|
35
|
+
end
|
36
|
+
|
37
|
+
def remote_contents
|
38
|
+
Timeout.timeout(TIMEOUT) {
|
39
|
+
simple_get(url)
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def simple_get(url)
|
46
|
+
logger.info("Loading feed from remote: #{url}")
|
47
|
+
parsed_url = URI.parse(url)
|
48
|
+
http = Net::HTTP.start(parsed_url.host, parsed_url.port)
|
49
|
+
response = http.request_get(url, 'User-Agent' => "BrowserCMS bcms_feed extension")
|
50
|
+
if response.is_a?(Net::HTTPSuccess)
|
51
|
+
return response.body
|
52
|
+
elsif response.is_a?(Net::HTTPRedirection)
|
53
|
+
logger.info("#{url} returned a redirect. Following . . ")
|
54
|
+
simple_get(response.header['Location'])
|
55
|
+
else
|
56
|
+
logger.info("#{url} returned a redirect. Following . . ")
|
57
|
+
raise StandardError
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class FeedPortlet < Cms::Portlet
|
2
|
+
handler "erb"
|
3
|
+
|
4
|
+
enable_template_editor true
|
5
|
+
|
6
|
+
def render
|
7
|
+
raise ArgumentError, "No feed URL specified" if self.url.blank?
|
8
|
+
@feed = BcmsFeeds::Feed.find_or_create_by_url(self.url).parsed_contents
|
9
|
+
if @portlet.limit.to_i != 0
|
10
|
+
@items = @feed.items[0..(@portlet.limit.to_i - 1)]
|
11
|
+
else
|
12
|
+
@items = @feed.items
|
13
|
+
end
|
14
|
+
instance_eval(self.code) unless self.code.blank?
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<%= f.cms_text_field :name %>
|
2
|
+
<%= f.cms_text_field :url %>
|
3
|
+
<%= f.cms_text_area :code %>
|
4
|
+
<%= f.cms_drop_down :limit,
|
5
|
+
[
|
6
|
+
['Unlimited','0'],['1','1'],['2','2'],['3','3'],['4','4'],['5','5'],['6','6'],['7','7'],['8','8'],['9','9'],
|
7
|
+
['10','10'],['11','11'],['12','12'],['13','13'],['14','14'],['15','15'],['16','16'],['17','17'],['18','18'],['19','19'],
|
8
|
+
['20','20']
|
9
|
+
], :instructions => 'Items are available in the @items array and will be limited to the number you select above. You can still access the items via @feed.items, but they will not have a limit applied to them for backwards compatibility.'
|
10
|
+
%>
|
11
|
+
<%= f.cms_template_editor :template %>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<div class="feed-list feed-number-<%= @portlet.id %>">
|
2
|
+
<h1><%= @feed.title %></h1>
|
3
|
+
<ul>
|
4
|
+
<% @items.each do |item| %>
|
5
|
+
<li>
|
6
|
+
<div class="title"><%= link_to item.title, item.link %></div>
|
7
|
+
<div class="description"><%= item.description %></div>
|
8
|
+
<div class="item-meta">by <%= item.dc_creator %> on <%= item.pubDate %></div>
|
9
|
+
</li>
|
10
|
+
<% end %>
|
11
|
+
</ul>
|
12
|
+
</div>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
class ModifyFeedsTableToUseMediumtext < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
if BcmsFeeds::Feed.connection.adapter_name == 'MySQL'
|
4
|
+
#The postgres text column suffices, and this syntax and column type don't work in pg.
|
5
|
+
execute "ALTER TABLE feeds MODIFY COLUMN contents MEDIUMTEXT"
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.down
|
10
|
+
if BcmsFeeds::Feed.connection.adapter_name == 'MySQL'
|
11
|
+
#The postgres text column suffices, and this syntax and column type don't work in pg.
|
12
|
+
execute "ALTER TABLE feeds MODIFY COLUMN contents TEXT"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'cms/module_installation'
|
2
|
+
|
3
|
+
module BcmsBmediaFeeds
|
4
|
+
end
|
5
|
+
class BcmsBmediaFeeds::InstallGenerator < Cms::ModuleInstallation
|
6
|
+
add_migrations_directory_to_source_root __FILE__
|
7
|
+
|
8
|
+
|
9
|
+
def copy_migrations
|
10
|
+
rake 'bcms_feeds:install:migrations'
|
11
|
+
end
|
12
|
+
|
13
|
+
# Uncomment to add module specific seed data to a project.
|
14
|
+
#def add_seed_data_to_project
|
15
|
+
# copy_file "../bcms_feeds.seeds.rb", "db/bcms_feeds.seeds.rb"
|
16
|
+
# append_to_file "db/seeds.rb", "load File.expand_path('../bcms_feeds.seeds.rb', __FILE__)\n"
|
17
|
+
#end
|
18
|
+
|
19
|
+
def add_routes
|
20
|
+
mount_engine(BcmsFeeds)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bcms_bmedia_feeds
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jon Leighton
|
9
|
+
- BrowserMedia
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2012-07-10 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: browsercms
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - <
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 3.6.0
|
23
|
+
- - ! '>='
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: 3.5.0
|
26
|
+
type: :runtime
|
27
|
+
prerelease: false
|
28
|
+
version_requirements: !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - <
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 3.6.0
|
34
|
+
- - ! '>='
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 3.5.0
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: simple-rss
|
39
|
+
requirement: !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: 1.2.3
|
45
|
+
type: :runtime
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: !ruby/object:Gem::Requirement
|
48
|
+
none: false
|
49
|
+
requirements:
|
50
|
+
- - ~>
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 1.2.3
|
53
|
+
description: A BrowserCMS module which fetches, caches and displays RSS/Atom feeds
|
54
|
+
email: github@browsermedia.com
|
55
|
+
executables: []
|
56
|
+
extensions: []
|
57
|
+
extra_rdoc_files:
|
58
|
+
- README.markdown
|
59
|
+
files:
|
60
|
+
- app/assets/javascripts/application.js
|
61
|
+
- app/assets/javascripts/bcms_feeds/application.js
|
62
|
+
- app/assets/stylesheets/application.css
|
63
|
+
- app/assets/stylesheets/bcms_feeds/application.css
|
64
|
+
- app/controllers/bcms_feeds/application_controller.rb
|
65
|
+
- app/helpers/bcms_feeds/application_helper.rb
|
66
|
+
- app/models/bcms_feeds/feed.rb
|
67
|
+
- app/portlets/feed_portlet.rb
|
68
|
+
- app/views/portlets/feed/_form.html.erb
|
69
|
+
- app/views/portlets/feed/render.html.erb
|
70
|
+
- config/routes.rb
|
71
|
+
- db/migrate/20090813213104_add_feeds.rb
|
72
|
+
- db/migrate/20100115202209_modify_feeds_table_to_use_mediumtext.rb
|
73
|
+
- db/migrate/20120710201056_bcms_feeds_v2_0_0.rb
|
74
|
+
- lib/bcms_bmedia_feeds.rb
|
75
|
+
- lib/bcms_feeds/engine.rb
|
76
|
+
- lib/bcms_feeds/version.rb
|
77
|
+
- lib/generators/bcms_bmedia_feeds/install/install_generator.rb
|
78
|
+
- lib/generators/bcms_bmedia_feeds/install/USAGE
|
79
|
+
- lib/tasks/bcms_feeds_tasks.rake
|
80
|
+
- README.markdown
|
81
|
+
- Gemfile
|
82
|
+
homepage: http://www.github.com/browsermedia/bcms_feeds
|
83
|
+
licenses: []
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options:
|
86
|
+
- --charset=UTF-8
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ! '>='
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
segments:
|
96
|
+
- 0
|
97
|
+
hash: -4420423868363560329
|
98
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
+
none: false
|
100
|
+
requirements:
|
101
|
+
- - ! '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
segments:
|
105
|
+
- 0
|
106
|
+
hash: -4420423868363560329
|
107
|
+
requirements: []
|
108
|
+
rubyforge_project:
|
109
|
+
rubygems_version: 1.8.24
|
110
|
+
signing_key:
|
111
|
+
specification_version: 3
|
112
|
+
summary: Feeds in BrowserCMS
|
113
|
+
test_files: []
|