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.
|
|
|
|
|
#
|
|
|
|
|
|
2006-02-18 11:08:33 +00:00
|
|
|
########################################
|
|
|
|
|
# the configuration bit
|
|
|
|
|
|
2006-02-14 21:13:55 +00:00
|
|
|
@podcasts = {
|
2006-02-18 11:08:33 +00:00
|
|
|
# the podcast name
|
2006-02-14 20:50:57 +00:00
|
|
|
"distortedview" => {
|
2006-02-18 11:08:33 +00:00
|
|
|
# where's the rss file
|
2006-02-14 20:50:57 +00:00
|
|
|
"rss" => 'http://www.distortedview.com/show/index.xml',
|
2006-02-18 11:08:33 +00:00
|
|
|
# where should enclosures be saved
|
|
|
|
|
"savedir" => '/Users/ward/Private/mp3/[books]/Distorted View',
|
|
|
|
|
# rename magic, this is used on the file name with sub!
|
2006-02-14 20:50:57 +00:00
|
|
|
"rename" => [ /_(\d\d\d\d)(\d\d)/, '\2\1' ],
|
2006-02-18 11:08:33 +00:00
|
|
|
# directory to put symlinks to the new files
|
|
|
|
|
"linkdir" => '/Users/ward/ipod_sync/[books]/Distorted View',
|
2006-03-15 12:20:03 +00:00
|
|
|
# option to write an m3u file after fetching the mp3s
|
|
|
|
|
"m3u" => '/Users/ward/dv.m3u',
|
2006-02-14 20:50:57 +00:00
|
|
|
},
|
2006-07-04 11:55:23 +00:00
|
|
|
# "tagesschau" => {
|
|
|
|
|
# "rss" => 'http://www.tagesschau.de/export/podcast',
|
|
|
|
|
# "savedir" => '/Users/ward/ipod_sync/[books]/Tagesschau',
|
|
|
|
|
# # delete files that aren't in the rss anylonger
|
|
|
|
|
# "delete" => true,
|
|
|
|
|
# },
|
2006-04-16 19:26:24 +00:00
|
|
|
"pennradio" => {
|
2006-07-08 09:34:27 +00:00
|
|
|
# "rss" => 'http://www.923freefm.com/pages/podcast/80.rss',
|
|
|
|
|
"rss" => 'http://penn.freefm.com/pages/podcast/431.rss',
|
2006-04-16 19:26:24 +00:00
|
|
|
# %%DATE%% is a magic word here, gets replaced by the pubdate in
|
|
|
|
|
# YYYYMMDD format. Won't work if there is no pubDate in the rss feed
|
|
|
|
|
"rename" => [ /^/, '%%DATE%%-' ],
|
|
|
|
|
"savedir" => '/Users/ward/Private/mp3/[books]/PennRadio',
|
|
|
|
|
"linkdir" => '/Users/ward/ipod_sync/[books]/PennRadio',
|
|
|
|
|
},
|
2006-02-14 20:50:57 +00:00
|
|
|
}
|
|
|
|
|
|
2006-02-18 11:08:33 +00:00
|
|
|
########################################
|
|
|
|
|
# code from here on
|
|
|
|
|
|
2006-02-14 20:50:57 +00:00
|
|
|
require 'net/http'
|
|
|
|
|
require 'uri'
|
|
|
|
|
require 'rexml/document'
|
2006-04-16 19:26:24 +00:00
|
|
|
require 'date'
|
2006-02-14 20:50:57 +00:00
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
2006-02-14 21:13:55 +00:00
|
|
|
def deleteold(podcast)
|
|
|
|
|
Dir.open(@podcasts[podcast]["savedir"]).each {|entry|
|
|
|
|
|
if File.file?("#{@podcasts[podcast]["savedir"]}/#{entry}") &&
|
|
|
|
|
! @filelist[entry]
|
2006-02-17 13:36:07 +00:00
|
|
|
puts " deleting #{entry}"
|
2006-02-14 21:13:55 +00:00
|
|
|
File.unlink("#{@podcasts[podcast]["savedir"]}/#{entry}")
|
|
|
|
|
end
|
|
|
|
|
}
|
|
|
|
|
end
|
|
|
|
|
|
2006-04-16 19:26:24 +00:00
|
|
|
def getenclosure(podcast, item)
|
|
|
|
|
enclosure = item.get_elements("enclosure")[0]
|
|
|
|
|
pubdate = item.get_elements("pubDate")[0]
|
|
|
|
|
date = nil
|
|
|
|
|
if ! enclosure.nil?
|
|
|
|
|
end
|
|
|
|
|
if ! pubdate.nil?
|
|
|
|
|
date = Date.parse(pubdate.text).strftime("%Y%m%d")
|
|
|
|
|
end
|
|
|
|
|
if ! enclosure.nil? && ! enclosure.attribute("url").nil?
|
2006-02-14 21:27:42 +00:00
|
|
|
cast = enclosure.attribute("url").to_s.dup
|
|
|
|
|
filename = cast.dup
|
|
|
|
|
filename.sub!(/^.*\//, "")
|
|
|
|
|
if @podcasts[podcast]["rename"]
|
2006-04-16 19:26:24 +00:00
|
|
|
replacement = @podcasts[podcast]["rename"][1].dup
|
|
|
|
|
if replacement.match(/%%DATE%%/)
|
|
|
|
|
replacement.sub!(/%%DATE%%/, date)
|
|
|
|
|
end
|
|
|
|
|
filename.sub!(@podcasts[podcast]["rename"][0], replacement)
|
2006-02-14 21:27:42 +00:00
|
|
|
end
|
|
|
|
|
@filelist[filename] = true
|
|
|
|
|
if ! File.exists?("#{@podcasts[podcast]["savedir"]}/#{filename}")
|
2006-02-17 13:36:07 +00:00
|
|
|
puts " getting #{@podcasts[podcast]["savedir"]}/#{filename}"
|
2006-03-15 12:00:53 +00:00
|
|
|
begin
|
|
|
|
|
response = fetch(cast)
|
|
|
|
|
File.open("#{@podcasts[podcast]["savedir"]}/#{filename}", "w"){|f|
|
|
|
|
|
f.print(response.body)
|
|
|
|
|
}
|
|
|
|
|
if @podcasts[podcast]["linkdir"]
|
|
|
|
|
File.symlink("#{@podcasts[podcast]["savedir"]}/#{filename}", "#{@podcasts[podcast]["linkdir"]}/#{filename}")
|
|
|
|
|
end
|
2006-03-15 12:20:03 +00:00
|
|
|
return "#{@podcasts[podcast]["savedir"]}/#{filename}"
|
2006-07-04 11:55:23 +00:00
|
|
|
rescue Timeout::Error, Errno::EHOSTUNREACH, Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::ETIMEDOUT, Net::HTTPFatalError
|
|
|
|
|
puts " error #{$!} fetching, skipping"
|
2006-02-18 11:08:33 +00:00
|
|
|
end
|
2006-03-15 12:20:03 +00:00
|
|
|
else
|
|
|
|
|
return "#{@podcasts[podcast]["savedir"]}/#{filename}"
|
2006-02-14 21:27:42 +00:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2006-02-14 21:13:55 +00:00
|
|
|
for podcast in @podcasts.keys.sort
|
2006-03-15 12:20:03 +00:00
|
|
|
files = Array.new
|
2006-02-14 20:50:57 +00:00
|
|
|
puts podcast
|
2006-08-10 11:23:08 +00:00
|
|
|
begin
|
|
|
|
|
res = fetch(@podcasts[podcast]["rss"])
|
|
|
|
|
@filelist = {}
|
|
|
|
|
|
|
|
|
|
xmldoc = REXML::Document.new(res.body)
|
|
|
|
|
xmldoc.elements.each("rss/channel/item") {|item|
|
|
|
|
|
files.push getenclosure(podcast, item)
|
2006-03-15 12:20:03 +00:00
|
|
|
}
|
2006-08-10 11:23:08 +00:00
|
|
|
if @podcasts[podcast]["delete"]
|
|
|
|
|
deleteold(podcast)
|
|
|
|
|
end
|
|
|
|
|
if @podcasts[podcast]["m3u"]
|
|
|
|
|
File.open(@podcasts[podcast]["m3u"], "w"){|f|
|
|
|
|
|
files.each{|file|
|
|
|
|
|
f.puts file
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
end
|
|
|
|
|
rescue
|
|
|
|
|
rescue Timeout::Error, Errno::EHOSTUNREACH, Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::ETIMEDOUT, Net::HTTPFatalError
|
|
|
|
|
puts " error #{$!} fetching, skipping"
|
2006-03-15 12:20:03 +00:00
|
|
|
end
|
2006-02-14 20:50:57 +00:00
|
|
|
end
|