The return of the blogroll
I’ve bought the blogroll back since it disappeared during the upgrade. It’s now generated from my google reader opml feed which I export and run though some ruby which means it’s going to be up-to-date more frequently.
Here is the code that takes the opml and outputs the html fragment:
#!/usr/bin/ruby
require 'rexml/Document'
require 'pp.rb'
class FeedData
attr_accessor :name, :url, :category
def initialize( name, url, category )
( @name, @url, @category ) = name, url, category
end
end
class FeedDataList
def initialize()
@array = Array::new
end
def add( name, url, category )
tmpFeed = FeedData::new( name, url, category )
@array.push( tmpFeed )
end
def eachCategory
catArray = Array::new
@array.each do |feed|
if !catArray.member?( feed.category ) then
catArray.push( feed.category )
end
end
catArray.sort.each do |result|
yield result
end
end
def eachItemInCategory( category )
@array.each do |feed|
if feed.category == category then
yield feed
end
end
end
end
def parse_opml( opml_node, feeds, parents_names=[] )
opml_node.elements.each('outline') do |element|
if element.elements.size != 0 then
feeds = parse_opml( element, feeds, parents_names + [ element.attributes[ 'text' ] ] )
end
if element.attributes['xmlUrl'] then
feeds.add( element.attributes['title'], element.attributes['htmlUrl'], parents_names.last )
end
end
return feeds
end
opml = REXML::Document.new( STDIN )
feeds = FeedDataList::new
feeds = parse_opml( opml.elements['opml/body'], feeds )
feeds.eachCategory do |category|
print "<br /><strong>#{category}</strong> "
feeds.eachItemInCategory( category ) do |item|
print "<a href=\"#{item.url}\">#{item.name}</a> "
end
print "\n"
endTo make it work:
$ ./opml2html.rb < <opml file>I got the inspiration for the recursive opml parsing code from the Dekstop blog, so thanks are due to them!