form_api.py 3.85 KB
import logging
import traceback

import colander
import deform.widget
from icecream import ic

log = logging.getLogger(__name__)
field_widgets = (deform.widget.TextInputWidget,
                 deform.widget.MoneyInputWidget,
                 deform.widget.AutocompleteInputWidget,
                 deform.widget.TimeInputWidget,
                 deform.widget.DateInputWidget,
                 deform.widget.DateTimeInputWidget,
                 deform.widget.TextAreaWidget,
                 deform.widget.RichTextWidget,
                 deform.widget.PasswordWidget,
                 deform.widget.HiddenWidget,
                 deform.widget.CheckboxWidget,
                 deform.widget.SelectWidget,
                 deform.widget.Select2Widget,
                 deform.widget.SelectizeWidget,
                 deform.widget.RadioChoiceWidget,
                 deform.widget.CheckboxChoiceWidget,
                 deform.widget.CheckedInputWidget,
                 deform.widget.CheckedPasswordWidget,
                 deform.widget.MappingWidget,
                 deform.widget.SequenceWidget,
                 deform.widget.FileUploadWidget,
                 deform.widget.DatePartsWidget,
                 deform.widget.TextAreaCSVWidget,
                 deform.widget.TextInputCSVWidget,)

field2remove = (
    "_parent", "counter", "bindings", "resource_registry", "renderer",
     "validator"
)


def form2dict(obj):
    d = {}
    if hasattr(obj, "__dict__"):
        for k, v in obj.__dict__.items():
            d[k] = v
    else:
        d = obj
    ic(d)
    for k, v in d.items():
        ic(k,v, type(v))
        try:
            if k in field2remove:
                d[k] = ""
            elif type(v) == colander.Invalid:
                d[k] = v.asdict()
            elif type(v) == type(colander.null):
                d[k] = None
            elif isinstance(v, dict):
                d[k] = form2dict(v)
            elif isinstance(v, list):
                lv = []
                for l in v:
                    if l and hasattr(l, "__dict__") and \
                            getattr(l, "__dict__", str(l)):
                        lv.append(form2dict(l))
                d[k] = lv

            elif v and hasattr(v, "__dict__") and \
                    getattr(v, "__dict__", str(v)):
                log.debug(v)
                d[k] = form2dict(v)

            elif getattr(v, "__dict__", str(v)) == {}:
                d[k] = {}


            # elif getattr(v, "__dict__", str(v)):
            #     d[k] = form2dict(v)

            if k == "widget" and type(v) in field_widgets:
                d[k].update({"template": v.template})
                
            if k == "missing" and v == colander.drop:
                d[k] = True
        except Exception as e:
            log.error(e)
            traceback.print_exc()
    ic(d)
    return d


def remove_child(data):
    resp = []
    for d in data:
        if "children" in d and d["children"]:
            # try:
            d["children"] = remove_child(d["children"])
        # except:
        #     pass
        res = {}

        for x in d:
            if x not in field2remove:
                res[x] = d[x]
                if x == "_cstruct" and not d[x]:
                    res[x] = ""
        resp.append(res)
    return resp


def formfield2dict(obj):
    resp = form2dict(obj)
    log.debug(resp)
    children = resp["children"]
    children = remove_child(children)
    table = "table" in resp and resp["table"] or None
    result = dict(title=resp.get("title"),
                  children=children,
                  buttons=resp["buttons"],
                  url=resp.get("url"),
                  table=table,
                  method = resp.get("method")
                  )
    log.debug(result)
    return result