From 322321b1ed074b39361e6fd28efc3f0571c52e12 Mon Sep 17 00:00:00 2001 From: Maveno Date: Thu, 26 Sep 2024 15:07:45 +0200 Subject: [PATCH] inc --- bin/ffx/model/pattern.py | 16 ++++++++- bin/ffx/model/show.py | 18 ++++++++-- bin/ffx/show_delete_screen.py | 3 +- bin/ffx/show_details_screen.py | 65 ++++++++++++++++++++++++++-------- bin/ffx/show_new_screen.py | 60 ------------------------------- 5 files changed, 82 insertions(+), 80 deletions(-) delete mode 100644 bin/ffx/show_new_screen.py diff --git a/bin/ffx/model/pattern.py b/bin/ffx/model/pattern.py index d1648af..9f8838f 100644 --- a/bin/ffx/model/pattern.py +++ b/bin/ffx/model/pattern.py @@ -1,10 +1,24 @@ from sqlalchemy import create_engine, Column, Integer, String, ForeignKey -from sqlalchemy.orm import relationship, sessionmaker +from sqlalchemy.orm import relationship, sessionmaker, Mapped from .show import Base class Pattern(Base): __tablename__ = 'patterns' + + # v1.x id = Column(Integer, primary_key=True) pattern = Column(String) + + # v2.0 + # id: Mapped[int] = mapped_column(Integer, primary_key=True) + # pattern: Mapped[str] = mapped_column(String, nullable=False) + + # v1.x + show_id = Column(Integer, ForeignKey('shows.id', ondelete="CASCADE")) + show = relationship('Show', back_populates='patterns') + + # v2.0 + # show_id: Mapped[int] = mapped_column(ForeignKey("shows.id", ondelete="CASCADE")) + # show: Mapped["Show"] = relationship(back_populates="patterns") diff --git a/bin/ffx/model/show.py b/bin/ffx/model/show.py index d472f93..e1889db 100644 --- a/bin/ffx/model/show.py +++ b/bin/ffx/model/show.py @@ -1,13 +1,25 @@ +# from typing import List from sqlalchemy import create_engine, Column, Integer, String, ForeignKey -from sqlalchemy.orm import relationship, sessionmaker - -from sqlalchemy.orm import declarative_base +from sqlalchemy.orm import relationship, declarative_base, sessionmaker Base = declarative_base() class Show(Base): __tablename__ = 'shows' + + # v1.x id = Column(Integer, primary_key=True) name = Column(String) year = Column(Integer) + + # v2.0 + # id: Mapped[int] = mapped_column(Integer, primary_key=True) + # name: Mapped[str] = mapped_column(String, nullable=False) + # year: Mapped[int] = mapped_column(Integer, nullable=False) + + # v1.x + patterns = relationship('Pattern', back_populates='show', cascade="all, delete") + + # v2.0 + # patterns: Mapped[List["Pattern"]] = relationship(back_populates="show", cascade="all, delete") diff --git a/bin/ffx/show_delete_screen.py b/bin/ffx/show_delete_screen.py index cee230c..c4aacee 100644 --- a/bin/ffx/show_delete_screen.py +++ b/bin/ffx/show_delete_screen.py @@ -108,7 +108,7 @@ class ShowDeleteScreen(Screen): def deleteShow(self, show_id): try: s = self.Session() - q = s.query(Show).filter(Show.id == show_id) + q = s.query(Show).filter(Show.id == int(show_id)) if q.count(): q.delete() @@ -120,4 +120,3 @@ class ShowDeleteScreen(Screen): click.ClickException(f"ShowDetailsScreen.updateShow(): {repr(ex)}") finally: s.close() - diff --git a/bin/ffx/show_details_screen.py b/bin/ffx/show_details_screen.py index 05694f2..2d6cd47 100644 --- a/bin/ffx/show_details_screen.py +++ b/bin/ffx/show_details_screen.py @@ -7,6 +7,7 @@ from textual.widgets import Header, Footer, Placeholder, Label, ListView, ListIt from textual.containers import Grid, Horizontal from ffx.model.show import Show +from ffx.model.pattern import Pattern # Screen[dict[int, str, int]] class ShowDetailsScreen(Screen): @@ -28,6 +29,11 @@ class ShowDetailsScreen(Screen): Button { border: none; } + DataTable { + column-span: 2; + min-height: 5; + } + #toplabel { height: 1; column-span: 2; @@ -55,37 +61,68 @@ class ShowDetailsScreen(Screen): self.show_obj = show + def loadPatterns(self, show_id): + + try: + s = self.Session() + q = s.query(Pattern).filter(Pattern.show_id == int(show_id)) + + return [{'id': int(p.id), 'pattern': p.pattern} for p in q.all()] + + except Exception as ex: + click.ClickException(f"loadPatterns(): {repr(ex)}") + finally: + s.close() + def on_mount(self): if self.show_obj: self.query_one("#id_wdg", Static).update(str(self.show_obj['id'])) - self.query_one("#name_input", Input).value = self.show_obj['name'] - self.query_one("#year_input", Input).value = self.show_obj['year'] + self.query_one("#name_input", Input).value = str(self.show_obj['name']) + self.query_one("#year_input", Input).value = str(self.show_obj['year']) + + for pattern in self.loadPatterns(int(self.show_obj['id'])): + row = (pattern['pattern'],) + self.patternTable.add_row(*map(str, row)) + def compose(self): + # Create the DataTable widget + self.patternTable = DataTable() + + # Define the columns with headers + self.column_key_id = self.patternTable.add_column("Pattern", width=60) + #self.column_key_name = self.patternTable.add_column("Name", width=50) + #self.column_key_year = self.patternTable.add_column("Year", width=10) + + self.patternTable.cursor_type = 'row' + + yield Header() with Grid(): - yield Static("New Show" if self.show_obj else "Show", id="toplabel") + yield Static("Show" if self.show_obj else "New Show", id="toplabel") yield Static("ID") if self.show_obj: yield Static("", id="id_wdg") else: - yield Input(type="text", id="id_wdg") + yield Input(type="integer", id="id_wdg") yield Static("Name") yield Input(type="text", id="name_input") yield Static("Year") - yield Input(type="text", id="year_input") + yield Input(type="integer", id="year_input") yield Static("") yield Static("") + yield self.patternTable + yield Static("") yield Static("") @@ -102,8 +139,8 @@ class ShowDetailsScreen(Screen): else: showId = int(self.query_one("#id_wdg", Input).value) - showName = self.query_one("#name_input", Input).value - showYear = self.query_one("#year_input", Input).value + showName = str(self.query_one("#name_input", Input).value) + showYear = int(self.query_one("#year_input", Input).value) return showId, showName, showYear @@ -136,9 +173,9 @@ class ShowDetailsScreen(Screen): q = s.query(Show).filter(Show.id == show_id) if not q.count(): - show = Show(id = show_id, - name = show_name, - year = show_year) + show = Show(id = int(show_id), + name = str(show_name), + year = int(show_year)) s.add(show) s.commit() return True @@ -147,11 +184,11 @@ class ShowDetailsScreen(Screen): currentShow = q.first() changed = False - if currentShow.name != show_name: - currentShow.name = show_name + if currentShow.name != str(show_name): + currentShow.name = str(show_name) changed = True - if currentShow.year != show_year: - currentShow.year = show_year + if currentShow.year != int(show_year): + currentShow.year = int(show_year) changed = True if changed: s.commit() diff --git a/bin/ffx/show_new_screen.py b/bin/ffx/show_new_screen.py deleted file mode 100644 index 7c3ff8b..0000000 --- a/bin/ffx/show_new_screen.py +++ /dev/null @@ -1,60 +0,0 @@ -import click - -from textual.app import App, ComposeResult -from textual.screen import Screen -from textual.widgets import Header, Footer, Placeholder, Label, ListView, ListItem, Static, DataTable, Button -from textual.containers import Grid, Horizontal - -from ffx.model.show import Show - -class ShowNewScreen(Screen): - - CSS = """ - - Grid { - grid-size: 2; - grid-rows: 2 auto; - height: 100%; - width: 100%; - padding: 1; - } - - #top { - height: 1; - } - - - #two { - column-span: 2; - row-span: 2; - tint: magenta 40%; - } - - .box { - height: 100%; - border: solid green; - } - """ - - BINDINGS = [ - ("q", "quit()", "Quit"), - ("h", "switch_mode('help')", "Help") - ] - - def __init__(self): - super().__init__() - - self.context = self.app.getContext() - - self.Session = self.context['database_session'] # convenience - - - def compose(self): - - yield Header() - - with Grid(): - - yield Static("New Show") - - yield Footer()