diff --git a/README.md b/README.md new file mode 100644 index 0000000..79c294e --- /dev/null +++ b/README.md @@ -0,0 +1,77 @@ +# ŻyrarBOT + +Bot muzyczny Discord z panelem webowym: kolejka odtwarzania, historia, serwerowa +baza plików i sterowanie na żywo przez WebSocket. + +## Uruchomienie + +```bash +pip install -r requirements.txt +python main.py # albo: python -m zyrarbot +``` + +Wymagane zmienne środowiskowe (plik `.env`): + +| Zmienna | Opis | +| --------------- | ----------------------------------------------------------- | +| `DISCORD_TOKEN` | Token bota Discord. | +| `GUILD_ID` | Opcjonalnie - synchronizuje komendy tylko z jednym serwerem. | + +Panel działa pod `http://localhost:8000`. W Dockerze: `docker compose up --build`. + +## Testy + +```bash +python -m unittest discover -s tests -t . +``` + +## Struktura pakietu + +Każda klasa mieszka w osobnym pliku, a pliki są pogrupowane w przestrzenie nazw +odpowiadające warstwom aplikacji: + +``` +zyrarbot/ +├── settings.py Settings - konfiguracja ze zmiennych środowiskowych +├── application.py Application - korzeń kompozycji, spina bota i serwer web +├── storage/ Warstwa trwałości (pliki JSON, katalog uploadów) +│ ├── json_file_store.py JsonFileStore +│ ├── guild_config_repository.py GuildConfigRepository +│ ├── history_repository.py HistoryRepository +│ ├── uploads_repository.py UploadsRepository +│ └── upload_file_info.py UploadFileInfo +├── audio/ Pozyskiwanie dźwięku +│ ├── ytdl_options.py YtdlOptions +│ ├── ytdl_source.py YTDLSource +│ ├── media_probe.py MediaProbe +│ └── track_factory.py TrackFactory +├── music/ Domena odtwarzania +│ ├── loop_mode.py LoopMode +│ ├── history_entry.py HistoryEntry +│ ├── guild_music_state.py GuildMusicState +│ ├── track_embed_factory.py TrackEmbedFactory +│ ├── notification_channel_resolver.py NotificationChannelResolver +│ └── music_player.py MusicPlayer +├── bot/ Warstwa Discorda +│ ├── client.py ZyrarBot +│ ├── guild_resolver.py GuildResolver +│ └── cogs/music_cog.py MusicCog +└── web/ Panel webowy (FastAPI) + ├── factory.py create_app + ├── connection_manager.py ConnectionManager + ├── status_service.py StatusService + ├── status_broadcaster.py StatusBroadcaster + ├── dependencies.py wstrzykiwanie zależności z app.state + ├── schemas/ modele żądań - jeden na plik + └── routers/ trasy pogrupowane tematycznie +``` + +### Zasady + +- **`MusicPlayer` jest jedynym właścicielem stanu odtwarzania.** Zarówno komendy + Discorda, jak i endpointy panelu operują wyłącznie przez niego - nie ma już + dwóch niezależnych ścieżek modyfikujących kolejkę. +- **Kolejka jest nieusuwalna, pozycję śledzi indeks** (`GuildMusicState.index`), + dzięki czemu działa przeskakiwanie i przewijanie w tył. +- **Zależności wędrują przez konstruktory**, a w warstwie web przez `app.state` + i funkcje z `web/dependencies.py`. Nie ma globalnych singletonów.