QIDNLF commited on
Commit
bc06362
ยท
verified ยท
1 Parent(s): 3dca055

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +31 -62
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
- # ๋ฐ์ดํ„ฐ๊ฐ€ ์ด๋ฏธ ๋ฐ”์ดํŠธ ํ˜•ํƒœ์ธ์ง€ ํ™•์ธ (b'\x89PNG' ๋“ฑ)
21
- if isinstance(blob_data, bytes):
22
  encoded_string = base64.b64encode(blob_data).decode('utf-8')
23
- # ๋„ˆ๋น„(width)๋Š” ์›ํ•˜์‹œ๋Š” ๋Œ€๋กœ ์กฐ์ ˆํ•˜์„ธ์š”.
24
- return f'<img src="data:image/png;base64,{encoded_string}" width="150" />'
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
- # 2. ์ปฌ๋Ÿผ ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ (๋Œ€์†Œ๋ฌธ์ž ๋ฌด์‹œ ์ฒ˜๋ฆฌ)
76
  cols_info = pd.read_sql(f"PRAGMA table_info([{main_t}])", conn)
77
- actual_cols = cols_info['name'].tolist()
78
- lower_cols = [c.lower() for c in actual_cols] # ๋น„๊ต์šฉ ์†Œ๋ฌธ์ž ๋ฆฌ์ŠคํŠธ
79
-
80
- # 3. Chapter / Category ๋ชฉ๋ก ์ƒ์„ฑ
81
- if 'chapter' in lower_cols and 'category' in lower_cols:
82
- # ์‹ค์ œ DB์— ์ €์žฅ๋œ ๋Œ€์†Œ๋ฌธ์ž ๊ทธ๋Œ€๋กœ์˜ ์ปฌ๋Ÿผ๋ช…์„ ์ฐพ์Œ
83
- col_chapter = actual_cols[lower_cols.index('chapter')]
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 Exception as e:
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
- df = pd.read_sql(f"SELECT * FROM [{main_t}] WHERE chapter=? AND category=?", conn, params=[ch, ca])
 
 
 
 
 
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
- # 1. ๋จผ์ € BLOB(์ด๋ฏธ์ง€) ๋ฐ์ดํ„ฐ๋ฅผ HTML๋กœ ๋ณ€ํ™˜
136
  for col in df.columns:
137
  df[col] = df[col].apply(blob_to_base64_html)
138
 
139
- # ๐Ÿ’ก [์ •๋ ฌ ๋กœ์ง ์ œ๊ฑฐ๋จ] DB์—์„œ ๋ถˆ๋Ÿฌ์˜จ ์ˆœ์„œ๋ฅผ ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.
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)