ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/ns_dev/Python/NinoCode/Active_prgs/Gromulus/models.py
Revision: 990
Committed: Mon Mar 9 21:20:37 2026 UTC (2 weeks, 5 days ago) by nino.borges
Content type: text/x-python
File size: 4296 byte(s)
Log Message:
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:
  - 
  - , 
  - , 
  - , 
  - , 
- Wired UI to user-first metadata precedence with  fallback for release date, genre, cooperative, max players, and description.
- Added release date display/storage conversion:
  - GUI display 
  - DB storage 
- Refactored main game info panel:
  - moved hash/file/No-Intro/TOSEC detail fields into  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:
  - 
  - 
  - canonical DB utility schema/migration logic

File Contents

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