add gh-email-comments.py

Script to send comments from github to email.

Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
diff --git a/README.md b/README.md
index 5080f53..e0fc1f4 100644
--- a/README.md
+++ b/README.md
@@ -10,3 +10,6 @@
 gh-imap.py - cron script to read patches from email and port to github page
 
 gh-mail-pr.py - format patches from github pull request and email them
+
+gh-email-comments.py - scripts reads comments from github web page and sends it to corresponding
+	email thread (generated by gh-mail-pr.py)
diff --git a/gh-email-comments.py b/gh-email-comments.py
new file mode 100755
index 0000000..6184ad2
--- /dev/null
+++ b/gh-email-comments.py
@@ -0,0 +1,147 @@
+#!/usr/bin/python
+#
+# Cron script to validate patches in open pull requests.
+# 1. Validation skipped if "checkpatch" label is set.
+# 2. Run both checkpatch.pl and odp agreement checks.
+# Result is status on odp pull request github web  page and
+# label "checkpatch" set.
+
+from github import Github
+import github
+import os
+import re
+import glob
+import sys
+import pickle
+import imaplib
+import email
+import smtplib
+from email.mime.text import MIMEText
+
+configfile = '/home/muvarov/gscripts_config.py'
+sys.path.append(os.path.dirname(os.path.expanduser(configfile)))
+import gscripts_config as gcfg
+
+
+gh_login = gcfg.gcfg['gh']['login']
+gh_password = gcfg.gcfg['gh']['pass']
+
+g = Github(gh_login, password=gh_password)
+
+for repo in g.get_user().get_repos():
+	if repo.full_name == "Linaro/odp":
+		break
+if not repo:
+	exit(1)
+
+# get Message-Id to reply with correct In-Reply-To
+def get_email_id_by_title(title):
+	ret_msg_id = None
+
+	imap_login = gcfg.gcfg['imap']['login']
+	imap_password = gcfg.gcfg['imap']['pass']
+
+	mail = imaplib.IMAP4_SSL('imap.yandex.ru')
+	mail.login(imap_login, imap_password)
+	mail.list()
+
+	# Out: list of "folders" aka labels in gmail.
+	mail.select("inbox") # connect to inbox.
+	mail.select(readonly=1) # Select inbox or default namespace
+
+	# imap truncates subject search
+	m = re.search(r'\[(PATCH.*v[0-9]+)\](.*)', title[0:52])
+	if not m:
+		mail.logout()
+		return None
+
+	prefix = m.group(1).lstrip() + " 0/" #look for PATCH v1 0/X
+	subject = m.group(2).lstrip()
+
+	(retcode, messages) = mail.uid('search', '(SUBJECT "%s")' % subject)
+	for num in messages[0].split():
+		typ, data = mail.fetch(num,'(RFC822)')
+		msg_str = email.message_from_string(data[0][1])
+		m = re.search(prefix,  msg_str['Subject'])
+		if not m:
+			continue
+		ret_msg_id = msg_str['Message-Id']
+		break
+	mail.logout()
+	return ret_msg_id
+
+def smtp_send_comment(pull, rvc, id):
+	if rvc.user.name:
+		user = "%s(%s)" % (rvc.user.name, rvc.user.login)
+	else:
+		user = "%s" % (rvc.user.login)
+
+	text = "%s replied on github web page:\n\n" % (user)
+
+	text += "%s\n" % (rvc.path)
+	if rvc.position:
+		text += "line %s\n" % (rvc.position)
+	text += "%s\n" % rvc.diff_hunk
+	text += "\n\n"
+	text += "Comment:\n"
+	text += rvc.body
+	text += "\n\n"
+
+	text += "%s\n" % rvc.html_url
+	text += "updated_at %s\n" % rvc.updated_at
+	msg = MIMEText(text.encode("utf-8"))
+
+	msg['Subject'] = "Re: %s" % pull.title
+	msg['From'] =  "Github ODP bot  <odpbot@yandex.ru>"
+	msg['To'] = "lng-odp@lists.linaro.org"
+	msg['In-Reply-To'] = id
+	#msg['To'] = "maxim.uvarov@linaro.org"
+
+	smtp_server = gcfg.gcfg['smtp']['server']
+	smtp_login = gcfg.gcfg['smtp']['login']
+	smtp_password = gcfg.gcfg['smtp']['pass']
+
+	s = smtplib.SMTP_SSL(smtp_server)
+	s.login(smtp_login, smtp_password)
+	s.sendmail(msg['From'], msg['To'], msg.as_string())
+	s.quit()
+
+def email_new_comment(pull, rvc):
+	id = get_email_id_by_title(pull.title)
+	smtp_send_comment(pull, rvc, id)
+
+### MAIN
+
+os.system("mkdir -p gh-ec-cache")
+
+
+for pull in repo.get_pulls():
+	try:
+		issue = repo.get_issue(pull.number)
+	except:
+		# timeout ssl http error can happen. Process this pr
+		# on next run.
+		continue
+
+	pull_cache = {}
+	filename = "gh-ec-cache/%d.cache" % pull.number
+	try:
+		f = open(filename, "rb" );
+		pull_cache = pickle.load(f)
+		f.close()
+	except:
+		print "return at 1"
+		break
+
+	try:
+		for rvc in pull.get_review_comments():
+			if rvc.id not in pull_cache:
+				email_new_comment(pull, rvc)
+				pull_cache[rvc.id] = { rvc.body }
+	except:
+		print "return at 2"
+		break
+
+	f = open(filename, 'w')
+	pickle.dump(pull_cache, f)
+	f.close()