view weather.tcl @ 153:8b888a9f07df

New script, weather.tcl. Needs backend stuff to be implemented.
author Matti Hamalainen <ccr@tnsp.org>
date Sun, 01 Jun 2014 17:37:02 +0300
parents
children a1f4c163e48c
line wrap: on
line source

##########################################################################
#
# Weather v0.1 by Matti 'ccr' Hamalainen <ccr@tnsp.org>
# (C) Copyright 2014 Tecnic Software productions (TNSP)
#
# Requires get_weather.tcl to be run as a cronjob, for example
# 15 * * * *     /absolute/path/to/get_weather.tcl
#
# This script is freely distributable under GNU GPL (version 2) license.
#
##########################################################################

set weather_default_locations "raahe"
set weather_datafile "/home/niinuska/bot/data.weather"
set weather_check_period 5

set weather_logmsg 1
set weather_preferredmsg "PRIVMSG"


set weather_msg_usage_1 "Käyttö: !sää2 \[paikka\]"
set weather_msg_usage_2 "Käyttö: !sää2 aseta <paikka>\[;<paikka2>\]"

set weather_msg_user_not_known "Tuntematon käyttäjä."
set weather_msg_no_results "Ei mittaustietoja."
set weather_msg_no_data_for_location "Paikkakunnan tietoja ei saatu."


##########################################################################
# No need to look below this line
##########################################################################
set weather_name "Weather"
set weather_version "0.1"

### Binding initializations
bind pub - !sää2 weather_cmd_pub
bind pub - !saa2 weather_cmd_pub
bind msg - !sää2 weather_cmd_msg
bind msg - !saa2 weather_cmd_msg


### Initialization messages
package require textutil::split
set weather_message "$weather_name v$weather_version by ccr/TNSP"
putlog "$weather_message"


#-------------------------------------------------------------------------
proc weather_log {arg} {
  global weather_logmsg weather_name
  if {$weather_logmsg != 0} {
    putlog "$weather_name: $arg"
  }
}


proc weather_msg {apublic anick achan amsg} {
  global weather_preferredmsg
  if {$apublic == 1} {
    putserv "$weather_preferredmsg $achan :$amsg"
  } else {
    putserv "$weather_preferredmsg $anick :$amsg" 
  }
}


proc weather_ctime {utime} {
  return [clock format $utime -format "%H:%M"]
}


#-------------------------------------------------------------------------
proc weather_update {} {
  global weather_datafile weather_data

  # Create dict
  array set weather_data {}
  set wtemp_min_val 500000
  set wtemp_max_val -500000
  set wtemp_min_key ""
  set wtemp_max_key ""
  
  # Read datafile
  if {![catch {set ufile [open $weather_datafile r 0600]} uerrmsg]} {
    while {![eof $ufile]} {
      gets $ufile uline
      set udata [split $uline "|"]
      if {[llength $udata] > 0} {
        set utemp [lindex $udata 2]
        set ukey [lindex $udata 0]

        set weather_data($ukey) $udata

        if {$utemp < $wtemp_min_val} {
          set wtemp_min_key $ukey
        }
        if {$utemp > $wtemp_max_val} {
          set wtemp_max_key $ukey
        }
      }
    }
    close $ufile
    
    # Store min/max 
    set weather_data(w_min) $weather_data($wtemp_min_key)
    set weather_data(w_max) $weather_data($wtemp_max_key)
  } else {
    weather_log "Could not open data file: $uerrmsg"
  }
}


#-------------------------------------------------------------------------
proc weather_exec {} {
  global weather_check_period weather_running 

  # Perform update
  weather_update

  # Schedule next update
  set weather_running [clock seconds]
  timer $weather_check_period weather_update
}


#-------------------------------------------------------------------------
if {![info exists weather_data]} {
  array set weather_data {}
}

if {[info exists weather_running]} {
  set weather_last [expr [clock seconds] - $weather_running]
} else {
  set weather_last -1
}

if {$weather_last < 0 || $weather_last > [expr $weather_check_period * 60]} {
  weather_log "Starting weather update."
  weather_exec
} else {
  weather_update
}

#-------------------------------------------------------------------------
proc weather_get_data {ukey udata} {
  return "\002[lindex $udata 0]\002, mitattu klo [weather_ctime [lindex $udata 1]]: \002[lindex $udata 2]°C\002."
}


proc weather_get_key {ukey} {
  global weather_data
  return [weather_get_data $ukey $weather_data($ukey)]
}


#-------------------------------------------------------------------------
proc weather_cmd {unick uhand uchan uargs upublic} {
  global weather_default_locations weather_data
  global weather_msg_usage_1 weather_msg_usage_2 weather_msg_user_not_known
  global weather_msg_no_results weather_msg_no_data_for_location

  # Check and handle arguments
  set rarglist [::textutil::split::splitx $uargs {\s+}]
  set rarg [lindex $rarglist 0]

  if {$rarg == "?" || $rarg == "help" || $rarg == "apua"} {
    weather_msg $upublic $unick $uchan $weather_msg_usage_1
    weather_msg $upublic $unick $uchan $weather_msg_usage_2
    return 0
  }
  
  # Setting the location
  if {$rarg == "aseta" || $rarg == "set"} {
    if {$uhand == "" || $uhand == "{}"} {
      weather_msg $upublic $unick $uchan $weather_msg_user_not_known
      return 0
    }

    # Split the list of desired locations
    set qlist [::textutil::split::splitx [join [lrange $rarglist 1 end] " "] {\s*\;\s*}]
    set nlist [lsearch -all -inline -not -exact $qlist ""]

    if {[llength $nlist] > 0} {
      set lista [join $nlist ";"]
      weather_msg $upublic $unick $uchan "Vakiopaikoiksi asetettu: \002${lista}\002."
      setuser $uhand XTRA "weather_locations" $lista
    } else {
      weather_msg $upublic $unick $uchan $weather_msg_usage_2
    }
    return 0
  }

  # Get args or default location(s)
  set rargs [join $rarglist " "]
  if {$rargs == "" && ($uhand == "" || $uhand == "{}")} {
    set rargs [getuser $uhand XTRA "weather_locations"]
  }
  if {$rargs == "" || $rargs == "{}"} {
    set rargs $weather_default_locations
  }

  # Handle argument list
  set rarglist [::textutil::split::splitx $rargs "\s*\;\s*"]
  foreach rarg $rarglist {
    if {$rarg == "min"} {
      # Min temp
      set umin [weather_get_key "w_min"]
      weather_msg $upublic $unick $uchan "Min: $umin"
    } elseif {$rarg == "max"} {
      # Max temp
      set umax [weather_get_key "w_max"]
      weather_msg $upublic $unick $uchan "Max: $umax"
    } elseif {$rarg == "minmax" || $rarg == "min max" || $rarg == "maxmin" || $rarg == "max min"} {
      # Min & Max temps
      set umin [weather_get_key "w_min"]
      set umax [weather_get_key "w_max"]
      weather_msg $upublic $unick $uchan "Min: $umin | Max: $umax"
    } else {
      # Location match
      set ufound 0
      foreach {ukey uvalue} [array get weather_data] {
        if {![string match "w_*" $ukey] && [string match -nocase "*${rarg}*" $ukey]} {
          if {[llength $uvalue] > 0} {
            weather_msg $upublic $unick $uchan [weather_get_data $ukey $uvalue]
          } else {
            weather_msg $upublic $unick $uchan "\002${ukey}\002: $weather_msg_no_results"
          }
          incr ufound
        }
      }
      
      if {$ufound == 0} {
        weather_msg $upublic $unick $uchan "\002${rarg}\002: $weather_msg_no_data_for_location"
      }
    }
  }
  return 0
}



#-------------------------------------------------------------------------
proc weather_cmd_pub {unick uhost uhand uchan uargs} {
  return [weather_cmd $unick $uhand $uchan $uargs 1]
}

#-------------------------------------------------------------------------
proc weather_cmd_msg {unick uhost uhand uargs} {
  return [weather_cmd $unick $uhand "PRIV" $uargs 0]
}

# end of script