3
0
mirror of https://github.com/jlu5/PyLink.git synced 2024-11-23 19:19:31 +01:00

core: Add irc argument to User and Server classes

Also, add a __deepcopy__ override to channel because we cannot clone IRCNetwork objects (locks cannot be pickled).
This commit is contained in:
James Lu 2017-08-25 13:53:45 -07:00
parent 96a202acce
commit 8c0f19422f
10 changed files with 51 additions and 36 deletions

View File

@ -12,7 +12,7 @@ import time
import socket import socket
import ssl import ssl
import hashlib import hashlib
from copy import deepcopy from copy import copy, deepcopy
import inspect import inspect
import ipaddress import ipaddress
import queue import queue
@ -41,7 +41,7 @@ class ChannelState(structures.IRCCaseInsensitiveDict):
if key not in self._data: if key not in self._data:
log.debug('(%s) ChannelState: creating new channel %s in memory', self._irc.name, key) log.debug('(%s) ChannelState: creating new channel %s in memory', self._irc.name, key)
self._data[key] = newchan = Channel(key) self._data[key] = newchan = Channel(self._irc, key)
return newchan return newchan
return self._data[key] return self._data[key]
@ -1336,7 +1336,7 @@ class IRCNetwork(PyLinkNetworkCoreWithUtils):
log.info('(%s) Enumerating our own SID %s', self.name, self.sid) log.info('(%s) Enumerating our own SID %s', self.name, self.sid)
host = self.hostname() host = self.hostname()
self.servers[self.sid] = Server(None, host, internal=True, self.servers[self.sid] = Server(self, None, host, internal=True,
desc=self.serverdata.get('serverdesc') desc=self.serverdata.get('serverdesc')
or conf.conf['pylink']['serverdesc']) or conf.conf['pylink']['serverdesc'])
@ -1515,7 +1515,7 @@ class User():
self.realname = realname self.realname = realname
self.modes = set() # Tracks user modes self.modes = set() # Tracks user modes
self.server = server self.server = server
self.irc = irc self._irc = irc
# Tracks PyLink identification status # Tracks PyLink identification status
self.account = '' self.account = ''
@ -1527,7 +1527,7 @@ class User():
self.services_account = '' self.services_account = ''
# Tracks channels the user is in # Tracks channels the user is in
self.channels = structures.IRCCaseInsensitiveSet(self.irc) self.channels = structures.IRCCaseInsensitiveSet(self._irc)
# Tracks away message status # Tracks away message status
self.away = '' self.away = ''
@ -1554,21 +1554,23 @@ class Server():
internal: Whether the server is an internal PyLink server. internal: Whether the server is an internal PyLink server.
""" """
def __init__(self, uplink, name, internal=False, desc="(None given)"): def __init__(self, irc, uplink, name, internal=False, desc="(None given)"):
self.uplink = uplink self.uplink = uplink
self.users = set() self.users = set()
self.internal = internal self.internal = internal
self.name = name.lower() self.name = name.lower()
self.desc = desc self.desc = desc
self._irc = irc
def __repr__(self): def __repr__(self):
return 'Server(%s)' % self.name return 'Server(%s)' % self.name
IrcServer = Server IrcServer = Server
class Channel(utils.DeprecatedAttributesObject, utils.CamelCaseToSnakeCase): class Channel(utils.DeprecatedAttributesObject, utils.CamelCaseToSnakeCase):
"""PyLink IRC channel class.""" """PyLink IRC channel class."""
def __init__(self, name=None): def __init__(self, irc, name=None):
# Initialize variables, such as the topic, user list, TS, who's opped, etc. # Initialize variables, such as the topic, user list, TS, who's opped, etc.
self.users = set() self.users = set()
self.modes = set() self.modes = set()
@ -1576,6 +1578,7 @@ class Channel(utils.DeprecatedAttributesObject, utils.CamelCaseToSnakeCase):
self.ts = int(time.time()) self.ts = int(time.time())
self.prefixmodes = {'op': set(), 'halfop': set(), 'voice': set(), self.prefixmodes = {'op': set(), 'halfop': set(), 'voice': set(),
'owner': set(), 'admin': set()} 'owner': set(), 'admin': set()}
self._irc = irc
# Determines whether a topic has been set here or not. Protocol modules # Determines whether a topic has been set here or not. Protocol modules
# should set this. # should set this.
@ -1596,8 +1599,20 @@ class Channel(utils.DeprecatedAttributesObject, utils.CamelCaseToSnakeCase):
self.users.discard(target) self.users.discard(target)
removeuser = remove_user removeuser = remove_user
def deepcopy(self): def __deepcopy__(self, memo):
"""Returns a deep copy of the channel object.""" """Returns a deep copy of the channel object."""
# XXX: we can't pickle IRCNetwork, so just return a reference of it.
channel_copy = copy(self)
# For everything else, create a copy.
for attr, val in self.__dict__.items():
if not isinstance(val, PyLinkNetworkCore):
setattr(channel_copy, attr, deepcopy(val))
memo[id(self)] = channel_copy
return channel_copy
def deepcopy(self):
return deepcopy(self) return deepcopy(self)
def is_voice(self, uid): def is_voice(self, uid):

View File

@ -103,7 +103,7 @@ class ClientbotWrapperProtocol(IRCCommonProtocol):
f('NICK %s' % nick) f('NICK %s' % nick)
f('USER %s 8 * :%s' % (ident, realname)) f('USER %s 8 * :%s' % (ident, realname))
self.pseudoclient = User(self, nick, int(time.time()), self.uidgen.next_uid(prefix='@ClientbotInternal'), self.sid, self.pseudoclient = User(self, nick, int(time.time()), self.uidgen.next_uid(prefix='@ClientbotInternal'), self.sid,
ident=ident, realname=realname, host=self.hostname()) ident=ident, realname=realname, host=self.hostname())
self.users[self.pseudoclient.uid] = self.pseudoclient self.users[self.pseudoclient.uid] = self.pseudoclient
@ -121,7 +121,7 @@ class ClientbotWrapperProtocol(IRCCommonProtocol):
ts = ts or int(time.time()) ts = ts or int(time.time())
log.debug('(%s) spawn_client stub called, saving nick %s as PUID %s', self.name, nick, uid) log.debug('(%s) spawn_client stub called, saving nick %s as PUID %s', self.name, nick, uid)
u = self.users[uid] = User(self, nick, ts, uid, server, ident=ident, host=host, realname=realname, u = self.users[uid] = User(self, nick, ts, uid, server, ident=ident, host=host, realname=realname,
manipulatable=manipulatable, realhost=realhost, ip=ip) manipulatable=manipulatable, realhost=realhost, ip=ip)
self.servers[server].users.add(uid) self.servers[server].users.add(uid)
@ -141,7 +141,7 @@ class ClientbotWrapperProtocol(IRCCommonProtocol):
# For others servers, just use the server name as the SID. # For others servers, just use the server name as the SID.
sid = name sid = name
self.servers[sid] = Server(uplink, name, internal=internal) self.servers[sid] = Server(self, uplink, name, internal=internal)
return sid return sid
def away(self, source, text): def away(self, source, text):

View File

@ -113,7 +113,7 @@ class HybridProtocol(TS6Protocol):
realname = realname or conf.conf['bot']['realname'] realname = realname or conf.conf['bot']['realname']
realhost = realhost or host realhost = realhost or host
raw_modes = self.join_modes(modes) raw_modes = self.join_modes(modes)
u = self.users[uid] = User(self, nick, ts, uid, server, ident=ident, host=host, realname=realname, u = self.users[uid] = User(self, nick, ts, uid, server, ident=ident, host=host, realname=realname,
realhost=realhost, ip=ip, manipulatable=manipulatable) realhost=realhost, ip=ip, manipulatable=manipulatable)
self.apply_modes(uid, modes) self.apply_modes(uid, modes)
self.servers[server].users.add(uid) self.servers[server].users.add(uid)
@ -199,7 +199,7 @@ class HybridProtocol(TS6Protocol):
'host=%s realname=%s ip=%s', self.name, nick, ts, uid, 'host=%s realname=%s ip=%s', self.name, nick, ts, uid,
ident, host, realname, ip) ident, host, realname, ip)
self.users[uid] = User(self, nick, ts, uid, numeric, ident, host, realname, host, ip) self.users[uid] = User(self, nick, ts, uid, numeric, ident, host, realname, host, ip)
parsedmodes = self.parse_modes(uid, [modes]) parsedmodes = self.parse_modes(uid, [modes])
log.debug('(%s) handle_uid: Applying modes %s for %s', self.name, parsedmodes, uid) log.debug('(%s) handle_uid: Applying modes %s for %s', self.name, parsedmodes, uid)

View File

@ -56,7 +56,7 @@ class InspIRCdProtocol(TS6BaseProtocol):
realname = realname or conf.conf['bot']['realname'] realname = realname or conf.conf['bot']['realname']
realhost = realhost or host realhost = realhost or host
raw_modes = self.join_modes(modes) raw_modes = self.join_modes(modes)
u = self.users[uid] = User(self, nick, ts, uid, server, ident=ident, host=host, realname=realname, u = self.users[uid] = User(self, nick, ts, uid, server, ident=ident, host=host, realname=realname,
realhost=realhost, ip=ip, manipulatable=manipulatable, opertype=opertype) realhost=realhost, ip=ip, manipulatable=manipulatable, opertype=opertype)
self.apply_modes(uid, modes) self.apply_modes(uid, modes)
@ -356,7 +356,7 @@ class InspIRCdProtocol(TS6BaseProtocol):
if not utils.isServerName(name): if not utils.isServerName(name):
raise ValueError('Invalid server name %r' % name) raise ValueError('Invalid server name %r' % name)
self._send_with_prefix(uplink, 'SERVER %s * 1 %s :%s' % (name, sid, desc)) self._send_with_prefix(uplink, 'SERVER %s * 1 %s :%s' % (name, sid, desc))
self.servers[sid] = Server(uplink, name, internal=True, desc=desc) self.servers[sid] = Server(self, uplink, name, internal=True, desc=desc)
def endburstf(): def endburstf():
# Delay ENDBURST by X seconds if requested. # Delay ENDBURST by X seconds if requested.
@ -587,7 +587,7 @@ class InspIRCdProtocol(TS6BaseProtocol):
uid, ts, nick, realhost, host, ident, ip = args[0:7] uid, ts, nick, realhost, host, ident, ip = args[0:7]
self._check_nick_collision(nick) self._check_nick_collision(nick)
realname = args[-1] realname = args[-1]
self.users[uid] = userobj = User(self, nick, ts, uid, numeric, ident, host, realname, realhost, ip) self.users[uid] = userobj = User(self, nick, ts, uid, numeric, ident, host, realname, realhost, ip)
parsedmodes = self.parse_modes(uid, [args[8], args[9]]) parsedmodes = self.parse_modes(uid, [args[8], args[9]])
self.apply_modes(uid, parsedmodes) self.apply_modes(uid, parsedmodes)
@ -611,7 +611,7 @@ class InspIRCdProtocol(TS6BaseProtocol):
raise ProtocolError('recvpass from uplink server %s does not match configuration!' % servername) raise ProtocolError('recvpass from uplink server %s does not match configuration!' % servername)
sdesc = args[-1] sdesc = args[-1]
self.servers[numeric] = Server(None, servername, desc=sdesc) self.servers[numeric] = Server(self, None, servername, desc=sdesc)
self.uplink = numeric self.uplink = numeric
return return
@ -620,7 +620,7 @@ class InspIRCdProtocol(TS6BaseProtocol):
servername = args[0].lower() servername = args[0].lower()
sid = args[3] sid = args[3]
sdesc = args[-1] sdesc = args[-1]
self.servers[sid] = Server(numeric, servername, desc=sdesc) self.servers[sid] = Server(self, numeric, servername, desc=sdesc)
return {'name': servername, 'sid': args[3], 'text': sdesc} return {'name': servername, 'sid': args[3], 'text': sdesc}

View File

@ -87,7 +87,7 @@ class NgIRCdProtocol(IRCS2SProtocol):
realname = realname or conf.conf['bot']['realname'] realname = realname or conf.conf['bot']['realname']
uid = self._uidgen.next_uid(prefix=nick) uid = self._uidgen.next_uid(prefix=nick)
userobj = self.users[uid] = User(self, nick, ts or int(time.time()), uid, server, ident=ident, host=host, realname=realname, userobj = self.users[uid] = User(self, nick, ts or int(time.time()), uid, server, ident=ident, host=host, realname=realname,
manipulatable=manipulatable, opertype=opertype, realhost=host) manipulatable=manipulatable, opertype=opertype, realhost=host)
self.apply_modes(uid, modes) self.apply_modes(uid, modes)
@ -130,7 +130,7 @@ class NgIRCdProtocol(IRCS2SProtocol):
# a number, we can simply use the counter in our PSID generator for this. # a number, we can simply use the counter in our PSID generator for this.
server_token = sid.rsplit('@')[-1] server_token = sid.rsplit('@')[-1]
self._send_with_prefix(uplink, 'SERVER %s 1 %s :%s' % (name, server_token, desc)) self._send_with_prefix(uplink, 'SERVER %s 1 %s :%s' % (name, server_token, desc))
self.servers[sid] = Server(uplink, name, internal=True, desc=desc) self.servers[sid] = Server(self, uplink, name, internal=True, desc=desc)
return sid return sid
def away(self, source, text): def away(self, source, text):
@ -445,7 +445,7 @@ class NgIRCdProtocol(IRCS2SProtocol):
realname = args[-1] realname = args[-1]
ts = int(time.time()) ts = int(time.time())
self.users[uid] = User(self, nick, ts, uid, source, ident=ident, host=host, realname=realname, realhost=host) self.users[uid] = User(self, nick, ts, uid, source, ident=ident, host=host, realname=realname, realhost=host)
parsedmodes = self.parse_modes(uid, [args[5]]) parsedmodes = self.parse_modes(uid, [args[5]])
self.apply_modes(uid, parsedmodes) self.apply_modes(uid, parsedmodes)
@ -524,7 +524,7 @@ class NgIRCdProtocol(IRCS2SProtocol):
serverdesc = args[-1] serverdesc = args[-1]
# The uplink should be set to None for the uplink; otherwise, set it equal to the sender server. # The uplink should be set to None for the uplink; otherwise, set it equal to the sender server.
self.servers[servername] = Server(source if source != servername else None, servername, desc=serverdesc) self.servers[servername] = Server(self, source if source != servername else None, servername, desc=serverdesc)
if self.uplink is None: if self.uplink is None:
self.uplink = servername self.uplink = servername

View File

@ -279,7 +279,7 @@ class P10Protocol(IRCS2SProtocol):
raw_modes = self.join_modes(modes) raw_modes = self.join_modes(modes)
# Initialize an User instance # Initialize an User instance
u = self.users[uid] = User(self, nick, ts, uid, server, ident=ident, host=host, realname=realname, u = self.users[uid] = User(self, nick, ts, uid, server, ident=ident, host=host, realname=realname,
realhost=realhost, ip=ip, manipulatable=manipulatable, opertype=opertype) realhost=realhost, ip=ip, manipulatable=manipulatable, opertype=opertype)
# Fill in modes and add it to our users index # Fill in modes and add it to our users index
@ -674,7 +674,7 @@ class P10Protocol(IRCS2SProtocol):
self._send_with_prefix(uplink, 'SERVER %s 1 %s %s P10 %s]]] +h6 :%s' % \ self._send_with_prefix(uplink, 'SERVER %s 1 %s %s P10 %s]]] +h6 :%s' % \
(name, self.start_ts, int(time.time()), sid, desc)) (name, self.start_ts, int(time.time()), sid, desc))
self.servers[sid] = Server(uplink, name, internal=True, desc=desc) self.servers[sid] = Server(self, uplink, name, internal=True, desc=desc)
return sid return sid
def squit(self, source, target, text='No reason given'): def squit(self, source, target, text='No reason given'):
@ -832,7 +832,7 @@ class P10Protocol(IRCS2SProtocol):
servername = args[0].lower() servername = args[0].lower()
sid = args[5][:2] sid = args[5][:2]
sdesc = args[-1] sdesc = args[-1]
self.servers[sid] = Server(source, servername, desc=sdesc) self.servers[sid] = Server(self, source, servername, desc=sdesc)
if self.uplink is None: if self.uplink is None:
# If we haven't already found our uplink, this is probably it. # If we haven't already found our uplink, this is probably it.
@ -858,7 +858,7 @@ class P10Protocol(IRCS2SProtocol):
'host=%s realname=%s realhost=%s ip=%s', self.name, nick, ts, uid, 'host=%s realname=%s realhost=%s ip=%s', self.name, nick, ts, uid,
ident, host, realname, realhost, ip) ident, host, realname, realhost, ip)
uobj = self.users[uid] = User(self, nick, ts, uid, source, ident, host, realname, realhost, ip) uobj = self.users[uid] = User(self, nick, ts, uid, source, ident, host, realname, realhost, ip)
self.servers[source].users.add(uid) self.servers[source].users.add(uid)
# https://github.com/evilnet/nefarious2/blob/master/doc/p10.txt#L708 # https://github.com/evilnet/nefarious2/blob/master/doc/p10.txt#L708

View File

@ -72,7 +72,7 @@ class RatboxProtocol(TS6Protocol):
orig_realhost = realhost orig_realhost = realhost
realhost = realhost or host realhost = realhost or host
u = self.users[uid] = User(self, nick, ts, uid, server, ident=ident, host=host, realname=realname, u = self.users[uid] = User(self, nick, ts, uid, server, ident=ident, host=host, realname=realname,
realhost=realhost, ip=ip, manipulatable=manipulatable) realhost=realhost, ip=ip, manipulatable=manipulatable)
self.apply_modes(uid, modes) self.apply_modes(uid, modes)
self.servers[server].users.add(uid) self.servers[server].users.add(uid)

View File

@ -55,7 +55,7 @@ class TS6Protocol(TS6BaseProtocol):
realname = realname or conf.conf['bot']['realname'] realname = realname or conf.conf['bot']['realname']
realhost = realhost or host realhost = realhost or host
raw_modes = self.join_modes(modes) raw_modes = self.join_modes(modes)
u = self.users[uid] = User(self, nick, ts, uid, server, ident=ident, host=host, realname=realname, u = self.users[uid] = User(self, nick, ts, uid, server, ident=ident, host=host, realname=realname,
realhost=realhost, ip=ip, manipulatable=manipulatable, opertype=opertype) realhost=realhost, ip=ip, manipulatable=manipulatable, opertype=opertype)
self.apply_modes(uid, modes) self.apply_modes(uid, modes)
@ -400,7 +400,7 @@ class TS6Protocol(TS6BaseProtocol):
# Server name and SID are sent in different messages, so we fill this # Server name and SID are sent in different messages, so we fill this
# with dummy information until we get the actual sid. # with dummy information until we get the actual sid.
self.servers[numeric] = Server(None, '') self.servers[numeric] = Server(self, None, '')
self.uplink = numeric self.uplink = numeric
def handle_capab(self, numeric, command, args): def handle_capab(self, numeric, command, args):
@ -548,7 +548,7 @@ class TS6Protocol(TS6BaseProtocol):
if ip == '0': # IP was invalid; something used for services. if ip == '0': # IP was invalid; something used for services.
ip = '0.0.0.0' ip = '0.0.0.0'
self.users[uid] = User(self, nick, ts, uid, numeric, ident, host, realname, realhost, ip) self.users[uid] = User(self, nick, ts, uid, numeric, ident, host, realname, realhost, ip)
parsedmodes = self.parse_modes(uid, [modes]) parsedmodes = self.parse_modes(uid, [modes])
log.debug('Applying modes %s for %s', parsedmodes, uid) log.debug('Applying modes %s for %s', parsedmodes, uid)

View File

@ -182,7 +182,7 @@ class TS6BaseProtocol(IRCS2SProtocol):
if not utils.isServerName(name): if not utils.isServerName(name):
raise ValueError('Invalid server name %r' % name) raise ValueError('Invalid server name %r' % name)
self._send_with_prefix(uplink, 'SID %s 1 %s :%s' % (name, sid, desc)) self._send_with_prefix(uplink, 'SID %s 1 %s :%s' % (name, sid, desc))
self.servers[sid] = Server(uplink, name, internal=True, desc=desc) self.servers[sid] = Server(self, uplink, name, internal=True, desc=desc)
return sid return sid
def away(self, source, text): def away(self, source, text):
@ -232,7 +232,7 @@ class TS6BaseProtocol(IRCS2SProtocol):
# <- :services.int SERVER a.bc 2 :(H) [GL] test jupe # <- :services.int SERVER a.bc 2 :(H) [GL] test jupe
servername = args[0].lower() servername = args[0].lower()
sdesc = args[-1] sdesc = args[-1]
self.servers[servername] = Server(numeric, servername, desc=sdesc) self.servers[servername] = Server(self, numeric, servername, desc=sdesc)
return {'name': servername, 'sid': None, 'text': sdesc} return {'name': servername, 'sid': None, 'text': sdesc}
def handle_sid(self, numeric, command, args): def handle_sid(self, numeric, command, args):
@ -242,7 +242,7 @@ class TS6BaseProtocol(IRCS2SProtocol):
sname = args[0].lower() sname = args[0].lower()
sid = args[2] sid = args[2]
sdesc = args[-1] sdesc = args[-1]
self.servers[sid] = Server(numeric, sname, desc=sdesc) self.servers[sid] = Server(self, numeric, sname, desc=sdesc)
return {'name': sname, 'sid': sid, 'text': sdesc} return {'name': sname, 'sid': sid, 'text': sdesc}
def handle_svsnick(self, source, command, args): def handle_svsnick(self, source, command, args):

View File

@ -69,7 +69,7 @@ class UnrealProtocol(TS6BaseProtocol):
modes |= {('+x', None), ('+t', None)} modes |= {('+x', None), ('+t', None)}
raw_modes = self.join_modes(modes) raw_modes = self.join_modes(modes)
u = self.users[uid] = User(self, nick, ts, uid, server, ident=ident, host=host, realname=realname, u = self.users[uid] = User(self, nick, ts, uid, server, ident=ident, host=host, realname=realname,
realhost=realhost, ip=ip, manipulatable=manipulatable, opertype=opertype) realhost=realhost, ip=ip, manipulatable=manipulatable, opertype=opertype)
self.apply_modes(uid, modes) self.apply_modes(uid, modes)
self.servers[server].users.add(uid) self.servers[server].users.add(uid)
@ -415,7 +415,7 @@ class UnrealProtocol(TS6BaseProtocol):
realname = args[-1] realname = args[-1]
self.users[uid] = User(self, nick, ts, uid, numeric, ident, host, realname, realhost, ip) self.users[uid] = User(self, nick, ts, uid, numeric, ident, host, realname, realhost, ip)
self.servers[numeric].users.add(uid) self.servers[numeric].users.add(uid)
# Handle user modes # Handle user modes
@ -480,7 +480,7 @@ class UnrealProtocol(TS6BaseProtocol):
if protover < self.min_proto_ver: if protover < self.min_proto_ver:
raise ProtocolError("Protocol version too old! (needs at least %s " raise ProtocolError("Protocol version too old! (needs at least %s "
"(Unreal 4.x), got %s)" % (self.min_proto_ver, protover)) "(Unreal 4.x), got %s)" % (self.min_proto_ver, protover))
self.servers[numeric] = Server(None, sname, desc=sdesc) self.servers[numeric] = Server(self, None, sname, desc=sdesc)
# Set irc.connected to True, meaning that protocol negotiation passed. # Set irc.connected to True, meaning that protocol negotiation passed.
log.debug('(%s) self.connected set!', self.name) log.debug('(%s) self.connected set!', self.name)