Merge branch 'rework-list'
This commit is contained in:
commit
5501752fdb
|
@ -9,13 +9,13 @@ proc getGraphProfile*(username: string): Future[Profile] {.async.} =
|
||||||
js = await fetch(graphUser ? {"variables": $variables})
|
js = await fetch(graphUser ? {"variables": $variables})
|
||||||
result = parseGraphProfile(js, username)
|
result = parseGraphProfile(js, username)
|
||||||
|
|
||||||
proc getGraphList*(name, list: string): Future[List] {.async.} =
|
proc getGraphListBySlug*(name, list: string): Future[List] {.async.} =
|
||||||
let
|
let
|
||||||
variables = %*{"screenName": name, "listSlug": list, "withHighlightedLabel": false}
|
variables = %*{"screenName": name, "listSlug": list, "withHighlightedLabel": false}
|
||||||
js = await fetch(graphList ? {"variables": $variables})
|
js = await fetch(graphList ? {"variables": $variables})
|
||||||
result = parseGraphList(js)
|
result = parseGraphList(js)
|
||||||
|
|
||||||
proc getGraphListById*(id: string): Future[List] {.async.} =
|
proc getGraphList*(id: string): Future[List] {.async.} =
|
||||||
let
|
let
|
||||||
variables = %*{"listId": id, "withHighlightedLabel": false}
|
variables = %*{"listId": id, "withHighlightedLabel": false}
|
||||||
js = await fetch(graphListId ? {"variables": $variables})
|
js = await fetch(graphListId ? {"variables": $variables})
|
||||||
|
|
|
@ -73,9 +73,9 @@ proc parseGraphList*(js: JsonNode): List =
|
||||||
|
|
||||||
result = List(
|
result = List(
|
||||||
id: list{"id_str"}.getStr,
|
id: list{"id_str"}.getStr,
|
||||||
name: list{"name"}.getStr.replace(' ', '-'),
|
name: list{"name"}.getStr,
|
||||||
username: list{"user", "legacy", "screen_name"}.getStr,
|
username: list{"user", "legacy", "screen_name"}.getStr,
|
||||||
userId: list{"user", "legacy", "id_str"}.getStr,
|
userId: list{"user", "rest_id"}.getStr,
|
||||||
description: list{"description"}.getStr,
|
description: list{"description"}.getStr,
|
||||||
members: list{"member_count"}.getInt,
|
members: list{"member_count"}.getInt,
|
||||||
banner: list{"custom_banner_media", "media_info", "url"}.getImageStr
|
banner: list{"custom_banner_media", "media_info", "url"}.getImageStr
|
||||||
|
|
|
@ -58,7 +58,7 @@ proc initRedisPool*(cfg: Config) {.async.} =
|
||||||
|
|
||||||
template pidKey(name: string): string = "pid:" & $(hash(name) div 1_000_000)
|
template pidKey(name: string): string = "pid:" & $(hash(name) div 1_000_000)
|
||||||
template profileKey(name: string): string = "p:" & name
|
template profileKey(name: string): string = "p:" & name
|
||||||
template listKey(l: List): string = toLower("l:" & l.username & '/' & l.name)
|
template listKey(l: List): string = "l:" & l.id
|
||||||
|
|
||||||
proc get(query: string): Future[string] {.async.} =
|
proc get(query: string): Future[string] {.async.} =
|
||||||
pool.withAcquire(r):
|
pool.withAcquire(r):
|
||||||
|
@ -131,17 +131,17 @@ proc getCachedPhotoRail*(name: string): Future[PhotoRail] {.async.} =
|
||||||
result = await getPhotoRail(name)
|
result = await getPhotoRail(name)
|
||||||
await cache(result, name)
|
await cache(result, name)
|
||||||
|
|
||||||
proc getCachedList*(username=""; name=""; id=""): Future[List] {.async.} =
|
proc getCachedList*(username=""; slug=""; id=""): Future[List] {.async.} =
|
||||||
let list = if id.len > 0: redisNil
|
let list = if id.len == 0: redisNil
|
||||||
else: await get(toLower("l:" & username & '/' & name))
|
else: await get("l:" & id)
|
||||||
|
|
||||||
if list != redisNil:
|
if list != redisNil:
|
||||||
result = fromFlatty(uncompress(list), List)
|
result = fromFlatty(uncompress(list), List)
|
||||||
else:
|
else:
|
||||||
if id.len > 0:
|
if id.len > 0:
|
||||||
result = await getGraphListById(id)
|
result = await getGraphList(id)
|
||||||
else:
|
else:
|
||||||
result = await getGraphList(username, name)
|
result = await getGraphListBySlug(username, slug)
|
||||||
await cache(result)
|
await cache(result)
|
||||||
|
|
||||||
proc getCachedRss*(key: string): Future[Rss] {.async.} =
|
proc getCachedRss*(key: string): Future[Rss] {.async.} =
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
import strutils
|
import strutils, uri
|
||||||
|
|
||||||
import jester
|
import jester
|
||||||
|
|
||||||
|
@ -8,41 +8,44 @@ import ".."/[types, redis_cache, api]
|
||||||
import ../views/[general, timeline, list]
|
import ../views/[general, timeline, list]
|
||||||
export getListTimeline, getGraphList
|
export getListTimeline, getGraphList
|
||||||
|
|
||||||
template respList*(list, timeline, vnode: typed) =
|
template respList*(list, timeline, title, vnode: typed) =
|
||||||
if list.id.len == 0:
|
if list.id.len == 0:
|
||||||
resp Http404, showError("List \"" & @"list" & "\" not found", cfg)
|
resp Http404, showError("List \"" & @"id" & "\" not found", cfg)
|
||||||
|
|
||||||
let
|
let
|
||||||
html = renderList(vnode, timeline.query, list)
|
html = renderList(vnode, timeline.query, list)
|
||||||
rss = "/$1/lists/$2/rss" % [@"name", @"list"]
|
rss = "/i/lists/$1/rss" % [@"id"]
|
||||||
|
|
||||||
resp renderMain(html, request, cfg, prefs, rss=rss, banner=list.banner)
|
resp renderMain(html, request, cfg, prefs, titleText=title, rss=rss, banner=list.banner)
|
||||||
|
|
||||||
proc createListRouter*(cfg: Config) =
|
proc createListRouter*(cfg: Config) =
|
||||||
router list:
|
router list:
|
||||||
get "/@name/lists/@list/?":
|
get "/@name/lists/@slug/?":
|
||||||
cond '.' notin @"name"
|
cond '.' notin @"name"
|
||||||
cond @"name" != "i"
|
cond @"name" != "i"
|
||||||
|
cond @"slug" != "memberships"
|
||||||
let
|
let
|
||||||
prefs = cookiePrefs()
|
slug = decodeUrl(@"slug")
|
||||||
list = await getCachedList(@"name", @"list")
|
list = await getCachedList(@"name", slug)
|
||||||
timeline = await getListTimeline(list.id, getCursor())
|
if list.id.len == 0:
|
||||||
vnode = renderTimelineTweets(timeline, prefs, request.path)
|
resp Http404, showError("List \"" & @"slug" & "\" not found", cfg)
|
||||||
respList(list, timeline, vnode)
|
redirect("/i/lists/" & list.id)
|
||||||
|
|
||||||
get "/@name/lists/@list/members":
|
|
||||||
cond '.' notin @"name"
|
|
||||||
cond @"name" != "i"
|
|
||||||
let
|
|
||||||
prefs = cookiePrefs()
|
|
||||||
list = await getCachedList(@"name", @"list")
|
|
||||||
members = await getListMembers(list, getCursor())
|
|
||||||
respList(list, members, renderTimelineUsers(members, prefs, request.path))
|
|
||||||
|
|
||||||
get "/i/lists/@id/?":
|
get "/i/lists/@id/?":
|
||||||
cond '.' notin @"id"
|
cond '.' notin @"id"
|
||||||
let list = await getCachedList(id=(@"id"))
|
let
|
||||||
if list.id.len == 0:
|
prefs = cookiePrefs()
|
||||||
resp Http404
|
list = await getCachedList(id=(@"id"))
|
||||||
await cache(list)
|
title = "@" & list.username & "/" & list.name
|
||||||
redirect("/" & list.username & "/lists/" & list.name)
|
timeline = await getListTimeline(list.id, getCursor())
|
||||||
|
vnode = renderTimelineTweets(timeline, prefs, request.path)
|
||||||
|
respList(list, timeline, title, vnode)
|
||||||
|
|
||||||
|
get "/i/lists/@id/members":
|
||||||
|
cond '.' notin @"id"
|
||||||
|
let
|
||||||
|
prefs = cookiePrefs()
|
||||||
|
list = await getCachedList(id=(@"id"))
|
||||||
|
title = "@" & list.username & "/" & list.name
|
||||||
|
members = await getListMembers(list, getCursor())
|
||||||
|
respList(list, members, title, renderTimelineUsers(members, prefs, request.path))
|
||||||
|
|
|
@ -62,7 +62,7 @@ proc createRssRouter*(cfg: Config) =
|
||||||
|
|
||||||
let
|
let
|
||||||
cursor = getCursor()
|
cursor = getCursor()
|
||||||
key = $hash(genQueryUrl(query)) & cursor
|
key = "search:" & $hash(genQueryUrl(query)) & ":" & cursor
|
||||||
|
|
||||||
var rss = await getCachedRss(key)
|
var rss = await getCachedRss(key)
|
||||||
if rss.cursor.len > 0:
|
if rss.cursor.len > 0:
|
||||||
|
@ -82,7 +82,7 @@ proc createRssRouter*(cfg: Config) =
|
||||||
let
|
let
|
||||||
cursor = getCursor()
|
cursor = getCursor()
|
||||||
name = @"name"
|
name = @"name"
|
||||||
key = name & cursor
|
key = "twitter:" & name & ":" & cursor
|
||||||
|
|
||||||
var rss = await getCachedRss(key)
|
var rss = await getCachedRss(key)
|
||||||
if rss.cursor.len > 0:
|
if rss.cursor.len > 0:
|
||||||
|
@ -105,9 +105,9 @@ proc createRssRouter*(cfg: Config) =
|
||||||
of "search": initQuery(params(request), name=name)
|
of "search": initQuery(params(request), name=name)
|
||||||
else: Query(fromUser: @[name])
|
else: Query(fromUser: @[name])
|
||||||
|
|
||||||
var key = @"name" & "/" & @"tab"
|
var key = @"tab" & ":" & @"name" & ":"
|
||||||
if @"tab" == "search":
|
if @"tab" == "search":
|
||||||
key &= $hash(genQueryUrl(query))
|
key &= $hash(genQueryUrl(query)) & "/"
|
||||||
key &= getCursor()
|
key &= getCursor()
|
||||||
|
|
||||||
var rss = await getCachedRss(key)
|
var rss = await getCachedRss(key)
|
||||||
|
@ -119,19 +119,20 @@ proc createRssRouter*(cfg: Config) =
|
||||||
await cacheRss(key, rss)
|
await cacheRss(key, rss)
|
||||||
respRss(rss)
|
respRss(rss)
|
||||||
|
|
||||||
get "/@name/lists/@list/rss":
|
get "/i/lists/@id/rss":
|
||||||
cond cfg.enableRss
|
cond cfg.enableRss
|
||||||
cond '.' notin @"name"
|
|
||||||
let
|
let
|
||||||
cursor = getCursor()
|
cursor = getCursor()
|
||||||
key = @"name" & "/" & @"list" & cursor
|
key =
|
||||||
|
if cursor.len == 0: "lists:" & @"id"
|
||||||
|
else: "lists:" & @"id" & ":" & cursor
|
||||||
|
|
||||||
var rss = await getCachedRss(key)
|
var rss = await getCachedRss(key)
|
||||||
if rss.cursor.len > 0:
|
if rss.cursor.len > 0:
|
||||||
respRss(rss)
|
respRss(rss)
|
||||||
|
|
||||||
let
|
let
|
||||||
list = await getCachedList(@"name", @"list")
|
list = await getCachedList(id=(@"id"))
|
||||||
timeline = await getListTimeline(list.id, cursor)
|
timeline = await getListTimeline(list.id, cursor)
|
||||||
rss.cursor = timeline.bottom
|
rss.cursor = timeline.bottom
|
||||||
rss.feed = compress renderListRss(timeline.content, list, cfg)
|
rss.feed = compress renderListRss(timeline.content, list, cfg)
|
||||||
|
|
|
@ -25,5 +25,5 @@ proc renderList*(body: VNode; query: Query; list: List): VNode =
|
||||||
tdiv(class="timeline-description"):
|
tdiv(class="timeline-description"):
|
||||||
text list.description
|
text list.description
|
||||||
|
|
||||||
renderListTabs(query, &"/{list.username}/lists/{list.name}")
|
renderListTabs(query, &"/i/lists/{list.id}")
|
||||||
body
|
body
|
||||||
|
|
|
@ -109,7 +109,7 @@ ${renderRssTweets(timeline.content, cfg)}
|
||||||
#end proc
|
#end proc
|
||||||
#
|
#
|
||||||
#proc renderListRss*(tweets: seq[Tweet]; list: List; cfg: Config): string =
|
#proc renderListRss*(tweets: seq[Tweet]; list: List; cfg: Config): string =
|
||||||
#let link = &"{getUrlPrefix(cfg)}/{list.username}/lists/{list.name}"
|
#let link = &"{getUrlPrefix(cfg)}/i/lists/{list.id}"
|
||||||
#result = ""
|
#result = ""
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
|
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
|
||||||
|
|
Loading…
Reference in New Issue