Skip to content

Commit d293201

Browse files
added dict -> json export option
- fixed recursive issue on vba json view
1 parent aad416a commit d293201

File tree

1 file changed

+88
-6
lines changed

1 file changed

+88
-6
lines changed

pyvba/export.py

Lines changed: 88 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ def _generate_dict(self):
210210
tag = XMLExport.Tag(self._browser.name, count=len(visited2))
211211
xml = self._xml_head + tag.open_tag + "\n"
212212

213-
# iterate through dictionary items
213+
# iterate through dictionary
214214
for var, value in visited2.items():
215215
tag1 = XMLExport.Tag(var, count=len(value))
216216
xml += "\t" + tag1.open_tag + "\n"
@@ -360,7 +360,7 @@ def json_encode(text: str) -> str:
360360
def _check(self):
361361
"""Check if the JSON string needs to be generated."""
362362
if self._data is None:
363-
self._data = self._generate_vba(self._browser)
363+
self._data = self._generate_vba(self._browser) if self._vba_form else self._generate_dict()
364364
self._data = re.sub(r',(?!\s*?[{\[\"\'\w])', '', self._data)
365365

366366
def _generate_vba(self, elem, tabs: int = 0, **kwargs) -> str:
@@ -380,29 +380,37 @@ def _generate_vba(self, elem, tabs: int = 0, **kwargs) -> str:
380380
"""
381381

382382
json = ''
383+
stack = kwargs.get('stack', [])
384+
383385
if isinstance(elem, Browser):
386+
# check if in stack already
387+
if elem in stack:
388+
return "\t" * tabs + f"{{ \"{self.json_encode(elem.name)}\": \"BrowserObject: See ancestors\" }},\n"
389+
else:
390+
stack.append(elem)
391+
384392
# display the browser and its children
385393
json += "\t" * tabs + f"{{ \"{self.json_encode(elem.name)}\": [\n"
386394

387395
for item, value in elem.all.items():
388396
if type(value) is list and len(value) > 0:
389397
json += "\t" * (tabs + 1) + "{ \"Item\": [\n"
390398
for i in value:
391-
json += self._generate_vba(i, tabs + 2)
399+
json += self._generate_vba(i, tabs + 2, stack=stack)
392400
json += "\t" * (tabs + 1) + "]},\n"
393401
else:
394-
json += self._generate_vba(value, tabs + 1, name=item)
402+
json += self._generate_vba(value, tabs + 1, name=item, stack=stack)
395403

396404
json += "\t" * tabs + "]},\n"
397405
elif isinstance(elem, FunctionViewer):
398406
if not self._skip_func:
399407
# display the function and its properties
400408
json += "\t" * tabs + f"{{ \"{self.json_encode(elem.name)}\": [\n"
401-
json += "\t" * (tabs + 1) + f"{{ \"Name\": \"{self.json_encode(elem.name)}\" }},\n"
409+
json += "\t" * (tabs + 1) + f"{{ \"name\": \"{self.json_encode(elem.name)}\" }},\n"
402410
json += "\t" * (tabs + 1) + f"{{ \"args\": {self.json_encode(str(len(elem.args)))} }},\n"
403411
json += "\t" * (tabs + 1) + f"{{ \"use\": \"{self.json_encode(str(elem)[26:])}\" }}\n"
404412
json += "\t" * tabs + "]},\n"
405-
elif isinstance(elem, BaseException):
413+
elif isinstance(elem, com_error):
406414
# display the error location and method
407415
if not self._skip_err:
408416
json += "\t" * tabs + "{ \"Error\": [\n"
@@ -425,3 +433,77 @@ def _generate_vba(self, elem, tabs: int = 0, **kwargs) -> str:
425433

426434
json += "\t" * tabs + f"{{ \"{name}\": {elem} }},\n"
427435
return json
436+
437+
def _generate_dict(self) -> str:
438+
# collect visited data and obtain a copy
439+
"""Begin generating the XML string based on the visited dictionary."""
440+
# populate browser and copy visited
441+
self._browser.browse_all()
442+
visited2 = copy.copy(visited)
443+
json = f'{{ "{self._browser.name}": [\n'
444+
445+
# iterate through dictionary items
446+
for var, value in visited2.items():
447+
json += f'\t{{ "{var}": [\n'
448+
449+
# iterate through each list
450+
for item in value:
451+
json += f'\t\t{{ "{item.name}": [\n'
452+
453+
# iterate through each browser in the list
454+
for var2, value2 in item.all.items():
455+
# check for a collection object
456+
if isinstance(value2, list):
457+
json += f'\t\t\t{{ "{var2}": [\n'
458+
459+
# iterate through the browser's collection
460+
for item2 in value2:
461+
output = item2.name if isinstance(item2, Browser) else item2
462+
json += f'\t\t\t\t{{ "{output}": "BrowserObject" }},\n'
463+
464+
json += '\t\t\t]},\n'
465+
else:
466+
if isinstance(value2, Browser):
467+
json += f'\t\t\t{{ \"{value2.name}\": \"BrowserObject\" }},\n'
468+
469+
elif isinstance(value2, com_error):
470+
if self._skip_err:
471+
continue
472+
473+
json += "\t\t\t{ \"Error\": [\n"
474+
try:
475+
json += f"\t\t\t\t{{ \"on\": \"{self.json_encode(str(value2.args[2][1]))}\" }},\n"
476+
json += f"\t\t\t\t{{ \"message\": \"{self.json_encode(str(value2.args[2][2]))}\" }}\n"
477+
except TypeError:
478+
json += f"\t\t\t\t{{ \"message\": \"{self.json_encode(str(value2.args[2]))}\" }}\n"
479+
except IndexError:
480+
json += f"\t\t\t\t{{ \"message\": \"{self.json_encode(str(value2))}\" }}\n"
481+
json += "\t\t\t]},\n"
482+
483+
elif isinstance(value2, FunctionViewer):
484+
if self._skip_func:
485+
continue
486+
# display the function and its properties
487+
json += f"\t\t\t{{ \"{self.json_encode(value2.name)}\": [\n"
488+
json += f"\t\t\t\t{{ \"name\": \"{self.json_encode(value2.name)}\" }},\n"
489+
json += f"\t\t\t\t{{ \"args\": {self.json_encode(str(len(value2.args)))} }},\n"
490+
json += f"\t\t\t\t{{ \"use\": \"{self.json_encode(str(value2)[26:])}\" }}\n"
491+
json += "\t\t\t]},\n"
492+
493+
else:
494+
# display the variable and value
495+
name = self.json_encode(var2)
496+
elem = value2
497+
498+
if isinstance(value2, bool):
499+
elem = str(value2).lower()
500+
elif not isinstance(value2, (int, float, complex)):
501+
elem = f"\"{self.json_encode(str(value2))}\""
502+
503+
json += f"\t\t\t{{ \"{name}\": {elem} }},\n"
504+
505+
json += '\t\t]},\n'
506+
507+
json += '\t]},\n'
508+
509+
return json + ']}\n'

0 commit comments

Comments
 (0)