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.

[clock format] issue (SOLVED)

Help for those learning Tcl or writing their own scripts.
Post Reply
T
Torrevado
Op
Posts: 101
Joined: Wed Aug 02, 2006 6:29 pm

[clock format] issue (SOLVED)

Post by Torrevado »

Hi,
I need to customize time format in this (reminder) script. Default format is "%Y-%m-%d %H:%M".
It can be easily modified for listing reminders output

Code: Select all

set when [clock format [lindex $reminder 0] -format "%d-%m-%Y %H:%M"]
<torrevado> !reminders
<bot> 1 active reminder(s):
<torrevado> 1289775002: For torrevado at 14-11-2010 23:59: let's do a test

The problem is that I can't make the script work for my date-time format inputs (activating reminder). For an input
!remind torrevado "15-11-2010 00:09" let's do a test
the script "understands" a wrong date:
<torrevado> !reminders
<bot> 1 active reminder(s):
<bot> 1289777003: For torrevado at 02-05-2021 00:09: let's do a test
My question is if it can be solved with [clock format] or if I'm wrong with it. Any help/explanation would be appreciated.

And here it's the script:

Code: Select all

################################################
#################### ABOUT #####################
################################################
#
# Reminder-0.2 by Fredrik Bostrom
# for Eggdrop IRC bot
#
# Usage:
# !remind nick time message
#   - creates a new reminder for nick in the 
#     current channel at time with message
#   - time is a format parseable by the tcl 
#     command 'clock scan'. If the time consists
#     of several words, it has to be enclosed
#     in "".
#   - examples: 
#     !remind morbaq "tomorrow 10:00" Call Peter 
#     !remind morbaq "2009-12-31 23:59" Happy new year!
#
# !reminders 
#   - lists all active reminders
#
# !cancelReminder id
#   - cancels the reminder with id
#   - the id is the number preceeding the 
#     reminder in the list produced by 
#     !reminders
#   - note: the id may change as new reminders 
#     are added or old reminders removed. Always
#     check the id just before cancelling
#
#
################################################
################ CONFIGURATION #################
################################################

set datafile "scripts/reminders.dat"

################################################
######## DON'T EDIT BEOYND THIS LINE! ##########
################################################

bind pub - "!remind" pub:newReminder
bind pub - "!reminders" pub:getReminders
bind pub - "!cancelReminder" pub:cancelReminder
bind pub n "\$inspectReminders" pub:inspectReminders

array set reminders {}

# save to file
proc saveReminders {} {
    global reminders
    global datafile

    set file [open $datafile w+]
    puts $file [array get reminders] 
    close $file
}

# the run-at-time procedure
proc at {time args} {
    if {[llength $args]==1} {
	set args [lindex $args 0]
    }
    set dt [expr {($time - [clock seconds])*1000}]
    return [after $dt $args]
}

proc printReminder {reminderId {fire "false"}} {
    global reminders

    # get the reminder
    set reminder $reminders($reminderId)

    set when [clock format [lindex $reminder 0] -format "%Y-%m-%d %H:%M"]
    set chan [lindex $reminder 1]
    set who [lindex $reminder 2]
    set timer [lindex $reminder 3]
    set what [lindex $reminder 4]

    if {$fire} {
	putserv "PRIVMSG $chan :$who: --REMINDER-- $what"
    } else {
	putserv "PRIVMSG $chan :$reminderId: For $who at $when: $what"
    }
}

proc fireReminder {reminderId} {
    global reminders

    printReminder $reminderId "true"
    unset reminders($reminderId)
    saveReminders
}

proc pub:newReminder {nick host handle chan text} {
    global reminders

    # parse parameters
    set id [clock seconds]
    set who [lindex $text 0]
    set when [lindex $text 1]
    set time [clock scan $when]
    set what [lrange $text 2 end]

    # create new entry
    set new [list $time $chan $who null $what]

    # activate the event
    set timer [at $time fireReminder $id]

    # putlog "new timer: $timer"

    # set the timer associated with this reminder
    set new [lreplace $new 3 3 $timer]
    # putlog "new reminder: $new"

    set reminders($id) $new
    saveReminders

    putserv "PRIVMSG $chan :$who: New reminder at $when: \"$what\""
}

proc pub:getReminders {nick host handle chan text} {
    global reminders
    set chanReminders {}
    
    # count all reminders for this channel
    foreach {key value} [array get reminders] {
	if {[lindex $value 1] == $chan} {
	    lappend chanReminders $key
	}
    }

    # count the reminders
    set howMany [llength $chanReminders]

    # do we have reminders?
    if {$howMany < 1} {
	putserv "PRIVMSG $chan :No active reminders."
	return
    }

    # print reminders for this channel
    putserv "PRIVMSG $chan :$howMany active reminder(s):"
    foreach key $chanReminders {
	printReminder $key
    }
}

proc pub:cancelReminder {nick host handle chan text} {
    global reminders

    set reminder $reminders($text)
    set timer [lindex $reminder 3]

    # putlog "Cancelling timer: $timer"
    after cancel $timer
    unset reminders($text)
    putserv "PRIVMSG $chan :Removed reminder with id $text"

    saveReminders
}

proc pub:inspectReminders {nick host handle chan text} {
    global reminders

    set timerString [after info]
    set reminderString [array get reminders]

    putserv "NOTICE $nick :Reminders: $reminderString"
    putserv "NOTICE $nick :Timers: $timerString"
}

proc initReminders {} {
    global reminders
    
    set reminderString [array get reminders]
    # putlog "Initiating reminders: $reminderString"

    # get current time
    set time [clock seconds]

    # get active timers
    set activeTimers [after info]

    # check for expired reminders and fire them
    foreach {key value} [array get reminders] {
	if {[lindex $value 0] < $time} {
	    fireReminder $key
	} elseif {[lsearch $activeTimers [lindex $value 3]] == -1} {
	    # if the reminder hasn't expired, check if the timer is already set
	    set timerId [at [lindex $value 0] fireReminder $key]
	    set reminders($key) [lreplace $value 3 3 $timerId]
	}
    }
    saveReminders
}


# read the old if they exist
set file [open $datafile]
set content [read $file]
close $file

if {$content == ""} {
    set content {}
}

array set reminders $content

initReminders


###################################
putlog "Reminder script loaded!"
###################################
Last edited by Torrevado on Sun Nov 14, 2010 8:58 pm, edited 1 time in total.
User avatar
speechles
Revered One
Posts: 1398
Joined: Sat Aug 26, 2006 10:19 pm
Location: emerald triangle, california (coastal redwoods)

Post by speechles »

Just a note: This script appears written for the tcl8.4 clock. Allowing a variety of different "free-form" strings to be interpreted. Clock was deprecated in tcl8.5 and this "feature" (some call it a "bug" as sometimes tcl8.4's clock was very ambiguous leading to confusion) has been removed. [clock] in tcl8.5 is "strict", not "lazy" free-form. So you must be precise in what you ask for or it will return bogus timestamps and values.

I'm assuming you are using tcl8.5. In which case [clock scan] has a -format option which tcl8.4 does not. This is enforcement of it's "strict" interpretations. So you simply need to make the change shown below to make tcl8.5 clock aware as to what we have altered it's expected date/time format to be.

Code: Select all

proc pub:newReminder {nick host handle chan text} {
    global reminders

    # parse parameters
    set id [clock seconds]
    set who [lindex $text 0]
    set when [lindex $text 1]
    # BELOW IS THE ONLY LINE YOU CHANGE THE REST IS TO GIVE CONTEXT
    set time [clock scan "$when" -format "%d-%m-%Y %H:%M"]
    ...
Also include the change you made here for completeness...

Code: Select all

proc printReminder {reminderId {fire "false"}} {
    global reminders

    # get the reminder
    set reminder $reminders($reminderId)
    # BELOW IS THE ONLY LINE YOU CHANGE THE REST IS TO GIVE CONTEXT
    set when [clock format [lindex $reminder 0] -format "%Y-%m-%d %H:%M"] 
    ...
Those 2 changes (to add and print) should allow your modified date format to now work correctly.
T
Torrevado
Op
Posts: 101
Joined: Wed Aug 02, 2006 6:29 pm

Post by Torrevado »

@speechles

Simply perfect. Thank you very much :)
Post Reply