Update app.py
Browse files
app.py
CHANGED
|
@@ -123,7 +123,6 @@ def fetch_database_records(std, ver, cat, table_type):
|
|
| 123 |
|
| 124 |
real_anchors = [c for c in df.columns if any(a.lower() == c.lower() for a in anchors)]
|
| 125 |
|
| 126 |
-
# π‘ [ν΅μ¬ ν΄κ²°] UI ν
μ€νΈλ°μ€μ Statusκ° νκΈ°λλ―λ‘, μλ νμμλ Status μ΄μ μΉ μ§μμ€λλ€.
|
| 127 |
status_cols = [c for c in df.columns if c.lower() == 'status']
|
| 128 |
if status_cols:
|
| 129 |
df = df.drop(columns=status_cols)
|
|
@@ -255,27 +254,15 @@ def update_comp_standard_dropdown(base_std, base_ver):
|
|
| 255 |
conn.close()
|
| 256 |
|
| 257 |
mapped_stds = sorted(df['Comp_std'].dropna().unique().tolist()) if not df.empty else []
|
| 258 |
-
|
| 259 |
-
if base_std not in mapped_stds:
|
| 260 |
-
mapped_stds.append(base_std)
|
| 261 |
-
mapped_stds.sort()
|
| 262 |
-
|
| 263 |
return gr.update(choices=mapped_stds, value=None, interactive=bool(mapped_stds))
|
| 264 |
except Exception:
|
| 265 |
-
return gr.update(choices=[
|
| 266 |
|
| 267 |
def update_comp_version_dropdown(base_std, base_ver, comp_std):
|
| 268 |
if not all([base_std, base_ver, comp_std]):
|
| 269 |
return gr.update(choices=[], value=None, interactive=False)
|
| 270 |
|
| 271 |
try:
|
| 272 |
-
if base_std.strip() == comp_std.strip():
|
| 273 |
-
versions = []
|
| 274 |
-
for file_name in os.listdir(UPLOAD_DIR):
|
| 275 |
-
if file_name.startswith(comp_std + "_") and file_name.endswith(".db"):
|
| 276 |
-
versions.append(file_name.replace(comp_std + "_", "").replace(".db", ""))
|
| 277 |
-
return gr.update(choices=sorted(list(set(versions))), value=None, interactive=True)
|
| 278 |
-
|
| 279 |
conn = sqlite3.connect(os.path.join(UPLOAD_DIR, "mapping.db"))
|
| 280 |
query = "SELECT DISTINCT TRIM(Comp_ver) AS Comp_ver FROM Mapping_registry WHERE TRIM(Base_std)=TRIM(?) AND TRIM(Base_ver)=TRIM(?) AND TRIM(Comp_std)=TRIM(?)"
|
| 281 |
df = pd.read_sql(query, conn, params=[base_std, base_ver, comp_std])
|
|
@@ -315,33 +302,6 @@ def update_comp_category_dropdown(base_std, base_ver, base_cat, comp_std, comp_v
|
|
| 315 |
pass
|
| 316 |
c_conn.close()
|
| 317 |
|
| 318 |
-
if base_std.strip() == comp_std.strip():
|
| 319 |
-
final_choices = ["ALL"]
|
| 320 |
-
if os.path.exists(comp_db_path) and c_main_table:
|
| 321 |
-
c_conn = sqlite3.connect(comp_db_path)
|
| 322 |
-
cols = pd.read_sql(f"PRAGMA table_info([{c_main_table}])", c_conn)['name'].tolist()
|
| 323 |
-
lower_cols = [c.lower() for c in cols]
|
| 324 |
-
if 'chapter' in lower_cols and 'category' in lower_cols:
|
| 325 |
-
ch_col = cols[lower_cols.index('chapter')]
|
| 326 |
-
ca_col = cols[lower_cols.index('category')]
|
| 327 |
-
c_df = pd.read_sql(f"SELECT DISTINCT [{ch_col}], [{ca_col}] FROM [{c_main_table}]", c_conn)
|
| 328 |
-
for _, row in c_df.iterrows():
|
| 329 |
-
ch = str(row[ch_col]).strip()
|
| 330 |
-
ca = str(row[ca_col]).strip()
|
| 331 |
-
if ch and ca and ch.lower() not in ['none', 'nan'] and ca.lower() not in ['none', 'nan']:
|
| 332 |
-
final_choices.append(f"{ch}.{ca}")
|
| 333 |
-
|
| 334 |
-
pattern = re.compile(f"^{comp_std}[_\\s-]*{comp_ver}[_\\s-]*", re.IGNORECASE)
|
| 335 |
-
for t in c_valid_tables:
|
| 336 |
-
if t == c_main_table: continue
|
| 337 |
-
short_name = pattern.sub("", t).strip(" _")
|
| 338 |
-
if short_name and short_name not in final_choices:
|
| 339 |
-
final_choices.append(short_name)
|
| 340 |
-
elif t not in final_choices:
|
| 341 |
-
final_choices.append(t)
|
| 342 |
-
c_conn.close()
|
| 343 |
-
return gr.update(choices=final_choices, value=final_choices[0] if final_choices else None, interactive=True), gr.update(value=status_value)
|
| 344 |
-
|
| 345 |
conn = sqlite3.connect(os.path.join(UPLOAD_DIR, "mapping.db"))
|
| 346 |
query = """
|
| 347 |
SELECT DISTINCT TRIM(Comp_Type) AS Comp_Type
|
|
@@ -460,9 +420,8 @@ def execute_unified_search(base_std, base_ver, base_cat, comp_std, comp_ver, com
|
|
| 460 |
s = s[:-2]
|
| 461 |
return s.replace(" ", "")
|
| 462 |
|
| 463 |
-
|
| 464 |
-
|
| 465 |
-
rename_c = {c: f"{c}_{comp_ver}(λΉκ΅)" for c in df_comp.columns if c != 'merge_key'}
|
| 466 |
|
| 467 |
df_base['merge_key'] = df_base[real_anchors_b].apply(lambda row: '-'.join([clean_key_val(x) for x in row]), axis=1)
|
| 468 |
df_comp['merge_key'] = df_comp[real_anchors_c].apply(lambda row: '-'.join([clean_key_val(x) for x in row]), axis=1)
|
|
@@ -495,7 +454,7 @@ def execute_unified_search(base_std, base_ver, base_cat, comp_std, comp_ver, com
|
|
| 495 |
df_rv = pd.read_sql(q_rv, conn_map, params=[base_std.strip(), base_ver.strip(), comp_std.strip(), comp_ver.strip()])
|
| 496 |
except Exception as sql_e:
|
| 497 |
conn_map.close()
|
| 498 |
-
return pd.DataFrame({"Error": [f"λ§€ν
|
| 499 |
conn_map.close()
|
| 500 |
|
| 501 |
cols_fw_lower = {c.lower(): c for c in df_fw.columns}
|
|
@@ -517,7 +476,7 @@ def execute_unified_search(base_std, base_ver, base_cat, comp_std, comp_ver, com
|
|
| 517 |
c_sec = cols_fw_lower.get('comp_section', 'Comp_section')
|
| 518 |
|
| 519 |
if b_sec not in df_fw.columns or c_sec not in df_fw.columns:
|
| 520 |
-
return pd.DataFrame({"Error": [f"'{target_table_name}'
|
| 521 |
|
| 522 |
df_fw = df_fw[[b_sec, c_sec]].rename(columns={b_sec: 'Base_section', c_sec: 'Comp_section'})
|
| 523 |
if not df_rv.empty:
|
|
@@ -540,8 +499,8 @@ def execute_unified_search(base_std, base_ver, base_cat, comp_std, comp_ver, com
|
|
| 540 |
else:
|
| 541 |
bridge = pd.DataFrame(columns=['Base_section', 'Comp_section'])
|
| 542 |
|
| 543 |
-
df_base = df_base.rename(columns=
|
| 544 |
-
df_comp = df_comp.rename(columns=
|
| 545 |
|
| 546 |
df_base['base_idx'], df_comp['comp_idx'] = range(len(df_base)), range(len(df_comp))
|
| 547 |
merged = pd.merge(bridge, df_base, left_on='Base_section', right_on='merge_key', how='outer')
|
|
@@ -557,22 +516,21 @@ def execute_unified_search(base_std, base_ver, base_cat, comp_std, comp_ver, com
|
|
| 557 |
has_b = not pd.isna(row.get('base_idx')) and row.get('base_idx') != float('inf')
|
| 558 |
has_c = not pd.isna(row.get('comp_idx')) and row.get('comp_idx') != float('inf')
|
| 559 |
|
| 560 |
-
for c in
|
| 561 |
-
for c in
|
| 562 |
|
| 563 |
if mapped_only:
|
| 564 |
-
b_has_val = any(str(row_dict[c]).strip() not in ["", "nan", "None", " "] for c in
|
| 565 |
-
c_has_val = any(str(row_dict[c]).strip() not in ["", "nan", "None", " "] for c in
|
| 566 |
-
|
| 567 |
if not (b_has_val and c_has_val):
|
| 568 |
continue
|
| 569 |
|
| 570 |
if has_b and has_c:
|
| 571 |
-
for orig_col in
|
| 572 |
-
if ('description' in orig_col.lower() or 'λ΄μ©' in orig_col) and
|
| 573 |
-
b_v, c_v = row_dict[
|
| 574 |
if b_v and c_v and "<img" not in b_v and "<img" not in c_v and b_v != c_v:
|
| 575 |
-
row_dict[
|
| 576 |
result_rows.append(row_dict)
|
| 577 |
|
| 578 |
final_df = combine_code_desc(pd.DataFrame(result_rows))
|
|
@@ -586,9 +544,17 @@ def execute_unified_search(base_std, base_ver, base_cat, comp_std, comp_ver, com
|
|
| 586 |
if final_df.empty:
|
| 587 |
return pd.DataFrame({"Info": ["π‘ μ ννμ 쑰건 κ°μ λ³κ²½λ λ΄μ©μ΄ μμ΅λλ€. (100% λμΌ)"]})
|
| 588 |
|
| 589 |
-
|
| 590 |
-
|
| 591 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 592 |
|
| 593 |
final_df = apply_visual_merge(final_df, b_cols_final)
|
| 594 |
final_df = apply_visual_merge(final_df, c_cols_final)
|
|
|
|
| 123 |
|
| 124 |
real_anchors = [c for c in df.columns if any(a.lower() == c.lower() for a in anchors)]
|
| 125 |
|
|
|
|
| 126 |
status_cols = [c for c in df.columns if c.lower() == 'status']
|
| 127 |
if status_cols:
|
| 128 |
df = df.drop(columns=status_cols)
|
|
|
|
| 254 |
conn.close()
|
| 255 |
|
| 256 |
mapped_stds = sorted(df['Comp_std'].dropna().unique().tolist()) if not df.empty else []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 257 |
return gr.update(choices=mapped_stds, value=None, interactive=bool(mapped_stds))
|
| 258 |
except Exception:
|
| 259 |
+
return gr.update(choices=[], value=None, interactive=False)
|
| 260 |
|
| 261 |
def update_comp_version_dropdown(base_std, base_ver, comp_std):
|
| 262 |
if not all([base_std, base_ver, comp_std]):
|
| 263 |
return gr.update(choices=[], value=None, interactive=False)
|
| 264 |
|
| 265 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 266 |
conn = sqlite3.connect(os.path.join(UPLOAD_DIR, "mapping.db"))
|
| 267 |
query = "SELECT DISTINCT TRIM(Comp_ver) AS Comp_ver FROM Mapping_registry WHERE TRIM(Base_std)=TRIM(?) AND TRIM(Base_ver)=TRIM(?) AND TRIM(Comp_std)=TRIM(?)"
|
| 268 |
df = pd.read_sql(query, conn, params=[base_std, base_ver, comp_std])
|
|
|
|
| 302 |
pass
|
| 303 |
c_conn.close()
|
| 304 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 305 |
conn = sqlite3.connect(os.path.join(UPLOAD_DIR, "mapping.db"))
|
| 306 |
query = """
|
| 307 |
SELECT DISTINCT TRIM(Comp_Type) AS Comp_Type
|
|
|
|
| 420 |
s = s[:-2]
|
| 421 |
return s.replace(" ", "")
|
| 422 |
|
| 423 |
+
internal_rename_b = {c: f"{c}_INTERNAL_BASE" for c in df_base.columns if c != 'merge_key'}
|
| 424 |
+
internal_rename_c = {c: f"{c}_INTERNAL_COMP" for c in df_comp.columns if c != 'merge_key'}
|
|
|
|
| 425 |
|
| 426 |
df_base['merge_key'] = df_base[real_anchors_b].apply(lambda row: '-'.join([clean_key_val(x) for x in row]), axis=1)
|
| 427 |
df_comp['merge_key'] = df_comp[real_anchors_c].apply(lambda row: '-'.join([clean_key_val(x) for x in row]), axis=1)
|
|
|
|
| 454 |
df_rv = pd.read_sql(q_rv, conn_map, params=[base_std.strip(), base_ver.strip(), comp_std.strip(), comp_ver.strip()])
|
| 455 |
except Exception as sql_e:
|
| 456 |
conn_map.close()
|
| 457 |
+
return pd.DataFrame({"Error": [f"λ§€ν '{target_table_name}'μ μ¬λ λ° μ€ν¨νμ΅λλ€. ν
μ΄λΈ μ΄λ¦μ νμΈνμΈμ: {str(sql_e)}"]})
|
| 458 |
conn_map.close()
|
| 459 |
|
| 460 |
cols_fw_lower = {c.lower(): c for c in df_fw.columns}
|
|
|
|
| 476 |
c_sec = cols_fw_lower.get('comp_section', 'Comp_section')
|
| 477 |
|
| 478 |
if b_sec not in df_fw.columns or c_sec not in df_fw.columns:
|
| 479 |
+
return pd.DataFrame({"Error": [f"'{target_table_name}' μ '{b_sec}' λλ '{c_sec}' μ΄μ΄ μμ΅λλ€. λμλ¬Έμλ₯Ό νμΈνμΈμ."]})
|
| 480 |
|
| 481 |
df_fw = df_fw[[b_sec, c_sec]].rename(columns={b_sec: 'Base_section', c_sec: 'Comp_section'})
|
| 482 |
if not df_rv.empty:
|
|
|
|
| 499 |
else:
|
| 500 |
bridge = pd.DataFrame(columns=['Base_section', 'Comp_section'])
|
| 501 |
|
| 502 |
+
df_base = df_base.rename(columns=internal_rename_b)
|
| 503 |
+
df_comp = df_comp.rename(columns=internal_rename_c)
|
| 504 |
|
| 505 |
df_base['base_idx'], df_comp['comp_idx'] = range(len(df_base)), range(len(df_comp))
|
| 506 |
merged = pd.merge(bridge, df_base, left_on='Base_section', right_on='merge_key', how='outer')
|
|
|
|
| 516 |
has_b = not pd.isna(row.get('base_idx')) and row.get('base_idx') != float('inf')
|
| 517 |
has_c = not pd.isna(row.get('comp_idx')) and row.get('comp_idx') != float('inf')
|
| 518 |
|
| 519 |
+
for c in internal_rename_b.values(): row_dict[c] = str(row[c]) if has_b and not pd.isna(row[c]) else ""
|
| 520 |
+
for c in internal_rename_c.values(): row_dict[c] = str(row[c]) if has_c and not pd.isna(row[c]) else ""
|
| 521 |
|
| 522 |
if mapped_only:
|
| 523 |
+
b_has_val = any(str(row_dict[c]).strip() not in ["", "nan", "None", " "] for c in internal_rename_b.values())
|
| 524 |
+
c_has_val = any(str(row_dict[c]).strip() not in ["", "nan", "None", " "] for c in internal_rename_c.values())
|
|
|
|
| 525 |
if not (b_has_val and c_has_val):
|
| 526 |
continue
|
| 527 |
|
| 528 |
if has_b and has_c:
|
| 529 |
+
for orig_col in internal_rename_b.keys():
|
| 530 |
+
if ('description' in orig_col.lower() or 'λ΄μ©' in orig_col) and internal_rename_c.get(orig_col) in row_dict:
|
| 531 |
+
b_v, c_v = row_dict[internal_rename_b[orig_col]], row_dict[internal_rename_c[orig_col]]
|
| 532 |
if b_v and c_v and "<img" not in b_v and "<img" not in c_v and b_v != c_v:
|
| 533 |
+
row_dict[internal_rename_b[orig_col]], row_dict[internal_rename_c[orig_col]] = generate_html_diff(b_v, c_v)
|
| 534 |
result_rows.append(row_dict)
|
| 535 |
|
| 536 |
final_df = combine_code_desc(pd.DataFrame(result_rows))
|
|
|
|
| 544 |
if final_df.empty:
|
| 545 |
return pd.DataFrame({"Info": ["π‘ μ ννμ 쑰건 κ°μ λ³κ²½λ λ΄μ©μ΄ μμ΅λλ€. (100% λμΌ)"]})
|
| 546 |
|
| 547 |
+
final_rename_map = {}
|
| 548 |
+
for col in final_df.columns:
|
| 549 |
+
if col.endswith("_INTERNAL_BASE"):
|
| 550 |
+
final_rename_map[col] = f"{col.replace('_INTERNAL_BASE', '')}_{base_ver}"
|
| 551 |
+
elif col.endswith("_INTERNAL_COMP"):
|
| 552 |
+
final_rename_map[col] = f"{col.replace('_INTERNAL_COMP', '')}_{comp_ver}"
|
| 553 |
+
|
| 554 |
+
final_df = final_df.rename(columns=final_rename_map)
|
| 555 |
+
|
| 556 |
+
b_cols_final = [c for c in final_df.columns if c.endswith(f"_{base_ver}")]
|
| 557 |
+
c_cols_final = [c for c in final_df.columns if c.endswith(f"_{comp_ver}")]
|
| 558 |
|
| 559 |
final_df = apply_visual_merge(final_df, b_cols_final)
|
| 560 |
final_df = apply_visual_merge(final_df, c_cols_final)
|