add message previews for backups
This commit is contained in:
parent
ce11c85f49
commit
71bcd3c9bb
2 changed files with 62 additions and 14 deletions
|
|
@ -360,7 +360,16 @@ class DiscordExporter:
|
||||||
new_count += 1
|
new_count += 1
|
||||||
accumulated_count += 1
|
accumulated_count += 1
|
||||||
if progress_callback:
|
if progress_callback:
|
||||||
await progress_callback(channel_name, accumulated_count)
|
author = getattr(msg, "author", None)
|
||||||
|
author_name = getattr(author, "display_name", "Unknown") if author else "Unknown"
|
||||||
|
content = msg.content or ""
|
||||||
|
attachments_len = len(msg.attachments) if hasattr(msg, "attachments") else 0
|
||||||
|
preview = content[:150] + ("..." if len(content) > 150 else "")
|
||||||
|
if attachments_len:
|
||||||
|
preview += f" [dim]({attachments_len} attachments)[/dim]"
|
||||||
|
if not preview:
|
||||||
|
preview = "[dim](no content)[/dim]"
|
||||||
|
await progress_callback(channel_name, accumulated_count, author_name=author_name, message_preview=preview)
|
||||||
except discord.Forbidden:
|
except discord.Forbidden:
|
||||||
logger.error(f"403 Forbidden: Missing Access to read messages in {channel_name} ({channel_id})")
|
logger.error(f"403 Forbidden: Missing Access to read messages in {channel_name} ({channel_id})")
|
||||||
if not messages: return accumulated_count
|
if not messages: return accumulated_count
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ class BackupPane(Container):
|
||||||
with Vertical(id="bp_actions"):
|
with Vertical(id="bp_actions"):
|
||||||
yield Button("Backup Server Profile", id="bp_backup_profile", disabled=True)
|
yield Button("Backup Server Profile", id="bp_backup_profile", disabled=True)
|
||||||
yield Button("Backup Channel Messages", id="bp_backup_msgs", disabled=True, variant="primary")
|
yield Button("Backup Channel Messages", id="bp_backup_msgs", disabled=True, variant="primary")
|
||||||
yield Button("Update & Sync Backup", id="bp_backup_sync", disabled=True, variant="success")
|
yield Button("Update Existing Backup", id="bp_backup_sync", disabled=True, variant="success")
|
||||||
|
|
||||||
def on_mount(self) -> None:
|
def on_mount(self) -> None:
|
||||||
self._validate()
|
self._validate()
|
||||||
|
|
@ -228,8 +228,12 @@ class BackupPane(Container):
|
||||||
await asyncio.sleep(0.1)
|
await asyncio.sleep(0.1)
|
||||||
|
|
||||||
msg = "Sync existing backups" if not force_overwrite else "Overwriting existing backups"
|
msg = "Sync existing backups" if not force_overwrite else "Overwriting existing backups"
|
||||||
|
target_preview = ", ".join([c.name for c in selected_channels[:3]])
|
||||||
|
if len(selected_channels) > 3:
|
||||||
|
target_preview += "..."
|
||||||
|
|
||||||
modal_prog.set_status(f"Awaiting Confirmation to backup [bold]{len(selected_channels)}[/bold] channels...")
|
modal_prog.set_status(f"Awaiting Confirmation to backup [bold]{len(selected_channels)}[/bold] channels...")
|
||||||
modal_prog.show_info(f"[cyan]{msg}[/cyan]", f"Targets: {', '.join([c.name for c in selected_channels[:3]])}{'...' if len(selected_channels) > 3 else ''}")
|
modal_prog.show_info(f"[cyan]{msg}[/cyan]", f"Targets: {target_preview}")
|
||||||
|
|
||||||
choice = await modal_prog.phase_wait_confirm(btn_start_label="Start Channel Backup", show_id=False)
|
choice = await modal_prog.phase_wait_confirm(btn_start_label="Start Channel Backup", show_id=False)
|
||||||
if choice == "btn_back":
|
if choice == "btn_back":
|
||||||
|
|
@ -244,29 +248,45 @@ class BackupPane(Container):
|
||||||
break
|
break
|
||||||
|
|
||||||
modal_prog.phase_progress()
|
modal_prog.phase_progress()
|
||||||
|
modal_prog.show_stats()
|
||||||
|
|
||||||
total_chans = len(selected_channels)
|
total_chans = len(selected_channels)
|
||||||
modal_prog.set_status("Backing up messages...")
|
modal_prog.set_status("Backing up messages...")
|
||||||
modal_prog.write(f"[yellow]Starting backup for {total_chans} channels...[/yellow]")
|
modal_prog.write(f"[yellow]Starting backup for {total_chans} channels...[/yellow]")
|
||||||
|
|
||||||
for chan in selected_channels:
|
accumulated_msgs = 0
|
||||||
|
|
||||||
|
for i, chan in enumerate(selected_channels):
|
||||||
await asyncio.sleep(0.01) # Yield to UI thread to keep it responsive
|
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()
|
backup_exists = (self.exporter.export_path / "message_backup" / f"{chan.id}.json").exists()
|
||||||
is_sync = backup_exists and not force_overwrite
|
is_sync = backup_exists and not force_overwrite
|
||||||
|
|
||||||
label = "Syncing Backup" if is_sync else "Backing up"
|
label = "Syncing Backup" if is_sync else "Backing up"
|
||||||
|
modal_prog.set_item_status(f"[cyan]Processing ({i+1}/{total_chans}): #{chan.name}[/cyan]")
|
||||||
|
modal_prog.set_progress(i, total_chans)
|
||||||
modal_prog.write(f"[cyan]{label}: {chan.name}[/cyan]")
|
modal_prog.write(f"[cyan]{label}: {chan.name}[/cyan]")
|
||||||
logger.info(f"{label} for channel: #{chan.name} ({chan.id})")
|
logger.info(f"{label} for channel: #{chan.name} ({chan.id})")
|
||||||
|
|
||||||
async def update_msg_count(name, count):
|
async def update_msg_count(name, count, author_name=None, message_preview=None):
|
||||||
modal_prog.set_status(f"{name}: {count} messages")
|
modal_prog.update_stats(messages=str(count))
|
||||||
|
if author_name and message_preview:
|
||||||
|
modal_prog.write(f"[bold]{author_name}:[/bold] {message_preview}")
|
||||||
|
|
||||||
await self.exporter.export_channel_messages(chan.id, progress_callback=update_msg_count, force=force_overwrite)
|
accumulated_msgs = await self.exporter.export_channel_messages(
|
||||||
await self.exporter.export_threads(chan.id, progress_callback=update_msg_count, force=force_overwrite)
|
chan.id, progress_callback=update_msg_count, force=force_overwrite,
|
||||||
|
accumulated_count=accumulated_msgs
|
||||||
|
)
|
||||||
|
accumulated_msgs = await self.exporter.export_threads(
|
||||||
|
chan.id, progress_callback=update_msg_count, force=force_overwrite,
|
||||||
|
accumulated_count=accumulated_msgs
|
||||||
|
)
|
||||||
|
|
||||||
modal_prog.write(f"[green]Completed: {chan.name}[/green]")
|
modal_prog.write(f"[green]Completed: {chan.name}[/green]")
|
||||||
|
|
||||||
|
modal_prog.set_progress(total_chans, total_chans)
|
||||||
|
modal_prog.set_item_status("[bold green]Backup completed successfully![/bold green]")
|
||||||
|
|
||||||
await self.exporter.export_metadata()
|
await self.exporter.export_metadata()
|
||||||
modal_prog.write("[bold green]Message backup complete![/bold green]")
|
modal_prog.write("[bold green]Message backup complete![/bold green]")
|
||||||
logger.info("Message backup operation completed successfully.")
|
logger.info("Message backup operation completed successfully.")
|
||||||
|
|
@ -315,19 +335,38 @@ class BackupPane(Container):
|
||||||
if not selected_channels:
|
if not selected_channels:
|
||||||
modal_prog.write("[yellow]No existing backups found to sync.[/yellow]")
|
modal_prog.write("[yellow]No existing backups found to sync.[/yellow]")
|
||||||
else:
|
else:
|
||||||
modal_prog.write(f"[yellow]Syncing {len(selected_channels)} channels...[/yellow]")
|
total_chans = len(selected_channels)
|
||||||
for chan in selected_channels:
|
modal_prog.show_stats()
|
||||||
|
modal_prog.set_status("Syncing messages...")
|
||||||
|
modal_prog.write(f"[yellow]Syncing {total_chans} channels...[/yellow]")
|
||||||
|
|
||||||
|
accumulated_msgs = 0
|
||||||
|
|
||||||
|
for i, chan in enumerate(selected_channels):
|
||||||
await asyncio.sleep(0.01) # Yield to UI thread
|
await asyncio.sleep(0.01) # Yield to UI thread
|
||||||
|
|
||||||
|
modal_prog.set_item_status(f"[cyan]Syncing ({i+1}/{total_chans}): #{chan.name}[/cyan]")
|
||||||
|
modal_prog.set_progress(i, total_chans)
|
||||||
modal_prog.write(f"[cyan]Syncing: {chan.name}[/cyan]")
|
modal_prog.write(f"[cyan]Syncing: {chan.name}[/cyan]")
|
||||||
logger.info(f"Syncing backup for channel: #{chan.name} ({chan.id})")
|
logger.info(f"Syncing backup for channel: #{chan.name} ({chan.id})")
|
||||||
|
|
||||||
async def update_msg_count(name, count):
|
async def update_msg_count(name, count, author_name=None, message_preview=None):
|
||||||
modal_prog.set_status(f"{name}: {count} messages")
|
modal_prog.update_stats(messages=str(count))
|
||||||
|
if author_name and message_preview:
|
||||||
|
modal_prog.write(f"[bold]{author_name}:[/bold] {message_preview}")
|
||||||
|
|
||||||
await self.exporter.export_channel_messages(chan.id, progress_callback=update_msg_count, force=False)
|
accumulated_msgs = await self.exporter.export_channel_messages(
|
||||||
await self.exporter.export_threads(chan.id, progress_callback=update_msg_count, force=False)
|
chan.id, progress_callback=update_msg_count, force=False,
|
||||||
|
accumulated_count=accumulated_msgs
|
||||||
|
)
|
||||||
|
accumulated_msgs = await self.exporter.export_threads(
|
||||||
|
chan.id, progress_callback=update_msg_count, force=False,
|
||||||
|
accumulated_count=accumulated_msgs
|
||||||
|
)
|
||||||
modal_prog.write(f"[green]Synced: {chan.name}[/green]")
|
modal_prog.write(f"[green]Synced: {chan.name}[/green]")
|
||||||
|
|
||||||
|
modal_prog.set_progress(total_chans, total_chans)
|
||||||
|
modal_prog.set_item_status("[bold green]Sync operation complete![/bold green]")
|
||||||
|
|
||||||
await self.exporter.export_metadata()
|
await self.exporter.export_metadata()
|
||||||
modal_prog.write("[bold green]Sync operation complete![/bold green]")
|
modal_prog.write("[bold green]Sync operation complete![/bold green]")
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue