Statswww
Statswww
- Code:
### NOTES: -This script uses flag 5 (F) so it WILL interfere with ###
### other scripts using that! ###
### Please send me email and tell the url where your stats are ###
### running, but DON'T ASK HELP! You're on your own! ###
##########################################################################
#
# HISTORY
#
# V3.01
# -Little bugfixes because of version difference in some tcl-funcs
#
# V3.0
# -Finally converted for Eggdrop version 1.3.x
# -Made some little optimizations.
#
# V2.x
# -Ported by somebody else, not me. I won't give any more comments ;-)
#
# V1.6
# -Removed WHEN-command because of uselessness. Use seen if needed!
# -Changed 'Last on' to use chanrecords
# -Optimized almost everything. Now takes MUCH less CPU-time!
# -Added stylesheet usability.
# -Added comment lines before procs :-)
# -People with 0 words aren't shown on web or any other lists.
#
# V1.52
# -Fixed several non-fatal bugs and made some little "pitchings".
# -Changed the layout a little.
#
# V1.51
# -Never published, was just on own use.
#
# V1.5
# -Now works with Eggdrop version greater than 1.2.0 only.
# -Added multichannel support.
# -Fastlog feature removed because in multichannel use you should have
# so many logfiles and to reduce taking CPU-time.
# -Lynxfile (plain txt-file) feature removed also for same reason.
# -Removed flag 2 usage and changed locking to flag o (oper)
# -Changed usage of flag 1 to flag 5
# -Changed totally the stats' saveformat in userfile.
# -Added WEED-command. (Idea from Alikki)
# -Removed autodeletion of users with less of 3 pubs 'cos of WEED-cmd
# -Noticed that getlaston & setlaston with channel attribute don't work
# if the user has no flags on that channel, so included last-on-times
# in channel specific stat-records.
# -Added PLACE-command
#
# V1.4
# -If somebody parts/quits and has less than 3 comments, the bot deletes
# that user because it's very big possibility that he just came to say
# "hello" and won't ever be back. That prevents userfile getting huge.
# -Added DOSTATS dcc-command, see below
#
# V1.3
# -Fixed bug with words/pubs, no more division by zero.
# -Fixed bug with auto_adduser
# -People can now ask somebody else's stats, see below
# -Added TOPTEN command, see below
#
# V1.2
# -STAT-command tells also idletime if user is on channel.
# -Fixed some little bugs in several places
# -Added words/publics section (Suggested by Luosto)
#
# V1.1
# -Fixed bug with actions, they go to the logs now.
# -Fixed some little bugs in several places
# -Fixed bug with count_words, no more errormsg with nonexistent users
##########################################################################
## ================== DCC COMMANDS TO HANDLE THE STATS ================ ##
##########################################################################
# (only masters can use these)
# CLRUSER <handle>
# Sets somebody's all stats to 0
# SUMUSER <handle1> <handle2>
# Adds handle2's hostmask(s) and stats to handle1 and deletes handle2
# DOSTATS
# Instantly creates the new html-file(s).
# WEED <words>
# Deletes users who have less than <words> words on ALL separate
# channels except if they have master or op flag.
##########################################################################
## ============================ MSG COMMANDS ========================== ##
##########################################################################
# (everybody can use these)
# STAT
# Sends a notice to the user and tells his/her statistics
# TOPTEN <channel>
# Says top ten talkers on <channel> and their wordcounts.
# PLACE <channel>
# Tells user's place on list and wordcount on <channel>.
#
##########################################################################
## ========================== PUBLIC COMMANDS ========================= ##
##########################################################################
# (everybody can use these)
# !STAT [nick]
# Tells user's (or nick's if given) statistics on current channel.
# !TOPTEN
# Says top ten talkers and their wordcounts on current channel.
# !PLACE [nick]
# Tells user's (or nick's if given) place on list and wordcount
# on current channel.
#
# ================ SPECIAL FLAGS USED BY THIS SCRIPT: ===================
# 5 = Do not include this user to the html and !topten output.
# This uses channel specific flag, so it must be set for all channels
# (counting still works so they can use STAT-command)
# It's good idea to remove next line now when you have read the documentation :-)
##########################################################################
## ============================== SETTINGS ============================ ##
##########################################################################
## webfile with a html-table, shows 50 top talkers.
## If you don't define a webfile for all channels your bot is monitoring,
## it just doesn't make webfile for those channels, but stats work and
## pub and msg commands are usable.
## NOTICE: Use only lowercase letters in channel name here!
set wwwfile(#votre_salon) "/home/login/stat.html"
## tag for the output, if you want to use your own colors etc.
set bodytag {<body bgcolor="#FFFFFF" text="#0020a0" link="#0020a0" vlink="#0020a0" alink="#0020a0">}
## tag for using a stylesheet. set to "" if you don't want to use.
set styletag {<link rel="stylesheet" type="text/css" href="/blerp.css">}
## should userfile be saved same time as the statistics-web page updates?
## (Generally a very good idea)
set saveonupdate 1
## should bot learn new users when they start talking on a channel?
## not good idea if you don't like BIG userfile... 1=enable 0=disable
## If a user with same nick already exists, new hostmask is added to user
## (except if the user has master or oper-flag when the new user is
## added as [num]_nick where [num] if first available number.)
## auto-add removes flags ofxp for security when bot learns new user.
set autoadd 1
# Remove next line now when you have configured the settings :-)
##########################################################################
### -------------------------- CODE BEGINS HERE --------------------- ###
### If you're not familiar with TCL, do not edit anything below this! ###
##########################################################################
## Returns handlelist in decreasing order by wordcount. ----------------------
proc sortbywords {chan} {
set chan [string tolower $chan]
foreach i [userlist] {
if {![matchchanattr $i 5|5 $chan]} {
set foo [lindex [getuser $i XTRA stat.$chan] 0]
if {$foo != ""} {
set foo [format "%.20d" $foo]
if {$i != "*ban"} {lappend foolist "$foo $i"}
}
}
}
set foolist [lsort -decreasing $foolist]
foreach i $foolist {
set bar [string trimleft [lindex $i 0] 0]
if {$bar != ""} {lappend quux "$bar [lindex $i 1]"}
}
return $quux
}
## Add user with *no*flags* if (s)he wasn't known before. --------------------
## If handle is in use, N_nick is used as handle, where N is 1st free number.
proc auto_adduser {nick uhost hand chan text} {
if {[validuser $nick]} {
if {![matchchanattr $nick o|o $chan] && ![matchchanattr $nick m|m $chan]} {
setuser $nick HOSTS [maskhost $nick!$uhost]
putlog "Learned hostmask [maskhost $nick!$uhost] for $nick"
count_words $nick $uhost $nick $chan $text
return 1
}
if {[matchchanattr $nick o|o $chan] || [matchchanattr $nick m|m $chan]} {
set foo 0
while {[validuser $foo\_$nick]} {incr foo}
set nick $foo\_$nick
}
}
adduser $nick [maskhost $nick!$uhost]
foreach i [channels] {addchanrec $nick $i}
putlog "Learned user $nick [maskhost $nick!$uhost]"
chattr $nick "-omntxjpcubdkfvah"
chattr $nick "-mnodfkvqa" $chan
count_words $nick $uhost $nick $chan $text
return 1
}
## Count the words and letters and update statrecord for user. ---------------
bind pubm - * count_words
proc count_words {nick uhost hand chan text} {
global autoadd
regsub -all "\"|\{|\}" $text "x" text
set text [join $text]
set chan [string tolower $chan]
if {[validuser $hand]} {
set foo [getuser $hand XTRA stat.$chan]
if {$foo == ""} {
setuser $hand XTRA stat.$chan {0 0 0 0 0 0 0}
set foo {0 0 0 0 0 0 0}
}
set wrds [expr {[lindex $foo 0] + [llength $text]}]
set ltrs [expr {[lindex $foo 1] + [string length [join $text ""]]}]
set pubs [lindex $foo 2]
incr pubs
setuser $hand XTRA stat.$chan [lreplace $foo 0 2 $wrds $ltrs $pubs]
} elseif {$autoadd == 1} {
auto_adduser $nick $uhost $hand $chan $text
} else {return 0}
}
## Make the webfiles NOW. ----------------------------------------------------
bind dcc m dostats dcc_dostats
proc dcc_dostats {hand idx text} {
if {[string range [time] 4 4] == 9} {
putdcc $idx "Naah, wait a minute :)"
return 0
}
if {([string range [time] 4 4] == 0)} {
putdcc $idx "I JUST made them! :)"
return 0
}
do_stats min hour day month year
putdcc $idx "Updated webfiles."
return 1
}
## Remove users with less than given wordcount. ------------------------------
bind dcc m weed dcc_weed
proc dcc_weed {hand idx text} {
if {[catch {expr $text}]} {
putdcc $idx "\"$text\" WORDS? Nothing to do!"
return 0
}
set fubaz " "
foreach i [userlist] {
set bar 0
foreach j [channels] {
set foo [lindex [getuser $i XTRA stat.[string tolower $j]] 0]
if {$foo > $text} {set bar 1}
}
if {($bar == 0) && !([matchchanattr $i o|o $j]
|| [matchchanattr $i v|v $j])} {
if {($i != "*ban") && ![matchchanattr $i m|m $j]} {
deluser $i
lappend fubaz $i
}
}
}
putdcc $idx "Deleted $fubaz"
return 1
}
## Sum two users hostmasks and statistics ------------------------------------
## For use if someone has a duplicate handle created by auto_adduser.
bind dcc m sumuser dcc_sumuser
proc dcc_sumuser {hand idx text} {
set realuser [lindex [split $text { }] 0]
set fakeuser [lindex [split $text { }] 1]
if {[validuser $realuser] != 1} {putdcc $idx "No such user ($realuser)"; return 0}
if {[validuser $fakeuser] != 1} {putdcc $idx "No such user ($fakeuser)"; return 0}
foreach i [channels] {
set i [string tolower $i]
set foo [getuser $realuser XTRA stat.$i]
set bar [getuser $fakeuser XTRA stat.$i]
if {$foo == ""} {set foo {0 0 0 0 0 0 0}}
if {$bar == ""} {set bar {0 0 0 0 0 0 0}}
for {set j 0} {$j < 7} {incr j} {
set foo [lreplace $foo $j $j [expr [lindex $foo $j]+[lindex $bar $j]]]
}
if {$foo != {0 0 0 0 0 0 0}} {setuser $realuser XTRA stat.$i $foo}
}
foreach i [channels] {
set i [string tolower $i]
if {[getuser $realuser LASTON $i] < [getuser $fakeuser LASTON $i]} {
setuser $realuser LASTON [getuser $fakeuser LASTON $i] $i *
}
}
foreach i [getuser $fakeuser HOSTS] {
setuser $realuser HOSTS $i
}
putdcc $idx "$fakeuser stats and hostmask(s) added to $realuser and $fakeuser deleted."
deluser $fakeuser
}
## Clear user's statistics values to 0 on all channels -----------------------
bind dcc m clruser dcc_clruser
proc dcc_clruser {hand idx text} {
if {![validuser $text]} {putdcc $idx "$text\? No such user!"; return 0}
if {[validuser $text]} {
putdcc $idx "Set all $text's stats to 0 on all channels."
foreach i [string tolower [channels]] {
set foo [getuser $text XTRA stat.$i]
if {$foo != ""} {setuser $text XTRA stat.$i {0 0 0 0 0 0 0}}
}
}
}
## Make the webfile(s)! -------------------------------------------------------
proc do_stats {min hour day month year} {
global wwwfile saveonupdate bodytag styletag
foreach statchan [channels] {
if {[info exists wwwfile([string tolower $statchan])]} {
putserv "ping 0"
set out "<meta http-equiv=\"Refresh\" content=\"588\">"
set out "<meta http-equiv=\"Pragma\" content=\"no-cache\">"
append out "\n<html><head>\n"
append out "<title>Top talkers on channel $statchan</title>\n"
append out "$styletag"
append out "\n</head>\n"
append out "\n$bodytag\n"
append out "\n<center><h1>Top talkers on channel $statchan</h1>"
append out "\n<table border=2 cellpadding=1>"
append out "\n<caption> [strftime "%d.%m.%Y %H:%M"] </caption>"
append out "\n<th align=left>Nr</th>"
append out "\n<th align=left>Nick</th>"
append out "\n<th align=left>Last on</th>"
append out "\n<th align=left>Words</th>"
append out "\n<th align=left>Publics</th>"
append out "\n<th align=left>W/P</th>"
append out "\n<th align=left>Letters</th>"
append out "\n<th align=left>Kicks</th>"
append out "\n<th align=left>Modes</th>"
append out "\n<th align=left>Topics</th>"
append out "\n<th align=left>Actions</th>"
set statchan [string tolower $statchan]
set hands ""
set idles ""
foreach i [chanlist $statchan] {
lappend hands [nick2hand $i $statchan]
lappend idles [getchanidle $i $statchan]
}
set foolista [lrange [sortbywords $statchan] 0 49]
set no 0
foreach i $foolista {
incr no
set handle [lindex $i 1]
set stats [getuser $handle XTRA stat.$statchan]
set lastonchan [strftime "%d.%m.%Y %H:%M" [getuser $handle LASTON $statchan]]
set w_wordperpub 0
if {[lindex $stats 2] > 0} {
set w_wordperpub [format "%.1f" [expr {([lindex $stats 0]+0.0)/[lindex $stats 2]}]]
} else {set w_wordperpub 0}
if {[getuser $handle LASTON $statchan] == ""} {set lastonchan "???"}
if {[lsearch $hands $handle] != -1} {
set fooidle [lindex $idles [lsearch $hands $handle]]
if {$fooidle < 11} {
set lastonchan "NOW!"
} else {
set lastonchan "idle "
if {$fooidle > 59} {append lastonchan "[expr $fooidle / 60]h "}
append lastonchan "[expr $fooidle - ($fooidle / 60 * 60)]min"
}
}
if {[onchansplit [hand2nick $handle $statchan] $statchan]} {
set lastonchan "SPLIT"
}
append out "\n<tr>"
append out "\n<td align=left>$no</td>"
append out "\n<td align=left>$handle</td>"
append out "\n<td>$lastonchan</td>"
append out "\n<td align=right>[lindex $stats 0]</td>"
append out "\n<td align=right>[lindex $stats 2]</td>"
append out "\n<td align=right>$w_wordperpub</td>"
append out "\n<td align=right>[lindex $stats 1]</td>"
append out "\n<td align=right>[lindex $stats 3]</td>"
append out "\n<td align=right>[lindex $stats 4]</td>"
append out "\n<td align=right>[lindex $stats 5]</td>"
append out "\n<td align=right>[lindex $stats 6]</td>"
}
append out "\n</table></center><br>"
append out "\n<center>This page updates every 10 minutes.</center><br>"
append out "\n<center><address>"
append out "<a href=\"http://www.goblet.net/scripts/\">StatWWW 3.01</a>"
append out "<a href=\"http://www.goblet.net/~goblet/\">"
append out "\nGoblet </a> 1997-1999</address></center>"
append out "\n</body></html>"
set fd [open "$wwwfile([string tolower $statchan])" w]
puts $fd $out
close $fd
unset out
}
}
if {$saveonupdate == 1} {save}
}
## Tell place on list on channel ---------------------------------------------
bind pub - !place pub_place
proc pub_place {nick uhost hand chan text} {
if {$text != ""} {set hand $text}
if {[matchchanattr $hand 5|5 $chan]} {
puthelp "PRIVMSG $chan :$hand\'s stats aren't included in the list."
return 1
}
if {[validuser $hand] && ![matchchanattr $hand 5|5 $chan]} {
set foolist "foo"
foreach i [sortbywords $chan] {
lappend foolist [string tolower [lindex $i 1]]
}
set foo "$hand is number "
append foo "[lsearch $foolist [string tolower $hand]] on the list."
append foo " ([lindex [getuser $hand XTRA stat.[string tolower $chan]] 0] words)"
putserv "PRIVMSG $chan :$foo"
return 1
}
}
## Tell place on list on channel, asked by a MSG -----------------------------
bind msg - place msg_place
proc msg_place {nick uhost hand arg} {
if {[string length $arg] < 1} {
putserv "NOTICE $nick :Usage: place <channel>"
return 1
}
if {![regexp -nocase " $arg " " [channels] "]} {
putserv "NOTICE $nick :I'm not monitoring channel $arg"
return 1
}
if {[matchchanattr $hand 5|5 $arg]} {
putserv "NOTICE $nick :Your stats aren't included in the list."
return 1
}
if {[validuser $hand] && ![matchchanattr $hand 5|5 $arg]} {
set foolist "foo"
foreach i [sortbywords $arg] {
lappend foolist [lindex $i 1]
}
set foo "You're number [lsearch $foolist $hand] on the list."
append foo " ([lindex [getuser $hand XTRA stat.[string tolower $arg]] 0] words)"
putserv "NOTICE $nick :$foo"
}
return 1
}
## Tell top 10 talkers on channel, asked by a MSG -----------------------------
bind msg - topten msg_topten
proc msg_topten {nick uhost hand arg} {
if {[regexp topten [timers]]} {return 0}
if {$arg == ""} {
putserv "NOTICE $nick :Usage: topten <channel>"
return 1
}
if {![regexp -nocase " $arg " " [channels] "]} {
putserv "NOTICE $nick :I'm not monitoring that channel"
return 1
}
set foolista [sortbywords $arg]
set foo ""
for {set i 0} {$i < 10} {incr i} {
append foo "[expr $i + 1]. [lindex [lindex $foolista $i] 1]"
append foo "([lindex [lindex $foolista $i] 0]) "
}
timer 1 {return topten}
putserv "NOTICE $nick :$foo"
return 1
}
## Tell top 10 talkers on channel. -------------------------------------------
bind pub - !topten pub_topten
proc pub_topten {nick uhost hand chan text} {
if {[regexp topten [timers]]} {return 0}
set foolista [sortbywords $chan]
set foo ""
for {set i 0} {$i < 10} {incr i} {
append foo "[expr $i + 1]. [lindex [lindex $foolista $i] 1]"
append foo "([lindex [lindex $foolista $i] 0]) "
}
timer 1 {return topten}
putserv "PRIVMSG $chan :$foo"
return 1
}
## Tell user's statistics on all channels, asked by a MSG --------------------
bind msg - stat msg_stat
proc msg_stat {nick uhost hand text} {
if {$text != ""} {set hand $text}
if {[validuser $hand] != 1} {return 0}
foreach chan [channels] {
set chan [string tolower $chan]
set foo [getuser $hand XTRA stat.$chan]
set statmessage "$hand has on $chan :"
append statmessage "[lindex $foo 0] words, "
append statmessage "[lindex $foo 2] publics, "
append statmessage "[lindex $foo 1] letters,"
putserv "NOTICE $nick :$statmessage"
set statmessage ""
append statmessage "[lindex $foo 3] kicks, "
append statmessage "[lindex $foo 4] mode changes, "
append statmessage "[lindex $foo 5] topic changes, "
append statmessage "[lindex $foo 6] actions."
putserv "NOTICE $nick :$statmessage"
}
return 1
}
## Tell user's statistics on the channel. ------------------------------------
bind pub - !stat pub_stat
proc pub_stat {nick uhost hand chan text} {
if {$text != ""} {set hand $text}
set chan [string tolower $chan]
if {[validuser $hand] != 1} {return 0}
if {[matchchanattr $hand 5|5 $chan]} {
puthelp "PRIVMSG $chan :$hand\'s stats aren't included in the list."
return 0
}
set foo [getuser $hand XTRA stat.$chan]
if {$foo == ""} {
putserv "PRIVMSG $chan :$hand has no record for this channel."
return 1
}
set statmessage "$hand has "
append statmessage "[lindex $foo 0] words "
append statmessage "[lindex $foo 2] publics "
append statmessage "[lindex $foo 1] letters."
putserv "PRIVMSG $chan :$statmessage"
set statmessage "and"
if {[lindex $foo 3] > 0} {append statmessage " [lindex $foo 3] kicks"}
if {[lindex $foo 4] > 0} {append statmessage " [lindex $foo 4] mode changes"}
if {[lindex $foo 5] > 0} {append statmessage " [lindex $foo 5] topic changes"}
if {[lindex $foo 6] > 0} {append statmessage " [lindex $foo 6] actions"}
if {$statmessage != "and"} {putserv "PRIVMSG $chan :$statmessage."}
return 1
}
## Catch a mode change and update the field in statrecord --------------------
bind mode - * set_umode
proc set_umode {nick uhost hand chan mode victim} {
if {[validuser $hand]} {
set chan [string tolower $chan]
set foo [getuser $hand XTRA stat.$chan]
if {$foo == ""} {set foo {0 0 0 0 0 0 0}}
set foo [lreplace $foo 4 4 [expr [lindex $foo 4] +1]]
setuser $hand XTRA stat.$chan $foo
}
}
## Catch a kick and update the field in statrecord ---------------------------
bind kick - * set_ukick
proc set_ukick {nick uhost hand chan knick reason} {
if {[validuser $hand]} {
set chan [string tolower $chan]
set foo [getuser $hand XTRA stat.$chan]
if {$foo == ""} {set foo {0 0 0 0 0 0 0}}
set foo [lreplace $foo 3 3 [expr [lindex $foo 3] +1]]
setuser $hand XTRA stat.$chan $foo
}
}
## Catch a topic change and update the field in statrecord -------------------
bind topc - * set_utopc
proc set_utopc {nick uhost hand chan topic} {
if {[validuser $hand]} {
set chan [string tolower $chan]
set foo [getuser $hand XTRA stat.$chan]
if {$foo == ""} {set foo {0 0 0 0 0 0 0}}
set foo [lreplace $foo 5 5 [expr [lindex $foo 5] +1]]
setuser $hand XTRA stat.$chan $foo
}
}
## Catch a CTCP-action and update the field in statrecord --------------------
bind ctcp - ACTION set_uaction
proc set_uaction {nick uhost hand dest keyword args} {
set chan [string tolower $dest]
if {![regexp $chan [string tolower [channels]]]} {return 0}
if {[validuser $hand]} {
set foo [getuser $hand XTRA stat.$chan]
if {$foo == ""} {set foo {0 0 0 0 0 0 0}}
set foo [lreplace $foo 6 6 [expr [lindex $foo 6] +1]]
setuser $hand XTRA stat.$chan $foo
}
return 0
}
## We must have channel specific LASTON records. -----------------------------
## Let's make sure that we really have for every user on every channel.
foreach i [string tolower [channels]] {
foreach j [userlist] {addchanrec $j $i}
}
# Log the start, make sanity checks for versions and init the time binding. ---
putlog "StatWWW 3.01 by Goblet"
if {$numversion < 1030000} {
putlog "WARNING! StatWWW will not work properly with Eggdop version $version"
}
if {$tcl_version < 7.6} {
putlog "WARNING! You need at least TCL7.6 but this is compiled with $tcl_version"
}
bind time - "*0 % % % %" do_stats
## THE END --------------------------------------------------------------------
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum
|
|