From 090860da8cedc74d7f97dae027dfa1dfbd3db4cd Mon Sep 17 00:00:00 2001 From: Ralph Bean Date: Mon, 17 Nov 2014 15:39:07 -0500 Subject: [PATCH] Let .pulls accept just a username. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this, it needed both a username and a repo. Check this out: ``` @threebean │ .pulls threebot │ threebean: (pulls ) -- List the pending pull requests on github repos. @threebean │ .pulls what/is/this threebot │ threebean: Must be GitHub repo of the format or just @threebean │ .pulls lmacken threebot │ threebean: One moment, please... Looking up lmacken. threebot │ threebean: @msabramo's "README.rst: syntax highlight + tweaks" https://github.com/lmacken/tbgrep/pull/8 filed │ 4 days ago threebot │ threebean: @Qalthos's "Update action_hooks" https://github.com/lmacken/pyramid-openshift-quickstart/pull/7 │ filed a year ago e @threebean │ .pulls fedora-infra threebot │ threebean: One moment, please... threebot │ threebean: @ralphbean's "Handle timezones." https://github.com/fedora-infra/bugzilla2fedmsg/pull/4 filed 41 │ minutes ago threebot │ threebean: @ralphbean's "Remove unused imports." https://github.com/fedora-infra/fedmsg/pull/300 filed 2 days │ ago threebot │ threebean: @pypingou's "Let the unorphan action call the unorphan API endpoint" │ https://github.com/fedora-infra/packagedb-cli/pull/21 filed 3 days ago threebot │ threebean: @ralphbean's "Getting ready for the 1.2.0 release." https://github.com/fedora-infra/kitchen/pull/5 │ filed 4 days ago threebot │ threebean: ... and 6 more. @threebean │ .pulls fedora-infra/fedmsg threebot │ threebean: @ralphbean's "Remove unused imports." https://github.com/fedora-infra/fedmsg/pull/300 filed 2 days │ ago ``` --- plugin.py | 87 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 60 insertions(+), 27 deletions(-) diff --git a/plugin.py b/plugin.py index 2f1636f..ef34d64 100644 --- a/plugin.py +++ b/plugin.py @@ -226,31 +226,77 @@ def _load_json(self, url): return json def pulls(self, irc, msg, args, slug): - """ + """ - List the pending pull requests on a github repo. + List the latest pending pull requests on github repos. """ - if slug.count('/') != 1: - irc.reply('Must be GitHub repo of the format ') + if not slug.strip(): + irc.reply('Must be GitHub repo of the format ' + ' or just ') + elif slug.count('/') == 0: + username, repo = slug.strip(), None + elif slug.count('/') == 1: + username, repo = slug.strip().split('/') + else: + irc.reply('Must be GitHub repo of the format ' + ' or just ') return - username, repo = slug.strip().split('/') + if repo: + repos = [repo] + else: + irc.reply('One moment, please... Looking up %s.' % username) + repos = list(self.yield_github_repos(username)) + + results = sum([ + list(self.yield_github_pulls(username, repo)) for repo in repos + ], []) + + # Reverse-sort by time (newest-first) + def comparator(a, b): + return cmp(arrow.get(b['created_at']), arrow.get(a['created_at'])) + results.sort(comparator) + + if not results: + irc.reply('No pending pull requests on {slug}'.format(slug=slug)) + else: + n = 4 + for pull in results[:n]: + irc.reply('@{user}\'s "{title}" {url} filed {age}'.format( + user=pull['user']['login'], + title=pull['title'], + url=pull['html_url'], + age=arrow.get(pull['created_at']).humanize(), + )) + + if len(results) > n: + irc.reply('... and %i more.' % (len(results) - n)) + pulls = wrap(pulls, ['text']) + + def yield_github_repos(self, username): + self.log.info("Finding github repos for %r" % username) + tmpl = "https://api.github.com/users/{username}/repos?per_page=100" + url = tmpl.format(username=username) + auth = dict(access_token=self.github_oauth_token) + for result in self.yield_github_results(url, auth): + yield result['name'] + def yield_github_pulls(self, username, repo): + self.log.info("Finding github pull requests for %r %r" % (username, repo)) tmpl = "https://api.github.com/repos/{username}/{repo}/" + \ "pulls?per_page=100" url = tmpl.format(username=username, repo=repo) auth = dict(access_token=self.github_oauth_token) + for result in self.yield_github_results(url, auth): + yield result + def yield_github_results(self, url, auth): results = [] link = dict(next=url) while 'next' in link: response = requests.get(link['next'], params=auth) - if response.status_code == 404: - irc.reply('No such GitHub repository %r' % slug) - return - # And.. if we didn't get good results, just bail. if response.status_code != 200: raise IOError( @@ -259,10 +305,13 @@ def pulls(self, irc, msg, args, slug): if callable(response.json): # Newer python-requests - results += response.json() + results = response.json() else: # Older python-requests - results += response.json + results = response.json + + for result in results: + yield result field = response.headers.get('link', None) @@ -275,22 +324,6 @@ def pulls(self, irc, msg, args, slug): ) for part in field.split(', ') ]) - if not results: - irc.reply('No pending pull requests on {slug}'.format(slug=slug)) - else: - n = 4 - for pull in results[:n]: - irc.reply('@{user}\'s "{title}" {url}'.format( - user=pull['user']['login'], - title=pull['title'], - url=pull['html_url'])) - - if len(results) > n: - irc.reply('... and %i more.' % (len(results) - n)) - - - pulls = wrap(pulls, ['text']) - def whoowns(self, irc, msg, args, package): """