require 'builder' module Rack class MusicIndex def initialize(app, options = {}) @app = app init(options) end def init(options) @dirs = options end def call(env) status, headers, response = @app.call(env) path_info = env['PATH_INFO'] update_files if dirs[path_info] headers['Content-Type'] = 'application/xml;charset=utf-8' body = podcast(env) headers["Content-Length"] = body.length.to_s response = [body] status = 200 elsif static_paths.include?(path_info) body = open(static_paths[path_info], 'rb').read headers["Content-Type"] = 'audio/mpeg' headers["Content-Length"] = body.length.to_s response = [body] status = 200 end [status, headers, response] end private def dirs @dirs end def files(media_dir) @files[media_dir] end def static_paths @static_paths end def update_files @files = {} @static_paths = {} dirs.each do |path, dir| @files[path] = Dir[dir + '/*.mp3'] @files[path].each do |filename| @static_paths[path + '/' + ::File.basename(filename)] = filename end end end def podcast(env) path = env['PATH_INFO'] req = Rack::Request.new(env) url = req.url files = files(path) xml = ::Builder::XmlMarkup.new xml.instruct! :xml, :version => '1.0' xml.rss :version => "2.0", 'xmlns:itunes' => 'http://www.itunes.com/dtds/podcast-1.0.dtd' do xml.channel do xml.title path xml.description 'Generated by Rack::MusicIndex' xml.link url files.each do |file| name = ::File.basename(file) item_link = url + '/' + name xml.item do xml.title name xml.description name xml.link item_link xml.guid item_link xml.enclosure :url => item_link end end end end end end end