weatherbot
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
weatherbot [2014/08/23 20:42] – sekula | weatherbot [2014/08/31 03:23] (current) – [Talking to WeatherBot] sekula | ||
---|---|---|---|
Line 22: | Line 22: | ||
* PyPump [[https:// | * PyPump [[https:// | ||
* LYNX (for converting HTML to plain text - some pump clients don't send messages in HTML, some do... this saved me having to write my own converter) | * LYNX (for converting HTML to plain text - some pump clients don't send messages in HTML, some do... this saved me having to write my own converter) | ||
+ | |||
+ | ===== Bug Reporting and Feature Requests ===== | ||
+ | |||
+ | * [[community: | ||
Line 32: | Line 36: | ||
# Distributed under an Apache 2.0 license | # Distributed under an Apache 2.0 license | ||
# For more information ,see | # For more information ,see | ||
- | # http:// | ||
- | # | ||
import re | import re | ||
Line 41: | Line 43: | ||
import sys | import sys | ||
import time | import time | ||
- | import subprocess | + | import subprocess |
import os | import os | ||
+ | import unicodedata | ||
+ | |||
+ | from datetime import datetime | ||
from pypump import PyPump, Client | from pypump import PyPump, Client | ||
Line 53: | Line 58: | ||
# city,region search pattern | # city,region search pattern | ||
- | citypattern = re.compile(' | + | citypattern = re.compile(' |
+ | |||
+ | tripletpattern = re.compile(' | ||
+ | doubletpattern = re.compile(' | ||
+ | |||
+ | for_tripletpattern = re.compile(' | ||
+ | in_tripletpattern = re.compile(' | ||
+ | |||
+ | for_doubletpattern = re.compile(' | ||
+ | in_doubletpattern = re.compile(' | ||
# Place the credentials below for the pump.io account | # Place the credentials below for the pump.io account | ||
# These can be obtained by using: http:// | # These can be obtained by using: http:// | ||
- | client_credentials = [] | + | client_credentials = [' |
- | client_tokens = [] | + | client_tokens = [' |
# Webfinger for your account | # Webfinger for your account | ||
- | webfinger = "me@example.com" | + | webfinger = "name@example.com" |
# Important: define a log file that contains a list of activities to which | # Important: define a log file that contains a list of activities to which | ||
Line 83: | Line 98: | ||
htmlfile.close() | htmlfile.close() | ||
+ | | ||
try: | try: | ||
ascii_text = subprocess.check_output([" | ascii_text = subprocess.check_output([" | ||
Line 102: | Line 117: | ||
| | ||
return True | return True | ||
+ | |||
+ | def KelvinToCelsius(temp_kelvin): | ||
+ | return temp_kelvin - 273.15 | ||
+ | |||
+ | def CelsiusToFarenheit(temp_celsius): | ||
+ | return temp_celsius*1.8 + 32.0 | ||
+ | |||
+ | def FarenheitToCelsius(temp_farenheit): | ||
+ | return (temp_farenheit - 32.0)/1.8 | ||
+ | |||
+ | def KPHToMPH(speed_kph): | ||
+ | return speed_kph/ | ||
+ | |||
+ | def current_conditions(weather_data): | ||
+ | humidity = weather_data[' | ||
+ | | ||
+ | temp_kelvin = weather_data[' | ||
+ | temp_celsius = KelvinToCelsius(temp_kelvin) | ||
+ | temp_farenheit = CelsiusToFarenheit(temp_celsius) | ||
+ | | ||
+ | wind_speed_kmh = weather_data[' | ||
+ | wind_speed_mph = KPHToMPH(wind_speed_kmh) | ||
+ | | ||
+ | heat_index_farenheit = -42.379 + 2.04901523*temp_farenheit + 10.14333127*humidity - .22475541*temp_farenheit*humidity - .00683783*temp_farenheit*temp_farenheit - .05481717*humidity*humidity + .00122874*temp_farenheit*temp_farenheit*humidity + .00085282*temp_farenheit*humidity*humidity - .00000199*temp_farenheit*temp_farenheit*humidity*humidity | ||
+ | heat_index_celsius = FarenheitToCelsius(heat_index_farenheit) | ||
+ | | ||
+ | response = "" | ||
+ | | ||
+ | response += "< | ||
+ | response += "< | ||
+ | response += "< | ||
+ | response += "< | ||
+ | response += "< | ||
+ | response += "< | ||
+ | response += "< | ||
+ | response += "< | ||
+ | response += "</ | ||
+ | |||
+ | |||
+ | return response | ||
+ | |||
+ | def forecast(weather_data): | ||
+ | list_of_data = weather_data[' | ||
+ | response = "" | ||
+ | |||
+ | response += "< | ||
+ | response += "< | ||
+ | response += "< | ||
+ | for moment in list_of_data: | ||
+ | dt = datetime.fromtimestamp(moment[" | ||
+ | timestamp = dt.strftime(' | ||
+ | temp_celsius = KelvinToCelsius(moment[" | ||
+ | temp_farenheit = CelsiusToFarenheit(temp_celsius) | ||
+ | humidity = moment[" | ||
+ | description = "%s - %s" % (moment[" | ||
+ | icon = " | ||
+ | response += "< | ||
+ | response += "</ | ||
+ | |||
+ | return response | ||
Line 163: | Line 238: | ||
| | ||
# handle this content | # handle this content | ||
+ | | ||
text_content = HTMLToText(content) | text_content = HTMLToText(content) | ||
+ | text_content = text_content.lower() | ||
- | | + | |
- | | + | if text_content.find(' |
- | | + | text_content.find(' |
+ | text_content.find(' | ||
+ | query = 0 | ||
+ | | ||
+ | query = 1 | ||
+ | pass | ||
+ | else: | ||
+ | # default to current conditions | ||
+ | query = 0 | ||
- | print "%s sent a weather request, which I will now process..." | ||
+ | search_result = in_tripletpattern.match(text_content) | ||
+ | if not search_result: | ||
+ | print " ... Search failed for in + triplet" | ||
+ | search_result = for_tripletpattern.match(text_content) | ||
+ | if not search_result: | ||
+ | print " ... Search failed for for + triplet" | ||
+ | search_result = tripletpattern.match(text_content) | ||
+ | | ||
+ | if not search_result: | ||
+ | print " ... Search failed for pure triplet" | ||
+ | search_result = in_doubletpattern.match(text_content) | ||
+ | if not search_result: | ||
+ | print " ... Search failed for in + doublet" | ||
+ | search_result = for_doubletpattern.match(text_content) | ||
+ | if not search_result: | ||
+ | print " ... Search failed for for + doublet" | ||
+ | search_result = doubletpattern.match(text_content) | ||
+ | if not search_result: | ||
+ | print " ... Search failed for pure doublet" | ||
+ | pass | ||
+ | |||
+ | if query >= 0 and search_result: | ||
cityrequest = search_result.group(1) | cityrequest = search_result.group(1) | ||
+ | |||
+ | query_type = " | ||
+ | if query == 1: | ||
+ | query_type = " | ||
+ | pass | ||
+ | | ||
+ | author = "" | ||
+ | if type(activity.obj.author) == Person: | ||
+ | author = activity.obj.author.display_name | ||
+ | elif type(activity.obj.author) == unicode: | ||
+ | author = unicodedata.normalize(' | ||
+ | else: | ||
+ | author = activity.obj.author | ||
+ | pass | ||
+ | | ||
+ | print "%s sent a weather request for the %s for %s, which I will now process..." | ||
| | ||
# clean up poor formatting in content | # clean up poor formatting in content | ||
Line 185: | Line 307: | ||
| | ||
c = pycurl.Curl() | c = pycurl.Curl() | ||
- | c.setopt(c.URL, | + | |
+ | # current conditions | ||
+ | | ||
+ | elif query == 1: | ||
+ | # forecast | ||
+ | c.setopt(c.URL, | ||
+ | pass | ||
c.setopt(c.WRITEFUNCTION, | c.setopt(c.WRITEFUNCTION, | ||
Line 231: | Line 359: | ||
try: | try: | ||
- | | + | |
+ | response = current_conditions(weather_data) | ||
+ | elif query == 1: | ||
+ | response = forecast(weather_data) | ||
+ | |||
+ | pass | ||
- | temp_kelvin = weather_data[' | ||
- | temp_celsius = temp_kelvin - 273.15 | ||
- | temp_farenheit = temp_celsius*1.8 + 32.0 | ||
- | | ||
- | wind_speed_kmh = weather_data[' | ||
- | wind_speed_mph = wind_speed_kmh/ | ||
- | | ||
- | response = "" | ||
- | | ||
- | response += "< | ||
- | response += "< | ||
- | response += "< | ||
- | response += "< | ||
- | response += "< | ||
- | response += "< | ||
- | response += "< | ||
- | response += "</ | ||
- | | ||
my_reply = pump.Comment(response) | my_reply = pump.Comment(response) | ||
my_reply.cc = cc | my_reply.cc = cc | ||
+ | my_reply.cc.append( pump.Public ) | ||
+ | | ||
try: | try: | ||
activity.obj.comment(my_reply) | activity.obj.comment(my_reply) | ||
Line 260: | Line 377: | ||
print " | print " | ||
continue | continue | ||
+ | |||
except KeyError: | except KeyError: | ||
response = "< | response = "< | ||
Line 269: | Line 387: | ||
print " | print " | ||
continue | continue | ||
- | | ||
pass | pass | ||
pass | pass | ||
Line 281: | Line 398: | ||
process_log.close() | process_log.close() | ||
| | ||
+ | |||
</ | </ | ||
+ | ===== Talking to WeatherBot ===== | ||
+ | |||
+ | WeatherBot (e.g. [[https:// | ||
+ | |||
+ | < | ||
+ | New York,NY,US | ||
+ | or | ||
+ | Stockholm, | ||
+ | </ | ||
+ | |||
+ | results in the original behavior - you get the current conditions. | ||
+ | |||
+ | Sending any of these: | ||
+ | |||
+ | < | ||
+ | Current conditions in Jefferson City,MO,US | ||
+ | Currently Uppsala,SE | ||
+ | Current in London,UK | ||
+ | Conditions for Moscow,RU | ||
+ | etc. | ||
+ | </ | ||
+ | |||
+ | also results in the current conditions. | ||
+ | |||
+ | But sending any of these: | ||
+ | |||
+ | < | ||
+ | Forecast for London,UK | ||
+ | Forecast in Dallas, | ||
+ | </ | ||
+ | |||
+ | will return a table of forecast data for the city in question, going out 3 days. This is just a first attempt to do simple request processing based on language, and, yes, it's only in English for now. But now you can at least get a forecast! | ||
+ | |||
+ | {{ : | ||
weatherbot.1408826551.txt.gz · Last modified: 2014/08/23 20:42 by sekula