SHARE
TWEET

m00nie-weather.1.6.tcl

random4t4x14 Dec 6th, 2015 25 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.        
  2.  
  3.     #########################################################################################
  4.     # Name                  m00nie::weather
  5.     # Description           Uses wunderground API to grab some weather...
  6.     # Version               1.6 - Corrects wind conditions when set to Metric, or Combined
  7.     #                             Adjusted styling for better readability
  8.     #                       1.5 - Corrects flag detection for chans and adds option for current conditions to display
  9.     #                             both F and C temps in the same output. Might add this to forecast in future version
  10.     #                       1.4 - Warn on more than 5 possible restults (stops LOTS of spam)
  11.     #                       1.3 - Added warning when mutlple/unclear matches
  12.     #                       1.2 - Correct RFC compliant output for some IRCDs (thanks to Alan and Robert for highlighting)
  13.     #                       1.1 - F/C tempreture option
  14.     #                       1.0 - Initial Release
  15.     # Website               https://www.m00nie.com
  16.     # Notes                 Grab your own key @ http://www.wunderground.com/weather/api
  17.     #########################################################################################
  18.     namespace eval m00nie {
  19.        namespace eval weather {
  20.             package require http
  21.             package require tdom
  22.             bind pub - !w m00nie::weather::current_call
  23.             bind pub - !wl m00nie::weather::location
  24.             bind pub - !fc m00nie::weather::forecast_call
  25.             variable version "1.6"
  26.             # Set forc to 0 for tempreture in Celsius, 1 for Farenheit or 2 for both!
  27.             # At the moment forecasts can only use 0 or 1, 2 will default back to Celsius
  28.             variable forc "2"
  29.             setudef flag weather
  30.             variable key "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  31.             ::http::config -useragent "Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0"
  32.      
  33.     proc current_call {nick uhost hand chan text} {
  34.             set location [verify $hand $chan $text]
  35.             if {$location != 0} {
  36.                     current $location $chan
  37.             }
  38.     }
  39.      
  40.     proc forecast_call {nick uhost hand chan text} {
  41.             set location [verify $hand $chan $text]
  42.             if {$location != 0} {
  43.                     forecast $location $chan
  44.             }
  45.     }
  46.      
  47.     # Allow a user to save their location so they can search without defining it each time
  48.     proc location {nick uhost hand chan text} {
  49.             if {![validuser $hand]} {
  50.                     set mask [maskhost [getchanhost $nick $chan]]
  51.                     adduser $nick $mask
  52.                     chattr $nick -hp
  53.                     putlog "m00nie::weather::location added user $nick with host $uhost"
  54.             }
  55.             setuser $nick XTRA m00nie:weather.location $text
  56.             puthelp "PRIVMSG $chan :Default weather location for $nick set to $text."
  57.             putlog "m00nie::weather::location $nick set their default location to $text."
  58.     }
  59.      
  60.     # Search for current weather
  61.     proc verify {hand chan text} {
  62.             if {(![channel get $chan weather])} {
  63.                     putlog "m00nie::weather::search Trigger seen but channel doesnt have +weather set!"
  64.                     return 0
  65.             }
  66.             if {$text != ""} {
  67.                     set location $text
  68.             } else {
  69.                     set location [getuser $hand XTRA m00nie:weather.location]
  70.             }
  71.      
  72.             if {[string length $location] == 0 || [regexp {[^0-9a-zA-Z,. ]} $location match] == 1} {
  73.                     putlog "m00nie::weather::search location b0rked or no location said/default? Argument: $location"
  74.                     puthelp "PRIVMSG $chan :Did you ask to search somewhere? Or use !wl to set a default location"
  75.                     return
  76.             } else {
  77.                     return $location
  78.             }
  79.     }
  80.      
  81.     proc current {location chan} {
  82.             putlog "m00nie::weather::current is running against location: $location"
  83.             set rawpage [getinfo $location conditions]
  84.             set doc [dom parse $rawpage]
  85.             set root [$doc documentElement]
  86.       # Check for no results!
  87.             set notfound [$root selectNodes /response/error/description/text()]
  88.             if {[llength $notfound] > 0 } {
  89.                     set errormsg [$notfound nodeValue]
  90.                     putlog "m00nie::weather::current ran but could not find any info for $location or an API error occured: $errormsg"
  91.                     puthelp "PRIVMSG $chan :$errormsg"
  92.                     return
  93.             }
  94.       # Check for multiple results
  95.       set multi [$root selectNodes /response/results/result]
  96.       if {[llength $multi]} {
  97.             putlog "m00nie::weather::current multiple results found"
  98.             # Lets check we dont have LOADS of results to spam
  99.             set i 0
  100.             foreach place [$root selectNodes "/response/results/result"] {
  101.                     incr i
  102.                     if {$i >= 5} {
  103.                             puthelp "PRIVMSG $chan :Your search returned more than 5 results. Please try a more specific search."
  104.                             return
  105.                     }
  106.             }
  107.             puthelp "PRIVMSG $chan :Multiple results found pick one and run again"
  108.             foreach place [$root selectNodes "/response/results/result"] {
  109.                     set name [lindex [$place selectNodes "name"] 0]
  110.                     set country [lindex [$place selectNodes "country"] 0]
  111.                     if {[$country text] eq "US"} {
  112.                             set state [lindex [$place selectNodes "state"] 0]
  113.                             puthelp "PRIVMSG $chan : - [$name text] [$state text] [$country text]"
  114.                     } else {
  115.                             puthelp "PRIVMSG $chan : - [$name text] [$country text]"
  116.                     }
  117.             }
  118.             return
  119.       }
  120.             set city [[$root selectNodes /response/current_observation/display_location/full/text()] nodeValue]
  121.             if { $m00nie::weather::forc == 0 } {
  122.                     foreach var { observation_time weather temp_c wind_dir wind_kph wind_gust_kph feelslike_c precip_today_string } {
  123.                             set $var [[$root selectNodes /response/current_observation/$var/text()] nodeValue]
  124.                     }
  125.                     set spam "Current weather for \002$city\002 ($observation_time) Current conditions: $weather, Temperature: $temp_c C, Wind: From $wind_dir at $wind_kph KPH Gusting to $wind_gust_kph KPH, Rain today: $precip_today_string, Feels like: $feelslike_c C"
  126.             } elseif { $m00nie::weather::forc == 1} {
  127.                     foreach var { observation_time weather temp_f wind_string feelslike_f precip_today_string } {
  128.                             set $var [[$root selectNodes /response/current_observation/$var/text()] nodeValue]
  129.                     }
  130.                     set spam "Current weather for \002$city\002 ($observation_time) Current conditions: $weather, Temperature: $temp_f F, Wind: $wind_string, Rain today: $precip_today_string, Feels like: $feelslike_f F"
  131.             } elseif { $m00nie::weather::forc == 2} {
  132.                     foreach var { observation_time weather temp_f temp_c wind_dir wind_mph wind_kph wind_gust_mph wind_gust_kph feelslike_string precip_today_string } {
  133.                             set $var [[$root selectNodes /response/current_observation/$var/text()] nodeValue]
  134.                     }
  135.                     set spam "Current weather for \002$city\002 ($observation_time) \002Current conditions:\002 $weather, \002Temperature:\002 $temp_f F ($temp_c C), \002Wind:\002 From the $wind_dir at $wind_mph MPH ($wind_kph KPH) Gusting to $wind_gust_mph MPH ($wind_gust_kph KPH), \002Rain today:\002 $precip_today_string, \002Feels like:\002 $feelslike_string"
  136.             } else {
  137.                     putlog "m00nie::weather::current $m00nie::weather::forc is not a valid value for forc..."
  138.                     return
  139.             }
  140.             puthelp "PRIVMSG $chan :$spam"
  141.     }
  142.      
  143.     proc forecast {location chan} {
  144.             putlog "m00nie::weather::forecast is running against location: $location"
  145.             set rawpage [getinfo $location forecast]
  146.             set doc [dom parse $rawpage]
  147.             set root [$doc documentElement]
  148.             set dayList [$root selectNodes /response/forecast/txt_forecast/forecastdays/forecastday/title/text()]
  149.             if { ($m00nie::weather::forc == 0) || ($m00nie::weather::forc == 2) } {
  150.                     set foreList [$root selectNodes /response/forecast/txt_forecast/forecastdays/forecastday/fcttext_metric/text()]
  151.             } elseif { $m00nie::weather::forc == 1 } {
  152.                     set foreList [$root selectNodes /response/forecast/txt_forecast/forecastdays/forecastday/fcttext/text()]
  153.             } else {
  154.                     putlog "m00nie::weather::forecast $m00nie::weather::forc is not a valid value for forc..."
  155.                     return
  156.             }
  157.      
  158.             puthelp "PRIVMSG $chan :Three day forecast for \002$location\002"
  159.             set x 0
  160.             while { $x < 6 } {
  161.                     set dayname [[lindex $dayList $x] nodeValue]
  162.                     set fore [[lindex $foreList $x] nodeValue]
  163.                     puthelp "PRIVMSG $chan :\002$dayname:\002 $fore"
  164.                     incr x
  165.             }
  166.     }
  167.      
  168.     proc getinfo {location type} {
  169.             regsub -all -- { } $location {%20} location
  170.             set url "http://api.wunderground.com/api/$m00nie::weather::key/$type/q/$location.xml"
  171.             putlog "m00nie::weather::getinfo grabbing data from $url"
  172.             for { set i 1 } { $i <= 5 } { incr i } {
  173.                     set xmlpage [::http::data [::http::geturl "$url" -timeout 10000]]
  174.                     if {[string length xmlpage] > 0} { break }
  175.             }
  176.             putlog "m00nie::weather::getinfo xmlpage length is: [string length $xmlpage]"
  177.             if { [string length $xmlpage] == 0 }  {
  178.                     error "wunderground returned ZERO no data :( or we couldnt connect properly"
  179.             }
  180.             return $xmlpage
  181.     }
  182.     }
  183.     }
  184.     putlog "m00nie::weather $m00nie::weather::version loaded"
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top