Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1897)

Unified Diff: my_activity.py

Issue 24047003: my_activity.py: Use gerrit new REST API. (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: maruel nit Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: my_activity.py
diff --git a/my_activity.py b/my_activity.py
index 16d3f7dba4770c620b381233818d5651d2bc88e8..3d73c8b1c3908853d714b14754f412203eb43ddd 100755
--- a/my_activity.py
+++ b/my_activity.py
@@ -116,14 +116,22 @@ rietveld_instances = [
gerrit_instances = [
{
- 'url': 'gerrit.chromium.org',
- 'port': 29418,
+ 'url': 'chromium-review.googlesource.com',
'shorturl': 'crosreview.com',
},
+ # TODO(deymo): chrome-internal-review requires login credentials. Enable once
+ # login support is added to this client. See crbug.com/281695.
+ #{
+ # 'url': 'chrome-internal-review.googlesource.com',
+ # 'shorturl': 'crosreview.com/i',
+ #},
+ {
+ 'host': 'gerrit.chromium.org',
+ 'port': 29418,
+ },
{
- 'url': 'gerrit-int.chromium.org',
+ 'host': 'gerrit-int.chromium.org',
'port': 29419,
- 'shorturl': 'crosreview.com/i',
},
]
@@ -239,6 +247,10 @@ def get_yes_or_no(msg):
return False
+def datetime_from_gerrit(date_string):
+ return datetime.strptime(date_string, '%Y-%m-%d %H:%M:%S.%f000')
+
+
def datetime_from_rietveld(date_string):
return datetime.strptime(date_string, '%Y-%m-%d %H:%M:%S.%f')
@@ -376,33 +388,70 @@ class MyActivity(object):
ret.append(r)
return ret
- def gerrit_search(self, instance, owner=None, reviewer=None):
- max_age = datetime.today() - self.modified_after
- max_age = max_age.days * 24 * 3600 + max_age.seconds
-
+ @staticmethod
+ def gerrit_changes_over_ssh(instance, filters):
# See https://review.openstack.org/Documentation/cmd-query.html
# Gerrit doesn't allow filtering by created time, only modified time.
- user_filter = 'owner:%s' % owner if owner else 'reviewer:%s' % reviewer
- gquery_cmd = ['ssh', '-p', str(instance['port']), instance['url'],
+ gquery_cmd = ['ssh', '-p', str(instance['port']), instance['host'],
'gerrit', 'query',
'--format', 'JSON',
'--comments',
- '--',
- '-age:%ss' % str(max_age),
- user_filter]
- [stdout, _] = subprocess.Popen(gquery_cmd, stdout=subprocess.PIPE,
+ '--'] + filters
+ (stdout, _) = subprocess.Popen(gquery_cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE).communicate()
- issues = str(stdout).split('\n')[:-2]
- issues = map(json.loads, issues)
+ # Drop the last line of the output with the stats.
+ issues = stdout.splitlines()[:-1]
+ return map(json.loads, issues)
+
+ @staticmethod
+ def gerrit_changes_over_rest(instance, filters):
+ # See https://gerrit-review.googlesource.com/Documentation/rest-api.html
+ # Gerrit doesn't allow filtering by created time, only modified time.
+ args = urllib.urlencode([
+ ('q', ' '.join(filters)),
+ ('o', 'MESSAGES'),
+ ('o', 'LABELS')])
+ rest_url = 'https://%s/changes/?%s' % (instance['url'], args)
+
+ req = urllib2.Request(rest_url, headers={'Accept': 'text/plain'})
+ try:
+ response = urllib2.urlopen(req)
+ stdout = response.read()
+ except urllib2.HTTPError, e:
+ print 'ERROR: Looking up %r: %s' % (rest_url, e)
+ return []
+
+ # Check that the returned JSON starts with the right marker.
+ if stdout[:5] != ")]}'\n":
+ print 'ERROR: Marker not found on REST API response: %r' % stdout[:5]
+ return []
+ return json.loads(stdout[5:])
+
+ def gerrit_search(self, instance, owner=None, reviewer=None):
+ max_age = datetime.today() - self.modified_after
+ max_age = max_age.days * 24 * 3600 + max_age.seconds
+ user_filter = 'owner:%s' % owner if owner else 'reviewer:%s' % reviewer
+ filters = ['-age:%ss' % max_age, user_filter]
+
+ # Determine the gerrit interface to use: SSH or REST API:
+ if 'host' in instance:
+ issues = self.gerrit_changes_over_ssh(instance, filters)
+ issues = [self.process_gerrit_ssh_issue(instance, issue)
+ for issue in issues]
+ elif 'url' in instance:
+ issues = self.gerrit_changes_over_rest(instance, filters)
+ issues = [self.process_gerrit_rest_issue(instance, issue)
+ for issue in issues]
+ else:
+ raise Exception('Invalid gerrit_instances configuration.')
# TODO(cjhopman): should we filter abandoned changes?
- issues = [self.process_gerrit_issue(instance, issue) for issue in issues]
issues = filter(self.filter_issue, issues)
issues = sorted(issues, key=lambda i: i['modified'], reverse=True)
return issues
- def process_gerrit_issue(self, instance, issue):
+ def process_gerrit_ssh_issue(self, instance, issue):
ret = {}
ret['review_url'] = issue['url']
if 'shorturl' in instance:
@@ -414,25 +463,56 @@ class MyActivity(object):
ret['created'] = datetime.fromtimestamp(issue['createdOn'])
ret['modified'] = datetime.fromtimestamp(issue['lastUpdated'])
if 'comments' in issue:
- ret['replies'] = self.process_gerrit_issue_replies(issue['comments'])
+ ret['replies'] = self.process_gerrit_ssh_issue_replies(issue['comments'])
else:
ret['replies'] = []
- ret['reviewers'] = set()
- for reply in ret['replies']:
- if reply['author'] != ret['author']:
- ret['reviewers'].add(reply['author'])
+ ret['reviewers'] = set(r['author'] for r in ret['replies'])
+ ret['reviewers'].discard(ret['author'])
return ret
@staticmethod
- def process_gerrit_issue_replies(replies):
+ def process_gerrit_ssh_issue_replies(replies):
ret = []
replies = filter(lambda r: 'email' in r['reviewer'], replies)
for reply in replies:
- r = {}
- r['author'] = reply['reviewer']['email']
- r['created'] = datetime.fromtimestamp(reply['timestamp'])
- r['content'] = ''
- ret.append(r)
+ ret.append({
+ 'author': reply['reviewer']['email'],
+ 'created': datetime.fromtimestamp(reply['timestamp']),
+ 'content': '',
+ })
+ return ret
+
+ def process_gerrit_rest_issue(self, instance, issue):
+ ret = {}
+ ret['review_url'] = 'https://%s/%s' % (instance['url'], issue['_number'])
+ if 'shorturl' in instance:
+ # TODO(deymo): Move this short link to https once crosreview.com supports
+ # it.
+ ret['review_url'] = 'http://%s/%s' % (instance['shorturl'],
+ issue['_number'])
+ ret['header'] = issue['subject']
+ ret['owner'] = issue['owner']['email']
+ ret['author'] = ret['owner']
+ ret['created'] = datetime_from_gerrit(issue['created'])
+ ret['modified'] = datetime_from_gerrit(issue['updated'])
+ if 'messages' in issue:
+ ret['replies'] = self.process_gerrit_rest_issue_replies(issue['messages'])
+ else:
+ ret['replies'] = []
+ ret['reviewers'] = set(r['author'] for r in ret['replies'])
+ ret['reviewers'].discard(ret['author'])
+ return ret
+
+ @staticmethod
+ def process_gerrit_rest_issue_replies(replies):
+ ret = []
+ replies = filter(lambda r: 'email' in r['author'], replies)
+ for reply in replies:
+ ret.append({
+ 'author': reply['author']['email'],
+ 'created': datetime_from_gerrit(reply['date']),
+ 'content': reply['message'],
+ })
return ret
def google_code_issue_search(self, instance):
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698