Spaces:
Running
Running
import streamlit as st | |
import pandas as pd | |
import random | |
import zipfile | |
from faker import Faker | |
from unidecode import unidecode | |
from pathlib import Path | |
from datetime import datetime | |
from PyDictionary import PyDictionary | |
faker = Faker('es_MX') | |
def generar_rfc(nombre, apellido, anio, mes, dia): | |
return f"{apellido[:2].upper()}{nombre[:2].upper()}{str(anio)[-2:]}{mes:02}{dia:02}{random.randint(10, 99)}" | |
def generar_telefono_por_estado(estado): | |
ladas = {'Ciudad de Mexico': '55', 'Jalisco': '33', 'Nuevo Leon': '81', 'Veracruz': '229', 'Yucatan': '999', | |
'Puebla': '222', 'Chiapas': '961', 'Tamaulipas': '834', 'Queretaro': '442', 'Coahuila': '871'} | |
return f"{ladas.get(estado, '55')}{random.randint(1000000, 9999999)}" | |
def generar_nss(): | |
return f"{random.randint(100, 999)}-{random.randint(10, 99)}-{random.randint(1000, 9999)}" | |
def limpiar_correo(correo): | |
return unidecode(correo.replace(" ", "").lower()) | |
def generar_correo_aleatorio(): | |
try: | |
diccionario = PyDictionary() | |
palabra = random.choice(list(diccionario.meaning("word").keys())) | |
except Exception: | |
palabra = faker.word() | |
dominio = random.choice(["gmail.com", "hotmail.com"]) | |
return limpiar_correo(f"{palabra}{random.randint(1, 999)}@{dominio}") | |
def generar_datos(cantidad, columnas, progreso): | |
try: | |
estados = ['Ciudad de Mexico', 'Jalisco', 'Nuevo Leon', 'Veracruz', 'Yucatan', | |
'Puebla', 'Chiapas', 'Tamaulipas', 'Queretaro', 'Coahuila'] | |
bancos, datos = ['BBVA', 'Banorte', 'Santander', 'Citibanamex', 'HSBC', | |
'AMEX', 'Inbursa', 'Bancoppel'], [] | |
for i in range(cantidad): | |
estado = random.choice(estados) | |
nombre, apellido = faker.first_name(), faker.last_name() | |
dia, mes, anio = faker.date_of_birth().day, faker.date_of_birth().month, faker.date_of_birth().year | |
fila = {'Nombre': f"{nombre} {apellido}" if 'Nombre' in columnas else None, | |
'RFC': generar_rfc(nombre, apellido, anio, mes, dia) if 'RFC' in columnas else None, | |
'Telefono': generar_telefono_por_estado(estado) if 'Telefono' in columnas else None, | |
'Estado': estado if 'Estado' in columnas else None, | |
'Direccion': faker.address() if 'Direccion' in columnas else None, | |
'Correo Electronico': generar_correo_aleatorio() if 'Correo Electronico' in columnas else None, | |
'Tarjeta': ''.join([str(random.randint(0, 9)) for _ in range(16)]) if 'Tarjeta' in columnas else None, | |
'Banco': random.choice(bancos) if 'Banco' in columnas else None, | |
'Score de Credito': random.randint(300, 850) if 'Score de Credito' in columnas else None, | |
'NSS': generar_nss() if 'NSS' in columnas else None} | |
datos.append({k: v for k, v in fila.items() if v is not None}) | |
if i % max(1, cantidad // 100) == 0: # Actualiza progreso proporcionalmente | |
progreso.progress(i / cantidad) | |
progreso.progress(1.0) | |
return pd.DataFrame(datos) | |
except Exception as e: | |
raise RuntimeError(f"Error al generar datos: {e}") | |
def guardar_varios_archivos(dfs, formato): | |
archivos = [] | |
try: | |
for i, df in enumerate(dfs): | |
timestamp = datetime.now().strftime("_%H%M%S") | |
archivo_nombre = f"leads_buro_{i+1}{timestamp}." + ("csv" if formato == "CSV" else "xlsx") | |
if formato == "CSV": | |
df.to_csv(archivo_nombre, index=False) | |
else: | |
df.to_excel(archivo_nombre, index=False, engine='openpyxl') | |
archivos.append(archivo_nombre) | |
return archivos | |
except Exception as e: | |
raise RuntimeError(f"Error al guardar archivos: {e}") | |
def crear_zip(archivos): | |
try: | |
zip_nombre = "archivos_generados.zip" | |
with zipfile.ZipFile(zip_nombre, 'w') as zipf: | |
for archivo in archivos: | |
zipf.write(archivo, Path(archivo).name) | |
for archivo in archivos: # Limpia archivos temporales | |
Path(archivo).unlink(missing_ok=True) | |
return zip_nombre | |
except Exception as e: | |
raise RuntimeError(f"Error al crear archivo ZIP: {e}") | |
def main(): | |
st.set_page_config(layout="wide") | |
st.sidebar.title("Configuraci贸n") | |
opciones_columnas = ["Nombre", "Telefono", "RFC", "Estado", "Direccion", | |
"Correo Electronico", "Tarjeta", "Banco", "Score de Credito", "NSS"] | |
columnas = [col for col in opciones_columnas if st.sidebar.checkbox(col, value=False)] | |
num_archivos = st.sidebar.slider("N煤mero de archivos (1M registros c/u):", min_value=1, max_value=25, value=1) | |
formato_descarga = st.sidebar.radio("Selecciona el formato de descarga:", ["CSV", "XLS"]) | |
if st.sidebar.button("Generar Datos"): | |
try: | |
if not columnas: | |
st.error("Debe seleccionar al menos una columna.") | |
return | |
progreso = st.progress(0) | |
st.write(f"Generando {num_archivos} archivo(s) de 1 mill贸n de registros...") | |
dfs = [generar_datos(1_000_000, columnas, progreso) for _ in range(num_archivos)] | |
st.subheader("Previsualizaci贸n de datos (primeros 100 registros del primer archivo):") | |
st.dataframe(dfs[0].head(100)) | |
archivos_generados = guardar_varios_archivos(dfs, formato_descarga) | |
if len(archivos_generados) > 1: | |
zip_nombre = crear_zip(archivos_generados) | |
with open(zip_nombre, "rb") as file: | |
st.download_button("Descargar todos en ZIP", data=file, file_name=zip_nombre, mime="application/zip") | |
else: | |
with open(archivos_generados[0], "rb") as file: | |
st.download_button(f"Descargar {formato_descarga}", data=file, | |
file_name=archivos_generados[0], | |
mime="text/csv" if formato_descarga == "CSV" else | |
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") | |
st.success("Archivos generados y listos para descargar.") | |
except Exception as e: | |
st.error(f"Error durante la generaci贸n: {e}") | |
if __name__ == "__main__": | |
main() |