Skip to content

Commit 894d0d1

Browse files
committed
Finish the interfaces
1 parent a3134bd commit 894d0d1

File tree

3 files changed

+129
-17
lines changed

3 files changed

+129
-17
lines changed

bot.py

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
from colorama import init, Fore, Style
3939
import emoji
4040

41-
from core.interfaces import Github, ModmailApiClient, SelfhostedApiInterface
41+
from core.clients import Github, ModmailApiClient, SelfhostedClient
4242
from core.thread import ThreadManager
4343
from core.config import ConfigManager
4444
from core.changelog import ChangeLog
@@ -58,7 +58,8 @@ def __init__(self):
5858
self.threads = ThreadManager(self)
5959
self.session = aiohttp.ClientSession(loop=self.loop)
6060
self.config = ConfigManager(self)
61-
self.modmail_api = ModmailApiClient(self)
61+
self.selfhosted = bool(self.config.get('mongo_uri'))
62+
self.modmail_api = SelfhostedClient(self) if self.selfhosted else ModmailApiClient(self)
6263
self.data_task = self.loop.create_task(self.data_loop())
6364
self.autoupdate_task = self.loop.create_task(self.autoupdate_loop())
6465
self._add_commands()
@@ -159,8 +160,9 @@ async def get_pre(bot, message):
159160

160161
async def on_connect(self):
161162
print(line + Fore.RED + Style.BRIGHT)
162-
await self.validate_api_token()
163-
print(line)
163+
if not self.selfhosted:
164+
await self.validate_api_token()
165+
print(line)
164166
print(Fore.CYAN + 'Connected to gateway.')
165167
await self.config.refresh()
166168
status = self.config.get('status')
@@ -393,11 +395,18 @@ async def data_loop(self):
393395
await asyncio.sleep(3600)
394396

395397
async def autoupdate_loop(self):
396-
while True:
397-
if self.config.get('disable_autoupdates'):
398-
await asyncio.sleep(3600)
399-
continue
398+
await self.wait_until_ready()
400399

400+
if self.config.get('disable_autoupdates'):
401+
print('Autoupdates disabled.')
402+
return
403+
404+
if self.selfhosted and not self.config.get('github_access_token'):
405+
print('Github access token not found.')
406+
print('Autoupdates disabled.')
407+
return
408+
409+
while True:
401410
metadata = await self.modmail_api.get_metadata()
402411

403412
if metadata['latest_version'] != self.version:

core/interfaces.py renamed to core/clients.py

Lines changed: 110 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import secrets
33
from datetime import datetime
44

5+
from pymongo import ReturnDocument
6+
57

68
class ApiClient:
79
def __init__(self, app):
@@ -18,15 +20,70 @@ async def request(self, url, method='GET', payload=None, return_response=False):
1820
except:
1921
return await resp.text()
2022

21-
2223
class Github(ApiClient):
23-
commit_url = 'https://api.github.com/repos/kyb3r/modmail/commits'
24+
BASE = 'https://api.github.com'
25+
REPO = BASE + '/repos/kyb3r/modmail'
26+
head = REPO + '/git/refs/heads/master'
27+
merge_url = BASE + '/repos/{username}/modmail/merges'
28+
fork_url = REPO + '/forks'
29+
star_url = BASE + '/user/starred/kyb3r/modmail'
30+
31+
def __init__(self, app, access_token=None, username=None):
32+
self.app = app
33+
self.session = app.session
34+
self.access_token = access_token
35+
self.username = username
36+
self.id = None
37+
self.avatar_url = None
38+
self.url = None
39+
self.headers = None
40+
if self.access_token:
41+
self.headers = {'Authorization': 'token ' + str(access_token)}
42+
43+
async def update_repository(self, sha=None):
44+
if sha is None:
45+
resp = await self.request(self.head)
46+
sha = resp['object']['sha']
47+
48+
payload = {
49+
'base': 'master',
50+
'head': sha,
51+
'commit_message': 'Updating bot'
52+
}
53+
54+
merge_url = self.merge_url.format(username=self.username)
55+
56+
resp = await self.request(merge_url, method='POST', payload=payload)
57+
if isinstance(resp, dict):
58+
return resp
59+
60+
async def fork_repository(self):
61+
await self.request(self.fork_url, method='POST')
62+
63+
async def has_starred(self):
64+
resp = await self.request(self.star_url, return_response=True)
65+
return resp.status == 204
66+
67+
async def star_repository(self):
68+
await self.request(self.star_url, method='PUT', headers={'Content-Length': '0'})
2469

2570
async def get_latest_commits(self, limit=3):
2671
resp = await self.request(self.commit_url)
2772
for index in range(limit):
2873
yield resp[index]
2974

75+
@classmethod
76+
async def login(cls, bot):
77+
self = cls(bot, bot.config.get('github_access_token'))
78+
resp = await self.request('https://api.github.com/user')
79+
self.username = resp['login']
80+
self.avatar_url = resp['avatar_url']
81+
self.url = resp['html_url']
82+
self.id = resp['id']
83+
self.raw_data = resp
84+
print(f'Logged in to: {self.username} - {self.id}')
85+
return self
86+
3087

3188
class ModmailApiClient(ApiClient):
3289

@@ -70,9 +127,7 @@ def get_config(self):
70127
return self.request(self.config)
71128

72129
def update_config(self, data):
73-
74-
valid_keys = self.app.config.valid_keys - {'token', 'modmail_api_token', 'modmail_guild_id', 'guild_id'}
75-
130+
valid_keys = self.app.config.valid_keys - self.app.config.protected_keys
76131
data = {k: v for k, v in data.items() if k in valid_keys}
77132
return self.request(self.config, method='PATCH', payload=data)
78133

@@ -121,7 +176,15 @@ def post_log(self, channel_id, payload):
121176
return self.request(self.logs + f'/{channel_id}', method='POST', payload=payload)
122177

123178

124-
class SelfhostedApiInterface(ModmailApiClient):
179+
class SelfhostedClient(ModmailApiClient):
180+
181+
def __init__(self, bot):
182+
super().__init__(bot)
183+
self.token = bot.config.get('github_access_token')
184+
if self.token:
185+
self.headers = {
186+
'Authorization': 'Bearer ' + self.token
187+
}
125188

126189
@property
127190
def db(self)
@@ -171,15 +234,54 @@ async def get_log_url(self, recipient, channel, creator):
171234
'messages': []
172235
})
173236

174-
return f'https://{self.bot.config.log_domain}/logs/{key}'
237+
return f'https://{self.app.config.log_domain}/logs/{key}'
175238

176239
async def get_config(self):
177240
return await self.db.config.find_one({})
178241

179242
async def update_config(self, data):
180-
valid_keys = self.app.config.valid_keys - {'token', 'modmail_api_token', 'modmail_guild_id', 'guild_id'}
243+
valid_keys = self.app.config.valid_keys - self.app.config.protected_keys
181244
data = {k: v for k, v in data.items() if k in valid_keys}
182245
return await self.db.config.find_one_and_replace({}, data)
183246

247+
async def append_log(self, message, channel_id=''):
248+
channel_id = str(channel_id) or str(message.channel.id)
249+
payload = {
250+
'timestamp': str(message.created_at),
251+
'message_id': str(message.id),
252+
# author
253+
'author': {
254+
'id': str(message.author.id),
255+
'name': message.author.name,
256+
'discriminator': message.author.discriminator,
257+
'avatar_url': message.author.avatar_url,
258+
'mod': not isinstance(message.channel, discord.DMChannel),
259+
},
260+
# message properties
261+
'content': message.content,
262+
'attachments': [i.url for i in message.attachments]
263+
}
264+
265+
return await self.logs.find_one_and_update(
266+
{'channel_id': channel_id},
267+
{'$push': {f'messages': payload}},
268+
return_document=ReturnDocument.AFTER
269+
)
270+
271+
async def post_log(self, channel_id, payload):
272+
await self.logs.find_one_and_replace({'channel_id': channel_id}, payload)
273+
274+
async def update_repository(self):
275+
user = await Github.login(self.app)
276+
data = await user.update_repository()
277+
return {'data': data}
184278

279+
def get_user_info(self):
280+
user = await Github.login(self.app)
281+
return {
282+
'user': {
283+
'username': user.username,
284+
'avatar_url': user.avatar_url,
285+
'url': user.url
286+
}
185287

core/config.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ class ConfigManager:
1616
}
1717

1818
protected_keys = {
19-
'token', 'owners', 'modmail_api_token', 'guild_id', 'modmail_guild_id',
19+
'token', 'owners', 'modmail_api_token', 'guild_id', 'modmail_guild_id',
20+
'mongo_uri', 'github_access_token', 'log_domain'
2021
}
2122

2223
valid_keys = allowed_to_change_in_command.union(internal_keys).union(protected_keys)

0 commit comments

Comments
 (0)