root/QuoteEngine/QuoteEngine.tcl @ 42

Revision 42, 18.0 KB (checked in by notopic, 19 months ago)

missed a shrinkspaces point

Line 
1# $Id: QuoteEngine.tcl,v 1.20 2004/03/30 21:52:12 James Exp $
2
3###############################################################################
4# QuoteEngine for eggdrop bots
5# Copyright (C) James Michael Seward 2003
6#
7# This program is covered by the GPL, please refer the to LICENCE file in the
8# distribution.
9###############################################################################
10
11# load the extension
12# CHANGE ME: My main bot's server has broken TCL, so I need the line below:
13#load /usr/local/lib/mysqltcl-2.12/libmysqltcl2.12.so
14#load /home/notopic/lib/mysqltcl-2.50/libmysqltcl2.50.so
15# BUT most people should get away with this if their server's setup right:
16package require mysqltcl
17
18# Use only one or other of the above!
19
20# connect to database
21# CHANGE ME
22proc quote_connect { } {
23        global db_handle
24               
25        set db_handle [mysqlconnect -host localhost -user notopic -password moo -db quotes]
26
27        if {$db_handle != ""} {
28                return 1
29        } else {
30                return 0
31        }
32}
33
34# url to site
35# CHANGE ME (use blank if you're not using the PHP script)
36set php_page "http://sakaki.jamesoff.net/~notopic/"
37
38# automatically spew "relevant" quotes?
39set quote_automatic 1
40
41# minimum number of seconds between automatic quotes
42set quote_automatic_minimum [expr 3 * 3600]
43
44# bind commands CHANGE as needed
45# use ".chanset #channel [+/-]quoteengine" to enable/disable individual
46# channels
47bind pub "m|fov" !addquote quote_add
48bind pub "m|fov" !randquote quote_rand
49bind pub "m|fov" !fetchquote quote_fetch
50bind pub "m|fov" !getquote quote_fetch
51bind pub "m|fov" !findquote quote_search
52bind pub "m|fov" !searchquote quote_search
53bind pub "m|fov" !urlquote quote_url
54bind pub "-|-" !quoteurl quote_url
55bind pub "m|ov" !delquote quote_delete
56bind pub "m|ov" !deletequote quote_delete
57bind pub "m|ov" !quotestats quote_stats
58bind pub "-|-" !quoteversion quote_version
59bind pub "-|-" !quotehelp quote_help
60bind pubm "-|ov" * quote_auto
61
62# a user with this flag(s) can't use the script at all
63set quote_noflags "Q|Q"
64
65# maximum number of quotes to show in channel when searching before switching
66# to /msg'ing the user
67set quote_chanmax 5
68
69# shrink multiple spaces to single spaces when fetching a quote?
70set quote_shrinkspaces 1
71
72### code starts here (no need to edit stuff below currently)
73#1.00
74set quote_version "cvs"
75set quote_auto_last(blah) 0
76
77#add setting to channel
78setudef flag quoteengine
79
80### procedures start here
81
82################################################################################
83# quote_ping
84# Check we're still connected to mysql
85################################################################################
86proc quote_ping { } {
87        global db_handle
88
89        if [::mysql::ping $db_handle] {
90                return 1
91        } else {
92                return [quote_connect]
93        }
94}
95
96################################################################################
97# quote_add
98# !addquote <text>
99#   Adds a quote to the database
100################################################################################
101proc quote_add { nick host handle channel text } {
102  global db_handle quote_noflags
103
104  if {![channel get $channel quoteengine]} {
105    return 0
106  }
107
108  if [matchattr $handle $quote_noflags] { return 0 }
109
110  if {($handle == "") || ($handle == "*")} {
111    set handle $nick
112  }
113
114        if {![quote_ping]} {
115                putquick "PRIVMSG $channel :Sorry, lost database connection :("
116                return 0
117        }
118
119  set sql "INSERT INTO quotes VALUES(null, "
120  append sql "'$handle', "
121  append sql "'$nick!$host', "
122  set text [mysqlescape $text]
123  append sql "'$text', "
124  append sql "'$channel', "
125  append sql "'[clock seconds]')"
126
127  putloglev d * "QuoteEngine: executing $sql"
128
129  set result [mysqlexec $db_handle $sql]
130  if {$result != 1} {
131    putlog "An error occurred with the sql :("
132  } else {
133    set id [mysqlinsertid $db_handle]
134    puthelp "PRIVMSG $channel :Quote \002$id\002 added"
135                if [regexp {[^]> ]\|[[<0-9(]} $text] {
136                        puthelp "PRIVMSG $nick :It's possible you didn't split the lines quite right on the quote you just added. For best results, split lines in quotes using '|' with a space each side. To delete the quote you just added and fix it, do '!delquote $id' in the channel."
137                }
138  }
139}
140
141
142################################################################################
143# quote_rand
144# !randquote [--all|--channel #channel]
145#   Gets a random quote from the database for the current channel
146#     --all: Choose from entire database
147#     --channel: Choose from given channel
148#     -c: Shortcut for --channel
149################################################################################
150proc quote_rand { nick host handle channel text } {
151  global db_handle quote_noflags quote_shrinkspaces
152
153  if {![channel get $channel quoteengine]} {
154    return 0
155  }
156
157  if [matchattr $handle $quote_noflags] { return 0 }
158
159        if {![quote_ping]} {
160                putquick "PRIVMSG $channel :Sorry, lost database connection :("
161                return 0
162        }
163
164  set where_clause "WHERE channel='$channel'"
165  if [regexp -- "--?all" $text] {
166    set where_clause ""
167  }
168
169  if [regexp -- "--?c(hannel)?( |=)(.+)" $text matches skip1 skip2 newchan] {
170    set where_clause "WHERE channel='[mysqlescape $newchan]'"
171  }
172
173  set sql "SELECT * FROM quotes $where_clause ORDER BY RAND() LIMIT 1"
174  putloglev d * "QuoteEngine: executing $sql"
175
176  set result [mysqlquery $db_handle $sql]
177
178  if {[set row [mysqlnext $result]] != ""} {
179    set id [lindex $row 0]
180    set quote [lindex $row 3]
181    set by [lindex $row 1]
182    set when [clock format [lindex $row 5] -format "%Y/%m/%d %H:%M"]
183                catch {
184                        if {$quote_shrinkspaces == 1} {
185                                regsub -all "  +" $quote " " quote
186                        }
187                        set quote [stripcodes bcruag $quote]
188                }
189
190    puthelp "PRIVMSG $channel :\[\002$id\002\] $quote"
191  } else {
192    puthelp "PRIVMSG $channel :Couldn't find a quote :("
193  }
194  mysqlendquery $result
195}
196
197
198################################################################################
199# quote_fetch
200# !getquote <id>
201#   Fetches the given quote from the database
202################################################################################
203proc quote_fetch { nick host handle channel text } {
204  global db_handle quote_noflags quote_shrinkspaces
205
206  if {![channel get $channel quoteengine]} {
207    return 0
208  }
209
210  if [matchattr $handle $quote_noflags] { return 0 }
211
212        set verbose ""
213
214  if {![regexp {(-v )?([0-9]+)} $text matches verbose quote_id]} {
215    puthelp "PRIVMSG $channel: Use: !getquote \[-v\] <id>"
216    return 0
217  }
218
219        if {![quote_ping]} {
220                putquick "PRIVMSG $channel :Sorry, lost database connection :("
221                return 0
222        }
223
224       
225        set text [mysqlescape $quote_id]
226  set sql "SELECT * FROM quotes WHERE id='$text'"
227  putloglev d * "QuoteEngine: executing $sql"
228
229  set result [mysqlquery $db_handle $sql]
230
231  if {[set row [mysqlnext $result]] != ""} {
232    set id [lindex $row 0]
233                set quote [lindex $row 3]
234                catch {
235                        if {$quote_shrinkspaces == 1} {
236                                regsub -all "  +" $quote " " quote
237                        }
238                        set quote [stripcodes bcruag $quote]
239                }
240    set by [lindex $row 1]
241    set when [clock format [lindex $row 5] -format "%Y/%m/%d %H:%M"]
242    set chan [lindex $row 4]
243    if {$chan != $channel} {
244      puthelp "PRIVMSG $channel :\[\002$id\002\] $quote"
245      if {$verbose != ""} {
246                                puthelp "PRIVMSG $channel :\[\002$id\002\] From $chan, by added $by at $when."
247                        }
248    } else {
249      puthelp "PRIVMSG $channel :\[\002$id\002\] $quote"
250                        if {$verbose != ""} {
251                                puthelp "PRIVMSG $channel :\[\002$id\002\] Added by $by at $when."
252                        }
253    }
254  } else {
255    puthelp "PRIVMSG $channel :Couldn't find quote $text"
256  }
257
258  mysqlendquery $result
259}
260
261
262################################################################################
263# quote_search
264# !findquote [--all] [--channel #channel] [--count <int>] <text>
265#   Find all quotes with "text" in them. (in random order)
266#   The first 5 (by default) are listed in the channel. The rest are /msg'd to
267#   you up to the maximum (default 5).
268#     --all: Search all channels, not just current one
269#     --channel: Search given channel
270#     --count <int>: Find this many total quotes
271#     -c: Shortcut for --channel
272#     -n: Shortcut for --count
273#   Note this is a SQL search, so use % as the wildcard (instead of *)
274#   The script automatically puts %s around your text when searching.
275################################################################################
276proc quote_search { nick host handle channel text } {
277  global db_handle php_page quote_noflags quote_chanmax
278
279  if {![channel get $channel quoteengine]} {
280    return 0
281  }
282
283  if [matchattr $handle $quote_noflags] { return 0 }
284
285  if {$text == ""} {
286    puthelp "PRIVMSG $channel :Use: !findquote <text>"
287    return 0
288  }
289
290        if {![quote_ping]} {
291                putquick "PRIVMSG $channel :Sorry, lost database connection :("
292                return 0
293        }
294
295  set where_clause "AND channel='[mysqlescape $channel]'"
296  if [regexp -- "--?all " $text matches skip1] {
297    set where_clause ""
298    regsub -- $matches $text "" text
299  }
300
301  if [regexp -- {--?c(hannel)?( |=)([^ ]+)} $text matches skip1 skip2 newchan] {
302    set where_clause "AND channel='[mysqlescape $newchan]'"
303    regsub -- $matches $text "" text
304  }
305
306  set limit 5
307  if [regexp -- {--?count( |=)([^ ]+)} $text matches skip1 count] {
308    set limit [mysqlescape $count]
309    regsub -- $matches $text "" text
310  }
311
312  if [regexp -- {-n( )?([^ ]+)} $text matches skip1 count] {
313    set limit [mysqlescape $count]
314    regsub -- $matches $text "" text
315  }
316
317  set sql "SELECT * FROM quotes WHERE quote LIKE '%[mysqlescape $text]%' $where_clause ORDER BY RAND()"
318
319  putloglev d * "QuoteEngine: executing $sql"
320
321  if {[mysqlsel $db_handle $sql] > 0} {
322
323    set count 0
324    mysqlmap $db_handle {id qnick qhost quote qchannel qts} {
325      if {$count == $limit} {
326        break
327      }
328
329      if {$count == $quote_chanmax} {
330        puthelp "PRIVMSG $nick :Rest of matches for your search '$text' follow in private:"
331      }
332
333      if {$count < $quote_chanmax} {
334        puthelp "PRIVMSG $channel :\[\002$id\002\] $quote"
335      } else {
336        puthelp "PRIVMSG $nick :\[\002$id\002\] $quote"
337      }
338      incr count
339    }
340
341    set remaining [mysqlresult $db_handle rows?]
342    if {$remaining > 0} {
343                        if {$count < $quote_chanmax} {
344                                set command "PRIVMSG $channel :"
345                        } else {
346                                set command "PRIVMSG $nick :"
347                        }
348
349      regsub "#" $channel "" chan
350      if {$php_page != ""} {
351        puthelp "${command}(Plus $remaining more matches: $php_page?filter=${text}&channel=${chan}&search=search)"
352      } else {
353        puthelp "${command}Plus $remaining other matches"
354      }
355    } else {
356      if {$count == 1} {
357        puthelp "${command}(All of 1 match)"
358      } else {
359        puthelp "${command}(All of $count matches)"
360      }
361    }
362  } else {
363    puthelp "PRIVMSG $channel :No matches"
364  }
365}
366
367
368################################################################################
369# quote_url
370# !quoteurl
371#   Gives the web of the web interface
372################################################################################
373proc quote_url { nick host handle channel text } {
374  global php_page quote_noflags
375
376  if {![channel get $channel quoteengine]} {
377    return 0
378  }
379
380  if [matchattr $handle $quote_noflags] { return 0 }
381
382  if {$php_page != ""} {
383# changed for better url by dubkat
384  puthelp "PRIVMSG $channel :${php_page}?channel=[string range $channel 1 end]"
385  } else {
386    puthelp "PRIVMSG $channel :Not available."
387  }
388}
389
390
391################################################################################
392# quote_stats
393# !quotestats
394#   Give some simple statistics about the db, channel, and user
395################################################################################
396proc quote_stats { nick host handle channel text } {
397  global db_handle quote_noflags
398
399  if {![channel get $channel quoteengine]} {
400    return 0
401  }
402
403  if [matchattr $handle $quote_noflags] { return 0 }
404
405        if {![quote_ping]} {
406                putquick "PRIVMSG $channel :Sorry, lost database connection :("
407                return 0
408        }
409
410  set sql "SELECT COUNT(*) AS total FROM quotes WHERE channel='$channel'"
411  putloglev d * "QuoteEngine: executing $sql"
412
413  set result [mysqlquery $db_handle $sql]
414  set total 0
415  set chan 0
416
417  if {[set row [mysqlnext $result]] != ""} {
418    set total [lindex $row 0]
419  }
420
421  mysqlendquery $result
422
423  set sql "SELECT COUNT(*) AS total FROM quotes"
424  putloglev d * "QuoteEngine: executing $sql"
425
426  set result [mysqlquery $db_handle $sql]
427
428  if {[set row [mysqlnext $result]] != ""} {
429    set chan [lindex $row 0]
430  }
431
432  mysqlendquery $result
433
434  set sql "SELECT COUNT(*) AS total FROM quotes WHERE nick='$handle' AND channel='$channel'"
435  putloglev d * "QuoteEngine: executing $sql"
436
437  set result [mysqlquery $db_handle $sql]
438
439  if {[set row [mysqlnext $result]] != ""} {
440    set by_handle [lindex $row 0]
441  }
442
443  mysqlendquery $result
444
445  puthelp "PRIVMSG $channel :Quotes for $channel: \002$total\002 (total: $chan). You have added \002$by_handle\002 quotes in this channel."
446}
447
448
449################################################################################
450# quote_delete
451# !delquote <id>
452#   Removes a quote from the database. You can only delete the quote if you
453#   are a bot/channel master, or if you're the person who added it.
454################################################################################
455proc quote_delete  { nick host handle channel text } {
456  global db_handle quote_noflags
457
458  if {![channel get $channel quoteengine]} {
459    return 0
460  }
461
462  if [matchattr $handle $quote_noflags] { return 0 }
463
464        if {![quote_ping]} {
465                putquick "PRIVMSG $channel :Sorry, lost database connection :("
466                return 0
467        }
468
469  set text [mysqlescape $text]
470  if {![matchattr $handle m|m $channel]} {
471    set sql "SELECT nick FROM quotes WHERE id='$text'"
472    putloglev d * "QuoteEngine: executing $sql"
473
474    set result [mysqlquery $db_handle $sql]
475    set owner [lindex [mysqlnext $result] 0]
476    mysqlendquery $result
477    if {$owner != $handle} {
478      puthelp "NOTICE $nick :You cannot delete that quote."
479      return 0
480    }
481  }
482
483  set sql "DELETE FROM quotes WHERE id='$text'"
484  putloglev d * "QuoteEngine: executing $sql"
485
486  set result [mysqlexec $db_handle $sql]
487  if {$result != 1} {
488    puthelp "PRIVMSG $channel :An error occurred deleting the quote :("
489    return 0
490  } else {
491    puthelp "PRIVMSG $channel :Deleted quote $text"
492  }
493}
494
495
496################################################################################
497# quote_version
498# !quoteversion
499#   Gives the version of the script
500################################################################################
501proc quote_version { nick host handle channel text } {
502  global quote_version quote_noflags
503
504  if [matchattr $handle $quote_noflags] { return 0 }
505
506  puthelp "PRIVMSG $channel :This is the QuoteEngine version $quote_version by JamesOff (http://www.jamesoff.net/go/quoteengine)"
507  return 0
508}
509
510
511################################################################################
512# quote_help
513# !quotehelp
514#   Handle help requests
515################################################################################
516 proc quote_help { nick host handle channel text } {
517  global quote_noflags
518
519  if [matchattr $handle $quote_noflags] { return 0 }
520
521  puthelp "PRIVMSG $nick :Commands for the QuoteEngine script:"
522  puthelp "PRIVMSG $nick :  !addquote <quote text> - adds a quote to the database"
523  puthelp "PRIVMSG $nick :  !delquote <id> - deletes a quote. You must be either a bot/channel master or the person who added the quote to delete it."
524  puthelp "PRIVMSG $nick :  !randquote \[--all\] \[--channel=#channel\] \[-c #channel\] - fetches a random quote from the current channel. --all chooses from all channels, not just the one the command is executed from. --channel and -c choose only from the given channel."
525  puthelp "PRIVMSG $nick :  !getquote \[-v\]<id> - fetches the quote with number <id>. Gives info of who added it if -v is specified."
526  puthelp "PRIVMSG $nick :  !findquote \[--all\] \[--channel=#channel\] \[-c #channel\] \[--count <int>\] \[-n <int>\] <text> - finds up to <int> (default 5) quotes containing 'text'. Optional parameters same as !randquote. -n is a shortcut for --count."
527  puthelp "PRIVMSG $nick :  !quoteurl - get the URL for the web interface to the quotes"
528  puthelp "PRIVMSG $nick :  !quotestats - get some information"
529  puthelp "PRIVMSG $nick :  !quoteversion - get the version of the script"
530  puthelp "PRIVMSG $nick :  Some commands have synonyms: !deletequote, !fetchquote, !urlquote, and !searchquote."
531  puthelp "PRIVMSG $nick :  (End of help)"
532  return 0
533}
534
535proc quote_auto { nick host handle channel text } {
536        global quote_automatic quote_shrinkspaces
537        if {$quote_automatic == 0} {
538                return
539        }
540
541  if {![channel get $channel quoteengine]} {
542                return
543        }
544
545        global quote_auto_last db_handle quote_automatic_minimum
546
547        if [info exists quote_auto_last($channel)] {
548                set diff [expr [clock seconds] - $quote_auto_last($channel)]
549                putloglev 1 * "diff for $channel is $diff"
550        } else {
551                set diff [expr $quote_automatic_minimum + 1]
552                putloglev d * "initialising diff for $channel"
553                set quote_auto_last($channel) 0
554        }
555
556        if {$diff < $quote_automatic_minimum} {
557                return
558        }
559
560        set words [split $text]
561        set newwords [list]
562
563        foreach word $words {
564                if [regexp -nocase {^[a-z0-9']{4,}$} $word] {
565                        if {[lsearch [list "yeah" "about" "hello" "their" "there" "that's" "can't" "morning" "won't"] $word] > -1} {
566                                continue
567                        }
568
569                        if [onchan $word] {
570                                continue
571                        }
572
573                        lappend newwords [mysqlescape $word]
574                }
575        }
576
577        if {[llength $newwords] == 0} {
578                return
579        }
580
581        putloglev d * "quoteengine: candidate words for random quote in $channel: $newwords"
582
583        if {![quote_ping]} {
584                return
585        }
586
587        set thisword [pickRandom $newwords]
588        putloglev d * "quoteengine: using $thisword"
589
590        if {[rand 100] < 95} {
591                putloglev d * "quoteengine: not random enough, ignoring"
592                return
593        }
594
595       
596        set where_clause "WHERE channel='[mysqlescape $channel]' AND quote LIKE '%$thisword%' ORDER BY RAND() LIMIT 1"
597        putloglev d * "quoteengine: $where_clause"
598        set sql "SELECT * FROM quotes $where_clause"
599
600        set result [mysqlquery $db_handle $sql]
601        if {[set row [mysqlnext $result]] != ""} {
602                set id [lindex $row 0]
603                set quote [lindex $row 3]
604
605                catch {
606                        if {$quote_shrinkspaces == 1} {
607                                regsub -all "  +" $quote " " quote
608                        }
609                        set quote [stripcodes bcruag $quote]
610                }
611
612                putlog "RANDOM QUOTE: $quote ($id)"
613                puthelp "PRIVMSG $channel :\[\002$id\002\] $quote"
614                set quote_auto_last($channel) [clock seconds]
615        }
616        mysqlendquery $result
617
618}
619
620
621quote_connect
622putlog "QuoteEngine $quote_version loaded"
Note: See TracBrowser for help on using the browser.