Implements replyingTo in the backend.
This commit is contained in:
parent
c4df36d461
commit
e34501a61a
2 changed files with 44 additions and 12 deletions
52
forum.nim
52
forum.nim
|
|
@ -888,10 +888,12 @@ proc selectUser(userRow: seq[string], avatarSize: int=80): User =
|
||||||
rank: parseEnum[Rank](userRow[3])
|
rank: parseEnum[Rank](userRow[3])
|
||||||
)
|
)
|
||||||
|
|
||||||
proc selectPost(postRow: seq[string], skippedPosts: seq[int]): Post =
|
proc selectPost(postRow: seq[string], skippedPosts: seq[int],
|
||||||
|
replyingTo: Option[PostLink]): Post =
|
||||||
return Post(
|
return Post(
|
||||||
id: postRow[0].parseInt,
|
id: postRow[0].parseInt,
|
||||||
author: selectUser(@[postRow[4], postRow[5], postRow[6], postRow[7]]),
|
replyingTo: replyingTo,
|
||||||
|
author: selectUser(@[postRow[5], postRow[6], postRow[7], postRow[8]]),
|
||||||
likes: @[], # TODO:
|
likes: @[], # TODO:
|
||||||
seen: false, # TODO:
|
seen: false, # TODO:
|
||||||
history: @[], # TODO:
|
history: @[], # TODO:
|
||||||
|
|
@ -902,6 +904,28 @@ proc selectPost(postRow: seq[string], skippedPosts: seq[int]): Post =
|
||||||
moreBefore: skippedPosts
|
moreBefore: skippedPosts
|
||||||
)
|
)
|
||||||
|
|
||||||
|
proc selectReplyingTo(replyingTo: string): Option[PostLink] =
|
||||||
|
if replyingTo.len == 0: return
|
||||||
|
|
||||||
|
const replyingToQuery = sql"""
|
||||||
|
select p.id, strftime('%s', p.creation), p.thread,
|
||||||
|
u.name, u.email, strftime('%s', u.lastOnline), u.status,
|
||||||
|
t.name
|
||||||
|
from post p, person u, thread t
|
||||||
|
where p.thread = t.id and p.author = u.id and p.id = ? and p.isDeleted = 0;
|
||||||
|
"""
|
||||||
|
|
||||||
|
let row = getRow(db, replyingToQuery, replyingTo)
|
||||||
|
if row[0].len == 0: return
|
||||||
|
|
||||||
|
return some(PostLink(
|
||||||
|
creation: row[1].parseInt(),
|
||||||
|
topic: row[^1],
|
||||||
|
threadId: row[2].parseInt(),
|
||||||
|
postId: row[0].parseInt(),
|
||||||
|
author: some(selectUser(@[row[3], row[4], row[5], row[6]]))
|
||||||
|
))
|
||||||
|
|
||||||
proc selectThread(threadRow: seq[string]): Thread =
|
proc selectThread(threadRow: seq[string]): Thread =
|
||||||
const postsQuery =
|
const postsQuery =
|
||||||
sql"""select count(*), strftime('%s', creation) from post
|
sql"""select count(*), strftime('%s', creation) from post
|
||||||
|
|
@ -950,23 +974,23 @@ proc selectThread(threadRow: seq[string]): Thread =
|
||||||
return thread
|
return thread
|
||||||
|
|
||||||
proc executeReply(c: TForumData, threadId: int, content: string,
|
proc executeReply(c: TForumData, threadId: int, content: string,
|
||||||
replyingTo: int): int64 =
|
replyingTo: Option[int]): int64 =
|
||||||
# TODO: Refactor TForumData.
|
# TODO: Refactor TForumData.
|
||||||
assert c.loggedIn()
|
assert c.loggedIn()
|
||||||
|
|
||||||
let subject = "" # TODO: Remove this redundant field.
|
|
||||||
if rateLimitCheck(c):
|
if rateLimitCheck(c):
|
||||||
raise newForumError("You're posting too fast!")
|
raise newForumError("You're posting too fast!")
|
||||||
|
|
||||||
if not validateRst(c, content):
|
if not validateRst(c, content):
|
||||||
raise newForumError("Message needs to be valid RST", @["msg"])
|
raise newForumError("Message needs to be valid RST", @["msg"])
|
||||||
|
|
||||||
# TODO: Replying to.
|
|
||||||
# Verify that content can be parsed as RST.
|
# Verify that content can be parsed as RST.
|
||||||
let retID = insertID(
|
let retID = insertID(
|
||||||
db,
|
db,
|
||||||
crud(crCreate, "post", "author", "ip", "content", "thread"),
|
crud(crCreate, "post", "author", "ip", "content", "thread", "replyingTo"),
|
||||||
c.userId, c.req.ip, content, $threadId, ""
|
c.userId, c.req.ip, content, $threadId,
|
||||||
|
if replyingTo.isSome(): $replyingTo.get()
|
||||||
|
else: nil
|
||||||
)
|
)
|
||||||
discard tryExec(
|
discard tryExec(
|
||||||
db,
|
db,
|
||||||
|
|
@ -1043,7 +1067,7 @@ proc executeNewThread(c: TForumData, subject, msg: string): (int64, int64) =
|
||||||
|
|
||||||
discard tryExec(db, crud(crCreate, "thread_fts", "id", "name"),
|
discard tryExec(db, crud(crCreate, "thread_fts", "id", "name"),
|
||||||
c.threadID, subject)
|
c.threadID, subject)
|
||||||
result[1] = executeReply(c, result[0].int, msg, -1)
|
result[1] = executeReply(c, result[0].int, msg, none[int]())
|
||||||
discard tryExec(db, sql"insert into post_fts(post_fts) values('optimize')")
|
discard tryExec(db, sql"insert into post_fts(post_fts) values('optimize')")
|
||||||
discard tryExec(db, sql"insert into post_fts(thread_fts) values('optimize')")
|
discard tryExec(db, sql"insert into post_fts(thread_fts) values('optimize')")
|
||||||
|
|
||||||
|
|
@ -1180,6 +1204,7 @@ routes:
|
||||||
let postsQuery =
|
let postsQuery =
|
||||||
sql(
|
sql(
|
||||||
"""select p.id, p.content, strftime('%s', p.creation), p.author,
|
"""select p.id, p.content, strftime('%s', p.creation), p.author,
|
||||||
|
p.replyingTo,
|
||||||
u.name, u.email, strftime('%s', u.lastOnline), u.status
|
u.name, u.email, strftime('%s', u.lastOnline), u.status
|
||||||
from post p, person u
|
from post p, person u
|
||||||
where u.id = p.author and p.thread = ? and p.isDeleted = 0
|
where u.id = p.author and p.thread = ? and p.isDeleted = 0
|
||||||
|
|
@ -1200,7 +1225,8 @@ routes:
|
||||||
let addDetail = i < count or rows.len-i < count or id == anchor
|
let addDetail = i < count or rows.len-i < count or id == anchor
|
||||||
|
|
||||||
if addDetail:
|
if addDetail:
|
||||||
let post = selectPost(rows[i], skippedPosts)
|
let replyingTo = selectReplyingTo(rows[i][4])
|
||||||
|
let post = selectPost(rows[i], skippedPosts, replyingTo)
|
||||||
list.posts.add(post)
|
list.posts.add(post)
|
||||||
skippedPosts = @[]
|
skippedPosts = @[]
|
||||||
else:
|
else:
|
||||||
|
|
@ -1217,6 +1243,7 @@ routes:
|
||||||
let intIDs = ids.elems.map(x => x.getInt())
|
let intIDs = ids.elems.map(x => x.getInt())
|
||||||
let postsQuery = sql("""
|
let postsQuery = sql("""
|
||||||
select p.id, p.content, strftime('%s', p.creation), p.author,
|
select p.id, p.content, strftime('%s', p.creation), p.author,
|
||||||
|
p.replyingTo,
|
||||||
u.name, u.email, strftime('%s', u.lastOnline), u.status
|
u.name, u.email, strftime('%s', u.lastOnline), u.status
|
||||||
from post p, person u
|
from post p, person u
|
||||||
where u.id = p.author and p.id in ($#)
|
where u.id = p.author and p.id in ($#)
|
||||||
|
|
@ -1226,7 +1253,7 @@ routes:
|
||||||
var list: seq[Post] = @[]
|
var list: seq[Post] = @[]
|
||||||
|
|
||||||
for row in db.getAllRows(postsQuery):
|
for row in db.getAllRows(postsQuery):
|
||||||
list.add(selectPost(row, @[]))
|
list.add(selectPost(row, @[], selectReplyingTo(row[4])))
|
||||||
|
|
||||||
resp $(%list), "application/json"
|
resp $(%list), "application/json"
|
||||||
|
|
||||||
|
|
@ -1440,11 +1467,14 @@ routes:
|
||||||
let threadId = getInt(formData["threadId"].body, -1)
|
let threadId = getInt(formData["threadId"].body, -1)
|
||||||
cond threadId != -1
|
cond threadId != -1
|
||||||
|
|
||||||
let replyingTo =
|
let replyingToId =
|
||||||
if "replyingTo" in formData:
|
if "replyingTo" in formData:
|
||||||
getInt(formData["replyingTo"].body, -1)
|
getInt(formData["replyingTo"].body, -1)
|
||||||
else:
|
else:
|
||||||
-1
|
-1
|
||||||
|
let replyingTo =
|
||||||
|
if replyingToId == -1: none[int]()
|
||||||
|
else: some(replyingToId)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
let id = executeReply(c, threadId, msg, replyingTo)
|
let id = executeReply(c, threadId, msg, replyingTo)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import strformat
|
import strformat, options
|
||||||
|
|
||||||
import user, threadlist
|
import user, threadlist
|
||||||
|
|
||||||
|
|
@ -20,12 +20,14 @@ type
|
||||||
info*: PostInfo
|
info*: PostInfo
|
||||||
moreBefore*: seq[int]
|
moreBefore*: seq[int]
|
||||||
isDeleted*: bool
|
isDeleted*: bool
|
||||||
|
replyingTo*: Option[PostLink]
|
||||||
|
|
||||||
PostLink* = object ## Used by profile
|
PostLink* = object ## Used by profile
|
||||||
creation*: int64
|
creation*: int64
|
||||||
topic*: string
|
topic*: string
|
||||||
threadId*: int
|
threadId*: int
|
||||||
postId*: int
|
postId*: int
|
||||||
|
author*: Option[User] ## Only used for `replyingTo`.
|
||||||
|
|
||||||
proc isModerated*(post: Post): bool =
|
proc isModerated*(post: Post): bool =
|
||||||
## Determines whether the specified thread is under moderation.
|
## Determines whether the specified thread is under moderation.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue