File size: 4,961 Bytes
00dc503
2363ba5
 
 
 
 
 
 
 
 
 
 
6163952
 
2233edf
2363ba5
 
6163952
2363ba5
 
 
 
2233edf
2363ba5
 
 
6163952
2363ba5
 
2233edf
2363ba5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2cc3aa4
 
 
2233edf
2363ba5
 
 
 
 
 
 
 
 
2cc3aa4
2363ba5
 
2233edf
7a30386
2363ba5
6163952
52fe6db
58e0d35
2cc3aa4
2363ba5
2233edf
 
9c9f5cf
d7e5a93
 
 
2233edf
 
 
2cc3aa4
9c9f5cf
9884c67
d7e5a93
9884c67
2233edf
7a30386
d7e5a93
 
 
 
 
 
2233edf
 
 
 
2363ba5
 
52fe6db
2233edf
2363ba5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2233edf
2363ba5
 
2233edf
 
 
2363ba5
2cc3aa4
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
import gradio as gr
from transformers import AutoModelForCausalLM, AutoTokenizer
from collections import defaultdict, OrderedDict
import re
import torch
from threading import Lock

# Configuración inicial
model_name = "microsoft/DialoGPT-small"
device = "cuda" if torch.cuda.is_available() else "cpu"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name).to(device)
model.eval()

# Cargar alojamientos en memoria con preprocesamiento
def cargar_alojamientos():
    with open("alojamientos.txt", "r", encoding="utf-8") as file:
        alojamientos = file.read().split("\n\n")
    return {idx: alojamiento for idx, alojamiento in enumerate(alojamientos)}

alojamientos_info = cargar_alojamientos()

# Índice invertido optimizado
indice_palabras = defaultdict(set)
for idx, alojamiento in alojamientos_info.items():
    for palabra in re.split(r'\W+', alojamiento.lower()):
        if len(palabra) > 2:
            indice_palabras[palabra].add(idx)

# Caché LRU con límite de tamaño
class LRUCache:
    def __init__(self, capacity=100):
        self.cache = OrderedDict()
        self.capacity = capacity
        self.lock = Lock()

    def get(self, key):
        with self.lock:
            if key not in self.cache:
                return None
            self.cache.move_to_end(key)
            return self.cache[key]

    def put(self, key, value):
        with self.lock:
            if key in self.cache:
                self.cache.move_to_end(key)
            self.cache[key] = value
            if len(self.cache) > self.capacity:
                self.cache.popitem(last=False)

cache_respuestas = LRUCache()
cache_paginas = LRUCache()

# Sinónimos de búsqueda
sinonimos = ["alojamiento", "alquiler", "hospedaje", "residencia", "vivienda"]

# Función de búsqueda optimizada
def buscar_alojamiento(consulta):
    consulta = consulta.lower()
    cached = cache_respuestas.get(consulta)
    if cached is not None:
        return cached

    palabras = set(re.split(r'\W+', consulta))
    indices = set()
    for palabra in palabras:
        if palabra in indice_palabras or palabra in sinonimos:
            indices.update(indice_palabras[palabra])

    resultados = [alojamientos_info[idx] for idx in indices]
    resultados.sort()  # Ordenar para mantener consistencia
    cache_respuestas.put(consulta, resultados)
    cache_paginas.put(consulta, 0)
    return resultados

# Formateo visual optimizado
def formatear_alojamiento(texto):
    bloques = texto.split("\n\n")
    resultado = []
    nombre_alojamiento = ""
    datos_contacto = []
    tipos_alojamiento = []

    for bloque in bloques:
        lineas = bloque.split("\n")
        for linea in lineas:
            if "Alojamiento:" in linea or "Alquiler:" in linea:
                nombre_alojamiento = linea  # Guardamos el nombre del alojamiento
            elif any(tag in linea for tag in ["Dirección:", "Teléfono:", "Email:", "Mascotas:", "Wifi:", "Directv:", "Ropa blanca:", "Habilitación provincial:"]):
                datos_contacto.append(linea)
            elif "Plazas:" in linea or any(tag in linea for tag in ["Descripción:", "Servicios:"]):
                tipos_alojamiento.append(linea)
    
    if nombre_alojamiento:
        resultado.append(nombre_alojamiento)
    if datos_contacto:
        resultado.append("\n".join(datos_contacto))
    if tipos_alojamiento:
        resultado.append("Tipos de alojamiento:\n" + "\n".join(tipos_alojamiento))
    
    return "\n\n".join(resultado)

# Paginación y resultados
def mostrar_resultados(consulta):
    resultados = buscar_alojamiento(consulta)
    if not resultados:
        return "Lo siento, no encontré información exacta. Intenta preguntar de otra manera.", ""

    pagina = cache_paginas.get(consulta) or 0
    inicio, fin = pagina * 3, (pagina + 1) * 3
    resultados_pagina = resultados[inicio:fin]

    respuesta = "\n\n".join(formatear_alojamiento(r) for r in resultados_pagina)
    pregunta_mas = ""
    if fin < len(resultados):
        cache_paginas.put(consulta, pagina + 1)
        pregunta_mas = "¿Quieres ver más resultados? Escribe 'sí' para continuar."
    elif pagina > 0:
        pregunta_mas = "¿Quieres ver resultados anteriores? Escribe 'atrás' para volver."

    return respuesta, pregunta_mas

# Interfaz con Gradio
with gr.Blocks(title="Chat de Turismo") as iface:
    gr.Markdown("### Asistente de Turismo - Alojamientos")
    output_box = gr.Textbox(label="Historial", lines=15, interactive=False)
    input_box = gr.Textbox(label="Consulta", placeholder="Escribe aquí y presiona Enter...")
    extra_box = gr.Textbox(label="Opciones", interactive=False)
    send_button = gr.Button("Enviar")

    send_button.click(mostrar_resultados, inputs=input_box, outputs=[output_box, extra_box])
    input_box.submit(mostrar_resultados, inputs=input_box, outputs=[output_box, extra_box])

iface.launch(share=True, inbrowser=True)