Browse Source

normalize db schema a bit, change layout

master
Wesley Kerfoot 4 years ago
parent
commit
bf5ce42b18
  1. 76
      src/tweetlogpkg/server.nim
  2. 19
      src/tweetlogpkg/templates.nim

76
src/tweetlogpkg/server.nim

@ -3,21 +3,25 @@ import twitter
import templates
import jester
type Author = object
name: string
authorID : int
type ThreadRequest = object
tweetID: string
author: string
author: Author
type TwitterThread = ref object of RootObj
tweetID: string
author: string
tweets: string
author: Author
proc parseTweetUrl(url : string) : Option[ThreadRequest] =
let path = url.parseUri.path
var author : string
var tweetID : int
if scanf(path, "/$w/status/$i$.", author, tweetID):
some(ThreadRequest(tweetID : $tweetID, author: author))
some(ThreadRequest(tweetID : $tweetID, author: Author(name: author)))
else:
none(ThreadRequest)
@ -30,38 +34,70 @@ chan.open(20)
let db = open("tweetlog.db", "", "", "")
proc createTweetTable() =
proc createTweetTables() =
db.exec(sql"""CREATE TABLE IF NOT EXISTS threads (
id INTEGER PRIMARY KEY,
tid TEXT,
author TEXT,
tweets TEXT
tweets TEXT,
authorID INTEGER
)""")
db.exec(sql"""CREATE TABLE IF NOT EXISTS authors (
id INTEGER PRIMARY KEY,
name TEXT,
UNIQUE(name, id)
)""")
proc threadExists(threadID : string, author : string) : Option[TwitterThread] =
let row = db.getRow(sql"SELECT * FROM threads WHERE tid=? AND author=?", threadID, author)
proc authorExists(authorName : string) : Option[Author] =
let authorID = db.getRow(sql"SELECT * from authors where name=?", authorName)
if authorID.all(col => col == ""):
return none(Author)
return some(Author(name: authorName, authorID: authorID[0].parseInt))
proc threadExists(threadID : string, authorName : string) : Option[TwitterThread] =
let author = authorName.authorExists
if not author.isSome:
return none(TwitterThread)
let row = db.getRow(sql"SELECT * FROM threads WHERE tid=? AND authorID=?", threadID, author.get.authorID)
if row.all(col => col == ""):
return none(TwitterThread)
some(
TwitterThread(tweetID: row[1],
author: row[2],
tweets: row[3])
author: author.get,
tweets: row[2])
)
iterator allAuthors() : string =
for author in db.getAllRows(sql"SELECT DISTINCT author FROM threads"):
for author in db.getAllRows(sql"SELECT DISTINCT name FROM authors"):
yield author[0]
iterator threadIDs(author : string) : string =
for threadID in db.getAllRows(sql"SELECT tid from threads WHERE author=?", author):
yield threadID[0]
let authorID = db.getRow(sql"SELECT * from authors where name=?", author)
if authorID.all(col => col == ""):
yield ""
else:
for threadID in db.getAllRows(sql"SELECT tid from threads WHERE authorID=?", authorID):
yield threadID[0]
proc insertThread(thread : TwitterThread) =
db.exec(sql"INSERT INTO threads (tid, author, tweets) VALUES (?, ?, ?)",
db.exec(sql"INSERT OR IGNORE INTO authors (name) VALUES (?)", thread.author.name)
let author = thread.author.name.authorExists
if not author.isSome:
return
db.exec(sql"INSERT INTO threads (tid, tweets, authorID) VALUES (?, ?, ?)",
thread.tweetID,
thread.author,
thread.tweets)
thread.tweets,
author.get.authorID)
# Routes
@ -96,7 +132,7 @@ router twitblog:
else:
# Send it off to the rendering thread for processing
# Let them know to check back later
chan.send(ThreadRequest(tweetID: tweetID, author: author))
chan.send(ThreadRequest(tweetID: tweetID, author: Author(name: author)))
resp checkBack()
get "/author/@author/threads":
@ -108,7 +144,7 @@ router twitblog:
# Entry points
proc startServer* =
createTweetTable()
createTweetTables()
defer: db.close()
let port = 8080.Port
let settings = newSettings(port=port)
@ -120,10 +156,10 @@ proc handleRenders* =
while true:
let t : ThreadRequest = chan.recv()
if threadExists(t.tweetID, t.author).isSome:
if threadExists(t.tweetID, t.author.name).isSome:
continue
let tweets = t.tweetID.renderThread(t.author)
let tweets = t.tweetID.renderThread(t.author.name)
if tweets.isSome:
insertThread(

19
src/tweetlogpkg/templates.nim

@ -1,12 +1,13 @@
import strformat
import karax / [karaxdsl, vdom]
proc layout(inner : VNode) : string =
proc layout(inner : VNode, title : string) : string =
let vnode = buildHtml(html):
head:
meta(charset="utf-8")
link(href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css", rel="stylesheet")
body:
h1(class="text-center"): text title
tdiv(class="text-center appearance-none"):
inner
"<!DOCTYPE html>\n" & $vnode
@ -23,12 +24,12 @@ proc tweetThread*(author : string,
ul(class="m-auto max-w-md list-decimal text-left"):
for tweet in tweets:
li: text tweet
result = $vnode.layout
result = $vnode.layout("Threads")
proc checkBack*() : string =
let vnode = buildHtml(tdiv):
h4: text "Check back later please"
result = $vnode.layout
result = $vnode.layout("Check back")
proc listThreads*(author : string,
threads : seq[string]) : string =
@ -39,7 +40,7 @@ proc listThreads*(author : string,
ul:
for thread in threads:
li: a(href=fmt"/thread/{author}/status/{thread}"): text thread
result = $vnode.layout
result = $vnode.layout("Threads")
# Main page
@ -64,7 +65,9 @@ proc submitThread() : VNode =
result = vnode
proc mainPage*(authors : seq[string]) : string =
let vnode = buildHtml(tdiv):
listAuthors(authors)
submitThread()
result = $vnode.layout
let vnode = buildHtml(tdiv(class="grid grid-cols-2 gap-4")):
tdiv:
listAuthors(authors)
tdiv:
submitThread()
result = $vnode.layout("Tweetlog")

Loading…
Cancel
Save