def processSpeechRules(self, text): '''Process all of the speech rules for the recognized speech text. * text -- The recognized speech text ''' self.log.debug("Processing %d speech rules for [%s]" % \ (len(self.__speechRules), text), level=10) # Process all of the speech rules for this plugin for ruleFunction in self.__speechRules: # If the given speech rule applies, then apply # it to the given text if self.__speechRuleApplies(ruleFunction, text): try: self.log.debug("Processing speech rule: %s" % \ ruleFunction.__name__, level=10) # Speech rule functions have no return value, make sure # to pass it the lowercase version of the text resp = ruleFunction(text.lower()) # Only apply the first matched speech rule return True if type(resp) != GeneratorType else resp except: self.log.error("Error in speech rule [%s]" % \ ruleFunction.__name__) self.log.error(getStackTrace()) # The text was not matched by any speech rules return False
def processFilters(self, obj, direction): """Process all the plugin filters for this object and data direction. * obj -- The object * direction -- The data direction """ response = None try: response = self.__processFilters(obj, direction) except: self.log.error("Failed processing filters") self.log.error(getStackTrace()) # Determine if the response should be used if response is not None: # If the response is False, then the object should be dropped # If the object has the same class as the original object, then # it should be returning if response == False: obj = None elif response.get("class") == obj.get("class"): obj = response return obj
def processFilters(self, obj, direction): '''Process all the plugin filters for this object and data direction. * obj -- The object * direction -- The data direction ''' response = None try: response = self.__processFilters(obj, direction) except: self.log.error("Failed processing filters") self.log.error(getStackTrace()) # Determine if the response should be used if response is not None: # If the response is False, then the object should be dropped # If the object has the same class as the original object, then # it should be returning if response == False: obj = None elif response.get('class') == obj.get('class'): obj = response return obj
def processSpeechRules(self, text): """Process all the plugin speech rules for this recognized text. * text -- The recognized text """ try: # Speech rules return True to indicate that the response from # Apple's server should be overriden. The speech rules return # False to indicate that the response from Apple's server should # be used. return self.__processSpeechRules(text) except: self.log.error("Failed processing speech rules") self.log.error(getStackTrace()) # Have Siri respond with the the error response self.say(self._options.get(Sections.Responses, Ids.ErrorResponse)) self.completeRequest() return True
def processSpeechRules(self, text): '''Process all the plugin speech rules for this recognized text. * text -- The recognized text ''' try: # Speech rules return True to indicate that the response from # Apple's server should be overriden. The speech rules return # False to indicate that the response from Apple's server should # be used. return self.__processSpeechRules(text) except: self.log.error("Failed processing speech rules") self.log.error(getStackTrace()) # Have Siri respond with the the error response self.say(self._options.get(Sections.Responses, Ids.ErrorResponse)) self.completeRequest() return True
def loadPlugins(self, directory): '''Load all of the plugins from the plugins directory. * directory -- The plugins directory ''' self.__addPluginsToPath(directory) # Traverse through all of the plugins for filename in listdir(directory): if not filename.startswith("__") and filename.endswith(".py"): # Get the module name from the filename by removing the # file extension pluginName = splitext(filename)[0] try: self.log.debug("Loading plugin [%s]" % pluginName, level=10) # Get the plugin class, and create the plugin object pluginClass = self.__importPlugin(pluginName) plugin = pluginClass(self, self._logger) # Ensure that all plugins subclass the base plugin if isinstance(plugin, BasePlugin): # Force plugins to have unique names if plugin.name not in self._pluginMap: self._pluginMap[plugin.name] = plugin else: self.log.error("Plugin in file [%s] has name " \ "[%s] which already exists!" % \ (pluginName, plugin.name)) else: self.log.error("Plugin [%s] must be a subclass of " \ "the BasePlugin class!" % \ plugin.name) except: self.log.error("Failed to load plugin [%s]" % pluginName) self.log.error(getStackTrace()) continue
def __fixItems(self, data): '''Ensure that any entries in the given dictionary that contain non-printable characters are wrapped with the biplist Data object. * data -- The data dictionary ''' # Traverse all the keys in the dictionary for key, item in data.iteritems(): # Determine how to handle the current value if key in self.UnicodeKeys: try: # Attempt to convert the string to unicode data[key] = unicode(item, "utf-8") except: data[key] = item self.__log.error("Error translating to unicode: %s, %s" % \ (type(item), item)) self.__log.error(getStackTrace()) elif key in self.DateKeys: # @todo: I have still seen this fail to properly determine # the date. The speakable text date can be different # than the displayed date. # Convert the number of seconds since the epoch into # an actual date # NOTE: This works better than just passing the time to the # fromtimestamp function as that throws exceptions sometimes date = datetime.fromtimestamp(0) + timedelta(seconds=item) # The epoch that these dates use is thirty one years in the # future from the standard epoch date date = date.replace(year=date.year + 31) data[key] = date else: data[key] = self.__fixItem(item) return data
def loadPlugins(self, directory): """Load all of the plugins from the plugins directory. * directory -- The plugins directory """ self.__addPluginsToPath(directory) # Traverse through all of the plugins for filename in listdir(directory): if not filename.startswith("__") and filename.endswith(".py"): # Get the module name from the filename by removing the # file extension pluginName = splitext(filename)[0] try: self.log.debug("Loading plugin [%s]" % pluginName, level=10) # Get the plugin class, and create the plugin object pluginClass = self.__importPlugin(pluginName) plugin = pluginClass(self, self._logger) # Ensure that all plugins subclass the base plugin if isinstance(plugin, BasePlugin): # Force plugins to have unique names if plugin.name not in self._pluginMap: self._pluginMap[plugin.name] = plugin else: self.log.error( "Plugin in file [%s] has name " "[%s] which already exists!" % (pluginName, plugin.name) ) else: self.log.error("Plugin [%s] must be a subclass of " "the BasePlugin class!" % plugin.name) except: self.log.error("Failed to load plugin [%s]" % pluginName) self.log.error(getStackTrace()) continue
def processFilters(self, obj, direction): '''Process the filters for this Plugin. .. note:: This function should return False if the object should be dropped, return None if the object is ignored by this filter, or return the new object corresponding to the response. * commandName -- The name of the object * direction -- The direction the object traveled to be received ''' self.log.debug("Processing %d filters" % len(self.__filters), level=10) # Process all of the filters for this plugin for filterFunction in self.__filters: # Determine if this filter function applies to the current # object or direction if self.__filterApplies(filterFunction, direction, obj): # Filters return None when they ignore the object, otherwise # they have some effect on the current object try: filterName = filterFunction.__name__ self.log.debug("Processing filter: %s" % filterName, level=10) response = filterFunction(obj, direction) if response is not None: return response except: self.log.error("Error in filter [%s]" % \ filterFunction.__name__) self.log.error(getStackTrace()) # Object is ignored by this plugin return None