Skip to content
This repository was archived by the owner on Aug 15, 2022. It is now read-only.

Commit 45e9f77

Browse files
committed
refactored main into start_rtmbot.py, refactored so that RtmBot class is more self sufficient and can be imported and used more easily, removed unused objects from main
1 parent c6a8b30 commit 45e9f77

File tree

3 files changed

+84
-65
lines changed

3 files changed

+84
-65
lines changed

rtmbot/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from core import *
2+
3+
site_config = {}

rtmbot.py renamed to rtmbot/core.py

Lines changed: 60 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,42 @@
1414

1515
from slackclient import SlackClient
1616

17-
def dbg(debug_string):
18-
if debug:
19-
logging.info(debug_string)
20-
2117
class RtmBot(object):
22-
def __init__(self, token):
18+
def __init__(self, config):
19+
#set the config object
20+
self.config = config
21+
global site_config
22+
site_config = self.config
23+
#set slack token
24+
self.token = config.get('SLACK_TOKEN')
25+
#set working directory for loading plugins or other files
26+
working_directory = os.path.dirname(sys.argv[0])
27+
self.directory = self.config.get('BASE_PATH', working_directory)
28+
if not self.directory.startswith('/'):
29+
path = '{}/{}'.format(os.getcwd(), self.directory)
30+
self.directory = os.path.abspath(path)
31+
#establish logging
32+
log_file = config.get('LOGFILE', 'rtmbot.log')
33+
logging.basicConfig(filename=log_file,
34+
level=logging.INFO,
35+
format='%(asctime)s %(message)s')
36+
logging.info(self.directory)
37+
self.debug = self.config.has_key('DEBUG')
38+
#initialize stateful fields
2339
self.last_ping = 0
24-
self.token = token
2540
self.bot_plugins = []
2641
self.slack_client = None
42+
43+
def _dbg(self, debug_string):
44+
if self.debug:
45+
logging.info(debug_string)
46+
2747
def connect(self):
2848
"""Convenience method that creates Server instance"""
2949
self.slack_client = SlackClient(self.token)
3050
self.slack_client.rtm_connect()
31-
def start(self):
51+
52+
def _start(self):
3253
self.connect()
3354
self.load_plugins()
3455
while True:
@@ -38,19 +59,30 @@ def start(self):
3859
self.output()
3960
self.autoping()
4061
time.sleep(.1)
62+
63+
def start(self):
64+
if self.config.has_key('DAEMON'):
65+
if self.config.get('DAEMON'):
66+
import daemon
67+
with daemon.DaemonContext():
68+
self._start()
69+
self._start()
70+
4171
def autoping(self):
4272
#hardcode the interval to 3 seconds
4373
now = int(time.time())
4474
if now > self.last_ping + 3:
4575
self.slack_client.server.ping()
4676
self.last_ping = now
77+
4778
def input(self, data):
4879
if "type" in data:
4980
function_name = "process_" + data["type"]
50-
dbg("got {}".format(function_name))
81+
self._dbg("got {}".format(function_name))
5182
for plugin in self.bot_plugins:
5283
plugin.register_jobs()
5384
plugin.do(function_name, data)
85+
5486
def output(self):
5587
for plugin in self.bot_plugins:
5688
limiter = False
@@ -63,18 +95,23 @@ def output(self):
6395
message = output[1].encode('ascii','ignore')
6496
channel.send_message("{}".format(message))
6597
limiter = True
98+
6699
def crons(self):
67100
for plugin in self.bot_plugins:
68101
plugin.do_jobs()
102+
69103
def load_plugins(self):
70-
for plugin in glob.glob(directory+'/plugins/*'):
104+
for plugin in glob.glob(self.directory+'/plugins/*'):
71105
sys.path.insert(0, plugin)
72-
sys.path.insert(0, directory+'/plugins/')
73-
for plugin in glob.glob(directory+'/plugins/*.py') + glob.glob(directory+'/plugins/*/*.py'):
106+
sys.path.insert(0, self.directory+'/plugins/')
107+
for plugin in glob.glob(self.directory+'/plugins/*.py') + glob.glob(self.directory+'/plugins/*/*.py'):
74108
logging.info(plugin)
75109
name = plugin.split('/')[-1][:-3]
76110
# try:
77-
self.bot_plugins.append(Plugin(name))
111+
if name in self.config:
112+
logging.info("config found for: " + name)
113+
plugin_config = self.config.get(name)
114+
self.bot_plugins.append(Plugin(name, plugin_config))
78115
# except:
79116
# print "error loading plugin %s" % name
80117

@@ -83,13 +120,12 @@ def __init__(self, name, plugin_config={}):
83120
self.name = name
84121
self.jobs = []
85122
self.module = __import__(name)
123+
self.module.config = plugin_config
86124
self.register_jobs()
87125
self.outputs = []
88-
if name in config:
89-
logging.info("config found for: " + name)
90-
self.module.config = config[name]
91126
if 'setup' in dir(self.module):
92127
self.module.setup()
128+
93129
def register_jobs(self):
94130
if 'crontable' in dir(self.module):
95131
for interval, function in self.module.crontable:
@@ -98,24 +134,27 @@ def register_jobs(self):
98134
self.module.crontable = []
99135
else:
100136
self.module.crontable = []
137+
101138
def do(self, function_name, data):
102139
if function_name in dir(self.module):
103140
#this makes the plugin fail with stack trace in debug mode
104141
if not debug:
105142
try:
106143
eval("self.module."+function_name)(data)
107144
except:
108-
dbg("problem in module {} {}".format(function_name, data))
145+
self._dbg("problem in module {} {}".format(function_name, data))
109146
else:
110147
eval("self.module."+function_name)(data)
111148
if "catch_all" in dir(self.module):
112149
try:
113150
self.module.catch_all(data)
114151
except:
115-
dbg("problem in catch all")
152+
self._dbg("problem in catch all")
153+
116154
def do_jobs(self):
117155
for job in self.jobs:
118156
job.check()
157+
119158
def do_output(self):
120159
output = []
121160
while True:
@@ -134,68 +173,24 @@ def __init__(self, interval, function):
134173
self.function = function
135174
self.interval = interval
136175
self.lastrun = 0
176+
137177
def __str__(self):
138178
return "{} {} {}".format(self.function, self.interval, self.lastrun)
179+
139180
def __repr__(self):
140181
return self.__str__()
182+
141183
def check(self):
142184
if self.lastrun + self.interval < time.time():
143185
if not debug:
144186
try:
145187
self.function()
146188
except:
147-
dbg("problem")
189+
self._dbg("problem")
148190
else:
149191
self.function()
150192
self.lastrun = time.time()
151193
pass
152194

153195
class UnknownChannel(Exception):
154196
pass
155-
156-
157-
def main_loop():
158-
if "LOGFILE" in config:
159-
logging.basicConfig(filename=config["LOGFILE"], level=logging.INFO, format='%(asctime)s %(message)s')
160-
logging.info(directory)
161-
try:
162-
bot.start()
163-
except KeyboardInterrupt:
164-
sys.exit(0)
165-
except:
166-
logging.exception('OOPS')
167-
168-
169-
def parse_args():
170-
parser = ArgumentParser()
171-
parser.add_argument(
172-
'-c',
173-
'--config',
174-
help='Full path to config file.',
175-
metavar='path'
176-
)
177-
return parser.parse_args()
178-
179-
180-
if __name__ == "__main__":
181-
args = parse_args()
182-
directory = os.path.dirname(sys.argv[0])
183-
if not directory.startswith('/'):
184-
directory = os.path.abspath("{}/{}".format(os.getcwd(),
185-
directory
186-
))
187-
188-
config = yaml.load(file(args.config or 'rtmbot.conf', 'r'))
189-
debug = config["DEBUG"]
190-
bot = RtmBot(config["SLACK_TOKEN"])
191-
site_plugins = []
192-
files_currently_downloading = []
193-
job_hash = {}
194-
195-
if config.has_key("DAEMON"):
196-
if config["DAEMON"]:
197-
import daemon
198-
with daemon.DaemonContext():
199-
main_loop()
200-
main_loop()
201-

start_rtmbot.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/usr/bin/env python
2+
from argparse import ArgumentParser
3+
4+
import yaml
5+
from rtmbot import RtmBot
6+
7+
def parse_args():
8+
parser = ArgumentParser()
9+
parser.add_argument(
10+
'-c',
11+
'--config',
12+
help='Full path to config file.',
13+
metavar='path'
14+
)
15+
return parser.parse_args()
16+
17+
# load args with config path
18+
args = parse_args()
19+
config = yaml.load(file(args.config or 'rtmbot.conf', 'r'))
20+
bot = RtmBot(config)
21+
bot.start()

0 commit comments

Comments
 (0)