Fixes CS problems.

This commit is contained in:
Dominik Picheta 2014-10-11 18:39:45 +01:00
commit da1876f7d0
3 changed files with 72 additions and 66 deletions

View file

@ -21,21 +21,21 @@
<th>Views</th> <th>Views</th>
<th>Last reply</th> <th>Last reply</th>
</tr> </tr>
# for row in Rows(db, query, $((c.pageNum-1) * ThreadsPerPage), $ThreadsPerPage): # for row in rows(db, query, $((c.pageNum-1) * ThreadsPerPage), $ThreadsPerPage):
# inc(count) # inc(count)
<tr> <tr>
<td class="topic"> <td class="topic">
${UrlButton(c, XMLencode(%name), c.genThreadUrl(threadid = %threadid))} ${UrlButton(c, xmlEncode(%name), c.genThreadUrl(threadid = %threadid))}
${genPagenumLocalNav(c, (%threadid).parseInt)} ${genPagenumLocalNav(c, (%threadid).parseInt)}
</td> </td>
#let authorName = getValue(db, sql("select name from person where id = " & #let authorName = getValue(db, sql("select name from person where id = " &
# "(select author from post where id = " & # "(select author from post where id = " &
# "(select min(id) from post where thread = ?))"), %threadId) # "(select min(id) from post where thread = ?))"), %threadId)
#let profileUrl = c.req.makeUri("profile/", false) & XMLEncode(authorName) #let profileUrl = c.req.makeUri("profile/", false) & xmlEncode(authorName)
<td class="author"><a href="$profileUrl">${authorName}</a></td> <td class="author"><a href="$profileUrl">${authorName}</a></td>
# let posts = GetValue(db, sql"select count(*) from post where thread = ?", %threadId) # let posts = getValue(db, sql"select count(*) from post where thread = ?", %threadId)
<td class="posts">$posts</td> <td class="posts">$posts</td>
<td class="views">${XMLencode(%views)}</td> <td class="views">${xmlEncode(%views)}</td>
#let latestReplyAuthor = getValue(db, sql("select name from person where id = " & #let latestReplyAuthor = getValue(db, sql("select name from person where id = " &
# "(select author from post where id = " & # "(select author from post where id = " &
# "(select max(id) from post where thread = ?))"), %threadId) # "(select max(id) from post where thread = ?))"), %threadId)
@ -44,7 +44,7 @@
<td class="lastreply"> <td class="lastreply">
<span>${formatTimestamp(latestReplyDate.parseInt())}</span><br/> <span>${formatTimestamp(latestReplyDate.parseInt())}</span><br/>
#let replyProfileUrl = c.req.makeUri("profile/", false) & #let replyProfileUrl = c.req.makeUri("profile/", false) &
# XMLEncode(latestReplyAuthor) # xmlEncode(latestReplyAuthor)
<span><a href="$replyProfileUrl">${latestReplyAuthor}</a></span> <span><a href="$replyProfileUrl">${latestReplyAuthor}</a></span>
</td> </td>
</tr> </tr>
@ -60,13 +60,13 @@
<table class="post"> <table class="post">
<tr> <tr>
<th colspan="2"> <th colspan="2">
<span>${XMLEncode(title)}</span> <span>${xmlEncode(title)}</span>
<span style="float:right;">${XMLencode(date)}</span> <span style="float:right;">${xmlEncode(date)}</span>
</th> </th>
</tr> </tr>
<tr> <tr>
<td class="left"> <td class="left">
<span>${XMLencode(author)}</span> <span>${xmlEncode(author)}</span>
</td> </td>
<td class="content"> <td class="content">
#try: #try:
@ -92,20 +92,20 @@
# const userEmail = 6 # const userEmail = 6
# result = "" # result = ""
# count = 0 # count = 0
# for row in FastRows(db, query, threadId, $((c.pageNum-1) * PostsPerPage), $PostsPerPage): # for row in fastRows(db, query, threadId, $((c.pageNum-1) * PostsPerPage), $PostsPerPage):
# inc(count) # inc(count)
<a name="${%postId}"></a> <a name="${%postId}"></a>
<table class="post"> <table class="post">
<tr> <tr>
<th colspan="2"> <th colspan="2">
<span>${XMLencode(%postHeader)}</span> <span>${xmlEncode(%postHeader)}</span>
<span style="float:right;">${XMLencode(%postCreation)}</span> <span style="float:right;">${xmlEncode(%postCreation)}</span>
</th> </th>
</tr> </tr>
<tr> <tr>
<td class="left"> <td class="left">
#let profileUrl = c.req.makeUri("profile/", false) & XMLencode(%userName) #let profileUrl = c.req.makeUri("profile/", false) & xmlEncode(%userName)
<span><a href="$profileUrl">${XMLencode(%userName)}</a></span> <span><a href="$profileUrl">${xmlEncode(%userName)}</a></span>
<hr/> <hr/>
<a href="$profileUrl">${genGravatar(%userEmail)}</a> <a href="$profileUrl">${genGravatar(%userEmail)}</a>
#if c.userId == %postAuthor and c.currentPost.subject.len == 0: #if c.userId == %postAuthor and c.currentPost.subject.len == 0:
@ -213,7 +213,7 @@
<span>Out of ${stats.totalUsers} users ${stats.activeUsers.len} are online${if stats.activeUsers.len == 0: "." else: ":"} <span>Out of ${stats.totalUsers} users ${stats.activeUsers.len} are online${if stats.activeUsers.len == 0: "." else: ":"}
#for index, usr in stats.activeUsers: #for index, usr in stats.activeUsers:
# let profileHref = """<a href="""" & c.req.makeUri("profile/", false) & # let profileHref = """<a href="""" & c.req.makeUri("profile/", false) &
# XMLencode(usr.nick) & """">""" # xmlEncode(usr.nick) & """">"""
# let hrefEnd = """</a>""" # let hrefEnd = """</a>"""
# if usr.isAdmin: # if usr.isAdmin:
#if index != 0: result.add ',' #if index != 0: result.add ','
@ -231,7 +231,7 @@
<hr/> <hr/>
#if stats.newestMember.nick != "": #if stats.newestMember.nick != "":
#let profileUrl = c.req.makeUri("profile/", false) & #let profileUrl = c.req.makeUri("profile/", false) &
# XMLEncode(stats.newestMember.nick) # xmlEncode(stats.newestMember.nick)
<span>Total threads: ${stats.totalThreads} | Total posts: ${stats.totalPosts} | Newest member: <a href="$profileUrl">${stats.newestMember.nick}</a></span> <span>Total threads: ${stats.totalThreads} | Total posts: ${stats.totalPosts} | Newest member: <a href="$profileUrl">${stats.newestMember.nick}</a></span>
#else: #else:
<span>Total threads: ${stats.totalThreads} | Total posts: ${stats.totalPosts}</span> <span>Total threads: ${stats.totalThreads} | Total posts: ${stats.totalPosts}</span>

View file

@ -9,7 +9,6 @@
import import
os, strutils, times, md5, strtabs, cgi, math, db_sqlite, matchers, os, strutils, times, md5, strtabs, cgi, math, db_sqlite, matchers,
rst, rstgen, captchas, scgi, jester, asyncdispatch, asyncnet rst, rstgen, captchas, scgi, jester, asyncdispatch, asyncnet
from htmlgen import tr, th, td, span from htmlgen import tr, th, td, span
const const
@ -90,14 +89,14 @@ const
proc TextWidget(c: TForumData, name, defaultText: string, proc TextWidget(c: TForumData, name, defaultText: string,
maxlength = 30, size = -1): string = maxlength = 30, size = -1): string =
let x = if defaultText != reuseText: defaultText let x = if defaultText != reuseText: defaultText
else: XMLencode(c.req.params[name]) else: xmlEncode(c.req.params[name])
return """<input type="text" name="$1" maxlength="$2" value="$3" $4/>""" % [ return """<input type="text" name="$1" maxlength="$2" value="$3" $4/>""" % [
name, $maxlength, x, if size != -1: "size=\"" & $size & "\"" else: ""] name, $maxlength, x, if size != -1: "size=\"" & $size & "\"" else: ""]
proc TextAreaWidget(c: TForumData, name, defaultText: string, proc TextAreaWidget(c: TForumData, name, defaultText: string,
width = 80, height = 20): string = width = 80, height = 20): string =
let x = if defaultText != reuseText: defaultText let x = if defaultText != reuseText: defaultText
else: XMLencode(c.req.params[name]) else: xmlEncode(c.req.params[name])
return """<textarea name="$1" cols="$2" rows="$3">$4</textarea>""" % [ return """<textarea name="$1" cols="$2" rows="$3">$4</textarea>""" % [
name, $width, $height, x] name, $width, $height, x]
@ -189,7 +188,7 @@ proc makePassword(password, salt: string): string =
template `||`(x: expr): expr = (if not isNil(x): x else: "") template `||`(x: expr): expr = (if not isNil(x): x else: "")
proc validThreadId(c: TForumData): bool = proc validThreadId(c: TForumData): bool =
result = GetValue(db, sql"select id from thread where id = ?", result = getValue(db, sql"select id from thread where id = ?",
$c.threadId).len > 0 $c.threadId).len > 0
proc antibot(c: var TForumData): string = proc antibot(c: var TForumData): string =
@ -197,12 +196,12 @@ proc antibot(c: var TForumData): string =
let b = math.random(1000)+1 let b = math.random(1000)+1
let answer = $(a+b) let answer = $(a+b)
Exec(db, sql"delete from antibot where ip = ?", c.req.ip) exec(db, sql"delete from antibot where ip = ?", c.req.ip)
let CaptchaId = TryInsertID(db, let captchaId = tryInsertID(db,
sql"insert into antibot(ip, answer) values (?, ?)", c.req.ip, sql"insert into antibot(ip, answer) values (?, ?)", c.req.ip,
answer).int mod 10_000 answer).int mod 10_000
let CaptchaFile = getCaptchaFilename(CaptchaId) let captchaFile = getCaptchaFilename(captchaId)
createCaptcha(CaptchaFile, $a & "+" & $b) createCaptcha(captchaFile, $a & "+" & $b)
result = """<img src="$1" />""" % c.req.getCaptchaUrl(captchaId) result = """<img src="$1" />""" % c.req.getCaptchaUrl(captchaId)
const const
@ -217,7 +216,7 @@ proc register(c: var TForumData, name, pass, antibot, email: string): bool =
# Username validation: # Username validation:
if name.len == 0 or not allCharsInSet(name, SecureChars): if name.len == 0 or not allCharsInSet(name, SecureChars):
return setError(c, "name", "Invalid username!") return setError(c, "name", "Invalid username!")
if GetValue(db, sql"select name from person where name = ?", name).len > 0: if getValue(db, sql"select name from person where name = ?", name).len > 0:
return setError(c, "name", "Username already exists!") return setError(c, "name", "Username already exists!")
# Password validation: # Password validation:
@ -225,7 +224,7 @@ proc register(c: var TForumData, name, pass, antibot, email: string): bool =
return setError(c, "new_password", "Invalid password!") return setError(c, "new_password", "Invalid password!")
# antibot validation: # antibot validation:
let correctRes = GetValue(db, let correctRes = getValue(db,
sql"select answer from antibot where ip = ?", c.req.ip) sql"select answer from antibot where ip = ?", c.req.ip)
if antibot != correctRes: if antibot != correctRes:
return setError(c, "antibot", "You seem to be a bot!") return setError(c, "antibot", "You seem to be a bot!")
@ -236,7 +235,7 @@ proc register(c: var TForumData, name, pass, antibot, email: string): bool =
# perform registration: # perform registration:
var salt = makeSalt() var salt = makeSalt()
Exec(db, sql("INSERT INTO person(name, password, email, salt, status, lastOnline) " & exec(db, sql("INSERT INTO person(name, password, email, salt, status, lastOnline) " &
"VALUES (?, ?, ?, ?, 'user', DATETIME('now'))"), name, "VALUES (?, ?, ?, ?, 'user', DATETIME('now'))"), name,
makePassword(pass, salt), email, salt) makePassword(pass, salt), email, salt)
# return setError(c, "", "Could not create your account!") # return setError(c, "", "Could not create your account!")
@ -245,12 +244,12 @@ proc register(c: var TForumData, name, pass, antibot, email: string): bool =
proc checkLoggedIn(c: var TForumData) = proc checkLoggedIn(c: var TForumData) =
let pass = c.req.cookies["sid"] let pass = c.req.cookies["sid"]
if pass.len == 0: return if pass.len == 0: return
if ExecAffectedRows(db, if execAffectedRows(db,
sql("update session set lastModified = DATETIME('now') " & sql("update session set lastModified = DATETIME('now') " &
"where ip = ? and password = ?"), "where ip = ? and password = ?"),
c.req.ip, pass) > 0: c.req.ip, pass) > 0:
c.userpass = pass c.userpass = pass
c.userid = GetValue(db, c.userid = getValue(db,
sql"select userid from session where ip = ? and password = ?", sql"select userid from session where ip = ? and password = ?",
c.req.ip, pass) c.req.ip, pass)
@ -270,11 +269,11 @@ proc logout(c: var TForumData) =
const query = sql"delete from session where ip = ? and password = ?" const query = sql"delete from session where ip = ? and password = ?"
c.username = "" c.username = ""
c.userpass = "" c.userpass = ""
Exec(db, query, c.req.ip, c.req.cookies["sid"]) exec(db, query, c.req.ip, c.req.cookies["sid"])
proc incrementViews(c: var TForumData) = proc incrementViews(c: var TForumData) =
const query = sql"update thread set views = views + 1 where id = ?" const query = sql"update thread set views = views + 1 where id = ?"
Exec(db, query, $c.threadId) exec(db, query, $c.threadId)
proc isPreview(c: TForumData): bool = proc isPreview(c: TForumData): bool =
result = c.req.params["previewBtn"].len > 0 # TODO: Could be wrong? result = c.req.params["previewBtn"].len > 0 # TODO: Could be wrong?
@ -363,10 +362,10 @@ proc edit(c: var TForumData, postId: int): bool =
setPreviewData(c) setPreviewData(c)
elif c.isDelete: elif c.isDelete:
checkOwnership(c, $postId) checkOwnership(c, $postId)
if not TryExec(db, crud(crDelete, "post"), $postId): if not tryExec(db, crud(crDelete, "post"), $postId):
return setError(c, "", "database error") return setError(c, "", "database error")
# delete corresponding thread: # delete corresponding thread:
if ExecAffectedRows(db, if execAffectedRows(db,
sql"delete from thread where id not in (select thread from post)") > 0: sql"delete from thread where id not in (select thread from post)") > 0:
# whole thread has been deleted, so: # whole thread has been deleted, so:
c.threadId = unselectedThread c.threadId = unselectedThread
@ -398,7 +397,7 @@ proc newThread(c: var TForumData): bool =
setPreviewData(c) setPreviewData(c)
c.threadID = transientThread c.threadID = transientThread
else: else:
c.threadID = TryInsertID(db, query, c.req.params["subject"]).int c.threadID = tryInsertID(db, query, c.req.params["subject"]).int
if c.threadID < 0: return setError(c, "subject", "Subject already exists") if c.threadID < 0: return setError(c, "subject", "Subject already exists")
writeToDb(c, crCreate, false) writeToDb(c, crCreate, false)
result = true result = true
@ -410,7 +409,7 @@ proc login(c: var TForumData, name, pass: string): bool =
if name.len == 0: if name.len == 0:
return c.setError("name", "Username cannot be nil.") return c.setError("name", "Username cannot be nil.")
var success = false var success = false
for row in FastRows(db, query, name): for row in fastRows(db, query, name):
if row[2] == makePassword(pass, row[4]): if row[2] == makePassword(pass, row[4]):
c.userid = row[0] c.userid = row[0]
c.username = row[1] c.username = row[1]
@ -421,7 +420,7 @@ proc login(c: var TForumData, name, pass: string): bool =
break break
if success: if success:
# create session: # create session:
Exec(db, exec(db,
sql"insert into session (ip, password, userid) values (?, ?, ?)", sql"insert into session (ip, password, userid) values (?, ?, ?)",
c.req.ip, c.userpass, c.userid) c.req.ip, c.userpass, c.userid)
return true return true
@ -434,11 +433,12 @@ proc genActionMenu(c: var TForumData): string =
# TODO: Make this detection better? # TODO: Make this detection better?
if c.req.pathInfo.normalizeUri notin noHomeBtn and not c.isThreadsList: if c.req.pathInfo.normalizeUri notin noHomeBtn and not c.isThreadsList:
btns.add(("Thread List", c.req.makeUri("/", false))) btns.add(("Thread List", c.req.makeUri("/", false)))
#echo c.loggedIn
if c.loggedIn: if c.loggedIn:
let hasReplyBtn = c.req.pathInfo != "/donewthread" and c.req.pathInfo != "/doreply" let hasReplyBtn = c.req.pathInfo != "/donewthread" and c.req.pathInfo != "/doreply"
if c.threadId >= 0 and hasReplyBtn: if c.threadId >= 0 and hasReplyBtn:
let replyUrl = c.genThreadUrl(action = "reply", let replyUrl = c.genThreadUrl(action = "reply",
pageNum = $(ceil(c.totalPosts / postsPerPage).int)) & "#reply" pageNum = $(ceil(c.totalPosts / PostsPerPage).int)) & "#reply"
btns.add(("Reply", replyUrl)) btns.add(("Reply", replyUrl))
btns.add(("New Thread", c.req.makeUri("/newthread", false))) btns.add(("New Thread", c.req.makeUri("/newthread", false)))
result = c.genButtons(btns) result = c.genButtons(btns)
@ -489,7 +489,7 @@ proc genPagenumNav(c: var TForumData, stats: TForumStats): string =
prevUrl = firstUrl prevUrl = firstUrl
else: else:
prevUrl = c.req.makeUri(firstUrl & "/" & $(c.pageNum-1)) prevUrl = c.req.makeUri(firstUrl & "/" & $(c.pageNum-1))
totalPages = ceil(c.totalPosts / postsPerPage).int totalPages = ceil(c.totalPosts / PostsPerPage).int
lastUrl = c.req.makeUri(firstUrl & "/" & $(totalPages)) lastUrl = c.req.makeUri(firstUrl & "/" & $(totalPages))
nextUrl = c.req.makeUri(firstUrl & "/" & $(c.pageNum+1)) nextUrl = c.req.makeUri(firstUrl & "/" & $(c.pageNum+1))
@ -540,7 +540,7 @@ proc genPagenumNav(c: var TForumData, stats: TForumStats): string =
proc gatherTotalPostsByID(c: var TForumData, thrid: int): int = proc gatherTotalPostsByID(c: var TForumData, thrid: int): int =
## Gets the total post count of a thread. ## Gets the total post count of a thread.
result = GetValue(db, sql"select count(*) from post where thread = ?", $thrid).parseInt result = getValue(db, sql"select count(*) from post where thread = ?", $thrid).parseInt
proc gatherTotalPosts(c: var TForumData) = proc gatherTotalPosts(c: var TForumData) =
if c.totalPosts > 0: return if c.totalPosts > 0: return
@ -551,13 +551,13 @@ proc gatherTotalPosts(c: var TForumData) =
proc getPagesInThread(c: var TForumData): int = proc getPagesInThread(c: var TForumData): int =
c.gatherTotalPosts() # Get total post count c.gatherTotalPosts() # Get total post count
result = ceil(c.totalPosts / postsPerPage).int-1 result = ceil(c.totalPosts / PostsPerPage).int-1
proc getPagesInThreadByID(c: var TForumData, thrid: int): int = proc getPagesInThreadByID(c: var TForumData, thrid: int): int =
result = ceil(c.gatherTotalPostsByID(thrid) / postsPerPage).int result = ceil(c.gatherTotalPostsByID(thrid) / PostsPerPage).int
proc getThreadTitle(thrid: int, pageNum: int): string = proc getThreadTitle(thrid: int, pageNum: int): string =
result = GetValue(db, sql"select name from thread where id = ?", $thrid) result = getValue(db, sql"select name from thread where id = ?", $thrid)
if pageNum notin {0,1}: if pageNum notin {0,1}:
result.add(" - Page " & $pageNum) result.add(" - Page " & $pageNum)
@ -605,7 +605,7 @@ proc genProfile(c: var TForumData, ui: TUserInfo): string =
result = "" result = ""
result.add(htmlgen.`div`(id = "avatar", genGravatar(ui.email, 250))) result.add(htmlgen.`div`(id = "avatar", genGravatar(ui.email, 250)))
let t2 = if ui.lastOnline != -1: getGMTime(TTime(ui.lastOnline)) let t2 = if ui.lastOnline != -1: getGMTime(TTime(ui.lastOnline))
else: getGMTime(GetTime()) else: getGMTime(getTime())
result.add(htmlgen.`div`(id = "info", result.add(htmlgen.`div`(id = "info",
htmlgen.table( htmlgen.table(
@ -651,13 +651,21 @@ template createTFD(): stmt =
if request.cookies.len > 0: if request.cookies.len > 0:
checkLoggedIn(c) checkLoggedIn(c)
var cached = ""
#var settings = newSettings()
#settings.port = Port(5000)
routes: routes:
get "/": get "/":
createTFD() createTFD()
c.isThreadsList = true c.isThreadsList = true
var count = 0 var count = 0
resp genMain(c, genThreadsList(c, count), discard genThreadsList(c, count)
additionalHeaders = genRSSHeaders(c), showRssLinks = true) if cached == "":
cached = genMain(c, genThreadsList(c, count),
additionalHeaders = genRSSHeaders(c), showRssLinks = true)
resp cached
get "/threadActivity.xml": get "/threadActivity.xml":
createTFD() createTFD()
@ -684,7 +692,7 @@ routes:
var title = "" var title = ""
case @"action" case @"action"
of "reply": of "reply":
let subject = GetValue(db, let subject = getValue(db,
sql"select header from post where id = (select max(id) from post where thread = ?)", sql"select header from post where id = (select max(id) from post where thread = ?)",
$c.threadId).prependRe $c.threadId).prependRe
body = genPostsList(c, $c.threadId, count) body = genPostsList(c, $c.threadId, count)
@ -817,7 +825,7 @@ routes:
when isMainModule: when isMainModule:
docConfig = rstgen.defaultConfig() docConfig = rstgen.defaultConfig()
math.randomize() math.randomize()
db = Open(connection="nimforum.db", user="postgres", password="", db = open(connection="nimforum.db", user="postgres", password="",
database="nimforum") database="nimforum")
var http = true var http = true
if paramCount() > 0: if paramCount() > 0:
@ -825,9 +833,7 @@ when isMainModule:
http = false http = false
#run("", port = TPort(9000), http = http) #run("", port = TPort(9000), http = http)
var settings = newSettings()
settings.port = TPort(8080)
jester.serve(settings, match)
runForever() runForever()
db.close() db.close()

View file

@ -10,7 +10,7 @@
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<title>${XmlEncode(title)}</title> <title>${xmlEncode(title)}</title>
<link rel="stylesheet" href="${c.req.makeUri("css/normalize.css", absolute = false)}"> <link rel="stylesheet" href="${c.req.makeUri("css/normalize.css", absolute = false)}">
<link rel="stylesheet" href="${c.req.makeUri("css/style.css", absolute = false)}">${additional_headers} <link rel="stylesheet" href="${c.req.makeUri("css/style.css", absolute = false)}">${additional_headers}
<meta charset="UTF-8"> <meta charset="UTF-8">
@ -30,7 +30,7 @@
#if c.loggedIn: #if c.loggedIn:
<a href="${frontQuery}logout" class="right">Logout</a> <a href="${frontQuery}logout" class="right">Logout</a>
#let profileUrl = c.req.makeUri("profile/", false) & #let profileUrl = c.req.makeUri("profile/", false) &
# XMLencode(c.username) # xmlEncode(c.username)
<span id="welcome"><a href="${profileUrl}">$c.username</a></span> <span id="welcome"><a href="${profileUrl}">$c.username</a></span>
<a href="$profileUrl">${genGravatar(c.email, 26)}</a> <a href="$profileUrl">${genGravatar(c.email, 26)}</a>
#else: #else:
@ -110,7 +110,7 @@
# const postContent = 5 # const postContent = 5
# const postId = 6 # const postId = 6
# let frontQuery = c.req.makeUri("/") # let frontQuery = c.req.makeUri("/")
# let recent = GetValue(db, sql"""SELECT # let recent = getValue(db, sql"""SELECT
# strftime('%Y-%m-%dT%H:%M:%SZ', (modified)) FROM thread # strftime('%Y-%m-%dT%H:%M:%SZ', (modified)) FROM thread
# ORDER BY modified DESC LIMIT 1""") # ORDER BY modified DESC LIMIT 1""")
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
@ -120,22 +120,22 @@
<link href="${frontQuery}" /> <link href="${frontQuery}" />
<id>${frontQuery}</id> <id>${frontQuery}</id>
<updated>${recent}</updated> <updated>${recent}</updated>
# for row in Rows(db, query, 10): # for row in rows(db, query, 10):
<entry> <entry>
<title>${XMLencode(%name)}</title> <title>${xmlEncode(%name)}</title>
<id>urn:entry:${%threadid}</id> <id>urn:entry:${%threadid}</id>
# let url = c.genThreadUrl(threadid = %threadid, # let url = c.genThreadUrl(threadid = %threadid,
# pageNum = $(ceil(parseInt(%postCount) / postsPerPage).int)) & # pageNum = $(ceil(parseInt(%postCount) / PostsPerPage).int)) &
# "#" & %postId # "#" & %postId
<link rel="alternate" type="text/html" <link rel="alternate" type="text/html"
href="${c.req.makeUri(url)}"/> href="${c.req.makeUri(url)}"/>
<published>${%threadDate}</published> <published>${%threadDate}</published>
<updated>${%threadDate}</updated> <updated>${%threadDate}</updated>
<author><name>${XMLEncode(%postAuthor)}</name></author> <author><name>${xmlEncode(%postAuthor)}</name></author>
<content type="html" <content type="html"
>Posts ${%postCount}, ${XMLEncode(%postAuthor)} said: >Posts ${%postCount}, ${xmlEncode(%postAuthor)} said:
&lt;p&gt; &lt;p&gt;
${XMLEncode(rstToHtml(%postContent))}</content> ${xmlEncode(rstToHtml(%postContent))}</content>
</entry> </entry>
# end for # end for
</feed> </feed>
@ -159,7 +159,7 @@ ${XMLEncode(rstToHtml(%postContent))}</content>
# const postHumanDate = 6 # const postHumanDate = 6
# const postPosition = 7 # const postPosition = 7
# let frontQuery = c.req.makeUri("/") # let frontQuery = c.req.makeUri("/")
# let recent = GetValue(db, sql"""SELECT # let recent = getValue(db, sql"""SELECT
# strftime('%Y-%m-%dT%H:%M:%SZ', creation) FROM post # strftime('%Y-%m-%dT%H:%M:%SZ', creation) FROM post
# ORDER BY creation DESC LIMIT 1""") # ORDER BY creation DESC LIMIT 1""")
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
@ -169,22 +169,22 @@ ${XMLEncode(rstToHtml(%postContent))}</content>
<link href="${frontQuery}" /> <link href="${frontQuery}" />
<id>${frontQuery}</id> <id>${frontQuery}</id>
<updated>${recent}</updated> <updated>${recent}</updated>
# for row in Rows(db, query, 10): # for row in rows(db, query, 10):
<entry> <entry>
<title>${XMLencode(%postHeader)}</title> <title>${xmlEncode(%postHeader)}</title>
<id>urn:entry:${%postId}</id> <id>urn:entry:${%postId}</id>
# let url = c.genThreadUrl(threadid = %postThread, # let url = c.genThreadUrl(threadid = %postThread,
# pageNum = $(ceil(parseInt(%postPosition) / postsPerPage).int)) & # pageNum = $(ceil(parseInt(%postPosition) / PostsPerPage).int)) &
# "#" & %postId # "#" & %postId
<link rel="alternate" type="text/html" <link rel="alternate" type="text/html"
href="${c.req.makeUri(url)}"/> href="${c.req.makeUri(url)}"/>
<published>${%postRssDate}</published> <published>${%postRssDate}</published>
<updated>${%postRssDate}</updated> <updated>${%postRssDate}</updated>
<author><name>${XMLEncode(%postAuthor)}</name></author> <author><name>${xmlEncode(%postAuthor)}</name></author>
<content type="html" <content type="html"
>On ${XMLEncode(%postHumanDate)}, ${XMLEncode(%postAuthor)} said: >On ${xmlEncode(%postHumanDate)}, ${xmlEncode(%postAuthor)} said:
&lt;p&gt; &lt;p&gt;
${XMLEncode(rstToHtml(%postContent))}</content> ${xmlEncode(rstToHtml(%postContent))}</content>
</entry> </entry>
# end for # end for
</feed> </feed>