| 1 | package Mobirc::Util; |
|---|
| 2 | use strict; |
|---|
| 3 | use warnings; |
|---|
| 4 | use base 'Exporter'; |
|---|
| 5 | use Carp; |
|---|
| 6 | use List::MoreUtils qw/any/; |
|---|
| 7 | use Encode; |
|---|
| 8 | |
|---|
| 9 | our @EXPORT = qw/true false DEBUG compact_channel_name normalize_channel_name add_message daemonize decorate_irc_color/; |
|---|
| 10 | |
|---|
| 11 | sub true () { 1 } ## no critic. |
|---|
| 12 | sub false () { 0 } ## no critic. |
|---|
| 13 | |
|---|
| 14 | sub DEBUG($) { ## no critic. |
|---|
| 15 | my $txt = shift; |
|---|
| 16 | print "$txt\n" if $ENV{DEBUG}; |
|---|
| 17 | } |
|---|
| 18 | |
|---|
| 19 | # ------------------------------------------------------------------------- |
|---|
| 20 | # shorten channel name |
|---|
| 21 | |
|---|
| 22 | sub compact_channel_name { |
|---|
| 23 | local ($_) = shift; |
|---|
| 24 | |
|---|
| 25 | # #name:*.jp to %name |
|---|
| 26 | if (s/:\*\.jp$//) { |
|---|
| 27 | s/^#/%/; |
|---|
| 28 | } |
|---|
| 29 | |
|---|
| 30 | # 末尾の単独の @ は取る (plumプラグインのmulticast.plm対策) |
|---|
| 31 | s/\@$//; |
|---|
| 32 | |
|---|
| 33 | $_; |
|---|
| 34 | } |
|---|
| 35 | |
|---|
| 36 | # ------------------------------------------------------------------------- |
|---|
| 37 | |
|---|
| 38 | sub normalize_channel_name { |
|---|
| 39 | local ($_) = shift; |
|---|
| 40 | tr/A-Z[\\]^/a-z{|}~/; |
|---|
| 41 | $_; |
|---|
| 42 | } |
|---|
| 43 | |
|---|
| 44 | # ------------------------------------------------------------------------- |
|---|
| 45 | |
|---|
| 46 | sub add_message { |
|---|
| 47 | my ( $poe, $channel, $who, $msg, $class ) = @_; |
|---|
| 48 | carp "hmmm... class missing?" unless $class; |
|---|
| 49 | |
|---|
| 50 | DEBUG "ADD MESSAGE TO $channel($class)"; |
|---|
| 51 | |
|---|
| 52 | # validation |
|---|
| 53 | unless (Encode::is_utf8($msg)) { |
|---|
| 54 | croak "msg shuld be flagged utf8"; |
|---|
| 55 | } |
|---|
| 56 | if ($who && !Encode::is_utf8($who)) { |
|---|
| 57 | croak "who shuld be flagged utf8 : $who"; |
|---|
| 58 | } |
|---|
| 59 | unless (Encode::is_utf8($channel)) { |
|---|
| 60 | croak "channel shuld be flagged utf8"; |
|---|
| 61 | } |
|---|
| 62 | |
|---|
| 63 | my $heap = $poe->kernel->alias_resolve('irc_session')->get_heap; |
|---|
| 64 | |
|---|
| 65 | my $config = $heap->{config} or die "missing config in heap"; |
|---|
| 66 | |
|---|
| 67 | my $row = { |
|---|
| 68 | channel => $channel, |
|---|
| 69 | who => $who, |
|---|
| 70 | msg => $msg, |
|---|
| 71 | class => $class, |
|---|
| 72 | time => time(), |
|---|
| 73 | }; |
|---|
| 74 | |
|---|
| 75 | my $canon_channel = normalize_channel_name($channel); |
|---|
| 76 | |
|---|
| 77 | # update message log |
|---|
| 78 | $heap->{channel_buffer}->{$canon_channel} ||= []; |
|---|
| 79 | push @{ $heap->{channel_buffer}->{$canon_channel} }, $row; |
|---|
| 80 | if ( @{ $heap->{channel_buffer}->{$canon_channel} } > $config->{httpd}->{lines} ) { |
|---|
| 81 | shift @{$heap->{channel_buffer}->{$canon_channel}}; # trash old one. |
|---|
| 82 | } |
|---|
| 83 | |
|---|
| 84 | # update recent messages buffer |
|---|
| 85 | $heap->{channel_recent}->{$canon_channel} ||= []; |
|---|
| 86 | push @{$heap->{channel_recent}->{$canon_channel}}, $row; |
|---|
| 87 | if ( @{$heap->{channel_recent}->{$canon_channel}} > $config->{httpd}->{lines}) { |
|---|
| 88 | shift @{$heap->{channel_recent}->{$canon_channel}}; # trash old one. |
|---|
| 89 | } |
|---|
| 90 | |
|---|
| 91 | # update unread lines |
|---|
| 92 | $heap->{unread_lines}->{$canon_channel} = scalar grep { |
|---|
| 93 | $_->{class} eq "public" || |
|---|
| 94 | $_->{class} eq "notice" |
|---|
| 95 | } @{ $heap->{channel_recent}->{$canon_channel} }; |
|---|
| 96 | |
|---|
| 97 | # update keyword buffer. |
|---|
| 98 | if ($row->{class} eq 'public') { |
|---|
| 99 | if (any { $row->{msg} =~ /$_/i } @{$config->{global}->{keywords} || []}) { |
|---|
| 100 | update_keyword_buffer($poe, $row); |
|---|
| 101 | } |
|---|
| 102 | } |
|---|
| 103 | |
|---|
| 104 | $row; |
|---|
| 105 | } |
|---|
| 106 | |
|---|
| 107 | # ------------------------------------------------------------------------- |
|---|
| 108 | |
|---|
| 109 | sub update_keyword_buffer { |
|---|
| 110 | my ($poe, $row) = @_; |
|---|
| 111 | |
|---|
| 112 | my $heap = $poe->kernel->alias_resolve('irc_session')->get_heap; |
|---|
| 113 | my $config = $heap->{config} or die "missing config in heap"; |
|---|
| 114 | |
|---|
| 115 | push @{$heap->{keyword_buffer}}, $row; |
|---|
| 116 | if ( @{$heap->{keyword_buffer}} > $config->{httpd}->{lines}) { |
|---|
| 117 | shift @{ $heap->{keyword_buffer} }; # trash old one. |
|---|
| 118 | } |
|---|
| 119 | |
|---|
| 120 | push @{$heap->{keyword_recent}}, $row; |
|---|
| 121 | if ( @{$heap->{keyword_recent}} > $config->{httpd}->{lines}) { |
|---|
| 122 | shift @{ $heap->{keyword_recent} }; # trash old one. |
|---|
| 123 | } |
|---|
| 124 | } |
|---|
| 125 | |
|---|
| 126 | # ------------------------------------------------------------------------- |
|---|
| 127 | |
|---|
| 128 | sub daemonize { |
|---|
| 129 | my $pid_fname = shift; |
|---|
| 130 | |
|---|
| 131 | require Proc::Daemon; |
|---|
| 132 | Proc::Daemon::Init(); |
|---|
| 133 | if ( defined $pid_fname ) { |
|---|
| 134 | open my $pid, '>', $pid_fname or die "cannot open pid file: $pid_fname"; |
|---|
| 135 | $pid->print("$$\n"); |
|---|
| 136 | close $pid; |
|---|
| 137 | } |
|---|
| 138 | } |
|---|
| 139 | |
|---|
| 140 | 1; |
|---|