-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
136 lines (114 loc) · 3.92 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
"""Main function for slackbot."""
import logging
import sys
import os
import pickle
import threading
import time
import asyncio
from slack_sdk.rtm import RTMClient
from commands import discover_commands
from config import obtain_config
from message import Message
score = {}
banned = {}
logging.basicConfig(level=logging.INFO,
format='%(asctime)s %(name)-12s %(levelname)-8s' +
' %(message)s',
datefmt='%m-%d %H:%M',
filename='data/slackbot.log')
_mypath = os.path.abspath(__file__)
config = obtain_config(logging)
kwargs = {}
def set_args():
"""Set the default config/settings."""
kwargs = dict(myworkdir=os.path.dirname(_mypath),
commands=discover_commands(logging),
slack_token=config.get('TOKEN'),
botid=config.get('BOTID'),
botuserid=config.get('BOTUSERID'),
botname=config.get('BOTNAME'),
admins=config.get('ADMINS'),
score=score,
banned=banned)
return kwargs
@RTMClient.run_on(event="message")
async def catch_message(**payload):
"""Slack provided example to retrieve a message from slack."""
data, web_client = payload.get('data'), payload.get('web_client')
logging.debug(data)
message = Message(data, **kwargs)
logging.debug(message)
if message.msg == '':
logging.debug("Empty message: skip processing, nothing to return")
return
send_message(message, web_client)
return
def send_message(message, web_client):
"""Return the processed message using the web client."""
web_client.chat_postMessage(
username=config.get('BOTNAME'),
user=config.get('BOTUSERID'),
icon_emoji=":{0}:".format(config.get('BOTNAME')),
channel=message.channel,
text=message.msg)
return
async def save_to_disk(fname, data):
"""Worker to save data to disk."""
logging.info("Starting {0} worker".format(fname))
while True:
await asyncio.sleep(30)
mwd = kwargs.get('myworkdir')
myfile = open('{0}/data/{1}'.format(mwd, fname), 'wb')
pickle.dump(data, myfile)
myfile.close()
return
async def check_for_runners(loop):
"""Check if worker dies. If so, kill the process."""
while True:
await asyncio.sleep(10)
if len(asyncio.Task.all_tasks(loop)) < 5:
logging.error("A worker died. So should I. :(")
tasks = []
loop.stop()
else:
logging.debug("{0} Runners in loop.".format(
len(asyncio.Task.all_tasks(loop))))
return
def pull_from_disk(fname):
"""Retrive saved content off disk."""
try:
logging.info("Loading {0} from disk".format(fname))
mwd = kwargs.get('myworkdir')
myfile = open('{0}/data/{1}'.format(mwd, fname), 'rb')
data = pickle.load(myfile)
kwargs[fname] = data
myfile.close()
except Exception as error:
text = "Failed to load filename: {0} --- {1}"
logging.debug(text.format(fname, error))
data = {}
return data
async def run_client(loop, **kwargs):
"""Run slack RTM server."""
logging.info("starting client")
slack_token = config.get('TOKEN')
rtm_client = RTMClient(token=slack_token, loop=loop, run_async=True)
rtm_client.start()
logging.info("started client server")
return
def main():
"""Execute setup and start the application."""
loop = asyncio.get_event_loop()
score = pull_from_disk('score')
banned = pull_from_disk('banned')
asyncio.ensure_future(run_client(loop, **kwargs))
asyncio.ensure_future(save_to_disk('score', score))
asyncio.ensure_future(save_to_disk('banned', banned))
asyncio.ensure_future(check_for_runners(loop))
logging.info("running loop forever")
loop.run_forever()
return
if __name__ == '__main__':
kwargs = set_args()
main()