Óscar Martín commited on
Commit
59d3177
1 Parent(s): 14b596c

nuevo programa

Browse files
.gitignore ADDED
@@ -0,0 +1 @@
 
 
1
+ .venv/
.streamlit/secrets.toml ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ [secrets]
2
+ clave-openai = "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"
3
+
4
+ clave-spaceserp = "a0119e8f-1852-4a23-add7-763205748abf"
Streamlit app.py ADDED
@@ -0,0 +1,321 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import openai
3
+ import os
4
+ import requests
5
+ import pandas as pd
6
+ import io
7
+ from wordcloud import WordCloud
8
+ import matplotlib.pyplot as plt
9
+ from PIL import Image
10
+ import base64
11
+ from collections import Counter
12
+ import numpy as np
13
+ import nltk
14
+ from nltk.corpus import stopwords
15
+ from nltk.tokenize import word_tokenize
16
+
17
+
18
+
19
+ nltk.download('stopwords')
20
+ nltk.download('punkt')
21
+
22
+ st.sidebar.image('logo-empresa.png', caption='Logo de la empresa')
23
+
24
+ st.sidebar.markdown('### Configuración IA')
25
+
26
+ # Solicita el API key de OpenAI en el panel lateral
27
+ api_key = st.sidebar.text_input('Ingresa tu API key de OpenAI:', type="password")
28
+
29
+
30
+ temperature = st.sidebar.slider('Ajuste de Temperature:', min_value=0.1, max_value=2.0, value=1.0, step=0.1)
31
+
32
+
33
+ max_tokens = st.sidebar.slider('Max Tokens:', min_value=50, max_value=1500, value=1000, step=50)
34
+
35
+
36
+ st.sidebar.markdown('### Información Adicional')
37
+
38
+ st.sidebar.markdown('<a href="https://ia.promocioneconomicadesalamanca.com/" target="_blank">Acceso Curso Completo</a>', unsafe_allow_html=True)
39
+
40
+
41
+
42
+ if api_key:
43
+ openai.api_key = api_key
44
+ else:
45
+ # Configura tus credenciales de OpenAI aquí
46
+ openai.api_key = st.secrets["secrets"]["clave-openai"] # Utilizará el valor por defecto si el usuario no proporciona un API key
47
+
48
+
49
+ # Muestra la imagen en la parte superior
50
+ st.image("logos.png", use_column_width=True)
51
+ st.empty() # Agrega un espacio vacío
52
+ st.markdown('---')
53
+ st.markdown('## Crea Automáticamente Contenido con tu IA Personalizada')
54
+
55
+ def plot_histogram(articulo):
56
+ # Tokenizar el artículo en palabras
57
+ palabras = word_tokenize(articulo, language='spanish')
58
+
59
+ # Obtener las stopwords en español
60
+ stop_words = set(stopwords.words('spanish'))
61
+
62
+ # Filtrar las palabras para eliminar las stopwords y palabras no alfabéticas
63
+ palabras_filtradas = [word for word in palabras if word.isalpha() and word.lower() not in stop_words]
64
+
65
+ # Obtener la frecuencia de cada palabra
66
+ freq = Counter(palabras_filtradas)
67
+
68
+ # Ordenar las palabras por frecuencia y tomar las 8 más comunes
69
+ common_words = freq.most_common(8)
70
+ labels, values = zip(*common_words)
71
+
72
+ # Mostrar el histograma
73
+ plt.figure(figsize=(12, 8))
74
+ plt.bar(labels, values)
75
+ plt.xticks(rotation=90) # Rotar las etiquetas del eje x para una mejor visualización
76
+
77
+ # Ajustar los márgenes para asegurar que las etiquetas no se corten
78
+ plt.subplots_adjust(left=0.1, bottom=0.2)
79
+
80
+ # Aumentar el tamaño de la fuente de las etiquetas y el título
81
+ plt.xlabel('Palabras clave', fontsize=14)
82
+ plt.ylabel('Frecuencia', fontsize=14)
83
+ plt.title('Top 8 Palabras clave más frecuentes', fontsize=16)
84
+ plt.xticks(fontsize=12)
85
+ plt.yticks(fontsize=12)
86
+
87
+ # Guardar la imagen en un buffer y mostrarla en Streamlit
88
+ buf = io.BytesIO()
89
+ plt.savefig(buf, format="png")
90
+ buf.seek(0)
91
+ tab1.image(buf, caption="Histograma de frecuencia de palabras (8 más comunes)", use_column_width=True)
92
+
93
+
94
+
95
+
96
+ # Función para generar imágenes con DALL·E
97
+ def generar_imagenes(descripcion, num_imagenes=4):
98
+ response = openai.Image.create(
99
+ prompt=descripcion,
100
+ n=num_imagenes,
101
+ size="512x512",
102
+ response_format="url"
103
+ )
104
+ urls = [data['url'] for data in response.data]
105
+ print(urls) # Añade esta línea para ver las URLs generadas.
106
+ return urls
107
+
108
+ def get_image_download_link(img_url, filename="imagen.png", text="Descargar imagen"):
109
+ """
110
+ Genera un link para descargar una imagen.
111
+ """
112
+ response = requests.get(img_url)
113
+ img_data = response.content
114
+ b64 = base64.b64encode(img_data).decode()
115
+ return f'<a href="data:image/png;base64,{b64}" download="{filename}">{text}</a>'
116
+
117
+
118
+ # Función para generar artículos
119
+ def generar_articulo(tema):
120
+ prompt_articulo = "Eres un experto en marketing de contenidos y generador de artículos en profundidad"
121
+ mensajes = [
122
+ {"role": "system", "content": prompt_articulo},
123
+ {"role": "user", "content": f"Quiero que hagas un artículo sobre \"{tema}\" con índice, titulares, desarrollo de temas y un resumen al final."}
124
+ ]
125
+
126
+ respuesta = openai.ChatCompletion.create(
127
+ model="gpt-3.5-turbo",
128
+ messages=mensajes,
129
+ temperature=temperature,
130
+ max_tokens=max_tokens,
131
+ top_p=1,
132
+ frequency_penalty=0,
133
+ presence_penalty=0
134
+ )
135
+
136
+ return respuesta.choices[0].message['content']
137
+
138
+ # Función para generar estudio de palabras clave
139
+
140
+
141
+ def generar_estudio_palabras(tema):
142
+ prompt_keywords = "Eres un experto en SEO y análisis de palabras clave. Por favor, genera una lista de palabras clave en español relacionadas con el tema. No escribas nada más"
143
+ mensajes = [
144
+ {"role": "system", "content": prompt_keywords},
145
+ {"role": "user", "content": f"¿Cuáles son las palabras clave relacionadas con \"{tema}\"?"}
146
+ ]
147
+
148
+ respuesta = openai.ChatCompletion.create(
149
+ model="gpt-3.5-turbo",
150
+ messages=mensajes,
151
+ temperature=1,
152
+ max_tokens=200,
153
+ top_p=1,
154
+ frequency_penalty=0,
155
+ presence_penalty=0
156
+ )
157
+
158
+ return respuesta.choices[0].message['content'].split(',')
159
+
160
+
161
+ def mostrar_palabras_clave(palabras_clave):
162
+ # Dividir la cadena de palabras clave en una lista
163
+ palabras_lista = palabras_clave[0].split('\n')
164
+
165
+ # Eliminar cualquier cadena vacía que pueda haber en la lista
166
+ palabras_lista = [palabra for palabra in palabras_lista if palabra]
167
+
168
+ # Mostrar las palabras clave en formato de lista en Streamlit
169
+ tab2.write("Aquí tienes una lista de palabras clave relacionadas con:")
170
+ for palabra in palabras_lista:
171
+ tab2.markdown(f"- {palabra}")
172
+
173
+
174
+ def contar_palabras(titulos):
175
+ nltk.download('stopwords')
176
+ nltk.download('punkt')
177
+
178
+ palabras = []
179
+ for titulo in titulos:
180
+ tokens = word_tokenize(titulo.lower())
181
+ palabras.extend(tokens)
182
+
183
+ stop_words = set(stopwords.words('spanish'))
184
+ palabras_filtradas = [p for p in palabras if p not in stop_words and p.isalpha()]
185
+
186
+ return Counter(palabras_filtradas)
187
+
188
+
189
+ def generar_nube_palabras(palabras):
190
+ wordcloud = WordCloud(width=800, height=400, background_color='white').generate(' '.join(palabras))
191
+ plt.figure(figsize=(10, 5))
192
+ plt.imshow(wordcloud, interpolation='bilinear')
193
+ plt.axis('off')
194
+
195
+ # Guardar la imagen en un buffer y mostrarla en Streamlit
196
+ buf = io.BytesIO()
197
+ plt.savefig(buf, format="png")
198
+ buf.seek(0)
199
+ tab2.image(buf, caption="Nube de palabras clave", use_column_width=True)
200
+
201
+
202
+
203
+ def generar_ideas_articulos(titulos):
204
+ ideas = []
205
+ for titulo in titulos:
206
+ prompt = f"Basándote en el título '{titulo}', proporcióna una idea original para un artículo que pueda posicionarse bien en los motores de búsqueda."
207
+ mensajes = [
208
+ {"role": "system", "content": prompt}
209
+ ]
210
+ respuesta = openai.ChatCompletion.create(
211
+ model="gpt-3.5-turbo",
212
+ messages=mensajes,
213
+ temperature=0.7,
214
+ max_tokens=150,
215
+ top_p=1,
216
+ frequency_penalty=0,
217
+ presence_penalty=0
218
+ )
219
+ idea = respuesta.choices[0].message['content']
220
+ ideas.append(idea)
221
+ return ideas
222
+
223
+ # Crear pestañas
224
+ tab4, tab2, tab1, tab3 = st.tabs(["Mejores Ideas Competencia", "Estudio de Palabras Clave", "Generar Artículo", "Generar Imagen con DALL·E"])
225
+
226
+
227
+ with tab1:
228
+ tab1.subheader("Generar un artículo")
229
+ tema = tab1.text_input('Introduce el tema para el artículo:')
230
+ if tab1.button('Generar Artículo'):
231
+ articulo = generar_articulo(tema)
232
+ tab1.text_area("Artículo Generado:", articulo, height=400)
233
+ st.download_button("Descargar Artículo", articulo, "mi_articulo.txt")
234
+ # Llama a plot_histogram() sólo después de haber definido articulo
235
+ plot_histogram(articulo)
236
+
237
+
238
+
239
+ with tab2:
240
+ tab2.subheader("Estudio de palabras clave")
241
+ tema_keywords = tab2.text_input('Introduce el tema para el estudio de palabras clave:')
242
+
243
+ # Inicializa el estado del botón si aún no está definido
244
+ if "btn_estudio_pressed" not in st.session_state:
245
+ st.session_state.btn_estudio_pressed = False
246
+
247
+ # Botón que cambia el estado cuando se presiona
248
+ if tab2.button('Generar Estudio'):
249
+ st.session_state.btn_estudio_pressed = not st.session_state.btn_estudio_pressed
250
+
251
+ # Verifica el estado para decidir si ejecutar el código
252
+ if st.session_state.btn_estudio_pressed:
253
+ palabras_clave = generar_estudio_palabras(tema_keywords)
254
+ generar_nube_palabras(palabras_clave)
255
+ mostrar_palabras_clave(palabras_clave) # Añade esta línea
256
+
257
+ with tab3:
258
+ tab3.subheader("Generar una imagen con DALL·E")
259
+ descripcion = tab3.text_input('Introduce una descripción para la imagen:')
260
+ if tab3.button('Generar Imagen'):
261
+ urls_imagenes = generar_imagenes(descripcion)
262
+
263
+ # Establece las columnas para las imágenes (2x2)
264
+ col1, col2 = tab3.columns(2)
265
+ for i, url in enumerate(urls_imagenes):
266
+ # Si es imagen impar, la muestra en la columna 1, si no, en la columna 2
267
+ if i % 2 == 0:
268
+ col = col1
269
+ else:
270
+ col = col2
271
+
272
+ # Mostrar la imagen
273
+ img = Image.open(requests.get(url, stream=True).raw)
274
+ col.image(img, caption=descripcion, use_column_width=True)
275
+
276
+ # Botón de descarga debajo de cada imagen
277
+ col.markdown(get_image_download_link(url, filename=f"imagen_{i+1}.png"), unsafe_allow_html=True)
278
+
279
+
280
+
281
+ with tab4:
282
+ tab4.subheader("Generar ideas de artículos posicionados de la competencia")
283
+
284
+ # Entrada de texto para el término de búsqueda
285
+ busqueda = tab4.text_input("Introduce el término de búsqueda:")
286
+
287
+ if tab4.button('Buscar Compentencia y Generar Ideas'):
288
+
289
+ # Consulta a la API de spaceserp con el término de búsqueda y tu API key
290
+ url = f"https://api.spaceserp.com/google/search?apiKey={st.secrets['secrets']['clave-spaceserp']}&q={busqueda}&gl=es&hl=es"
291
+ response = requests.get(url)
292
+ if response.status_code == 200:
293
+ data = response.json()
294
+ titulos_serp = [result["title"] for result in data["organic_results"]]
295
+
296
+ # Genera ideas de artículos basadas en estos títulos
297
+ ideas_articulos = generar_ideas_articulos(titulos_serp)
298
+
299
+ # Convertir los resultados en un DataFrame y mostrarlo en una tabla
300
+ df = pd.DataFrame({
301
+ 'Título SERP': titulos_serp,
302
+ 'Idea para Artículo': ideas_articulos
303
+ })
304
+ tab4.table(df)
305
+
306
+ # Contar las palabras clave más usadas en los títulos
307
+ frecuencia_palabras = contar_palabras(titulos_serp)
308
+
309
+ # Generar el histograma con Streamlit y matplotlib
310
+ palabras, frecuencias = zip(*frecuencia_palabras.most_common(30))
311
+ fig, ax = plt.subplots(figsize=(10, 8))
312
+ ax.barh(palabras, frecuencias)
313
+ ax.set_title("Palabras clave más utilizadas")
314
+ ax.invert_yaxis() # invertir el eje y para que las palabras más frecuentes estén en la parte superior
315
+ tab4.pyplot(fig)
316
+
317
+ else:
318
+ tab4.warning("Hubo un error al consultar la API de spaceserp.")
319
+
320
+
321
+
logo-empresa.png ADDED
logos.png ADDED
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ streamlit
2
+ openai
3
+ requests
4
+ pandas
5
+ matplotlib
6
+ PILlow
7
+ numpy
8
+ nltk
9
+ wordcloud