nitter/src/api/search.nim

54 lines
1.7 KiB
Nim
Raw Normal View History

2019-09-06 01:37:12 +00:00
import httpclient, asyncdispatch, htmlparser
import strutils, json, xmltree, uri
2019-09-06 01:37:12 +00:00
import ".."/[types, parser, parserutils, query]
import utils, consts, timeline
2019-09-06 01:37:12 +00:00
2019-09-20 13:03:18 +00:00
proc getResult*[T](json: JsonNode; query: Query; after: string): Result[T] =
if json == nil: return Result[T](beginning: true, query: query)
2019-09-13 20:24:58 +00:00
Result[T](
hasMore: json{"has_more_items"}.getBool(false),
maxId: json{"max_position"}.getStr(""),
minId: json{"min_position"}.getStr(""),
2019-09-19 00:23:22 +00:00
query: query,
2019-09-13 20:24:58 +00:00
beginning: after.len == 0
)
proc getSearch*[T](query: Query; after, agent: string;
media=true): Future[Result[T]] {.async.} =
2019-09-13 20:24:58 +00:00
let
kind = if query.kind == users: "users" else: "tweets"
2019-09-13 20:24:58 +00:00
param = genQueryParam(query)
encoded = encodeUrl(param, usePlus=false)
2019-10-02 08:13:17 +00:00
referer = base / ("search?f=$1&q=$2&src=typd" % [kind, encoded])
2020-01-22 13:01:27 +00:00
headers = genHeaders(agent, referer, auth=true, xml=true)
2019-09-13 20:24:58 +00:00
params = {
"f": kind,
"vertical": "default",
"q": param,
"src": "typd",
"include_available_features": "1",
"include_entities": "1",
"max_position": if after.len > 0: after else: "0",
2019-09-13 20:24:58 +00:00
"reset_error_state": "false"
}
2019-09-06 01:37:12 +00:00
2019-09-20 13:03:26 +00:00
if param in ["include:nativeretweets", "-filter:nativeretweets", ""]:
return Result[T](query: query, beginning: true)
2019-09-06 01:37:12 +00:00
let json = await fetchJson(base / searchUrl ? params, headers)
2019-09-13 20:24:58 +00:00
result = getResult[T](json, query, after)
2019-09-20 23:08:30 +00:00
if json == nil or not json.hasKey("items_html"): return
2019-09-13 20:24:58 +00:00
when T is Tweet:
result = await finishTimeline(json, query, after, agent, media)
2019-09-13 20:24:58 +00:00
elif T is Profile:
2019-09-20 13:03:18 +00:00
let html = json["items_html"].to(string)
result.hasMore = html != "\n"
for p in parseHtml(html).selectAll(".js-stream-item"):
2019-09-13 20:24:58 +00:00
result.content.add parsePopupProfile(p, ".ProfileCard")