2121from enum import Enum
2222from discord .ext import bridge
2323from shinobu .beacon .protocol import (drivers as beacon_drivers , spaces as beacon_spaces , messages as beacon_messages ,
24- filters as beacon_filters , pausing as beacon_pausing )
24+ filters as beacon_filters , pausing as beacon_pausing , moderators as beacon_mods ,
25+ bans as beacon_bans )
2526from shinobu .beacon .models import (space as beacon_space , message as beacon_message , content as beacon_content ,
2627 filter as beacon_filter , member as beacon_member , channel as beacon_channel ,
2728 driver as beacon_driver , server as beacon_server , user as beacon_user )
@@ -39,6 +40,10 @@ class BeaconPlatformDisabled(Exception):
3940 def __init__ (self , platform : str ):
4041 super ().__init__ (f"The resource is not available because { platform } is disabled." )
4142
43+ class BeaconIsBanned (Exception ):
44+ def __init__ (self , user_or_server : str ):
45+ super ().__init__ (f"This action cannot be done as { user_or_server } is banned." )
46+
4247class BeaconCallback :
4348 def __init__ (self , func , args : list | None = None , kwargs : dict | None = None ):
4449 self ._func = func
@@ -91,6 +96,8 @@ def __init__(self, bot: bridge.Bot, files_wrapper: fine_grained.FineGrainedSecur
9196 self ._messages : beacon_messages .BeaconMessageCache = beacon_messages .BeaconMessageCache (self .__wrapper )
9297 self ._filters : beacon_filters .BeaconFilterManager = beacon_filters .BeaconFilterManager ()
9398 self ._pausing : beacon_pausing .BeaconPauseManager = beacon_pausing .BeaconPauseManager ()
99+ self ._moderators : beacon_mods .BeaconModManager = beacon_mods .BeaconModManager ()
100+ self ._bans : beacon_bans .BeaconBanManager = beacon_bans .BeaconBanManager ()
94101
95102 @property
96103 def initialized (self ) -> bool :
@@ -112,6 +119,14 @@ def spaces(self) -> beacon_spaces.BeaconSpaceManager:
112119 def messages (self ) -> beacon_messages .BeaconMessageCache :
113120 return self ._messages
114121
122+ @property
123+ def moderators (self ) -> beacon_mods .BeaconModManager :
124+ return self ._moderators
125+
126+ @property
127+ def bans (self ) -> beacon_bans .BeaconBanManager :
128+ return self ._bans
129+
115130 @property
116131 def disabled_platforms (self ) -> list [str ]:
117132 return self ._disabled_platforms
@@ -333,6 +348,33 @@ def _load_data(self):
333348
334349 self .messages .add_message (group )
335350
351+ # Load moderators
352+ if data .get ("moderators" ):
353+ for _ , mod_data in data ["moderators" ].get ("moderators" , {}).items ():
354+ moderator : beacon_mods .BeaconModerator = beacon_mods .BeaconModerator (
355+ user_id = mod_data ["id" ],
356+ platform = mod_data ["platform" ]
357+ )
358+ self .moderators .add_moderator (moderator )
359+
360+ for _ , admin_data in data ["moderators" ].get ("admins" , {}).items ():
361+ admin : beacon_mods .BeaconAdmin = beacon_mods .BeaconAdmin (
362+ user_id = admin_data ["id" ],
363+ platform = admin_data ["platform" ]
364+ )
365+ self .moderators .add_admin (admin )
366+
367+ # Load bans
368+ for ban_id , ban_data in data .get ("bans" , {}).items ():
369+ ban : beacon_bans .BeaconBan = beacon_bans .BeaconBan (
370+ user_id = ban_id ,
371+ ban_type = ban_data .get ("type" , 0 ),
372+ platform = ban_data .get ("platform" ),
373+ expiry = ban_data .get ("expiry" )
374+ )
375+
376+ self .bans .add_ban (ban )
377+
336378 self ._init = True
337379
338380 # Add shutdown cleanup
@@ -350,6 +392,8 @@ def save_data(self):
350392 # Assemble data dict
351393 data : dict = {
352394 "spaces" : self ._spaces .to_dict (),
395+ "moderators" : self ._moderators .to_dict (),
396+ "bans" : self ._bans .to_dict (),
353397 "paused" : self ._pausing .to_dict (),
354398 "raw" : self ._data
355399 }
@@ -589,6 +633,14 @@ async def send(self, author: beacon_member.BeaconMember | beacon_member.BeaconPa
589633 if content .original_platform in self ._disabled_platforms :
590634 raise BeaconPlatformDisabled (content .original_platform )
591635
636+ # Ensure user is not banned
637+ if self .bans .is_banned (author ):
638+ raise BeaconIsBanned (author .id )
639+
640+ # Ensure server is not banned
641+ if self .bans .is_banned (author .server ):
642+ raise BeaconIsBanned (author .server_id )
643+
592644 # Ensure content is not empty
593645 if len (content .blocks ) == 0 and len (content .files ) == 0 :
594646 return
@@ -704,6 +756,14 @@ async def edit(self, message: beacon_message.BeaconMessage, content: beacon_mess
704756 if content .original_platform in self ._disabled_platforms :
705757 raise BeaconPlatformDisabled (content .original_platform )
706758
759+ # Ensure user is not banned
760+ if self .bans .is_banned (message .author ):
761+ raise BeaconIsBanned (message .author .id )
762+
763+ # Ensure server is not banned
764+ if self .bans .is_banned (message .server ):
765+ raise BeaconIsBanned (message .server .id )
766+
707767 origin_driver : beacon_driver .BeaconDriver = self ._drivers .get_driver (message .platform )
708768
709769 # Get message metadata
@@ -772,6 +832,10 @@ async def delete(self, message: beacon_message.BeaconMessage):
772832 if message .platform in self ._disabled_platforms :
773833 raise BeaconPlatformDisabled (message .platform )
774834
835+ # Ensure server is not banned
836+ if self .bans .is_banned (message .server ):
837+ raise BeaconIsBanned (message .server .id )
838+
775839 # Get message group
776840 message_group : beacon_message .BeaconMessageGroup = self .messages .get_group_from_message (message .id )
777841 if not message_group :
@@ -817,6 +881,10 @@ async def purge(self, messages: list[beacon_message.BeaconMessage]):
817881 if messages [0 ].platform in self ._disabled_platforms :
818882 raise BeaconPlatformDisabled (messages [0 ].platform )
819883
884+ # Ensure server is not banned
885+ if self .bans .is_banned (messages [0 ].server ):
886+ raise BeaconIsBanned (messages [0 ].server .id )
887+
820888 # Get message groups
821889 message_groups : list [beacon_message .BeaconMessageGroup ] = []
822890 for message in messages :
@@ -859,14 +927,22 @@ async def purge(self, messages: list[beacon_message.BeaconMessage]):
859927 await self .__bot .loop .run_in_executor (None , lambda : self .messages .remove_message_group (message_group ))
860928
861929 async def pin (self , message : beacon_message .BeaconMessage , unpin : bool = False ):
862- """Pins a message sent to a Space."""
930+ """Pins or unpins a message sent to a Space."""
863931
864932 if not self .initialized :
865933 raise BeaconNotInit ()
866934
867935 if message .platform in self ._disabled_platforms :
868936 raise BeaconPlatformDisabled (message .platform )
869937
938+ # Ensure user is not banned
939+ if self .bans .is_banned (message .author ):
940+ raise BeaconIsBanned (message .author .id )
941+
942+ # Ensure server is not banned
943+ if self .bans .is_banned (message .server ):
944+ raise BeaconIsBanned (message .server .id )
945+
870946 # Get message group
871947 message_group : beacon_message .BeaconMessageGroup = self .messages .get_group_from_message (message .id )
872948 if not message_group :
@@ -901,5 +977,6 @@ async def pin(self, message: beacon_message.BeaconMessage, unpin: bool = False):
901977 await self ._strategy_async (tasks , return_exceptions = not self .debug )
902978
903979 async def unpin (self , message : beacon_message .BeaconMessage ):
904- """Unpins a message sent to a Space."""
980+ """Unpins a message sent to a Space.
981+ Shorthand for Beacon.pin(message, unpin=True)"""
905982 return await self .pin (message , unpin = True )
0 commit comments