openfree commited on
Commit
7683f53
Β·
verified Β·
1 Parent(s): 1e914c8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +258 -26
app.py CHANGED
@@ -180,6 +180,182 @@ COUNTRY_LOCATIONS = {
180
 
181
  MAJOR_COUNTRIES = list(COUNTRY_LOCATIONS.keys())
182
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  def translate_query(query, country):
184
  try:
185
  # μ˜μ–΄ μž…λ ₯ 확인
@@ -822,22 +998,34 @@ with gr.Blocks(theme="Nymbo/Nymbo_Theme", css=css, title="NewsAI μ„œλΉ„μŠ€") as
822
  'index': i,
823
  })
824
 
825
- # 전세계 νƒ­
826
  with gr.Tab("전세계"):
827
- gr.Markdown("검색어λ₯Ό μž…λ ₯ν•˜λ©΄ 67개ꡭ(ν•œκ΅­ μ œμ™Έ) 전체에 λŒ€ν•΄ κ΅­κ°€λ³„λ‘œ κ΅¬λΆ„ν•˜μ—¬ 24μ‹œκ°„ 이내 λ‰΄μŠ€κ°€ μ΅œλŒ€ 1000개 순차 좜λ ₯λ©λ‹ˆλ‹€.")
828
- gr.Markdown("κ΅­κ°€ 선택후 검색어에 'ν•œκΈ€'을 μž…λ ₯ν•˜λ©΄ ν˜„μ§€ μ–Έμ–΄λ‘œ λ²ˆμ—­λ˜μ–΄ κ²€μƒ‰ν•©λ‹ˆλ‹€. 예: 'Taiwan' κ΅­κ°€ 선택후 'μ‚Όμ„±' μž…λ ₯μ‹œ 'δΈ‰ζ˜Ÿ'으둜 μžλ™ 검색")
829
-
830
  with gr.Column():
831
  with gr.Column(elem_id="status_area"):
832
  with gr.Row():
833
  query_global = gr.Textbox(label="검색어")
834
- search_button_global = gr.Button("전세계 검색", variant="primary")
835
-
 
 
 
 
 
 
 
 
 
 
 
 
836
  status_message_global = gr.Markdown("")
837
  translated_query_display_global = gr.Markdown("")
838
-
839
  with gr.Column(elem_id="results_area"):
840
  articles_state_global = gr.State([])
 
 
841
 
842
  global_article_components = []
843
  for i in range(1000):
@@ -947,10 +1135,30 @@ with gr.Blocks(theme="Nymbo/Nymbo_Theme", css=css, title="NewsAI μ„œλΉ„μŠ€") as
947
 
948
  return outputs
949
 
950
- def search_global(query, articles_state_global):
951
- status_msg = "전세계 검색을 μ‹œμž‘ν•©λ‹ˆλ‹€..."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
952
  all_results = []
953
-
954
  outputs = [
955
  gr.update(value=status_msg, visible=True),
956
  gr.update(value=f"**검색어:** {query}", visible=True),
@@ -962,13 +1170,16 @@ with gr.Blocks(theme="Nymbo/Nymbo_Theme", css=css, title="NewsAI μ„œλΉ„μŠ€") as
962
  gr.update(), gr.update()
963
  ])
964
  outputs.append([])
965
-
966
  yield outputs
967
 
968
- total_countries = len(COUNTRY_LOCATIONS)
969
- for idx, (country, location) in enumerate(COUNTRY_LOCATIONS.items(), 1):
 
 
 
970
  try:
971
- status_msg = f"{country} 검색 쀑... ({idx}/{total_countries} κ΅­κ°€)"
972
  outputs[0] = gr.update(value=status_msg, visible=True)
973
  yield outputs
974
 
@@ -976,6 +1187,7 @@ with gr.Blocks(theme="Nymbo/Nymbo_Theme", css=css, title="NewsAI μ„œλΉ„μŠ€") as
976
  if not error_message and articles:
977
  for article in articles:
978
  article['source_country'] = country
 
979
 
980
  all_results.extend(articles)
981
  sorted_results = sorted(all_results, key=lambda x: x.get('time', ''), reverse=True)
@@ -987,14 +1199,14 @@ with gr.Blocks(theme="Nymbo/Nymbo_Theme", css=css, title="NewsAI μ„œλΉ„μŠ€") as
987
  if url not in seen_urls:
988
  seen_urls.add(url)
989
  unique_results.append(article)
990
-
991
- unique_results = unique_results[:1000]
992
-
993
  outputs = [
994
- gr.update(value=f"{idx}/{total_countries} κ΅­κ°€ 검색 μ™„λ£Œ\nν˜„μž¬κΉŒμ§€ 발견된 λ‰΄μŠ€: {len(unique_results)}건", visible=True),
995
- gr.update(value=f"**검색어:** {query}", visible=True),
996
  ]
997
-
998
  for idx, comp in enumerate(global_article_components):
999
  if idx < len(unique_results):
1000
  article = unique_results[idx]
@@ -1008,14 +1220,17 @@ with gr.Blocks(theme="Nymbo/Nymbo_Theme", css=css, title="NewsAI μ„œλΉ„μŠ€") as
1008
  gr.update(value=f"### [{article['title']}]({article['link']})"),
1009
  image_update,
1010
  gr.update(value=f"**μš”μ•½:** {article['snippet']}\n\n**ν•œκΈ€ μš”μ•½:** {korean_summary}"),
1011
- gr.update(value=f"**좜처:** {article['channel']} | **κ΅­κ°€:** {article['source_country']} | **μ‹œκ°„:** {article['time']}")
1012
  ])
1013
  else:
1014
  outputs.extend([
1015
- gr.update(visible=False), gr.update(), gr.update(),
1016
- gr.update(), gr.update()
 
 
 
1017
  ])
1018
-
1019
  outputs.append(unique_results)
1020
  yield outputs
1021
 
@@ -1023,9 +1238,11 @@ with gr.Blocks(theme="Nymbo/Nymbo_Theme", css=css, title="NewsAI μ„œλΉ„μŠ€") as
1023
  print(f"Error searching {country}: {str(e)}")
1024
  continue
1025
 
1026
- final_status = f"검색 μ™„λ£Œ! 총 {len(unique_results)}개의 λ‰΄μŠ€κ°€ λ°œκ²¬λ˜μ—ˆμŠ΅λ‹ˆλ‹€."
1027
  outputs[0] = gr.update(value=final_status, visible=True)
1028
  yield outputs
 
 
1029
 
1030
 
1031
 
@@ -1053,11 +1270,26 @@ with gr.Blocks(theme="Nymbo/Nymbo_Theme", css=css, title="NewsAI μ„œλΉ„μŠ€") as
1053
  show_progress=True
1054
  )
1055
 
 
1056
  # 전세계 νƒ­ 이벀트 μ—°κ²°
1057
  global_search_outputs = [
1058
  status_message_global,
1059
- translated_query_display_global,
1060
  ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1061
 
1062
  # AI 리포터 νƒ­ 이벀트 μ—°κ²°
1063
  hn_outputs = [status_message_hn]
 
180
 
181
  MAJOR_COUNTRIES = list(COUNTRY_LOCATIONS.keys())
182
 
183
+ # λ™μ•„μ‹œμ•„ μ§€μ—­
184
+ COUNTRY_LANGUAGES_EAST_ASIA = {
185
+ "Taiwan": "zh-TW",
186
+ "Japan": "ja",
187
+ "China": "zh",
188
+ "South Korea": "ko",
189
+ "Hong Kong": "zh-HK"
190
+ }
191
+
192
+ COUNTRY_LOCATIONS_EAST_ASIA = {
193
+ "Taiwan": "Taiwan",
194
+ "Japan": "Japan",
195
+ "China": "China",
196
+ "South Korea": "South Korea",
197
+ "Hong Kong": "Hong Kong"
198
+ }
199
+
200
+ # λ™λ‚¨μ•„μ‹œμ•„/μ˜€μ„Έμ•„λ‹ˆμ•„ μ§€μ—­
201
+ COUNTRY_LANGUAGES_SOUTHEAST_ASIA_OCEANIA = {
202
+ "Indonesia": "id",
203
+ "Malaysia": "ms",
204
+ "Philippines": "tl",
205
+ "Thailand": "th",
206
+ "Vietnam": "vi",
207
+ "Singapore": "en",
208
+ "Papua New Guinea": "en",
209
+ "Australia": "en",
210
+ "New Zealand": "en"
211
+ }
212
+
213
+ COUNTRY_LOCATIONS_SOUTHEAST_ASIA_OCEANIA = {
214
+ "Indonesia": "Indonesia",
215
+ "Malaysia": "Malaysia",
216
+ "Philippines": "Philippines",
217
+ "Thailand": "Thailand",
218
+ "Vietnam": "Vietnam",
219
+ "Singapore": "Singapore",
220
+ "Papua New Guinea": "Papua New Guinea",
221
+ "Australia": "Australia",
222
+ "New Zealand": "New Zealand"
223
+ }
224
+
225
+ # λ™μœ λŸ½ μ§€μ—­
226
+ COUNTRY_LANGUAGES_EAST_EUROPE = {
227
+ "Poland": "pl",
228
+ "Czech Republic": "cs",
229
+ "Greece": "el",
230
+ "Hungary": "hu",
231
+ "Romania": "ro",
232
+ "Ukraine": "uk",
233
+ "Croatia": "hr",
234
+ "Slovakia": "sk",
235
+ "Bulgaria": "bg",
236
+ "Serbia": "sr",
237
+ "Estonia": "et",
238
+ "Latvia": "lv",
239
+ "Lithuania": "lt",
240
+ "Slovenia": "sl",
241
+ "Malta": "mt",
242
+ "Cyprus": "el",
243
+ "Iceland": "is",
244
+ "Russia": "ru"
245
+ }
246
+
247
+ COUNTRY_LOCATIONS_EAST_EUROPE = {
248
+ "Poland": "Poland",
249
+ "Czech Republic": "Czech Republic",
250
+ "Greece": "Greece",
251
+ "Hungary": "Hungary",
252
+ "Romania": "Romania",
253
+ "Ukraine": "Ukraine",
254
+ "Croatia": "Croatia",
255
+ "Slovakia": "Slovakia",
256
+ "Bulgaria": "Bulgaria",
257
+ "Serbia": "Serbia",
258
+ "Estonia": "Estonia",
259
+ "Latvia": "Latvia",
260
+ "Lithuania": "Lithuania",
261
+ "Slovenia": "Slovenia",
262
+ "Malta": "Malta",
263
+ "Cyprus": "Cyprus",
264
+ "Iceland": "Iceland",
265
+ "Russia": "Russia"
266
+ }
267
+
268
+ # μ„œμœ λŸ½ μ§€μ—­
269
+ COUNTRY_LANGUAGES_WEST_EUROPE = {
270
+ "Germany": "de",
271
+ "France": "fr",
272
+ "Italy": "it",
273
+ "Spain": "es",
274
+ "Netherlands": "nl",
275
+ "Belgium": "nl",
276
+ "Ireland": "en",
277
+ "Sweden": "sv",
278
+ "Switzerland": "de",
279
+ "Austria": "de",
280
+ "Portugal": "pt",
281
+ "Luxembourg": "fr",
282
+ "United Kingdom": "en"
283
+ }
284
+
285
+ COUNTRY_LOCATIONS_WEST_EUROPE = {
286
+ "Germany": "Germany",
287
+ "France": "France",
288
+ "Italy": "Italy",
289
+ "Spain": "Spain",
290
+ "Netherlands": "Netherlands",
291
+ "Belgium": "Belgium",
292
+ "Ireland": "Ireland",
293
+ "Sweden": "Sweden",
294
+ "Switzerland": "Switzerland",
295
+ "Austria": "Austria",
296
+ "Portugal": "Portugal",
297
+ "Luxembourg": "Luxembourg",
298
+ "United Kingdom": "United Kingdom"
299
+ }
300
+
301
+ # 쀑동/아프리카 μ§€μ—­
302
+ COUNTRY_LANGUAGES_ARAB_AFRICA = {
303
+ "South Africa": "en",
304
+ "Nigeria": "en",
305
+ "Kenya": "sw",
306
+ "Egypt": "ar",
307
+ "Morocco": "ar",
308
+ "Saudi Arabia": "ar",
309
+ "United Arab Emirates": "ar",
310
+ "Israel": "he"
311
+ }
312
+
313
+ COUNTRY_LOCATIONS_ARAB_AFRICA = {
314
+ "South Africa": "South Africa",
315
+ "Nigeria": "Nigeria",
316
+ "Kenya": "Kenya",
317
+ "Egypt": "Egypt",
318
+ "Morocco": "Morocco",
319
+ "Saudi Arabia": "Saudi Arabia",
320
+ "United Arab Emirates": "United Arab Emirates",
321
+ "Israel": "Israel"
322
+ }
323
+
324
+ # 아메리카 μ§€μ—­
325
+ COUNTRY_LANGUAGES_AMERICA = {
326
+ "United States": "en",
327
+ "Canada": "en",
328
+ "Mexico": "es",
329
+ "Brazil": "pt",
330
+ "Argentina": "es",
331
+ "Chile": "es",
332
+ "Colombia": "es",
333
+ "Peru": "es",
334
+ "Venezuela": "es"
335
+ }
336
+
337
+ COUNTRY_LOCATIONS_AMERICA = {
338
+ "United States": "United States",
339
+ "Canada": "Canada",
340
+ "Mexico": "Mexico",
341
+ "Brazil": "Brazil",
342
+ "Argentina": "Argentina",
343
+ "Chile": "Chile",
344
+ "Colombia": "Colombia",
345
+ "Peru": "Peru",
346
+ "Venezuela": "Venezuela"
347
+ }
348
+
349
+ # μ§€μ—­ 선택 리슀트
350
+ REGIONS = [
351
+ "λ™μ•„μ‹œμ•„",
352
+ "λ™λ‚¨μ•„μ‹œμ•„/μ˜€μ„Έμ•„λ‹ˆμ•„",
353
+ "λ™μœ λŸ½",
354
+ "μ„œμœ λŸ½",
355
+ "쀑동/아프리카",
356
+ "아메리카"
357
+ ]
358
+
359
  def translate_query(query, country):
360
  try:
361
  # μ˜μ–΄ μž…λ ₯ 확인
 
998
  'index': i,
999
  })
1000
 
 
1001
  with gr.Tab("전세계"):
1002
+ gr.Markdown("λŒ€λ₯™λ³„λ‘œ 24μ‹œκ°„ 이내 λ‰΄μŠ€λ₯Ό κ²€μƒ‰ν•©λ‹ˆλ‹€.")
1003
+
 
1004
  with gr.Column():
1005
  with gr.Column(elem_id="status_area"):
1006
  with gr.Row():
1007
  query_global = gr.Textbox(label="검색어")
1008
+ region_select = gr.Dropdown(
1009
+ choices=[
1010
+ "λ™μ•„μ‹œμ•„",
1011
+ "λ™λ‚¨μ•„μ‹œμ•„/μ˜€μ„Έμ•„λ‹ˆμ•„",
1012
+ "λ™μœ λŸ½",
1013
+ "μ„œμœ λŸ½",
1014
+ "쀑동/아프리카",
1015
+ "아메리카"
1016
+ ],
1017
+ label="μ§€μ—­ 선택",
1018
+ value="λ™μ•„μ‹œμ•„"
1019
+ )
1020
+ search_button_global = gr.Button("검색", variant="primary")
1021
+
1022
  status_message_global = gr.Markdown("")
1023
  translated_query_display_global = gr.Markdown("")
1024
+
1025
  with gr.Column(elem_id="results_area"):
1026
  articles_state_global = gr.State([])
1027
+ global_article_components = create_article_components(MAX_GLOBAL_RESULTS)
1028
+
1029
 
1030
  global_article_components = []
1031
  for i in range(1000):
 
1135
 
1136
  return outputs
1137
 
1138
+
1139
+ def get_region_countries(region):
1140
+ """μ„ νƒλœ μ§€μ—­μ˜ κ΅­κ°€ 및 μ–Έμ–΄ 정보 λ°˜ν™˜"""
1141
+ if region == "λ™μ•„μ‹œμ•„":
1142
+ return COUNTRY_LOCATIONS_EAST_ASIA, COUNTRY_LANGUAGES_EAST_ASIA
1143
+ elif region == "λ™λ‚¨μ•„μ‹œμ•„/μ˜€μ„Έμ•„λ‹ˆμ•„":
1144
+ return COUNTRY_LOCATIONS_SOUTHEAST_ASIA_OCEANIA, COUNTRY_LANGUAGES_SOUTHEAST_ASIA_OCEANIA
1145
+ elif region == "λ™μœ λŸ½":
1146
+ return COUNTRY_LOCATIONS_EAST_EUROPE, COUNTRY_LANGUAGES_EAST_EUROPE
1147
+ elif region == "μ„œμœ λŸ½":
1148
+ return COUNTRY_LOCATIONS_WEST_EUROPE, COUNTRY_LANGUAGES_WEST_EUROPE
1149
+ elif region == "쀑동/아프리카":
1150
+ return COUNTRY_LOCATIONS_ARAB_AFRICA, COUNTRY_LANGUAGES_ARAB_AFRICA
1151
+ elif region == "아메리카":
1152
+ return COUNTRY_LOCATIONS_AMERICA, COUNTRY_LANGUAGES_AMERICA
1153
+ return {}, {}
1154
+
1155
+
1156
+
1157
+ def search_global(query, region, articles_state_global):
1158
+ """지역별 검색 ν•¨μˆ˜"""
1159
+ status_msg = f"{region} μ§€μ—­ 검색을 μ‹œμž‘ν•©λ‹ˆλ‹€..."
1160
  all_results = []
1161
+
1162
  outputs = [
1163
  gr.update(value=status_msg, visible=True),
1164
  gr.update(value=f"**검색어:** {query}", visible=True),
 
1170
  gr.update(), gr.update()
1171
  ])
1172
  outputs.append([])
1173
+
1174
  yield outputs
1175
 
1176
+ # μ„ νƒλœ μ§€μ—­μ˜ κ΅­κ°€ 정보 κ°€μ Έμ˜€κΈ°
1177
+ locations, languages = get_region_countries(region)
1178
+ total_countries = len(locations)
1179
+
1180
+ for idx, (country, location) in enumerate(locations.items(), 1):
1181
  try:
1182
+ status_msg = f"{region} - {country} 검색 쀑... ({idx}/{total_countries} κ΅­κ°€)"
1183
  outputs[0] = gr.update(value=status_msg, visible=True)
1184
  yield outputs
1185
 
 
1187
  if not error_message and articles:
1188
  for article in articles:
1189
  article['source_country'] = country
1190
+ article['region'] = region
1191
 
1192
  all_results.extend(articles)
1193
  sorted_results = sorted(all_results, key=lambda x: x.get('time', ''), reverse=True)
 
1199
  if url not in seen_urls:
1200
  seen_urls.add(url)
1201
  unique_results.append(article)
1202
+
1203
+ unique_results = unique_results[:MAX_GLOBAL_RESULTS]
1204
+
1205
  outputs = [
1206
+ gr.update(value=f"{region} - {idx}/{total_countries} κ΅­κ°€ 검색 μ™„λ£Œ\nν˜„μž¬κΉŒμ§€ 발견된 λ‰΄μŠ€: {len(unique_results)}건", visible=True),
1207
+ gr.update(value=f"**검색어:** {query} | **μ§€μ—­:** {region}", visible=True),
1208
  ]
1209
+
1210
  for idx, comp in enumerate(global_article_components):
1211
  if idx < len(unique_results):
1212
  article = unique_results[idx]
 
1220
  gr.update(value=f"### [{article['title']}]({article['link']})"),
1221
  image_update,
1222
  gr.update(value=f"**μš”μ•½:** {article['snippet']}\n\n**ν•œκΈ€ μš”μ•½:** {korean_summary}"),
1223
+ gr.update(value=f"**좜처:** {article['channel']} | **κ΅­κ°€:** {article['source_country']} | **μ§€μ—­:** {article['region']} | **μ‹œκ°„:** {article['time']}")
1224
  ])
1225
  else:
1226
  outputs.extend([
1227
+ gr.update(visible=False),
1228
+ gr.update(),
1229
+ gr.update(),
1230
+ gr.update(),
1231
+ gr.update()
1232
  ])
1233
+
1234
  outputs.append(unique_results)
1235
  yield outputs
1236
 
 
1238
  print(f"Error searching {country}: {str(e)}")
1239
  continue
1240
 
1241
+ final_status = f"{region} 검색 μ™„λ£Œ! 총 {len(unique_results)}개의 λ‰΄μŠ€κ°€ λ°œκ²¬λ˜μ—ˆμŠ΅λ‹ˆλ‹€."
1242
  outputs[0] = gr.update(value=final_status, visible=True)
1243
  yield outputs
1244
+
1245
+
1246
 
1247
 
1248
 
 
1270
  show_progress=True
1271
  )
1272
 
1273
+
1274
  # 전세계 νƒ­ 이벀트 μ—°κ²°
1275
  global_search_outputs = [
1276
  status_message_global,
1277
+ translated_query_display_global,
1278
  ]
1279
+
1280
+ for comp in global_article_components:
1281
+ global_search_outputs.extend([
1282
+ comp['group'], comp['title'], comp['image'],
1283
+ comp['snippet'], comp['info']
1284
+ ])
1285
+ global_search_outputs.append(articles_state_global)
1286
+
1287
+ search_button_global.click(
1288
+ fn=search_global,
1289
+ inputs=[query_global, region_select, articles_state_global],
1290
+ outputs=global_search_outputs
1291
+ )
1292
+
1293
 
1294
  # AI 리포터 νƒ­ 이벀트 μ—°κ²°
1295
  hn_outputs = [status_message_hn]