Last active
August 29, 2022 18:50
-
-
Save jacobsebek/92f80930ffeb4bbe8b210f28833e2e8b to your computer and use it in GitHub Desktop.
Command line Czech news feed about the war in Ukraine (Deprecated)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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