bots: Move all bots and the bots API to separate package.

This commit is contained in:
Eeshan Garg 2017-07-18 01:47:16 -02:30
parent 928d5ca16d
commit 879f44ab3a
130 changed files with 183 additions and 144 deletions

1
.gitignore vendored
View file

@ -10,7 +10,6 @@ dist
build
eggs
parts
var
sdist
develop-eggs
.installed.cfg

View file

@ -1,86 +0,0 @@
#!/usr/bin/env python
from __future__ import print_function
from __future__ import absolute_import
import importlib
import logging
import optparse
import os
import sys
import provision
from types import ModuleType
our_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, our_dir)
from bot_lib import run_message_handler_for_bot
def validate_path(bots_fn):
# type: (str) -> None
bots_fn = os.path.realpath(bots_fn)
if not os.path.dirname(bots_fn).startswith(os.path.normpath(os.path.join(our_dir, "../bots"))):
print('Sorry, we will only import code from api/bots.')
sys.exit(1)
if not bots_fn.endswith('.py'):
print('Please use a .py extension for library files.')
sys.exit(1)
def get_lib_module(bots_fn):
# type: (str) -> ModuleType
base_bots_fn = os.path.basename(os.path.splitext(bots_fn)[0])
sys.path.insert(1, os.path.dirname(bots_fn))
module_name = base_bots_fn
module = importlib.import_module(module_name)
return module
def run():
# type: () -> None
usage = '''
./run.py <lib file>
Example: ./run.py lib/followup.py
(This program loads bot-related code from the
library code and then runs a message loop,
feeding messages to the library code to handle.)
Please make sure you have a current ~/.zuliprc
file with the credentials you want to use for
this bot.
See lib/readme.md for more context.
'''
parser = optparse.OptionParser(usage=usage)
parser.add_option('--quiet', '-q',
action='store_true',
help='Turn off logging output.')
parser.add_option('--config-file',
action='store',
help='(alternate config file to ~/.zuliprc)')
parser.add_option('--provision',
action='store_true',
help='Install dependencies for the bot')
parser.add_option('--force',
action='store_true',
help='Try running the bot even if dependencies install fails.')
(options, args) = parser.parse_args()
if len(args) == 0:
print('You must specify a library!')
sys.exit(1)
bots_fn = args[0]
validate_path(bots_fn)
if options.provision:
print("Provisioning")
provision.provision_bot(os.path.dirname(bots_fn), options.force)
lib_module = get_lib_module(bots_fn)
if not options.quiet:
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
run_message_handler_for_bot(
lib_module=lib_module,
config_file=options.config_file,
quiet=options.quiet
)
if __name__ == '__main__':
run()

View file

@ -17,11 +17,11 @@ def dir_join(dir1, dir2):
if __name__ == '__main__':
bots_dir = os.path.dirname(os.path.abspath(__file__))
root_dir = dir_join(bots_dir, '..')
bots_test_dir = dir_join(bots_dir, '../bots')
tools_dir = os.path.dirname(os.path.abspath(__file__))
bots_dir = os.path.join(tools_dir, '..', 'zulip_bots', 'zulip_bots')
bots_test_dir = dir_join(bots_dir, 'bots')
sys.path.insert(0, root_dir)
sys.path.insert(0, bots_dir)
sys.path.insert(0, bots_test_dir)
btd = bots_test_dir
@ -57,7 +57,7 @@ if __name__ == '__main__':
sys.path.insert(0, dep_path)
try:
suites.append(loader.discover(start_dir = dir_join(bots_test_dir, bot_to_test),
top_level_dir = root_dir))
top_level_dir = bots_dir))
except ImportError:
logging.error("Bot %s requires __init__.py to be added" % (bot_to_test))
failed = True

5
zulip_bots/MANIFEST.in Normal file
View file

@ -0,0 +1,5 @@
include zulip_bots/bots/giphy/fixtures/test_1.json
include zulip_bots/bots/github_detail/fixtures/test_404.json
include zulip_bots/bots/github_detail/fixtures/test_issue.json
include zulip_bots/bots/github_detail/fixtures/test_pull.json

View file

@ -24,13 +24,17 @@ to messages in any of the following settings:
account specific authentication, for example: a gmail bot that lets
one send emails directly through Zulip.
## Installing
To install the bots and bots API, run:
python setup.py install
## Running bots
Here is an example of running the "follow-up" bot from
inside a Zulip repo (and in your remote instance):
Here is an example of running the "follow-up" bot:
cd ~/zulip/api
bots_api/run.py bots/followup/followup.py --config-file ~/.zuliprc-prod
zulip-run-bot followup --config-file ~/.zuliprc-prod
Once the bot code starts running, you will see a
message explaining how to use the bot, as well as

78
zulip_bots/setup.py Executable file
View file

@ -0,0 +1,78 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
import sys
# We should be installable with either setuptools or distutils.
package_info = dict(
name='zulip_bots',
version='0.3.1',
description='Zulip\'s Bot framework',
author='Zulip Open Source Project',
author_email='zulip-devel@googlegroups.com',
classifiers=[
'Development Status :: 4 - Beta',
'Environment :: Web Environment',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Topic :: Communications :: Chat',
],
url='https://www.zulip.org/',
entry_points={
'console_scripts': [
'zulip-run-bot=zulip_bots.run:main',
],
},
include_package_data=True,
) # type: Dict[str, Any]
setuptools_info = dict(
install_requires=[
'zulip>=0.3.1',
'mock>=2.0.0',
'html2text', # for bots/define
'PyDictionary', # for bots/thesaurus
],
)
try:
from setuptools import setup, find_packages
package_info.update(setuptools_info)
package_info['packages'] = find_packages()
except ImportError:
from distutils.core import setup
from distutils.version import LooseVersion
from importlib import import_module
# Manual dependency check
def check_dependency_manually(module_name, version=None):
try:
module = import_module(module_name)
if version is not None:
assert(LooseVersion(module.__version__) >= LooseVersion(version))
except (ImportError, AssertionError):
if version is not None:
print("{name}>={version} is not installed.".format(
req=req, version=version), file=sys.stderr)
else:
print("{name} is not installed.".format(name=module_name), file=sys.stderr)
sys.exit(1)
check_dependency_manually('zulip', '0.3.1')
check_dependency_manually('mock', '2.0.0')
check_dependency_manually('html2text')
check_dependency_manually('PyDictionary')
# Include all submodules under bots/
package_list = ['zulip_bots']
dirs = os.listdir('zulip_bots/bots/')
for dir_name in dirs:
if os.path.isdir(os.path.join('zulip_bots/bots/', dir_name)):
package_list.append('zulip_bots.bots.' + dir_name)
package_info['packages'] = package_list
setup(**package_info)

View file

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

View file

@ -5,11 +5,10 @@ from __future__ import division
import copy
import importlib
import sys
from math import log10, floor
import utils
import re
from zulip_bots.bots.converter import utils
def is_float(value):
try:

View file

@ -3,7 +3,7 @@
from __future__ import absolute_import
from __future__ import print_function
from bots_test_lib import BotTestCase
from zulip_bots.test_lib import BotTestCase
class TestConverterBot(BotTestCase):
bot_name = "converter"

View file

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 73 KiB

View file

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View file

@ -3,7 +3,7 @@
from __future__ import absolute_import
from __future__ import print_function
from bots_test_lib import BotTestCase
from zulip_bots.test_lib import BotTestCase
class TestDefineBot(BotTestCase):
bot_name = "define"

View file

Before

Width:  |  Height:  |  Size: 287 KiB

After

Width:  |  Height:  |  Size: 287 KiB

View file

Before

Width:  |  Height:  |  Size: 180 KiB

After

Width:  |  Height:  |  Size: 180 KiB

View file

Before

Width:  |  Height:  |  Size: 160 KiB

After

Width:  |  Height:  |  Size: 160 KiB

View file

Before

Width:  |  Height:  |  Size: 170 KiB

After

Width:  |  Height:  |  Size: 170 KiB

View file

@ -3,7 +3,7 @@
from __future__ import absolute_import
from __future__ import print_function
from bots_test_lib import BotTestCase
from zulip_bots.test_lib import BotTestCase
class TestEncryptBot(BotTestCase):
bot_name = "encrypt"

View file

@ -3,7 +3,7 @@
from __future__ import absolute_import
from __future__ import print_function
from bots_test_lib import BotTestCase
from zulip_bots.test_lib import BotTestCase
class TestFollowUpBot(BotTestCase):
bot_name = "followup"

View file

@ -5,7 +5,7 @@ from __future__ import print_function
import json
from bots_test_lib import BotTestCase
from zulip_bots.test_lib import BotTestCase
class TestGiphyBot(BotTestCase):
bot_name = "giphy"

View file

@ -27,7 +27,7 @@ Here is an example of running the `git_hub_comment` bot from
inside a Zulip repo:
`cd ~/zulip/api`
`bots_api/run.py bots/git_hub_comment/git_hub_comment.py --config-file ~/.zuliprc-prod`
`zulip-run-bot git_hub_comment --config-file ~/.zuliprc-prod`
Once the bot code starts running, you will see a
message explaining how to use the bot, as well as
@ -49,5 +49,3 @@ page to create a user-owned bot.
email=someuser@example.com
key=<your api key>
site=https://zulip.somewhere.com

View file

@ -3,16 +3,9 @@
from __future__ import absolute_import
from __future__ import print_function
import os
import sys
import json
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
from zulip_bots.test_lib import BotTestCase
class TestGithubDetailBot(BotTestCase):
bot_name = "github_detail"

View file

@ -5,7 +5,7 @@ from __future__ import print_function
from six.moves import zip
from bots_test_lib import BotTestCase
from zulip_bots.test_lib import BotTestCase
class TestHelloWorldBot(BotTestCase):
bot_name = "helloworld"

View file

@ -5,7 +5,7 @@ from __future__ import print_function
from six.moves import zip
from bots_test_lib import BotTestCase
from zulip_bots.test_lib import BotTestCase
class TestHelpBot(BotTestCase):
bot_name = "help"

View file

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

View file

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

View file

Before

Width:  |  Height:  |  Size: 9 KiB

After

Width:  |  Height:  |  Size: 9 KiB

View file

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View file

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 83 KiB

View file

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 49 KiB

View file

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

View file

@ -1,6 +1,5 @@
import json
import os
import sys
from random import choice
@ -12,9 +11,6 @@ except ImportError:
Please: pip install chatterbot""")
BOTS_DIR = os.path.dirname(os.path.abspath(__file__))
os.chdir(os.path.dirname(BOTS_DIR))
sys.path.insert(0, os.path.dirname(BOTS_DIR))
JOKES_PATH = os.path.join(BOTS_DIR, 'assets/var/jokes.json')
DATABASE_PATH = os.path.join(BOTS_DIR, 'assets/var/database.db')
DIRECTORY_PATH = os.path.join(BOTS_DIR, 'assets')

View file

@ -3,7 +3,7 @@
from __future__ import absolute_import
from __future__ import print_function
from bots_test_lib import BotTestCase
from zulip_bots.test_lib import BotTestCase
class TestThesaurusBot(BotTestCase):
bot_name = "thesaurus"

View file

@ -3,7 +3,7 @@
from __future__ import absolute_import
from __future__ import print_function
from bots_test_lib import BotTestCase
from zulip_bots.test_lib import BotTestCase
class TestVirtualFsBot(BotTestCase):
bot_name = "virtual_fs"

View file

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 67 KiB

Some files were not shown because too many files have changed in this diff Show more