changeset 1148:e86483cb8c39

Update mcwizz setup script (Mulander)
author Mikael Berthe <mikael@lilotux.net>
date Sat, 10 Feb 2007 18:43:38 +0100
parents fcef5d34b7d4
children 13d125a2020f
files mcabber/contrib/mcwizz.pl mcabber/contrib/mcwizz.rb
diffstat 2 files changed, 631 insertions(+), 391 deletions(-) [+]
line wrap: on
line diff
--- a/mcabber/contrib/mcwizz.pl	Sat Feb 10 18:42:02 2007 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,391 +0,0 @@
-#!/usr/bin/perl
-#
-#  Copyright (C) 2006 Adam Wolk "Mulander" <netprobe@gmail.com>
-#  Copyright (C) 2006 Mateusz Karkula "Karql"
-#  A few tweaks by Mikael Berthe
-#
-# This script is provided under the terms of the GNU General Public License,
-# see the file COPYING in the root mcabber source directory.
-#
-
-use warnings;
-use strict;
-
-use Getopt::Long;
-use Term::ReadKey;
-
-my %options;
-
-Getopt::Long::Configure qw(bundling);
-my $result = GetOptions(
-		"help|h"	=> \$options{help},
-		"version|V"	=> \$options{version},
-		"ignore|i"	=> \$options{ignore},
-		"ignore-auto|I"	=> \$options{ignore_auto},
-		"output|o"	=> \$options{output},
-		"passwd|p"	=> \$options{passwd},
-		"color|c"	=> \$options{color},
-		"ssl|s"		=> \$options{ssl},
-		"status|S"	=> \$options{status},
-		"proxy|P"	=> \$options{proxy},
-		"keep|k"	=> \$options{keep},
-		"log|l"		=> \$options{log},
-		"tracelog|t"	=> \$options{tracelog},
-);
-
-##
-# Allowed colors
-my @bg_color	= qw( black red green yellow blue magenta cyan white );
-my @fg_color	= (@bg_color, map("bright$_", @bg_color), map("bold$_", @bg_color));
-
-##
-# info for specific settings
-my %info = (
-	# not grouped
-	beep_on_message => { msg => 'Should mcabber beep when you receive a message?', allow => undef, type => 'yesno', anwsers => undef, default => 0},
-	password	=> { msg => 'Enter your password (at your own risk, this will be saved in plain text)', allow=>'.+', type=>'pass',anwsers => undef, default => undef },
-	pinginterval	=> { msg => 'Enter pinginterval in seconds for keepalive settings, set this to 0 to disable, ', allow =>'\d+', type=>'edit', anwsers => undef, default => 40 },
-	hide_offline_buddies => {msg => 'Display only connected buddies in the roster?', allow => undef, type => 'yesno', anwsers => undef, default => 0 },
-	iq_version_hide_os => { msg => 'Hide Your OS information?', allow => undef, type => 'yesno', anwsers => undef, default => 0 },
-	# server settings
-	username 	=> { msg => 'Your username', allow => '[^\s\@:<>&\'"]+', type => 'edit', anwsers => undef, default => undef },
-	server		=> { msg => 'Your jabber server', allow => '\S+', type => 'edit', anwsers => undef, default => undef },
-	resource	=> { msg => 'Resource (If your don\'t know what a resource is, use the default setting)', allow => '.{1,1024}', type => 'edit', anwsers => undef, default => 'mcabber' },
-	nickname	=> { msg => 'Conference nickname (if you skip this setting your username will be used as a nickname in MUC chatrooms)', allow => '.+', type => 'edit', anwsers => undef, default => undef },
-	# ssl settings
-	ssl		=> { msg => 'Enable ssl?', allow => undef, type => 'yesno', anwsers => undef, default => 0 },
-	port		=> { msg => 'Enter ssl port', allow => '\d+', type => 'edit', anwsers => undef, default => 5222 },
-	# proxy settings
-	proxy_host	=> { msg => 'Proxy host', allow => '\S+?\.\S+?', type => 'edit', anwsers => undef, default => undef },
-	proxy_port	=> { msg => 'Proxy port', allow => '\d+', type => 'edit', anwsers => undef, default => 3128 },
-	proxy_user	=> { msg => 'Proxy user (optional, you can skip this if not required)', allow => '.+', type => 'edit', anwsers => undef, default => undef },
-	proxy_pass	=> { msg => 'Proxy pass (optional, you can skip this if not required)', allow => '.+', type => 'pass', anwsers => undef, default => undef },
-	# trace logs
-	tracelog_level => { msg => 'Specify level of advanced traces', allow => undef, type => 'multi', anwsers => ['lvl0: I don\'t want advanced tracing','lvl1: most events of the log window are written to the file','lvl2: debug logging (XML etc.)'], default => 0 },
-	tracelog_file => { msg => 'Specify a file to which the logs will be written', allow => undef, type => 'edit', anwsers => undef, default => undef },
-	# logging settings
-	log_win_height => { msg => 'Set log window height (minimum 1)', allow => '[1-9]\d*', type => 'edit', anwsers => undef, default => 5 },
-	log_display_sender => { msg => 'Display the message sender\'s jid in the log window?', allow => undef, type => 'yesno', anwsers => undef, default => 0 },
-	logging		=> { msg => 'Enable logging?', allow => undef, type => 'yesno', anwsers => undef, default => 1 },
-	load_logs 	=> { msg => 'Enable loading logs?', allow => undef, type => 'yesno', anwsers => undef, default => 1 },
-	logging_dir	=> { msg => 'Enter logging directory', allow => '.+' , type => 'edit', anwsers => undef, default => undef },
-	log_muc_conf	=> { msg => 'Log MUC chats?', allow => undef, type => 'yesno', anwsers => undef, default => 1 },
-	load_muc_logs	=> { msg => 'Load MUC chat logs?', allow => undef, type => 'yesno', default => 0 },
-	# status settings
-	roster_width => { msg => 'Set buddylist window width (minimum 2)', allow => '[2-9]\d*', type => 'edit', anwsers => undef, default => 24 },
-	buddy_format => { msg => 'What buddy name format (in status window) do you prefer?', allow => undef, type => 'multi', anwsers => ['<jid/resource>','name <jid/resource> (name is omitted if same as the jid)','name/resource (if the name is same as the jid, use <jid/res>','name (if the name is the same as the jid, use <jid/res>'], default => 0 },
-	show_status_in_buffer => { msg => 'What status changes should be displayed in the buffer?', allow => undef, type => 'multi', anwsers => ['none','connect/disconnect','all'], default => 2 },
-	autoaway => { msg => 'After how many seconds of inactivity should You become auto away? (0 for never)', allow => '\d+', type => 'edit', anwsers => undef, default => 0 },
-	message		=> { msg => 'Skip this setting unless you want to override all other status messages', allow => undef, type => 'edit', default => 'Unique message status'},
-	message_avail	=> { msg => 'Set avaible status', allow => undef, type =>'edit',anwsers => undef, default =>'I\'m avaible'},
-	message_free	=> { msg => 'Set free for chat status', allow => undef, type =>'edit', anwsers => undef, default => 'I\'m free for chat'},
-	message_dnd	=> { msg => 'Set do not disturb status', allow => undef, type => 'edit', anwsers => undef, default => 'Please do not disturb'},
-	message_notavail=> { msg => 'Set not avaible status', allow => undef, type => 'edit', anwsers => undef, default => 'I\'m not avaible'},
-	message_away	=> { msg => 'Set away status', allow => undef, type => 'edit', anwsers => undef, default => 'I\'m away' },
-	message_autoaway=> { msg => 'Set auto-away status', allow => undef, type => 'edit', anwsers => undef, default => 'Auto-away'},
-	# color settings
-	color_background=> { msg => 'Select background color of the chat window and the log window', allow => undef, type => 'multi', anwsers => \@bg_color, default => 'black' },
-	color_general	=> { msg => 'Select text color in the chat window and the log window', allow => undef, type =>'multi', anwsers => \@fg_color , default => 'white' },
-	color_msgout	=> { msg => 'Select text color in the chat window for outgoing messages', allow => undef,  type => 'multi', anwsers => \@fg_color, default => 'cyan'},
-	color_bgstatus	=> { msg => 'Select background color of the status lines', allow => undef, type => 'multi', anwsers => \@bg_color, default =>'blue'},
-	color_status	=> { msg => 'Select text color of the status lines', allow => undef, type => 'multi', anwsers => \@fg_color, default => 'white' },
-	color_roster	=> { msg => 'Select text color of the roster (buddylist) normal items', allow => undef, type => 'multi', anwsers => \@fg_color, default => 'green' },
-	color_bgrostersel=>{ msg => 'Select background color of the selected roster item', allow => undef, type => 'multi', anwsers => \@bg_color, default => 'cyan' },
-	color_rostersel	=> { msg => 'Select text color of the selected roster item', allow => undef, type => 'multi', anwsers => \@fg_color, default => 'blue' },
-	color_rosterselmsg=>{ msg => 'Select text color of the selected roster item, if there is a new message', allow => undef, type => 'multi', anwsers => \@fg_color, default => 'red' },
-	color_rosternewmsg=>{ msg => 'Select text color of items with unread messages', allow => undef, type => 'multi', anwsers => \@fg_color , default => 'red' },
-);
-
-##
-# question groups
-my %groups = ( 	required => [qw(username server resource nickname ssl port)],
-		proxy_settings  => [qw(proxy_host proxy_port proxy_user proxy_pass)],
-		logging_settings=> [qw(logging log_win_height log_display_sender load_logs logging_dir log_muc_conf load_muc_logs)],
-		status_settings => [qw(buddy_format roster_width show_status_in_buffer autoaway message message_avail message_free message_dnd message_notavail message_away message_autoaway )],
-		color_settings  => [qw(color_background color_general color_msgout color_bgstatus color_status color_roster color_bgrostersel color_rostersel color_rosterselmsg color_rosternewmsg)],
-		tracelog_settings => [qw(tracelog_level tracelog_file)],
-);
-
-my (%conf,@old);
-##
-# regexp for valid keys
-my $key_reg = join '|', keys %info;
-
-help() 		if $options{help};
-version() 	if $options{version};
-
-prepare();
-ask('password') if $options{passwd};
-
-ask($_) for @{ $groups{required} };
-if($options{proxy}) { ask($_) for @{ $groups{proxy_settings} } };
-ask('pinginterval') if $options{keep};
-ask('beep_on_message');
-ask('hide_offline_buddies');
-ask('iq_version_hide_os');
-ask('autoaway');
-if($options{log}   	)   { ask($_) for @{ $groups{logging_settings} } };
-if($options{status}	)   { ask($_) for @{ $groups{status_settings}  } };
-if($options{color} 	)   { ask($_) for @{ $groups{color_settings}   } };
-if($options{tracelog}	)   { ask($_) for @{ $groups{tracelog_settings}} };
-build_config();
-
-##
-# Prepare for work
-sub prepare
-{
-	mkdir "$ENV{HOME}/.mcabber", 0700 unless ( -d "$ENV{HOME}/.mcabber" );
-
-	parse_config() if ( -e "$ENV{HOME}/.mcabber/mcabberrc" && !$options{ignore} );
-}
-
-##
-# Parse current user configuration and save it
-sub parse_config
-{
-	my $conf_file = "$ENV{HOME}/.mcabber/mcabberrc";
-	my $flag = 1;
-
-	open CONF, "<$conf_file" or return;
-
-	my ($key,$value);
-	while(<CONF>)
-	{
-		push @old, $_;
-		$flag = 0 if $options{ignore_auto} && m/^#BEGIN AUTO GENERATED SECTION/;
-		$flag = 1 if $options{ignore_auto} && m/^#END AUTO GENERATED SECTION/;
-		if ( $flag && m/^set\s+($key_reg)\s*=\s*(.+)$/ )
-		{
-			($key,$value) = ($1,$2);
-
-			$conf{$key} = $value if ( exists $info{$key} );
-		}
-	}
-
-	close CONF;
-	return 1;
-}
-
-##
-# Ask the user for a setting
-sub ask
-{
-	my ($key) = @_;
-
-	my %dispatch = (
-		edit 	=> \&_ask_edit,
-		yesno 	=> \&_ask_yesno,
-		multi	=> \&_ask_multi,
-		pass	=> \&_ask_pass
-	);
-
-	my $lp = 1;
-
-	print 	"\n'$key'\n",
-		$info{$key}->{msg},"\n",
-		( defined $info{$key}->{default} ) ?
-			( $lp++, '. ', ( exists $conf{$key} ) ? 'Reset' : 'Set', " to Default [",show($key,'default'),"]\n" ) : '',
-		( exists $conf{$key} ) ? ( $lp++, ". Leave Current setting [",show($key,'current'),"]\n", $lp++ ) : $lp++ , ". ",
-		( $info{$key}->{type} eq 'pass') ? 'Enter Passowrd' : ( ( $info{$key}->{type} eq 'edit' ) ? 'Edit' : 'Set' ),
-		"\n$lp. Skip\n[choice]: ";
-
-	chomp(my $action = <STDIN>);
-	unless ( $action =~ /^\d$/ && $action >= 1 && $action <= $lp ) {
-		ask($key);
-		return;
-	}
-
-	##
-	# Edit
-	if ( $lp -1  == $action )
-	{
-		&{ $dispatch{ $info{$key}->{type} } }($key);
-	}
-
-	##
-	# Default
-	elsif ( $action == 1 )
-	{
-		$conf{$key} = $info{$key}->{default}  if defined $info{$key}->{default};
-	}
-
-	##
-	# Skip
-	elsif ( $lp == $action )
-	{
-		delete $conf{$key};
-	}
-
-	##
-	# Nothing for Leave Current setting
-
-	return 1;
-}
-
-sub _ask_yesno
-{
-	my ($key) = @_;
-
-	print "1. yes\n2. no\n[choice]: ";
-
-	chomp(my $set = <STDIN>);
-	unless ( $set =~ /^[12]$/ ) {
-		ask($key);
-		return;
-	}
-
-	$conf{$key} = $set;
-	$conf{$key} = 0 if $set eq 2;
-}
-
-sub _ask_multi
-{
-	my ($key) = @_;
-	my $count = scalar @{$info{$key}->{anwsers}};
-	my $row = sprintf("%0.f",($count/3+0.5));
-
-	for (my $i = 0; $i < $row; ++$i)
-	{
-		printf("%-25s", ($i+1) . ". " . $info{$key}->{anwsers}->[$i]);
-		printf("%-25s", ($i+$row+1) . ". " . $info{$key}->{anwsers}->[$i+$row]) if ($i+$row < $count);
-		printf("%-25s", ($i+2*$row+1) . ". " . $info{$key}->{anwsers}->[$i+2*$row]) if ($i+2*$row < $count);
-		print "\n";
-	}
-
-	print '[choice]: ';
-	chomp(my $set = <STDIN>);
-	unless ( $set =~ /^\d+$/ && $set >= 1 && $set <= $count ) {
-		ask($key);
-		return;
-	}
-	$conf{$key} = $info{$key}->{anwsers}->[$set-1];
-}
-
-sub _ask_edit
-{
-	my ($key) = @_;
-	print '[edit]: ';
-	chomp(my $set = <STDIN>);
-	unless ( $set =~ /^$info{$key}->{allow}$/ ) {
-		ask($key);
-		return;
-	}
-
-	$conf{$key} = $set;
-}
-
-sub _ask_pass
-{
-	my ($key) = @_;
-	print "Characters you type in will not be shown\n[password]: ";
-
-	ReadMode(2);
-	my $anws = ReadLine(0);
-	ReadMode(0);
-
-	ask($key) unless $anws =~ /^$info{$key}->{allow}$/;
-	chomp($anws);
-
-	$anws =~ s/^((?:\s.+)|(?:.+\s))$/"$1"/;
-	$conf{$key} = $anws;
-}
-
-##
-# Build configuration file
-sub build_config
-{
-	my $config_file = "$ENV{HOME}/.mcabber/mcabberrc";
-
-	local *STDOUT unless $options{output} ;
-
-	unless($options{output})
-	{
-		open STDOUT,">$config_file" or die "Can't create config file";
-		chmod 0600, $config_file
-	}
-
-	my ($flag,$dumped) = (1,0);
-	for (@old)
-	{
-		$flag = 0 if m/^#BEGIN AUTO GENERATED SECTION/;
-		$flag = 1 if m/^#END AUTO GENERATED SECTION/;
-		if ( $flag )
-		{
-			print
-		}
-		elsif( !$flag && !$dumped )
-		{
-			print "#BEGIN AUTO GENERATED SECTION\n\n";
-			print "set $_ = $conf{$_}\n" for sort keys %conf;
-			print "\n";
-			$dumped = 1;
-		}
-	}
-
-	unless($dumped)
-	{
-		print "\n#BEGIN AUTO GENERATED SECTION\n\n";
-		print "set $_ = $conf{$_}\n" for sort keys %conf;
-		print "\n#END AUTO GENERATED SECTION\n";
-	}
-
-	close STDOUT unless $options{output};
-}
-
-sub show
-{
-	my ($key,$name) = @_;
-	my $value;
-
-	$value = $info{$key}->{default} 	if $name eq 'default';
-	$value = $conf{$key}		 	if $name eq 'current';
-
-	if ( $info{$key}->{type} eq 'yesno' )
-	{
-		return ( $value ) ? 'yes' : 'no';
-	}
-
-	elsif ( $info{$key}->{type} eq 'multi' )
-	{
-		return $info{$key}->{anwsers}->[$value];
-	}
-
-	else
-	{
-		return $value;
-	}
-}
-
-sub help
-{
-print<<EOF;
-Usage: $0 options
-
-This script generates configuration files for mcabber jabber client
-
--h, --help		display this help screen
--v, --version		display version information
--i, --ignore		ignore previous user configuration
--I, --ignore-auto	ignore auto generated section
--o, --output		output to stdout instead of file
--p, --passwd		save password in the config file (not recommended)
--s, --ssl		ask for ssl settings
--c, --color		ask for color settings
--S, --status		ask for status settings
--P, --proxy		ask for proxy settings
--k, --keep		ping/keepalive connection settings
--l, --log		ask for logging settings
--t, --tracelog		ask for trace log settings
-EOF
-exit;
-}
-
-sub version
-{
-print<<EOF;
-mcwizz v0.02 coded by Karql & mulander <netprobe\@gmail.com>
-EOF
-exit;
-}
-
-# vim: set noexpandtab sts=8:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/contrib/mcwizz.rb	Sat Feb 10 18:43:38 2007 +0100
@@ -0,0 +1,631 @@
+#!/usr/bin/ruby -w
+#
+#  Copyright (C) 2006,2007 Adam Wolk "Mulander" <netprobe@gmail.com>
+#  Copyright (C) 2006 Mateusz Karkula "Karql"
+#
+# This script is provided under the terms of the GNU General Public License,
+# see the file COPYING in the root mcabber source directory.
+#
+#
+
+require 'getoptlong'
+
+##
+# strings of colors ;)
+module Colors
+  @@color = true
+
+  ESC 	= 27.chr
+
+  RED 	= ESC + '[31m'
+  GREEN = ESC + '[32m'
+  YELLOW= ESC + '[33m'
+  BLUE  = ESC + '[34m'
+  PURPLE= ESC + '[35m'
+  CYAN  = ESC + '[36m'
+
+  BGREEN= ESC + '[42m'
+
+  ENDCOL= ESC + '[0m'
+
+  def color(color)
+    return '[' + self + ']' unless @@color
+    color + self + ENDCOL
+  end
+  def red;	color(RED);	end
+  def green;	color(GREEN);	end
+  def yellow;	color(YELLOW);	end
+  def blue;	color(BLUE);	end
+  def purple;	color(PURPLE);	end
+  def cyan;	color(CYAN);	end
+  def bgreen;	color(BGREEN);	end
+end
+
+class String;  include Colors;	end
+
+class Option
+  attr_accessor :value, :current, :default
+  attr_reader :name,:msg
+
+  def initialize(args)
+    @name	= args[:name]
+    @msg	= args[:msg]
+    @default	= args[:default]
+    @value	= nil
+    @current	= nil
+    @prompt	= ''
+  end
+
+  def set?;		!@value.nil?;		end
+  def to_s;		"set #@name=#@value";	end
+  def additional?; 	false;			end
+
+  def ask()
+    puts @msg
+    print @prompt
+    $stdin.gets.chomp
+  end
+
+end
+
+class YesNo < Option
+  def initialize(args)
+    super(args)
+    @ifSet  = args[:ifSet]
+    @prompt = '[Yes/no]: '
+  end
+  def ask()
+    # 1 == yes, 0 == no
+    case super
+      when /^Y/i
+        @value = 1
+	return additional()
+      when /^N/i
+        @value = 0
+	return []
+      else
+        puts 'Please answer yes or no'
+	puts
+        ask()
+      end
+  end
+
+  def additional?
+    (@value == 1 && !@ifSet.nil?) ? true : false
+  end
+
+  def additional
+    (@ifSet.nil?) ? [] : @ifSet
+  end
+end
+
+class Edit < Option
+  def initialize(args)
+    super(args)
+    @regex  = args[:regex]
+    @prompt = '[edit]: '
+  end
+  def ask()
+    answer = super
+    if answer.empty? || ( !@regex.nil? && !(answer =~ @regex) )
+      ask()
+    else
+      @value = answer
+    end
+    return []
+  end
+end
+
+class Multi < Option
+  attr_reader :choices
+  def initialize(args)
+    super(args)
+    @choices = args[:choices]
+    @max     = @choices.length - 1
+    @prompt  = "[0-#{ @max }] "
+  end
+
+  def ask()
+    puts  @msg
+    @choices.each_with_index do |choice,idx|
+      print "#{idx}. #{choice}\n"
+    end
+    print @prompt
+    answer = $stdin.gets.chomp
+
+    ask() if answer.empty? # we ask here because ''.to_i == 0
+
+    case answer.to_i
+      when 0 ... @max
+        @value = answer
+      else
+        ask()
+    end
+    return []
+  end
+end
+
+class Wizzard
+  VERSION = 0.04
+  attr_accessor :options, :ignore_previous, :ignore_auto, :target
+  def initialize()
+    if File.exists?(ENV['HOME'] + '/.mcabberrc')
+      @target = ENV['HOME'] + '/.mcabberrc'
+    else
+      Dir.mkdir(ENV['HOME'] + '/.mcabber') unless File.exists?(ENV['HOME'] + '/.mcabber')
+      @target = ENV['HOME'] + '/.mcabber/mcabberrc'
+    end
+    @ignore_previous = false
+    @ignore_auto     = false
+    @options   = Hash.new
+    @order     = Array.new
+    @processed = Array.new
+    @old     = Array.new # for storing the users file untouched
+  end
+
+  ##
+  # add a group of settings to the order queue
+  def enqueue(group)
+    group = group.to_a if group.class.to_s == 'String'
+    @order += group
+  end
+
+
+  ## adds options to the settings object
+  def add(args)
+    @options[args[:name]] = args[:type].new(args)
+  end
+
+  ## run the wizzard
+  def run()
+    parse()
+    display(@order)
+    save()
+  end
+
+  ##
+  # displays the setting and allows the user to modify it
+  def display(order)
+    order.each do |name|
+      # this line here is less efficient then on the end of this method
+      # but if placed on the end, recursion then breaks the order of settings
+      @processed.push(name)
+      ##
+      # I know this is not efficient, but I have no better idea to modify the default port
+      @options['port'].default = 5223 if @options['ssl'].value == 1
+
+      puts
+      puts "'#{name}'"
+      puts @options[name].msg
+      puts 'e'.green + 'dit setting'
+      puts 'l'.green + 'eave current setting ' + show(@options[name],:current).cyan unless @options[name].current.nil?
+      puts 'u'.green + 'se default ' + show(@options[name],:default).cyan unless @options[name].default.nil?
+      puts 's'.green + 'kip'
+      puts 'a'.red + 'bort configuration'
+      print '[action]: '
+      case $stdin.gets.chomp
+        when /^s/
+          next
+        when /^l/
+          @options[name].value = @options[name].current
+	  display(@options[name].additional) if @options[name].additional?
+        when /^u/
+          @options[name].value = @options[name].default
+	  display(@options[name].additional) if @options[name].additional?
+        when /^e/
+          additional = @options[name].ask
+	  display(additional) if additional.empty?
+	when /^a/
+	  puts 'aborted!!'.red
+	  exit
+      end
+     end
+  end
+
+  ##
+  # this allows us to print 'yes' 'no' or descriptions of multi option settings
+  # insted of just showing an integer
+  def show(option,type)
+    value = ''
+    if type == :default
+      value = option.default
+    else
+      value = option.current
+    end
+
+    case option.class.to_s
+      when 'YesNo'
+        return (value.to_i==1) ? 'yes' : 'no'
+      when 'Multi'
+        return option.choices[value.to_i]
+      else
+        return value.to_s
+    end
+  end
+
+  ## save
+  # save all settings to a file
+  def save()
+    flag,dumped = true,false
+    target	= File.new(@target,"w")
+
+    @old.each do |line|
+      flag = false if line =~ /^#BEGIN AUTO GENERATED SECTION/
+      flag = true  if line =~ /^#END AUTO GENERATED SECTION/
+      if flag
+        target << line
+      elsif( !flag && !dumped )
+        target << "#BEGIN AUTO GENERATED SECTION\n\n"
+        @processed.each do |name|
+          target << @options[name].to_s + "\n" if @options[name].set?
+        end
+	puts
+	dumped = true
+      end
+    end
+
+    unless dumped
+      target << "#BEGIN AUTO GENERATED SECTION\n\n"
+      @processed.each do |name|
+        target << @options[name].to_s + "\n" if @options[name].set?
+      end
+      target << "#END AUTO GENERATED SECTION\n\n"
+    end
+
+    target.close
+  end
+  ## parse
+  # attempt to load settings from file
+  def parse()
+    return if @ignore_previous
+    return unless File.exists?(@target)
+    keyreg = @options.keys.join('|')
+    parse  = true
+    File.open(@target) do |config|
+      config.each do |line|
+
+        @old << line
+	parse = false if @ignore_auto && line =~ /^#BEGIN AUTO GENERATED SECTION/
+	parse = true  if @ignore_auto && line =~ /^#END AUTO GENERATED SECTION/
+
+	if parse && line =~ /^set\s+(#{keyreg})\s*=\s*(.+)$/
+	  @options[$1].current = $2 if @options.has_key?($1)
+	end
+
+      end
+    end
+  end
+
+  ##
+  # display onscreen help
+  def Wizzard.help()
+    puts %{
+Usage: #{ $0.to_s.blue } #{ 'options'.green }
+
+This script generates configuration files for mcabber jabber client
+
+#{ "Options:".green }
+#{ "-h".green }, #{ "--help".green }		display this help screen
+#{ "-v".green }, #{ "--version".green }		display version information
+#{ "-T".green }, #{ "--target".green }		configuration file
+#{ "-i".green }, #{ "--ignore".green }		ignore previous configuration
+#{ "-I".green }, #{ "--ignore-auto".green }	ignore auto generated section
+#{ "-S".green }, #{ "--status".green }		ask for status settings
+#{ "-P".green }, #{ "--proxy".green }		ask for proxy settings
+#{ "-k".green }, #{ "--keep".green }		ping/keepalive connection settings
+#{ "-t".green }, #{ "--tracelog".green }		ask for tracelog settings
+#{ "-C".green }, #{ "--nocolor".green }		turn of color output
+    }
+    exit
+  end
+
+  ##
+  # display version information
+  def Wizzard.version()
+    puts "mcwizz v#{VERSION.to_s.purple} coded by #{ 'Karql'.purple } & #{ 'mulander'.purple } <netprobe@gmail.com>"
+    exit
+  end
+end
+
+required	= %w{ 	username server resource nickname ssl port pgp logging }
+proxy 		= %w{ 	proxy_host proxy_port proxy_user proxy_pass }
+status		= %w{ 	buddy_format roster_width show_status_in_buffer autoaway message message_avail message_free
+			message_dnd message_notavail message_away message_autoaway }
+tracelog	= %w{	tracelog_level tracelog_file }
+
+opts = GetoptLong.new(
+  ["--help","-h",       GetoptLong::NO_ARGUMENT],
+  ["--version","-v",    GetoptLong::NO_ARGUMENT],
+  ["--target", "-T",	GetoptLong::REQUIRED_ARGUMENT],
+  ["--ignore","-i",     GetoptLong::NO_ARGUMENT],
+  ["--ignore-auto","-I",GetoptLong::NO_ARGUMENT],
+  ["--proxy","-P",      GetoptLong::NO_ARGUMENT],
+  ["--keep","-k",       GetoptLong::NO_ARGUMENT],
+  ["--status","-S",     GetoptLong::NO_ARGUMENT],
+  ["--tracelog","-t",   GetoptLong::NO_ARGUMENT],
+  ["--nocolor","-C",   GetoptLong::NO_ARGUMENT]
+)
+
+opts.ordering = GetoptLong::REQUIRE_ORDER
+
+config = Wizzard.new()
+config.enqueue(required)
+config.enqueue( %w{ beep_on_message hide_offline_buddies iq_version_hide_os autoaway } )
+
+##
+# Description of the add() syntax
+# :name - name of the setting
+# :msg  - message displayed to the user
+# :type - type of settings - avaible types are: YesNo, Edit, Multi
+# :default - default setting
+# YesNo type specific flag:
+# :ifSet  - an array of other options, that will be asked if the flag holding option is set to true
+# Edit type specific flag:
+# :regex- regular expression to which input will be compared
+# Multi type specific flag:
+# :choices - an array of possible settings
+#
+
+##
+# here we add all the settings that we want to be able to handle
+
+##
+# ungrouped settings
+config.add(	:name  => 'beep_on_message',
+		:msg   => 'Should mcabber beep when you receive a message?',
+		:type  => YesNo,
+		:default => 0 )
+
+config.add(	:name  => 'hide_offline_buddies',
+		:msg   => 'Display only connected buddies in the roster?',
+		:type  => YesNo,
+		:default => 0 )
+
+config.add(	:name  => 'pinginterval',
+		:msg   => 'Enter pinginterval in seconds for keepalive settings' \
+			  ' set this to 0 to disable.',
+		:type  => Edit,
+		:regex => /^\d+$/,
+		:default => 40)
+
+config.add(	:name  => 'iq_version_hide_os',
+		:msg   => 'Hide Your OS information?',
+		:type  => YesNo,
+		:default => 0 )
+
+
+config.add(	:name  => 'port',
+		:msg   => 'Enter port number',
+		:type  => Edit,
+		:regex => /^\d+$/,
+		:default => 5222 )
+
+##
+# server settings
+config.add(	:name  => 'username',
+		:msg   => 'Your username',
+		:type  => Edit,
+		:regex => /^[^\s\@:<>&\'"]+$/ )
+
+config.add(	:name  => 'server',
+		:msg   => 'Your jabber server',
+		:type  => Edit,
+		:regex => /^\S+$/ )
+
+config.add(	:name  => 'resource',
+		:msg   => 'Resource (If you don\'t know what a resource is, use the default setting)',
+		:type  => Edit,
+		:regex => /^.{1,1024}$/,
+		:default => 'mcabber' )
+
+config.add(	:name  => 'nickname',
+		:msg   => 'Conference nickname (if you skip this setting your username will be used as' \
+			  ' nickname in MUC chatrooms)',
+		:type  => Edit )
+
+##
+# ssl settings
+config.add(	:name  => 'ssl',
+		:msg   => 'Enable ssl?',
+		:type  => YesNo,
+		:ifSet => %w{ ssl_verify ssl_cafile ssl_capath ciphers },
+		:default => 0 )
+
+
+config.add(	:name  => 'ssl_verify',
+		:msg   => 'Set to 0 to disable certificate verification, or non-zero to set desired maximum CA' \
+			  ' verification depth. Use -1 to specify an unlimited depth.',
+		:type  => Edit,
+		:regex => /^(-1)|(\d+)$/,
+		:default => -1 )
+
+config.add(	:name  => 'ssl_cafile',
+		:msg   => 'Set to a path to a CA certificate file (may contain multiple CA certificates)',
+		:type  => Edit )
+
+config.add(	:name  => 'ssl_capath',
+		:msg   => 'Set to a directory containing CA certificates (use c_rehash to generate hash links)',
+		:type  => Edit )
+
+config.add(	:name  => 'ciphers',
+		:msg   => 'Set to a list of desired SSL ciphers (run "openssl ciphers" for a candidate values)',
+		:type  => Edit )
+
+##
+# pgp support
+config.add(	:name  => 'pgp',
+		:msg   => 'Enable OpenPGP support?',
+		:type  => YesNo,
+		:ifSet => %w{ pgp_private_key },
+		:default => 0 )
+
+config.add(	:name  => 'pgp_private_key',
+		:msg   => 'Enter your private key id. You can get the Key Id with gpg: ' \
+			  '"gpg --list-keys --keyid-format long"',
+		:type  => Edit )
+##
+# proxy settings
+config.add(	:name  => 'proxy_host',
+		:msg   => 'Proxy host',
+		:type  => Edit,
+		:regex => /^\S+?\.\S+?$/ )
+
+config.add(	:name  => 'proxy_port',
+		:msg   => 'Proxy port',
+		:type  => Edit,
+		:regex => /^\d+$/,
+		:default => 3128 )
+
+config.add(	:name  => 'proxy_user',
+		:msg   => 'Proxy user',
+		:type  => Edit )
+
+config.add(     :name  => 'proxy_pass',
+		:msg   => 'Proxy pass (will be stored unencrypted an the pass will be echoed during input)',
+		:type  => Edit )
+##
+# trace logs
+config.add(	:name  => 'tracelog_level',
+		:msg   => 'Specify level of advanced traces',
+		:type  => Multi,
+		:choices => [ 	'lvl0: I don\'t want advanced tracing',
+				'lvl1: most events of the log window are written to the file',
+				'lvl2: debug logging (XML etc.)' ],
+		:default => 0 )
+
+config.add(	:name  => 'tracelog_file',
+		:msg   => 'Specify a file to which the logs will be written',
+		:type  => Edit )
+##
+# logging settings
+config.add(	:name  => 'logging',
+		:msg   => 'Enable logging?',
+		:type  => YesNo,
+		:ifSet => %w{ log_win_height log_display_sender load_logs logging_dir log_muc_conf},
+		:default => 1 )
+
+config.add(	:name  => 'log_win_height',
+		:msg   => 'Set log window height (minimum 1)',
+		:type  => Edit,
+		:regex => /^[1-9]\d*/,
+		:default => 5 )
+
+config.add(	:name  => 'log_display_sender',
+		:msg   => 'Display the message sender\'s jid in the log window?',
+		:type  => YesNo,
+		:default => 0 )
+
+config.add(	:name  => 'load_logs',
+		:msg   => 'Enable loading logs?',
+		:type  => YesNo,
+		:default => 1 )
+
+config.add(	:name  => 'logging_dir',
+		:msg   => 'Enter logging directory',
+		:type  => Edit )
+
+config.add(	:name  => 'log_muc_conf',
+		:msg   => 'Log MUC chats?',
+		:ifSet => %w{ load_muc_logs },
+		:type  => YesNo,
+		:default => 1 )
+
+config.add(	:name  => 'load_muc_logs',
+		:msg   => 'Load MUC chat logs?',
+		:type  => YesNo,
+		:default => 0 )
+##
+# status settings
+config.add(	:name  => 'roster_width',
+		:msg   => 'Set buddylist window width (minimum 2)',
+		:type  => Edit,
+		:regex => /^[2-9]\d*$/,
+		:default => 24 )
+
+config.add(	:name  => 'buddy_format',
+		:msg   => 'What buddy format (in status window) do you prefer?',
+		:type  => Multi,
+		:choices => [ 	'<jid/resource>',
+				'name <jid/resource> (name is omitted if same as the jid)',
+				'name/resource (if the name is same as the jid, use <jid/res>',
+				'name (if the name is the same as the jid, use <jid/res>' ] )
+
+config.add(	:name  => 'show_status_in_buffer',
+		:msg   => 'What status changes should be displayed in the buffer?',
+		:type  => Multi,
+		:choices => [	'none',
+				'connect/disconnect',
+				'all' ],
+		:default => 2 )
+
+config.add(	:name  => 'autoaway',
+		:msg   => 'After how many seconds of inactivity should You become away? (0 for never)',
+		:type  => Edit,
+		:regex => /^\d+$/,
+		:default => 0 )
+
+config.add(	:name  => 'message',
+		:msg   => 'Skip this setting unless you want to override all other status messages',
+		:type  => Edit )
+
+config.add(	:name  => 'message_avail',
+		:message   => 'Set avaible status',
+		:type  => Edit,
+		:default => 'I\'m avaible' )
+
+
+config.add(	:name  => 'message_free',
+		:message   => 'Set free for chat status',
+		:type  => Edit,
+		:default => 'I\'m free for chat' )
+
+config.add(	:name  => 'message_dnd',
+		:message   => 'Set do not disturb status',
+		:type  => Edit,
+		:default => 'Please do not disturb' )
+
+config.add(	:name  => 'message_notavail',
+		:message   => 'Set not avaible status',
+		:type  => Edit,
+		:default => 'I\'m not avaible' )
+
+config.add(	:name  => 'message_away',
+		:message   => 'Set away status',
+		:type  => Edit,
+		:default => 'I\'m away' )
+
+config.add(	:name  => 'message_autoaway',
+		:msg   => 'Set auto-away status',
+		:type  => Edit,
+		:default => 'Auto-away' )
+
+begin
+  opts.each do |opt,arg|
+    case opt
+      when '--help'
+        Wizzard.help()
+      when '--version'
+        Wizzard.version()
+      when '--target'
+        config.target          = arg
+      when '--ignore'
+        config.ignore_previous = true
+      when '--ignore-auto'
+        config.ignore_auto     = true
+      when '--proxy'
+        config.enqueue(proxy)
+      when '--keep'
+        config.enqueue('pinginterval')
+      when '--tracelog'
+        config.enqueue(tracelog)
+      when '--status'
+        config.enqueue(status)
+      when '--nocolor'
+        class String; @@color = false; end
+    end
+  end
+rescue GetoptLong::InvalidOption
+  Wizzard.help()
+end
+
+config.run