-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathapp.py
More file actions
187 lines (147 loc) · 5.42 KB
/
app.py
File metadata and controls
187 lines (147 loc) · 5.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
import os
import datetime
from pathlib import Path
import streamlit as st
import pandas as pd
import multiprocessing
from src.FileFinder.FileFinderClass import FileFinder
from src.Database.DBClass import DB
from src.Logger.ColorClass import col
from src.Utils.ParamsLoader import ConfigManager
from src.Utils.TeeHandler import tee_handler
from src.ui.sidebar import render_sidebar
from src.ui.holo_view import render_holo_section
from src.ui.hd_view import render_hd_section
from src.ui.ef_view import render_ef_section
from src.ui.export_view import render_export_section
def get_appdata_db_path() -> Path:
"""
Constructs the database path in the user's AppData/Roaming folder
and ensures the directory exists.
"""
config_path = ConfigManager.get("DB.DB_PATH") or ""
if config_path != "":
return Path(config_path)
# Get AppData\Roaming folder
appdata_path = os.getenv("APPDATA")
# If not set, default to the local dir
if not appdata_path:
return Path("renders.db")
app_dir = Path(appdata_path) / "DopplerManager"
os.makedirs(app_dir, exist_ok=True)
return app_dir / "renders.db"
def get_log_path() -> Path:
"""
Constructs the log file path in the user's AppData/Roaming folder
and ensures the directory exists.
"""
config_path = ConfigManager.get("LOG.LOG_PATH") or ""
if config_path != "":
return Path(config_path)
appdata_path = os.getenv("APPDATA")
# If not set, default to the local dir
if not appdata_path:
return Path("logs")
log_dir = Path(appdata_path) / "DopplerManager" / "logs"
os.makedirs(log_dir, exist_ok=True)
return log_dir / f"log_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.txt"
@st.cache_resource
def initialize_database(db_path):
"""
Connects to the database, instantiates the FileFinder,
and ensures tables are created. This runs only once.
"""
ff_instance = FileFinder(DB(db_path))
ff_instance.CreateDB()
return ff_instance
@st.cache_data
def load_data(query, _ff: FileFinder):
"""
Loads data from the database using the provided SQL query.
Caches the result to avoid redundant database calls.
"""
# try:
# df = pd.read_sql_query(query, _conn)
# return df
# except Exception as e:
# st.error(f"Error while loading data: {e}")
# return pd.DataFrame()
return pd.read_sql_query(query, _ff.DB.SQLconnect)
def main():
"""
Main function to run the Streamlit app.
Acts as a conductor, calling rendering functions in order.
"""
# --- Page Configuration ---
st.set_page_config(page_title="DopplerManager", layout="wide")
# --- Session Log Initialization ---
# This block runs only once per user session.
if "session_log_started" not in st.session_state:
log_path = get_log_path()
# Start the global Tee handler for this session
tee_handler.start(log_path)
st.session_state.session_log_started = True
print(f"--- Session log started at: {log_path} ---")
# --- Initialization ---
try:
DB_FILE = get_appdata_db_path()
if "db_initialized" not in st.session_state:
with st.spinner("Initializing database connection..."):
initialize_database(DB_FILE)
st.session_state.db_initialized = True
st.toast("Database initialized.")
ff = initialize_database(DB_FILE)
# --- UI Rendering ---
render_sidebar(ff)
st.title("DopplerManager")
# --- Data Loading ---
query = """
SELECT
h_data.path AS holo_file,
h_data.tag AS measure_tag,
h_data.created_at AS holo_created_at,
hd.path AS hd_folder,
hd.render_number as hd_render_number,
hd.version AS hd_version,
hd.raw_h5_path AS hd_raw_h5_path,
ef.path AS ef_folder,
ef.render_number AS ef_render_number,
ef.version AS ef_version,
ef.report_path AS ef_report_path,
ef.h5_output AS ef_h5_output,
ef.error_log_path AS error_log_path
FROM
holo_data AS h_data
LEFT JOIN
hd_render AS hd ON h_data.id = hd.holo_id
LEFT JOIN
ef_render AS ef ON hd.id = ef.hd_id
"""
combined_df = load_data(query, ff)
if combined_df.empty:
st.warning(
"The database is empty. Please start by adding a directory in the sidebar and start a scan."
)
return
filtered_by_holo = render_holo_section(combined_df)
st.markdown("---")
filtered_by_hd = render_hd_section(filtered_by_holo)
st.markdown("---")
filtered_by_ef, errored_ef = render_ef_section(filtered_by_hd)
st.markdown("---")
render_export_section(filtered_by_ef, errored_ef)
except Exception:
tee_handler.log_and_reraise()
if __name__ == "__main__":
import sys
if sys.version_info < (3, 13):
print(
f"{col.BOLD}{col.RED}You are using a Python version before 3.13!{col.RES}"
)
print("This could result in failure to load")
print(f"Current version {sys.version}")
sys.exit(1)
# For Windows compatibility in multiprocessing
multiprocessing.freeze_support()
# with Tee(LOG_FILE_PATH):
main()