|
|
|
@ -0,0 +1,105 @@
|
|
|
|
|
#!/usr/bin/python3
|
|
|
|
|
|
|
|
|
|
import socket
|
|
|
|
|
from os import _exit
|
|
|
|
|
from random import randint
|
|
|
|
|
|
|
|
|
|
class IRC:
|
|
|
|
|
"""A set of methods for basic IRC communication."""
|
|
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
|
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
|
|
|
|
|
|
|
|
def set_prefs(self, prefs):
|
|
|
|
|
"""Set environment variables from a dictionary of values."""
|
|
|
|
|
self.server = prefs["server"]
|
|
|
|
|
self.channels = prefs["channels"]
|
|
|
|
|
self.bot_nick = prefs["bot_nick"]
|
|
|
|
|
self.admin_user = prefs["admin_user"]
|
|
|
|
|
self.admin_code = prefs["admin_code"]
|
|
|
|
|
self.req_prefix = prefs["req_prefix"]
|
|
|
|
|
self.is_debug = prefs["is_debug"]
|
|
|
|
|
|
|
|
|
|
def msg(self, command, text, *args, **kwargs):
|
|
|
|
|
"""Send messages given the IRC command and text. Optionally specify a
|
|
|
|
|
message recipient with `recvr=user`."""
|
|
|
|
|
recvr = kwargs.get("recvr", "")
|
|
|
|
|
if recvr != "":
|
|
|
|
|
recvr += " :"
|
|
|
|
|
self.sock.sendall(bytes(command + " " + recvr + text + "\n", "utf-8"))
|
|
|
|
|
|
|
|
|
|
def pm(self, text, recipient):
|
|
|
|
|
"""Alias of msg() with the PRIVMSG IRC command and a recipient."""
|
|
|
|
|
self.msg("PRIVMSG", text, recvr=recipient)
|
|
|
|
|
|
|
|
|
|
def connect(self):
|
|
|
|
|
"""Connect to the server and sends user/nick information."""
|
|
|
|
|
self.sock.connect(self.server)
|
|
|
|
|
self.msg("USER", self.bot_nick + " " + self.bot_nick + " " + \
|
|
|
|
|
self.bot_nick + " ehlo")
|
|
|
|
|
self.msg("NICK", self.bot_nick)
|
|
|
|
|
|
|
|
|
|
def parse_line(self, line):
|
|
|
|
|
"""Extract the request, the nick and username of the requester,
|
|
|
|
|
the channel where the request originated and returns a dictionary of
|
|
|
|
|
values."""
|
|
|
|
|
data = {"req": "", "req_chan": "", "nick": "", "user": ""}
|
|
|
|
|
if (":" + self.req_prefix) in self.line:
|
|
|
|
|
data["req"] = line.split("PRIVMSG", 1)[1].split(":" + \
|
|
|
|
|
self.req_prefix, 1)[1].strip()
|
|
|
|
|
data["req_chan"] = line.split("PRIVMSG ", 1)[1].split(" :", 1)[0]
|
|
|
|
|
data["nick"] = line.split("!~", 1)[0][1:]
|
|
|
|
|
data["user"] = line.split("!~", 2)[1][0:].split("@", 1)[0]
|
|
|
|
|
return data
|
|
|
|
|
|
|
|
|
|
def keep_alive(self):
|
|
|
|
|
"""Stay connected to a server by responding to server pings."""
|
|
|
|
|
self.line = self.sock.recv(2040).decode("utf-8").strip("\n\r")
|
|
|
|
|
if "PING" in self.line:
|
|
|
|
|
self.msg("PONG", ":" + self.server[0])
|
|
|
|
|
if self.is_debug:
|
|
|
|
|
print(self.line)
|
|
|
|
|
|
|
|
|
|
def join_chans(self):
|
|
|
|
|
"""Join channels from a list provided in environment settings."""
|
|
|
|
|
for c in self.channels:
|
|
|
|
|
if c.strip() != "" or c.strip() != "#":
|
|
|
|
|
self.msg("JOIN", c)
|
|
|
|
|
|
|
|
|
|
def map_actions(self, channel):
|
|
|
|
|
"""Listen for bot requests in a channel and match responses."""
|
|
|
|
|
data = self.parse_line(self.line)
|
|
|
|
|
|
|
|
|
|
# Respond only in the channel the request was made
|
|
|
|
|
if channel == data["req_chan"]:
|
|
|
|
|
# General commands
|
|
|
|
|
if data["req"] == "rollcall" or data["req"] == "help":
|
|
|
|
|
rollcall = (
|
|
|
|
|
"一、二、三、らーめん缶! "
|
|
|
|
|
"Hello, I am a ramen vending machine. "
|
|
|
|
|
"Please type a code to request service: "
|
|
|
|
|
"!help "
|
|
|
|
|
"Support: +81 012-700-1MIO "
|
|
|
|
|
"どうぞめしあがれ。"
|
|
|
|
|
)
|
|
|
|
|
self.pm(rollcall, data["req_chan"])
|
|
|
|
|
|
|
|
|
|
elif data["req"] == ("water " + self.bot_nick):
|
|
|
|
|
resp = [
|
|
|
|
|
("\x01ACTION happily pours the hot liquid into a bowl of "
|
|
|
|
|
"noodles and offers it to ") + data["nick"] + "\x01",
|
|
|
|
|
"( ^_^)o自自o(^_^ )Cheers!",
|
|
|
|
|
"Water Level [/////////] 200% - Thanks! (^▽^)"
|
|
|
|
|
]
|
|
|
|
|
self.pm(resp[randint(0, len(resp)-1)], data["req_chan"])
|
|
|
|
|
|
|
|
|
|
elif data["req"] == ("botsnack " + self.bot_nick):
|
|
|
|
|
self.pm("Ramen time anytime! ヽ(´▽`)/", data["req_chan"])
|
|
|
|
|
|
|
|
|
|
# Respond to some commands only in private message
|
|
|
|
|
if data["req_chan"] == self.bot_nick:
|
|
|
|
|
if data["req"] == ("exit " + self.admin_code) and \
|
|
|
|
|
data["user"].lower() == self.admin_user.lower():
|
|
|
|
|
self.pm("Okay, okay, I'll leave. (´・ω・`)", self.admin_user)
|
|
|
|
|
self.msg("QUIT", ":noodling off")
|
|
|
|
|
_exit(0)
|