class UserListForm(Form): user_ids = StripStringField('User IDs', validators=[InputRequired()]) def validate_user_ids(self, field): raw_ids = field.data.split() int_ids = set() for id in raw_ids: try: int_ids.add(int(id)) except TypeError: raise ValidationError('Invalid ID "{}"'.format(id)) q_ids = db.session.query(db.cast(db.func.unnest(field.data.split()), db.Integer).label('id')).subquery() users = User.query.join((q_ids, q_ids.c.id == User.id)).all() new_ids = int_ids - {u.id for u in users} for id in new_ids: #TODO: use api to load multiple users in one request user = User.se_load(id) if user is None: raise ValidationError('Invalid ID "{}"'.format(id)) users.append(user) self.users = users
class WikiPageForm(Form): title = StripStringField(validators=[DataRequired()]) body = TextAreaField() space_re = re.compile(r'\s+') invalid_re = re.compile(r'(^\.{1,2}$|[/_]|%[0-9a-f]{2}|&#?[0-9a-z]+?;)', re.I) def __init__(self, *args, **kwargs): self.obj = kwargs.get('obj') super().__init__(*args, **kwargs) def validate_title(self, field): field.data = title = self.space_re.sub(field.data, ' ').strip() match = self.invalid_re.search(title) if match: raise ValidationError('Invalid characters: "{}"'.format( match.group(1))) existing = WikiPage.query.filter_by(title=title).first() # check existing title when creating new page # skip if existing page is current page when editing if existing is not None and (self.obj is None or self.obj.id != existing.id): raise ValidationError( Markup( '<a href="{}">A page with this title</a> already exists. Rename or delete it before continuing.' .format(existing.detail_url)))
class WikiPageForm(Form): title = StripStringField(validators=[DataRequired()]) body = TextAreaField() space_re = re.compile(r'\s+') invalid_re = re.compile(r'(^\.{1,2}$|[/_]|%[0-9a-f]{2}|&#?[0-9a-z]+?;)', re.I) def __init__(self, *args, **kwargs): self.obj = kwargs.get('obj') super().__init__(*args, **kwargs) def validate_title(self, field): field.data = title = self.space_re.sub(field.data, ' ').strip() match = self.invalid_re.search(title) if match: raise ValidationError('Invalid characters: "{}"'.format( match.group(1))) unique_title_q = db.session.query(db.func.count( WikiPage.id)).filter(WikiPage.title == title) if self.obj is not None: # When editing an existing page, only check *other* pages for duplicate titles. unique_title_q = unique_title_q.filter(WikiPage.id != self.obj.id) if unique_title_q.scalar(): raise ValidationError('A page with this title already exists.')
class CanonItemForm(FlaskForm): title = StripStringField(validators=[InputRequired()]) excerpt = TextAreaField() body = TextAreaField() tags = SeparatedField() question_links = SeparatedField('Questions', pattern=r'[\r\n]+', separator='\n', sort=True, widget=TextArea())
class LoginForm(FlaskForm): user_id = StripStringField('User ID', validators=[InputRequired()]) def validate_user_id(self, field): self.user = User.se_load(field.data)
class CanonSearchForm(BaseForm): q = StripStringField() def __init__(self, formdata=None, *args, **kwargs): if formdata is None: formdata = request.args.copy() super(CanonSearchForm, self).__init__(formdata, *args, **kwargs) @classmethod def query(cls): query = CanonItem.query.order_by(CanonItem.title) if not has_group('editor'): query = query.filter(db.not_(CanonItem.draft)) return query def apply(self, query=None): self.validate() query = query if query is not None else self.query() if not self.q.data: return query tags = [] terms = [] for token in self.q.data.split(): if token.startswith('[') and token.endswith(']'): tags.append(token[1:-1]) elif token.startswith('is:'): flag = token[3:] if flag == 'draft': query = query.filter(CanonItem.draft) elif flag == 'community': query = query.filter(CanonItem.community) else: terms.append(token) if tags: tag_q = db.session.query( db.func.unnest(tags).label('name')).subquery() tag_count = db.session.query( CanonItem.id, db.func.count( CanonItem.id).label('tags')).join(CanonItem._tags).filter( Tag.name.in_(tag_q)).group_by(CanonItem.id).subquery() query = query.join( (tag_count, tag_count.c.id == CanonItem.id)).filter( tag_count.c.tags >= len(tags)) if terms: tsvector = db.func.to_tsvector( 'english', (CanonItem.title + ' ' + CanonItem.excerpt + ' ' + CanonItem.body)) tsquery = ' & '.join(terms) query = query.filter( tsvector.match(tsquery, postgresql_regconfig='english')) return query
class SaladForm(Form): term = StripStringField(validators=[InputRequired()]) definition = StripStringField(validators=[InputRequired()])