Commit Graph
9 Commits
Author SHA1 Message Date
lgooseandClaude Bot 3fb1e26fb4 refactor(web): routery tematyczne i wstrzykiwanie zależności
22 endpointy z jednego pliku rozdzielone na routery według obszaru:
status, playback, queue, voice, uploads, settings i websocket.

- Powtarzany w każdym endpoincie blok "pobierz cog, sprawdź czy istnieje,
  ustal aktywny serwer, w razie czego rzuć 400" zastąpiony zależnościami
  z dependencies.py. Zniknęło 22-krotne bot.get_cog("MusicBot").
- Zależności wędrują przez app.state zamiast importu globalnego obiektu
  bota, więc warstwa web nie ma już zależności cyklicznej z modułem bota.
- create_app składa aplikację i montuje routery.
- Wycofane @app.on_event("startup") zastąpione lifespanem, który dodatkowo
  sprząta po sobie: odpina hook i zatrzymuje pętlę rozgłaszania.

Kontrakt HTTP pozostaje bez zmian - te same ścieżki, metody, kody błędów
i kształt odpowiedzi.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 01:10:59 +02:00
lgooseandClaude Bot c2f6d265c1 refactor(web): rozgłaszanie stanu po WebSockecie
- ConnectionManager - rejestr aktywnych połączeń (bez zmian poza typami).
- StatusService - budowanie obrazu stanu bota. Endpoint get_status miał
  126 linii i składał odpowiedź w dwóch wariantach; teraz jest to zestaw
  metod budujących poszczególne fragmenty payloadu.
- StatusBroadcaster - rozgłaszanie na żądanie oraz pętla cykliczna, wraz
  z zatrzymywaniem zadania przy wyłączaniu aplikacji. Wcześniej zadanie
  było tworzone w on_event("startup") i nigdy nie anulowane.

Wariant odpowiedzi dla bota bez serwerów zwraca teraz komplet kluczy
(dochodzi queue_index: -1), więc panel dostaje zawsze ten sam kształt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 01:10:42 +02:00
lgooseandClaude Bot 6e61892c04 refactor(web): modele żądań w osobnych plikach
Jedenaście klas pydantic zadeklarowanych jednym blokiem na górze web.py
rozdzielone na pliki zgodnie z zasadą jedna klasa = jeden plik. Każdy
model dostaje docstring mówiący, do czego służy - z samych nazw pól
(np. channel_id akceptujące pusty string jako reset) nie wynikało to
w oczywisty sposób.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 01:10:42 +02:00
lgooseandClaude Bot b2651bb957 refactor(bot): klient Discorda i cienki cog komend
- ZyrarBot buduje intencje, rejestruje cog i synchronizuje drzewo komend.
- MusicCog zawiera już wyłącznie obsługę komend ukośnikowych: walidację
  argumentów, komunikaty dla użytkownika i wywołania MusicPlayer. Cała
  praca ze stanem zniknęła z tego pliku.
- GuildResolver ustala kontekst serwera dla panelu webowego, który nie ma
  interakcji Discorda - wcześniej robiła to funkcja get_active_guild
  w web.py, sięgająca po globalny obiekt bota.
- Powtarzana w czterech komendach odpowiedź "dodano do kolejki" albo
  "teraz odtwarzane" zebrana w jednym helperze.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 01:10:28 +02:00
lgooseandClaude Bot a143cb21d3 refactor(music): MusicPlayer jako jedyny właściciel stanu odtwarzania
Logika odtwarzania wyprowadzona z coga Discorda do osobnej klasy. Dotąd
kolejkę modyfikowały dwie niezależne ścieżki: metody MusicBot oraz
endpointy w web.py sięgające po music_cog.queues[guild_id] i ustawiające
music_cog.jump_flag wprost. Teraz obie warstwy wołają MusicPlayer.

Przeniesione bez zmiany zachowania: enqueue, play_next wraz z arytmetyką
indeksu i limitem odtworzeń, remove, reorder, jump, sterowanie głośnością
oraz hook on_state_change rozgłaszający stan po WebSockecie.

Wybór kolejnego indeksu wydzielony do _next_index, dzięki czemu reguły
trybów zapętlania i przeskoku dają się czytać bez śledzenia całej metody.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 01:10:28 +02:00
lgooseandClaude Bot 4cc00618d1 refactor(music): stan serwera, tryb zapętlania i budowanie powiadomień
- GuildMusicState zbiera stan jednego serwera w jedną strukturę. Dotąd
  było to dziewięć równoległych słowników indeksowanych guild_id
  (queues, currents, volumes, loop_currents, loop_playlists, last_channels,
  history, queue_indices, jump_flag), co wymagało pamiętania, że przy
  każdej zmianie trzeba ruszyć kilka z nich naraz.
- LoopMode zastępuje parę booleanów loop_current/loop_playlist, których
  kombinacja "oba włączone" nie miała sensu, a mimo to była osiągalna.
  Wartości enuma (off/playlist/single) odpowiadają kontraktowi API panelu.
- TrackEmbedFactory zbiera budowanie osadzeń Discorda, powielone dotąd
  w enqueue_track i play_next.
- NotificationChannelResolver opisuje kolejność szukania kanału logów:
  zapamiętany -> z konfiguracji -> pierwszy zapisywalny na serwerze.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 01:10:11 +02:00
lgooseandClaude Bot 53ffae1663 refactor(audio): wydzielenie warstwy pozyskiwania dźwięku
ytdl.py rozbity na cztery pliki o rozłącznych rolach:

- YtdlOptions   opcje yt-dlp i FFmpeg, wcześniej moduły-globalne
- MediaProbe    odczyt długości pliku przez ffprobe
- YTDLSource    samo źródło audio - dane utworu i zliczanie odtworzonego
                czasu; dochodzą właściwości is_local, filepath, display_url
                i has_web_link, które zastępują powtarzane w kilku miejscach
                data.get("webpage_url") or url
- TrackFactory  budowanie źródeł z zapytania, adresu lub pliku

Rozdzielenie źródła od sposobu jego tworzenia usuwa globalną instancję
YoutubeDL i pozwala podmienić fabrykę w testach. Metoda recreate zbiera
w jednym miejscu odtwarzanie utworu od nowa z zachowaniem jego tożsamości
i pozostałej liczby odtworzeń.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 01:10:11 +02:00
lgooseandClaude Bot e59b4ad9f1 refactor(storage): repozytoria konfiguracji, historii i plików
Dostęp do danych trwałych schodzi za trzy repozytoria, zamiast być
rozsmarowany po metodach coga i endpointach:

- GuildConfigRepository - kanały powiadomień per serwer i domyślna liczba
  odtworzeń.
- HistoryRepository - historia per serwer z buforem w pamięci i limitem
  wpisów. Zasada odsiewania duplikatów (zgodny tytuł albo adres) siedzi
  teraz w HistoryEntry.is_same_track_as zamiast w warunku wbudowanym
  w listę składaną.
- UploadsRepository - katalog uploadów. Każda nazwa przechodzi przez
  os.path.basename w jednym miejscu, co zamyka temat ścieżek względnych
  przychodzących z API.

Wpisy historii i pliki opisują struktury HistoryEntry oraz UploadFileInfo
zamiast luźnych słowników z kluczami sprawdzanymi przez .get().

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 01:09:52 +02:00
lgooseandClaude Bot e194a8611c refactor(config): Settings i JsonFileStore jako podstawa pakietu
Początek pakietu zyrarbot, budowanego wedle zasady jedna klasa = jeden plik.

- Settings zbiera konfigurację ze zmiennych środowiskowych oraz ścieżki
  i limity, które dotąd były literałami rozsianymi po bot.py i web.py
  ("config/config.json", "uploads", zakres 1-999, domyślne 5 odtworzeń).
- JsonFileStore zastępuje sześć niemal identycznych bloków open/json.load
  z ręcznym try/except. Brakujący lub uszkodzony plik daje pusty słownik
  zamiast wyjątku, a zapis sam tworzy katalog.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 01:09:52 +02:00