Skip to content
Permalink
Browse files
add today's forecast handling
  • Loading branch information
soperd committed Nov 2, 2018
1 parent c62c82e commit 766c5170eb5b1bba61d668e7072307b71f972bf2
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 28 deletions.
@@ -1,6 +1,7 @@
from concurrent.futures import ThreadPoolExecutor, wait as future_wait
from datetime import datetime, timedelta
from collections import OrderedDict
from functools import partial

import requests

@@ -16,7 +17,7 @@ class WeatherService(Service):
self._api_endpoint = "https://api.darksky.net/forecast/{}".format(
self.config.token)

def get_weather_at(self, long: float, lat: float, time=None) -> dict:
def get_weather_at(self, long, lat, time=None) -> dict:
epoch = 0 # epoch is the unix timestamp
if time is not None:
if type(time) is datetime:
@@ -26,6 +27,11 @@ class WeatherService(Service):
else:
raise TypeError(
"time should be datetime.datetime, int, or float")

if type(long) not in (float, int):
raise TypeError("long must be numeric")
elif type(lat) not in (float, int):
raise TypeError("lat must be numeric")

# if we have a valid epoch, pass it to the DarkSky API
if epoch > 0:
@@ -38,29 +44,33 @@ class WeatherService(Service):

return res.json()

def get_weekly_summary(self, long: float, lat: float, time=datetime.now()) -> OrderedDict:
days = OrderedDict()
def get_hourly_summary(self, long, lat, time=None) -> str:
return self.get_weather_at(long, lat, time)["hourly"]["summary"]

def get_weekly_summary(self, long, lat, time=datetime.now()) -> str:
day_pairs = []
# nested function that gets the daily summary for a given time
def _get_day(t):
w_info = self.get_weather_at(long, lat, t)
print(t.timestamp())
return (t, w_info["hourly"]["summary"])

# nested function that acts as a callback to _get_day future
def _update_days(f):
# add result to day_pairs
day_pairs.append(f.result())
def _update_days(i, f):
print(f, i)
# insert the result to day_pairs at i
day_pairs.insert(i, f.result())

futures = []
with ThreadPoolExecutor(max_workers=7) as executor:
for i in range(0, 7):
# get the days summary in a separate thread
f = executor.submit(_get_day, time + timedelta(i))
f.add_done_callback(_update_days)
# pass the index to the callback so it can be ordered
f.add_done_callback(partial(_update_days, i))
futures.append(f)

future_wait(futures)
day_pairs.sort(key=lambda x: x[0].weekday())
future_wait(futures) # wait for all futures to complete
summary = ""
for pair in day_pairs:
days[pair[0].strftime("%A")] = pair[1]
return days
summary += "{}: {}\n".format(pair[0].strftime("%A"), pair[1])
return summary[:-1] # remove last newline
@@ -1,6 +1,7 @@
import discord
import asyncio
import json
from datetime import datetime

from rasa_nlu.model import Interpreter

@@ -9,7 +10,7 @@ from .bot import ChatBot


class DiscordBot(ChatBot):

def start(self):
self.client = discord.Client()
# nested event handlers because self.client
@@ -21,19 +22,19 @@ class DiscordBot(ChatBot):
@self.client.event
async def on_message(message):
await self._handle_message(message)

self._interpreter = Interpreter.load("./training/models/current/nlu")
self.client.run(self.config.token)

async def _ready(self):
print("DiscordBot running!")

async def _handle_message(self, message):
client = self.client

if message.author.bot:
return

if client.user in message.mentions:
# remove the first word
message_str = " ".join(message.content.split(" ")[1:])
@@ -48,7 +49,7 @@ class DiscordBot(ChatBot):
elif intent == "get_weather":
await self.client.send_message(message.channel,
self.get_weather_summary(entities))

def get_weather_summary(self, entities: list) -> str:
ws = self.services["weather"]
if not entities:
@@ -66,17 +67,18 @@ class DiscordBot(ChatBot):
# test for time periods
if periods:
# if it's a week, return weekly
p = periods[0]["value"]
p = periods[0]["value"].lower()
if p == "week":
tmp = "```\n"
for k, v in ws.get_weekly_summary(51.5, 0).items():
tmp += "{}: {}\n".format(k, v)
tmp += "```"
summary = tmp
else:
summary = "Don't know about that."

return summary
return ws.get_weekly_summary(51.5, 0)
elif days:
d = days[0]["value"]
if d == "today":
return ws.get_hourly_summary(51.5, 0, datetime.today())

return "I don't understand that request"






0 comments on commit 766c517

Please sign in to comment.