1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
|
# -*- cperl -*-
# -----------------------------------------------------------------------------
# $Id: AliasDB.pm 11365 2008-05-10 14:58:28Z topia $
# -----------------------------------------------------------------------------
# エイリアスファイルの読み込みと生成、#(name|nick)といった文字列の置換を行なうクラス。
# Tiarraモジュールではない。
# このクラスは共通のインスタンスを一つだけ持つ。
# -----------------------------------------------------------------------------
package Auto::AliasDB;
use strict;
use warnings;
use IO::File;
use File::stat;
use Module::Use qw(Auto::AliasDB::CallbackUtils Tools::GroupDB Tools::Hash);
use Auto::AliasDB::CallbackUtils;
use Tools::GroupDB;
use Tools::Hash;
use Mask;
use Configuration;
use Configuration::Block;
use Tiarra::SharedMixin;
use Tiarra::Utils;
our $_shared_instance;
Tiarra::Utils->define_attr_getter(1, qw(database config));
Tiarra::Utils->define_proxy('database', 1,
[qw(add_alias add_group)],
map { [$_.'_prefix', $_.'_primary'] }
qw(add_value_with del_value_with));
sub setfile {
# クラス関数。
my ($fpath,$charset) = @_;
# re-initialize
__PACKAGE__->_shared_init($fpath,$charset);
}
sub _new {
# fpathを省略するか空の文字列を指定すると、空のAliasDBが作られます。
my ($class,$fpath,$charset) = @_;
my $obj = {
database => Tools::GroupDB->new($fpath, 'user', $charset || undef, 0),
config => Configuration::shared_conf->get(__PACKAGE__)
|| Configuration::Block->new(__PACKAGE__),
};
bless $obj,$class;
}
sub find_alias_prefix {
# userinfoはnick!user@hostの形式。
# 見付からなければundefを返す。
# flagに付いてはfind_alias参照。
my ($class_or_this, $userinfo, $flag) = @_;
my $this = $class_or_this->_this;
return $this->find_alias('user', $userinfo, $flag);
}
sub find_alias {
# on not found return 'undef'
# $keys is ref[array or scalar]
# $values is ref[array or scalar]
# $flag is public_alias flag. true is 'public', default false.
my ($class_or_this, $keys, $values, $flag) = @_;
my $this = $class_or_this->_this;
$flag = 0 unless defined($flag);
my $person = $this->{database}->find_group($keys, $values);
if (defined($person)) {
if ($flag) {
# public. remove private alias.
return $this->remove_private(dup_struct($person));
} else {
# not public
return $person;
}
}
return undef;
}
sub add_value {
my ($class_or_this, $alias, $key, $value) = @_;
return $alias->add_value($key, $value);
}
sub del_value {
my ($class_or_this, $alias, $key, $value) = @_;
return $alias->del_value($key, $value);
}
# alias misc functions
sub find_alias_with_stdreplace {
my ($class_or_this, $nick, $name, $host, $prefix, $flag) = @_;
my $this = $class_or_this->_this;
return add_stdreplace(dup_struct($this->find_alias_prefix($prefix, $flag)),
$nick, $name, $host, $prefix);
}
sub add_stdreplace {
my ($alias, $nick, $name, $host, $prefix) = @_;
$alias = Tools::Hash->new() unless defined($alias);
$alias->{'nick.now'} = $nick;
$alias->{'user.now'} = $name;
$alias->{'host.now'} = $host;
$alias->{'prefix.now'} = $prefix;
return $alias;
}
sub remove_private {
my ($class_or_this, $alias, $prefix, $suffix) = @_;
my $this = $class_or_this->_this;
$prefix = '' unless defined($prefix);
$suffix = '' unless defined($suffix);
foreach my $remove_key ($this->config->private('all')) {
delete $alias->{$prefix . $remove_key . $suffix};
}
return $alias;
}
sub check_readonly {
my ($class_or_this, $keys) = @_;
my $this = $class_or_this->_this;
foreach my $check_key ($this->config->readonly('all')) {
@$keys = grep {
$_ ne $check_key;
} @$keys;
}
return $keys;
}
sub dup_struct {
my ($alias) = @_;
return undef unless defined($alias);
return $alias->clone;
}
sub concat_string_to_key {
return Tools::GroupDB::concat_string_to_key(@_);
}
# first param should be Tool::Hash.
sub get_value_random { shift->get_value_random(@_); }
sub get_value { shift->get_value(@_) }
sub get_array { shift->get_array(@_) }
# replace support functions
sub replace {
# エイリアスマクロの置換を行なう。%optionalは置換に追加するキーと値の組みで、省略可。
# optionalの値はSCALARでもARRAY<SCALAR>でも良い。
# userinfoはnick!user@hostの形式。
my ($class_or_this,$userinfo,$str,%optional) = @_;
my $this = $class_or_this->_this;
$this->replace_with_callbacks($userinfo,$str,undef,%optional);
}
sub stdreplace {
my ($class_or_this, $userinfo, $str, $msg, $sender, %optional) = @_;
my $this = $class_or_this->_this;
my (@callbacks);
return $this->stdreplace_add($userinfo, $str, \@callbacks, $msg, $sender, %optional);
}
sub stdreplace_add {
my ($class_or_this, $userinfo, $str, $callbacks, $msg, $sender, %optional) = @_;
my $this = $class_or_this->_this;
Auto::AliasDB::CallbackUtils::register_stdcallbacks($callbacks, $msg, $sender);
my ($add_alias) = add_stdreplace(
undef,
$msg->nick || RunLoop->shared->current_nick,
$msg->name,
$msg->host,
$msg->prefix);
return $this->replace_with_callbacks($userinfo, $str, $callbacks, %optional, %$add_alias);
}
sub replace_with_callbacks {
# エイリアスマクロの置換を行なう。%optionalは置換に追加するキーと値の組みで、省略可。
# $callbacksはalias/optionalで置換できなかった際に呼び出されるコールバック関数のリファレンス。
# optionalの値はSCALARでもARRAY<SCALAR>でも良い。
# userinfoはnick!user@hostの形式。
my ($class_or_this,$userinfo,$str,$callbacks,%optional) = @_;
my $this = $class_or_this->_this;
return $this->{database}->replace_with_callbacks($userinfo, $str, $callbacks, %optional);
}
1;
|