Skip to content

Instantly share code, notes, and snippets.

@redraw
Created October 17, 2026 16:55
Show Gist options
  • Select an option

  • Save redraw/ab50078f854989b0bed0e74eabcbc13a to your computer and use it in GitHub Desktop.

Select an option

Save redraw/ab50078f854989b0bed0e74eabcbc13a to your computer and use it in GitHub Desktop.
cliente IRC, anthropic vs deepseek
# agent: claude code
# prompt: crea un cliente IRC en python super simple, sin usar librerias externas, para conectarte a https://puaj.club/irc/
# plan: opus 5.5
# build: sonnet 5.5
import os
import random
import socket
import ssl
import sys
import threading
HOST, PORT = "irc.puaj.club", 6697
nick = sys.argv[1] if len(sys.argv) > 1 else f"invitado{random.randint(100, 999)}"
channel = sys.argv[2] if len(sys.argv) > 2 else "#puaj"
password = os.environ.get("IRC_PASS")
sock = ssl.create_default_context().wrap_socket(
socket.create_connection((HOST, PORT)), server_hostname=HOST
)
def send(line):
sock.sendall((line + "\r\n").encode())
def handle(line):
global nick
prefix = ""
if line.startswith(":"):
prefix, line = line[1:].split(" ", 1)
head, _, trailing = line.partition(" :")
parts = head.split()
cmd, args = parts[0], parts[1:]
who = prefix.split("!")[0]
if cmd == "PING":
send("PONG :" + trailing)
elif cmd == "001":
print(trailing)
if password:
send(f"PRIVMSG NickServ :IDENTIFY {nick} {password}")
send("JOIN " + channel)
elif cmd == "433":
nick += "_"
send("NICK " + nick)
elif cmd == "PRIVMSG":
if trailing.startswith("\x01ACTION "):
print(f"[{args[0]}] * {who} {trailing[8:].strip(chr(1))}")
else:
print(f"[{args[0]}] <{who}> {trailing}")
elif cmd in ("JOIN", "PART", "QUIT"):
print(f"-- {who} {cmd} {(args or [trailing])[0]}")
elif cmd == "NICK":
print(f"-- {who} ahora es {trailing or args[0]}")
else:
print(f"{cmd} {' '.join(args[1:])} {trailing}".strip())
def reader():
buf = b""
while True:
data = sock.recv(4096)
if not data:
print("Conexión cerrada")
os._exit(0)
buf += data
while b"\r\n" in buf:
raw, buf = buf.split(b"\r\n", 1)
handle(raw.decode("utf-8", errors="replace"))
send("NICK " + nick)
send(f"USER {nick} 0 * :{nick}")
threading.Thread(target=reader, daemon=True).start()
try:
while True:
text = input()
if not text.startswith("/"):
send(f"PRIVMSG {channel} :{text}")
continue
cmd, _, rest = text[1:].partition(" ")
if cmd == "join":
channel = rest
send("JOIN " + rest)
elif cmd == "msg":
target, _, msg = rest.partition(" ")
send(f"PRIVMSG {target} :{msg}")
elif cmd == "me":
send(f"PRIVMSG {channel} :\x01ACTION {rest}\x01")
elif cmd == "nick":
nick = rest
send("NICK " + rest)
elif cmd == "quit":
break
elif cmd == "raw":
send(rest)
else:
print("Comandos: /join /msg /me /nick /raw /quit")
except (EOFError, KeyboardInterrupt):
pass
send("QUIT :chau")
# agent: opencode
# prompt: crea un cliente IRC en python super simple, sin usar librerias externas, para conectarte a https://puaj.club/irc/
# plan: deepseek pro 4.1
# build: deepseek flash 4.1
#!/usr/bin/env python3
"""Cliente IRC minimo para puaj.club. Solo biblioteca estandar."""
import random
import select
import socket
import ssl
import sys
HOST = "irc.puaj.club"
PORT = 6697
CANAL = "#puaj"
REALNAME = "cliente irc.py"
AYUDA = """\
comandos:
/join #canal entrar a un canal (o crearlo)
/part [#canal] salir del canal
/msg <nick> <texto> mensaje privado (ej: /msg NickServ identify nick pass)
/me <texto> accion
/nick <nuevo> cambiar de nick
/quit desconectarse
/help esta ayuda
todo lo demas se manda como mensaje al canal actual."""
def parse(line):
"""Separa una linea IRC en (prefijo, comando, parametros, trailing)."""
prefix = ""
if line.startswith(":"):
prefix, _, line = line[1:].partition(" ")
command, _, params = line.partition(" ")
trailing = None
if params.startswith(":"):
params, trailing = "", params[1:]
elif " :" in params:
params, _, trailing = params.partition(" :")
return prefix, command, params, trailing
def nick_of(prefix):
return prefix.split("!", 1)[0]
class Cliente:
def __init__(self, nick, canal):
self.nick = nick
self.canal = canal
self.sock = None
self.buf = b""
self.activo = True
# --- conexion -------------------------------------------------------
def conectar(self):
raw = socket.create_connection((HOST, PORT), timeout=15)
ctx = ssl.create_default_context()
self.sock = ctx.wrap_socket(raw, server_hostname=HOST)
self.sock.settimeout(None)
self.enviar(f"NICK {self.nick}")
self.enviar(f"USER {self.nick} 0 * :{REALNAME}")
self.enviar(f"JOIN {self.canal}")
def enviar(self, linea):
if self.sock is None:
return
try:
self.sock.sendall(linea.encode("utf-8") + b"\r\n")
except OSError:
self.activo = False
def cerrar(self, motivo="chau"):
if self.sock is None:
return
if self.activo:
self.activo = False
self.enviar_quit(motivo)
try:
self.sock.close()
except OSError:
pass
self.sock = None
def enviar_quit(self, motivo):
try:
self.sock.sendall(f"QUIT :{motivo}\r\n".encode("utf-8"))
except OSError:
pass
# --- lectura --------------------------------------------------------
def leer(self):
try:
data = self.sock.recv(4096)
except OSError:
data = b""
if not data:
print("\n[desconectado del servidor]")
self.activo = False
return
self.buf += data
while b"\r\n" in self.buf:
linea, self.buf = self.buf.split(b"\r\n", 1)
self.procesar(linea.decode("utf-8", "replace"))
def procesar(self, linea):
prefix, comando, params, texto = parse(linea)
if comando == "PING":
self.enviar(f"PONG :{texto or params}")
return
if comando == "PRIVMSG":
destino, msg = params, texto or ""
nick = nick_of(prefix)
if msg.startswith("\x01ACTION ") and msg.endswith("\x01"):
self.imprimir(f"* {nick} {msg[8:-1]}")
elif destino == self.nick:
self.imprimir(f"(privado) <{nick}> {msg}")
else:
self.imprimir(f"[{destino}] <{nick}> {msg}")
return
if comando == "NOTICE":
self.imprimir(f"-{nick_of(prefix) or 'servidor'}- {texto or ''}")
return
if comando == "JOIN":
if nick_of(prefix) == self.nick:
self.imprimir(f"* estas en {params}")
else:
self.imprimir(f"--> {nick_of(prefix)} entro a {params}")
return
if comando == "PART":
motivo = f" ({texto})" if texto else ""
if nick_of(prefix) == self.nick:
self.imprimir(f"* saliste de {params}{motivo}")
else:
self.imprimir(f"<-- {nick_of(prefix)} salio de {params}{motivo}")
return
if comando == "QUIT":
self.imprimir(f"<-- {nick_of(prefix)} se fue ({texto or ''})")
return
if comando == "NICK":
nuevo = texto if texto is not None else params
viejo = nick_of(prefix)
if viejo == self.nick:
self.nick = nuevo
self.imprimir(f"* {viejo} ahora es {nuevo}")
return
if comando.isdigit():
self.numeric(int(comando), params, texto or "")
def numeric(self, codigo, params, texto):
"""Muestra los avisos del servidor que vale la pena ver."""
if codigo == 332: # tema del canal
self.imprimir(f"[tema] {texto}")
elif codigo == 372: # lineas del MOTD
self.imprimir(f"-motd- {texto}")
elif codigo >= 400:
detalle = params.split()[-1] if params else ""
self.imprimir(f"! {texto}" + (f" ({detalle})" if detalle else ""))
def imprimir(self, texto):
# \r limpia el prompt/linea a medio escribir para no mezclar salida.
print(f"\r{texto}")
if sys.stdin.isatty():
print("> ", end="", flush=True)
# --- entrada --------------------------------------------------------
def comando(self, linea):
"""Ejecuta un /comando. Devuelve False si hay que terminar."""
cmd, _, arg = linea[1:].partition(" ")
cmd = cmd.lower()
arg = arg.strip()
if cmd in ("quit", "exit", "salir"):
self.cerrar(arg or "chau")
return False
if cmd == "help":
print(AYUDA)
elif cmd == "join":
if not arg:
print("uso: /join #canal")
else:
self.canal = arg if arg[0] in "#&" else "#" + arg
self.enviar(f"JOIN {self.canal}")
elif cmd == "part":
self.enviar(f"PART {arg or self.canal} :chau")
elif cmd == "msg":
destino, _, msg = arg.partition(" ")
if not destino or not msg.strip():
print("uso: /msg <nick|#canal> <texto>")
else:
self.enviar(f"PRIVMSG {destino} :{msg}")
elif cmd == "me":
if arg:
self.enviar(f"PRIVMSG {self.canal} :\x01ACTION {arg}\x01")
self.imprimir(f"* {self.nick} {arg}")
elif cmd == "nick":
if arg:
self.nick = arg.split()[0]
self.enviar(f"NICK {self.nick}")
else:
print("uso: /nick <nuevo>")
else:
print(f"comando desconocido: /{cmd} (proba /help)")
return True
def mandar_texto(self, linea):
if linea.startswith("/") and len(linea) > 1:
return self.comando(linea)
self.enviar(f"PRIVMSG {self.canal} :{linea}")
self.imprimir(f"[{self.canal}] <{self.nick}> {linea}")
return True
def correr(self):
while self.activo:
# ssl puede tener datos ya leidos aunque select no lo marque.
if self.sock.pending():
self.leer()
continue
listos, _, _ = select.select([self.sock, sys.stdin], [], [])
if self.sock in listos:
self.leer()
if self.activo and sys.stdin in listos:
linea = sys.stdin.readline()
if not linea:
break
if not self.mandar_texto(linea.rstrip("\r\n")):
break
def main():
nick = sys.argv[1] if len(sys.argv) > 1 else f"invitado{random.randint(1000, 9999)}"
cliente = Cliente(nick, CANAL)
try:
cliente.conectar()
except (OSError, ssl.SSLError) as error:
sys.exit(f"no pude conectar a {HOST}:{PORT}: {error}")
print(f"conectado a {HOST} como {nick}, entrando a {CANAL}.")
print("escribi y enter para hablar. /help para comandos, /quit para salir.")
if sys.stdin.isatty():
print("> ", end="", flush=True)
try:
cliente.correr()
except KeyboardInterrupt:
pass
finally:
cliente.cerrar()
print("\nchau")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment