Update app.py
Browse files
app.py
CHANGED
|
@@ -145,9 +145,37 @@ def fetch_announcements(keyword="", category="전체", region="전체(지역)",
|
|
| 145 |
end_idx = start_idx + rows
|
| 146 |
df_page = df.iloc[start_idx:end_idx].copy()
|
| 147 |
df_page.insert(0, "번호", range(total_filtered - start_idx, total_filtered - start_idx - len(df_page), -1))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 148 |
internal_cols = [c for c in df_page.columns if c.startswith("_")]
|
| 149 |
df_page = df_page.drop(columns=internal_cols)
|
| 150 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 151 |
status = f"✅ {len(df_page)}건 표시 (페이지 {page}) | 필터 결과: {total_filtered}건 | 수집: {total_before_filter}건"
|
| 152 |
if status_prefix:
|
| 153 |
status = f"{status_prefix} | {status}"
|
|
@@ -528,12 +556,10 @@ def create_interface():
|
|
| 528 |
search_btn = gr.Button("🔎 검색", variant="primary", scale=2)
|
| 529 |
|
| 530 |
status_output = gr.Textbox(label="📊 조회 결과", interactive=False)
|
| 531 |
-
results_output = gr.Dataframe(label="📋 공고 목록 (행 클릭으로 선택)", wrap=True, interactive=False)
|
| 532 |
with gr.Row():
|
| 533 |
prev_btn = gr.Button("◀️ 이전", size="sm")
|
| 534 |
next_btn = gr.Button("다음 ▶️", size="sm")
|
| 535 |
-
export_btn = gr.Button("📥 CSV 내보내기", size="sm", variant="secondary")
|
| 536 |
-
csv_output = gr.File(label="📁 다운로드", visible=True)
|
| 537 |
|
| 538 |
# 탭 2: AI 분석
|
| 539 |
with gr.Tab("🤖 AI 분석"):
|
|
@@ -729,14 +755,6 @@ def create_interface():
|
|
| 729 |
display_df = df[[c for c in display_cols if c in df.columns]] if not df.empty else df
|
| 730 |
return display_df, status, df, new_page
|
| 731 |
|
| 732 |
-
def export_to_csv(df):
|
| 733 |
-
if df is None or (isinstance(df, pd.DataFrame) and df.empty):
|
| 734 |
-
return None
|
| 735 |
-
filepath = "/tmp/bizinfo_announcements.csv"
|
| 736 |
-
export_cols = [c for c in df.columns if not c.startswith("_")]
|
| 737 |
-
df[export_cols].to_csv(filepath, index=False, encoding='utf-8-sig')
|
| 738 |
-
return filepath
|
| 739 |
-
|
| 740 |
def on_row_select(evt: gr.SelectData, df):
|
| 741 |
if evt.index[0] < len(df):
|
| 742 |
row = df.iloc[evt.index[0]]
|
|
@@ -848,9 +866,6 @@ def create_interface():
|
|
| 848 |
org_type_dropdown, sort_dropdown, status_dropdown, rows_dropdown],
|
| 849 |
outputs=[results_output, status_output, current_df, page_input])
|
| 850 |
|
| 851 |
-
# CSV 내보내기
|
| 852 |
-
export_btn.click(fn=export_to_csv, inputs=[current_df], outputs=[csv_output])
|
| 853 |
-
|
| 854 |
results_output.select(fn=on_row_select, inputs=[current_df],
|
| 855 |
outputs=[selected_url, selected_name, selected_print_file, selected_description, selected_info])
|
| 856 |
|
|
|
|
| 145 |
end_idx = start_idx + rows
|
| 146 |
df_page = df.iloc[start_idx:end_idx].copy()
|
| 147 |
df_page.insert(0, "번호", range(total_filtered - start_idx, total_filtered - start_idx - len(df_page), -1))
|
| 148 |
+
|
| 149 |
+
# ⭐ 바로가기 링크 컬럼 추가 (새 탭에서 열기)
|
| 150 |
+
def make_link(row):
|
| 151 |
+
link = row.get("상세링크", "")
|
| 152 |
+
if link:
|
| 153 |
+
if link.startswith('/'):
|
| 154 |
+
link = f"https://www.bizinfo.go.kr{link}"
|
| 155 |
+
return f'<a href="{link}" target="_blank">🔗 열기</a>'
|
| 156 |
+
return ""
|
| 157 |
+
|
| 158 |
+
df_page["바로가기"] = df_page.apply(make_link, axis=1)
|
| 159 |
+
|
| 160 |
+
# 컬럼 순서 재정렬 (바로가기를 앞쪽으로)
|
| 161 |
+
cols = df_page.columns.tolist()
|
| 162 |
+
# 상세링크 컬럼 제거하고 바로가기로 대체
|
| 163 |
+
if "상세링크" in cols:
|
| 164 |
+
cols.remove("상세링크")
|
| 165 |
+
if "바로가기" in cols:
|
| 166 |
+
cols.remove("바로가기")
|
| 167 |
+
cols.insert(2, "바로가기") # 번호, 지원분야 다음에 배치
|
| 168 |
+
df_page = df_page[cols]
|
| 169 |
+
|
| 170 |
internal_cols = [c for c in df_page.columns if c.startswith("_")]
|
| 171 |
df_page = df_page.drop(columns=internal_cols)
|
| 172 |
|
| 173 |
+
# 불필요한 컬럼 숨기기
|
| 174 |
+
hide_cols = ["공고ID", "첨부파일", "본문출력파일", "사업개요", "지원대상", "문의처", "신청URL"]
|
| 175 |
+
for col in hide_cols:
|
| 176 |
+
if col in df_page.columns:
|
| 177 |
+
df_page = df_page.drop(columns=[col])
|
| 178 |
+
|
| 179 |
status = f"✅ {len(df_page)}건 표시 (페이지 {page}) | 필터 결과: {total_filtered}건 | 수집: {total_before_filter}건"
|
| 180 |
if status_prefix:
|
| 181 |
status = f"{status_prefix} | {status}"
|
|
|
|
| 556 |
search_btn = gr.Button("🔎 검색", variant="primary", scale=2)
|
| 557 |
|
| 558 |
status_output = gr.Textbox(label="📊 조회 결과", interactive=False)
|
| 559 |
+
results_output = gr.Dataframe(label="📋 공고 목록 (행 클릭으로 선택)", wrap=True, interactive=False, datatype="markdown")
|
| 560 |
with gr.Row():
|
| 561 |
prev_btn = gr.Button("◀️ 이전", size="sm")
|
| 562 |
next_btn = gr.Button("다음 ▶️", size="sm")
|
|
|
|
|
|
|
| 563 |
|
| 564 |
# 탭 2: AI 분석
|
| 565 |
with gr.Tab("🤖 AI 분석"):
|
|
|
|
| 755 |
display_df = df[[c for c in display_cols if c in df.columns]] if not df.empty else df
|
| 756 |
return display_df, status, df, new_page
|
| 757 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 758 |
def on_row_select(evt: gr.SelectData, df):
|
| 759 |
if evt.index[0] < len(df):
|
| 760 |
row = df.iloc[evt.index[0]]
|
|
|
|
| 866 |
org_type_dropdown, sort_dropdown, status_dropdown, rows_dropdown],
|
| 867 |
outputs=[results_output, status_output, current_df, page_input])
|
| 868 |
|
|
|
|
|
|
|
|
|
|
| 869 |
results_output.select(fn=on_row_select, inputs=[current_df],
|
| 870 |
outputs=[selected_url, selected_name, selected_print_file, selected_description, selected_info])
|
| 871 |
|