Add experimental GraphQL user parser

This commit is contained in:
Zed 2022-01-26 17:24:03 +01:00
parent 535f6936b9
commit ae7091e69d
6 changed files with 49 additions and 34 deletions

View file

@ -2,14 +2,14 @@
import asyncdispatch, httpclient, uri, strutils, sequtils, sugar import asyncdispatch, httpclient, uri, strutils, sequtils, sugar
import packedjson import packedjson
import types, query, formatters, consts, apiutils, parser import types, query, formatters, consts, apiutils, parser
import experimental/parser/user import experimental/parser/[user, graphql]
proc getGraphUser*(id: string): Future[User] {.async.} = proc getGraphUser*(id: string): Future[User] {.async.} =
if id.len == 0 or id.any(c => not c.isDigit): return if id.len == 0 or id.any(c => not c.isDigit): return
let let
variables = %*{"userId": id, "withSuperFollowsUserFields": true} variables = %*{"userId": id, "withSuperFollowsUserFields": true}
js = await fetch(graphUser ? {"variables": $variables}, Api.userRestId) js = await fetchRaw(graphUser ? {"variables": $variables}, Api.userRestId)
result = parseGraphUser(js, id) result = parseGraphUser(js)
proc getGraphListBySlug*(name, list: string): Future[List] {.async.} = proc getGraphListBySlug*(name, list: string): Future[List] {.async.} =
let let

View file

@ -0,0 +1,8 @@
import jsony
import ../types/graphql, user
from ../../types import User
proc parseGraphUser*(json: string): User =
let raw = json.fromJson(GraphUser)
result = toUser raw.data.user.result.legacy
result.id = raw.data.user.result.restId

View file

@ -37,6 +37,30 @@ proc getBanner(user: RawUser): string =
if user.profileLinkColor.len > 0: if user.profileLinkColor.len > 0:
return '#' & user.profileLinkColor return '#' & user.profileLinkColor
proc toUser*(raw: RawUser): User =
result = User(
id: raw.idStr,
username: raw.screenName,
fullname: raw.name,
location: raw.location,
bio: raw.description,
following: raw.friendsCount,
followers: raw.followersCount,
tweets: raw.statusesCount,
likes: raw.favouritesCount,
media: raw.mediaCount,
verified: raw.verified,
protected: raw.protected,
joinDate: parseTwitterDate(raw.createdAt),
banner: getBanner(raw),
userPic: getImageUrl(raw.profileImageUrlHttps).replace("_normal", "")
)
if raw.pinnedTweetIdsStr.len > 0:
result.pinnedTweet = parseBiggestInt(raw.pinnedTweetIdsStr[0])
result.expandUserEntities(raw)
proc parseUser*(json: string; username=""): User = proc parseUser*(json: string; username=""): User =
handleErrors: handleErrors:
case error.code case error.code
@ -44,24 +68,4 @@ proc parseUser*(json: string; username=""): User =
of userNotFound: return of userNotFound: return
else: echo "[error - parseUser]: ", error else: echo "[error - parseUser]: ", error
let user = json.fromJson(RawUser) result = toUser json.fromJson(RawUser)
result = User(
id: user.idStr,
username: user.screenName,
fullname: user.name,
location: user.location,
bio: user.description,
following: user.friendsCount,
followers: user.followersCount,
tweets: user.statusesCount,
likes: user.favouritesCount,
media: user.mediaCount,
verified: user.verified,
protected: user.protected,
joinDate: parseTwitterDate(user.createdAt),
banner: getBanner(user),
userPic: getImageUrl(user.profileImageUrlHttps).replace("_normal", "")
)
result.expandUserEntities(user)

View file

@ -0,0 +1,12 @@
import user
type
GraphUserResult* = object
legacy*: RawUser
restId*: string
GraphUserData* = object
result*: GraphUserResult
GraphUser* = object
data*: tuple[user: GraphUserData]

View file

@ -19,6 +19,7 @@ type
profileBannerUrl*: string profileBannerUrl*: string
profileImageUrlHttps*: string profileImageUrlHttps*: string
profileLinkColor*: string profileLinkColor*: string
pinnedTweetIdsStr*: seq[string]
Entities* = object Entities* = object
url*: Urls url*: Urls

View file

@ -26,16 +26,6 @@ proc parseUser(js: JsonNode; id=""): User =
result.expandUserEntities(js) result.expandUserEntities(js)
proc parseGraphUser*(js: JsonNode; id: string): User =
if js.isNull: return
with user, js{"data", "user", "result", "legacy"}:
result = parseUser(user, id)
with pinned, user{"pinned_tweet_ids_str"}:
if pinned.kind == JArray and pinned.len > 0:
result.pinnedTweet = parseBiggestInt(pinned[0].getStr)
proc parseGraphList*(js: JsonNode): List = proc parseGraphList*(js: JsonNode): List =
if js.isNull: return if js.isNull: return