root/lang/perl/tiarra/module/Log/Logger.pm @ 3004

Revision 3004, 3.9 kB (checked in by topia, 5 years ago)

lang/perl/tiarra: import.

  • Property svn:mime-type set to text/x-perl; charset=EUC-JP
  • Property svn:eol-style set to LF
  • Property svn:keywords set to Id URL Date Rev Author
Line 
1# -----------------------------------------------------------------------------
2# $Id$
3# -----------------------------------------------------------------------------
4package Log::Logger;
5use strict;
6use warnings;
7use Multicast;
8
9sub new {
10    my ($class,$enstringed_callback,$exception_object,@exceptions) = @_;
11    # enstringed_callback:
12    #   メッセージをログ文字列化した時に呼ばれる関数。CODE型。
13    #   引数を二つ取り、一つ目はチャンネル名、二つ目はログ文字列。
14    # exception_object:
15    #   exceptionsで指定されたメソッドを呼ぶとき、どのオブジェクトで呼ぶか。
16    # exceptions:
17    #   特定のメッセージのログ文字列化をオーバーライドする
18    #   'S_PRIVMSG'等。
19    #   引数は(Tiarra::IRC::Message,IrcIO)、戻り値は[チャンネル名,ログ文字列]の配列
20    my $this = {
21        enstringed => $enstringed_callback,
22        exception_object => $exception_object,
23        exceptions => do {
24            my %hash = map { $_ => 1 } @exceptions;
25            \%hash;
26        },
27    };
28    bless $this,$class;
29}
30
31sub log {
32    my ($this,$msg,$sender) = @_;
33    my $prefix = do {
34        if ($sender->isa('IrcIO::Server')) {
35            'S';
36        }
37        elsif ($sender->isa('IrcIO::Client')) {
38            'C';
39        }
40    };
41    my $method_name = "${prefix}_".$msg->command;
42    my @results;
43    # このメソッドはexceptionsで定義されているか?
44    if (defined $this->{exceptions}->{$method_name}) {
45        eval {
46            @results = $this->{exception_object}->$method_name($msg,$sender);
47        }; if ($@) {
48            RunLoop->shared->notify_error($@);
49        }
50    }
51    else {
52        # このクラスにメソッドはあるか?
53        if ($this->can($method_name)) {
54            eval {
55                @results = $this->$method_name($msg,$sender);
56            }; if ($@) {
57                RunLoop->shared->notify_error($@);
58            }
59        }
60    }
61   
62    foreach (@results) {
63        $this->{enstringed}->($_->[0],$_->[1]);
64    }
65}
66
67sub S_JOIN {
68    my ($this,$msg,$sender) = @_;
69   
70    $msg->param(0) =~ m/^([^\x07]+)(?:\x07(.*))?/;
71    my ($ch_name,$mode) = ($1,(defined $2 ? $2 : ''));
72    $mode =~ tr/ov/@+/;
73
74    [$msg->param(0),
75     sprintf('+ %s%s (%s) to %s',
76             $mode,$msg->nick,$msg->prefix,$msg->param(0))];
77}
78
79sub S_PART {
80    my ($this,$msg,$sender) = @_;
81    if (defined $msg->param(1)) {
82        [$msg->param(0),
83         sprintf('- %s from %s (%s)',
84                 $msg->nick,$msg->param(0),$msg->param(1))];
85    } else {
86        [$msg->param(0),
87         sprintf('- %s from %s',
88                 $msg->nick,$msg->param(0))];
89    }
90}
91
92sub S_KICK {
93    my ($this,$msg,$sender) = @_;
94    # RFC2812には、「サーバはクライアントに複数のチャンネルやユーザのKICKメッセージを
95    # 送っては「いけません」。これは、古いクライアントソフトウェアとの下位互換のためです。」とある。
96    [$msg->param(0),
97     sprintf('- %s by %s from %s (%s)',
98             $msg->param(1),$msg->nick,$msg->param(0),$msg->param(2))];
99}
100
101sub S_INVITE {
102    my ($this,$msg,$sender) = @_;
103    [$msg->param(1),
104        sprintf 'Invited by %s: %s',$msg->nick,$msg->param(1)];
105}
106
107sub S_MODE {
108    my ($this,$msg,$sender) = @_;
109    [$msg->param(0),
110     sprintf('Mode by %s: %s %s',
111             $msg->nick,
112             $msg->param(0),
113             join(' ',@{$msg->params}[1 .. ($msg->n_params - 1)]))];
114}
115
116sub S_NICK {
117    my ($this,$msg,$sender) = @_;
118    my $network_name = $sender->network_name;
119    my $line = do {
120        sprintf(
121            do {
122                if ($msg->param(0) eq $sender->current_nick) {
123                    'My nick is changed (%s -> %s)';
124                }
125                else {
126                    '%s -> %s';
127                }
128            },
129            $msg->nick,
130            $msg->param(0));
131    };
132    my @result;
133    foreach my $ch_name (@{$msg->remark('affected-channels')}) {
134        push @result,[Multicast::attach($ch_name,$network_name),
135                      $line];
136    }
137    @result;
138}
139
140*S_KILL = \&S_QUIT;
141sub S_QUIT {
142    my ($this,$msg,$sender) = @_;
143    my $network_name = $sender->network_name;
144    my @result;
145    foreach my $ch_name (@{$msg->remark('affected-channels')}) {
146        push @result,[Multicast::attach($ch_name,$network_name),
147                      sprintf '! %s (%s)',$msg->nick,$msg->param(0)];
148    }
149    @result;
150}
151
152sub S_TOPIC {
153    my ($this,$msg,$sender) = @_;
154    [$msg->param(0),
155     sprintf('Topic of channel %s by %s: %s',
156             $msg->param(0),
157             $msg->nick,
158             $msg->param(1))];
159}
160
1611;
Note: See TracBrowser for help on using the browser.