]> git.donarmstrong.com Git - infobot.git/blob - src/Factoids/Update.pl
reduce sql, fix CMD: DOS
[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     # freshmeat
56     if (&IsChanConf("freshmeatForFactoid")) {
57         # todo: "name" is invalid for fm ][
58         if ( &sqlSelect("freshmeat", "name", { name => $lhs } ) ) {
59             &msg($who, "permission denied. (freshmeat)");
60             &status("alert: $who wanted to teach me something that freshmeat already has info on.");
61             return 1;
62         }
63     }
64
65     # factoid arguments handler.
66     # must start with a non-variable
67     if (&IsChanConf("factoidArguments") and $lhs =~ /^[^\$]+.*\$/) {
68         &status("Update: Factoid Arguments found.");
69         &status("Update: orig lhs => '$lhs'.");
70         &status("Update: orig rhs => '$rhs'.");
71
72         my @list;
73         my $count = 0;
74         $lhs =~ s/^/CMD: /;
75         while ($lhs =~ s/\$(\S+)/(.*?)/) {
76             push(@list, "\$$1");
77             $count++;
78             last if ($count >= 10);
79         }
80
81         if ($count >= 10) {
82             &msg($who, "error: could not SAR properly.");
83             &DEBUG("error: lhs => '$lhs' rhs => '$rhs'.");
84             return;
85         }
86
87         my $z = join(',',@list);
88         $rhs =~ s/^/($z): /;
89
90         &status("Update: new lhs => '$lhs' rhs => '$rhs'.");
91     }
92
93     # the fun begins.
94     my $exists = &getFactoid($lhs);
95
96     if (!$exists) {
97         # nice 'are' hack (or work-around).
98         if ($mhs =~ /^are$/i and $rhs !~ /<\S+>/) {
99             &status("Update: 'are' hack detected.");
100             $mhs = "is";
101             $rhs = "<REPLY> are ". $rhs;
102         }
103
104         &status("enter: <$who> \'$lhs\' =$mhs=> \'$rhs\'");
105         $count{'Update'}++;
106
107         &performAddressedReply("okay");
108
109         &sqlReplace("factoids", {
110                 created_by      => $nuh,
111                 created_time    => time(),      # modified time.
112                 factoid_key     => $lhs,
113                 factoid_value   => $rhs,
114         } );
115
116         if (!defined $rhs or $rhs eq "") {
117             &ERROR("Update: rhs1 == NULL.");
118         }
119
120         return 1;
121     }
122
123     # factoid exists.
124     if ($exists eq $rhs) {
125         # this catches the following situation: (right or wrong?)
126         #    "test is test"
127         #    "test is also test"
128         &performAddressedReply("i already had it that way");
129         return 1;
130     }
131
132     if ($also) {                        # 'is also'.
133         if ($exists =~ /^<REPLY> see /i) {
134             &DEBUG("Update.pl: todo: append to linked factoid.");
135         }
136
137         if ($also_or) {                 # 'is also ||'.
138             $rhs = $exists.' || '.$rhs;
139         } else {
140 #           if ($exists =~ s/\,\s*$/,  /) {
141             if ($exists =~ /\,\s*$/) {
142                 &DEBUG("current has trailing comma, just append as is");
143                 &DEBUG("Up: exists => $exists");
144                 &DEBUG("Up: rhs    => $rhs");
145                 # $rhs =~ s/^\s+//;
146                 # $rhs = $exists." ".$rhs;      # keep comma.
147             }
148
149             if ($exists =~ /\.\s*$/) {
150                 &DEBUG("current has trailing period, just append as is with 2 WS");
151                 &DEBUG("Up: exists => $exists");
152                 &DEBUG("Up: rhs    => $rhs");
153                 # $rhs =~ s/^\s+//;
154                 # use ucfirst();?
155                 # $rhs = $exists."  ".$rhs;     # keep comma.
156             }
157
158             if ($rhs =~ /^[A-Z]/) {
159                 if ($rhs =~ /\w+\s*$/) {
160                     &status("auto insert period to factoid.");
161                     $rhs = $exists.".  ".$rhs;
162                 } else {        # '?' or '.' assumed at end.
163                     &status("orig factoid already had trailing symbol; not adding period.");
164                     $rhs = $exists."  ".$rhs;
165                 }
166             } elsif ($exists =~ /[\,\.\-]\s*$/) {
167                 &VERB("U: current has trailing symbols; inserting whitespace + new.",2);
168                 $rhs = $exists." ".$rhs;
169             } elsif ($rhs =~ /^\./) {
170                 &VERB("U: new text has ^.; appending directly",2);
171                 $rhs = $exists.$rhs;
172             } else {
173                 $rhs = $exists.', or '.$rhs;
174             }
175         }
176
177         # max length check again.
178         if (length $rhs > $param{'maxDataSize'}) {
179             if (length $rhs > length $exists) {
180                 &performAddressedReply("that's too long");
181                 return 1;
182             } else {
183                 &status("Update: new length is still longer than maxDataSize but less than before, we'll let it go.");
184             }
185         }
186
187         &performAddressedReply("okay");
188
189         $count{'Update'}++;
190         &status("update: <$who> \'$lhs\' =$mhs=> \'$rhs\'; was \'$exists\'");
191         &sqlReplace("factoids", {
192                 factoid_key     => $lhs,
193                 modified_by     => $nuh,
194                 modified_time   => time(),
195                 factoid_value   => $rhs,
196         } );
197
198         if (!defined $rhs or $rhs eq "") {
199             &ERROR("Update: rhs1 == NULL.");
200         }
201     } else {                            # not "also"
202
203         if (!$correction_plausible) {   # "no, blah is ..."
204             if ($addressed) {
205                 &performStrictReply("...but \002$lhs\002 is already something else...");
206                 &status("FAILED update: <$who> \'$lhs\' =$mhs=> \'$rhs\'");
207             }
208             return 1;
209         }
210
211         my $author = &getFactInfo($lhs, "created_by") || "";
212
213         if (IsFlag("m") ne "m" && IsFlag("o") ne "o" &&
214             $author !~ /^\Q$who\E\!/i
215         ) {
216             &msg($who, "you can't change that factoid.");
217             return 1;
218         }
219
220         &performAddressedReply("okay");
221
222         $count{'Update'}++;
223         &status("update: <$who> \'$lhs\' =$mhs=> \'$rhs\'; was \'$exists\'");
224
225         &sqlReplace("factoids", {
226                 factoid_key     => $lhs,
227                 modified_by     => $nuh,
228                 modified_time   => time(),
229                 factoid_value   => $rhs,
230         } );
231
232         if (!defined $rhs or $rhs eq "") {
233             &ERROR("Update: rhs1 == NULL.");
234         }
235     }
236
237     return 1;
238 }
239
240 1;