/plugin/gitwatcher.py

https://bitbucket.org/mcreenan/crappy-irc-bot · Python · 138 lines · 95 code · 30 blank · 13 comment · 11 complexity · 4f9950dd987a66639867fb7453cbeb46 MD5 · raw file

  1. from __future__ import unicode_literals
  2. import threading
  3. import json
  4. from six.moves.BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
  5. from six.moves.socketserver import ThreadingMixIn
  6. from six.moves.urllib.parse import unquote_plus
  7. # Git push announcer plugin
  8. # Code lifted from sloat's webadmin plugin :)
  9. irc = None
  10. plugin = None
  11. auth_key = "secure"
  12. announce_channel = "#liek"
  13. httpd = None
  14. def init(p, bot):
  15. global irc, plugin, auth_key, announce_channel
  16. irc = bot
  17. plugin = p
  18. wa = GitWatcherThread(irc=bot)
  19. wa.start()
  20. try:
  21. auth_key = irc.cfg.get('gitwatcher', 'auth_key')
  22. except:
  23. pass
  24. try:
  25. announce_channel = irc.cfg.get('gitwatcher', 'channel')
  26. except:
  27. pass
  28. def unload():
  29. global httpd
  30. if httpd:
  31. httpd.shutdown()
  32. class GitWatcherThread(threading.Thread):
  33. def __init__(self, group=None, target=None, name=None, *args, **kwargs):
  34. threading.Thread.__init__(self, group, target, name, args, kwargs)
  35. self.irc = kwargs['irc']
  36. self.daemon = True
  37. def run(self):
  38. global httpd
  39. addr_info = ('', 8042)
  40. httpd = GitWatcherWebServer(addr_info, GitWatcherHandler)
  41. #while True:
  42. #if not self.irc.connected:
  43. # break
  44. #httpd.handle_request()
  45. httpd.serve_forever()
  46. class GitWatcherWebServer(ThreadingMixIn, HTTPServer):
  47. pass
  48. class GitWatcherHandler(BaseHTTPRequestHandler):
  49. def __init__(self, request, client_address, server):
  50. BaseHTTPRequestHandler.__init__(self, request, client_address,
  51. server)
  52. def do_GET(self):
  53. self.send_response(200)
  54. self.send_header("Content-type", "text/plain")
  55. self.end_headers()
  56. self.wfile.write("Rabbit season!\r\n\r\n".encode('utf-8'))
  57. def do_POST(self):
  58. global irc, auth_key, announce_channel
  59. self.cmd = self.path
  60. try:
  61. data_len = int(self.headers['Content-Length'])
  62. except:
  63. data_len = int(self.headers.getheader('Content-Length'))
  64. self.post_data = self.rfile.read(data_len).decode('utf-8')
  65. self.post_data = unquote_plus(self.post_data)
  66. if self.post_data.startswith('payload='):
  67. self.post_data = self.post_data[8:]
  68. self.send_response(200)
  69. self.send_header("Content-type", "text/plain")
  70. self.end_headers()
  71. # BitBucket can't send a basic auth header apparently, wow.
  72. #if self.headers.getheader("Authorization") != auth_key:
  73. # self.wfile.write("go away\r\n\r\n")
  74. # h = str(self.headers).split("\n")
  75. # for i in h:
  76. # irc.privmsg("#liek", i)
  77. # return
  78. if self.cmd != ("/" + auth_key):
  79. self.wfile.write("What's up doc?\r\n\r\n".encode('utf-8'))
  80. return
  81. try:
  82. data = json.loads(self.post_data)
  83. except:
  84. return
  85. try:
  86. if 'issue_id' in data:
  87. irc.privmsg(announce_channel,
  88. "\002CIB Issue\002 #%s created: %s" %
  89. (data['issue_id'], data['issue_title']))
  90. irc.privmsg(announce_channel, data['issue_url'])
  91. self.wfile.write("Beep Beep\r\n".encode('utf-8'))
  92. return
  93. irc.privmsg(announce_channel,
  94. "\002Git Push\002 \037%s\037 (%s) %d changeset(s)" %
  95. (data['repository']['name'], data['user'],
  96. len(data['commits'])))
  97. for c in data['commits']:
  98. irc.privmsg(announce_channel,
  99. "\002Branch\002: %s \002Commit\002: %s" %
  100. (c['branch'], c['node']))
  101. msg = c['message'].split("\n")
  102. for line in msg:
  103. irc.privmsg(announce_channel, line)
  104. except:
  105. pass
  106. json.dump(data, open('gitwatch.json', 'w+'), sort_keys=True,
  107. indent=4, separators=(',', ': '))
  108. self.wfile.write("Duck season!\r\n\r\n".encode('utf-8'))