From 188b756b7b184316de769ec28f01ce289de9f081 Mon Sep 17 00:00:00 2001 From: Clary <100237954+NeonClary@users.noreply.github.com> Date: Wed, 2 Nov 2022 22:59:52 -0700 Subject: [PATCH 01/44] Update opening_minutes.dialog --- locale/en-us/dialog/en/opening_minutes.dialog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locale/en-us/dialog/en/opening_minutes.dialog b/locale/en-us/dialog/en/opening_minutes.dialog index ce55fcc..9bc6ef2 100644 --- a/locale/en-us/dialog/en/opening_minutes.dialog +++ b/locale/en-us/dialog/en/opening_minutes.dialog @@ -1 +1 @@ -{{shop_name}} is closed now. Opens in {{wait_min}} minutes. \ No newline at end of file +{{shop_name}} is closed now. It opens in {{wait_min}} minutes. From 75410adb80865a0eb4e8bb517080797bd190d3d8 Mon Sep 17 00:00:00 2001 From: Clary <100237954+NeonClary@users.noreply.github.com> Date: Wed, 2 Nov 2022 22:59:37 -0700 Subject: [PATCH 02/44] Update shop_by_floor.dialog --- locale/en-us/dialog/en/shop_by_floor.dialog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locale/en-us/dialog/en/shop_by_floor.dialog b/locale/en-us/dialog/en/shop_by_floor.dialog index 97c1ac0..ede6d37 100644 --- a/locale/en-us/dialog/en/shop_by_floor.dialog +++ b/locale/en-us/dialog/en/shop_by_floor.dialog @@ -1 +1 @@ -Do you want to get shop info by floor? \ No newline at end of file +Do you want to get store info by floor? From d209e7940ed5495e89ea25ebe88671bed32461af Mon Sep 17 00:00:00 2001 From: Clary <100237954+NeonClary@users.noreply.github.com> Date: Wed, 2 Nov 2022 22:58:50 -0700 Subject: [PATCH 03/44] Update shop_not_found.dialog --- locale/en-us/dialog/en/shop_not_found.dialog | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/locale/en-us/dialog/en/shop_not_found.dialog b/locale/en-us/dialog/en/shop_not_found.dialog index 859f286..261cf75 100644 --- a/locale/en-us/dialog/en/shop_not_found.dialog +++ b/locale/en-us/dialog/en/shop_not_found.dialog @@ -1,2 +1,3 @@ -Sorry, this store doesn't exist in this mall. I am not sure I've understood what you said. Repeat, please. -Sorry, I can not find this shop. I am not sure I've understood what you said. Repeat, please. \ No newline at end of file +Sorry, I can't find {{store_name}}, but maybe I misunderstood, could you ask again please? +{{store_name}} isn't here, could you please repeat your query in case I misunderstood? +I apologize, I can't find a listing for {{store_name}} here. Can you please say that again? From fa2529676d7021cbf227c5cb044d4384b0dc3034 Mon Sep 17 00:00:00 2001 From: Clary <100237954+NeonClary@users.noreply.github.com> Date: Wed, 2 Nov 2022 22:51:39 -0700 Subject: [PATCH 04/44] Update start_parsing.dialog --- locale/en-us/dialog/en/start_parsing.dialog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locale/en-us/dialog/en/start_parsing.dialog b/locale/en-us/dialog/en/start_parsing.dialog index 4071f9b..15fc6b6 100644 --- a/locale/en-us/dialog/en/start_parsing.dialog +++ b/locale/en-us/dialog/en/start_parsing.dialog @@ -1 +1 @@ -I am parsing shops and malls for your request. \ No newline at end of file +Let me look that up for you. From 3b8e3e3361901529c97e6d5fbeb977d194f017ef Mon Sep 17 00:00:00 2001 From: Clary <100237954+NeonClary@users.noreply.github.com> Date: Wed, 2 Nov 2022 22:50:45 -0700 Subject: [PATCH 05/44] Update stop.dialog --- locale/en-us/dialog/en/stop.dialog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locale/en-us/dialog/en/stop.dialog b/locale/en-us/dialog/en/stop.dialog index 2874c27..b1c96ba 100644 --- a/locale/en-us/dialog/en/stop.dialog +++ b/locale/en-us/dialog/en/stop.dialog @@ -1 +1 @@ -Do you want to exit the mall directory? \ No newline at end of file +Are you finished getting store information for now? From 0c1bf36c9991888ea801ec49aa4da3e9b44eebd8 Mon Sep 17 00:00:00 2001 From: Clary <100237954+NeonClary@users.noreply.github.com> Date: Wed, 2 Nov 2022 22:49:32 -0700 Subject: [PATCH 06/44] Update which_floor.dialog --- locale/en-us/dialog/en/which_floor.dialog | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/locale/en-us/dialog/en/which_floor.dialog b/locale/en-us/dialog/en/which_floor.dialog index 4333de5..c3edcfa 100644 --- a/locale/en-us/dialog/en/which_floor.dialog +++ b/locale/en-us/dialog/en/which_floor.dialog @@ -1,3 +1,2 @@ -Which floor are you staying on? +Which floor are you on? On which floor are you? -what is your floor? \ No newline at end of file From e4884b9b9ed0169b1a5cd3e667d7e3f145613521 Mon Sep 17 00:00:00 2001 From: Clary <100237954+NeonClary@users.noreply.github.com> Date: Wed, 2 Nov 2022 22:44:34 -0700 Subject: [PATCH 07/44] Update no_shop_request.dialog --- locale/en-us/dialog/en/no_shop_request.dialog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locale/en-us/dialog/en/no_shop_request.dialog b/locale/en-us/dialog/en/no_shop_request.dialog index 6ca56f4..0718253 100644 --- a/locale/en-us/dialog/en/no_shop_request.dialog +++ b/locale/en-us/dialog/en/no_shop_request.dialog @@ -1 +1 @@ -Okay. I will stop mall parsing. \ No newline at end of file +Okay. Have a good day! From 4a622a58b85f921962e92283b31f5ff5a02c3fbe Mon Sep 17 00:00:00 2001 From: Clary <100237954+NeonClary@users.noreply.github.com> Date: Wed, 2 Nov 2022 22:43:51 -0700 Subject: [PATCH 08/44] Update no_shop_on_level.dialog --- locale/en-us/dialog/en/no_shop_on_level.dialog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locale/en-us/dialog/en/no_shop_on_level.dialog b/locale/en-us/dialog/en/no_shop_on_level.dialog index 69b5d6d..e0dfce1 100644 --- a/locale/en-us/dialog/en/no_shop_on_level.dialog +++ b/locale/en-us/dialog/en/no_shop_on_level.dialog @@ -1 +1 @@ -There is no requested shop on your level. Here are all possible locations. \ No newline at end of file +I did not find that store on your level. Here are all possible locations. From b32670c41d1c64a0a5f2e94423e8073ae8875168 Mon Sep 17 00:00:00 2001 From: Clary <100237954+NeonClary@users.noreply.github.com> Date: Wed, 2 Nov 2022 22:40:30 -0700 Subject: [PATCH 09/44] Update more_than_one.dialog --- locale/en-us/dialog/en/more_than_one.dialog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locale/en-us/dialog/en/more_than_one.dialog b/locale/en-us/dialog/en/more_than_one.dialog index 70532f4..a9c36a8 100644 --- a/locale/en-us/dialog/en/more_than_one.dialog +++ b/locale/en-us/dialog/en/more_than_one.dialog @@ -1 +1 @@ -I found more than one shop in your request. \ No newline at end of file +I found more than one store in your request. From a0379d715e2221efa61c5f81ff4b51a921d89664 Mon Sep 17 00:00:00 2001 From: Clary <100237954+NeonClary@users.noreply.github.com> Date: Wed, 2 Nov 2022 22:39:32 -0700 Subject: [PATCH 10/44] Update finished.dialog --- locale/en-us/dialog/en/finished.dialog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locale/en-us/dialog/en/finished.dialog b/locale/en-us/dialog/en/finished.dialog index 17ed73d..5566371 100644 --- a/locale/en-us/dialog/en/finished.dialog +++ b/locale/en-us/dialog/en/finished.dialog @@ -1 +1 @@ -Finished. Goodbye! \ No newline at end of file +Have a good day! From dd59f52ce77d4893d3cd53fc3d8f4b37567b9f96 Mon Sep 17 00:00:00 2001 From: Clary <100237954+NeonClary@users.noreply.github.com> Date: Wed, 2 Nov 2022 22:38:16 -0700 Subject: [PATCH 11/44] Update closing_minutes.dialog --- locale/en-us/dialog/en/closing_minutes.dialog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locale/en-us/dialog/en/closing_minutes.dialog b/locale/en-us/dialog/en/closing_minutes.dialog index 46d9f8b..4075ad7 100644 --- a/locale/en-us/dialog/en/closing_minutes.dialog +++ b/locale/en-us/dialog/en/closing_minutes.dialog @@ -1 +1 @@ -{{shop_name}} is open now. Closes in {{wait_min}} minutes. \ No newline at end of file +{{shop_name}} is open now. It closes in {{wait_min}} minutes. From 3a2e3491fffb43b5b488d0c5b2e33321bf06b2a9 Mon Sep 17 00:00:00 2001 From: Clary <100237954+NeonClary@users.noreply.github.com> Date: Wed, 2 Nov 2022 22:37:58 -0700 Subject: [PATCH 12/44] Update closed_now.dialog --- locale/en-us/dialog/en/closed_now.dialog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locale/en-us/dialog/en/closed_now.dialog b/locale/en-us/dialog/en/closed_now.dialog index d095784..d1c345b 100644 --- a/locale/en-us/dialog/en/closed_now.dialog +++ b/locale/en-us/dialog/en/closed_now.dialog @@ -1 +1 @@ -{{shop_name}} is closed now. Opens at {{open_time}}. \ No newline at end of file +{{shop_name}} is closed now. It opens at {{open_time}}. From 2a622d6f7abc8febbc269de3eac144de2dbee428 Mon Sep 17 00:00:00 2001 From: Clary <100237954+NeonClary@users.noreply.github.com> Date: Wed, 2 Nov 2022 22:36:59 -0700 Subject: [PATCH 13/44] Update choose_selection.dialog --- locale/en-us/dialog/en/choose_selection.dialog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locale/en-us/dialog/en/choose_selection.dialog b/locale/en-us/dialog/en/choose_selection.dialog index 23ac161..56419a0 100644 --- a/locale/en-us/dialog/en/choose_selection.dialog +++ b/locale/en-us/dialog/en/choose_selection.dialog @@ -1 +1 @@ -Do you want to select store by work hours or location? \ No newline at end of file +Do you want to select a result by open hours or location? From 1cd8c7c137faa1da02bb830ccf79e347a68c7e1b Mon Sep 17 00:00:00 2001 From: Clary <100237954+NeonClary@users.noreply.github.com> Date: Wed, 2 Nov 2022 22:34:50 -0700 Subject: [PATCH 14/44] Update ask_more.dialog --- locale/en-us/dialog/en/ask_more.dialog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locale/en-us/dialog/en/ask_more.dialog b/locale/en-us/dialog/en/ask_more.dialog index b2b8db3..05d8228 100644 --- a/locale/en-us/dialog/en/ask_more.dialog +++ b/locale/en-us/dialog/en/ask_more.dialog @@ -1 +1 @@ -Do you want to get another shop info? \ No newline at end of file +Do you want to get info for another store? From 94b6a3143f68dcf4cd41de6df22963cffd1db103 Mon Sep 17 00:00:00 2001 From: mariiarazno Date: Mon, 14 Nov 2022 15:21:28 +0100 Subject: [PATCH 15/44] time processing in lingua-franca, shop->store replacement --- __init__.py | 276 +++++++++--------- locale/en-us/dialog/en/another_shop.dialog | 1 - locale/en-us/dialog/en/another_store.dialog | 1 + locale/en-us/dialog/en/closed_now.dialog | 2 +- locale/en-us/dialog/en/closing_minutes.dialog | 2 +- .../{found_shop.dialog => found_store.dialog} | 0 ..._level.dialog => no_store_on_level.dialog} | 0 ...request.dialog => no_store_request.dialog} | 0 locale/en-us/dialog/en/open_now.dialog | 2 +- locale/en-us/dialog/en/opening_hours.dialog | 1 - locale/en-us/dialog/en/opening_minutes.dialog | 1 - ..._by_floor.dialog => store_by_floor.dialog} | 0 ...ot_found.dialog => store_not_found.dialog} | 0 .../dialog/en/time_before_closing.dialog | 1 + .../dialog/en/waiting_for_opening.dialog | 1 + request_handling.py | 78 ++--- requirements/test_requirements.txt | 1 + test/test_skill.py | 45 +-- 18 files changed, 208 insertions(+), 204 deletions(-) delete mode 100644 locale/en-us/dialog/en/another_shop.dialog create mode 100644 locale/en-us/dialog/en/another_store.dialog rename locale/en-us/dialog/en/{found_shop.dialog => found_store.dialog} (100%) rename locale/en-us/dialog/en/{no_shop_on_level.dialog => no_store_on_level.dialog} (100%) rename locale/en-us/dialog/en/{no_shop_request.dialog => no_store_request.dialog} (100%) delete mode 100644 locale/en-us/dialog/en/opening_hours.dialog delete mode 100644 locale/en-us/dialog/en/opening_minutes.dialog rename locale/en-us/dialog/en/{shop_by_floor.dialog => store_by_floor.dialog} (100%) rename locale/en-us/dialog/en/{shop_not_found.dialog => store_not_found.dialog} (100%) create mode 100644 locale/en-us/dialog/en/time_before_closing.dialog create mode 100644 locale/en-us/dialog/en/waiting_for_opening.dialog diff --git a/__init__.py b/__init__.py index e6acc2f..7f53354 100644 --- a/__init__.py +++ b/__init__.py @@ -29,13 +29,15 @@ from neon_utils.skills.neon_skill import NeonSkill, LOG from mycroft.skills.core import intent_file_handler -from .request_handling import RequestHandler -from .request_handling import existing_lang_check, get_shop_data,\ - shop_selection_by_floors,\ - location_format,\ - curent_time_extraction +from .request_handling import existing_lang_check, get_store_data, \ + store_selection_by_floors, \ + location_format, \ + curent_time_extraction import re +import lingua_franca +from lingua_franca.format import nice_duration +lingua_franca.load_language('en') class DirectorySkill(NeonSkill): @@ -43,7 +45,7 @@ class DirectorySkill(NeonSkill): def __init__(self): super(DirectorySkill, self).__init__(name="DirectorySkill") self.url = "https://www.alamoanacenter.com/en/directory/" - + self.request_lang = self.lang.split('-')[0] def initialize(self): # When first run or prompt not dismissed, wait for load and prompt user @@ -75,15 +77,14 @@ def user_request_handling(self, message): if message.data == {} or message is None: return None, None else: - request_lang = self.lang.split('-')[0] - user_request = message.data['shop'] + user_request = message.data['store'] LOG.info(f"{self.mall_link()}") - LOG.info(str(request_lang)) + LOG.info(str(self.request_lang)) LOG.info(user_request) - found, link = existing_lang_check(request_lang, self.mall_link()) + found, link = existing_lang_check(self.request_lang, self.mall_link()) if found: - link = self.mall_link()+request_lang+'/directory/' - LOG.info('new link: '+ link) + link = self.mall_link() + self.request_lang + '/directory/' + LOG.info('new link: ' + link) return user_request, link else: self.speak_dialog("no_lang") @@ -92,135 +93,133 @@ def user_request_handling(self, message): def start_again(self): """ Asks yes/no question whether user wants to - get another shop info, after Neon gave the - information about previously selected shop. - If user's answer 'yes': asks what shop is + get another store info, after Neon gave the + information about previously selected store. + If user's answer 'yes': asks what store is needed. Returns user's answer. If 'no', speaks corresponding dialog. If some other answer, speaks corresponding dialog Returns: - None (if no shop in request, if user's + None (if no store in request, if user's answer is 'no', if user gives some other answer) """ start_again = self.ask_yesno("ask_more") if start_again == "yes": - another_shop = self.get_response('another_shop') - if another_shop is not None: - LOG.info(f'another shop {another_shop}') - return another_shop + another_store = self.get_response('another_store') + if another_store is not None: + LOG.info(f'another store {another_store}') + return another_store elif start_again == "no": - self.speak_dialog('no_shop_request') + self.speak_dialog('no_store_request') else: self.speak_dialog('unexpected_error') return None - def speak_shops(self, shop_info): + def speak_stores(self, store_info): """ - Speaks shop info that was found. + Speaks store info that was found. Substitutes time format for better pronunciation. - speak_dialog('found_shop', {"name": shop['name'], "hours": hours, "location": location}) - Shows shop label image in gui. + speak_dialog('found_store', {"name": store['name'], "hours": hours, "location": location}) + Shows store label image in gui. Args: - shop_info (list): found shops on user's + store_info (list): found stores on user's request """ - for shop in shop_info: - LOG.info(shop) - location = location_format(shop['location']) - hours = re.sub('(\d+)am.+(\d+)pm', r'from \1 A M to \2 P M', shop['hours']) - self.speak_dialog('found_shop', {"name": shop['name'], "hours": hours, "location": location}) - LOG.info({"name": shop['name'], "hours": hours, "location": location}) - self.gui.show_image(shop['logo'], caption=f'{hours} {location}', title=shop['name']) + for store in store_info: + LOG.info(store) + location = location_format(store['location']) + hours = re.sub('(\d+)am.+(\d+)pm', r'from \1 A M to \2 P M', store['hours']) + self.speak_dialog('found_store', {"name": store['name'], "hours": hours, "location": location}) + LOG.info({"name": store['name'], "hours": hours, "location": location}) + #self.gui.show_image(store['logo'], caption=f'{hours} {location}', title=store['name']) - def location_selection(self, shop_info): + def location_selection(self, store_info): """ - If there are several shops in found shops list - and user wants to get shop info on the certain - floor. If shop on that floor exists speaks - this shop info. Else speaks all shops info. + If there are several stores in found stores list + and user wants to get store info on the certain + floor. If store on that floor exists speaks + this store info. Else speaks all stores info. Args: - shop_info (list): found shops on user's + store_info (list): found stores on user's request Returns: - 3, None (to ask for another shop info) + 3, None (to ask for another store info) """ - LOG.info(f"Shop by location selection {shop_info}") + LOG.info(f"Shop by location selection {store_info}") floor = self.get_response('which_floor') - shops = shop_selection_by_floors(floor, shop_info) - if shops: - self.speak_shops(shops) + stores = store_selection_by_floors(floor, store_info) + if stores: + self.speak_stores(stores) else: - self.speak_dialog('no_shop_on_level') - self.speak_shops(shop_info) + self.speak_dialog('no_store_on_level') + self.speak_stores(store_info) return 3, None - def open_shops_search(self, shop_info, day_time, hour, min): + def open_stores_search(self, store_info, day_time, hour, min): """ - Selects open shops. Collects the list of - open shops else return empty list. + Selects open stores. Collects the list of + open stores else return empty list. Args: - shop_info (list): found shops on user's + store_info (list): found stores on user's request Returns: - shop_info (list): open shops + store_info (list): open stores """ - open_shops = [] + open_stores = [] LOG.info(f"User's time {day_time, hour, min}") - for shop in shop_info: - parse_time = re.findall(r'(\d+)+[am|pm]', shop['hours']) + for store in store_info: + parse_time = re.findall(r'(\d+)+[am|pm]', store['hours']) LOG.info(f'Parsed time {parse_time}') open_time = int(parse_time[0]) close_time = int(parse_time[1]) if open_time <= hour < close_time: - open_shops.append(shop) + open_stores.append(store) elif day_time[1] == 'am' and open_time <= hour: - open_shops.append(shop) - return open_shops - + open_stores.append(store) + return open_stores - def time_calculation(self, shop_info, open, day_time, hour, min): - # add logic if shop opens and closes not at am-pm time period - # change to speak dialog + def time_calculation(self, store_info, open, day_time, hour, min): + #Todo: add logic if store opens and closes not at am-pm time period """ Calculates time difference between user's current time - and shop working hours. + and store working hours. If 'open' argument is True: If user one hour or less before closing: speaks how - many minutes left. Speaks shop info. - Else speaks corresponging dialog. - Speaks shop info. + many minutes left. Speaks store info. + Else speaks corresponging dialog. + Speaks store info. If 'open' argument is False: Speaks corresponding dialog. - If user is one hour or less before opening hours - speaks how much time is left for waiting. + If user is one hour or less before opening hours + speaks how much time is left for waiting. If user's time is 'am' and user is before opening - hours, speaks how many hours and minutes left + hours, speaks how many hours and minutes left waiting. - If user's time is evening (pm) speaks when the shop + If user's time is evening (pm) speaks when the store opens in the morning. - Speaks shop info. + Speaks store info. Args: - shop_info (list): found shops on user's request - open (boolean): True - if shop is open - day_time (str): user's current day time (am|pm) + store_info (list): found stores on user's request + open (boolean): True - if store is open + day_time (str): user's current day time (am|pm) hour (int): user's current hour min (int): user's current minute Returns: - 3, None (to ask for another shop info) + 3, None (to ask for another store info) Examples: work time 9am-10pm user's time 8am Prompt: 'Shop is closed now. Opens in 1 hour' """ - for shop in shop_info: - work_time = shop['hours'] + for store in store_info: + work_time = store['hours'] normalized_time = re.findall(r'(\d+)[am|pm]', work_time) open_time = int(normalized_time[0]) close_time = int(normalized_time[1]) LOG.info(f'work_time {work_time}') - shop_name = shop['name'] + store_name = store['name'] parse_time = work_time.split('-') LOG.info(f'parse_time {parse_time}') # time left @@ -228,98 +227,102 @@ def time_calculation(self, shop_info, open, day_time, hour, min): wait_min = 60 - min if open: if day_time[1] == 'pm' and 0 < (close_time - hour) <= 1: - LOG.info(f'{shop_name} closes in {wait_min} minutes.') - self.speak_dialog('closing_minutes', {"shop_name": shop_name, "wait_min": wait_min}) + duration = wait_min * 60 + formated_duration = nice_duration(duration, lang=str(self.request_lang), speech=True) + LOG.info(f'{store_name} closes in {formated_duration}.') + self.speak_dialog('time_before_closing', {"store_name": store_name, "duration": formated_duration}) else: - LOG.info(f'{shop_name} is open.') - self.speak_dialog('open_now', {'shop_name': shop_name}) - LOG.info([shop]) - self.speak_shops([shop]) + LOG.info(f'{store_name} is open.') + self.speak_dialog('open_now', {'store_name': store_name}) + LOG.info([store]) + self.speak_stores([store]) else: if day_time[1] == 'am' and hour < open_time: if wait_h == 0: - LOG.info(f'{shop_name} is closed now. Opens in {wait_min} minutes') - self.speak_dialog('opening_minutes', {"shop_name": shop_name, "wait_min": wait_min}) + LOG.info(f'{store_name} is closed now. Opens in {wait_min} minutes') + self.speak_dialog('opening_minutes', {"store_name": store_name, "wait_min": wait_min}) else: - LOG.info(f'{shop_name} is closed now. Opens in {wait_h} hour and {wait_min} minutes') - self.speak_dialog('opening_hours', {"shop_name": shop_name, "wait_h": wait_h, "wait_min": wait_min}) + duration = wait_h * 3600 + wait_min * 60 + formated_duration = nice_duration(duration, lang=str(self.request_lang), speech=True) + LOG.info(f'{store_name} is closed now. Opens in {formated_duration} ') + self.speak_dialog('waiting_for_opening', {"store_name": store_name, 'duration': formated_duration}) elif hour >= close_time: - LOG.info(f'{shop_name} is closed now. Shop opens at {open_time}') - self.speak_dialog('closed_now', {'shop_name': shop_name, 'open_time': open_time}) - LOG.info([shop]) - self.speak_shops([shop]) + LOG.info(f'{store_name} is closed now. Shop opens at {open_time}') + self.speak_dialog('closed_now', {'store_name': store_name, 'open_time': open_time}) + LOG.info([store]) + self.speak_stores([store]) return 3, None - def shops_by_time_selection(self, shop_info): + def stores_by_time_selection(self, store_info): """ - If user chose to select shops by time or + If user chose to select stores by time or use like default selection. Gets user's - current time. Selects open shops. + current time. Selects open stores. Args: - shop_info (list): found shops on user's + store_info (list): found stores on user's request Returns: - time_calculation function with True + time_calculation function with True in 'open' argument. - time_calculation function with False + time_calculation function with False in 'open' argument. (if list - of open shops is 0) - + of open stores is 0) + """ - LOG.info(f"Shop by time selection {shop_info}") + LOG.info(f"Shop by time selection {store_info}") day_time, hour, min = curent_time_extraction() # day_time, hour, min = ['11:15', 'pm'], 11, 15 - open_shops = self.open_shops_search(shop_info, day_time, hour, min) - if len(open_shops) >= 1: - return self.time_calculation(open_shops, True, day_time, hour, min) + open_stores = self.open_stores_search(store_info, day_time, hour, min) + if len(open_stores) >= 1: + return self.time_calculation(open_stores, True, day_time, hour, min) else: - return self.time_calculation(shop_info, False, day_time, hour, min) + return self.time_calculation(store_info, False, day_time, hour, min) - def find_shop(self, user_request, mall_link): + def find_store(self, user_request, mall_link): """ When the intent is matched, user_request - variable contains the name of the shop. - The matching function get_shop_data() is - used to find the shop name in cache or + variable contains the name of the store. + The matching function get_store_data() is + used to find the store name in cache or on the mall page. If user's request is not None this function - can return several shops, one shop or empty + can return several stores, one store or empty list. - If no shop was found asks user to repeat. + If no store was found asks user to repeat. returns 1, user_request to continue the execution loop in self.execute(). - If there are several shops asks user what way + If there are several stores asks user what way of sorting to choose: time, level, nothing. - If 'time' - finds open shops. If open shops - list is not empty speaks open shops, else - tells time difference between user and shops' + If 'time' - finds open stores. If open stores + list is not empty speaks open stores, else + tells time difference between user and stores' work hours. If 'location' - asks what level user is interested - in. If shops were found speaks shops' info, - else tells that there is no shop on that level - and speaks all found shops. + in. If stores were found speaks stores' info, + else tells that there is no store on that level + and speaks all found stores. If 'no' - sorts by time. If nothing matched in the answer - sorts by time. - If there was one shop found speaks this - shop info. Returns 3, None to stop current - shop search. + If there was one store found speaks this + store info. Returns 3, None to stop current + store search. Location and time sorting functions return - 3, None to stop current shop search. + 3, None to stop current store search. """ LOG.info(f'user_request {user_request}') LOG.info(f'mall_link {mall_link}') if user_request is not None: self.speak_dialog("start_parsing") - LOG.info(f"I am parsing shops and malls for your request") + LOG.info(f"I am parsing stores and malls for your request") file_path = self.file_system.path LOG.info(f'file_path {file_path}') - shop_info = get_shop_data(mall_link, user_request, file_path) - LOG.info(f"I found {len(shop_info)} shops") - LOG.info(f"shop list: {shop_info}") - if len(shop_info) == 0: - user_request = self.get_response('shop_not_found') + store_info = get_store_data(mall_link, user_request, file_path) + LOG.info(f"I found {len(store_info)} stores") + LOG.info(f"store list: {store_info}") + if len(store_info) == 0: + user_request = self.get_response('store_not_found') return 1, user_request - elif len(shop_info) > 1: + elif len(store_info) > 1: self.speak_dialog('more_than_one') # ask for the way of selection: time, location, nothing sorting_selection = self.get_response('choose_selection') @@ -327,26 +330,26 @@ def find_shop(self, user_request, mall_link): LOG.info(f'Users answer on sorting options: {sorting_selection}') if self.voc_match(sorting_selection, "time"): LOG.info('Time sorting selected') - return self.shops_by_time_selection(shop_info) + return self.stores_by_time_selection(store_info) elif self.voc_match(sorting_selection, "location"): LOG.info('Location sorting selected') - return self.location_selection(shop_info) + return self.location_selection(store_info) elif self.voc_match(sorting_selection, "no"): LOG.info('No sorting selected. Sorting by time on default.') - return self.shops_by_time_selection(shop_info) + return self.stores_by_time_selection(store_info) else: LOG.info('Nothing matched. Sorting by time on default.') - return self.shops_by_time_selection(shop_info) + return self.stores_by_time_selection(store_info) else: - LOG.info(f"found shop {shop_info}") - self.speak_shops(shop_info) + LOG.info(f"found store {store_info}") + self.speak_stores(store_info) return 3, None def execute(self, user_request, mall_link): count = 0 LOG.info('Start execute') while count < 3 and user_request is not None and mall_link is not None: - new_count, user_request = self.find_shop(user_request, mall_link) + new_count, user_request = self.find_store(user_request, mall_link) count = count + new_count user_request = self.start_again() LOG.info(str(user_request)) @@ -361,7 +364,7 @@ def _start_mall_parser_prompt(self, message): LOG.info('Prompting Mall parsing start') self.make_active() if message is not None: - LOG.info('new message'+str(message)) + LOG.info('new message' + str(message)) user_request, mall_link = self.user_request_handling(message) LOG.info(mall_link) if user_request is not None: @@ -374,7 +377,6 @@ def _start_mall_parser_prompt(self, message): self.speak_dialog('finished') else: return - def create_skill(): diff --git a/locale/en-us/dialog/en/another_shop.dialog b/locale/en-us/dialog/en/another_shop.dialog deleted file mode 100644 index be4fbfd..0000000 --- a/locale/en-us/dialog/en/another_shop.dialog +++ /dev/null @@ -1 +0,0 @@ -What shop you are looking for? \ No newline at end of file diff --git a/locale/en-us/dialog/en/another_store.dialog b/locale/en-us/dialog/en/another_store.dialog new file mode 100644 index 0000000..0967824 --- /dev/null +++ b/locale/en-us/dialog/en/another_store.dialog @@ -0,0 +1 @@ +What store you are looking for? \ No newline at end of file diff --git a/locale/en-us/dialog/en/closed_now.dialog b/locale/en-us/dialog/en/closed_now.dialog index d1c345b..197d364 100644 --- a/locale/en-us/dialog/en/closed_now.dialog +++ b/locale/en-us/dialog/en/closed_now.dialog @@ -1 +1 @@ -{{shop_name}} is closed now. It opens at {{open_time}}. +{{store_name}} is closed now. It opens at {{open_time}}. diff --git a/locale/en-us/dialog/en/closing_minutes.dialog b/locale/en-us/dialog/en/closing_minutes.dialog index 4075ad7..05eee31 100644 --- a/locale/en-us/dialog/en/closing_minutes.dialog +++ b/locale/en-us/dialog/en/closing_minutes.dialog @@ -1 +1 @@ -{{shop_name}} is open now. It closes in {{wait_min}} minutes. +{{store_name}} is open now. It closes in {{wait_min}} minutes. diff --git a/locale/en-us/dialog/en/found_shop.dialog b/locale/en-us/dialog/en/found_store.dialog similarity index 100% rename from locale/en-us/dialog/en/found_shop.dialog rename to locale/en-us/dialog/en/found_store.dialog diff --git a/locale/en-us/dialog/en/no_shop_on_level.dialog b/locale/en-us/dialog/en/no_store_on_level.dialog similarity index 100% rename from locale/en-us/dialog/en/no_shop_on_level.dialog rename to locale/en-us/dialog/en/no_store_on_level.dialog diff --git a/locale/en-us/dialog/en/no_shop_request.dialog b/locale/en-us/dialog/en/no_store_request.dialog similarity index 100% rename from locale/en-us/dialog/en/no_shop_request.dialog rename to locale/en-us/dialog/en/no_store_request.dialog diff --git a/locale/en-us/dialog/en/open_now.dialog b/locale/en-us/dialog/en/open_now.dialog index 3421d4c..a4aa479 100644 --- a/locale/en-us/dialog/en/open_now.dialog +++ b/locale/en-us/dialog/en/open_now.dialog @@ -1 +1 @@ -{{shop_name}} is open. \ No newline at end of file +{{store_name}} is open. \ No newline at end of file diff --git a/locale/en-us/dialog/en/opening_hours.dialog b/locale/en-us/dialog/en/opening_hours.dialog deleted file mode 100644 index 3bcb8ce..0000000 --- a/locale/en-us/dialog/en/opening_hours.dialog +++ /dev/null @@ -1 +0,0 @@ -{{shop_name}} is closed now. Opens in {{wait_h}} hour and {{wait_min}} minutes' \ No newline at end of file diff --git a/locale/en-us/dialog/en/opening_minutes.dialog b/locale/en-us/dialog/en/opening_minutes.dialog deleted file mode 100644 index 9bc6ef2..0000000 --- a/locale/en-us/dialog/en/opening_minutes.dialog +++ /dev/null @@ -1 +0,0 @@ -{{shop_name}} is closed now. It opens in {{wait_min}} minutes. diff --git a/locale/en-us/dialog/en/shop_by_floor.dialog b/locale/en-us/dialog/en/store_by_floor.dialog similarity index 100% rename from locale/en-us/dialog/en/shop_by_floor.dialog rename to locale/en-us/dialog/en/store_by_floor.dialog diff --git a/locale/en-us/dialog/en/shop_not_found.dialog b/locale/en-us/dialog/en/store_not_found.dialog similarity index 100% rename from locale/en-us/dialog/en/shop_not_found.dialog rename to locale/en-us/dialog/en/store_not_found.dialog diff --git a/locale/en-us/dialog/en/time_before_closing.dialog b/locale/en-us/dialog/en/time_before_closing.dialog new file mode 100644 index 0000000..112f3dd --- /dev/null +++ b/locale/en-us/dialog/en/time_before_closing.dialog @@ -0,0 +1 @@ +{{store_name}} is open now. Closes in {{duration}}.' \ No newline at end of file diff --git a/locale/en-us/dialog/en/waiting_for_opening.dialog b/locale/en-us/dialog/en/waiting_for_opening.dialog new file mode 100644 index 0000000..2fb08e8 --- /dev/null +++ b/locale/en-us/dialog/en/waiting_for_opening.dialog @@ -0,0 +1 @@ +{{store_name}} is closed now. Opens in {{duration}}.' \ No newline at end of file diff --git a/request_handling.py b/request_handling.py index 049e56a..9dbad87 100644 --- a/request_handling.py +++ b/request_handling.py @@ -49,13 +49,13 @@ class RequestHandler(): def find_cached_stores(user_request: str, url, file_path): """ - Check shop name existence in cache keys + Check store name existence in cache keys Args: - user_request (str): shop from user's message + user_request (str): store from user's message Returns: if file is empty -> None, {} - if shop wasn't found -> None, read data - if shop found -> store_info (list), read data + if store wasn't found -> None, read data + if store found -> store_info (list), read data Examples: [ {"name": "ABS stores", "time": "8am-10pm", "location": "1 level"}, @@ -76,21 +76,21 @@ def find_cached_stores(user_request: str, url, file_path): LOG.info(f'found key {found_key}') if len(found_key) >=1 : store_name = str(found_key[0]) - LOG.info(f'Shop exists {data[store_name]}') + LOG.info(f'Store exists {data[store_name]}') return data[store_name], data else: - LOG.info("Shop doesn't exist in cache") + LOG.info("Store doesn't exist in cache") return None, data def caching_stores_in_mall(file_path, url): """ Creates caching file in the current class. Creates empty dictionary for cache. Parses - all shops info. Creates dict key from shop - name. Value list of dicts with current shop + all stores info. Creates dict key from store + name. Value list of dicts with current store info. - If shop name already exists in created dict - append current shop dict to existing + If store name already exists in created dict + append current store dict to existing list. Writes created dict to created JSON file. Args: @@ -104,22 +104,22 @@ def caching_stores_in_mall(file_path, url): """ caching_file = file_path+'/cached_stores.json' LOG.info(f'caching_file {caching_file}') - shop_cache = {} + store_cache = {} soup = parse(url) - for shop in soup.find_all(attrs={"class": "directory-tenant-card"}): - logo = shop.find_next("img").get('src') - info = shop.find_next(attrs={"class": "tenant-info-container"}) + for store in soup.find_all(attrs={"class": "directory-tenant-card"}): + logo = store.find_next("img").get('src') + info = store.find_next(attrs={"class": "tenant-info-container"}) name = info.find_next(attrs={"class": "tenant-info-row"}).text.strip().strip('\n') hours = info.find_next(attrs={"class": "tenant-hours-container"}).text.strip('\n') location = info.find_next(attrs={"tenant-location-container"}).text.strip('\n') - shop_data = {'name': name, 'hours': hours, 'location': location, 'logo': logo} - if name in shop_cache.keys(): - shop_cache[name].append(shop_data) + store_data = {'name': name, 'hours': hours, 'location': location, 'logo': logo} + if name in store_cache.keys(): + store_cache[name].append(store_data) else: - shop_cache[name] = [shop_data] + store_cache[name] = [store_data] with open(caching_file, 'w+') as outfile: - json.dump(shop_cache, outfile, ensure_ascii=False) + json.dump(store_cache, outfile, ensure_ascii=False) os.chmod(caching_file, 777) LOG.info("Created mall's cache") @@ -167,7 +167,7 @@ def location_format(location): formats them to numeral words. Args: location (str): location info - from shops info + from stores info Returns: if digits were found: pronounced (str): utterance with @@ -186,32 +186,32 @@ def location_format(location): else: return location -def shop_selection_by_floors(user_request, found_shops): +def store_selection_by_floors(user_request, found_stores): """ - If there are several shops in found shops list - and user agrees to select shop by floor. + If there are several stores in found stores list + and user agrees to select store by floor. Finds all digits in store's location and formats them to ordinal and cardinal numerals. Matches formated numerals with user's request. - If shop was found appends it to the new found + If store was found appends it to the new found list. Args: user_request (str): floor from user - found_shops (list): found shops on user's + found_stores (list): found stores on user's request Returns: - shops_by_floor (list): shops that was found by floor + stores_by_floor (list): stores that was found by floor """ - shops_by_floor = [] - for shop in found_shops: - numbers = re.findall(r'\d+', shop['location']) + stores_by_floor = [] + for store in found_stores: + numbers = re.findall(r'\d+', store['location']) if len(numbers) > 0: numbers = numbers[0] num = pronounce_number(int(numbers), ordinals=False) num_ordinal = pronounce_number(int(numbers), ordinals=True) if num in user_request or num_ordinal in user_request: - shops_by_floor.append(shop) - return shops_by_floor + stores_by_floor.append(store) + return stores_by_floor def parse(url): headers = { @@ -227,10 +227,10 @@ def parse(url): LOG.info("Failed url parsing") -def get_shop_data(url, user_request, file_path): +def get_store_data(url, user_request, file_path): """ Check existence of user's request store in cache - if shop was found returns list with shop info, + if store was found returns list with store info, else does parsing of mall's web-page. Matches the name of existing stores with user's request. If store was found, returns list with @@ -241,15 +241,15 @@ def get_shop_data(url, user_request, file_path): url (str): mall link from hardcoded in init.py user_request (str): utterance from stt parsing Returns: - : found_shops (list): found shops' info + : found_stores (list): found stores' info """ # search for store existence in cache LOG.info(file_path) - found_shops, data = find_cached_stores(user_request, url, file_path) - LOG.info(found_shops) - if found_shops: - LOG.info(f"found_shops: {found_shops}") - return found_shops + found_stores, data = find_cached_stores(user_request, url, file_path) + LOG.info(found_stores) + if found_stores: + LOG.info(f"found_stores: {found_stores}") + return found_stores else: return [] diff --git a/requirements/test_requirements.txt b/requirements/test_requirements.txt index 55b033e..615fac9 100644 --- a/requirements/test_requirements.txt +++ b/requirements/test_requirements.txt @@ -1 +1,2 @@ +mock pytest \ No newline at end of file diff --git a/test/test_skill.py b/test/test_skill.py index 411ad8f..f200fdf 100644 --- a/test/test_skill.py +++ b/test/test_skill.py @@ -81,38 +81,39 @@ def test_en_skill_init(self): self.skill.gui._pages2uri = Mock() self.skill._start_mall_parser_prompt( Message('test', {'utterance': 'find ABC stores', - 'shop': 'ABC stores', - 'lang': 'en-us'}, - {'context_key': 'MallParsing'}) + 'store': 'ABC stores', + 'lang': 'en-us'}, + {'context_key': 'MallParsing'}) ) - + message = Message('test', {'utterance': 'find ABC stores', - 'shop': 'ABC stores', + 'store': 'ABC stores', 'lang': 'en-us'}, {'context_key': 'MallParsing'}) self.skill.user_request_handling(message) def test_en_time_extraction(self): - shop_info = [{'name': 'ABC Stores', 'hours': '9am – 9pm', 'location': 'Street Level 1, near Centerstage', 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937914061-abcstores.png'}, - {'name': 'ABC Stores', 'hours': '10am – 8pm', 'location': 'Street Level 1, in the Ewa Wing', 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937946329-abcstores.png'}] + store_info = [{'name': 'ABC Stores', 'hours': '9am – 9pm', 'location': 'Street Level 1, near Centerstage', + 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937914061-abcstores.png'}, + {'name': 'ABC Stores', 'hours': '10am – 8pm', 'location': 'Street Level 1, in the Ewa Wing', + 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937946329-abcstores.png'}] day_time, hour, min = ['10:15', 'am'], 10, 15 - result_shops = self.skill.open_shops_search(shop_info, day_time, hour, min) - self.assertEqual(shop_info, result_shops) + result_stores = self.skill.open_stores_search(store_info, day_time, hour, min) + self.assertEqual(store_info, result_stores) day_time, hour, min = ['9:15', 'am'], 9, 15 - result_shops = self.skill.open_shops_search(shop_info, day_time, hour, min) - self.assertEqual(shop_info[0], result_shops[0]) - - # def test_en_time_extraction(self): - # shop_info = [{'name': 'ABC Stores', 'hours': '9am – 9pm', 'location': 'Street Level 1, near Centerstage', 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937914061-abcstores.png'}, - # {'name': 'ABC Stores', 'hours': '10am – 8pm', 'location': 'Street Level 1, in the Ewa Wing', 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937946329-abcstores.png'}, - # {'name': 'ABC Stores', 'hours': '10am – 9pm', 'location': 'Street Level 1, in the Ewa Wing', 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937946329-abcstores.png'}] - - # day_time, hour, min = ['9:15', 'pm'], 9, 15 - # print(self.skill.time_calculation(shop_info, False, day_time, hour, min)) - - # day_time, hour, min = ['8:15', 'pm'], 8, 15 - # print(self.skill.time_calculation(shop_info, False, day_time, hour, min)) + result_stores = self.skill.open_stores_search(store_info, day_time, hour, min) + self.assertEqual(store_info[0], result_stores[0]) + + def test_en_hours_extraction(self): + store_info = [{'name': 'ABC Stores', 'hours': '9am – 9pm', 'location': 'Street Level 1, near Centerstage', + 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937914061-abcstores.png'}, + {'name': 'ABC Stores', 'hours': '10am – 8pm', 'location': 'Street Level 1, in the Ewa Wing', + 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937946329-abcstores.png'}] + day_time, hour, min = ['6:15', 'am'], 6, 15 + open = False + waiting_time = self.skill.time_calculation(store_info, open, day_time, hour, min) + print(waiting_time) if __name__ == '__main__': From 46a7a240ea65171c23822ac799b2480aa5d532b6 Mon Sep 17 00:00:00 2001 From: NeonMariia Date: Mon, 14 Nov 2022 09:37:50 -0500 Subject: [PATCH 16/44] time processing changes --- __init__.py | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/__init__.py b/__init__.py index 7f53354..8225fd4 100644 --- a/__init__.py +++ b/__init__.py @@ -133,7 +133,7 @@ def speak_stores(self, store_info): hours = re.sub('(\d+)am.+(\d+)pm', r'from \1 A M to \2 P M', store['hours']) self.speak_dialog('found_store', {"name": store['name'], "hours": hours, "location": location}) LOG.info({"name": store['name'], "hours": hours, "location": location}) - #self.gui.show_image(store['logo'], caption=f'{hours} {location}', title=store['name']) + self.gui.show_image(store['logo'], caption=f'{hours} {location}', title=store['name']) def location_selection(self, store_info): """ @@ -147,7 +147,7 @@ def location_selection(self, store_info): Returns: 3, None (to ask for another store info) """ - LOG.info(f"Shop by location selection {store_info}") + LOG.info(f"store by location selection {store_info}") floor = self.get_response('which_floor') stores = store_selection_by_floors(floor, store_info) if stores: @@ -211,7 +211,7 @@ def time_calculation(self, store_info, open, day_time, hour, min): Examples: work time 9am-10pm user's time 8am - Prompt: 'Shop is closed now. Opens in 1 hour' + Prompt: 'store is closed now. Opens in 1 hour' """ for store in store_info: work_time = store['hours'] @@ -238,16 +238,12 @@ def time_calculation(self, store_info, open, day_time, hour, min): self.speak_stores([store]) else: if day_time[1] == 'am' and hour < open_time: - if wait_h == 0: - LOG.info(f'{store_name} is closed now. Opens in {wait_min} minutes') - self.speak_dialog('opening_minutes', {"store_name": store_name, "wait_min": wait_min}) - else: - duration = wait_h * 3600 + wait_min * 60 - formated_duration = nice_duration(duration, lang=str(self.request_lang), speech=True) - LOG.info(f'{store_name} is closed now. Opens in {formated_duration} ') - self.speak_dialog('waiting_for_opening', {"store_name": store_name, 'duration': formated_duration}) + duration = wait_h * 3600 + wait_min * 60 + formated_duration = nice_duration(duration, lang=str(self.request_lang), speech=True) + LOG.info(f'{store_name} is closed now. store opens in {formated_duration}') + self.speak_dialog('waiting_for_opening', {"store_name": store_name, 'duration': formated_duration}) elif hour >= close_time: - LOG.info(f'{store_name} is closed now. Shop opens at {open_time}') + LOG.info(f'{store_name} is closed now. store opens at {open_time}') self.speak_dialog('closed_now', {'store_name': store_name, 'open_time': open_time}) LOG.info([store]) self.speak_stores([store]) @@ -269,7 +265,7 @@ def stores_by_time_selection(self, store_info): of open stores is 0) """ - LOG.info(f"Shop by time selection {store_info}") + LOG.info(f"store by time selection {store_info}") day_time, hour, min = curent_time_extraction() # day_time, hour, min = ['11:15', 'pm'], 11, 15 open_stores = self.open_stores_search(store_info, day_time, hour, min) From 3bd5a45d8a7c989263ffd1edd04f91d22273f521 Mon Sep 17 00:00:00 2001 From: NeonMariia Date: Wed, 16 Nov 2022 07:09:54 -0500 Subject: [PATCH 17/44] required fixes, gui mock setup --- __init__.py | 12 ++++++------ test/test_skill.py | 34 +++++++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/__init__.py b/__init__.py index 8225fd4..ee786ad 100644 --- a/__init__.py +++ b/__init__.py @@ -34,18 +34,18 @@ location_format, \ curent_time_extraction import re -import lingua_franca from lingua_franca.format import nice_duration -lingua_franca.load_language('en') - class DirectorySkill(NeonSkill): def __init__(self): super(DirectorySkill, self).__init__(name="DirectorySkill") self.url = "https://www.alamoanacenter.com/en/directory/" - self.request_lang = self.lang.split('-')[0] + + @property + def request_lang(self): + return self.lang.split('-')[0] def initialize(self): # When first run or prompt not dismissed, wait for load and prompt user @@ -267,7 +267,6 @@ def stores_by_time_selection(self, store_info): """ LOG.info(f"store by time selection {store_info}") day_time, hour, min = curent_time_extraction() - # day_time, hour, min = ['11:15', 'pm'], 11, 15 open_stores = self.open_stores_search(store_info, day_time, hour, min) if len(open_stores) >= 1: return self.time_calculation(open_stores, True, day_time, hour, min) @@ -316,10 +315,11 @@ def find_store(self, user_request, mall_link): LOG.info(f"I found {len(store_info)} stores") LOG.info(f"store list: {store_info}") if len(store_info) == 0: - user_request = self.get_response('store_not_found') + user_request = self.get_response('store_not_found', {"store_name": user_request}) return 1, user_request elif len(store_info) > 1: self.speak_dialog('more_than_one') + # ask for the way of selection: time, location, nothing sorting_selection = self.get_response('choose_selection') if sorting_selection: diff --git a/test/test_skill.py b/test/test_skill.py index f200fdf..b542d30 100644 --- a/test/test_skill.py +++ b/test/test_skill.py @@ -35,9 +35,11 @@ from ovos_utils.messagebus import FakeBus from mycroft.skills.skill_loader import SkillLoader - from mycroft_bus_client import Message +import lingua_franca +lingua_franca.load_language('en') + class TestSkill(unittest.TestCase): @@ -63,22 +65,39 @@ def setUpClass(cls) -> None: # Override speak and speak_dialog to test passed arguments cls.skill.speak = Mock() cls.skill.speak_dialog = Mock() - - # TODO: Put any skill method overrides here + def setUp(self): + + class MockGui: + def __init__(self): + self._data = dict() + self.show_image = Mock() + + def __setitem__(self, key, value): + self._data[key] = value + + def __getitem__(self, item): + return self._data[item] + + @staticmethod + def clear(): + pass + self.skill.speak.reset_mock() self.skill.speak_dialog.reset_mock() - # TODO: Put any cleanup here that runs before each test case + mock_gui = MockGui() + self.skill.gui = mock_gui + @classmethod def tearDownClass(cls) -> None: shutil.rmtree(cls.test_fs) def test_en_skill_init(self): + self.skill.ask_yesno = Mock(return_value="yes") - self.skill.gui._pages2uri = Mock() self.skill._start_mall_parser_prompt( Message('test', {'utterance': 'find ABC stores', 'store': 'ABC stores', @@ -97,6 +116,7 @@ def test_en_time_extraction(self): 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937914061-abcstores.png'}, {'name': 'ABC Stores', 'hours': '10am – 8pm', 'location': 'Street Level 1, in the Ewa Wing', 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937946329-abcstores.png'}] + day_time, hour, min = ['10:15', 'am'], 10, 15 result_stores = self.skill.open_stores_search(store_info, day_time, hour, min) self.assertEqual(store_info, result_stores) @@ -110,10 +130,10 @@ def test_en_hours_extraction(self): 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937914061-abcstores.png'}, {'name': 'ABC Stores', 'hours': '10am – 8pm', 'location': 'Street Level 1, in the Ewa Wing', 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937946329-abcstores.png'}] + day_time, hour, min = ['6:15', 'am'], 6, 15 open = False - waiting_time = self.skill.time_calculation(store_info, open, day_time, hour, min) - print(waiting_time) + self.skill.time_calculation(store_info, open, day_time, hour, min) if __name__ == '__main__': From 92fda95a2e942e2a190d5b3e56c3bda2f19540b8 Mon Sep 17 00:00:00 2001 From: NeonMariia Date: Wed, 16 Nov 2022 07:17:01 -0500 Subject: [PATCH 18/44] changes in intent file --- locale/en-us/run_mall_parser.intent | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/locale/en-us/run_mall_parser.intent b/locale/en-us/run_mall_parser.intent index ccbf4d9..3f4878b 100644 --- a/locale/en-us/run_mall_parser.intent +++ b/locale/en-us/run_mall_parser.intent @@ -1,8 +1,8 @@ -where (is|are|can i find) {shop} -where (is|are) {shop} located -i am looking for {shop} -location of {shop} -where {shop} -show {shop} -show me {shop} -find {shop} \ No newline at end of file +where (is|are|can i find) {store} +where (is|are) {store} located +i am looking for {store} +location of {store} +where {store} +show {store} +show me {store} +find {store} \ No newline at end of file From ff9ab391ea3b560e416283dd2f66d202020d09f0 Mon Sep 17 00:00:00 2001 From: NeonMariia Date: Fri, 18 Nov 2022 11:53:10 -0500 Subject: [PATCH 19/44] time bug fixes --- __init__.py | 13 +++++++++---- test/test_skill.py | 12 ++++++------ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/__init__.py b/__init__.py index ee786ad..6e7f075 100644 --- a/__init__.py +++ b/__init__.py @@ -130,7 +130,8 @@ def speak_stores(self, store_info): for store in store_info: LOG.info(store) location = location_format(store['location']) - hours = re.sub('(\d+)am.+(\d+)pm', r'from \1 A M to \2 P M', store['hours']) + hours = re.sub('(\d+)\:*(\d*)am.+(\d+)pm', r'from \1 \2 A M to \3 P M', store['hours']) + LOG.info(f'changed hours {hours}') self.speak_dialog('found_store', {"name": store['name'], "hours": hours, "location": location}) LOG.info({"name": store['name'], "hours": hours, "location": location}) self.gui.show_image(store['logo'], caption=f'{hours} {location}', title=store['name']) @@ -170,12 +171,16 @@ def open_stores_search(self, store_info, day_time, hour, min): open_stores = [] LOG.info(f"User's time {day_time, hour, min}") for store in store_info: - parse_time = re.findall(r'(\d+)+[am|pm]', store['hours']) + parse_time = re.findall(r'(\d+\:*\d*)+[am|pm]', store['hours']) LOG.info(f'Parsed time {parse_time}') - open_time = int(parse_time[0]) + open_hour_mins = re.findall(r'(\d+)', parse_time[0]) + LOG.info(f'Parsed hour {open_hour_mins}') + open_time = int(open_hour_mins[0]) + open_minutes = int(open_hour_mins[1]) close_time = int(parse_time[1]) if open_time <= hour < close_time: - open_stores.append(store) + if open_minutes >= min: + open_stores.append(store) elif day_time[1] == 'am' and open_time <= hour: open_stores.append(store) return open_stores diff --git a/test/test_skill.py b/test/test_skill.py index b542d30..59690d1 100644 --- a/test/test_skill.py +++ b/test/test_skill.py @@ -112,12 +112,12 @@ def test_en_skill_init(self): self.skill.user_request_handling(message) def test_en_time_extraction(self): - store_info = [{'name': 'ABC Stores', 'hours': '9am – 9pm', 'location': 'Street Level 1, near Centerstage', + store_info = [{'name': 'ABC Stores', 'hours': '9:30am – 9pm', 'location': 'Street Level 1, near Centerstage', 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937914061-abcstores.png'}, - {'name': 'ABC Stores', 'hours': '10am – 8pm', 'location': 'Street Level 1, in the Ewa Wing', + {'name': 'ABC Stores', 'hours': '10:30am – 8pm', 'location': 'Street Level 1, in the Ewa Wing', 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937946329-abcstores.png'}] - day_time, hour, min = ['10:15', 'am'], 10, 15 + day_time, hour, min = ['10:15', 'am'], 10 , 15 result_stores = self.skill.open_stores_search(store_info, day_time, hour, min) self.assertEqual(store_info, result_stores) @@ -126,12 +126,12 @@ def test_en_time_extraction(self): self.assertEqual(store_info[0], result_stores[0]) def test_en_hours_extraction(self): - store_info = [{'name': 'ABC Stores', 'hours': '9am – 9pm', 'location': 'Street Level 1, near Centerstage', + store_info = [{'name': 'ABC Stores', 'hours': '9:30am – 9pm', 'location': 'Street Level 1, near Centerstage', 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937914061-abcstores.png'}, - {'name': 'ABC Stores', 'hours': '10am – 8pm', 'location': 'Street Level 1, in the Ewa Wing', + {'name': 'ABC Stores', 'hours': '10:30am – 8pm', 'location': 'Street Level 1, in the Ewa Wing', 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937946329-abcstores.png'}] - day_time, hour, min = ['6:15', 'am'], 6, 15 + day_time, hour, min = ['9:15', 'am'], 9, 15 open = False self.skill.time_calculation(store_info, open, day_time, hour, min) From 500cf7479898147d4c340e42f390e43aa14f8cd3 Mon Sep 17 00:00:00 2001 From: NeonMariia Date: Mon, 21 Nov 2022 12:32:35 -0500 Subject: [PATCH 20/44] time bug fixes --- __init__.py | 68 ++++++++++++++++++++++++++++------------------ test/test_skill.py | 24 ++++++++-------- 2 files changed, 53 insertions(+), 39 deletions(-) diff --git a/__init__.py b/__init__.py index 6e7f075..140152c 100644 --- a/__init__.py +++ b/__init__.py @@ -169,24 +169,37 @@ def open_stores_search(self, store_info, day_time, hour, min): store_info (list): open stores """ open_stores = [] - LOG.info(f"User's time {day_time, hour, min}") + LOG.info(f"User's time {store['hours']}") for store in store_info: - parse_time = re.findall(r'(\d+\:*\d*)+[am|pm]', store['hours']) - LOG.info(f'Parsed time {parse_time}') - open_hour_mins = re.findall(r'(\d+)', parse_time[0]) - LOG.info(f'Parsed hour {open_hour_mins}') - open_time = int(open_hour_mins[0]) - open_minutes = int(open_hour_mins[1]) - close_time = int(parse_time[1]) - if open_time <= hour < close_time: - if open_minutes >= min: + formated_work_time = self.time_normalization(store['hours']) + LOG.info(f'formated_work_time {formated_work_time}') + if day_time[1] == 'am' and formated_work_time[0][0] <= hour: + if formated_work_time[0][1] > min: + open_stores.append(store) + elif day_time[1] == 'pm' and formated_work_time[1][0] <= hour: + if formated_work_time[1][1] > min: open_stores.append(store) - elif day_time[1] == 'am' and open_time <= hour: - open_stores.append(store) return open_stores + def time_normalization(self, work_time): + parse_time = re.findall(r'(\d+\:*\d*)+', work_time) + + open_hour_mins = re.findall(r'(\d+)', parse_time[0]) + open_hour = int(open_hour_mins[0]) + if len(open_hour_mins) > 1: + open_minutes = int(open_hour_mins[1]) + else: + open_minutes = 0 + + close_hour_mins = re.findall(r'(\d+)', parse_time[1]) + close_hour = int(close_hour_mins[0]) + if len(close_hour_mins) > 1: + close_minutes = int(close_hour_mins[1]) + else: + close_minutes = 0 + return ([open_hour, open_minutes], [close_hour, close_minutes]) + def time_calculation(self, store_info, open, day_time, hour, min): - #Todo: add logic if store opens and closes not at am-pm time period """ Calculates time difference between user's current time and store working hours. @@ -195,7 +208,7 @@ def time_calculation(self, store_info, open, day_time, hour, min): many minutes left. Speaks store info. Else speaks corresponging dialog. Speaks store info. - If 'open' argument is False: + If 'closed' argument is False: Speaks corresponding dialog. If user is one hour or less before opening hours speaks how much time is left for waiting. @@ -220,19 +233,19 @@ def time_calculation(self, store_info, open, day_time, hour, min): """ for store in store_info: work_time = store['hours'] - normalized_time = re.findall(r'(\d+)[am|pm]', work_time) - open_time = int(normalized_time[0]) - close_time = int(normalized_time[1]) - LOG.info(f'work_time {work_time}') store_name = store['name'] - parse_time = work_time.split('-') - LOG.info(f'parse_time {parse_time}') + LOG.info(f'Store work time {work_time}') + normalized_time = self.time_normalization(work_time) + LOG.info(f'Normalixed time {normalized_time}') # time left - wait_h = open_time - hour - 1 - wait_min = 60 - min + wait_h_opening = normalized_time[0][0] - hour + wait_min_opening = normalized_time[0][1] - min + + wait_h_closing = normalized_time[1][0] - hour + wait_min_closing = normalized_time[1][1] - min if open: - if day_time[1] == 'pm' and 0 < (close_time - hour) <= 1: - duration = wait_min * 60 + if day_time[1] == 'pm' and 0 <= wait_h_closing < 1: + duration = wait_min_closing * 60 formated_duration = nice_duration(duration, lang=str(self.request_lang), speech=True) LOG.info(f'{store_name} closes in {formated_duration}.') self.speak_dialog('time_before_closing', {"store_name": store_name, "duration": formated_duration}) @@ -242,12 +255,13 @@ def time_calculation(self, store_info, open, day_time, hour, min): LOG.info([store]) self.speak_stores([store]) else: - if day_time[1] == 'am' and hour < open_time: - duration = wait_h * 3600 + wait_min * 60 + if day_time[1] == 'am': + duration = wait_h_opening * 3600 + wait_min_opening * 60 formated_duration = nice_duration(duration, lang=str(self.request_lang), speech=True) LOG.info(f'{store_name} is closed now. store opens in {formated_duration}') self.speak_dialog('waiting_for_opening', {"store_name": store_name, 'duration': formated_duration}) - elif hour >= close_time: + elif hour >= normalized_time[1][0] and wait_min_closing > normalized_time[1][1]: + open_time = work_time.split('-')[0] LOG.info(f'{store_name} is closed now. store opens at {open_time}') self.speak_dialog('closed_now', {'store_name': store_name, 'open_time': open_time}) LOG.info([store]) diff --git a/test/test_skill.py b/test/test_skill.py index 59690d1..188b1ed 100644 --- a/test/test_skill.py +++ b/test/test_skill.py @@ -111,19 +111,19 @@ def test_en_skill_init(self): {'context_key': 'MallParsing'}) self.skill.user_request_handling(message) - def test_en_time_extraction(self): - store_info = [{'name': 'ABC Stores', 'hours': '9:30am – 9pm', 'location': 'Street Level 1, near Centerstage', - 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937914061-abcstores.png'}, - {'name': 'ABC Stores', 'hours': '10:30am – 8pm', 'location': 'Street Level 1, in the Ewa Wing', - 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937946329-abcstores.png'}] + # def test_en_time_extraction(self): + # store_info = [{'name': 'ABC Stores', 'hours': '9:30am – 9:30pm', 'location': 'Street Level 1, near Centerstage', + # 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937914061-abcstores.png'}, + # {'name': 'ABC Stores', 'hours': '10:30am – 8:30pm', 'location': 'Street Level 1, in the Ewa Wing', + # 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937946329-abcstores.png'}] - day_time, hour, min = ['10:15', 'am'], 10 , 15 - result_stores = self.skill.open_stores_search(store_info, day_time, hour, min) - self.assertEqual(store_info, result_stores) + # day_time, hour, min = ['10:15', 'am'], 10 , 15 + # result_stores = self.skill.open_stores_search(store_info, day_time, hour, min) + # self.assertEqual(store_info, result_stores) - day_time, hour, min = ['9:15', 'am'], 9, 15 - result_stores = self.skill.open_stores_search(store_info, day_time, hour, min) - self.assertEqual(store_info[0], result_stores[0]) + # day_time, hour, min = ['9:15', 'am'], 9, 15 + # result_stores = self.skill.open_stores_search(store_info, day_time, hour, min) + # self.assertEqual(store_info[0], result_stores[0]) def test_en_hours_extraction(self): store_info = [{'name': 'ABC Stores', 'hours': '9:30am – 9pm', 'location': 'Street Level 1, near Centerstage', @@ -131,7 +131,7 @@ def test_en_hours_extraction(self): {'name': 'ABC Stores', 'hours': '10:30am – 8pm', 'location': 'Street Level 1, in the Ewa Wing', 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937946329-abcstores.png'}] - day_time, hour, min = ['9:15', 'am'], 9, 15 + day_time, hour, min = ['9:15', 'pm'], 9, 15 open = False self.skill.time_calculation(store_info, open, day_time, hour, min) From f17c3e9c9d7fb5df3dbddb6e12278c9377ed2931 Mon Sep 17 00:00:00 2001 From: NeonMariia Date: Tue, 22 Nov 2022 04:52:54 -0500 Subject: [PATCH 21/44] time fixes --- __init__.py | 20 ++++++++++++++------ test/test_skill.py | 24 ++++++++++++------------ 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/__init__.py b/__init__.py index 140152c..14cf399 100644 --- a/__init__.py +++ b/__init__.py @@ -243,16 +243,24 @@ def time_calculation(self, store_info, open, day_time, hour, min): wait_h_closing = normalized_time[1][0] - hour wait_min_closing = normalized_time[1][1] - min + LOG.info(f'wait_h_closing {wait_h_closing}') + LOG.info(f'wait_min_closing {wait_min_closing}') + LOG.info(f'day_time {day_time[1]}') if open: - if day_time[1] == 'pm' and 0 <= wait_h_closing < 1: - duration = wait_min_closing * 60 + if day_time[1] == 'pm': + if 0 == wait_h_closing and wait_min_closing > 0: + duration = wait_min_closing * 60 + elif wait_h_closing == 1 and wait_min_closing < 0: + wait_min_closing = 60 - min + duration = wait_min_closing * 60 + elif wait_h_closing == 1 and wait_min_closing == 0: + duration = 60 * 60 formated_duration = nice_duration(duration, lang=str(self.request_lang), speech=True) LOG.info(f'{store_name} closes in {formated_duration}.') self.speak_dialog('time_before_closing', {"store_name": store_name, "duration": formated_duration}) else: LOG.info(f'{store_name} is open.') self.speak_dialog('open_now', {'store_name': store_name}) - LOG.info([store]) self.speak_stores([store]) else: if day_time[1] == 'am': @@ -260,11 +268,11 @@ def time_calculation(self, store_info, open, day_time, hour, min): formated_duration = nice_duration(duration, lang=str(self.request_lang), speech=True) LOG.info(f'{store_name} is closed now. store opens in {formated_duration}') self.speak_dialog('waiting_for_opening', {"store_name": store_name, 'duration': formated_duration}) - elif hour >= normalized_time[1][0] and wait_min_closing > normalized_time[1][1]: - open_time = work_time.split('-')[0] + else: + open_time = work_time.split(' – ')[0] + open_time = re.sub('(\d+)\:*(\d*)am', r'\1 \2 A M', open_time) LOG.info(f'{store_name} is closed now. store opens at {open_time}') self.speak_dialog('closed_now', {'store_name': store_name, 'open_time': open_time}) - LOG.info([store]) self.speak_stores([store]) return 3, None diff --git a/test/test_skill.py b/test/test_skill.py index 188b1ed..86e5b07 100644 --- a/test/test_skill.py +++ b/test/test_skill.py @@ -111,19 +111,19 @@ def test_en_skill_init(self): {'context_key': 'MallParsing'}) self.skill.user_request_handling(message) - # def test_en_time_extraction(self): - # store_info = [{'name': 'ABC Stores', 'hours': '9:30am – 9:30pm', 'location': 'Street Level 1, near Centerstage', - # 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937914061-abcstores.png'}, - # {'name': 'ABC Stores', 'hours': '10:30am – 8:30pm', 'location': 'Street Level 1, in the Ewa Wing', - # 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937946329-abcstores.png'}] + def test_en_time_extraction(self): + store_info = [{'name': 'ABC Stores', 'hours': '9:30am – 9:30pm', 'location': 'Street Level 1, near Centerstage', + 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937914061-abcstores.png'}, + {'name': 'ABC Stores', 'hours': '10:30am – 8:30pm', 'location': 'Street Level 1, in the Ewa Wing', + 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937946329-abcstores.png'}] - # day_time, hour, min = ['10:15', 'am'], 10 , 15 - # result_stores = self.skill.open_stores_search(store_info, day_time, hour, min) - # self.assertEqual(store_info, result_stores) + day_time, hour, min = ['10:15', 'am'], 10 , 15 + result_stores = self.skill.open_stores_search(store_info, day_time, hour, min) + self.assertEqual(store_info, result_stores) - # day_time, hour, min = ['9:15', 'am'], 9, 15 - # result_stores = self.skill.open_stores_search(store_info, day_time, hour, min) - # self.assertEqual(store_info[0], result_stores[0]) + day_time, hour, min = ['9:15', 'am'], 9, 15 + result_stores = self.skill.open_stores_search(store_info, day_time, hour, min) + self.assertEqual(store_info[0], result_stores[0]) def test_en_hours_extraction(self): store_info = [{'name': 'ABC Stores', 'hours': '9:30am – 9pm', 'location': 'Street Level 1, near Centerstage', @@ -131,7 +131,7 @@ def test_en_hours_extraction(self): {'name': 'ABC Stores', 'hours': '10:30am – 8pm', 'location': 'Street Level 1, in the Ewa Wing', 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937946329-abcstores.png'}] - day_time, hour, min = ['9:15', 'pm'], 9, 15 + day_time, hour, min = ['10:15', 'pm'], 10, 15 open = False self.skill.time_calculation(store_info, open, day_time, hour, min) From 8511b683db2410ab1c985cc78ceb1ab016c30614 Mon Sep 17 00:00:00 2001 From: NeonMariia Date: Tue, 22 Nov 2022 05:11:08 -0500 Subject: [PATCH 22/44] tests fixes --- __init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/__init__.py b/__init__.py index 14cf399..bc46ec2 100644 --- a/__init__.py +++ b/__init__.py @@ -169,7 +169,6 @@ def open_stores_search(self, store_info, day_time, hour, min): store_info (list): open stores """ open_stores = [] - LOG.info(f"User's time {store['hours']}") for store in store_info: formated_work_time = self.time_normalization(store['hours']) LOG.info(f'formated_work_time {formated_work_time}') From 4c16ab03c346aeedab31c979c28f4cd47303faa4 Mon Sep 17 00:00:00 2001 From: Clary Date: Tue, 29 Nov 2022 15:45:53 -0800 Subject: [PATCH 23/44] Update another_store.dialog --- locale/en-us/dialog/en/another_store.dialog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locale/en-us/dialog/en/another_store.dialog b/locale/en-us/dialog/en/another_store.dialog index 0967824..067e61d 100644 --- a/locale/en-us/dialog/en/another_store.dialog +++ b/locale/en-us/dialog/en/another_store.dialog @@ -1 +1 @@ -What store you are looking for? \ No newline at end of file +What store are you looking for? From 22ebd9ad41143644f058437d65f9fdddc58c9c91 Mon Sep 17 00:00:00 2001 From: Clary Date: Tue, 29 Nov 2022 16:02:50 -0800 Subject: [PATCH 24/44] Update another_store.dialog --- locale/en-us/dialog/en/another_store.dialog | 1 + 1 file changed, 1 insertion(+) diff --git a/locale/en-us/dialog/en/another_store.dialog b/locale/en-us/dialog/en/another_store.dialog index 067e61d..b9c794a 100644 --- a/locale/en-us/dialog/en/another_store.dialog +++ b/locale/en-us/dialog/en/another_store.dialog @@ -1 +1,2 @@ What store are you looking for? + From fc530daeb103d12c24c502307e228511077054c7 Mon Sep 17 00:00:00 2001 From: Clary Date: Tue, 29 Nov 2022 16:03:36 -0800 Subject: [PATCH 25/44] Update open_now.dialog --- locale/en-us/dialog/en/open_now.dialog | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/locale/en-us/dialog/en/open_now.dialog b/locale/en-us/dialog/en/open_now.dialog index a4aa479..180a428 100644 --- a/locale/en-us/dialog/en/open_now.dialog +++ b/locale/en-us/dialog/en/open_now.dialog @@ -1 +1,2 @@ -{{store_name}} is open. \ No newline at end of file +{{store_name}} is open. + From 18c6abdabdb93ccfad7e72d9b5f8ab486493ed63 Mon Sep 17 00:00:00 2001 From: Clary Date: Tue, 29 Nov 2022 16:04:13 -0800 Subject: [PATCH 26/44] Update time_before_closing.dialog --- locale/en-us/dialog/en/time_before_closing.dialog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locale/en-us/dialog/en/time_before_closing.dialog b/locale/en-us/dialog/en/time_before_closing.dialog index 112f3dd..5a9974b 100644 --- a/locale/en-us/dialog/en/time_before_closing.dialog +++ b/locale/en-us/dialog/en/time_before_closing.dialog @@ -1 +1 @@ -{{store_name}} is open now. Closes in {{duration}}.' \ No newline at end of file +{{store_name}} is open now. Closes in {{duration}}.' From 2bb18eb3208f4c1de9986917ff50ab0a422ac33c Mon Sep 17 00:00:00 2001 From: Clary Date: Tue, 29 Nov 2022 16:04:44 -0800 Subject: [PATCH 27/44] Update run_mall_parser.intent --- locale/en-us/run_mall_parser.intent | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locale/en-us/run_mall_parser.intent b/locale/en-us/run_mall_parser.intent index 3f4878b..6d68908 100644 --- a/locale/en-us/run_mall_parser.intent +++ b/locale/en-us/run_mall_parser.intent @@ -5,4 +5,4 @@ location of {store} where {store} show {store} show me {store} -find {store} \ No newline at end of file +find {store} From 4e0e9756b74208fe6c458cb1f9f2fd2f3b452220 Mon Sep 17 00:00:00 2001 From: Clary Date: Tue, 29 Nov 2022 16:05:11 -0800 Subject: [PATCH 28/44] Update waiting_for_opening.dialog --- locale/en-us/dialog/en/waiting_for_opening.dialog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locale/en-us/dialog/en/waiting_for_opening.dialog b/locale/en-us/dialog/en/waiting_for_opening.dialog index 2fb08e8..b1f9410 100644 --- a/locale/en-us/dialog/en/waiting_for_opening.dialog +++ b/locale/en-us/dialog/en/waiting_for_opening.dialog @@ -1 +1 @@ -{{store_name}} is closed now. Opens in {{duration}}.' \ No newline at end of file +{{store_name}} is closed now. Opens in {{duration}}.' From d2c481fe53c20e79e6712feca1bf639bfedf8c85 Mon Sep 17 00:00:00 2001 From: Clary Date: Tue, 29 Nov 2022 16:05:43 -0800 Subject: [PATCH 29/44] Update waiting_for_opening.dialog --- locale/en-us/dialog/en/waiting_for_opening.dialog | 1 + 1 file changed, 1 insertion(+) diff --git a/locale/en-us/dialog/en/waiting_for_opening.dialog b/locale/en-us/dialog/en/waiting_for_opening.dialog index b1f9410..38bf2d3 100644 --- a/locale/en-us/dialog/en/waiting_for_opening.dialog +++ b/locale/en-us/dialog/en/waiting_for_opening.dialog @@ -1 +1,2 @@ {{store_name}} is closed now. Opens in {{duration}}.' + From a06c28429c65914c3cffbcbb1eab72ffcfb20af9 Mon Sep 17 00:00:00 2001 From: NeonMariia Date: Wed, 30 Nov 2022 08:04:22 -0500 Subject: [PATCH 30/44] open store search fixes --- __init__.py | 12 ++++++++++-- locale/en-us/dialog/en/no_store_request.dialog | 2 +- test/test_skill.py | 16 +++++++++++----- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/__init__.py b/__init__.py index bc46ec2..134305b 100644 --- a/__init__.py +++ b/__init__.py @@ -42,6 +42,7 @@ class DirectorySkill(NeonSkill): def __init__(self): super(DirectorySkill, self).__init__(name="DirectorySkill") self.url = "https://www.alamoanacenter.com/en/directory/" + self._speak_timeout = 60 @property def request_lang(self): @@ -169,15 +170,19 @@ def open_stores_search(self, store_info, day_time, hour, min): store_info (list): open stores """ open_stores = [] + LOG.info(f'users_time {day_time, hour, min}') for store in store_info: formated_work_time = self.time_normalization(store['hours']) LOG.info(f'formated_work_time {formated_work_time}') if day_time[1] == 'am' and formated_work_time[0][0] <= hour: if formated_work_time[0][1] > min: open_stores.append(store) - elif day_time[1] == 'pm' and formated_work_time[1][0] <= hour: + elif day_time[1] == 'pm' and formated_work_time[1][0] == hour: if formated_work_time[1][1] > min: open_stores.append(store) + elif day_time[1] == 'pm' and formated_work_time[1][0] > hour: + open_stores.append(store) + LOG.info(f'open stores {open_stores}') return open_stores def time_normalization(self, work_time): @@ -246,6 +251,7 @@ def time_calculation(self, store_info, open, day_time, hour, min): LOG.info(f'wait_min_closing {wait_min_closing}') LOG.info(f'day_time {day_time[1]}') if open: + duration = None if day_time[1] == 'pm': if 0 == wait_h_closing and wait_min_closing > 0: duration = wait_min_closing * 60 @@ -254,6 +260,7 @@ def time_calculation(self, store_info, open, day_time, hour, min): duration = wait_min_closing * 60 elif wait_h_closing == 1 and wait_min_closing == 0: duration = 60 * 60 + if duration: formated_duration = nice_duration(duration, lang=str(self.request_lang), speech=True) LOG.info(f'{store_name} closes in {formated_duration}.') self.speak_dialog('time_before_closing', {"store_name": store_name, "duration": formated_duration}) @@ -292,7 +299,8 @@ def stores_by_time_selection(self, store_info): """ LOG.info(f"store by time selection {store_info}") - day_time, hour, min = curent_time_extraction() + #day_time, hour, min = curent_time_extraction() + day_time, hour, min = ['7:55', 'pm'], 7, 55 open_stores = self.open_stores_search(store_info, day_time, hour, min) if len(open_stores) >= 1: return self.time_calculation(open_stores, True, day_time, hour, min) diff --git a/locale/en-us/dialog/en/no_store_request.dialog b/locale/en-us/dialog/en/no_store_request.dialog index 0718253..fa054b1 100644 --- a/locale/en-us/dialog/en/no_store_request.dialog +++ b/locale/en-us/dialog/en/no_store_request.dialog @@ -1 +1 @@ -Okay. Have a good day! +Okay! diff --git a/test/test_skill.py b/test/test_skill.py index 86e5b07..7dfacd8 100644 --- a/test/test_skill.py +++ b/test/test_skill.py @@ -117,9 +117,9 @@ def test_en_time_extraction(self): {'name': 'ABC Stores', 'hours': '10:30am – 8:30pm', 'location': 'Street Level 1, in the Ewa Wing', 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937946329-abcstores.png'}] - day_time, hour, min = ['10:15', 'am'], 10 , 15 + day_time, hour, min = ['9:00', 'pm'], 9 , 00 result_stores = self.skill.open_stores_search(store_info, day_time, hour, min) - self.assertEqual(store_info, result_stores) + self.assertEqual(store_info[0], result_stores[0]) day_time, hour, min = ['9:15', 'am'], 9, 15 result_stores = self.skill.open_stores_search(store_info, day_time, hour, min) @@ -128,11 +128,17 @@ def test_en_time_extraction(self): def test_en_hours_extraction(self): store_info = [{'name': 'ABC Stores', 'hours': '9:30am – 9pm', 'location': 'Street Level 1, near Centerstage', 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937914061-abcstores.png'}, - {'name': 'ABC Stores', 'hours': '10:30am – 8pm', 'location': 'Street Level 1, in the Ewa Wing', + {'name': 'ABC Stores', 'hours': '10:30am – 8:30pm', 'location': 'Street Level 1, in the Ewa Wing', 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937946329-abcstores.png'}] - day_time, hour, min = ['10:15', 'pm'], 10, 15 - open = False + day_time, hour, min = ['6:00', 'pm'], 6, 00 + result_stores = self.skill.open_stores_search(store_info, day_time, hour, min) + for store in store_info: + if store in result_stores: + open = True + else: + open = False + self.skill.time_calculation(store_info, open, day_time, hour, min) From 0897a33a484f6fcaa94e414464c933d4624b267e Mon Sep 17 00:00:00 2001 From: NeonMariia Date: Wed, 30 Nov 2022 09:29:09 -0500 Subject: [PATCH 31/44] open store search fixes --- __init__.py | 5 +++-- test/test_skill.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/__init__.py b/__init__.py index 134305b..5bf53cd 100644 --- a/__init__.py +++ b/__init__.py @@ -269,6 +269,7 @@ def time_calculation(self, store_info, open, day_time, hour, min): self.speak_dialog('open_now', {'store_name': store_name}) self.speak_stores([store]) else: + LOG.info(f'{store_name} is closed.') if day_time[1] == 'am': duration = wait_h_opening * 3600 + wait_min_opening * 60 formated_duration = nice_duration(duration, lang=str(self.request_lang), speech=True) @@ -299,8 +300,8 @@ def stores_by_time_selection(self, store_info): """ LOG.info(f"store by time selection {store_info}") - #day_time, hour, min = curent_time_extraction() - day_time, hour, min = ['7:55', 'pm'], 7, 55 + day_time, hour, min = curent_time_extraction() + #day_time, hour, min = ['10:55', 'pm'], 10, 55 open_stores = self.open_stores_search(store_info, day_time, hour, min) if len(open_stores) >= 1: return self.time_calculation(open_stores, True, day_time, hour, min) diff --git a/test/test_skill.py b/test/test_skill.py index 7dfacd8..87d3ea2 100644 --- a/test/test_skill.py +++ b/test/test_skill.py @@ -131,7 +131,7 @@ def test_en_hours_extraction(self): {'name': 'ABC Stores', 'hours': '10:30am – 8:30pm', 'location': 'Street Level 1, in the Ewa Wing', 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937946329-abcstores.png'}] - day_time, hour, min = ['6:00', 'pm'], 6, 00 + day_time, hour, min = ['10:00', 'pm'], 10, 00 result_stores = self.skill.open_stores_search(store_info, day_time, hour, min) for store in store_info: if store in result_stores: From b3086db7b7a42f276b304e936dfd50c5c28e2402 Mon Sep 17 00:00:00 2001 From: Clary Date: Wed, 30 Nov 2022 16:51:34 -0800 Subject: [PATCH 32/44] Update more_than_one.dialog --- locale/en-us/dialog/en/more_than_one.dialog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locale/en-us/dialog/en/more_than_one.dialog b/locale/en-us/dialog/en/more_than_one.dialog index a9c36a8..aec13a4 100644 --- a/locale/en-us/dialog/en/more_than_one.dialog +++ b/locale/en-us/dialog/en/more_than_one.dialog @@ -1 +1 @@ -I found more than one store in your request. +I found more than one store location. From 9058a3c2a519250050c109f80b83d22d1768e9c7 Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Wed, 30 Nov 2022 19:14:45 -0800 Subject: [PATCH 33/44] GUI fixes --- __init__.py | 7 ++++++- requirements/requirements.txt | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/__init__.py b/__init__.py index 5bf53cd..51b1dc7 100644 --- a/__init__.py +++ b/__init__.py @@ -135,7 +135,12 @@ def speak_stores(self, store_info): LOG.info(f'changed hours {hours}') self.speak_dialog('found_store', {"name": store['name'], "hours": hours, "location": location}) LOG.info({"name": store['name'], "hours": hours, "location": location}) - self.gui.show_image(store['logo'], caption=f'{hours} {location}', title=store['name']) + if store['logo'] and store['logo'].startswith('http'): + self.gui.show_image(store['logo'], + caption=f'{hours} {location}', + title=store['name'], + fill="PreserveAspectFit", + background_color="#FFFFFF") def location_selection(self, store_info): """ diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 5a2a1bd..d587614 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -4,3 +4,4 @@ bs4 requests ovos-lingua-franca datetime +ovos_utils~=0.0,>=0.0.27a4 From b6c6cd4e18d94a3345bbdd808117f1c2144ae731 Mon Sep 17 00:00:00 2001 From: NeonDaniel Date: Thu, 1 Dec 2022 03:18:50 +0000 Subject: [PATCH 34/44] Update skill.json --- skill.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/skill.json b/skill.json index 1394d21..55a585c 100644 --- a/skill.json +++ b/skill.json @@ -1,6 +1,6 @@ { "title": "{Malls parser skill neon}", - "url": "https://github.com/NeonGeckoCom/skill-directory", + "url": "https://github.com/NeonGeckoCom/mall_guide_skill", "summary": "Skill for mall parsing", "short_description": "Skill for mall parsing", "description": "Skill parses mall web page and returns user name, location and work hours of requested shop, store", @@ -18,6 +18,7 @@ "neon-utils~=1.0", "numpy", "ovos-lingua-franca", + "ovos_utils~=0.0,>=0.0.27a4", "requests" ], "system": {}, @@ -43,7 +44,7 @@ "NeonGeckoCom", "NeonMariia" ], - "skillname": "skill-directory", + "skillname": "mall_guide_skill", "authorname": "NeonGeckoCom", "foldername": null } \ No newline at end of file From 5824fc30df8c70dade4042ed9ecd44af25a59b49 Mon Sep 17 00:00:00 2001 From: NeonMariia Date: Sun, 11 Dec 2022 13:30:04 -0500 Subject: [PATCH 35/44] refactoring time from 12h to 24h format --- __init__.py | 146 +++++++++++++++++++++----------------------- request_handling.py | 58 +++++++++++++----- test/test_skill.py | 45 ++++++++------ 3 files changed, 135 insertions(+), 114 deletions(-) diff --git a/__init__.py b/__init__.py index 51b1dc7..4029d22 100644 --- a/__init__.py +++ b/__init__.py @@ -28,14 +28,20 @@ from neon_utils.skills.neon_skill import NeonSkill, LOG +# from neon_utils.skills.kiosk_skill import KioskSkill from mycroft.skills.core import intent_file_handler from .request_handling import existing_lang_check, get_store_data, \ store_selection_by_floors, \ location_format, \ - curent_time_extraction + left_lime_calculation, \ + time_refactoring + import re from lingua_franca.format import nice_duration +from datetime import datetime +import pytz + class DirectorySkill(NeonSkill): @@ -163,52 +169,73 @@ def location_selection(self, store_info): self.speak_dialog('no_store_on_level') self.speak_stores(store_info) return 3, None + + def stores_by_time_selection(self, store_info): + """ + If user chose to select stores by time or + use like default selection. Gets user's + current time. Selects open stores. + Args: + store_info (list): found stores on user's + request + Returns: + time_calculation function with True + in 'open' argument. + time_calculation function with False + in 'open' argument. (if list + of open stores is 0) + + """ + LOG.info(f"store by time selection {store_info}") + # user's time + now = datetime.utcnow().replace(tzinfo=pytz.utc).strftime("%H:%M") + # splitting user's time on hour and mins + now_h_m = now.split(':') + LOG.info(f'users_time {now_h_m}') + now_h = int(now_h_m[0]) + now_m = int(now_h_m[1]) + # open stores search + open_stores = self.open_stores_search(store_info, now_h, now_m) + if len(open_stores) >= 1: + return self.time_calculation(open_stores, True, now_h, now_m) + else: + return self.time_calculation(store_info, False, now_h, now_m) - def open_stores_search(self, store_info, day_time, hour, min): + def open_stores_search(self, store_info, now_h, now_m): """ Selects open stores. Collects the list of open stores else return empty list. Args: store_info (list): found stores on user's request + now (str): current user's time Returns: store_info (list): open stores """ open_stores = [] - LOG.info(f'users_time {day_time, hour, min}') + LOG.info(f" user's current time {now_h, now_m}") + for store in store_info: - formated_work_time = self.time_normalization(store['hours']) - LOG.info(f'formated_work_time {formated_work_time}') - if day_time[1] == 'am' and formated_work_time[0][0] <= hour: - if formated_work_time[0][1] > min: + # formating store's work hours + time_splited = store['hours'].split(' – ') + open = time_refactoring(time_splited[0]) + close = time_refactoring(time_splited[1]) + LOG.info(f'formated_work_time {open, close}') + + if now_h == open[0]: + if now_m >= open[1]: open_stores.append(store) - elif day_time[1] == 'pm' and formated_work_time[1][0] == hour: - if formated_work_time[1][1] > min: + elif now_h > open[0]: + open_stores.append(store) + elif now_h == close[0]: + if now_m < close[1]: open_stores.append(store) - elif day_time[1] == 'pm' and formated_work_time[1][0] > hour: + elif now_h < close[0]: open_stores.append(store) LOG.info(f'open stores {open_stores}') return open_stores - def time_normalization(self, work_time): - parse_time = re.findall(r'(\d+\:*\d*)+', work_time) - - open_hour_mins = re.findall(r'(\d+)', parse_time[0]) - open_hour = int(open_hour_mins[0]) - if len(open_hour_mins) > 1: - open_minutes = int(open_hour_mins[1]) - else: - open_minutes = 0 - - close_hour_mins = re.findall(r'(\d+)', parse_time[1]) - close_hour = int(close_hour_mins[0]) - if len(close_hour_mins) > 1: - close_minutes = int(close_hour_mins[1]) - else: - close_minutes = 0 - return ([open_hour, open_minutes], [close_hour, close_minutes]) - - def time_calculation(self, store_info, open, day_time, hour, min): + def time_calculation(self, store_info, open, now_h, now_m): """ Calculates time difference between user's current time and store working hours. @@ -230,9 +257,8 @@ def time_calculation(self, store_info, open, day_time, hour, min): Args: store_info (list): found stores on user's request open (boolean): True - if store is open - day_time (str): user's current day time (am|pm) - hour (int): user's current hour - min (int): user's current minute + now_h (int): user's current hour + now_m (int): user's current minute Returns: 3, None (to ask for another store info) Examples: @@ -241,30 +267,19 @@ def time_calculation(self, store_info, open, day_time, hour, min): Prompt: 'store is closed now. Opens in 1 hour' """ for store in store_info: - work_time = store['hours'] + work_time = store['hours'].split(' – ') store_name = store['name'] + LOG.info(f'Store work time {work_time}') - normalized_time = self.time_normalization(work_time) - LOG.info(f'Normalixed time {normalized_time}') - # time left - wait_h_opening = normalized_time[0][0] - hour - wait_min_opening = normalized_time[0][1] - min + open_time = time_refactoring(work_time[0]) + close_time = time_refactoring(work_time[1]) + LOG.info(f'Normalixed time {open_time, close_time}') - wait_h_closing = normalized_time[1][0] - hour - wait_min_closing = normalized_time[1][1] - min - LOG.info(f'wait_h_closing {wait_h_closing}') - LOG.info(f'wait_min_closing {wait_min_closing}') - LOG.info(f'day_time {day_time[1]}') if open: duration = None - if day_time[1] == 'pm': - if 0 == wait_h_closing and wait_min_closing > 0: - duration = wait_min_closing * 60 - elif wait_h_closing == 1 and wait_min_closing < 0: - wait_min_closing = 60 - min - duration = wait_min_closing * 60 - elif wait_h_closing == 1 and wait_min_closing == 0: - duration = 60 * 60 + if 0 <= (close_time[0] - now_h) <= 1: + LOG.info(f'hour waiting {close_time[0] - now_h}') + duration = left_lime_calculation(now_h, now_m, close_time[0], close_time[1]) if duration: formated_duration = nice_duration(duration, lang=str(self.request_lang), speech=True) LOG.info(f'{store_name} closes in {formated_duration}.') @@ -275,8 +290,8 @@ def time_calculation(self, store_info, open, day_time, hour, min): self.speak_stores([store]) else: LOG.info(f'{store_name} is closed.') - if day_time[1] == 'am': - duration = wait_h_opening * 3600 + wait_min_opening * 60 + if (close_time[0] - now_h) >= 0: + duration = left_lime_calculation(now_h, now_m, close_time[1], close_time[0]) formated_duration = nice_duration(duration, lang=str(self.request_lang), speech=True) LOG.info(f'{store_name} is closed now. store opens in {formated_duration}') self.speak_dialog('waiting_for_opening', {"store_name": store_name, 'duration': formated_duration}) @@ -288,31 +303,6 @@ def time_calculation(self, store_info, open, day_time, hour, min): self.speak_stores([store]) return 3, None - def stores_by_time_selection(self, store_info): - """ - If user chose to select stores by time or - use like default selection. Gets user's - current time. Selects open stores. - Args: - store_info (list): found stores on user's - request - Returns: - time_calculation function with True - in 'open' argument. - time_calculation function with False - in 'open' argument. (if list - of open stores is 0) - - """ - LOG.info(f"store by time selection {store_info}") - day_time, hour, min = curent_time_extraction() - #day_time, hour, min = ['10:55', 'pm'], 10, 55 - open_stores = self.open_stores_search(store_info, day_time, hour, min) - if len(open_stores) >= 1: - return self.time_calculation(open_stores, True, day_time, hour, min) - else: - return self.time_calculation(store_info, False, day_time, hour, min) - def find_store(self, user_request, mall_link): """ When the intent is matched, user_request diff --git a/request_handling.py b/request_handling.py index 9dbad87..a7a390d 100644 --- a/request_handling.py +++ b/request_handling.py @@ -41,6 +41,7 @@ import json from datetime import datetime +import pytz class RequestHandler(): @@ -141,25 +142,48 @@ def existing_lang_check(user_lang: str, url): LOG.info('This language is not supported') return False, link -def curent_time_extraction(): +# time operations + +def change_format(time): + """ + Changing format from 12h to 24h. + Returns: + formated_time (list): [int(hour), int(min)] """ - Defines current time in utc timezone - Format: hour:minutes part of day (1:23 pm) + in_time = datetime.strptime(time, "%I:%M %p") + out_time = datetime.strftime(in_time, "%H:%M") + hour_min = out_time.split(':') + formated_time = [int(hour_min[0]), int(hour_min[1])] + return formated_time +def time_refactoring(time_str): + """ + Adding space detween time and am|pm. + If working time doesn't have mins add them. + Args: + time_str (list): store's work time Returns: - day_time (list): contains splited time - numerals and part of the day - day_time -> ['07:19', 'am'] - hour (int): current hour - min (int): current minute - """ - now = datetime.now().time().strftime("%I:%M %p") - # now = datetime.today().strftime("%H:%M %p") - LOG.info(f'now {now}') - day_time = now.lower().split(' ') - exact_time = day_time[0].split(':') - hour, min = int(exact_time[0]), int(exact_time[1]) - return day_time, hour, min + open_time (list): open_h (int), open_m (int), + close_time (list): close_h (int), close_m (int), + """ + if ':' not in time_str: + time_refactored = re.sub(r'(\d+)(am|pm)', '\g<1>:00 \g<2>', time_str) + else: + time_refactored = re.sub(r'(am|pm)', ' \g<1>', time_str) + new_format = change_format(time_refactored) + return new_format + +def left_lime_calculation(user_h, user_m, work_h, work_m): + if work_m < user_m: + wait_min = user_m - work_m + else: + wait_min = work_m - user_m + wait_h_opening = work_h - user_h + LOG.info(f'Hour difference {wait_h_opening}') + duration = wait_h_opening * 3600 + wait_min * 60 + return duration + +#location operations def location_format(location): """ @@ -213,6 +237,8 @@ def store_selection_by_floors(user_request, found_stores): stores_by_floor.append(store) return stores_by_floor +# mall link parsing + def parse(url): headers = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36' diff --git a/test/test_skill.py b/test/test_skill.py index 87d3ea2..7d5d8ca 100644 --- a/test/test_skill.py +++ b/test/test_skill.py @@ -36,6 +36,9 @@ from mycroft.skills.skill_loader import SkillLoader from mycroft_bus_client import Message +import datetime +from neon_utils.skills.neon_skill import LOG +import pytz import lingua_franca lingua_franca.load_language('en') @@ -111,35 +114,37 @@ def test_en_skill_init(self): {'context_key': 'MallParsing'}) self.skill.user_request_handling(message) - def test_en_time_extraction(self): - store_info = [{'name': 'ABC Stores', 'hours': '9:30am – 9:30pm', 'location': 'Street Level 1, near Centerstage', + + def test_en_open_stores_search(self): + store_info = [{'name': 'ABC Stores', 'hours': '9:30am – 9pm', 'location': 'Street Level 1, near Centerstage', 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937914061-abcstores.png'}, {'name': 'ABC Stores', 'hours': '10:30am – 8:30pm', 'location': 'Street Level 1, in the Ewa Wing', 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937946329-abcstores.png'}] - - day_time, hour, min = ['9:00', 'pm'], 9 , 00 - result_stores = self.skill.open_stores_search(store_info, day_time, hour, min) - self.assertEqual(store_info[0], result_stores[0]) - day_time, hour, min = ['9:15', 'am'], 9, 15 - result_stores = self.skill.open_stores_search(store_info, day_time, hour, min) - self.assertEqual(store_info[0], result_stores[0]) + now_hour, now_min = 10, 00 + result_stores = self.skill.open_stores_search(store_info, now_hour, now_min) + self.assertEqual(result_stores[0], store_info[0]) - def test_en_hours_extraction(self): + def test_en_time_calculation(self): store_info = [{'name': 'ABC Stores', 'hours': '9:30am – 9pm', 'location': 'Street Level 1, near Centerstage', 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937914061-abcstores.png'}, {'name': 'ABC Stores', 'hours': '10:30am – 8:30pm', 'location': 'Street Level 1, in the Ewa Wing', 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937946329-abcstores.png'}] - - day_time, hour, min = ['10:00', 'pm'], 10, 00 - result_stores = self.skill.open_stores_search(store_info, day_time, hour, min) - for store in store_info: - if store in result_stores: - open = True - else: - open = False - - self.skill.time_calculation(store_info, open, day_time, hour, min) + + now_hour, now_min = 9, 30 + open = True + + result = self.skill.time_calculation(store_info, open, now_hour, now_min) + self.assertEqual(result, (3, None)) + + def test_en_stores_by_time_selection(self): + store_info = [{'name': 'ABC Stores', 'hours': '9:30am – 9pm', 'location': 'Street Level 1, near Centerstage', + 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937914061-abcstores.png'}, + {'name': 'ABC Stores', 'hours': '10:30am – 8:30pm', 'location': 'Street Level 1, in the Ewa Wing', + 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937946329-abcstores.png'}] + + result = self.skill.stores_by_time_selection(store_info) + self.assertEqual(result, (3, None)) if __name__ == '__main__': From 5f5916b7b2ce22ceb6373b5f62ca991937d69c8b Mon Sep 17 00:00:00 2001 From: NeonMariia Date: Sun, 11 Dec 2022 14:07:14 -0500 Subject: [PATCH 36/44] files refactoring --- __init__.py | 49 +++--------- location_processing.py | 56 ++++++++++++++ request_handling.py | 142 +++++----------------------------- requirements/requirements.txt | 2 +- test/test_skill.py | 13 ---- time_processing.py | 77 ++++++++++++++++++ 6 files changed, 163 insertions(+), 176 deletions(-) create mode 100644 location_processing.py create mode 100644 time_processing.py diff --git a/__init__.py b/__init__.py index 4029d22..b1d9df3 100644 --- a/__init__.py +++ b/__init__.py @@ -30,11 +30,14 @@ from neon_utils.skills.neon_skill import NeonSkill, LOG # from neon_utils.skills.kiosk_skill import KioskSkill from mycroft.skills.core import intent_file_handler -from .request_handling import existing_lang_check, get_store_data, \ - store_selection_by_floors, \ - location_format, \ - left_lime_calculation, \ - time_refactoring +from .request_handling import existing_lang_check, get_store_data + +from .time_processing import left_lime_calculation, \ + time_refactoring, \ + open_stores_search + +from .location_processing import store_selection_by_floors, \ + location_format import re from lingua_franca.format import nice_duration @@ -195,46 +198,12 @@ def stores_by_time_selection(self, store_info): now_h = int(now_h_m[0]) now_m = int(now_h_m[1]) # open stores search - open_stores = self.open_stores_search(store_info, now_h, now_m) + open_stores = open_stores_search(store_info, now_h, now_m) if len(open_stores) >= 1: return self.time_calculation(open_stores, True, now_h, now_m) else: return self.time_calculation(store_info, False, now_h, now_m) - def open_stores_search(self, store_info, now_h, now_m): - """ - Selects open stores. Collects the list of - open stores else return empty list. - Args: - store_info (list): found stores on user's - request - now (str): current user's time - Returns: - store_info (list): open stores - """ - open_stores = [] - LOG.info(f" user's current time {now_h, now_m}") - - for store in store_info: - # formating store's work hours - time_splited = store['hours'].split(' – ') - open = time_refactoring(time_splited[0]) - close = time_refactoring(time_splited[1]) - LOG.info(f'formated_work_time {open, close}') - - if now_h == open[0]: - if now_m >= open[1]: - open_stores.append(store) - elif now_h > open[0]: - open_stores.append(store) - elif now_h == close[0]: - if now_m < close[1]: - open_stores.append(store) - elif now_h < close[0]: - open_stores.append(store) - LOG.info(f'open stores {open_stores}') - return open_stores - def time_calculation(self, store_info, open, now_h, now_m): """ Calculates time difference between user's current time diff --git a/location_processing.py b/location_processing.py new file mode 100644 index 0000000..cd71314 --- /dev/null +++ b/location_processing.py @@ -0,0 +1,56 @@ +#location operations +from lingua_franca.format import pronounce_number +import re + + +def location_format(location): + """ + Finds all digits in store's location and + formats them to numeral words. + Args: + location (str): location info + from stores info + Returns: + if digits were found: + pronounced (str): utterance with + pronounced digits + else: + location (str): not changed utterance + Examples: + 'level 1' -> 'level one' + """ + floor = re.findall(r'\d+', location) + if len(floor) > 0: + floor = floor[0] + num = pronounce_number(int(floor), ordinals=False) + pronounced = re.sub(r'\d+', num, location) + return pronounced + else: + return location + +def store_selection_by_floors(user_request, found_stores): + """ + If there are several stores in found stores list + and user agrees to select store by floor. + Finds all digits in store's location and + formats them to ordinal and cardinal numerals. + Matches formated numerals with user's request. + If store was found appends it to the new found + list. + Args: + user_request (str): floor from user + found_stores (list): found stores on user's + request + Returns: + stores_by_floor (list): stores that was found by floor + """ + stores_by_floor = [] + for store in found_stores: + numbers = re.findall(r'\d+', store['location']) + if len(numbers) > 0: + numbers = numbers[0] + num = pronounce_number(int(numbers), ordinals=False) + num_ordinal = pronounce_number(int(numbers), ordinals=True) + if num in user_request or num_ordinal in user_request: + stores_by_floor.append(store) + return stores_by_floor \ No newline at end of file diff --git a/request_handling.py b/request_handling.py index a7a390d..d9edf3f 100644 --- a/request_handling.py +++ b/request_handling.py @@ -32,22 +32,34 @@ from neon_utils.skills.neon_skill import LOG import urllib.request -import lingua_franca -from lingua_franca.format import pronounce_number -lingua_franca.load_language('en') - -import re import os import json -from datetime import datetime -import pytz - class RequestHandler(): caching_file = '' + +def existing_lang_check(user_lang: str, url): + """ + Check existence of user's language + on the mall web-page + Args: + user_lang (str): user's lang in ISO 639-1 + Returns: + bool: True if lang exists + """ + link = url+user_lang+'/directory/' + response = requests.get(link) + if response.status_code == 200: + LOG.info('This language is supported') + return True, link + else: + LOG.info('This language is not supported') + return False, link + +#caching stores' info def find_cached_stores(user_request: str, url, file_path): """ Check store name existence in cache keys @@ -124,121 +136,7 @@ def caching_stores_in_mall(file_path, url): os.chmod(caching_file, 777) LOG.info("Created mall's cache") -def existing_lang_check(user_lang: str, url): - """ - Check existence of user's language - on the mall web-page - Args: - user_lang (str): user's lang in ISO 639-1 - Returns: - bool: True if lang exists - """ - link = url+user_lang+'/directory/' - response = requests.get(link) - if response.status_code == 200: - LOG.info('This language is supported') - return True, link - else: - LOG.info('This language is not supported') - return False, link - -# time operations - -def change_format(time): - """ - Changing format from 12h to 24h. - Returns: - formated_time (list): [int(hour), int(min)] - """ - in_time = datetime.strptime(time, "%I:%M %p") - out_time = datetime.strftime(in_time, "%H:%M") - hour_min = out_time.split(':') - formated_time = [int(hour_min[0]), int(hour_min[1])] - return formated_time - -def time_refactoring(time_str): - """ - Adding space detween time and am|pm. - If working time doesn't have mins add them. - Args: - time_str (list): store's work time - Returns: - open_time (list): open_h (int), open_m (int), - close_time (list): close_h (int), close_m (int), - """ - if ':' not in time_str: - time_refactored = re.sub(r'(\d+)(am|pm)', '\g<1>:00 \g<2>', time_str) - else: - time_refactored = re.sub(r'(am|pm)', ' \g<1>', time_str) - new_format = change_format(time_refactored) - return new_format - -def left_lime_calculation(user_h, user_m, work_h, work_m): - if work_m < user_m: - wait_min = user_m - work_m - else: - wait_min = work_m - user_m - wait_h_opening = work_h - user_h - LOG.info(f'Hour difference {wait_h_opening}') - duration = wait_h_opening * 3600 + wait_min * 60 - return duration - -#location operations - -def location_format(location): - """ - Finds all digits in store's location and - formats them to numeral words. - Args: - location (str): location info - from stores info - Returns: - if digits were found: - pronounced (str): utterance with - pronounced digits - else: - location (str): not changed utterance - Examples: - 'level 1' -> 'level one' - """ - floor = re.findall(r'\d+', location) - if len(floor) > 0: - floor = floor[0] - num = pronounce_number(int(floor), ordinals=False) - pronounced = re.sub(r'\d+', num, location) - return pronounced - else: - return location - -def store_selection_by_floors(user_request, found_stores): - """ - If there are several stores in found stores list - and user agrees to select store by floor. - Finds all digits in store's location and - formats them to ordinal and cardinal numerals. - Matches formated numerals with user's request. - If store was found appends it to the new found - list. - Args: - user_request (str): floor from user - found_stores (list): found stores on user's - request - Returns: - stores_by_floor (list): stores that was found by floor - """ - stores_by_floor = [] - for store in found_stores: - numbers = re.findall(r'\d+', store['location']) - if len(numbers) > 0: - numbers = numbers[0] - num = pronounce_number(int(numbers), ordinals=False) - num_ordinal = pronounce_number(int(numbers), ordinals=True) - if num in user_request or num_ordinal in user_request: - stores_by_floor.append(store) - return stores_by_floor - # mall link parsing - def parse(url): headers = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36' diff --git a/requirements/requirements.txt b/requirements/requirements.txt index d587614..d11fc7d 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -1,5 +1,5 @@ numpy -neon-utils~=1.0 +neon-utils==1.1.3a6 bs4 requests ovos-lingua-franca diff --git a/test/test_skill.py b/test/test_skill.py index 7d5d8ca..16bdd12 100644 --- a/test/test_skill.py +++ b/test/test_skill.py @@ -36,9 +36,6 @@ from mycroft.skills.skill_loader import SkillLoader from mycroft_bus_client import Message -import datetime -from neon_utils.skills.neon_skill import LOG -import pytz import lingua_franca lingua_franca.load_language('en') @@ -114,16 +111,6 @@ def test_en_skill_init(self): {'context_key': 'MallParsing'}) self.skill.user_request_handling(message) - - def test_en_open_stores_search(self): - store_info = [{'name': 'ABC Stores', 'hours': '9:30am – 9pm', 'location': 'Street Level 1, near Centerstage', - 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937914061-abcstores.png'}, - {'name': 'ABC Stores', 'hours': '10:30am – 8:30pm', 'location': 'Street Level 1, in the Ewa Wing', - 'logo': 'https://gizmostorageprod.blob.core.windows.net/tenant-logos/1615937946329-abcstores.png'}] - - now_hour, now_min = 10, 00 - result_stores = self.skill.open_stores_search(store_info, now_hour, now_min) - self.assertEqual(result_stores[0], store_info[0]) def test_en_time_calculation(self): store_info = [{'name': 'ABC Stores', 'hours': '9:30am – 9pm', 'location': 'Street Level 1, near Centerstage', diff --git a/time_processing.py b/time_processing.py new file mode 100644 index 0000000..8deb8a3 --- /dev/null +++ b/time_processing.py @@ -0,0 +1,77 @@ +# time operations +from datetime import datetime +from neon_utils.skills.neon_skill import LOG +import re + +def change_format(time): + """ + Changing format from 12h to 24h. + Returns: + formated_time (list): [int(hour), int(min)] + """ + in_time = datetime.strptime(time, "%I:%M %p") + out_time = datetime.strftime(in_time, "%H:%M") + hour_min = out_time.split(':') + formated_time = [int(hour_min[0]), int(hour_min[1])] + return formated_time + +def time_refactoring(time_str): + """ + Adding space detween time and am|pm. + If working time doesn't have mins add them. + Args: + time_str (list): store's work time + Returns: + open_time (list): open_h (int), open_m (int), + close_time (list): close_h (int), close_m (int), + """ + if ':' not in time_str: + time_refactored = re.sub(r'(\d+)(am|pm)', '\g<1>:00 \g<2>', time_str) + else: + time_refactored = re.sub(r'(am|pm)', ' \g<1>', time_str) + new_format = change_format(time_refactored) + return new_format + +def left_lime_calculation(user_h, user_m, work_h, work_m): + if work_m < user_m: + wait_min = user_m - work_m + else: + wait_min = work_m - user_m + wait_h_opening = work_h - user_h + LOG.info(f'Hour difference {wait_h_opening}') + duration = wait_h_opening * 3600 + wait_min * 60 + return duration + +def open_stores_search(store_info, now_h, now_m): + """ + Selects open stores. Collects the list of + open stores else return empty list. + Args: + store_info (list): found stores on user's + request + now (str): current user's time + Returns: + store_info (list): open stores + """ + open_stores = [] + LOG.info(f" user's current time {now_h, now_m}") + + for store in store_info: + # formating store's work hours + time_splited = store['hours'].split(' – ') + open = time_refactoring(time_splited[0]) + close = time_refactoring(time_splited[1]) + LOG.info(f'formated_work_time {open, close}') + + if now_h == open[0]: + if now_m >= open[1]: + open_stores.append(store) + elif now_h > open[0]: + open_stores.append(store) + elif now_h == close[0]: + if now_m < close[1]: + open_stores.append(store) + elif now_h < close[0]: + open_stores.append(store) + LOG.info(f'open stores {open_stores}') + return open_stores \ No newline at end of file From acd988cfafefa7e05f3883e0c8ec385a82fefc6e Mon Sep 17 00:00:00 2001 From: NeonMariia Date: Sun, 11 Dec 2022 14:15:03 -0500 Subject: [PATCH 37/44] requirements fixes --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index d11fc7d..d587614 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -1,5 +1,5 @@ numpy -neon-utils==1.1.3a6 +neon-utils~=1.0 bs4 requests ovos-lingua-franca From 8f3165af1bfe96b70409005a39aef3551c66eb14 Mon Sep 17 00:00:00 2001 From: NeonMariia Date: Tue, 13 Dec 2022 06:35:48 -0500 Subject: [PATCH 38/44] Kiosk skill integration --- __init__.py | 4 ++-- requirements/requirements.txt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/__init__.py b/__init__.py index b1d9df3..fce57b6 100644 --- a/__init__.py +++ b/__init__.py @@ -28,7 +28,7 @@ from neon_utils.skills.neon_skill import NeonSkill, LOG -# from neon_utils.skills.kiosk_skill import KioskSkill +from neon_utils.skills.kiosk_skill import KioskSkill from mycroft.skills.core import intent_file_handler from .request_handling import existing_lang_check, get_store_data @@ -46,7 +46,7 @@ import pytz -class DirectorySkill(NeonSkill): +class DirectorySkill(KioskSkill): def __init__(self): super(DirectorySkill, self).__init__(name="DirectorySkill") diff --git a/requirements/requirements.txt b/requirements/requirements.txt index d587614..bf588e7 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -1,5 +1,5 @@ numpy -neon-utils~=1.0 +neon-utils[network]==1.1.3a6 bs4 requests ovos-lingua-franca From 695b5f89d661a43f725e4113a71bb43c0b9c9548 Mon Sep 17 00:00:00 2001 From: NeonMariia Date: Wed, 14 Dec 2022 14:01:19 -0500 Subject: [PATCH 39/44] kiosk methods adaptation --- __init__.py | 153 ++++++++++++++---- __pycache__/__init__.cpython-310.pyc | Bin 0 -> 14331 bytes .../location_processing.cpython-310.pyc | Bin 0 -> 1781 bytes __pycache__/request_handling.cpython-310.pyc | Bin 0 -> 5190 bytes __pycache__/time_processing.cpython-310.pyc | Bin 0 -> 2320 bytes locale/en-us/dialog/en/goodbye.dialog | 1 + locale/en-us/dialog/en/greeting.dialog | 1 + .../dialog/en/start_mall_directory.intent | 3 + locale/en-us/dialog/en/timeout.dialog | 1 + test/test_skill.py | 12 +- 10 files changed, 128 insertions(+), 43 deletions(-) create mode 100644 __pycache__/__init__.cpython-310.pyc create mode 100644 __pycache__/location_processing.cpython-310.pyc create mode 100644 __pycache__/request_handling.cpython-310.pyc create mode 100644 __pycache__/time_processing.cpython-310.pyc create mode 100644 locale/en-us/dialog/en/goodbye.dialog create mode 100644 locale/en-us/dialog/en/greeting.dialog create mode 100644 locale/en-us/dialog/en/start_mall_directory.intent create mode 100644 locale/en-us/dialog/en/timeout.dialog diff --git a/__init__.py b/__init__.py index fce57b6..6009b22 100644 --- a/__init__.py +++ b/__init__.py @@ -27,8 +27,11 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -from neon_utils.skills.neon_skill import NeonSkill, LOG +from neon_utils.skills.neon_skill import LOG from neon_utils.skills.kiosk_skill import KioskSkill + +from time import time + from mycroft.skills.core import intent_file_handler from .request_handling import existing_lang_check, get_store_data @@ -57,22 +60,103 @@ def __init__(self): def request_lang(self): return self.lang.split('-')[0] - def initialize(self): - # When first run or prompt not dismissed, wait for load and prompt user - if self.settings.get('prompt_on_start'): - self.bus.once('mycroft.ready', self._start_mall_parser_prompt) - - @intent_file_handler("run_mall_parser.intent") - def start_mall_parser_intent(self, message): - LOG.info(message.data) - self._start_mall_parser_prompt(message) - return - - # @property + @property def mall_link(self): mall_link = 'https://www.alamoanacenter.com/' return self.settings.get("mall_link") or mall_link + @property + def timeout_seconds(self) -> int: + """ + Time in seconds to wait for a user response before timing out + """ + return 60 + + @property + def greeting_dialog(self) -> str: + """ + Specify a dialog to speak on interaction start + """ + return 'greeting' + + @property + def goodbye_dialog(self) -> str: + """ + Specify a dialog to speak when an interaction ends cleanly + """ + return 'goodbye' + + @property + def timeout_dialog(self) -> str: + """ + Specify a dialog to speak when an interaction ends after some timeout + """ + return 'timeout' + + @property + def error_dialog(self) -> str: + """ + Specify a dialog to speak on unhandled errors + """ + return 'unexpected_error' + + def setup_new_interaction(self, message) -> bool: + """ + Override to include skill-specific actions on first user interaction. + This is the first action that could prompt user to input language, etc. + :param message: Message associated with start request + :returns: True if user interaction is supported + """ + if message: + return True + + def handle_new_interaction(self, message): + """ + Override to interact with the user after the greeting message has been + spoken. + :param message: Message associated with start request + """ + self.converse(message) + + def handle_end_interaction(self, message): + """ + Override to do any skill-specific cleanup when a user interaction is + completed. + :param message: Message associated with request triggering end + """ + self.speak_dialog(self.goodbye_dialog) + + def handle_user_utterance(self, message): + """ + Handle any input from a user interacting with the kiosk. + :param message: Message associated with user utterance + """ + user_request, mall_link = self.user_request_handling(message) + if user_request and mall_link: + LOG.info(mall_link) + if self.execute(user_request, mall_link) is not None: + LOG.info('executed') + return + else: + self.handle_end_interaction(message) + else: + self.handle_end_interaction(message) + + # def initialize(self): + # # When first run or prompt not dismissed, wait for load and prompt user + # if self.settings.get('prompt_on_start'): + # self.bus.once('mycroft.ready', self._start_mall_parser_prompt) + + # @intent_file_handler("run_mall_parser.intent") + # def start_mall_parser_intent(self, message): + # LOG.info(message.data) + # self._start_mall_parser_prompt(message) + # return + + @intent_file_handler("start_mall_directory") + def start_interaction(self, message): + super().start_interaction(message) + def user_request_handling(self, message): """ Checks user language existence on mall's web-page @@ -88,12 +172,12 @@ def user_request_handling(self, message): return None, None else: user_request = message.data['store'] - LOG.info(f"{self.mall_link()}") + LOG.info(f"{self.mall_link}") LOG.info(str(self.request_lang)) LOG.info(user_request) - found, link = existing_lang_check(self.request_lang, self.mall_link()) + found, link = existing_lang_check(self.request_lang, self.mall_link) if found: - link = self.mall_link() + self.request_lang + '/directory/' + link = self.mall_link + self.request_lang + '/directory/' LOG.info('new link: ' + link) return user_request, link else: @@ -124,6 +208,7 @@ def start_again(self): elif start_again == "no": self.speak_dialog('no_store_request') else: + self.speak_dialog('unexpected_error') return None @@ -354,24 +439,24 @@ def execute(self, user_request, mall_link): else: return None - def _start_mall_parser_prompt(self, message): - if self.neon_in_request(message): - LOG.info('Prompting Mall parsing start') - self.make_active() - if message is not None: - LOG.info('new message' + str(message)) - user_request, mall_link = self.user_request_handling(message) - LOG.info(mall_link) - if user_request is not None: - if self.execute(user_request, mall_link) is not None: - LOG.info('executed') - return - else: - self.speak_dialog('finished') - else: - self.speak_dialog('finished') - else: - return + # def _start_mall_parser_prompt(self, message): + # if self.neon_in_request(message): + # LOG.info('Prompting Mall parsing start') + # self.make_active() + # if message is not None: + # LOG.info('new message' + str(message)) + # user_request, mall_link = self.user_request_handling(message) + # LOG.info(mall_link) + # if user_request is not None: + # if self.execute(user_request, mall_link) is not None: + # LOG.info('executed') + # return + # else: + # self.speak_dialog('finished') + # else: + # self.speak_dialog('finished') + # else: + # return def create_skill(): diff --git a/__pycache__/__init__.cpython-310.pyc b/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8cb8a09fde258309ac2a00b545714ecf8ee75e4b GIT binary patch literal 14331 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 a{UWEs5xp%N4a+v^3DKUZ{eb?}Fa9rk-7jhY literal 0 HcmV?d00001 diff --git a/__pycache__/location_processing.cpython-310.pyc b/__pycache__/location_processing.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..44746709fd7472b2528adfa161a4536e74507d5a GIT binary patch literal 1781 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 q)b64-w%s9|a!=(eX z(>QNj>7MeLYrO`paD%<(MEOXKoSD~naBMI=?h6?A$4NQL%8?jWx=5@T>Z%ZT_Q%3j zV*j)8E-C$>Y^_UkKn(8cl$DI}zG5fOjExS&k6CGV##ODOTLQ@39n%e9bX|n4aVkM22E_PfE;>nIx$aQrQ!wN`W^ONhw8AG?Svs(xag`sq`@_(`Q*J zQ*K)^PF^Shp)n$nQrNMY>)+F(m6Ve2kbq@2jjgoWHe{0wzP}WziR!Yk+(?qK*uj+D z62ujAZdpKSUKw?^dOFc^U&o%=s1X3u!Om0pNwhulzg0Mdpd)i@1<)u*c9jsF|_-8to) zHNJEs7}lU-x8pb4NpyvNgxhfwlDX2YSa{^_ zl#a*qwP*vZ6Xa2aT!>We1(VZu%QebIpncY&zDnd@QKK6D~V@nl(z4}Ga z!=aI#ez0uzRLP`29jq7@@U~#x=^Hp<)e%P9AelfwWfZpk|8Ca$;2FSzmZH6gcH%Bl ztxsz^pe{gf60{2sHCmrq)p>wiS=k*MmFRT*DI9NZ!Q@@s1az!B13uuJd;n{oJFk$# zUq|Ci*uf1^*u9V+m8vS^+Ge@g?H;jRk`UcFifxHH9XU$K(`aJle)uA4YHH!#qLOv4 T4)GZ#;Nk^Bgzg}`Jm~)m%;;BF literal 0 HcmV?d00001 diff --git a/locale/en-us/dialog/en/goodbye.dialog b/locale/en-us/dialog/en/goodbye.dialog new file mode 100644 index 0000000..79f7f7d --- /dev/null +++ b/locale/en-us/dialog/en/goodbye.dialog @@ -0,0 +1 @@ +Ok. See you later! \ No newline at end of file diff --git a/locale/en-us/dialog/en/greeting.dialog b/locale/en-us/dialog/en/greeting.dialog new file mode 100644 index 0000000..39c1651 --- /dev/null +++ b/locale/en-us/dialog/en/greeting.dialog @@ -0,0 +1 @@ +Hello! How can I help you? \ No newline at end of file diff --git a/locale/en-us/dialog/en/start_mall_directory.intent b/locale/en-us/dialog/en/start_mall_directory.intent new file mode 100644 index 0000000..bc2e93e --- /dev/null +++ b/locale/en-us/dialog/en/start_mall_directory.intent @@ -0,0 +1,3 @@ +start mall directory skill +start mall skill +start mall parsing diff --git a/locale/en-us/dialog/en/timeout.dialog b/locale/en-us/dialog/en/timeout.dialog new file mode 100644 index 0000000..f16450a --- /dev/null +++ b/locale/en-us/dialog/en/timeout.dialog @@ -0,0 +1 @@ +Sorry, but waiting time is over. \ No newline at end of file diff --git a/test/test_skill.py b/test/test_skill.py index 16bdd12..eec8f89 100644 --- a/test/test_skill.py +++ b/test/test_skill.py @@ -55,12 +55,12 @@ def setUpClass(cls) -> None: cls.test_fs = join(dirname(__file__), "skill") if not exists(cls.test_fs): mkdir(cls.test_fs) - + # Override the configuration and fs paths to use the test directory cls.skill.settings_write_path = cls.test_fs cls.skill.file_system.path = cls.test_fs cls.skill._init_settings() - cls.skill.initialize() + # cls.skill.initialize() # Override speak and speak_dialog to test passed arguments cls.skill.speak = Mock() @@ -98,13 +98,7 @@ def tearDownClass(cls) -> None: def test_en_skill_init(self): self.skill.ask_yesno = Mock(return_value="yes") - self.skill._start_mall_parser_prompt( - Message('test', {'utterance': 'find ABC stores', - 'store': 'ABC stores', - 'lang': 'en-us'}, - {'context_key': 'MallParsing'}) - ) - + message = Message('test', {'utterance': 'find ABC stores', 'store': 'ABC stores', 'lang': 'en-us'}, From 67b8408260e970c9640770d1f1a7de9e088197e7 Mon Sep 17 00:00:00 2001 From: NeonMariia Date: Thu, 15 Dec 2022 13:52:55 -0500 Subject: [PATCH 40/44] store name extraction using regex --- __init__.py | 67 +++++++++--------- __pycache__/__init__.cpython-310.pyc | Bin 14331 -> 0 bytes .../location_processing.cpython-310.pyc | Bin 1781 -> 0 bytes __pycache__/request_handling.cpython-310.pyc | Bin 5190 -> 0 bytes __pycache__/time_processing.cpython-310.pyc | Bin 2320 -> 0 bytes locale/en-us/dialog/en/greeting.dialog | 2 +- .../en-us/dialog/en/how_can_i_help_you.dialog | 1 + .../dialog/en/start_mall_directory.intent | 2 + regex/store.rx | 1 + test/test_skill.py | 3 +- 10 files changed, 39 insertions(+), 37 deletions(-) delete mode 100644 __pycache__/__init__.cpython-310.pyc delete mode 100644 __pycache__/location_processing.cpython-310.pyc delete mode 100644 __pycache__/request_handling.cpython-310.pyc delete mode 100644 __pycache__/time_processing.cpython-310.pyc create mode 100644 locale/en-us/dialog/en/how_can_i_help_you.dialog create mode 100644 regex/store.rx diff --git a/__init__.py b/__init__.py index 6009b22..603b0f8 100644 --- a/__init__.py +++ b/__init__.py @@ -31,6 +31,7 @@ from neon_utils.skills.kiosk_skill import KioskSkill from time import time +from neon_utils.message_utils import get_message_user from mycroft.skills.core import intent_file_handler from .request_handling import existing_lang_check, get_store_data @@ -131,7 +132,8 @@ def handle_user_utterance(self, message): Handle any input from a user interacting with the kiosk. :param message: Message associated with user utterance """ - user_request, mall_link = self.user_request_handling(message) + answer = self.get_response('how_can_i_help_you') + user_request, mall_link = self.user_request_handling(message, answer) if user_request and mall_link: LOG.info(mall_link) if self.execute(user_request, mall_link) is not None: @@ -142,22 +144,32 @@ def handle_user_utterance(self, message): else: self.handle_end_interaction(message) - # def initialize(self): - # # When first run or prompt not dismissed, wait for load and prompt user - # if self.settings.get('prompt_on_start'): - # self.bus.once('mycroft.ready', self._start_mall_parser_prompt) - - # @intent_file_handler("run_mall_parser.intent") - # def start_mall_parser_intent(self, message): - # LOG.info(message.data) - # self._start_mall_parser_prompt(message) - # return - @intent_file_handler("start_mall_directory") def start_interaction(self, message): super().start_interaction(message) - def user_request_handling(self, message): + def _extract_store_name(self, utt: str): + """ + Patch the regex bug and try extracting a store name from the utterance + :param utt: string utterance + :return: extracted store name string if found in utterance + """ + rx_file = self.find_resource('store.rx', 'regex') + if rx_file and utt: + with open(rx_file) as f: + for pat in f.readlines(): + pat = pat.strip() + LOG.info(f"Regex pattern: {pat}") + res = re.sub(pat, '\\4', str(utt)) + LOG.info(f"Matched store {res}") + if res: + try: + return res + except IndexError: + pass + return None + + def user_request_handling(self, message, answer): """ Checks user language existence on mall's web-page using existing_lang_check() function. @@ -168,10 +180,15 @@ def user_request_handling(self, message): answer) """ LOG.info(f"Message is {message.data}") - if message.data == {} or message is None: + LOG.info(f"User's greeting answer {answer}") + # extracting store name from user's answer on greeting prompt + user_request = self._extract_store_name(answer) + LOG.info(f"Store in request {user_request}") + + if not user_request: + self.speak('store_not_found') return None, None else: - user_request = message.data['store'] LOG.info(f"{self.mall_link}") LOG.info(str(self.request_lang)) LOG.info(user_request) @@ -439,25 +456,5 @@ def execute(self, user_request, mall_link): else: return None - # def _start_mall_parser_prompt(self, message): - # if self.neon_in_request(message): - # LOG.info('Prompting Mall parsing start') - # self.make_active() - # if message is not None: - # LOG.info('new message' + str(message)) - # user_request, mall_link = self.user_request_handling(message) - # LOG.info(mall_link) - # if user_request is not None: - # if self.execute(user_request, mall_link) is not None: - # LOG.info('executed') - # return - # else: - # self.speak_dialog('finished') - # else: - # self.speak_dialog('finished') - # else: - # return - - def create_skill(): return DirectorySkill() diff --git a/__pycache__/__init__.cpython-310.pyc b/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index 8cb8a09fde258309ac2a00b545714ecf8ee75e4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14331 zcmc&*-H#ksRG`ld6Wejcn`GR{c${olAd|3(i8tAhWD>2tEX-!rsi|8% z)1K<8&aG-srng7C$d-0_2p|wbViRFY2ob>p;t7erfEQko>IDfTq`bhxzMufR{LZ;m z)gLqCBw8fep6aSw_nv$1J>Tctj%H_T8a^+a|5NYBZ)n=T(!==2!o$n>i~kZAp$R?E zy85=R)4dTGU31&ydo!@Q*0#m>R#57ex68OMiE>cs+S_)wx?SbxN>J<0Y|nJ-+x713 z_AIyA!CZHKd%oM)Zt(bOu&})V__biMyR^N;Z8O1gcX@j`dw*v8%xjvci`jdcnDx!O z=Jr`JC+6>I+vh~}rq*nH3T(Beo|8EAh9dCgr#cNZ(k1_cPMmbY-B#e@;_dm~emb}7C#^V%q~8*5;x^6nOyIYZRseV{ z&kekO;3l0YOdB*qOZsisLvKJy7o(mZs)P2b>&|m`%pXTytz2hIE8+~FM3-YyXU1;0JkF>TfbYa}H zw@u#?rm*g5clGTO?m;QOFXO)ASK5ZKMfIMAw>Gy_(NYsL+)^uAhyv7Srf4B5P)ogN zX@~`GnFZWAKv@(^_pI%Cu`JGjUJY?poWu8mSP`rEUi6p5BX@Pi^t`xm&jzezaZx;q zcW1;U;o$qMcuZWz_c`$u@i@L$#1rC4e6NZ%aRuLxh^BZ7-{-~CVjbTXexzC2_C@f; z)pYJgM`EuddC1)05xMgZ-J988d>J>1mgqz6u5sI-UHg!@-W+Nz>>I9@&;YTtB^&5T zTot-qf3UunB)xd^+O>m&gAF%uyOA5Z9=Obx8(!4C=7-lrj={B0U!v=sMyzGOhD z-D-8hPSR?nW?u&BTr2MR?tY7i9QBh=Fb}w;jqhr!R-lRT*hTlFY7gZaBgyQHuC-_?$RqXnASej zZfp0!R}Zj9tF$NP)@S-vnF*3b@`Dxjf=(jOp}Ra^TrS`)txNy?z8^!1(D4Pd{M5ju zVGPbsVKd%u0wd~AbYqNYT|z$s-54w5f!?bQb;fFN>2rvaR(Z>UPPh-@v|~RZ4G^a$ z> z=N8ECbV4Wgy(kp1lSIye+esYg2FG>!u`eCz$Gs?weP_o49B+*5m3`p|XZ?n4%kcWEimFld^*g3B@Vr#gNv`fq*#^bhv@&~Yc% z;1jXDz<0youmF)(cB4q_9QvoPWG?HGE#zCpLM~3xVY1)nuH!oe5~q{l)OEOR5XXt3 zXo$H;9Tm{hO4jm_CFLxmX!F~rE@`sg=Pv1`0*TX?1a9hw%EAi=nidAO7?n2qq5lDx zGVw)=-<`gOI=|0|@?NomX-zfW%Oe5GKXji9dR)iDP?r`7yD&&Yxfk)WK1fCJ@C z0@4Y+ppRSD<5wXr5TTCeC`pM)a@rjkCrT5H3DHIY?bco=cJM#h^RvF0m?e8|;&@R% z5Kd1<-ChQSC++nUhtzW4-SyWUKk-KJHhZpgyH3}SW4zpS-cmOXEK=lk;FbvIpp)z= zDTZ=l9baIxskC6c>D-ciXtwq-%n4VR#a<)_A zUMutuU`z{*vWpF8b7xg7-TL|9@hMq4anLdPnSeryI-Vo?Y4<_H2jm$jmHih5s*~hX zNT@9#60piv0!5FxKFasg*>htkaz8AeP7465)_%`XI_o4RDuBWJ z>IFWS>C5k7#=TA=JG;9+`ST7GdjWY1&O)6{Sf&}|I&J8~b``_NIrA{z)yAp2IyGWq zSJ~|V2xiM|+~jQeu5n}>nL|T9IW*;yiGJT0n#8Plk5=5nvF+>f61@>{l@uG}tuCy>FSG1u(VAz?t3&F!~u_hos-={e2%M*YB_7f7K(DRG=w^G~x z!1wwfD!k}3)C)nE@+O%X$y*?1O|4GYj?zljTmA~#nwE0tzDn=w<6}?q@zOIHcXP)A zmEXZ&c7o?hHazGC{w#gYm@|$kmlKDl%k1Q|*gX_^TrfdfLZ4I){qanRb{Fn;MjyD_ zpXlH}xrEp0f`V4;d=x4sT*XTz-=rPo%eZ_*H;>^maHgdA7>o&YN*F@y#;o?|xJlUe zAL_S_pJ*R53(R?a1Q!%R}oNLjzM=ZP-#UZADa=p)q&UcE2`m zSzn=OK2~g+n>U98ejn^b)|3dc7CQ(2&ea~wTfuStn1%m%Zs1DOY4<~RTu1EvEq3+e z&0@HN&sG$|meO^T>|SQU$lUobz9TR3guVr?=p07L3HFf&jkEH)L&1!5B~IizOtEb8 zoCO?S^T-vV(QX(Y__A4`JebKXJ0=CEZEYc#qZG(sW-O8&)L?6Qu1zPcgb@dGO`C;J zZh}oxi!vrGS*Zy`q=QCTp$kQ!&C*C1<%?)YOYNv1iqsh{Q-rPVCQ{9K8hAyK#v|7 zL$EaT=Y_<$Z;H}zBm!VTVG+}dGDb8>hi2?Zt@LCwbKi8YDxpiL(Yo*EZqw0p|m9B(v#9JQe!BfX#I> zS>P2E<0l}mh0z+Al+qoDnIfqIT0sJ*LWYUn9EPYRD_l+ zt-;(RbyFjZ(gviAk<3k=yasNC9jp>8KtZ26B`ovAz(^RC$eAp1>5NkN?ylPjeyBlby36V{oC%_J6_NS+$=-(jGa{j4;$=2E+y+HXwhCo1uO~``)e0 zEGWfKa;2{#HF;zvCS=7x+Kr9J0~i5T_@$v$m>carl9za2S=ELx5yJimevL9LQ>{8Y zA461EHTj$B`+ix}9_V<|ZdY#Gs*NCvnIX*6$22RTQleSReOS`9_YE-*iEX%ITw)P- z63gZs(~cl$5QPJ{@T|l}e0#IMgQRi-hXwLWDIFz)oW|Kfwh0oB7%YS#K?DWK9E}`z zFR!dISVet^%=a%->hbcX!r;4W^tAT9b?5S4)R!^Z`5Vu9N*PW0?a_z{Z|+40`6>c; z#}AxN7q*YmPDmn-P`NI5r%ak+L((YDl>ljTSQ*ApA;jS+Dc&i`Awih_Ovj0-og+F} zx$>@fy7}(rQ}}+W>2^1s=7wH(u)=QVyU#lBe$~0|yhZWyyU#iAIB%sTUio0ogZH%y zb;gfQIy1I^asfQpH2F)ugM0ZlF0eb%Zj@S-F#Jq+(uH>*MZUb_Uk4$)$Qq{U>&EF|@z`U9))>p8j#@#(~>;u-EA{}Z~#4lZ`Brq}gF2=I!27XRw_ zSJn;uEC09gL+d|}rCrCNOi1!X)ImyuB@GZ6wKW z9+l*A2ie7v`^V!_2HQgh&Uak=#XcfeH^>2*{4- z%LF>G7{`T}4F~h8zT6FR&F#uvgt)Nm7h@92vW!4)INu16kyV`>_>?1r+tL4zM4f2( zo>LB~a|NOU>%sbH(&P}oja0?pf?DIwVWCJepMl(obmm~M{b?t!8;l9Nt2Uq?DL^k1p&KW)WHo4e$r4E|!*g;&{qNrHi?mK<+xLrTqs+#f!K! z>NO6_*i`+D0<^(nQ^xA}=m}0IH{@(-bww07_m#I*M;3M-7@7uzH zr)XwYi>!*WaaCBVGTS&Sp?laF*t=3v8|tuPrMu=)Ihh%j@9LtmUy|1$GxcFv*!1oJ zq=TPzQO%#5HJ3`41tWrMN##1;UIYdNS=GMe{0G9Z{fT5T0^Q-j@B5BG*|Hx%Lh_y5 za9;D_a89XkuMZC`Oc>6FbCWwm)uYUrP4W=_W+Ji<`vncgw7ocyyJ@B4<=G-qQ+Wx> zKo+}@8zg9yHCoFW)Xi?ci-nGsLw!C6=BqB`{)+%*cXL8rUI(QozPb6tTc7EhgBc=T%vD5(D|3?g`PQq=*)b8EM^jqvCtesG zq!sD+0#q(jt9O_TP>f7GRKyb5rs?D*>S`jaS>33^vY~jmHYMRoZ5)T< zQ9>jCkoqB6XF2~jz-Qm|-;YYe68WQu10lOdWjvWkWK=k7W(~`QOq-C<63ej-i&xI% zyUP74LwkrKdfpc~xjzv0Q4LXJmBtLs6@;Cpwy(>V5HsrXw?g=^;W-{#9rek_BV}Sj z_SM)b&tx6dhBbMZl!i4R^5+BMZIa743Qda3gbz*sgE)HENvQaS(RqEt- zalvRlTf~l%MUZ7e@A`DPj!Rl43b6yk)5{-Hqe4ry4yj>5rIT=uA>Y&~Z%V$8ZjY1W z^mW|Wmncu(fXh_ZmvsyIa)*-w7M{-HuK}kDS#@0LiTI2J-tQXPrE+`&QW+(c^q?_jQx`XhHmg;2_IxozIIvY@KWsX7%@ zAq9`{3FkqxG+_mf5Kbe)<*}7Z!7vas<+G^wqJ|{>w=q*i%)mv`$<;a1#q3b0T2j_$ zcHfeJ#n{Yc&QnFq!ySZkC_iDijbSN=i+(oT#Dxcj`~kmP%*J5u2RJE^y%F zLODnoDgrp`D%M#8<(cJTz#W_~baw*eN}`Z*CF(c{$+3fQrLZz119A(%86>HTyg)|z zmn?NnMIn^VI-{IAG#|80gfl8IiUmZ6=YW~=T%ZR>s6Z)8-cZ5Lp;Fyw?vc^X>-Sh6 zmCdO32GDrQF)E;WIKL&iYB!Z)T4#SFQ#Ep`R7dgK#JolQpvVEM5(%kwS{!04-yIvG zri`6uC-JQR33gfjcTb zf|@Z--VoIYhrI||eUps?snhvWIA17UvbvngOXD^Kj7mth~&B#WN9kAnT$P+@e4&El- zAznF424Tu&b{t$CJDx;fJK-p2NEKx4eU_UX^Sk3U^h1emVhd<-PPQN_ASlA|o@CBX zo`PgVCdP8mp(Y?n7|(_tTOC)burQ)999NYJI@T+rZ>|xD$w(Zt!r!T*L1KkBu|5f! zl9`DuAlWOhSMO;zMn%Hh#{%!+buV}3rpBma^drRI%udWR#fb|G9?s=F&V;)Fbjm~- z($f_GDd~Sm)>|5!qs-xjp90g^Ajn^F(;j(UzYbW9OAR`mkX2FZ@U19yMQwFzHR=2U-%VU=2BohXDt)~=<#~-}nee&D z-y$lq&qZl#oQqe9X!e$nbT;=j`7}H&4W8E1D0ZrEcwF$JkPyPD8wK`w`$3XJ?NGIO|2_O9~CxCIJlJmegYe#4Q6lBX>U|j_&Apo z+_r@?C55S*s22Pl-b<=EDaZN++~r3|M)WG-RBM=|RXPUBw^QViH0-a5E<|XYA%XWx zbXfVBZSn~cJXyxz?9^^&I5r=p-)fLwg5PS?TBzQOK7L2kO6#rG`+YZ1Z}@i>sg0^G ze&LZEsu18ZAs*3XjV?Fn@)TY8+~5Y?J%dYXQ5YB);$SFDf|7(KN6`(z{|S)6B@XZUI=lxrPWV5LA;@U^|HY&e9zHXdhvJ{K82`$ z6C+KUi=-r7>K=MBLWV2@glv@08=W>XC0(2tQU{kvlcfBki5BSVAu|WXuVOxq{x~(h zl)Dn+eYnm=1z<@rV7d$wf-}~wHXUztH&hg-;zr8J%YZHoy3n#u+$j4+#eZL?UFJe> a{UWEs5xp%N4a+v^3DKUZ{eb?}Fa9rk-7jhY diff --git a/__pycache__/location_processing.cpython-310.pyc b/__pycache__/location_processing.cpython-310.pyc deleted file mode 100644 index 44746709fd7472b2528adfa161a4536e74507d5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1781 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 q)b64-w%s9|a!=(eX z(>QNj>7MeLYrO`paD%<(MEOXKoSD~naBMI=?h6?A$4NQL%8?jWx=5@T>Z%ZT_Q%3j zV*j)8E-C$>Y^_UkKn(8cl$DI}zG5fOjExS&k6CGV##ODOTLQ@39n%e9bX|n4aVkM22E_PfE;>nIx$aQrQ!wN`W^ONhw8AG?Svs(xag`sq`@_(`Q*J zQ*K)^PF^Shp)n$nQrNMY>)+F(m6Ve2kbq@2jjgoWHe{0wzP}WziR!Yk+(?qK*uj+D z62ujAZdpKSUKw?^dOFc^U&o%=s1X3u!Om0pNwhulzg0Mdpd)i@1<)u*c9jsF|_-8to) zHNJEs7}lU-x8pb4NpyvNgxhfwlDX2YSa{^_ zl#a*qwP*vZ6Xa2aT!>We1(VZu%QebIpncY&zDnd@QKK6D~V@nl(z4}Ga z!=aI#ez0uzRLP`29jq7@@U~#x=^Hp<)e%P9AelfwWfZpk|8Ca$;2FSzmZH6gcH%Bl ztxsz^pe{gf60{2sHCmrq)p>wiS=k*MmFRT*DI9NZ!Q@@s1az!B13uuJd;n{oJFk$# zUq|Ci*uf1^*u9V+m8vS^+Ge@g?H;jRk`UcFifxHH9XU$K(`aJle)uA4YHH!#qLOv4 T4)GZ#;Nk^Bgzg}`Jm~)m%;;BF diff --git a/locale/en-us/dialog/en/greeting.dialog b/locale/en-us/dialog/en/greeting.dialog index 39c1651..05a682b 100644 --- a/locale/en-us/dialog/en/greeting.dialog +++ b/locale/en-us/dialog/en/greeting.dialog @@ -1 +1 @@ -Hello! How can I help you? \ No newline at end of file +Hello! \ No newline at end of file diff --git a/locale/en-us/dialog/en/how_can_i_help_you.dialog b/locale/en-us/dialog/en/how_can_i_help_you.dialog new file mode 100644 index 0000000..c1c20e4 --- /dev/null +++ b/locale/en-us/dialog/en/how_can_i_help_you.dialog @@ -0,0 +1 @@ +How can I help you? \ No newline at end of file diff --git a/locale/en-us/dialog/en/start_mall_directory.intent b/locale/en-us/dialog/en/start_mall_directory.intent index bc2e93e..867d0c0 100644 --- a/locale/en-us/dialog/en/start_mall_directory.intent +++ b/locale/en-us/dialog/en/start_mall_directory.intent @@ -1,3 +1,5 @@ start mall directory skill start mall skill start mall parsing +start kiosk skill +kiosk skill diff --git a/regex/store.rx b/regex/store.rx new file mode 100644 index 0000000..9028dcd --- /dev/null +++ b/regex/store.rx @@ -0,0 +1 @@ +(where|find|show|i)?\s(is|are|need|can\s*i?\s?find*|me)?\s?(find)?\s?(\w+\s?\w*\s*)(situated)? \ No newline at end of file diff --git a/test/test_skill.py b/test/test_skill.py index eec8f89..7b0138e 100644 --- a/test/test_skill.py +++ b/test/test_skill.py @@ -103,7 +103,8 @@ def test_en_skill_init(self): 'store': 'ABC stores', 'lang': 'en-us'}, {'context_key': 'MallParsing'}) - self.skill.user_request_handling(message) + answer = 'where is abc stores' + self.skill.user_request_handling(message, answer) def test_en_time_calculation(self): From 8c2971ebcd2e08a9d1f0d489d3aa0a9f9115e681 Mon Sep 17 00:00:00 2001 From: NeonMariia Date: Tue, 27 Dec 2022 05:42:49 -0500 Subject: [PATCH 41/44] end interaction changes --- __init__.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/__init__.py b/__init__.py index 603b0f8..f384da3 100644 --- a/__init__.py +++ b/__init__.py @@ -119,14 +119,6 @@ def handle_new_interaction(self, message): """ self.converse(message) - def handle_end_interaction(self, message): - """ - Override to do any skill-specific cleanup when a user interaction is - completed. - :param message: Message associated with request triggering end - """ - self.speak_dialog(self.goodbye_dialog) - def handle_user_utterance(self, message): """ Handle any input from a user interacting with the kiosk. @@ -140,9 +132,9 @@ def handle_user_utterance(self, message): LOG.info('executed') return else: - self.handle_end_interaction(message) + self.end_interaction(message) else: - self.handle_end_interaction(message) + self.end_interaction(message) @intent_file_handler("start_mall_directory") def start_interaction(self, message): From 5568f8bbc4a0bd6e504d2622b3c1b3fe4fbe1fe7 Mon Sep 17 00:00:00 2001 From: NeonMariia Date: Wed, 28 Dec 2022 14:41:16 -0500 Subject: [PATCH 42/44] message parsing changes --- __init__.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/__init__.py b/__init__.py index f384da3..e1cb85e 100644 --- a/__init__.py +++ b/__init__.py @@ -117,14 +117,17 @@ def handle_new_interaction(self, message): spoken. :param message: Message associated with start request """ - self.converse(message) + self.speak_dialog('how_can_i_help_you') + #self.converse(message) def handle_user_utterance(self, message): """ Handle any input from a user interacting with the kiosk. :param message: Message associated with user utterance """ - answer = self.get_response('how_can_i_help_you') + #answer = self.get_response('how_can_i_help_you') + #user_request, mall_link = self.user_request_handling(message, answer) + answer = message.data['utterances'] user_request, mall_link = self.user_request_handling(message, answer) if user_request and mall_link: LOG.info(mall_link) From 14462b7c7acac0289a7af235fba0e7650a40dc88 Mon Sep 17 00:00:00 2001 From: NeonMariia Date: Wed, 28 Dec 2022 14:46:39 -0500 Subject: [PATCH 43/44] comments removal --- __init__.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/__init__.py b/__init__.py index e1cb85e..b658ac3 100644 --- a/__init__.py +++ b/__init__.py @@ -118,15 +118,12 @@ def handle_new_interaction(self, message): :param message: Message associated with start request """ self.speak_dialog('how_can_i_help_you') - #self.converse(message) def handle_user_utterance(self, message): """ Handle any input from a user interacting with the kiosk. :param message: Message associated with user utterance """ - #answer = self.get_response('how_can_i_help_you') - #user_request, mall_link = self.user_request_handling(message, answer) answer = message.data['utterances'] user_request, mall_link = self.user_request_handling(message, answer) if user_request and mall_link: From a093ff97cb9b1a20fb96d392fded8e8a61cee486 Mon Sep 17 00:00:00 2001 From: NeonMariia Date: Thu, 29 Dec 2022 11:11:01 -0500 Subject: [PATCH 44/44] small changes --- __init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__init__.py b/__init__.py index b658ac3..7f3f0f6 100644 --- a/__init__.py +++ b/__init__.py @@ -124,7 +124,7 @@ def handle_user_utterance(self, message): Handle any input from a user interacting with the kiosk. :param message: Message associated with user utterance """ - answer = message.data['utterances'] + answer = message.data['utterances'][0] user_request, mall_link = self.user_request_handling(message, answer) if user_request and mall_link: LOG.info(mall_link)