kelan.io

Personal Podcast Generator Script

I’ve been using the heck out of Instacast recently, especially during my commute, and I’ve really been enjoying both the app and the great content from 5by5 and others. But, the other day, I ran across a stand-alone mp3 file that I wanted to listen to on my commute, and realized I didn’t have an easy way to get it on my iPhone. Ever since switching to iOS 5 and Instacast (and with my long-time usage of Rhapsody for music), I don’t have any need to regularly sync to my computer. So, the easiest thing would be if I had my own “personal podcast” feed that I could simply subscribe to in Instacast.

A little googling found a clever AppleScript to do this. However, since I’m a nerd (and not a fan of AppleScript), I naturally wanted to hack up my own Ruby script to do the same thing.

I did like the AppleScript author’s idea of using Dropbox to host this. That means I can easily add to it from any of my computers.

I also like the Folder Action setup, but haven’t tackled that part. I figure I can manually re-run the script for now, and if it’s something I end up using often then I’ll fix that deficiency.

For now, it’s working great. Admittedly, it probably would have been quicker to just manually sync my iPhone for this one instance… Oh well.

Code

Here is the ruby script I ended up with (also available as a gist):

#!/usr/bin/env ruby -wKU
#
# by Kelan Champagne
# http://kelan.io
#
# A script to generate a personal podcast feed, hosted on Dropbox
#
# Inspired by http://hints.macworld.com/article.php?story=20100421153627718
#
# Simply put this, and some .mp3 or .m4a files in a sub-dir under your Dropbox
# Public folder, update the config values below, and run the script.  To get
# the public_url_base value, you can right click on a file in that folder
# in Finder, then go to Dropbox > Copy Public Link, and then remove the
# filename.
#
# Notes:
#  * You'll need to re-run it after adding new files to the dir, or you can
#    set up Folder Actions as suggested by the above hint.
#  * This script uses `mdls` to get the title and summary of the podcast
#    from the Spotlight metadata, which requires it to be run on a Mac. But,
#    the rest of the script should be cross-platform compatible.

require 'date'


# Config values
podcast_title = "My personal podcast"
podcast_description = "My personal podcast description"
public_url_base = "<put the public url to your dropbox folder here>"


# Generated values
date_format = '%a, %d %b %Y %H:%M:%S %z'
podcast_pub_date = DateTime.now.strftime(date_format)

# Build the items
items_content = ""
Dir.entries('.').each do |file|
    next if file =~ /^\./  # ignore invisible files
    next unless file =~ /\.(mp3|m4a)$/  # only use audio files

    puts "adding file: #{file}"

    item_size_in_bytes = File.size(file).to_s
    item_pub_date = File.mtime(file).strftime(date_format)
    item_title = `mdls --name kMDItemTitle #{file}`.sub(/^.*? = "/, '').sub(/"$/, '').chomp
    item_subtitle = `mdls --name kMDItemComment #{file}`.sub(/^.*? = "/, '').sub(/"$/, '').chomp
    item_summary = item_subtitle
    item_url = "#{public_url_base}/#{file}"
    item_content = <<-HTML
        <item>
            <title>#{item_title}</title>
            <itunes:subtitle>#{item_subtitle}</itunes:subtitle>
            <itunes:summary>#{item_summary}</itunes:summary>
            <enclosure url="#{item_url}" length="#{item_size_in_bytes}" type="audio/mpeg" />
            <pubDate>#{item_pub_date}</pubDate>
        </item>
HTML

    items_content << item_content
end

# Build the whole file
content = <<-HTML
<?xml version="1.0" encoding="ISO-8859-1"?>
<rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0">
    <channel>
        <title>#{podcast_title}</title>
        <description>#{podcast_description}</description>
        <pubDate>#{podcast_pub_date}</pubDate>
#{items_content}
    </channel>
</rss>
HTML

# write it out
output_file = File.new("podcast.rss", 'w')
output_file.write(content)
output_file.close