Update app.py
Browse files
app.py
CHANGED
@@ -313,21 +313,27 @@ def serphouse_search(query, country):
|
|
313 |
css = """
|
314 |
footer {visibility: hidden;}
|
315 |
|
316 |
-
|
317 |
-
#global_results_container {
|
318 |
-
margin-top: 20px;
|
319 |
-
padding-top: 20px;
|
320 |
-
}
|
321 |
-
|
322 |
-
/* ์งํ ์ํ ์ปจํ
์ด๋ ์คํ์ผ */
|
323 |
-
#progress_status_container {
|
324 |
position: sticky;
|
325 |
top: 0;
|
326 |
-
background: white;
|
327 |
padding: 10px;
|
328 |
-
margin-bottom: 20px;
|
329 |
border-bottom: 2px solid #eee;
|
330 |
-
z-index:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
331 |
}
|
332 |
"""
|
333 |
|
@@ -343,12 +349,8 @@ with gr.Blocks(theme="Nymbo/Nymbo_Theme", css=css, title="NewsAI ์๋น์ค") as
|
|
343 |
query = gr.Textbox(label="๊ฒ์์ด")
|
344 |
country = gr.Dropdown(MAJOR_COUNTRIES, label="๊ตญ๊ฐ", value="South Korea")
|
345 |
|
346 |
-
# ๊ฒ์ ์ํ ๋ฉ์์ง
|
347 |
status_message = gr.Markdown("", visible=True)
|
348 |
-
|
349 |
-
# ๋ฒ์ญ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ฌ์ฃผ๋ ์ปดํฌ๋ํธ
|
350 |
translated_query_display = gr.Markdown(visible=False)
|
351 |
-
|
352 |
search_button = gr.Button("๊ฒ์", variant="primary")
|
353 |
|
354 |
progress = gr.Progress()
|
@@ -371,28 +373,24 @@ with gr.Blocks(theme="Nymbo/Nymbo_Theme", css=css, title="NewsAI ์๋น์ค") as
|
|
371 |
'index': i,
|
372 |
})
|
373 |
|
|
|
374 |
with gr.Tab("์ ์ธ๊ณ"):
|
375 |
gr.Markdown("๊ฒ์์ด๋ฅผ ์
๋ ฅํ๋ฉด 67๊ฐ๊ตญ์ 24์๊ฐ ์ด๋ด ๋ด์ค๋ฅผ ์ต๋ 1000๊ฐ ์ถ๋ ฅํฉ๋๋ค.")
|
376 |
-
|
377 |
with gr.Column():
|
378 |
-
# ์๋จ ๊ฒ์ ์์ญ
|
379 |
with gr.Row():
|
380 |
query_global = gr.Textbox(label="๊ฒ์์ด")
|
381 |
search_button_global = gr.Button("์ ์ธ๊ณ ๊ฒ์", variant="primary")
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
progress_global = gr.Progress()
|
388 |
-
|
389 |
-
# ๊ตฌ๋ถ์
|
390 |
gr.Markdown("---")
|
391 |
-
|
392 |
-
|
393 |
-
with gr.Column(elem_id="global_results_container"):
|
394 |
articles_state_global = gr.State([])
|
395 |
-
|
396 |
global_article_components = []
|
397 |
for i in range(1000):
|
398 |
with gr.Group(visible=False) as article_group:
|
@@ -400,7 +398,7 @@ with gr.Blocks(theme="Nymbo/Nymbo_Theme", css=css, title="NewsAI ์๋น์ค") as
|
|
400 |
image = gr.Image(width=200, height=150)
|
401 |
snippet = gr.Markdown()
|
402 |
info = gr.Markdown()
|
403 |
-
|
404 |
global_article_components.append({
|
405 |
'group': article_group,
|
406 |
'title': title,
|
@@ -410,16 +408,10 @@ with gr.Blocks(theme="Nymbo/Nymbo_Theme", css=css, title="NewsAI ์๋น์ค") as
|
|
410 |
'index': i,
|
411 |
})
|
412 |
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
def search_and_display(query, country, articles_state, progress=gr.Progress()):
|
417 |
-
# ๊ฒ์ ์ํ ๋ฉ์์ง ์
๋ฐ์ดํธ
|
418 |
status_msg = "๊ฒ์์ ์งํ์ค์
๋๋ค. ์ ์๋ง ๊ธฐ๋ค๋ฆฌ์ธ์..."
|
419 |
|
420 |
progress(0, desc="๊ฒ์์ด ๋ฒ์ญ ์ค...")
|
421 |
-
|
422 |
-
# ๊ฒ์์ด ๋ฒ์ญ
|
423 |
translated_query = translate_query(query, country)
|
424 |
translated_display = f"**์๋ณธ ๊ฒ์์ด:** {query}\n**๋ฒ์ญ๋ ๊ฒ์์ด:** {translated_query}" if translated_query != query else f"**๊ฒ์์ด:** {query}"
|
425 |
|
@@ -428,8 +420,8 @@ with gr.Blocks(theme="Nymbo/Nymbo_Theme", css=css, title="NewsAI ์๋น์ค") as
|
|
428 |
progress(0.5, desc="๊ฒฐ๊ณผ ์ฒ๋ฆฌ ์ค...")
|
429 |
|
430 |
outputs = []
|
431 |
-
outputs.append(gr.update(value=status_msg, visible=True))
|
432 |
-
outputs.append(gr.update(value=translated_display, visible=True))
|
433 |
|
434 |
if error_message:
|
435 |
outputs.append(gr.update(value=error_message, visible=True))
|
@@ -449,7 +441,6 @@ with gr.Blocks(theme="Nymbo/Nymbo_Theme", css=css, title="NewsAI ์๋น์ค") as
|
|
449 |
image_url = article['image_url']
|
450 |
image_update = gr.update(value=image_url, visible=True) if image_url and not image_url.startswith('data:image') else gr.update(value=None, visible=False)
|
451 |
|
452 |
-
# ์์ฝ ๋ด์ฉ ํ๊ธ ๋ฒ์ญ
|
453 |
korean_summary = translate_to_korean(article['snippet'])
|
454 |
|
455 |
outputs.extend([
|
@@ -468,100 +459,88 @@ with gr.Blocks(theme="Nymbo/Nymbo_Theme", css=css, title="NewsAI ์๋น์ค") as
|
|
468 |
|
469 |
progress(1.0, desc="์๋ฃ!")
|
470 |
outputs.append(articles_state)
|
471 |
-
|
472 |
-
# ๊ฒ์ ์๋ฃ ํ ์ํ ๋ฉ์์ง ์จ๊น
|
473 |
outputs[0] = gr.update(value="", visible=False)
|
474 |
|
475 |
return outputs
|
476 |
|
477 |
def search_global(query, articles_state_global, progress=gr.Progress()):
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
if not error_message and articles:
|
504 |
-
for article in articles:
|
505 |
-
article['source_country'] = country
|
506 |
-
|
507 |
-
all_results.extend(articles)
|
508 |
-
sorted_results = sorted(all_results, key=lambda x: x.get('time', ''), reverse=True)
|
509 |
-
|
510 |
-
# ์ค๋ณต ์ ๊ฑฐ
|
511 |
-
seen_urls = set()
|
512 |
-
unique_results = []
|
513 |
-
for article in sorted_results:
|
514 |
-
url = article.get('link', '')
|
515 |
-
if url not in seen_urls:
|
516 |
-
seen_urls.add(url)
|
517 |
-
unique_results.append(article)
|
518 |
-
|
519 |
-
unique_results = unique_results[:1000]
|
520 |
-
|
521 |
-
# ๊ฒฐ๊ณผ ์ถ๋ ฅ ์
๋ฐ์ดํธ
|
522 |
-
outputs = []
|
523 |
-
# ์๋จ ์ํ ํ์ ์
๋ฐ์ดํธ
|
524 |
-
outputs.append(gr.update(
|
525 |
-
value=f"๊ฒ์ ์งํ ์ค... ({idx + 1}/{len(COUNTRY_LOCATIONS)} ๊ตญ๊ฐ ์๋ฃ)\nํ์ฌ๊น์ง ๋ฐ๊ฒฌ๋ ๋ด์ค: {len(unique_results)}๊ฑด",
|
526 |
-
visible=True
|
527 |
-
))
|
528 |
-
outputs.append(gr.update(value=f"**๊ฒ์์ด:** {query}", visible=True))
|
529 |
-
|
530 |
-
# ๊ฒฐ๊ณผ ์ปดํฌ๋ํธ ์
๋ฐ์ดํธ
|
531 |
-
for idx, comp in enumerate(global_article_components):
|
532 |
-
if idx < len(unique_results):
|
533 |
-
article = unique_results[idx]
|
534 |
-
image_url = article.get('image_url', '')
|
535 |
-
image_update = gr.update(value=image_url, visible=True) if image_url and not image_url.startswith('data:image') else gr.update(value=None, visible=False)
|
536 |
-
|
537 |
-
korean_summary = translate_to_korean(article['snippet'])
|
538 |
-
|
539 |
-
outputs.extend([
|
540 |
-
gr.update(visible=True),
|
541 |
-
gr.update(value=f"### [{article['title']}]({article['link']})"),
|
542 |
-
image_update,
|
543 |
-
gr.update(value=f"**์์ฝ:** {article['snippet']}\n\n**ํ๊ธ ์์ฝ:** {korean_summary}"),
|
544 |
-
gr.update(value=f"**์ถ์ฒ:** {article['channel']} | **๊ตญ๊ฐ:** {article['source_country']} | **์๊ฐ:** {article['time']}")
|
545 |
-
])
|
546 |
-
else:
|
547 |
-
outputs.extend([
|
548 |
-
gr.update(visible=False), gr.update(), gr.update(),
|
549 |
-
gr.update(), gr.update()
|
550 |
-
])
|
551 |
-
|
552 |
-
outputs.append(unique_results)
|
553 |
-
yield outputs
|
554 |
-
|
555 |
-
except Exception as e:
|
556 |
-
print(f"Error searching {country}: {str(e)}")
|
557 |
-
continue
|
558 |
-
|
559 |
-
# ์ต์ข
์ํ ์
๋ฐ์ดํธ
|
560 |
-
final_status = f"๊ฒ์ ์๋ฃ! ์ด {len(unique_results)}๊ฐ์ ๋ด์ค๊ฐ ๋ฐ๊ฒฌ๋์์ต๋๋ค."
|
561 |
-
outputs[0] = gr.update(value=final_status, visible=True)
|
562 |
-
yield outputs
|
563 |
|
564 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
565 |
|
566 |
search_outputs = [
|
567 |
status_message,
|
@@ -583,7 +562,6 @@ with gr.Blocks(theme="Nymbo/Nymbo_Theme", css=css, title="NewsAI ์๋น์ค") as
|
|
583 |
show_progress=True
|
584 |
)
|
585 |
|
586 |
-
# ์ ์ธ๊ณ ๊ฒ์ ์ด๋ฒคํธ ์ฐ๊ฒฐ
|
587 |
global_search_outputs = [
|
588 |
status_message_global,
|
589 |
translated_query_display_global,
|
|
|
313 |
css = """
|
314 |
footer {visibility: hidden;}
|
315 |
|
316 |
+
#status_area {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
317 |
position: sticky;
|
318 |
top: 0;
|
319 |
+
background-color: white;
|
320 |
padding: 10px;
|
|
|
321 |
border-bottom: 2px solid #eee;
|
322 |
+
z-index: 1000;
|
323 |
+
margin-bottom: 20px;
|
324 |
+
}
|
325 |
+
|
326 |
+
#results_area {
|
327 |
+
margin-top: 20px;
|
328 |
+
padding-top: 10px;
|
329 |
+
}
|
330 |
+
|
331 |
+
.progress-container {
|
332 |
+
display: none !important;
|
333 |
+
}
|
334 |
+
|
335 |
+
.progress-container:first-child {
|
336 |
+
display: block !important;
|
337 |
}
|
338 |
"""
|
339 |
|
|
|
349 |
query = gr.Textbox(label="๊ฒ์์ด")
|
350 |
country = gr.Dropdown(MAJOR_COUNTRIES, label="๊ตญ๊ฐ", value="South Korea")
|
351 |
|
|
|
352 |
status_message = gr.Markdown("", visible=True)
|
|
|
|
|
353 |
translated_query_display = gr.Markdown(visible=False)
|
|
|
354 |
search_button = gr.Button("๊ฒ์", variant="primary")
|
355 |
|
356 |
progress = gr.Progress()
|
|
|
373 |
'index': i,
|
374 |
})
|
375 |
|
376 |
+
# ์ ์ธ๊ณ ํญ
|
377 |
with gr.Tab("์ ์ธ๊ณ"):
|
378 |
gr.Markdown("๊ฒ์์ด๋ฅผ ์
๋ ฅํ๋ฉด 67๊ฐ๊ตญ์ 24์๊ฐ ์ด๋ด ๋ด์ค๋ฅผ ์ต๋ 1000๊ฐ ์ถ๋ ฅํฉ๋๋ค.")
|
379 |
+
|
380 |
with gr.Column():
|
|
|
381 |
with gr.Row():
|
382 |
query_global = gr.Textbox(label="๊ฒ์์ด")
|
383 |
search_button_global = gr.Button("์ ์ธ๊ณ ๊ฒ์", variant="primary")
|
384 |
+
|
385 |
+
with gr.Column(elem_id="status_area", visible=True):
|
386 |
+
status_message_global = gr.Markdown("")
|
387 |
+
progress_global = gr.Progress(track_tqdm=True)
|
388 |
+
|
|
|
|
|
|
|
389 |
gr.Markdown("---")
|
390 |
+
|
391 |
+
with gr.Column(elem_id="results_area"):
|
|
|
392 |
articles_state_global = gr.State([])
|
393 |
+
|
394 |
global_article_components = []
|
395 |
for i in range(1000):
|
396 |
with gr.Group(visible=False) as article_group:
|
|
|
398 |
image = gr.Image(width=200, height=150)
|
399 |
snippet = gr.Markdown()
|
400 |
info = gr.Markdown()
|
401 |
+
|
402 |
global_article_components.append({
|
403 |
'group': article_group,
|
404 |
'title': title,
|
|
|
408 |
'index': i,
|
409 |
})
|
410 |
|
|
|
|
|
|
|
411 |
def search_and_display(query, country, articles_state, progress=gr.Progress()):
|
|
|
412 |
status_msg = "๊ฒ์์ ์งํ์ค์
๋๋ค. ์ ์๋ง ๊ธฐ๋ค๋ฆฌ์ธ์..."
|
413 |
|
414 |
progress(0, desc="๊ฒ์์ด ๋ฒ์ญ ์ค...")
|
|
|
|
|
415 |
translated_query = translate_query(query, country)
|
416 |
translated_display = f"**์๋ณธ ๊ฒ์์ด:** {query}\n**๋ฒ์ญ๋ ๊ฒ์์ด:** {translated_query}" if translated_query != query else f"**๊ฒ์์ด:** {query}"
|
417 |
|
|
|
420 |
progress(0.5, desc="๊ฒฐ๊ณผ ์ฒ๋ฆฌ ์ค...")
|
421 |
|
422 |
outputs = []
|
423 |
+
outputs.append(gr.update(value=status_msg, visible=True))
|
424 |
+
outputs.append(gr.update(value=translated_display, visible=True))
|
425 |
|
426 |
if error_message:
|
427 |
outputs.append(gr.update(value=error_message, visible=True))
|
|
|
441 |
image_url = article['image_url']
|
442 |
image_update = gr.update(value=image_url, visible=True) if image_url and not image_url.startswith('data:image') else gr.update(value=None, visible=False)
|
443 |
|
|
|
444 |
korean_summary = translate_to_korean(article['snippet'])
|
445 |
|
446 |
outputs.extend([
|
|
|
459 |
|
460 |
progress(1.0, desc="์๋ฃ!")
|
461 |
outputs.append(articles_state)
|
|
|
|
|
462 |
outputs[0] = gr.update(value="", visible=False)
|
463 |
|
464 |
return outputs
|
465 |
|
466 |
def search_global(query, articles_state_global, progress=gr.Progress()):
|
467 |
+
status_msg = "์ ์ธ๊ณ ๊ฒ์์ ์งํ์ค์
๋๋ค. ์ค์๊ฐ์ผ๋ก ๊ฒฐ๊ณผ๊ฐ ์ถ๋ ฅ๋ฉ๋๋ค..."
|
468 |
+
all_results = []
|
469 |
+
|
470 |
+
outputs = [
|
471 |
+
gr.update(value=status_msg, visible=True),
|
472 |
+
gr.update(value="", visible=False),
|
473 |
+
]
|
474 |
+
|
475 |
+
for _ in global_article_components:
|
476 |
+
outputs.extend([
|
477 |
+
gr.update(visible=False), gr.update(), gr.update(),
|
478 |
+
gr.update(), gr.update()
|
479 |
+
])
|
480 |
+
outputs.append([])
|
481 |
+
|
482 |
+
yield outputs
|
483 |
+
|
484 |
+
for idx, (country, location) in enumerate(COUNTRY_LOCATIONS.items()):
|
485 |
+
progress((idx + 1) / len(COUNTRY_LOCATIONS), f"์งํ ์ํฉ: {idx + 1}/{len(COUNTRY_LOCATIONS)} ๊ตญ๊ฐ ๊ฒ์ ์ค... (ํ์ฌ: {country})")
|
486 |
+
|
487 |
+
try:
|
488 |
+
error_message, articles = serphouse_search(query, country)
|
489 |
+
if not error_message and articles:
|
490 |
+
for article in articles:
|
491 |
+
article['source_country'] = country
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
492 |
|
493 |
+
all_results.extend(articles)
|
494 |
+
sorted_results = sorted(all_results, key=lambda x: x.get('time', ''), reverse=True)
|
495 |
+
|
496 |
+
seen_urls = set()
|
497 |
+
unique_results = []
|
498 |
+
for article in sorted_results:
|
499 |
+
url = article.get('link', '')
|
500 |
+
if url not in seen_urls:
|
501 |
+
seen_urls.add(url)
|
502 |
+
unique_results.append(article)
|
503 |
+
|
504 |
+
unique_results = unique_results[:1000]
|
505 |
+
|
506 |
+
outputs = []
|
507 |
+
outputs.append(gr.update(
|
508 |
+
value=f"๊ฒ์ ์งํ ์ค... ({idx + 1}/{len(COUNTRY_LOCATIONS)} ๊ตญ๊ฐ ์๋ฃ)\nํ์ฌ๊น์ง ๋ฐ๊ฒฌ๋ ๋ด์ค: {len(unique_results)}๊ฑด",
|
509 |
+
visible=True
|
510 |
+
))
|
511 |
+
outputs.append(gr.update(value=f"**๊ฒ์์ด:** {query}", visible=True))
|
512 |
+
|
513 |
+
for idx, comp in enumerate(global_article_components):
|
514 |
+
if idx < len(unique_results):
|
515 |
+
article = unique_results[idx]
|
516 |
+
image_url = article.get('image_url', '')
|
517 |
+
image_update = gr.update(value=image_url, visible=True) if image_url and not image_url.startswith('data:image') else gr.update(value=None, visible=False)
|
518 |
+
|
519 |
+
korean_summary = translate_to_korean(article['snippet'])
|
520 |
+
|
521 |
+
outputs.extend([
|
522 |
+
gr.update(visible=True),
|
523 |
+
gr.update(value=f"### [{article['title']}]({article['link']})"),
|
524 |
+
image_update,
|
525 |
+
gr.update(value=f"**์์ฝ:** {article['snippet']}\n\n**ํ๊ธ ์์ฝ:** {korean_summary}"),
|
526 |
+
gr.update(value=f"**์ถ์ฒ:** {article['channel']} | **๊ตญ๊ฐ:** {article['source_country']} | **์๊ฐ:** {article['time']}")
|
527 |
+
])
|
528 |
+
else:
|
529 |
+
outputs.extend([
|
530 |
+
gr.update(visible=False), gr.update(), gr.update(),
|
531 |
+
gr.update(), gr.update()
|
532 |
+
])
|
533 |
+
|
534 |
+
outputs.append(unique_results)
|
535 |
+
yield outputs
|
536 |
+
|
537 |
+
except Exception as e:
|
538 |
+
print(f"Error searching {country}: {str(e)}")
|
539 |
+
continue
|
540 |
+
|
541 |
+
final_status = f"๊ฒ์ ์๋ฃ! ์ด {len(unique_results)}๊ฐ์ ๋ด์ค๊ฐ ๋ฐ๊ฒฌ๋์์ต๋๋ค."
|
542 |
+
outputs[0] = gr.update(value=final_status, visible=True)
|
543 |
+
yield outputs
|
544 |
|
545 |
search_outputs = [
|
546 |
status_message,
|
|
|
562 |
show_progress=True
|
563 |
)
|
564 |
|
|
|
565 |
global_search_outputs = [
|
566 |
status_message_global,
|
567 |
translated_query_display_global,
|