]> git.donarmstrong.com Git - infobot.git/blob - src/Factoids/Update.pl
* Fix previous patches missing "and" statements
[infobot.git] / src / Factoids / Update.pl
1 #
2 # Update.pl: Add or modify factoids in the db.
3 #    Author: Kevin Lenzo
4 #            dms
5 #   Version: 19991209
6 #   Created: 1997
7 #
8
9 # use strict;   # TODO
10
11 sub update {
12     my($lhs, $mhs, $rhs) = @_;
13
14     for ($lhs) {
15         s/^i (heard|think) //i;
16         s/^some(one|1|body) said //i;
17         s/\s+/ /g;
18     }
19
20     # locked.
21     return if (&IsLocked($lhs) == 1);
22
23     # profanity.
24     if (&IsParam('profanityCheck') and &hasProfanity($rhs)) {
25         &performReply("please, watch your language.");
26         return 1;
27     }
28
29     # teaching.
30     if (&IsFlag('t') ne 't' && &IsFlag('o') ne 'o') {
31         &msg($who, "permission denied.");
32         &status("alert: $who wanted to teach me.");
33         return 1;
34     }
35
36     # invalid verb.
37     if ($mhs !~ /^(is|are)$/i) {
38         &ERROR("UNKNOWN verb: $mhs.");
39         return;
40     }
41
42     # check if the arguments are too long to be stored in our table.
43     my $toolong = 0;
44     $toolong++  if (length $lhs > $param{'maxKeySize'});
45     $toolong++  if (length $rhs > $param{'maxDataSize'});
46     if ($toolong) {
47         &performAddressedReply("that's too long");
48         return 1;
49     }
50
51     # also checking.
52     my $also    = ($rhs =~ s/^-?also //i);
53     my $also_or = ($also and $rhs =~ s/\s+(or|\|\|)\s+//);
54
55     if ($also or $also_or) {
56         my $author  = &getFactInfo($from, 'created_by');
57         $author =~ /^(.*)!/;
58         my $created_by = $1;
59
60         # Can they even modify factoids?
61         if (&IsFlag('m') ne 'm' and &IsFlag('M') ne 'M' and &IsFlag('o') ne 'o') {
62             &performReply("You do not have permission to modify factoids");
63             return 1;
64
65         # If they have +M but they didnt create the factoid
66         } elsif (&IsFlag('M') eq 'M' and
67             $who !~ /^\Q$created_by\E$/i and
68             &IsFlag('m') ne 'm' and
69             &IsFlag('o') ne 'o') {
70                 &performReply("factoid '$lhs' is not yours to modify.");
71                 return 1;
72         }
73     }
74
75     # factoid arguments handler.
76     # must start with a non-variable
77     if (&IsChanConf('factoidArguments') > 0 and $lhs =~ /^[^\$]+.*\$/) {
78         &status("Update: Factoid Arguments found.");
79         &status("Update: orig lhs => '$lhs'.");
80         &status("Update: orig rhs => '$rhs'.");
81
82         my @list;
83         my $count = 0;
84         $lhs =~ s/^/cmd: /;
85         while ($lhs =~ s/\$(\S+)/(.*?)/) {
86             push(@list, "\$$1");
87             $count++;
88             last if ($count >= 10);
89         }
90
91         if ($count >= 10) {
92             &msg($who, "error: could not SAR properly.");
93             &DEBUG("error: lhs => '$lhs' rhs => '$rhs'.");
94             return;
95         }
96
97         my $z = join(',',@list);
98         $rhs =~ s/^/($z): /;
99
100         &status("Update: new lhs => '$lhs' rhs => '$rhs'.");
101     }
102
103     # the fun begins.
104     my $exists = &getFactoid($lhs);
105
106     if (!$exists) {
107         # nice 'are' hack (or work-around).
108         if ($mhs =~ /^are$/i and $rhs !~ /<\S+>/) {
109             &status("Update: 'are' hack detected.");
110             $mhs = 'is';
111             $rhs = "<REPLY> are ". $rhs;
112         }
113
114         &status("enter: <$who> \'$lhs\' =$mhs=> \'$rhs\'");
115         $count{'Update'}++;
116
117         &performAddressedReply('okay');
118
119         &sqlInsert('factoids', {
120                 created_by      => $nuh,
121                 created_time    => time(),      # modified time.
122                 factoid_key     => $lhs,
123                 factoid_value   => $rhs,
124         } );
125
126         if (!defined $rhs or $rhs eq '') {
127             &ERROR("Update: rhs1 == NULL.");
128         }
129
130         return 1;
131     }
132
133     # factoid exists.
134     if ($exists eq $rhs) {
135         # this catches the following situation: (right or wrong?)
136         #    "test is test"
137         #    "test is also test"
138         &performAddressedReply("i already had it that way");
139         return 1;
140     }
141
142     if ($also) {                        # 'is also'.
143         my $redircount = 5;
144         my $origlhs = $lhs;
145         while ($exists =~ /^<REPLY> ?see (.*)/i) {
146             $redircount--;
147             unless ($redircount) {
148                 &msg($who, "$origlhs has too many levels of redirection.");
149                 return 1;
150             }
151
152             $lhs = $1;
153             $exists = &getFactoid($lhs);
154             unless( $exists ) {
155                 &msg($who, "$1 is a dangling redirection.");
156                 return 1;
157             }
158         }
159         if ($exists =~ /^<REPLY> ?see (.*)/i) {
160             &TODO("Update.pl: append to linked factoid.");
161         }
162
163         if ($also_or) {                 # 'is also ||'.
164             $rhs = $exists.' || '.$rhs;
165         } else {
166 #           if ($exists =~ s/\,\s*$/,  /) {
167             if ($exists =~ /\,\s*$/) {
168                 &DEBUG("current has trailing comma, just append as is");
169                 &DEBUG("Up: exists => $exists");
170                 &DEBUG("Up: rhs    => $rhs");
171                 # $rhs =~ s/^\s+//;
172                 # $rhs = $exists." ".$rhs;      # keep comma.
173             }
174
175             if ($exists =~ /\.\s*$/) {
176                 &DEBUG("current has trailing period, just append as is with 2 WS");
177                 &DEBUG("Up: exists => $exists");
178                 &DEBUG("Up: rhs    => $rhs");
179                 # $rhs =~ s/^\s+//;
180                 # use ucfirst();?
181                 # $rhs = $exists."  ".$rhs;     # keep comma.
182             }
183
184             if ($rhs =~ /^[A-Z]/) {
185                 if ($rhs =~ /\w+\s*$/) {
186                     &status("auto insert period to factoid.");
187                     $rhs = $exists.".  ".$rhs;
188                 } else {        # '?' or '.' assumed at end.
189                     &status("orig factoid already had trailing symbol; not adding period.");
190                     $rhs = $exists."  ".$rhs;
191                 }
192             } elsif ($exists =~ /[\,\.\-]\s*$/) {
193                 &VERB("U: current has trailing symbols; inserting whitespace + new.",2);
194                 $rhs = $exists." ".$rhs;
195             } elsif ($rhs =~ /^\./) {
196                 &VERB("U: new text has ^.; appending directly",2);
197                 $rhs = $exists.$rhs;
198             } else {
199                 $rhs = $exists.', or '.$rhs;
200             }
201         }
202
203         # max length check again.
204         if (length $rhs > $param{'maxDataSize'}) {
205             if (length $rhs > length $exists) {
206                 &performAddressedReply("that's too long");
207                 return 1;
208             } else {
209                 &status("Update: new length is still longer than maxDataSize but less than before, we'll let it go.");
210             }
211         }
212
213         &performAddressedReply('okay');
214
215         $count{'Update'}++;
216         &status("update: <$who> \'$lhs\' =$mhs=> \'$rhs\'; was \'$exists\'");
217         &sqlSet('factoids', {'factoid_key' => $lhs}, {
218                 modified_by     => $nuh,
219                 modified_time   => time(),
220                 factoid_value   => $rhs,
221         } );
222
223         if (!defined $rhs or $rhs eq '') {
224             &ERROR("Update: rhs1 == NULL.");
225         }
226     } else {                            # not 'also'
227
228         if (!$correction_plausible) {   # "no, blah is ..."
229             if ($addressed) {
230                 &performStrictReply("...but \002$lhs\002 is already something else...");
231                 &status("FAILED update: <$who> \'$lhs\' =$mhs=> \'$rhs\'");
232             }
233             return 1;
234         }
235
236         my $author = &getFactInfo($lhs, 'created_by') || '';
237
238         if (IsFlag('m') ne 'm' && IsFlag('o') ne 'o' &&
239             $author !~ /^\Q$who\E\!/i
240         ) {
241             &msg($who, "you can't change that factoid.");
242             return 1;
243         }
244
245         &performAddressedReply('okay');
246
247         $count{'Update'}++;
248         &status("update: <$who> \'$lhs\' =$mhs=> \'$rhs\'; was \'$exists\'");
249
250         &sqlSet('factoids', {'factoid_key' => $lhs}, {
251                 modified_by     => $nuh,
252                 modified_time   => time(),
253                 factoid_value   => $rhs,
254         } );
255
256         if (!defined $rhs or $rhs eq '') {
257             &ERROR("Update: rhs1 == NULL.");
258         }
259     }
260
261     return 1;
262 }
263
264 1;
265
266 # vim:ts=4:sw=4:expandtab:tw=80