/ bin / darkirc / script / bots / taubot.py
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)