Start building a drag and drop ui
Apparently this is synced between all windows... I don't actually want that
This commit is contained in:
parent
71db89646f
commit
57e3c86b20
@ -0,0 +1,25 @@
|
|||||||
|
from argparse import ArgumentParser, Namespace
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
QUEENS_FILE = "queens.txt"
|
||||||
|
PICKS_FILE_GLOB = "picks-*.txt"
|
||||||
|
ELIMINATIONS_FILE = "eliminations.txt"
|
||||||
|
ROSTERS_FILE = "rosters.json"
|
||||||
|
|
||||||
|
|
||||||
|
def parse_args() -> Namespace:
|
||||||
|
parser = ArgumentParser()
|
||||||
|
parser.add_argument(
|
||||||
|
"season_dir",
|
||||||
|
type=Path,
|
||||||
|
default=Path("."),
|
||||||
|
help="Directory containing season data",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--eliminate", type=str, help="Eliminate a queen", metavar="QUEEN"
|
||||||
|
)
|
||||||
|
parser.add_argument("--draft", action="store_true", help="Run the initial draft")
|
||||||
|
parser.add_argument("--print", action="store_true", help="Print the current status")
|
||||||
|
|
||||||
|
return parser.parse_args()
|
@ -1,13 +1,15 @@
|
|||||||
import json
|
import json
|
||||||
import random
|
import random
|
||||||
from argparse import ArgumentParser
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import DefaultDict
|
from typing import DefaultDict
|
||||||
|
|
||||||
QUEENS_FILE = "queens.txt"
|
from drag_draft import (
|
||||||
PICKS_FILE_GLOB = "picks-*.txt"
|
ELIMINATIONS_FILE,
|
||||||
ELIMINATIONS_FILE = "eliminations.txt"
|
PICKS_FILE_GLOB,
|
||||||
ROSTERS_FILE = "rosters.json"
|
QUEENS_FILE,
|
||||||
|
ROSTERS_FILE,
|
||||||
|
parse_args,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Draft:
|
class Draft:
|
||||||
@ -33,7 +35,10 @@ class Draft:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, queens_file: Path, picks_files: list[Path], roster_file: Path|None = None
|
self,
|
||||||
|
queens_file: Path,
|
||||||
|
picks_files: list[Path],
|
||||||
|
roster_file: Path | None = None,
|
||||||
):
|
):
|
||||||
self.queens = self.load_queens(queens_file)
|
self.queens = self.load_queens(queens_file)
|
||||||
self.players = self.load_players(picks_files)
|
self.players = self.load_players(picks_files)
|
||||||
@ -58,7 +63,9 @@ class Draft:
|
|||||||
picks_set = set(picks)
|
picks_set = set(picks)
|
||||||
assert len(picks_set) == len(picks), f"Player {player} has duplicate picks"
|
assert len(picks_set) == len(picks), f"Player {player} has duplicate picks"
|
||||||
unknown_queens = picks_set - self.queens
|
unknown_queens = picks_set - self.queens
|
||||||
assert len(unknown_queens) == 0, f"Player {player} has invalid picks: {unknown_queens}"
|
assert (
|
||||||
|
len(unknown_queens) == 0
|
||||||
|
), f"Player {player} has invalid picks: {unknown_queens}"
|
||||||
|
|
||||||
players[player] = picks
|
players[player] = picks
|
||||||
|
|
||||||
@ -143,7 +150,9 @@ class Draft:
|
|||||||
return scores
|
return scores
|
||||||
|
|
||||||
|
|
||||||
def eliminate_queen(queens_file: Path, eliminations_file: Path, queen: str) -> list[str]|None:
|
def eliminate_queen(
|
||||||
|
queens_file: Path, eliminations_file: Path, queen: str
|
||||||
|
) -> list[str] | None:
|
||||||
"""Eliminate a queen from the list of queens."""
|
"""Eliminate a queen from the list of queens."""
|
||||||
queens = set(queens_file.read_text().strip().split("\n"))
|
queens = set(queens_file.read_text().strip().split("\n"))
|
||||||
if queen not in queens:
|
if queen not in queens:
|
||||||
@ -162,22 +171,9 @@ def eliminate_queen(queens_file: Path, eliminations_file: Path, queen: str) -> l
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = ArgumentParser()
|
args = parse_args()
|
||||||
parser.add_argument(
|
|
||||||
"season_dir",
|
|
||||||
type=Path,
|
|
||||||
default=Path("."),
|
|
||||||
help="Directory containing season data",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"--eliminate", type=str, help="Eliminate a queen", metavar="QUEEN"
|
|
||||||
)
|
|
||||||
parser.add_argument("--draft", action="store_true", help="Run the initial draft")
|
|
||||||
parser.add_argument("--print", action="store_true", help="Print the current status")
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
# Create a Draft object for the given season directory
|
# Create a Draft object for the given season directory
|
||||||
|
|
||||||
queens_file = args.season_dir / QUEENS_FILE
|
queens_file = args.season_dir / QUEENS_FILE
|
||||||
picks_files = list(args.season_dir.glob(PICKS_FILE_GLOB))
|
picks_files = list(args.season_dir.glob(PICKS_FILE_GLOB))
|
||||||
eliminations_file = args.season_dir / ELIMINATIONS_FILE
|
eliminations_file = args.season_dir / ELIMINATIONS_FILE
|
||||||
@ -212,4 +208,3 @@ def main():
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
62
drag_draft/ui.py
Normal file
62
drag_draft/ui.py
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
from nicegui import context, ui
|
||||||
|
|
||||||
|
from drag_draft import QUEENS_FILE, parse_args
|
||||||
|
|
||||||
|
|
||||||
|
def run_draft() -> None:
|
||||||
|
args = parse_args()
|
||||||
|
queens_file = args.season_dir / QUEENS_FILE
|
||||||
|
queens = queens_file.read_text().strip().split("\n")
|
||||||
|
|
||||||
|
ui.label("Make your picks")
|
||||||
|
player_name = ui.input("Player name", placeholder="Enter your name")
|
||||||
|
|
||||||
|
with ui.row():
|
||||||
|
with ui.column().classes("sortable"):
|
||||||
|
for queen in queens:
|
||||||
|
with ui.card().classes("cursor-grab"):
|
||||||
|
ui.label(queen)
|
||||||
|
|
||||||
|
def drop_queen(e) -> None:
|
||||||
|
# Move in UI
|
||||||
|
print(e)
|
||||||
|
context.client.elements[e.args["id"]].move(target_index=e.args["new_index"])
|
||||||
|
queens.insert(e.args["new_index"], queens.pop(e.args["old_index"]))
|
||||||
|
print(
|
||||||
|
f'Moved queen {queens[e.args["new_index"]]} to index {e.args["new_index"]}'
|
||||||
|
)
|
||||||
|
|
||||||
|
ui.on(
|
||||||
|
"item-drop",
|
||||||
|
drop_queen,
|
||||||
|
)
|
||||||
|
|
||||||
|
def save_picks() -> None:
|
||||||
|
print(f"Player {player_name.value} picked:")
|
||||||
|
print(context.client.elements)
|
||||||
|
(args.season_dir / f"picks-{player_name.value}.txt").write_text(
|
||||||
|
"\n".join(queen for queen in queens)
|
||||||
|
)
|
||||||
|
print("Picks saved!")
|
||||||
|
|
||||||
|
ui.button("Save").on_click(save_picks)
|
||||||
|
|
||||||
|
ui.add_body_html(
|
||||||
|
r"""
|
||||||
|
<script type="module">
|
||||||
|
import 'https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.15.6/Sortable.min.js';
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
Sortable.create(document.querySelector('.sortable'), {
|
||||||
|
animation: 150,
|
||||||
|
ghostClass: 'opacity-50',
|
||||||
|
onEnd: (evt) => emitEvent("item-drop", {id: parseInt(evt.item.id.slice(1)), new_index: evt.newIndex, old_index: evt.oldIndex}),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
run_draft()
|
||||||
|
|
||||||
|
ui.run()
|
1830
poetry.lock
generated
1830
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@ -7,8 +7,9 @@ authors = [
|
|||||||
]
|
]
|
||||||
license = {text = "MIT"}
|
license = {text = "MIT"}
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12,<4.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"nicegui (>=2.9.1,<3.0.0)"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user