1
0
Fork 0
mirror of https://github.com/zedeus/nitter.git synced 2025-04-21 08:24:05 +00:00

fix: build errors

This commit is contained in:
guanbinrui 2025-04-01 23:08:11 +08:00
parent aaa11d3059
commit 25a45b9447
No known key found for this signature in database
GPG key ID: 849DB262B0F9CFE6
5 changed files with 67 additions and 108 deletions

View file

@ -1,15 +1,15 @@
# SPDX-License-Identifier: AGPL-3.0-only
import asyncdispatch
import json
import packedjson
import jester
import router_utils, timeline
import ".."/routes/[router_utils]
import "../jsons/timeline"
proc createJsonApiHealthRouter*(cfg: Config) =
router jsonapi:
get "/hello":
router jsonapi_health:
get "/api/health":
cond cfg.enableJsonApi
let headers = {"Content-Type": "application/json; charset=utf-8"}
resp Http200, headers, """{"message": "Hello, world"}"""
resp Http200, headers, """{"message": "OK"}"""

View file

@ -1,11 +1,15 @@
# SPDX-License-Identifier: AGPL-3.0-only
import json
import asyncdispatch
import packedjson
import renderutils
import ".."/[types]
import jester
import timeline
import ".."/routes/[router_utils]
import ".."/[types, redis_cache, api]
proc formatListAsJson*(list: List): JsonNode =
result = %*{
return %*{
"id": list.id,
"name": list.name,
"userId": list.userId,
@ -17,17 +21,18 @@ proc formatListAsJson*(list: List): JsonNode =
proc createJsonApiListRouter*(cfg: Config) =
router jsonapi_list:
get "/api/@name/lists/@slug/?":
cond cfg.enableJsonApi
cond '.' notin @"name"
cond @"name" != "i"
cond @"slug" != "memberships"
let
slug = decodeUrl(@"slug")
list = await getCachedList(@"name", slug)
if list.id.len == 0:
resp Http404, showError(&"""List "{@"slug"}" not found""", cfg)
redirect(&"/api/i/lists/{list.id}")
# get "/api/@name/lists/@slug/?":
# cond cfg.enableJsonApi
# cond '.' notin @"name"
# cond @"name" != "i"
# cond @"slug" != "memberships"
# let
# slug = decodeUrl(@"slug")
# list = await getCachedList(@"name", slug)
# if list.id.len == 0:
# let json = %*{ "error": "List not found" }
# resp Http200, $json
# redirect(&"/api/i/lists/{list.id}")
get "/api/i/lists/@id/?":
cond cfg.enableJsonApi
@ -39,7 +44,7 @@ proc createJsonApiListRouter*(cfg: Config) =
"list": $formatListAsJson(list),
"timeline": $formatTimelineAsJson(timeline)
}
resp Http200, headers, $json
resp Http200, $json
get "/api/i/lists/@id/members":
cond cfg.enableJsonApi
@ -51,4 +56,4 @@ proc createJsonApiListRouter*(cfg: Config) =
"list": $formatListAsJson(list),
"members": $formatUsersAsJson(members)
}
resp Http200, headers, $json
resp Http200, $json

View file

@ -1,6 +1,6 @@
# SPDX-License-Identifier: AGPL-3.0-only
import options
import json
import packedjson
import times
import ".."/[types]
@ -8,7 +8,7 @@ import ".."/[types]
# JSON formatting functions
proc formatUserAsJson*(user: User): JsonNode =
result = %*{
return %*{
"id": user.id,
"username": user.username,
"fullname": user.fullname,
@ -30,7 +30,7 @@ proc formatUserAsJson*(user: User): JsonNode =
}
proc formatTweetAsJson*(tweet: Tweet): JsonNode =
result = %*{
let result = %*{
"id": tweet.id,
"threadId": tweet.threadId,
"replyId": tweet.replyId,
@ -49,35 +49,21 @@ proc formatTweetAsJson*(tweet: Tweet): JsonNode =
"retweets": tweet.stats.retweets,
"likes": tweet.stats.likes,
"quotes": tweet.stats.quotes
}
},
"retweet": if tweet.retweet.isSome: formatTweetAsJson(get(tweet.retweet)) else: JsonTree(newJNull()),
"attribution": if tweet.attribution.isSome: formatUserAsJson(get(tweet.attribution)) else: JsonTree(newJNull()),
"quote": if tweet.quote.isSome: formatTweetAsJson(get(tweet.quote)) else: JsonTree(newJNull()),
"poll": if tweet.poll.isSome: %*get(tweet.poll) else: JsonTree(newJNull()),
"gif": if tweet.gif.isSome: %*get(tweet.gif) else: JsonTree(newJNull()),
"video": if tweet.video.isSome: %*get(tweet.video) else: JsonTree(newJNull()),
"photos": if tweet.photos.len > 0: %tweet.photos else: JsonTree(newJNull())
}
if tweet.retweet.isSome:
result["retweet"] = formatTweetAsJson(get(tweet.retweet))
if tweet.attribution.isSome:
result["attribution"] = formatUserAsJson(get(tweet.attribution))
if tweet.quote.isSome:
result["quote"] = formatTweetAsJson(get(tweet.quote))
if tweet.poll.isSome:
result["poll"] = %*get(tweet.poll)
if tweet.gif.isSome:
result["gif"] = %*get(tweet.gif)
if tweet.video.isSome:
result["video"] = %*get(tweet.video)
if tweet.photos.len > 0:
result["photos"] = %tweet.photos
return result
proc formatTimelineAsJson*(results: Timeline): JsonNode =
result = %*{
"list": %*{
"beginning": results.beginning,
"top": results.top,
"bottom": results.bottom
},
"timeline": newJArray()
}
var retweets: seq[int64]
var timeline = newJArray()
for thread in results.content:
if thread.len == 1:
let tweet = thread[0]
@ -89,20 +75,33 @@ proc formatTimelineAsJson*(results: Timeline): JsonNode =
if retweetId != 0 and tweet.retweet.isSome:
retweets &= retweetId
result["timeline"].add(formatTweetAsJson(tweet))
timeline.add(formatTweetAsJson(tweet))
else:
var threadJson = newJArray()
for tweet in thread:
threadJson.add(formatTweetAsJson(tweet))
result["timeline"].add(threadJson)
timeline.add(formatTweetAsJson(tweet))
timeline.add(timeline)
proc formatUsersAsJson*(results: Result[User]): JsonNode =
result = %*{
"beginning": results.beginning,
"top": results.top,
"bottom": results.bottom,
"content": newJArray()
return %*{
"list": %*{
"beginning": results.beginning,
"top": results.top,
"bottom": results.bottom
},
"timeline": timeline
}
proc formatUsersAsJson*(results: Result[User]): JsonNode =
var users = newJArray()
for user in results.content:
result["content"].add(formatUserAsJson(user))
users.add(formatUserAsJson(user))
return %*{
"list": %*{
"beginning": results.beginning,
"top": results.top,
"bottom": results.bottom,
},
"users": users
}

View file

@ -106,7 +106,8 @@ routes:
resp Http429, showError(
&"Instance has no auth tokens, or is fully rate limited.<br>Use {link} or try again later.", cfg)
extend jsonapi, ""
extend jsonapi_list, ""
extend jsonapi_health, ""
extend rss, ""
extend status, ""
extend search, ""

View file

@ -1,46 +0,0 @@
# SPDX-License-Identifier: AGPL-3.0-only
import asyncdispatch, httpclient, uri, strutils, sequtils, sugar
import packedjson
import jester
import ".."/[types, query, formatters, consts, apiutils, parser]
import "../jsons/timeline"
proc createApiRouter*(cfg: Config) =
router api:
get "/api/timeline/@name/?@tab?/?":
cond '.' notin @"name"
cond @"name" notin ["pic", "gif", "video", "search", "settings", "login", "intent", "i"]
cond @"tab" in ["with_replies", "media", "search", ""]
let
prefs = cookiePrefs()
after = getCursor()
names = getNames(@"name")
var query = request.getQuery(@"tab", @"name")
if names.len != 1:
query.fromUser = names
if query.fromUser.len != 1:
var timeline = await getGraphTweetSearch(query, after)
if timeline.content.len == 0: resp Http404
resp $formatTimelineAsJson(timeline)
else:
var profile = await fetchProfile(after, query, skipRail=true)
if profile.tweets.content.len == 0: resp Http404
resp $formatTimelineAsJson(profile.tweets)
get "/api/users/@name/?":
cond '.' notin @"name"
cond @"name" notin ["pic", "gif", "video", "search", "settings", "login", "intent", "i"]
let
prefs = cookiePrefs()
after = getCursor()
names = getNames(@"name")
var query = request.getQuery("", @"name")
if names.len != 1:
query.fromUser = names
var results = await getGraphUserSearch(query, after)
if results.content.len == 0: resp Http404
resp $formatUsersAsJson(results)