134 lines
3.2 KiB
Nim
134 lines
3.2 KiB
Nim
import asyncdispatch, db_sqlite, jester, moustachu, os,
|
|
shorturl, strutils, tables, times, typetraits
|
|
|
|
const
|
|
baseTemplate*: string = staticRead "./templates/layout.mustache"
|
|
browseTemplate*: string = staticRead "./templates/browse.mustache"
|
|
errorTemplate*: string = staticRead "./templates/error.mustache"
|
|
|
|
testTemplate*: string = """<p>hi!</p>"""
|
|
|
|
let
|
|
db = open("data/quotes.db", nil, nil, nil)
|
|
|
|
try:
|
|
db.exec(sql"""create table if not exists quotes (
|
|
id INTEGER PRIMARY KEY,
|
|
channel TEXT,
|
|
adder TEXT,
|
|
nick TEXT,
|
|
message TEXT,
|
|
time REAL,
|
|
deleted INTEGER DEFAULT 0)""")
|
|
|
|
except:
|
|
echo getCurrentExceptionMsg()
|
|
raise
|
|
|
|
template renderMustache*(title: string, templ: string, ctx: Context): expr =
|
|
var
|
|
layoutCtx = moustachu.newContext()
|
|
|
|
layoutCtx["title"] = title
|
|
layoutCtx["body"] = render(templ, ctx)
|
|
|
|
resp render(baseTemplate, layoutCtx)
|
|
|
|
template fail*(): expr =
|
|
var ctx = newContext()
|
|
ctx["exception"] = getCurrentExceptionMsg()
|
|
|
|
var
|
|
layoutCtx = moustachu.newContext()
|
|
|
|
layoutCtx["title"] = "fail"
|
|
layoutCtx["body"] = render(errorTemplate, ctx)
|
|
|
|
halt render(baseTemplate, layoutCtx)
|
|
|
|
template contextQuote(ctx: Context, qid: int, quote: Row): expr =
|
|
ctx["listid"] = qid
|
|
ctx["id"] = quote[0].parseInt().encodeURLSimple()
|
|
ctx["channel"] = quote[1]
|
|
ctx["channelsafe"] = quote[1].replace("#", "hashtag-")
|
|
ctx["nick"] = quote[2]
|
|
ctx["adder"] = quote[3]
|
|
ctx["message"] = quote[4]
|
|
ctx["time"] = parseInt(split(quote[5], '.')[0])
|
|
|
|
template pagination(ctx: Context, qid: int, kind: string): expr =
|
|
ctx["paging"] = true
|
|
if qid != 0:
|
|
ctx["isnt1"] = true
|
|
ctx["prev"] = qid - 1
|
|
ctx["next"] = qid + 1
|
|
ctx["kind"] = kind
|
|
|
|
settings:
|
|
port = 5000.Port
|
|
bindAddr = "0.0.0.0"
|
|
|
|
routes:
|
|
get "/test":
|
|
renderMustache("test", testTemplate, newContext())
|
|
|
|
get "/":
|
|
redirect "/browse/0"
|
|
|
|
get "/channel":
|
|
try:
|
|
var
|
|
channels = db.getAllRows(sql"select channel from quotes group by channel")
|
|
ctx: Context = newContext()
|
|
|
|
renderMustache("channel list", testTemplate, ctx)
|
|
except:
|
|
fail()
|
|
|
|
get "/@kind/@id":
|
|
var
|
|
title: string = ""
|
|
ctx: Context
|
|
rows: seq[Row]
|
|
qid: int = 0
|
|
|
|
try:
|
|
qid = (@"id").parseInt
|
|
except:
|
|
qid = (@"id").decodeURLSimple()
|
|
redirect "/" & @"kind" & "/" & $qid
|
|
|
|
case @"kind":
|
|
of "browse":
|
|
rows = db.getAllRows(sql"SELECT * FROM quotes ORDER BY time desc LIMIT 20 OFFSET ?", (qid * 20))
|
|
|
|
title = "page " & @"id"
|
|
of "quotes":
|
|
rows = db.getAllRows(sql"SELECT * FROM quotes WHERE id = ?", qid)
|
|
|
|
title = "quote #" & $qid & " by " & rows[0][2]
|
|
else:
|
|
if (@"kind").startsWith "hashtag-":
|
|
let channel = (@"kind").replace("hashtag-", "#")
|
|
|
|
rows = db.getAllRows(sql"SELECT * FROM quotes WHERE channel=? ORDER BY time desc LIMIT 20 OFFSET ?", channel, qid * 20)
|
|
|
|
title = channel & " page " & @"id"
|
|
else:
|
|
halt Http404, "not found"
|
|
|
|
ctx = newContext()
|
|
var quoteSeq = newSeq[Context]()
|
|
|
|
for row in items(rows):
|
|
var c = newContext()
|
|
c.contextQuote row[0].parseInt(), row
|
|
quoteSeq.add c
|
|
|
|
ctx["quotes"] = quoteSeq
|
|
ctx.pagination(qid, @"kind")
|
|
|
|
renderMustache(title, browseTemplate, ctx)
|
|
|
|
runForever()
|