bots: Add bot for uploading files to Zulip server.

Add file_uploader bot as an example of using
ExternalBotHandler's methods for uploading files
to Zulip server.
This commit is contained in:
novokrest 2018-05-05 09:18:56 +03:00 committed by showell
parent e5239c5c54
commit 7fc1ff5e0e
7 changed files with 122 additions and 1 deletions

View file

@ -0,0 +1,21 @@
# File Uploader Bot
This bot allows the user to upload a file with a given path to the Zulip server.
## Usage
Use this bot with any of the following commands:
- `@uploader <local_file_path>` : Upload a file, where `<local_file_path>` is the path to the file
- `@uploader help` : Display help message
### Usage examples
The following command will upload the file `/tmp/image.png` to the Zulip server:
```
@**uploader** /tmp/image.png
```
Here's an example response:
> [image.png](https://server.zulipchat.com/user_uploads/3787/RgoZReSsfMjlQSzvVxjIgAQy/image.png)

View file

@ -0,0 +1,41 @@
from typing import Any, Dict
import os
from pathlib import Path
class FileUploaderHandler(object):
def usage(self) -> str:
return (
'This interactive bot is used to upload files (such as images) to the Zulip server:'
'\n- @uploader <local_file_path> : Upload a file, where <local_file_path> is the path to the file'
'\n- @uploader help : Display help message'
)
def handle_message(self, message: Dict[str, str], bot_handler: Any) -> None:
HELP_STR = (
'Use this bot with any of the following commands:'
'\n* `@uploader <local_file_path>` : Upload a file, where `<local_file_path>` is the path to the file'
'\n* `@uploader help` : Display help message'
)
content = message['content'].strip()
if content == 'help':
bot_handler.send_reply(message, HELP_STR)
return
path = Path(os.path.expanduser(content))
if not path.is_file():
bot_handler.send_reply(message, 'File `{}` not found'.format(content))
return
path = path.resolve()
upload = bot_handler.upload_file_from_path(str(path))
if upload['result'] != 'success':
msg = upload['msg']
bot_handler.send_reply(message, 'Failed to upload `{}` file: {}'.format(path, msg))
return
uploaded_file_reply = '[{}]({})'.format(path.name, upload['uri'])
bot_handler.send_reply(message, uploaded_file_reply)
handler_class = FileUploaderHandler

View file

@ -0,0 +1,39 @@
from unittest.mock import patch, MagicMock, Mock
from zulip_bots.test_lib import (
get_bot_message_handler,
StubBotHandler,
BotTestCase,
DefaultTests,
)
from pathlib import Path
class TestFileUploaderBot(BotTestCase, DefaultTests):
bot_name = "file_uploader"
@patch('pathlib.Path.is_file', return_value=False)
def test_file_not_found(self, is_file: Mock) -> None:
self.verify_reply('file.txt', 'File `file.txt` not found')
@patch('pathlib.Path.resolve', return_value=Path('/file.txt'))
@patch('pathlib.Path.is_file', return_value=True)
def test_file_upload_failed(self, is_file: Mock, resolve: Mock) -> None:
server_reply = dict(result='', msg='error')
with patch('zulip_bots.test_lib.StubBotHandler.upload_file_from_path',
return_value=server_reply) as m:
self.verify_reply('file.txt', 'Failed to upload `/file.txt` file: error')
@patch('pathlib.Path.resolve', return_value=Path('/file.txt'))
@patch('pathlib.Path.is_file', return_value=True)
def test_file_upload_success(self, is_file: Mock, resolve: Mock) -> None:
server_reply = dict(result='success', uri='https://file/uri')
with patch('zulip_bots.test_lib.StubBotHandler.upload_file_from_path',
return_value=server_reply) as m:
self.verify_reply('file.txt', '[file.txt](https://file/uri)')
def test_help(self):
self.verify_reply('help',
('Use this bot with any of the following commands:'
'\n* `@uploader <local_file_path>` : Upload a file, where `<local_file_path>` is the path to the file'
'\n* `@uploader help` : Display help message'))