Просмотр исходного кода

Add experimental GraphQL user parser

Zed 4 лет назад
Родитель
Сommit
ae7091e69d

+ 3 - 3
src/api.nim

@@ -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

+ 8 - 0
src/experimental/parser/graphql.nim

@@ -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

+ 25 - 21
src/experimental/parser/user.nim

@@ -37,6 +37,30 @@ 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
@@ -44,24 +68,4 @@ proc parseUser*(json: string; username=""): User =
     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 - 0
src/experimental/types/graphql.nim

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

+ 1 - 0
src/experimental/types/user.nim

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

+ 0 - 10
src/parser.nim

@@ -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