2021-12-27 01:37:38 +00:00
|
|
|
# SPDX-License-Identifier: AGPL-3.0-only
|
2020-06-01 00:25:39 +00:00
|
|
|
import times, sequtils, options, tables
|
2019-09-08 11:01:20 +00:00
|
|
|
import prefs_impl
|
|
|
|
|
2020-05-08 00:48:47 +00:00
|
|
|
genPrefsType()
|
|
|
|
|
2019-08-06 17:02:38 +00:00
|
|
|
type
|
2021-01-07 21:31:29 +00:00
|
|
|
RateLimitError* = object of CatchableError
|
2021-12-28 04:02:28 +00:00
|
|
|
InternalError* = object of CatchableError
|
2023-04-21 12:41:30 +00:00
|
|
|
BadClientError* = object of CatchableError
|
|
|
|
|
|
|
|
TimelineKind* {.pure.} = enum
|
2023-11-25 10:06:12 +00:00
|
|
|
tweets, replies, media
|
2021-01-07 21:31:29 +00:00
|
|
|
|
2022-01-05 21:48:45 +00:00
|
|
|
Api* {.pure.} = enum
|
2023-02-24 00:01:22 +00:00
|
|
|
tweetDetail
|
2023-04-21 12:41:30 +00:00
|
|
|
tweetResult
|
2023-07-21 16:56:39 +00:00
|
|
|
photoRail
|
2022-01-05 21:48:45 +00:00
|
|
|
search
|
|
|
|
list
|
|
|
|
listBySlug
|
|
|
|
listMembers
|
2023-04-21 12:41:30 +00:00
|
|
|
listTweets
|
2022-01-23 06:04:50 +00:00
|
|
|
userRestId
|
2023-01-20 03:54:19 +00:00
|
|
|
userScreenName
|
2023-04-21 12:41:30 +00:00
|
|
|
userTweets
|
|
|
|
userTweetsAndReplies
|
|
|
|
userMedia
|
2022-01-05 21:48:45 +00:00
|
|
|
|
|
|
|
RateLimit* = object
|
2020-06-01 00:25:39 +00:00
|
|
|
remaining*: int
|
2022-01-05 23:19:09 +00:00
|
|
|
reset*: int
|
2023-08-20 09:56:42 +00:00
|
|
|
limited*: bool
|
|
|
|
limitedAt*: int
|
2022-01-05 21:48:45 +00:00
|
|
|
|
2023-08-18 22:25:14 +00:00
|
|
|
GuestAccount* = ref object
|
2023-11-04 02:56:32 +00:00
|
|
|
id*: int64
|
2023-08-18 22:25:14 +00:00
|
|
|
oauthToken*: string
|
|
|
|
oauthSecret*: string
|
2022-01-05 22:38:46 +00:00
|
|
|
pending*: int
|
2022-01-05 21:48:45 +00:00
|
|
|
apis*: Table[Api, RateLimit]
|
2020-06-01 00:25:39 +00:00
|
|
|
|
|
|
|
Error* = enum
|
2020-06-01 07:45:38 +00:00
|
|
|
null = 0
|
2020-06-17 15:19:08 +00:00
|
|
|
noUserMatches = 17
|
2020-06-01 00:25:39 +00:00
|
|
|
protectedUser = 22
|
2023-04-21 12:41:30 +00:00
|
|
|
missingParams = 25
|
2020-06-01 00:25:39 +00:00
|
|
|
couldntAuth = 32
|
|
|
|
doesntExist = 34
|
2023-04-21 12:41:30 +00:00
|
|
|
invalidParam = 47
|
2020-06-01 07:45:38 +00:00
|
|
|
userNotFound = 50
|
2020-06-01 00:25:39 +00:00
|
|
|
suspended = 63
|
2020-06-15 14:40:27 +00:00
|
|
|
rateLimited = 88
|
2023-08-30 01:04:22 +00:00
|
|
|
expiredToken = 89
|
2020-06-01 00:25:39 +00:00
|
|
|
listIdOrSlug = 112
|
2022-01-23 08:11:14 +00:00
|
|
|
tweetNotFound = 144
|
2023-03-06 10:00:27 +00:00
|
|
|
tweetNotAuthorized = 179
|
2020-06-01 00:25:39 +00:00
|
|
|
forbidden = 200
|
2020-06-15 14:40:27 +00:00
|
|
|
badToken = 239
|
2020-06-01 00:25:39 +00:00
|
|
|
noCsrf = 353
|
2023-03-03 23:46:44 +00:00
|
|
|
tweetUnavailable = 421
|
|
|
|
tweetCensored = 422
|
2020-06-01 00:25:39 +00:00
|
|
|
|
2023-11-25 10:06:12 +00:00
|
|
|
VerifiedType* = enum
|
|
|
|
none = "None"
|
|
|
|
blue = "Blue"
|
|
|
|
business = "Business"
|
|
|
|
government = "Government"
|
|
|
|
|
2022-01-23 06:04:50 +00:00
|
|
|
User* = object
|
2020-06-01 00:25:39 +00:00
|
|
|
id*: string
|
|
|
|
username*: string
|
|
|
|
fullname*: string
|
|
|
|
location*: string
|
|
|
|
website*: string
|
|
|
|
bio*: string
|
2022-01-06 02:57:14 +00:00
|
|
|
userPic*: string
|
2020-06-01 00:25:39 +00:00
|
|
|
banner*: string
|
2022-01-23 06:04:50 +00:00
|
|
|
pinnedTweet*: int64
|
2022-01-16 02:32:18 +00:00
|
|
|
following*: int
|
|
|
|
followers*: int
|
|
|
|
tweets*: int
|
|
|
|
likes*: int
|
|
|
|
media*: int
|
2023-11-25 10:06:12 +00:00
|
|
|
verifiedType*: VerifiedType
|
2020-06-01 00:25:39 +00:00
|
|
|
protected*: bool
|
|
|
|
suspended*: bool
|
2021-12-20 02:11:12 +00:00
|
|
|
joinDate*: DateTime
|
2020-06-01 00:25:39 +00:00
|
|
|
|
2019-08-06 17:02:38 +00:00
|
|
|
VideoType* = enum
|
2020-06-01 00:25:39 +00:00
|
|
|
m3u8 = "application/x-mpegURL"
|
|
|
|
mp4 = "video/mp4"
|
|
|
|
vmap = "video/vmap"
|
2019-08-06 17:02:38 +00:00
|
|
|
|
2020-06-01 00:25:39 +00:00
|
|
|
VideoVariant* = object
|
2022-01-12 23:36:30 +00:00
|
|
|
contentType*: VideoType
|
2020-06-01 00:25:39 +00:00
|
|
|
url*: string
|
|
|
|
bitrate*: int
|
2022-05-18 17:47:03 +00:00
|
|
|
resolution*: int
|
2020-06-01 00:25:39 +00:00
|
|
|
|
|
|
|
Video* = object
|
|
|
|
durationMs*: int
|
|
|
|
url*: string
|
|
|
|
thumb*: string
|
|
|
|
views*: string
|
|
|
|
available*: bool
|
|
|
|
reason*: string
|
|
|
|
title*: string
|
|
|
|
description*: string
|
|
|
|
playbackType*: VideoType
|
|
|
|
variants*: seq[VideoVariant]
|
2019-09-08 10:22:52 +00:00
|
|
|
|
2019-07-11 17:22:23 +00:00
|
|
|
QueryKind* = enum
|
2019-10-08 11:54:20 +00:00
|
|
|
posts, replies, media, users, tweets, userList
|
2019-07-03 09:46:03 +00:00
|
|
|
|
|
|
|
Query* = object
|
2019-07-11 17:22:23 +00:00
|
|
|
kind*: QueryKind
|
2019-09-13 11:20:08 +00:00
|
|
|
text*: string
|
2019-07-04 09:55:19 +00:00
|
|
|
filters*: seq[string]
|
|
|
|
includes*: seq[string]
|
|
|
|
excludes*: seq[string]
|
2019-08-06 15:41:06 +00:00
|
|
|
fromUser*: seq[string]
|
2019-09-19 20:11:38 +00:00
|
|
|
since*: string
|
|
|
|
until*: string
|
2019-09-19 21:36:21 +00:00
|
|
|
near*: string
|
2019-07-04 09:55:19 +00:00
|
|
|
sep*: string
|
2019-07-03 09:46:03 +00:00
|
|
|
|
2019-06-24 03:14:14 +00:00
|
|
|
Gif* = object
|
|
|
|
url*: string
|
|
|
|
thumb*: string
|
|
|
|
|
2019-07-04 02:18:32 +00:00
|
|
|
GalleryPhoto* = object
|
|
|
|
url*: string
|
|
|
|
tweetId*: string
|
|
|
|
color*: string
|
|
|
|
|
2020-05-26 12:24:41 +00:00
|
|
|
PhotoRail* = seq[GalleryPhoto]
|
|
|
|
|
2019-06-29 12:11:23 +00:00
|
|
|
Poll* = object
|
|
|
|
options*: seq[string]
|
|
|
|
values*: seq[int]
|
2020-06-01 00:25:39 +00:00
|
|
|
votes*: int
|
2019-06-29 12:11:23 +00:00
|
|
|
leader*: int
|
2020-06-01 00:25:39 +00:00
|
|
|
status*: string
|
2019-06-29 12:11:23 +00:00
|
|
|
|
2019-07-11 17:22:23 +00:00
|
|
|
CardKind* = enum
|
2020-06-03 00:33:34 +00:00
|
|
|
amplify = "amplify"
|
2020-06-02 14:31:10 +00:00
|
|
|
app = "app"
|
2020-06-03 00:33:34 +00:00
|
|
|
appPlayer = "appplayer"
|
2020-06-01 00:25:39 +00:00
|
|
|
player = "player"
|
2019-07-15 14:03:01 +00:00
|
|
|
summary = "summary"
|
|
|
|
summaryLarge = "summary_large_image"
|
|
|
|
promoWebsite = "promo_website"
|
2020-06-03 00:42:26 +00:00
|
|
|
promoVideo = "promo_video_website"
|
2019-11-08 21:52:34 +00:00
|
|
|
promoVideoConvo = "promo_video_convo"
|
2020-06-01 02:19:21 +00:00
|
|
|
promoImageConvo = "promo_image_convo"
|
2020-06-01 06:18:37 +00:00
|
|
|
promoImageApp = "promo_image_app"
|
2020-06-03 00:33:34 +00:00
|
|
|
storeLink = "direct_store_link_app"
|
2019-07-15 14:03:01 +00:00
|
|
|
liveEvent = "live_event"
|
2020-06-01 00:25:39 +00:00
|
|
|
broadcast = "broadcast"
|
|
|
|
periscope = "periscope_broadcast"
|
2020-06-03 00:33:34 +00:00
|
|
|
unified = "unified_card"
|
2020-06-01 06:18:37 +00:00
|
|
|
moment = "moment"
|
|
|
|
messageMe = "message_me"
|
2020-06-10 14:13:40 +00:00
|
|
|
videoDirectMessage = "video_direct_message"
|
|
|
|
imageDirectMessage = "image_direct_message"
|
2021-06-23 21:15:41 +00:00
|
|
|
audiospace = "audiospace"
|
2022-01-02 12:48:52 +00:00
|
|
|
newsletterPublication = "newsletter_publication"
|
2023-11-25 05:31:15 +00:00
|
|
|
jobDetails = "job_details"
|
2023-04-21 12:41:30 +00:00
|
|
|
hidden
|
2021-11-20 22:12:33 +00:00
|
|
|
unknown
|
2023-11-04 02:56:32 +00:00
|
|
|
|
2019-07-11 17:22:23 +00:00
|
|
|
Card* = object
|
|
|
|
kind*: CardKind
|
|
|
|
url*: string
|
|
|
|
title*: string
|
|
|
|
dest*: string
|
|
|
|
text*: string
|
2020-06-01 00:25:39 +00:00
|
|
|
image*: string
|
2019-07-15 14:03:01 +00:00
|
|
|
video*: Option[Video]
|
2019-07-11 17:22:23 +00:00
|
|
|
|
2019-07-01 21:48:25 +00:00
|
|
|
TweetStats* = object
|
2020-05-26 12:24:41 +00:00
|
|
|
replies*: int
|
|
|
|
retweets*: int
|
|
|
|
likes*: int
|
2020-11-08 00:32:17 +00:00
|
|
|
quotes*: int
|
2019-07-01 21:48:25 +00:00
|
|
|
|
2019-06-24 03:14:14 +00:00
|
|
|
Tweet* = ref object
|
2019-12-09 23:39:12 +00:00
|
|
|
id*: int64
|
|
|
|
threadId*: int64
|
2020-06-01 00:25:39 +00:00
|
|
|
replyId*: int64
|
2022-01-23 06:04:50 +00:00
|
|
|
user*: User
|
2019-06-20 14:16:20 +00:00
|
|
|
text*: string
|
2021-12-20 02:11:12 +00:00
|
|
|
time*: DateTime
|
2019-07-01 22:52:50 +00:00
|
|
|
reply*: seq[string]
|
2019-06-20 14:16:20 +00:00
|
|
|
pinned*: bool
|
2019-07-01 22:52:50 +00:00
|
|
|
hasThread*: bool
|
2019-09-08 12:34:26 +00:00
|
|
|
available*: bool
|
|
|
|
tombstone*: string
|
2019-12-21 04:44:58 +00:00
|
|
|
location*: string
|
2023-02-25 17:25:02 +00:00
|
|
|
# Unused, needed for backwards compat
|
2023-02-24 00:02:28 +00:00
|
|
|
source*: string
|
2022-02-27 00:00:06 +00:00
|
|
|
stats*: TweetStats
|
2020-06-01 00:25:39 +00:00
|
|
|
retweet*: Option[Tweet]
|
2022-01-23 06:04:50 +00:00
|
|
|
attribution*: Option[User]
|
|
|
|
mediaTags*: seq[User]
|
2020-06-01 00:25:39 +00:00
|
|
|
quote*: Option[Tweet]
|
2019-07-11 17:22:23 +00:00
|
|
|
card*: Option[Card]
|
2020-06-01 00:25:39 +00:00
|
|
|
poll*: Option[Poll]
|
2019-06-24 03:14:14 +00:00
|
|
|
gif*: Option[Gif]
|
|
|
|
video*: Option[Video]
|
|
|
|
photos*: seq[string]
|
2019-06-20 14:16:20 +00:00
|
|
|
|
2023-07-11 23:34:39 +00:00
|
|
|
Tweets* = seq[Tweet]
|
|
|
|
|
2020-06-01 00:25:39 +00:00
|
|
|
Result*[T] = object
|
2020-04-29 16:09:13 +00:00
|
|
|
content*: seq[T]
|
2020-06-01 00:25:39 +00:00
|
|
|
top*, bottom*: string
|
2020-04-29 16:09:13 +00:00
|
|
|
beginning*: bool
|
|
|
|
query*: Query
|
|
|
|
|
2020-06-01 00:25:39 +00:00
|
|
|
Chain* = object
|
2023-07-11 23:34:39 +00:00
|
|
|
content*: Tweets
|
2022-01-23 06:04:50 +00:00
|
|
|
hasMore*: bool
|
2020-06-01 00:25:39 +00:00
|
|
|
cursor*: string
|
2019-06-20 14:16:20 +00:00
|
|
|
|
2019-06-24 03:14:14 +00:00
|
|
|
Conversation* = ref object
|
2019-06-20 14:16:20 +00:00
|
|
|
tweet*: Tweet
|
2019-10-08 18:47:45 +00:00
|
|
|
before*: Chain
|
|
|
|
after*: Chain
|
|
|
|
replies*: Result[Chain]
|
2019-06-20 14:16:20 +00:00
|
|
|
|
2023-07-11 23:34:39 +00:00
|
|
|
Timeline* = Result[Tweets]
|
2019-06-25 05:36:36 +00:00
|
|
|
|
2022-01-23 06:04:50 +00:00
|
|
|
Profile* = object
|
|
|
|
user*: User
|
|
|
|
photoRail*: PhotoRail
|
|
|
|
pinned*: Option[Tweet]
|
|
|
|
tweets*: Timeline
|
|
|
|
|
2020-06-01 00:25:39 +00:00
|
|
|
List* = object
|
|
|
|
id*: string
|
|
|
|
name*: string
|
|
|
|
userId*: string
|
|
|
|
username*: string
|
|
|
|
description*: string
|
|
|
|
members*: int
|
|
|
|
banner*: string
|
|
|
|
|
|
|
|
GlobalObjects* = ref object
|
|
|
|
tweets*: Table[string, Tweet]
|
2022-01-23 06:04:50 +00:00
|
|
|
users*: Table[string, User]
|
2020-06-01 00:25:39 +00:00
|
|
|
|
2019-07-31 00:15:43 +00:00
|
|
|
Config* = ref object
|
|
|
|
address*: string
|
|
|
|
port*: int
|
2019-08-19 01:02:34 +00:00
|
|
|
useHttps*: bool
|
2021-06-23 21:17:16 +00:00
|
|
|
httpMaxConns*: int
|
2019-10-21 03:19:00 +00:00
|
|
|
title*: string
|
|
|
|
hostname*: string
|
2020-06-01 00:26:04 +00:00
|
|
|
staticDir*: string
|
|
|
|
|
2019-10-23 22:17:38 +00:00
|
|
|
hmacKey*: string
|
2020-06-09 13:04:38 +00:00
|
|
|
base64Media*: bool
|
2020-06-01 00:26:04 +00:00
|
|
|
minTokens*: int
|
2021-12-28 05:21:22 +00:00
|
|
|
enableRss*: bool
|
2022-01-05 18:08:08 +00:00
|
|
|
enableDebug*: bool
|
2021-09-30 16:03:07 +00:00
|
|
|
proxy*: string
|
|
|
|
proxyAuth*: string
|
2020-06-01 00:26:04 +00:00
|
|
|
|
|
|
|
rssCacheTime*: int
|
|
|
|
listCacheTime*: int
|
|
|
|
|
|
|
|
redisHost*: string
|
|
|
|
redisPort*: int
|
|
|
|
redisConns*: int
|
|
|
|
redisMaxConns*: int
|
2021-08-06 22:53:16 +00:00
|
|
|
redisPassword*: string
|
2019-07-31 00:15:43 +00:00
|
|
|
|
2020-06-06 07:27:25 +00:00
|
|
|
Rss* = object
|
|
|
|
feed*, cursor*: string
|
|
|
|
|
2019-10-08 18:47:45 +00:00
|
|
|
proc contains*(thread: Chain; tweet: Tweet): bool =
|
2019-08-23 00:15:25 +00:00
|
|
|
thread.content.anyIt(it.id == tweet.id)
|
2023-07-10 09:25:34 +00:00
|
|
|
|
2023-07-11 23:34:39 +00:00
|
|
|
proc add*(timeline: var seq[Tweets]; tweet: Tweet) =
|
|
|
|
timeline.add @[tweet]
|