From 5505fa53a6b48d7db39d065a6cab2ec5b13bd952 Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Wed, 21 Apr 2021 16:39:14 -0700 Subject: [PATCH 1/3] Catch empty server release check response Default assume enable/disable WW command is valid if no preference found --- __init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/__init__.py b/__init__.py index 7fc68bc..6fb04f6 100644 --- a/__init__.py +++ b/__init__.py @@ -102,6 +102,9 @@ def _check_release(self, message): """ LOG.debug("Checking release!") resp = self.bus.wait_for_response(Message("neon.client.check_release")) + if not resp: + LOG.error(f"No response from server!") + return False version_file = glob.glob( f'{self.configuration_available.get("dirVars", {}).get("ngiDir") or os.path.expanduser("~/neon")}' f'/*.release')[0] @@ -137,7 +140,7 @@ def handle_use_wake_words(self, message): Enable wake words and stop always-listening recognizer :param message: message object associated with request """ - if not self.configuration_available.get("interface", {}).get("wake_word_enabled", True): + if not self.configuration_available.get("interface", {}).get("wake_word_enabled", False): user = self.get_utterance_user(message) self.await_confirmation(user, "StopSWW") self.speak_dialog("AskStartRequiring", expect_response=True, private=True) From 5df856e7c45bb8e5fc6f23767d56a692bce85e4f Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Tue, 27 Apr 2021 17:40:45 -0700 Subject: [PATCH 2/3] Update configuration_available references to local_config to get updates automatically --- __init__.py | 49 +++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/__init__.py b/__init__.py index 6fb04f6..53f9392 100644 --- a/__init__.py +++ b/__init__.py @@ -79,9 +79,9 @@ def initialize(self): self.register_intent(stop_solo_intent, self.handle_use_wake_words) # When first run or demo prompt not dismissed, wait for load and prompt user - if self.configuration_available.get("prefFlags", {}).get("showDemo", False) and not self.server: + if self.local_config.get("prefFlags", {}).get("showDemo", False) and not self.server: self.bus.once('mycroft.ready', self._show_demo_prompt) - elif self.configuration_available.get("prefFlags", {}).get("notifyRelease", False) and not self.server: + elif self.local_config.get("prefFlags", {}).get("notifyRelease", False) and not self.server: self.bus.once('mycroft.ready', self._check_release) def _show_demo_prompt(self, message): @@ -106,7 +106,7 @@ def _check_release(self, message): LOG.error(f"No response from server!") return False version_file = glob.glob( - f'{self.configuration_available.get("dirVars", {}).get("ngiDir") or os.path.expanduser("~/neon")}' + f'{self.local_config.get("dirVars", {}).get("ngiDir") or os.path.expanduser("~/.neon")}' f'/*.release')[0] version = os.path.splitext(os.path.basename(version_file))[0] # 2009.0 major, minor = version.split('.') @@ -128,7 +128,7 @@ def handle_skip_wake_words(self, message): """ if self.neon_in_request(message): user = self.get_utterance_user(message) - if self.configuration_available.get("interface", {}).get("wake_word_enabled", True): + if self.local_config.get("interface", {}).get("wake_word_enabled", True): self.clear_signals("DCC") self.await_confirmation(user, "StartSWW") self.speak_dialog("AskStartSkipping", expect_response=True, private=True) @@ -140,7 +140,7 @@ def handle_use_wake_words(self, message): Enable wake words and stop always-listening recognizer :param message: message object associated with request """ - if not self.configuration_available.get("interface", {}).get("wake_word_enabled", False): + if not self.local_config.get("interface", {}).get("wake_word_enabled", False): user = self.get_utterance_user(message) self.await_confirmation(user, "StopSWW") self.speak_dialog("AskStartRequiring", expect_response=True, private=True) @@ -209,12 +209,12 @@ def handle_update_neon(self, message): self.clear_signals("DCC") if self.check_for_signal('CORE_useHesitation', -1): self.speak("Understood. Give me a moment to check for available updates.", private=True) - current_version = self.configuration_available.get("devVars", {}).get("version", "0000-00-00") + current_version = self.local_config.get("devVars", {}).get("version", "0000-00-00") try: - new_version = git.Git(self.configuration_available["dirVars"]["coreDir"]).log( + new_version = git.Git(self.local_config["dirVars"]["coreDir"]).log( "-1", "--format=%ai", - f'origin/{self.configuration_available.get("remoteVars", {}).get("coreBranch")}') + f'origin/{self.local_config.get("remoteVars", {}).get("coreBranch")}') new_date, new_time, _ = new_version.split(" ", 2) new_time = new_time.replace(":", "") new_version = f"{new_date}-{new_time}" @@ -248,7 +248,7 @@ def handle_show_demo(self, message): if self.check_for_signal('CORE_useHesitation', -1): self.speak("Here you go", private=True) # import os - os.chdir(self.configuration_available["dirVars"]["ngiDir"]) + os.chdir(self.local_config["dirVars"]["ngiDir"]) os.system('gnome-terminal -- shortcuts/demoNeon.sh') def handle_exit_shutdown_intent(self, message): @@ -396,7 +396,7 @@ def converse(self, message=None): if not self.server: self.speak("Starting the update.", private=True) try: - os.chdir(self.configuration_available.get("dirVars", {}).get("ngiDir")) + os.chdir(self.local_config.get("dirVars", {}).get("ngiDir")) subprocess.call(['gnome-terminal', '--', 'sudo', "./update.sh"]) except HTTPError as e: LOG.info(e) @@ -413,7 +413,7 @@ def converse(self, message=None): if f"exitNow_{confrimed_num}" in actions_requested: self.speak_dialog("Exiting", private=True, wait=True) if not self.server: - subprocess.call([self.configuration_available["dirVars"]["coreDir"] + '/stop_neon.sh']) + subprocess.call([self.local_config["dirVars"]["coreDir"] + '/stop_neon.sh']) if f"shutdownNow_{confrimed_num}" in actions_requested: LOG.info('quiting') @@ -425,7 +425,8 @@ def converse(self, message=None): LOG.info(">>> Clear All") self.speak_dialog("ConfirmClearAll", private=True) if not self.server: - subprocess.call(['bash', '-c', ". " + self.configuration_available["dirVars"]["ngiDir"] + # TODO: Move clear data methods to Python DM + subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] + "/functions.sh; refreshNeon -a"]) else: user_dict['ignored_brands'] = {} @@ -457,7 +458,7 @@ def converse(self, message=None): user_dict["secondary_tts_gender"] = "" user_dict["secondary_neon_voice"] = "" user_dict["speed_multiplier"] = 1.0 - subprocess.call(['bash', '-c', ". " + self.configuration_available["dirVars"]["ngiDir"] + subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] + "/functions.sh; refreshNeon -A " + user_dict["username"]]) if request_from_mobile(message): self.mobile_skill_intent("clear_data", {"kind": "all"}, message) @@ -481,10 +482,10 @@ def converse(self, message=None): else: self.speak("Taking care of your selected transcripts folder", private=True) if self.server: - subprocess.call(['bash', '-c', ". " + self.configuration_available["dirVars"]["ngiDir"] + subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] + "/functions.sh; refreshNeon -S " + user_dict["username"]]) else: - subprocess.call(['bash', '-c', ". " + self.configuration_available["dirVars"]["ngiDir"] + subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] + "/functions.sh; refreshNeon -s"]) if f"eraseIgnoredTranscriptions_{confrimed_num}" in actions_requested: @@ -499,10 +500,10 @@ def converse(self, message=None): else: self.speak("Taking care of your ignored brands transcriptions", private=True) if self.server: - subprocess.call(['bash', '-c', ". " + self.configuration_available["dirVars"]["ngiDir"] + subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] + "/functions.sh; refreshNeon -I " + user_dict["username"]]) else: - subprocess.call(['bash', '-c', ". " + self.configuration_available["dirVars"]["ngiDir"] + subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] + "/functions.sh; refreshNeon -i"]) if f"eraseAllTranscriptions_{confrimed_num}" in actions_requested: @@ -511,12 +512,12 @@ def converse(self, message=None): private=True) # self.speak("Audio recordings and transcriptions cleared", private=True) if self.server: - subprocess.call(['bash', '-c', ". " + self.configuration_available["dirVars"]["ngiDir"] + subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] + "/functions.sh; refreshNeon -T " + user_dict["username"]]) if request_from_mobile(message): self.mobile_skill_intent("clear_data", {"kind": "transcripts"}, message) else: - subprocess.call(['bash', '-c', ". " + self.configuration_available["dirVars"]["ngiDir"] + subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] + "/functions.sh; refreshNeon -t"]) if f"eraseProfile_{confrimed_num}" in actions_requested: @@ -534,14 +535,14 @@ def converse(self, message=None): user_dict["about"] = "" else: # TODO: Update user profile DM - subprocess.call(['bash', '-c', ". " + self.configuration_available["dirVars"]["ngiDir"] + subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] + "/functions.sh; refreshNeon -u"]) if f"eraseCache_{confrimed_num}" in actions_requested: self.speak_dialog("ConfirmClearData", {"kind": "cached responses"}, private=True) if not self.server: # self.speak("Clearing All cached responses.", private=True) - subprocess.call(['bash', '-c', ". " + self.configuration_available["dirVars"]["ngiDir"] + subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] + "/functions.sh; refreshNeon -c"]) else: LOG.debug("Clear Caches") @@ -559,7 +560,7 @@ def converse(self, message=None): user_dict["date"] = "MDY" user_dict["measure"] = "imperial" else: - subprocess.call(['bash', '-c', ". " + self.configuration_available["dirVars"]["ngiDir"] + subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] + "/functions.sh; refreshNeon -r"]) # self.speak("Resetting all interface preferences.", private=True) @@ -574,7 +575,7 @@ def converse(self, message=None): else: pass else: - subprocess.call(['bash', '-c', ". " + self.configuration_available["dirVars"]["ngiDir"] + subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] + "/functions.sh; refreshNeon -p"]) if f"eraseLanguages_{confrimed_num}" in actions_requested: @@ -593,7 +594,7 @@ def converse(self, message=None): user_dict["secondary_neon_voice"] = "" user_dict["speed_multiplier"] = 1.0 else: - subprocess.call(['bash', '-c', ". " + self.configuration_available["dirVars"]["ngiDir"] + subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] + "/functions.sh; refreshNeon -l"]) LOG.debug("DM: Clear Data Confirmed") From 99e08c3415737dc5bb1536056eff141f226a26fa Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Tue, 4 May 2021 19:19:05 -0700 Subject: [PATCH 3/3] Move data clearing methods to python in data_utils Update restart to utilize messagebus event Annotate Versioning changes --- __init__.py | 120 +++++++++++++++++++++++++++----------------------- data_utils.py | 84 +++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+), 55 deletions(-) create mode 100644 data_utils.py diff --git a/__init__.py b/__init__.py index 53f9392..a8c6a52 100644 --- a/__init__.py +++ b/__init__.py @@ -28,6 +28,8 @@ from random import randint from mycroft_bus_client import Message from neon_utils.skills.neon_skill import NeonSkill, LOG + +from .data_utils import refresh_neon # from mycroft.skills.core import MycroftSkill # from mycroft.messagebus.message import Message # from mycroft.util.log import LOG @@ -105,6 +107,7 @@ def _check_release(self, message): if not resp: LOG.error(f"No response from server!") return False + # TODO: Use versioning checks in neon_utils DM version_file = glob.glob( f'{self.local_config.get("dirVars", {}).get("ngiDir") or os.path.expanduser("~/.neon")}' f'/*.release')[0] @@ -114,6 +117,7 @@ def _check_release(self, message): new_minor = resp.data.get("version_minor", 0) # LOG.debug(str(result)) if new_major > major or (new_major == major and new_minor > minor): + # TODO: Dialog update when moved to packaged core DM # Server Reported Release Different than Install self.speak("There is a new release available from Neon Gecko. " "Please pull changes on GitHub.", private=True, message=message) @@ -212,6 +216,7 @@ def handle_update_neon(self, message): current_version = self.local_config.get("devVars", {}).get("version", "0000-00-00") try: + # TODO: Support packaged installations here DM new_version = git.Git(self.local_config["dirVars"]["coreDir"]).log( "-1", "--format=%ai", f'origin/{self.local_config.get("remoteVars", {}).get("coreBranch")}') @@ -248,6 +253,7 @@ def handle_show_demo(self, message): if self.check_for_signal('CORE_useHesitation', -1): self.speak("Here you go", private=True) # import os + # TODO: Make a new demo? DM os.chdir(self.local_config["dirVars"]["ngiDir"]) os.system('gnome-terminal -- shortcuts/demoNeon.sh') @@ -413,7 +419,8 @@ def converse(self, message=None): if f"exitNow_{confrimed_num}" in actions_requested: self.speak_dialog("Exiting", private=True, wait=True) if not self.server: - subprocess.call([self.local_config["dirVars"]["coreDir"] + '/stop_neon.sh']) + self.bus.emit(Message("neon.shutdown")) + # subprocess.call([self.local_config["dirVars"]["coreDir"] + '/stop_neon.sh']) if f"shutdownNow_{confrimed_num}" in actions_requested: LOG.info('quiting') @@ -424,11 +431,8 @@ def converse(self, message=None): if f"eraseAllData_{confrimed_num}" in actions_requested: LOG.info(">>> Clear All") self.speak_dialog("ConfirmClearAll", private=True) - if not self.server: - # TODO: Move clear data methods to Python DM - subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] - + "/functions.sh; refreshNeon -a"]) - else: + # TODO: Non-server clear yml? + if self.server: user_dict['ignored_brands'] = {} user_dict['favorite_brands'] = {} user_dict['specially_requested'] = {} @@ -458,14 +462,14 @@ def converse(self, message=None): user_dict["secondary_tts_gender"] = "" user_dict["secondary_neon_voice"] = "" user_dict["speed_multiplier"] = 1.0 - subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] - + "/functions.sh; refreshNeon -A " + user_dict["username"]]) + # subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] + # + "/functions.sh; refreshNeon -A " + user_dict["username"]]) if request_from_mobile(message): self.mobile_skill_intent("clear_data", {"kind": "all"}, message) else: self.socket_emit_to_server("clear cookies intent", [message.context["klat_data"]["request_id"]]) - + refresh_neon("all", user) if f"eraseSelectedTranscriptions_{confrimed_num}" in actions_requested: LOG.info(">>> Clear Selected Transcripts") if f"eraseLikes_{confrimed_num}" in actions_requested: @@ -481,12 +485,13 @@ def converse(self, message=None): self.user_config.update_yaml_file("brands", "specially_requested", {}) else: self.speak("Taking care of your selected transcripts folder", private=True) - if self.server: - subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] - + "/functions.sh; refreshNeon -S " + user_dict["username"]]) - else: - subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] - + "/functions.sh; refreshNeon -s"]) + refresh_neon("selected", user) + # if self.server: + # subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] + # + "/functions.sh; refreshNeon -S " + user_dict["username"]]) + # else: + # subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] + # + "/functions.sh; refreshNeon -s"]) if f"eraseIgnoredTranscriptions_{confrimed_num}" in actions_requested: LOG.info(">>> Clear Ignored Transcripts") @@ -499,26 +504,28 @@ def converse(self, message=None): self.user_config.update_yaml_file("brands", "ignored_brands", {}) else: self.speak("Taking care of your ignored brands transcriptions", private=True) - if self.server: - subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] - + "/functions.sh; refreshNeon -I " + user_dict["username"]]) - else: - subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] - + "/functions.sh; refreshNeon -i"]) + refresh_neon("ignored", user) + # if self.server: + # subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] + # + "/functions.sh; refreshNeon -I " + user_dict["username"]]) + # else: + # subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] + # + "/functions.sh; refreshNeon -i"]) if f"eraseAllTranscriptions_{confrimed_num}" in actions_requested: LOG.info(">>> Clear All Transcripts") self.speak_dialog("ConfirmClearData", {"kind": "audio recordings and transcriptions"}, private=True) # self.speak("Audio recordings and transcriptions cleared", private=True) - if self.server: - subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] - + "/functions.sh; refreshNeon -T " + user_dict["username"]]) - if request_from_mobile(message): - self.mobile_skill_intent("clear_data", {"kind": "transcripts"}, message) - else: - subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] - + "/functions.sh; refreshNeon -t"]) + refresh_neon("transcripts", user) + # if self.server: + # subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] + # + "/functions.sh; refreshNeon -T " + user_dict["username"]]) + # if request_from_mobile(message): + # self.mobile_skill_intent("clear_data", {"kind": "transcripts"}, message) + # else: + # subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] + # + "/functions.sh; refreshNeon -t"]) if f"eraseProfile_{confrimed_num}" in actions_requested: LOG.info(">>> Clear Profile") @@ -535,33 +542,36 @@ def converse(self, message=None): user_dict["about"] = "" else: # TODO: Update user profile DM - subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] - + "/functions.sh; refreshNeon -u"]) + pass + # subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] + # + "/functions.sh; refreshNeon -u"]) if f"eraseCache_{confrimed_num}" in actions_requested: self.speak_dialog("ConfirmClearData", {"kind": "cached responses"}, private=True) - if not self.server: - # self.speak("Clearing All cached responses.", private=True) - subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] - + "/functions.sh; refreshNeon -c"]) + # if not self.server: + # # self.speak("Clearing All cached responses.", private=True) + # subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] + # + "/functions.sh; refreshNeon -c"]) + # else: + LOG.debug("Clear Caches") + if request_from_mobile(message): + self.mobile_skill_intent("clear_data", {"kind": "cache"}, message) else: - LOG.debug("Clear Caches") - if request_from_mobile(message): - self.mobile_skill_intent("clear_data", {"kind": "cache"}, message) - else: - self.socket_emit_to_server("clear cookies intent", - [message.context["klat_data"]["request_id"]]) + self.socket_emit_to_server("clear cookies intent", + [message.context["klat_data"]["request_id"]]) + refresh_neon("caches", user) if f"erasePrefs_{confrimed_num}" in actions_requested: LOG.info(">>> Clear Preferences") self.speak_dialog("ConfirmClearData", {"kind": "unit preferences"}, private=True) + # TODO: Update for non-server? DM if self.server: user_dict["time"] = 12 user_dict["date"] = "MDY" user_dict["measure"] = "imperial" - else: - subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] - + "/functions.sh; refreshNeon -r"]) + # else: + # subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] + # + "/functions.sh; refreshNeon -r"]) # self.speak("Resetting all interface preferences.", private=True) if f"eraseMedia_{confrimed_num}" in actions_requested: @@ -569,19 +579,19 @@ def converse(self, message=None): self.speak_dialog("ConfirmClearData", {"kind": "pictures, videos, and audio recordings I have taken."}, private=True) - if self.server: - if request_from_mobile(message): - self.mobile_skill_intent("clear_data", {"kind": "media"}, message) - else: - pass - else: - subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] - + "/functions.sh; refreshNeon -p"]) + # if self.server: + if request_from_mobile(message): + self.mobile_skill_intent("clear_data", {"kind": "media"}, message) + refresh_neon("media", user) + # else: + # subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] + # + "/functions.sh; refreshNeon -p"]) if f"eraseLanguages_{confrimed_num}" in actions_requested: self.speak_dialog("ConfirmClearData", {"kind": "language preferences"}, private=True) # self.speak("Resetting your language preferences.", private=True) # Neon.clear_data(['l']) + # TODO: Update for non-server? DM if self.server: user_dict["stt_language"] = "en" user_dict["stt_region"] = "US" @@ -593,9 +603,9 @@ def converse(self, message=None): user_dict["secondary_tts_gender"] = "" user_dict["secondary_neon_voice"] = "" user_dict["speed_multiplier"] = 1.0 - else: - subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] - + "/functions.sh; refreshNeon -l"]) + # else: + # subprocess.call(['bash', '-c', ". " + self.local_config["dirVars"]["ngiDir"] + # + "/functions.sh; refreshNeon -l"]) LOG.debug("DM: Clear Data Confirmed") if self.server: diff --git a/data_utils.py b/data_utils.py new file mode 100644 index 0000000..3f6fc0c --- /dev/null +++ b/data_utils.py @@ -0,0 +1,84 @@ +# NEON AI (TM) SOFTWARE, Software Development Kit & Application Development System +# +# Copyright 2008-2021 Neongecko.com Inc. | All Rights Reserved +# +# Notice of License - Duplicating this Notice of License near the start of any file containing +# a derivative of this software is a condition of license for this software. +# Friendly Licensing: +# No charge, open source royalty free use of the Neon AI software source and object is offered for +# educational users, noncommercial enthusiasts, Public Benefit Corporations (and LLCs) and +# Social Purpose Corporations (and LLCs). Developers can contact developers@neon.ai +# For commercial licensing, distribution of derivative works or redistribution please contact licenses@neon.ai +# Distributed on an "AS IS” basis without warranties or conditions of any kind, either express or implied. +# Trademarks of Neongecko: Neon AI(TM), Neon Assist (TM), Neon Communicator(TM), Klat(TM) +# Authors: Guy Daniels, Daniel McKnight, Regina Bloomstine, Elon Gasper, Richard Leeds +# +# Specialized conversational reconveyance options from Conversation Processing Intelligence Corp. +# US Patents 2008-2021: US7424516, US20140161250, US20140177813, US8638908, US8068604, US8553852, US10530923, US10530924 +# China Patent: CN102017585 - Europe Patent: EU2156652 - Patents Pending +import os + +from glob import glob +from shutil import rmtree +from neon_utils.configuration_utils import get_neon_local_config, get_neon_device_type +from neon_utils.logger import LOG + +LOCAL_CONF = get_neon_local_config() +ALL_TRANSCRIPTS = ("ts_transcripts", "ts_selected_transcripts", "ts_ignored_transcripts", + "ts_transcript_audio_segments") +ALL_MEDIA = ("music", "video", "pictures") + + +# TODO: Add unit tests for these! DM +def refresh_neon(data_to_remove: str, user: str): + if data_to_remove == "all": + remove_transcripts(ALL_TRANSCRIPTS, user) + remove_media(ALL_MEDIA, user) + elif data_to_remove == "ignored": + remove_transcripts(tuple("ts_ignored_transcripts"), user) + elif data_to_remove == "selected": + remove_transcripts(tuple("ts_selected_transcripts"), user) + elif data_to_remove == "brands": + remove_transcripts(("ts_selected_transcripts", "ts_ignored_transcripts"), user) + elif data_to_remove == "transcripts": + remove_transcripts(ALL_TRANSCRIPTS, user) + elif data_to_remove == "media": + remove_media(ALL_MEDIA, user) + elif data_to_remove == "caches": + remove_cache(user) + else: + LOG.warning(f"Unknown data type: {data_to_remove}") + + +def remove_transcripts(directories: tuple, user: str): + docs_dir = os.path.expanduser(LOCAL_CONF["dirVars"].get("docsDir", "~/Documents/NeonGecko")) + for directory in directories: + transcript_path = os.path.join(docs_dir, directory) + if get_neon_device_type() == "server": + user_transcripts = glob(os.path.join(transcript_path, f"{user}-*")) + for transcript in user_transcripts: + rmtree(transcript) + else: + rmtree(transcript_path) + + +def remove_media(media: tuple, user: str): + media_locations = {"music": LOCAL_CONF["dirVars"]["musicDir"], + "pictures": LOCAL_CONF["dirVars"]["picsDir"], + "video": LOCAL_CONF["dirVars"]["videoDir"]} + for kind in media: + dir_to_clean = media_locations.get(kind) + if dir_to_clean: + if get_neon_device_type() == "server": + # TODO: Remove media indexed by username + pass + else: + rmtree(dir_to_clean) + + +def remove_cache(user): + if get_neon_device_type() == "server" and user != "admin": + LOG.warning(f"{user} not allowed to clear cache!") + return + if LOCAL_CONF["dirVars"].get("cacheDir"): + rmtree(LOCAL_CONF["dirVars"]["cacheDir"])