Skip to content

Instantly share code, notes, and snippets.

@kamilion
Created September 5, 2018 03:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kamilion/248d1cbd63f05e1e6dfa66b2b4687b76 to your computer and use it in GitHub Desktop.
Save kamilion/248d1cbd63f05e1e6dfa66b2b4687b76 to your computer and use it in GitHub Desktop.
#!/usr/bin/env micropython
__author__ = 'Kamilion@gmail.com'
import socket
import sys
import _thread
class uPyIRC:
# Automatically initialized class variables
# Status variables
connected = False
joined = False
last_response = ""
# Class methods
def __init__(self, username="John_Connor", channel="#ESP32", server="irc.freenode.net", port=6667):
self.username = username
self.server = server
self.port = port
self.channel = channel
def connect(self):
self.conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.conn.connect((self.server, self.port))
self.connect_loop() # When this returns, we should be alright, hopefully.
self.connected = True
def send_quit(self, message="Goodbye..."):
self.send_cmd("QUIT", message)
def send_nick(self):
self.send_cmd("NICK", self.username)
def send_user(self):
self.send_cmd("USER", "{} * * :{}".format(self.username, self.username))
def send_pong(self, resp):
self.send_cmd("PONG", ":" + resp.split(":")[1])
def get_response(self):
return self.conn.recv(1024).decode("utf-8")
def send_cmd(self, cmd, message):
command = "{} {}\r\n".format(cmd, message).encode("utf-8")
self.conn.send(command)
def send_message_to_channel(self, message):
command = "PRIVMSG {}".format(self.channel)
message = ":" + message
self.send_cmd(command, message)
def join_channel(self):
command = "JOIN"
channel = self.check_channel(self.channel)
self.send_cmd(command, channel)
def check_channel(self, channel):
if channel.startswith("#") == False:
return "#" + channel
return channel
def connect_loop(self):
while(self.joined == False):
resp = self.get_response()
print(resp.strip())
if "No Ident response" in resp:
self.send_nick()
self.send_user()
# we're accepted, now let's join the channel!
if "376" in resp:
self.join_channel()
# username already in use? try to use username with _
if "433" in resp:
self.username = "_" + self.username
self.send_nick()
self.send_user()
# Got a response to /NAMES from channel join
if "366" in resp:
self.joined = True # Break out of the while loop
# End of uPyIRC class
# _thread target function to print responses
def print_response():
while(client.connected):
client.last_response = client.get_response()
if(client.last_response != ''):
if "PING" in client.last_response: # Respond to pongs from the server
client.send_pong(client.last_response) # Give the server the timestamped PONG
if "Closing Link" in client.last_response: # Server said goodbye
client.connected = False # So we're disconnected now, thread ends.
msg = client.last_response.strip().split(":") # otherwise split at the :
try:
host = msg[1]
nick = host.split("!")[0]
message = msg[2].strip()
print("< {}> {}".format(nick, message))
except IndexError:
print("RAW: {}".format(msg)) # Something went wrong with the next few lines...
# socket conn.receive blocks the program until a response is received
# to prevent blocking program execution, receive should be threaded
def go():
cmd = "" # Start with an empty string
client.connect() # Connect to the server
_thread.stack_size(10*1024) # Get a 10KB Stack
enginethread = _thread.start_new_thread("uPyIRC", print_response, ())
_thread.stack_size(4*1024) # Go back to 4KB
# Loop until quit, _thread will handle printing.
while(cmd != "/quit"):
cmd = input("< {}> ".format(client.username)).strip()
if cmd == "/quit":
client.send_quit()
client.send_message_to_channel(cmd)
# End of functions
client = uPyIRC() # Create the client object so it is a global to the REPL
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment