-
Notifications
You must be signed in to change notification settings - Fork 0
/
ghstatus.py
125 lines (104 loc) · 4.44 KB
/
ghstatus.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
# Copyright 2018 Argo AI, LLC.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from errbot import BotPlugin, botcmd, arg_botcmd
from github import Github
USERS = 'users'
class GHStatus(BotPlugin):
"""
This plugin allows you to query github for state on developers.
"""
def get_configuration_template(self):
"""
Get configuration template for this plugin.
It works by mapping users on chat to github users.
"""
return {'github-token': '73fb2928cf017d0ff1e493a7d6ccd4cde1e591f7', 'repo': 'argoai/av'}
def check_id(self, usr: str):
try:
self.build_identifier(usr)
except Exception as _:
return False
return True
def activate(self):
if not self.config:
return # do not activate if the plugin is not configured
super().activate()
self.gh = Github(self.config['github-token'], api_preview=True)
self.repo = self.gh.get_repo(self.config['repo'])
self.USERS = USERS # easier to use for external dependencies.
if USERS not in self:
self[USERS]={}
@botcmd
def gh_users(self, msg, _):
"""List currently configured users."""
response = '__Configured users__\n'
if not self[USERS]:
return ' -> no user configured yet, use !gh users add'
for chat_usr, gh_usr in self[USERS].items():
response += f'- {chat_usr} ▶ {gh_usr}\n'
return response
@arg_botcmd('gh_usr')
@arg_botcmd('chat_usr')
def gh_users_add(self, _, chat_usr, gh_usr):
"""Add a user mapping from chat user to github user."""
if not self.check_id(chat_usr):
return f'{chat_usr} is not a valid {self.mode} user.' # self.mode is for example 'Slack'
with self.mutable(USERS) as users:
users[chat_usr] = gh_usr
return f'{chat_usr} ▶ {gh_usr} configured.'
@arg_botcmd('chat_usr')
def gh_users_rm(self, _, chat_usr):
"""Removes a user mapping."""
with self.mutable(USERS) as users:
del users[chat_usr]
return f'{chat_usr} removed.'
@botcmd
def gh_prs(self, msg, chat_usr):
"""Lists PRs opened by your user or the one specified as an argument."""
if not chat_usr:
chat_usr = str(msg.frm.aclattr)
if not self.check_id(chat_usr):
return f'{chat_usr} is not a valid slack user.'
users = self[USERS]
if chat_usr not in users:
return f'{chat_usr} user is unknown. Use !gh users add.'
gh_user = users[chat_usr]
prs = [i for i in self.repo.get_issues(creator=gh_user) if i.pull_request]
if not prs:
return 'No PRs found.'
response = f'__PRs currently opened by {chat_usr}__\n\n'
for pr in prs:
response += f'- [{pr.number}]({pr.html_url}) {pr.title}\n'
return response
@botcmd
def gh_reviews(self, msg, chat_usr):
"""Lists the PRs you are specifically named as reviewer on or specify a chat user."""
if not chat_usr:
chat_usr = str(msg.frm.aclattr)
if not self.check_id(chat_usr):
return f'{chat_usr} is not a valid slack user.'
users = self[USERS]
if chat_usr not in users:
return f'{chat_usr} user is unknown. Use !gh users add.'
gh_user = users[chat_usr]
# adding review-requested AND involves is a trick to only get PRs you are explicitely asked to review.
# otherwise you will get any group you belong to.
prs = self.gh.search_issues(f'state:open type:pr review-requested:{gh_user} '
f'involves:{gh_user} repo:{self.repo.full_name}')
if not prs:
return 'No PRs found.'
response = f'__PRs open for review for {chat_usr}__\n\n'
for pr in prs:
response += f'- [{pr.number}]({pr.html_url}) {pr.title}\n'
return response