Mercurial > hg
comparison mcabber/contrib/mcwizz.rb @ 1148:e86483cb8c39
Update mcwizz setup script (Mulander)
author | Mikael Berthe <mikael@lilotux.net> |
---|---|
date | Sat, 10 Feb 2007 18:43:38 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1147:fcef5d34b7d4 | 1148:e86483cb8c39 |
---|---|
1 #!/usr/bin/ruby -w | |
2 # | |
3 # Copyright (C) 2006,2007 Adam Wolk "Mulander" <netprobe@gmail.com> | |
4 # Copyright (C) 2006 Mateusz Karkula "Karql" | |
5 # | |
6 # This script is provided under the terms of the GNU General Public License, | |
7 # see the file COPYING in the root mcabber source directory. | |
8 # | |
9 # | |
10 | |
11 require 'getoptlong' | |
12 | |
13 ## | |
14 # strings of colors ;) | |
15 module Colors | |
16 @@color = true | |
17 | |
18 ESC = 27.chr | |
19 | |
20 RED = ESC + '[31m' | |
21 GREEN = ESC + '[32m' | |
22 YELLOW= ESC + '[33m' | |
23 BLUE = ESC + '[34m' | |
24 PURPLE= ESC + '[35m' | |
25 CYAN = ESC + '[36m' | |
26 | |
27 BGREEN= ESC + '[42m' | |
28 | |
29 ENDCOL= ESC + '[0m' | |
30 | |
31 def color(color) | |
32 return '[' + self + ']' unless @@color | |
33 color + self + ENDCOL | |
34 end | |
35 def red; color(RED); end | |
36 def green; color(GREEN); end | |
37 def yellow; color(YELLOW); end | |
38 def blue; color(BLUE); end | |
39 def purple; color(PURPLE); end | |
40 def cyan; color(CYAN); end | |
41 def bgreen; color(BGREEN); end | |
42 end | |
43 | |
44 class String; include Colors; end | |
45 | |
46 class Option | |
47 attr_accessor :value, :current, :default | |
48 attr_reader :name,:msg | |
49 | |
50 def initialize(args) | |
51 @name = args[:name] | |
52 @msg = args[:msg] | |
53 @default = args[:default] | |
54 @value = nil | |
55 @current = nil | |
56 @prompt = '' | |
57 end | |
58 | |
59 def set?; !@value.nil?; end | |
60 def to_s; "set #@name=#@value"; end | |
61 def additional?; false; end | |
62 | |
63 def ask() | |
64 puts @msg | |
65 print @prompt | |
66 $stdin.gets.chomp | |
67 end | |
68 | |
69 end | |
70 | |
71 class YesNo < Option | |
72 def initialize(args) | |
73 super(args) | |
74 @ifSet = args[:ifSet] | |
75 @prompt = '[Yes/no]: ' | |
76 end | |
77 def ask() | |
78 # 1 == yes, 0 == no | |
79 case super | |
80 when /^Y/i | |
81 @value = 1 | |
82 return additional() | |
83 when /^N/i | |
84 @value = 0 | |
85 return [] | |
86 else | |
87 puts 'Please answer yes or no' | |
88 puts | |
89 ask() | |
90 end | |
91 end | |
92 | |
93 def additional? | |
94 (@value == 1 && !@ifSet.nil?) ? true : false | |
95 end | |
96 | |
97 def additional | |
98 (@ifSet.nil?) ? [] : @ifSet | |
99 end | |
100 end | |
101 | |
102 class Edit < Option | |
103 def initialize(args) | |
104 super(args) | |
105 @regex = args[:regex] | |
106 @prompt = '[edit]: ' | |
107 end | |
108 def ask() | |
109 answer = super | |
110 if answer.empty? || ( !@regex.nil? && !(answer =~ @regex) ) | |
111 ask() | |
112 else | |
113 @value = answer | |
114 end | |
115 return [] | |
116 end | |
117 end | |
118 | |
119 class Multi < Option | |
120 attr_reader :choices | |
121 def initialize(args) | |
122 super(args) | |
123 @choices = args[:choices] | |
124 @max = @choices.length - 1 | |
125 @prompt = "[0-#{ @max }] " | |
126 end | |
127 | |
128 def ask() | |
129 puts @msg | |
130 @choices.each_with_index do |choice,idx| | |
131 print "#{idx}. #{choice}\n" | |
132 end | |
133 print @prompt | |
134 answer = $stdin.gets.chomp | |
135 | |
136 ask() if answer.empty? # we ask here because ''.to_i == 0 | |
137 | |
138 case answer.to_i | |
139 when 0 ... @max | |
140 @value = answer | |
141 else | |
142 ask() | |
143 end | |
144 return [] | |
145 end | |
146 end | |
147 | |
148 class Wizzard | |
149 VERSION = 0.04 | |
150 attr_accessor :options, :ignore_previous, :ignore_auto, :target | |
151 def initialize() | |
152 if File.exists?(ENV['HOME'] + '/.mcabberrc') | |
153 @target = ENV['HOME'] + '/.mcabberrc' | |
154 else | |
155 Dir.mkdir(ENV['HOME'] + '/.mcabber') unless File.exists?(ENV['HOME'] + '/.mcabber') | |
156 @target = ENV['HOME'] + '/.mcabber/mcabberrc' | |
157 end | |
158 @ignore_previous = false | |
159 @ignore_auto = false | |
160 @options = Hash.new | |
161 @order = Array.new | |
162 @processed = Array.new | |
163 @old = Array.new # for storing the users file untouched | |
164 end | |
165 | |
166 ## | |
167 # add a group of settings to the order queue | |
168 def enqueue(group) | |
169 group = group.to_a if group.class.to_s == 'String' | |
170 @order += group | |
171 end | |
172 | |
173 | |
174 ## adds options to the settings object | |
175 def add(args) | |
176 @options[args[:name]] = args[:type].new(args) | |
177 end | |
178 | |
179 ## run the wizzard | |
180 def run() | |
181 parse() | |
182 display(@order) | |
183 save() | |
184 end | |
185 | |
186 ## | |
187 # displays the setting and allows the user to modify it | |
188 def display(order) | |
189 order.each do |name| | |
190 # this line here is less efficient then on the end of this method | |
191 # but if placed on the end, recursion then breaks the order of settings | |
192 @processed.push(name) | |
193 ## | |
194 # I know this is not efficient, but I have no better idea to modify the default port | |
195 @options['port'].default = 5223 if @options['ssl'].value == 1 | |
196 | |
197 puts | |
198 puts "'#{name}'" | |
199 puts @options[name].msg | |
200 puts 'e'.green + 'dit setting' | |
201 puts 'l'.green + 'eave current setting ' + show(@options[name],:current).cyan unless @options[name].current.nil? | |
202 puts 'u'.green + 'se default ' + show(@options[name],:default).cyan unless @options[name].default.nil? | |
203 puts 's'.green + 'kip' | |
204 puts 'a'.red + 'bort configuration' | |
205 print '[action]: ' | |
206 case $stdin.gets.chomp | |
207 when /^s/ | |
208 next | |
209 when /^l/ | |
210 @options[name].value = @options[name].current | |
211 display(@options[name].additional) if @options[name].additional? | |
212 when /^u/ | |
213 @options[name].value = @options[name].default | |
214 display(@options[name].additional) if @options[name].additional? | |
215 when /^e/ | |
216 additional = @options[name].ask | |
217 display(additional) if additional.empty? | |
218 when /^a/ | |
219 puts 'aborted!!'.red | |
220 exit | |
221 end | |
222 end | |
223 end | |
224 | |
225 ## | |
226 # this allows us to print 'yes' 'no' or descriptions of multi option settings | |
227 # insted of just showing an integer | |
228 def show(option,type) | |
229 value = '' | |
230 if type == :default | |
231 value = option.default | |
232 else | |
233 value = option.current | |
234 end | |
235 | |
236 case option.class.to_s | |
237 when 'YesNo' | |
238 return (value.to_i==1) ? 'yes' : 'no' | |
239 when 'Multi' | |
240 return option.choices[value.to_i] | |
241 else | |
242 return value.to_s | |
243 end | |
244 end | |
245 | |
246 ## save | |
247 # save all settings to a file | |
248 def save() | |
249 flag,dumped = true,false | |
250 target = File.new(@target,"w") | |
251 | |
252 @old.each do |line| | |
253 flag = false if line =~ /^#BEGIN AUTO GENERATED SECTION/ | |
254 flag = true if line =~ /^#END AUTO GENERATED SECTION/ | |
255 if flag | |
256 target << line | |
257 elsif( !flag && !dumped ) | |
258 target << "#BEGIN AUTO GENERATED SECTION\n\n" | |
259 @processed.each do |name| | |
260 target << @options[name].to_s + "\n" if @options[name].set? | |
261 end | |
262 puts | |
263 dumped = true | |
264 end | |
265 end | |
266 | |
267 unless dumped | |
268 target << "#BEGIN AUTO GENERATED SECTION\n\n" | |
269 @processed.each do |name| | |
270 target << @options[name].to_s + "\n" if @options[name].set? | |
271 end | |
272 target << "#END AUTO GENERATED SECTION\n\n" | |
273 end | |
274 | |
275 target.close | |
276 end | |
277 ## parse | |
278 # attempt to load settings from file | |
279 def parse() | |
280 return if @ignore_previous | |
281 return unless File.exists?(@target) | |
282 keyreg = @options.keys.join('|') | |
283 parse = true | |
284 File.open(@target) do |config| | |
285 config.each do |line| | |
286 | |
287 @old << line | |
288 parse = false if @ignore_auto && line =~ /^#BEGIN AUTO GENERATED SECTION/ | |
289 parse = true if @ignore_auto && line =~ /^#END AUTO GENERATED SECTION/ | |
290 | |
291 if parse && line =~ /^set\s+(#{keyreg})\s*=\s*(.+)$/ | |
292 @options[$1].current = $2 if @options.has_key?($1) | |
293 end | |
294 | |
295 end | |
296 end | |
297 end | |
298 | |
299 ## | |
300 # display onscreen help | |
301 def Wizzard.help() | |
302 puts %{ | |
303 Usage: #{ $0.to_s.blue } #{ 'options'.green } | |
304 | |
305 This script generates configuration files for mcabber jabber client | |
306 | |
307 #{ "Options:".green } | |
308 #{ "-h".green }, #{ "--help".green } display this help screen | |
309 #{ "-v".green }, #{ "--version".green } display version information | |
310 #{ "-T".green }, #{ "--target".green } configuration file | |
311 #{ "-i".green }, #{ "--ignore".green } ignore previous configuration | |
312 #{ "-I".green }, #{ "--ignore-auto".green } ignore auto generated section | |
313 #{ "-S".green }, #{ "--status".green } ask for status settings | |
314 #{ "-P".green }, #{ "--proxy".green } ask for proxy settings | |
315 #{ "-k".green }, #{ "--keep".green } ping/keepalive connection settings | |
316 #{ "-t".green }, #{ "--tracelog".green } ask for tracelog settings | |
317 #{ "-C".green }, #{ "--nocolor".green } turn of color output | |
318 } | |
319 exit | |
320 end | |
321 | |
322 ## | |
323 # display version information | |
324 def Wizzard.version() | |
325 puts "mcwizz v#{VERSION.to_s.purple} coded by #{ 'Karql'.purple } & #{ 'mulander'.purple } <netprobe@gmail.com>" | |
326 exit | |
327 end | |
328 end | |
329 | |
330 required = %w{ username server resource nickname ssl port pgp logging } | |
331 proxy = %w{ proxy_host proxy_port proxy_user proxy_pass } | |
332 status = %w{ buddy_format roster_width show_status_in_buffer autoaway message message_avail message_free | |
333 message_dnd message_notavail message_away message_autoaway } | |
334 tracelog = %w{ tracelog_level tracelog_file } | |
335 | |
336 opts = GetoptLong.new( | |
337 ["--help","-h", GetoptLong::NO_ARGUMENT], | |
338 ["--version","-v", GetoptLong::NO_ARGUMENT], | |
339 ["--target", "-T", GetoptLong::REQUIRED_ARGUMENT], | |
340 ["--ignore","-i", GetoptLong::NO_ARGUMENT], | |
341 ["--ignore-auto","-I",GetoptLong::NO_ARGUMENT], | |
342 ["--proxy","-P", GetoptLong::NO_ARGUMENT], | |
343 ["--keep","-k", GetoptLong::NO_ARGUMENT], | |
344 ["--status","-S", GetoptLong::NO_ARGUMENT], | |
345 ["--tracelog","-t", GetoptLong::NO_ARGUMENT], | |
346 ["--nocolor","-C", GetoptLong::NO_ARGUMENT] | |
347 ) | |
348 | |
349 opts.ordering = GetoptLong::REQUIRE_ORDER | |
350 | |
351 config = Wizzard.new() | |
352 config.enqueue(required) | |
353 config.enqueue( %w{ beep_on_message hide_offline_buddies iq_version_hide_os autoaway } ) | |
354 | |
355 ## | |
356 # Description of the add() syntax | |
357 # :name - name of the setting | |
358 # :msg - message displayed to the user | |
359 # :type - type of settings - avaible types are: YesNo, Edit, Multi | |
360 # :default - default setting | |
361 # YesNo type specific flag: | |
362 # :ifSet - an array of other options, that will be asked if the flag holding option is set to true | |
363 # Edit type specific flag: | |
364 # :regex- regular expression to which input will be compared | |
365 # Multi type specific flag: | |
366 # :choices - an array of possible settings | |
367 # | |
368 | |
369 ## | |
370 # here we add all the settings that we want to be able to handle | |
371 | |
372 ## | |
373 # ungrouped settings | |
374 config.add( :name => 'beep_on_message', | |
375 :msg => 'Should mcabber beep when you receive a message?', | |
376 :type => YesNo, | |
377 :default => 0 ) | |
378 | |
379 config.add( :name => 'hide_offline_buddies', | |
380 :msg => 'Display only connected buddies in the roster?', | |
381 :type => YesNo, | |
382 :default => 0 ) | |
383 | |
384 config.add( :name => 'pinginterval', | |
385 :msg => 'Enter pinginterval in seconds for keepalive settings' \ | |
386 ' set this to 0 to disable.', | |
387 :type => Edit, | |
388 :regex => /^\d+$/, | |
389 :default => 40) | |
390 | |
391 config.add( :name => 'iq_version_hide_os', | |
392 :msg => 'Hide Your OS information?', | |
393 :type => YesNo, | |
394 :default => 0 ) | |
395 | |
396 | |
397 config.add( :name => 'port', | |
398 :msg => 'Enter port number', | |
399 :type => Edit, | |
400 :regex => /^\d+$/, | |
401 :default => 5222 ) | |
402 | |
403 ## | |
404 # server settings | |
405 config.add( :name => 'username', | |
406 :msg => 'Your username', | |
407 :type => Edit, | |
408 :regex => /^[^\s\@:<>&\'"]+$/ ) | |
409 | |
410 config.add( :name => 'server', | |
411 :msg => 'Your jabber server', | |
412 :type => Edit, | |
413 :regex => /^\S+$/ ) | |
414 | |
415 config.add( :name => 'resource', | |
416 :msg => 'Resource (If you don\'t know what a resource is, use the default setting)', | |
417 :type => Edit, | |
418 :regex => /^.{1,1024}$/, | |
419 :default => 'mcabber' ) | |
420 | |
421 config.add( :name => 'nickname', | |
422 :msg => 'Conference nickname (if you skip this setting your username will be used as' \ | |
423 ' nickname in MUC chatrooms)', | |
424 :type => Edit ) | |
425 | |
426 ## | |
427 # ssl settings | |
428 config.add( :name => 'ssl', | |
429 :msg => 'Enable ssl?', | |
430 :type => YesNo, | |
431 :ifSet => %w{ ssl_verify ssl_cafile ssl_capath ciphers }, | |
432 :default => 0 ) | |
433 | |
434 | |
435 config.add( :name => 'ssl_verify', | |
436 :msg => 'Set to 0 to disable certificate verification, or non-zero to set desired maximum CA' \ | |
437 ' verification depth. Use -1 to specify an unlimited depth.', | |
438 :type => Edit, | |
439 :regex => /^(-1)|(\d+)$/, | |
440 :default => -1 ) | |
441 | |
442 config.add( :name => 'ssl_cafile', | |
443 :msg => 'Set to a path to a CA certificate file (may contain multiple CA certificates)', | |
444 :type => Edit ) | |
445 | |
446 config.add( :name => 'ssl_capath', | |
447 :msg => 'Set to a directory containing CA certificates (use c_rehash to generate hash links)', | |
448 :type => Edit ) | |
449 | |
450 config.add( :name => 'ciphers', | |
451 :msg => 'Set to a list of desired SSL ciphers (run "openssl ciphers" for a candidate values)', | |
452 :type => Edit ) | |
453 | |
454 ## | |
455 # pgp support | |
456 config.add( :name => 'pgp', | |
457 :msg => 'Enable OpenPGP support?', | |
458 :type => YesNo, | |
459 :ifSet => %w{ pgp_private_key }, | |
460 :default => 0 ) | |
461 | |
462 config.add( :name => 'pgp_private_key', | |
463 :msg => 'Enter your private key id. You can get the Key Id with gpg: ' \ | |
464 '"gpg --list-keys --keyid-format long"', | |
465 :type => Edit ) | |
466 ## | |
467 # proxy settings | |
468 config.add( :name => 'proxy_host', | |
469 :msg => 'Proxy host', | |
470 :type => Edit, | |
471 :regex => /^\S+?\.\S+?$/ ) | |
472 | |
473 config.add( :name => 'proxy_port', | |
474 :msg => 'Proxy port', | |
475 :type => Edit, | |
476 :regex => /^\d+$/, | |
477 :default => 3128 ) | |
478 | |
479 config.add( :name => 'proxy_user', | |
480 :msg => 'Proxy user', | |
481 :type => Edit ) | |
482 | |
483 config.add( :name => 'proxy_pass', | |
484 :msg => 'Proxy pass (will be stored unencrypted an the pass will be echoed during input)', | |
485 :type => Edit ) | |
486 ## | |
487 # trace logs | |
488 config.add( :name => 'tracelog_level', | |
489 :msg => 'Specify level of advanced traces', | |
490 :type => Multi, | |
491 :choices => [ 'lvl0: I don\'t want advanced tracing', | |
492 'lvl1: most events of the log window are written to the file', | |
493 'lvl2: debug logging (XML etc.)' ], | |
494 :default => 0 ) | |
495 | |
496 config.add( :name => 'tracelog_file', | |
497 :msg => 'Specify a file to which the logs will be written', | |
498 :type => Edit ) | |
499 ## | |
500 # logging settings | |
501 config.add( :name => 'logging', | |
502 :msg => 'Enable logging?', | |
503 :type => YesNo, | |
504 :ifSet => %w{ log_win_height log_display_sender load_logs logging_dir log_muc_conf}, | |
505 :default => 1 ) | |
506 | |
507 config.add( :name => 'log_win_height', | |
508 :msg => 'Set log window height (minimum 1)', | |
509 :type => Edit, | |
510 :regex => /^[1-9]\d*/, | |
511 :default => 5 ) | |
512 | |
513 config.add( :name => 'log_display_sender', | |
514 :msg => 'Display the message sender\'s jid in the log window?', | |
515 :type => YesNo, | |
516 :default => 0 ) | |
517 | |
518 config.add( :name => 'load_logs', | |
519 :msg => 'Enable loading logs?', | |
520 :type => YesNo, | |
521 :default => 1 ) | |
522 | |
523 config.add( :name => 'logging_dir', | |
524 :msg => 'Enter logging directory', | |
525 :type => Edit ) | |
526 | |
527 config.add( :name => 'log_muc_conf', | |
528 :msg => 'Log MUC chats?', | |
529 :ifSet => %w{ load_muc_logs }, | |
530 :type => YesNo, | |
531 :default => 1 ) | |
532 | |
533 config.add( :name => 'load_muc_logs', | |
534 :msg => 'Load MUC chat logs?', | |
535 :type => YesNo, | |
536 :default => 0 ) | |
537 ## | |
538 # status settings | |
539 config.add( :name => 'roster_width', | |
540 :msg => 'Set buddylist window width (minimum 2)', | |
541 :type => Edit, | |
542 :regex => /^[2-9]\d*$/, | |
543 :default => 24 ) | |
544 | |
545 config.add( :name => 'buddy_format', | |
546 :msg => 'What buddy format (in status window) do you prefer?', | |
547 :type => Multi, | |
548 :choices => [ '<jid/resource>', | |
549 'name <jid/resource> (name is omitted if same as the jid)', | |
550 'name/resource (if the name is same as the jid, use <jid/res>', | |
551 'name (if the name is the same as the jid, use <jid/res>' ] ) | |
552 | |
553 config.add( :name => 'show_status_in_buffer', | |
554 :msg => 'What status changes should be displayed in the buffer?', | |
555 :type => Multi, | |
556 :choices => [ 'none', | |
557 'connect/disconnect', | |
558 'all' ], | |
559 :default => 2 ) | |
560 | |
561 config.add( :name => 'autoaway', | |
562 :msg => 'After how many seconds of inactivity should You become away? (0 for never)', | |
563 :type => Edit, | |
564 :regex => /^\d+$/, | |
565 :default => 0 ) | |
566 | |
567 config.add( :name => 'message', | |
568 :msg => 'Skip this setting unless you want to override all other status messages', | |
569 :type => Edit ) | |
570 | |
571 config.add( :name => 'message_avail', | |
572 :message => 'Set avaible status', | |
573 :type => Edit, | |
574 :default => 'I\'m avaible' ) | |
575 | |
576 | |
577 config.add( :name => 'message_free', | |
578 :message => 'Set free for chat status', | |
579 :type => Edit, | |
580 :default => 'I\'m free for chat' ) | |
581 | |
582 config.add( :name => 'message_dnd', | |
583 :message => 'Set do not disturb status', | |
584 :type => Edit, | |
585 :default => 'Please do not disturb' ) | |
586 | |
587 config.add( :name => 'message_notavail', | |
588 :message => 'Set not avaible status', | |
589 :type => Edit, | |
590 :default => 'I\'m not avaible' ) | |
591 | |
592 config.add( :name => 'message_away', | |
593 :message => 'Set away status', | |
594 :type => Edit, | |
595 :default => 'I\'m away' ) | |
596 | |
597 config.add( :name => 'message_autoaway', | |
598 :msg => 'Set auto-away status', | |
599 :type => Edit, | |
600 :default => 'Auto-away' ) | |
601 | |
602 begin | |
603 opts.each do |opt,arg| | |
604 case opt | |
605 when '--help' | |
606 Wizzard.help() | |
607 when '--version' | |
608 Wizzard.version() | |
609 when '--target' | |
610 config.target = arg | |
611 when '--ignore' | |
612 config.ignore_previous = true | |
613 when '--ignore-auto' | |
614 config.ignore_auto = true | |
615 when '--proxy' | |
616 config.enqueue(proxy) | |
617 when '--keep' | |
618 config.enqueue('pinginterval') | |
619 when '--tracelog' | |
620 config.enqueue(tracelog) | |
621 when '--status' | |
622 config.enqueue(status) | |
623 when '--nocolor' | |
624 class String; @@color = false; end | |
625 end | |
626 end | |
627 rescue GetoptLong::InvalidOption | |
628 Wizzard.help() | |
629 end | |
630 | |
631 config.run |