Merge pull request #36 from jammons/master
Make bot code and plugin examples PEP8 compliant
This commit is contained in:
commit
134710718b
6 changed files with 69 additions and 38 deletions
|
|
@ -1,8 +1,9 @@
|
||||||
import time
|
import time
|
||||||
outputs = []
|
outputs = []
|
||||||
|
|
||||||
|
|
||||||
def canary():
|
def canary():
|
||||||
#NOTE: you must add a real channel ID for this to work
|
# NOTE: you must add a real channel ID for this to work
|
||||||
outputs.append(["D12345678", "bot started: " + str(time.time())])
|
outputs.append(["D12345678", "bot started: " + str(time.time())])
|
||||||
|
|
||||||
canary()
|
canary()
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,9 @@ import time
|
||||||
crontable = []
|
crontable = []
|
||||||
outputs = []
|
outputs = []
|
||||||
|
|
||||||
crontable.append([5,"say_time"])
|
crontable.append([5, "say_time"])
|
||||||
|
|
||||||
|
|
||||||
def say_time():
|
def say_time():
|
||||||
#NOTE: you must add a real channel ID for this to work
|
# NOTE: you must add a real channel ID for this to work
|
||||||
outputs.append(["D12345678", time.time()])
|
outputs.append(["D12345678", time.time()])
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
import time
|
|
||||||
crontable = []
|
crontable = []
|
||||||
outputs = []
|
outputs = []
|
||||||
|
|
||||||
|
|
||||||
def process_message(data):
|
def process_message(data):
|
||||||
if data['channel'].startswith("D"):
|
if data['channel'].startswith("D"):
|
||||||
outputs.append([data['channel'], "from repeat1 \"{}\" in channel {}".format(data['text'], data['channel']) ])
|
outputs.append([data['channel'], "from repeat1 \"{}\" in channel {}".format(
|
||||||
|
data['text'], data['channel'])]
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import print_function
|
||||||
import os
|
import os
|
||||||
import pickle
|
import pickle
|
||||||
|
|
||||||
|
|
@ -6,19 +7,21 @@ crontabs = []
|
||||||
|
|
||||||
tasks = {}
|
tasks = {}
|
||||||
|
|
||||||
FILE="plugins/todo.data"
|
|
||||||
|
FILE = "plugins/todo.data"
|
||||||
if os.path.isfile(FILE):
|
if os.path.isfile(FILE):
|
||||||
tasks = pickle.load(open(FILE, 'rb'))
|
tasks = pickle.load(open(FILE, 'rb'))
|
||||||
|
|
||||||
|
|
||||||
def process_message(data):
|
def process_message(data):
|
||||||
global tasks
|
global tasks
|
||||||
channel = data["channel"]
|
channel = data["channel"]
|
||||||
text = data["text"]
|
text = data["text"]
|
||||||
#only accept tasks on DM channels
|
# only accept tasks on DM channels
|
||||||
if channel.startswith("D"):
|
if channel.startswith("D"):
|
||||||
if channel not in tasks.keys():
|
if channel not in tasks.keys():
|
||||||
tasks[channel] = []
|
tasks[channel] = []
|
||||||
#do command stuff
|
# do command stuff
|
||||||
if text.startswith("todo"):
|
if text.startswith("todo"):
|
||||||
tasks[channel].append(text[5:])
|
tasks[channel].append(text[5:])
|
||||||
outputs.append([channel, "added"])
|
outputs.append([channel, "added"])
|
||||||
|
|
@ -35,5 +38,5 @@ def process_message(data):
|
||||||
num = int(text.split()[1]) - 1
|
num = int(text.split()[1]) - 1
|
||||||
tasks[channel].pop(num)
|
tasks[channel].pop(num)
|
||||||
if text == "show":
|
if text == "show":
|
||||||
print tasks
|
print(tasks)
|
||||||
pickle.dump(tasks, open(FILE,"wb"))
|
pickle.dump(tasks, open(FILE, "wb"))
|
||||||
|
|
|
||||||
77
rtmbot.py
77
rtmbot.py
|
|
@ -1,33 +1,35 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
sys.dont_write_bytecode = True
|
|
||||||
|
|
||||||
import glob
|
import glob
|
||||||
import yaml
|
import yaml
|
||||||
import json
|
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
import time
|
import time
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
|
|
||||||
from slackclient import SlackClient
|
from slackclient import SlackClient
|
||||||
|
|
||||||
|
sys.dont_write_bytecode = True
|
||||||
|
|
||||||
|
|
||||||
def dbg(debug_string):
|
def dbg(debug_string):
|
||||||
if debug:
|
if debug:
|
||||||
logging.info(debug_string)
|
logging.info(debug_string)
|
||||||
|
|
||||||
|
|
||||||
class RtmBot(object):
|
class RtmBot(object):
|
||||||
def __init__(self, token):
|
def __init__(self, token):
|
||||||
self.last_ping = 0
|
self.last_ping = 0
|
||||||
self.token = token
|
self.token = token
|
||||||
self.bot_plugins = []
|
self.bot_plugins = []
|
||||||
self.slack_client = None
|
self.slack_client = None
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
"""Convenience method that creates Server instance"""
|
"""Convenience method that creates Server instance"""
|
||||||
self.slack_client = SlackClient(self.token)
|
self.slack_client = SlackClient(self.token)
|
||||||
self.slack_client.rtm_connect()
|
self.slack_client.rtm_connect()
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.connect()
|
self.connect()
|
||||||
self.load_plugins()
|
self.load_plugins()
|
||||||
|
|
@ -38,12 +40,14 @@ class RtmBot(object):
|
||||||
self.output()
|
self.output()
|
||||||
self.autoping()
|
self.autoping()
|
||||||
time.sleep(.1)
|
time.sleep(.1)
|
||||||
|
|
||||||
def autoping(self):
|
def autoping(self):
|
||||||
#hardcode the interval to 3 seconds
|
# hardcode the interval to 3 seconds
|
||||||
now = int(time.time())
|
now = int(time.time())
|
||||||
if now > self.last_ping + 3:
|
if now > self.last_ping + 3:
|
||||||
self.slack_client.server.ping()
|
self.slack_client.server.ping()
|
||||||
self.last_ping = now
|
self.last_ping = now
|
||||||
|
|
||||||
def input(self, data):
|
def input(self, data):
|
||||||
if "type" in data:
|
if "type" in data:
|
||||||
function_name = "process_" + data["type"]
|
function_name = "process_" + data["type"]
|
||||||
|
|
@ -51,35 +55,43 @@ class RtmBot(object):
|
||||||
for plugin in self.bot_plugins:
|
for plugin in self.bot_plugins:
|
||||||
plugin.register_jobs()
|
plugin.register_jobs()
|
||||||
plugin.do(function_name, data)
|
plugin.do(function_name, data)
|
||||||
|
|
||||||
def output(self):
|
def output(self):
|
||||||
for plugin in self.bot_plugins:
|
for plugin in self.bot_plugins:
|
||||||
limiter = False
|
limiter = False
|
||||||
for output in plugin.do_output():
|
for output in plugin.do_output():
|
||||||
channel = self.slack_client.server.channels.find(output[0])
|
channel = self.slack_client.server.channels.find(output[0])
|
||||||
if channel != None and output[1] != None:
|
if channel is not None and output[1] is not None:
|
||||||
if limiter == True:
|
if limiter:
|
||||||
time.sleep(.1)
|
time.sleep(.1)
|
||||||
limiter = False
|
limiter = False
|
||||||
message = output[1].encode('ascii','ignore')
|
message = output[1].encode('ascii', 'ignore')
|
||||||
channel.send_message("{}".format(message))
|
channel.send_message("{}".format(message))
|
||||||
limiter = True
|
limiter = True
|
||||||
|
|
||||||
def crons(self):
|
def crons(self):
|
||||||
for plugin in self.bot_plugins:
|
for plugin in self.bot_plugins:
|
||||||
plugin.do_jobs()
|
plugin.do_jobs()
|
||||||
|
|
||||||
def load_plugins(self):
|
def load_plugins(self):
|
||||||
for plugin in glob.glob(directory+'/plugins/*'):
|
for plugin in glob.glob(directory + '/plugins/*'):
|
||||||
sys.path.insert(0, plugin)
|
sys.path.insert(0, plugin)
|
||||||
sys.path.insert(0, directory+'/plugins/')
|
sys.path.insert(0, directory + '/plugins/')
|
||||||
for plugin in glob.glob(directory+'/plugins/*.py') + glob.glob(directory+'/plugins/*/*.py'):
|
for plugin in glob.glob(directory + '/plugins/*.py') + \
|
||||||
|
glob.glob(directory + '/plugins/*/*.py'):
|
||||||
logging.info(plugin)
|
logging.info(plugin)
|
||||||
name = plugin.split('/')[-1][:-3]
|
name = plugin.split('/')[-1][:-3]
|
||||||
# try:
|
# try:
|
||||||
self.bot_plugins.append(Plugin(name))
|
self.bot_plugins.append(Plugin(name))
|
||||||
# except:
|
# except:
|
||||||
# print "error loading plugin %s" % name
|
# print "error loading plugin %s" % name
|
||||||
|
|
||||||
|
|
||||||
class Plugin(object):
|
class Plugin(object):
|
||||||
def __init__(self, name, plugin_config={}):
|
|
||||||
|
def __init__(self, name, plugin_config=None):
|
||||||
|
if plugin_config is None:
|
||||||
|
plugin_config = {} # TODO: is this variable necessary?
|
||||||
self.name = name
|
self.name = name
|
||||||
self.jobs = []
|
self.jobs = []
|
||||||
self.module = __import__(name)
|
self.module = __import__(name)
|
||||||
|
|
@ -90,32 +102,36 @@ class Plugin(object):
|
||||||
self.module.config = config[name]
|
self.module.config = config[name]
|
||||||
if 'setup' in dir(self.module):
|
if 'setup' in dir(self.module):
|
||||||
self.module.setup()
|
self.module.setup()
|
||||||
|
|
||||||
def register_jobs(self):
|
def register_jobs(self):
|
||||||
if 'crontable' in dir(self.module):
|
if 'crontable' in dir(self.module):
|
||||||
for interval, function in self.module.crontable:
|
for interval, function in self.module.crontable:
|
||||||
self.jobs.append(Job(interval, eval("self.module."+function)))
|
self.jobs.append(Job(interval, eval("self.module." + function)))
|
||||||
logging.info(self.module.crontable)
|
logging.info(self.module.crontable)
|
||||||
self.module.crontable = []
|
self.module.crontable = []
|
||||||
else:
|
else:
|
||||||
self.module.crontable = []
|
self.module.crontable = []
|
||||||
|
|
||||||
def do(self, function_name, data):
|
def do(self, function_name, data):
|
||||||
if function_name in dir(self.module):
|
if function_name in dir(self.module):
|
||||||
#this makes the plugin fail with stack trace in debug mode
|
# this makes the plugin fail with stack trace in debug mode
|
||||||
if not debug:
|
if not debug:
|
||||||
try:
|
try:
|
||||||
eval("self.module."+function_name)(data)
|
eval("self.module." + function_name)(data)
|
||||||
except:
|
except:
|
||||||
dbg("problem in module {} {}".format(function_name, data))
|
dbg("problem in module {} {}".format(function_name, data))
|
||||||
else:
|
else:
|
||||||
eval("self.module."+function_name)(data)
|
eval("self.module." + function_name)(data)
|
||||||
if "catch_all" in dir(self.module):
|
if "catch_all" in dir(self.module):
|
||||||
try:
|
try:
|
||||||
self.module.catch_all(data)
|
self.module.catch_all(data)
|
||||||
except:
|
except:
|
||||||
dbg("problem in catch all")
|
dbg("problem in catch all")
|
||||||
|
|
||||||
def do_jobs(self):
|
def do_jobs(self):
|
||||||
for job in self.jobs:
|
for job in self.jobs:
|
||||||
job.check()
|
job.check()
|
||||||
|
|
||||||
def do_output(self):
|
def do_output(self):
|
||||||
output = []
|
output = []
|
||||||
while True:
|
while True:
|
||||||
|
|
@ -129,15 +145,19 @@ class Plugin(object):
|
||||||
self.module.outputs = []
|
self.module.outputs = []
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
|
||||||
class Job(object):
|
class Job(object):
|
||||||
def __init__(self, interval, function):
|
def __init__(self, interval, function):
|
||||||
self.function = function
|
self.function = function
|
||||||
self.interval = interval
|
self.interval = interval
|
||||||
self.lastrun = 0
|
self.lastrun = 0
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "{} {} {}".format(self.function, self.interval, self.lastrun)
|
return "{} {} {}".format(self.function, self.interval, self.lastrun)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return self.__str__()
|
return self.__str__()
|
||||||
|
|
||||||
def check(self):
|
def check(self):
|
||||||
if self.lastrun + self.interval < time.time():
|
if self.lastrun + self.interval < time.time():
|
||||||
if not debug:
|
if not debug:
|
||||||
|
|
@ -150,13 +170,18 @@ class Job(object):
|
||||||
self.lastrun = time.time()
|
self.lastrun = time.time()
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class UnknownChannel(Exception):
|
class UnknownChannel(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def main_loop():
|
def main_loop():
|
||||||
if "LOGFILE" in config:
|
if "LOGFILE" in config:
|
||||||
logging.basicConfig(filename=config["LOGFILE"], level=logging.INFO, format='%(asctime)s %(message)s')
|
logging.basicConfig(
|
||||||
|
filename=config["LOGFILE"],
|
||||||
|
level=logging.INFO,
|
||||||
|
format='%(asctime)s %(message)s'
|
||||||
|
)
|
||||||
logging.info(directory)
|
logging.info(directory)
|
||||||
try:
|
try:
|
||||||
bot.start()
|
bot.start()
|
||||||
|
|
@ -182,20 +207,20 @@ if __name__ == "__main__":
|
||||||
directory = os.path.dirname(sys.argv[0])
|
directory = os.path.dirname(sys.argv[0])
|
||||||
if not directory.startswith('/'):
|
if not directory.startswith('/'):
|
||||||
directory = os.path.abspath("{}/{}".format(os.getcwd(),
|
directory = os.path.abspath("{}/{}".format(os.getcwd(),
|
||||||
directory
|
directory
|
||||||
))
|
))
|
||||||
|
|
||||||
config = yaml.load(file(args.config or 'rtmbot.conf', 'r'))
|
config = yaml.load(open(args.config or 'rtmbot.conf', 'r'))
|
||||||
debug = config["DEBUG"]
|
debug = config["DEBUG"]
|
||||||
bot = RtmBot(config["SLACK_TOKEN"])
|
bot = RtmBot(config["SLACK_TOKEN"])
|
||||||
site_plugins = []
|
site_plugins = []
|
||||||
files_currently_downloading = []
|
files_currently_downloading = []
|
||||||
job_hash = {}
|
job_hash = {}
|
||||||
|
|
||||||
if config.has_key("DAEMON"):
|
if 'DAEMON' in config:
|
||||||
if config["DAEMON"]:
|
if config["DAEMON"]:
|
||||||
import daemon
|
import daemon
|
||||||
|
|
||||||
with daemon.DaemonContext():
|
with daemon.DaemonContext():
|
||||||
main_loop()
|
main_loop()
|
||||||
main_loop()
|
main_loop()
|
||||||
|
|
||||||
|
|
|
||||||
2
tox.ini
2
tox.ini
|
|
@ -20,4 +20,4 @@ basepython =
|
||||||
[testenv:flake8]
|
[testenv:flake8]
|
||||||
basepython=python
|
basepython=python
|
||||||
deps=flake8
|
deps=flake8
|
||||||
commands=flake8 {toxinidir}/rtmbot.py {toxinidir}/example-plugins
|
commands=flake8 {toxinidir}/rtmbot.py {toxinidir}/doc/example-plugins
|
||||||
Loading…
Add table
Add a link
Reference in a new issue