Update app.py
Browse files
app.py
CHANGED
|
@@ -57,6 +57,92 @@ def fetch_available_standards():
|
|
| 57 |
|
| 58 |
return sorted(list(set([d["standard"] for d in db_registry])))
|
| 59 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 60 |
|
| 61 |
# ==========================================
|
| 62 |
# 2. UI Component Handlers
|
|
|
|
| 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()
|
| 72 |
+
|
| 73 |
+
if config_df.empty:
|
| 74 |
+
return pd.DataFrame({"Error": [f"Table_Config์์ '{table_type}' ์ค์ ์ ์ฐพ์ ์ ์์ต๋๋ค."]}), []
|
| 75 |
+
|
| 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}"
|
| 83 |
+
if main_table not in valid_tables:
|
| 84 |
+
main_table = valid_tables[0] if valid_tables else None
|
| 85 |
+
|
| 86 |
+
if not main_table:
|
| 87 |
+
return pd.DataFrame({"Error": ["๋ฐ์ดํฐ ํ
์ด๋ธ์ ์ฐพ์ ์ ์์ต๋๋ค."]}), []
|
| 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 |
+
|
| 95 |
+
conditions = []
|
| 96 |
+
if cat and cat != "ALL":
|
| 97 |
+
if "." in cat and 'chapter' in lower_cols and 'category' in lower_cols:
|
| 98 |
+
ch, ca = cat.split(".", 1)
|
| 99 |
+
ch_col = cols[lower_cols.index('chapter')]
|
| 100 |
+
ca_col = cols[lower_cols.index('category')]
|
| 101 |
+
conditions.append(f"[{ch_col}] = '{ch}' AND [{ca_col}] = '{ca}'")
|
| 102 |
+
elif 'category' in lower_cols:
|
| 103 |
+
ca_col = cols[lower_cols.index('category')]
|
| 104 |
+
conditions.append(f"[{ca_col}] = '{cat}'")
|
| 105 |
+
|
| 106 |
+
if conditions:
|
| 107 |
+
query += " WHERE " + " AND ".join(conditions)
|
| 108 |
+
|
| 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:
|
| 116 |
+
if d.lower() == c.lower():
|
| 117 |
+
final_cols.append(c)
|
| 118 |
+
break
|
| 119 |
+
|
| 120 |
+
real_anchors = [c for c in df.columns if any(a.lower() == c.lower() for a in anchors)]
|
| 121 |
+
|
| 122 |
+
if not final_cols:
|
| 123 |
+
return df, real_anchors
|
| 124 |
+
|
| 125 |
+
return df[final_cols], real_anchors
|
| 126 |
+
|
| 127 |
+
except Exception as e:
|
| 128 |
+
import traceback
|
| 129 |
+
traceback.print_exc()
|
| 130 |
+
return pd.DataFrame({"Error": [f"๋ฐ์ดํฐ ๋ก๋ ์ค๋ฅ: {str(e)}"]}), []
|
| 131 |
+
|
| 132 |
+
def generate_html_diff(text1, text2):
|
| 133 |
+
try:
|
| 134 |
+
diff = difflib.ndiff(str(text1).split(), str(text2).split())
|
| 135 |
+
res1, res2 = [], []
|
| 136 |
+
for token in diff:
|
| 137 |
+
if token.startswith('- '): res1.append(f"<span style='color:#ff4d4f; font-weight:bold;'>{token[2:]}</span>")
|
| 138 |
+
elif token.startswith('+ '): res2.append(f"<span style='color:#2ecc71; font-weight:bold;'>{token[2:]}</span>")
|
| 139 |
+
elif token.startswith(' '):
|
| 140 |
+
res1.append(token[2:])
|
| 141 |
+
res2.append(token[2:])
|
| 142 |
+
return " ".join(res1), " ".join(res2)
|
| 143 |
+
except:
|
| 144 |
+
return text1, text2
|
| 145 |
+
# ==========================================
|
| 146 |
|
| 147 |
# ==========================================
|
| 148 |
# 2. UI Component Handlers
|