Skip to content

Instantly share code, notes, and snippets.

@jacobsebek
Last active August 29, 2022 18:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jacobsebek/92f80930ffeb4bbe8b210f28833e2e8b to your computer and use it in GitHub Desktop.
Save jacobsebek/92f80930ffeb4bbe8b210f28833e2e8b to your computer and use it in GitHub Desktop.
Command line Czech news feed about the war in Ukraine (Deprecated)
#!/usr/bin/env tclsh
# !! DEPRECATED !! THE NEWS ENDPOINT USED BY THIS SCRIPT HAS BEEN CLOSED !!
# Keep up with breaking news about Ukraine on the command line
# This Tcl script reports summaries of the most important events that
# took place since you last checked, scraped right from novinky.cz
# Dependencies: Tcl, curl
# Run with --raw, -r for a more parser-friendly format
# Run with --all, -a to list all the available news
# Run with --timef, -t [fmt] to specify time format (strftime)
# Jakub Sebek, May 2022, Public Domain
puts "As of August 2022, the news endpoint used by ukreport has been closed definitely."
if {[file isdirectory "~/.cache/ukreport"]} {
file delete -force -- "~/.cache/ukreport"
puts "Cache cleared."
}
exit 1
proc arg {a s {alt ""}} {
set argi [lsearch -regexp $::argv "^(--$a$|-\[^-$s\]*$s)"]
if {$alt != ""} {
if {$argi == -1} {
return $alt
} elseif {$argi != [llength $::argv]-1} {
return [lindex $::argv [expr {$argi + 1}]]
} else { error "Argument $a is missing a value" }
} else {
return [expr {$argi != -1}]
}
}
proc html2ansi {t} {
regsub -all -- {<strong>} $t "\033\[1m" t
regsub -all -- {</strong>} $t "\033\[0m" t
regsub -all -- {<em>} $t "\033\[3m" t
regsub -all -- {</em>} $t "\033\[0m"
}
proc paragraphs {ps mw} {
set linew 0
foreach p $ps {
foreach w [split $p] {
incr linew [string length $w]
if {$linew >= $mw} {
set linew [string length $w]
puts ""
}
puts -nonewline "$w "
}
puts -nonewline "\n\n"
}
}
proc plural {n str} {
if {$n > 1} { return "$n ${str}s" } else { return "$n ${str}" }
}
set cachedir "~/.cache/ukreport"
file mkdir $cachedir
if {[file exists $cachedir/data]} {
set cachefile [open $cachedir/data r]
set cache [read -nonewline $cachefile]
close $cachefile
} else {
set cache [dict create "last_checked" [clock format 0 -format "%+"]]
}
set lastchecked [clock scan [dict get $cache "last_checked"] -format "%+"]
dict set cache "last_checked" [clock format [clock seconds] -format "%+"]
set url {https://www.novinky.cz/api/documents/40388819}
if {[catch {exec -- curl --silent --show-error --fail -- $url} html err]} { dict with err {
puts ${-errorinfo}
exit ${-code}
}}
set alltexts [list]
foreach {_ a} [regexp -inline -all -- {"texts"\s*:\s*\[([^]]*)\]} $html] {
foreach {_ t _} [regexp -inline -all -- {"((\\"|[^"])*)"} $a] {
lappend alltexts [subst -nocommands -novariables $t]
}
}
set updates [list]
set dayshift 0
set lasttime [clock seconds]
foreach p $alltexts {
if {[regexp -- {^\s*<strong>\s*(\d+)\D+(\d+)} $p _ h m]} {
if {[info exists curr]} { lappend updates $curr }
set t [clock scan "$h $m" -format "%H %M"]
if {[clock add $t -$dayshift days] > $lasttime} { incr dayshift }
set t [clock add $t -$dayshift days]
regsub -- {^\s*<strong>\s*\d+\D+\d+[^\w<]*(</strong>[^\w<]*)?} $p {} p
set curr [dict create "time" $t "content" [list $p]]
set lasttime $t
} else {
dict lappend curr "content" $p
}
}
if {[info exists curr]} { lappend updates $curr }
if {![arg raw r]} { puts [html2ansi "<em>It is [clock format [clock seconds] -format {%c}].</em>"] }
if {![arg all a]} {
set lastupdatetime [dict get [lindex $updates 0] "time"]
set updates [lmap u $updates {if {[dict get $u "time"] > $lastchecked} {expr {$u}} else break}]
if {![arg raw r]} {
if {[llength $updates] > 0} {
puts [html2ansi "<em>[llength $updates] news since [clock format $lastchecked -format {%a %H:%M}].</em>"]
} else {
puts [html2ansi "<em>No news since [clock format $lastupdatetime -format {%a %H:%M}].</em>"]
}
}
}
foreach u [lreverse $updates] { dict with u {
if {[arg raw r]} {
puts [clock format $time -format [arg timef t {%a %H:%M}]]
puts [join $content "\n"]
puts ""
} else {
set minutediff [expr {([clock seconds] - $time) / 60}]
set timestr [if {$minutediff < (60 * 3)} {
if {$minutediff == 0} {
expr {"Just now"}
} elseif {$minutediff < 40} {
expr {"[plural $minutediff "minute"] ago"}
} else {
expr {"[plural [expr {($minutediff + 30) / 60}] "hour"] ago"}
}
} else {
clock format $time -format [arg timef t {%a %H:%M}]
}]
puts [html2ansi "<em>\[$timestr\]</em>"]
paragraphs [html2ansi $content] [arg width w 60]
}
}}
puts [open $cachedir/data w] $cache
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment