ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/ns_dev/Python/NinoCode/Active_prgs/Gromulus/models.py
Revision: 991
Committed: Mon Mar 9 21:52:02 2026 UTC (2 weeks, 4 days ago) by nino.borges
Content type: text/x-python
File size: 4297 byte(s)
Log Message:
I meant to have this as the commit message for 1.5 but I had an issue wiht the message.  so I added some spaces to the files to force another commit.

Gromulus v1.5: user metadata save workflow, schema expansion, and UI refactor

- Added user-editable game metadata workflow with explicit Save button (no autosave).
- Added dirty-state tracking and Save/Discard/Cancel prompts when navigating away or closing with unsaved changes.
- Added DB schema support for new metadata fields:
  - favorite_game
  - release_date, release_date_scraped
  - game_genre, game_genre_scraped
  - cooperative, cooperative_scraped
  - max_players, max_players_scraped
- Wired UI to user-first metadata precedence with _scraped fallback for release date, genre, cooperative, max players, and description.
- Added release date display/storage conversion:
  - GUI display MM-DD-YYYY
  - DB storage YYYY-MM-DD
- Refactored main game info panel:
  - moved hash/file/No-Intro/TOSEC detail fields into Reports -> Game Properties modal
  - added compact TOSEC/NoIntro match indicators
  - added Favorite, Release Date, Genre, Cooperative, Max Players, Description, and User Notes controls
- Enhanced artwork previews from prior update:
  - larger preview boxes
  - aspect-ratio-preserving scaling
  - click-to-open full-size modal viewer
- Updated schema/documentation files to stay aligned:
  - models.py
  - Database Dictonary.md
  - canonical DB utility schema/migration logic


File Contents

# Content
1 """SQLAlchemy schema definitions for the current Gromulus SQLite database.
2
3 This module is intentionally written with SQLAlchemy Core ``Table`` objects
4 instead of ORM declarative classes so it can represent tables that do not
5 have primary keys (for example ``no_intro_main`` and ``tosec_main``).
6 """
7
8 from sqlalchemy import (
9 Column,
10 ForeignKey,
11 Index,
12 Integer,
13 MetaData,
14 Table,
15 Text,
16 UniqueConstraint,
17 )
18
19
20
21 metadata = MetaData()
22
23
24 main_app_system = Table(
25 "main_app_system",
26 metadata,
27 Column("id", Integer, primary_key=True, autoincrement=True, nullable=False),
28 Column("name", Text),
29 Column("short_name", Text),
30 Column("relative_file_path", Text),
31 )
32
33
34 main_app = Table(
35 "main_app",
36 metadata,
37 Column("id", Integer, primary_key=True, autoincrement=True, nullable=False),
38 Column("game_name", Text),
39 Column("game_name_scraped", Text),
40 Column("container_file_name", Text),
41 Column("description", Text),
42 Column("description_scraped", Text),
43 Column("system_console", Integer),
44 Column("system_console_scraped", Text),
45 Column("path_to_screenshot_box", Text),
46 Column("path_to_screenshot_title", Text),
47 Column("path_to_screenshot_ingame", Text),
48 Column("path_to_video", Text),
49 Column("user_notes", Text),
50 Column("container_md5_hash", Text),
51 Column("version", Text),
52 Column("favorite_game", Integer),
53 Column("release_date", Text),
54 Column("release_date_scraped", Text),
55 Column("game_genre", Text),
56 Column("game_genre_scraped", Text),
57 Column("cooperative", Text),
58 Column("cooperative_scraped", Text),
59 Column("max_players", Text),
60 Column("max_players_scraped", Text),
61 )
62
63
64 main_app_file_hash = Table(
65 "main_app_file_hash",
66 metadata,
67 Column("id", Integer, primary_key=True, autoincrement=True, nullable=False),
68 Column("file_name", Text),
69 Column("file_md5_hash", Text),
70 Column("container_file_id", Integer, ForeignKey("main_app.id"), nullable=False),
71 )
72
73
74 no_intro_system = Table(
75 "no_intro_system",
76 metadata,
77 Column("id", Integer, primary_key=True, nullable=False),
78 Column("name", Text),
79 Column("description", Text),
80 Column("dat_version", Text),
81 )
82
83
84 no_intro_main = Table(
85 "no_intro_main",
86 metadata,
87 Column("game_name", Text),
88 Column("no_intro_id", Text),
89 Column("clone_of_id", Text),
90 Column("description", Text),
91 Column("rom_name", Text),
92 Column("crc", Text),
93 Column("md5", Text),
94 Column("sha1", Text),
95 Column("sha256", Text),
96 Column("status", Text),
97 Column("no_intro_system_id", Integer, ForeignKey("no_intro_system.id"), nullable=False),
98 Column("app_system_id", Integer),
99 )
100
101
102 tosec_main = Table(
103 "tosec_main",
104 metadata,
105 Column("game_name", Text),
106 Column("description", Text),
107 Column("rom_name", Text),
108 Column("crc", Text),
109 Column("md5", Text),
110 Column("sha1", Text),
111 Column("system_id", Integer, ForeignKey("no_intro_system.id"), nullable=False),
112 Column("app_system_id", Integer),
113 )
114
115
116 dat_import_history = Table(
117 "dat_import_history",
118 metadata,
119 Column("id", Integer, primary_key=True, autoincrement=True),
120 Column("app_system_id", Integer, ForeignKey("main_app_system.id"), nullable=False),
121 Column("source", Text, nullable=False),
122 Column("dat_name", Text),
123 Column("dat_description", Text),
124 Column("dat_version", Text),
125 Column("imported_at", Text, nullable=False),
126 Column("entry_count", Integer, nullable=False, default=0),
127 UniqueConstraint("app_system_id", "source", name="uq_dat_import_history_system_source"),
128 )
129
130
131 Index("idx_main_app_md5", main_app.c.container_md5_hash)
132 Index("idx_main_app_system", main_app.c.system_console)
133 Index("idx_no_intro_md5", no_intro_main.c.md5)
134 Index("idx_tosec_md5", tosec_main.c.md5)
135 Index("idx_no_intro_system_md5", no_intro_main.c.app_system_id, no_intro_main.c.md5)
136 Index("idx_tosec_system_md5", tosec_main.c.app_system_id, tosec_main.c.md5)
137 Index("idx_dat_import_system_source", dat_import_history.c.app_system_id, dat_import_history.c.source)
138
139
140 __all__ = [
141 "metadata",
142 "main_app_system",
143 "main_app",
144 "main_app_file_hash",
145 "no_intro_system",
146 "no_intro_main",
147 "tosec_main",
148 "dat_import_history",
149 ]