Source code for lerna.fields

# -*- coding: utf-8 -*-
"""General, standardized definitions for form data.

Used for standardizing data from various sources with
one "schema." The fields are described through meta
classes: description, field data structure, regex.

Autocomplete values inserted from sheet at:
https://docs.google.com/a/ave81.com/spreadsheets/d/1qpPtPvbFTGKrBMxTjYIWERv8zmEPR0dNc4x31IS00ZM/edit?usp=sharing
"""
from __future__ import absolute_import
import inspect
import six

from req import schema


class _BaseField(schema.Schema):
    """The generic representation of a field.
    """

    #: The field's name, which maps to an HTML ``name`` attribute. Required.
    name = schema.String(
        _description="The field's name, this maps to an HTML <code>name</code> attribute."
    )

    #: The field's label or caption, which maps to an HTML ``label`` element. Required.
    label = schema.String(
        _description="The field's label/caption, this maps to an HTML <code>label</code> element."
    )

    #: The field's description, which maps to the HTML ``description`` attribute. Optional.
    description = schema.String(
        _optional=True,
        _description="The field's description, this maps to the HTML <code>description</code> attribute.",
    )

    #: Optional: a placeholder that is displayed when the field has no value. Optional.
    placeholder = schema.String(
        _optional=True,
        _description="A placeholder that is displayed when the field has no value.",
    )

    #: Represents whether or not this field is required.
    required = schema.Boolean(
        _description="Represents whether or not this field is required."
    )

    autocomplete = schema.String(
        _name="autoComplete",
        _optional=True,
        _description="The autocomplete merge field name",
    )


[docs]class TextField(_BaseField): """A generic text field. """ #: The field's default value. Optional. value = schema.String(_optional=True, _description="The field's default value.")
[docs]class CheckBoxField(_BaseField): """A generic checkbox field. """ #: A value that will get sent through when ``checked`` is ``True``. value = schema.String( _description="""A value that will get sent through when <code>checked</code> is <code>True</code>.""" ) #: Represents whether or not the ``value`` should be inspected. checked = schema.Boolean( _description="Represents whether or not the <code>value</code> should be inspected." )
[docs]class ChoiceField(_BaseField): """A generic field representing a single choice of a number of choices. """ #: Represents the default choice (by its ``value``). value = schema.String( _optional=True, _description="Represents the default choice (by its <code>value</code>).", ) #: This represents the possible choices for this field's value. values = schema.List( schema.Dictionary(value=schema.String(), label=schema.String()), _optional=True, _description="This represents the possible choices for this field's value.", )
[docs]class SelectField(ChoiceField): """A generic select field. """
[docs]class MultiSelectField(_BaseField): """A field representing multiple choice select. Differs from a SelectField in that SelectField may have only one selection (of the available choices), whereas a MultiSelectField may have multiple choices selected for its value. """ #: This represents the default selected possible value(s) for this field's value. value = schema.List( schema.String(), _optional=True, _description="""This represents the default selected possible value(s) for this field's value.""", ) #: This represents the possible values this field can have (any number of). values = schema.List( schema.Dictionary(value=schema.String(), label=schema.String()), _optional=True, _description="""This represents the possible values this field can have (any number of).""", )
[docs]class RadioField(ChoiceField): """A field representing multiple linked radio buttons. """
[docs]class ReadOnlyField(TextField): """A read only field. Must contain a default value. """ #: The field's value. value = schema.String(_description="The field's value.")
[docs]class HiddenField(TextField): """A hidden text field. """
[docs]class SystemHiddenField(HiddenField): """A hidden text field reserved for system use. This should be retained everywhere normal HiddenFields are, but generally should not be displayed to, or made editable by, users. """
[docs]class HiddenMultiSelectField(MultiSelectField): """A hidden field containing a list of values. This should be literally a MultiSelectField, but hidden. Differs from a HiddenField, which only has one value, and a MultiSelectField by being hidden. """
[docs]class NumberField(TextField): """A generic numeric field. """ #: The minimum numeric value that this field can contain. min_value = schema.Number( _name="minValue", _optional=True, _description="The minimum numeric value that this field can contain.", ) #: The maximum numeric value that this field can contain. max_value = schema.Number( _name="maxValue", _optional=True, _description="The maximum numeric value that this field can contain.", ) #: Specifies the legal number intervals for this field. step = schema.Number( _optional=True, _description="Specifies the legal number intervals for this field.", ) #: A number representing this field's default value. value = schema.Number( _optional=True, _description="A number representing this field's value." )
[docs]class IntegerField(NumberField): """A generic numeric field. """ #: The minimum numeric value that this field can contain. min_value = schema.Integer( _name="minValue", _optional=True, _description="The minimum numeric value that this field can contain.", ) #: The maximum numeric value that this field can contain. max_value = schema.Integer( _name="maxValue", _optional=True, _description="The maximum numeric value that this field can contain.", ) #: Specifies the legal number intervals for this field. step = schema.Integer( _optional=True, _description="Specifies the legal integer intervals for this field.", ) #: A number representing this field's default value. value = schema.Integer( _optional=True, _description="A integer representing this field's value." )
[docs]class PaymentAmountField(IntegerField): """A field representing a payment amount as a multiple of a currency's atomic units. For example, for USD this would represent some number of cents. The currency may be specified as a separate (CurrencyField or StrictCurrencyField) field. """
[docs]class RefundAmountField(PaymentAmountField): """A field representing a refund. See PaymentAmountField. """
[docs]class CouponAmountField(PaymentAmountField): """A field representing a coupon value (usually subtracted from the item's original price). See PaymentAmountField. """
[docs]class CurrencyField(TextField): """A generic field representing some currency in any format. """ AUTOCOMPLETE = "transaction-currency"
[docs]class StrictCurrencyField(ChoiceField): """A choice field representing the set of 3-letter currency codes defined by ISO4217. """
[docs]class PercentageField(NumberField): """A generic field representing a percentage. """ #: A number representing a percentage. value = schema.Number( _optional=True, _minimum=0, _maximum=1, _description="A number representing a percentage.", )
[docs]class TextAreaField(TextField): """A generic text area field. """
[docs]class CommentField(TextAreaField): """A generic comment field. """
[docs]class DayField(TextField): """A text field representing a day of the year. """ #: Day field values are in ``MM-DD`` format. value = schema.Regexp( r"\d{2}-\d{2}$", _optional=True, _description="Day field values are in <code>MM-DD</code> format.", )
[docs]class DateField(TextField): """A text field representing a date. """ #: Date field values are in ``YYYY-MM-DD`` format. value = schema.Regexp( r"\d{4}-\d{2}-\d{2}$", _optional=True, _description="Date field values are in <code>YYYY-MM-DD</code> format.", )
[docs]class DateTimeField(TextField): """A text field representing a date and time. """ # This could match: # 9999-99-99T99:99:99+99:99 #: Date time field values are in ``YYYY-MM-DDTHH:mm:SS+HH:mm`` format. value = schema.Regexp( r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|(\+|-)\d{2}(:?\d{2})?)$", _optional=True, _description="Date time field values are in <code>YYYY-MM-DDTHH:mm:SS+HH:mm</code> format.", )
[docs]class TimezoneOffsetField(TextField): """A text field representing an ISO 8601 timezone offset. """ # This could match +99:99 #: Timezone offset values are in ``±hh:mm``, ``±hhmm``, or ``±hh`` format, or ``Z``. value = schema.Regexp( r"(Z|(\+|-)\d{2}(:?\d{2})?)", _optional=True, _description=( "Timezone offset values are in <code>&plusmn;hh:mm</code>, " "<code>&plusmn;hhmm</code>, or <code>&plusmn;hh</code> " "format, or <code>Z</code>." ), )
[docs]class URIField(TextField): """A generic text field representing a URI. """
[docs]class PathField(TextField): """A generic text field representing the path portion of a URI. """
[docs]class UserAgentField(TextField): """A generic text field representing a user agent. """
[docs]class IPAddressField(TextField): """A generic text field representing an IPv4 or IPv6 address. """ value = schema.Or(schema.IPv4(), schema.IPv6())
[docs]class IPv4AddressField(TextField): """A generic text field representing an IPv4 address. """
[docs]class IPv6AddressField(TextField): """A generic text field representing an IPv6 address. """
[docs]class PasswordField(TextField): """A generic password field. """
[docs]class EmailField(TextField): """A generic e-mail address field. """ AUTOCOMPLETE = "email" # This matches: jane@invaliddomain jane value = schema.Regexp( r".+@.+$", _optional=True, _description="E-mail fields must contain an @ sign." )
[docs]class SalutationField(ChoiceField): """A single choice field representing a user's salutation. """ AUTOCOMPLETE = "honorific-prefix"
[docs]class FullNameField(TextField): """A text field representing a user's full name. """ AUTOCOMPLETE = "name"
[docs]class FirstNameField(TextField): """A text field representing a user's first name. """ AUTOCOMPLETE = "given-name"
[docs]class MiddleNameField(TextField): """A text field representing a user's middle name. """ AUTOCOMPLETE = "additional-name"
[docs]class LastNameField(TextField): """A text field representing a user's last name. """ AUTOCOMPLETE = "family-name"
[docs]class AgeField(NumberField): """A text field representing a user's age. """
[docs]class BirthdayField(DayField): """A text field representing a user's birth _day_. """
[docs]class BirthdateField(DateField): """A text field representing a user's birth _date_. """ AUTOCOMPLETE = "bday"
[docs]class PhoneNumberField(TextField): """A text field representing a user's phone number. """ AUTOCOMPLETE = "tel"
[docs]class HomePhoneNumberField(PhoneNumberField): """A text field representing a user's home phone number. """ AUTOCOMPLETE = "home tel"
[docs]class WorkPhoneNumberField(PhoneNumberField): """A text field representing a user's work phone number. """ AUTOCOMPLETE = "work tel"
[docs]class MobilePhoneNumberField(PhoneNumberField): """A text field representing a user's mobile/cell phone number. """ AUTOCOMPLETE = "mobile tel"
[docs]class FaxNumberField(PhoneNumberField): """A text field representing a user's fax number. """ AUTOCOMPLETE = "fax tel"
[docs]class HomeFaxNumberField(FaxNumberField): """A text field representing a user's home fax number. """ AUTOCOMPLETE = "fax tel"
[docs]class WorkFaxNumberField(FaxNumberField): """A text field representing a user's work fax number. """ AUTOCOMPLETE = "fax tel"
[docs]class CompanyField(TextField): """A text field representing a user's company. """ AUTOCOMPLETE = "organization"
[docs]class JobTitleField(TextField): """A text field representing a user's job title. """ AUTOCOMPLETE = "organization-title"
[docs]class IndustryField(TextField): """A text field representing a user's industry. """
[docs]class NumberOfEmployeesField(NumberField): """A numeric field representing a company's employee count. """
[docs]class AnnualRevenueField(CurrencyField): """A currency field representing a user's annual revenue. """
[docs]class WebsiteField(URIField): """A URI field representing a user's website. """ AUTOCOMPLETE = "url"
[docs]class TagField(TextField): """A text field representing a single tag. """
[docs]class MultiTagField(_BaseField): """A field representing 0 or more tags. """ #: This represents the possible tags for this field's values. values = schema.List(schema.String(), _optional=True) #: This represents the selected tags for this field selected = schema.List(schema.String(), _optional=True)
[docs]class HiddenMultiTagField(MultiTagField): """A hidden field representing 0 or more tags. This should be literally a MultiTagField, but hidden. Differs from a HiddenField, which only has one value, and a MultiTagField by being hidden. """
[docs]class PostalCodeField(TextField): """An integer field representing a zip/postal code. """ AUTOCOMPLETE = "postal-code"
[docs]class AddressStreetField(TextField): """A text field representing the street identifier of a user's address. """ AUTOCOMPLETE = "street-address"
[docs]class AddressCityField(TextField): """A text field representing the city identifier of a user's address. """ AUTOCOMPLETE = "address-level2"
[docs]class AddressStateField(TextField): """A text field representing the state identifier of a user's address. """ AUTOCOMPLETE = "address-level1"
[docs]class AddressStrictStateField(SelectField): """A choice field representing the set of country subdivisions defined by ISO3166-2. """ AUTOCOMPLETE = "address-level1"
[docs]class AddressPostalCodeField(PostalCodeField): """A text field representing the postal code identifier of a user's address. """ AUTOCOMPLETE = "postal-code"
[docs]class AddressCountryField(TextField): """A text field representing the country identifier of a user's address. The values of these fields are free-form text, see :class:`.AddressStrictCountryField` for a more restrictive representation of country fields. """ AUTOCOMPLETE = "country-name"
[docs]class AddressStrictCountryField(SelectField): """A choice field representing the set of countries defined by ISO3166-2. These fields' values must be in ISO3166-2 alpha-2 format. """ AUTOCOMPLETE = "country"
[docs]class BillingAddressStreetField(AddressStreetField): """A text field representing the street identifier of a user's billing address. """ AUTOCOMPLETE = "billing street-address"
[docs]class BillingAddressCityField(AddressCityField): """A text field representing the city identifier of a user's billing address. """ AUTOCOMPLETE = "billing address-level2"
[docs]class BillingAddressStateField(AddressStateField): """A text field representing the state identifier of a user's billing address. """ AUTOCOMPLETE = "billing address-level1"
[docs]class BillingAddressStrictStateField(AddressStrictStateField): """A billing address version of the :class:`.AddressStrictStateField`. """ AUTOCOMPLETE = "billing address-level1"
[docs]class BillingAddressPostalCodeField(AddressPostalCodeField): """A text field representing the postal code identifier of a user's billing address. """ AUTOCOMPLETE = "billing postal-code"
[docs]class BillingAddressCountryField(AddressCountryField): """A text field representing the country identifier of a user's billing address. """ AUTOCOMPLETE = "billing country-name"
[docs]class BillingAddressStrictCountryField(AddressStrictCountryField): """A billing address version of the :class:`.AddressStrictCountryField`. """ AUTOCOMPLETE = "billing country"
[docs]class ShippingAddressStreetField(AddressStreetField): """A text field representing the street identifier of a user's shipping address. """ AUTOCOMPLETE = "shipping street-address"
[docs]class ShippingAddressCityField(AddressCityField): """A text field representing the city identifier of a user's shipping address. """ AUTOCOMPLETE = "shipping address-level2"
[docs]class ShippingAddressStateField(AddressStateField): """A text field representing the state identifier of a user's shipping address. """ AUTOCOMPLETE = "shipping address-level1"
[docs]class ShippingAddressStrictStateField(AddressStrictStateField): """A shipping address version of the :class:`.AddressStrictStateField`. """ AUTOCOMPLETE = "shipping address-level1"
[docs]class ShippingAddressPostalCodeField(AddressPostalCodeField): """A text field representing the postal code identifier of a user's shipping address. """ AUTOCOMPLETE = "shipping postal-code"
[docs]class ShippingAddressCountryField(AddressCountryField): """A text field representing the country identifier of a user's shipping address. """ AUTOCOMPLETE = "shipping country-name"
[docs]class ShippingAddressStrictCountryField(AddressStrictCountryField): """A shipping address version of the :class:`.AddressStrictCountryField`. """ AUTOCOMPLETE = "shipping country"
[docs]class UserHandleField(TextField): """A user's handle or username on a website. """
[docs]class TwitterUserHandleField(UserHandleField): """A user's Twitter handle. """
[docs]class FacebookUserHandleField(UserHandleField): """A user's Facebook username. """
[docs]class LinkedInUserHandleField(UserHandleField): """A user's LinkedIn username. """
[docs]class GooglePlusUserHandleField(UserHandleField): """A user's Google Plus username. """
[docs]class GeographicLatitudeField(NumberField): """A geographic latitude in the WGS84 spatial reference system. """
[docs]class GeographicLongitudeField(NumberField): """A geographic longitude in the WGS84 spatial reference system. """
[docs]class GeographicElevationField(NumberField): """A geographic elevation relative to Mean Sea Level. """
[docs]class ViewportWidthField(IntegerField): """The horizontal number of pixels in a viewport (screen, window, etc.). """
[docs]class ViewportHeightField(IntegerField): """The vertical number of pixels in a viewport (screen, window, etc.). """
[docs]class LocaleField(TextField): """A generic field representing a locale in any format. """ AUTOCOMPLETE = "language"
[docs]class StrictLocaleField(ChoiceField): """A choice field representing the set of language codes as defined by ISO639/BCP47. """
[docs]class RatingField(IntegerField): """A rating on a scale from `min_value` to `max_value`. """
[docs]class LeadScoreField(IntegerField): """A score ranking a lead relative to other leads. """
[docs]class LifetimeValueField(IntegerField): """A field representing a contact's lifetime value as a multiple of a currency's atomic units. For example, for USD this would represent some number of cents. The currency may be specified as a separate (CurrencyField or StrictCurrencyField) field. """
[docs]class DurationMinutesField(IntegerField): """A duration expressed in seconds but which should be displayed as a pair of minute and second inputs. """
[docs]class CenterViewerUUIDField(HiddenField): """The UUID of a viewer (visitor) on a website on which the Center tracking code is installed. """
FIELD_SCHEMAS = {} for name, clazz in list(six.iteritems(locals())): if not inspect.isclass(clazz) or clazz == _BaseField: continue if issubclass(clazz, _BaseField): FIELD_SCHEMAS[name] = clazz()
[docs]class Field(schema.Schema): #: The class name of the exact kind of field, as a string. kind = schema.String( _choices=list(six.iterkeys(FIELD_SCHEMAS)), _description="The field's exact type.", ) #: A map containing the field's properties defined in the field class described by ``kind``. field = schema.Or( *six.itervalues(FIELD_SCHEMAS), _description="The structure of this must match the type described by <code>kind</code>." )
[docs] def materialize(self, sparse=False): """Materialize, setting autocomplete value before returning. Parameters: sparse (bool): Controls whether or not null properties should be included in the result. Returns: dict: The dictionary representation of this instance. (An alternative way to do this might be to make a special kind of Property for `autocomplete`) """ result = super(Field, self).materialize(sparse=sparse) kind = FIELD_SCHEMAS.get(self.kind, None) autocomplete = getattr(kind, "AUTOCOMPLETE", None) if not sparse or autocomplete is not None: result["field"]["autoComplete"] = autocomplete return result