Update app.py
Browse files
app.py
CHANGED
|
@@ -3,7 +3,7 @@ import sqlite3
|
|
| 3 |
import pandas as pd
|
| 4 |
import os
|
| 5 |
import re
|
| 6 |
-
import base64
|
| 7 |
|
| 8 |
# 1๏ธโฃ ์ ์ฅ์ ์ค์
|
| 9 |
UPLOAD_DIR = "uploaded_dbs"
|
|
@@ -12,17 +12,15 @@ if not os.path.exists(UPLOAD_DIR):
|
|
| 12 |
|
| 13 |
db_registry = []
|
| 14 |
|
| 15 |
-
# BLOB ๋ฐ์ดํฐ๋ฅผ Base64 HTML ์ด๋ฏธ์ง ํ๊ทธ๋ก ๋ณํ
|
| 16 |
def blob_to_base64_html(blob_data):
|
| 17 |
-
if blob_data is None:
|
| 18 |
return ""
|
| 19 |
try:
|
| 20 |
-
|
| 21 |
-
if isinstance(blob_data, bytes):
|
| 22 |
encoded_string = base64.b64encode(blob_data).decode('utf-8')
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
return str(blob_data) # ๋ฐ์ดํธ๊ฐ ์๋๋ฉด ๊ทธ๋ฅ ๋ฌธ์์ด๋ก ๋ฐํ
|
| 26 |
except:
|
| 27 |
return "[์ด๋ฏธ์ง ๋ณํ ์๋ฌ]"
|
| 28 |
|
|
@@ -65,100 +63,72 @@ def update_category_dd(standard, version):
|
|
| 65 |
conn = sqlite3.connect(target_db["path"])
|
| 66 |
all_tables = pd.read_sql("SELECT name FROM sqlite_master WHERE type='table';", conn)['name'].tolist()
|
| 67 |
|
| 68 |
-
# 1. ๋ฉ์ธ ํ
์ด๋ธ ๊ฒฐ์ ๋ก์ง ๊ฐํ
|
| 69 |
main_t = f"{standard}_{version}"
|
| 70 |
-
if main_t not in all_tables:
|
| 71 |
-
# ํ์ผ๋ช
๊ณผ ์๋ฒฝํ ์ผ์นํ๋ ํ
์ด๋ธ์ด ์์ผ๋ฉด, standard์ version์ ํฌํจํ๋ ๊ฐ์ฅ ์งง์ ์ด๋ฆ์ ์ ํ
|
| 72 |
-
candidates = [t for t in all_tables if standard in t and version in t]
|
| 73 |
-
main_t = min(candidates, key=len) if candidates else all_tables[0]
|
| 74 |
|
| 75 |
-
#
|
| 76 |
cols_info = pd.read_sql(f"PRAGMA table_info([{main_t}])", conn)
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
col_category = actual_cols[lower_cols.index('category')]
|
| 85 |
-
|
| 86 |
-
# DISTINCT ์ฟผ๋ฆฌ๋ก ๋ชฉ๋ก ์ถ์ถ
|
| 87 |
-
df_cat = pd.read_sql(f"SELECT DISTINCT [{col_chapter}], [{col_category}] FROM [{main_t}]", conn)
|
| 88 |
-
|
| 89 |
-
cats = []
|
| 90 |
-
for _, row in df_cat.iterrows():
|
| 91 |
-
ch = str(row[col_chapter]) if row[col_chapter] is not None else ""
|
| 92 |
-
ca = str(row[col_category]) if row[col_category] is not None else ""
|
| 93 |
-
if ch or ca: # ๋ ์ค ํ๋๋ผ๋ ๋ด์ฉ์ด ์์ผ๋ฉด ์ถ๊ฐ
|
| 94 |
-
cats.append(f"{ch}.{ca}")
|
| 95 |
-
|
| 96 |
cats.sort(key=natural_sort_key)
|
| 97 |
choices.extend(cats)
|
| 98 |
|
| 99 |
-
# 4. ๋ถ์ ํ
์ด๋ธ(Annex ๋ฑ) ์ถ๊ฐ
|
| 100 |
prefix = f"{standard}_{version}_"
|
| 101 |
sub_tables = [t.replace(prefix, "") for t in all_tables if t != main_t]
|
| 102 |
choices.extend(sorted(sub_tables))
|
| 103 |
-
|
| 104 |
conn.close()
|
| 105 |
-
except
|
| 106 |
-
print(f"Error: {e}")
|
| 107 |
-
pass
|
| 108 |
-
|
| 109 |
return gr.Dropdown(choices=choices, value=None)
|
| 110 |
|
| 111 |
-
# 3๏ธโฃ ๋ฐ์ดํฐ ์กฐํ ๋ก์ง (์ ๋ ฌ
|
| 112 |
def display_data(standard, version, selection):
|
| 113 |
if not all([standard, version, selection]): return None
|
| 114 |
try:
|
| 115 |
target_db = next(db for db in db_registry if db["standard"] == standard and db["version"] == version)
|
| 116 |
conn = sqlite3.connect(target_db["path"])
|
| 117 |
all_tables = pd.read_sql("SELECT name FROM sqlite_master WHERE type='table';", conn)['name'].tolist()
|
| 118 |
-
|
| 119 |
main_t = f"{standard}_{version}"
|
| 120 |
if main_t not in all_tables: main_t = all_tables[0]
|
| 121 |
|
| 122 |
is_sub_table = False
|
|
|
|
| 123 |
if selection == "ALL":
|
| 124 |
-
df = pd.read_sql(f"SELECT * FROM [{main_t}]", conn)
|
| 125 |
elif "." in selection:
|
| 126 |
ch, ca = selection.split('.', 1)
|
| 127 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 128 |
else:
|
| 129 |
is_sub_table = True
|
| 130 |
actual_table = next((t for t in all_tables if t.endswith(selection)), selection)
|
| 131 |
-
df = pd.read_sql(f"SELECT * FROM [{actual_table}]", conn)
|
| 132 |
conn.close()
|
| 133 |
|
| 134 |
if not df.empty:
|
| 135 |
-
#
|
| 136 |
for col in df.columns:
|
| 137 |
df[col] = df[col].apply(blob_to_base64_html)
|
| 138 |
|
| 139 |
-
#
|
| 140 |
-
|
| 141 |
-
# 2. ๐ก [์ด ํํฐ๋ง ๋ก์ง]
|
| 142 |
if not is_sub_table:
|
| 143 |
-
# ๊ธฐ๋ณธ์ ์ผ๋ก ๋ณด์ฌ์ค ์ด ์ ์
|
| 144 |
base_cols = [c for c in ['section', 'description'] if c in df.columns]
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
image_cols = [
|
| 148 |
-
c for c in df.columns
|
| 149 |
-
if c not in base_cols and df[c].astype(str).str.contains('<img', na=False).any()
|
| 150 |
-
]
|
| 151 |
-
|
| 152 |
-
# ์ต์ข
์ ์ผ๋ก ํ์ํ ์ด๋ง ํ์ (DB ์์ ์ ์ง)
|
| 153 |
df = df[base_cols + image_cols]
|
| 154 |
-
else:
|
| 155 |
-
# ๋ถ์ ํ
์ด๋ธ์ ๋ชจ๋ ์ด์ ๋ณด์ฌ์ฃผ๋ ์ ๋ ฌ ์กฐ์ ์์
|
| 156 |
-
df = df
|
| 157 |
|
| 158 |
return df
|
| 159 |
except Exception as e:
|
| 160 |
return pd.DataFrame({"Error": [f"์กฐํ ์คํจ: {str(e)}"]})
|
| 161 |
-
|
| 162 |
# 4๏ธโฃ UI ๊ตฌ์ฑ
|
| 163 |
with gr.Blocks() as demo:
|
| 164 |
gr.Markdown("# ๐ Regulation Viewer")
|
|
@@ -168,7 +138,6 @@ with gr.Blocks() as demo:
|
|
| 168 |
version_dd = gr.Dropdown(label="2. Version ์ ํ")
|
| 169 |
category_dd = gr.Dropdown(label="3. Category / Table ์ ํ")
|
| 170 |
|
| 171 |
-
# ๐ก [์ค์] datatype="html"์ ์ถ๊ฐํ์ฌ <img> ํ๊ทธ๊ฐ ์ด๋ฏธ์ง๋ก ๋ณด์ด๊ฒ ํจ
|
| 172 |
output_df = gr.Dataframe(wrap=True, interactive=False, datatype="html")
|
| 173 |
|
| 174 |
demo.load(on_load, None, standard_dd)
|
|
|
|
| 3 |
import pandas as pd
|
| 4 |
import os
|
| 5 |
import re
|
| 6 |
+
import base64
|
| 7 |
|
| 8 |
# 1๏ธโฃ ์ ์ฅ์ ์ค์
|
| 9 |
UPLOAD_DIR = "uploaded_dbs"
|
|
|
|
| 12 |
|
| 13 |
db_registry = []
|
| 14 |
|
| 15 |
+
# BLOB ๋ฐ์ดํฐ๋ฅผ Base64 HTML ์ด๋ฏธ์ง ํ๊ทธ๋ก ๋ณํ
|
| 16 |
def blob_to_base64_html(blob_data):
|
| 17 |
+
if blob_data is None or pd.isna(blob_data):
|
| 18 |
return ""
|
| 19 |
try:
|
| 20 |
+
if isinstance(blob_data, (bytes, bytearray)):
|
|
|
|
| 21 |
encoded_string = base64.b64encode(blob_data).decode('utf-8')
|
| 22 |
+
return f'<img src="data:image/png;base64,{encoded_string}" width="200" height="auto" />'
|
| 23 |
+
return str(blob_data)
|
|
|
|
| 24 |
except:
|
| 25 |
return "[์ด๋ฏธ์ง ๋ณํ ์๋ฌ]"
|
| 26 |
|
|
|
|
| 63 |
conn = sqlite3.connect(target_db["path"])
|
| 64 |
all_tables = pd.read_sql("SELECT name FROM sqlite_master WHERE type='table';", conn)['name'].tolist()
|
| 65 |
|
|
|
|
| 66 |
main_t = f"{standard}_{version}"
|
| 67 |
+
if main_t not in all_tables: main_t = all_tables[0]
|
|
|
|
|
|
|
|
|
|
| 68 |
|
| 69 |
+
# ์ปฌ๋ผ๋ช
๋์๋ฌธ์ ๊ตฌ๋ถ ์์ด chapter/category ์ฐพ๊ธฐ
|
| 70 |
cols_info = pd.read_sql(f"PRAGMA table_info([{main_t}])", conn)
|
| 71 |
+
cols_lower = [c.lower() for c in cols_info['name'].tolist()]
|
| 72 |
+
|
| 73 |
+
if 'chapter' in cols_lower and 'category' in cols_lower:
|
| 74 |
+
real_ch = cols_info['name'].tolist()[cols_lower.index('chapter')]
|
| 75 |
+
real_cat = cols_info['name'].tolist()[cols_lower.index('category')]
|
| 76 |
+
df_cat = pd.read_sql(f"SELECT DISTINCT [{real_ch}], [{real_cat}] FROM [{main_t}]", conn)
|
| 77 |
+
cats = [f"{row[real_ch]}.{row[real_cat]}" for _, row in df_cat.iterrows() if row[real_ch]]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 78 |
cats.sort(key=natural_sort_key)
|
| 79 |
choices.extend(cats)
|
| 80 |
|
|
|
|
| 81 |
prefix = f"{standard}_{version}_"
|
| 82 |
sub_tables = [t.replace(prefix, "") for t in all_tables if t != main_t]
|
| 83 |
choices.extend(sorted(sub_tables))
|
|
|
|
| 84 |
conn.close()
|
| 85 |
+
except: pass
|
|
|
|
|
|
|
|
|
|
| 86 |
return gr.Dropdown(choices=choices, value=None)
|
| 87 |
|
| 88 |
+
# 3๏ธโฃ ๋ฐ์ดํฐ ์กฐํ ๋ก์ง (์ ๋ ฌ ์ง์ฐ๊ณ ์ด๋ฏธ์ง+DB ์์ ์ ์ง)
|
| 89 |
def display_data(standard, version, selection):
|
| 90 |
if not all([standard, version, selection]): return None
|
| 91 |
try:
|
| 92 |
target_db = next(db for db in db_registry if db["standard"] == standard and db["version"] == version)
|
| 93 |
conn = sqlite3.connect(target_db["path"])
|
| 94 |
all_tables = pd.read_sql("SELECT name FROM sqlite_master WHERE type='table';", conn)['name'].tolist()
|
|
|
|
| 95 |
main_t = f"{standard}_{version}"
|
| 96 |
if main_t not in all_tables: main_t = all_tables[0]
|
| 97 |
|
| 98 |
is_sub_table = False
|
| 99 |
+
# ORDER BY rowid๋ก DB ์ ์ฅ ์์ ๊ทธ๋๋ก ๊ฐ์ ธ์ค๊ธฐ
|
| 100 |
if selection == "ALL":
|
| 101 |
+
df = pd.read_sql(f"SELECT * FROM [{main_t}] ORDER BY rowid", conn)
|
| 102 |
elif "." in selection:
|
| 103 |
ch, ca = selection.split('.', 1)
|
| 104 |
+
# ๋์๋ฌธ์ ๋์์ ์ํด ํํฐ๋ง ์ฟผ๋ฆฌ ์์ฑ
|
| 105 |
+
cols_info = pd.read_sql(f"PRAGMA table_info([{main_t}])", conn)
|
| 106 |
+
cols_lower = [c.lower() for c in cols_info['name'].tolist()]
|
| 107 |
+
real_ch = cols_info['name'].tolist()[cols_lower.index('chapter')]
|
| 108 |
+
real_cat = cols_info['name'].tolist()[cols_lower.index('category')]
|
| 109 |
+
df = pd.read_sql(f"SELECT * FROM [{main_t}] WHERE [{real_ch}]=? AND [{real_cat}]=? ORDER BY rowid", conn, params=[ch, ca])
|
| 110 |
else:
|
| 111 |
is_sub_table = True
|
| 112 |
actual_table = next((t for t in all_tables if t.endswith(selection)), selection)
|
| 113 |
+
df = pd.read_sql(f"SELECT * FROM [{actual_table}] ORDER BY rowid", conn)
|
| 114 |
conn.close()
|
| 115 |
|
| 116 |
if not df.empty:
|
| 117 |
+
# ๋ชจ๋ ์
์ ๋ํด ์ด๋ฏธ์ง ๋ณํ ์ฒ๋ฆฌ
|
| 118 |
for col in df.columns:
|
| 119 |
df[col] = df[col].apply(blob_to_base64_html)
|
| 120 |
|
| 121 |
+
# ์ด ํํฐ๋ง: ๋ณธ๋ฌธ ์กฐํ ์ ์ฃผ์ ์ด + ์ด๋ฏธ์ง๊ฐ ํฌํจ๋ ์ด๋ง ํ์
|
|
|
|
|
|
|
| 122 |
if not is_sub_table:
|
|
|
|
| 123 |
base_cols = [c for c in ['section', 'description'] if c in df.columns]
|
| 124 |
+
# ์ด๋ฏธ์ง๊ฐ ๋ค์ด์๋ ์ด(HTML ํ๊ทธ๊ฐ ํฌํจ๋ ์ด)์ ์ฐพ์
|
| 125 |
+
image_cols = [c for c in df.columns if c not in base_cols and '<img' in str(df[col].iloc[0] if len(df)>0 else "")]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
df = df[base_cols + image_cols]
|
|
|
|
|
|
|
|
|
|
| 127 |
|
| 128 |
return df
|
| 129 |
except Exception as e:
|
| 130 |
return pd.DataFrame({"Error": [f"์กฐํ ์คํจ: {str(e)}"]})
|
| 131 |
+
|
| 132 |
# 4๏ธโฃ UI ๊ตฌ์ฑ
|
| 133 |
with gr.Blocks() as demo:
|
| 134 |
gr.Markdown("# ๐ Regulation Viewer")
|
|
|
|
| 138 |
version_dd = gr.Dropdown(label="2. Version ์ ํ")
|
| 139 |
category_dd = gr.Dropdown(label="3. Category / Table ์ ํ")
|
| 140 |
|
|
|
|
| 141 |
output_df = gr.Dataframe(wrap=True, interactive=False, datatype="html")
|
| 142 |
|
| 143 |
demo.load(on_load, None, standard_dd)
|