2 # Update.pl: Add or modify factoids in the db.
11 use Encode qw(decode_utf8 encode_utf8);
14 my ( $lhs, $mhs, $rhs ) = @_;
16 my $lhs_utf8 = decode_utf8($lhs);
17 my $rhs_utf8 = decode_utf8($rhs);
19 $lhs_utf8 =~ s/^i (heard|think) //i;
20 $lhs_utf8 =~ s/^some(one|1|body) said //i;
21 $lhs_utf8 =~ s/\s+/ /g;
23 for my $temp ($lhs_utf8,$rhs_utf8 ) {
24 if ($temp =~ /([^[:print:]])/ or $temp =~ /(\N{U+FFFD})/) {
25 &status("statement: illegal character '$1' ".ord($1).".");
26 &performAddressedReply(
27 "i'm not going to learn illegal characters");
32 $rhs = encode_utf8($rhs_utf8);
33 $lhs = encode_utf8($lhs_utf8);
36 return if ( &IsLocked($lhs) == 1 );
39 if ( &IsParam('profanityCheck') and &hasProfanity($rhs_utf8) ) {
40 &performReply("please, watch your language.");
45 if ( &IsFlag('t') ne 't' && &IsFlag('o') ne 'o' ) {
46 &msg( $who, "permission denied." );
47 &status("alert: $who wanted to teach me.");
52 if ( $mhs !~ /^(is|are)$/i ) {
53 &ERROR("UNKNOWN verb: $mhs.");
57 # check if the arguments are too long to be stored in our table.
59 $toolong++ if ( length $lhs > $param{'maxKeySize'} );
60 $toolong++ if ( length $rhs > $param{'maxDataSize'} );
62 &performAddressedReply("that's too long");
67 my $also = ( $rhs_utf8 =~ s/^-?also //i );
68 my $also_or = ( $also and $rhs_utf8 =~ s/\s+(or|\|\|)\s+// );
70 $rhs = encode_utf8($rhs_utf8);
71 $lhs = encode_utf8($lhs_utf8);
73 if ( $also or $also_or ) {
74 my $author = &getFactInfo( $from, 'created_by' );
78 # Can they even modify factoids?
79 if ( &IsFlag('m') ne 'm'
80 and &IsFlag('M') ne 'M'
81 and &IsFlag('o') ne 'o' )
83 &performReply("You do not have permission to modify factoids");
86 # If they have +M but they didnt create the factoid
88 elsif ( &IsFlag('M') eq 'M'
89 and $who !~ /^\Q$created_by\E$/i
90 and &IsFlag('m') ne 'm'
91 and &IsFlag('o') ne 'o' )
93 &performReply("factoid '$lhs' is not yours to modify.");
98 # factoid arguments handler.
99 # must start with a non-variable
100 if ( &IsChanConf('factoidArguments') > 0 and $lhs_utf8 =~ /^[^\$]+.*\$/ ) {
101 &status("Update: Factoid Arguments found.");
102 &status("Update: orig lhs => '$lhs'.");
103 &status("Update: orig rhs => '$rhs'.");
107 $lhs_utf8 =~ s/^/cmd: /;
108 while ( $lhs_utf8 =~ s/\$(\S+)/(.*?)/ ) {
109 push( @list, "\$$1" );
111 last if ( $count >= 10 );
114 if ( $count >= 10 ) {
115 &msg( $who, "error: could not SAR properly." );
116 &DEBUG("error: lhs => '$lhs' rhs => '$rhs'.");
120 my $z = join( ',', @list );
121 $rhs_utf8 =~ s/^/($z): /;
123 $rhs = encode_utf8($rhs_utf8);
124 $lhs = encode_utf8($lhs_utf8);
126 &status("Update: new lhs => '$lhs' rhs => '$rhs'.");
130 my $exists = &getFactoid($lhs);
131 my $exists_utf8 = decode_utf8($exists);
135 # nice 'are' hack (or work-around).
136 if ( $mhs =~ /^are$/i and $rhs_utf8 !~ /<\S+>/ ) {
137 &status("Update: 'are' hack detected.");
139 $rhs_utf8 = "<REPLY> are " . $rhs_utf8;
142 $rhs = encode_utf8($rhs_utf8);
143 $lhs = encode_utf8($lhs_utf8);
145 &status("enter: <$who> \'$lhs\' =$mhs=> \'$rhs\'");
148 &performAddressedReply('okay');
154 created_time => time(), # modified time.
156 factoid_value => $rhs,
160 if ( !defined $rhs or $rhs eq '' ) {
161 &ERROR("Update: rhs1 == NULL.");
168 if ( $exists eq $rhs ) {
170 # this catches the following situation: (right or wrong?)
172 # "test is also test"
173 &performAddressedReply("i already had it that way");
177 if ($also) { # 'is also'.
180 my $origlhs_utf8 = $lhs_utf8;
181 while ( $exists_utf8 =~ /^<REPLY> ?see (.*)/i ) {
183 unless ($redircount) {
184 &msg( $who, "$origlhs has too many levels of redirection." );
189 $exists = &getFactoid($lhs);
191 &msg( $who, "$1 is a dangling redirection." );
194 $exists_utf8 = decode_utf8($exists);
197 if ($also_or) { # 'is also ||'.
198 $rhs_utf8 = $exists . ' || ' . $rhs_utf8;
199 $rhs = encode_utf8($rhs_utf8);
200 $lhs = encode_utf8($lhs_utf8);
204 # if ($exists =~ s/\,\s*$/, /) {
205 if ( $exists_utf8 =~ /\,\s*$/ ) {
206 &DEBUG("current has trailing comma, just append as is");
207 &DEBUG("Up: exists => $exists");
208 &DEBUG("Up: rhs => $rhs");
211 # $rhs = $exists." ".$rhs; # keep comma.
214 if ( $exists_utf8 =~ /\.\s*$/ ) {
216 "current has trailing period, just append as is with 2 WS");
217 &DEBUG("Up: exists => $exists");
218 &DEBUG("Up: rhs => $rhs");
222 # $rhs = $exists." ".$rhs; # keep comma.
225 if ( $rhs_utf8 =~ /^[A-Z]/ ) {
226 if ( $rhs_utf8 =~ /\w+\s*$/ ) {
227 &status("auto insert period to factoid.");
228 $rhs_utf8 = $exists_utf8 . ". " . $rhs_utf8;
230 else { # '?' or '.' assumed at end.
232 "orig factoid already had trailing symbol; not adding period."
234 $rhs_utf8 = $exists_utf8 . " " . $rhs_utf8;
237 elsif ( $exists =~ /[\,\.\-]\s*$/ ) {
239 "U: current has trailing symbols; inserting whitespace + new.",
242 $rhs_utf8 = $exists_utf8 . " " . $rhs_utf8;
244 elsif ( $rhs_utf8 =~ /^\./ ) {
245 &VERB( "U: new text starts with period; appending directly", 2 );
246 $rhs_utf8 = $exists_utf8 . $rhs_utf8;
249 $rhs_utf8 = $exists_utf8 . ', or ' . $rhs_utf8;
251 $rhs = encode_utf8($rhs_utf8);
254 # max length check again.
255 if ( length $rhs > $param{'maxDataSize'} ) {
256 if ( length $rhs_utf8 > length $exists_utf8 ) {
257 &performAddressedReply("that's too long");
262 "Update: new length is still longer than maxDataSize but less than before, we'll let it go."
266 $rhs = encode_utf8($rhs_utf8);
267 $lhs = encode_utf8($lhs_utf8);
268 $exists = encode_utf8($exists_utf8);
270 &performAddressedReply('okay');
273 &status("update: <$who> \'$lhs\' =$mhs=> \'$rhs\'; was \'$exists\'");
276 { 'factoid_key' => $lhs },
279 modified_time => time(),
280 factoid_value => $rhs,
284 if ( !defined $rhs or $rhs eq '' ) {
285 &ERROR("Update: rhs1 == NULL.");
290 if ( !$correction_plausible ) { # "no, blah is ..."
293 "...but \002$lhs\002 is already something else...");
294 &status("FAILED update: <$who> \'$lhs\' =$mhs=> \'$rhs\'");
299 my $author = &getFactInfo( $lhs, 'created_by' ) || '';
301 if ( IsFlag('m') ne 'm'
302 && IsFlag('o') ne 'o'
303 && $author !~ /^\Q$who\E\!/i )
305 &msg( $who, "you can't change that factoid." );
309 &performAddressedReply('okay');
312 &status("update: <$who> \'$lhs\' =$mhs=> \'$rhs\'; was \'$exists\'");
316 { 'factoid_key' => $lhs },
319 modified_time => time(),
320 factoid_value => $rhs,
324 if ( !defined $rhs or $rhs eq '' ) {
325 &ERROR("Update: rhs1 == NULL.");
334 # vim:ts=4:sw=4:expandtab:tw=80