taubot.py
1 import argparse 2 import signal 3 import irc 4 import json 5 import sys 6 7 # parse arguments 8 parser = argparse.ArgumentParser(description='IRC bot to send a pipe to an IRC channel') 9 parser.add_argument('--server',default='127.0.0.1', help='IRC server') 10 parser.add_argument('--port', default=22024, help='port of the IRC server') 11 parser.add_argument('--nickname', default='tau-notifier', help='bot nickname in IRC') 12 parser.add_argument('--channel', default="#dev", action='append', help='channel to join') 13 parser.add_argument('--pipe', default="/tmp/tau_pipe" , help='pipe to read from') 14 parser.add_argument('--skip', default="prv", help='Project or Tags to skip notifications for') 15 parser.add_argument('--skip-workspace', default="prv-ws", help='Workspace to skip notifications for') 16 parser.add_argument('--alt-chan', default="#test", required='--skip' in sys.argv or '--skip-workspace' in sys.argv, help='Alternative channel to send notifications to when there are skipped tasks') 17 18 args = parser.parse_args() 19 20 channels = [args.channel, args.alt_chan] if args.alt_chan is not None else args.channel 21 22 ircc = irc.IRC() 23 ircc.connect(args.server, int(args.port), channels, args.nickname) 24 25 def signal_handler(sig, frame): 26 print("Caught termination signal, cleaning up and exiting...") 27 ircc.disconnect(args.server, args.port) 28 print("Shut down successfully") 29 exit(0) 30 31 signal.signal(signal.SIGINT, signal_handler) 32 33 while True: 34 with open(args.pipe) as handle: 35 while True: 36 log_line = handle.readline() 37 if not log_line: 38 break 39 print(log_line) 40 print("======================================") 41 task = json.loads(log_line) 42 channel = args.channel 43 44 for event in task['events']: 45 cmd = event['action'] 46 if cmd == "add_task": 47 user = task['owner'] 48 refid = task['ref_id'][:6] 49 title = task['title'] 50 assigned = ", ".join(task['assign']) 51 52 project = task['project'] if task['project'] is not None else [] 53 if args.skip in project or '+' + args.skip in task['tags'] or args.skip_workspace in task['workspace']: 54 channel = args.alt_chan 55 56 if len(assigned) > 0: 57 notification = f"{user} added task ({refid}): {title}. assigned to {assigned}" 58 else: 59 notification = f"{user} added task ({refid}): {title}" 60 # print(notification) 61 ircc.send(channel, notification) 62 elif cmd == "state": 63 user = event['author'] 64 state = event['content'] 65 refid = task['ref_id'][:6] 66 title = task['title'] 67 68 project = task['project'] if task['project'] is not None else [] 69 if args.skip in project or '+' + args.skip in task['tags'] or args.skip_workspace in task['workspace']: 70 channel = args.alt_chan 71 72 if state == "start": 73 notification = f"{user} started task ({refid}): {title}" 74 elif state == "pause": 75 notification = f"{user} paused task ({refid}): {title}" 76 elif state == "stop": 77 notification = f"{user} stopped task ({refid}): {title}" 78 elif state == "cancel": 79 notification = f"{user} canceled task ({refid}): {title}" 80 # print(notification) 81 ircc.send(channel, notification) 82 elif cmd == "comment": 83 user = event['author'] 84 refid = task['ref_id'][:6] 85 title = task['title'] 86 87 project = task['project'] if task['project'] is not None else [] 88 if args.skip in project or '+' + args.skip in task['tags'] or args.skip_workspace in task['workspace']: 89 channel = args.alt_chan 90 91 notification = f"{user} commented on task ({refid}): {title}" 92 # print(notification) 93 ircc.send(channel, notification) 94 elif cmd == "assign": 95 user = event['author'] 96 assignees = event['content'] 97 refid = task['ref_id'][:6] 98 title = task['title'] 99 100 project = task['project'] if task['project'] is not None else [] 101 if args.skip in project or '+' + args.skip in task['tags'] or args.skip_workspace in task['workspace']: 102 channel = args.alt_chan 103 104 removed = [] 105 added = [] 106 for assignee in assignees.split(', '): 107 if assignee.startswith("-"): 108 removed.append(assignee[1:]) 109 else: 110 added.append(assignee) 111 112 if removed and added: 113 notification = f"{user} added {', '.join(added)} and removed {', '.join(removed)} from assign in task ({refid}): {title}" 114 if (not removed) and added: 115 notification = f"{user} added {', '.join(added)} to assign in task ({refid}): {title}" 116 if (not added) and removed: 117 notification = f"{user} removed {', '.join(removed)} from assign in task ({refid}): {title}" 118 119 # print(notification) 120 ircc.send(channel, notification)