From 78389f252a021d642a7a0146b658f0465da6e264 Mon Sep 17 00:00:00 2001 From: schneefux Date: Sat, 26 Jul 2014 23:31:25 +0000 Subject: Work on Google STT on RPi. --- client/modules/HN.py | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 client/modules/HN.py (limited to 'client/modules/HN.py') diff --git a/client/modules/HN.py b/client/modules/HN.py new file mode 100644 index 0000000..493fa1d --- /dev/null +++ b/client/modules/HN.py @@ -0,0 +1,130 @@ +import urllib2 +import re +import random +from bs4 import BeautifulSoup +import app_utils +from semantic.numbers import NumberService + +WORDS = ["HACKER", "NEWS", "YES", "NO", "FIRST", "SECOND", "THIRD"] + +PRIORITY = 4 + +URL = 'http://news.ycombinator.com' + + +class HNStory: + + def __init__(self, title, URL): + self.title = title + self.URL = URL + + +def getTopStories(maxResults=None): + """ + Returns the top headlines from Hacker News. + + Arguments: + maxResults -- if provided, returns a random sample of size maxResults + """ + hdr = {'User-Agent': 'Mozilla/5.0'} + req = urllib2.Request(URL, headers=hdr) + page = urllib2.urlopen(req).read() + soup = BeautifulSoup(page) + matches = soup.findAll('td', class_="title") + matches = [m.a for m in matches if m.a and m.text != u'More'] + matches = [HNStory(m.text, m['href']) for m in matches] + + if maxResults: + num_stories = min(maxResults, len(matches)) + return random.sample(matches, num_stories) + + return matches + + +def handle(text, mic, profile): + """ + Responds to user-input, typically speech text, with a sample of + Hacker News's top headlines, sending them to the user over email + if desired. + + Arguments: + text -- user-input, typically transcribed speech + mic -- used to interact with the user (for both input and output) + profile -- contains information related to the user (e.g., phone number) + """ + mic.say("Pulling up some stories.") + stories = getTopStories(maxResults=3) + all_titles = '... '.join(str(idx + 1) + ") " + + story.title for idx, story in enumerate(stories)) + + def handleResponse(text): + + def extractOrdinals(text): + output = [] + service = NumberService() + for w in text.split(): + if w in service.__ordinals__: + output.append(service.__ordinals__[w]) + return [service.parse(w) for w in output] + + chosen_articles = extractOrdinals(text) + send_all = chosen_articles is [] and app_utils.isPositive(text) + + if send_all or chosen_articles: + mic.say("Sure, just give me a moment") + + if profile['prefers_email']: + body = "" + if not app_utils.emailUser(profile, SUBJECT="From the Front Page of Hacker News", BODY=body): + mic.say( + "I'm having trouble sending you these articles. Please make sure that your phone number and carrier are correct on the dashboard.") + return + + mic.say("All done.") + + else: + mic.say("OK I will not send any articles") + + if not profile['prefers_email'] and profile['phone_number']: + mic.say("Here are some front-page articles. " + + all_titles + ". Would you like me to send you these? If so, which?") + handleResponse(mic.activeListen()) + + else: + mic.say( + "Here are some front-page articles. " + all_titles) + + +def isValid(text): + """ + Returns True if the input is related to Hacker News. + + Arguments: + text -- user-input, typically transcribed speech + """ + return bool(re.search(r'\b(hack(er)?|HN)\b', text, re.IGNORECASE)) -- cgit v1.3.1