Skip to content

Commit c8f5fa8

Browse files
committed
adding delete functionality
1 parent d9a4c0b commit c8f5fa8

9 files changed

+885
-256
lines changed

__init__.py

+311-256
Large diffs are not rendered by default.

__init__.py.erase

+311
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
from mycroft import MycroftSkill, intent_handler
2+
from mycroft.util.log import getLogger
3+
from mycroft.util import extract_number
4+
from mycroft.api import DeviceApi
5+
import sys
6+
import os
7+
from pathlib import Path
8+
import time
9+
import sqlite3 as sq
10+
LOGGER = getLogger(__name__)
11+
#test
12+
13+
class MySqliteDatabaseAssistant(MycroftSkill):
14+
def __init__(self):
15+
super(MySqliteDatabaseAssistant, self).__init__(name="My SQLite Database Assistant")
16+
17+
def initialize(self):
18+
self.settings_change_callback = self.on_settings_changed
19+
self.on_settings_changed()
20+
self.same_device = DeviceApi()
21+
self.info = self.same_device.get(); self.same_device = self.info['description'].lower()
22+
#self.con = sq.connect(self.db_adr, check_same_thread=False)
23+
#self.cursor = self.con.cursor()
24+
25+
26+
def on_settings_changed(self):
27+
self.db_path = self.settings.get('db_path')
28+
self.db_file_01 = self.settings.get('db_filename_01')
29+
self.db_file_02 = self.settings.get('db_filename_02')
30+
self.db_adr = self.db_path + self.db_file_01
31+
LOGGER.info("Database: " + self.db_adr)
32+
33+
def db_file_check(self, db_path):
34+
LOGGER.info(db_path)
35+
db_file = Path(db_path)
36+
return db_file.is_file()
37+
38+
## Make db execution
39+
def execution(self,db_adre,sql):
40+
with sq.connect(self.db_adr, check_same_thread=False) as conn:
41+
cur = conn.cursor()
42+
cur.execute(sql)
43+
return cur.fetchall()
44+
45+
46+
##Database functions
47+
#create if not exists
48+
def db_creation(self, db_location = '../databases/', db_name = 'tools.db', table_name = 'tool'):
49+
db_adre = db_location + db_name
50+
if not os.path.exists(db_location):
51+
os.makedirs(db_location)
52+
sql = """CREATE TABLE '""" + table_name + """' (key INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \
53+
t_name TEXT, t_synonym TEXT, t_storage TEXT, t_place TEXT);
54+
"""
55+
if self.db_file_check(db_adre) == False:
56+
con = sq.connect(db_adre, check_same_thread=False)
57+
con.commit()
58+
else:
59+
self.speak_dialog('database.exists',{'database': db_name})
60+
return None
61+
cursor = con.cursor()
62+
cursor.execute(sql)
63+
con.commit()
64+
if self.db_file_check(db_adre) == True:
65+
self.speak_dialog('dbcreation.successful', {'database': db_name})
66+
else:
67+
self.speak_dialog('dbcreation.no.success', {'database': db_name})
68+
69+
70+
# Simple requests
71+
def check_tool_names_exact(self, tool):
72+
"""Checks with exact name if a tool exists and returns the ID"""
73+
sql = """
74+
SELECT t_name, t_synonym, t_storage, t_place, key FROM tool WHERE t_name LIKE '"""+ tool +"""';
75+
"""
76+
if self.db_file_check(self.db_adr) == True:
77+
res = self.execution(self.db_adr, sql)
78+
#res = self.cursor.fetchall()
79+
return res
80+
else:
81+
self.speak_dialog('no_database',{'database': self.db_file_01})
82+
83+
def check_tool_names_raw(self, tool):
84+
"""Checks with a part of name if a tool exists and returns the t_name"""
85+
sql = """
86+
SELECT t_name, t_synonym, t_storage, t_place FROM tool WHERE t_name LIKE '"""+ '%' +tool + '%'+"""';
87+
"""
88+
if self.db_file_check(self.db_adr) == True:
89+
res = self.execution(self.db_adr, sql)
90+
#res = self.cursor.fetchall()
91+
return res
92+
else:
93+
self.speak_dialog('no_database',{'database': self.db_file_01})
94+
95+
96+
def check_tool_synonyms(self, tool):
97+
"""Checks if a tool exists and returns the t_name"""
98+
sql = """
99+
SELECT t_name, t_synonym, t_storage, t_place FROM tool WHERE t_synonym LIKE '"""+ '%' +tool + '%'+"""';
100+
"""
101+
if self.db_file_check(self.db_adr) == True:
102+
res = self.execution(self.db_adr, sql)
103+
#res = self.cursor.fetchall()
104+
return res
105+
else:
106+
self.speak_dialog('no_database',{'database': self.db_file_01})
107+
108+
def insert_new_tool(self, tool, synonym, storage, place):
109+
"""inserts a new tool if not exists"""
110+
stored_tool = self.check_tool_names_exact(tool)
111+
sql = """
112+
INSERT INTO tool (key, t_name, t_synonym, t_storage, t_place) VALUES \
113+
(NULL, '""" + tool +"""', '""" + synonym +"""', '""" + storage +"""',\
114+
'""" + place +"""');
115+
"""
116+
if self.db_file_check(self.db_adr) == True:
117+
res = self.execution(self.db_adr, sql)
118+
else:
119+
self.speak_dialog('no_database',{'database': self.db_file_01})
120+
121+
def update_tool(self, key_tool, new_storage, new_place):
122+
"""updates storage and place of a known tool"""
123+
sql = """
124+
UPDATE tool SET t_storage = '""" + new_storage + """', t_place = '""" + new_place + """' \
125+
WHERE key = '""" + str(key_tool) + """';
126+
"""
127+
self.execution(self.db_adr, sql)
128+
129+
def erase_one(key_tool):
130+
sql = """
131+
DELETE FROM '""" + self.db_adr + """' WHERE key = '""" + key_tool + """';
132+
"""
133+
self.execute(self.db_adr, sql)
134+
135+
def erase_all(self, selected_tools):
136+
for i in range(len(selected_tools)):
137+
sql = """
138+
DELETE FROM '""" + self.db_adr + """' WHERE key = '""" + selection_list[i][4] + """';
139+
"""
140+
self.execution(self.db_adr, sql)
141+
142+
143+
def change_storage(self, tool):
144+
"""Changes a storage or place of a tool"""
145+
selection_list = []
146+
counter = 0
147+
res = self.check_tool_names_exact(tool)
148+
if len(res) > 0:
149+
selected_tools = [i for i in range(len(res))]
150+
for i in selected_tools:
151+
selection_list = selection_list + [str(res[i][0]) + ' in ' + str(res[i][2]) + ', ' + str(res[i][3])]
152+
for i in selection_list:
153+
counter = counter + 1
154+
self.speak_dialog('speak.selection.list',{'counter': counter, 'i': i})
155+
nr_from_sel_list = self.get_response('speak.selection')
156+
if nr_from_sel_list == None:
157+
return
158+
nr_from_sel_list = extract_number(nr_from_sel_list); nr_from_sel_list -= 1;nr_from_sel_list = int(nr_from_sel_list)
159+
#LOGGER.info("Key Nr: " + str(res[nr_from_sel_list]))
160+
key_tool = res[nr_from_sel_list][4]
161+
new_storage = self.get_response('new.storage')
162+
new_place = self.get_response('new.place')
163+
try:
164+
self.update_tool(key_tool,new_storage, new_place)
165+
self.speak_dialog('update.success')
166+
except sq.OperationalError as e:
167+
self.speak_dialog('database.error')
168+
return
169+
170+
def erase_tool(self, tool):
171+
"""Erases tool from tools.db"""
172+
selection_list = []
173+
counter = 0
174+
res = self.check_tool_names_exact(tool)
175+
if len(res) > 0:
176+
selected_tools = [i for i in range(len(res))]
177+
for i in selected_tools:
178+
selection_list = selection_list + [str(res[i][0]) + ' in ' + str(res[i][2]) + ', ' + str(res[i][3])]
179+
for i in selection_list:
180+
counter = counter + 1
181+
self.speak_dialog('speak.erase',{'counter': counter, 'i': i})
182+
nr_from_sel_list = self.get_response('speak.erase.list')
183+
nr_from_sel_list = extract_number(nr_from_sel_list); nr_from_sel_list -= 1;nr_from_sel_list = int(nr_from_sel_list)
184+
#LOGGER.info("Key Nr: " + str(res[nr_from_sel_list]))
185+
if nr_from_sel_list == None:
186+
return
187+
if self.voc_match(nr_from_sel_list, 'all'):
188+
try:
189+
self.erase_all(selected_tools)
190+
self.speak_dialog('erase.all.success', {'tool': tool})
191+
except sq.OperationalError as e:
192+
self.speak_dialog('database.error')
193+
return
194+
else:
195+
try:
196+
LOGGER.info(str(nr_from_sel_list[4]))
197+
key_tool = res[nr_from_sel_list][4]
198+
self.erase_one(key_tool)
199+
self.speak_dialog('erase.one.success', {'tool': tool})
200+
except sq.OperationalError as e:
201+
self.speak_dialog('database.error')
202+
return
203+
204+
205+
206+
## Helper functions
207+
# file exist
208+
def db_file_check(self, db_path):
209+
"""Checks if db file exists"""
210+
LOGGER.info(db_path)
211+
db_file = Path(db_path)
212+
return db_file.is_file()
213+
214+
# db infos
215+
def count_db_rows(self):
216+
sql = """SELECT COUNT() FROM tool;"""
217+
res = self.execution(self.db_adr, sql)
218+
return res
219+
220+
#Formatting data tuples to speech
221+
def make_utterance(self, res, tool):
222+
"""Makes an utterance if tool is found in column t_name"""
223+
if len(res) == 0:
224+
self.speak_dialog('notool', {'tool': tool})
225+
else:
226+
i = 0
227+
while i < len(res):
228+
tool = res[i][0]
229+
storage = res[i][2]
230+
place = res[i][3]
231+
self.speak_dialog('tool.is.in', {'tool': tool, 'storage': storage, 'place': place})
232+
i += 1
233+
234+
def make_utterance_from_synonym(self, res, tool):
235+
"""Makes an utterance if tool is found in column t_synonym and speaks the primary name from t_name"""
236+
if len(res) == 0:
237+
self.speak_dialog('notool', {'tool': tool})
238+
else:
239+
i = 0
240+
while i < len(res):
241+
tool = res[i][0]
242+
synonym = res[i][1]
243+
storage = res[i][2]
244+
place = res[i][3]
245+
self.speak_dialog('synonym.is.in', {'tool': tool, 'synonym': synonym, 'storage': storage, 'place': place})
246+
time.sleep(1)
247+
i += 1
248+
249+
250+
##Intent handlers
251+
@intent_handler('create.database.intent')
252+
def handle_create_database(self):
253+
self.db_creation()
254+
255+
@intent_handler('insert.tool.intent')
256+
def handle_insert_tool(self):
257+
res = self.count_db_rows()
258+
res_rows_old = int(res[0][0])
259+
tool = self.get_response('insert.tool.name',0)
260+
synonym = self.get_response('insert.tool.synonym',0)
261+
if synonym == None:
262+
synonym = " "
263+
storage = self.get_response('insert.tool.storage',0)
264+
place = self.get_response('insert.tool.place',0)
265+
self.insert_new_tool(tool, synonym, storage, place)
266+
res = self.count_db_rows()
267+
res_rows_new = int(res[0][0])
268+
if res_rows_new - res_rows_old == 1:
269+
self.speak_dialog('tool.stored.success', {'tool': tool})
270+
271+
272+
@intent_handler('find.tool.intent')
273+
def handle_find_tool(self, message):
274+
'''Looks for a tool in column t_name. If search isn't successful\
275+
you are asked for looking in column t_synonym'''
276+
tool = message.data.get('tool')
277+
if self.db_file_check(self.db_adr) == True:
278+
res = self.check_tool_names_exact(tool)
279+
if len(res) == 0:
280+
answer = self.ask_yesno('look.for.synonym', {'tool': tool})
281+
if answer == 'yes':
282+
res = self.check_tool_synonyms(tool)
283+
if len(res) == 0:
284+
self.speak_dialog('nosynonym', {'tool': tool})
285+
else:
286+
self.make_utterance_from_synonym(res, tool)
287+
else:
288+
self.speak_dialog('no.tool.name')
289+
return
290+
else:
291+
self.make_utterance(res, tool)
292+
else:
293+
self.speak_dialog('no_database',{'database': self.db_file_01})
294+
295+
@intent_handler('change.storage.intent')
296+
def handle_change_storage(self, message):
297+
tool = message.data.get('tool')
298+
if self.db_file_check(self.db_adr) == True:
299+
self.change_storage(tool)
300+
else:
301+
pass
302+
303+
@intent_handler('erase.tool.intent')
304+
def handle_erase_tool(self, message):
305+
tool = message.data.get('tool')
306+
if self.db_file_check(self.db_adr) == True:
307+
self.erase_tool(tool)
308+
else:
309+
pass
310+
def create_skill():
311+
return MySqliteDatabaseAssistant()

0 commit comments

Comments
 (0)