Zenity.rb

Zenity is a command line based tool that helps shell scripts display GTK dialog boxes as a more interactive way to display error messages, get user input and other stuff like that. From it’s Freshmeat page,

Zenity is a tool that allows you to display Gtk+ dialog boxes from the command line and through shell scripts. It is similar to gdialog, but is intended to be saner. It comes from the same family as dialog, Xdialog, and cdialog, but it surpasses those projects by having a cooler name.

Zenity.rb is a gem (or optionally a single file that you can download and include in your script) that provides a easy way to display zenity dialogs. You can look at the Github and RubyForge project pages.

To install it, run this command in a shell (you may need to run it as su)

gem install Zenity.rb

Then try this out in irb:

require 'zenity'
Zenity::entry(:title => 'Enter some text', :text => 'This is a password dialog.', :arg => ['hide-text'])

The last line there gets translated to this: “zenity --entry --title='Enter some text' --text='This is a password dialog.' --hide-text” which is then passed to the operating system. So it basically depends upon the presence of zenity.

The code itself is very minimal. The only important file is listed below. If it doesn’t fit completely on your screen, you can also view it here.

module Zenity
  class << self
 
    # Let's just use method_missing instead of defining all of those.
    def method_missing(m, options=false)
      # Check if the dialog box we have to show is allowed
      if [ :calendar, :entry, :error, :'file-selection', :info, :list,
           :notification, :progress, :question, :'text-info', :warning, :scale 
      ].include? m
        # It's in the array and everything seems to be fine
        ret = %x[ #{parseopts('zenity --' + m.to_s, options)} ]
      else
        # We don't know about this dialog, raise an error
        raise "Unknown dialog #{m}"
      end
      # Check if any of the options passed were invalid.
      if ret.rstrip == 'This option is not available. Please see --help for all possible usages.'
        # Write a message to STDERR if there were invalid options, but don't
        # raise an error.
        STDERR << "Invalid option"
      else
        # Everything looks fine. Return what we got.
        return ret
      end
    end
 
 
    private
    # Very confusing code that generates the shell command.
    def parseopts(cmd, options)
      if options != false
        options.each do |k, v|
          cmd << " --#{k}='#{v}'" if k != :arg
        end
        options[:arg].each { |opt| cmd << " --#{opt}" } if options.has_key?(:arg)
      end
      cmd
    end
 
  end
end

As you can see, I chose to use method_missing to reduce the amount of code I’d need to write. As a possible side-effect of this, you may not be able to mix the module into your own classes or into the global namespace.

Overall, the purpose of packaging this in a gem was more for convenience of usage than anything else.

Leave a Reply