Add experimental GraphQL list members parser

This commit is contained in:
Zed 2022-01-26 17:57:46 +01:00
parent ae7091e69d
commit a54d6aa1eb
6 changed files with 65 additions and 34 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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