|
import gradio as gr |
|
import json |
|
from seo_analyzer import SEOSpaceAnalyzer |
|
import spacy |
|
import subprocess |
|
import sys |
|
import logging |
|
|
|
logging.basicConfig(level=logging.INFO) |
|
logger = logging.getLogger(__name__) |
|
|
|
def setup_spacy_model() -> None: |
|
""" |
|
Verifica y descarga el modelo de spaCy 'es_core_news_lg' si no está instalado. |
|
""" |
|
try: |
|
spacy.load("es_core_news_lg") |
|
logger.info("Modelo spaCy 'es_core_news_lg' cargado correctamente.") |
|
except OSError: |
|
logger.info("Descargando modelo spaCy 'es_core_news_lg'...") |
|
try: |
|
subprocess.run( |
|
[sys.executable, "-m", "spacy", "download", "es_core_news_lg"], |
|
check=True, |
|
stdout=subprocess.PIPE, |
|
stderr=subprocess.PIPE |
|
) |
|
logger.info("Modelo descargado exitosamente.") |
|
except subprocess.CalledProcessError as e: |
|
logger.error(f"Error al descargar modelo: {e.stderr.decode()}") |
|
raise RuntimeError("No se pudo descargar el modelo spaCy") from e |
|
|
|
def create_interface() -> gr.Blocks: |
|
analyzer = SEOSpaceAnalyzer() |
|
with gr.Blocks(title="SEO Analyzer Pro", theme=gr.themes.Soft()) as interface: |
|
gr.Markdown(""" |
|
# 🕵️ SEO Analyzer Pro |
|
**Analizador SEO avanzado con modelos de lenguaje** |
|
|
|
Ingresa la URL de un sitemap.xml para analizar el sitio web. |
|
""") |
|
with gr.Row(): |
|
with gr.Column(): |
|
sitemap_input = gr.Textbox( |
|
label="URL del Sitemap", |
|
placeholder="https://ejemplo.com/sitemap.xml", |
|
interactive=True |
|
) |
|
analyze_btn = gr.Button("Analizar Sitio", variant="primary") |
|
with gr.Row(): |
|
clear_btn = gr.Button("Limpiar") |
|
download_btn = gr.Button("Descargar Reporte", variant="secondary") |
|
plot_btn = gr.Button("Visualizar Enlaces Internos", variant="secondary") |
|
with gr.Column(): |
|
status_output = gr.Textbox(label="Estado del Análisis", interactive=False) |
|
with gr.Tabs(): |
|
with gr.Tab("📊 Resumen"): |
|
stats_output = gr.JSON(label="Estadísticas Generales") |
|
recommendations_output = gr.JSON(label="Recomendaciones SEO") |
|
with gr.Tab("📝 Contenido"): |
|
content_output = gr.JSON(label="Análisis de Contenido") |
|
with gr.Tab("🔗 Enlaces"): |
|
links_output = gr.JSON(label="Análisis de Enlaces") |
|
links_plot = gr.Plot(label="Visualización de Enlaces Internos") |
|
with gr.Tab("📄 Detalles"): |
|
details_output = gr.JSON(label="Detalles Individuales") |
|
def generate_report() -> str: |
|
if analyzer.current_analysis: |
|
report_path = "content_storage/seo_report.json" |
|
with open(report_path, 'w', encoding='utf-8') as f: |
|
json.dump(analyzer.current_analysis, f, indent=2, ensure_ascii=False) |
|
return report_path |
|
return "" |
|
def plot_internal_links(links_json: dict) -> any: |
|
return analyzer.plot_internal_links(links_json) |
|
analyze_btn.click( |
|
fn=analyzer.analyze_sitemap, |
|
inputs=sitemap_input, |
|
outputs=[stats_output, recommendations_output, content_output, links_output, details_output], |
|
show_progress=True |
|
) |
|
clear_btn.click( |
|
fn=lambda: [None, None, None, None, None], |
|
outputs=[stats_output, recommendations_output, content_output, links_output, details_output] |
|
) |
|
download_btn.click( |
|
fn=generate_report, |
|
outputs=gr.File(label="Descargar Reporte") |
|
) |
|
plot_btn.click( |
|
fn=plot_internal_links, |
|
inputs=links_output, |
|
outputs=links_plot |
|
) |
|
return interface |
|
|
|
if __name__ == "__main__": |
|
setup_spacy_model() |
|
app = create_interface() |
|
app.launch(server_name="0.0.0.0", server_port=7860, show_error=True, share=False) |
|
|