This page provides examples of how to read and write a Microsoft Outlook document using the Tcom package. See How one discovers the API for a COM-exporting application for more help on finding Outlook commands.
package require tcom proc ConvertTime {t} { regexp {([+-])(\d\d)(\d\d)} [clock format [clock seconds] -format %z] m sign hours minutes set tlocal [expr "$t $sign ($hours *60 +$minutes)*60"] return [expr {(25569+$tlocal/24/3600)+(($tlocal%(24*3600))/(24.0*3600))}] } set outlook [::tcom::ref getactiveobject Outlook.Application] set app [$outlook Application] set entry [$app CreateItem [expr 1]] $entry Subject "This is the subject" $entry Start [ConvertTime [clock scan {2009-02-13 21:00}]] $entry End [ConvertTime [clock scan {2009-02-13 21:30}]] $entry Save
Jaf:A Small Outlook Calendar Clien/Server Pair I used these to query my appointments from my UNIX machine, I tend to miss meetings while working on a Unix station.
This could help finish the work on A Calendar Widget, see Future Feature discussion.
First the Server:
proc msdate_to_iso {val} { set base_ticks [clock scan 20000101] set base_offset 36526;# days since 31. Dec 1899, ARRRGGHHHHH set offset [expr {int($val)-$base_offset}] set clkdate [clock scan "$offset days" -base $base_ticks] set isodate [clock format $clkdate -format %Y%m%d] set fhours [expr {24.0*($val-int($val))}] set hours [expr {int($fhours)}] set mins [expr {int(($fhours-$hours)*60)}] return "$isodate $hours:$mins" } proc get_appointments {startdate enddate} { # set up search scope set w_startdate \ [clock format [clock scan "${startdate}T000000"] -format "'%d/%m/%Y'"] set w_enddate \ [clock format [clock scan "${enddate}T000000"] -format "'%d/%m/%Y'"] set restriction "\[Start\] <= $w_enddate AND \[End\] >= $w_startdate" # tcom stuff if {[catch {::tcom::ref getactiveobject Outlook.Application} outlook]} { return {} } set app [$outlook Application] set session [$app Session] $session Logon set calitems [$session GetDefaultFolder 9] set calendar [$calitems Items] $calendar IncludeRecurrences 1 $calendar Sort "\[Start\]" set wanted [$calendar Restrict $restriction] $wanted Sort "\[Start\]" # make list out of the returned data set retlist {} ::tcom::foreach ent $wanted { lappend retlist [list "Start" [msdate_to_iso [$ent Start]] \ "End" [msdate_to_iso [$ent End]] \ "Subject" [$ent Subject] \ "Location" [$ent Location] \ "Categories" [$ent Categories]] } puts "returning [llength $retlist] items" return $retlist } proc process {chan addr port} { # if nothing there if {[eof $chan]} { close $chan; return } # buffering to lines to accomodate puts/gets on the other side fconfigure $chan -buffering line # retrieve message set mess [gets $chan] # report message puts "$addr:$port \@ $chan tells me \"$mess\"" # remove extra blanks set mess_clean [string trim [regsub -all -- { +} $mess { }]] # retrieve command and argument set mesg_list [split $mess_clean { }] set command [lindex $mesg_list 0] set startdate [lindex $mesg_list 1] set enddate [lindex $mesg_list 2] # react switch -exact -- $command { "get_appointments" { puts $chan [$command $startdate $enddate] } default { puts $chan "Only \"get_appointments\" allowed" puts "erroneous command: $command" } } close $chan } package require tcom set listen [socket -server process 3456] vwait forever
The client is trivially simple:
set ipserver "mypcname_or_inetaddress_here"; # put PC name or address here set ipport "3456" ; # big (> 1024) port here proc get_appointments {startdate enddate} { set channel [socket $::ipserver $::ipport] fconfigure $channel -buffering line puts $channel "get_appointments $startdate $enddate" gets $channel retval close $channel return $retval }
By the way: Does anybody know why Microsoft chose to format dates as floats (apart from the fact that they might have wanted to do something different than Unix)?
An integer part counting the days since 31 Dec 1899 (Day 0) while the fractional part represents the fraction of the day that elapsed is kind of odd. Or is there a hiden benefit I'm not aware of?
Cheers, Jaf.