This repository has been archived by the owner on Feb 5, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
action-ourgroceriesIntentsParser.py
executable file
·183 lines (159 loc) · 7.46 KB
/
action-ourgroceriesIntentsParser.py
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#!/usr/bin/env python3
"""Action for the Our Groceries skill"""
import gettext
import locale
import re
import sys
import our_groceries_client
from snipskit.hermes.apps import HermesSnipsApp
from snipskit.config import AppConfig
from snipskit.hermes.decorators import intent
from hermes_python.ontology.injection import (
InjectionRequestMessage,
AddFromVanillaInjectionRequest
)
# Set up localse
locale.setlocale(locale.LC_ALL, '')
# Set gettext to be the right thing for python2 and python3
if sys.version_info[0] < 3:
gettext = gettext.translation('messages', localedir='locales').ugettext
else:
gettext.bindtextdomain('messages', 'locales')
gettext = gettext.gettext
class OurGroceriesApp(HermesSnipsApp):
"""HermeseSnipsApp for Our Groceries skill"""
#injection_timer = RepeatTimer(3600, self.inject_lists_and_items, self)
@intent('franc:addToList')
def add_to_list(self, hermes, intent_message):
"""Intent handler for addToList"""
quantity = 1
what = None
which_list = None
if intent_message.slots is not None:
try:
what = intent_message.slots.what[0].raw_value
except (TypeError, LookupError, ValueError):
pass
try:
which_list = intent_message.slots.list[0].slot_value.value.value
except (TypeError, LookupError, ValueError):
pass
try:
quantity = int(float(intent_message.slots.quantity[0].slot_value.value.value))
except (TypeError, LookupError, ValueError):
pass
# Set whichList to defaultlist if it's None or matches
# gettext("STR_DEFAULT_LIST") The API would use the same list if we
# passed None, but the code below would fail when giving the
# response.
if (which_list is None) or \
(which_list.casefold() == gettext("STR_DEFAULT_LIST").casefold()):
which_list = self.config['secret']['defaultlist']
if what is None:
sentence = gettext("STR_ADD_MISSING_WHAT").format(l=which_list)
hermes.publish_end_session(intent_message.session_id, sentence)
return
client = our_groceries_client.OurGroceriesClient()
client.authenticate(self.config['secret']['username'],
self.config['secret']['password'],
self.config['secret']['defaultlist'])
client.add_to_list(what, quantity, which_list)
# Respond that we added it to the list
sentence = gettext("STR_ADD_SUCCESS_DETAILS") \
.format(q=quantity, w=what, l=which_list)
hermes.publish_end_session(intent_message.session_id, sentence)
@intent('franc:checkList')
def check_list(self, hermes, intent_message):
"""Intent handler for checkList"""
sentence = None
quantity = '1'
what = None
which_list = None
if intent_message.slots is not None:
try:
what = intent_message.slots.what[0].raw_value
except (TypeError, LookupError, ValueError):
pass
try:
which_list = intent_message.slots.list[0].slot_value.value.value
except (TypeError, LookupError, ValueError):
pass
# Set whichList to defaultlist if it's None or matches
# gettext("STR_DEFAULT_LIST") The API would use the same list if we
# passed None, but the code below would fail when giving the
# response.
if (which_list is None) or \
(which_list.casefold() == gettext("STR_DEFAULT_LIST").casefold()):
which_list = self.config['secret']['defaultlist']
if what is None:
sentence = gettext("STR_CHECK_MISSING_WHAT").format(l=which_list)
hermes.publish_end_session(intent_message.session_id, sentence)
return
client = our_groceries_client.OurGroceriesClient()
client.authenticate(self.config['secret']['username'],
self.config['secret']['password'],
self.config['secret']['defaultlist'])
items = client._get_list_data(which_list)
for item in items:
crossed_off = item.get('crossedOff', False)
# Note our two primary regular expressions are commented out
# below and combined into regex. The uncommented regex line
# below this is just building the expression all at once.
#regex1 = r"^" + re.escape(what) + r" *$"
#regex2 = r"^" + re.escape(what) + r"\ \((\d+)\)$"
#regex = r"(" + regex1 + r")|(" + regex2 + r")"
regex = r'(^' + re.escape(what) + r' *$)|(^' + re.escape(what) + r'\ \((\d+)\)$)'
res = re.search(regex, item['value'], re.IGNORECASE)
# Note the following two conditions are not combined because we
# want to break the loop even if the item is crossed off. If
# it's crossed off, we don't need to keep looking for a match --
# you can't have the same item on the list with different case.
# Perhaps with different spelling, but we're not doing sounds
# like checking here. :(
if res is not None:
if not crossed_off:
quantity = res.group(3)
if quantity is None:
quantity = '1'
sentence = gettext("STR_CHECK_SUCCESS_DETAILS") \
.format(q=quantity, w=what, l=which_list)
break
if sentence is None:
sentence = gettext("STR_CHECK_NOT_FOUND").format(w=what, l=which_list)
# Respond that we added it to the list
hermes.publish_end_session(intent_message.session_id, sentence)
def initialize(self):
"""Initialization; inject our lists and items"""
self.inject_lists_and_items()
#self.injection_timer.start()
def get_items_payload(self, client, list_names):
"""Gets the items as an AddFromVanillaInjectionRequest"""
item_names = []
for list_name in list_names:
items = client._get_list_data(list_name)
for item in items:
item_names.append(item['value'])
item_names = list(set(item_names))
return AddFromVanillaInjectionRequest({'our_groceries_item_name': item_names})
def get_lists_payload(self, list_names):
"""Gets the lists as an AddFromVanillaInjectionRequest"""
return AddFromVanillaInjectionRequest({'our_groceries_list_name': list_names})
def get_update_payload(self):
"""Gets all injection requests as an InjectionRequestMessage"""
operations = []
client = our_groceries_client.OurGroceriesClient()
client.authenticate(self.config['secret']['username'],
self.config['secret']['password'],
self.config['secret']['defaultlist'])
list_names = []
for list_info in client._lists:
list_names.append(list_info['name'])
operations.append(self.get_lists_payload(list_names))
operations.append(self.get_items_payload(client, list_names))
return InjectionRequestMessage(operations)
def inject_lists_and_items(self):
"""Requests an injection of the lists and items"""
payload = self.get_update_payload()
self.hermes.request_injection(payload)
if __name__ == "__main__":
OurGroceriesApp(config=AppConfig())