diff --git a/utils/feed-bot.py b/utils/feed-bot.py index b8a59ea..64c5452 100755 --- a/utils/feed-bot.py +++ b/utils/feed-bot.py @@ -1,114 +1,116 @@ #!/usr/bin/env python3 import json, os, ssl from http.server import BaseHTTPRequestHandler, HTTPServer from phabricator import Phabricator from configparser import ConfigParser from hypchat import HypChat import logging ''' Dependencies: pip3 install phabricator hypchat configparser + +TODO: Support Webhook HMAC Key ''' HOST = '0.0.0.0' PORT = 9000 TXT = 'Nothing to see here' PROJECT_USERS = ['scitas-all'] CHATROOM = 'Activity' CERTFILE = '/etc/letsencrypt/live/myserver/combined.pem' def get_users(): proj = phab.project.query(names=PROJECT_USERS) members = [] for p in proj['data']: members.extend(proj['data'][p]['members']) logging.info('Loaded {} members of {}'.format(len(members), PROJECT_USERS)) return members def connect_chat(): config = ConfigParser() config.read([os.path.expanduser('~/.hypchat')]) token = config.get('HipChat', 'token') uri = config.get('HipChat', 'uri') hc = HypChat(token, endpoint=uri) logging.info('Connected to {}'.format(uri)) return hc def send_message(msg, uri): msg = '{txt} {uri}'.format(txt=msg, uri=uri) room = chat.get_room(CHATROOM) room.notification(msg, color='gray', format='text') return msg class MyHandler(BaseHTTPRequestHandler): def do_GET(self): # HTTP Response self.send_response(500) self.send_header('Content-type', 'text/html') self.end_headers() self.wfile.write(bytes(TXT, 'UTF-8')) def do_POST(self): # Only react to request with JSON data if 'Content-Length' in self.headers and 'Content-Type' in self.headers: if self.headers['Content-Type'] == 'application/json': # Read request data content_len = int(self.headers['Content-Length']) content_data = self.rfile.read(content_len) obj = json.loads(content_data.decode('utf-8')) if not obj['action']['secure'] and not obj['action']['silent']: # Get last Feed stories for modified object tlen = len(obj['transactions']) if len(obj['transactions']) > 1 else 1 stories = phab.feed.query(filterPHIDs=[obj['object']['phid']], view="text", limit=tlen) for s in stories: if stories[s]['authorPHID'] in members: # Get object URI phid = stories[s]['objectPHID'] o = phab.phid.query(phids=[phid]) msg = send_message(stories[s]['text'], o[phid]['uri']) logging.info('Posting: {}'.format(msg)) else: logging.info('Author not a member of project {}'.format(members)) else: logging.info('Silenced or Secured object, doing nothing') else: logging.info('Invalid Content Type {}'.format(self.headers['Content-Type'])) else: logging.info('Request without content') # HTTP Response self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() self.wfile.write(bytes(TXT, 'UTF-8')) if __name__ == '__main__': logging.basicConfig(level=logging.INFO) # Initialize APIs phab = Phabricator() members = get_users() chat = connect_chat() # Start web server httpd = HTTPServer((HOST, PORT), MyHandler) httpd.socket = ssl.wrap_socket(httpd.socket, server_side=True, certfile=CERTFILE, ssl_version=ssl.PROTOCOL_TLSv1_2) try: httpd.serve_forever() except KeyboardInterrupt: pass httpd.server_close()