prepare for backup_reader refactor

This commit is contained in:
rambros 2026-03-04 13:13:38 +05:30
parent a2e6f3f828
commit 3a6a138c89
6 changed files with 66 additions and 2656 deletions

View file

View file

@ -10,6 +10,14 @@ class DiscordReader:
MESSAGE_TYPE_REPLY = discord.MessageType.reply MESSAGE_TYPE_REPLY = discord.MessageType.reply
MESSAGE_TYPE_THREAD_STARTER = discord.MessageType.thread_starter_message MESSAGE_TYPE_THREAD_STARTER = discord.MessageType.thread_starter_message
# Exceptions
Forbidden = discord.Forbidden
# Channel Types
CHANNEL_TYPE_TEXT = discord.ChannelType.text
CHANNEL_TYPE_NEWS = discord.ChannelType.news
CHANNEL_TYPE_FORUM = discord.ChannelType.forum
@staticmethod @staticmethod
def find_item(iterable, **attrs): def find_item(iterable, **attrs):
"""Find first item in iterable matching all attrs. Drop-in for discord.utils.get().""" """Find first item in iterable matching all attrs. Drop-in for discord.utils.get()."""

View file

@ -4,7 +4,6 @@ Embedded inside ModeScreen's "Backup" tab.
""" """
import asyncio import asyncio
import discord
import json import json
import re import re
from pathlib import Path from pathlib import Path
@ -147,7 +146,7 @@ class BackupPane(Container):
modal.write(f"- {e_count} emojis, {s_count} stickers.") modal.write(f"- {e_count} emojis, {s_count} stickers.")
modal.phase_report("Profile Backup") modal.phase_report("Profile Backup")
except discord.Forbidden as e: except self.engine.discord_reader.Forbidden as e:
modal.write(f"[bold red]Backup failed: {e}[/bold red]") modal.write(f"[bold red]Backup failed: {e}[/bold red]")
modal.phase_report("Profile Backup", "error") modal.phase_report("Profile Backup", "error")
except Exception as e: except Exception as e:
@ -174,7 +173,11 @@ class BackupPane(Container):
eligible_channels = [ eligible_channels = [
c for c in all_channels c for c in all_channels
if c.type in [discord.ChannelType.text, discord.ChannelType.news, discord.ChannelType.forum] if c.type in [
self.engine.discord_reader.CHANNEL_TYPE_TEXT,
self.engine.discord_reader.CHANNEL_TYPE_NEWS,
self.engine.discord_reader.CHANNEL_TYPE_FORUM
]
] ]
if not eligible_channels: if not eligible_channels:
@ -284,7 +287,11 @@ class BackupPane(Container):
all_channels = await self.engine.discord_reader.get_channels() all_channels = await self.engine.discord_reader.get_channels()
eligible_channels = [ eligible_channels = [
c for c in all_channels c for c in all_channels
if c.type in [discord.ChannelType.text, discord.ChannelType.news, discord.ChannelType.forum] if c.type in [
self.engine.discord_reader.CHANNEL_TYPE_TEXT,
self.engine.discord_reader.CHANNEL_TYPE_NEWS,
self.engine.discord_reader.CHANNEL_TYPE_FORUM
]
] ]
selected_channels = [ selected_channels = [

File diff suppressed because it is too large Load diff

View file

@ -4,7 +4,6 @@ Embedded inside ModeScreen's "Migrate" tab.
""" """
import asyncio import asyncio
import discord
import logging import logging
import re import re
import time import time
@ -13,7 +12,7 @@ import traceback
from pathlib import Path from pathlib import Path
from textual.app import ComposeResult from textual.app import ComposeResult
from textual.containers import Container, Vertical, VerticalScroll from textual.containers import Container, Vertical, Horizontal, VerticalScroll
from textual.widgets import Button, Label, Rule from textual.widgets import Button, Label, Rule
from textual import work from textual import work
@ -86,6 +85,11 @@ class ShuttlePane(Container):
ShuttlePane #sp_info { ShuttlePane #sp_info {
height: auto; border: tall cyan; padding: 1; margin-bottom: 1; height: auto; border: tall cyan; padding: 1; margin-bottom: 1;
} }
#sp_info_split { height: auto; layout: horizontal; }
.info_pane { width: 1fr; height: auto; }
.info_pane Label { width: 100%; }
.pane_header { text-style: bold; color: $accent; margin-bottom: 1; }
ShuttlePane #sp_actions { height: auto; } ShuttlePane #sp_actions { height: auto; }
ShuttlePane #sp_actions Button { width: 100%; margin-bottom: 1; } ShuttlePane #sp_actions Button { width: 100%; margin-bottom: 1; }
""" """
@ -104,8 +108,18 @@ class ShuttlePane(Container):
def compose(self) -> ComposeResult: def compose(self) -> ComposeResult:
with VerticalScroll(): with VerticalScroll():
with Vertical(id="sp_info"): with Vertical(id="sp_info"):
yield Label("Discord: [yellow]Loading...[/yellow]", id="sp_lbl_discord") with Horizontal(id="sp_info_split"):
yield Label("Target: [yellow]Loading...[/yellow]", id="sp_lbl_target") with Vertical(classes="info_pane"):
yield Label("Discord", classes="pane_header")
yield Label("Server: [yellow]Loading...[/yellow]", id="sp_lbl_d_server")
yield Label("Bot: [yellow]Loading...[/yellow]", id="sp_lbl_d_bot")
with Vertical(classes="info_pane"):
yield Label("Target", id="sp_lbl_t_header", classes="pane_header")
yield Label("Community: [yellow]Loading...[/yellow]", id="sp_lbl_t_comm")
yield Label("Bot: [yellow]Loading...[/yellow]", id="sp_lbl_t_bot")
yield Rule()
yield Label("Status: [yellow]Validating...[/yellow]", id="sp_lbl_status") yield Label("Status: [yellow]Validating...[/yellow]", id="sp_lbl_status")
with Vertical(id="sp_actions"): with Vertical(id="sp_actions"):
yield Button("Clone Server Template", id="sp_clone", disabled=True) yield Button("Clone Server Template", id="sp_clone", disabled=True)
@ -138,28 +152,39 @@ class ShuttlePane(Container):
# Discord # Discord
d_name = v.get("discord_server_name") d_name = v.get("discord_server_name")
d_bot = v.get("discord_bot_name") d_bot = v.get("discord_bot_name")
if v.get("discord_timeout"): if v.get("discord_timeout"):
d_disp = "[red]TIMEOUT[/red]" s_disp, b_disp = "[red]TIMEOUT[/red]", "[red]TIMEOUT[/red]"
elif d_name and v.get("discord_token") and v.get("discord_server"): elif v.get("discord_token") and v.get("discord_server"):
d_disp = f'[green]"{d_name}"[/green] Bot: [green]{d_bot}[/green]' s_disp = f'[green]"{d_name}"[/green]'
b_disp = f'[green]{d_bot}[/green]'
elif v.get("discord_token") is False: elif v.get("discord_token") is False:
d_disp = "[red]INVALID TOKEN[/red]" s_disp, b_disp = "[red]INVALID TOKEN[/red]", "[red]INVALID TOKEN[/red]"
else: else:
d_disp = "[red]NOT SET UP[/red]" s_disp, b_disp = "[red]NOT SET UP[/red]", "[red]NOT SET UP[/red]"
self.query_one("#sp_lbl_discord", Label).update(f"Discord: {d_disp}")
self.query_one("#sp_lbl_d_server", Label).update(f"Server: {s_disp}")
self.query_one("#sp_lbl_d_bot", Label).update(f"Bot: {b_disp}")
# Target # Target
plat = "Fluxer" if self.target_platform == "fluxer" else "Stoat" plat = "Fluxer" if self.target_platform == "fluxer" else "Stoat"
t_name = v.get("target_community_name") t_name = v.get("target_community_name")
t_bot = v.get("target_bot_name")
self.query_one("#sp_lbl_t_header", Label).update(plat)
if v.get("target_timeout"): if v.get("target_timeout"):
t_disp = "[red]TIMEOUT[/red]" c_disp, tb_disp = "[red]TIMEOUT[/red]", "[red]TIMEOUT[/red]"
elif t_name and v.get("target_token") and v.get("target_community"): elif v.get("target_token") and v.get("target_community"):
t_disp = f'[green]"{t_name}"[/green]' c_disp = f'[green]"{t_name}"[/green]'
tb_disp = f'[green]{t_bot}[/green]'
elif v.get("target_token") is False: elif v.get("target_token") is False:
t_disp = "[red]INVALID TOKEN[/red]" c_disp, tb_disp = "[red]INVALID TOKEN[/red]", "[red]INVALID TOKEN[/red]"
else: else:
t_disp = "[red]NOT SET UP[/red]" c_disp, tb_disp = "[red]NOT SET UP[/red]", "[red]NOT SET UP[/red]"
self.query_one("#sp_lbl_target", Label).update(f"{plat}: {t_disp}")
self.query_one("#sp_lbl_t_comm", Label).update(f"Community: {c_disp}")
self.query_one("#sp_lbl_t_bot", Label).update(f"Bot: {tb_disp}")
# Status # Status
if not self.tokens_valid: if not self.tokens_valid:
@ -299,11 +324,11 @@ class ShuttlePane(Container):
def _open_sync_menu(self): def _open_sync_menu(self):
options = [ options = [
("sub_emoji", "Sync Emojis"), ("sub_emoji", "Custom Emojis"),
("sub_sticker", "Sync Stickers"), ("sub_sticker", "Custom Stickers"),
("sub_name", "Sync Server Name"), ("sub_name", "Server Name"),
("sub_icon", "Sync Server Icon"), ("sub_icon", "Server Icon"),
("sub_banner", "Sync Server Banner"), ("sub_banner", "Server Banner"),
] ]
def on_result(choices): def on_result(choices):
if choices: if choices:
@ -664,7 +689,7 @@ class ShuttlePane(Container):
await self.engine.start_connections() await self.engine.start_connections()
full_d = await self.engine.discord_reader.get_channels() full_d = await self.engine.discord_reader.get_channels()
d_channels = [c for c in full_d if c.type in [discord.ChannelType.text, discord.ChannelType.news]] d_channels = [c for c in full_d if c.type in [self.engine.discord_reader.CHANNEL_TYPE_TEXT, self.engine.discord_reader.CHANNEL_TYPE_NEWS]]
d_cats = await self.engine.discord_reader.get_categories() d_cats = await self.engine.discord_reader.get_categories()
d_cat_map = {c.id: c.name for c in d_cats} d_cat_map = {c.id: c.name for c in d_cats}

File diff suppressed because it is too large Load diff