I'm trying to convert data from a post to Json formed.
But I still haven't had success.
I tried to do in this format
Unfortunately I couldn't think of anything.
Could anyone help?
Post
{'csrfmiddlewaretoken': 'AdbaFrsoWeZTnT07m3VjncmYnYHztaQ214qh8AYH2cI40veXfe0dmfSwkI1o2ma1',
'det[0][CNPJ]': '8768678678678',
'det[0][UF]': 'SP',
'det[0][dhEmi]': '2021-07-13T08:26:30-03:00',
'det[0][nNF]': '8267',
'det[0][xNome]': 'INDÚSTRIA',
'prod[0][0][CFOP]': '6102',
'prod[0][0][NCM]': '84384000',
'prod[0][0][UF]': 'SP',
'prod[0][0][aliquotaInterna]': '18',
'prod[0][0][counter]': '1',
'prod[0][0][mva]': '34',
'prod[0][0][tributacaoEstadual]': '7',
'prod[0][0][vICMSST]': '0',
'prod[0][0][vICMS]': '25.74',
'prod[0][0][vIPI]': '0',
'prod[0][0][vProd]': '367.68',
'prod[0][0][xProd]': 'FUSO',
'prod[0][1][CFOP]': '6102',
'prod[0][1][NCM]': '84384000',
'prod[0][1][UF]': 'SP',
'prod[0][1][aliquotaInterna]': '18',
'prod[0][1][counter]': '2',
'prod[0][1][mva]': '23',
'prod[0][1][tributacaoEstadual]': '7',
'prod[0][1][vICMSST]': '0',
'prod[0][1][vICMS]': '15.96',
'prod[0][1][vIPI]': '0',
'prod[0][1][vProd]': '228.07',
'prod[0][1][xProd]': 'PORCA',
'xNome': 'COMERCIAL'}
View
if post:
import re
pattDet = re.compile('^([a-zA-Z_]\w .)\[([0-9_\-][\w\-]*)\]\[([a-zA-Z_\-][\w\-]*)\]$')
pattProd = re.compile('^([a-zA-Z_]\w .)\[([0-9_\-][\w\-]*)\]\[([0-9_\-][\w\-]*)\]\[([a-zA-Z_\-][\w\-]*)\]$')
pprint.pprint(post)
det = []
prodtem = []
count = 0
for post_name, value in post.items():
try:
det_count = int(pattDet.match(post_name).group(2))
if pattDet.match(post_name).group(1) == 'det':
det[pattDet.match(post_name).group(3)] = value
except:
pass
try:
if pattProd.match(post_name).group(1) == 'prod':
if count == int(pattProd.match(post_name).group(3)):
prodtem.insert(count, {pattProd.match(post_name).group(4): value})
else:
count = 1
except Exception as e:
print(e)
pass
result.append({
'det': det,
'prod': prodtem
})
CodePudding user response:
many month ago i have create this for django rest framwork, a parser mutli dimensional, source is here i have adapted the parser for you
import re
class ParserMultiDimensional:
_reg_split = re.compile(r"(\[.*?\])")
REG_NAME = r"\s*[a-zA-Z_]\w*\s*"
_reg_name = re.compile(r"^" REG_NAME r"$")
REG_INDEX_LIST = r"\s*(\d )?\s*"
_reg_index_list = re.compile(r"^\[(" REG_INDEX_LIST r")\]$") # can be number or nothing
_reg_index_object = re.compile(r"^\[(" REG_NAME r")\]$") # need to start with char alpaha
_reg_list = re.compile(r"^\[" REG_INDEX_LIST r"]$")
_reg_object = re.compile(r"^\[" REG_NAME r"]$")
def __init__(self, data):
self.data = data
self._valid = None
def conv_list_index(self, key):
ret = self._reg_index_list.search(key).groups()[0]
if not ret:
return -1
return int(ret)
def conv_object_index(self, key):
return self._reg_index_object.search(key).groups()[0]
def conv_index(self, index):
if self.is_list(index):
return self.conv_list_index(index)
elif self.is_object(index):
return self.conv_object_index(index)
else:
return index
def is_list(self, key):
if not key or self._reg_list.match(key):
return True
return False
def is_object(self, key):
if self._reg_object.match(key):
return True
return False
def is_name(self, key):
if self._reg_name.match(key):
return True
return False
def split_key(self, key):
# remove space
key = key.replace(" ", "")
results = self._reg_split.split(key)
# remove empty string
return list(filter(None, results))
def valid_key(self, key):
results = self.split_key(key)
# not result or check first element
if not results or not self.is_name(results[0]):
return []
for r in results[1:]:
if not self.is_list(r) and not self.is_object(r):
return []
return results
def set_type(self, dtc, key, value):
index = self.conv_index(key)
if self.is_list(key):
if not len(dtc) or index == len(dtc):
dtc.append(value)
key = len(dtc) - 1
elif index not in dtc:
# TODO dict same as list
dtc[index] = value
return index
def construct(self, data):
dictionary = {}
for key, value in data.items():
keys = self.valid_key(key)
if not keys:
raise Exception(f"invalid key {keys}")
tmp = dictionary
for curr, nxt in zip(keys, keys[1:]):
set_type = [] if self.is_list(nxt) else {}
tmp = tmp[self.set_type(tmp, curr, set_type)]
self.set_type(tmp, keys[-1], data.get(key))
self.__validate_data = dictionary
def is_valid(self):
self._valid = False
try:
self.construct(self.data)
self._valid = True
except Exception as err:
self.errors = err
return self._valid
@property
def validate_data(self):
if self._valid is None:
raise ValueError("You need to be call is_valid() before access validate_data")
if self._valid is False:
raise ValueError("You can't get validate data")
return self.__validate_data
to use it
parser = ParserMultiDimensional(data_query) # add your post data
if parser.is_valid():
data = parser.validate_data
# do your things
else:
print(parser.errors)
the result with your data is
{
"csrfmiddlewaretoken": "AdbaFrsoWeZTnT07m3VjncmYnYHztaQ214qh8AYH2cI40veXfe0dmfSwkI1o2ma1",
"det": [
{
"CNPJ": "8768678678678",
"UF": "SP",
"dhEmi": "2021-07-13T08:26:30-03:00",
"nNF": "8267",
"xNome": "INDÚSTRIA"
}
],
"prod": [
[
{
"CFOP": "6102",
"NCM": "84384000",
"UF": "SP",
"aliquotaInterna": "18",
"counter": "1",
"mva": "34",
"tributacaoEstadual": "7",
"vICMSST": "0",
"vICMS": "25.74",
"vIPI": "0",
"vProd": "367.68",
"xProd": "FUSO"
},
{
"CFOP": "6102",
"NCM": "84384000",
"UF": "SP",
"aliquotaInterna": "18",
"counter": "2",
"mva": "23",
"tributacaoEstadual": "7",
"vICMSST": "0",
"vICMS": "15.96",
"vIPI": "0",
"vProd": "228.07",
"xProd": "PORCA"
}
]
],
"xNome": "COMERCIAL"
}
have fun with it ! ;)