slack-exporter/tui.py
2025-04-30 12:26:35 +02:00

119 lines
3.4 KiB
Python

import sys
from textual import work
from textual.app import App, ComposeResult
from textual.containers import Container
from textual.screen import Screen
from textual.widgets import Header, Button, ListView, ListItem, Footer, Label
from exporter_ng import SlackExporter, SlackConfig
class SlackExporterScreen(Screen):
"""Ekran główny eksportera Slack"""
def __init__(self, exporter: SlackExporter, *args, **kwargs):
super().__init__(*args, **kwargs)
self.exporter = exporter
self.selected_channels = set()
def compose(self) -> ComposeResult:
"""Komponuje widgety na ekranie"""
yield Header(show_clock=True)
yield Container(
ListView(*[
ListItem(Label(ch.short_label, id=ch.id))
for ch in self.exporter.channels
], id="channel-list"),
Button("Eksportuj zaznaczone", variant="primary", id="export-btn"),
id="main-container"
)
yield Footer()
def on_list_view_selected(self, event: ListView.Selected) -> None:
"""Obsługuje zaznaczenie elementu listy"""
item = event.item
item_id = item.children[0].id
if item_id in self.selected_channels:
self.selected_channels.remove(item_id)
item.remove_class("selected")
else:
self.selected_channels.add(item_id)
item.add_class("selected")
@work(exclusive=True)
async def export_channels(self):
"""Eksportuje zaznaczone kanały"""
if not self.selected_channels:
self.notify("Nie wybrano żadnych kanałów")
return
# self.notify("Rozpoczynam eksport...")
# self.exporter.export_channels(list(self.selected_channels))
# # for channel_id in self.selected_channels:
# # self.notify(f"Eksportuję kanał {channel_id}...")
# # self.exporter.export_channel_history(channel_id)
# self.notify("Eksport zakończony")
self.app.exit(return_code=8080)
async def on_button_pressed(self, event: Button.Pressed) -> None:
"""Obsługuje kliknięcie przycisku"""
if event.button.id == "export-btn":
self.export_channels()
class SlackTUI(App):
"""Główna klasa interfejsu użytkownika"""
CSS = """
#main-container {
layout: vertical;
height: 100%;
padding: 1;
}
ListView {
height: 1fr;
border: solid green;
}
.selected {
background: $accent;
color: $text;
}
Button {
margin: 1;
width: 100%;
}
"""
def __init__(self, exporter: SlackExporter):
super().__init__()
self.exporter = exporter
self._screen = SlackExporterScreen(self.exporter)
def on_mount(self) -> None:
"""Wywoływane przy montowaniu aplikacji"""
self.push_screen(self._screen)
def get_selection(self):
return self._screen.selected_channels
def get_return_code(self):
return self._return_code
def run_tui(exporter: SlackExporter):
"""Uruchamia interfejs użytkownika"""
app = SlackTUI(exporter)
app.run()
if app.get_return_code() == 8080:
exporter.export_channels(app.get_selection())
if __name__ == "__main__":
try:
config = SlackConfig.from_env()
exporter = SlackExporter(config)
run_tui(exporter)
except Exception as e:
print(f"Błąd: {e}")
sys.exit(1)