Skip to content

Instantly share code, notes, and snippets.

@JustDevZero
Created December 5, 2018 17:59
Show Gist options
  • Save JustDevZero/3f7e5f833d25b5991c317df14c2fb3e4 to your computer and use it in GitHub Desktop.
Save JustDevZero/3f7e5f833d25b5991c317df14c2fb3e4 to your computer and use it in GitHub Desktop.
Script to monitorize redmine and send stuff to slack
#!/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