8
|
1 local Luan = require "luan:Luan.luan"
|
|
2 local error = Luan.error
|
9
|
3 local ipairs = Luan.ipairs or error()
|
8
|
4 local set_metatable = Luan.set_metatable or error()
|
|
5 local Time = require "luan:Time.luan"
|
|
6 local time_now = Time.now or error()
|
9
|
7 local Html = require "luan:Html.luan"
|
|
8 local html_encode = Html.encode or error()
|
42
|
9 local Number = require "luan:Number.luan"
|
|
10 local long = Number.long or error()
|
8
|
11 local Db = require "site:/lib/Db.luan"
|
|
12
|
|
13
|
|
14 local Post = {}
|
|
15
|
18
|
16 local times = {
|
|
17 {
|
|
18 time = 1000*60*60*24*365
|
|
19 unit = "year"
|
|
20 }
|
|
21 {
|
|
22 time = 1000*60*60*24*7
|
|
23 unit = "week"
|
|
24 }
|
|
25 {
|
|
26 time = 1000*60*60*24
|
|
27 unit = "day"
|
|
28 }
|
|
29 {
|
|
30 time = 1000*60*60
|
|
31 unit = "hour"
|
|
32 }
|
|
33 {
|
|
34 time = 1000*60
|
|
35 unit = "minute"
|
|
36 }
|
|
37 }
|
|
38
|
8
|
39 local function from_doc(doc)
|
|
40 doc.type == "post" or error "wrong type"
|
|
41 return Post.new {
|
|
42 id = doc.id
|
|
43 content = doc.content
|
|
44 date = doc.date
|
|
45 author_name = doc.post_author_name
|
9
|
46 root_id = doc.post_root_id
|
42
|
47 is_root = doc.post_is_root == "true"
|
9
|
48
|
|
49 -- root only
|
|
50 subject = doc.subject
|
8
|
51 }
|
|
52 end
|
|
53
|
|
54 local function to_doc(post)
|
|
55 return {
|
|
56 type = "post"
|
|
57 id = post.id
|
|
58 content = post.content or error()
|
42
|
59 date = long(post.date)
|
8
|
60 post_author_name = post.author_name or error()
|
42
|
61 post_root_id = long(post.root_id)
|
|
62 post_is_root = post.is_root and "true" or nil
|
9
|
63
|
|
64 -- root only
|
|
65 subject = post.subject
|
8
|
66 }
|
|
67 end
|
|
68
|
|
69 local metatable = {}
|
|
70 function metatable.__index(post,key)
|
|
71 if key == "author" then
|
|
72 local User = require "site:/lib/User.luan"
|
10
|
73 return User.get_by_name(post.author_name)
|
8
|
74 end
|
9
|
75 if key == "subject_html" then
|
|
76 return post.subject and html_encode(post.subject)
|
|
77 end
|
|
78 if key == "root" then
|
|
79 return post.is_root and post or Post.get_by_id(post.root_id)
|
|
80 end
|
8
|
81 return nil
|
|
82 end
|
|
83
|
|
84 function Post.new(post)
|
42
|
85 post.date = post.date or time_now()
|
8
|
86
|
|
87 function post.save()
|
|
88 local doc = to_doc(post)
|
|
89 Db.save(doc)
|
|
90 post.id = doc.id
|
|
91 end
|
|
92
|
42
|
93 function post.delete()
|
|
94 Db.run_in_transaction( function()
|
|
95 not post.is_root or Post.thread_size(post.root_id) == 1 or error "can't delete root post with replies"
|
|
96 Db.delete("id:"..post.id)
|
9
|
97 end )
|
|
98 end
|
|
99
|
16
|
100 function post.author_is_current()
|
|
101 local User = require "site:/lib/User.luan"
|
|
102 local user = User.current()
|
|
103 return user ~= nil and user.name == post.author_name
|
|
104 end
|
|
105
|
18
|
106 function post.ago(now)
|
|
107 local diff = now - post.date
|
|
108 for _, t in ipairs(times) do
|
|
109 local n = diff // t.time
|
|
110 if n > 0 then
|
|
111 %><%=n%> <%=t.unit%><%
|
|
112 if n > 1 then
|
|
113 %>s<%
|
|
114 end
|
|
115 return
|
|
116 end
|
|
117 end
|
|
118 %>0 minutes<%
|
|
119 end
|
|
120
|
8
|
121 set_metatable(post,metatable)
|
|
122 return post
|
|
123 end
|
|
124
|
|
125 function Post.get_by_id(id)
|
|
126 local doc = Db.get_document("id:"..id)
|
9
|
127 return doc and from_doc(doc)
|
8
|
128 end
|
|
129
|
|
130 function Post.new_thread(author,subject,content)
|
|
131 return Db.run_in_transaction( function()
|
|
132 local post = Post.new{
|
9
|
133 subject = subject or error()
|
8
|
134 content = content
|
|
135 author_name = author.name
|
|
136 is_root = true
|
|
137 }
|
|
138 post.save()
|
|
139 post.root_id = post.id or error()
|
|
140 post.save()
|
|
141 return post
|
|
142 end )
|
|
143 end
|
|
144
|
9
|
145 function Post.from_docs(docs)
|
|
146 local posts = {}
|
|
147 for _, doc in ipairs(docs) do
|
|
148 local post = from_doc(doc)
|
|
149 posts[#posts+1] = post
|
|
150 end
|
|
151 return posts
|
|
152 end
|
|
153
|
42
|
154 function Post.thread_size(root_id)
|
|
155 return Db.count("post_root_id:"..root_id)
|
|
156 end
|
|
157
|
8
|
158 return Post
|