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

Rewrite network intitialization bits

- Move protocols.connect -> protocols.post_connect to fix namespace conflict
- Starting an IRC connection is now explicit (via irc.connect instead of __init__)
This commit is contained in:
James Lu 2017-06-25 01:12:22 -07:00
parent 8acf39cad6
commit d0209f720a
12 changed files with 50 additions and 48 deletions

View File

@ -1130,17 +1130,6 @@ class PyLinkNetworkCoreWithUtils(PyLinkNetworkCore):
_getUid = _get_UID _getUid = _get_UID
class IRCNetwork(PyLinkNetworkCoreWithUtils): class IRCNetwork(PyLinkNetworkCoreWithUtils):
def __init__(self, *args):
super().__init__(*args)
if world.testing:
# HACK: Don't thread if we're running tests.
self.connect()
else:
self.connection_thread = threading.Thread(target=self.connect,
name="Listener for %s" %
self.name)
self.connection_thread.start()
def schedule_ping(self): def schedule_ping(self):
"""Schedules periodic pings in a loop.""" """Schedules periodic pings in a loop."""
self.proto.ping() self.proto.ping()
@ -1152,7 +1141,7 @@ class IRCNetwork(PyLinkNetworkCoreWithUtils):
log.debug('(%s) Ping scheduled at %s', self.name, time.time()) log.debug('(%s) Ping scheduled at %s', self.name, time.time())
def connect(self): def _connect(self):
""" """
Runs the connect loop for the IRC object. This is usually called by Runs the connect loop for the IRC object. This is usually called by
__init__ in a separate thread to allow multiple concurrent connections. __init__ in a separate thread to allow multiple concurrent connections.
@ -1265,7 +1254,7 @@ class IRCNetwork(PyLinkNetworkCoreWithUtils):
self.sid = self.serverdata.get("sid") self.sid = self.serverdata.get("sid")
# All our checks passed, get the protocol module to connect and run the listen # All our checks passed, get the protocol module to connect and run the listen
# loop. This also updates any SID values should the protocol module do so. # loop. This also updates any SID values should the protocol module do so.
self.proto.connect() self.post_connect()
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()
@ -1296,6 +1285,17 @@ class IRCNetwork(PyLinkNetworkCoreWithUtils):
if not self._run_autoconnect(): if not self._run_autoconnect():
return return
def connect(self):
log.debug('(%s) calling _connect() (world.testing=%s)', self.name, world.testing)
if world.testing:
# HACK: Don't thread if we're running tests.
self._connect()
else:
self.connection_thread = threading.Thread(target=self._connect,
name="Listener for %s" %
self.name)
self.connection_thread.start()
def disconnect(self): def disconnect(self):
"""Handle disconnects from the remote server.""" """Handle disconnects from the remote server."""
self._pre_disconnect() self._pre_disconnect()

View File

@ -11,8 +11,8 @@ COMMON_PREFIXMODES = [('h', 'halfop'), ('a', 'admin'), ('q', 'owner'), ('y', 'ow
IRCV3_CAPABILITIES = {'multi-prefix', 'sasl'} IRCV3_CAPABILITIES = {'multi-prefix', 'sasl'}
class ClientbotWrapperProtocol(IRCCommonProtocol): class ClientbotWrapperProtocol(IRCCommonProtocol):
def __init__(self, irc): def __init__(self, *args, **kwargs):
super().__init__(irc) super().__init__(*args, **kwargs)
self.protocol_caps = {'clear-channels-on-leave', 'slash-in-nicks', 'slash-in-hosts', 'underscore-in-hosts'} self.protocol_caps = {'clear-channels-on-leave', 'slash-in-nicks', 'slash-in-hosts', 'underscore-in-hosts'}
@ -51,7 +51,7 @@ class ClientbotWrapperProtocol(IRCCommonProtocol):
return nick return nick
return uid return uid
def connect(self): def post_connect(self):
"""Initializes a connection to a server.""" """Initializes a connection to a server."""
# (Re)initialize counter-based pseudo UID generators # (Re)initialize counter-based pseudo UID generators
self.uidgen = utils.PUIDGenerator('PUID') self.uidgen = utils.PUIDGenerator('PUID')

View File

@ -5,10 +5,10 @@ from pylinkirc.log import log
from pylinkirc.classes import * from pylinkirc.classes import *
from pylinkirc.protocols.ts6 import * from pylinkirc.protocols.ts6 import *
# This protocol module inherits from the TS6 protocol.
class HybridProtocol(TS6Protocol): class HybridProtocol(TS6Protocol):
def __init__(self, irc): def __init__(self, *args, **kwargs):
# This protocol module inherits from the TS6 protocol. super().__init__(*args, **kwargs)
super().__init__(irc)
self.casemapping = 'ascii' self.casemapping = 'ascii'
self.caps = {} self.caps = {}
@ -16,7 +16,7 @@ class HybridProtocol(TS6Protocol):
self.has_eob = False self.has_eob = False
self.protocol_caps -= {'slash-in-hosts'} self.protocol_caps -= {'slash-in-hosts'}
def connect(self): def post_connect(self):
"""Initializes a connection to a server.""" """Initializes a connection to a server."""
ts = self.irc.start_ts ts = self.irc.start_ts
self.has_eob = False self.has_eob = False

View File

@ -11,8 +11,8 @@ from pylinkirc.log import log
from pylinkirc.protocols.ts6_common import * from pylinkirc.protocols.ts6_common import *
class InspIRCdProtocol(TS6BaseProtocol): class InspIRCdProtocol(TS6BaseProtocol):
def __init__(self, irc): def __init__(self, *args, **kwargs):
super().__init__(irc) super().__init__(*args, **kwargs)
self.protocol_caps |= {'slash-in-nicks', 'slash-in-hosts', 'underscore-in-hosts'} self.protocol_caps |= {'slash-in-nicks', 'slash-in-hosts', 'underscore-in-hosts'}
@ -392,7 +392,7 @@ class InspIRCdProtocol(TS6BaseProtocol):
### Core / command handlers ### Core / command handlers
def connect(self): def post_connect(self):
"""Initializes a connection to a server.""" """Initializes a connection to a server."""
ts = self.irc.start_ts ts = self.irc.start_ts

View File

@ -11,7 +11,7 @@ from pylinkirc.log import log
from pylinkirc import utils from pylinkirc import utils
class IRCCommonProtocol(IRCNetwork): class IRCCommonProtocol(IRCNetwork):
def validateServerConf(self): def validate_server_conf(self):
"""Validates that the server block given contains the required keys.""" """Validates that the server block given contains the required keys."""
for k in self.conf_keys: for k in self.conf_keys:
assert k in self.irc.serverdata, "Missing option %r in server block for network %s." % (k, self.irc.name) assert k in self.irc.serverdata, "Missing option %r in server block for network %s." % (k, self.irc.name)
@ -142,8 +142,8 @@ class IRCCommonProtocol(IRCNetwork):
class IRCS2SProtocol(IRCCommonProtocol): class IRCS2SProtocol(IRCCommonProtocol):
COMMAND_TOKENS = {} COMMAND_TOKENS = {}
def __init__(self, irc): def __init__(self, *args, **kwargs):
super().__init__(irc) super().__init__(*args, **kwargs)
self.protocol_caps = {'can-spawn-clients', 'has-ts', 'can-host-relay', self.protocol_caps = {'can-spawn-clients', 'has-ts', 'can-host-relay',
'can-track-servers'} 'can-track-servers'}

View File

@ -6,8 +6,8 @@ from pylinkirc.log import log
from pylinkirc.protocols.p10 import * from pylinkirc.protocols.p10 import *
class NefariousProtocol(P10Protocol): class NefariousProtocol(P10Protocol):
def __init__(self, irc): def __init__(self, *args, **kwargs):
super().__init__(irc) super().__init__(*args, **kwargs)
log.warning("(%s) protocols/nefarious.py has been renamed to protocols/p10.py, which " log.warning("(%s) protocols/nefarious.py has been renamed to protocols/p10.py, which "
"now also supports other IRCu variants. Please update your configuration, " "now also supports other IRCu variants. Please update your configuration, "
"as this migration stub will be removed in a future version.", "as this migration stub will be removed in a future version.",

View File

@ -151,14 +151,14 @@ class P10Protocol(IRCS2SProtocol):
'FA': 'FAKE' 'FA': 'FAKE'
} }
def __init__(self, irc): def __init__(self, *args, **kwargs):
super().__init__(irc) super().__init__(*args, **kwargs)
# Dictionary of UID generators (one for each server). # Dictionary of UID generators (one for each server).
self.uidgen = structures.KeyedDefaultdict(P10UIDGenerator) self.uidgen = structures.KeyedDefaultdict(P10UIDGenerator)
# SID generator for P10. # SID generator for P10.
self.sidgen = P10SIDGenerator(irc) self.sidgen = P10SIDGenerator(self)
self.hook_map = {'END_OF_BURST': 'ENDBURST', 'OPMODE': 'MODE', 'CLEARMODE': 'MODE', 'BURST': 'JOIN'} self.hook_map = {'END_OF_BURST': 'ENDBURST', 'OPMODE': 'MODE', 'CLEARMODE': 'MODE', 'BURST': 'JOIN'}
@ -754,7 +754,7 @@ class P10Protocol(IRCS2SProtocol):
### HANDLERS ### HANDLERS
def connect(self): def post_connect(self):
"""Initializes a connection to a server.""" """Initializes a connection to a server."""
ts = self.irc.start_ts ts = self.irc.start_ts

View File

@ -7,17 +7,16 @@ from pylinkirc.protocols.ts6 import *
class RatboxProtocol(TS6Protocol): class RatboxProtocol(TS6Protocol):
def __init__(self, irc): def __init__(self, *args, **kwargs):
super().__init__(irc) super().__init__(*args, **kwargs)
# Don't require EUID for Ratbox # Don't require EUID for Ratbox
self.required_caps.discard('EUID') self.required_caps.discard('EUID')
self.hook_map['LOGIN'] = 'CLIENT_SERVICES_LOGIN' self.hook_map['LOGIN'] = 'CLIENT_SERVICES_LOGIN'
self.protocol_caps -= {'slash-in-hosts'} self.protocol_caps -= {'slash-in-hosts'}
def connect(self): def post_connect(self):
"""Initializes a connection to a server.""" """Initializes a connection to a server."""
super().connect()
# Note: +r, +e, and +I support will be negotiated on link # Note: +r, +e, and +I support will be negotiated on link
self.irc.cmodes = {'op': 'o', 'secret': 's', 'private': 'p', 'noextmsg': 'n', 'moderated': 'm', self.irc.cmodes = {'op': 'o', 'secret': 's', 'private': 'p', 'noextmsg': 'n', 'moderated': 'm',

View File

@ -13,8 +13,8 @@ from pylinkirc.protocols.ts6_common import *
S2S_BUFSIZE = 510 S2S_BUFSIZE = 510
class TS6Protocol(TS6BaseProtocol): class TS6Protocol(TS6BaseProtocol):
def __init__(self, irc): def __init__(self, *args, **kwargs):
super().__init__(irc) super().__init__(*args, **kwargs)
self.protocol_caps |= {'slash-in-hosts'} self.protocol_caps |= {'slash-in-hosts'}
self.casemapping = 'rfc1459' self.casemapping = 'rfc1459'
self.hook_map = {'SJOIN': 'JOIN', 'TB': 'TOPIC', 'TMODE': 'MODE', 'BMASK': 'MODE', self.hook_map = {'SJOIN': 'JOIN', 'TB': 'TOPIC', 'TMODE': 'MODE', 'BMASK': 'MODE',
@ -255,7 +255,7 @@ class TS6Protocol(TS6BaseProtocol):
### Core / handlers ### Core / handlers
def connect(self): def post_connect(self):
"""Initializes a connection to a server.""" """Initializes a connection to a server."""
ts = self.irc.start_ts ts = self.irc.start_ts
self.has_eob = False self.has_eob = False

View File

@ -99,15 +99,14 @@ class TS6UIDGenerator(utils.IncrementalUIDGenerator):
super().__init__(sid) super().__init__(sid)
class TS6BaseProtocol(IRCS2SProtocol): class TS6BaseProtocol(IRCS2SProtocol):
def __init__(self, *args, **kwargs):
def __init__(self, irc): super().__init__(*args, **kwargs)
super().__init__(irc)
# Dictionary of UID generators (one for each server). # Dictionary of UID generators (one for each server).
self.uidgen = structures.KeyedDefaultdict(TS6UIDGenerator) self.uidgen = structures.KeyedDefaultdict(TS6UIDGenerator)
# SID generator for TS6. # SID generator for TS6.
self.sidgen = TS6SIDGenerator(irc) self.sidgen = TS6SIDGenerator(self)
def _send_with_prefix(self, source, msg, **kwargs): def _send_with_prefix(self, source, msg, **kwargs):
"""Sends a TS6-style raw command from a source numeric to the self.irc connection given.""" """Sends a TS6-style raw command from a source numeric to the self.irc connection given."""

View File

@ -21,8 +21,8 @@ SJOIN_PREFIXES = {'q': '*', 'a': '~', 'o': '@', 'h': '%', 'v': '+', 'b': '&', 'e
S2S_BUFSIZE = 427 S2S_BUFSIZE = 427
class UnrealProtocol(TS6BaseProtocol): class UnrealProtocol(TS6BaseProtocol):
def __init__(self, irc): def __init__(self, *args, **kwargs):
super().__init__(irc) super().__init__(*args, **kwargs)
self.protocol_caps |= {'slash-in-nicks', 'underscore-in-hosts'} self.protocol_caps |= {'slash-in-nicks', 'underscore-in-hosts'}
# Set our case mapping (rfc1459 maps "\" and "|" together, for example) # Set our case mapping (rfc1459 maps "\" and "|" together, for example)
self.casemapping = 'ascii' self.casemapping = 'ascii'
@ -335,7 +335,7 @@ class UnrealProtocol(TS6BaseProtocol):
### HANDLERS ### HANDLERS
def connect(self): def post_connect(self):
"""Initializes a connection to a server.""" """Initializes a connection to a server."""
ts = self.irc.start_ts ts = self.irc.start_ts
self.irc.prefixmodes = {'q': '~', 'a': '&', 'o': '@', 'h': '%', 'v': '+'} self.irc.prefixmodes = {'q': '~', 'a': '&', 'o': '@', 'h': '%', 'v': '+'}

8
pylink
View File

@ -83,9 +83,13 @@ if __name__ == '__main__':
except (KeyError, TypeError): except (KeyError, TypeError):
log.error("(%s) Configuration error: No protocol module specified, aborting.", network) log.error("(%s) Configuration error: No protocol module specified, aborting.", network)
else: else:
# Fetch the correct protocol module # Fetch the correct protocol module.
proto = utils.getProtocolModule(protoname) proto = utils.getProtocolModule(protoname)
world.networkobjects[network] = proto.Class(network)
# Create and connect the network.
world.networkobjects[network] = irc = proto.Class(network)
log.debug('Connecting to network %r', network)
irc.connect()
world.started.set() world.started.set()
log.info("Loaded plugins: %s", ', '.join(sorted(world.plugins.keys()))) log.info("Loaded plugins: %s", ', '.join(sorted(world.plugins.keys())))