def handle_issue_comment(data): """ Handle a issue_comment event. This event is triggered any time a pull request or issue is commented on. """ # We're only interested in pull request comments for now if "pull_request" not in data["issue"]: return # TODO: Might need to do something different for different "action" values # if different action values are ever implemented # TODO message-id # Figure out what email this will be a reply to pull_request = get_github(data["issue"]["pull_request"]["url"]).json() cover_msg_id = pull_request_msg_id(pull_request) subject = "Re: " + pull_request_subject(pull_request) from_addr = "%s <%s>" % (data["comment"]["user"]["login"], os.environ["GHEH_EMAIL_FROM"]) body = data["comment"]["body"] + email_footer(data["issue"]["html_url"]) msg = MIMEText(body) msg['From'] = from_addr msg['Subject'] = subject msg['In-Reply-To'] = cover_msg_id msg['Date'] = json_to_email_date(data["issue"]["updated_at"]) send_email(msg)
def handle_pull_request_review_comment(data): """ Handle a pull request review comment. This event is triggered by comments left on the unified diff (both split and unified views) for a pull request, via the "Files changed" tab. """ # TODO: same as issue comments, might need to do something with "action" if # action ever gets used # TODO Message-Id cover_msg_id = pull_request_msg_id(data["pull_request"]) subject = "Re: " + pull_request_subject(data["pull_request"]) from_addr = "%s <%s>" % (data["comment"]["user"]["login"], os.environ["GHEH_EMAIL_FROM"]) # Start with the diff being commented on as a quote body = '\n'.join('> ' + line for line in data["comment"]["diff_hunk"].split('\n')) body += '\n\n' + data["comment"]["body"] body += '\n' + email_footer(data["comment"]["html_url"]) msg = MIMEText(body) msg['From'] = from_addr msg['Subject'] = subject msg['In-Reply-To'] = cover_msg_id msg['Date'] = json_to_email_date(data["comment"]["updated_at"]) send_email(msg)
def handle_pull_request(data): """ Handle a pull_request event. This event is triggered when a pull request is assigned, unassigned, labeled, unlabeled, opened, closed, reopened, or synchronized. https://developer.github.com/v3/activity/events/types/#pullrequestevent """ # Pull requests form the base of the email threads used in this webook. # Any time a request is opened or synchronized (push --force on the branch # to be pulled), start a new email thread using the pull request body as # the cover letter, and reply to it with each of the patches. pull_request = data["pull_request"] # Construct the message ID for the cover letter that we will either be # sending or replying to cover_msg_id = pull_request_msg_id(data["pull_request"]) subject_base = pull_request_subject(pull_request) if data["action"] in ("opened", "synchronize"): if data["action"] == "opened": subject = "New: " else: subject = "Updated: " subject += subject_base from_addr = "%s <%s>" % (data["sender"]["login"], os.environ["GHEH_EMAIL_FROM"]) body = pull_request["body"] + email_footer(pull_request["html_url"]) cover_letter = MIMEText(body) cover_letter['From'] = from_addr cover_letter['Subject'] = subject cover_letter['Message-Id'] = cover_msg_id cover_letter['Date'] = json_to_email_date(pull_request['updated_at']) send_email(cover_letter) # Get a list of commits in this pull request commit_list = get_github(pull_request["url"] + "/commits").json() patch_num = 1 tot_num = len(commit_list) # Start with the PR date for the patches and add one second to each # as we go so that the patches appear in the right order. # This is the same thing that git-send-email does, both in terms of # throwing away the commit Date and using incrementing seconds to # order the patch emails. patch_date_ts = iso8601.parse_date(pull_request['updated_at']).timestamp() for commit in commit_list: # Start with the .patch file provided by github since it's # formatted all nice and email-like msg = read_message(commit['html_url'] + '.patch') # Set the message as a reply to the cover letter msg['In-Reply-To'] = cover_msg_id msg['Message-Id'] = patch_msg_id(pull_request, commit["sha"]) del msg['Date'] msg['Date'] = email.utils.formatdate(timeval=patch_date_ts) # Prepend a From: to the body of the message so git-am works right. # Add the footer. msg.set_payload('From: %s\n\n%s\n%s' % \ (msg['From'], msg.get_payload(), email_footer(commit['html_url'], msg_type='commit'))) # Replace the From header with ourselves del msg['From'] msg['From'] = from_addr # Reset the Content-Transfer-Encoding so that non-ascii characters # get encoded right. This will encode the payload as base64. del msg['Content-Transfer-Encoding'] msg.set_charset('utf-8') # Monkey with the subject to get the patch numbers and branch name in there subject = msg['Subject'].replace('[PATCH]', '[%s %d/%d]' % (pull_request["base"]["ref"], patch_num, tot_num), 1) del msg['Subject'] msg['Subject'] = subject send_email(msg) patch_date_ts += 1 patch_num += 1 # Create (or update) a database record with the pull request and # the list of commits client = pymongo.MongoClient(os.environ[os.environ["GHEH_DB_ENVVAR"]]) db = client[os.environ['GHEH_DB_NAME']] pull_request_coll = db[PULL_REQUEST_COLLECTION] record = pull_request_coll.find_one({'pull_request.id': pull_request['id']}) if record: record['pull_request'] = pull_request record['commit_list'] = commit_list pull_request_coll.save(record) else: pull_request_coll.insert({'pull_request': pull_request, 'commit_list': commit_list}) elif data["action"] in ("closed", "reopened", "assigned", "unassigned", "labeled", "unlabeled"): subject = "Re: %s" % subject_base # If the action was assigned, say whom it was assigned to in the body if data["action"] == "assigned": body = "Assigned to %s" % data["assignee"]["login"] # For labels, put the label in the body elif data["action"] == "labeled": body = "Added label: %s." % data["label"]["name"] elif data["action"] == "unlabeled": body = "Removed label: %s." % data["label"]["name"] # For everything else just say what happened # uppercase the first letter else: body = "%s." % data["action"].title() from_addr = "%s <%s>" % (data["sender"]["login"], os.environ["GHEH_EMAIL_FROM"]) msg = MIMEText(body + email_footer(pull_request["html_url"])) msg["From"] = from_addr msg["Subject"] = subject msg["In-Reply-To"] = cover_msg_id msg["Date"] = json_to_email_date(pull_request["updated_at"]) send_email(msg)