Skip to content

Commit

Permalink
fix(nitter): add graphql user search (#1047)
Browse files Browse the repository at this point in the history
* fix(nitter): add graphql user search

* fix(nitter): rm gitignore 2nd guest_accounts

* fix(nitter): keep query from user search in result. remove personal mods

* fix(nitter): removce useless line gitignore
  • Loading branch information
DrSocket authored Oct 30, 2023
1 parent 537af7f commit 735b30c
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 26 deletions.
28 changes: 16 additions & 12 deletions src/api.nim
Original file line number Diff line number Diff line change
Expand Up @@ -112,25 +112,29 @@ proc getGraphTweetSearch*(query: Query; after=""): Future[Timeline] {.async.} =
if after.len > 0:
variables["cursor"] = % after
let url = graphSearchTimeline ? {"variables": $variables, "features": gqlFeatures}
result = parseGraphSearch(await fetch(url, Api.search), after)
result = parseGraphSearch[Tweets](await fetch(url, Api.search), after)
result.query = query

proc getUserSearch*(query: Query; page="1"): Future[Result[User]] {.async.} =
proc getGraphUserSearch*(query: Query; after=""): Future[Result[User]] {.async.} =
if query.text.len == 0:
return Result[User](query: query, beginning: true)

let
page = if page.len == 0: "1" else: page
url = userSearch ? genParams({"q": query.text, "skip_status": "1", "page": page})
js = await fetchRaw(url, Api.userSearch)

result = parseUsers(js)
var
variables = %*{
"rawQuery": query.text,
"count": 20,
"product": "People",
"withDownvotePerspective": false,
"withReactionsMetadata": false,
"withReactionsPerspective": false
}
if after.len > 0:
variables["cursor"] = % after
result.beginning = false

let url = graphSearchTimeline ? {"variables": $variables, "features": gqlFeatures}
result = parseGraphSearch[User](await fetch(url, Api.search), after)
result.query = query
if page.len == 0:
result.bottom = "2"
elif page.allCharsInSet(Digits):
result.bottom = $(parseInt(page) + 1)

proc getPhotoRail*(name: string): Future[PhotoRail] {.async.} =
if name.len == 0: return
Expand Down
3 changes: 1 addition & 2 deletions src/consts.nim
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ const
activate* = $(api / "1.1/guest/activate.json")

photoRail* = api / "1.1/statuses/media_timeline.json"
userSearch* = api / "1.1/users/search.json"

graphql = api / "graphql"
graphUser* = graphql / "u7wQyGi6oExe8_TRWGMq4Q/UserResultByScreenNameQuery"
Expand All @@ -35,7 +34,7 @@ const
"include_user_entities": "1",
"include_ext_reply_count": "1",
"include_ext_is_blue_verified": "1",
#"include_ext_verified_type": "1",
# "include_ext_verified_type": "1",
"include_ext_media_color": "0",
"cards_platform": "Web-13",
"tweet_mode": "extended",
Expand Down
24 changes: 15 additions & 9 deletions src/parser.nim
Original file line number Diff line number Diff line change
Expand Up @@ -443,8 +443,8 @@ proc parseGraphTimeline*(js: JsonNode; root: string; after=""): Profile =
tweet.id = parseBiggestInt(entryId)
result.pinned = some tweet

proc parseGraphSearch*(js: JsonNode; after=""): Timeline =
result = Timeline(beginning: after.len == 0)
proc parseGraphSearch*[T: User | Tweets](js: JsonNode; after=""): Result[T] =
result = Result[T](beginning: after.len == 0)

let instructions = js{"data", "search_by_raw_query", "search_timeline", "timeline", "instructions"}
if instructions.len == 0:
Expand All @@ -455,13 +455,19 @@ proc parseGraphSearch*(js: JsonNode; after=""): Timeline =
if typ == "TimelineAddEntries":
for e in instruction{"entries"}:
let entryId = e{"entryId"}.getStr
if entryId.startsWith("tweet"):
with tweetRes, e{"content", "itemContent", "tweet_results", "result"}:
let tweet = parseGraphTweet(tweetRes, true)
if not tweet.available:
tweet.id = parseBiggestInt(entryId.getId())
result.content.add tweet
elif entryId.startsWith("cursor-bottom"):
when T is Tweets:
if entryId.startsWith("tweet"):
with tweetRes, e{"content", "itemContent", "tweet_results", "result"}:
let tweet = parseGraphTweet(tweetRes)
if not tweet.available:
tweet.id = parseBiggestInt(entryId.getId())
result.content.add tweet
elif T is User:
if entryId.startsWith("user"):
with userRes, e{"content", "itemContent"}:
result.content.add parseGraphUser(userRes)

if entryId.startsWith("cursor-bottom"):
result.bottom = e{"content", "value"}.getStr
elif typ == "TimelineReplaceEntry":
if instruction{"entry_id_to_replace"}.getStr.startsWith("cursor-bottom"):
Expand Down
2 changes: 1 addition & 1 deletion src/routes/search.nim
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ proc createSearchRouter*(cfg: Config) =
redirect("/" & q)
var users: Result[User]
try:
users = await getUserSearch(query, getCursor())
users = await getGraphUserSearch(query, getCursor())
except InternalError:
users = Result[User](beginning: true, query: query)
resp renderMain(renderUserSearch(users, prefs), request, cfg, prefs, title)
Expand Down
1 change: 0 additions & 1 deletion src/tokens.nim
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ proc getPoolJson*(): JsonNode =
Api.userRestId, Api.userScreenName,
Api.tweetResult,
Api.list, Api.listTweets, Api.listMembers, Api.listBySlug: 500
of Api.userSearch: 900
reqs = maxReqs - apiStatus.remaining

reqsPerApi[$api] = reqsPerApi.getOrDefault($api, 0) + reqs
Expand Down
1 change: 0 additions & 1 deletion src/types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ type
tweetResult
photoRail
search
userSearch
list
listBySlug
listMembers
Expand Down

0 comments on commit 735b30c

Please sign in to comment.