7 changed files with 105 additions and 67 deletions
@ -1 +1,2 @@ |
|||
switch("define", "ssl") |
|||
switch("threads", "on") |
|||
|
@ -1,34 +1,6 @@ |
|||
import twit2blogpkg/twitter, twit2blogpkg/help |
|||
import os, system, parseopt, strutils, tables |
|||
import twit2blogpkg/twitter, twit2blogpkg/server |
|||
import threadpool |
|||
|
|||
when isMainModule: |
|||
var args = initOptParser(commandLineParams().join(" ")) |
|||
var twitterParams = initTable[string, string]() |
|||
let validArgs = @["u", "t", "user", "thread"] |
|||
var currentKey : string |
|||
|
|||
while true: |
|||
args.next() |
|||
case args.kind |
|||
of cmdEnd: break |
|||
of cmdShortOption, cmdLongOption: |
|||
if (args.key == "help") or (args.key == "h"): |
|||
writeHelp() |
|||
if args.val == "": |
|||
continue |
|||
else: |
|||
if validArgs.contains(args.key): |
|||
twitterParams[args.key] = args.val |
|||
of cmdArgument: |
|||
if validArgs.contains(currentKey): |
|||
twitterParams[currentKey] = args.val |
|||
|
|||
if twitterParams.hasKey("u"): |
|||
twitterParams["user"] = twitterParams["u"] |
|||
if twitterParams.hasKey("t"): |
|||
twitterParams["thread"] = twitterParams["t"] |
|||
|
|||
if not (twitterParams.hasKey("user") and twitterParams.hasKey("thread")): |
|||
writeHelp() |
|||
|
|||
echo twitterParams["thread"].renderThread(twitterParams["user"]) |
|||
spawn handleRenders() |
|||
startServer() |
|||
|
@ -1,18 +0,0 @@ |
|||
import system |
|||
|
|||
const |
|||
help = """ |
|||
Usage: twit2blog [opts] |
|||
|
|||
Options: |
|||
-u, --user The screen name of the twitter user. E.g. If your twitter is https://twitter.com/foobar, then `foobar`. |
|||
-t, --thread The ID of the last tweet in your thread. E.g. 12345. |
|||
|
|||
For more information read the Github readme: |
|||
https://github.com/weskerfoot/Twit2Blog#readme |
|||
""" |
|||
|
|||
proc writeHelp*(quit=true) = |
|||
echo(help) |
|||
if quit: |
|||
quit(1) |
@ -0,0 +1,89 @@ |
|||
import strutils, sets, options, sugar, sequtils, asyncdispatch, threadpool, db_sqlite |
|||
import twitter |
|||
import xander |
|||
|
|||
# one thread just receives messages with thread ID / username |
|||
# thread then passes messages to worker threads in round-robin fashion |
|||
# worker threads gather thread contents, then update Redis DB (or sqlite) with thread ID mapped to content |
|||
# user can go back to page with thread ID / user combo (or unique ID we give them?) and see compiled thread |
|||
|
|||
type |
|||
ThreadRequest = object |
|||
tweetID: string |
|||
author: string |
|||
|
|||
type TwitterThread = ref object of RootObj |
|||
tweetID: string |
|||
author: string |
|||
tweets: string |
|||
|
|||
var chan : Channel[ThreadRequest] |
|||
|
|||
# Max 20 items processing |
|||
chan.open(20) |
|||
|
|||
var server = newAsyncHttpServer() |
|||
|
|||
let db = open("twit2blog.db", "", "", "") |
|||
|
|||
proc createTweetTable() = |
|||
db.exec(sql"""CREATE TABLE IF NOT EXISTS threads ( |
|||
id INTEGER PRIMARY KEY, |
|||
tid TEXT, |
|||
author TEXT, |
|||
tweets TEXT |
|||
)""") |
|||
|
|||
proc threadExists(threadID : string, author : string) : Option[TwitterThread] = |
|||
let row = db.getRow(sql"SELECT * FROM threads WHERE tid=? AND author=?", threadID, author) |
|||
|
|||
if row.all(col => col == ""): |
|||
return none(TwitterThread) |
|||
some( |
|||
TwitterThread(tweetID: row[1], |
|||
author: row[2], |
|||
tweets: row[3]) |
|||
) |
|||
|
|||
proc insertThread(thread : TwitterThread) = |
|||
db.exec(sql"INSERT INTO threads (tid, author, tweets) VALUES (?, ?, ?)", |
|||
thread.tweetID, |
|||
thread.author, |
|||
thread.tweets) |
|||
|
|||
get "/thread/:author/status/:threadID": |
|||
let threadID = data{"threadID"}.getStr() |
|||
let author = data{"author"}.getStr() |
|||
|
|||
let thread = threadExists(threadID, author) |
|||
|
|||
if thread.isSome: |
|||
respond thread.get.tweets |
|||
else: |
|||
chan.send(ThreadRequest(tweetID: data{"threadID"}.getStr(), author: data{"author"}.getStr())) |
|||
respond "Hang on, we're grabbing your thread :) Come back to this page later." |
|||
|
|||
proc startServer* = |
|||
createTweetTable() |
|||
defer: db.close() |
|||
runForever(8080) |
|||
|
|||
proc handleRenders* = |
|||
var processing = initHashSet[string]() |
|||
|
|||
while true: |
|||
let t : ThreadRequest = chan.recv() |
|||
|
|||
if processing.contains(t.author & t.tweetID): |
|||
continue |
|||
|
|||
processing.incl(t.author & t.tweetID) |
|||
|
|||
let tweets = t.tweetID.renderThread(t.author) |
|||
|
|||
if tweets.isSome: |
|||
insertThread( |
|||
TwitterThread(tweetID: t.tweetID, |
|||
author: t.author, |
|||
tweets: tweets.get.join("\n")) |
|||
) |
Loading…
Reference in new issue