File size: 6,134 Bytes
777494f
 
 
 
9b5015e
abd8329
be58766
90c809d
 
777494f
05f3df8
 
 
 
8b65f87
 
777494f
22d0be8
 
 
 
 
 
20df700
 
 
 
 
 
 
 
 
 
2d4eeb6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28dd8cd
2d4eeb6
28dd8cd
2d4eeb6
28dd8cd
2d4eeb6
a4e40d7
 
 
 
 
 
 
 
 
 
22d0be8
 
 
90c809d
 
 
22d0be8
90c809d
 
 
 
 
 
 
 
 
 
 
 
22f5e99
 
 
90c809d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22d0be8
 
01dcddf
 
 
f2d26c7
01dcddf
8b65f87
 
 
 
 
 
90c809d
777494f
 
 
e0dea3f
01dcddf
90c809d
8b65f87
 
 
90c809d
8b65f87
777494f
 
 
 
 
90c809d
6f85941
 
 
93a7699
90c809d
6f85941
 
 
 
842a655
6f85941
ef53ac9
a4e40d7
6f85941
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90c809d
22d0be8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
import gradio as gr
import networkx as nx
import matplotlib.pyplot as plt
import uuid
import os
import json
import textwrap
import requests
import pandas as pd

api_key = os.getenv("AIRT_KEY")
AIRT_DBASEx = os.getenv("AIRT_DBASE")
AIRT_TABLEx = os.getenv("AIRT_TABLE")

# Use Directed Graph to represent relationships
G = nx.DiGraph()  # Fix: Use DiGraph instead of Graph

url = f"https://api.airtable.com/v0/{AIRT_DBASEx}/{AIRT_TABLEx}"
headers = {
    "Authorization": f"Bearer {api_key}",
    "Content-Type": "application/json"
}

# Cargar el JSON de normativas
def cargar_normativas():
    with open('normativas.json', 'r', encoding='utf-8') as f:
        return json.load(f)

# Cargar la lista de estudiantes
def cargar_estudiantes():
    with open('estudiantes.json', 'r', encoding='utf-8') as f:
        return json.load(f)

def crear_html(normativa):
    htmlx = f"""
    <div style="padding: 16px; border: 1px solid #ddd; border-radius: 8px;">
        <style>
            p {{ font-size: 20px; }}
        </style>
        <h2>{normativa["nombre"]}</h2>
        <h2>{normativa["titulo"], normativa["a帽o"]}</h2>
        <p><strong>ID:</strong> {normativa["id"]}</p>
        <p><strong>Descripci贸n:</strong> {normativa["descripcion"]}</p>
        <p><strong>Enfoque de Gesti贸n:</strong> {normativa["enfoque_riesgo"]}</p>
        <p><strong>Opini贸n Docente:</strong> {normativa["opinion_docente"]}</p>
        <p><strong>Visite <a href={normativa["url"]} target="_blank">este sitio web</a> para m谩s informaci贸n.</strong></p>
    </div>
    """
    return htmlx

def mostrar_detalles(normativa_seleccionada):
    if not normativa_seleccionada:
        return "<p>Por favor selecciona una normativa</p>", None    
    normativas = cargar_normativas()
    partes = normativa_seleccionada.split()
    id_normativa = normativa['nombre']
    for normativa in normativas["normativa_peruana_gestion_riesgos"]:
        if id_normativa == normativa['nombre']:
            html = crear_html(normativa)
            return html

def mostrar_detalles(normativa_seleccionada):
    if not normativa_seleccionada:
        return "<p>Por favor selecciona una normativa</p>", ""
    normativas = cargar_normativas()
    id_normativa = normativa_seleccionada  # Extract the norm name
    for normativa in normativas["normativa_peruana_gestion_riesgos"]:
        if id_normativa == normativa['nombre']:
            return crear_html(normativa), normativa["nombre"]  # Return both HTML and name
    return "<p>No se encontr贸 la normativa</p>", ""

def cargar_desde_airtable():
    response = requests.get(url, headers=headers)
    
    if response.status_code != 200:
        print(f"Error: {response.status_code} - {response.text}")  # Debugging info
        return pd.DataFrame(columns=["Nombre", "Enfoque", "Norma", "Texto_HF"])  # Return empty DataFrame
    
    records = response.json().get("records", [])

    # Compact list comprehension to extract data
    aportes = [
        [record["fields"].get("Nombre", ""), 
         record["fields"].get("Enfoque", ""), 
         record["fields"].get("Norma", ""), 
         record["fields"].get("Texto_HF", "")] for record in records
    ]

    return pd.DataFrame(aportes, columns=["Nombre", "Enfoque", "Norma", "Texto_HF"])

def wrap_text(text, width=10):
    return "\n".join(textwrap.wrap(text, width=width))
    
def inicializar_grafo():
    df = cargar_desde_airtable()
    
    # Add base nodes for categories
    G.add_node("Determinista", color='red')
    G.add_node("Sist茅mico", color='blue')

    # Process each row and add nodes/edges
    for _, row in df.iterrows():
        nombre, enfoque, norma, texto = row["Nombre"], row["Enfoque"], row["Norma"], row["Texto_HF"]
        textox = wrap_text(f"{nombre}: {texto}")

        if not G.has_node(norma):
            G.add_node(norma, color='gray')
        if not G.has_edge(norma, enfoque):
            G.add_edge(norma, enfoque, label=textox)

def guardar_en_airtable(nombre, enfoque, norma, texto): 
    data = {"fields": {"Nombre": nombre, "Enfoque": enfoque, "Norma": norma, "Texto_HF": texto}}
    requests.post(url, headers=headers, json=data)

def agregar_aporte(nombre, enfoque, norma, texto):
    textox = wrap_text(f"{nombre}: {texto}")
    
    if not G.has_node(norma):
        G.add_node(norma, color='gray')
    if not G.has_edge(norma, enfoque):
        G.add_edge(norma, enfoque, label=textox)

    guardar_en_airtable(nombre, enfoque, norma, texto)  
    return visualizar_grafo()

def visualizar_grafo():
    plt.figure(figsize=(8, 8))
    pos = nx.spring_layout(G)

    edge_labels = nx.get_edge_attributes(G, 'label')
    
    nx.draw(G, pos, with_labels=True, node_color='lightblue', edge_color='gray', node_size=2000, font_size=10)
    nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels, font_size=8)

    plt.title("Red de Aportes")
    plt.savefig("graph.png")
    plt.close()
    return "graph.png"

inicializar_grafo()
normativas = cargar_normativas()
estudiantes = cargar_estudiantes()
norm_options = [f"{norm['nombre']} {norm['id']}" for norm in normativas["normativa_peruana_gestion_riesgos"]]
student_names = [student for student in estudiantes["estudiantes"]]

iface = gr.Blocks()

with iface:
    gr.Markdown("# Foro Din谩mico con Visualizaci贸n de Red")

    with gr.Row():
        gr.Markdown('## Selecci贸n de Norma')   
    normativa_dropdown.change(fn=mostrar_detalles, inputs=normativa_dropdown, outputs=[normativa_html, norma_field])

    with gr.Row():
        gr.Markdown("## Red de Aportes:")
    graph_output = gr.Image(visualizar_grafo(), label="Red de Aportes")

    with gr.Row():
        nombre = gr.Dropdown(choices=student_names, label="Nombre del Estudiante")
        enfoque = gr.Radio(["Determinista", "Sist茅mico"], label="Enfoque")
    
    with gr.Row():
        norma_field = gr.Textbox(label="Norma", interactive=False)  # Read-only
        texto = gr.Textbox(label="Tu aporte")

    submit_button = gr.Button("Agregar Aporte")
    submit_button.click(fn=agregar_aporte, inputs=[nombre, enfoque, norma_field, texto], outputs=graph_output)

iface.launch(share=True)