- TypeScript 79.9%
- JavaScript 9.1%
- PowerShell 3.4%
- HTML 2.9%
- CSS 2.8%
- Other 1.9%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| .forgejo/workflows | ||
| docs | ||
| install | ||
| scripts | ||
| src | ||
| tests | ||
| .gitattributes | ||
| .gitignore | ||
| package-lock.json | ||
| package.json | ||
| playwright.config.ts | ||
| README.md | ||
| tsconfig.json | ||
| vitest.config.ts | ||
ariku.pl // radio — rozszerzenie Chromium
Rozszerzenie dodaje muzykę z YouTube (opcjonalnie ze Spotify) do wspólnej kolejki
ariku.pl (Music Hub, ariku.pl/music). Gra ją Orin na Discordzie. Rozszerzenie nie odtwarza
dźwięku i nie ma własnych playlist. Źródłem prawdy jest ariku.pl.
Główny scenariusz: oglądasz utwór na YouTube, klikasz „+ Dodaj do radia” pod filmem albo w popupie, a utwór trafia do kolejki na ariku.pl. Jeśli jest w bibliotece, od razu wchodzi do kolejki. Jeśli nie, serwer go pobiera i dodaje po indeksacji.
Działa w Chrome, Chromium, Brave i Edge (Manifest V3, Chrome 116+) oraz w Firefoksie 140+
(osobna paczka .xpi, ten sam kod).
1. Instalacja lokalna
Najprościej skryptem install/install.ps1 (Windows) albo install/install.sh (Linux, macOS).
Pobiera najnowsze wydanie z git.ariku.pl, sprawdza SHA256 i kładzie rozszerzenie w stałym
folderze. Ponowne uruchomienie aktualizuje. Wydania, skrypty i dystrybucja:
docs/PUBLIKACJA.md.
Ręcznie:
- Rozpakuj
release/ariku-radio-<wersja>.zipdo katalogu albo zbudujdist/(punkt 2). - Otwórz
chrome://extensions(Edge:edge://extensions, Brave:brave://extensions). - Włącz Tryb dewelopera.
- Kliknij Załaduj rozpakowane i wskaż katalog z
manifest.json(rozpakowany ZIP albodist/). - Przypnij ikonę rozszerzenia. Karty YouTube otwarte przed instalacją odśwież, żeby pojawił się przycisk na stronie.
Firefox
Paczka: release/ariku-radio-firefox-<wersja>.xpi (albo katalog dist-firefox/). Nie jest
podpisana przez Mozillę, więc:
- Firefox (wydanie zwykłe):
about:debugging#/runtime/this-firefox→ Załaduj tymczasowy dodatek… → wskaż plik.xpi. Dodatek działa do zamknięcia Firefoksa. - Na stałe (Firefox ESR, Developer Edition, Nightly): w
about:configustawxpinstall.signatures.requirednafalse, potemabout:addons→ koło zębate → Zainstaluj dodatek z pliku… → plik.xpi. - Jeśli popup pokaże „Zezwól na dostęp”, kliknij i zaakceptuj. Firefox pozwala nie przyznać albo odebrać dostęp do ariku.pl, YouTube i Spotify.
Podpis do zwykłego Firefoksa wymaga wysłania paczki na AMO (np. jako niepubliczna, „unlisted”).
npm run lint:firefox uruchamia ten sam walidator, którego używa AMO.
2. Kompilacja
Wymagany Node.js 20+.
npm install
npm run build # dist/ (Chromium) i dist-firefox/
npm run package # + release/ariku-radio-<wersja>.zip i ariku-radio-firefox-<wersja>.xpi
npm run lint:firefox # walidator Mozilli (addons-linter) dla dist-firefox/
npm run typecheck
npm test # testy jednostkowe i integracyjne (vitest)
npm run test:e2e # E2E w Chromium (Playwright) i Firefoksie (Selenium), patrz niżej
npm run check # typecheck + test + package + lint:firefox
CI (.forgejo/workflows/ci.yml, runner Forgejo) przy każdym pushu i PR odpala gitleaks,
typy, testy i build z ZIP-em. Nie używa sekretów.
E2E (tests/e2e/extension.spec.ts) ładuje dist/ do Chromium z Playwright. Domeny youtube.com
i ariku.pl są przekierowane na lokalny serwer HTTPS z atrapami. Test wymaga npm run build,
npx playwright install chromium, wolnego portu 443 na 127.0.0.1 i openssl w PATH.
tests/e2e/firefox.spec.ts instaluje .xpi w Firefoksie przez Selenium i geckodrivera
(ścieżki: FIREFOX_BIN, GECKODRIVER, domyślnie .tools/). Bez nich test jest pomijany.
3. Konfiguracja domeny
Rozszerzenie rozmawia wyłącznie z https://ariku.pl. Domenę ustawiasz w dwóch miejscach:
src/shared/config.ts:ARIKU_ORIGIN;- manifest (
src/manifest.ts) bierze z niejhost_permissionsiconnect-srcw CSP. Testtests/manifest.test.tspilnuje, żeby obie wartości się zgadzały.
Uprawnienia: storage, activeTab i host https://ariku.pl/*. Content scripty działają tylko
na www.youtube.com, youtube.com, m.youtube.com, youtu.be i open.spotify.com.
Rozszerzenie nie ma dostępu do wszystkich kart, historii, schowka ani ciasteczek przez API.
Nie używa też externally_connectable.
4. Logowanie
Rozszerzenie nie ma własnych kont. Są dwa tryby (popup → ustawienia):
- Sesja Discord (domyślny, zalecany). Przycisk „Połącz z ariku.pl” otwiera istniejące
logowanie
ariku.pl/api/auth/discord?next=/music. Po zalogowaniu przeglądarka sama dołącza ciasteczko sesji ariku.pl do żądań rozszerzenia. Rozszerzenie go nie czyta, nie kopiuje i nie zapisuje. Jeśli przed logowaniem przerwałeś dodawanie utworu, po ponownym otwarciu popupu pojawi się „Dokończyć po zalogowaniu…?”. Utwór doda się dopiero po Twoim kliknięciu. - Token urządzenia. Na
ariku.pl/lunetautwórz urządzenie i wklej tokenlnt_…. Rozszerzenie użyje wtedy/api/luneta/music/*z nagłówkiemAuthorization: Bearer. Przydaje się, gdy przeglądarka blokuje ciasteczka. Token leży lokalnie wchrome.storage.locali nie wraca w całości do interfejsu. Zajmuje 1 z 3 slotów urządzeń Lunety.
Wygasła sesja albo unieważniony token wraca jako komunikat z przyciskiem ponownego połączenia.
5. Backend: wymagane zmienne środowiskowe
Rozszerzenie nie wymaga żadnej zmiennej po swojej stronie i nie ma .env. Korzysta
z istniejącego API afterlife, które potrzebuje (już skonfigurowane na produkcji):
| Funkcja | Zmienne (afterlife .env) |
|---|---|
| logowanie Discord | DISCORD_CLIENT_ID, DISCORD_CLIENT_SECRET, DISCORD_GUILD_ID, opcjonalnie DISCORD_REDIRECT_URI |
| kolejka / odtwarzacz | Redis (REDIS_URL) |
| biblioteka | NAVIDROME_URL, NAVIDROME_USER, NAVIDROME_PASSWORD (bez nich API zwraca 503 → „muzyka nieskonfigurowana”) |
| pobieranie z YouTube | MUSIC_DOWNLOAD_HOST, MUSIC_DOWNLOAD_SSH_USER, MUSIC_DOWNLOAD_SSH_KEY_PATH, MUSIC_DOWNLOAD_SSH_KNOWN_HOSTS_PATH (bez nich 503 dla /youtube i play {videoId}) |
| tryb tokenu | Lemuria/Postgres Lunety |
Dokładne nazwy są w .env.example repo afterlife. Endpointy, z których korzysta rozszerzenie
(potwierdzone w kodzie, lib/musicApi.ts):
GET /api/auth/discord/statusGET /api/music/queue|jobs|control|search?q=|youtube?q=(albo/api/luneta/music/…)POST /api/music/play { videoId | query },POST /api/music/queue { trackId, title, artist, durationSec }
Czego API dziś nie ma (idempotencja, Spotify po stronie serwera, playlisty, „następny
w kolejce”): docs/ZLECENIE-API-AFTERLIFE.md.
6. Spotify (opcjonalnie)
Rozszerzenie działa bez żadnej konfiguracji Spotify. Na open.spotify.com popup pokazuje:
- utwór: „Dopasuj na YouTube i dodaj”. Rozszerzenie szuka przez wyszukiwarkę ariku.pl i ocenia wyniki (tytuł, wykonawca, długość, inna wersja typu live/remix/cover). Pewne dopasowanie dodaje od razu, niepewne pokazuje do wyboru;
- album / playlistę: „Importuj N pozycji”. Wyświetla postęp dopasowania, potem listę z zaznaczonymi pewnymi pozycjami (niepewne trzeba zaznaczyć ręcznie). Na koniec dodaje wybrane pozycje. Import trwa w tle, a popup można zamknąć.
Pozycje są czytane z tego, co Spotify pokazuje na stronie (tytuł karty, meta tagi, lista utworów). Rozszerzenie nie używa Web API Spotify, nie pobiera audio i nie obchodzi limitów. Długą playlistę przewiń do końca przed importem. Pełne listy przez oficjalne API wymagają endpointu po stronie ariku.pl (zlecenie, pkt 2). Limit serwera to 20 pobrań z YouTube na godzinę, a utwory z biblioteki się nie liczą. Import zatrzymuje się po jego osiągnięciu.
7. Diagnozowanie
| Objaw | Przyczyna / co zrobić |
|---|---|
| „niepołączono” | brak sesji: „Połącz z ariku.pl” i zaloguj się Discordem (członek serwera) |
| „brak połączenia” | ariku.pl nieosiągalne albo przekroczony limit czasu: sprawdź sieć/VPN |
| „muzyka nieskonfigurowana na ariku.pl” | API zwraca 503: brak Navidrome/Redis/workera po stronie serwera |
| „Limit pobierania na godzinę…” | 429 z serwera (20 utworów, 3 playlisty na godzinę na osobę) |
| „Ten utwór był już dodany przed chwilą” | ochrona przed duplikatem (10 min); „Dodaj mimo to” wymusza |
| „Poprzednia próba nie dostała odpowiedzi…” | timeout zapisu, więc wynik nieznany: sprawdź kolejkę, potem „Dodaj mimo to” |
| brak przycisku pod filmem | odśwież kartę; sprawdź ustawienie „przycisk na YouTube”; nowy układ YouTube = przycisk się nie pokaże, popup działa dalej |
| „Rozszerzenie zostało zaktualizowane — odśwież kartę” | stary content script po aktualizacji/przeładowaniu rozszerzenia |
| ciągle „niepołączono” mimo logowania | przeglądarka blokuje ciasteczka ariku.pl dla rozszerzeń: użyj trybu tokenu |
Logi: chrome://extensions → „ariku.pl // radio” → service worker (konsola). Rozszerzenie
nie loguje tokenów ani ciasteczek.
Architektura
src/
manifest.ts manifest (MV3) jako kod, generowany do dist/manifest.json
shared/ config, protokół komunikatów (wersjonowany), parsery YouTube/Spotify, dopasowanie
adapter/ariku.ts jedyne miejsce, które zna API ariku.pl (oba tryby auth, timeouty, mapowanie błędów)
background/ service worker: router komunikatów, weryfikacja nadawcy, ochrona duplikatów, import
content/youtube*.ts wykrywanie filmu (także SPA), przycisk w shadow DOM, odpowiedź dla popupu
content/spotify*.ts odczyt strony Spotify dla popupu
popup/ interfejs (bez frameworka)
scripts/ build (esbuild), ikony PNG generowane w kodzie, ZIP bez zewnętrznych narzędzi
tests/ vitest (+ jsdom), tests/e2e: Playwright w Chromium