-
Notifications
You must be signed in to change notification settings - Fork 1
/
prs.5m.py
146 lines (126 loc) · 5.58 KB
/
prs.5m.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#!/usr/bin/env PYTHONIOENCODING=UTF-8 python
# -*- coding: utf-8 -*-
# <bitbar.title>GitHub Pull Requests</bitbar.title>
# <bitbar.version>v1.0</bitbar.version>
# <bitbar.author>Rafael Quintela</bitbar.author>
# <bitbar.author.github>rafaelsq</bitbar.author.github>
# <bitbar.desc>Show github pull requests for the projects you follow</bitbar.desc>
# <bitbar.image></bitbar.image>
# <bitbar.dependencies>python</bitbar.dependencies>
# <bitbar.abouturl></bitbar.abouturl>
import re
import json
import urllib2
# https://github.com/settings/tokens with 'repo' perms
github_api_key = 'TOKEN'
me = 'USER'
ignore_labels = ('WIP',)
# to use github Approvals; repositories = (('rafaelsq/pullRequests', True), ...)
repositories = ('rafaelsq/pullRequests', )
colors = dict(nop='#660000', ok='#006600', normal='#666666', title='#FFFFFF', link='#666666', link_me='#222222', wait='#DBAB09')
imgs = dict(
red='iVBORw0KGgoAAAANSUhEUgAAAAoAAAAQCAYAAAAvf+5AAAAA1klEQVQoU83Ry03DQBRA0TOWsocOUoLpIHTgEhwJR+ycVEDoIOxQzCIdQAekBJfgPhAeNDiJDGLhJW81nzvvcyeYGOEvriJvaMd3YUURqQPtnk1FibJh8QOs6D7IZxzQBeoR0PUsXziGiiNeUxYsw/BgHmkDeSQ2XIc7FhnvkaeGdcnVjG1aV+xShcjNBcTjnu24r9Wwf+i5/Q/geZhxj+dhvntMegJvSU9G8UyX4Hvm/XB+iBQJvAiP7JLcBJ601Rmbz5Ts9IVrtMnd79LIw+BzWkwGvwAVBlT6zNjR1wAAAABJRU5ErkJggg==',
green='iVBORw0KGgoAAAANSUhEUgAAAAoAAAAQCAYAAAAvf+5AAAAA2UlEQVQoU83SzW3CQBBA4W8tcU86oASnA9KBSwApRrkZKgjpwLlFOAc6IB2EElyC+4jijbwIYSIOHLOn/Xm7M/N2ghtHuMqVco12fBYsFaJK0NpaK80x15hdgqXOt9zEDp2gGgGd3sKHQ1A6YJ9eYSGkC1NRK8hFUeM+eDKT+RK9aazM3ZnYpHmpThGihzPIq63NRXHLtH7Re/wX4KmYcZKnYlKOg57gM+nJFN51iX021af9nagYwLPwqB7kJvCorZJZ+xmEH79whTa5+xuaXFBfb4ornXIz+AvvblT6LJdT/QAAAABJRU5ErkJggg==',
grey='iVBORw0KGgoAAAANSUhEUgAAAAgAAAAOCAYAAAASVl2WAAAA6UlEQVQoU62QPUoEQRCF3+vIxNDIA4gXMDDSSFNBNh5humaEFTQxWMFcIwMVpoeRwcyfAxgIxh5B8BATCtL9pIU12A02scKqj3o/xILh7L0oiqW+77+me5pZCWDbOXeaUloGMA4hjP8A7/07yUNJ5wA2Sa4A+JZ0PwxDlT88SlqTdOKc25e0DuCa5LOkDXrvRyQfQgi/fqqq2m2a5sXMBGA0B0y1/xEws0tJeyQnIYSnLFGW5ZZz7krSR07xCuBMUt227UEGzOyW5F1K6Sab3CF5HGM86rruMwN1Xa/GGC8kvc1VPVv9QuAH2FB08Dh1TaoAAAAASUVORK5CYII='
)
reps = dict([(r, False) if not isinstance(r, tuple) else r for r in repositories])
query = '''
{%s}
fragment comparisonFields on Repository {
owner {
login
}
url
pullRequests(last: 100, states: OPEN) {
edges {
node {
title
url
author {
login
}
labels(first: 10) {
edges {
node {
name
}
}
}
mergeable
reviews(first:10, states:APPROVED) {
edges {
node {
state
}
}
}
commits(last: 1) {
edges {
node {
commit {
status {
state
}
}
}
}
}
}
}
}
}
''' % (' '.join(['%s: repository(owner: "%s", name: "%s") { ...comparisonFields }' % (
(repository.split("/")[1], ) + tuple(repository.split("/"))) for repository in reps.keys()]), )
def make_github_request(url, query):
request = urllib2.Request(url, headers={'Authorization': 'token ' + github_api_key})
response = urllib2.urlopen(request, json.dumps(dict(query=query)))
return json.load(response) if response.headers.get('content-length', 0) > 0 else {}
repos = make_github_request("https://api.github.com/graphql", query=query)['data']
lines = [u"---"]
countPRs = 0
countPRsApproved = 0
showGreenIco = False
showRedIco = False
for repository, repo in repos.iteritems():
lines.append(u"%s | color=%s href=%s/pulls" % (repository, colors['title'], repo['url']))
own = repo['owner']['login'] + '/' + repository
for pr in repo['pullRequests']['edges']:
color = colors['link']
u = u" (@%s)" % pr['node']['author']['login']
status = pr['node']['commits']['edges'][0]['node']['commit']['status']
tags = [l['node']['name'] for l in pr['node']['labels']['edges']]
ico = False
brokenHeart = [':broken_heart: ', ''][pr['node']['mergeable'] == "MERGEABLE"]
approvals = len(pr['node']['reviews']['edges'])
if me == pr['node']['author']['login']:
countPRs += 1
u = ""
color = colors['link_me']
if status and status['state'] == "SUCCESS":
color = colors['ok']
if approvals < 2:
color = colors['wait']
elif approvals > 1:
countPRsApproved += 1
showGreenIco = True
ico = True
elif (status and status['state'] in ("FAILURE", "ERROR")) or (status and not status.get('context')):
color = colors['nop']
showRedIco = True
if brokenHeart:
color = colors['nop']
showRedIco = True
elif (not status or status['state'] in ("FAILURE", "ERROR")) or set(tags).intersection(ignore_labels):
continue
elif status and status['state'] == "SUCCESS" and approvals > 1:
ico = True
lines.append(u"%s%s%s | color=%s href=%s image=%s" % (brokenHeart, pr['node']['title'].replace("|", " "), u, color, pr['node']['url'], imgs['green'] if ico else ''))
lines.append(u"---")
lines.append(u"Refresh | refresh=true")
lines.insert(0, u"%s%s| color=%s image=%s" % (
("%d/" % countPRsApproved) if countPRsApproved else "",
str(countPRs or ""),
colors['nop'] if showRedIco else (colors['ok'] if showGreenIco else colors['normal']),
imgs['red'] if showRedIco else (imgs['green'] if showGreenIco else imgs['grey']),
))
print u"\n".join(lines)