Implements naive /profile.json endpoint.
This commit is contained in:
parent
6380ea699d
commit
d345bf76ae
4 changed files with 81 additions and 21 deletions
64
forum.nim
64
forum.nim
|
|
@ -9,12 +9,12 @@
|
||||||
import
|
import
|
||||||
os, strutils, times, md5, strtabs, math, db_sqlite,
|
os, strutils, times, md5, strtabs, math, db_sqlite,
|
||||||
scgi, jester, asyncdispatch, asyncnet, cache, sequtils,
|
scgi, jester, asyncdispatch, asyncnet, cache, sequtils,
|
||||||
parseutils, utils, random, rst, ranks, recaptcha, json, re, sugar
|
parseutils, utils, random, rst, recaptcha, json, re, sugar
|
||||||
import cgi except setCookie
|
import cgi except setCookie
|
||||||
import options
|
import options
|
||||||
|
|
||||||
import redesign/threadlist except User
|
import redesign/threadlist except User
|
||||||
import redesign/[category, postlist, error, header, post]
|
import redesign/[category, postlist, error, header, post, profile]
|
||||||
|
|
||||||
when not defined(windows):
|
when not defined(windows):
|
||||||
import bcrypt # TODO
|
import bcrypt # TODO
|
||||||
|
|
@ -1016,17 +1016,17 @@ template createTFD() =
|
||||||
#[ DB functions. TODO: Move to another module? ]#
|
#[ DB functions. TODO: Move to another module? ]#
|
||||||
|
|
||||||
proc selectUser(userRow: seq[string]): threadlist.User =
|
proc selectUser(userRow: seq[string]): threadlist.User =
|
||||||
let isOnline = getTime().toUnix() - userRow[2].parseInt > (60*5)
|
|
||||||
return threadlist.User(
|
return threadlist.User(
|
||||||
name: userRow[0],
|
name: userRow[0],
|
||||||
avatarUrl: userRow[1].getGravatarUrl(),
|
avatarUrl: userRow[1].getGravatarUrl(),
|
||||||
isOnline: isOnline
|
lastOnline: userRow[2].parseInt,
|
||||||
|
rank: parseEnum[Rank](userRow[3])
|
||||||
)
|
)
|
||||||
|
|
||||||
proc selectPost(postRow: seq[string], skippedPosts: seq[int]): Post =
|
proc selectPost(postRow: seq[string], skippedPosts: seq[int]): Post =
|
||||||
return Post(
|
return Post(
|
||||||
id: postRow[0].parseInt,
|
id: postRow[0].parseInt,
|
||||||
author: selectUser(@[postRow[4], postRow[5], postRow[6]]),
|
author: selectUser(@[postRow[4], postRow[5], postRow[6], postRow[7]]),
|
||||||
likes: @[], # TODO:
|
likes: @[], # TODO:
|
||||||
seen: false, # TODO:
|
seen: false, # TODO:
|
||||||
history: @[], # TODO:
|
history: @[], # TODO:
|
||||||
|
|
@ -1043,7 +1043,7 @@ proc selectThread(threadRow: seq[string]): Thread =
|
||||||
where thread = ?
|
where thread = ?
|
||||||
order by creation asc limit 1;"""
|
order by creation asc limit 1;"""
|
||||||
const usersListQuery =
|
const usersListQuery =
|
||||||
sql"""select distinct name, email, strftime('%s', lastOnline)
|
sql"""select distinct name, email, strftime('%s', lastOnline), status
|
||||||
from person where id in
|
from person where id in
|
||||||
(select author from post where thread = ?)
|
(select author from post where thread = ?)
|
||||||
limit 5;""" # TODO: Order by most posts.
|
limit 5;""" # TODO: Order by most posts.
|
||||||
|
|
@ -1158,7 +1158,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,
|
||||||
u.name, u.email, strftime('%s', u.lastOnline)
|
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 $#
|
where u.id = p.author and p.thread = ? and $#
|
||||||
and (u.status <> 'Spammer' or p.author = ?)
|
and (u.status <> 'Spammer' or p.author = ?)
|
||||||
|
|
@ -1196,7 +1196,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,
|
||||||
u.name, u.email, strftime('%s', u.lastOnline)
|
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 ($#)
|
||||||
order by p.id;
|
order by p.id;
|
||||||
|
|
@ -1209,6 +1209,51 @@ routes:
|
||||||
|
|
||||||
resp $(%list), "application/json"
|
resp $(%list), "application/json"
|
||||||
|
|
||||||
|
get "/karax/profile.json":
|
||||||
|
createTFD()
|
||||||
|
var
|
||||||
|
username = @"username"
|
||||||
|
|
||||||
|
let postsQuery = sql("""
|
||||||
|
select p.id, p.content, strftime('%s', p.creation), p.author,
|
||||||
|
u.name, u.email, strftime('%s', u.lastOnline), u.status
|
||||||
|
from post p, person u
|
||||||
|
where u.id = p.author and u.name = ?
|
||||||
|
order by p.id desc;
|
||||||
|
""")
|
||||||
|
|
||||||
|
var profile = Profile(
|
||||||
|
threads: @[],
|
||||||
|
posts: @[]
|
||||||
|
)
|
||||||
|
|
||||||
|
let rows = db.getAllRows(postsQuery, username)
|
||||||
|
profile.user = selectUser(@[
|
||||||
|
rows[0][4], rows[0][5], rows[0][6], rows[0][7]
|
||||||
|
])
|
||||||
|
|
||||||
|
if c.rank >= Admin:
|
||||||
|
profile.email = some(rows[0][5])
|
||||||
|
|
||||||
|
for row in rows:
|
||||||
|
let firstPostForThread = getRow(db,
|
||||||
|
sql"""select t.id, t.name, t.views, t.modified, p.id
|
||||||
|
from thread t, post p
|
||||||
|
where p.thread = t.id
|
||||||
|
order by p.id limit 1""", row[0])
|
||||||
|
|
||||||
|
# Check if the thread that contains this post was created by the user.
|
||||||
|
if firstPostForThread[4] == row[0]:
|
||||||
|
profile.threads.add(
|
||||||
|
selectThread(firstPostForThread)
|
||||||
|
)
|
||||||
|
|
||||||
|
profile.posts.add(
|
||||||
|
selectPost(row, @[])
|
||||||
|
)
|
||||||
|
|
||||||
|
resp $(%profile), "application/json"
|
||||||
|
|
||||||
post "/karax/login":
|
post "/karax/login":
|
||||||
createTFD()
|
createTFD()
|
||||||
let formData = request.formData
|
let formData = request.formData
|
||||||
|
|
@ -1232,7 +1277,8 @@ routes:
|
||||||
some(threadlist.User(
|
some(threadlist.User(
|
||||||
name: c.username,
|
name: c.username,
|
||||||
avatarUrl: c.email.getGravatarUrl(),
|
avatarUrl: c.email.getGravatarUrl(),
|
||||||
isOnline: true
|
lastOnline: getTime().toUnix(),
|
||||||
|
rank: c.rank
|
||||||
))
|
))
|
||||||
else:
|
else:
|
||||||
none[threadlist.User]()
|
none[threadlist.User]()
|
||||||
|
|
|
||||||
11
ranks.nim
11
ranks.nim
|
|
@ -1,11 +0,0 @@
|
||||||
|
|
||||||
type
|
|
||||||
Rank* = enum ## serialized as 'status'
|
|
||||||
Spammer ## spammer: every post is invisible
|
|
||||||
Troll ## troll: cannot write new posts
|
|
||||||
EmailUnconfirmed ## member with unconfirmed email address
|
|
||||||
Moderated ## new member: posts manually reviewed before everybody
|
|
||||||
## can see them
|
|
||||||
User ## Ordinary user
|
|
||||||
Moderator ## Moderator: can ban/moderate users
|
|
||||||
Admin ## Admin: can do everything
|
|
||||||
11
redesign/profile.nim
Normal file
11
redesign/profile.nim
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
import options
|
||||||
|
import threadlist, post
|
||||||
|
type
|
||||||
|
Profile* = object
|
||||||
|
user*: User
|
||||||
|
joinTime*: int64
|
||||||
|
threads*: seq[Thread]
|
||||||
|
posts*: seq[Post]
|
||||||
|
# Information that only admins should see.
|
||||||
|
email*: Option[string]
|
||||||
|
|
||||||
|
|
@ -3,10 +3,21 @@ import strformat, times, options, json, httpcore, sugar
|
||||||
import category
|
import category
|
||||||
|
|
||||||
type
|
type
|
||||||
|
Rank* {.pure.} = enum ## serialized as 'status'
|
||||||
|
Spammer ## spammer: every post is invisible
|
||||||
|
Troll ## troll: cannot write new posts
|
||||||
|
EmailUnconfirmed ## member with unconfirmed email address
|
||||||
|
Moderated ## new member: posts manually reviewed before everybody
|
||||||
|
## can see them
|
||||||
|
User ## Ordinary user
|
||||||
|
Moderator ## Moderator: can ban/moderate users
|
||||||
|
Admin ## Admin: can do everything
|
||||||
|
|
||||||
User* = object
|
User* = object
|
||||||
name*: string
|
name*: string
|
||||||
avatarUrl*: string
|
avatarUrl*: string
|
||||||
isOnline*: bool
|
lastOnline*: int64
|
||||||
|
rank*: Rank
|
||||||
|
|
||||||
Thread* = object
|
Thread* = object
|
||||||
id*: int
|
id*: int
|
||||||
|
|
@ -25,6 +36,9 @@ type
|
||||||
lastVisit*: int64 ## Unix timestamp
|
lastVisit*: int64 ## Unix timestamp
|
||||||
moreCount*: int ## How many more threads are left
|
moreCount*: int ## How many more threads are left
|
||||||
|
|
||||||
|
proc isOnline*(user: User): bool =
|
||||||
|
return getTime().toUnix() - user.lastOnline > (60*5)
|
||||||
|
|
||||||
when defined(js):
|
when defined(js):
|
||||||
include karax/prelude
|
include karax/prelude
|
||||||
import karax / [vstyles, kajax, kdom]
|
import karax / [vstyles, kajax, kdom]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue