Stop thinking it's too hard

:  ~ 3 min read

I finally got around and implemented the RSS feed. Wasn't as hard as I expected; piss easy, actually (check the end for the updated version):

get '/feed' do
  posts = Dir['posts/*.md'].sort_by!{ |m| m.downcase }.reverse
  rss = RSS::Maker.make('2.0') do |maker|
    maker.channel.icon = "/public/favicon.ico"
    maker.channel.logo = "/public/favicon.ico"
    maker.channel.title = 'Roland Leth'
    maker.channel.description = 'Roland Leth'
    maker.channel.link = "/"
    maker.channel.language = 'en'
    hours = [0, 1, 2, 3, 20, 21, 22, 23]
	
	maker.items.do_sort = false
	posts.each do |post|
	  matches = post.match(/\/(\d{4})-(\d{2})-(\d{2})-([\w\s\.\}\{\[\]:"';!=\?\+\*\-\)\(]+)\.md$/)
	  i = maker.items.new_item
	  i.title = matches[4]
	  time_string = File.readlines(post)[1]
	  # in case I forget to fill the time, just create a random hour between 8 PM and 3 AM, that's when I work most of the time
	  if time_string.length == 8 or time_string.length == 9
	    time = Date._strptime("#{time_string} EEST","%H:%M %p %Z")
		time[:leftover] = nil
	  else
		min = rand(0..59)
		time = Date._strptime("#{hours.sample}:#{min} EEST","%H:%M %Z")
	  end

	  # titles are written 'Like this', links need to be 'Like-this'
	  i.link = "http://rolandleth.com/#{matches[4].gsub("\s", "-")}".gsub(";", "")
	  content = _markdown(File.readlines(post)[3..-1].join())
	  i.description = content
	  i.date = DateTime.new(matches[1].to_i, matches[2].to_i, matches[3].to_i, time[:hour], time[:min], 0, time[:zone]).to_time
	end
  end
  rss.to_s
end

But now I had another problem to fix: RSS Readers do not interpret my custom CSS, meaning the hack I did with the underline to show up as italic doesn't work with maker.
Well, I reached GitHub while searching for a solution and it turned out that Sam posted this 4 days ago. TL;DR: He hacked Redcarpet to parse ==text== as <mark>text</mark> and the guys merged his changes. How fortunate :)

get '/feed' do
  posts = repository(:default).adapter.select('SELECT * FROM application_posts')
  posts.map! { |struc| struc.to_h }
  posts.sort! { |a, b| a[:datetime] <=> b[:datetime] }.reverse!
  rss ||= RSS::Maker.make('atom') do |maker|
    maker.channel.icon = '/public/favicon.ico'
    maker.channel.logo = '/public/favicon.ico'
    maker.channel.id = 'http://rolandleth.com'
    maker.channel.link = 'http://rolandleth.com/feed'
    maker.channel.title = 'Roland Leth'
    maker.channel.description = 'Roland Leth'
    maker.channel.author = 'Roland Leth'
    maker.channel.language = 'en'
    maker.channel.rights = "© #{Time.now.year} Roland Leth"
    maker.channel.subtitle = 'iOS and Ruby development thoughts by Roland Leth.'
    maker.items.do_sort = false

    posts.each do |post|
      i = maker.items.new_item
      i.title = post[:title]
      date_matches = post[:datetime].match(/(\d{4})-(\d{2})-(\d{2})-(\d{4})/)
      time = Date._strptime("#{date_matches[4]} EEST", '%H%M %Z')
      i.link = "http://rolandleth.com/#{post[:link]}"
      i.content.content = _markdown_for_feed(post[:body].lines[2..-1].join())
      i.content.type = 'html'
      i.updated = DateTime.new(date_matches[1].to_i, date_matches[2].to_i, date_matches[3].to_i, time[:hour], time[:min], 0, time[:zone]).to_time
      i.published = DateTime.new(date_matches[1].to_i, date_matches[2].to_i, date_matches[3].to_i, time[:hour], time[:min], 0, time[:zone]).to_time
      # The RSS was last updated when the last post was posted (which is first in the array)
      maker.channel.updated ||= DateTime.new(date_matches[1].to_i, date_matches[2].to_i, date_matches[3].to_i, time[:hour], time[:min], 0, time[:zone]).to_time
    end
  end
  rss.link.rel = 'self'
  rss.link.type = 'application/atom+xml'
  rss.entries.each do |entry|
    entry.content.lang = 'en'
    entry.title.type = 'html'
  end
  rss.to_s
end