Created
December 5, 2018 17:59
-
-
Save JustDevZero/3f7e5f833d25b5991c317df14c2fb3e4 to your computer and use it in GitHub Desktop.
Script to monitorize redmine and send stuff to slack
This file contains 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
#!/home/dripoll/.env/redminer/bin/python | |
# coding: utf8 | |
from os import environ, path | |
from requests import get, post | |
from hashlib import md5 | |
from requests.auth import HTTPBasicAuth | |
from json import loads | |
from sys import stderr | |
from itertools import chain | |
PRIORITIES = { | |
'BLOCKER': 27, | |
'HIGH': 5, | |
'LOW': 1, | |
'NORMAL': 2 | |
} | |
def eprint(*args, **kwargs): | |
print(*args, file=stderr, **kwargs) | |
class Redminer(object): | |
url = None | |
base_url = None | |
username = None | |
password = None | |
priorities = [1, 2, 5, 27] | |
redminer_controller_file = '%s/.redminer.list.json' % environ['HOME'] | |
slack_url = None | |
def __init__(self): | |
self.load_config() | |
def load_config(self): | |
credentials_file = '%s/.redmine.json' % environ['HOME'] | |
if not path.isfile(credentials_file): | |
raise Exception('Credentials are not found.') | |
json_data = open(credentials_file, 'r').read() | |
try: | |
redmine_data = loads(json_data) | |
except Exception: | |
raise Exception('Config is not a valid JSON file.') | |
if not {'user_id', 'username', 'password', | |
'url', 'slack_url'}.issubset(redmine_data): | |
raise Exception('Config is corrupted.') | |
self.username = redmine_data['username'] | |
self.password = redmine_data['password'] | |
self.base_url = redmine_data['url'] | |
limit = redmine_data.get('limit') or 40 | |
self.url = '%s/issues.json?limit=%s&assigned_to_id=%s' % (redmine_data['url'], | |
limit, | |
redmine_data['user_id']) | |
self.priorities = {x: y for x, y in PRIORITIES.items( | |
) if y in redmine_data.get('priorities', [])} or PRIORITIES | |
def get_issues(self, priority): | |
url = '%s&priority_id=%s' % (self.url, priority) | |
json_data = get(url, auth=HTTPBasicAuth(self.username, self.password)) | |
if json_data.status_code != 200: | |
eprint('server dont return 200') | |
#raise Exception('JSON Api is not available, or password/username are wrong.') | |
return [] | |
try: | |
data_issues = json_data.json() | |
except Exception: | |
eprint('json data corrupted') | |
#raise Exception('Somehow issues are not now a JSON.') | |
return [] | |
if data_issues.get('total_count') < 1: | |
print('No issues for this priority') | |
# XXX: Should we log that nothing is found? | |
#raise Exception('No issues.') | |
return [] | |
return data_issues.get('issues') or {} | |
def prepare_alert(self, priority_name, issue): | |
priority_name = priority_name | |
subject = issue.get('subject') or 'UNKNOWN' | |
if len(subject) > 117: | |
subject = subject[:114] + "..." | |
category = issue.get('category') or {} | |
category = category.get('name') or 'UNKNOWN' | |
issue_id = issue.get('id') | |
base_url = self.base_url | |
redmine_url = f'{base_url}/issues/{issue_id}' | |
alert_msg = f'Priority: {priority_name}, Subject: {subject}' | |
alert_msg += f'\nCategory: {category}' | |
alert_msg += f'\nURL: {redmine_url}' | |
return alert_msg + "\n---" | |
def send_slack_alert(self, message): | |
slack_url = self.slack_url | |
post(slack_url, json={'text': message}) | |
def get_old_hashes(self): | |
if not path.isfile(self.redminer_controller_file): | |
return [] | |
redminer_data = open(self.redminer_controller_file).read() | |
return redminer_data.split('\n') | |
def save_hashes(self, hashes): | |
with open(self.redminer_controller_file, 'w') as hashed_file: | |
hashed_file.write("\n".join(hashes)) | |
hashed_file.close() | |
def prepare_batch(self, priority_name, priority_number): | |
issues = self.get_issues(priority_number) | |
issue_list = [] | |
issue_list.extend( | |
self.prepare_alert(priority_name, issue) | |
for issue in issues | |
if issue.get('status', {}).get('id') not in [11] | |
) | |
message_diggested = "\n".join(issue_list) | |
if not message_diggested: | |
return None | |
return {md5(message_diggested.encode('utf-8')).hexdigest(): | |
message_diggested} | |
def process(self): | |
monit_file = '%s/.monitorize' % environ['HOME'] | |
if not path.isfile(monit_file): | |
return | |
hashes = {} | |
notify = False | |
hashes = {} | |
for priority_name, priority_number in self.priorities.items(): | |
batch = self.prepare_batch(priority_name, priority_number) | |
if batch: | |
hashes.update(batch) | |
stored_hashes = self.get_old_hashes() | |
if not hashes: | |
self.send_slack_alert('Hurray! No issues open on for you') | |
self.save_hashes([]) | |
return | |
if len(hashes) > len(stored_hashes): | |
self.send_slack_alert('Oops! Guess you are fucked up, more issues') | |
notify = True | |
if len(hashes) < len(stored_hashes): | |
self.send_slack_alert('Hurray! You managed to level down the' | |
'issues, but beware, there are more.') | |
notify = True | |
if set(hashes.keys()) == set(stored_hashes): | |
self.send_slack_alert("Now news, good... news? Not really.") | |
notify = False | |
self.save_hashes(hashes) | |
if not notify: | |
return | |
for x, y in hashes.items(): | |
self.send_slack_alert(y) | |
redminer = Redminer() | |
try: | |
redminer.process() | |
except Exception as err: | |
eprint(err) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment