Browse files

refactor network stuff from rest of em and put in new file

* collect some common code for both asyncore subclasses
* pass Uzbl a Protocol instance instead of creating in the constructor
  • Loading branch information...
1 parent dd4827b commit fef467ee97e0429f97e03b12aadc17c3b7cc307a @keis keis committed Feb 19, 2012
Showing with 102 additions and 77 deletions.
  1. +4 −25 uzbl/core.py
  2. +4 −52 uzbl/event_manager.py
  3. +94 −0 uzbl/net.py
View
29 uzbl/core.py
@@ -1,36 +1,15 @@
import time
import logging
-import asynchat
from collections import defaultdict
-class Protocol(asynchat.async_chat):
-
- def __init__(self, socket, uzbl):
- asynchat.async_chat.__init__(self, socket)
- self.uzbl = uzbl
- self.buffer = bytearray()
- self.set_terminator(b'\n')
-
- def collect_incoming_data(self, data):
- self.buffer += data
-
- def found_terminator(self):
- val = self.buffer.decode('utf-8')
- del self.buffer[:]
- self.uzbl.parse_msg(val)
-
- def handle_error(self):
- raise
-
-
class Uzbl(object):
- def __init__(self, parent, child_socket, options):
+ def __init__(self, parent, proto, options):
+ proto.target = self
self.opts = options
self.parent = parent
- self.proto = Protocol(child_socket, self)
- self._child_socket = child_socket
+ self.proto = proto
self.time = time.time()
self.pid = None
self.name = None
@@ -154,7 +133,7 @@ def close(self):
# Remove self from parent uzbls dict.
self.logger.debug('removing self from uzbls list')
- self.parent.remove_instance(self._child_socket)
+ self.parent.remove_instance(self.proto.socket)
for plugin in self._plugin_instances:
plugin.cleanup()
View
56 uzbl/event_manager.py
@@ -37,7 +37,6 @@
import re
import errno
import asyncore
-import socket
from collections import defaultdict
from functools import partial
from glob import glob
@@ -47,6 +46,7 @@
from signal import signal, SIGTERM, SIGINT, SIGKILL
from traceback import format_exc
+from uzbl.net import Listener, Protocol
from uzbl.core import Uzbl
def xdghome(key, default):
@@ -134,58 +134,9 @@ def make_dirs(path):
logger.error('failed to create directories', exc_info=True)
-class NoTargetSet(Exception):
- pass
-
-
-class TargetAlreadySet(Exception):
- pass
-
-
-class Listener(asyncore.dispatcher):
-
- def __init__(self, addr, target=None):
- asyncore.dispatcher.__init__(self)
- self.addr = addr
- self.target = target
- self.create_socket(socket.AF_UNIX, socket.SOCK_STREAM)
- self.set_reuse_addr()
- self.bind(addr)
- self.listen(5)
-
- def writable(self):
- return False
-
- def set_target(self, target):
- if self.target is not None:
- raise TargetAlreadySet(
- "target of listener already set (%r)" % self.target
- )
- self.target = target
-
- def handle_accept(self):
- try:
- sock, addr = self.accept()
- except socket.error:
- return
- else:
- if self.target is None:
- raise NoTargetSet("No target for %r" % self)
- self.target.add_instance(sock)
-
- def close(self):
- super(Listener, self).close()
- if os.path.exists(self.addr):
- logger.info('unlinking %r', self.addr)
- os.unlink(self.addr)
-
- def handle_error(self):
- raise
-
-
class UzblEventDaemon(object):
def __init__(self, listener):
- listener.set_target(self)
+ listener.target = self
self.opts = opts
self.listener = listener
self._quit = False
@@ -250,7 +201,8 @@ def run(self):
logger.debug('exiting main loop')
def add_instance(self, sock):
- uzbl = Uzbl(self, sock, opts)
+ proto = Protocol(sock)
+ uzbl = Uzbl(self, proto, opts)
self.uzbls[sock] = uzbl
def remove_instance(self, sock):
View
94 uzbl/net.py
@@ -0,0 +1,94 @@
+# Network communication classes
+# vi: set et ts=4:
+import asyncore
+import asynchat
+import socket
+import os
+import logging
+
+logger = logging.getLogger('uzbl.net')
+
+
+class NoTargetSet(Exception):
+ pass
+
+
+class TargetAlreadySet(Exception):
+ pass
+
+
+class WithTarget(object):
+ '''
+ Mixin that adds a property 'target' than can only be set once and
+ raises an exception if not set when accesed
+ '''
+
+ @property
+ def target(self):
+ try:
+ return self._target
+ except AttributeError as e:
+ raise NoTargetSet("No target for %r" % self, e)
+
+ @target.setter
+ def target(self, value):
+ if hasattr(self, '_target') and self._target is not None:
+ raise TargetAlreadySet(
+ "target of listener already set (%r)" % self._target
+ )
+ self._target = value
+
+
+class Listener(asyncore.dispatcher, WithTarget):
+ ''' Waits for new connections and accept()s them '''
+
+ def __init__(self, addr, target=None):
+ asyncore.dispatcher.__init__(self)
+ self.addr = addr
+ self.target = target
+ self.create_socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ self.set_reuse_addr()
+ self.bind(addr)
+ self.listen(5)
+
+ def writable(self):
+ return False
+
+ def handle_accept(self):
+ try:
+ sock, addr = self.accept()
+ except socket.error:
+ return
+ else:
+ self.target.add_instance(sock)
+
+ def close(self):
+ super(Listener, self).close()
+ if os.path.exists(self.addr):
+ logger.info('unlinking %r', self.addr)
+ os.unlink(self.addr)
+
+ def handle_error(self):
+ raise
+
+
+class Protocol(asynchat.async_chat):
+ ''' A connection with a single client '''
+
+ def __init__(self, socket, target=None):
+ asynchat.async_chat.__init__(self, socket)
+ self.socket = socket
+ self.target = target
+ self.buffer = bytearray()
+ self.set_terminator(b'\n')
+
+ def collect_incoming_data(self, data):
+ self.buffer += data
+
+ def found_terminator(self):
+ val = self.buffer.decode('utf-8')
+ del self.buffer[:]
+ self.target.parse_msg(val)
+
+ def handle_error(self):
+ raise

0 comments on commit fef467e

Please sign in to comment.