Fix handling binary menus.

This commit is contained in:
Jakub Skiepko 2014-06-14 15:39:11 +02:00
parent 6dade12592
commit 5f5729c445
2 changed files with 51 additions and 35 deletions

View file

@ -12,17 +12,17 @@ class ApiCommunicator(object):
self.response_buffor = collections.defaultdict(AsynchronousResponse)
def call(self, path, command, arguments=None, queries=None,
additional_queries=()):
additional_queries=(), binary=False):
self.send_command(path, command, arguments, queries,
additional_queries=additional_queries)
return self.receive_synchronous()
return self._get_receiver(binary).receive_synchronous()
def call_async(self, path, command, arguments=None, queries=None,
additional_queries=()):
additional_queries=(), binary=False):
tag = self._get_next_tag()
self.send_command(path, command, arguments, queries, tag=tag,
additional_queries=additional_queries)
return ResponsePromise(self, tag)
return ResponsePromise(self._get_receiver(binary), tag)
def send_command(self, path, command, arguments=None, queries=None,
tag=None, additional_queries=()):
@ -37,32 +37,53 @@ class ApiCommunicator(object):
command.filter(additional_query)
self.base.send_sentence(command.get_api_format())
def receive_single_response(self, binary=False):
return self._get_receiver(binary).receive_single_response()
def _get_next_tag(self):
self.tag += 1
return str(self.tag)
def _get_receiver(self, binary):
if binary:
return ApiReceiver(self.base, self.response_buffor)
else:
return AsciiApiReceiver(self.base, self.response_buffor)
class ApiReceiver(object):
sentence_class = sentence.ResponseSentence
def __init__(self, base, response_buffor):
self.base = base
self.response_buffor = response_buffor
def receive_single_response(self):
serialized = []
while not serialized:
serialized = self.base.receive_sentence()
response = sentence.ResponseSentence.parse(serialized)
response = self.sentence_class.parse(serialized)
return response
def process_single_response(self):
response = self.receive_single_response()
tag = response.tag if response.tag is not None else b'synchronous'
tag = response.tag if response.tag is not None else 'synchronous'
asynchronous_response = self.response_buffor[tag]
if response.type == b're':
if response.type == 're':
attributes = response.attributes
asynchronous_response.attributes.append(attributes)
elif response.type == b'done':
elif response.type == 'done':
asynchronous_response.done = True
elif response.type == b'trap':
elif response.type == 'trap':
asynchronous_response.done = True
asynchronous_response.error = response.attributes[b'message']
asynchronous_response.error = response.attributes['message']
else:
del(self.response_buffor[tag])
raise exceptions.RouterOsApiConnectionClosedError(
response.attributes[b'message'])
response.attributes['message'])
def receive_synchronous(self):
return self.receive_asynchronous(b'synchronous')
return self.receive_asynchronous('synchronous')
def receive_asynchronous(self, tag):
response = self.response_buffor[tag]
@ -74,9 +95,9 @@ class ApiCommunicator(object):
else:
return response.attributes
def _get_next_tag(self):
self.tag += 1
return str(self.tag).encode()
class AsciiApiReceiver(ApiReceiver):
sentence_class = sentence.AsciiResponseSentence
class AsynchronousResponse(object):
@ -87,22 +108,9 @@ class AsynchronousResponse(object):
class ResponsePromise(object):
def __init__(self, communicator, tag):
self.communicator = communicator
def __init__(self, receiver, tag):
self.receiver = receiver
self.tag = tag
def get(self):
return self.communicator.receive_asynchronous(self.tag)
class UnicodeApiCommunicator(ApiCommunicator):
def receive_asynchronous(self, tag):
original = super(UnicodeApiCommunicator, self).receive_asynchronous(
tag)
response = []
for original_row in original:
row = {}
response.append(row)
for key, value in original_row.items():
row[key.decode()] = value.decode()
return response
return self.receiver.receive_asynchronous(self.tag)

View file

@ -20,7 +20,7 @@ class ResponseSentence(object):
def parse(cls, sentence):
response_match = response_re.match(sentence[0])
if response_match:
response = cls(response_match.group(1))
response = cls(response_match.group(1).decode())
response.parse_attributes(sentence[1:])
else:
raise exceptions.RouterOsApiParsingError("Malformed sentence %s",
@ -34,13 +34,21 @@ class ResponseSentence(object):
tag_match = tag_re.match(serialized)
if attribute_match:
key, value = attribute_match.groups()
self.attributes[key] = value
self.attributes[key.decode()] = self.process_value(value)
elif tag_match:
self.tag = tag_match.group(1)
self.tag = tag_match.group(1).decode()
else:
raise exceptions.RouterOsApiParsingError(
"Malformed attribute %s", serialized)
def process_value(self, value):
return value
class AsciiResponseSentence(ResponseSentence):
def process_value(self, value):
return value.decode()
class CommandSentence(object):
def __init__(self, path, command, tag=None):
@ -49,7 +57,7 @@ class CommandSentence(object):
self.attributes = {}
self.api_attributes = {}
self.queries = set()
self.tag = tag
self.tag = utils.get_bytes(tag)
def get_api_format(self):
formated = [self.path + self.command]