-
Notifications
You must be signed in to change notification settings - Fork 0
/
irc.py
84 lines (74 loc) · 3 KB
/
irc.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import socket, json, threading, time
class irc_: # channel
users = {}
parrot = None
def __send(self, socket, message):
socket.send(bytes(message, "utf-8"))
time.sleep(0.2)
def __form_m(self, mjson):
r = ""
if "message_reference" in mjson:
r = mjson["referenced_message"]["author"]["username"]+": "
r = r + (mjson["content"])
return r
def __parse_m(self, marray):
user = marray[0].split('!')[0][1:]
# TODO: do mentions here
m = " ".join(marray[3:])[1:-2] # remove the leading ':' and trailing '\r\n'
return m, user
def __parse_cm(self, marray): # parse channel message (e.g. parrot only)
m, user = self.__parse_m(marray)
self.bridge.push(self.channel, user, m)
def __parse_dm(self, marray):
pass # TODO: dms (on discord side)
def __listen(self, user, socket):
while True:
buff = socket.recv(1024)
m = str(buff, "utf-8").split(' ')
print(m) # DEBUG
if m[0] == '':
print("received zero length packet, assuming connection closed")
self.users[user] = None
socket.close()
return
if m[0] == "PING":
self.__send(socket, ("PONG %s\n" % m[1]) )
continue
if len(m) > 2 and m[1] == "PRIVMSG" and m[0].split('!')[0][1:] not in self.users:
if m[2] == user:
self.__parse_dm(m)
continue
elif m[2] == self.channel and user == "ubridge":
self.__parse_cm(m)
continue
def create_user(self, name):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((self.ip, self.port))
if self.bridge.cfg["pword"]:
self.__send(s, ("PASS %s\n" % self.bridge.cfg["pword"]))
self.__send(s, ("NICK %s\n" % name))
self.__send(s, ("USER %s 0 * :%s\n" % (name, name)))
if name != "ubridge":
#self.__send(s, ("MODE %s +%s\n" % (name, 'd'))) # deafen channel messages
pass
self.__send(s, ("JOIN %s\n" % self.channel))
# start listening
t = threading.Thread(target=self.__listen, args=(name, s))
t.start()
return s
def push(self, name, msg): # we can deduce name, and reduce complexity here
# plaintext only
if int(msg["type"]) != 0:
print("illegal message type: %s, ignoring" % msg["type"])
return
name = msg["author"]["username"]
if name not in self.users:
self.users[name] = self.create_user(name)
self.__send(self.users[name], ("PRIVMSG %s :%s\n" % (self.channel, self.__form_m(msg))))
def __init__(self, ip, port, channel, bridge):
self.ip = ip
self.port = port
self.channel = channel
self.bridge = bridge
# form parrot
self.parrot = self.create_user("ubridge")