From fdc8f8f602d9b856da531220033976a018e7d834 Mon Sep 17 00:00:00 2001 From: Javanaut Date: Thu, 26 Sep 2024 19:10:36 +0200 Subject: [PATCH] nightly --- bin/ffx/pattern_delete_screen.py | 134 ++++++++++++++++++++++ bin/ffx/pattern_details_screen.py | 185 ++++++++++++++++++++++++++++++ bin/ffx/show_details_screen.py | 53 ++++++++- bin/ffx/shows_screen.py | 4 +- 4 files changed, 373 insertions(+), 3 deletions(-) create mode 100644 bin/ffx/pattern_delete_screen.py create mode 100644 bin/ffx/pattern_details_screen.py diff --git a/bin/ffx/pattern_delete_screen.py b/bin/ffx/pattern_delete_screen.py new file mode 100644 index 0000000..e8c9dc6 --- /dev/null +++ b/bin/ffx/pattern_delete_screen.py @@ -0,0 +1,134 @@ +import click + +from textual import events +from textual.app import App, ComposeResult +from textual.screen import Screen +from textual.widgets import Header, Footer, Placeholder, Label, ListView, ListItem, Static, DataTable, Button, Input +from textual.containers import Grid, Horizontal + +from ffx.model.pattern import Pattern + +# Screen[dict[int, str, int]] +class PatternDeleteScreen(Screen): + + CSS = """ + + Grid { + grid-size: 2; + grid-rows: 2 auto; + grid-columns: 30 330; + height: 100%; + width: 100%; + padding: 1; + } + + Input { + border: none; + } + Button { + border: none; + } + #toplabel { + height: 1; + column-span: 2; + } + + + #two { + column-span: 2; + row-span: 2; + tint: magenta 40%; + } + + .box { + height: 100%; + border: solid green; + } + """ + + def __init__(self, pattern = {}, show = {}): + super().__init__() + + self.context = self.app.getContext() + self.Session = self.context['database_session'] # convenience + + self.pattern_obj = pattern + self.show_obj = show + + + def on_mount(self): + if self.show_obj: + self.query_one("#showlabel", Static).update(f"{self.show_obj['id']} - {self.show_obj['name']} ({self.show_obj['year']})") + if self.pattern_obj: + self.query_one("#patternlabel", Static).update(str(self.pattern_obj['pattern'])) + + + def compose(self): + + yield Header() + + with Grid(): + + yield Static("Are you sure to delete the following filename pattern?", id="toplabel") + + yield Static("") + yield Static("") + + yield Static("Pattern") + yield Static("", id="patternlabel") + + yield Static("") + yield Static("") + + yield Static("from show") + yield Static("", id="showlabel") + + yield Static("") + yield Static("") + + yield Button("Delete", id="delete_button") + yield Button("Cancel", id="cancel_button") + + yield Footer() + + + # Event handler for button press + def on_button_pressed(self, event: Button.Pressed) -> None: + + if event.button.id == "delete_button": + + if self.deletePattern(self.show_obj['id'], self.pattern_obj['pattern']): + + screenResult = {} + screenResult['show_id'] = self.show_obj['id'] + screenResult['pattern'] = self.pattern_obj['pattern'] + + self.dismiss(screenResult) + + else: + #TODO: Meldung + self.app.pop_screen() + + if event.button.id == "cancel_button": + self.app.pop_screen() + + def deletePattern(self, show_id, pattern): + try: + s = self.Session() + q = s.query(Pattern).filter(Pattern.show_id == int(show_id), Pattern.pattern == str(pattern)) + + if q.count(): + + #DAFUQ: https://stackoverflow.com/a/19245058 + # q.delete() + pattern = q.first() + s.delete(pattern) + + s.commit() + return True + return False + + except Exception as ex: + click.ClickException(f"deletePattern(): {repr(ex)}") + finally: + s.close() diff --git a/bin/ffx/pattern_details_screen.py b/bin/ffx/pattern_details_screen.py new file mode 100644 index 0000000..104e627 --- /dev/null +++ b/bin/ffx/pattern_details_screen.py @@ -0,0 +1,185 @@ +import click + +from textual import events +from textual.app import App, ComposeResult +from textual.screen import Screen +from textual.widgets import Header, Footer, Placeholder, Label, ListView, ListItem, Static, DataTable, Button, Input +from textual.containers import Grid, Horizontal + +from ffx.model.show import Show +from ffx.model.pattern import Pattern + +# Screen[dict[int, str, int]] +class PatternDetailsScreen(Screen): + + CSS = """ + + Grid { + grid-size: 2; + grid-rows: 2 auto; + grid-columns: 30 330; + height: 100%; + width: 100%; + padding: 1; + } + + Input { + border: none; + } + Button { + border: none; + } + DataTable { + column-span: 2; + min-height: 5; + } + + #toplabel { + height: 1; + column-span: 2; + } + + + #two { + column-span: 2; + row-span: 2; + tint: magenta 40%; + } + + .box { + height: 100%; + border: solid green; + } + """ + + def __init__(self, pattern = {}, show = {}): + super().__init__() + + self.context = self.app.getContext() + self.Session = self.context['database_session'] # convenience + + self.pattern_obj = pattern + 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.pattern_obj: + + self.query_one("#show_id_static", Static).update(str(self.pattern_obj['show_id'])) + self.query_one("#pattern_input", Input).value = str(self.pattern_obj['pattern']) + + # 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("Filename pattern" if self.pattern_obj else "New filename pattern", id="toplabel") + + yield Static("Show") + yield Static("", id="show_id_static") + + yield Static("Pattern") + yield Input(type="text", id="pattern_input") + + yield Static("") + yield Static("") + + yield Button("Save", id="save_button") + yield Button("Cancel", id="cancel_button") + + yield Footer() + + + def getValues(self): + + showId = int(self.show_obj['id']) + + pattern = str(self.query_one("#pattern_input", Input).value) + + return showId, pattern + + + # Event handler for button press + def on_button_pressed(self, event: Button.Pressed) -> None: + # Check if the button pressed is the one we are interested in + if event.button.id == "save_button": + + showId, pattern = self.getValues() + + if self.updatePattern(showId, pattern): + + screenResult = {} + screenResult['show_id'] = showId + screenResult['pattern'] = pattern + + self.dismiss(screenResult) + else: + #TODO: Meldung + self.app.pop_screen() + + if event.button.id == "cancel_button": + self.app.pop_screen() + + def updatePattern(self, show_id, pattern): + + try: + s = self.Session() + q = s.query(Pattern).filter(Pattern.show_id == int(show_id), Pattern.pattern == str(pattern)) + + if not q.count(): + pattern = Pattern(show_id = int(show_id), pattern = str(pattern)) + s.add(pattern) + s.commit() + return True +# else: +# +# currentShow = q.first() +# +# changed = False +# if currentShow.name != str(show_name): +# currentShow.name = str(show_name) +# changed = True +# if currentShow.year != int(show_year): +# currentShow.year = int(show_year) +# changed = True +# if changed: +# s.commit() +# return changed + + except Exception as ex: + 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 2d6cd47..8b7a7ec 100644 --- a/bin/ffx/show_details_screen.py +++ b/bin/ffx/show_details_screen.py @@ -9,6 +9,9 @@ from textual.containers import Grid, Horizontal from ffx.model.show import Show from ffx.model.pattern import Pattern +from .pattern_details_screen import PatternDetailsScreen +from .pattern_delete_screen import PatternDeleteScreen + # Screen[dict[int, str, int]] class ShowDetailsScreen(Screen): @@ -17,7 +20,7 @@ class ShowDetailsScreen(Screen): Grid { grid-size: 2; grid-rows: 2 auto; - grid-columns: 30 auto; + grid-columns: 30 330; height: 100%; width: 100%; padding: 1; @@ -52,6 +55,12 @@ class ShowDetailsScreen(Screen): } """ + BINDINGS = [ + #("e", "edit_show", "Edit Show"), + ("a", "add_pattern", "Add Pattern"), + ("r", "remove_pattern", "Remove Pattern"), + ] + def __init__(self, show = {}): super().__init__() @@ -88,6 +97,48 @@ class ShowDetailsScreen(Screen): self.patternTable.add_row(*map(str, row)) + + def getSelectedPattern(self): + + # Fetch the currently selected row when 'Enter' is pressed + #selected_row_index = self.table.cursor_row + row_key, col_key = self.patternTable.coordinate_to_cell_key(self.patternTable.cursor_coordinate) + + selectedPattern = {} + + if row_key is not None: + selected_row_data = self.patternTable.get_row(row_key) + + selectedPattern['pattern'] = selected_row_data[0] + #selectedPattern['pattern'] = selected_row_data[1] + + return selectedPattern + + + + def action_add_pattern(self): + if self.show_obj: + self.app.push_screen(PatternDetailsScreen(show = self.show_obj), self.handle_add_pattern) + + + def handle_add_pattern(self, screenResult): + + pattern = (screenResult['pattern'],) + self.patternTable.add_row(*map(str, pattern)) + + + def action_remove_pattern(self): + + selectedPattern = self.getSelectedPattern() + + if selectedPattern: + self.app.push_screen(PatternDeleteScreen(pattern = selectedPattern, show = self.show_obj), self.handle_remove_pattern) + + def handle_remove_pattern(self, screenResult): + row_key, col_key = self.patternTable.coordinate_to_cell_key(self.patternTable.cursor_coordinate) + self.patternTable.remove_row(row_key) + + def compose(self): # Create the DataTable widget diff --git a/bin/ffx/shows_screen.py b/bin/ffx/shows_screen.py index a0052c1..be55bb4 100644 --- a/bin/ffx/shows_screen.py +++ b/bin/ffx/shows_screen.py @@ -108,10 +108,10 @@ class ShowsScreen(Screen): selectedShow = self.getSelectedShow() if selectedShow: - self.app.push_screen(ShowDeleteScreen(show = selectedShow), self.handle_delete_screen) + self.app.push_screen(ShowDeleteScreen(show = selectedShow), self.handle_delete_show) - def handle_delete_screen(self, screenResult): + def handle_delete_show(self, screenResult): row_key, col_key = self.table.coordinate_to_cell_key(self.table.cursor_coordinate) self.table.remove_row(row_key)