bercow 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,31 @@
1
+ # Bercow
2
+
3
+ Convert an RSS feed to a Podcast suitable for subscribing to in iTunes.
4
+
5
+ ## Installing
6
+
7
+ You need to setup [King](https://github.com/craigw/king) and the dependencies
8
+ for that.
9
+
10
+ ## Usage
11
+
12
+ I make a few assumptions for this example:
13
+
14
+ * That King is running at `http://10.0.1.200:4567/`.
15
+ * That your mp3 files will be hosted under `http://example.com/media/`.
16
+ * That your RSS feed is available at `http://blog.example.com/rss.xml`.
17
+
18
+ Run Bercow like this:
19
+
20
+ bercow \
21
+ --king http://10.0.1.200:4567/ \
22
+ --host http://example.com/media/ \
23
+ --rss http://blog.example.com/rss.xml \
24
+ --cache /var/www/example.com/htdocs/media
25
+
26
+ Obviously you'll need to put your own locations in for these options.
27
+
28
+
29
+ ## Authors
30
+
31
+ Craig R Webster <http://barkingiguana.com/>
@@ -0,0 +1,93 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ require "getoptlong"
4
+ require 'nokogiri'
5
+ require 'open-uri'
6
+ require 'digest/sha1'
7
+ require 'cgi'
8
+
9
+ options = {}
10
+ argv = GetoptLong.new(
11
+ [ "--broker", "-b", GetoptLong::OPTIONAL_ARGUMENT ],
12
+ [ "--rss", "-r", GetoptLong::REQUIRED_ARGUMENT ],
13
+ [ "--cache", "-c", GetoptLong::OPTIONAL_ARGUMENT ],
14
+ [ "--host", "-h", GetoptLong::REQUIRED_ARGUMENT ],
15
+ [ "--king", "-k", GetoptLong::OPTIONAL_ARGUMENT ],
16
+ [ "--verbose", "-v", GetoptLong::NO_ARGUMENT ]
17
+ )
18
+ argv.each do |option, value|
19
+ options['broker'] = value if option == '--broker'
20
+ options['rss'] = value if option == '--rss'
21
+ options['cache'] = value if option == '--cache'
22
+ options['host'] = value if option == '--host'
23
+ options['king'] = value if option == '--king'
24
+ options['verbose'] = true if option == '--verbose'
25
+ end
26
+ options['broker'] ||= 'stomp://127.0.0.1:61613'
27
+ options['king'] ||= 'http://127.0.0.1:4567/'
28
+ options['cache'] ||= File.expand_path('../tmp/cache', File.basename(__FILE__))
29
+
30
+ unless File.exists? options['cache']
31
+ puts "The cache directory does not exist: #{options['cache']}"
32
+ exit 1
33
+ end
34
+
35
+ remove_nodes = %w{
36
+ content:encoded
37
+ wfw:commentRss
38
+ slash:comments
39
+ description
40
+ category
41
+ }
42
+
43
+ rss = Nokogiri::XML open(options['rss']).read
44
+ items = rss.xpath '//channel/item'
45
+ items.to_a.each do |item|
46
+ item_link = item.xpath(".//link").to_a[0]
47
+ item_url = item_link.inner_text.to_s
48
+ article = CGI.escape item_url
49
+ url = URI.parse item_url
50
+ cache_key = Digest::SHA1.hexdigest item_url
51
+ file_dir = [ url.host, *(cache_key.scan(/(.)/)[0..3]) ].inject(options['cache']) { |a, e|
52
+ dir = File.join a, e
53
+ Dir.mkdir dir unless File.exists? dir
54
+ dir
55
+ }
56
+ file_path = File.join file_dir, cache_key + '.mp3'
57
+ url_path = file_path.gsub /^#{options['cache']}\//, ''
58
+ file_url = "#{options['host']}#{url_path}"
59
+ guid = item.xpath(".//guid").to_a[0]
60
+ guid.content = file_url
61
+ guid['isPermaLink'] = 'true'
62
+ remove_nodes.each do |node|
63
+ item.xpath(node).remove
64
+ end
65
+ enclosure = Nokogiri::XML::Node.new 'enclosure', rss
66
+ enclosure['url'] = file_url
67
+ enclosure['type'] = "audio/mpeg"
68
+ item << enclosure
69
+ next if File.exists? file_path
70
+ print "Encoding #{item_url}... " if options['verbose']
71
+ mp3 = open(options['king'] + 'read?url=' + article).read
72
+ File.open file_path, 'w+' do |f|
73
+ f.print mp3
74
+ end
75
+ puts "#{file_path}" if options['verbose']
76
+ end
77
+
78
+ rss.root.add_namespace_definition 'itunes', 'http://www.itunes.com/dtds/podcast-1.0.dtd'
79
+
80
+ rss_host = URI.parse(options['rss']).host
81
+ rss_url = "#{options['host']}#{rss_host}/rss.xml"
82
+ reference = rss.xpath("//channel/atom:link[@rel = 'self']").to_a[0]
83
+ reference['href'] = rss_url
84
+
85
+ rss_feed = File.join options['cache'], rss_host, 'rss.xml'
86
+ File.open rss_feed, 'w+' do |f|
87
+ f.print rss.to_s
88
+ end
89
+
90
+ if options['verbose']
91
+ iptc_url = rss_url.gsub /^http/, 'iptc'
92
+ puts "iTunes users can subscribe at #{iptc_url}"
93
+ end
@@ -0,0 +1 @@
1
+ require 'bach/version'
@@ -0,0 +1,3 @@
1
+ module Bercow
2
+ VERSION = '0.0.1'
3
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bercow
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Craig R Webster
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-10-08 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: stomp
16
+ requirement: &70179254038080 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70179254038080
25
+ - !ruby/object:Gem::Dependency
26
+ name: nokogiri
27
+ requirement: &70179254030200 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70179254030200
36
+ description: ''
37
+ email:
38
+ - craig@barkingiguana.com
39
+ executables:
40
+ - bercow
41
+ extensions: []
42
+ extra_rdoc_files: []
43
+ files:
44
+ - lib/bercow/version.rb
45
+ - lib/bercow.rb
46
+ - bin/bercow
47
+ - README.md
48
+ homepage:
49
+ licenses: []
50
+ post_install_message:
51
+ rdoc_options: []
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ! '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ requirements:
67
+ - A broker capable of talking Stomp
68
+ - A King server
69
+ rubyforge_project:
70
+ rubygems_version: 1.8.10
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: ''
74
+ test_files: []