Merge branch 'comments'
[zzz-floof.git] / floof / controllers / comments.py
diff --git a/floof/controllers/comments.py b/floof/controllers/comments.py
new file mode 100644 (file)
index 0000000..b096ba2
--- /dev/null
@@ -0,0 +1,93 @@
+import logging
+
+import elixir
+from pylons import config, request, response, session, tmpl_context as c
+from pylons.controllers.util import abort, redirect, redirect_to
+from sqlalchemy import and_
+
+from floof.lib.base import BaseController, render
+from floof.model.art import Art
+from floof.model.comments import Comment
+
+log = logging.getLogger(__name__)
+
+def find_owner(owner_url):
+    """Returns whatever thing owns a group of comments."""
+
+    # Need to prepend a slash to make this an absolute URL
+    route = config['routes.map'].match('/' + owner_url)
+
+    if route['action'] not in ('show', 'view'):
+        abort(404)
+
+    if route['controller'] == 'art':
+        model = Art
+    else:
+        abort(404)
+
+    owner = model.query.get(route['id'])
+    if not owner:
+        abort(404)
+
+    return owner
+
+
+class CommentsController(BaseController):
+
+    def thread(self, owner_url, id=None):
+        """View a thread of comments, either attached to an item or starting
+        from a parent comment belonging to that item.
+        """
+        owner_object = find_owner(owner_url)
+        c.owner_url = owner_url
+        c.root_comment_id = id
+
+        if id:
+            # Get a thread starting from a certain point
+            c.root_comment = Comment.query.get(id)
+            if c.root_comment.discussion != owner_object.discussion:
+                abort(404)
+
+            c.comments = Comment.query.filter(and_(
+                Comment.discussion_id == owner_object.discussion_id,
+                Comment.left > c.root_comment.left,
+                Comment.right < c.root_comment.right
+            )).all()
+        else:
+            # Get everything
+            c.root_comment = None
+            c.comments = owner_object.discussion.comments
+
+        return render('/comments/thread.mako')
+
+    def reply(self, owner_url, id=None):
+        """Reply to a comment or discussion."""
+
+        c.parent_comment_id = id
+        if id:
+            c.parent_comment = Comment.query.get(id)
+        else:
+            c.parent_comment = None
+
+        return render('/comments/reply.mako')
+
+    def reply_done(self, owner_url, id=None):
+        """Finish replying to a comment or discussion."""
+        # XXX form validation woo
+
+        owner_object = find_owner(owner_url)
+
+        if id:
+            parent_comment = Comment.query.get(id)
+        else:
+            parent_comment = None
+
+        new_comment = Comment(
+            text=request.params['text'],
+            user=c.user,
+            discussion=owner_object.discussion,
+            parent=parent_comment,
+        )
+        elixir.session.commit()
+
+        return redirect('/' + owner_url, code=301)