-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuser_content.py
131 lines (111 loc) · 3.5 KB
/
user_content.py
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
from abc import ABC
from datetime import datetime
from typing import List
from asyncpg import Record
import postgres
from things import Thing
from util import path
class UserContent(Thing, ABC):
def __init__(
self, author: str, content: str, timestamp: datetime = None, id_=None,
):
self.author, self.content, self._timestamp, self._id = (
author,
content,
timestamp if timestamp is not None else datetime.utcnow(),
id_,
)
@property
def timestamp(self):
return self._timestamp.replace(tzinfo=None)
def serialize(self) -> dict:
return {
"author": self.author,
"timestamp": self.timestamp.timestamp(),
"content": self.content,
}
class Post(UserContent):
def __init__(
self,
author: str,
title: str,
board: str,
content: str = "",
timestamp: datetime = None,
id_=None,
):
super().__init__(author, content, timestamp, id_)
self.title = title
self.board = board
def serialize(self) -> dict:
values = super().serialize()
values.update({"title": self.title, "board": self.board})
return values
@staticmethod
def deserialize(serialized: dict, orig_id: str):
return Post(**serialized, id_=orig_id)
@staticmethod
async def retrieve(id_: str) -> "Post":
record = await postgres.pool.fetchrow("SELECT * FROM posts WHERE id = $1", id_)
return Post(
author=record["author"],
title=record["title"],
board=record["board"],
timestamp=record["timestamp"],
content=record["content"],
id_=record["id"],
)
class Comment(UserContent):
def __init__(
self,
author: str,
content: str,
parent: str,
timestamp: datetime = None,
id_: str = None,
):
super().__init__(author, content, timestamp, id_)
self.parent = parent
@property
def id(self):
if not self._id:
# this call to super().id hashes, and we then assign the internal value
# to avoid that in the future
self._id = "{}.{}".format(self.parent, super().id)
return super().id
def serialize(self) -> dict:
values = super().serialize()
values.update({"parent": self.parent})
return values
@staticmethod
async def children_of(id_: str) -> List["Comment"]:
"""
Returns all direct children of id_
"""
ids = await postgres.pool.fetch(
"SELECT * FROM comments WHERE id ~ $1", id_ + ".*{1}"
)
ret = []
for row in ids:
ret.append(Comment.from_record(row))
return ret
async def children(self) -> List["Comment"]:
return await Comment.children_of(self.id)
@staticmethod
def deserialize(serialized: dict, orig_id: str):
return Comment(**serialized, id_=orig_id)
@staticmethod
def from_record(record) -> "Comment":
return Comment(
author=record["author"],
content=record["content"],
parent=path.parent_of(record["id"]),
timestamp=record["timestamp"],
id_=record["id"],
)
@staticmethod
async def retrieve(id_: str) -> "Comment":
record = await postgres.pool.fetchrow(
"SELECT * FROM comments WHERE id = $1", id_
)
return Comment.from_record(record)