2006-02-14 20:50:57 +00:00
|
|
|
#!/opt/local/bin/ruby
|
|
|
|
|
|
2006-02-14 20:53:13 +00:00
|
|
|
# $Id$
|
|
|
|
|
# $URL$
|
2006-02-14 20:50:57 +00:00
|
|
|
|
|
|
|
|
#
|
|
|
|
|
# Copyright (c) 2006 Ward Wouts <ward@wouts.nl>
|
|
|
|
|
#
|
|
|
|
|
# Permission to use, copy, modify, and distribute this software for any
|
|
|
|
|
# purpose with or without fee is hereby granted, provided that the above
|
|
|
|
|
# copyright notice and this permission notice appear in all copies.
|
|
|
|
|
#
|
|
|
|
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
|
|
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
|
|
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
|
|
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
|
|
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
|
|
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
|
|
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
|
#
|
|
|
|
|
|
|
|
|
|
podcasts = {
|
|
|
|
|
"distortedview" => {
|
|
|
|
|
"rss" => 'http://www.distortedview.com/show/index.xml',
|
|
|
|
|
"savedir" => '/Users/ward/ipod_sync/[books]/Distorted View',
|
|
|
|
|
"rename" => [ /_(\d\d\d\d)(\d\d)/, '\2\1' ],
|
|
|
|
|
},
|
|
|
|
|
"tagesschau" => {
|
|
|
|
|
"rss" => 'http://www.tagesschau.de/export/podcast',
|
|
|
|
|
"savedir" => '/Users/ward/ipod_sync/[books]/Tagesschau',
|
|
|
|
|
"delete" => true,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
require 'net/http'
|
|
|
|
|
require 'uri'
|
|
|
|
|
require 'rexml/document'
|
|
|
|
|
|
|
|
|
|
def fetch(uri_str, limit = 10)
|
|
|
|
|
# You should choose better exception.
|
|
|
|
|
raise ArgumentError, 'HTTP redirect too deep' if limit == 0
|
|
|
|
|
|
|
|
|
|
response = Net::HTTP.get_response(URI.parse(uri_str))
|
|
|
|
|
case response
|
|
|
|
|
when Net::HTTPSuccess then response
|
|
|
|
|
when Net::HTTPRedirection then fetch(response['location'], limit - 1)
|
|
|
|
|
else
|
|
|
|
|
response.error!
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
for podcast in podcasts.keys.sort
|
|
|
|
|
puts podcast
|
|
|
|
|
res = fetch(podcasts[podcast]["rss"])
|
|
|
|
|
filelist = {}
|
|
|
|
|
|
|
|
|
|
xmldoc = REXML::Document.new(res.body)
|
|
|
|
|
xmldoc.elements.each("rss/channel/*/enclosure") {|x|
|
|
|
|
|
if ! x.attribute("url").nil?
|
|
|
|
|
cast = x.attribute("url").to_s.dup
|
|
|
|
|
filename = cast.dup
|
|
|
|
|
filename.sub!(/^.*\//, "")
|
|
|
|
|
if podcasts[podcast]["rename"]
|
|
|
|
|
filename.sub!(podcasts[podcast]["rename"][0], podcasts[podcast]["rename"][1])
|
|
|
|
|
end
|
|
|
|
|
filelist[filename] = true
|
|
|
|
|
if ! File.exists?("#{podcasts[podcast]["savedir"]}/#{filename}")
|
|
|
|
|
puts "gotta get #{podcasts[podcast]["savedir"]}/#{filename}"
|
|
|
|
|
response = fetch(cast)
|
|
|
|
|
File.open("#{podcasts[podcast]["savedir"]}/#{filename}", "w"){|f|
|
|
|
|
|
f.print(response.body)
|
|
|
|
|
}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
}
|
|
|
|
|
if podcasts[podcast]["delete"]
|
|
|
|
|
Dir.open(podcasts[podcast]["savedir"]).each {|entry|
|
|
|
|
|
if File.file?("#{podcasts[podcast]["savedir"]}/#{entry}") &&
|
|
|
|
|
! filelist[entry]
|
|
|
|
|
puts "deleting #{entry}"
|
|
|
|
|
File.unlink("#{podcasts[podcast]["savedir"]}/#{entry}")
|
|
|
|
|
end
|
|
|
|
|
}
|
|
|
|
|
end
|
|
|
|
|
end
|