Skip to content
This repository has been archived by the owner on Mar 12, 2019. It is now read-only.

Commit

Permalink
Merge pull request #20 from marvinpinto/ping-plugin
Browse files Browse the repository at this point in the history
Add a Ping plugin to Charlesbot!
  • Loading branch information
marvinpinto committed Sep 21, 2015
2 parents 80135ed + df1e6eb commit ca8bf36
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 3 deletions.
48 changes: 48 additions & 0 deletions charlesbot/plugins/ping_plugin.py
@@ -0,0 +1,48 @@
from charlesbot.base_plugin import BasePlugin
from charlesbot.util.parse import does_msg_contain_prefix
from charlesbot.slack.slack_message import SlackMessage
from charlesbot.slack.slack_pong import SlackPong
import asyncio
from aiocron import crontab
import pkg_resources


class Ping(BasePlugin):

def __init__(self):
super().__init__("Ping Pong")
self.schedule_ping_frequency()
self.get_package_version_number()

def get_package_version_number(self): # pragma: no cover
self.version = pkg_resources.require("charlesbot")[0].version

def schedule_ping_frequency(self): # pragma: no cover
"Send a ping message to slack every 20 seconds"
ping = crontab('* * * * * */20', func=self.send_ping, start=False)
ping.start()

def get_help_message(self):
return "!version - List the running CharlesBOT version"

@asyncio.coroutine
def process_message(self, message):
if not type(message) in [SlackMessage, SlackPong]:
return

if type(message) is SlackMessage:
if does_msg_contain_prefix("!version", message.text):
yield from self.send_version_message(message.channel)

if type(message) is SlackPong:
self.log.debug(str(message))

@asyncio.coroutine
def send_version_message(self, channel_id): # pragma: no cover
version_str = "CharlesBOT version %s" % self.version
yield from self.slack.send_channel_message(channel_id,
version_str)

@asyncio.coroutine
def send_ping(self): # pragma: no cover
yield from self.slack.send_ping_message()
6 changes: 6 additions & 0 deletions charlesbot/robot.py
Expand Up @@ -49,8 +49,14 @@ def initialize_plugins(self):
return return_list

def initialize_static_plugins(self):
self.initialize_ping_plugin()
self.initialize_help_plugin()

def initialize_ping_plugin(self):
from charlesbot.plugins.ping_plugin import Ping
p = Ping()
self.plugin_list.append(p)

def initialize_help_plugin(self):
from charlesbot.plugins.help_plugin import Help
h = Help()
Expand Down
6 changes: 6 additions & 0 deletions charlesbot/slack/slack_connection.py
Expand Up @@ -53,6 +53,7 @@ def get_stream_messages(self):
def get_message_type(self, msg):
self.initialize()
obj_list = [
"charlesbot.slack.slack_pong.SlackPong",
"charlesbot.slack.slack_channel_joined.SlackChannelJoined",
"charlesbot.slack.slack_channel_left.SlackChannelLeft",
"charlesbot.slack.slack_group_joined.SlackGroupJoined",
Expand All @@ -74,6 +75,11 @@ def send_channel_message(self, channel_id, message): # pragma: no cover
self.initialize()
self.sc.rtm_send_message(channel_id, message)

@asyncio.coroutine
def send_ping_message(self): # pragma: no cover
self.initialize()
self.sc.server.ping()

@asyncio.coroutine
def api_call(self, api_endpoint, **kwargs):
self.initialize()
Expand Down
15 changes: 15 additions & 0 deletions charlesbot/slack/slack_pong.py
@@ -0,0 +1,15 @@
from charlesbot.slack.slack_base_object import SlackBaseObject


class SlackPong(SlackBaseObject):

properties = ['type',
'reply_to',
'time']

def __init__(self, **kwargs):
super().__init__(**kwargs)

@property
def compatibility_key(self):
return "pong"
3 changes: 3 additions & 0 deletions requirements.txt
@@ -1,7 +1,10 @@
PyYAML==3.11
aiocron==0.3
aiohttp==0.17.0
cchardet==0.3.5
chardet==2.3.0
croniter==0.3.8
python-dateutil==2.4.2
websocket-client==0.32.0
wheel==0.24.0
git+https://github.com/slackhq/python-slackclient.git@ba71b24603f63e54e704d0481812efcd9f7b8c14
3 changes: 3 additions & 0 deletions setup.py
Expand Up @@ -44,6 +44,9 @@
"cchardet",
"aiohttp",
"PyYAML",
"aiocron",
"croniter",
"python-dateutil",
],

test_suite='nose.collector'
Expand Down
Empty file.
59 changes: 59 additions & 0 deletions tests/plugins/ping_plugin/test_ping_plugin.py
@@ -0,0 +1,59 @@
import asynctest
from asynctest.mock import MagicMock
from asynctest.mock import call
from asynctest.mock import patch
from charlesbot.slack.slack_message import SlackMessage
from charlesbot.slack.slack_pong import SlackPong


class TestPingPlugin(asynctest.TestCase):

def setUp(self):
patcher1 = patch('charlesbot.plugins.ping_plugin.Ping.schedule_ping_frequency') # NOQA
self.addCleanup(patcher1.stop)
self.mock_schedule_ping_frequency = patcher1.start()

patcher2 = patch('charlesbot.plugins.ping_plugin.Ping.get_package_version_number') # NOQA
self.addCleanup(patcher2.stop)
self.mock_get_package_version_number = patcher2.start()

from charlesbot.plugins.ping_plugin import Ping
self.ping = Ping()
self.ping.send_version_message = MagicMock()

@asynctest.ignore_loop
def test_get_help_string(self):
"""
Don't care about the contents of the help string, just as long as there
is something in there.
"""
help_str = self.ping.get_help_message()
self.assertTrue(help_str)

def test_process_incorrect_msg_type(self):
yield from self.ping.process_message("invalid")
self.assertEqual(self.ping.send_version_message.mock_calls, [])

def test_process_irrelevant_slack_message(self):
msg = SlackMessage(type="message",
user="U2147483697",
channel="C2147483705",
text="This is not the prefix you are looking for")
yield from self.ping.process_message(msg)
self.assertEqual(self.ping.send_version_message.mock_calls, [])

def test_process_slack_message(self):
msg = SlackMessage(type="message",
user="U2147483697",
channel="C2147483705",
text="!version")
yield from self.ping.process_message(msg)
expected = [call('C2147483705')]
self.ping.send_version_message.assert_has_calls(expected)

def test_process_pong_message(self):
msg = SlackPong(type="pong",
reply_to="bob",
time="12:00am")
yield from self.ping.process_message(msg)
self.assertEqual(self.ping.send_version_message.mock_calls, [])
6 changes: 3 additions & 3 deletions tests/test_robot_help_messages.py
Expand Up @@ -17,19 +17,19 @@ def setUp(self):
def test_empty_plugin_list(self):
self.robot.plugin_list = []
self.robot.initialize_static_plugins()
self.assertEqual(len(self.robot.plugin_list), 1)
self.assertEqual(len(self.robot.plugin_list), 2)

@asynctest.ignore_loop
def test_plugin_list_one_entry(self):
plugin1 = MagicMock()
self.robot.plugin_list = [plugin1]
self.robot.initialize_static_plugins()
self.assertEqual(len(self.robot.plugin_list), 2)
self.assertEqual(len(self.robot.plugin_list), 3)

@asynctest.ignore_loop
def test_plugin_list_two_entries(self):
plugin1 = MagicMock()
plugin2 = MagicMock()
self.robot.plugin_list = [plugin1, plugin2]
self.robot.initialize_static_plugins()
self.assertEqual(len(self.robot.plugin_list), 3)
self.assertEqual(len(self.robot.plugin_list), 4)

0 comments on commit ca8bf36

Please sign in to comment.