2
2
import secrets
3
3
from datetime import datetime
4
4
5
+ from pymongo import ReturnDocument
6
+
5
7
6
8
class ApiClient :
7
9
def __init__ (self , app ):
@@ -18,15 +20,70 @@ async def request(self, url, method='GET', payload=None, return_response=False):
18
20
except :
19
21
return await resp .text ()
20
22
21
-
22
23
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' })
24
69
25
70
async def get_latest_commits (self , limit = 3 ):
26
71
resp = await self .request (self .commit_url )
27
72
for index in range (limit ):
28
73
yield resp [index ]
29
74
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
+
30
87
31
88
class ModmailApiClient (ApiClient ):
32
89
@@ -70,9 +127,7 @@ def get_config(self):
70
127
return self .request (self .config )
71
128
72
129
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
76
131
data = {k : v for k , v in data .items () if k in valid_keys }
77
132
return self .request (self .config , method = 'PATCH' , payload = data )
78
133
@@ -121,7 +176,15 @@ def post_log(self, channel_id, payload):
121
176
return self .request (self .logs + f'/{ channel_id } ' , method = 'POST' , payload = payload )
122
177
123
178
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
+ }
125
188
126
189
@property
127
190
def db (self )
@@ -171,15 +234,54 @@ async def get_log_url(self, recipient, channel, creator):
171
234
'messages' : []
172
235
})
173
236
174
- return f'https://{ self .bot .config .log_domain } /logs/{ key } '
237
+ return f'https://{ self .app .config .log_domain } /logs/{ key } '
175
238
176
239
async def get_config (self ):
177
240
return await self .db .config .find_one ({})
178
241
179
242
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
181
244
data = {k : v for k , v in data .items () if k in valid_keys }
182
245
return await self .db .config .find_one_and_replace ({}, data )
183
246
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 }
184
278
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
+ }
185
287
0 commit comments