bots: Move contrib_bots to api/bots*.
This will make it convenient to include these bots in Zulip API releases on pypi. Fix #5009.
This commit is contained in:
parent
7531c4fb26
commit
894adb1e43
110 changed files with 36 additions and 27 deletions
0
bots/xkcd/__init__.py
Normal file
0
bots/xkcd/__init__.py
Normal file
BIN
bots/xkcd/assets/xkcd-help.png
Normal file
BIN
bots/xkcd/assets/xkcd-help.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
BIN
bots/xkcd/assets/xkcd-latest.png
Normal file
BIN
bots/xkcd/assets/xkcd-latest.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 43 KiB |
BIN
bots/xkcd/assets/xkcd-random.png
Normal file
BIN
bots/xkcd/assets/xkcd-random.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 45 KiB |
BIN
bots/xkcd/assets/xkcd-specific-id.png
Normal file
BIN
bots/xkcd/assets/xkcd-specific-id.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
BIN
bots/xkcd/assets/xkcd-wrong-command.png
Normal file
BIN
bots/xkcd/assets/xkcd-wrong-command.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
BIN
bots/xkcd/assets/xkcd-wrong-id.png
Normal file
BIN
bots/xkcd/assets/xkcd-wrong-id.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
40
bots/xkcd/readme.md
Normal file
40
bots/xkcd/readme.md
Normal file
|
@ -0,0 +1,40 @@
|
|||
# xkcd bot
|
||||
|
||||
xkcd bot is a Zulip bot that can fetch a comic strip from xkcd. To use xkcd
|
||||
bot you can simply call it with `@xkcd` followed by a command. Like this:
|
||||
|
||||
```
|
||||
@xkcd <command>
|
||||
```
|
||||
|
||||
xkcd bot has four commands:
|
||||
|
||||
1. `help`
|
||||
This command is used to list all commands that can be used with this bot.
|
||||
You can use this command by typing `@xkcd help` in a stream.
|
||||

|
||||
|
||||
2. `latest`
|
||||
This command is used to fetch the latest comic strip from xkcd. You can use
|
||||
this command by typing `@xkcd latest` in a stream.
|
||||

|
||||
|
||||
3. `random`
|
||||
This command is used to fetch a random comic strip from xkcd. You can use
|
||||
this command by typing `@xkcd random` in a stream, xkcd bot will post a
|
||||
random xkcd comic strip.
|
||||

|
||||
|
||||
4. `<comic_id>`
|
||||
To fetch a comic strip based on id, you can directly use `@xkcd <comic_id>`,
|
||||
for example if you want to fetch a comic strip with id 1234, you can type
|
||||
`@xkcd 1234`, xkcd bot will post a comic strip with id 1234.
|
||||

|
||||
|
||||
If you type a wrong command to xkcd bot, xkcd bot will post information
|
||||
you'd get from `@xkcd help`.
|
||||

|
||||
|
||||
And if you type a wrong id, xkcd bot will post a message that an xkcd comic
|
||||
strip with that id is not available.
|
||||

|
43
bots/xkcd/test_xkcd.py
Normal file
43
bots/xkcd/test_xkcd.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
|
||||
import mock
|
||||
import os
|
||||
import sys
|
||||
|
||||
our_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, os.path.normpath(os.path.join(our_dir)))
|
||||
# For dev setups, we can find the API in the repo itself.
|
||||
if os.path.exists(os.path.join(our_dir, '..')):
|
||||
sys.path.insert(0, '..')
|
||||
from bots_test_lib import BotTestCase
|
||||
|
||||
class TestXkcdBot(BotTestCase):
|
||||
bot_name = "xkcd"
|
||||
|
||||
@mock.patch('logging.exception')
|
||||
def test_bot(self, mock_logging_exception):
|
||||
help_txt = "xkcd bot supports these commands:"
|
||||
err_txt = "xkcd bot only supports these commands:"
|
||||
commands = '''
|
||||
* `@xkcd help` to show this help message.
|
||||
* `@xkcd latest` to fetch the latest comic strip from xkcd.
|
||||
* `@xkcd random` to fetch a random comic strip from xkcd.
|
||||
* `@xkcd <comic id>` to fetch a comic strip based on `<comic id>` e.g `@xkcd 1234`.'''
|
||||
invalid_id_txt = "Sorry, there is likely no xkcd comic strip with id: #"
|
||||
expected = {
|
||||
"": err_txt+commands,
|
||||
"help": help_txt+commands,
|
||||
"x": err_txt+commands,
|
||||
"0": invalid_id_txt + "0",
|
||||
"1": ("#1: **Barrel - Part 1**\n[Don't we all.]"
|
||||
"(https://imgs.xkcd.com/comics/barrel_cropped_(1).jpg)"),
|
||||
"1800": ("#1800: **Chess Notation**\n"
|
||||
"[I've decided to score all my conversations "
|
||||
"using chess win-loss notation. (??)]"
|
||||
"(https://imgs.xkcd.com/comics/chess_notation.png)"),
|
||||
"999999999": invalid_id_txt + "999999999",
|
||||
}
|
||||
self.check_expected_responses(expected)
|
114
bots/xkcd/xkcd.py
Normal file
114
bots/xkcd/xkcd.py
Normal file
|
@ -0,0 +1,114 @@
|
|||
from random import randint
|
||||
|
||||
import logging
|
||||
import requests
|
||||
|
||||
XKCD_TEMPLATE_URL = 'https://xkcd.com/%s/info.0.json'
|
||||
LATEST_XKCD_URL = 'https://xkcd.com/info.0.json'
|
||||
|
||||
class XkcdHandler(object):
|
||||
'''
|
||||
This plugin provides several commands that can be used for fetch a comic
|
||||
strip from https://xkcd.com. The bot looks for messages starting with
|
||||
"@mention-bot" and responds with a message with the comic based on provided
|
||||
commands.
|
||||
'''
|
||||
|
||||
def usage(self):
|
||||
return '''
|
||||
This plugin allows users to fetch a comic strip provided by
|
||||
https://xkcd.com. Users should preface the command with "@mention-bot".
|
||||
|
||||
There are several commands to use this bot:
|
||||
- @mention-bot help -> To show all commands the bot supports.
|
||||
- @mention-bot latest -> To fetch the latest comic strip from xkcd.
|
||||
- @mention-bot random -> To fetch a random comic strip from xkcd.
|
||||
- @mention-bot <comic_id> -> To fetch a comic strip based on
|
||||
`<comic_id>`, e.g `@mention-bot 1234`.
|
||||
'''
|
||||
|
||||
def handle_message(self, message, client, state_handler):
|
||||
xkcd_bot_response = get_xkcd_bot_response(message)
|
||||
client.send_reply(message, xkcd_bot_response)
|
||||
|
||||
class XkcdBotCommand(object):
|
||||
LATEST = 0
|
||||
RANDOM = 1
|
||||
COMIC_ID = 2
|
||||
|
||||
class XkcdNotFoundError(Exception):
|
||||
pass
|
||||
|
||||
class XkcdServerError(Exception):
|
||||
pass
|
||||
|
||||
def get_xkcd_bot_response(message):
|
||||
original_content = message['content'].strip()
|
||||
command = original_content.strip()
|
||||
|
||||
commands_help = ("%s"
|
||||
"\n* `@xkcd help` to show this help message."
|
||||
"\n* `@xkcd latest` to fetch the latest comic strip from xkcd."
|
||||
"\n* `@xkcd random` to fetch a random comic strip from xkcd."
|
||||
"\n* `@xkcd <comic id>` to fetch a comic strip based on `<comic id>` "
|
||||
"e.g `@xkcd 1234`.")
|
||||
|
||||
try:
|
||||
if command == 'help':
|
||||
return commands_help % ('xkcd bot supports these commands:')
|
||||
elif command == 'latest':
|
||||
fetched = fetch_xkcd_query(XkcdBotCommand.LATEST)
|
||||
elif command == 'random':
|
||||
fetched = fetch_xkcd_query(XkcdBotCommand.RANDOM)
|
||||
elif command.isdigit():
|
||||
fetched = fetch_xkcd_query(XkcdBotCommand.COMIC_ID, command)
|
||||
else:
|
||||
return commands_help % ('xkcd bot only supports these commands:')
|
||||
except (requests.exceptions.ConnectionError, XkcdServerError):
|
||||
logging.exception('Connection error occurred when trying to connect to xkcd server')
|
||||
return 'Sorry, I cannot process your request right now, please try again later!'
|
||||
except XkcdNotFoundError:
|
||||
logging.exception('XKCD server responded 404 when trying to fetch comic with id %s'
|
||||
% (command))
|
||||
return 'Sorry, there is likely no xkcd comic strip with id: #%s' % (command,)
|
||||
else:
|
||||
return ("#%s: **%s**\n[%s](%s)" % (fetched['num'],
|
||||
fetched['title'],
|
||||
fetched['alt'],
|
||||
fetched['img']))
|
||||
|
||||
def fetch_xkcd_query(mode, comic_id=None):
|
||||
try:
|
||||
if mode == XkcdBotCommand.LATEST: # Fetch the latest comic strip.
|
||||
url = LATEST_XKCD_URL
|
||||
|
||||
elif mode == XkcdBotCommand.RANDOM: # Fetch a random comic strip.
|
||||
latest = requests.get(LATEST_XKCD_URL)
|
||||
|
||||
if latest.status_code != 200:
|
||||
raise XkcdServerError()
|
||||
|
||||
latest_id = latest.json()['num']
|
||||
random_id = randint(1, latest_id)
|
||||
url = XKCD_TEMPLATE_URL % (str(random_id))
|
||||
|
||||
elif mode == XkcdBotCommand.COMIC_ID: # Fetch specific comic strip by id number.
|
||||
if comic_id is None:
|
||||
raise Exception('Missing comic_id argument')
|
||||
url = XKCD_TEMPLATE_URL % (comic_id)
|
||||
|
||||
fetched = requests.get(url)
|
||||
|
||||
if fetched.status_code == 404:
|
||||
raise XkcdNotFoundError()
|
||||
elif fetched.status_code != 200:
|
||||
raise XkcdServerError()
|
||||
|
||||
xkcd_json = fetched.json()
|
||||
except requests.exceptions.ConnectionError as e:
|
||||
logging.warning(e)
|
||||
raise
|
||||
|
||||
return xkcd_json
|
||||
|
||||
handler_class = XkcdHandler
|
Loading…
Add table
Add a link
Reference in a new issue