From bfbbbe5851c71706f79d823696648f96ff88af40 Mon Sep 17 00:00:00 2001 From: Jacob Mason Date: Fri, 6 Aug 2010 15:07:59 -0500 Subject: [PATCH] moved _serializable_list into db.py --- sphinx/builders/websupport.py | 3 +- sphinx/websupport/storage/db.py | 53 +++++++++++++++++-- .../websupport/storage/sqlalchemystorage.py | 48 +---------------- 3 files changed, 51 insertions(+), 53 deletions(-) diff --git a/sphinx/builders/websupport.py b/sphinx/builders/websupport.py index eeadfc231..095bd5556 100644 --- a/sphinx/builders/websupport.py +++ b/sphinx/builders/websupport.py @@ -30,11 +30,10 @@ class WebSupportBuilder(StandaloneHTMLBuilder): self.translator_class = WebSupportTranslator def write_doc(self, docname, doctree): - # The translator needs the docname to generate ids. - self.cur_docname = docname destination = StringOutput(encoding='utf-8') doctree.settings = self.docsettings + self.cur_docname = docname self.secnumbers = self.env.toc_secnumbers.get(docname, {}) self.imgpath = '/' + posixpath.join(self.app.staticdir, '_images') self.post_process_images(doctree) diff --git a/sphinx/websupport/storage/db.py b/sphinx/websupport/storage/db.py index 23b6a462c..568558a3d 100644 --- a/sphinx/websupport/storage/db.py +++ b/sphinx/websupport/storage/db.py @@ -16,7 +16,7 @@ from sqlalchemy import Column, Integer, Text, String, Boolean, ForeignKey,\ DateTime from sqlalchemy.schema import UniqueConstraint from sqlalchemy.ext.declarative import declarative_base -from sqlalchemy.orm import relation, sessionmaker +from sqlalchemy.orm import relation, sessionmaker, aliased Base = declarative_base() @@ -33,6 +33,54 @@ class Node(Base): line = Column(Integer) source = Column(Text, nullable=False) + def nested_comments(self, username, moderator): + session = Session() + + if username: + # If a username is provided, create a subquery to retrieve all + # votes by this user. We will outerjoin with the comment query + # with this subquery so we have a user's voting information. + sq = session.query(CommentVote).\ + filter(CommentVote.username == username).subquery() + cvalias = aliased(CommentVote, sq) + q = session.query(Comment, cvalias.value).outerjoin(cvalias) + else: + q = session.query(Comment) + + # Filter out all comments not descending from this node. + q = q.filter(Comment.path.like(str(self.id) + '.%')) + # Filter out non-displayed comments if this isn't a moderator. + if not moderator: + q = q.filter(Comment.displayed == True) + # Retrieve all results. Results must be ordered by Comment.path + # so that we can easily transform them from a flat list to a tree. + results = q.order_by(Comment.path).all() + session.close() + + # We now need to convert the flat list of results to a nested + # lists to form the comment tree. Results will by ordered by + # the materialized path. + return self._nest_comments(results, username) + + def _nest_comments(self, results, username): + comments = [] + list_stack = [comments] + for r in results: + comment, vote = r if username else (r, 0) + + inheritance_chain = comment.path.split('.')[1:] + + if len(inheritance_chain) == len(list_stack) + 1: + parent = list_stack[-1][-1] + list_stack.append(parent['children']) + elif len(inheritance_chain) < len(list_stack): + while len(inheritance_chain) < len(list_stack): + list_stack.pop() + + list_stack[-1].append(comment.serializable(vote=vote)) + + return comments + def __init__(self, document, line, source, treeloc): self.document = document self.line = line @@ -52,9 +100,6 @@ class Comment(Base): proposal_diff = Column(Text) path = Column(String(256), index=True) - #node_id = Column(Integer, ForeignKey(db_prefix + 'nodes.id')) - #node = relation(Node, backref='comments') - def __init__(self, text, displayed, username, rating, time, proposal, proposal_diff): self.text = text diff --git a/sphinx/websupport/storage/sqlalchemystorage.py b/sphinx/websupport/storage/sqlalchemystorage.py index e96f38cf0..02fa33b50 100644 --- a/sphinx/websupport/storage/sqlalchemystorage.py +++ b/sphinx/websupport/storage/sqlalchemystorage.py @@ -11,7 +11,6 @@ from datetime import datetime -from sqlalchemy.orm import aliased from sphinx.websupport.errors import * from sphinx.websupport.storage import StorageBackend from sphinx.websupport.storage.db import Base, Node, Comment, CommentVote,\ @@ -83,55 +82,10 @@ class SQLAlchemyStorage(StorageBackend): session = Session() node = session.query(Node).filter(Node.id == node_id).one() session.close() - comments = self._serializable_list(node_id, username, moderator) + comments = node.nested_comments(username, moderator) return {'source': node.source, 'comments': comments} - def _serializable_list(self, node_id, username, moderator): - session = Session() - - if username: - # If a username is provided, create a subquery to retrieve all - # votes by this user. We will outerjoin with the comment query - # with this subquery so we have a user's voting information. - sq = session.query(CommentVote).\ - filter(CommentVote.username == username).subquery() - cvalias = aliased(CommentVote, sq) - q = session.query(Comment, cvalias.value).outerjoin(cvalias) - else: - q = session.query(Comment) - - # Filter out all comments not descending from this node. - q = q.filter(Comment.path.like(str(node_id) + '.%')) - # Filter out non-displayed comments if this isn't a moderator. - if not moderator: - q = q.filter(Comment.displayed == True) - # Retrieve all results. Results must be ordered by Comment.path - # so that we can easily transform them from a flat list to a tree. - results = q.order_by(Comment.path).all() - session.close() - - # We now need to convert the flat list of results to a nested - # lists to form the comment tree. Results will by ordered by - # the materialized path. - comments = [] - list_stack = [comments] - for r in results: - comment, vote = r if username else (r, 0) - - inheritance_chain = comment.path.split('.')[1:] - - if len(inheritance_chain) == len(list_stack) + 1: - parent = list_stack[-1][-1] - list_stack.append(parent['children']) - elif len(inheritance_chain) < len(list_stack): - while len(inheritance_chain) < len(list_stack): - list_stack.pop() - - list_stack[-1].append(comment.serializable(vote=vote)) - - return comments - def process_vote(self, comment_id, username, value): session = Session() vote = session.query(CommentVote).filter(