Update app.py
Browse files
app.py
CHANGED
|
@@ -5,7 +5,6 @@ import os
|
|
| 5 |
import re
|
| 6 |
import base64
|
| 7 |
import difflib
|
| 8 |
-
import traceback
|
| 9 |
|
| 10 |
# ==========================================
|
| 11 |
# 1. Environment Setup & Data Helpers
|
|
@@ -57,15 +56,12 @@ def fetch_available_standards():
|
|
| 57 |
|
| 58 |
return sorted(list(set([d["standard"] for d in db_registry])))
|
| 59 |
|
| 60 |
-
# ==========================================
|
| 61 |
-
# ๐ก [๋ณต๊ตฌ๋ ํต์ฌ ํจ์] ์ด ๋ถ๋ถ์ ์ถ๊ฐํด ์ฃผ์ธ์!
|
| 62 |
-
# ==========================================
|
| 63 |
def fetch_database_records(std, ver, cat, table_type):
|
| 64 |
try:
|
| 65 |
db_path = os.path.join(UPLOAD_DIR, f"{std}_{ver}.db")
|
| 66 |
conn = sqlite3.connect(db_path)
|
|
|
|
| 67 |
|
| 68 |
-
# Table_Config ์ฝ์ด์ค๊ธฐ
|
| 69 |
conn_map = sqlite3.connect(os.path.join(UPLOAD_DIR, "mapping.db"))
|
| 70 |
config_df = pd.read_sql("SELECT * FROM Table_Config WHERE TRIM(Table_Type)=?", conn_map, params=[table_type.strip()])
|
| 71 |
conn_map.close()
|
|
@@ -76,7 +72,6 @@ def fetch_database_records(std, ver, cat, table_type):
|
|
| 76 |
anchors = [x.strip() for x in config_df.iloc[0]['Anchor_Column'].split(',')]
|
| 77 |
displays = [x.strip() for x in config_df.iloc[0]['Display_Columns'].split(',')] if pd.notna(config_df.iloc[0]['Display_Columns']) else anchors
|
| 78 |
|
| 79 |
-
# ๋ฉ์ธ ํ
์ด๋ธ ์ฐพ๊ธฐ
|
| 80 |
tables = pd.read_sql("SELECT name FROM sqlite_master WHERE type='table';", conn)['name'].tolist()
|
| 81 |
valid_tables = [t for t in tables if t.lower() not in ['mapping_registry', 'mapping_table', 'table_config', 'sqlite_sequence']]
|
| 82 |
main_table = f"{std}_{ver}"
|
|
@@ -88,7 +83,6 @@ def fetch_database_records(std, ver, cat, table_type):
|
|
| 88 |
|
| 89 |
query = f"SELECT * FROM [{main_table}]"
|
| 90 |
|
| 91 |
-
# ์นดํ
๊ณ ๋ฆฌ ํํฐ๋ง
|
| 92 |
cols = pd.read_sql(f"PRAGMA table_info([{main_table}])", conn)['name'].tolist()
|
| 93 |
lower_cols = [c.lower() for c in cols]
|
| 94 |
|
|
@@ -109,7 +103,6 @@ def fetch_database_records(std, ver, cat, table_type):
|
|
| 109 |
df = pd.read_sql(query, conn)
|
| 110 |
conn.close()
|
| 111 |
|
| 112 |
-
# ํ๋ฉด์ ๋ณด์ฌ์ค ์ด ์ ๋ฆฌ
|
| 113 |
final_cols = []
|
| 114 |
for d in displays:
|
| 115 |
for c in df.columns:
|
|
@@ -122,6 +115,9 @@ def fetch_database_records(std, ver, cat, table_type):
|
|
| 122 |
if not final_cols:
|
| 123 |
return df, real_anchors
|
| 124 |
|
|
|
|
|
|
|
|
|
|
| 125 |
return df[final_cols], real_anchors
|
| 126 |
|
| 127 |
except Exception as e:
|
|
@@ -133,9 +129,6 @@ def generate_html_diff(text1, text2):
|
|
| 133 |
try:
|
| 134 |
s1, s2 = str(text1), str(text2)
|
| 135 |
|
| 136 |
-
# ========================================================
|
| 137 |
-
# ๐ก๏ธ [์์ ์ฅ์น 1] ๊ธ์๊ฐ ๋๋ฌด ๊ธธ๋ฉด (์: 1000์ ์ด์) ์ปดํจํฐ ํฐ์ง ๋ฐฉ์ง
|
| 138 |
-
# ========================================================
|
| 139 |
if len(s1) > 1000 or len(s2) > 1000:
|
| 140 |
return s1, s2
|
| 141 |
|
|
@@ -143,17 +136,13 @@ def generate_html_diff(text1, text2):
|
|
| 143 |
if not words1 or not words2:
|
| 144 |
return s1, s2
|
| 145 |
|
| 146 |
-
# ========================================================
|
| 147 |
-
# ๐ก๏ธ [์์ ์ฅ์น 2] ํ๊ธ vs ์์ด์ฒ๋ผ ๊ฒน์น๋ ๋จ์ด๊ฐ 5%๋ ์ ๋๋ฉด ๋น๊ต ์๋ต
|
| 148 |
-
# ========================================================
|
| 149 |
common_words = set(words1) & set(words2)
|
| 150 |
if len(common_words) / min(len(words1), len(words2)) < 0.05:
|
| 151 |
return s1, s2
|
| 152 |
|
| 153 |
-
# ์์ ๊ฒ์ฌ๋ฅผ ํต๊ณผํ ์ง์ง ๋น์ทํ ํ
์คํธ๋ค๋ง ์ด๊ณ ์ ๋น๊ต!
|
| 154 |
matcher = difflib.SequenceMatcher(None, words1, words2)
|
| 155 |
-
|
| 156 |
res1, res2 = [], []
|
|
|
|
| 157 |
for tag, i1, i2, j1, j2 in matcher.get_opcodes():
|
| 158 |
if tag == 'replace':
|
| 159 |
res1.append(f"<span style='color:#ff4d4f; font-weight:bold;'>{' '.join(words1[i1:i2])}</span>")
|
|
@@ -169,10 +158,10 @@ def generate_html_diff(text1, text2):
|
|
| 169 |
return " ".join(res1), " ".join(res2)
|
| 170 |
except Exception:
|
| 171 |
return text1, text2
|
|
|
|
| 172 |
# ==========================================
|
| 173 |
# 2. UI Component Handlers
|
| 174 |
# ==========================================
|
| 175 |
-
|
| 176 |
def load_initial_standards():
|
| 177 |
return gr.Dropdown(choices=fetch_available_standards())
|
| 178 |
|
|
@@ -182,13 +171,12 @@ def update_version_dropdown(standard):
|
|
| 182 |
versions = sorted(set(d["version"] for d in db_registry if d["standard"] == standard))
|
| 183 |
return gr.Dropdown(choices=versions)
|
| 184 |
|
| 185 |
-
# โฌ๏ธ [์์ ] Version์ด ์ ํ๋๋ฉด Category์ ํจ๊ป Status ๊ฐ๋ ๊ฐ์ด ๋ฆฌํดํฉ๋๋ค.
|
| 186 |
def update_base_category_dropdown(standard, version):
|
| 187 |
if not standard or not version:
|
| 188 |
return gr.update(choices=[], value=None, interactive=False), gr.update(value="")
|
| 189 |
|
| 190 |
choices = ["ALL"]
|
| 191 |
-
status_value = ""
|
| 192 |
|
| 193 |
db_path = os.path.join(UPLOAD_DIR, f"{standard}_{version}.db")
|
| 194 |
if not os.path.exists(db_path):
|
|
@@ -197,15 +185,12 @@ def update_base_category_dropdown(standard, version):
|
|
| 197 |
try:
|
| 198 |
conn = sqlite3.connect(db_path)
|
| 199 |
tables = pd.read_sql("SELECT name FROM sqlite_master WHERE type='table';", conn)['name'].tolist()
|
| 200 |
-
|
| 201 |
valid_tables = [t for t in tables if t.lower() not in ['mapping_registry', 'mapping_table', 'table_config', 'sqlite_sequence']]
|
| 202 |
-
|
| 203 |
main_table = f"{standard}_{version}"
|
| 204 |
if main_table not in valid_tables:
|
| 205 |
main_table = valid_tables[0] if valid_tables else None
|
| 206 |
|
| 207 |
if main_table:
|
| 208 |
-
# ๐ก [ํต์ฌ ์ถ๊ฐ] DB์์ Status ๊ฐ์ ์ฝ์ด์ต๋๋ค.
|
| 209 |
try:
|
| 210 |
cols_check = pd.read_sql(f"PRAGMA table_info([{main_table}])", conn)['name'].tolist()
|
| 211 |
if "Status" in cols_check or "status" in cols_check:
|
|
@@ -239,8 +224,7 @@ def update_base_category_dropdown(standard, version):
|
|
| 239 |
|
| 240 |
conn.close()
|
| 241 |
except Exception:
|
| 242 |
-
|
| 243 |
-
traceback.print_exc()
|
| 244 |
|
| 245 |
return gr.update(choices=choices, value=None, interactive=True), gr.update(value=status_value)
|
| 246 |
|
|
@@ -274,7 +258,6 @@ def update_comp_version_dropdown(base_std, base_ver, comp_std):
|
|
| 274 |
except Exception:
|
| 275 |
return gr.update(choices=[], value=None, interactive=False)
|
| 276 |
|
| 277 |
-
# โฌ๏ธ [์์ ] ๋น๊ต ๋ฒ๊ท์์๋ Category ๊ฐฑ์ ์ Status๋ฅผ ์ฝ์ด์ต๋๋ค.
|
| 278 |
def update_comp_category_dropdown(base_std, base_ver, base_cat, comp_std, comp_ver):
|
| 279 |
if not all([base_std, base_ver, base_cat, comp_std, comp_ver]):
|
| 280 |
return gr.update(choices=[], value=None, interactive=False), gr.update(value="")
|
|
@@ -283,7 +266,6 @@ def update_comp_category_dropdown(base_std, base_ver, base_cat, comp_std, comp_v
|
|
| 283 |
status_value = ""
|
| 284 |
|
| 285 |
try:
|
| 286 |
-
# Status ์ฝ๊ธฐ
|
| 287 |
comp_db_path = os.path.join(UPLOAD_DIR, f"{comp_std}_{comp_ver}.db")
|
| 288 |
if os.path.exists(comp_db_path):
|
| 289 |
c_conn = sqlite3.connect(comp_db_path)
|
|
@@ -324,7 +306,6 @@ def update_comp_category_dropdown(base_std, base_ver, base_cat, comp_std, comp_v
|
|
| 324 |
if "Main" in allowed_types:
|
| 325 |
final_choices.append("ALL")
|
| 326 |
if os.path.exists(comp_db_path):
|
| 327 |
-
# c_conn is already closed above, reopen if needed
|
| 328 |
c_conn = sqlite3.connect(comp_db_path)
|
| 329 |
if c_main_table:
|
| 330 |
cols = pd.read_sql(f"PRAGMA table_info([{c_main_table}])", c_conn)['name'].tolist()
|
|
@@ -346,20 +327,18 @@ def update_comp_category_dropdown(base_std, base_ver, base_cat, comp_std, comp_v
|
|
| 346 |
|
| 347 |
return gr.update(choices=final_choices, value=final_choices[0] if final_choices else None, interactive=True), gr.update(value=status_value)
|
| 348 |
|
| 349 |
-
except Exception
|
| 350 |
-
import traceback
|
| 351 |
-
traceback.print_exc()
|
| 352 |
return gr.update(choices=[], value=None), gr.update(value="")
|
| 353 |
|
| 354 |
def reset_base_selections():
|
| 355 |
-
# Status๊น์ง 4๊ฐ๋ฅผ ๋ฆฌ์
|
| 356 |
return gr.update(value=None), gr.update(choices=[], value=None), gr.update(choices=[], value=None), gr.update(value="")
|
| 357 |
|
| 358 |
def reset_comp_selections():
|
| 359 |
-
# Status๊น์ง 4๊ฐ๋ฅผ ๋ฆฌ์
|
| 360 |
return gr.update(value=None), gr.update(choices=[], value=None), gr.update(choices=[], value=None), gr.update(value="")
|
| 361 |
|
| 362 |
-
|
|
|
|
|
|
|
| 363 |
def execute_unified_search(base_std, base_ver, base_cat, comp_std, comp_ver, comp_cat, mapped_only, diff_only):
|
| 364 |
try:
|
| 365 |
def get_type_by_cat(cat):
|
|
@@ -433,9 +412,6 @@ def execute_unified_search(base_std, base_ver, base_cat, comp_std, comp_ver, com
|
|
| 433 |
df_base['merge_key'] = df_base[real_anchors_b].apply(lambda row: '-'.join([clean_key_val(x) for x in row]), axis=1)
|
| 434 |
df_comp['merge_key'] = df_comp[real_anchors_c].apply(lambda row: '-'.join([clean_key_val(x) for x in row]), axis=1)
|
| 435 |
|
| 436 |
-
# =========================================================
|
| 437 |
-
# ๐ก [๋ฐฉ์ด๋ง 1] Target_Table ์ด๋ฆ ๊น๋ํ๊ฒ ๊ฐ์ ธ์ค๊ธฐ
|
| 438 |
-
# =========================================================
|
| 439 |
conn_map = sqlite3.connect(os.path.join(UPLOAD_DIR, "mapping.db"))
|
| 440 |
registry_query = """
|
| 441 |
SELECT Target_Table FROM Mapping_registry
|
|
@@ -450,9 +426,6 @@ def execute_unified_search(base_std, base_ver, base_cat, comp_std, comp_ver, com
|
|
| 450 |
if val and val.lower() not in ["none", "nan"]:
|
| 451 |
target_table_name = val
|
| 452 |
|
| 453 |
-
# =========================================================
|
| 454 |
-
# ๐ก [๋ฐฉ์ด๋ง 2] ๋งคํ ์ฅ๋ถ ์์ ํ๊ฒ ์ฝ์ด์ค๊ธฐ (์คํ๋๋ฉด ์๋ฌ ๋์)
|
| 455 |
-
# =========================================================
|
| 456 |
try:
|
| 457 |
q_fw = f"SELECT * FROM [{target_table_name}] WHERE TRIM(Base_std)=? AND TRIM(Base_ver)=? AND TRIM(Comp_std)=? AND TRIM(Comp_ver)=?"
|
| 458 |
df_fw = pd.read_sql(q_fw, conn_map, params=[base_std.strip(), base_ver.strip(), comp_std.strip(), comp_ver.strip()])
|
|
@@ -501,9 +474,6 @@ def execute_unified_search(base_std, base_ver, base_cat, comp_std, comp_ver, com
|
|
| 501 |
df_mapping['Base_section'] = df_mapping['Base_section'].apply(clean_key_val)
|
| 502 |
df_mapping['Comp_section'] = df_mapping['Comp_section'].apply(clean_key_val)
|
| 503 |
|
| 504 |
-
# =========================================================
|
| 505 |
-
# ๐ฃ [๋ฐฉ์ด๋ง 3] ์นดํ
์์ ํญ๋ฐ ๋ฐฉ์ง: ๋น์นธ๋ผ๋ฆฌ ์ฐ๊ฒฐ๋ ๊ฐ์ง ๋งคํ ์ญ์
|
| 506 |
-
# =========================================================
|
| 507 |
df_mapping = df_mapping[(df_mapping['Base_section'] != "") & (df_mapping['Comp_section'] != "")]
|
| 508 |
df_mapping = df_mapping.dropna().drop_duplicates()
|
| 509 |
else:
|
|
@@ -575,9 +545,6 @@ def execute_unified_search(base_std, base_ver, base_cat, comp_std, comp_ver, com
|
|
| 575 |
|
| 576 |
return pd.DataFrame({"Info": ["์กฐ๊ฑด์ ์ ํํ์ธ์."]})
|
| 577 |
except Exception as e:
|
| 578 |
-
import traceback
|
| 579 |
-
traceback.print_exc()
|
| 580 |
-
# ์์คํ
์๋ฌ ๋์ ํ๋ฉด์ ๊น๋ํ๊ฒ ์์ธ์ ๋์์ค๋๋ค.
|
| 581 |
error_msg = str(e)
|
| 582 |
if "database is locked" in error_msg.lower():
|
| 583 |
return pd.DataFrame({"Error": ["๐จ DB๊ฐ ์ ๊ฒจ์์ต๋๋ค! ์ผ๋์ผ์ 'DB Browser' ํ๋ก๊ทธ๋จ์ ์์ ํ ์ข
๋ฃํ ๋ค ๋ค์ ์กฐํํด ์ฃผ์ธ์."]})
|
|
@@ -598,7 +565,6 @@ with gr.Blocks() as demo:
|
|
| 598 |
|
| 599 |
with gr.Row(elem_classes="reset-row"):
|
| 600 |
base_category = gr.Dropdown(label="Category", scale=4)
|
| 601 |
-
# โฌ๏ธ elem_classes="reset-btn" ์ถ๊ฐ!
|
| 602 |
base_reset_btn = gr.Button("โบ ์ด๊ธฐํ", scale=1, elem_classes="reset-btn")
|
| 603 |
|
| 604 |
with gr.Accordion("๐ ๋น๊ต ๋ฒ๊ท", open=False):
|
|
@@ -609,12 +575,10 @@ with gr.Blocks() as demo:
|
|
| 609 |
|
| 610 |
with gr.Row(elem_classes="reset-row"):
|
| 611 |
comp_category = gr.Dropdown(label="Category", choices=[], scale=4)
|
| 612 |
-
# โฌ๏ธ elem_classes="reset-btn" ์ถ๊ฐ!
|
| 613 |
comp_reset_btn = gr.Button("โบ ์ด๊ธฐํ", scale=1, elem_classes="reset-btn")
|
| 614 |
|
| 615 |
with gr.Row(elem_id="search_row"):
|
| 616 |
search_btn = gr.Button("๐ ์กฐํ", variant="primary", scale=10)
|
| 617 |
-
# โฌ๏ธ [์ถ๊ฐ] ๋งคํ ์ฒดํฌ๋ฐ์ค ์ถ๊ฐ!
|
| 618 |
mapped_only_cb = gr.Checkbox(label="๐ ๋งคํ๋ ํญ๋ชฉ๋ง ๋ณด๊ธฐ", value=False, elem_id="mapped_cb_item", container=False, scale=1)
|
| 619 |
diff_filter_cb = gr.Checkbox(label="๐ก ๋ณ๊ฒฝ๋ ๋ด์ฉ๋ง ๋ณด๊ธฐ", value=False, elem_id="diff_cb_item", container=False, scale=1)
|
| 620 |
|
|
|
|
| 5 |
import re
|
| 6 |
import base64
|
| 7 |
import difflib
|
|
|
|
| 8 |
|
| 9 |
# ==========================================
|
| 10 |
# 1. Environment Setup & Data Helpers
|
|
|
|
| 56 |
|
| 57 |
return sorted(list(set([d["standard"] for d in db_registry])))
|
| 58 |
|
|
|
|
|
|
|
|
|
|
| 59 |
def fetch_database_records(std, ver, cat, table_type):
|
| 60 |
try:
|
| 61 |
db_path = os.path.join(UPLOAD_DIR, f"{std}_{ver}.db")
|
| 62 |
conn = sqlite3.connect(db_path)
|
| 63 |
+
conn.text_factory = decode_sqlite_text
|
| 64 |
|
|
|
|
| 65 |
conn_map = sqlite3.connect(os.path.join(UPLOAD_DIR, "mapping.db"))
|
| 66 |
config_df = pd.read_sql("SELECT * FROM Table_Config WHERE TRIM(Table_Type)=?", conn_map, params=[table_type.strip()])
|
| 67 |
conn_map.close()
|
|
|
|
| 72 |
anchors = [x.strip() for x in config_df.iloc[0]['Anchor_Column'].split(',')]
|
| 73 |
displays = [x.strip() for x in config_df.iloc[0]['Display_Columns'].split(',')] if pd.notna(config_df.iloc[0]['Display_Columns']) else anchors
|
| 74 |
|
|
|
|
| 75 |
tables = pd.read_sql("SELECT name FROM sqlite_master WHERE type='table';", conn)['name'].tolist()
|
| 76 |
valid_tables = [t for t in tables if t.lower() not in ['mapping_registry', 'mapping_table', 'table_config', 'sqlite_sequence']]
|
| 77 |
main_table = f"{std}_{ver}"
|
|
|
|
| 83 |
|
| 84 |
query = f"SELECT * FROM [{main_table}]"
|
| 85 |
|
|
|
|
| 86 |
cols = pd.read_sql(f"PRAGMA table_info([{main_table}])", conn)['name'].tolist()
|
| 87 |
lower_cols = [c.lower() for c in cols]
|
| 88 |
|
|
|
|
| 103 |
df = pd.read_sql(query, conn)
|
| 104 |
conn.close()
|
| 105 |
|
|
|
|
| 106 |
final_cols = []
|
| 107 |
for d in displays:
|
| 108 |
for c in df.columns:
|
|
|
|
| 115 |
if not final_cols:
|
| 116 |
return df, real_anchors
|
| 117 |
|
| 118 |
+
for c in final_cols:
|
| 119 |
+
df[c] = df[c].apply(convert_blob_to_html_img)
|
| 120 |
+
|
| 121 |
return df[final_cols], real_anchors
|
| 122 |
|
| 123 |
except Exception as e:
|
|
|
|
| 129 |
try:
|
| 130 |
s1, s2 = str(text1), str(text2)
|
| 131 |
|
|
|
|
|
|
|
|
|
|
| 132 |
if len(s1) > 1000 or len(s2) > 1000:
|
| 133 |
return s1, s2
|
| 134 |
|
|
|
|
| 136 |
if not words1 or not words2:
|
| 137 |
return s1, s2
|
| 138 |
|
|
|
|
|
|
|
|
|
|
| 139 |
common_words = set(words1) & set(words2)
|
| 140 |
if len(common_words) / min(len(words1), len(words2)) < 0.05:
|
| 141 |
return s1, s2
|
| 142 |
|
|
|
|
| 143 |
matcher = difflib.SequenceMatcher(None, words1, words2)
|
|
|
|
| 144 |
res1, res2 = [], []
|
| 145 |
+
|
| 146 |
for tag, i1, i2, j1, j2 in matcher.get_opcodes():
|
| 147 |
if tag == 'replace':
|
| 148 |
res1.append(f"<span style='color:#ff4d4f; font-weight:bold;'>{' '.join(words1[i1:i2])}</span>")
|
|
|
|
| 158 |
return " ".join(res1), " ".join(res2)
|
| 159 |
except Exception:
|
| 160 |
return text1, text2
|
| 161 |
+
|
| 162 |
# ==========================================
|
| 163 |
# 2. UI Component Handlers
|
| 164 |
# ==========================================
|
|
|
|
| 165 |
def load_initial_standards():
|
| 166 |
return gr.Dropdown(choices=fetch_available_standards())
|
| 167 |
|
|
|
|
| 171 |
versions = sorted(set(d["version"] for d in db_registry if d["standard"] == standard))
|
| 172 |
return gr.Dropdown(choices=versions)
|
| 173 |
|
|
|
|
| 174 |
def update_base_category_dropdown(standard, version):
|
| 175 |
if not standard or not version:
|
| 176 |
return gr.update(choices=[], value=None, interactive=False), gr.update(value="")
|
| 177 |
|
| 178 |
choices = ["ALL"]
|
| 179 |
+
status_value = ""
|
| 180 |
|
| 181 |
db_path = os.path.join(UPLOAD_DIR, f"{standard}_{version}.db")
|
| 182 |
if not os.path.exists(db_path):
|
|
|
|
| 185 |
try:
|
| 186 |
conn = sqlite3.connect(db_path)
|
| 187 |
tables = pd.read_sql("SELECT name FROM sqlite_master WHERE type='table';", conn)['name'].tolist()
|
|
|
|
| 188 |
valid_tables = [t for t in tables if t.lower() not in ['mapping_registry', 'mapping_table', 'table_config', 'sqlite_sequence']]
|
|
|
|
| 189 |
main_table = f"{standard}_{version}"
|
| 190 |
if main_table not in valid_tables:
|
| 191 |
main_table = valid_tables[0] if valid_tables else None
|
| 192 |
|
| 193 |
if main_table:
|
|
|
|
| 194 |
try:
|
| 195 |
cols_check = pd.read_sql(f"PRAGMA table_info([{main_table}])", conn)['name'].tolist()
|
| 196 |
if "Status" in cols_check or "status" in cols_check:
|
|
|
|
| 224 |
|
| 225 |
conn.close()
|
| 226 |
except Exception:
|
| 227 |
+
pass
|
|
|
|
| 228 |
|
| 229 |
return gr.update(choices=choices, value=None, interactive=True), gr.update(value=status_value)
|
| 230 |
|
|
|
|
| 258 |
except Exception:
|
| 259 |
return gr.update(choices=[], value=None, interactive=False)
|
| 260 |
|
|
|
|
| 261 |
def update_comp_category_dropdown(base_std, base_ver, base_cat, comp_std, comp_ver):
|
| 262 |
if not all([base_std, base_ver, base_cat, comp_std, comp_ver]):
|
| 263 |
return gr.update(choices=[], value=None, interactive=False), gr.update(value="")
|
|
|
|
| 266 |
status_value = ""
|
| 267 |
|
| 268 |
try:
|
|
|
|
| 269 |
comp_db_path = os.path.join(UPLOAD_DIR, f"{comp_std}_{comp_ver}.db")
|
| 270 |
if os.path.exists(comp_db_path):
|
| 271 |
c_conn = sqlite3.connect(comp_db_path)
|
|
|
|
| 306 |
if "Main" in allowed_types:
|
| 307 |
final_choices.append("ALL")
|
| 308 |
if os.path.exists(comp_db_path):
|
|
|
|
| 309 |
c_conn = sqlite3.connect(comp_db_path)
|
| 310 |
if c_main_table:
|
| 311 |
cols = pd.read_sql(f"PRAGMA table_info([{c_main_table}])", c_conn)['name'].tolist()
|
|
|
|
| 327 |
|
| 328 |
return gr.update(choices=final_choices, value=final_choices[0] if final_choices else None, interactive=True), gr.update(value=status_value)
|
| 329 |
|
| 330 |
+
except Exception:
|
|
|
|
|
|
|
| 331 |
return gr.update(choices=[], value=None), gr.update(value="")
|
| 332 |
|
| 333 |
def reset_base_selections():
|
|
|
|
| 334 |
return gr.update(value=None), gr.update(choices=[], value=None), gr.update(choices=[], value=None), gr.update(value="")
|
| 335 |
|
| 336 |
def reset_comp_selections():
|
|
|
|
| 337 |
return gr.update(value=None), gr.update(choices=[], value=None), gr.update(choices=[], value=None), gr.update(value="")
|
| 338 |
|
| 339 |
+
# ==========================================
|
| 340 |
+
# 3. Core Search Logic
|
| 341 |
+
# ==========================================
|
| 342 |
def execute_unified_search(base_std, base_ver, base_cat, comp_std, comp_ver, comp_cat, mapped_only, diff_only):
|
| 343 |
try:
|
| 344 |
def get_type_by_cat(cat):
|
|
|
|
| 412 |
df_base['merge_key'] = df_base[real_anchors_b].apply(lambda row: '-'.join([clean_key_val(x) for x in row]), axis=1)
|
| 413 |
df_comp['merge_key'] = df_comp[real_anchors_c].apply(lambda row: '-'.join([clean_key_val(x) for x in row]), axis=1)
|
| 414 |
|
|
|
|
|
|
|
|
|
|
| 415 |
conn_map = sqlite3.connect(os.path.join(UPLOAD_DIR, "mapping.db"))
|
| 416 |
registry_query = """
|
| 417 |
SELECT Target_Table FROM Mapping_registry
|
|
|
|
| 426 |
if val and val.lower() not in ["none", "nan"]:
|
| 427 |
target_table_name = val
|
| 428 |
|
|
|
|
|
|
|
|
|
|
| 429 |
try:
|
| 430 |
q_fw = f"SELECT * FROM [{target_table_name}] WHERE TRIM(Base_std)=? AND TRIM(Base_ver)=? AND TRIM(Comp_std)=? AND TRIM(Comp_ver)=?"
|
| 431 |
df_fw = pd.read_sql(q_fw, conn_map, params=[base_std.strip(), base_ver.strip(), comp_std.strip(), comp_ver.strip()])
|
|
|
|
| 474 |
df_mapping['Base_section'] = df_mapping['Base_section'].apply(clean_key_val)
|
| 475 |
df_mapping['Comp_section'] = df_mapping['Comp_section'].apply(clean_key_val)
|
| 476 |
|
|
|
|
|
|
|
|
|
|
| 477 |
df_mapping = df_mapping[(df_mapping['Base_section'] != "") & (df_mapping['Comp_section'] != "")]
|
| 478 |
df_mapping = df_mapping.dropna().drop_duplicates()
|
| 479 |
else:
|
|
|
|
| 545 |
|
| 546 |
return pd.DataFrame({"Info": ["์กฐ๊ฑด์ ์ ํํ์ธ์."]})
|
| 547 |
except Exception as e:
|
|
|
|
|
|
|
|
|
|
| 548 |
error_msg = str(e)
|
| 549 |
if "database is locked" in error_msg.lower():
|
| 550 |
return pd.DataFrame({"Error": ["๐จ DB๊ฐ ์ ๊ฒจ์์ต๋๋ค! ์ผ๋์ผ์ 'DB Browser' ํ๋ก๊ทธ๋จ์ ์์ ํ ์ข
๋ฃํ ๋ค ๋ค์ ์กฐํํด ์ฃผ์ธ์."]})
|
|
|
|
| 565 |
|
| 566 |
with gr.Row(elem_classes="reset-row"):
|
| 567 |
base_category = gr.Dropdown(label="Category", scale=4)
|
|
|
|
| 568 |
base_reset_btn = gr.Button("โบ ์ด๊ธฐํ", scale=1, elem_classes="reset-btn")
|
| 569 |
|
| 570 |
with gr.Accordion("๐ ๋น๊ต ๋ฒ๊ท", open=False):
|
|
|
|
| 575 |
|
| 576 |
with gr.Row(elem_classes="reset-row"):
|
| 577 |
comp_category = gr.Dropdown(label="Category", choices=[], scale=4)
|
|
|
|
| 578 |
comp_reset_btn = gr.Button("โบ ์ด๊ธฐํ", scale=1, elem_classes="reset-btn")
|
| 579 |
|
| 580 |
with gr.Row(elem_id="search_row"):
|
| 581 |
search_btn = gr.Button("๐ ์กฐํ", variant="primary", scale=10)
|
|
|
|
| 582 |
mapped_only_cb = gr.Checkbox(label="๐ ๋งคํ๋ ํญ๋ชฉ๋ง ๋ณด๊ธฐ", value=False, elem_id="mapped_cb_item", container=False, scale=1)
|
| 583 |
diff_filter_cb = gr.Checkbox(label="๐ก ๋ณ๊ฒฝ๋ ๋ด์ฉ๋ง ๋ณด๊ธฐ", value=False, elem_id="diff_cb_item", container=False, scale=1)
|
| 584 |
|