diff --git a/.bin/wx b/.bin/wx index 234aa03..cab095f 100755 --- a/.bin/wx +++ b/.bin/wx @@ -1,10 +1,10 @@ #!/bin/bash ## wx: a METAR parser written in Bash -# (c) 2021 Allyson Bowles +# (c) 2023 Al Bowles ## Usage: -# wx [[ temp [ f|F | c|C | k|K ]] | humidity | wind | altimeter | visibility | rvr | condition | phenomena | metar | remarks | refresh ] +# wx [[ temp [ f|F | c|C | k|K ]] | humidity | wind | altimeter | visibility | rvr | condition | phenomena | metar | remarks | feelslike ] ## References: # http://www.met.tamu.edu/class/metar/quick-metar.html @@ -21,60 +21,19 @@ STATION=KRYV #STATION=KHNB DATA_URI="data/observations/metar/stations/$STATION.TXT" DATA_URL="https://tgftp.nws.noaa.gov/$DATA_URI" -CACHE="$HOME/.cache/wx/metar" -TIMEOUT=10 -PLATFORM=$(uname) - -[[ ! -d "$(dirname $CACHE)" ]] && mkdir -p "$(dirname $CACHE)" -[[ ! -f "$CACHE" ]] && touch $CACHE - -# TODO uuoc -metar=`cat $CACHE` - -_check_last_modified() { - last_modified=$(curl -I -s $DATA_URL | grep Last\-Modified | awk -F': ' '{ print $2 }') - [[ "$last_modified" == "" ]] && return 1 - - case $PLATFORM in - Linux) - src=$(date --date="$last_modified" +'%s') - # FIXME are we handling the case where $CACHE is empty? - cache=$(date -r $CACHE +'%s') - ;; - Darwin) - src=$(date -j -f "%a, %e %b %Y %T %Z" "$last_modified" "+%s" 2&> /dev/null) - cache=$(stat -f "%m" -q $CACHE) - ;; - esac - [[ "$src" > "$cache" ]] && return 1 || return 0 -} - -_check_md5sum() { - case $PLATFORM in - Linux) - md5sum $1 | awk '{print $1}' - ;; - Darwin) - md5 $1 | awk '{print $4}' - ;; - esac -} -refresh() { - data=$(curl --connect-timeout $TIMEOUT --create-dirs -s $DATA_URL | tr "\n" " ") - [[ "$data" != "" && $(_check_md5sum <<< $data) != $(_check_md5sum $CACHE) ]] && echo $data > $CACHE -} +metar=$(curl --connect-timeout 2 -s $DATA_URL) metar() { - echo $metar + echo "$metar" } remarks() { - awk -F 'RMK' '{print $2}' $CACHE + awk -F 'RMK' '{print $2}' <<< $metar } rvr() { - awk '$0 ~ /\(R\[0-9\]\+\/\[0-9\]\+V?\(M\|P\)\[0-9\]\+FT\)/' $CACHE + awk '$0 ~ /\(R\[0-9\]\+\/\[0-9\]\+V?\(M\|P\)\[0-9\]\+FT\)/' <<< $metar } phenomena() { @@ -122,7 +81,6 @@ phenomena() { case ${phen[0]} in *SQ*) other="squall" ;; - *FC*) other="funnel cloud" ;; *SS*) other="sandstorm" ;; *FC*) other="tornado" ;; *DS*) other="dust storm" ;; @@ -132,14 +90,14 @@ phenomena() { if [[ -n "$qual" || -n "$desc" || -n "$precip" || -n "$obsc" || -n "$other" ]] then printf " %s" $qual $desc $precip $obsc $other - exit 0 + return 0 else - exit 1 + return 1 fi } condition() { - cond=$(grep -o '\(\(CLR\|SKC\|FEW\|SCT\|BKN\|OVC\|VV\)\([0-9]\+\)\?\(\|TCU\|CB\)\?\)\+' $CACHE) + cond=$(grep -o '\(\(CLR\|SKC\|FEW\|SCT\|BKN\|OVC\|VV\)\([0-9]\+\)\?\(\|TCU\|CB\)\?\)\+' <<< $metar) case ${cond[${#cond[@]} - 1]} in CLR*|SKC*) condition="clear" ;; FEW*) condition="partly cloudy" ;; @@ -150,15 +108,15 @@ condition() { **) condition="" ;; esac - printf " %s" $condition + printf " $condition" } visibility() { - grep -o '\([0-9]\+SM\)' $CACHE + grep -o '\([0-9]\+SM\)' <<< $metar } altimeter() { - grep -o 'A[0-9]\{4\}' $CACHE + grep -o 'A[0-9]\{4\}' <<< $metar } _wind_speed_conversion() { @@ -172,11 +130,11 @@ _wind_speed_conversion() { } _wind_speed(){ - read wind_speed gusting <<< $(grep -o '\([0-9]\{2\}G\)\?[0-9]\{2\}KT' $CACHE | awk -F 'G' '{ printf "%d %d", $1, $2 }') + read wind_speed gusting <<< $(grep -o '\([0-9]\{2\}G\)\?[0-9]\{2\}KT' <<< $metar | awk -F 'G' '{ printf "%d %d", $1, $2 }') } _wind_direction() { - wd=$(printf "%.3s" $(grep -o '\(VRB\|[0-9]\{3\}\)\([0-9]\{2\}G\)\?[0-9]\{2\}KT' $CACHE)) + wd=$(printf "%.3s" $(grep -o '\(VRB\|[0-9]\{3\}\)\([0-9]\{2\}G\)\?[0-9]\{2\}KT' <<< $metar)) if [[ "$wd" == "VRB" ]] then @@ -226,7 +184,7 @@ wind() { } _temperature_dewpoint() { - temperature_dewpoint=$(grep -o '\s\(M\)\?\([0-9]\{2\}\/\(M\)\?[0-9]\{2\}\)\s' $CACHE) + temperature_dewpoint=$(grep -o '\s\(M\)\?\([0-9]\{2\}\/\(M\)\?[0-9]\{2\}\)\s' <<< $metar) read temp dp <<< $(awk -F '/' '{ printf "%d %d", $1, $2 }' <<< $(echo $temperature_dewpoint | sed 's/M/-/g')) } @@ -254,16 +212,24 @@ temp() { } wind_chill() { + # Wind chill is only a useful metric at or below 10C /and/ + # when wind speeds exceed 4.8 kph. _temperature_dewpoint + [[ $(bc <<< "$temp <= 10") == 1 ]] || return 1 _wind_speed + x=$(_wind_speed_conversion "$wind_speed" kph) + [[ $(bc <<< "$x > 4.8") == 1 ]] || return 1 + # bc does not support floating point exponents - y=$(awk -v "wc=$wind_speed" 'BEGIN {print wc**0.16}') + y=$(awk -v "wc=$x" 'BEGIN {print wc**0.16}') wind_chill=$(bc <<< "13.12 + (0.6215 * $temp) - (11.37 * $y) + (0.3965 * $temp * $y)") _temperature_conversion $wind_chill $1 } heat_index() { + # heat index is only a useful metric at or above 26C _temperature_dewpoint + [[ $(bc <<< "$temp > 26") == 1 ]] || return 1 _relative_humidity c1="-8.78469475556" c2="1.61139411" @@ -278,4 +244,15 @@ heat_index() { _temperature_conversion $heat_index $1 } -$@ && _check_last_modified || refresh +feelslike() { + wind_chill $1 || heat_index $1 || return 1 +} + +summary() { + temp f + # TODO don't print if feelslike returns 1 + printf " (%s)" "$(feelslike f)" + phenomena || condition +} + +$@ diff --git a/.vimrc b/.vimrc index 3709967..69d1484 100755 --- a/.vimrc +++ b/.vimrc @@ -93,20 +93,26 @@ let g:ale_fix_on_save = 1 let g:ale_echo_msg_error_str = 'E' let g:ale_echo_msg_warning_str = 'W' let g:ale_echo_msg_format = '[%linter%] %s [%severity%]' +let g:ale_list_window_size = 5 let g:ale_fixers = { \ '*': ['remove_trailing_lines', 'trim_whitespace'], \ 'javascript': ['prettier'], +\ 'json': ['jq'], \ 'terraform': ['terraform'], -\ 'yaml': ['yamlfix'] +\ 'yaml': ['yamlfix'], \} let g:ale_linters = { -\ 'go': ['gofmt', 'golint', 'go vet', 'gopls'], +\ 'go': ['gofmt', 'golint', 'go vet', 'gopls', 'golangci-lint'], \ 'ansible': ['ansible-lint'], \ 'perl': ['perlcritic'], \ 'terraform': ['terraform'], +\ 'ruby': ['rubocop'], +\ 'javascript': ['eslint'], \} " TODO markdown linter + +"let b:ale_ruby_rubocop_executable = './vendor/bundle/ruby/2.6.0/bin/rubocop' " TODO j2-lint integration " TODO new panes bottom / right " TODO middle click = set paste/insert/set nopaste