From a54d6aa1eb09a8bebc014e2120acb27b7aad4d0c Mon Sep 17 00:00:00 2001 From: Zed Date: Wed, 26 Jan 2022 17:57:46 +0100 Subject: [PATCH] Add experimental GraphQL list members parser --- src/api.nim | 2 +- src/experimental/parser/graphql.nim | 23 +++++++++++++-- src/experimental/types/graphlistmembers.nim | 31 +++++++++++++++++++++ src/experimental/types/graphql.nim | 12 -------- src/experimental/types/graphuser.nim | 12 ++++++++ src/parser.nim | 19 ------------- 6 files changed, 65 insertions(+), 34 deletions(-) create mode 100644 src/experimental/types/graphlistmembers.nim delete mode 100644 src/experimental/types/graphql.nim create mode 100644 src/experimental/types/graphuser.nim diff --git a/src/api.nim b/src/api.nim index 8c97493..8fdaf3d 100644 --- a/src/api.nim +++ b/src/api.nim @@ -37,7 +37,7 @@ proc getGraphListMembers*(list: List; after=""): Future[Result[User]] {.async.} "withSuperFollowsTweetFields": false } url = graphListMembers ? {"variables": $variables} - result = parseGraphListMembers(await fetch(url, Api.listMembers), after) + result = parseGraphListMembers(await fetchRaw(url, Api.listMembers), after) proc getListTimeline*(id: string; after=""): Future[Timeline] {.async.} = if id.len == 0: return diff --git a/src/experimental/parser/graphql.nim b/src/experimental/parser/graphql.nim index df5c40a..b00ab24 100644 --- a/src/experimental/parser/graphql.nim +++ b/src/experimental/parser/graphql.nim @@ -1,8 +1,27 @@ import jsony -import ../types/graphql, user -from ../../types import User +import user, ../types/[graphuser, graphlistmembers] +from ../../types import User, Result, Query, QueryKind proc parseGraphUser*(json: string): User = let raw = json.fromJson(GraphUser) result = toUser raw.data.user.result.legacy result.id = raw.data.user.result.restId + +proc parseGraphListMembers*(json, cursor: string): Result[User] = + result = Result[User]( + beginning: cursor.len == 0, + query: Query(kind: userList) + ) + + let raw = json.fromJson(GraphListMembers) + for instruction in raw.data.list.membersTimeline.timeline.instructions: + if instruction.kind == "TimelineAddEntries": + for entry in instruction.entries: + case entry.content.entryType + of TimelineTimelineItem: + let userResult = entry.content.itemContent.userResults.result + if userResult.restId.len > 0: + result.content.add toUser userResult.legacy + of TimelineTimelineCursor: + if entry.content.cursorType == "Bottom": + result.bottom = entry.content.value diff --git a/src/experimental/types/graphlistmembers.nim b/src/experimental/types/graphlistmembers.nim new file mode 100644 index 0000000..4cb3757 --- /dev/null +++ b/src/experimental/types/graphlistmembers.nim @@ -0,0 +1,31 @@ +import graphuser + +type + GraphListMembers* = object + data*: tuple[list: List] + + List = object + membersTimeline*: tuple[timeline: Timeline] + + Timeline = object + instructions*: seq[Instruction] + + Instruction = object + kind*: string + entries*: seq[tuple[content: Content]] + + ContentEntryType* = enum + TimelineTimelineItem + TimelineTimelineCursor + + Content = object + case entryType*: ContentEntryType + of TimelineTimelineItem: + itemContent*: tuple[userResults: UserData] + of TimelineTimelineCursor: + value*: string + cursorType*: string + +proc renameHook*(v: var Instruction; fieldName: var string) = + if fieldName == "type": + fieldName = "kind" diff --git a/src/experimental/types/graphql.nim b/src/experimental/types/graphql.nim deleted file mode 100644 index 6697d07..0000000 --- a/src/experimental/types/graphql.nim +++ /dev/null @@ -1,12 +0,0 @@ -import user - -type - GraphUserResult* = object - legacy*: RawUser - restId*: string - - GraphUserData* = object - result*: GraphUserResult - - GraphUser* = object - data*: tuple[user: GraphUserData] diff --git a/src/experimental/types/graphuser.nim b/src/experimental/types/graphuser.nim new file mode 100644 index 0000000..dded4eb --- /dev/null +++ b/src/experimental/types/graphuser.nim @@ -0,0 +1,12 @@ +import user + +type + GraphUser* = object + data*: tuple[user: UserData] + + UserData* = object + result*: UserResult + + UserResult = object + legacy*: RawUser + restId*: string diff --git a/src/parser.nim b/src/parser.nim index 177eaed..580f449 100644 --- a/src/parser.nim +++ b/src/parser.nim @@ -45,25 +45,6 @@ proc parseGraphList*(js: JsonNode): List = banner: list{"custom_banner_media", "media_info", "url"}.getImageStr ) -proc parseGraphListMembers*(js: JsonNode; cursor: string): Result[User] = - result = Result[User]( - beginning: cursor.len == 0, - query: Query(kind: userList) - ) - - if js.isNull: return - - let root = js{"data", "list", "members_timeline", "timeline", "instructions"} - for instruction in root: - if instruction{"type"}.getStr == "TimelineAddEntries": - for entry in instruction{"entries"}: - let content = entry{"content"} - if content{"entryType"}.getStr == "TimelineTimelineItem": - with legacy, content{"itemContent", "user_results", "result", "legacy"}: - result.content.add parseUser(legacy) - elif content{"cursorType"}.getStr == "Bottom": - result.bottom = content{"value"}.getStr - proc parsePoll(js: JsonNode): Poll = let vals = js{"binding_values"}