egghelp.org community Forum Index
[ egghelp.org home | forum home ]
egghelp.org community
Discussion of eggdrop bots, shell accounts and tcl scripts.
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Deleted File Keeps Coming Back

 
Post new topic   Reply to topic    egghelp.org community Forum Index -> Scripting Help
View previous topic :: View next topic  
Author Message
Landslyde
Halfop


Joined: 01 May 2014
Posts: 43

PostPosted: Thu May 04, 2017 3:33 am    Post subject: Deleted File Keeps Coming Back Reply with quote

One of my bots (1.6.21) uses a statistics script that generates a file, tracking how much the users yack on the channel. I have a cron job that deletes this file daily (verified deletion). But, even though the file gets deleted, it keeps showing the old data as if it was never deleted.

My Cron:
Code:
00 03 * * * rm  /home/shianne/eggdrop/scripts/dbase/statistics

What can I do to make my bot clear out the stats of this deleted file statistics? I've tried rehashing to no avail. And if I restart it, the deleted file is back!

This is silly stuff, something so simple as this, but I can't make it work. Any ideas? Anyone?
Back to top
View user's profile Send private message
willyw
Owner


Joined: 15 Jan 2009
Posts: 925

PostPosted: Thu May 04, 2017 4:36 am    Post subject: Re: Deleted File Keeps Coming Back Reply with quote

Landslyde wrote:

....
it keeps showing the old data as if it was never deleted.


What do you mean by, "showing" ?
For example: The bot posts the data to a channel at specific times?

Quote:

...
And if I restart it, the deleted file is back!


After deletion, and immediately after a restart, is there data in this file?

Quote:

...
Any ideas? Anyone?


Without seeing the complete script, I'll guess that there is code in it that upon rehash and/or restart - checks to see if file exists, and if not then it creates it. If it has data in it, then it creates it just before the .restart.


I suggest that you post the complete script.
_________________
For a fun (and popular) Trivia game, visit us at: irc.librairc.net #science-fiction . Over 300K Q & A to play in BogusTrivia !
Back to top
View user's profile Send private message
Landslyde
Halfop


Joined: 01 May 2014
Posts: 43

PostPosted: Thu May 04, 2017 6:23 am    Post subject: Reply with quote

My cron job:
Code:
00 03 * * * rm  /home/shianne/eggdrop/scripts/dbase/statistics

This works fine.

Here's the restart.tcl. This works fine.
Code:
## this equals 04:00 am CST
bind cron - {00 03 * * *} restart:cron

proc restart:cron {min hour day month weekday} {
   restart
}


The bot restarts at the same time the file is deleted. And when she co,es back, the statistic data from the deleted file is still there. This is very frustrating. Very.

Quote:
What do you mean by, "showing" ?
For example: The bot posts the data to a channel at specific times?

You manually call up the data, at any time, using commands.

Quote:
After deletion, and immediately after a restart, is there data in this file?

Yes. It's like the contents of the deleted file are still in the bot's memory, even after a restart. And mysteriously, the file is back. Just as if it had never been deleted.

Quote:
Without seeing the complete script, I'll guess that there is code in it that upon rehash and/or restart - checks to see if file exists, and if not then it creates it. If it has data in it, then it creates it just before the .restart.

Code:
# Statistics.tcl (C) 2004 perpleXa
#  type ".chanset <chan> +stat" on the partyline to ativate the script for a specific channel.
#  commands: $stat <nick> - shows information about you or a nick. (works only for other nicks when you are op on a channel)
#            $top10 <smilies|words|lines|letters> - shows the top10 chatters, default option is words
#            $top20 <smilies|words|lines|letters> - same as $top10 but with places 11-20


namespace eval statistics {
# Storage file
  variable storage {scripts/dbase/statistics}

# Kill unused entries after x days
  variable killafter 30

# Command trigger
  variable trigger {.}

# smiley regex (only touch this, if you really know, what you are doing!)
  variable smileyregex {(:|8|;|=)(-|o)?(>|<|D|O|o|\)|\(|\]|\[|P|p|\||\\|/)}

  bind PUB   -|-  ${trigger}stats   [namespace current]::spew
  bind PUB   -|-  ${trigger}top10   [namespace current]::toplist
  bind PUB   -|-  ${trigger}top20   [namespace current]::toplist
  bind PUBM  -|-  *                 [namespace current]::monitor
  bind CTCP  -|-  ACTION            [namespace current]::ctcp
  bind EVNT  -|-  save              [namespace current]::save
  bind TIME  -|-  {00 * * * *}      [namespace current]::cleanupdb

  setudef flag stat

  namespace export spew top10 toplist save load monitor
}

proc statistics::ctcp {nickname hostname handle target keyword arguments} {
  if {[validchan $target]} {
    monitor $nickname $hostname $handle $target $arguments
  }
  return 0
}

proc statistics::monitor {nickname hostname handle channel arguments} {
  variable data
 
variable smileyregex
  if {$nickname == "maricar"} { return 0 }
  if {$nickname == "Stryker"} { return 0 }
  if {$nickname == "Cyell"} { return 0 }
  if {([isbotnick $nickname]) || (![channel get $channel stat])} {
    return 0
  }
  set hostname [maskhost *!$hostname]
  regsub -all -- {\002|\003[\d]{0,2}(,[\d]{0,2})?|\006|\007|\017|\026|\037|\n|\t} $arguments {} arguments
  set added(words) [regexp -all -- {\S+} $arguments]
  set added(letters) [regexp -all -- {\S} $arguments]
  if {[string length $smileyregex] >= 1} {
    set added(smilies) [regexp -all -- $smileyregex $arguments]
  } else {
    set added(smilies) 0
  }
  if {(![info exists data($channel,$hostname)])} {
    set data($channel,$hostname) "0 0 0 0 0 NULL"
  }
  regexp -- {^(\d+)\s(\d+)\s(\d+)\s(\d+)\s(\d+)\s(\S+)$} $data($channel,$hostname) -> lastseen lines words letters smilies lastnick
  incr lines 1
  incr words $added(words)
  incr letters $added(letters)
  incr smilies $added(smilies)
  set data($channel,$hostname) "[unixtime] $lines $words $letters $smilies $nickname"
}

proc statistics::spew {nickname hostname handle channel arguments} {
  variable data
  if {(![channel get $channel stat])} {
    return 0
  }
  if {([string length $arguments] >= 1)} {
    set target [lindex [clean $arguments] 0]
  } else {
    set target $nickname
  }
  if {![onchan $target $channel]} {
    putserv "PRIVMSG $channel :\[Statistics - Unknown user \002$target\002\]"
    return 0
  }
  set targethost [maskhost *![getchanhost $target $channel]]

  if {[info exists data($channel,$targethost)]} {
    regexp -- {^(\d+)\s(\d+)\s(\d+)\s(\d+)\s(\d+)\s(\S+)$} $data($channel,$targethost) -> lastseen lines words letters smilies lastnick
    set wpl [round [expr ($words / $lines.)]]
    set spl [round [expr ($smilies / $lines.)]]
    set lpw [round [expr ($letters / $words.)]]
    putserv "PRIVMSG $channel :\[Statistics - \002$target\002 has written \002$lines\002 lines, \002$words\002 ($wpl per line) words and \002$letters\002 ($lpw per word) letters, containing \002$smilies\002 ($spl per line) smilies\]"
  } else {
    putserv "PRIVMSG $channel :\[Statistics - No valuable information available for \002$target\002\]"
  }
}

proc statistics::top {channel number {type ""}} {
  variable data
  set statistics {}
  switch $type {
    {lines} {set index 1}
    {letters} {set index 3}
    {smilies} {set index 4}
    {default} {set index 2 ; set type "words"}
  }
  foreach {user stats} [array get data $channel,*] {
    set stats [clean $stats]
    lappend statistics "[lindex [clean $stats] 5] [lindex $stats $index]"
  }
  set statistics [lrange [lsort -integer -decreasing -index 1 [lsort -unique -index 0 [lsort -integer -increasing -index 1 $statistics]]] [expr $number - 10] [expr $number - 1]]
  if {$statistics == ""} {
    return "\[Top$number $type - No valuable information available for \002$channel\002\]"
  }
  set output "\[Top$number $type -"
  for {set i 0} {$i < [llength $statistics]} {incr i 1} {
    set item [lindex $statistics $i]
    append output "\x20[expr $i+$number-9]: \002[join [lindex [clean $item] 0] { }]\002 ([lindex $item 1])"
  }
  append output "\]"
  return $output
}

proc statistics::toplist {nickname hostname handle channel arguments} {
  global lastbind
  if {(![channel get $channel stat])} {
    return 0
  }
  set arguments [clean $arguments]
  set key [lindex $arguments 0]
  if {![regexp -- {^.*?([0-9]+)$} $lastbind -> number]} {
    return 0
  }
  if {![regexp -nocase -- {^(words|letters|smilies|lines|)$} $key]} {
    putserv "PRIVMSG $channel :\[Statistics - Unknown option: \002$key\002, valid options are \002letters\002, \002lines\002, \002smilies\002 and \002words\002\]"
    return 0
  }
  putserv "PRIVMSG $channel :[top $channel $number [string tolower $key]]"
}

proc statistics::cleanupdb {args} {
  variable killafter
  variable data
  set killed 0
  foreach {item} [array names data] {
    set lastseen [lindex [clean $data($item)] 0]
    set expire [expr 60 * 60 * 24 * $killafter]
    if {[expr [unixtime] - $lastseen] >= $expire} {
      incr killed
      unset data($item)
    }
  }
  return $killed
}

proc statistics::load {} {
  variable data
  variable storage
  regexp -- {^(\S+/)?.*$} $storage -> directory
  if {[string length $directory] >= 1} {
    if {![file isdirectory $directory]} {
      file mkdir $directory
    }
  }
  if {![file exists $storage]} {
    return 0
  }
  if {[array exists data]} {
    array unset data
  }
  set file [open $storage r]
  while {![eof $file]} {
    gets $file line
    if {[regexp -nocase -- {^channel:(\S+)\sid:(\S+)\svalue:(\d+)\s(\d+)\s(\d+)\s(\d+)\s(\d+)\s(\S+)$} $line -> channel hostname lastseen lines words letters smilies lastnick]} {
      set data($channel,$hostname) "$lastseen $lines $words $letters $smilies $lastnick"
    }
  }
  close $file
}

proc statistics::save {args} {
  variable data
  variable storage
  set file [open $storage w]
  foreach chan_user [array names data] {
    regexp {^(\S+),(\S+)$} $chan_user -> channel user
    puts $file "channel:$channel id:$user value:$data($chan_user)"
  }
  close $file
}

proc statistics::clean {i} {
  regsub -all -- \\\\ $i \\\\\\\\ i
  regsub -all -- \\\[ $i \\\\\[ i
  regsub -all -- \\\] $i \\\\\] i
  regsub -all -- \\\} $i \\\\\} i
  regsub -all -- \\\{ $i \\\\\{ i
  return $i
}

proc statistics::round {num} {
  if {![string match "*.*" $num]} {
    return $num\.0
  }
  if {![regexp -- {^(\d+?)\.(\d+)$} $num -> primary secondary]} {
    error "syntax error in expression '$num'"
  }
  set secondary [expr round([string index $secondary 0].[string range $secondary 1 end])]
  return [expr {($secondary == 10) ? ($primary+1.0) : "$primary.$secondary"}]
}

statistics::load

putlog "Script loaded: Statistics by perpleXa"
Back to top
View user's profile Send private message
willyw
Owner


Joined: 15 Jan 2009
Posts: 925

PostPosted: Thu May 04, 2017 2:59 pm    Post subject: Reply with quote

Landslyde wrote:

...
It's like the contents of the deleted file are still in the bot's memory,


Exactly.

Quote:

even after a restart.


Or ... stored in a file and read back into memory, on restart? Smile


Ok... let's see...

See that line, second from the end of the script?
Code:

statistics::load

that line runs a procedure named
load
found in your script's namespace named "statistics" , every time this script is loaded. That means : every start up, every rehash and every restart

So let's go see what that proc does.

Found this? : proc statistics::load {} {
see those lines like :
set file [open $storage r]
and
close $file
?
That's open and closing a file, and there are lines in between that read that file, and store it in an array named
data

The variable name "data" is used throughout the script ... looks like that is where all the stats are stored.

Now we know how and why the stats are loaded into memory.
They come from a file where they are stored, and it is read in on every start up, or rehash, or .restart
Make sense so far?

Next, let's look at:
Code:

bind EVNT  -|-  save              [namespace current]::save


( go here : http://www.eggheads.org/support/egghtml/1.6.21/tcl-commands.html
and text search to find
bind evnt
and read about what the
save
event is, and when it is triggered. )

Next, find that proc that is called by the bind EVNT
Find this:
proc statistics::save {args} {

That's going through everything in the array named "data" and saving it to a file.
Apparently this happens every time the userfile is saved. I'm not sure, but I seem to recall that happens automatically every 10 minutes, and also on normal exits of the bot... like if you used .restart or .die .

Can you picture now, what is happening?
It's simply coming right behind your cron job that deletes the file, and re-creating it.... just like you described.

I see you have already worked with
bind cron
in your experiments with restart, so you are familiar with it.
If you set a bind cron to trigger at the same time as your cron job that deletes the file, and in this bind cron you have it
unset data
wouldn't you now have: no longer any file that is storing the stats, and no stats in memory?
_________________
For a fun (and popular) Trivia game, visit us at: irc.librairc.net #science-fiction . Over 300K Q & A to play in BogusTrivia !
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    egghelp.org community Forum Index -> Scripting Help All times are GMT - 4 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Forum hosting provided by Reverse.net

Powered by phpBB © 2001, 2005 phpBB Group
subGreen style by ktauber