summaryrefslogtreecommitdiff
path: root/sphinx/websupport/comments/__init__.py
blob: 395bde5802536435259441717c7596c797b0cff6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
from datetime import datetime

from sqlalchemy.orm import sessionmaker

from sphinx.websupport.comments.db import Base, Node, Comment, Vote

Session = sessionmaker()

class CommentBackend(object):
    def pre_build(self):
        pass

    def add_node(self, document, line, source, treeloc):
        raise NotImplemented
    
    def post_build(self):
        pass

    def add_comment(self, parent_id, text, displayed, username, 
                    rating, time):
        raise NotImplemented

    def get_comments(self, parent_id):
        raise NotImplemented


class SQLAlchemyComments(CommentBackend):
    def __init__(self, engine):
        self.engine = engine
        Base.metadata.bind = engine
        Base.metadata.create_all()
        Session.configure(bind=engine)
        self.session = Session()

    def pre_build(self):
        self.current_pk = None

    def add_node(self, document, line, source, treeloc):
        node = Node(document, line, source, treeloc)
        self.session.add(node)
        if self.current_pk is None:
            self.session.commit()
            self.current_pk = node.id
        else:
            self.current_pk += 1
        return self.current_pk

    def post_build(self):
        self.session.commit()

    def add_comment(self, parent_id, text, displayed, 
                    username, rating, time):
        time = time or datetime.now()

        id = parent_id[1:]
        if parent_id[0] == 's':
            node = self.session.query(Node).filter(Node.id == id).first()
            comment = Comment(text, displayed, username, rating, 
                              time, node=node)
        elif parent_id[0] == 'c':
            parent = self.session.query(Comment).filter(Comment.id == id).first()
            comment = Comment(text, displayed, username, rating, 
                              time, parent=parent)
            
        self.session.add(comment)
        self.session.commit()
        return self.serializable(comment)
        
    def get_comments(self, parent_id, user_id):
        parent_id = parent_id[1:]
        node = self.session.query(Node).filter(Node.id == parent_id).first()
        comments = []
        for comment in node.comments:
            comments.append(self.serializable(comment, user_id))

        return comments

    def process_vote(self, comment_id, user_id, value):
        vote = self.session.query(Vote).filter(
            Vote.comment_id == comment_id).filter(
            Vote.user_id == user_id).first()
        
        comment = self.session.query(Comment).filter(
            Comment.id == comment_id).first()

        if vote is None:
            vote = Vote(comment_id, user_id, value)
            comment.rating += value
        else:
            comment.rating += value - vote.value
            vote.value = value
        self.session.add(vote)
        self.session.commit()

    def serializable(self, comment, user_id=None):
        delta = datetime.now() - comment.time

        time = {'year': comment.time.year,
                'month': comment.time.month,
                'day': comment.time.day,
                'hour': comment.time.hour,
                'minute': comment.time.minute,
                'second': comment.time.second,
                'iso': comment.time.isoformat(),
                'delta': self.pretty_delta(delta)}

        vote = ''
        if user_id is not None:
            vote = self.session.query(Vote).filter(
                Vote.comment_id == comment.id).filter(
                Vote.user_id == user_id).first()
            if vote is not None:
                vote = vote.value 

        return {'text': comment.text,
                'username': comment.username or 'Anonymous',
                'id': comment.id,
                'rating': comment.rating,
                'age': delta.seconds,
                'time': time,
                'vote': vote or 0,
                'node': comment.node.id if comment.node else None,
                'parent': comment.parent.id if comment.parent else None,
                'children': [self.serializable(child, user_id) 
                             for child in comment.children]}

    def pretty_delta(self, delta):
        days = delta.days
        seconds = delta.seconds
        hours = seconds / 3600
        minutes = seconds / 60

        if days == 0:
            dt = (minutes, 'minute') if hours == 0 else (hours, 'hour')
        else:
            dt = (days, 'day')

        return '%s %s ago' % dt if dt[0] == 1 else '%s %ss ago' % dt