Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make DataOutputAgent serve RSS output as application/rss+xml #1973

Merged
merged 1 commit into from
Apr 19, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 6 additions & 1 deletion app/models/agents/data_output_agent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class DataOutputAgent < Agent
* `ttl` - A value for the \\<ttl\\> element in RSS output. (default: `60`)
* `ns_media` - Add [yahoo media namespace](https://en.wikipedia.org/wiki/Media_RSS) in output xml
* `ns_itunes` - Add [itunes compatible namespace](http://lists.apple.com/archives/syndication-dev/2005/Nov/msg00002.html) in output xml
* `rss_content_type` - Content-Type for RSS output (default: `application/rss+xml`)
* `push_hubs` - Set to a list of PubSubHubbub endpoints you want to publish an update to every time this agent receives an event. (default: none) Popular hubs include [Superfeedr](https://pubsubhubbub.superfeedr.com/) and [Google](https://pubsubhubbub.appspot.com/). Note that publishing updates will make your feed URL known to the public, so if you want to keep it secret, set up a reverse proxy to serve your feed via a safe URL and specify it in `template.self`.

If you'd like to output RSS tags with attributes, such as `enclosure`, use something like the following in your `template`:
Expand Down Expand Up @@ -165,6 +166,10 @@ def feed_description
interpolated['template']['description'].presence || "A feed of Events received by the '#{name}' Huginn Agent"
end

def rss_content_type
interpolated['rss_content_type'].presence || 'application/rss+xml'
end

def xml_namespace
namespaces = ['xmlns:atom="http://www.w3.org/2005/Atom"']

Expand Down Expand Up @@ -285,7 +290,7 @@ def receive_web_request(params, method, format)
.to_xml(skip_types: true, root: "items", skip_instruct: true, indent: 1)
.gsub(%r{^</?items>\n}, '')

return [<<-XML, 200, 'text/xml']
return [<<-XML, 200, rss_content_type]
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" #{xml_namespace}>
<channel>
Expand Down
18 changes: 18 additions & 0 deletions db/migrate/20170419073748_set_rss_content_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class SetRssContentType < ActiveRecord::Migration[5.0]
def up
Agents::DataOutputAgent.find_each do |agent|
if agent.options['rss_content_type'].nil?
agent.options['rss_content_type'] = 'text/xml'
agent.save(validate: false)
end
end
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be a down too?


def down
Agents::DataOutputAgent.find_each do |agent|
if agent.options.delete('rss_content_type')
agent.save(validate: false)
end
end
end
end
35 changes: 24 additions & 11 deletions spec/models/agents/data_output_agent_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@
stub(agent).feed_link { "https://yoursite.com" }
content, status, content_type = agent.receive_web_request({ 'secret' => 'secret1' }, 'get', 'text/xml')
expect(status).to eq(200)
expect(content_type).to eq('text/xml')
expect(content_type).to eq('application/rss+xml')
expect(content.gsub(/\s+/, '')).to eq Utils.unindent(<<-XML).gsub(/\s+/, '')
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
Expand Down Expand Up @@ -193,12 +193,25 @@
XML
end

describe "with cumstom rss_content_type given" do
before do
agent.options['rss_content_type'] = 'text/xml'
agent.save!
end

it "can output RSS with the Content-Type" do
content, status, content_type = agent.receive_web_request({ 'secret' => 'secret1' }, 'get', 'text/xml')
expect(status).to eq(200)
expect(content_type).to eq('text/xml')
end
end

it "can output RSS with hub links when push_hubs is specified" do
stub(agent).feed_link { "https://yoursite.com" }
agent.options[:push_hubs] = %w[https://pubsubhubbub.superfeedr.com/ https://pubsubhubbub.appspot.com/]
content, status, content_type = agent.receive_web_request({ 'secret' => 'secret1' }, 'get', 'text/xml')
expect(status).to eq(200)
expect(content_type).to eq('text/xml')
expect(content_type).to eq('application/rss+xml')
xml = Nokogiri::XML(content)
expect(xml.xpath('/rss/channel/atom:link[@rel="hub"]/@href').map(&:text).sort).to eq agent.options[:push_hubs].sort
end
Expand Down Expand Up @@ -314,7 +327,7 @@
stub(agent).feed_link { "https://yoursite.com" }
content, status, content_type = agent.receive_web_request({ 'secret' => 'secret1' }, 'get', 'text/xml')
expect(status).to eq(200)
expect(content_type).to eq('text/xml')
expect(content_type).to eq('application/rss+xml')
expect(Nokogiri(content).at('/rss/channel/title/text()').text).to eq('XKCD comics as a feed (XKCD)')
end

Expand Down Expand Up @@ -358,7 +371,7 @@
stub(agent).feed_link { "https://yoursite.com" }
content, status, content_type = agent.receive_web_request({ 'secret' => 'secret1' }, 'get', 'text/xml')
expect(status).to eq(200)
expect(content_type).to eq('text/xml')
expect(content_type).to eq('application/rss+xml')
expect(Nokogiri(content).at('/rss/channel/atom:icon/text()').text).to eq('https://somesite.com/icon.png')
end
end
Expand All @@ -373,7 +386,7 @@
stub(agent).feed_link { "https://yoursite.com" }
content, status, content_type = agent.receive_web_request({ 'secret' => 'secret1' }, 'get', 'text/xml')
expect(status).to eq(200)
expect(content_type).to eq('text/xml')
expect(content_type).to eq('application/rss+xml')

doc = Nokogiri(content)
namespaces = doc.collect_namespaces
Expand All @@ -391,7 +404,7 @@
stub(agent).feed_link { "https://yoursite.com" }
content, status, content_type = agent.receive_web_request({ 'secret' => 'secret1' }, 'get', 'text/xml')
expect(status).to eq(200)
expect(content_type).to eq('text/xml')
expect(content_type).to eq('application/rss+xml')

doc = Nokogiri(content)
namespaces = doc.collect_namespaces
Expand All @@ -411,7 +424,7 @@
stub(agent).feed_link { "https://yoursite.com" }
content, status, content_type = agent.receive_web_request({ 'secret' => 'secret1' }, 'get', 'text/xml')
expect(status).to eq(200)
expect(content_type).to eq('text/xml')
expect(content_type).to eq('application/rss+xml')

doc = Nokogiri(content)
namespaces = doc.collect_namespaces
Expand All @@ -429,7 +442,7 @@
stub(agent).feed_link { "https://yoursite.com" }
content, status, content_type = agent.receive_web_request({ 'secret' => 'secret1' }, 'get', 'text/xml')
expect(status).to eq(200)
expect(content_type).to eq('text/xml')
expect(content_type).to eq('application/rss+xml')

doc = Nokogiri(content)
namespaces = doc.collect_namespaces
Expand All @@ -447,7 +460,7 @@
stub(agent).feed_link { "https://yoursite.com" }
content, status, content_type = agent.receive_web_request({ 'secret' => 'secret1' }, 'get', 'text/xml')
expect(status).to eq(200)
expect(content_type).to eq('text/xml')
expect(content_type).to eq('application/rss+xml')

doc = Nokogiri(content)
namespaces = doc.collect_namespaces
Expand All @@ -467,7 +480,7 @@
stub(agent).feed_link { "https://yoursite.com" }
content, status, content_type = agent.receive_web_request({ 'secret' => 'secret1' }, 'get', 'text/xml')
expect(status).to eq(200)
expect(content_type).to eq('text/xml')
expect(content_type).to eq('application/rss+xml')

doc = Nokogiri(content)
namespaces = doc.collect_namespaces
Expand Down Expand Up @@ -569,7 +582,7 @@
stub(agent).feed_link { "https://yoursite.com" }
content, status, content_type = agent.receive_web_request({ 'secret' => 'secret1' }, 'get', 'text/xml')
expect(status).to eq(200)
expect(content_type).to eq('text/xml')
expect(content_type).to eq('application/rss+xml')
expect(content.gsub(/\s+/, '')).to eq Utils.unindent(<<-XML).gsub(/\s+/, '')
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" >
Expand Down