Add, search and randomly display quotes

# quotecollector.tcl
#
# Copyright (c) 2003 Jochen "Y0Gi" Kupperschmidt <http://homework.nwsnet.de/>
# Version: 28-Sep-2003
# Released under the terms of the MIT License.
#
# Add, search and randomly display quotes.
#
# Commands provided:
#   !quotehelp             - explain available commands
#   !addquote <quote>      - adds quote to database
#   !quote                 - return random quote from database
#   !quote <pattern>       - return random quote from list of matches
#   !quotecount            - return number of quotes in database
#   !quotecount <pattern>  - return number of matching quotes

# configuration
set qcol(datafile) "quotecollector.dat"

# triggers
bind pub - !quotehelp qcol:pub:quotehelp
bind pub - !addquote qcol:pub:addquote
bind pub - !quote qcol:pub:getquote
bind pub - !quotecount qcol:pub:getquotecount

# Print command list.
proc qcol:pub:quotehelp {nick host hand chan text} {
    puthelp "NOTICE $nick :!addquote <quote>      - adds quote to database"
    puthelp "NOTICE $nick :!quote                 - return random quote from database"
    puthelp "NOTICE $nick :!quote <pattern>       - return random quote from list of matches"
    puthelp "NOTICE $nick :!quotecount            - return number of quotes in database"
    puthelp "NOTICE $nick :!quotecount <pattern>  - return number of matching quotes"
    puthelp "NOTICE $nick :                         <pattern> accepts wildcards * and ?"
    return 0
}

# Append quote to file.
proc qcol:pub:addquote {nick host hand chan text} {
    global qcol

    set fh [open $qcol(datafile) a+]
    puts $fh $text
    close $fh
    puthelp "PRIVMSG $chan :Quote added."
    return 0
}

# Fetch random quote from file.
proc qcol:pub:getquote {nick host hand chan text} {
    global qcol

    # Assure file exists.
    if {![file exists $qcol(datafile)]} {
        puthelp "PRIVMSG $chan :Error: Quotes file not found! Creating it."
        catch {exec touch $qcol(datafile)}
        return 0
    }

    # Fetch and check quotes array.
    set quotes [qcol:getquoteslist $qcol(datafile)]
    if {[llength $quotes] == 0} {
        puthelp "PRIVMSG $chan :Error: No quotes found! Add some first."
        return 0
    }

    # If no search string is specified, return a random quote.
    if {[lindex $text 0] == ""} {
        set randomquote [lindex $quotes [rand [llength $quotes]]]
        puthelp "PRIVMSG $chan :$randomquote"
        return 0
    }

    # Return first quote that matches pattern.
    set matches [list]
    foreach quote $quotes {
        if {[string match -nocase $text $quote]} {
            lappend matches $quote
        }
    }
    if {[llength $matches] > 0} {
        set randomquote [lindex $matches [rand [llength $matches]]]
        puthelp "PRIVMSG $chan :$randomquote"
    }
    puthelp "PRIVMSG $chan :[llength $matches] matching quotes found overall."
    return 0
}

# Count occurences of given word.
proc qcol:pub:getquotecount {nick host hand chan text} {
    global qcol

    # Assure file exists.
    if {![file exists $qcol(datafile)]} {
        puthelp "PRIVMSG $chan :Error: Quotes file not found! Creating it."
        catch {exec touch $qcol(datafile)}
        return 0
    }

    # Fetch and check quotes array.
    set quotes [qcol:getquoteslist $qcol(datafile)]
    if {[llength $quotes] == 0} {
        puthelp "PRIVMSG $chan :Error: No quotes found! Add some first."
        return 0
    }

    # If no search string is specified, return number of quotes in database.
    if {[lindex $text 0] == ""} {
        puthelp "PRIVMSG $chan :[llength $quotes] quotes in database."
        return 0
    }

    # Count lines matching given search string.
    set matchcount 0
    foreach quote $quotes {
        if {[string match -nocase $text $quote]} {
            incr matchcount
        }
    }
    puthelp "PRIVMSG $chan :$matchcount matching quotes found."
    return 0
}

proc qcol:getquoteslist {file} {
    # Read file into and return list.
    set quotes [list]
    set fh [open $file r]
    while {![eof $fh]} {
        gets $fh quote
        if {$quote != ""} {
            lappend quotes $quote
        }
    }
    close $fh
    return $quotes
}

putlog "quotecollector.tcl loaded."