fix(nitter): add graphql user search (#1047)
* 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
This commit is contained in:
		
							parent
							
								
									537af7fd5e
								
							
						
					
					
						commit
						735b30c2da
					
				
					 6 changed files with 33 additions and 26 deletions
				
			
		
							
								
								
									
										28
									
								
								src/api.nim
									
										
									
									
									
								
							
							
						
						
									
										28
									
								
								src/api.nim
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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"
 | 
			
		||||
| 
						 | 
				
			
			@ -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",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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:
 | 
			
		||||
| 
						 | 
				
			
			@ -455,13 +455,19 @@ proc parseGraphSearch*(js: JsonNode; after=""): Timeline =
 | 
			
		|||
    if typ == "TimelineAddEntries":
 | 
			
		||||
      for e in instruction{"entries"}:
 | 
			
		||||
        let entryId = e{"entryId"}.getStr
 | 
			
		||||
        when T is Tweets:
 | 
			
		||||
          if entryId.startsWith("tweet"):
 | 
			
		||||
            with tweetRes, e{"content", "itemContent", "tweet_results", "result"}:
 | 
			
		||||
            let tweet = parseGraphTweet(tweetRes, true)
 | 
			
		||||
              let tweet = parseGraphTweet(tweetRes)
 | 
			
		||||
              if not tweet.available:
 | 
			
		||||
                tweet.id = parseBiggestInt(entryId.getId())
 | 
			
		||||
              result.content.add tweet
 | 
			
		||||
        elif entryId.startsWith("cursor-bottom"):
 | 
			
		||||
        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"):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,7 +19,6 @@ type
 | 
			
		|||
    tweetResult
 | 
			
		||||
    photoRail
 | 
			
		||||
    search
 | 
			
		||||
    userSearch
 | 
			
		||||
    list
 | 
			
		||||
    listBySlug
 | 
			
		||||
    listMembers
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue