Revision ee4bb099 ncclient/listeners.py
b/ncclient/listeners.py | ||
---|---|---|
1 |
# Copyright 2009 Shikhar Bhushan
|
|
1 |
# Copyright 2009 Shikhar Bhushan |
|
2 | 2 |
# |
3 | 3 |
# Licensed under the Apache License, Version 2.0 (the "License"); |
4 | 4 |
# you may not use this file except in compliance with the License. |
... | ... | |
13 | 13 |
# limitations under the License. |
14 | 14 |
|
15 | 15 |
import logging |
16 |
import weakref |
|
16 |
from weakref import WeakValueDictionary |
|
17 |
|
|
18 |
import content |
|
17 | 19 |
|
18 | 20 |
logger = logging.getLogger('ncclient.listeners') |
19 | 21 |
|
20 |
import content |
|
22 |
session_listeners = {} |
|
23 |
def session_listener_factory(session): |
|
24 |
try: |
|
25 |
return session_listeners[session] |
|
26 |
except KeyError: |
|
27 |
session_listeners[session] = SessionListener() |
|
28 |
return session_listeners[session] |
|
21 | 29 |
|
22 | 30 |
class SessionListener(object): |
23 | 31 |
|
24 |
'A multiton - one listener per session' |
|
25 |
|
|
26 |
instances = weakref.WeakValueDictionary() |
|
27 |
|
|
28 |
def __new__(cls, sid): |
|
29 |
if sid in instances:# not been gc'd |
|
30 |
return cls.instances[sid] |
|
31 |
else: |
|
32 |
inst = object.__new__(cls) |
|
33 |
cls.instances[sid] = inst |
|
34 |
return inst |
|
32 |
def __init__(self): |
|
33 |
self._id2rpc = WeakValueDictionary() |
|
34 |
self._expecting_close = False |
|
35 |
self._subscription = None |
|
35 | 36 |
|
36 | 37 |
def __str__(self): |
37 | 38 |
return 'SessionListener' |
38 | 39 |
|
39 |
def set_subscription(self, id):
|
|
40 |
def set_subscription(self, id): |
|
40 | 41 |
self._subscription = id |
41 | 42 |
|
43 |
def expect_close(self): |
|
44 |
self._expecting_close = True |
|
45 |
|
|
42 | 46 |
def register(self, id, op): |
43 | 47 |
self._id2rpc[id] = op |
44 | 48 |
|
45 |
def unregister(self, id): |
|
46 |
del self._id2prc[id] |
|
47 |
|
|
48 | 49 |
### Events |
49 | 50 |
|
50 | 51 |
def reply(self, raw): |
51 |
id = content.parse_message(raw) |
|
52 |
if id: |
|
53 |
self._id2rpc[id]._deliver(raw) |
|
54 |
else: |
|
55 |
self._id2rpc[self._sub_id]._notify(raw) |
|
52 |
try: |
|
53 |
id = content.parse_message_root(raw) |
|
54 |
if id is None: |
|
55 |
pass |
|
56 |
elif id == 'notification': |
|
57 |
self._id2rpc[self._sub_id]._notify(raw) |
|
58 |
else: |
|
59 |
self._id2rpc[id]._response_cb(raw) |
|
60 |
except Exception as e: |
|
61 |
logger.warning(e) |
|
56 | 62 |
|
57 |
def close(self, buf): |
|
58 |
pass # TODO |
|
63 |
def error(self, err): |
|
64 |
from ssh import SessionCloseError |
|
65 |
if err is SessionCloseError: |
|
66 |
logger.debug('received session close, expecting_close=%s' % |
|
67 |
self._expecting_close) |
|
68 |
if not self._expecting_close: |
|
69 |
raise err |
|
59 | 70 |
|
60 | 71 |
class DebugListener: |
61 | 72 |
|
... | ... | |
63 | 74 |
return 'DebugListener' |
64 | 75 |
|
65 | 76 |
def reply(self, raw): |
66 |
logger.debug('reply:\n%s' % raw) |
|
77 |
logger.debug('DebugListener:reply:\n%s' % raw)
|
|
67 | 78 |
|
68 | 79 |
def error(self, err): |
69 |
logger.debug(err) |
|
80 |
logger.debug('DebugListener:error:\n%s' % err) |
Also available in: Unified diff