Skip to content

Instantly share code, notes, and snippets.

@sivers
Created October 29, 2019 21:30
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sivers/e3a90a742cfc0802ede9dbf553339174 to your computer and use it in GitHub Desktop.
Save sivers/e3a90a742cfc0802ede9dbf553339174 to your computer and use it in GitHub Desktop.
Podcast RSS generator in Ruby
#!/usr/bin/env ruby
require 'date'
require 'xml'
def htmlit(infile)
lines = File.readlines(infile)
/<!--\s+(.+)\s+-->/.match lines.shift
lines.unshift('<h2>%s</h2>' % $1)
html = ''
lines.each do |line|
html << line.strip.gsub('="/', '="https://sivers.org/')
end
html
end
def subtitle(infile)
txt = File.readlines(infile)[2].strip
txt.gsub(/<[^>]+>/, '')
end
def duration(mp3)
seconds = %x(soxi -D /w/m/#{mp3}).to_i
Time.at(seconds).utc.strftime('%H:%M:%S')
end
doc = XML::Document.new()
doc.root = XML::Node.new('rss')
rss = doc.root
rss['version'] = '2.0'
rss['xmlns:itunes'] = 'http://www.itunes.com/dtds/podcast-1.0.dtd'
rss['xmlns:atom'] = 'http://www.w3.org/2005/Atom'
rss['xmlns:content'] = 'http://purl.org/rss/1.0/modules/content/'
rss['xmlns:googleplay'] = 'https://www.google.com/schemas/play-podcasts/1.0/'
rss << channel = XML::Node.new('channel')
channel << title = XML::Node.new('title')
title << 'Derek Sivers'
channel << description = XML::Node.new('description')
description << 'sivers.org'
channel << managingEditor = XML::Node.new('managingEditor')
managingEditor << 'derek@sivers.org'
channel << copyright = XML::Node.new('copyright')
copyright << '© 2019 Derek Sivers'
channel << generator = XML::Node.new('generator')
generator << 'Derek Sivers'
channel << atomlink = XML::Node.new('atom:link')
atomlink['href'] = 'https://sivers.org/podcast.rss'
atomlink['rel'] = 'self'
atomlink['type'] = 'application/rss+xml'
channel << link = XML::Node.new('link')
link << 'https://sivers.org/'
channel << itunesnewfeed = XML::Node.new('itunes:new-feed-url')
itunesnewfeed << 'https://sivers.org/podcast.rss'
channel << itunesowner = XML::Node.new('itunes:owner')
itunesowner << itunesemail = XML::Node.new('itunes:email')
itunesemail << 'derek@sivers.org'
itunesowner << itunesname = XML::Node.new('itunes:name')
itunesname << 'Derek Sivers'
channel << itunesauthor = XML::Node.new('itunes:author')
itunesauthor << 'Derek Sivers'
channel << itunessummary = XML::Node.new('itunes:summary')
itunessummary << 'Derek Sivers posts from sivers.org'
channel << itunessubtitle = XML::Node.new('itunes:subtitle')
itunessubtitle << 'Derek Sivers posts from sivers.org'
channel << language = XML::Node.new('language')
language << 'en'
channel << itunesexplicit = XML::Node.new('itunes:explicit')
itunesexplicit << 'no'
channel << cat1 = XML::Node.new('itunes:category')
cat1['text'] = 'Education'
cat1 << subcat1 = XML::Node.new('itunes:category')
subcat1['text'] = 'Self-Improvement'
channel << cat2 = XML::Node.new('itunes:category')
cat2['text'] = 'Society & Culture'
cat2 << subcat2 = XML::Node.new('itunes:category')
subcat2['text'] = 'Philosophy'
channel << cat3 = XML::Node.new('itunes:category')
cat3['text'] = 'Arts'
cat3 << subcat3 = XML::Node.new('itunes:category')
subcat3['text'] = 'Books'
channel << ituneskeywords = XML::Node.new('itunes:keywords')
ituneskeywords << 'Derek Sivers,sivers,sivers.org'
channel << itunestype = XML::Node.new('itunes:type')
itunestype << 'episodic'
channel << itunesimage = XML::Node.new('itunes:image')
itunesimage['href'] = 'https://sivers.org/images/DerekSivers-20141209a-1400.jpg'
channel << image = XML::Node.new('image')
image << image_url = XML::Node.new('url')
image_url << 'https://sivers.org/images/DerekSivers-20141209a-1400.jpg'
image << image_link = XML::Node.new('link')
image_link << 'https://sivers.org/'
image << image_title = XML::Node.new('title')
image_title << 'Derek Sivers'
d = %w(trd exan trav1 pg2 masch exex vls1 ment wtg polut d22 gofear daydream antic autom negz sauna erra hooky ldn isms metac ddown uncomf hf dq pe abio ww tp3 tp2 tp1 pinit)
d.each do |x|
infile = Dir['/w/sivers.org/content/blog/*-' + x][0]
m = /\A([0-9]{4}-[0-9]{2}-[0-9]{2})-(\S+)\Z/.match(File.basename(infile))
date = m[1]
contents = htmlit(infile)
lines = File.readlines(infile)
/<!--\s+(.+)\s+-->/.match lines.shift
blogtitle = $1
mp3 = 'sivers.org.%s.mp3' % x
item_url = "https://m.sivers.org/#{mp3}"
channel << item = XML::Node.new('item')
item << item_link = XML::Node.new('link')
item_link << "https://sivers.org/#{x}"
item << title = XML::Node.new('title')
title << blogtitle
item << itunestitle = XML::Node.new('itunes:title')
itunestitle << blogtitle
item << itunessubtitle = XML::Node.new('itunes:subtitle')
itunessubtitle << subtitle(infile)
item << itunesauthor = XML::Node.new('itunes:author')
itunesauthor << 'Derek Sivers'
item << description = XML::Node.new('description')
description << XML::Node.new_cdata(contents)
item << summary = XML::Node.new('itunes:summary')
summary << XML::Node.new_cdata(contents)
item << contente = XML::Node.new('content:encoded')
contente << XML::Node.new_cdata(contents)
item << season = XML::Node.new('itunes:season')
season << '1'
item << guid = XML::Node.new('guid')
guid << 'https://sivers.org/' + x
item << pubDate = XML::Node.new('pubDate')
pubDate << Date.parse(date).strftime('%a, %d %b %Y %H:%M:%S %z')
item << itunesepisodeType = XML::Node.new('itunes:episodeType')
itunesepisodeType << 'full'
item << itunesexplicit = XML::Node.new('itunes:explicit')
itunesexplicit << 'no'
item << itunesimage = XML::Node.new('itunes:image')
itunesimage['href'] = 'https://sivers.org/images/DerekSivers-20141209a-1400.jpg'
item << itunesduration = XML::Node.new('itunes:duration')
itunesduration << duration(mp3)
item << enclosure = XML::Node.new('enclosure')
enclosure['url'] = 'https://m.sivers.org/%s' % mp3
enclosure['type'] = 'audio/mpeg'
enclosure['length'] = File.size("/w/m/#{mp3}").to_s
end
doc.save('site/podcast.rss', indent: true, encoding: XML::Encoding::UTF_8)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment