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 itunes compatible optional #1411

Merged
merged 3 commits into from
Apr 30, 2016
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions app/models/agents/data_output_agent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class DataOutputAgent < Agent
* `template` - A JSON object representing a mapping between item output keys and incoming event values. Use [Liquid](https://github.com/cantino/huginn/wiki/Formatting-Events-using-Liquid) to format the values. Values of the `link`, `title`, `description` and `icon` keys will be put into the \\<channel\\> section of RSS output. Value of the `self` key will be used as URL for this feed itself, which is useful when you serve it via reverse proxy. The `item` key will be repeated for every Event. The `pubDate` key for each item will have the creation time of the Event unless given.
* `events_to_show` - The number of events to output in RSS or JSON. (default: `40`)
* `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
* `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 @@ -68,7 +70,8 @@ def default_options
"description" => "Secret hovertext: {{hovertext}}",
"link" => "{{url}}"
}
}
},
"ns_media" => "true"
}
end

Expand Down Expand Up @@ -156,6 +159,18 @@ def feed_description
interpolated['template']['description'].presence || "A feed of Events received by the '#{name}' Huginn Agent"
end

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

if (boolify(interpolated['ns_media']))
namespaces << 'xmlns:media="http://search.yahoo.com/mrss/"'
end
if (boolify(interpolated['ns_itunes']))
namespaces << 'xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"'
end
namespaces.join(' ')
end

def push_hubs
interpolated['push_hubs'].presence || []
end
Expand Down Expand Up @@ -214,7 +229,7 @@ def receive_web_request(params, method, format)

return [<<-XML, 200, 'text/xml']
<?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/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">
<rss version="2.0" #{xml_namespace}>
<channel>
<atom:link href=#{feed_url(secret: params['secret'], format: :xml).encode(xml: :attr)} rel="self" type="application/rss+xml" />
<atom:icon>#{feed_icon.encode(xml: :text)}</atom:icon>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class AddXmlNamespaceOptionToDataOutputAgents < ActiveRecord::Migration
def up
Agents::DataOutputAgent.find_each do |agent|
agent.options['ns_media'] = 'true'
agent.options['ns_itunes'] = 'true'
agent.save!(validate: false)
end
end

def down
Agents::DataOutputAgent.find_each do |agent|
agent.options.delete 'ns_media'
agent.options.delete 'ns_itunes'
agent.save!(validate: false)
end
end
end
116 changes: 114 additions & 2 deletions spec/models/agents/data_output_agent_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@
expect(content_type).to eq('text/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/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
<channel>
<atom:link href="https://yoursite.com/users/#{agent.user.id}/web_requests/#{agent.id}/secret1.xml" rel="self" type="application/rss+xml"/>
<atom:icon>https://yoursite.com/favicon.ico</atom:icon>
Expand Down Expand Up @@ -294,6 +294,118 @@
expect(Nokogiri(content).at('/rss/channel/atom:icon/text()').text).to eq('https://somesite.com/icon.png')
end
end

describe "with media namespace not set" do
before do
agent.options['ns_media'] = nil
agent.save!
end

it "can output RSS" do
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')

doc = Nokogiri(content)
namespaces = doc.collect_namespaces
expect(namespaces).not_to include("xmlns:media")
end
end

describe "with media namespace set true" do
before do
agent.options['ns_media'] = 'true'
agent.save!
end

it "can output RSS" do
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')

doc = Nokogiri(content)
namespaces = doc.collect_namespaces
expect(namespaces).to include(
"xmlns:media" => 'http://search.yahoo.com/mrss/'
)
end
end

describe "with media namespace set false" do
before do
agent.options['ns_media'] = 'false'
agent.save!
end

it "can output RSS" do
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')

doc = Nokogiri(content)
namespaces = doc.collect_namespaces
expect(namespaces).not_to include("xmlns:media")
end
end

describe "with itunes namespace not set" do
before do
agent.options['ns_itunes'] = nil
agent.save!
end

it "can output RSS" do
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')

doc = Nokogiri(content)
namespaces = doc.collect_namespaces
expect(namespaces).not_to include("xmlns:itunes")
end
end

describe "with itunes namespace set true" do
before do
agent.options['ns_itunes'] = 'true'
agent.save!
end

it "can output RSS" do
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')

doc = Nokogiri(content)
namespaces = doc.collect_namespaces
expect(namespaces).to include(
"xmlns:itunes" => 'http://www.itunes.com/dtds/podcast-1.0.dtd'
)
end
end

describe "with itunes namespace set false" do
before do
agent.options['ns_itunes'] = 'false'
agent.save!
end

it "can output RSS" do
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')

doc = Nokogiri(content)
namespaces = doc.collect_namespaces
expect(namespaces).not_to include("xmlns:itunes")
end
end
end

describe "outputting nesting" do
Expand Down Expand Up @@ -392,7 +504,7 @@
expect(content_type).to eq('text/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/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" >
<channel>
<atom:link href="https://yoursite.com/users/#{agent.user.id}/web_requests/#{agent.id}/secret1.xml" rel="self" type="application/rss+xml"/>
<atom:icon>https://yoursite.com/favicon.ico</atom:icon>
Expand Down