79742963

Date: 2025-08-22 04:37:23
Score: 6
Natty:
Report link
                messagebox.showerror(
                    "Ruta requerida",
                    "Debes indicar una ruta completa. Usa 'Examinar...' o escribe una ruta absoluta (por ejemplo, C:\\carpeta\\archivo.txt)."
                )
                return
            # Evitar que se indique una carpeta como archivo
            if os.path.isdir(archivo_path):
                messagebox.showerror(
                    "Error",
                    "La ruta indicada es una carpeta. Especifica un archivo (por ejemplo, datos.txt)."
                )
                return
            # Verificar/crear carpeta
            try:
                dir_path = os.path.dirname(os.path.abspath(archivo_path))
            except (OSError, ValueError):
                messagebox.showerror("Error", "La ruta del archivo destino no es válida")
                return
            if dir_path and not os.path.exists(dir_path):
                crear = messagebox.askyesno(
                    "Crear carpeta",
                    f"La carpeta no existe:\n{dir_path}\n\n¿Deseas crearla?"
                )
                if crear:
                    try:
                        os.makedirs(dir_path, exist_ok=True)
                    except OSError as e:
                        messagebox.showerror("Error", f"No se pudo crear la carpeta:\n{e}")
                        return
                else:
                    return

            self._mostrar_progreso_gen()

            header = (
                "ID|Nombre|Email|Edad|Salario|FechaNacimiento|Activo|Codigo|Telefono|Puntuacion|Categoria|Comentarios\n"
            )
            with open(archivo_path, 'w', encoding='utf-8') as f:
                f.write(header)
                tamano_actual = len(header.encode('utf-8'))
                rid = 1
                while tamano_actual < tamano_objetivo_bytes:
                    linea = self._generar_registro_aleatorio(rid)
                    f.write(linea)
                    tamano_actual += len(linea.encode('utf-8'))
                    rid += 1
                    if rid % 1000 == 0:
                        # Actualización periódica del progreso para no saturar la UI
                        try:
                            if self.root.winfo_exists():
                                progreso = min(100, (tamano_actual / tamano_objetivo_bytes) * 100)
                                self.progress['value'] = progreso
                                self.estado_label.config(
                                    text=f"Registros... {rid:,} registros ({progreso:.1f}%)")
                                self.root.update()
                        except tk.TclError:
                            break

            tamano_real_bytes = os.path.getsize(archivo_path)
            tamano_real_mb = tamano_real_bytes / (1024 * 1024)

            try:
                if self.root.winfo_exists():
                    self.progress['value'] = 100
                    self.estado_label.config(text="¡Archivo generado exitosamente!", fg='#4CAF50')
                    self.root.update()
            except tk.TclError:
                pass

            abrir = messagebox.askyesno(
                "Archivo Generado",
                "Archivo creado exitosamente:\n\n"
                f"Ruta: {archivo_path}\n"
                f"Tamaño objetivo: {tamano_objetivo_mb:,.1f} MB\n"
                f"Tamaño real: {tamano_real_mb:.1f} MB\n"
                f"Registros generados: {rid-1:,}\n\n"
                "¿Deseas abrir la carpeta donde se guardó el archivo?"
            )
            if abrir:
                try:
                    destino = os.path.abspath(archivo_path)
                    # Abrir Explorer seleccionando el archivo generado
                    subprocess.run(['explorer', '/select,', destino], check=True)
                except (OSError, subprocess.CalledProcessError) as e:
                    print(f"No se pudo abrir Explorer: {e}")

            try:
                if self.root.winfo_exists():
                    self.root.after(3000, self._ocultar_progreso_gen)
            except tk.TclError:
                pass

        except (IOError, OSError, ValueError) as e:
            messagebox.showerror("❌ Error", f"Error al generar el archivo:\n{str(e)}")
            try:
                if self.root.winfo_exists():
                    self.estado_label.config(text="❌ Error en la generación", fg='red')
                    self.root.after(2000, self._ocultar_progreso_gen)
            except tk.TclError:
                pass

    # ------------------------------
    # Lógica: División de archivo
    # ------------------------------
    def _dividir_archivo(self):
        """Divide un archivo en múltiples partes respetando líneas completas.

        Reglas y comportamiento:
            - El tamaño máximo de cada parte se define en "Tamaño por parte (MB)".
            - No corta líneas: si una línea no cabe en la parte actual y ésta ya tiene
              contenido, se inicia una nueva parte y se escribe allí la línea completa.
            - Los nombres de salida se forman como: <base>_NN<ext> (NN con 2 dígitos).

        Manejo de errores:
            - Valida ruta de origen, tamaño de parte y tamaño > 0 del archivo.
            - Muestra mensajes de error/aviso según corresponda.
        """
        try:
            src = self.split_source_file.get()
            if not src or not os.path.isfile(src):
                messagebox.showerror("Error", "Selecciona un archivo origen válido")
                return

            part_size_mb = self.split_size_mb.get()
            if part_size_mb <= 0:
                messagebox.showerror("Error", "El tamaño por parte debe ser mayor a 0")
                return
            part_size_bytes = int(part_size_mb * 1024 * 1024)

            total_bytes = os.path.getsize(src)
            if total_bytes == 0:
                messagebox.showwarning("Aviso", "El archivo está vacío")
                return

            self._mostrar_progreso_split()

            base, ext = os.path.splitext(src)
            part_idx = 1
            bytes_procesados = 0
            bytes_en_parte = 0
            out = None

            def abrir_nueva_parte(idx: int):
                nonlocal out, bytes_en_parte
                if out:
                    out.close()
                nombre = f"{base}_{idx:02d}{ext}"
                out = open(nombre, 'wb')  # escritura binaria
                bytes_en_parte = 0

            abrir_nueva_parte(part_idx)

            line_count = 0
            with open(src, 'rb') as fin:  # lectura binaria
                for linea in fin:
                    lb = len(linea)

                    # Si excede y ya escribimos algo, nueva parte
                    if bytes_en_parte > 0 and bytes_en_parte + lb > part_size_bytes:
                        part_idx += 1
                        abrir_nueva_parte(part_idx)

                    # Escribimos la línea completa
                    out.write(linea)
                    bytes_en_parte += lb
                    bytes_procesados += lb
                    line_count += 1

                    # Actualizar progreso cada 1000 líneas
                    if line_count % 1000 == 0:
                        try:
                            if self.root.winfo_exists():
                                progreso = min(100, (bytes_procesados / total_bytes) * 100)
                                self.split_progress['value'] = progreso
                                self.split_estado_label.config(
                                    text=f"Procesando... {line_count:,} líneas ({progreso:.1f}%)")
                                self.root.update()
                        except tk.TclError:
                            break

            if out:
                out.close()

            try:
                if self.root.winfo_exists():
                    self.split_progress['value'] = 100
                    self.split_estado_label.config(text="¡Archivo dividido exitosamente!", fg='#4CAF50')
                    self.root.update()
            except tk.TclError:
                pass

            abrir = messagebox.askyesno(
                "División completada",
                "El archivo se dividió correctamente en partes con sufijos _01, _02, ...\n\n"
                f"Origen: {src}\n"
                f"Tamaño por parte: {part_size_mb:.1f} MB\n\n"
                "¿Deseas abrir la carpeta del archivo origen?"
            )
            if abrir:
                try:
                    # Si existe la primera parte, seleccionarla; si no, abrir carpeta del origen
                    base, ext = os.path.splitext(src)
                    primera_parte = f"{base}_{1:02d}{ext}"
                    if os.path.exists(primera_parte):
                        subprocess.run(['explorer', '/select,', os.path.abspath(primera_parte)], check=True)
                    else:
                        carpeta = os.path.dirname(src)
                        subprocess.run(['explorer', carpeta], check=True)
                except (OSError, subprocess.CalledProcessError) as e:
                    print(f"No se pudo abrir Explorer: {e}")

            try:
                if self.root.winfo_exists():
                    self.root.after(3000, self._ocultar_progreso_split)
            except tk.TclError:
                pass

        except (IOError, OSError, ValueError) as e:
            messagebox.showerror("❌ Error", f"Error al dividir el archivo:\n{str(e)}")
            try:
                if self.root.winfo_exists():
                    self.split_estado_label.config(text="❌ Error en la división", fg='red')
                    self.root.after(2000, self._ocultar_progreso_split)
            except tk.TclError:
                pass


def main():
    """Punto de entrada de la aplicación.

    Crea la ventana raíz, instancia la clase de la UI, centra la ventana y
    arranca el loop principal de Tkinter.
    """
    root = tk.Tk()
    GeneradorArchivo(root)

    # Centrar ventana
    root.update_idletasks()
    width = root.winfo_width()
    height = root.winfo_height()
    x = (root.winfo_screenwidth() // 2) - (width // 2)
    y = (root.winfo_screenheight() // 2) - (height // 2)
    root.geometry(f"{width}x{height}+{x}+{y}")

    root.mainloop()


if __name__ == "__main__":
    main()

Reasons:
  • Blacklisted phrase (1): ¿
  • Blacklisted phrase (1): está
  • Blacklisted phrase (2): crear
  • Blacklisted phrase (2): Crear
  • Long answer (-1):
  • Has code block (-0.5):
  • Unregistered user (0.5):
  • Low reputation (1):
Posted by: Eliseo