This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

Line deletion in a file [solved]

Help for those learning Tcl or writing their own scripts.
Post Reply
L
Luminous
Op
Posts: 146
Joined: Fri Feb 12, 2010 1:00 pm

Line deletion in a file [solved]

Post by Luminous »

So I've hit another wall with an idea I had... I want to create my own banlist, basically, that will allow me to better track the time/dates and reasons for bans. That part I think I have below. It sets a ban and then writes the info I want to a file. Problem is that I have been unable to retrieve that line to delete it if !uban is used, and that ban matches a line with that mask in the file. Here's what I have so far, not sure how much of it is correct for what I am trying to do, but I think the first part is okay:

Code: Select all

bind pub o|o !ban ban
proc ban {nick host hand chan text} {
   global botnick
 set ban [lindex [split $text] 0]
 set reason [join [lrange [split $text] 1 end]]
 set phile [open "bans.txt" r+]
    if {$ban == ""} {
 set bnum 0
    while {[gets $phile line] >= 0} {
        puthelp "NOTICE $nick :[incr bnum]. $line"
}
 return
    } elseif {[ischanban $ban $chan]} {
        putnotc $nick "Ban: $ban already exists."
 return
    } elseif {$reason == ""} {
        putnotc $nick "Please specify a ban reason."
 return
}
 set when [clock seconds]
        putquick "MODE $chan +b $ban $reason"
        puts $phile "$ban - Set by $nick on [clock format $when -format %D-%T] - Reason - $reason"
        close $phile
 return
}

# Need to also remove the corresponding ban info in ban.txt if chanban is removed.

bind pub o|o !uban uban
proc uban {nick host hand chan text} {
 set bans [chanbans $chan]
 set ban [lindex [split $text] 0]
 set phile [open "bans.txt" r+]
    if {[ischanban $ban $chan]} {
        putquick "MODE $chan -b $ban"
    } else {
        putnotc $nick "No such ban: $ban"
    }
}
Help on finishing it off please? I've talked to several people and read a lot of stuff, but nothign has ben able to explain what iI need to do for this to work..
Last edited by Luminous on Fri Aug 13, 2010 1:35 pm, edited 1 time in total.
h
horgh
Voice
Posts: 10
Joined: Sat Feb 13, 2010 3:12 pm

Post by horgh »

Code: Select all

bind pub o|o !uban uban
proc uban {nick host hand chan text} {
  set ban [lindex [split $text] 0]

  set fid [open bans.txt]
  set records [read -nonewline $fid]
  close $fid

  set records [split $records \n]
  set record [lsearch $records $ban*]

  if {$record > -1 && [ischanban $ban $chan]} {
    set records [lreplace $records $record $record]
    set fid [open bans.txt w]
    foreach line $records {
      puts $fid $line
    }
    close $fid
    putquick "MODE $chan -b $ban"
  } else {
    putnotc $nick "No such ban: $ban"
  }
}
I didn't test this!
It reads whole file in, makes each ban record an element in a list, searches this list, and removes the index from the list if found. It then writes each record line by line back to the file (overwriting the old file).
L
Luminous
Op
Posts: 146
Joined: Fri Feb 12, 2010 1:00 pm

Post by Luminous »

Hm, realized I made a few minor mistakes in the !ban proc, like keeping the global botnick when I didn't need it and having a $reason on the ban line- lol, oops. Before, I was using newchanban, and I was trying to set timed bans, so that's what the global botnick was from. Newchanban has stopped setting bans for me though, so I'm forced to use regular banning.

Anyway, I only had a chance to test that briefly, but i set a ban, then removed it and it vanished from the file. So it seems to work. :o I actually wasn't too far off in my earlier attempts, Ireplace hadn't occurred to me. :S
Last edited by Luminous on Sun Jul 04, 2010 6:24 pm, edited 1 time in total.
L
Luminous
Op
Posts: 146
Joined: Fri Feb 12, 2010 1:00 pm

Post by Luminous »

Hm, I've run into a few issues. Firstly, when !uban <mask> is used, it deletes all lines from the file. Also, when noticing the user the ban list, it does not number the bans, instead it looks like this:

1. *!*@*.pools.spcsdns.net - Set by me on 07/04/2010-17:35:31 - Reason - testing
1. test!*@* - Set by me on 07/04/2010-18:12:28 - Reason - testing
1. testing!*@* - Set by me on 07/04/2010-18:14:38 - Reason - testing

I want it to be 1., 2., 3., etc. But the most major problem is that it deletes all lines from the file rather than just the one. My guess is its the lreplace line, but the man page for that is not very helpful, so I don't fully understand its usage..
h
horgh
Voice
Posts: 10
Joined: Sat Feb 13, 2010 3:12 pm

Post by horgh »

Well you'll have to pastebin the current script so we can look.
L
Luminous
Op
Posts: 146
Joined: Fri Feb 12, 2010 1:00 pm

Post by Luminous »

h
horgh
Voice
Posts: 10
Joined: Sat Feb 13, 2010 3:12 pm

Post by horgh »

You are closing the file and returning inside the while loop for reading which is probably not what you want.

Your file gets cleared when a ban is added as you are opening it with "w". To add a line to the end of the file you should open with "a". This is maybe what is causing the file to be cleared as only the latest ban would show up.

The unban portion doesn't look as though it would empty the file. It does clear it in that it rewrites the whole file each time but only one line should be removed.

The lreplace just removes the index given twice:

Code: Select all

% set l [list one two three four]
one two three four
% lsearch $l two
1
% lreplace $l 1 1
one three four
L
Luminous
Op
Posts: 146
Joined: Fri Feb 12, 2010 1:00 pm

Post by Luminous »

Its not the ban part, that appends to the file fine. Whenever I set that part from w to a though, it rewrites the previous ban.Still don't understand why it labels each one as "1." either...
L
Luminous
Op
Posts: 146
Joined: Fri Feb 12, 2010 1:00 pm

Post by Luminous »

Okay, I've tried this a few more ways.... Based on what I have read the last few days, I have come up with this:

Code: Select all

bind pub o|o ~kb kickban
proc kickban {nick uhost hand chan text} {
 set whom [lindex [split $text] 0]
 set reason [join [lrange [split $text] 1 end]]
 set host [getchanhost $whom $chan]
 set split(host) [string trimleft $host @]
    if {$whom == ""} {
 set phile [open "bans.txt" r+]
 set bnum 0
    while {[gets $phile line] >= 0} {
        puthelp "NOTICE $nick :[expr {$bnum + 1}]. $line"
     close $phile
 return
    }
}
    if {[onchan $whom $chan]} {
     if {[isop $whom $chan]} {
       putserv "PRIVMSG $nick :Its not polite to attempt to kickban a fellow operator."
 return 0
}   
    if {[regexp -nocase -- {@([:0-9A-Fa-f]+$)} $host a b]} {
       putquick "MODE $chan +b *!*$b"
 set mask *!*$b
    } elseif {[regexp -nocase -- {@(\D*\d+[-.]\d+)[-.]\d+[-.]\d+$} $host a b]} {
       putquick "MODE $chan +b *!*@$b*"
 set mask *!*@$b*
    } elseif {[regexp -nocase -- {@\D*(?:[a-z]+)$} $host a]} {
       putquick "MODE $chan +b *!*$a"
 set mask *!*$a
    } elseif {[regexp -nocase -- {@\D*(?:\d+[-.]){4}(\D*)$} $host a b]} {
       putquick "MODE $chan +b *!*@*.$b"
 set mask *!*@*.$b
    } else {
     if {[string match "*.*" $host]} {
       putquick "MODE $chan +b *!*[lindex [split $host @] 0]@*.[join [lrange [split $host .] end-2 end] .]"
 set mask *!*[lindex [split $host @] 0]@*.[join [lrange [split $host .] end-2 end] .]
     } else {
       putquick "MODE $chan +b *!*[lindex [split $host @] 0]@*.[join [lrange [split $host /] end-2 end] /]"
 set mask *!*[lindex [split $host @] 0]@*.[join [lrange [split $host /] end-2 end] /]
     }
 }
     if {$reason == ""} {
       putserv "KICK $chan $whom :Banned."
     } else {
       putserv "KICK $chan $whom :$reason"
}
 set when [clock seconds]
 set phile [open "bans.txt" w]
       puts $phile "$mask - Set by $nick on [clock format $when -format %D-%T] -Reason - $reason"
       close $phile
 return
    } else {
  putserv "PRIVMSG $nick :$whom is not here to kickban!"
    }
}

bind pub o|o ~uban uban
proc uban {nick host hand chan text} {
 set ban [lindex [split $text] 0]
    if {$ban == ""} {
 return
    } elseif {[ischanban $ban $chan]} {
 set fid [open bans.txt]
 set bans [read -nonewline $fid]
  close $fid
 set banl [split $bans \n]
 set match "$ban *"
   while {[set i [lsearch -glob $banl $match]] > -1} {
 set lines [lreplace $banl $i $i]
}   
 set fid [open bans.txt w]
   puts $fid [join $lines "\n"]
   close $fid
      putquick "MODE $chan -b $ban"
    } else {
      putnotc $nick "No such ban: $ban"
   }
}
Same problem remains. Still numbers every line as "1." and still erases all lines in the file. And that lsearch/lreplace line came from a post that I think user made... it, of course, does not work. Seems like the only flaw is in how it removes lines from the lines. Its gotta be something... maybe its how its written to the file? Doesn't seem like this should be this hard...
User avatar
speechles
Revered One
Posts: 1398
Joined: Sat Aug 26, 2006 10:19 pm
Location: emerald triangle, california (coastal redwoods)

Post by speechles »

Code: Select all

bind pub o|o ~kb kickban
proc kickban {nick uhost hand chan text} {
 set whom [lindex [split $text] 0]
 set reason [join [lrange [split $text] 1 end]]
 set host [getchanhost $whom $chan]
 set split(host) [string trimleft $host @]
 if {![string length $whom]} {
   set phile [open "bans.txt" r+]
   set bnum 0
   while {[gets $phile line] >= 0} {
      puthelp "NOTICE $nick :[incr bnum]. $line"
      close $phile
      return
   }
 }
 if {[onchan $whom $chan]} {
   if {[isop $whom $chan]} {
     putserv "PRIVMSG $nick :Its not polite to attempt to kickban a fellow operator."
     return 0
   }   
   if {[regexp -nocase -- {@([:0-9A-Fa-f]+$)} $host a b]} {
     putquick "MODE $chan +b *!*$b"
     set mask *!*$b
   } elseif {[regexp -nocase -- {@(\D*\d+[-.]\d+)[-.]\d+[-.]\d+$} $host a b]} {
     putquick "MODE $chan +b *!*@$b*"
     set mask *!*@$b*
   } elseif {[regexp -nocase -- {@\D*(?:[a-z]+)$} $host a]} {
       putquick "MODE $chan +b *!*$a"
       set mask *!*$a
   } elseif {[regexp -nocase -- {@\D*(?:\d+[-.]){4}(\D*)$} $host a b]} {
       putquick "MODE $chan +b *!*@*.$b"
       set mask *!*@*.$b
   } else {
     if {[string match "*.*" $host]} {
       putquick "MODE $chan +b *!*[lindex [split $host @] 0]@*.[join [lrange [split $host .] end-2 end] .]"
       set mask *!*[lindex [split $host @] 0]@*.[join [lrange [split $host .] end-2 end] .]
     } else {
       putquick "MODE $chan +b *!*[lindex [split $host @] 0]@*.[join [lrange [split $host /] end-2 end] /]"
       set mask *!*[lindex [split $host @] 0]@*.[join [lrange [split $host /] end-2 end] /]
     }
   }
   if {$reason == ""} {
     putserv "KICK $chan $whom :Banned."
   } else {
     putserv "KICK $chan $whom :$reason"
   }
   set when [clock seconds]
   set phile [open "bans.txt" w]
   puts $phile "$mask - Set by $nick on [clock format $when -format %D-%T] -Reason - $reason"
   close $phile
   return
 } else {
   putserv "PRIVMSG $nick :$whom is not here to kickban!"
 }
}

bind pub o|o ~uban uban
proc uban {nick host hand chan text} {
 set ban [lindex [split $text] 0]
 if {![string length $ban]} {
   return
 } elseif {[ischanban $ban $chan]} {
 set fid [open bans.txt]
 set bans [split [read -nonewline $fid] \n]
 close $fid
 while {[set i [lsearch -glob $bans "$ban *"]] > -1} {
   putquick "MODE $chan -b [lindex [split [lindex $bans $i]] 0]"
   set lines [lreplace $bans $i $i]
 }
 if {[info exists $lines]} {   
   set fid [open bans.txt w]
   puts $fid [join $lines "\n"]
   close $fid
 } else {
   putnotc $nick "No such ban: $ban"
 }
} 
Now it won't suffer those issues. Enjoy ;)
L
Luminous
Op
Posts: 146
Joined: Fri Feb 12, 2010 1:00 pm

Post by Luminous »

'm still get the same issues, regarding the file writing/reading part... :\ I did have to add a brace to that uban code. I have been unable to test it by actually using it on multiple people, but I added a fake ban, etc to the file, then banned a tester I brought on. I actually think it IS the initial banning part. Upon further testing, it does seem to remove the line properly, but adding it seems to be the problem. :S I did try opening it with a... that does absolutely nothing as far as I can tell, although that does seem to be what I want- an appendment to the file.
Post Reply