@@ -62,7 +62,7 @@ def __init__(
62
62
self .log = logger # Logger of the child cog for a correct name in the logs
63
63
64
64
self ._consume_task = None
65
- self .watched_users = defaultdict ( dict )
65
+ self .watched_users = {}
66
66
self .message_queue = defaultdict (lambda : defaultdict (deque ))
67
67
self .consumption_queue = {}
68
68
self .retries = 5
@@ -154,7 +154,7 @@ async def fetch_user_cache(self) -> bool:
154
154
self .log .exception ("Failed to fetch the watched users from the API" , exc_info = err )
155
155
return False
156
156
157
- self .watched_users = defaultdict ( dict )
157
+ self .watched_users . clear ( )
158
158
159
159
for entry in data :
160
160
user_id = entry .pop ("user" )
@@ -185,13 +185,16 @@ async def consume_messages(self, delay_consumption: bool = True) -> None:
185
185
self .consumption_queue = self .message_queue .copy ()
186
186
self .message_queue .clear ()
187
187
188
- for user_channel_queues in self .consumption_queue .values ():
189
- for channel_queue in user_channel_queues .values ():
188
+ for user_id , channel_queues in self .consumption_queue .items ():
189
+ for channel_queue in channel_queues .values ():
190
190
while channel_queue :
191
191
msg = channel_queue .popleft ()
192
192
193
- self .log .trace (f"Consuming message { msg .id } ({ len (msg .attachments )} attachments)" )
194
- await self .relay_message (msg )
193
+ if watch_info := self .watched_users .get (user_id , None ):
194
+ self .log .trace (f"Consuming message { msg .id } ({ len (msg .attachments )} attachments)" )
195
+ await self .relay_message (msg , watch_info )
196
+ else :
197
+ self .log .trace (f"Not consuming message { msg .id } as user { user_id } is no longer watched." )
195
198
196
199
self .consumption_queue .clear ()
197
200
@@ -218,7 +221,7 @@ async def webhook_send(
218
221
exc_info = exc
219
222
)
220
223
221
- async def relay_message (self , msg : Message ) -> None :
224
+ async def relay_message (self , msg : Message , watch_info : dict ) -> None :
222
225
"""Relays the message to the relevant watch channel."""
223
226
limit = BigBrotherConfig .header_message_limit
224
227
@@ -229,7 +232,7 @@ async def relay_message(self, msg: Message) -> None:
229
232
):
230
233
self .message_history = MessageHistory (last_author = msg .author .id , last_channel = msg .channel .id )
231
234
232
- await self .send_header (msg )
235
+ await self .send_header (msg , watch_info )
233
236
234
237
if DiscordTokenFilter .find_token_in_message (msg .content ) or WEBHOOK_URL_RE .search (msg .content ):
235
238
cleaned_content = "Content is censored because it contains a bot or webhook token."
@@ -268,21 +271,19 @@ async def relay_message(self, msg: Message) -> None:
268
271
269
272
self .message_history .message_count += 1
270
273
271
- async def send_header (self , msg : Message ) -> None :
274
+ async def send_header (self , msg : Message , watch_info : dict ) -> None :
272
275
"""Sends a header embed with information about the relayed messages to the watch channel."""
273
276
if self .disable_header :
274
277
return
275
278
276
- user_id = msg .author .id
277
-
278
279
guild = self .bot .get_guild (GuildConfig .id )
279
- actor = await get_or_fetch_member (guild , self . watched_users [ user_id ] ["actor" ])
280
- actor = actor .display_name if actor else self . watched_users [ user_id ] ["actor" ]
280
+ actor = await get_or_fetch_member (guild , watch_info ["actor" ])
281
+ actor = actor .display_name if actor else watch_info ["actor" ]
281
282
282
- inserted_at = self . watched_users [ user_id ] ["inserted_at" ]
283
+ inserted_at = watch_info ["inserted_at" ]
283
284
time_delta = time .format_relative (inserted_at )
284
285
285
- reason = self . watched_users [ user_id ] ["reason" ]
286
+ reason = watch_info ["reason" ]
286
287
287
288
if isinstance (msg .channel , DMChannel ):
288
289
# If a watched user DMs the bot there won't be a channel name or jump URL
@@ -343,12 +344,13 @@ async def prepare_watched_users_data(
343
344
update_cache = False
344
345
list_data ["updated" ] = update_cache
345
346
346
- watched_iter = self .watched_users .items ()
347
+ # Copy into list to prevent issues if it is modified elsewhere while it's being iterated over.
348
+ watched_list = list (self .watched_users .items ())
347
349
if oldest_first :
348
- watched_iter = reversed ( watched_iter )
350
+ watched_list . reverse ( )
349
351
350
352
list_data ["info" ] = {}
351
- for user_id , user_data in watched_iter :
353
+ for user_id , user_data in watched_list :
352
354
member = await get_or_fetch_member (ctx .guild , user_id )
353
355
line = f"- `{ user_id } `"
354
356
if member :
@@ -366,8 +368,6 @@ async def prepare_watched_users_data(
366
368
def _remove_user (self , user_id : int ) -> None :
367
369
"""Removes a user from a watch channel."""
368
370
self .watched_users .pop (user_id , None )
369
- self .message_queue .pop (user_id , None )
370
- self .consumption_queue .pop (user_id , None )
371
371
372
372
async def cog_unload (self ) -> None :
373
373
"""Takes care of unloading the cog and canceling the consumption task."""
0 commit comments