QIDNLF commited on
Commit
e15465f
·
verified ·
1 Parent(s): d706f51

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +72 -36
app.py CHANGED
@@ -61,6 +61,7 @@ def fetch_available_standards():
61
  # ==========================================
62
  # 2. UI Component Handlers
63
  # ==========================================
 
64
  def load_initial_standards():
65
  return gr.Dropdown(choices=fetch_available_standards())
66
 
@@ -70,13 +71,17 @@ def update_version_dropdown(standard):
70
  versions = sorted(set(d["version"] for d in db_registry if d["standard"] == standard))
71
  return gr.Dropdown(choices=versions)
72
 
 
73
  def update_base_category_dropdown(standard, version):
74
  if not standard or not version:
75
- return gr.update(choices=[], value=None, interactive=False)
76
 
77
  choices = ["ALL"]
 
 
78
  db_path = os.path.join(UPLOAD_DIR, f"{standard}_{version}.db")
79
- if not os.path.exists(db_path): return gr.update(choices=choices)
 
80
 
81
  try:
82
  conn = sqlite3.connect(db_path)
@@ -88,16 +93,17 @@ def update_base_category_dropdown(standard, version):
88
  if main_table not in valid_tables:
89
  main_table = valid_tables[0] if valid_tables else None
90
 
91
- pattern = re.compile(f"^{standard}[_\\s-]*{version}[_\\s-]*", re.IGNORECASE)
92
- for t in valid_tables:
93
- if t == main_table: continue
94
- short_name = pattern.sub("", t).strip(" _")
95
- if short_name and short_name not in choices:
96
- choices.append(short_name)
97
- elif t not in choices:
98
- choices.append(t)
99
-
100
  if main_table:
 
 
 
 
 
 
 
 
 
 
101
  cols = pd.read_sql(f"PRAGMA table_info([{main_table}])", conn)['name'].tolist()
102
  lower_cols = [c.lower() for c in cols]
103
  if 'chapter' in lower_cols and 'category' in lower_cols:
@@ -110,12 +116,22 @@ def update_base_category_dropdown(standard, version):
110
  ca = str(row[ca_col]).strip()
111
  if ch and ca and ch.lower() not in ['none', 'nan'] and ca.lower() not in ['none', 'nan']:
112
  choices.append(f"{ch}.{ca}")
 
 
 
 
 
 
 
 
 
 
113
  conn.close()
114
  except Exception:
115
  import traceback
116
  traceback.print_exc()
117
 
118
- return gr.update(choices=choices, value=None, interactive=True)
119
 
120
  def update_comp_standard_dropdown(base_std, base_ver):
121
  if not base_std or not base_ver:
@@ -147,13 +163,35 @@ def update_comp_version_dropdown(base_std, base_ver, comp_std):
147
  except Exception:
148
  return gr.update(choices=[], value=None, interactive=False)
149
 
 
150
  def update_comp_category_dropdown(base_std, base_ver, base_cat, comp_std, comp_ver):
151
  if not all([base_std, base_ver, base_cat, comp_std, comp_ver]):
152
- return gr.update(choices=[], value=None, interactive=False)
153
 
154
  base_type = "Main" if not base_cat or base_cat == "ALL" or "." in base_cat else base_cat
 
155
 
156
  try:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  conn = sqlite3.connect(os.path.join(UPLOAD_DIR, "mapping.db"))
158
  query = """
159
  SELECT DISTINCT TRIM(Comp_Type) AS Comp_Type
@@ -169,22 +207,14 @@ def update_comp_category_dropdown(base_std, base_ver, base_cat, comp_std, comp_v
169
 
170
  allowed_types = df['Comp_Type'].dropna().tolist()
171
  if not allowed_types:
172
- return gr.update(choices=[], value=None)
173
 
174
  final_choices = []
175
  if "Main" in allowed_types:
176
  final_choices.append("ALL")
177
- comp_db_path = os.path.join(UPLOAD_DIR, f"{comp_std}_{comp_ver}.db")
178
-
179
  if os.path.exists(comp_db_path):
 
180
  c_conn = sqlite3.connect(comp_db_path)
181
- c_tables = pd.read_sql("SELECT name FROM sqlite_master WHERE type='table';", c_conn)['name'].tolist()
182
- c_valid_tables = [t for t in c_tables if t.lower() not in ['mapping_registry', 'mapping_table', 'table_config', 'sqlite_sequence']]
183
-
184
- c_main_table = f"{comp_std}_{comp_ver}"
185
- if c_main_table not in c_valid_tables:
186
- c_main_table = c_valid_tables[0] if c_valid_tables else None
187
-
188
  if c_main_table:
189
  cols = pd.read_sql(f"PRAGMA table_info([{c_main_table}])", c_conn)['name'].tolist()
190
  lower_cols = [c.lower() for c in cols]
@@ -203,18 +233,20 @@ def update_comp_category_dropdown(base_std, base_ver, base_cat, comp_std, comp_v
203
  for t in allowed_types:
204
  if t != "Main": final_choices.append(t)
205
 
206
- return gr.update(choices=final_choices, value=final_choices[0] if final_choices else None, interactive=True)
207
 
208
  except Exception as e:
209
  import traceback
210
  traceback.print_exc()
211
- return gr.update(choices=[], value=None)
212
 
213
  def reset_base_selections():
214
- return gr.update(value=None), gr.update(choices=[], value=None), gr.update(choices=[], value=None)
 
215
 
216
  def reset_comp_selections():
217
- return gr.update(value=None), gr.update(choices=[], value=None), gr.update(choices=[], value=None)
 
218
 
219
 
220
  # ==========================================
@@ -536,9 +568,6 @@ def execute_unified_search(base_std, base_ver, base_cat, comp_std, comp_ver, com
536
  return pd.DataFrame({"Error": [f"시스템 오류 발생: {str(e)}"]})
537
 
538
 
539
- # ==========================================
540
- # 4. UI Layout & Event Binding
541
- # ==========================================
542
  with gr.Blocks() as demo:
543
  gr.Markdown("# 📜 Regulation Viewer")
544
 
@@ -547,6 +576,8 @@ with gr.Blocks() as demo:
547
  with gr.Column():
548
  base_standard = gr.Dropdown(label="Standard")
549
  base_version = gr.Dropdown(label="Version")
 
 
550
 
551
  with gr.Row(elem_classes="reset-row"):
552
  base_category = gr.Dropdown(label="Category", scale=4)
@@ -556,12 +587,13 @@ with gr.Blocks() as demo:
556
  with gr.Column():
557
  comp_standard = gr.Dropdown(label="Standard", choices=[])
558
  comp_version = gr.Dropdown(label="Version", choices=[])
 
 
559
 
560
  with gr.Row(elem_classes="reset-row"):
561
  comp_category = gr.Dropdown(label="Category", choices=[], scale=4)
562
  comp_reset_btn = gr.Button("↺ 초기화", scale=1)
563
 
564
- # 누락되었던 조회 버튼과 필터 체크박스 복구
565
  with gr.Row(elem_id="search_row"):
566
  search_btn = gr.Button("🔍 조회", variant="primary", scale=10)
567
  diff_filter_cb = gr.Checkbox(label="💡 변경된 내용만 보기", value=False, elem_id="diff_cb_item", container=False, scale=1)
@@ -570,15 +602,18 @@ with gr.Blocks() as demo:
570
 
571
  demo.load(fn=load_initial_standards, inputs=None, outputs=base_standard)
572
 
 
573
  base_standard.change(fn=update_version_dropdown, inputs=[base_standard], outputs=[base_version])
574
- base_version.change(fn=update_base_category_dropdown, inputs=[base_standard, base_version], outputs=[base_category])
575
 
576
  base_version.change(fn=update_comp_standard_dropdown, inputs=[base_standard, base_version], outputs=[comp_standard])
577
  comp_standard.change(fn=update_comp_version_dropdown, inputs=[base_standard, base_version, comp_standard], outputs=[comp_version])
578
 
579
  comp_change_triggers = [base_standard, base_version, base_category, comp_standard, comp_version]
580
- base_category.change(fn=update_comp_category_dropdown, inputs=comp_change_triggers, outputs=[comp_category])
581
- comp_version.change(fn=update_comp_category_dropdown, inputs=comp_change_triggers, outputs=[comp_category])
 
 
582
 
583
  search_btn.click(
584
  fn=execute_unified_search,
@@ -592,8 +627,9 @@ with gr.Blocks() as demo:
592
  outputs=[output_df]
593
  )
594
 
595
- base_reset_btn.click(fn=reset_base_selections, inputs=None, outputs=[base_standard, base_version, base_category])
596
- comp_reset_btn.click(fn=reset_comp_selections, inputs=None, outputs=[comp_standard, comp_version, comp_category])
 
597
 
598
 
599
  # ==========================================
 
61
  # ==========================================
62
  # 2. UI Component Handlers
63
  # ==========================================
64
+
65
  def load_initial_standards():
66
  return gr.Dropdown(choices=fetch_available_standards())
67
 
 
71
  versions = sorted(set(d["version"] for d in db_registry if d["standard"] == standard))
72
  return gr.Dropdown(choices=versions)
73
 
74
+ # ⬇️ [수정] Version이 선택되면 Category와 함께 Status 값도 같이 리턴합니다.
75
  def update_base_category_dropdown(standard, version):
76
  if not standard or not version:
77
+ return gr.update(choices=[], value=None, interactive=False), gr.update(value="")
78
 
79
  choices = ["ALL"]
80
+ status_value = "" # Status 기본값
81
+
82
  db_path = os.path.join(UPLOAD_DIR, f"{standard}_{version}.db")
83
+ if not os.path.exists(db_path):
84
+ return gr.update(choices=choices), gr.update(value="")
85
 
86
  try:
87
  conn = sqlite3.connect(db_path)
 
93
  if main_table not in valid_tables:
94
  main_table = valid_tables[0] if valid_tables else None
95
 
 
 
 
 
 
 
 
 
 
96
  if main_table:
97
+ # 💡 [핵심 추가] DB에서 Status 값을 읽어옵니다.
98
+ try:
99
+ cols_check = pd.read_sql(f"PRAGMA table_info([{main_table}])", conn)['name'].tolist()
100
+ if "Status" in cols_check or "status" in cols_check:
101
+ status_df = pd.read_sql(f"SELECT Status FROM [{main_table}] WHERE Status IS NOT NULL AND Status != '' LIMIT 1", conn)
102
+ if not status_df.empty:
103
+ status_value = str(status_df.iloc[0]['Status'])
104
+ except Exception:
105
+ pass
106
+
107
  cols = pd.read_sql(f"PRAGMA table_info([{main_table}])", conn)['name'].tolist()
108
  lower_cols = [c.lower() for c in cols]
109
  if 'chapter' in lower_cols and 'category' in lower_cols:
 
116
  ca = str(row[ca_col]).strip()
117
  if ch and ca and ch.lower() not in ['none', 'nan'] and ca.lower() not in ['none', 'nan']:
118
  choices.append(f"{ch}.{ca}")
119
+
120
+ pattern = re.compile(f"^{standard}[_\\s-]*{version}[_\\s-]*", re.IGNORECASE)
121
+ for t in valid_tables:
122
+ if t == main_table: continue
123
+ short_name = pattern.sub("", t).strip(" _")
124
+ if short_name and short_name not in choices:
125
+ choices.append(short_name)
126
+ elif t not in choices:
127
+ choices.append(t)
128
+
129
  conn.close()
130
  except Exception:
131
  import traceback
132
  traceback.print_exc()
133
 
134
+ return gr.update(choices=choices, value=None, interactive=True), gr.update(value=status_value)
135
 
136
  def update_comp_standard_dropdown(base_std, base_ver):
137
  if not base_std or not base_ver:
 
163
  except Exception:
164
  return gr.update(choices=[], value=None, interactive=False)
165
 
166
+ # ⬇️ [수정] 비교 법규에서도 Category 갱신 시 Status를 읽어옵니다.
167
  def update_comp_category_dropdown(base_std, base_ver, base_cat, comp_std, comp_ver):
168
  if not all([base_std, base_ver, base_cat, comp_std, comp_ver]):
169
+ return gr.update(choices=[], value=None, interactive=False), gr.update(value="")
170
 
171
  base_type = "Main" if not base_cat or base_cat == "ALL" or "." in base_cat else base_cat
172
+ status_value = ""
173
 
174
  try:
175
+ # Status 읽기
176
+ comp_db_path = os.path.join(UPLOAD_DIR, f"{comp_std}_{comp_ver}.db")
177
+ if os.path.exists(comp_db_path):
178
+ c_conn = sqlite3.connect(comp_db_path)
179
+ c_tables = pd.read_sql("SELECT name FROM sqlite_master WHERE type='table';", c_conn)['name'].tolist()
180
+ c_valid_tables = [t for t in c_tables if t.lower() not in ['mapping_registry', 'mapping_table', 'table_config', 'sqlite_sequence']]
181
+ c_main_table = f"{comp_std}_{comp_ver}"
182
+ if c_main_table not in c_valid_tables:
183
+ c_main_table = c_valid_tables[0] if c_valid_tables else None
184
+
185
+ if c_main_table:
186
+ try:
187
+ cols_check = pd.read_sql(f"PRAGMA table_info([{c_main_table}])", c_conn)['name'].tolist()
188
+ if "Status" in cols_check or "status" in cols_check:
189
+ status_df = pd.read_sql(f"SELECT Status FROM [{c_main_table}] WHERE Status IS NOT NULL AND Status != '' LIMIT 1", c_conn)
190
+ if not status_df.empty:
191
+ status_value = str(status_df.iloc[0]['Status'])
192
+ except Exception:
193
+ pass
194
+
195
  conn = sqlite3.connect(os.path.join(UPLOAD_DIR, "mapping.db"))
196
  query = """
197
  SELECT DISTINCT TRIM(Comp_Type) AS Comp_Type
 
207
 
208
  allowed_types = df['Comp_Type'].dropna().tolist()
209
  if not allowed_types:
210
+ return gr.update(choices=[], value=None), gr.update(value=status_value)
211
 
212
  final_choices = []
213
  if "Main" in allowed_types:
214
  final_choices.append("ALL")
 
 
215
  if os.path.exists(comp_db_path):
216
+ # c_conn is already closed above, reopen if needed
217
  c_conn = sqlite3.connect(comp_db_path)
 
 
 
 
 
 
 
218
  if c_main_table:
219
  cols = pd.read_sql(f"PRAGMA table_info([{c_main_table}])", c_conn)['name'].tolist()
220
  lower_cols = [c.lower() for c in cols]
 
233
  for t in allowed_types:
234
  if t != "Main": final_choices.append(t)
235
 
236
+ return gr.update(choices=final_choices, value=final_choices[0] if final_choices else None, interactive=True), gr.update(value=status_value)
237
 
238
  except Exception as e:
239
  import traceback
240
  traceback.print_exc()
241
+ return gr.update(choices=[], value=None), gr.update(value="")
242
 
243
  def reset_base_selections():
244
+ # Status까지 4개를 리셋
245
+ return gr.update(value=None), gr.update(choices=[], value=None), gr.update(choices=[], value=None), gr.update(value="")
246
 
247
  def reset_comp_selections():
248
+ # Status까지 4개를 리셋
249
+ return gr.update(value=None), gr.update(choices=[], value=None), gr.update(choices=[], value=None), gr.update(value="")
250
 
251
 
252
  # ==========================================
 
568
  return pd.DataFrame({"Error": [f"시스템 오류 발생: {str(e)}"]})
569
 
570
 
 
 
 
571
  with gr.Blocks() as demo:
572
  gr.Markdown("# 📜 Regulation Viewer")
573
 
 
576
  with gr.Column():
577
  base_standard = gr.Dropdown(label="Standard")
578
  base_version = gr.Dropdown(label="Version")
579
+ # ⬇️ [UI 추가] Version과 Category 사이에 Status 칸 추가 (읽기 전용)
580
+ base_status = gr.Textbox(label="Status", interactive=False, lines=1)
581
 
582
  with gr.Row(elem_classes="reset-row"):
583
  base_category = gr.Dropdown(label="Category", scale=4)
 
587
  with gr.Column():
588
  comp_standard = gr.Dropdown(label="Standard", choices=[])
589
  comp_version = gr.Dropdown(label="Version", choices=[])
590
+ # ⬇️ [UI 추가] Version과 Category 사이에 Status 칸 추가 (읽기 전용)
591
+ comp_status = gr.Textbox(label="Status", interactive=False, lines=1)
592
 
593
  with gr.Row(elem_classes="reset-row"):
594
  comp_category = gr.Dropdown(label="Category", choices=[], scale=4)
595
  comp_reset_btn = gr.Button("↺ 초기화", scale=1)
596
 
 
597
  with gr.Row(elem_id="search_row"):
598
  search_btn = gr.Button("🔍 조회", variant="primary", scale=10)
599
  diff_filter_cb = gr.Checkbox(label="💡 변경된 내용만 보기", value=False, elem_id="diff_cb_item", container=False, scale=1)
 
602
 
603
  demo.load(fn=load_initial_standards, inputs=None, outputs=base_standard)
604
 
605
+ # ⬇️ [이벤트 수정] Version이 변경될 때 base_status에도 값을 보냅니다.
606
  base_standard.change(fn=update_version_dropdown, inputs=[base_standard], outputs=[base_version])
607
+ base_version.change(fn=update_base_category_dropdown, inputs=[base_standard, base_version], outputs=[base_category, base_status])
608
 
609
  base_version.change(fn=update_comp_standard_dropdown, inputs=[base_standard, base_version], outputs=[comp_standard])
610
  comp_standard.change(fn=update_comp_version_dropdown, inputs=[base_standard, base_version, comp_standard], outputs=[comp_version])
611
 
612
  comp_change_triggers = [base_standard, base_version, base_category, comp_standard, comp_version]
613
+
614
+ # ⬇️ [이벤트 수정] 비교 법규쪽 갱신 시에도 comp_status에 값을 보냅니다.
615
+ base_category.change(fn=update_comp_category_dropdown, inputs=comp_change_triggers, outputs=[comp_category, comp_status])
616
+ comp_version.change(fn=update_comp_category_dropdown, inputs=comp_change_triggers, outputs=[comp_category, comp_status])
617
 
618
  search_btn.click(
619
  fn=execute_unified_search,
 
627
  outputs=[output_df]
628
  )
629
 
630
+ # ⬇️ [이벤트 수정] 초기화 버튼 누를 때 status도 리셋되도록 4개의 outputs 지정
631
+ base_reset_btn.click(fn=reset_base_selections, inputs=None, outputs=[base_standard, base_version, base_category, base_status])
632
+ comp_reset_btn.click(fn=reset_comp_selections, inputs=None, outputs=[comp_standard, comp_version, comp_category, comp_status])
633
 
634
 
635
  # ==========================================