added ugly proposals

This commit is contained in:
Jacob Mason 2010-07-27 16:12:35 -05:00
parent 3a32d12bf8
commit c23e26833a
4 changed files with 95 additions and 26 deletions

View File

@ -10,7 +10,10 @@
"""
import cPickle as pickle
import re
from os import path
from cgi import escape
from difflib import Differ
from datetime import datetime
from jinja2 import Environment, FileSystemLoader
@ -203,17 +206,16 @@ class WebSupport(object):
:param rating: the starting rating of the comment, defaults to 0.
:param time: the time the comment was created, defaults to now.
"""
return self.storage.add_comment(parent_id, text, displayed,
username, rating, time, proposal)
id = parent_id[1:]
is_node = parent_id[0] == 's'
node = self.storage.get_node(id) if is_node else None
parent = self.storage.get_comment(id) if not is_node else None
diff = get_diff_html(node.source, proposal) if proposal else None
return self.storage.add_comment(text, displayed, username, rating,
time, proposal, diff, node, parent)
def get_proposals(self, node_id, user_id=None):
return self.storage.get_proposals(node_id, user_id)
def add_proposal(self, parent_id, text, displayed=True, username=None,
rating=0, time=None):
return self.storage.add_proposal(parent_id, text, displayed,
username, rating, time)
def process_vote(self, comment_id, user_id, value):
"""Process a user's vote. The web support package relies
on the API user to perform authentication. The API user will
@ -240,3 +242,55 @@ class WebSupport(object):
"""
value = int(value)
self.storage.process_vote(comment_id, user_id, value)
highlight_regex = re.compile(r'([\+\-\^]+)')
def highlight_text(text, next, tag):
next = next[2:]
new_text = []
start = 0
for match in highlight_regex.finditer(next):
new_text.append(text[start:match.start()])
new_text.append('<%s>' % tag)
new_text.append(text[match.start():match.end()])
new_text.append('</%s>' % tag)
start = match.end()
new_text.append(text[start:])
return ''.join(new_text)
def get_diff_html(source, proposal):
proposal = escape(proposal)
def handle_line(line, next=None):
prefix = line[0]
text = line[2:]
if prefix == ' ':
return text
elif prefix == '?':
return ''
if next[0] == '?':
tag = 'ins' if prefix == '+' else 'del'
text = highlight_text(text, next, tag)
css_class = 'prop_added' if prefix == '+' else 'prop_removed'
return '<span class="%s">%s</span>\n' % (css_class, text.rstrip())
differ = Differ()
diff = list(differ.compare(source.splitlines(1), proposal.splitlines(1)))
html = []
line = diff.pop(0)
next = diff.pop(0)
while True:
html.append(handle_line(line, next))
line = next
try:
next = diff.pop(0)
except IndexError:
handle_line(line)
break
return ''.join(html)

View File

@ -19,6 +19,9 @@ class StorageBackend(object):
"""
raise NotImplementedError()
def get_node(self, node_id):
raise NotImplementedError()
def post_build(self):
"""Called after a build has completed. Use this to finalize the
addition of nodes if needed.
@ -26,11 +29,14 @@ class StorageBackend(object):
pass
def add_comment(self, parent_id, text, displayed,
username, rating, time, proposal):
username, rating, time, proposal, proposal_diff):
"""Called when a comment is being added."""
raise NotImplementedError()
def get_comments(self, parent_id):
def get_comment(self, comment_id):
raise NotImplementedError()
def get_comments(self, parent_id, user_id):
"""Called to retrieve all comments for a node."""
raise NotImplementedError()

View File

@ -38,6 +38,7 @@ class Comment(Base):
displayed = Column(Boolean, index=True, default=False)
username = Column(String(64))
proposal = Column(Text)
proposal_diff = Column(Text)
node_id = Column(Integer, ForeignKey(db_prefix + 'nodes.id'))
node = relation(Node, backref='comments')
@ -46,7 +47,7 @@ class Comment(Base):
parent = relation('Comment', backref='children', remote_side=[id])
def __init__(self, text, displayed, username, rating, time,
proposal, node=None, parent=None):
proposal, proposal_diff, node, parent):
self.text = text
self.displayed = displayed
self.username = username
@ -55,6 +56,7 @@ class Comment(Base):
self.node = node
self.parent = parent
self.proposal = proposal
self.proposal_diff = proposal_diff
def serializable(self, user_id=None):
delta = datetime.now() - self.time
@ -86,6 +88,7 @@ class Comment(Base):
'vote': vote or 0,
'node': self.node.id if self.node else None,
'parent': self.parent.id if self.parent else None,
'proposal_diff': self.proposal_diff,
'children': [child.serializable(user_id)
for child in self.children]}

View File

@ -19,32 +19,39 @@ class SQLAlchemyStorage(StorageBackend):
self.build_session.flush()
return node.id
def get_node(self, node_id):
session = Session()
node = session.query(Node).filter(Node.id == node_id).first()
session.close()
return node
def post_build(self):
self.build_session.commit()
self.build_session.close()
def add_comment(self, parent_id, text, displayed,
username, rating, time, proposal):
def add_comment(self, text, displayed, username, rating, time,
proposal, proposal_diff, node=None, parent=None):
time = time or datetime.now()
session = Session()
id = parent_id[1:]
if parent_id[0] == 's':
node = session.query(Node).filter(Node.id == id).first()
comment = Comment(text, displayed, username, rating,
time, proposal, node=node)
elif parent_id[0] == 'c':
parent = session.query(Comment).filter(Comment.id == id).first()
comment = Comment(text, displayed, username, rating,
time,proposal, parent=parent)
comment = Comment(text, displayed, username, rating, time,
proposal, proposal_diff, node, parent)
session.add(comment)
session.commit()
comment = comment.serializable()
session.close()
return comment
def get_comment(self, comment_id):
session = Session()
comment = session.query(Comment) \
.filter(Comment.id == comment_id).first()
session.close()
return comment
def get_comments(self, parent_id, user_id):
parent_id = parent_id[1:]
session = Session()
@ -73,4 +80,3 @@ class SQLAlchemyStorage(StorageBackend):
session.add(vote)
session.commit()
session.close()