Indietronica_Hardtech_Piton/jp_beta.py

203 lines
5.7 KiB
Python
Raw Permalink Normal View History

2025-12-01 19:12:25 -03:00
import socket
import threading
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import os
# ==========================================
# CONFIGURACIÓN
# ==========================================
def obtener_ip_local():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
s.connect(("8.8.8.8", 80))
ip = s.getsockname()[0]
except:
ip = "127.0.0.1"
finally:
s.close()
return ip
PUERTO = 5000
IP_LOCAL = obtener_ip_local()
# ==========================================
# SERVIDOR
# ==========================================
def servidor_archivos():
if not os.path.exists("recibidos"):
os.makedirs("recibidos")
srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
srv.bind(("0.0.0.0", PUERTO))
srv.listen(5)
print(f"[SERVIDOR] Escuchando en {IP_LOCAL}:{PUERTO}")
while True:
client, addr = srv.accept()
print(f"[SERVIDOR] Conexión desde {addr}")
info = client.recv(1024).decode()
nombre, tamaño = info.split("|")
tamaño = int(tamaño)
with open(f"recibidos/{nombre}", "wb") as f:
recibido = 0
while recibido < tamaño:
datos = client.recv(4096)
if not datos:
break
f.write(datos)
recibido += len(datos)
client.send("Archivo recibido correctamente".encode())
client.close()
threading.Thread(target=servidor_archivos, daemon=True).start()
# ==========================================
# APLICACIÓN GUI
# ==========================================
class App:
def __init__(self, root):
self.root = root
self.root.title("Enviador de Archivos")
self.root.geometry("450x320")
self.crear_pantalla_principal()
# -------------------------
# PANTALLA PRINCIPAL
# -------------------------
def crear_pantalla_principal(self):
self.limpiar_ventana()
tk.Label(self.root, text="Enviador de archivos", font=("Arial", 18)).pack(pady=10)
tk.Label(self.root, text=f"Tu IP: {IP_LOCAL}", font=("Arial", 12)).pack(pady=5)
tk.Button(self.root, text="Buscar equipos", font=("Arial", 14),
command=self.buscar_equipos).pack(pady=20)
self.lista = tk.Listbox(self.root, width=40, height=6)
self.lista.pack()
tk.Button(self.root, text="Enviar archivo al equipo seleccionado",
command=self.ir_a_seleccionar_archivo).pack(pady=10)
# -------------------------
# BUSCAR EQUIPOS
# -------------------------
def buscar_equipos(self):
self.lista.delete(0, tk.END)
base = IP_LOCAL.rsplit(".", 1)[0]
for i in range(1, 255):
ip_objetivo = f"{base}.{i}"
threading.Thread(target=self.comprobar_equipo, args=(ip_objetivo,), daemon=True).start()
def comprobar_equipo(self, ip):
s = socket.socket()
s.settimeout(0.3)
try:
s.connect((ip, PUERTO))
self.lista.insert(tk.END, ip)
except:
pass
s.close()
# -------------------------
# SELECCIONAR ARCHIVO
# -------------------------
def ir_a_seleccionar_archivo(self):
seleccionado = self.lista.curselection()
if not seleccionado:
messagebox.showwarning("Aviso", "Selecciona un equipo primero.")
return
self.ip_destino = self.lista.get(seleccionado[0])
self.crear_pantalla_seleccionar_archivo()
def crear_pantalla_seleccionar_archivo(self):
self.limpiar_ventana()
tk.Label(self.root, text=f"Enviando a: {self.ip_destino}", font=("Arial", 14)).pack(pady=10)
tk.Button(self.root, text="Seleccionar archivo",
command=self.seleccionar_archivo).pack(pady=20)
tk.Button(self.root, text="Volver", command=self.crear_pantalla_principal).pack(pady=10)
def seleccionar_archivo(self):
archivo = filedialog.askopenfilename()
if archivo:
self.enviar_archivo(archivo)
# -------------------------
# ENVÍO DEL ARCHIVO
# -------------------------
def enviar_archivo(self, ruta):
nombre = os.path.basename(ruta)
tamaño = os.path.getsize(ruta)
try:
s = socket.socket()
s.connect((self.ip_destino, PUERTO))
s.send(f"{nombre}|{tamaño}".encode())
with open(ruta, "rb") as f:
while True:
datos = f.read(4096)
if not datos:
break
s.send(datos)
confirm = s.recv(1024).decode()
s.close()
self.pantalla_confirmacion(confirm)
except Exception as e:
messagebox.showerror("Error", f"No se pudo enviar el archivo:\n{e}")
# -------------------------
# PANTALLA DE CONFIRMACIÓN
# -------------------------
def pantalla_confirmacion(self, mensaje):
self.limpiar_ventana()
tk.Label(self.root, text="✔️ Archivo enviado", font=("Arial", 18)).pack(pady=20)
tk.Label(self.root, text=mensaje, font=("Arial", 14)).pack(pady=10)
tk.Button(self.root, text="Volver al inicio",
command=self.crear_pantalla_principal,
font=("Arial", 14)).pack(pady=20)
# -------------------------
# UTILIDAD
# -------------------------
def limpiar_ventana(self):
for widget in self.root.winfo_children():
widget.destroy()
# ==========================================
# INICIAR APP
# ==========================================
root = tk.Tk()
app = App(root)
root.mainloop()