|
| 1 | +import json, os, re, requests |
| 2 | + |
| 3 | +difficulties = {'good-first-issue':20000,'easy':100000,'medium':250000,'medium-hard':500000,'hard':1000000} |
| 4 | +priorities = {'low':0.5,'medium':1.5,'high':2,'urgent':3} |
| 5 | +ignored = ['huumn', 'ekzyis'] |
| 6 | +fn = 'awards.csv' |
| 7 | + |
| 8 | +sess = requests.Session() |
| 9 | +headers = {'Authorization':'Bearer %s' % os.getenv('GITHUB_TOKEN') } |
| 10 | +awards = [] |
| 11 | + |
| 12 | +def getIssue(n): |
| 13 | + url = 'https://api.github.com/repos/stackernews/stacker.news/issues/' + n |
| 14 | + r = sess.get(url, headers=headers) |
| 15 | + j = json.loads(r.text) |
| 16 | + return j |
| 17 | + |
| 18 | +def findIssueInPR(j): |
| 19 | + p = re.compile('(#|https://github.com/stackernews/stacker.news/issues/)([0-9]+)') |
| 20 | + for m in p.finditer(j['title']): |
| 21 | + return m.group(2) |
| 22 | + if not 'body' in j or j['body'] is None: |
| 23 | + return |
| 24 | + for s in j['body'].split('\n'): |
| 25 | + for m in p.finditer(s): |
| 26 | + return m.group(2) |
| 27 | + |
| 28 | +def addAward(user, kind, pr, issue, difficulty, priority, count, amount): |
| 29 | + if amount >= 1000000 and amount % 1000000 == 0: |
| 30 | + amount = str(int(amount / 1000000)) + 'm' |
| 31 | + elif amount >= 1000 and amount % 1000 == 0: |
| 32 | + amount = str(int(amount / 1000)) + 'k' |
| 33 | + for a in awards: |
| 34 | + if a[0] == user and a[1] == kind and a[2] == pr: |
| 35 | + print('found existing entry %s' % a) |
| 36 | + if a[8] != amount: |
| 37 | + print('warning: amount %s != %s' % (a[8], amount)) |
| 38 | + return |
| 39 | + if count < 1: |
| 40 | + count = '' |
| 41 | + addr = '???' |
| 42 | + for a in awards: |
| 43 | + if a[0] == user and a[9] != '???': |
| 44 | + addr = a[9] |
| 45 | + print('adding %s,%s,%s,%s,%s,%s,%s,,%s,%s,???' % (user, kind, pr, issue, difficulty, priority, count, amount, addr)) |
| 46 | + with open(fn, 'a') as f: |
| 47 | + print('%s,%s,%s,%s,%s,%s,%s,,%s,%s,???' % (user, kind, pr, issue, difficulty, priority, count, amount, addr), file=f) |
| 48 | + |
| 49 | +def countReviews(pr): |
| 50 | + url = 'https://api.github.com/repos/stackernews/stacker.news/issues/%s/timeline' % pr |
| 51 | + r = sess.get(url, headers=headers) |
| 52 | + j = json.loads(r.text) |
| 53 | + count = 0 |
| 54 | + for e in j: |
| 55 | + if e['event'] == 'reviewed' and e['state'] == 'changes_requested': |
| 56 | + count += 1 |
| 57 | + return count |
| 58 | + |
| 59 | +def checkPR(i): |
| 60 | + pr = str(i['number']) |
| 61 | + print('pr %s' % pr) |
| 62 | + n = findIssueInPR(i) |
| 63 | + if not n: |
| 64 | + print('pr %s does not solve an issue' % pr) |
| 65 | + return |
| 66 | + print('solves issue %s' % n) |
| 67 | + j = getIssue(n) |
| 68 | + difficulty = '' |
| 69 | + amount = 0 |
| 70 | + priority = '' |
| 71 | + multiplier = 1 |
| 72 | + for l in j['labels']: |
| 73 | + for d in difficulties: |
| 74 | + if l['name'] == 'difficulty:' + d: |
| 75 | + difficulty = d |
| 76 | + amount = difficulties[d] |
| 77 | + for p in priorities: |
| 78 | + if l['name'] == 'priority:' + p: |
| 79 | + priority = p |
| 80 | + multiplier = priorities[p] |
| 81 | + if amount * multiplier <= 0: |
| 82 | + print('issue gives no award') |
| 83 | + return |
| 84 | + count = countReviews(pr) |
| 85 | + if count >= 10: |
| 86 | + print('too many reviews, no award') |
| 87 | + return |
| 88 | + if count > 0: |
| 89 | + print('%d reviews, %d%% reduction' % (count, count * 10)) |
| 90 | + award = amount * multiplier * (10 - count) / 10 |
| 91 | + print('award is %d' % award) |
| 92 | + if i['user']['login'] not in ignored: |
| 93 | + addAward(i['user']['login'], 'pr', '#' + pr, '#' + n, difficulty, priority, count, award) |
| 94 | + if j['user']['login'] not in ignored: |
| 95 | + count = 0 |
| 96 | + addAward(j['user']['login'], 'issue', '#' + pr, '#' + n, difficulty, priority, count, int(award / 10)) |
| 97 | + |
| 98 | +with open(fn, 'r') as f: |
| 99 | + for s in f: |
| 100 | + s = s.split('\n')[0] |
| 101 | + awards.append(s.split(',')) |
| 102 | + |
| 103 | +j = json.loads(os.getenv('GITHUB_CONTEXT')) |
| 104 | +checkPR(j['event']['pull_request']) |
0 commit comments