8
8
import snakecore
9
9
from typing import TypedDict , Collection
10
10
from collections import OrderedDict
11
+ import logging
11
12
12
13
from ..base import BaseExtensionCog
13
14
14
15
# Define the type for the bot, supporting both Bot and AutoShardedBot from snakecore
15
16
BotT = snakecore .commands .Bot | snakecore .commands .AutoShardedBot
16
17
18
+ logger = logging .getLogger (__name__ )
17
19
18
20
fetched_attachments : dict [int , bytes ] = {}
19
21
20
22
21
23
async def fetch_attachment (attachment : discord .Attachment , cache : bool = True ) -> bytes :
22
24
if cache and attachment .id in fetched_attachments :
25
+ logger .debug (f"Fetched attachment from cache: { attachment .id } " )
23
26
return fetched_attachments [attachment .id ]
24
- return await attachment .read ()
27
+ data = await attachment .read ()
28
+ if cache :
29
+ fetched_attachments [attachment .id ] = data
30
+ logger .debug (f"Fetched attachment from source: { attachment .id } " )
31
+ return data
25
32
26
33
27
34
async def crosspost_cmp (message : discord .Message , other : discord .Message ) -> bool :
@@ -43,22 +50,20 @@ async def crosspost_cmp(message: discord.Message, other: discord.Message) -> boo
43
50
have_content = message .content and other .content
44
51
have_attachments = message .attachments and other .attachments
45
52
53
+ logger .debug (
54
+ f"Comparing messages { message .jump_url } and { other .jump_url } from { message .author .name } "
55
+ )
56
+
46
57
if have_content :
47
58
hamming_score = sum (
48
59
x != y for x , y in zip (message .content , other .content )
49
60
) / max (len (message .content ), len (other .content ))
50
61
similarity_score = min (max (0 , 1 - hamming_score ), 1 )
62
+ logger .debug (f"Computed similarity score for content: { similarity_score } " )
51
63
else :
52
64
similarity_score = 0
53
65
54
66
if have_attachments :
55
- # Check if the attachments are the same:
56
- # - Sort the attachments by filename and size
57
- # - Compare the sorted lists of attachments
58
- # - if filename and size are the same,
59
- # additionally check if the content is the same
60
- # (only if under 8mb)
61
-
62
67
try :
63
68
matching_attachments = all (
64
69
[
@@ -74,7 +79,9 @@ async def crosspost_cmp(message: discord.Message, other: discord.Message) -> boo
74
79
)
75
80
]
76
81
)
77
- except discord .HTTPException :
82
+ logger .debug (f"Attachment comparison result: { matching_attachments } " )
83
+ except discord .HTTPException as e :
84
+ logger .debug (f"HTTPException during attachment comparison: { e } " )
78
85
matching_attachments = False
79
86
else :
80
87
matching_attachments = False
@@ -155,6 +162,8 @@ async def on_message(self, message: discord.Message):
155
162
):
156
163
return
157
164
165
+ logger .debug (f"Received message from { message .author .name } : { message .jump_url } " )
166
+
158
167
# Attempt to enforce the cache size limit
159
168
for user_id in list (self .crossposting_cache .keys ()):
160
169
if len (self .crossposting_cache ) <= self .max_tracked_users :
@@ -163,15 +172,18 @@ async def on_message(self, message: discord.Message):
163
172
user_cache = self .crossposting_cache [user_id ]
164
173
if not any (len (group ) > 1 for group in user_cache ["message_groups" ]):
165
174
self .crossposting_cache .pop (user_id )
175
+ logger .debug (f"Removed user { user_id } from cache to enforce size limit" )
166
176
167
177
# Initialize cache for new users
168
178
if message .author .id not in self .crossposting_cache :
169
179
self .crossposting_cache [message .author .id ] = UserCrosspostCache (
170
180
message_groups = [[message ]],
171
181
message_to_alert = {},
172
182
)
183
+ logger .debug (f"Initialized cache for new user { message .author .name } " )
173
184
else :
174
185
user_cache = self .crossposting_cache [message .author .id ]
186
+ logger .debug (f"Checking for crossposts for user { message .author .name } " )
175
187
176
188
# Check for crossposts or duplicates in existing message groups
177
189
for messages in user_cache ["message_groups" ]:
@@ -183,8 +195,10 @@ async def on_message(self, message: discord.Message):
183
195
<= self .crosspost_timedelta_threshold
184
196
):
185
197
messages .append (message )
198
+ logger .debug (
199
+ f"Found crosspost for user { message .author .name } , message URL { message .jump_url } !!!!!!!!!!"
200
+ )
186
201
187
- # Send an alert message and add its ID to the alert list
188
202
try :
189
203
alert_message = await message .reply (
190
204
"This message is a recent crosspost/duplicate among the following messages: "
@@ -194,15 +208,18 @@ async def on_message(self, message: discord.Message):
194
208
user_cache ["message_to_alert" ][
195
209
message .id
196
210
] = alert_message .id
197
- except discord . HTTPException :
198
- # Silently handle errors
199
- pass
211
+ logger . debug ( f"Sent alert message for crosspost URL { message . jump_url } " )
212
+ except discord . HTTPException as e :
213
+ logger . debug ( f"Failed to send alert message: { e } " )
200
214
break
201
215
else :
202
216
continue
203
217
break
204
218
else :
205
219
user_cache ["message_groups" ].append ([message ])
220
+ logger .debug (
221
+ f"Added message to new group for user { message .author .name } "
222
+ )
206
223
207
224
# Remove oldest message groups if limit is exceeded and the group is too small
208
225
if (
@@ -214,6 +231,9 @@ async def on_message(self, message: discord.Message):
214
231
):
215
232
if len (messages ) < 2 :
216
233
user_cache ["message_groups" ].pop (i )
234
+ logger .debug (
235
+ f"Removed oldest message group for user { message .author .name } "
236
+ )
217
237
break
218
238
219
239
@commands .Cog .listener ()
@@ -241,6 +261,9 @@ async def on_message_delete(self, message: discord.Message):
241
261
stale_alert_message_ids .append (
242
262
user_cache ["message_to_alert" ].pop (message .id )
243
263
)
264
+ logger .debug (
265
+ f"Removed message { message .jump_url } from user { message .author .name } 's cache due to deletion"
266
+ )
244
267
break
245
268
246
269
# Mark last alert message for this crosspost group as stale if the group
@@ -256,9 +279,11 @@ async def on_message_delete(self, message: discord.Message):
256
279
await discord .PartialMessage (
257
280
channel = message .channel , id = alert_message_id
258
281
).delete ()
259
- except (discord .NotFound , discord .Forbidden ):
260
- # Silently handle errors
261
- pass
282
+ logger .debug (f"Deleted stale alert message ID { alert_message_id } " )
283
+ except (discord .NotFound , discord .Forbidden ) as e :
284
+ logger .debug (
285
+ f"Failed to delete alert message ID { alert_message_id } : { e } "
286
+ )
262
287
263
288
def _is_valid_channel (self , channel : discord .abc .GuildChannel ) -> bool :
264
289
"""
0 commit comments