This commit is contained in:
Javanaut
2026-04-12 18:35:13 +02:00
parent a24b6dedaa
commit 0e51d6337f
10 changed files with 120 additions and 19 deletions

View File

@@ -1,6 +1,6 @@
import os, shutil, click
from sqlalchemy import create_engine, inspect
from sqlalchemy import create_engine, inspect, text
from sqlalchemy.orm import sessionmaker
# Import the full model package so SQLAlchemy registers every mapped class
@@ -98,6 +98,30 @@ def ensureDatabaseVersion(databaseContext):
f"Current database version ({currentDatabaseVersion}) does not match required ({DATABASE_VERSION})"
)
ensureCurrentSchemaCompatibility(databaseContext)
def ensureCurrentSchemaCompatibility(databaseContext):
engine = databaseContext['engine']
inspector = inspect(engine)
showColumns = {
column['name']
for column in inspector.get_columns('shows')
}
alterStatements = []
if 'quality' not in showColumns:
alterStatements.append("ALTER TABLE shows ADD COLUMN quality INTEGER DEFAULT 0")
if 'notes' not in showColumns:
alterStatements.append("ALTER TABLE shows ADD COLUMN notes TEXT DEFAULT ''")
if not alterStatements:
return
with engine.begin() as connection:
for alterStatement in alterStatements:
connection.execute(text(alterStatement))
def promptForDatabaseMigration(databaseContext, currentDatabaseVersion: int, targetDatabaseVersion: int):
migrationPlan = getMigrationPlan(currentDatabaseVersion, targetDatabaseVersion)

View File

@@ -78,3 +78,7 @@ def applyMigration(databaseContext):
connection.execute(
text("ALTER TABLE shows ADD COLUMN quality INTEGER DEFAULT 0")
)
if 'notes' not in showColumns:
connection.execute(
text("ALTER TABLE shows ADD COLUMN notes TEXT DEFAULT ''")
)

View File

@@ -1,5 +1,5 @@
# from typing import List
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy import create_engine, Column, Integer, String, Text, ForeignKey
from sqlalchemy.orm import relationship, declarative_base, sessionmaker
from ffx.show_descriptor import ShowDescriptor
@@ -46,6 +46,7 @@ class Show(Base):
indicator_season_digits = Column(Integer, default=ShowDescriptor.DEFAULT_INDICATOR_SEASON_DIGITS)
indicator_episode_digits = Column(Integer, default=ShowDescriptor.DEFAULT_INDICATOR_EPISODE_DIGITS)
quality = Column(Integer, default=0)
notes = Column(Text, default='')
def getDescriptor(self, context):
@@ -60,5 +61,6 @@ class Show(Base):
kwargs[ShowDescriptor.INDICATOR_SEASON_DIGITS_KEY] = int(self.indicator_season_digits)
kwargs[ShowDescriptor.INDICATOR_EPISODE_DIGITS_KEY] = int(self.indicator_episode_digits)
kwargs[ShowDescriptor.QUALITY_KEY] = int(self.quality or 0)
kwargs[ShowDescriptor.NOTES_KEY] = str(self.notes or '')
return ShowDescriptor(**kwargs)

View File

@@ -63,7 +63,8 @@ class ShowController():
index_episode_digits = showDescriptor.getIndexEpisodeDigits(),
indicator_season_digits = showDescriptor.getIndicatorSeasonDigits(),
indicator_episode_digits = showDescriptor.getIndicatorEpisodeDigits(),
quality = showDescriptor.getQuality())
quality = showDescriptor.getQuality(),
notes = showDescriptor.getNotes())
s.add(show)
s.commit()
@@ -92,6 +93,9 @@ class ShowController():
if int(currentShow.quality or 0) != int(showDescriptor.getQuality()):
currentShow.quality = int(showDescriptor.getQuality())
changed = True
if str(currentShow.notes or '') != str(showDescriptor.getNotes()):
currentShow.notes = str(showDescriptor.getNotes())
changed = True
if changed:
s.commit()

View File

@@ -22,6 +22,7 @@ class ShowDescriptor():
INDICATOR_SEASON_DIGITS_KEY = 'indicator_season_digits'
INDICATOR_EPISODE_DIGITS_KEY = 'indicator_episode_digits'
QUALITY_KEY = 'quality'
NOTES_KEY = 'notes'
DEFAULT_INDEX_SEASON_DIGITS = DEFAULT_SHOW_INDEX_SEASON_DIGITS
DEFAULT_INDEX_EPISODE_DIGITS = DEFAULT_SHOW_INDEX_EPISODE_DIGITS
@@ -132,6 +133,13 @@ class ShowDescriptor():
else:
self.__quality = 0
if ShowDescriptor.NOTES_KEY in kwargs.keys():
if type(kwargs[ShowDescriptor.NOTES_KEY]) is not str:
raise TypeError(f"ShowDescriptor.__init__(): Argument {ShowDescriptor.NOTES_KEY} is required to be of type str")
self.__notes = kwargs[ShowDescriptor.NOTES_KEY]
else:
self.__notes = ''
def getId(self):
return self.__showId
@@ -150,6 +158,8 @@ class ShowDescriptor():
return self.__indicatorEpisodeDigits
def getQuality(self):
return self.__quality
def getNotes(self):
return self.__notes
def getFilenamePrefix(self):
return f"{self.__showName} ({str(self.__showYear)})"

View File

@@ -1,7 +1,7 @@
import click
from textual.screen import Screen
from textual.widgets import Header, Footer, Static, Button, DataTable, Input
from textual.widgets import Header, Footer, Static, Button, DataTable, Input, TextArea
from textual.containers import Grid
from textual.widgets._data_table import CellDoesNotExist
@@ -25,8 +25,8 @@ class ShowDetailsScreen(Screen):
CSS = """
Grid {
grid-size: 5 16;
grid-rows: 2 2 2 2 2 2 2 2 2 2 2 9 2 9 2 2;
grid-size: 5 18;
grid-rows: 2 2 2 2 2 2 6 2 2 2 2 2 9 2 9 2 2 2;
grid-columns: 30 30 30 30 30;
height: 100%;
width: 100%;
@@ -77,6 +77,10 @@ class ShowDetailsScreen(Screen):
height: 100%;
border: solid green;
}
.note_box {
min-height: 6;
}
"""
BINDINGS = [
@@ -152,6 +156,8 @@ class ShowDetailsScreen(Screen):
self.query_one("#indicator_episode_digits_input", Input).value = str(self.__showDescriptor.getIndicatorEpisodeDigits())
if self.__showDescriptor.getQuality():
self.query_one("#quality_input", Input).value = str(self.__showDescriptor.getQuality())
if self.__showDescriptor.getNotes():
self.query_one("#notes_textarea", TextArea).text = str(self.__showDescriptor.getNotes())
#raise click.ClickException(f"show_id {showId}")
@@ -354,25 +360,32 @@ class ShowDetailsScreen(Screen):
yield Input(type="integer", id="quality_input", classes="four")
#6
yield Static("Notes")
yield Static(" ", classes="four")
#7
yield TextArea(id="notes_textarea", classes="five note_box")
#8
yield Static("Index Season Digits")
yield Input(type="integer", id="index_season_digits_input", classes="four")
#7
#9
yield Static("Index Episode Digits")
yield Input(type="integer", id="index_episode_digits_input", classes="four")
#8
#10
yield Static("Indicator Season Digits")
yield Input(type="integer", id="indicator_season_digits_input", classes="four")
#9
#11
yield Static("Indicator Edisode Digits")
yield Input(type="integer", id="indicator_episode_digits_input", classes="four")
# 10
# 12
yield Static(" ", classes="five")
# 11
# 13
yield Static("Shifted seasons", classes="two")
if self.__showDescriptor is not None:
@@ -384,18 +397,18 @@ class ShowDetailsScreen(Screen):
yield Static(" ")
yield Static(" ")
# 12
# 14
yield self.shiftedSeasonsTable
# 13
# 15
yield Static("File patterns", classes="five")
# 14
# 16
yield self.patternTable
# 15
# 17
yield Static(" ", classes="five")
# 16
# 18
yield Button("Save", id="save_button")
yield Button("Cancel", id="cancel_button")
@@ -445,6 +458,7 @@ class ShowDetailsScreen(Screen):
kwargs[ShowDescriptor.QUALITY_KEY] = int(self.query_one("#quality_input", Input).value)
except ValueError:
pass
kwargs[ShowDescriptor.NOTES_KEY] = str(self.query_one("#notes_textarea", TextArea).text)
return ShowDescriptor(**kwargs)