Edoruin commited on
Commit
d058982
·
1 Parent(s): a50bf9c

password recuperation scripts

Browse files
Files changed (3) hide show
  1. HUGGINGFACE_PERSISTENCE.md +148 -0
  2. README.md +53 -11
  3. app/main.py +8 -2
HUGGINGFACE_PERSISTENCE.md ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Persistencia de Datos en Hugging Face Spaces
2
+
3
+ ## ⚠️ Problema
4
+
5
+ Hugging Face Spaces **NO soporta volúmenes persistentes**. Cuando el Space se reinicia (por inactividad, actualización, o manualmente), todos los datos en `/app/data` se pierden.
6
+
7
+ ## 🔄 Soluciones para Producción
8
+
9
+ ### Opción 1: Hugging Face Datasets (Recomendado)
10
+
11
+ Usar Hugging Face Datasets como almacenamiento persistente:
12
+
13
+ ```python
14
+ from datasets import Dataset, load_dataset
15
+ import json
16
+
17
+ class UserManager:
18
+ def __init__(self, dataset_name="tu-usuario/makerpage-users"):
19
+ self.dataset_name = dataset_name
20
+ try:
21
+ self.dataset = load_dataset(dataset_name, split="train")
22
+ self.users = self.dataset.to_dict()['data']
23
+ except:
24
+ self.users = []
25
+
26
+ def save(self):
27
+ """Guarda en Hugging Face Dataset"""
28
+ dataset = Dataset.from_dict({"data": [self.users]})
29
+ dataset.push_to_hub(self.dataset_name, private=True)
30
+ ```
31
+
32
+ **Ventajas:**
33
+ - ✅ Gratuito
34
+ - ✅ Integrado con HF
35
+ - ✅ Persistencia garantizada
36
+
37
+ **Desventajas:**
38
+ - ❌ Requiere token de HF con permisos de escritura
39
+ - ❌ Más lento que archivos locales
40
+
41
+ **Variables de entorno adicionales:**
42
+ - `HF_TOKEN` - Token de Hugging Face con permisos de escritura
43
+ - `HF_DATASET_NAME` - Nombre del dataset (ej: `tu-usuario/makerpage-users`)
44
+
45
+ ---
46
+
47
+ ### Opción 2: MongoDB Atlas (Recomendado para Producción)
48
+
49
+ Usar MongoDB Atlas (gratis hasta 512MB):
50
+
51
+ ```python
52
+ from pymongo import MongoClient
53
+ import os
54
+
55
+ class UserManager:
56
+ def __init__(self):
57
+ mongo_uri = os.getenv("MONGODB_URI")
58
+ self.client = MongoClient(mongo_uri)
59
+ self.db = self.client.makerpage
60
+ self.collection = self.db.users
61
+
62
+ def add_user(self, username, password, email, status="PENDING"):
63
+ user = {
64
+ "id": str(uuid.uuid4()),
65
+ "username": username,
66
+ "email": email,
67
+ "password": generate_password_hash(password),
68
+ "status": status,
69
+ "reset_token": None,
70
+ "reset_expiry": None
71
+ }
72
+ self.collection.insert_one(user)
73
+ return True
74
+
75
+ def get_by_username(self, username):
76
+ return self.collection.find_one({"username": username})
77
+ ```
78
+
79
+ **Ventajas:**
80
+ - ✅ Persistencia real
81
+ - ✅ Escalable
82
+ - ✅ Mejor rendimiento
83
+ - ✅ Gratis hasta 512MB
84
+
85
+ **Configuración:**
86
+ 1. Crear cuenta en [MongoDB Atlas](https://www.mongodb.com/cloud/atlas)
87
+ 2. Crear cluster gratuito
88
+ 3. Obtener connection string
89
+ 4. Agregar en HF Secrets: `MONGODB_URI=mongodb+srv://...`
90
+
91
+ ---
92
+
93
+ ### Opción 3: PostgreSQL (Render/Supabase)
94
+
95
+ Usar PostgreSQL gratuito:
96
+
97
+ ```python
98
+ import psycopg2
99
+ import os
100
+
101
+ class UserManager:
102
+ def __init__(self):
103
+ self.conn = psycopg2.connect(os.getenv("DATABASE_URL"))
104
+ self._create_tables()
105
+
106
+ def _create_tables(self):
107
+ with self.conn.cursor() as cur:
108
+ cur.execute("""
109
+ CREATE TABLE IF NOT EXISTS users (
110
+ id VARCHAR PRIMARY KEY,
111
+ username VARCHAR UNIQUE,
112
+ email VARCHAR UNIQUE,
113
+ password VARCHAR,
114
+ status VARCHAR,
115
+ reset_token VARCHAR,
116
+ reset_expiry TIMESTAMP
117
+ )
118
+ """)
119
+ self.conn.commit()
120
+ ```
121
+
122
+ **Servicios gratuitos:**
123
+ - [Supabase](https://supabase.com) - 500MB gratis
124
+ - [Render](https://render.com) - PostgreSQL gratis
125
+
126
+ ---
127
+
128
+ ## 🎯 Recomendación
129
+
130
+ | Caso de Uso | Solución Recomendada |
131
+ |-------------|---------------------|
132
+ | **Desarrollo/Pruebas** | Archivos JSON (actual) |
133
+ | **Producción Pequeña** | MongoDB Atlas |
134
+ | **Producción Grande** | PostgreSQL + Supabase |
135
+ | **Integración HF** | Hugging Face Datasets |
136
+
137
+ ## 📝 Configuración Actual
138
+
139
+ El código actual usa archivos JSON en `/app/data/`:
140
+ - ✅ Funciona para desarrollo y pruebas
141
+ - ⚠️ Los datos son **temporales** (se pierden al reiniciar)
142
+
143
+ Para producción, implementa una de las soluciones anteriores modificando las clases `UserManager` y `LoanManager` en `app/main.py`.
144
+
145
+ ## 🔧 Variables de Entorno en HF Spaces
146
+
147
+ Configura las variables en **Settings → Repository secrets** (no necesitas archivo `.env`).
148
+
README.md CHANGED
@@ -1,11 +1,53 @@
1
- ---
2
- title: makerspacepage
3
- emoji: 🏢
4
- colorFrom: green
5
- colorTo: yellow
6
- sdk: docker
7
- pinned: false
8
- short_description: Makerspace page server
9
- ---
10
-
11
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🛠️ Makerpage - Sistema de Gestión Maker Space
2
+
3
+ Aplicación web para gestionar préstamos de herramientas y proyectos en un Maker Space, con integración de Telegram para notificaciones y aprobaciones.
4
+
5
+ ## 🌟 Características
6
+
7
+ - 📝 **Registro y autenticación de usuarios** con aprobación por administrador
8
+ - 🔐 **Recuperación de contraseña** vía email
9
+ - 🛠️ **Sistema de préstamos** de herramientas y dispositivos
10
+ - 📱 **Integración con Telegram** para notificaciones y aprobaciones en tiempo real
11
+ - 📊 **Gestión de proyectos GitLab**
12
+ - 💾 **Persistencia de datos** en archivos JSON
13
+
14
+ ## 🚀 Despliegue en Hugging Face Spaces
15
+
16
+ ### 1. Configurar Variables de Entorno
17
+
18
+ En **Settings → Repository secrets**, configura las siguientes variables:
19
+
20
+ | Variable | Descripción |
21
+ |----------|-------------|
22
+ | `TELEGRAM_TOKEN` | Token de tu bot de Telegram |
23
+ | `TELEGRAM_CHAT_ID` | ID del chat para notificaciones |
24
+ | `GOOGLE_PROXY_URL` | URL del proxy de Google Script |
25
+ | `GITLAB_TOKEN` | Token de acceso personal de GitLab |
26
+ | `GITLAB_GROUP_ID` | ID del grupo de GitLab |
27
+ | `RESEND_API_KEY` | API key de Resend para emails |
28
+ | `FROM_EMAIL` | Email remitente verificado en Resend |
29
+ | `SECRET_KEY` | Clave secreta de Flask |
30
+
31
+ ### 2. Desplegar
32
+
33
+ El Space se desplegará automáticamente al hacer push al repositorio.
34
+
35
+ ## ⚠️ Persistencia de Datos
36
+
37
+ > **Importante:** Hugging Face Spaces NO soporta volúmenes persistentes. Los datos se guardan temporalmente en `/app/data` pero se perderán al reiniciar el Space.
38
+
39
+ Para producción, considera implementar una solución de persistencia externa. Ver [HUGGINGFACE_PERSISTENCE.md](HUGGINGFACE_PERSISTENCE.md) para opciones.
40
+
41
+ ## 🔧 Tecnologías
42
+
43
+ - **Backend:** Flask + Flask-SocketIO
44
+ - **Autenticación:** Flask-Login
45
+ - **Notificaciones:** Telegram Bot API
46
+ - **Email:** Resend API
47
+ - **Integración:** GitLab API
48
+ - **Persistencia:** JSON (temporal en HF Spaces)
49
+ - **Despliegue:** Docker + Gunicorn + Eventlet
50
+
51
+ ## 📝 Licencia
52
+
53
+ Este proyecto es de código abierto.
app/main.py CHANGED
@@ -45,7 +45,10 @@ class User(UserMixin):
45
  class UserManager:
46
  """Clase para manejar los usuarios en un archivo JSON."""
47
  def __init__(self, filename="users.json"):
48
- self.filename = filename
 
 
 
49
  self.users = self._load()
50
 
51
  def _load(self):
@@ -166,7 +169,10 @@ def load_user(user_id):
166
  class LoanManager:
167
  """Clase para manejar la persistencia de préstamos en un archivo JSON."""
168
  def __init__(self, filename="prestamos.json"):
169
- self.filename = filename
 
 
 
170
  self.loans = self._load()
171
 
172
  def _load(self):
 
45
  class UserManager:
46
  """Clase para manejar los usuarios en un archivo JSON."""
47
  def __init__(self, filename="users.json"):
48
+ # Usar directorio de datos configurable (para volúmenes Docker)
49
+ data_dir = os.getenv("DATA_DIR", "/app/data")
50
+ os.makedirs(data_dir, exist_ok=True)
51
+ self.filename = os.path.join(data_dir, filename)
52
  self.users = self._load()
53
 
54
  def _load(self):
 
169
  class LoanManager:
170
  """Clase para manejar la persistencia de préstamos en un archivo JSON."""
171
  def __init__(self, filename="prestamos.json"):
172
+ # Usar directorio de datos configurable (para volúmenes Docker)
173
+ data_dir = os.getenv("DATA_DIR", "/app/data")
174
+ os.makedirs(data_dir, exist_ok=True)
175
+ self.filename = os.path.join(data_dir, filename)
176
  self.loans = self._load()
177
 
178
  def _load(self):