# Ligi centralne PZBS - koordynacja Zestaw skryptów do obsługi lig centralnych PZBS. Podzielony na kilka modułów, każdy z nich wywoływany jako osobny *target* polecenia `make`. Moduły czytają część konfiguracji ze zmiennych środowiskowych. Przykładowy zestaw zmiennych używanych w projekcie znajduje się w pliku `.envrc.sample`. W repozytorium są podmoduły, pamiętaj o `git submodule update --init --recursive` po wyciągnięciu tego kodu. ## Kopie zapasowe stron z wynikami Moduł tworzy w katalogu `http` kopie zapasowe plików wyników, ściagane z serwera. W założeniu - ma to robić bez interakcji z użytkownikiem. Opcjonalnie, dostarcza również skryptu, który równie bezobsługowo wersjonuje zmiany w repozytorium Git. ### Wymagania wstępne * dostęp do serwera wyników po SSH * rsync * opcjonalnie: git ### Wywołanie Kopia zapasowa: `make pull` Kopia zapasowa z wersjonowaniem zmian: `make autocommit` ### Konfiguracja Zmienne środowiskowe: * `LIGA_REMOTE_WWW_DIR`: kopletna zdalna ścieżka do backupu (`user@serwer:/ścieżka`) * `LIGA_SSH_OPTS`: dodatkowe parametry wywołania programu `ssh` (np. wczytujące klucz prywatny do uwierzytelnienia), przekazywane do poleceń `git push` oraz `rsync` W przypadku wersjonowania kopii zapasowych, w katalogu wyjściowym `http` musi być zainicjowane repozytorium Git ze skonfigurowanym zdalnym repozytorium docelowym. ## Kopie zapasowe baz danych turniejów Moduł wczytuje do lokalnie skonfigurowanej bazy danych, zrzuty baz turniejów, dostarczane przez sędziów w kotłach. Wprowadza do zrzutów często potrzebne poprawki (jak np. uzupełnienie tabeli `logoh`), a także umożliwia zdefiniowanie własnych poleceń, wykonywanych na każdej z baz danych po jej wgraniu ze zrzutu. ### Wymagania wstępne * s3cmd * klient MySQL * opcjonalnie: dbxcli Zrzuty baz danych muszą zostać niezależnie pozyskane od sędziów poszczególnych kotłów i wrzucone do jednego wiaderka S3, np. używając [Spedytora](https://github.com/emkael/spedytor/). Opcjonalnie, sędziowie mogą wrzucać zrzuty na Dropboksa, lub na FTP, do swojego katalogu wyników (pamiętaj o wyłączeniu publicznego dostępu do takich plików!). ### Wywołanie `make dumps` ### Konfiguracja Zmienne środowiskowe: * `LIGA_MYSQL_CONNECTION_OPTS`: komplet przełączników polecenia `mysql` pozwalający podłączyć się do docelowego (lokalnego) serwera MySQL * `LIGA_S3_BUCKET`: URI wiaderka S3, w którym trzymane są zrzuty - uwaga, obiekty z podkatalogów są ignorowane * `LIGA_DROPBOX_DUMP_FOLDER`: (opcjonalnie) ścieżka w ramach konta Dropbox, z której kopiowane będą zrzuty * `LIGA_LOCAL_DUMP_PATTERN`: (opcjonalnie) wzorzec ścieżki lokalnych plików SQL do dodania do katalogu zrzutów * `LIGA_LOCAL_DUMP_PATH`: (opcjonalnie) ścieżka, w której należy szukać ww. W przypadku określenia `LIGA_LOCAL_DUMP_PATTERN`, katalog `LIGA_LOCAL_DUMP_PATH` (albo bieżący katalog) przeszukiwane są pod kątem plików pasujących do wzorca. Następnie z każdego katalogu **najnowszy ze znalezionych plików** kopiowany jest do katalogu zrzutów baz danych. Z nazwy tego pliku usuwane jest wszystko od pierwszego myślnika - żeby obsłużyć format plikóé Spedytora. Pliki konfiguracyjne: * `dumps/.s3config`: konfiguracja klienta `s3cmd`, można wygenerować ją poleceniem `s3cmd --configure -c dumps/.s3config` * `dumps/.mapping`: mapowanie nazw plików zrzutów na docelowe bazy danych, do których zrzuty są wgrywane, każdy wiersz to jeden turniej, w każdym wierszu najpierw pojawia się nazwa bazy danych, a następnie, po odstępie, nazwa pliku relatywna względem `./dumps/` (domyślnie zrzuty trafiają do katalogu `./dumps/sync/`) * `dumps/.queries`: spis poleceń SQL wykonywanych na każdej bazie danych po wgraniu jej do lokalnego serwera, po jednym poleceniu na wiersz * w przypadku korzystania z Dropboksa, `dbxcli` musi zostać skonfigurowane niezależnie ## Kopie zapasowe lokalnych baz danych Moduł zrzuca do określonej ścieżki w S3 lokalne (z punktu widzenia koordynatora) bazy danych, może służyć np. do wykonywania kopii zapasowych baz butlerów ogólnopolskich. ### Wymagania wstępne * s3cmd * klient MySQL z mysqldump ### Wywołanie `make backups` ### Konfiguracja Zmienne środowiskowe: * `LIGA_MYSQL_CONNECTION_OPTS`: komplet przełączników polecenia `mysql` pozwalający podłączyć się do źródłowego (lokalnego) serwera MySQL * `LIGA_S3_BACKUP_BUCKET`: URI wiaderka S3, w którym trzymane będą zrzuty Pliki konfiguracyjne: * `dumps/.backup`: spis baz danych do zrzucenia z lokalnego serwera, po jednej bazie na wiersz ## Sprawdzenia przedsezonowe Moduł kontroli typowych błędów przy zakładaniu turniejów. Sprawdza: * daty rozpoczęcia rund * logohy * kolorki * tabele VP * język strony z wynikami * nazwy teamów i składy z Cezarem ### Wymagania wstępne * python, w wersji 3 * `requirements.txt` z katalogu modułu (`preseason`), w tym co najmniej requests i beautifulsoup z parserem lxml ### Wywołanie `python3 checks.py PLIK_KONFIGURACJI SPRAWDZENIE SPRAWDZENIE SPRAWDZENIE...` `PLIK_KONFIGURACJI` to ścieżka do pliku JSON z konfiguracją dla danej grupy (patrz niżej), a kolejne argumenty to nazwy poszczególnych sprawdzeń do wykonania: `dates`, `logoh`, `vp_table`, `page_language`, `team_names`, `kolorki`. `make preseason` Przelatuje po wszystkich plikach `.json` z katalogu `preseason/config/` i wykonuje na każdym wszyskie sprawdzenia. ### Konfiguracja Format pliku JSON: ``` { "source": { "path": "ŚCIEŻKA_DO_WYNIKÓW", "prefix": "PREFIKS_TURNIEJU" }, "language": "TŁUMACZENIE_FRAZY_MIEJSCE", "vp_table": "PLIK_Z_TABELĄ_VP", "logoh": { "custom_file": "NAZWA_PLIKU_LOGOHA", "template": "PLIK_SZABLONU", "variables": { ZMIENNE_DO_PODMIANY } }, "round_dates": [ DATY_RUND ], "team_names": "ID_TEAMÓW_Z_CEZARA", "kolorki": "PLIK_KOLORKÓW" } ``` Sekcja `source` definiuje stronę z wynikami, którą sprawdzamy: `path` to ścieżka (bez nazwy pliku) do katalogu dostępnego po HTTP(S), a `prefix` to prefiks turnieju. Język strony sprawdzany jest na podstawie tego, jak brzmi fraza `"miejsce"` na stronie tabeli z wynikami (`PREFIXleaderb.html`). Tabela VPów pobierana jest z pliku w katalogu `config`, zawierającym wiersze formatu `IMPY - VP : VP`. Logoh turnieju porównywany jest do zawartości pliku szablonu w katalogu `config`. W szablonie podmieniane są zmienne, oznaczone w szablonie `%zmienna%`. Jeśli turniej ma logoh w pliku nazwanym inaczej niż po prefiksie, można podać tę nazwę w `custom_file`. Daty rund odczytywane są z nagłówków stron `PREFIXrundaN.html` - daty nie są parsowane, więc sprawdzany jest też ich format. Nazwy teamów porównywane są z Cezarem na podstawie mapowania między ID teamu w turnieju a ID drużyny w Cezarze - w konfiguracji podaje się plik mapowania, w formacie jak dla modułu bazy graczy. Kolorki poróénywane są z plikiem w katalogu `config`. ## Moduł butlera Zbija wiele turniejów w jeden, w celu wyliczenia wspólnego butlera. ### Wymagania wstępne * python, wersji dowolnej (testowane pod 2.7.18 i 3.8.6) * klient MySQL * założony prawidłowo w pakiecie JFR Teamy turniej docelowy dla wspólnej klasyfikacji (choć jego parametry startowe - liczba teamów, stołów itp. nie muszą być wcześniej poprawnie ustawione) ### Wywołanie `make butler` Wywołany zostanie również moduł synchronizujący i ładujący zrzuty baz danych. Ręczne wywołanie samego scalania polega na uruchomieniu skryptu `butler/butler.py` z parametrem odpowiadającym właściwemu zestawowi zbijanych turniejów (patrz: Konfiguracja poniżej) i wgraniu wynikowego skryptu SQL do docelowego serwera bazy danych. Na tak spreparowanym turnieju docelowym trzeba później **ręcznie** (tj. JFR Teamy Adminem) dokonać zamknęcia niezamkniętych rund (wtedy odbywa się właściwe przeliczanie łącznego butlera) oraz wysłania stron statycznych. ### Konfiguracja Zmienne środowiskowe: * `LIGA_MYSQL_CONNECTION_OPTS`: komplet przełączników polecenia `mysql` pozwalający podłączyć się do docelowego (lokalnego) serwera MySQL * `LIGA_BUTLER_FINISHED_ROUND`, `LIGA_BUTLER_FINISHED_SEGMENT`: opcjonalne, jeśli ustawione, docelowy turniej cofany jest tylko do zdefiniowanego momentu, a nie do samego początku (żeby nie przeliczać wszystkich rund po kolei za każdym razem) * `LIGA_BUTLER_TABLE_STEP`, `LIGA_BUTLER_TEAM_STEP` i `LIGA_BUTLER_PLAYER_STEP` (opcjonalne) definiują, o ile podbijane są dla każdego kolejnego zbijanego turnieju bazodanowe ID stołów, teamów i graczy - numeracja stołów i teamów po tej operacji musi być ciągła Plik konfiguracyjny `config.json`: * plik formatu JSON, zawierający obiekt słownikowy * klucz `__groups` określa nazwy "grup", tj. prefiksy, które są doklejane do nazw teamów w wynikowym turnieju, jeśli chcemy w zbiorczym butlerze rozróżnić, skąd pochodzą źródłowe drużyny - jest to prosty słownik wartości `"baza_danych": "prefiks"` * klucz `__queries` określa dodatkowe polecenia SQL, które wykonywane są na **źródłowej** bazie danych przed poleceniami wklejającymi dane do bazy docelowej, może służyć np. do ustawienia BYEów czy korekty nierównolicznych grup, zaleca się modyfikować wyłącznie tabele, dla których w trakcie zbijania tworzone są **kopie** (prefiksowane podkreślnikiem, np. `_matches` czy `_teams`) - i działać na tych kopiach - jest to słownik formatu `"baza_danych": ["polecenie_1", "polecenie_2"]` Pozostałe klucze słownika w `config.json` przyjmują następującą postać: ``` "identyfikator_turnieju": { "source": [ "źródłowa_baza_danych_1", "źródłowa_baza_danych_2", "źródłowa_baza_danych_3" ], "output": "docelowa_baza_danych" } ``` W takiej konfiguracji `identyfikator_turnieju` jest parametrem wywołania skryptu `butler/butler.py`, a źródłowe turnieje zbijane są w zdefiniowanej kolejności i umeiszczane w docelowej bazie danych. Dodatkowo, w pliku `butler/butler.py` zakładane są następujące maksymalne rozmiary turniejów źródłowych, możliwe do przesłonięcia zmiennymi środowiskowymi `LIGA_BUTLER_*_STEP`: * zmienna `TABL_STEP` (liczba stołów w turnieju): 8 * zmienna `TEAM_STEP` (liczba teamów w turnieju): 16 * zmienna `PLAYER_STEP` (liczba zawodników w turnieju): 400 ## "Australijskie" butlery Moduł zewnętrzny, liczący i wysyłający butlery znormalizowane dla określonych turniejów. Szczegółowa dokumentacja: [pzbs-liga-ausbutler](https://github.com/emkael/pzbs-liga-ausbutler). ### Wywołanie `make ausbutler` Przeliczone zostaną wszystkie butlery zdefiniowane w podmodule `pzbs-liga-ausbutler` (z katalogu `ausbutler`). ## Baza graczy Dwa polecenia operujące na bazie zawodników. ### Konfiguracja Zmienna środowiskowa `LIGA_PLAYERS_DB_NAME`: nazwa bazy danych JFR Players. ### Wywołania `make players` lub `./dumps/import-players.sh` Importuje `baza.csv` do bazy zawodników w stylu JFR. Nazwa bazy do importu czytana jest ze zmiennej środowiskowej `LIGA_PLAYERS_DB_NAME`. `make teams` Sprawdza przynależność graczy do drużyn, wg przypisania w Cezarze. Wymaga CSVki w specyficznym formacie, zawierającej ID drużyn z Cezara. Jej URL ustawia się dla `import-players.sh`, w zmiennej `LIGA_BAZA_CSV`. Mapowanie drużyn w bazach danych turniejów odbywa się przy pomocy plików `.dumps/.cezar-teams-*`. Wywołuje `dumps/check-all-teams.sh`, które pobiera z `dumps/.paid-queries` argumenty do wywołania, kolejno, `dumps/check-teams.sh TURNIEJ`. `make paid` Sprawdza status opłacenia składek wśród graczy, którzy wystąpili w turnieju teamów w danym zakresie segmentów. Wywołuje `dumps/check-all-paid.sh`, które pobiera z `dumps/.paid-queries` argumenty do wywołania, kolejno, `dumps/check-paid.sh TURNIEJ SEGMENT_OD SEGMENT_DO`. `make lineups` Sprawdza poprawność lineupów oraz spójność lineupów z tabelą `butler` w turniejach. Wywołuje `dumps/check-all-lineups.sh`, które pobiera z `dumps/.paid-queries` argumenty do wywołania, kolejno, `dumps/check-lineups.sh TURNIEJ`. `make checks` Wywołuje kolejno `paid`, `teams` i `lineups`. ## Strona z rozkładami Generator plików dla strony z rozkładami do publikacji przy wynikach. ### Wymagania * [deal-convert](https://github.com/emkael/deal-convert) (uwaga: Python 2.x!) wraz z podmodułami * lftp, do wysyłania wygenerowanych stron ### Konfiguracja Zmienne środowiskowe: * `LIGA_BOARDS_DEAL_CONVERT_PATH` - ścieżka do `deal-converter.py` * `LIGA_BOARDS_FTP_ENABLED` - włącza synchronizację przez FTP * `LIGA_BOARDS_FTP_PATH` - ścieżka na serwerze zdalnym * `LIGA_FTP_HOST`, `LIGA_FTP_USER`, `LIGA_FTP_PASS` Pliki JSON w `boards/config` - definiują, które pliki PBN z `boards/pbns` mają zostać przetworzone i wyświetlone na stronie. Generowane są strony dla każdego z obecnych tam plików `*.json`, z osobna, przyjmując jego nazwę jako identyfikator. Szablony stron rozkładów można zdefiniować w `boards/template/IDENTYFIKATOR.html`. Do zaślepki `` wpisywana jest zawartość pliku `boards/template/IDENTYFIKATOR.logo.html. ### Wywołania `make records` lub `./boards/run.sh` ## Play-off Moduł zewnętrzny, generujący i wysyłający drabinki play-off. Szczegółowa dokumentacja: [liga-playoff](https://github.com/PZBS/liga-playoff) oraz [teamy-playoff](https://github.com/emkael/jfrteamy-playoff). ## Wymagania * [jfrteamy-playoff](https://github.com/emkael/jfrteamy-playoff#wymagania-systemowe) * lftp, do wysyłania drabinek ## Konfiguracja Zmienne środowiskowe: * `LIGA_FTP_HOST` * `LIGA_FTP_USER` * `LIGA_FTP_PASS` * `LIGA_PLAYOFF_FTP_PATH` * `LIGA_PLAYOFF_LOGFILE` Dane dostępu do FTP ### Wywołanie `make brackets` Wygenerowane i wysłane zostaną wszystkie drabinki zdefiniowane w `scripts/.groups` z podmodułu `playoff`. ## Kontrola teamów i carry-over w play-offach Przy użyciu `playoff/scripts/pagechecks/check-playoff.py` można sprawdzić, czy: * pod skonfiguowanymi w drabince linkami są już założone mecze, * czy w tych meczach ustawiono prawidłowe drużyny (i czy ich nazwy zgadzają się z fazą zasadniczą lub znanymi aliasami), * czy w meczach ustawiono prawidłowe carry-over. ### Wywołanie `make carryovers PHASE=FAZA_DRABINKI` `FAZA_DRABINKI` to liczba naturalna, wskazująca fazę drabinki, dla której ma nastąpić sprawdzenie. Skrypt oblicza wszystkie fazy drabinki do określonej włącznie, a następnie sprawdza, czy to, co udaje się (lub nie) pobrać z zewnętrznych źródeł (bazy danych, stron z wynikami), zgadza się z tym, co wynika z pliku drabinki (np. z `selected_teams` czy automatycznie wyliczanego c/o).