types.nim 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. # SPDX-License-Identifier: AGPL-3.0-only
  2. import times, sequtils, options, tables
  3. import prefs_impl
  4. genPrefsType()
  5. type
  6. RateLimitError* = object of CatchableError
  7. NoSessionsError* = object of CatchableError
  8. InternalError* = object of CatchableError
  9. BadClientError* = object of CatchableError
  10. TimelineKind* {.pure.} = enum
  11. tweets, replies, media, articles
  12. ApiUrl* = object
  13. endpoint*: string
  14. params*: seq[(string, string)]
  15. skipTid*: bool
  16. ApiReq* = object
  17. oauth*: ApiUrl
  18. cookie*: ApiUrl
  19. RateLimit* = object
  20. limit*: int
  21. remaining*: int
  22. reset*: int
  23. SessionKind* = enum
  24. oauth
  25. cookie
  26. Session* = ref object
  27. id*: int64
  28. username*: string
  29. pending*: int
  30. limited*: bool
  31. limitedAt*: int
  32. apis*: Table[string, RateLimit]
  33. case kind*: SessionKind
  34. of oauth:
  35. oauthToken*: string
  36. oauthSecret*: string
  37. of cookie:
  38. authToken*: string
  39. ct0*: string
  40. Error* = enum
  41. null = 0
  42. noUserMatches = 17
  43. protectedUser = 22
  44. missingParams = 25
  45. timeout = 29
  46. couldntAuth = 32
  47. doesntExist = 34
  48. unauthorized = 37
  49. invalidParam = 47
  50. userNotFound = 50
  51. suspended = 63
  52. rateLimited = 88
  53. expiredToken = 89
  54. listIdOrSlug = 112
  55. timelineUnavailable = 131
  56. tweetNotFound = 144
  57. tweetNotAuthorized = 179
  58. forbidden = 200
  59. badRequest = 214
  60. badToken = 239
  61. locked = 326
  62. noCsrf = 353
  63. tweetUnavailable = 421
  64. tweetCensored = 422
  65. VerifiedType* = enum
  66. none = "None"
  67. blue = "Blue"
  68. business = "Business"
  69. government = "Government"
  70. User* = object
  71. id*: string
  72. username*: string
  73. fullname*: string
  74. location*: string
  75. website*: string
  76. bio*: string
  77. userPic*: string
  78. banner*: string
  79. pinnedTweet*: int64
  80. following*: int
  81. followers*: int
  82. tweets*: int
  83. likes*: int
  84. media*: int
  85. verifiedType*: VerifiedType
  86. protected*: bool
  87. suspended*: bool
  88. joinDate*: DateTime
  89. AccountInfo* = object
  90. username*: string
  91. fullname*: string
  92. userPic*: string
  93. joinDate*: DateTime
  94. verifiedType*: VerifiedType
  95. suspended*: bool
  96. basedIn*: string
  97. source*: string
  98. usernameChanges*: int
  99. lastUsernameChange*: DateTime
  100. affiliateUsername*: string
  101. affiliateLabel*: string
  102. isIdentityVerified*: bool
  103. verifiedSince*: DateTime
  104. overrideVerifiedYear*: int
  105. Broadcast* = object
  106. id*: string
  107. title*: string
  108. state*: string
  109. thumb*: string
  110. mediaKey*: string
  111. m3u8Url*: string
  112. totalWatched*: int
  113. startTime*: DateTime
  114. endTime*: DateTime
  115. replayStart*: int
  116. availableForReplay*: bool
  117. user*: User
  118. SpaceParticipant* = object
  119. userId*: string
  120. username*: string
  121. displayName*: string
  122. avatarUrl*: string
  123. isVerified*: bool
  124. AudioSpace* = object
  125. id*: string
  126. title*: string
  127. state*: string
  128. mediaKey*: string
  129. m3u8Url*: string
  130. totalLiveListeners*: int
  131. totalReplayWatched*: int
  132. startTime*: DateTime
  133. endTime*: DateTime
  134. availableForReplay*: bool
  135. creator*: User
  136. admins*: seq[SpaceParticipant]
  137. speakers*: seq[SpaceParticipant]
  138. VideoType* = enum
  139. m3u8 = "application/x-mpegURL"
  140. mp4 = "video/mp4"
  141. vmap = "video/vmap"
  142. VideoVariant* = object
  143. contentType*: VideoType
  144. url*: string
  145. bitrate*: int
  146. resolution*: int
  147. Video* = object
  148. durationMs*: int
  149. url*: string
  150. thumb*: string
  151. available*: bool
  152. reason*: string
  153. title*: string
  154. description*: string
  155. playbackType*: VideoType
  156. variants*: seq[VideoVariant]
  157. QueryKind* = enum
  158. posts, replies, media, users, tweets, userList, followers, following, lists, top,
  159. articles
  160. RankingMode* = enum
  161. Relevance, Recency, Likes
  162. Query* = object
  163. kind*: QueryKind
  164. view*: string
  165. text*: string
  166. filters*: seq[string]
  167. includes*: seq[string]
  168. excludes*: seq[string]
  169. fromUser*: seq[string]
  170. since*: string
  171. until*: string
  172. minLikes*: string
  173. sep*: string
  174. Gif* = object
  175. url*: string
  176. thumb*: string
  177. altText*: string
  178. Photo* = object
  179. url*: string
  180. altText*: string
  181. MediaKind* = enum
  182. photoMedia
  183. videoMedia
  184. gifMedia
  185. Media* = object
  186. case kind*: MediaKind
  187. of photoMedia:
  188. photo*: Photo
  189. of videoMedia:
  190. video*: Video
  191. of gifMedia:
  192. gif*: Gif
  193. MediaEntities* = seq[Media]
  194. GalleryPhoto* = object
  195. url*: string
  196. tweetId*: string
  197. color*: string
  198. PhotoRail* = seq[GalleryPhoto]
  199. Article* = ref object
  200. title*: string
  201. coverImage*: string
  202. user*: User
  203. time*: DateTime
  204. stats*: TweetStats
  205. paragraphs*: seq[ArticleParagraph]
  206. entities*: Table[int, ArticleEntity]
  207. media*: Table[string, ArticleMedia]
  208. ArticleParagraph* = object
  209. text*: string
  210. kind*: string
  211. inlineStyles*: seq[ArticleStyle]
  212. entityRanges*: seq[ArticleEntityRange]
  213. ArticleStyle* = object
  214. offset*: int
  215. length*: int
  216. style*: string
  217. ArticleEntityRange* = object
  218. offset*: int
  219. length*: int
  220. key*: int
  221. ArticleEntity* = object
  222. kind*: string
  223. url*: string
  224. mediaIds*: seq[string]
  225. tweetId*: string
  226. markdown*: string
  227. caption*: string
  228. ArticleMedia* = object
  229. kind*: string
  230. url*: string
  231. Poll* = object
  232. options*: seq[string]
  233. values*: seq[int]
  234. votes*: int
  235. leader*: int
  236. status*: string
  237. CardKind* = enum
  238. amplify = "amplify"
  239. app = "app"
  240. appPlayer = "appplayer"
  241. player = "player"
  242. summary = "summary"
  243. summaryLarge = "summary_large_image"
  244. promoWebsite = "promo_website"
  245. promoVideo = "promo_video_website"
  246. promoVideoConvo = "promo_video_convo"
  247. promoImageConvo = "promo_image_convo"
  248. promoImageApp = "promo_image_app"
  249. storeLink = "direct_store_link_app"
  250. liveEvent = "live_event"
  251. broadcast = "broadcast"
  252. periscope = "periscope_broadcast"
  253. unified = "unified_card"
  254. moment = "moment"
  255. messageMe = "message_me"
  256. videoDirectMessage = "video_direct_message"
  257. imageDirectMessage = "image_direct_message"
  258. audiospace = "audiospace"
  259. newsletterPublication = "newsletter_publication"
  260. jobDetails = "job_details"
  261. hidden
  262. unknown
  263. Card* = object
  264. kind*: CardKind
  265. url*: string
  266. title*: string
  267. dest*: string
  268. text*: string
  269. image*: string
  270. video*: Option[Video]
  271. TweetStats* = object
  272. replies*: int
  273. retweets*: int
  274. likes*: int
  275. views*: int
  276. ArticlePreview* = object
  277. title*: string
  278. previewText*: string
  279. coverImage*: string
  280. tweetId*: int64
  281. Tweet* = ref object
  282. id*: int64
  283. threadId*: int64
  284. replyId*: int64
  285. user*: User
  286. text*: string
  287. time*: DateTime
  288. reply*: seq[string]
  289. pinned*: bool
  290. hasThread*: bool
  291. available*: bool
  292. tombstone*: string
  293. location*: string
  294. # Unused, needed for backwards compat
  295. source*: string
  296. stats*: TweetStats
  297. retweet*: Option[Tweet]
  298. attribution*: Option[User]
  299. attributionLink*: string
  300. mediaTags*: seq[User]
  301. quote*: Option[Tweet]
  302. card*: Option[Card]
  303. poll*: Option[Poll]
  304. media*: MediaEntities
  305. history*: seq[int64]
  306. note*: string
  307. isAd*: bool
  308. isAI*: bool
  309. articlePreview*: Option[ArticlePreview]
  310. Tweets* = seq[Tweet]
  311. Result*[T] = object
  312. content*: seq[T]
  313. top*, bottom*: string
  314. beginning*: bool
  315. query*: Query
  316. Chain* = object
  317. content*: Tweets
  318. hasMore*: bool
  319. cursor*: string
  320. related*: bool
  321. Conversation* = ref object
  322. tweet*: Tweet
  323. before*: Chain
  324. after*: Chain
  325. replies*: Result[Chain]
  326. EditHistory* = object
  327. latest*: Tweet
  328. history*: Tweets
  329. Timeline* = Result[Tweets]
  330. Profile* = object
  331. user*: User
  332. photoRail*: PhotoRail
  333. pinned*: Option[Tweet]
  334. tweets*: Timeline
  335. accountInfo*: AccountInfo
  336. List* = object
  337. id*: string
  338. name*: string
  339. userId*: string
  340. username*: string
  341. description*: string
  342. members*: int
  343. banner*: string
  344. ListSearchResult* = object
  345. list*: List
  346. owner*: User
  347. followersContext*: string
  348. facepiles*: seq[string]
  349. CommunityRule* = object
  350. name*: string
  351. description*: string
  352. Community* = object
  353. id*: string
  354. name*: string
  355. description*: string
  356. memberCount*: int
  357. banner*: string
  358. creator*: User
  359. category*: string
  360. joinPolicy*: string
  361. createdAt*: DateTime
  362. rules*: seq[CommunityRule]
  363. hashtags*: seq[string]
  364. GlobalObjects* = ref object
  365. tweets*: Table[string, Tweet]
  366. users*: Table[string, User]
  367. Config* = ref object
  368. address*: string
  369. port*: int
  370. useHttps*: bool
  371. httpMaxConns*: int
  372. title*: string
  373. hostname*: string
  374. staticDir*: string
  375. hmacKey*: string
  376. base64Media*: bool
  377. minTokens*: int
  378. enableRSSUserTweets*: bool
  379. enableRSSUserReplies*: bool
  380. enableRSSUserMedia*: bool
  381. enableRSSUserArticles*: bool
  382. enableRSSSearch*: bool
  383. enableRSSList*: bool
  384. enableDebug*: bool
  385. proxy*: string
  386. proxyAuth*: string
  387. apiProxy*: string
  388. disableTid*: bool
  389. maxConcurrentReqs*: int
  390. maxRetries*: int
  391. retryDelayMs*: int
  392. rssCacheTime*: int
  393. listCacheTime*: int
  394. redisHost*: string
  395. redisPort*: int
  396. redisConns*: int
  397. redisMaxConns*: int
  398. redisPassword*: string
  399. Rss* = object
  400. feed*, cursor*: string
  401. proc contains*(thread: Chain; tweet: Tweet): bool =
  402. thread.content.anyIt(it.id == tweet.id)
  403. proc add*(timeline: var seq[Tweets]; tweet: Tweet) =
  404. timeline.add @[tweet]
  405. proc getPhotos*(tweet: Tweet): seq[Photo] =
  406. tweet.media.filterIt(it.kind == photoMedia).mapIt(it.photo)
  407. proc getVideos*(tweet: Tweet): seq[Video] =
  408. tweet.media.filterIt(it.kind == videoMedia).mapIt(it.video)
  409. proc hasPhotos*(tweet: Tweet): bool =
  410. tweet.media.anyIt(it.kind == photoMedia)
  411. proc hasVideos*(tweet: Tweet): bool =
  412. tweet.media.anyIt(it.kind == videoMedia)
  413. proc hasGifs*(tweet: Tweet): bool =
  414. tweet.media.anyIt(it.kind == gifMedia)
  415. proc getThumb*(media: Media): string =
  416. case media.kind
  417. of photoMedia: media.photo.url
  418. of videoMedia: media.video.thumb
  419. of gifMedia: media.gif.thumb