mirror of
https://github.com/socialwifi/RouterOS-api.git
synced 2025-08-31 23:20:05 +02:00
Fix handling binary menus.
This commit is contained in:
parent
6dade12592
commit
5f5729c445
2 changed files with 51 additions and 35 deletions
|
@ -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)
|
||||
|
|
|
@ -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]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue