mirror of
https://github.com/zedeus/nitter
synced 2026-09-25 23:09:20 +00:00
parent
bd9d492d36
commit
35882ed88d
16 changed files with 1192 additions and 24 deletions
87
src/experimental/parser/article.nim
Normal file
87
src/experimental/parser/article.nim
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
import std/[strutils, tables, times, options]
|
||||
import jsony
|
||||
import utils, graphql, ../types/article
|
||||
from ../../types import Article, ArticleParagraph, ArticleEntity, ArticleMedia,
|
||||
User, TweetStats
|
||||
|
||||
proc parseGraphArticle*(json: string): Article =
|
||||
if json.len == 0 or json[0] != '{':
|
||||
return
|
||||
|
||||
var raw: GraphArticle
|
||||
try:
|
||||
raw = json.fromJson(GraphArticle)
|
||||
except CatchableError:
|
||||
return
|
||||
|
||||
let
|
||||
tweet = raw.data.tweetResult.result
|
||||
article = tweet.article.articleResults.result
|
||||
|
||||
if article.title.len == 0:
|
||||
return
|
||||
|
||||
let publishedAt = article.metadata.firstPublishedAtSecs
|
||||
var articleTime: DateTime
|
||||
if publishedAt > 0:
|
||||
articleTime = publishedAt.int64.fromUnix.utc
|
||||
elif tweet.legacy.createdAt.len > 0:
|
||||
articleTime = parseTwitterDate(tweet.legacy.createdAt)
|
||||
|
||||
result = Article(
|
||||
title: article.title,
|
||||
coverImage: getImageUrl(article.coverMedia.mediaInfo.originalImgUrl),
|
||||
time: articleTime,
|
||||
user: parseUserResult(tweet.core.userResults.result),
|
||||
)
|
||||
|
||||
result.stats = TweetStats(
|
||||
replies: tweet.legacy.replyCount,
|
||||
retweets: tweet.legacy.retweetCount,
|
||||
likes: tweet.legacy.favoriteCount,
|
||||
)
|
||||
if tweet.views.count.len > 0:
|
||||
try: result.stats.views = parseInt(tweet.views.count)
|
||||
except ValueError: discard
|
||||
|
||||
for blk in article.contentState.blocks:
|
||||
result.paragraphs.add ArticleParagraph(
|
||||
text: blk.text,
|
||||
kind: blk.blockKind,
|
||||
inlineStyles: blk.inlineStyleRanges,
|
||||
entityRanges: blk.entityRanges,
|
||||
)
|
||||
|
||||
for entry in article.contentState.entityMap:
|
||||
let key = try: parseInt(entry.key) except ValueError: continue
|
||||
var entity = ArticleEntity(kind: entry.value.entityKind)
|
||||
case entity.kind
|
||||
of "LINK": entity.url = entry.value.data.url
|
||||
of "MEDIA":
|
||||
for mi in entry.value.data.mediaItems:
|
||||
entity.mediaIds.add mi.mediaId
|
||||
of "TWEET": entity.tweetId = entry.value.data.tweetId
|
||||
of "MARKDOWN": entity.markdown = entry.value.data.markdown
|
||||
else: discard
|
||||
result.entities[key] = entity
|
||||
|
||||
for me in article.mediaEntities:
|
||||
let typeName = me.mediaInfo.typeName
|
||||
var media = ArticleMedia(kind: typeName)
|
||||
if me.mediaInfo.videoInfo.isSome:
|
||||
let variants = me.mediaInfo.videoInfo.get.variants
|
||||
case typeName
|
||||
of "ApiGif":
|
||||
if variants.len > 0:
|
||||
media.url = variants[0].url
|
||||
of "ApiVideo":
|
||||
var bestBitrate = -1
|
||||
for v in variants:
|
||||
if v.bitrate > bestBitrate:
|
||||
bestBitrate = v.bitrate
|
||||
media.url = v.url
|
||||
else: discard
|
||||
elif typeName == "ApiImage":
|
||||
media.url = getImageUrl(me.mediaInfo.originalImgUrl)
|
||||
result.media[me.mediaId] = media
|
||||
Loading…
Reference in a new issue