""" This bot uses the python library `howdoi` which is not a dependency of Zulip. To use this module, you will have to install it in your local machine. In your terminal, enter the following command: $ sudo pip install howdoi --upgrade Note: * You might have to use `pip3` if you are using python 3. * The install command would also download any dependency required by `howdoi`. """ import sys import logging from textwrap import fill try: from howdoi.howdoi import howdoi except ImportError: logging.error("Dependency missing!!\n%s" % (__doc__)) sys.exit(0) class HowdoiHandler(object): ''' This plugin facilitates searching Stack Overflow for techanical answers based on the Python library `howdoi`. To get the best possible answer, only include keywords in your questions. There are two possible commands: * @howdowe > This would return the answer to the same stream that it was called from. * @howdoi > The bot would send a private message to the user containing the answer. By default, howdoi only returns the coding section of the first search result if possible, to see the full answer from Stack Overflow, append a '!' to the commands. (ie '@howdoi!', '@howdowe!') ''' MAX_LINE_LENGTH = 85 def usage(self): return ''' This plugin will allow users to get techanical answers from Stackoverflow. Users should preface their questions with one of the following: * @howdowe > Answer to the same stream * @howdoi > Answer via private message * @howdowe! OR @howdoi! > Full answer from SO ''' def triage_message(self, message): cmd_list = ['@howdowe', '@howdoi', '@howdowe!', '@howdoi!'] question = message['content'] # This next line of code is defensive, as we never want # to get into an infinite loop of searching answers # from Stackoverflow! if message['sender_email'].startswith('howdoi'): return False is_howdoi = any([question.startswith(cmd) for cmd in cmd_list]) return is_howdoi def line_wrap(self, string, length): lines = string.split("\n") wrapped = [(fill(line) if len(line) > length else line) for line in lines] return "\n".join(wrapped).strip() def get_answer(self, command, query): question = query[len(command):].strip() result = howdoi(dict( query=question, num_answers=1, pos=1, all=command[-1] == '!', color=False )) _answer = self.line_wrap(result, HowdoiHandler.MAX_LINE_LENGTH) answer = "Answer to '%s':\n```\n%s\n```" % (question, _answer) return answer def handle_message(self, message, client, state_handler): question = message['content'] if question.startswith('@howdowe!'): client.send_message(dict( type='stream', to=message['display_recipient'], subject=message['subject'], content=self.get_answer('@howdowe!', question) )) elif question.startswith('@howdoi!'): client.send_message(dict( type='private', to=message['sender_email'], content=self.get_answer('@howdoi!', question) )) elif question.startswith('@howdowe'): client.send_message(dict( type='stream', to=message['display_recipient'], subject=message['subject'], content=self.get_answer('@howdowe', question) )) elif question.startswith('@howdoi'): client.send_message(dict( type='private', to=message['sender_email'], content=self.get_answer('@howdoi', question) )) handler_class = HowdoiHandler