clientbot/tools/DecodeDatabase.py

140 lines
4.3 KiB
Python
Raw Normal View History

2020-07-20 19:57:27 +00:00
#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# module DecodeDatabase
#
# Copyright (C) 2019 AleaJactaEst
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from tools import getPowerOf2
LOGGER='DecodeDatabase'
def show_dico(dico, level=1):
for ele in dico:
if isinstance(dico[ele], dict):
print("." * level, ele , ":")
if isinstance(dico[ele], dict):
show_dico(dico[ele], level+1)
else:
print("." * level, ele, ':', dico[ele])
def child(ele):
ret = {}
ret_branch = {}
ref_other = {}
id_branch = 0
id_other = 0
min_i = -1
max_i = -1
for k in ele.keys():
ret[k] = ele.get(k)
print(k, ele.get(k))
for _child in list(ele):
x = child(_child)
if x['name'] == 'branch':
ret_branch.setdefault(id_branch, x)
id_branch += 1
else:
ref_other.setdefault(id_other, x)
id_other += 1
if ret_branch or ref_other:
ret['child'] = {}
id = 0
for x in ret_branch:
min_i = max_i + 1
max_i = min_i
#show_dico( ret_branch[x])
if 'count' in ret_branch[x]:
max_i = min_i + int(ret_branch[x]['count']) - 1
ret_branch[x]['min'] = min_i
ret_branch[x]['max'] = max_i
ret['child'].setdefault(id, ret_branch[x])
id += 1
for x in ref_other:
min_i = max_i + 1
max_i = min_i
#show_dico( ref_other[x])
if 'count' in ref_other[x]:
max_i = min_i + int(ref_other[x]['count']) - 1
ref_other[x]['min'] = min_i
ref_other[x]['max'] = max_i
ret['child'].setdefault(id, ref_other[x])
id += 1
return ret
def count_elements(head):
try:
return head.items()[-1]['max'] + 1
except TypeError:
return len(head)
def get_element(head, id):
print("id:", id)
for ele in head:
if id <= head[ele]['max'] and id >= head[ele]['min']:
return head[ele]
return None
class DecodeDatabase():
def __init__(self):
self.databaseXml = None
self.databasePlr = None
def loadDatabase(self, databaseXml):
logging.getLogger(LOGGER).debug("loadDatabase")
self.databaseXml = databaseXml
id = 0
self.databasePlr = {}
for ele in self.databaseXml:
if ele.tag == 'branch':
if ele.get('bank') == "PLR":
self.databasePlr[id] = child(ele)
self.databasePlr[id]['min'] = id
self.databasePlr[id]['max'] = id
id += 1
print(dir(ele))
print("-" * 80)
show_dico(self.databasePlr)
print("-" * 80)
#raise "Decode"
def execute(self, msgin, world):
logging.getLogger(LOGGER).debug("execute")
head = self.databasePlr
listpath = []
while True:
logging.getLogger(LOGGER).debug("count_elements:" + str(count_elements(head)))
nbBit = getPowerOf2.getPowerOf2(count_elements(head))
logging.getLogger(LOGGER).debug("nbBit:" + str(nbBit))
id = msgin.readSerial(nbBit, name='DatabaseXML', typeName='Number', emulate=True)
logging.getLogger(LOGGER).debug("XML DECODE : %3d -> %s" % (nbBit, ':'.join(listpath)) )
ele = get_element(head, id)
print(ele)
show_dico(ele)
name = ele['name']
listpath.append(name)
fullname = ':'.join(listpath)
logging.getLogger(LOGGER).debug(fullname)
if 'type' in ele:
print("+"*80)
return True
head = ele
print("-"*80)
return False