fix fluxer file attachments

This commit is contained in:
rambros 2026-02-27 00:19:15 +05:30
parent f477321c2f
commit 8a96017155
4 changed files with 42 additions and 23 deletions

View file

@ -1,4 +1,5 @@
import asyncio import asyncio
import discord
import logging import logging
import re import re
from typing import Callable, Awaitable, Dict, Any from typing import Callable, Awaitable, Dict, Any
@ -74,6 +75,16 @@ async def migrate_messages(context: MigrationContext, source_channel_id: int, ta
if not context.is_running: if not context.is_running:
break break
# Skip system messages like "pinned a message", etc.
# We treat thread_starter_message (type 21) as our thread marker.
if msg.type == discord.MessageType.thread_starter_message:
content = f"> <<< THREAD: **{msg.channel.name}** >>>"
elif msg.type not in [discord.MessageType.default, discord.MessageType.reply]:
continue
else:
# Get clean content
content = msg.clean_content
# Process attachments # Process attachments
files = [] files = []
attachments_to_process = list(msg.attachments) attachments_to_process = list(msg.attachments)
@ -85,13 +96,13 @@ async def migrate_messages(context: MigrationContext, source_channel_id: int, ta
is_forwarded = msg.flags.forwarded is_forwarded = msg.flags.forwarded
# If forwarded, the content and attachments might be in message_snapshots (discord.py 2.5+) # If forwarded, the content and attachments might be in message_snapshots (discord.py 2.5+)
content = msg.clean_content # Note: If content was set by thread_starter_message, we don't overwrite it.
if is_forwarded: if is_forwarded:
logger.debug(f"Detected forwarded message: ID={msg.id}, Flags={msg.flags.value}") logger.debug(f"Detected forwarded message: ID={msg.id}, Flags={msg.flags.value}")
if hasattr(msg, 'message_snapshots') and msg.message_snapshots: if hasattr(msg, 'message_snapshots') and msg.message_snapshots:
# For now we handle the first snapshot # For now we handle the first snapshot
snapshot = msg.message_snapshots[0] snapshot = msg.message_snapshots[0]
if not content: if not content: # Only update content if it wasn't already set (e.g., by thread_starter_message)
content = snapshot.content content = snapshot.content
if hasattr(msg, 'guild') and msg.guild: if hasattr(msg, 'guild') and msg.guild:
content = clean_mentions(content, msg.guild) content = clean_mentions(content, msg.guild)
@ -132,13 +143,6 @@ async def migrate_messages(context: MigrationContext, source_channel_id: int, ta
thread = msg.thread thread = msg.thread
logger.info(f"Detected thread '{thread.name}' on message {msg.id}") logger.info(f"Detected thread '{thread.name}' on message {msg.id}")
# Send Start Marker
stats["threads"] += 1
await context.fluxer_writer.send_marker(
channel_id=target_channel_id,
content=f"> <<< THREAD: **{thread.name}** >>>"
)
# Migrate thread messages # Migrate thread messages
# We don't pass a progress callback here to avoid confusing the UI # We don't pass a progress callback here to avoid confusing the UI
# but we do want to track count if possible. # but we do want to track count if possible.

View file

@ -1,7 +1,8 @@
import asyncio import asyncio
import io
import logging import logging
from typing import Optional, List, Dict, Any from typing import Optional, List, Dict, Any
from fluxer import Bot, Webhook, Forbidden from fluxer import Bot, Webhook, Forbidden, File
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -245,6 +246,11 @@ class FluxerWriter:
final_content = prefix + display_content if display_content else prefix final_content = prefix + display_content if display_content else prefix
# Convert files to fluxer.File objects
fluxer_files = None
if files:
fluxer_files = [File(io.BytesIO(f["data"]), filename=f["filename"]) for f in files]
try: try:
# Current limitation: fluxer.py execute_webhook doesn't support 'message_reference' yet. # Current limitation: fluxer.py execute_webhook doesn't support 'message_reference' yet.
# So if we have a reply, we MUST use the bot's direct send method. # So if we have a reply, we MUST use the bot's direct send method.
@ -253,7 +259,7 @@ class FluxerWriter:
content=final_content, content=final_content,
username=f"{author_name} (discord)", username=f"{author_name} (discord)",
avatar_url=author_avatar_url, avatar_url=author_avatar_url,
files=files, files=fluxer_files,
wait=True wait=True
) )
return str(msg.id) if msg else None return str(msg.id) if msg else None
@ -274,7 +280,7 @@ class FluxerWriter:
msg_data = await self.client.send_message( msg_data = await self.client.send_message(
channel_id=channel_id, channel_id=channel_id,
content=final_bot_content, content=final_bot_content,
files=files, files=fluxer_files,
message_reference=message_reference message_reference=message_reference
) )
return str(msg_data["id"]) if msg_data else None return str(msg_data["id"]) if msg_data else None
@ -290,11 +296,16 @@ class FluxerWriter:
Sends a simple marker message (e.g., thread start/end) using the bot directly. Sends a simple marker message (e.g., thread start/end) using the bot directly.
""" """
assert self.client is not None assert self.client is not None
fluxer_files = None
if files:
fluxer_files = [File(io.BytesIO(f["data"]), filename=f["filename"]) for f in files]
try: try:
msg_data = await self.client.send_message( msg_data = await self.client.send_message(
channel_id=channel_id, channel_id=channel_id,
content=content, content=content,
files=files files=fluxer_files
) )
return str(msg_data["id"]) if msg_data else None return str(msg_data["id"]) if msg_data else None
except Exception as e: except Exception as e:

View file

@ -1,4 +1,5 @@
import asyncio import asyncio
import discord
import logging import logging
import re import re
from typing import Callable, Awaitable, Dict, Any from typing import Callable, Awaitable, Dict, Any
@ -73,6 +74,17 @@ async def migrate_messages(context: MigrationContext, source_channel_id: int, ta
if not context.is_running: if not context.is_running:
break break
# Skip system messages like "pinned a message", etc.
# We treat thread_starter_message (type 21) as our thread marker.
content = "" # Initialize content
if msg.type == discord.MessageType.thread_starter_message:
content = f"> <<< THREAD: **{msg.channel.name}** >>>"
elif msg.type not in [discord.MessageType.default, discord.MessageType.reply]:
continue
else:
# Get clean content
content = msg.clean_content
# Process attachments # Process attachments
files = [] files = []
attachments_to_process = list(msg.attachments) attachments_to_process = list(msg.attachments)
@ -82,8 +94,6 @@ async def migrate_messages(context: MigrationContext, source_channel_id: int, ta
if hasattr(msg.flags, 'forwarded'): if hasattr(msg.flags, 'forwarded'):
is_forwarded = msg.flags.forwarded is_forwarded = msg.flags.forwarded
# Get clean content
content = msg.clean_content
if is_forwarded: if is_forwarded:
logger.debug(f"Detected forwarded message: ID={msg.id}, Flags={msg.flags.value}") logger.debug(f"Detected forwarded message: ID={msg.id}, Flags={msg.flags.value}")
if hasattr(msg, 'message_snapshots') and msg.message_snapshots: if hasattr(msg, 'message_snapshots') and msg.message_snapshots:
@ -128,13 +138,6 @@ async def migrate_messages(context: MigrationContext, source_channel_id: int, ta
thread = msg.thread thread = msg.thread
logger.info(f"Detected thread '{thread.name}' on message {msg.id}") logger.info(f"Detected thread '{thread.name}' on message {msg.id}")
# Send Start Marker
stats["threads"] += 1
await context.stoat_writer.send_marker(
channel_id=target_channel_id,
content=f"> <<< THREAD: **{thread.name}** >>>"
)
# Migrate thread messages recursively # Migrate thread messages recursively
thread_stats = await migrate_messages( thread_stats = await migrate_messages(
context=context, context=context,

View file

@ -1076,7 +1076,8 @@ class MigrationCLI:
# 2. Select Target Channel # 2. Select Target Channel
with console.status(f"[yellow]Fetching {platform_name} channels...[/yellow]"): with console.status(f"[yellow]Fetching {platform_name} channels...[/yellow]"):
f_channels = await self.engine.writer.get_channels() full_f_channels = await self.engine.writer.get_channels()
f_channels = [c for c in full_f_channels if c.get('name') not in ["reaper_logs", "reaper-logs"]]
if not f_channels: if not f_channels:
console.print(f"[yellow]No channels found in {platform_name} community.[/yellow]") console.print(f"[yellow]No channels found in {platform_name} community.[/yellow]")
return return