"""A retarded little bot program written in honor of a retarded little man. This module implements BrtBot, which scans textual input from strings and produces random responses from a YAML database file. """ __version__ = '1.02' import os import random import re import yaml class BrtBot: """BrtBot main class.""" def __init__(self, filename='bedrocktruth'): """Constructor. Arguments: filename: str, identifies the file named 'brt-%s.yaml' containing quote data in same directory as source file. Defaults to 'bedrocktruth'. """ quotes_file = open(os.path.split(__file__)[0] + 'brt-%s.yaml' % filename) self.quotes = yaml.load(quotes_file) quotes_file.close() self.keywords = set() self.quote_sets = {} for quote, keywords in self.quotes['specific']: for keyword in keywords: # Add all keywords to the master keyword set self.keywords.add(keyword) # Generate mapping from keyword to quote if keyword not in self.quote_sets: self.quote_sets[keyword] = set() self.quote_sets[keyword].add(quote) def _scan(self, input): """Scan input for keywords from the quotes file. Arguments: input: str, contains search text Returns: Tuple of keywords found. """ keywords = [] for keyword in self.keywords: if re.search(keyword, input, re.IGNORECASE): keywords.append(keyword) return tuple(keywords) def _find_quotes(self, keywords): """ Find quotes related to keywords. Arguments: keywords: iterable, gives keywords for which to search Returns: Tuple of found quotes. """ quotes = set() # The union of all keyword sets can produce heavily discursive, # non-sequitur responses. # # ...and that's a vital feature for any wingnut emulator for keyword in keywords: quotes = quotes.union(self.quote_sets[keyword]) return tuple(quotes) def blather(self, input): """Crank out some good old-fashioned BRT blather. Arguments: input: str, contains search text Returns: One randomly selected quote relevant to keywords found in input, or one randomly selected off-hand remark if no keywords match. """ keywords = self._scan(input) # Produce a response relevant to keywords if possible if keywords: quotes = self._find_quotes(keywords) # Use a stock answer if all else fails else: quotes = self.quotes['off-hand'] return quotes[random.randint(0, len(quotes) - 1)]