summaryrefslogtreecommitdiff
path: root/client/modules/HN.py
diff options
context:
space:
mode:
authorschneefux <schneefux+commit@schneefux.xyz>2014-07-26 23:31:25 +0000
committerschneefux <schneefux+commit@schneefux.xyz>2014-07-26 23:31:25 +0000
commit78389f252a021d642a7a0146b658f0465da6e264 (patch)
treeb740c6339ceba381004d3441f2459f65d38d02a6 /client/modules/HN.py
parent2c55f4da462383ee6c7b89ea44e5c40cd5badf0c (diff)
downloadjasper-client-78389f252a021d642a7a0146b658f0465da6e264.tar.gz
jasper-client-78389f252a021d642a7a0146b658f0465da6e264.zip
Work on Google STT on RPi.
Diffstat (limited to 'client/modules/HN.py')
-rw-r--r--client/modules/HN.py130
1 files changed, 130 insertions, 0 deletions
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 = "<ul>"
+
+ def formatArticle(article):
+ tiny_url = app_utils.generateTinyURL(article.URL)
+
+ if profile['prefers_email']:
+ return "<li><a href=\'%s\'>%s</a></li>" % (tiny_url,
+ article.title)
+ else:
+ return article.title + " -- " + tiny_url
+
+ for idx, article in enumerate(stories):
+ if send_all or (idx + 1) in chosen_articles:
+ article_link = formatArticle(article)
+
+ if profile['prefers_email']:
+ body += article_link
+ else:
+ if not app_utils.emailUser(profile, SUBJECT="", BODY=article_link):
+ 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
+
+ # if prefers email, we send once, at the end
+ if profile['prefers_email']:
+ body += "</ul>"
+ 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))