Skip to content

Commit

Permalink
Add experimental GraphQL user parser
Browse files Browse the repository at this point in the history
  • Loading branch information
zedeus committed Jan 26, 2022
1 parent 535f693 commit ae7091e
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 34 deletions.
6 changes: 3 additions & 3 deletions src/api.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
import asyncdispatch, httpclient, uri, strutils, sequtils, sugar
import packedjson
import types, query, formatters, consts, apiutils, parser
import experimental/parser/user
import experimental/parser/[user, graphql]

proc getGraphUser*(id: string): Future[User] {.async.} =
if id.len == 0 or id.any(c => not c.isDigit): return
let
variables = %*{"userId": id, "withSuperFollowsUserFields": true}
js = await fetch(graphUser ? {"variables": $variables}, Api.userRestId)
result = parseGraphUser(js, id)
js = await fetchRaw(graphUser ? {"variables": $variables}, Api.userRestId)
result = parseGraphUser(js)

proc getGraphListBySlug*(name, list: string): Future[List] {.async.} =
let
Expand Down
8 changes: 8 additions & 0 deletions src/experimental/parser/graphql.nim
Original file line number Diff line number Diff line change
@@ -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
46 changes: 25 additions & 21 deletions src/experimental/parser/user.nim
Original file line number Diff line number Diff line change
Expand Up @@ -37,31 +37,35 @@ proc getBanner(user: RawUser): string =
if user.profileLinkColor.len > 0:
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 =
handleErrors:
case error.code
of suspended: return User(username: username, suspended: true)
of userNotFound: return
else: echo "[error - parseUser]: ", error

let user = 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)
result = toUser json.fromJson(RawUser)
12 changes: 12 additions & 0 deletions src/experimental/types/graphql.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import user

type
GraphUserResult* = object
legacy*: RawUser
restId*: string

GraphUserData* = object
result*: GraphUserResult

GraphUser* = object
data*: tuple[user: GraphUserData]
1 change: 1 addition & 0 deletions src/experimental/types/user.nim
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type
profileBannerUrl*: string
profileImageUrlHttps*: string
profileLinkColor*: string
pinnedTweetIdsStr*: seq[string]

Entities* = object
url*: Urls
Expand Down
10 changes: 0 additions & 10 deletions src/parser.nim
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,6 @@ proc parseUser(js: JsonNode; id=""): User =

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 =
if js.isNull: return

Expand Down

0 comments on commit ae7091e

Please sign in to comment.