ginipick commited on
Commit
c4a9537
·
verified ·
1 Parent(s): 3c561b8

Update app-backup2.py

Browse files
Files changed (1) hide show
  1. app-backup2.py +110 -62
app-backup2.py CHANGED
@@ -141,37 +141,72 @@ def display_results(articles):
141
  output += f"요약: {article['snippet']}\n\n"
142
  return output
143
 
 
 
 
 
144
  def search_company(company):
145
  """
146
- 단일 기업(또는 키워드)에 대해 미국 뉴스 검색, DB 저장 후 결과 Markdown 반환
 
 
147
  """
148
  error_message, articles = serphouse_search(company, "United States")
149
  if not error_message and articles:
150
- save_to_db(company, "United States", articles)
151
- return display_results(articles)
 
 
 
 
 
 
 
 
 
 
 
 
152
  return f"{company}에 대한 검색 결과가 없습니다."
153
 
 
 
 
154
  def load_company(company):
155
  """
156
- DB에서 단일 기업(또는 키워드)의 미국 뉴스 검색 결과를 불러와 Markdown 반환
 
157
  """
158
- results, timestamp = load_from_db(company, "United States")
159
- if results:
160
- return f"### {company} 검색 결과\n저장 시간: {timestamp}\n\n" + display_results(results)
 
 
 
 
 
 
 
161
  return f"{company}에 대한 저장된 결과가 없습니다."
162
 
 
 
 
 
163
  def show_stats():
164
  """
165
  KOREAN_COMPANIES 목록 내 모든 기업에 대해:
166
  - 가장 최근 DB 저장 일자
167
  - 기사 수
168
  - 감성 분석 결과
169
- 순차(또는 병렬)로 조회하여 보고서 형태로 반환
 
 
170
  """
171
  conn = sqlite3.connect("search_results.db")
172
  c = conn.cursor()
173
 
174
- output = "## 한국 기업 뉴스 분석 리포트\n\n"
175
 
176
  # 모든 기업에 대해 DB에서 읽어올 (company, timestamp, articles) 목록 수집
177
  data_list = []
@@ -187,45 +222,48 @@ def show_stats():
187
  row = c.fetchone()
188
  if row:
189
  results_json, timestamp = row
190
- articles = json.loads(results_json)
191
- seoul_time = convert_to_seoul_time(timestamp)
192
- data_list.append((company, seoul_time, articles))
193
 
194
  conn.close()
195
 
196
- # (옵션) 각 기업 감성 분석을 병렬 처리
197
  def analyze_data(item):
198
- comp, tstamp, arts = item
199
- sentiment = ""
200
- if arts:
201
- sentiment = analyze_sentiment_batch(arts, client)
202
- return (comp, tstamp, len(arts), sentiment)
 
 
 
 
 
 
203
 
204
- # ThreadPoolExecutor로 병렬 감성 분석
205
  results_list = []
206
  with ThreadPoolExecutor(max_workers=5) as executor:
207
  futures = [executor.submit(analyze_data, dl) for dl in data_list]
208
  for future in as_completed(futures):
209
  results_list.append(future.result())
210
 
211
- # 결과 정렬(원하는 순서대로) - 여기서는 기업명 기준 or 그냥 순서 없음
212
- for comp, tstamp, count, sentiment in results_list:
 
213
  output += f"### {comp}\n"
214
- output += f"- 마지막 업데이트: {tstamp}\n"
215
  output += f"- 저장된 기사 수: {count}건\n\n"
216
- if sentiment:
217
  output += "#### 뉴스 감성 분석\n"
218
- output += f"{sentiment}\n\n"
219
  output += "---\n\n"
220
 
221
  return output
222
 
223
 
224
- ### (1) 전체 검색: 멀티스레드 적용
225
  def search_all_companies():
226
  """
227
- KOREAN_COMPANIES 리스트 내 모든 기업에 대해,
228
- 검색을 병렬(쓰레드)로 수행 결과를 합쳐 Markdown 형태로 반환
229
  """
230
  overall_result = "# [전체 검색 결과]\n\n"
231
 
@@ -243,8 +281,8 @@ def search_all_companies():
243
 
244
  def load_all_companies():
245
  """
246
- KOREAN_COMPANIES 리스트 내 모든 기업에 대해,
247
- DB에서 불러온 결과를 순차(또는 병렬)로 합쳐서 Markdown 형태로 반환
248
  """
249
  overall_result = "# [전체 출력 결과]\n\n"
250
 
@@ -256,22 +294,22 @@ def load_all_companies():
256
 
257
  def full_summary_report():
258
  """
259
- (1) 모든 기업 검색 -> (2) DB에서 모든 기업 불러오기 -> (3) 감성 분석 통계
260
  순서대로 실행하여, 전체 리포트를 합쳐 반환
261
  """
262
- # 1) 전체 검색(병렬)
263
  search_result_text = search_all_companies()
264
 
265
- # 2) 전체 출력(순차)
266
  load_result_text = load_all_companies()
267
 
268
- # 3) 전체 통계(감성 분석)
269
  stats_text = show_stats()
270
 
271
  combined_report = (
272
  "# 전체 분석 보고 요약\n\n"
273
  "아래 순서로 실행되었습니다:\n"
274
- "1. 모든 종목 검색(병렬) 2. 모든 종목 DB 결과 출력 3. 전체 감성 분석 통계\n\n"
275
  f"{search_result_text}\n\n"
276
  f"{load_result_text}\n\n"
277
  "## [전체 감성 분석 통계]\n\n"
@@ -280,46 +318,54 @@ def full_summary_report():
280
  return combined_report
281
 
282
 
283
- ### (2) 사용자 임의 검색 + 국가 선택 기능
 
 
284
  def search_custom(query, country):
285
  """
286
- 사용자가 입력한 (query, country) 대상으로
287
- - 검색 (API 요청)
288
- - DB 저장
289
- - DB 로드 후 감성 분석
290
- - 최종 결과를 Markdown 형태로 반환
291
  """
292
- # 1) 검색
293
  error_message, articles = serphouse_search(query, country)
294
  if error_message:
295
  return f"오류 발생: {error_message}"
296
  if not articles:
297
  return "검색 결과가 없습니다."
298
 
299
- # 2) DB 저장
300
- save_to_db(query, country, articles)
301
 
302
- # 3) DB에서 다시 불러오기
303
- results, timestamp = load_from_db(query, country)
304
- if not results:
305
- return f"DB 로드 실패: 저장된 결과가 없습니다."
 
 
306
 
307
- # 4) 감성 분석
308
- sentiment_analysis = analyze_sentiment_batch(results, client)
 
 
 
 
 
 
 
 
 
 
 
309
 
310
- # 5) 최종 리포트(기사 목록 + 감성 분석)
311
- output = f"## [사용자 임의 검색 결과]\n\n"
312
- output += f"**키워드**: {query}\n\n"
313
- output += f"**국가**: {country}\n\n"
314
- output += f"**저장 시간**: {timestamp}\n\n"
315
- output += display_results(results)
316
 
317
- output += "### 뉴스 감성 분석\n"
318
- output += f"{sentiment_analysis}\n"
319
- return output
320
 
321
 
322
- ### (필수) API 인증
 
 
323
  ACCESS_TOKEN = os.getenv("HF_TOKEN")
324
  if not ACCESS_TOKEN:
325
  raise ValueError("HF_TOKEN environment variable is not set")
@@ -332,7 +378,9 @@ client = OpenAI(
332
  API_KEY = os.getenv("SERPHOUSE_API_KEY")
333
 
334
 
335
- ### 국가별 설정
 
 
336
  COUNTRY_LANGUAGES = {
337
  "United States": "en",
338
  "KOREA": "ko",
@@ -840,7 +888,7 @@ with gr.Blocks(theme="Yntec/HaleyCH_Theme_Orange", css=css, title="NewsAI 서비
840
  gr.Markdown("## EarnBot: 글로벌 빅테크 기업 및 투자 전망 AI 자동 분석")
841
  gr.Markdown(" * '전체 분석 보고 요약' 클릭 시 전체 자동 보고 생성.\n * 아래 개별 종목의 '검색(DB 자동 저장)'과 '출력(DB 자동 호출)'도 가능.\n * 추가로, 원하는 임의 키워드 및 국가로 검색/분석할 수도 있습니다.")
842
 
843
- # (2) 사용자 임의 검색 섹션
844
  with gr.Group():
845
  gr.Markdown("### 사용자 임의 검색")
846
  with gr.Row():
@@ -876,7 +924,7 @@ with gr.Blocks(theme="Yntec/HaleyCH_Theme_Orange", css=css, title="NewsAI 서비
876
  outputs=full_report_display
877
  )
878
 
879
- # 기존 개별 기업 검색/출력 영역
880
  with gr.Column():
881
  for i in range(0, len(KOREAN_COMPANIES), 2):
882
  with gr.Row():
 
141
  output += f"요약: {article['snippet']}\n\n"
142
  return output
143
 
144
+
145
+ ########################################
146
+ # 1) 검색 시 => 기사 + 분석 동시 출력, DB 저장
147
+ ########################################
148
  def search_company(company):
149
  """
150
+ 단일 기업(또는 키워드)에 대해 미국 뉴스 검색 후,
151
+ 1) 기사 목록 + 2) 감성 분석 보고를 함께 출력
152
+ => { "articles": [...], "analysis": ... } 형태로 DB에 저장
153
  """
154
  error_message, articles = serphouse_search(company, "United States")
155
  if not error_message and articles:
156
+ # 감성 분석
157
+ analysis = analyze_sentiment_batch(articles, client)
158
+
159
+ # DB 저장용 데이터 구성
160
+ store_dict = {
161
+ "articles": articles,
162
+ "analysis": analysis
163
+ }
164
+ save_to_db(company, "United States", store_dict)
165
+
166
+ # 화면 출력용
167
+ output = display_results(articles)
168
+ output += f"\n\n### 분석 보고\n{analysis}\n"
169
+ return output
170
  return f"{company}에 대한 검색 결과가 없습니다."
171
 
172
+ ########################################
173
+ # 2) 출력 시 => DB에 저장된 기사 + 분석 함께 출력
174
+ ########################################
175
  def load_company(company):
176
  """
177
+ DB에서 단일 기업(또는 키워드)의 미국 뉴스 검색 결과를 불러와
178
+ 기사 목록 + 분석 결과를 함께 출력
179
  """
180
+ data, timestamp = load_from_db(company, "United States")
181
+ if data:
182
+ # data는 { "articles": [...], "analysis": "..."} 형태
183
+ articles = data.get("articles", [])
184
+ analysis = data.get("analysis", "")
185
+
186
+ output = f"### {company} 검색 결과\n저장 시간: {timestamp}\n\n"
187
+ output += display_results(articles)
188
+ output += f"\n\n### 분석 보고\n{analysis}\n"
189
+ return output
190
  return f"{company}에 대한 저장된 결과가 없습니다."
191
 
192
+
193
+ ########################################
194
+ # 3) 기존 show_stats()에서 리포트 제목 변경
195
+ ########################################
196
  def show_stats():
197
  """
198
  KOREAN_COMPANIES 목록 내 모든 기업에 대해:
199
  - 가장 최근 DB 저장 일자
200
  - 기사 수
201
  - 감성 분석 결과
202
+ 병렬처리로 조회하여 보고서 형태로 반환
203
+
204
+ (문구 변경) "한국 기업 뉴스 분석 리포트" -> "EarnBOT 분석 리포트"
205
  """
206
  conn = sqlite3.connect("search_results.db")
207
  c = conn.cursor()
208
 
209
+ output = "## EarnBOT 분석 리포트\n\n" # 여기서 문구 변경
210
 
211
  # 모든 기업에 대해 DB에서 읽어올 (company, timestamp, articles) 목록 수집
212
  data_list = []
 
222
  row = c.fetchone()
223
  if row:
224
  results_json, timestamp = row
225
+ data_list.append((company, timestamp, results_json))
 
 
226
 
227
  conn.close()
228
 
229
+ # 감성 분석 병렬 처리 함수
230
  def analyze_data(item):
231
+ comp, tstamp, results_json = item
232
+ data = json.loads(results_json)
233
+ articles = data.get("articles", [])
234
+ analysis = data.get("analysis", "")
235
+
236
+ count_articles = len(articles)
237
+ # 여기서는 이미 DB에 "analysis"가 들어 있으므로,
238
+ # 굳이 재분석할 필요가 없으면 그대로 사용
239
+ # (필요 시 재분석 가능)
240
+
241
+ return (comp, tstamp, count_articles, analysis)
242
 
 
243
  results_list = []
244
  with ThreadPoolExecutor(max_workers=5) as executor:
245
  futures = [executor.submit(analyze_data, dl) for dl in data_list]
246
  for future in as_completed(futures):
247
  results_list.append(future.result())
248
 
249
+ # 결과 출력
250
+ for comp, tstamp, count, analysis in results_list:
251
+ seoul_time = convert_to_seoul_time(tstamp)
252
  output += f"### {comp}\n"
253
+ output += f"- 마지막 업데이트: {seoul_time}\n"
254
  output += f"- 저장된 기사 수: {count}건\n\n"
255
+ if analysis:
256
  output += "#### 뉴스 감성 분석\n"
257
+ output += f"{analysis}\n\n"
258
  output += "---\n\n"
259
 
260
  return output
261
 
262
 
 
263
  def search_all_companies():
264
  """
265
+ KOREAN_COMPANIES 리스트 내 모든 기업 검색 (멀티스레딩) =>
266
+ => 분석 + DB 저장 => 결과 Markdown 반환
267
  """
268
  overall_result = "# [전체 검색 결과]\n\n"
269
 
 
281
 
282
  def load_all_companies():
283
  """
284
+ KOREAN_COMPANIES 리스트 내 모든 기업 DB 불러오기 =>
285
+ 기사 목록 + 분석 보고 => 결과 Markdown
286
  """
287
  overall_result = "# [전체 출력 결과]\n\n"
288
 
 
294
 
295
  def full_summary_report():
296
  """
297
+ (1) 모든 기업 검색(병렬) -> (2) DB에서 불러오기 -> (3) 감성 분석 통계
298
  순서대로 실행하여, 전체 리포트를 합쳐 반환
299
  """
300
+ # 1) 전체 검색(병렬) => 기사 + 분석 DB 저장
301
  search_result_text = search_all_companies()
302
 
303
+ # 2) 전체 출력 => DB에 저장된 기사 + 분석 결과
304
  load_result_text = load_all_companies()
305
 
306
+ # 3) 전체 통계(감성 분석) - 리포트 제목 변경됨(EarnBOT 분석 리포트)
307
  stats_text = show_stats()
308
 
309
  combined_report = (
310
  "# 전체 분석 보고 요약\n\n"
311
  "아래 순서로 실행되었습니다:\n"
312
+ "1. 모든 종목 검색(병렬) + 분석 => 2. 모든 종목 DB 결과 출력 => 3. 전체 감성 분석 통계\n\n"
313
  f"{search_result_text}\n\n"
314
  f"{load_result_text}\n\n"
315
  "## [전체 감성 분석 통계]\n\n"
 
318
  return combined_report
319
 
320
 
321
+ ########################################
322
+ # 사용자 임의 검색 (추가 기능)
323
+ ########################################
324
  def search_custom(query, country):
325
  """
326
+ 사용자가 입력한 (query, country) 대해
327
+ 1) 검색 + 분석 => DB 저장
328
+ 2) DB 로드 => 결과(기사 목록 + 분석) 출력
 
 
329
  """
 
330
  error_message, articles = serphouse_search(query, country)
331
  if error_message:
332
  return f"오류 발생: {error_message}"
333
  if not articles:
334
  return "검색 결과가 없습니다."
335
 
336
+ # 1) 분석
337
+ analysis = analyze_sentiment_batch(articles, client)
338
 
339
+ # 2) DB 저장
340
+ save_data = {
341
+ "articles": articles,
342
+ "analysis": analysis
343
+ }
344
+ save_to_db(query, country, save_data)
345
 
346
+ # 3) DB 재로드
347
+ loaded_data, timestamp = load_from_db(query, country)
348
+ if not loaded_data:
349
+ return "DB에서 로드 실패"
350
+
351
+ # 4) 결과 표시
352
+ out = f"## [사용자 임의 검색 결과]\n\n"
353
+ out += f"**키워드**: {query}\n\n"
354
+ out += f"**국가**: {country}\n\n"
355
+ out += f"**저장 시간**: {timestamp}\n\n"
356
+
357
+ arts = loaded_data.get("articles", [])
358
+ analy = loaded_data.get("analysis", "")
359
 
360
+ out += display_results(arts)
361
+ out += f"### 뉴스 감성 분석\n{analy}\n"
 
 
 
 
362
 
363
+ return out
 
 
364
 
365
 
366
+ ########################################
367
+ # API 인증
368
+ ########################################
369
  ACCESS_TOKEN = os.getenv("HF_TOKEN")
370
  if not ACCESS_TOKEN:
371
  raise ValueError("HF_TOKEN environment variable is not set")
 
378
  API_KEY = os.getenv("SERPHOUSE_API_KEY")
379
 
380
 
381
+ ########################################
382
+ # 국가별 설정
383
+ ########################################
384
  COUNTRY_LANGUAGES = {
385
  "United States": "en",
386
  "KOREA": "ko",
 
888
  gr.Markdown("## EarnBot: 글로벌 빅테크 기업 및 투자 전망 AI 자동 분석")
889
  gr.Markdown(" * '전체 분석 보고 요약' 클릭 시 전체 자동 보고 생성.\n * 아래 개별 종목의 '검색(DB 자동 저장)'과 '출력(DB 자동 호출)'도 가능.\n * 추가로, 원하는 임의 키워드 및 국가로 검색/분석할 수도 있습니다.")
890
 
891
+ # (사용자 임의 검색 섹션)
892
  with gr.Group():
893
  gr.Markdown("### 사용자 임의 검색")
894
  with gr.Row():
 
924
  outputs=full_report_display
925
  )
926
 
927
+ # 지정된 리스트 (KOREAN_COMPANIES) 개별 기업 검색/출력
928
  with gr.Column():
929
  for i in range(0, len(KOREAN_COMPANIES), 2):
930
  with gr.Row():