This repository has been archived on 2025-11-27. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Fitz_Studio/domains/TextManager/notas_mmr.py
T
egutierrez aef8791151 feat: Implement main application shell with navigation and color scheme toggle
- Added Appshell component with responsive navbar and main content area
- Integrated ColorSchemeToggle for light/dark mode switching
- Created Welcome component with styled title and introductory text
- Developed ChatPage for LLM interaction with WebSocket support
- Implemented Biblioteca for managing notes with rich text editor
- Added LoginPage for user authentication with error handling
- Introduced MessageList and MessageBubble components for chat messages
- Styled components with CSS modules for consistent design
2025-06-21 02:01:21 +02:00

196 lines
6.6 KiB
Python

import os
from dotenv import load_dotenv
from sqlalchemy import Table, Column, String, Text, MetaData
from pgvector.sqlalchemy import Vector
from sqlalchemy.orm import registry, Session
from domains.TextManager.nota import Nota
from domains.ConexionSql.Base_conexion import ConexionBase
from typing import Tuple
import re
from domains.ArquitectureLayer.Mapper import Mapper_base
from domains.ArquitectureLayer.Model import Model_base
from domains.ArquitectureLayer.Repo import Repo_base
from domains.Credenciales.postgres_credencial import PostgresCredencial # Asegúrate de tener esta clase implementada correctamente
titulo = os.getenv('DB_TITLE')
usuario = os.getenv('DB_USER')
passwrd = os.getenv('DB_PASSWORD')
host = os.getenv('DB_HOST')
port = os.getenv('DB_PORT')
db_name = os.getenv('DB_NAME')
db_credencial = PostgresCredencial(
titulo=titulo,
user=usuario,
password=passwrd,
host=host,
port=port,
dbname=db_name
)
# from entrypoint.init_db import db_credencial
from domains.Logger.logger_db import LoggerDB, logger
LoggerDB(db_credencial, "logger_textos", created_by="sistema")
from domains.base import Base # Este es tu declarative_base()
# ----------------------
# Cargar .env
# ----------------------
from entrypoint import ENV_PATH
load_dotenv(ENV_PATH)
# ----------------------
# REGISTRO DINÁMICO PARA TABLAS
# ----------------------
mapper_registry = registry()
# ----------------------
# FUNCIONES AUXILIARES
# ----------------------
def generar_tabla_nota_para_biblioteca(biblioteca_nombre: str, vector_dim: int, metadata: MetaData) -> Tuple[Table, type]:
"""
Genera una tabla dinámica y modelo ORM para una biblioteca dada, con campos vectoriales y campos del sistema.
"""
try:
logger.info(f"Generando tabla para biblioteca: '{biblioteca_nombre}' con dimensión de vector: {vector_dim}")
# Nombre SQL-safe
nombre_tabla = re.sub(r"[^a-zA-Z0-9_]", "_", biblioteca_nombre.strip().lower())
logger.debug(f"Nombre de tabla SQL-safe: '{nombre_tabla}'")
# Modelo ORM dinámico
class NotaModel(Base, Model_base):
__tablename__ = nombre_tabla
__table_args__ = {"extend_existing": True}
id = Column(String, primary_key=True)
titulo = Column(String, nullable=False)
tags = Column(String)
conexiones = Column(String)
texto = Column(Text)
resumen = Column(Text)
vector = Column(Vector(vector_dim), nullable=True)
vector_resumen = Column(Vector(vector_dim), nullable=True)
logger.info(f"Modelo ORM 'NotaModel' creado para la tabla '{nombre_tabla}'")
logger.debug(f"Columnas del modelo: {[c.name for c in NotaModel.__table__.columns]}")
logger.debug(f"Tipos de columnas: {[str(c.type) for c in NotaModel.__table__.columns]}")
logger.debug(f"Claves primarias: {[c.name for c in NotaModel.__table__.primary_key]}")
return NotaModel.__table__, NotaModel
except Exception as e:
logger.error(f"Error al generar la tabla y modelo ORM para '{biblioteca_nombre}': {e}")
raise
# ----------------------
# MAPPER
# ----------------------
class NotaMapper(Mapper_base[Nota, object]): # Usa `object` si el modelo es dinámico
@staticmethod
def to_model(nota: Nota):
return {
"id": nota.id,
"titulo": nota.titulo,
"tags": ",".join(nota.tags),
"conexiones": ",".join(nota.conexiones),
"texto": nota.texto,
"resumen": nota.resumen,
"vector": nota.vector,
"vector_resumen": nota.vector_resumen
}
@staticmethod
def from_model(model) -> Nota:
return Nota(
id=model.id,
titulo=model.titulo,
tags=model.tags.split(",") if model.tags else [],
conexiones=model.conexiones.split(",") if model.conexiones else [],
texto=model.texto,
resumen=model.resumen,
vector=list(model.vector) if model.vector is not None else None,
vector_resumen=list(model.vector_resumen) if model.vector_resumen is not None else None
)
@staticmethod
def to_dict(nota: Nota) -> dict:
return {
"id": nota.id,
"titulo": nota.titulo,
"tags": ",".join(nota.tags),
"conexiones": ",".join(nota.conexiones),
"texto": nota.texto,
"resumen": nota.resumen,
"vector": nota.vector,
"vector_resumen": nota.vector_resumen
}
@staticmethod
def from_dict(data: dict) -> Nota:
return Nota(
id=data["id"],
titulo=data["titulo"],
tags=data["tags"].split(",") if data.get("tags") else [],
conexiones=data["conexiones"].split(",") if data.get("conexiones") else [],
texto=data["texto"],
resumen=data["resumen"],
vector=data.get("vector"),
vector_resumen=data.get("vector_resumen")
)
# ----------------------
# REPO
# ----------------------
class NotaRepo(Repo_base):
def __init__(self, session: Session, modelo_nota: type):
if modelo_nota is None:
raise ValueError("No se puede instanciar NotaRepo sin un modelo válido de nota.")
super().__init__(session=session, modelo=modelo_nota, mapper=NotaMapper)
# ------------------------
# Métodos personalizados
# ------------------------
def get_by_tag(self, tag: str) -> list[Nota]:
query = self.session.query(self.Modelo).filter(self.Modelo.tags.contains([tag]))
models = query.all()
return self.Mapper.from_model_list(models)
def search_by_text(self, texto: str) -> list[Nota]:
query = self.session.query(self.Modelo).filter(self.Modelo.texto.ilike(f'%{texto}%'))
models = query.all()
return self.Mapper.from_model_list(models)
def get_paginated(self, offset: int = 0, limit: int = 10) -> list[Nota]:
models = self.session.query(self.Modelo).offset(offset).limit(limit).all()
return self.Mapper.from_model_list(models)
def update(self, id_: str, nota_actualizada: Nota) -> bool:
model = self.session.get(self.Modelo, id_)
if not model:
return False
# Campos de dominio
model.titulo = nota_actualizada.titulo
model.texto = nota_actualizada.texto
model.tags = nota_actualizada.tags
model.conexiones = nota_actualizada.conexiones
model.resumen = nota_actualizada.resumen
# Actualización de campos de sistema
model.sys_version = (model.sys_version or 1) + 1
self.session.commit()
return True