class VoteForm(FlaskForm): VOTE_VALUE_CHOICES = { 1: "Definitely yes!", 0: "I'm impartial.", -1: "Definitely not.", } action = StringField() value = RadioField( choices=list(VOTE_VALUE_CHOICES.items()), coerce=int, validators=[OptionalValidator()], ) comment = TextAreaField(validators=[OptionalValidator()]) def validate(self) -> bool: """Validate that a value is provided if the actions is vote.""" if not super().validate(): return False if self.action.data not in ("skip", "vote"): self.action.errors.append("Action must be vote or skip.") return False if self.action.data == "vote" and self.value.data is None: self.value.errors.append("Please cast a vote.") return False if self.action.data == "vote" and not self.comment.data: self.comment.errors.append("Please add a comment.") return False return True
class DemographicSurveyForm(FlaskForm): gender = SelectMultipleOrOtherField(choices=enum_choices(Gender)) ethnicity = SelectMultipleOrOtherField(choices=enum_choices(Ethnicity)) past_speaking = SelectMultipleOrOtherField( choices=enum_choices(PastSpeaking)) age_group = RadioField("age_group", choices=enum_choices(AgeGroup), validators=[OptionalValidator()]) programming_experience = RadioField( "programming_experience", choices=enum_choices(ProgrammingExperience), validators=[OptionalValidator()], ) def __init__(self, obj: DemographicSurvey): # make a fake obj to pass in that adapts the enum values to their # names which the select fields are more happy to work with data = dict((col.name, getattr(obj, col.name, None)) for col in obj.__table__.columns) if data["age_group"]: data["age_group"] = data["age_group"].name if data["programming_experience"]: data["programming_experience"] = data[ "programming_experience"].name # unfortunately, the obj must be a thing that supports attribute # access, so use a bunch (see https://github.com/dsc/bunch) super().__init__(obj=Bunch(data)) def populate_obj(self, obj: DemographicSurvey) -> None: # all sorts of weird hackery because I can't figure out how to make # wtforms work well with enums right now, and the CFP start date # is looming. see https://gitlab.com/bigapplepy/yak-bak/issues/22 def clean_list(values: Optional[List[str]]) -> Optional[List[str]]: if values: values = [v for v in values if v] return values or None obj.gender = clean_list(self.gender.data) obj.ethnicity = clean_list(self.ethnicity.data) obj.past_speaking = clean_list(self.past_speaking.data) if self.age_group.data: if self.age_group.data == "None": obj.age_group = None else: obj.age_group = AgeGroup[self.age_group.data] if self.programming_experience.data: if self.programming_experience.data == "None": obj.programming_experience = None else: obj.programming_experience = ProgrammingExperience[ self.programming_experience.data]
def add_reference_systems(form: Any, form_name: str) -> None: precisions = [('', '')] for id_ in Node.get_hierarchy('External reference match').subs: precisions.append((str(g.nodes[id_].id), g.nodes[id_].name)) for system in g.reference_systems.values(): if form_name not in [ form_['name'] for form_ in system.get_forms().values() ]: continue setattr( form, 'reference_system_id_{id}'.format(id=system.id), StringField(system.name, validators=[OptionalValidator()], description=system.description, render_kw={ 'autocomplete': 'off', 'placeholder': system.placeholder })) setattr( form, 'reference_system_precision_{id}'.format(id=system.id), SelectField(_('precision'), choices=precisions, default=system.precision_default_id))
def add_reference_systems(form: Any, class_: str) -> None: precisions = [('', '')] + [ (str(g.types[id_].id), g.types[id_].name) for id_ in Type.get_hierarchy('External reference match').subs ] systems = list(g.reference_systems.values()) systems.sort(key=lambda x: x.name.casefold()) for system in systems: if class_ not in system.classes: continue setattr( form, f'reference_system_id_{system.id}', StringField(uc_first(system.name), [OptionalValidator()], description=system.description, render_kw={ 'autocomplete': 'off', 'placeholder': system.placeholder })) setattr( form, f'reference_system_precision_{system.id}', SelectField(_('precision'), choices=precisions, default=system.precision_default_id))
def add_fields(form: Any, class_: str, code: Union[str, None], item: Union[Entity, Node, Link, None], origin: Union[Entity, Node, None]) -> None: if class_ == 'actor_actor_relation': setattr(form, 'inverse', BooleanField(_('inverse'))) if not item: setattr(form, 'actor', TableMultiField(_('actor'), [InputRequired()])) setattr(form, 'relation_origin_id', HiddenField()) elif class_ in ['activity', 'acquisition', 'move']: setattr(form, 'event_id', HiddenField()) setattr(form, 'event', TableField(_('sub event of'))) if class_ == 'activity': setattr(form, 'place', TableField(_('location'))) if class_ == 'acquisition': setattr(form, 'place', TableField(_('location'))) setattr(form, 'given_place', TableMultiField(_('given place'))) elif class_ == 'move': setattr(form, 'place_from', TableField(_('from'))) setattr(form, 'place_to', TableField(_('to'))) setattr(form, 'artifact', TableMultiField()) setattr(form, 'person', TableMultiField()) elif class_ == 'file' and not item: setattr(form, 'file', FileField(_('file'), [InputRequired()])) elif class_ == 'group': setattr(form, 'residence', TableField(_('residence'))) setattr(form, 'begins_in', TableField(_('begins in'))) setattr(form, 'ends_in', TableField(_('ends in'))) elif class_ == 'hierarchy': if code == 'custom' or (item and not item.value_type): setattr( form, 'multiple', BooleanField(_('multiple'), description=_('tooltip hierarchy multiple'))) setattr( form, 'forms', SelectMultipleField(_('classes'), render_kw={'disabled': True}, description=_('tooltip hierarchy forms'), choices=[], option_widget=widgets.CheckboxInput(), widget=widgets.ListWidget(prefix_label=False), coerce=int)) elif class_ == 'involvement': if not item and origin: involved_with = 'actor' if origin.class_.view == 'event' else 'event' setattr(form, involved_with, TableMultiField(_(involved_with), [InputRequired()])) setattr(form, 'activity', SelectField(_('activity'))) elif class_ == 'member' and not item: setattr(form, 'member_origin_id', HiddenField()) setattr(form, 'actor' if code == 'member' else 'group', TableMultiField(_('actor'), [InputRequired()])) elif class_ in g.classes and g.classes[class_].view == 'type': setattr(form, 'is_node_form', HiddenField()) node = item if item else origin root = g.nodes[node.root[-1]] if node.root else node setattr(form, str(root.id), TreeField(str(root.id))) if root.directional: setattr(form, 'name_inverse', StringField(_('inverse'))) elif class_ == 'person': setattr(form, 'residence', TableField(_('residence'))) setattr(form, 'begins_in', TableField(_('born in'))) setattr(form, 'ends_in', TableField(_('died in'))) elif class_ == 'reference_system': setattr( form, 'website_url', StringField(_('website URL'), validators=[OptionalValidator(), URL()])) setattr( form, 'resolver_url', StringField(_('resolver URL'), validators=[OptionalValidator(), URL()])) setattr(form, 'placeholder', StringField(_('example ID'))) precision_node_id = str( Node.get_hierarchy('External reference match').id) setattr(form, precision_node_id, TreeField(precision_node_id)) choices = ReferenceSystem.get_form_choices(item) if choices: setattr( form, 'forms', SelectMultipleField( _('forms'), render_kw={'disabled': True}, choices=choices, option_widget=widgets.CheckboxInput(), widget=widgets.ListWidget(prefix_label=False), coerce=int)) elif class_ == 'source': setattr(form, 'artifact', TableMultiField())
def add_value_type_fields(form: Any, subs: List[int]) -> None: for sub_id in subs: sub = g.nodes[sub_id] setattr(form, str(sub.id), ValueFloatField(sub.name, [OptionalValidator()])) add_value_type_fields(form, sub.subs)
def add_date_fields(form: Any) -> None: validator_day = [OptionalValidator(), NumberRange(min=1, max=31)] validator_month = [OptionalValidator(), NumberRange(min=1, max=12)] validator_year = [ OptionalValidator(), NumberRange(min=-4713, max=9999), NoneOf([0]) ] setattr( form, 'begin_year_from', IntegerField(render_kw={'placeholder': _('YYYY')}, validators=validator_year)) setattr( form, 'begin_month_from', IntegerField(render_kw={'placeholder': _('MM')}, validators=validator_month)) setattr( form, 'begin_day_from', IntegerField(render_kw={'placeholder': _('DD')}, validators=validator_day)) setattr( form, 'begin_year_to', IntegerField(render_kw={'placeholder': _('YYYY')}, validators=validator_year)) setattr( form, 'begin_month_to', IntegerField(render_kw={'placeholder': _('MM')}, validators=validator_month)) setattr( form, 'begin_day_to', IntegerField(render_kw={'placeholder': _('DD')}, validators=validator_day)) setattr(form, 'begin_comment', StringField(render_kw={'placeholder': _('comment')})) setattr( form, 'end_year_from', IntegerField(render_kw={'placeholder': _('YYYY')}, validators=validator_year)) setattr( form, 'end_month_from', IntegerField(render_kw={'placeholder': _('MM')}, validators=validator_month)) setattr( form, 'end_day_from', IntegerField(render_kw={'placeholder': _('DD')}, validators=validator_day)) setattr( form, 'end_year_to', IntegerField(render_kw={'placeholder': _('YYYY')}, validators=validator_year)) setattr( form, 'end_month_to', IntegerField(render_kw={'placeholder': _('MM')}, validators=validator_month)) setattr( form, 'end_day_to', IntegerField(render_kw={'placeholder': _('DD')}, validators=validator_day)) setattr(form, 'end_comment', StringField(render_kw={'placeholder': _('comment')}))
def add_fields(form: Any, class_: str, code: Union[str, None], entity: Union[Entity, Link, ReferenceSystem, Type, None], origin: Union[Entity, Type, None]) -> None: if class_ == 'actor_actor_relation': setattr(form, 'inverse', BooleanField(_('inverse'))) if not entity: setattr(form, 'actor', TableMultiField(_('actor'), [InputRequired()])) setattr(form, 'relation_origin_id', HiddenField()) elif class_ == 'artifact': setattr(form, 'actor', TableField(_('owned by'))) elif class_ in view_class_mapping['event']: setattr(form, 'event_id', HiddenField()) setattr(form, 'event', TableField(_('sub event of'))) setattr(form, 'event_preceding', TableField(_('preceding event'))) if class_ in ['activity', 'acquisition', 'production']: setattr(form, 'place', TableField(_('location'))) if class_ == 'acquisition': setattr(form, 'given_place', TableMultiField(_('given place'))) elif class_ == 'move': setattr(form, 'place_from', TableField(_('from'))) setattr(form, 'place_to', TableField(_('to'))) setattr(form, 'artifact', TableMultiField()) setattr(form, 'person', TableMultiField()) elif class_ == 'production': setattr(form, 'artifact', TableMultiField()) elif class_ == 'file' and not entity: setattr(form, 'file', MultipleFileField(_('file'), [InputRequired()])) if origin and origin.class_.view == 'reference': setattr(form, 'page', StringField()) elif class_ == 'group': setattr(form, 'residence', TableField(_('residence'))) setattr(form, 'begins_in', TableField(_('begins in'))) setattr(form, 'ends_in', TableField(_('ends in'))) elif class_ == 'hierarchy': if code == 'custom' or (entity and isinstance(entity, Type) and entity.category != 'value'): setattr( form, 'multiple', BooleanField(_('multiple'), description=_('tooltip hierarchy multiple'))) setattr( form, 'classes', SelectMultipleField(_('classes'), render_kw={'disabled': True}, description=_('tooltip hierarchy forms'), choices=[], option_widget=widgets.CheckboxInput(), widget=widgets.ListWidget(prefix_label=False))) elif class_ == 'involvement': if not entity and origin: involved_with = 'actor' \ if origin.class_.view == 'event' else 'event' setattr(form, involved_with, TableMultiField(_(involved_with), [InputRequired()])) setattr(form, 'activity', SelectField(_('activity'))) elif class_ == 'actor_function' and not entity: setattr(form, 'member_origin_id', HiddenField()) setattr(form, 'actor' if code == 'member' else 'group', TableMultiField(_('actor'), [InputRequired()])) elif class_ in g.view_class_mapping['type']: setattr(form, 'is_type_form', HiddenField()) type_ = entity if entity else origin if isinstance(type_, Type): root = g.types[type_.root[0]] if type_.root else type_ setattr(form, str(root.id), TreeField(str(root.id))) if root.directional: setattr(form, 'name_inverse', StringField(_('inverse'))) elif class_ == 'person': setattr(form, 'residence', TableField(_('residence'))) setattr(form, 'begins_in', TableField(_('born in'))) setattr(form, 'ends_in', TableField(_('died in'))) elif class_ == 'reference_system': setattr(form, 'website_url', StringField(_('website URL'), [OptionalValidator(), URL()])) setattr(form, 'resolver_url', StringField(_('resolver URL'), [OptionalValidator(), URL()])) setattr(form, 'placeholder', StringField(_('example ID'))) precision_id = str(Type.get_hierarchy('External reference match').id) setattr(form, precision_id, TreeField(precision_id)) if choices := ReferenceSystem.get_class_choices( entity): # type: ignore setattr( form, 'classes', SelectMultipleField( _('classes'), render_kw={'disabled': True}, choices=choices, option_widget=widgets.CheckboxInput(), widget=widgets.ListWidget(prefix_label=False)))