151 lines
4.5 KiB
Python
151 lines
4.5 KiB
Python
#!/usr/bin/env python
|
|
# _*_coding:utf-8_*_
|
|
|
|
"""
|
|
@Time : 2023/6/6 10:13
|
|
@Author : ji hao ran
|
|
@File : parser.py
|
|
@Project : StreamlitAntdComponents
|
|
@Software : PyCharm
|
|
"""
|
|
from .data_class import BsIcon, AntIcon, Tag
|
|
from dataclasses import is_dataclass
|
|
from typing import List, Union, Callable, Any
|
|
|
|
__all__ = ['update_kw', 'update_index', 'get_default', 'ParseItems', 'parse_icon']
|
|
|
|
|
|
def parse_icon(icon):
|
|
if isinstance(icon, str):
|
|
icon = BsIcon(name=icon).__dict__
|
|
elif isinstance(icon, BsIcon):
|
|
icon = icon.__dict__
|
|
elif isinstance(icon, AntIcon):
|
|
icon = icon.__dict__
|
|
return icon
|
|
|
|
|
|
def parse_tag(tag):
|
|
if isinstance(tag, Tag):
|
|
tag = tag.__dict__
|
|
elif isinstance(tag, str):
|
|
tag = Tag(tag).__dict__
|
|
elif isinstance(tag, list):
|
|
tag = [Tag(i).__dict__ if isinstance(i, str) else i.__dict__ for i in tag]
|
|
return tag
|
|
|
|
|
|
def update_kw(kw: dict, **kwargs):
|
|
r = kw.copy()
|
|
r.update(**kwargs)
|
|
delete_keys = ['format_func', 'key', 'on_change', 'args', 'kwargs']
|
|
for k in delete_keys:
|
|
if k in r.keys():
|
|
del r[k]
|
|
return r
|
|
|
|
|
|
def update_index(i, return_type='array'):
|
|
if return_type == 'array':
|
|
if isinstance(i, int):
|
|
return [i]
|
|
if i is None:
|
|
return []
|
|
return i
|
|
|
|
|
|
def get_default(index, return_index, kv):
|
|
if return_index:
|
|
return index
|
|
else:
|
|
if isinstance(index, int):
|
|
return kv.get(index)
|
|
if isinstance(index, list):
|
|
return [kv.get(i) for i in index]
|
|
if index is None:
|
|
return None
|
|
|
|
|
|
class ParseItems:
|
|
|
|
def __init__(self, items: List[Union[str, dict, Any]], format_func: Union[str, Callable] = None):
|
|
"""
|
|
|
|
:param items: component items data
|
|
:param format_func: format component item label func
|
|
"""
|
|
self.items = items if items is not None else []
|
|
self.format_func = format_func
|
|
|
|
def _label_format(self, label: str):
|
|
if self.format_func is not None:
|
|
if self.format_func == 'title':
|
|
return str.title(label)
|
|
elif self.format_func == 'upper':
|
|
return str.upper(label)
|
|
elif isinstance(self.format_func, Callable):
|
|
return self.format_func(label)
|
|
else:
|
|
return label
|
|
|
|
def transfer(self):
|
|
r, kv = [], {}
|
|
for idx, v in enumerate(self.items):
|
|
item = {'title': v}
|
|
item.update(key=idx) # add key
|
|
item.update(titleFormatter=self._label_format(v))
|
|
r.append(item)
|
|
kv.update({idx: v})
|
|
return r, kv
|
|
|
|
@staticmethod
|
|
def _item_to_dict(item, field: str = 'label'):
|
|
if isinstance(item, str):
|
|
it = {field: item}
|
|
elif is_dataclass(item):
|
|
it = item.__dict__
|
|
elif isinstance(item, dict):
|
|
it = item.copy()
|
|
else:
|
|
it = {}
|
|
if it.get('icon'):
|
|
it['icon'] = parse_icon(it.get('icon'))
|
|
if it.get('tag'):
|
|
it['tag'] = parse_tag(it.get('tag'))
|
|
return it
|
|
|
|
def single(self, key_field: str = 'key', label_field: str = 'label', key_as_str: bool = False):
|
|
"""parse single level component items data"""
|
|
r, kv = [], {}
|
|
for idx, v in enumerate(self.items):
|
|
item = self._item_to_dict(v, label_field)
|
|
label = item.get(label_field)
|
|
item.update({key_field: str(idx) if key_as_str else idx}) # add key
|
|
item.update({label_field: self._label_format(label)})
|
|
r.append(item)
|
|
kv.update({idx: label})
|
|
return r, kv
|
|
|
|
def multi(self, field: str = 'key'):
|
|
"""parse multiple levels component items data"""
|
|
key, kv0 = 0, []
|
|
|
|
def _add_key(items):
|
|
r1 = []
|
|
nonlocal key
|
|
for i in items:
|
|
item = self._item_to_dict(i)
|
|
kv0.append(item.get('label'))
|
|
children = item.get('children')
|
|
item.update({field: key}) # add field
|
|
key += 1
|
|
item.update(label=self._label_format(item.get('label')))
|
|
if children:
|
|
item.update(children=_add_key(children))
|
|
r1.append(item)
|
|
return r1
|
|
|
|
r = _add_key(self.items)
|
|
kv = {idx: v for idx, v in enumerate(kv0)}
|
|
return r, kv
|