class EventForm(Form): title = StringField(label=_l("Title"), filters=(strip, ), validators=[required()]) start = DateTimeField(_l("Start"), validators=[required()]) end = DateTimeField(_l("End"), validators=[required()]) location = TextAreaField(label=_l("Location"), filters=(strip, )) url = URLField(label=_l("URL"), filters=(strip, )) description = TextAreaField( label=_l("Description"), widget=RichTextWidget(allowed_tags=WIDGET_ALLOWED), filters=(strip, ), validators=[required()]) def validate_description(self, field): field.data = bleach.clean(field.data, tags=ALLOWED_TAGS, attributes=ALLOWED_ATTRIBUTES, styles=ALLOWED_STYLES, strip=True) def validate_end(self, field): if self.start.data > self.end.data: raise ValidationError(_l("End date/time must be after start"))
class BaseUserAdminForm(Form): email = StringField( _l("Email"), description=_l("Users log in with their email address."), view_widget=widgets.EmailWidget(), filters=(strip,), validators=[required()], ) first_name = StringField( _l("First Name"), description=_l("ex: John"), filters=(strip,), validators=[required()], ) last_name = StringField( _l("Last Name"), description=_l("ex: Smith"), filters=(strip,), validators=[required()], ) can_login = BooleanField( _l("Login enabled"), description=_l("If unchecked, user will not be able to connect."), widget=widgets.BooleanWidget(), ) groups = QuerySelect2Field( _l("Groups"), validators=(optional(),), multiple=True, collection_class=set, query_factory=lambda: Group.query.order_by(sa.sql.func.lower(Group.name).asc()), get_label="name", ) roles = Select2MultipleField( _l("Roles"), description=_l( "Prefer groups to manage access rights. Directly assigning roles " "to users is possible but discouraged." ), choices=lambda: [(r.name, r.label) for r in Role.assignable_roles()], ) password = StringField( _l("New Password"), description=_l("If empty the current password will not be changed."), widget=widgets.PasswordInput(autocomplete="off"), )
class GroupForm(Form): name = StringField( _l("Name"), filters=(strip, ), validators=[required(message=_l("Name is required."))], ) description = TextAreaField(_l("Description"))
class GroupAdminForm(Form): name = StringField(_l(u'Name'), filters=(strip,), validators=[required()]) description = StringField(_l(u'Description'), filters=(strip,)) public = BooleanField( _l(u'Public'), widget=widgets.BooleanWidget(on_off_mode=True)) roles = fields.Select2MultipleField( _l(u'Roles'), choices=lambda: [(r.name, r.label) for r in Role.assignable_roles()],)
class AttachmentForm(Form): blob = FileField(_l(u'file'), validators=[required()], filters=[strip], multiple=False) description = StringField(_l(u'description (optional)'), filters=[strip]) class Meta: model = Attachment include_primary_keys = True assign_required = False # for 'id': allow None, for new records
class CommentForm(Form): body = TextAreaField( label=_l(u'Comment'), validators=[required()], filters=(strip, ), widget=TextArea(rows=5, resizeable='vertical'), ) class Meta: model = Comment include_primary_keys = True assign_required = False # for 'id': allow None, for new records
class EditForm(ModelForm): label = StringField(_l(u'Label'), description=_l(u'allowed tags: %(tags)s', tags=', '.join(ALLOWED_TAGS)), filters=(strip, ), validators=[required()]) default = BooleanField(_l(u'Default'), default=False) active = BooleanField(_l(u'Active'), default=True) def validate_label(self, field): field.data = bleach.clean(field.data, tags=ALLOWED_TAGS, attributes=ALLOWED_ATTRIBUTES, strip=True)
def get_validators(self, *args, **kwargs): """Default validators.""" validators = [] if self.required: validators.append(aw_validators.required()) else: validators.append(aw_validators.optional()) if self.validator_length_max != -1 or self.validator_length_min != -1: validators.append( aw_validators.Length( min=self.validator_length_min, max=self.validator_length_max ) ) return validators
class BasePostForm(Form): message = TextAreaField(label=_l("Message"), widget=RichTextWidget(allowed_tags=WIDGET_ALLOWED), filters=(strip, ), validators=[required()]) attachments = FileField(label=_l('Attachments'), multiple=True, validators=[optional()]) def validate_message(self, field): field.data = bleach.clean(field.data, tags=ALLOWED_TAGS, attributes=ALLOWED_ATTRIBUTES, styles=ALLOWED_STYLES, strip=True)
def __filter_validators(self, field): required = self.flags.required if required == field.flags.required: return field.validators validators = [] remove = "optional" if required else "required" has_required = False for v in field.validators: if required and any(f == "required" for f in v.field_flags): has_required = True if any(f == remove for f in v.field_flags): continue validators.append(v) if required and not has_required: validators.append(required()) return validators
class UserPreferencesForm(Form): password = StringField(_l(u'New Password'), widget=widgets.PasswordInput(autocomplete='off')) confirm_password = StringField( _l(u'Confirm new password'), widget=widgets.PasswordInput(autocomplete='off')) photo = fields.FileField(label=_l('Photo'), widget=widgets.ImageInput(width=55, height=55)) locale = fields.LocaleSelectField( label=_l(u'Preferred Language'), validators=(validators.required(), ), default=lambda: get_default_locale(), ) timezone = fields.TimezoneField( label=_l(u'Time zone'), validators=(validators.required(), ), default=babel.dates.LOCALTZ, ) def validate_password(self, field): pwd = field.data confirmed = self['confirm_password'].data if pwd != confirmed: raise ValidationError( _(u'Passwords differ. Ensure you have typed same password in both' u' "password" field and "confirm password" field.')) def validate_photo(self, field): data = request.form.get(field.name) if not data: return data = field.data filename = data.filename valid = any(filename.lower().endswith(ext) for ext in ('.png', '.jpg', '.jpeg')) if not valid: raise ValidationError( _(u'Only PNG or JPG image files are accepted')) img_type = imghdr.what('ignored', data.read()) if img_type not in ('png', 'jpeg'): raise ValidationError( _(u'Only PNG or JPG image files are accepted')) data.seek(0) try: # check this is actually an image file im = PIL.Image.open(data) im.load() except: raise ValidationError(_(u'Could not decode image file')) # convert to jpeg # FIXME: better do this at model level? jpeg = BytesIO() im.convert('RGBA').save(jpeg, 'JPEG') field.data = jpeg.getvalue()
class TagForm(Form): """ Form for a single tag """ label = StringField(u'Label', filters=[strip], validators=[required()])
# all_tags is an InstrumentedSet. add/remove will result in DB operations. all_tags = extension.entity_tags(obj) all_ns_tags = { t for t in extension.entity_tags(obj) if t.ns == self.ns } to_remove = all_ns_tags - self.data for tag in to_remove: all_tags.remove(tag) for tag in self.data: all_tags.add(tag) _NS = StringField(u'Namespace', validators=[required()], filters=[strip]) class TagForm(Form): """ Form for a single tag """ label = StringField(u'Label', filters=[strip], validators=[required()]) class TagNSForm(TagForm): """ Allows to edit namespace. """ ns = _NS
"img": ["src", "alt", "title"], } ALLOWED_STYLES = ["text-align"] WIDGET_ALLOWED = {} for attr in ALLOWED_TAGS: allowed = ALLOWED_ATTRIBUTES.get(attr, True) if not isinstance(allowed, bool): allowed = {tag: True for tag in allowed} WIDGET_ALLOWED[attr] = allowed # instantiate this one before PostForm fields, so that it is listed first # when Threadform is displayed _TITLE_FIELD = StringField( label=_l("Title"), filters=(strip,), validators=[required(), Length(max=150)] ) class BasePostForm(Form): message = TextAreaField( label=_l("Message"), widget=RichTextWidget(allowed_tags=WIDGET_ALLOWED), filters=(strip,), validators=[required()], ) attachments = FileField( label=_l("Attachments"), multiple=True, validators=[optional()] ) def validate_message(self, field):
self.data = data def populate_obj(self, obj, name): extension = current_app.extensions["tags"] # all_tags is an InstrumentedSet. add/remove will result in DB # operations. all_tags = extension.entity_tags(obj) all_ns_tags = {t for t in extension.entity_tags(obj) if t.ns == self.ns} to_remove = all_ns_tags - self.data for tag in to_remove: all_tags.remove(tag) for tag in self.data: all_tags.add(tag) _NS = StringField("Namespace", validators=[required()], filters=[strip]) class TagForm(Form): """Form for a single tag.""" label = StringField("Label", filters=[strip], validators=[required()]) class TagNSForm(TagForm): """Allows to edit namespace.""" ns = _NS
extension = current_app.extensions['tags'] # all_tags is an InstrumentedSet. add/remove will result in DB operations. all_tags = extension.entity_tags(obj) all_ns_tags = {t for t in extension.entity_tags(obj) if t.ns == self.ns} to_remove = all_ns_tags - self.data for tag in to_remove: all_tags.remove(tag) for tag in self.data: all_tags.add(tag) _NS = StringField(u'Namespace', validators=[required()], filters=(strip,),) class TagForm(Form): """ Form for a single tag """ label = StringField(u'Label', filters=(strip,), validators=[required(),]) class TagNSForm(TagForm): """ Allow to edit namespace. """ ns = _NS