Created
October 20, 2016 06:01
-
-
Save epequeno/09da2983f6313e098b4612c4777fe849 to your computer and use it in GitHub Desktop.
slackbot to monitor urls for 200 status code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# stdlib | |
import multiprocessing as mp | |
from time import sleep | |
from subprocess import call | |
from urllib.parse import quote | |
# 3rd party | |
import requests | |
from slackbot.bot import Bot, respond_to | |
import validators | |
# local | |
from slackbot_settings import API_TOKEN | |
# globals | |
JOBS = [] | |
WORKERS = [] | |
JOB_COUNTER = 0 | |
def send(message, room): | |
cmd = 'curl https://slack.com/api/chat.postMessage?token={}&channel={}&text={}&as_user=true&pretty=1' | |
cmd = cmd.format(API_TOKEN, quote(room), quote(message)) | |
call(cmd.split()) | |
@respond_to('mon (.*)') | |
@respond_to('mon (.*) (.*)') | |
def monitor(message, action=None, job_num=None): | |
# job_num can be an int or str, cast to int if needed. | |
if job_num and job_num != 'all': | |
job_num = int(job_num) | |
def worker(j): | |
while True: | |
res = None | |
try: | |
res = requests.get(j['url']) | |
except Exception as e: | |
m = '{}) {} - {}'.format(j['job_num'], j['url'], e) | |
send(m, message.body['channel']) | |
sleep(600) | |
if res is None: | |
continue | |
elif res.status_code != 200: | |
m = '{}) {} - {}'.format(j['job_num'], res.status_code, j['url']) | |
send(m, message.body['channel']) | |
sleep(600) | |
sleep(60) | |
def ls(): | |
global JOBS | |
if len(JOBS) == 0: | |
message.send('no current jobs') | |
return | |
m = '```{}```' | |
body = '' | |
for j in sorted(JOBS, key=lambda x: x['job_num']): | |
if j['active']: | |
line = '{}) {}\n'.format(j['job_num'], j['url']) | |
else: | |
line = '{}) {} (paused)\n'.format(j['job_num'], j['url']) | |
body += line | |
body.rstrip() | |
message.send(m.format(body)) | |
def pause(job): | |
global JOBS | |
global WORKERS | |
if job == 'all': | |
pass | |
elif job not in [x['job_num'] for x in JOBS]: | |
message.send('job {} not found'.format(job)) | |
return | |
m = 'pausing job: {}'.format(job) | |
message.send(m) | |
if job == 'all': | |
for w in WORKERS: | |
w.terminate() | |
for j in JOBS: | |
j['active'] = False | |
else: | |
for j in JOBS: | |
if j['job_num'] == job: | |
j['active'] = False | |
for w in WORKERS: | |
if w.pid == j['worker']: | |
w.terminate() | |
def rm(job): | |
global JOB_COUNTER | |
global JOBS | |
global WORKERS | |
m = 'removing job: {}'.format(job) | |
message.send(m) | |
if job == 'all': | |
JOBS = [] | |
JOB_COUNTER = 0 | |
for w in WORKERS: | |
w.terminate() | |
WORKERS = [] | |
return | |
elif not isinstance(job, int): | |
message.send("I didn't understand that") | |
return | |
JOB_COUNTER -= 1 | |
for j in JOBS: | |
if j['job_num'] == job: | |
for w in WORKERS: | |
if w.pid == j['worker']: | |
w.terminate() | |
JOBS = [x for x in JOBS if x['job_num'] != job] | |
def resume(job): | |
global JOBS | |
global WORKERS | |
if job == 'all': | |
pass | |
elif job not in [x['job_num'] for x in JOBS]: | |
message.send('job {} not found'.format(job)) | |
return | |
m = 'resuming job: {}'.format(job) | |
message.send(m) | |
if job == 'all': | |
for j in JOBS: | |
if not j['active']: | |
w = mp.Process(target=worker, args=[j]) | |
w.start() | |
WORKERS.append(w) | |
j['active'] = True | |
j['worker'] = w.pid | |
return | |
for j in JOBS: | |
if j['job_num'] == job: | |
w = mp.Process(target=worker, args=[j]) | |
w.start() | |
WORKERS.append(w) | |
j['active'] = True | |
j['worker'] = w.pid | |
def mon_help(): | |
with open('mon_help', 'r') as fd: | |
message.send(fd.read()) | |
actions = {'ls': ls, | |
'pause': pause, | |
'rm': rm, | |
'resume': resume, | |
'help': mon_help} | |
url = action.lstrip('<').rstrip('>') | |
valid_url = validators.url(url) | |
if valid_url: | |
global JOB_COUNTER | |
global WORKERS | |
if JOB_COUNTER == 5: | |
message.send('too many jobs, please remove one.') | |
return | |
JOB_COUNTER += 1 | |
full = set(range(1, 6)) | |
current = set(j['job_num'] for j in JOBS) | |
j = {'job_num': min(full - current) if current != full else JOB_COUNTER, | |
'url': url, | |
'active': True} | |
p = mp.Process(target=worker, args=[j]) | |
p.start() | |
j['worker'] = p.pid | |
JOBS.append(j) | |
WORKERS.append(p) | |
msg = 'added job {}) {}'.format(j['job_num'], j['url']) | |
message.send(msg) | |
elif action in actions: | |
if job_num: | |
try: | |
actions[action](job_num) | |
except TypeError: | |
message.send('`job_num` not needed for {}'.format(action)) | |
actions[action]() | |
else: | |
if len(action.split()) == 2: | |
return | |
try: | |
actions[action]() | |
except TypeError: | |
message.send("missing argument `job_num` to: {}".format(action)) | |
elif not len(url.split()) > 1: | |
msg = 'invalid url: {}'.format(url) | |
message.send(msg) | |
def main(): | |
bot = Bot() | |
bot.run() | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment