123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405 |
- # -*- coding: utf-8 -*-
- """
- flaskbb.management.forms
- ~~~~~~~~~~~~~~~~~~~~~~~~
- It provides the forms that are needed for the management views.
- :copyright: (c) 2014 by the FlaskBB Team.
- :license: BSD, see LICENSE for more details.
- """
- from flask_wtf import Form
- from wtforms import (StringField, TextAreaField, PasswordField, IntegerField,
- BooleanField, SelectField, SubmitField)
- from wtforms.validators import (DataRequired, Optional, Email, regexp, Length,
- URL, ValidationError)
- from wtforms.ext.sqlalchemy.fields import (QuerySelectField,
- QuerySelectMultipleField)
- from flask_babelex import lazy_gettext as _
- from flaskbb.utils.fields import BirthdayField
- from flaskbb.utils.widgets import SelectBirthdayWidget
- from flaskbb.extensions import db
- from flaskbb.forum.models import Forum, Category
- from flaskbb.user.models import User, Group
- USERNAME_RE = r'^[\w.+-]+$'
- is_username = regexp(USERNAME_RE,
- message=_("You can only use letters, numbers or dashes."))
- def selectable_forums():
- return Forum.query.order_by(Forum.position)
- def selectable_categories():
- return Category.query.order_by(Category.position)
- def select_primary_group():
- return Group.query.filter(Group.guest != True).order_by(Group.id)
- class UserForm(Form):
- username = StringField(_("Username"), validators=[
- DataRequired(message=_("A Username is required.")),
- is_username])
- email = StringField(_("E-Mail Address"), validators=[
- DataRequired(message=_("A E-Mail Address is required.")),
- Email(message=_("Invalid E-Mail Address."))])
- password = PasswordField("Password", validators=[
- Optional()])
- birthday = BirthdayField(_("Birthday"), format="%d %m %Y",
- widget=SelectBirthdayWidget(),
- validators=[Optional()])
- gender = SelectField(_("Gender"), default="None", choices=[
- ("None", ""),
- ("Male", _("Male")),
- ("Female", _("Female"))])
- location = StringField(_("Location"), validators=[
- Optional()])
- website = StringField(_("Website"), validators=[
- Optional(), URL()])
- avatar = StringField(_("Avatar"), validators=[
- Optional(), URL()])
- signature = TextAreaField(_("Forum Signature"), validators=[
- Optional(), Length(min=0, max=250)])
- notes = TextAreaField(_("Notes"), validators=[
- Optional(), Length(min=0, max=5000)])
- primary_group = QuerySelectField(
- _("Primary Group"),
- query_factory=select_primary_group,
- get_label="name")
- secondary_groups = QuerySelectMultipleField(
- _("Secondary Groups"),
- # TODO: Template rendering errors "NoneType is not callable"
- # without this, figure out why.
- query_factory=select_primary_group,
- get_label="name")
- submit = SubmitField(_("Save"))
- def validate_username(self, field):
- if hasattr(self, "user"):
- user = User.query.filter(
- db.and_(
- User.username.like(field.data),
- db.not_(User.id == self.user.id)
- )
- ).first()
- else:
- user = User.query.filter(User.username.like(field.data)).first()
- if user:
- raise ValidationError(_("This Username is already taken."))
- def validate_email(self, field):
- if hasattr(self, "user"):
- user = User.query.filter(
- db.and_(
- User.email.like(field.data),
- db.not_(User.id == self.user.id)
- )
- ).first()
- else:
- user = User.query.filter(User.email.like(field.data)).first()
- if user:
- raise ValidationError(_("This E-Mail Address is already taken."))
- def save(self):
- user = User(**self.data)
- return user.save()
- class AddUserForm(UserForm):
- pass
- class EditUserForm(UserForm):
- def __init__(self, user, *args, **kwargs):
- self.user = user
- kwargs['obj'] = self.user
- UserForm.__init__(self, *args, **kwargs)
- class GroupForm(Form):
- name = StringField(_("Group Name"), validators=[
- DataRequired(message=_("A Group name is required."))])
- description = TextAreaField(_("Description"), validators=[
- Optional()])
- admin = BooleanField(
- _("Is Admin Group?"),
- description=_("With this option the group has access to "
- "the admin panel.")
- )
- super_mod = BooleanField(
- _("Is Super Moderator Group?"),
- description=_("Check this if the users in this group are allowed to "
- "moderate every forum.")
- )
- mod = BooleanField(
- _("Is Moderator Group?"),
- description=_("Check this if the users in this group are allowed to "
- "moderate specified forums.")
- )
- banned = BooleanField(
- _("Is Banned Group?"),
- description=_("Only one Banned group is allowed.")
- )
- guest = BooleanField(
- _("Is Guest Group?"),
- description=_("Only one Guest group is allowed.")
- )
- editpost = BooleanField(
- _("Can edit posts"),
- description=_("Check this if the users in this group can edit posts.")
- )
- deletepost = BooleanField(
- _("Can delete posts"),
- description=_("Check this is the users in this group can delete posts.")
- )
- deletetopic = BooleanField(
- _("Can delete topics"),
- description=_("Check this is the users in this group can delete "
- "topics.")
- )
- posttopic = BooleanField(
- _("Can create topics"),
- description=_("Check this is the users in this group can create "
- "topics.")
- )
- postreply = BooleanField(
- _("Can post replies"),
- description=_("Check this is the users in this group can post replies.")
- )
- mod_edituser = BooleanField(
- _("Moderators can edit user profiles"),
- description=_("Allow moderators to edit a another users profile "
- "including password and email changes.")
- )
- mod_banuser = BooleanField(
- _("Moderators can ban users"),
- description=_("Allow moderators to ban other users.")
- )
- submit = SubmitField(_("Save"))
- def validate_name(self, field):
- if hasattr(self, "group"):
- group = Group.query.filter(
- db.and_(
- Group.name.like(field.data),
- db.not_(Group.id == self.group.id)
- )
- ).first()
- else:
- group = Group.query.filter(Group.name.like(field.data)).first()
- if group:
- raise ValidationError(_("This Group name is already taken."))
- def validate_banned(self, field):
- if hasattr(self, "group"):
- group = Group.query.filter(
- db.and_(
- Group.banned,
- db.not_(Group.id == self.group.id)
- )
- ).count()
- else:
- group = Group.query.filter_by(banned=True).count()
- if field.data and group > 0:
- raise ValidationError(_("There is already a Banned group."))
- def validate_guest(self, field):
- if hasattr(self, "group"):
- group = Group.query.filter(
- db.and_(
- Group.guest,
- db.not_(Group.id == self.group.id)
- )
- ).count()
- else:
- group = Group.query.filter_by(guest=True).count()
- if field.data and group > 0:
- raise ValidationError(_("There is already a Guest group."))
- def save(self):
- group = Group(**self.data)
- return group.save()
- class EditGroupForm(GroupForm):
- def __init__(self, group, *args, **kwargs):
- self.group = group
- kwargs['obj'] = self.group
- GroupForm.__init__(self, *args, **kwargs)
- class AddGroupForm(GroupForm):
- pass
- class ForumForm(Form):
- title = StringField(
- _("Forum Title"),
- validators=[DataRequired(message=_("A Forum Title is required."))]
- )
- description = TextAreaField(
- _("Description"),
- validators=[Optional()],
- description=_("You can format your description with BBCode.")
- )
- position = IntegerField(
- _("Position"),
- default=1,
- validators=[DataRequired(message=_("The Forum Position is required."))]
- )
- category = QuerySelectField(
- _("Category"),
- query_factory=selectable_categories,
- allow_blank=False,
- get_label="title",
- description=_("The category that contains this forum.")
- )
- external = StringField(
- _("External Link"),
- validators=[Optional(), URL()],
- description=_("A link to a website i.e. 'http://flaskbb.org'.")
- )
- moderators = StringField(
- _("Moderators"),
- description=_("Comma seperated usernames. Leave it blank if you do not "
- "want to set any moderators.")
- )
- show_moderators = BooleanField(
- _("Show Moderators"),
- description=_("Do you want show the moderators on the index page?")
- )
- locked = BooleanField(
- _("Locked?"),
- description=_("Disable new posts and topics in this forum.")
- )
- submit = SubmitField(_("Save"))
- def validate_external(self, field):
- if hasattr(self, "forum"):
- if self.forum.topics:
- raise ValidationError(_("You cannot convert a forum that "
- "contain topics in a external link."))
- def validate_show_moderators(self, field):
- if field.data and not self.moderators.data:
- raise ValidationError(_("You also need to specify some "
- "moderators."))
- def validate_moderators(self, field):
- approved_moderators = list()
- if field.data:
- # convert the CSV string in a list
- moderators = field.data.split(",")
- # remove leading and ending spaces
- moderators = [mod.strip() for mod in moderators]
- for moderator in moderators:
- # Check if the usernames exist
- user = User.query.filter_by(username=moderator).first()
- # Check if the user has the permissions to moderate a forum
- if user:
- if not (user.get_permissions()["mod"] or
- user.get_permissions()["admin"] or
- user.get_permissions()["super_mod"]):
- raise ValidationError(
- _("%(user)s is not in a moderators group.",
- user=user.username)
- )
- else:
- approved_moderators.append(user)
- else:
- raise ValidationError(_("User %(moderator)s not found.",
- moderator=moderator))
- field.data = approved_moderators
- else:
- field.data = approved_moderators
- def save(self):
- forum = Forum(title=self.title.data,
- description=self.description.data,
- position=self.position.data,
- external=self.external.data,
- show_moderators=self.show_moderators.data,
- locked=self.locked.data)
- if self.moderators.data:
- # is already validated
- forum.moderators = self.moderators.data
- forum.category_id = self.category.data.id
- return forum.save()
- class EditForumForm(ForumForm):
- def __init__(self, forum, *args, **kwargs):
- self.forum = forum
- kwargs['obj'] = self.forum
- ForumForm.__init__(self, *args, **kwargs)
- class AddForumForm(ForumForm):
- pass
- class CategoryForm(Form):
- title = StringField(_("Category Title"), validators=[
- DataRequired(message=_("A Category Title is required."))])
- description = TextAreaField(
- _("Description"),
- validators=[Optional()],
- description=_("You can format your description with BBCode.")
- )
- position = IntegerField(
- _("Position"),
- default=1,
- validators=[DataRequired(message=_("The Category Position is "
- "required."))]
- )
- submit = SubmitField(_("Save"))
- def save(self):
- data = self.data
- # remove the button
- data.pop('submit', None)
- category = Category(**data)
- return category.save()
|