1- from discord import Message , Reaction , User , Status , Game , DMChannel , Embed
1+ from discord import Message , Status , Game , DMChannel , Embed , Interaction , InteractionType
22from discord .abc import PrivateChannel
33from discord .ext .commands import Bot , Context
4+ from discord .ui import View , Button
45from discord .utils import oauth_url
56
67from bashbot .command .about import AboutCommand
2122from bashbot .core .exceptions import SessionDontExistException , ArgumentFormatException , TerminalNotFoundException , \
2223 MacroNotFoundException
2324from bashbot .core .settings import settings
24- from bashbot .terminal . control import TerminalControl
25+ from bashbot .core . state import state
2526from bashbot .terminal .sessions import sessions
2627from bashbot .terminal .terminal import TerminalState
27- from bashbot .core .updater import updater
28+ from bashbot .core .updater import updater , Updater
2829from bashbot .core .utils import get_logger , parse_template , extract_prefix , is_command , remove_prefix
2930
3031
3132class BashBot (Bot ):
3233 logger = get_logger ('BashBot' )
3334 cmd_logger = get_logger ('Command' )
3435
35- def __init__ (self , command_prefix , ** options ):
36- super ().__init__ (command_prefix , ** options )
37- self .add_cog (OpenCommand ())
38- self .add_cog (CloseCommand ())
39- self .add_cog (HereCommand ())
40- self .add_cog (FreezeCommand ())
41- self .add_cog (RenameCommand ())
42- self .add_cog (ControlsCommand ())
43- self .add_cog (AboutCommand ())
44- self .add_cog (RepeatCommand ())
45- self .add_cog (MacroCommand ())
46- self .add_cog (SelectCommand ())
47- self .add_cog (InteractiveCommand ())
48- self .add_cog (SubmitCommand ())
49- self .add_cog (ExecCommand ())
50- self .add_cog (WhitelistCommand ())
36+ async def setup_hook (self ):
37+ await self .add_cog (OpenCommand ())
38+ await self .add_cog (CloseCommand ())
39+ await self .add_cog (HereCommand ())
40+ await self .add_cog (FreezeCommand ())
41+ await self .add_cog (RenameCommand ())
42+ await self .add_cog (ControlsCommand ())
43+ await self .add_cog (AboutCommand ())
44+ await self .add_cog (RepeatCommand ())
45+ await self .add_cog (MacroCommand ())
46+ await self .add_cog (SelectCommand ())
47+ await self .add_cog (InteractiveCommand ())
48+ await self .add_cog (SubmitCommand ())
49+ await self .add_cog (ExecCommand ())
50+ await self .add_cog (WhitelistCommand ())
5151
5252 self .remove_command ("help" )
53- self .add_cog (HelpCommand ())
53+ await self .add_cog (HelpCommand ())
5454
5555 async def on_ready (self ):
56+ if state ()['last_run_version' ] != Updater .get_local_commit ():
57+ self .logger .info ('Synchronizing command tree...' )
58+ await self .tree .sync ()
59+ self .logger .info ('Command tree synchronized' )
60+
5661 self .__check_for_updates ()
5762
5863 self .logger .info (f'Logged in as { self .user .name } ({ self .user .id } )' )
@@ -71,11 +76,14 @@ def __check_for_updates(self):
7176 if settings ().get ('other.check_for_updates' ):
7277 self .logger .info (f'Checking for updates...' )
7378
74- update_details = updater ().check_for_updates (rate_limit = False )
75- if update_details :
76- self .logger .info (f'New update available. Try running `git pull`. '
77- f'Commit "{ update_details ["message" ]} " '
78- f'({ update_details ["sha" ]} )' )
79+ releases = updater ().check_for_updates ()
80+ if releases is None :
81+ self .logger .info (f'Failed to fetch updates information' )
82+ elif releases :
83+ self .logger .info (
84+ f'New updates available. Try running `git pull`. \n ' +
85+ '\n ' .join ([f'- { x ["name" ]} ({ x ["html_url" ]} )' for x in releases ])
86+ )
7987 else :
8088 self .logger .info (f'BashBot is up to date' )
8189
@@ -146,6 +154,24 @@ async def on_message(self, message: Message):
146154 if should_delete_any or (should_delete_interactive and terminal .interactive ):
147155 await message .delete ()
148156
157+ async def on_interaction (self , interaction : Interaction ):
158+ if interaction .type != InteractionType .component :
159+ return
160+
161+ terminal = sessions ().by_message (interaction .message )
162+
163+ label = interaction .data ['custom_id' ]
164+ if label .startswith ('control_' ) and not terminal :
165+ await interaction .response .send_message (content = 'This terminal is unavailable' , ephemeral = True )
166+ view = View .from_message (interaction .message )
167+ for component in view .children :
168+ if isinstance (component , Button ):
169+ component .disabled = True
170+
171+ await interaction .message .edit (view = view )
172+ terminal .state = TerminalState .BROKEN
173+ terminal .refresh ()
174+
149175 async def on_command (self , ctx : Context ):
150176 if not isinstance (ctx .message .channel , DMChannel ):
151177 guild_name = ctx .message .channel .guild .name
@@ -159,20 +185,6 @@ async def on_command(self, ctx: Context):
159185
160186 self .cmd_logger .info (f"[{ guild_name } /#{ channel_name } ] { author_name } invoked command: { content } " )
161187
162- async def on_reaction_add (self , reaction : Reaction , user : User ):
163- if user .bot :
164- return
165-
166- terminal = sessions ().by_message (reaction .message )
167- if reaction .emoji not in terminal .controls :
168- return
169-
170- control : TerminalControl = terminal .controls [reaction .emoji ]
171- terminal .send_input (control .text )
172-
173- async def on_reaction_remove (self , reaction : Reaction , user : User ):
174- await self .on_reaction_add (reaction , user )
175-
176188 async def on_command_error (self , ctx : Context , error ):
177189 message = None
178190
0 commit comments