fix message backup screen
This commit is contained in:
parent
3a6a138c89
commit
ce11c85f49
2 changed files with 25 additions and 1 deletions
|
|
@ -354,6 +354,7 @@ class DiscordExporter:
|
|||
# 1. Fetch new messages - Handle Forbidden gracefully
|
||||
try:
|
||||
async for msg in self.reader.fetch_message_history(channel_id, after_id=last_id):
|
||||
await asyncio.sleep(0) # Yield control
|
||||
msg_data = await self._format_message(msg, asset_dir, base_filename, avatar_dir, avatar_rel_base)
|
||||
messages.append(msg_data)
|
||||
new_count += 1
|
||||
|
|
@ -393,6 +394,7 @@ class DiscordExporter:
|
|||
|
||||
thread_count = len(all_threads)
|
||||
for t in all_threads:
|
||||
await asyncio.sleep(0) # Yield for safety
|
||||
thread_msg_count += (t.message_count or 0)
|
||||
|
||||
msg_type = "Text"
|
||||
|
|
@ -428,6 +430,7 @@ class DiscordExporter:
|
|||
output_data[k] = v
|
||||
|
||||
# Save channel messages
|
||||
await asyncio.sleep(0) # Yield before writing large JSON
|
||||
with open(json_file, "w", encoding="utf-8") as f:
|
||||
json.dump(output_data, f, indent=4, ensure_ascii=False)
|
||||
|
||||
|
|
@ -646,6 +649,8 @@ class DiscordExporter:
|
|||
logger.info(f"Found {len(all_threads)} threads in {channel.name}. Starting backup...")
|
||||
|
||||
for thread in all_threads:
|
||||
await asyncio.sleep(0) # important yield between threads
|
||||
|
||||
# First backup the full thread — this creates {thread_id}.json with totalAttachmentSizeBytes
|
||||
accumulated_count = await self.export_channel_messages(thread.id, progress_callback=progress_callback, force=force, accumulated_count=accumulated_count)
|
||||
thread_count += 1
|
||||
|
|
@ -726,6 +731,7 @@ class DiscordExporter:
|
|||
# Keep chronological order
|
||||
forum_data["messages"].sort(key=lambda x: x["timestamp"])
|
||||
|
||||
await asyncio.sleep(0) # Yield before writing
|
||||
with open(forum_json_file, "w", encoding="utf-8") as f:
|
||||
json.dump(forum_data, f, indent=4, ensure_ascii=False)
|
||||
logger.info(f"Appended starter message for {thread.name} to {forum_json_file.name}")
|
||||
|
|
|
|||
|
|
@ -6,9 +6,13 @@ Embedded inside ModeScreen's "Backup" tab.
|
|||
import asyncio
|
||||
import json
|
||||
import re
|
||||
import logging
|
||||
import traceback
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
from textual.app import ComposeResult
|
||||
from textual.containers import Container, Vertical, VerticalScroll
|
||||
from textual.widgets import Button, Label, Rule
|
||||
|
|
@ -139,11 +143,14 @@ class BackupPane(Container):
|
|||
modal.write("Exporting structure...")
|
||||
_, cat_count, chan_count = await self.exporter.export_channels_structure()
|
||||
|
||||
modal.write("Exporting roles...")
|
||||
roles = await self.exporter.export_roles()
|
||||
|
||||
modal.write("Exporting assets...")
|
||||
e_count, s_count = await self.exporter.export_assets()
|
||||
|
||||
modal.write(f"[bold green]Server Profile backed up to: {self.exporter.export_path}[/bold green]")
|
||||
modal.write(f"- {e_count} emojis, {s_count} stickers.")
|
||||
modal.write(f"- {len(roles)} roles, {e_count} emojis, {s_count} stickers.")
|
||||
modal.phase_report("Profile Backup")
|
||||
|
||||
except self.engine.discord_reader.Forbidden as e:
|
||||
|
|
@ -216,6 +223,7 @@ class BackupPane(Container):
|
|||
selected_channels = [c for c in eligible_channels if c.id in selected_ids]
|
||||
|
||||
# Phase 2: Confirmation
|
||||
modal_prog = ProgressScreen() # Re-instantiate to avoid Textual re-push UI freeze
|
||||
self.app.push_screen(modal_prog)
|
||||
await asyncio.sleep(0.1)
|
||||
|
||||
|
|
@ -242,11 +250,14 @@ class BackupPane(Container):
|
|||
modal_prog.write(f"[yellow]Starting backup for {total_chans} channels...[/yellow]")
|
||||
|
||||
for chan in selected_channels:
|
||||
await asyncio.sleep(0.01) # Yield to UI thread to keep it responsive
|
||||
|
||||
backup_exists = (self.exporter.export_path / "message_backup" / f"{chan.id}.json").exists()
|
||||
is_sync = backup_exists and not force_overwrite
|
||||
|
||||
label = "Syncing Backup" if is_sync else "Backing up"
|
||||
modal_prog.write(f"[cyan]{label}: {chan.name}[/cyan]")
|
||||
logger.info(f"{label} for channel: #{chan.name} ({chan.id})")
|
||||
|
||||
async def update_msg_count(name, count):
|
||||
modal_prog.set_status(f"{name}: {count} messages")
|
||||
|
|
@ -258,9 +269,11 @@ class BackupPane(Container):
|
|||
|
||||
await self.exporter.export_metadata()
|
||||
modal_prog.write("[bold green]Message backup complete![/bold green]")
|
||||
logger.info("Message backup operation completed successfully.")
|
||||
modal_prog.phase_report("Message Backup")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Message backup failed: {e}\n{traceback.format_exc()}")
|
||||
modal_prog.write(f"[bold red]Message backup failed: {e}[/bold red]")
|
||||
modal_prog.phase_report("Message Backup", "error")
|
||||
finally:
|
||||
|
|
@ -304,7 +317,10 @@ class BackupPane(Container):
|
|||
else:
|
||||
modal_prog.write(f"[yellow]Syncing {len(selected_channels)} channels...[/yellow]")
|
||||
for chan in selected_channels:
|
||||
await asyncio.sleep(0.01) # Yield to UI thread
|
||||
|
||||
modal_prog.write(f"[cyan]Syncing: {chan.name}[/cyan]")
|
||||
logger.info(f"Syncing backup for channel: #{chan.name} ({chan.id})")
|
||||
|
||||
async def update_msg_count(name, count):
|
||||
modal_prog.set_status(f"{name}: {count} messages")
|
||||
|
|
@ -315,9 +331,11 @@ class BackupPane(Container):
|
|||
|
||||
await self.exporter.export_metadata()
|
||||
modal_prog.write("[bold green]Sync operation complete![/bold green]")
|
||||
logger.info("Sync operation completed successfully.")
|
||||
modal_prog.phase_report("Backup Sync")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Sync failed: {e}\n{traceback.format_exc()}")
|
||||
modal_prog.write(f"[bold red]Sync failed: {e}[/bold red]")
|
||||
modal_prog.phase_report("Backup Sync", "error")
|
||||
finally:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue