diff --git a/docs/operations/boards.rst b/docs/operations/boards.rst index e2f2f0c..21d0c8b 100644 --- a/docs/operations/boards.rst +++ b/docs/operations/boards.rst @@ -12,40 +12,108 @@ Kanonickým zdrojem pravdy je ale `výpis na justice.cz `_ + * + * * Jan Čermák + * `@sairon `_ + * |:moneybag:| + * * Karolina Surma + * `@befeleme `_ + * |:crown:| + * * Petr Viktorin + * `@encukou `_ + * + * * Jakub Červinka + * `@JakubDotPy `_ + * + +Výbor od 1.9.2022 ------------------------------------------------- -.. csv-table:: - :header: "Jméno", "GitHub", "Funkce" - - Barbora Drbohlavová, `@baradrb `_, |:crown:| - Anežka Müller, `@anezkamll `_, - Jan Javorek, `@honzajavorek `_, - Jakub Vysoký, `@kvbik `_, - Jan Čermák, `@sairon `_, |:moneybag:| - -Výbor od 8.4.2019 +.. list-table:: + :header-rows: 1 + + * * Jméno + * GitHub + * Funkce + * * Barbora Drbohlavová + * `@baradrb `_ + * |:crown:| + * * Anežka Müller + * `@anezkamll `_ + * + * * Jan Javorek + * `@honzajavorek `_ + * + * * Jakub Vysoký + * `@kvbik `_ + * + * * Jan Čermák + * `@sairon `_ + * |:moneybag:| + +Výbor od 4.5.2019 ------------------------------------------------- -.. csv-table:: - :header: "Jméno", "GitHub", "Funkce" - - Martin Bílek, `@martinbilek `_, |:crown:| |:moneybag:| - Aleš Zoulek, `@aleszoulek `_, - Jan Javorek, `@honzajavorek `_, - Jakub Vysoký, `@kvbik `_, - Jiří Bartoň, `@whiskybar `_, +.. list-table:: + :header-rows: 1 + + * * Jméno + * GitHub + * Funkce + * * Martin Bílek + * `@martinbilek `_ + * |:crown:| |:moneybag:| + * * Aleš Zoulek + * `@aleszoulek `_ + * + * * Jan Javorek + * `@honzajavorek `_ + * + * * Jakub Vysoký + * `@kvbik `_ + * + * * Jiří Bartoň + * `@whiskybar `_ + * Výbor od 27.3.2012 ------------------------------------------------- -.. csv-table:: - :header: "Jméno", "GitHub", "Funkce" - - Martin Bílek, `@martinbilek `_, |:crown:| |:moneybag:| - Aleš Zoulek, `@aleszoulek `_, - Robin Gottfried, `@czervenka `_, - Jan Král, `@honzakral `_, - Jakub Vysoký, `@kvbik `_, - Jiří Bartoň, `@whiskybar `_, - Vítězslav Pliska, `@whit `_, +.. list-table:: + :header-rows: 1 + + * * Jméno + * GitHub + * Funkce + * * Martin Bílek + * `@martinbilek `_ + * |:crown:| |:moneybag:| + * * Aleš Zoulek + * `@aleszoulek `_ + * + * * Robin Gottfried + * `@czervenka `_ + * + * * Jan Král + * `@honzakral `_ + * + * * Jakub Vysoký + * `@kvbik `_ + * + * * Jiří Bartoň + * `@whiskybar `_ + * + * * Vítězslav Pliska + * `@whit `_ + * diff --git a/docs/operations/boards.rst.jinja b/docs/operations/boards.rst.jinja index 6916e72..f742c6d 100644 --- a/docs/operations/boards.rst.jinja +++ b/docs/operations/boards.rst.jinja @@ -12,12 +12,29 @@ Kanonickým zdrojem pravdy je ale `výpis na justice.cz `_, {% if member.is_chair %}|:crown:| {% endif %}{% if member.is_treasurer %}|:moneybag:| {% endif %} -{%- endfor %} +{%- else %} +Nově zvolený výbor +------------------ +{%- endif %} + +.. list-table:: + :header-rows: 1 + + * * Jméno + * GitHub + * Funkce + {%- for member in board.members %} + * * {{ member.name }} + * `@{{ member.github }} `_ + * + {%- if member.is_chair -%} + {{- " " -}} |:crown:| + {%- endif -%} + {%- if member.is_treasurer -%} + {{- " " -}} |:moneybag:| + {%- endif -%} + {% endfor %} {% endfor %} diff --git a/docs/operations/elections.rst b/docs/operations/elections.rst index b500a58..a66b991 100644 --- a/docs/operations/elections.rst +++ b/docs/operations/elections.rst @@ -8,11 +8,11 @@ Volby do výboru probíhají asynchronně a zpravidla trvají týden, aby stihli Kdy se volí ----------- -+------------------------------------+--------------------+ -| |:ballot_box:| Předchozí volba | |board_start| | -+------------------------------------+--------------------+ -| |:warning:| Příští volba | |board_end| | -+------------------------------------+--------------------+ ++------------------------------------+------------------------+ +| |:ballot_box:| Předchozí volba | |board_vote_date| | ++------------------------------------+------------------------+ +| |:warning:| Příští volba | |next_board_vote_date| | ++------------------------------------+------------------------+ Příprava -------- diff --git a/src/pyvec_docs/boards.py b/src/pyvec_docs/boards.py index f7eafa2..86c3306 100644 --- a/src/pyvec_docs/boards.py +++ b/src/pyvec_docs/boards.py @@ -40,10 +40,26 @@ def is_treasurer(self) -> bool: class Board(BaseModel): start_on: date + voted_on: date + has_started: bool members: list[BoardMember] model_config = {"extra": "forbid", "frozen": True} + @classmethod + def create(cls, voted_on=None, start_on=None, **kwargs): + if start_on is None: + start_on = voted_on + has_started = False + else: + has_started = True + return cls( + voted_on=voted_on, + start_on=start_on, + has_started=has_started, + **kwargs, + ) + @property def years(self) -> tuple[int, int]: start_year = self.start_on.year @@ -52,9 +68,15 @@ def years(self) -> tuple[int, int]: @cache def load_boards(path: Path | str = BOARDS_CONFIG_PATH) -> list[Board]: + """Load all boards, including inactive ones""" data = tomllib.loads(Path(path).read_text()) return sorted( - (Board(**board) for board in data["board"]), - key=attrgetter("start_on"), + (Board.create(**board) for board in data["board"]), + key=attrgetter('start_on'), reverse=True, ) + +@cache +def load_current_board(path: Path | str = BOARDS_CONFIG_PATH) -> Board: + """Load the board that is currently in power""" + return next(board for board in load_boards(path) if board.has_started) diff --git a/src/pyvec_docs/boards.toml b/src/pyvec_docs/boards.toml index c68bcd3..51a95de 100644 --- a/src/pyvec_docs/boards.toml +++ b/src/pyvec_docs/boards.toml @@ -1,9 +1,44 @@ # The Pyvec board members in time -# The current board is first, previous boards are listed in descending order +# The most recent board is first, previous boards are listed in descending order # Each member has a `name`, `github`, and optionally a `roles` array +# +# "voted_on" is the day when we voted for the board. It's approximate, since +# votes can take longer than a day. +# +# "start_on" should ideally be the date from justice.cz. +# If the board doesn't officially have power yet, leave it out; "voted_on` will +# be used as default. + + +[[board]] +voted_on = "2025-05-07" + +[[board.members]] +name = "Jakub Vysoký" +github = "kvbik" + +[[board.members]] +name = "Jan Čermák" +github = "sairon" +roles = ["treasurer"] + +[[board.members]] +name = "Karolina Surma" +github = "befeleme" +roles = ["chair"] + +[[board.members]] +name = "Petr Viktorin" +github = "encukou" + +[[board.members]] +name = "Jakub Červinka" +github = "JakubDotPy" + [[board]] -start_on = "2022-04-09" +start_on = "2022-09-01" +voted_on = "2022-04-09" [[board.members]] name = "Barbora Drbohlavová" @@ -30,7 +65,8 @@ roles = ["treasurer"] [[board]] -start_on = "2019-04-08" +start_on = "2019-05-04" +voted_on = "2019-04-08" [[board.members]] name = "Martin Bílek" @@ -57,6 +93,7 @@ github = "whiskybar" [[board]] start_on = "2012-03-27" +voted_on = "2012-03-27" # approximation [[board.members]] name = "Martin Bílek" diff --git a/src/pyvec_docs/ext/board_dates.py b/src/pyvec_docs/ext/board_dates.py index 7fa25d9..2a12f2b 100644 --- a/src/pyvec_docs/ext/board_dates.py +++ b/src/pyvec_docs/ext/board_dates.py @@ -10,14 +10,14 @@ def board_dates(app: Sphinx, config: Config): board = load_boards()[0] - board_start = board.start_on - board_end = board_start + timedelta(days=BOARDS_MANDATE_LENGTH * 365) + last_vote = board.voted_on + next_vote = last_vote + timedelta(days=BOARDS_MANDATE_LENGTH * 365) existing_epilog = app.config.rst_epilog or "" app.config.rst_epilog = ( f"{existing_epilog}\n\n" - f".. |board_start| replace:: {board_start:%-d.%-m.%Y}\n" - f".. |board_end| replace:: {board_end:%Y}\n" + f".. |board_vote_date| replace:: {last_vote:%-d.%-m.%Y}\n" + f".. |next_board_vote_date| replace:: {next_vote:%Y}\n" ) diff --git a/src/pyvec_docs/ext/slack.py b/src/pyvec_docs/ext/slack.py index 983f997..038c381 100644 --- a/src/pyvec_docs/ext/slack.py +++ b/src/pyvec_docs/ext/slack.py @@ -9,7 +9,7 @@ from docutils import nodes -from pyvec_docs.boards import load_boards +from pyvec_docs.boards import load_current_board # https://docutils.readthedocs.io/en/sphinx-docs/howto/rst-roles.html @@ -34,6 +34,6 @@ def slack( def setup(app): - pyvec_board_years = load_boards()[0].years + pyvec_board_years = load_current_board().years app.add_role("slack", functools.partial(slack, pyvec_board_years=pyvec_board_years)) return {"version": "1.0", "parallel_read_safe": True} diff --git a/src/pyvec_docs/grants.py b/src/pyvec_docs/grants.py index 458dc3c..421be5f 100644 --- a/src/pyvec_docs/grants.py +++ b/src/pyvec_docs/grants.py @@ -18,6 +18,8 @@ def remove_comments(html): def get_board_member_name(username, voted_at, boards: list[Board]): for board in boards: # sorted from the most recent + if not board.has_started: + continue if voted_at > board.start_on: for member in board.members: if member.github == username: diff --git a/tests/test_scripts_generate_grants.py b/tests/test_scripts_generate_grants.py index 1c3d4f3..8692dfd 100644 --- a/tests/test_scripts_generate_grants.py +++ b/tests/test_scripts_generate_grants.py @@ -14,18 +14,29 @@ @pytest.fixture def boards(): return [ # sorted! - Board( + Board.create( + **{ + # No start_on; votes don't count + "voted_on": date(2023, 1, 1), + "members": [ + {"name": "Bob", "github": "bobby"}, + ], + } + ), + Board.create( **{ "start_on": date(2020, 1, 1), + "voted_on": date(2019, 12, 1), "members": [ {"name": "Alice", "github": "alice"}, {"name": "Doubravka", "github": "doubravka"}, ], } ), - Board( + Board.create( **{ "start_on": date(2019, 1, 1), + "voted_on": date(2018, 12, 1), "members": [ {"name": "Bob", "github": "bobby"}, ], @@ -34,6 +45,22 @@ def boards(): ] +def assert_boards_sorted(boards): + assert boards == sorted(boards) + + +def assert_start_on_defaults(boards): + assert [b.start_on for b in boards] == [ + date(2023, 1, 1), # from voted_on + date(2020, 1, 1), # explicit + date(2018, 12, 1), # explicit + ] + + +def assert_started_values(boards): + assert [b.start_on for b in boards] == [False, True, True] + + def test_to_date(): assert to_date("2020-02-12T13:22:01Z") == date(2020, 2, 12)