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