Make itunes compatible optional (#1411)

* Make itunes compatible optional

in generated xml

* Add tests + migration

* Description change

as per comment

Irfan Charania 8 years ago
parent
commit
50aff67a8a

+ 17 - 2
app/models/agents/data_output_agent.rb

@@ -24,6 +24,8 @@ module Agents
24 24
           * `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.
25 25
           * `events_to_show` - The number of events to output in RSS or JSON. (default: `40`)
26 26
           * `ttl` - A value for the \\<ttl\\> element in RSS output. (default: `60`)
27
+          * `ns_media` - Add [yahoo media namespace](https://en.wikipedia.org/wiki/Media_RSS) in output xml
28
+          * `ns_itunes` - Add [itunes compatible namespace](http://lists.apple.com/archives/syndication-dev/2005/Nov/msg00002.html) in output xml
27 29
           * `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`.
28 30
 
29 31
         If you'd like to output RSS tags with attributes, such as `enclosure`, use something like the following in your `template`:
@@ -68,7 +70,8 @@ module Agents
68 70
             "description" => "Secret hovertext: {{hovertext}}",
69 71
             "link" => "{{url}}"
70 72
           }
71
-        }
73
+        },
74
+        "ns_media" => "true"
72 75
       }
73 76
     end
74 77
 
@@ -156,6 +159,18 @@ module Agents
156 159
       interpolated['template']['description'].presence || "A feed of Events received by the '#{name}' Huginn Agent"
157 160
     end
158 161
 
162
+    def xml_namespace
163
+      namespaces = ['xmlns:atom="http://www.w3.org/2005/Atom"']
164
+
165
+      if (boolify(interpolated['ns_media']))
166
+        namespaces << 'xmlns:media="http://search.yahoo.com/mrss/"'
167
+      end
168
+      if (boolify(interpolated['ns_itunes']))
169
+        namespaces << 'xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"'
170
+      end
171
+      namespaces.join(' ')
172
+    end
173
+
159 174
     def push_hubs
160 175
       interpolated['push_hubs'].presence || []
161 176
     end
@@ -214,7 +229,7 @@ module Agents
214 229
 
215 230
           return [<<-XML, 200, 'text/xml']
216 231
 <?xml version="1.0" encoding="UTF-8" ?>
217
-<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">
232
+<rss version="2.0" #{xml_namespace}>
218 233
 <channel>
219 234
  <atom:link href=#{feed_url(secret: params['secret'], format: :xml).encode(xml: :attr)} rel="self" type="application/rss+xml" />
220 235
  <atom:icon>#{feed_icon.encode(xml: :text)}</atom:icon>

+ 17 - 0
db/migrate/20160423163416_add_xml_namespace_option_to_data_output_agents.rb

@@ -0,0 +1,17 @@
1
+class AddXmlNamespaceOptionToDataOutputAgents < ActiveRecord::Migration
2
+  def up
3
+    Agents::DataOutputAgent.find_each do |agent|
4
+      agent.options['ns_media'] = 'true'
5
+      agent.options['ns_itunes'] = 'true'
6
+      agent.save!(validate: false)
7
+    end
8
+  end
9
+
10
+  def down
11
+    Agents::DataOutputAgent.find_each do |agent|
12
+      agent.options.delete 'ns_media'
13
+      agent.options.delete 'ns_itunes'
14
+      agent.save!(validate: false)
15
+    end
16
+  end
17
+end

+ 114 - 2
spec/models/agents/data_output_agent_spec.rb

@@ -153,7 +153,7 @@ describe Agents::DataOutputAgent do
153 153
         expect(content_type).to eq('text/xml')
154 154
         expect(content.gsub(/\s+/, '')).to eq Utils.unindent(<<-XML).gsub(/\s+/, '')
155 155
           <?xml version="1.0" encoding="UTF-8" ?>
156
-          <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">
156
+          <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
157 157
           <channel>
158 158
            <atom:link href="https://yoursite.com/users/#{agent.user.id}/web_requests/#{agent.id}/secret1.xml" rel="self" type="application/rss+xml"/>
159 159
            <atom:icon>https://yoursite.com/favicon.ico</atom:icon>
@@ -294,6 +294,118 @@ describe Agents::DataOutputAgent do
294 294
           expect(Nokogiri(content).at('/rss/channel/atom:icon/text()').text).to eq('https://somesite.com/icon.png')
295 295
         end
296 296
       end
297
+
298
+      describe "with media namespace not set" do
299
+        before do
300
+          agent.options['ns_media'] = nil
301
+          agent.save!
302
+        end
303
+
304
+        it "can output RSS" do
305
+          stub(agent).feed_link { "https://yoursite.com" }
306
+          content, status, content_type = agent.receive_web_request({ 'secret' => 'secret1' }, 'get', 'text/xml')
307
+          expect(status).to eq(200)
308
+          expect(content_type).to eq('text/xml')
309
+
310
+          doc = Nokogiri(content)
311
+          namespaces = doc.collect_namespaces
312
+          expect(namespaces).not_to include("xmlns:media")
313
+        end
314
+      end
315
+
316
+      describe "with media namespace set true" do
317
+        before do
318
+          agent.options['ns_media'] = 'true'
319
+          agent.save!
320
+        end
321
+
322
+        it "can output RSS" do
323
+          stub(agent).feed_link { "https://yoursite.com" }
324
+          content, status, content_type = agent.receive_web_request({ 'secret' => 'secret1' }, 'get', 'text/xml')
325
+          expect(status).to eq(200)
326
+          expect(content_type).to eq('text/xml')
327
+
328
+          doc = Nokogiri(content)
329
+          namespaces = doc.collect_namespaces
330
+          expect(namespaces).to include(
331
+            "xmlns:media" => 'http://search.yahoo.com/mrss/'
332
+          )
333
+        end
334
+      end
335
+
336
+      describe "with media namespace set false" do
337
+        before do
338
+          agent.options['ns_media'] = 'false'
339
+          agent.save!
340
+        end
341
+
342
+        it "can output RSS" do
343
+          stub(agent).feed_link { "https://yoursite.com" }
344
+          content, status, content_type = agent.receive_web_request({ 'secret' => 'secret1' }, 'get', 'text/xml')
345
+          expect(status).to eq(200)
346
+          expect(content_type).to eq('text/xml')
347
+
348
+          doc = Nokogiri(content)
349
+          namespaces = doc.collect_namespaces
350
+          expect(namespaces).not_to include("xmlns:media")
351
+        end
352
+      end
353
+
354
+      describe "with itunes namespace not set" do
355
+        before do
356
+          agent.options['ns_itunes'] = nil
357
+          agent.save!
358
+        end
359
+
360
+        it "can output RSS" do
361
+          stub(agent).feed_link { "https://yoursite.com" }
362
+          content, status, content_type = agent.receive_web_request({ 'secret' => 'secret1' }, 'get', 'text/xml')
363
+          expect(status).to eq(200)
364
+          expect(content_type).to eq('text/xml')
365
+
366
+          doc = Nokogiri(content)
367
+          namespaces = doc.collect_namespaces
368
+          expect(namespaces).not_to include("xmlns:itunes")
369
+        end
370
+      end
371
+
372
+      describe "with itunes namespace set true" do
373
+        before do
374
+          agent.options['ns_itunes'] = 'true'
375
+          agent.save!
376
+        end
377
+
378
+        it "can output RSS" do
379
+          stub(agent).feed_link { "https://yoursite.com" }
380
+          content, status, content_type = agent.receive_web_request({ 'secret' => 'secret1' }, 'get', 'text/xml')
381
+          expect(status).to eq(200)
382
+          expect(content_type).to eq('text/xml')
383
+
384
+          doc = Nokogiri(content)
385
+          namespaces = doc.collect_namespaces
386
+          expect(namespaces).to include(
387
+            "xmlns:itunes" => 'http://www.itunes.com/dtds/podcast-1.0.dtd'
388
+          )
389
+        end
390
+      end
391
+
392
+      describe "with itunes namespace set false" do
393
+        before do
394
+          agent.options['ns_itunes'] = 'false'
395
+          agent.save!
396
+        end
397
+
398
+        it "can output RSS" do
399
+          stub(agent).feed_link { "https://yoursite.com" }
400
+          content, status, content_type = agent.receive_web_request({ 'secret' => 'secret1' }, 'get', 'text/xml')
401
+          expect(status).to eq(200)
402
+          expect(content_type).to eq('text/xml')
403
+
404
+          doc = Nokogiri(content)
405
+          namespaces = doc.collect_namespaces
406
+          expect(namespaces).not_to include("xmlns:itunes")
407
+        end
408
+      end
297 409
     end
298 410
 
299 411
     describe "outputting nesting" do
@@ -392,7 +504,7 @@ describe Agents::DataOutputAgent do
392 504
         expect(content_type).to eq('text/xml')
393 505
         expect(content.gsub(/\s+/, '')).to eq Utils.unindent(<<-XML).gsub(/\s+/, '')
394 506
           <?xml version="1.0" encoding="UTF-8" ?>
395
-          <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">
507
+          <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" >
396 508
           <channel>
397 509
            <atom:link href="https://yoursite.com/users/#{agent.user.id}/web_requests/#{agent.id}/secret1.xml" rel="self" type="application/rss+xml"/>
398 510
            <atom:icon>https://yoursite.com/favicon.ico</atom:icon>