mirror of
https://github.com/zulip/zulip.git
synced 2025-11-12 18:06:44 +00:00
interactive bots: Create Howdoi bot.
This bot allows users to search technical questions from Stack Overflow.
This commit is contained in:
130
contrib_bots/lib/howdoi_bot.py
Normal file
130
contrib_bots/lib/howdoi_bot.py
Normal file
@@ -0,0 +1,130 @@
|
||||
"""
|
||||
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
|
||||
Reference in New Issue
Block a user