Update app.py
Browse files
app.py
CHANGED
|
@@ -120,53 +120,45 @@ def update_base_category_dropdown(standard, version):
|
|
| 120 |
return gr.update(choices=choices, value=None, interactive=True)
|
| 121 |
|
| 122 |
def update_comp_standard_dropdown(base_std, base_ver):
|
|
|
|
| 123 |
if not base_std or not base_ver:
|
| 124 |
-
return gr.Dropdown(choices=[], interactive=False)
|
| 125 |
|
| 126 |
try:
|
| 127 |
conn = sqlite3.connect(os.path.join(UPLOAD_DIR, "mapping.db"))
|
|
|
|
| 128 |
query = """
|
| 129 |
-
SELECT DISTINCT Comp_std
|
| 130 |
UNION
|
| 131 |
-
SELECT DISTINCT Base_std
|
| 132 |
"""
|
| 133 |
df = pd.read_sql(query, conn, params=[base_std, base_ver, base_std, base_ver])
|
| 134 |
conn.close()
|
| 135 |
|
| 136 |
-
if df.empty
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
return gr.
|
| 140 |
except Exception:
|
| 141 |
-
return gr.
|
| 142 |
|
| 143 |
def update_comp_version_dropdown(base_std, base_ver, comp_std):
|
| 144 |
-
|
|
|
|
| 145 |
return gr.update(choices=[], value=None, interactive=False)
|
| 146 |
|
| 147 |
try:
|
| 148 |
conn = sqlite3.connect(os.path.join(UPLOAD_DIR, "mapping.db"))
|
| 149 |
query = """
|
| 150 |
-
SELECT DISTINCT Comp_ver
|
| 151 |
UNION
|
| 152 |
-
SELECT DISTINCT Base_ver
|
| 153 |
"""
|
| 154 |
df = pd.read_sql(query, conn, params=[base_std, base_ver, comp_std, base_std, base_ver, comp_std])
|
| 155 |
conn.close()
|
| 156 |
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
if not choices:
|
| 160 |
-
for f in os.listdir(UPLOAD_DIR):
|
| 161 |
-
if f.startswith(comp_std + "_") and f.endswith(".db"):
|
| 162 |
-
ver = f.replace(comp_std + "_", "").replace(".db", "")
|
| 163 |
-
choices.append(ver)
|
| 164 |
-
choices = sorted(list(set(choices)))
|
| 165 |
-
|
| 166 |
-
if not choices:
|
| 167 |
-
return gr.update(choices=[], value=None, interactive=False)
|
| 168 |
-
|
| 169 |
-
return gr.update(choices=choices, value=None, interactive=True)
|
| 170 |
except Exception:
|
| 171 |
return gr.update(choices=[], value=None, interactive=False)
|
| 172 |
|
|
@@ -498,7 +490,7 @@ def execute_unified_search(base_std, base_ver, base_cat, comp_std, comp_ver, com
|
|
| 498 |
|
| 499 |
|
| 500 |
# ==========================================
|
| 501 |
-
# 4. UI Layout & Event Binding
|
| 502 |
# ==========================================
|
| 503 |
with gr.Blocks() as demo:
|
| 504 |
gr.Markdown("# 📜 Regulation Viewer")
|
|
@@ -513,44 +505,92 @@ with gr.Blocks() as demo:
|
|
| 513 |
|
| 514 |
with gr.Accordion("🔄 비교 법규", open=False):
|
| 515 |
with gr.Column():
|
| 516 |
-
|
| 517 |
-
|
| 518 |
-
|
|
|
|
| 519 |
comp_reset_btn = gr.Button("↺ 초기화")
|
| 520 |
|
| 521 |
search_btn = gr.Button("🔍 조회", variant="primary")
|
| 522 |
output_df = gr.Dataframe(wrap=True, interactive=False, datatype="html", max_height=800)
|
| 523 |
|
| 524 |
-
# 초기 로드
|
| 525 |
-
demo.load(load_initial_standards, None, base_standard)
|
| 526 |
|
| 527 |
-
#
|
| 528 |
-
#
|
| 529 |
-
|
| 530 |
-
|
| 531 |
-
|
| 532 |
-
|
| 533 |
-
|
| 534 |
-
|
| 535 |
-
#
|
| 536 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 537 |
|
| 538 |
-
#
|
|
|
|
|
|
|
|
|
|
| 539 |
comp_change_triggers = [base_standard, base_version, base_category, comp_standard, comp_version]
|
| 540 |
|
| 541 |
-
base_category.change(
|
| 542 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 543 |
|
| 544 |
-
#
|
|
|
|
|
|
|
| 545 |
search_btn.click(
|
| 546 |
-
execute_unified_search,
|
| 547 |
inputs=[base_standard, base_version, base_category, comp_standard, comp_version, comp_category],
|
| 548 |
-
outputs=output_df
|
| 549 |
)
|
| 550 |
|
| 551 |
-
|
| 552 |
-
|
| 553 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 554 |
|
| 555 |
|
| 556 |
# ==========================================
|
|
|
|
| 120 |
return gr.update(choices=choices, value=None, interactive=True)
|
| 121 |
|
| 122 |
def update_comp_standard_dropdown(base_std, base_ver):
|
| 123 |
+
"""기준 법규 선택 시, 매핑이 허용된 상대 Standard만 반환"""
|
| 124 |
if not base_std or not base_ver:
|
| 125 |
+
return gr.Dropdown(choices=[], value=None, interactive=False)
|
| 126 |
|
| 127 |
try:
|
| 128 |
conn = sqlite3.connect(os.path.join(UPLOAD_DIR, "mapping.db"))
|
| 129 |
+
# Registry에 등록된 쌍방향(Base<->Comp) 매핑 Standard만 추출
|
| 130 |
query = """
|
| 131 |
+
SELECT DISTINCT Comp_std FROM Mapping_registry WHERE Base_std=? AND Base_ver=?
|
| 132 |
UNION
|
| 133 |
+
SELECT DISTINCT Base_std FROM Mapping_registry WHERE Comp_std=? AND Comp_ver=?
|
| 134 |
"""
|
| 135 |
df = pd.read_sql(query, conn, params=[base_std, base_ver, base_std, base_ver])
|
| 136 |
conn.close()
|
| 137 |
|
| 138 |
+
mapped_stds = sorted(df['Comp_std'].dropna().unique().tolist()) if not df.empty else []
|
| 139 |
+
|
| 140 |
+
# 매핑된 것이 없으면 선택 불가 상태로 반환
|
| 141 |
+
return gr.update(choices=mapped_stds, value=None, interactive=bool(mapped_stds))
|
| 142 |
except Exception:
|
| 143 |
+
return gr.update(choices=[], value=None, interactive=False)
|
| 144 |
|
| 145 |
def update_comp_version_dropdown(base_std, base_ver, comp_std):
|
| 146 |
+
"""선택된 비교 Standard에 대해, 매핑이 허용된 버전만 반환"""
|
| 147 |
+
if not all([base_std, base_ver, comp_std]):
|
| 148 |
return gr.update(choices=[], value=None, interactive=False)
|
| 149 |
|
| 150 |
try:
|
| 151 |
conn = sqlite3.connect(os.path.join(UPLOAD_DIR, "mapping.db"))
|
| 152 |
query = """
|
| 153 |
+
SELECT DISTINCT Comp_ver FROM Mapping_registry WHERE Base_std=? AND Base_ver=? AND Comp_std=?
|
| 154 |
UNION
|
| 155 |
+
SELECT DISTINCT Base_ver FROM Mapping_registry WHERE Comp_std=? AND Comp_ver=? AND Base_std=?
|
| 156 |
"""
|
| 157 |
df = pd.read_sql(query, conn, params=[base_std, base_ver, comp_std, base_std, base_ver, comp_std])
|
| 158 |
conn.close()
|
| 159 |
|
| 160 |
+
mapped_vers = sorted(df['Comp_ver'].dropna().unique().tolist()) if not df.empty else []
|
| 161 |
+
return gr.update(choices=mapped_vers, value=None, interactive=bool(mapped_vers))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 162 |
except Exception:
|
| 163 |
return gr.update(choices=[], value=None, interactive=False)
|
| 164 |
|
|
|
|
| 490 |
|
| 491 |
|
| 492 |
# ==========================================
|
| 493 |
+
# 4. UI Layout & Event Binding (화면 구성 및 이벤트 연결)
|
| 494 |
# ==========================================
|
| 495 |
with gr.Blocks() as demo:
|
| 496 |
gr.Markdown("# 📜 Regulation Viewer")
|
|
|
|
| 505 |
|
| 506 |
with gr.Accordion("🔄 비교 법규", open=False):
|
| 507 |
with gr.Column():
|
| 508 |
+
# 초기에는 선택지를 비워둠 (기준 법규 선택 전까지 철저히 통제)
|
| 509 |
+
comp_standard = gr.Dropdown(label="Standard", choices=[])
|
| 510 |
+
comp_version = gr.Dropdown(label="Version", choices=[])
|
| 511 |
+
comp_category = gr.Dropdown(label="Category", choices=[])
|
| 512 |
comp_reset_btn = gr.Button("↺ 초기화")
|
| 513 |
|
| 514 |
search_btn = gr.Button("🔍 조회", variant="primary")
|
| 515 |
output_df = gr.Dataframe(wrap=True, interactive=False, datatype="html", max_height=800)
|
| 516 |
|
|
|
|
|
|
|
| 517 |
|
| 518 |
+
# --------------------------------------------------------
|
| 519 |
+
# 🔗 이벤트 바인딩 (데이터 흐름도)
|
| 520 |
+
# --------------------------------------------------------
|
| 521 |
+
|
| 522 |
+
# [0] 앱 초기 로드
|
| 523 |
+
demo.load(fn=load_initial_standards, inputs=None, outputs=base_standard)
|
| 524 |
+
|
| 525 |
+
# --------------------------------------------------------
|
| 526 |
+
# [1] 기준 법규 흐름 (Base Flow)
|
| 527 |
+
# --------------------------------------------------------
|
| 528 |
+
# ① 기준 Standard 선택 -> 기준 Version 목록 갱신
|
| 529 |
+
base_standard.change(
|
| 530 |
+
fn=update_version_dropdown,
|
| 531 |
+
inputs=[base_standard],
|
| 532 |
+
outputs=[base_version]
|
| 533 |
+
)
|
| 534 |
+
# ② 기준 Version 선택 -> 기준 Category 목록 갱신 (DB 전체 목록)
|
| 535 |
+
base_version.change(
|
| 536 |
+
fn=update_base_category_dropdown,
|
| 537 |
+
inputs=[base_standard, base_version],
|
| 538 |
+
outputs=[base_category]
|
| 539 |
+
)
|
| 540 |
+
|
| 541 |
+
# --------------------------------------------------------
|
| 542 |
+
# [2] 비교 법규 통제 흐름 (Base -> Comp Flow)
|
| 543 |
+
# --------------------------------------------------------
|
| 544 |
+
# ③ 기준 Version이 결정되면 -> 허용된 '비교 Standard' 목록 갱신
|
| 545 |
+
base_version.change(
|
| 546 |
+
fn=update_comp_standard_dropdown,
|
| 547 |
+
inputs=[base_standard, base_version],
|
| 548 |
+
outputs=[comp_standard]
|
| 549 |
+
)
|
| 550 |
+
# ④ 비교 Standard 선택 -> 허용된 '비교 Version' 목록 갱신
|
| 551 |
+
comp_standard.change(
|
| 552 |
+
fn=update_comp_version_dropdown,
|
| 553 |
+
inputs=[base_standard, base_version, comp_standard],
|
| 554 |
+
outputs=[comp_version]
|
| 555 |
+
)
|
| 556 |
|
| 557 |
+
# --------------------------------------------------------
|
| 558 |
+
# [3] 최종 카테고리 통제 (Registry 필터링)
|
| 559 |
+
# --------------------------------------------------------
|
| 560 |
+
# ⑤ 기준 Category가 바뀌거나, 비교 Version이 바뀌면 -> 허용된 '비교 Category' 목록 갱신
|
| 561 |
comp_change_triggers = [base_standard, base_version, base_category, comp_standard, comp_version]
|
| 562 |
|
| 563 |
+
base_category.change(
|
| 564 |
+
fn=update_comp_category_dropdown,
|
| 565 |
+
inputs=comp_change_triggers,
|
| 566 |
+
outputs=[comp_category]
|
| 567 |
+
)
|
| 568 |
+
comp_version.change(
|
| 569 |
+
fn=update_comp_category_dropdown,
|
| 570 |
+
inputs=comp_change_triggers,
|
| 571 |
+
outputs=[comp_category]
|
| 572 |
+
)
|
| 573 |
|
| 574 |
+
# --------------------------------------------------------
|
| 575 |
+
# [4] 버튼 동작 (Action)
|
| 576 |
+
# --------------------------------------------------------
|
| 577 |
search_btn.click(
|
| 578 |
+
fn=execute_unified_search,
|
| 579 |
inputs=[base_standard, base_version, base_category, comp_standard, comp_version, comp_category],
|
| 580 |
+
outputs=[output_df]
|
| 581 |
)
|
| 582 |
|
| 583 |
+
base_reset_btn.click(
|
| 584 |
+
fn=reset_base_selections,
|
| 585 |
+
inputs=None,
|
| 586 |
+
outputs=[base_standard, base_version, base_category]
|
| 587 |
+
)
|
| 588 |
+
|
| 589 |
+
comp_reset_btn.click(
|
| 590 |
+
fn=reset_comp_selections,
|
| 591 |
+
inputs=None,
|
| 592 |
+
outputs=[comp_standard, comp_version, comp_category]
|
| 593 |
+
)
|
| 594 |
|
| 595 |
|
| 596 |
# ==========================================
|