Skip to content

Commit 0cb5150

Browse files
committed
Remove base64 snooze/unsnooze logic, fix notification crash, clean up replay logic
1 parent 19c0668 commit 0cb5150

File tree

1 file changed

+62
-48
lines changed

1 file changed

+62
-48
lines changed

core/thread.py

Lines changed: 62 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -319,96 +319,109 @@ async def restore_from_snooze(self):
319319
f"[UNSNOOZE] Tried to restore thread {self.id} but snooze_data is None or not a dict."
320320
)
321321
return False
322-
# Now safe to access self.snooze_data
322+
323+
# Cache some fields we need later (before we potentially clear snooze_data)
323324
snoozed_by = self.snooze_data.get("snoozed_by")
324325
snooze_command = self.snooze_data.get("snooze_command")
326+
325327
guild = self.bot.modmail_guild
326328
behavior = (self.bot.config.get("snooze_behavior") or "delete").lower()
329+
327330
# Determine original category; fall back to main_category_id if original missing
328331
orig_category = (
329-
guild.get_channel(self.snooze_data["category_id"])
332+
guild.get_channel(self.snooze_data.get("category_id"))
330333
if self.snooze_data.get("category_id")
331334
else None
332335
)
333336
if not isinstance(orig_category, discord.CategoryChannel):
334337
main_cat_id = self.bot.config.get("main_category_id")
335338
orig_category = guild.get_channel(int(main_cat_id)) if main_cat_id else None
336339

340+
# Default: assume we'll need to recreate
341+
channel: typing.Optional[discord.TextChannel] = None
342+
343+
# If move-behavior and channel still exists, move it back and restore overwrites
337344
if behavior == "move" and isinstance(self.channel, discord.TextChannel):
338-
# Channel exists but is snoozed in another category; move back
339345
try:
340346
await self.channel.edit(
341347
category=orig_category,
342348
position=self.snooze_data.get("position", self.channel.position),
343349
reason="Thread unsnoozed/restored",
344350
)
345-
# After moving back, restore original overwrites captured at snooze time
351+
# Restore original overwrites captured at snooze time
346352
try:
347-
overwrites = {}
353+
ow_map: dict = {}
348354
for role_id, perm_values in self.snooze_data.get("overwrites", []):
349355
target = guild.get_role(role_id) or guild.get_member(role_id)
350-
if target:
351-
overwrites[target] = discord.PermissionOverwrite(**perm_values)
352-
if overwrites:
353-
await self.channel.edit(overwrites=overwrites, reason="Restore original overwrites")
356+
if target is None:
357+
continue
358+
ow_map[target] = discord.PermissionOverwrite(**perm_values)
359+
if ow_map:
360+
await self.channel.edit(overwrites=ow_map, reason="Restore original overwrites")
354361
except Exception as e:
355362
logger.warning("Failed to restore original overwrites on unsnooze: %s", e)
356363

357364
channel = self.channel
358365
except Exception as e:
359366
logger.warning("Failed to move snoozed channel back, recreating: %s", e)
360367
channel = None
361-
else:
362-
channel = None
363368

369+
# If we couldn't move back (or behavior=delete), recreate the channel
364370
if channel is None:
365-
# Recreate channel and replay messages (delete behavior or move fallback)
366-
overwrites = {}
367-
for role_id, perm_values in self.snooze_data["overwrites"]:
368-
role = guild.get_role(role_id) or guild.get_member(role_id)
369-
if role:
370-
overwrites[role] = discord.PermissionOverwrite(**perm_values)
371-
channel = await guild.create_text_channel(
372-
name=self.snooze_data["name"],
373-
category=orig_category,
374-
topic=self.snooze_data["topic"],
375-
slowmode_delay=self.snooze_data["slowmode_delay"],
376-
overwrites=overwrites,
377-
nsfw=self.snooze_data["nsfw"],
378-
position=self.snooze_data["position"],
379-
reason="Thread unsnoozed/restored",
380-
)
381-
self._channel = channel
382-
else:
383-
self._channel = channel
371+
try:
372+
ow_map: dict = {}
373+
for role_id, perm_values in self.snooze_data.get("overwrites", []):
374+
target = guild.get_role(role_id) or guild.get_member(role_id)
375+
if target is None:
376+
continue
377+
ow_map[target] = discord.PermissionOverwrite(**perm_values)
378+
379+
channel = await guild.create_text_channel(
380+
name=self.snooze_data.get("name") or f"thread-{self.id}",
381+
category=orig_category,
382+
overwrites=ow_map or None,
383+
position=self.snooze_data.get("position"),
384+
topic=self.snooze_data.get("topic"),
385+
slowmode_delay=self.snooze_data.get("slowmode_delay") or 0,
386+
nsfw=bool(self.snooze_data.get("nsfw")),
387+
reason="Thread unsnoozed/restored (recreated)",
388+
)
389+
self._channel = channel
390+
except Exception:
391+
logger.error("Failed to recreate thread channel during unsnooze.", exc_info=True)
392+
return False
384393
# Strictly restore the log_key from snooze_data (never create a new one)
385394
self.log_key = self.snooze_data.get("log_key")
395+
386396
# Replay messages only if we re-created the channel (delete behavior or move fallback)
387397
if behavior != "move" or (behavior == "move" and not self.snooze_data.get("moved", False)):
388-
for msg in self.snooze_data["messages"]:
398+
for msg in self.snooze_data.get("messages", []):
389399
try:
390400
author = self.bot.get_user(msg["author_id"]) or await self.bot.get_or_fetch_user(
391401
msg["author_id"]
392402
)
393403
except discord.NotFound:
394404
author = None
395-
content = msg["content"]
405+
406+
content = msg.get("content")
396407
embeds = [discord.Embed.from_dict(e) for e in msg.get("embeds", []) if e]
397408
attachments = msg.get("attachments", [])
398-
msg_type = msg.get("type")
399-
# Only send if there is content, embeds, or attachments
409+
410+
# Only send if there is something to send
400411
if not content and not embeds and not attachments:
401-
continue # Skip empty messages
412+
continue
413+
402414
author_is_mod = msg["author_id"] not in [r.id for r in self.recipients]
403415
if author_is_mod:
404-
# Prioritize stored author_name from snooze data over fetched user
416+
# Prefer stored author_name/avatar
405417
username = (
406418
msg.get("author_name")
407419
or (getattr(author, "name", None) if author else None)
408420
or "Unknown"
409421
)
410422
user_id = msg.get("author_id")
411423
if embeds:
424+
# Ensure embeds show author details
412425
embeds[0].set_author(
413426
name=f"{username} ({user_id})",
414427
icon_url=msg.get("author_avatar")
@@ -418,21 +431,22 @@ async def restore_from_snooze(self):
418431
else None
419432
),
420433
)
421-
await channel.send(
422-
embeds=embeds, allowed_mentions=discord.AllowedMentions.none()
423-
)
434+
await channel.send(embeds=embeds, allowed_mentions=discord.AllowedMentions.none())
424435
else:
425-
formatted = (
426-
f"**{username} ({user_id})**: {content}"
427-
if content
428-
else f"**{username} ({user_id})**"
429-
)
430-
await channel.send(
431-
formatted, allowed_mentions=discord.AllowedMentions.none()
432-
)
436+
# Build a non-empty message; include attachment URLs if no content
437+
header = f"**{username} ({user_id})**"
438+
if content:
439+
formatted = f"{header}: {content}"
440+
elif attachments:
441+
formatted = header + "\n" + "\n".join(attachments)
442+
else:
443+
formatted = header
444+
await channel.send(formatted, allowed_mentions=discord.AllowedMentions.none())
433445
else:
446+
# Recipient message: include attachment URLs if content is empty
447+
content_to_send = content if content else ("\n".join(attachments) if attachments else None)
434448
await channel.send(
435-
content=content or None,
449+
content=content_to_send,
436450
embeds=embeds or None,
437451
allowed_mentions=discord.AllowedMentions.none(),
438452
)

0 commit comments

Comments
 (0)