Skip to content

Instantly share code, notes, and snippets.

@adamnew123456
Last active February 28, 2020 02:15
Show Gist options
  • Save adamnew123456/b2bd1c4128823bb08545d212fab58628 to your computer and use it in GitHub Desktop.
Save adamnew123456/b2bd1c4128823bb08545d212fab58628 to your computer and use it in GitHub Desktop.
Task Checker
package require Tk
# Checktask format:
#
# %Y-%m-%d,%H:%M:%S,message
if [string equal $tcl_platform(platform) "windows"] {
set checktask_file $env(APPDATA)/checktask.csv
} else {
set checktask_file $env(HOME)/.checktask.csv
}
# Reads a file and executes the block once for each line
# Binds the line to the variable linevar
proc dofile {filename linevar block} {
set handle [open $filename]
set status [catch {
upvar 1 $linevar line
while {[gets $handle line] >= 0} {
uplevel 1 $block
}
} result]
close $handle
if {$status == 1} {
error $result
}
}
# Appends a message to the end of the checktask file
proc add_message {time message} {
global checktask_file
set handle [open $checktask_file a]
puts $handle \
[join \
[list \
[clock format $time -format %Y-%m-%d] \
[clock format $time -format %H:%M:%S] \
$message] \
","]
close $handle
}
# Gets just the message from a checktask file line
proc extract_message line {
set end_date [string first "," $line]
incr end_date
set end_time [string first "," $line $end_date]
incr end_time
return [string range $line $end_time end]
}
# Reads all the messages from the checktask file
proc read_messages {} {
global checktask_file
set messages {}
if [file exists $checktask_file] {
dofile $checktask_file line {
lappend messages [extract_message $line]
}
}
return [lsort -unique $messages]
}
# Does a fuzzy match and returns the results
proc fuzzy_match {pattern candidates} {
if [string equal $pattern ""] {
return $candidates
}
set results {}
set match_pattern "*[regsub -all . $pattern &*]"
foreach candidate $candidates {
if [string match -nocase $match_pattern $candidate] {
lappend results $candidate
}
}
return $results
}
entry .log
listbox .suggest
set old_entries [read_messages]
# Updates .suggest to contain only fuzzy matches from .log
proc update_suggestions {} {
global old_entries
.suggest delete 0 end
set candidates [fuzzy_match [.log get] $old_entries]
.suggest insert end {*}$candidates
}
after 60000 {exit 0}
bind . <Key-Escape> {exit 0}
bind .log <Key-Return> {
add_message [clock seconds] [.log get]
exit 0
}
bind .log <KeyRelease> {
update_suggestions
}
bind .log <Key-Down> {
.suggest activate 0
focus .suggest
}
bind .suggest <Key-BackSpace> {
focus .log
}
bind .suggest <Key-space> {
set selection [.suggest curselection]
if {[llength $selection] > 0} {
.log delete 0 end
.log insert end [.suggest get [lindex $selection 0]]
focus .log
break
}
}
bind .suggest <Key-Return> {
set selection [.suggest curselection]
if {[llength $selection] > 0} {
add_message [clock seconds] [.suggest get [lindex $selection 0]]
exit 0
}
}
update_suggestions
pack .log -fill x
pack .suggest -fill both -expand true
wm geometry . 500x500
wm title . Checktask
raise .
if [string equal $tcl_platform(platform) "windows"] {
set checktask_file $env(APPDATA)/checktask.csv
} else {
set checktask_file $env(HOME)/.checktask.csv
}
# Reads a file and executes the block once for each line
# Binds the line to the variable linevar
proc dofile {filename linevar block} {
set handle [open $filename]
set status [catch {
upvar 1 $linevar line
while {[gets $handle line] >= 0} {
uplevel 1 $block
}
} result]
close $handle
if {$status == 1} {
error $result
}
}
# Extracts the tags from a message
proc get_tags {line} {
return [regexp -all -inline {#[A-Za-z0-9]+} $line]
}
# Formats a time using minutes and hours
proc format_time {minutes} {
set hours [expr {int($minutes / 60)}]
set minutes [expr {$minutes % 60}]
return [format "%d:%02d" $hours $minutes]
}
puts {
<html>
<head>
<title> Checktask Report </title>
<style>
table, td, th {
border: 1px solid black;
border-collapse: collapse;
}
body {
display: flex;
flex-direction: row;
flex-wrap wrap;
}
div {
flex: 1 1 auto;
}
</style>
</head>
}
set previous_date ""
dofile $checktask_file line {
set components [split $line ,]
set date [lindex $components 0]
set time [lindex $components 1]
set message [join [lrange $components 2 end] ,]
if {![string equal $date $previous_date]} {
if {![string equal $previous_date ""]} {
puts {
</table>
</div>
}
}
puts {
<div>
}
puts "<h1> $date </h1>"
puts {
<table>
<tr>
<th>Time</th>
<th>Message</th>
</tr>
}
set previous_date $date
}
foreach tag [get_tags $line] {
set tag [string tolower $tag]
if [info exists tag_times($tag)] {
set tag_times($tag) [expr {$tag_times($tag) + 15}]
} else {
set tag_times($tag) 15
}
}
puts "<tr><td>$time</td><td>$message</td></tr>"
}
if {![string equal $previous_date ""]} {
puts {
</table>
</div>
}
}
puts {
<div>
<h1> Tag Usages </h1>
<table>
<tr>
<th>Tag</th>
<th>Time</th>
</tr>
}
foreach tag [array names tag_times] {
puts "<tr><td>$tag</td><td>[format_time $tag_times($tag)]</td></tr>"
}
puts {
</table>
</div>
</html>
}
file rename -force $checktask_file $checktask_file.bak
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment