1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
# -*- coding: utf-8-*-
import feedparser
import app_utils
import re
from semantic.numbers import NumberService
WORDS = ["NEWS", "YES", "NO", "FIRST", "SECOND", "THIRD"]
PRIORITY = 3
URL = 'http://news.ycombinator.com'
class Article:
def __init__(self, title, URL):
self.title = title
self.URL = URL
def getTopArticles(maxResults=None):
d = feedparser.parse("http://news.google.com/?output=rss")
count = 0
articles = []
for item in d['items']:
articles.append(Article(item['title'], item['link'].split("&url=")[1]))
count += 1
if maxResults and count > maxResults:
break
return articles
def handle(text, mic, profile):
"""
Responds to user-input, typically speech text, with a summary of
the day's top news 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 the news")
articles = getTopArticles(maxResults=3)
titles = [" ".join(x.title.split(" - ")[:-1]) for x in articles]
all_titles = "... ".join(str(idx + 1) + ")" +
title for idx, title in enumerate(titles))
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 = not chosen_articles 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(articles):
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="Your Top Headlines",
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 set")
else:
mic.say("OK I will not send any articles")
if 'phone_number' in profile:
mic.say("Here are the current top headlines. " + all_titles +
". Would you like me to send you these articles? " +
"If so, which?")
handleResponse(mic.activeListen())
else:
mic.say(
"Here are the current top headlines. " + all_titles)
def isValid(text):
"""
Returns True if the input is related to the news.
Arguments:
text -- user-input, typically transcribed speech
"""
return bool(re.search(r'\b(news|headline)\b', text, re.IGNORECASE))
|