Browse Source

Added ability to create and remove categories.
Renamed the templates for adding and creating users, groups and forums to a more appropriate name.

sh4nks 11 years ago
parent
commit
183ba9ff42

+ 33 - 31
flaskbb/admin/forms.py

@@ -19,7 +19,7 @@ from wtforms.ext.sqlalchemy.fields import (QuerySelectField,
 
 from flaskbb.utils.widgets import SelectDateWidget
 from flaskbb.extensions import db
-from flaskbb.forum.models import Forum
+from flaskbb.forum.models import Forum, Category
 from flaskbb.user.models import User, Group
 
 USERNAME_RE = r'^[\w.+-]+$'
@@ -28,7 +28,11 @@ is_username = regexp(USERNAME_RE,
 
 
 def selectable_forums():
-    return Forum.query.order_by(Forum.id)
+    return Forum.query.order_by(Forum.position)
+
+
+def selectable_categories():
+    return Category.query.order_by(Category.position)
 
 
 def select_primary_group():
@@ -215,48 +219,34 @@ class AddGroupForm(GroupForm):
 
 
 class ForumForm(Form):
-    _id = None
     _moderators = set()
 
     title = TextField("Forum Title", validators=[
         Required(message="Forum title required")])
 
     description = TextAreaField("Description", validators=[
-        Optional()])
+        Optional()],
+        description="You can format your description with BBCode.")
 
     position = IntegerField("Position", default=1, validators=[
         Required(message="Forum position required")])
 
-    parent = QuerySelectField("Parent",
-                              query_factory=selectable_forums,
-                              allow_blank=True,
-                              get_label="title",
-                              description="This field is not saved if this \
-                                           forum is a category (see \"Is a \
-                                           category?\" field below).")
+    category = QuerySelectField(
+        "Category",
+        query_factory=selectable_categories,
+        allow_blank=False,
+        get_label="title",
+        description="The category that contains this forum."
+    )
 
     moderators = TextField("Moderators",
                            description="Comma seperated usernames. Leave it \
                                         blank if you do not want to set any \
                                         moderators.")
 
-    is_category = BooleanField("Is a category?",
-                               description="Categories are root-level parents \
-                                            for forums. They can not contain \
-                                            topics.")
-
     locked = BooleanField("Locked?", description="Disable new posts and topics \
                                                   in this forum.")
 
-    def validate_parent(self, field):
-        if hasattr(field.data, "id"):
-            if field.data.id == self._id:
-                raise ValidationError("A forum cannot be it's own parent!")
-        else:
-            if not self.is_category.data:
-                raise ValidationError("Please choose a parent or is it a \
-                                      category?")
-
     def validate_moderators(self, field):
         if field.data:
             # Check if the usernames exist
@@ -274,7 +264,7 @@ class ForumForm(Form):
                     raise ValidationError("User not found")
             field.data = self._moderators
 
-    def save(self, category_id=None):
+    def save(self):
         forum = Forum(title=self.title.data,
                       description=self.description.data,
                       position=self.position.data)
@@ -282,10 +272,22 @@ class ForumForm(Form):
         if self.moderators.data and not self.is_category.data:
             forum.moderators = self.moderators.data
 
-        if self.is_category.data:
-            forum.is_category = True
-            forum.parent_id = None
-        else:
-            forum.parent_id = self.parent.data.id
+        forum.category_id = self.category.data.id
 
         return forum.save()
+
+
+class CategoryForm(Form):
+    title = TextField("Category title", validators=[
+        Required(message="Category title required")])
+
+    description = TextAreaField("Description", validators=[
+        Optional()],
+        description="You can format your description with BBCode.")
+
+    position = IntegerField("Position", default=1, validators=[
+        Required(message="Category position required")])
+
+    def save(self):
+        category = Category(**self.data)
+        return category.save()

+ 53 - 20
flaskbb/admin/views.py

@@ -19,7 +19,7 @@ from flaskbb.extensions import db
 from flaskbb.user.models import User, Group
 from flaskbb.forum.models import Post, Topic, Forum, Category
 from flaskbb.admin.forms import (AddUserForm, EditUserForm, AddGroupForm,
-                                 EditGroupForm, ForumForm)
+                                 EditGroupForm, ForumForm, CategoryForm)
 
 
 admin = Blueprint("admin", __name__)
@@ -115,7 +115,8 @@ def edit_user(user_id):
         form.primary_group.data = user.primary_group
         form.secondary_groups.data = user.secondary_groups
 
-    return render_template("admin/edit_user.html", form=form)
+    return render_template("admin/user_form.html", form=form,
+                           title="Edit User")
 
 
 @admin.route("/users/<int:user_id>/delete")
@@ -136,7 +137,8 @@ def add_user():
         flash("User successfully added.", "success")
         return redirect(url_for("admin.users"))
 
-    return render_template("admin/edit_user.html", form=form)
+    return render_template("admin/user_form.html", form=form,
+                           title="Add User")
 
 
 @admin.route("/groups/<int:group_id>/edit", methods=["GET", "POST"])
@@ -165,7 +167,8 @@ def edit_group(group_id):
         form.posttopic.data = group.posttopic
         form.postreply.data = group.postreply
 
-    return render_template("admin/edit_group.html", form=form)
+    return render_template("admin/group_form.html", form=form,
+                           title="Edit Group")
 
 
 @admin.route("/groups/<int:group_id>/delete")
@@ -186,7 +189,8 @@ def add_group():
         flash("Group successfully added.", "success")
         return redirect(url_for("admin.groups"))
 
-    return render_template("admin/edit_group.html", form=form)
+    return render_template("admin/group_form.html", form=form,
+                           title="Add Group")
 
 
 @admin.route("/forums/<int:forum_id>/edit", methods=["GET", "POST"])
@@ -201,17 +205,12 @@ def edit_forum(forum_id):
         forum.title = form.title.data
         forum.description = form.description.data
         forum.position = form.position.data
-        forum.is_category = form.is_category.data
         forum.locked = form.locked.data
+        forum.category_id = form.category.data.id
 
         if form.moderators.data:
             forum.moderators = form.moderators.data
 
-        if hasattr(form.parent.data, 'id'):
-            forum.parent_id = form.parent.data.id
-        else:
-            forum.parent_id = form.parent.data
-
         forum.save()
 
         flash("Forum successfully edited.", "success")
@@ -220,8 +219,7 @@ def edit_forum(forum_id):
         form.title.data = forum.title
         form.description.data = forum.description
         form.position.data = forum.position
-        form.parent.data = forum.parent
-        form.is_category.data = forum.is_category
+        form.category.data = forum.category
         form.locked.data = forum.locked
 
         if forum.moderators:
@@ -230,7 +228,8 @@ def edit_forum(forum_id):
         else:
             form.moderators.data = None
 
-    return render_template("admin/edit_forum.html", form=form)
+    return render_template("admin/forum_form.html", form=form,
+                           title="Edit Forum")
 
 
 @admin.route("/forums/<int:forum_id>/delete")
@@ -248,29 +247,63 @@ def delete_forum(forum_id):
 
 
 @admin.route("/forums/add", methods=["GET", "POST"])
-@admin.route("/forums/<int:category_id>/add")
+@admin.route("/forums/<int:category_id>/add", methods=["GET", "POST"])
 @admin_required
 def add_forum(category_id=None):
     form = ForumForm()
 
     if form.validate_on_submit():
-        form.save(category_id)
+        form.save()
         flash("Forum successfully added.", "success")
         return redirect(url_for("admin.forums"))
+    else:
+        if category_id:
+            category = Category.query.filter_by(id=category_id).first()
+            form.category.data = category
 
-    return render_template("admin/edit_forum.html", form=form)
+    return render_template("admin/forum_form.html", form=form,
+                           title="Add Forum")
 
 
 @admin.route("/category/add", methods=["GET", "POST"])
 def add_category():
-    pass
+    form = CategoryForm()
+
+    if form.validate_on_submit():
+        form.save()
+        flash("Category successfully created.", "success")
+        return redirect(url_for("admin.forums"))
+
+    return render_template("admin/category_form.html", form=form,
+                           title="Add Category")
 
 
 @admin.route("/category/<int:category_id>/edit", methods=["GET", "POST"])
 def edit_category(category_id):
-    pass
+    category = Category.query.filter_by(id=category_id).first_or_404()
+
+    form = CategoryForm()
+
+    if form.validate_on_submit():
+        form.populate_obj(category)
+        category.save()
+    else:
+        form.title.data = category.title
+        form.description.data = category.description
+        form.position.data = category.position
+
+    return render_template("admin/category_form.html", form=form,
+                           title="Edit Category")
 
 
 @admin.route("/category/<int:category_id>/delete", methods=["GET", "POST"])
 def delete_category(category_id):
-    pass
+    category = Category.query.filter_by(id=category_id).first_or_404()
+
+    involved_users = User.query.filter(Forum.category_id == category.id,
+                                       Topic.forum_id == Forum.id,
+                                       Post.user_id == User.id).all()
+
+    category.delete(involved_users)
+    flash("Category with all associated forums deleted.", "success")
+    return redirect(url_for("admin.forums"))

+ 16 - 14
flaskbb/forum/models.py

@@ -382,18 +382,10 @@ class Forum(db.Model):
         db.session.commit()
 
         # Update the users post count
-        # Need to import it from here, because otherwise it would be
-        # a circular import
-        from flaskbb.user.models import User
-
-        users = User.query.\
-            filter(Topic.forum_id == self.id,
-                   Post.topic_id == Topic.id).\
-            all()
-
-        for user in users:
-            user.post_count = Post.query.filter_by(user_id=user.id).count()
-            db.session.commit()
+        if users:
+            for user in users:
+                user.post_count = Post.query.filter_by(user_id=user.id).count()
+                db.session.commit()
 
         return self
 
@@ -418,13 +410,23 @@ class Category(db.Model):
         db.session.commit()
         return self
 
-    def delete(self):
-        """Deletes a category"""
+    def delete(self, users=None):
+        """Deletes a category. If a list with involved user objects is passed,
+        it will also update their post counts
+
+        :param users: A list with user objects
+        """
 
         # Delete all the forums in the category
         for forum in self.forums:
             forum.delete()
 
+        # Update the users post count
+        if users:
+            for user in users:
+                user.post_count = Post.query.filter_by(user_id=user.id).count()
+                db.session.commit()
+
         # and finally delete the category itself
         db.session.delete(self)
         db.session.commit()

+ 23 - 0
flaskbb/templates/admin/category_form.html

@@ -0,0 +1,23 @@
+{% set page_title = title %}
+{% set active_forum_nav=True %}
+
+{% extends "admin/admin_layout.html" %}
+{% block admin_content %}
+{% from "macros.html" import horizontal_field, render_boolean_field %}
+
+<form class="form-horizontal" role="form" method="post">
+    {{ form.hidden_tag() }}
+    <legend class="">{{ title }}</legend>
+        {{ horizontal_field(form.title) }}
+        {{ horizontal_field(form.description, rows=5, div_class="col-lg-9") }}
+
+        {{ horizontal_field(form.position) }}
+
+        <div class="form-group">
+            <div class="col-lg-offset-0 col-lg-9">
+                <button type="submit" class="btn btn-success">Save</button>
+            </div>
+        </div>
+</form>
+
+{% endblock %}

+ 3 - 4
flaskbb/templates/admin/edit_forum.html → flaskbb/templates/admin/forum_form.html

@@ -1,4 +1,4 @@
-{% set page_title = "Edit Forum" %}
+{% set page_title = title %}
 {% set active_forum_nav=True %}
 
 {% extends "admin/admin_layout.html" %}
@@ -7,16 +7,15 @@
 
 <form class="form-horizontal" role="form" method="post">
     {{ form.hidden_tag() }}
-    <legend class="">Edit Forum</legend>
+    <legend class="">{{ title }}</legend>
         {{ horizontal_field(form.title) }}
         {{ horizontal_field(form.description, rows=5, div_class="col-lg-9") }}
 
-        {{ horizontal_field(form.parent) }}
+        {{ horizontal_field(form.category) }}
         {{ horizontal_field(form.position) }}
 
         {{ horizontal_field(form.moderators) }}
 
-        {{ render_boolean_field(form.is_category) }}
         {{ render_boolean_field(form.locked) }}
 
         <div class="form-group">

+ 1 - 1
flaskbb/templates/admin/forums.html

@@ -12,7 +12,7 @@
                 <div><strong><a href="{{ url_for('forum.view_category', category_id=category.id) }}">{{ category.title }}</a></strong></div>
             </td>
             <td valign="top" align="center" style="white-space: nowrap">
-                <a href="{{ url_for('admin.add_forum', category_id = category.id) }}">Add Forum</a> |
+                <a href="{{ url_for('admin.add_forum', category_id=category.id) }}">Add Forum</a> |
                 <a href="{{ url_for('admin.edit_category', category_id = category.id) }}">Edit</a> |
                 <a href="{{ url_for('admin.delete_category', category_id = category.id) }}">Delete</a>
             </td>

+ 2 - 2
flaskbb/templates/admin/edit_group.html → flaskbb/templates/admin/group_form.html

@@ -1,4 +1,4 @@
-{% set page_title = "Edit Group" %}
+{% set page_title = title %}
 {% set active_forum_nav=True %}
 
 {% extends "admin/admin_layout.html" %}
@@ -7,7 +7,7 @@
 
 <form class="form-horizontal" role="form" method="post">
     {{ form.hidden_tag() }}
-    <legend class="">Edit Group</legend>
+    <legend class="">{{ title }}</legend>
         {{ horizontal_field(form.name) }}
         {{ horizontal_field(form.description) }}
 

+ 2 - 2
flaskbb/templates/admin/edit_user.html → flaskbb/templates/admin/user_form.html

@@ -1,4 +1,4 @@
-{% set page_title = "Edit User" %}
+{% set page_title = title %}
 {% set active_forum_nav=True %}
 
 {% extends "admin/admin_layout.html" %}
@@ -7,7 +7,7 @@
 
 <form class="form-horizontal" role="form" method="post">
     {{ form.hidden_tag() }}
-    <legend class="">Edit User</legend>
+    <legend class="">{{ title }}</legend>
         {{ horizontal_field(form.username) }}
         {{ horizontal_field(form.email) }}
         {{ horizontal_field(form.password) }}