mirror of
https://github.com/zedeus/nitter.git
synced 2024-12-23 04:15:38 +00:00
Add experimental GraphQL list members parser
This commit is contained in:
parent
ae7091e69d
commit
a54d6aa1eb
|
@ -37,7 +37,7 @@ proc getGraphListMembers*(list: List; after=""): Future[Result[User]] {.async.}
|
||||||
"withSuperFollowsTweetFields": false
|
"withSuperFollowsTweetFields": false
|
||||||
}
|
}
|
||||||
url = graphListMembers ? {"variables": $variables}
|
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.} =
|
proc getListTimeline*(id: string; after=""): Future[Timeline] {.async.} =
|
||||||
if id.len == 0: return
|
if id.len == 0: return
|
||||||
|
|
|
@ -1,8 +1,27 @@
|
||||||
import jsony
|
import jsony
|
||||||
import ../types/graphql, user
|
import user, ../types/[graphuser, graphlistmembers]
|
||||||
from ../../types import User
|
from ../../types import User, Result, Query, QueryKind
|
||||||
|
|
||||||
proc parseGraphUser*(json: string): User =
|
proc parseGraphUser*(json: string): User =
|
||||||
let raw = json.fromJson(GraphUser)
|
let raw = json.fromJson(GraphUser)
|
||||||
result = toUser raw.data.user.result.legacy
|
result = toUser raw.data.user.result.legacy
|
||||||
result.id = raw.data.user.result.restId
|
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
|
||||||
|
|
31
src/experimental/types/graphlistmembers.nim
Normal file
31
src/experimental/types/graphlistmembers.nim
Normal 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"
|
|
@ -1,12 +0,0 @@
|
||||||
import user
|
|
||||||
|
|
||||||
type
|
|
||||||
GraphUserResult* = object
|
|
||||||
legacy*: RawUser
|
|
||||||
restId*: string
|
|
||||||
|
|
||||||
GraphUserData* = object
|
|
||||||
result*: GraphUserResult
|
|
||||||
|
|
||||||
GraphUser* = object
|
|
||||||
data*: tuple[user: GraphUserData]
|
|
12
src/experimental/types/graphuser.nim
Normal file
12
src/experimental/types/graphuser.nim
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import user
|
||||||
|
|
||||||
|
type
|
||||||
|
GraphUser* = object
|
||||||
|
data*: tuple[user: UserData]
|
||||||
|
|
||||||
|
UserData* = object
|
||||||
|
result*: UserResult
|
||||||
|
|
||||||
|
UserResult = object
|
||||||
|
legacy*: RawUser
|
||||||
|
restId*: string
|
|
@ -45,25 +45,6 @@ proc parseGraphList*(js: JsonNode): List =
|
||||||
banner: list{"custom_banner_media", "media_info", "url"}.getImageStr
|
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 =
|
proc parsePoll(js: JsonNode): Poll =
|
||||||
let vals = js{"binding_values"}
|
let vals = js{"binding_values"}
|
||||||
|
|
Loading…
Reference in a new issue