Advertisement
random4t4x14

m00nie-weather.1.6.tcl

Dec 6th, 2015
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
TCL 10.27 KB | None | 0 0
  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"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement