Turning man pages into nicely printable PS files

[Posted by Urban Hafner on 16 Jun 2009]

As seen on Twitter:

man -t program > program.ps

Turns the man page of a program into a nicely formatted PostScript file.

Tags man, ps, print

Relaunched my Blog using Jekyll

[Posted by Urban Hafner on 03 Jun 2009]

After Euruko I started rewriting my blog using Jekyll. That’s because it generated static HTML files that can be easily hosted on my TextDrive shared hosting plan (i.e. no expensive Ruby processes).

Have a look at my github repository and the Jekyll Wiki for information on how to do it yourself.

Tags software, blog, jekyll, ruby

Announcing Dacelo

[Posted by Urban Hafner on 15 Mar 2009]

With this post I’m announcing Dacelo. My personal Blog engine. It’s in its infancy right now but I hope to have a useable version in a few weeks (Yes, that long as I don’t have much time).

It’s mostly for my personal use as Typo is just getting to heavy and feature rich for me. That means that it’s goal is to be as minimal as possible and that it should only have the needed features, where needed is defined by me ;) The current feature list looks like this:

  • Blog posts and comments
  • Login via OpenID
  • Textile formating of the posts
  • Secure admin area (using https)
  • Easy way to setup your blog as your OpenID URL (whatever the terminology for that may be)
  • Tags and a tag cloud in the sidebar
  • Highlighting for your code snippets
  • Live preview of your edits on the posts
  • Atom/RSS feeds for the blog and comments (and maybe for the comments on a blog post)
  • Comment management (i.e. Spam protection, maybe Akismet support)
  • And anything else that I’ve now forgotten and will “need”.

Feel free to check out the code at http://github.com/ujh/dacelo/tree/master and the tickets at http://www.assembla.com/spaces/dacelo.

Tags ruby, rails, blog, engine

Multisite ActionMailer Ruby on Rails plugin

[Posted by Urban Hafner on 26 Feb 2009]

I just released a new Ruby on Rails plugin. Here’s the contents of the README:


If you want ActionMailer templates handled the same way as views when
you are using the rails-multisite plugin use this plugin.

Right now it only works in conjunction with the msales fork of
rails-multisite [1] and is in conflict with action_mailer_layouts [2]

[1] http://github.com/msales/rails-multisite/tree/master
[2] http://github.com/willcodeforfoo/action_mailer_layouts/tree/master

You can get it at http://github.com/msales/multisite_action_mailer/tree/master. Patches welcome.

Tags ruby, rubyonrails, rails, plugin, git, github, actionmailer, mail, multisite

Rails partials and their dependencies

[Posted by Urban Hafner on 21 Feb 2009]

Have you ever wondered how your Ruby on Rails views and partials relate? Did you want to know which views change when you change that one partial?

I don’t know about you but I had that problem on a project recently. That why I created a Rails plugin called partial_dependencies. It creates a graphical representation of your views and partials for you.

Get it now while it’s still hot :)

Tags rails, rubyonrails, ruby, partials, graphviz, dependencies, plugin

Fink, Mysql, and Mysql Ruby gem

[Posted by Urban Hafner on 13 Jan 2009]

Installing the ruby mysql gem with a mysql installed via fink worked for me using the following command:

sudo gem install mysql -- --with-mysql-include=/sw/include/mysql \
 --with-mysql-lib=/sw/lib --with-mysql-config=/sw/bin/mysql_config

Tags fink, ruby, mac, osx, rubygems

Bad bad Firefox

[Posted by Urban Hafner on 12 Jun 2008]

A few days ago I bought a new DSLR (a Nikon D40) and started to upload more pictures to flickr (see http://flickr.com/photos/ujh for my photo stream). I also started looking at much more pictures on flickr from other people. And in one of those the photographer was complaining how bad the pictures looked on flickr. In a comment someone else explained that the problem is not flickr but Firefox! And true enough. The difference between Firefox and for example Safari is so big even I could see it! So if you like to look at pictures don’t use Firefox.

Tags firefox, browser, flickr

For all the bass players out there ...

[Posted by Urban Hafner on 28 Dec 2007]

I just happened to run across a guy recording himself playing bass on youtube. Here’s a sample:

It makes we want to start playing again. Maybe I can get somewhere close (well maybe not).

Tags bass, youtube

CGOS "rotation" script II

[Posted by Urban Hafner on 01 Dec 2007]

Here’s the updated cgos.rb script. The main change is that the bots are chosen at random (instead of in the order specified).

#!/usr/bin/env ruby
#
# Run bots one after the other on CGOS. The BOTS variable is an array
# if directories of the bots. In each of these directory there has to
# be an executable file called 'cgos.sh' that connects the bot to CGOS.
# This executable is also required to set the sentinel file name to the
# one given in the TERM variable below.

require 'optparse'

# :bot    :: The directory containing you cgos connection script
# :script :: The name of the script (defaults to cgos.sh)
# :games  :: The number of games the bot should play in a row
BOTS = [
  {:bot => "libEGO-AMAF-3"},
  {:bot => "libEGO-AMAF-2"},
  {:bot => "erlygo"},
  {:bot => "libEGO-AMAF-2", :script => "cgos19.sh"},
  {:bot => "libEGO-AMAF-3", :script => "cgos19.sh"},
  {:bot => "erlygo",        :script => "cgos19.sh"}
]
# Sentinel filename to be used by CGOS
TERM     = "stop.txt"
$verbose = false

round       = 0
total_games = 0
games       = Hash.new {|h,k| h[k] = 0}

opts = OptionParser.new
opts.on("-v", "--verbose") { $verbose = true }
opts.on("-s", "--stop") do
  File.new(TERM, "w")
  exit
end

opts.parse(ARGV)

def time
  Time.now.strftime("%H:%M:%S")
end

# Clean up (if script wasn't terminated correctly)
(BOTS+[{:bot => "."}]).each do |bot|
  bot[:games]  = 1         unless bot[:games]
  bot[:script] = "cgos.sh" unless bot[:script]
  Dir.chdir(bot[:bot]) do
    File.delete(TERM) if File.exists?(TERM)
  end
end

until(File.exists?(TERM))
  round += 1
  if (round % 5).zero?
    games.each do |k,v|
      puts "#{sprintf("%03d", v)} games for '#{k}'"
    end
  end
  bot = BOTS[rand(BOTS.length)]
  msg = "[#{time}] Running '#{bot[:bot]}' (#{bot[:script]})"
  msg += " for #{bot[:games]} games" 
  puts msg
  last_was_print = false
  Dir.chdir(bot[:bot]) do
    IO.popen("./#{bot[:script]} 2>/dev/null") do |pipe|
      until(pipe.eof?)
        line = pipe.gets
        if $verbose
          puts line
          STDOUT.flush
        end
        case line
        when /gameover/
          line =~ /gameover\s+\d\d\d\d-\d\d-\d\d\s+(\S+)/
          print "\n" if last_was_print
          puts "[#{time}] #{$1}"
          last_was_print = false
        when /setup/
          File.new(TERM, "w") if games[bot[:bot]] >= (bot[:games]-1)
          games[bot[:bot]] += 1
          total_games      += 1
          line =~ /setup\s+.*?(\S+\(.*\)\s+\S+\(.*\))/
          print "\n" if last_was_print
          stats = "(game #{games[bot[:bot]]} of #{bot[:games]},"
          stats += "#{total_games} games in total)"
          puts "[#{time}] #{$1} #{stats}"
          last_was_print = false
        when /info/
          unless $verbose
            print "."
            STDOUT.flush
            last_was_print = true
          end
        end
      end
    end
    File.delete(TERM) if File.exists?(TERM)
  end
  round += 1
end
File.delete(TERM)

Tags cgos, go, ai, game, computer, computer go, ruby, computer-go, baduk, weiqi

CGOS "rotation" script

[Posted by Urban Hafner on 10 Oct 2007]

While playing around with libEGO and trying to see how far I can get with a simple “all-moves-as-first” Monte Carlo bot. I wrote many (well, three) different versions of the same bot and tested them against each other. Of course for a real test I had to use CGOS. But as I only have one computer that I also use for work I had to run the different bots one after the other. To automate that I wrote a small script that lets you run any number of bots in rotation on CGOS.

It’s a very simple script written in Ruby, so you’ll need to have that installed. For the rest see the comments at the beginning of the file.

#!/usr/bin/env ruby
#
# Run bots one after the other on CGOS. The BOTS variable is an array
# if directories of the bots. In each of these directory there has to
# be an executable file called 'cgos.sh' that connects the bot to CGOS.
# This executable is also required to set the sentinel file name to the
# one given in the TERM variable below.

# Number of games for each bot
GAMES = 1
# The bots that should play
BOTS = ["libEGO-AMAF", "libEGO-AMAF-2", "libEGO-AMAF-3"]
# Sentinel filename to be used by CGOS
TERM  = "stop.txt"

round = 0

if ARGV.length > 0 and ARGV.first == "stop"
  File.new(TERM, "w")
  exit
end

# Clean up (if script wasn't terminated correctly)
(BOTS+["."]).each do |dir|
  Dir.chdir do
    File.delete(TERM) if File.exists?(TERM)
  end
end

until(File.exists?(TERM))
  dir = BOTS[round % BOTS.length]
  puts "[#{Time.now}] Round #{round+1}"
  puts "[#{Time.now}] Running '#{dir}' for #{GAMES} games"
  last_was_print = false
  Dir.chdir(dir) do
    games = 0
    IO.popen('./cgos.sh 2>/dev/null') do |pipe|
      until(pipe.eof?)
        line = pipe.gets
        if line =~ /setup/
          games += 1
          File.new(TERM, "w") if games >= (GAMES-1)
        end
        case line
        when /gameover/
          line =~ /gameover\s+\d\d\d\d-\d\d-\d\d\s+(\S+)/
          print "\n" if last_was_print
          puts "[#{Time.now}] #{$1}"
          last_was_print = false
        when /setup/
          line =~ /setup\s+.*?(\S+\(.*\)\s+\S+\(.*\))/
          print "\n" if last_was_print
          puts "[#{Time.now}] #{$1}"
          last_was_print = false
        when /info/
          print "."
          STDOUT.flush
          last_was_print = true
        end
      end
    end
    File.delete(TERM)
  end
  round += 1
end
File.delete(TERM)

Tags go, computer, computer go, ruby, computer-go, baduk, weiqi