use strict; use Text::Iconv; use vars qw($VERSION %IRSSI); ######## RECODE PREFERENCE ######## # BASIC DEFINITION our $iconv_utf8 = Text::Iconv->new("utf-8", "utf-8"); our $iconv_iso8859_1_in = Text::Iconv->new("iso8859-1", "utf-8"); our $iconv_iso8859_1_out= Text::Iconv->new("utf-8", "iso8859-1"); our $iconv_big5_in = Text::Iconv->new("Big5", "utf-8"); our $iconv_big5_out = Text::Iconv->new("utf-8", "Big5"); # YOUR PREFERENCE # this is for "Default Big5, and fallback for UTF-8". our $iconv_in_fallback = $iconv_utf8; our $iconv_default_in = $iconv_big5_in; our $iconv_default_out = $iconv_big5_out; #### OTHER SAMPLES #our $iconv_in_fallback = Text::Iconv->new("utf-8", "utf-8"); #our $iconv_default_in = Text::Iconv->new("big5//translit", "utf-8"); #our $iconv_default_out = Text::Iconv->new("utf-8", "big5//translit"); ######## CHANNEL CONFIGURATION ######## our %conversions_in = ( '#ntucsie' => $iconv_big5_in, '#ntucsie8' => $iconv_utf8, ); our %conversions_out = ( '#ntucsie' => $iconv_big5_out, '#ntucsie8' => $iconv_utf8, ); ######## $VERSION = "0.2"; %IRSSI = ( authors => 'Marcin Kowalczyk, changes by Timo Sirainen, Taneli Kaivola, Kuang-che Wu and Geert Hauwawerts', name => 'recode', description => 'Charset translator - defaults to UTF-8 with fallback to ISO-8859-15', license => 'GPLv2' ); our %workers_pre = (); our %workers_post = (); our %locks = (); sub wrapper { my $signal = Irssi::signal_get_emitted(); return if $locks{$signal}; &{$workers_pre{$signal}} or return; $locks{$signal} = 1; Irssi::signal_emit($signal, @_); $locks{$signal} = 0; &{$workers_post{$signal}}; Irssi::signal_stop(); } sub signal_add_good { my ($signal, $worker_pre, $worker_post) = @_; $workers_pre{$signal} = $worker_pre; $workers_post{$signal} = $worker_post || sub {}; Irssi::signal_add($signal, \&wrapper); } sub convert { my ($iconv, $s_in) = @_; local $SIG{'__WARN__'} = sub {}; my $s_out = $iconv->convert($s_in); if (!defined $s_out) { $s_out = $iconv_in_fallback->convert($s_in); defined $s_out or $s_out = "$s_in \cc7,1[conversion error]\co"; } return $s_out; } our $last_own; sub sig_message_own { if (defined $last_own) {$_[1] = $last_own; return 1} return 0; } signal_add_good("message own_public", \&sig_message_own); signal_add_good("message own_private", \&sig_message_own); signal_add_good("message irc own_action", \&sig_message_own); signal_add_good("message dcc own", \&sig_message_own); signal_add_good("message dcc own_action", \&sig_message_own); sub get_converter_in { my $converter = $conversions_in{lc $_[0]}; $converter = $iconv_default_in if (!$converter); return $converter; } sub get_converter_out { my $converter = $conversions_out{lc $_[0]}; $converter = $iconv_default_out if (!$converter); return $converter; } sub sig_command_msg { $_[0] =~ /^((?:-\S+ )*)([^ ]+) (.*)$/ or return 0; my ($opt, $who, $msg) = ($1, $2, $3); (my $who1 = $who) =~ s/^=//; $who1 =~ s/^"(.+)"$/$1/; my $converter; if ($msg =~ /^([\S]+): / && Irssi::settings_get_bool("channelthingy")) { # 'nick: ' in channel. $converter = $conversions_out{lc $1}; } $converter = get_converter_out($who1) if (!$converter); if ($converter) { $last_own = $msg; $msg = convert($converter, $msg); $_[0] = "$opt$who $msg"; return 1; } return 0; } sub undef_last_own {undef $last_own} signal_add_good("command msg", \&sig_command_msg, \&undef_last_own); sub sig_command_me { my $converter = get_converter_out($_[2]->{name}); if ($converter) { $last_own = $_[0]; $_[0] = convert($converter, $_[0]); return 1; } return 0; } signal_add_good("command me", \&sig_command_me, \&undef_last_own); sub sig_command_action { $_[0] =~ /^([^ ]+) (.*)$/ or return 0; my ($who, $msg) = ($1, $2, $3); (my $who1 = $who) =~ s/^=//; my $converter = get_converter_out($who1); if ($converter) { $last_own = $msg; $msg = convert($converter, $msg); $_[0] = "$who $msg"; return 1; } return 0; } signal_add_good("command action", \&sig_command_action, \&undef_last_own); sub sig_message_public { # first check for target my $converter = get_converter_in($_[4]); # if not found, use the origin nick $converter = $converter || get_converter_in($_[2]); if ($converter) {$_[1] = convert($converter, $_[1]); return 1} return 0; } signal_add_good("message public", \&sig_message_public); sub sig_message_private { my $converter = get_converter_in($_[2]); if ($converter) {$_[1] = convert($converter, $_[1]); return 1} return 0; } signal_add_good("message private", \&sig_message_private); signal_add_good("message irc action", \&sig_message_private); sub sig_message_dcc { my $converter = get_converter_in($_[0]->{nick}); if ($converter) {$_[1] = convert($converter, $_[1]); return 1} return 0; } signal_add_good("message dcc", \&sig_message_dcc); signal_add_good("message dcc action", \&sig_message_dcc); sub sig_event_topic { my ($chan,$topic)=split(" :",$_[1],2); my $converter = get_converter_in($chan); if($converter) { $topic = convert($converter,$topic); $_[1]="$chan :$topic"; return 1; } return 0; } signal_add_good("event topic", \&sig_event_topic); signal_add_good("event 332",\&sig_event_topic); sub sig_command_topic { my $converter = get_converter_out($_[2]->{name}); if($converter) { $_[0] = convert($converter,$_[0]); return 1} return 0; } signal_add_good("command topic", \&sig_command_topic); sub sig_message_part { my $converter = get_converter_in($_[1]); if($converter) { $_[4] = convert($converter,$_[4]); return 1} return 0; } signal_add_good("message part",\&sig_message_part); sub sig_command_part { my $converter = get_converter_out($_[2]->{name}); if($converter) { $_[0] = convert($converter,$_[0]); return 1} return 0; } signal_add_good("command part",\&sig_command_part); sub sig_message_quit { my $converter = get_converter_in($_[1]); if($converter) { $_[3] = convert($converter,$_[3]); return 1;} return 0; } signal_add_good("message quit",\&sig_message_quit); sub sig_command_quit { my $converter = $iconv_default_out; #TODO: Any better ideas? if($converter) { $_[0] = convert($converter,$_[0]); return 1} return 0; } signal_add_good("command quit",\&sig_command_quit); Irssi::settings_add_bool("misc", "channelthingy", 0);