carlosdimare commited on
Commit
b92ae70
verified
1 Parent(s): 31c2313

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +140 -162
app.py CHANGED
@@ -1,169 +1,147 @@
1
- import gradio as gr
2
- from transformers import pipeline
3
- import feedparser
4
- from datetime import datetime, timedelta
5
- import pytz
6
  from bs4 import BeautifulSoup
7
- import hashlib
8
- import threading
9
  import pandas as pd
 
10
 
11
- # Global settings
12
- SUMMARIZER_MODELS = {
13
- "Default (facebook/bart-large-cnn)": "facebook/bart-large-cnn",
14
- "Free Model (distilbart-cnn-6-6)": "sshleifer/distilbart-cnn-6-6"
 
 
15
  }
16
- CACHE_SIZE = 500
17
- RSS_FETCH_INTERVAL = timedelta(hours=8)
18
- ARTICLE_LIMIT = 5
19
-
20
- NEWS_SOURCES = {
21
- "Movilizaciones Sindicales": {
22
-
23
- "Pagina12": "https://www.pagina12.com.ar/rss/edicion-impresa",
24
-
25
- }
26
- }
27
-
28
- class NewsCache:
29
- def __init__(self, size):
30
- self.cache = {}
31
- self.size = size
32
- self.lock = threading.Lock()
33
-
34
- def get(self, key):
35
- with self.lock:
36
- return self.cache.get(key)
37
-
38
- def set(self, key, value):
39
- with self.lock:
40
- if len(self.cache) >= self.size:
41
- oldest_key = next(iter(self.cache))
42
- del self.cache[oldest_key]
43
- self.cache[key] = value
44
-
45
- cache = NewsCache(CACHE_SIZE)
46
-
47
- def fetch_rss_news(categories):
48
- articles = []
49
- cutoff_time = datetime.now(pytz.UTC) - RSS_FETCH_INTERVAL
50
- for category in categories:
51
- for source, url in NEWS_SOURCES.get(category, {}).items():
52
- try:
53
- feed = feedparser.parse(url)
54
- for entry in feed.entries:
55
- published = datetime(*entry.published_parsed[:6], tzinfo=pytz.UTC)
56
- if published > cutoff_time:
57
- articles.append({
58
- "title": entry.title,
59
- "description": BeautifulSoup(entry.description, "html.parser").get_text(),
60
- "link": entry.link,
61
- "category": category,
62
- "source": source,
63
- "published": published
64
- })
65
- except Exception:
66
- continue
67
- articles = sorted(articles, key=lambda x: x["published"], reverse=True)[:ARTICLE_LIMIT]
68
- return articles
69
-
70
- def summarize_text(text, model_name):
71
- summarizer = pipeline("summarization", model=model_name, device=-1)
72
- content_hash = hashlib.md5(text.encode()).hexdigest()
73
- cached_summary = cache.get(content_hash)
74
- if cached_summary:
75
- return cached_summary
76
- try:
77
- result = summarizer(text, max_length=120, min_length=40, truncation=True)
78
- summary = result[0]['summary_text']
79
- cache.set(content_hash, summary)
80
- return summary
81
- except Exception:
82
- return "Summary unavailable."
83
-
84
- def summarize_articles(articles, model_name):
85
- summaries = []
86
- for article in articles:
87
- content = article["description"]
88
- summary = summarize_text(content, model_name)
89
- summaries.append(f"""
90
- 馃摪 {article['title']}
91
- - 馃搧 Category: {article['category']}
92
- - 馃挕 Source: {article['source']}
93
- - 馃敆 Read More: {article['link']}
94
- 馃搩 Summary: {summary}
95
- """)
96
- return "\n".join(summaries)
97
-
98
- def generate_summary(selected_categories, model_name):
99
- if not selected_categories:
100
- return "Please select at least one category."
101
- articles = fetch_rss_news(selected_categories)
102
- if not articles:
103
- return "No recent news found in the selected categories."
104
- return summarize_articles(articles, model_name)
105
-
106
- def fetch_union_mobilizations():
107
- articles = []
108
- cutoff_time = datetime.now(pytz.UTC) - timedelta(days=1)
109
- for source, url in NEWS_SOURCES["Movilizaciones Sindicales"].items():
110
- try:
111
- feed = feedparser.parse(url)
112
- for entry in feed.entries:
113
- published = datetime(*entry.published_parsed[:6], tzinfo=pytz.UTC)
114
- if published > cutoff_time:
115
- # Filtrar por movilizaciones sindicales
116
- if "movilizaci贸n" in entry.title.lower() or "sindical" in entry.title.lower():
117
- articles.append({
118
- "title": entry.title,
119
- "description": BeautifulSoup(entry.description, "html.parser").get_text(),
120
- "link": entry.link,
121
- "source": source,
122
- "published": published
123
- })
124
- except Exception:
125
- continue
126
- return articles
127
-
128
- def create_mobilization_table():
129
- articles = fetch_union_mobilizations()
130
- if not articles:
131
- return "No se encontraron movilizaciones sindicales recientes."
132
-
133
- # Crear una tabla con pandas
134
- df = pd.DataFrame(articles)
135
- return df.to_string(index=False)
136
-
137
- # Gradio Interface
138
- demo = gr.Blocks()
139
-
140
- with demo:
141
- gr.Markdown("# 馃摪 AI News Summarizer")
142
- with gr.Row():
143
- categories = gr.CheckboxGroup(
144
- choices=list(NEWS_SOURCES.keys()),
145
- label="Select News Categories"
146
- )
147
- model_selector = gr.Radio(
148
- choices=list(SUMMARIZER_MODELS.keys()),
149
- label="Choose Summarization Model",
150
- value="Default (facebook/bart-large-cnn)"
151
- )
152
- summarize_button = gr.Button("Get News Summary")
153
- summary_output = gr.Textbox(label="News Summary", lines=20)
154
-
155
- def get_summary(selected_categories, selected_model):
156
- model_name = SUMMARIZER_MODELS[selected_model]
157
- return generate_summary(selected_categories, model_name)
158
-
159
- summarize_button.click(get_summary, inputs=[categories, model_selector], outputs=summary_output)
160
-
161
- if __name__ == "__main__":
162
- demo.launch()
163
-
164
-
165
-
166
-
167
 
 
 
 
168
 
 
 
169
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
 
 
 
 
2
  from bs4 import BeautifulSoup
3
+ from transformers import pipeline
 
4
  import pandas as pd
5
+ from datetime import datetime, timedelta
6
 
7
+ # Configuraci贸n inicial
8
+ SITIOS = {
9
+ "Mundo Gremial": "https://www.mundogremial.com.ar",
10
+ "ANRed": "https://www.anred.org",
11
+ "Prensa Obrera": "https://www.prensaobrera.com",
12
+ "La Izquierda Diario": "https://www.laizquierdadiario.com"
13
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
+ # Fecha actual y l铆mite para noticias recientes (煤ltimos 7 d铆as)
16
+ FECHA_ACTUAL = datetime(2025, 1, 28) # Hoy es 28 de enero de 2025
17
+ LIMITE_RECIENTE = FECHA_ACTUAL - timedelta(days=7)
18
 
19
+ # Cargar modelo de IA para an谩lisis de texto
20
+ analizador = pipeline("text-classification", model="deepseek-ai/r1-zero")
21
 
22
+ # Funci贸n para hacer scraping en un sitio
23
+ def scrapear_sitio(url):
24
+ try:
25
+ response = requests.get(url)
26
+ response.raise_for_status()
27
+ soup = BeautifulSoup(response.text, "html.parser")
28
+ return soup
29
+ except Exception as e:
30
+ print(f"Error al scrapear {url}: {e}")
31
+ return None
32
+
33
+ # Funci贸n para extraer noticias de Mundo Gremial
34
+ def extraer_mundo_gremial(soup):
35
+ noticias = []
36
+ for articulo in soup.find_all("article", class_="post"):
37
+ titulo = articulo.find("h2").text.strip()
38
+ enlace = articulo.find("a")["href"]
39
+ contenido = articulo.find("div", class_="entry-content").text.strip()
40
+ fecha_texto = articulo.find("time")["datetime"] # Extraer fecha
41
+ fecha = datetime.strptime(fecha_texto, "%Y-%m-%d") # Convertir a objeto datetime
42
+ noticias.append({"titulo": titulo, "contenido": contenido, "enlace": enlace, "fecha": fecha})
43
+ return noticias
44
+
45
+ # Funci贸n para extraer noticias de ANRed
46
+ def extraer_anred(soup):
47
+ noticias = []
48
+ for articulo in soup.find_all("article"):
49
+ titulo = articulo.find("h2").text.strip()
50
+ enlace = articulo.find("a")["href"]
51
+ contenido = articulo.find("div", class_="entry-content").text.strip()
52
+ fecha_texto = articulo.find("time")["datetime"] # Extraer fecha
53
+ fecha = datetime.strptime(fecha_texto, "%Y-%m-%d") # Convertir a objeto datetime
54
+ noticias.append({"titulo": titulo, "contenido": contenido, "enlace": enlace, "fecha": fecha})
55
+ return noticias
56
+
57
+ # Funci贸n para extraer noticias de Prensa Obrera
58
+ def extraer_prensa_obrera(soup):
59
+ noticias = []
60
+ for articulo in soup.find_all("article"):
61
+ titulo = articulo.find("h2").text.strip()
62
+ enlace = articulo.find("a")["href"]
63
+ contenido = articulo.find("div", class_="entry-content").text.strip()
64
+ fecha_texto = articulo.find("time")["datetime"] # Extraer fecha
65
+ fecha = datetime.strptime(fecha_texto, "%Y-%m-%d") # Convertir a objeto datetime
66
+ noticias.append({"titulo": titulo, "contenido": contenido, "enlace": enlace, "fecha": fecha})
67
+ return noticias
68
+
69
+ # Funci贸n para extraer noticias de La Izquierda Diario
70
+ def extraer_la_izquierda_diario(soup):
71
+ noticias = []
72
+ for articulo in soup.find_all("article"):
73
+ titulo = articulo.find("h2").text.strip()
74
+ enlace = articulo.find("a")["href"]
75
+ contenido = articulo.find("div", class_="entry-content").text.strip()
76
+ fecha_texto = articulo.find("time")["datetime"] # Extraer fecha
77
+ fecha = datetime.strptime(fecha_texto, "%Y-%m-%d") # Convertir a objeto datetime
78
+ noticias.append({"titulo": titulo, "contenido": contenido, "enlace": enlace, "fecha": fecha})
79
+ return noticias
80
+
81
+ # Funci贸n para clasificar noticias
82
+ def clasificar_noticia(texto):
83
+ try:
84
+ resultado = analizador(texto)
85
+ return resultado[0]["label"]
86
+ except Exception as e:
87
+ print(f"Error al clasificar texto: {e}")
88
+ return "Desconocido"
89
+
90
+ # Funci贸n para detectar conflictos laborales
91
+ def es_conflicto_laboral(texto):
92
+ palabras_clave = ["huelga", "paro", "despido", "salario", "protesta", "trabajadores", "sindicato"]
93
+ return any(palabra in texto.lower() for palabra in palabras_clave)
94
+
95
+ # Funci贸n para detectar protestas pr贸ximas
96
+ def es_protesta_proxima(texto):
97
+ palabras_clave = ["marcha", "manifestaci贸n", "concentraci贸n", "asamblea", "corte", "huelga"]
98
+ return any(palabra in texto.lower() for palabra in palabras_clave)
99
+
100
+ # Procesar todos los sitios
101
+ conflictos_laborales = []
102
+ agenda_protestas = []
103
+
104
+ for nombre, url in SITIOS.items():
105
+ print(f"Scrapeando {nombre}...")
106
+ soup = scrapear_sitio(url)
107
+ if soup:
108
+ if nombre == "Mundo Gremial":
109
+ noticias = extraer_mundo_gremial(soup)
110
+ elif nombre == "ANRed":
111
+ noticias = extraer_anred(soup)
112
+ elif nombre == "Prensa Obrera":
113
+ noticias = extraer_prensa_obrera(soup)
114
+ elif nombre == "La Izquierda Diario":
115
+ noticias = extraer_la_izquierda_diario(soup)
116
+
117
+ for noticia in noticias:
118
+ # Filtrar noticias recientes (煤ltimos 7 d铆as)
119
+ if noticia["fecha"] >= LIMITE_RECIENTE:
120
+ if es_conflicto_laboral(noticia["contenido"]):
121
+ conflictos_laborales.append({
122
+ "Sitio": nombre,
123
+ "T铆tulo": noticia["titulo"],
124
+ "Enlace": noticia["enlace"],
125
+ "Fecha": noticia["fecha"].strftime("%Y-%m-%d")
126
+ })
127
+ if es_protesta_proxima(noticia["contenido"]):
128
+ agenda_protestas.append({
129
+ "Sitio": nombre,
130
+ "T铆tulo": noticia["titulo"],
131
+ "Enlace": noticia["enlace"],
132
+ "Fecha": noticia["fecha"].strftime("%Y-%m-%d")
133
+ })
134
+
135
+ # Crear tablas con Pandas
136
+ df_conflictos = pd.DataFrame(conflictos_laborales)
137
+ df_protestas = pd.DataFrame(agenda_protestas)
138
+
139
+ # Guardar tablas en archivos CSV
140
+ df_conflictos.to_csv("conflictos_laborales.csv", index=False)
141
+ df_protestas.to_csv("agenda_protestas.csv", index=False)
142
+
143
+ print("Tablas generadas:")
144
+ print("\nConflictos Laborales en Desarrollo (煤ltimos 7 d铆as):")
145
+ print(df_conflictos)
146
+ print("\nAgenda de Protestas Pr贸ximas (煤ltimos 7 d铆as):")
147
+ print(df_protestas)