From 30dc3146a1b188e7a3758234a4e1f5f195a1a3be Mon Sep 17 00:00:00 2001 From: Stefano Miccoli Date: Thu, 10 Apr 2014 22:22:14 +0200 Subject: [PATCH] better OwnetProxy init logic --- TODO | 2 -- pyownet/__init__.py | 2 +- pyownet/protocol.py | 76 ++++++++++++++++++--------------------------- tests.py | 2 ++ 4 files changed, 33 insertions(+), 49 deletions(-) diff --git a/TODO b/TODO index cb8d4b6..af0baff 100644 --- a/TODO +++ b/TODO @@ -1,8 +1,6 @@ document that every pathname has to by an ASCIIZ string in the wire -sending on the wire non ASCIIZ strings gives unpredictable results - FLG_ALIAS is apparently not working on the dir() reply offset field seems to code some info (?) diff --git a/pyownet/__init__.py b/pyownet/__init__.py index fcc9b17..ade5150 100644 --- a/pyownet/__init__.py +++ b/pyownet/__init__.py @@ -17,4 +17,4 @@ # along with this program. If not, see . # -__version__ = '0.7.1.dev1' +__version__ = '0.7.1.dev2' diff --git a/pyownet/protocol.py b/pyownet/protocol.py index 3d6dc27..307cc2b 100644 --- a/pyownet/protocol.py +++ b/pyownet/protocol.py @@ -266,14 +266,17 @@ def __init__(self, sockaddr, family=socket.AF_INET, verbose=False): "establish a connection with server at sockaddr" self.verbose = verbose + self.socket = socket.socket(family, socket.SOCK_STREAM) self.socket.settimeout(_SCK_TIMEOUT) self.socket.connect(sockaddr) + if self.verbose: print(self.socket.getsockname(), '->', self.socket.getpeername()) def shutdown(self): "shutdown connection" + self.socket.shutdown(socket.SHUT_RDWR) self.socket.close() @@ -336,6 +339,20 @@ def __init__(self, host='localhost', port=4304, flags=0, printed on stdout. """ + # save init args + self._hostport = (host, port) + self.flags = flags | FLG_OWNET + self.verbose = verbose + + # default (empty) errcodes tuple + self.errmess = _errtuple() + + # + # init logic: + # try to connect to the given owserver, send a MSG_NOP, + # and check answer + # + # resolve host name/port try: gai = socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM) @@ -344,43 +361,26 @@ def __init__(self, host='localhost', port=4304, flags=0, # gai is a list of tuples, search for the first working one lasterr = None - for (family, _, _, _, sockaddr) in gai: + for (self._family, _, _, _, self._sockaddr) in gai: try: - conn = OwnetConnection(sockaddr, family, verbose) - except socket.error as err: + self.ping() + except ConnError as err: # not working, go over to next sockaddr lasterr = err else: # ok, this is working, stop searching break else: - # no working (sockaddr, family) found: raise error - assert isinstance(lasterr, socket.error) - assert isinstance(lasterr, IOError) - raise ConnError(*lasterr.args) + # no working (sockaddr, family) found: reraise last exception + assert isinstance(lasterr, ConnError) + raise lasterr - # here we have an open connection, close for now - conn.shutdown() - - # setup self attributes - self._sockaddr, self._family = sockaddr, family - self._hostport = (host, port) # for display only - - self.verbose = verbose - self.flags = flags | FLG_OWNET - - self.errmess = _errtuple() - - # final sanity checks - # does the remote end speak the ownet protocol? - self.ping() - # fetch errcodes array from owserver try: self.errmess = _errtuple( m for m in bytes2str(self.read(PTH_ERRCODES)).split(',')) except OwnetError: - # failed, leave the default defined above + # failed, leave the default empty errcodes defined above pass def __str__(self): @@ -394,8 +394,7 @@ def sendmess(self, type, payload, flags=0, size=0, offset=0): flags |= self.flags try: - conn = OwnetConnection(self._sockaddr, self._family, - self.verbose) + conn = OwnetConnection(self._sockaddr, self._family, self.verbose) ret, _, data = conn.req(type, payload, flags, size, offset) conn.shutdown() except IOError as err: @@ -413,8 +412,7 @@ def present(self, path): "returns True if there is an entity at path" ret, data = self.sendmess(MSG_PRESENCE, str2bytez(path)) - assert ret <= 0 - assert len(data) == 0 + assert ret <= 0 and len(data) == 0 if ret < 0: return False else: @@ -458,26 +456,12 @@ def write(self, path, data): ensure proper encoding. """ - assert isinstance(data, bytes) + # fixme: check of path type delayed to str2bytez + if not isinstance(data, bytes): + raise TypeError("'data' argument must be of type 'bytes'") + ret, rdata = self.sendmess(MSG_WRITE, str2bytez(path)+data, size=len(data)) assert len(rdata) == 0 if ret < 0: raise OwnetError(-ret, self.errmess[-ret], path) - -def _main(): - # print sensors on localhost owserver - try: - proxy = OwnetProxy() - except ConnError: - print("No owserver on localhost") - return 1 - print("directory on {0}:".format(proxy)) - print("id".center(17), "type".center(7)) - for sensor in proxy.dir(slash=False, bus=False): - stype = bytes2str(proxy.read(sensor + '/type')) - print(sensor.ljust(17), stype.ljust(7)) - return 0 - -if __name__ == '__main__': - _main() diff --git a/tests.py b/tests.py index 328fd95..6c72e32 100644 --- a/tests.py +++ b/tests.py @@ -31,6 +31,8 @@ def test_exceptions(self): self.assertRaises(protocol.ConnError, protocol.OwnetProxy, host='nonexistent.fake') self.assertRaises(TypeError, self.proxy.dir, 1) + self.assertRaises(TypeError, self.proxy.write, '/', 1) + self.assertRaises(TypeError, self.proxy.write, 1, b'abc') if __name__ == '__main__': unittest.main()