def __init__(self, opts): #import the recognizer so Gst doesn't clobber our -h from Recognizer import Recognizer self.ui = None #keep track of the opts self.opts = opts ui_continuous_listen = False self.continuous_listen = False self.commands = {} self.read_commands() self.recognizer = Recognizer(lang_file, dic_file) self.recognizer.connect('finished',self.recognizer_finished) if opts.interface != None: if opts.interface == "q": #import the ui from qt from QtUI import UI elif opts.interface == "g": from GtkUI import UI else: print "no GUI defined" sys.exit() self.ui = UI(args,opts.continuous) self.ui.connect("command", self.process_command) if self.opts.history: self.history = []
def __init__(self, opts): #import the recognizer so Gst doesn't clobber our -h from Recognizer import Recognizer self.ui = None self.options = {} ui_continuous_listen = True self.continuous_listen = False self.commands = {} #read the commands self.read_commands() #load the options file self.load_options() #merge the opts for k,v in opts.__dict__.items(): if (not k in self.options) or opts.override: self.options[k] = v if self.options['interface'] != None: if self.options['interface'] == "q": from QtUI import UI elif self.options['interface'] == "g": from GtkUI import UI elif self.options['interface'] == "gt": from GtkTrayUI import UI else: print "no GUI defined" sys.exit() self.ui = UI(args, self.options['continuous']) self.ui.connect("command", self.process_command) #can we load the icon resource? icon = self.load_resource("icon.png") if icon: self.ui.set_icon_active_asset(icon) #can we load the icon_inactive resource? icon_inactive = self.load_resource("icon_inactive.png") if icon_inactive: self.ui.set_icon_inactive_asset(icon_inactive) if self.options['history']: self.history = [] #create the recognizer try: self.recognizer = Recognizer(lang_file, dic_file, self.options['microphone'] ) except Exception, e: #no recognizer? bummer sys.exit()
def __init__(self, opts): #import the recognizer so Gst doesn't clobber our -h from Recognizer import Recognizer self.ui = None #keep track of the opts self.opts = opts ui_continuous_listen = False self.continuous_listen = False self.commands = {} self.read_commands() self.recognizer = Recognizer(lang_file, dic_file, opts.microphone ) self.recognizer.connect('finished',self.recognizer_finished) self.matchTime = 0 self.keywordTimeLimit = opts.keytime #set to 0 to always speak the keyword self.commandFileTime = 0 #updates language file and commands on start self.checkCommandFile() self.commandFileTime = os.path.getmtime(command_file) #read options if opts.interface != None: if opts.interface == "q": #import the ui from qt from QtUI import UI elif opts.interface == "g": from GtkUI import UI else: print "no GUI defined" sys.exit() self.ui = UI(args,opts.continuous) self.ui.connect("command", self.process_command) #can we load the icon resource? icon = self.load_resource("icon.png") if icon: self.ui.set_icon(icon) if self.opts.history: self.history = []
class Blather: def __init__(self, opts): #import the recognizer so Gst doesn't clobber our -h from Recognizer import Recognizer self.ui = None #keep track of the opts self.opts = opts ui_continuous_listen = False self.continuous_listen = False self.commands = {} self.read_commands() self.recognizer = Recognizer(lang_file, dic_file, opts.microphone ) self.recognizer.connect('finished',self.recognizer_finished) self.matchTime = 0 self.keywordTimeLimit = opts.keytime #set to 0 to always speak the keyword self.commandFileTime = 0 #updates language file and commands on start self.checkCommandFile() self.commandFileTime = os.path.getmtime(command_file) #read options if opts.interface != None: if opts.interface == "q": #import the ui from qt from QtUI import UI elif opts.interface == "g": from GtkUI import UI else: print "no GUI defined" sys.exit() self.ui = UI(args,opts.continuous) self.ui.connect("command", self.process_command) #can we load the icon resource? icon = self.load_resource("icon.png") if icon: self.ui.set_icon(icon) if self.opts.history: self.history = [] def read_commands(self): #read the.commands file file_lines = open(command_file) strings = open(strings_file, "w") self.commands = {} keywords = [] for line in file_lines: print line #trim the white spaces line = line.strip() #if the line has length and the first char isn't a hash if len(line) and line[0]!="#": #this is a parsible line (key,value) = line.split(":",1) print key, value #get the keyword out of the commands file if value == "keyword" and key.strip().lower() not in keywords: keywords.append(key.strip().lower()) continue self.commands[key.strip().lower()] = value.strip() strings.write( key.strip()+"\n") #close the strings file strings.close() def log_history(self,text): if self.opts.history: self.history.append(text) if len(self.history) > self.opts.history: #pop off the first item self.history.pop(0) #open and truncate the blather history file hfile = open(history_file, "w") for line in self.history: hfile.write( line+"\n") #close the file hfile.close() def recognizer_finished(self, recognizer, text): #split the words spoken into an array t = text.lower() textWords = t.split(" ") #get the keys array for all commands biggestKey = "" biggestKeySet = [] biggestKeyCount = 0 ret = self.search_for_matches(textWords) biggestKey = ret['biggestKey'] biggestKeySet = ret['biggestKeySet'] biggestKeyCount = ret['biggestKeyCount'] #find the match percentage percentMatch = self.calculate_match_percentage(biggestKeySet, biggestKeyCount) #call the process if biggestKeyCount > 0 and ((len(textWords) <= 2 and len(biggestKeySet) == len(textWords)) or percentMatch >= PERCENT_MATCH_LIMIT): #must be equal or a 60% match self.matchTime = time.time() print("Best match: " + biggestKey, "Detected: " + text.lower(), "Percent match: " + str(percentMatch)); cmd = self.commands[biggestKey] if cmd == "cancel" and hasattr(self, 'runningProcess'): print("Cancelling previous command with PID "+str(self.runningProcess.pid)) self.terminate_child_processes(self.runningProcess.pid) #terminate parent process self.runningProcess.terminate(); elif cmd != "cancel": print cmd if "plugins/" in cmd: #execute a plugin script self.runningProcess = subprocess.Popen(os.path.join(file_dir,cmd), shell=True) else: self.runningProcess = subprocess.Popen(cmd, shell=True) self.log_history(text) else: print("No matching command", "Percent match: " + str(percentMatch)) #if there is a UI and we are not continuous listen if self.ui: if not self.continuous_listen: #stop listening self.recognizer.pause() #let the UI know that there is a finish self.ui.finished(t) #check if the command.conf file has changed. self.checkCommandFile() def run(self): if self.ui: self.ui.run() else: blather.recognizer.listen() def quit(self): sys.exit(0) def checkCommandFile(self): newFileTime = os.path.getmtime(command_file) if newFileTime > self.commandFileTime: print("Command.conf file modified") subprocess.call(language_update_script) print("Language file updated") self.commandFileTime = newFileTime self.read_commands() def process_command(self, UI, command): print command if command == "listen": self.recognizer.listen() elif command == "stop": self.recognizer.pause() elif command == "continuous_listen": self.continuous_listen = True self.recognizer.listen() elif command == "continuous_stop": self.continuous_listen = False self.recognizer.pause() elif command == "quit": self.quit() def load_resource(self,string): local_data = os.path.join(os.path.dirname(__file__), 'data') paths = ["/usr/share/blather/","/usr/local/share/blather", local_data] for path in paths: resource = os.path.join(path, string) if os.path.exists( resource ): return resource #if we get this far, no resource was found return False def search_for_matches(self, textWords): #TODO: https://github.com/ajbogh/blather/issues/1 ret = {'biggestKey':'', 'biggestKeySet':{}, 'biggestKeyCount':0} currentTime = time.time() matchLimit = 1 for key in self.commands.keys(): if self.commands[key] == "keyword": continue #split the keys on each word words = set(key.split(" ")) #append the keyword to the command if it's not there already ##only if the timed keyword activation is needed if self.continuous_listen and (currentTime - self.matchTime) > self.keywordTimeLimit and len(set(keywords).intersection(set(words))) == 0: words.update(keywords) #find the matching words matches = words.intersection(set(textWords)) #determine if the words match if self.continuous_listen and len(set(keywords).intersection(set(textWords))) > 0 and (currentTime - self.matchTime) > self.keywordTimeLimit: matchLimit = 2 if len(matches) >= matchLimit and len(matches) > ret['biggestKeyCount']: ret['biggestKeySet'] = words ret['biggestKeyCount'] = len(matches) ret['biggestKey'] = key return ret def calculate_match_percentage(self, biggestKeySet, biggestKeyCount): percentMatch = 0 if len(biggestKeySet) > 0: percentMatch = (biggestKeyCount/float(len(biggestKeySet))) * 100 return percentMatch # terminate_child_processes kills any child processes under a parent pid. # It uses pgrep to list child processes, so the system must have pgrep installed in order # to use the 'cancel' commands def terminate_child_processes(self, pid): out = subprocess.Popen(['pgrep', '-P', str(pid)], stdout=subprocess.PIPE).communicate()[0] childProcesses = out.splitlines() # Kill any orphaned children. for pid in childProcesses: #recursive call to kill entire family tree self.terminate_child_processes(int(pid)) print("Killing child with PID "+str(pid)) p = psutil.Process(int(pid)) p.terminate()
def __init__(self, opts): #import the recognizer so Gst doesn't clobber our -h from Recognizer import Recognizer #set variables self.ui = None self.options = {} ui_continuous_listen = False self.continuous_listen = False self.commands = {} #read the commands self.load_commands_file() #load the options file print("load the options") self.load_options_file() #merge the opts for k, v in opts.__dict__.items(): if (not k in self.options) or opts.override: self.options[k] = v # should we be updating? if self.options['update']: #make the sentences corpus self.generate_sentences_corpus() #run the update stuff UpdateLanguage.update_language() if self.options['interface'] != None: if self.options['interface'] == "q": from QtUI import UI elif self.options['interface'] == "g": from GtkUI import UI elif self.options['interface'] == "gt": from GtkTrayUI import UI else: print("no GUI defined") sys.exit() self.ui = UI(args, self.options['continuous']) self.ui.connect("command", self.process_command) #can we load the icon resource? icon = self.load_resource("icon.png") if icon: self.ui.set_icon_active_asset(icon) #can we load the icon_inactive resource? icon_inactive = self.load_resource("icon_inactive.png") if icon_inactive: self.ui.set_icon_inactive_asset(icon_inactive) if self.options['history']: self.history = [] #create the recognizer try: self.recognizer = Recognizer(lang_file, dic_file, self.options['microphone']) except Exception as e: print(e) #no recognizer? bummer sys.exit() self.recognizer.connect('finished', self.recognizer_finished) print("Using Options: ", self.options)
class Blather: def __init__(self, opts): #import the recognizer so Gst doesn't clobber our -h from Recognizer import Recognizer #set variables self.ui = None self.options = {} ui_continuous_listen = False self.continuous_listen = False self.commands = {} #read the commands self.load_commands_file() #load the options file print("load the options") self.load_options_file() #merge the opts for k, v in opts.__dict__.items(): if (not k in self.options) or opts.override: self.options[k] = v # should we be updating? if self.options['update']: #make the sentences corpus self.generate_sentences_corpus() #run the update stuff UpdateLanguage.update_language() if self.options['interface'] != None: if self.options['interface'] == "q": from QtUI import UI elif self.options['interface'] == "g": from GtkUI import UI elif self.options['interface'] == "gt": from GtkTrayUI import UI else: print("no GUI defined") sys.exit() self.ui = UI(args, self.options['continuous']) self.ui.connect("command", self.process_command) #can we load the icon resource? icon = self.load_resource("icon.png") if icon: self.ui.set_icon_active_asset(icon) #can we load the icon_inactive resource? icon_inactive = self.load_resource("icon_inactive.png") if icon_inactive: self.ui.set_icon_inactive_asset(icon_inactive) if self.options['history']: self.history = [] #create the recognizer try: self.recognizer = Recognizer(lang_file, dic_file, self.options['microphone']) except Exception as e: print(e) #no recognizer? bummer sys.exit() self.recognizer.connect('finished', self.recognizer_finished) print("Using Options: ", self.options) def read_key_val_file(self, file_path, lowercase_key=False, lowercase_value=False): print(file_path) file_text = open(file_path) return_struct = {} for line in file_text: #trim the white spaces line = line.strip() #if the line has length and the first char isn't a hash if len(line) and line[0] != "#": #this is a parsible line (key, value) = line.split(":", 1) key = key.strip() value = value.strip() print(key, value) if lowercase_key: key = key.lower() if lowercase_value: value = value.lower() if value == "None" or value == "null": value = None if value == "True" or value == "true": value = True if value == "False" or value == "false": value = False return_struct[key] = value return return_struct def load_commands_file(self): #read the.commands file self.commands = self.read_key_val_file(command_file) def generate_sentences_corpus(self): file_lines = open(command_file) strings = open(strings_file, "w") for i in self.commands: strings.write(i.lower() + "\n") #close the strings file strings.close() def load_options_file(self): #is there an opt file? try: self.options = self.read_key_val_file(opt_file) #if there is a microphone option, convert value to int if 'microphone' in self.options: self.options['microphone'] = int(self.options['microphone']) except: print("failed to read options file") def log_history(self, text): if self.options['history']: self.history.append(text) if len(self.history) > self.options['history']: #pop off the first item self.history.pop(0) #open and truncate the blather history file hfile = open(history_file, "w") for line in self.history: hfile.write(line + "\n") #close the file hfile.close() # Print the cmd and then run the command def run_command(self, cmd): print(cmd) subprocess.call(cmd, shell=True) def recognizer_finished(self, recognizer, text): t = text.lower() #is there a matching command? if t in self.commands: #run the valid_sentence_command if there is a valid sentence command if self.options['valid_sentence_command']: subprocess.call(self.options['valid_sentence_command'], shell=True) cmd = self.commands[t] #should we be passing words? if self.options['pass_words']: cmd += " " + t self.run_command(cmd) else: self.run_command(cmd) self.log_history(text) else: #run the invalid_sentence_command if there is a valid sentence command if self.options['invalid_sentence_command']: subprocess.call(self.options['invalid_sentence_command'], shell=True) print("no matching command %s" % (t)) #if there is a UI and we are not continuous listen if self.ui: if not self.continuous_listen: #stop listening self.recognizer.pause() #let the UI know that there is a finish self.ui.finished(t) def run(self): #is a UI going to be used? if self.ui: self.ui.run() else: blather.recognizer.listen() def quit(self): sys.exit() def process_command(self, UI, command): print(command) if command == "listen": self.recognizer.listen() elif command == "stop": self.recognizer.pause() elif command == "continuous_listen": self.continuous_listen = True self.recognizer.listen() elif command == "continuous_stop": self.continuous_listen = False self.recognizer.pause() elif command == "quit": self.quit() def load_resource(self, string): local_data = os.path.join(os.path.dirname(__file__), 'data') paths = ["/usr/share/blather/", "/usr/local/share/blather", local_data] for path in paths: resource = os.path.join(path, string) if os.path.exists(resource): return resource #if we get this far, no resource was found return False
class Blather: def __init__(self, opts): #import the recognizer so Gst doesn't clobber our -h from Recognizer import Recognizer self.ui = None #keep track of the opts self.opts = opts ui_continuous_listen = False self.continuous_listen = False self.commands = {} self.read_commands() self.recognizer = Recognizer(lang_file, dic_file) self.recognizer.connect('finished',self.recognizer_finished) if opts.interface != None: if opts.interface == "q": #import the ui from qt from QtUI import UI elif opts.interface == "g": from GtkUI import UI else: print "no GUI defined" sys.exit() self.ui = UI(args,opts.continuous) self.ui.connect("command", self.process_command) if self.opts.history: self.history = [] def read_commands(self): #read the.commands file file_lines = open(command_file) strings = open(strings_file, "w") for line in file_lines: print line #trim the white spaces line = line.strip() #if the line has length and the first char isn't a hash if len(line) and line[0]!="#": #this is a parsible line (key,value) = line.split(":",1) print key, value self.commands[key.strip().lower()] = value.strip() strings.write( key.strip()+"\n") #close the strings file strings.close() def log_history(self,text): if self.opts.history: self.history.append(text) if len(self.history) > self.opts.history: #pop off the first item self.history.pop(0) #open and truncate the blather history file hfile = open(history_file, "w") for line in self.history: hfile.write( line+"\n") #close the file hfile.close() def recognizer_finished(self, recognizer, text): t = text.lower() #is there a matching command? if self.commands.has_key( t ): cmd = self.commands[t] print cmd subprocess.call(cmd, shell=True) self.log_history(text) else: print "no matching command" #if there is a UI and we are not continuous listen if self.ui: if not self.continuous_listen: #stop listening self.recognizer.pause() #let the UI know that there is a finish self.ui.finished(t) def run(self): if self.ui: self.ui.run() else: blather.recognizer.listen() def quit(self): if self.ui: self.ui.quit() sys.exit() def process_command(self, UI, command): print command if command == "listen": self.recognizer.listen() elif command == "stop": self.recognizer.pause() elif command == "continuous_listen": self.continuous_listen = True self.recognizer.listen() elif command == "continuous_stop": self.continuous_listen = False self.recognizer.pause() elif command == "quit": self.quit()