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.

read from a file ?

Help for those learning Tcl or writing their own scripts.
Post Reply
G
Gemster
Halfop
Posts: 51
Joined: Mon Oct 04, 2010 5:43 pm

read from a file ?

Post by Gemster »

Hi, how do i make this read from the file and output it ?

Code: Select all

bind raw - 322 channel:list
proc channel:list {from keyword text} {
set cl [open scripts/chanlist.txt a+]
puts $cl "[lindex $text 1]" 
close $cl
}

bind pub - ".chanlist" chanlist
proc chanlist {nick uhost hand chan text} {
putserv "list"
}
I need it to msg channel ###1 all lines in that file.

Thanks
Gemster
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

One simple way of doing it is like this:

Code: Select all

...
proc chanlist {nick uhost hand chan text} {
  if {[catch {open "scripts/chanlist.txt" "RDONLY"} fd]} {
    puthelp "PRIVMSG ###1 :Unable to open the channel-list"
    putlog "Error during open: $fd"
    return 0
  }
  fconfigure $fd -blocking 0
  while {![eof $fd] && ![fblocked $fd]} {
    if {[gets $fd data] > 0} {
      puthelp "PRIVMSG ###1 :$data"
    }
  }
  close $fd
}
Some prefer using read, split, and foreach instead, which also works..

Edit: Fixed typo spotted by caesar
Last edited by nml375 on Sun Mar 06, 2011 6:38 pm, edited 1 time in total.
NML_375
G
Gemster
Halfop
Posts: 51
Joined: Mon Oct 04, 2010 5:43 pm

Post by Gemster »

Thanks nml375, but thats kinda too complicated for me to understand atm lol, im new to tcl scripting.

Is it possible to use the code i posted but will a read command that will msg channel ###1 the output ?

The file is written as a list like this:

#channel1
#channel2
#channel3

Thanks
Gemster
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

That is what my code will do (provided you use the bindning from your original post, simply replacing the "chanlist" proc).
NML_375
User avatar
caesar
Mint Rubber
Posts: 3778
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

Shouldn't it be 'fblocked $fd' and not 'fblocked $df'?
Once the game is over, the king and the pawn go back in the same box.
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

caesar:
True, thanks for pointing out the typo. Updated the original post.
NML_375
G
Gemster
Halfop
Posts: 51
Joined: Mon Oct 04, 2010 5:43 pm

Post by Gemster »

I still dont understand that script you posted lol

Ill i want is a command that will read from a file ?

Thanks
Gemster
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

Add the binding

Code: Select all

bind pub - ".chanlist" chanlist
as I said, and that's exactly what it does
NML_375
G
Gemster
Halfop
Posts: 51
Joined: Mon Oct 04, 2010 5:43 pm

Post by Gemster »

I know yours does that nml375, but id like to learn this but i cant as i dont understand your script.

The script i posted i made my self and took a few hours as for googleing everything but the examples i seen for "gets" i just cant get them to work.

The main reason i need to learn is that there are a lot of script id like to make but they require a file made and read from , this is why i need to learn myself as simple as possible.

Thanks
Gemster
User avatar
caesar
Mint Rubber
Posts: 3778
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

@Gemster : You don't need to google anything, just have a look on Tcl Commands. All the stuff are explained in there.

Also, if you checked the Tcl FAQ you would have found Basic File Operations where you would have found some interesting stuff to read on this topic.

Regarding your first post, you don't need to add " in:

Code: Select all

puts $cl "[lindex $text 1]" 
unless you want to add two or more variables, like:

Code: Select all

puts $cl "$bla $blah" 
or some text:

Code: Select all

puts $cl "bla blah" 
@nml375 : no problem. keep up the good work. :)
Once the game is over, the king and the pawn go back in the same box.
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

Since you're not looking for someone just writing code for you, I believe this thread rather belongs to the "Scripting Help" forum (I'll move it there once I'm done with this post)

As for the code, it's not that complex; I'll walk you through it..

Code: Select all

if {[catch {open "scripts/chanlist.txt" "RDONLY"} fd]} {
  puthelp "PRIVMSG ###1 :Unable to open the channel-list"
  putlog "Error during open: $fd"
  return 0
}
This simply opens the file in a safe manner. "catch" simply catches any errors thrown by open, allowing us to send an error to the person using the command, and logging the actual error message for further investigation.
If the open-command succeeds, a file descriptor is stored in the variable fd instead...

Code: Select all

fconfigure $fd -blocking 0
Sets the file descriptor to "non-blocking" mode; which means that no operations on this descriptor may block (blocking == not returning / completing immediately). Usually not needed to be set explicitly with normal files, but it's a good practice in most cases (makes sure your code won't cause your eggie to stop responding in case of I/O issues)

Code: Select all

while {![eof $fd] && ![fblocked $fd]} {
...
}
Run a loop which checks the EOF (End of File) and fblocked (blocking operation, see above) status of the last operation (in this case; reading a line from the file). EOF will be true if we've reached the end of the file. Fblocked would be true if the last call to "gets" would not return a complete line - not likely to happen with files, but once again good practice (especially if you start reading sockets, serial ports, or pipes in the future).
Simply put, this will make sure we keep on reading the file until we've reached the end of it.

Code: Select all

..
if {[gets fd data] > 0 } {
  ...
}
Try to read one line from the file, and store it in the variable "data". Also check how many characters we actually read (0 means an empty line, anything less than 0 means there was an error, such as EOF). If we've read something, then we should write it to the channel..

Code: Select all

...
puthelp "PRIVMSG ###1 :$data"
...
Send the line of text we've read into the channel ###1.
NML_375
Post Reply