1
1
from __future__ import annotations
2
2
3
- import asyncio
4
- import importlib
5
- import os
6
- import re
7
- import subprocess # nosec # We already know this is dangerous, but it's needed
8
- import sys
9
3
from typing import TYPE_CHECKING , Literal , Optional
10
4
11
5
import discord
12
6
from discord .ext import commands
13
7
from discord .ext .commands import Greedy
14
8
15
9
if TYPE_CHECKING :
16
- from libs . utils import RoboContext
10
+ from utils . context import RoboContext
17
11
18
12
from bot .rodhaj import Rodhaj
19
13
20
- GIT_PULL_REGEX = re .compile (r"\s+(?P<filename>.*)\b\s+\|\s+[\d]" )
21
-
22
14
23
15
class Admin (commands .Cog , command_attrs = dict (hidden = True )):
24
16
"""Administrative commands for Rodhaj"""
@@ -33,78 +25,6 @@ def display_emoji(self) -> discord.PartialEmoji:
33
25
async def cog_check (self , ctx : RoboContext ) -> bool :
34
26
return await self .bot .is_owner (ctx .author )
35
27
36
- async def reload_or_load_extension (self , module : str ) -> None :
37
- try :
38
- await self .bot .reload_extension (module )
39
- except commands .ExtensionNotLoaded :
40
- await self .bot .load_extension (module )
41
-
42
- def find_modules_from_git (self , output : str ) -> list [tuple [int , str ]]:
43
- files = GIT_PULL_REGEX .findall (output )
44
- ret : list [tuple [int , str ]] = []
45
- for file in files :
46
- root , ext = os .path .splitext (file )
47
- if ext != ".py" or root .endswith ("__init__" ):
48
- continue
49
-
50
- true_root = "." .join (root .split ("/" )[1 :])
51
-
52
- if true_root .startswith ("cogs" ) or true_root .startswith ("libs" ):
53
- # A subdirectory within these are a part of the codebase
54
-
55
- ret .append ((true_root .count ("." ) + 1 , true_root ))
56
-
57
- # For reload order, the submodules should be reloaded first
58
- ret .sort (reverse = True )
59
- return ret
60
-
61
- async def run_process (self , command : str ) -> list [str ]:
62
- process = await asyncio .create_subprocess_shell (
63
- command , stdout = subprocess .PIPE , stderr = subprocess .PIPE
64
- )
65
- result = await process .communicate ()
66
-
67
- return [output .decode () for output in result ]
68
-
69
- def tick (self , opt : Optional [bool ], label : Optional [str ] = None ) -> str :
70
- lookup = {
71
- True : "\U00002705 " ,
72
- False : "\U0000274c " ,
73
- None : "\U000023e9 " ,
74
- }
75
- emoji = lookup .get (opt , "\U0000274c " )
76
- if label is not None :
77
- return f"{ emoji } : { label } "
78
- return emoji
79
-
80
- def format_results (self , statuses : list ) -> str :
81
- desc = "\U00002705 - Successful reload | \U0000274c - Failed reload | \U000023e9 - Skipped\n \n "
82
- status = "\n " .join (f"- { status } : `{ module } `" for status , module in statuses )
83
- desc += status
84
- return desc
85
-
86
- async def reload_exts (self , module : str ) -> list [tuple [str , str ]]:
87
- statuses = []
88
- try :
89
- await self .reload_or_load_extension (module )
90
- statuses .append ((self .tick (True ), module ))
91
- except commands .ExtensionError :
92
- statuses .append ((self .tick (False ), module ))
93
-
94
- return statuses
95
-
96
- def reload_lib_modules (self , module : str ) -> list [tuple [str , str ]]:
97
- statuses = []
98
- try :
99
- actual_module = sys .modules [module ]
100
- importlib .reload (actual_module )
101
- statuses .append ((self .tick (True ), module ))
102
- except KeyError :
103
- statuses .append ((self .tick (None ), module ))
104
- except Exception :
105
- statuses .append ((self .tick (False ), module ))
106
- return statuses
107
-
108
28
# Umbra's sync command
109
29
# To learn more about it, see the link below (and ?tag ass on the dpy server):
110
30
# https://about.abstractumbra.dev/discord.py/2023/01/29/sync-command-example.html
@@ -147,43 +67,6 @@ async def sync(
147
67
148
68
await ctx .send (f"Synced the tree to { ret } /{ len (guilds )} ." )
149
69
150
- @commands .command (name = "reload-all" , hidden = True )
151
- async def reload (self , ctx : RoboContext ) -> None :
152
- """Reloads all cogs and utils"""
153
- async with ctx .typing ():
154
- stdout , _ = await self .run_process ("git pull" )
155
-
156
- # progress and stuff is redirected to stderr in git pull
157
- # however, things like "fast forward" and files
158
- # along with the text "already up-to-date" are in stdout
159
-
160
- if stdout .startswith ("Already up-to-date." ):
161
- await ctx .send (stdout )
162
- return
163
-
164
- modules = self .find_modules_from_git (stdout )
165
-
166
- mods_text = "\n " .join (
167
- f"{ index } . `{ module } `" for index , (_ , module ) in enumerate (modules , start = 1 )
168
- )
169
- prompt_text = (
170
- f"This will update the following modules, are you sure?\n { mods_text } "
171
- )
172
-
173
- confirm = await ctx .prompt (prompt_text )
174
- if not confirm :
175
- await ctx .send ("Aborting...." )
176
- return
177
-
178
- statuses = []
179
- for is_submodule , module in modules :
180
- if is_submodule :
181
- statuses = self .reload_lib_modules (module )
182
- else :
183
- statuses = await self .reload_exts (module )
184
-
185
- await ctx .send (self .format_results (statuses ))
186
-
187
70
188
71
async def setup (bot : Rodhaj ) -> None :
189
72
await bot .add_cog (Admin (bot ))
0 commit comments