Esempio n. 1
0
def network_choice_node():
    """Create a colander.SchemaNode() with a drop down to choose one of AssetNetworks."""
    return colander.SchemaNode(

        # Convert selection widget UUIDs back to Customer objects
        UUIDForeignKeyValue(model=AssetNetwork, match_column="id"),
        title="Chain",

        # A SelectWidget with values lazily populated
        widget=network_choice_widget)
Esempio n. 2
0
    def map_standard_relationship(self, mode, request, node, model, name, rel) -> colander.SchemaNode:
        """Build a widget for choosing a relationship with target.

        The relationship must be foreign_key and the remote must offer ``uuid`` attribute which we use as a vocabulary key..
        """

        if isinstance(rel.argument, Mapper):
            # TODO: How to handle this kind of relationships
            return TypeOverridesHandling.drop

        if isinstance(rel.argument, _class_resolver):
            # Case from tutorialapp:
            # <RelationshipProperty at 0x1095a4438; question>
            # <class 'sqlalchemy.ext.declarative.clsregistry._class_resolver'>
            remote_model = rel.argument()
        else:
            remote_model = rel.argument

        # Get first column of the set
        for column in rel.local_columns:
            break

        # For now, we automatically deal with this only if the model provides uuid
        if hasattr(remote_model, "uuid"):
            dbsession = request.dbsession
            # TODO: We probably need a mechanism for system wide empty default label

            required = not column.nullable

            if mode in (EditMode.add, EditMode.edit):
                default_choice = "--- Choose one ---"
            else:
                default_choice = "(not set)"

            if required:
                missing = colander.required
            else:
                missing = None

            vocabulary = get_uuid_vocabulary_for_model(dbsession, remote_model, default_choice=default_choice)

            if rel.uselist:
                # Show out all relationships
                if mode == EditMode.show:
                    return colander.SchemaNode(UUIDModelSet(remote_model), name=name, missing=missing, widget=deform.widget.CheckboxChoiceWidget(values=vocabulary))
            else:
                # Select from a single relationship
                return colander.SchemaNode(UUIDForeignKeyValue(remote_model), name=name, missing=missing, widget=deform.widget.SelectWidget(values=vocabulary))

        return TypeOverridesHandling.drop
Esempio n. 3
0
class AssetSchema(colander.Schema):

    #: Human readable name
    name = colander.SchemaNode(colander.String())

    #:  The network this asset is in
    network = colander.SchemaNode(
        UUIDForeignKeyValue(model=AssetNetwork, match_column="id"),
        widget=defer_widget_values(deform.widget.SelectWidget,
                                   available_networks),
    )

    #: Symbol how this asset is presented in tickers
    symbol = colander.SchemaNode(colander.String())

    description = colander.SchemaNode(colander.String(), missing="")

    #: Markdown page telling about this asset
    long_description = colander.SchemaNode(colander.String(),
                                           description="Markdown formatted",
                                           missing="",
                                           widget=deform.widget.TextAreaWidget(
                                               rows=20, cols=80))

    #: Ethereum address
    external_id = colander.SchemaNode(colander.String(),
                                      title="Address",
                                      validator=validate_ethereum_address,
                                      missing=None,
                                      description="0x hex string format")

    #: Number of units avaialble
    supply = colander.SchemaNode(colander.Decimal(), missing=None)

    #: What kind of asset is this
    asset_class = colander.SchemaNode(
        EnumValue(AssetClass),
        widget=deform.widget.SelectWidget(values=enum_values(AssetClass)))

    #: Workflow state of this asset
    state = colander.SchemaNode(
        EnumValue(AssetState),
        widget=deform.widget.SelectWidget(values=enum_values(AssetState)))

    other_data = colander.SchemaNode(
        JSONValue(),
        widget=JSONWidget(),
        description="JSON bag of attributes of the object",
        missing=dict)

    def dictify(self, obj: Asset) -> dict:
        """Serialize SQLAlchemy model instance to nested dictionary appstruct presentation."""

        appstruct = dictify(self,
                            obj,
                            excludes=("long_description", "external_id"))

        # Convert between binary storage and human readable hex presentation
        appstruct["long_description"] = obj.other_data.pop(
            "long_description", "")

        if obj.external_id:
            appstruct["external_id"] = bin_to_eth_address(obj.external_id)
        else:
            appstruct["external_id"] = ""

        return appstruct

    def objectify(self, appstruct: dict, obj: Asset):
        """Store the dictionary data from the form submission on the object."""

        objectify(self,
                  appstruct,
                  obj,
                  excludes=("long_description", "external_id"))

        if not obj.other_data:
            # When creating the object JSON value may be None
            # instead of empty dict
            obj.other_data = {}

        # Special case of field stored inside JSON bag
        obj.other_data["long_description"] = appstruct["long_description"]

        # Convert between binary storage and human readable hex presentation
        if appstruct["external_id"]:
            obj.external_id = eth_address_to_bin(appstruct["external_id"])