Skip to content

Commit 4a8f361

Browse files
committed
Add github commands
1 parent a08366f commit 4a8f361

File tree

2 files changed

+147
-67
lines changed

2 files changed

+147
-67
lines changed

bot.py

Lines changed: 95 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
SOFTWARE.
2323
'''
2424

25-
__version__ = '1.5.0'
25+
__version__ = '1.4.8'
2626

2727
from contextlib import redirect_stdout
2828
from urllib.parse import urlparse
@@ -44,7 +44,7 @@
4444
import aiohttp
4545

4646
from utils.paginator import PaginatorSession
47-
from utils.github import Github
47+
from utils.api import Github, ModmailApiClient
4848

4949

5050
class Modmail(commands.Bot):
@@ -325,6 +325,76 @@ async def about(self, ctx):
325325

326326
await ctx.send(embed=em)
327327

328+
@commands.group(invoke_without_subcommand=True)
329+
async def github(self, ctx):
330+
if ctx.invoked_subcommand:
331+
return
332+
333+
client = ModmailApiClient(self)
334+
data = await client.get_user_info()
335+
336+
prefix = self.config.get('PREFIX', 'm.')
337+
338+
em = discord.Embed(
339+
title='Github',
340+
color=discord.Color.red(),
341+
description=f'Not logged in, do `{prefix}github login` to login with GitHub.'
342+
)
343+
344+
if not data['error']:
345+
user = data['user']
346+
em.color = discord.Color.green()
347+
em.description = f"Currently logged in."
348+
em.set_author(name=user['username'], icon_url=user['avatar_url'], url=user['url'])
349+
em.set_thumbnail(url=user['avatar_url'])
350+
await ctx.send(embed=em)
351+
else:
352+
await ctx.send(embed=em)
353+
354+
@github.command(name='login')
355+
async def _login(self, ctx):
356+
client = ModmailApiClient(self)
357+
358+
oauth_url = 'https://github.com/login/oauth/authorize?client_id' \
359+
'=e54e4ff0f234ee9f22aa&scope=public_repo&redirect_uri=' \
360+
'https://api.kybr.tk/modmail/github/callback' \
361+
f'?token={client.token}'
362+
363+
em = discord.Embed(
364+
color=discord.Color.green(),
365+
title='Login with GitHub',
366+
description='In order to use the update command, you need ' \
367+
'to have fork the [repo](https://github.com/kyb3r/modmail) and ' \
368+
'login with GitHub so that we can update your fork to ' \
369+
'match the main repository whenever there is an update.' \
370+
'Click the link below to be taken to log in with github to authorize Modmail.'
371+
)
372+
em.set_thumbnail(url='https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png')
373+
374+
em.add_field(name='Login', value=f'[Click Here]({oauth_url})', inline=False)
375+
em.add_field(name='Warning', value='Dont share this link as it contains sensitive information.')
376+
await ctx.author.send(embed=em)
377+
378+
@github.command(name='logout')
379+
async def _logout(self, ctx):
380+
client = ModmailApiClient(self)
381+
data = await client.logout()
382+
383+
em = discord.Embed(
384+
color=discord.Color.green(),
385+
title='Logged out',
386+
description='Successfully logged out.'
387+
)
388+
389+
if data['error']:
390+
em.color = discord.Color.red()
391+
em.title = 'Error'
392+
em.description = 'You are not logged in already.'
393+
394+
await ctx.send(embed=em)
395+
396+
397+
328398

329399
@commands.command()
330400
async def update(self, ctx):
@@ -334,65 +404,44 @@ async def update(self, ctx):
334404
if ctx.author.id not in allowed:
335405
return
336406

337-
async with self.session.get('https://api.kybr.tk/modmail') as resp:
338-
data = await resp.json()
407+
client = ModmailApiClient(self)
408+
409+
metadata = await client.get_metadata()
339410

340411
em = discord.Embed(
341412
title='Already up to date',
342413
description=f'The latest version is [`{__version__}`](https://github.com/kyb3r/modmail/blob/master/bot.py#L25)',
343414
color=discord.Color.green()
344415
)
345416

346-
oauth_url = f'https://github.com/login/oauth/authorize?client_id=e54e4ff0f234ee9f22aa&scope=public_repo&redirect_uri=https://api.kybr.tk/modmail/github/callback?user_id={self.user.id}'
347-
348-
if data['latest_version'] == __version__:
349-
async with self.session.get(f'https://api.kybr.tk/modmail/github/user/{self.user.id}') as resp:
350-
if resp.status == 403:
351-
em.title = 'Unauthorised'
352-
em.description = 'You have not authorised modmail. '\
353-
'Ask the user who setup modmail to go '\
354-
f'to [this]({oauth_url}) url to authorise the '\
355-
'bot. Come back for the command later.'
356-
357-
em.color = discord.Color.red()
358-
return await ctx.send(embed=em)
359-
elif resp.status == 200:
360-
# updated!
361-
new_commit = await resp.json()
362-
commit_data = new_commit['data']
363-
else:
364-
raise NotImplementedError(f'Server returned {resp.status}')
365-
em.set_author(name=new_commit['user']['username'], icon_url=new_commit['user']['avatar_url'], url=new_commit['user']['url'])
366-
367-
if data['latest_version'] != __version__:
368-
async with self.session.get(f'https://api.kybr.tk/modmail/github/pull/{self.user.id}') as resp:
369-
if resp.status == 403:
370-
em.title = 'Unauthorised'
371-
em.description = 'You have not authorised modmail. '\
372-
'Ask the user who setup modmail to go '\
373-
f'to [this]({oauth_url}) url to authorise the '\
374-
'bot. Come back for the command later.'
375-
376-
em.color = discord.Color.red()
377-
return await ctx.send(embed=em)
378-
elif resp.status == 200:
379-
# updated!
380-
new_commit = await resp.json()
381-
commit_data = new_commit['data']
382-
else:
383-
raise NotImplementedError(f'Server returned {resp.status}')
384-
385-
em.set_footer(text=f"Updating modmail v{__version__} -> v{data['latest_version']}")
417+
if metadata['latest_version'] == __version__:
418+
data = await client.get_user_info()
419+
if not data['error']:
420+
user = data['user']
421+
em.set_author(name=user['username'], icon_url=user['avatar_url'], url=user['url'])
422+
423+
if metadata['latest_version'] != __version__:
424+
data = await client.update_repository()
425+
426+
if data['error']:
427+
prefix = self.config.get('PREFIX', 'm.')
428+
em.title = 'Unauthorised'
429+
em.description = f"You haven't logged in with github yet. Type the command `{prefix}github login` to authorize this bot."
430+
em.color = discord.Color.red()
431+
return await ctx.send(embed=em)
386432

433+
commit_data = data['data']
434+
user = data['user']
387435
em.title = 'Success'
388-
em.set_author(name=new_commit['user']['username'], icon_url=new_commit['user']['avatar_url'], url=new_commit['user']['url'])
436+
em.set_author(name=user['username'], icon_url=user['avatar_url'], url=user['url'])
437+
em.set_footer(text=f"Updating modmail v{__version__} -> v{metadata['latest_version']}")
389438

390439
if commit_data:
391440
em.description = 'Bot successfully updated, the bot will restart momentarily'
392441
message = commit_data['commit']['message']
393442
html_url = commit_data["html_url"]
394443
short_sha = commit_data['sha'][:6]
395-
em.add_field(name='Merge Commit', value=f"[`{short_sha}`]({html_url}) {message} - {new_commit['user']['username']}")
444+
em.add_field(name='Merge Commit', value=f"[`{short_sha}`]({html_url}) {message} - {user['username']}")
396445
else:
397446
em.description = 'Already up to date with master repository.'
398447

Lines changed: 52 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,42 @@
1-
class Github:
1+
from hashlib import sha256
2+
3+
class ApiClient:
4+
def __init__(self, app):
5+
self.app = app
6+
self.session = app.session
7+
self.headers = None
8+
9+
async def request(self, url, method='GET', payload=None):
10+
async with self.session.request(method, url, headers=self.headers, json=payload) as resp:
11+
try:
12+
return await resp.json()
13+
except:
14+
return await resp.text()
15+
16+
17+
class Github(ApiClient):
218
head = 'https://api.github.com/repos/kyb3r/modmail/git/refs/heads/master'
319
merge_url = 'https://api.github.com/repos/{username}/modmail/merges'
420
commit_url = 'https://api.github.com/repos/kyb3r/modmail/commits'
521

6-
def __init__(self, app, access_token=None, username=None):
7-
self.app = app
8-
self.session = app.session
9-
self.access_token = access_token
10-
self.username = username
22+
def __init__(self, app, access_token=None):
23+
super().__init__(app)
24+
self.username = None
1125
self.avatar_url = None
1226
self.url = None
1327
self.headers = None
14-
if self.access_token:
28+
if access_token:
1529
self.headers = {'Authorization': 'token ' + str(access_token)}
1630

31+
@classmethod
32+
async def login(cls, bot, access_token):
33+
self = cls(bot, access_token)
34+
resp = await self.request('https://api.github.com/user')
35+
self.username = resp['login']
36+
self.avatar_url = resp['avatar_url']
37+
self.url = resp['html_url']
38+
return self
39+
1740
async def get_latest_commits(self, limit=3):
1841
resp = await self.request(self.commit_url)
1942
for index in range(limit):
@@ -36,18 +59,26 @@ async def update_repository(self, sha=None):
3659
if isinstance(resp, dict):
3760
return resp
3861

39-
async def request(self, url, method='GET', payload=None):
40-
async with self.session.request(method, url, headers=self.headers, json=payload) as resp:
41-
try:
42-
return await resp.json()
43-
except:
44-
return await resp.text()
62+
class ModmailApiClient(ApiClient):
4563

46-
@classmethod
47-
async def login(cls, bot, access_token):
48-
self = cls(bot, access_token)
49-
resp = await self.request('https://api.github.com/user')
50-
self.username = resp['login']
51-
self.avatar_url = resp['avatar_url']
52-
self.url = resp['html_url']
53-
return self
64+
base = 'https://api.kybr.tk/modmail'
65+
github = base + '/github'
66+
67+
def __init__(self, bot):
68+
super().__init__(bot)
69+
self.token = str(sha256(bot.token.encode()).hexdigest()) # added security
70+
self.headers = {
71+
'Authorization': 'Bearer ' + self.token
72+
}
73+
74+
def get_user_info(self):
75+
return self.request(self.github + '/userinfo')
76+
77+
def update_repository(self):
78+
return self.request(self.github + '/update-repository')
79+
80+
def logout(self):
81+
return self.request(self.github + '/logout')
82+
83+
def get_metadata(self):
84+
return self.request(self.base)

0 commit comments

Comments
 (0)