File: AliasDB.pm

package info (click to toggle)
tiarra 20100212-4
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 2,732 kB
  • ctags: 1,712
  • sloc: perl: 32,032; lisp: 193; sh: 109; makefile: 10
file content (204 lines) | stat: -rw-r--r-- 6,033 bytes parent folder | download | duplicates (4)
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;